te.js 2.0.3 → 2.1.1

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 (68) hide show
  1. package/README.md +197 -187
  2. package/auto-docs/analysis/handler-analyzer.js +58 -58
  3. package/auto-docs/analysis/source-resolver.js +101 -101
  4. package/auto-docs/constants.js +37 -37
  5. package/auto-docs/docs-llm/index.js +7 -0
  6. package/auto-docs/{llm → docs-llm}/prompts.js +222 -222
  7. package/auto-docs/{llm → docs-llm}/provider.js +132 -187
  8. package/auto-docs/index.js +146 -146
  9. package/auto-docs/openapi/endpoint-processor.js +277 -277
  10. package/auto-docs/openapi/generator.js +107 -107
  11. package/auto-docs/openapi/level3.js +131 -131
  12. package/auto-docs/openapi/spec-builders.js +244 -244
  13. package/auto-docs/ui/docs-ui.js +186 -186
  14. package/auto-docs/utils/logger.js +17 -17
  15. package/auto-docs/utils/strip-usage.js +10 -10
  16. package/cli/docs-command.js +315 -315
  17. package/cli/fly-command.js +71 -71
  18. package/cli/index.js +56 -56
  19. package/database/index.js +165 -165
  20. package/database/mongodb.js +146 -146
  21. package/database/redis.js +201 -201
  22. package/docs/README.md +36 -36
  23. package/docs/ammo.md +362 -362
  24. package/docs/api-reference.md +490 -489
  25. package/docs/auto-docs.md +216 -215
  26. package/docs/cli.md +152 -152
  27. package/docs/configuration.md +275 -233
  28. package/docs/database.md +390 -391
  29. package/docs/error-handling.md +438 -417
  30. package/docs/file-uploads.md +333 -334
  31. package/docs/getting-started.md +214 -215
  32. package/docs/middleware.md +355 -356
  33. package/docs/rate-limiting.md +393 -394
  34. package/docs/routing.md +302 -302
  35. package/package.json +62 -62
  36. package/rate-limit/algorithms/fixed-window.js +141 -141
  37. package/rate-limit/algorithms/sliding-window.js +147 -147
  38. package/rate-limit/algorithms/token-bucket.js +115 -115
  39. package/rate-limit/base.js +165 -165
  40. package/rate-limit/index.js +147 -147
  41. package/rate-limit/storage/base.js +104 -104
  42. package/rate-limit/storage/memory.js +101 -101
  43. package/rate-limit/storage/redis.js +88 -88
  44. package/server/ammo/body-parser.js +220 -220
  45. package/server/ammo/dispatch-helper.js +103 -103
  46. package/server/ammo/enhancer.js +57 -57
  47. package/server/ammo.js +454 -356
  48. package/server/endpoint.js +97 -74
  49. package/server/error.js +9 -9
  50. package/server/errors/code-context.js +125 -0
  51. package/server/errors/llm-error-service.js +140 -0
  52. package/server/files/helper.js +33 -33
  53. package/server/files/uploader.js +143 -143
  54. package/server/handler.js +158 -113
  55. package/server/target.js +185 -175
  56. package/server/targets/middleware-validator.js +22 -22
  57. package/server/targets/path-validator.js +21 -21
  58. package/server/targets/registry.js +160 -160
  59. package/server/targets/shoot-validator.js +21 -21
  60. package/te.js +428 -363
  61. package/utils/auto-register.js +17 -17
  62. package/utils/configuration.js +64 -64
  63. package/utils/errors-llm-config.js +84 -0
  64. package/utils/request-logger.js +43 -43
  65. package/utils/status-codes.js +82 -82
  66. package/utils/tejas-entrypoint-html.js +18 -18
  67. package/auto-docs/llm/index.js +0 -6
  68. package/auto-docs/llm/parse.js +0 -88
