mirror of
https://github.com/balena-io/balena-cli.git
synced 2024-12-18 21:27:51 +00:00
Enforce and improve lazy loading of resin-cli-form
Change-type: patch
This commit is contained in:
parent
0bd27bd7ac
commit
eea8c83bff
@ -19,7 +19,7 @@ import { flags } from '@oclif/command';
|
|||||||
import type { IArg } from '@oclif/parser/lib/args';
|
import type { IArg } from '@oclif/parser/lib/args';
|
||||||
import Command from '../../command';
|
import Command from '../../command';
|
||||||
import * as cf from '../../utils/common-flags';
|
import * as cf from '../../utils/common-flags';
|
||||||
import { getBalenaSdk, stripIndent } from '../../utils/lazy';
|
import { getBalenaSdk, stripIndent, getCliForm } from '../../utils/lazy';
|
||||||
import { tryAsInteger } from '../../utils/validation';
|
import { tryAsInteger } from '../../utils/validation';
|
||||||
import type { Device } from 'balena-sdk';
|
import type { Device } from 'balena-sdk';
|
||||||
import { ExpectedError } from '../../errors';
|
import { ExpectedError } from '../../errors';
|
||||||
@ -78,7 +78,6 @@ export default class DeviceOsUpdateCmd extends Command {
|
|||||||
|
|
||||||
const sdk = getBalenaSdk();
|
const sdk = getBalenaSdk();
|
||||||
const patterns = await import('../../utils/patterns');
|
const patterns = await import('../../utils/patterns');
|
||||||
const form = await import('resin-cli-form');
|
|
||||||
|
|
||||||
// Get device info
|
// Get device info
|
||||||
const {
|
const {
|
||||||
@ -121,7 +120,7 @@ export default class DeviceOsUpdateCmd extends Command {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
targetOsVersion = await form.ask({
|
targetOsVersion = await getCliForm().ask({
|
||||||
message: 'Target OS version',
|
message: 'Target OS version',
|
||||||
type: 'list',
|
type: 'list',
|
||||||
choices: hupVersionInfo.versions.map((version) => ({
|
choices: hupVersionInfo.versions.map((version) => ({
|
||||||
|
@ -19,7 +19,7 @@ import { flags } from '@oclif/command';
|
|||||||
import type { IArg } from '@oclif/parser/lib/args';
|
import type { IArg } from '@oclif/parser/lib/args';
|
||||||
import Command from '../../command';
|
import Command from '../../command';
|
||||||
import * as cf from '../../utils/common-flags';
|
import * as cf from '../../utils/common-flags';
|
||||||
import { getBalenaSdk, stripIndent } from '../../utils/lazy';
|
import { getBalenaSdk, stripIndent, getCliForm } from '../../utils/lazy';
|
||||||
import { tryAsInteger } from '../../utils/validation';
|
import { tryAsInteger } from '../../utils/validation';
|
||||||
|
|
||||||
interface FlagsDef {
|
interface FlagsDef {
|
||||||
@ -69,11 +69,10 @@ export default class DeviceRenameCmd extends Command {
|
|||||||
const { args: params } = this.parse<FlagsDef, ArgsDef>(DeviceRenameCmd);
|
const { args: params } = this.parse<FlagsDef, ArgsDef>(DeviceRenameCmd);
|
||||||
|
|
||||||
const balena = getBalenaSdk();
|
const balena = getBalenaSdk();
|
||||||
const form = await import('resin-cli-form');
|
|
||||||
|
|
||||||
const newName =
|
const newName =
|
||||||
params.newName ||
|
params.newName ||
|
||||||
(await form.ask({
|
(await getCliForm().ask({
|
||||||
message: 'How do you want to name this device?',
|
message: 'How do you want to name this device?',
|
||||||
type: 'input',
|
type: 'input',
|
||||||
})) ||
|
})) ||
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
import { flags } from '@oclif/command';
|
import { flags } from '@oclif/command';
|
||||||
import Command from '../command';
|
import Command from '../command';
|
||||||
import * as cf from '../utils/common-flags';
|
import * as cf from '../utils/common-flags';
|
||||||
import { getBalenaSdk, stripIndent } from '../utils/lazy';
|
import { getBalenaSdk, stripIndent, getCliForm } from '../utils/lazy';
|
||||||
import { ExpectedError } from '../errors';
|
import { ExpectedError } from '../errors';
|
||||||
|
|
||||||
interface FlagsDef {
|
interface FlagsDef {
|
||||||
@ -147,8 +147,7 @@ ${messages.reachingOut}`);
|
|||||||
// Token
|
// Token
|
||||||
if (loginOptions.token) {
|
if (loginOptions.token) {
|
||||||
if (!token) {
|
if (!token) {
|
||||||
const form = await import('resin-cli-form');
|
token = await getCliForm().ask({
|
||||||
token = await form.ask({
|
|
||||||
message: 'Session token or API key from the preferences page',
|
message: 'Session token or API key from the preferences page',
|
||||||
name: 'token',
|
name: 'token',
|
||||||
type: 'input',
|
type: 'input',
|
||||||
|
@ -23,7 +23,7 @@ import Command from '../../command';
|
|||||||
|
|
||||||
import { ExpectedError } from '../../errors';
|
import { ExpectedError } from '../../errors';
|
||||||
import * as cf from '../../utils/common-flags';
|
import * as cf from '../../utils/common-flags';
|
||||||
import { getBalenaSdk, stripIndent } from '../../utils/lazy';
|
import { getBalenaSdk, stripIndent, getCliForm } from '../../utils/lazy';
|
||||||
import { CommandHelp } from '../../utils/oclif-utils';
|
import { CommandHelp } from '../../utils/oclif-utils';
|
||||||
|
|
||||||
const BOOT_PARTITION = 1;
|
const BOOT_PARTITION = 1;
|
||||||
@ -396,7 +396,6 @@ async function askQuestionsForDeviceType(
|
|||||||
options: FlagsDef,
|
options: FlagsDef,
|
||||||
configJson?: import('../../utils/config').ImgConfig,
|
configJson?: import('../../utils/config').ImgConfig,
|
||||||
): Promise<Answers> {
|
): Promise<Answers> {
|
||||||
const form = await import('resin-cli-form');
|
|
||||||
const helpers = await import('../../utils/helpers');
|
const helpers = await import('../../utils/helpers');
|
||||||
const answerSources: any[] = [camelifyConfigOptions(options)];
|
const answerSources: any[] = [camelifyConfigOptions(options)];
|
||||||
const defaultAnswers: Partial<Answers> = {};
|
const defaultAnswers: Partial<Answers> = {};
|
||||||
@ -436,7 +435,7 @@ async function askQuestionsForDeviceType(
|
|||||||
extraOpts = { override: defaultAnswers };
|
extraOpts = { override: defaultAnswers };
|
||||||
}
|
}
|
||||||
|
|
||||||
return form.run(questions, extraOpts);
|
return getCliForm().run(questions, extraOpts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||||||
import * as commandOptions from './command-options';
|
import * as commandOptions from './command-options';
|
||||||
|
|
||||||
import { normalizeUuidProp } from '../utils/normalization';
|
import { normalizeUuidProp } from '../utils/normalization';
|
||||||
import { getBalenaSdk, getVisuals } from '../utils/lazy';
|
import { getBalenaSdk, getVisuals, getCliForm } from '../utils/lazy';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
const getUmountAsync = async () => {
|
const getUmountAsync = async () => {
|
||||||
@ -303,7 +303,6 @@ Examples:
|
|||||||
normalizeUuidProp(options, 'device');
|
normalizeUuidProp(options, 'device');
|
||||||
const Bluebird = require('bluebird');
|
const Bluebird = require('bluebird');
|
||||||
const balena = getBalenaSdk();
|
const balena = getBalenaSdk();
|
||||||
const form = require('resin-cli-form');
|
|
||||||
const prettyjson = require('prettyjson');
|
const prettyjson = require('prettyjson');
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -378,7 +377,7 @@ See the help page for examples:
|
|||||||
formOptions, // Pass params as an override: if there is any param with exactly the same name as a
|
formOptions, // Pass params as an override: if there is any param with exactly the same name as a
|
||||||
) =>
|
) =>
|
||||||
// required option, that value is used (and the corresponding question is not asked)
|
// required option, that value is used (and the corresponding question is not asked)
|
||||||
form.run(formOptions, { override: options }),
|
getCliForm().run(formOptions, { override: options }),
|
||||||
)
|
)
|
||||||
.then(function (answers) {
|
.then(function (answers) {
|
||||||
answers.version = options.version;
|
answers.version = options.version;
|
||||||
|
@ -2,7 +2,7 @@ import * as Bluebird from 'bluebird';
|
|||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import * as dockerUtils from '../../utils/docker';
|
import * as dockerUtils from '../../utils/docker';
|
||||||
import { exitWithExpectedError } from '../../errors';
|
import { exitWithExpectedError } from '../../errors';
|
||||||
import { getChalk } from '../../utils/lazy';
|
import { getChalk, getCliForm } from '../../utils/lazy';
|
||||||
|
|
||||||
export const dockerPort = 2375;
|
export const dockerPort = 2375;
|
||||||
export const dockerTimeout = 2000;
|
export const dockerTimeout = 2000;
|
||||||
@ -26,7 +26,6 @@ export const selectContainerFromDevice = Bluebird.method(function (
|
|||||||
if (filterSupervisor == null) {
|
if (filterSupervisor == null) {
|
||||||
filterSupervisor = false;
|
filterSupervisor = false;
|
||||||
}
|
}
|
||||||
const form = require('resin-cli-form');
|
|
||||||
const docker = dockerUtils.createClient({
|
const docker = dockerUtils.createClient({
|
||||||
host: deviceIp,
|
host: deviceIp,
|
||||||
port: dockerPort,
|
port: dockerPort,
|
||||||
@ -45,7 +44,7 @@ export const selectContainerFromDevice = Bluebird.method(function (
|
|||||||
exitWithExpectedError(`No containers found in ${deviceIp}`);
|
exitWithExpectedError(`No containers found in ${deviceIp}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return form.ask({
|
return getCliForm().ask({
|
||||||
message: 'Select a container',
|
message: 'Select a container',
|
||||||
type: 'list',
|
type: 'list',
|
||||||
choices: _.map(containers, function (container) {
|
choices: _.map(containers, function (container) {
|
||||||
|
@ -17,7 +17,12 @@ limitations under the License.
|
|||||||
import type { CommandDefinition } from 'capitano';
|
import type { CommandDefinition } from 'capitano';
|
||||||
import type * as SDK from 'etcher-sdk';
|
import type * as SDK from 'etcher-sdk';
|
||||||
|
|
||||||
import { getChalk, getVisuals, stripIndent } from '../../utils/lazy';
|
import {
|
||||||
|
getChalk,
|
||||||
|
getVisuals,
|
||||||
|
stripIndent,
|
||||||
|
getCliForm,
|
||||||
|
} from '../../utils/lazy';
|
||||||
import { ExpectedError } from '../../errors';
|
import { ExpectedError } from '../../errors';
|
||||||
|
|
||||||
async function getDrive(options: {
|
async function getDrive(options: {
|
||||||
@ -71,14 +76,13 @@ export const flash: CommandDefinition<
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
async action(params, options) {
|
async action(params, options) {
|
||||||
const form = await import('resin-cli-form');
|
|
||||||
const { sourceDestination, multiWrite } = await import('etcher-sdk');
|
const { sourceDestination, multiWrite } = await import('etcher-sdk');
|
||||||
|
|
||||||
const drive = await getDrive(options);
|
const drive = await getDrive(options);
|
||||||
|
|
||||||
const yes =
|
const yes =
|
||||||
options.yes ||
|
options.yes ||
|
||||||
(await form.ask({
|
(await getCliForm().ask({
|
||||||
message: 'This will erase the selected drive. Are you sure?',
|
message: 'This will erase the selected drive. Are you sure?',
|
||||||
type: 'confirm',
|
type: 'confirm',
|
||||||
name: 'yes',
|
name: 'yes',
|
||||||
|
@ -17,7 +17,7 @@ limitations under the License.
|
|||||||
import * as commandOptions from './command-options';
|
import * as commandOptions from './command-options';
|
||||||
|
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import { getBalenaSdk, getVisuals } from '../utils/lazy';
|
import { getBalenaSdk, getVisuals, getCliForm } from '../utils/lazy';
|
||||||
|
|
||||||
const formatVersion = function (v, isRecommended) {
|
const formatVersion = function (v, isRecommended) {
|
||||||
let result = `v${v}`;
|
let result = `v${v}`;
|
||||||
@ -35,7 +35,6 @@ const resolveVersion = function (deviceType, version) {
|
|||||||
return Promise.resolve(version);
|
return Promise.resolve(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
const form = require('resin-cli-form');
|
|
||||||
const balena = getBalenaSdk();
|
const balena = getBalenaSdk();
|
||||||
|
|
||||||
return balena.models.os
|
return balena.models.os
|
||||||
@ -46,7 +45,7 @@ const resolveVersion = function (deviceType, version) {
|
|||||||
name: formatVersion(v, v === recommended),
|
name: formatVersion(v, v === recommended),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return form.ask({
|
return getCliForm().ask({
|
||||||
message: 'Select the OS version:',
|
message: 'Select the OS version:',
|
||||||
type: 'list',
|
type: 'list',
|
||||||
choices,
|
choices,
|
||||||
@ -185,7 +184,6 @@ const buildConfigForDeviceType = function (deviceType, advanced) {
|
|||||||
if (advanced == null) {
|
if (advanced == null) {
|
||||||
advanced = false;
|
advanced = false;
|
||||||
}
|
}
|
||||||
const form = require('resin-cli-form');
|
|
||||||
const helpers = require('../utils/helpers');
|
const helpers = require('../utils/helpers');
|
||||||
|
|
||||||
let override;
|
let override;
|
||||||
@ -201,7 +199,7 @@ const buildConfigForDeviceType = function (deviceType, advanced) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return form.run(questions, { override });
|
return getCliForm().run(questions, { override });
|
||||||
};
|
};
|
||||||
|
|
||||||
const $buildConfig = function (image, deviceTypeSlug, advanced) {
|
const $buildConfig = function (image, deviceTypeSlug, advanced) {
|
||||||
@ -287,7 +285,6 @@ Examples:
|
|||||||
action(params, options) {
|
action(params, options) {
|
||||||
const Bluebird = require('bluebird');
|
const Bluebird = require('bluebird');
|
||||||
const umountAsync = Bluebird.promisify(require('umount').umount);
|
const umountAsync = Bluebird.promisify(require('umount').umount);
|
||||||
const form = require('resin-cli-form');
|
|
||||||
const patterns = require('../utils/patterns');
|
const patterns = require('../utils/patterns');
|
||||||
const helpers = require('../utils/helpers');
|
const helpers = require('../utils/helpers');
|
||||||
|
|
||||||
@ -298,7 +295,7 @@ ${INIT_WARNING_MESSAGE}\
|
|||||||
`);
|
`);
|
||||||
return Bluebird.resolve(helpers.getManifest(params.image, options.type))
|
return Bluebird.resolve(helpers.getManifest(params.image, options.type))
|
||||||
.then((manifest) =>
|
.then((manifest) =>
|
||||||
form.run(manifest.initialization?.options, {
|
getCliForm().run(manifest.initialization?.options, {
|
||||||
override: {
|
override: {
|
||||||
drive: options.drive,
|
drive: options.drive,
|
||||||
},
|
},
|
||||||
|
@ -15,7 +15,7 @@ limitations under the License.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
import { getBalenaSdk, getVisuals } from '../utils/lazy';
|
import { getBalenaSdk, getVisuals, getCliForm } from '../utils/lazy';
|
||||||
import * as dockerUtils from '../utils/docker';
|
import * as dockerUtils from '../utils/docker';
|
||||||
|
|
||||||
const isCurrent = (commit) => commit === 'latest' || commit === 'current';
|
const isCurrent = (commit) => commit === 'latest' || commit === 'current';
|
||||||
@ -83,7 +83,6 @@ const getApplicationsWithSuccessfulBuilds = function (deviceType) {
|
|||||||
|
|
||||||
const selectApplication = function (deviceType) {
|
const selectApplication = function (deviceType) {
|
||||||
const visuals = getVisuals();
|
const visuals = getVisuals();
|
||||||
const form = require('resin-cli-form');
|
|
||||||
const { exitWithExpectedError } = require('../errors');
|
const { exitWithExpectedError } = require('../errors');
|
||||||
|
|
||||||
const applicationInfoSpinner = new visuals.Spinner(
|
const applicationInfoSpinner = new visuals.Spinner(
|
||||||
@ -100,7 +99,7 @@ const selectApplication = function (deviceType) {
|
|||||||
`You have no apps with successful releases for a '${deviceType}' device type.`,
|
`You have no apps with successful releases for a '${deviceType}' device type.`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return form.ask({
|
return getCliForm().ask({
|
||||||
message: 'Select an application',
|
message: 'Select an application',
|
||||||
type: 'list',
|
type: 'list',
|
||||||
choices: applications.map((app) => ({
|
choices: applications.map((app) => ({
|
||||||
@ -112,7 +111,6 @@ const selectApplication = function (deviceType) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const selectApplicationCommit = function (releases) {
|
const selectApplicationCommit = function (releases) {
|
||||||
const form = require('resin-cli-form');
|
|
||||||
const { exitWithExpectedError } = require('../errors');
|
const { exitWithExpectedError } = require('../errors');
|
||||||
|
|
||||||
if (releases.length === 0) {
|
if (releases.length === 0) {
|
||||||
@ -125,7 +123,7 @@ const selectApplicationCommit = function (releases) {
|
|||||||
value: release.commit,
|
value: release.commit,
|
||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
return form.ask({
|
return getCliForm().ask({
|
||||||
message: 'Select a release',
|
message: 'Select a release',
|
||||||
type: 'list',
|
type: 'list',
|
||||||
default: 'current',
|
default: 'current',
|
||||||
@ -140,7 +138,6 @@ const offerToDisableAutomaticUpdates = function (
|
|||||||
) {
|
) {
|
||||||
const Bluebird = require('bluebird');
|
const Bluebird = require('bluebird');
|
||||||
const balena = getBalenaSdk();
|
const balena = getBalenaSdk();
|
||||||
const form = require('resin-cli-form');
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
isCurrent(commit) ||
|
isCurrent(commit) ||
|
||||||
@ -162,7 +159,7 @@ see https://balena.io/docs/reference/api/resources/device/#set-device-to-release
|
|||||||
|
|
||||||
Alternatively you can pass the --pin-device-to-release flag to pin only this device to the selected release.\
|
Alternatively you can pass the --pin-device-to-release flag to pin only this device to the selected release.\
|
||||||
`;
|
`;
|
||||||
return form
|
return getCliForm()
|
||||||
.ask({
|
.ask({
|
||||||
message,
|
message,
|
||||||
type: 'confirm',
|
type: 'confirm',
|
||||||
|
@ -19,6 +19,7 @@ limitations under the License.
|
|||||||
import type * as BalenaSdk from 'balena-sdk';
|
import type * as BalenaSdk from 'balena-sdk';
|
||||||
import type { Chalk } from 'chalk';
|
import type { Chalk } from 'chalk';
|
||||||
import type * as visuals from 'resin-cli-visuals';
|
import type * as visuals from 'resin-cli-visuals';
|
||||||
|
import type * as CliForm from 'resin-cli-form';
|
||||||
import type { stripIndent as StripIndent } from 'common-tags';
|
import type { stripIndent as StripIndent } from 'common-tags';
|
||||||
|
|
||||||
// Equivalent of _.once but avoiding the need to import lodash for lazy deps
|
// Equivalent of _.once but avoiding the need to import lodash for lazy deps
|
||||||
@ -52,6 +53,10 @@ export const getVisuals = once(
|
|||||||
|
|
||||||
export const getChalk = once(() => require('chalk') as Chalk);
|
export const getChalk = once(() => require('chalk') as Chalk);
|
||||||
|
|
||||||
|
export const getCliForm = once(
|
||||||
|
() => require('resin-cli-form') as typeof CliForm,
|
||||||
|
);
|
||||||
|
|
||||||
// Directly export stripIndent as we always use it immediately, but importing just `stripIndent` reduces startup time
|
// Directly export stripIndent as we always use it immediately, but importing just `stripIndent` reduces startup time
|
||||||
// tslint:disable-next-line:no-var-requires
|
// tslint:disable-next-line:no-var-requires
|
||||||
export const stripIndent = require('common-tags/lib/stripIndent') as typeof StripIndent;
|
export const stripIndent = require('common-tags/lib/stripIndent') as typeof StripIndent;
|
||||||
|
@ -16,7 +16,6 @@ limitations under the License.
|
|||||||
import { BalenaApplicationNotFound } from 'balena-errors';
|
import { BalenaApplicationNotFound } from 'balena-errors';
|
||||||
import type * as BalenaSdk from 'balena-sdk';
|
import type * as BalenaSdk from 'balena-sdk';
|
||||||
import _ = require('lodash');
|
import _ = require('lodash');
|
||||||
import _form = require('resin-cli-form');
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
exitWithExpectedError,
|
exitWithExpectedError,
|
||||||
@ -24,15 +23,13 @@ import {
|
|||||||
NotLoggedInError,
|
NotLoggedInError,
|
||||||
ExpectedError,
|
ExpectedError,
|
||||||
} from '../errors';
|
} from '../errors';
|
||||||
import { getBalenaSdk, getVisuals, stripIndent } from './lazy';
|
import { getBalenaSdk, getVisuals, stripIndent, getCliForm } from './lazy';
|
||||||
import validation = require('./validation');
|
import validation = require('./validation');
|
||||||
import { delay } from './helpers';
|
import { delay } from './helpers';
|
||||||
|
|
||||||
const getForm = _.once((): typeof _form => require('resin-cli-form'));
|
|
||||||
|
|
||||||
export function authenticate(options: {}): Promise<void> {
|
export function authenticate(options: {}): Promise<void> {
|
||||||
const balena = getBalenaSdk();
|
const balena = getBalenaSdk();
|
||||||
return getForm()
|
return getCliForm()
|
||||||
.run(
|
.run(
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
@ -56,7 +53,7 @@ export function authenticate(options: {}): Promise<void> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return getForm()
|
return getCliForm()
|
||||||
.ask({
|
.ask({
|
||||||
message: 'Two factor auth challenge:',
|
message: 'Two factor auth challenge:',
|
||||||
name: 'code',
|
name: 'code',
|
||||||
@ -91,7 +88,7 @@ export async function checkLoggedIn(): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function askLoginType() {
|
export function askLoginType() {
|
||||||
return getForm().ask<'web' | 'credentials' | 'token' | 'register'>({
|
return getCliForm().ask<'web' | 'credentials' | 'token' | 'register'>({
|
||||||
message: 'How would you like to login?',
|
message: 'How would you like to login?',
|
||||||
name: 'loginType',
|
name: 'loginType',
|
||||||
type: 'list',
|
type: 'list',
|
||||||
@ -123,7 +120,7 @@ export function selectDeviceType() {
|
|||||||
deviceTypes = _.sortBy(deviceTypes, 'name').filter(
|
deviceTypes = _.sortBy(deviceTypes, 'name').filter(
|
||||||
(dt) => dt.state !== 'DISCONTINUED',
|
(dt) => dt.state !== 'DISCONTINUED',
|
||||||
);
|
);
|
||||||
return getForm().ask({
|
return getCliForm().ask({
|
||||||
message: 'Device Type',
|
message: 'Device Type',
|
||||||
type: 'list',
|
type: 'list',
|
||||||
choices: _.map(deviceTypes, ({ slug: value, name }) => ({
|
choices: _.map(deviceTypes, ({ slug: value, name }) => ({
|
||||||
@ -147,7 +144,7 @@ export async function confirm(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const confirmed = await getForm().ask<boolean>({
|
const confirmed = await getCliForm().ask<boolean>({
|
||||||
message,
|
message,
|
||||||
type: 'confirm',
|
type: 'confirm',
|
||||||
default: false,
|
default: false,
|
||||||
@ -177,7 +174,7 @@ export function selectApplication(
|
|||||||
})
|
})
|
||||||
.filter(filter || _.constant(true))
|
.filter(filter || _.constant(true))
|
||||||
.then((applications) => {
|
.then((applications) => {
|
||||||
return getForm().ask({
|
return getCliForm().ask({
|
||||||
message: 'Select an application',
|
message: 'Select an application',
|
||||||
type: 'list',
|
type: 'list',
|
||||||
choices: _.map(applications, (application) => ({
|
choices: _.map(applications, (application) => ({
|
||||||
@ -212,7 +209,7 @@ export function selectOrCreateApplication() {
|
|||||||
value: null,
|
value: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
return getForm().ask({
|
return getCliForm().ask({
|
||||||
message: 'Select an application',
|
message: 'Select an application',
|
||||||
type: 'list',
|
type: 'list',
|
||||||
choices: appOptions,
|
choices: appOptions,
|
||||||
@ -224,7 +221,7 @@ export function selectOrCreateApplication() {
|
|||||||
return application;
|
return application;
|
||||||
}
|
}
|
||||||
|
|
||||||
return getForm().ask({
|
return getCliForm().ask({
|
||||||
message: 'Choose a Name for your new application',
|
message: 'Choose a Name for your new application',
|
||||||
type: 'input',
|
type: 'input',
|
||||||
validate: validation.validateApplicationName,
|
validate: validation.validateApplicationName,
|
||||||
@ -324,7 +321,7 @@ export function inferOrSelectDevice(preferredUuid: string) {
|
|||||||
? preferredUuid
|
? preferredUuid
|
||||||
: onlineDevices[0].uuid;
|
: onlineDevices[0].uuid;
|
||||||
|
|
||||||
return getForm().ask({
|
return getCliForm().ask({
|
||||||
message: 'Select a device',
|
message: 'Select a device',
|
||||||
type: 'list',
|
type: 'list',
|
||||||
default: defaultUuid,
|
default: defaultUuid,
|
||||||
@ -381,7 +378,7 @@ export async function getOnlineTargetUuid(
|
|||||||
throw new ExpectedError('No accessible devices are online');
|
throw new ExpectedError('No accessible devices are online');
|
||||||
}
|
}
|
||||||
|
|
||||||
return await getForm().ask({
|
return await getCliForm().ask({
|
||||||
message: 'Select a device',
|
message: 'Select a device',
|
||||||
type: 'list',
|
type: 'list',
|
||||||
default: devices[0].uuid,
|
default: devices[0].uuid,
|
||||||
@ -416,7 +413,7 @@ export function selectFromList<T>(
|
|||||||
message: string,
|
message: string,
|
||||||
choices: Array<T & { name: string }>,
|
choices: Array<T & { name: string }>,
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
return getForm().ask<T>({
|
return getCliForm().ask<T>({
|
||||||
message,
|
message,
|
||||||
type: 'list',
|
type: 'list',
|
||||||
choices: _.map(choices, (s) => ({
|
choices: _.map(choices, (s) => ({
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
import type * as BalenaSdk from 'balena-sdk';
|
import type * as BalenaSdk from 'balena-sdk';
|
||||||
|
|
||||||
import { ExpectedError, printErrorMessage } from '../errors';
|
import { ExpectedError, printErrorMessage } from '../errors';
|
||||||
import { getVisuals, stripIndent } from './lazy';
|
import { getVisuals, stripIndent, getCliForm } from './lazy';
|
||||||
import Logger = require('./logger');
|
import Logger = require('./logger');
|
||||||
import { exec, execBuffered, getDeviceOsRelease } from './ssh';
|
import { exec, execBuffered, getDeviceOsRelease } from './ssh';
|
||||||
|
|
||||||
@ -206,7 +206,6 @@ async function getOrSelectApplication(
|
|||||||
appName?: string,
|
appName?: string,
|
||||||
): Promise<BalenaSdk.Application> {
|
): Promise<BalenaSdk.Application> {
|
||||||
const _ = await import('lodash');
|
const _ = await import('lodash');
|
||||||
const form = await import('resin-cli-form');
|
|
||||||
|
|
||||||
const allDeviceTypes = await sdk.models.config.getDeviceTypes();
|
const allDeviceTypes = await sdk.models.config.getDeviceTypes();
|
||||||
const deviceTypeManifest = _.find(allDeviceTypes, { slug: deviceType });
|
const deviceTypeManifest = _.find(allDeviceTypes, { slug: deviceType });
|
||||||
@ -227,12 +226,7 @@ async function getOrSelectApplication(
|
|||||||
.value();
|
.value();
|
||||||
|
|
||||||
if (!appName) {
|
if (!appName) {
|
||||||
return createOrSelectAppOrExit(
|
return createOrSelectAppOrExit(sdk, compatibleDeviceTypes, deviceType);
|
||||||
form,
|
|
||||||
sdk,
|
|
||||||
compatibleDeviceTypes,
|
|
||||||
deviceType,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const options: BalenaSdk.PineOptionsFor<BalenaSdk.Application> = {};
|
const options: BalenaSdk.PineOptionsFor<BalenaSdk.Application> = {};
|
||||||
@ -254,7 +248,7 @@ async function getOrSelectApplication(
|
|||||||
const applications = await sdk.models.application.getAll(options);
|
const applications = await sdk.models.application.getAll(options);
|
||||||
|
|
||||||
if (applications.length === 0) {
|
if (applications.length === 0) {
|
||||||
const shouldCreateApp = await form.ask({
|
const shouldCreateApp = await getCliForm().ask({
|
||||||
message:
|
message:
|
||||||
`No application found with name "${appName}".\n` +
|
`No application found with name "${appName}".\n` +
|
||||||
'Would you like to create it now?',
|
'Would you like to create it now?',
|
||||||
@ -288,7 +282,6 @@ async function getOrSelectApplication(
|
|||||||
// `getOrSelectApplication` above in order to satisfy some resin-lint v3
|
// `getOrSelectApplication` above in order to satisfy some resin-lint v3
|
||||||
// rules, but it looks like there's a fair amount of duplicate logic.
|
// rules, but it looks like there's a fair amount of duplicate logic.
|
||||||
async function createOrSelectAppOrExit(
|
async function createOrSelectAppOrExit(
|
||||||
form: any,
|
|
||||||
sdk: BalenaSdk.BalenaSDK,
|
sdk: BalenaSdk.BalenaSDK,
|
||||||
compatibleDeviceTypes: string[],
|
compatibleDeviceTypes: string[],
|
||||||
deviceType: string,
|
deviceType: string,
|
||||||
@ -301,7 +294,7 @@ async function createOrSelectAppOrExit(
|
|||||||
const applications = await sdk.models.application.getAll(options);
|
const applications = await sdk.models.application.getAll(options);
|
||||||
|
|
||||||
if (applications.length === 0) {
|
if (applications.length === 0) {
|
||||||
const shouldCreateApp = await form.ask({
|
const shouldCreateApp = await getCliForm().ask({
|
||||||
message:
|
message:
|
||||||
'You have no applications this device can join.\n' +
|
'You have no applications this device can join.\n' +
|
||||||
'Would you like to create one now?',
|
'Would you like to create one now?',
|
||||||
@ -322,7 +315,6 @@ async function createApplication(
|
|||||||
deviceType: string,
|
deviceType: string,
|
||||||
name?: string,
|
name?: string,
|
||||||
): Promise<BalenaSdk.Application> {
|
): Promise<BalenaSdk.Application> {
|
||||||
const form = await import('resin-cli-form');
|
|
||||||
const validation = await import('./validation');
|
const validation = await import('./validation');
|
||||||
|
|
||||||
let username = await sdk.auth.whoami();
|
let username = await sdk.auth.whoami();
|
||||||
@ -334,7 +326,7 @@ async function createApplication(
|
|||||||
const applicationName = await new Promise<string>(async (resolve, reject) => {
|
const applicationName = await new Promise<string>(async (resolve, reject) => {
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
const appName = await form.ask({
|
const appName = await getCliForm().ask({
|
||||||
message: 'Enter a name for your new application:',
|
message: 'Enter a name for your new application:',
|
||||||
type: 'input',
|
type: 'input',
|
||||||
default: name,
|
default: name,
|
||||||
@ -376,7 +368,6 @@ async function generateApplicationConfig(
|
|||||||
app: BalenaSdk.Application,
|
app: BalenaSdk.Application,
|
||||||
options: { version: string },
|
options: { version: string },
|
||||||
) {
|
) {
|
||||||
const form = await import('resin-cli-form');
|
|
||||||
const { generateApplicationConfig: configGen } = await import('./config');
|
const { generateApplicationConfig: configGen } = await import('./config');
|
||||||
|
|
||||||
const manifest = await sdk.models.device.getManifestBySlug(app.device_type);
|
const manifest = await sdk.models.device.getManifestBySlug(app.device_type);
|
||||||
@ -384,7 +375,7 @@ async function generateApplicationConfig(
|
|||||||
manifest.options &&
|
manifest.options &&
|
||||||
manifest.options.filter((opt) => opt.name !== 'network');
|
manifest.options.filter((opt) => opt.name !== 'network');
|
||||||
const values = {
|
const values = {
|
||||||
...(opts ? await form.run(opts) : {}),
|
...(opts ? await getCliForm().run(opts) : {}),
|
||||||
...options,
|
...options,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,6 +2,6 @@
|
|||||||
"extends": "./node_modules/@balena/lint/config/tslint-prettier.json",
|
"extends": "./node_modules/@balena/lint/config/tslint-prettier.json",
|
||||||
"rules": {
|
"rules": {
|
||||||
"ignoreDefinitionFiles": false,
|
"ignoreDefinitionFiles": false,
|
||||||
"import-blacklist": [true, "resin-cli-visuals", "chalk", "common-tags"]
|
"import-blacklist": [true, "resin-cli-visuals", "chalk", "common-tags", "resin-cli-form"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
22
typings/resin-cli-form/index.d.ts
vendored
22
typings/resin-cli-form/index.d.ts
vendored
@ -18,13 +18,13 @@
|
|||||||
declare module 'resin-cli-form' {
|
declare module 'resin-cli-form' {
|
||||||
import Bluebird = require('bluebird');
|
import Bluebird = require('bluebird');
|
||||||
|
|
||||||
type TypeOrPromiseLike<T> = T | PromiseLike<T>;
|
export type TypeOrPromiseLike<T> = T | PromiseLike<T>;
|
||||||
|
|
||||||
type Validate = (
|
export type Validate = (
|
||||||
input: any,
|
input: any,
|
||||||
) => TypeOrPromiseLike<boolean | string | undefined>;
|
) => TypeOrPromiseLike<boolean | string | undefined>;
|
||||||
|
|
||||||
interface AskOptions<T> {
|
export interface AskOptions<T> {
|
||||||
message: string;
|
message: string;
|
||||||
type?: string;
|
type?: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
@ -36,20 +36,16 @@ declare module 'resin-cli-form' {
|
|||||||
validate?: Validate;
|
validate?: Validate;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RunQuestion {
|
export interface RunQuestion {
|
||||||
message: string;
|
message: string;
|
||||||
name: string;
|
name: string;
|
||||||
type?: string;
|
type?: string;
|
||||||
validate?: Validate;
|
validate?: Validate;
|
||||||
}
|
}
|
||||||
|
|
||||||
const form: {
|
export const ask: <T = string>(options: AskOptions<T>) => Bluebird<T>;
|
||||||
ask: <T = string>(options: AskOptions<T>) => Bluebird<T>;
|
export const run: <T = any>(
|
||||||
run: <T = any>(
|
questions?: RunQuestion[],
|
||||||
questions?: RunQuestion[],
|
extraOptions?: { override?: object },
|
||||||
extraOptions?: { override?: object },
|
) => Bluebird<T>;
|
||||||
) => Bluebird<T>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export = form;
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user