diff --git a/packages/core-kernel/package.json b/packages/core-kernel/package.json index 44202d92b3..7a63c98d3b 100644 --- a/packages/core-kernel/package.json +++ b/packages/core-kernel/package.json @@ -36,6 +36,7 @@ "micromatch": "^4.0.2", "nsfw": "^1.2.5", "semver": "^6.3.0", + "strman": "^2.0.1", "type-fest": "^0.7.1" }, "publishConfig": { diff --git a/packages/core-kernel/src/application.ts b/packages/core-kernel/src/application.ts index 968fa5e73f..c42f86e5aa 100644 --- a/packages/core-kernel/src/application.ts +++ b/packages/core-kernel/src/application.ts @@ -43,7 +43,7 @@ export class Application extends Container implements Kernel.IApplication { public async bootstrap(config: JsonObject): Promise { app.bind("config", config); - app.singleton("providers", ProviderRepository); + app.singleton("service-providers", ProviderRepository); await this.runBootstrappers("app"); @@ -401,7 +401,7 @@ export class Application extends Container implements Kernel.IApplication { * @memberof Application */ private async disposeServiceProviders(): Promise { - for (const provider of app.resolve("providers").allLoadedProviders()) { + for (const provider of app.resolve("service-providers").allLoadedProviders()) { await provider.dispose(); } } diff --git a/packages/core-kernel/src/bootstrap/app/index.ts b/packages/core-kernel/src/bootstrap/app/index.ts index 22c8c19deb..85fec395fd 100644 --- a/packages/core-kernel/src/bootstrap/app/index.ts +++ b/packages/core-kernel/src/bootstrap/app/index.ts @@ -1,14 +1,15 @@ -export * from "./load-error-handler"; - -export * from "./load-factories"; -export * from "./load-services"; - -export * from "./load-bindings"; -export * from "./load-namespace"; -export * from "./load-paths"; - +// Foundation +export * from "./register-error-handler"; +export * from "./register-base-service-providers"; +export * from "./register-base-bindings"; +export * from "./register-base-namespace"; +export * from "./register-base-paths"; +export * from "./register-application-service-providers"; + +// Configuration export * from "./load-environment-variables"; export * from "./load-configuration"; export * from "./load-cryptography"; +// Service Providers export * from "./load-service-providers"; diff --git a/packages/core-kernel/src/bootstrap/app/load-configuration.ts b/packages/core-kernel/src/bootstrap/app/load-configuration.ts index 95417e9c7e..1a6b18d428 100644 --- a/packages/core-kernel/src/bootstrap/app/load-configuration.ts +++ b/packages/core-kernel/src/bootstrap/app/load-configuration.ts @@ -1,6 +1,5 @@ import { JsonObject } from "type-fest"; -import { ConfigRepository } from "../../config"; -import { IConfigAdapter } from "../../contracts/core-kernel"; +import { ConfigManager, ConfigRepository } from "../../services/config"; import { AbstractBootstrapper } from "../bootstrapper"; /** @@ -17,6 +16,8 @@ export class LoadConfiguration extends AbstractBootstrapper { this.app.resolve("config").set("options", config.options || {}); - await this.app.resolve("configLoader").loadConfiguration(); + await (await this.app + .resolve("configManager") + .driver((config.configLoader || "local") as string)).loadConfiguration(); } } diff --git a/packages/core-kernel/src/bootstrap/app/load-environment-variables.ts b/packages/core-kernel/src/bootstrap/app/load-environment-variables.ts index c30099096f..341e2652ad 100644 --- a/packages/core-kernel/src/bootstrap/app/load-environment-variables.ts +++ b/packages/core-kernel/src/bootstrap/app/load-environment-variables.ts @@ -1,4 +1,5 @@ -import { Kernel } from "../../contracts"; +import { JsonObject } from "type-fest"; +import { ConfigManager } from "../../services/config"; import { AbstractBootstrapper } from "../bootstrapper"; /** @@ -11,6 +12,10 @@ export class LoadEnvironmentVariables extends AbstractBootstrapper { * @memberof LoadEnvironmentVariables */ public async bootstrap(): Promise { - await this.app.resolve("configLoader").loadEnvironmentVariables(); + const config: JsonObject = this.app.resolve("config"); + + await (await this.app + .resolve("configManager") + .driver((config.configLoader || "local") as string)).loadEnvironmentVariables(); } } diff --git a/packages/core-kernel/src/bootstrap/app/load-factories.ts b/packages/core-kernel/src/bootstrap/app/load-factories.ts deleted file mode 100644 index eb6f374b2d..0000000000 --- a/packages/core-kernel/src/bootstrap/app/load-factories.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { CacheFactory } from "../../services/cache"; -import { FilesystemFactory } from "../../services/filesystem"; -import { LoggerFactory } from "../../services/logger"; -import { QueueFactory } from "../../services/queue"; -import { AbstractBootstrapper } from "../bootstrapper"; - -/** - * @export - * @class LoadFactories - */ -export class LoadFactories extends AbstractBootstrapper { - /** - * @returns {Promise} - * @memberof LoadFactories - */ - public async bootstrap(): Promise { - this.app.bind("factoryFilesystem", new FilesystemFactory(this.app)); - this.app.bind("factoryLogger", new LoggerFactory(this.app)); - this.app.bind("factoryCache", new CacheFactory(this.app)); - this.app.bind("factoryQueue", new QueueFactory(this.app)); - } -} diff --git a/packages/core-kernel/src/bootstrap/app/load-service-providers.ts b/packages/core-kernel/src/bootstrap/app/load-service-providers.ts index 088d67526b..603815da45 100644 --- a/packages/core-kernel/src/bootstrap/app/load-service-providers.ts +++ b/packages/core-kernel/src/bootstrap/app/load-service-providers.ts @@ -13,10 +13,10 @@ export class LoadServiceProviders extends AbstractBootstrapper { * @memberof RegisterProviders */ public async bootstrap(): Promise { - for (const [pkg, opts] of Object.entries(this.app.config("providers"))) { + for (const [pkg, opts] of Object.entries(this.app.config("service-providers"))) { const provider: AbstractServiceProvider = new (require(pkg)).ServiceProvider(this.app, opts); - this.app.resolve("providers").set(pkg, provider); + this.app.resolve("service-providers").set(pkg, provider); } } } diff --git a/packages/core-kernel/src/bootstrap/app/load-services.ts b/packages/core-kernel/src/bootstrap/app/load-services.ts deleted file mode 100644 index dac9ee6246..0000000000 --- a/packages/core-kernel/src/bootstrap/app/load-services.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { JsonObject } from "type-fest"; -import { ConfigFactory, ConfigRepository } from "../../config"; -import { IConfigAdapter } from "../../contracts/core-kernel"; -import { EventDispatcher } from "../../services/events"; -import { FilesystemFactory } from "../../services/filesystem"; -import { LocalAdapter } from "../../services/filesystem/adapters/local"; -import { LoggerFactory } from "../../services/logger"; -import { ConsoleLogger } from "../../services/logger/adapters/console"; -import { AbstractBootstrapper } from "../bootstrapper"; - -/** - * @export - * @class LoadServices - */ -export class LoadServices extends AbstractBootstrapper { - /** - * @returns {Promise} - * @memberof LoadServices - */ - public async bootstrap(): Promise { - await this.registerFilesystem(); - - this.registerEventDispatcher(); - - await this.registerLogger(); - - this.registerConfigLoader(); - } - - /** - * @private - * @returns {Promise} - * @memberof LoadServices - */ - private async registerFilesystem(): Promise { - this.app.bind( - "filesystem", - await this.app.resolve("factoryFilesystem").make(new LocalAdapter()), - ); - } - - /** - * @private - * @memberof LoadServices - */ - private registerEventDispatcher(): void { - this.app.singleton("events", EventDispatcher); - } - - /** - * @private - * @returns {Promise} - * @memberof LoadServices - */ - private async registerLogger(): Promise { - this.app.bind("logger", await this.app.resolve("factoryLogger").make(new ConsoleLogger())); - } - - /** - * @private - * @memberof LoadServices - */ - private registerConfigLoader(): void { - const config: JsonObject = this.app.resolve("config"); - - this.app.bind( - "configLoader", - ConfigFactory.make(this.app, (config.configLoader || "local") as string), - ); - - this.app.bind("config", new ConfigRepository(config)); - } -} diff --git a/packages/core-kernel/src/bootstrap/app/register-application-service-providers.ts b/packages/core-kernel/src/bootstrap/app/register-application-service-providers.ts new file mode 100644 index 0000000000..d420eabeaf --- /dev/null +++ b/packages/core-kernel/src/bootstrap/app/register-application-service-providers.ts @@ -0,0 +1,23 @@ +import { Cache, Filesystem, Log, Queue } from "../../services"; +import { AbstractBootstrapper } from "../bootstrapper"; + +/** + * @export + * @class RegisterApplicationServiceProviders + */ +export class RegisterApplicationServiceProviders extends AbstractBootstrapper { + /** + * @param {Kernel.IApplication} app + * @returns {Promise} + * @memberof RegisterApplicationServiceProviders + */ + public async bootstrap(): Promise { + await new Log.ServiceProvider(this.app).register(); + + await new Filesystem.ServiceProvider(this.app).register(); + + await new Cache.ServiceProvider(this.app).register(); + + await new Queue.ServiceProvider(this.app).register(); + } +} diff --git a/packages/core-kernel/src/bootstrap/app/load-bindings.ts b/packages/core-kernel/src/bootstrap/app/register-base-bindings.ts similarity index 86% rename from packages/core-kernel/src/bootstrap/app/load-bindings.ts rename to packages/core-kernel/src/bootstrap/app/register-base-bindings.ts index 45ad8d740b..72ea3d635d 100644 --- a/packages/core-kernel/src/bootstrap/app/load-bindings.ts +++ b/packages/core-kernel/src/bootstrap/app/register-base-bindings.ts @@ -2,13 +2,13 @@ import { AbstractBootstrapper } from "../bootstrapper"; /** * @export - * @class LoadBindings + * @class RegisterBaseBindings */ -export class LoadBindings extends AbstractBootstrapper { +export class RegisterBaseBindings extends AbstractBootstrapper { /** * @param {Kernel.IApplication} app * @returns {Promise} - * @memberof LoadBindings + * @memberof RegisterBaseBindings */ public async bootstrap(): Promise { this.app.bind("app.env", this.app.config("env")); diff --git a/packages/core-kernel/src/bootstrap/app/load-namespace.ts b/packages/core-kernel/src/bootstrap/app/register-base-namespace.ts similarity index 80% rename from packages/core-kernel/src/bootstrap/app/load-namespace.ts rename to packages/core-kernel/src/bootstrap/app/register-base-namespace.ts index d0ae48b8d1..cedbd4fc45 100644 --- a/packages/core-kernel/src/bootstrap/app/load-namespace.ts +++ b/packages/core-kernel/src/bootstrap/app/register-base-namespace.ts @@ -3,12 +3,12 @@ import { AbstractBootstrapper } from "../bootstrapper"; /** * @export - * @class LoadNamespace + * @class RegisterBaseNamespace */ -export class LoadNamespace extends AbstractBootstrapper { +export class RegisterBaseNamespace extends AbstractBootstrapper { /** * @returns {Promise} - * @memberof LoadNamespace + * @memberof RegisterBaseNamespace */ public async bootstrap(): Promise { const token: string = this.app.token(); diff --git a/packages/core-kernel/src/bootstrap/app/load-paths.ts b/packages/core-kernel/src/bootstrap/app/register-base-paths.ts similarity index 88% rename from packages/core-kernel/src/bootstrap/app/load-paths.ts rename to packages/core-kernel/src/bootstrap/app/register-base-paths.ts index 5d9f46a249..211fab7496 100644 --- a/packages/core-kernel/src/bootstrap/app/load-paths.ts +++ b/packages/core-kernel/src/bootstrap/app/register-base-paths.ts @@ -8,12 +8,12 @@ import { AbstractBootstrapper } from "../bootstrapper"; /** * @export - * @class LoadPaths + * @class RegisterBasePaths */ -export class LoadPaths extends AbstractBootstrapper { +export class RegisterBasePaths extends AbstractBootstrapper { /** * @returns {Promise} - * @memberof LoadPaths + * @memberof RegisterBasePaths */ public async bootstrap(): Promise { const paths: Array<[string, string]> = Object.entries(envPaths(this.app.token(), { suffix: "core" })); diff --git a/packages/core-kernel/src/bootstrap/app/register-base-service-providers.ts b/packages/core-kernel/src/bootstrap/app/register-base-service-providers.ts new file mode 100644 index 0000000000..a91d799989 --- /dev/null +++ b/packages/core-kernel/src/bootstrap/app/register-base-service-providers.ts @@ -0,0 +1,19 @@ +import { Config, Events } from "../../services"; +import { AbstractBootstrapper } from "../bootstrapper"; + +/** + * @export + * @class RegisterBaseServiceProviders + */ +export class RegisterBaseServiceProviders extends AbstractBootstrapper { + /** + * @param {Kernel.IApplication} app + * @returns {Promise} + * @memberof RegisterBaseServiceProviders + */ + public async bootstrap(): Promise { + await new Events.ServiceProvider(this.app).register(); + + await new Config.ServiceProvider(this.app).register(); + } +} diff --git a/packages/core-kernel/src/bootstrap/app/load-error-handler.ts b/packages/core-kernel/src/bootstrap/app/register-error-handler.ts similarity index 73% rename from packages/core-kernel/src/bootstrap/app/load-error-handler.ts rename to packages/core-kernel/src/bootstrap/app/register-error-handler.ts index 968b03b171..902c81a6f9 100644 --- a/packages/core-kernel/src/bootstrap/app/load-error-handler.ts +++ b/packages/core-kernel/src/bootstrap/app/register-error-handler.ts @@ -3,12 +3,12 @@ import { AbstractBootstrapper } from "../bootstrapper"; /** * @export - * @class LoadErrorHandler + * @class RegisterErrorHandler */ -export class LoadErrorHandler extends AbstractBootstrapper { +export class RegisterErrorHandler extends AbstractBootstrapper { /** * @returns {Promise} - * @memberof LoadErrorHandler + * @memberof RegisterErrorHandler */ public async bootstrap(): Promise { // @TODO: implement passing in of options and ensure handling of critical exceptions diff --git a/packages/core-kernel/src/bootstrap/service-providers/boot-service-providers.ts b/packages/core-kernel/src/bootstrap/service-providers/boot-service-providers.ts index 7d8b159f39..5e8a3a1574 100644 --- a/packages/core-kernel/src/bootstrap/service-providers/boot-service-providers.ts +++ b/packages/core-kernel/src/bootstrap/service-providers/boot-service-providers.ts @@ -11,7 +11,7 @@ export class BootServiceProviders extends AbstractBootstrapper { * @memberof RegisterProviders */ public async bootstrap(): Promise { - const repository: ProviderRepository = this.app.resolve("providers"); + const repository: ProviderRepository = this.app.resolve("service-providers"); for (const [name] of repository.all()) { await repository.boot(name); diff --git a/packages/core-kernel/src/bootstrap/service-providers/register-service-providers.ts b/packages/core-kernel/src/bootstrap/service-providers/register-service-providers.ts index b2a19e3ab6..ad266269ac 100644 --- a/packages/core-kernel/src/bootstrap/service-providers/register-service-providers.ts +++ b/packages/core-kernel/src/bootstrap/service-providers/register-service-providers.ts @@ -15,14 +15,14 @@ export class RegisterServiceProviders extends AbstractBootstrapper { * @memberof RegisterProviders */ public async bootstrap(): Promise { - const providers: ProviderRepository = this.app.resolve("providers"); + const serviceProviders: ProviderRepository = this.app.resolve("service-providers"); - for (const [name, serviceProvider] of providers.all()) { + for (const [name, serviceProvider] of serviceProviders.all()) { if (this.satisfiesDependencies(serviceProvider)) { // @TODO: check conditional state and mark as either deferred or failed // @TODO: check dependencies and either register or mark as failed - await providers.register(name); + await serviceProviders.register(name); } } } @@ -34,7 +34,7 @@ export class RegisterServiceProviders extends AbstractBootstrapper { * @memberof RegisterProviders */ private satisfiesDependencies(serviceProvider: AbstractServiceProvider): boolean { - const dependencies: Record = serviceProvider.depends(); + const dependencies: Record = serviceProvider.getDependencies(); if (!dependencies) { return true; diff --git a/packages/core-kernel/src/config/adapters/remote.ts b/packages/core-kernel/src/config/adapters/remote.ts deleted file mode 100644 index 8d6b967165..0000000000 --- a/packages/core-kernel/src/config/adapters/remote.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Kernel } from "../../contracts"; - -/** - * @export - * @class RemoteAdapter - * @implements {Kernel.IConfigAdapter} - */ -export class RemoteAdapter implements Kernel.IConfigAdapter { - /** - * @param {Kernel.IApplication} app - * @memberof BaseAdapter - */ - public constructor(protected readonly app: Kernel.IApplication) {} - - /** - * @returns {Promise} - * @memberof RemoteAdapter - */ - public async loadConfiguration(): Promise { - // @TODO - } - - /** - * @returns {Promise} - * @memberof RemoteAdapter - */ - public async loadEnvironmentVariables(): Promise { - // @TODO - } -} diff --git a/packages/core-kernel/src/config/factory.ts b/packages/core-kernel/src/config/factory.ts deleted file mode 100644 index e613dadfd7..0000000000 --- a/packages/core-kernel/src/config/factory.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Kernel } from "../contracts"; -import { LocalAdapter, RemoteAdapter } from "./adapters"; - -/** - * @export - * @class ConfigFactory - */ -export class ConfigFactory { - /** - * @static - * @param {Kernel.IApplication} app - * @param {string} adapter - * @returns {Record} - * @memberof ConfigFactory - */ - public static make(app: Kernel.IApplication, adapter: string): Kernel.IConfigAdapter { - if (adapter === "remote") { - return new RemoteAdapter(app); - } - - return new LocalAdapter(app); - } -} diff --git a/packages/core-kernel/src/config/index.ts b/packages/core-kernel/src/config/index.ts deleted file mode 100644 index e09a91db0b..0000000000 --- a/packages/core-kernel/src/config/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./factory"; -export * from "./repository"; diff --git a/packages/core-kernel/src/config/repository.ts b/packages/core-kernel/src/config/repository.ts deleted file mode 100644 index 537cde869b..0000000000 --- a/packages/core-kernel/src/config/repository.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { JsonObject } from "type-fest"; - -/** - * @export - * @class ConfigRepository - * @extends {Map} - */ -export class ConfigRepository extends Map { - /** - * @param {JsonObject} config - * @memberof ConfigRepository - */ - public constructor(config: JsonObject) { - super(Object.entries(config)); - } -} diff --git a/packages/core-kernel/src/container.ts b/packages/core-kernel/src/container.ts index 8e9b7dee48..f17eeab3e2 100644 --- a/packages/core-kernel/src/container.ts +++ b/packages/core-kernel/src/container.ts @@ -123,7 +123,7 @@ export class Container { * @returns * @memberof Container */ - public call(targetOrResolver: ClassOrFunctionReturning | Resolver, opts?: BuildResolverOptions<{}>) { + public build(targetOrResolver: ClassOrFunctionReturning | Resolver, opts?: BuildResolverOptions<{}>) { return this.container.build(targetOrResolver, opts); } } diff --git a/packages/core-kernel/src/contracts/core-kernel/container.ts b/packages/core-kernel/src/contracts/core-kernel/container.ts index 23e09050ad..43271e6239 100644 --- a/packages/core-kernel/src/contracts/core-kernel/container.ts +++ b/packages/core-kernel/src/contracts/core-kernel/container.ts @@ -3,31 +3,60 @@ import { BuildResolverOptions, ClassOrFunctionReturning, Resolver } from "awilix export interface IContainer { /** * Resolve the given name from the container. + * + * @template T + * @param {string} name + * @returns {T} + * @memberof IContainer */ resolve(name: string): T; /** * Register a class within the container. + * + * @template T + * @param {string} name + * @param {(T | ClassOrFunctionReturning)} concrete + * @memberof IContainer */ bind(name: string, concrete: T | ClassOrFunctionReturning): void; /** * Register a class within the container. + * + * @template T + * @param {string} name + * @param {ClassOrFunctionReturning} concrete + * @memberof IContainer */ singleton(name: string, concrete: ClassOrFunctionReturning): void; /** * Alias a registration to a different name. + * + * @param {string} name + * @param {string} alias + * @memberof IContainer */ alias(name: string, alias: string): void; /** * Determine if the given name has been registered. + * + * @param {string} name + * @returns {boolean} + * @memberof IContainer */ has(name: string): boolean; /** * Given a class or function, builds it up and returns it. + * + * @template T + * @param {(ClassOrFunctionReturning | Resolver)} targetOrResolver + * @param {BuildResolverOptions<{}>} [opts] + * @returns {*} + * @memberof IContainer */ - call(targetOrResolver: ClassOrFunctionReturning | Resolver, opts?: BuildResolverOptions<{}>): any; + build(targetOrResolver: ClassOrFunctionReturning | Resolver, opts?: BuildResolverOptions<{}>): any; } diff --git a/packages/core-kernel/src/contracts/core-kernel/filesystem.ts b/packages/core-kernel/src/contracts/core-kernel/filesystem.ts index 2033f9fb8f..c37448fb37 100644 --- a/packages/core-kernel/src/contracts/core-kernel/filesystem.ts +++ b/packages/core-kernel/src/contracts/core-kernel/filesystem.ts @@ -1,14 +1,11 @@ -import { IApplication } from "./application"; - export interface IFilesystem { /** * Create a new instance of the filesystem. * - * @param {IApplication} app * @returns {Promise} * @memberof IFilesystem */ - make(app: IApplication): Promise; + make(): Promise; /** * Determine if a file exists. diff --git a/packages/core-kernel/src/contracts/core-kernel/index.ts b/packages/core-kernel/src/contracts/core-kernel/index.ts index 2ec857a3db..92b8d6e466 100644 --- a/packages/core-kernel/src/contracts/core-kernel/index.ts +++ b/packages/core-kernel/src/contracts/core-kernel/index.ts @@ -5,3 +5,4 @@ export * from "./container"; export * from "./event-dispatcher"; export * from "./filesystem"; export * from "./logger"; +export * from "./queue"; diff --git a/packages/core-kernel/src/contracts/core-kernel/logger.ts b/packages/core-kernel/src/contracts/core-kernel/logger.ts index 9231841d57..a1285de059 100644 --- a/packages/core-kernel/src/contracts/core-kernel/logger.ts +++ b/packages/core-kernel/src/contracts/core-kernel/logger.ts @@ -1,17 +1,15 @@ -import { IApplication } from "./application"; - /** - * @see https://tools.ietf.org/html/rfc5424 + * @remarks + * This interface represents the {@link https://tools.ietf.org/html/rfc5424 | The Syslog Protocol}. */ export interface ILogger { /** * Create a new instance of the logger. * - * @param {IApplication} app * @returns {Promise} * @memberof ILogger */ - make(app: IApplication): Promise; + make(): Promise; /** * System is unusable. diff --git a/packages/core-kernel/src/contracts/core-kernel/queue.ts b/packages/core-kernel/src/contracts/core-kernel/queue.ts new file mode 100644 index 0000000000..2f043af509 --- /dev/null +++ b/packages/core-kernel/src/contracts/core-kernel/queue.ts @@ -0,0 +1,7 @@ +/** + * @export + * @interface IQueue + */ +export interface IQueue { + // +} diff --git a/packages/core-kernel/src/repositories/provider.ts b/packages/core-kernel/src/repositories/provider.ts index b045358068..1edd6e8bc7 100644 --- a/packages/core-kernel/src/repositories/provider.ts +++ b/packages/core-kernel/src/repositories/provider.ts @@ -94,7 +94,6 @@ export class ProviderRepository { } /** - * * @param {string} name * @param {AbstractServiceProvider} provider * @memberof ProviderRepository diff --git a/packages/core-kernel/src/services/cache/drivers/index.ts b/packages/core-kernel/src/services/cache/drivers/index.ts new file mode 100644 index 0000000000..33dac29e22 --- /dev/null +++ b/packages/core-kernel/src/services/cache/drivers/index.ts @@ -0,0 +1 @@ +export * from "./memory"; diff --git a/packages/core-kernel/src/services/cache/adapters/memory.ts b/packages/core-kernel/src/services/cache/drivers/memory.ts similarity index 89% rename from packages/core-kernel/src/services/cache/adapters/memory.ts rename to packages/core-kernel/src/services/cache/drivers/memory.ts index 72a4815e3f..07ad2bf345 100644 --- a/packages/core-kernel/src/services/cache/adapters/memory.ts +++ b/packages/core-kernel/src/services/cache/drivers/memory.ts @@ -4,14 +4,14 @@ import { NotImplementedError } from "../../../errors"; /** * @export - * @class MemoryStore + * @class Memory * @implements {ICacheStore} */ -export class MemoryStore implements ICacheStore { +export class Memory implements ICacheStore { /** * @private * @type {Map} - * @memberof MemoryStore + * @memberof Memory */ private readonly store: Map = new Map(); @@ -30,7 +30,7 @@ export class MemoryStore implements ICacheStore { * Get all of the items in the cache. * * @returns {Array<[K, T]>} - * @memberof MemoryStore + * @memberof Memory */ public async all(): Promise> { return Array.from(this.store.entries()); @@ -40,7 +40,7 @@ export class MemoryStore implements ICacheStore { * Get the keys of the cache items. * * @returns {K[]} - * @memberof MemoryStore + * @memberof Memory */ public async keys(): Promise { return Array.from(this.store.keys()); @@ -50,7 +50,7 @@ export class MemoryStore implements ICacheStore { * Get the values of the cache items. * * @returns {T[]} - * @memberof MemoryStore + * @memberof Memory */ public async values(): Promise { return Array.from(this.store.values()); @@ -61,7 +61,7 @@ export class MemoryStore implements ICacheStore { * * @param {K} key * @returns {(T | undefined)} - * @memberof MemoryStore + * @memberof Memory */ public async get(key: K): Promise { return this.store.get(key); @@ -72,7 +72,7 @@ export class MemoryStore implements ICacheStore { * * @param {K[]} keys * @returns {(Array)} - * @memberof MemoryStore + * @memberof Memory */ public async getMany(keys: K[]): Promise> { return keys.map((key: K) => this.store.get(key)); @@ -85,7 +85,7 @@ export class MemoryStore implements ICacheStore { * @param {T} value * @param {number} seconds * @returns {boolean} - * @memberof MemoryStore + * @memberof Memory */ public async put(key: K, value: T, seconds?: number): Promise { this.store.set(key, value); @@ -99,7 +99,7 @@ export class MemoryStore implements ICacheStore { * @param {Array<[K, T]>} values * @param {number} seconds * @returns {boolean[]} - * @memberof MemoryStore + * @memberof Memory */ public async putMany(values: Array<[K, T]>, seconds?: number): Promise { return Promise.all(values.map(async (value: [K, T]) => this.put(value[0], value[1]))); @@ -110,7 +110,7 @@ export class MemoryStore implements ICacheStore { * * @param {K} key * @returns {boolean} - * @memberof MemoryStore + * @memberof Memory */ public async has(key: K): Promise { return this.store.has(key); @@ -121,7 +121,7 @@ export class MemoryStore implements ICacheStore { * * @param {K[]} keys * @returns {boolean[]} - * @memberof MemoryStore + * @memberof Memory */ public async hasMany(keys: K[]): Promise { return Promise.all(keys.map((key: K) => this.has(key))); @@ -132,7 +132,7 @@ export class MemoryStore implements ICacheStore { * * @param {K} key * @returns {boolean} - * @memberof MemoryStore + * @memberof Memory */ public async missing(key: K): Promise { return !this.has(key); @@ -143,7 +143,7 @@ export class MemoryStore implements ICacheStore { * * @param {K[]} keys * @returns {boolean[]} - * @memberof MemoryStore + * @memberof Memory */ public async missingMany(keys: K[]): Promise { return Promise.all([...keys].map((key: K) => this.missing(key))); @@ -155,7 +155,7 @@ export class MemoryStore implements ICacheStore { * @param {K} key * @param {T} value * @returns {boolean} - * @memberof MemoryStore + * @memberof Memory */ public async forever(key: K, value: T): Promise { throw new NotImplementedError(this.constructor.name, "forever"); @@ -167,7 +167,7 @@ export class MemoryStore implements ICacheStore { * @param {Array<[K, T]>} values * @param {T} value * @returns {boolean[]} - * @memberof MemoryStore + * @memberof Memory */ public async foreverMany(values: Array<[K, T]>, value: T): Promise { throw new NotImplementedError(this.constructor.name, "foreverMany"); @@ -178,7 +178,7 @@ export class MemoryStore implements ICacheStore { * * @param {K} key * @returns {boolean} - * @memberof MemoryStore + * @memberof Memory */ public async forget(key: K): Promise { this.store.delete(key); @@ -191,7 +191,7 @@ export class MemoryStore implements ICacheStore { * * @param {K[]} keys * @returns {boolean[]} - * @memberof MemoryStore + * @memberof Memory */ public async forgetMany(keys: K[]): Promise { return Promise.all(keys.map((key: K) => this.missing(key))); @@ -201,7 +201,7 @@ export class MemoryStore implements ICacheStore { * Remove all items from the cache. * * @returns {boolean} - * @memberof MemoryStore + * @memberof Memory */ public async flush(): Promise { this.store.clear(); @@ -213,7 +213,7 @@ export class MemoryStore implements ICacheStore { * Get the cache key prefix. * * @returns {string} - * @memberof MemoryStore + * @memberof Memory */ public async getPrefix(): Promise { throw new NotImplementedError(this.constructor.name, "getPrefix"); diff --git a/packages/core-kernel/src/services/cache/factory.ts b/packages/core-kernel/src/services/cache/factory.ts deleted file mode 100644 index 382cfbac28..0000000000 --- a/packages/core-kernel/src/services/cache/factory.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Kernel } from "../../contracts"; - -/** - * @export - * @class CacheFactory - */ -export class CacheFactory { - /** - * @param {Kernel.IApplication} app - * @memberof CacheFactory - */ - public constructor(private readonly app: Kernel.IApplication) {} - - /** - * @param {Kernel.ICacheStore} store - * @returns {Kernel.ICacheStore} - * @memberof CacheFactory - */ - public async make(store: Kernel.ICacheStore): Promise> { - return store.make(this.app); - } -} diff --git a/packages/core-kernel/src/services/cache/index.ts b/packages/core-kernel/src/services/cache/index.ts index 676441e825..0ddd6982c8 100644 --- a/packages/core-kernel/src/services/cache/index.ts +++ b/packages/core-kernel/src/services/cache/index.ts @@ -1,2 +1,2 @@ -export * from "./factory"; -export * from "./adapters/memory"; +export * from "./service-provider"; +export * from "./manager"; diff --git a/packages/core-kernel/src/services/cache/manager.ts b/packages/core-kernel/src/services/cache/manager.ts new file mode 100644 index 0000000000..109d30bd4d --- /dev/null +++ b/packages/core-kernel/src/services/cache/manager.ts @@ -0,0 +1,26 @@ +// import { Kernel } from "../../contracts"; +import { Manager } from "../../support/manager"; +import { Memory } from "./drivers"; + +export class CacheManager extends Manager { + /** + * Create an instance of the Memory driver. + * + * @returns {Promise} + * @memberof CacheManager + */ + public async createMemoryDriver(): Promise { + return this.app.build(Memory).make(); + } + + /** + * Get the default log driver name. + * + * @protected + * @returns {string} + * @memberof CacheManager + */ + protected getDefaultDriver(): string { + return "memory"; + } +} diff --git a/packages/core-kernel/src/services/cache/service-provider.ts b/packages/core-kernel/src/services/cache/service-provider.ts new file mode 100644 index 0000000000..1e78c8f926 --- /dev/null +++ b/packages/core-kernel/src/services/cache/service-provider.ts @@ -0,0 +1,25 @@ +import { PackageJson } from "type-fest"; +import { AbstractServiceProvider } from "../../support"; +import { CacheManager } from "./manager"; + +export class ServiceProvider extends AbstractServiceProvider { + /** + * Register the service provider. + * + * @returns {Promise} + * @memberof ServiceProvider + */ + public async register(): Promise { + this.app.singleton("cacheManager", CacheManager); + } + + /** + * Get the manifest of the service provider. + * + * @returns {PackageJson} + * @memberof ServiceProvider + */ + public getPackageJson(): PackageJson { + return {}; + } +} diff --git a/packages/core-kernel/src/config/adapters/index.ts b/packages/core-kernel/src/services/config/drivers/index.ts similarity index 100% rename from packages/core-kernel/src/config/adapters/index.ts rename to packages/core-kernel/src/services/config/drivers/index.ts diff --git a/packages/core-kernel/src/config/adapters/local.ts b/packages/core-kernel/src/services/config/drivers/local.ts similarity index 76% rename from packages/core-kernel/src/config/adapters/local.ts rename to packages/core-kernel/src/services/config/drivers/local.ts index 18b1bb0516..e5ff055903 100644 --- a/packages/core-kernel/src/config/adapters/local.ts +++ b/packages/core-kernel/src/services/config/drivers/local.ts @@ -2,24 +2,37 @@ import cosmiconfig from "cosmiconfig"; import { set } from "dottie"; import { parseFileSync } from "envfile"; import { JsonObject } from "type-fest"; -import { Kernel } from "../../contracts"; -import { InvalidApplicationConfiguration, InvalidEnvironmentConfiguration } from "../../errors"; +import { Kernel } from "../../../contracts"; +import { InvalidApplicationConfiguration, InvalidEnvironmentConfiguration } from "../../../errors"; /** * @export - * @class LocalAdapter + * @class Local * @implements {Kernel.IConfigAdapter} */ -export class LocalAdapter implements Kernel.IConfigAdapter { +export class Local implements Kernel.IConfigAdapter { /** - * @param {Kernel.IApplication} app - * @memberof BaseAdapter + * The application instance. + * + * @protected + * @type {Kernel.IApplication} + * @memberof Manager */ - public constructor(protected readonly app: Kernel.IApplication) {} + protected readonly app: Kernel.IApplication; + + /** + * Create a new manager instance. + * + * @param {{ app:Kernel.IApplication }} { app } + * @memberof Manager + */ + public constructor({ app }: { app: Kernel.IApplication }) { + this.app = app; + } /** * @returns {Promise} - * @memberof LocalAdapter + * @memberof Local */ public async loadConfiguration(): Promise { try { @@ -35,7 +48,7 @@ export class LocalAdapter implements Kernel.IConfigAdapter { /** * @returns {Promise} - * @memberof LocalAdapter + * @memberof Local */ public async loadEnvironmentVariables(): Promise { // @TODO: enable this after initial migration @@ -57,11 +70,11 @@ export class LocalAdapter implements Kernel.IConfigAdapter { /** * @private * @returns {Promise} - * @memberof LocalAdapter + * @memberof Local */ private async loadServiceProviders(): Promise { this.app.config( - "providers", + "service-providers", this.loadFromLocation([ this.app.configPath("service-providers.json"), this.app.configPath("service-providers.js"), @@ -72,7 +85,7 @@ export class LocalAdapter implements Kernel.IConfigAdapter { /** * @private * @returns {Promise} - * @memberof LocalAdapter + * @memberof Local */ private async loadPeers(): Promise { this.app.config("peers", this.loadFromLocation([this.app.configPath("peers.json")])); @@ -81,7 +94,7 @@ export class LocalAdapter implements Kernel.IConfigAdapter { /** * @private * @returns {Promise} - * @memberof LocalAdapter + * @memberof Local */ private async loadDelegates(): Promise { this.app.config("delegates", this.loadFromLocation([this.app.configPath("delegates.json")])); @@ -91,7 +104,7 @@ export class LocalAdapter implements Kernel.IConfigAdapter { * @private * @param {string[]} searchPlaces * @returns {JsonObject} - * @memberof LocalAdapter + * @memberof Local */ private loadFromLocation(searchPlaces: string[]): JsonObject { return cosmiconfig(this.app.namespace(), { diff --git a/packages/core-kernel/src/services/config/drivers/remote.ts b/packages/core-kernel/src/services/config/drivers/remote.ts new file mode 100644 index 0000000000..d40da837c6 --- /dev/null +++ b/packages/core-kernel/src/services/config/drivers/remote.ts @@ -0,0 +1,43 @@ +import { Kernel } from "../../../contracts"; + +/** + * @export + * @class Remote + * @implements {Kernel.IConfigAdapter} + */ +export class Remote implements Kernel.IConfigAdapter { + /** + * The application instance. + * + * @protected + * @type {Kernel.IApplication} + * @memberof Manager + */ + protected readonly app: Kernel.IApplication; + + /** + * Create a new manager instance. + * + * @param {{ app:Kernel.IApplication }} { app } + * @memberof Manager + */ + public constructor({ app }: { app: Kernel.IApplication }) { + this.app = app; + } + + /** + * @returns {Promise} + * @memberof Remote + */ + public async loadConfiguration(): Promise { + // @TODO + } + + /** + * @returns {Promise} + * @memberof Remote + */ + public async loadEnvironmentVariables(): Promise { + // @TODO + } +} diff --git a/packages/core-kernel/src/services/config/index.ts b/packages/core-kernel/src/services/config/index.ts new file mode 100644 index 0000000000..b545bf7156 --- /dev/null +++ b/packages/core-kernel/src/services/config/index.ts @@ -0,0 +1,3 @@ +export * from "./service-provider"; +export * from "./manager"; +export * from "./repository"; diff --git a/packages/core-kernel/src/services/config/manager.ts b/packages/core-kernel/src/services/config/manager.ts new file mode 100644 index 0000000000..a52ed5e1de --- /dev/null +++ b/packages/core-kernel/src/services/config/manager.ts @@ -0,0 +1,36 @@ +import { Kernel } from "../../contracts"; +import { Manager } from "../../support/manager"; +import { Local, Remote } from "./drivers"; + +export class ConfigManager extends Manager { + /** + * Create an instance of the Local driver. + * + * @returns {Promise} + * @memberof ConfigManager + */ + public async createLocalDriver(): Promise { + return this.app.build(Local); + } + + /** + * Create an instance of the Remote driver. + * + * @returns {Promise} + * @memberof ConfigManager + */ + public async createRemoteDriver(): Promise { + return this.app.build(Remote); + } + + /** + * Get the default log driver name. + * + * @protected + * @returns {string} + * @memberof ConfigManager + */ + protected getDefaultDriver(): string { + return "local"; + } +} diff --git a/packages/core-kernel/src/services/config/repository.ts b/packages/core-kernel/src/services/config/repository.ts new file mode 100644 index 0000000000..1220f39d34 --- /dev/null +++ b/packages/core-kernel/src/services/config/repository.ts @@ -0,0 +1,71 @@ +import { get, set } from "dottie"; +import { JsonObject } from "type-fest"; + +/** + * @export + * @class ConfigRepository + * @extends {Map} + */ +export class ConfigRepository { + /** + * All of the configuration items. + * + * @private + * @type {JsonObject} + * @memberof ConfigRepository + */ + private readonly items: JsonObject; + + /** + * Create a new configuration repository. + * + * @param {JsonObject} config + * @memberof ConfigRepository + */ + public constructor(config: JsonObject) { + this.items = config; + } + + /** + * Get the specified configuration value. + * + * @template T + * @param {string} key + * @param {T} [defaultValue] + * @returns {T} + * @memberof ConfigRepository + */ + public get(key: string, defaultValue?: T): T { + if (!this.has(key)) { + return defaultValue; + } + + return get(this.items, key, defaultValue) as T; + } + + /** + * Set a given configuration value. + * + * @template T + * @param {string} key + * @param {T} value + * @returns {boolean} + * @memberof ConfigRepository + */ + public set(key: string, value: T): boolean { + set(this.items, key, value); + + return this.has(key); + } + + /** + * Determine if the given configuration value exists. + * + * @param {string} key + * @returns {boolean} + * @memberof ConfigRepository + */ + public has(key: string): boolean { + return !!get(this.items, key); + } +} diff --git a/packages/core-kernel/src/services/config/service-provider.ts b/packages/core-kernel/src/services/config/service-provider.ts new file mode 100644 index 0000000000..e28a253fe7 --- /dev/null +++ b/packages/core-kernel/src/services/config/service-provider.ts @@ -0,0 +1,28 @@ +import { JsonObject, PackageJson } from "type-fest"; +import { AbstractServiceProvider } from "../../support"; +import { ConfigManager } from "./manager"; +import { ConfigRepository } from "./repository"; + +export class ServiceProvider extends AbstractServiceProvider { + /** + * Register the service provider. + * + * @returns {Promise} + * @memberof ServiceProvider + */ + public async register(): Promise { + this.app.singleton("configManager", ConfigManager); + + this.app.bind("config", new ConfigRepository(this.app.resolve("config"))); + } + + /** + * Get the manifest of the service provider. + * + * @returns {PackageJson} + * @memberof ServiceProvider + */ + public getPackageJson(): PackageJson { + return {}; + } +} diff --git a/packages/core-kernel/src/config/watcher.ts b/packages/core-kernel/src/services/config/watcher.ts similarity index 96% rename from packages/core-kernel/src/config/watcher.ts rename to packages/core-kernel/src/services/config/watcher.ts index 1f29bdc741..102a0daa50 100644 --- a/packages/core-kernel/src/config/watcher.ts +++ b/packages/core-kernel/src/services/config/watcher.ts @@ -1,5 +1,5 @@ import nsfw from "nsfw"; -import { Kernel } from "../contracts"; +import { Kernel } from "../../contracts"; /** * @interface IFileEvent diff --git a/packages/core-kernel/src/services/events/index.ts b/packages/core-kernel/src/services/events/index.ts index a52c36178c..3b38217493 100644 --- a/packages/core-kernel/src/services/events/index.ts +++ b/packages/core-kernel/src/services/events/index.ts @@ -1 +1,2 @@ +export * from "./service-provider"; export * from "./dispatcher"; diff --git a/packages/core-kernel/src/services/events/service-provider.ts b/packages/core-kernel/src/services/events/service-provider.ts new file mode 100644 index 0000000000..ab747cfe98 --- /dev/null +++ b/packages/core-kernel/src/services/events/service-provider.ts @@ -0,0 +1,25 @@ +import { PackageJson } from "type-fest"; +import { AbstractServiceProvider } from "../../support"; +import { EventDispatcher } from "./dispatcher"; + +export class ServiceProvider extends AbstractServiceProvider { + /** + * Register the service provider. + * + * @returns {Promise} + * @memberof ServiceProvider + */ + public async register(): Promise { + this.app.singleton("events", EventDispatcher); + } + + /** + * Get the manifest of the service provider. + * + * @returns {PackageJson} + * @memberof ServiceProvider + */ + public getPackageJson(): PackageJson { + return {}; + } +} diff --git a/packages/core-kernel/src/services/filesystem/adapters/local.ts b/packages/core-kernel/src/services/filesystem/drivers/local.ts similarity index 95% rename from packages/core-kernel/src/services/filesystem/adapters/local.ts rename to packages/core-kernel/src/services/filesystem/drivers/local.ts index 05e5f2b703..348ff9769d 100644 --- a/packages/core-kernel/src/services/filesystem/adapters/local.ts +++ b/packages/core-kernel/src/services/filesystem/drivers/local.ts @@ -12,17 +12,16 @@ import { writeFile, } from "fs-extra"; import { resolve } from "path"; -import { IApplication, IFilesystem } from "../../../contracts/core-kernel"; +import { IFilesystem } from "../../../contracts/core-kernel"; -export class LocalAdapter implements IFilesystem { +export class Local implements IFilesystem { /** * Create a new instance of the filesystem. * - * @param {IApplication} app * @returns {Promise} * @memberof IFilesystem */ - public async make(app: IApplication): Promise { + public async make(): Promise { return this; } diff --git a/packages/core-kernel/src/services/filesystem/factory.ts b/packages/core-kernel/src/services/filesystem/factory.ts deleted file mode 100644 index ecf5314eb4..0000000000 --- a/packages/core-kernel/src/services/filesystem/factory.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Kernel } from "../../contracts"; - -/** - * @export - * @class FilesystemFactory - */ -export class FilesystemFactory { - /** - * @param {Kernel.IApplication} app - * @memberof FilesystemFactory - */ - public constructor(private readonly app: Kernel.IApplication) {} - - /** - * @param {Kernel.IFilesystem} driver - * @returns {Promise} - * @memberof FilesystemFactory - */ - public async make(driver: Kernel.IFilesystem): Promise { - return driver.make(this.app); - } -} diff --git a/packages/core-kernel/src/services/filesystem/index.ts b/packages/core-kernel/src/services/filesystem/index.ts index 47d38b8071..0ddd6982c8 100644 --- a/packages/core-kernel/src/services/filesystem/index.ts +++ b/packages/core-kernel/src/services/filesystem/index.ts @@ -1 +1,2 @@ -export * from "./factory"; +export * from "./service-provider"; +export * from "./manager"; diff --git a/packages/core-kernel/src/services/filesystem/manager.ts b/packages/core-kernel/src/services/filesystem/manager.ts new file mode 100644 index 0000000000..a5004a7ab9 --- /dev/null +++ b/packages/core-kernel/src/services/filesystem/manager.ts @@ -0,0 +1,26 @@ +import { Kernel } from "../../contracts"; +import { Manager } from "../../support/manager"; +import { Local } from "./drivers/local"; + +export class FilesystemManager extends Manager { + /** + * Create an instance of the Local driver. + * + * @returns {Promise} + * @memberof FilesystemManager + */ + public async createLocalDriver(): Promise { + return this.app.build(Local).make(); + } + + /** + * Get the default log driver name. + * + * @protected + * @returns {string} + * @memberof FilesystemManager + */ + protected getDefaultDriver(): string { + return "local"; + } +} diff --git a/packages/core-kernel/src/services/filesystem/service-provider.ts b/packages/core-kernel/src/services/filesystem/service-provider.ts new file mode 100644 index 0000000000..f95513753e --- /dev/null +++ b/packages/core-kernel/src/services/filesystem/service-provider.ts @@ -0,0 +1,27 @@ +import { PackageJson } from "type-fest"; +import { AbstractServiceProvider } from "../../support"; +import { FilesystemManager } from "./manager"; + +export class ServiceProvider extends AbstractServiceProvider { + /** + * Register the service provider. + * + * @returns {Promise} + * @memberof ServiceProvider + */ + public async register(): Promise { + this.app.singleton("filesystemManager", FilesystemManager); + + this.app.bind("filesystem", await this.app.resolve("filesystemManager").driver()); + } + + /** + * Get the manifest of the service provider. + * + * @returns {PackageJson} + * @memberof ServiceProvider + */ + public getPackageJson(): PackageJson { + return {}; + } +} diff --git a/packages/core-kernel/src/services/index.ts b/packages/core-kernel/src/services/index.ts index d79df5d83c..d22e961fa7 100644 --- a/packages/core-kernel/src/services/index.ts +++ b/packages/core-kernel/src/services/index.ts @@ -1,7 +1,9 @@ import * as Cache from "./cache"; +import * as Config from "./config"; import * as Events from "./events"; -import * as Log from "./logger"; +import * as Filesystem from "./filesystem"; +import * as Log from "./log"; import * as Queue from "./queue"; import * as Scheduler from "./scheduler"; -export { Cache, Events, Log, Queue, Scheduler }; +export { Cache, Config, Events, Filesystem, Log, Queue, Scheduler }; diff --git a/packages/core-kernel/src/services/logger/adapters/console.ts b/packages/core-kernel/src/services/log/drivers/console.ts similarity index 65% rename from packages/core-kernel/src/services/logger/adapters/console.ts rename to packages/core-kernel/src/services/log/drivers/console.ts index a74e465456..d040f73df4 100644 --- a/packages/core-kernel/src/services/logger/adapters/console.ts +++ b/packages/core-kernel/src/services/log/drivers/console.ts @@ -1,15 +1,14 @@ -import { IApplication, ILogger } from "../../../contracts/core-kernel"; +import { ILogger } from "../../../contracts/core-kernel"; import { AbstractLogger } from "../logger"; -export class ConsoleLogger extends AbstractLogger implements ILogger { +export class Console extends AbstractLogger implements ILogger { /** - * Create a new instance of the logger. + * Create a new instance of the Console driver. * - * @param {IApplication} app * @returns {Promise} - * @memberof ConsoleLogger + * @memberof Console */ - public async make(app: IApplication): Promise { + public async make(): Promise { this.logger = console; return this; diff --git a/packages/core-kernel/src/services/log/drivers/index.ts b/packages/core-kernel/src/services/log/drivers/index.ts new file mode 100644 index 0000000000..bf4f5ebda5 --- /dev/null +++ b/packages/core-kernel/src/services/log/drivers/index.ts @@ -0,0 +1 @@ +export * from "./console"; diff --git a/packages/core-kernel/src/services/log/index.ts b/packages/core-kernel/src/services/log/index.ts new file mode 100644 index 0000000000..0dd287cd5d --- /dev/null +++ b/packages/core-kernel/src/services/log/index.ts @@ -0,0 +1,3 @@ +export * from "./service-provider"; +export * from "./manager"; +export * from "./logger"; diff --git a/packages/core-kernel/src/services/logger/logger.ts b/packages/core-kernel/src/services/log/logger.ts similarity index 100% rename from packages/core-kernel/src/services/logger/logger.ts rename to packages/core-kernel/src/services/log/logger.ts diff --git a/packages/core-kernel/src/services/log/manager.ts b/packages/core-kernel/src/services/log/manager.ts new file mode 100644 index 0000000000..fc605749b1 --- /dev/null +++ b/packages/core-kernel/src/services/log/manager.ts @@ -0,0 +1,26 @@ +import { Kernel } from "../../contracts"; +import { Manager } from "../../support/manager"; +import { Console } from "./drivers"; + +export class LogManager extends Manager { + /** + * Create an instance of the Console driver. + * + * @returns {Promise} + * @memberof LogManager + */ + public async createConsoleDriver(): Promise { + return this.app.build(Console).make(); + } + + /** + * Get the default log driver name. + * + * @protected + * @returns {string} + * @memberof LogManager + */ + protected getDefaultDriver(): string { + return "console"; + } +} diff --git a/packages/core-kernel/src/services/log/service-provider.ts b/packages/core-kernel/src/services/log/service-provider.ts new file mode 100644 index 0000000000..41ed7bfe9a --- /dev/null +++ b/packages/core-kernel/src/services/log/service-provider.ts @@ -0,0 +1,25 @@ +import { PackageJson } from "type-fest"; +import { AbstractServiceProvider } from "../../support"; +import { LogManager } from "./manager"; + +export class ServiceProvider extends AbstractServiceProvider { + /** + * Register the service provider. + * + * @returns {Promise} + * @memberof ServiceProvider + */ + public async register(): Promise { + this.app.singleton("logManager", LogManager); + } + + /** + * Get the manifest of the service provider. + * + * @returns {PackageJson} + * @memberof ServiceProvider + */ + public getPackageJson(): PackageJson { + return {}; + } +} diff --git a/packages/core-kernel/src/services/logger/factory.ts b/packages/core-kernel/src/services/logger/factory.ts deleted file mode 100644 index b22e5eef00..0000000000 --- a/packages/core-kernel/src/services/logger/factory.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { Kernel } from "../../contracts"; - -/** - * @export - * @class LoggerFactory - */ -export class LoggerFactory { - /** - * @param {Kernel.IApplication} app - * @memberof LoggerFactory - */ - public constructor(private readonly app: Kernel.IApplication) {} - - /** - * @param {Kernel.ILogger} driver - * @returns {Promise} - * @memberof LoggerFactory - */ - public async make(driver: Kernel.ILogger): Promise { - const instance: Kernel.ILogger = await driver.make(this.app); - - // instance.debug(`${this.app.token()}/${this.app.network()}@${this.app.version()}`); - - // this.logPaths(instance); - - return instance; - } - - // /** - // * @private - // * @param {Kernel.ILogger} driver - // * @memberof LoggerFactory - // */ - // private logPaths(driver: Kernel.ILogger): void { - // for (const [key, value] of Object.entries({ - // Data: this.app.dataPath(), - // Config: this.app.configPath(), - // Cache: this.app.cachePath(), - // Log: this.app.logPath(), - // Temp: this.app.tempPath(), - // })) { - // driver.debug(`${key} Directory: ${value}`); - // } - // } -} diff --git a/packages/core-kernel/src/services/logger/index.ts b/packages/core-kernel/src/services/logger/index.ts deleted file mode 100644 index dcc2e57881..0000000000 --- a/packages/core-kernel/src/services/logger/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./factory"; -export * from "./logger"; diff --git a/packages/core-kernel/src/services/queue/drivers/memory.ts b/packages/core-kernel/src/services/queue/drivers/memory.ts new file mode 100644 index 0000000000..aad12d92d8 --- /dev/null +++ b/packages/core-kernel/src/services/queue/drivers/memory.ts @@ -0,0 +1,3 @@ +export class Memory { + // +} diff --git a/packages/core-kernel/src/services/queue/factory.ts b/packages/core-kernel/src/services/queue/factory.ts deleted file mode 100644 index 42f4b2ab6b..0000000000 --- a/packages/core-kernel/src/services/queue/factory.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Kernel } from "../../contracts"; - -/** - * @export - * @class QueueFactory - */ -export class QueueFactory { - /** - * @param {Kernel.IApplication} app - * @memberof QueueFactory - */ - // @ts-ignore - public constructor(private readonly app: Kernel.IApplication) {} -} diff --git a/packages/core-kernel/src/services/queue/index.ts b/packages/core-kernel/src/services/queue/index.ts index 47d38b8071..0ddd6982c8 100644 --- a/packages/core-kernel/src/services/queue/index.ts +++ b/packages/core-kernel/src/services/queue/index.ts @@ -1 +1,2 @@ -export * from "./factory"; +export * from "./service-provider"; +export * from "./manager"; diff --git a/packages/core-kernel/src/services/queue/manager.ts b/packages/core-kernel/src/services/queue/manager.ts new file mode 100644 index 0000000000..6a267485b3 --- /dev/null +++ b/packages/core-kernel/src/services/queue/manager.ts @@ -0,0 +1,26 @@ +import { Kernel } from "../../contracts"; +import { Manager } from "../../support/manager"; +import { Memory } from "./drivers/memory"; + +export class QueueManager extends Manager { + /** + * Create an instance of the Memory driver. + * + * @returns {Promise} + * @memberof QueueManager + */ + public async createMemoryDriver(): Promise { + return this.app.build(Memory).make(); + } + + /** + * Get the default log driver name. + * + * @protected + * @returns {string} + * @memberof QueueManager + */ + protected getDefaultDriver(): string { + return "memory"; + } +} diff --git a/packages/core-kernel/src/services/queue/service-provider.ts b/packages/core-kernel/src/services/queue/service-provider.ts new file mode 100644 index 0000000000..49457493a2 --- /dev/null +++ b/packages/core-kernel/src/services/queue/service-provider.ts @@ -0,0 +1,25 @@ +import { PackageJson } from "type-fest"; +import { AbstractServiceProvider } from "../../support"; +import { QueueManager } from "./manager"; + +export class ServiceProvider extends AbstractServiceProvider { + /** + * Register the service provider. + * + * @returns {Promise} + * @memberof ServiceProvider + */ + public async register(): Promise { + this.app.singleton("queueManager", QueueManager); + } + + /** + * Get the manifest of the service provider. + * + * @returns {PackageJson} + * @memberof ServiceProvider + */ + public getPackageJson(): PackageJson { + return {}; + } +} diff --git a/packages/core-kernel/src/services/scheduler/cron-frequencies.ts b/packages/core-kernel/src/services/scheduler/cron-frequencies.ts index c0691bad88..3a5df6afe9 100644 --- a/packages/core-kernel/src/services/scheduler/cron-frequencies.ts +++ b/packages/core-kernel/src/services/scheduler/cron-frequencies.ts @@ -1,6 +1,7 @@ /** - * @see https://crontab.guru/ - * @see https://github.com/kelektiv/node-cron + * @remarks + * {@link https://crontab.guru/ | crontab guru} + * {@link https://github.com/kelektiv/node-cron | node-cron} * * @export * @class CronFrequencies diff --git a/packages/core-kernel/src/support/manager.ts b/packages/core-kernel/src/support/manager.ts new file mode 100644 index 0000000000..1a03163c5f --- /dev/null +++ b/packages/core-kernel/src/support/manager.ts @@ -0,0 +1,147 @@ +import { toStudlyCaps } from "strman"; +import { IApplication } from "../contracts/core-kernel"; + +/** + * @export + * @abstract + * @class Manager + * @template T + */ +export abstract class Manager { + /** + * The application instance. + * + * @protected + * @type {IApplication} + * @memberof Manager + */ + protected readonly app: IApplication; + + /** + * @private + * @type {string} + * @memberof Manager + */ + private defaultDriver: string; + + /** + * The array of created "drivers". + * + * @private + * @type {Map} + * @memberof Manager + */ + private drivers: Map = new Map(); + + /** + * The registered custom driver creators. + * + * @private + * @type {Map Promise>} + * @memberof Manager + */ + private customCreators: Map Promise> = new Map< + string, + (app: IApplication) => Promise + >(); + + /** + * Create a new manager instance. + * + * @param {{ app:IApplication }} { app } + * @memberof Manager + */ + public constructor({ app }: { app: IApplication }) { + this.app = app; + this.defaultDriver = this.getDefaultDriver(); + } + + /** + * Get a driver instance. + * + * @param {string} [name] + * @returns {Promise} + * @memberof Manager + */ + public async driver(name?: string): Promise { + name = name || this.defaultDriver; + + if (this.drivers.has(name)) { + return this.drivers.get(name); + } + + if (this.customCreators.has(name)) { + return this.callCustomCreator(name); + } + + return this.createDriver(name); + } + + /** + * Register a custom driver creator callback. + * + * @param {string} name + * @param {(app: IApplication) => T} callback + * @memberof Manager + */ + public extend(name: string, callback: (app: IApplication) => Promise): void { + this.customCreators.set(name, callback); + } + + /** + * Set the default driver name. + * + * @param {string} name + * @memberof Manager + */ + public setDefaultDriver(name: string): void { + this.defaultDriver = name; + } + + /** + * Get the default driver name. + * + * @protected + * @abstract + * @returns {string} + * @memberof Manager + */ + protected abstract getDefaultDriver(): string; + + /** + * Call a custom driver creator. + * + * @private + * @param {string} name + * @returns {Promise} + * @memberof Manager + */ + private async callCustomCreator(name: string): Promise { + // tslint:disable-next-line: await-promise + const value: T = await this.customCreators.get(name)(this.app); + this.drivers.set(name, value); + + return value; + } + + /** + * Create a new driver instance. + * + * @private + * @param {string} name + * @returns {Promise} + * @memberof Manager + */ + private async createDriver(name: string): Promise { + const creatorFunction: string = `create${toStudlyCaps(name)}Driver`; + + if (typeof this[creatorFunction] !== "function") { + throw new Error(`${name} driver is not supported by ${this.constructor.name}.`); + } + + const value: T = await this[creatorFunction](this.app); + this.drivers.set(name, value); + + return value; + } +} diff --git a/packages/core-kernel/src/support/service-provider.ts b/packages/core-kernel/src/support/service-provider.ts index f2273e98e6..81f1b9e8da 100644 --- a/packages/core-kernel/src/support/service-provider.ts +++ b/packages/core-kernel/src/support/service-provider.ts @@ -4,6 +4,8 @@ import { ConfigObject } from "../types"; export abstract class AbstractServiceProvider { /** + * The application instance. + * * @protected * @type {ConfigObject} * @memberof AbstractServiceProvider @@ -11,6 +13,8 @@ export abstract class AbstractServiceProvider { protected opts: ConfigObject; /** + * Create a new service provider instance. + * * @param {Kernel.IApplication} app * @param {ConfigObject} [opts={}] * @memberof AbstractServiceProvider @@ -20,6 +24,8 @@ export abstract class AbstractServiceProvider { } /** + * Register the service provider. + * * @abstract * @returns {Promise} * @memberof AbstractServiceProvider @@ -27,6 +33,8 @@ export abstract class AbstractServiceProvider { public abstract async register(): Promise; /** + * Boot the service provider. + * * @returns {Promise} * @memberof AbstractServiceProvider */ @@ -35,6 +43,8 @@ export abstract class AbstractServiceProvider { } /** + * Dispose the service provider. + * * @returns {Promise} * @memberof AbstractServiceProvider */ @@ -43,6 +53,8 @@ export abstract class AbstractServiceProvider { } /** + * Get the manifest of the service provider. + * * @abstract * @returns {PackageJson} * @memberof AbstractServiceProvider @@ -50,6 +62,8 @@ export abstract class AbstractServiceProvider { public abstract getPackageJson(): PackageJson; /** + * Get the name of the service provider. + * * @returns {string} * @memberof AbstractServiceProvider */ @@ -58,6 +72,8 @@ export abstract class AbstractServiceProvider { } /** + * Get the version of the service provider. + * * @returns {string} * @memberof AbstractServiceProvider */ @@ -66,6 +82,8 @@ export abstract class AbstractServiceProvider { } /** + * Get the default of the service provider. + * * @returns {ConfigObject} * @memberof AbstractServiceProvider */ @@ -74,10 +92,12 @@ export abstract class AbstractServiceProvider { } /** + * Get the dependencies of the service provider. + * * @returns {Record} * @memberof AbstractServiceProvider */ - public depends(): Record { + public getDependencies(): Record { return {}; } @@ -90,10 +110,14 @@ export abstract class AbstractServiceProvider { protected buildConfig(opts: ConfigObject): ConfigObject { opts = { ...opts, ...this.getDefaults() }; - const globalOptions: ConfigObject | undefined = this.app.config("options")[this.getName()]; + try { + const globalOptions: ConfigObject | undefined = this.app.config("options")[this.getName()]; - if (globalOptions) { - this.opts = { ...this.opts, ...globalOptions }; + if (globalOptions) { + this.opts = { ...this.opts, ...globalOptions }; + } + } catch { + // ignore global configuration errors } return opts; diff --git a/packages/core-logger-pino/src/service-provider.ts b/packages/core-logger-pino/src/service-provider.ts index b9ac4c38eb..d5c8e1f282 100644 --- a/packages/core-logger-pino/src/service-provider.ts +++ b/packages/core-logger-pino/src/service-provider.ts @@ -1,10 +1,15 @@ -import { Support, Types } from "@arkecosystem/core-kernel"; +import { Services, Support, Types } from "@arkecosystem/core-kernel"; import { defaults } from "./defaults"; import { PinoLogger } from "./driver"; export class ServiceProvider extends Support.AbstractServiceProvider { public async register(): Promise { - this.app.bind("logger", await this.app.resolve("factoryLogger").make(new PinoLogger(this.opts))); + const logManager: Services.Log.LogManager = this.app.resolve("logManager"); + logManager.extend("pino", async () => new PinoLogger(this.opts).make()); + logManager.setDefaultDriver("pino"); + + // Note: Ensure that we rebind the logger that is bound to the container so IoC can do it's job. + this.app.bind("log", await logManager.driver()); } public getDefaults(): Types.ConfigObject { diff --git a/packages/core-logger-signale/src/service-provider.ts b/packages/core-logger-signale/src/service-provider.ts index 68a0d7d751..d962e6c9f9 100644 --- a/packages/core-logger-signale/src/service-provider.ts +++ b/packages/core-logger-signale/src/service-provider.ts @@ -1,10 +1,15 @@ -import { Support, Types } from "@arkecosystem/core-kernel"; +import { Services, Support, Types } from "@arkecosystem/core-kernel"; import { defaults } from "./defaults"; import { SignaleLogger } from "./driver"; export class ServiceProvider extends Support.AbstractServiceProvider { public async register(): Promise { - this.app.bind("logger", await this.app.resolve("factoryLogger").make(new SignaleLogger(this.opts))); + const logManager: Services.Log.LogManager = this.app.resolve("logManager"); + logManager.extend("signale", async () => new SignaleLogger(this.opts).make()); + logManager.setDefaultDriver("signale"); + + // Note: Ensure that we rebind the logger that is bound to the container so IoC can do it's job. + this.app.bind("log", await logManager.driver()); } public getDefaults(): Types.ConfigObject { diff --git a/packages/core-logger-winston/src/service-provider.ts b/packages/core-logger-winston/src/service-provider.ts index 97d5464ce6..d390826bb9 100644 --- a/packages/core-logger-winston/src/service-provider.ts +++ b/packages/core-logger-winston/src/service-provider.ts @@ -1,10 +1,15 @@ -import { Support, Types } from "@arkecosystem/core-kernel"; +import { Services, Support, Types } from "@arkecosystem/core-kernel"; import { defaults } from "./defaults"; import { WinstonLogger } from "./driver"; export class ServiceProvider extends Support.AbstractServiceProvider { public async register(): Promise { - this.app.bind("logger", await this.app.resolve("factoryLogger").make(new WinstonLogger(this.opts))); + const logManager: Services.Log.LogManager = this.app.resolve("logManager"); + logManager.extend("winston", async () => new WinstonLogger(this.opts).make()); + logManager.setDefaultDriver("winston"); + + // Note: Ensure that we rebind the logger that is bound to the container so IoC can do it's job. + this.app.bind("log", await logManager.driver()); } public getDefaults(): Types.ConfigObject { diff --git a/packages/core/bin/config/testnet/service-providers.js b/packages/core/bin/config/testnet/service-providers.js index cc37be0c62..0cfceaec29 100644 --- a/packages/core/bin/config/testnet/service-providers.js +++ b/packages/core/bin/config/testnet/service-providers.js @@ -1,6 +1,6 @@ module.exports = { + "@arkecosystem/core-logger-pino": {}, "@arkecosystem/core-kernel-dummy": {}, - // "@arkecosystem/core-logger-pino": {}, // "@arkecosystem/core-state": {}, // "@arkecosystem/core-database": {}, // "@arkecosystem/core-database-postgres": { diff --git a/yarn.lock b/yarn.lock index 77b1d47e88..21271d9ca0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11410,6 +11410,11 @@ strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" +strman@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strman/-/strman-2.0.1.tgz#d43bb91c91e100609f336fd4a6539fd8e980e1de" + integrity sha512-00kB9pulmzaQUBl8DJQ4255QXnQn/MHnJzYqKz4a/W5KqCMSaqmv0VReOzkSg2u4FYkKpNhxpp6bs6aEMZeLPw== + strong-log-transformer@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz#0f5ed78d325e0421ac6f90f7f10e691d6ae3ae10"