@slates/proto 1.0.0-rc.2 → 1.0.0-rc.21
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 +1632 -2
- package/dist/index.d.cts +5397 -0
- package/dist/index.d.ts +5397 -4
- package/dist/index.module.js +1480 -2
- package/package.json +9 -8
- 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 +51 -154
- package/src/messages/adapter.ts +72 -0
- package/src/messages/auth.ts +21 -13
- package/src/messages/config.ts +12 -3
- package/src/messages/controlFlow.ts +2 -1
- package/src/messages/hub.ts +92 -0
- package/src/messages/identify.ts +10 -3
- package/src/messages/index.ts +68 -14
- package/src/messages/legacyTrigger.ts +149 -0
- package/src/messages/tracing.ts +38 -0
- package/src/messages/triggerGroup.ts +383 -0
- package/src/messages/webhookErrors.ts +21 -0
- package/src/types/action.ts +25 -13
- package/src/types/adapter.ts +15 -0
- package/src/types/authMethod.ts +19 -1
- package/src/types/index.ts +2 -0
- package/src/types/triggerGroup.ts +49 -0
- 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 -46
- 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 -496
- package/dist/messages/auth.d.ts.map +0 -1
- package/dist/messages/config.d.ts +0 -138
- 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 -48
- package/dist/messages/identify.d.ts.map +0 -1
- package/dist/messages/index.d.ts +0 -556
- 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.21",
|
|
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
|
-
"
|
|
30
|
-
"
|
|
29
|
+
"build": "tsup --config ../../tsup.packages.config.ts",
|
|
30
|
+
"typecheck": "tsc --noEmit",
|
|
31
|
+
"biome:check": "biome check --write src"
|
|
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,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