mirror of
https://github.com/arduino/arduino-ide.git
synced 2025-04-19 12:57:17 +00:00
chore: Updated to Theia 1.31.1
(#1662)
Closes #1655 Closes #1656 Signed-off-by: Akos Kitta <a.kitta@arduino.cc>
This commit is contained in:
parent
3ad660927f
commit
ac9cce16f7
4
.gitignore
vendored
4
.gitignore
vendored
@ -7,7 +7,7 @@ build/
|
||||
Examples/
|
||||
!electron/build/
|
||||
src-gen/
|
||||
!webpack.config.js
|
||||
webpack.config.js
|
||||
gen-webpack.config.js
|
||||
.DS_Store
|
||||
# switching from `electron` to `browser` in dev mode.
|
||||
@ -15,8 +15,6 @@ gen-webpack.config.js
|
||||
yarn*.log
|
||||
# For the VS Code extensions used by Theia.
|
||||
plugins
|
||||
# the config files for the CLI
|
||||
arduino-ide-extension/data/cli/config
|
||||
# the tokens folder for the themes
|
||||
scripts/themes/tokens
|
||||
# environment variables
|
||||
|
@ -21,27 +21,31 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@grpc/grpc-js": "^1.6.7",
|
||||
"@theia/application-package": "1.25.0",
|
||||
"@theia/core": "1.25.0",
|
||||
"@theia/editor": "1.25.0",
|
||||
"@theia/electron": "1.25.0",
|
||||
"@theia/filesystem": "1.25.0",
|
||||
"@theia/keymaps": "1.25.0",
|
||||
"@theia/markers": "1.25.0",
|
||||
"@theia/monaco": "1.25.0",
|
||||
"@theia/navigator": "1.25.0",
|
||||
"@theia/outline-view": "1.25.0",
|
||||
"@theia/output": "1.25.0",
|
||||
"@theia/preferences": "1.25.0",
|
||||
"@theia/search-in-workspace": "1.25.0",
|
||||
"@theia/terminal": "1.25.0",
|
||||
"@theia/workspace": "1.25.0",
|
||||
"@theia/application-package": "1.31.1",
|
||||
"@theia/core": "1.31.1",
|
||||
"@theia/debug": "1.31.1",
|
||||
"@theia/editor": "1.31.1",
|
||||
"@theia/electron": "1.31.1",
|
||||
"@theia/filesystem": "1.31.1",
|
||||
"@theia/keymaps": "1.31.1",
|
||||
"@theia/markers": "1.31.1",
|
||||
"@theia/messages": "1.31.1",
|
||||
"@theia/monaco": "1.31.1",
|
||||
"@theia/monaco-editor-core": "1.67.2",
|
||||
"@theia/navigator": "1.31.1",
|
||||
"@theia/outline-view": "1.31.1",
|
||||
"@theia/output": "1.31.1",
|
||||
"@theia/plugin-ext": "1.31.1",
|
||||
"@theia/preferences": "1.31.1",
|
||||
"@theia/scm": "1.31.1",
|
||||
"@theia/search-in-workspace": "1.31.1",
|
||||
"@theia/terminal": "1.31.1",
|
||||
"@theia/typehierarchy": "1.31.1",
|
||||
"@theia/workspace": "1.31.1",
|
||||
"@tippyjs/react": "^4.2.5",
|
||||
"@types/atob": "^2.1.2",
|
||||
"@types/auth0-js": "^9.14.0",
|
||||
"@types/btoa": "^1.2.3",
|
||||
"@types/dateformat": "^3.0.1",
|
||||
"@types/deep-equal": "^1.0.1",
|
||||
"@types/deepmerge": "^2.2.0",
|
||||
"@types/glob": "^7.2.0",
|
||||
"@types/google-protobuf": "^3.7.2",
|
||||
@ -50,49 +54,48 @@
|
||||
"@types/lodash.debounce": "^4.0.6",
|
||||
"@types/ncp": "^2.0.4",
|
||||
"@types/node-fetch": "^2.5.7",
|
||||
"@types/p-queue": "^2.3.1",
|
||||
"@types/ps-tree": "^1.1.0",
|
||||
"@types/react-select": "^3.0.0",
|
||||
"@types/react-tabs": "^2.3.2",
|
||||
"@types/react-virtualized": "^9.21.21",
|
||||
"@types/temp": "^0.8.34",
|
||||
"@types/which": "^1.3.1",
|
||||
"ajv": "^6.5.3",
|
||||
"arduino-serial-plotter-webapp": "0.2.0",
|
||||
"async-mutex": "^0.3.0",
|
||||
"atob": "^2.1.2",
|
||||
"auth0-js": "^9.14.0",
|
||||
"btoa": "^1.2.1",
|
||||
"classnames": "^2.3.1",
|
||||
"dateformat": "^3.0.3",
|
||||
"deep-equal": "^2.0.5",
|
||||
"deepmerge": "2.0.1",
|
||||
"electron-updater": "^4.6.5",
|
||||
"fast-safe-stringify": "^2.1.1",
|
||||
"glob": "^7.1.6",
|
||||
"google-protobuf": "^3.20.1",
|
||||
"hash.js": "^1.1.7",
|
||||
"is-valid-path": "^0.1.1",
|
||||
"js-yaml": "^3.13.1",
|
||||
"jwt-decode": "^3.1.2",
|
||||
"keytar": "7.2.0",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"minimatch": "^3.1.2",
|
||||
"ncp": "^2.0.0",
|
||||
"node-fetch": "^2.6.1",
|
||||
"open": "^8.0.6",
|
||||
"p-queue": "^5.0.0",
|
||||
"p-debounce": "^2.1.0",
|
||||
"p-queue": "^2.4.2",
|
||||
"ps-tree": "^1.2.0",
|
||||
"query-string": "^7.0.1",
|
||||
"react-disable": "^0.1.0",
|
||||
"react-disable": "^0.1.1",
|
||||
"react-markdown": "^8.0.0",
|
||||
"react-select": "^3.0.4",
|
||||
"react-perfect-scrollbar": "^1.5.8",
|
||||
"react-select": "^5.6.0",
|
||||
"react-tabs": "^3.1.2",
|
||||
"react-virtualized": "^9.22.3",
|
||||
"react-window": "^1.8.6",
|
||||
"semver": "^7.3.2",
|
||||
"string-natural-compare": "^2.0.3",
|
||||
"temp": "^0.9.1",
|
||||
"temp-dir": "^2.0.0",
|
||||
"tree-kill": "^1.2.1",
|
||||
"upath": "^1.1.2",
|
||||
"url": "^0.11.0",
|
||||
"which": "^1.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -101,11 +104,10 @@
|
||||
"@types/chai-string": "^1.4.2",
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/react-window": "^1.8.5",
|
||||
"@types/sinon": "^10.0.6",
|
||||
"@types/sinon-chai": "^3.2.6",
|
||||
"chai": "^4.2.0",
|
||||
"chai-string": "^1.5.0",
|
||||
"decompress": "^4.2.0",
|
||||
"decompress-tarbz2": "^4.1.1",
|
||||
"decompress-targz": "^4.1.1",
|
||||
"decompress-unzip": "^4.0.1",
|
||||
"download": "^7.1.0",
|
||||
@ -115,9 +117,6 @@
|
||||
"moment": "^2.24.0",
|
||||
"protoc": "^1.0.4",
|
||||
"shelljs": "^0.8.3",
|
||||
"sinon": "^12.0.1",
|
||||
"sinon-chai": "^3.7.0",
|
||||
"typemoq": "^2.1.0",
|
||||
"uuid": "^3.2.1",
|
||||
"yargs": "^11.1.0"
|
||||
},
|
||||
|
@ -3,10 +3,7 @@ import { ContainerModule } from '@theia/core/shared/inversify';
|
||||
import { WidgetFactory } from '@theia/core/lib/browser/widget-manager';
|
||||
import { CommandContribution } from '@theia/core/lib/common/command';
|
||||
import { bindViewContribution } from '@theia/core/lib/browser/shell/view-contribution';
|
||||
import {
|
||||
TabBarToolbarContribution,
|
||||
TabBarToolbarFactory,
|
||||
} from '@theia/core/lib/browser/shell/tab-bar-toolbar';
|
||||
import { TabBarToolbarContribution } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
|
||||
import { WebSocketConnectionProvider } from '@theia/core/lib/browser/messaging/ws-connection-provider';
|
||||
import {
|
||||
FrontendApplicationContribution,
|
||||
@ -84,10 +81,7 @@ import { BoardsAutoInstaller } from './boards/boards-auto-installer';
|
||||
import { ShellLayoutRestorer } from './theia/core/shell-layout-restorer';
|
||||
import { ListItemRenderer } from './widgets/component-list/list-item-renderer';
|
||||
import { ColorContribution } from '@theia/core/lib/browser/color-application-contribution';
|
||||
import {
|
||||
MonacoThemeJson,
|
||||
MonacoThemingService,
|
||||
} from '@theia/monaco/lib/browser/monaco-theming-service';
|
||||
|
||||
import {
|
||||
ArduinoDaemonPath,
|
||||
ArduinoDaemon,
|
||||
@ -137,7 +131,6 @@ import { Settings } from './contributions/settings';
|
||||
import { WorkspaceCommandContribution } from './theia/workspace/workspace-commands';
|
||||
import { WorkspaceDeleteHandler as TheiaWorkspaceDeleteHandler } from '@theia/workspace/lib/browser/workspace-delete-handler';
|
||||
import { WorkspaceDeleteHandler } from './theia/workspace/workspace-delete-handler';
|
||||
import { TabBarToolbar } from './theia/core/tab-bar-toolbar';
|
||||
import { EditorWidgetFactory as TheiaEditorWidgetFactory } from '@theia/editor/lib/browser/editor-widget-factory';
|
||||
import { EditorWidgetFactory } from './theia/editor/editor-widget-factory';
|
||||
import { BurnBootloader } from './contributions/burn-bootloader';
|
||||
@ -181,8 +174,6 @@ import { EditorCommandContribution } from './theia/editor/editor-command';
|
||||
import { NavigatorTabBarDecorator as TheiaNavigatorTabBarDecorator } from '@theia/navigator/lib/browser/navigator-tab-bar-decorator';
|
||||
import { NavigatorTabBarDecorator } from './theia/navigator/navigator-tab-bar-decorator';
|
||||
import { Debug } from './contributions/debug';
|
||||
import { DebugSessionManager } from './theia/debug/debug-session-manager';
|
||||
import { DebugSessionManager as TheiaDebugSessionManager } from '@theia/debug/lib/browser/debug-session-manager';
|
||||
import { Sketchbook } from './contributions/sketchbook';
|
||||
import { DebugFrontendApplicationContribution } from './theia/debug/debug-frontend-application-contribution';
|
||||
import { DebugFrontendApplicationContribution as TheiaDebugFrontendApplicationContribution } from '@theia/debug/lib/browser/debug-frontend-application-contribution';
|
||||
@ -241,7 +232,6 @@ import { UploadFirmware } from './contributions/upload-firmware';
|
||||
import {
|
||||
UploadFirmwareDialog,
|
||||
UploadFirmwareDialogProps,
|
||||
UploadFirmwareDialogWidget,
|
||||
} from './dialogs/firmware-uploader/firmware-uploader-dialog';
|
||||
|
||||
import { UploadCertificate } from './contributions/upload-certificate';
|
||||
@ -258,7 +248,6 @@ import { PlotterFrontendContribution } from './serial/plotter/plotter-frontend-c
|
||||
import {
|
||||
UserFieldsDialog,
|
||||
UserFieldsDialogProps,
|
||||
UserFieldsDialogWidget,
|
||||
} from './dialogs/user-fields/user-fields-dialog';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { IDEUpdaterCommands } from './ide-updater/ide-updater-commands';
|
||||
@ -271,7 +260,6 @@ import { IDEUpdaterClientImpl } from './ide-updater/ide-updater-client-impl';
|
||||
import {
|
||||
IDEUpdaterDialog,
|
||||
IDEUpdaterDialogProps,
|
||||
IDEUpdaterDialogWidget,
|
||||
} from './dialogs/ide-updater/ide-updater-dialog';
|
||||
import { ElectronIpcConnectionProvider } from '@theia/core/lib/electron-browser/messaging/electron-ipc-connection-provider';
|
||||
import { MonitorModel } from './monitor-model';
|
||||
@ -313,10 +301,6 @@ import { SelectedBoard } from './contributions/selected-board';
|
||||
import { CheckForIDEUpdates } from './contributions/check-for-ide-updates';
|
||||
import { OpenBoardsConfig } from './contributions/open-boards-config';
|
||||
import { SketchFilesTracker } from './contributions/sketch-files-tracker';
|
||||
import { MonacoThemeServiceIsReady } from './utils/window';
|
||||
import { Deferred } from '@theia/core/lib/common/promise-util';
|
||||
import { StatusBarImpl } from './theia/core/status-bar';
|
||||
import { StatusBarImpl as TheiaStatusBarImpl } from '@theia/core/lib/browser';
|
||||
import { EditorMenuContribution } from './theia/editor/editor-file';
|
||||
import { EditorMenuContribution as TheiaEditorMenuContribution } from '@theia/editor/lib/browser/editor-menu';
|
||||
import { PreferencesEditorWidget as TheiaPreferencesEditorWidget } from '@theia/preferences/lib/browser/views/preference-editor-widget';
|
||||
@ -337,32 +321,16 @@ import { InterfaceScale } from './contributions/interface-scale';
|
||||
import { OpenHandler } from '@theia/core/lib/browser/opener-service';
|
||||
import { NewCloudSketch } from './contributions/new-cloud-sketch';
|
||||
import { SketchbookCompositeWidget } from './widgets/sketchbook/sketchbook-composite-widget';
|
||||
|
||||
const registerArduinoThemes = () => {
|
||||
const themes: MonacoThemeJson[] = [
|
||||
{
|
||||
id: 'arduino-theme',
|
||||
label: 'Light (Arduino)',
|
||||
uiTheme: 'vs',
|
||||
json: require('../../src/browser/data/default.color-theme.json'),
|
||||
},
|
||||
{
|
||||
id: 'arduino-theme-dark',
|
||||
label: 'Dark (Arduino)',
|
||||
uiTheme: 'vs-dark',
|
||||
json: require('../../src/browser/data/dark.color-theme.json'),
|
||||
},
|
||||
];
|
||||
themes.forEach((theme) => MonacoThemingService.register(theme));
|
||||
};
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const global = window as any;
|
||||
const ready = global[MonacoThemeServiceIsReady] as Deferred;
|
||||
if (ready) {
|
||||
ready.promise.then(registerArduinoThemes);
|
||||
} else {
|
||||
registerArduinoThemes();
|
||||
}
|
||||
import { WindowTitleUpdater } from './theia/core/window-title-updater';
|
||||
import { WindowTitleUpdater as TheiaWindowTitleUpdater } from '@theia/core/lib/browser/window/window-title-updater';
|
||||
import { ThemeService } from './theia/core/theming';
|
||||
import { ThemeService as TheiaThemeService } from '@theia/core/lib/browser/theming';
|
||||
import { MonacoThemingService } from './theia/monaco/monaco-theming-service';
|
||||
import { MonacoThemingService as TheiaMonacoThemingService } from '@theia/monaco/lib/browser/monaco-theming-service';
|
||||
import { TypeHierarchyServiceProvider } from './theia/typehierarchy/type-hierarchy-service';
|
||||
import { TypeHierarchyServiceProvider as TheiaTypeHierarchyServiceProvider } from '@theia/typehierarchy/lib/browser/typehierarchy-service';
|
||||
import { TypeHierarchyContribution } from './theia/typehierarchy/type-hierarchy-contribution';
|
||||
import { TypeHierarchyContribution as TheiaTypeHierarchyContribution } from '@theia/typehierarchy/lib/browser/typehierarchy-contribution';
|
||||
|
||||
export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
// Commands and toolbar items
|
||||
@ -587,14 +555,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
.to(WorkspaceDeleteHandler)
|
||||
.inSingletonScope();
|
||||
rebind(TheiaEditorWidgetFactory).to(EditorWidgetFactory).inSingletonScope();
|
||||
rebind(TabBarToolbarFactory).toFactory(
|
||||
({ container: parentContainer }) =>
|
||||
() => {
|
||||
const container = parentContainer.createChild();
|
||||
container.bind(TabBarToolbar).toSelf().inSingletonScope();
|
||||
return container.get(TabBarToolbar);
|
||||
}
|
||||
);
|
||||
bind(OutputChannelManager).toSelf().inSingletonScope();
|
||||
rebind(TheiaOutputChannelManager).toService(OutputChannelManager);
|
||||
bind(OutputChannelRegistryMainImpl).toSelf().inTransientScope();
|
||||
@ -838,9 +798,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
bind(AboutDialog).toSelf().inSingletonScope();
|
||||
rebind(TheiaAboutDialog).toService(AboutDialog);
|
||||
|
||||
// To avoid running `Save All` when there are no dirty editors before starting the debug session.
|
||||
bind(DebugSessionManager).toSelf().inSingletonScope();
|
||||
rebind(TheiaDebugSessionManager).toService(DebugSessionManager);
|
||||
// To remove the `Run` menu item from the application menu.
|
||||
bind(DebugFrontendApplicationContribution).toSelf().inSingletonScope();
|
||||
rebind(TheiaDebugFrontendApplicationContribution).toService(
|
||||
@ -854,10 +811,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
bind(WidgetManager).toSelf().inSingletonScope();
|
||||
rebind(TheiaWidgetManager).toService(WidgetManager);
|
||||
|
||||
// To avoid running a status bar update on every single `keypress` event from the editor.
|
||||
bind(StatusBarImpl).toSelf().inSingletonScope();
|
||||
rebind(TheiaStatusBarImpl).toService(StatusBarImpl);
|
||||
|
||||
// Debounced update for the tab-bar toolbar when typing in the editor.
|
||||
bind(DockPanelRenderer).toSelf();
|
||||
rebind(TheiaDockPanelRenderer).toService(DockPanelRenderer);
|
||||
@ -942,12 +895,11 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
bind(LocalCacheFsProvider).toSelf().inSingletonScope();
|
||||
bind(FileServiceContribution).toService(LocalCacheFsProvider);
|
||||
bind(CloudSketchbookCompositeWidget).toSelf();
|
||||
bind<WidgetFactory>(WidgetFactory).toDynamicValue((ctx) => ({
|
||||
bind(WidgetFactory).toDynamicValue((ctx) => ({
|
||||
id: 'cloud-sketchbook-composite-widget',
|
||||
createWidget: () => ctx.container.get(CloudSketchbookCompositeWidget),
|
||||
}));
|
||||
|
||||
bind(UploadFirmwareDialogWidget).toSelf().inSingletonScope();
|
||||
bind(UploadFirmwareDialog).toSelf().inSingletonScope();
|
||||
bind(UploadFirmwareDialogProps).toConstantValue({
|
||||
title: 'UploadFirmware',
|
||||
@ -958,13 +910,11 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
title: 'UploadCertificate',
|
||||
});
|
||||
|
||||
bind(IDEUpdaterDialogWidget).toSelf().inSingletonScope();
|
||||
bind(IDEUpdaterDialog).toSelf().inSingletonScope();
|
||||
bind(IDEUpdaterDialogProps).toConstantValue({
|
||||
title: 'IDEUpdater',
|
||||
});
|
||||
|
||||
bind(UserFieldsDialogWidget).toSelf().inSingletonScope();
|
||||
bind(UserFieldsDialog).toSelf().inSingletonScope();
|
||||
bind(UserFieldsDialogProps).toConstantValue({
|
||||
title: 'UserFields',
|
||||
@ -991,4 +941,23 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
rebind(TheiaHostedPluginSupport).toService(HostedPluginSupport);
|
||||
bind(HostedPluginEvents).toSelf().inSingletonScope();
|
||||
bind(FrontendApplicationContribution).toService(HostedPluginEvents);
|
||||
|
||||
// custom window titles
|
||||
bind(WindowTitleUpdater).toSelf().inSingletonScope();
|
||||
rebind(TheiaWindowTitleUpdater).toService(WindowTitleUpdater);
|
||||
|
||||
// register Arduino themes
|
||||
bind(ThemeService).toSelf().inSingletonScope();
|
||||
rebind(TheiaThemeService).toService(ThemeService);
|
||||
bind(MonacoThemingService).toSelf().inSingletonScope();
|
||||
rebind(TheiaMonacoThemingService).toService(MonacoThemingService);
|
||||
|
||||
// disable type-hierarchy support
|
||||
// https://github.com/eclipse-theia/theia/commit/16c88a584bac37f5cf3cc5eb92ffdaa541bda5be
|
||||
bind(TypeHierarchyServiceProvider).toSelf().inSingletonScope();
|
||||
rebind(TheiaTypeHierarchyServiceProvider).toService(
|
||||
TypeHierarchyServiceProvider
|
||||
);
|
||||
bind(TypeHierarchyContribution).toSelf().inSingletonScope();
|
||||
rebind(TheiaTypeHierarchyContribution).toService(TypeHierarchyContribution);
|
||||
});
|
||||
|
@ -235,7 +235,7 @@ export class SketchControl extends SketchContribution {
|
||||
});
|
||||
registry.registerKeybinding({
|
||||
command: CommonCommands.PREVIOUS_TAB.id,
|
||||
keybinding: 'CtrlCmd+Alt+Left', // TODO: check why electron does not show the keybindings in the UI.
|
||||
keybinding: 'CtrlCmd+Alt+Left',
|
||||
});
|
||||
registry.registerKeybinding({
|
||||
command: CommonCommands.NEXT_TAB.id,
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { URI as Uri } from 'vscode-uri';
|
||||
import { URI as Uri } from '@theia/core/shared/vscode-uri';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { toPosixPath, parentPosix, posix } from './create-paths';
|
||||
import { Create } from './typings';
|
||||
|
@ -5,10 +5,8 @@ import {
|
||||
postConstruct,
|
||||
} from '@theia/core/shared/inversify';
|
||||
import { DialogProps } from '@theia/core/lib/browser/dialogs';
|
||||
import { AbstractDialog } from '../../theia/dialogs/dialogs';
|
||||
import { Widget } from '@theia/core/shared/@phosphor/widgets';
|
||||
import { ReactDialog } from '../../theia/dialogs/dialogs';
|
||||
import { Message } from '@theia/core/shared/@phosphor/messaging';
|
||||
import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget';
|
||||
import {
|
||||
AvailableBoard,
|
||||
BoardsServiceProvider,
|
||||
@ -23,26 +21,30 @@ import { Port } from '../../../common/protocol';
|
||||
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
||||
|
||||
@injectable()
|
||||
export class UploadFirmwareDialogWidget extends ReactWidget {
|
||||
export class UploadFirmwareDialogProps extends DialogProps {}
|
||||
|
||||
@injectable()
|
||||
export class UploadFirmwareDialog extends ReactDialog<void> {
|
||||
@inject(BoardsServiceProvider)
|
||||
protected readonly boardsServiceClient: BoardsServiceProvider;
|
||||
|
||||
private readonly boardsServiceClient: BoardsServiceProvider;
|
||||
@inject(ArduinoFirmwareUploader)
|
||||
protected readonly arduinoFirmwareUploader: ArduinoFirmwareUploader;
|
||||
|
||||
private readonly arduinoFirmwareUploader: ArduinoFirmwareUploader;
|
||||
@inject(FrontendApplicationStateService)
|
||||
private readonly appStatusService: FrontendApplicationStateService;
|
||||
|
||||
protected updatableFqbns: string[] = [];
|
||||
protected availableBoards: AvailableBoard[] = [];
|
||||
protected isOpen = new Object();
|
||||
private updatableFqbns: string[] = [];
|
||||
private availableBoards: AvailableBoard[] = [];
|
||||
private isOpen = new Object();
|
||||
private busy = false;
|
||||
|
||||
public busyCallback = (busy: boolean) => {
|
||||
return;
|
||||
};
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
constructor(
|
||||
@inject(UploadFirmwareDialogProps)
|
||||
protected override readonly props: UploadFirmwareDialogProps
|
||||
) {
|
||||
super({ title: UploadFirmware.Commands.OPEN.label || '' });
|
||||
this.node.id = 'firmware-uploader-dialog-container';
|
||||
this.contentNode.classList.add('firmware-uploader-dialog');
|
||||
this.acceptButton = undefined;
|
||||
}
|
||||
|
||||
@postConstruct()
|
||||
@ -59,79 +61,34 @@ export class UploadFirmwareDialogWidget extends ReactWidget {
|
||||
});
|
||||
}
|
||||
|
||||
protected flashFirmware(firmware: FirmwareInfo, port: Port): Promise<any> {
|
||||
this.busyCallback(true);
|
||||
return this.arduinoFirmwareUploader
|
||||
.flash(firmware, port)
|
||||
.finally(() => this.busyCallback(false));
|
||||
}
|
||||
|
||||
protected override onCloseRequest(msg: Message): void {
|
||||
super.onCloseRequest(msg);
|
||||
this.isOpen = new Object();
|
||||
}
|
||||
|
||||
protected render(): React.ReactNode {
|
||||
return (
|
||||
<form>
|
||||
<FirmwareUploaderComponent
|
||||
availableBoards={this.availableBoards}
|
||||
firmwareUploader={this.arduinoFirmwareUploader}
|
||||
flashFirmware={this.flashFirmware.bind(this)}
|
||||
updatableFqbns={this.updatableFqbns}
|
||||
isOpen={this.isOpen}
|
||||
/>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@injectable()
|
||||
export class UploadFirmwareDialogProps extends DialogProps {}
|
||||
|
||||
@injectable()
|
||||
export class UploadFirmwareDialog extends AbstractDialog<void> {
|
||||
@inject(UploadFirmwareDialogWidget)
|
||||
protected readonly widget: UploadFirmwareDialogWidget;
|
||||
|
||||
private busy = false;
|
||||
|
||||
constructor(
|
||||
@inject(UploadFirmwareDialogProps)
|
||||
protected override readonly props: UploadFirmwareDialogProps
|
||||
) {
|
||||
super({ title: UploadFirmware.Commands.OPEN.label || '' });
|
||||
this.node.id = 'firmware-uploader-dialog-container';
|
||||
this.contentNode.classList.add('firmware-uploader-dialog');
|
||||
this.acceptButton = undefined;
|
||||
}
|
||||
|
||||
get value(): void {
|
||||
return;
|
||||
}
|
||||
|
||||
protected override render(): React.ReactNode {
|
||||
return (
|
||||
<div>
|
||||
<form>
|
||||
<FirmwareUploaderComponent
|
||||
availableBoards={this.availableBoards}
|
||||
firmwareUploader={this.arduinoFirmwareUploader}
|
||||
flashFirmware={this.flashFirmware.bind(this)}
|
||||
updatableFqbns={this.updatableFqbns}
|
||||
isOpen={this.isOpen}
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
protected override onAfterAttach(msg: Message): void {
|
||||
if (this.widget.isAttached) {
|
||||
Widget.detach(this.widget);
|
||||
}
|
||||
Widget.attach(this.widget, this.contentNode);
|
||||
const firstButton = this.widget.node.querySelector('button');
|
||||
const firstButton = this.node.querySelector('button');
|
||||
firstButton?.focus();
|
||||
this.widget.busyCallback = this.busyCallback.bind(this);
|
||||
super.onAfterAttach(msg);
|
||||
this.update();
|
||||
}
|
||||
|
||||
protected override onUpdateRequest(msg: Message): void {
|
||||
super.onUpdateRequest(msg);
|
||||
this.widget.update();
|
||||
}
|
||||
|
||||
protected override onActivateRequest(msg: Message): void {
|
||||
super.onActivateRequest(msg);
|
||||
this.widget.activate();
|
||||
}
|
||||
|
||||
// eslint-disable-next-line unused-imports/no-unused-vars, @typescript-eslint/no-unused-vars
|
||||
protected override handleEnter(event: KeyboardEvent): boolean | void {
|
||||
return false;
|
||||
}
|
||||
@ -140,11 +97,11 @@ export class UploadFirmwareDialog extends AbstractDialog<void> {
|
||||
if (this.busy) {
|
||||
return;
|
||||
}
|
||||
this.widget.close();
|
||||
super.close();
|
||||
this.isOpen = new Object();
|
||||
}
|
||||
|
||||
busyCallback(busy: boolean): void {
|
||||
private busyCallback(busy: boolean): void {
|
||||
this.busy = busy;
|
||||
if (busy) {
|
||||
this.closeCrossNode.classList.add('disabled');
|
||||
@ -152,4 +109,11 @@ export class UploadFirmwareDialog extends AbstractDialog<void> {
|
||||
this.closeCrossNode.classList.remove('disabled');
|
||||
}
|
||||
}
|
||||
|
||||
private flashFirmware(firmware: FirmwareInfo, port: Port): Promise<any> {
|
||||
this.busyCallback(true);
|
||||
return this.arduinoFirmwareUploader
|
||||
.flash(firmware, port)
|
||||
.finally(() => this.busyCallback(false));
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
import { shell } from 'electron';
|
||||
import { shell } from '@theia/core/electron-shared/@electron/remote';
|
||||
import * as React from '@theia/core/shared/react';
|
||||
import * as ReactDOM from '@theia/core/shared/react-dom';
|
||||
import ReactMarkdown from 'react-markdown';
|
||||
import { ProgressInfo, UpdateInfo } from '../../../common/protocol/ide-updater';
|
||||
import ProgressBar from '../../components/ProgressBar';
|
||||
@ -28,32 +27,19 @@ export const IDEUpdaterComponent = ({
|
||||
},
|
||||
}: IDEUpdaterComponentProps): React.ReactElement => {
|
||||
const { version, releaseNotes } = updateInfo;
|
||||
const changelogDivRef =
|
||||
React.useRef() as React.MutableRefObject<HTMLDivElement>;
|
||||
const [changelog, setChangelog] = React.useState<string>('');
|
||||
React.useEffect(() => {
|
||||
if (!!releaseNotes && changelogDivRef.current) {
|
||||
let changelog: string;
|
||||
if (typeof releaseNotes === 'string') changelog = releaseNotes;
|
||||
else
|
||||
changelog = releaseNotes.reduce((acc, item) => {
|
||||
return item.note ? (acc += `${item.note}\n\n`) : acc;
|
||||
}, '');
|
||||
ReactDOM.render(
|
||||
<ReactMarkdown
|
||||
components={{
|
||||
a: ({ href, children, ...props }) => (
|
||||
<a onClick={() => href && shell.openExternal(href)} {...props}>
|
||||
{children}
|
||||
</a>
|
||||
),
|
||||
}}
|
||||
>
|
||||
{changelog}
|
||||
</ReactMarkdown>,
|
||||
changelogDivRef.current
|
||||
if (releaseNotes) {
|
||||
setChangelog(
|
||||
typeof releaseNotes === 'string'
|
||||
? releaseNotes
|
||||
: releaseNotes.reduce(
|
||||
(acc, item) => (item.note ? (acc += `${item.note}\n\n`) : acc),
|
||||
''
|
||||
)
|
||||
);
|
||||
}
|
||||
}, [updateInfo]);
|
||||
}, [releaseNotes, changelog]);
|
||||
|
||||
const DownloadCompleted: () => React.ReactElement = () => (
|
||||
<div className="ide-updater-dialog--downloaded">
|
||||
@ -106,9 +92,24 @@ export const IDEUpdaterComponent = ({
|
||||
version
|
||||
)}
|
||||
</div>
|
||||
{releaseNotes && (
|
||||
{changelog && (
|
||||
<div className="dialogRow changelog-container">
|
||||
<div className="changelog" ref={changelogDivRef} />
|
||||
<div className="changelog">
|
||||
<ReactMarkdown
|
||||
components={{
|
||||
a: ({ href, children, ...props }) => (
|
||||
<a
|
||||
onClick={() => href && shell.openExternal(href)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</a>
|
||||
),
|
||||
}}
|
||||
>
|
||||
{changelog}
|
||||
</ReactMarkdown>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
@ -5,10 +5,8 @@ import {
|
||||
postConstruct,
|
||||
} from '@theia/core/shared/inversify';
|
||||
import { DialogProps } from '@theia/core/lib/browser/dialogs';
|
||||
import { AbstractDialog } from '../../theia/dialogs/dialogs';
|
||||
import { Widget } from '@theia/core/shared/@phosphor/widgets';
|
||||
import { Message } from '@theia/core/shared/@phosphor/messaging';
|
||||
import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget';
|
||||
import { ReactDialog } from '../../theia/dialogs/dialogs';
|
||||
import { nls } from '@theia/core';
|
||||
import { IDEUpdaterComponent, UpdateProgress } from './ide-updater-component';
|
||||
import {
|
||||
@ -22,47 +20,11 @@ import { WindowService } from '@theia/core/lib/browser/window/window-service';
|
||||
|
||||
const DOWNLOAD_PAGE_URL = 'https://www.arduino.cc/en/software';
|
||||
|
||||
@injectable()
|
||||
export class IDEUpdaterDialogWidget extends ReactWidget {
|
||||
private _updateInfo: UpdateInfo;
|
||||
private _updateProgress: UpdateProgress = {};
|
||||
|
||||
setUpdateInfo(updateInfo: UpdateInfo): void {
|
||||
this._updateInfo = updateInfo;
|
||||
this.update();
|
||||
}
|
||||
|
||||
mergeUpdateProgress(updateProgress: UpdateProgress): void {
|
||||
this._updateProgress = { ...this._updateProgress, ...updateProgress };
|
||||
this.update();
|
||||
}
|
||||
|
||||
get updateInfo(): UpdateInfo {
|
||||
return this._updateInfo;
|
||||
}
|
||||
|
||||
get updateProgress(): UpdateProgress {
|
||||
return this._updateProgress;
|
||||
}
|
||||
|
||||
protected render(): React.ReactNode {
|
||||
return !!this._updateInfo ? (
|
||||
<IDEUpdaterComponent
|
||||
updateInfo={this._updateInfo}
|
||||
updateProgress={this._updateProgress}
|
||||
/>
|
||||
) : null;
|
||||
}
|
||||
}
|
||||
|
||||
@injectable()
|
||||
export class IDEUpdaterDialogProps extends DialogProps {}
|
||||
|
||||
@injectable()
|
||||
export class IDEUpdaterDialog extends AbstractDialog<UpdateInfo> {
|
||||
@inject(IDEUpdaterDialogWidget)
|
||||
private readonly widget: IDEUpdaterDialogWidget;
|
||||
|
||||
export class IDEUpdaterDialog extends ReactDialog<UpdateInfo | undefined> {
|
||||
@inject(IDEUpdater)
|
||||
private readonly updater: IDEUpdater;
|
||||
|
||||
@ -75,6 +37,9 @@ export class IDEUpdaterDialog extends AbstractDialog<UpdateInfo> {
|
||||
@inject(WindowService)
|
||||
private readonly windowService: WindowService;
|
||||
|
||||
private _updateInfo: UpdateInfo | undefined;
|
||||
private _updateProgress: UpdateProgress = {};
|
||||
|
||||
constructor(
|
||||
@inject(IDEUpdaterDialogProps)
|
||||
protected override readonly props: IDEUpdaterDialogProps
|
||||
@ -94,26 +59,34 @@ export class IDEUpdaterDialog extends AbstractDialog<UpdateInfo> {
|
||||
protected init(): void {
|
||||
this.updaterClient.onUpdaterDidFail((error) => {
|
||||
this.appendErrorButtons();
|
||||
this.widget.mergeUpdateProgress({ error });
|
||||
this.mergeUpdateProgress({ error });
|
||||
});
|
||||
this.updaterClient.onDownloadProgressDidChange((progressInfo) => {
|
||||
this.widget.mergeUpdateProgress({ progressInfo });
|
||||
this.mergeUpdateProgress({ progressInfo });
|
||||
});
|
||||
this.updaterClient.onDownloadDidFinish(() => {
|
||||
this.appendInstallButtons();
|
||||
this.widget.mergeUpdateProgress({ downloadFinished: true });
|
||||
this.mergeUpdateProgress({ downloadFinished: true });
|
||||
});
|
||||
}
|
||||
|
||||
get value(): UpdateInfo {
|
||||
return this.widget.updateInfo;
|
||||
protected render(): React.ReactNode {
|
||||
return (
|
||||
this.updateInfo && (
|
||||
<IDEUpdaterComponent
|
||||
updateInfo={this.updateInfo}
|
||||
updateProgress={this.updateProgress}
|
||||
/>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
get value(): UpdateInfo | undefined {
|
||||
return this.updateInfo;
|
||||
}
|
||||
|
||||
protected override onAfterAttach(msg: Message): void {
|
||||
if (this.widget.isAttached) {
|
||||
Widget.detach(this.widget);
|
||||
}
|
||||
Widget.attach(this.widget, this.contentNode);
|
||||
this.update();
|
||||
this.appendInitialButtons();
|
||||
super.onAfterAttach(msg);
|
||||
}
|
||||
@ -196,15 +169,19 @@ export class IDEUpdaterDialog extends AbstractDialog<UpdateInfo> {
|
||||
}
|
||||
|
||||
private skipVersion(): void {
|
||||
if (!this.updateInfo) {
|
||||
console.warn(`Nothing to skip. No update info is available`);
|
||||
return;
|
||||
}
|
||||
this.localStorageService.setData<string>(
|
||||
SKIP_IDE_VERSION,
|
||||
this.widget.updateInfo.version
|
||||
this.updateInfo.version
|
||||
);
|
||||
this.close();
|
||||
}
|
||||
|
||||
private startDownload(): void {
|
||||
this.widget.mergeUpdateProgress({
|
||||
this.mergeUpdateProgress({
|
||||
downloadStarted: true,
|
||||
});
|
||||
this.clearButtons();
|
||||
@ -216,31 +193,48 @@ export class IDEUpdaterDialog extends AbstractDialog<UpdateInfo> {
|
||||
this.close();
|
||||
}
|
||||
|
||||
private set updateInfo(updateInfo: UpdateInfo | undefined) {
|
||||
this._updateInfo = updateInfo;
|
||||
this.update();
|
||||
}
|
||||
|
||||
private get updateInfo(): UpdateInfo | undefined {
|
||||
return this._updateInfo;
|
||||
}
|
||||
|
||||
private get updateProgress(): UpdateProgress {
|
||||
return this._updateProgress;
|
||||
}
|
||||
|
||||
private mergeUpdateProgress(updateProgress: UpdateProgress): void {
|
||||
this._updateProgress = { ...this._updateProgress, ...updateProgress };
|
||||
this.update();
|
||||
}
|
||||
|
||||
override async open(
|
||||
data: UpdateInfo | undefined = undefined
|
||||
): Promise<UpdateInfo | undefined> {
|
||||
if (data && data.version) {
|
||||
this.widget.mergeUpdateProgress({
|
||||
this.mergeUpdateProgress({
|
||||
progressInfo: undefined,
|
||||
downloadStarted: false,
|
||||
downloadFinished: false,
|
||||
error: undefined,
|
||||
});
|
||||
this.widget.setUpdateInfo(data);
|
||||
this.updateInfo = data;
|
||||
return super.open();
|
||||
}
|
||||
}
|
||||
|
||||
protected override onActivateRequest(msg: Message): void {
|
||||
super.onActivateRequest(msg);
|
||||
this.widget.activate();
|
||||
this.update();
|
||||
}
|
||||
|
||||
override close(): void {
|
||||
this.widget.dispose();
|
||||
if (
|
||||
this.widget.updateProgress?.downloadStarted &&
|
||||
!this.widget.updateProgress?.downloadFinished
|
||||
this.updateProgress?.downloadStarted &&
|
||||
!this.updateProgress?.downloadFinished
|
||||
) {
|
||||
this.updater.stopDownload();
|
||||
}
|
||||
|
@ -218,16 +218,14 @@ export class SettingsComponent extends React.Component<
|
||||
<div className="flex-line">
|
||||
<select
|
||||
className="theia-select"
|
||||
value={ThemeService.get().getCurrentTheme().label}
|
||||
value={this.props.themeService.getCurrentTheme().label}
|
||||
onChange={this.themeDidChange}
|
||||
>
|
||||
{ThemeService.get()
|
||||
.getThemes()
|
||||
.map(({ id, label }) => (
|
||||
<option key={id} value={label}>
|
||||
{label}
|
||||
</option>
|
||||
))}
|
||||
{this.props.themeService.getThemes().map(({ id, label }) => (
|
||||
<option key={id} value={label}>
|
||||
{label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div className="flex-line">
|
||||
@ -612,11 +610,11 @@ export class SettingsComponent extends React.Component<
|
||||
event: React.ChangeEvent<HTMLSelectElement>
|
||||
): void => {
|
||||
const { selectedIndex } = event.target.options;
|
||||
const theme = ThemeService.get().getThemes()[selectedIndex];
|
||||
const theme = this.props.themeService.getThemes()[selectedIndex];
|
||||
if (theme) {
|
||||
this.setState({ themeId: theme.id });
|
||||
if (ThemeService.get().getCurrentTheme().id !== theme.id) {
|
||||
ThemeService.get().setCurrentTheme(theme.id);
|
||||
if (this.props.themeService.getCurrentTheme().id !== theme.id) {
|
||||
this.props.themeService.setCurrentTheme(theme.id);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -755,6 +753,7 @@ export namespace SettingsComponent {
|
||||
readonly fileDialogService: FileDialogService;
|
||||
readonly windowService: WindowService;
|
||||
readonly localizationProvider: AsyncLocalizationProvider;
|
||||
readonly themeService: ThemeService;
|
||||
}
|
||||
export type State = Settings & {
|
||||
rawAdditionalUrlsValue: string;
|
||||
|
@ -35,6 +35,9 @@ export class SettingsWidget extends ReactWidget {
|
||||
@inject(AsyncLocalizationProvider)
|
||||
protected readonly localizationProvider: AsyncLocalizationProvider;
|
||||
|
||||
@inject(ThemeService)
|
||||
private readonly themeService: ThemeService;
|
||||
|
||||
protected render(): React.ReactNode {
|
||||
return (
|
||||
<SettingsComponent
|
||||
@ -43,6 +46,7 @@ export class SettingsWidget extends ReactWidget {
|
||||
fileDialogService={this.fileDialogService}
|
||||
windowService={this.windowService}
|
||||
localizationProvider={this.localizationProvider}
|
||||
themeService={this.themeService}
|
||||
/>
|
||||
);
|
||||
}
|
||||
@ -59,6 +63,9 @@ export class SettingsDialog extends AbstractDialog<Promise<Settings>> {
|
||||
@inject(SettingsWidget)
|
||||
protected readonly widget: SettingsWidget;
|
||||
|
||||
@inject(ThemeService)
|
||||
private readonly themeService: ThemeService;
|
||||
|
||||
constructor(
|
||||
@inject(SettingsDialogProps)
|
||||
protected override readonly props: SettingsDialogProps
|
||||
@ -121,11 +128,11 @@ export class SettingsDialog extends AbstractDialog<Promise<Settings>> {
|
||||
}
|
||||
|
||||
override async open(): Promise<Promise<Settings> | undefined> {
|
||||
const themeIdBeforeOpen = ThemeService.get().getCurrentTheme().id;
|
||||
const themeIdBeforeOpen = this.themeService.getCurrentTheme().id;
|
||||
const result = await super.open();
|
||||
if (!result) {
|
||||
if (ThemeService.get().getCurrentTheme().id !== themeIdBeforeOpen) {
|
||||
ThemeService.get().setCurrentTheme(themeIdBeforeOpen);
|
||||
if (this.themeService.getCurrentTheme().id !== themeIdBeforeOpen) {
|
||||
this.themeService.setCurrentTheme(themeIdBeforeOpen);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
@ -5,7 +5,7 @@ import {
|
||||
} from '@theia/core/shared/inversify';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { Emitter } from '@theia/core/lib/common/event';
|
||||
import { Deferred, timeout } from '@theia/core/lib/common/promise-util';
|
||||
import { Deferred } from '@theia/core/lib/common/promise-util';
|
||||
import { deepClone } from '@theia/core/lib/common/objects';
|
||||
import { FileService } from '@theia/filesystem/lib/browser/file-service';
|
||||
import { ThemeService } from '@theia/core/lib/browser/theming';
|
||||
@ -25,6 +25,8 @@ import {
|
||||
LanguageInfo,
|
||||
} from '@theia/core/lib/common/i18n/localization';
|
||||
import { ElectronCommands } from '@theia/core/lib/electron-browser/menu/electron-menu-contribution';
|
||||
import { DefaultTheme } from '@theia/application-package/lib/application-props';
|
||||
import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider';
|
||||
|
||||
export const EDITOR_SETTING = 'editor';
|
||||
export const FONT_SIZE_SETTING = `${EDITOR_SETTING}.fontSize`;
|
||||
@ -101,6 +103,9 @@ export class SettingsService {
|
||||
@inject(CommandService)
|
||||
protected commandService: CommandService;
|
||||
|
||||
@inject(ThemeService)
|
||||
private readonly themeService: ThemeService;
|
||||
|
||||
protected readonly onDidChangeEmitter = new Emitter<Readonly<Settings>>();
|
||||
readonly onDidChange = this.onDidChangeEmitter.event;
|
||||
protected readonly onDidResetEmitter = new Emitter<Readonly<Settings>>();
|
||||
@ -141,10 +146,9 @@ export class SettingsService {
|
||||
this.preferenceService.get<number>(FONT_SIZE_SETTING, 12),
|
||||
this.preferenceService.get<string>(
|
||||
'workbench.colorTheme',
|
||||
window.matchMedia &&
|
||||
window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
? 'arduino-theme-dark'
|
||||
: 'arduino-theme'
|
||||
DefaultTheme.defaultForOSTheme(
|
||||
FrontendApplicationConfigProvider.get().defaultTheme
|
||||
)
|
||||
),
|
||||
this.preferenceService.get<Settings.AutoSave>(
|
||||
AUTO_SAVE_SETTING,
|
||||
@ -231,11 +235,7 @@ export class SettingsService {
|
||||
'Invalid editor font size. It must be a positive integer.'
|
||||
);
|
||||
}
|
||||
if (
|
||||
!ThemeService.get()
|
||||
.getThemes()
|
||||
.find(({ id }) => id === themeId)
|
||||
) {
|
||||
if (!this.themeService.getThemes().find(({ id }) => id === themeId)) {
|
||||
return nls.localize(
|
||||
'arduino/preferences/invalid.theme',
|
||||
'Invalid theme.'
|
||||
@ -252,7 +252,6 @@ export class SettingsService {
|
||||
|
||||
private async savePreference(name: string, value: unknown): Promise<void> {
|
||||
await this.preferenceService.set(name, value, PreferenceScope.User);
|
||||
await timeout(5);
|
||||
}
|
||||
|
||||
async save(): Promise<string | true> {
|
||||
@ -283,19 +282,21 @@ export class SettingsService {
|
||||
(config as any).network = network;
|
||||
(config as any).locale = currentLanguage;
|
||||
|
||||
await this.savePreference('editor.fontSize', editorFontSize);
|
||||
await this.savePreference('workbench.colorTheme', themeId);
|
||||
await this.savePreference(AUTO_SAVE_SETTING, autoSave);
|
||||
await this.savePreference('editor.quickSuggestions', quickSuggestions);
|
||||
await this.savePreference(AUTO_SCALE_SETTING, autoScaleInterface);
|
||||
await this.savePreference(ZOOM_LEVEL_SETTING, interfaceScale);
|
||||
await this.savePreference(ZOOM_LEVEL_SETTING, interfaceScale);
|
||||
await this.savePreference(COMPILE_VERBOSE_SETTING, verboseOnCompile);
|
||||
await this.savePreference(COMPILE_WARNINGS_SETTING, compilerWarnings);
|
||||
await this.savePreference(UPLOAD_VERBOSE_SETTING, verboseOnUpload);
|
||||
await this.savePreference(UPLOAD_VERIFY_SETTING, verifyAfterUpload);
|
||||
await this.savePreference(SHOW_ALL_FILES_SETTING, sketchbookShowAllFiles);
|
||||
await this.configService.setConfiguration(config);
|
||||
await Promise.all([
|
||||
this.savePreference('editor.fontSize', editorFontSize),
|
||||
this.savePreference('workbench.colorTheme', themeId),
|
||||
this.savePreference(AUTO_SAVE_SETTING, autoSave),
|
||||
this.savePreference('editor.quickSuggestions', quickSuggestions),
|
||||
this.savePreference(AUTO_SCALE_SETTING, autoScaleInterface),
|
||||
this.savePreference(ZOOM_LEVEL_SETTING, interfaceScale),
|
||||
this.savePreference(ZOOM_LEVEL_SETTING, interfaceScale),
|
||||
this.savePreference(COMPILE_VERBOSE_SETTING, verboseOnCompile),
|
||||
this.savePreference(COMPILE_WARNINGS_SETTING, compilerWarnings),
|
||||
this.savePreference(UPLOAD_VERBOSE_SETTING, verboseOnUpload),
|
||||
this.savePreference(UPLOAD_VERIFY_SETTING, verifyAfterUpload),
|
||||
this.savePreference(SHOW_ALL_FILES_SETTING, sketchbookShowAllFiles),
|
||||
this.configService.setConfiguration(config),
|
||||
]);
|
||||
this.onDidChangeEmitter.fire(this._settings);
|
||||
|
||||
// after saving all the settings, if we need to change the language we need to perform a reload
|
||||
|
@ -1,63 +1,18 @@
|
||||
import * as React from '@theia/core/shared/react';
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import {
|
||||
AbstractDialog,
|
||||
DialogProps,
|
||||
ReactWidget,
|
||||
} from '@theia/core/lib/browser';
|
||||
import { Widget } from '@theia/core/shared/@phosphor/widgets';
|
||||
import { DialogProps } from '@theia/core/lib/browser/dialogs';
|
||||
import { Message } from '@theia/core/shared/@phosphor/messaging';
|
||||
import { UploadSketch } from '../../contributions/upload-sketch';
|
||||
import { UserFieldsComponent } from './user-fields-component';
|
||||
import { BoardUserField } from '../../../common/protocol';
|
||||
|
||||
@injectable()
|
||||
export class UserFieldsDialogWidget extends ReactWidget {
|
||||
private _currentUserFields: BoardUserField[] = [];
|
||||
|
||||
constructor(private cancel: () => void, private accept: () => Promise<void>) {
|
||||
super();
|
||||
}
|
||||
|
||||
set currentUserFields(userFields: BoardUserField[]) {
|
||||
this.setUserFields(userFields);
|
||||
}
|
||||
|
||||
get currentUserFields(): BoardUserField[] {
|
||||
return this._currentUserFields;
|
||||
}
|
||||
|
||||
resetUserFieldsValue(): void {
|
||||
this._currentUserFields = this._currentUserFields.map((field) => {
|
||||
field.value = '';
|
||||
return field;
|
||||
});
|
||||
}
|
||||
|
||||
private setUserFields(userFields: BoardUserField[]): void {
|
||||
this._currentUserFields = userFields;
|
||||
}
|
||||
|
||||
protected render(): React.ReactNode {
|
||||
return (
|
||||
<form>
|
||||
<UserFieldsComponent
|
||||
initialBoardUserFields={this._currentUserFields}
|
||||
updateUserFields={this.setUserFields.bind(this)}
|
||||
cancel={this.cancel}
|
||||
accept={this.accept}
|
||||
/>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
}
|
||||
import { ReactDialog } from '../../theia/dialogs/dialogs';
|
||||
|
||||
@injectable()
|
||||
export class UserFieldsDialogProps extends DialogProps {}
|
||||
|
||||
@injectable()
|
||||
export class UserFieldsDialog extends AbstractDialog<BoardUserField[]> {
|
||||
protected readonly widget: UserFieldsDialogWidget;
|
||||
export class UserFieldsDialog extends ReactDialog<BoardUserField[]> {
|
||||
private _currentUserFields: BoardUserField[] = [];
|
||||
|
||||
constructor(
|
||||
@inject(UserFieldsDialogProps)
|
||||
@ -69,39 +24,36 @@ export class UserFieldsDialog extends AbstractDialog<BoardUserField[]> {
|
||||
this.titleNode.classList.add('user-fields-dialog-title');
|
||||
this.contentNode.classList.add('user-fields-dialog-content');
|
||||
this.acceptButton = undefined;
|
||||
this.widget = new UserFieldsDialogWidget(
|
||||
this.close.bind(this),
|
||||
this.accept.bind(this)
|
||||
);
|
||||
}
|
||||
|
||||
set value(userFields: BoardUserField[]) {
|
||||
this.widget.currentUserFields = userFields;
|
||||
}
|
||||
|
||||
get value(): BoardUserField[] {
|
||||
return this.widget.currentUserFields;
|
||||
return this._currentUserFields;
|
||||
}
|
||||
|
||||
set value(userFields: BoardUserField[]) {
|
||||
this._currentUserFields = userFields;
|
||||
}
|
||||
|
||||
protected override render(): React.ReactNode {
|
||||
return (
|
||||
<div>
|
||||
<form>
|
||||
<UserFieldsComponent
|
||||
initialBoardUserFields={this.value}
|
||||
updateUserFields={this.doUpdateUserFields}
|
||||
cancel={this.doCancel}
|
||||
accept={this.doAccept}
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
protected override onAfterAttach(msg: Message): void {
|
||||
if (this.widget.isAttached) {
|
||||
Widget.detach(this.widget);
|
||||
}
|
||||
Widget.attach(this.widget, this.contentNode);
|
||||
super.onAfterAttach(msg);
|
||||
this.update();
|
||||
}
|
||||
|
||||
protected override onUpdateRequest(msg: Message): void {
|
||||
super.onUpdateRequest(msg);
|
||||
this.widget.update();
|
||||
}
|
||||
|
||||
protected override onActivateRequest(msg: Message): void {
|
||||
super.onActivateRequest(msg);
|
||||
this.widget.activate();
|
||||
}
|
||||
|
||||
protected override async accept(): Promise<void> {
|
||||
// If the user presses enter and at least
|
||||
// a field is empty don't accept the input
|
||||
@ -114,8 +66,21 @@ export class UserFieldsDialog extends AbstractDialog<BoardUserField[]> {
|
||||
}
|
||||
|
||||
override close(): void {
|
||||
this.widget.resetUserFieldsValue();
|
||||
this.widget.close();
|
||||
this.resetUserFieldsValue();
|
||||
super.close();
|
||||
}
|
||||
|
||||
private resetUserFieldsValue(): void {
|
||||
this.value = this.value.map((field) => {
|
||||
field.value = '';
|
||||
return field;
|
||||
});
|
||||
}
|
||||
|
||||
private readonly doCancel: () => void = () => this.close();
|
||||
private readonly doAccept: () => Promise<void> = () => this.accept();
|
||||
private readonly doUpdateUserFields: (userFields: BoardUserField[]) => void =
|
||||
(userFields: BoardUserField[]) => {
|
||||
this.value = userFields;
|
||||
};
|
||||
}
|
||||
|
6
arduino-ide-extension/src/browser/icons/loading-dark.svg
Normal file
6
arduino-ide-extension/src/browser/icons/loading-dark.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<!--Copyright (c) Microsoft Corporation. All rights reserved.-->
|
||||
<!--Copyright (C) 2020 TypeFox and others.-->
|
||||
<!--Copied from https://raw.githubusercontent.com/microsoft/vscode-icons/9c90ce81b1f3c309000b80da0763aa09975a85f0/icons/dark/loading.svg -->
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8 0.75C8.17188 0.75 8.33333 0.783854 8.48438 0.851562C8.63542 0.914062 8.76823 1.0026 8.88281 1.11719C8.9974 1.23177 9.08594 1.36458 9.14844 1.51562C9.21615 1.66667 9.25 1.82812 9.25 2C9.25 2.17188 9.21615 2.33333 9.14844 2.48438C9.08594 2.63542 8.9974 2.76823 8.88281 2.88281C8.76823 2.9974 8.63542 3.08854 8.48438 3.15625C8.33333 3.21875 8.17188 3.25 8 3.25C7.82812 3.25 7.66667 3.21875 7.51562 3.15625C7.36458 3.08854 7.23177 2.9974 7.11719 2.88281C7.0026 2.76823 6.91146 2.63542 6.84375 2.48438C6.78125 2.33333 6.75 2.17188 6.75 2C6.75 1.82812 6.78125 1.66667 6.84375 1.51562C6.91146 1.36458 7.0026 1.23177 7.11719 1.11719C7.23177 1.0026 7.36458 0.914062 7.51562 0.851562C7.66667 0.783854 7.82812 0.75 8 0.75ZM2.63281 3.75781C2.63281 3.60156 2.66146 3.45573 2.71875 3.32031C2.77604 3.1849 2.85417 3.06771 2.95312 2.96875C3.05729 2.86458 3.17708 2.78385 3.3125 2.72656C3.45312 2.66406 3.60156 2.63281 3.75781 2.63281C3.91406 2.63281 4.0599 2.66406 4.19531 2.72656C4.33073 2.78385 4.44792 2.86458 4.54688 2.96875C4.65104 3.06771 4.73177 3.1849 4.78906 3.32031C4.85156 3.45573 4.88281 3.60156 4.88281 3.75781C4.88281 3.91406 4.85156 4.0625 4.78906 4.20312C4.73177 4.33854 4.65104 4.45833 4.54688 4.5625C4.44792 4.66146 4.33073 4.73958 4.19531 4.79688C4.0599 4.85417 3.91406 4.88281 3.75781 4.88281C3.60156 4.88281 3.45312 4.85417 3.3125 4.79688C3.17708 4.73958 3.05729 4.66146 2.95312 4.5625C2.85417 4.45833 2.77604 4.33854 2.71875 4.20312C2.66146 4.0625 2.63281 3.91406 2.63281 3.75781ZM2 7C2.14062 7 2.27083 7.02604 2.39062 7.07812C2.51042 7.13021 2.61458 7.20312 2.70312 7.29688C2.79688 7.38542 2.86979 7.48958 2.92188 7.60938C2.97396 7.72917 3 7.85938 3 8C3 8.14062 2.97396 8.27083 2.92188 8.39062C2.86979 8.51042 2.79688 8.61719 2.70312 8.71094C2.61458 8.79948 2.51042 8.86979 2.39062 8.92188C2.27083 8.97396 2.14062 9 2 9C1.85938 9 1.72917 8.97396 1.60938 8.92188C1.48958 8.86979 1.38281 8.79948 1.28906 8.71094C1.20052 8.61719 1.13021 8.51042 1.07812 8.39062C1.02604 8.27083 1 8.14062 1 8C1 7.85938 1.02604 7.72917 1.07812 7.60938C1.13021 7.48958 1.20052 7.38542 1.28906 7.29688C1.38281 7.20312 1.48958 7.13021 1.60938 7.07812C1.72917 7.02604 1.85938 7 2 7ZM2.88281 12.2422C2.88281 12.1224 2.90625 12.0104 2.95312 11.9062C3 11.7969 3.0625 11.7031 3.14062 11.625C3.21875 11.5469 3.3099 11.4844 3.41406 11.4375C3.52344 11.3906 3.63802 11.3672 3.75781 11.3672C3.8776 11.3672 3.98958 11.3906 4.09375 11.4375C4.20312 11.4844 4.29688 11.5469 4.375 11.625C4.45312 11.7031 4.51562 11.7969 4.5625 11.9062C4.60938 12.0104 4.63281 12.1224 4.63281 12.2422C4.63281 12.362 4.60938 12.4766 4.5625 12.5859C4.51562 12.6901 4.45312 12.7812 4.375 12.8594C4.29688 12.9375 4.20312 13 4.09375 13.0469C3.98958 13.0938 3.8776 13.1172 3.75781 13.1172C3.63802 13.1172 3.52344 13.0938 3.41406 13.0469C3.3099 13 3.21875 12.9375 3.14062 12.8594C3.0625 12.7812 3 12.6901 2.95312 12.5859C2.90625 12.4766 2.88281 12.362 2.88281 12.2422ZM8 13.25C8.20833 13.25 8.38542 13.3229 8.53125 13.4688C8.67708 13.6146 8.75 13.7917 8.75 14C8.75 14.2083 8.67708 14.3854 8.53125 14.5312C8.38542 14.6771 8.20833 14.75 8 14.75C7.79167 14.75 7.61458 14.6771 7.46875 14.5312C7.32292 14.3854 7.25 14.2083 7.25 14C7.25 13.7917 7.32292 13.6146 7.46875 13.4688C7.61458 13.3229 7.79167 13.25 8 13.25ZM11.6172 12.2422C11.6172 12.0651 11.6771 11.9167 11.7969 11.7969C11.9167 11.6771 12.0651 11.6172 12.2422 11.6172C12.4193 11.6172 12.5677 11.6771 12.6875 11.7969C12.8073 11.9167 12.8672 12.0651 12.8672 12.2422C12.8672 12.4193 12.8073 12.5677 12.6875 12.6875C12.5677 12.8073 12.4193 12.8672 12.2422 12.8672C12.0651 12.8672 11.9167 12.8073 11.7969 12.6875C11.6771 12.5677 11.6172 12.4193 11.6172 12.2422ZM14 7.5C14.1354 7.5 14.2526 7.54948 14.3516 7.64844C14.4505 7.7474 14.5 7.86458 14.5 8C14.5 8.13542 14.4505 8.2526 14.3516 8.35156C14.2526 8.45052 14.1354 8.5 14 8.5C13.8646 8.5 13.7474 8.45052 13.6484 8.35156C13.5495 8.2526 13.5 8.13542 13.5 8C13.5 7.86458 13.5495 7.7474 13.6484 7.64844C13.7474 7.54948 13.8646 7.5 14 7.5ZM12.2422 2.38281C12.4297 2.38281 12.6068 2.41927 12.7734 2.49219C12.9401 2.5651 13.0859 2.66406 13.2109 2.78906C13.3359 2.91406 13.4349 3.0599 13.5078 3.22656C13.5807 3.39323 13.6172 3.57031 13.6172 3.75781C13.6172 3.94531 13.5807 4.1224 13.5078 4.28906C13.4349 4.45573 13.3359 4.60156 13.2109 4.72656C13.0859 4.85156 12.9401 4.95052 12.7734 5.02344C12.6068 5.09635 12.4297 5.13281 12.2422 5.13281C12.0547 5.13281 11.8776 5.09635 11.7109 5.02344C11.5443 4.95052 11.3984 4.85156 11.2734 4.72656C11.1484 4.60156 11.0495 4.45573 10.9766 4.28906C10.9036 4.1224 10.8672 3.94531 10.8672 3.75781C10.8672 3.57031 10.9036 3.39323 10.9766 3.22656C11.0495 3.0599 11.1484 2.91406 11.2734 2.78906C11.3984 2.66406 11.5443 2.5651 11.7109 2.49219C11.8776 2.41927 12.0547 2.38281 12.2422 2.38281Z" fill="#C5C5C5" />
|
||||
</svg>
|
After Width: | Height: | Size: 5.0 KiB |
@ -0,0 +1,6 @@
|
||||
<!--Copyright (c) Microsoft Corporation. All rights reserved.-->
|
||||
<!--Copyright (C) 2020 TypeFox and others.-->
|
||||
<!--Copied from https://raw.githubusercontent.com/microsoft/vscode-icons/9c90ce81b1f3c309000b80da0763aa09975a85f0/icons/light/loading.svg -->
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8 0.75C8.17188 0.75 8.33333 0.783854 8.48438 0.851562C8.63542 0.914062 8.76823 1.0026 8.88281 1.11719C8.9974 1.23177 9.08594 1.36458 9.14844 1.51562C9.21615 1.66667 9.25 1.82812 9.25 2C9.25 2.17188 9.21615 2.33333 9.14844 2.48438C9.08594 2.63542 8.9974 2.76823 8.88281 2.88281C8.76823 2.9974 8.63542 3.08854 8.48438 3.15625C8.33333 3.21875 8.17188 3.25 8 3.25C7.82812 3.25 7.66667 3.21875 7.51562 3.15625C7.36458 3.08854 7.23177 2.9974 7.11719 2.88281C7.0026 2.76823 6.91146 2.63542 6.84375 2.48438C6.78125 2.33333 6.75 2.17188 6.75 2C6.75 1.82812 6.78125 1.66667 6.84375 1.51562C6.91146 1.36458 7.0026 1.23177 7.11719 1.11719C7.23177 1.0026 7.36458 0.914062 7.51562 0.851562C7.66667 0.783854 7.82812 0.75 8 0.75ZM2.63281 3.75781C2.63281 3.60156 2.66146 3.45573 2.71875 3.32031C2.77604 3.1849 2.85417 3.06771 2.95312 2.96875C3.05729 2.86458 3.17708 2.78385 3.3125 2.72656C3.45312 2.66406 3.60156 2.63281 3.75781 2.63281C3.91406 2.63281 4.0599 2.66406 4.19531 2.72656C4.33073 2.78385 4.44792 2.86458 4.54688 2.96875C4.65104 3.06771 4.73177 3.1849 4.78906 3.32031C4.85156 3.45573 4.88281 3.60156 4.88281 3.75781C4.88281 3.91406 4.85156 4.0625 4.78906 4.20312C4.73177 4.33854 4.65104 4.45833 4.54688 4.5625C4.44792 4.66146 4.33073 4.73958 4.19531 4.79688C4.0599 4.85417 3.91406 4.88281 3.75781 4.88281C3.60156 4.88281 3.45312 4.85417 3.3125 4.79688C3.17708 4.73958 3.05729 4.66146 2.95312 4.5625C2.85417 4.45833 2.77604 4.33854 2.71875 4.20312C2.66146 4.0625 2.63281 3.91406 2.63281 3.75781ZM2 7C2.14062 7 2.27083 7.02604 2.39062 7.07812C2.51042 7.13021 2.61458 7.20312 2.70312 7.29688C2.79688 7.38542 2.86979 7.48958 2.92188 7.60938C2.97396 7.72917 3 7.85938 3 8C3 8.14062 2.97396 8.27083 2.92188 8.39062C2.86979 8.51042 2.79688 8.61719 2.70312 8.71094C2.61458 8.79948 2.51042 8.86979 2.39062 8.92188C2.27083 8.97396 2.14062 9 2 9C1.85938 9 1.72917 8.97396 1.60938 8.92188C1.48958 8.86979 1.38281 8.79948 1.28906 8.71094C1.20052 8.61719 1.13021 8.51042 1.07812 8.39062C1.02604 8.27083 1 8.14062 1 8C1 7.85938 1.02604 7.72917 1.07812 7.60938C1.13021 7.48958 1.20052 7.38542 1.28906 7.29688C1.38281 7.20312 1.48958 7.13021 1.60938 7.07812C1.72917 7.02604 1.85938 7 2 7ZM2.88281 12.2422C2.88281 12.1224 2.90625 12.0104 2.95312 11.9062C3 11.7969 3.0625 11.7031 3.14062 11.625C3.21875 11.5469 3.3099 11.4844 3.41406 11.4375C3.52344 11.3906 3.63802 11.3672 3.75781 11.3672C3.8776 11.3672 3.98958 11.3906 4.09375 11.4375C4.20312 11.4844 4.29688 11.5469 4.375 11.625C4.45312 11.7031 4.51562 11.7969 4.5625 11.9062C4.60938 12.0104 4.63281 12.1224 4.63281 12.2422C4.63281 12.362 4.60938 12.4766 4.5625 12.5859C4.51562 12.6901 4.45312 12.7812 4.375 12.8594C4.29688 12.9375 4.20312 13 4.09375 13.0469C3.98958 13.0938 3.8776 13.1172 3.75781 13.1172C3.63802 13.1172 3.52344 13.0938 3.41406 13.0469C3.3099 13 3.21875 12.9375 3.14062 12.8594C3.0625 12.7812 3 12.6901 2.95312 12.5859C2.90625 12.4766 2.88281 12.362 2.88281 12.2422ZM8 13.25C8.20833 13.25 8.38542 13.3229 8.53125 13.4688C8.67708 13.6146 8.75 13.7917 8.75 14C8.75 14.2083 8.67708 14.3854 8.53125 14.5312C8.38542 14.6771 8.20833 14.75 8 14.75C7.79167 14.75 7.61458 14.6771 7.46875 14.5312C7.32292 14.3854 7.25 14.2083 7.25 14C7.25 13.7917 7.32292 13.6146 7.46875 13.4688C7.61458 13.3229 7.79167 13.25 8 13.25ZM11.6172 12.2422C11.6172 12.0651 11.6771 11.9167 11.7969 11.7969C11.9167 11.6771 12.0651 11.6172 12.2422 11.6172C12.4193 11.6172 12.5677 11.6771 12.6875 11.7969C12.8073 11.9167 12.8672 12.0651 12.8672 12.2422C12.8672 12.4193 12.8073 12.5677 12.6875 12.6875C12.5677 12.8073 12.4193 12.8672 12.2422 12.8672C12.0651 12.8672 11.9167 12.8073 11.7969 12.6875C11.6771 12.5677 11.6172 12.4193 11.6172 12.2422ZM14 7.5C14.1354 7.5 14.2526 7.54948 14.3516 7.64844C14.4505 7.7474 14.5 7.86458 14.5 8C14.5 8.13542 14.4505 8.2526 14.3516 8.35156C14.2526 8.45052 14.1354 8.5 14 8.5C13.8646 8.5 13.7474 8.45052 13.6484 8.35156C13.5495 8.2526 13.5 8.13542 13.5 8C13.5 7.86458 13.5495 7.7474 13.6484 7.64844C13.7474 7.54948 13.8646 7.5 14 7.5ZM12.2422 2.38281C12.4297 2.38281 12.6068 2.41927 12.7734 2.49219C12.9401 2.5651 13.0859 2.66406 13.2109 2.78906C13.3359 2.91406 13.4349 3.0599 13.5078 3.22656C13.5807 3.39323 13.6172 3.57031 13.6172 3.75781C13.6172 3.94531 13.5807 4.1224 13.5078 4.28906C13.4349 4.45573 13.3359 4.60156 13.2109 4.72656C13.0859 4.85156 12.9401 4.95052 12.7734 5.02344C12.6068 5.09635 12.4297 5.13281 12.2422 5.13281C12.0547 5.13281 11.8776 5.09635 11.7109 5.02344C11.5443 4.95052 11.3984 4.85156 11.2734 4.72656C11.1484 4.60156 11.0495 4.45573 10.9766 4.28906C10.9036 4.1224 10.8672 3.94531 10.8672 3.75781C10.8672 3.57031 10.9036 3.39323 10.9766 3.22656C11.0495 3.0599 11.1484 2.91406 11.2734 2.78906C11.3984 2.66406 11.5443 2.5651 11.7109 2.49219C11.8776 2.41927 12.0547 2.38281 12.2422 2.38281Z" fill="#424242" />
|
||||
</svg>
|
After Width: | Height: | Size: 5.0 KiB |
@ -1,5 +1,5 @@
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import { URI as Uri } from 'vscode-uri';
|
||||
import { URI as Uri } from '@theia/core/shared/vscode-uri';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { Deferred } from '@theia/core/lib/common/promise-util';
|
||||
import {
|
||||
|
@ -1,6 +1,5 @@
|
||||
import * as React from '@theia/core/shared/react';
|
||||
import { injectable, inject } from '@theia/core/shared/inversify';
|
||||
import { OptionsType } from 'react-select/src/types';
|
||||
import { Emitter } from '@theia/core/lib/common/event';
|
||||
import { Disposable } from '@theia/core/lib/common/disposable';
|
||||
import {
|
||||
@ -128,9 +127,7 @@ export class MonitorWidget extends ReactWidget {
|
||||
);
|
||||
};
|
||||
|
||||
protected get lineEndings(): OptionsType<
|
||||
SerialMonitorOutput.SelectOption<MonitorModel.EOL>
|
||||
> {
|
||||
protected get lineEndings(): SerialMonitorOutput.SelectOption<MonitorModel.EOL>[] {
|
||||
return [
|
||||
{
|
||||
label: nls.localize('arduino/serial/noLineEndings', 'No Line Ending'),
|
||||
|
@ -20,6 +20,16 @@
|
||||
@import './progress-bar.css';
|
||||
@import './settings-step-input.css';
|
||||
|
||||
/* Revive of the `--theia-icon-loading`. The variable has been removed from Theia while IDE2 still uses is. */
|
||||
/* The SVG icons are still part of Theia (1.31.1) */
|
||||
/* https://github.com/arduino/arduino-ide/pull/1662#issuecomment-1324997134 */
|
||||
body {
|
||||
--theia-icon-loading: url(../icons/loading-light.svg);
|
||||
}
|
||||
body.theia-dark {
|
||||
--theia-icon-loading: url(../icons/loading-dark.svg);
|
||||
}
|
||||
|
||||
.theia-input.warning:focus {
|
||||
outline-width: 1px;
|
||||
outline-style: solid;
|
||||
|
@ -24,7 +24,7 @@ export class CommonFrontendContribution extends TheiaCommonFrontendContribution
|
||||
CommonCommands.TOGGLE_MAXIMIZED,
|
||||
CommonCommands.PIN_TAB,
|
||||
CommonCommands.UNPIN_TAB,
|
||||
CommonCommands.NEW_FILE,
|
||||
CommonCommands.NEW_UNTITLED_FILE,
|
||||
]) {
|
||||
commandRegistry.unregisterCommand(command);
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
import { StatusBarImpl as TheiaStatusBarImpl } from '@theia/core/lib/browser';
|
||||
|
||||
@injectable()
|
||||
export class StatusBarImpl extends TheiaStatusBarImpl {
|
||||
override async removeElement(id: string): Promise<void> {
|
||||
await this.ready;
|
||||
if (this.entries.delete(id)) {
|
||||
// Unlike Theia, IDE2 updates the status bar only if the element to remove was among the entries. Otherwise, it's a NOOP.
|
||||
this.update();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
import * as React from '@theia/core/shared/react';
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
import { LabelIcon } from '@theia/core/lib/browser/label-parser';
|
||||
import {
|
||||
TabBarToolbar as TheiaTabBarToolbar,
|
||||
TabBarToolbarItem,
|
||||
} from '@theia/core/lib/browser/shell/tab-bar-toolbar';
|
||||
|
||||
@injectable()
|
||||
export class TabBarToolbar extends TheiaTabBarToolbar {
|
||||
/**
|
||||
* Copied over from Theia. Added an ID to the parent of the toolbar item (`--container`).
|
||||
* CSS3 does not support parent selectors but we want to style the parent of the toolbar item.
|
||||
*/
|
||||
protected override renderItem(item: TabBarToolbarItem): React.ReactNode {
|
||||
let innerText = '';
|
||||
const classNames = [];
|
||||
if (item.text) {
|
||||
for (const labelPart of this.labelParser.parse(item.text)) {
|
||||
if (typeof labelPart !== 'string' && LabelIcon.is(labelPart)) {
|
||||
const className = `fa fa-${labelPart.name}${
|
||||
labelPart.animation ? ' fa-' + labelPart.animation : ''
|
||||
}`;
|
||||
classNames.push(...className.split(' '));
|
||||
} else {
|
||||
innerText = labelPart;
|
||||
}
|
||||
}
|
||||
}
|
||||
const command = this.commands.getCommand(item.command);
|
||||
const iconClass =
|
||||
(typeof item.icon === 'function' && item.icon()) ||
|
||||
item.icon ||
|
||||
(command && command.iconClass);
|
||||
if (iconClass) {
|
||||
classNames.push(iconClass);
|
||||
}
|
||||
const tooltip = item.tooltip || (command && command.label);
|
||||
return (
|
||||
<div
|
||||
id={`${item.id}--container`}
|
||||
key={item.id}
|
||||
className={`${TabBarToolbar.Styles.TAB_BAR_TOOLBAR_ITEM}${
|
||||
command && this.commandIsEnabled(command.id) ? ' enabled' : ''
|
||||
}`}
|
||||
onMouseDown={this.onMouseDownEvent}
|
||||
onMouseUp={this.onMouseUpEvent}
|
||||
onMouseOut={this.onMouseUpEvent}
|
||||
>
|
||||
<div
|
||||
id={item.id}
|
||||
className={classNames.join(' ')}
|
||||
onClick={this.executeCommand}
|
||||
title={tooltip}
|
||||
>
|
||||
{innerText}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
26
arduino-ide-extension/src/browser/theia/core/theming.ts
Normal file
26
arduino-ide-extension/src/browser/theia/core/theming.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { ThemeService as TheiaThemeService } from '@theia/core/lib/browser/theming';
|
||||
import type { Theme } from '@theia/core/lib/common/theme';
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
|
||||
export namespace ArduinoThemes {
|
||||
export const Light: Theme = {
|
||||
id: 'arduino-theme',
|
||||
type: 'light',
|
||||
label: 'Light (Arduino)',
|
||||
editorTheme: 'arduino-theme',
|
||||
};
|
||||
export const Dark: Theme = {
|
||||
id: 'arduino-theme-dark',
|
||||
type: 'dark',
|
||||
label: 'Dark (Arduino)',
|
||||
editorTheme: 'arduino-theme-dark',
|
||||
};
|
||||
}
|
||||
|
||||
@injectable()
|
||||
export class ThemeService extends TheiaThemeService {
|
||||
protected override init(): void {
|
||||
this.register(ArduinoThemes.Light, ArduinoThemes.Dark);
|
||||
super.init();
|
||||
}
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
import type { MaybePromise } from '@theia/core';
|
||||
import type { Widget } from '@theia/core/lib/browser';
|
||||
import { WidgetManager as TheiaWidgetManager } from '@theia/core/lib/browser/widget-manager';
|
||||
import {
|
||||
@ -8,7 +7,6 @@ import {
|
||||
} from '@theia/core/shared/inversify';
|
||||
import { EditorWidget } from '@theia/editor/lib/browser';
|
||||
import { OutputWidget } from '@theia/output/lib/browser/output-widget';
|
||||
import deepEqual = require('deep-equal');
|
||||
import {
|
||||
CurrentSketch,
|
||||
SketchesServiceClientImpl,
|
||||
@ -72,44 +70,4 @@ export class WidgetManager extends TheiaWidgetManager {
|
||||
title.className += title.className + ` ${uncloseableClass}`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Customized to find any existing widget based on `options` deepEquals instead of string equals.
|
||||
* See https://github.com/eclipse-theia/theia/issues/11309.
|
||||
*/
|
||||
protected override doGetWidget<T extends Widget>(
|
||||
key: string
|
||||
): MaybePromise<T> | undefined {
|
||||
const pendingWidget = this.findExistingWidget<T>(key);
|
||||
if (pendingWidget) {
|
||||
return pendingWidget as MaybePromise<T>;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private findExistingWidget<T extends Widget>(
|
||||
key: string
|
||||
): MaybePromise<T> | undefined {
|
||||
const parsed = this.parseJson(key);
|
||||
for (const [candidateKey, widget] of [
|
||||
...this.widgetPromises.entries(),
|
||||
...this.pendingWidgetPromises.entries(),
|
||||
]) {
|
||||
const candidate = this.parseJson(candidateKey);
|
||||
if (deepEqual(candidate, parsed)) {
|
||||
return widget as MaybePromise<T>;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
private parseJson(json: string): any {
|
||||
try {
|
||||
return JSON.parse(json);
|
||||
} catch (err) {
|
||||
console.log(`Failed to parse JSON: <${json}>.`, err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,87 @@
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider';
|
||||
import { NavigatableWidget } from '@theia/core/lib/browser/navigatable-types';
|
||||
import { ApplicationShell } from '@theia/core/lib/browser/shell/application-shell';
|
||||
import { Widget } from '@theia/core/lib/browser/widgets/widget';
|
||||
import { WindowTitleUpdater as TheiaWindowTitleUpdater } from '@theia/core/lib/browser/window/window-title-updater';
|
||||
import { ApplicationServer } from '@theia/core/lib/common/application-protocol';
|
||||
import { isOSX } from '@theia/core/lib/common/os';
|
||||
import {
|
||||
inject,
|
||||
injectable,
|
||||
postConstruct,
|
||||
} from '@theia/core/shared/inversify';
|
||||
import { EditorWidget } from '@theia/editor/lib/browser/editor-widget';
|
||||
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service';
|
||||
|
||||
@injectable()
|
||||
export class WindowTitleUpdater extends TheiaWindowTitleUpdater {
|
||||
@inject(ApplicationServer)
|
||||
private readonly applicationServer: ApplicationServer;
|
||||
@inject(ApplicationShell)
|
||||
private readonly applicationShell: ApplicationShell;
|
||||
@inject(WorkspaceService)
|
||||
private readonly workspaceService: WorkspaceService;
|
||||
|
||||
private _previousRepresentedFilename: string | undefined;
|
||||
|
||||
private readonly applicationName =
|
||||
FrontendApplicationConfigProvider.get().applicationName;
|
||||
private applicationVersion: string | undefined;
|
||||
|
||||
@postConstruct()
|
||||
protected init(): void {
|
||||
setTimeout(
|
||||
() =>
|
||||
this.applicationServer.getApplicationInfo().then((info) => {
|
||||
this.applicationVersion = info?.version;
|
||||
if (this.applicationVersion) {
|
||||
this.handleWidgetChange(this.applicationShell.currentWidget);
|
||||
}
|
||||
}),
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
protected override handleWidgetChange(widget?: Widget | undefined): void {
|
||||
if (isOSX) {
|
||||
this.maybeUpdateRepresentedFilename(widget);
|
||||
}
|
||||
// Unlike Theia, IDE2 does not want to show in the window title if the current widget is dirty or not.
|
||||
// Hence, IDE2 does not track widgets but updates the window title on current widget change.
|
||||
this.updateTitleWidget(widget);
|
||||
}
|
||||
|
||||
protected override updateTitleWidget(widget?: Widget | undefined): void {
|
||||
let activeEditorShort = '';
|
||||
const rootName = this.workspaceService.workspace?.name ?? '';
|
||||
let appName = `${this.applicationName}${
|
||||
this.applicationVersion ? ` ${this.applicationVersion}` : ''
|
||||
}`;
|
||||
if (rootName) {
|
||||
appName = ` | ${appName}`;
|
||||
}
|
||||
const uri = NavigatableWidget.getUri(widget);
|
||||
if (uri) {
|
||||
const base = uri.path.base;
|
||||
// Do not show the basename of the main sketch file. Only other sketch file names are visible in the title.
|
||||
if (`${rootName}.ino` !== base) {
|
||||
activeEditorShort = ` - ${base} `;
|
||||
}
|
||||
}
|
||||
this.windowTitleService.update({ rootName, appName, activeEditorShort });
|
||||
}
|
||||
|
||||
private maybeUpdateRepresentedFilename(widget?: Widget | undefined): void {
|
||||
if (widget instanceof EditorWidget) {
|
||||
const { uri } = widget.editor;
|
||||
const filename = uri.path.toString();
|
||||
// Do not necessarily require the current window if not needed. It's a synchronous, blocking call.
|
||||
if (this._previousRepresentedFilename !== filename) {
|
||||
const currentWindow = remote.getCurrentWindow();
|
||||
currentWindow.setRepresentedFilename(uri.path.toString());
|
||||
this._previousRepresentedFilename = filename;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,9 @@
|
||||
import debounce = require('p-debounce');
|
||||
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
|
||||
import {
|
||||
inject,
|
||||
injectable,
|
||||
postConstruct,
|
||||
} from '@theia/core/shared/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';
|
||||
@ -126,7 +130,7 @@ export class DebugConfigurationManager extends TheiaDebugConfigurationManager {
|
||||
const uri = tempFolderUri.resolve('launch.json');
|
||||
const { value } = await this.fileService.read(uri);
|
||||
const configurations = DebugConfigurationModel.parse(JSON.parse(value));
|
||||
return { uri, configurations };
|
||||
return { uri, configurations, compounds: [] };
|
||||
} catch (err) {
|
||||
if (
|
||||
err instanceof FileOperationError &&
|
||||
|
@ -29,6 +29,7 @@ export class DebugConfigurationModel extends TheiaDebugConfigurationModel {
|
||||
return {
|
||||
uri: this.configUri,
|
||||
configurations: this.config,
|
||||
compounds: [],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,90 +0,0 @@
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
import { DebugError } from '@theia/debug/lib/common/debug-service';
|
||||
import { DebugSession } from '@theia/debug/lib/browser/debug-session';
|
||||
import { DebugSessionOptions } from '@theia/debug/lib/browser/debug-session-options';
|
||||
import { DebugSessionManager as TheiaDebugSessionManager } from '@theia/debug/lib/browser/debug-session-manager';
|
||||
import { nls } from '@theia/core/lib/common';
|
||||
|
||||
@injectable()
|
||||
export class DebugSessionManager extends TheiaDebugSessionManager {
|
||||
override async start(options: DebugSessionOptions): Promise<DebugSession | undefined> {
|
||||
return this.progressService.withProgress(
|
||||
nls.localize('theia/debug/start', 'Start...'),
|
||||
'debug',
|
||||
async () => {
|
||||
try {
|
||||
// Only save when dirty. To avoid saving temporary sketches.
|
||||
// This is a quick fix for not saving the editor when there are no dirty editors.
|
||||
// // https://github.com/bcmi-labs/arduino-editor/pull/172#issuecomment-741831888
|
||||
if (this.shell.canSaveAll()) {
|
||||
await this.shell.saveAll();
|
||||
}
|
||||
await this.fireWillStartDebugSession();
|
||||
const resolved = await this.resolveConfiguration(options);
|
||||
|
||||
//#region "cherry-picked" from here: https://github.com/eclipse-theia/theia/commit/e6b57ba4edabf797f3b4e67bc2968cdb8cc25b1e#diff-08e04edb57cd2af199382337aaf1dbdb31171b37ae4ab38a38d36cd77bc656c7R196-R207
|
||||
if (!resolved) {
|
||||
// As per vscode API: https://code.visualstudio.com/api/references/vscode-api#DebugConfigurationProvider
|
||||
// "Returning the value 'undefined' prevents the debug session from starting.
|
||||
// Returning the value 'null' prevents the debug session from starting and opens the
|
||||
// underlying debug configuration instead."
|
||||
|
||||
if (resolved === null) {
|
||||
this.debugConfigurationManager.openConfiguration();
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
//#endregion end of cherry-pick
|
||||
|
||||
// preLaunchTask isn't run in case of auto restart as well as postDebugTask
|
||||
if (!options.configuration.__restart) {
|
||||
const taskRun = await this.runTask(
|
||||
options.workspaceFolderUri,
|
||||
resolved.configuration.preLaunchTask,
|
||||
true
|
||||
);
|
||||
if (!taskRun) {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
const sessionId = await this.debug.createDebugSession(
|
||||
resolved.configuration
|
||||
);
|
||||
return this.doStart(sessionId, resolved);
|
||||
} catch (e) {
|
||||
if (DebugError.NotFound.is(e)) {
|
||||
this.messageService.error(
|
||||
nls.localize(
|
||||
'theia/debug/typeNotSupported',
|
||||
'The debug session type "{0}" is not supported.',
|
||||
e.data.type
|
||||
)
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
this.messageService.error(
|
||||
nls.localize(
|
||||
'theia/debug/startError',
|
||||
'There was an error starting the debug session, check the logs for more details.'
|
||||
)
|
||||
);
|
||||
console.error('Error starting the debug session', e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
override async terminateSession(session?: DebugSession): Promise<void> {
|
||||
if (!session) {
|
||||
this.updateCurrentSession(this._currentSession);
|
||||
session = this._currentSession;
|
||||
}
|
||||
// The cortex-debug extension does not respond to close requests
|
||||
// So we simply terminate the debug session immediately
|
||||
// Alternatively the `super.terminateSession` call will terminate it after 5 seconds without a response
|
||||
await this.debug.terminateDebugSession(session!.id);
|
||||
await super.terminateSession(session);
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
import { injectable, inject } from '@theia/core/shared/inversify';
|
||||
|
||||
import {
|
||||
AbstractDialog as TheiaAbstractDialog,
|
||||
codiconArray,
|
||||
DialogProps,
|
||||
} from '@theia/core/lib/browser';
|
||||
|
||||
@injectable()
|
||||
export abstract class AbstractDialog<T> extends TheiaAbstractDialog<T> {
|
||||
constructor(@inject(DialogProps) protected override readonly props: DialogProps) {
|
||||
super(props);
|
||||
|
||||
this.closeCrossNode.classList.remove(...codiconArray('close'));
|
||||
this.closeCrossNode.classList.add('fa', 'fa-close');
|
||||
}
|
||||
}
|
63
arduino-ide-extension/src/browser/theia/dialogs/dialogs.tsx
Normal file
63
arduino-ide-extension/src/browser/theia/dialogs/dialogs.tsx
Normal file
@ -0,0 +1,63 @@
|
||||
import {
|
||||
AbstractDialog as TheiaAbstractDialog,
|
||||
DialogProps,
|
||||
} from '@theia/core/lib/browser/dialogs';
|
||||
import { ReactDialog as TheiaReactDialog } from '@theia/core/lib/browser/dialogs/react-dialog';
|
||||
import { codiconArray, Message } from '@theia/core/lib/browser/widgets/widget';
|
||||
import {
|
||||
Disposable,
|
||||
DisposableCollection,
|
||||
} from '@theia/core/lib/common/disposable';
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import * as React from '@theia/core/shared/react';
|
||||
import { createRoot } from '@theia/core/shared/react-dom/client';
|
||||
|
||||
@injectable()
|
||||
export abstract class AbstractDialog<T> extends TheiaAbstractDialog<T> {
|
||||
constructor(
|
||||
@inject(DialogProps) protected override readonly props: DialogProps
|
||||
) {
|
||||
super(props);
|
||||
|
||||
this.closeCrossNode.classList.remove(...codiconArray('close'));
|
||||
this.closeCrossNode.classList.add('fa', 'fa-close');
|
||||
}
|
||||
}
|
||||
|
||||
@injectable()
|
||||
export abstract class ReactDialog<T> extends TheiaReactDialog<T> {
|
||||
protected override onUpdateRequest(msg: Message): void {
|
||||
// This is tricky to bypass the default Theia code.
|
||||
// Otherwise, there is a warning when opening the dialog for the second time.
|
||||
// You are calling ReactDOMClient.createRoot() on a container that has already been passed to createRoot() before. Instead, call root.render() on the existing root instead if you want to update it.
|
||||
const disposables = new DisposableCollection();
|
||||
if (!this.isMounted) {
|
||||
// toggle the `isMounted` logic for the time being of the super call so that the `createRoot` does not run
|
||||
this.isMounted = true;
|
||||
disposables.push(Disposable.create(() => (this.isMounted = false)));
|
||||
}
|
||||
|
||||
// Always unset the `contentNodeRoot` so there is no double update when calling super.
|
||||
const restoreContentNodeRoot = this.contentNodeRoot;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(this.contentNodeRoot as any) = undefined;
|
||||
disposables.push(
|
||||
Disposable.create(() => (this.contentNodeRoot = restoreContentNodeRoot))
|
||||
);
|
||||
|
||||
try {
|
||||
super.onUpdateRequest(msg);
|
||||
} finally {
|
||||
disposables.dispose();
|
||||
}
|
||||
|
||||
// Use the patched rendering.
|
||||
if (!this.isMounted) {
|
||||
this.contentNodeRoot = createRoot(this.contentNode);
|
||||
// Resetting the prop is missing from the Theia code.
|
||||
// https://github.com/eclipse-theia/theia/blob/v1.31.1/packages/core/src/browser/dialogs/react-dialog.tsx#L41-L47
|
||||
this.isMounted = true;
|
||||
}
|
||||
this.contentNodeRoot?.render(<>{this.render()}</>);
|
||||
}
|
||||
}
|
@ -20,7 +20,7 @@ export class EditorWidgetFactory extends TheiaEditorWidgetFactory {
|
||||
|
||||
protected override async createEditor(
|
||||
uri: URI,
|
||||
options: NavigatableWidgetOptions
|
||||
options?: NavigatableWidgetOptions
|
||||
): Promise<EditorWidget> {
|
||||
const widget = await super.createEditor(uri, options);
|
||||
return this.maybeUpdateCaption(widget);
|
||||
|
@ -3,7 +3,7 @@ import {
|
||||
injectable,
|
||||
postConstruct,
|
||||
} from '@theia/core/shared/inversify';
|
||||
import { Diagnostic } from 'vscode-languageserver-types';
|
||||
import { Diagnostic } from '@theia/core/shared/vscode-languageserver-types';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { ILogger } from '@theia/core';
|
||||
import { Marker } from '@theia/markers/lib/common/marker';
|
||||
|
@ -1,5 +1,4 @@
|
||||
import * as React from '@theia/core/shared/react';
|
||||
import * as ReactDOM from '@theia/core/shared/react-dom';
|
||||
import {
|
||||
inject,
|
||||
injectable,
|
||||
@ -25,15 +24,14 @@ export class NotificationsRenderer extends TheiaNotificationsRenderer {
|
||||
}
|
||||
|
||||
protected override render(): void {
|
||||
ReactDOM.render(
|
||||
this.containerRoot.render(
|
||||
<div>
|
||||
<NotificationToastsComponent
|
||||
manager={this.manager}
|
||||
corePreferences={this.corePreferences}
|
||||
/>
|
||||
<NotificationCenterComponent manager={this.manager} />
|
||||
</div>,
|
||||
this.container
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,23 @@
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
import { MonacoThemingService as TheiaMonacoThemingService } from '@theia/monaco/lib/browser/monaco-theming-service';
|
||||
import { ArduinoThemes } from '../core/theming';
|
||||
|
||||
@injectable()
|
||||
export class MonacoThemingService extends TheiaMonacoThemingService {
|
||||
override initialize(): void {
|
||||
super.initialize();
|
||||
const { Light, Dark } = ArduinoThemes;
|
||||
this.registerParsedTheme({
|
||||
id: Light.id,
|
||||
label: Light.label,
|
||||
uiTheme: 'vs',
|
||||
json: require('../../../../src/browser/data/default.color-theme.json'),
|
||||
});
|
||||
this.registerParsedTheme({
|
||||
id: Dark.id,
|
||||
label: Dark.label,
|
||||
uiTheme: 'vs-dark',
|
||||
json: require('../../../../src/browser/data/dark.color-theme.json'),
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
import { KeybindingRegistry } from '@theia/core/lib/browser/keybinding';
|
||||
import { CommandRegistry } from '@theia/core/lib/common/command';
|
||||
import { MenuModelRegistry } from '@theia/core/lib/common/menu';
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
import {
|
||||
TypeHierarchyCommands,
|
||||
TypeHierarchyContribution as TheiaTypeHierarchyContribution,
|
||||
} from '@theia/typehierarchy/lib/browser/typehierarchy-contribution';
|
||||
|
||||
@injectable()
|
||||
export class TypeHierarchyContribution extends TheiaTypeHierarchyContribution {
|
||||
protected override init(): void {
|
||||
// NOOP
|
||||
}
|
||||
|
||||
override registerCommands(registry: CommandRegistry): void {
|
||||
super.registerCommands(registry);
|
||||
registry.unregisterCommand(TypeHierarchyCommands.OPEN_SUBTYPE.id);
|
||||
registry.unregisterCommand(TypeHierarchyCommands.OPEN_SUPERTYPE.id);
|
||||
}
|
||||
|
||||
override registerMenus(registry: MenuModelRegistry): void {
|
||||
super.registerMenus(registry);
|
||||
registry.unregisterMenuAction(TypeHierarchyCommands.OPEN_SUBTYPE.id);
|
||||
registry.unregisterMenuAction(TypeHierarchyCommands.OPEN_SUPERTYPE.id);
|
||||
}
|
||||
|
||||
override registerKeybindings(registry: KeybindingRegistry): void {
|
||||
super.registerKeybindings(registry);
|
||||
registry.unregisterKeybinding(TypeHierarchyCommands.OPEN_SUBTYPE.id);
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
import { TypeHierarchyServiceProvider as TheiaTypeHierarchyServiceProvider } from '@theia/typehierarchy/lib/browser/typehierarchy-service';
|
||||
|
||||
@injectable()
|
||||
export class TypeHierarchyServiceProvider extends TheiaTypeHierarchyServiceProvider {
|
||||
override init(): void {
|
||||
// NOOP
|
||||
}
|
||||
}
|
@ -1,58 +1,37 @@
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import { injectable, inject, named } from '@theia/core/shared/inversify';
|
||||
import { ContributionProvider } from '@theia/core/lib/common/contribution-provider';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { EditorWidget } from '@theia/editor/lib/browser';
|
||||
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 {
|
||||
DEFAULT_WINDOW_HASH,
|
||||
NewWindowOptions,
|
||||
} from '@theia/core/lib/common/window';
|
||||
import { inject, injectable, named } from '@theia/core/shared/inversify';
|
||||
import { FileStat } from '@theia/filesystem/lib/common/files';
|
||||
import {
|
||||
WorkspaceInput,
|
||||
WorkspaceService as TheiaWorkspaceService,
|
||||
} from '@theia/workspace/lib/browser/workspace-service';
|
||||
import {
|
||||
SketchesService,
|
||||
Sketch,
|
||||
SketchesError,
|
||||
SketchesService,
|
||||
} from '../../../common/protocol/sketches-service';
|
||||
import { FileStat } from '@theia/filesystem/lib/common/files';
|
||||
import {
|
||||
StartupTask,
|
||||
StartupTaskProvider,
|
||||
} from '../../../electron-common/startup-task';
|
||||
import { WindowServiceExt } from '../core/window-service-ext';
|
||||
import { ContributionProvider } from '@theia/core/lib/common/contribution-provider';
|
||||
|
||||
@injectable()
|
||||
export class WorkspaceService extends TheiaWorkspaceService {
|
||||
@inject(SketchesService)
|
||||
private readonly sketchService: SketchesService;
|
||||
@inject(ApplicationServer)
|
||||
private readonly applicationServer: ApplicationServer;
|
||||
@inject(WindowServiceExt)
|
||||
private readonly windowServiceExt: WindowServiceExt;
|
||||
@inject(ContributionProvider)
|
||||
@named(StartupTaskProvider)
|
||||
private readonly providers: ContributionProvider<StartupTaskProvider>;
|
||||
|
||||
private version?: string;
|
||||
private _workspaceError: Error | undefined;
|
||||
|
||||
async onStart(application: FrontendApplication): Promise<void> {
|
||||
const info = await this.applicationServer.getApplicationInfo();
|
||||
this.version = info?.version;
|
||||
application.shell.onDidChangeCurrentWidget(
|
||||
this.onCurrentWidgetChange.bind(this)
|
||||
);
|
||||
const newValue = application.shell.currentWidget
|
||||
? application.shell.currentWidget
|
||||
: null;
|
||||
this.onCurrentWidgetChange({ newValue, oldValue: null });
|
||||
}
|
||||
|
||||
get workspaceError(): Error | undefined {
|
||||
return this._workspaceError;
|
||||
}
|
||||
@ -121,58 +100,6 @@ export class WorkspaceService extends TheiaWorkspaceService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copied from Theia as-is to be able to pass the original `options` down.
|
||||
*/
|
||||
protected override async doOpen(
|
||||
uri: URI,
|
||||
options?: WorkspaceInput
|
||||
): Promise<URI | undefined> {
|
||||
const stat = await this.toFileStat(uri);
|
||||
if (stat) {
|
||||
if (!stat.isDirectory && !this.isWorkspaceFile(stat)) {
|
||||
const message = `Not a valid workspace: ${uri.path.toString()}`;
|
||||
this.messageService.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
// The same window has to be preserved too (instead of opening a new one), if the workspace root is not yet available and we are setting it for the first time.
|
||||
// Option passed as parameter has the highest priority (for api developers), then the preference, then the default.
|
||||
await this.roots;
|
||||
const { preserveWindow } = {
|
||||
preserveWindow:
|
||||
this.preferences['workspace.preserveWindow'] || !this.opened,
|
||||
...options,
|
||||
};
|
||||
await this.server.setMostRecentlyUsedWorkspace(uri.toString());
|
||||
if (preserveWindow) {
|
||||
this._workspace = stat;
|
||||
}
|
||||
this.openWindow(stat, Object.assign(options ?? {}, { preserveWindow })); // Unlike Theia, IDE2 passes the whole `input` downstream and not only { preserveWindow }
|
||||
return;
|
||||
}
|
||||
throw new Error(
|
||||
'Invalid workspace root URI. Expected an existing directory or workspace file.'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copied from Theia. Can pass the `options` further down the chain.
|
||||
*/
|
||||
protected override openWindow(uri: FileStat, options?: WorkspaceInput): void {
|
||||
const workspacePath = uri.resource.path.toString();
|
||||
if (this.shouldPreserveWindow(options)) {
|
||||
this.reloadWindow(options); // Unlike Theia, IDE2 passes the `input` downstream.
|
||||
} else {
|
||||
try {
|
||||
this.openNewWindow(workspacePath, options); // Unlike Theia, IDE2 passes the `input` downstream.
|
||||
} catch (error) {
|
||||
// Fall back to reloading the current window in case the browser has blocked the new window
|
||||
this._workspace = uri;
|
||||
this.logger.error(error.toString()).then(() => this.reloadWindow());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override reloadWindow(options?: WorkspaceInput): void {
|
||||
const tasks = this.tasks(options);
|
||||
this.setURLFragment(this._workspace?.resource.path.toString() || '');
|
||||
@ -192,6 +119,10 @@ export class WorkspaceService extends TheiaWorkspaceService {
|
||||
);
|
||||
}
|
||||
|
||||
protected override updateTitle(): void {
|
||||
// NOOP. IDE2 handles the `window.title` updates solely via the customized `WindowTitleUpdater`.
|
||||
}
|
||||
|
||||
private tasks(options?: WorkspaceInput): StartupTask[] {
|
||||
const tasks = this.providers
|
||||
.getContributions()
|
||||
@ -202,37 +133,4 @@ export class WorkspaceService extends TheiaWorkspaceService {
|
||||
}
|
||||
return tasks;
|
||||
}
|
||||
|
||||
protected onCurrentWidgetChange({
|
||||
newValue,
|
||||
}: FocusTracker.IChangedArgs<Widget>): void {
|
||||
if (newValue instanceof EditorWidget) {
|
||||
const { uri } = newValue.editor;
|
||||
const currentWindow = remote.getCurrentWindow();
|
||||
currentWindow.setRepresentedFilename(uri.path.toString());
|
||||
if (Sketch.isSketchFile(uri.toString())) {
|
||||
this.updateTitle();
|
||||
} else {
|
||||
const title = this.workspaceTitle;
|
||||
const fileName = this.labelProvider.getName(uri);
|
||||
document.title = this.formatTitle(
|
||||
title ? `${title} - ${fileName}` : fileName
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.updateTitle();
|
||||
}
|
||||
}
|
||||
|
||||
protected override formatTitle(title?: string): string {
|
||||
const version = this.version ? ` ${this.version}` : '';
|
||||
const name = `${this.applicationName} ${version}`;
|
||||
return title ? `${title} | ${name}` : name;
|
||||
}
|
||||
|
||||
protected get workspaceTitle(): string | undefined {
|
||||
if (this.workspace) {
|
||||
return this.labelProvider.getName(this.workspace.resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,22 @@
|
||||
import * as React from '@theia/core/shared/react';
|
||||
import Select from 'react-select';
|
||||
import { Styles } from 'react-select/src/styles';
|
||||
import { Props } from 'react-select/src/components';
|
||||
import { ThemeConfig } from 'react-select/src/theme';
|
||||
import type { StylesConfig } from 'react-select/dist/declarations/src/styles';
|
||||
import type { ThemeConfig } from 'react-select/dist/declarations/src/theme';
|
||||
import type { GroupBase } from 'react-select/dist/declarations/src/types';
|
||||
import type { StateManagerProps } from 'react-select/dist/declarations/src/useStateManager';
|
||||
|
||||
export class ArduinoSelect<T> extends Select<T> {
|
||||
constructor(props: Readonly<Props<T, false>>) {
|
||||
export class ArduinoSelect<
|
||||
Option,
|
||||
IsMulti extends boolean = false,
|
||||
Group extends GroupBase<Option> = GroupBase<Option>
|
||||
> extends React.Component<StateManagerProps<Option, IsMulti, Group>> {
|
||||
constructor(props: StateManagerProps<Option, IsMulti, Group>) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
override render(): React.ReactNode {
|
||||
const controlHeight = 27; // from `monitor.css` -> `.serial-monitor-container .head` (`height: 27px;`)
|
||||
const styles: Styles<T, false> = {
|
||||
const styles: StylesConfig = {
|
||||
control: (styles) => ({
|
||||
...styles,
|
||||
minWidth: 120,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import * as React from '@theia/core/shared/react';
|
||||
import * as ReactDOM from '@theia/core/shared/react-dom';
|
||||
import type { Root } from '@theia/core/shared/react-dom/client';
|
||||
import {
|
||||
inject,
|
||||
injectable,
|
||||
@ -49,8 +49,8 @@ export class CloudSketchbookCompositeWidget extends BaseSketchbookCompositeWidge
|
||||
return this.cloudSketchbookTreeWidget;
|
||||
}
|
||||
|
||||
protected renderFooter(footerNode: HTMLElement): void {
|
||||
ReactDOM.render(
|
||||
protected renderFooter(footerRoot: Root): void {
|
||||
footerRoot.render(
|
||||
<>
|
||||
{this._session && (
|
||||
<CreateNew
|
||||
@ -67,8 +67,7 @@ export class CloudSketchbookCompositeWidget extends BaseSketchbookCompositeWidge
|
||||
}
|
||||
authenticationService={this.authenticationService}
|
||||
/>
|
||||
</>,
|
||||
footerNode
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import * as React from '@theia/core/shared/react';
|
||||
import * as ReactDOM from '@theia/core/shared/react-dom';
|
||||
import { createRoot, Root } from '@theia/core/shared/react-dom/client';
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import { nls } from '@theia/core/lib/common/nls';
|
||||
import { Widget } from '@theia/core/shared/@phosphor/widgets';
|
||||
@ -18,29 +18,30 @@ export abstract class BaseSketchbookCompositeWidget<
|
||||
protected readonly commandService: CommandService;
|
||||
|
||||
private readonly compositeNode: HTMLElement;
|
||||
private readonly footerNode: HTMLElement;
|
||||
private readonly footerRoot: Root;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.compositeNode = document.createElement('div');
|
||||
this.compositeNode.classList.add('composite-node');
|
||||
this.footerNode = document.createElement('div');
|
||||
this.footerNode.classList.add('footer-node');
|
||||
this.compositeNode.appendChild(this.footerNode);
|
||||
const footerNode = document.createElement('div');
|
||||
footerNode.classList.add('footer-node');
|
||||
this.compositeNode.appendChild(footerNode);
|
||||
this.footerRoot = createRoot(footerNode);
|
||||
this.node.appendChild(this.compositeNode);
|
||||
this.title.closable = false;
|
||||
}
|
||||
|
||||
abstract get treeWidget(): TW;
|
||||
protected abstract renderFooter(footerNode: HTMLElement): void;
|
||||
protected abstract renderFooter(footerRoot: Root): void;
|
||||
protected updateFooter(): void {
|
||||
this.renderFooter(this.footerNode);
|
||||
this.renderFooter(this.footerRoot);
|
||||
}
|
||||
|
||||
protected override onAfterAttach(message: Message): void {
|
||||
super.onAfterAttach(message);
|
||||
Widget.attach(this.treeWidget, this.compositeNode);
|
||||
this.renderFooter(this.footerNode);
|
||||
this.renderFooter(this.footerRoot);
|
||||
this.toDisposeOnDetach.push(
|
||||
Disposable.create(() => Widget.detach(this.treeWidget))
|
||||
);
|
||||
@ -77,13 +78,12 @@ export class SketchbookCompositeWidget extends BaseSketchbookCompositeWidget<Ske
|
||||
return this.sketchbookTreeWidget;
|
||||
}
|
||||
|
||||
protected renderFooter(footerNode: HTMLElement): void {
|
||||
ReactDOM.render(
|
||||
protected renderFooter(footerRoot: Root): void {
|
||||
footerRoot.render(
|
||||
<CreateNew
|
||||
label={nls.localize('arduino/sketchbook/newSketch', 'New Sketch')}
|
||||
onClick={this.onDidClickCreateNew}
|
||||
/>,
|
||||
footerNode
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,23 +1,25 @@
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import * as remote from '@theia/core/electron-shared/@electron/remote';
|
||||
import { isOSX } from '@theia/core/lib/common/os';
|
||||
import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider';
|
||||
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
||||
import {
|
||||
ActionMenuNode,
|
||||
CompositeMenuNode,
|
||||
CommandMenuNode,
|
||||
CompoundMenuNode,
|
||||
CompoundMenuNodeRole,
|
||||
MAIN_MENU_BAR,
|
||||
MenuNode,
|
||||
MenuPath,
|
||||
} from '@theia/core/lib/common/menu';
|
||||
import { isOSX } from '@theia/core/lib/common/os';
|
||||
import {
|
||||
ElectronMainMenuFactory as TheiaElectronMainMenuFactory,
|
||||
ElectronMenuItemRole,
|
||||
ElectronMenuOptions,
|
||||
} from '@theia/core/lib/electron-browser/menu/electron-main-menu-factory';
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import {
|
||||
ArduinoMenus,
|
||||
PlaceholderMenuNode,
|
||||
} from '../../../browser/menu/arduino-menus';
|
||||
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
||||
|
||||
@injectable()
|
||||
export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory {
|
||||
@ -40,7 +42,9 @@ export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory {
|
||||
override createElectronMenuBar(): Electron.Menu {
|
||||
this._toggledCommands.clear(); // https://github.com/eclipse-theia/theia/issues/8977
|
||||
const menuModel = this.menuProvider.getMenu(MAIN_MENU_BAR);
|
||||
const template = this.fillMenuTemplate([], menuModel);
|
||||
const template = this.fillMenuTemplate([], menuModel, [], {
|
||||
rootMenuPath: MAIN_MENU_BAR,
|
||||
});
|
||||
if (isOSX) {
|
||||
template.unshift(this.createOSXMenu());
|
||||
}
|
||||
@ -68,11 +72,15 @@ export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory {
|
||||
|
||||
override createElectronContextMenu(
|
||||
menuPath: MenuPath,
|
||||
args?: any[]
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
args?: any[],
|
||||
context?: HTMLElement
|
||||
): Electron.Menu {
|
||||
const menuModel = this.menuProvider.getMenu(menuPath);
|
||||
const template = this.fillMenuTemplate([], menuModel, args, {
|
||||
showDisabled: false,
|
||||
context,
|
||||
rootMenuPath: menuPath,
|
||||
});
|
||||
return remote.Menu.buildFromTemplate(this.escapeAmpersand(template));
|
||||
}
|
||||
@ -96,20 +104,26 @@ export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory {
|
||||
|
||||
protected override createOSXMenu(): Electron.MenuItemConstructorOptions {
|
||||
const { submenu } = super.createOSXMenu();
|
||||
const label = 'Arduino IDE';
|
||||
const label = FrontendApplicationConfigProvider.get().applicationName;
|
||||
if (!!submenu && Array.isArray(submenu)) {
|
||||
const [, , /* about */ /* preferences */ ...rest] = submenu;
|
||||
const about = this.fillMenuTemplate(
|
||||
[],
|
||||
this.menuProvider.getMenu(ArduinoMenus.HELP__ABOUT_GROUP)
|
||||
this.menuProvider.getMenu(ArduinoMenus.HELP__ABOUT_GROUP),
|
||||
[],
|
||||
{ rootMenuPath: ArduinoMenus.HELP__ABOUT_GROUP }
|
||||
);
|
||||
const preferences = this.fillMenuTemplate(
|
||||
[],
|
||||
this.menuProvider.getMenu(ArduinoMenus.FILE__PREFERENCES_GROUP)
|
||||
this.menuProvider.getMenu(ArduinoMenus.FILE__PREFERENCES_GROUP),
|
||||
[],
|
||||
{ rootMenuPath: ArduinoMenus.FILE__PREFERENCES_GROUP }
|
||||
);
|
||||
const advanced = this.fillMenuTemplate(
|
||||
[],
|
||||
this.menuProvider.getMenu(ArduinoMenus.FILE__ADVANCED_GROUP)
|
||||
this.menuProvider.getMenu(ArduinoMenus.FILE__ADVANCED_GROUP),
|
||||
[],
|
||||
{ rootMenuPath: ArduinoMenus.FILE__ADVANCED_GROUP }
|
||||
);
|
||||
return {
|
||||
label,
|
||||
@ -126,7 +140,7 @@ export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory {
|
||||
return { label, submenu };
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars
|
||||
protected override roleFor(id: string): ElectronMenuItemRole | undefined {
|
||||
// MenuItem `roles` are completely broken on macOS:
|
||||
// - https://github.com/eclipse-theia/theia/issues/11217,
|
||||
@ -135,135 +149,133 @@ export class ElectronMainMenuFactory extends TheiaElectronMainMenuFactory {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
protected override handleElectronDefault(
|
||||
menuNode: MenuNode,
|
||||
args: any[] = [],
|
||||
options?: ElectronMenuOptions
|
||||
protected override fillMenuTemplate(
|
||||
parentItems: Electron.MenuItemConstructorOptions[],
|
||||
menuModel: MenuNode,
|
||||
args: unknown[] | undefined,
|
||||
options: ElectronMenuOptions
|
||||
): Electron.MenuItemConstructorOptions[] {
|
||||
if (menuNode instanceof PlaceholderMenuNode) {
|
||||
return [
|
||||
{
|
||||
label: menuNode.label,
|
||||
enabled: false,
|
||||
visible: true,
|
||||
},
|
||||
];
|
||||
if (menuModel instanceof PlaceholderMenuNode) {
|
||||
parentItems.push({
|
||||
label: menuModel.label,
|
||||
enabled: false,
|
||||
visible: true,
|
||||
});
|
||||
} else {
|
||||
this.superFillMenuTemplate(parentItems, menuModel, args, options);
|
||||
}
|
||||
return [];
|
||||
return parentItems;
|
||||
}
|
||||
|
||||
// Copied from 1.25.0 Theia as is to customize the enablement of the menu items.
|
||||
// Source: https://github.com/eclipse-theia/theia/blob/ca417a31e402bd35717d3314bf6254049d1dae44/packages/core/src/electron-browser/menu/electron-main-menu-factory.ts#L125-L220
|
||||
// Copied from 1.31.1 Theia as is to customize the enablement of the menu items.
|
||||
// Source: https://github.com/eclipse-theia/theia/blob/5e641750af83383f2ce0cb3432ec333df70778a8/packages/core/src/electron-browser/menu/electron-main-menu-factory.ts#L132-L203
|
||||
// See https://github.com/arduino/arduino-ide/issues/1533
|
||||
protected override fillMenuTemplate(
|
||||
items: Electron.MenuItemConstructorOptions[],
|
||||
menuModel: CompositeMenuNode,
|
||||
args: any[] = [],
|
||||
options?: ElectronMenuOptions
|
||||
private superFillMenuTemplate(
|
||||
parentItems: Electron.MenuItemConstructorOptions[],
|
||||
menu: MenuNode,
|
||||
args: unknown[] = [],
|
||||
options: ElectronMenuOptions
|
||||
): Electron.MenuItemConstructorOptions[] {
|
||||
const showDisabled =
|
||||
options?.showDisabled === undefined ? true : options?.showDisabled;
|
||||
for (const menu of menuModel.children) {
|
||||
if (menu instanceof CompositeMenuNode) {
|
||||
if (menu.children.length > 0) {
|
||||
// do not render empty nodes
|
||||
|
||||
if (menu.isSubmenu) {
|
||||
// submenu node
|
||||
|
||||
const submenu = this.fillMenuTemplate([], menu, args, options);
|
||||
if (submenu.length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
items.push({
|
||||
label: menu.label,
|
||||
submenu,
|
||||
});
|
||||
} else {
|
||||
// group node
|
||||
|
||||
// process children
|
||||
const submenu = this.fillMenuTemplate([], menu, args, options);
|
||||
if (submenu.length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (items.length > 0) {
|
||||
// do not put a separator above the first group
|
||||
|
||||
items.push({
|
||||
type: 'separator',
|
||||
});
|
||||
}
|
||||
|
||||
// render children
|
||||
items.push(...submenu);
|
||||
}
|
||||
}
|
||||
} else if (menu instanceof ActionMenuNode) {
|
||||
const node =
|
||||
menu.altNode && this.context.altPressed ? menu.altNode : menu;
|
||||
const commandId = node.action.commandId;
|
||||
|
||||
// That is only a sanity check at application startup.
|
||||
if (!this.commandRegistry.getCommand(commandId)) {
|
||||
console.debug(
|
||||
`Skipping menu item with missing command: "${commandId}".`
|
||||
);
|
||||
continue;
|
||||
}
|
||||
const showDisabled = options?.showDisabled !== false;
|
||||
|
||||
if (
|
||||
CompoundMenuNode.is(menu) &&
|
||||
menu.children.length &&
|
||||
this.undefinedOrMatch(menu.when, options.context)
|
||||
) {
|
||||
const role = CompoundMenuNode.getRole(menu);
|
||||
if (role === CompoundMenuNodeRole.Group && menu.id === 'inline') {
|
||||
return parentItems;
|
||||
}
|
||||
const children = CompoundMenuNode.getFlatChildren(menu.children);
|
||||
const myItems: Electron.MenuItemConstructorOptions[] = [];
|
||||
children.forEach((child) =>
|
||||
this.fillMenuTemplate(myItems, child, args, options)
|
||||
);
|
||||
if (myItems.length === 0) {
|
||||
return parentItems;
|
||||
}
|
||||
if (role === CompoundMenuNodeRole.Submenu) {
|
||||
parentItems.push({ label: menu.label, submenu: myItems });
|
||||
} else if (role === CompoundMenuNodeRole.Group && menu.id !== 'inline') {
|
||||
if (
|
||||
!this.commandRegistry.isVisible(commandId, ...args) ||
|
||||
(!!node.action.when &&
|
||||
!this.contextKeyService.match(node.action.when))
|
||||
parentItems.length &&
|
||||
parentItems[parentItems.length - 1].type !== 'separator'
|
||||
) {
|
||||
continue;
|
||||
parentItems.push({ type: 'separator' });
|
||||
}
|
||||
parentItems.push(...myItems);
|
||||
parentItems.push({ type: 'separator' });
|
||||
}
|
||||
} else if (menu.command) {
|
||||
const node =
|
||||
menu.altNode && this.context.altPressed
|
||||
? menu.altNode
|
||||
: (menu as MenuNode & CommandMenuNode);
|
||||
const commandId = node.command;
|
||||
|
||||
// We should omit rendering context-menu items which are disabled.
|
||||
if (
|
||||
!showDisabled &&
|
||||
!this.commandRegistry.isEnabled(commandId, ...args)
|
||||
) {
|
||||
continue;
|
||||
// That is only a sanity check at application startup.
|
||||
if (!this.commandRegistry.getCommand(commandId)) {
|
||||
console.debug(
|
||||
`Skipping menu item with missing command: "${commandId}".`
|
||||
);
|
||||
return parentItems;
|
||||
}
|
||||
|
||||
if (
|
||||
!this.menuCommandExecutor.isVisible(
|
||||
options.rootMenuPath,
|
||||
commandId,
|
||||
...args
|
||||
) ||
|
||||
!this.undefinedOrMatch(node.when, options.context)
|
||||
) {
|
||||
return parentItems;
|
||||
}
|
||||
|
||||
// We should omit rendering context-menu items which are disabled.
|
||||
if (
|
||||
!showDisabled &&
|
||||
!this.menuCommandExecutor.isEnabled(
|
||||
options.rootMenuPath,
|
||||
commandId,
|
||||
...args
|
||||
)
|
||||
) {
|
||||
return parentItems;
|
||||
}
|
||||
|
||||
const bindings =
|
||||
this.keybindingRegistry.getKeybindingsForCommand(commandId);
|
||||
|
||||
const accelerator = bindings[0] && this.acceleratorFor(bindings[0]);
|
||||
|
||||
const menuItem: Electron.MenuItemConstructorOptions = {
|
||||
id: node.id,
|
||||
label: node.label,
|
||||
type: this.commandRegistry.getToggledHandler(commandId, ...args)
|
||||
? 'checkbox'
|
||||
: 'normal',
|
||||
checked: this.commandRegistry.isToggled(commandId, ...args),
|
||||
enabled: this.commandRegistry.isEnabled(commandId, ...args), // Unlike Theia https://github.com/eclipse-theia/theia/blob/v1.31.1/packages/core/src/electron-browser/menu/electron-main-menu-factory.ts#L183
|
||||
visible: true,
|
||||
accelerator,
|
||||
click: () => this.execute(commandId, args, options.rootMenuPath),
|
||||
};
|
||||
|
||||
if (isOSX) {
|
||||
const role = this.roleFor(node.id);
|
||||
if (role) {
|
||||
menuItem.role = role;
|
||||
delete menuItem.click;
|
||||
}
|
||||
}
|
||||
parentItems.push(menuItem);
|
||||
|
||||
const bindings =
|
||||
this.keybindingRegistry.getKeybindingsForCommand(commandId);
|
||||
|
||||
const accelerator = bindings[0] && this.acceleratorFor(bindings[0]);
|
||||
|
||||
const menuItem: Electron.MenuItemConstructorOptions = {
|
||||
id: node.id,
|
||||
label: node.label,
|
||||
type: this.commandRegistry.getToggledHandler(commandId, ...args)
|
||||
? 'checkbox'
|
||||
: 'normal',
|
||||
checked: this.commandRegistry.isToggled(commandId, ...args),
|
||||
enabled: this.commandRegistry.isEnabled(commandId, ...args), // Unlike Theia https://github.com/eclipse-theia/theia/blob/ca417a31e402bd35717d3314bf6254049d1dae44/packages/core/src/electron-browser/menu/electron-main-menu-factory.ts#L197
|
||||
visible: true,
|
||||
accelerator,
|
||||
click: () => this.execute(commandId, args),
|
||||
};
|
||||
|
||||
if (isOSX) {
|
||||
const role = this.roleFor(node.id);
|
||||
if (role) {
|
||||
menuItem.role = role;
|
||||
delete menuItem.click;
|
||||
}
|
||||
}
|
||||
items.push(menuItem);
|
||||
|
||||
if (this.commandRegistry.getToggledHandler(commandId, ...args)) {
|
||||
this._toggledCommands.add(commandId);
|
||||
}
|
||||
} else {
|
||||
items.push(...this.handleElectronDefault(menu, args, options));
|
||||
if (this.commandRegistry.getToggledHandler(commandId, ...args)) {
|
||||
this._toggledCommands.add(commandId);
|
||||
}
|
||||
}
|
||||
return items;
|
||||
return parentItems;
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import {
|
||||
ElectronMainApplication as TheiaElectronMainApplication,
|
||||
ElectronMainApplicationContribution,
|
||||
} from '@theia/core/lib/electron-main/electron-main-application';
|
||||
import { ElectronMessagingContribution as TheiaElectronMessagingContribution } from '@theia/core/lib/electron-main/messaging/electron-messaging-contribution';
|
||||
import { TheiaElectronWindow as DefaultTheiaElectronWindow } from '@theia/core/lib/electron-main/theia-electron-window';
|
||||
import { ContainerModule } from '@theia/core/shared/inversify';
|
||||
import {
|
||||
@ -17,8 +18,8 @@ import { IsTempSketch } from '../node/is-temp-sketch';
|
||||
import { IDEUpdaterImpl } from './ide-updater/ide-updater-impl';
|
||||
import { ElectronMainApplication } from './theia/electron-main-application';
|
||||
import { ElectronMainWindowServiceImpl } from './theia/electron-main-window-service';
|
||||
import { ElectronMessagingContribution } from './theia/electron-messaging-contribution';
|
||||
import { TheiaElectronWindow } from './theia/theia-electron-window';
|
||||
import { ElectronNativeKeymap } from '@theia/core/lib/electron-main/electron-native-keymap';
|
||||
|
||||
export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
bind(ElectronMainApplication).toSelf().inSingletonScope();
|
||||
@ -60,7 +61,9 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
|
||||
bind(IsTempSketch).toSelf().inSingletonScope();
|
||||
|
||||
// https://github.com/eclipse-theia/theia/issues/11688
|
||||
bind(ElectronNativeKeymap).toSelf().inSingletonScope();
|
||||
bind(ElectronMainApplicationContribution).toService(ElectronNativeKeymap);
|
||||
// Fix for cannot reload window: https://github.com/eclipse-theia/theia/issues/11600
|
||||
bind(ElectronMessagingContribution).toSelf().inSingletonScope();
|
||||
rebind(TheiaElectronMessagingContribution).toService(
|
||||
ElectronMessagingContribution
|
||||
);
|
||||
});
|
||||
|
@ -0,0 +1,44 @@
|
||||
import { ChannelMultiplexer } from '@theia/core/lib/common/message-rpc/channel';
|
||||
import {
|
||||
ElectronMessagingContribution as TheiaElectronMessagingContribution,
|
||||
ElectronWebContentChannel,
|
||||
} from '@theia/core/lib/electron-main/messaging/electron-messaging-contribution';
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
|
||||
// Electron window cannot reload: https://github.com/eclipse-theia/theia/issues/11600
|
||||
// This patch fixes it by removing the channel multiplexer from the cache.
|
||||
// A related PR in Theia: https://github.com/eclipse-theia/theia/pull/11810
|
||||
@injectable()
|
||||
export class ElectronMessagingContribution extends TheiaElectronMessagingContribution {
|
||||
// Based on: https://github.com/kittaakos/theia/commit/12dd318df589f1c48de2b58545912d8385919b22
|
||||
protected override createWindowChannelData(sender: Electron.WebContents): {
|
||||
channel: ElectronWebContentChannel;
|
||||
multiplexer: ChannelMultiplexer;
|
||||
} {
|
||||
const mainChannel = this.createWindowMainChannel(sender);
|
||||
const multiplexer = new ChannelMultiplexer(mainChannel);
|
||||
multiplexer.onDidOpenChannel((openEvent) => {
|
||||
const { channel, id } = openEvent;
|
||||
if (this.channelHandlers.route(id, channel)) {
|
||||
console.debug(`Opening channel for service path '${id}'.`);
|
||||
channel.onClose(() =>
|
||||
console.debug(`Closing channel on service path '${id}'.`)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// When refreshing the browser window.
|
||||
sender.once('did-navigate', () => {
|
||||
multiplexer.onUnderlyingChannelClose({ reason: 'Window was refreshed' });
|
||||
this.windowChannelMultiplexer.delete(sender.id);
|
||||
});
|
||||
// When closing the browser window.
|
||||
sender.once('destroyed', () => {
|
||||
multiplexer.onUnderlyingChannelClose({ reason: 'Window was closed' });
|
||||
this.windowChannelMultiplexer.delete(sender.id);
|
||||
});
|
||||
const data = { channel: mainChannel, multiplexer };
|
||||
this.windowChannelMultiplexer.set(sender.id, data);
|
||||
return data;
|
||||
}
|
||||
}
|
@ -1,46 +1,16 @@
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
import { ipcMain, IpcMainEvent } from '@theia/electron/shared/electron';
|
||||
import {
|
||||
RELOAD_REQUESTED_SIGNAL,
|
||||
StopReason,
|
||||
} from '@theia/core/lib/electron-common/messaging/electron-messages';
|
||||
import { TheiaElectronWindow as DefaultTheiaElectronWindow } from '@theia/core/lib/electron-main/theia-electron-window';
|
||||
import { FileUri } from '@theia/core/lib/node';
|
||||
import URI from '@theia/core/lib/common/uri';
|
||||
import { createDisposableListener } from '@theia/core/lib/electron-main/event-utils';
|
||||
import { TheiaElectronWindow as DefaultTheiaElectronWindow } from '@theia/core/lib/electron-main/theia-electron-window';
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
import { ipcMain, IpcMainEvent } from '@theia/electron/shared/electron';
|
||||
import { StartupTask } from '../../electron-common/startup-task';
|
||||
import { load } from './window';
|
||||
|
||||
@injectable()
|
||||
export class TheiaElectronWindow extends DefaultTheiaElectronWindow {
|
||||
protected override async handleStopRequest(
|
||||
onSafeCallback: () => unknown,
|
||||
reason: StopReason
|
||||
): Promise<boolean> {
|
||||
// Only confirm close to windows that have loaded our frontend.
|
||||
// Both the windows's URL and the FS path of the `index.html` should be converted to the "same" format to be able to compare them. (#11226)
|
||||
// Notes:
|
||||
// - Windows: file:///C:/path/to/somewhere vs file:///c%3A/path/to/somewhere
|
||||
// - macOS: file:///Applications/App%20Name.app/Contents vs /Applications/App Name.app/Contents
|
||||
// This URL string comes from electron, we can expect that this is properly encoded URL. For example, a space is `%20`
|
||||
const currentUrl = new URI(this.window.webContents.getURL()).toString();
|
||||
// THEIA_FRONTEND_HTML_PATH is an FS path, we have to covert to an encoded URI string.
|
||||
const frontendUri = FileUri.create(
|
||||
this.globals.THEIA_FRONTEND_HTML_PATH
|
||||
).toString();
|
||||
const safeToClose =
|
||||
!currentUrl.includes(frontendUri) || (await this.checkSafeToStop(reason));
|
||||
if (safeToClose) {
|
||||
try {
|
||||
await onSafeCallback();
|
||||
return true;
|
||||
} catch (e) {
|
||||
console.warn(`Request ${StopReason[reason]} failed.`, e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override reload(tasks?: StartupTask[]): void {
|
||||
this.handleStopRequest(() => {
|
||||
this.applicationState = 'init';
|
||||
|
@ -100,8 +100,8 @@ import WebSocketProviderImpl from './web-socket/web-socket-provider-impl';
|
||||
import { WebSocketProvider } from './web-socket/web-socket-provider';
|
||||
import { ClangFormatter } from './clang-formatter';
|
||||
import { FormatterPath } from '../common/protocol/formatter';
|
||||
import { LocalizationBackendContribution } from './i18n/localization-backend-contribution';
|
||||
import { LocalizationBackendContribution as TheiaLocalizationBackendContribution } from '@theia/core/lib/node/i18n/localization-backend-contribution';
|
||||
import { HostedPluginLocalizationService } from './theia/plugin-ext/hosted-plugin-localization-service';
|
||||
import { HostedPluginLocalizationService as TheiaHostedPluginLocalizationService } from '@theia/plugin-ext/lib/hosted/node/hosted-plugin-localization-service';
|
||||
import { SurveyNotificationServiceImpl } from './survey-service-impl';
|
||||
import {
|
||||
SurveyNotificationService,
|
||||
@ -360,9 +360,9 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
||||
bind(BackendApplicationContribution).toService(PlotterBackendContribution);
|
||||
bind(ArduinoLocalizationContribution).toSelf().inSingletonScope();
|
||||
bind(LocalizationContribution).toService(ArduinoLocalizationContribution);
|
||||
bind(LocalizationBackendContribution).toSelf().inSingletonScope();
|
||||
rebind(TheiaLocalizationBackendContribution).toService(
|
||||
LocalizationBackendContribution
|
||||
bind(HostedPluginLocalizationService).toSelf().inSingletonScope();
|
||||
rebind(TheiaHostedPluginLocalizationService).toService(
|
||||
HostedPluginLocalizationService
|
||||
);
|
||||
|
||||
// Survey notification bindings
|
||||
|
@ -1,45 +0,0 @@
|
||||
import * as express from 'express';
|
||||
import { inject, injectable } from '@theia/core/shared/inversify';
|
||||
import { LocalizationBackendContribution as TheiaLocalizationBackendContribution } from '@theia/core/lib/node/i18n/localization-backend-contribution';
|
||||
import { PluginDeployer } from '@theia/plugin-ext/lib/common/plugin-protocol';
|
||||
import { PluginDeployerImpl } from '@theia/plugin-ext/lib/main/node/plugin-deployer-impl';
|
||||
import { Deferred } from '@theia/core/lib/common/promise-util';
|
||||
|
||||
@injectable()
|
||||
export class LocalizationBackendContribution extends TheiaLocalizationBackendContribution {
|
||||
@inject(PluginDeployer)
|
||||
private readonly pluginDeployer: PluginDeployerImpl;
|
||||
|
||||
private readonly initialized = new Deferred<void>();
|
||||
|
||||
override async initialize(): Promise<void> {
|
||||
this.pluginDeployer.onDidDeploy(() => {
|
||||
this.initialized.resolve();
|
||||
});
|
||||
return super.initialize();
|
||||
}
|
||||
|
||||
override configure(app: express.Application): void {
|
||||
app.get('/i18n/:locale', async (req, res) => {
|
||||
let locale = req.params.locale;
|
||||
/*
|
||||
Waiting for the deploy of the language plugins is necessary to avoid checking the available
|
||||
languages before they're finished to be loaded: https://github.com/eclipse-theia/theia/issues/11471
|
||||
*/
|
||||
const start = performance.now();
|
||||
await this.initialized.promise;
|
||||
console.info(
|
||||
'Waiting for the deploy of the language plugins took: ' +
|
||||
(performance.now() - start) +
|
||||
' ms.'
|
||||
);
|
||||
locale = this.localizationProvider
|
||||
.getAvailableLanguages()
|
||||
.some((e) => e.languageId === locale)
|
||||
? locale
|
||||
: 'en';
|
||||
this.localizationProvider.setCurrentLanguage(locale);
|
||||
res.send(this.localizationProvider.loadLocalization(locale));
|
||||
});
|
||||
}
|
||||
}
|
@ -12,7 +12,7 @@ import {
|
||||
} from './cli-protocol/cc/arduino/cli/commands/v1/monitor_pb';
|
||||
import { CoreClientAware } from './core-client-provider';
|
||||
import { WebSocketProvider } from './web-socket/web-socket-provider';
|
||||
import { Port as RpcPort } from 'arduino-ide-extension/src/node/cli-protocol/cc/arduino/cli/commands/v1/port_pb';
|
||||
import { Port as RpcPort } from './cli-protocol/cc/arduino/cli/commands/v1/port_pb';
|
||||
import {
|
||||
MonitorSettings,
|
||||
PluggableMonitorSettings,
|
||||
|
@ -1,6 +1,10 @@
|
||||
import * as fs from 'fs';
|
||||
import { join } from 'path';
|
||||
import { injectable, inject, postConstruct } from 'inversify';
|
||||
import {
|
||||
injectable,
|
||||
inject,
|
||||
postConstruct,
|
||||
} from '@theia/core/shared/inversify';
|
||||
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
|
||||
import { FileUri } from '@theia/core/lib/node/file-uri';
|
||||
import { promisify } from 'util';
|
||||
@ -95,7 +99,7 @@ export class MonitorSettingsProviderImpl implements MonitorSettingsProvider {
|
||||
const rawJson = await promisify(fs.readFile)(
|
||||
this.pluggableMonitorSettingsPath,
|
||||
{
|
||||
encoding: 'utf-8',
|
||||
encoding: 'utf8',
|
||||
flag: 'a+', // a+ = append and read, creating the file if it doesn't exist
|
||||
}
|
||||
);
|
||||
|
@ -1,5 +1,5 @@
|
||||
import * as path from 'path';
|
||||
import * as express from 'express';
|
||||
import * as express from '@theia/core/shared/express';
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
import { BackendApplicationContribution } from '@theia/core/lib/node/backend-application';
|
||||
|
||||
|
@ -0,0 +1,13 @@
|
||||
import * as fs from '@theia/core/shared/fs-extra';
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
import { HostedPluginLocalizationService as TheiaHostedPluginLocalizationService } from '@theia/plugin-ext/lib/hosted/node/hosted-plugin-localization-service';
|
||||
|
||||
@injectable()
|
||||
export class HostedPluginLocalizationService extends TheiaHostedPluginLocalizationService {
|
||||
// Remove when https://github.com/eclipse-theia/theia/pull/11853 is available from Theia.
|
||||
override async initialize(): Promise<void> {
|
||||
this.getLocalizationCacheDir()
|
||||
.then((cacheDir) => fs.emptyDir(cacheDir))
|
||||
.then(() => this._ready.resolve());
|
||||
}
|
||||
}
|
@ -71,7 +71,7 @@ namespace Chunks {
|
||||
if (current && current.buffers) {
|
||||
result.push([
|
||||
current.severity,
|
||||
Buffer.concat(current.buffers).toString('utf-8'),
|
||||
Buffer.concat(current.buffers).toString('utf8'),
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Emitter } from '@theia/core';
|
||||
import { injectable } from '@theia/core/shared/inversify';
|
||||
import * as WebSocket from 'ws';
|
||||
import * as WebSocket from '@theia/core/shared/ws';
|
||||
import { WebSocketProvider } from './web-socket-provider';
|
||||
|
||||
@injectable()
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Event } from '@theia/core/lib/common/event';
|
||||
import * as WebSocket from 'ws';
|
||||
import * as WebSocket from '@theia/core/shared/ws';
|
||||
|
||||
export const WebSocketProvider = Symbol('WebSocketProvider');
|
||||
export interface WebSocketProvider {
|
||||
|
@ -1,7 +1,5 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"noImplicitAny": true,
|
||||
"noEmitOnError": true,
|
||||
"noImplicitThis": true,
|
||||
|
@ -5,26 +5,26 @@
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"main": "src-gen/frontend/electron-main.js",
|
||||
"dependencies": {
|
||||
"@theia/core": "1.25.0",
|
||||
"@theia/debug": "1.25.0",
|
||||
"@theia/editor": "1.25.0",
|
||||
"@theia/electron": "1.25.0",
|
||||
"@theia/file-search": "1.25.0",
|
||||
"@theia/filesystem": "1.25.0",
|
||||
"@theia/keymaps": "1.25.0",
|
||||
"@theia/messages": "1.25.0",
|
||||
"@theia/monaco": "1.25.0",
|
||||
"@theia/navigator": "1.25.0",
|
||||
"@theia/plugin-ext": "1.25.0",
|
||||
"@theia/plugin-ext-vscode": "1.25.0",
|
||||
"@theia/preferences": "1.25.0",
|
||||
"@theia/process": "1.25.0",
|
||||
"@theia/terminal": "1.25.0",
|
||||
"@theia/workspace": "1.25.0",
|
||||
"@theia/core": "1.31.1",
|
||||
"@theia/debug": "1.31.1",
|
||||
"@theia/editor": "1.31.1",
|
||||
"@theia/electron": "1.31.1",
|
||||
"@theia/file-search": "1.31.1",
|
||||
"@theia/filesystem": "1.31.1",
|
||||
"@theia/keymaps": "1.31.1",
|
||||
"@theia/messages": "1.31.1",
|
||||
"@theia/monaco": "1.31.1",
|
||||
"@theia/navigator": "1.31.1",
|
||||
"@theia/plugin-ext": "1.31.1",
|
||||
"@theia/plugin-ext-vscode": "1.31.1",
|
||||
"@theia/preferences": "1.31.1",
|
||||
"@theia/process": "1.31.1",
|
||||
"@theia/terminal": "1.31.1",
|
||||
"@theia/workspace": "1.31.1",
|
||||
"arduino-ide-extension": "2.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@theia/cli": "1.25.0",
|
||||
"@theia/cli": "1.31.1",
|
||||
"electron": "^15.3.5"
|
||||
},
|
||||
"scripts": {
|
||||
@ -37,8 +37,13 @@
|
||||
"frontend": {
|
||||
"config": {
|
||||
"applicationName": "Arduino IDE",
|
||||
"defaultTheme": "arduino-theme",
|
||||
"defaultTheme": {
|
||||
"light": "arduino-theme",
|
||||
"dark": "arduino-theme-dark"
|
||||
},
|
||||
"validatePreferencesSchema": false,
|
||||
"preferences": {
|
||||
"window.title": "${rootName}${activeEditorShort}${appName}",
|
||||
"files.autoSave": "afterDelay",
|
||||
"editor.minimap.enabled": false,
|
||||
"editor.tabSize": 2,
|
||||
@ -49,6 +54,7 @@
|
||||
"strings": false
|
||||
},
|
||||
"editor.maxTokenizationLineLength": 500,
|
||||
"editor.bracketPairColorization.enabled": false,
|
||||
"breadcrumbs.enabled": false,
|
||||
"workbench.tree.renderIndentGuides": "none",
|
||||
"explorer.compactFolders": false
|
||||
|
@ -1,152 +0,0 @@
|
||||
// Patch for the startup theme. Customizes the `ThemeService.get().defaultTheme();` to dispatch the default IDE2 theme based on the OS' theme.
|
||||
// For all subsequent starts of the IDE the theme applied will be the last one set by the user.
|
||||
|
||||
// With the current version of Theia adopted (1.25) it is not possible to extend the `ThemeService`, it will be possible starting from Theia 1.27.
|
||||
// Once the version of Theia is updated, this patch will be removed and this functionality will be implemented via dependency injection.
|
||||
// Ideally, we should open a PR in Theia and add support for `light` and `dark` default themes in the app config.
|
||||
|
||||
const {
|
||||
ThemeService,
|
||||
ThemeServiceSymbol,
|
||||
BuiltinThemeProvider,
|
||||
} = require('@theia/core/lib/browser/theming');
|
||||
const {
|
||||
ApplicationProps,
|
||||
} = require('@theia/application-package/lib/application-props');
|
||||
const {
|
||||
FrontendApplicationConfigProvider,
|
||||
} = require('@theia/core/lib/browser/frontend-application-config-provider');
|
||||
|
||||
function fetchFrom(path) {
|
||||
const { Endpoint } = require('@theia/core/lib/browser/endpoint');
|
||||
const endpoint = new Endpoint({ path }).getRestUrl().toString();
|
||||
return fetch(endpoint);
|
||||
}
|
||||
|
||||
async function loadTranslations() {
|
||||
const { nls } = require('@theia/core/lib/common/nls');
|
||||
const defaultLocale = typeof window === 'object' && window && window.localStorage.getItem(nls.localeId) || '';
|
||||
if (defaultLocale && !nls.locale) {
|
||||
Object.assign(nls, {
|
||||
locale: defaultLocale
|
||||
});
|
||||
}
|
||||
if (nls.locale) {
|
||||
const response = await fetchFrom(`/i18n/${nls.locale}`);
|
||||
nls.localization = await response.json();
|
||||
}
|
||||
}
|
||||
|
||||
async function loadBackendOS() {
|
||||
const response = await fetchFrom('/os');
|
||||
const osType = await response.text();
|
||||
const isWindows = osType === 'Windows';
|
||||
const isOSX = osType === 'OSX';
|
||||
OS.backend.isOSX = isOSX;
|
||||
OS.backend.isWindows = isWindows;
|
||||
OS.backend.type = () => osType;
|
||||
}
|
||||
|
||||
function customizeMonacoNls() {
|
||||
const MonacoNls = require('@theia/monaco-editor-core/esm/vs/nls');
|
||||
const { nls: TheiaNls } = require('@theia/core/lib/common/nls');
|
||||
const { Localization } = require('@theia/core/lib/common/i18n/localization');
|
||||
Object.assign(MonacoNls, {
|
||||
localize(_, label, ...args) {
|
||||
if (TheiaNls.locale) {
|
||||
const defaultKey = TheiaNls.getDefaultKey(label);
|
||||
if (defaultKey) {
|
||||
return TheiaNls.localize(defaultKey, label, ...args);
|
||||
}
|
||||
}
|
||||
return Localization.format(label, args);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// It is a mighty hack to support theme updates in the bundled IDE2.
|
||||
// If the custom theme registration happens before the restoration of the existing monaco themes, then any custom theme changes will be ignored.
|
||||
// This patch introduces a static deferred promise in the monaco-theming service that will be resolved when the restoration is ready.
|
||||
// IDE2 cannot require the monaco theme service on the outer module level, as it requires the application config provider to be initialized,
|
||||
// but the initialization happens only in the generated `index.js`.
|
||||
// This patch customizes the monaco theme service behavior before loading the DI containers via the preload.
|
||||
// The preload is called only once before the app loads. The Theia extensions are not loaded at that point, but the app config provider is ready.
|
||||
const preloader = require('@theia/core/lib/browser/preloader');
|
||||
preloader.preload = async function () {
|
||||
// Must require the monaco frontend module to activate the NLS customization for monaco.
|
||||
// Otherwise, the NLS customization would trigger after the monaco UI components with all their translations are already loaded.
|
||||
await Promise.allSettled([
|
||||
loadTranslations(),
|
||||
loadBackendOS(),
|
||||
]);
|
||||
customizeMonacoNls();
|
||||
const { MonacoThemingService } = require('@theia/monaco/lib/browser/monaco-theming-service');
|
||||
const { MonacoThemeServiceIsReady } = require('arduino-ide-extension/lib/browser/utils/window');
|
||||
const { Deferred } = require('@theia/core/lib/common/promise-util');
|
||||
const ready = new Deferred();
|
||||
if (!window[MonacoThemeServiceIsReady]) {
|
||||
window[MonacoThemeServiceIsReady] = ready;
|
||||
console.log('Registered a custom monaco-theme service initialization signal on the window object.');
|
||||
}
|
||||
// Here, it is safe to patch the theme service, app config provider is ready.
|
||||
MonacoThemingService.init = async function () {
|
||||
this.updateBodyUiTheme();
|
||||
ThemeService.get().onDidColorThemeChange(() => this.updateBodyUiTheme());
|
||||
await this.restore();
|
||||
ready.resolve();
|
||||
}.bind(MonacoThemingService);
|
||||
}.bind(preloader);
|
||||
|
||||
const lightTheme = 'arduino-theme';
|
||||
const darkTheme = 'arduino-theme-dark';
|
||||
const defaultTheme =
|
||||
window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
? darkTheme
|
||||
: lightTheme;
|
||||
|
||||
const originalGet = FrontendApplicationConfigProvider.get;
|
||||
FrontendApplicationConfigProvider.get = function () {
|
||||
const originalProps = originalGet.bind(FrontendApplicationConfigProvider)();
|
||||
return { ...originalProps, defaultTheme };
|
||||
}.bind(FrontendApplicationConfigProvider);
|
||||
|
||||
const arduinoDarkTheme = {
|
||||
id: 'arduino-theme-dark',
|
||||
type: 'dark',
|
||||
label: 'Dark (Arduino)',
|
||||
editorTheme: 'arduino-theme-dark',
|
||||
activate() {},
|
||||
deactivate() {},
|
||||
};
|
||||
|
||||
const arduinoLightTheme = {
|
||||
id: 'arduino-theme',
|
||||
type: 'light',
|
||||
label: 'Light (Arduino)',
|
||||
editorTheme: 'arduino-theme',
|
||||
activate() {},
|
||||
deactivate() {},
|
||||
};
|
||||
|
||||
if (!window[ThemeServiceSymbol]) {
|
||||
const themeService = new ThemeService();
|
||||
Object.defineProperty(themeService, 'defaultTheme', {
|
||||
get: function () {
|
||||
return (
|
||||
this.themes[defaultTheme] ||
|
||||
this.themes[ApplicationProps.DEFAULT.frontend.config.defaultTheme]
|
||||
);
|
||||
},
|
||||
});
|
||||
themeService.register(
|
||||
...BuiltinThemeProvider.themes,
|
||||
arduinoDarkTheme,
|
||||
arduinoLightTheme
|
||||
);
|
||||
themeService.startupTheme();
|
||||
themeService.setCurrentTheme(defaultTheme);
|
||||
window[ThemeServiceSymbol] = themeService;
|
||||
}
|
||||
|
||||
// Require the original, generated `index.js` for `webpack` as the next entry for the `bundle.js`.
|
||||
require('../../src-gen/frontend/index');
|
@ -1,26 +0,0 @@
|
||||
/**
|
||||
* This file can be edited to customize webpack configuration.
|
||||
* To reset delete this file and rerun theia build again.
|
||||
*/
|
||||
// @ts-check
|
||||
const config = require('./gen-webpack.config.js');
|
||||
|
||||
config.resolve.fallback['http'] = false;
|
||||
config.resolve.fallback['fs'] = false;
|
||||
|
||||
/**
|
||||
* Expose bundled modules on window.theia.moduleName namespace, e.g.
|
||||
* window['theia']['@theia/core/lib/common/uri'].
|
||||
* Such syntax can be used by external code, for instance, for testing.
|
||||
config.module.rules.push({
|
||||
test: /\.js$/,
|
||||
loader: require.resolve('@theia/application-manager/lib/expose-loader')
|
||||
}); */
|
||||
|
||||
|
||||
// Load the patched `index.js` that sets the desired theme in IDE2 based on the OS' theme.
|
||||
// The `patch/frontend/index.js` will require the original, generated `index.js`.
|
||||
// See: https://github.com/arduino/arduino-ide/pull/1160.
|
||||
config.entry.bundle = require('path').resolve(__dirname, 'patch/frontend/index.js');
|
||||
|
||||
module.exports = config;
|
2
electron/.gitignore
vendored
2
electron/.gitignore
vendored
@ -6,6 +6,7 @@ working-copy/
|
||||
src-gen/
|
||||
node_modules/
|
||||
build/yarn.lock
|
||||
webpack.config.js
|
||||
lib/
|
||||
|
||||
# The electron-builder output.
|
||||
@ -19,4 +20,3 @@ build/package.json
|
||||
|
||||
# Resources the packager copies from dev to prod
|
||||
build/resources/preload.html
|
||||
build/patch/frontend/index.js
|
||||
|
@ -9,7 +9,7 @@
|
||||
"node-log-rotate": "^0.1.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@theia/cli": "1.25.0",
|
||||
"@theia/cli": "1.31.1",
|
||||
"cross-env": "^7.0.2",
|
||||
"electron-builder": "23.3.3",
|
||||
"electron-notarize": "^1.1.1",
|
||||
|
@ -1,10 +0,0 @@
|
||||
// @ts-check
|
||||
const config = require('./gen-webpack.config.js');
|
||||
const path = require('path');
|
||||
|
||||
// Load the patched `index.js` that sets the desired theme in IDE2 based on the OS' theme.
|
||||
// The `patch/frontend/index.js` will require the original, generated `index.js`.
|
||||
// See: https://github.com/arduino/arduino-ide/pull/1160.
|
||||
config.entry.bundle = path.resolve(__dirname, 'patch/frontend/index.js');
|
||||
|
||||
module.exports = config;
|
@ -42,251 +42,256 @@
|
||||
);
|
||||
}
|
||||
|
||||
//---------------------------+
|
||||
// Clean the previous state. |
|
||||
//---------------------------+
|
||||
// rm -rf ../working-copy
|
||||
rm('-rf', path('..', workingCopy));
|
||||
// Clean up the `./electron/build` folder.
|
||||
const resourcesToKeep = [
|
||||
'patch',
|
||||
'resources',
|
||||
'scripts',
|
||||
'template-package.json',
|
||||
'webpack.config.js'
|
||||
];
|
||||
fs.readdirSync(path('..', 'build'))
|
||||
.filter((filename) => resourcesToKeep.indexOf(filename) === -1)
|
||||
.forEach((filename) => rm('-rf', path('..', 'build', filename)));
|
||||
try {
|
||||
//---------------------------+
|
||||
// Clean the previous state. |
|
||||
//---------------------------+
|
||||
// rm -rf ../working-copy
|
||||
rm('-rf', path('..', workingCopy));
|
||||
// Clean up the `./electron/build` folder.
|
||||
const resourcesToKeep = [
|
||||
'patch',
|
||||
'resources',
|
||||
'scripts',
|
||||
'template-package.json'
|
||||
];
|
||||
fs.readdirSync(path('..', 'build'))
|
||||
.filter((filename) => resourcesToKeep.indexOf(filename) === -1)
|
||||
.forEach((filename) => rm('-rf', path('..', 'build', filename)));
|
||||
|
||||
// Clean up the `./electron/build/patch` and `./electron/build/resources` folder with Git.
|
||||
// To avoid file duplication between bundled app and dev mode, some files are copied from `./electron-app` to `./electron/build` folder.
|
||||
const foldersToSyncFromDev = ['patch', 'resources'];
|
||||
foldersToSyncFromDev.forEach(filename => shell.exec(`git -C ${path('..', 'build', filename)} clean -ffxdq`, { async: false }));
|
||||
// Clean up the `./electron/build/resources` folder with Git.
|
||||
// To avoid file duplication between bundled app and dev mode, some files are copied from `./electron-app` to `./electron/build` folder.
|
||||
const foldersToSyncFromDev = ['resources'];
|
||||
foldersToSyncFromDev.forEach((filename) =>
|
||||
shell.exec(`git -C ${path('..', 'build', filename)} clean -ffxdq`, {
|
||||
async: false,
|
||||
})
|
||||
);
|
||||
|
||||
const extensions = require('./extensions.json');
|
||||
echo(
|
||||
`Building the application with the following extensions:\n${extensions
|
||||
.map((ext) => ` - ${ext}`)
|
||||
.join(',\n')}`
|
||||
);
|
||||
const allDependencies = [...extensions, 'electron-app'];
|
||||
const extensions = require('./extensions.json');
|
||||
echo(
|
||||
`Building the application with the following extensions:\n${extensions
|
||||
.map((ext) => ` - ${ext}`)
|
||||
.join(',\n')}`
|
||||
);
|
||||
const allDependencies = [...extensions, 'electron-app'];
|
||||
|
||||
//----------------------------------------------------------------------------------------------+
|
||||
// Copy the following items into the `working-copy` folder. Make sure to reuse the `yarn.lock`. |
|
||||
//----------------------------------------------------------------------------------------------+
|
||||
mkdir('-p', path('..', workingCopy));
|
||||
for (const filename of [
|
||||
...allDependencies,
|
||||
'yarn.lock',
|
||||
'package.json',
|
||||
'lerna.json',
|
||||
'i18n'
|
||||
]) {
|
||||
cp('-rf', path(rootPath, filename), path('..', workingCopy));
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------+
|
||||
// Copy the following items into the `working-copy` folder. Make sure to reuse the `yarn.lock`. |
|
||||
//----------------------------------------------------------------------------------------------+
|
||||
mkdir('-p', path('..', workingCopy));
|
||||
for (const filename of [
|
||||
...allDependencies,
|
||||
'yarn.lock',
|
||||
'package.json',
|
||||
'lerna.json',
|
||||
'i18n',
|
||||
]) {
|
||||
cp('-rf', path(rootPath, filename), path('..', workingCopy));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------+
|
||||
// Copy the patched `index.js` for the frontend, the Theia preload, etc. from `./electron-app` |
|
||||
//---------------------------------------------------------------------------------------------+
|
||||
for (const filename of foldersToSyncFromDev) {
|
||||
cp('-rf', path('..', workingCopy, 'electron-app', filename), path('..', 'build'));
|
||||
}
|
||||
//---------------------------------------------------------------------------------------------+
|
||||
// Copy the patched `index.js` for the frontend, the Theia preload, etc. from `./electron-app` |
|
||||
//---------------------------------------------------------------------------------------------+
|
||||
for (const filename of foldersToSyncFromDev) {
|
||||
cp(
|
||||
'-rf',
|
||||
path('..', workingCopy, 'electron-app', filename),
|
||||
path('..', 'build')
|
||||
);
|
||||
}
|
||||
|
||||
//----------------------------------------------+
|
||||
// Sanity check: all versions must be the same. |
|
||||
//----------------------------------------------+
|
||||
verifyVersions(allDependencies);
|
||||
//----------------------------------------------+
|
||||
// Sanity check: all versions must be the same. |
|
||||
//----------------------------------------------+
|
||||
verifyVersions(allDependencies);
|
||||
|
||||
//----------------------------------------------------------------------+
|
||||
// Use the nightly patch version if not a release but requires publish. |
|
||||
//----------------------------------------------------------------------+
|
||||
if (!isRelease) {
|
||||
for (const dependency of allDependencies) {
|
||||
const pkg = require(`../working-copy/${dependency}/package.json`);
|
||||
pkg.version = version;
|
||||
for (const dependency in pkg.dependencies) {
|
||||
if (allDependencies.indexOf(dependency) !== -1) {
|
||||
pkg.dependencies[dependency] = version;
|
||||
//----------------------------------------------------------------------+
|
||||
// Use the nightly patch version if not a release but requires publish. |
|
||||
//----------------------------------------------------------------------+
|
||||
if (!isRelease) {
|
||||
for (const dependency of allDependencies) {
|
||||
const pkg = require(`../working-copy/${dependency}/package.json`);
|
||||
pkg.version = version;
|
||||
for (const dependency in pkg.dependencies) {
|
||||
if (allDependencies.indexOf(dependency) !== -1) {
|
||||
pkg.dependencies[dependency] = version;
|
||||
}
|
||||
}
|
||||
fs.writeFileSync(
|
||||
path('..', workingCopy, dependency, 'package.json'),
|
||||
JSON.stringify(pkg, null, 2)
|
||||
);
|
||||
}
|
||||
fs.writeFileSync(
|
||||
path('..', workingCopy, dependency, 'package.json'),
|
||||
JSON.stringify(pkg, null, 2)
|
||||
);
|
||||
}
|
||||
}
|
||||
verifyVersions(allDependencies);
|
||||
verifyVersions(allDependencies);
|
||||
|
||||
//---------------------------------------------------------------------------------------------------+
|
||||
// Save some time: no need to build the projects that are not needed in final app. Currently unused. |
|
||||
//---------------------------------------------------------------------------------------------------+
|
||||
//@ts-ignore
|
||||
const rootPackageJson = require('../working-copy/package.json');
|
||||
const workspaces = rootPackageJson.workspaces;
|
||||
// We cannot remove the `electron-app`. Otherwise, there is not way to collect the unused dependencies.
|
||||
const dependenciesToRemove = [];
|
||||
for (const dependencyToRemove of dependenciesToRemove) {
|
||||
const index = workspaces.indexOf(dependencyToRemove);
|
||||
if (index !== -1) {
|
||||
workspaces.splice(index, 1);
|
||||
//---------------------------------------------------------------------------------------------------+
|
||||
// Save some time: no need to build the projects that are not needed in final app. Currently unused. |
|
||||
//---------------------------------------------------------------------------------------------------+
|
||||
//@ts-ignore
|
||||
const rootPackageJson = require('../working-copy/package.json');
|
||||
const workspaces = rootPackageJson.workspaces;
|
||||
// We cannot remove the `electron-app`. Otherwise, there is not way to collect the unused dependencies.
|
||||
const dependenciesToRemove = [];
|
||||
for (const dependencyToRemove of dependenciesToRemove) {
|
||||
const index = workspaces.indexOf(dependencyToRemove);
|
||||
if (index !== -1) {
|
||||
workspaces.splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
rootPackageJson.workspaces = workspaces;
|
||||
fs.writeFileSync(
|
||||
path('..', workingCopy, 'package.json'),
|
||||
JSON.stringify(rootPackageJson, null, 2)
|
||||
);
|
||||
rootPackageJson.workspaces = workspaces;
|
||||
fs.writeFileSync(
|
||||
path('..', workingCopy, 'package.json'),
|
||||
JSON.stringify(rootPackageJson, null, 2)
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------------------------------------------+
|
||||
// Rebuild the extension with the copied `yarn.lock`. It is a must to use the same Theia versions. |
|
||||
//-------------------------------------------------------------------------------------------------+
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', workingCopy)}`,
|
||||
`Building the ${productName} application`
|
||||
);
|
||||
//-------------------------------------------------------------------------------------------------+
|
||||
// Rebuild the extension with the copied `yarn.lock`. It is a must to use the same Theia versions. |
|
||||
//-------------------------------------------------------------------------------------------------+
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', workingCopy)}`,
|
||||
`Building the ${productName} application`
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------+
|
||||
// Test the application. With this approach, we cannot publish test results to GH Actions but save 6-10 minutes per builds |
|
||||
//-------------------------------------------------------------------------------------------------------------------------+
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', workingCopy)} test`,
|
||||
`Testing the ${productName} application`
|
||||
);
|
||||
//-------------------------------------------------------------------------------------------------------------------------+
|
||||
// Test the application. With this approach, we cannot publish test results to GH Actions but save 6-10 minutes per builds |
|
||||
//-------------------------------------------------------------------------------------------------------------------------+
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', workingCopy)} test`,
|
||||
`Testing the ${productName} application`
|
||||
);
|
||||
|
||||
// Collect all unused dependencies by the backend. We have to remove them from the electron app.
|
||||
// The `bundle.js` already contains everything we need for the frontend.
|
||||
// We have to do it before changing the dependencies to `local-path`.
|
||||
const unusedDependencies = await utils.collectUnusedDependencies(
|
||||
'../working-copy/electron-app/'
|
||||
);
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------+
|
||||
// Change the regular NPM dependencies to `local-paths`, so that we can build them without any NPM registries. |
|
||||
//-------------------------------------------------------------------------------------------------------------+
|
||||
for (const extension of extensions) {
|
||||
if (extension !== 'arduino-ide-extension') {
|
||||
// Do not unlink self.
|
||||
// @ts-ignore
|
||||
rootPackageJson = require(`../working-copy/${extension}/package.json`);
|
||||
// @ts-ignore
|
||||
rootPackageJson.dependencies['arduino-ide-extension'] =
|
||||
'file:../arduino-ide-extension';
|
||||
fs.writeFileSync(
|
||||
path('..', workingCopy, extension, 'package.json'),
|
||||
JSON.stringify(rootPackageJson, null, 2)
|
||||
);
|
||||
//-------------------------------------------------------------------------------------------------------------+
|
||||
// Change the regular NPM dependencies to `local-paths`, so that we can build them without any NPM registries. |
|
||||
//-------------------------------------------------------------------------------------------------------------+
|
||||
for (const extension of extensions) {
|
||||
if (extension !== 'arduino-ide-extension') {
|
||||
// Do not unlink self.
|
||||
// @ts-ignore
|
||||
rootPackageJson = require(`../working-copy/${extension}/package.json`);
|
||||
// @ts-ignore
|
||||
rootPackageJson.dependencies['arduino-ide-extension'] =
|
||||
'file:../arduino-ide-extension';
|
||||
fs.writeFileSync(
|
||||
path('..', workingCopy, extension, 'package.json'),
|
||||
JSON.stringify(rootPackageJson, null, 2)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------+
|
||||
// Merge the `working-copy/package.json` with `electron/build/template-package.json`. |
|
||||
//------------------------------------------------------------------------------------+
|
||||
// @ts-ignore
|
||||
const appPackageJson = require('../working-copy/electron-app/package.json');
|
||||
template.build.files = [
|
||||
...template.build.files,
|
||||
...unusedDependencies.map((name) => `!node_modules/${name}`),
|
||||
];
|
||||
|
||||
const dependencies = {};
|
||||
for (const extension of extensions) {
|
||||
dependencies[extension] = `file:../working-copy/${extension}`;
|
||||
}
|
||||
// @ts-ignore
|
||||
appPackageJson.dependencies = { ...appPackageJson.dependencies, ...dependencies };
|
||||
appPackageJson.devDependencies = { ...appPackageJson.devDependencies, ...template.devDependencies };
|
||||
// Deep-merging the Theia application configuration.
|
||||
// @ts-ignore
|
||||
const theia = merge(appPackageJson.theia || {}, template.theia || {});
|
||||
const content = {
|
||||
...appPackageJson,
|
||||
...template,
|
||||
theia,
|
||||
//------------------------------------------------------------------------------------+
|
||||
// Merge the `working-copy/package.json` with `electron/build/template-package.json`. |
|
||||
//------------------------------------------------------------------------------------+
|
||||
// @ts-ignore
|
||||
dependencies: appPackageJson.dependencies,
|
||||
devDependencies: appPackageJson.devDependencies,
|
||||
// VS Code extensions and the plugins folder is defined in the top level `package.json`. The template picks them up.
|
||||
theiaPluginsDir: rootPackageJson.theiaPluginsDir,
|
||||
theiaPlugins: rootPackageJson.theiaPlugins,
|
||||
};
|
||||
fs.writeFileSync(
|
||||
path('..', 'build', 'package.json'),
|
||||
JSON.stringify(
|
||||
merge(content, template, { arrayMerge: (_, sourceArray) => sourceArray }),
|
||||
null,
|
||||
2
|
||||
)
|
||||
);
|
||||
const appPackageJson = require('../working-copy/electron-app/package.json');
|
||||
const dependencies = {};
|
||||
for (const extension of extensions) {
|
||||
dependencies[extension] = `file:../working-copy/${extension}`;
|
||||
}
|
||||
// @ts-ignore
|
||||
appPackageJson.dependencies = {
|
||||
...appPackageJson.dependencies,
|
||||
...dependencies,
|
||||
};
|
||||
appPackageJson.devDependencies = {
|
||||
...appPackageJson.devDependencies,
|
||||
...template.devDependencies,
|
||||
};
|
||||
// Deep-merging the Theia application configuration.
|
||||
// @ts-ignore
|
||||
const theia = merge(appPackageJson.theia || {}, template.theia || {});
|
||||
const content = {
|
||||
...appPackageJson,
|
||||
...template,
|
||||
theia,
|
||||
// @ts-ignore
|
||||
dependencies: appPackageJson.dependencies,
|
||||
devDependencies: appPackageJson.devDependencies,
|
||||
// VS Code extensions and the plugins folder is defined in the top level `package.json`. The template picks them up.
|
||||
theiaPluginsDir: rootPackageJson.theiaPluginsDir,
|
||||
theiaPlugins: rootPackageJson.theiaPlugins,
|
||||
};
|
||||
fs.writeFileSync(
|
||||
path('..', 'build', 'package.json'),
|
||||
JSON.stringify(
|
||||
merge(content, template, {
|
||||
arrayMerge: (_, sourceArray) => sourceArray,
|
||||
}),
|
||||
null,
|
||||
2
|
||||
)
|
||||
);
|
||||
|
||||
echo(`📜 Effective 'package.json' for the ${productName} application is:
|
||||
echo(`📜 Effective 'package.json' for the ${productName} application is:
|
||||
-----------------------
|
||||
${fs.readFileSync(path('..', 'build', 'package.json')).toString()}
|
||||
-----------------------
|
||||
`);
|
||||
|
||||
// Make sure the original `yarn.lock` file is used from the electron application.
|
||||
if (fs.existsSync(path('..', 'build', 'yarn.lock'))) {
|
||||
echo(`${path('..', 'build', 'yarn.lock')} must not exist.`);
|
||||
shell.exit(1);
|
||||
}
|
||||
cp('-rf', path(rootPath, 'yarn.lock'), path('..', 'build'));
|
||||
if (!fs.existsSync(path('..', 'build', 'yarn.lock'))) {
|
||||
echo(`${path('..', 'build', 'yarn.lock')} does not exist.`);
|
||||
shell.exit(1);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------+
|
||||
// Install all private and public dependencies for the electron application and build Theia. |
|
||||
//-------------------------------------------------------------------------------------------+
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', 'build')}`,
|
||||
'Installing dependencies'
|
||||
);
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', 'build')} build`,
|
||||
`Building the ${productName} application`
|
||||
);
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', 'build')} rebuild`,
|
||||
'Rebuild native dependencies'
|
||||
);
|
||||
|
||||
//------------------------------------------------------------------------------+
|
||||
// Create a throw away dotenv file which we use to feed the builder with input. |
|
||||
//------------------------------------------------------------------------------+
|
||||
const dotenv = 'electron-builder.env';
|
||||
if (fs.existsSync(path('..', 'build', dotenv))) {
|
||||
rm('-rf', path('..', 'build', dotenv));
|
||||
}
|
||||
// For the releases we use the desired tag as is defined by `$(Release.Tag)` from Azure.
|
||||
// For the preview builds we use the version from the `electron/build/package.json` with the short commit hash.
|
||||
fs.writeFileSync(path('..', 'build', dotenv), `ARDUINO_VERSION=${version}`);
|
||||
|
||||
//-----------------------------------+
|
||||
// Package the electron application. |
|
||||
//-----------------------------------+
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', 'build')} package`,
|
||||
`Packaging your ${productName} application`
|
||||
);
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------+
|
||||
// Recalculate artifacts hash and copy to another folder (because they can change after signing them).
|
||||
// Azure does not support wildcard for `PublishBuildArtifacts@1.pathToPublish` |
|
||||
//-----------------------------------------------------------------------------------------------------+
|
||||
if (isCI) {
|
||||
try {
|
||||
await recalculateArtifactsHash();
|
||||
await copyFilesToBuildArtifacts();
|
||||
} catch (e) {
|
||||
echo(JSON.stringify(e));
|
||||
// Make sure the original `yarn.lock` file is used from the electron application.
|
||||
if (fs.existsSync(path('..', 'build', 'yarn.lock'))) {
|
||||
echo(`${path('..', 'build', 'yarn.lock')} must not exist.`);
|
||||
shell.exit(1);
|
||||
}
|
||||
cp('-rf', path(rootPath, 'yarn.lock'), path('..', 'build'));
|
||||
if (!fs.existsSync(path('..', 'build', 'yarn.lock'))) {
|
||||
echo(`${path('..', 'build', 'yarn.lock')} does not exist.`);
|
||||
shell.exit(1);
|
||||
}
|
||||
}
|
||||
echo(`🎉 Success. Your application is at: ${path('..', 'build', 'dist')}`);
|
||||
|
||||
restore();
|
||||
//-------------------------------------------------------------------------------------------+
|
||||
// Install all private and public dependencies for the electron application and build Theia. |
|
||||
//-------------------------------------------------------------------------------------------+
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', 'build')}`,
|
||||
'Installing dependencies'
|
||||
);
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', 'build')} build`,
|
||||
`Building the ${productName} application`
|
||||
);
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', 'build')} rebuild`,
|
||||
'Rebuild native dependencies'
|
||||
);
|
||||
|
||||
//------------------------------------------------------------------------------+
|
||||
// Create a throw away dotenv file which we use to feed the builder with input. |
|
||||
//------------------------------------------------------------------------------+
|
||||
const dotenv = 'electron-builder.env';
|
||||
if (fs.existsSync(path('..', 'build', dotenv))) {
|
||||
rm('-rf', path('..', 'build', dotenv));
|
||||
}
|
||||
// For the releases we use the desired tag as is defined by `$(Release.Tag)` from Azure.
|
||||
// For the preview builds we use the version from the `electron/build/package.json` with the short commit hash.
|
||||
fs.writeFileSync(path('..', 'build', dotenv), `ARDUINO_VERSION=${version}`);
|
||||
|
||||
//-----------------------------------+
|
||||
// Package the electron application. |
|
||||
//-----------------------------------+
|
||||
exec(
|
||||
`yarn --network-timeout 1000000 --cwd ${path('..', 'build')} package`,
|
||||
`Packaging your ${productName} application`
|
||||
);
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------+
|
||||
// Recalculate artifacts hash and copy to another folder (because they can change after signing them).
|
||||
// Azure does not support wildcard for `PublishBuildArtifacts@1.pathToPublish` |
|
||||
//-----------------------------------------------------------------------------------------------------+
|
||||
if (isCI) {
|
||||
try {
|
||||
await recalculateArtifactsHash();
|
||||
await copyFilesToBuildArtifacts();
|
||||
} catch (e) {
|
||||
echo(JSON.stringify(e));
|
||||
shell.exit(1);
|
||||
}
|
||||
}
|
||||
echo(`🎉 Success. Your application is at: ${path('..', 'build', 'dist')}`);
|
||||
} finally {
|
||||
restore();
|
||||
}
|
||||
|
||||
//--------+
|
||||
// Utils. |
|
||||
@ -514,7 +519,8 @@ ${fs.readFileSync(path('..', 'build', 'package.json')).toString()}
|
||||
if (expectedVersion) {
|
||||
if (!versions.has(expectedVersion)) {
|
||||
echo(
|
||||
`Mismatching version configuration. Expected version was: '${expectedVersion}' actual was: '${Array.from(versions)[0]
|
||||
`Mismatching version configuration. Expected version was: '${expectedVersion}' actual was: '${
|
||||
Array.from(versions)[0]
|
||||
}'.`
|
||||
);
|
||||
shell.exit(1);
|
||||
|
@ -20,7 +20,6 @@
|
||||
"crypto": "^1.0.1",
|
||||
"dateformat": "^3.0.3",
|
||||
"deepmerge": "2.01",
|
||||
"depcheck": "^0.9.2",
|
||||
"file-type": "^14.1.4",
|
||||
"glob": "^7.1.6",
|
||||
"is-ci": "^2.0.0",
|
||||
|
@ -5,51 +5,8 @@ const zip = require('7zip-min');
|
||||
const temp = require('temp');
|
||||
const path = require('path');
|
||||
const shell = require('shelljs');
|
||||
const depcheck = require('depcheck');
|
||||
const fromFile = require('file-type').fromFile;
|
||||
|
||||
/**
|
||||
* Resolves to an array of `npm` package names that are declared in the `package.json` but **not** used by the project.
|
||||
*/
|
||||
function collectUnusedDependencies(pathToProject = process.cwd()) {
|
||||
const p = path.isAbsolute(pathToProject)
|
||||
? pathToProject
|
||||
: path.resolve(process.cwd(), pathToProject);
|
||||
console.log(`⏱️ >>> Collecting unused backend dependencies for ${p}...`);
|
||||
return new Promise((resolve) => {
|
||||
depcheck(
|
||||
p,
|
||||
{
|
||||
ignoreDirs: ['frontend'],
|
||||
parsers: {
|
||||
'*.js': depcheck.parser.es6,
|
||||
'*.jsx': depcheck.parser.jsx,
|
||||
},
|
||||
detectors: [
|
||||
depcheck.detector.requireCallExpression,
|
||||
depcheck.detector.importDeclaration,
|
||||
],
|
||||
specials: [depcheck.special.eslint, depcheck.special.webpack],
|
||||
},
|
||||
(unused) => {
|
||||
const { dependencies } = unused;
|
||||
if (dependencies && dependencies.length > 0) {
|
||||
console.log(
|
||||
`👌 <<< The following unused dependencies have been found: ${JSON.stringify(
|
||||
dependencies,
|
||||
null,
|
||||
2
|
||||
)}`
|
||||
);
|
||||
} else {
|
||||
console.log('👌 <<< No unused dependencies have been found.');
|
||||
}
|
||||
resolve(dependencies);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* `pathToZip` is a `path/to/your/app-name.zip`.
|
||||
* If the `pathToZip` archive does not have a root directory with name `app-name`, it creates one, and move the content from the
|
||||
@ -127,7 +84,7 @@ function unpack(what, where) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve();
|
||||
resolve(undefined);
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -139,7 +96,7 @@ function pack(what, where) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve();
|
||||
resolve(undefined);
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -212,7 +169,6 @@ function getChannelFile(platform) {
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
collectUnusedDependencies,
|
||||
adjustArchiveStructure,
|
||||
isZip,
|
||||
unpack,
|
||||
|
@ -14,112 +14,6 @@
|
||||
dependencies:
|
||||
"7zip-bin" "^5.0.3"
|
||||
|
||||
"@babel/code-frame@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e"
|
||||
integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==
|
||||
dependencies:
|
||||
"@babel/highlight" "^7.8.3"
|
||||
|
||||
"@babel/generator@^7.9.0":
|
||||
version "7.9.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.9.3.tgz#7c8b2956c6f68b3ab732bd16305916fbba521d94"
|
||||
integrity sha512-RpxM252EYsz9qLUIq6F7YJyK1sv0wWDBFuztfDGWaQKzHjqDHysxSiRUpA/X9jmfqo+WzkAVKFaUily5h+gDCQ==
|
||||
dependencies:
|
||||
"@babel/types" "^7.9.0"
|
||||
jsesc "^2.5.1"
|
||||
lodash "^4.17.13"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/helper-function-name@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz#eeeb665a01b1f11068e9fb86ad56a1cb1a824cca"
|
||||
integrity sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==
|
||||
dependencies:
|
||||
"@babel/helper-get-function-arity" "^7.8.3"
|
||||
"@babel/template" "^7.8.3"
|
||||
"@babel/types" "^7.8.3"
|
||||
|
||||
"@babel/helper-get-function-arity@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz#b894b947bd004381ce63ea1db9f08547e920abd5"
|
||||
integrity sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==
|
||||
dependencies:
|
||||
"@babel/types" "^7.8.3"
|
||||
|
||||
"@babel/helper-split-export-declaration@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz#31a9f30070f91368a7182cf05f831781065fc7a9"
|
||||
integrity sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==
|
||||
dependencies:
|
||||
"@babel/types" "^7.8.3"
|
||||
|
||||
"@babel/helper-validator-identifier@^7.9.0":
|
||||
version "7.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz#ad53562a7fc29b3b9a91bbf7d10397fd146346ed"
|
||||
integrity sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==
|
||||
|
||||
"@babel/highlight@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.8.3.tgz#28f173d04223eaaa59bc1d439a3836e6d1265797"
|
||||
integrity sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==
|
||||
dependencies:
|
||||
chalk "^2.0.0"
|
||||
esutils "^2.0.2"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@babel/parser@^7.7.7", "@babel/parser@^7.9.0":
|
||||
version "7.9.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.9.3.tgz#043a5fc2ad8b7ea9facddc4e802a1f0f25da7255"
|
||||
integrity sha512-E6SpIDJZ0cZAKoCNk+qSDd0ChfTnpiJN9FfNf3RZ20dzwA2vL2oq5IX1XTVT+4vDmRlta2nGk5HGMMskJAR+4A==
|
||||
|
||||
"@babel/parser@^7.8.3":
|
||||
version "7.8.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.4.tgz#d1dbe64691d60358a974295fa53da074dd2ce8e8"
|
||||
integrity sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==
|
||||
|
||||
"@babel/template@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.3.tgz#e02ad04fe262a657809327f578056ca15fd4d1b8"
|
||||
integrity sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.8.3"
|
||||
"@babel/parser" "^7.8.3"
|
||||
"@babel/types" "^7.8.3"
|
||||
|
||||
"@babel/traverse@^7.7.4":
|
||||
version "7.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.9.0.tgz#d3882c2830e513f4fe4cec9fe76ea1cc78747892"
|
||||
integrity sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.8.3"
|
||||
"@babel/generator" "^7.9.0"
|
||||
"@babel/helper-function-name" "^7.8.3"
|
||||
"@babel/helper-split-export-declaration" "^7.8.3"
|
||||
"@babel/parser" "^7.9.0"
|
||||
"@babel/types" "^7.9.0"
|
||||
debug "^4.1.0"
|
||||
globals "^11.1.0"
|
||||
lodash "^4.17.13"
|
||||
|
||||
"@babel/types@^7.8.3":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.3.tgz#5a383dffa5416db1b73dedffd311ffd0788fb31c"
|
||||
integrity sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==
|
||||
dependencies:
|
||||
esutils "^2.0.2"
|
||||
lodash "^4.17.13"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@babel/types@^7.9.0":
|
||||
version "7.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.0.tgz#00b064c3df83ad32b2dbf5ff07312b15c7f1efb5"
|
||||
integrity sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.9.0"
|
||||
lodash "^4.17.13"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@sinonjs/commons@^1", "@sinonjs/commons@^1.6.0", "@sinonjs/commons@^1.7.0":
|
||||
version "1.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.7.1.tgz#da5fd19a5f71177a53778073978873964f49acf1"
|
||||
@ -161,11 +55,6 @@
|
||||
resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.1.1.tgz#f0d92c12f87079ddfd1b29f614758b9696bc29e3"
|
||||
integrity sha512-XO6INPbZCxdprl+9qa/AAbFFOMzzwqYxpjPgLICrMD6C2FCw6qfJOPcBk6JqqPLSaZ/Qx87qn4rpPmPMwaAK6w==
|
||||
|
||||
"@types/color-name@^1.1.1":
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
|
||||
integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
|
||||
|
||||
"@types/debug@^4.1.5":
|
||||
version "4.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd"
|
||||
@ -210,11 +99,6 @@ ansi-regex@^4.1.0:
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
|
||||
integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
|
||||
|
||||
ansi-regex@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
|
||||
integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
|
||||
|
||||
ansi-styles@^3.2.0, ansi-styles@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
|
||||
@ -222,14 +106,6 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1:
|
||||
dependencies:
|
||||
color-convert "^1.9.0"
|
||||
|
||||
ansi-styles@^4.0.0:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359"
|
||||
integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==
|
||||
dependencies:
|
||||
"@types/color-name" "^1.1.1"
|
||||
color-convert "^2.0.1"
|
||||
|
||||
anymatch@~3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142"
|
||||
@ -280,31 +156,7 @@ browser-stdout@1.3.1:
|
||||
resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60"
|
||||
integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==
|
||||
|
||||
builtin-modules@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.1.0.tgz#aad97c15131eb76b65b50ef208e7584cd76a7484"
|
||||
integrity sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==
|
||||
|
||||
caller-callsite@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134"
|
||||
integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=
|
||||
dependencies:
|
||||
callsites "^2.0.0"
|
||||
|
||||
caller-path@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4"
|
||||
integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=
|
||||
dependencies:
|
||||
caller-callsite "^2.0.0"
|
||||
|
||||
callsites@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50"
|
||||
integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=
|
||||
|
||||
camelcase@^5.0.0, camelcase@^5.3.1:
|
||||
camelcase@^5.0.0:
|
||||
version "5.3.1"
|
||||
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
|
||||
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
|
||||
@ -321,7 +173,7 @@ chai@^4.2.0:
|
||||
pathval "^1.1.0"
|
||||
type-detect "^4.0.5"
|
||||
|
||||
chalk@^2.0.0, chalk@^2.4.2:
|
||||
chalk@^2.4.2:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
||||
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
|
||||
@ -373,15 +225,6 @@ cliui@^5.0.0:
|
||||
strip-ansi "^5.2.0"
|
||||
wrap-ansi "^5.1.0"
|
||||
|
||||
cliui@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1"
|
||||
integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==
|
||||
dependencies:
|
||||
string-width "^4.2.0"
|
||||
strip-ansi "^6.0.0"
|
||||
wrap-ansi "^6.2.0"
|
||||
|
||||
code-point-at@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
|
||||
@ -394,38 +237,16 @@ color-convert@^1.9.0:
|
||||
dependencies:
|
||||
color-name "1.1.3"
|
||||
|
||||
color-convert@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
|
||||
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
|
||||
dependencies:
|
||||
color-name "~1.1.4"
|
||||
|
||||
color-name@1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
|
||||
integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
|
||||
|
||||
color-name@~1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||
|
||||
cosmiconfig@^5.2.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a"
|
||||
integrity sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==
|
||||
dependencies:
|
||||
import-fresh "^2.0.0"
|
||||
is-directory "^0.3.1"
|
||||
js-yaml "^3.13.1"
|
||||
parse-json "^4.0.0"
|
||||
|
||||
cross-spawn@^6.0.0:
|
||||
version "6.0.5"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
|
||||
@ -447,11 +268,6 @@ dateformat@^3.0.3:
|
||||
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
|
||||
integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==
|
||||
|
||||
de-indent@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d"
|
||||
integrity sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=
|
||||
|
||||
debug@3.2.6:
|
||||
version "3.2.6"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
|
||||
@ -459,7 +275,7 @@ debug@3.2.6:
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debug@^4.1.0, debug@^4.1.1:
|
||||
debug@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
|
||||
integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
|
||||
@ -490,34 +306,6 @@ define-properties@^1.1.2, define-properties@^1.1.3:
|
||||
dependencies:
|
||||
object-keys "^1.0.12"
|
||||
|
||||
depcheck@^0.9.2:
|
||||
version "0.9.2"
|
||||
resolved "https://registry.yarnpkg.com/depcheck/-/depcheck-0.9.2.tgz#9e3198b44a527836914c61ba5395479c62ecbaf4"
|
||||
integrity sha512-w5f+lSZqLJJkk58s44eOd0Vor7hLZot4PlFL0y2JsIX5LuHQ2eAjHlDVeGBD4Mj6ZQSKakvKWRRCcPlvrdU2Sg==
|
||||
dependencies:
|
||||
"@babel/parser" "^7.7.7"
|
||||
"@babel/traverse" "^7.7.4"
|
||||
builtin-modules "^3.0.0"
|
||||
camelcase "^5.3.1"
|
||||
cosmiconfig "^5.2.1"
|
||||
debug "^4.1.1"
|
||||
deps-regex "^0.1.4"
|
||||
js-yaml "^3.4.2"
|
||||
lodash "^4.17.15"
|
||||
minimatch "^3.0.2"
|
||||
node-sass-tilde-importer "^1.0.2"
|
||||
please-upgrade-node "^3.2.0"
|
||||
require-package-name "^2.0.1"
|
||||
resolve "^1.14.1"
|
||||
vue-template-compiler "^2.6.11"
|
||||
walkdir "^0.4.1"
|
||||
yargs "^15.0.2"
|
||||
|
||||
deps-regex@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/deps-regex/-/deps-regex-0.1.4.tgz#518667b7691460a5e7e0a341be76eb7ce8090184"
|
||||
integrity sha1-UYZnt2kUYKXn4KNBvnbrfOgJAYQ=
|
||||
|
||||
diff@3.5.0:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
|
||||
@ -533,11 +321,6 @@ emoji-regex@^7.0.1:
|
||||
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156"
|
||||
integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==
|
||||
|
||||
emoji-regex@^8.0.0:
|
||||
version "8.0.0"
|
||||
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
|
||||
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
|
||||
|
||||
end-of-stream@^1.1.0:
|
||||
version "1.4.4"
|
||||
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
|
||||
@ -545,13 +328,6 @@ end-of-stream@^1.1.0:
|
||||
dependencies:
|
||||
once "^1.4.0"
|
||||
|
||||
error-ex@^1.3.1:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
|
||||
integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==
|
||||
dependencies:
|
||||
is-arrayish "^0.2.1"
|
||||
|
||||
es-abstract@^1.17.0-next.1:
|
||||
version "1.17.5"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.5.tgz#d8c9d1d66c8981fb9200e2251d799eee92774ae9"
|
||||
@ -588,11 +364,6 @@ esprima@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
|
||||
integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
|
||||
|
||||
esutils@^2.0.2:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
|
||||
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
|
||||
|
||||
execa@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8"
|
||||
@ -623,11 +394,6 @@ fill-range@^7.0.1:
|
||||
dependencies:
|
||||
to-regex-range "^5.0.1"
|
||||
|
||||
find-parent-dir@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54"
|
||||
integrity sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ=
|
||||
|
||||
find-up@3.0.0, find-up@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73"
|
||||
@ -635,14 +401,6 @@ find-up@3.0.0, find-up@^3.0.0:
|
||||
dependencies:
|
||||
locate-path "^3.0.0"
|
||||
|
||||
find-up@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
|
||||
integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
|
||||
dependencies:
|
||||
locate-path "^5.0.0"
|
||||
path-exists "^4.0.0"
|
||||
|
||||
flat@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.0.tgz#090bec8b05e39cba309747f1d588f04dbaf98db2"
|
||||
@ -718,11 +476,6 @@ glob@^7.0.0, glob@^7.1.3, glob@^7.1.6:
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
globals@^11.1.0:
|
||||
version "11.12.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
|
||||
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
|
||||
|
||||
growl@1.10.5:
|
||||
version "1.10.5"
|
||||
resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e"
|
||||
@ -750,7 +503,7 @@ has@^1.0.3:
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
|
||||
he@1.2.0, he@^1.1.0:
|
||||
he@1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
||||
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
|
||||
@ -760,14 +513,6 @@ ieee754@^1.1.13:
|
||||
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84"
|
||||
integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==
|
||||
|
||||
import-fresh@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546"
|
||||
integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY=
|
||||
dependencies:
|
||||
caller-path "^2.0.0"
|
||||
resolve-from "^3.0.0"
|
||||
|
||||
inflight@^1.0.4:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||
@ -791,11 +536,6 @@ invert-kv@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02"
|
||||
integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==
|
||||
|
||||
is-arrayish@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
|
||||
integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
|
||||
|
||||
is-binary-path@~2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
|
||||
@ -825,11 +565,6 @@ is-date-object@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e"
|
||||
integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==
|
||||
|
||||
is-directory@^0.3.1:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1"
|
||||
integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=
|
||||
|
||||
is-extglob@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||
@ -847,11 +582,6 @@ is-fullwidth-code-point@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
|
||||
integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
|
||||
|
||||
is-fullwidth-code-point@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
|
||||
integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
|
||||
|
||||
is-glob@^4.0.1, is-glob@~4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc"
|
||||
@ -898,12 +628,7 @@ isexe@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
||||
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
|
||||
|
||||
js-tokens@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
|
||||
|
||||
js-yaml@3.13.1, js-yaml@^3.13.1, js-yaml@^3.4.2:
|
||||
js-yaml@3.13.1:
|
||||
version "3.13.1"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
|
||||
integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
|
||||
@ -911,16 +636,6 @@ js-yaml@3.13.1, js-yaml@^3.13.1, js-yaml@^3.4.2:
|
||||
argparse "^1.0.7"
|
||||
esprima "^4.0.0"
|
||||
|
||||
jsesc@^2.5.1:
|
||||
version "2.5.2"
|
||||
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
|
||||
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
|
||||
|
||||
json-parse-better-errors@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
|
||||
integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==
|
||||
|
||||
just-extend@^4.0.2:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.1.0.tgz#7278a4027d889601640ee0ce0e5a00b992467da4"
|
||||
@ -941,19 +656,12 @@ locate-path@^3.0.0:
|
||||
p-locate "^3.0.0"
|
||||
path-exists "^3.0.0"
|
||||
|
||||
locate-path@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
|
||||
integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==
|
||||
dependencies:
|
||||
p-locate "^4.1.0"
|
||||
|
||||
lodash.get@^4.4.2:
|
||||
version "4.4.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
|
||||
integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
|
||||
|
||||
lodash@^4.17.13, lodash@^4.17.15:
|
||||
lodash@^4.17.15:
|
||||
version "4.17.15"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
|
||||
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
|
||||
@ -986,7 +694,7 @@ mimic-fn@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
|
||||
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
|
||||
|
||||
minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4:
|
||||
minimatch@3.0.4, minimatch@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
|
||||
@ -1069,13 +777,6 @@ node-environment-flags@1.0.6:
|
||||
object.getownpropertydescriptors "^2.0.3"
|
||||
semver "^5.7.0"
|
||||
|
||||
node-sass-tilde-importer@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/node-sass-tilde-importer/-/node-sass-tilde-importer-1.0.2.tgz#1a15105c153f648323b4347693fdb0f331bad1ce"
|
||||
integrity sha512-Swcmr38Y7uB78itQeBm3mThjxBy9/Ah/ykPIaURY/L6Nec9AyRoL/jJ7ECfMR+oZeCTVQNxVMu/aHU+TLRVbdg==
|
||||
dependencies:
|
||||
find-parent-dir "^0.3.0"
|
||||
|
||||
normalize-path@^3.0.0, normalize-path@~3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
||||
@ -1152,7 +853,7 @@ p-is-promise@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e"
|
||||
integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==
|
||||
|
||||
p-limit@^2.0.0, p-limit@^2.2.0:
|
||||
p-limit@^2.0.0:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e"
|
||||
integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==
|
||||
@ -1166,36 +867,16 @@ p-locate@^3.0.0:
|
||||
dependencies:
|
||||
p-limit "^2.0.0"
|
||||
|
||||
p-locate@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07"
|
||||
integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==
|
||||
dependencies:
|
||||
p-limit "^2.2.0"
|
||||
|
||||
p-try@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
|
||||
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
|
||||
|
||||
parse-json@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0"
|
||||
integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=
|
||||
dependencies:
|
||||
error-ex "^1.3.1"
|
||||
json-parse-better-errors "^1.0.1"
|
||||
|
||||
path-exists@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
|
||||
integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=
|
||||
|
||||
path-exists@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
|
||||
integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
|
||||
|
||||
path-is-absolute@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||
@ -1233,13 +914,6 @@ picomatch@^2.0.4:
|
||||
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad"
|
||||
integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==
|
||||
|
||||
please-upgrade-node@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz#aeddd3f994c933e4ad98b99d9a556efa0e2fe942"
|
||||
integrity sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==
|
||||
dependencies:
|
||||
semver-compare "^1.0.0"
|
||||
|
||||
pump@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
|
||||
@ -1282,17 +956,7 @@ require-main-filename@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
|
||||
integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
|
||||
|
||||
require-package-name@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/require-package-name/-/require-package-name-2.0.1.tgz#c11e97276b65b8e2923f75dabf5fb2ef0c3841b9"
|
||||
integrity sha1-wR6XJ2tluOKSP3Xav1+y7ww4Qbk=
|
||||
|
||||
resolve-from@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748"
|
||||
integrity sha1-six699nWiBvItuZTM17rywoYh0g=
|
||||
|
||||
resolve@^1.1.6, resolve@^1.14.1:
|
||||
resolve@^1.1.6:
|
||||
version "1.15.1"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8"
|
||||
integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==
|
||||
@ -1306,11 +970,6 @@ rimraf@~2.6.2:
|
||||
dependencies:
|
||||
glob "^7.1.3"
|
||||
|
||||
semver-compare@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
|
||||
integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w=
|
||||
|
||||
semver@^5.5.0, semver@^5.7.0:
|
||||
version "5.7.1"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
||||
@ -1365,11 +1024,6 @@ sinon@^9.0.1:
|
||||
nise "^4.0.1"
|
||||
supports-color "^7.1.0"
|
||||
|
||||
source-map@^0.5.0:
|
||||
version "0.5.7"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
||||
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
|
||||
|
||||
sprintf-js@~1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||
@ -1401,15 +1055,6 @@ string-width@^3.0.0, string-width@^3.1.0:
|
||||
is-fullwidth-code-point "^2.0.0"
|
||||
strip-ansi "^5.1.0"
|
||||
|
||||
string-width@^4.1.0, string-width@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5"
|
||||
integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==
|
||||
dependencies:
|
||||
emoji-regex "^8.0.0"
|
||||
is-fullwidth-code-point "^3.0.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
string.prototype.trimleft@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74"
|
||||
@ -1447,13 +1092,6 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0:
|
||||
dependencies:
|
||||
ansi-regex "^4.1.0"
|
||||
|
||||
strip-ansi@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532"
|
||||
integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==
|
||||
dependencies:
|
||||
ansi-regex "^5.0.0"
|
||||
|
||||
strip-eof@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf"
|
||||
@ -1502,11 +1140,6 @@ temp@^0.9.1:
|
||||
dependencies:
|
||||
rimraf "~2.6.2"
|
||||
|
||||
to-fast-properties@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
|
||||
integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
|
||||
|
||||
to-regex-range@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
|
||||
@ -1534,19 +1167,6 @@ typedarray-to-buffer@^3.1.5:
|
||||
dependencies:
|
||||
is-typedarray "^1.0.0"
|
||||
|
||||
vue-template-compiler@^2.6.11:
|
||||
version "2.6.11"
|
||||
resolved "https://registry.yarnpkg.com/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz#c04704ef8f498b153130018993e56309d4698080"
|
||||
integrity sha512-KIq15bvQDrcCjpGjrAhx4mUlyyHfdmTaoNfeoATHLAiWB+MU3cx4lOzMwrnUh9cCxy0Lt1T11hAFY6TQgroUAA==
|
||||
dependencies:
|
||||
de-indent "^1.0.2"
|
||||
he "^1.1.0"
|
||||
|
||||
walkdir@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/walkdir/-/walkdir-0.4.1.tgz#dc119f83f4421df52e3061e514228a2db20afa39"
|
||||
integrity sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==
|
||||
|
||||
which-module@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
|
||||
@ -1583,15 +1203,6 @@ wrap-ansi@^5.1.0:
|
||||
string-width "^3.0.0"
|
||||
strip-ansi "^5.0.0"
|
||||
|
||||
wrap-ansi@^6.2.0:
|
||||
version "6.2.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53"
|
||||
integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==
|
||||
dependencies:
|
||||
ansi-styles "^4.0.0"
|
||||
string-width "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
@ -1623,14 +1234,6 @@ yargs-parser@^11.1.1:
|
||||
camelcase "^5.0.0"
|
||||
decamelize "^1.2.0"
|
||||
|
||||
yargs-parser@^18.1.1:
|
||||
version "18.1.1"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.1.tgz#bf7407b915427fc760fcbbccc6c82b4f0ffcbd37"
|
||||
integrity sha512-KRHEsOM16IX7XuLnMOqImcPNbLVXMNHYAoFc3BKR8Ortl5gzDbtXvvEoGx9imk5E+X1VeNKNlcHr8B8vi+7ipA==
|
||||
dependencies:
|
||||
camelcase "^5.0.0"
|
||||
decamelize "^1.2.0"
|
||||
|
||||
yargs-unparser@1.6.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.6.0.tgz#ef25c2c769ff6bd09e4b0f9d7c605fb27846ea9f"
|
||||
@ -1673,20 +1276,3 @@ yargs@^12.0.5:
|
||||
which-module "^2.0.0"
|
||||
y18n "^3.2.1 || ^4.0.0"
|
||||
yargs-parser "^11.1.1"
|
||||
|
||||
yargs@^15.0.2:
|
||||
version "15.3.1"
|
||||
resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.3.1.tgz#9505b472763963e54afe60148ad27a330818e98b"
|
||||
integrity sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==
|
||||
dependencies:
|
||||
cliui "^6.0.0"
|
||||
decamelize "^1.2.0"
|
||||
find-up "^4.1.0"
|
||||
get-caller-file "^2.0.1"
|
||||
require-directory "^2.1.1"
|
||||
require-main-filename "^2.0.0"
|
||||
set-blocking "^2.0.0"
|
||||
string-width "^4.2.0"
|
||||
which-module "^2.0.0"
|
||||
y18n "^4.0.0"
|
||||
yargs-parser "^18.1.1"
|
||||
|
@ -450,11 +450,6 @@
|
||||
"offline": "Offline",
|
||||
"quitTitle": "Are you sure you want to quit?"
|
||||
},
|
||||
"debug": {
|
||||
"start": "Start...",
|
||||
"startError": "There was an error starting the debug session, check the logs for more details.",
|
||||
"typeNotSupported": "The debug session type \"{0}\" is not supported."
|
||||
},
|
||||
"editor": {
|
||||
"unsavedTitle": "Unsaved – {0}"
|
||||
},
|
||||
|
11
package.json
11
package.json
@ -10,9 +10,9 @@
|
||||
"node": ">=16.0.0 <17"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@theia/cli": "1.25.0",
|
||||
"@types/sinon": "^2.3.5",
|
||||
"@theia/cli": "1.31.1",
|
||||
"@types/jsdom": "^11.0.4",
|
||||
"@types/sinon": "^2.3.5",
|
||||
"@typescript-eslint/eslint-plugin": "^4.27.0",
|
||||
"@typescript-eslint/parser": "^4.27.0",
|
||||
"cross-env": "^7.0.2",
|
||||
@ -24,6 +24,7 @@
|
||||
"eslint-plugin-unused-imports": "^1.1.1",
|
||||
"husky": "^6.0.0",
|
||||
"ignore-styles": "^5.0.1",
|
||||
"jsdom": "^11.5.1",
|
||||
"lerna": "^3.20.2",
|
||||
"lint-staged": "^11.0.0",
|
||||
"node-gyp": "^9.3.0",
|
||||
@ -31,13 +32,13 @@
|
||||
"reflect-metadata": "^0.1.10",
|
||||
"rimraf": "^2.6.1",
|
||||
"semver": "^7.3.2",
|
||||
"typescript": "~4.5.5",
|
||||
"jsdom": "^11.5.1",
|
||||
"style-dictionary": "^3.7.0",
|
||||
"typescript": "~4.5.5",
|
||||
"xhr2": "^0.2.1"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/react": "16.14.25",
|
||||
"@types/react": "18.0.0",
|
||||
"@types/react-dom": "18.0.0",
|
||||
"electron-rebuild": "3.2.9"
|
||||
},
|
||||
"scripts": {
|
||||
|
26
scripts/sort-dependencies
Executable file
26
scripts/sort-dependencies
Executable file
@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
// Sorts the dependencies and devDependencies in the package.json without yarn.
|
||||
// Usage `./scripts/sort-dependencies ./path/to/package.json`
|
||||
|
||||
const { promises: fs } = require('fs');
|
||||
const { join, isAbsolute } = require('path');
|
||||
const arg = process.argv.slice(2).pop();
|
||||
const path = isAbsolute(arg) ? arg : join(process.cwd(), arg);
|
||||
fs.readFile(path, { encoding: 'utf8' }).then((raw) => {
|
||||
const json = JSON.parse(raw);
|
||||
['dependencies', 'devDependencies'].forEach((prop) => {
|
||||
const value = json[prop];
|
||||
if (value) {
|
||||
json[prop] = Array.from(Object.entries(value))
|
||||
.sort(([left], [right]) => left.localeCompare(right))
|
||||
.reduce((acc, [key, value]) => {
|
||||
acc[key] = value;
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
});
|
||||
fs.writeFile(path, JSON.stringify(json, null, 2) + '\n', {
|
||||
encoding: 'utf8',
|
||||
});
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user