diff --git a/packages/@ionic/cli/src/commands/capacitor/sync.ts b/packages/@ionic/cli/src/commands/capacitor/sync.ts index 5dafe72477..b736cd367d 100644 --- a/packages/@ionic/cli/src/commands/capacitor/sync.ts +++ b/packages/@ionic/cli/src/commands/capacitor/sync.ts @@ -1,7 +1,9 @@ -import { CommandMetadataOption } from '@ionic/cli-framework'; +import { BaseError, CommandMetadataOption } from '@ionic/cli-framework'; -import { CommandInstanceInfo, CommandLineInputs, CommandLineOptions, CommandMetadata, CommandPreRun } from '../../definitions'; +import { CapacitorSyncHookName, CommandInstanceInfo, CommandLineInputs, CommandLineOptions, CommandMetadata, CommandPreRun } from '../../definitions'; import { input } from '../../lib/color'; +import { FatalException } from '../../lib/errors'; +import { Hook, HookDeps } from '../../lib/hooks'; import { CapacitorCommand } from './base'; @@ -53,6 +55,10 @@ ${input('ionic capacitor sync')} will do the following: } async run(inputs: CommandLineInputs, options: CommandLineOptions): Promise { + if (!this.project) { + throw new FatalException(`Cannot run ${input('ionic capacitor sync')} outside a project directory.`); + } + const [ platform ] = inputs; if (options.build) { @@ -66,5 +72,42 @@ ${input('ionic capacitor sync')} will do the following: } await this.runCapacitor(args); + + const hookDeps: HookDeps = { + config: this.env.config, + project: this.project, + shell: this.env.shell, + }; + + await this.runCapacitorSyncHook('capacitor:sync:after', inputs, options, hookDeps); + } + + private async runCapacitorSyncHook(name: CapacitorSyncHookName, inputs: CommandLineInputs, options: CommandLineOptions, e: HookDeps): Promise { + const hook = new CapacitorSyncHook(name, e); + const buildRunner = await e.project.requireBuildRunner(); + + try { + await hook.run({ + name: hook.name, + build: buildRunner.createOptionsFromCommandLine(inputs, options), + capacitor: this.createOptionsFromCommandLine(inputs, options), + }); + } catch (e) { + if (e instanceof BaseError) { + throw new FatalException(e.message); + } + + throw e; + } + } +} + +class CapacitorSyncHook extends Hook { + readonly name: CapacitorSyncHookName; + + constructor(name: CapacitorSyncHookName, e: HookDeps) { + super(e); + + this.name = name; } } diff --git a/packages/@ionic/cli/src/definitions.ts b/packages/@ionic/cli/src/definitions.ts index e5596ab9c0..4c7483bcb4 100644 --- a/packages/@ionic/cli/src/definitions.ts +++ b/packages/@ionic/cli/src/definitions.ts @@ -74,10 +74,11 @@ export interface Runner { } export type ProjectType = 'angular' | 'ionic-angular' | 'ionic1' | 'custom' | 'bare' | 'react' | 'vue'; -export type HookName = 'build:before' | 'build:after' | 'serve:before' | 'serve:after' | 'capacitor:run:before' | 'capacitor:build:before'; +export type HookName = 'build:before' | 'build:after' | 'serve:before' | 'serve:after' | 'capacitor:run:before' | 'capacitor:build:before' | 'capacitor:sync:after'; export type CapacitorRunHookName = 'capacitor:run:before'; export type CapacitorBuildHookName = 'capacitor:build:before'; +export type CapacitorSyncHookName = 'capacitor:sync:after'; export interface BaseHookContext { project: { @@ -92,6 +93,11 @@ export interface BaseHookContext { export type AnyServeOptions = ReactServeOptions | AngularServeOptions | IonicAngularServeOptions | Ionic1ServeOptions; export type AnyBuildOptions = ReactBuildOptions | AngularBuildOptions | IonicAngularBuildOptions | Ionic1BuildOptions; +export interface CapacitorSyncHookInput { + readonly name: CapacitorSyncHookName; + readonly build?: AnyBuildOptions; + readonly capacitor: IonicCapacitorOptions; +} export interface CapacitorRunHookInput { readonly name: CapacitorRunHookName; readonly serve?: AnyServeOptions; @@ -120,7 +126,7 @@ export interface ServeAfterHookInput { readonly serve: (AngularServeOptions | IonicAngularServeOptions | Ionic1ServeOptions) & ServeDetails; } -export type HookInput = BuildHookInput | ServeBeforeHookInput | ServeAfterHookInput | CapacitorRunHookInput | CapacitorBuildHookInput; +export type HookInput = BuildHookInput | ServeBeforeHookInput | ServeAfterHookInput | CapacitorRunHookInput | CapacitorBuildHookInput | CapacitorSyncHookInput; export type HookContext = BaseHookContext & HookInput; export type HookFn = (ctx: HookContext) => Promise;