@@ -1,160 +1,160 @@
1
- import isMiddlewareValid from './middleware-validator.js';
2
- import { standardizePath } from './path-validator.js';
3
-
4
- class TargetRegistry {
5
- constructor() {
6
- if (TargetRegistry.instance) {
7
- return TargetRegistry.instance;
8
- }
9
-
10
- TargetRegistry.instance = this;
11
-
12
- // TODO - Add a default target
13
- this.targets = [];
14
- this.globalMiddlewares = [];
15
- /** Current source group (target file id) set by loader before importing a target file. */
16
- this._currentSourceGroup = null;
17
- }
18
-
19
- setCurrentSourceGroup(group) {
20
- this._currentSourceGroup = group ?? null;
21
- }
22
-
23
- getCurrentSourceGroup() {
24
- return this._currentSourceGroup;
25
- }
26
-
27
- addGlobalMiddleware() {
28
- if (!arguments) return;
29
-
30
- const middlewares = [...arguments];
31
- const validMiddlewares = middlewares.filter(isMiddlewareValid);
32
- this.globalMiddlewares = this.globalMiddlewares.concat(validMiddlewares);
33
- }
34
-
35
- /**
36
- * @param {Array || Object} targets
37
- */
38
- register(targets) {
39
- if (Array.isArray(targets)) {
40
- this.targets = this.targets.concat(targets);
41
- } else {
42
- this.targets.push(targets);
43
- }
44
- }
45
-
46
- /**
47
- * Matches an endpoint URL to a registered target, supporting parameterized routes.
48
- *
49
- * @param {string} endpoint - The endpoint URL to match
50
- * @returns {Object|null} An object with `target` and `params`, or null if no match
51
- */
52
- aim(endpoint) {
53
- const standardizedEndpoint = standardizePath(endpoint);
54
-
55
- // First, try exact match (most specific)
56
- const exactMatch = this.targets.find((target) => {
57
- return target.getPath() === standardizedEndpoint;
58
- });
59
-
60
- if (exactMatch) {
61
- return { target: exactMatch, params: {} };
62
- }
63
-
64
- // Then, try parameterized route matching
65
- for (const target of this.targets) {
66
- const targetPath = target.getPath();
67
- const params = this.matchParameterizedRoute(
68
- targetPath,
69
- standardizedEndpoint,
70
- );
71
-
72
- if (params !== null) {
73
- return { target, params };
74
- }
75
- }
76
-
77
- return null;
78
- }
79
-
80
- /**
81
- * Matches a parameterized route pattern against an actual URL.
82
- *
83
- * @param {string} pattern - The route pattern (e.g., '/api/categories/:id')
84
- * @param {string} url - The actual URL to match (e.g., '/api/categories/123')
85
- * @returns {Object|null} An object with extracted parameters, or null if no match
86
- */
87
- matchParameterizedRoute(pattern, url) {
88
- // Handle root path case
89
- if (pattern === '/' && url === '/') {
90
- return {};
91
- }
92
-
93
- // Split both pattern and URL into segments
94
- const patternSegments = pattern.split('/').filter((s) => s.length > 0);
95
- const urlSegments = url.split('/').filter((s) => s.length > 0);
96
-
97
- // Must have same number of segments
98
- if (patternSegments.length !== urlSegments.length) {
99
- return null;
100
- }
101
-
102
- // If both are empty (root paths), they match
103
- if (patternSegments.length === 0 && urlSegments.length === 0) {
104
- return {};
105
- }
106
-
107
- const params = {};
108
-
109
- // Match each segment
110
- for (let i = 0; i < patternSegments.length; i++) {
111
- const patternSegment = patternSegments[i];
112
- const urlSegment = urlSegments[i];
113
-
114
- // If it's a parameter (starts with :)
115
- if (patternSegment.startsWith(':')) {
116
- const paramName = patternSegment.slice(1); // Remove the ':'
117
- params[paramName] = urlSegment;
118
- } else if (patternSegment !== urlSegment) {
119
- // If it's not a parameter and doesn't match, no match
120
- return null;
121
- }
122
- }
123
-
124
- return params;
125
- }
126
-
127
- /**
128
- * Get all registered endpoints.
129
- *
130
- * @param {boolean|{ detailed?: boolean, grouped?: boolean }} [options] - If boolean, treated as grouped (backward compat).
131
- * If object: detailed=true returns full metadata per endpoint; grouped=true returns paths grouped by first segment.
132
- * @returns {string[]|Object|Array<{ path: string, metadata: object|null, handler: function }>}
133
- */
134
- getAllEndpoints(options = {}) {
135
- const grouped =
136
- typeof options === 'boolean' ? options : (options && options.grouped);
137
- const detailed =
138
- typeof options === 'object' && options && options.detailed === true;
139
-
140
- if (detailed) {
141
- return this.targets.map((t) => ({
142
- path: t.getPath(),
143
- metadata: t.getMetadata(),
144
- handler: t.getHandler(),
145
- }));
146
- }
147
- if (grouped) {
148
- return this.targets.reduce((acc, target) => {
149
- const group = target.getPath().split('/')[1];
150
- if (!acc[group]) acc[group] = [];
151
- acc[group].push(target.getPath());
152
- return acc;
153
- }, {});
154
- }
155
- return this.targets.map((target) => target.getPath());
156
- }
157
- }
158
-
159
- const targetRegistry = new TargetRegistry();
160
- export default targetRegistry;
1
+ import isMiddlewareValid from './middleware-validator.js';
2
+ import { standardizePath } from './path-validator.js';
3
+
4
+ class TargetRegistry {
5
+ constructor() {
6
+ if (TargetRegistry.instance) {
7
+ return TargetRegistry.instance;
8
+ }
9
+
10
+ TargetRegistry.instance = this;
11
+
12
+ // TODO - Add a default target
13
+ this.targets = [];
14
+ this.globalMiddlewares = [];
15
+ /** Current source group (target file id) set by loader before importing a target file. */
16
+ this._currentSourceGroup = null;
17
+ }
18
+
19
+ setCurrentSourceGroup(group) {
20
+ this._currentSourceGroup = group ?? null;
21
+ }
22
+
23
+ getCurrentSourceGroup() {
24
+ return this._currentSourceGroup;
25
+ }
26
+
27
+ addGlobalMiddleware() {
28
+ if (!arguments) return;
29
+
30
+ const middlewares = [...arguments];
31
+ const validMiddlewares = middlewares.filter(isMiddlewareValid);
32
+ this.globalMiddlewares = this.globalMiddlewares.concat(validMiddlewares);
33
+ }
34
+
35
+ /**
36
+ * @param {Array || Object} targets
37
+ */
38
+ register(targets) {
39
+ if (Array.isArray(targets)) {
40
+ this.targets = this.targets.concat(targets);
41
+ } else {
42
+ this.targets.push(targets);
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Matches an endpoint URL to a registered target, supporting parameterized routes.
48
+ *
49
+ * @param {string} endpoint - The endpoint URL to match
50
+ * @returns {Object|null} An object with `target` and `params`, or null if no match
51
+ */
52
+ aim(endpoint) {
53
+ const standardizedEndpoint = standardizePath(endpoint);
54
+
55
+ // First, try exact match (most specific)
56
+ const exactMatch = this.targets.find((target) => {
57
+ return target.getPath() === standardizedEndpoint;
58
+ });
59
+
60
+ if (exactMatch) {
61
+ return { target: exactMatch, params: {} };
62
+ }
63
+
64
+ // Then, try parameterized route matching
65
+ for (const target of this.targets) {
66
+ const targetPath = target.getPath();
67
+ const params = this.matchParameterizedRoute(
68
+ targetPath,
69
+ standardizedEndpoint,
70
+ );
71
+
72
+ if (params !== null) {
73
+ return { target, params };
74
+ }
75
+ }
76
+
77
+ return null;
78
+ }
79
+
80
+ /**
81
+ * Matches a parameterized route pattern against an actual URL.
82
+ *
83
+ * @param {string} pattern - The route pattern (e.g., '/api/categories/:id')
84
+ * @param {string} url - The actual URL to match (e.g., '/api/categories/123')
85
+ * @returns {Object|null} An object with extracted parameters, or null if no match
86
+ */
87
+ matchParameterizedRoute(pattern, url) {
88
+ // Handle root path case
89
+ if (pattern === '/' && url === '/') {
90
+ return {};
91
+ }
92
+
93
+ // Split both pattern and URL into segments
94
+ const patternSegments = pattern.split('/').filter((s) => s.length > 0);
95
+ const urlSegments = url.split('/').filter((s) => s.length > 0);
96
+
97
+ // Must have same number of segments
98
+ if (patternSegments.length !== urlSegments.length) {
99
+ return null;
100
+ }
101
+
102
+ // If both are empty (root paths), they match
103
+ if (patternSegments.length === 0 && urlSegments.length === 0) {
104
+ return {};
105
+ }
106
+
107
+ const params = {};
108
+
109
+ // Match each segment
110
+ for (let i = 0; i < patternSegments.length; i++) {
111
+ const patternSegment = patternSegments[i];
112
+ const urlSegment = urlSegments[i];
113
+
114
+ // If it's a parameter (starts with :)
115
+ if (patternSegment.startsWith(':')) {
116
+ const paramName = patternSegment.slice(1); // Remove the ':'
117
+ params[paramName] = urlSegment;
118
+ } else if (patternSegment !== urlSegment) {
119
+ // If it's not a parameter and doesn't match, no match
120
+ return null;
121
+ }
122
+ }
123
+
124
+ return params;
125
+ }
126
+
127
+ /**
128
+ * Get all registered endpoints.
129
+ *
130
+ * @param {boolean|{ detailed?: boolean, grouped?: boolean }} [options] - If boolean, treated as grouped (backward compat).
131
+ * If object: detailed=true returns full metadata per endpoint; grouped=true returns paths grouped by first segment.
132
+ * @returns {string[]|Object|Array<{ path: string, metadata: object|null, handler: function }>}
133
+ */
134
+ getAllEndpoints(options = {}) {
135
+ const grouped =
136
+ typeof options === 'boolean' ? options : (options && options.grouped);
137
+ const detailed =
138
+ typeof options === 'object' && options && options.detailed === true;
139
+
140
+ if (detailed) {
141
+ return this.targets.map((t) => ({
142
+ path: t.getPath(),
143
+ metadata: t.getMetadata(),
144
+ handler: t.getHandler(),
145
+ }));
146
+ }
147
+ if (grouped) {
148
+ return this.targets.reduce((acc, target) => {
149
+ const group = target.getPath().split('/')[1];
150
+ if (!acc[group]) acc[group] = [];
151
+ acc[group].push(target.getPath());
152
+ return acc;
153
+ }, {});
154
+ }
155
+ return this.targets.map((target) => target.getPath());
156
+ }
157
+ }
158
+
159
+ const targetRegistry = new TargetRegistry();
160
+ export default targetRegistry;
@@ -1,21 +1,21 @@
1
- import TejLogger from 'tej-logger';
2
- import Ammo from '../ammo.js';
3
- const logger = new TejLogger('ShootValidator');
4
-
5
- const isShootValid = (shoot) => {
6
- if (typeof shoot !== 'function') {
7
- logger.error(`Shoot ${shoot} should be a function. Skipping...`);
8
- return false;
9
- }
10
-
11
- // Shoot should have 1 parameter, and it must be an instance of Ammo
12
- if (shoot.length !== 1) {
13
- logger.error(`Shoot function must have 1 parameter. Skipping...`);
14
- return false;
15
- }
16
-
17
-
18
- return true;
19
- };
20
-
21
- export default isShootValid;
1
+ import TejLogger from 'tej-logger';
2
+ import Ammo from '../ammo.js';
3
+ const logger = new TejLogger('ShootValidator');
4
+
5
+ const isShootValid = (shoot) => {
6
+ if (typeof shoot !== 'function') {
7
+ logger.error(`Shoot ${shoot} should be a function. Skipping...`);
8
+ return false;
9
+ }
10
+
11
+ // Shoot should have 1 parameter, and it must be an instance of Ammo
12
+ if (shoot.length !== 1) {
13
+ logger.error(`Shoot function must have 1 parameter. Skipping...`);
14
+ return false;
15
+ }
16
+
17
+
18
+ return true;
19
+ };
20
+
21
+ export default isShootValid;