observability-toolkit 1.8.0 → 1.8.4

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 (186) hide show
  1. package/README.md +81 -3
  2. package/dist/backends/index.d.ts +119 -0
  3. package/dist/backends/index.d.ts.map +1 -1
  4. package/dist/backends/index.js +57 -0
  5. package/dist/backends/index.js.map +1 -1
  6. package/dist/backends/index.test.d.ts +5 -0
  7. package/dist/backends/index.test.d.ts.map +1 -0
  8. package/dist/backends/index.test.js +156 -0
  9. package/dist/backends/index.test.js.map +1 -0
  10. package/dist/backends/local-jsonl-boolean-search.test.js +8 -27
  11. package/dist/backends/local-jsonl-boolean-search.test.js.map +1 -1
  12. package/dist/backends/local-jsonl-logs.test.d.ts +2 -0
  13. package/dist/backends/local-jsonl-logs.test.d.ts.map +1 -0
  14. package/dist/backends/local-jsonl-logs.test.js +603 -0
  15. package/dist/backends/local-jsonl-logs.test.js.map +1 -0
  16. package/dist/backends/local-jsonl-traces.test.d.ts +2 -0
  17. package/dist/backends/local-jsonl-traces.test.d.ts.map +1 -0
  18. package/dist/backends/local-jsonl-traces.test.js +1723 -0
  19. package/dist/backends/local-jsonl-traces.test.js.map +1 -0
  20. package/dist/backends/local-jsonl.d.ts +4 -1
  21. package/dist/backends/local-jsonl.d.ts.map +1 -1
  22. package/dist/backends/local-jsonl.js +185 -1
  23. package/dist/backends/local-jsonl.js.map +1 -1
  24. package/dist/backends/local-jsonl.test.js +723 -46
  25. package/dist/backends/local-jsonl.test.js.map +1 -1
  26. package/dist/backends/signoz-api.d.ts +32 -0
  27. package/dist/backends/signoz-api.d.ts.map +1 -1
  28. package/dist/backends/signoz-api.js +231 -33
  29. package/dist/backends/signoz-api.js.map +1 -1
  30. package/dist/backends/signoz-api.test.js +410 -63
  31. package/dist/backends/signoz-api.test.js.map +1 -1
  32. package/dist/lib/constants.d.ts +59 -0
  33. package/dist/lib/constants.d.ts.map +1 -1
  34. package/dist/lib/constants.js +252 -6
  35. package/dist/lib/constants.js.map +1 -1
  36. package/dist/lib/constants.test.js +357 -21
  37. package/dist/lib/constants.test.js.map +1 -1
  38. package/dist/lib/edge-cases.test.d.ts +11 -0
  39. package/dist/lib/edge-cases.test.d.ts.map +1 -0
  40. package/dist/lib/edge-cases.test.js +634 -0
  41. package/dist/lib/edge-cases.test.js.map +1 -0
  42. package/dist/lib/error-sanitizer.d.ts +57 -0
  43. package/dist/lib/error-sanitizer.d.ts.map +1 -0
  44. package/dist/lib/error-sanitizer.js +207 -0
  45. package/dist/lib/error-sanitizer.js.map +1 -0
  46. package/dist/lib/error-sanitizer.test.d.ts +8 -0
  47. package/dist/lib/error-sanitizer.test.d.ts.map +1 -0
  48. package/dist/lib/error-sanitizer.test.js +369 -0
  49. package/dist/lib/error-sanitizer.test.js.map +1 -0
  50. package/dist/lib/file-utils.d.ts +134 -0
  51. package/dist/lib/file-utils.d.ts.map +1 -1
  52. package/dist/lib/file-utils.js +395 -9
  53. package/dist/lib/file-utils.js.map +1 -1
  54. package/dist/lib/file-utils.test.js +444 -3
  55. package/dist/lib/file-utils.test.js.map +1 -1
  56. package/dist/lib/indexer.d.ts +9 -1
  57. package/dist/lib/indexer.d.ts.map +1 -1
  58. package/dist/lib/indexer.js +51 -2
  59. package/dist/lib/indexer.js.map +1 -1
  60. package/dist/lib/indexer.test.js +138 -20
  61. package/dist/lib/indexer.test.js.map +1 -1
  62. package/dist/lib/input-validator.d.ts +103 -0
  63. package/dist/lib/input-validator.d.ts.map +1 -0
  64. package/dist/lib/input-validator.js +250 -0
  65. package/dist/lib/input-validator.js.map +1 -0
  66. package/dist/lib/input-validator.test.d.ts +2 -0
  67. package/dist/lib/input-validator.test.d.ts.map +1 -0
  68. package/dist/lib/input-validator.test.js +287 -0
  69. package/dist/lib/input-validator.test.js.map +1 -0
  70. package/dist/lib/query-sanitizer.d.ts +143 -0
  71. package/dist/lib/query-sanitizer.d.ts.map +1 -0
  72. package/dist/lib/query-sanitizer.js +261 -0
  73. package/dist/lib/query-sanitizer.js.map +1 -0
  74. package/dist/lib/query-sanitizer.test.d.ts +5 -0
  75. package/dist/lib/query-sanitizer.test.d.ts.map +1 -0
  76. package/dist/lib/query-sanitizer.test.js +400 -0
  77. package/dist/lib/query-sanitizer.test.js.map +1 -0
  78. package/dist/lib/server-utils.d.ts +80 -0
  79. package/dist/lib/server-utils.d.ts.map +1 -0
  80. package/dist/lib/server-utils.js +141 -0
  81. package/dist/lib/server-utils.js.map +1 -0
  82. package/dist/lib/shared-schemas.d.ts +59 -0
  83. package/dist/lib/shared-schemas.d.ts.map +1 -0
  84. package/dist/lib/shared-schemas.js +58 -0
  85. package/dist/lib/shared-schemas.js.map +1 -0
  86. package/dist/lib/shared-schemas.test.d.ts +5 -0
  87. package/dist/lib/shared-schemas.test.d.ts.map +1 -0
  88. package/dist/lib/shared-schemas.test.js +106 -0
  89. package/dist/lib/shared-schemas.test.js.map +1 -0
  90. package/dist/lib/toon-encoder.d.ts +21 -0
  91. package/dist/lib/toon-encoder.d.ts.map +1 -0
  92. package/dist/lib/toon-encoder.js +46 -0
  93. package/dist/lib/toon-encoder.js.map +1 -0
  94. package/dist/server.d.ts +1 -1
  95. package/dist/server.d.ts.map +1 -1
  96. package/dist/server.js +155 -81
  97. package/dist/server.js.map +1 -1
  98. package/dist/server.test.js +363 -0
  99. package/dist/server.test.js.map +1 -1
  100. package/dist/test-helpers/env-utils.d.ts +65 -0
  101. package/dist/test-helpers/env-utils.d.ts.map +1 -0
  102. package/dist/test-helpers/env-utils.js +94 -0
  103. package/dist/test-helpers/env-utils.js.map +1 -0
  104. package/dist/test-helpers/file-utils.d.ts +93 -0
  105. package/dist/test-helpers/file-utils.d.ts.map +1 -0
  106. package/dist/test-helpers/file-utils.js +206 -0
  107. package/dist/test-helpers/file-utils.js.map +1 -0
  108. package/dist/test-helpers/index.d.ts +10 -0
  109. package/dist/test-helpers/index.d.ts.map +1 -0
  110. package/dist/test-helpers/index.js +28 -0
  111. package/dist/test-helpers/index.js.map +1 -0
  112. package/dist/test-helpers/mock-backends.d.ts +139 -0
  113. package/dist/test-helpers/mock-backends.d.ts.map +1 -0
  114. package/dist/test-helpers/mock-backends.js +227 -0
  115. package/dist/test-helpers/mock-backends.js.map +1 -0
  116. package/dist/test-helpers/mock-backends.test.d.ts +5 -0
  117. package/dist/test-helpers/mock-backends.test.d.ts.map +1 -0
  118. package/dist/test-helpers/mock-backends.test.js +368 -0
  119. package/dist/test-helpers/mock-backends.test.js.map +1 -0
  120. package/dist/test-helpers/schema-validators.d.ts +32 -0
  121. package/dist/test-helpers/schema-validators.d.ts.map +1 -0
  122. package/dist/test-helpers/schema-validators.js +125 -0
  123. package/dist/test-helpers/schema-validators.js.map +1 -0
  124. package/dist/test-helpers/test-data-builders.d.ts +223 -0
  125. package/dist/test-helpers/test-data-builders.d.ts.map +1 -0
  126. package/dist/test-helpers/test-data-builders.js +288 -0
  127. package/dist/test-helpers/test-data-builders.js.map +1 -0
  128. package/dist/test-helpers/test-data-builders.test.d.ts +2 -0
  129. package/dist/test-helpers/test-data-builders.test.d.ts.map +1 -0
  130. package/dist/test-helpers/test-data-builders.test.js +306 -0
  131. package/dist/test-helpers/test-data-builders.test.js.map +1 -0
  132. package/dist/test-helpers/tool-validators.d.ts +28 -0
  133. package/dist/test-helpers/tool-validators.d.ts.map +1 -0
  134. package/dist/test-helpers/tool-validators.js +56 -0
  135. package/dist/test-helpers/tool-validators.js.map +1 -0
  136. package/dist/tools/context-stats.d.ts +1 -0
  137. package/dist/tools/context-stats.d.ts.map +1 -1
  138. package/dist/tools/context-stats.js +9 -5
  139. package/dist/tools/context-stats.js.map +1 -1
  140. package/dist/tools/context-stats.test.js +24 -10
  141. package/dist/tools/context-stats.test.js.map +1 -1
  142. package/dist/tools/get-trace-url.js +2 -2
  143. package/dist/tools/get-trace-url.js.map +1 -1
  144. package/dist/tools/health-check.js +2 -2
  145. package/dist/tools/health-check.js.map +1 -1
  146. package/dist/tools/index.d.ts +1 -0
  147. package/dist/tools/index.d.ts.map +1 -1
  148. package/dist/tools/index.js +1 -0
  149. package/dist/tools/index.js.map +1 -1
  150. package/dist/tools/query-evaluations.d.ts +186 -0
  151. package/dist/tools/query-evaluations.d.ts.map +1 -0
  152. package/dist/tools/query-evaluations.js +351 -0
  153. package/dist/tools/query-evaluations.js.map +1 -0
  154. package/dist/tools/query-evaluations.test.d.ts +5 -0
  155. package/dist/tools/query-evaluations.test.d.ts.map +1 -0
  156. package/dist/tools/query-evaluations.test.js +733 -0
  157. package/dist/tools/query-evaluations.test.js.map +1 -0
  158. package/dist/tools/query-llm-events.d.ts +24 -18
  159. package/dist/tools/query-llm-events.d.ts.map +1 -1
  160. package/dist/tools/query-llm-events.js +103 -60
  161. package/dist/tools/query-llm-events.js.map +1 -1
  162. package/dist/tools/query-llm-events.test.js +271 -9
  163. package/dist/tools/query-llm-events.test.js.map +1 -1
  164. package/dist/tools/query-logs.d.ts +28 -20
  165. package/dist/tools/query-logs.d.ts.map +1 -1
  166. package/dist/tools/query-logs.js +85 -61
  167. package/dist/tools/query-logs.js.map +1 -1
  168. package/dist/tools/query-logs.test.js +74 -145
  169. package/dist/tools/query-logs.test.js.map +1 -1
  170. package/dist/tools/query-metrics.d.ts +20 -20
  171. package/dist/tools/query-metrics.d.ts.map +1 -1
  172. package/dist/tools/query-metrics.js +109 -61
  173. package/dist/tools/query-metrics.js.map +1 -1
  174. package/dist/tools/query-metrics.test.js +26 -61
  175. package/dist/tools/query-metrics.test.js.map +1 -1
  176. package/dist/tools/query-traces.d.ts +24 -22
  177. package/dist/tools/query-traces.d.ts.map +1 -1
  178. package/dist/tools/query-traces.js +95 -70
  179. package/dist/tools/query-traces.js.map +1 -1
  180. package/dist/tools/query-traces.test.js +294 -90
  181. package/dist/tools/query-traces.test.js.map +1 -1
  182. package/dist/tools/setup-claudeignore.js +7 -7
  183. package/dist/tools/setup-claudeignore.js.map +1 -1
  184. package/dist/tools/setup-claudeignore.test.js +4 -25
  185. package/dist/tools/setup-claudeignore.test.js.map +1 -1
  186. package/package.json +3 -4
