@controller-contract/server 0.2.6 → 0.3.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/index.d.mts +56 -38
- package/dist/index.mjs +36 -23
- package/package.json +1 -1
- package/src/classes/controller-contract-controller/controller-contract-controller.ts +14 -0
- package/src/classes/controller-contract-controller-builder/builder-steps/post-endpoint-step.ts +48 -0
- package/src/classes/controller-contract-controller-builder/builder-steps/post-inject-step.ts +19 -0
- package/src/classes/{PostInputStep.ts → controller-contract-controller-builder/builder-steps/post-input-step.ts} +14 -20
- package/src/classes/controller-contract-controller-builder/controller-contract-controller-builder.ts +24 -0
- package/src/classes/controller-contract-controller-router/controller-contract-controller-router-factory.ts +13 -0
- package/src/classes/controller-contract-controller-router/controller-contract-controller-router.ts +16 -0
- package/src/classes/framework-integration-factory.ts +19 -0
- package/src/index.ts +2 -1
- package/src/interfaces/ControllerContractSpec.ts +7 -7
- package/src/types/index.ts +25 -7
- package/src/types/infer-controller-contracts-from-router.ts +5 -0
- package/src/classes/ControllerContractAdapterFactory.ts +0 -13
- package/src/classes/ControllerContractBuilder.ts +0 -24
- package/src/classes/ControllerContractRouter.ts +0 -9
- package/src/classes/PostEndpointStep.ts +0 -49
- package/src/classes/PostInjectStep.ts +0 -19
package/dist/index.d.mts
CHANGED
|
@@ -1,24 +1,29 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ControllerContract, ExitOutput, FailOutput, InputChannel, Method, NextOutput, NoInput, Output, ParamsFrom, PassOutput } from "@controller-contract/core";
|
|
2
2
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
3
3
|
|
|
4
|
+
//#region src/classes/controller-contract-controller/controller-contract-controller.d.ts
|
|
5
|
+
type ControllerContractController<TMethod extends Method, TPath extends string, TParamsInput, TQueryInput, TBodyInput, TOuput extends Output, TRouter> = (() => TRouter) & {
|
|
6
|
+
'~cc'?: TMethod | TPath | TParamsInput | TQueryInput | TBodyInput | TOuput;
|
|
7
|
+
};
|
|
8
|
+
//#endregion
|
|
4
9
|
//#region src/interfaces/ControllerContractSpec.d.ts
|
|
5
|
-
interface NullaryControllerContractSpec<
|
|
10
|
+
interface NullaryControllerContractSpec<TFrameworkContext, TInject> {
|
|
6
11
|
readonly type: 'nullary';
|
|
7
12
|
readonly injectable: TInject;
|
|
8
13
|
readonly method: Method;
|
|
9
14
|
readonly path: string;
|
|
10
|
-
readonly outputFn: OutputFn<
|
|
15
|
+
readonly outputFn: OutputFn<TFrameworkContext, string, Output>;
|
|
11
16
|
}
|
|
12
|
-
interface SanitizedControllerContractSpec<
|
|
17
|
+
interface SanitizedControllerContractSpec<TFrameworkContext, TInject> {
|
|
13
18
|
readonly type: 'sanitized';
|
|
14
19
|
readonly injectable: TInject;
|
|
15
20
|
readonly method: Method;
|
|
16
21
|
readonly path: string;
|
|
17
22
|
readonly channel: InputChannel;
|
|
18
23
|
readonly schema: StandardSchemaV1;
|
|
19
|
-
readonly outputFn: SanitizedOutputFn<
|
|
24
|
+
readonly outputFn: SanitizedOutputFn<TFrameworkContext, string, unknown, Output>;
|
|
20
25
|
}
|
|
21
|
-
type ControllerContractSpec<
|
|
26
|
+
type ControllerContractSpec<TFrameworkContext, TInject> = NullaryControllerContractSpec<TFrameworkContext, TInject> | SanitizedControllerContractSpec<TFrameworkContext, TInject>;
|
|
22
27
|
//#endregion
|
|
23
28
|
//#region src/utils/outputs.d.ts
|
|
24
29
|
declare namespace outputs {
|
|
@@ -53,68 +58,81 @@ declare const StandardOutputs: Readonly<{
|
|
|
53
58
|
}>;
|
|
54
59
|
//#endregion
|
|
55
60
|
//#region src/types/index.d.ts
|
|
56
|
-
type
|
|
57
|
-
type
|
|
61
|
+
type BuilderIntegratorFn<TFrameworkContext, TFrameworkInject, TFrameworkRouter> = (spec: ControllerContractSpec<TFrameworkContext, TFrameworkInject>) => TFrameworkRouter;
|
|
62
|
+
type RouterIntegratorFn<TRouter> = <TRoutes extends Record<any, ControllerContractController<any, any, any, any, any, any, TRouter>>>(routes: TRoutes) => TRouter;
|
|
58
63
|
type Prettify<T> = { [K in keyof T]: T[K] } & {};
|
|
59
|
-
type OutputFn<
|
|
64
|
+
type OutputFn<TFrameworkContext, TPath extends string, TOutput> = (context: Prettify<TFrameworkContext & {
|
|
60
65
|
params: ParamsFrom<TPath>;
|
|
61
66
|
outputs: typeof outputs;
|
|
62
67
|
}>) => Promise<TOutput>;
|
|
63
|
-
type SanitizedOutputFn<
|
|
68
|
+
type SanitizedOutputFn<TFrameworkContext, TPath extends string, TInput, TOutput> = OutputFn<TFrameworkContext & {
|
|
64
69
|
input: TInput;
|
|
65
70
|
}, TPath, TOutput>;
|
|
71
|
+
type InferControllerContract<T> = T extends ControllerContractController<infer M, infer P, any, infer Q, infer B, infer O, any> ? ControllerContract<M, P, ParamsFrom<P>, Q, B, O> : never;
|
|
72
|
+
type MapToControllerContract<TRoutes> = { [TRouteName in Extract<keyof TRoutes, string> as Capitalize<TRouteName>]: InferControllerContract<TRoutes[TRouteName]> };
|
|
66
73
|
//#endregion
|
|
67
|
-
//#region src/classes/
|
|
68
|
-
declare class PostInputStep<
|
|
74
|
+
//#region src/classes/controller-contract-controller-builder/builder-steps/post-input-step.d.ts
|
|
75
|
+
declare class PostInputStep<TFrameworkContext, TFrameworkInject, TRouter, const TMethod extends Method, const TPath extends string, const TChannel extends InputChannel, TInput, TOutputFromInput extends Output> {
|
|
69
76
|
private readonly injectable;
|
|
70
77
|
private readonly integrator;
|
|
71
78
|
private readonly method;
|
|
72
79
|
private readonly path;
|
|
73
80
|
private readonly channel;
|
|
74
81
|
private readonly schema;
|
|
75
|
-
constructor(injectable:
|
|
76
|
-
output<TOutput extends Output>(outputFn: SanitizedOutputFn<
|
|
82
|
+
constructor(injectable: TFrameworkInject, integrator: BuilderIntegratorFn<TFrameworkContext, TFrameworkInject, TRouter>, method: TMethod, path: TPath, channel: TChannel, schema: StandardSchemaV1<TInput>);
|
|
83
|
+
output<TOutput extends Output>(outputFn: SanitizedOutputFn<TFrameworkContext, TPath, TInput, TOutput>): ControllerContractController<TMethod, TPath, ParamsFrom<TPath>, TChannel extends "query" ? TInput : NoInput, TChannel extends "body" ? TInput : NoInput, TOutputFromInput | TOutput, TRouter>;
|
|
77
84
|
}
|
|
78
85
|
//#endregion
|
|
79
|
-
//#region src/classes/
|
|
80
|
-
declare class PostEndpointStep<
|
|
86
|
+
//#region src/classes/controller-contract-controller-builder/builder-steps/post-endpoint-step.d.ts
|
|
87
|
+
declare class PostEndpointStep<TFrameworkContext, TFrameworkInject, TRouter, const TMethod extends Method, const TPath extends string> {
|
|
81
88
|
private readonly injectable;
|
|
82
89
|
private readonly integrator;
|
|
83
90
|
private readonly method;
|
|
84
91
|
private readonly path;
|
|
85
|
-
constructor(injectable:
|
|
86
|
-
input<const TChannel extends InputChannel, TInput>(channel: TChannel, schema: StandardSchemaV1<TInput>): PostInputStep<
|
|
87
|
-
output<TOutput extends Output>(outputFn: OutputFn<
|
|
92
|
+
constructor(injectable: TFrameworkInject, integrator: BuilderIntegratorFn<TFrameworkContext, TFrameworkInject, TRouter>, method: TMethod, path: TPath);
|
|
93
|
+
input<const TChannel extends InputChannel, TInput>(channel: TChannel, schema: StandardSchemaV1<TInput>): PostInputStep<TFrameworkContext, TFrameworkInject, TRouter, TMethod, TPath, TChannel, TInput, FailOutput<Extract<keyof TInput, string>>>;
|
|
94
|
+
output<TOutput extends Output>(outputFn: OutputFn<TFrameworkContext, TPath, TOutput>): ControllerContractController<TMethod, TPath, ParamsFrom<TPath>, NoInput, NoInput, TOutput, TRouter>;
|
|
88
95
|
}
|
|
89
96
|
//#endregion
|
|
90
|
-
//#region src/classes/
|
|
91
|
-
declare class PostInjectStep<
|
|
97
|
+
//#region src/classes/controller-contract-controller-builder/builder-steps/post-inject-step.d.ts
|
|
98
|
+
declare class PostInjectStep<TFrameworkContext, TFrameworkInject, TRouter> {
|
|
92
99
|
private readonly injectable;
|
|
93
100
|
private readonly integrator;
|
|
94
|
-
constructor(injectable:
|
|
95
|
-
endpoint<const TMethod extends Method, const TPath extends string>(method: TMethod, path: TPath): PostEndpointStep<
|
|
101
|
+
constructor(injectable: TFrameworkInject, integrator: BuilderIntegratorFn<TFrameworkContext, TFrameworkInject, TRouter>);
|
|
102
|
+
endpoint<const TMethod extends Method, const TPath extends string>(method: TMethod, path: TPath): PostEndpointStep<TFrameworkContext, TFrameworkInject, TRouter, TMethod, TPath>;
|
|
96
103
|
}
|
|
97
104
|
//#endregion
|
|
98
|
-
//#region src/classes/
|
|
99
|
-
declare class
|
|
105
|
+
//#region src/classes/controller-contract-controller-builder/controller-contract-controller-builder.d.ts
|
|
106
|
+
declare class ControllerContractControllerBuilder<TFrameworkContext, TFrameworkInject, TFrameworkRouter> {
|
|
100
107
|
private readonly injectableDefaultValue;
|
|
101
108
|
private readonly integrator;
|
|
102
|
-
constructor(injectableDefaultValue:
|
|
103
|
-
inject(injectable:
|
|
104
|
-
endpoint<const TMethod extends Method, const TPath extends string>(method: TMethod, path: TPath): PostEndpointStep<
|
|
109
|
+
constructor(injectableDefaultValue: TFrameworkInject, integrator: BuilderIntegratorFn<TFrameworkContext, TFrameworkInject, TFrameworkRouter>);
|
|
110
|
+
inject(injectable: TFrameworkInject): PostInjectStep<TFrameworkContext, TFrameworkInject, TFrameworkRouter>;
|
|
111
|
+
endpoint<const TMethod extends Method, const TPath extends string>(method: TMethod, path: TPath): PostEndpointStep<TFrameworkContext, TFrameworkInject, TFrameworkRouter, TMethod, TPath>;
|
|
112
|
+
}
|
|
113
|
+
//#endregion
|
|
114
|
+
//#region src/classes/controller-contract-controller-router/controller-contract-controller-router.d.ts
|
|
115
|
+
declare class ControllerContractControllerRouter<TRouter, TRoutes extends Record<any, ControllerContractController<any, any, any, any, any, any, TRouter>>> {
|
|
116
|
+
private readonly integrator;
|
|
117
|
+
private readonly routes;
|
|
118
|
+
constructor(integrator: RouterIntegratorFn<TRouter>, routes: TRoutes);
|
|
119
|
+
getIntegratedRouter(): TRouter;
|
|
105
120
|
}
|
|
106
121
|
//#endregion
|
|
107
|
-
//#region src/classes/
|
|
108
|
-
declare class
|
|
109
|
-
private readonly
|
|
110
|
-
constructor(
|
|
111
|
-
|
|
122
|
+
//#region src/classes/controller-contract-controller-router/controller-contract-controller-router-factory.d.ts
|
|
123
|
+
declare class ControllerContractControllerRouterFactory<TRouter> {
|
|
124
|
+
private readonly integrator;
|
|
125
|
+
constructor(integrator: RouterIntegratorFn<TRouter>);
|
|
126
|
+
createControllerContractControllerRouter<TRoutes extends Record<any, ControllerContractController<any, any, any, any, any, any, TRouter>>>(routes: TRoutes): ControllerContractControllerRouter<TRouter, TRoutes>;
|
|
112
127
|
}
|
|
113
128
|
//#endregion
|
|
114
|
-
//#region src/classes/
|
|
115
|
-
declare class
|
|
116
|
-
|
|
117
|
-
|
|
129
|
+
//#region src/classes/framework-integration-factory.d.ts
|
|
130
|
+
declare class FrameworkIntegrationFactory<TFrameworkContext, TFrameworkInject, TFrameworkRouter> {
|
|
131
|
+
createControllerContractControllerBuilder(injectableDefaultValue: TFrameworkInject, integrator: BuilderIntegratorFn<TFrameworkContext, TFrameworkInject, TFrameworkRouter>): ControllerContractControllerBuilder<TFrameworkContext, TFrameworkInject, TFrameworkRouter>;
|
|
132
|
+
createControllerContractControllerRouterFactory(integrator: RouterIntegratorFn<TFrameworkRouter>): ControllerContractControllerRouterFactory<TFrameworkRouter>;
|
|
118
133
|
}
|
|
119
134
|
//#endregion
|
|
120
|
-
|
|
135
|
+
//#region src/types/infer-controller-contracts-from-router.d.ts
|
|
136
|
+
type InferControllerContractsFromRouter<T> = T extends ControllerContractControllerRouter<any, infer TRoutes> ? MapToControllerContract<TRoutes> : never;
|
|
137
|
+
//#endregion
|
|
138
|
+
export { FrameworkIntegrationFactory, InferControllerContractsFromRouter, StandardOutputs, outputs, rootOnly };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//#region src/classes/
|
|
1
|
+
//#region src/classes/controller-contract-controller-builder/builder-steps/post-input-step.ts
|
|
2
2
|
var PostInputStep = class {
|
|
3
3
|
injectable;
|
|
4
4
|
integrator;
|
|
@@ -15,7 +15,7 @@ var PostInputStep = class {
|
|
|
15
15
|
this.schema = schema;
|
|
16
16
|
}
|
|
17
17
|
output(outputFn) {
|
|
18
|
-
this.integrator({
|
|
18
|
+
const product = this.integrator({
|
|
19
19
|
type: "sanitized",
|
|
20
20
|
injectable: this.injectable,
|
|
21
21
|
method: this.method,
|
|
@@ -24,11 +24,11 @@ var PostInputStep = class {
|
|
|
24
24
|
schema: this.schema,
|
|
25
25
|
outputFn
|
|
26
26
|
});
|
|
27
|
-
return
|
|
27
|
+
return (() => product);
|
|
28
28
|
}
|
|
29
29
|
};
|
|
30
30
|
//#endregion
|
|
31
|
-
//#region src/classes/
|
|
31
|
+
//#region src/classes/controller-contract-controller-builder/builder-steps/post-endpoint-step.ts
|
|
32
32
|
var PostEndpointStep = class {
|
|
33
33
|
injectable;
|
|
34
34
|
integrator;
|
|
@@ -44,18 +44,18 @@ var PostEndpointStep = class {
|
|
|
44
44
|
return new PostInputStep(this.injectable, this.integrator, this.method, this.path, channel, schema);
|
|
45
45
|
}
|
|
46
46
|
output(outputFn) {
|
|
47
|
-
this.integrator({
|
|
47
|
+
const product = this.integrator({
|
|
48
48
|
type: "nullary",
|
|
49
49
|
method: this.method,
|
|
50
50
|
path: this.path,
|
|
51
51
|
injectable: this.injectable,
|
|
52
52
|
outputFn
|
|
53
53
|
});
|
|
54
|
-
return
|
|
54
|
+
return (() => product);
|
|
55
55
|
}
|
|
56
56
|
};
|
|
57
57
|
//#endregion
|
|
58
|
-
//#region src/classes/
|
|
58
|
+
//#region src/classes/controller-contract-controller-builder/builder-steps/post-inject-step.ts
|
|
59
59
|
var PostInjectStep = class {
|
|
60
60
|
injectable;
|
|
61
61
|
integrator;
|
|
@@ -68,8 +68,8 @@ var PostInjectStep = class {
|
|
|
68
68
|
}
|
|
69
69
|
};
|
|
70
70
|
//#endregion
|
|
71
|
-
//#region src/classes/
|
|
72
|
-
var
|
|
71
|
+
//#region src/classes/controller-contract-controller-builder/controller-contract-controller-builder.ts
|
|
72
|
+
var ControllerContractControllerBuilder = class {
|
|
73
73
|
injectableDefaultValue;
|
|
74
74
|
integrator;
|
|
75
75
|
constructor(injectableDefaultValue, integrator) {
|
|
@@ -84,24 +84,37 @@ var ControllerContractBuilder = class {
|
|
|
84
84
|
}
|
|
85
85
|
};
|
|
86
86
|
//#endregion
|
|
87
|
-
//#region src/classes/
|
|
88
|
-
var
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
87
|
+
//#region src/classes/controller-contract-controller-router/controller-contract-controller-router.ts
|
|
88
|
+
var ControllerContractControllerRouter = class {
|
|
89
|
+
integrator;
|
|
90
|
+
routes;
|
|
91
|
+
constructor(integrator, routes) {
|
|
92
|
+
this.integrator = integrator;
|
|
93
|
+
this.routes = routes;
|
|
94
|
+
}
|
|
95
|
+
getIntegratedRouter() {
|
|
96
|
+
return this.integrator(this.routes);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
//#endregion
|
|
100
|
+
//#region src/classes/controller-contract-controller-router/controller-contract-controller-router-factory.ts
|
|
101
|
+
var ControllerContractControllerRouterFactory = class {
|
|
102
|
+
integrator;
|
|
103
|
+
constructor(integrator) {
|
|
104
|
+
this.integrator = integrator;
|
|
92
105
|
}
|
|
93
|
-
|
|
94
|
-
return this.
|
|
106
|
+
createControllerContractControllerRouter(routes) {
|
|
107
|
+
return new ControllerContractControllerRouter(this.integrator, routes);
|
|
95
108
|
}
|
|
96
109
|
};
|
|
97
110
|
//#endregion
|
|
98
|
-
//#region src/classes/
|
|
99
|
-
var
|
|
100
|
-
|
|
101
|
-
return new
|
|
111
|
+
//#region src/classes/framework-integration-factory.ts
|
|
112
|
+
var FrameworkIntegrationFactory = class {
|
|
113
|
+
createControllerContractControllerBuilder(injectableDefaultValue, integrator) {
|
|
114
|
+
return new ControllerContractControllerBuilder(injectableDefaultValue, integrator);
|
|
102
115
|
}
|
|
103
|
-
|
|
104
|
-
return new
|
|
116
|
+
createControllerContractControllerRouterFactory(integrator) {
|
|
117
|
+
return new ControllerContractControllerRouterFactory(integrator);
|
|
105
118
|
}
|
|
106
119
|
};
|
|
107
120
|
//#endregion
|
|
@@ -155,4 +168,4 @@ const StandardOutputs = Object.freeze({
|
|
|
155
168
|
BadGateway: outputs.fail(rootOnly("Bad Gateway"), 502)
|
|
156
169
|
});
|
|
157
170
|
//#endregion
|
|
158
|
-
export {
|
|
171
|
+
export { FrameworkIntegrationFactory, StandardOutputs, outputs, rootOnly };
|
package/package.json
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Method, Output } from '@controller-contract/core';
|
|
2
|
+
|
|
3
|
+
export type ControllerContractController<
|
|
4
|
+
TMethod extends Method,
|
|
5
|
+
TPath extends string,
|
|
6
|
+
TParamsInput,
|
|
7
|
+
TQueryInput,
|
|
8
|
+
TBodyInput,
|
|
9
|
+
TOuput extends Output,
|
|
10
|
+
TRouter,
|
|
11
|
+
> = (() => TRouter) & {
|
|
12
|
+
// Suppresses the linter warning about unused variables
|
|
13
|
+
'~cc'?: TMethod | TPath | TParamsInput | TQueryInput | TBodyInput | TOuput;
|
|
14
|
+
};
|
package/src/classes/controller-contract-controller-builder/builder-steps/post-endpoint-step.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { FailOutput, InputChannel, Method, NoInput, Output, ParamsFrom } from '@controller-contract/core';
|
|
2
|
+
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
3
|
+
import type { NullaryControllerContractSpec } from '../../../interfaces/ControllerContractSpec';
|
|
4
|
+
import type { BuilderIntegratorFn, OutputFn } from '../../../types';
|
|
5
|
+
import type { ControllerContractController } from '../../controller-contract-controller/controller-contract-controller';
|
|
6
|
+
import { PostInputStep } from './post-input-step';
|
|
7
|
+
|
|
8
|
+
export class PostEndpointStep<
|
|
9
|
+
TFrameworkContext,
|
|
10
|
+
TFrameworkInject,
|
|
11
|
+
TRouter,
|
|
12
|
+
const TMethod extends Method,
|
|
13
|
+
const TPath extends string,
|
|
14
|
+
> {
|
|
15
|
+
constructor(
|
|
16
|
+
private readonly injectable: TFrameworkInject,
|
|
17
|
+
private readonly integrator: BuilderIntegratorFn<TFrameworkContext, TFrameworkInject, TRouter>,
|
|
18
|
+
private readonly method: TMethod,
|
|
19
|
+
private readonly path: TPath,
|
|
20
|
+
) {}
|
|
21
|
+
|
|
22
|
+
input<const TChannel extends InputChannel, TInput>(channel: TChannel, schema: StandardSchemaV1<TInput>) {
|
|
23
|
+
return new PostInputStep<
|
|
24
|
+
TFrameworkContext,
|
|
25
|
+
TFrameworkInject,
|
|
26
|
+
TRouter,
|
|
27
|
+
TMethod,
|
|
28
|
+
TPath,
|
|
29
|
+
TChannel,
|
|
30
|
+
TInput,
|
|
31
|
+
FailOutput<Extract<keyof TInput, string>>
|
|
32
|
+
>(this.injectable, this.integrator, this.method, this.path, channel, schema);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
output<TOutput extends Output>(outputFn: OutputFn<TFrameworkContext, TPath, TOutput>) {
|
|
36
|
+
const product = this.integrator(<NullaryControllerContractSpec<TFrameworkContext, TFrameworkInject>>{
|
|
37
|
+
type: 'nullary',
|
|
38
|
+
method: this.method,
|
|
39
|
+
path: this.path,
|
|
40
|
+
injectable: this.injectable,
|
|
41
|
+
outputFn,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
return <ControllerContractController<TMethod, TPath, ParamsFrom<TPath>, NoInput, NoInput, TOutput, TRouter>>(
|
|
45
|
+
(() => product)
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Method } from '@controller-contract/core';
|
|
2
|
+
import type { BuilderIntegratorFn } from '../../../types';
|
|
3
|
+
import { PostEndpointStep } from './post-endpoint-step';
|
|
4
|
+
|
|
5
|
+
export class PostInjectStep<TFrameworkContext, TFrameworkInject, TRouter> {
|
|
6
|
+
constructor(
|
|
7
|
+
private readonly injectable: TFrameworkInject,
|
|
8
|
+
private readonly integrator: BuilderIntegratorFn<TFrameworkContext, TFrameworkInject, TRouter>,
|
|
9
|
+
) {}
|
|
10
|
+
|
|
11
|
+
endpoint<const TMethod extends Method, const TPath extends string>(method: TMethod, path: TPath) {
|
|
12
|
+
return new PostEndpointStep<TFrameworkContext, TFrameworkInject, TRouter, TMethod, TPath>(
|
|
13
|
+
this.injectable,
|
|
14
|
+
this.integrator,
|
|
15
|
+
method,
|
|
16
|
+
path,
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -1,19 +1,13 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
ControllerContractProduct,
|
|
3
|
-
InputChannel,
|
|
4
|
-
Method,
|
|
5
|
-
NoInput,
|
|
6
|
-
Output,
|
|
7
|
-
ParamsFrom,
|
|
8
|
-
} from '@controller-contract/core';
|
|
1
|
+
import type { InputChannel, Method, NoInput, Output, ParamsFrom } from '@controller-contract/core';
|
|
9
2
|
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
10
|
-
import type { SanitizedControllerContractSpec } from '
|
|
11
|
-
import type {
|
|
3
|
+
import type { SanitizedControllerContractSpec } from '../../../interfaces/ControllerContractSpec';
|
|
4
|
+
import type { BuilderIntegratorFn, SanitizedOutputFn } from '../../../types';
|
|
5
|
+
import type { ControllerContractController } from '../../controller-contract-controller/controller-contract-controller';
|
|
12
6
|
|
|
13
7
|
export class PostInputStep<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
TFrameworkContext,
|
|
9
|
+
TFrameworkInject,
|
|
10
|
+
TRouter,
|
|
17
11
|
const TMethod extends Method,
|
|
18
12
|
const TPath extends string,
|
|
19
13
|
const TChannel extends InputChannel,
|
|
@@ -21,16 +15,16 @@ export class PostInputStep<
|
|
|
21
15
|
TOutputFromInput extends Output,
|
|
22
16
|
> {
|
|
23
17
|
constructor(
|
|
24
|
-
private readonly injectable:
|
|
25
|
-
private readonly integrator:
|
|
18
|
+
private readonly injectable: TFrameworkInject,
|
|
19
|
+
private readonly integrator: BuilderIntegratorFn<TFrameworkContext, TFrameworkInject, TRouter>,
|
|
26
20
|
private readonly method: TMethod,
|
|
27
21
|
private readonly path: TPath,
|
|
28
22
|
private readonly channel: TChannel,
|
|
29
23
|
private readonly schema: StandardSchemaV1<TInput>,
|
|
30
24
|
) {}
|
|
31
25
|
|
|
32
|
-
output<TOutput extends Output>(outputFn: SanitizedOutputFn<
|
|
33
|
-
const product = this.integrator(<SanitizedControllerContractSpec<
|
|
26
|
+
output<TOutput extends Output>(outputFn: SanitizedOutputFn<TFrameworkContext, TPath, TInput, TOutput>) {
|
|
27
|
+
const product = this.integrator(<SanitizedControllerContractSpec<TFrameworkContext, TFrameworkInject>>{
|
|
34
28
|
type: 'sanitized',
|
|
35
29
|
injectable: this.injectable,
|
|
36
30
|
method: this.method,
|
|
@@ -41,15 +35,15 @@ export class PostInputStep<
|
|
|
41
35
|
});
|
|
42
36
|
|
|
43
37
|
return <
|
|
44
|
-
|
|
38
|
+
ControllerContractController<
|
|
45
39
|
TMethod,
|
|
46
40
|
TPath,
|
|
47
41
|
ParamsFrom<TPath>,
|
|
48
42
|
TChannel extends 'query' ? TInput : NoInput,
|
|
49
43
|
TChannel extends 'body' ? TInput : NoInput,
|
|
50
44
|
TOutputFromInput | TOutput,
|
|
51
|
-
|
|
45
|
+
TRouter
|
|
52
46
|
>
|
|
53
|
-
>
|
|
47
|
+
>(() => product);
|
|
54
48
|
}
|
|
55
49
|
}
|
package/src/classes/controller-contract-controller-builder/controller-contract-controller-builder.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Method } from '@controller-contract/core';
|
|
2
|
+
import type { BuilderIntegratorFn } from '../../types';
|
|
3
|
+
import { PostEndpointStep } from './builder-steps/post-endpoint-step';
|
|
4
|
+
import { PostInjectStep } from './builder-steps/post-inject-step';
|
|
5
|
+
|
|
6
|
+
export class ControllerContractControllerBuilder<TFrameworkContext, TFrameworkInject, TFrameworkRouter> {
|
|
7
|
+
constructor(
|
|
8
|
+
private readonly injectableDefaultValue: TFrameworkInject,
|
|
9
|
+
private readonly integrator: BuilderIntegratorFn<TFrameworkContext, TFrameworkInject, TFrameworkRouter>,
|
|
10
|
+
) {}
|
|
11
|
+
|
|
12
|
+
inject(injectable: TFrameworkInject) {
|
|
13
|
+
return new PostInjectStep<TFrameworkContext, TFrameworkInject, TFrameworkRouter>(injectable, this.integrator);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
endpoint<const TMethod extends Method, const TPath extends string>(method: TMethod, path: TPath) {
|
|
17
|
+
return new PostEndpointStep<TFrameworkContext, TFrameworkInject, TFrameworkRouter, TMethod, TPath>(
|
|
18
|
+
this.injectableDefaultValue,
|
|
19
|
+
this.integrator,
|
|
20
|
+
method,
|
|
21
|
+
path,
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { RouterIntegratorFn } from '../../types';
|
|
2
|
+
import type { ControllerContractController } from '../controller-contract-controller/controller-contract-controller';
|
|
3
|
+
import { ControllerContractControllerRouter } from './controller-contract-controller-router';
|
|
4
|
+
|
|
5
|
+
export class ControllerContractControllerRouterFactory<TRouter> {
|
|
6
|
+
constructor(private readonly integrator: RouterIntegratorFn<TRouter>) {}
|
|
7
|
+
|
|
8
|
+
createControllerContractControllerRouter<
|
|
9
|
+
TRoutes extends Record<any, ControllerContractController<any, any, any, any, any, any, TRouter>>,
|
|
10
|
+
>(routes: TRoutes) {
|
|
11
|
+
return new ControllerContractControllerRouter(this.integrator, routes);
|
|
12
|
+
}
|
|
13
|
+
}
|
package/src/classes/controller-contract-controller-router/controller-contract-controller-router.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { RouterIntegratorFn } from '../../types';
|
|
2
|
+
import type { ControllerContractController } from '../controller-contract-controller/controller-contract-controller';
|
|
3
|
+
|
|
4
|
+
export class ControllerContractControllerRouter<
|
|
5
|
+
TRouter,
|
|
6
|
+
TRoutes extends Record<any, ControllerContractController<any, any, any, any, any, any, TRouter>>,
|
|
7
|
+
> {
|
|
8
|
+
constructor(
|
|
9
|
+
private readonly integrator: RouterIntegratorFn<TRouter>,
|
|
10
|
+
private readonly routes: TRoutes,
|
|
11
|
+
) {}
|
|
12
|
+
|
|
13
|
+
getIntegratedRouter(): TRouter {
|
|
14
|
+
return this.integrator(this.routes);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { BuilderIntegratorFn, RouterIntegratorFn } from '../types';
|
|
2
|
+
import { ControllerContractControllerBuilder } from './controller-contract-controller-builder/controller-contract-controller-builder';
|
|
3
|
+
import { ControllerContractControllerRouterFactory } from './controller-contract-controller-router/controller-contract-controller-router-factory';
|
|
4
|
+
|
|
5
|
+
export class FrameworkIntegrationFactory<TFrameworkContext, TFrameworkInject, TFrameworkRouter> {
|
|
6
|
+
createControllerContractControllerBuilder(
|
|
7
|
+
injectableDefaultValue: TFrameworkInject,
|
|
8
|
+
integrator: BuilderIntegratorFn<TFrameworkContext, TFrameworkInject, TFrameworkRouter>,
|
|
9
|
+
) {
|
|
10
|
+
return new ControllerContractControllerBuilder<TFrameworkContext, TFrameworkInject, TFrameworkRouter>(
|
|
11
|
+
injectableDefaultValue,
|
|
12
|
+
integrator,
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
createControllerContractControllerRouterFactory(integrator: RouterIntegratorFn<TFrameworkRouter>) {
|
|
17
|
+
return new ControllerContractControllerRouterFactory<TFrameworkRouter>(integrator);
|
|
18
|
+
}
|
|
19
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -2,24 +2,24 @@ import type { InputChannel, Method, Output } from '@controller-contract/core';
|
|
|
2
2
|
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
3
3
|
import type { OutputFn, SanitizedOutputFn } from '../types';
|
|
4
4
|
|
|
5
|
-
export interface NullaryControllerContractSpec<
|
|
5
|
+
export interface NullaryControllerContractSpec<TFrameworkContext, TInject> {
|
|
6
6
|
readonly type: 'nullary';
|
|
7
7
|
readonly injectable: TInject;
|
|
8
8
|
readonly method: Method;
|
|
9
9
|
readonly path: string;
|
|
10
|
-
readonly outputFn: OutputFn<
|
|
10
|
+
readonly outputFn: OutputFn<TFrameworkContext, string, Output>;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export interface SanitizedControllerContractSpec<
|
|
13
|
+
export interface SanitizedControllerContractSpec<TFrameworkContext, TInject> {
|
|
14
14
|
readonly type: 'sanitized';
|
|
15
15
|
readonly injectable: TInject;
|
|
16
16
|
readonly method: Method;
|
|
17
17
|
readonly path: string;
|
|
18
18
|
readonly channel: InputChannel;
|
|
19
19
|
readonly schema: StandardSchemaV1;
|
|
20
|
-
readonly outputFn: SanitizedOutputFn<
|
|
20
|
+
readonly outputFn: SanitizedOutputFn<TFrameworkContext, string, unknown, Output>;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
export type ControllerContractSpec<
|
|
24
|
-
| NullaryControllerContractSpec<
|
|
25
|
-
| SanitizedControllerContractSpec<
|
|
23
|
+
export type ControllerContractSpec<TFrameworkContext, TInject> =
|
|
24
|
+
| NullaryControllerContractSpec<TFrameworkContext, TInject>
|
|
25
|
+
| SanitizedControllerContractSpec<TFrameworkContext, TInject>;
|
package/src/types/index.ts
CHANGED
|
@@ -1,26 +1,44 @@
|
|
|
1
|
-
import type { ParamsFrom } from '@controller-contract/core';
|
|
1
|
+
import type { ControllerContract, ParamsFrom } from '@controller-contract/core';
|
|
2
|
+
import type { ControllerContractController } from '../classes/controller-contract-controller/controller-contract-controller';
|
|
2
3
|
import type { ControllerContractSpec } from '../interfaces/ControllerContractSpec';
|
|
3
4
|
import type { outputs } from '../utils';
|
|
4
5
|
|
|
5
|
-
export type
|
|
6
|
+
export type BuilderIntegratorFn<TFrameworkContext, TFrameworkInject, TFrameworkRouter> = (
|
|
7
|
+
spec: ControllerContractSpec<TFrameworkContext, TFrameworkInject>,
|
|
8
|
+
) => TFrameworkRouter;
|
|
6
9
|
|
|
7
|
-
export type
|
|
10
|
+
export type RouterIntegratorFn<TRouter> = <
|
|
11
|
+
TRoutes extends Record<any, ControllerContractController<any, any, any, any, any, any, TRouter>>,
|
|
12
|
+
>(
|
|
13
|
+
routes: TRoutes,
|
|
14
|
+
) => TRouter;
|
|
8
15
|
|
|
9
16
|
export type Prettify<T> = {
|
|
10
17
|
[K in keyof T]: T[K];
|
|
11
18
|
} & {};
|
|
12
19
|
|
|
13
|
-
export type OutputFn<
|
|
20
|
+
export type OutputFn<TFrameworkContext, TPath extends string, TOutput> = (
|
|
14
21
|
context: Prettify<
|
|
15
|
-
|
|
22
|
+
TFrameworkContext & {
|
|
16
23
|
params: ParamsFrom<TPath>;
|
|
17
24
|
outputs: typeof outputs;
|
|
18
25
|
}
|
|
19
26
|
>,
|
|
20
27
|
) => Promise<TOutput>;
|
|
21
28
|
|
|
22
|
-
export type SanitizedOutputFn<
|
|
23
|
-
|
|
29
|
+
export type SanitizedOutputFn<TFrameworkContext, TPath extends string, TInput, TOutput> = OutputFn<
|
|
30
|
+
TFrameworkContext & { input: TInput },
|
|
24
31
|
TPath,
|
|
25
32
|
TOutput
|
|
26
33
|
>;
|
|
34
|
+
|
|
35
|
+
export type InferControllerContract<T> =
|
|
36
|
+
T extends ControllerContractController<infer M, infer P, any, infer Q, infer B, infer O, any>
|
|
37
|
+
? ControllerContract<M, P, ParamsFrom<P>, Q, B, O>
|
|
38
|
+
: never;
|
|
39
|
+
|
|
40
|
+
export type MapToControllerContract<TRoutes> = {
|
|
41
|
+
[TRouteName in Extract<keyof TRoutes, string> as Capitalize<TRouteName>]: InferControllerContract<
|
|
42
|
+
TRoutes[TRouteName]
|
|
43
|
+
>;
|
|
44
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ControllerContractControllerRouter } from '../classes/controller-contract-controller-router/controller-contract-controller-router';
|
|
2
|
+
import type { MapToControllerContract } from './index';
|
|
3
|
+
|
|
4
|
+
export type InferControllerContractsFromRouter<T> =
|
|
5
|
+
T extends ControllerContractControllerRouter<any, infer TRoutes> ? MapToControllerContract<TRoutes> : never;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import type { IntegratorFn, RouterAdapterFn } from '../types';
|
|
2
|
-
import { ControllerContractBuilder } from './ControllerContractBuilder';
|
|
3
|
-
import { ControllerContractRouter } from './ControllerContractRouter';
|
|
4
|
-
|
|
5
|
-
export class ControllerContractAdapterFactory<TContext, TInject, TProduct> {
|
|
6
|
-
createBuilder(injectableDefaultValue: TInject, integrator: IntegratorFn<TContext, TInject, TProduct>) {
|
|
7
|
-
return new ControllerContractBuilder<TContext, TInject, TProduct>(injectableDefaultValue, integrator);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
createRouter(routerAdapterFn: RouterAdapterFn<TProduct>) {
|
|
11
|
-
return new ControllerContractRouter<TProduct>(routerAdapterFn);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { Method } from '@controller-contract/core';
|
|
2
|
-
import type { IntegratorFn } from '../types';
|
|
3
|
-
import { PostEndpointStep } from './PostEndpointStep';
|
|
4
|
-
import { PostInjectStep } from './PostInjectStep';
|
|
5
|
-
|
|
6
|
-
export class ControllerContractBuilder<TContext, TInject, TProduct> {
|
|
7
|
-
constructor(
|
|
8
|
-
private readonly injectableDefaultValue: TInject,
|
|
9
|
-
private readonly integrator: IntegratorFn<TContext, TInject, TProduct>,
|
|
10
|
-
) {}
|
|
11
|
-
|
|
12
|
-
inject(injectable: TInject) {
|
|
13
|
-
return new PostInjectStep<TContext, TInject, TProduct>(injectable, this.integrator);
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
endpoint<const TMethod extends Method, const TPath extends string>(method: TMethod, path: TPath) {
|
|
17
|
-
return new PostEndpointStep<TContext, TInject, TProduct, TMethod, TPath>(
|
|
18
|
-
this.injectableDefaultValue,
|
|
19
|
-
this.integrator,
|
|
20
|
-
method,
|
|
21
|
-
path,
|
|
22
|
-
);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { RouterAdapterFn } from '../types';
|
|
2
|
-
|
|
3
|
-
export class ControllerContractRouter<TProduct> {
|
|
4
|
-
constructor(private readonly routerAdapterFn: RouterAdapterFn<TProduct>) {}
|
|
5
|
-
|
|
6
|
-
getRouter(routes: Record<string, TProduct>): TProduct {
|
|
7
|
-
return this.routerAdapterFn(routes);
|
|
8
|
-
}
|
|
9
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
ControllerContractProduct,
|
|
3
|
-
FailOutput,
|
|
4
|
-
InputChannel,
|
|
5
|
-
Method,
|
|
6
|
-
NoInput,
|
|
7
|
-
Output,
|
|
8
|
-
ParamsFrom,
|
|
9
|
-
} from '@controller-contract/core';
|
|
10
|
-
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
11
|
-
import type { NullaryControllerContractSpec } from '../interfaces/ControllerContractSpec';
|
|
12
|
-
import type { IntegratorFn, OutputFn } from '../types';
|
|
13
|
-
import { PostInputStep } from './PostInputStep';
|
|
14
|
-
|
|
15
|
-
export class PostEndpointStep<TContext, TInject, TProduct, const TMethod extends Method, const TPath extends string> {
|
|
16
|
-
constructor(
|
|
17
|
-
private readonly injectable: TInject,
|
|
18
|
-
private readonly integrator: IntegratorFn<TContext, TInject, TProduct>,
|
|
19
|
-
private readonly method: TMethod,
|
|
20
|
-
private readonly path: TPath,
|
|
21
|
-
) {}
|
|
22
|
-
|
|
23
|
-
input<const TChannel extends InputChannel, TInput>(channel: TChannel, schema: StandardSchemaV1<TInput>) {
|
|
24
|
-
return new PostInputStep<
|
|
25
|
-
TContext,
|
|
26
|
-
TInject,
|
|
27
|
-
TProduct,
|
|
28
|
-
TMethod,
|
|
29
|
-
TPath,
|
|
30
|
-
TChannel,
|
|
31
|
-
TInput,
|
|
32
|
-
FailOutput<Extract<keyof TInput, string>>
|
|
33
|
-
>(this.injectable, this.integrator, this.method, this.path, channel, schema);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
output<TOutput extends Output>(outputFn: OutputFn<TContext, TPath, TOutput>) {
|
|
37
|
-
const product = this.integrator(<NullaryControllerContractSpec<TContext, TInject>>{
|
|
38
|
-
type: 'nullary',
|
|
39
|
-
method: this.method,
|
|
40
|
-
path: this.path,
|
|
41
|
-
injectable: this.injectable,
|
|
42
|
-
outputFn,
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
return <ControllerContractProduct<TMethod, TPath, ParamsFrom<TPath>, NoInput, NoInput, TOutput, TProduct>>{
|
|
46
|
-
...() => product,
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { Method } from '@controller-contract/core';
|
|
2
|
-
import type { IntegratorFn } from '../types';
|
|
3
|
-
import { PostEndpointStep } from './PostEndpointStep';
|
|
4
|
-
|
|
5
|
-
export class PostInjectStep<TContext, TInject, TProduct> {
|
|
6
|
-
constructor(
|
|
7
|
-
private readonly injectable: TInject,
|
|
8
|
-
private readonly integrator: IntegratorFn<TContext, TInject, TProduct>,
|
|
9
|
-
) {}
|
|
10
|
-
|
|
11
|
-
endpoint<const TMethod extends Method, const TPath extends string>(method: TMethod, path: TPath) {
|
|
12
|
-
return new PostEndpointStep<TContext, TInject, TProduct, TMethod, TPath>(
|
|
13
|
-
this.injectable,
|
|
14
|
-
this.integrator,
|
|
15
|
-
method,
|
|
16
|
-
path,
|
|
17
|
-
);
|
|
18
|
-
}
|
|
19
|
-
}
|