@codebaz/nextdoctor-agent 0.1.0-beta.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 (80) hide show
  1. package/.turbo/turbo-build.log +3 -0
  2. package/README.md +568 -0
  3. package/dist/detectors/__tests__/cold-start-threshold.test.d.ts +2 -0
  4. package/dist/detectors/__tests__/cold-start-threshold.test.d.ts.map +1 -0
  5. package/dist/detectors/__tests__/cold-start-threshold.test.js +156 -0
  6. package/dist/detectors/__tests__/cold-start-threshold.test.js.map +1 -0
  7. package/dist/detectors/__tests__/dynamic-route-candidate.test.d.ts +2 -0
  8. package/dist/detectors/__tests__/dynamic-route-candidate.test.d.ts.map +1 -0
  9. package/dist/detectors/__tests__/dynamic-route-candidate.test.js +318 -0
  10. package/dist/detectors/__tests__/dynamic-route-candidate.test.js.map +1 -0
  11. package/dist/detectors/__tests__/fetch-no-cache.test.d.ts +2 -0
  12. package/dist/detectors/__tests__/fetch-no-cache.test.d.ts.map +1 -0
  13. package/dist/detectors/__tests__/fetch-no-cache.test.js +199 -0
  14. package/dist/detectors/__tests__/fetch-no-cache.test.js.map +1 -0
  15. package/dist/detectors/base-detector.d.ts +17 -0
  16. package/dist/detectors/base-detector.d.ts.map +1 -0
  17. package/dist/detectors/base-detector.js +50 -0
  18. package/dist/detectors/base-detector.js.map +1 -0
  19. package/dist/detectors/cold-start-threshold.detector.d.ts +11 -0
  20. package/dist/detectors/cold-start-threshold.detector.d.ts.map +1 -0
  21. package/dist/detectors/cold-start-threshold.detector.js +87 -0
  22. package/dist/detectors/cold-start-threshold.detector.js.map +1 -0
  23. package/dist/detectors/dynamic-route-candidate.detector.d.ts +23 -0
  24. package/dist/detectors/dynamic-route-candidate.detector.d.ts.map +1 -0
  25. package/dist/detectors/dynamic-route-candidate.detector.js +96 -0
  26. package/dist/detectors/dynamic-route-candidate.detector.js.map +1 -0
  27. package/dist/detectors/fetch-no-cache.detector.d.ts +12 -0
  28. package/dist/detectors/fetch-no-cache.detector.d.ts.map +1 -0
  29. package/dist/detectors/fetch-no-cache.detector.js +178 -0
  30. package/dist/detectors/fetch-no-cache.detector.js.map +1 -0
  31. package/dist/detectors/index.d.ts +28 -0
  32. package/dist/detectors/index.d.ts.map +1 -0
  33. package/dist/detectors/index.js +97 -0
  34. package/dist/detectors/index.js.map +1 -0
  35. package/dist/detectors/types.d.ts +32 -0
  36. package/dist/detectors/types.d.ts.map +1 -0
  37. package/dist/detectors/types.js +2 -0
  38. package/dist/detectors/types.js.map +1 -0
  39. package/dist/index.d.ts +10 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +7 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/init.d.ts +133 -0
  44. package/dist/init.d.ts.map +1 -0
  45. package/dist/init.js +363 -0
  46. package/dist/init.js.map +1 -0
  47. package/dist/middleware.d.ts +10 -0
  48. package/dist/middleware.d.ts.map +1 -0
  49. package/dist/middleware.js +61 -0
  50. package/dist/middleware.js.map +1 -0
  51. package/dist/optimization.d.ts +43 -0
  52. package/dist/optimization.d.ts.map +1 -0
  53. package/dist/optimization.js +139 -0
  54. package/dist/optimization.js.map +1 -0
  55. package/dist/system-monitor.d.ts +124 -0
  56. package/dist/system-monitor.d.ts.map +1 -0
  57. package/dist/system-monitor.js +221 -0
  58. package/dist/system-monitor.js.map +1 -0
  59. package/dist/types.d.ts +61 -0
  60. package/dist/types.d.ts.map +1 -0
  61. package/dist/types.js +14 -0
  62. package/dist/types.js.map +1 -0
  63. package/package.json +55 -0
  64. package/src/detectors/__tests__/cold-start-threshold.test.ts +183 -0
  65. package/src/detectors/__tests__/dynamic-route-candidate.test.ts +365 -0
  66. package/src/detectors/__tests__/fetch-no-cache.test.ts +239 -0
  67. package/src/detectors/base-detector.ts +69 -0
  68. package/src/detectors/cold-start-threshold.detector.ts +95 -0
  69. package/src/detectors/dynamic-route-candidate.detector.ts +107 -0
  70. package/src/detectors/fetch-no-cache.detector.ts +204 -0
  71. package/src/detectors/index.ts +127 -0
  72. package/src/detectors/types.ts +38 -0
  73. package/src/index.ts +60 -0
  74. package/src/init.ts +424 -0
  75. package/src/middleware.ts +75 -0
  76. package/src/optimization.ts +164 -0
  77. package/src/system-monitor.ts +295 -0
  78. package/src/types.ts +66 -0
  79. package/tsconfig.json +11 -0
  80. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,156 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { ColdStartThresholdDetector } from '../cold-start-threshold.detector.js';
