@webda/core
Version:
Expose API with Lambda
868 lines (867 loc) • 20.5 kB
TypeScript
import { WorkerLogLevel, WorkerOutput } from "@webda/workout";
import { JSONSchema7 } from "json-schema";
import { OpenAPIV3 } from "openapi-types";
import { Constructor, Core, CoreModel, CoreModelDefinition, Service } from "./index.js";
export type PackageDescriptorAuthor = string | {
name?: string;
email?: string;
url?: string;
};
export type Modda = ServiceConstructor<Service>;
/**
* Defined relationship for one model
*/
export type ModelGraph = {
parent?: Omit<ModelRelation, "type">;
links?: ModelRelation[];
queries?: {
attribute: string;
model: string;
targetAttribute: string;
}[];
maps?: {
attribute: string;
model: string;
targetAttributes: string[];
targetLink: string;
cascadeDelete: boolean;
}[];
children?: string[];
binaries?: {
attribute: string;
cardinality: "ONE" | "MANY";
metadata?: string;
}[];
};
/**
* Defined relationship for all models
*/
export type ModelsGraph = {
[key: string]: ModelGraph;
};
/**
* Some package exists but seems pretty big for this
* https://classic.yarnpkg.com/en/docs/package-json
*/
export interface PackageDescriptor {
name?: string;
version?: string;
description?: string;
keywords?: string[];
license?: string | {
name: string;
};
homepage?: string;
bugs?: string;
repository?: string;
author?: PackageDescriptorAuthor;
contributors?: string[] | PackageDescriptorAuthor[];
files?: string[];
main?: string;
bin?: string | {
[key: string]: string;
};
man?: string | string[];
directories?: {
[key: string]: string;
};
scripts?: {
[key: string]: string;
};
config?: any;
dependencies?: {
[key: string]: string;
};
devDependencies?: {
[key: string]: string;
};
peerDependencies?: {
[key: string]: string;
};
peerDependenciesMeta?: {
[key: string]: {
optional: boolean;
};
};
optionalDependencies?: {
[key: string]: string;
};
bundledDependencies?: string[];
flat?: boolean;
resolutions?: {
[key: string]: string;
};
engines?: {
[key: string]: string;
};
os?: string[];
cpu?: string[];
private?: boolean;
publishConfig?: any;
webda?: Partial<WebdaPackageDescriptor>;
termsOfService?: string;
title?: string;
}
export type ModelRelation = {
attribute: string;
model: string;
type: "LINK" | "LINKS_MAP" | "LINKS_ARRAY" | "LINKS_SIMPLE_ARRAY";
};
/**
* Define the model hierarchy
*/
export type ModelsTree = {
[key: string]: ModelsTree;
};
/**
* A Webda module is a NPM package
*
* It contains one or more Modda to provide features
*/
export interface Module {
/**
* Services provided by the module
*/
moddas?: {
[key: string]: string;
};
/**
* Models provided by the module
*/
models: {
/**
* Models provided by the module
*/
list: {
[key: string]: string;
};
/**
* Models hierarchy tree
*
* Models Graph establish the relationship between models
* Models Tree establish the hierarchy between models classes
*/
tree: ModelsTree;
/**
* Models graph
*
* Typescript does not have reflection, we therefore deduct the
* relations on compilation time and inject in the module
*
* The parent is define by a ModelParent type on the model
* The links are attribute of types ModelLink
*/
graph: ModelsGraph;
/**
* Specific plurals for a model
*/
plurals: {
[key: string]: string;
};
/**
* Contains the shortcut id for the models
*/
shortIds: {
[key: string]: string;
};
/**
* Store the model attributes types
*/
reflections: {
[key: string]: {
[key: string]: string;
};
};
};
/**
* Deployers provided by the module
*
* @link Deployer
*/
deployers?: {
[key: string]: string;
};
/**
* Schemas for services, deployers and coremodel
*/
schemas?: {
[key: string]: JSONSchema7;
};
/**
* Application beans
*/
beans?: {
[key: string]: string;
};
}
/**
* Cached module is all modules discover plus local package including the sources list
*/
export interface CachedModule extends Module {
/**
* Contained dynamic information on the project
* Statically capture on deployment
*/
project: ProjectInformation;
}
export type StaticWebsite = {
url: string;
path?: string;
index?: string;
catchAll?: boolean;
};
export type UnpackedConfiguration = {
version: 3;
/**
* Services configuration
*/
services?: any;
/**
* Global parameters
*/
parameters?: {
/**
* Trust this reverse proxies
*/
trustedProxies?: string | string[];
/**
* Allowed origin for referer that match
* any of this regexp
*
* {@link OriginFilter}
*/
csrfOrigins?: string[];
/**
* Allow you to authorize one or several websites
* If you use "*" then the API is open to direct call and any origins
* You can also serve one static website by having a
*
* {@link WebsiteOriginFilter}
*/
website?: string | string[];
/**
* Serve statically a website
*/
static?: StaticWebsite;
/**
* Read from the configuration service before init
*/
configurationService?: string;
/**
* Define the api url
*/
apiUrl?: string;
/**
* Will not try to parse request bigger than this
*
* This parameter can be overriden by a direct call to
* getHttpContext().getRawBody(xxx)
*
* @default 10Mb
*/
requestLimit?: number;
/**
* Will not take more than this to read a request (unit: milliseconds)
*
* This parameter can be overriden by a direct call to
* getHttpContext().getRawBody(undefined, xxx)
*
* @default 60000
*/
requestTimeout?: number;
/**
* Define the default store
*/
defaultStore?: string;
/**
* Define metrics
*/
metrics?: false | {
labels?: {
[key: string]: string;
};
config?: {
[key: string]: any;
};
prefix?: string;
};
/**
* Allow any other type of parameters
*/
[key: string]: any;
};
/**
* OpenAPI override
*/
openapi?: Partial<OpenAPIV3.Document>;
/**
* Include other configuration.json
*
* This allow you so share Store definition or parameters between different components
* The configuration is merged with `deepmerge(...imports, local)`
*/
imports?: string[];
};
export type Configuration = UnpackedConfiguration & {
/**
* Cached modules to avoid scanning node_modules
* This is used by packagers
*/
cachedModules?: CachedModule;
};
export type StoredConfiguration = Configuration;
/**
* Return the gather information from the repository
* @mermaid Make TypeDoc easy to use with mermaid.js
* graph TB
* mermaid.js --> TypeDoc;
*/
export interface GitInformation {
/**
* Current commit reference
*
* `git rev-parse HEAD`
*/
commit: string;
/**
* Current branch
*
* `git symbolic-ref --short HEAD`
*/
branch: string;
/**
* Current commit short reference
*
* `git rev-parse --short HEAD`
*/
short: string;
/**
* Current tag name that match the package version
*/
tag: string;
/**
* Return all tags that point to the current HEAD
*
* `git tag --points-at HEAD`
*/
tags: string[];
/**
* Current version as return by package.json with auto snapshot
*
* If the version return by package is not in the current `tags`, the version is
* incremented to the next patch version with a +{date}
*
* Example:
*
* with package.json version = "1.1.0" name = "mypackage"
* if a tag "v1.1.0" or "mypackage@1.1.0" then version = "1.1.0"
* else version = "1.1.1+20201110163014178"
*/
version: string;
}
/**
* Helper to define a ServiceContrustor
*/
export interface ServiceConstructor<T extends Service> {
new (webda: Core, name: string, params: any): T;
}
export declare enum SectionEnum {
Moddas = "moddas",
Deployers = "deployers",
Beans = "beans"
}
/**
* Webda specific metadata for the project
*/
export interface WebdaPackageDescriptor {
/**
* Webda namespace
*/
namespace?: string;
/**
* Logo to display within the shell tty
*/
logo?: string;
/**
* Service to replace default launcher
*/
launcher?: {
/**
* Service to use for launch
*/
service: string;
/**
* Method to use
*/
method: string;
};
/**
* Information on the workspace
*/
workspaces?: {
packages: string[];
parent: PackageDescriptor;
path: string;
};
[key: string]: any;
}
/**
* Information on the whole project
*/
export interface ProjectInformation {
/**
* package.json information
*/
package: PackageDescriptor;
/**
* Webda project information
*
* It is the aggregation of webda information contained in package
* and its workspace meta
*/
webda: WebdaPackageDescriptor;
/**
* Git information gathered
*/
git: GitInformation;
/**
* Deployment information
*/
deployment: {
name: string;
[key: string]: any;
};
}
/**
* Type of Section
*/
export type Section = "moddas" | "deployers" | "models" | "beans";
/**
* Map a Webda Application
*
* It allows to:
* - Analyse imported modules
* - Scan code for Modda and generate the webda.config.json
* - Compile and Watch
* - Migrate from old configuration
* - List deployments
*
*
* @category CoreFeatures
*/
export declare class Application {
/**
* Get Application root path
*/
readonly appPath: string;
/**
* Base configuration loaded from webda.config.json
*/
protected baseConfiguration: Configuration;
/**
* Current deployment
*/
protected currentDeployment: string;
/**
* Contains definitions of current application
*/
protected appModule: Module;
/**
* Contains already loaded modules
*/
protected _loaded: string[];
/**
* Deployers type registry
*/
protected deployers: {
[key: string]: any;
};
/**
* Moddas registry
*/
protected moddas: {
[key: string]: Modda;
};
/**
* Models type registry
*/
protected models: {
[key: string]: CoreModelDefinition;
};
/**
* Models graph
*/
protected graph: ModelsGraph;
/**
* Models specific plurals
*/
protected plurals: {
[key: string]: string;
};
/**
* Class Logger
*/
protected logger: WorkerOutput;
/**
* Detect if running as workspace
*/
protected workspacesPath: string;
/**
* When the application got initiated
*/
protected initTime: number;
/**
* Direct parent of a model
*/
protected flatHierarchy: {
[key: string]: string;
};
/**
* Configuration file
*/
readonly configurationFile: string;
/**
* Current deployment file
*/
deploymentFile: string;
/**
* Current application
*/
protected static active: Application;
/**
*
* @param {string} fileOrFolder to load Webda Application from
* @param {Logger} logger
*/
constructor(file: string, logger?: WorkerOutput);
/**
* Import all required modules
*/
load(): Promise<this>;
/**
* Allow subclass to implement migration
*
* @param file
* @returns
*/
loadConfiguration(file: string): void;
/**
*
* @param proto Prototype to send
*/
getFullNameFromPrototype(proto: any): string;
/**
* Get a schema from a type
*
* Schema should be precomputed in the default app
* @param type
* @returns
*/
getSchema(type: string): JSONSchema7;
/**
* Get schemas
* @returns
*/
getSchemas(): {
[key: string]: JSONSchema7;
};
/**
* Check if a schema exists
* @param type
* @returns schema name if it exists
*/
hasSchema(type: string): boolean;
/**
* Get model graph
*/
getRelations(model: string | Constructor<CoreModel> | CoreModel): ModelGraph;
/**
* Get the all graph
* @returns
*/
getGraph(): ModelsGraph;
/**
* Check if application has cached modules
*
* When deployed the application contains cachedModules in the `webda.config.json`
* It allows to avoid the search for `webda.module.json` inside node_modules and
* take the schema from the cached modules also
*/
isCached(): boolean;
/**
* Retrieve specific webda conf from package.json
*
* In case of workspaces the object is combined
*/
getPackageWebda(): WebdaPackageDescriptor;
/**
* Retrieve content of package.json
*/
getPackageDescription(): PackageDescriptor;
/**
* Log information
*
* @param level to log for
* @param args anything to display same as console.log
*/
log(level: WorkerLogLevel, ...args: any[]): void;
/**
* Get current logger
*/
getWorkerOutput(): WorkerOutput;
/**
* Return the current app path
*
* @param subpath to append to
*/
getAppPath(subpath?: string): string;
/**
* Add a new service
*
* @param name
* @param service
*/
addService(name: string, service: Modda): this;
/**
* Register a new schema in the application
* @param name
* @param schema
*/
registerSchema(name: string, schema: JSONSchema7): void;
/**
* Get plural of an Id
* @param name
* @returns
*/
getModelPlural(name: string): string;
/**
*
* @param section
* @param name
* @param caseSensitive
*/
hasWebdaObject(section: Section, name: string, caseSensitive?: boolean): boolean;
/**
*
* @param section
* @param name
* @returns
*/
getWebdaObject(section: Section, name: string, caseSensitive?: boolean): any;
/**
* Get a service based on name
*
* @param name
*/
getModda(name: any): Modda;
/**
* Return all services of the application
*/
getModdas(): {
[key: string]: Modda;
};
/**
* Return all beans of the application
*/
getBeans(): {
[key: string]: string;
};
/**
* Retrieve the model implementation
*
* @param name model to retrieve
*/
getModel<T extends CoreModel = CoreModel>(name: string): CoreModelDefinition<T>;
/**
* Get all models definitions
*/
getModels(): {
[key: string]: CoreModelDefinition;
};
/**
* Return models that do not have parents
* @returns
*/
getRootModels(): string[];
/**
* Return models that do not have parents and are exposed
* Or specifically set as root via the Expose.root parameter
* @returns
*/
getRootExposedModels(): string[];
/**
* Return the model name for a object
* @param object
*/
getModelFromInstance(object: CoreModel): string | undefined;
/**
* Return the model name for a object
* @param object
*/
getModelFromConstructor(model: Constructor<CoreModel>): string | undefined;
/**
* Get the model name from a model or a constructor
*
* @param model
* @returns longId for a model
*/
getModelName(model: CoreModel | Constructor<CoreModel>): string | undefined;
/**
* Get the model hierarchy
* @param model
*/
getModelHierarchy(model: CoreModel | Constructor<CoreModel> | string): {
ancestors: string[];
children: ModelsTree;
};
/**
* Get all model types with the hierarchy
* @param model
* @returns
*/
getModelTypes(model: CoreModel): string[];
/**
* Return all deployers
*/
getDeployers(): {
[key: string]: Modda;
};
/**
* Add a new model
*
* @param name
* @param model
*/
addModel(name: string, model: any, dynamic?: boolean): this;
/**
* Add a new deployer
*
* @param name
* @param model
*/
addDeployer(name: string, model: any): this;
/**
* Return webda current version
*
* @returns package version
* @since 0.4.0
*/
getWebdaVersion(): string;
/**
* Retrieve Git Repository information
*
* {@link GitInformation} for more details on how the information is gathered
* @return the git information
*/
getGitInformation(_packageName?: string, _version?: string): GitInformation;
/**
* Allow variable inside of string
*
* @param templateString to copy
* @param replacements additional replacements to run
*/
protected stringParameter(templateString: string, replacements?: any): any;
/**
* Allow variable inside object strings
*
* Example
* ```js
* replaceVariables({
* myobj: "${test.replace}"
* }, {
* test: {
* replace: 'plop'
* }
* })
* ```
* will return
* ```
* {
* myobj: 'plop'
* }
* ```
*
* By default the replacements map contains
* ```
* {
* git: GitInformation,
* package: 'package.json content',
* deployment: string,
* now: number,
* ...replacements
* }
* ```
*
* See: {@link GitInformation}
*
* @param object a duplicated object with replacement done
* @param replacements additional replacements to run
*/
replaceVariables(object: any, replacements?: any): any;
/**
* Get current deployment name
*/
getCurrentDeployment(): string;
/**
* Return all application modules merged as one
*
* Used when deployed
* @returns
*/
getModules(): CachedModule;
/**
* Get application configuration
* @returns
*/
getConfiguration(_deployment?: string): Configuration;
/**
* Return current Configuration of the Application
*
* Same as calling
*
* ```js
* getConfiguration(this.currentDeployment);
* ```
*/
getCurrentConfiguration(): Configuration;
/**
* Import a file
*
* If the `default` is set take this or use old format
*
* @param info
*/
importFile(info: string, withExport?: boolean): Promise<any>;
/**
* Load local module
*/
loadLocalModule(): Promise<void>;
/**
* Load the module,
*
* @protected
* @ignore Useless for documentation
*/
loadModule(module: Module, parent?: string): Promise<void>;
/**
* Return the full name including namespace
*
* In Webda the ServiceType include namespace `Webda/Store` or `Webda/Test`
* This method will make sure the namespace is present, adding it if no '/'
* is found in the name
*
* @param name
*/
completeNamespace(name?: string): string;
/**
* Return current namespace
* @returns
*/
getNamespace(): string;
/**
* Get short id for a name
* @param name if name is shortId return longId else return shortId
* @returns
*/
getShortId(name: string): string;
}