@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.
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
+ }