WIP module node16 for ESM

change-type: patch
This commit is contained in:
Otavio Jacobi 2024-07-12 22:25:40 -03:00
parent 003d537433
commit 5e5b3a2635
100 changed files with 290 additions and 264 deletions

View File

@ -18,15 +18,15 @@
import type { JsonVersions } from '../lib/commands/version/index'; import type { JsonVersions } from '../lib/commands/version/index';
import { run as oclifRun } from '@oclif/core'; import { run as oclifRun } from '@oclif/core';
import * as archiver from 'archiver'; import archiver from 'archiver';
import * as Bluebird from 'bluebird'; import Bluebird from 'bluebird';
import { exec, execFile } from 'child_process'; import { exec, execFile } from 'child_process';
import * as filehound from 'filehound'; import * as filehound from 'filehound';
import type { Stats } from 'fs'; import type { Stats } from 'fs';
import * as fs from 'fs-extra'; import * as fs from 'fs-extra';
import * as klaw from 'klaw'; import klaw from 'klaw';
import * as path from 'path'; import * as path from 'path';
import * as rimraf from 'rimraf'; import rimraf from 'rimraf';
import * as semver from 'semver'; import * as semver from 'semver';
import { promisify } from 'util'; import { promisify } from 'util';
import { notarize } from '@electron/notarize'; import { notarize } from '@electron/notarize';
@ -87,7 +87,7 @@ export const finalReleaseAssets: { [platform: string]: string[] } = {
* Throw an error if the diff is not empty. * Throw an error if the diff is not empty.
*/ */
async function diffPkgOutput(pkgOut: string) { async function diffPkgOutput(pkgOut: string) {
const { monochrome } = await import('../tests/helpers'); const { monochrome } = await import('../tests/helpers.js');
const relSavedPath = path.join( const relSavedPath = path.join(
'tests', 'tests',
'test-data', 'test-data',
@ -263,7 +263,7 @@ async function testPkg() {
'version', 'version',
'-j', '-j',
]); ]);
const { filterCliOutputForTests } = await import('../tests/helpers'); const { filterCliOutputForTests } = await import('../tests/helpers.js');
const filtered = filterCliOutputForTests({ const filtered = filterCliOutputForTests({
err: stderr.split(/\r?\n/), err: stderr.split(/\r?\n/),
out: stdout.split(/\r?\n/), out: stdout.split(/\r?\n/),

View File

@ -97,7 +97,7 @@ export function loadPackageJson() {
* @returns The program's full path, e.g. 'C:\WINDOWS\System32\OpenSSH\ssh.EXE' * @returns The program's full path, e.g. 'C:\WINDOWS\System32\OpenSSH\ssh.EXE'
*/ */
export async function which(program: string): Promise<string> { export async function which(program: string): Promise<string> {
const whichMod = await import('which'); const { default: whichMod } = await import('which');
let programPath: string; let programPath: string;
try { try {
programPath = await whichMod(program); programPath = await whichMod(program);

View File

@ -31,7 +31,7 @@ import { run as mainRun, settings } from '@oclif/core';
* @see https://docs.sentry.io/error-reporting/quickstart/?platform=node * @see https://docs.sentry.io/error-reporting/quickstart/?platform=node
*/ */
export const setupSentry = onceAsync(async () => { export const setupSentry = onceAsync(async () => {
const config = await import('./config'); const config = await import('./config.js');
const Sentry = await import('@sentry/node'); const Sentry = await import('@sentry/node');
Sentry.init({ Sentry.init({
autoSessionTracking: false, autoSessionTracking: false,
@ -51,7 +51,7 @@ export const setupSentry = onceAsync(async () => {
async function checkNodeVersion() { async function checkNodeVersion() {
const validNodeVersions = packageJSON.engines.node; const validNodeVersions = packageJSON.engines.node;
if (!(await import('semver')).satisfies(process.version, validNodeVersions)) { if (!(await import('semver')).satisfies(process.version, validNodeVersions)) {
const { getNodeEngineVersionWarn } = await import('./utils/messages'); const { getNodeEngineVersionWarn } = await import('./utils/messages.js');
console.warn(getNodeEngineVersionWarn(process.version, validNodeVersions)); console.warn(getNodeEngineVersionWarn(process.version, validNodeVersions));
} }
} }
@ -89,13 +89,13 @@ async function init() {
const settings = new CliSettings(); const settings = new CliSettings();
// Proxy setup should be done early on, before loading balena-sdk // Proxy setup should be done early on, before loading balena-sdk
await (await import('./utils/proxy')).setupGlobalHttpProxy(settings); await (await import('./utils/proxy.js')).setupGlobalHttpProxy(settings);
setupBalenaSdkSharedOptions(settings); setupBalenaSdkSharedOptions(settings);
// check for CLI updates once a day // check for CLI updates once a day
if (!process.env.BALENARC_OFFLINE_MODE) { if (!process.env.BALENARC_OFFLINE_MODE) {
(await import('./utils/update')).notify(); (await import('./utils/update.js')).notify();
} }
} }
@ -106,7 +106,7 @@ async function oclifRun(command: string[], options: AppOptions) {
if (unsupportedFlag || process.env.BALENARC_UNSUPPORTED) { if (unsupportedFlag || process.env.BALENARC_UNSUPPORTED) {
deprecationPromise = Promise.resolve(); deprecationPromise = Promise.resolve();
} else { } else {
const { DeprecationChecker } = await import('./deprecation'); const { DeprecationChecker } = await import('./deprecation.js');
const deprecationChecker = new DeprecationChecker(packageJSON.version); const deprecationChecker = new DeprecationChecker(packageJSON.version);
// warnAndAbortIfDeprecated uses previously cached data only // warnAndAbortIfDeprecated uses previously cached data only
await deprecationChecker.warnAndAbortIfDeprecated(); await deprecationChecker.warnAndAbortIfDeprecated();
@ -137,7 +137,8 @@ async function oclifRun(command: string[], options: AppOptions) {
} }
} }
if (shouldFlush) { if (shouldFlush) {
await import('@oclif/core/flush'); const { default: flush } = await import('@oclif/core/flush.js');
await flush();
} }
// TODO: figure out why we need to call fast-boot stop() here, in // TODO: figure out why we need to call fast-boot stop() here, in
// addition to calling it in the main `run()` function in this file. // addition to calling it in the main `run()` function in this file.
@ -148,11 +149,11 @@ async function oclifRun(command: string[], options: AppOptions) {
// the try/catch block above, execution does not get past the // the try/catch block above, execution does not get past the
// Promise.all() call below, but I don't understand why. // Promise.all() call below, but I don't understand why.
if (isEEXIT) { if (isEEXIT) {
(await import('./fast-boot')).stop(); (await import('./fast-boot.js')).stop();
} }
})(!options.noFlush); })(!options.noFlush);
const { trackPromise } = await import('./hooks/prerun/track'); const { trackPromise } = await import('./hooks/prerun/track.js');
await Promise.all([trackPromise, deprecationPromise, runPromise]); await Promise.all([trackPromise, deprecationPromise, runPromise]);
} }
@ -161,7 +162,7 @@ async function oclifRun(command: string[], options: AppOptions) {
export async function run(cliArgs = process.argv, options: AppOptions) { export async function run(cliArgs = process.argv, options: AppOptions) {
try { try {
const { setOfflineModeEnvVars, normalizeEnvVars, pkgExec } = await import( const { setOfflineModeEnvVars, normalizeEnvVars, pkgExec } = await import(
'./utils/bootstrap' './utils/bootstrap.js'
); );
setOfflineModeEnvVars(); setOfflineModeEnvVars();
normalizeEnvVars(); normalizeEnvVars();
@ -180,10 +181,10 @@ export async function run(cliArgs = process.argv, options: AppOptions) {
const args = await preparseArgs(cliArgs); const args = await preparseArgs(cliArgs);
await oclifRun(args, options); await oclifRun(args, options);
} catch (err) { } catch (err) {
await (await import('./errors')).handleError(err); await (await import('./errors.js')).handleError(err);
} finally { } finally {
try { try {
(await import('./fast-boot')).stop(); (await import('./fast-boot.js')).stop();
} catch (e) { } catch (e) {
if (process.env.DEBUG) { if (process.env.DEBUG) {
console.error(`[debug] Stopping fast-boot: ${e}`); console.error(`[debug] Stopping fast-boot: ${e}`);

View File

@ -42,7 +42,7 @@ import { LoginServer } from './server';
* console.log("My session token is: #{sessionToken}") * console.log("My session token is: #{sessionToken}")
*/ */
export async function login({ host = '127.0.0.1', port = 0 }) { export async function login({ host = '127.0.0.1', port = 0 }) {
const utils = await import('./utils'); const utils = await import('./utils.js');
const loginServer = new LoginServer(); const loginServer = new LoginServer();
const { const {
@ -55,7 +55,7 @@ export async function login({ host = '127.0.0.1', port = 0 }) {
const loginUrl = await utils.getDashboardLoginURL(callbackUrl); const loginUrl = await utils.getDashboardLoginURL(callbackUrl);
console.info(`Opening web browser for URL:\n${loginUrl}`); console.info(`Opening web browser for URL:\n${loginUrl}`);
const open = await import('open'); const { default: open } = await import('open');
await open(loginUrl, { wait: false }); await open(loginUrl, { wait: false });
const balena = getBalenaSdk(); const balena = getBalenaSdk();

View File

@ -16,7 +16,7 @@ limitations under the License.
import * as bodyParser from 'body-parser'; import * as bodyParser from 'body-parser';
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
import * as express from 'express'; import express from 'express';
import type { Socket } from 'net'; import type { Socket } from 'net';
import * as path from 'path'; import * as path from 'path';

View File

@ -71,7 +71,7 @@ export default abstract class BalenaCommand extends Command {
* - other code needs to execute before check * - other code needs to execute before check
*/ */
protected static async checkElevatedPrivileges() { protected static async checkElevatedPrivileges() {
const isElevated = await (await import('is-elevated'))(); const isElevated = await (await import('is-elevated')).default();
if (!isElevated) { if (!isElevated) {
throw new InsufficientPrivilegesError( throw new InsufficientPrivilegesError(
'You need root/admin privileges to run this command', 'You need root/admin privileges to run this command',
@ -94,7 +94,7 @@ export default abstract class BalenaCommand extends Command {
* @throws {NotLoggedInError} * @throws {NotLoggedInError}
*/ */
public static async checkLoggedIn() { public static async checkLoggedIn() {
await (await import('./utils/patterns')).checkLoggedIn(); await (await import('./utils/patterns.js')).checkLoggedIn();
} }
/** /**
@ -139,14 +139,16 @@ export default abstract class BalenaCommand extends Command {
* values from stdin based in configuration, minimising command implementation. * values from stdin based in configuration, minimising command implementation.
*/ */
protected async getStdin() { protected async getStdin() {
this.stdin = await (await import('get-stdin'))(); const { default: getStdin } = await import('get-stdin');
this.stdin = await getStdin();
} }
/** /**
* Get a logger instance. * Get a logger instance.
*/ */
protected static async getLogger() { protected static async getLogger() {
return (await import('./utils/logger')).getLogger(); const { default: logger } = await import('./utils/logger.js');
return logger.getLogger();
} }
protected async init() { protected async init() {

View File

@ -46,7 +46,7 @@ export default class ApiKeysCmd extends Command {
public async run() { public async run() {
const { flags: options } = await this.parse(ApiKeysCmd); const { flags: options } = await this.parse(ApiKeysCmd);
const { getApplication } = await import('../../utils/sdk'); const { getApplication } = await import('../../utils/sdk.js');
const actorId = options.fleet const actorId = options.fleet
? ( ? (
await getApplication(getBalenaSdk(), options.fleet, { await getApplication(getBalenaSdk(), options.fleet, {

View File

@ -77,7 +77,7 @@ export default class AppCreateCmd extends Command {
const { args: params, flags: options } = await this.parse(AppCreateCmd); const { args: params, flags: options } = await this.parse(AppCreateCmd);
await ( await (
await import('../../utils/application-create') await import('../../utils/application-create.js')
).applicationCreateBase('app', options, params); ).applicationCreateBase('app', options, params);
} }
} }

View File

@ -77,7 +77,7 @@ export default class BlockCreateCmd extends Command {
const { args: params, flags: options } = await this.parse(BlockCreateCmd); const { args: params, flags: options } = await this.parse(BlockCreateCmd);
await ( await (
await import('../../utils/application-create') await import('../../utils/application-create.js')
).applicationCreateBase('block', options, params); ).applicationCreateBase('block', options, params);
} }
} }

View File

@ -36,6 +36,7 @@ import type { ComposeCliFlags, ComposeOpts } from '../../utils/compose-types';
import { buildProject, composeCliFlags } from '../../utils/compose_ts'; import { buildProject, composeCliFlags } from '../../utils/compose_ts';
import type { BuildOpts, DockerCliFlags } from '../../utils/docker'; import type { BuildOpts, DockerCliFlags } from '../../utils/docker';
import { dockerCliFlags } from '../../utils/docker'; import { dockerCliFlags } from '../../utils/docker';
import type Dockerode from 'dockerode';
// TODO: For this special one we can't use Interfaces.InferredFlags/InferredArgs // TODO: For this special one we can't use Interfaces.InferredFlags/InferredArgs
// because of the 'registry-secrets' type which is defined in the actual code // because of the 'registry-secrets' type which is defined in the actual code
@ -157,14 +158,16 @@ ${dockerignoreHelp}
(opts.fleet == null && (opts.arch == null || opts.deviceType == null)) || (opts.fleet == null && (opts.arch == null || opts.deviceType == null)) ||
(opts.fleet != null && (opts.arch != null || opts.deviceType != null)) (opts.fleet != null && (opts.arch != null || opts.deviceType != null))
) { ) {
const { ExpectedError } = await import('../../errors'); const { ExpectedError } = await import('../../errors.js');
throw new ExpectedError( throw new ExpectedError(
'You must specify either a fleet (-f), or the device type (-d) and optionally the architecture (-A)', 'You must specify either a fleet (-f), or the device type (-d) and optionally the architecture (-A)',
); );
} }
// Validate project directory // Validate project directory
const { validateProjectDirectory } = await import('../../utils/compose_ts'); const { validateProjectDirectory } = await import(
'../../utils/compose_ts.js'
);
const { dockerfilePath, registrySecrets } = await validateProjectDirectory( const { dockerfilePath, registrySecrets } = await validateProjectDirectory(
sdk, sdk,
{ {
@ -197,7 +200,7 @@ ${dockerignoreHelp}
)) as PineTypedResult<DeviceType, typeof deviceTypeOpts> )) as PineTypedResult<DeviceType, typeof deviceTypeOpts>
).is_of__cpu_architecture[0].slug; ).is_of__cpu_architecture[0].slug;
} catch (err) { } catch (err) {
const { ExpectedError } = await import('../../errors'); const { ExpectedError } = await import('../../errors.js');
if (err instanceof sdk.errors.BalenaInvalidDeviceType) { if (err instanceof sdk.errors.BalenaInvalidDeviceType) {
let message = err.message; let message = err.message;
if (!(await sdk.auth.isLoggedIn())) { if (!(await sdk.auth.isLoggedIn())) {
@ -214,7 +217,7 @@ ${dockerignoreHelp}
protected async getAppAndResolveArch(opts: FlagsDef) { protected async getAppAndResolveArch(opts: FlagsDef) {
if (opts.fleet) { if (opts.fleet) {
const { getAppWithArch } = await import('../../utils/helpers'); const { getAppWithArch } = await import('../../utils/helpers.js');
const app = await getAppWithArch(opts.fleet); const app = await getAppWithArch(opts.fleet);
opts.arch = app.arch; opts.arch = app.arch;
opts.deviceType = app.is_for__device_type[0].slug; opts.deviceType = app.is_for__device_type[0].slug;
@ -222,8 +225,14 @@ ${dockerignoreHelp}
} }
} }
protected async prepareBuild(options: FlagsDef) { protected async prepareBuild(options: FlagsDef): Promise<{
const { getDocker, generateBuildOpts } = await import('../../utils/docker'); docker: Dockerode;
buildOpts: BuildOpts;
composeOpts: ComposeOpts;
}> {
const { getDocker, generateBuildOpts } = await import(
'../../utils/docker.js'
);
const [docker, buildOpts, composeOpts] = await Promise.all([ const [docker, buildOpts, composeOpts] = await Promise.all([
getDocker(options), getDocker(options),
generateBuildOpts(options), generateBuildOpts(options),
@ -261,7 +270,7 @@ ${dockerignoreHelp}
buildOpts: BuildOpts; buildOpts: BuildOpts;
}, },
) { ) {
const { loadProject } = await import('../../utils/compose_ts'); const { loadProject } = await import('../../utils/compose_ts.js');
const project = await loadProject( const project = await loadProject(
logger, logger,

View File

@ -126,7 +126,7 @@ export default class ConfigGenerateCmd extends Command {
public static authenticated = true; public static authenticated = true;
public async getApplication(balena: BalenaSDK, fleet: string) { public async getApplication(balena: BalenaSDK, fleet: string) {
const { getApplication } = await import('../../utils/sdk'); const { getApplication } = await import('../../utils/sdk.js');
return await getApplication(balena, fleet, { return await getApplication(balena, fleet, {
$select: 'slug', $select: 'slug',
$expand: { $expand: {
@ -152,7 +152,7 @@ export default class ConfigGenerateCmd extends Command {
$expand: { is_of__device_type: { $select: 'slug' } }, $expand: { is_of__device_type: { $select: 'slug' } },
}); });
if (!rawDevice.belongs_to__application) { if (!rawDevice.belongs_to__application) {
const { ExpectedError } = await import('../../errors'); const { ExpectedError } = await import('../../errors.js');
throw new ExpectedError(stripIndent` throw new ExpectedError(stripIndent`
Device ${options.device} does not appear to belong to an accessible fleet. Device ${options.device} does not appear to belong to an accessible fleet.
Try with a different device, or use '--fleet' instead of '--device'.`); Try with a different device, or use '--fleet' instead of '--device'.`);
@ -171,14 +171,14 @@ export default class ConfigGenerateCmd extends Command {
// Check compatibility if application and deviceType provided // Check compatibility if application and deviceType provided
if (options.fleet && options.deviceType) { if (options.fleet && options.deviceType) {
const helpers = await import('../../utils/helpers'); const helpers = await import('../../utils/helpers.js');
if ( if (
!(await helpers.areDeviceTypesCompatible( !(await helpers.areDeviceTypesCompatible(
resourceDeviceType, resourceDeviceType,
deviceType, deviceType,
)) ))
) { ) {
const { ExpectedError } = await import('../../errors'); const { ExpectedError } = await import('../../errors.js');
throw new ExpectedError( throw new ExpectedError(
`Device type ${options.deviceType} is incompatible with fleet ${options.fleet}`, `Device type ${options.deviceType} is incompatible with fleet ${options.fleet}`,
); );
@ -189,7 +189,7 @@ export default class ConfigGenerateCmd extends Command {
await balena.models.config.getDeviceTypeManifestBySlug(deviceType); await balena.models.config.getDeviceTypeManifestBySlug(deviceType);
const { validateSecureBootOptionAndWarn } = await import( const { validateSecureBootOptionAndWarn } = await import(
'../../utils/config' '../../utils/config.js'
); );
await validateSecureBootOptionAndWarn( await validateSecureBootOptionAndWarn(
options.secureBoot, options.secureBoot,
@ -211,7 +211,7 @@ export default class ConfigGenerateCmd extends Command {
// Generate config // Generate config
const { generateDeviceConfig, generateApplicationConfig } = await import( const { generateDeviceConfig, generateApplicationConfig } = await import(
'../../utils/config' '../../utils/config.js'
); );
let config; let config;
@ -250,7 +250,7 @@ export default class ConfigGenerateCmd extends Command {
protected async validateOptions( protected async validateOptions(
options: Interfaces.InferredFlags<typeof ConfigGenerateCmd.flags>, options: Interfaces.InferredFlags<typeof ConfigGenerateCmd.flags>,
) { ) {
const { ExpectedError } = await import('../../errors'); const { ExpectedError } = await import('../../errors.js');
if (options.device == null && options.fleet == null) { if (options.device == null && options.fleet == null) {
throw new ExpectedError(this.missingDeviceOrAppMessage); throw new ExpectedError(this.missingDeviceOrAppMessage);
@ -259,9 +259,9 @@ export default class ConfigGenerateCmd extends Command {
if (!options.fleet && options.deviceType) { if (!options.fleet && options.deviceType) {
throw new ExpectedError(this.deviceTypeNotAllowedMessage); throw new ExpectedError(this.deviceTypeNotAllowedMessage);
} }
const { normalizeOsVersion } = await import('../../utils/normalization'); const { normalizeOsVersion } = await import('../../utils/normalization.js');
options.version = normalizeOsVersion(options.version); options.version = normalizeOsVersion(options.version);
const { validateDevOptionAndWarn } = await import('../../utils/config'); const { validateDevOptionAndWarn } = await import('../../utils/config.js');
await validateDevOptionAndWarn(options.dev, options.version); await validateDevOptionAndWarn(options.dev, options.version);
} }
} }

View File

@ -56,7 +56,7 @@ export default class ConfigInjectCmd extends Command {
public async run() { public async run() {
const { args: params, flags: options } = await this.parse(ConfigInjectCmd); const { args: params, flags: options } = await this.parse(ConfigInjectCmd);
const { safeUmount } = await import('../../utils/umount'); const { safeUmount } = await import('../../utils/umount.js');
const drive = const drive =
options.drive || (await getVisuals().drive('Select the device/OS drive')); options.drive || (await getVisuals().drive('Select the device/OS drive'));

View File

@ -50,7 +50,7 @@ export default class ConfigReadCmd extends Command {
public async run() { public async run() {
const { flags: options } = await this.parse(ConfigReadCmd); const { flags: options } = await this.parse(ConfigReadCmd);
const { safeUmount } = await import('../../utils/umount'); const { safeUmount } = await import('../../utils/umount.js');
const drive = const drive =
options.drive || (await getVisuals().drive('Select the device drive')); options.drive || (await getVisuals().drive('Select the device drive'));

View File

@ -59,7 +59,7 @@ export default class ConfigReconfigureCmd extends Command {
public async run() { public async run() {
const { flags: options } = await this.parse(ConfigReconfigureCmd); const { flags: options } = await this.parse(ConfigReconfigureCmd);
const { safeUmount } = await import('../../utils/umount'); const { safeUmount } = await import('../../utils/umount.js');
const drive = const drive =
options.drive || (await getVisuals().drive('Select the device drive')); options.drive || (await getVisuals().drive('Select the device drive'));
@ -70,7 +70,7 @@ export default class ConfigReconfigureCmd extends Command {
await safeUmount(drive); await safeUmount(drive);
if (!uuid) { if (!uuid) {
const { ExpectedError } = await import('../../errors'); const { ExpectedError } = await import('../../errors.js');
throw new ExpectedError( throw new ExpectedError(
`Error: UUID not found in 'config.json' file for '${drive}'`, `Error: UUID not found in 'config.json' file for '${drive}'`,
); );
@ -84,7 +84,7 @@ export default class ConfigReconfigureCmd extends Command {
configureCommand.push('--advanced'); configureCommand.push('--advanced');
} }
const { runCommand } = await import('../../utils/helpers'); const { runCommand } = await import('../../utils/helpers.js');
await runCommand(configureCommand); await runCommand(configureCommand);
console.info('Done'); console.info('Done');

View File

@ -61,7 +61,7 @@ export default class ConfigWriteCmd extends Command {
public async run() { public async run() {
const { args: params, flags: options } = await this.parse(ConfigWriteCmd); const { args: params, flags: options } = await this.parse(ConfigWriteCmd);
const { denyMount, safeUmount } = await import('../../utils/umount'); const { denyMount, safeUmount } = await import('../../utils/umount.js');
const drive = const drive =
options.drive || (await getVisuals().drive('Select the device drive')); options.drive || (await getVisuals().drive('Select the device drive'));

View File

@ -175,7 +175,7 @@ ${dockerignoreHelp}
const sdk = getBalenaSdk(); const sdk = getBalenaSdk();
const { getRegistrySecrets, validateProjectDirectory } = await import( const { getRegistrySecrets, validateProjectDirectory } = await import(
'../../utils/compose_ts' '../../utils/compose_ts.js'
); );
const { releaseTagKeys, releaseTagValues } = parseReleaseTagKeysAndValues( const { releaseTagKeys, releaseTagValues } = parseReleaseTagKeysAndValues(
@ -199,10 +199,10 @@ ${dockerignoreHelp}
(options as FlagsDef)['registry-secrets'] = registrySecrets; (options as FlagsDef)['registry-secrets'] = registrySecrets;
} }
const helpers = await import('../../utils/helpers'); const helpers = await import('../../utils/helpers.js');
const app = await helpers.getAppWithArch(fleet); const app = await helpers.getAppWithArch(fleet);
const dockerUtils = await import('../../utils/docker'); const dockerUtils = await import('../../utils/docker.js');
const [docker, buildOpts, composeOpts] = await Promise.all([ const [docker, buildOpts, composeOpts] = await Promise.all([
dockerUtils.getDocker(options), dockerUtils.getDocker(options),
dockerUtils.generateBuildOpts(options as FlagsDef), dockerUtils.generateBuildOpts(options as FlagsDef),
@ -250,7 +250,7 @@ ${dockerignoreHelp}
const doodles = await import('resin-doodles'); const doodles = await import('resin-doodles');
const sdk = getBalenaSdk(); const sdk = getBalenaSdk();
const { deployProject: $deployProject, loadProject } = await import( const { deployProject: $deployProject, loadProject } = await import(
'../../utils/compose_ts' '../../utils/compose_ts.js'
); );
const appType = opts.app.application_type[0]; const appType = opts.app.application_type[0];

View File

@ -55,7 +55,7 @@ export default class DeviceDeactivateCmd extends Command {
await this.parse(DeviceDeactivateCmd); await this.parse(DeviceDeactivateCmd);
const balena = getBalenaSdk(); const balena = getBalenaSdk();
const patterns = await import('../../utils/patterns'); const patterns = await import('../../utils/patterns.js');
const uuid = params.uuid; const uuid = params.uuid;
const deactivationWarning = ` const deactivationWarning = `

View File

@ -122,7 +122,7 @@ export default class DeviceCmd extends Command {
)) as ExtendedDevice; )) as ExtendedDevice;
if (options.view) { if (options.view) {
const open = await import('open'); const { default: open } = await import('open');
const dashboardUrl = balena.models.device.getDashboardUrl(device.uuid); const dashboardUrl = balena.models.device.getDashboardUrl(device.uuid);
await open(dashboardUrl, { wait: false }); await open(dashboardUrl, { wait: false });
return; return;

View File

@ -113,12 +113,12 @@ export default class DeviceInitCmd extends Command {
// Imports // Imports
const { promisify } = await import('util'); const { promisify } = await import('util');
const rimraf = promisify(await import('rimraf')); const rimraf = promisify((await import('rimraf')).default);
const tmp = await import('tmp'); const tmp = await import('tmp');
const tmpNameAsync = promisify(tmp.tmpName); const tmpNameAsync = promisify(tmp.tmpName);
tmp.setGracefulCleanup(); tmp.setGracefulCleanup();
const { downloadOSImage } = await import('../../utils/cloud'); const { downloadOSImage } = await import('../../utils/cloud.js');
const { getApplication } = await import('../../utils/sdk'); const { getApplication } = await import('../../utils/sdk.js');
const logger = await Command.getLogger(); const logger = await Command.getLogger();
const balena = getBalenaSdk(); const balena = getBalenaSdk();
@ -133,7 +133,7 @@ export default class DeviceInitCmd extends Command {
}, },
}, },
}) })
: await (await import('../../utils/patterns')).selectApplication(); : await (await import('../../utils/patterns.js')).selectApplication();
// Register new device // Register new device
const deviceUuid = balena.models.device.generateUniqueKey(); const deviceUuid = balena.models.device.generateUniqueKey();

View File

@ -101,7 +101,7 @@ export default class DeviceMoveCmd extends Command {
const devices = await this.getDevices(balena, deviceUuids); const devices = await this.getDevices(balena, deviceUuids);
// Disambiguate application // Disambiguate application
const { getApplication } = await import('../../utils/sdk'); const { getApplication } = await import('../../utils/sdk.js');
// Get destination application // Get destination application
const application = options.fleet const application = options.fleet
@ -151,7 +151,7 @@ export default class DeviceMoveCmd extends Command {
}) })
.map((deviceType) => deviceType.id); .map((deviceType) => deviceType.id);
const patterns = await import('../../utils/patterns'); const patterns = await import('../../utils/patterns.js');
try { try {
const application = await patterns.selectApplication( const application = await patterns.selectApplication(
{ {

View File

@ -122,7 +122,9 @@ export default class DeviceOsUpdateCmd extends Command {
// Get target OS version // Get target OS version
let targetOsVersion = options.version; let targetOsVersion = options.version;
if (targetOsVersion != null) { if (targetOsVersion != null) {
const { normalizeOsVersion } = await import('../../utils/normalization'); const { normalizeOsVersion } = await import(
'../../utils/normalization.js'
);
targetOsVersion = normalizeOsVersion(targetOsVersion); targetOsVersion = normalizeOsVersion(targetOsVersion);
if (!hupVersionInfo.versions.includes(targetOsVersion)) { if (!hupVersionInfo.versions.includes(targetOsVersion)) {
throw new ExpectedError( throw new ExpectedError(
@ -143,7 +145,7 @@ export default class DeviceOsUpdateCmd extends Command {
}); });
} }
const patterns = await import('../../utils/patterns'); const patterns = await import('../../utils/patterns.js');
// Confirm and start update // Confirm and start update
await patterns.confirm( await patterns.confirm(
options.yes || false, options.yes || false,

View File

@ -64,7 +64,7 @@ export default class DeviceRegisterCmd extends Command {
const { args: params, flags: options } = const { args: params, flags: options } =
await this.parse(DeviceRegisterCmd); await this.parse(DeviceRegisterCmd);
const { getApplication } = await import('../../utils/sdk'); const { getApplication } = await import('../../utils/sdk.js');
const balena = getBalenaSdk(); const balena = getBalenaSdk();

View File

@ -94,8 +94,8 @@ export default class DeviceRestartCmd extends Command {
deviceUuid: string, deviceUuid: string,
serviceNames: string[], serviceNames: string[],
) { ) {
const { ExpectedError, instanceOf } = await import('../../errors'); const { ExpectedError, instanceOf } = await import('../../errors.js');
const { getExpandedProp } = await import('../../utils/pine'); const { getExpandedProp } = await import('../../utils/pine.js');
// Get device // Get device
let device: DeviceWithServiceDetails<CurrentServiceWithCommit>; let device: DeviceWithServiceDetails<CurrentServiceWithCommit>;
@ -161,7 +161,7 @@ export default class DeviceRestartCmd extends Command {
// Note: device.restartApplication throws `BalenaDeviceNotFound: Device not found` if device not online. // Note: device.restartApplication throws `BalenaDeviceNotFound: Device not found` if device not online.
// Need to use device.get first to distinguish between non-existant and offline devices. // Need to use device.get first to distinguish between non-existant and offline devices.
// Remove this workaround when SDK issue resolved: https://github.com/balena-io/balena-sdk/issues/649 // Remove this workaround when SDK issue resolved: https://github.com/balena-io/balena-sdk/issues/649
const { instanceOf, ExpectedError } = await import('../../errors'); const { instanceOf, ExpectedError } = await import('../../errors.js');
try { try {
const device = await balena.models.device.get(deviceUuid); const device = await balena.models.device.get(deviceUuid);
if (!device.is_online) { if (!device.is_online) {

View File

@ -56,7 +56,7 @@ export default class DeviceRmCmd extends Command {
const { args: params, flags: options } = await this.parse(DeviceRmCmd); const { args: params, flags: options } = await this.parse(DeviceRmCmd);
const balena = getBalenaSdk(); const balena = getBalenaSdk();
const patterns = await import('../../utils/patterns'); const patterns = await import('../../utils/patterns.js');
// Confirm // Confirm
const uuids = params.uuid.split(','); const uuids = params.uuid.split(',');

View File

@ -78,8 +78,8 @@ export default class DeviceStartServiceCmd extends Command {
deviceUuid: string, deviceUuid: string,
serviceNames: string[], serviceNames: string[],
) { ) {
const { ExpectedError } = await import('../../errors'); const { ExpectedError } = await import('../../errors.js');
const { getExpandedProp } = await import('../../utils/pine'); const { getExpandedProp } = await import('../../utils/pine.js');
// Get device // Get device
const device = await balena.models.device.getWithServiceDetails( const device = await balena.models.device.getWithServiceDetails(

View File

@ -78,8 +78,8 @@ export default class DeviceStopServiceCmd extends Command {
deviceUuid: string, deviceUuid: string,
serviceNames: string[], serviceNames: string[],
) { ) {
const { ExpectedError } = await import('../../errors'); const { ExpectedError } = await import('../../errors.js');
const { getExpandedProp } = await import('../../utils/pine'); const { getExpandedProp } = await import('../../utils/pine.js');
// Get device // Get device
const device = await balena.models.device.getWithServiceDetails( const device = await balena.models.device.getWithServiceDetails(

View File

@ -78,7 +78,7 @@ export default class DevicesCmd extends Command {
const devices = ( const devices = (
await (async () => { await (async () => {
if (options.fleet != null) { if (options.fleet != null) {
const { getApplication } = await import('../../utils/sdk'); const { getApplication } = await import('../../utils/sdk.js');
const application = await getApplication(balena, options.fleet, { const application = await getApplication(balena, options.fleet, {
$select: 'slug', $select: 'slug',
$expand: { $expand: {
@ -115,7 +115,7 @@ export default class DevicesCmd extends Command {
]; ];
if (options.json) { if (options.json) {
const { pickAndRename } = await import('../../utils/helpers'); const { pickAndRename } = await import('../../utils/helpers.js');
const mapped = devices.map((device) => pickAndRename(device, fields)); const mapped = devices.map((device) => pickAndRename(device, fields));
console.log(JSON.stringify(mapped, null, 4)); console.log(JSON.stringify(mapped, null, 4));
} else { } else {

View File

@ -185,7 +185,7 @@ async function resolveFleetSlugs(
fleetOption: string, fleetOption: string,
) { ) {
const fleetSlugs: string[] = []; const fleetSlugs: string[] = [];
const { getFleetSlug } = await import('../../utils/sdk'); const { getFleetSlug } = await import('../../utils/sdk.js');
for (const appNameOrSlug of fleetOption.split(',')) { for (const appNameOrSlug of fleetOption.split(',')) {
try { try {
fleetSlugs.push(await getFleetSlug(balena, appNameOrSlug)); fleetSlugs.push(await getFleetSlug(balena, appNameOrSlug));
@ -222,7 +222,7 @@ async function setServiceVars(
} }
} }
} else if (options.device) { } else if (options.device) {
const { getDeviceAndAppFromUUID } = await import('../../utils/cloud'); const { getDeviceAndAppFromUUID } = await import('../../utils/cloud.js');
for (const uuid of options.device.split(',')) { for (const uuid of options.device.split(',')) {
let device; let device;
let app; let app;

View File

@ -71,7 +71,7 @@ export default class EnvRmCmd extends Command {
await Command.checkLoggedIn(); await Command.checkLoggedIn();
const { confirm } = await import('../../utils/patterns'); const { confirm } = await import('../../utils/patterns.js');
await confirm( await confirm(
opt.yes || false, opt.yes || false,
'Are you sure you want to delete the environment variable?', 'Are you sure you want to delete the environment variable?',

View File

@ -125,14 +125,14 @@ export default class EnvsCmd extends Command {
let fleetSlug: string | undefined = options.fleet let fleetSlug: string | undefined = options.fleet
? await ( ? await (
await import('../../utils/sdk') await import('../../utils/sdk.js')
).getFleetSlug(balena, options.fleet) ).getFleetSlug(balena, options.fleet)
: undefined; : undefined;
let fullUUID: string | undefined; // as oppposed to the short, 7-char UUID let fullUUID: string | undefined; // as oppposed to the short, 7-char UUID
if (options.device) { if (options.device) {
const { getDeviceAndMaybeAppFromUUID } = await import( const { getDeviceAndMaybeAppFromUUID } = await import(
'../../utils/cloud' '../../utils/cloud.js'
); );
const [device, app] = await getDeviceAndMaybeAppFromUUID( const [device, app] = await getDeviceAndMaybeAppFromUUID(
balena, balena,
@ -186,7 +186,7 @@ export default class EnvsCmd extends Command {
} }
if (options.json) { if (options.json) {
const { pickAndRename } = await import('../../utils/helpers'); const { pickAndRename } = await import('../../utils/helpers.js');
const mapped = varArray.map((o) => pickAndRename(o, fields)); const mapped = varArray.map((o) => pickAndRename(o, fields));
this.log(JSON.stringify(mapped, null, 4)); this.log(JSON.stringify(mapped, null, 4));
} else { } else {

View File

@ -77,7 +77,7 @@ export default class FleetCreateCmd extends Command {
const { args: params, flags: options } = await this.parse(FleetCreateCmd); const { args: params, flags: options } = await this.parse(FleetCreateCmd);
await ( await (
await import('../../utils/application-create') await import('../../utils/application-create.js')
).applicationCreateBase('fleet', options, params); ).applicationCreateBase('fleet', options, params);
} }
} }

View File

@ -58,7 +58,7 @@ export default class FleetCmd extends Command {
public async run() { public async run() {
const { args: params, flags: options } = await this.parse(FleetCmd); const { args: params, flags: options } = await this.parse(FleetCmd);
const { getApplication } = await import('../../utils/sdk'); const { getApplication } = await import('../../utils/sdk.js');
const balena = getBalenaSdk(); const balena = getBalenaSdk();
@ -70,7 +70,7 @@ export default class FleetCmd extends Command {
}); });
if (options.view) { if (options.view) {
const open = await import('open'); const { default: open } = await import('open');
const dashboardUrl = balena.models.application.getDashboardUrl( const dashboardUrl = balena.models.application.getDashboardUrl(
application.id, application.id,
); );

View File

@ -51,7 +51,7 @@ export default class FleetPurgeCmd extends Command {
public async run() { public async run() {
const { args: params } = await this.parse(FleetPurgeCmd); const { args: params } = await this.parse(FleetPurgeCmd);
const { getApplication } = await import('../../utils/sdk'); const { getApplication } = await import('../../utils/sdk.js');
const balena = getBalenaSdk(); const balena = getBalenaSdk();

View File

@ -59,13 +59,15 @@ export default class FleetRenameCmd extends Command {
public async run() { public async run() {
const { args: params } = await this.parse(FleetRenameCmd); const { args: params } = await this.parse(FleetRenameCmd);
const { validateApplicationName } = await import('../../utils/validation'); const { validateApplicationName } = await import(
const { ExpectedError } = await import('../../errors'); '../../utils/validation.js'
);
const { ExpectedError } = await import('../../errors.js');
const balena = getBalenaSdk(); const balena = getBalenaSdk();
// Disambiguate target application (if params.params is a number, it could either be an ID or a numerical name) // Disambiguate target application (if params.params is a number, it could either be an ID or a numerical name)
const { getApplication } = await import('../../utils/sdk'); const { getApplication } = await import('../../utils/sdk.js');
const application = await getApplication(balena, params.fleet, { const application = await getApplication(balena, params.fleet, {
$select: ['id', 'app_name', 'slug'], $select: ['id', 'app_name', 'slug'],
$expand: { $expand: {

View File

@ -50,7 +50,7 @@ export default class FleetRestartCmd extends Command {
public async run() { public async run() {
const { args: params } = await this.parse(FleetRestartCmd); const { args: params } = await this.parse(FleetRestartCmd);
const { getApplication } = await import('../../utils/sdk'); const { getApplication } = await import('../../utils/sdk.js');
const balena = getBalenaSdk(); const balena = getBalenaSdk();

View File

@ -54,8 +54,8 @@ export default class FleetRmCmd extends Command {
public async run() { public async run() {
const { args: params, flags: options } = await this.parse(FleetRmCmd); const { args: params, flags: options } = await this.parse(FleetRmCmd);
const { confirm } = await import('../../utils/patterns'); const { confirm } = await import('../../utils/patterns.js');
const { getApplication } = await import('../../utils/sdk'); const { getApplication } = await import('../../utils/sdk.js');
const balena = getBalenaSdk(); const balena = getBalenaSdk();
// Confirm // Confirm

View File

@ -63,7 +63,7 @@ export default class OsinitCmd extends Command {
const config = JSON.parse(params.config); const config = JSON.parse(params.config);
const { getManifest, osProgressHandler } = await import( const { getManifest, osProgressHandler } = await import(
'../../utils/helpers' '../../utils/helpers.js'
); );
const manifest = await getManifest(params.image, params.type); const manifest = await getManifest(params.image, params.type);

View File

@ -78,7 +78,7 @@ export default class JoinCmd extends Command {
public async run() { public async run() {
const { args: params, flags: options } = await this.parse(JoinCmd); const { args: params, flags: options } = await this.parse(JoinCmd);
const promote = await import('../../utils/promote'); const promote = await import('../../utils/promote.js');
const sdk = getBalenaSdk(); const sdk = getBalenaSdk();
const logger = await Command.getLogger(); const logger = await Command.getLogger();
return promote.join( return promote.join(

View File

@ -52,7 +52,7 @@ export default class KeyRmCmd extends Command {
public async run() { public async run() {
const { args: params, flags: options } = await this.parse(KeyRmCmd); const { args: params, flags: options } = await this.parse(KeyRmCmd);
const patterns = await import('../../utils/patterns'); const patterns = await import('../../utils/patterns.js');
await patterns.confirm( await patterns.confirm(
options.yes ?? false, options.yes ?? false,

View File

@ -62,7 +62,7 @@ export default class LeaveCmd extends Command {
public async run() { public async run() {
const { args: params } = await this.parse(LeaveCmd); const { args: params } = await this.parse(LeaveCmd);
const promote = await import('../../utils/promote'); const promote = await import('../../utils/promote.js');
const logger = await Command.getLogger(); const logger = await Command.getLogger();
return promote.leave(logger, params.deviceIpOrHostname); return promote.leave(logger, params.deviceIpOrHostname);
} }

View File

@ -53,8 +53,8 @@ export default class LocalConfigureCmd extends Command {
const { args: params } = await this.parse(LocalConfigureCmd); const { args: params } = await this.parse(LocalConfigureCmd);
const reconfix = await import('reconfix'); const reconfix = await import('reconfix');
const { denyMount, safeUmount } = await import('../../utils/umount'); const { denyMount, safeUmount } = await import('../../utils/umount.js');
const Logger = await import('../../utils/logger'); const { default: Logger } = await import('../../utils/logger.js');
const logger = Logger.getLogger(); const logger = Logger.getLogger();

View File

@ -79,7 +79,7 @@ export default class LocalFlashCmd extends Command {
const drive = await this.getDrive(options); const drive = await this.getDrive(options);
const { confirm } = await import('../../utils/patterns'); const { confirm } = await import('../../utils/patterns.js');
await confirm( await confirm(
options.yes, options.yes,
'This will erase the selected drive. Are you sure?', 'This will erase the selected drive. Are you sure?',

View File

@ -123,7 +123,7 @@ export default class LoginCmd extends Command {
const { flags: options, args: params } = await this.parse(LoginCmd); const { flags: options, args: params } = await this.parse(LoginCmd);
const balena = getBalenaSdk(); const balena = getBalenaSdk();
const messages = await import('../../utils/messages'); const messages = await import('../../utils/messages.js');
const balenaUrl = await balena.settings.get('balenaUrl'); const balenaUrl = await balena.settings.get('balenaUrl');
// Consolidate user/email options // Consolidate user/email options
@ -202,20 +202,20 @@ ${messages.reachingOut}`);
} }
// Credentials // Credentials
else if (loginOptions.credentials) { else if (loginOptions.credentials) {
const patterns = await import('../../utils/patterns'); const patterns = await import('../../utils/patterns.js');
return patterns.authenticate(loginOptions); return patterns.authenticate(loginOptions);
} }
// Web // Web
else if (loginOptions.web) { else if (loginOptions.web) {
const auth = await import('../../auth'); const auth = await import('../../auth/index.js');
await auth.login({ port: loginOptions.port }); await auth.login({ port: loginOptions.port });
return; return;
} else { } else {
const patterns = await import('../../utils/patterns'); const patterns = await import('../../utils/patterns.js');
// User had not selected login preference, prompt interactively // User had not selected login preference, prompt interactively
const loginType = await patterns.askLoginType(); const loginType = await patterns.askLoginType();
if (loginType === 'register') { if (loginType === 'register') {
const open = await import('open'); const { default: open } = await import('open');
const signupUrl = `https://dashboard.${balenaUrl}/signup`; const signupUrl = `https://dashboard.${balenaUrl}/signup`;
await open(signupUrl, { wait: false }); await open(signupUrl, { wait: false });
throw new ExpectedError(`Please sign up at ${signupUrl}`); throw new ExpectedError(`Please sign up at ${signupUrl}`);

View File

@ -96,14 +96,14 @@ export default class LogsCmd extends Command {
const { args: params, flags: options } = await this.parse(LogsCmd); const { args: params, flags: options } = await this.parse(LogsCmd);
const balena = getBalenaSdk(); const balena = getBalenaSdk();
const { serviceIdToName } = await import('../../utils/cloud'); const { serviceIdToName } = await import('../../utils/cloud.js');
const { connectAndDisplayDeviceLogs, displayLogObject } = await import( const { connectAndDisplayDeviceLogs, displayLogObject } = await import(
'../../utils/device/logs' '../../utils/device/logs.js'
); );
const { validateIPAddress, validateDotLocalUrl } = await import( const { validateIPAddress, validateDotLocalUrl } = await import(
'../../utils/validation' '../../utils/validation.js'
); );
const Logger = await import('../../utils/logger'); const { default: Logger } = await import('../../utils/logger.js');
const logger = Logger.getLogger(); const logger = Logger.getLogger();
@ -132,13 +132,13 @@ export default class LogsCmd extends Command {
validateDotLocalUrl(params.device) validateDotLocalUrl(params.device)
) { ) {
// Logs from local device // Logs from local device
const { DeviceAPI } = await import('../../utils/device/api'); const { DeviceAPI } = await import('../../utils/device/api.js');
const deviceApi = new DeviceAPI(logger, params.device); const deviceApi = new DeviceAPI(logger, params.device);
logger.logDebug('Checking we can access device'); logger.logDebug('Checking we can access device');
try { try {
await deviceApi.ping(); await deviceApi.ping();
} catch (e) { } catch (e) {
const { ExpectedError } = await import('../../errors'); const { ExpectedError } = await import('../../errors.js');
throw new ExpectedError( throw new ExpectedError(
`Cannot access device at address ${params.device}. Device may not be in local mode.`, `Cannot access device at address ${params.device}. Device may not be in local mode.`,
); );

View File

@ -38,7 +38,7 @@ export default class OrgsCmd extends Command {
public async run() { public async run() {
await this.parse(OrgsCmd); await this.parse(OrgsCmd);
const { getOwnOrganizations } = await import('../../utils/sdk'); const { getOwnOrganizations } = await import('../../utils/sdk.js');
// Get organizations // Get organizations
const organizations = await getOwnOrganizations(getBalenaSdk(), { const organizations = await getOwnOrganizations(getBalenaSdk(), {

View File

@ -82,7 +82,7 @@ export default class OsBuildConfigCmd extends Command {
async buildConfig(image: string, deviceTypeSlug: string, advanced: boolean) { async buildConfig(image: string, deviceTypeSlug: string, advanced: boolean) {
advanced = advanced || false; advanced = advanced || false;
const { getManifest } = await import('../../utils/helpers'); const { getManifest } = await import('../../utils/helpers.js');
const deviceTypeManifest = await getManifest(image, deviceTypeSlug); const deviceTypeManifest = await getManifest(image, deviceTypeSlug);
return this.buildConfigForDeviceType(deviceTypeManifest, advanced); return this.buildConfigForDeviceType(deviceTypeManifest, advanced);
@ -103,7 +103,7 @@ export default class OsBuildConfigCmd extends Command {
}); });
if (advancedGroup != null) { if (advancedGroup != null) {
const { getGroupDefaults } = await import('../../utils/helpers'); const { getGroupDefaults } = await import('../../utils/helpers.js');
override = getGroupDefaults(advancedGroup); override = getGroupDefaults(advancedGroup);
} }
} }

View File

@ -170,10 +170,10 @@ export default class OsConfigureCmd extends Command {
const devInit = await import('balena-device-init'); const devInit = await import('balena-device-init');
const { promises: fs } = await import('fs'); const { promises: fs } = await import('fs');
const { generateDeviceConfig, generateApplicationConfig } = await import( const { generateDeviceConfig, generateApplicationConfig } = await import(
'../../utils/config' '../../utils/config.js'
); );
const helpers = await import('../../utils/helpers'); const helpers = await import('../../utils/helpers.js');
const { getApplication } = await import('../../utils/sdk'); const { getApplication } = await import('../../utils/sdk.js');
let app: ApplicationWithDeviceTypeSlug | undefined; let app: ApplicationWithDeviceTypeSlug | undefined;
let device; let device;
@ -211,7 +211,7 @@ export default class OsConfigureCmd extends Command {
configJson = JSON.parse(rawConfig); configJson = JSON.parse(rawConfig);
} }
const { normalizeOsVersion } = await import('../../utils/normalization'); const { normalizeOsVersion } = await import('../../utils/normalization.js');
const osVersion = normalizeOsVersion( const osVersion = normalizeOsVersion(
options.version || options.version ||
(await getOsVersionFromImage( (await getOsVersionFromImage(
@ -221,11 +221,11 @@ export default class OsConfigureCmd extends Command {
)), )),
); );
const { validateDevOptionAndWarn } = await import('../../utils/config'); const { validateDevOptionAndWarn } = await import('../../utils/config.js');
await validateDevOptionAndWarn(options.dev, osVersion); await validateDevOptionAndWarn(options.dev, osVersion);
const { validateSecureBootOptionAndWarn } = await import( const { validateSecureBootOptionAndWarn } = await import(
'../../utils/config' '../../utils/config.js'
); );
await validateSecureBootOptionAndWarn( await validateSecureBootOptionAndWarn(
options.secureBoot, options.secureBoot,
@ -363,7 +363,7 @@ async function checkDeviceTypeCompatibility(
}, },
) { ) {
if (options['device-type']) { if (options['device-type']) {
const helpers = await import('../../utils/helpers'); const helpers = await import('../../utils/helpers.js');
if ( if (
!(await helpers.areDeviceTypesCompatible( !(await helpers.areDeviceTypesCompatible(
app.is_for__device_type[0].slug, app.is_for__device_type[0].slug,
@ -417,7 +417,7 @@ async function askQuestionsForDeviceType(
isGroup: true, isGroup: true,
}); });
if (!_.isEmpty(advancedGroup)) { if (!_.isEmpty(advancedGroup)) {
const helpers = await import('../../utils/helpers'); const helpers = await import('../../utils/helpers.js');
answerSources.push(helpers.getGroupDefaults(advancedGroup)); answerSources.push(helpers.getGroupDefaults(advancedGroup));
} }
} }

View File

@ -95,7 +95,7 @@ export default class OsDownloadCmd extends Command {
await OsDownloadCmd.checkLoggedIn(); await OsDownloadCmd.checkLoggedIn();
} catch (e) { } catch (e) {
const { ExpectedError, NotLoggedInError } = await import( const { ExpectedError, NotLoggedInError } = await import(
'../../errors' '../../errors.js'
); );
if (e instanceof NotLoggedInError) { if (e instanceof NotLoggedInError) {
throw new ExpectedError(stripIndent` throw new ExpectedError(stripIndent`
@ -107,7 +107,7 @@ export default class OsDownloadCmd extends Command {
} }
} }
const { downloadOSImage } = await import('../../utils/cloud'); const { downloadOSImage } = await import('../../utils/cloud.js');
try { try {
await downloadOSImage(params.type, options.output, options.version); await downloadOSImage(params.type, options.output, options.version);

View File

@ -62,7 +62,7 @@ export default class OsInitializeCmd extends Command {
public async run() { public async run() {
const { args: params, flags: options } = await this.parse(OsInitializeCmd); const { args: params, flags: options } = await this.parse(OsInitializeCmd);
const { getManifest, sudo } = await import('../../utils/helpers'); const { getManifest, sudo } = await import('../../utils/helpers.js');
console.info(`Initializing device ${INIT_WARNING_MESSAGE}`); console.info(`Initializing device ${INIT_WARNING_MESSAGE}`);
@ -75,13 +75,13 @@ export default class OsInitializeCmd extends Command {
}); });
if (answers.drive != null) { if (answers.drive != null) {
const { confirm } = await import('../../utils/patterns'); const { confirm } = await import('../../utils/patterns.js');
await confirm( await confirm(
options.yes, options.yes,
`This will erase ${answers.drive}. Are you sure?`, `This will erase ${answers.drive}. Are you sure?`,
`Going to erase ${answers.drive}.`, `Going to erase ${answers.drive}.`,
); );
const { safeUmount } = await import('../../utils/umount'); const { safeUmount } = await import('../../utils/umount.js');
await safeUmount(answers.drive); await safeUmount(answers.drive);
} }
@ -94,7 +94,7 @@ export default class OsInitializeCmd extends Command {
]); ]);
if (answers.drive != null) { if (answers.drive != null) {
const { safeUmount } = await import('../../utils/umount'); const { safeUmount } = await import('../../utils/umount.js');
await safeUmount(answers.drive); await safeUmount(answers.drive);
console.info(`You can safely remove ${answers.drive} now`); console.info(`You can safely remove ${answers.drive} now`);
} }

View File

@ -58,7 +58,7 @@ export default class OsVersionsCmd extends Command {
const { args: params, flags: options } = await this.parse(OsVersionsCmd); const { args: params, flags: options } = await this.parse(OsVersionsCmd);
if (options['include-draft']) { if (options['include-draft']) {
const { warnify } = await import('../../utils/messages'); const { warnify } = await import('../../utils/messages.js');
console.error( console.error(
warnify(stripIndent` warnify(stripIndent`
Using pre-release balenaOS versions is only supported for OS updates Using pre-release balenaOS versions is only supported for OS updates
@ -68,7 +68,7 @@ export default class OsVersionsCmd extends Command {
} }
const { formatOsVersion, getOsVersions } = await import( const { formatOsVersion, getOsVersions } = await import(
'../../utils/cloud' '../../utils/cloud.js'
); );
const vs = await getOsVersions( const vs = await getOsVersions(
params.type, params.type,

View File

@ -39,6 +39,7 @@ import type {
Release, Release,
} from 'balena-sdk'; } from 'balena-sdk';
import type { Preloader } from 'balena-preload'; import type { Preloader } from 'balena-preload';
import type { EventEmitter } from 'events';
export default class PreloadCmd extends Command { export default class PreloadCmd extends Command {
public static description = stripIndent` public static description = stripIndent`
@ -145,10 +146,10 @@ Can be repeated to add multiple certificates.\
const { args: params, flags: options } = await this.parse(PreloadCmd); const { args: params, flags: options } = await this.parse(PreloadCmd);
const balena = getBalenaSdk(); const balena = getBalenaSdk();
const balenaPreload = await import('balena-preload'); const { default: balenaPreload } = await import('balena-preload');
const visuals = getVisuals(); const visuals = getVisuals();
const nodeCleanup = await import('node-cleanup'); const { default: nodeCleanup } = await import('node-cleanup');
const { instanceOf } = await import('../../errors'); const { instanceOf } = await import('../../errors.js');
// Check image file exists // Check image file exists
try { try {
@ -172,7 +173,7 @@ Can be repeated to add multiple certificates.\
// Load app here, and use app slug from hereon // Load app here, and use app slug from hereon
const fleetSlug: string | undefined = options.fleet const fleetSlug: string | undefined = options.fleet
? await ( ? await (
await import('../../utils/sdk') await import('../../utils/sdk.js')
).getFleetSlug(balena, options.fleet) ).getFleetSlug(balena, options.fleet)
: undefined; : undefined;
@ -229,7 +230,7 @@ Can be repeated to add multiple certificates.\
} }
// Get a configured dockerode instance // Get a configured dockerode instance
const dockerUtils = await import('../../utils/docker'); const dockerUtils = await import('../../utils/docker.js');
const docker = await dockerUtils.getDocker(options); const docker = await dockerUtils.getDocker(options);
const preloader = new balenaPreload.Preloader( const preloader = new balenaPreload.Preloader(
undefined, undefined,
@ -243,7 +244,7 @@ Can be repeated to add multiple certificates.\
pinDevice ?? false, pinDevice ?? false,
certificates, certificates,
additionalSpace, additionalSpace,
); ) as Preloader & EventEmitter;
let gotSignal = false; let gotSignal = false;
@ -481,7 +482,7 @@ Would you like to disable automatic updates for this fleet now?\
} }
async getAppWithReleases(balenaSdk: BalenaSDK, slug: string) { async getAppWithReleases(balenaSdk: BalenaSDK, slug: string) {
const { getApplication } = await import('../../utils/sdk'); const { getApplication } = await import('../../utils/sdk.js');
return await getApplication(balenaSdk, slug, { return await getApplication(balenaSdk, slug, {
$expand: this.applicationExpandOptions, $expand: this.applicationExpandOptions,

View File

@ -233,7 +233,9 @@ export default class PushCmd extends Command {
logger.logDebug(`Using build source directory: ${options.source} `); logger.logDebug(`Using build source directory: ${options.source} `);
const sdk = getBalenaSdk(); const sdk = getBalenaSdk();
const { validateProjectDirectory } = await import('../../utils/compose_ts'); const { validateProjectDirectory } = await import(
'../../utils/compose_ts.js'
);
const { dockerfilePath, registrySecrets } = await validateProjectDirectory( const { dockerfilePath, registrySecrets } = await validateProjectDirectory(
sdk, sdk,
{ {
@ -276,8 +278,8 @@ export default class PushCmd extends Command {
dockerfilePath: string, dockerfilePath: string,
registrySecrets: RegistrySecrets, registrySecrets: RegistrySecrets,
) { ) {
const remote = await import('../../utils/remote-build'); const remote = await import('../../utils/remote-build.js');
const { getApplication } = await import('../../utils/sdk'); const { getApplication } = await import('../../utils/sdk.js');
// Check for invalid options // Check for invalid options
const localOnlyOptions: Array<keyof FlagsDef> = [ const localOnlyOptions: Array<keyof FlagsDef> = [
@ -356,7 +358,7 @@ export default class PushCmd extends Command {
'is only valid when pushing to a fleet', 'is only valid when pushing to a fleet',
); );
const deviceDeploy = await import('../../utils/device/deploy'); const deviceDeploy = await import('../../utils/device/deploy.js');
try { try {
await deviceDeploy.deployToDevice({ await deviceDeploy.deployToDevice({
@ -376,7 +378,7 @@ export default class PushCmd extends Command {
convertEol: !options['noconvert-eol'], convertEol: !options['noconvert-eol'],
}); });
} catch (e) { } catch (e) {
const { BuildError } = await import('../../utils/device/errors'); const { BuildError } = await import('../../utils/device/errors.js');
if (instanceOf(e, BuildError)) { if (instanceOf(e, BuildError)) {
throw new ExpectedError(e.toString()); throw new ExpectedError(e.toString());
} else { } else {
@ -387,7 +389,7 @@ export default class PushCmd extends Command {
protected async getBuildTarget(appOrDevice: string): Promise<BuildTarget> { protected async getBuildTarget(appOrDevice: string): Promise<BuildTarget> {
const { validateLocalHostnameOrIp } = await import( const { validateLocalHostnameOrIp } = await import(
'../../utils/validation' '../../utils/validation.js'
); );
return validateLocalHostnameOrIp(appOrDevice) return validateLocalHostnameOrIp(appOrDevice)

View File

@ -67,7 +67,7 @@ export default class ReleasesCmd extends Command {
]; ];
const balena = getBalenaSdk(); const balena = getBalenaSdk();
const { getFleetSlug } = await import('../../utils/sdk'); const { getFleetSlug } = await import('../../utils/sdk.js');
const releases = await balena.models.release.getAllByApplication( const releases = await balena.models.release.getAllByApplication(
await getFleetSlug(balena, params.fleet), await getFleetSlug(balena, params.fleet),

View File

@ -65,10 +65,10 @@ export default class ScanCmd extends Command {
public async run() { public async run() {
const _ = await import('lodash'); const _ = await import('lodash');
const { discoverLocalBalenaOsDevices } = await import( const { discoverLocalBalenaOsDevices } = await import(
'../../utils/discover' '../../utils/discover.js'
); );
const prettyjson = await import('prettyjson'); const prettyjson = await import('prettyjson');
const dockerUtils = await import('../../utils/docker'); const dockerUtils = await import('../../utils/docker.js');
const dockerPort = 2375; const dockerPort = 2375;
const dockerTimeout = 2000; const dockerTimeout = 2000;

View File

@ -111,7 +111,9 @@ export default class SshCmd extends Command {
// Local connection // Local connection
if (validateLocalHostnameOrIp(params.fleetOrDevice)) { if (validateLocalHostnameOrIp(params.fleetOrDevice)) {
const { performLocalDeviceSSH } = await import('../../utils/device/ssh'); const { performLocalDeviceSSH } = await import(
'../../utils/device/ssh.js'
);
return await performLocalDeviceSSH({ return await performLocalDeviceSSH({
hostname: params.fleetOrDevice, hostname: params.fleetOrDevice,
port: options.port || 'local', port: options.port || 'local',
@ -122,8 +124,10 @@ export default class SshCmd extends Command {
} }
// Remote connection // Remote connection
const { getProxyConfig } = await import('../../utils/helpers'); const { getProxyConfig } = await import('../../utils/helpers.js');
const { getOnlineTargetDeviceUuid } = await import('../../utils/patterns'); const { getOnlineTargetDeviceUuid } = await import(
'../../utils/patterns.js'
);
const sdk = getBalenaSdk(); const sdk = getBalenaSdk();
const proxyConfig = getProxyConfig(); const proxyConfig = getProxyConfig();
@ -137,7 +141,7 @@ export default class SshCmd extends Command {
params.fleetOrDevice, params.fleetOrDevice,
); );
const { which } = await import('../../utils/which'); const { which } = await import('../../utils/which.js');
const [whichProxytunnel, { username }, proxyUrl] = await Promise.all([ const [whichProxytunnel, { username }, proxyUrl] = await Promise.all([
useProxy ? which('proxytunnel', false) : undefined, useProxy ? which('proxytunnel', false) : undefined,
@ -189,7 +193,7 @@ export default class SshCmd extends Command {
let containerId: string | undefined; let containerId: string | undefined;
if (params.service != null) { if (params.service != null) {
const { getContainerIdForService } = await import( const { getContainerIdForService } = await import(
'../../utils/device/ssh' '../../utils/device/ssh.js'
); );
containerId = await getContainerIdForService({ containerId = await getContainerIdForService({
deviceUuid, deviceUuid,
@ -207,7 +211,7 @@ export default class SshCmd extends Command {
} else { } else {
accessCommand = `host ${deviceUuid}`; accessCommand = `host ${deviceUuid}`;
} }
const { runRemoteCommand } = await import('../../utils/ssh'); const { runRemoteCommand } = await import('../../utils/ssh.js');
await runRemoteCommand({ await runRemoteCommand({
cmd: accessCommand, cmd: accessCommand,
hostname: `ssh.${proxyUrl}`, hostname: `ssh.${proxyUrl}`,

View File

@ -116,7 +116,7 @@ export default class SupportCmd extends Command {
ux.action.stop(); ux.action.stop();
} }
const { getFleetSlug } = await import('../../utils/sdk'); const { getFleetSlug } = await import('../../utils/sdk.js');
// Process applications // Process applications
for (const appName of appNames) { for (const appName of appNames) {

View File

@ -72,12 +72,12 @@ export default class TagRmCmd extends Command {
// Check user has specified one of application/device/release // Check user has specified one of application/device/release
if (!options.fleet && !options.device && !options.release) { if (!options.fleet && !options.device && !options.release) {
const { ExpectedError } = await import('../../errors'); const { ExpectedError } = await import('../../errors.js');
throw new ExpectedError(TagRmCmd.missingResourceMessage); throw new ExpectedError(TagRmCmd.missingResourceMessage);
} }
if (options.fleet) { if (options.fleet) {
const { getFleetSlug } = await import('../../utils/sdk'); const { getFleetSlug } = await import('../../utils/sdk.js');
return balena.models.application.tags.remove( return balena.models.application.tags.remove(
await getFleetSlug(balena, options.fleet), await getFleetSlug(balena, options.fleet),
params.tagKey, params.tagKey,
@ -88,7 +88,7 @@ export default class TagRmCmd extends Command {
} }
if (options.release) { if (options.release) {
const { disambiguateReleaseParam } = await import( const { disambiguateReleaseParam } = await import(
'../../utils/normalization' '../../utils/normalization.js'
); );
const releaseParam = await disambiguateReleaseParam( const releaseParam = await disambiguateReleaseParam(
balena, balena,

View File

@ -85,14 +85,14 @@ export default class TagSetCmd extends Command {
// Check user has specified one of application/device/release // Check user has specified one of application/device/release
if (!options.fleet && !options.device && !options.release) { if (!options.fleet && !options.device && !options.release) {
const { ExpectedError } = await import('../../errors'); const { ExpectedError } = await import('../../errors.js');
throw new ExpectedError(TagSetCmd.missingResourceMessage); throw new ExpectedError(TagSetCmd.missingResourceMessage);
} }
params.value ??= ''; params.value ??= '';
if (options.fleet) { if (options.fleet) {
const { getFleetSlug } = await import('../../utils/sdk'); const { getFleetSlug } = await import('../../utils/sdk.js');
return balena.models.application.tags.set( return balena.models.application.tags.set(
await getFleetSlug(balena, options.fleet), await getFleetSlug(balena, options.fleet),
params.tagKey, params.tagKey,
@ -108,7 +108,7 @@ export default class TagSetCmd extends Command {
} }
if (options.release) { if (options.release) {
const { disambiguateReleaseParam } = await import( const { disambiguateReleaseParam } = await import(
'../../utils/normalization' '../../utils/normalization.js'
); );
const releaseParam = await disambiguateReleaseParam( const releaseParam = await disambiguateReleaseParam(
balena, balena,

View File

@ -71,7 +71,7 @@ export default class TagsCmd extends Command {
let tags; let tags;
if (options.fleet) { if (options.fleet) {
const { getFleetSlug } = await import('../../utils/sdk'); const { getFleetSlug } = await import('../../utils/sdk.js');
tags = await balena.models.application.tags.getAllByApplication( tags = await balena.models.application.tags.getAllByApplication(
await getFleetSlug(balena, options.fleet), await getFleetSlug(balena, options.fleet),
); );
@ -81,7 +81,7 @@ export default class TagsCmd extends Command {
} }
if (options.release) { if (options.release) {
const { disambiguateReleaseParam } = await import( const { disambiguateReleaseParam } = await import(
'../../utils/normalization' '../../utils/normalization.js'
); );
const releaseParam = await disambiguateReleaseParam( const releaseParam = await disambiguateReleaseParam(
balena, balena,

View File

@ -122,7 +122,9 @@ export default class TunnelCmd extends Command {
} }
// Ascertain device uuid // Ascertain device uuid
const { getOnlineTargetDeviceUuid } = await import('../../utils/patterns'); const { getOnlineTargetDeviceUuid } = await import(
'../../utils/patterns.js'
);
const uuid = await getOnlineTargetDeviceUuid(sdk, params.deviceOrFleet); const uuid = await getOnlineTargetDeviceUuid(sdk, params.deviceOrFleet);
logger.logInfo(`Opening a tunnel to ${uuid}...`); logger.logInfo(`Opening a tunnel to ${uuid}...`);
@ -134,7 +136,7 @@ export default class TunnelCmd extends Command {
.map(async ({ localPort, localAddress, remotePort }) => { .map(async ({ localPort, localAddress, remotePort }) => {
try { try {
const { tunnelConnectionToDevice } = await import( const { tunnelConnectionToDevice } = await import(
'../../utils/tunnel' '../../utils/tunnel.js'
); );
const handler = await tunnelConnectionToDevice(uuid, remotePort, sdk); const handler = await tunnelConnectionToDevice(uuid, remotePort, sdk);

View File

@ -72,7 +72,7 @@ export default class VersionCmd extends Command {
public async run() { public async run() {
const { flags: options } = await this.parse(VersionCmd); const { flags: options } = await this.parse(VersionCmd);
const versions: JsonVersions = { const versions: JsonVersions = {
'balena-cli': (await import('../../../package.json')).version, 'balena-cli': (await import('../../../package.json')).default.version,
'Node.js': 'Node.js':
process.version && process.version.startsWith('v') process.version && process.version.startsWith('v')
? process.version.slice(1) ? process.version.slice(1)

View File

@ -102,7 +102,7 @@ export class DeprecationChecker {
protected async fetchPublishedTimestampForVersion( protected async fetchPublishedTimestampForVersion(
version: string, version: string,
): Promise<string | undefined> { ): Promise<string | undefined> {
const { default: got } = await import('got'); const { default: got } = (await import('got')).default;
const url = this.getNpmUrl(version); const url = this.getNpmUrl(version);
let response: import('got').Response<Dictionary<any>> | undefined; let response: import('got').Response<Dictionary<any>> | undefined;
try { try {
@ -198,7 +198,7 @@ or release date not available`);
const nextMajorDate = new Date(nextMajorDateStr).getTime(); const nextMajorDate = new Date(nextMajorDateStr).getTime();
const daysElapsed = Math.trunc((this.now - nextMajorDate) / this.msInDay); const daysElapsed = Math.trunc((this.now - nextMajorDate) / this.msInDay);
if (daysElapsed > this.expiryDays) { if (daysElapsed > this.expiryDays) {
const { ExpectedError } = await import('./errors'); const { ExpectedError } = await import('./errors.js');
throw new ExpectedError(this.getExpiryMsg(daysElapsed)); throw new ExpectedError(this.getExpiryMsg(daysElapsed));
} else if (daysElapsed > this.deprecationDays && process.stderr.isTTY) { } else if (daysElapsed > this.deprecationDays && process.stderr.isTTY) {
console.error(this.getDeprecationMsg(daysElapsed)); console.error(this.getDeprecationMsg(daysElapsed));

View File

@ -44,7 +44,7 @@ export async function trackCommand(commandSignature: string) {
scope.setExtra('command', commandSignature); scope.setExtra('command', commandSignature);
}); });
} }
const { getCachedUsername } = await import('./utils/bootstrap'); const { getCachedUsername } = await import('./utils/bootstrap.js');
let username: string | undefined; let username: string | undefined;
try { try {
username = (await getCachedUsername())?.username; username = (await getCachedUsername())?.username;
@ -79,7 +79,7 @@ const TIMEOUT = 4000;
* Make the event tracking HTTPS request to balenaCloud's '/mixpanel' endpoint. * Make the event tracking HTTPS request to balenaCloud's '/mixpanel' endpoint.
*/ */
async function sendEvent(balenaUrl: string, event: string, username?: string) { async function sendEvent(balenaUrl: string, event: string, username?: string) {
const { default: got } = await import('got'); const { default: got } = (await import('got')).default;
const trackData = { const trackData = {
api_key: 'balena-main', api_key: 'balena-main',
events: [ events: [

View File

@ -74,7 +74,7 @@ async function $start() {
stat(path.join(root, 'npm-shrinkwrap.json'), { bigint: true }), stat(path.join(root, 'npm-shrinkwrap.json'), { bigint: true }),
]); ]);
// Include timestamps to account for dev-time changes to node_modules // Include timestamps to account for dev-time changes to node_modules
const cacheKiller = `${pJson.version}-${pStat.mtimeMs}-${nStat.mtimeMs}`; const cacheKiller = `${pJson.default.version}-${pStat.mtimeMs}-${nStat.mtimeMs}`;
require('fast-boot2').start({ require('fast-boot2').start({
cacheFile, cacheFile,
cacheKiller, cacheKiller,

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import { Help } from '@oclif/core'; import { Help } from '@oclif/core';
import * as indent from 'indent-string'; import indent from 'indent-string';
import { getChalk } from './utils/lazy'; import { getChalk } from './utils/lazy';
// Partially overrides standard implementation of help plugin // Partially overrides standard implementation of help plugin

View File

@ -33,7 +33,7 @@ export const trackPromise = new Promise((resolve) => {
* literally so: 'NAME' and 'VALUE' are NOT replaced with actual values. * literally so: 'NAME' and 'VALUE' are NOT replaced with actual values.
*/ */
const hook: Hook<'prerun'> = async function (options) { const hook: Hook<'prerun'> = async function (options) {
const events = await import('../../events'); const events = await import('../../events.js');
const usage: string | string[] | undefined = options.Command.usage; const usage: string | string[] | undefined = options.Command.usage;
const cmdSignature = const cmdSignature =
usage == null ? '*' : typeof usage === 'string' ? usage : usage.join(' '); usage == null ? '*' : typeof usage === 'string' ? usage : usage.join(' ');

View File

@ -68,7 +68,7 @@ export async function preparseArgs(argv: string[]): Promise<string[]> {
process.env.BLUEBIRD_LONG_STACK_TRACES = '1'; process.env.BLUEBIRD_LONG_STACK_TRACES = '1';
} }
const Logger = await import('./utils/logger'); const Logger = await import('./utils/logger.js');
Logger.command = cmdSlice[0]; Logger.command = cmdSlice[0];
let args = cmdSlice; let args = cmdSlice;
@ -157,7 +157,7 @@ Please use "balena ${alternative}" instead.`);
// Check if this is a space separated 'topic command' style command subcommand (e.g. `end add`) // Check if this is a space separated 'topic command' style command subcommand (e.g. `end add`)
// by comparing with oclif style colon-separated subcommand list (e.g. `env:add`) // by comparing with oclif style colon-separated subcommand list (e.g. `env:add`)
export async function isSubcommand(args: string[]) { export async function isSubcommand(args: string[]) {
const { getCommandIdsFromManifest } = await import('./utils/oclif-utils'); const { getCommandIdsFromManifest } = await import('./utils/oclif-utils.js');
const commandIds = await getCommandIdsFromManifest(); const commandIds = await getCommandIdsFromManifest();
return commandIds.includes(`${args[0] || ''}:${args[1] || ''}`); return commandIds.includes(`${args[0] || ''}:${args[1] || ''}`);
} }

View File

@ -18,12 +18,12 @@ export async function applicationCreateBase(
) { ) {
// Ascertain device type // Ascertain device type
const deviceType = const deviceType =
options.type || (await (await import('./patterns')).selectDeviceType()); options.type || (await (await import('./patterns.js')).selectDeviceType());
// Ascertain organization // Ascertain organization
const organization = const organization =
options.organization?.toLowerCase() || options.organization?.toLowerCase() ||
(await (await import('./patterns')).getAndSelectOrganization()); (await (await import('./patterns.js')).getAndSelectOrganization());
// Create application // Create application
try { try {

View File

@ -139,7 +139,7 @@ export async function getCachedUsername(): Promise<CachedUsername | undefined> {
return cachedUsername; return cachedUsername;
} }
const [{ getBalenaSdk }, { getStorage }, settings] = await Promise.all([ const [{ getBalenaSdk }, { getStorage }, settings] = await Promise.all([
import('./lazy'), import('./lazy.js'),
import('balena-settings-storage'), import('balena-settings-storage'),
import('balena-settings-client'), import('balena-settings-client'),
]); ]);

View File

@ -206,7 +206,7 @@ async function resolveOSVersion(
false, false,
); );
} }
const { normalizeOsVersion } = await import('./normalization'); const { normalizeOsVersion } = await import('./normalization.js');
version = normalizeOsVersion(version); version = normalizeOsVersion(version);
return version; return version;
} }

View File

@ -479,10 +479,8 @@ export class BuildProgressUI implements Renderer {
} }
_renderStatus(end = false) { _renderStatus(end = false) {
const moment = require('moment') as typeof import('moment'); const moment = require('moment');
( require('moment-duration-format')(moment);
require('moment-duration-format') as typeof import('moment-duration-format')
)(moment);
this._tty.clearLine(); this._tty.clearLine();
this._tty.write(this._prefix); this._tty.write(this._prefix);
@ -577,10 +575,8 @@ export class BuildProgressInline implements Renderer {
} }
end(summary?: Dictionary<string>) { end(summary?: Dictionary<string>) {
const moment = require('moment') as typeof import('moment'); const moment = require('moment');
( require('moment-duration-format')(moment);
require('moment-duration-format') as typeof import('moment-duration-format')
)(moment);
if (this._ended) { if (this._ended) {
return; return;

View File

@ -117,7 +117,7 @@ export async function loadProject(
imageTag?: string, imageTag?: string,
): Promise<ComposeProject> { ): Promise<ComposeProject> {
const compose = await import('@balena/compose/dist/parse'); const compose = await import('@balena/compose/dist/parse');
const { createProject } = await import('./compose'); const { createProject } = await import('./compose.js');
let composeName: string; let composeName: string;
let composeStr: string; let composeStr: string;
@ -265,7 +265,7 @@ export async function buildProject(
const renderer = await startRenderer({ imageDescriptors, ...opts }); const renderer = await startRenderer({ imageDescriptors, ...opts });
let buildSummaryByService: Dictionary<string> | undefined; let buildSummaryByService: Dictionary<string> | undefined;
try { try {
const { awaitInterruptibleTask } = await import('./helpers'); const { awaitInterruptibleTask } = await import('./helpers.js');
const [images, summaryMsgByService] = await awaitInterruptibleTask( const [images, summaryMsgByService] = await awaitInterruptibleTask(
$buildProject, $buildProject,
imageDescriptors, imageDescriptors,
@ -330,7 +330,7 @@ async function $buildProject(
logger.logDebug('Prepared tasks; building...'); logger.logDebug('Prepared tasks; building...');
const { BALENA_ENGINE_TMP_PATH } = await import('../config'); const { BALENA_ENGINE_TMP_PATH } = await import('../config.js');
const builder = await import('@balena/compose/dist/multibuild'); const builder = await import('@balena/compose/dist/multibuild');
const builtImages = await builder.performBuilds( const builtImages = await builder.performBuilds(
@ -358,13 +358,14 @@ async function startRenderer({
}): Promise<Renderer> { }): Promise<Renderer> {
let renderer: Renderer; let renderer: Renderer;
if (inlineLogs) { if (inlineLogs) {
renderer = new (await import('./compose')).BuildProgressInline( renderer = new (await import('./compose.js')).BuildProgressInline(
logger.streams['build'], logger.streams['build'],
imageDescriptors, imageDescriptors,
); );
} else { } else {
const tty = (await import('./tty'))(process.stdout); const { default: $tty } = await import('./tty.js');
renderer = new (await import('./compose')).BuildProgressUI( const tty = $tty(process.stdout);
renderer = new (await import('./compose.js')).BuildProgressUI(
tty, tty,
imageDescriptors, imageDescriptors,
); );
@ -388,7 +389,7 @@ async function installQemuIfNeeded({
logger: Logger; logger: Logger;
projectPath: string; projectPath: string;
}): Promise<boolean> { }): Promise<boolean> {
const qemu = await import('./qemu'); const qemu = await import('./qemu.js');
const needsQemu = await qemu.installQemuIfNeeded( const needsQemu = await qemu.installQemuIfNeeded(
emulated, emulated,
logger, logger,
@ -471,7 +472,7 @@ async function qemuTransposeBuildStream({
dockerfilePath?: string; dockerfilePath?: string;
projectPath: string; projectPath: string;
}): Promise<TransposeOptions> { }): Promise<TransposeOptions> {
const qemu = await import('./qemu'); const qemu = await import('./qemu.js');
const binPath = qemu.qemuPathInContext( const binPath = qemu.qemuPathInContext(
path.join(projectPath, task.context ?? ''), path.join(projectPath, task.context ?? ''),
); );
@ -681,7 +682,7 @@ export async function getServiceDirsFromComposition(
sourceDir: string, sourceDir: string,
composition?: Composition, composition?: Composition,
): Promise<Dictionary<string>> { ): Promise<Dictionary<string>> {
const { createProject } = await import('./compose'); const { createProject } = await import('./compose.js');
const serviceDirs: Dictionary<string> = {}; const serviceDirs: Dictionary<string> = {};
if (!composition) { if (!composition) {
const [, composeStr] = await resolveProject( const [, composeStr] = await resolveProject(
@ -757,7 +758,7 @@ export async function tarDirectory(
preFinalizeCallback, preFinalizeCallback,
}: TarDirectoryOptions, }: TarDirectoryOptions,
): Promise<import('stream').Readable> { ): Promise<import('stream').Readable> {
const { filterFilesWithDockerignore } = await import('./ignore'); const { filterFilesWithDockerignore } = await import('./ignore.js');
const { toPosixPath } = (await import('@balena/compose/dist/multibuild')) const { toPosixPath } = (await import('@balena/compose/dist/multibuild'))
.PathUtils; .PathUtils;
@ -891,7 +892,7 @@ export async function checkBuildSecretsRequirements(
) { ) {
const [metaObj, metaFilename] = await loadBuildMetatada(sourceDir); const [metaObj, metaFilename] = await loadBuildMetatada(sourceDir);
if (metaObj && !_.isEmpty(metaObj['build-secrets'])) { if (metaObj && !_.isEmpty(metaObj['build-secrets'])) {
const dockerUtils = await import('./docker'); const dockerUtils = await import('./docker.js');
const isBalenaEngine = await dockerUtils.isBalenaEngine(docker); const isBalenaEngine = await dockerUtils.isBalenaEngine(docker);
if (!isBalenaEngine) { if (!isBalenaEngine) {
throw new ExpectedError(stripIndent` throw new ExpectedError(stripIndent`
@ -1222,7 +1223,7 @@ async function getTokenForPreviousRepos(
taggedImages: TaggedImage[], taggedImages: TaggedImage[],
): Promise<string> { ): Promise<string> {
logger.logDebug('Authorizing push...'); logger.logDebug('Authorizing push...');
const { authorizePush, getPreviousRepos } = await import('./compose'); const { authorizePush, getPreviousRepos } = await import('./compose.js');
const sdk = getBalenaSdk(); const sdk = getBalenaSdk();
const previousRepos = await getPreviousRepos(sdk, logger, appId); const previousRepos = await getPreviousRepos(sdk, logger, appId);
@ -1246,9 +1247,10 @@ async function pushAndUpdateServiceImages(
) => Promise<void>, ) => Promise<void>,
) { ) {
const { DockerProgress } = await import('docker-progress'); const { DockerProgress } = await import('docker-progress');
const { retry } = await import('./helpers'); const { retry } = await import('./helpers.js');
const { pushProgressRenderer } = await import('./compose'); const { pushProgressRenderer } = await import('./compose.js');
const tty = (await import('./tty'))(process.stdout); const { default: $tty } = await import('./tty.js');
const tty = $tty(process.stdout);
const opts = { authconfig: { registrytoken: token } }; const opts = { authconfig: { registrytoken: token } };
const progress = new DockerProgress({ docker }); const progress = new DockerProgress({ docker });
const renderer = pushProgressRenderer( const renderer = pushProgressRenderer(
@ -1361,8 +1363,9 @@ export async function deployProject(
isDraft: boolean, isDraft: boolean,
): Promise<import('@balena/compose/dist/release/models').ReleaseModel> { ): Promise<import('@balena/compose/dist/release/models').ReleaseModel> {
const releaseMod = await import('@balena/compose/dist/release'); const releaseMod = await import('@balena/compose/dist/release');
const { createRelease, tagServiceImages } = await import('./compose'); const { createRelease, tagServiceImages } = await import('./compose.js');
const tty = (await import('./tty'))(process.stdout); const { default: $tty } = await import('./tty.js');
const tty = $tty(process.stdout);
const prefix = getChalk().cyan('[Info]') + ' '; const prefix = getChalk().cyan('[Info]') + ' ';
const spinner = createSpinner(); const spinner = createSpinner();
@ -1397,7 +1400,7 @@ export async function deployProject(
logger.logDebug('Tagging images...'); logger.logDebug('Tagging images...');
const taggedImages = await tagServiceImages(docker, images, serviceImages); const taggedImages = await tagServiceImages(docker, images, serviceImages);
try { try {
const { awaitInterruptibleTask } = await import('./helpers'); const { awaitInterruptibleTask } = await import('./helpers.js');
// awaitInterruptibleTask throws SIGINTError on CTRL-C, // awaitInterruptibleTask throws SIGINTError on CTRL-C,
// causing the release status to be set to 'failed' // causing the release status to be set to 'failed'
await awaitInterruptibleTask(async () => { await awaitInterruptibleTask(async () => {

View File

@ -161,13 +161,13 @@ export async function validateDevOptionAndWarn(
return; return;
} }
if (version && /\bprod\b/.test(version)) { if (version && /\bprod\b/.test(version)) {
const { ExpectedError } = await import('../errors'); const { ExpectedError } = await import('../errors.js');
throw new ExpectedError( throw new ExpectedError(
`Error: The '--dev' option conflicts with production balenaOS version '${version}'`, `Error: The '--dev' option conflicts with production balenaOS version '${version}'`,
); );
} }
if (!logger) { if (!logger) {
const Logger = await import('./logger'); const { default: Logger } = await import('./logger.js');
logger = Logger.getLogger(); logger = Logger.getLogger();
} }
logger.logInfo(stripIndent` logger.logInfo(stripIndent`
@ -192,7 +192,7 @@ export async function validateSecureBootOptionAndWarn(
if (!secureBoot) { if (!secureBoot) {
return; return;
} }
const { ExpectedError } = await import('../errors'); const { ExpectedError } = await import('../errors.js');
if (!version) { if (!version) {
throw new ExpectedError(`Error: No version provided`); throw new ExpectedError(`Error: No version provided`);
} }
@ -215,7 +215,7 @@ export async function validateSecureBootOptionAndWarn(
}) })
) { ) {
if (!logger) { if (!logger) {
const Logger = await import('./logger'); const { default: Logger } = await import('./logger.js');
logger = Logger.getLogger(); logger = Logger.getLogger();
} }
logger.logInfo(stripIndent` logger.logInfo(stripIndent`

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import * as _ from 'lodash'; import * as _ from 'lodash';
import * as request from 'request'; import request from 'request';
import type * as Stream from 'stream'; import type * as Stream from 'stream';
import { retry } from '../helpers'; import { retry } from '../helpers';

View File

@ -16,7 +16,7 @@
*/ */
import * as semver from 'balena-semver'; import * as semver from 'balena-semver';
import * as Docker from 'dockerode'; import Docker from 'dockerode';
import * as _ from 'lodash'; import * as _ from 'lodash';
import type { Composition } from '@balena/compose/dist/parse'; import type { Composition } from '@balena/compose/dist/parse';
import type { import type {
@ -215,7 +215,7 @@ export async function deployToDevice(opts: DeviceDeployOptions): Promise<void> {
imageIds = {}; imageIds = {};
} }
const { awaitInterruptibleTask } = await import('../helpers'); const { awaitInterruptibleTask } = await import('../helpers.js');
const buildTasks = await awaitInterruptibleTask<typeof performBuilds>( const buildTasks = await awaitInterruptibleTask<typeof performBuilds>(
performBuilds, performBuilds,
project.composition, project.composition,
@ -295,7 +295,7 @@ async function streamDeviceLogs(
return; return;
} }
globalLogger.logInfo('Streaming device logs...'); globalLogger.logInfo('Streaming device logs...');
const { connectAndDisplayDeviceLogs } = await import('./logs'); const { connectAndDisplayDeviceLogs } = await import('./logs.js');
return connectAndDisplayDeviceLogs({ return connectAndDisplayDeviceLogs({
deviceApi, deviceApi,
logger: globalLogger, logger: globalLogger,

View File

@ -108,8 +108,8 @@ export class LivepushManager {
this.logger.logLivepush('Device state settled'); this.logger.logLivepush('Device state settled');
// Prepare dockerignore data for file watcher // Prepare dockerignore data for file watcher
const { getDockerignoreByService } = await import('../ignore'); const { getDockerignoreByService } = await import('../ignore.js');
const { getServiceDirsFromComposition } = await import('../compose_ts'); const { getServiceDirsFromComposition } = await import('../compose_ts.js');
const rootContext = path.resolve(this.buildContext); const rootContext = path.resolve(this.buildContext);
const serviceDirsByService = await getServiceDirsFromComposition( const serviceDirsByService = await getServiceDirsFromComposition(
this.deployOpts.source, this.deployOpts.source,

View File

@ -62,7 +62,7 @@ async function displayDeviceLogs(
system: boolean, system: boolean,
filterServices?: string[], filterServices?: string[],
): Promise<void> { ): Promise<void> {
const { addSIGINTHandler } = await import('../helpers'); const { addSIGINTHandler } = await import('../helpers.js');
const { parse: ndjsonParse } = await import('ndjson'); const { parse: ndjsonParse } = await import('ndjson');
let gotSignal = false; let gotSignal = false;
const handleSignal = () => { const handleSignal = () => {
@ -125,7 +125,7 @@ export async function connectAndDisplayDeviceLogs({
return displayDeviceLogs(logStream, logger, system, filterServices); return displayDeviceLogs(logStream, logger, system, filterServices);
} }
const { retry } = await import('../../utils/helpers'); const { retry } = await import('../../utils/helpers.js');
try { try {
await retry({ await retry({
func: connectAndDisplay, func: connectAndDisplay,

View File

@ -21,7 +21,7 @@ export async function discoverLocalBalenaOsDevices(
): Promise<LocalBalenaOsDevice[]> { ): Promise<LocalBalenaOsDevice[]> {
const services = await new Promise<Service[]>((resolve) => { const services = await new Promise<Service[]>((resolve) => {
const bonjour = new Bonjour({}, async (err: string | Error) => { const bonjour = new Bonjour({}, async (err: string | Error) => {
await (await import('../errors')).handleError(err); await (await import('../errors.js')).handleError(err);
}); });
const resinSshServices: Service[] = []; const resinSshServices: Service[] = [];
const browser = bonjour.find(avahiBalenaSshConfig, (service) => const browser = bonjour.find(avahiBalenaSshConfig, (service) =>

View File

@ -186,7 +186,7 @@ export async function getDocker(
export async function createClient( export async function createClient(
opts: dockerode.DockerOptions, opts: dockerode.DockerOptions,
): Promise<dockerode> { ): Promise<dockerode> {
const Docker = await import('dockerode'); const { default: Docker } = await import('dockerode');
return new Docker(opts); return new Docker(opts);
} }

View File

@ -77,7 +77,7 @@ export async function sudo(
isCLIcmd, isCLIcmd,
}: { stderr?: NodeJS.WritableStream; msg?: string; isCLIcmd?: boolean } = {}, }: { stderr?: NodeJS.WritableStream; msg?: string; isCLIcmd?: boolean } = {},
) { ) {
const { executeWithPrivileges } = await import('./sudo'); const { executeWithPrivileges } = await import('./sudo.js');
if (process.platform !== 'win32') { if (process.platform !== 'win32') {
console.log( console.log(
@ -115,7 +115,7 @@ export async function getManifest(
manifest.slug !== deviceType && manifest.slug !== deviceType &&
manifest.slug !== (await sdk.models.deviceType.get(deviceType)).slug manifest.slug !== (await sdk.models.deviceType.get(deviceType)).slug
) { ) {
const { ExpectedError } = await import('../errors'); const { ExpectedError } = await import('../errors.js');
throw new ExpectedError( throw new ExpectedError(
`The device type of the provided OS image ${manifest.slug}, does not match the expected device type ${deviceType}`, `The device type of the provided OS image ${manifest.slug}, does not match the expected device type ${deviceType}`,
); );
@ -182,7 +182,7 @@ export async function osProgressHandler(step: InitializeEmitter) {
} }
export async function getAppWithArch(applicationName: string) { export async function getAppWithArch(applicationName: string) {
const { getApplication } = await import('./sdk'); const { getApplication } = await import('./sdk.js');
const balena = getBalenaSdk(); const balena = getBalenaSdk();
const app = await getApplication(balena, applicationName, { const app = await getApplication(balena, applicationName, {
$expand: { $expand: {
@ -239,7 +239,7 @@ export async function retry<T>({
backoffScaler?: number; backoffScaler?: number;
maxSingleDelayMs?: number; maxSingleDelayMs?: number;
}): Promise<T> { }): Promise<T> {
const { SIGINTError } = await import('../errors'); const { SIGINTError } = await import('../errors.js');
let delayMs = initialDelayMs; let delayMs = initialDelayMs;
for (let count = 0; count < maxAttempts - 1; count++) { for (let count = 0; count < maxAttempts - 1; count++) {
const lastAttemptMs = Date.now(); const lastAttemptMs = Date.now();

View File

@ -104,7 +104,7 @@ export async function getDockerIgnoreInstance(
): Promise<Ignore> { ): Promise<Ignore> {
const dockerIgnoreStr = await readDockerIgnoreFile(directory); const dockerIgnoreStr = await readDockerIgnoreFile(directory);
const $dockerIgnore = (await import('@balena/dockerignore')).default; const $dockerIgnore = (await import('@balena/dockerignore')).default;
const ig = $dockerIgnore({ ignorecase: false }); const ig = $dockerIgnore.default({ ignorecase: false });
ig.add(['**/.git']); ig.add(['**/.git']);
if (dockerIgnoreStr) { if (dockerIgnoreStr) {

View File

@ -28,8 +28,9 @@ import { instanceOf, NotLoggedInError, ExpectedError } from '../errors';
import { getBalenaSdk, getVisuals, stripIndent, getCliForm } 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';
import type Bluebird from 'bluebird';
export function authenticate(options: object): Promise<void> { export function authenticate(options: object): Bluebird<void> {
const balena = getBalenaSdk(); const balena = getBalenaSdk();
return getCliForm() return getCliForm()
.run( .run(
@ -229,7 +230,7 @@ export async function selectOrganization(
} }
export async function getAndSelectOrganization() { export async function getAndSelectOrganization() {
const { getOwnOrganizations } = await import('./sdk'); const { getOwnOrganizations } = await import('./sdk.js');
const organizations = await getOwnOrganizations(getBalenaSdk(), { const organizations = await getOwnOrganizations(getBalenaSdk(), {
$select: ['name', 'handle'], $select: ['name', 'handle'],
}); });
@ -304,7 +305,8 @@ export async function getOnlineTargetDeviceUuid(
sdk: BalenaSDK, sdk: BalenaSDK,
fleetOrDevice: string, fleetOrDevice: string,
) { ) {
const logger = (await import('../utils/logger')).getLogger(); const { default: Logger } = await import('../utils/logger.js');
const logger = Logger.getLogger();
// If looks like UUID, probably device // If looks like UUID, probably device
if (validation.validateUuid(fleetOrDevice)) { if (validation.validateUuid(fleetOrDevice)) {
@ -337,7 +339,7 @@ export async function getOnlineTargetDeviceUuid(
const application = await (async () => { const application = await (async () => {
try { try {
logger.logDebug(`Fetching fleet ${fleetOrDevice}`); logger.logDebug(`Fetching fleet ${fleetOrDevice}`);
const { getApplication } = await import('./sdk'); const { getApplication } = await import('./sdk.js');
return await getApplication(sdk, fleetOrDevice, { return await getApplication(sdk, fleetOrDevice, {
$select: ['id', 'slug'], $select: ['id', 'slug'],
$expand: { $expand: {
@ -382,7 +384,7 @@ export async function getOnlineTargetDeviceUuid(
export function selectFromList<T>( export function selectFromList<T>(
message: string, message: string,
choices: Array<T & { name: string }>, choices: Array<T & { name: string }>,
): Promise<T> { ): Bluebird<T> {
return getCliForm().ask<T>({ return getCliForm().ask<T>({
message, message,
type: 'list', type: 'list',

View File

@ -167,7 +167,7 @@ const dockerPort = 2375;
const dockerTimeout = 2000; const dockerTimeout = 2000;
async function selectLocalBalenaOsDevice(timeout = 4000): Promise<string> { async function selectLocalBalenaOsDevice(timeout = 4000): Promise<string> {
const { discoverLocalBalenaOsDevices } = await import('../utils/discover'); const { discoverLocalBalenaOsDevices } = await import('../utils/discover.js');
const { SpinnerPromise } = getVisuals(); const { SpinnerPromise } = getVisuals();
const devices = await new SpinnerPromise({ const devices = await new SpinnerPromise({
promise: discoverLocalBalenaOsDevices(timeout), promise: discoverLocalBalenaOsDevices(timeout),
@ -176,7 +176,7 @@ async function selectLocalBalenaOsDevice(timeout = 4000): Promise<string> {
}); });
const responsiveDevices: typeof devices = []; const responsiveDevices: typeof devices = [];
const Docker = await import('dockerode'); const { default: Docker } = await import('dockerode');
await Promise.all( await Promise.all(
devices.map(async function (device) { devices.map(async function (device) {
const address = device?.address; const address = device?.address;
@ -231,7 +231,7 @@ async function selectAppFromList(
applications: ApplicationWithDeviceTypeSlug[], applications: ApplicationWithDeviceTypeSlug[],
): Promise<ApplicationWithDeviceTypeSlug> { ): Promise<ApplicationWithDeviceTypeSlug> {
const _ = await import('lodash'); const _ = await import('lodash');
const { selectFromList } = await import('../utils/patterns'); const { selectFromList } = await import('../utils/patterns.js');
// Present a list to the user which shows the fully qualified fleet // Present a list to the user which shows the fully qualified fleet
// name (user/fleetname) and allows them to select. // name (user/fleetname) and allows them to select.
@ -384,7 +384,7 @@ async function createApplication(
deviceType: string, deviceType: string,
name?: string, name?: string,
): Promise<ApplicationWithDeviceTypeSlug> { ): Promise<ApplicationWithDeviceTypeSlug> {
const validation = await import('./validation'); const validation = await import('./validation.js');
let username: string; let username: string;
try { try {
@ -447,7 +447,7 @@ async function generateApplicationConfig(
appUpdatePollInterval?: number; appUpdatePollInterval?: number;
}, },
) { ) {
const { generateApplicationConfig: configGen } = await import('./config'); const { generateApplicationConfig: configGen } = await import('./config.js');
const manifest = await sdk.models.config.getDeviceTypeManifestBySlug( const manifest = await sdk.models.config.getDeviceTypeManifestBySlug(
app.is_for__device_type[0].slug, app.is_for__device_type[0].slug,

View File

@ -94,7 +94,7 @@ async function installQemu(arch: string, qemuPath: string) {
const urlVersion = encodeURIComponent(QEMU_VERSION); const urlVersion = encodeURIComponent(QEMU_VERSION);
const qemuUrl = `https://github.com/balena-io/qemu/releases/download/${urlVersion}/${urlFile}`; const qemuUrl = `https://github.com/balena-io/qemu/releases/download/${urlVersion}/${urlFile}`;
const request = await import('request'); const { default: request } = await import('request');
const fs = await import('fs'); const fs = await import('fs');
const zlib = await import('zlib'); const zlib = await import('zlib');
const tar = await import('tar-stream'); const tar = await import('tar-stream');

View File

@ -126,7 +126,7 @@ export async function startRemoteBuild(
} }
}; };
const { addSIGINTHandler } = await import('./helpers'); const { addSIGINTHandler } = await import('./helpers.js');
addSIGINTHandler(sigintHandler); addSIGINTHandler(sigintHandler);
try { try {

View File

@ -42,7 +42,7 @@ export async function getApplication(
nameOrSlugOrId: string | number, nameOrSlugOrId: string | number,
options?: PineOptions<Application>, options?: PineOptions<Application>,
): Promise<Application> { ): Promise<Application> {
const { looksLikeFleetSlug } = await import('./validation'); const { looksLikeFleetSlug } = await import('./validation.js');
const whoamiResult = await sdk.auth.whoami(); const whoamiResult = await sdk.auth.whoami();
const isDeviceActor = whoamiResult?.actorType === 'device'; const isDeviceActor = whoamiResult?.actorType === 'device';
@ -97,7 +97,7 @@ export async function getFleetSlug(
sdk: BalenaSDK, sdk: BalenaSDK,
nameOrSlug: string, nameOrSlug: string,
): Promise<string> { ): Promise<string> {
const { looksLikeFleetSlug } = await import('./validation'); const { looksLikeFleetSlug } = await import('./validation.js');
if (!looksLikeFleetSlug(nameOrSlug)) { if (!looksLikeFleetSlug(nameOrSlug)) {
// Not a slug: must be an app name. // Not a slug: must be an app name.
// TODO: revisit this logic when we add support for fleet UUIDs. // TODO: revisit this logic when we add support for fleet UUIDs.

View File

@ -127,7 +127,7 @@ export async function runRemoteCommand({
} else { } else {
ignoreStdin = false; ignoreStdin = false;
} }
const { which } = await import('./which'); const { which } = await import('./which.js');
const program = await which('ssh'); const program = await which('ssh');
const args = sshArgsForRemoteCommand({ const args = sshArgsForRemoteCommand({
cmd, cmd,
@ -140,7 +140,7 @@ export async function runRemoteCommand({
}); });
if (process.env.DEBUG) { if (process.env.DEBUG) {
const logger = (await import('./logger')).getLogger(); const logger = (await import('./logger.js')).default.getLogger();
logger.logDebug(`Executing [${program},${args}]`); logger.logDebug(`Executing [${program},${args}]`);
} }
@ -296,11 +296,11 @@ export const findBestUsernameForDevice = _.memoize(
if (await isRootUserGood(hostname, port)) { if (await isRootUserGood(hostname, port)) {
username = 'root'; username = 'root';
} else { } else {
const { getCachedUsername } = await import('./bootstrap'); const { getCachedUsername } = await import('./bootstrap.js');
username = (await getCachedUsername())?.username; username = (await getCachedUsername())?.username;
} }
if (!username) { if (!username) {
const { stripIndent } = await import('./lazy'); const { stripIndent } = await import('./lazy.js');
throw new ExpectedError(stripIndent` throw new ExpectedError(stripIndent`
SSH authentication failed for 'root@${hostname}'. SSH authentication failed for 'root@${hostname}'.
Please login with 'balena login' for alternative authentication.`); Please login with 'balena login' for alternative authentication.`);

View File

@ -43,8 +43,8 @@ export async function executeWithPrivileges(
isCLIcmd = true, isCLIcmd = true,
): Promise<void> { ): Promise<void> {
// whether the CLI is already running with admin / super user privileges // whether the CLI is already running with admin / super user privileges
const isElevated = await (await import('is-elevated'))(); const isElevated = await (await import('is-elevated')).default();
const { shellEscape } = await import('./helpers'); const { shellEscape } = await import('./helpers.js');
const opts: SpawnOptions = { const opts: SpawnOptions = {
env: process.env, env: process.env,
stdio: ['inherit', 'inherit', stderr ? 'pipe' : 'inherit'], stdio: ['inherit', 'inherit', stderr ? 'pipe' : 'inherit'],

View File

@ -39,7 +39,7 @@ export async function umount(device: string): Promise<void> {
if (process.platform === 'win32') { if (process.platform === 'win32') {
return; return;
} }
const { sanitizePath, whichBin } = await import('./which'); const { sanitizePath, whichBin } = await import('./which.js');
// sanitize user's input (regular expression attacks ?) // sanitize user's input (regular expression attacks ?)
device = sanitizePath(device); device = sanitizePath(device);
const cmd: string[] = []; const cmd: string[] = [];
@ -48,7 +48,7 @@ export async function umount(device: string): Promise<void> {
cmd.push('/usr/sbin/diskutil', 'unmountDisk', 'force', device); cmd.push('/usr/sbin/diskutil', 'unmountDisk', 'force', device);
} else { } else {
// Linux // Linux
const glob = promisify(await import('glob')); const glob = promisify((await import('glob')).default);
// '?*' expands a base device path like '/dev/sdb' to an array of paths // '?*' expands a base device path like '/dev/sdb' to an array of paths
// like '/dev/sdb1', '/dev/sdb2', ..., '/dev/sdb11', ... (partitions) // like '/dev/sdb1', '/dev/sdb2', ..., '/dev/sdb11', ... (partitions)
// that exist for balenaOS images and are needed as arguments to 'umount' // that exist for balenaOS images and are needed as arguments to 'umount'
@ -75,7 +75,7 @@ export async function umount(device: string): Promise<void> {
} }
return; return;
} }
const { ExpectedError } = await import('../errors'); const { ExpectedError } = await import('../errors.js');
throw new ExpectedError(msg.join('\n')); throw new ExpectedError(msg.join('\n'));
} }
} }
@ -92,7 +92,7 @@ export async function isMounted(device: string): Promise<boolean> {
if (!device) { if (!device) {
return false; return false;
} }
const { whichBin } = await import('./which'); const { whichBin } = await import('./which.js');
const mountCmd = await whichBin('mount'); const mountCmd = await whichBin('mount');
let stdout = ''; let stdout = '';
let stderr = ''; let stderr = '';
@ -101,7 +101,7 @@ export async function isMounted(device: string): Promise<boolean> {
stdout = proc.stdout; stdout = proc.stdout;
stderr = proc.stderr; stderr = proc.stderr;
} catch (err) { } catch (err) {
const { ExpectedError } = await import('../errors'); const { ExpectedError } = await import('../errors.js');
throw new ExpectedError( throw new ExpectedError(
`Error executing "${mountCmd}":\n${stderr}\n${err.message}`, `Error executing "${mountCmd}":\n${stderr}\n${err.message}`,
); );
@ -131,7 +131,7 @@ export async function denyMount(
handler: () => any, handler: () => any,
opts: { autoMountOnSuccess?: boolean; executablePath?: string } = {}, opts: { autoMountOnSuccess?: boolean; executablePath?: string } = {},
) { ) {
const denymount = promisify(await import('denymount')); const denymount = promisify((await import('denymount')).default);
if (process.pkg) { if (process.pkg) {
// when running in a standalone pkg install, the 'denymount' // when running in a standalone pkg install, the 'denymount'
// executable is placed on the same folder as process.execPath // executable is placed on the same folder as process.execPath

View File

@ -15,7 +15,7 @@ limitations under the License.
*/ */
import isRoot = require('is-root'); import isRoot = require('is-root');
import * as UpdateNotifier from 'update-notifier'; import UpdateNotifier from 'update-notifier';
import packageJSON = require('../../package.json'); import packageJSON = require('../../package.json');

View File

@ -76,14 +76,14 @@ export async function which(
program: string, program: string,
rejectOnMissing = true, rejectOnMissing = true,
): Promise<string> { ): Promise<string> {
const whichMod = await import('which'); const { default: whichMod } = await import('which');
let programPath: string; let programPath: string;
try { try {
programPath = await whichMod(program); programPath = await whichMod(program);
} catch (err) { } catch (err) {
if (err.code === 'ENOENT') { if (err.code === 'ENOENT') {
if (rejectOnMissing) { if (rejectOnMissing) {
const { ExpectedError } = await import('../errors'); const { ExpectedError } = await import('../errors.js');
throw new ExpectedError( throw new ExpectedError(
`'${program}' program not found. Is it installed?`, `'${program}' program not found. Is it installed?`,
); );

View File

@ -1,4 +1,4 @@
import * as Bluebird from 'bluebird'; import Bluebird from 'bluebird';
import { expect } from 'chai'; import { expect } from 'chai';
import rewire = require('rewire'); import rewire = require('rewire');
import * as sinon from 'sinon'; import * as sinon from 'sinon';

View File

@ -17,7 +17,7 @@
import { expect } from 'chai'; import { expect } from 'chai';
import * as _ from 'lodash'; import * as _ from 'lodash';
import * as mock from 'mock-require'; import mock from 'mock-require';
import { promises as fs } from 'fs'; import { promises as fs } from 'fs';
import * as path from 'path'; import * as path from 'path';

View File

@ -16,7 +16,7 @@
*/ */
import { expect } from 'chai'; import { expect } from 'chai';
import mock = require('mock-require'); import mock from 'mock-require';
import type { Server } from 'net'; import type { Server } from 'net';
import { createServer } from 'net'; import { createServer } from 'net';
@ -149,7 +149,7 @@ describe('balena ssh', function () {
/** Check whether the 'ssh' tool (executable) exists in the PATH */ /** Check whether the 'ssh' tool (executable) exists in the PATH */
async function checkSsh(): Promise<boolean> { async function checkSsh(): Promise<boolean> {
const { which } = await import('../../build/utils/which'); const { which } = await import('../../build/utils/which.js');
const sshPath = await which('ssh', false); const sshPath = await which('ssh', false);
if ((sshPath || '').includes('\\Windows\\System32\\OpenSSH\\ssh')) { if ((sshPath || '').includes('\\Windows\\System32\\OpenSSH\\ssh')) {
// don't use Windows' built-in ssh tool for these test cases // don't use Windows' built-in ssh tool for these test cases

View File

@ -90,8 +90,8 @@ export function filterCliOutputForTests({
* @param cmd Command to execute, e.g. `push myApp` (without 'balena' prefix) * @param cmd Command to execute, e.g. `push myApp` (without 'balena' prefix)
*/ */
async function runCommandInProcess(cmd: string): Promise<TestOutput> { async function runCommandInProcess(cmd: string): Promise<TestOutput> {
const balenaCLI = await import('../build/app'); const balenaCLI = await import('../build/app.js');
const intercept = await import('intercept-stdout'); const { default: intercept } = await import('intercept-stdout');
const preArgs = [process.argv[0], path.join(process.cwd(), 'bin', 'balena')]; const preArgs = [process.argv[0], path.join(process.cwd(), 'bin', 'balena')];
@ -236,7 +236,7 @@ export async function runCommand(cmd: string): Promise<TestOutput> {
} catch { } catch {
throw new Error(`Standalone executable not found: "${standalonePath}"`); throw new Error(`Standalone executable not found: "${standalonePath}"`);
} }
const proxy = await import('./nock/proxy-server'); const proxy = await import('./nock/proxy-server.js');
const [proxyPort] = await proxy.createProxyServerOnce(); const [proxyPort] = await proxy.createProxyServerOnce();
return runCommandInSubprocess(cmd, proxyPort); return runCommandInSubprocess(cmd, proxyPort);
} else { } else {
@ -353,7 +353,7 @@ export function deepJsonParse(data: any): any {
export async function switchSentry( export async function switchSentry(
enabled: boolean | undefined, enabled: boolean | undefined,
): Promise<boolean | undefined> { ): Promise<boolean | undefined> {
const balenaCLI = await import('../build/app'); const balenaCLI = await import('../build/app.js');
const sentryOpts = (await balenaCLI.setupSentry()).getClient()?.getOptions(); const sentryOpts = (await balenaCLI.setupSentry()).getClient()?.getOptions();
if (sentryOpts) { if (sentryOpts) {
const sentryStatus = sentryOpts.enabled; const sentryStatus = sentryOpts.enabled;

View File

@ -15,7 +15,7 @@
* limitations under the License. * limitations under the License.
*/ */
import * as nock from 'nock'; import nock from 'nock';
import * as fs from 'fs'; import * as fs from 'fs';
export interface ScopeOpts { export interface ScopeOpts {

View File

@ -83,10 +83,10 @@ describeSS('LivepushManager::setupFilesystemWatcher', function () {
changedPathHandler: (serviceName: string, changedPath: string) => void, changedPathHandler: (serviceName: string, changedPath: string) => void,
): Promise<ByService<chokidar.FSWatcher>> { ): Promise<ByService<chokidar.FSWatcher>> {
const { getServiceDirsFromComposition } = await import( const { getServiceDirsFromComposition } = await import(
'../../../build/utils/compose_ts' '../../../build/utils/compose_ts.js'
); );
const { getDockerignoreByService } = await import( const { getDockerignoreByService } = await import(
'../../../build/utils/ignore' '../../../build/utils/ignore.js'
); );
const rootContext = path.resolve(projectPath); const rootContext = path.resolve(projectPath);

View File

@ -22,7 +22,7 @@ describe('@balena/compose/multibuild consistency', function () {
const { QEMU_BIN_NAME: MQEMU_BIN_NAME } = await import( const { QEMU_BIN_NAME: MQEMU_BIN_NAME } = await import(
'@balena/compose/dist/multibuild' '@balena/compose/dist/multibuild'
); );
const { QEMU_BIN_NAME } = await import('../../build/utils/qemu'); const { QEMU_BIN_NAME } = await import('../../build/utils/qemu.js');
expect(QEMU_BIN_NAME).to.equal(MQEMU_BIN_NAME); expect(QEMU_BIN_NAME).to.equal(MQEMU_BIN_NAME);
}); });
}); });

View File

@ -16,7 +16,7 @@
*/ */
import { expect } from 'chai'; import { expect } from 'chai';
import * as stripIndent from 'common-tags/lib/stripIndent'; import stripIndent from 'common-tags/lib/stripIndent';
import { getNotifierMessage } from '../../build/utils/update'; import { getNotifierMessage } from '../../build/utils/update';

View File

@ -1,8 +1,8 @@
{ {
"compilerOptions": { "compilerOptions": {
"declaration": true, "declaration": true,
"module": "commonjs", "module": "Node16",
"target": "es2018", "target": "es2022",
"outDir": "build", "outDir": "build",
"strict": true, "strict": true,
"strictPropertyInitialization": false, "strictPropertyInitialization": false,