Convert utils.js to typescript

Change-type: patch
This commit is contained in:
Alexis Svinartchouk 2020-01-08 18:31:37 +01:00 committed by Lorenzo Alberto Maria Ambrosi
parent d08d2e00ee
commit b5593ef5b2
9 changed files with 149 additions and 164 deletions

View File

@ -27,6 +27,7 @@ const supportedFormats = require('../../../shared/supported-formats')
const errors = require('../../../shared/errors')
// eslint-disable-next-line node/no-missing-require
const fileExtensions = require('../../../shared/file-extensions')
// eslint-disable-next-line node/no-missing-require
const utils = require('../../../shared/utils')
const settings = require('./settings')

View File

@ -29,6 +29,7 @@ const { buildWindowMenu } = require('./menu')
const settings = require('./app/models/settings')
// eslint-disable-next-line node/no-missing-require
const analytics = require('./app/modules/analytics')
// eslint-disable-next-line node/no-missing-require
const { getConfig } = require('../shared/utils')
const { version, packageType } = require('../../package.json')
/* eslint-disable lodash/prefer-lodash-method */

View File

@ -160,9 +160,9 @@ export function getDescription(
*/
export function createError(options: {
title: string;
description: string;
report: boolean;
code: string;
description?: string;
report?: boolean;
code?: string;
}): Error & { description?: string; report?: boolean; code?: string } {
if (isBlank(options.title)) {
throw new Error(`Invalid error title: ${options.title}`);

View File

@ -31,6 +31,7 @@ const { promisify } = require('util')
// eslint-disable-next-line node/no-missing-require
const errors = require('./errors')
// eslint-disable-next-line node/no-missing-require
const { tmpFileDisposer } = require('./utils')
// eslint-disable-next-line node/no-missing-require
const { sudo: catalinaSudo } = require('./catalina-sudo/sudo')

View File

@ -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
View 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
View File

@ -1098,6 +1098,12 @@
"integrity": "sha512-0Vk/kqkukxPKSzP9c8WJgisgGDx5oZDbsLLWIP5t70yThO/YleE+GEm2S1GlRALTaack3O7U5OS5qEm7q2kciA==",
"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": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/color/-/color-3.0.0.tgz",
@ -1278,6 +1284,31 @@
"@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": {
"version": "1.20.2",
"resolved": "https://registry.npmjs.org/@types/sanitize-html/-/sanitize-html-1.20.2.tgz",
@ -1304,6 +1335,18 @@
"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": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/@types/usb/-/usb-1.5.1.tgz",

View File

@ -97,6 +97,8 @@
"@types/mime-types": "^2.1.0",
"@types/node": "^12.12.24",
"@types/react-dom": "^16.8.4",
"@types/request": "^2.48.4",
"@types/tmp": "^0.1.0",
"babel-loader": "^8.0.4",
"chalk": "^1.1.3",
"electron": "6.1.4",

View File

@ -17,6 +17,7 @@
'use strict'
const m = require('mochainon')
// eslint-disable-next-line node/no-missing-require
const utils = require('../../lib/shared/utils')
describe('Shared: Utils', function () {