@owlmeans/module 0.1.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/LICENSE +21 -0
- package/README.md +521 -0
- package/build/.gitkeep +0 -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/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/module.d.ts +5 -0
- package/build/module.d.ts.map +1 -0
- package/build/module.js +79 -0
- package/build/module.js.map +1 -0
- package/build/types.d.ts +80 -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/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/module.d.ts +3 -0
- package/build/utils/module.d.ts.map +1 -0
- package/build/utils/module.js +2 -0
- package/build/utils/module.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 +44 -0
- package/src/consts.ts +7 -0
- package/src/filter.ts +26 -0
- package/src/helper.ts +37 -0
- package/src/index.ts +6 -0
- package/src/module.ts +105 -0
- package/src/types.ts +93 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/module.ts +3 -0
- package/src/utils/types.ts +6 -0
- package/tsconfig.json +15 -0
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAE9C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AAE7D,eAAO,MAAM,MAAM,EAAE,qBAAqB,CAAC,YAAY,CAoFtD,CAAA;AAED,eAAO,MAAM,MAAM,GAAI,CAAC,SAAS,YAAY,GAAG,YAAY,EAAE,UAAU,CAAC,iBAAiB,MAAM,YAAY,MAAM,KAAG,CAcpH,CAAA"}
|
package/build/module.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { appendContextual } from '@owlmeans/context';
|
|
2
|
+
export const module = (route, opts) => {
|
|
3
|
+
let guards = null;
|
|
4
|
+
let gates = null;
|
|
5
|
+
const module = appendContextual(route.route.alias, {
|
|
6
|
+
_module: true,
|
|
7
|
+
sticky: false,
|
|
8
|
+
route,
|
|
9
|
+
getAlias: () => module.route.route.alias,
|
|
10
|
+
getPath: () => module.route.route.path,
|
|
11
|
+
getParentAlias: () => module.route.route.parent ?? null,
|
|
12
|
+
hasParent: () => module.getParentAlias() != null,
|
|
13
|
+
resolve: async () => {
|
|
14
|
+
if (module.ctx == null) {
|
|
15
|
+
throw new SyntaxError(`Module has no context yet - ${module.getAlias()}`);
|
|
16
|
+
}
|
|
17
|
+
await module.route.resolve(module.ctx);
|
|
18
|
+
return module;
|
|
19
|
+
},
|
|
20
|
+
getParent: () => {
|
|
21
|
+
const parent = module.getParentAlias();
|
|
22
|
+
if (parent == null) {
|
|
23
|
+
throw new SyntaxError(`Module has no parent - ${module.getAlias()}`);
|
|
24
|
+
}
|
|
25
|
+
if (module.ctx == null) {
|
|
26
|
+
throw new SyntaxError(`Module has no context yet - ${module.getAlias()}`);
|
|
27
|
+
}
|
|
28
|
+
return module.ctx.module(parent);
|
|
29
|
+
},
|
|
30
|
+
setService: service => {
|
|
31
|
+
if (module.route.route.resolved) {
|
|
32
|
+
throw new SyntaxError(`Cannot update a resolved module - ${module.getAlias()}`);
|
|
33
|
+
}
|
|
34
|
+
module.route.route.service = service;
|
|
35
|
+
},
|
|
36
|
+
getGuards: () => {
|
|
37
|
+
if (guards != null) {
|
|
38
|
+
return guards;
|
|
39
|
+
}
|
|
40
|
+
guards = module.guards ?? [];
|
|
41
|
+
if (module.hasParent()) {
|
|
42
|
+
guards.push(...module.getParent().getGuards().filter(guard => !guards?.includes(guard)));
|
|
43
|
+
}
|
|
44
|
+
return guards;
|
|
45
|
+
},
|
|
46
|
+
getGates: () => {
|
|
47
|
+
if (gates != null) {
|
|
48
|
+
return gates;
|
|
49
|
+
}
|
|
50
|
+
gates = module.gate != null ? [[
|
|
51
|
+
module.gate, module.gateParams == null
|
|
52
|
+
? [] : Array.isArray(module.gateParams)
|
|
53
|
+
? module.gateParams : [module.gateParams]
|
|
54
|
+
]] : [];
|
|
55
|
+
if (module.hasParent()) {
|
|
56
|
+
gates.push(...module.getParent().getGates()
|
|
57
|
+
.filter(([gate]) => !gates?.some(([g]) => g === gate)));
|
|
58
|
+
}
|
|
59
|
+
return gates;
|
|
60
|
+
},
|
|
61
|
+
...opts
|
|
62
|
+
});
|
|
63
|
+
return module;
|
|
64
|
+
};
|
|
65
|
+
export const parent = (module, aliasOrParent, _parent) => {
|
|
66
|
+
if (Array.isArray(module)) {
|
|
67
|
+
if (_parent == null) {
|
|
68
|
+
throw SyntaxError('Elevating parent requires parent name to be specified');
|
|
69
|
+
}
|
|
70
|
+
module = module.find(module => module.route.route.alias === aliasOrParent);
|
|
71
|
+
if (module == null) {
|
|
72
|
+
throw SyntaxError(`Module not found ${aliasOrParent}`);
|
|
73
|
+
}
|
|
74
|
+
return parent(module, _parent);
|
|
75
|
+
}
|
|
76
|
+
module.route.route.parent = aliasOrParent;
|
|
77
|
+
return module;
|
|
78
|
+
};
|
|
79
|
+
//# sourceMappingURL=module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.js","sourceRoot":"","sources":["../src/module.ts"],"names":[],"mappings":"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"}
|
package/build/types.d.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { CommonRouteModel } from '@owlmeans/route';
|
|
2
|
+
import type { InitializedService, LazyService, BasicModule } from '@owlmeans/context';
|
|
3
|
+
import type { AnySchemaObject } from 'ajv';
|
|
4
|
+
import type { ModuleOutcome } from './consts.js';
|
|
5
|
+
import type { Auth } from '@owlmeans/auth';
|
|
6
|
+
export interface CommonModule extends BasicModule {
|
|
7
|
+
route: CommonRouteModel;
|
|
8
|
+
/**
|
|
9
|
+
* @property {boolean} - if true — router attaches this module unconditionaly
|
|
10
|
+
* @default false
|
|
11
|
+
*/
|
|
12
|
+
sticky: boolean;
|
|
13
|
+
filter?: Filter;
|
|
14
|
+
guards?: string[];
|
|
15
|
+
gate?: string;
|
|
16
|
+
gateParams?: string | string[];
|
|
17
|
+
handle?: ModuleHandler;
|
|
18
|
+
getAlias: () => string;
|
|
19
|
+
getPath: () => string;
|
|
20
|
+
getParentAlias: () => string | null;
|
|
21
|
+
hasParent: () => boolean;
|
|
22
|
+
resolve: <M extends CommonModule>() => Promise<M>;
|
|
23
|
+
getParent: <M extends CommonModule>() => M;
|
|
24
|
+
setService: (service: string) => void;
|
|
25
|
+
getGuards: () => string[];
|
|
26
|
+
getGates: () => [string, string[]][];
|
|
27
|
+
}
|
|
28
|
+
export interface CommonModuleOptions extends Partial<CommonModule> {
|
|
29
|
+
}
|
|
30
|
+
export interface ModuleMatch {
|
|
31
|
+
<R extends AbstractRequest, P extends AbstractResponse<any>>(req: R, res: P): Promise<boolean>;
|
|
32
|
+
}
|
|
33
|
+
export interface ModuleHandler {
|
|
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 ModuleAssert {
|
|
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
|
+
}
|
|
53
|
+
export interface AbstractResponse<T> {
|
|
54
|
+
responseProvider?: any;
|
|
55
|
+
value?: T;
|
|
56
|
+
outcome?: ModuleOutcome;
|
|
57
|
+
error?: Error;
|
|
58
|
+
resolve: (value: T, outcome?: ModuleOutcome) => void;
|
|
59
|
+
reject: (error: Error) => void;
|
|
60
|
+
}
|
|
61
|
+
export interface GuardService extends InitializedService {
|
|
62
|
+
token?: string;
|
|
63
|
+
authenticated: (req?: Partial<AbstractRequest>) => Promise<string | null>;
|
|
64
|
+
match: ModuleMatch;
|
|
65
|
+
handle: ModuleHandler;
|
|
66
|
+
}
|
|
67
|
+
export interface GateService extends LazyService {
|
|
68
|
+
/**
|
|
69
|
+
* @throws {Error}
|
|
70
|
+
*/
|
|
71
|
+
assert: ModuleAssert;
|
|
72
|
+
}
|
|
73
|
+
export interface Filter {
|
|
74
|
+
query?: AnySchemaObject;
|
|
75
|
+
params?: AnySchemaObject;
|
|
76
|
+
body?: AnySchemaObject;
|
|
77
|
+
response?: AnySchemaObject;
|
|
78
|
+
headers?: AnySchemaObject;
|
|
79
|
+
}
|
|
80
|
+
//# 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":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../src/utils/module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,eAAO,MAAM,QAAQ,WAAY,MAAM,KAAG,MAAM,IAAI,YAAmC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module.js","sourceRoot":"","sources":["../../src/utils/module.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,MAAc,EAA0B,EAAE,CAAC,SAAS,IAAI,MAAM,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,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAEjD,MAAM,WAAW,qBAAqB,CAAC,CAAC;IACtC,CAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,CAAC,EAAE,mBAAmB,GAAG,CAAC,CAAC;CAC1D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/utils/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@owlmeans/module",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"build": "tsc -b",
|
|
7
|
+
"dev": "sleep 186 && nodemon -e ts,tsx,json --watch src --exec \"tsc -p ./tsconfig.json\"",
|
|
8
|
+
"watch": "tsc -b -w --preserveWatchOutput --pretty"
|
|
9
|
+
},
|
|
10
|
+
"main": "build/index.js",
|
|
11
|
+
"module": "build/index.js",
|
|
12
|
+
"types": "build/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"import": "./build/index.js",
|
|
16
|
+
"require": "./build/index.js",
|
|
17
|
+
"default": "./build/index.js",
|
|
18
|
+
"module": "./build/index.js",
|
|
19
|
+
"types": "./build/index.d.ts"
|
|
20
|
+
},
|
|
21
|
+
"./utils": {
|
|
22
|
+
"default": "./build/utils/index.js",
|
|
23
|
+
"types": "./build/utils/index.js",
|
|
24
|
+
"import": "./build/utils/index.js",
|
|
25
|
+
"require": "./build/utils/index.js",
|
|
26
|
+
"module": "./build/utils/index.js"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@owlmeans/auth": "^0.1.0",
|
|
31
|
+
"@owlmeans/context": "^0.1.0",
|
|
32
|
+
"@owlmeans/route": "^0.1.0",
|
|
33
|
+
"ajv": "^8.17.1"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"nodemon": "^3.1.7",
|
|
37
|
+
"npm-check": "^6.0.1",
|
|
38
|
+
"typescript": "^5.6.3"
|
|
39
|
+
},
|
|
40
|
+
"private": false,
|
|
41
|
+
"publishConfig": {
|
|
42
|
+
"access": "public"
|
|
43
|
+
}
|
|
44
|
+
}
|
package/src/consts.ts
ADDED
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, CommonModuleOptions, AbstractResponse, CommonModule } from './types.js'
|
|
3
|
+
import { module } from './module.js'
|
|
4
|
+
|
|
5
|
+
export const filter = (filter: Filter, opts?: CommonModuleOptions): CommonModuleOptions => ({ filter, ...opts })
|
|
6
|
+
|
|
7
|
+
export const guard = (guard: string, opts?: CommonModuleOptions): CommonModuleOptions =>
|
|
8
|
+
({ ...opts, guards: [...new Set([guard, ...(opts?.guards ?? [])])] })
|
|
9
|
+
|
|
10
|
+
export const gate = (gate: string, params: string | string[], opts?: CommonModuleOptions): CommonModuleOptions =>
|
|
11
|
+
({ ...opts, gate, gateParams: params })
|
|
12
|
+
|
|
13
|
+
export const provideResponse = <T>(originalResponse?: unknown): AbstractResponse<T> => {
|
|
14
|
+
const hanlder: AbstractResponse<T> = {
|
|
15
|
+
responseProvider: originalResponse,
|
|
16
|
+
|
|
17
|
+
resolve: (value, outcome) => {
|
|
18
|
+
hanlder.value = value
|
|
19
|
+
hanlder.outcome = outcome
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
reject: (error) => {
|
|
23
|
+
hanlder.error = error
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return hanlder
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const clone = <M extends CommonModule>(modules: M[], from: string, to: string, service: string) => {
|
|
31
|
+
const source = modules.find(m => m.alias === from)
|
|
32
|
+
|
|
33
|
+
if (source?.route.route != null) {
|
|
34
|
+
const _route = { ...source.route.route, service, resolved: false, alias: to }
|
|
35
|
+
modules.push(module(route(to, _route.path, _route)) as M)
|
|
36
|
+
}
|
|
37
|
+
}
|
package/src/index.ts
ADDED
package/src/module.ts
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { CommonModule } from './types.js'
|
|
2
|
+
import { appendContextual } from '@owlmeans/context'
|
|
3
|
+
import type { CreateModuleSignature } from './utils/types.js'
|
|
4
|
+
|
|
5
|
+
export const module: CreateModuleSignature<CommonModule> = (route, opts) => {
|
|
6
|
+
let guards: string[] | null = null
|
|
7
|
+
let gates: [string, string[]][] | null = null
|
|
8
|
+
const module: CommonModule = appendContextual<CommonModule>(route.route.alias, {
|
|
9
|
+
_module: true,
|
|
10
|
+
|
|
11
|
+
sticky: false,
|
|
12
|
+
|
|
13
|
+
route,
|
|
14
|
+
|
|
15
|
+
getAlias: () => module.route.route.alias,
|
|
16
|
+
getPath: () => module.route.route.path,
|
|
17
|
+
getParentAlias: () => module.route.route.parent ?? null,
|
|
18
|
+
hasParent: () => module.getParentAlias() != null,
|
|
19
|
+
|
|
20
|
+
resolve: async <M extends CommonModule>() => {
|
|
21
|
+
if (module.ctx == null) {
|
|
22
|
+
throw new SyntaxError(`Module has no context yet - ${module.getAlias()}`)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
await module.route.resolve(module.ctx)
|
|
26
|
+
|
|
27
|
+
return module as M
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
getParent: () => {
|
|
31
|
+
const parent = module.getParentAlias()
|
|
32
|
+
if (parent == null) {
|
|
33
|
+
throw new SyntaxError(`Module has no parent - ${module.getAlias()}`)
|
|
34
|
+
}
|
|
35
|
+
if (module.ctx == null) {
|
|
36
|
+
throw new SyntaxError(`Module has no context yet - ${module.getAlias()}`)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return module.ctx.module(parent)
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
setService: service => {
|
|
43
|
+
if (module.route.route.resolved) {
|
|
44
|
+
throw new SyntaxError(`Cannot update a resolved module - ${module.getAlias()}`)
|
|
45
|
+
}
|
|
46
|
+
module.route.route.service = service
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
getGuards: () => {
|
|
50
|
+
if (guards != null) {
|
|
51
|
+
return guards
|
|
52
|
+
}
|
|
53
|
+
guards = module.guards ?? []
|
|
54
|
+
|
|
55
|
+
if (module.hasParent()) {
|
|
56
|
+
guards.push(
|
|
57
|
+
...module.getParent().getGuards().filter(guard => !guards?.includes(guard))
|
|
58
|
+
)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return guards
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
getGates: () => {
|
|
65
|
+
if (gates != null) {
|
|
66
|
+
return gates
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
gates = module.gate != null ? [[
|
|
70
|
+
module.gate, module.gateParams == null
|
|
71
|
+
? [] : Array.isArray(module.gateParams)
|
|
72
|
+
? module.gateParams : [module.gateParams]
|
|
73
|
+
]] : []
|
|
74
|
+
|
|
75
|
+
if (module.hasParent()) {
|
|
76
|
+
gates.push(
|
|
77
|
+
...module.getParent().getGates()
|
|
78
|
+
.filter(([gate]) => !gates?.some(([g]) => g === gate))
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return gates
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
...opts
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
return module
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export const parent = <T extends CommonModule | CommonModule[]>(module: T, aliasOrParent: string, _parent?: string): T => {
|
|
92
|
+
if (Array.isArray(module)) {
|
|
93
|
+
if (_parent == null) {
|
|
94
|
+
throw SyntaxError('Elevating parent requires parent name to be specified')
|
|
95
|
+
}
|
|
96
|
+
module = module.find(module => module.route.route.alias === aliasOrParent) as T
|
|
97
|
+
if (module == null) {
|
|
98
|
+
throw SyntaxError(`Module not found ${aliasOrParent}`)
|
|
99
|
+
}
|
|
100
|
+
return parent(module, _parent)
|
|
101
|
+
}
|
|
102
|
+
module.route.route.parent = aliasOrParent
|
|
103
|
+
|
|
104
|
+
return module
|
|
105
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { CommonRouteModel } from '@owlmeans/route'
|
|
2
|
+
import type { InitializedService, LazyService, BasicModule } from '@owlmeans/context'
|
|
3
|
+
import type { AnySchemaObject } from 'ajv'
|
|
4
|
+
import type { ModuleOutcome } from './consts.js'
|
|
5
|
+
import type { Auth } from '@owlmeans/auth'
|
|
6
|
+
|
|
7
|
+
export interface CommonModule extends BasicModule {
|
|
8
|
+
route: CommonRouteModel
|
|
9
|
+
/**
|
|
10
|
+
* @property {boolean} - if true — router attaches this module unconditionaly
|
|
11
|
+
* @default false
|
|
12
|
+
*/
|
|
13
|
+
sticky: boolean
|
|
14
|
+
filter?: Filter
|
|
15
|
+
guards?: string[]
|
|
16
|
+
gate?: string
|
|
17
|
+
gateParams?: string | string[]
|
|
18
|
+
handle?: ModuleHandler
|
|
19
|
+
getAlias: () => string
|
|
20
|
+
getPath: () => string
|
|
21
|
+
getParentAlias: () => string | null
|
|
22
|
+
hasParent: () => boolean
|
|
23
|
+
resolve: <M extends CommonModule>() => Promise<M>
|
|
24
|
+
getParent: <M extends CommonModule>() => M
|
|
25
|
+
setService: (service: string) => void
|
|
26
|
+
getGuards: () => string[]
|
|
27
|
+
getGates: () => [string, string[]][]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface CommonModuleOptions extends Partial<CommonModule> { }
|
|
31
|
+
|
|
32
|
+
export interface ModuleMatch {
|
|
33
|
+
<R extends AbstractRequest, P extends AbstractResponse<any>>(req: R, res: P): Promise<boolean>
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface ModuleHandler {
|
|
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 ModuleAssert {
|
|
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
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface AbstractResponse<T> {
|
|
63
|
+
responseProvider?: any
|
|
64
|
+
value?: T,
|
|
65
|
+
outcome?: ModuleOutcome
|
|
66
|
+
error?: Error
|
|
67
|
+
resolve: (value: T, outcome?: ModuleOutcome) => void
|
|
68
|
+
reject: (error: Error) => void
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface GuardService extends InitializedService {
|
|
72
|
+
// Client guard
|
|
73
|
+
token?: string
|
|
74
|
+
authenticated: (req?: Partial<AbstractRequest>) => Promise<string | null>
|
|
75
|
+
// Server guard
|
|
76
|
+
match: ModuleMatch
|
|
77
|
+
handle: ModuleHandler
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface GateService extends LazyService {
|
|
81
|
+
/**
|
|
82
|
+
* @throws {Error}
|
|
83
|
+
*/
|
|
84
|
+
assert: ModuleAssert
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface Filter {
|
|
88
|
+
query?: AnySchemaObject
|
|
89
|
+
params?: AnySchemaObject
|
|
90
|
+
body?: AnySchemaObject
|
|
91
|
+
response?: AnySchemaObject
|
|
92
|
+
headers?: AnySchemaObject
|
|
93
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": [
|
|
3
|
+
"../tsconfig.default.json",
|
|
4
|
+
],
|
|
5
|
+
"compilerOptions": {
|
|
6
|
+
"rootDir": "./src/", /* Specify the root folder within your source files. */
|
|
7
|
+
"outDir": "./build/", /* Specify an output folder for all emitted files. */
|
|
8
|
+
"moduleResolution": "Bundler"
|
|
9
|
+
},
|
|
10
|
+
"exclude": [
|
|
11
|
+
"./dist/**/*",
|
|
12
|
+
"./build/**/*",
|
|
13
|
+
"./*.ts"
|
|
14
|
+
]
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["./src/consts.ts","./src/filter.ts","./src/helper.ts","./src/index.ts","./src/module.ts","./src/types.ts","./src/utils/index.ts","./src/utils/module.ts","./src/utils/types.ts"],"version":"5.6.3"}
|