@e22m4u/ts-rest-router 0.0.2
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/.c8rc +9 -0
- package/.commitlintrc +5 -0
- package/.editorconfig +13 -0
- package/.husky/commit-msg +1 -0
- package/.husky/pre-commit +6 -0
- package/.mocharc.json +5 -0
- package/.prettierrc +7 -0
- package/LICENSE +21 -0
- package/README-ru.md +41 -0
- package/README.md +41 -0
- package/build-cjs.js +16 -0
- package/dist/cjs/index.cjs +692 -0
- package/dist/esm/controller-registry.d.ts +65 -0
- package/dist/esm/controller-registry.js +281 -0
- package/dist/esm/controller-registry.spec.d.ts +1 -0
- package/dist/esm/controller-registry.spec.js +719 -0
- package/dist/esm/debuggable-service.d.ts +18 -0
- package/dist/esm/debuggable-service.js +23 -0
- package/dist/esm/debuggable-service.spec.d.ts +1 -0
- package/dist/esm/debuggable-service.spec.js +16 -0
- package/dist/esm/decorators/action/action-decorator.d.ts +53 -0
- package/dist/esm/decorators/action/action-decorator.js +66 -0
- package/dist/esm/decorators/action/action-decorator.spec.d.ts +1 -0
- package/dist/esm/decorators/action/action-decorator.spec.js +59 -0
- package/dist/esm/decorators/action/action-metadata.d.ts +23 -0
- package/dist/esm/decorators/action/action-metadata.js +5 -0
- package/dist/esm/decorators/action/action-reflector.d.ts +22 -0
- package/dist/esm/decorators/action/action-reflector.js +29 -0
- package/dist/esm/decorators/action/action-reflector.spec.d.ts +1 -0
- package/dist/esm/decorators/action/action-reflector.spec.js +84 -0
- package/dist/esm/decorators/action/index.d.ts +3 -0
- package/dist/esm/decorators/action/index.js +3 -0
- package/dist/esm/decorators/controller/controller-decorator.d.ts +13 -0
- package/dist/esm/decorators/controller/controller-decorator.js +20 -0
- package/dist/esm/decorators/controller/controller-decorator.spec.d.ts +1 -0
- package/dist/esm/decorators/controller/controller-decorator.spec.js +53 -0
- package/dist/esm/decorators/controller/controller-metadata.d.ts +17 -0
- package/dist/esm/decorators/controller/controller-metadata.js +5 -0
- package/dist/esm/decorators/controller/controller-reflector.d.ts +20 -0
- package/dist/esm/decorators/controller/controller-reflector.js +24 -0
- package/dist/esm/decorators/controller/controller-reflector.spec.d.ts +1 -0
- package/dist/esm/decorators/controller/controller-reflector.spec.js +45 -0
- package/dist/esm/decorators/controller/index.d.ts +3 -0
- package/dist/esm/decorators/controller/index.js +3 -0
- package/dist/esm/decorators/index.d.ts +4 -0
- package/dist/esm/decorators/index.js +4 -0
- package/dist/esm/decorators/request-context/index.d.ts +3 -0
- package/dist/esm/decorators/request-context/index.js +3 -0
- package/dist/esm/decorators/request-context/request-context-decorator.d.ts +17 -0
- package/dist/esm/decorators/request-context/request-context-decorator.js +32 -0
- package/dist/esm/decorators/request-context/request-context-decorator.spec.d.ts +1 -0
- package/dist/esm/decorators/request-context/request-context-decorator.spec.js +59 -0
- package/dist/esm/decorators/request-context/request-context-metadata.d.ts +17 -0
- package/dist/esm/decorators/request-context/request-context-metadata.js +5 -0
- package/dist/esm/decorators/request-context/request-context-reflector.d.ts +24 -0
- package/dist/esm/decorators/request-context/request-context-reflector.js +31 -0
- package/dist/esm/decorators/request-context/request-context-reflector.spec.d.ts +1 -0
- package/dist/esm/decorators/request-context/request-context-reflector.spec.js +59 -0
- package/dist/esm/decorators/request-data/index.d.ts +3 -0
- package/dist/esm/decorators/request-data/index.js +3 -0
- package/dist/esm/decorators/request-data/request-data-decorator.d.ts +28 -0
- package/dist/esm/decorators/request-data/request-data-decorator.js +84 -0
- package/dist/esm/decorators/request-data/request-data-decorator.spec.d.ts +1 -0
- package/dist/esm/decorators/request-data/request-data-decorator.spec.js +534 -0
- package/dist/esm/decorators/request-data/request-data-metadata.d.ts +29 -0
- package/dist/esm/decorators/request-data/request-data-metadata.js +16 -0
- package/dist/esm/decorators/request-data/request-data-reflector.d.ts +24 -0
- package/dist/esm/decorators/request-data/request-data-reflector.js +31 -0
- package/dist/esm/decorators/request-data/request-data-reflector.spec.d.ts +1 -0
- package/dist/esm/decorators/request-data/request-data-reflector.spec.js +60 -0
- package/dist/esm/errors/index.d.ts +1 -0
- package/dist/esm/errors/index.js +1 -0
- package/dist/esm/errors/not-a-controller-error.d.ts +12 -0
- package/dist/esm/errors/not-a-controller-error.js +14 -0
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/rest-router.d.ts +19 -0
- package/dist/esm/rest-router.js +24 -0
- package/dist/esm/types.d.ts +57 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/utils/capitalize.d.ts +6 -0
- package/dist/esm/utils/capitalize.js +8 -0
- package/dist/esm/utils/capitalize.spec.d.ts +1 -0
- package/dist/esm/utils/capitalize.spec.js +8 -0
- package/dist/esm/utils/create-debugger.d.ts +11 -0
- package/dist/esm/utils/create-debugger.js +15 -0
- package/dist/esm/utils/create-debugger.spec.d.ts +1 -0
- package/dist/esm/utils/create-debugger.spec.js +8 -0
- package/dist/esm/utils/create-error.d.ts +10 -0
- package/dist/esm/utils/create-error.js +13 -0
- package/dist/esm/utils/create-error.spec.d.ts +1 -0
- package/dist/esm/utils/create-error.spec.js +8 -0
- package/dist/esm/utils/index.d.ts +4 -0
- package/dist/esm/utils/index.js +4 -0
- package/dist/esm/utils/to-camel-case.d.ts +6 -0
- package/dist/esm/utils/to-camel-case.js +11 -0
- package/dist/esm/utils/to-camel-case.spec.d.ts +1 -0
- package/dist/esm/utils/to-camel-case.spec.js +10 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/eslint.config.js +43 -0
- package/package.json +74 -0
- package/src/controller-registry.spec.ts +592 -0
- package/src/controller-registry.ts +355 -0
- package/src/debuggable-service.spec.ts +18 -0
- package/src/debuggable-service.ts +27 -0
- package/src/decorators/action/action-decorator.spec.ts +42 -0
- package/src/decorators/action/action-decorator.ts +100 -0
- package/src/decorators/action/action-metadata.ts +28 -0
- package/src/decorators/action/action-reflector.spec.ts +84 -0
- package/src/decorators/action/action-reflector.ts +38 -0
- package/src/decorators/action/index.ts +3 -0
- package/src/decorators/controller/controller-decorator.spec.ts +41 -0
- package/src/decorators/controller/controller-decorator.ts +29 -0
- package/src/decorators/controller/controller-metadata.ts +21 -0
- package/src/decorators/controller/controller-reflector.spec.ts +45 -0
- package/src/decorators/controller/controller-reflector.ts +28 -0
- package/src/decorators/controller/index.ts +3 -0
- package/src/decorators/index.ts +4 -0
- package/src/decorators/request-context/index.ts +3 -0
- package/src/decorators/request-context/request-context-decorator.spec.ts +41 -0
- package/src/decorators/request-context/request-context-decorator.ts +57 -0
- package/src/decorators/request-context/request-context-metadata.ts +21 -0
- package/src/decorators/request-context/request-context-reflector.spec.ts +77 -0
- package/src/decorators/request-context/request-context-reflector.ts +57 -0
- package/src/decorators/request-data/index.ts +3 -0
- package/src/decorators/request-data/request-data-decorator.spec.ts +477 -0
- package/src/decorators/request-data/request-data-decorator.ts +106 -0
- package/src/decorators/request-data/request-data-metadata.ts +34 -0
- package/src/decorators/request-data/request-data-reflector.spec.ts +78 -0
- package/src/decorators/request-data/request-data-reflector.ts +57 -0
- package/src/errors/index.ts +1 -0
- package/src/errors/not-a-controller-error.ts +15 -0
- package/src/index.ts +5 -0
- package/src/rest-router.ts +31 -0
- package/src/types.ts +59 -0
- package/src/utils/capitalize.spec.ts +9 -0
- package/src/utils/capitalize.ts +8 -0
- package/src/utils/create-debugger.spec.ts +9 -0
- package/src/utils/create-debugger.ts +21 -0
- package/src/utils/create-error.spec.ts +9 -0
- package/src/utils/create-error.ts +19 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/to-camel-case.spec.ts +11 -0
- package/src/utils/to-camel-case.ts +11 -0
- package/tsconfig.json +17 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import {Constructor} from '../../types.js';
|
|
2
|
+
import {Reflector} from '@e22m4u/ts-reflector';
|
|
3
|
+
import {RequestDataMetadata} from './request-data-metadata.js';
|
|
4
|
+
import {RequestDataMetadataMap} from './request-data-metadata.js';
|
|
5
|
+
import {REQUEST_DATA_METADATA_KEY} from './request-data-metadata.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Request data reflector.
|
|
9
|
+
*/
|
|
10
|
+
export class RequestDataReflector {
|
|
11
|
+
/**
|
|
12
|
+
* Set metadata.
|
|
13
|
+
*
|
|
14
|
+
* @param metadata
|
|
15
|
+
* @param target
|
|
16
|
+
* @param index
|
|
17
|
+
* @param propertyKey
|
|
18
|
+
*/
|
|
19
|
+
static setMetadata(
|
|
20
|
+
metadata: RequestDataMetadata,
|
|
21
|
+
target: Constructor,
|
|
22
|
+
index: number,
|
|
23
|
+
propertyKey: string,
|
|
24
|
+
) {
|
|
25
|
+
const oldMap = Reflector.getOwnMetadata(
|
|
26
|
+
REQUEST_DATA_METADATA_KEY,
|
|
27
|
+
target,
|
|
28
|
+
propertyKey,
|
|
29
|
+
);
|
|
30
|
+
const newMap = new Map(oldMap);
|
|
31
|
+
newMap.set(index, metadata);
|
|
32
|
+
Reflector.defineMetadata(
|
|
33
|
+
REQUEST_DATA_METADATA_KEY,
|
|
34
|
+
newMap,
|
|
35
|
+
target,
|
|
36
|
+
propertyKey,
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Get metadata.
|
|
42
|
+
*
|
|
43
|
+
* @param target
|
|
44
|
+
* @param propertyKey
|
|
45
|
+
*/
|
|
46
|
+
static getMetadata(
|
|
47
|
+
target: Constructor,
|
|
48
|
+
propertyKey: string,
|
|
49
|
+
): RequestDataMetadataMap {
|
|
50
|
+
const metadata = Reflector.getOwnMetadata(
|
|
51
|
+
REQUEST_DATA_METADATA_KEY,
|
|
52
|
+
target,
|
|
53
|
+
propertyKey,
|
|
54
|
+
);
|
|
55
|
+
return metadata ?? new Map();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './not-a-controller-error.js';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {Errorf} from '@e22m4u/js-format';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Not a controller error.
|
|
5
|
+
*/
|
|
6
|
+
export class NotAControllerError extends Errorf {
|
|
7
|
+
/**
|
|
8
|
+
* Constructor.
|
|
9
|
+
*
|
|
10
|
+
* @param value
|
|
11
|
+
*/
|
|
12
|
+
constructor(value: unknown) {
|
|
13
|
+
super('%v is not a controller, do use @controller decorator on it.', value);
|
|
14
|
+
}
|
|
15
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {Constructor} from './types.js';
|
|
2
|
+
import {TrieRouter} from '@e22m4u/js-trie-router';
|
|
3
|
+
import {DebuggableService} from './debuggable-service.js';
|
|
4
|
+
import {ControllerRegistry} from './controller-registry.js';
|
|
5
|
+
import {ControllerRootOptions} from './controller-registry.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Rest router.
|
|
9
|
+
*/
|
|
10
|
+
export class RestRouter extends DebuggableService {
|
|
11
|
+
/**
|
|
12
|
+
* Request listener.
|
|
13
|
+
*/
|
|
14
|
+
get requestListener() {
|
|
15
|
+
return this.getService(TrieRouter).requestListener;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Add controller.
|
|
20
|
+
*
|
|
21
|
+
* @param ctor
|
|
22
|
+
* @param options
|
|
23
|
+
*/
|
|
24
|
+
addController<T extends object>(
|
|
25
|
+
ctor: Constructor<T>,
|
|
26
|
+
options?: ControllerRootOptions,
|
|
27
|
+
): this {
|
|
28
|
+
this.getService(ControllerRegistry).addController(ctor, options);
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/* eslint @typescript-eslint/no-explicit-any: 0 */
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Function type that excludes
|
|
5
|
+
* class and constructor types.
|
|
6
|
+
*/
|
|
7
|
+
export type Callable<T = unknown> = (...args: any[]) => T;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Callable type with the "new" operator
|
|
11
|
+
* that allows class and constructor types.
|
|
12
|
+
*/
|
|
13
|
+
export interface Constructor<T = unknown> {
|
|
14
|
+
new (...args: any[]): T;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Object prototype that excludes
|
|
19
|
+
* function and scalar values.
|
|
20
|
+
*/
|
|
21
|
+
export type Prototype<T = unknown> = T &
|
|
22
|
+
object & {bind?: never} & {call?: never} & {prototype?: object};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Make a specific property as optional.
|
|
26
|
+
*/
|
|
27
|
+
export type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* A part of the Flatten type.
|
|
31
|
+
*/
|
|
32
|
+
export type Identity<T> = T;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Makes T more human-readable.
|
|
36
|
+
*/
|
|
37
|
+
export type Flatten<T> = Identity<{[k in keyof T]: T[k]}>;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* A promise or value.
|
|
41
|
+
*/
|
|
42
|
+
export type ValueOrPromise<T> = T | PromiseLike<T>;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Plain object.
|
|
46
|
+
*/
|
|
47
|
+
export type PlainObject = {[key: string]: unknown};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Remove null and undefined from T.
|
|
51
|
+
*/
|
|
52
|
+
export type NoUndef<T> = Exclude<T, null | undefined>;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Object type with open properties.
|
|
56
|
+
*/
|
|
57
|
+
export type AnyObject = {
|
|
58
|
+
[property: PropertyKey]: any;
|
|
59
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import {expect} from 'chai';
|
|
2
|
+
import {capitalize} from './capitalize.js';
|
|
3
|
+
|
|
4
|
+
describe('capitalize', function () {
|
|
5
|
+
it('makes the first letter to upper case', function () {
|
|
6
|
+
expect(capitalize('foo')).to.be.eq('Foo');
|
|
7
|
+
expect(capitalize('foo bar')).to.be.eq('Foo bar');
|
|
8
|
+
});
|
|
9
|
+
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import DebugFactory from 'debug';
|
|
2
|
+
import {format} from '@e22m4u/js-format';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Debugger.
|
|
6
|
+
*/
|
|
7
|
+
export type Debugger = (...args: Parameters<typeof format>) => void;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Create debugger.
|
|
11
|
+
*
|
|
12
|
+
* @param name
|
|
13
|
+
*/
|
|
14
|
+
export function createDebugger(name: string): Debugger {
|
|
15
|
+
const debug = DebugFactory(`tsRestRouter:${name}`);
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
17
|
+
return function (message: string, ...args: any[]) {
|
|
18
|
+
const interpolatedMessage = format(message, ...args);
|
|
19
|
+
return debug(interpolatedMessage);
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import {expect} from 'chai';
|
|
2
|
+
import {createError} from './create-error.js';
|
|
3
|
+
|
|
4
|
+
describe('createError', function () {
|
|
5
|
+
it('interpolates the given message with arguments', function () {
|
|
6
|
+
const res = createError(Error, 'My %s', 'message');
|
|
7
|
+
expect(res.message).to.be.eq('My message');
|
|
8
|
+
});
|
|
9
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {Constructor} from '../types.js';
|
|
2
|
+
import {format} from '@e22m4u/js-format';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Create error.
|
|
6
|
+
*
|
|
7
|
+
* @param {Function} errorCtor
|
|
8
|
+
* @param {string} message
|
|
9
|
+
* @param {*[]|undefined} args
|
|
10
|
+
* @returns {object}
|
|
11
|
+
*/
|
|
12
|
+
export function createError<T>(
|
|
13
|
+
errorCtor: Constructor<T>,
|
|
14
|
+
message: string,
|
|
15
|
+
...args: unknown[]
|
|
16
|
+
): T {
|
|
17
|
+
const interpolatedMessage = format(message, ...args);
|
|
18
|
+
return new errorCtor(interpolatedMessage);
|
|
19
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import {expect} from 'chai';
|
|
2
|
+
import {toCamelCase} from './to-camel-case.js';
|
|
3
|
+
|
|
4
|
+
describe('toCamelCase', function () {
|
|
5
|
+
it('returns a camelCase string', function () {
|
|
6
|
+
expect(toCamelCase('TestString')).to.be.eq('testString');
|
|
7
|
+
expect(toCamelCase('test-string')).to.be.eq('testString');
|
|
8
|
+
expect(toCamelCase('test string')).to.be.eq('testString');
|
|
9
|
+
expect(toCamelCase('Test string')).to.be.eq('testString');
|
|
10
|
+
});
|
|
11
|
+
});
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"rootDir": "src",
|
|
4
|
+
"outDir": "dist/esm",
|
|
5
|
+
"target": "es2022",
|
|
6
|
+
"module": "NodeNext",
|
|
7
|
+
"moduleResolution": "NodeNext",
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"forceConsistentCasingInFileNames": true,
|
|
10
|
+
"strict": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"declaration": true,
|
|
13
|
+
"emitDecoratorMetadata": true,
|
|
14
|
+
"experimentalDecorators": true,
|
|
15
|
+
"resolveJsonModule": true
|
|
16
|
+
}
|
|
17
|
+
}
|