mirror of
https://github.com/balena-io/balena-cli.git
synced 2025-02-20 09:26:42 +00:00
Lots of small TypeScript tweaks & clarifications from review
This commit is contained in:
parent
6ab60d0ccd
commit
612012aff8
@ -17,17 +17,15 @@ export function getOptionSignature(signature: string) {
|
||||
export function parseSignature(option: OptionDefinition) {
|
||||
let result = getOptionSignature(option.signature);
|
||||
|
||||
if (!_.isEmpty(option.alias)) {
|
||||
if (_.isString(option.alias)) {
|
||||
result += `, ${getOptionSignature(option.alias)}`;
|
||||
} else {
|
||||
for (let alias of option.alias!) {
|
||||
result += `, ${getOptionSignature(alias)}`;
|
||||
}
|
||||
if (_.isArray(option.alias)) {
|
||||
for (let alias of option.alias) {
|
||||
result += `, ${getOptionSignature(alias)}`;
|
||||
}
|
||||
} else if (_.isString(option.alias)) {
|
||||
result += `, ${getOptionSignature(option.alias)}`;
|
||||
}
|
||||
|
||||
if (option.parameter != null) {
|
||||
if (option.parameter) {
|
||||
result += ` <${option.parameter}>`;
|
||||
}
|
||||
|
||||
|
@ -36,8 +36,7 @@ export function generateBaseConfig(application: ResinSdk.Application, options: {
|
||||
vpnUrl: resin.settings.get('vpnUrl'),
|
||||
registryUrl: resin.settings.get('registryUrl'),
|
||||
deltaUrl: resin.settings.get('deltaUrl'),
|
||||
pubNubKeys: resin.models.config.getAll().get('pubnub'),
|
||||
mixpanelToken: resin.models.config.getAll().get('mixpanelToken'),
|
||||
apiConfig: resin.models.config.getAll(),
|
||||
}).then((results) => {
|
||||
return deviceConfig.generate({
|
||||
application,
|
||||
@ -51,9 +50,9 @@ export function generateBaseConfig(application: ResinSdk.Application, options: {
|
||||
registry: results.registryUrl,
|
||||
delta: results.deltaUrl,
|
||||
},
|
||||
pubnub: results.pubNubKeys,
|
||||
pubnub: results.apiConfig.pubnub,
|
||||
mixpanel: {
|
||||
token: results.mixpanelToken,
|
||||
token: results.apiConfig.mixpanelToken,
|
||||
},
|
||||
}, options);
|
||||
});
|
||||
@ -61,7 +60,7 @@ export function generateBaseConfig(application: ResinSdk.Application, options: {
|
||||
|
||||
export function generateApplicationConfig(application: ResinSdk.Application, options: {}) {
|
||||
return generateBaseConfig(application, options)
|
||||
.tap(config => authenticateWithApplicationKey(config, application.id));
|
||||
.tap(config => addApplicationKey(config, application.id));
|
||||
}
|
||||
|
||||
export function generateDeviceConfig(
|
||||
@ -76,10 +75,10 @@ export function generateDeviceConfig(
|
||||
// Device API keys are only safe for ResinOS 2.0.3+. We could somehow obtain
|
||||
// the expected version for this config and generate one when we know it's safe,
|
||||
// but instead for now we fall back to app keys unless the user has explicitly opted in.
|
||||
if (deviceApiKey != null) {
|
||||
return authenticateWithDeviceKey(config, device.uuid, deviceApiKey);
|
||||
if (deviceApiKey) {
|
||||
return addDeviceKey(config, device.uuid, deviceApiKey);
|
||||
} else {
|
||||
return authenticateWithApplicationKey(config, application.id);
|
||||
return addApplicationKey(config, application.id);
|
||||
}
|
||||
});
|
||||
}).then((config) => {
|
||||
@ -93,14 +92,14 @@ export function generateDeviceConfig(
|
||||
});
|
||||
}
|
||||
|
||||
function authenticateWithApplicationKey(config: any, applicationNameOrId: string | number) {
|
||||
function addApplicationKey(config: any, applicationNameOrId: string | number) {
|
||||
return resin.models.application.generateApiKey(applicationNameOrId)
|
||||
.tap((apiKey) => {
|
||||
config.apiKey = apiKey;
|
||||
});
|
||||
}
|
||||
|
||||
function authenticateWithDeviceKey(config: any, uuid: string, customDeviceApiKey: string) {
|
||||
function addDeviceKey(config: any, uuid: string, customDeviceApiKey: string) {
|
||||
return Promise.try(() => {
|
||||
return customDeviceApiKey || resin.models.device.generateDeviceKey(uuid);
|
||||
}).tap((deviceApiKey) => {
|
||||
|
@ -26,6 +26,10 @@ import ResinSdk = require('resin-sdk');
|
||||
import { execute } from 'president';
|
||||
import { InitializeEmitter, OperationState } from 'resin-device-init';
|
||||
|
||||
const extractStreamAsync = Promise.promisify(rindle.extract);
|
||||
const waitStreamAsync = Promise.promisify(rindle.wait);
|
||||
const presidentExecuteAsync = Promise.promisify(execute);
|
||||
|
||||
const resin = ResinSdk.fromSharedOptions();
|
||||
|
||||
export function getGroupDefaults(
|
||||
@ -39,8 +43,8 @@ export function getGroupDefaults(
|
||||
}
|
||||
|
||||
export function stateToString(state: OperationState) {
|
||||
const percentage = _.padStart(`${state.percentage}`, 3, '0') + '%';
|
||||
const result = `${chalk.blue(percentage)} ${chalk.cyan(state.operation.command)}`;
|
||||
const percentage = _.padStart(`${state.percentage}`, 3, '0');
|
||||
const result = `${chalk.blue(percentage + '%')} ${chalk.cyan(state.operation.command)}`;
|
||||
|
||||
switch (state.operation.command) {
|
||||
case 'copy':
|
||||
@ -61,7 +65,6 @@ export function sudo(command: string[]) {
|
||||
|
||||
command = _.union(_.take(process.argv, 2), command);
|
||||
|
||||
const presidentExecuteAsync = Promise.promisify(execute);
|
||||
return presidentExecuteAsync(command);
|
||||
}
|
||||
|
||||
@ -75,7 +78,8 @@ export function getManifest(image: string, deviceType: string): Promise<ResinSdk
|
||||
primary: 1,
|
||||
},
|
||||
path: '/device-type.json',
|
||||
}).then(Promise.promisify(rindle.extract))
|
||||
})
|
||||
.then(extractStreamAsync)
|
||||
.then(JSON.parse)
|
||||
.catch(() => resin.models.device.getManifestBySlug(deviceType));
|
||||
}
|
||||
@ -86,7 +90,7 @@ export function osProgressHandler(step: InitializeEmitter) {
|
||||
|
||||
step.on('state', function(state) {
|
||||
if (state.operation.command === 'burn') { return; }
|
||||
return console.log(exports.stateToString(state));
|
||||
console.log(exports.stateToString(state));
|
||||
});
|
||||
|
||||
const progressBars = {
|
||||
@ -96,7 +100,7 @@ export function osProgressHandler(step: InitializeEmitter) {
|
||||
|
||||
step.on('burn', state => progressBars[state.type].update(state));
|
||||
|
||||
return Promise.promisify(rindle.wait)(step);
|
||||
return waitStreamAsync(step);
|
||||
}
|
||||
|
||||
export function getArchAndDeviceType(applicationName: string): Promise<{ arch: string, device_type: string }> {
|
||||
@ -104,9 +108,9 @@ export function getArchAndDeviceType(applicationName: string): Promise<{ arch: s
|
||||
getApplication(applicationName),
|
||||
resin.models.config.getDeviceTypes(),
|
||||
function (app, deviceTypes) {
|
||||
let config = _.find(deviceTypes, { slug: app.device_type });
|
||||
const config = _.find(deviceTypes, { slug: app.device_type });
|
||||
|
||||
if (config == null) {
|
||||
if (!config) {
|
||||
throw new Error('Could not read application information!');
|
||||
}
|
||||
|
||||
@ -116,11 +120,11 @@ export function getArchAndDeviceType(applicationName: string): Promise<{ arch: s
|
||||
}
|
||||
|
||||
function getApplication(applicationName: string) {
|
||||
let match;
|
||||
|
||||
// Check for an app of the form `user/application`, and send
|
||||
// this off to a special handler (before importing any modules)
|
||||
if (match = /(\w+)\/(\w+)/.exec(applicationName)) {
|
||||
// that off to a special handler (before importing any modules)
|
||||
const match = /(\w+)\/(\w+)/.exec(applicationName);
|
||||
|
||||
if (match) {
|
||||
return resin.models.application.getAppByOwner(match[2], match[1]);
|
||||
}
|
||||
|
||||
|
@ -33,11 +33,9 @@ export class Logger {
|
||||
error: logger.createLogStream('error'),
|
||||
};
|
||||
|
||||
_.mapKeys(this.streams, function(stream, key) {
|
||||
if (key !== 'debug') {
|
||||
return stream.pipe(process.stdout);
|
||||
} else {
|
||||
if (process.env.DEBUG != null) { return stream.pipe(process.stdout); }
|
||||
_.forEach(this.streams, function(stream, key) {
|
||||
if (key !== 'debug' || process.env.DEBUG) {
|
||||
stream.pipe(process.stdout);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -25,8 +25,8 @@ import messages = require('./messages');
|
||||
|
||||
const resin = ResinSdk.fromSharedOptions();
|
||||
|
||||
export function authenticate(options: {}) {
|
||||
form.run([{
|
||||
export function authenticate(options: {}): Promise<void> {
|
||||
return form.run([{
|
||||
message: 'Email:',
|
||||
name: 'email',
|
||||
type: 'input',
|
||||
@ -44,13 +44,17 @@ export function authenticate(options: {}) {
|
||||
return form.ask({
|
||||
message: 'Two factor auth challenge:',
|
||||
name: 'code',
|
||||
type: 'input'}).then(resin.auth.twoFactor.challenge)
|
||||
.catch((error: any) => resin.auth.logout().then(() => {
|
||||
if ((error.name === 'ResinRequestError') && (error.statusCode === 401)) {
|
||||
throw new Error('Invalid two factor authentication code');
|
||||
}
|
||||
throw error;
|
||||
}));
|
||||
type: 'input',
|
||||
})
|
||||
.then(resin.auth.twoFactor.challenge)
|
||||
.catch((error: any) => {
|
||||
return resin.auth.logout().then(() => {
|
||||
if ((error.name === 'ResinRequestError') && (error.statusCode === 401)) {
|
||||
throw new Error('Invalid two factor authentication code');
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -132,8 +136,10 @@ export function selectOrCreateApplication() {
|
||||
if (!hasAnyApplications) return;
|
||||
|
||||
return resin.models.application.getAll().then((applications) => {
|
||||
let appOptions: { name: string, value: string | null }[];
|
||||
appOptions = _.map(applications, application => ({
|
||||
const appOptions = _.map<
|
||||
ResinSdk.Application,
|
||||
{ name: string, value: string | null }
|
||||
>(applications, application => ({
|
||||
name: `${application.app_name} (${application.device_type})`,
|
||||
value: application.app_name,
|
||||
}));
|
||||
@ -150,7 +156,9 @@ export function selectOrCreateApplication() {
|
||||
});
|
||||
});
|
||||
}).then((application) => {
|
||||
if (application != null) return application;
|
||||
if (application) {
|
||||
return application;
|
||||
}
|
||||
|
||||
return form.ask({
|
||||
message: 'Choose a Name for your new application',
|
||||
@ -189,13 +197,13 @@ export function awaitDevice(uuid: string) {
|
||||
|
||||
export function inferOrSelectDevice(preferredUuid: string) {
|
||||
return resin.models.device.getAll()
|
||||
.filter((device: ResinSdk.Device) => device.is_online)
|
||||
.then((onlineDevices: ResinSdk.Device[]) => {
|
||||
.filter<ResinSdk.Device>((device) => device.is_online)
|
||||
.then((onlineDevices) => {
|
||||
if (_.isEmpty(onlineDevices)) {
|
||||
throw new Error('You don\'t have any devices online');
|
||||
}
|
||||
|
||||
let defaultUuid = Array.from(_.map(onlineDevices, 'uuid')).includes(preferredUuid) ?
|
||||
const defaultUuid = _.map(onlineDevices, 'uuid').includes(preferredUuid) ?
|
||||
preferredUuid :
|
||||
onlineDevices[0].uuid;
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
import { ReadStream } from 'fs';
|
||||
|
||||
export async function buffer(stream: NodeJS.ReadableStream, bufferFile: string) {
|
||||
const Promise = await import('bluebird');
|
||||
const fs = await import('fs');
|
||||
@ -7,14 +5,15 @@ export async function buffer(stream: NodeJS.ReadableStream, bufferFile: string)
|
||||
const fileWriteStream = fs.createWriteStream(bufferFile);
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
return stream
|
||||
stream
|
||||
.on('error', reject)
|
||||
.on('end', resolve)
|
||||
.pipe(fileWriteStream);
|
||||
}).then(() => new Promise(function(resolve, reject) {
|
||||
fs.createReadStream(bufferFile)
|
||||
.on('open', function(this: ReadStream) {
|
||||
resolve(this);
|
||||
}).on('error', reject);
|
||||
const stream = fs.createReadStream(bufferFile);
|
||||
|
||||
stream
|
||||
.on('open', () => resolve(stream))
|
||||
.on('error', reject);
|
||||
}));
|
||||
}
|
||||
|
@ -34,18 +34,14 @@ if (!isRoot()) {
|
||||
});
|
||||
}
|
||||
|
||||
export function hasAvailableUpdate() {
|
||||
return notifier != null;
|
||||
}
|
||||
|
||||
export function notify() {
|
||||
if (!exports.hasAvailableUpdate()) {
|
||||
if (!notifier) {
|
||||
return;
|
||||
}
|
||||
|
||||
notifier.notify({ defer: false });
|
||||
|
||||
if (notifier.update != null) {
|
||||
return console.log('Notice that you might need administrator privileges depending on your setup\n');
|
||||
console.log('Notice that you might need administrator privileges depending on your setup\n');
|
||||
}
|
||||
}
|
||||
|
1
typings/resin-device-init.d.ts
vendored
1
typings/resin-device-init.d.ts
vendored
@ -1,4 +1,5 @@
|
||||
declare module 'resin-device-init' {
|
||||
import * as Promise from 'bluebird';
|
||||
import { EventEmitter } from 'events';
|
||||
|
||||
interface OperationState {
|
||||
|
2
typings/resin-sdk-preconfigured.d.ts
vendored
2
typings/resin-sdk-preconfigured.d.ts
vendored
@ -1,4 +1,4 @@
|
||||
declare module 'resin-sdk-preconfiguredasd' {
|
||||
declare module 'resin-sdk-preconfigured' {
|
||||
import { ResinSDK } from 'resin-sdk';
|
||||
let sdk: ResinSDK;
|
||||
export = sdk;
|
||||
|
Loading…
x
Reference in New Issue
Block a user