@sentio/action 1.0.0 → 1.1.0-rc.1
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/lib/action-plugin.d.ts.map +1 -1
- package/lib/action-plugin.js +29 -0
- package/lib/action-plugin.js.map +1 -1
- package/lib/action-processor.d.ts +1 -11
- package/lib/action-processor.d.ts.map +1 -1
- package/lib/action-processor.js +3 -5
- package/lib/action-processor.js.map +1 -1
- package/lib/index.d.ts +4 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +4 -1
- package/lib/index.js.map +1 -1
- package/lib/schema.d.ts +51 -0
- package/lib/schema.d.ts.map +1 -0
- package/lib/schema.js +133 -0
- package/lib/schema.js.map +1 -0
- package/lib/tests/action.test.d.ts +2 -0
- package/lib/tests/action.test.d.ts.map +1 -0
- package/lib/tests/action.test.js.map +1 -0
- package/lib/typed-action-processor.d.ts +21 -0
- package/lib/typed-action-processor.d.ts.map +1 -0
- package/lib/typed-action-processor.js +49 -0
- package/lib/typed-action-processor.js.map +1 -0
- package/lib/types.d.ts +20 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +13 -0
- package/lib/types.js.map +1 -0
- package/package.json +3 -8
- package/src/action-plugin.ts +38 -0
- package/src/action-processor.ts +3 -24
- package/src/index.ts +4 -1
- package/src/schema.ts +178 -0
- package/src/typed-action-processor.ts +84 -0
- package/src/types.ts +30 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action-plugin.d.ts","sourceRoot":"","sources":["../src/action-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAA;AAE7B,OAAO,EAAE,MAAM,EAAiB,MAAM,iBAAiB,CAAA;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"action-plugin.d.ts","sourceRoot":"","sources":["../src/action-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAA;AAE7B,OAAO,EAAE,MAAM,EAAiB,MAAM,iBAAiB,CAAA;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAA;AAWtD,qBAAa,YAAa,SAAQ,MAAM;IACtC,MAAM;;MAAY;IAClB,IAAI,SAAkB;;IAMhB,SAAS,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IA6CvD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAcxC,cAAc;CAGrB"}
|
package/lib/action-plugin.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import fastify from 'fastify';
|
|
2
2
|
import { Plugin, PluginManager } from '@sentio/runtime';
|
|
3
3
|
import { ActionProcessorState } from './action-processor.js';
|
|
4
|
+
import { TypedActionProcessorState } from './typed-action-processor.js';
|
|
5
|
+
import { toJsonSchema } from './schema.js';
|
|
4
6
|
export class ActionPlugin extends Plugin {
|
|
5
7
|
server = fastify();
|
|
6
8
|
name = 'action-plugin';
|
|
@@ -8,6 +10,7 @@ export class ActionPlugin extends Plugin {
|
|
|
8
10
|
super();
|
|
9
11
|
}
|
|
10
12
|
async configure(config) {
|
|
13
|
+
const docs = [];
|
|
11
14
|
for (const processor of ActionProcessorState.INSTANCE.getValues()) {
|
|
12
15
|
for (const route of processor.route) {
|
|
13
16
|
this.server.route({
|
|
@@ -18,8 +21,34 @@ export class ActionPlugin extends Plugin {
|
|
|
18
21
|
return route.handler(request, context);
|
|
19
22
|
}
|
|
20
23
|
});
|
|
24
|
+
docs.push({
|
|
25
|
+
method: route.method,
|
|
26
|
+
url: route.url
|
|
27
|
+
});
|
|
21
28
|
}
|
|
22
29
|
}
|
|
30
|
+
for (const processor of TypedActionProcessorState.INSTANCE.getValues()) {
|
|
31
|
+
for (const route of processor.route) {
|
|
32
|
+
const schema = toJsonSchema(route.schema);
|
|
33
|
+
this.server.route({
|
|
34
|
+
method: route.method,
|
|
35
|
+
url: route.url,
|
|
36
|
+
schema,
|
|
37
|
+
handler: async (request, reply) => {
|
|
38
|
+
const context = {};
|
|
39
|
+
return route.handler(request, context);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
docs.push({
|
|
43
|
+
method: route.method,
|
|
44
|
+
url: route.url,
|
|
45
|
+
schema
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
this.server.get('/_docs', async (request, reply) => {
|
|
50
|
+
return docs;
|
|
51
|
+
});
|
|
23
52
|
}
|
|
24
53
|
async startServer(port) {
|
|
25
54
|
this.server.get('/healthz', async (request, reply) => {
|
package/lib/action-plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action-plugin.js","sourceRoot":"","sources":["../src/action-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAA;AAE7B,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAEvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"action-plugin.js","sourceRoot":"","sources":["../src/action-plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,5 @@
|
|
|
1
|
-
import { FastifyRequest } from 'fastify';
|
|
2
1
|
import { ListStateStorage } from '@sentio/runtime';
|
|
3
|
-
|
|
4
|
-
type HTTPMethod = 'DELETE' | 'GET' | 'HEAD' | 'PATCH' | 'POST' | 'PUT' | 'OPTIONS';
|
|
5
|
-
type ActionProcessorOption = {
|
|
6
|
-
name?: string;
|
|
7
|
-
};
|
|
8
|
-
type Route = {
|
|
9
|
-
method: HTTPMethod | HTTPMethod[];
|
|
10
|
-
url: string;
|
|
11
|
-
handler: ActionHandler<unknown>;
|
|
12
|
-
};
|
|
2
|
+
import { ActionHandler, HTTPMethod, Route, ActionProcessorOption } from './types.js';
|
|
13
3
|
interface IActionsProcessor<T> {
|
|
14
4
|
onAction<RESP>(handler: ActionHandler<RESP>): T;
|
|
15
5
|
onAction<RESP>(method: HTTPMethod | HTTPMethod[], handler: ActionHandler<RESP>): T;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action-processor.d.ts","sourceRoot":"","sources":["../src/action-processor.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"action-processor.d.ts","sourceRoot":"","sources":["../src/action-processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,EAAe,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAEjG,UAAU,iBAAiB,CAAC,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAE/C,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,GAAG,UAAU,EAAE,EAAE,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAElF,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,GAAG,UAAU,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;CAChG;AAED,qBAAa,oBAAqB,SAAQ,gBAAgB,CAAC,eAAe,CAAC;IACzE,MAAM,CAAC,QAAQ,uBAA6B;CAC7C;AAED,qBAAa,eAAgB,YAAW,iBAAiB,CAAC,eAAe,CAAC;IAE5D,QAAQ,CAAC,MAAM,CAAC,EAAE,qBAAqB;IADnD,KAAK,EAAE,KAAK,EAAE,CAAK;gBACE,MAAM,CAAC,EAAE,qBAAqB,YAAA;IAInD,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,eAAe;IAGxE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,eAAe;IAGzE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,eAAe;IAGxE,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,eAAe;IAG3E,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,eAAe;IAIxE,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,eAAe;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,GAAG,UAAU,EAAE,EAAE,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,eAAe;IAChG,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,GAAG,UAAU,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,eAAe;IAgB7G,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,qBAAqB;CAG5C"}
|
package/lib/action-processor.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import fastify from 'fastify';
|
|
2
1
|
import { ListStateStorage } from '@sentio/runtime';
|
|
3
|
-
|
|
2
|
+
import { HTTPMethods } from './types.js';
|
|
4
3
|
export class ActionProcessorState extends ListStateStorage {
|
|
5
4
|
static INSTANCE = new ActionProcessorState();
|
|
6
5
|
}
|
|
7
|
-
const server = fastify();
|
|
8
6
|
export class ActionProcessor {
|
|
9
7
|
option;
|
|
10
8
|
route = [];
|
|
@@ -30,11 +28,11 @@ export class ActionProcessor {
|
|
|
30
28
|
onAction(method, url, handler) {
|
|
31
29
|
if (typeof method === 'function') {
|
|
32
30
|
const handler = method;
|
|
33
|
-
this.route.push({ handler, url:
|
|
31
|
+
this.route.push({ handler, url: '*', method: HTTPMethods });
|
|
34
32
|
}
|
|
35
33
|
else if (typeof url === 'function') {
|
|
36
34
|
const handler = url;
|
|
37
|
-
this.route.push({ method: method, handler, url:
|
|
35
|
+
this.route.push({ method: method, handler, url: '*' });
|
|
38
36
|
}
|
|
39
37
|
else {
|
|
40
38
|
const h = handler;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"action-processor.js","sourceRoot":"","sources":["../src/action-processor.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"action-processor.js","sourceRoot":"","sources":["../src/action-processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,EAAoC,WAAW,EAAyB,MAAM,YAAY,CAAA;AAUjG,MAAM,OAAO,oBAAqB,SAAQ,gBAAiC;IACzE,MAAM,CAAC,QAAQ,GAAG,IAAI,oBAAoB,EAAE,CAAA;;AAG9C,MAAM,OAAO,eAAe;IAEL;IADrB,KAAK,GAAY,EAAE,CAAA;IACnB,YAAqB,MAA8B;QAA9B,WAAM,GAAN,MAAM,CAAwB;QACjD,oBAAoB,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC9C,CAAC;IAED,KAAK,CAAO,IAAY,EAAE,OAA4B;QACpD,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IAC5C,CAAC;IACD,MAAM,CAAO,IAAY,EAAE,OAA4B;QACrD,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IAC7C,CAAC;IACD,KAAK,CAAO,IAAY,EAAE,OAA4B;QACpD,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IAC5C,CAAC;IACD,QAAQ,CAAO,IAAY,EAAE,OAA4B;QACvD,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IAC/C,CAAC;IACD,KAAK,CAAO,IAAY,EAAE,OAA4B;QACpD,OAAO,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IAClD,CAAC;IAKD,QAAQ,CAAC,MAAe,EAAE,GAAa,EAAE,OAAiB;QACxD,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;YACjC,MAAM,OAAO,GAAG,MAAgC,CAAA;YAChD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAA;QAC7D,CAAC;aAAM,IAAI,OAAO,GAAG,KAAK,UAAU,EAAE,CAAC;YACrC,MAAM,OAAO,GAAG,GAA6B,CAAA;YAC7C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAoB,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAA;QACtE,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,OAAiC,CAAA;YAC3C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAoB,EAAE,GAAG,EAAE,GAAa,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,CAAA;QACnF,CAAC;QAED,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,OAA+B;QACzC,OAAO,IAAI,eAAe,CAAC,OAAO,CAAC,CAAA;IACrC,CAAC;CACF"}
|
package/lib/index.d.ts
CHANGED
|
@@ -2,5 +2,8 @@
|
|
|
2
2
|
* @module .
|
|
3
3
|
*/
|
|
4
4
|
export { ActionPlugin } from './action-plugin.js';
|
|
5
|
-
export
|
|
5
|
+
export { ActionProcessor } from './action-processor.js';
|
|
6
|
+
export * from './types.js';
|
|
7
|
+
export * from './schema.js';
|
|
8
|
+
export { TypedActionProcessor } from './typed-action-processor.js';
|
|
6
9
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAA"}
|
package/lib/index.js
CHANGED
|
@@ -2,5 +2,8 @@
|
|
|
2
2
|
* @module .
|
|
3
3
|
*/
|
|
4
4
|
export { ActionPlugin } from './action-plugin.js';
|
|
5
|
-
export
|
|
5
|
+
export { ActionProcessor } from './action-processor.js';
|
|
6
|
+
export * from './types.js';
|
|
7
|
+
export * from './schema.js';
|
|
8
|
+
export { TypedActionProcessor } from './typed-action-processor.js';
|
|
6
9
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAA"}
|
package/lib/schema.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export interface Type<T> {
|
|
2
|
+
type: string;
|
|
3
|
+
default?: T;
|
|
4
|
+
validate?: (value: any) => void;
|
|
5
|
+
toJSONSchema: () => any;
|
|
6
|
+
nullable?: boolean;
|
|
7
|
+
}
|
|
8
|
+
declare function string(defaultValue?: string): Type<string>;
|
|
9
|
+
declare function number(defaultValue?: number): Type<number>;
|
|
10
|
+
declare function nullable<T>(item: Type<T>): Type<T | null | undefined>;
|
|
11
|
+
declare function boolean(defaultValue?: boolean): Type<boolean>;
|
|
12
|
+
interface TypeArray<T> extends Type<T[]> {
|
|
13
|
+
type: 'array';
|
|
14
|
+
elementType: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function array<T>(item: Type<T>): TypeArray<T>;
|
|
17
|
+
export type TPropertyKey = string | number;
|
|
18
|
+
export type TProperties = Record<TPropertyKey, Type<any>>;
|
|
19
|
+
export interface TSchema<TBody extends Type<any>, TQuery extends Type<any>, TPath extends Type<any>> {
|
|
20
|
+
body?: TBody;
|
|
21
|
+
query?: TQuery;
|
|
22
|
+
params?: TPath;
|
|
23
|
+
}
|
|
24
|
+
export type TSchemNoBody<TQuery extends Type<any>, TPath extends Type<any>> = TSchema<never, TQuery, TPath>;
|
|
25
|
+
export declare function toJsonSchema(schema: TSchema<Type<any>, Type<any>, Type<any>>): {
|
|
26
|
+
body: any;
|
|
27
|
+
querystring: any;
|
|
28
|
+
params: any;
|
|
29
|
+
};
|
|
30
|
+
type Infer<T> = T extends TypeArray<infer U> ? U[] : T extends Type<infer U> ? U : never;
|
|
31
|
+
export type TypedActionRequest<TBody, TQuery, TPath> = {
|
|
32
|
+
body?: Infer<TBody>;
|
|
33
|
+
query?: Infer<TQuery>;
|
|
34
|
+
params?: Infer<TPath>;
|
|
35
|
+
headers: Record<string, string[]>;
|
|
36
|
+
};
|
|
37
|
+
export type TypedActionHandler<TBody, TQuery, TPath> = (request: TypedActionRequest<TBody, TQuery, TPath>, context: any) => Promise<any>;
|
|
38
|
+
export declare function object<T extends TProperties>(props: T): Type<{
|
|
39
|
+
[K in keyof T]: Infer<T[K]>;
|
|
40
|
+
}>;
|
|
41
|
+
export declare const T: {
|
|
42
|
+
string: typeof string;
|
|
43
|
+
number: typeof number;
|
|
44
|
+
boolean: typeof boolean;
|
|
45
|
+
array: typeof array;
|
|
46
|
+
object: typeof object;
|
|
47
|
+
nullable: typeof nullable;
|
|
48
|
+
optional: typeof nullable;
|
|
49
|
+
};
|
|
50
|
+
export {};
|
|
51
|
+
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
|
package/lib/schema.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { InvalidTypeError } from './types.js';
|
|
2
|
+
function string(defaultValue) {
|
|
3
|
+
return {
|
|
4
|
+
type: 'string',
|
|
5
|
+
default: defaultValue,
|
|
6
|
+
validate: (value) => {
|
|
7
|
+
if (typeof value !== 'string') {
|
|
8
|
+
throw new InvalidTypeError(value, 'string');
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
toJSONSchema: () => {
|
|
12
|
+
return {
|
|
13
|
+
type: 'string',
|
|
14
|
+
default: defaultValue
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function number(defaultValue) {
|
|
20
|
+
return {
|
|
21
|
+
type: 'number',
|
|
22
|
+
default: defaultValue,
|
|
23
|
+
validate: (value) => {
|
|
24
|
+
if (typeof value !== 'number') {
|
|
25
|
+
throw new InvalidTypeError(value, 'number');
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
toJSONSchema: () => {
|
|
29
|
+
return {
|
|
30
|
+
type: 'number',
|
|
31
|
+
default: defaultValue
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function nullable(item) {
|
|
37
|
+
return {
|
|
38
|
+
type: `Nuallable<${item.type}>`,
|
|
39
|
+
default: null,
|
|
40
|
+
nullable: true,
|
|
41
|
+
validate: (value) => {
|
|
42
|
+
if (value != null) {
|
|
43
|
+
item.validate?.(value);
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
toJSONSchema: () => {
|
|
47
|
+
return {
|
|
48
|
+
type: item.type,
|
|
49
|
+
required: false,
|
|
50
|
+
default: item.default
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function boolean(defaultValue) {
|
|
56
|
+
return {
|
|
57
|
+
type: 'boolean',
|
|
58
|
+
default: defaultValue,
|
|
59
|
+
validate: (value) => {
|
|
60
|
+
if (typeof value !== 'boolean') {
|
|
61
|
+
throw new InvalidTypeError(value, 'boolean');
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
toJSONSchema: () => {
|
|
65
|
+
return {
|
|
66
|
+
type: 'boolean',
|
|
67
|
+
required: true,
|
|
68
|
+
default: defaultValue
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export function array(item) {
|
|
74
|
+
return {
|
|
75
|
+
type: 'array',
|
|
76
|
+
elementType: item.type,
|
|
77
|
+
validate: (value) => {
|
|
78
|
+
if (!Array.isArray(value)) {
|
|
79
|
+
throw new InvalidTypeError(value, 'array');
|
|
80
|
+
}
|
|
81
|
+
for (const itemValue of value) {
|
|
82
|
+
item.validate?.(itemValue);
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
toJSONSchema: () => {
|
|
86
|
+
return {
|
|
87
|
+
type: 'array',
|
|
88
|
+
items: item.toJSONSchema?.()
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
export function toJsonSchema(schema) {
|
|
94
|
+
return {
|
|
95
|
+
body: schema.body?.toJSONSchema?.(),
|
|
96
|
+
querystring: schema.query?.toJSONSchema?.(),
|
|
97
|
+
params: schema.params?.toJSONSchema?.()
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
export function object(props) {
|
|
101
|
+
return {
|
|
102
|
+
type: 'object',
|
|
103
|
+
validate: (value) => {
|
|
104
|
+
if (typeof value !== 'object') {
|
|
105
|
+
throw new InvalidTypeError(value, 'object');
|
|
106
|
+
}
|
|
107
|
+
for (const key in props) {
|
|
108
|
+
props[key].validate?.(value[key]);
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
toJSONSchema: () => {
|
|
112
|
+
const properties = {};
|
|
113
|
+
for (const key in props) {
|
|
114
|
+
properties[key] = props[key].toJSONSchema?.();
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
type: 'object',
|
|
118
|
+
properties,
|
|
119
|
+
required: Object.keys(props).filter((key) => props[key].nullable != true)
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
export const T = {
|
|
125
|
+
string,
|
|
126
|
+
number,
|
|
127
|
+
boolean,
|
|
128
|
+
array,
|
|
129
|
+
object,
|
|
130
|
+
nullable,
|
|
131
|
+
optional: nullable
|
|
132
|
+
};
|
|
133
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action.test.d.ts","sourceRoot":"","sources":["../../src/tests/action.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"action.test.js","sourceRoot":"","sources":["../../src/tests/action.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ActionProcessorOption, Route } from './types.js';
|
|
2
|
+
import { ListStateStorage } from '@sentio/runtime';
|
|
3
|
+
import { Type, TSchema, TypedActionHandler, TSchemNoBody } from './schema.js';
|
|
4
|
+
export declare class TypedActionProcessorState extends ListStateStorage<TypedActionProcessor> {
|
|
5
|
+
static INSTANCE: TypedActionProcessorState;
|
|
6
|
+
}
|
|
7
|
+
export interface TypedRoute extends Route {
|
|
8
|
+
schema: TSchema<any, any, any>;
|
|
9
|
+
}
|
|
10
|
+
export declare class TypedActionProcessor {
|
|
11
|
+
readonly option?: ActionProcessorOption | undefined;
|
|
12
|
+
route: TypedRoute[];
|
|
13
|
+
constructor(option?: ActionProcessorOption | undefined);
|
|
14
|
+
static bind(options?: ActionProcessorOption): TypedActionProcessor;
|
|
15
|
+
onGet<TQuery extends Type<any>, TPath extends Type<any>>(path: string, schema: TSchemNoBody<TQuery, TPath>, handler: TypedActionHandler<never, TQuery, TPath>): TypedActionProcessor;
|
|
16
|
+
onPost<TBody extends Type<any>, TQuery extends Type<any>, TPath extends Type<any>>(path: string, schema: TSchema<TBody, TQuery, TPath>, handler: TypedActionHandler<TBody, TQuery, TPath>): TypedActionProcessor;
|
|
17
|
+
onPut<TBody extends Type<any>, TQuery extends Type<any>, TPath extends Type<any>>(path: string, schema: TSchema<TBody, TQuery, TPath>, handler: TypedActionHandler<TBody, TQuery, TPath>): TypedActionProcessor;
|
|
18
|
+
onDelete<TQuery extends Type<any>, TPath extends Type<any>>(path: string, schema: TSchemNoBody<TQuery, TPath>, handler: TypedActionHandler<never, TQuery, TPath>): TypedActionProcessor;
|
|
19
|
+
onAction<TBody extends Type<any>, TQuery extends Type<any>, TPath extends Type<any>>(method: unknown, path: string, schema: TSchema<TBody, TQuery, TPath>, handler: TypedActionHandler<TBody, TQuery, TPath>): TypedActionProcessor;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=typed-action-processor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typed-action-processor.d.ts","sourceRoot":"","sources":["../src/typed-action-processor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAc,KAAK,EAAE,MAAM,YAAY,CAAA;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,kBAAkB,EAAsB,YAAY,EAAE,MAAM,aAAa,CAAA;AAEjG,qBAAa,yBAA0B,SAAQ,gBAAgB,CAAC,oBAAoB,CAAC;IACnF,MAAM,CAAC,QAAQ,4BAAkC;CAClD;AAED,MAAM,WAAW,UAAW,SAAQ,KAAK;IACvC,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;CAC/B;AAED,qBAAa,oBAAoB;IAGnB,QAAQ,CAAC,MAAM,CAAC,EAAE,qBAAqB;IAFnD,KAAK,EAAE,UAAU,EAAE,CAAK;gBAEH,MAAM,CAAC,EAAE,qBAAqB,YAAA;IAInD,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,qBAAqB;IAI3C,KAAK,CAAC,MAAM,SAAS,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,SAAS,IAAI,CAAC,GAAG,CAAC,EACrD,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,EACnC,OAAO,EAAE,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAChD,oBAAoB;IAIvB,MAAM,CAAC,KAAK,SAAS,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,SAAS,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,SAAS,IAAI,CAAC,GAAG,CAAC,EAC/E,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EACrC,OAAO,EAAE,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAChD,oBAAoB;IAIvB,KAAK,CAAC,KAAK,SAAS,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,SAAS,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,SAAS,IAAI,CAAC,GAAG,CAAC,EAC9E,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EACrC,OAAO,EAAE,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAChD,oBAAoB;IAIvB,QAAQ,CAAC,MAAM,SAAS,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,SAAS,IAAI,CAAC,GAAG,CAAC,EACxD,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,EACnC,OAAO,EAAE,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAChD,oBAAoB;IAIvB,QAAQ,CAAC,KAAK,SAAS,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,SAAS,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,SAAS,IAAI,CAAC,GAAG,CAAC,EACjF,MAAM,EAAE,OAAO,EACf,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EACrC,OAAO,EAAE,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAChD,oBAAoB;CAuBxB"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ListStateStorage } from '@sentio/runtime';
|
|
2
|
+
export class TypedActionProcessorState extends ListStateStorage {
|
|
3
|
+
static INSTANCE = new TypedActionProcessorState();
|
|
4
|
+
}
|
|
5
|
+
export class TypedActionProcessor {
|
|
6
|
+
option;
|
|
7
|
+
route = [];
|
|
8
|
+
constructor(option) {
|
|
9
|
+
this.option = option;
|
|
10
|
+
TypedActionProcessorState.INSTANCE.addValue(this);
|
|
11
|
+
}
|
|
12
|
+
static bind(options) {
|
|
13
|
+
return new TypedActionProcessor(options);
|
|
14
|
+
}
|
|
15
|
+
onGet(path, schema, handler) {
|
|
16
|
+
return this.onAction('GET', path, schema, handler);
|
|
17
|
+
}
|
|
18
|
+
onPost(path, schema, handler) {
|
|
19
|
+
return this.onAction('POST', path, schema, handler);
|
|
20
|
+
}
|
|
21
|
+
onPut(path, schema, handler) {
|
|
22
|
+
return this.onAction('PUT', path, schema, handler);
|
|
23
|
+
}
|
|
24
|
+
onDelete(path, schema, handler) {
|
|
25
|
+
return this.onAction('PUT', path, schema, handler);
|
|
26
|
+
}
|
|
27
|
+
onAction(method, path, schema, handler) {
|
|
28
|
+
this.route.push({
|
|
29
|
+
method: method,
|
|
30
|
+
schema,
|
|
31
|
+
url: path,
|
|
32
|
+
handler: async (request, context) => {
|
|
33
|
+
// no need, fastify should do validate
|
|
34
|
+
// schema.body?.validate?.(request.body)
|
|
35
|
+
// schema.query?.validate?.(request.query)
|
|
36
|
+
// schema.params?.validate?.(request.params)
|
|
37
|
+
const req = {
|
|
38
|
+
body: request.body,
|
|
39
|
+
query: request.query,
|
|
40
|
+
params: request.params,
|
|
41
|
+
headers: request.headers
|
|
42
|
+
};
|
|
43
|
+
return handler(req, context);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
return this;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=typed-action-processor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typed-action-processor.js","sourceRoot":"","sources":["../src/typed-action-processor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAGlD,MAAM,OAAO,yBAA0B,SAAQ,gBAAsC;IACnF,MAAM,CAAC,QAAQ,GAAG,IAAI,yBAAyB,EAAE,CAAA;;AAOnD,MAAM,OAAO,oBAAoB;IAGV;IAFrB,KAAK,GAAiB,EAAE,CAAA;IAExB,YAAqB,MAA8B;QAA9B,WAAM,GAAN,MAAM,CAAwB;QACjD,yBAAyB,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;IACnD,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,OAA+B;QACzC,OAAO,IAAI,oBAAoB,CAAC,OAAO,CAAC,CAAA;IAC1C,CAAC;IAED,KAAK,CACH,IAAY,EACZ,MAAmC,EACnC,OAAiD;QAEjD,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;IACpD,CAAC;IAED,MAAM,CACJ,IAAY,EACZ,MAAqC,EACrC,OAAiD;QAEjD,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;IACrD,CAAC;IAED,KAAK,CACH,IAAY,EACZ,MAAqC,EACrC,OAAiD;QAEjD,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;IACpD,CAAC;IAED,QAAQ,CACN,IAAY,EACZ,MAAmC,EACnC,OAAiD;QAEjD,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,CAAA;IACpD,CAAC;IAED,QAAQ,CACN,MAAe,EACf,IAAY,EACZ,MAAqC,EACrC,OAAiD;QAEjD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YACd,MAAM,EAAE,MAAoB;YAC5B,MAAM;YACN,GAAG,EAAE,IAAI;YACT,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;gBAClC,sCAAsC;gBACtC,wCAAwC;gBACxC,0CAA0C;gBAC1C,4CAA4C;gBAE5C,MAAM,GAAG,GAAG;oBACV,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,OAAO,EAAE,OAAO,CAAC,OAAO;iBACmB,CAAA;gBAE7C,OAAO,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;YAC9B,CAAC;SACF,CAAC,CAAA;QACF,OAAO,IAAI,CAAA;IACb,CAAC;CACF"}
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { FastifyRequest } from 'fastify';
|
|
2
|
+
export type ActionRequest = FastifyRequest;
|
|
3
|
+
export type ActionHandler<RESP> = (request: ActionRequest, context: any) => Promise<RESP>;
|
|
4
|
+
export type HTTPMethod = 'DELETE' | 'GET' | 'HEAD' | 'PATCH' | 'POST' | 'PUT' | 'OPTIONS';
|
|
5
|
+
export declare const HTTPMethods: HTTPMethod[];
|
|
6
|
+
export type ActionProcessorOption = {
|
|
7
|
+
name?: string;
|
|
8
|
+
};
|
|
9
|
+
export type Route = {
|
|
10
|
+
method: HTTPMethod | HTTPMethod[];
|
|
11
|
+
url: string;
|
|
12
|
+
handler: ActionHandler<unknown>;
|
|
13
|
+
};
|
|
14
|
+
export declare class InvalidTypeError extends Error {
|
|
15
|
+
readonly value: any;
|
|
16
|
+
readonly expected: string;
|
|
17
|
+
readonly valueType: string;
|
|
18
|
+
constructor(value: any, expected: string);
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAE7C,MAAM,MAAM,aAAa,GAAG,cAAc,CAAA;AAE1C,MAAM,MAAM,aAAa,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAEzF,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAA;AAEzF,eAAO,MAAM,WAAW,EAAE,UAAU,EAAiE,CAAA;AAErG,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAED,MAAM,MAAM,KAAK,GAAG;IAClB,MAAM,EAAE,UAAU,GAAG,UAAU,EAAE,CAAA;IACjC,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,CAAA;CAChC,CAAA;AAED,qBAAa,gBAAiB,SAAQ,KAAK;IAGvC,QAAQ,CAAC,KAAK,EAAE,GAAG;IACnB,QAAQ,CAAC,QAAQ,EAAE,MAAM;IAH3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;gBAEf,KAAK,EAAE,GAAG,EACV,QAAQ,EAAE,MAAM;CAK5B"}
|
package/lib/types.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const HTTPMethods = ['DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT', 'OPTIONS'];
|
|
2
|
+
export class InvalidTypeError extends Error {
|
|
3
|
+
value;
|
|
4
|
+
expected;
|
|
5
|
+
valueType;
|
|
6
|
+
constructor(value, expected) {
|
|
7
|
+
super(`Invalid type ${typeof value}, expected ${expected}`);
|
|
8
|
+
this.value = value;
|
|
9
|
+
this.expected = expected;
|
|
10
|
+
this.valueType = typeof value;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=types.js.map
|
package/lib/types.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAQA,MAAM,CAAC,MAAM,WAAW,GAAiB,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,CAAA;AAYrG,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAG9B;IACA;IAHF,SAAS,CAAQ;IAC1B,YACW,KAAU,EACV,QAAgB;QAEzB,KAAK,CAAC,gBAAgB,OAAO,KAAK,cAAc,QAAQ,EAAE,CAAC,CAAA;QAHlD,UAAK,GAAL,KAAK,CAAK;QACV,aAAQ,GAAR,QAAQ,CAAQ;QAGzB,IAAI,CAAC,SAAS,GAAG,OAAO,KAAK,CAAA;IAC/B,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentio/action",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.1.0-rc.1",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -13,11 +13,8 @@
|
|
|
13
13
|
],
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"fastify": "^5.1.0",
|
|
16
|
-
"@sentio/protos": "2.
|
|
17
|
-
"@sentio/runtime": "^2.
|
|
18
|
-
},
|
|
19
|
-
"peerDependencies": {
|
|
20
|
-
"tsup": "npm:@sentio/tsup@^6.7.6"
|
|
16
|
+
"@sentio/protos": "2.47.0-rc.1",
|
|
17
|
+
"@sentio/runtime": "^2.47.0-rc.1"
|
|
21
18
|
},
|
|
22
19
|
"devDependencies": {
|
|
23
20
|
"prettier": "^3.2.4",
|
|
@@ -31,8 +28,6 @@
|
|
|
31
28
|
"build": "pnpm gen && pnpm compile",
|
|
32
29
|
"build:all": "pnpm --filter=$(node -p \"require('./package.json').name\")... build",
|
|
33
30
|
"build:bundle": "pnpm gen && pnpm bundle && pnpm bundle:dts",
|
|
34
|
-
"bundle": "tsup --config src/bundle.config.ts && cp src/tsup.config.ts lib",
|
|
35
|
-
"bundle:dts": "tsc --emitDeclarationOnly --declaration",
|
|
36
31
|
"compile": "tsc && cp src/tsup.config.ts lib",
|
|
37
32
|
"gen": "echo",
|
|
38
33
|
"test": "glob -c 'tsx --test' '**/*.test.ts'"
|
package/src/action-plugin.ts
CHANGED
|
@@ -3,6 +3,14 @@ import fastify from 'fastify'
|
|
|
3
3
|
import { Plugin, PluginManager } from '@sentio/runtime'
|
|
4
4
|
import { ProcessConfigResponse } from '@sentio/protos'
|
|
5
5
|
import { ActionProcessorState } from './action-processor.js'
|
|
6
|
+
import { TypedActionProcessorState } from './typed-action-processor.js'
|
|
7
|
+
import { toJsonSchema } from './schema.js'
|
|
8
|
+
|
|
9
|
+
interface RouteDoc {
|
|
10
|
+
method: string | string[]
|
|
11
|
+
url: string
|
|
12
|
+
schema?: any
|
|
13
|
+
}
|
|
6
14
|
|
|
7
15
|
export class ActionPlugin extends Plugin {
|
|
8
16
|
server = fastify()
|
|
@@ -13,6 +21,8 @@ export class ActionPlugin extends Plugin {
|
|
|
13
21
|
}
|
|
14
22
|
|
|
15
23
|
async configure(config: ProcessConfigResponse): Promise<void> {
|
|
24
|
+
const docs: RouteDoc[] = []
|
|
25
|
+
|
|
16
26
|
for (const processor of ActionProcessorState.INSTANCE.getValues()) {
|
|
17
27
|
for (const route of processor.route) {
|
|
18
28
|
this.server.route({
|
|
@@ -23,8 +33,36 @@ export class ActionPlugin extends Plugin {
|
|
|
23
33
|
return route.handler(request, context)
|
|
24
34
|
}
|
|
25
35
|
})
|
|
36
|
+
docs.push({
|
|
37
|
+
method: route.method,
|
|
38
|
+
url: route.url
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
for (const processor of TypedActionProcessorState.INSTANCE.getValues()) {
|
|
44
|
+
for (const route of processor.route) {
|
|
45
|
+
const schema = toJsonSchema(route.schema)
|
|
46
|
+
this.server.route({
|
|
47
|
+
method: route.method,
|
|
48
|
+
url: route.url,
|
|
49
|
+
schema,
|
|
50
|
+
handler: async (request, reply) => {
|
|
51
|
+
const context = {}
|
|
52
|
+
return route.handler(request, context)
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
docs.push({
|
|
56
|
+
method: route.method,
|
|
57
|
+
url: route.url,
|
|
58
|
+
schema
|
|
59
|
+
})
|
|
26
60
|
}
|
|
27
61
|
}
|
|
62
|
+
|
|
63
|
+
this.server.get('/_docs', async (request, reply) => {
|
|
64
|
+
return docs
|
|
65
|
+
})
|
|
28
66
|
}
|
|
29
67
|
|
|
30
68
|
async startServer(port: number): Promise<void> {
|
package/src/action-processor.ts
CHANGED
|
@@ -1,21 +1,5 @@
|
|
|
1
|
-
import fastify, { FastifyRequest } from 'fastify'
|
|
2
1
|
import { ListStateStorage } from '@sentio/runtime'
|
|
3
|
-
|
|
4
|
-
type ActionHandler<RESP> = (request: FastifyRequest, context: any) => Promise<RESP>
|
|
5
|
-
|
|
6
|
-
type HTTPMethod = 'DELETE' | 'GET' | 'HEAD' | 'PATCH' | 'POST' | 'PUT' | 'OPTIONS'
|
|
7
|
-
|
|
8
|
-
const HTTPMethods: HTTPMethod[] = ['DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT', 'OPTIONS']
|
|
9
|
-
|
|
10
|
-
type ActionProcessorOption = {
|
|
11
|
-
name?: string
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
type Route = {
|
|
15
|
-
method: HTTPMethod | HTTPMethod[]
|
|
16
|
-
url: string
|
|
17
|
-
handler: ActionHandler<unknown>
|
|
18
|
-
}
|
|
2
|
+
import { ActionHandler, HTTPMethod, Route, HTTPMethods, ActionProcessorOption } from './types.js'
|
|
19
3
|
|
|
20
4
|
interface IActionsProcessor<T> {
|
|
21
5
|
onAction<RESP>(handler: ActionHandler<RESP>): T
|
|
@@ -29,8 +13,6 @@ export class ActionProcessorState extends ListStateStorage<ActionProcessor> {
|
|
|
29
13
|
static INSTANCE = new ActionProcessorState()
|
|
30
14
|
}
|
|
31
15
|
|
|
32
|
-
const server = fastify()
|
|
33
|
-
|
|
34
16
|
export class ActionProcessor implements IActionsProcessor<ActionProcessor> {
|
|
35
17
|
route: Route[] = []
|
|
36
18
|
constructor(readonly option?: ActionProcessorOption) {
|
|
@@ -59,10 +41,10 @@ export class ActionProcessor implements IActionsProcessor<ActionProcessor> {
|
|
|
59
41
|
onAction(method: unknown, url?: unknown, handler?: unknown): ActionProcessor {
|
|
60
42
|
if (typeof method === 'function') {
|
|
61
43
|
const handler = method as ActionHandler<unknown>
|
|
62
|
-
this.route.push({ handler, url:
|
|
44
|
+
this.route.push({ handler, url: '*', method: HTTPMethods })
|
|
63
45
|
} else if (typeof url === 'function') {
|
|
64
46
|
const handler = url as ActionHandler<unknown>
|
|
65
|
-
this.route.push({ method: method as HTTPMethod, handler, url:
|
|
47
|
+
this.route.push({ method: method as HTTPMethod, handler, url: '*' })
|
|
66
48
|
} else {
|
|
67
49
|
const h = handler as ActionHandler<unknown>
|
|
68
50
|
this.route.push({ method: method as HTTPMethod, url: url as string, handler: h })
|
|
@@ -75,6 +57,3 @@ export class ActionProcessor implements IActionsProcessor<ActionProcessor> {
|
|
|
75
57
|
return new ActionProcessor(options)
|
|
76
58
|
}
|
|
77
59
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
package/src/index.ts
CHANGED
|
@@ -3,4 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
export { ActionPlugin } from './action-plugin.js'
|
|
6
|
-
export
|
|
6
|
+
export { ActionProcessor } from './action-processor.js'
|
|
7
|
+
export * from './types.js'
|
|
8
|
+
export * from './schema.js'
|
|
9
|
+
export { TypedActionProcessor } from './typed-action-processor.js'
|
package/src/schema.ts
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { InvalidTypeError } from './types.js'
|
|
2
|
+
|
|
3
|
+
export interface Type<T> {
|
|
4
|
+
type: string
|
|
5
|
+
default?: T
|
|
6
|
+
validate?: (value: any) => void
|
|
7
|
+
toJSONSchema: () => any
|
|
8
|
+
nullable?: boolean
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function string(defaultValue?: string): Type<string> {
|
|
12
|
+
return {
|
|
13
|
+
type: 'string',
|
|
14
|
+
default: defaultValue,
|
|
15
|
+
validate: (value: any) => {
|
|
16
|
+
if (typeof value !== 'string') {
|
|
17
|
+
throw new InvalidTypeError(value, 'string')
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
toJSONSchema: () => {
|
|
21
|
+
return {
|
|
22
|
+
type: 'string',
|
|
23
|
+
default: defaultValue
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function number(defaultValue?: number): Type<number> {
|
|
30
|
+
return {
|
|
31
|
+
type: 'number',
|
|
32
|
+
default: defaultValue,
|
|
33
|
+
validate: (value: any) => {
|
|
34
|
+
if (typeof value !== 'number') {
|
|
35
|
+
throw new InvalidTypeError(value, 'number')
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
toJSONSchema: () => {
|
|
39
|
+
return {
|
|
40
|
+
type: 'number',
|
|
41
|
+
default: defaultValue
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function nullable<T>(item: Type<T>): Type<T | null | undefined> {
|
|
48
|
+
return {
|
|
49
|
+
type: `Nuallable<${item.type}>`,
|
|
50
|
+
default: null,
|
|
51
|
+
nullable: true,
|
|
52
|
+
validate: (value: any) => {
|
|
53
|
+
if (value != null) {
|
|
54
|
+
item.validate?.(value)
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
toJSONSchema: () => {
|
|
58
|
+
return {
|
|
59
|
+
type: item.type,
|
|
60
|
+
required: false,
|
|
61
|
+
default: item.default
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function boolean(defaultValue?: boolean): Type<boolean> {
|
|
68
|
+
return {
|
|
69
|
+
type: 'boolean',
|
|
70
|
+
default: defaultValue,
|
|
71
|
+
validate: (value: any) => {
|
|
72
|
+
if (typeof value !== 'boolean') {
|
|
73
|
+
throw new InvalidTypeError(value, 'boolean')
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
toJSONSchema: () => {
|
|
77
|
+
return {
|
|
78
|
+
type: 'boolean',
|
|
79
|
+
required: true,
|
|
80
|
+
default: defaultValue
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
interface TypeArray<T> extends Type<T[]> {
|
|
87
|
+
type: 'array'
|
|
88
|
+
elementType: string
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function array<T>(item: Type<T>): TypeArray<T> {
|
|
92
|
+
return {
|
|
93
|
+
type: 'array',
|
|
94
|
+
elementType: item.type,
|
|
95
|
+
validate: (value: any) => {
|
|
96
|
+
if (!Array.isArray(value)) {
|
|
97
|
+
throw new InvalidTypeError(value, 'array')
|
|
98
|
+
}
|
|
99
|
+
for (const itemValue of value) {
|
|
100
|
+
item.validate?.(itemValue)
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
toJSONSchema: () => {
|
|
104
|
+
return {
|
|
105
|
+
type: 'array',
|
|
106
|
+
items: item.toJSONSchema?.()
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export type TPropertyKey = string | number
|
|
113
|
+
export type TProperties = Record<TPropertyKey, Type<any>>
|
|
114
|
+
|
|
115
|
+
export interface TSchema<TBody extends Type<any>, TQuery extends Type<any>, TPath extends Type<any>> {
|
|
116
|
+
body?: TBody
|
|
117
|
+
query?: TQuery
|
|
118
|
+
params?: TPath
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export type TSchemNoBody<TQuery extends Type<any>, TPath extends Type<any>> = TSchema<never, TQuery, TPath>
|
|
122
|
+
|
|
123
|
+
export function toJsonSchema(schema: TSchema<Type<any>, Type<any>, Type<any>>) {
|
|
124
|
+
return {
|
|
125
|
+
body: schema.body?.toJSONSchema?.(),
|
|
126
|
+
querystring: schema.query?.toJSONSchema?.(),
|
|
127
|
+
params: schema.params?.toJSONSchema?.()
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
type Infer<T> = T extends TypeArray<infer U> ? U[] : T extends Type<infer U> ? U : never
|
|
132
|
+
|
|
133
|
+
export type TypedActionRequest<TBody, TQuery, TPath> = {
|
|
134
|
+
body?: Infer<TBody>
|
|
135
|
+
query?: Infer<TQuery>
|
|
136
|
+
params?: Infer<TPath>
|
|
137
|
+
headers: Record<string, string[]>
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export type TypedActionHandler<TBody, TQuery, TPath> = (
|
|
141
|
+
request: TypedActionRequest<TBody, TQuery, TPath>,
|
|
142
|
+
context: any
|
|
143
|
+
) => Promise<any>
|
|
144
|
+
|
|
145
|
+
export function object<T extends TProperties>(props: T): Type<{ [K in keyof T]: Infer<T[K]> }> {
|
|
146
|
+
return {
|
|
147
|
+
type: 'object',
|
|
148
|
+
validate: (value: any) => {
|
|
149
|
+
if (typeof value !== 'object') {
|
|
150
|
+
throw new InvalidTypeError(value, 'object')
|
|
151
|
+
}
|
|
152
|
+
for (const key in props) {
|
|
153
|
+
props[key as TPropertyKey].validate?.(value[key])
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
toJSONSchema: () => {
|
|
157
|
+
const properties: Record<string, any> = {}
|
|
158
|
+
for (const key in props) {
|
|
159
|
+
properties[key] = props[key as TPropertyKey].toJSONSchema?.()
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
type: 'object',
|
|
163
|
+
properties,
|
|
164
|
+
required: Object.keys(props).filter((key) => props[key as TPropertyKey].nullable != true)
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export const T = {
|
|
171
|
+
string,
|
|
172
|
+
number,
|
|
173
|
+
boolean,
|
|
174
|
+
array,
|
|
175
|
+
object,
|
|
176
|
+
nullable,
|
|
177
|
+
optional: nullable
|
|
178
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { ActionProcessorOption, HTTPMethod, Route } from './types.js'
|
|
2
|
+
import { ListStateStorage } from '@sentio/runtime'
|
|
3
|
+
import { Type, TSchema, TypedActionHandler, TypedActionRequest, TSchemNoBody } from './schema.js'
|
|
4
|
+
|
|
5
|
+
export class TypedActionProcessorState extends ListStateStorage<TypedActionProcessor> {
|
|
6
|
+
static INSTANCE = new TypedActionProcessorState()
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface TypedRoute extends Route {
|
|
10
|
+
schema: TSchema<any, any, any>
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export class TypedActionProcessor {
|
|
14
|
+
route: TypedRoute[] = []
|
|
15
|
+
|
|
16
|
+
constructor(readonly option?: ActionProcessorOption) {
|
|
17
|
+
TypedActionProcessorState.INSTANCE.addValue(this)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static bind(options?: ActionProcessorOption) {
|
|
21
|
+
return new TypedActionProcessor(options)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
onGet<TQuery extends Type<any>, TPath extends Type<any>>(
|
|
25
|
+
path: string,
|
|
26
|
+
schema: TSchemNoBody<TQuery, TPath>,
|
|
27
|
+
handler: TypedActionHandler<never, TQuery, TPath>
|
|
28
|
+
): TypedActionProcessor {
|
|
29
|
+
return this.onAction('GET', path, schema, handler)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
onPost<TBody extends Type<any>, TQuery extends Type<any>, TPath extends Type<any>>(
|
|
33
|
+
path: string,
|
|
34
|
+
schema: TSchema<TBody, TQuery, TPath>,
|
|
35
|
+
handler: TypedActionHandler<TBody, TQuery, TPath>
|
|
36
|
+
): TypedActionProcessor {
|
|
37
|
+
return this.onAction('POST', path, schema, handler)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
onPut<TBody extends Type<any>, TQuery extends Type<any>, TPath extends Type<any>>(
|
|
41
|
+
path: string,
|
|
42
|
+
schema: TSchema<TBody, TQuery, TPath>,
|
|
43
|
+
handler: TypedActionHandler<TBody, TQuery, TPath>
|
|
44
|
+
): TypedActionProcessor {
|
|
45
|
+
return this.onAction('PUT', path, schema, handler)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
onDelete<TQuery extends Type<any>, TPath extends Type<any>>(
|
|
49
|
+
path: string,
|
|
50
|
+
schema: TSchemNoBody<TQuery, TPath>,
|
|
51
|
+
handler: TypedActionHandler<never, TQuery, TPath>
|
|
52
|
+
): TypedActionProcessor {
|
|
53
|
+
return this.onAction('PUT', path, schema, handler)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
onAction<TBody extends Type<any>, TQuery extends Type<any>, TPath extends Type<any>>(
|
|
57
|
+
method: unknown,
|
|
58
|
+
path: string,
|
|
59
|
+
schema: TSchema<TBody, TQuery, TPath>,
|
|
60
|
+
handler: TypedActionHandler<TBody, TQuery, TPath>
|
|
61
|
+
): TypedActionProcessor {
|
|
62
|
+
this.route.push({
|
|
63
|
+
method: method as HTTPMethod,
|
|
64
|
+
schema,
|
|
65
|
+
url: path,
|
|
66
|
+
handler: async (request, context) => {
|
|
67
|
+
// no need, fastify should do validate
|
|
68
|
+
// schema.body?.validate?.(request.body)
|
|
69
|
+
// schema.query?.validate?.(request.query)
|
|
70
|
+
// schema.params?.validate?.(request.params)
|
|
71
|
+
|
|
72
|
+
const req = {
|
|
73
|
+
body: request.body,
|
|
74
|
+
query: request.query,
|
|
75
|
+
params: request.params,
|
|
76
|
+
headers: request.headers
|
|
77
|
+
} as TypedActionRequest<TBody, TQuery, TPath>
|
|
78
|
+
|
|
79
|
+
return handler(req, context)
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
return this
|
|
83
|
+
}
|
|
84
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { FastifyRequest } from 'fastify'
|
|
2
|
+
|
|
3
|
+
export type ActionRequest = FastifyRequest
|
|
4
|
+
|
|
5
|
+
export type ActionHandler<RESP> = (request: ActionRequest, context: any) => Promise<RESP>
|
|
6
|
+
|
|
7
|
+
export type HTTPMethod = 'DELETE' | 'GET' | 'HEAD' | 'PATCH' | 'POST' | 'PUT' | 'OPTIONS'
|
|
8
|
+
|
|
9
|
+
export const HTTPMethods: HTTPMethod[] = ['DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT', 'OPTIONS']
|
|
10
|
+
|
|
11
|
+
export type ActionProcessorOption = {
|
|
12
|
+
name?: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type Route = {
|
|
16
|
+
method: HTTPMethod | HTTPMethod[]
|
|
17
|
+
url: string
|
|
18
|
+
handler: ActionHandler<unknown>
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export class InvalidTypeError extends Error {
|
|
22
|
+
readonly valueType: string
|
|
23
|
+
constructor(
|
|
24
|
+
readonly value: any,
|
|
25
|
+
readonly expected: string
|
|
26
|
+
) {
|
|
27
|
+
super(`Invalid type ${typeof value}, expected ${expected}`)
|
|
28
|
+
this.valueType = typeof value
|
|
29
|
+
}
|
|
30
|
+
}
|