@slates/proto 1.0.0-rc.6 → 1.0.0-rc.8
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 +1092 -2
- package/dist/index.d.cts +3462 -0
- package/dist/index.d.ts +3462 -4
- package/dist/index.module.js +986 -2
- package/package.json +7 -6
- 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 +26 -7
- 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.8",
|
|
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,22 +23,23 @@
|
|
|
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
|
}
|
|
@@ -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,9 +70,27 @@ 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
|
-
message: z.string().optional()
|
|
75
|
+
message: z.string().optional(),
|
|
76
|
+
attachments: z
|
|
77
|
+
.array(
|
|
78
|
+
z.object({
|
|
79
|
+
mimeType: z.string().optional(),
|
|
80
|
+
content: z.union([
|
|
81
|
+
z.object({
|
|
82
|
+
type: z.literal('url'),
|
|
83
|
+
url: z.string()
|
|
84
|
+
}),
|
|
85
|
+
z.object({
|
|
86
|
+
type: z.literal('content'),
|
|
87
|
+
encoding: z.union([z.literal('base64'), z.literal('utf-8')]),
|
|
88
|
+
content: z.string()
|
|
89
|
+
})
|
|
90
|
+
])
|
|
91
|
+
})
|
|
92
|
+
)
|
|
93
|
+
.optional()
|
|
75
94
|
})
|
|
76
95
|
});
|
|
77
96
|
|
|
@@ -99,7 +118,7 @@ export type SlatesMessageActionTriggerEventMapRequest = z.infer<
|
|
|
99
118
|
export let slatesMessageActionTriggerEventMapResponse = z.object({
|
|
100
119
|
jsonrpc: z.literal('2.0'),
|
|
101
120
|
id: z.string(),
|
|
102
|
-
result:
|
|
121
|
+
result: withRequestTraces({
|
|
103
122
|
type: z.string(),
|
|
104
123
|
id: z.string(),
|
|
105
124
|
output: z.record(z.string(), z.any())
|
|
@@ -130,7 +149,7 @@ export type SlatesMessageActionTriggerEventsPollRequest = z.infer<
|
|
|
130
149
|
export let slatesMessageActionTriggerEventsPollResponse = z.object({
|
|
131
150
|
jsonrpc: z.literal('2.0'),
|
|
132
151
|
id: z.string(),
|
|
133
|
-
result:
|
|
152
|
+
result: withRequestTraces({
|
|
134
153
|
inputs: z.array(z.record(z.string(), z.any())),
|
|
135
154
|
updatedState: z.any().nullable().optional()
|
|
136
155
|
})
|
|
@@ -169,7 +188,7 @@ export type SlatesMessageActionTriggerWebhookHandleRequest = z.infer<
|
|
|
169
188
|
export let slatesMessageActionTriggerWebhookHandleResponse = z.object({
|
|
170
189
|
jsonrpc: z.literal('2.0'),
|
|
171
190
|
id: z.string(),
|
|
172
|
-
result:
|
|
191
|
+
result: withRequestTraces({
|
|
173
192
|
inputs: z.array(z.record(z.string(), z.any())),
|
|
174
193
|
updatedState: z.any().nullable().optional()
|
|
175
194
|
})
|
|
@@ -199,7 +218,7 @@ export type SlatesMessageActionTriggerWebhookRegisterRequest = z.infer<
|
|
|
199
218
|
export let slatesMessageActionTriggerWebhookRegisterResponse = z.object({
|
|
200
219
|
jsonrpc: z.literal('2.0'),
|
|
201
220
|
id: z.string(),
|
|
202
|
-
result:
|
|
221
|
+
result: withRequestTraces({
|
|
203
222
|
registrationDetails: z.any(),
|
|
204
223
|
state: z.any().optional()
|
|
205
224
|
})
|
|
@@ -231,7 +250,7 @@ export type SlatesMessageActionTriggerWebhookUnregisterRequest = z.infer<
|
|
|
231
250
|
export let slatesMessageActionTriggerWebhookUnregisterResponse = z.object({
|
|
232
251
|
jsonrpc: z.literal('2.0'),
|
|
233
252
|
id: z.string(),
|
|
234
|
-
result:
|
|
253
|
+
result: withRequestTraces({})
|
|
235
254
|
});
|
|
236
255
|
|
|
237
256
|
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
|
});
|