diff --git a/sdk-core/src/core/service.ts b/sdk-core/src/core/service.ts index b755d89..2b77565 100644 --- a/sdk-core/src/core/service.ts +++ b/sdk-core/src/core/service.ts @@ -31,6 +31,15 @@ export interface ServiceConfig { readonly auth?: ServiceAuth | null; } +/** + * Static container used for holding the default service, since sdk-core is used + * in multiple projects, using an anti-pattern can become troublesome for state + * storage + */ +export interface ServiceStaticContainer { + service: Service | null; +} + /** * Locked down, immutable version of ServiceConfig with defaults already set */ @@ -45,9 +54,7 @@ export interface LockedServiceConfig { } } -export class Service { - private static _defaultService: Service | null = null; - +export abstract class Service { private readonly _config: LockedServiceConfig; public constructor(config: ServiceConfig) { @@ -65,18 +72,23 @@ export class Service { } } + /** + * Configure a new default service + */ public static config(config: ServiceConfig): Service { - this._defaultService = new Service(config); - - return this._defaultService; + throw new Error('Service.config is not implemented correctly, contact admin'); } public static get default(): Service { - if (!this._defaultService) { + if (!this.container.service) { throw new Error('Service.default is not configured, use Service.config() to set a new default'); } - return this._defaultService; + return this.container.service; + } + + public static get container(): ServiceStaticContainer { + throw new Error('Service.container is not implemented correctly, contact admin'); } public get config(): LockedServiceConfig { @@ -87,6 +99,6 @@ export class Service { * This returns the base url and versioning combined */ public get url(): string { - return `${this.config.url}/${this.config.version}` + return `${this.config.url}/${this.config.version}`; } } \ No newline at end of file diff --git a/sdk-core/src/generator/generator.ts b/sdk-core/src/generator/generator.ts index 3a37233..fe7c938 100644 --- a/sdk-core/src/generator/generator.ts +++ b/sdk-core/src/generator/generator.ts @@ -2,6 +2,7 @@ import { CoreController } from "@plattar/api-core"; import { GeneratedProject, PackageJsonVars, Project } from "./generators/project"; import { GeneratedSchema, Schema } from "./generators/schema"; import fs from "fs"; +import { Util } from "./generators/util"; export interface GeneratorData { readonly controllers: Array; @@ -24,6 +25,7 @@ export class Generator { // ensure project folder exists fs.mkdirSync(`${outputDir}/src/schemas`, { recursive: true }); + fs.mkdirSync(`${outputDir}/src/core`, { recursive: true }); // write the .npmignore file await fs.promises.writeFile(`${outputDir}/${project.npmIgnore.fname}`, project.npmIgnore.data); @@ -43,21 +45,60 @@ export class Generator { allSchemas.push(fs.promises.writeFile(`${outputDir}/src/schemas/${schema.fname}`, schema.data)); }); + const serviceSchema = this.generateServiceFile(data); + + // write the service file + allSchemas.push(fs.promises.writeFile(`${outputDir}/src/core/${serviceSchema.fname}`, serviceSchema.data)); + await Promise.all(allSchemas); // write the index.ts file - await fs.promises.writeFile(`${outputDir}/src/index.ts`, this.generateIndexFile(schemas)); + await fs.promises.writeFile(`${outputDir}/src/index.ts`, this.generateIndexFile([ + { + dir: 'schemas', + schemas: schemas + }, + { + dir: 'core', + schemas: [serviceSchema] + } + ])); } - private static generateIndexFile(schemas: Array): string { + private static generateIndexFile(files: Array<{ dir: string, schemas: Array }>): string { let output: string = '/*\n * Warning: Do Not Edit - Auto Generated via @plattar/sdk-core\n */\n\n'; - output += 'export { Service, ServiceConfig, ServiceAuth } from "@plattar/sdk-core";\n'; + output += `export { Service, ServiceConfig, ServiceAuth } from '@plattar/sdk-core';\n`; - schemas.forEach((schema) => { - output += `export * from "./schemas/${schema.name}";\n`; + files.forEach((schemas) => { + schemas.schemas.forEach((schema) => { + output += `export * from "./${schemas.dir}/${schema.name}";\n`; + }); }); return output; } + + public static generateServiceFile(data: GeneratorData): GeneratedSchema { + const className: string = `${Util.capitaliseClassName(data.package.name)}Service`; + + let output: string = `import { Service, ServiceStaticContainer } from '@plattar/sdk-core';\n\n`; + + output += `export class ${className} extends Service {\n`; + output += `\tprivate static readonly serviceContainer:ServiceStaticContainer = {service:null}\n`; + output += `\tpublic static override get container(): ServiceStaticContainer {\n`; + output += `\t\treturn this.serviceContainer;\n`; + output += `\t}\n`; + output += `\tpublic static override config(config: ServiceConfig): ${className} {\n`; + output += `\t\tthis.container.service = new ${className}(config);\n`; + output += `\t\treturn <${className}>this.container.service;\n`; + output += `\t}\n`; + output += '}\n'; + + return { + name: `${data.package.name}-service`, + fname: `${data.package.name}-service.ts`, + data: output + } + } } \ No newline at end of file diff --git a/sdk-core/src/generator/generators/util.ts b/sdk-core/src/generator/generators/util.ts index 291ecd8..b054d1a 100644 --- a/sdk-core/src/generator/generators/util.ts +++ b/sdk-core/src/generator/generators/util.ts @@ -5,7 +5,11 @@ export class Util { * my_named_class = MyNamedClass */ public static capitaliseClassName(name: string): string { - return name.split('_').map((word: string) => { + const capName: string = name.split('_').map((word: string) => { + return word[0].toUpperCase() + word.substring(1); + }).join(''); + + return capName.split('-').map((word: string) => { return word[0].toUpperCase() + word.substring(1); }).join(''); }