diff --git a/.eslintrc.js b/.eslintrc.cjs
similarity index 100%
rename from .eslintrc.js
rename to .eslintrc.cjs
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index c310c863..b5bc0b9f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -8,14 +8,14 @@ The balena CLI is an open source project and your contribution is welcome!
* Clone the `balena-cli` repository (or a [forked
repo](https://docs.github.com/en/free-pro-team@latest/github/getting-started-with-github/fork-a-repo),
if you are not in the balena team), `cd` to it and run `npm install`.
-* Build the CLI with `npm run build` or `npm test`, and execute it with `./bin/balena`
+* Build the CLI with `npm run build` or `npm test`, and execute it with `./bin/balena.js`
(on a Windows command prompt, you may need to run `node .\bin\balena`).
In order to ease development:
* `npm run build:fast` skips some of the build steps for interactive testing, or
* `npm run test:source` skips testing the standalone zip packages (which is rather slow)
-* `./bin/balena-dev` uses `ts-node/register` to transpile on the fly.
+* `./bin/balena-dev.js` uses `ts-node/register` to transpile on the fly.
Before opening a PR, test your changes with `npm test`. Keep compatibility in mind, as the CLI is
meant to run on Linux, macOS and Windows. balena CI will run test code on all three platforms, but
@@ -230,7 +230,7 @@ be automatically invalidated if `npm link` is used or if manual modifications ar
`node_modules` folder. In this situation:
* Manually delete the module cache file (typically `~/.balena/cli-module-cache.json`), or
-* Use the `bin/balena-dev` entry point (instead of `bin/balena`) as it does not activate
+* Use the `bin/balena-dev.js` entry point (instead of `bin/balena.js`) as it does not activate
`fast-boot2`.
## TypeScript and oclif
diff --git a/INSTALL-ADVANCED.md b/INSTALL-ADVANCED.md
index 9b4f2e02..9cac0c61 100644
--- a/INSTALL-ADVANCED.md
+++ b/INSTALL-ADVANCED.md
@@ -40,7 +40,7 @@ By default, the CLI is installed to the following folders:
OS | Folders
--- | ---
Windows: | `C:\Program Files\balena-cli\`
-macOS: | `/usr/local/lib/balena-cli/`
`/usr/local/bin/balena`
+macOS: | `/usr/local/lib/balena-cli/`
`/usr/local/bin/balena.js`
## Standalone Zip Package
@@ -65,7 +65,7 @@ macOS: | `/usr/local/lib/balena-cli/`
`/usr/local/bin/balena`
> these "compact" Linux distributions, because of the alternative C libraries they ship with.
> For these, consider the [NPM Installation](#npm-installation) option.
> * Note that moving the `balena` executable out of the extracted `balena-cli` folder on its own
-> (e.g. moving it to `/usr/local/bin/balena`) will **not** work, as it depends on the other
+> (e.g. moving it to `/usr/local/bin/balena.js`) will **not** work, as it depends on the other
> folders and files also present in the `balena-cli` folder.
To update the CLI to a new version, download a new release zip file and replace the previous
diff --git a/automation/capitanodoc/index.ts b/automation/capitanodoc/index.ts
index 0c605cf0..84f62003 100644
--- a/automation/capitanodoc/index.ts
+++ b/automation/capitanodoc/index.ts
@@ -83,6 +83,7 @@ function importOclifCommands(jsFilename: string): OclifCommand[] {
// an error when parsed. This should be improved so that `usage` does not have
// to be overridden if not necessary.
+ // TODO: FIX ME ESM
const command: OclifCommand =
jsFilename === 'help'
? (new FakeHelpCommand() as unknown as OclifCommand)
diff --git a/automation/utils.ts b/automation/utils.ts
index 87921024..84b6acb2 100644
--- a/automation/utils.ts
+++ b/automation/utils.ts
@@ -97,7 +97,7 @@ export function loadPackageJson() {
* @returns The program's full path, e.g. 'C:\WINDOWS\System32\OpenSSH\ssh.EXE'
*/
export async function which(program: string): Promise {
- const whichMod = await import('which');
+ const { default: whichMod } = await import('which');
let programPath: string;
try {
programPath = await whichMod(program);
diff --git a/bin/balena-dev b/bin/balena-dev.js
similarity index 97%
rename from bin/balena-dev
rename to bin/balena-dev.js
index ceaf47c4..9bc7f43c 100755
--- a/bin/balena-dev
+++ b/bin/balena-dev.js
@@ -2,7 +2,7 @@
// ****************************************************************************
// THIS IS FOR DEV PURPOSES ONLY AND WILL NOT BE PART OF THE PUBLISHED PACKAGE
-// Before opening a PR you should build and test your changes using bin/balena
+// Before opening a PR you should build and test your changes using bin/balena.js
// ****************************************************************************
// We boost the threadpool size as ext2fs can deadlock with some
@@ -57,7 +57,10 @@ require('ts-node').register({
project: path.join(rootDir, 'tsconfig.json'),
transpileOnly: true,
});
-require('../lib/app').run(undefined, { dir: __dirname, development: true });
+require('../lib/app').run(undefined, {
+ dir: import.meta.url,
+ development: true,
+});
// Modify package.json oclif paths from build/ -> lib/, or vice versa
function modifyOclifPaths(revert) {
diff --git a/bin/balena b/bin/balena.js
similarity index 67%
rename from bin/balena
rename to bin/balena.js
index 6a27aff0..8927d4c3 100755
--- a/bin/balena
+++ b/bin/balena.js
@@ -9,13 +9,13 @@ process.env.OCLIF_TS_NODE = 0;
async function run() {
// Use fast-boot to cache require lookups, speeding up startup
- await require('../build/fast-boot').start();
+ await (await import('../build/fast-boot.js')).start();
// Set the desired es version for downstream modules that support it
- require('@balena/es-version').set('es2018');
+ (await import('@balena/es-version')).set('es2018');
// Run the CLI
- await require('../build/app').run(undefined, { dir: __dirname });
+ await (await import('../build/app.js')).run(undefined, { dir: import.meta.url });
}
-run();
+await run();
diff --git a/lib/app.ts b/lib/app.ts
index 4794bd51..654d94e8 100644
--- a/lib/app.ts
+++ b/lib/app.ts
@@ -15,23 +15,23 @@
* limitations under the License.
*/
-import * as packageJSON from '../package.json';
+import packageJSON from '../package.json' assert {type: 'json'};
import {
AppOptions,
checkDeletedCommand,
preparseArgs,
unsupportedFlag,
-} from './preparser';
-import { CliSettings } from './utils/bootstrap';
-import { onceAsync } from './utils/lazy';
-import { run as mainRun, settings } from '@oclif/core';
+} from './preparser.js';
+import { CliSettings } from './utils/bootstrap.js';
+import { onceAsync } from './utils/lazy.js';
+import { run as mainRun, flush, settings } from '@oclif/core';
/**
* Sentry.io setup
* @see https://docs.sentry.io/error-reporting/quickstart/?platform=node
*/
export const setupSentry = onceAsync(async () => {
- const config = await import('./config');
+ const config = await import('./config.js');
const Sentry = await import('@sentry/node');
Sentry.init({
autoSessionTracking: false,
@@ -51,14 +51,14 @@ export const setupSentry = onceAsync(async () => {
async function checkNodeVersion() {
const validNodeVersions = packageJSON.engines.node;
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));
}
}
/** Setup balena-sdk options that are shared with imported packages */
-function setupBalenaSdkSharedOptions(settings: CliSettings) {
- const BalenaSdk = require('balena-sdk') as typeof import('balena-sdk');
+async function setupBalenaSdkSharedOptions(settings: CliSettings) {
+ const BalenaSdk = await import('balena-sdk');
BalenaSdk.setSharedOptions({
apiUrl: settings.get('apiUrl'),
dataDirectory: settings.get('dataDirectory'),
@@ -71,8 +71,8 @@ function setupBalenaSdkSharedOptions(settings: CliSettings) {
* leak detected. 11 error listeners added. Use emitter.setMaxListeners() to
* increase limit
*/
-export function setMaxListeners(maxListeners: number) {
- require('events').EventEmitter.defaultMaxListeners = maxListeners;
+export async function setMaxListeners(maxListeners: number) {
+ (await import('events')).EventEmitter.defaultMaxListeners = maxListeners;
}
/** Selected CLI initialization steps */
@@ -89,13 +89,13 @@ async function init() {
const settings = new CliSettings();
// 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);
+ await setupBalenaSdkSharedOptions(settings);
// check for CLI updates once a day
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) {
deprecationPromise = Promise.resolve();
} else {
- const { DeprecationChecker } = await import('./deprecation');
+ const { DeprecationChecker } = await import('./deprecation.js');
const deprecationChecker = new DeprecationChecker(packageJSON.version);
// warnAndAbortIfDeprecated uses previously cached data only
await deprecationChecker.warnAndAbortIfDeprecated();
@@ -137,7 +137,7 @@ async function oclifRun(command: string[], options: AppOptions) {
}
}
if (shouldFlush) {
- await import('@oclif/core/flush');
+ await flush();
}
// 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.
@@ -148,20 +148,20 @@ async function oclifRun(command: string[], options: AppOptions) {
// the try/catch block above, execution does not get past the
// Promise.all() call below, but I don't understand why.
if (isEEXIT) {
- (await import('./fast-boot')).stop();
+ (await import('./fast-boot.js')).stop();
}
})(!options.noFlush);
- const { trackPromise } = await import('./hooks/prerun/track');
+ const { trackPromise } = await import('./hooks/prerun/track.js');
await Promise.all([trackPromise, deprecationPromise, runPromise]);
}
-/** CLI entrypoint. Called by the `bin/balena` and `bin/balena-dev` scripts. */
+/** CLI entrypoint. Called by the `bin/balena.js` and `bin/balena-dev.js` scripts. */
export async function run(cliArgs = process.argv, options: AppOptions) {
try {
const { setOfflineModeEnvVars, normalizeEnvVars, pkgExec } = await import(
- './utils/bootstrap'
+ './utils/bootstrap.js'
);
setOfflineModeEnvVars();
normalizeEnvVars();
@@ -175,15 +175,15 @@ export async function run(cliArgs = process.argv, options: AppOptions) {
await init();
// Look for commands that have been removed and if so, exit with a notice
- checkDeletedCommand(cliArgs.slice(2));
+ await checkDeletedCommand(cliArgs.slice(2));
const args = await preparseArgs(cliArgs);
await oclifRun(args, options);
} catch (err) {
- await (await import('./errors')).handleError(err);
+ await (await import('./errors.js')).handleError(err);
} finally {
try {
- (await import('./fast-boot')).stop();
+ (await import('./fast-boot.js')).stop();
} catch (e) {
if (process.env.DEBUG) {
console.error(`[debug] Stopping fast-boot: ${e}`);
diff --git a/lib/auth/index.ts b/lib/auth/index.ts
index 2089eaad..79779212 100644
--- a/lib/auth/index.ts
+++ b/lib/auth/index.ts
@@ -14,8 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import { getBalenaSdk } from '../utils/lazy';
-import { LoginServer } from './server';
+import { getBalenaSdk } from '../utils/lazy.js';
+import { LoginServer } from './server.js';
/**
* @module auth
@@ -42,7 +42,7 @@ import { LoginServer } from './server';
* console.log("My session token is: #{sessionToken}")
*/
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 {
@@ -55,10 +55,10 @@ export async function login({ host = '127.0.0.1', port = 0 }) {
const loginUrl = await utils.getDashboardLoginURL(callbackUrl);
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 });
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
const token = await loginServer.awaitForToken();
await balena.auth.loginWithToken(token);
loginServer.shutdown();
diff --git a/lib/auth/server.ts b/lib/auth/server.ts
index df7880d4..72d5fdef 100644
--- a/lib/auth/server.ts
+++ b/lib/auth/server.ts
@@ -14,14 +14,14 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import * as bodyParser from 'body-parser';
+import bodyParser from 'body-parser';
import { EventEmitter } from 'events';
-import * as express from 'express';
+import express from 'express';
import type { Socket } from 'net';
-import * as path from 'path';
+import path from 'path';
-import * as utils from './utils';
-import { ExpectedError } from '../errors';
+import * as utils from './utils.js';
+import { ExpectedError } from '../errors.js';
export class LoginServer extends EventEmitter {
protected expressApp: express.Express;
@@ -56,7 +56,7 @@ export class LoginServer extends EventEmitter {
);
app.set('view engine', 'ejs');
- app.set('views', path.join(__dirname, 'pages'));
+ app.set('views', path.join(import.meta.url, 'pages'));
this.server = await new Promise((resolve, reject) => {
const callback = (err: Error) => {
diff --git a/lib/auth/utils.ts b/lib/auth/utils.ts
index 7956b55b..b528962f 100644
--- a/lib/auth/utils.ts
+++ b/lib/auth/utils.ts
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import { getBalenaSdk } from '../utils/lazy';
+import { getBalenaSdk } from '../utils/lazy.js';
/**
* Get dashboard CLI login URL
@@ -32,7 +32,7 @@ export async function getDashboardLoginURL(
const [{ URL }, dashboardUrl] = await Promise.all([
import('url'),
- getBalenaSdk().settings.get('dashboardUrl'),
+ (await getBalenaSdk()).settings.get('dashboardUrl'),
]);
return new URL(`/login/cli/${callbackUrl}`, dashboardUrl).href;
}
@@ -54,7 +54,7 @@ export async function loginIfTokenValid(token?: string): Promise {
if (!token) {
return false;
}
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
let currentToken;
try {
diff --git a/lib/command.ts b/lib/command.ts
index 1b260a35..b2442d2b 100644
--- a/lib/command.ts
+++ b/lib/command.ts
@@ -19,9 +19,9 @@ import { Command } from '@oclif/core';
import {
InsufficientPrivilegesError,
NotAvailableInOfflineModeError,
-} from './errors';
-import { stripIndent } from './utils/lazy';
-import * as output from './framework/output';
+} from './errors.js';
+import { stripIndent } from './utils/lazy.js';
+import * as output from './framework/output.js';
export default abstract class BalenaCommand extends Command {
/**
@@ -71,7 +71,7 @@ export default abstract class BalenaCommand extends Command {
* - other code needs to execute before check
*/
protected static async checkElevatedPrivileges() {
- const isElevated = await (await import('is-elevated'))();
+ const isElevated = await (await import('is-elevated')).default();
if (!isElevated) {
throw new InsufficientPrivilegesError(
'You need root/admin privileges to run this command',
@@ -94,7 +94,7 @@ export default abstract class BalenaCommand extends Command {
* @throws {NotLoggedInError}
*/
public static async checkLoggedIn() {
- await (await import('./utils/patterns')).checkLoggedIn();
+ await (await import('./utils/patterns.js')).checkLoggedIn();
}
/**
@@ -139,14 +139,14 @@ export default abstract class BalenaCommand extends Command {
* values from stdin based in configuration, minimising command implementation.
*/
protected async getStdin() {
- this.stdin = await (await import('get-stdin'))();
+ this.stdin = await (await import('get-stdin')).default();
}
/**
* Get a logger instance.
*/
protected static async getLogger() {
- return (await import('./utils/logger')).getLogger();
+ return (await import('./utils/logger.js')).default.getLogger();
}
protected async init() {
diff --git a/lib/commands/api-key/generate.ts b/lib/commands/api-key/generate.ts
index c9213b67..00076b47 100644
--- a/lib/commands/api-key/generate.ts
+++ b/lib/commands/api-key/generate.ts
@@ -16,10 +16,10 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import { ExpectedError } from '../../errors';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import { ExpectedError } from '../../errors.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
export default class GenerateCmd extends Command {
public static description = stripIndent`
@@ -53,7 +53,7 @@ export default class GenerateCmd extends Command {
let key;
try {
- key = await getBalenaSdk().models.apiKey.create(params.name);
+ key = await (await getBalenaSdk()).models.apiKey.create(params.name);
} catch (e) {
if (e.name === 'BalenaNotLoggedIn') {
throw new ExpectedError(stripIndent`
diff --git a/lib/commands/api-key/revoke.ts b/lib/commands/api-key/revoke.ts
index 27475f39..00051172 100644
--- a/lib/commands/api-key/revoke.ts
+++ b/lib/commands/api-key/revoke.ts
@@ -16,9 +16,9 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
export default class RevokeCmd extends Command {
public static description = stripIndent`
@@ -59,7 +59,8 @@ export default class RevokeCmd extends Command {
}
await Promise.all(
apiKeyIds.map(
- async (id) => await getBalenaSdk().models.apiKey.revoke(Number(id)),
+ async (id) =>
+ await (await getBalenaSdk()).models.apiKey.revoke(Number(id)),
),
);
console.log('Successfully revoked the given API keys');
diff --git a/lib/commands/api-keys/index.ts b/lib/commands/api-keys/index.ts
index be8de21b..32941004 100644
--- a/lib/commands/api-keys/index.ts
+++ b/lib/commands/api-keys/index.ts
@@ -16,9 +16,9 @@
*/
import { Flags } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy.js';
export default class ApiKeysCmd extends Command {
public static description = stripIndent`
@@ -46,15 +46,16 @@ export default class ApiKeysCmd extends Command {
public async run() {
const { flags: options } = await this.parse(ApiKeysCmd);
- const { getApplication } = await import('../../utils/sdk');
+ const { getApplication } = await import('../../utils/sdk.js');
+ const balena = await getBalenaSdk();
const actorId = options.fleet
? (
- await getApplication(getBalenaSdk(), options.fleet, {
+ await getApplication(balena, options.fleet, {
$select: 'actor',
})
).actor
- : await getBalenaSdk().auth.getActorId();
- const keys = await getBalenaSdk().pine.get({
+ : await balena.auth.getActorId();
+ const keys = await balena.pine.get({
resource: 'api_key',
options: {
$select: ['id', 'created_at', 'name', 'description', 'expiry_date'],
diff --git a/lib/commands/app/create.ts b/lib/commands/app/create.ts
index 5d82e33c..60baabc8 100644
--- a/lib/commands/app/create.ts
+++ b/lib/commands/app/create.ts
@@ -17,9 +17,9 @@
import { Flags, Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { stripIndent } from '../../utils/lazy.js';
export default class AppCreateCmd extends Command {
public static description = stripIndent`
@@ -77,7 +77,7 @@ export default class AppCreateCmd extends Command {
const { args: params, flags: options } = await this.parse(AppCreateCmd);
await (
- await import('../../utils/application-create')
+ await import('../../utils/application-create.js')
).applicationCreateBase('app', options, params);
}
}
diff --git a/lib/commands/block/create.ts b/lib/commands/block/create.ts
index efb5ced7..9372bff1 100644
--- a/lib/commands/block/create.ts
+++ b/lib/commands/block/create.ts
@@ -17,9 +17,9 @@
import { Flags, Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { stripIndent } from '../../utils/lazy.js';
export default class BlockCreateCmd extends Command {
public static description = stripIndent`
@@ -77,7 +77,7 @@ export default class BlockCreateCmd extends Command {
const { args: params, flags: options } = await this.parse(BlockCreateCmd);
await (
- await import('../../utils/application-create')
+ await import('../../utils/application-create.js')
).applicationCreateBase('block', options, params);
}
}
diff --git a/lib/commands/build/index.ts b/lib/commands/build/index.ts
index 44718584..c4669fe7 100644
--- a/lib/commands/build/index.ts
+++ b/lib/commands/build/index.ts
@@ -16,20 +16,23 @@
*/
import { Args, Flags } from '@oclif/core';
-import Command from '../../command';
-import { getBalenaSdk } from '../../utils/lazy';
-import * as cf from '../../utils/common-flags';
-import * as compose from '../../utils/compose';
+import Command from '../../command.js';
+import { getBalenaSdk } from '../../utils/lazy.js';
+import * as cf from '../../utils/common-flags.js';
+import * as compose from '../../utils/compose.js';
import type { ApplicationType, BalenaSDK } from 'balena-sdk';
import {
buildArgDeprecation,
dockerignoreHelp,
registrySecretsHelp,
-} from '../../utils/messages';
-import type { ComposeCliFlags, ComposeOpts } from '../../utils/compose-types';
-import { buildProject, composeCliFlags } from '../../utils/compose_ts';
-import type { BuildOpts, DockerCliFlags } from '../../utils/docker';
-import { dockerCliFlags } from '../../utils/docker';
+} from '../../utils/messages.js';
+import type {
+ ComposeCliFlags,
+ ComposeOpts,
+} from '../../utils/compose-types.js';
+import { buildProject, composeCliFlags } from '../../utils/compose_ts.js';
+import type { BuildOpts, DockerCliFlags } from '../../utils/docker.js';
+import { dockerCliFlags } from '../../utils/docker.js';
// 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
@@ -105,7 +108,7 @@ ${dockerignoreHelp}
(await import('events')).defaultMaxListeners = 1000;
- const sdk = getBalenaSdk();
+ const sdk = await getBalenaSdk();
const logger = await Command.getLogger();
logger.logDebug('Parsing input...');
@@ -148,14 +151,16 @@ ${dockerignoreHelp}
(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(
'You must specify either a fleet (-f), or the device type (-d) and architecture (-A)',
);
}
// Validate project directory
- const { validateProjectDirectory } = await import('../../utils/compose_ts');
+ const { validateProjectDirectory } = await import(
+ '../../utils/compose_ts.js'
+ );
const { dockerfilePath, registrySecrets } = await validateProjectDirectory(
sdk,
{
@@ -172,7 +177,7 @@ ${dockerignoreHelp}
protected async getAppAndResolveArch(opts: FlagsDef) {
if (opts.fleet) {
- const { getAppWithArch } = await import('../../utils/helpers');
+ const { getAppWithArch } = await import('../../utils/helpers.js');
const app = await getAppWithArch(opts.fleet);
opts.arch = app.arch;
opts.deviceType = app.is_for__device_type[0].slug;
@@ -180,8 +185,11 @@ ${dockerignoreHelp}
}
}
- protected async prepareBuild(options: FlagsDef) {
- const { getDocker, generateBuildOpts } = await import('../../utils/docker');
+ // TODO: FIX ME ESM
+ protected async prepareBuild(options: FlagsDef): Promise {
+ const { getDocker, generateBuildOpts } = await import(
+ '../../utils/docker.js'
+ );
const [docker, buildOpts, composeOpts] = await Promise.all([
getDocker(options),
generateBuildOpts(options),
@@ -209,7 +217,7 @@ ${dockerignoreHelp}
*/
protected async buildProject(
docker: import('dockerode'),
- logger: import('../../utils/logger'),
+ logger: import('../../utils/logger.js').default,
composeOpts: ComposeOpts,
opts: {
app?: {
@@ -221,7 +229,7 @@ ${dockerignoreHelp}
buildOpts: BuildOpts;
},
) {
- const { loadProject } = await import('../../utils/compose_ts');
+ const { loadProject } = await import('../../utils/compose_ts.js');
const project = await loadProject(
logger,
diff --git a/lib/commands/config/generate.ts b/lib/commands/config/generate.ts
index 59d77fb8..4615ec74 100644
--- a/lib/commands/config/generate.ts
+++ b/lib/commands/config/generate.ts
@@ -17,14 +17,14 @@
import { Flags } from '@oclif/core';
import type { Interfaces } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, getCliForm, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, getCliForm, stripIndent } from '../../utils/lazy.js';
import {
applicationIdInfo,
devModeInfo,
secureBootInfo,
-} from '../../utils/messages';
+} from '../../utils/messages.js';
import type { BalenaSDK, PineDeferred } from 'balena-sdk';
export default class ConfigGenerateCmd extends Command {
@@ -126,7 +126,7 @@ export default class ConfigGenerateCmd extends Command {
public static authenticated = true;
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, {
$select: 'slug',
$expand: {
@@ -137,7 +137,7 @@ export default class ConfigGenerateCmd extends Command {
public async run() {
const { flags: options } = await this.parse(ConfigGenerateCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
await this.validateOptions(options);
@@ -152,7 +152,7 @@ export default class ConfigGenerateCmd extends Command {
$expand: { is_of__device_type: { $select: 'slug' } },
});
if (!rawDevice.belongs_to__application) {
- const { ExpectedError } = await import('../../errors');
+ const { ExpectedError } = await import('../../errors.js');
throw new ExpectedError(stripIndent`
Device ${options.device} does not appear to belong to an accessible fleet.
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
if (options.fleet && options.deviceType) {
- const helpers = await import('../../utils/helpers');
+ const helpers = await import('../../utils/helpers.js');
if (
!(await helpers.areDeviceTypesCompatible(
resourceDeviceType,
deviceType,
))
) {
- const { ExpectedError } = await import('../../errors');
+ const { ExpectedError } = await import('../../errors.js');
throw new ExpectedError(
`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);
const { validateSecureBootOptionAndWarn } = await import(
- '../../utils/config'
+ '../../utils/config.js'
);
await validateSecureBootOptionAndWarn(
options.secureBoot,
@@ -211,7 +211,7 @@ export default class ConfigGenerateCmd extends Command {
// Generate config
const { generateDeviceConfig, generateApplicationConfig } = await import(
- '../../utils/config'
+ '../../utils/config.js'
);
let config;
@@ -250,7 +250,7 @@ export default class ConfigGenerateCmd extends Command {
protected async validateOptions(
options: Interfaces.InferredFlags,
) {
- const { ExpectedError } = await import('../../errors');
+ const { ExpectedError } = await import('../../errors.js');
if (options.device == null && options.fleet == null) {
throw new ExpectedError(this.missingDeviceOrAppMessage);
@@ -259,7 +259,7 @@ export default class ConfigGenerateCmd extends Command {
if (!options.fleet && options.deviceType) {
throw new ExpectedError(this.deviceTypeNotAllowedMessage);
}
- const { validateDevOptionAndWarn } = await import('../../utils/config');
+ const { validateDevOptionAndWarn } = await import('../../utils/config.js');
await validateDevOptionAndWarn(options.dev, options.version);
}
}
diff --git a/lib/commands/config/inject.ts b/lib/commands/config/inject.ts
index 6e344f70..05a267ab 100644
--- a/lib/commands/config/inject.ts
+++ b/lib/commands/config/inject.ts
@@ -16,9 +16,9 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getVisuals, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getVisuals, stripIndent } from '../../utils/lazy.js';
export default class ConfigInjectCmd extends Command {
public static description = stripIndent`
@@ -56,7 +56,7 @@ export default class ConfigInjectCmd extends Command {
public async run() {
const { args: params, flags: options } = await this.parse(ConfigInjectCmd);
- const { safeUmount } = await import('../../utils/umount');
+ const { safeUmount } = await import('../../utils/umount.js');
const drive =
options.drive || (await getVisuals().drive('Select the device/OS drive'));
diff --git a/lib/commands/config/read.ts b/lib/commands/config/read.ts
index 333fea87..3acd906d 100644
--- a/lib/commands/config/read.ts
+++ b/lib/commands/config/read.ts
@@ -15,9 +15,9 @@
* limitations under the License.
*/
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getVisuals, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getVisuals, stripIndent } from '../../utils/lazy.js';
export default class ConfigReadCmd extends Command {
public static description = stripIndent`
@@ -50,7 +50,7 @@ export default class ConfigReadCmd extends Command {
public async run() {
const { flags: options } = await this.parse(ConfigReadCmd);
- const { safeUmount } = await import('../../utils/umount');
+ const { safeUmount } = await import('../../utils/umount.js');
const drive =
options.drive || (await getVisuals().drive('Select the device drive'));
diff --git a/lib/commands/config/reconfigure.ts b/lib/commands/config/reconfigure.ts
index be9ab466..7e1d6b4e 100644
--- a/lib/commands/config/reconfigure.ts
+++ b/lib/commands/config/reconfigure.ts
@@ -16,9 +16,9 @@
*/
import { Flags } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getVisuals, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getVisuals, stripIndent } from '../../utils/lazy.js';
export default class ConfigReconfigureCmd extends Command {
public static description = stripIndent`
@@ -59,7 +59,7 @@ export default class ConfigReconfigureCmd extends Command {
public async run() {
const { flags: options } = await this.parse(ConfigReconfigureCmd);
- const { safeUmount } = await import('../../utils/umount');
+ const { safeUmount } = await import('../../utils/umount.js');
const drive =
options.drive || (await getVisuals().drive('Select the device drive'));
@@ -70,7 +70,7 @@ export default class ConfigReconfigureCmd extends Command {
await safeUmount(drive);
if (!uuid) {
- const { ExpectedError } = await import('../../errors');
+ const { ExpectedError } = await import('../../errors.js');
throw new ExpectedError(
`Error: UUID not found in 'config.json' file for '${drive}'`,
);
@@ -84,7 +84,7 @@ export default class ConfigReconfigureCmd extends Command {
configureCommand.push('--advanced');
}
- const { runCommand } = await import('../../utils/helpers');
+ const { runCommand } = await import('../../utils/helpers.js');
await runCommand(configureCommand);
console.info('Done');
diff --git a/lib/commands/config/write.ts b/lib/commands/config/write.ts
index e1323f5f..e70b1b4b 100644
--- a/lib/commands/config/write.ts
+++ b/lib/commands/config/write.ts
@@ -16,10 +16,11 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getVisuals, stripIndent } from '../../utils/lazy';
-
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getVisuals, stripIndent } from '../../utils/lazy.js';
+import { createRequire } from 'node:module';
+const require = createRequire(import.meta.url);
export default class ConfigWriteCmd extends Command {
public static description = stripIndent`
Write a key-value pair to the config.json file of an OS image or attached media.
@@ -61,7 +62,7 @@ export default class ConfigWriteCmd extends Command {
public async run() {
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 =
options.drive || (await getVisuals().drive('Select the device drive'));
diff --git a/lib/commands/deploy/index.ts b/lib/commands/deploy/index.ts
index c4be73c0..c8346f63 100644
--- a/lib/commands/deploy/index.ts
+++ b/lib/commands/deploy/index.ts
@@ -14,35 +14,34 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
import { Args, Flags } from '@oclif/core';
import type { ImageDescriptor } from '@balena/compose/dist/parse';
-import Command from '../../command';
-import { ExpectedError } from '../../errors';
-import { getBalenaSdk, getChalk, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import { ExpectedError } from '../../errors.js';
+import { getBalenaSdk, getChalk, stripIndent } from '../../utils/lazy.js';
import {
dockerignoreHelp,
registrySecretsHelp,
buildArgDeprecation,
-} from '../../utils/messages';
-import * as ca from '../../utils/common-args';
-import * as compose from '../../utils/compose';
+} from '../../utils/messages.js';
+import * as ca from '../../utils/common-args.js';
+import * as compose from '../../utils/compose.js';
import type {
BuiltImage,
ComposeCliFlags,
ComposeOpts,
Release as ComposeReleaseInfo,
-} from '../../utils/compose-types';
-import type { BuildOpts, DockerCliFlags } from '../../utils/docker';
+} from '../../utils/compose-types.js';
+import type { BuildOpts, DockerCliFlags } from '../../utils/docker.js';
import {
applyReleaseTagKeysAndValues,
buildProject,
composeCliFlags,
isBuildConfig,
parseReleaseTagKeysAndValues,
-} from '../../utils/compose_ts';
-import { dockerCliFlags } from '../../utils/docker';
+} from '../../utils/compose_ts.js';
+import { dockerCliFlags } from '../../utils/docker.js';
import type { ApplicationType, DeviceType, Release } from 'balena-sdk';
interface ApplicationWithArch {
@@ -173,9 +172,9 @@ ${dockerignoreHelp}
);
}
- const sdk = getBalenaSdk();
+ const sdk = await getBalenaSdk();
const { getRegistrySecrets, validateProjectDirectory } = await import(
- '../../utils/compose_ts'
+ '../../utils/compose_ts.js'
);
const { releaseTagKeys, releaseTagValues } = parseReleaseTagKeysAndValues(
@@ -199,10 +198,10 @@ ${dockerignoreHelp}
(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 dockerUtils = await import('../../utils/docker');
+ const dockerUtils = await import('../../utils/docker.js');
const [docker, buildOpts, composeOpts] = await Promise.all([
dockerUtils.getDocker(options),
dockerUtils.generateBuildOpts(options as FlagsDef),
@@ -232,7 +231,7 @@ ${dockerignoreHelp}
async deployProject(
docker: import('dockerode'),
- logger: import('../../utils/logger'),
+ logger: import('../../utils/logger.js').default,
composeOpts: ComposeOpts,
opts: {
app: ApplicationWithArch; // the application instance to deploy to
@@ -248,9 +247,9 @@ ${dockerignoreHelp}
) {
const _ = await import('lodash');
const doodles = await import('resin-doodles');
- const sdk = getBalenaSdk();
+ const sdk = await getBalenaSdk();
const { deployProject: $deployProject, loadProject } = await import(
- '../../utils/compose_ts'
+ '../../utils/compose_ts.js'
);
const appType = opts.app.application_type[0];
@@ -321,7 +320,7 @@ ${dockerignoreHelp}
builtImagesByService = _.keyBy(builtImages, 'serviceName');
}
const images: BuiltImage[] = project.descriptors.map(
- (d) =>
+ (d: any) =>
builtImagesByService[d.serviceName] ?? {
serviceName: d.serviceName,
name: (isBuildConfig(d.image) ? d.image.tag : d.image) || '',
@@ -332,7 +331,7 @@ ${dockerignoreHelp}
let release: Release | ComposeReleaseInfo['release'];
if (appType.slug === 'legacy-v1' || appType.slug === 'legacy-v2') {
- const { deployLegacy } = require('../../utils/deploy-legacy');
+ const { deployLegacy } = await import('../../utils/deploy-legacy.js');
const msg = getChalk().yellow(
'Target fleet requires legacy deploy method.',
diff --git a/lib/commands/device/deactivate.ts b/lib/commands/device/deactivate.ts
index 43afcc8e..63839056 100644
--- a/lib/commands/device/deactivate.ts
+++ b/lib/commands/device/deactivate.ts
@@ -16,9 +16,9 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
export default class DeviceDeactivateCmd extends Command {
public static description = stripIndent`
@@ -54,8 +54,8 @@ export default class DeviceDeactivateCmd extends Command {
const { args: params, flags: options } =
await this.parse(DeviceDeactivateCmd);
- const balena = getBalenaSdk();
- const patterns = await import('../../utils/patterns');
+ const balena = await getBalenaSdk();
+ const patterns = await import('../../utils/patterns.js');
const uuid = params.uuid;
const deactivationWarning = `
diff --git a/lib/commands/device/identify.ts b/lib/commands/device/identify.ts
index 7766a088..56364313 100644
--- a/lib/commands/device/identify.ts
+++ b/lib/commands/device/identify.ts
@@ -16,10 +16,10 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
-import { ExpectedError } from '../../errors';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
+import { ExpectedError } from '../../errors.js';
export default class DeviceIdentifyCmd extends Command {
public static description = stripIndent`
@@ -47,7 +47,7 @@ export default class DeviceIdentifyCmd extends Command {
public async run() {
const { args: params } = await this.parse(DeviceIdentifyCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
try {
await balena.models.device.identify(params.uuid);
diff --git a/lib/commands/device/index.ts b/lib/commands/device/index.ts
index 7ef83af0..1fe233d3 100644
--- a/lib/commands/device/index.ts
+++ b/lib/commands/device/index.ts
@@ -16,11 +16,11 @@
*/
import { Flags, Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { expandForAppName } from '../../utils/helpers';
-import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
-import { jsonInfo } from '../../utils/messages';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { expandForAppName } from '../../utils/helpers.js';
+import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy.js';
+import { jsonInfo } from '../../utils/messages.js';
import type { Application, Release } from 'balena-sdk';
@@ -79,7 +79,7 @@ export default class DeviceCmd extends Command {
public async run() {
const { args: params, flags: options } = await this.parse(DeviceCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
const device = (await balena.models.device.get(
params.uuid,
@@ -124,7 +124,7 @@ export default class DeviceCmd extends Command {
if (options.view) {
const open = await import('open');
const dashboardUrl = balena.models.device.getDashboardUrl(device.uuid);
- await open(dashboardUrl, { wait: false });
+ await open.default(dashboardUrl, { wait: false });
return;
}
diff --git a/lib/commands/device/init.ts b/lib/commands/device/init.ts
index b60fe073..ca6e57a4 100644
--- a/lib/commands/device/init.ts
+++ b/lib/commands/device/init.ts
@@ -16,11 +16,11 @@
*/
import { Flags } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
-import { applicationIdInfo } from '../../utils/messages';
-import { runCommand } from '../../utils/helpers';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
+import { applicationIdInfo } from '../../utils/messages.js';
+import { runCommand } from '../../utils/helpers.js';
interface FlagsDef {
fleet?: string;
@@ -113,15 +113,15 @@ export default class DeviceInitCmd extends Command {
// Imports
const { promisify } = await import('util');
- const rimraf = promisify(await import('rimraf'));
+ const rimraf = promisify((await import('rimraf')).default);
const tmp = await import('tmp');
const tmpNameAsync = promisify(tmp.tmpName);
tmp.setGracefulCleanup();
- const { downloadOSImage } = await import('../../utils/cloud');
- const { getApplication } = await import('../../utils/sdk');
+ const { downloadOSImage } = await import('../../utils/cloud.js');
+ const { getApplication } = await import('../../utils/sdk.js');
const logger = await Command.getLogger();
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
// Get application and
const application = options.fleet
@@ -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
const deviceUuid = balena.models.device.generateUniqueKey();
diff --git a/lib/commands/device/local-mode.ts b/lib/commands/device/local-mode.ts
index 1d048baf..20600b14 100644
--- a/lib/commands/device/local-mode.ts
+++ b/lib/commands/device/local-mode.ts
@@ -16,9 +16,9 @@
*/
import { Flags, Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
export default class DeviceLocalModeCmd extends Command {
public static description = stripIndent`
@@ -66,7 +66,7 @@ export default class DeviceLocalModeCmd extends Command {
const { args: params, flags: options } =
await this.parse(DeviceLocalModeCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
if (options.enable) {
await balena.models.device.enableLocalMode(params.uuid);
diff --git a/lib/commands/device/move.ts b/lib/commands/device/move.ts
index 20e4c9af..cc1ff77e 100644
--- a/lib/commands/device/move.ts
+++ b/lib/commands/device/move.ts
@@ -22,11 +22,11 @@ import type {
PineOptions,
PineTypedResult,
} from 'balena-sdk';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { ExpectedError } from '../../errors';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
-import { applicationIdInfo } from '../../utils/messages';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { ExpectedError } from '../../errors.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
+import { applicationIdInfo } from '../../utils/messages.js';
export default class DeviceMoveCmd extends Command {
public static description = stripIndent`
@@ -93,7 +93,7 @@ export default class DeviceMoveCmd extends Command {
public async run() {
const { args: params, flags: options } = await this.parse(DeviceMoveCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
// Split uuids string into array of uuids
const deviceUuids = params.uuid.split(',');
@@ -101,7 +101,7 @@ export default class DeviceMoveCmd extends Command {
const devices = await this.getDevices(balena, deviceUuids);
// Disambiguate application
- const { getApplication } = await import('../../utils/sdk');
+ const { getApplication } = await import('../../utils/sdk.js');
// Get destination application
const application = options.fleet
@@ -151,7 +151,7 @@ export default class DeviceMoveCmd extends Command {
})
.map((deviceType) => deviceType.id);
- const patterns = await import('../../utils/patterns');
+ const patterns = await import('../../utils/patterns.js');
try {
const application = await patterns.selectApplication(
{
diff --git a/lib/commands/device/os-update.ts b/lib/commands/device/os-update.ts
index 9b66b1b7..c5fe82fa 100644
--- a/lib/commands/device/os-update.ts
+++ b/lib/commands/device/os-update.ts
@@ -16,11 +16,11 @@
*/
import { Flags, Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent, getCliForm } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent, getCliForm } from '../../utils/lazy.js';
import type { Device } from 'balena-sdk';
-import { ExpectedError } from '../../errors';
+import { ExpectedError } from '../../errors.js';
export default class DeviceOsUpdateCmd extends Command {
public static description = stripIndent`
@@ -62,7 +62,7 @@ export default class DeviceOsUpdateCmd extends Command {
const { args: params, flags: options } =
await this.parse(DeviceOsUpdateCmd);
- const sdk = getBalenaSdk();
+ const sdk = await getBalenaSdk();
// Get device info
const { uuid, is_of__device_type, os_version, os_variant } =
@@ -119,7 +119,7 @@ export default class DeviceOsUpdateCmd extends Command {
});
}
- const patterns = await import('../../utils/patterns');
+ const patterns = await import('../../utils/patterns.js');
// Confirm and start update
await patterns.confirm(
options.yes || false,
diff --git a/lib/commands/device/pin.ts b/lib/commands/device/pin.ts
index 51f582bf..1d7031c1 100644
--- a/lib/commands/device/pin.ts
+++ b/lib/commands/device/pin.ts
@@ -16,10 +16,10 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
-import { getExpandedProp } from '../../utils/pine';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
+import { getExpandedProp } from '../../utils/pine.js';
export default class DevicePinCmd extends Command {
public static description = stripIndent`
@@ -55,7 +55,7 @@ export default class DevicePinCmd extends Command {
public async run() {
const { args: params } = await this.parse(DevicePinCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
const device = await balena.models.device.get(params.uuid, {
$expand: {
diff --git a/lib/commands/device/public-url.ts b/lib/commands/device/public-url.ts
index 51326070..c5a78ea4 100644
--- a/lib/commands/device/public-url.ts
+++ b/lib/commands/device/public-url.ts
@@ -16,10 +16,10 @@
*/
import { Flags, Args } from '@oclif/core';
-import Command from '../../command';
-import { ExpectedError } from '../../errors';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import { ExpectedError } from '../../errors.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
export default class DevicePublicUrlCmd extends Command {
public static description = stripIndent`
@@ -68,7 +68,7 @@ export default class DevicePublicUrlCmd extends Command {
const { args: params, flags: options } =
await this.parse(DevicePublicUrlCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
if (options.enable) {
// Enable public URL
diff --git a/lib/commands/device/purge.ts b/lib/commands/device/purge.ts
index a40d00e6..3403cfed 100644
--- a/lib/commands/device/purge.ts
+++ b/lib/commands/device/purge.ts
@@ -16,9 +16,9 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, getCliUx, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, getCliUx, stripIndent } from '../../utils/lazy.js';
export default class DevicePurgeCmd extends Command {
public static description = stripIndent`
@@ -53,7 +53,7 @@ export default class DevicePurgeCmd extends Command {
public async run() {
const { args: params } = await this.parse(DevicePurgeCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
const ux = getCliUx();
const deviceUuids = params.uuid.split(',');
diff --git a/lib/commands/device/reboot.ts b/lib/commands/device/reboot.ts
index daef864b..4641dfb9 100644
--- a/lib/commands/device/reboot.ts
+++ b/lib/commands/device/reboot.ts
@@ -16,9 +16,9 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
export default class DeviceRebootCmd extends Command {
public static description = stripIndent`
@@ -47,7 +47,7 @@ export default class DeviceRebootCmd extends Command {
public async run() {
const { args: params, flags: options } = await this.parse(DeviceRebootCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
// The SDK current throws "BalenaDeviceNotFound: Device not found: xxxxx"
// when the device is not online, which may be confusing.
diff --git a/lib/commands/device/register.ts b/lib/commands/device/register.ts
index 7a9d10b5..027e9b7b 100644
--- a/lib/commands/device/register.ts
+++ b/lib/commands/device/register.ts
@@ -16,11 +16,11 @@
*/
import { Flags } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import * as ca from '../../utils/common-args';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
-import { applicationIdInfo } from '../../utils/messages';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import * as ca from '../../utils/common-args.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
+import { applicationIdInfo } from '../../utils/messages.js';
export default class DeviceRegisterCmd extends Command {
public static description = stripIndent`
@@ -64,9 +64,9 @@ export default class DeviceRegisterCmd extends Command {
const { args: params, flags: options } =
await this.parse(DeviceRegisterCmd);
- const { getApplication } = await import('../../utils/sdk');
+ const { getApplication } = await import('../../utils/sdk.js');
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
const application = await getApplication(balena, params.fleet, {
$select: ['id', 'slug'],
diff --git a/lib/commands/device/rename.ts b/lib/commands/device/rename.ts
index be6c38f4..ca10f183 100644
--- a/lib/commands/device/rename.ts
+++ b/lib/commands/device/rename.ts
@@ -16,9 +16,9 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent, getCliForm } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent, getCliForm } from '../../utils/lazy.js';
export default class DeviceRenameCmd extends Command {
public static description = stripIndent`
@@ -54,7 +54,7 @@ export default class DeviceRenameCmd extends Command {
public async run() {
const { args: params } = await this.parse(DeviceRenameCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
const newName =
params.newName ||
diff --git a/lib/commands/device/restart.ts b/lib/commands/device/restart.ts
index 71f35f7b..c809f66d 100644
--- a/lib/commands/device/restart.ts
+++ b/lib/commands/device/restart.ts
@@ -16,9 +16,9 @@
*/
import { Flags, Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, getCliUx, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, getCliUx, stripIndent } from '../../utils/lazy.js';
import type {
BalenaSDK,
DeviceWithServiceDetails,
@@ -69,7 +69,7 @@ export default class DeviceRestartCmd extends Command {
public async run() {
const { args: params, flags: options } = await this.parse(DeviceRestartCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
const ux = getCliUx();
const deviceUuids = params.uuid.split(',');
@@ -94,8 +94,8 @@ export default class DeviceRestartCmd extends Command {
deviceUuid: string,
serviceNames: string[],
) {
- const { ExpectedError, instanceOf } = await import('../../errors');
- const { getExpandedProp } = await import('../../utils/pine');
+ const { ExpectedError, instanceOf } = await import('../../errors.js');
+ const { getExpandedProp } = await import('../../utils/pine.js');
// Get device
let device: DeviceWithServiceDetails;
@@ -161,7 +161,7 @@ export default class DeviceRestartCmd extends Command {
// 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.
// 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 {
const device = await balena.models.device.get(deviceUuid);
if (!device.is_online) {
diff --git a/lib/commands/device/rm.ts b/lib/commands/device/rm.ts
index 6f3cc482..0558bb57 100644
--- a/lib/commands/device/rm.ts
+++ b/lib/commands/device/rm.ts
@@ -16,9 +16,9 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
export default class DeviceRmCmd extends Command {
public static description = stripIndent`
@@ -55,8 +55,8 @@ export default class DeviceRmCmd extends Command {
public async run() {
const { args: params, flags: options } = await this.parse(DeviceRmCmd);
- const balena = getBalenaSdk();
- const patterns = await import('../../utils/patterns');
+ const balena = await getBalenaSdk();
+ const patterns = await import('../../utils/patterns.js');
// Confirm
const uuids = params.uuid.split(',');
diff --git a/lib/commands/device/shutdown.ts b/lib/commands/device/shutdown.ts
index 7da13ade..def53aef 100644
--- a/lib/commands/device/shutdown.ts
+++ b/lib/commands/device/shutdown.ts
@@ -16,10 +16,10 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
-import { ExpectedError } from '../../errors';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
+import { ExpectedError } from '../../errors.js';
export default class DeviceShutdownCmd extends Command {
public static description = stripIndent`
@@ -49,7 +49,7 @@ export default class DeviceShutdownCmd extends Command {
const { args: params, flags: options } =
await this.parse(DeviceShutdownCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
try {
await balena.models.device.shutdown(params.uuid, options);
diff --git a/lib/commands/device/start-service.ts b/lib/commands/device/start-service.ts
index 4637f221..b0163ccb 100644
--- a/lib/commands/device/start-service.ts
+++ b/lib/commands/device/start-service.ts
@@ -16,9 +16,9 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, getCliUx, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, getCliUx, stripIndent } from '../../utils/lazy.js';
import type { BalenaSDK } from 'balena-sdk';
export default class DeviceStartServiceCmd extends Command {
@@ -57,7 +57,7 @@ export default class DeviceStartServiceCmd extends Command {
public async run() {
const { args: params } = await this.parse(DeviceStartServiceCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
const ux = getCliUx();
const deviceUuids = params.uuid.split(',');
@@ -78,8 +78,8 @@ export default class DeviceStartServiceCmd extends Command {
deviceUuid: string,
serviceNames: string[],
) {
- const { ExpectedError } = await import('../../errors');
- const { getExpandedProp } = await import('../../utils/pine');
+ const { ExpectedError } = await import('../../errors.js');
+ const { getExpandedProp } = await import('../../utils/pine.js');
// Get device
const device = await balena.models.device.getWithServiceDetails(
diff --git a/lib/commands/device/stop-service.ts b/lib/commands/device/stop-service.ts
index b7aa53dc..686b3964 100644
--- a/lib/commands/device/stop-service.ts
+++ b/lib/commands/device/stop-service.ts
@@ -16,9 +16,9 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, getCliUx, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, getCliUx, stripIndent } from '../../utils/lazy.js';
import type { BalenaSDK } from 'balena-sdk';
export default class DeviceStopServiceCmd extends Command {
@@ -57,7 +57,7 @@ export default class DeviceStopServiceCmd extends Command {
public async run() {
const { args: params } = await this.parse(DeviceStopServiceCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
const ux = getCliUx();
const deviceUuids = params.uuid.split(',');
@@ -78,8 +78,8 @@ export default class DeviceStopServiceCmd extends Command {
deviceUuid: string,
serviceNames: string[],
) {
- const { ExpectedError } = await import('../../errors');
- const { getExpandedProp } = await import('../../utils/pine');
+ const { ExpectedError } = await import('../../errors.js');
+ const { getExpandedProp } = await import('../../utils/pine.js');
// Get device
const device = await balena.models.device.getWithServiceDetails(
diff --git a/lib/commands/device/track-fleet.ts b/lib/commands/device/track-fleet.ts
index edb164ef..d95c5ec5 100644
--- a/lib/commands/device/track-fleet.ts
+++ b/lib/commands/device/track-fleet.ts
@@ -16,9 +16,9 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
export default class DeviceTrackFleetCmd extends Command {
public static description = stripIndent`
@@ -46,7 +46,7 @@ export default class DeviceTrackFleetCmd extends Command {
public async run() {
const { args: params } = await this.parse(DeviceTrackFleetCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
await balena.models.device.trackApplicationRelease(params.uuid);
}
diff --git a/lib/commands/devices/index.ts b/lib/commands/devices/index.ts
index e7196c42..2d5190be 100644
--- a/lib/commands/devices/index.ts
+++ b/lib/commands/devices/index.ts
@@ -15,11 +15,11 @@
* limitations under the License.
*/
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { expandForAppName } from '../../utils/helpers';
-import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
-import { applicationIdInfo, jsonInfo } from '../../utils/messages';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { expandForAppName } from '../../utils/helpers.js';
+import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy.js';
+import { applicationIdInfo, jsonInfo } from '../../utils/messages.js';
import type { Device, PineOptions } from 'balena-sdk';
@@ -68,7 +68,7 @@ export default class DevicesCmd extends Command {
public async run() {
const { flags: options } = await this.parse(DevicesCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
const devicesOptions = {
...devicesSelectFields,
...expandForAppName,
@@ -78,7 +78,7 @@ export default class DevicesCmd extends Command {
const devices = (
await (async () => {
if (options.fleet != null) {
- const { getApplication } = await import('../../utils/sdk');
+ const { getApplication } = await import('../../utils/sdk.js');
const application = await getApplication(balena, options.fleet, {
$select: 'slug',
$expand: {
@@ -115,7 +115,7 @@ export default class DevicesCmd extends Command {
];
if (options.json) {
- const { pickAndRename } = await import('../../utils/helpers');
+ const { pickAndRename } = await import('../../utils/helpers.js');
const mapped = devices.map((device) => pickAndRename(device, fields));
console.log(JSON.stringify(mapped, null, 4));
} else {
diff --git a/lib/commands/devices/supported.ts b/lib/commands/devices/supported.ts
index 93305a41..21c74107 100644
--- a/lib/commands/devices/supported.ts
+++ b/lib/commands/devices/supported.ts
@@ -16,12 +16,12 @@
*/
import { Flags } from '@oclif/core';
import type * as BalenaSdk from 'balena-sdk';
-import * as _ from 'lodash';
-import Command from '../../command';
+import _ from 'lodash';
+import Command from '../../command.js';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
-import { CommandHelp } from '../../utils/oclif-utils';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy.js';
+import { CommandHelp } from '../../utils/oclif-utils.js';
export default class DevicesSupportedCmd extends Command {
public static description = stripIndent`
@@ -65,9 +65,9 @@ export default class DevicesSupportedCmd extends Command {
},
},
} satisfies BalenaSdk.PineOptions;
- const dts = (await getBalenaSdk().models.deviceType.getAllSupported(
- pineOptions,
- )) as Array<
+ const dts = (await (
+ await getBalenaSdk()
+ ).models.deviceType.getAllSupported(pineOptions)) as Array<
BalenaSdk.PineTypedResult
>;
interface DT {
diff --git a/lib/commands/env/add.ts b/lib/commands/env/add.ts
index 479e03c4..adc346eb 100644
--- a/lib/commands/env/add.ts
+++ b/lib/commands/env/add.ts
@@ -17,11 +17,11 @@
import { Args } from '@oclif/core';
import type * as BalenaSdk from 'balena-sdk';
-import Command from '../../command';
-import { ExpectedError } from '../../errors';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
-import { applicationIdInfo } from '../../utils/messages';
+import Command from '../../command.js';
+import { ExpectedError } from '../../errors.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
+import { applicationIdInfo } from '../../utils/messages.js';
interface FlagsDef {
fleet?: string;
@@ -128,7 +128,7 @@ export default class EnvAddCmd extends Command {
}
}
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
const reservedPrefixes = await getReservedPrefixes(balena);
const isConfigVar = reservedPrefixes.some((prefix) =>
params.name.startsWith(prefix),
@@ -185,7 +185,7 @@ async function resolveFleetSlugs(
fleetOption: string,
) {
const fleetSlugs: string[] = [];
- const { getFleetSlug } = await import('../../utils/sdk');
+ const { getFleetSlug } = await import('../../utils/sdk.js');
for (const appNameOrSlug of fleetOption.split(',')) {
try {
fleetSlugs.push(await getFleetSlug(balena, appNameOrSlug));
@@ -222,7 +222,7 @@ async function setServiceVars(
}
}
} else if (options.device) {
- const { getDeviceAndAppFromUUID } = await import('../../utils/cloud');
+ const { getDeviceAndAppFromUUID } = await import('../../utils/cloud.js');
for (const uuid of options.device.split(',')) {
let device;
let app;
diff --git a/lib/commands/env/rename.ts b/lib/commands/env/rename.ts
index 6f9a3b99..e9e384fa 100644
--- a/lib/commands/env/rename.ts
+++ b/lib/commands/env/rename.ts
@@ -15,12 +15,12 @@
* limitations under the License.
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
+import Command from '../../command.js';
-import * as cf from '../../utils/common-flags';
-import * as ec from '../../utils/env-common';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
-import { parseAsInteger } from '../../utils/validation';
+import * as cf from '../../utils/common-flags.js';
+import * as ec from '../../utils/env-common.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
+import { parseAsInteger } from '../../utils/validation.js';
export default class EnvRenameCmd extends Command {
public static description = stripIndent`
@@ -67,7 +67,9 @@ export default class EnvRenameCmd extends Command {
await Command.checkLoggedIn();
- await getBalenaSdk().pine.patch({
+ await (
+ await getBalenaSdk()
+ ).pine.patch({
resource: ec.getVarResourceName(opt.config, opt.device, opt.service),
id: params.id,
body: {
diff --git a/lib/commands/env/rm.ts b/lib/commands/env/rm.ts
index d3589001..d2ad3030 100644
--- a/lib/commands/env/rm.ts
+++ b/lib/commands/env/rm.ts
@@ -16,11 +16,11 @@
*/
import { Flags, Args } from '@oclif/core';
-import Command from '../../command';
+import Command from '../../command.js';
-import * as ec from '../../utils/env-common';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
-import { parseAsInteger } from '../../utils/validation';
+import * as ec from '../../utils/env-common.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
+import { parseAsInteger } from '../../utils/validation.js';
export default class EnvRmCmd extends Command {
public static description = stripIndent`
@@ -71,13 +71,13 @@ export default class EnvRmCmd extends Command {
await Command.checkLoggedIn();
- const { confirm } = await import('../../utils/patterns');
+ const { confirm } = await import('../../utils/patterns.js');
await confirm(
opt.yes || false,
'Are you sure you want to delete the environment variable?',
);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
await balena.pine.delete({
resource: ec.getVarResourceName(opt.config, opt.device, opt.service),
id: params.id,
diff --git a/lib/commands/envs/index.ts b/lib/commands/envs/index.ts
index 9434b7f9..82efaa56 100644
--- a/lib/commands/envs/index.ts
+++ b/lib/commands/envs/index.ts
@@ -17,12 +17,12 @@
import { Flags } from '@oclif/core';
import type { Interfaces } from '@oclif/core';
import type * as SDK from 'balena-sdk';
-import * as _ from 'lodash';
-import Command from '../../command';
-import { ExpectedError } from '../../errors';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
-import { applicationIdInfo } from '../../utils/messages';
+import _ from 'lodash';
+import Command from '../../command.js';
+import { ExpectedError } from '../../errors.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy.js';
+import { applicationIdInfo } from '../../utils/messages.js';
type FlagsDef = Interfaces.InferredFlags;
@@ -121,18 +121,18 @@ export default class EnvsCmd extends Command {
throw new ExpectedError('Missing --fleet or --device option');
}
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
let fleetSlug: string | undefined = options.fleet
? await (
- await import('../../utils/sdk')
+ await import('../../utils/sdk.js')
).getFleetSlug(balena, options.fleet)
: undefined;
let fullUUID: string | undefined; // as oppposed to the short, 7-char UUID
if (options.device) {
const { getDeviceAndMaybeAppFromUUID } = await import(
- '../../utils/cloud'
+ '../../utils/cloud.js'
);
const [device, app] = await getDeviceAndMaybeAppFromUUID(
balena,
@@ -186,7 +186,7 @@ export default class EnvsCmd extends Command {
}
if (options.json) {
- const { pickAndRename } = await import('../../utils/helpers');
+ const { pickAndRename } = await import('../../utils/helpers.js');
const mapped = varArray.map((o) => pickAndRename(o, fields));
this.log(JSON.stringify(mapped, null, 4));
} else {
diff --git a/lib/commands/fleet/create.ts b/lib/commands/fleet/create.ts
index 2d10c221..5026df92 100644
--- a/lib/commands/fleet/create.ts
+++ b/lib/commands/fleet/create.ts
@@ -17,9 +17,9 @@
import { Flags, Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { stripIndent } from '../../utils/lazy.js';
export default class FleetCreateCmd extends Command {
public static description = stripIndent`
@@ -77,7 +77,7 @@ export default class FleetCreateCmd extends Command {
const { args: params, flags: options } = await this.parse(FleetCreateCmd);
await (
- await import('../../utils/application-create')
+ await import('../../utils/application-create.js')
).applicationCreateBase('fleet', options, params);
}
}
diff --git a/lib/commands/fleet/index.ts b/lib/commands/fleet/index.ts
index b59c135a..4a35a0d9 100644
--- a/lib/commands/fleet/index.ts
+++ b/lib/commands/fleet/index.ts
@@ -17,11 +17,11 @@
import { Flags } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import * as ca from '../../utils/common-args';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
-import { applicationIdInfo } from '../../utils/messages';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import * as ca from '../../utils/common-args.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
+import { applicationIdInfo } from '../../utils/messages.js';
export default class FleetCmd extends Command {
public static description = stripIndent`
@@ -58,9 +58,9 @@ export default class FleetCmd extends Command {
public async run() {
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 = await getBalenaSdk();
const application = await getApplication(balena, params.fleet, {
$expand: {
@@ -70,7 +70,7 @@ export default class FleetCmd extends Command {
});
if (options.view) {
- const open = await import('open');
+ const { default: open } = await import('open');
const dashboardUrl = balena.models.application.getDashboardUrl(
application.id,
);
diff --git a/lib/commands/fleet/pin.ts b/lib/commands/fleet/pin.ts
index 2b9f6cc1..2239fb17 100644
--- a/lib/commands/fleet/pin.ts
+++ b/lib/commands/fleet/pin.ts
@@ -16,10 +16,10 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
-import { getExpandedProp } from '../../utils/pine';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
+import { getExpandedProp } from '../../utils/pine.js';
export default class FleetPinCmd extends Command {
public static description = stripIndent`
@@ -55,7 +55,7 @@ export default class FleetPinCmd extends Command {
public async run() {
const { args: params } = await this.parse(FleetPinCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
const fleet = await balena.models.application.get(params.slug, {
$expand: {
diff --git a/lib/commands/fleet/purge.ts b/lib/commands/fleet/purge.ts
index 5456ea0a..7748ccaa 100644
--- a/lib/commands/fleet/purge.ts
+++ b/lib/commands/fleet/purge.ts
@@ -15,11 +15,11 @@
* limitations under the License.
*/
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import * as ca from '../../utils/common-args';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
-import { applicationIdInfo } from '../../utils/messages';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import * as ca from '../../utils/common-args.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
+import { applicationIdInfo } from '../../utils/messages.js';
export default class FleetPurgeCmd extends Command {
public static description = stripIndent`
@@ -51,9 +51,9 @@ export default class FleetPurgeCmd extends Command {
public async run() {
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 = await getBalenaSdk();
// balena.models.application.purge only accepts a numeric id
// so we must first fetch the app to get it's id,
diff --git a/lib/commands/fleet/rename.ts b/lib/commands/fleet/rename.ts
index 9214d2e6..2722ee43 100644
--- a/lib/commands/fleet/rename.ts
+++ b/lib/commands/fleet/rename.ts
@@ -17,11 +17,11 @@
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import * as ca from '../../utils/common-args';
-import { getBalenaSdk, stripIndent, getCliForm } from '../../utils/lazy';
-import { applicationIdInfo } from '../../utils/messages';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import * as ca from '../../utils/common-args.js';
+import { getBalenaSdk, stripIndent, getCliForm } from '../../utils/lazy.js';
+import { applicationIdInfo } from '../../utils/messages.js';
export default class FleetRenameCmd extends Command {
public static description = stripIndent`
@@ -59,13 +59,15 @@ export default class FleetRenameCmd extends Command {
public async run() {
const { args: params } = await this.parse(FleetRenameCmd);
- const { validateApplicationName } = await import('../../utils/validation');
- const { ExpectedError } = await import('../../errors');
+ const { validateApplicationName } = await import(
+ '../../utils/validation.js'
+ );
+ const { ExpectedError } = await import('../../errors.js');
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
// 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, {
$select: ['id', 'app_name', 'slug'],
$expand: {
diff --git a/lib/commands/fleet/restart.ts b/lib/commands/fleet/restart.ts
index f9a8c4b6..f2e0db1e 100644
--- a/lib/commands/fleet/restart.ts
+++ b/lib/commands/fleet/restart.ts
@@ -15,11 +15,11 @@
* limitations under the License.
*/
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import * as ca from '../../utils/common-args';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
-import { applicationIdInfo } from '../../utils/messages';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import * as ca from '../../utils/common-args.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
+import { applicationIdInfo } from '../../utils/messages.js';
export default class FleetRestartCmd extends Command {
public static description = stripIndent`
@@ -50,9 +50,9 @@ export default class FleetRestartCmd extends Command {
public async run() {
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 = await getBalenaSdk();
// Disambiguate application
const application = await getApplication(balena, params.fleet, {
diff --git a/lib/commands/fleet/rm.ts b/lib/commands/fleet/rm.ts
index e75d1c04..3e358861 100644
--- a/lib/commands/fleet/rm.ts
+++ b/lib/commands/fleet/rm.ts
@@ -15,11 +15,11 @@
* limitations under the License.
*/
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import * as ca from '../../utils/common-args';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
-import { applicationIdInfo } from '../../utils/messages';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import * as ca from '../../utils/common-args.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
+import { applicationIdInfo } from '../../utils/messages.js';
export default class FleetRmCmd extends Command {
public static description = stripIndent`
@@ -54,9 +54,9 @@ export default class FleetRmCmd extends Command {
public async run() {
const { args: params, flags: options } = await this.parse(FleetRmCmd);
- const { confirm } = await import('../../utils/patterns');
- const { getApplication } = await import('../../utils/sdk');
- const balena = getBalenaSdk();
+ const { confirm } = await import('../../utils/patterns.js');
+ const { getApplication } = await import('../../utils/sdk.js');
+ const balena = await getBalenaSdk();
// Confirm
await confirm(
diff --git a/lib/commands/fleet/track-latest.ts b/lib/commands/fleet/track-latest.ts
index e05a9365..6f291056 100644
--- a/lib/commands/fleet/track-latest.ts
+++ b/lib/commands/fleet/track-latest.ts
@@ -16,9 +16,9 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
export default class FleetTrackLatestCmd extends Command {
public static description = stripIndent`
@@ -49,7 +49,7 @@ export default class FleetTrackLatestCmd extends Command {
public async run() {
const { args: params } = await this.parse(FleetTrackLatestCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
await balena.models.application.trackLatestRelease(params.slug);
}
diff --git a/lib/commands/fleets/index.ts b/lib/commands/fleets/index.ts
index fe649c18..c561501f 100644
--- a/lib/commands/fleets/index.ts
+++ b/lib/commands/fleets/index.ts
@@ -17,9 +17,9 @@
import type * as BalenaSdk from 'balena-sdk';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
interface ExtendedApplication extends ApplicationWithDeviceTypeSlug {
device_count: number;
@@ -52,7 +52,7 @@ export default class FleetsCmd extends Command {
public async run() {
const { flags: options } = await this.parse(FleetsCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
const pineOptions = {
$select: ['id', 'app_name', 'slug'],
diff --git a/lib/commands/internal/osinit.ts b/lib/commands/internal/osinit.ts
index 8bc12992..73d3a450 100644
--- a/lib/commands/internal/osinit.ts
+++ b/lib/commands/internal/osinit.ts
@@ -16,9 +16,9 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import { stripIndent } from '../../utils/lazy';
-import { CommandHelp } from '../../utils/oclif-utils';
+import Command from '../../command.js';
+import { stripIndent } from '../../utils/lazy.js';
+import { CommandHelp } from '../../utils/oclif-utils.js';
// 'Internal' commands are called during the execution of other commands.
// `osinit` is called during `os initialize`
@@ -63,7 +63,7 @@ export default class OsinitCmd extends Command {
const config = JSON.parse(params.config);
const { getManifest, osProgressHandler } = await import(
- '../../utils/helpers'
+ '../../utils/helpers.js'
);
const manifest = await getManifest(params.image, params.type);
diff --git a/lib/commands/join/index.ts b/lib/commands/join/index.ts
index 152381b3..b4f693d8 100644
--- a/lib/commands/join/index.ts
+++ b/lib/commands/join/index.ts
@@ -16,11 +16,11 @@
*/
import { Args, Flags } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
-import { applicationIdInfo } from '../../utils/messages';
-import { parseAsLocalHostnameOrIp } from '../../utils/validation';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
+import { applicationIdInfo } from '../../utils/messages.js';
+import { parseAsLocalHostnameOrIp } from '../../utils/validation.js';
export default class JoinCmd extends Command {
public static description = stripIndent`
@@ -78,8 +78,8 @@ export default class JoinCmd extends Command {
public async run() {
const { args: params, flags: options } = await this.parse(JoinCmd);
- const promote = await import('../../utils/promote');
- const sdk = getBalenaSdk();
+ const promote = await import('../../utils/promote.js');
+ const sdk = await getBalenaSdk();
const logger = await Command.getLogger();
return promote.join(
logger,
diff --git a/lib/commands/key/add.ts b/lib/commands/key/add.ts
index 797c251b..d61ebe29 100644
--- a/lib/commands/key/add.ts
+++ b/lib/commands/key/add.ts
@@ -16,10 +16,10 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import { ExpectedError } from '../../errors';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import { ExpectedError } from '../../errors.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
export default class KeyAddCmd extends Command {
public static description = stripIndent`
@@ -84,6 +84,6 @@ export default class KeyAddCmd extends Command {
throw new ExpectedError('No public key file or path provided.');
}
- await getBalenaSdk().models.key.create(params.name, key);
+ await (await getBalenaSdk()).models.key.create(params.name, key);
}
}
diff --git a/lib/commands/key/index.ts b/lib/commands/key/index.ts
index 895e7451..5df64480 100644
--- a/lib/commands/key/index.ts
+++ b/lib/commands/key/index.ts
@@ -16,10 +16,10 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
-import { parseAsInteger } from '../../utils/validation';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy.js';
+import { parseAsInteger } from '../../utils/validation.js';
export default class KeyCmd extends Command {
public static description = stripIndent`
@@ -49,7 +49,7 @@ export default class KeyCmd extends Command {
public async run() {
const { args: params } = await this.parse(KeyCmd);
- const key = await getBalenaSdk().models.key.get(params.id);
+ const key = await (await getBalenaSdk()).models.key.get(params.id);
// Use 'name' instead of 'title' to match dashboard.
const displayKey = {
diff --git a/lib/commands/key/rm.ts b/lib/commands/key/rm.ts
index 5e0ad100..c2df7d46 100644
--- a/lib/commands/key/rm.ts
+++ b/lib/commands/key/rm.ts
@@ -16,10 +16,10 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
-import { parseAsInteger } from '../../utils/validation';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
+import { parseAsInteger } from '../../utils/validation.js';
export default class KeyRmCmd extends Command {
public static description = stripIndent`
@@ -52,13 +52,13 @@ export default class KeyRmCmd extends Command {
public async run() {
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(
options.yes ?? false,
`Are you sure you want to delete key ${params.id}?`,
);
- await getBalenaSdk().models.key.remove(params.id);
+ await (await getBalenaSdk()).models.key.remove(params.id);
}
}
diff --git a/lib/commands/keys/index.ts b/lib/commands/keys/index.ts
index ca81f366..15f676b4 100644
--- a/lib/commands/keys/index.ts
+++ b/lib/commands/keys/index.ts
@@ -15,9 +15,9 @@
* limitations under the License.
*/
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy.js';
export default class KeysCmd extends Command {
public static description = stripIndent`
@@ -38,7 +38,7 @@ export default class KeysCmd extends Command {
public async run() {
await this.parse(KeysCmd);
- const keys = await getBalenaSdk().models.key.getAll();
+ const keys = await (await getBalenaSdk()).models.key.getAll();
// Use 'name' instead of 'title' to match dashboard.
const displayKeys: Array<{ id: number; name: string }> = keys.map((k) => {
diff --git a/lib/commands/leave/index.ts b/lib/commands/leave/index.ts
index 2365d007..8db65dd3 100644
--- a/lib/commands/leave/index.ts
+++ b/lib/commands/leave/index.ts
@@ -16,10 +16,10 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { stripIndent } from '../../utils/lazy';
-import { parseAsLocalHostnameOrIp } from '../../utils/validation';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { stripIndent } from '../../utils/lazy.js';
+import { parseAsLocalHostnameOrIp } from '../../utils/validation.js';
export default class LeaveCmd extends Command {
public static description = stripIndent`
@@ -62,7 +62,7 @@ export default class LeaveCmd extends Command {
public async run() {
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();
return promote.leave(logger, params.deviceIpOrHostname);
}
diff --git a/lib/commands/local/configure.ts b/lib/commands/local/configure.ts
index 53aa170d..6f2b84b4 100644
--- a/lib/commands/local/configure.ts
+++ b/lib/commands/local/configure.ts
@@ -17,9 +17,9 @@
import { Args } from '@oclif/core';
import { promisify } from 'util';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { stripIndent } from '../../utils/lazy.js';
export default class LocalConfigureCmd extends Command {
public static description = stripIndent`
@@ -53,8 +53,8 @@ export default class LocalConfigureCmd extends Command {
const { args: params } = await this.parse(LocalConfigureCmd);
const reconfix = await import('reconfix');
- const { denyMount, safeUmount } = await import('../../utils/umount');
- const Logger = await import('../../utils/logger');
+ const { denyMount, safeUmount } = await import('../../utils/umount.js');
+ const { default: Logger } = await import('../../utils/logger.js');
const logger = Logger.getLogger();
diff --git a/lib/commands/local/flash.ts b/lib/commands/local/flash.ts
index e2301718..f36e68d2 100644
--- a/lib/commands/local/flash.ts
+++ b/lib/commands/local/flash.ts
@@ -17,10 +17,10 @@
import { Args } from '@oclif/core';
import type { BlockDevice } from 'etcher-sdk/build/source-destination';
-import Command from '../../command';
-import { ExpectedError } from '../../errors';
-import * as cf from '../../utils/common-flags';
-import { getChalk, getVisuals, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import { ExpectedError } from '../../errors.js';
+import * as cf from '../../utils/common-flags.js';
+import { getChalk, getVisuals, stripIndent } from '../../utils/lazy.js';
export default class LocalFlashCmd extends Command {
public static description = stripIndent`
@@ -79,7 +79,7 @@ export default class LocalFlashCmd extends Command {
const drive = await this.getDrive(options);
- const { confirm } = await import('../../utils/patterns');
+ const { confirm } = await import('../../utils/patterns.js');
await confirm(
options.yes,
'This will erase the selected drive. Are you sure?',
diff --git a/lib/commands/login/index.ts b/lib/commands/login/index.ts
index 70d6c1c6..f87c788b 100644
--- a/lib/commands/login/index.ts
+++ b/lib/commands/login/index.ts
@@ -16,10 +16,10 @@
*/
import { Flags, Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent, getCliForm } from '../../utils/lazy';
-import { ExpectedError } from '../../errors';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent, getCliForm } from '../../utils/lazy.js';
+import { ExpectedError } from '../../errors.js';
import type { WhoamiResult } from 'balena-sdk';
interface FlagsDef {
@@ -122,8 +122,8 @@ export default class LoginCmd extends Command {
public async run() {
const { flags: options, args: params } = await this.parse(LoginCmd);
- const balena = getBalenaSdk();
- const messages = await import('../../utils/messages');
+ const balena = await getBalenaSdk();
+ const messages = await import('../../utils/messages.js');
const balenaUrl = await balena.settings.get('balenaUrl');
// Consolidate user/email options
@@ -186,7 +186,7 @@ ${messages.reachingOut}`);
type: 'input',
});
}
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
await balena.auth.loginWithToken(token!);
try {
if (!(await balena.auth.whoami())) {
@@ -202,20 +202,20 @@ ${messages.reachingOut}`);
}
// Credentials
else if (loginOptions.credentials) {
- const patterns = await import('../../utils/patterns');
+ const patterns = await import('../../utils/patterns.js');
return patterns.authenticate(loginOptions);
}
// Web
else if (loginOptions.web) {
- const auth = await import('../../auth');
+ const auth = await import('../../auth/index.js');
await auth.login({ port: loginOptions.port });
return;
} else {
- const patterns = await import('../../utils/patterns');
+ const patterns = await import('../../utils/patterns.js');
// User had not selected login preference, prompt interactively
const loginType = await patterns.askLoginType();
if (loginType === 'register') {
- const open = await import('open');
+ const { default: open } = await import('open');
const signupUrl = `https://dashboard.${balenaUrl}/signup`;
await open(signupUrl, { wait: false });
throw new ExpectedError(`Please sign up at ${signupUrl}`);
diff --git a/lib/commands/logout/index.ts b/lib/commands/logout/index.ts
index 5ea45963..b095c972 100644
--- a/lib/commands/logout/index.ts
+++ b/lib/commands/logout/index.ts
@@ -15,8 +15,8 @@
* limitations under the License.
*/
-import Command from '../../command';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
export default class LogoutCmd extends Command {
public static description = stripIndent`
@@ -30,6 +30,6 @@ export default class LogoutCmd extends Command {
public async run() {
await this.parse(LogoutCmd);
- await getBalenaSdk().auth.logout();
+ await (await getBalenaSdk()).auth.logout();
}
}
diff --git a/lib/commands/logs/index.ts b/lib/commands/logs/index.ts
index 4745211a..afacb998 100644
--- a/lib/commands/logs/index.ts
+++ b/lib/commands/logs/index.ts
@@ -16,9 +16,9 @@
*/
import { Flags, Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
import { LogMessage } from 'balena-sdk';
const MAX_RETRY = 1000;
@@ -95,15 +95,15 @@ export default class LogsCmd extends Command {
public async run() {
const { args: params, flags: options } = await this.parse(LogsCmd);
- const balena = getBalenaSdk();
- const { serviceIdToName } = await import('../../utils/cloud');
+ const balena = await getBalenaSdk();
+ const { serviceIdToName } = await import('../../utils/cloud.js');
const { connectAndDisplayDeviceLogs, displayLogObject } = await import(
- '../../utils/device/logs'
+ '../../utils/device/logs.js'
);
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();
@@ -132,13 +132,13 @@ export default class LogsCmd extends Command {
validateDotLocalUrl(params.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);
logger.logDebug('Checking we can access device');
try {
await deviceApi.ping();
} catch (e) {
- const { ExpectedError } = await import('../../errors');
+ const { ExpectedError } = await import('../../errors.js');
throw new ExpectedError(
`Cannot access device at address ${params.device}. Device may not be in local mode.`,
);
diff --git a/lib/commands/notes/index.ts b/lib/commands/notes/index.ts
index fb3e38fc..ca8ef440 100644
--- a/lib/commands/notes/index.ts
+++ b/lib/commands/notes/index.ts
@@ -16,10 +16,10 @@
*/
import { Flags, Args } from '@oclif/core';
-import Command from '../../command';
-import { ExpectedError } from '../../errors';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import { ExpectedError } from '../../errors.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
export default class NoteCmd extends Command {
public static description = stripIndent`
@@ -73,7 +73,7 @@ export default class NoteCmd extends Command {
throw new ExpectedError('Missing device UUID (--device)');
}
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
return balena.models.device.setNote(options.device, params.note);
}
diff --git a/lib/commands/orgs/index.ts b/lib/commands/orgs/index.ts
index f50604f8..548f67c4 100644
--- a/lib/commands/orgs/index.ts
+++ b/lib/commands/orgs/index.ts
@@ -15,9 +15,9 @@
* limitations under the License.
*/
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy.js';
export default class OrgsCmd extends Command {
public static description = stripIndent`
@@ -38,10 +38,10 @@ export default class OrgsCmd extends Command {
public async run() {
await this.parse(OrgsCmd);
- const { getOwnOrganizations } = await import('../../utils/sdk');
+ const { getOwnOrganizations } = await import('../../utils/sdk.js');
// Get organizations
- const organizations = await getOwnOrganizations(getBalenaSdk(), {
+ const organizations = await getOwnOrganizations(await getBalenaSdk(), {
$select: ['name', 'handle'],
});
diff --git a/lib/commands/os/build-config.ts b/lib/commands/os/build-config.ts
index 0b6d954a..685f2063 100644
--- a/lib/commands/os/build-config.ts
+++ b/lib/commands/os/build-config.ts
@@ -16,10 +16,10 @@
*/
import { Flags, Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getCliForm, stripIndent } from '../../utils/lazy';
-import * as _ from 'lodash';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getCliForm, stripIndent } from '../../utils/lazy.js';
+import _ from 'lodash';
import type { DeviceTypeJson } from 'balena-sdk';
export default class OsBuildConfigCmd extends Command {
@@ -82,7 +82,7 @@ export default class OsBuildConfigCmd extends Command {
async buildConfig(image: string, deviceTypeSlug: string, advanced: boolean) {
advanced = advanced || false;
- const { getManifest } = await import('../../utils/helpers');
+ const { getManifest } = await import('../../utils/helpers.js');
const deviceTypeManifest = await getManifest(image, deviceTypeSlug);
return this.buildConfigForDeviceType(deviceTypeManifest, advanced);
@@ -103,7 +103,7 @@ export default class OsBuildConfigCmd extends Command {
});
if (advancedGroup != null) {
- const { getGroupDefaults } = await import('../../utils/helpers');
+ const { getGroupDefaults } = await import('../../utils/helpers.js');
override = getGroupDefaults(advancedGroup);
}
}
diff --git a/lib/commands/os/configure.ts b/lib/commands/os/configure.ts
index 3853e18c..60a20347 100644
--- a/lib/commands/os/configure.ts
+++ b/lib/commands/os/configure.ts
@@ -19,16 +19,16 @@ import { Flags, Args } from '@oclif/core';
import type { Interfaces } from '@oclif/core';
import type * as BalenaSdk from 'balena-sdk';
import { promisify } from 'util';
-import * as _ from 'lodash';
-import Command from '../../command';
-import { ExpectedError } from '../../errors';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent, getCliForm } from '../../utils/lazy';
+import _ from 'lodash';
+import Command from '../../command.js';
+import { ExpectedError } from '../../errors.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent, getCliForm } from '../../utils/lazy.js';
import {
applicationIdInfo,
devModeInfo,
secureBootInfo,
-} from '../../utils/messages';
+} from '../../utils/messages.js';
const CONNECTIONS_FOLDER = '/system-connections';
@@ -175,16 +175,16 @@ export default class OsConfigureCmd extends Command {
const devInit = await import('balena-device-init');
const { promises: fs } = await import('fs');
const { generateDeviceConfig, generateApplicationConfig } = await import(
- '../../utils/config'
+ '../../utils/config.js'
);
- const helpers = await import('../../utils/helpers');
- const { getApplication } = await import('../../utils/sdk');
+ const helpers = await import('../../utils/helpers.js');
+ const { getApplication } = await import('../../utils/sdk.js');
let app: ApplicationWithDeviceTypeSlug | undefined;
let device;
let deviceTypeSlug: string;
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
if (options.device) {
device = (await balena.models.device.get(options.device, {
$expand: {
@@ -210,7 +210,7 @@ export default class OsConfigureCmd extends Command {
deviceTypeSlug,
);
- let configJson: import('../../utils/config').ImgConfig | undefined;
+ let configJson: import('../../utils/config.js').ImgConfig | undefined;
if (options.config) {
const rawConfig = await fs.readFile(options.config, 'utf8');
configJson = JSON.parse(rawConfig);
@@ -220,11 +220,11 @@ export default class OsConfigureCmd extends Command {
options.version ||
(await getOsVersionFromImage(params.image, deviceTypeManifest, devInit));
- const { validateDevOptionAndWarn } = await import('../../utils/config');
+ const { validateDevOptionAndWarn } = await import('../../utils/config.js');
await validateDevOptionAndWarn(options.dev, osVersion);
const { validateSecureBootOptionAndWarn } = await import(
- '../../utils/config'
+ '../../utils/config.js'
);
await validateSecureBootOptionAndWarn(
options.secureBoot,
@@ -362,7 +362,7 @@ async function checkDeviceTypeCompatibility(
},
) {
if (options['device-type']) {
- const helpers = await import('../../utils/helpers');
+ const helpers = await import('../../utils/helpers.js');
if (
!(await helpers.areDeviceTypesCompatible(
app.is_for__device_type[0].slug,
@@ -393,7 +393,7 @@ async function checkDeviceTypeCompatibility(
async function askQuestionsForDeviceType(
deviceType: BalenaSdk.DeviceTypeJson.DeviceType,
options: FlagsDef,
- configJson?: import('../../utils/config').ImgConfig,
+ configJson?: import('../../utils/config.js').ImgConfig,
): Promise {
const answerSources: any[] = [
{
@@ -416,7 +416,7 @@ async function askQuestionsForDeviceType(
isGroup: true,
});
if (!_.isEmpty(advancedGroup)) {
- const helpers = await import('../../utils/helpers');
+ const helpers = await import('../../utils/helpers.js');
answerSources.push(helpers.getGroupDefaults(advancedGroup));
}
}
diff --git a/lib/commands/os/download.ts b/lib/commands/os/download.ts
index e7ef1bda..0c9e0088 100644
--- a/lib/commands/os/download.ts
+++ b/lib/commands/os/download.ts
@@ -16,9 +16,9 @@
*/
import { Flags, Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { stripIndent } from '../../utils/lazy.js';
export default class OsDownloadCmd extends Command {
public static description = stripIndent`
@@ -95,7 +95,7 @@ export default class OsDownloadCmd extends Command {
await OsDownloadCmd.checkLoggedIn();
} catch (e) {
const { ExpectedError, NotLoggedInError } = await import(
- '../../errors'
+ '../../errors.js'
);
if (e instanceof NotLoggedInError) {
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 {
await downloadOSImage(params.type, options.output, options.version);
diff --git a/lib/commands/os/initialize.ts b/lib/commands/os/initialize.ts
index 322c1ab8..801b67c0 100644
--- a/lib/commands/os/initialize.ts
+++ b/lib/commands/os/initialize.ts
@@ -16,9 +16,9 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getCliForm, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getCliForm, stripIndent } from '../../utils/lazy.js';
const INIT_WARNING_MESSAGE = `
@@ -62,7 +62,7 @@ export default class OsInitializeCmd extends Command {
public async run() {
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}`);
@@ -75,13 +75,13 @@ export default class OsInitializeCmd extends Command {
});
if (answers.drive != null) {
- const { confirm } = await import('../../utils/patterns');
+ const { confirm } = await import('../../utils/patterns.js');
await confirm(
options.yes,
`This will erase ${answers.drive}. Are you sure?`,
`Going to erase ${answers.drive}.`,
);
- const { safeUmount } = await import('../../utils/umount');
+ const { safeUmount } = await import('../../utils/umount.js');
await safeUmount(answers.drive);
}
@@ -94,7 +94,7 @@ export default class OsInitializeCmd extends Command {
]);
if (answers.drive != null) {
- const { safeUmount } = await import('../../utils/umount');
+ const { safeUmount } = await import('../../utils/umount.js');
await safeUmount(answers.drive);
console.info(`You can safely remove ${answers.drive} now`);
}
diff --git a/lib/commands/os/versions.ts b/lib/commands/os/versions.ts
index d4f7f5b5..df3f967d 100644
--- a/lib/commands/os/versions.ts
+++ b/lib/commands/os/versions.ts
@@ -16,9 +16,9 @@
*/
import { Flags, Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { stripIndent } from '../../utils/lazy.js';
export default class OsVersionsCmd extends Command {
public static description = stripIndent`
@@ -54,7 +54,7 @@ export default class OsVersionsCmd extends Command {
const { args: params, flags: options } = await this.parse(OsVersionsCmd);
const { formatOsVersion, getOsVersions } = await import(
- '../../utils/cloud'
+ '../../utils/cloud.js'
);
const vs = await getOsVersions(params.type, !!options.esr);
diff --git a/lib/commands/preload/index.ts b/lib/commands/preload/index.ts
index 3ecee597..d5e2721a 100644
--- a/lib/commands/preload/index.ts
+++ b/lib/commands/preload/index.ts
@@ -15,21 +15,21 @@
* limitations under the License.
*/
-import Command from '../../command';
-import { ExpectedError } from '../../errors';
-import * as cf from '../../utils/common-flags';
+import Command from '../../command.js';
+import { ExpectedError } from '../../errors.js';
+import * as cf from '../../utils/common-flags.js';
import {
getBalenaSdk,
getCliForm,
getVisuals,
stripIndent,
-} from '../../utils/lazy';
-import { applicationIdInfo } from '../../utils/messages';
-import { dockerConnectionCliFlags } from '../../utils/docker';
-import { parseAsInteger } from '../../utils/validation';
+} from '../../utils/lazy.js';
+import { applicationIdInfo } from '../../utils/messages.js';
+import { dockerConnectionCliFlags } from '../../utils/docker.js';
+import { parseAsInteger } from '../../utils/validation.js';
import { Flags, Args } from '@oclif/core';
-import * as _ from 'lodash';
+import _ from 'lodash';
import type {
Application,
BalenaSDK,
@@ -39,6 +39,7 @@ import type {
Release,
} from 'balena-sdk';
import type { Preloader } from 'balena-preload';
+import type EventEmitter from 'events';
export default class PreloadCmd extends Command {
public static description = stripIndent`
@@ -144,11 +145,11 @@ Can be repeated to add multiple certificates.\
public async run() {
const { args: params, flags: options } = await this.parse(PreloadCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
const balenaPreload = await import('balena-preload');
const visuals = getVisuals();
const nodeCleanup = await import('node-cleanup');
- const { instanceOf } = await import('../../errors');
+ const { instanceOf } = await import('../../errors.js');
// Check image file exists
try {
@@ -172,7 +173,7 @@ Can be repeated to add multiple certificates.\
// Load app here, and use app slug from hereon
const fleetSlug: string | undefined = options.fleet
? await (
- await import('../../utils/sdk')
+ await import('../../utils/sdk.js')
).getFleetSlug(balena, options.fleet)
: undefined;
@@ -229,7 +230,7 @@ Can be repeated to add multiple certificates.\
}
// 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 preloader = new balenaPreload.Preloader(
undefined,
@@ -243,11 +244,11 @@ Can be repeated to add multiple certificates.\
pinDevice ?? false,
certificates,
additionalSpace,
- );
+ ) as Preloader & EventEmitter;
let gotSignal = false;
- nodeCleanup(function (_exitCode, signal) {
+ nodeCleanup.default(function (_exitCode, signal) {
if (signal) {
gotSignal = true;
nodeCleanup.uninstall(); // don't call cleanup handler again
@@ -326,7 +327,7 @@ Can be repeated to add multiple certificates.\
}
async getApplicationsWithSuccessfulBuilds(deviceTypeSlug: string) {
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
try {
await balena.models.deviceType.get(deviceTypeSlug);
@@ -434,7 +435,7 @@ Can be repeated to add multiple certificates.\
commit: string,
pinDevice: boolean | undefined,
) {
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
if (
this.isCurrentCommit(commit) ||
@@ -481,7 +482,7 @@ Would you like to disable automatic updates for this fleet now?\
}
async getAppWithReleases(balenaSdk: BalenaSDK, slug: string) {
- const { getApplication } = await import('../../utils/sdk');
+ const { getApplication } = await import('../../utils/sdk.js');
return await getApplication(balenaSdk, slug, {
$expand: this.applicationExpandOptions,
diff --git a/lib/commands/push/index.ts b/lib/commands/push/index.ts
index a00c0fb4..d67d702d 100644
--- a/lib/commands/push/index.ts
+++ b/lib/commands/push/index.ts
@@ -17,18 +17,18 @@
import { Flags, Args } from '@oclif/core';
import type { Interfaces } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
-import { dockerignoreHelp, registrySecretsHelp } from '../../utils/messages';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
+import { dockerignoreHelp, registrySecretsHelp } from '../../utils/messages.js';
import type { BalenaSDK } from 'balena-sdk';
-import { ExpectedError, instanceOf } from '../../errors';
+import { ExpectedError, instanceOf } from '../../errors.js';
import { RegistrySecrets } from '@balena/compose/dist/multibuild';
-import { lowercaseIfSlug } from '../../utils/normalization';
+import { lowercaseIfSlug } from '../../utils/normalization.js';
import {
applyReleaseTagKeysAndValues,
parseReleaseTagKeysAndValues,
-} from '../../utils/compose_ts';
+} from '../../utils/compose_ts.js';
enum BuildTarget {
Cloud,
@@ -232,8 +232,10 @@ export default class PushCmd extends Command {
const logger = await Command.getLogger();
logger.logDebug(`Using build source directory: ${options.source} `);
- const sdk = getBalenaSdk();
- const { validateProjectDirectory } = await import('../../utils/compose_ts');
+ const sdk = await getBalenaSdk();
+ const { validateProjectDirectory } = await import(
+ '../../utils/compose_ts.js'
+ );
const { dockerfilePath, registrySecrets } = await validateProjectDirectory(
sdk,
{
@@ -276,8 +278,8 @@ export default class PushCmd extends Command {
dockerfilePath: string,
registrySecrets: RegistrySecrets,
) {
- const remote = await import('../../utils/remote-build');
- const { getApplication } = await import('../../utils/sdk');
+ const remote = await import('../../utils/remote-build.js');
+ const { getApplication } = await import('../../utils/sdk.js');
// Check for invalid options
const localOnlyOptions: Array = [
@@ -356,7 +358,7 @@ export default class PushCmd extends Command {
'is only valid when pushing to a fleet',
);
- const deviceDeploy = await import('../../utils/device/deploy');
+ const deviceDeploy = await import('../../utils/device/deploy.js');
try {
await deviceDeploy.deployToDevice({
@@ -376,7 +378,7 @@ export default class PushCmd extends Command {
convertEol: !options['noconvert-eol'],
});
} catch (e) {
- const { BuildError } = await import('../../utils/device/errors');
+ const { BuildError } = await import('../../utils/device/errors.js');
if (instanceOf(e, BuildError)) {
throw new ExpectedError(e.toString());
} else {
@@ -387,7 +389,7 @@ export default class PushCmd extends Command {
protected async getBuildTarget(appOrDevice: string): Promise {
const { validateLocalHostnameOrIp } = await import(
- '../../utils/validation'
+ '../../utils/validation.js'
);
return validateLocalHostnameOrIp(appOrDevice)
diff --git a/lib/commands/release/finalize.ts b/lib/commands/release/finalize.ts
index 2ddb422e..d12f1a37 100644
--- a/lib/commands/release/finalize.ts
+++ b/lib/commands/release/finalize.ts
@@ -15,10 +15,10 @@
* limitations under the License.
*/
-import { commitOrIdArg } from '.';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
+import { commitOrIdArg } from './index.js';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
export default class ReleaseFinalizeCmd extends Command {
public static description = stripIndent`
@@ -58,7 +58,7 @@ export default class ReleaseFinalizeCmd extends Command {
public async run() {
const { args: params } = await this.parse(ReleaseFinalizeCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
const release = await balena.models.release.get(params.commitOrId, {
$select: ['id', 'is_final'],
diff --git a/lib/commands/release/index.ts b/lib/commands/release/index.ts
index a73a8d31..7062f8c5 100644
--- a/lib/commands/release/index.ts
+++ b/lib/commands/release/index.ts
@@ -14,15 +14,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
import { Flags, Args, type Interfaces } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy.js';
import type * as BalenaSdk from 'balena-sdk';
-import jsyaml = require('js-yaml');
-import { tryAsInteger } from '../../utils/validation';
-import { jsonInfo } from '../../utils/messages';
+import jsyaml from 'js-yaml';
+import { tryAsInteger } from '../../utils/validation.js';
+import { jsonInfo } from '../../utils/messages.js';
export const commitOrIdArg = Args.custom({
parse: async (commitOrId: string) => tryAsInteger(commitOrId),
@@ -66,7 +65,7 @@ export default class ReleaseCmd extends Command {
public async run() {
const { args: params, flags: options } = await this.parse(ReleaseCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
if (options.composition) {
await this.showComposition(params.commitOrId, balena);
} else {
diff --git a/lib/commands/release/invalidate.ts b/lib/commands/release/invalidate.ts
index f9f3f9b2..dee32bf0 100644
--- a/lib/commands/release/invalidate.ts
+++ b/lib/commands/release/invalidate.ts
@@ -15,10 +15,10 @@
* limitations under the License.
*/
-import { commitOrIdArg } from '.';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
+import { commitOrIdArg } from './index.js';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
export default class ReleaseInvalidateCmd extends Command {
public static description = stripIndent`
@@ -53,7 +53,7 @@ export default class ReleaseInvalidateCmd extends Command {
public async run() {
const { args: params } = await this.parse(ReleaseInvalidateCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
const release = await balena.models.release.get(params.commitOrId, {
$select: ['id', 'is_invalidated'],
diff --git a/lib/commands/release/validate.ts b/lib/commands/release/validate.ts
index 85ce4b45..82e88256 100644
--- a/lib/commands/release/validate.ts
+++ b/lib/commands/release/validate.ts
@@ -15,10 +15,10 @@
* limitations under the License.
*/
-import { commitOrIdArg } from '.';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
+import { commitOrIdArg } from './index.js';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
export default class ReleaseValidateCmd extends Command {
public static description = stripIndent`
@@ -52,7 +52,7 @@ export default class ReleaseValidateCmd extends Command {
public async run() {
const { args: params } = await this.parse(ReleaseValidateCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
const release = await balena.models.release.get(params.commitOrId, {
$select: ['id', 'is_invalidated'],
diff --git a/lib/commands/releases/index.ts b/lib/commands/releases/index.ts
index 5efc7ce0..c10a1bcf 100644
--- a/lib/commands/releases/index.ts
+++ b/lib/commands/releases/index.ts
@@ -16,12 +16,12 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
-import { applicationNameNote } from '../../utils/messages';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy.js';
+import { applicationNameNote } from '../../utils/messages.js';
import type * as BalenaSdk from 'balena-sdk';
-import { jsonInfo } from '../../utils/messages';
+import { jsonInfo } from '../../utils/messages.js';
export default class ReleasesCmd extends Command {
public static description = stripIndent`
@@ -66,8 +66,8 @@ export default class ReleasesCmd extends Command {
'is_final',
];
- const balena = getBalenaSdk();
- const { getFleetSlug } = await import('../../utils/sdk');
+ const balena = await getBalenaSdk();
+ const { getFleetSlug } = await import('../../utils/sdk.js');
const releases = await balena.models.release.getAllByApplication(
await getFleetSlug(balena, params.fleet),
diff --git a/lib/commands/scan/index.ts b/lib/commands/scan/index.ts
index fd6fdcc2..0bf15f63 100644
--- a/lib/commands/scan/index.ts
+++ b/lib/commands/scan/index.ts
@@ -16,9 +16,9 @@
*/
import { Flags } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getCliUx, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getCliUx, stripIndent } from '../../utils/lazy.js';
export default class ScanCmd extends Command {
public static description = stripIndent`
@@ -65,10 +65,10 @@ export default class ScanCmd extends Command {
public async run() {
const _ = await import('lodash');
const { discoverLocalBalenaOsDevices } = await import(
- '../../utils/discover'
+ '../../utils/discover.js'
);
const prettyjson = await import('prettyjson');
- const dockerUtils = await import('../../utils/docker');
+ const dockerUtils = await import('../../utils/docker.js');
const dockerPort = 2375;
const dockerTimeout = 2000;
diff --git a/lib/commands/settings/index.ts b/lib/commands/settings/index.ts
index f54c4db0..d672a98a 100644
--- a/lib/commands/settings/index.ts
+++ b/lib/commands/settings/index.ts
@@ -15,9 +15,9 @@
* limitations under the License.
*/
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
export default class SettingsCmd extends Command {
public static description = stripIndent`
@@ -36,7 +36,7 @@ export default class SettingsCmd extends Command {
public async run() {
await this.parse(SettingsCmd);
- const settings = await getBalenaSdk().settings.getAll();
+ const settings = await (await getBalenaSdk()).settings.getAll();
const prettyjson = await import('prettyjson');
console.log(prettyjson.render(settings));
diff --git a/lib/commands/ssh/index.ts b/lib/commands/ssh/index.ts
index 477736ff..a061e95e 100644
--- a/lib/commands/ssh/index.ts
+++ b/lib/commands/ssh/index.ts
@@ -16,13 +16,13 @@
*/
import { Flags, Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
import {
parseAsInteger,
validateLocalHostnameOrIp,
-} from '../../utils/validation';
+} from '../../utils/validation.js';
export default class SshCmd extends Command {
public static description = stripIndent`
@@ -111,7 +111,9 @@ export default class SshCmd extends Command {
// Local connection
if (validateLocalHostnameOrIp(params.fleetOrDevice)) {
- const { performLocalDeviceSSH } = await import('../../utils/device/ssh');
+ const { performLocalDeviceSSH } = await import(
+ '../../utils/device/ssh.js'
+ );
return await performLocalDeviceSSH({
hostname: params.fleetOrDevice,
port: options.port || 'local',
@@ -122,9 +124,11 @@ export default class SshCmd extends Command {
}
// Remote connection
- const { getProxyConfig } = await import('../../utils/helpers');
- const { getOnlineTargetDeviceUuid } = await import('../../utils/patterns');
- const sdk = getBalenaSdk();
+ const { getProxyConfig } = await import('../../utils/helpers.js');
+ const { getOnlineTargetDeviceUuid } = await import(
+ '../../utils/patterns.js'
+ );
+ const sdk = await getBalenaSdk();
const proxyConfig = getProxyConfig();
const useProxy = !!proxyConfig && !options.noproxy;
@@ -137,7 +141,7 @@ export default class SshCmd extends Command {
params.fleetOrDevice,
);
- const { which } = await import('../../utils/which');
+ const { which } = await import('../../utils/which.js');
const [whichProxytunnel, { username }, proxyUrl] = await Promise.all([
useProxy ? which('proxytunnel', false) : undefined,
@@ -189,7 +193,7 @@ export default class SshCmd extends Command {
let containerId: string | undefined;
if (params.service != null) {
const { getContainerIdForService } = await import(
- '../../utils/device/ssh'
+ '../../utils/device/ssh.js'
);
containerId = await getContainerIdForService({
deviceUuid,
@@ -207,7 +211,7 @@ export default class SshCmd extends Command {
} else {
accessCommand = `host ${deviceUuid}`;
}
- const { runRemoteCommand } = await import('../../utils/ssh');
+ const { runRemoteCommand } = await import('../../utils/ssh.js');
await runRemoteCommand({
cmd: accessCommand,
hostname: `ssh.${proxyUrl}`,
diff --git a/lib/commands/support/index.ts b/lib/commands/support/index.ts
index 84af6f4c..14521de5 100644
--- a/lib/commands/support/index.ts
+++ b/lib/commands/support/index.ts
@@ -16,11 +16,11 @@
*/
import { Flags, Args } from '@oclif/core';
-import Command from '../../command';
-import { ExpectedError } from '../../errors';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, getCliUx, stripIndent } from '../../utils/lazy';
-import { applicationIdInfo } from '../../utils/messages';
+import Command from '../../command.js';
+import { ExpectedError } from '../../errors.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, getCliUx, stripIndent } from '../../utils/lazy.js';
+import { applicationIdInfo } from '../../utils/messages.js';
export default class SupportCmd extends Command {
public static description = stripIndent`
@@ -77,7 +77,7 @@ export default class SupportCmd extends Command {
public async run() {
const { args: params, flags: options } = await this.parse(SupportCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
const ux = getCliUx();
const enabling = params.action === 'enable';
@@ -116,7 +116,7 @@ export default class SupportCmd extends Command {
ux.action.stop();
}
- const { getFleetSlug } = await import('../../utils/sdk');
+ const { getFleetSlug } = await import('../../utils/sdk.js');
// Process applications
for (const appName of appNames) {
diff --git a/lib/commands/tag/rm.ts b/lib/commands/tag/rm.ts
index 057418f4..d0e6222e 100644
--- a/lib/commands/tag/rm.ts
+++ b/lib/commands/tag/rm.ts
@@ -16,10 +16,10 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
-import { applicationIdInfo } from '../../utils/messages';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
+import { applicationIdInfo } from '../../utils/messages.js';
export default class TagRmCmd extends Command {
public static description = stripIndent`
@@ -68,16 +68,16 @@ export default class TagRmCmd extends Command {
public async run() {
const { args: params, flags: options } = await this.parse(TagRmCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
// Check user has specified one of application/device/release
if (!options.fleet && !options.device && !options.release) {
- const { ExpectedError } = await import('../../errors');
+ const { ExpectedError } = await import('../../errors.js');
throw new ExpectedError(TagRmCmd.missingResourceMessage);
}
if (options.fleet) {
- const { getFleetSlug } = await import('../../utils/sdk');
+ const { getFleetSlug } = await import('../../utils/sdk.js');
return balena.models.application.tags.remove(
await getFleetSlug(balena, options.fleet),
params.tagKey,
@@ -88,7 +88,7 @@ export default class TagRmCmd extends Command {
}
if (options.release) {
const { disambiguateReleaseParam } = await import(
- '../../utils/normalization'
+ '../../utils/normalization.js'
);
const releaseParam = await disambiguateReleaseParam(
balena,
diff --git a/lib/commands/tag/set.ts b/lib/commands/tag/set.ts
index d77e4190..6156be86 100644
--- a/lib/commands/tag/set.ts
+++ b/lib/commands/tag/set.ts
@@ -16,10 +16,10 @@
*/
import { Args } from '@oclif/core';
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
-import { applicationIdInfo } from '../../utils/messages';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
+import { applicationIdInfo } from '../../utils/messages.js';
export default class TagSetCmd extends Command {
public static description = stripIndent`
@@ -81,18 +81,18 @@ export default class TagSetCmd extends Command {
public async run() {
const { args: params, flags: options } = await this.parse(TagSetCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
// Check user has specified one of application/device/release
if (!options.fleet && !options.device && !options.release) {
- const { ExpectedError } = await import('../../errors');
+ const { ExpectedError } = await import('../../errors.js');
throw new ExpectedError(TagSetCmd.missingResourceMessage);
}
params.value ??= '';
if (options.fleet) {
- const { getFleetSlug } = await import('../../utils/sdk');
+ const { getFleetSlug } = await import('../../utils/sdk.js');
return balena.models.application.tags.set(
await getFleetSlug(balena, options.fleet),
params.tagKey,
@@ -108,7 +108,7 @@ export default class TagSetCmd extends Command {
}
if (options.release) {
const { disambiguateReleaseParam } = await import(
- '../../utils/normalization'
+ '../../utils/normalization.js'
);
const releaseParam = await disambiguateReleaseParam(
balena,
diff --git a/lib/commands/tags/index.ts b/lib/commands/tags/index.ts
index 9653c396..e444d00b 100644
--- a/lib/commands/tags/index.ts
+++ b/lib/commands/tags/index.ts
@@ -15,11 +15,11 @@
* limitations under the License.
*/
-import Command from '../../command';
-import { ExpectedError } from '../../errors';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
-import { applicationIdInfo } from '../../utils/messages';
+import Command from '../../command.js';
+import { ExpectedError } from '../../errors.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy.js';
+import { applicationIdInfo } from '../../utils/messages.js';
export default class TagsCmd extends Command {
public static description = stripIndent`
@@ -61,7 +61,7 @@ export default class TagsCmd extends Command {
public async run() {
const { flags: options } = await this.parse(TagsCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
// Check user has specified one of application/device/release
if (!options.fleet && !options.device && !options.release) {
@@ -71,7 +71,7 @@ export default class TagsCmd extends Command {
let tags;
if (options.fleet) {
- const { getFleetSlug } = await import('../../utils/sdk');
+ const { getFleetSlug } = await import('../../utils/sdk.js');
tags = await balena.models.application.tags.getAllByApplication(
await getFleetSlug(balena, options.fleet),
);
@@ -81,7 +81,7 @@ export default class TagsCmd extends Command {
}
if (options.release) {
const { disambiguateReleaseParam } = await import(
- '../../utils/normalization'
+ '../../utils/normalization.js'
);
const releaseParam = await disambiguateReleaseParam(
balena,
diff --git a/lib/commands/tunnel/index.ts b/lib/commands/tunnel/index.ts
index 91be2fe6..480487a1 100644
--- a/lib/commands/tunnel/index.ts
+++ b/lib/commands/tunnel/index.ts
@@ -16,15 +16,15 @@
*/
import { Flags, Args } from '@oclif/core';
-import Command from '../../command';
+import Command from '../../command.js';
import {
NoPortsDefinedError,
InvalidPortMappingError,
ExpectedError,
-} from '../../errors';
-import * as cf from '../../utils/common-flags';
-import { getBalenaSdk, stripIndent } from '../../utils/lazy';
-import { lowercaseIfSlug } from '../../utils/normalization';
+} from '../../errors.js';
+import * as cf from '../../utils/common-flags.js';
+import { getBalenaSdk, stripIndent } from '../../utils/lazy.js';
+import { lowercaseIfSlug } from '../../utils/normalization.js';
import type { Server, Socket } from 'net';
@@ -97,7 +97,7 @@ export default class TunnelCmd extends Command {
const { args: params, flags: options } = await this.parse(TunnelCmd);
const logger = await Command.getLogger();
- const sdk = getBalenaSdk();
+ const sdk = await getBalenaSdk();
const logConnection = (
fromHost: string,
@@ -122,7 +122,9 @@ export default class TunnelCmd extends Command {
}
// Ascertain device uuid
- const { getOnlineTargetDeviceUuid } = await import('../../utils/patterns');
+ const { getOnlineTargetDeviceUuid } = await import(
+ '../../utils/patterns.js'
+ );
const uuid = await getOnlineTargetDeviceUuid(sdk, params.deviceOrFleet);
logger.logInfo(`Opening a tunnel to ${uuid}...`);
@@ -134,7 +136,7 @@ export default class TunnelCmd extends Command {
.map(async ({ localPort, localAddress, remotePort }) => {
try {
const { tunnelConnectionToDevice } = await import(
- '../../utils/tunnel'
+ '../../utils/tunnel.js'
);
const handler = await tunnelConnectionToDevice(uuid, remotePort, sdk);
diff --git a/lib/commands/util/available-drives.ts b/lib/commands/util/available-drives.ts
index ac71d201..8705dd77 100644
--- a/lib/commands/util/available-drives.ts
+++ b/lib/commands/util/available-drives.ts
@@ -15,9 +15,9 @@
* limitations under the License.
*/
-import Command from '../../command';
-import * as cf from '../../utils/common-flags';
-import { stripIndent, getChalk, getVisuals } from '../../utils/lazy';
+import Command from '../../command.js';
+import * as cf from '../../utils/common-flags.js';
+import { stripIndent, getChalk, getVisuals } from '../../utils/lazy.js';
export default class UtilAvailableDrivesCmd extends Command {
public static description = stripIndent`
diff --git a/lib/commands/version/index.ts b/lib/commands/version/index.ts
index 9c59a8cc..dd3cd19f 100644
--- a/lib/commands/version/index.ts
+++ b/lib/commands/version/index.ts
@@ -16,8 +16,8 @@
*/
import { Flags } from '@oclif/core';
-import Command from '../../command';
-import { stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import { stripIndent } from '../../utils/lazy.js';
export interface JsonVersions {
'balena-cli': string;
@@ -71,8 +71,9 @@ export default class VersionCmd extends Command {
public async run() {
const { flags: options } = await this.parse(VersionCmd);
+ const { default: packageJson } = await import('../../../package.json');
const versions: JsonVersions = {
- 'balena-cli': (await import('../../../package.json')).version,
+ 'balena-cli': packageJson.version,
'Node.js':
process.version && process.version.startsWith('v')
? process.version.slice(1)
diff --git a/lib/commands/whoami/index.ts b/lib/commands/whoami/index.ts
index adc81acd..c1987120 100644
--- a/lib/commands/whoami/index.ts
+++ b/lib/commands/whoami/index.ts
@@ -15,8 +15,8 @@
* limitations under the License.
*/
-import Command from '../../command';
-import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy';
+import Command from '../../command.js';
+import { getBalenaSdk, getVisuals, stripIndent } from '../../utils/lazy.js';
export default class WhoamiCmd extends Command {
public static description = stripIndent`
@@ -34,7 +34,7 @@ export default class WhoamiCmd extends Command {
public async run() {
await this.parse(WhoamiCmd);
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
const [whoamiResult, url] = await Promise.all([
balena.auth.whoami(),
diff --git a/lib/deprecation.ts b/lib/deprecation.ts
index 7a8762bb..5d56eb55 100644
--- a/lib/deprecation.ts
+++ b/lib/deprecation.ts
@@ -14,7 +14,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
+import { createRequire } from 'node:module';
+const require = createRequire(import.meta.url);
import type { BalenaSettingsStorage } from 'balena-settings-storage';
export interface ReleaseTimestampsByVersion {
@@ -106,7 +107,7 @@ export class DeprecationChecker {
const url = this.getNpmUrl(version);
let response: import('got').Response> | undefined;
try {
- response = await got(url, {
+ response = await got.default(url, {
responseType: 'json',
retry: 0,
timeout: 4000,
@@ -198,17 +199,16 @@ or release date not available`);
const nextMajorDate = new Date(nextMajorDateStr).getTime();
const daysElapsed = Math.trunc((this.now - nextMajorDate) / this.msInDay);
if (daysElapsed > this.expiryDays) {
- const { ExpectedError } = await import('./errors');
+ const { ExpectedError } = await import('./errors.js');
throw new ExpectedError(this.getExpiryMsg(daysElapsed));
} else if (daysElapsed > this.deprecationDays && process.stderr.isTTY) {
- console.error(this.getDeprecationMsg(daysElapsed));
+ console.error(await this.getDeprecationMsg(daysElapsed));
}
}
/** Separate function for the benefit of code testing */
- getDeprecationMsg(daysElapsed: number) {
- const { warnify } =
- require('./utils/messages') as typeof import('./utils/messages');
+ async getDeprecationMsg(daysElapsed: number) {
+ const { warnify } = await import('./utils/messages.js');
return warnify(`\
CLI version ${this.nextMajorVersion} was released ${daysElapsed} days ago: please upgrade.
This version of the balena CLI (${this.currentVersion}) will exit with an error
diff --git a/lib/errors.ts b/lib/errors.ts
index 157bc318..f7c862bd 100644
--- a/lib/errors.ts
+++ b/lib/errors.ts
@@ -15,12 +15,12 @@ limitations under the License.
*/
import type { BalenaError } from 'balena-errors';
-import * as _ from 'lodash';
+import _ from 'lodash';
import * as os from 'os';
import { TypedError } from 'typed-error';
-import { getChalk, stripIndent } from './utils/lazy';
-import { getHelp } from './utils/messages';
-import { CliSettings } from './utils/bootstrap';
+import { getChalk, stripIndent } from './utils/lazy.js';
+import { getHelp } from './utils/messages.js';
+import { CliSettings } from './utils/bootstrap.js';
export class ExpectedError extends TypedError {
public code?: string;
diff --git a/lib/events.ts b/lib/events.ts
index fd0f74f6..0dd2bd38 100644
--- a/lib/events.ts
+++ b/lib/events.ts
@@ -15,8 +15,8 @@
* limitations under the License.
*/
-import * as packageJSON from '../package.json';
-import { stripIndent } from './utils/lazy';
+import packageJSON from '../package.json' assert {type: 'json'};
+import { stripIndent } from './utils/lazy.js';
/**
* Track balena CLI usage events (product improvement analytics).
@@ -44,7 +44,7 @@ export async function trackCommand(commandSignature: string) {
scope.setExtra('command', commandSignature);
});
}
- const { getCachedUsername } = await import('./utils/bootstrap');
+ const { getCachedUsername } = await import('./utils/bootstrap.js');
let username: string | undefined;
try {
username = (await getCachedUsername())?.username;
@@ -99,7 +99,7 @@ async function sendEvent(balenaUrl: string, event: string, username?: string) {
const url = `https://data.${balenaUrl}/amplitude/2/httpapi`;
try {
- await got.post(url, {
+ await got.default.post(url, {
json: trackData,
retry: 0,
timeout: {
diff --git a/lib/fast-boot.ts b/lib/fast-boot.ts
index bc842340..3d7b5f99 100644
--- a/lib/fast-boot.ts
+++ b/lib/fast-boot.ts
@@ -20,13 +20,14 @@
* we have permissions over the cache file before even attempting to load
* fast boot.
* DON'T IMPORT BALENA-CLI MODULES HERE, as this module is loaded directly
- * from `bin/balena`, before the CLI's entrypoint in `lib/app.ts`.
+ * from `bin/balena.js`, before the CLI's entrypoint in `lib/app.ts`.
*/
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
-
+import { createRequire } from 'node:module';
+const require = createRequire(import.meta.url);
const stat = process.pkg ? fs.statSync : fs.promises.stat;
let fastBootStarted = false;
@@ -66,15 +67,15 @@ async function $start() {
// such as `/usr[/local]/lib/balena-cli`, while being executed by
// a regular user account.
const cacheFile = path.join(dataDir, 'cli-module-cache.json');
- const root = path.join(__dirname, '..');
- const [, pJson, pStat, nStat] = await Promise.all([
+ const root = path.join(import.meta.url, '..');
+ const [, pStat, nStat] = await Promise.all([
ensureCanWrite(dataDir, cacheFile),
- import('../package.json'),
stat(path.join(root, 'package.json'), { bigint: true }),
stat(path.join(root, 'npm-shrinkwrap.json'), { bigint: true }),
]);
// Include timestamps to account for dev-time changes to node_modules
- const cacheKiller = `${pJson.version}-${pStat.mtimeMs}-${nStat.mtimeMs}`;
+ const pJson = await import('../package.json');
+ const cacheKiller = `${pJson.default.version}-${pStat.mtimeMs}-${nStat.mtimeMs}`;
require('fast-boot2').start({
cacheFile,
cacheKiller,
diff --git a/lib/framework/index.ts b/lib/framework/index.ts
index 24097f7b..65281aca 100644
--- a/lib/framework/index.ts
+++ b/lib/framework/index.ts
@@ -14,6 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import type { DataOutputOptions, DataSetOutputOptions } from './output';
+import type { DataOutputOptions, DataSetOutputOptions } from './output.js';
export { DataOutputOptions, DataSetOutputOptions };
diff --git a/lib/framework/output.ts b/lib/framework/output.ts
index e60c6850..c8adb6f2 100644
--- a/lib/framework/output.ts
+++ b/lib/framework/output.ts
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import { getCliUx, getChalk } from '../utils/lazy';
+import { getCliUx, getChalk } from '../utils/lazy.js';
export interface DataOutputOptions {
fields?: string;
diff --git a/lib/help.ts b/lib/help.ts
index e9644fee..124cc1a6 100644
--- a/lib/help.ts
+++ b/lib/help.ts
@@ -15,8 +15,8 @@
* limitations under the License.
*/
import { Help } from '@oclif/core';
-import * as indent from 'indent-string';
-import { getChalk } from './utils/lazy';
+import indent from 'indent-string';
+import { getChalk } from './utils/lazy.js';
// Partially overrides standard implementation of help plugin
// https://github.com/oclif/plugin-help/blob/master/src/index.ts
@@ -44,7 +44,7 @@ export default class BalenaHelp extends Help {
const subject = getHelpSubject(argv);
if (!subject) {
const verbose = argv.includes('-v') || argv.includes('--verbose');
- console.log(this.getCustomRootHelp(verbose));
+ console.log(await this.getCustomRootHelp(verbose));
return;
}
@@ -83,7 +83,7 @@ export default class BalenaHelp extends Help {
console.log(`command ${chalk.cyan.bold(subject)} not found`);
}
- getCustomRootHelp(showAllCommands: boolean): string {
+ async getCustomRootHelp(showAllCommands: boolean): Promise {
const { bold, cyan } = getChalk();
let commands = this.config.commands;
@@ -147,8 +147,9 @@ See: https://git.io/JRHUW#deprecation-policy`,
];
globalOps[0][0] = globalOps[0][0].padEnd(usageLength);
- const { deprecationPolicyNote, reachingOut } =
- require('./utils/messages') as typeof import('./utils/messages');
+ const { deprecationPolicyNote, reachingOut } = await import(
+ './utils/messages.js'
+ );
return [
bold('USAGE'),
diff --git a/lib/hooks/command-not-found/suggest.ts b/lib/hooks/command-not-found/suggest.ts
index 834dc003..952bde9f 100644
--- a/lib/hooks/command-not-found/suggest.ts
+++ b/lib/hooks/command-not-found/suggest.ts
@@ -16,7 +16,7 @@
*/
import type { Hook, Interfaces } from '@oclif/core';
-import { getChalk } from '../../utils/lazy';
+import { getChalk } from '../../utils/lazy.js';
/*
A modified version of the command-not-found plugin logic,
diff --git a/lib/hooks/prerun/track.ts b/lib/hooks/prerun/track.ts
index c57061aa..434ff534 100644
--- a/lib/hooks/prerun/track.ts
+++ b/lib/hooks/prerun/track.ts
@@ -33,7 +33,7 @@ export const trackPromise = new Promise((resolve) => {
* literally so: 'NAME' and 'VALUE' are NOT replaced with actual values.
*/
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 cmdSignature =
usage == null ? '*' : typeof usage === 'string' ? usage : usage.join(' ');
diff --git a/lib/preparser.ts b/lib/preparser.ts
index b09418a8..5fefe6d5 100644
--- a/lib/preparser.ts
+++ b/lib/preparser.ts
@@ -68,7 +68,7 @@ export async function preparseArgs(argv: string[]): Promise {
process.env.BLUEBIRD_LONG_STACK_TRACES = '1';
}
- const Logger = await import('./utils/logger');
+ const { default: Logger } = await import('./utils/logger.js');
Logger.command = cmdSlice[0];
let args = cmdSlice;
@@ -104,8 +104,8 @@ function extractBooleanFlag(argv: string[], flag: string): boolean {
* Check whether the command line refers to a command that has been deprecated
* and removed and, if so, exit with an informative error message.
*/
-export function checkDeletedCommand(argvSlice: string[]): void {
- const { ExpectedError } = require('./errors') as typeof import('./errors');
+export async function checkDeletedCommand(argvSlice: string[]): Promise {
+ const { ExpectedError } = await import('./errors.js');
if (argvSlice[0] === 'help') {
argvSlice = argvSlice.slice(1);
@@ -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`)
// by comparing with oclif style colon-separated subcommand list (e.g. `env:add`)
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();
return commandIds.includes(`${args[0] || ''}:${args[1] || ''}`);
}
diff --git a/lib/utils/application-create.ts b/lib/utils/application-create.ts
index 8a7e9a48..de336a8a 100644
--- a/lib/utils/application-create.ts
+++ b/lib/utils/application-create.ts
@@ -1,5 +1,5 @@
-import { ExpectedError } from '../errors';
-import { getBalenaSdk } from './lazy';
+import { ExpectedError } from '../errors.js';
+import { getBalenaSdk } from './lazy.js';
export interface FlagsDef {
organization?: string;
@@ -18,16 +18,18 @@ export async function applicationCreateBase(
) {
// Ascertain device type
const deviceType =
- options.type || (await (await import('./patterns')).selectDeviceType());
+ options.type || (await (await import('./patterns.js')).selectDeviceType());
// Ascertain organization
const organization =
options.organization?.toLowerCase() ||
- (await (await import('./patterns')).getAndSelectOrganization());
+ (await (await import('./patterns.js')).getAndSelectOrganization());
// Create application
try {
- const application = await getBalenaSdk().models.application.create({
+ const application = await (
+ await getBalenaSdk()
+ ).models.application.create({
name: params.name,
deviceType,
organization,
diff --git a/lib/utils/bootstrap.ts b/lib/utils/bootstrap.ts
index bcf5c587..addde949 100644
--- a/lib/utils/bootstrap.ts
+++ b/lib/utils/bootstrap.ts
@@ -22,6 +22,9 @@
* like Sentry error reporting, preparser, oclif parser and the like.
*/
+import { createRequire } from 'node:module';
+const require = createRequire(import.meta.url);
+
export class CliSettings {
public readonly settings: any;
constructor() {
@@ -139,7 +142,7 @@ export async function getCachedUsername(): Promise {
return cachedUsername;
}
const [{ getBalenaSdk }, { getStorage }, settings] = await Promise.all([
- import('./lazy'),
+ import('./lazy.js'),
import('balena-settings-storage'),
import('balena-settings-client'),
]);
@@ -167,7 +170,7 @@ export async function getCachedUsername(): Promise {
// ignore
}
try {
- const { username } = await getBalenaSdk().auth.getUserInfo();
+ const { username } = await (await getBalenaSdk()).auth.getUserInfo();
if (username) {
cachedUsername = { token, username };
await storage.set('cachedUsername', cachedUsername);
diff --git a/lib/utils/cloud.ts b/lib/utils/cloud.ts
index 590852c8..e7622cff 100644
--- a/lib/utils/cloud.ts
+++ b/lib/utils/cloud.ts
@@ -16,10 +16,10 @@
*/
import type * as SDK from 'balena-sdk';
-import * as _ from 'lodash';
-import { getBalenaSdk, getCliForm, getVisuals, stripIndent } from './lazy';
+import _ from 'lodash';
+import { getBalenaSdk, getCliForm, getVisuals, stripIndent } from './lazy.js';
-import { ExpectedError } from '../errors';
+import { ExpectedError } from '../errors.js';
export const serviceIdToName = _.memoize(
async (
@@ -238,7 +238,7 @@ export async function getOsVersions(
deviceType: string,
esr: boolean,
): Promise {
- const sdk = getBalenaSdk();
+ const sdk = await getBalenaSdk();
let slug = deviceType;
let versions: SDK.OsVersion[] =
await sdk.models.os.getAvailableOsVersions(slug);
diff --git a/lib/utils/common-args.ts b/lib/utils/common-args.ts
index 74ae9baa..040541eb 100644
--- a/lib/utils/common-args.ts
+++ b/lib/utils/common-args.ts
@@ -15,7 +15,7 @@
* limitations under the License.
*/
import { Args } from '@oclif/core';
-import { lowercaseIfSlug } from './normalization';
+import { lowercaseIfSlug } from './normalization.js';
export const fleetRequired = Args.string({
description: 'fleet name or slug (preferred)',
diff --git a/lib/utils/common-flags.ts b/lib/utils/common-flags.ts
index 0941ed43..9c90ae1d 100644
--- a/lib/utils/common-flags.ts
+++ b/lib/utils/common-flags.ts
@@ -16,8 +16,8 @@
*/
import { Flags } from '@oclif/core';
-import { stripIndent } from './lazy';
-import { lowercaseIfSlug } from './normalization';
+import { stripIndent } from './lazy.js';
+import { lowercaseIfSlug } from './normalization.js';
export const fleet = Flags.string({
char: 'f',
diff --git a/lib/utils/compose-types.d.ts b/lib/utils/compose-types.d.ts
index 1d8924a2..982f8a41 100644
--- a/lib/utils/compose-types.d.ts
+++ b/lib/utils/compose-types.d.ts
@@ -18,7 +18,7 @@
import type {
ImageModel,
ReleaseModel,
-} from '@balena/compose/dist/release/models';
+} from '@balena/compose/dist/release/models.js';
import type { Composition, ImageDescriptor } from '@balena/compose/dist/parse';
import type { Pack } from 'tar-stream';
diff --git a/lib/utils/compose.ts b/lib/utils/compose.ts
index c9c39496..bd7be12e 100644
--- a/lib/utils/compose.ts
+++ b/lib/utils/compose.ts
@@ -15,9 +15,12 @@
* limitations under the License.
*/
-import type { Renderer } from './compose_ts';
+import { createRequire } from 'node:module';
+const require = createRequire(import.meta.url);
+
+import type { Renderer } from './compose_ts.js';
import type * as SDK from 'balena-sdk';
-import type Dockerode = require('dockerode');
+import type Dockerode from 'dockerode';
import * as path from 'path';
import type { Composition, ImageDescriptor } from '@balena/compose/dist/parse';
import type {
@@ -26,12 +29,12 @@ import type {
ComposeProject,
Release,
TaggedImage,
-} from './compose-types';
-import { getChalk } from './lazy';
-import Logger = require('./logger');
+} from './compose-types.js';
+import { getChalk } from './lazy.js';
+import type Logger from './logger.js';
import { ProgressCallback } from 'docker-progress';
-export function generateOpts(options: {
+export async function generateOpts(options: {
source?: string;
projectName?: string;
nologs: boolean;
@@ -40,7 +43,7 @@ export function generateOpts(options: {
'multi-dockerignore': boolean;
'noparent-check': boolean;
}): Promise {
- const { promises: fs } = require('fs') as typeof import('fs');
+ const { promises: fs } = await import('fs');
return fs.realpath(options.source || '.').then((projectPath) => ({
projectName: options.projectName,
projectPath,
@@ -56,19 +59,19 @@ export function generateOpts(options: {
* - composePath: the *absolute* path to the directory containing the compose file
* - composeStr: the contents of the compose file, as a string
*/
-export function createProject(
+export async function createProject(
composePath: string,
composeStr: string,
projectName = '',
imageTag = '',
-): ComposeProject {
- const yml = require('js-yaml') as typeof import('js-yaml');
- const compose =
- require('@balena/compose/dist/parse') as typeof import('@balena/compose/dist/parse');
+): Promise {
+ const yml = await import('js-yaml');
+ const compose = await import('@balena/compose/dist/parse');
// both methods below may throw.
const rawComposition = yml.load(composeStr);
const composition = compose.normalize(rawComposition);
+ const { makeImageName } = await import('./compose_ts.js');
projectName ||= path.basename(composePath);
@@ -80,8 +83,6 @@ export function createProject(
descr.image.context != null &&
descr.image.tag == null
) {
- const { makeImageName } =
- require('./compose_ts') as typeof import('./compose_ts');
descr.image.tag = makeImageName(projectName, descr.serviceName, imageTag);
}
return descr;
@@ -104,10 +105,9 @@ export const createRelease = async function (
semver?: string,
contract?: string,
): Promise {
- const _ = require('lodash') as typeof import('lodash');
- const crypto = require('crypto') as typeof import('crypto');
- const releaseMod =
- require('@balena/compose/dist/release') as typeof import('@balena/compose/dist/release');
+ const _ = await import('lodash');
+ const crypto = await import('crypto');
+ const releaseMod = await import('@balena/compose/dist/release');
const client = releaseMod.createClient({ apiEndpoint, auth });
@@ -271,7 +271,7 @@ const renderProgressBar = function (percentage: number, stepCount: number) {
};
export const pushProgressRenderer = function (
- tty: ReturnType,
+ tty: ReturnType,
prefix: string,
): ProgressCallback & { end: () => void } {
const fn: ProgressCallback & { end: () => void } = function (e) {
@@ -305,14 +305,14 @@ export class BuildProgressUI implements Renderer {
private _spinner;
private _runloop:
| undefined
- | ReturnType;
+ | ReturnType;
// these are to handle window wrapping
private _maxLineWidth: undefined | number;
private _lineWidths: number[] = [];
constructor(
- tty: ReturnType,
+ tty: ReturnType,
descriptors: ImageDescriptor[],
) {
this._handleEvent = this._handleEvent.bind(this);
@@ -353,7 +353,7 @@ export class BuildProgressUI implements Renderer {
this._ended = false;
this._cancelled = false;
this._spinner = (
- require('./compose_ts') as typeof import('./compose_ts')
+ require('./compose_ts.js') as typeof import('./compose_ts.js')
).createSpinner();
this.streams = streams;
@@ -372,12 +372,12 @@ export class BuildProgressUI implements Renderer {
this.streams[service].write({ status: 'Preparing...' });
});
this._runloop = (
- require('./compose_ts') as typeof import('./compose_ts')
+ require('./compose_ts.js') as typeof import('./compose_ts.js')
).createRunLoop(this._display);
this._startTime = Date.now();
}
- end(summary?: Dictionary) {
+ async end(summary?: Dictionary) {
if (this._ended) {
return;
}
@@ -386,14 +386,14 @@ export class BuildProgressUI implements Renderer {
this._runloop = undefined;
this._clear();
- this._renderStatus(true);
+ await this._renderStatus(true);
this._renderSummary(summary ?? this._getServiceSummary());
this._tty.showCursor();
}
- _display() {
+ async _display() {
this._clear();
- this._renderStatus();
+ await this._renderStatus();
this._renderSummary(this._getServiceSummary());
this._tty.cursorUp(this._services.length + 1); // for status line
}
@@ -431,11 +431,9 @@ export class BuildProgressUI implements Renderer {
.value();
}
- _renderStatus(end = false) {
- const moment = require('moment') as typeof import('moment');
- (
- require('moment-duration-format') as typeof import('moment-duration-format')
- )(moment);
+ async _renderStatus(end = false) {
+ const moment = await import('moment');
+ (await import('moment-duration-format')).default(moment);
this._tty.clearLine();
this._tty.write(this._prefix);
@@ -529,11 +527,9 @@ export class BuildProgressInline implements Renderer {
this._startTime = Date.now();
}
- end(summary?: Dictionary) {
- const moment = require('moment') as typeof import('moment');
- (
- require('moment-duration-format') as typeof import('moment-duration-format')
- )(moment);
+ async end(summary?: Dictionary) {
+ const moment = await import('moment');
+ (await import('moment-duration-format')).default(moment);
if (this._ended) {
return;
diff --git a/lib/utils/compose_ts.ts b/lib/utils/compose_ts.ts
index 202d85f1..7b09a000 100644
--- a/lib/utils/compose_ts.ts
+++ b/lib/utils/compose_ts.ts
@@ -14,13 +14,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+import { createRequire } from 'node:module';
+const require = createRequire(import.meta.url);
import { Flags } from '@oclif/core';
import { BalenaSDK } from 'balena-sdk';
import type { TransposeOptions } from '@balena/compose/dist/emulate';
import type * as Dockerode from 'dockerode';
import { promises as fs } from 'fs';
-import jsyaml = require('js-yaml');
-import * as _ from 'lodash';
+import jsyaml from 'js-yaml';
+import _ from 'lodash';
import * as path from 'path';
import type {
BuildConfig,
@@ -31,18 +33,18 @@ import type * as MultiBuild from '@balena/compose/dist/multibuild';
import * as semver from 'semver';
import type { Duplex, Readable } from 'stream';
import type { Pack } from 'tar-stream';
-import { ExpectedError } from '../errors';
+import { ExpectedError } from '../errors.js';
import {
BuiltImage,
ComposeOpts,
ComposeProject,
TaggedImage,
TarDirectoryOptions,
-} from './compose-types';
-import type { DeviceInfo } from './device/api';
-import { getBalenaSdk, getChalk, stripIndent } from './lazy';
-import Logger = require('./logger');
-import { exists } from './which';
+} from './compose-types.js';
+import type { DeviceInfo } from './device/api.js';
+import { getBalenaSdk, getChalk, stripIndent } from './lazy.js';
+import Logger from './logger.js';
+import { exists } from './which.js';
const allowedContractTypes = ['sw.application', 'sw.block'];
@@ -117,7 +119,7 @@ export async function loadProject(
imageTag?: string,
): Promise {
const compose = await import('@balena/compose/dist/parse');
- const { createProject } = await import('./compose');
+ const { createProject } = await import('./compose.js');
let composeName: string;
let composeStr: string;
@@ -236,7 +238,7 @@ interface BuildTaskPlus extends MultiBuild.BuildTask {
export interface Renderer {
start: () => void;
- end: (buildSummaryByService?: Dictionary) => void;
+ end: (buildSummaryByService?: Dictionary) => Promise;
streams: Dictionary;
}
@@ -249,7 +251,7 @@ export interface BuildProjectOpts {
arch: string;
deviceType: string;
emulated: boolean;
- buildOpts: import('./docker').BuildOpts;
+ buildOpts: import('./docker.js').BuildOpts;
inlineLogs?: boolean;
convertEol: boolean;
dockerfilePath?: string;
@@ -265,7 +267,7 @@ export async function buildProject(
const renderer = await startRenderer({ imageDescriptors, ...opts });
let buildSummaryByService: Dictionary | undefined;
try {
- const { awaitInterruptibleTask } = await import('./helpers');
+ const { awaitInterruptibleTask } = await import('./helpers.js');
const [images, summaryMsgByService] = await awaitInterruptibleTask(
$buildProject,
imageDescriptors,
@@ -275,7 +277,7 @@ export async function buildProject(
buildSummaryByService = summaryMsgByService;
return images;
} finally {
- renderer.end(buildSummaryByService);
+ await renderer.end(buildSummaryByService);
}
}
@@ -330,7 +332,7 @@ async function $buildProject(
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 builtImages = await builder.performBuilds(
@@ -358,13 +360,13 @@ async function startRenderer({
}): Promise {
let renderer: Renderer;
if (inlineLogs) {
- renderer = new (await import('./compose')).BuildProgressInline(
+ renderer = new (await import('./compose.js')).BuildProgressInline(
logger.streams['build'],
imageDescriptors,
);
} else {
- const tty = (await import('./tty'))(process.stdout);
- renderer = new (await import('./compose')).BuildProgressUI(
+ const tty = (await import('./tty.js')).default(process.stdout);
+ renderer = new (await import('./compose.js')).BuildProgressUI(
tty,
imageDescriptors,
);
@@ -388,7 +390,7 @@ async function installQemuIfNeeded({
logger: Logger;
projectPath: string;
}): Promise {
- const qemu = await import('./qemu');
+ const qemu = await import('./qemu.js');
const needsQemu = await qemu.installQemuIfNeeded(
emulated,
logger,
@@ -431,7 +433,7 @@ function setTaskAttributes({
projectName,
}: {
tasks: BuildTaskPlus[];
- buildOpts: import('./docker').BuildOpts;
+ buildOpts: import('./docker.js').BuildOpts;
imageDescriptorsByServiceName: Dictionary;
projectName: string;
}) {
@@ -471,8 +473,8 @@ async function qemuTransposeBuildStream({
dockerfilePath?: string;
projectPath: string;
}): Promise {
- const qemu = await import('./qemu');
- const binPath = qemu.qemuPathInContext(
+ const qemu = await import('./qemu.js');
+ const binPath = await qemu.qemuPathInContext(
path.join(projectPath, task.context ?? ''),
);
if (task.buildStream == null) {
@@ -681,7 +683,7 @@ export async function getServiceDirsFromComposition(
sourceDir: string,
composition?: Composition,
): Promise> {
- const { createProject } = await import('./compose');
+ const { createProject } = await import('./compose.js');
const serviceDirs: Dictionary = {};
if (!composition) {
const [, composeStr] = await resolveProject(
@@ -690,7 +692,7 @@ export async function getServiceDirsFromComposition(
true,
);
if (composeStr) {
- composition = createProject(sourceDir, composeStr).composition;
+ composition = (await createProject(sourceDir, composeStr)).composition;
}
}
if (composition?.services) {
@@ -757,13 +759,13 @@ export async function tarDirectory(
preFinalizeCallback,
}: TarDirectoryOptions,
): Promise {
- const { filterFilesWithDockerignore } = await import('./ignore');
+ const { filterFilesWithDockerignore } = await import('./ignore.js');
const { toPosixPath } = (await import('@balena/compose/dist/multibuild'))
.PathUtils;
let readFile: (file: string) => Promise;
if (process.platform === 'win32') {
- const { readFileWithEolConversion } = require('./eol-conversion');
+ const { readFileWithEolConversion } = await import('./eol-conversion.js');
readFile = (file) => readFileWithEolConversion(file, convertEol);
} else {
readFile = fs.readFile;
@@ -773,7 +775,11 @@ export async function tarDirectory(
const serviceDirs = await getServiceDirsFromComposition(dir, composition);
const { filteredFileList, dockerignoreFiles } =
await filterFilesWithDockerignore(dir, multiDockerignore, serviceDirs);
- printDockerignoreWarn(dockerignoreFiles, serviceDirs, multiDockerignore);
+ await printDockerignoreWarn(
+ dockerignoreFiles,
+ serviceDirs,
+ multiDockerignore,
+ );
for (const fileStats of filteredFileList) {
pack.entry(
{
@@ -799,18 +805,18 @@ export async function tarDirectory(
* @param serviceDirsByService Map of service names to service subdirectories
* @param multiDockerignore Whether --multi-dockerignore (-m) was provided
*/
-function printDockerignoreWarn(
- dockerignoreFiles: Array,
+async function printDockerignoreWarn(
+ dockerignoreFiles: Array,
serviceDirsByService: Dictionary,
multiDockerignore: boolean,
) {
- let rootDockerignore: import('./ignore').FileStats | undefined;
+ let rootDockerignore: import('./ignore.js').FileStats | undefined;
const logger = Logger.getLogger();
const relPrefix = '.' + path.sep;
const serviceDirs = Object.values(serviceDirsByService || {});
// compute a list of unused .dockerignore files
const unusedFiles = dockerignoreFiles.filter(
- (dockerignoreStats: import('./ignore').FileStats) => {
+ (dockerignoreStats: import('./ignore.js').FileStats) => {
let dirname = path.dirname(dockerignoreStats.relPath);
dirname = dirname.startsWith(relPrefix) ? dirname.slice(2) : dirname;
const isProjectRootDir = !dirname || dirname === '.';
@@ -873,7 +879,7 @@ function printDockerignoreWarn(
}
}
if (msg.length) {
- const { warnify } = require('./messages') as typeof import('./messages');
+ const { warnify } = await import('./messages.js');
logFunc.call(logger, ' \n' + warnify(msg.join('\n'), ''));
}
}
@@ -891,7 +897,7 @@ export async function checkBuildSecretsRequirements(
) {
const [metaObj, metaFilename] = await loadBuildMetatada(sourceDir);
if (metaObj && !_.isEmpty(metaObj['build-secrets'])) {
- const dockerUtils = await import('./docker');
+ const dockerUtils = await import('./docker.js');
const isBalenaEngine = await dockerUtils.isBalenaEngine(docker);
if (!isBalenaEngine) {
throw new ExpectedError(stripIndent`
@@ -1222,8 +1228,8 @@ async function getTokenForPreviousRepos(
taggedImages: TaggedImage[],
): Promise {
logger.logDebug('Authorizing push...');
- const { authorizePush, getPreviousRepos } = await import('./compose');
- const sdk = getBalenaSdk();
+ const { authorizePush, getPreviousRepos } = await import('./compose.js');
+ const sdk = await getBalenaSdk();
const previousRepos = await getPreviousRepos(sdk, logger, appId);
const token = await authorizePush(
@@ -1241,14 +1247,14 @@ async function pushAndUpdateServiceImages(
token: string,
images: TaggedImage[],
afterEach: (
- serviceImage: import('@balena/compose/dist/release/models').ImageModel,
+ serviceImage: import('@balena/compose/dist/release/models.js').ImageModel,
props: object,
) => Promise,
) {
const { DockerProgress } = await import('docker-progress');
- const { retry } = await import('./helpers');
- const { pushProgressRenderer } = await import('./compose');
- const tty = (await import('./tty'))(process.stdout);
+ const { retry } = await import('./helpers.js');
+ const { pushProgressRenderer } = await import('./compose.js');
+ const tty = (await import('./tty.js')).default(process.stdout);
const opts = { authconfig: { registrytoken: token } };
const progress = new DockerProgress({ docker });
const renderer = pushProgressRenderer(
@@ -1363,10 +1369,10 @@ export async function deployProject(
skipLogUpload: boolean,
projectPath: string,
isDraft: boolean,
-): Promise {
+): Promise {
const releaseMod = await import('@balena/compose/dist/release');
- const { createRelease, tagServiceImages } = await import('./compose');
- const tty = (await import('./tty'))(process.stdout);
+ const { createRelease, tagServiceImages } = await import('./compose.js');
+ const tty = (await import('./tty.js')).default(process.stdout);
const prefix = getChalk().cyan('[Info]') + ' ';
const spinner = createSpinner();
@@ -1401,7 +1407,7 @@ export async function deployProject(
logger.logDebug('Tagging images...');
const taggedImages = await tagServiceImages(docker, images, serviceImages);
try {
- const { awaitInterruptibleTask } = await import('./helpers');
+ const { awaitInterruptibleTask } = await import('./helpers.js');
// awaitInterruptibleTask throws SIGINTError on CTRL-C,
// causing the release status to be set to 'failed'
await awaitInterruptibleTask(async () => {
@@ -1448,7 +1454,7 @@ export function createSpinner() {
}
async function runSpinner(
- tty: ReturnType,
+ tty: ReturnType,
spinner: () => string,
msg: string,
fn: () => Promise,
diff --git a/lib/utils/config.ts b/lib/utils/config.ts
index fef0b0b7..cbfe15c6 100644
--- a/lib/utils/config.ts
+++ b/lib/utils/config.ts
@@ -15,7 +15,7 @@ limitations under the License.
*/
import type * as BalenaSdk from 'balena-sdk';
import * as semver from 'balena-semver';
-import { getBalenaSdk, stripIndent } from './lazy';
+import { getBalenaSdk, stripIndent } from './lazy.js';
export interface ImgConfig {
applicationName: string;
@@ -75,10 +75,9 @@ export async function generateApplicationConfig(
appUpdatePollInterval: options.appUpdatePollInterval || 10,
};
- const config = (await getBalenaSdk().models.os.getConfig(
- application.slug,
- options,
- )) as ImgConfig;
+ const config = (await (
+ await getBalenaSdk()
+ ).models.os.getConfig(application.slug, options)) as ImgConfig;
// merge sshKeys to config, when they have been specified
if (options.os && options.os.sshKeys) {
@@ -98,14 +97,14 @@ export async function generateApplicationConfig(
return config;
}
-export function generateDeviceConfig(
+export async function generateDeviceConfig(
device: DeviceWithDeviceType & {
belongs_to__application: BalenaSdk.PineDeferred;
},
deviceApiKey: string | true | undefined,
options: { version: string },
) {
- const sdk = getBalenaSdk();
+ const sdk = await getBalenaSdk();
return sdk.models.application
.get(device.belongs_to__application.__id)
.then(async (application) => {
@@ -155,20 +154,20 @@ export function generateDeviceConfig(
export async function validateDevOptionAndWarn(
dev?: boolean,
version?: string,
- logger?: import('./logger'),
+ logger?: import('./logger.js').default,
) {
if (!dev) {
return;
}
if (version && /\bprod\b/.test(version)) {
- const { ExpectedError } = await import('../errors');
+ const { ExpectedError } = await import('../errors.js');
throw new ExpectedError(
`Error: The '--dev' option conflicts with production balenaOS version '${version}'`,
);
}
if (!logger) {
- const Logger = await import('./logger');
- logger = Logger.getLogger();
+ const Logger = await import('./logger.js');
+ logger = Logger.default.getLogger();
}
logger.logInfo(stripIndent`
The '--dev' option is being used to configure a balenaOS image in development mode.
@@ -187,19 +186,19 @@ export async function validateSecureBootOptionAndWarn(
secureBoot?: boolean,
slug?: string,
version?: string,
- logger?: import('./logger'),
+ logger?: import('./logger.js').default,
) {
if (!secureBoot) {
return;
}
- const { ExpectedError } = await import('../errors');
+ const { ExpectedError } = await import('../errors.js');
if (!version) {
throw new ExpectedError(`Error: No version provided`);
}
if (!slug) {
throw new ExpectedError(`Error: No device type provided`);
}
- const sdk = getBalenaSdk();
+ const sdk = await getBalenaSdk();
const [osRelease] = await sdk.models.os.getAllOsVersions(slug, {
$select: 'contract',
$filter: { raw_version: `${version.replace(/^v/, '')}` },
@@ -215,8 +214,8 @@ export async function validateSecureBootOptionAndWarn(
})
) {
if (!logger) {
- const Logger = await import('./logger');
- logger = Logger.getLogger();
+ const Logger = await import('./logger.js');
+ logger = Logger.default.getLogger();
}
logger.logInfo(stripIndent`
The '--secureBoot' option is being used to configure a balenaOS installer image
diff --git a/lib/utils/deploy-legacy.ts b/lib/utils/deploy-legacy.ts
index 074e9cf2..60e52735 100644
--- a/lib/utils/deploy-legacy.ts
+++ b/lib/utils/deploy-legacy.ts
@@ -15,29 +15,29 @@
* limitations under the License.
*/
-import { getVisuals } from './lazy';
+import { getVisuals } from './lazy.js';
import { promisify } from 'util';
import type * as Dockerode from 'dockerode';
-import type Logger = require('./logger');
+import type Logger from './logger.js';
import type { Request } from 'request';
-const getBuilderPushEndpoint = function (
+const getBuilderPushEndpoint = async function (
baseUrl: string,
owner: string,
app: string,
) {
- const querystring = require('querystring') as typeof import('querystring');
+ const querystring = await import('querystring');
const args = querystring.stringify({ owner, app });
return `https://builder.${baseUrl}/v1/push?${args}`;
};
-const getBuilderLogPushEndpoint = function (
+const getBuilderLogPushEndpoint = async function (
baseUrl: string,
buildId: number,
owner: string,
app: string,
) {
- const querystring = require('querystring') as typeof import('querystring');
+ const querystring = await import('querystring');
const args = querystring.stringify({ owner, app, buildId });
return `https://builder.${baseUrl}/v1/pushLogs?${args}`;
};
@@ -47,12 +47,12 @@ const getBuilderLogPushEndpoint = function (
* @param {string} imageId
* @param {string} bufferFile
*/
-const bufferImage = function (
+const bufferImage = async function (
docker: Dockerode,
imageId: string,
bufferFile: string,
): Promise {
- const streamUtils = require('./streams') as typeof import('./streams');
+ const streamUtils = await import('./streams.js');
const image = docker.getImage(imageId);
const sizePromise = image.inspect().then((img) => img.Size);
@@ -109,7 +109,7 @@ const uploadToPromise = (uploadRequest: Request, logger: Logger) =>
/**
* @returns {Promise<{ buildId: number }>}
*/
-const uploadImage = function (
+const uploadImage = async function (
imageStream: NodeJS.ReadableStream & { length: number },
token: string,
username: string,
@@ -117,10 +117,9 @@ const uploadImage = function (
appName: string,
logger: Logger,
): Promise<{ buildId: number }> {
- const request = require('request') as typeof import('request');
- const progressStream =
- require('progress-stream') as typeof import('progress-stream');
- const zlib = require('zlib') as typeof import('zlib');
+ const request = await import('request');
+ const { default: progressStream } = await import('progress-stream');
+ const zlib = await import('zlib');
// Need to strip off the newline
const progressMessage = logger
@@ -142,7 +141,7 @@ const uploadImage = function (
);
const uploadRequest = request.post({
- url: getBuilderPushEndpoint(url, username, appName),
+ url: await getBuilderPushEndpoint(url, username, appName),
headers: {
'Content-Encoding': 'gzip',
},
@@ -159,7 +158,7 @@ const uploadImage = function (
return uploadToPromise(uploadRequest, logger);
};
-const uploadLogs = function (
+const uploadLogs = async function (
logs: string,
token: string,
url: string,
@@ -167,10 +166,10 @@ const uploadLogs = function (
username: string,
appName: string,
) {
- const request = require('request') as typeof import('request');
+ const request = await import('request');
return request.post({
json: true,
- url: getBuilderLogPushEndpoint(url, buildId, username, appName),
+ url: await getBuilderLogPushEndpoint(url, buildId, username, appName),
auth: {
bearer: token,
},
@@ -196,7 +195,7 @@ export const deployLegacy = async function (
shouldUploadLogs: boolean;
},
): Promise {
- const tmp = require('tmp') as typeof import('tmp');
+ const tmp = await import('tmp');
const tmpNameAsync = promisify(tmp.tmpName);
// Ensure the tmp files gets deleted
@@ -208,6 +207,7 @@ export const deployLegacy = async function (
const bufferFile = await tmpNameAsync();
logger.logInfo('Initializing deploy...');
+ const fs = await import('fs');
const { buildId } = await bufferImage(docker, imageName, bufferFile)
.then((stream) =>
uploadImage(stream, token, username, url, appName, logger),
@@ -217,9 +217,7 @@ export const deployLegacy = async function (
// has occured before any data was written) this call will throw an
// ugly error, just suppress it
- (require('fs') as typeof import('fs')).promises
- .unlink(bufferFile)
- .catch(() => undefined),
+ fs.promises.unlink(bufferFile).catch(() => undefined),
);
if (shouldUploadLogs) {
diff --git a/lib/utils/device/api.ts b/lib/utils/device/api.ts
index bff6ffbf..0e10e1c0 100644
--- a/lib/utils/device/api.ts
+++ b/lib/utils/device/api.ts
@@ -14,15 +14,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import * as _ from 'lodash';
+import _ from 'lodash';
import type { NodeJSSocketWithFileDescriptor } from 'net-keepalive';
import * as os from 'os';
-import * as request from 'request';
+import request from 'request';
import type * as Stream from 'stream';
-import { retry } from '../helpers';
-import Logger = require('../logger');
-import * as ApiErrors from './errors';
+import { retry } from '../helpers.js';
+import type Logger from '../logger.js';
+import * as ApiErrors from './errors.js';
export interface DeviceResponse {
[key: string]: any;
diff --git a/lib/utils/device/deploy.ts b/lib/utils/device/deploy.ts
index 6717735b..ad8a0e3b 100644
--- a/lib/utils/device/deploy.ts
+++ b/lib/utils/device/deploy.ts
@@ -14,10 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+import { createRequire } from 'node:module';
+const require = createRequire(import.meta.url);
import * as semver from 'balena-semver';
-import * as Docker from 'dockerode';
-import * as _ from 'lodash';
+import Docker from 'dockerode';
+import _ from 'lodash';
import { Composition } from '@balena/compose/dist/parse';
import {
BuildTask,
@@ -27,21 +29,21 @@ import {
} from '@balena/compose/dist/multibuild';
import type { Readable } from 'stream';
-import { BALENA_ENGINE_TMP_PATH } from '../../config';
-import { ExpectedError } from '../../errors';
+import { BALENA_ENGINE_TMP_PATH } from '../../config.js';
+import { ExpectedError } from '../../errors.js';
import {
checkBuildSecretsRequirements,
loadProject,
makeBuildTasks,
tarDirectory,
makeImageName,
-} from '../compose_ts';
-import Logger = require('../logger');
-import { DeviceAPI, DeviceInfo } from './api';
-import * as LocalPushErrors from './errors';
-import LivepushManager from './live';
-import { displayBuildLog } from './logs';
-import { stripIndent } from '../lazy';
+} from '../compose_ts.js';
+import Logger from '../logger.js';
+import { DeviceAPI, DeviceInfo } from './api.js';
+import * as LocalPushErrors from './errors.js';
+import LivepushManager from './live.js';
+import { displayBuildLog } from './logs.js';
+import { stripIndent } from '../lazy.js';
const LOCAL_APPNAME = 'localapp';
const LOCAL_RELEASEHASH = '10ca12e1ea5e';
@@ -214,7 +216,7 @@ export async function deployToDevice(opts: DeviceDeployOptions): Promise {
imageIds = {};
}
- const { awaitInterruptibleTask } = await import('../helpers');
+ const { awaitInterruptibleTask } = await import('../helpers.js');
const buildTasks = await awaitInterruptibleTask(
performBuilds,
project.composition,
@@ -294,7 +296,7 @@ async function streamDeviceLogs(
return;
}
globalLogger.logInfo('Streaming device logs...');
- const { connectAndDisplayDeviceLogs } = await import('./logs');
+ const { connectAndDisplayDeviceLogs } = await import('./logs.js');
return connectAndDisplayDeviceLogs({
deviceApi,
logger: globalLogger,
diff --git a/lib/utils/device/errors.ts b/lib/utils/device/errors.ts
index 5455a803..5f3668a4 100644
--- a/lib/utils/device/errors.ts
+++ b/lib/utils/device/errors.ts
@@ -14,9 +14,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import * as _ from 'lodash';
+import _ from 'lodash';
-import { ExpectedError } from '../../errors';
+import { ExpectedError } from '../../errors.js';
export interface BuildFailure {
error: Error;
diff --git a/lib/utils/device/live.ts b/lib/utils/device/live.ts
index 6bc83cc9..029d274c 100644
--- a/lib/utils/device/live.ts
+++ b/lib/utils/device/live.ts
@@ -19,25 +19,25 @@ import * as chokidar from 'chokidar';
import type * as Dockerode from 'dockerode';
import * as fs from 'fs';
import Livepush, { ContainerNotRunningError } from 'livepush';
-import * as _ from 'lodash';
+import _ from 'lodash';
import * as path from 'path';
import type { Composition } from '@balena/compose/dist/parse';
import type { BuildTask } from '@balena/compose/dist/multibuild';
-import { instanceOf } from '../../errors';
-import Logger = require('../logger');
+import { instanceOf } from '../../errors.js';
+import type Logger from '../logger.js';
import { Dockerfile } from 'livepush';
-import type DeviceAPI from './api';
-import type { DeviceInfo, Status } from './api';
+import type DeviceAPI from './api.js';
+import type { DeviceInfo, Status } from './api.js';
import {
DeviceDeployOptions,
generateTargetState,
rebuildSingleTask,
-} from './deploy';
-import { BuildError } from './errors';
-import { getServiceColourFn } from './logs';
-import { delay } from '../helpers';
+} from './deploy.js';
+import { BuildError } from './errors.js';
+import { getServiceColourFn } from './logs.js';
+import { delay } from '../helpers.js';
// How often do we want to check the device state
// engine has settled (delay in ms)
@@ -47,7 +47,7 @@ const LIVEPUSH_DEBOUNCE_TIMEOUT = 2000;
interface MonitoredContainer {
context: string;
- livepush: Livepush;
+ livepush: Livepush.default;
monitor: chokidar.FSWatcher;
containerId: string;
}
@@ -111,8 +111,8 @@ export class LivepushManager {
this.logger.logLivepush('Device state settled');
// Prepare dockerignore data for file watcher
- const { getDockerignoreByService } = await import('../ignore');
- const { getServiceDirsFromComposition } = await import('../compose_ts');
+ const { getDockerignoreByService } = await import('../ignore.js');
+ const { getServiceDirsFromComposition } = await import('../compose_ts.js');
const rootContext = path.resolve(this.buildContext);
const serviceDirsByService = await getServiceDirsFromComposition(
this.deployOpts.source,
@@ -170,7 +170,7 @@ export class LivepushManager {
// and also converts forward slashes to backslashes on Windows.
const context = path.resolve(rootContext, service.build.context);
- const livepush = await Livepush.init({
+ const livepush = await Livepush.default.init({
dockerfile,
context,
containerId: container.containerId,
@@ -441,7 +441,7 @@ export class LivepushManager {
const dockerfile = new Dockerfile(buildTask.dockerfile!);
- instance.livepush = await Livepush.init({
+ instance.livepush = await Livepush.default.init({
dockerfile,
context: buildTask.context!,
containerId: container.containerId,
@@ -476,7 +476,7 @@ export class LivepushManager {
private assignLivepushOutputHandlers(
serviceName: string,
- livepush: Livepush,
+ livepush: Livepush.default,
) {
const msgString = (msg: string) =>
`[${getServiceColourFn(serviceName)(serviceName)}] ${msg}`;
diff --git a/lib/utils/device/logs.ts b/lib/utils/device/logs.ts
index 267ba1f4..d08693da 100644
--- a/lib/utils/device/logs.ts
+++ b/lib/utils/device/logs.ts
@@ -14,13 +14,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import ColorHash = require('color-hash');
-import * as _ from 'lodash';
+import ColorHash from 'color-hash';
+import _ from 'lodash';
import type { Readable } from 'stream';
-import { getChalk } from '../lazy';
-import Logger = require('../logger');
-import { ExpectedError, SIGINTError } from '../../errors';
+import { getChalk } from '../lazy.js';
+import type Logger from '../logger.js';
+import { ExpectedError, SIGINTError } from '../../errors.js';
class DeviceConnectionLostError extends ExpectedError {
public static defaultMsg = 'Connection to device lost';
@@ -62,7 +62,7 @@ async function displayDeviceLogs(
system: boolean,
filterServices?: string[],
): Promise {
- const { addSIGINTHandler } = await import('../helpers');
+ const { addSIGINTHandler } = await import('../helpers.js');
const { parse: ndjsonParse } = await import('ndjson');
let gotSignal = false;
const handleSignal = () => {
@@ -113,7 +113,7 @@ export async function connectAndDisplayDeviceLogs({
filterServices,
maxAttempts = 3,
}: {
- deviceApi: import('./api').DeviceAPI;
+ deviceApi: import('./api.js').DeviceAPI;
logger: Logger;
system: boolean;
filterServices?: string[];
@@ -125,7 +125,7 @@ export async function connectAndDisplayDeviceLogs({
return displayDeviceLogs(logStream, logger, system, filterServices);
}
- const { retry } = await import('../../utils/helpers');
+ const { retry } = await import('../../utils/helpers.js');
try {
await retry({
func: connectAndDisplay,
diff --git a/lib/utils/device/ssh.ts b/lib/utils/device/ssh.ts
index 0a7ee732..31e7abfb 100644
--- a/lib/utils/device/ssh.ts
+++ b/lib/utils/device/ssh.ts
@@ -14,22 +14,22 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import { ExpectedError } from '../../errors';
-import { stripIndent } from '../lazy';
+import { ExpectedError } from '../../errors.js';
+import { stripIndent } from '../lazy.js';
import {
findBestUsernameForDevice,
getRemoteCommandOutput,
runRemoteCommand,
SshRemoteCommandOpts,
-} from '../ssh';
+} from '../ssh.js';
export interface DeviceSSHOpts extends SshRemoteCommandOpts {
forceTTY?: boolean;
service?: string;
}
-const deviceContainerEngineBinary = `$(if [ -f /usr/bin/balena ]; then echo "balena"; else echo "docker"; fi)`;
+const deviceContainerEngineBinary = `$(if [ -f /usr/bin/balena.js ]; then echo "balena"; else echo "docker"; fi)`;
/**
* List the running containers on the device over ssh, and return the full
diff --git a/lib/utils/docker.ts b/lib/utils/docker.ts
index f93ecf03..fb21ca11 100644
--- a/lib/utils/docker.ts
+++ b/lib/utils/docker.ts
@@ -14,12 +14,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
+import { createRequire } from 'node:module';
+const require = createRequire(import.meta.url);
import type * as dockerode from 'dockerode';
import { Flags } from '@oclif/core';
-import { ExpectedError } from '../errors';
-import { parseAsInteger } from './validation';
+import { ExpectedError } from '../errors.js';
+import { parseAsInteger } from './validation.js';
interface BalenaEngineVersion extends dockerode.DockerVersion {
Engine?: string;
@@ -186,7 +187,7 @@ export async function getDocker(
export async function createClient(
opts: dockerode.DockerOptions,
): Promise {
- const Docker = await import('dockerode');
+ const { default: Docker } = await import('dockerode');
return new Docker(opts);
}
diff --git a/lib/utils/env-common.ts b/lib/utils/env-common.ts
index 194c2cbb..aedefac8 100644
--- a/lib/utils/env-common.ts
+++ b/lib/utils/env-common.ts
@@ -16,9 +16,9 @@
*/
import { Flags } from '@oclif/core';
-import { stripIndent } from './lazy';
+import { stripIndent } from './lazy.js';
-import { ExpectedError } from '../errors';
+import { ExpectedError } from '../errors.js';
export const booleanConfig = Flags.boolean({
char: 'c',
diff --git a/lib/utils/eol-conversion.ts b/lib/utils/eol-conversion.ts
index 2d015c6b..ec76fcdd 100644
--- a/lib/utils/eol-conversion.ts
+++ b/lib/utils/eol-conversion.ts
@@ -16,7 +16,7 @@
*/
import { promises as fs } from 'fs';
-import Logger = require('./logger');
+import Logger from './logger.js';
const globalLogger = Logger.getLogger();
diff --git a/lib/utils/helpers.ts b/lib/utils/helpers.ts
index 8d040383..d30c66a7 100644
--- a/lib/utils/helpers.ts
+++ b/lib/utils/helpers.ts
@@ -13,14 +13,15 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
-
+import { createRequire } from 'node:module';
+const require = createRequire(import.meta.url);
import type { InitializeEmitter, OperationState } from 'balena-device-init';
import type * as BalenaSdk from 'balena-sdk';
-import * as _ from 'lodash';
+import _ from 'lodash';
import { promisify } from 'util';
-import { getBalenaSdk, getChalk, getVisuals } from './lazy';
+import { getBalenaSdk, getChalk, getVisuals } from './lazy.js';
export function getGroupDefaults(group: {
options: Array<{ name: string; default: string | number }>;
@@ -77,7 +78,7 @@ export async function sudo(
isCLIcmd,
}: { stderr?: NodeJS.WritableStream; msg?: string; isCLIcmd?: boolean } = {},
) {
- const { executeWithPrivileges } = await import('./sudo');
+ const { executeWithPrivileges } = await import('./sudo.js');
if (process.platform !== 'win32') {
console.log(
@@ -90,8 +91,7 @@ export async function sudo(
}
export async function runCommand(commandArgs: string[]): Promise {
- const { isSubcommand } =
- require('../preparser') as typeof import('../preparser');
+ const { isSubcommand } = await import('../preparser.js');
if (await isSubcommand(commandArgs)) {
commandArgs = [
commandArgs[0] + ':' + commandArgs[1],
@@ -99,7 +99,7 @@ export async function runCommand(commandArgs: string[]): Promise {
];
}
- const { run } = require('@oclif/core') as typeof import('@oclif/core');
+ const { run } = await import('@oclif/core');
return run(commandArgs) as Promise;
}
@@ -108,14 +108,14 @@ export async function getManifest(
deviceType: string,
): Promise {
const init = await import('balena-device-init');
- const sdk = getBalenaSdk();
+ const sdk = await getBalenaSdk();
const manifest = await init.getImageManifest(image);
if (
manifest != null &&
manifest.slug !== deviceType &&
manifest.slug !== (await sdk.models.deviceType.get(deviceType)).slug
) {
- const { ExpectedError } = await import('../errors');
+ const { ExpectedError } = await import('../errors.js');
throw new ExpectedError(
`The device type of the provided OS image ${manifest.slug}, does not match the expected device type ${deviceType}`,
);
@@ -133,7 +133,7 @@ export const areDeviceTypesCompatible = async (
if (appDeviceTypeSlug === osDeviceTypeSlug) {
return true;
}
- const sdk = getBalenaSdk();
+ const sdk = await getBalenaSdk();
const pineOptions = {
$select: 'is_of__cpu_architecture',
$expand: {
@@ -182,8 +182,8 @@ export async function osProgressHandler(step: InitializeEmitter) {
}
export async function getAppWithArch(applicationName: string) {
- const { getApplication } = await import('./sdk');
- const balena = getBalenaSdk();
+ const { getApplication } = await import('./sdk.js');
+ const balena = await getBalenaSdk();
const app = await getApplication(balena, applicationName, {
$expand: {
application_type: {
@@ -239,7 +239,7 @@ export async function retry({
backoffScaler?: number;
maxSingleDelayMs?: number;
}): Promise {
- const { SIGINTError } = await import('../errors');
+ const { SIGINTError } = await import('../errors.js');
let delayMs = initialDelayMs;
for (let count = 0; count < maxAttempts - 1; count++) {
const lastAttemptMs = Date.now();
@@ -486,7 +486,7 @@ export async function awaitInterruptibleTask<
const sigintPromise = new Promise((_resolve, reject) => {
sigintHandler = () => {
const { SIGINTError } =
- require('../errors') as typeof import('../errors');
+ require('../errors.js') as typeof import('../errors.js');
reject(new SIGINTError('Task aborted on SIGINT signal'));
};
addSIGINTHandler(sigintHandler);
diff --git a/lib/utils/ignore.ts b/lib/utils/ignore.ts
index 42275d63..f7e2b69c 100644
--- a/lib/utils/ignore.ts
+++ b/lib/utils/ignore.ts
@@ -14,13 +14,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import * as _ from 'lodash';
+import _ from 'lodash';
import { promises as fs, Stats } from 'fs';
import * as path from 'path';
import type { Ignore } from '@balena/dockerignore';
-import { ExpectedError } from '../errors';
+import { ExpectedError } from '../errors.js';
export interface FileStats {
filePath: string;
@@ -102,7 +102,8 @@ export async function getDockerIgnoreInstance(
directory: string,
): Promise {
const dockerIgnoreStr = await readDockerIgnoreFile(directory);
- const $dockerIgnore = (await import('@balena/dockerignore')).default;
+ const { default: $dockerIgnore } = (await import('@balena/dockerignore'))
+ .default;
const ig = $dockerIgnore({ ignorecase: false });
ig.add(['**/.git']);
diff --git a/lib/utils/lazy.ts b/lib/utils/lazy.ts
index c6d0a984..283dc0f2 100644
--- a/lib/utils/lazy.ts
+++ b/lib/utils/lazy.ts
@@ -15,8 +15,8 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
-
-import type * as BalenaSdk from 'balena-sdk';
+import { createRequire } from 'node:module';
+const require = createRequire(import.meta.url);
import type { Chalk } from 'chalk';
import type * as visuals from 'resin-cli-visuals';
import type * as CliForm from 'resin-cli-form';
@@ -43,8 +43,8 @@ export const onceAsync = (fn: () => Promise) => {
};
};
-export const getBalenaSdk = once(() =>
- (require('balena-sdk') as typeof BalenaSdk).fromSharedOptions(),
+export const getBalenaSdk = once(async () =>
+ (await import('balena-sdk')).fromSharedOptions(),
);
export const getVisuals = once(
diff --git a/lib/utils/logger.ts b/lib/utils/logger.ts
index 7aa69314..24c97947 100644
--- a/lib/utils/logger.ts
+++ b/lib/utils/logger.ts
@@ -14,10 +14,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import _ = require('lodash');
+import _ from 'lodash';
import { EOL as eol } from 'os';
import { StreamLogger } from 'resin-stream-logger';
-import { getChalk } from './lazy';
+import { getChalk } from './lazy.js';
enum Level {
BUILD = 'build',
@@ -175,4 +175,4 @@ class Logger {
}
}
-export = Logger;
+export default Logger;
diff --git a/lib/utils/normalization.ts b/lib/utils/normalization.ts
index cf179a29..7073d557 100644
--- a/lib/utils/normalization.ts
+++ b/lib/utils/normalization.ts
@@ -16,7 +16,7 @@
*/
import type { BalenaSDK } from 'balena-sdk';
-import { ExpectedError } from '../errors';
+import { ExpectedError } from '../errors.js';
/**
* Takes a string which may represent one of:
diff --git a/lib/utils/oclif-utils.ts b/lib/utils/oclif-utils.ts
index ceac7501..8579a760 100644
--- a/lib/utils/oclif-utils.ts
+++ b/lib/utils/oclif-utils.ts
@@ -20,6 +20,8 @@
* @oclif/plugin-help/command/CommandHelp, which is used to generate oclif's
* command help output.
*/
+import { createRequire } from 'node:module';
+const require = createRequire(import.meta.url);
export class CommandHelp {
constructor(public command: { args?: { [name: string]: any } }) {}
diff --git a/lib/utils/patterns.ts b/lib/utils/patterns.ts
index ebae0aa6..a9ec0bbf 100644
--- a/lib/utils/patterns.ts
+++ b/lib/utils/patterns.ts
@@ -24,13 +24,13 @@ import type {
PineTypedResult,
} from 'balena-sdk';
-import { instanceOf, NotLoggedInError, ExpectedError } from '../errors';
-import { getBalenaSdk, getVisuals, stripIndent, getCliForm } from './lazy';
-import validation = require('./validation');
-import { delay } from './helpers';
+import { instanceOf, NotLoggedInError, ExpectedError } from '../errors.js';
+import { getBalenaSdk, getVisuals, stripIndent, getCliForm } from './lazy.js';
+import * as validation from './validation.js';
+import { delay } from './helpers.js';
-export function authenticate(options: object): Promise {
- const balena = getBalenaSdk();
+export async function authenticate(options: object): Promise {
+ const balena = await getBalenaSdk();
return getCliForm()
.run(
[
@@ -81,7 +81,7 @@ export function authenticate(options: object): Promise {
* Note: `NotLoggedInError` is an `ExpectedError`.
*/
export async function checkLoggedIn(): Promise {
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
if (!(await balena.auth.isLoggedIn())) {
throw new NotLoggedInError(stripIndent`
Login required: use the “balena login” command to log in.
@@ -116,7 +116,7 @@ export function askLoginType() {
}
export async function selectDeviceType() {
- const sdk = getBalenaSdk();
+ const sdk = await getBalenaSdk();
let deviceTypes = await sdk.models.deviceType.getAllSupported();
if (deviceTypes.length === 0) {
// Without this open-balena users would get an empty list
@@ -184,7 +184,7 @@ export async function selectApplication(
| ((app: SelectApplicationResult) => boolean),
errorOnEmptySelection = false,
) {
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
let apps = (await balena.models.application.getAllDirectlyAccessible({
...selectApplicationPineOptions,
...(filter != null && typeof filter === 'object' && { $filter: filter }),
@@ -215,7 +215,9 @@ export async function selectOrganization(
organizations?: Array>,
) {
// Use either provided orgs (if e.g. already loaded) or load from cloud
- organizations ??= await getBalenaSdk().models.organization.getAll({
+ organizations ??= await (
+ await getBalenaSdk()
+ ).models.organization.getAll({
$select: ['name', 'handle'],
});
return getCliForm().ask({
@@ -229,8 +231,8 @@ export async function selectOrganization(
}
export async function getAndSelectOrganization() {
- const { getOwnOrganizations } = await import('./sdk');
- const organizations = await getOwnOrganizations(getBalenaSdk(), {
+ const { getOwnOrganizations } = await import('./sdk.js');
+ const organizations = await getOwnOrganizations(await getBalenaSdk(), {
$select: ['name', 'handle'],
});
@@ -250,7 +252,7 @@ export async function awaitDeviceOsUpdate(
uuid: string,
targetOsVersion: string,
) {
- const balena = getBalenaSdk();
+ const balena = await getBalenaSdk();
const deviceName = await balena.models.device.getName(uuid);
const visuals = getVisuals();
@@ -304,7 +306,7 @@ export async function getOnlineTargetDeviceUuid(
sdk: BalenaSDK,
fleetOrDevice: string,
) {
- const logger = (await import('../utils/logger')).getLogger();
+ const logger = (await import('../utils/logger.js')).default.getLogger();
// If looks like UUID, probably device
if (validation.validateUuid(fleetOrDevice)) {
@@ -337,7 +339,7 @@ export async function getOnlineTargetDeviceUuid(
const application = await (async () => {
try {
logger.logDebug(`Fetching fleet ${fleetOrDevice}`);
- const { getApplication } = await import('./sdk');
+ const { getApplication } = await import('./sdk.js');
return await getApplication(sdk, fleetOrDevice, {
$select: ['id', 'slug'],
$expand: {
@@ -383,6 +385,7 @@ export function selectFromList(
message: string,
choices: Array,
): Promise {
+ // @ts-expect-error promise
return getCliForm().ask({
message,
type: 'list',
diff --git a/lib/utils/promote.ts b/lib/utils/promote.ts
index 805dc259..cbd4150a 100644
--- a/lib/utils/promote.ts
+++ b/lib/utils/promote.ts
@@ -16,11 +16,11 @@
*/
import type * as BalenaSdk from 'balena-sdk';
-import { ExpectedError, printErrorMessage } from '../errors';
-import { getVisuals, stripIndent, getCliForm } from './lazy';
-import Logger = require('./logger');
-import { confirm } from './patterns';
-import { getLocalDeviceCmdStdout, getDeviceOsRelease } from './ssh';
+import { ExpectedError, printErrorMessage } from '../errors.js';
+import { getVisuals, stripIndent, getCliForm } from './lazy.js';
+import Logger from './logger.js';
+import { confirm } from './patterns.js';
+import { getLocalDeviceCmdStdout, getDeviceOsRelease } from './ssh.js';
const MIN_BALENAOS_VERSION = 'v2.14.0';
@@ -167,7 +167,7 @@ const dockerPort = 2375;
const dockerTimeout = 2000;
async function selectLocalBalenaOsDevice(timeout = 4000): Promise {
- const { discoverLocalBalenaOsDevices } = await import('../utils/discover');
+ const { discoverLocalBalenaOsDevices } = await import('../utils/discover.js');
const { SpinnerPromise } = getVisuals();
const devices = await new SpinnerPromise({
promise: discoverLocalBalenaOsDevices(timeout),
@@ -185,7 +185,7 @@ async function selectLocalBalenaOsDevice(timeout = 4000): Promise {
}
try {
- const docker = new Docker({
+ const docker = new Docker.default({
host: address,
port: dockerPort,
timeout: dockerTimeout,
@@ -231,7 +231,7 @@ async function selectAppFromList(
applications: ApplicationWithDeviceTypeSlug[],
): Promise {
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
// name (user/fleetname) and allows them to select.
@@ -384,7 +384,7 @@ async function createApplication(
deviceType: string,
name?: string,
): Promise {
- const validation = await import('./validation');
+ const validation = await import('./validation.js');
let username: string;
try {
@@ -447,7 +447,7 @@ async function generateApplicationConfig(
appUpdatePollInterval?: number;
},
) {
- const { generateApplicationConfig: configGen } = await import('./config');
+ const { generateApplicationConfig: configGen } = await import('./config.js');
const manifest = await sdk.models.config.getDeviceTypeManifestBySlug(
app.is_for__device_type[0].slug,
diff --git a/lib/utils/proxy.ts b/lib/utils/proxy.ts
index ebc7aa72..5f49ec49 100644
--- a/lib/utils/proxy.ts
+++ b/lib/utils/proxy.ts
@@ -18,7 +18,7 @@
import type { Options as GlobalTunnelNgConfig } from 'global-tunnel-ng';
export type { GlobalTunnelNgConfig };
-import { CliSettings } from './bootstrap';
+import { CliSettings } from './bootstrap.js';
type ProxyConfig = string | GlobalTunnelNgConfig;
diff --git a/lib/utils/qemu.ts b/lib/utils/qemu.ts
index a9e379dc..5e1a2824 100644
--- a/lib/utils/qemu.ts
+++ b/lib/utils/qemu.ts
@@ -17,23 +17,23 @@
import type * as Dockerode from 'dockerode';
-import { ExpectedError } from '../errors';
-import { getBalenaSdk, stripIndent } from './lazy';
-import Logger = require('./logger');
+import { ExpectedError } from '../errors.js';
+import { getBalenaSdk, stripIndent } from './lazy.js';
+import type Logger from './logger.js';
export const QEMU_VERSION = 'v7.0.0+balena1';
export const QEMU_BIN_NAME = 'qemu-execve';
-export function qemuPathInContext(context: string) {
- const path = require('path') as typeof import('path');
+export async function qemuPathInContext(context: string) {
+ const path = await import('path');
const binDir = path.join(context, '.balena');
const binPath = path.join(binDir, QEMU_BIN_NAME);
return path.relative(context, binPath);
}
-export function copyQemu(context: string, arch: string) {
- const path = require('path') as typeof import('path');
- const fs = require('fs') as typeof import('fs');
+export async function copyQemu(context: string, arch: string) {
+ const path = await import('path');
+ const fs = await import('fs');
// Create a hidden directory in the build context, containing qemu
const binDir = path.join(context, '.balena');
const binPath = path.join(binDir, QEMU_BIN_NAME);
@@ -65,11 +65,11 @@ export function copyQemu(context: string, arch: string) {
.then(() => path.relative(context, binPath));
}
-export const getQemuPath = function (balenaArch: string) {
+export const getQemuPath = async function (balenaArch: string) {
const qemuArch = balenaArchToQemuArch(balenaArch);
- const balena = getBalenaSdk();
- const path = require('path') as typeof import('path');
- const { promises: fs } = require('fs') as typeof import('fs');
+ const balena = await getBalenaSdk();
+ const path = await import('path');
+ const { promises: fs } = await import('fs');
return balena.settings.get('binDirectory').then((binDir) =>
fs
@@ -117,7 +117,8 @@ async function installQemu(arch: string, qemuPath: string) {
reject(err);
}
});
- request(qemuUrl)
+ request
+ .default(qemuUrl)
.on('error', reject)
.pipe(zlib.createGunzip())
.on('error', reject)
diff --git a/lib/utils/remote-build.ts b/lib/utils/remote-build.ts
index 3ed2271f..08fe743a 100644
--- a/lib/utils/remote-build.ts
+++ b/lib/utils/remote-build.ts
@@ -13,19 +13,22 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
+import { createRequire } from 'node:module';
+const require = createRequire(import.meta.url);
+
import type { BalenaSDK } from 'balena-sdk';
import * as JSONStream from 'JSONStream';
import * as readline from 'readline';
import * as request from 'request';
import { RegistrySecrets } from '@balena/compose/dist/multibuild';
import type * as Stream from 'stream';
-import streamToPromise = require('stream-to-promise');
+import streamToPromise from 'stream-to-promise';
import type { Pack } from 'tar-stream';
-import { ExpectedError, SIGINTError } from '../errors';
-import { tarDirectory } from './compose_ts';
-import { getVisuals, stripIndent } from './lazy';
-import Logger = require('./logger');
+import { ExpectedError, SIGINTError } from '../errors.js';
+import { tarDirectory } from './compose_ts.js';
+import { getVisuals, stripIndent } from './lazy.js';
+import Logger from './logger.js';
const globalLogger = Logger.getLogger();
@@ -126,7 +129,7 @@ export async function startRemoteBuild(
}
};
- const { addSIGINTHandler } = await import('./helpers');
+ const { addSIGINTHandler } = await import('./helpers.js');
addSIGINTHandler(sigintHandler);
try {
diff --git a/lib/utils/sdk.ts b/lib/utils/sdk.ts
index 0df612df..4e95833f 100644
--- a/lib/utils/sdk.ts
+++ b/lib/utils/sdk.ts
@@ -42,7 +42,7 @@ export async function getApplication(
nameOrSlugOrId: string | number,
options?: PineOptions,
): Promise {
- const { looksLikeFleetSlug } = await import('./validation');
+ const { looksLikeFleetSlug } = await import('./validation.js');
const whoamiResult = await sdk.auth.whoami();
const isDeviceActor = whoamiResult?.actorType === 'device';
@@ -97,7 +97,7 @@ export async function getFleetSlug(
sdk: BalenaSDK,
nameOrSlug: string,
): Promise {
- const { looksLikeFleetSlug } = await import('./validation');
+ const { looksLikeFleetSlug } = await import('./validation.js');
if (!looksLikeFleetSlug(nameOrSlug)) {
// Not a slug: must be an app name.
// TODO: revisit this logic when we add support for fleet UUIDs.
diff --git a/lib/utils/ssh.ts b/lib/utils/ssh.ts
index 830f63d4..13939b95 100644
--- a/lib/utils/ssh.ts
+++ b/lib/utils/ssh.ts
@@ -15,9 +15,9 @@
* limitations under the License.
*/
import { spawn, StdioOptions } from 'child_process';
-import * as _ from 'lodash';
+import _ from 'lodash';
-import { ExpectedError } from '../errors';
+import { ExpectedError } from '../errors.js';
export class SshPermissionDeniedError extends ExpectedError {}
@@ -126,7 +126,7 @@ export async function runRemoteCommand({
} else {
ignoreStdin = false;
}
- const { which } = await import('./which');
+ const { which } = await import('./which.js');
const program = await which('ssh');
const args = sshArgsForRemoteCommand({
cmd,
@@ -139,7 +139,7 @@ export async function runRemoteCommand({
});
if (process.env.DEBUG) {
- const logger = (await import('./logger')).getLogger();
+ const logger = (await import('./logger.js')).default.getLogger();
logger.logDebug(`Executing [${program},${args}]`);
}
@@ -295,11 +295,11 @@ export const findBestUsernameForDevice = _.memoize(
if (await isRootUserGood(hostname, port)) {
username = 'root';
} else {
- const { getCachedUsername } = await import('./bootstrap');
+ const { getCachedUsername } = await import('./bootstrap.js');
username = (await getCachedUsername())?.username;
}
if (!username) {
- const { stripIndent } = await import('./lazy');
+ const { stripIndent } = await import('./lazy.js');
throw new ExpectedError(stripIndent`
SSH authentication failed for 'root@${hostname}'.
Please login with 'balena login' for alternative authentication.`);
diff --git a/lib/utils/streams.ts b/lib/utils/streams.ts
index 23f51e88..e8459e66 100644
--- a/lib/utils/streams.ts
+++ b/lib/utils/streams.ts
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import fs = require('fs');
+import fs from 'fs';
export function buffer(
stream: NodeJS.ReadableStream,
diff --git a/lib/utils/sudo.ts b/lib/utils/sudo.ts
index 9cf7de9d..1ec540e8 100644
--- a/lib/utils/sudo.ts
+++ b/lib/utils/sudo.ts
@@ -14,9 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+import { createRequire } from 'node:module';
+const require = createRequire(import.meta.url);
import { ChildProcess, spawn, SpawnOptions } from 'child_process';
-import { stripIndent } from './lazy';
+import { stripIndent } from './lazy.js';
/**
* Execute a child process with admin / superuser privileges, prompting the user for
@@ -42,8 +44,8 @@ export async function executeWithPrivileges(
isCLIcmd = true,
): Promise {
// whether the CLI is already running with admin / super user privileges
- const isElevated = await (await import('is-elevated'))();
- const { shellEscape } = await import('./helpers');
+ const isElevated = await (await import('is-elevated')).default();
+ const { shellEscape } = await import('./helpers.js');
const opts: SpawnOptions = {
env: process.env,
stdio: ['inherit', 'inherit', stderr ? 'pipe' : 'inherit'],
diff --git a/lib/utils/tty.ts b/lib/utils/tty.ts
index 7c786956..a6e29cde 100644
--- a/lib/utils/tty.ts
+++ b/lib/utils/tty.ts
@@ -14,6 +14,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+import { createRequire } from 'node:module';
+const require = createRequire(import.meta.url);
const windowSize: { width?: number; height?: number } = {};
@@ -25,7 +27,7 @@ const updateWindowSize = () => {
process.stdout.on('resize', updateWindowSize);
-export = (stream: NodeJS.WriteStream = process.stdout) => {
+const tty = (stream: NodeJS.WriteStream = process.stdout) => {
// make sure we get initial metrics
updateWindowSize();
@@ -73,3 +75,5 @@ export = (stream: NodeJS.WriteStream = process.stdout) => {
deleteToEnd,
};
};
+
+export default tty;
diff --git a/lib/utils/tunnel.ts b/lib/utils/tunnel.ts
index 5e37863a..5c409187 100644
--- a/lib/utils/tunnel.ts
+++ b/lib/utils/tunnel.ts
@@ -17,7 +17,7 @@ import type { BalenaSDK } from 'balena-sdk';
import { Socket } from 'net';
import * as tls from 'tls';
import { TypedError } from 'typed-error';
-import { ExpectedError } from '../errors';
+import { ExpectedError } from '../errors.js';
const PROXY_CONNECT_TIMEOUT_MS = 10000;
diff --git a/lib/utils/umount.ts b/lib/utils/umount.ts
index 335a9536..37ab045e 100644
--- a/lib/utils/umount.ts
+++ b/lib/utils/umount.ts
@@ -39,7 +39,7 @@ export async function umount(device: string): Promise {
if (process.platform === 'win32') {
return;
}
- const { sanitizePath, whichBin } = await import('./which');
+ const { sanitizePath, whichBin } = await import('./which.js');
// sanitize user's input (regular expression attacks ?)
device = sanitizePath(device);
const cmd: string[] = [];
@@ -48,7 +48,7 @@ export async function umount(device: string): Promise {
cmd.push('/usr/sbin/diskutil', 'unmountDisk', 'force', device);
} else {
// 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
// like '/dev/sdb1', '/dev/sdb2', ..., '/dev/sdb11', ... (partitions)
// that exist for balenaOS images and are needed as arguments to 'umount'
@@ -75,7 +75,7 @@ export async function umount(device: string): Promise {
}
return;
}
- const { ExpectedError } = await import('../errors');
+ const { ExpectedError } = await import('../errors.js');
throw new ExpectedError(msg.join('\n'));
}
}
@@ -92,7 +92,7 @@ export async function isMounted(device: string): Promise {
if (!device) {
return false;
}
- const { whichBin } = await import('./which');
+ const { whichBin } = await import('./which.js');
const mountCmd = await whichBin('mount');
let stdout = '';
let stderr = '';
@@ -101,7 +101,7 @@ export async function isMounted(device: string): Promise {
stdout = proc.stdout;
stderr = proc.stderr;
} catch (err) {
- const { ExpectedError } = await import('../errors');
+ const { ExpectedError } = await import('../errors.js');
throw new ExpectedError(
`Error executing "${mountCmd}":\n${stderr}\n${err.message}`,
);
@@ -131,7 +131,7 @@ export async function denyMount(
handler: () => any,
opts: { autoMountOnSuccess?: boolean; executablePath?: string } = {},
) {
- const denymount = promisify(await import('denymount'));
+ const denymount = promisify((await import('denymount')).default);
if (process.pkg) {
// when running in a standalone pkg install, the 'denymount'
// executable is placed on the same folder as process.execPath
diff --git a/lib/utils/update.ts b/lib/utils/update.ts
index caf1ca2e..4aa12f52 100644
--- a/lib/utils/update.ts
+++ b/lib/utils/update.ts
@@ -13,11 +13,13 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
+import { createRequire } from 'node:module';
+const require = createRequire(import.meta.url);
-import isRoot = require('is-root');
-import * as UpdateNotifier from 'update-notifier';
+import isRoot from 'is-root';
+import UpdateNotifier from 'update-notifier';
-import packageJSON = require('../../package.json');
+import packageJSON from '../../package.json' assert {type: 'json'};;
// Check for an update at most once a day. 1 day granularity should be
// enough, rather than every run. Note because we show the information
diff --git a/lib/utils/validation.ts b/lib/utils/validation.ts
index 891ec39b..a86267a2 100644
--- a/lib/utils/validation.ts
+++ b/lib/utils/validation.ts
@@ -14,8 +14,8 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import validEmail = require('@resin.io/valid-email');
-import { ExpectedError } from '../errors';
+import validEmail from '@resin.io/valid-email';
+import { ExpectedError } from '../errors.js';
const APPNAME_REGEX = new RegExp(/^[a-zA-Z0-9_-]+$/);
// An regex to detect an IP address, from https://www.regular-expressions.info/ip.html
diff --git a/lib/utils/version.ts b/lib/utils/version.ts
index 739b3803..4f307438 100644
--- a/lib/utils/version.ts
+++ b/lib/utils/version.ts
@@ -16,7 +16,7 @@
*/
import * as semver from 'semver';
-import { version } from '../../package.json';
+import { version } from '../../package.json' assert {type: 'json'};;
export function isVersionGTE(v: string): boolean {
return semver.gte(process.env.BALENA_CLI_VERSION_OVERRIDE || version, v);
diff --git a/lib/utils/which.ts b/lib/utils/which.ts
index d35b72bb..679e4163 100644
--- a/lib/utils/which.ts
+++ b/lib/utils/which.ts
@@ -17,6 +17,8 @@
import { promises as fs, constants } from 'fs';
import * as path from 'path';
+import { createRequire } from 'node:module';
+const require = createRequire(import.meta.url);
export const { F_OK, R_OK, W_OK, X_OK } = constants;
@@ -76,14 +78,14 @@ export async function which(
program: string,
rejectOnMissing = true,
): Promise {
- const whichMod = await import('which');
+ const { default: whichMod } = await import('which');
let programPath: string;
try {
programPath = await whichMod(program);
} catch (err) {
if (err.code === 'ENOENT') {
if (rejectOnMissing) {
- const { ExpectedError } = await import('../errors');
+ const { ExpectedError } = await import('../errors.js');
throw new ExpectedError(
`'${program}' program not found. Is it installed?`,
);
diff --git a/package.json b/package.json
index d535376c..4bdd1bbb 100644
--- a/package.json
+++ b/package.json
@@ -8,6 +8,7 @@
"type": "git",
"url": "git@github.com:balena-io/balena-cli.git"
},
+ "type": "module",
"preferGlobal": true,
"files": [
"bin/.fast-boot.json",
@@ -21,7 +22,7 @@
"oclif.manifest.json"
],
"bin": {
- "balena": "./bin/balena"
+ "balena": "./bin/balena.js"
},
"pkg": {
"scripts": [
@@ -71,7 +72,7 @@
"ci": "npm run test && npm run catch-uncommitted",
"lint": "npm run lint-tsconfig && npm run lint-other",
"lint-tsconfig": "balena-lint -e ts -e js -t tsconfig.dev.json --fix automation/ lib/ tests/ typings/",
- "lint-other": "balena-lint -e ts -e js --fix bin/balena bin/balena-dev completion/ .mocharc.js .mocharc-standalone.js",
+ "lint-other": "balena-lint -e ts -e js --fix bin/balena.js bin/balena-dev.js completion/ .mocharc.js .mocharc-standalone.js",
"update": "ts-node --transpile-only ./automation/update-module.ts",
"prepare": "echo {} > bin/.fast-boot.json",
"prepublishOnly": "npm run build"
diff --git a/patches/all/oclif+4.0.3.patch b/patches/all/oclif+4.0.3.patch
index 212aa9da..ea092977 100644
--- a/patches/all/oclif+4.0.3.patch
+++ b/patches/all/oclif+4.0.3.patch
@@ -68,8 +68,8 @@ index 9ced03f..4040aee 100644
(0, promises_1.rm)(path.join(c.workspace(), path.basename(tarball)), { recursive: true }),
(0, fs_extra_1.remove)(path.join(c.workspace(), 'bin', 'run.cmd')),
]);
-+ // rename the original balena-cli ./bin/balena entry point for oclif compatibility
-+ await fs.move(path.join(c.workspace(), 'bin', 'balena'), path.join(c.workspace(), 'bin', 'run'));
++ // rename the original balena-cli ./bin/balena.js entry point for oclif compatibility
++ await fs.move(path.join(c.workspace(), 'bin', 'balena.js'), path.join(c.workspace(), 'bin', 'run.js'));
+ // The oclif installers are a production installation, while the source
+ // `bin` folder may contain a `.fast-boot.json` file of a dev installation.
+ // This has previously led to issues preventing the CLI from starting, so
diff --git a/patches/apply-patches.js b/patches/apply-patches.js
index 26c1118a..fbe02e23 100644
--- a/patches/apply-patches.js
+++ b/patches/apply-patches.js
@@ -15,11 +15,11 @@
* limitations under the License.
*/
-const { execFile } = require('child_process');
-const fs = require('fs');
-const path = require('path');
+import { execFile } from 'child_process';
+import fs from 'fs';
+import path from 'path';
-const { promisify } = require('util');
+import { promisify } from 'util';
const execFileAsync = promisify(execFile);
const patchesDir = 'patches';
@@ -80,4 +80,4 @@ async function run() {
}
}
-run();
+await run();
diff --git a/tests/auth/utils.spec.ts b/tests/auth/utils.spec.ts
index ad1e8285..c71b05e1 100644
--- a/tests/auth/utils.spec.ts
+++ b/tests/auth/utils.spec.ts
@@ -7,7 +7,7 @@ import { getBalenaSdk } from '../../build/utils/lazy';
import tokens from './tokens';
const utils = rewire('../../build/auth/utils');
-const balena = getBalenaSdk();
+const balena = await getBalenaSdk();
describe('Utils:', function () {
describe('.getDashboardLoginURL()', function () {
diff --git a/tests/deprecation.spec.ts b/tests/deprecation.spec.ts
index dcaf09b2..8efe0367 100644
--- a/tests/deprecation.spec.ts
+++ b/tests/deprecation.spec.ts
@@ -29,7 +29,7 @@ import {
} from '../build/deprecation';
import { BalenaAPIMock } from './nock/balena-api-mock';
import { NpmMock } from './nock/npm-mock';
-import { runCommand, TestOutput } from './helpers';
+import { runCommand, TestOutput } from './helpers.js';
// "itSS" means "it() Skip Standalone"
const itSS = process.env.BALENA_CLI_TEST_TYPE === 'standalone' ? it.skip : it;
diff --git a/tests/docker-build.ts b/tests/docker-build.ts
index bbe7c3e0..7f767797 100644
--- a/tests/docker-build.ts
+++ b/tests/docker-build.ts
@@ -36,7 +36,7 @@ import {
deepJsonParse,
deepTemplateReplace,
runCommand,
-} from './helpers';
+} from './helpers.js';
import {
ExpectedTarStreamFile,
ExpectedTarStreamFiles,
diff --git a/tsconfig.json b/tsconfig.json
index bfe183cb..d347434b 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"declaration": true,
- "module": "commonjs",
+ "module": "NodeNext",
"target": "es2018",
"outDir": "build",
"strict": true,
diff --git a/typings/resin-cli-form/index.d.ts b/typings/resin-cli-form/index.d.ts
index 625e4cb8..e83e9fef 100644
--- a/typings/resin-cli-form/index.d.ts
+++ b/typings/resin-cli-form/index.d.ts
@@ -16,7 +16,7 @@
*/
declare module 'resin-cli-form' {
- import Bluebird = require('bluebird');
+ import Bluebird from 'bluebird';
export type TypeOrPromiseLike = T | PromiseLike;