@sfdx-falcon/generator
Version:
Extends Yeoman's Generator class, adding customized support for SFDX-Falcon specific tools and capabilities. Part of the SFDX-Falcon Library.
262 lines (261 loc) • 15.5 kB
TypeScript
/**
* @author Vivek M. Chawla <@VivekMChawla>
* @copyright 2019, Vivek M. Chawla / Salesforce. All rights reserved.
* @license BSD-3-Clause For full license text, see the LICENSE file in the repo root or
* `https://opensource.org/licenses/BSD-3-Clause`
* @file packages/generator/src/generator.ts
* @summary Exports `SfdxFalconGenerator` for use with custom Yeoman generators.
* @description Exports an abstract class that extends Yeoman's `Generator` class, adding
* customized support for SFDX-Falcon specific tools and capabilities.
*/
import * as Generator from 'yeoman-generator';
import { ExternalContext } from '@sfdx-falcon/builder';
import { SfdxEnvironment } from '@sfdx-falcon/environment';
import { SfdxFalconInterview } from '@sfdx-falcon/interview';
import { SfdxFalconResult } from '@sfdx-falcon/status';
import { GeneratorStatus } from '@sfdx-falcon/status';
import { GeneratorOptions } from '@sfdx-falcon/command';
import { SfdxEnvironmentRequirements } from '@sfdx-falcon/environment';
import { SfdxFalconTableData } from '@sfdx-falcon/status';
import { ConfirmationAnswers } from '@sfdx-falcon/types';
import { JsonMap } from '@sfdx-falcon/types';
/**
* Interface. Collection of objects that represent the Answers that will be leveraged by an
* `SfdxFalconGenerator`.
*/
export interface Answers<T extends JsonMap> {
/** Required. The set of default answers for the Interview of an `SfdxFalconGenerator`. */
default: T;
/** Required. The set of answers provided by the user for the Interview of an `SfdxFalconGenerator`. */
user: T;
/** Required. The set of final answers for the Interview of an `SfdxFalconGenerator`. In other words, the merging of User and Default answers in case the user did not supply some answers. */
final: T;
/** Required. Special set of answers. Provides a means to send meta values (usually template tags) to EJS templates. */
meta: T;
/** Required. The set of answers provided when the user is asked to proceed/retry/abort something. */
confirmation: ConfirmationAnswers;
}
/**
* Interface. Collection of message strings that are displayed at various times during the execution
* of an `SfdxFalconGenerator`.
*/
export interface GeneratorMessages {
/** Required. Message that will be displayed by the opening Banner when the generator is loaded. */
opening: string;
/** Required. Message shown to the user before the interview starts during the prompting() run-loop function. */
preInterview: string;
/** Required. Message shown to the user to help them decide to exit the prompting() run-loop function. */
confirmation: string;
/** Required. Message shown to the user after the interview ends but before the prompting() run-loop function exits. */
postInterview: string;
/** Required. Message that will be displayed by the `end()` run-loop function upon successful completion of the Generator. */
success: string;
/** Required. Message that will be displayed by the `end()` run-loop function upon failure of the Generator. */
failure: string;
/** Required. Message that will be displayed by the `end()` run-loop function upon partial success of the Generator. */
warning: string;
}
/**
* Interface. Collection of requirements for the initialization process of an `SfdxFalconGenerator`.
*/
export interface GeneratorRequirements {
gitEnvReqs: object;
sfdxEnvReqs: SfdxEnvironmentRequirements;
localEnvReqs: object;
}
/**
* Interface. Collection of status `boolean` variables that reflect the status of various Yeoman
* run-loop functions.
*/
export interface RunLoopStatus {
/** Required. Indicates that the `initializing()` run-loop function has completed successfully. */
initializingComplete: boolean;
/** Required. Indicates that the `prompting()` run-loop function has completed successfully. */
promptingComplete: boolean;
/** Required. Indicates that the `configuring()` run-loop function has completed successfully. */
configuringComplete: boolean;
/** Required. Indicates that the `writing()` run-loop function has completed successfully. */
writingComplete: boolean;
/** Required. Indicates that the `install()` run-loop function has completed successfully. */
installComplete: boolean;
/** Required. Indicates that the `end()` run-loop function completed successfully. */
endComplete: boolean;
}
/**
* @class SfdxFalconGenerator
* @extends Generator
* @summary Abstract base class class for building Yeoman Generators for SFDX-Falcon commands.
* @description Classes that extend `SfdxFalconGenerator` must provide a type parameter to
* ensure that the "answers" family of member variables (`defaultAnswers`,
* `userAnswers`, `metaAnswers`, and `finalAnswers`) has the appropriate interface
* type which defines the answers that are relevant to a concrete child class.
* @public @abstract
*/
export declare abstract class SfdxFalconGenerator<T extends JsonMap> extends Generator {
/** Debug namespace of the derived class. Makes it easier to debug superclass operations when extending `SfdxFalconGenerator`. */
protected readonly dbgNs: string;
/** Name of the CLI command that kicked off this Generator. */
protected readonly commandName: string;
/** External Context describing an instance of the derived class. Used by Builder-derived classes. */
protected readonly extCtx: ExternalContext;
/** Reference to the package manifest (`package.json`) of the module that owns the class that implements the command entrypoint. */
protected readonly packageJson: JsonMap;
/** Version of the plugin that's running this Generator. Taken dynamically from `package.json`. */
protected readonly pluginVersion: string;
/** Custom `falcon` options key from `package.json`. Can be used to read package-global settings that a plugin developer chooses to add to `package.json`. */
protected readonly falcon: JsonMap;
/** Specifies the various messages used by this Generator. */
protected readonly generatorMessages: GeneratorMessages;
/** Tracks the name (type) of Generator being run, eg. `clone-appx-package-project`. */
protected readonly generatorType: string;
/** Tracks the path to the of the source file containing the Generator being run, eg `../../generators`. */
protected readonly generatorPath: string;
/** Used to keep track of status and to return messages to the caller. */
protected readonly generatorStatus: GeneratorStatus;
/** Used to keep track of status and to return messages to the caller. */
protected readonly generatorResult: SfdxFalconResult;
/** Determines which initialization tasks are performed during the Default Initialization process. */
protected readonly generatorReqs: GeneratorRequirements;
/** Tracks the status of various run-loop functions. */
protected readonly runLoopStatus: RunLoopStatus;
/** Collection of objects that represent the Answers to questions that will be asked during the Interview. */
protected readonly answers: Answers<T>;
/** Used to share data between the Generator, Inqurirer Prompts, and Listr Tasks. */
protected readonly sharedData: object;
/** Holds the `SfdxFalconInterview` object that will be run during the `prompting()` run-loop function. */
protected userInterview: SfdxFalconInterview<T>;
/** Represents the SFDX Environment. */
protected sfdxEnv: SfdxEnvironment;
/**
* @constructs SfdxFalconGenerator
* @param {string|string[]} args Required. Array of arguments that are
* passed to this generator by Yeoman if the generator is being
* invoked from the command line. Passed directly through to
* the superclass constructor without modification.
* @param {GeneratorOptions} opts Required. Object containing options
* that help specify how a specific generator is run. These
* options are set when external code uses a Yeoman Environment
* to `run()` a Generator that's derived from this class.
* @description Constructs an `SfdxFalconGenerator` object.
* @public
*/
constructor(args: string | string[], opts: GeneratorOptions, reqs: GeneratorRequirements);
abstract initializing(): Promise<void>;
abstract prompting(): Promise<void>;
abstract configuring(): Promise<void>;
abstract writing(): Promise<void>;
abstract install(): Promise<void>;
abstract end(): Promise<void>;
/**
* @method _showOpener
* @returns {Promise<void>}
* @description Shows an opening message when the `initializing` run-loop
* function is executed. Uses the string from
* `this.generatorMessage.opening` as the source of the message
* contents. Can be overridden by derived class to customize the
* opener behavior.
* @protected @async
*/
protected _showOpener(): Promise<void>;
/**
* @method __initializing
* @returns {Promise<void>}
* @description STEP ONE in the Yeoman run-loop. Intended to be executed as
* part of Yeoman's `initializing` run-loop priority. Will call
* the matching single-underscore method `_initializing()` from
* the derived class after executing logic that's specialized
* for `SfdxFalconGenerator` based Generators. This method must
* be called by the `initializing()` method that's implemented
* by the dervived class.
* @protected @async
*/
protected __initializing(): Promise<void>;
/**
* @method __prompting
* @returns {Promise<void>}
* @description STEP TWO in the Yeoman run-loop. Interviews the User to get
* information needed by the `writing` and `installing` phases.
* Intended to be executed as part of Yeoman's `prompting`
* run-loop priority. Will call the matching single-underscore
* method `_prompting()` from the derived class after executing
* logic that's specialized for `SfdxFalconGenerator` based
* Generators. This method must be called by the `prompting()`
* method that's implemented by the dervived class.
* @protected @async
*/
protected __prompting(): Promise<void>;
/**
* @method __configuring
* @returns {void}
* @description STEP THREE in the Yeoman run-loop. Perform any pre-install
* configuration steps based on the answers provided by the User.
* Intended to be executed as part of Yeoman's `configuring`
* run-loop priority. Will call the matching single-underscore
* method `_configuring()` from the derived class after executing
* logic that's specialized for `SfdxFalconGenerator` based
* Generators. this method must be called by the `configuring()`
* method that's implemented by the dervived class.
* @protected @async
*/
protected __configuring(): Promise<void>;
/**
* @method __writing
* @returns {Promise<void>}
* @description __STEP FOUR in the Yeoman run-loop.__ Typically, this is where
* you perform filesystem writes, git clone operations, etc.
* Intended to be executed as part of Yeoman's `writing` run-loop
* priority. Will call the matching single-underscore method
* `_writing()` from the derived class after executing logic
* that's specialized for `SfdxFalconGenerator` based Generators.
* This method must] be called by the `writing()` method that's
* implemented by the dervived class.
* @protected @async
*/
protected __writing(): Promise<void>;
/**
* @method install
* @returns {Promise<void>}
* @description __STEP FIVE in the Yeoman run-loop.__ Typically, this is where
* you perform operations that must happen AFTER files are
* written to disk. For example, if the `writing` step downloaded
* an app to install, the `install` step would run the
* installation. Intended to be executed as part of Yeoman's
* `install` run-loop priority. Will call the matching
* single-underscore method `_install()` from the derived class
* after executing logic that's specialized for `SfdxFalconGenerator`
* based Generators. This method must be called by the `install()`
* method that's implemented by the dervived class.
* @protected @async
*/
protected __install(): Promise<void>;
/**
* @method __end
* @returns {Promise<void>}
* @description __STEP SIX in the Yeoman run-loop.__ This is the FINAL step
* that Yeoman runs and it gives us a chance to do any post-Yeoman
* updates and/or cleanup. Intended to be executed as part of the
* `end` run-loop priority. Will call the matching single-underscore
* method `_end()` from the derived class after executing logic
* that's specialized for `SfdxFalconGenerator` based Generators.
* This method must be called by the `end()` method that's
* implemented by the dervived class.
* @protected @async
*/
protected __end(): Promise<void>;
/** Builds a complete `SfdxFalconInterview` object, which may include zero or more confirmation groupings. */
protected abstract _buildInterview(): SfdxFalconInterview<T>;
/** Creates Interview Answers table data. Can be used to render an `SfdxFalconTable` object. */
protected abstract _buildInterviewAnswersTableData(userAnswers: T): Promise<SfdxFalconTableData>;
/** STEP ONE in the Yeoman run-loop. Uses Yeoman's "initializing" run-loop priority. */
protected abstract _initializing(): Promise<void>;
/** STEP TWO in the Yeoman run-loop. Interviews the User to get information needed by the `_writing()` and `_install()` functions. */
protected abstract _prompting(): Promise<void>;
/** STEP THREE in the Yeoman run-loop. Perform any pre-install configuration steps based on the answers provided by the User. */
protected abstract _configuring(): Promise<void>;
/** STEP FOUR in the Yeoman run-loop. Typically, this is where you perform filesystem writes, git clone operations, etc. */
protected abstract _writing(): Promise<void>;
/** STEP FIVE in the Yeoman run-loop. Typically, this is where you perform operations that must happen AFTER files are written to disk. For example, if the `_writing()` step downloaded an app to install, the `_install()` step would run the installation. */
protected abstract _install(): Promise<void>;
/** STEP SIX in the Yeoman run-loop. This is the FINAL step that Yeoman runs and it gives us a chance to do any post-Yeoman updates and/or cleanup. */
protected abstract _end(): Promise<void>;
}