3
+ function createMockSpan(overrides = {}) {
4
+ const defaultStartTime = [Math.floor(Date.now() / 1000), 0];
5
+ const defaultEndTime = [
6
+ defaultStartTime[0],
7
+ defaultStartTime[1] + 100_000_000, // 100ms
8
+ ];
9
+ return {
10
+ name: 'http.request',
11
+ spanContext: () => ({
12
+ traceId: 'test-trace',
13
+ spanId: 'test-span-' + Math.random().toString(36).substr(2, 9),
14
+ traceFlags: 0x01,
15
+ traceState: undefined,
16
+ isRecording: true,
17
+ }),
18
+ parentSpanId: undefined,
19
+ startTime: defaultStartTime,
20
+ endTime: defaultEndTime,
21
+ attributes: {
22
+ 'http.route': '/api/test',
23
+ ...overrides.attributes,
24
+ },
25
+ links: [],
26
+ events: [],
27
+ status: { code: 0 },
28
+ instrumentationLibrary: {
29
+ name: 'nextdoctor',
30
+ version: '0.1.0',
31
+ },
32
+ resource: {
33
+ attributes: {},
34
+ },
35
+ duration: defaultEndTime,
36
+ ended: true,
37
+ ...overrides,
38
+ };
39
+ }
40
+ describe('ColdStartThresholdDetector', () => {
41
+ const detector = new ColdStartThresholdDetector();
42
+ it('detects cold start above threshold (800ms)', () => {
43
+ const issues = detector.detect([], {
44
+ runtime: 'edge',
45
+ startupTimeMs: 1200,
46
+ });
47
+ expect(issues).toHaveLength(1);
48
+ expect(issues[0].id).toBe('COLD_START_THRESHOLD');
49
+ expect(issues[0].severity).toBe('critical');
50
+ expect(issues[0].message).toContain('1200ms');
51
+ expect(issues[0].message).toContain('800ms');
52
+ });
53
+ it('ignores cold start below threshold', () => {
54
+ const issues = detector.detect([], {
55
+ runtime: 'edge',
56
+ startupTimeMs: 500,
57
+ });
58
+ expect(issues).toHaveLength(0);
59
+ });
60
+ it('detects cold start exactly at threshold', () => {
61
+ const issues = detector.detect([], {
62
+ runtime: 'edge',
63
+ startupTimeMs: 800,
64
+ });
65
+ // At threshold should pass (not exceed)
66
+ expect(issues).toHaveLength(0);
67
+ });
68
+ it('fires with 20+ spans when P99 - P50 > 2000ms', () => {
69
+ const spans = Array.from({ length: 20 }).map((_, i) => {
70
+ const durationNano = i < 10
71
+ ? 100_000_000 // 100ms (P50)
72
+ : 2500_000_000; // 2500ms (P99)
73
+ return createMockSpan({
74
+ name: 'http.request',
75
+ attributes: {
76
+ 'http.route': '/api/users',
77
+ },
78
+ startTime: [1000, 0],
79
+ endTime: [1000, durationNano],
80
+ spanContext: () => ({
81
+ traceId: 'test-trace',
82
+ spanId: `span-${i}`,
83
+ traceFlags: 0x01,
84
+ traceState: undefined,
85
+ isRecording: true,
86
+ }),
87
+ });
88
+ });
89
+ const issues = detector.detect(spans, {
90
+ runtime: 'edge',
91
+ route: '/api/users',
92
+ });
93
+ expect(issues.some(i => i.id === 'COLD_START_INTERMITTENT')).toBe(true);
94
+ const issue = issues.find(i => i.id === 'COLD_START_INTERMITTENT');
95
+ expect(issue?.severity).toBe('warning');
96
+ expect(issue?.message).toContain('high latency variance');
97
+ });
98
+ it('ignores low variance', () => {
99
+ const spans = Array.from({ length: 20 }).map((_, i) => createMockSpan({
100
+ name: 'http.request',
101
+ attributes: {
102
+ 'http.route': '/api/test',
103
+ },
104
+ startTime: [1000, 0],
105
+ endTime: [1000, 100_000_000 + i * 10_000_000], // 100-190ms range
106
+ spanContext: () => ({
107
+ traceId: 'test-trace',
108
+ spanId: `span-${i}`,
109
+ traceFlags: 0x01,
110
+ traceState: undefined,
111
+ isRecording: true,
112
+ }),
113
+ }));
114
+ const issues = detector.detect(spans, {
115
+ runtime: 'edge',
116
+ route: '/api/test',
117
+ });
118
+ expect(issues.filter(i => i.id === 'COLD_START_INTERMITTENT')).toHaveLength(0);
119
+ });
120
+ it('does not fire with fewer than 20 spans for variance calculation', () => {
121
+ const spans = Array.from({ length: 19 }).map((_, i) => createMockSpan({
122
+ startTime: [1000, 0],
123
+ endTime: [1000, i < 2 ? 100_000_000 : 3000_000_000],
124
+ spanContext: () => ({
125
+ traceId: 'test-trace',
126
+ spanId: `span-${i}`,
127
+ traceFlags: 0x01,
128
+ traceState: undefined,
129
+ isRecording: true,
130
+ }),
131
+ }));
132
+ const issues = detector.detect(spans, {
133
+ runtime: 'edge',
134
+ route: '/api/test',
135
+ });
136
+ expect(issues.every(i => i.id !== 'COLD_START_INTERMITTENT')).toBe(true);
137
+ });
138
+ it('includes suggestions in issue', () => {
139
+ const issues = detector.detect([], {
140
+ runtime: 'edge',
141
+ startupTimeMs: 1200,
142
+ });
143
+ expect(issues[0].suggestion).toContain('import');
144
+ expect(issues[0].suggestion).toContain('runtime');
145
+ });
146
+ it('includes attributes with threshold data', () => {
147
+ const issues = detector.detect([], {
148
+ runtime: 'edge',
149
+ startupTimeMs: 1200,
150
+ });
151
+ expect(issues[0].attributes?.startupTimeMs).toBe(1200);
152
+ expect(issues[0].attributes?.threshold).toBe(800);
153
+ expect(issues[0].attributes?.runtime).toBe('edge');
154
+ });
155
+ });
156
+ //# sourceMappingURL=cold-start-threshold.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cold-start-threshold.test.js","sourceRoot":"","sources":["../../../src/detectors/__tests__/cold-start-threshold.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=dynamic-route-candidate.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dynamic-route-candidate.test.d.ts","sourceRoot":"","sources":["../../../src/detectors/__tests__/dynamic-route-candidate.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,318 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { DynamicRouteCandidateDetector } from '../dynamic-route-candidate.detector.js';
3
+ function createMockSpan(overrides = {}) {
4
+ const defaultStartTime = [Math.floor(Date.now() / 1000), 0];
5
+ const defaultEndTime = [
6
+ defaultStartTime[0],
7
+ defaultStartTime[1] + 50_000_000, // 50ms
8
+ ];
9
+ return {
10
+ name: 'http.request',
11
+ spanContext: () => ({
12
+ traceId: 'test-trace',
13
+ spanId: 'test-span-' + Math.random().toString(36).substr(2, 9),
14
+ traceFlags: 0x01,
15
+ traceState: undefined,
16
+ isRecording: true,
17
+ }),
18
+ parentSpanId: undefined,
19
+ startTime: defaultStartTime,
20
+ endTime: defaultEndTime,
21
+ attributes: {
22
+ 'http.route': '/dashboard/[id]',
23
+ ...overrides.attributes,
24
+ },
25
+ links: [],
26
+ events: [],
27
+ status: { code: 0 },
28
+ instrumentationLibrary: {
29
+ name: 'nextdoctor',
30
+ version: '0.1.0',
31
+ },
32
+ resource: {
33
+ attributes: {},
34
+ },
35
+ duration: defaultEndTime,
36
+ ended: true,
37
+ ...overrides,
38
+ };
39
+ }
40
+ describe('DynamicRouteCandidateDetector', () => {
41
+ const detector = new DynamicRouteCandidateDetector();
42
+ it('detects cookies() call without specific key access', () => {
43
+ const parentSpan = createMockSpan({
44
+ name: 'http.request',
45
+ spanContext: () => ({
46
+ traceId: 'test-trace',
47
+ spanId: 'parent-span',
48
+ traceFlags: 0x01,
49
+ traceState: undefined,
50
+ isRecording: true,
51
+ }),
52
+ });
53
+ const cookieSpan = createMockSpan({
54
+ name: 'cookies',
55
+ spanContext: () => ({
56
+ traceId: 'test-trace',
57
+ spanId: 'cookie-span',
58
+ traceFlags: 0x01,
59
+ traceState: undefined,
60
+ isRecording: true,
61
+ }),
62
+ parentSpanId: 'parent-span',
63
+ attributes: {
64
+ 'function.name': 'cookies',
65
+ },
66
+ });
67
+ const issues = detector.detect([parentSpan, cookieSpan], {
68
+ runtime: 'nodejs',
69
+ route: '/dashboard/[id]',
70
+ });
71
+ expect(issues.length).toBeGreaterThan(0);
72
+ const issue = issues.find(i => i.id === 'DYNAMIC_ROUTE_CANDIDATE');
73
+ expect(issue?.severity).toBe('info');
74
+ expect(issue?.message).toContain('cookies()');
75
+ });
76
+ it('detects headers() call without specific key access', () => {
77
+ const parentSpan = createMockSpan({
78
+ spanContext: () => ({
79
+ traceId: 'test-trace',
80
+ spanId: 'parent-span',
81
+ traceFlags: 0x01,
82
+ traceState: undefined,
83
+ isRecording: true,
84
+ }),
85
+ });
86
+ const headerSpan = createMockSpan({
87
+ name: 'headers',
88
+ spanContext: () => ({
89
+ traceId: 'test-trace',
90
+ spanId: 'header-span',
91
+ traceFlags: 0x01,
92
+ traceState: undefined,
93
+ isRecording: true,
94
+ }),
95
+ parentSpanId: 'parent-span',
96
+ attributes: {
97
+ 'function.name': 'headers',
98
+ },
99
+ });
100
+ const issues = detector.detect([parentSpan, headerSpan], {
101
+ runtime: 'nodejs',
102
+ route: '/api/user',
103
+ });
104
+ const issue = issues.find(i => i.id === 'DYNAMIC_ROUTE_CANDIDATE');
105
+ expect(issue?.message).toContain('headers()');
106
+ });
107
+ it('does not fire when cookies span has child spans', () => {
108
+ const parentSpan = createMockSpan({
109
+ spanContext: () => ({
110
+ traceId: 'test-trace',
111
+ spanId: 'parent-span',
112
+ traceFlags: 0x01,
113
+ traceState: undefined,
114
+ isRecording: true,
115
+ }),
116
+ });
117
+ const cookieSpan = createMockSpan({
118
+ name: 'cookies',
119
+ spanContext: () => ({
120
+ traceId: 'test-trace',
121
+ spanId: 'cookie-span',
122
+ traceFlags: 0x01,
123
+ traceState: undefined,
124
+ isRecording: true,
125
+ }),
126
+ parentSpanId: 'parent-span',
127
+ attributes: {
128
+ 'function.name': 'cookies',
129
+ },
130
+ });
131
+ const cookieGetSpan = createMockSpan({
132
+ name: 'cookies.get("session")',
133
+ spanContext: () => ({
134
+ traceId: 'test-trace',
135
+ spanId: 'cookie-get-span',
136
+ traceFlags: 0x01,
137
+ traceState: undefined,
138
+ isRecording: true,
139
+ }),
140
+ parentSpanId: 'cookie-span',
141
+ attributes: {
142
+ 'cookie.key': 'session',
143
+ },
144
+ });
145
+ const issues = detector.detect([parentSpan, cookieSpan, cookieGetSpan], {
146
+ runtime: 'nodejs',
147
+ route: '/dashboard/[id]',
148
+ });
149
+ expect(issues.filter(i => i.id === 'DYNAMIC_ROUTE_CANDIDATE' &&
150
+ i.message.includes('cookies()'))).toHaveLength(0);
151
+ });
152
+ it('does not fire when headers span has child spans', () => {
153
+ const parentSpan = createMockSpan({
154
+ spanContext: () => ({
155
+ traceId: 'test-trace',
156
+ spanId: 'parent-span',
157
+ traceFlags: 0x01,
158
+ traceState: undefined,
159
+ isRecording: true,
160
+ }),
161
+ });
162
+ const headerSpan = createMockSpan({
163
+ name: 'headers',
164
+ spanContext: () => ({
165
+ traceId: 'test-trace',
166
+ spanId: 'header-span',
167
+ traceFlags: 0x01,
168
+ traceState: undefined,
169
+ isRecording: true,
170
+ }),
171
+ parentSpanId: 'parent-span',
172
+ attributes: {
173
+ 'function.name': 'headers',
174
+ },
175
+ });
176
+ const headerGetSpan = createMockSpan({
177
+ name: 'headers.get("authorization")',
178
+ spanContext: () => ({
179
+ traceId: 'test-trace',
180
+ spanId: 'header-get-span',
181
+ traceFlags: 0x01,
182
+ traceState: undefined,
183
+ isRecording: true,
184
+ }),
185
+ parentSpanId: 'header-span',
186
+ attributes: {
187
+ 'header.name': 'authorization',
188
+ },
189
+ });
190
+ const issues = detector.detect([parentSpan, headerSpan, headerGetSpan], {
191
+ runtime: 'nodejs',
192
+ route: '/api/protected',
193
+ });
194
+ expect(issues.filter(i => i.id === 'DYNAMIC_ROUTE_CANDIDATE' &&
195
+ i.message.includes('headers()'))).toHaveLength(0);
196
+ });
197
+ it('suggests removing cookies() when not needed', () => {
198
+ const parentSpan = createMockSpan({
199
+ spanContext: () => ({
200
+ traceId: 'test-trace',
201
+ spanId: 'parent-span',
202
+ traceFlags: 0x01,
203
+ traceState: undefined,
204
+ isRecording: true,
205
+ }),
206
+ });
207
+ const cookieSpan = createMockSpan({
208
+ name: 'cookies',
209
+ spanContext: () => ({
210
+ traceId: 'test-trace',
211
+ spanId: 'cookie-span',
212
+ traceFlags: 0x01,
213
+ traceState: undefined,
214
+ isRecording: true,
215
+ }),
216
+ parentSpanId: 'parent-span',
217
+ });
218
+ const issues = detector.detect([parentSpan, cookieSpan], {
219
+ runtime: 'nodejs',
220
+ route: '/dashboard/[id]',
221
+ });
222
+ const issue = issues.find(i => i.id === 'DYNAMIC_ROUTE_CANDIDATE');
223
+ expect(issue?.suggestion).toContain('Remove');
224
+ expect(issue?.suggestion).toContain('cookies()');
225
+ });
226
+ it('includes remediation options in suggestion', () => {
227
+ const parentSpan = createMockSpan({
228
+ spanContext: () => ({
229
+ traceId: 'test-trace',
230
+ spanId: 'parent-span',
231
+ traceFlags: 0x01,
232
+ traceState: undefined,
233
+ isRecording: true,
234
+ }),
235
+ });
236
+ const headerSpan = createMockSpan({
237
+ name: 'headers',
238
+ spanContext: () => ({
239
+ traceId: 'test-trace',
240
+ spanId: 'header-span',
241
+ traceFlags: 0x01,
242
+ traceState: undefined,
243
+ isRecording: true,
244
+ }),
245
+ parentSpanId: 'parent-span',
246
+ });
247
+ const issues = detector.detect([parentSpan, headerSpan], {
248
+ runtime: 'nodejs',
249
+ route: '/api/user',
250
+ });
251
+ const issue = issues.find(i => i.id === 'DYNAMIC_ROUTE_CANDIDATE');
252
+ // Should include 3 remediation options
253
+ expect(issue?.suggestion).toContain('Option 1');
254
+ expect(issue?.suggestion).toContain('Option 2');
255
+ expect(issue?.suggestion).toContain('Option 3');
256
+ });
257
+ it('does not detect issues for static routes', () => {
258
+ const parentSpan = createMockSpan({
259
+ spanContext: () => ({
260
+ traceId: 'test-trace',
261
+ spanId: 'parent-span',
262
+ traceFlags: 0x01,
263
+ traceState: undefined,
264
+ isRecording: true,
265
+ }),
266
+ });
267
+ const cookieSpan = createMockSpan({
268
+ name: 'cookies',
269
+ spanContext: () => ({
270
+ traceId: 'test-trace',
271
+ spanId: 'cookie-span',
272
+ traceFlags: 0x01,
273
+ traceState: undefined,
274
+ isRecording: true,
275
+ }),
276
+ parentSpanId: 'parent-span',
277
+ });
278
+ // Even with cookies span, should not report for static routes
279
+ const issues = detector.detect([parentSpan, cookieSpan], {
280
+ runtime: 'nodejs',
281
+ route: '/about', // static route
282
+ });
283
+ // May or may not have other issues, but cookies() issue should be present
284
+ // (detector doesn't filter by route type - that's parent's responsibility)
285
+ expect(issues.length >= 0).toBe(true);
286
+ });
287
+ it('includes route and span context in issue attributes', () => {
288
+ const parentSpan = createMockSpan({
289
+ spanContext: () => ({
290
+ traceId: 'test-trace',
291
+ spanId: 'parent-span',
292
+ traceFlags: 0x01,
293
+ traceState: undefined,
294
+ isRecording: true,
295
+ }),
296
+ });
297
+ const headerSpan = createMockSpan({
298
+ name: 'headers',
299
+ spanContext: () => ({
300
+ traceId: 'test-trace',
301
+ spanId: 'header-span',
302
+ traceFlags: 0x01,
303
+ traceState: undefined,
304
+ isRecording: true,
305
+ }),
306
+ parentSpanId: 'parent-span',
307
+ });
308
+ const issues = detector.detect([parentSpan, headerSpan], {
309
+ runtime: 'nodejs',
310
+ route: '/api/user',
311
+ });
312
+ expect(issues.length).toBeGreaterThan(0);
313
+ const issue = issues[0];
314
+ expect(issue.route).toBe('/api/user');
315
+ expect(issue.spanId).toBeDefined();
316
+ });
317
+ });
318
+ //# sourceMappingURL=dynamic-route-candidate.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dynamic-route-candidate.test.js","sourceRoot":"","sources":["../../../src/detectors/__tests__/dynamic-route-candidate.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=fetch-no-cache.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-no-cache.test.d.ts","sourceRoot":"","sources":["../../../src/detectors/__tests__/fetch-no-cache.test.ts"],"names":[],"mappings":""}