From 81fd1c3912b986e318cac5f04de62276cef939b2 Mon Sep 17 00:00:00 2001 From: Scott Wyatt Date: Mon, 14 Oct 2019 10:44:37 -0500 Subject: [PATCH] feat(): adds to spool configuration - #45 --- lib/Core.ts | 3 ++- lib/Fabrix.ts | 29 ++++++++++++++++------ lib/common/Spool.ts | 37 +++++++++++++++++++++++++---- lib/common/index.ts | 1 + lib/common/interfaces/IConfig.ts | 1 + lib/common/interfaces/ILifecycle.ts | 6 ++++- 6 files changed, 64 insertions(+), 13 deletions(-) diff --git a/lib/Core.ts b/lib/Core.ts index 7c44516..5f32c7b 100755 --- a/lib/Core.ts +++ b/lib/Core.ts @@ -356,7 +356,7 @@ export const Core = { }, /** - * Bind listeners to fabrix application events + * Bind listeners to FabrixApp events */ bindApplicationListeners (app: FabrixApp): void { app.once('spool:all:configured', () => { @@ -386,6 +386,7 @@ export const Core = { }) app.once('fabrix:stop', () => { app.log.info(Templates.info.stop) + // Unfreezes the config so that modifications can be made before starting again app.config.unfreeze() }) }, diff --git a/lib/Fabrix.ts b/lib/Fabrix.ts index 163df85..0f693e1 100644 --- a/lib/Fabrix.ts +++ b/lib/Fabrix.ts @@ -3,7 +3,7 @@ import { union } from 'lodash' import { Core } from './Core' import { Configuration } from './Configuration' import { LoggerProxy } from './LoggerProxy' -import { Spool, IApi, IPkg, IConfig, IEnv } from './common' +import { Spool, IApi, IPkg, IConfig, IEnv, IVersions } from './common' import * as Errors from './errors' import * as pkg from '../package.json' import { FabrixGeneric } from './common/Generic' @@ -13,8 +13,8 @@ import { DatastoreSpool } from './common/spools/datastore' import { SystemSpool } from './common/spools/system' import { ToolSpool } from './common/spools/tool' import { MiscSpool } from './common/spools/misc' + import { enumerable } from './common/decorators/enumerable' -import { IVersions } from './common/interfaces/IVersions' // inject Error and Resource types into the global namespace // Deprecate Globals v1.6 @@ -28,15 +28,23 @@ export interface FabrixApp extends EventEmitter { [key: string]: any } +export interface ISpools { + [key: string]: Spool | ServerSpool | ExtensionSpool | DatastoreSpool | SystemSpool | ToolSpool | MiscSpool +} + +export interface IApis { + [key: string]: FabrixGeneric | {} +} + export class FabrixApp extends EventEmitter { private _logger: LoggerProxy private _env: IEnv - private _pkg: any // IPkg + private _pkg: IPkg private _versions: IVersions private _config: Configuration private _api: IApi private _fabrix: FabrixApp - private _spools: {[key: string]: Spool | ServerSpool | ExtensionSpool | DatastoreSpool | SystemSpool | ToolSpool | MiscSpool } + private _spools: ISpools private _resources: string[] = [ ] // Deprecate Globals v1.6 @@ -80,6 +88,7 @@ export class FabrixApp extends EventEmitter { // ensure process.env is an immutable object const processEnv = Object.freeze(Object.assign({}, JSON.parse(JSON.stringify(process.env)))) + // Define some essential properties/methods to the FabrixApp instance Object.defineProperties(this, { _logger: { value: new LoggerProxy(this), @@ -118,6 +127,9 @@ export class FabrixApp extends EventEmitter { // Set the max listeners from the config this.setMaxListeners(this.config.get('main.maxListeners')) + // Emit the event that the fabrix app is constructing + this.emit('fabrix:constructing') + // Set the resources from the configuration (this bypasses the setter with the initial config // in case the resourceLock is configured) this._resources = this.config.get('main.resources') @@ -125,7 +137,7 @@ export class FabrixApp extends EventEmitter { this.resources = union(Object.keys(app.api), this.config.get('main.resources')) // Set each api resource to make sure it's provided as an object in the app - this.resources.forEach(resource => { + this.resources.forEach((resource: string) => { app.api[resource] = app.api[resource] || (app.api[resource] = { }) }) @@ -148,6 +160,8 @@ export class FabrixApp extends EventEmitter { } catch (e) { console.log(e.stack) + // SBW: we may either need to remove the error being thrown and pass it to stop + // this.stop(e) throw new Errors.SpoolError(Spool, e, 'constructor') } }) @@ -161,6 +175,7 @@ export class FabrixApp extends EventEmitter { // Bind the Phase listeners for the Spool lifecycle Core.bindSpoolPhaseListeners(this, Object.values(this.spools)) + // Emit the event that the fabrix app was successfully constructed this.emit('fabrix:constructed') } @@ -201,7 +216,7 @@ export class FabrixApp extends EventEmitter { * Gets the Spools that have been installed */ // @enumerable(false) - get spools (): {[key: string]: Spool} { + get spools (): ISpools { return this._spools } @@ -209,7 +224,7 @@ export class FabrixApp extends EventEmitter { * Gets the api */ // @enumerable(false) - get api (): {[key: string]: FabrixGeneric | {}} { + get api (): IApis { return this._api } diff --git a/lib/common/Spool.ts b/lib/common/Spool.ts index 21ec216..55ad04f 100644 --- a/lib/common/Spool.ts +++ b/lib/common/Spool.ts @@ -15,6 +15,7 @@ export interface Spool extends FabrixGeneric { } export class Spool extends FabrixGeneric { + private _address: string private _stage = 'pre' private _config: ISpoolConfig private _pkg: any // IPkg @@ -50,6 +51,10 @@ export class Spool extends FabrixGeneric { */ static get defaultLifecycle (): ILifecycle { return { + validate: { + listen: [ ], + emit: [ ] + }, configure: { listen: [ ], emit: [ ] @@ -65,11 +70,14 @@ export class Spool extends FabrixGeneric { } } - static configuredSpoolLifecycle (config) { + static configuredSpoolLifecycle (config: ISpoolConfig) { const level1 = config.lifecycle || {} const level2 = config.spool && config.spool.lifecycle - ? config.spool.lifecycle : config.trailpack && config.trailpack.lifecycle - ? config.trailpack.lifecycle : {} + ? config.spool.lifecycle + : config.trailpack && config.trailpack.lifecycle + ? config.trailpack.lifecycle + : {} + const level3 = Spool.defaultLifecycle return defaultsDeep({}, level1, level2, level3) } @@ -147,12 +155,15 @@ export class Spool extends FabrixGeneric { this._config = config } + /** + * Virtual getter for `pkg` + */ get pkg () { return this._pkg } /** - * Return a reference to the Fabrix logger + * Return a reference to the Fabrix logger, so you can use `this.log` instead of this.app.log */ get log (): FabrixApp['log'] { return this.app.log @@ -193,6 +204,15 @@ export class Spool extends FabrixGeneric { } + /** + * Once the FabrixApp is bootstrapped and ready, the spool can run additional logic + * By defining a function here. However, config is now immutable so this should not + * set any configuration. + */ + ready (): any { + + } + /** * Unload this Spool. This method will instruct the spool to perform * any necessary cleanup with the expectation that the app will stop or reload @@ -208,6 +228,8 @@ export class Spool extends FabrixGeneric { * Return the name of this Spool. By default, this is the name of the * npm module (in package.json). This method can be overridden for spools * which do not follow the "spool-" prefix naming convention. + * Some Trailpacks will just work in fabrix without modifying anything, + * In which case, they will have the "trailpack-" prefix which is also removed */ get name (): string { return this.pkg.name @@ -223,4 +245,11 @@ export class Spool extends FabrixGeneric { } + /** + * Vitual Getter for the "address" for this spool if the app is distributed + */ + get address (): string { + return this._address + } + } diff --git a/lib/common/index.ts b/lib/common/index.ts index 504469c..ef28f97 100644 --- a/lib/common/index.ts +++ b/lib/common/index.ts @@ -21,3 +21,4 @@ export { ISpoolConfig } from './interfaces/ISpoolConfig' export { IPkg } from './interfaces/IPkg' export { ILifecycle } from './interfaces/ILifecycle' export { IEnv } from './interfaces/IEnv' +export { IVersions } from './interfaces/IVersions' diff --git a/lib/common/interfaces/IConfig.ts b/lib/common/interfaces/IConfig.ts index 0085614..b5066ce 100644 --- a/lib/common/interfaces/IConfig.ts +++ b/lib/common/interfaces/IConfig.ts @@ -5,5 +5,6 @@ export interface IConfig { main: { [key: string]: any, spools: any[] // typeof Spool[] + target?: string } } diff --git a/lib/common/interfaces/ILifecycle.ts b/lib/common/interfaces/ILifecycle.ts index 61d7cff..cf5119d 100644 --- a/lib/common/interfaces/ILifecycle.ts +++ b/lib/common/interfaces/ILifecycle.ts @@ -1,4 +1,8 @@ export interface ILifecycle { + validate?: { + listen: string[], + emit: string[] + }, configure: { listen: string[], emit: string[] @@ -7,7 +11,7 @@ export interface ILifecycle { listen: string[], emit: string[] }, - sanity: { + sanity?: { listen: string[], emit: string[] }