@e22m4u/ts-rest-router 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (145) hide show
  1. package/.c8rc +9 -0
  2. package/.commitlintrc +5 -0
  3. package/.editorconfig +13 -0
  4. package/.husky/commit-msg +1 -0
  5. package/.husky/pre-commit +6 -0
  6. package/.mocharc.json +5 -0
  7. package/.prettierrc +7 -0
  8. package/LICENSE +21 -0
  9. package/README-ru.md +41 -0
  10. package/README.md +41 -0
  11. package/build-cjs.js +16 -0
  12. package/dist/cjs/index.cjs +692 -0
  13. package/dist/esm/controller-registry.d.ts +65 -0
  14. package/dist/esm/controller-registry.js +281 -0
  15. package/dist/esm/controller-registry.spec.d.ts +1 -0
  16. package/dist/esm/controller-registry.spec.js +719 -0
  17. package/dist/esm/debuggable-service.d.ts +18 -0
  18. package/dist/esm/debuggable-service.js +23 -0
  19. package/dist/esm/debuggable-service.spec.d.ts +1 -0
  20. package/dist/esm/debuggable-service.spec.js +16 -0
  21. package/dist/esm/decorators/action/action-decorator.d.ts +53 -0
  22. package/dist/esm/decorators/action/action-decorator.js +66 -0
  23. package/dist/esm/decorators/action/action-decorator.spec.d.ts +1 -0
  24. package/dist/esm/decorators/action/action-decorator.spec.js +59 -0
  25. package/dist/esm/decorators/action/action-metadata.d.ts +23 -0
  26. package/dist/esm/decorators/action/action-metadata.js +5 -0
  27. package/dist/esm/decorators/action/action-reflector.d.ts +22 -0
  28. package/dist/esm/decorators/action/action-reflector.js +29 -0
  29. package/dist/esm/decorators/action/action-reflector.spec.d.ts +1 -0
  30. package/dist/esm/decorators/action/action-reflector.spec.js +84 -0
  31. package/dist/esm/decorators/action/index.d.ts +3 -0
  32. package/dist/esm/decorators/action/index.js +3 -0
  33. package/dist/esm/decorators/controller/controller-decorator.d.ts +13 -0
  34. package/dist/esm/decorators/controller/controller-decorator.js +20 -0
  35. package/dist/esm/decorators/controller/controller-decorator.spec.d.ts +1 -0
  36. package/dist/esm/decorators/controller/controller-decorator.spec.js +53 -0
  37. package/dist/esm/decorators/controller/controller-metadata.d.ts +17 -0
  38. package/dist/esm/decorators/controller/controller-metadata.js +5 -0
  39. package/dist/esm/decorators/controller/controller-reflector.d.ts +20 -0
  40. package/dist/esm/decorators/controller/controller-reflector.js +24 -0
  41. package/dist/esm/decorators/controller/controller-reflector.spec.d.ts +1 -0
  42. package/dist/esm/decorators/controller/controller-reflector.spec.js +45 -0
  43. package/dist/esm/decorators/controller/index.d.ts +3 -0
  44. package/dist/esm/decorators/controller/index.js +3 -0
  45. package/dist/esm/decorators/index.d.ts +4 -0
  46. package/dist/esm/decorators/index.js +4 -0
  47. package/dist/esm/decorators/request-context/index.d.ts +3 -0
  48. package/dist/esm/decorators/request-context/index.js +3 -0
  49. package/dist/esm/decorators/request-context/request-context-decorator.d.ts +17 -0
  50. package/dist/esm/decorators/request-context/request-context-decorator.js +32 -0
  51. package/dist/esm/decorators/request-context/request-context-decorator.spec.d.ts +1 -0
  52. package/dist/esm/decorators/request-context/request-context-decorator.spec.js +59 -0
  53. package/dist/esm/decorators/request-context/request-context-metadata.d.ts +17 -0
  54. package/dist/esm/decorators/request-context/request-context-metadata.js +5 -0
  55. package/dist/esm/decorators/request-context/request-context-reflector.d.ts +24 -0
  56. package/dist/esm/decorators/request-context/request-context-reflector.js +31 -0
  57. package/dist/esm/decorators/request-context/request-context-reflector.spec.d.ts +1 -0
  58. package/dist/esm/decorators/request-context/request-context-reflector.spec.js +59 -0
  59. package/dist/esm/decorators/request-data/index.d.ts +3 -0
  60. package/dist/esm/decorators/request-data/index.js +3 -0
  61. package/dist/esm/decorators/request-data/request-data-decorator.d.ts +28 -0
  62. package/dist/esm/decorators/request-data/request-data-decorator.js +84 -0
  63. package/dist/esm/decorators/request-data/request-data-decorator.spec.d.ts +1 -0
  64. package/dist/esm/decorators/request-data/request-data-decorator.spec.js +534 -0
  65. package/dist/esm/decorators/request-data/request-data-metadata.d.ts +29 -0
  66. package/dist/esm/decorators/request-data/request-data-metadata.js +16 -0
  67. package/dist/esm/decorators/request-data/request-data-reflector.d.ts +24 -0
  68. package/dist/esm/decorators/request-data/request-data-reflector.js +31 -0
  69. package/dist/esm/decorators/request-data/request-data-reflector.spec.d.ts +1 -0
  70. package/dist/esm/decorators/request-data/request-data-reflector.spec.js +60 -0
  71. package/dist/esm/errors/index.d.ts +1 -0
  72. package/dist/esm/errors/index.js +1 -0
  73. package/dist/esm/errors/not-a-controller-error.d.ts +12 -0
  74. package/dist/esm/errors/not-a-controller-error.js +14 -0
  75. package/dist/esm/index.d.ts +5 -0
  76. package/dist/esm/index.js +5 -0
  77. package/dist/esm/rest-router.d.ts +19 -0
  78. package/dist/esm/rest-router.js +24 -0
  79. package/dist/esm/types.d.ts +57 -0
  80. package/dist/esm/types.js +2 -0
  81. package/dist/esm/utils/capitalize.d.ts +6 -0
  82. package/dist/esm/utils/capitalize.js +8 -0
  83. package/dist/esm/utils/capitalize.spec.d.ts +1 -0
  84. package/dist/esm/utils/capitalize.spec.js +8 -0
  85. package/dist/esm/utils/create-debugger.d.ts +11 -0
  86. package/dist/esm/utils/create-debugger.js +15 -0
  87. package/dist/esm/utils/create-debugger.spec.d.ts +1 -0
  88. package/dist/esm/utils/create-debugger.spec.js +8 -0
  89. package/dist/esm/utils/create-error.d.ts +10 -0
  90. package/dist/esm/utils/create-error.js +13 -0
  91. package/dist/esm/utils/create-error.spec.d.ts +1 -0
  92. package/dist/esm/utils/create-error.spec.js +8 -0
  93. package/dist/esm/utils/index.d.ts +4 -0
  94. package/dist/esm/utils/index.js +4 -0
  95. package/dist/esm/utils/to-camel-case.d.ts +6 -0
  96. package/dist/esm/utils/to-camel-case.js +11 -0
  97. package/dist/esm/utils/to-camel-case.spec.d.ts +1 -0
  98. package/dist/esm/utils/to-camel-case.spec.js +10 -0
  99. package/dist/tsconfig.tsbuildinfo +1 -0
  100. package/eslint.config.js +43 -0
  101. package/package.json +74 -0
  102. package/src/controller-registry.spec.ts +592 -0
  103. package/src/controller-registry.ts +355 -0
  104. package/src/debuggable-service.spec.ts +18 -0
  105. package/src/debuggable-service.ts +27 -0
  106. package/src/decorators/action/action-decorator.spec.ts +42 -0
  107. package/src/decorators/action/action-decorator.ts +100 -0
  108. package/src/decorators/action/action-metadata.ts +28 -0
  109. package/src/decorators/action/action-reflector.spec.ts +84 -0
  110. package/src/decorators/action/action-reflector.ts +38 -0
  111. package/src/decorators/action/index.ts +3 -0
  112. package/src/decorators/controller/controller-decorator.spec.ts +41 -0
  113. package/src/decorators/controller/controller-decorator.ts +29 -0
  114. package/src/decorators/controller/controller-metadata.ts +21 -0
  115. package/src/decorators/controller/controller-reflector.spec.ts +45 -0
  116. package/src/decorators/controller/controller-reflector.ts +28 -0
  117. package/src/decorators/controller/index.ts +3 -0
  118. package/src/decorators/index.ts +4 -0
  119. package/src/decorators/request-context/index.ts +3 -0
  120. package/src/decorators/request-context/request-context-decorator.spec.ts +41 -0
  121. package/src/decorators/request-context/request-context-decorator.ts +57 -0
  122. package/src/decorators/request-context/request-context-metadata.ts +21 -0
  123. package/src/decorators/request-context/request-context-reflector.spec.ts +77 -0
  124. package/src/decorators/request-context/request-context-reflector.ts +57 -0
  125. package/src/decorators/request-data/index.ts +3 -0
  126. package/src/decorators/request-data/request-data-decorator.spec.ts +477 -0
  127. package/src/decorators/request-data/request-data-decorator.ts +106 -0
  128. package/src/decorators/request-data/request-data-metadata.ts +34 -0
  129. package/src/decorators/request-data/request-data-reflector.spec.ts +78 -0
  130. package/src/decorators/request-data/request-data-reflector.ts +57 -0
  131. package/src/errors/index.ts +1 -0
  132. package/src/errors/not-a-controller-error.ts +15 -0
  133. package/src/index.ts +5 -0
  134. package/src/rest-router.ts +31 -0
  135. package/src/types.ts +59 -0
  136. package/src/utils/capitalize.spec.ts +9 -0
  137. package/src/utils/capitalize.ts +8 -0
  138. package/src/utils/create-debugger.spec.ts +9 -0
  139. package/src/utils/create-debugger.ts +21 -0
  140. package/src/utils/create-error.spec.ts +9 -0
  141. package/src/utils/create-error.ts +19 -0
  142. package/src/utils/index.ts +4 -0
  143. package/src/utils/to-camel-case.spec.ts +11 -0
  144. package/src/utils/to-camel-case.ts +11 -0
  145. 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,5 @@
