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