@@ -0,0 +1,287 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert';
3
+ import { validateLimit, validateDuration, validateDateRange, validateRegexPattern, InputValidationError, isInputValidationError, MAX_LIMIT, MAX_DATE_RANGE_DAYS, MAX_REGEX_LENGTH, MAX_REGEX_GROUPS, DEFAULT_LIMIT, MAX_DURATION_MS, } from './input-validator.js';
4
+ describe('input-validator', () => {
5
+ describe('validateLimit', () => {
6
+ it('should return default limit when undefined', () => {
7
+ const result = validateLimit(undefined);
8
+ assert.strictEqual(result, DEFAULT_LIMIT);
9
+ });
10
+ it('should return default limit when null', () => {
11
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
+ const result = validateLimit(null);
13
+ assert.strictEqual(result, DEFAULT_LIMIT);
14
+ });
15
+ it('should return value when within valid range', () => {
16
+ assert.strictEqual(validateLimit(100), 100);
17
+ assert.strictEqual(validateLimit(500), 500);
18
+ assert.strictEqual(validateLimit(1), 1);
19
+ });
20
+ it('should clamp to MAX_LIMIT when value exceeds maximum', () => {
21
+ assert.strictEqual(validateLimit(5000), MAX_LIMIT);
22
+ assert.strictEqual(validateLimit(1001), MAX_LIMIT);
23
+ assert.strictEqual(validateLimit(Number.MAX_SAFE_INTEGER), MAX_LIMIT);
24
+ });
25
+ it('should clamp to 1 when value is zero or negative', () => {
26
+ assert.strictEqual(validateLimit(0), 1);
27
+ assert.strictEqual(validateLimit(-1), 1);
28
+ assert.strictEqual(validateLimit(-100), 1);
29
+ });
30
+ it('should handle edge cases', () => {
31
+ assert.strictEqual(validateLimit(MAX_LIMIT), MAX_LIMIT);
32
+ assert.strictEqual(validateLimit(1), 1);
33
+ });
34
+ });
35
+ describe('validateDuration', () => {
36
+ it('should return undefined when undefined', () => {
37
+ const result = validateDuration(undefined, 'minDurationMs');
38
+ assert.strictEqual(result, undefined);
39
+ });
40
+ it('should return undefined when null', () => {
41
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
42
+ const result = validateDuration(null, 'minDurationMs');
43
+ assert.strictEqual(result, undefined);
44
+ });
45
+ it('should return value when within valid range', () => {
46
+ assert.strictEqual(validateDuration(0, 'minDurationMs'), 0);
47
+ assert.strictEqual(validateDuration(1000, 'minDurationMs'), 1000);
48
+ assert.strictEqual(validateDuration(5000, 'maxDurationMs'), 5000);
49
+ assert.strictEqual(validateDuration(MAX_DURATION_MS, 'maxDurationMs'), MAX_DURATION_MS);
50
+ });
51
+ it('should clamp to MAX_DURATION_MS when value exceeds maximum', () => {
52
+ assert.strictEqual(validateDuration(MAX_DURATION_MS + 1, 'minDurationMs'), MAX_DURATION_MS);
53
+ assert.strictEqual(validateDuration(100000000, 'maxDurationMs'), MAX_DURATION_MS);
54
+ assert.strictEqual(validateDuration(Number.MAX_SAFE_INTEGER, 'minDurationMs'), MAX_DURATION_MS);
55
+ });
56
+ it('should throw when value is negative', () => {
57
+ assert.throws(() => validateDuration(-1, 'minDurationMs'), (err) => {
58
+ assert.strictEqual(err.field, 'minDurationMs');
59
+ assert.strictEqual(err.constraint, 'range');
60
+ assert.ok(err.message.includes('cannot be negative'));
61
+ return true;
62
+ });
63
+ assert.throws(() => validateDuration(-100, 'maxDurationMs'), (err) => {
64
+ assert.strictEqual(err.field, 'maxDurationMs');
65
+ assert.strictEqual(err.constraint, 'range');
66
+ return true;
67
+ });
68
+ });
69
+ it('should handle edge cases', () => {
70
+ assert.strictEqual(validateDuration(0, 'minDurationMs'), 0);
71
+ assert.strictEqual(validateDuration(MAX_DURATION_MS, 'maxDurationMs'), MAX_DURATION_MS);
72
+ });
73
+ });
74
+ describe('validateDateRange', () => {
75
+ it('should parse valid date strings', () => {
76
+ const result = validateDateRange('2024-01-01', '2024-01-31');
77
+ assert.strictEqual(result.start.getFullYear(), 2024);
78
+ assert.strictEqual(result.start.getMonth(), 0); // January
79
+ assert.strictEqual(result.start.getDate(), 1);
80
+ assert.strictEqual(result.end.getFullYear(), 2024);
81
+ assert.strictEqual(result.end.getMonth(), 0);
82
+ assert.strictEqual(result.end.getDate(), 31);
83
+ });
84
+ it('should return defaults when both dates undefined', () => {
85
+ const result = validateDateRange(undefined, undefined);
86
+ const today = new Date();
87
+ // End should be today
88
+ assert.strictEqual(result.end.getFullYear(), today.getFullYear());
89
+ assert.strictEqual(result.end.getMonth(), today.getMonth());
90
+ assert.strictEqual(result.end.getDate(), today.getDate());
91
+ // Start should be MAX_DATE_RANGE_DAYS ago
92
+ const expectedStart = new Date(today.getTime() - MAX_DATE_RANGE_DAYS * 24 * 60 * 60 * 1000);
93
+ assert.strictEqual(result.start.getFullYear(), expectedStart.getFullYear());
94
+ assert.strictEqual(result.start.getMonth(), expectedStart.getMonth());
95
+ assert.strictEqual(result.start.getDate(), expectedStart.getDate());
96
+ });
97
+ it('should throw on invalid startDate format', () => {
98
+ assert.throws(() => validateDateRange('invalid', '2024-01-31'), (err) => {
99
+ assert.strictEqual(err.field, 'startDate');
100
+ assert.strictEqual(err.constraint, 'format');
101
+ assert.ok(err.message.includes('Invalid startDate format'));
102
+ return true;
103
+ });
104
+ });
105
+ it('should throw on invalid endDate format', () => {
106
+ assert.throws(() => validateDateRange('2024-01-01', 'not-a-date'), (err) => {
107
+ assert.strictEqual(err.field, 'endDate');
108
+ assert.strictEqual(err.constraint, 'format');
109
+ assert.ok(err.message.includes('Invalid endDate format'));
110
+ return true;
111
+ });
112
+ });
113
+ it('should throw on partial date format', () => {
114
+ assert.throws(() => validateDateRange('2024-01', '2024-01-31'), (err) => {
115
+ assert.strictEqual(err.field, 'startDate');
116
+ assert.strictEqual(err.constraint, 'format');
117
+ return true;
118
+ });
119
+ });
120
+ it('should throw on invalid date like Feb 30', () => {
121
+ assert.throws(() => validateDateRange('2024-02-30', '2024-03-01'), (err) => {
122
+ assert.strictEqual(err.field, 'startDate');
123
+ assert.strictEqual(err.constraint, 'format');
124
+ return true;
125
+ });
126
+ });
127
+ it('should throw on invalid month', () => {
128
+ assert.throws(() => validateDateRange('2024-13-01', '2024-12-31'), (err) => {
129
+ assert.strictEqual(err.field, 'startDate');
130
+ assert.strictEqual(err.constraint, 'format');
131
+ return true;
132
+ });
133
+ });
134
+ it('should throw when startDate is after endDate', () => {
135
+ assert.throws(() => validateDateRange('2024-12-31', '2024-01-01'), (err) => {
136
+ assert.strictEqual(err.field, 'startDate');
137
+ assert.strictEqual(err.constraint, 'range');
138
+ assert.ok(err.message.includes('cannot be after'));
139
+ return true;
140
+ });
141
+ });
142
+ it('should throw when date range exceeds maximum', () => {
143
+ // Calculate dates that exceed MAX_DATE_RANGE_DAYS
144
+ const start = '2022-01-01';
145
+ const end = '2024-01-01'; // ~730 days
146
+ assert.throws(() => validateDateRange(start, end), (err) => {
147
+ assert.strictEqual(err.field, 'dateRange');
148
+ assert.strictEqual(err.constraint, 'maxRange');
149
+ assert.ok(err.message.includes(`exceeds maximum of ${MAX_DATE_RANGE_DAYS}`));
150
+ return true;
151
+ });
152
+ });
153
+ it('should allow range exactly at maximum', () => {
154
+ const start = new Date();
155
+ start.setDate(start.getDate() - MAX_DATE_RANGE_DAYS);
156
+ const startStr = start.toISOString().split('T')[0];
157
+ const endStr = new Date().toISOString().split('T')[0];
158
+ // Should not throw
159
+ const result = validateDateRange(startStr, endStr);
160
+ assert.ok(result.start);
161
+ assert.ok(result.end);
162
+ });
163
+ it('should handle same start and end date', () => {
164
+ const result = validateDateRange('2024-06-15', '2024-06-15');
165
+ assert.strictEqual(result.start.getTime(), result.end.getTime());
166
+ });
167
+ });
168
+ describe('validateRegexPattern', () => {
169
+ it('should accept valid simple patterns', () => {
170
+ assert.doesNotThrow(() => validateRegexPattern('error'));
171
+ assert.doesNotThrow(() => validateRegexPattern('error.*timeout'));
172
+ assert.doesNotThrow(() => validateRegexPattern('^start'));
173
+ assert.doesNotThrow(() => validateRegexPattern('end$'));
174
+ });
175
+ it('should accept patterns with allowed capture groups', () => {
176
+ assert.doesNotThrow(() => validateRegexPattern('(foo)'));
177
+ assert.doesNotThrow(() => validateRegexPattern('(a)(b)(c)'));
178
+ // 10 groups is the max
179
+ assert.doesNotThrow(() => validateRegexPattern('(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)'));
180
+ });
181
+ it('should accept non-capturing groups without counting', () => {
182
+ // Non-capturing groups don't count toward limit
183
+ assert.doesNotThrow(() => validateRegexPattern('(?:foo)'));
184
+ assert.doesNotThrow(() => validateRegexPattern('(?:a)(?:b)(?:c)(?:d)(?:e)(?:f)(?:g)(?:h)(?:i)(?:j)(?:k)'));
185
+ });
186
+ it('should accept lookahead/lookbehind without counting', () => {
187
+ assert.doesNotThrow(() => validateRegexPattern('(?=foo)'));
188
+ assert.doesNotThrow(() => validateRegexPattern('(?!foo)'));
189
+ assert.doesNotThrow(() => validateRegexPattern('(?<=foo)'));
190
+ assert.doesNotThrow(() => validateRegexPattern('(?<!foo)'));
191
+ });
192
+ it('should throw when pattern exceeds max length', () => {
193
+ const longPattern = 'a'.repeat(MAX_REGEX_LENGTH + 1);
194
+ assert.throws(() => validateRegexPattern(longPattern), (err) => {
195
+ assert.strictEqual(err.field, 'pattern');
196
+ assert.strictEqual(err.constraint, 'maxLength');
197
+ assert.ok(err.message.includes(`exceeds maximum of ${MAX_REGEX_LENGTH}`));
198
+ return true;
199
+ });
200
+ });
201
+ it('should throw when pattern has too many capture groups', () => {
202
+ // 11 groups exceeds the limit of 10
203
+ const manyGroups = '(1)(2)(3)(4)(5)(6)(7)(8)(9)(10)(11)';
204
+ assert.throws(() => validateRegexPattern(manyGroups), (err) => {
205
+ assert.strictEqual(err.field, 'pattern');
206
+ assert.strictEqual(err.constraint, 'maxGroups');
207
+ assert.ok(err.message.includes(`exceeding maximum of ${MAX_REGEX_GROUPS}`));
208
+ return true;
209
+ });
210
+ });
211
+ it('should throw on invalid regex syntax', () => {
212
+ assert.throws(() => validateRegexPattern('[invalid'), (err) => {
213
+ assert.strictEqual(err.field, 'pattern');
214
+ assert.strictEqual(err.constraint, 'syntax');
215
+ assert.ok(err.message.includes('Invalid regex pattern'));
216
+ return true;
217
+ });
218
+ });
219
+ it('should throw on unclosed parenthesis', () => {
220
+ assert.throws(() => validateRegexPattern('(unclosed'), (err) => {
221
+ assert.strictEqual(err.field, 'pattern');
222
+ assert.strictEqual(err.constraint, 'syntax');
223
+ return true;
224
+ });
225
+ });
226
+ it('should handle escaped parentheses', () => {
227
+ // Escaped parens don't count as groups
228
+ assert.doesNotThrow(() => validateRegexPattern('\\(not a group\\)'));
229
+ assert.doesNotThrow(() => validateRegexPattern('\\(\\)\\(\\)\\(\\)\\(\\)\\(\\)\\(\\)\\(\\)\\(\\)\\(\\)\\(\\)\\(\\)'));
230
+ });
231
+ it('should handle parentheses inside character classes', () => {
232
+ // Parens inside [] don't count as groups
233
+ assert.doesNotThrow(() => validateRegexPattern('[(]'));
234
+ assert.doesNotThrow(() => validateRegexPattern('[()]'));
235
+ });
236
+ it('should handle complex patterns', () => {
237
+ // Mix of real groups, non-capturing, and escaped
238
+ assert.doesNotThrow(() => validateRegexPattern('(a)(?:b)\\(c\\)[d]'));
239
+ });
240
+ });
241
+ describe('InputValidationError', () => {
242
+ it('should have correct properties', () => {
243
+ const error = new InputValidationError('Test message', 'testField', 'testConstraint');
244
+ assert.strictEqual(error.message, 'Test message');
245
+ assert.strictEqual(error.field, 'testField');
246
+ assert.strictEqual(error.constraint, 'testConstraint');
247
+ assert.strictEqual(error.name, 'InputValidationError');
248
+ });
249
+ it('should be instanceof Error', () => {
250
+ const error = new InputValidationError('Test', 'field', 'constraint');
251
+ assert.ok(error instanceof Error);
252
+ assert.ok(error instanceof InputValidationError);
253
+ });
254
+ it('should have stack trace', () => {
255
+ const error = new InputValidationError('Test', 'field', 'constraint');
256
+ assert.ok(error.stack);
257
+ assert.ok(error.stack.includes('InputValidationError'));
258
+ });
259
+ });
260
+ describe('isInputValidationError', () => {
261
+ it('should return true for InputValidationError', () => {
262
+ const error = new InputValidationError('Test', 'field', 'constraint');
263
+ assert.strictEqual(isInputValidationError(error), true);
264
+ });
265
+ it('should return false for regular Error', () => {
266
+ const error = new Error('Test');
267
+ assert.strictEqual(isInputValidationError(error), false);
268
+ });
269
+ it('should return false for non-error objects', () => {
270
+ assert.strictEqual(isInputValidationError({ message: 'fake' }), false);
271
+ assert.strictEqual(isInputValidationError(null), false);
272
+ assert.strictEqual(isInputValidationError(undefined), false);
273
+ assert.strictEqual(isInputValidationError('string'), false);
274
+ });
275
+ });
276
+ describe('constants', () => {
277
+ it('should export expected constant values', () => {
278
+ assert.strictEqual(MAX_LIMIT, 1000);
279
+ assert.strictEqual(MAX_DATE_RANGE_DAYS, 365);
280
+ assert.strictEqual(MAX_REGEX_LENGTH, 200);
281
+ assert.strictEqual(MAX_REGEX_GROUPS, 10);
282
+ assert.strictEqual(DEFAULT_LIMIT, 50);
283
+ assert.strictEqual(MAX_DURATION_MS, 86400000); // 24 hours
284
+ });
285
+ });
286
+ });
287
+ //# sourceMappingURL=input-validator.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"input-validator.test.js","sourceRoot":"","sources":["../../src/lib/input-validator.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * ClickHouse-specific query escaping and input validation
3
+ *
4
+ * Provides security utilities for sanitizing user inputs before
5
+ * including them in ClickHouse queries via SigNoz API.
6
+ */
7
+ /**
8
+ * Dangerous SQL/query patterns that should never appear in user input
9
+ * Case-insensitive matching is used
10
+ */
11
+ export declare const DANGEROUS_PATTERNS: readonly string[];
12
+ /**
13
+ * Escape a string value for use in ClickHouse single-quoted strings
14
+ *
15
+ * ClickHouse uses backslash escaping for special characters.
16
+ * @see https://clickhouse.com/docs/en/sql-reference/syntax#string
17
+ *
18
+ * @param value - The string value to escape
19
+ * @returns Escaped string safe for use in single-quoted ClickHouse strings
20
+ */
21
+ export declare function escapeClickHouseString(value: string): string;
22
+ /**
23
+ * Escape LIKE wildcard characters for use in ClickHouse LIKE patterns
24
+ *
25
+ * This escapes % and _ which have special meaning in LIKE patterns.
26
+ * Use this when the user's input should be treated as a literal string
27
+ * in a LIKE clause, not as a pattern.
28
+ *
29
+ * @param value - The string value to escape for LIKE
30
+ * @returns Escaped string with LIKE wildcards escaped
31
+ */
32
+ export declare function escapeClickHouseLike(value: string): string;
33
+ /**
34
+ * Sanitize an identifier (column name, table name, etc.)
35
+ *
36
+ * Only allows alphanumeric characters, underscores, and dots.
37
+ * Removes all other characters.
38
+ *
39
+ * @param name - The identifier to sanitize
40
+ * @returns Sanitized identifier containing only safe characters
41
+ */
42
+ export declare function sanitizeIdentifier(name: string): string;
43
+ /**
44
+ * Maximum length for query input validation
45
+ * Prevents performance issues with very long inputs
46
+ */
47
+ export declare const MAX_QUERY_INPUT_LENGTH = 10000;
48
+ /**
49
+ * Check if a string contains any dangerous SQL patterns
50
+ *
51
+ * Uses case-insensitive matching and word boundary detection
52
+ * for most patterns to reduce false positives.
53
+ *
54
+ * Performance: O(1) Set lookup for special chars + O(1) pre-compiled regex
55
+ * for SQL keywords (previously O(n) with n=22 patterns).
56
+ *
57
+ * Defense in depth: Rejects inputs exceeding MAX_QUERY_INPUT_LENGTH
58
+ * to prevent performance issues with very long strings.
59
+ *
60
+ * Security: Uses String() to freeze input as primitive, preventing TOCTOU
61
+ * race conditions with Proxy objects or getter-modified values.
62
+ *
63
+ * @param input - The input string to check
64
+ * @returns true if dangerous pattern found, false otherwise
65
+ */
66
+ export declare function containsDangerousPattern(input: string): boolean;
67
+ /**
68
+ * Validate that user input does not contain dangerous patterns
69
+ *
70
+ * Throws an error if dangerous patterns are detected, including
71
+ * the field name for better error messages.
72
+ *
73
+ * @param input - The input string to validate
74
+ * @param fieldName - Name of the field being validated (for error messages)
75
+ * @throws Error if dangerous pattern is found
76
+ */
77
+ export declare function validateQueryInput(input: string, fieldName: string): void;
78
+ /**
79
+ * Options for composable value sanitization
80
+ */
81
+ export interface SanitizeOptions {
82
+ /** Validate input for dangerous SQL patterns (default: true) */
83
+ validate?: boolean;
84
+ /** Escape for ClickHouse string context (default: true) */
85
+ escapeString?: boolean;
86
+ /** Escape LIKE wildcards before string escaping (default: false) */
87
+ escapeLike?: boolean;
88
+ /** Field name for validation error messages */
89
+ fieldName?: string;
90
+ /** Allow empty strings (default: true). When false, throws on empty input. */
91
+ allowEmpty?: boolean;
92
+ }
93
+ /**
94
+ * Composable value sanitizer with configurable validation and escaping
95
+ *
96
+ * Provides flexible control over which operations to apply:
97
+ * - validate: Check for dangerous SQL patterns
98
+ * - escapeString: Escape for ClickHouse string context
99
+ * - escapeLike: Escape LIKE wildcards (%, _)
100
+ *
101
+ * @example
102
+ * // Validate only (no escaping)
103
+ * sanitizeValue(input, { escapeString: false, fieldName: 'search' });
104
+ *
105
+ * // Escape only (no validation) - use when input is already trusted
106
+ * sanitizeValue(input, { validate: false });
107
+ *
108
+ * // Full sanitization for LIKE clause
109
+ * sanitizeValue(input, { escapeLike: true, fieldName: 'search' });
110
+ *
111
+ * @param value - The value to sanitize
112
+ * @param options - Sanitization options
113
+ * @returns Sanitized string
114
+ * @throws Error if validation enabled and dangerous pattern found
115
+ */
116
+ export declare function sanitizeValue(value: string, options?: SanitizeOptions): string;
117
+ /**
118
+ * Escape and validate a string value for use in WHERE clause conditions
119
+ *
120
+ * @deprecated Use sanitizeValue() for more flexibility:
121
+ * sanitizeValue(value, { fieldName }) - same behavior
122
+ * sanitizeValue(value, { validate: false }) - escape only
123
+ *
124
+ * @param value - The value to escape
125
+ * @param fieldName - Name of the field (for error messages)
126
+ * @returns Escaped string safe for ClickHouse queries
127
+ * @throws Error if dangerous pattern is found
128
+ */
129
+ export declare function escapeFilterValueSafe(value: string, fieldName: string): string;
130
+ /**
131
+ * Escape and validate a value for use in LIKE clauses
132
+ *
133
+ * @deprecated Use sanitizeValue() for more flexibility:
134
+ * sanitizeValue(value, { escapeLike: true, fieldName }) - same behavior
135
+ * sanitizeValue(value, { escapeLike: true, validate: false }) - escape only
136
+ *
137
+ * @param value - The value to escape
138
+ * @param fieldName - Name of the field (for error messages)
139
+ * @returns Escaped string safe for ClickHouse LIKE clauses
140
+ * @throws Error if dangerous pattern is found
141
+ */
142
+ export declare function escapeLikeValueSafe(value: string, fieldName: string): string;
143
+ //# sourceMappingURL=query-sanitizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-sanitizer.d.ts","sourceRoot":"","sources":["../../src/lib/query-sanitizer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAuBtC,CAAC;AAEX;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAc5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAO1D;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;GAGG;AACH,eAAO,MAAM,sBAAsB,QAAQ,CAAC;AAiD5C;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAqB/D;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAIzE;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,gEAAgE;IAChE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2DAA2D;IAC3D,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oEAAoE;IACpE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,eAAoB,GAAG,MAAM,CA+BlF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAE9E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAE5E"}