@declaro/core 2.0.0-beta.9 → 2.0.0-y.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/app-context.d.ts +8 -0
- package/dist/app/app-lifecycle.d.ts +4 -0
- package/dist/app/app.d.ts +22 -0
- package/dist/app/index.d.ts +3 -20
- package/dist/auth/permission-validator.d.ts +34 -0
- package/dist/auth/permission-validator.test.d.ts +1 -0
- package/dist/context/context.d.ts +88 -13
- package/dist/context/legacy-context.test.d.ts +1 -0
- package/dist/errors/errors.d.ts +36 -0
- package/dist/events/event-manager.d.ts +11 -6
- package/dist/http/headers.d.ts +4 -0
- package/dist/http/headers.spec.d.ts +1 -0
- package/dist/http/request-context.d.ts +12 -0
- package/dist/http/request-context.spec.d.ts +1 -0
- package/dist/http/request.d.ts +8 -0
- package/dist/http/request.spec.d.ts +1 -0
- package/dist/http/url.d.ts +8 -0
- package/dist/http/url.spec.d.ts +1 -0
- package/dist/index.d.ts +9 -3
- package/dist/pkg.cjs +30 -2
- package/dist/pkg.mjs +56461 -207
- package/dist/schema/application.d.ts +83 -0
- package/dist/schema/application.test.d.ts +1 -0
- package/dist/schema/define-model.d.ts +7 -4
- package/dist/schema/index.d.ts +7 -0
- package/dist/schema/labels.d.ts +13 -0
- package/dist/schema/labels.test.d.ts +1 -0
- package/dist/schema/module.d.ts +7 -0
- package/dist/schema/module.test.d.ts +1 -0
- package/dist/schema/properties.d.ts +19 -0
- package/dist/schema/response.d.ts +31 -0
- package/dist/schema/response.test.d.ts +1 -0
- package/dist/schema/transform-model.d.ts +1 -1
- package/dist/schema/types.d.ts +81 -15
- package/dist/schema/types.test.d.ts +1 -0
- package/dist/typescript/constant-manipulation/snake-case.d.ts +22 -0
- package/dist/typescript/index.d.ts +1 -0
- package/dist/typescript/objects.d.ts +6 -0
- package/package.json +8 -3
- package/src/app/app-context.ts +14 -0
- package/src/app/app-lifecycle.ts +14 -0
- package/src/app/app.ts +45 -0
- package/src/app/index.ts +3 -34
- package/src/auth/permission-validator.test.ts +209 -0
- package/src/auth/permission-validator.ts +135 -0
- package/src/context/context.test.ts +585 -94
- package/src/context/context.ts +348 -32
- package/src/context/legacy-context.test.ts +141 -0
- package/src/errors/errors.ts +73 -0
- package/src/events/event-manager.spec.ts +54 -8
- package/src/events/event-manager.ts +40 -24
- package/src/http/headers.spec.ts +48 -0
- package/src/http/headers.ts +16 -0
- package/src/http/request-context.spec.ts +39 -0
- package/src/http/request-context.ts +43 -0
- package/src/http/request.spec.ts +52 -0
- package/src/http/request.ts +22 -0
- package/src/http/url.spec.ts +87 -0
- package/src/http/url.ts +48 -0
- package/src/index.ts +9 -3
- package/src/schema/application.test.ts +286 -0
- package/src/schema/application.ts +150 -0
- package/src/schema/define-model.test.ts +48 -2
- package/src/schema/define-model.ts +40 -9
- package/src/schema/index.ts +7 -0
- package/src/schema/labels.test.ts +60 -0
- package/src/schema/labels.ts +30 -0
- package/src/schema/module.test.ts +39 -0
- package/src/schema/module.ts +6 -0
- package/src/schema/properties.ts +40 -0
- package/src/schema/response.test.ts +101 -0
- package/src/schema/response.ts +93 -0
- package/src/schema/transform-model.ts +1 -1
- package/src/schema/types.test.ts +28 -0
- package/src/schema/types.ts +135 -15
- package/src/typescript/constant-manipulation/snake-case.md +496 -0
- package/src/typescript/constant-manipulation/snake-case.ts +76 -0
- package/src/typescript/index.ts +1 -0
- package/src/typescript/objects.ts +8 -5
- package/tsconfig.json +4 -1
- package/dist/context/index.d.ts +0 -3
- package/dist/interfaces/IDatastoreProvider.d.ts +0 -16
- package/dist/interfaces/IStore.d.ts +0 -4
- package/dist/interfaces/index.d.ts +0 -2
- package/dist/server/index.d.ts +0 -2
- package/src/context/index.ts +0 -3
- package/src/interfaces/IDatastoreProvider.ts +0 -23
- package/src/interfaces/IStore.ts +0 -4
- package/src/interfaces/index.ts +0 -2
- package/src/server/index.ts +0 -3
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Model } from './define-model';
|
|
2
|
+
import { Module } from './module';
|
|
3
|
+
import { DeclaroSchema } from './types';
|
|
4
|
+
import { Response } from './response';
|
|
5
|
+
export type ModuleFactory = (mod: Module) => Module | undefined;
|
|
6
|
+
export declare class Application {
|
|
7
|
+
private _info;
|
|
8
|
+
private _modules;
|
|
9
|
+
private _models;
|
|
10
|
+
private _responses;
|
|
11
|
+
constructor(info: DeclaroSchema.InfoObject);
|
|
12
|
+
/**
|
|
13
|
+
* Get the application info (read-only). Application info can only be set in the constructor of the application.
|
|
14
|
+
*
|
|
15
|
+
* Note: This should be set by the application implementation. It would be dangerous for any one module to be able to change the application info for all of the others.
|
|
16
|
+
*/
|
|
17
|
+
get info(): import("openapi-types").OpenAPIV3_1.InfoObject;
|
|
18
|
+
/**
|
|
19
|
+
* Define a module for the application.
|
|
20
|
+
*
|
|
21
|
+
* @param tag The tag info for the module, to be used in the OpenAPI schema
|
|
22
|
+
* @param factory A convenience function to define the module, adding endpoints, etc.
|
|
23
|
+
* @returns
|
|
24
|
+
*/
|
|
25
|
+
defineModule(tag: DeclaroSchema.TagObject, factory?: ModuleFactory): Module;
|
|
26
|
+
/**
|
|
27
|
+
* Get a module by name.
|
|
28
|
+
*
|
|
29
|
+
* @param name The name of the module to get
|
|
30
|
+
* @returns The `Module` instance for the given name
|
|
31
|
+
*/
|
|
32
|
+
getModule(name: string): Module;
|
|
33
|
+
/**
|
|
34
|
+
* Add models to the application.
|
|
35
|
+
*
|
|
36
|
+
* @param models The models to add to the application
|
|
37
|
+
* @example app.addModel(User)
|
|
38
|
+
* @example app.addModel(User, Post)
|
|
39
|
+
* @example app.addModel(...myModels)
|
|
40
|
+
* @returns The application instance
|
|
41
|
+
*/
|
|
42
|
+
addModel(...models: Model[]): this;
|
|
43
|
+
/**
|
|
44
|
+
* Get a model by name.
|
|
45
|
+
*
|
|
46
|
+
* @param name The name of the model to get
|
|
47
|
+
* @returns The `Model` instance for the given name
|
|
48
|
+
*/
|
|
49
|
+
getModel(name: string): Model;
|
|
50
|
+
/**
|
|
51
|
+
* Get all models.
|
|
52
|
+
*
|
|
53
|
+
* @returns All models in the application
|
|
54
|
+
*/
|
|
55
|
+
getModels(): Model[];
|
|
56
|
+
/**
|
|
57
|
+
* Add a response to the application.
|
|
58
|
+
*
|
|
59
|
+
* @param code The HTTP status code for the response
|
|
60
|
+
* @param response The response object
|
|
61
|
+
* @returns The application instance
|
|
62
|
+
*/
|
|
63
|
+
addResponse(...responses: Response[]): this;
|
|
64
|
+
/**
|
|
65
|
+
* Get a response by status code.
|
|
66
|
+
*
|
|
67
|
+
* @param code The HTTP status code for the response
|
|
68
|
+
* @returns The `Response` instance for the given status code
|
|
69
|
+
*/
|
|
70
|
+
getResponse(code: number): Response;
|
|
71
|
+
/**
|
|
72
|
+
* Get all responses. (read-only)
|
|
73
|
+
*
|
|
74
|
+
* @returns All responses in the application
|
|
75
|
+
*/
|
|
76
|
+
get responses(): Map<number, Response>;
|
|
77
|
+
/**
|
|
78
|
+
* Get all responses as a hash of keys and values.
|
|
79
|
+
*
|
|
80
|
+
* @returns A hash of keys and values representing all responses in the application
|
|
81
|
+
*/
|
|
82
|
+
getResponseSchema(): DeclaroSchema.ResponsesObject;
|
|
83
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { DeclaroSchema } from './types';
|
|
2
|
-
export type Model = {
|
|
3
|
-
name:
|
|
4
|
-
schema: DeclaroSchema.SchemaObject
|
|
2
|
+
export type Model<T extends DeclaroSchema.AnyObjectProperties = DeclaroSchema.AnyObjectProperties, N extends Readonly<string> = string> = {
|
|
3
|
+
name: N;
|
|
4
|
+
schema: DeclaroSchema.SchemaObject<T>;
|
|
5
5
|
isModel: true;
|
|
6
6
|
};
|
|
7
|
-
export
|
|
7
|
+
export type ModelName<T extends Model<any, string>> = T['name'];
|
|
8
|
+
export type ModelProperties<T extends Model<any, string>> = T['schema']['properties'];
|
|
9
|
+
export declare function initializeModel(schema: DeclaroSchema.SchemaObject<any>): DeclaroSchema.SchemaObject<any, string>;
|
|
10
|
+
export declare function defineModel<T extends DeclaroSchema.AnyObjectProperties, N extends Readonly<string>>(name: N, doc: DeclaroSchema.SchemaObject<T>): Model<T, N>;
|
package/dist/schema/index.d.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
1
|
export * from './define-model';
|
|
2
2
|
export * from './supported-types';
|
|
3
3
|
export * from './transform-model';
|
|
4
|
+
export * from './labels';
|
|
5
|
+
export * from './module';
|
|
6
|
+
export * from './application';
|
|
7
|
+
export * from './response';
|
|
8
|
+
export * from './formats';
|
|
9
|
+
export * from './properties';
|
|
10
|
+
export * from './types';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type EntityLabels = {
|
|
2
|
+
singularLabel?: string;
|
|
3
|
+
pluralLabel?: string;
|
|
4
|
+
singularParameter?: string;
|
|
5
|
+
pluralParameter?: string;
|
|
6
|
+
singularSlug?: string;
|
|
7
|
+
pluralSlug?: string;
|
|
8
|
+
singularEntityName?: string;
|
|
9
|
+
pluralEntityName?: string;
|
|
10
|
+
singularTableName?: string;
|
|
11
|
+
pluralTableName?: string;
|
|
12
|
+
};
|
|
13
|
+
export declare function getEntityLabels(entity: string, labels?: Partial<EntityLabels>): EntityLabels;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Application } from './application';
|
|
2
|
+
import { DeclaroSchema } from './types';
|
|
3
|
+
export declare class Module {
|
|
4
|
+
readonly application: Application;
|
|
5
|
+
readonly tag: DeclaroSchema.TagObject;
|
|
6
|
+
constructor(application: Application, tag: DeclaroSchema.TagObject);
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { DeclaroSchema } from './types';
|
|
2
|
+
export declare const t: {
|
|
3
|
+
string: <T extends DeclaroSchema.NonArraySchemaObject<any, any>>(property?: T) => T & {
|
|
4
|
+
type: "string";
|
|
5
|
+
};
|
|
6
|
+
number: <T extends DeclaroSchema.NonArraySchemaObject<any, any>>(property?: T) => T & {
|
|
7
|
+
type: "number";
|
|
8
|
+
};
|
|
9
|
+
boolean: <T extends DeclaroSchema.NonArraySchemaObject<any, any>>(property?: T) => T & {
|
|
10
|
+
type: "boolean";
|
|
11
|
+
};
|
|
12
|
+
integer: <T extends DeclaroSchema.NonArraySchemaObject<any, any>>(property?: T) => T & {
|
|
13
|
+
type: "integer";
|
|
14
|
+
};
|
|
15
|
+
object: <T extends DeclaroSchema.NonArraySchemaObject<any, any>>(property?: T) => T & {
|
|
16
|
+
type: "object";
|
|
17
|
+
};
|
|
18
|
+
array: <T extends DeclaroSchema.NonArraySchemaObject<any, any>>(property?: T) => never;
|
|
19
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { DeclaroSchema } from './types';
|
|
2
|
+
export type MediaRecord<T extends DeclaroSchema.AnyObjectProperties> = {
|
|
3
|
+
contentType: string;
|
|
4
|
+
media: DeclaroSchema.MediaTypeObject<T>;
|
|
5
|
+
};
|
|
6
|
+
export declare class Response {
|
|
7
|
+
private _code;
|
|
8
|
+
private _response;
|
|
9
|
+
private _mediaTypes;
|
|
10
|
+
constructor(code: number, response: DeclaroSchema.ResponseObject);
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
* @param contentType The HTTP content type
|
|
14
|
+
* @param media The openapi media schema defining the response type.
|
|
15
|
+
* @returns An instance of the response object for chaining content types.
|
|
16
|
+
*/
|
|
17
|
+
content(contentType: string, ...media: DeclaroSchema.MediaTypeObject<any>[]): this;
|
|
18
|
+
merge(response: Response): this;
|
|
19
|
+
/**
|
|
20
|
+
* The response code.
|
|
21
|
+
*
|
|
22
|
+
* Note: Read-only. This can only be initialized in the constructor.
|
|
23
|
+
*/
|
|
24
|
+
get code(): number;
|
|
25
|
+
/**
|
|
26
|
+
* The fully composed openapi response object.
|
|
27
|
+
*/
|
|
28
|
+
get schema(): DeclaroSchema.ResponseObject;
|
|
29
|
+
protected getContentTypes(): string[];
|
|
30
|
+
protected getMediaForContentType(contentType: string): DeclaroSchema.MediaTypeObject<any>[];
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/schema/types.d.ts
CHANGED
|
@@ -1,29 +1,95 @@
|
|
|
1
1
|
import { OpenAPIV3_1 } from 'openapi-types';
|
|
2
2
|
import { ModelNames } from '$models/reference';
|
|
3
|
+
import { EntityLabels } from './labels';
|
|
3
4
|
export declare namespace DeclaroSchema {
|
|
5
|
+
type Modify<T, R> = Omit<T, keyof R> & R;
|
|
4
6
|
type NonArraySchemaObjectType = OpenAPIV3_1.NonArraySchemaObjectType;
|
|
5
7
|
type ArraySchemaObjectType = OpenAPIV3_1.ArraySchemaObjectType;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
type AnySchemaObjectType = NonArraySchemaObjectType | ArraySchemaObjectType;
|
|
9
|
+
type AnyObjectProperties = {
|
|
10
|
+
[name: string]: SchemaObject<any> | ReferenceObject;
|
|
11
|
+
};
|
|
12
|
+
type AnyObjectParameters = {
|
|
13
|
+
[name: string]: Omit<DeclaroSchema.ParameterObject, 'name'>;
|
|
14
|
+
};
|
|
15
|
+
interface BaseSchemaObject<T extends AnyObjectProperties, N extends ModelNames = ModelNames> extends OpenAPIV3_1.BaseSchemaObject {
|
|
16
|
+
$schema?: N;
|
|
17
|
+
propertyName?: string;
|
|
18
|
+
additionalProperties?: boolean | ReferenceObject | SchemaObject<T>;
|
|
19
|
+
properties?: T;
|
|
20
|
+
labels?: EntityLabels;
|
|
21
|
+
not?: ReferenceObject | SchemaObject<T>;
|
|
22
|
+
allOf?: (ReferenceObject | SchemaObject<T>)[];
|
|
23
|
+
anyOf?: (ReferenceObject | SchemaObject<T>)[];
|
|
24
|
+
oneOf?: (ReferenceObject | SchemaObject<T>)[];
|
|
16
25
|
}
|
|
17
|
-
interface NonArraySchemaObject extends BaseSchemaObject {
|
|
26
|
+
interface NonArraySchemaObject<T extends AnyObjectProperties, N extends ModelNames> extends BaseSchemaObject<T, N> {
|
|
18
27
|
type?: NonArraySchemaObjectType;
|
|
28
|
+
labels?: EntityLabels;
|
|
19
29
|
}
|
|
20
|
-
interface ArraySchemaObject extends BaseSchemaObject {
|
|
30
|
+
interface ArraySchemaObject<T extends AnyObjectProperties, N extends ModelNames> extends BaseSchemaObject<T> {
|
|
21
31
|
type: ArraySchemaObjectType;
|
|
22
|
-
items: ReferenceObject | SchemaObject
|
|
32
|
+
items: ReferenceObject | SchemaObject<T, N>;
|
|
23
33
|
}
|
|
24
|
-
type SchemaObject = ArraySchemaObject | NonArraySchemaObject
|
|
34
|
+
type SchemaObject<T extends AnyObjectProperties, N extends string = string> = ArraySchemaObject<T, N> | NonArraySchemaObject<T, N>;
|
|
35
|
+
type PropertyType<T extends SchemaObject<any>> = T['type'] extends 'string' ? string : T['type'] extends 'boolean' ? boolean : T['type'] extends 'number' ? number : T['type'] extends 'integer' ? number : T['type'] extends 'object' ? ObjectPayload<T['properties']> : T['type'] extends 'array' ? ObjectPayload<T['properties']>[] : any;
|
|
36
|
+
type OperationInput<T extends AnyObjectParameters> = {
|
|
37
|
+
[K in keyof T]: PropertyType<T[K]['schema']>;
|
|
38
|
+
};
|
|
39
|
+
type ObjectPayload<T extends AnyObjectProperties> = {
|
|
40
|
+
[K in keyof T]: PropertyType<T[K]>;
|
|
41
|
+
};
|
|
42
|
+
type Payload<T extends AnyObjectProperties, TSchema extends SchemaObject<T>> = any;
|
|
25
43
|
interface ReferenceObject {
|
|
26
44
|
$ref: ModelNames;
|
|
27
|
-
format
|
|
45
|
+
format?: string;
|
|
28
46
|
}
|
|
47
|
+
type InfoObject = OpenAPIV3_1.InfoObject;
|
|
48
|
+
type TagObject = OpenAPIV3_1.TagObject;
|
|
49
|
+
type ExampleObject = OpenAPIV3_1.ExampleObject;
|
|
50
|
+
type MediaTypeObject<T extends AnyObjectProperties> = Modify<OpenAPIV3_1.MediaTypeObject, {
|
|
51
|
+
schema?: SchemaObject<T> | ReferenceObject;
|
|
52
|
+
examples?: Record<string, ReferenceObject | ExampleObject>;
|
|
53
|
+
}>;
|
|
54
|
+
type ServerObject = OpenAPIV3_1.ServerObject;
|
|
55
|
+
type LinkObject = Modify<OpenAPIV3_1.LinkObject, {
|
|
56
|
+
server?: ServerObject;
|
|
57
|
+
}>;
|
|
58
|
+
type ResponseObject = Modify<OpenAPIV3_1.ResponseObject, {
|
|
59
|
+
headers?: {
|
|
60
|
+
[header: string]: ReferenceObject | HeaderObject;
|
|
61
|
+
};
|
|
62
|
+
content?: {
|
|
63
|
+
[media: string]: MediaTypeObject<any>;
|
|
64
|
+
};
|
|
65
|
+
links?: {
|
|
66
|
+
[link: string]: ReferenceObject | LinkObject;
|
|
67
|
+
};
|
|
68
|
+
}>;
|
|
69
|
+
type ResponsesObject = OpenAPIV3_1.ResponsesObject;
|
|
70
|
+
type HeaderObject = OpenAPIV3_1.HeaderObject;
|
|
71
|
+
type HttpMethods = OpenAPIV3_1.HttpMethods;
|
|
72
|
+
type ParameterObject = Modify<OpenAPIV3_1.ParameterObject, {
|
|
73
|
+
in: 'query' | 'header' | 'path' | 'cookie';
|
|
74
|
+
schema?: SchemaObject<any> | ReferenceObject;
|
|
75
|
+
}>;
|
|
76
|
+
type RequestBodyObject<T extends AnyObjectProperties> = Modify<OpenAPIV3_1.RequestBodyObject, {
|
|
77
|
+
content: {
|
|
78
|
+
[media: string]: MediaTypeObject<T>;
|
|
79
|
+
};
|
|
80
|
+
}>;
|
|
81
|
+
type CallbackObject = Record<string, PathItemObject | ReferenceObject>;
|
|
82
|
+
type PathItemObject<T extends {} = {}> = Modify<OpenAPIV3_1.PathItemObject<T>, {
|
|
83
|
+
servers?: ServerObject[];
|
|
84
|
+
parameters?: (ReferenceObject | ParameterObject)[];
|
|
85
|
+
}> & {
|
|
86
|
+
[method in HttpMethods]?: OperationObject<T>;
|
|
87
|
+
};
|
|
88
|
+
type OperationObject<T extends {} = {}> = Modify<OpenAPIV3_1.OperationObject<T>, {
|
|
89
|
+
parameters?: ParameterObject[];
|
|
90
|
+
requestBody?: ReferenceObject | RequestBodyObject<T>;
|
|
91
|
+
responses?: ResponsesObject;
|
|
92
|
+
callbacks?: Record<string, ReferenceObject | CallbackObject>;
|
|
93
|
+
servers?: ServerObject[];
|
|
94
|
+
}> & T;
|
|
29
95
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This util converts typescript constants to snake case.
|
|
3
|
+
*
|
|
4
|
+
* Why would anyone do this to themselves? Because now we can take constants defined in one place in one case (i.e. a data type called "User") and we can automatically infer strongly typed dirivative types (i.e. snake case table name) without needing to generate code.
|
|
5
|
+
*
|
|
6
|
+
* Limitations:
|
|
7
|
+
* - This utility is designed to work with typescript constants, not arbitrary strings.
|
|
8
|
+
* - This utility supports only the English alphabet, numerals, and a few special characters (-_ ).
|
|
9
|
+
*
|
|
10
|
+
* Note: This was built with the help of AI (Github Copilot). See adjacent md file for info.
|
|
11
|
+
*
|
|
12
|
+
*/
|
|
13
|
+
type LowercaseLetters = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z';
|
|
14
|
+
type Numerals = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
|
|
15
|
+
type UppercaseLetters = Uppercase<LowercaseLetters>;
|
|
16
|
+
type AllowedSpecialCharacters = ' ' | '_' | '-';
|
|
17
|
+
type Replace<S extends string, From extends string, To extends string> = S extends '' ? '' : S extends `${infer P}${From}${infer R}` ? `${P}${To}${Replace<R, From, To>}` : S;
|
|
18
|
+
type Trim<S extends string> = S extends `${AllowedSpecialCharacters}${infer T}` ? Trim<T> : S extends `${infer T}${AllowedSpecialCharacters}` ? Trim<T> : S;
|
|
19
|
+
type CamelToSnakeCase<S extends string, Acc extends string = ''> = S extends `${infer L}${infer R}` ? L extends LowercaseLetters ? `${Acc}${L}` extends `${infer T}${UppercaseLetters}` | `${infer T}${Numerals}` ? CamelToSnakeCase<R, `${T}_${Lowercase<L>}`> : CamelToSnakeCase<R, `${Acc}${L}`> : L extends UppercaseLetters ? CamelToSnakeCase<R, `${Acc}_${Lowercase<L>}`> : L extends Numerals ? `${Acc}` extends `${infer T}${LowercaseLetters}` ? CamelToSnakeCase<R, `${Acc}_${L}`> : `${Acc}${L}` extends `${infer T}${Numerals}` ? CamelToSnakeCase<R, `${T}${L}`> : CamelToSnakeCase<R, `${Acc}_${L}`> : CamelToSnakeCase<R, Acc> : Acc;
|
|
20
|
+
type Normalize<S extends string> = Lowercase<Trim<Replace<Replace<Replace<S, ' ', '_'>, '-', '_'>, '__', '_'>>>;
|
|
21
|
+
export type SnakeCase<S extends string> = Normalize<CamelToSnakeCase<S>>;
|
|
22
|
+
export {};
|
|
@@ -4,3 +4,9 @@ export default _default;
|
|
|
4
4
|
export type DeepPartial<T> = T extends object ? {
|
|
5
5
|
[P in keyof T]?: DeepPartial<T[P]>;
|
|
6
6
|
} : T;
|
|
7
|
+
/**
|
|
8
|
+
* Merge two object types without using an intersection type. Intersection types preserve the original types of the objects causing confusion, while this type will merge the types of the objects.
|
|
9
|
+
*/
|
|
10
|
+
export type Merge<A, B> = {
|
|
11
|
+
[key in keyof A | keyof B]: key extends keyof B ? B[key] : key extends keyof A ? A[key] : never;
|
|
12
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@declaro/core",
|
|
3
|
-
"version": "2.0.0-
|
|
3
|
+
"version": "2.0.0-y.0",
|
|
4
4
|
"description": "Declarative Business Module Definition",
|
|
5
5
|
"main": "dist/pkg.cjs",
|
|
6
6
|
"module": "dist/pkg.mjs",
|
|
@@ -18,13 +18,18 @@
|
|
|
18
18
|
"test": "vitest"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
|
+
"@types/whatwg-url": "^13.0.0",
|
|
21
22
|
"@vitest/coverage-v8": "^2.0.5",
|
|
22
23
|
"json-schema-library": "^7.4.8",
|
|
24
|
+
"lodash": "^4.17.21",
|
|
25
|
+
"minimatch": "^10.0.1",
|
|
26
|
+
"node-mocks-http": "^1.16.2",
|
|
23
27
|
"openapi-types": "^12.1.3",
|
|
24
28
|
"typescript": "^5.5.4",
|
|
25
29
|
"vite": "^5.4.1",
|
|
26
30
|
"vite-plugin-dts": "^4.0.3",
|
|
27
|
-
"vitest": "^2.0.5"
|
|
31
|
+
"vitest": "^2.0.5",
|
|
32
|
+
"whatwg-url": "^14.1.1"
|
|
28
33
|
},
|
|
29
34
|
"dependencies": {
|
|
30
35
|
"change-case": "^4.1.2",
|
|
@@ -38,5 +43,5 @@
|
|
|
38
43
|
"url": "https://github.com/emmertio/declaro/issues"
|
|
39
44
|
},
|
|
40
45
|
"homepage": "https://github.com/emmertio/declaro/tree/main#readme",
|
|
41
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "639b567b4f8adfb9da9c3005c3b0ac0aca10c0e6"
|
|
42
47
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useHeader } from '../http/headers'
|
|
2
|
+
import { Context } from '../context/context'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Get the name of the app making the current request via header x-app. (returns "default" when no app was provided).
|
|
6
|
+
*
|
|
7
|
+
* @param context
|
|
8
|
+
* @returns the name of the app in a string.
|
|
9
|
+
*/
|
|
10
|
+
export function useApp(context: Context) {
|
|
11
|
+
const appHeader = useHeader(context, 'x-app') as string
|
|
12
|
+
|
|
13
|
+
return appHeader ?? 'default'
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Context, type ContextListener } from '../context/context'
|
|
2
|
+
import { App } from './app'
|
|
3
|
+
|
|
4
|
+
export function onInit(context: Context, listener: ContextListener) {
|
|
5
|
+
context.on(App.Events.Init, listener)
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export function onStart(context: Context, listener: ContextListener) {
|
|
9
|
+
context.on(App.Events.Start, listener)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function onDestroy(context: Context, listener: ContextListener) {
|
|
13
|
+
context.on(App.Events.Destroy, listener)
|
|
14
|
+
}
|
package/src/app/app.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Context, type ContextMiddleware, type ContextListener } from '../context/context'
|
|
2
|
+
import { onDestroy, onInit, onStart } from './app-lifecycle'
|
|
3
|
+
|
|
4
|
+
export type AppConfig = {
|
|
5
|
+
context?: Context
|
|
6
|
+
init?: ContextMiddleware
|
|
7
|
+
start?: ContextMiddleware
|
|
8
|
+
destroy?: ContextMiddleware
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class App {
|
|
12
|
+
constructor(public readonly context: Context) {}
|
|
13
|
+
|
|
14
|
+
static Events = {
|
|
15
|
+
Init: 'declaro:init',
|
|
16
|
+
Start: 'declaro:start',
|
|
17
|
+
Destroy: 'declaro:destroy',
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async init() {
|
|
21
|
+
await this.context.emit(App.Events.Init)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
onInit(listener: ContextListener) {
|
|
25
|
+
onInit(this.context, listener)
|
|
26
|
+
return this
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async start() {
|
|
30
|
+
await this.context.emit(App.Events.Start)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
onStart(listener: ContextListener) {
|
|
34
|
+
onStart(this.context, listener)
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async destroy() {
|
|
39
|
+
await this.context.emit(App.Events.Start)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
onDestroy(listener: ContextListener) {
|
|
43
|
+
onDestroy(this.context, listener)
|
|
44
|
+
}
|
|
45
|
+
}
|
package/src/app/index.ts
CHANGED
|
@@ -1,34 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
/**
|
|
5
|
-
* A human-friendly title for your app
|
|
6
|
-
*/
|
|
7
|
-
title: string
|
|
8
|
-
/**
|
|
9
|
-
* A unique parameterized name for your app
|
|
10
|
-
*/
|
|
11
|
-
name: string
|
|
12
|
-
/**
|
|
13
|
-
* A human-friendly description for your app
|
|
14
|
-
*/
|
|
15
|
-
description: string
|
|
16
|
-
/**
|
|
17
|
-
* A URL to a logo for your app
|
|
18
|
-
*/
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export type App = {
|
|
22
|
-
meta: AppMeta
|
|
23
|
-
context: ContextMiddleware
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function defineApp(
|
|
27
|
-
meta: AppMeta,
|
|
28
|
-
configureContext: ContextMiddleware,
|
|
29
|
-
): App {
|
|
30
|
-
return {
|
|
31
|
-
meta,
|
|
32
|
-
context: configureContext,
|
|
33
|
-
}
|
|
34
|
-
}
|
|
1
|
+
export * from './app-context'
|
|
2
|
+
export * from './app-lifecycle'
|
|
3
|
+
export * from './app'
|