@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.
Files changed (90) hide show
  1. package/dist/app/app-context.d.ts +8 -0
  2. package/dist/app/app-lifecycle.d.ts +4 -0
  3. package/dist/app/app.d.ts +22 -0
  4. package/dist/app/index.d.ts +3 -20
  5. package/dist/auth/permission-validator.d.ts +34 -0
  6. package/dist/auth/permission-validator.test.d.ts +1 -0
  7. package/dist/context/context.d.ts +88 -13
  8. package/dist/context/legacy-context.test.d.ts +1 -0
  9. package/dist/errors/errors.d.ts +36 -0
  10. package/dist/events/event-manager.d.ts +11 -6
  11. package/dist/http/headers.d.ts +4 -0
  12. package/dist/http/headers.spec.d.ts +1 -0
  13. package/dist/http/request-context.d.ts +12 -0
  14. package/dist/http/request-context.spec.d.ts +1 -0
  15. package/dist/http/request.d.ts +8 -0
  16. package/dist/http/request.spec.d.ts +1 -0
  17. package/dist/http/url.d.ts +8 -0
  18. package/dist/http/url.spec.d.ts +1 -0
  19. package/dist/index.d.ts +9 -3
  20. package/dist/pkg.cjs +30 -2
  21. package/dist/pkg.mjs +56461 -207
  22. package/dist/schema/application.d.ts +83 -0
  23. package/dist/schema/application.test.d.ts +1 -0
  24. package/dist/schema/define-model.d.ts +7 -4
  25. package/dist/schema/index.d.ts +7 -0
  26. package/dist/schema/labels.d.ts +13 -0
  27. package/dist/schema/labels.test.d.ts +1 -0
  28. package/dist/schema/module.d.ts +7 -0
  29. package/dist/schema/module.test.d.ts +1 -0
  30. package/dist/schema/properties.d.ts +19 -0
  31. package/dist/schema/response.d.ts +31 -0
  32. package/dist/schema/response.test.d.ts +1 -0
  33. package/dist/schema/transform-model.d.ts +1 -1
  34. package/dist/schema/types.d.ts +81 -15
  35. package/dist/schema/types.test.d.ts +1 -0
  36. package/dist/typescript/constant-manipulation/snake-case.d.ts +22 -0
  37. package/dist/typescript/index.d.ts +1 -0
  38. package/dist/typescript/objects.d.ts +6 -0
  39. package/package.json +8 -3
  40. package/src/app/app-context.ts +14 -0
  41. package/src/app/app-lifecycle.ts +14 -0
  42. package/src/app/app.ts +45 -0
  43. package/src/app/index.ts +3 -34
  44. package/src/auth/permission-validator.test.ts +209 -0
  45. package/src/auth/permission-validator.ts +135 -0
  46. package/src/context/context.test.ts +585 -94
  47. package/src/context/context.ts +348 -32
  48. package/src/context/legacy-context.test.ts +141 -0
  49. package/src/errors/errors.ts +73 -0
  50. package/src/events/event-manager.spec.ts +54 -8
  51. package/src/events/event-manager.ts +40 -24
  52. package/src/http/headers.spec.ts +48 -0
  53. package/src/http/headers.ts +16 -0
  54. package/src/http/request-context.spec.ts +39 -0
  55. package/src/http/request-context.ts +43 -0
  56. package/src/http/request.spec.ts +52 -0
  57. package/src/http/request.ts +22 -0
  58. package/src/http/url.spec.ts +87 -0
  59. package/src/http/url.ts +48 -0
  60. package/src/index.ts +9 -3
  61. package/src/schema/application.test.ts +286 -0
  62. package/src/schema/application.ts +150 -0
  63. package/src/schema/define-model.test.ts +48 -2
  64. package/src/schema/define-model.ts +40 -9
  65. package/src/schema/index.ts +7 -0
  66. package/src/schema/labels.test.ts +60 -0
  67. package/src/schema/labels.ts +30 -0
  68. package/src/schema/module.test.ts +39 -0
  69. package/src/schema/module.ts +6 -0
  70. package/src/schema/properties.ts +40 -0
  71. package/src/schema/response.test.ts +101 -0
  72. package/src/schema/response.ts +93 -0
  73. package/src/schema/transform-model.ts +1 -1
  74. package/src/schema/types.test.ts +28 -0
  75. package/src/schema/types.ts +135 -15
  76. package/src/typescript/constant-manipulation/snake-case.md +496 -0
  77. package/src/typescript/constant-manipulation/snake-case.ts +76 -0
  78. package/src/typescript/index.ts +1 -0
  79. package/src/typescript/objects.ts +8 -5
  80. package/tsconfig.json +4 -1
  81. package/dist/context/index.d.ts +0 -3
  82. package/dist/interfaces/IDatastoreProvider.d.ts +0 -16
  83. package/dist/interfaces/IStore.d.ts +0 -4
  84. package/dist/interfaces/index.d.ts +0 -2
  85. package/dist/server/index.d.ts +0 -2
  86. package/src/context/index.ts +0 -3
  87. package/src/interfaces/IDatastoreProvider.ts +0 -23
  88. package/src/interfaces/IStore.ts +0 -4
  89. package/src/interfaces/index.ts +0 -2
  90. package/src/server/index.ts +0 -3
