@stratal/testing 0.0.11 → 0.0.13
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.
- package/dist/core/env/test-env.js +1 -1
- package/dist/core/env/test-env.js.map +1 -1
- package/dist/core/http/index.d.ts +1 -1
- package/dist/core/http/index.js +1 -1
- package/dist/core/http/mock-fetch.d.ts +88 -0
- package/dist/core/http/mock-fetch.d.ts.map +1 -0
- package/dist/core/http/mock-fetch.js +111 -0
- package/dist/core/http/mock-fetch.js.map +1 -0
- package/dist/core/override/provider-override-builder.d.ts +1 -0
- package/dist/core/override/provider-override-builder.d.ts.map +1 -1
- package/dist/core/override/provider-override-builder.js.map +1 -1
- package/dist/core/sse/index.d.ts +3 -0
- package/dist/core/sse/index.d.ts.map +1 -0
- package/dist/core/sse/index.js +3 -0
- package/dist/core/sse/index.js.map +1 -0
- package/dist/core/sse/test-sse-connection.d.ts +61 -0
- package/dist/core/sse/test-sse-connection.d.ts.map +1 -0
- package/dist/core/sse/test-sse-connection.js +233 -0
- package/dist/core/sse/test-sse-connection.js.map +1 -0
- package/dist/core/sse/test-sse-request.d.ts +42 -0
- package/dist/core/sse/test-sse-request.d.ts.map +1 -0
- package/dist/core/sse/test-sse-request.js +76 -0
- package/dist/core/sse/test-sse-request.js.map +1 -0
- package/dist/core/testing-module-builder.js +2 -2
- package/dist/core/testing-module-builder.js.map +1 -1
- package/dist/core/testing-module.d.ts +10 -0
- package/dist/core/testing-module.d.ts.map +1 -1
- package/dist/core/testing-module.js +15 -3
- package/dist/core/testing-module.js.map +1 -1
- package/dist/core/ws/index.d.ts +3 -0
- package/dist/core/ws/index.d.ts.map +1 -0
- package/dist/core/ws/index.js +3 -0
- package/dist/core/ws/index.js.map +1 -0
- package/dist/core/ws/test-ws-connection.d.ts +54 -0
- package/dist/core/ws/test-ws-connection.d.ts.map +1 -0
- package/dist/core/ws/test-ws-connection.js +119 -0
- package/dist/core/ws/test-ws-connection.js.map +1 -0
- package/dist/core/ws/test-ws-request.d.ts +43 -0
- package/dist/core/ws/test-ws-request.d.ts.map +1 -0
- package/dist/core/ws/test-ws-request.js +83 -0
- package/dist/core/ws/test-ws-request.js.map +1 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -1
- package/dist/index.js.map +1 -1
- package/dist/vitest-plugin/index.d.ts +2 -0
- package/dist/vitest-plugin/index.d.ts.map +1 -0
- package/dist/vitest-plugin/index.js +2 -0
- package/dist/vitest-plugin/index.js.map +1 -0
- package/dist/vitest-plugin/stratal-test.d.ts +28 -0
- package/dist/vitest-plugin/stratal-test.d.ts.map +1 -0
- package/dist/vitest-plugin/stratal-test.js +47 -0
- package/dist/vitest-plugin/stratal-test.js.map +1 -0
- package/package.json +17 -10
- package/dist/core/http/fetch-mock.d.ts +0 -236
- package/dist/core/http/fetch-mock.d.ts.map +0 -1
- package/dist/core/http/fetch-mock.js +0 -290
- package/dist/core/http/fetch-mock.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-env.js","sourceRoot":"","sources":["../../../src/core/env/test-env.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,IAAI,aAAa,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"test-env.js","sourceRoot":"","sources":["../../../src/core/env/test-env.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,IAAI,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAEzD;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,SAA+B;IACxD,OAAO;QACL,GAAG,aAAa;QAChB,GAAG,SAAS;KACC,CAAA;AACjB,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { TestHttpClient } from './test-http-client';
|
|
2
2
|
export { TestHttpRequest } from './test-http-request';
|
|
3
3
|
export { TestResponse } from './test-response';
|
|
4
|
-
export {
|
|
4
|
+
export { MockFetch, createMockFetch } from './mock-fetch';
|
|
5
5
|
export type { MockJsonOptions, MockErrorOptions } from './fetch-mock.types';
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/core/http/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { TestHttpClient } from './test-http-client';
|
|
2
2
|
export { TestHttpRequest } from './test-http-request';
|
|
3
3
|
export { TestResponse } from './test-response';
|
|
4
|
-
export {
|
|
4
|
+
export { MockFetch, createMockFetch } from './mock-fetch';
|
|
5
5
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { type RequestHandler } from 'msw';
|
|
2
|
+
import type { MockErrorOptions, MockJsonOptions } from './fetch-mock.types';
|
|
3
|
+
/**
|
|
4
|
+
* MSW-based fetch mock for declarative HTTP mocking in tests.
|
|
5
|
+
*
|
|
6
|
+
* Replaces the old Cloudflare `fetchMock` (undici MockAgent) with MSW's `setupServer`.
|
|
7
|
+
* Works in both Node.js and workerd test environments.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { createMockFetch } from '@stratal/testing'
|
|
12
|
+
*
|
|
13
|
+
* const mock = createMockFetch()
|
|
14
|
+
*
|
|
15
|
+
* beforeAll(() => mock.listen())
|
|
16
|
+
* afterEach(() => mock.reset())
|
|
17
|
+
* afterAll(() => mock.close())
|
|
18
|
+
*
|
|
19
|
+
* it('should mock external API', async () => {
|
|
20
|
+
* mock.mockJsonResponse('https://api.example.com/data', { success: true })
|
|
21
|
+
*
|
|
22
|
+
* const response = await fetch('https://api.example.com/data')
|
|
23
|
+
* const json = await response.json()
|
|
24
|
+
*
|
|
25
|
+
* expect(json.success).toBe(true)
|
|
26
|
+
* })
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare class MockFetch {
|
|
30
|
+
private server;
|
|
31
|
+
constructor(handlers?: RequestHandler[]);
|
|
32
|
+
/** Start intercepting. Call in beforeAll/beforeEach. */
|
|
33
|
+
listen(): void;
|
|
34
|
+
/** Reset runtime handlers. Call in afterEach. */
|
|
35
|
+
reset(): void;
|
|
36
|
+
/** Stop intercepting. Call in afterAll. */
|
|
37
|
+
close(): void;
|
|
38
|
+
/** Add runtime handler(s) for a single test. */
|
|
39
|
+
use(...handlers: RequestHandler[]): void;
|
|
40
|
+
/**
|
|
41
|
+
* Mock a JSON response.
|
|
42
|
+
*
|
|
43
|
+
* @param url - Full URL to mock (e.g., 'https://api.example.com/users')
|
|
44
|
+
* @param data - JSON data to return
|
|
45
|
+
* @param options - HTTP method, status code, headers
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* mock.mockJsonResponse('https://api.example.com/users', { users: [] })
|
|
50
|
+
* mock.mockJsonResponse('https://api.example.com/users', { created: true }, { method: 'POST', status: 201 })
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
mockJsonResponse(url: string, data: Record<string, unknown> | unknown[], options?: MockJsonOptions): void;
|
|
54
|
+
/**
|
|
55
|
+
* Mock an error response.
|
|
56
|
+
*
|
|
57
|
+
* @param url - Full URL to mock
|
|
58
|
+
* @param status - HTTP error status code
|
|
59
|
+
* @param message - Optional error message
|
|
60
|
+
* @param options - HTTP method, headers
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* mock.mockError('https://api.example.com/fail', 401, 'Unauthorized')
|
|
65
|
+
* mock.mockError('https://api.example.com/fail', 500, 'Server Error', { method: 'POST' })
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
mockError(url: string, status: number, message?: string, options?: MockErrorOptions): void;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Factory function to create a new MockFetch instance
|
|
72
|
+
*
|
|
73
|
+
* @param handlers - Optional initial MSW request handlers
|
|
74
|
+
* @returns A new MockFetch instance
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* import { createMockFetch } from '@stratal/testing'
|
|
79
|
+
*
|
|
80
|
+
* const mock = createMockFetch()
|
|
81
|
+
*
|
|
82
|
+
* beforeAll(() => mock.listen())
|
|
83
|
+
* afterEach(() => mock.reset())
|
|
84
|
+
* afterAll(() => mock.close())
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export declare function createMockFetch(handlers?: RequestHandler[]): MockFetch;
|
|
88
|
+
//# sourceMappingURL=mock-fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-fetch.d.ts","sourceRoot":"","sources":["../../../src/core/http/mock-fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,cAAc,EAAE,MAAM,KAAK,CAAA;AAE7D,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAI3E;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAa;gBAEf,QAAQ,GAAE,cAAc,EAAO;IAI3C,wDAAwD;IACxD,MAAM;IAIN,iDAAiD;IACjD,KAAK;IAIL,2CAA2C;IAC3C,KAAK;IAIL,gDAAgD;IAChD,GAAG,CAAC,GAAG,QAAQ,EAAE,cAAc,EAAE;IAIjC;;;;;;;;;;;;OAYG;IACH,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,EAAE,EAAE,OAAO,GAAE,eAAoB;IAWtG;;;;;;;;;;;;;OAaG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB;CASxF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,QAAQ,CAAC,EAAE,cAAc,EAAE,GAAG,SAAS,CAEtE"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { http, HttpResponse } from 'msw';
|
|
2
|
+
import { setupServer } from 'msw/node';
|
|
3
|
+
/**
|
|
4
|
+
* MSW-based fetch mock for declarative HTTP mocking in tests.
|
|
5
|
+
*
|
|
6
|
+
* Replaces the old Cloudflare `fetchMock` (undici MockAgent) with MSW's `setupServer`.
|
|
7
|
+
* Works in both Node.js and workerd test environments.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { createMockFetch } from '@stratal/testing'
|
|
12
|
+
*
|
|
13
|
+
* const mock = createMockFetch()
|
|
14
|
+
*
|
|
15
|
+
* beforeAll(() => mock.listen())
|
|
16
|
+
* afterEach(() => mock.reset())
|
|
17
|
+
* afterAll(() => mock.close())
|
|
18
|
+
*
|
|
19
|
+
* it('should mock external API', async () => {
|
|
20
|
+
* mock.mockJsonResponse('https://api.example.com/data', { success: true })
|
|
21
|
+
*
|
|
22
|
+
* const response = await fetch('https://api.example.com/data')
|
|
23
|
+
* const json = await response.json()
|
|
24
|
+
*
|
|
25
|
+
* expect(json.success).toBe(true)
|
|
26
|
+
* })
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export class MockFetch {
|
|
30
|
+
server;
|
|
31
|
+
constructor(handlers = []) {
|
|
32
|
+
this.server = setupServer(...handlers);
|
|
33
|
+
}
|
|
34
|
+
/** Start intercepting. Call in beforeAll/beforeEach. */
|
|
35
|
+
listen() {
|
|
36
|
+
this.server.listen({ onUnhandledRequest: 'error' });
|
|
37
|
+
}
|
|
38
|
+
/** Reset runtime handlers. Call in afterEach. */
|
|
39
|
+
reset() {
|
|
40
|
+
this.server.resetHandlers();
|
|
41
|
+
}
|
|
42
|
+
/** Stop intercepting. Call in afterAll. */
|
|
43
|
+
close() {
|
|
44
|
+
this.server.close();
|
|
45
|
+
}
|
|
46
|
+
/** Add runtime handler(s) for a single test. */
|
|
47
|
+
use(...handlers) {
|
|
48
|
+
this.server.use(...handlers);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Mock a JSON response.
|
|
52
|
+
*
|
|
53
|
+
* @param url - Full URL to mock (e.g., 'https://api.example.com/users')
|
|
54
|
+
* @param data - JSON data to return
|
|
55
|
+
* @param options - HTTP method, status code, headers
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* mock.mockJsonResponse('https://api.example.com/users', { users: [] })
|
|
60
|
+
* mock.mockJsonResponse('https://api.example.com/users', { created: true }, { method: 'POST', status: 201 })
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
mockJsonResponse(url, data, options = {}) {
|
|
64
|
+
const method = (options.method ?? 'GET').toLowerCase();
|
|
65
|
+
const handler = http[method](url, () => HttpResponse.json(data, {
|
|
66
|
+
status: options.status ?? 200,
|
|
67
|
+
headers: options.headers,
|
|
68
|
+
}));
|
|
69
|
+
this.server.use(handler);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Mock an error response.
|
|
73
|
+
*
|
|
74
|
+
* @param url - Full URL to mock
|
|
75
|
+
* @param status - HTTP error status code
|
|
76
|
+
* @param message - Optional error message
|
|
77
|
+
* @param options - HTTP method, headers
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* mock.mockError('https://api.example.com/fail', 401, 'Unauthorized')
|
|
82
|
+
* mock.mockError('https://api.example.com/fail', 500, 'Server Error', { method: 'POST' })
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
mockError(url, status, message, options = {}) {
|
|
86
|
+
const method = (options.method ?? 'GET').toLowerCase();
|
|
87
|
+
const body = message ? { error: message } : undefined;
|
|
88
|
+
this.server.use(http[method](url, () => HttpResponse.json(body, { status, headers: options.headers })));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Factory function to create a new MockFetch instance
|
|
93
|
+
*
|
|
94
|
+
* @param handlers - Optional initial MSW request handlers
|
|
95
|
+
* @returns A new MockFetch instance
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```typescript
|
|
99
|
+
* import { createMockFetch } from '@stratal/testing'
|
|
100
|
+
*
|
|
101
|
+
* const mock = createMockFetch()
|
|
102
|
+
*
|
|
103
|
+
* beforeAll(() => mock.listen())
|
|
104
|
+
* afterEach(() => mock.reset())
|
|
105
|
+
* afterAll(() => mock.close())
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
export function createMockFetch(handlers) {
|
|
109
|
+
return new MockFetch(handlers);
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=mock-fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-fetch.js","sourceRoot":"","sources":["../../../src/core/http/mock-fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,YAAY,EAAuB,MAAM,KAAK,CAAA;AAC7D,OAAO,EAAE,WAAW,EAAoB,MAAM,UAAU,CAAA;AAKxD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,OAAO,SAAS;IACZ,MAAM,CAAa;IAE3B,YAAY,WAA6B,EAAE;QACzC,IAAI,CAAC,MAAM,GAAG,WAAW,CAAC,GAAG,QAAQ,CAAC,CAAA;IACxC,CAAC;IAED,wDAAwD;IACxD,MAAM;QACJ,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,kBAAkB,EAAE,OAAO,EAAE,CAAC,CAAA;IACrD,CAAC;IAED,iDAAiD;IACjD,KAAK;QACH,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAA;IAC7B,CAAC;IAED,2CAA2C;IAC3C,KAAK;QACH,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAA;IACrB,CAAC;IAED,gDAAgD;IAChD,GAAG,CAAC,GAAG,QAA0B;QAC/B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAA;IAC9B,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,gBAAgB,CAAC,GAAW,EAAE,IAAyC,EAAE,UAA2B,EAAE;QACpG,MAAM,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAgB,CAAA;QACpE,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CACrC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE;YACtB,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,GAAG;YAC7B,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,CAAC,CACH,CAAA;QACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IAC1B,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,SAAS,CAAC,GAAW,EAAE,MAAc,EAAE,OAAgB,EAAE,UAA4B,EAAE;QACrF,MAAM,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAgB,CAAA;QACpE,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;QACrD,IAAI,CAAC,MAAM,CAAC,GAAG,CACb,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CACrB,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAC9D,CACF,CAAA;IACH,CAAC;CACF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,eAAe,CAAC,QAA2B;IACzD,OAAO,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAA;AAChC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider-override-builder.d.ts","sourceRoot":"","sources":["../../../src/core/override/provider-override-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAErE;;GAEG;AACH,MAAM,WAAW,sBAAsB,CAAC,CAAC,GAAG,OAAO;IACjD,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,CAAA;IACxB,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,CAAA;IAChD,cAAc,EAAE,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,SAAS,KAAK,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA;CACxG;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,uBAAuB,CAAC,CAAC;IAElC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBADL,MAAM,EAAE,oBAAoB,EAC5B,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC;IAG3C;;;;;;;OAOG;IACH,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,oBAAoB;IAQxC;;;;;;;OAOG;IACH,QAAQ,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,oBAAoB;IAQlE;;;;;;;OAOG;IACH,UAAU,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,CAAC,GAAG,oBAAoB;IAQtE;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,oBAAoB;CAOpE"}
|
|
1
|
+
{"version":3,"file":"provider-override-builder.d.ts","sourceRoot":"","sources":["../../../src/core/override/provider-override-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AAErE;;GAEG;AACH,MAAM,WAAW,sBAAsB,CAAC,CAAC,GAAG,OAAO;IACjD,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,CAAA;IACxB,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,CAAA;IAChD,cAAc,EAAE,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,EAAE,SAAS,KAAK,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA;CACxG;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,uBAAuB,CAAC,CAAC;IAElC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBADL,MAAM,EAAE,oBAAoB,EAC5B,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC;IAG3C;;;;;;;OAOG;IACH,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,oBAAoB;IAQxC;;;;;;;OAOG;IACH,QAAQ,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,oBAAoB;IAQlE;;;;;;;OAOG;IACH,UAAU,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,CAAC,GAAG,oBAAoB;IAQtE;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,oBAAoB;CAOpE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider-override-builder.js","sourceRoot":"","sources":["../../../src/core/override/provider-override-builder.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"provider-override-builder.js","sourceRoot":"","sources":["../../../src/core/override/provider-override-builder.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,uBAAuB;IAEf;IACA;IAFnB,YACmB,MAA4B,EAC5B,KAAwB;QADxB,WAAM,GAAN,MAAM,CAAsB;QAC5B,UAAK,GAAL,KAAK,CAAmB;IACvC,CAAC;IAEL;;;;;;;OAOG;IACH,QAAQ,CAAC,KAAQ;QACf,OAAO,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC;YACrC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,OAAO;YACb,cAAc,EAAE,KAAK;SACtB,CAAC,CAAA;IACJ,CAAC;IAED;;;;;;;OAOG;IACH,QAAQ,CAAC,GAAkC;QACzC,OAAO,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC;YACrC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,OAAO;YACb,cAAc,EAAE,GAAG;SACpB,CAAC,CAAA;IACJ,CAAC;IAED;;;;;;;OAOG;IACH,UAAU,CAAC,OAAoC;QAC7C,OAAO,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC;YACrC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,SAAS;YACf,cAAc,EAAE,OAAO;SACxB,CAAC,CAAA;IACJ,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,WAAW,CAAC,aAAgC;QAC1C,OAAO,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC;YACrC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,UAAU;YAChB,cAAc,EAAE,aAAa;SAC9B,CAAC,CAAA;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/sse/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,EAAE,iBAAiB,EAAE,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/sse/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,EAAE,iBAAiB,EAAqB,MAAM,uBAAuB,CAAA"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Represents a parsed SSE event
|
|
3
|
+
*/
|
|
4
|
+
export interface TestSseEvent {
|
|
5
|
+
data: string;
|
|
6
|
+
event?: string;
|
|
7
|
+
id?: string;
|
|
8
|
+
retry?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* TestSseConnection
|
|
12
|
+
*
|
|
13
|
+
* Live SSE connection wrapper with assertion helpers for testing.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const sse = await module.sse('/streaming/sse').connect()
|
|
18
|
+
* await sse.assertEvent({ event: 'message', data: 'hello', id: '1' })
|
|
19
|
+
* await sse.waitForEnd()
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare class TestSseConnection {
|
|
23
|
+
private readonly response;
|
|
24
|
+
private readonly eventQueue;
|
|
25
|
+
private eventWaiters;
|
|
26
|
+
private streamEnded;
|
|
27
|
+
private endWaiters;
|
|
28
|
+
constructor(response: Response);
|
|
29
|
+
/**
|
|
30
|
+
* Wait for the next SSE event
|
|
31
|
+
*/
|
|
32
|
+
waitForEvent(timeout?: number): Promise<TestSseEvent>;
|
|
33
|
+
/**
|
|
34
|
+
* Wait for the stream to end
|
|
35
|
+
*/
|
|
36
|
+
waitForEnd(timeout?: number): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Collect all remaining events until the stream ends
|
|
39
|
+
*/
|
|
40
|
+
collectEvents(timeout?: number): Promise<TestSseEvent[]>;
|
|
41
|
+
/**
|
|
42
|
+
* Assert that the next event matches the expected partial shape
|
|
43
|
+
*/
|
|
44
|
+
assertEvent(expected: Partial<TestSseEvent>, timeout?: number): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Assert that the next event's data matches the expected string
|
|
47
|
+
*/
|
|
48
|
+
assertEventData(expected: string, timeout?: number): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Assert that the next event's data is JSON matching the expected value
|
|
51
|
+
*/
|
|
52
|
+
assertJsonEventData<T>(expected: T, timeout?: number): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Access the raw Response
|
|
55
|
+
*/
|
|
56
|
+
get raw(): Response;
|
|
57
|
+
private startReading;
|
|
58
|
+
private parseEvent;
|
|
59
|
+
private dispatchEvent;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=test-sse-connection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-sse-connection.d.ts","sourceRoot":"","sources":["../../../src/core/sse/test-sse-connection.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,iBAAiB;IAMjB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IALrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD,OAAO,CAAC,YAAY,CAAwC;IAC5D,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,UAAU,CAAqB;gBAEV,QAAQ,EAAE,QAAQ;IAI/C;;OAEG;IACG,YAAY,CAAC,OAAO,SAAO,GAAG,OAAO,CAAC,YAAY,CAAC;IAyBzD;;OAEG;IACG,UAAU,CAAC,OAAO,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB/C;;OAEG;IACG,aAAa,CAAC,OAAO,SAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAmC5D;;OAEG;IACG,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,YAAY,CAAC,EAAE,OAAO,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAKjF;;OAEG;IACG,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAKtE;;OAEG;IACG,mBAAmB,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAMxE;;OAEG;IACH,IAAI,GAAG,IAAI,QAAQ,CAElB;IAED,OAAO,CAAC,YAAY;IAwDpB,OAAO,CAAC,UAAU;IA6ClB,OAAO,CAAC,aAAa;CAOrB"}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { expect } from "vitest";
|
|
2
|
+
/**
|
|
3
|
+
* TestSseConnection
|
|
4
|
+
*
|
|
5
|
+
* Live SSE connection wrapper with assertion helpers for testing.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const sse = await module.sse('/streaming/sse').connect()
|
|
10
|
+
* await sse.assertEvent({ event: 'message', data: 'hello', id: '1' })
|
|
11
|
+
* await sse.waitForEnd()
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export class TestSseConnection {
|
|
15
|
+
response;
|
|
16
|
+
eventQueue = [];
|
|
17
|
+
eventWaiters = [];
|
|
18
|
+
streamEnded = false;
|
|
19
|
+
endWaiters = [];
|
|
20
|
+
constructor(response) {
|
|
21
|
+
this.response = response;
|
|
22
|
+
this.startReading();
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Wait for the next SSE event
|
|
26
|
+
*/
|
|
27
|
+
async waitForEvent(timeout = 5000) {
|
|
28
|
+
if (this.eventQueue.length > 0) {
|
|
29
|
+
return this.eventQueue.shift();
|
|
30
|
+
}
|
|
31
|
+
if (this.streamEnded) {
|
|
32
|
+
throw new Error('SSE: stream has ended, no more events');
|
|
33
|
+
}
|
|
34
|
+
return new Promise((resolve, reject) => {
|
|
35
|
+
const waiter = (event) => {
|
|
36
|
+
clearTimeout(timer);
|
|
37
|
+
resolve(event);
|
|
38
|
+
};
|
|
39
|
+
const timer = setTimeout(() => {
|
|
40
|
+
const index = this.eventWaiters.indexOf(waiter);
|
|
41
|
+
if (index !== -1)
|
|
42
|
+
this.eventWaiters.splice(index, 1);
|
|
43
|
+
reject(new Error(`SSE: no event received within ${timeout}ms`));
|
|
44
|
+
}, timeout);
|
|
45
|
+
this.eventWaiters.push(waiter);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Wait for the stream to end
|
|
50
|
+
*/
|
|
51
|
+
async waitForEnd(timeout = 5000) {
|
|
52
|
+
if (this.streamEnded)
|
|
53
|
+
return;
|
|
54
|
+
return new Promise((resolve, reject) => {
|
|
55
|
+
const waiter = () => {
|
|
56
|
+
clearTimeout(timer);
|
|
57
|
+
resolve();
|
|
58
|
+
};
|
|
59
|
+
const timer = setTimeout(() => {
|
|
60
|
+
const index = this.endWaiters.indexOf(waiter);
|
|
61
|
+
if (index !== -1)
|
|
62
|
+
this.endWaiters.splice(index, 1);
|
|
63
|
+
reject(new Error(`SSE: stream did not end within ${timeout}ms`));
|
|
64
|
+
}, timeout);
|
|
65
|
+
this.endWaiters.push(waiter);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Collect all remaining events until the stream ends
|
|
70
|
+
*/
|
|
71
|
+
async collectEvents(timeout = 5000) {
|
|
72
|
+
const events = [];
|
|
73
|
+
if (this.streamEnded) {
|
|
74
|
+
return [...this.eventQueue.splice(0)];
|
|
75
|
+
}
|
|
76
|
+
return new Promise((resolve, reject) => {
|
|
77
|
+
// Listen for new events until stream ends
|
|
78
|
+
const originalDispatch = this.dispatchEvent.bind(this);
|
|
79
|
+
this.dispatchEvent = (event) => {
|
|
80
|
+
events.push(event);
|
|
81
|
+
originalDispatch(event);
|
|
82
|
+
};
|
|
83
|
+
const endWaiter = () => {
|
|
84
|
+
clearTimeout(timer);
|
|
85
|
+
this.dispatchEvent = originalDispatch;
|
|
86
|
+
resolve(events);
|
|
87
|
+
};
|
|
88
|
+
const timer = setTimeout(() => {
|
|
89
|
+
this.dispatchEvent = originalDispatch;
|
|
90
|
+
const index = this.endWaiters.indexOf(endWaiter);
|
|
91
|
+
if (index !== -1)
|
|
92
|
+
this.endWaiters.splice(index, 1);
|
|
93
|
+
reject(new Error(`SSE: stream did not end within ${timeout}ms`));
|
|
94
|
+
}, timeout);
|
|
95
|
+
// Drain any queued events first
|
|
96
|
+
events.push(...this.eventQueue.splice(0));
|
|
97
|
+
this.endWaiters.push(endWaiter);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Assert that the next event matches the expected partial shape
|
|
102
|
+
*/
|
|
103
|
+
async assertEvent(expected, timeout = 5000) {
|
|
104
|
+
const event = await this.waitForEvent(timeout);
|
|
105
|
+
expect(event).toMatchObject(expected);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Assert that the next event's data matches the expected string
|
|
109
|
+
*/
|
|
110
|
+
async assertEventData(expected, timeout = 5000) {
|
|
111
|
+
const event = await this.waitForEvent(timeout);
|
|
112
|
+
expect(event.data, `Expected SSE data "${expected}", got "${event.data}"`).toBe(expected);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Assert that the next event's data is JSON matching the expected value
|
|
116
|
+
*/
|
|
117
|
+
async assertJsonEventData(expected, timeout = 5000) {
|
|
118
|
+
const event = await this.waitForEvent(timeout);
|
|
119
|
+
const parsed = JSON.parse(event.data);
|
|
120
|
+
expect(parsed).toEqual(expected);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Access the raw Response
|
|
124
|
+
*/
|
|
125
|
+
get raw() {
|
|
126
|
+
return this.response;
|
|
127
|
+
}
|
|
128
|
+
startReading() {
|
|
129
|
+
const body = this.response.body;
|
|
130
|
+
if (!body) {
|
|
131
|
+
this.streamEnded = true;
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const reader = body.getReader();
|
|
135
|
+
const decoder = new TextDecoder();
|
|
136
|
+
let buffer = '';
|
|
137
|
+
const read = async () => {
|
|
138
|
+
try {
|
|
139
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
140
|
+
while (true) {
|
|
141
|
+
const { done, value } = await reader.read();
|
|
142
|
+
if (done) {
|
|
143
|
+
// Parse any remaining buffered data
|
|
144
|
+
if (buffer.trim()) {
|
|
145
|
+
const event = this.parseEvent(buffer);
|
|
146
|
+
if (event)
|
|
147
|
+
this.dispatchEvent(event);
|
|
148
|
+
}
|
|
149
|
+
this.streamEnded = true;
|
|
150
|
+
for (const waiter of this.endWaiters) {
|
|
151
|
+
waiter();
|
|
152
|
+
}
|
|
153
|
+
this.endWaiters = [];
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
buffer += decoder.decode(value, { stream: true });
|
|
157
|
+
// Split on double newlines (SSE event boundary)
|
|
158
|
+
const parts = buffer.split('\n\n');
|
|
159
|
+
// Last part may be incomplete, keep it in the buffer
|
|
160
|
+
buffer = parts.pop();
|
|
161
|
+
for (const part of parts) {
|
|
162
|
+
if (!part.trim())
|
|
163
|
+
continue;
|
|
164
|
+
const event = this.parseEvent(part);
|
|
165
|
+
if (event)
|
|
166
|
+
this.dispatchEvent(event);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
this.streamEnded = true;
|
|
172
|
+
for (const waiter of this.endWaiters) {
|
|
173
|
+
waiter();
|
|
174
|
+
}
|
|
175
|
+
this.endWaiters = [];
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
void read();
|
|
179
|
+
}
|
|
180
|
+
parseEvent(raw) {
|
|
181
|
+
const lines = raw.split('\n');
|
|
182
|
+
const dataLines = [];
|
|
183
|
+
let event;
|
|
184
|
+
let id;
|
|
185
|
+
let retry;
|
|
186
|
+
for (const line of lines) {
|
|
187
|
+
if (line.startsWith(':'))
|
|
188
|
+
continue; // comment line
|
|
189
|
+
const colonIndex = line.indexOf(':');
|
|
190
|
+
if (colonIndex === -1)
|
|
191
|
+
continue;
|
|
192
|
+
const field = line.slice(0, colonIndex);
|
|
193
|
+
// Strip optional leading space after colon
|
|
194
|
+
const value = line[colonIndex + 1] === ' ' ? line.slice(colonIndex + 2) : line.slice(colonIndex + 1);
|
|
195
|
+
switch (field) {
|
|
196
|
+
case 'data':
|
|
197
|
+
dataLines.push(value);
|
|
198
|
+
break;
|
|
199
|
+
case 'event':
|
|
200
|
+
event = value;
|
|
201
|
+
break;
|
|
202
|
+
case 'id':
|
|
203
|
+
id = value;
|
|
204
|
+
break;
|
|
205
|
+
case 'retry': {
|
|
206
|
+
const parsed = parseInt(value, 10);
|
|
207
|
+
if (!isNaN(parsed))
|
|
208
|
+
retry = parsed;
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (dataLines.length === 0)
|
|
214
|
+
return null;
|
|
215
|
+
const result = { data: dataLines.join('\n') };
|
|
216
|
+
if (event !== undefined)
|
|
217
|
+
result.event = event;
|
|
218
|
+
if (id !== undefined)
|
|
219
|
+
result.id = id;
|
|
220
|
+
if (retry !== undefined)
|
|
221
|
+
result.retry = retry;
|
|
222
|
+
return result;
|
|
223
|
+
}
|
|
224
|
+
dispatchEvent(event) {
|
|
225
|
+
if (this.eventWaiters.length > 0) {
|
|
226
|
+
this.eventWaiters.shift()(event);
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
this.eventQueue.push(event);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=test-sse-connection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-sse-connection.js","sourceRoot":"","sources":["../../../src/core/sse/test-sse-connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { TestingModule } from '../testing-module';
|
|
2
|
+
import { TestSseConnection } from './test-sse-connection';
|
|
3
|
+
/**
|
|
4
|
+
* TestSseRequest
|
|
5
|
+
*
|
|
6
|
+
* Builder for SSE connection requests. Follows the TestWsRequest pattern.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const sse = await module.sse('/streaming/sse').connect()
|
|
11
|
+
* await sse.assertEvent({ event: 'message', data: 'hello' })
|
|
12
|
+
* await sse.waitForEnd()
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* @example Authenticated SSE
|
|
16
|
+
* ```typescript
|
|
17
|
+
* const sse = await module.sse('/streaming/sse').actingAs({ id: user.id }).connect()
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare class TestSseRequest {
|
|
21
|
+
private readonly path;
|
|
22
|
+
private readonly module;
|
|
23
|
+
private requestHeaders;
|
|
24
|
+
private actingAsUser;
|
|
25
|
+
constructor(path: string, module: TestingModule);
|
|
26
|
+
/**
|
|
27
|
+
* Add custom headers to the request
|
|
28
|
+
*/
|
|
29
|
+
withHeaders(headers: Record<string, string>): this;
|
|
30
|
+
/**
|
|
31
|
+
* Authenticate the SSE connection as a specific user
|
|
32
|
+
*/
|
|
33
|
+
actingAs(user: {
|
|
34
|
+
id: string;
|
|
35
|
+
}): this;
|
|
36
|
+
/**
|
|
37
|
+
* Send the request and return a live SSE connection
|
|
38
|
+
*/
|
|
39
|
+
connect(): Promise<TestSseConnection>;
|
|
40
|
+
private applyAuthentication;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=test-sse-request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-sse-request.d.ts","sourceRoot":"","sources":["../../../src/core/sse/test-sse-request.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAA;AAEzD;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,cAAc;IAKzB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM;IALxB,OAAO,CAAC,cAAc,CAAyB;IAC/C,OAAO,CAAC,YAAY,CAA8B;gBAGhC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,aAAa;IAGvC;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAOlD;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAKpC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,iBAAiB,CAAC;YA0B7B,mBAAmB;CAajC"}
|