Merge pull request #3628 from balena-io/device-info-draft

Device info draft
This commit is contained in:
bulldozer-balena[bot] 2021-11-09 16:07:20 +00:00 committed by GitHub
commit d22fc91585
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 4863 additions and 4381 deletions

View File

@ -7,7 +7,6 @@ indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

View File

@ -24,7 +24,6 @@
"generated",
"lib/shared/catalina-sudo/sudo-askpass.osascript.js"
],
"beforeBuild": "./beforeBuild.js",
"afterSign": "./afterSignHook.js",
"mac": {
"category": "public.app-category.developer-tools",

View File

@ -90,11 +90,8 @@ TARGET_ARCH ?= $(HOST_ARCH)
# ---------------------------------------------------------------------
electron-develop:
git submodule update --init && \
$(RESIN_SCRIPTS)/electron/install.sh \
-b $(shell pwd) \
-r $(TARGET_ARCH) \
-s $(PLATFORM) \
-m $(NPM_VERSION)
npm ci && \
npm run webpack
electron-test:
$(RESIN_SCRIPTS)/electron/test.sh \

View File

@ -1,33 +0,0 @@
'use strict'
const cp = require('child_process');
const rimraf = require('rimraf');
const process = require('process');
// Rebuild native modules for ia32 and run webpack again for the ia32 part of windows packages
exports.default = function(context) {
if (['windows', 'mac'].includes(context.platform.name)) {
const run = context.platform.name === 'windows' ? 'sh' : 'node';
cp.execFileSync(
run,
['node_modules/.bin/electron-rebuild', '--types', 'dev', '--arch', context.arch],
{
env: {
...process.env,
npm_config_msvs_version: '2019',
},
},
);
rimraf.sync('generated');
cp.execFileSync(
run,
['node_modules/.bin/webpack'],
{
env: {
...process.env,
npm_config_target_arch: context.arch,
},
},
);
}
}

View File

@ -4,7 +4,6 @@ productName: balenaEtcher
npmRebuild: true
nodeGypRebuild: false
publish: null
beforeBuild: "./beforeBuild.js"
afterPack: "./afterPack.js"
asar: false
files:

View File

@ -217,8 +217,7 @@ function prepareDrive(drive: Drive) {
disabled: true,
icon: 'warning',
size: null,
link:
'https://www.raspberrypi.org/documentation/hardware/computemodule/cm-emmc-flashing.md',
link: 'https://www.raspberrypi.org/documentation/hardware/computemodule/cm-emmc-flashing.md',
linkCTA: 'Install',
linkTitle: 'Install missing drivers',
linkMessage: outdent`
@ -335,7 +334,7 @@ window.addEventListener('beforeunload', async (event) => {
flashingWorkflowUuid,
});
popupExists = false;
} catch (error) {
} catch (error: any) {
exceptionReporter.report(error);
}
});

View File

@ -379,8 +379,8 @@ export class DriveSelector extends React.Component<
const displayedDrives = this.getDisplayedDrives(drives);
const disabledDrives = this.getDisabledDrives(drives, image);
const numberOfSystemDrives = drives.filter(isSystemDrive).length;
const numberOfDisplayedSystemDrives = displayedDrives.filter(isSystemDrive)
.length;
const numberOfDisplayedSystemDrives =
displayedDrives.filter(isSystemDrive).length;
const numberOfHiddenSystemDrives =
numberOfSystemDrives - numberOfDisplayedSystemDrives;
const hasSystemDrives = selectedList.filter(isSystemDrive).length;
@ -534,7 +534,7 @@ export class DriveSelector extends React.Component<
if (missingDriversModal.drive !== undefined) {
openExternal(missingDriversModal.drive.link);
}
} catch (error) {
} catch (error: any) {
logException(error);
} finally {
this.setState({ missingDriversModal: {} });

View File

@ -59,13 +59,8 @@ function FinishPage({ goToMain }: { goToMain: () => void }) {
).map(([, error]: [string, FlashError]) => ({
...error,
}));
const {
averageSpeed,
blockmappedSize,
bytesWritten,
failed,
size,
} = flashState.getFlashState();
const { averageSpeed, blockmappedSize, bytesWritten, failed, size } =
flashState.getFlashState();
const {
skip,
results = {

View File

@ -17,7 +17,7 @@
import GithubSvg from '@fortawesome/fontawesome-free/svgs/brands/github.svg';
import * as _ from 'lodash';
import * as React from 'react';
import { Flex, Checkbox, Txt } from 'rendition';
import { Box, Checkbox, Flex, TextWithCopy, Txt } from 'rendition';
import { version, packageType } from '../../../../../package.json';
import * as settings from '../../models/settings';
@ -50,6 +50,14 @@ interface SettingsModalProps {
toggleModal: (value: boolean) => void;
}
const UUID = process.env.BALENA_DEVICE_UUID;
const InfoBox = (props: any) => (
<Box fontSize={14}>
<Txt>{props.label}</Txt>
<TextWithCopy code text={props.value} copy={props.value} />
</Box>
);
export function SettingsModal({ toggleModal }: SettingsModalProps) {
const [settingsList, setCurrentSettingsList] = React.useState<Setting[]>([]);
React.useEffect(() => {
@ -103,6 +111,12 @@ export function SettingsModal({ toggleModal }: SettingsModalProps) {
</Flex>
);
})}
{UUID !== undefined && (
<Flex flexDirection="column">
<Txt fontSize={24}>System Information</Txt>
<InfoBox label="UUID" value={UUID.substr(0, 7)} />
</Flex>
)}
<Flex
mt={18}
alignItems="center"

View File

@ -65,6 +65,7 @@ import SrcSvg from '../../../assets/src.svg';
import { DriveSelector } from '../drive-selector/drive-selector';
import { DrivelistDrive } from '../../../../shared/drive-constraints';
import axios, { AxiosRequestConfig } from 'axios';
import { isJson } from '../../../../shared/utils';
const recentUrlImagesKey = 'recentUrlImages';
@ -76,7 +77,7 @@ function normalizeRecentUrlImages(urls: any[]): URL[] {
.map((url) => {
try {
return new URL(url);
} catch (error) {
} catch (error: any) {
// Invalid URL, skip
}
})
@ -378,7 +379,9 @@ export class SourceSelector extends React.Component<
this.setState({ imageLoading: true });
await this.selectSource(
imagePath,
isURL(imagePath) ? sourceDestination.Http : sourceDestination.File,
isURL(this.normalizeImagePath(imagePath))
? sourceDestination.Http
: sourceDestination.File,
).promise;
this.setState({ imageLoading: false });
}
@ -390,11 +393,11 @@ export class SourceSelector extends React.Component<
) {
try {
selected = await replaceWindowsNetworkDriveLetter(selected);
} catch (error) {
} catch (error: any) {
analytics.logException(error);
}
if (this.isJson(decodeURIComponent(selected))) {
if (isJson(decodeURIComponent(selected))) {
const config: AxiosRequestConfig = JSON.parse(
decodeURIComponent(selected),
);
@ -413,13 +416,12 @@ export class SourceSelector extends React.Component<
return new sourceDestination.Http({ url: selected, auth });
}
public isJson(jsonString: string) {
try {
JSON.parse(jsonString);
} catch (e) {
return false;
public normalizeImagePath(imgPath: string) {
const decodedPath = decodeURIComponent(imgPath);
if (isJson(decodedPath)) {
return JSON.parse(decodedPath).url ?? decodedPath;
}
return true;
return decodedPath;
}
private reselectSource() {
@ -445,7 +447,10 @@ export class SourceSelector extends React.Component<
let source;
let metadata: SourceMetadata | undefined;
if (isString(selected)) {
if (SourceType === sourceDestination.Http && !isURL(selected)) {
if (
SourceType === sourceDestination.Http &&
!isURL(this.normalizeImagePath(selected))
) {
this.handleError(
'Unsupported protocol',
selected,
@ -489,7 +494,7 @@ export class SourceSelector extends React.Component<
},
});
}
} catch (error) {
} catch (error: any) {
this.handleError(
'Error opening source',
sourcePath,
@ -499,7 +504,7 @@ export class SourceSelector extends React.Component<
} finally {
try {
await source.close();
} catch (error) {
} catch (error: any) {
// Noop
}
}
@ -589,7 +594,7 @@ export class SourceSelector extends React.Component<
return;
}
await this.selectSource(imagePath, sourceDestination.File).promise;
} catch (error) {
} catch (error: any) {
exceptionReporter.report(error);
} finally {
this.setState({ imageSelectorOpen: false });

View File

@ -14,7 +14,6 @@
* limitations under the License.
*/
import { scanner } from 'etcher-sdk';
import * as React from 'react';
import { Flex, Txt } from 'rendition';
@ -37,6 +36,7 @@ import { TargetSelectorButton } from './target-selector-button';
import TgtSvg from '../../../assets/tgt.svg';
import DriveSvg from '../../../assets/drive.svg';
import { warning } from '../../../../shared/messages';
import { DrivelistDrive } from '../../../../shared/drive-constraints';
export const getDriveListLabel = () => {
return getSelectedDrives()
@ -70,9 +70,7 @@ export const TargetSelectorModal = (
/>
);
export const selectAllTargets = (
modalTargets: scanner.adapters.DrivelistDrive[],
) => {
export const selectAllTargets = (modalTargets: DrivelistDrive[]) => {
const selectedDrivesFromState = getSelectedDrives();
const deselected = selectedDrivesFromState.filter(
(drive) =>
@ -114,9 +112,8 @@ export const TargetSelector = ({
const [{ driveListLabel, targets }, setStateSlice] = React.useState(
getDriveSelectionStateSlice(),
);
const [showTargetSelectorModal, setShowTargetSelectorModal] = React.useState(
false,
);
const [showTargetSelectorModal, setShowTargetSelectorModal] =
React.useState(false);
React.useEffect(() => {
return observe(() => {

View File

@ -17,6 +17,7 @@
import * as electron from 'electron';
import * as sdk from 'etcher-sdk';
import * as _ from 'lodash';
import { DrivelistDrive } from '../../../shared/drive-constraints';
import { bytesToMegabytes } from '../../../shared/units';
import { Actions, store } from './store';
@ -84,7 +85,7 @@ export function addFailedDeviceError({
device,
error,
}: {
device: sdk.scanner.adapters.DrivelistDrive;
device: DrivelistDrive;
error: Error;
}) {
const failedDeviceErrorsMap = new Map(

View File

@ -245,16 +245,16 @@ export async function init(): Promise<void> {
for (const [drivePath, ledsNames] of Object.entries(ledsMapping)) {
leds.set('/dev/disk/by-path/' + drivePath, new RGBLed(ledsNames));
}
ledColors = (await settings.get('ledColors')) || {};
ledAnimationFunctions = {
blinkGreen: createAnimationFunction(blink, ledColors['green']),
blinkPurple: createAnimationFunction(blink, ledColors['purple']),
staticRed: createAnimationFunction(one, ledColors['red']),
staticGreen: createAnimationFunction(one, ledColors['green']),
staticBlue: createAnimationFunction(one, ledColors['blue']),
staticWhite: createAnimationFunction(one, ledColors['white']),
staticBlack: createAnimationFunction(one, ledColors['black']),
};
observe(_.debounce(stateObserver, 1000, { maxWait: 1000 }));
}
ledColors = (await settings.get('ledColors')) || {};
ledAnimationFunctions = {
blinkGreen: createAnimationFunction(blink, ledColors['green']),
blinkPurple: createAnimationFunction(blink, ledColors['purple']),
staticRed: createAnimationFunction(one, ledColors['red']),
staticGreen: createAnimationFunction(one, ledColors['green']),
staticBlue: createAnimationFunction(one, ledColors['blue']),
staticWhite: createAnimationFunction(one, ledColors['white']),
staticBlack: createAnimationFunction(one, ledColors['black']),
};
observe(_.debounce(stateObserver, 1000, { maxWait: 1000 }));
}

View File

@ -51,7 +51,7 @@ async function readConfigFile(filename: string): Promise<_.Dictionary<any>> {
let contents = '{}';
try {
contents = await fs.readFile(filename, { encoding: 'utf8' });
} catch (error) {
} catch (error: any) {
// noop
}
try {
@ -104,7 +104,7 @@ export async function set(
settings[key] = value;
try {
await writeConfigFileFn(CONFIG_PATH, settings);
} catch (error) {
} catch (error: any) {
// Revert to previous value if persisting settings failed
settings[key] = previousValue;
throw error;

View File

@ -102,10 +102,9 @@ function validateMixpanelConfig(config: {
* This function sends the debug message to product analytics services.
*/
export function logEvent(message: string, data: _.Dictionary<any> = {}) {
const {
applicationSessionUuid,
flashingWorkflowUuid,
} = store.getState().toJS();
const { applicationSessionUuid, flashingWorkflowUuid } = store
.getState()
.toJS();
resinCorvus.logEvent(message, {
...data,
sample: mixpanelSample,

View File

@ -15,10 +15,15 @@
*/
import * as sdk from 'etcher-sdk';
import {
Adapter,
BlockDeviceAdapter,
UsbbootDeviceAdapter,
} from 'etcher-sdk/build/scanner/adapters';
import { geteuid, platform } from 'process';
const adapters: sdk.scanner.adapters.Adapter[] = [
new sdk.scanner.adapters.BlockDeviceAdapter({
const adapters: Adapter[] = [
new BlockDeviceAdapter({
includeSystemDrives: () => true,
}),
];
@ -26,14 +31,15 @@ const adapters: sdk.scanner.adapters.Adapter[] = [
// Can't use permissions.isElevated() here as it returns a promise and we need to set
// module.exports = scanner right now.
if (platform !== 'linux' || geteuid() === 0) {
adapters.push(new sdk.scanner.adapters.UsbbootDeviceAdapter());
adapters.push(new UsbbootDeviceAdapter());
}
if (
platform === 'win32' &&
sdk.scanner.adapters.DriverlessDeviceAdapter !== undefined
) {
adapters.push(new sdk.scanner.adapters.DriverlessDeviceAdapter());
if (platform === 'win32') {
const {
DriverlessDeviceAdapter: driverless,
// tslint:disable-next-line:no-var-requires
} = require('etcher-sdk/build/scanner/adapters/driverless');
adapters.push(new driverless());
}
export const scanner = new sdk.scanner.Scanner(adapters);

View File

@ -218,7 +218,7 @@ async function performWrite(
});
flashResults.cancelled = cancelled || results.cancelled;
flashResults.skip = skip;
} catch (error) {
} catch (error: any) {
// This happens when the child is killed using SIGKILL
const SIGKILL_EXIT_CODE = 137;
if (error.code === SIGKILL_EXIT_CODE) {
@ -287,7 +287,7 @@ export async function flash(
try {
const result = await write(image, drives, flashState.setProgressState);
await flashState.unsetFlashingFlag(result);
} catch (error) {
} catch (error: any) {
await flashState.unsetFlashingFlag({
cancelled: false,
errorCode: error.code,
@ -349,7 +349,7 @@ export async function cancel(type: string) {
if (socket !== undefined) {
ipc.server.emit(socket, status);
}
} catch (error) {
} catch (error: any) {
analytics.logException(error);
}
}

View File

@ -27,7 +27,7 @@ async function mountSourceDrive() {
if (sourceDrivePath) {
try {
await electron.ipcRenderer.invoke('mount-drive', sourceDrivePath);
} catch (error) {
} catch (error: any) {
// noop
}
}

View File

@ -117,7 +117,7 @@ async function flashImageToDrive(
}
goToSuccess();
}
} catch (error) {
} catch (error: any) {
notifyFailure(iconPath, basename, drives);
let errorMessage = getErrorMessageFromCode(error.code);
if (!errorMessage) {

View File

@ -35,8 +35,10 @@ import { totalmem } from 'os';
import { toJSON } from '../../shared/errors';
import { GENERAL_ERROR, SUCCESS } from '../../shared/exit-codes';
import { delay } from '../../shared/utils';
import { delay, isJson } from '../../shared/utils';
import { SourceMetadata } from '../app/components/source-selector/source-selector';
import axios from 'axios';
import * as _ from 'lodash';
ipc.config.id = process.env.IPC_CLIENT_ID as string;
ipc.config.socketRoot = process.env.IPC_SOCKET_ROOT as string;
@ -171,6 +173,7 @@ interface WriteOptions {
autoBlockmapping: boolean;
decompressFirst: boolean;
SourceType: string;
httpRequest?: any;
}
ipc.connectTo(IPC_SERVER_ID, () => {
@ -281,7 +284,17 @@ ipc.connectTo(IPC_SERVER_ID, () => {
path: imagePath,
});
} else {
source = new Http({ url: imagePath, avoidRandomAccess: true });
const decodedImagePath = decodeURIComponent(imagePath);
if (isJson(decodedImagePath)) {
const imagePathObject = JSON.parse(decodedImagePath);
source = new Http({
url: imagePathObject.url,
avoidRandomAccess: true,
axiosInstance: axios.create(_.omit(imagePathObject, ['url'])),
});
} else {
source = new Http({ url: imagePath, avoidRandomAccess: true });
}
}
}
const results = await writeAndValidate({
@ -300,7 +313,7 @@ ipc.connectTo(IPC_SERVER_ID, () => {
ipc.of[IPC_SERVER_ID].emit('done', { results });
await delay(DISCONNECT_DELAY);
await terminate(exitCode);
} catch (error) {
} catch (error: any) {
exitCode = GENERAL_ERROR;
ipc.of[IPC_SERVER_ID].emit('error', toJSON(error));
}

View File

@ -50,7 +50,7 @@ export async function sudo(
stdout: stdout.slice(EXPECTED_SUCCESSFUL_AUTH_MARKER.length),
stderr,
};
} catch (error) {
} catch (error: any) {
if (error.code === 1) {
if (!error.stdout.startsWith(EXPECTED_SUCCESSFUL_AUTH_MARKER)) {
return { cancelled: true };

View File

@ -60,7 +60,7 @@ export async function isElevated(): Promise<boolean> {
// See http://stackoverflow.com/a/28268802
try {
await execAsync('fltmc');
} catch (error) {
} catch (error: any) {
if (error.code === os.constants.errno.EPERM) {
return false;
}
@ -146,7 +146,7 @@ async function elevateScriptCatalina(
try {
const { cancelled } = await catalinaSudo(cmd);
return { cancelled };
} catch (error) {
} catch (error: any) {
throw errors.createError({ title: error.stderr });
}
}
@ -190,7 +190,7 @@ export async function elevateCommand(
}
try {
return await elevateScriptUnix(path, options.applicationName);
} catch (error) {
} catch (error: any) {
// We're hardcoding internal error messages declared by `sudo-prompt`.
// There doesn't seem to be a better way to handle these errors, so
// for now, we should make sure we double check if the error messages

View File

@ -61,3 +61,12 @@ export function getAppPath(): string {
)
);
}
export function isJson(jsonString: string) {
try {
JSON.parse(jsonString);
} catch (e) {
return false;
}
return true;
}

File diff suppressed because it is too large Load Diff

View File

@ -22,7 +22,7 @@
"test": "npm run lint && npm run test-gui && npm run test-shared && npm run test-spectron && npm run sanity-checks",
"sanity-checks": "bash scripts/ci/ensure-all-file-extensions-in-gitattributes.sh",
"start": "./node_modules/.bin/electron .",
"postshrinkwrap": "ts-node ./scripts/clean-shrinkwrap.ts",
"postinstall": "electron-builder install-app-deps",
"webpack": "webpack",
"watch": "webpack serve --no-optimization-minimize --config ./webpack.dev.config.ts",
"concourse-build-electron": "npm run webpack",
@ -44,85 +44,75 @@
},
"author": "Balena Inc. <hello@etcher.io>",
"license": "Apache-2.0",
"platformSpecificDependencies": [
"xmlbuilder",
"xmldom",
"@types/plist",
"@types/verror",
"crc",
"iconv-corefoundation",
"plist",
"dmg-license",
"fsevents",
"winusb-driver-generator"
],
"devDependencies": {
"@balena/lint": "^5.3.0",
"@fortawesome/fontawesome-free": "^5.13.1",
"@svgr/webpack": "^5.5.0",
"@types/chai": "^4.2.7",
"@types/copy-webpack-plugin": "^6.0.0",
"@types/mime-types": "^2.1.0",
"@types/mini-css-extract-plugin": "^1.2.2",
"@types/mocha": "^8.0.3",
"@types/node": "^14.14.41",
"@types/node-ipc": "^9.1.2",
"@types/react-dom": "^16.8.4",
"@types/semver": "^7.1.0",
"@types/sinon": "^9.0.0",
"@types/terser-webpack-plugin": "^5.0.2",
"@types/tmp": "^0.2.0",
"@types/webpack-node-externals": "^2.5.0",
"dependencies": {
"@fortawesome/fontawesome-free": "5.13.1",
"aws4-axios": "2.2.1",
"chai": "^4.2.0",
"copy-webpack-plugin": "^7.0.0",
"css-loader": "^5.0.1",
"d3": "^4.13.0",
"debug": "^4.2.0",
"electron": "12.0.2",
"electron-builder": "^22.10.5",
"electron-mocha": "^9.3.2",
"electron-notarize": "^1.0.0",
"electron-rebuild": "^2.3.2",
"electron-updater": "^4.3.5",
"etcher-sdk": "^6.2.5",
"file-loader": "^6.2.0",
"husky": "^4.2.5",
"immutable": "^3.8.1",
"lint-staged": "^10.2.2",
"lodash": "^4.17.10",
"mini-css-extract-plugin": "^1.3.3",
"mocha": "^8.0.1",
"native-addon-loader": "^2.0.1",
"node-ipc": "^9.1.1",
"d3": "4.13.0",
"debug": "4.2.0",
"etcher-sdk": "6.3.0",
"immutable": "3.8.1",
"lodash": "4.17.10",
"node-ipc": "9.1.1",
"omit-deep-lodash": "1.1.4",
"outdent": "^0.7.1",
"path-is-inside": "^1.0.2",
"pnp-webpack-plugin": "^1.6.4",
"pretty-bytes": "^5.3.0",
"react": "^16.8.5",
"react-dom": "^16.8.5",
"redux": "^4.0.5",
"rendition": "^19.2.0",
"resin-corvus": "^2.0.5",
"semver": "^7.3.2",
"simple-progress-webpack-plugin": "^1.1.2",
"sinon": "^9.0.2",
"spectron": "^14.0.0",
"string-replace-loader": "^3.0.1",
"style-loader": "^2.0.0",
"styled-components": "^5.1.0",
"outdent": "0.7.1",
"path-is-inside": "1.0.2",
"pretty-bytes": "5.3.0",
"react": "16.8.5",
"react-dom": "16.8.5",
"redux": "4.0.5",
"rendition": "19.2.0",
"resin-corvus": "2.0.5",
"semver": "7.3.2",
"styled-components": "5.1.0",
"sudo-prompt": "github:zvin/sudo-prompt#7cdede2f0da28fbcc2db48402d7d935f3a825c91",
"sys-class-rgb-led": "^3.0.0",
"ts-loader": "^8.0.12",
"ts-node": "^9.1.1",
"tslib": "^2.0.0",
"typescript": "^4.2.2",
"url-loader": "^4.1.1",
"uuid": "^8.1.0",
"webpack": "^5.11.0",
"webpack-cli": "^4.2.0",
"webpack-dev-server": "^3.11.2"
"sys-class-rgb-led": "3.0.0",
"url-loader": "4.1.1",
"uuid": "8.1.0"
},
"devDependencies": {
"@balena/lint": "5.3.0",
"@svgr/webpack": "5.5.0",
"@types/chai": "4.2.7",
"@types/copy-webpack-plugin": "6.0.0",
"@types/mime-types": "2.1.0",
"@types/mini-css-extract-plugin": "1.2.2",
"@types/mocha": "8.0.3",
"@types/node": "14.14.41",
"@types/node-ipc": "9.1.2",
"@types/react": "^16.8.5",
"@types/react-dom": "16.8.4",
"@types/semver": "7.1.0",
"@types/sinon": "9.0.0",
"@types/terser-webpack-plugin": "5.0.2",
"@types/tmp": "0.2.0",
"@types/webpack-node-externals": "2.5.0",
"chai": "4.2.0",
"copy-webpack-plugin": "7.0.0",
"css-loader": "5.0.1",
"electron": "12.0.2",
"electron-builder": "22.10.5",
"electron-mocha": "9.3.2",
"electron-notarize": "1.0.0",
"electron-updater": "4.3.5",
"file-loader": "6.2.0",
"husky": "4.2.5",
"lint-staged": "10.2.2",
"mini-css-extract-plugin": "1.3.3",
"mocha": "8.0.1",
"native-addon-loader": "2.0.1",
"pnp-webpack-plugin": "1.6.4",
"simple-progress-webpack-plugin": "1.1.2",
"sinon": "9.0.2",
"spectron": "14.0.0",
"string-replace-loader": "3.0.1",
"style-loader": "2.0.0",
"ts-loader": "8.0.12",
"ts-node": "9.1.1",
"tslib": "2.0.0",
"typescript": "4.2.2",
"webpack": "5.11.0",
"webpack-cli": "4.2.0",
"webpack-dev-server": "3.11.2"
},
"versionist": {
"publishedAt": "2021-09-20T10:42:04.882Z"

View File

@ -37,7 +37,7 @@ async function main() {
SHRINKWRAP_FILENAME,
JSON.stringify(cleaned, null, JSON_INDENT),
);
} catch (error) {
} catch (error: any) {
console.log(`[ERROR] Couldn't write shrinkwrap file: ${error.stack}`);
process.exitCode = 1;
}

View File

@ -573,7 +573,8 @@ describe('Model: flashState', function () {
});
describe('.getFlashUuid()', function () {
const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
const UUID_REGEX =
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
it('should be initially undefined', function () {
expect(flashState.getFlashUuid()).to.be.undefined;

View File

@ -23,7 +23,7 @@ import * as settings from '../../../lib/gui/app/models/settings';
async function checkError(promise: Promise<any>, fn: (err: Error) => any) {
try {
await promise;
} catch (error) {
} catch (error: any) {
await fn(error);
return;
}

View File

@ -83,7 +83,7 @@ describe('Browser: imageWriter', () => {
imageWriter.flash(image, [fakeDrive], performWriteStub),
]);
assert.fail('Writing twice should fail');
} catch (error) {
} catch (error: any) {
expect(error.message).to.equal(
'There is already a flash in progress',
);
@ -133,7 +133,7 @@ describe('Browser: imageWriter', () => {
});
try {
await imageWriter.flash(image, [fakeDrive], performWriteStub);
} catch (error) {
} catch (error: any) {
expect(error).to.be.an.instanceof(Error);
expect(error.message).to.equal('write error');
}

View File

@ -1158,7 +1158,7 @@ describe('Shared: DriveConstraints', function () {
'/dev/disk6',
];
const drives = [
({
{
device: drivePaths[0],
description: 'My Drive',
size: 123456789,
@ -1166,8 +1166,8 @@ describe('Shared: DriveConstraints', function () {
mountpoints: [{ path: __dirname }],
isSystem: false,
isReadOnly: false,
} as unknown) as constraints.DrivelistDrive,
({
} as unknown as constraints.DrivelistDrive,
{
device: drivePaths[1],
description: 'My Other Drive',
size: 123456789,
@ -1175,8 +1175,8 @@ describe('Shared: DriveConstraints', function () {
mountpoints: [],
isSystem: false,
isReadOnly: true,
} as unknown) as constraints.DrivelistDrive,
({
} as unknown as constraints.DrivelistDrive,
{
device: drivePaths[2],
description: 'My Drive',
size: 1234567,
@ -1184,8 +1184,8 @@ describe('Shared: DriveConstraints', function () {
mountpoints: [],
isSystem: false,
isReadOnly: false,
} as unknown) as constraints.DrivelistDrive,
({
} as unknown as constraints.DrivelistDrive,
{
device: drivePaths[3],
description: 'My Drive',
size: 123456789,
@ -1193,8 +1193,8 @@ describe('Shared: DriveConstraints', function () {
mountpoints: [],
isSystem: true,
isReadOnly: false,
} as unknown) as constraints.DrivelistDrive,
({
} as unknown as constraints.DrivelistDrive,
{
device: drivePaths[4],
description: 'My Drive',
size: 128000000001,
@ -1202,8 +1202,8 @@ describe('Shared: DriveConstraints', function () {
mountpoints: [],
isSystem: false,
isReadOnly: false,
} as unknown) as constraints.DrivelistDrive,
({
} as unknown as constraints.DrivelistDrive,
{
device: drivePaths[5],
description: 'My Drive',
size: 12345678,
@ -1211,8 +1211,8 @@ describe('Shared: DriveConstraints', function () {
mountpoints: [],
isSystem: false,
isReadOnly: false,
} as unknown) as constraints.DrivelistDrive,
({
} as unknown as constraints.DrivelistDrive,
{
device: drivePaths[6],
description: 'My Drive',
size: 123456789,
@ -1220,7 +1220,7 @@ describe('Shared: DriveConstraints', function () {
mountpoints: [],
isSystem: false,
isReadOnly: false,
} as unknown) as constraints.DrivelistDrive,
} as unknown as constraints.DrivelistDrive,
];
const image: SourceMetadata = {

View File

@ -30,9 +30,8 @@ describe('Shared: SupportedFormats', function () {
],
(imagePath) => {
it(`should return true if filename is ${imagePath}`, function () {
const looksLikeWindowsImage = supportedFormats.looksLikeWindowsImage(
imagePath,
);
const looksLikeWindowsImage =
supportedFormats.looksLikeWindowsImage(imagePath);
expect(looksLikeWindowsImage).to.be.true;
});
},
@ -45,9 +44,8 @@ describe('Shared: SupportedFormats', function () {
],
(imagePath) => {
it(`should return false if filename is ${imagePath}`, function () {
const looksLikeWindowsImage = supportedFormats.looksLikeWindowsImage(
imagePath,
);
const looksLikeWindowsImage =
supportedFormats.looksLikeWindowsImage(imagePath);
expect(looksLikeWindowsImage).to.be.false;
});
},

View File

@ -28,7 +28,7 @@ if (platform() !== 'darwin') {
this.timeout(40000);
const app = new Application({
path: (electronPath as unknown) as string,
path: electronPath as unknown as string,
args: ['--no-sandbox', '.'],
});