mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-21 10:16:32 +00:00
Convert utils.js to typescript
Change-type: patch
This commit is contained in:
parent
d08d2e00ee
commit
b5593ef5b2
@ -27,6 +27,7 @@ const supportedFormats = require('../../../shared/supported-formats')
|
|||||||
const errors = require('../../../shared/errors')
|
const errors = require('../../../shared/errors')
|
||||||
// eslint-disable-next-line node/no-missing-require
|
// eslint-disable-next-line node/no-missing-require
|
||||||
const fileExtensions = require('../../../shared/file-extensions')
|
const fileExtensions = require('../../../shared/file-extensions')
|
||||||
|
// eslint-disable-next-line node/no-missing-require
|
||||||
const utils = require('../../../shared/utils')
|
const utils = require('../../../shared/utils')
|
||||||
const settings = require('./settings')
|
const settings = require('./settings')
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ const { buildWindowMenu } = require('./menu')
|
|||||||
const settings = require('./app/models/settings')
|
const settings = require('./app/models/settings')
|
||||||
// eslint-disable-next-line node/no-missing-require
|
// eslint-disable-next-line node/no-missing-require
|
||||||
const analytics = require('./app/modules/analytics')
|
const analytics = require('./app/modules/analytics')
|
||||||
|
// eslint-disable-next-line node/no-missing-require
|
||||||
const { getConfig } = require('../shared/utils')
|
const { getConfig } = require('../shared/utils')
|
||||||
const { version, packageType } = require('../../package.json')
|
const { version, packageType } = require('../../package.json')
|
||||||
/* eslint-disable lodash/prefer-lodash-method */
|
/* eslint-disable lodash/prefer-lodash-method */
|
||||||
|
@ -160,9 +160,9 @@ export function getDescription(
|
|||||||
*/
|
*/
|
||||||
export function createError(options: {
|
export function createError(options: {
|
||||||
title: string;
|
title: string;
|
||||||
description: string;
|
description?: string;
|
||||||
report: boolean;
|
report?: boolean;
|
||||||
code: string;
|
code?: string;
|
||||||
}): Error & { description?: string; report?: boolean; code?: string } {
|
}): Error & { description?: string; report?: boolean; code?: string } {
|
||||||
if (isBlank(options.title)) {
|
if (isBlank(options.title)) {
|
||||||
throw new Error(`Invalid error title: ${options.title}`);
|
throw new Error(`Invalid error title: ${options.title}`);
|
||||||
|
@ -31,6 +31,7 @@ const { promisify } = require('util')
|
|||||||
// eslint-disable-next-line node/no-missing-require
|
// eslint-disable-next-line node/no-missing-require
|
||||||
const errors = require('./errors')
|
const errors = require('./errors')
|
||||||
|
|
||||||
|
// eslint-disable-next-line node/no-missing-require
|
||||||
const { tmpFileDisposer } = require('./utils')
|
const { tmpFileDisposer } = require('./utils')
|
||||||
// eslint-disable-next-line node/no-missing-require
|
// eslint-disable-next-line node/no-missing-require
|
||||||
const { sudo: catalinaSudo } = require('./catalina-sudo/sudo')
|
const { sudo: catalinaSudo } = require('./catalina-sudo/sudo')
|
||||||
|
@ -1,161 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2017 balena.io
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
const _ = require('lodash')
|
|
||||||
const Bluebird = require('bluebird')
|
|
||||||
const request = Bluebird.promisifyAll(require('request'))
|
|
||||||
const tmp = require('tmp')
|
|
||||||
|
|
||||||
// eslint-disable-next-line node/no-missing-require
|
|
||||||
const errors = require('./errors')
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Minimum percentage value
|
|
||||||
* @constant
|
|
||||||
* @public
|
|
||||||
* @type {Number}
|
|
||||||
*/
|
|
||||||
exports.PERCENTAGE_MINIMUM = 0
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Maximum percentage value
|
|
||||||
* @constant
|
|
||||||
* @public
|
|
||||||
* @type {Number}
|
|
||||||
*/
|
|
||||||
exports.PERCENTAGE_MAXIMUM = 100
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Check if a percentage is valid
|
|
||||||
* @function
|
|
||||||
* @public
|
|
||||||
*
|
|
||||||
* @param {Number} percentage - percentage
|
|
||||||
* @returns {Boolean} whether the percentage is valid
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* if (utils.isValidPercentage(85)) {
|
|
||||||
* console.log('The percentage is valid');
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
exports.isValidPercentage = (percentage) => {
|
|
||||||
return _.every([
|
|
||||||
_.isNumber(percentage),
|
|
||||||
percentage >= exports.PERCENTAGE_MINIMUM,
|
|
||||||
percentage <= exports.PERCENTAGE_MAXIMUM
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Convert a percentage to a float
|
|
||||||
* @function
|
|
||||||
* @public
|
|
||||||
*
|
|
||||||
* @param {Number} percentage - percentage
|
|
||||||
* @returns {Number} float percentage
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* const value = utils.percentageToFloat(50);
|
|
||||||
* console.log(value);
|
|
||||||
* > 0.5
|
|
||||||
*/
|
|
||||||
exports.percentageToFloat = (percentage) => {
|
|
||||||
if (!exports.isValidPercentage(percentage)) {
|
|
||||||
throw errors.createError({
|
|
||||||
title: `Invalid percentage: ${percentage}`
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return percentage / exports.PERCENTAGE_MAXIMUM
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Check if obj has one or many specific props
|
|
||||||
* @function
|
|
||||||
* @public
|
|
||||||
*
|
|
||||||
* @param {Object} obj - object
|
|
||||||
* @param {Array<String>} props - properties
|
|
||||||
*
|
|
||||||
* @returns {Boolean}
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* const doesIt = hasProps({ foo: 'bar' }, [ 'foo' ]);
|
|
||||||
*/
|
|
||||||
exports.hasProps = (obj, props) => {
|
|
||||||
return _.every(props, (prop) => {
|
|
||||||
return _.has(obj, prop)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Get etcher configs stored online
|
|
||||||
* @param {String} - url where config.json is stored
|
|
||||||
*/
|
|
||||||
// eslint-disable-next-line
|
|
||||||
exports.getConfig = (configUrl) => {
|
|
||||||
return request.getAsync(configUrl, { json: true })
|
|
||||||
.get('body')
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary returns { path: String, cleanup: Function }
|
|
||||||
* @function
|
|
||||||
*
|
|
||||||
* @param {Object} options - options
|
|
||||||
*
|
|
||||||
* @returns {Promise<{ path: String, cleanup: Function }>}
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* tmpFileAsync()
|
|
||||||
* .then({ path, cleanup } => {
|
|
||||||
* console.log(path)
|
|
||||||
* cleanup()
|
|
||||||
* });
|
|
||||||
*/
|
|
||||||
const tmpFileAsync = (options) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
tmp.file(options, (error, path, _fd, cleanup) => {
|
|
||||||
if (error) {
|
|
||||||
reject(error)
|
|
||||||
} else {
|
|
||||||
resolve({ path, cleanup })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Disposer for tmpFileAsync, calls cleanup()
|
|
||||||
* @function
|
|
||||||
*
|
|
||||||
* @param {Object} options - options
|
|
||||||
*
|
|
||||||
* @returns {Disposer<{ path: String, cleanup: Function }>}
|
|
||||||
*
|
|
||||||
* @example
|
|
||||||
* await Bluebird.using(tmpFileDisposer(), ({ path }) => {
|
|
||||||
* console.log(path);
|
|
||||||
* })
|
|
||||||
*/
|
|
||||||
exports.tmpFileDisposer = (options) => {
|
|
||||||
return Bluebird.resolve(tmpFileAsync(options))
|
|
||||||
.disposer(({ cleanup }) => {
|
|
||||||
cleanup()
|
|
||||||
})
|
|
||||||
}
|
|
97
lib/shared/utils.ts
Executable file
97
lib/shared/utils.ts
Executable file
@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 balena.io
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as Bluebird from 'bluebird';
|
||||||
|
import * as _ from 'lodash';
|
||||||
|
import * as request from 'request';
|
||||||
|
import * as tmp from 'tmp';
|
||||||
|
import { promisify } from 'util';
|
||||||
|
|
||||||
|
import * as errors from './errors';
|
||||||
|
|
||||||
|
const getAsync = promisify(request.get);
|
||||||
|
|
||||||
|
export function isValidPercentage(percentage: any): boolean {
|
||||||
|
return _.every([_.isNumber(percentage), percentage >= 0, percentage <= 100]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function percentageToFloat(percentage: any) {
|
||||||
|
if (!isValidPercentage(percentage)) {
|
||||||
|
throw errors.createError({
|
||||||
|
title: `Invalid percentage: ${percentage}`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return percentage / 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Check if obj has one or many specific props
|
||||||
|
*/
|
||||||
|
export function hasProps(obj: any, props: string[]): boolean {
|
||||||
|
return _.every(props, prop => {
|
||||||
|
return _.has(obj, prop);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Get etcher configs stored online
|
||||||
|
* @param {String} - url where config.json is stored
|
||||||
|
*/
|
||||||
|
export async function getConfig(configUrl: string): Promise<any> {
|
||||||
|
return (await getAsync({ url: configUrl, json: true })).body;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary returns { path: String, cleanup: Function }
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* tmpFileAsync()
|
||||||
|
* .then({ path, cleanup } => {
|
||||||
|
* console.log(path)
|
||||||
|
* cleanup()
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
function tmpFileAsync(
|
||||||
|
options: tmp.FileOptions,
|
||||||
|
): Promise<{ path: string; cleanup: () => void }> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
tmp.file(options, (error, path, _fd, cleanup) => {
|
||||||
|
if (error) {
|
||||||
|
reject(error);
|
||||||
|
} else {
|
||||||
|
resolve({ path, cleanup });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Disposer for tmpFileAsync, calls cleanup()
|
||||||
|
*
|
||||||
|
* @returns {Disposer<{ path: String, cleanup: Function }>}
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* await Bluebird.using(tmpFileDisposer(), ({ path }) => {
|
||||||
|
* console.log(path);
|
||||||
|
* })
|
||||||
|
*/
|
||||||
|
export function tmpFileDisposer(
|
||||||
|
options: tmp.FileOptions,
|
||||||
|
): Bluebird.Disposer<{ path: string; cleanup: () => void }> {
|
||||||
|
return Bluebird.resolve(tmpFileAsync(options)).disposer(({ cleanup }) => {
|
||||||
|
cleanup();
|
||||||
|
});
|
||||||
|
}
|
43
npm-shrinkwrap.json
generated
43
npm-shrinkwrap.json
generated
@ -1098,6 +1098,12 @@
|
|||||||
"integrity": "sha512-0Vk/kqkukxPKSzP9c8WJgisgGDx5oZDbsLLWIP5t70yThO/YleE+GEm2S1GlRALTaack3O7U5OS5qEm7q2kciA==",
|
"integrity": "sha512-0Vk/kqkukxPKSzP9c8WJgisgGDx5oZDbsLLWIP5t70yThO/YleE+GEm2S1GlRALTaack3O7U5OS5qEm7q2kciA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"@types/caseless": {
|
||||||
|
"version": "0.12.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz",
|
||||||
|
"integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@types/color": {
|
"@types/color": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/color/-/color-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/color/-/color-3.0.0.tgz",
|
||||||
@ -1278,6 +1284,31 @@
|
|||||||
"@types/react": "*"
|
"@types/react": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/request": {
|
||||||
|
"version": "2.48.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.4.tgz",
|
||||||
|
"integrity": "sha512-W1t1MTKYR8PxICH+A4HgEIPuAC3sbljoEVfyZbeFJJDbr30guDspJri2XOaM2E+Un7ZjrihaDi7cf6fPa2tbgw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/caseless": "*",
|
||||||
|
"@types/node": "*",
|
||||||
|
"@types/tough-cookie": "*",
|
||||||
|
"form-data": "^2.5.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"form-data": {
|
||||||
|
"version": "2.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz",
|
||||||
|
"integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"asynckit": "^0.4.0",
|
||||||
|
"combined-stream": "^1.0.6",
|
||||||
|
"mime-types": "^2.1.12"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/sanitize-html": {
|
"@types/sanitize-html": {
|
||||||
"version": "1.20.2",
|
"version": "1.20.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/sanitize-html/-/sanitize-html-1.20.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/sanitize-html/-/sanitize-html-1.20.2.tgz",
|
||||||
@ -1304,6 +1335,18 @@
|
|||||||
"csstype": "^2.6.4"
|
"csstype": "^2.6.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/tmp": {
|
||||||
|
"version": "0.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.1.0.tgz",
|
||||||
|
"integrity": "sha512-6IwZ9HzWbCq6XoQWhxLpDjuADodH/MKXRUIDFudvgjcVdjFknvmR+DNsoUeer4XPrEnrZs04Jj+kfV9pFsrhmA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"@types/tough-cookie": {
|
||||||
|
"version": "2.3.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.6.tgz",
|
||||||
|
"integrity": "sha512-wHNBMnkoEBiRAd3s8KTKwIuO9biFtTf0LehITzBhSco+HQI0xkXZbLOD55SW3Aqw3oUkHstkm5SPv58yaAdFPQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@types/usb": {
|
"@types/usb": {
|
||||||
"version": "1.5.1",
|
"version": "1.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/usb/-/usb-1.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/usb/-/usb-1.5.1.tgz",
|
||||||
|
@ -97,6 +97,8 @@
|
|||||||
"@types/mime-types": "^2.1.0",
|
"@types/mime-types": "^2.1.0",
|
||||||
"@types/node": "^12.12.24",
|
"@types/node": "^12.12.24",
|
||||||
"@types/react-dom": "^16.8.4",
|
"@types/react-dom": "^16.8.4",
|
||||||
|
"@types/request": "^2.48.4",
|
||||||
|
"@types/tmp": "^0.1.0",
|
||||||
"babel-loader": "^8.0.4",
|
"babel-loader": "^8.0.4",
|
||||||
"chalk": "^1.1.3",
|
"chalk": "^1.1.3",
|
||||||
"electron": "6.1.4",
|
"electron": "6.1.4",
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const m = require('mochainon')
|
const m = require('mochainon')
|
||||||
|
// eslint-disable-next-line node/no-missing-require
|
||||||
const utils = require('../../lib/shared/utils')
|
const utils = require('../../lib/shared/utils')
|
||||||
|
|
||||||
describe('Shared: Utils', function () {
|
describe('Shared: Utils', function () {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user