@@ -0,0 +1,8 @@
1
+ import { Context } from '../context/context';
2
+ /**
3
+ * Get the name of the app making the current request via header x-app. (returns "default" when no app was provided).
4
+ *
5
+ * @param context
6
+ * @returns the name of the app in a string.
7
+ */
8
+ export declare function useApp(context: Context): string;
@@ -0,0 +1,4 @@
1
+ import { Context, ContextListener } from '../context/context';
2
+ export declare function onInit(context: Context, listener: ContextListener): void;
3
+ export declare function onStart(context: Context, listener: ContextListener): void;
4
+ export declare function onDestroy(context: Context, listener: ContextListener): void;
@@ -0,0 +1,22 @@
1
+ import { Context, ContextMiddleware, ContextListener } from '../context/context';
2
+ export type AppConfig = {
3
+ context?: Context;
4
+ init?: ContextMiddleware;
5
+ start?: ContextMiddleware;
6
+ destroy?: ContextMiddleware;
7
+ };
8
+ export declare class App {
9
+ readonly context: Context;
10
+ constructor(context: Context);
11
+ static Events: {
12
+ Init: string;
13
+ Start: string;
14
+ Destroy: string;
15
+ };
16
+ init(): Promise<void>;
17
+ onInit(listener: ContextListener): this;
18
+ start(): Promise<void>;
19
+ onStart(listener: ContextListener): void;
20
+ destroy(): Promise<void>;
21
+ onDestroy(listener: ContextListener): void;
22
+ }
@@ -1,20 +1,3 @@
1
- import { ContextMiddleware } from '../context';
2
- export type AppMeta = {
3
- /**
4
- * A human-friendly title for your app
5
- */
6
- title: string;
7
- /**
8
- * A unique parameterized name for your app
9
- */
10
- name: string;
11
- /**
12
- * A human-friendly description for your app
13
- */
14
- description: string;
15
- };
16
- export type App = {
17
- meta: AppMeta;
18
- context: ContextMiddleware;
19
- };
20
- export declare function defineApp(meta: AppMeta, configureContext: ContextMiddleware): App;
1
+ export * from './app-context';
2
+ export * from './app-lifecycle';
3
+ export * from './app';
@@ -0,0 +1,34 @@
1
+ export declare enum PermissionRuleType {
2
+ ALL_OF = "ALL_OF",
3
+ NONE_OF = "NONE_OF",
4
+ SOME_OF = "SOME_OF"
5
+ }
6
+ export type RulePermission = string | PermissionValidator;
7
+ export type PermissionRule = {
8
+ type: PermissionRuleType;
9
+ permissions: RulePermission[];
10
+ errorMessage: string;
11
+ };
12
+ export declare class PermissionError extends Error {
13
+ rule: PermissionRule;
14
+ permissions: RulePermission[];
15
+ constructor(message: string, rule: PermissionRule, permissions: RulePermission[]);
16
+ }
17
+ export type PermissionValidationResults = {
18
+ valid: boolean;
19
+ errorMessage: string;
20
+ errors: PermissionError[];
21
+ };
22
+ export declare class PermissionValidator {
23
+ readonly rules: PermissionRule[];
24
+ static create(): PermissionValidator;
25
+ addRule(...rule: PermissionRule[]): this;
26
+ extend(...validators: PermissionValidator[]): this;
27
+ allOf(permissions: RulePermission[], errorMessage?: string): this;
28
+ noneOf(permissions: RulePermission[], errorMessage?: string): this;
29
+ someOf(permissions: RulePermission[], errorMessage?: string): this;
30
+ private validateRule;
31
+ private hasPermission;
32
+ validate(permissions?: string[]): boolean;
33
+ safeValidate(permissions?: string[]): PermissionValidationResults;
34
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,38 +1,113 @@
1
+ import { Class, PromiseOrValue, UnwrapPromise } from '../typescript';
1
2
  import { Validator } from '../validation';
2
3
  import { ContextConsumer } from './context-consumer';
4
+ export type AppScope = {};
5
+ export type RequestScope = {};
6
+ export type AppContext = Context<AppScope>;
7
+ export type RequestContext = Context<RequestScope>;
3
8
  export type ContextMiddleware = (context: Context) => any | Promise<any>;
4
- export type ContextState = Record<PropertyKey, ContextAttribute<StateValue<any>>>;
9
+ export type ContextState<TContext extends Context> = Record<PropertyKey, ContextAttribute<TContext, StateValue<any>>>;
5
10
  export type ContextResolver<T> = (context: Context) => StateValue<T>;
6
11
  export type StateValue<T> = T;
7
- export type ContextAttribute<T> = {
12
+ export declare enum DependencyType {
13
+ VALUE = "VALUE",
14
+ FACTORY = "FACTORY",
15
+ CLASS = "CLASS"
16
+ }
17
+ export type FactoryFn<T, A extends any[]> = (...args: A) => T;
18
+ export type ValueLoader<C extends Context, T> = (context: C) => T;
19
+ export type FilterKeysByType<TScope, TValue> = {
20
+ [Key in keyof TScope]: TScope[Key] extends TValue ? Key : never;
21
+ }[keyof TScope];
22
+ export type FilterKeysByAsyncType<TScope, TValue> = {
23
+ [Key in keyof TScope]: TScope[Key] extends PromiseOrValue<TValue> ? Key : never;
24
+ }[keyof TScope];
25
+ export type FilterArgsByType<TScope, TArgs extends any[]> = {
26
+ [Key in keyof TArgs]: FilterKeysByType<TScope, TArgs[Key]>;
27
+ };
28
+ export type FilterAsyncArgsByType<TScope, TArgs extends any[]> = {
29
+ [Key in keyof TArgs]: FilterKeysByAsyncType<TScope, TArgs[Key]>;
30
+ };
31
+ export type ContextAttribute<TContext extends Context<any>, TValue> = {
8
32
  key: PropertyKey;
9
- value?: T;
33
+ value?: ValueLoader<TContext, TValue>;
34
+ type: DependencyType;
35
+ resolveOptions: ResolveOptions;
36
+ cachedValue?: TValue;
37
+ inject: PropertyKey[];
38
+ };
39
+ export type ScopeKey<S extends object> = keyof S;
40
+ export type ContextListener = (context: Context) => any;
41
+ export type ResolveOptions = {
42
+ strict?: boolean;
43
+ eager?: boolean;
44
+ singleton?: boolean;
10
45
  };
11
- export type ContextListener = (context: Context, ...args: any[]) => any;
12
- export declare class Context {
46
+ export declare function defaultResolveOptions(): ResolveOptions;
47
+ export type ContextOptions = {
48
+ defaultResolveOptions?: ResolveOptions;
49
+ };
50
+ export declare class Context<Scope extends object = any> {
13
51
  private readonly state;
14
52
  private readonly emitter;
53
+ readonly scope: Scope;
54
+ protected readonly defaultResolveOptions: ResolveOptions;
55
+ constructor(options?: ContextOptions);
15
56
  /**
16
57
  * Set a value in context, to be injected later.
17
58
  *
18
59
  * @param key
19
60
  * @param payload
61
+ * @deprecated Use `provideValue` instead, or you can register the same dependency as a factory with `provideFactory` or class with `provideClass`.
62
+ */
63
+ provide<K extends ScopeKey<Scope>>(key: K, payload: Scope[K]): void;
64
+ /**
65
+ * Manually register a dependency. This should normally be used by utils or integrations that need to register dependencies in creative ways. For normal use cases, using `provideValue`, `provideFactory`, or `provideClass` is sufficient.
66
+ *
67
+ * @param key The key to register the dependency under
68
+ * @param dep The dependency record
69
+ */
70
+ register<K extends ScopeKey<Scope>>(key: K, dep: ContextAttribute<this, Scope[K]>): void;
71
+ /**
72
+ * Register a value in context scope.
73
+ *
74
+ * @param key The key to register the dependency under
75
+ * @param value The value to register
76
+ */
77
+ registerValue<K extends ScopeKey<Scope>>(key: K, value: Scope[K], defaultResolveOptions?: ResolveOptions): this;
78
+ /**
79
+ * Register a dependency as a factory in context scope.
80
+ *
81
+ * @param key The key to register the dependency under
82
+ * @param factory A factory function that will be called to generate the value when it is requested.
83
+ * @param inject An array of keys to use when injecting factory args.
84
+ * @returns A chainable instance of context
20
85
  */
21
- provide<T>(key: PropertyKey, payload: StateValue<T>): void;
86
+ registerFactory<K extends ScopeKey<Scope>, A extends any[]>(key: K, factory: FactoryFn<Scope[K], A>, inject?: FilterArgsByType<Scope, A>, defaultResolveOptions?: ResolveOptions): this;
87
+ registerAsyncFactory<K extends FilterKeysByType<Scope, Promise<any>>, A extends any[]>(key: K, factory: FactoryFn<Scope[K], A>, inject?: FilterAsyncArgsByType<Scope, A>, defaultResolveOptions?: ResolveOptions): this;
88
+ registerClass<K extends FilterKeysByType<Scope, InstanceType<T>>, T extends Class<Scope[K]>>(key: K, Class: T, inject?: FilterArgsByType<Scope, ConstructorParameters<T>>, defaultResolveOptions?: ResolveOptions): this;
89
+ registerAsyncClass<K extends FilterKeysByType<Scope, InstanceType<any>>, T extends Class<UnwrapPromise<Scope[K]>>>(key: K, Class: T, inject?: FilterAsyncArgsByType<Scope, ConstructorParameters<T>>, defaultResolveOptions?: ResolveOptions): this;
90
+ getAllDependencies<K extends ScopeKey<Scope>>(key: K): ContextAttribute<this, any>[];
91
+ getAllDependents<K extends ScopeKey<Scope>>(key: K): ContextAttribute<this, any>[];
92
+ introspect<K extends ScopeKey<Scope>>(key: K): ContextState<this>[K];
93
+ protected _cacheIsValid<K extends ScopeKey<Scope>>(key: K): boolean;
94
+ protected _resolveValue<K extends ScopeKey<Scope>>(key: K, resolveOptions?: ResolveOptions): Scope[K];
22
95
  /**
23
96
  * Extract a value from context.
24
97
  *
25
98
  * @param key
26
99
  * @returns
100
+ * @deprecated Use `resolve` instead
27
101
  */
28
- inject<T = any>(key: PropertyKey): T | undefined;
102
+ inject<T = any>(key: ScopeKey<Scope>): T | undefined;
103
+ resolve<K extends ScopeKey<Scope>>(key: K, resolveOptions?: ResolveOptions): Scope[K];
29
104
  /**
30
105
  * Ensure that only one copy of this instance exists in this context. Provides the instance if it doesn't exist yet, otherwise inject the cached instance.
31
106
  *
32
107
  * @param key
33
108
  * @param instance
34
109
  */
35
- singleton<T = any>(key: PropertyKey, instance: T): T;
110
+ singleton<T = any>(key: ScopeKey<Scope>, instance: T): T;
36
111
  /**
37
112
  * Instantiate a ContextConsumer class
38
113
  *
@@ -46,7 +121,7 @@ export declare class Context {
46
121
  * @param contexts
47
122
  * @returns
48
123
  */
49
- extend(...contexts: Context[]): ContextState;
124
+ extend(...contexts: Context[]): this;
50
125
  /**
51
126
  * Modify context with middleware
52
127
  *
@@ -60,13 +135,13 @@ export declare class Context {
60
135
  * @param validators
61
136
  * @returns
62
137
  */
63
- validate(...validators: Validator<Context>[]): import('../validation').Validation<Context>;
138
+ validate(...validators: Validator<Context>[]): import('..').Validation<Context<any>>;
64
139
  /**
65
140
  * Validate context ensuring at least one validator is valid
66
141
  * @param validators
67
142
  * @returns
68
143
  */
69
- validateAny(...validators: Validator<Context>[]): import('../validation').Validation<any>;
144
+ validateAny(...validators: Validator<Context>[]): import('..').Validation<any>;
70
145
  /**
71
146
  * Add a callback to listen for an event in this context.
72
147
  *
@@ -74,7 +149,7 @@ export declare class Context {
74
149
  * @param listener
75
150
  * @returns
76
151
  */
77
- on(event: string, listener: ContextListener): () => boolean;
152
+ on(event: string, listener: ContextListener): () => void;
78
153
  /**
79
154
  * Emit an event in this context
80
155
  *
@@ -82,5 +157,5 @@ export declare class Context {
82
157
  * @param args
83
158
  * @returns
84
159
  */
85
- emit(event: string, ...args: any[]): Promise<void>;
160
+ emit(event: string): Promise<void>;
86
161
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,36 @@
1
+ export interface IError {
2
+ code: number;
3
+ message: string;
4
+ meta: any;
5
+ }
6
+ export declare abstract class BaseError extends Error implements IError {
7
+ readonly meta: any;
8
+ readonly code: number;
9
+ constructor(message: string, meta?: any);
10
+ toJSON(): {
11
+ code: number;
12
+ message: string;
13
+ meta: any;
14
+ };
15
+ toString(): string;
16
+ }
17
+ export declare class SystemError extends BaseError {
18
+ readonly code: number;
19
+ constructor(message: string, meta?: any);
20
+ }
21
+ export declare class ValidationError extends BaseError {
22
+ readonly code: number;
23
+ constructor(message: string, meta?: any);
24
+ }
25
+ export declare class NotFoundError extends BaseError {
26
+ readonly code: number;
27
+ constructor(message: string, meta?: any);
28
+ }
29
+ export declare class UnauthorizedError extends BaseError {
30
+ readonly code: number;
31
+ constructor(message: string, meta?: any);
32
+ }
33
+ export declare class ForbiddenError extends BaseError {
34
+ readonly code: number;
35
+ constructor(message: string, meta?: any);
36
+ }
@@ -1,11 +1,16 @@
1
- export type Listener = (...args: any[]) => any;
2
- export declare class EventManager<T> {
1
+ export interface IEvent {
2
+ type: string;
3
+ }
4
+ export type Listener = (event: IEvent) => any;
5
+ export declare class EventManager<E extends IEvent = IEvent> {
3
6
  protected readonly listeners: {
4
7
  [key: string]: Listener[];
5
8
  };
6
9
  getListeners(event: string): Listener[];
7
- on(event: string, listener: Listener): () => boolean;
8
- emitAsync(event: string, ...args: any[]): Promise<void>;
9
- emitAll(event: string, ...args: any[]): Promise<void>;
10
- emit(event: string, ...args: any[]): void;
10
+ getEvents(): string[];
11
+ on(event: string | string[], listener: Listener): () => void;
12
+ emitAsync(event: E): Promise<void>;
13
+ emitAll(event: E): Promise<void>;
14
+ emit(event: E): void;
15
+ protected getListenerArray(event: string): Listener[];
11
16
  }
@@ -0,0 +1,4 @@
1
+ import { Context } from '../context/context';
2
+ export type HeaderMap = Record<string, string>;
3
+ export declare function useHeaders(context: Context): import('http').IncomingHttpHeaders;
4
+ export declare function useHeader(context: Context, header: string): string | string[];
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ import { Context, ContextMiddleware } from '../context/context';
2
+ import { IncomingMessage, ServerResponse } from 'http';
3
+ export declare const REQUEST_CONTEXT_MIDDLEWARE: unique symbol;
4
+ export declare function useRequestMiddleware(context: Context): ContextMiddleware[];
5
+ export declare function provideRequestMiddleware(context: Context, ...middleware: ContextMiddleware[]): ContextMiddleware[];
6
+ export declare const REQUEST_NODE_MIDDLEWARE: unique symbol;
7
+ export type NodeListener = (req: IncomingMessage, res: ServerResponse) => void;
8
+ export type NodePromisifiedHandler = (req: IncomingMessage, res: ServerResponse) => Promise<any>;
9
+ export type NodeMiddleware = (req: IncomingMessage, res: ServerResponse, next: (err?: Error) => any) => any;
10
+ export type AllNodeMiddleware = NodeListener | NodePromisifiedHandler | NodeMiddleware;
11
+ export declare function useNodeMiddleware(context: Context): AllNodeMiddleware[];
12
+ export declare function provideNodeMiddleware(context: Context, ...middleware: AllNodeMiddleware[]): AllNodeMiddleware[];
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ import { Context } from '../context/context';
2
+ import { IncomingMessage } from 'http';
3
+ export declare const REQUEST: unique symbol;
4
+ export interface Request extends IncomingMessage {
5
+ }
6
+ export declare function provideRequest(context: Context, request: Request): void;
7
+ export declare function useRequest(context: Context): Request;
8
+ export declare function useRequestMethod(context: Context): string;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ import { Context } from '../context/context';
2
+ import { URL } from 'whatwg-url';
3
+ export declare function useRequestURL(context: Context): URL;
4
+ export declare function useRequestURLString(context: Context): string;
5
+ export declare function useRequestDomain(context: Context): string;
6
+ export declare function useRequestPath(context: Context): string;
7
+ export declare function useRequestQuery(context: Context): Record<string, string>;
8
+ export declare function useFormattedQueryParam(context: Context, key: string): void;
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.d.ts CHANGED
@@ -1,13 +1,19 @@
1
1
  export * from './typescript';
2
2
  export * from './app';
3
- export * from './server';
4
- export * from './context';
3
+ export * from './context/context';
4
+ export * from './context/context-consumer';
5
+ export * from './context/validators';
5
6
  export * from './dataflow';
6
7
  export * from './events';
7
8
  export * from './validation';
8
9
  export * from './timing';
9
10
  export * from './schema';
10
11
  export * from './helpers';
11
- export * from './interfaces';
12
+ export * from './errors/errors';
12
13
  export * from './schema/formats';
13
14
  export * from './pipelines';
15
+ export * from './http/headers';
16
+ export * from './http/request-context';
17
+ export * from './http/request';
18
+ export * from './http/url';
19
+ export * from './auth/permission-validator';