Skip to content

Commit 5dbc780

Browse files
committed
feat: add key commands
1 parent ba3293c commit 5dbc780

26 files changed

+1206
-352
lines changed

lib/bootstrap.ts

+9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { injector } from "./common/yok";
22

33
require("./common/bootstrap");
4+
45
injector.requirePublicClass("logger", "./common/logger/logger");
56
injector.require("config", "./config");
67
injector.require("options", "./options");
@@ -278,6 +279,7 @@ injector.require(
278279
"./helpers/android-bundle-validator-helper"
279280
);
280281
injector.require("liveSyncCommandHelper", "./helpers/livesync-command-helper");
282+
281283
injector.require("deployCommandHelper", "./helpers/deploy-command-helper");
282284
injector.require("platformCommandHelper", "./helpers/platform-command-helper");
283285
injector.require("optionsTracker", "./helpers/options-track-helper");
@@ -442,3 +444,10 @@ injector.require(
442444
injector.require("tempService", "./services/temp-service");
443445

444446
injector.require("sharedEventBus", "./shared-event-bus");
447+
448+
injector.require("keyCommandHelper", "./helpers/key-command-helper");
449+
450+
injector.requireCommand("start", "./commands/start");
451+
injector.require("startService", "./services/start-service");
452+
453+
require("./key-commands/bootstrap");

lib/color.ts

+5
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
// using chalk as some of our other dependencies are already using it...
22
// exporting from here so we can easily refactor to a different color library if needed
3+
import * as ansi from "ansi-colors";
34
import * as chalk from "chalk";
45

56
export type Color = typeof chalk.Color;
67

8+
export function stripColors(formatStr: string) {
9+
return ansi.stripColor(formatStr);
10+
}
11+
712
export const color = chalk;

lib/commands/run.ts

+23-14
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,25 @@
11
import { ERROR_NO_VALID_SUBCOMMAND_FORMAT } from "../common/constants";
2-
import {
3-
ANDROID_RELEASE_BUILD_ERROR_MESSAGE,
4-
ANDROID_APP_BUNDLE_SIGNING_ERROR_MESSAGE,
5-
} from "../constants";
2+
import { IErrors, IHostInfo } from "../common/declarations";
63
import { cache } from "../common/decorators";
7-
import { hasValidAndroidSigning } from "../common/helpers";
8-
import { IProjectData, IProjectDataService } from "../definitions/project";
9-
import { IMigrateController } from "../definitions/migrate";
10-
import { IOptions, IPlatformValidationService } from "../declarations";
114
import { ICommand, ICommandParameter } from "../common/definitions/commands";
12-
import { IErrors, IHostInfo } from "../common/declarations";
5+
import {
6+
IKeyCommandHelper,
7+
IKeyCommandPlatform,
8+
} from "../common/definitions/key-commands";
139
import { IInjector } from "../common/definitions/yok";
10+
import { hasValidAndroidSigning } from "../common/helpers";
1411
import { injector } from "../common/yok";
12+
import {
13+
ANDROID_APP_BUNDLE_SIGNING_ERROR_MESSAGE,
14+
ANDROID_RELEASE_BUILD_ERROR_MESSAGE,
15+
} from "../constants";
16+
import { IOptions, IPlatformValidationService } from "../declarations";
17+
import { IMigrateController } from "../definitions/migrate";
18+
import { IProjectData, IProjectDataService } from "../definitions/project";
1519

1620
export class RunCommandBase implements ICommand {
17-
private liveSyncCommandHelperAdditionalOptions: ILiveSyncCommandHelperAdditionalOptions = <
18-
ILiveSyncCommandHelperAdditionalOptions
19-
>{};
21+
private liveSyncCommandHelperAdditionalOptions: ILiveSyncCommandHelperAdditionalOptions =
22+
<ILiveSyncCommandHelperAdditionalOptions>{};
2023

2124
public platform: string;
2225
constructor(
@@ -26,15 +29,21 @@ export class RunCommandBase implements ICommand {
2629
private $liveSyncCommandHelper: ILiveSyncCommandHelper,
2730
private $migrateController: IMigrateController,
2831
private $options: IOptions,
29-
private $projectData: IProjectData
32+
private $projectData: IProjectData,
33+
private $keyCommandHelper: IKeyCommandHelper
3034
) {}
3135

3236
public allowedParameters: ICommandParameter[] = [];
3337
public async execute(args: string[]): Promise<void> {
34-
return this.$liveSyncCommandHelper.executeCommandLiveSync(
38+
await this.$liveSyncCommandHelper.executeCommandLiveSync(
3539
this.platform,
3640
this.liveSyncCommandHelperAdditionalOptions
3741
);
42+
43+
this.$keyCommandHelper.attachKeyCommands(
44+
this.platform as IKeyCommandPlatform,
45+
"run"
46+
);
3847
}
3948

4049
public async canExecute(args: string[]): Promise<boolean> {

lib/commands/start.ts

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { ICommand, ICommandParameter } from "../common/definitions/commands";
2+
import { injector } from "../common/yok";
3+
import { IStartService } from "../definitions/start-service";
4+
5+
export class StartCommand implements ICommand {
6+
constructor(private $startService: IStartService) {}
7+
async execute(args: string[]): Promise<void> {
8+
this.$startService.start();
9+
return;
10+
}
11+
allowedParameters: ICommandParameter[];
12+
async canExecute?(args: string[]): Promise<boolean> {
13+
return true;
14+
}
15+
}
16+
17+
injector.registerCommand("start", StartCommand);
+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
export type IKeyCommandPlatform = "Android" | "iOS" | "all";
2+
export type IKeysLowerCase =
3+
| "a"
4+
| "b"
5+
| "c"
6+
| "d"
7+
| "e"
8+
| "f"
9+
| "g"
10+
| "h"
11+
| "i"
12+
| "j"
13+
| "k"
14+
| "l"
15+
| "m"
16+
| "n"
17+
| "o"
18+
| "p"
19+
| "q"
20+
| "r"
21+
| "s"
22+
| "t"
23+
| "u"
24+
| "v"
25+
| "w"
26+
| "x"
27+
| "y"
28+
| "z";
29+
30+
export type IValidKeyCommands = IKeysLowerCase | `${Uppercase<IKeysLowerCase>}`;
31+
32+
export interface IKeyCommandHelper {
33+
attachKeyCommands: (
34+
platform: IKeyCommandPlatform,
35+
processType: SupportedProcessType
36+
) => void;
37+
38+
addOverride(key: IValidKeyCommands, execute: () => Promise<boolean>);
39+
removeOverride(key: IValidKeyCommands);
40+
printCommands(platform: IKeyCommandPlatform): void;
41+
}
42+
43+
export type SupportedProcessType = "start" | "run";
44+
45+
export interface IKeyCommand {
46+
key: IValidKeyCommands;
47+
platform: IKeyCommandPlatform;
48+
description: string;
49+
willBlockKeyCommandExecution?: boolean;
50+
execute(platform: string): Promise<void>;
51+
canExecute?: (processType: SupportedProcessType) => boolean;
52+
}

lib/common/definitions/yok.d.ts

+5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { IDisposable, IDictionary } from "../declarations";
22
import { ICommand } from "./commands";
3+
import { IKeyCommand, IValidKeyCommands } from "./key-commands";
34

45
interface IInjector extends IDisposable {
56
require(name: string, file: string): void;
@@ -8,6 +9,7 @@ interface IInjector extends IDisposable {
89
requirePublicClass(names: string | string[], file: string): void;
910
requireCommand(name: string, file: string): void;
1011
requireCommand(names: string[], file: string): void;
12+
requireKeyCommand(name: string, file: string): void;
1113
/**
1214
* Resolves an implementation by constructor function.
1315
* The injector will create new instances for every call.
@@ -22,10 +24,13 @@ interface IInjector extends IDisposable {
2224
resolve<T>(name: string, ctorArguments?: IDictionary<any>): T;
2325

2426
resolveCommand(name: string): ICommand;
27+
resolveKeyCommand(key: string): IKeyCommand;
2528
register(name: string, resolver: any, shared?: boolean): void;
2629
registerCommand(name: string, resolver: any): void;
2730
registerCommand(names: string[], resolver: any): void;
31+
registerKeyCommand(key: IValidKeyCommands, resolver: any): void;
2832
getRegisteredCommandsNames(includeDev: boolean): string[];
33+
getRegisteredKeyCommandsNames(): string[];
2934
dynamicCallRegex: RegExp;
3035
dynamicCall(call: string, args?: any[]): Promise<any>;
3136
isDefaultCommand(commandName: string): boolean;

lib/common/header.ts

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { color, stripColors } from "../color";
2+
3+
export function printHeader() {
4+
if (process.env.HIDE_HEADER) return;
5+
const version = "8.5.3";
6+
const middle = [
7+
color.dim("│ "),
8+
color.cyanBright.bold(" {N} NativeScript "),
9+
color.whiteBright.bold("CLI"),
10+
color.dim(` [v${version}] `),
11+
color.dim(" │"),
12+
].join("");
13+
const middle2 = [
14+
color.dim("│ "),
15+
color.whiteBright.bold(" Empowering JS with Native APIs "),
16+
color.dim(" │"),
17+
].join("");
18+
19+
const end = [color.dim("─┘")].join("");
20+
21+
const width = stripColors(middle).length;
22+
const endWidth = stripColors(end).length;
23+
console.info(" ");
24+
console.info(" " + color.dim("┌" + "─".repeat(width - 2) + "┐"));
25+
console.info(" " + middle);
26+
console.info(" " + middle2);
27+
console.info(" " + color.dim("└" + "─".repeat(width - endWidth - 1)) + end);
28+
}

lib/common/mobile/mobile-core/android-device-discovery.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ interface IAdbAndroidDeviceInfo {
1111

1212
export class AndroidDeviceDiscovery
1313
extends DeviceDiscovery
14-
implements Mobile.IAndroidDeviceDiscovery {
14+
implements Mobile.IAndroidDeviceDiscovery
15+
{
1516
private _devices: IAdbAndroidDeviceInfo[] = [];
1617
private isStarted: boolean;
1718

@@ -56,7 +57,6 @@ export class AndroidDeviceDiscovery
5657

5758
private async checkForDevices(): Promise<void> {
5859
const devices = await this.$adb.getDevices();
59-
6060
await this.checkCurrentData(devices);
6161
}
6262

lib/common/mobile/mobile-core/devices-service.ts

+19-19
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,28 @@
1-
import * as util from "util";
2-
import * as helpers from "../../helpers";
31
import * as assert from "assert";
4-
import * as _ from "lodash";
5-
import * as constants from "../../constants";
6-
import { exported } from "../../decorators";
7-
import { settlePromises } from "../../helpers";
82
import { EventEmitter } from "events";
3+
import * as _ from "lodash";
94
import { EOL } from "os";
10-
import { CONNECTED_STATUS } from "../../constants";
11-
import { isInteractive } from "../../helpers";
5+
import * as util from "util";
126
import { DebugCommandErrors } from "../../../constants";
13-
import { performanceLog } from "../../decorators";
7+
import { IOptions } from "../../../declarations";
8+
import * as constants from "../../constants";
9+
import { CONNECTED_STATUS } from "../../constants";
1410
import {
11+
IAppInstalledInfo,
1512
IDictionary,
1613
IErrors,
1714
IHostInfo,
18-
IAppInstalledInfo,
1915
} from "../../declarations";
16+
import { exported, performanceLog } from "../../decorators";
2017
import { IInjector } from "../../definitions/yok";
18+
import * as helpers from "../../helpers";
19+
import { isInteractive, settlePromises } from "../../helpers";
2120
import { injector } from "../../yok";
22-
import { IOptions } from "../../../declarations";
2321

2422
export class DevicesService
2523
extends EventEmitter
26-
implements Mobile.IDevicesService {
24+
implements Mobile.IDevicesService
25+
{
2726
private static DEVICE_LOOKING_INTERVAL = 200;
2827
private static EMULATOR_IMAGES_DETECTION_INTERVAL = 60 * 1000;
2928
private _devices: IDictionary<Mobile.IDevice> = {};
@@ -190,9 +189,10 @@ export class DevicesService
190189
const availableEmulatorsOutput = await this.getEmulatorImages({
191190
platform: options.platform,
192191
});
193-
const emulators = this.$emulatorHelper.getEmulatorsFromAvailableEmulatorsOutput(
194-
availableEmulatorsOutput
195-
);
192+
const emulators =
193+
this.$emulatorHelper.getEmulatorsFromAvailableEmulatorsOutput(
194+
availableEmulatorsOutput
195+
);
196196
const errors = this.$emulatorHelper.getErrorsFromAvailableEmulatorsOutput(
197197
availableEmulatorsOutput
198198
);
@@ -893,7 +893,7 @@ export class DevicesService
893893
// TODO: Remove from here as it calls startLookingForDevices, so we double the calls to specific device detection services
894894
await this.startEmulatorIfNecessary(deviceInitOpts);
895895
}
896-
896+
deviceInitOpts;
897897
const platform = deviceInitOpts.platform;
898898
const deviceOption = deviceInitOpts.deviceId;
899899
const deviceLookingOptions: Mobile.IDeviceLookingOptions = {
@@ -910,6 +910,7 @@ export class DevicesService
910910
);
911911
await this.startLookingForDevices(deviceLookingOptions);
912912
this._device = await this.getDevice(deviceOption);
913+
913914
if (this._device.deviceInfo.platform !== this._platform) {
914915
this.$errors.fail(constants.ERROR_CANNOT_RESOLVE_DEVICE);
915916
}
@@ -1023,9 +1024,8 @@ export class DevicesService
10231024
appIdentifier: string
10241025
): Promise<Mobile.IDebugWebViewInfo[]> {
10251026
const device = this.getDeviceByIdentifier(deviceIdentifier),
1026-
debuggableViewsPerApp = await device.applicationManager.getDebuggableAppViews(
1027-
[appIdentifier]
1028-
);
1027+
debuggableViewsPerApp =
1028+
await device.applicationManager.getDebuggableAppViews([appIdentifier]);
10291029

10301030
return debuggableViewsPerApp && debuggableViewsPerApp[appIdentifier];
10311031
}

lib/common/services/commands-service.ts

+8-6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
ICommand,
2020
ISimilarCommand,
2121
} from "../definitions/commands";
22+
import { printHeader } from "../header";
2223

2324
class CommandArgumentsValidationHelper {
2425
constructor(public isValid: boolean, _remainingArguments: string[]) {
@@ -65,9 +66,8 @@ export class CommandsService implements ICommandsService {
6566
!command.disableAnalytics &&
6667
!this.$options.disableAnalytics
6768
) {
68-
const analyticsService = this.$injector.resolve<IAnalyticsService>(
69-
"analyticsService"
70-
); // This should be resolved here due to cyclic dependency
69+
const analyticsService =
70+
this.$injector.resolve<IAnalyticsService>("analyticsService"); // This should be resolved here due to cyclic dependency
7171
await analyticsService.checkConsent();
7272

7373
const beautifiedCommandName = this.beautifyCommandName(
@@ -183,6 +183,7 @@ export class CommandsService implements ICommandsService {
183183
: canExecuteResult;
184184

185185
if (canExecute) {
186+
printHeader();
186187
await this.executeCommandAction(
187188
commandName,
188189
commandArguments,
@@ -246,9 +247,10 @@ export class CommandsService implements ICommandsService {
246247
defaultCommandDelimiter: CommandsDelimiters.DefaultHierarchicalCommand,
247248
};
248249

249-
const extensionData = await this.$extensibilityService.getExtensionNameWhereCommandIsRegistered(
250-
commandInfo
251-
);
250+
const extensionData =
251+
await this.$extensibilityService.getExtensionNameWhereCommandIsRegistered(
252+
commandInfo
253+
);
252254

253255
if (extensionData) {
254256
this.$logger.warn(extensionData.installationMessage);

0 commit comments

Comments
 (0)