@slates/proto 1.0.0-rc.6 → 1.0.0-rc.7
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/index.cjs +1076 -2
- package/dist/index.d.cts +3429 -0
- package/dist/index.d.ts +3429 -4
- package/dist/index.module.js +970 -2
- package/package.json +8 -7
- package/src/handler/provider.test.ts +118 -0
- package/src/handler/provider.ts +262 -27
- package/src/index.ts +1 -0
- package/src/messages/action.ts +7 -6
- package/src/messages/auth.ts +10 -8
- package/src/messages/config.ts +3 -2
- package/src/messages/controlFlow.ts +2 -1
- package/src/messages/identify.ts +2 -1
- package/src/messages/index.ts +13 -12
- package/src/messages/tracing.ts +38 -0
- package/src/types/action.ts +11 -1
- package/src/version.ts +3 -0
- package/dist/handler/index.d.ts +0 -2
- package/dist/handler/index.d.ts.map +0 -1
- package/dist/handler/provider.d.ts +0 -29
- package/dist/handler/provider.d.ts.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.module.js.map +0 -1
- package/dist/index.umd.js +0 -2
- package/dist/index.umd.js.map +0 -1
- package/dist/messages/action.d.ts +0 -474
- package/dist/messages/action.d.ts.map +0 -1
- package/dist/messages/auth.d.ts +0 -500
- package/dist/messages/auth.d.ts.map +0 -1
- package/dist/messages/config.d.ts +0 -140
- package/dist/messages/config.d.ts.map +0 -1
- package/dist/messages/controlFlow.d.ts +0 -64
- package/dist/messages/controlFlow.d.ts.map +0 -1
- package/dist/messages/identify.d.ts +0 -50
- package/dist/messages/identify.d.ts.map +0 -1
- package/dist/messages/index.d.ts +0 -560
- package/dist/messages/index.d.ts.map +0 -1
- package/dist/messages/log.d.ts +0 -27
- package/dist/messages/log.d.ts.map +0 -1
- package/dist/types/action.d.ts +0 -98
- package/dist/types/action.d.ts.map +0 -1
- package/dist/types/authMethod.d.ts +0 -29
- package/dist/types/authMethod.d.ts.map +0 -1
- package/dist/types/index.d.ts +0 -4
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/participant.d.ts +0 -10
- package/dist/types/participant.d.ts.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slates/proto",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.7",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"package.json"
|
|
12
12
|
],
|
|
13
13
|
"author": "Tobias Herber",
|
|
14
|
-
"license": "
|
|
14
|
+
"license": "FSL 1.1",
|
|
15
15
|
"type": "module",
|
|
16
16
|
"source": "src/index.ts",
|
|
17
17
|
"exports": {
|
|
@@ -23,23 +23,24 @@
|
|
|
23
23
|
"main": "./dist/index.cjs",
|
|
24
24
|
"module": "./dist/index.module.js",
|
|
25
25
|
"types": "dist/index.d.ts",
|
|
26
|
-
"unpkg": "./dist/index.
|
|
26
|
+
"unpkg": "./dist/index.module.js",
|
|
27
27
|
"scripts": {
|
|
28
28
|
"test": "vitest run --passWithNoTests",
|
|
29
29
|
"lint": "prettier src/**/*.ts --check",
|
|
30
|
-
"build": "
|
|
30
|
+
"build": "tsup --config ../../tsup.packages.config.ts",
|
|
31
|
+
"typecheck": "tsc --noEmit"
|
|
31
32
|
},
|
|
32
33
|
"dependencies": {
|
|
33
34
|
"@lowerdeck/emitter": "^1.0.4",
|
|
34
|
-
"@lowerdeck/error": "^1.0
|
|
35
|
+
"@lowerdeck/error": "^1.1.0",
|
|
35
36
|
"@toon-format/toon": "^2.1.0",
|
|
36
37
|
"axios": "^1.13.2",
|
|
37
38
|
"zod": "^4.2.1"
|
|
38
39
|
},
|
|
39
40
|
"devDependencies": {
|
|
40
41
|
"microbundle": "^0.15.1",
|
|
41
|
-
"@slates/tsconfig": "
|
|
42
|
+
"@slates/tsconfig": "1.0.0-rc.1",
|
|
42
43
|
"typescript": "5.8.2",
|
|
43
44
|
"vitest": "^3.1.2"
|
|
44
45
|
}
|
|
45
|
-
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { ServiceError, badRequestError } from '@lowerdeck/error';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import { SlateError } from '../../../provider/src/error/base';
|
|
4
|
+
import { createSlatesProviderProtoHandler, SlatesProviderProtoHandlerManager } from './provider';
|
|
5
|
+
|
|
6
|
+
describe('SlatesProviderProtoHandlerManager', () => {
|
|
7
|
+
it('serializes SlateError instances directly into JSON-RPC errors', async () => {
|
|
8
|
+
let manager = await createSlatesProviderProtoHandler(async manager => {
|
|
9
|
+
manager.onRequest('slates/provider.identify', async () => {
|
|
10
|
+
throw new SlateError({
|
|
11
|
+
code: 'upstream.rate_limited',
|
|
12
|
+
kind: 'upstream',
|
|
13
|
+
message: 'GitHub rate limit exceeded',
|
|
14
|
+
retryable: true,
|
|
15
|
+
upstream: {
|
|
16
|
+
status: 429,
|
|
17
|
+
code: 'rate_limited'
|
|
18
|
+
},
|
|
19
|
+
baggage: {
|
|
20
|
+
scope: 'issues'
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
}).run();
|
|
25
|
+
|
|
26
|
+
let response = await SlatesProviderProtoHandlerManager.handleInput(manager, {
|
|
27
|
+
jsonrpc: '2.0',
|
|
28
|
+
id: 'req_1',
|
|
29
|
+
method: 'slates/provider.identify',
|
|
30
|
+
params: {}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
expect(response).toEqual({
|
|
34
|
+
jsonrpc: '2.0',
|
|
35
|
+
id: 'req_1',
|
|
36
|
+
error: {
|
|
37
|
+
code: 'upstream.rate_limited',
|
|
38
|
+
kind: 'upstream',
|
|
39
|
+
message: 'GitHub rate limit exceeded',
|
|
40
|
+
retryable: true,
|
|
41
|
+
status: 429,
|
|
42
|
+
upstream: {
|
|
43
|
+
status: 429,
|
|
44
|
+
code: 'rate_limited'
|
|
45
|
+
},
|
|
46
|
+
baggage: {
|
|
47
|
+
scope: 'issues'
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('maps ServiceError instances to SlateError protocol responses', async () => {
|
|
54
|
+
let manager = await createSlatesProviderProtoHandler(async manager => {
|
|
55
|
+
manager.onRequest('slates/provider.identify', async () => {
|
|
56
|
+
throw new ServiceError(
|
|
57
|
+
badRequestError({
|
|
58
|
+
message: 'Invalid provider state'
|
|
59
|
+
})
|
|
60
|
+
);
|
|
61
|
+
});
|
|
62
|
+
}).run();
|
|
63
|
+
|
|
64
|
+
let response = await SlatesProviderProtoHandlerManager.handleInput(manager, {
|
|
65
|
+
jsonrpc: '2.0',
|
|
66
|
+
id: 'req_2',
|
|
67
|
+
method: 'slates/provider.identify',
|
|
68
|
+
params: {}
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
expect(response).toEqual({
|
|
72
|
+
jsonrpc: '2.0',
|
|
73
|
+
id: 'req_2',
|
|
74
|
+
error: {
|
|
75
|
+
code: 'request.bad',
|
|
76
|
+
kind: 'request',
|
|
77
|
+
message: 'Invalid provider state',
|
|
78
|
+
retryable: false,
|
|
79
|
+
status: 400,
|
|
80
|
+
baggage: {
|
|
81
|
+
serviceError: {
|
|
82
|
+
code: 'bad_request',
|
|
83
|
+
status: 400
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('returns slate errors for protocol validation failures', async () => {
|
|
91
|
+
let manager = await createSlatesProviderProtoHandler(async () => {}).run();
|
|
92
|
+
|
|
93
|
+
let response = await SlatesProviderProtoHandlerManager.handleInput(manager, {
|
|
94
|
+
jsonrpc: '1.0',
|
|
95
|
+
id: 'req_3',
|
|
96
|
+
method: 'slates/provider.identify',
|
|
97
|
+
params: {}
|
|
98
|
+
} as any);
|
|
99
|
+
|
|
100
|
+
expect(response).toEqual({
|
|
101
|
+
jsonrpc: '2.0',
|
|
102
|
+
id: 'req_3',
|
|
103
|
+
error: {
|
|
104
|
+
code: 'request.bad',
|
|
105
|
+
kind: 'request',
|
|
106
|
+
message: 'Invalid jsonrpc version',
|
|
107
|
+
retryable: false,
|
|
108
|
+
status: 400,
|
|
109
|
+
baggage: {
|
|
110
|
+
serviceError: {
|
|
111
|
+
code: 'bad_request',
|
|
112
|
+
status: 400
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
});
|
package/src/handler/provider.ts
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
badRequestError,
|
|
3
|
-
internalServerError,
|
|
4
3
|
isServiceError,
|
|
5
4
|
notFoundError,
|
|
6
5
|
validationError
|
|
7
6
|
} from '@lowerdeck/error';
|
|
8
|
-
import z from 'zod';
|
|
7
|
+
import type z from 'zod';
|
|
9
8
|
import {
|
|
10
|
-
SlatesNotifications,
|
|
9
|
+
type SlatesNotifications,
|
|
10
|
+
type SlatesRequests,
|
|
11
|
+
type SlatesResponsesByMethod,
|
|
11
12
|
slatesNotificationsByMethod,
|
|
12
|
-
|
|
13
|
-
slatesRequestsByMethod,
|
|
14
|
-
SlatesResponsesByMethod
|
|
13
|
+
slatesRequestsByMethod
|
|
15
14
|
} from '../messages';
|
|
16
15
|
|
|
17
16
|
export class SlatesProviderProtoHandlerManager {
|
|
@@ -64,7 +63,7 @@ export class SlatesProviderProtoHandlerManager {
|
|
|
64
63
|
return {
|
|
65
64
|
jsonrpc: '2.0' as const,
|
|
66
65
|
id: (input as any).id,
|
|
67
|
-
error: badRequestError({ message: 'Invalid input' })
|
|
66
|
+
error: toSlateErrorResponse(badRequestError({ message: 'Invalid input' }))
|
|
68
67
|
};
|
|
69
68
|
}
|
|
70
69
|
|
|
@@ -72,7 +71,7 @@ export class SlatesProviderProtoHandlerManager {
|
|
|
72
71
|
return {
|
|
73
72
|
jsonrpc: '2.0' as const,
|
|
74
73
|
id: (input as any).id,
|
|
75
|
-
error: badRequestError({ message: 'Invalid jsonrpc version' })
|
|
74
|
+
error: toSlateErrorResponse(badRequestError({ message: 'Invalid jsonrpc version' }))
|
|
76
75
|
};
|
|
77
76
|
}
|
|
78
77
|
|
|
@@ -81,7 +80,7 @@ export class SlatesProviderProtoHandlerManager {
|
|
|
81
80
|
return {
|
|
82
81
|
jsonrpc: '2.0' as const,
|
|
83
82
|
id: (input as any).id,
|
|
84
|
-
error: badRequestError({ message: 'Invalid or missing method' })
|
|
83
|
+
error: toSlateErrorResponse(badRequestError({ message: 'Invalid or missing method' }))
|
|
85
84
|
};
|
|
86
85
|
}
|
|
87
86
|
|
|
@@ -90,7 +89,7 @@ export class SlatesProviderProtoHandlerManager {
|
|
|
90
89
|
return {
|
|
91
90
|
jsonrpc: '2.0' as const,
|
|
92
91
|
id: (input as any).id,
|
|
93
|
-
error: notFoundError('handler', input.method)
|
|
92
|
+
error: toSlateErrorResponse(notFoundError('handler', input.method))
|
|
94
93
|
};
|
|
95
94
|
}
|
|
96
95
|
|
|
@@ -99,14 +98,16 @@ export class SlatesProviderProtoHandlerManager {
|
|
|
99
98
|
return {
|
|
100
99
|
jsonrpc: '2.0' as const,
|
|
101
100
|
id: (input as any).id,
|
|
102
|
-
error:
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
101
|
+
error: toSlateErrorResponse(
|
|
102
|
+
validationError({
|
|
103
|
+
entity: 'request',
|
|
104
|
+
message: 'Invalid request parameters',
|
|
105
|
+
errors: parsed.error.issues.map(i => ({
|
|
106
|
+
...i,
|
|
107
|
+
path: i.path.map(p => String(p))
|
|
108
|
+
}))
|
|
109
|
+
})
|
|
110
|
+
)
|
|
110
111
|
};
|
|
111
112
|
}
|
|
112
113
|
|
|
@@ -123,20 +124,16 @@ export class SlatesProviderProtoHandlerManager {
|
|
|
123
124
|
result
|
|
124
125
|
};
|
|
125
126
|
} catch (err) {
|
|
126
|
-
if (
|
|
127
|
-
|
|
128
|
-
jsonrpc: '2.0' as const,
|
|
129
|
-
id: (input as any).id,
|
|
130
|
-
error: err.toResponse()
|
|
131
|
-
};
|
|
127
|
+
if (!getSlateErrorResponse(err) && !getServiceErrorData(err)) {
|
|
128
|
+
console.error(err);
|
|
132
129
|
}
|
|
133
130
|
|
|
134
|
-
console.error(err);
|
|
135
|
-
|
|
136
131
|
return {
|
|
137
132
|
jsonrpc: '2.0' as const,
|
|
138
133
|
id: (input as any).id,
|
|
139
|
-
error:
|
|
134
|
+
error: toSlateErrorResponse(err, {
|
|
135
|
+
message: 'Internal server error'
|
|
136
|
+
})
|
|
140
137
|
};
|
|
141
138
|
}
|
|
142
139
|
}
|
|
@@ -160,3 +157,241 @@ export let createSlatesProviderProtoHandler = (
|
|
|
160
157
|
return manager;
|
|
161
158
|
}
|
|
162
159
|
});
|
|
160
|
+
|
|
161
|
+
let toSlateErrorResponse = (
|
|
162
|
+
error: unknown,
|
|
163
|
+
defaults: Partial<{ code: string; message: string }> = {}
|
|
164
|
+
) => {
|
|
165
|
+
let slateError = getSlateErrorResponse(error);
|
|
166
|
+
if (slateError) return slateError;
|
|
167
|
+
|
|
168
|
+
let serviceError = getServiceErrorData(error);
|
|
169
|
+
if (serviceError) {
|
|
170
|
+
return mapServiceErrorToSlateErrorResponse(serviceError, defaults);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return mapUnknownErrorToSlateErrorResponse(error, defaults);
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
let SERVICE_ERROR_CODE_MAP: Record<string, string> = {
|
|
177
|
+
invalid_data: 'input.invalid',
|
|
178
|
+
bad_request: 'request.bad',
|
|
179
|
+
not_found: 'resource.not_found',
|
|
180
|
+
unauthorized: 'auth.required',
|
|
181
|
+
forbidden: 'permission.denied',
|
|
182
|
+
invalid_version: 'request.invalid_version',
|
|
183
|
+
conflict: 'resource.conflict',
|
|
184
|
+
gone: 'resource.gone',
|
|
185
|
+
payment_required: 'payment.required',
|
|
186
|
+
precondition_failed: 'request.precondition_failed',
|
|
187
|
+
not_acceptable: 'request.not_acceptable',
|
|
188
|
+
not_implemented: 'operation.not_implemented',
|
|
189
|
+
too_many_requests: 'request.rate_limited',
|
|
190
|
+
timeout: 'internal.timeout',
|
|
191
|
+
internal_server_error: 'internal.unexpected'
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
let isRecord = (value: unknown): value is Record<string, unknown> =>
|
|
195
|
+
typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
196
|
+
|
|
197
|
+
let isStructuredValue = (value: unknown): value is Record<string, unknown> | Function =>
|
|
198
|
+
(typeof value === 'object' || typeof value === 'function') && value !== null;
|
|
199
|
+
|
|
200
|
+
let isSlateErrorPayload = (
|
|
201
|
+
value: unknown
|
|
202
|
+
): value is { code: string; message: string; kind?: string; [key: string]: unknown } =>
|
|
203
|
+
isRecord(value) &&
|
|
204
|
+
typeof value.code === 'string' &&
|
|
205
|
+
typeof value.message === 'string' &&
|
|
206
|
+
typeof value.kind === 'string';
|
|
207
|
+
|
|
208
|
+
let isServiceErrorData = (
|
|
209
|
+
value: unknown
|
|
210
|
+
): value is {
|
|
211
|
+
status: number;
|
|
212
|
+
code: string;
|
|
213
|
+
message: string;
|
|
214
|
+
errors?: unknown;
|
|
215
|
+
hint?: string;
|
|
216
|
+
description?: string;
|
|
217
|
+
reason?: string;
|
|
218
|
+
[key: string]: unknown;
|
|
219
|
+
} =>
|
|
220
|
+
isRecord(value) &&
|
|
221
|
+
typeof value.status === 'number' &&
|
|
222
|
+
typeof value.code === 'string' &&
|
|
223
|
+
typeof value.message === 'string' &&
|
|
224
|
+
!('config' in value) &&
|
|
225
|
+
!('request' in value) &&
|
|
226
|
+
!('response' in value) &&
|
|
227
|
+
!('isAxiosError' in value);
|
|
228
|
+
|
|
229
|
+
let getSlateErrorResponse = (error: unknown) => {
|
|
230
|
+
if (
|
|
231
|
+
isStructuredValue(error) &&
|
|
232
|
+
'name' in error &&
|
|
233
|
+
typeof error.name === 'string' &&
|
|
234
|
+
error.name.startsWith('SlateError') &&
|
|
235
|
+
'toResponse' in error &&
|
|
236
|
+
typeof error.toResponse === 'function'
|
|
237
|
+
) {
|
|
238
|
+
let response = error.toResponse();
|
|
239
|
+
return isSlateErrorPayload(response) ? response : null;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
if (isSlateErrorPayload(error)) return error;
|
|
243
|
+
|
|
244
|
+
if (isStructuredValue(error) && 'data' in error && isSlateErrorPayload(error.data)) {
|
|
245
|
+
return error.data;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return null;
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
let getServiceErrorData = (error: unknown) => {
|
|
252
|
+
if (isServiceError(error) && isServiceErrorData(error.data)) {
|
|
253
|
+
return error.data;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (isServiceErrorData(error)) return error;
|
|
257
|
+
|
|
258
|
+
if (isStructuredValue(error) && 'data' in error && isServiceErrorData(error.data)) {
|
|
259
|
+
return error.data;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (isStructuredValue(error) && 'toResponse' in error && typeof error.toResponse === 'function') {
|
|
263
|
+
let response = error.toResponse();
|
|
264
|
+
if (isServiceErrorData(response)) return response;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return null;
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
let mapKind = (code: string) => {
|
|
271
|
+
if (code.startsWith('declaration.')) return 'declaration';
|
|
272
|
+
if (code.startsWith('input.')) return 'validation';
|
|
273
|
+
if (code.startsWith('request.')) return 'request';
|
|
274
|
+
if (code.startsWith('config.')) return 'config';
|
|
275
|
+
if (code.startsWith('auth.') || code.startsWith('permission.')) return 'auth';
|
|
276
|
+
if (code.startsWith('resource.')) return 'resource';
|
|
277
|
+
if (code.startsWith('payment.')) return 'payment';
|
|
278
|
+
if (code.startsWith('transport.')) return 'transport';
|
|
279
|
+
if (code.startsWith('upstream.')) return 'upstream';
|
|
280
|
+
return 'internal';
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
let mapRetryable = (code: string) =>
|
|
284
|
+
code === 'request.rate_limited' ||
|
|
285
|
+
code === 'upstream.rate_limited' ||
|
|
286
|
+
code === 'upstream.timeout' ||
|
|
287
|
+
code === 'upstream.network_error' ||
|
|
288
|
+
code === 'upstream.unavailable' ||
|
|
289
|
+
code === 'upstream.error' ||
|
|
290
|
+
code === 'transport.invoke_failed' ||
|
|
291
|
+
code === 'internal.timeout';
|
|
292
|
+
|
|
293
|
+
let mapServiceErrorCode = (code: string, status?: number) => {
|
|
294
|
+
if (SERVICE_ERROR_CODE_MAP[code]) return SERVICE_ERROR_CODE_MAP[code];
|
|
295
|
+
if (status === 400) return 'request.bad';
|
|
296
|
+
if (status === 401) return 'auth.required';
|
|
297
|
+
if (status === 402) return 'payment.required';
|
|
298
|
+
if (status === 403) return 'permission.denied';
|
|
299
|
+
if (status === 404) return 'resource.not_found';
|
|
300
|
+
if (status === 406) return 'request.not_acceptable';
|
|
301
|
+
if (status === 409) return 'resource.conflict';
|
|
302
|
+
if (status === 410) return 'resource.gone';
|
|
303
|
+
if (status === 412) return 'request.precondition_failed';
|
|
304
|
+
if (status === 429) return 'request.rate_limited';
|
|
305
|
+
if (status === 501) return 'operation.not_implemented';
|
|
306
|
+
if (status === 504) return 'internal.timeout';
|
|
307
|
+
if (status && status >= 500) return 'internal.unexpected';
|
|
308
|
+
return 'internal.unexpected';
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
let mapIssues = (errors: unknown) => {
|
|
312
|
+
if (!Array.isArray(errors)) return undefined;
|
|
313
|
+
let issues = errors.map(error => {
|
|
314
|
+
if (!isRecord(error)) {
|
|
315
|
+
return { message: String(error) };
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return {
|
|
319
|
+
...error,
|
|
320
|
+
path: Array.isArray(error.path) ? error.path.map(entry => String(entry)) : undefined,
|
|
321
|
+
code: typeof error.code === 'string' ? error.code : undefined,
|
|
322
|
+
message: typeof error.message === 'string' ? error.message : 'Validation issue'
|
|
323
|
+
};
|
|
324
|
+
});
|
|
325
|
+
return issues.length > 0 ? issues : undefined;
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
let mapServiceErrorToSlateErrorResponse = (
|
|
329
|
+
error: {
|
|
330
|
+
status: number;
|
|
331
|
+
code: string;
|
|
332
|
+
message: string;
|
|
333
|
+
errors?: unknown;
|
|
334
|
+
hint?: string;
|
|
335
|
+
description?: string;
|
|
336
|
+
reason?: string;
|
|
337
|
+
[key: string]: unknown;
|
|
338
|
+
},
|
|
339
|
+
defaults: Partial<{ code: string; message: string }> = {}
|
|
340
|
+
) => {
|
|
341
|
+
let code = defaults.code ?? mapServiceErrorCode(error.code, error.status);
|
|
342
|
+
let extraEntries = Object.entries(error).filter(
|
|
343
|
+
([key]) =>
|
|
344
|
+
![
|
|
345
|
+
'status',
|
|
346
|
+
'code',
|
|
347
|
+
'message',
|
|
348
|
+
'errors',
|
|
349
|
+
'hint',
|
|
350
|
+
'description',
|
|
351
|
+
'reason',
|
|
352
|
+
'object',
|
|
353
|
+
'ok'
|
|
354
|
+
].includes(key)
|
|
355
|
+
);
|
|
356
|
+
|
|
357
|
+
return {
|
|
358
|
+
code,
|
|
359
|
+
kind: mapKind(code),
|
|
360
|
+
message: error.message,
|
|
361
|
+
retryable: mapRetryable(code),
|
|
362
|
+
status: error.status,
|
|
363
|
+
...(mapIssues(error.errors) ? { issues: mapIssues(error.errors) } : {}),
|
|
364
|
+
baggage: {
|
|
365
|
+
serviceError: {
|
|
366
|
+
code: error.code,
|
|
367
|
+
status: error.status,
|
|
368
|
+
hint: error.hint,
|
|
369
|
+
description: error.description,
|
|
370
|
+
reason: error.reason
|
|
371
|
+
},
|
|
372
|
+
...(extraEntries.length > 0
|
|
373
|
+
? { serviceErrorData: Object.fromEntries(extraEntries) }
|
|
374
|
+
: {})
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
let mapUnknownErrorToSlateErrorResponse = (
|
|
380
|
+
error: unknown,
|
|
381
|
+
defaults: Partial<{ code: string; message: string }> = {}
|
|
382
|
+
) => ({
|
|
383
|
+
code: defaults.code ?? 'internal.unexpected',
|
|
384
|
+
kind: 'internal',
|
|
385
|
+
message:
|
|
386
|
+
defaults.message ??
|
|
387
|
+
(error instanceof Error ? error.message : 'An unexpected internal error occurred.'),
|
|
388
|
+
retryable: false,
|
|
389
|
+
status: 500,
|
|
390
|
+
...(error instanceof Error
|
|
391
|
+
? {
|
|
392
|
+
baggage: {
|
|
393
|
+
originalName: error.name
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
: {})
|
|
397
|
+
});
|
package/src/index.ts
CHANGED
package/src/messages/action.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import z from 'zod';
|
|
2
2
|
import { slatesAction } from '../types';
|
|
3
|
+
import { withRequestTraces } from './tracing';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* List Actions
|
|
@@ -69,7 +70,7 @@ export type SlatesMessageActionInvokeRequest = z.infer<
|
|
|
69
70
|
export let slatesMessageActionInvokeResponse = z.object({
|
|
70
71
|
jsonrpc: z.literal('2.0'),
|
|
71
72
|
id: z.string(),
|
|
72
|
-
result:
|
|
73
|
+
result: withRequestTraces({
|
|
73
74
|
output: z.record(z.string(), z.any()),
|
|
74
75
|
message: z.string().optional()
|
|
75
76
|
})
|
|
@@ -99,7 +100,7 @@ export type SlatesMessageActionTriggerEventMapRequest = z.infer<
|
|
|
99
100
|
export let slatesMessageActionTriggerEventMapResponse = z.object({
|
|
100
101
|
jsonrpc: z.literal('2.0'),
|
|
101
102
|
id: z.string(),
|
|
102
|
-
result:
|
|
103
|
+
result: withRequestTraces({
|
|
103
104
|
type: z.string(),
|
|
104
105
|
id: z.string(),
|
|
105
106
|
output: z.record(z.string(), z.any())
|
|
@@ -130,7 +131,7 @@ export type SlatesMessageActionTriggerEventsPollRequest = z.infer<
|
|
|
130
131
|
export let slatesMessageActionTriggerEventsPollResponse = z.object({
|
|
131
132
|
jsonrpc: z.literal('2.0'),
|
|
132
133
|
id: z.string(),
|
|
133
|
-
result:
|
|
134
|
+
result: withRequestTraces({
|
|
134
135
|
inputs: z.array(z.record(z.string(), z.any())),
|
|
135
136
|
updatedState: z.any().nullable().optional()
|
|
136
137
|
})
|
|
@@ -169,7 +170,7 @@ export type SlatesMessageActionTriggerWebhookHandleRequest = z.infer<
|
|
|
169
170
|
export let slatesMessageActionTriggerWebhookHandleResponse = z.object({
|
|
170
171
|
jsonrpc: z.literal('2.0'),
|
|
171
172
|
id: z.string(),
|
|
172
|
-
result:
|
|
173
|
+
result: withRequestTraces({
|
|
173
174
|
inputs: z.array(z.record(z.string(), z.any())),
|
|
174
175
|
updatedState: z.any().nullable().optional()
|
|
175
176
|
})
|
|
@@ -199,7 +200,7 @@ export type SlatesMessageActionTriggerWebhookRegisterRequest = z.infer<
|
|
|
199
200
|
export let slatesMessageActionTriggerWebhookRegisterResponse = z.object({
|
|
200
201
|
jsonrpc: z.literal('2.0'),
|
|
201
202
|
id: z.string(),
|
|
202
|
-
result:
|
|
203
|
+
result: withRequestTraces({
|
|
203
204
|
registrationDetails: z.any(),
|
|
204
205
|
state: z.any().optional()
|
|
205
206
|
})
|
|
@@ -231,7 +232,7 @@ export type SlatesMessageActionTriggerWebhookUnregisterRequest = z.infer<
|
|
|
231
232
|
export let slatesMessageActionTriggerWebhookUnregisterResponse = z.object({
|
|
232
233
|
jsonrpc: z.literal('2.0'),
|
|
233
234
|
id: z.string(),
|
|
234
|
-
result:
|
|
235
|
+
result: withRequestTraces({})
|
|
235
236
|
});
|
|
236
237
|
|
|
237
238
|
export type SlatesMessageActionTriggerWebhookUnregisterResponse = z.infer<
|
package/src/messages/auth.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import z from 'zod';
|
|
2
2
|
import { slatesAuthenticationMethod } from '../types';
|
|
3
|
+
import { withRequestTraces } from './tracing';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Set Authentication
|
|
@@ -92,7 +93,7 @@ export type SlatesMessageAuthInputChangedRequest = z.infer<
|
|
|
92
93
|
export let slatesMessageAuthInputChangedResponse = z.object({
|
|
93
94
|
jsonrpc: z.literal('2.0'),
|
|
94
95
|
id: z.string(),
|
|
95
|
-
result:
|
|
96
|
+
result: withRequestTraces({
|
|
96
97
|
input: z.record(z.string(), z.any()).optional()
|
|
97
98
|
})
|
|
98
99
|
});
|
|
@@ -120,7 +121,7 @@ export type SlatesMessageAuthDefaultInputGetRequest = z.infer<
|
|
|
120
121
|
export let slatesMessageAuthDefaultInputGetResponse = z.object({
|
|
121
122
|
jsonrpc: z.literal('2.0'),
|
|
122
123
|
id: z.string(),
|
|
123
|
-
result:
|
|
124
|
+
result: withRequestTraces({
|
|
124
125
|
input: z.record(z.string(), z.any())
|
|
125
126
|
})
|
|
126
127
|
});
|
|
@@ -155,7 +156,7 @@ export type SlatesMessageAuthAuthorizationUrlGetRequest = z.infer<
|
|
|
155
156
|
export let slatesMessageAuthAuthorizationUrlGetResponse = z.object({
|
|
156
157
|
jsonrpc: z.literal('2.0'),
|
|
157
158
|
id: z.string(),
|
|
158
|
-
result:
|
|
159
|
+
result: withRequestTraces({
|
|
159
160
|
authorizationUrl: z.string(),
|
|
160
161
|
input: z.record(z.string(), z.any()).optional(),
|
|
161
162
|
callbackState: z.record(z.string(), z.any()).optional()
|
|
@@ -194,9 +195,10 @@ export type SlatesMessageAuthAuthorizationCallbackHandleRequest = z.infer<
|
|
|
194
195
|
export let slatesMessageAuthAuthorizationCallbackHandleResponse = z.object({
|
|
195
196
|
jsonrpc: z.literal('2.0'),
|
|
196
197
|
id: z.string(),
|
|
197
|
-
result:
|
|
198
|
+
result: withRequestTraces({
|
|
198
199
|
output: z.record(z.string(), z.any()),
|
|
199
|
-
input: z.record(z.string(), z.any()).optional()
|
|
200
|
+
input: z.record(z.string(), z.any()).optional(),
|
|
201
|
+
scopes: z.array(z.string()).optional()
|
|
200
202
|
})
|
|
201
203
|
});
|
|
202
204
|
|
|
@@ -229,7 +231,7 @@ export type SlatesMessageAuthTokenRefreshHandleRequest = z.infer<
|
|
|
229
231
|
export let slatesMessageAuthTokenRefreshHandleResponse = z.object({
|
|
230
232
|
jsonrpc: z.literal('2.0'),
|
|
231
233
|
id: z.string(),
|
|
232
|
-
result:
|
|
234
|
+
result: withRequestTraces({
|
|
233
235
|
output: z.record(z.string(), z.any()),
|
|
234
236
|
input: z.record(z.string(), z.any()).optional()
|
|
235
237
|
})
|
|
@@ -262,7 +264,7 @@ export type SlatesMessageAuthProfileGetRequest = z.infer<
|
|
|
262
264
|
export let slatesMessageAuthProfileGetResponse = z.object({
|
|
263
265
|
jsonrpc: z.literal('2.0'),
|
|
264
266
|
id: z.string(),
|
|
265
|
-
result:
|
|
267
|
+
result: withRequestTraces({
|
|
266
268
|
profile: z.record(z.string(), z.any())
|
|
267
269
|
})
|
|
268
270
|
});
|
|
@@ -292,7 +294,7 @@ export type SlatesMessageAuthOutputGetRequest = z.infer<
|
|
|
292
294
|
export let slatesMessageAuthOutputGetResponse = z.object({
|
|
293
295
|
jsonrpc: z.literal('2.0'),
|
|
294
296
|
id: z.string(),
|
|
295
|
-
result:
|
|
297
|
+
result: withRequestTraces({
|
|
296
298
|
output: z.record(z.string(), z.any())
|
|
297
299
|
})
|
|
298
300
|
});
|
package/src/messages/config.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import z from 'zod';
|
|
2
|
+
import { withRequestTraces } from './tracing';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Set Config
|
|
@@ -61,7 +62,7 @@ export type SlatesMessageConfigChangedRequest = z.infer<
|
|
|
61
62
|
export let slatesMessageConfigChangedResponse = z.object({
|
|
62
63
|
jsonrpc: z.literal('2.0'),
|
|
63
64
|
id: z.string(),
|
|
64
|
-
result:
|
|
65
|
+
result: withRequestTraces({
|
|
65
66
|
success: z.boolean(),
|
|
66
67
|
config: z.record(z.string(), z.any()).optional(),
|
|
67
68
|
errors: z
|
|
@@ -97,7 +98,7 @@ export type SlatesMessageConfigDefaultGetRequest = z.infer<
|
|
|
97
98
|
export let slatesMessageConfigDefaultGetResponse = z.object({
|
|
98
99
|
jsonrpc: z.literal('2.0'),
|
|
99
100
|
id: z.string(),
|
|
100
|
-
result:
|
|
101
|
+
result: withRequestTraces({
|
|
101
102
|
config: z.record(z.string(), z.any()).nullable()
|
|
102
103
|
})
|
|
103
104
|
});
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import z from 'zod';
|
|
2
2
|
import { slatesParticipant } from '../types';
|
|
3
|
+
import { SLATES_PROTOCOL_VERSION } from '../version';
|
|
3
4
|
|
|
4
5
|
export let slatesMessageHelloNotification = z.object({
|
|
5
6
|
jsonrpc: z.literal('2.0'),
|
|
6
7
|
method: z.literal('slates/hello'),
|
|
7
8
|
params: z.object({
|
|
8
|
-
protocol: z.literal(
|
|
9
|
+
protocol: z.literal(SLATES_PROTOCOL_VERSION)
|
|
9
10
|
})
|
|
10
11
|
});
|
|
11
12
|
|