Skip to content

Commit

Permalink
feat: add key commands
Browse files Browse the repository at this point in the history
  • Loading branch information
ammarahm-ed committed Aug 27, 2023
1 parent ba3293c commit 5dbc780
Show file tree
Hide file tree
Showing 26 changed files with 1,206 additions and 352 deletions.
9 changes: 9 additions & 0 deletions lib/bootstrap.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { injector } from "./common/yok";

require("./common/bootstrap");

injector.requirePublicClass("logger", "./common/logger/logger");
injector.require("config", "./config");
injector.require("options", "./options");
Expand Down Expand Up @@ -278,6 +279,7 @@ injector.require(
"./helpers/android-bundle-validator-helper"
);
injector.require("liveSyncCommandHelper", "./helpers/livesync-command-helper");

injector.require("deployCommandHelper", "./helpers/deploy-command-helper");
injector.require("platformCommandHelper", "./helpers/platform-command-helper");
injector.require("optionsTracker", "./helpers/options-track-helper");
Expand Down Expand Up @@ -442,3 +444,10 @@ injector.require(
injector.require("tempService", "./services/temp-service");

injector.require("sharedEventBus", "./shared-event-bus");

injector.require("keyCommandHelper", "./helpers/key-command-helper");

injector.requireCommand("start", "./commands/start");
injector.require("startService", "./services/start-service");

require("./key-commands/bootstrap");
5 changes: 5 additions & 0 deletions lib/color.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
// using chalk as some of our other dependencies are already using it...
// exporting from here so we can easily refactor to a different color library if needed
import * as ansi from "ansi-colors";
import * as chalk from "chalk";

export type Color = typeof chalk.Color;

export function stripColors(formatStr: string) {
return ansi.stripColor(formatStr);
}

export const color = chalk;
37 changes: 23 additions & 14 deletions lib/commands/run.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,25 @@
import { ERROR_NO_VALID_SUBCOMMAND_FORMAT } from "../common/constants";
import {
ANDROID_RELEASE_BUILD_ERROR_MESSAGE,
ANDROID_APP_BUNDLE_SIGNING_ERROR_MESSAGE,
} from "../constants";
import { IErrors, IHostInfo } from "../common/declarations";
import { cache } from "../common/decorators";
import { hasValidAndroidSigning } from "../common/helpers";
import { IProjectData, IProjectDataService } from "../definitions/project";
import { IMigrateController } from "../definitions/migrate";
import { IOptions, IPlatformValidationService } from "../declarations";
import { ICommand, ICommandParameter } from "../common/definitions/commands";
import { IErrors, IHostInfo } from "../common/declarations";
import {
IKeyCommandHelper,
IKeyCommandPlatform,
} from "../common/definitions/key-commands";
import { IInjector } from "../common/definitions/yok";
import { hasValidAndroidSigning } from "../common/helpers";
import { injector } from "../common/yok";
import {
ANDROID_APP_BUNDLE_SIGNING_ERROR_MESSAGE,
ANDROID_RELEASE_BUILD_ERROR_MESSAGE,
} from "../constants";
import { IOptions, IPlatformValidationService } from "../declarations";
import { IMigrateController } from "../definitions/migrate";
import { IProjectData, IProjectDataService } from "../definitions/project";

export class RunCommandBase implements ICommand {
private liveSyncCommandHelperAdditionalOptions: ILiveSyncCommandHelperAdditionalOptions = <
ILiveSyncCommandHelperAdditionalOptions
>{};
private liveSyncCommandHelperAdditionalOptions: ILiveSyncCommandHelperAdditionalOptions =
<ILiveSyncCommandHelperAdditionalOptions>{};

public platform: string;
constructor(
Expand All @@ -26,15 +29,21 @@ export class RunCommandBase implements ICommand {
private $liveSyncCommandHelper: ILiveSyncCommandHelper,
private $migrateController: IMigrateController,
private $options: IOptions,
private $projectData: IProjectData
private $projectData: IProjectData,
private $keyCommandHelper: IKeyCommandHelper
) {}

public allowedParameters: ICommandParameter[] = [];
public async execute(args: string[]): Promise<void> {
return this.$liveSyncCommandHelper.executeCommandLiveSync(
await this.$liveSyncCommandHelper.executeCommandLiveSync(
this.platform,
this.liveSyncCommandHelperAdditionalOptions
);

this.$keyCommandHelper.attachKeyCommands(
this.platform as IKeyCommandPlatform,
"run"
);
}

public async canExecute(args: string[]): Promise<boolean> {
Expand Down
17 changes: 17 additions & 0 deletions lib/commands/start.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { ICommand, ICommandParameter } from "../common/definitions/commands";
import { injector } from "../common/yok";
import { IStartService } from "../definitions/start-service";

export class StartCommand implements ICommand {
constructor(private $startService: IStartService) {}
async execute(args: string[]): Promise<void> {
this.$startService.start();
return;
}
allowedParameters: ICommandParameter[];
async canExecute?(args: string[]): Promise<boolean> {
return true;
}
}

injector.registerCommand("start", StartCommand);
52 changes: 52 additions & 0 deletions lib/common/definitions/key-commands.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
export type IKeyCommandPlatform = "Android" | "iOS" | "all";
export type IKeysLowerCase =
| "a"
| "b"
| "c"
| "d"
| "e"
| "f"
| "g"
| "h"
| "i"
| "j"
| "k"
| "l"
| "m"
| "n"
| "o"
| "p"
| "q"
| "r"
| "s"
| "t"
| "u"
| "v"
| "w"
| "x"
| "y"
| "z";

export type IValidKeyCommands = IKeysLowerCase | `${Uppercase<IKeysLowerCase>}`;

export interface IKeyCommandHelper {
attachKeyCommands: (
platform: IKeyCommandPlatform,
processType: SupportedProcessType
) => void;

addOverride(key: IValidKeyCommands, execute: () => Promise<boolean>);
removeOverride(key: IValidKeyCommands);
printCommands(platform: IKeyCommandPlatform): void;
}

export type SupportedProcessType = "start" | "run";

export interface IKeyCommand {
key: IValidKeyCommands;
platform: IKeyCommandPlatform;
description: string;
willBlockKeyCommandExecution?: boolean;
execute(platform: string): Promise<void>;
canExecute?: (processType: SupportedProcessType) => boolean;
}
5 changes: 5 additions & 0 deletions lib/common/definitions/yok.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { IDisposable, IDictionary } from "../declarations";
import { ICommand } from "./commands";
import { IKeyCommand, IValidKeyCommands } from "./key-commands";

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

resolveCommand(name: string): ICommand;
resolveKeyCommand(key: string): IKeyCommand;
register(name: string, resolver: any, shared?: boolean): void;
registerCommand(name: string, resolver: any): void;
registerCommand(names: string[], resolver: any): void;
registerKeyCommand(key: IValidKeyCommands, resolver: any): void;
getRegisteredCommandsNames(includeDev: boolean): string[];
getRegisteredKeyCommandsNames(): string[];
dynamicCallRegex: RegExp;
dynamicCall(call: string, args?: any[]): Promise<any>;
isDefaultCommand(commandName: string): boolean;
Expand Down
28 changes: 28 additions & 0 deletions lib/common/header.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { color, stripColors } from "../color";

export function printHeader() {
if (process.env.HIDE_HEADER) return;
const version = "8.5.3";
const middle = [
color.dim("│ "),
color.cyanBright.bold(" {N} NativeScript "),
color.whiteBright.bold("CLI"),
color.dim(` [v${version}] `),
color.dim(" │"),
].join("");
const middle2 = [
color.dim("│ "),
color.whiteBright.bold(" Empowering JS with Native APIs "),
color.dim(" │"),
].join("");

const end = [color.dim("─┘")].join("");

const width = stripColors(middle).length;
const endWidth = stripColors(end).length;
console.info(" ");
console.info(" " + color.dim("┌" + "─".repeat(width - 2) + "┐"));
console.info(" " + middle);
console.info(" " + middle2);
console.info(" " + color.dim("└" + "─".repeat(width - endWidth - 1)) + end);
}
4 changes: 2 additions & 2 deletions lib/common/mobile/mobile-core/android-device-discovery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ interface IAdbAndroidDeviceInfo {

export class AndroidDeviceDiscovery
extends DeviceDiscovery
implements Mobile.IAndroidDeviceDiscovery {
implements Mobile.IAndroidDeviceDiscovery
{
private _devices: IAdbAndroidDeviceInfo[] = [];
private isStarted: boolean;

Expand Down Expand Up @@ -56,7 +57,6 @@ export class AndroidDeviceDiscovery

private async checkForDevices(): Promise<void> {
const devices = await this.$adb.getDevices();

await this.checkCurrentData(devices);
}

Expand Down
38 changes: 19 additions & 19 deletions lib/common/mobile/mobile-core/devices-service.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
import * as util from "util";
import * as helpers from "../../helpers";
import * as assert from "assert";
import * as _ from "lodash";
import * as constants from "../../constants";
import { exported } from "../../decorators";
import { settlePromises } from "../../helpers";
import { EventEmitter } from "events";
import * as _ from "lodash";
import { EOL } from "os";
import { CONNECTED_STATUS } from "../../constants";
import { isInteractive } from "../../helpers";
import * as util from "util";
import { DebugCommandErrors } from "../../../constants";
import { performanceLog } from "../../decorators";
import { IOptions } from "../../../declarations";
import * as constants from "../../constants";
import { CONNECTED_STATUS } from "../../constants";
import {
IAppInstalledInfo,
IDictionary,
IErrors,
IHostInfo,
IAppInstalledInfo,
} from "../../declarations";
import { exported, performanceLog } from "../../decorators";
import { IInjector } from "../../definitions/yok";
import * as helpers from "../../helpers";
import { isInteractive, settlePromises } from "../../helpers";
import { injector } from "../../yok";
import { IOptions } from "../../../declarations";

export class DevicesService
extends EventEmitter
implements Mobile.IDevicesService {
implements Mobile.IDevicesService
{
private static DEVICE_LOOKING_INTERVAL = 200;
private static EMULATOR_IMAGES_DETECTION_INTERVAL = 60 * 1000;
private _devices: IDictionary<Mobile.IDevice> = {};
Expand Down Expand Up @@ -190,9 +189,10 @@ export class DevicesService
const availableEmulatorsOutput = await this.getEmulatorImages({
platform: options.platform,
});
const emulators = this.$emulatorHelper.getEmulatorsFromAvailableEmulatorsOutput(
availableEmulatorsOutput
);
const emulators =
this.$emulatorHelper.getEmulatorsFromAvailableEmulatorsOutput(
availableEmulatorsOutput
);
const errors = this.$emulatorHelper.getErrorsFromAvailableEmulatorsOutput(
availableEmulatorsOutput
);
Expand Down Expand Up @@ -893,7 +893,7 @@ export class DevicesService
// TODO: Remove from here as it calls startLookingForDevices, so we double the calls to specific device detection services
await this.startEmulatorIfNecessary(deviceInitOpts);
}

deviceInitOpts;
const platform = deviceInitOpts.platform;
const deviceOption = deviceInitOpts.deviceId;
const deviceLookingOptions: Mobile.IDeviceLookingOptions = {
Expand All @@ -910,6 +910,7 @@ export class DevicesService
);
await this.startLookingForDevices(deviceLookingOptions);
this._device = await this.getDevice(deviceOption);

if (this._device.deviceInfo.platform !== this._platform) {
this.$errors.fail(constants.ERROR_CANNOT_RESOLVE_DEVICE);
}
Expand Down Expand Up @@ -1023,9 +1024,8 @@ export class DevicesService
appIdentifier: string
): Promise<Mobile.IDebugWebViewInfo[]> {
const device = this.getDeviceByIdentifier(deviceIdentifier),
debuggableViewsPerApp = await device.applicationManager.getDebuggableAppViews(
[appIdentifier]
);
debuggableViewsPerApp =
await device.applicationManager.getDebuggableAppViews([appIdentifier]);

return debuggableViewsPerApp && debuggableViewsPerApp[appIdentifier];
}
Expand Down
14 changes: 8 additions & 6 deletions lib/common/services/commands-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
ICommand,
ISimilarCommand,
} from "../definitions/commands";
import { printHeader } from "../header";

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

const beautifiedCommandName = this.beautifyCommandName(
Expand Down Expand Up @@ -183,6 +183,7 @@ export class CommandsService implements ICommandsService {
: canExecuteResult;

if (canExecute) {
printHeader();
await this.executeCommandAction(
commandName,
commandArguments,
Expand Down Expand Up @@ -246,9 +247,10 @@ export class CommandsService implements ICommandsService {
defaultCommandDelimiter: CommandsDelimiters.DefaultHierarchicalCommand,
};

const extensionData = await this.$extensibilityService.getExtensionNameWhereCommandIsRegistered(
commandInfo
);
const extensionData =
await this.$extensibilityService.getExtensionNameWhereCommandIsRegistered(
commandInfo
);

if (extensionData) {
this.$logger.warn(extensionData.installationMessage);
Expand Down
Loading

0 comments on commit 5dbc780

Please sign in to comment.