1
+ export * from './utils/index.js';
2
+ export * from './rest-router.js';
3
+ export * from './errors/index.js';
4
+ export * from './decorators/index.js';
5
+ export * from './controller-registry.js';
@@ -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,8 @@
1
+ /**
2
+ * Capitalize.
3
+ *
4
+ * @param input
5
+ */
6
+ export function capitalize(input: string): string {
7
+ return input.charAt(0).toUpperCase() + input.slice(1);
8
+ }
@@ -0,0 +1,9 @@
1
+ import {expect} from 'chai';
2
+ import {createDebugger} from './create-debugger.js';
3
+
4
+ describe('createDebugger', function () {
5
+ it('returns a function', function () {
6
+ const res = createDebugger('name');
7
+ expect(typeof res).to.be.eq('function');
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,4 @@
1
+ export * from './capitalize.js';
2
+ export * from './create-error.js';
3
+ export * from './to-camel-case.js';
4
+ export * from './create-debugger.js';
@@ -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
+ });
@@ -0,0 +1,11 @@
1
+ /**
2
+ * To camel case.
3
+ *
4
+ * @param input
5
+ */
6
+ export function toCamelCase(input: string): string {
7
+ return input
8
+ .replace(/(^\w|[A-Z]|\b\w)/g, c => c.toUpperCase())
9
+ .replace(/\W+/g, '')
10
+ .replace(/(^\w)/g, c => c.toLowerCase());
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
+ }