@apiquest/plugin-sse 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,160 @@
1
+ # @apiquest/plugin-sse
2
+
3
+ Server-Sent Events (SSE) protocol plugin for ApiQuest. Provides support for testing SSE endpoints with event streaming and message validation.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install -g @apiquest/plugin-sse
9
+ ```
10
+
11
+ ## Features
12
+
13
+ - SSE connection management
14
+ - Event streaming with named events
15
+ - Message data validation
16
+ - Event counting and assertions
17
+ - Custom headers support
18
+ - Authentication integration (via `@apiquest/plugin-auth`)
19
+ - Timeout configuration
20
+
21
+ ## Usage
22
+
23
+ Set the collection protocol to `sse`:
24
+
25
+ ```json
26
+ {
27
+ "$schema": "https://apiquest.net/schemas/collection-v1.0.json",
28
+ "protocol": "sse",
29
+ "items": [
30
+ {
31
+ "type": "request",
32
+ "id": "stream-events",
33
+ "name": "Stream Server Events",
34
+ "data": {
35
+ "url": "https://api.example.com/events",
36
+ "timeout": 30000,
37
+ "scripts": [
38
+ {
39
+ "event": "onMessage",
40
+ "script": "quest.test('Message received', () => {\n const msg = quest.message;\n expect(msg.data).to.be.a('string');\n});"
41
+ },
42
+ {
43
+ "event": "onComplete",
44
+ "script": "quest.test('Stream completed', () => {\n expect(quest.messages.length).to.be.greaterThan(0);\n});"
45
+ }
46
+ ]
47
+ }
48
+ }
49
+ ]
50
+ }
51
+ ```
52
+
53
+ ### With Custom Headers
54
+
55
+ ```json
56
+ {
57
+ "data": {
58
+ "url": "https://api.example.com/stream",
59
+ "headers": {
60
+ "Accept": "text/event-stream",
61
+ "x-stream-id": "{{streamId}}"
62
+ },
63
+ "timeout": 60000
64
+ }
65
+ }
66
+ ```
67
+
68
+ ### Event Scripts
69
+
70
+ SSE requests support event-based scripts:
71
+
72
+ - **onMessage** - Runs for each received message
73
+ - **onError** - Runs when an error occurs
74
+ - **onComplete** - Runs when the stream completes
75
+
76
+ ```json
77
+ {
78
+ "data": {
79
+ "scripts": [
80
+ {
81
+ "event": "onMessage",
82
+ "script": "const data = JSON.parse(quest.message.data);\nquest.variables.set('lastEventId', data.id);\n\nquest.test('Valid event data', () => {\n expect(data).to.have.property('timestamp');\n});"
83
+ },
84
+ {
85
+ "event": "onError",
86
+ "script": "console.error('Stream error:', quest.error);"
87
+ },
88
+ {
89
+ "event": "onComplete",
90
+ "script": "quest.test('Received messages', () => {\n expect(quest.messages.length).to.equal(10);\n});"
91
+ }
92
+ ]
93
+ }
94
+ }
95
+ ```
96
+
97
+ ### Message Counting
98
+
99
+ Use `quest.expectMessages()` in the preRequestScript to enable deterministic test counting:
100
+
101
+ ```json
102
+ {
103
+ "type": "request",
104
+ "id": "stream-events",
105
+ "name": "Stream Server Events",
106
+ "preRequestScript": "quest.expectMessages(5, 10000);",
107
+ "data": {
108
+ "url": "https://api.example.com/events",
109
+ "scripts": [
110
+ {
111
+ "event": "onMessage",
112
+ "script": "quest.test('Message received', () => {\n expect(quest.message.data).to.exist;\n});"
113
+ }
114
+ ]
115
+ }
116
+ }
117
+ ```
118
+
119
+ This informs the runner to expect 5 messages, enabling accurate test count reporting (5 messages × tests per message).
120
+
121
+ ## Response Handling
122
+
123
+ Access SSE data in scripts:
124
+
125
+ ```javascript
126
+ // In onMessage script
127
+ quest.test('Event has data', () => {
128
+ expect(quest.message.data).to.be.a('string');
129
+ });
130
+
131
+ quest.test('Event type is update', () => {
132
+ expect(quest.message.event).to.equal('update');
133
+ });
134
+
135
+ // In onComplete script
136
+ quest.test('Received all messages', () => {
137
+ expect(quest.messages.length).to.equal(5);
138
+ });
139
+
140
+ quest.test('All messages valid', () => {
141
+ quest.messages.forEach(msg => {
142
+ const data = JSON.parse(msg.data);
143
+ expect(data).to.have.property('id');
144
+ });
145
+ });
146
+ ```
147
+
148
+ ## Compatibility
149
+
150
+ - **Authentication:** Works with `@apiquest/plugin-auth` for Bearer, Basic, API Key
151
+ - **Node.js:** Requires Node.js 20+
152
+
153
+ ## Documentation
154
+
155
+ - [Fracture Documentation](https://apiquest.net/docs/fracture)
156
+ - [Schema Reference](https://apiquest.net/schemas/collection-v1.0.json)
157
+
158
+ ## License
159
+
160
+ Dual-licensed under AGPL-3.0-or-later and commercial license. See LICENSE.txt for details.
@@ -0,0 +1,4 @@
1
+ import type { IProtocolPlugin } from '@apiquest/types';
2
+ export declare const ssePlugin: IProtocolPlugin;
3
+ export default ssePlugin;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAA2G,MAAM,iBAAiB,CAAC;AAkBhK,eAAO,MAAM,SAAS,EAAE,eA8WvB,CAAC;AAEF,eAAe,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,341 @@
1
+ // Helper functions for string validation
2
+ function isNullOrWhitespace(value) {
3
+ return value === null || value === undefined || value.trim() === '';
4
+ }
5
+ const ssePlugin = {
6
+ name: 'SSE Client',
7
+ version: '1.0.0',
8
+ description: 'Server-Sent Events (SSE) protocol support',
9
+ // What protocols this plugin provides
10
+ protocols: ['sse'],
11
+ // Supported authentication types
12
+ supportedAuthTypes: ['bearer', 'basic', 'apikey', 'none'],
13
+ // Accept additional auth plugins beyond the listed types
14
+ strictAuthList: false,
15
+ // Data schema for SSE requests
16
+ dataSchema: {
17
+ type: 'object',
18
+ required: ['url'],
19
+ properties: {
20
+ url: {
21
+ type: 'string',
22
+ description: 'SSE endpoint URL'
23
+ },
24
+ timeout: {
25
+ type: 'number',
26
+ description: 'Connection timeout in milliseconds',
27
+ default: 30000
28
+ },
29
+ headers: {
30
+ type: 'object',
31
+ description: 'HTTP headers',
32
+ additionalProperties: { type: 'string' }
33
+ }
34
+ }
35
+ },
36
+ // Options schema for runtime configuration
37
+ optionsSchema: {
38
+ timeout: {
39
+ type: 'number',
40
+ default: 30000,
41
+ description: 'Request timeout in milliseconds'
42
+ }
43
+ },
44
+ // Plugin events
45
+ events: [
46
+ {
47
+ name: 'onMessage',
48
+ description: 'Fired when an SSE message is received',
49
+ canHaveTests: true,
50
+ required: false
51
+ },
52
+ {
53
+ name: 'onError',
54
+ description: 'Fired when an error occurs during streaming',
55
+ canHaveTests: false,
56
+ required: false
57
+ },
58
+ {
59
+ name: 'onComplete',
60
+ description: 'Fired when the SSE stream completes',
61
+ canHaveTests: true,
62
+ required: false
63
+ }
64
+ ],
65
+ async execute(request, context, options, emitEvent, logger) {
66
+ const startTime = Date.now();
67
+ const url = String(request.data.url ?? '');
68
+ if (isNullOrWhitespace(url)) {
69
+ logger?.error('SSE request missing URL');
70
+ throw new Error('URL is required for SSE requests');
71
+ }
72
+ const headers = typeof request.data.headers === 'object' && request.data.headers !== null
73
+ ? Object.fromEntries(Object.entries(request.data.headers).map(([k, v]) => [k, String(v)]))
74
+ : {};
75
+ const sseOptions = options.plugins?.sse ?? {};
76
+ const sseTimeout = typeof sseOptions.timeout === 'number' ? sseOptions.timeout : null;
77
+ const timeout = (typeof request.data.timeout === 'number' ? request.data.timeout : null) ?? options.timeout?.request ?? sseTimeout ?? 30000;
78
+ logger?.debug('SSE request starting', { url, timeout });
79
+ const messages = [];
80
+ let messageCount = 0;
81
+ return new Promise((resolve, reject) => {
82
+ const controller = new AbortController();
83
+ const timeoutId = setTimeout(() => {
84
+ controller.abort();
85
+ logger?.debug('SSE connection timeout', { url, messageCount, duration: Date.now() - startTime });
86
+ resolve({
87
+ status: 200,
88
+ statusText: 'Stream Complete (Timeout)',
89
+ body: JSON.stringify({ messages, count: messageCount }),
90
+ headers: {},
91
+ duration: Date.now() - startTime,
92
+ messageCount,
93
+ messages
94
+ });
95
+ }, timeout);
96
+ try {
97
+ // Use fetch with streaming which is more universally supported in Node.js
98
+ const signal = context.abortSignal || controller.signal;
99
+ // Handle abort signal
100
+ if (context.abortSignal) {
101
+ context.abortSignal.addEventListener('abort', () => {
102
+ controller.abort();
103
+ clearTimeout(timeoutId);
104
+ logger?.debug('SSE request aborted', { url, messageCount, duration: Date.now() - startTime });
105
+ resolve({
106
+ status: 0,
107
+ statusText: 'Aborted',
108
+ body: JSON.stringify({ messages, count: messageCount }),
109
+ headers: {},
110
+ duration: Date.now() - startTime,
111
+ error: 'Request aborted',
112
+ messageCount,
113
+ messages
114
+ });
115
+ });
116
+ }
117
+ // Use fetch with streaming
118
+ fetch(url, {
119
+ method: 'GET',
120
+ headers: {
121
+ ...headers,
122
+ 'Accept': 'text/event-stream',
123
+ 'Cache-Control': 'no-cache'
124
+ },
125
+ signal
126
+ }).then(async (response) => {
127
+ if (!response.ok) {
128
+ clearTimeout(timeoutId);
129
+ logger?.warn('SSE connection failed', { status: response.status, statusText: response.statusText });
130
+ resolve({
131
+ status: response.status,
132
+ statusText: response.statusText,
133
+ body: await response.text(),
134
+ headers: Object.fromEntries(response.headers.entries()),
135
+ duration: Date.now() - startTime,
136
+ messageCount: 0,
137
+ messages: []
138
+ });
139
+ return;
140
+ }
141
+ if (!response.body) {
142
+ clearTimeout(timeoutId);
143
+ logger?.error('SSE response has no body');
144
+ resolve({
145
+ status: response.status,
146
+ statusText: 'No Body',
147
+ body: '',
148
+ headers: Object.fromEntries(response.headers.entries()),
149
+ duration: Date.now() - startTime,
150
+ messageCount: 0,
151
+ messages: []
152
+ });
153
+ return;
154
+ }
155
+ const reader = response.body.getReader();
156
+ const decoder = new TextDecoder();
157
+ let buffer = '';
158
+ const processLine = async (line) => {
159
+ if (line.startsWith('data:')) {
160
+ const data = line.slice(5).trim();
161
+ const message = { data };
162
+ messages.push(message);
163
+ messageCount++;
164
+ logger?.trace('SSE message received', { messageCount, data: data.slice(0, 100) });
165
+ // Emit onMessage event
166
+ if (emitEvent) {
167
+ try {
168
+ await emitEvent('onMessage', {
169
+ index: messageCount,
170
+ data: message
171
+ });
172
+ }
173
+ catch (err) {
174
+ logger?.error('SSE onMessage event error', { error: err instanceof Error ? err.message : String(err) });
175
+ }
176
+ }
177
+ }
178
+ else if (line.startsWith('event:')) {
179
+ const lastMessage = messages[messages.length - 1];
180
+ if (lastMessage) {
181
+ lastMessage.event = line.slice(6).trim();
182
+ }
183
+ }
184
+ else if (line.startsWith('id:')) {
185
+ const lastMessage = messages[messages.length - 1];
186
+ if (lastMessage) {
187
+ lastMessage.id = line.slice(3).trim();
188
+ }
189
+ }
190
+ else if (line.startsWith('retry:')) {
191
+ const lastMessage = messages[messages.length - 1];
192
+ if (lastMessage) {
193
+ lastMessage.retry = parseInt(line.slice(6).trim(), 10);
194
+ }
195
+ }
196
+ };
197
+ try {
198
+ while (true) {
199
+ const { done, value } = await reader.read();
200
+ if (done) {
201
+ // Process remaining buffer
202
+ if (buffer.trim()) {
203
+ const lines = buffer.split('\n');
204
+ for (const line of lines) {
205
+ if (line.trim()) {
206
+ await processLine(line);
207
+ }
208
+ }
209
+ }
210
+ clearTimeout(timeoutId);
211
+ logger?.debug('SSE stream complete', { messageCount, duration: Date.now() - startTime });
212
+ // Emit onComplete event
213
+ if (emitEvent) {
214
+ try {
215
+ await emitEvent('onComplete', { messageCount, messages });
216
+ }
217
+ catch (err) {
218
+ logger?.error('SSE onComplete event error', { error: err instanceof Error ? err.message : String(err) });
219
+ }
220
+ }
221
+ resolve({
222
+ status: response.status,
223
+ statusText: 'Stream Complete',
224
+ body: JSON.stringify({ messages, count: messageCount }),
225
+ headers: Object.fromEntries(response.headers.entries()),
226
+ duration: Date.now() - startTime,
227
+ messageCount,
228
+ messages
229
+ });
230
+ break;
231
+ }
232
+ // Decode chunk and add to buffer
233
+ buffer += decoder.decode(value, { stream: true });
234
+ // Process complete lines
235
+ const lines = buffer.split('\n');
236
+ buffer = lines.pop() || ''; // Keep incomplete line in buffer
237
+ for (const line of lines) {
238
+ if (line.trim()) {
239
+ await processLine(line);
240
+ }
241
+ }
242
+ }
243
+ }
244
+ catch (err) {
245
+ clearTimeout(timeoutId);
246
+ // Check if it was aborted
247
+ if (signal.aborted) {
248
+ logger?.debug('SSE stream aborted', { messageCount, duration: Date.now() - startTime });
249
+ resolve({
250
+ status: 0,
251
+ statusText: 'Aborted',
252
+ body: JSON.stringify({ messages, count: messageCount }),
253
+ headers: {},
254
+ duration: Date.now() - startTime,
255
+ error: 'Request aborted',
256
+ messageCount,
257
+ messages
258
+ });
259
+ }
260
+ else {
261
+ logger?.error('SSE stream error', { error: err instanceof Error ? err.message : String(err) });
262
+ // Emit onError event
263
+ if (emitEvent) {
264
+ try {
265
+ await emitEvent('onError', { error: err instanceof Error ? err.message : String(err) });
266
+ }
267
+ catch (emitErr) {
268
+ logger?.error('SSE onError event error', { error: emitErr instanceof Error ? emitErr.message : String(emitErr) });
269
+ }
270
+ }
271
+ resolve({
272
+ status: 0,
273
+ statusText: 'Stream Error',
274
+ body: JSON.stringify({ messages, count: messageCount }),
275
+ headers: {},
276
+ duration: Date.now() - startTime,
277
+ error: err instanceof Error ? err.message : String(err),
278
+ messageCount,
279
+ messages
280
+ });
281
+ }
282
+ }
283
+ }).catch((err) => {
284
+ clearTimeout(timeoutId);
285
+ logger?.error('SSE fetch error', { error: err instanceof Error ? err.message : String(err) });
286
+ // Emit onError event
287
+ if (emitEvent) {
288
+ emitEvent('onError', { error: err instanceof Error ? err.message : String(err) }).catch((emitErr) => {
289
+ logger?.error('SSE onError event error', { error: emitErr instanceof Error ? emitErr.message : String(emitErr) });
290
+ });
291
+ }
292
+ resolve({
293
+ status: 0,
294
+ statusText: 'Connection Error',
295
+ body: '',
296
+ headers: {},
297
+ duration: Date.now() - startTime,
298
+ error: err instanceof Error ? err.message : String(err),
299
+ messageCount: 0,
300
+ messages: []
301
+ });
302
+ });
303
+ }
304
+ catch (err) {
305
+ clearTimeout(timeoutId);
306
+ logger?.error('SSE unexpected error', { error: err instanceof Error ? err.message : String(err) });
307
+ resolve({
308
+ status: 0,
309
+ statusText: 'Error',
310
+ body: '',
311
+ headers: {},
312
+ duration: Date.now() - startTime,
313
+ error: err instanceof Error ? err.message : String(err),
314
+ messageCount: 0,
315
+ messages: []
316
+ });
317
+ }
318
+ });
319
+ },
320
+ validate(request, options) {
321
+ const errors = [];
322
+ // Check URL
323
+ if (typeof request.data.url !== 'string' || isNullOrWhitespace(request.data.url)) {
324
+ errors.push({
325
+ message: 'URL is required',
326
+ location: '',
327
+ source: 'protocol'
328
+ });
329
+ }
330
+ if (errors.length > 0) {
331
+ return {
332
+ valid: false,
333
+ errors
334
+ };
335
+ }
336
+ return { valid: true };
337
+ }
338
+ };
339
+
340
+ export { ssePlugin as default, ssePlugin };
341
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { IProtocolPlugin } from '@apiquest/types';
2
+ export declare const httpPlugin: IProtocolPlugin;
3
+ export default httpPlugin;
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAA2G,MAAM,iBAAiB,CAAC;AAmBhK,eAAO,MAAM,UAAU,EAAE,eAmRxB,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -0,0 +1,34 @@
1
+ import esbuild from 'esbuild';
2
+
3
+ await esbuild.build({
4
+ entryPoints: ['src/index.ts'],
5
+ bundle: true,
6
+ outfile: 'dist/index.js',
7
+ format: 'esm',
8
+ platform: 'node',
9
+ target: 'node18',
10
+ // Externalize peerDependencies and Node.js built-ins
11
+ external: [
12
+ '@apiquest/fracture',
13
+ // Node.js built-in modules (got depends on these)
14
+ 'http',
15
+ 'https',
16
+ 'http2',
17
+ 'net',
18
+ 'tls',
19
+ 'stream',
20
+ 'util',
21
+ 'url',
22
+ 'zlib',
23
+ 'events',
24
+ 'buffer',
25
+ 'querystring',
26
+ 'dns',
27
+ 'fs',
28
+ 'path',
29
+ ],
30
+ minify: false,
31
+ sourcemap: true,
32
+ });
33
+
34
+ console.log('✓ Built plugin-sse');
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@apiquest/plugin-sse",
3
+ "version": "1.0.2",
4
+ "description": "SSE protocol plugin for Quest",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "type": "module",
8
+ "scripts": {
9
+ "build": "rollup -c && tsc --emitDeclarationOnly",
10
+ "dev": "rollup -c --watch",
11
+ "test": "vitest"
12
+ },
13
+ "keywords": [
14
+ "api",
15
+ "http",
16
+ "quest",
17
+ "plugin"
18
+ ],
19
+ "author": "ApiQuest",
20
+ "license": "AGPL-3.0-or-later",
21
+ "dependencies": {
22
+ "got": "^14.6.6",
23
+ "hpagent": "^1.2.0"
24
+ },
25
+ "devDependencies": {
26
+ "@apiquest/types": "workspace:*",
27
+ "@rollup/plugin-commonjs": "^25.0.0",
28
+ "@rollup/plugin-node-resolve": "^15.0.0",
29
+ "@rollup/plugin-typescript": "^11.0.0",
30
+ "@types/node": "^20.10.6",
31
+ "rollup": "^4.0.0",
32
+ "typescript": "^5.3.3",
33
+ "vitest": "^4.0.18"
34
+ },
35
+ "peerDependencies": {
36
+ "@apiquest/types": "^1.0.0"
37
+ },
38
+ "apiquest": {
39
+ "type": "protocol",
40
+ "runtime": [
41
+ "fracture"
42
+ ],
43
+ "capabilities": {
44
+ "provides": {
45
+ "protocols": [
46
+ "sse"
47
+ ]
48
+ },
49
+ "supports": {
50
+ "authTypes": [
51
+ "bearer",
52
+ "basic",
53
+ "oauth2",
54
+ "apikey",
55
+ "digest",
56
+ "ntlm"
57
+ ],
58
+ "strictAuthList": false
59
+ }
60
+ }
61
+ }
62
+ }
@@ -0,0 +1,31 @@
1
+ import typescript from '@rollup/plugin-typescript';
2
+ import resolve from '@rollup/plugin-node-resolve';
3
+ import commonjs from '@rollup/plugin-commonjs';
4
+
5
+ export default {
6
+ input: 'src/index.ts',
7
+ output: {
8
+ file: 'dist/index.js',
9
+ format: 'esm',
10
+ sourcemap: true,
11
+ },
12
+ external: [
13
+ // Externalize peer dependencies
14
+ '@apiquest/fracture',
15
+ ],
16
+ plugins: [
17
+ // Resolve node modules
18
+ resolve({
19
+ preferBuiltins: true, // Prefer Node.js built-in modules
20
+ exportConditions: ['node', 'import', 'default'],
21
+ }),
22
+ // Convert CommonJS to ESM (for any CJS dependencies)
23
+ commonjs(),
24
+ // Compile TypeScript
25
+ typescript({
26
+ tsconfig: './tsconfig.json',
27
+ sourceMap: true,
28
+ declaration: false, // We'll use tsc for declarations
29
+ }),
30
+ ],
31
+ };