@owlmeans/entrypoint 0.1.3
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/README.md +95 -0
- package/build/consts.d.ts +7 -0
- package/build/consts.d.ts.map +1 -0
- package/build/consts.js +8 -0
- package/build/consts.js.map +1 -0
- package/build/entrypoint.d.ts +5 -0
- package/build/entrypoint.d.ts.map +1 -0
- package/build/entrypoint.js +80 -0
- package/build/entrypoint.js.map +1 -0
- package/build/filter.d.ts +8 -0
- package/build/filter.d.ts.map +1 -0
- package/build/filter.js +20 -0
- package/build/filter.js.map +1 -0
- package/build/helper.d.ts +7 -0
- package/build/helper.d.ts.map +1 -0
- package/build/helper.js +26 -0
- package/build/helper.js.map +1 -0
- package/build/index.d.ts +6 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +5 -0
- package/build/index.js.map +1 -0
- package/build/types.d.ts +81 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +2 -0
- package/build/types.js.map +1 -0
- package/build/utils/entrypoint.d.ts +3 -0
- package/build/utils/entrypoint.d.ts.map +1 -0
- package/build/utils/entrypoint.js +2 -0
- package/build/utils/entrypoint.js.map +1 -0
- package/build/utils/index.d.ts +3 -0
- package/build/utils/index.d.ts.map +1 -0
- package/build/utils/index.js +3 -0
- package/build/utils/index.js.map +1 -0
- package/build/utils/types.d.ts +6 -0
- package/build/utils/types.d.ts.map +1 -0
- package/build/utils/types.js +2 -0
- package/build/utils/types.js.map +1 -0
- package/package.json +45 -0
- package/src/consts.ts +7 -0
- package/src/entrypoint.ts +106 -0
- package/src/filter.ts +26 -0
- package/src/helper.ts +37 -0
- package/src/index.ts +6 -0
- package/src/types.ts +94 -0
- package/src/utils/entrypoint.ts +4 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/types.ts +6 -0
- package/tsconfig.json +10 -0
package/README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# @owlmeans/entrypoint
|
|
2
|
+
|
|
3
|
+
Entrypoint system — the URL unit abstraction shared between server and client in OwlMeans apps.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
- An **entrypoint** is a URL unit: an alias + path + optional guards/gates/filters
|
|
8
|
+
- On the server, entrypoints become API routes with attached handlers
|
|
9
|
+
- On the client, entrypoints provide URL generation and navigation
|
|
10
|
+
- All AJV validation schemas are defined at entrypoint level, keeping data contracts consistent fullstack
|
|
11
|
+
- Most commonly used via re-exports in `@owlmeans/server-app` or `@owlmeans/client-entrypoint`
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bun add @owlmeans/entrypoint
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Usage
|
|
20
|
+
|
|
21
|
+
Define an entrypoint with body validation and a guard:
|
|
22
|
+
|
|
23
|
+
```typescript
|
|
24
|
+
import { entrypoint, guard, filter, body, params } from '@owlmeans/server-app'
|
|
25
|
+
import { route } from '@owlmeans/route'
|
|
26
|
+
|
|
27
|
+
const createStoryModule = entrypoint(
|
|
28
|
+
route('story-create', '/stories', { method: 'POST', parent: 'api' }),
|
|
29
|
+
filter(body({
|
|
30
|
+
type: 'object',
|
|
31
|
+
properties: { story: { type: 'string' }, projectId: { type: 'string' } },
|
|
32
|
+
required: ['story', 'projectId']
|
|
33
|
+
}), guard('authenticated'))
|
|
34
|
+
)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Use `AbstractRequest` type in a handler:
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
import type { AbstractRequest } from '@owlmeans/entrypoint'
|
|
41
|
+
|
|
42
|
+
export const create = handleBody(async (body, context, request) => {
|
|
43
|
+
const req = request as AbstractRequest<{ id: string }>
|
|
44
|
+
const projectId = req.params.id
|
|
45
|
+
})
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## API
|
|
49
|
+
|
|
50
|
+
### `entrypoint(route, opts?): CommonEntrypoint`
|
|
51
|
+
|
|
52
|
+
Creates an entrypoint. `opts` is typically produced by `filter()`, `guard()`, or `gate()`.
|
|
53
|
+
|
|
54
|
+
### `guard(guard, opts?): CommonEntrypointOptions`
|
|
55
|
+
|
|
56
|
+
Adds an authentication guard requirement.
|
|
57
|
+
|
|
58
|
+
### `gate(gate, params, opts?): CommonEntrypointOptions`
|
|
59
|
+
|
|
60
|
+
Adds an authorization gate with parameters.
|
|
61
|
+
|
|
62
|
+
### `filter(filter, opts?): CommonEntrypointOptions`
|
|
63
|
+
|
|
64
|
+
Attaches validation schemas (AJV format) to the entrypoint.
|
|
65
|
+
|
|
66
|
+
### `body(schema, filter?) / query(schema, filter?) / params(schema, filter?)`
|
|
67
|
+
|
|
68
|
+
Build a `Filter` object with the given AJV schema applied to the corresponding request part.
|
|
69
|
+
|
|
70
|
+
### `parent(entrypoint, parentAlias): CommonEntrypoint`
|
|
71
|
+
|
|
72
|
+
Sets a parent-child relationship so child entrypoints inherit guards/gates.
|
|
73
|
+
|
|
74
|
+
### `provideResponse<T>(): AbstractResponse<T>`
|
|
75
|
+
|
|
76
|
+
Creates a response object for use in non-elevated handlers.
|
|
77
|
+
|
|
78
|
+
### `EntrypointOutcome`
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
enum EntrypointOutcome { Ok, Accepted, Created, Finished }
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Types
|
|
85
|
+
|
|
86
|
+
- `AbstractRequest<T>` — request with `params`, `body`, `query`, `headers`, `auth`
|
|
87
|
+
- `AbstractResponse<T>` — response with `resolve(value, outcome?)` and `reject(error)`
|
|
88
|
+
- `CommonEntrypoint` — entrypoint with `getAlias()`, `getPath()`, `getGuards()`, `handle`
|
|
89
|
+
|
|
90
|
+
## Related Packages
|
|
91
|
+
|
|
92
|
+
- [`@owlmeans/route`](../route) — `route()` factory used in `entrypoint(route(...), ...)`
|
|
93
|
+
- [`@owlmeans/server-entrypoint`](../server-entrypoint) — server-side `elevate()` to attach handlers
|
|
94
|
+
- [`@owlmeans/client-entrypoint`](../client-entrypoint) — client-side entrypoint with API call support
|
|
95
|
+
- [`@owlmeans/server-app`](../server-app) — re-exports everything from this package
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA,oBAAY,iBAAiB;IAC3B,EAAE,OAAO;IACT,QAAQ,aAAa;IACrB,OAAO,YAAY;IACnB,QAAQ,aAAa;CACtB"}
|
package/build/consts.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export var EntrypointOutcome;
|
|
2
|
+
(function (EntrypointOutcome) {
|
|
3
|
+
EntrypointOutcome["Ok"] = "ok";
|
|
4
|
+
EntrypointOutcome["Accepted"] = "accepted";
|
|
5
|
+
EntrypointOutcome["Created"] = "created";
|
|
6
|
+
EntrypointOutcome["Finished"] = "finished";
|
|
7
|
+
})(EntrypointOutcome || (EntrypointOutcome = {}));
|
|
8
|
+
//# sourceMappingURL=consts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AACA,MAAM,CAAN,IAAY,iBAKX;AALD,WAAY,iBAAiB;IAC3B,8BAAS,CAAA;IACT,0CAAqB,CAAA;IACrB,wCAAmB,CAAA;IACnB,0CAAqB,CAAA;AACvB,CAAC,EALW,iBAAiB,KAAjB,iBAAiB,QAK5B"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { CommonEntrypoint } from './types.js';
|
|
2
|
+
import type { CreateEntrypointSignature } from './utils/types.js';
|
|
3
|
+
export declare const entrypoint: CreateEntrypointSignature<CommonEntrypoint>;
|
|
4
|
+
export declare const parent: <T extends CommonEntrypoint | CommonEntrypoint[]>(ep: T, aliasOrParent: string, _parent?: string) => T;
|
|
5
|
+
//# sourceMappingURL=entrypoint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entrypoint.d.ts","sourceRoot":"","sources":["../src/entrypoint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAA;AAEjE,eAAO,MAAM,UAAU,EAAE,yBAAyB,CAAC,gBAAgB,CAqFlE,CAAA;AAED,eAAO,MAAM,MAAM,GAAI,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,EAAE,EAAE,IAAI,CAAC,EAAE,eAAe,MAAM,EAAE,UAAU,MAAM,KAAG,CAcxH,CAAA"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { appendContextual } from '@owlmeans/context';
|
|
2
|
+
export const entrypoint = (route, opts) => {
|
|
3
|
+
let guards = null;
|
|
4
|
+
let gates = null;
|
|
5
|
+
const ep = appendContextual(route.route.alias, {
|
|
6
|
+
_entrypoint: true,
|
|
7
|
+
_module: true,
|
|
8
|
+
sticky: false,
|
|
9
|
+
route,
|
|
10
|
+
getAlias: () => ep.route.route.alias,
|
|
11
|
+
getPath: () => ep.route.route.path,
|
|
12
|
+
getParentAlias: () => ep.route.route.parent ?? null,
|
|
13
|
+
hasParent: () => ep.getParentAlias() != null,
|
|
14
|
+
resolve: async () => {
|
|
15
|
+
if (ep.ctx == null) {
|
|
16
|
+
throw new SyntaxError(`Entrypoint has no context yet - ${ep.getAlias()}`);
|
|
17
|
+
}
|
|
18
|
+
await ep.route.resolve(ep.ctx);
|
|
19
|
+
return ep;
|
|
20
|
+
},
|
|
21
|
+
getParent: () => {
|
|
22
|
+
const parentAlias = ep.getParentAlias();
|
|
23
|
+
if (parentAlias == null) {
|
|
24
|
+
throw new SyntaxError(`Entrypoint has no parent - ${ep.getAlias()}`);
|
|
25
|
+
}
|
|
26
|
+
if (ep.ctx == null) {
|
|
27
|
+
throw new SyntaxError(`Entrypoint has no context yet - ${ep.getAlias()}`);
|
|
28
|
+
}
|
|
29
|
+
return ep.ctx.entrypoint(parentAlias);
|
|
30
|
+
},
|
|
31
|
+
setService: service => {
|
|
32
|
+
if (ep.route.route.resolved) {
|
|
33
|
+
throw new SyntaxError(`Cannot update a resolved entrypoint - ${ep.getAlias()}`);
|
|
34
|
+
}
|
|
35
|
+
ep.route.route.service = service;
|
|
36
|
+
},
|
|
37
|
+
getGuards: () => {
|
|
38
|
+
if (guards != null) {
|
|
39
|
+
return guards;
|
|
40
|
+
}
|
|
41
|
+
guards = ep.guards ?? [];
|
|
42
|
+
if (ep.hasParent()) {
|
|
43
|
+
guards.push(...ep.getParent().getGuards().filter(guard => !guards?.includes(guard)));
|
|
44
|
+
}
|
|
45
|
+
return guards;
|
|
46
|
+
},
|
|
47
|
+
getGates: () => {
|
|
48
|
+
if (gates != null) {
|
|
49
|
+
return gates;
|
|
50
|
+
}
|
|
51
|
+
gates = ep.gate != null ? [[
|
|
52
|
+
ep.gate, ep.gateParams == null
|
|
53
|
+
? [] : Array.isArray(ep.gateParams)
|
|
54
|
+
? ep.gateParams : [ep.gateParams]
|
|
55
|
+
]] : [];
|
|
56
|
+
if (ep.hasParent()) {
|
|
57
|
+
gates.push(...ep.getParent().getGates()
|
|
58
|
+
.filter(([gate]) => !gates?.some(([g]) => g === gate)));
|
|
59
|
+
}
|
|
60
|
+
return gates;
|
|
61
|
+
},
|
|
62
|
+
...opts
|
|
63
|
+
});
|
|
64
|
+
return ep;
|
|
65
|
+
};
|
|
66
|
+
export const parent = (ep, aliasOrParent, _parent) => {
|
|
67
|
+
if (Array.isArray(ep)) {
|
|
68
|
+
if (_parent == null) {
|
|
69
|
+
throw SyntaxError('Elevating parent requires parent name to be specified');
|
|
70
|
+
}
|
|
71
|
+
ep = ep.find(e => e.route.route.alias === aliasOrParent);
|
|
72
|
+
if (ep == null) {
|
|
73
|
+
throw SyntaxError(`Entrypoint not found ${aliasOrParent}`);
|
|
74
|
+
}
|
|
75
|
+
return parent(ep, _parent);
|
|
76
|
+
}
|
|
77
|
+
ep.route.route.parent = aliasOrParent;
|
|
78
|
+
return ep;
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=entrypoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entrypoint.js","sourceRoot":"","sources":["../src/entrypoint.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { JSONSchemaType } from 'ajv';
|
|
2
|
+
import type { Filter } from './types.js';
|
|
3
|
+
export declare const body: <T>(schema: JSONSchemaType<T>, filter?: Filter) => Filter;
|
|
4
|
+
export declare const query: <T>(schema: JSONSchemaType<T>, filter?: Filter) => Filter;
|
|
5
|
+
export declare const params: <T>(schema: JSONSchemaType<T>, filter?: Filter) => Filter;
|
|
6
|
+
export declare const response: <T>(schema: JSONSchemaType<T>, code?: number, filter?: Filter) => Filter;
|
|
7
|
+
export declare const headers: <T>(schema: JSONSchemaType<T>, filter?: Filter) => Filter;
|
|
8
|
+
//# sourceMappingURL=filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,CAAA;AACzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAExC,eAAO,MAAM,IAAI,GAAI,CAAC,EAAE,QAAQ,cAAc,CAAC,CAAC,CAAC,EAAE,SAAS,MAAM,KAAG,MAEpE,CAAA;AAED,eAAO,MAAM,KAAK,GAAI,CAAC,EAAE,QAAQ,cAAc,CAAC,CAAC,CAAC,EAAE,SAAS,MAAM,KAAG,MAErE,CAAA;AAED,eAAO,MAAM,MAAM,GAAI,CAAC,EAAE,QAAQ,cAAc,CAAC,CAAC,CAAC,EAAE,SAAS,MAAM,KAAG,MAEtE,CAAA;AAED,eAAO,MAAM,QAAQ,GAAI,CAAC,EAAE,QAAQ,cAAc,CAAC,CAAC,CAAC,EAAE,OAAO,MAAM,EAAE,SAAS,MAAM,KAAG,MAMvF,CAAA;AAED,eAAO,MAAM,OAAO,GAAI,CAAC,EAAE,QAAQ,cAAc,CAAC,CAAC,CAAC,EAAE,SAAS,MAAM,KAAG,MAEvE,CAAA"}
|
package/build/filter.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export const body = (schema, filter) => {
|
|
2
|
+
return { ...filter, body: schema };
|
|
3
|
+
};
|
|
4
|
+
export const query = (schema, filter) => {
|
|
5
|
+
return { ...filter, query: schema };
|
|
6
|
+
};
|
|
7
|
+
export const params = (schema, filter) => {
|
|
8
|
+
return { ...filter, params: schema };
|
|
9
|
+
};
|
|
10
|
+
export const response = (schema, code, filter) => {
|
|
11
|
+
let _schema = schema;
|
|
12
|
+
if (filter?.response != null && code != null) {
|
|
13
|
+
_schema = { ...filter.response, [code]: schema };
|
|
14
|
+
}
|
|
15
|
+
return { ...filter, response: _schema };
|
|
16
|
+
};
|
|
17
|
+
export const headers = (schema, filter) => {
|
|
18
|
+
return { ...filter, headers: schema };
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter.js","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,IAAI,GAAG,CAAI,MAAyB,EAAE,MAAe,EAAU,EAAE;IAC5E,OAAO,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,MAAa,EAAE,CAAA;AAC3C,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,KAAK,GAAG,CAAI,MAAyB,EAAE,MAAe,EAAU,EAAE;IAC7E,OAAO,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,MAAa,EAAE,CAAA;AAC5C,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,CAAI,MAAyB,EAAE,MAAe,EAAU,EAAE;IAC9E,OAAO,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,MAAa,EAAE,CAAA;AAC7C,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAI,MAAyB,EAAE,IAAa,EAAE,MAAe,EAAU,EAAE;IAC/F,IAAI,OAAO,GAAQ,MAAM,CAAA;IACzB,IAAI,MAAM,EAAE,QAAQ,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;QAC7C,OAAO,GAAG,EAAE,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IAClD,CAAC;IACD,OAAO,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAA;AACzC,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,CAAI,MAAyB,EAAE,MAAe,EAAU,EAAE;IAC/E,OAAO,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,MAAa,EAAE,CAAA;AAC9C,CAAC,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Filter, CommonEntrypointOptions, AbstractResponse, CommonEntrypoint } from './types.js';
|
|
2
|
+
export declare const filter: (filter: Filter, opts?: CommonEntrypointOptions) => CommonEntrypointOptions;
|
|
3
|
+
export declare const guard: (guard: string, opts?: CommonEntrypointOptions) => CommonEntrypointOptions;
|
|
4
|
+
export declare const gate: (gate: string, params: string | string[], opts?: CommonEntrypointOptions) => CommonEntrypointOptions;
|
|
5
|
+
export declare const provideResponse: <T>(originalResponse?: unknown) => AbstractResponse<T>;
|
|
6
|
+
export declare const clone: <M extends CommonEntrypoint>(entrypoints: M[], from: string, to: string, service: string) => void;
|
|
7
|
+
//# sourceMappingURL=helper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helper.d.ts","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAGhG,eAAO,MAAM,MAAM,GAAI,QAAQ,MAAM,EAAE,OAAO,uBAAuB,KAAG,uBAAgD,CAAA;AAExH,eAAO,MAAM,KAAK,GAAI,OAAO,MAAM,EAAE,OAAO,uBAAuB,KAAG,uBACC,CAAA;AAEvE,eAAO,MAAM,IAAI,GAAI,MAAM,MAAM,EAAE,QAAQ,MAAM,GAAG,MAAM,EAAE,EAAE,OAAO,uBAAuB,KAAG,uBACtD,CAAA;AAEzC,eAAO,MAAM,eAAe,GAAI,CAAC,EAAE,mBAAmB,OAAO,KAAG,gBAAgB,CAAC,CAAC,CAejF,CAAA;AAED,eAAO,MAAM,KAAK,GAAI,CAAC,SAAS,gBAAgB,EAAE,aAAa,CAAC,EAAE,EAAE,MAAM,MAAM,EAAE,IAAI,MAAM,EAAE,SAAS,MAAM,SAO5G,CAAA"}
|
package/build/helper.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { route } from '@owlmeans/route';
|
|
2
|
+
import { entrypoint } from './entrypoint.js';
|
|
3
|
+
export const filter = (filter, opts) => ({ filter, ...opts });
|
|
4
|
+
export const guard = (guard, opts) => ({ ...opts, guards: [...new Set([guard, ...(opts?.guards ?? [])])] });
|
|
5
|
+
export const gate = (gate, params, opts) => ({ ...opts, gate, gateParams: params });
|
|
6
|
+
export const provideResponse = (originalResponse) => {
|
|
7
|
+
const handler = {
|
|
8
|
+
responseProvider: originalResponse,
|
|
9
|
+
resolve: (value, outcome) => {
|
|
10
|
+
handler.value = value;
|
|
11
|
+
handler.outcome = outcome;
|
|
12
|
+
},
|
|
13
|
+
reject: (error) => {
|
|
14
|
+
handler.error = error;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
return handler;
|
|
18
|
+
};
|
|
19
|
+
export const clone = (entrypoints, from, to, service) => {
|
|
20
|
+
const source = entrypoints.find(e => e.alias === from);
|
|
21
|
+
if (source?.route.route != null) {
|
|
22
|
+
const _route = { ...source.route.route, service, resolved: false, alias: to };
|
|
23
|
+
entrypoints.push(entrypoint(route(to, _route.path, _route)));
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=helper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helper.js","sourceRoot":"","sources":["../src/helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAEvC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAE5C,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,MAAc,EAAE,IAA8B,EAA2B,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,CAAA;AAExH,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,IAA8B,EAA2B,EAAE,CAC9F,CAAC,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;AAEvE,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,MAAyB,EAAE,IAA8B,EAA2B,EAAE,CACvH,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,CAAA;AAEzC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAI,gBAA0B,EAAuB,EAAE;IACpF,MAAM,OAAO,GAAwB;QACnC,gBAAgB,EAAE,gBAAgB;QAElC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YAC1B,OAAO,CAAC,KAAK,GAAG,KAAK,CAAA;YACrB,OAAO,CAAC,OAAO,GAAG,OAAO,CAAA;QAC3B,CAAC;QAED,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YAChB,OAAO,CAAC,KAAK,GAAG,KAAK,CAAA;QACvB,CAAC;KACF,CAAA;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,KAAK,GAAG,CAA6B,WAAgB,EAAE,IAAY,EAAE,EAAU,EAAE,OAAe,EAAE,EAAE;IAC/G,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,CAAA;IAEtD,IAAI,MAAM,EAAE,KAAK,CAAC,KAAK,IAAI,IAAI,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,CAAA;QAC7E,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAM,CAAC,CAAA;IACnE,CAAC;AACH,CAAC,CAAA"}
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,mBAAmB,YAAY,CAAA;AAC/B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA"}
|
package/build/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,iBAAiB,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA"}
|
package/build/types.d.ts
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { CommonRouteModel } from '@owlmeans/route';
|
|
2
|
+
import type { InitializedService, LazyService, BasicEntrypoint } from '@owlmeans/context';
|
|
3
|
+
import type { AnySchemaObject } from 'ajv';
|
|
4
|
+
import type { EntrypointOutcome } from './consts.js';
|
|
5
|
+
import type { Auth } from '@owlmeans/auth';
|
|
6
|
+
export interface CommonEntrypoint extends BasicEntrypoint {
|
|
7
|
+
route: CommonRouteModel;
|
|
8
|
+
/**
|
|
9
|
+
* @property {boolean} - if true — router attaches this entrypoint unconditionally
|
|
10
|
+
* @default false
|
|
11
|
+
*/
|
|
12
|
+
sticky: boolean;
|
|
13
|
+
filter?: Filter;
|
|
14
|
+
guards?: string[];
|
|
15
|
+
gate?: string;
|
|
16
|
+
gateParams?: string | string[];
|
|
17
|
+
handle?: EntrypointHandler;
|
|
18
|
+
getAlias: () => string;
|
|
19
|
+
getPath: () => string;
|
|
20
|
+
getParentAlias: () => string | null;
|
|
21
|
+
hasParent: () => boolean;
|
|
22
|
+
resolve: <M extends CommonEntrypoint>() => Promise<M>;
|
|
23
|
+
getParent: <M extends CommonEntrypoint>() => M;
|
|
24
|
+
setService: (service: string) => void;
|
|
25
|
+
getGuards: () => string[];
|
|
26
|
+
getGates: () => [string, string[]][];
|
|
27
|
+
}
|
|
28
|
+
export interface CommonEntrypointOptions extends Partial<CommonEntrypoint> {
|
|
29
|
+
}
|
|
30
|
+
export interface EntrypointMatch {
|
|
31
|
+
<R extends AbstractRequest, P extends AbstractResponse<any>>(req: R, res: P): Promise<boolean>;
|
|
32
|
+
}
|
|
33
|
+
export interface EntrypointHandler {
|
|
34
|
+
<T, R extends AbstractRequest<any> = AbstractRequest<any>, P extends AbstractResponse<any> = AbstractResponse<any>>(req: R, res: P): T | Promise<T>;
|
|
35
|
+
}
|
|
36
|
+
export interface EntrypointAssert {
|
|
37
|
+
<R extends AbstractRequest, P extends AbstractResponse<any>>(req: R, res: P, params: string[]): Promise<void>;
|
|
38
|
+
}
|
|
39
|
+
export interface AbstractRequest<T extends {} = {}> {
|
|
40
|
+
alias: string;
|
|
41
|
+
auth?: Auth;
|
|
42
|
+
params: Record<string, string | number | undefined | null> | Partial<T>;
|
|
43
|
+
body?: Record<string, any> | Partial<T>;
|
|
44
|
+
headers: Record<string, string[] | string | undefined>;
|
|
45
|
+
query: Record<string, string | number | undefined | null> | Partial<T>;
|
|
46
|
+
path: string;
|
|
47
|
+
original?: any;
|
|
48
|
+
canceled?: boolean;
|
|
49
|
+
cancel?: () => void;
|
|
50
|
+
host?: string;
|
|
51
|
+
base?: string | boolean;
|
|
52
|
+
unsecure?: boolean;
|
|
53
|
+
}
|
|
54
|
+
export interface AbstractResponse<T> {
|
|
55
|
+
responseProvider?: any;
|
|
56
|
+
value?: T;
|
|
57
|
+
outcome?: EntrypointOutcome;
|
|
58
|
+
error?: Error;
|
|
59
|
+
resolve: (value: T, outcome?: EntrypointOutcome) => void;
|
|
60
|
+
reject: (error: Error) => void;
|
|
61
|
+
}
|
|
62
|
+
export interface GuardService extends InitializedService {
|
|
63
|
+
token?: string;
|
|
64
|
+
authenticated: (req?: Partial<AbstractRequest>) => Promise<string | null>;
|
|
65
|
+
match: EntrypointMatch;
|
|
66
|
+
handle: EntrypointHandler;
|
|
67
|
+
}
|
|
68
|
+
export interface GateService extends LazyService {
|
|
69
|
+
/**
|
|
70
|
+
* @throws {Error}
|
|
71
|
+
*/
|
|
72
|
+
assert: EntrypointAssert;
|
|
73
|
+
}
|
|
74
|
+
export interface Filter {
|
|
75
|
+
query?: AnySchemaObject;
|
|
76
|
+
params?: AnySchemaObject;
|
|
77
|
+
body?: AnySchemaObject;
|
|
78
|
+
response?: AnySchemaObject;
|
|
79
|
+
headers?: AnySchemaObject;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/build/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entrypoint.d.ts","sourceRoot":"","sources":["../../src/utils/entrypoint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAE9C,eAAO,MAAM,YAAY,GAAI,KAAK,MAAM,KAAG,GAAG,IAAI,gBACR,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entrypoint.js","sourceRoot":"","sources":["../../src/utils/entrypoint.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAW,EAA2B,EAAE,CACnE,aAAa,IAAI,GAAG,IAAI,SAAS,IAAI,GAAG,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAA;AAC1B,cAAc,iBAAiB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAA;AAC1B,cAAc,iBAAiB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/utils/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAA;AAErD,MAAM,WAAW,yBAAyB,CAAC,CAAC;IAC1C,CAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,CAAC,EAAE,uBAAuB,GAAG,CAAC,CAAC;CAC9D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/utils/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@owlmeans/entrypoint",
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "tsc -b",
|
|
8
|
+
"dev": "sleep 186 && nodemon -e ts,tsx,json --watch src --exec \"tsc -p ./tsconfig.json\"",
|
|
9
|
+
"watch": "tsc -b -w --preserveWatchOutput --pretty"
|
|
10
|
+
},
|
|
11
|
+
"main": "build/index.js",
|
|
12
|
+
"module": "build/index.js",
|
|
13
|
+
"types": "build/index.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"import": "./build/index.js",
|
|
17
|
+
"require": "./build/index.js",
|
|
18
|
+
"default": "./build/index.js",
|
|
19
|
+
"module": "./build/index.js",
|
|
20
|
+
"types": "./build/index.d.ts"
|
|
21
|
+
},
|
|
22
|
+
"./utils": {
|
|
23
|
+
"default": "./build/utils/index.js",
|
|
24
|
+
"types": "./build/utils/index.js",
|
|
25
|
+
"import": "./build/utils/index.js",
|
|
26
|
+
"require": "./build/utils/index.js",
|
|
27
|
+
"module": "./build/utils/index.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@owlmeans/auth": "^0.1.3",
|
|
32
|
+
"@owlmeans/context": "^0.1.3",
|
|
33
|
+
"@owlmeans/route": "^0.1.3",
|
|
34
|
+
"ajv": "^8.17.1"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@owlmeans/dep-config": "workspace:*",
|
|
38
|
+
"nodemon": "^3.1.11",
|
|
39
|
+
"npm-check": "^6.0.1",
|
|
40
|
+
"typescript": "^6.0.2"
|
|
41
|
+
},
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
}
|
|
45
|
+
}
|
package/src/consts.ts
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { CommonEntrypoint } from './types.js'
|
|
2
|
+
import { appendContextual } from '@owlmeans/context'
|
|
3
|
+
import type { CreateEntrypointSignature } from './utils/types.js'
|
|
4
|
+
|
|
5
|
+
export const entrypoint: CreateEntrypointSignature<CommonEntrypoint> = (route, opts) => {
|
|
6
|
+
let guards: string[] | null = null
|
|
7
|
+
let gates: [string, string[]][] | null = null
|
|
8
|
+
const ep: CommonEntrypoint = appendContextual<CommonEntrypoint>(route.route.alias, {
|
|
9
|
+
_entrypoint: true,
|
|
10
|
+
_module: true,
|
|
11
|
+
|
|
12
|
+
sticky: false,
|
|
13
|
+
|
|
14
|
+
route,
|
|
15
|
+
|
|
16
|
+
getAlias: () => ep.route.route.alias,
|
|
17
|
+
getPath: () => ep.route.route.path,
|
|
18
|
+
getParentAlias: () => ep.route.route.parent ?? null,
|
|
19
|
+
hasParent: () => ep.getParentAlias() != null,
|
|
20
|
+
|
|
21
|
+
resolve: async <M extends CommonEntrypoint>() => {
|
|
22
|
+
if (ep.ctx == null) {
|
|
23
|
+
throw new SyntaxError(`Entrypoint has no context yet - ${ep.getAlias()}`)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
await ep.route.resolve(ep.ctx)
|
|
27
|
+
|
|
28
|
+
return ep as M
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
getParent: () => {
|
|
32
|
+
const parentAlias = ep.getParentAlias()
|
|
33
|
+
if (parentAlias == null) {
|
|
34
|
+
throw new SyntaxError(`Entrypoint has no parent - ${ep.getAlias()}`)
|
|
35
|
+
}
|
|
36
|
+
if (ep.ctx == null) {
|
|
37
|
+
throw new SyntaxError(`Entrypoint has no context yet - ${ep.getAlias()}`)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return ep.ctx.entrypoint(parentAlias)
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
setService: service => {
|
|
44
|
+
if (ep.route.route.resolved) {
|
|
45
|
+
throw new SyntaxError(`Cannot update a resolved entrypoint - ${ep.getAlias()}`)
|
|
46
|
+
}
|
|
47
|
+
ep.route.route.service = service
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
getGuards: () => {
|
|
51
|
+
if (guards != null) {
|
|
52
|
+
return guards
|
|
53
|
+
}
|
|
54
|
+
guards = ep.guards ?? []
|
|
55
|
+
|
|
56
|
+
if (ep.hasParent()) {
|
|
57
|
+
guards.push(
|
|
58
|
+
...ep.getParent().getGuards().filter(guard => !guards?.includes(guard))
|
|
59
|
+
)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return guards
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
getGates: () => {
|
|
66
|
+
if (gates != null) {
|
|
67
|
+
return gates
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
gates = ep.gate != null ? [[
|
|
71
|
+
ep.gate, ep.gateParams == null
|
|
72
|
+
? [] : Array.isArray(ep.gateParams)
|
|
73
|
+
? ep.gateParams : [ep.gateParams]
|
|
74
|
+
]] : []
|
|
75
|
+
|
|
76
|
+
if (ep.hasParent()) {
|
|
77
|
+
gates.push(
|
|
78
|
+
...ep.getParent().getGates()
|
|
79
|
+
.filter(([gate]) => !gates?.some(([g]) => g === gate))
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return gates
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
...opts
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
return ep
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export const parent = <T extends CommonEntrypoint | CommonEntrypoint[]>(ep: T, aliasOrParent: string, _parent?: string): T => {
|
|
93
|
+
if (Array.isArray(ep)) {
|
|
94
|
+
if (_parent == null) {
|
|
95
|
+
throw SyntaxError('Elevating parent requires parent name to be specified')
|
|
96
|
+
}
|
|
97
|
+
ep = ep.find(e => e.route.route.alias === aliasOrParent) as T
|
|
98
|
+
if (ep == null) {
|
|
99
|
+
throw SyntaxError(`Entrypoint not found ${aliasOrParent}`)
|
|
100
|
+
}
|
|
101
|
+
return parent(ep, _parent)
|
|
102
|
+
}
|
|
103
|
+
ep.route.route.parent = aliasOrParent
|
|
104
|
+
|
|
105
|
+
return ep
|
|
106
|
+
}
|
package/src/filter.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { JSONSchemaType } from 'ajv'
|
|
2
|
+
import type { Filter } from './types.js'
|
|
3
|
+
|
|
4
|
+
export const body = <T>(schema: JSONSchemaType<T>, filter?: Filter): Filter => {
|
|
5
|
+
return { ...filter, body: schema as any }
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const query = <T>(schema: JSONSchemaType<T>, filter?: Filter): Filter => {
|
|
9
|
+
return { ...filter, query: schema as any }
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const params = <T>(schema: JSONSchemaType<T>, filter?: Filter): Filter => {
|
|
13
|
+
return { ...filter, params: schema as any }
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const response = <T>(schema: JSONSchemaType<T>, code?: number, filter?: Filter): Filter => {
|
|
17
|
+
let _schema: any = schema
|
|
18
|
+
if (filter?.response != null && code != null) {
|
|
19
|
+
_schema = { ...filter.response, [code]: schema }
|
|
20
|
+
}
|
|
21
|
+
return { ...filter, response: _schema }
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const headers = <T>(schema: JSONSchemaType<T>, filter?: Filter): Filter => {
|
|
25
|
+
return { ...filter, headers: schema as any }
|
|
26
|
+
}
|
package/src/helper.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { route } from '@owlmeans/route'
|
|
2
|
+
import { Filter, CommonEntrypointOptions, AbstractResponse, CommonEntrypoint } from './types.js'
|
|
3
|
+
import { entrypoint } from './entrypoint.js'
|
|
4
|
+
|
|
5
|
+
export const filter = (filter: Filter, opts?: CommonEntrypointOptions): CommonEntrypointOptions => ({ filter, ...opts })
|
|
6
|
+
|
|
7
|
+
export const guard = (guard: string, opts?: CommonEntrypointOptions): CommonEntrypointOptions =>
|
|
8
|
+
({ ...opts, guards: [...new Set([guard, ...(opts?.guards ?? [])])] })
|
|
9
|
+
|
|
10
|
+
export const gate = (gate: string, params: string | string[], opts?: CommonEntrypointOptions): CommonEntrypointOptions =>
|
|
11
|
+
({ ...opts, gate, gateParams: params })
|
|
12
|
+
|
|
13
|
+
export const provideResponse = <T>(originalResponse?: unknown): AbstractResponse<T> => {
|
|
14
|
+
const handler: AbstractResponse<T> = {
|
|
15
|
+
responseProvider: originalResponse,
|
|
16
|
+
|
|
17
|
+
resolve: (value, outcome) => {
|
|
18
|
+
handler.value = value
|
|
19
|
+
handler.outcome = outcome
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
reject: (error) => {
|
|
23
|
+
handler.error = error
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return handler
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const clone = <M extends CommonEntrypoint>(entrypoints: M[], from: string, to: string, service: string) => {
|
|
31
|
+
const source = entrypoints.find(e => e.alias === from)
|
|
32
|
+
|
|
33
|
+
if (source?.route.route != null) {
|
|
34
|
+
const _route = { ...source.route.route, service, resolved: false, alias: to }
|
|
35
|
+
entrypoints.push(entrypoint(route(to, _route.path, _route)) as M)
|
|
36
|
+
}
|
|
37
|
+
}
|
package/src/index.ts
ADDED
package/src/types.ts
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { CommonRouteModel } from '@owlmeans/route'
|
|
2
|
+
import type { InitializedService, LazyService, BasicEntrypoint } from '@owlmeans/context'
|
|
3
|
+
import type { AnySchemaObject } from 'ajv'
|
|
4
|
+
import type { EntrypointOutcome } from './consts.js'
|
|
5
|
+
import type { Auth } from '@owlmeans/auth'
|
|
6
|
+
|
|
7
|
+
export interface CommonEntrypoint extends BasicEntrypoint {
|
|
8
|
+
route: CommonRouteModel
|
|
9
|
+
/**
|
|
10
|
+
* @property {boolean} - if true — router attaches this entrypoint unconditionally
|
|
11
|
+
* @default false
|
|
12
|
+
*/
|
|
13
|
+
sticky: boolean
|
|
14
|
+
filter?: Filter
|
|
15
|
+
guards?: string[]
|
|
16
|
+
gate?: string
|
|
17
|
+
gateParams?: string | string[]
|
|
18
|
+
handle?: EntrypointHandler
|
|
19
|
+
getAlias: () => string
|
|
20
|
+
getPath: () => string
|
|
21
|
+
getParentAlias: () => string | null
|
|
22
|
+
hasParent: () => boolean
|
|
23
|
+
resolve: <M extends CommonEntrypoint>() => Promise<M>
|
|
24
|
+
getParent: <M extends CommonEntrypoint>() => M
|
|
25
|
+
setService: (service: string) => void
|
|
26
|
+
getGuards: () => string[]
|
|
27
|
+
getGates: () => [string, string[]][]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface CommonEntrypointOptions extends Partial<CommonEntrypoint> { }
|
|
31
|
+
|
|
32
|
+
export interface EntrypointMatch {
|
|
33
|
+
<R extends AbstractRequest, P extends AbstractResponse<any>>(req: R, res: P): Promise<boolean>
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface EntrypointHandler {
|
|
37
|
+
<
|
|
38
|
+
T, R extends AbstractRequest<any> = AbstractRequest<any>,
|
|
39
|
+
P extends AbstractResponse<any> = AbstractResponse<any>,
|
|
40
|
+
>(req: R, res: P): T | Promise<T>
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface EntrypointAssert {
|
|
44
|
+
<R extends AbstractRequest, P extends AbstractResponse<any>>(req: R, res: P, params: string[]): Promise<void>
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface AbstractRequest<T extends {} = {}> {
|
|
48
|
+
alias: string
|
|
49
|
+
auth?: Auth
|
|
50
|
+
params: Record<string, string | number | undefined | null> | Partial<T>
|
|
51
|
+
body?: Record<string, any> | Partial<T>
|
|
52
|
+
headers: Record<string, string[] | string | undefined>
|
|
53
|
+
query: Record<string, string | number | undefined | null> | Partial<T>
|
|
54
|
+
path: string
|
|
55
|
+
original?: any
|
|
56
|
+
canceled?: boolean
|
|
57
|
+
cancel?: () => void
|
|
58
|
+
host?: string
|
|
59
|
+
base?: string | boolean
|
|
60
|
+
unsecure?: boolean
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface AbstractResponse<T> {
|
|
64
|
+
responseProvider?: any
|
|
65
|
+
value?: T,
|
|
66
|
+
outcome?: EntrypointOutcome
|
|
67
|
+
error?: Error
|
|
68
|
+
resolve: (value: T, outcome?: EntrypointOutcome) => void
|
|
69
|
+
reject: (error: Error) => void
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface GuardService extends InitializedService {
|
|
73
|
+
// Client guard
|
|
74
|
+
token?: string
|
|
75
|
+
authenticated: (req?: Partial<AbstractRequest>) => Promise<string | null>
|
|
76
|
+
// Server guard
|
|
77
|
+
match: EntrypointMatch
|
|
78
|
+
handle: EntrypointHandler
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface GateService extends LazyService {
|
|
82
|
+
/**
|
|
83
|
+
* @throws {Error}
|
|
84
|
+
*/
|
|
85
|
+
assert: EntrypointAssert
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface Filter {
|
|
89
|
+
query?: AnySchemaObject
|
|
90
|
+
params?: AnySchemaObject
|
|
91
|
+
body?: AnySchemaObject
|
|
92
|
+
response?: AnySchemaObject
|
|
93
|
+
headers?: AnySchemaObject
|
|
94
|
+
}
|