arri 0.0.37 → 0.0.40
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/chunks/index.cjs +3 -3
- package/dist/chunks/index.mjs +3 -3
- package/dist/cli.cjs +11 -11
- package/dist/cli.mjs +4 -4
- package/dist/codegen.cjs +43 -56
- package/dist/codegen.d.cts +3 -4
- package/dist/codegen.d.mts +3 -4
- package/dist/codegen.d.ts +3 -4
- package/dist/codegen.mjs +5 -9
- package/dist/index.cjs +656 -25
- package/dist/index.d.cts +105 -5
- package/dist/index.d.mts +105 -5
- package/dist/index.d.ts +105 -5
- package/dist/index.mjs +639 -6
- package/dist/shared/arri.0752aa2b.cjs +192 -0
- package/dist/shared/{arri.1a30c6b5.mjs → arri.3b1c1533.mjs} +74 -2
- package/dist/shared/arri.4536bc49.d.cts +77 -0
- package/dist/shared/arri.4536bc49.d.mts +77 -0
- package/dist/shared/arri.4536bc49.d.ts +77 -0
- package/dist/shared/{arri.edc9d295.cjs → arri.529292e9.cjs} +103 -25
- package/dist/shared/arri.ebf86912.mjs +179 -0
- package/package.json +3 -3
- package/dist/shared/arri.8a065f92.cjs +0 -934
- package/dist/shared/arri.a8159363.d.cts +0 -205
- package/dist/shared/arri.a8159363.d.mts +0 -205
- package/dist/shared/arri.a8159363.d.ts +0 -205
- package/dist/shared/arri.f1c922a6.mjs +0 -893
|
@@ -1,893 +0,0 @@
|
|
|
1
|
-
import { Type, TypeGuard } from '@sinclair/typebox';
|
|
2
|
-
import { createError, isError, setResponseStatus, sendError, eventHandler, isPreflightRequest, readValidatedBody, getValidatedQuery, setResponseHeader, send, createRouter, createApp, getQuery, readBody } from 'h3';
|
|
3
|
-
import { ValueErrorType } from '@sinclair/typebox/errors';
|
|
4
|
-
import { Value } from '@sinclair/typebox/value';
|
|
5
|
-
|
|
6
|
-
const ErrorResponse = Type.Object(
|
|
7
|
-
{
|
|
8
|
-
statusCode: Type.Integer(),
|
|
9
|
-
statusMessage: Type.String(),
|
|
10
|
-
stack: Type.Array(Type.Any()),
|
|
11
|
-
data: Type.Optional(Type.Object({}, { additionalProperties: true }))
|
|
12
|
-
},
|
|
13
|
-
{ $id: "ErrorResponse" }
|
|
14
|
-
);
|
|
15
|
-
function defineError(statusCode, input = {}) {
|
|
16
|
-
const defaultVals = errorResponseDefaults[statusCode];
|
|
17
|
-
return createError({
|
|
18
|
-
statusCode,
|
|
19
|
-
statusMessage: input.statusMessage ?? defaultVals.message ?? "An unknown error occurred",
|
|
20
|
-
stack: input.stack ?? "",
|
|
21
|
-
data: input.data
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
function errorResponseFromValidationErrors(errors, prefixText = `Missing or invalid parameters`) {
|
|
25
|
-
const errorParts = [];
|
|
26
|
-
for (const err of errors) {
|
|
27
|
-
const propName = err.path.split("/");
|
|
28
|
-
propName.shift();
|
|
29
|
-
if (!errorParts.includes(propName.join("."))) {
|
|
30
|
-
errorParts.push(propName.join("."));
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
throw defineError(400, {
|
|
34
|
-
statusMessage: `${prefixText}: [${errorParts.join(",")}]`,
|
|
35
|
-
data: errors
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
const errorResponseDefaults = {
|
|
39
|
-
400: {
|
|
40
|
-
name: "BAD_REQUEST",
|
|
41
|
-
message: "Bad Request"
|
|
42
|
-
},
|
|
43
|
-
401: {
|
|
44
|
-
name: "UNAUTHORIZED",
|
|
45
|
-
message: "Unauthorized"
|
|
46
|
-
},
|
|
47
|
-
402: {
|
|
48
|
-
name: "PAYMENT_REQUIRED",
|
|
49
|
-
message: "Payment Required"
|
|
50
|
-
},
|
|
51
|
-
403: {
|
|
52
|
-
name: "FORBIDDEN",
|
|
53
|
-
message: "Forbidden"
|
|
54
|
-
},
|
|
55
|
-
404: {
|
|
56
|
-
name: "NOT_FOUND",
|
|
57
|
-
message: "Not Found"
|
|
58
|
-
},
|
|
59
|
-
405: {
|
|
60
|
-
name: "METHOD_NOT_ALLOWED",
|
|
61
|
-
message: "Method Not Allowed"
|
|
62
|
-
},
|
|
63
|
-
406: {
|
|
64
|
-
name: "NOT_ACCEPTABLE",
|
|
65
|
-
message: "Not Acceptable"
|
|
66
|
-
},
|
|
67
|
-
407: {
|
|
68
|
-
name: "PROXY_AUTHENTICATION_REQUIRED",
|
|
69
|
-
message: "Proxy Authentication Required"
|
|
70
|
-
},
|
|
71
|
-
408: {
|
|
72
|
-
name: "REQUEST_TIMEOUT",
|
|
73
|
-
message: "Request Timeout"
|
|
74
|
-
},
|
|
75
|
-
409: {
|
|
76
|
-
name: "CONFLICT",
|
|
77
|
-
message: "Conflict"
|
|
78
|
-
},
|
|
79
|
-
410: {
|
|
80
|
-
name: "GONE",
|
|
81
|
-
message: "Gone"
|
|
82
|
-
},
|
|
83
|
-
411: {
|
|
84
|
-
name: "LENGTH_REQUIRED",
|
|
85
|
-
message: "Length Required"
|
|
86
|
-
},
|
|
87
|
-
412: {
|
|
88
|
-
name: "PRECONDITION_FAILED",
|
|
89
|
-
message: "Precondition Failed"
|
|
90
|
-
},
|
|
91
|
-
413: {
|
|
92
|
-
name: "REQUEST_TOO_LONG",
|
|
93
|
-
message: "Request Entity Too Large"
|
|
94
|
-
},
|
|
95
|
-
414: {
|
|
96
|
-
name: "REQUEST_URI_TOO_LONG",
|
|
97
|
-
message: "Request-URI Too Long"
|
|
98
|
-
},
|
|
99
|
-
415: {
|
|
100
|
-
name: "UNSUPPORTED_MEDIA_TYPE",
|
|
101
|
-
message: "Unsupported Media Type"
|
|
102
|
-
},
|
|
103
|
-
416: {
|
|
104
|
-
name: "REQUESTED_RANGE_NOT_SATISFIABLE",
|
|
105
|
-
message: "Requested Range Not Satisfiable"
|
|
106
|
-
},
|
|
107
|
-
417: {
|
|
108
|
-
name: "EXPECTATION_FAILED",
|
|
109
|
-
message: "Expectation Failed"
|
|
110
|
-
},
|
|
111
|
-
418: {
|
|
112
|
-
name: "IM_A_TEAPOT",
|
|
113
|
-
message: "I'm a teapot"
|
|
114
|
-
},
|
|
115
|
-
419: {
|
|
116
|
-
name: "INSUFFICIENT_SPACE_ON_RESOURCE",
|
|
117
|
-
message: "Insufficient Space on Resource"
|
|
118
|
-
},
|
|
119
|
-
420: {
|
|
120
|
-
name: "METHOD_FAILURE",
|
|
121
|
-
message: "Method Failure"
|
|
122
|
-
},
|
|
123
|
-
421: {
|
|
124
|
-
name: "MISDIRECTED_REQUEST",
|
|
125
|
-
message: "Misdirected Request"
|
|
126
|
-
},
|
|
127
|
-
422: {
|
|
128
|
-
name: "UNPROCESSABLE_ENTITY",
|
|
129
|
-
message: "Unprocessable Entity"
|
|
130
|
-
},
|
|
131
|
-
423: {
|
|
132
|
-
name: "LOCKED",
|
|
133
|
-
message: "Locked"
|
|
134
|
-
},
|
|
135
|
-
424: {
|
|
136
|
-
name: "FAILED_DEPENDENCY",
|
|
137
|
-
message: "Failed Dependency"
|
|
138
|
-
},
|
|
139
|
-
428: {
|
|
140
|
-
name: "PRECONDITION_REQUIRED",
|
|
141
|
-
message: "Precondition Required"
|
|
142
|
-
},
|
|
143
|
-
429: {
|
|
144
|
-
name: "TOO_MANY_REQUESTS",
|
|
145
|
-
message: "Too Many Requests"
|
|
146
|
-
},
|
|
147
|
-
431: {
|
|
148
|
-
name: "REQUEST_HEADER_FIELDS_TOO_LARGE",
|
|
149
|
-
message: "Request Header Fields Too Large"
|
|
150
|
-
},
|
|
151
|
-
451: {
|
|
152
|
-
name: "UNAVAILABLE_FOR_LEGAL_REASONS",
|
|
153
|
-
message: "Unavailable For Legal Reasons"
|
|
154
|
-
},
|
|
155
|
-
500: {
|
|
156
|
-
name: "INTERNAL_SERVER_ERROR",
|
|
157
|
-
message: "Internal Server Error"
|
|
158
|
-
},
|
|
159
|
-
501: {
|
|
160
|
-
name: "NOT_IMPLEMENTED",
|
|
161
|
-
message: "Not Implemented"
|
|
162
|
-
},
|
|
163
|
-
502: {
|
|
164
|
-
name: "BAD_GATEWAY",
|
|
165
|
-
message: "Bad Gateway"
|
|
166
|
-
},
|
|
167
|
-
503: {
|
|
168
|
-
name: "SERVICE_UNAVAILABLE",
|
|
169
|
-
message: "Service Unavailable"
|
|
170
|
-
},
|
|
171
|
-
504: {
|
|
172
|
-
name: "GATEWAY_TIMEOUT",
|
|
173
|
-
message: "Gateway Timeout"
|
|
174
|
-
},
|
|
175
|
-
505: {
|
|
176
|
-
name: "HTTP_VERSION_NOT_SUPPORTED",
|
|
177
|
-
message: "HTTP Version Not Supported"
|
|
178
|
-
},
|
|
179
|
-
507: {
|
|
180
|
-
name: "INSUFFICIENT_STORAGE",
|
|
181
|
-
message: "Insufficient Storage"
|
|
182
|
-
},
|
|
183
|
-
511: {
|
|
184
|
-
name: "NETWORK_AUTHENTICATION_REQUIRED",
|
|
185
|
-
message: "Network Authentication Required"
|
|
186
|
-
}
|
|
187
|
-
};
|
|
188
|
-
async function handleH3Error(err, context, event, onError) {
|
|
189
|
-
const error = isError(err) ? err : defineError(500, { data: err, stack: `${err}` });
|
|
190
|
-
setResponseStatus(event, error.statusCode);
|
|
191
|
-
if (onError) {
|
|
192
|
-
await onError(error, context, event);
|
|
193
|
-
}
|
|
194
|
-
if (event.handled) {
|
|
195
|
-
return;
|
|
196
|
-
}
|
|
197
|
-
sendError(event, error);
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
const NUMBER_CHAR_RE = /\d/;
|
|
201
|
-
const STR_SPLITTERS = ["-", "_", "/", "."];
|
|
202
|
-
function isUppercase(char = "") {
|
|
203
|
-
if (NUMBER_CHAR_RE.test(char)) {
|
|
204
|
-
return void 0;
|
|
205
|
-
}
|
|
206
|
-
return char.toUpperCase() === char;
|
|
207
|
-
}
|
|
208
|
-
function splitByCase(string_, separators) {
|
|
209
|
-
const splitters = separators ?? STR_SPLITTERS;
|
|
210
|
-
const parts = [];
|
|
211
|
-
if (!string_ || typeof string_ !== "string") {
|
|
212
|
-
return parts;
|
|
213
|
-
}
|
|
214
|
-
let buff = "";
|
|
215
|
-
let previousUpper;
|
|
216
|
-
let previousSplitter;
|
|
217
|
-
for (const char of string_) {
|
|
218
|
-
const isSplitter = splitters.includes(char);
|
|
219
|
-
if (isSplitter === true) {
|
|
220
|
-
parts.push(buff);
|
|
221
|
-
buff = "";
|
|
222
|
-
previousUpper = void 0;
|
|
223
|
-
continue;
|
|
224
|
-
}
|
|
225
|
-
const isUpper = isUppercase(char);
|
|
226
|
-
if (previousSplitter === false) {
|
|
227
|
-
if (previousUpper === false && isUpper === true) {
|
|
228
|
-
parts.push(buff);
|
|
229
|
-
buff = char;
|
|
230
|
-
previousUpper = isUpper;
|
|
231
|
-
continue;
|
|
232
|
-
}
|
|
233
|
-
if (previousUpper === true && isUpper === false && buff.length > 1) {
|
|
234
|
-
const lastChar = buff[buff.length - 1];
|
|
235
|
-
parts.push(buff.slice(0, Math.max(0, buff.length - 1)));
|
|
236
|
-
buff = lastChar + char;
|
|
237
|
-
previousUpper = isUpper;
|
|
238
|
-
continue;
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
buff += char;
|
|
242
|
-
previousUpper = isUpper;
|
|
243
|
-
previousSplitter = isSplitter;
|
|
244
|
-
}
|
|
245
|
-
parts.push(buff);
|
|
246
|
-
return parts;
|
|
247
|
-
}
|
|
248
|
-
function upperFirst(string_) {
|
|
249
|
-
return !string_ ? "" : string_[0].toUpperCase() + string_.slice(1);
|
|
250
|
-
}
|
|
251
|
-
function lowerFirst(string_) {
|
|
252
|
-
return !string_ ? "" : string_[0].toLowerCase() + string_.slice(1);
|
|
253
|
-
}
|
|
254
|
-
function pascalCase(string_) {
|
|
255
|
-
return !string_ ? "" : (Array.isArray(string_) ? string_ : splitByCase(string_)).map((p) => upperFirst(p)).join("");
|
|
256
|
-
}
|
|
257
|
-
function camelCase(string_) {
|
|
258
|
-
return lowerFirst(pascalCase(string_));
|
|
259
|
-
}
|
|
260
|
-
function kebabCase(string_, joiner) {
|
|
261
|
-
return !string_ ? "" : (Array.isArray(string_) ? string_ : splitByCase(string_)).map((p) => p.toLowerCase()).join(joiner ?? "-");
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
function normalizeWhitespace(input) {
|
|
265
|
-
if (input.includes("\n\n")) {
|
|
266
|
-
return normalizeWhitespace(input.split("\n\n").join("\n"));
|
|
267
|
-
}
|
|
268
|
-
const lines = [];
|
|
269
|
-
for (const line of input.split("\n")) {
|
|
270
|
-
lines.push(line.trim());
|
|
271
|
-
}
|
|
272
|
-
const result = lines.join("\n").trim();
|
|
273
|
-
if (result.includes("\n\n")) {
|
|
274
|
-
return normalizeWhitespace(result.split("\n\n").join("\n"));
|
|
275
|
-
}
|
|
276
|
-
return result;
|
|
277
|
-
}
|
|
278
|
-
function isProcedureDef(input) {
|
|
279
|
-
if (typeof input !== "object") {
|
|
280
|
-
return false;
|
|
281
|
-
}
|
|
282
|
-
const expectedKeys = ["path", "method"];
|
|
283
|
-
const existingKeys = Object.keys(input);
|
|
284
|
-
for (const key of expectedKeys) {
|
|
285
|
-
if (!existingKeys.includes(key)) {
|
|
286
|
-
return false;
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
return isHttpMethod(input.method) && typeof input.path === "string" && (typeof input.params === "string" || typeof input.params === "undefined") && (typeof input.response === "string" || typeof input.response === "undefined");
|
|
290
|
-
}
|
|
291
|
-
function isServiceDef(input) {
|
|
292
|
-
if (typeof input !== "object") {
|
|
293
|
-
return false;
|
|
294
|
-
}
|
|
295
|
-
for (const key of Object.keys(input)) {
|
|
296
|
-
if (typeof input[key] !== "object") {
|
|
297
|
-
return false;
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
return true;
|
|
301
|
-
}
|
|
302
|
-
function isApplicationDef(input) {
|
|
303
|
-
if (typeof input !== "object") {
|
|
304
|
-
return false;
|
|
305
|
-
}
|
|
306
|
-
if (!("procedures" in input) || typeof input.procedures !== "object") {
|
|
307
|
-
return false;
|
|
308
|
-
}
|
|
309
|
-
if (!("models" in input) || typeof input.models !== "object") {
|
|
310
|
-
return false;
|
|
311
|
-
}
|
|
312
|
-
if (!("errors" in input) || typeof input.errors !== "object") {
|
|
313
|
-
return false;
|
|
314
|
-
}
|
|
315
|
-
return true;
|
|
316
|
-
}
|
|
317
|
-
function unflattenObject(data) {
|
|
318
|
-
if (Object(data) !== data || Array.isArray(data))
|
|
319
|
-
return data;
|
|
320
|
-
const regex = /\.?([^.[\]]+)|\[(\d+)\]/g;
|
|
321
|
-
const result = {};
|
|
322
|
-
for (const p in data) {
|
|
323
|
-
let cur = result;
|
|
324
|
-
let prop = "";
|
|
325
|
-
let m;
|
|
326
|
-
while (m = regex.exec(p)) {
|
|
327
|
-
cur = cur[prop] || (cur[prop] = m[2] ? [] : {});
|
|
328
|
-
prop = m[2] || m[1];
|
|
329
|
-
}
|
|
330
|
-
cur[prop] = data[p];
|
|
331
|
-
}
|
|
332
|
-
return result[""] || result;
|
|
333
|
-
}
|
|
334
|
-
function unflattenProcedures(procedures) {
|
|
335
|
-
return unflattenObject(procedures);
|
|
336
|
-
}
|
|
337
|
-
function setNestedObjectProperty(targetProp, value, object) {
|
|
338
|
-
const parts = targetProp.split(".");
|
|
339
|
-
let current = object;
|
|
340
|
-
for (let i = 0; i < parts.length; i++) {
|
|
341
|
-
const key = parts[i];
|
|
342
|
-
if (i === parts.length - 1) {
|
|
343
|
-
current[key] = value;
|
|
344
|
-
} else {
|
|
345
|
-
if (!current[key]) {
|
|
346
|
-
current[key] = {};
|
|
347
|
-
}
|
|
348
|
-
current = current[key];
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
return object;
|
|
352
|
-
}
|
|
353
|
-
const removeDisallowedChars = (input, disallowedChars) => {
|
|
354
|
-
let result = input;
|
|
355
|
-
for (const char of disallowedChars) {
|
|
356
|
-
if (result.includes(char)) {
|
|
357
|
-
result = result.split(char).join("");
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
return result;
|
|
361
|
-
};
|
|
362
|
-
const JsonSchemaScalarTypeValues = [
|
|
363
|
-
"integer",
|
|
364
|
-
"number",
|
|
365
|
-
"bigint",
|
|
366
|
-
"string",
|
|
367
|
-
"boolean",
|
|
368
|
-
"Date"
|
|
369
|
-
];
|
|
370
|
-
const JsonSchemaNullTypeValues = ["null", "undefined"];
|
|
371
|
-
const JsonSchemaComplexTypeValues = [
|
|
372
|
-
"object",
|
|
373
|
-
"list",
|
|
374
|
-
"array",
|
|
375
|
-
"Uint8Array"
|
|
376
|
-
];
|
|
377
|
-
function isJsonSchemaScalarType(input) {
|
|
378
|
-
if (typeof input !== "object") {
|
|
379
|
-
return false;
|
|
380
|
-
}
|
|
381
|
-
if (!("type" in input)) {
|
|
382
|
-
return false;
|
|
383
|
-
}
|
|
384
|
-
return JsonSchemaScalarTypeValues.includes(input.type);
|
|
385
|
-
}
|
|
386
|
-
function isJsonSchemaNullType(input) {
|
|
387
|
-
if (typeof input !== "object") {
|
|
388
|
-
return false;
|
|
389
|
-
}
|
|
390
|
-
if (!("type" in input)) {
|
|
391
|
-
return false;
|
|
392
|
-
}
|
|
393
|
-
return JsonSchemaNullTypeValues.includes(input.type);
|
|
394
|
-
}
|
|
395
|
-
const isJsonSchemaObject = (input) => {
|
|
396
|
-
if (typeof input !== "object") {
|
|
397
|
-
return false;
|
|
398
|
-
}
|
|
399
|
-
return "type" in input && input.type === "object" && "properties" in input && typeof input.properties === "object";
|
|
400
|
-
};
|
|
401
|
-
const isJsonSchemaRecord = (input) => {
|
|
402
|
-
if (typeof input !== "object") {
|
|
403
|
-
return false;
|
|
404
|
-
}
|
|
405
|
-
return "type" in input && input.type === "object" && "patternProperties" in input && typeof input.patternProperties === "object";
|
|
406
|
-
};
|
|
407
|
-
function isJsonSchemaArray(input) {
|
|
408
|
-
if (typeof input !== "object") {
|
|
409
|
-
return false;
|
|
410
|
-
}
|
|
411
|
-
if ("type" in input && input.type === "array") {
|
|
412
|
-
return true;
|
|
413
|
-
}
|
|
414
|
-
return false;
|
|
415
|
-
}
|
|
416
|
-
function isJsonSchemaEnum(input) {
|
|
417
|
-
if (typeof input !== "object") {
|
|
418
|
-
return false;
|
|
419
|
-
}
|
|
420
|
-
if (!("anyOf" in input) || !Array.isArray(input.anyOf)) {
|
|
421
|
-
return false;
|
|
422
|
-
}
|
|
423
|
-
let prevType;
|
|
424
|
-
for (const item of input.anyOf) {
|
|
425
|
-
if (!isJsonSchemaScalarType(item)) {
|
|
426
|
-
return false;
|
|
427
|
-
}
|
|
428
|
-
if (item.type !== "string" && item.type !== "integer" && item.type !== "number") {
|
|
429
|
-
return false;
|
|
430
|
-
}
|
|
431
|
-
if (!prevType) {
|
|
432
|
-
prevType = item.type;
|
|
433
|
-
} else if (prevType !== item.type) {
|
|
434
|
-
return false;
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
return true;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
function typeboxSafeValidate(schema, coerce = false) {
|
|
441
|
-
const fn = (input) => {
|
|
442
|
-
const finalInput = coerce ? Value.Convert(schema, input) : input;
|
|
443
|
-
if (Value.Check(schema, finalInput)) {
|
|
444
|
-
return { success: true, value: finalInput };
|
|
445
|
-
}
|
|
446
|
-
const errs = [...Value.Errors(schema, finalInput)];
|
|
447
|
-
return {
|
|
448
|
-
success: false,
|
|
449
|
-
errors: errs
|
|
450
|
-
};
|
|
451
|
-
};
|
|
452
|
-
return fn;
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
function isRpc(input) {
|
|
456
|
-
if (typeof input !== "object") {
|
|
457
|
-
return false;
|
|
458
|
-
}
|
|
459
|
-
const anyInput = input;
|
|
460
|
-
if (!isHttpMethod(anyInput.method)) {
|
|
461
|
-
return false;
|
|
462
|
-
}
|
|
463
|
-
if (typeof anyInput.handler !== "function") {
|
|
464
|
-
return false;
|
|
465
|
-
}
|
|
466
|
-
return true;
|
|
467
|
-
}
|
|
468
|
-
function defineRpc(config) {
|
|
469
|
-
return config;
|
|
470
|
-
}
|
|
471
|
-
function createRpcDefinition(rpcName, httpPath, procedure) {
|
|
472
|
-
return {
|
|
473
|
-
description: procedure.description,
|
|
474
|
-
path: httpPath,
|
|
475
|
-
method: procedure.method ?? "post",
|
|
476
|
-
params: getRpcParamDefinition(rpcName, procedure),
|
|
477
|
-
response: getRpcResponseDefinition(rpcName, procedure)
|
|
478
|
-
};
|
|
479
|
-
}
|
|
480
|
-
function getRpcPath(rpcName, prefix = "") {
|
|
481
|
-
const path = rpcName.split(".").map(
|
|
482
|
-
(part) => removeDisallowedChars(
|
|
483
|
-
kebabCase(part),
|
|
484
|
-
`!@#$%^&*()+=[]{}|\\;:'"<>,./?`
|
|
485
|
-
)
|
|
486
|
-
).join("/");
|
|
487
|
-
const finalPath = prefix ? `/${prefix}/${path}` : `/${path}`;
|
|
488
|
-
return finalPath;
|
|
489
|
-
}
|
|
490
|
-
function getRpcParamName(rpcName, procedure) {
|
|
491
|
-
if (!procedure.params) {
|
|
492
|
-
return null;
|
|
493
|
-
}
|
|
494
|
-
const nameParts = rpcName.split(".").map(
|
|
495
|
-
(part) => removeDisallowedChars(part, `!@#$%^&*()+=[]{}|\\;:'"<>,./?`)
|
|
496
|
-
);
|
|
497
|
-
const paramName = procedure.params.$id ?? pascalCase(`${nameParts.join(`_`)}_params`);
|
|
498
|
-
return paramName;
|
|
499
|
-
}
|
|
500
|
-
function getRpcParamDefinition(rpcName, procedure) {
|
|
501
|
-
if (!procedure.params) {
|
|
502
|
-
return void 0;
|
|
503
|
-
}
|
|
504
|
-
const name = getRpcParamName(rpcName, procedure);
|
|
505
|
-
if (!name) {
|
|
506
|
-
return void 0;
|
|
507
|
-
}
|
|
508
|
-
return name;
|
|
509
|
-
}
|
|
510
|
-
function getRpcResponseName(rpcName, procedure) {
|
|
511
|
-
if (!procedure.response) {
|
|
512
|
-
return null;
|
|
513
|
-
}
|
|
514
|
-
if (TypeGuard.TObject(procedure.response)) {
|
|
515
|
-
const nameParts = rpcName.split(".").map(
|
|
516
|
-
(part) => removeDisallowedChars(part, `!@#$%^&*()+=[]{}|\\;:'"<>,./?`)
|
|
517
|
-
);
|
|
518
|
-
const responseName = procedure.response.$id ?? pascalCase(`${nameParts.join("_")}_response`);
|
|
519
|
-
return responseName;
|
|
520
|
-
}
|
|
521
|
-
return null;
|
|
522
|
-
}
|
|
523
|
-
function getRpcResponseDefinition(rpcName, procedure) {
|
|
524
|
-
if (!procedure.response) {
|
|
525
|
-
return void 0;
|
|
526
|
-
}
|
|
527
|
-
const name = getRpcResponseName(rpcName, procedure);
|
|
528
|
-
if (!name) {
|
|
529
|
-
return void 0;
|
|
530
|
-
}
|
|
531
|
-
return name;
|
|
532
|
-
}
|
|
533
|
-
function registerRpc(router, path, procedure, middleware, opts) {
|
|
534
|
-
const httpMethod = procedure.method ?? "post";
|
|
535
|
-
const handler = eventHandler(async (event) => {
|
|
536
|
-
const context = {
|
|
537
|
-
type: "procedure",
|
|
538
|
-
params: void 0
|
|
539
|
-
};
|
|
540
|
-
if (isPreflightRequest(event)) {
|
|
541
|
-
return "ok";
|
|
542
|
-
}
|
|
543
|
-
try {
|
|
544
|
-
if (middleware.length) {
|
|
545
|
-
await Promise.all(middleware.map((m) => m(context, event)));
|
|
546
|
-
}
|
|
547
|
-
if (procedure.params) {
|
|
548
|
-
switch (httpMethod) {
|
|
549
|
-
case "get":
|
|
550
|
-
case "head": {
|
|
551
|
-
const parsedParams = await getValidatedQuery(
|
|
552
|
-
event,
|
|
553
|
-
typeboxSafeValidate(procedure.params, true)
|
|
554
|
-
);
|
|
555
|
-
if (!parsedParams.success) {
|
|
556
|
-
const errorParts = [];
|
|
557
|
-
for (const err of parsedParams.errors) {
|
|
558
|
-
const propName = err.path.split("/");
|
|
559
|
-
propName.shift();
|
|
560
|
-
if (!errorParts.includes(propName.join("."))) {
|
|
561
|
-
errorParts.push(propName.join("."));
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
throw defineError(400, {
|
|
565
|
-
statusMessage: `Missing or invalid url query parameters: [${errorParts.join(
|
|
566
|
-
","
|
|
567
|
-
)}]`,
|
|
568
|
-
data: parsedParams.errors
|
|
569
|
-
});
|
|
570
|
-
}
|
|
571
|
-
context.params = parsedParams.value;
|
|
572
|
-
break;
|
|
573
|
-
}
|
|
574
|
-
case "delete":
|
|
575
|
-
case "patch":
|
|
576
|
-
case "post":
|
|
577
|
-
case "put": {
|
|
578
|
-
const parsedParams = await readValidatedBody(
|
|
579
|
-
event,
|
|
580
|
-
typeboxSafeValidate(procedure.params)
|
|
581
|
-
);
|
|
582
|
-
if (!parsedParams.success) {
|
|
583
|
-
let isObjectError = false;
|
|
584
|
-
const errorParts = [];
|
|
585
|
-
for (const err of parsedParams.errors) {
|
|
586
|
-
if (err.type === ValueErrorType.Object) {
|
|
587
|
-
isObjectError = true;
|
|
588
|
-
}
|
|
589
|
-
const propName = err.path.split("/");
|
|
590
|
-
propName.shift();
|
|
591
|
-
if (!errorParts.includes(propName.join("."))) {
|
|
592
|
-
errorParts.push(propName.join("."));
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
if (isObjectError) {
|
|
596
|
-
throw defineError(400, {
|
|
597
|
-
statusMessage: `Invalid request body. Expected object.`
|
|
598
|
-
});
|
|
599
|
-
}
|
|
600
|
-
throw defineError(400, {
|
|
601
|
-
statusMessage: `Invalid request body. Affected properties [${errorParts.join(
|
|
602
|
-
", "
|
|
603
|
-
)}]`,
|
|
604
|
-
data: parsedParams.errors
|
|
605
|
-
});
|
|
606
|
-
}
|
|
607
|
-
context.params = parsedParams.value;
|
|
608
|
-
break;
|
|
609
|
-
}
|
|
610
|
-
default:
|
|
611
|
-
break;
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
const response = await procedure.handler(context, event);
|
|
615
|
-
context.response = response;
|
|
616
|
-
if (opts.onBeforeResponse) {
|
|
617
|
-
await opts.onBeforeResponse(context, event);
|
|
618
|
-
}
|
|
619
|
-
if (typeof response === "object") {
|
|
620
|
-
setResponseHeader(event, "Content-Type", "application/json");
|
|
621
|
-
await send(event, JSON.stringify(response));
|
|
622
|
-
} else {
|
|
623
|
-
await send(event, response ?? "");
|
|
624
|
-
}
|
|
625
|
-
if (opts.onAfterResponse) {
|
|
626
|
-
await opts.onAfterResponse(context, event);
|
|
627
|
-
}
|
|
628
|
-
if (procedure.postHandler) {
|
|
629
|
-
await procedure.postHandler(context, event);
|
|
630
|
-
}
|
|
631
|
-
} catch (err) {
|
|
632
|
-
await handleH3Error(err, context, event, opts.onError);
|
|
633
|
-
}
|
|
634
|
-
return "";
|
|
635
|
-
});
|
|
636
|
-
switch (httpMethod) {
|
|
637
|
-
case "get":
|
|
638
|
-
router.get(path, handler);
|
|
639
|
-
break;
|
|
640
|
-
case "head":
|
|
641
|
-
router.head(path, handler);
|
|
642
|
-
break;
|
|
643
|
-
case "delete":
|
|
644
|
-
router.delete(path, handler);
|
|
645
|
-
break;
|
|
646
|
-
case "patch":
|
|
647
|
-
router.patch(path, handler);
|
|
648
|
-
break;
|
|
649
|
-
case "put":
|
|
650
|
-
router.put(path, handler);
|
|
651
|
-
break;
|
|
652
|
-
case "post":
|
|
653
|
-
default:
|
|
654
|
-
router.post(path, handler);
|
|
655
|
-
break;
|
|
656
|
-
}
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
function defineRoute(config) {
|
|
660
|
-
return config;
|
|
661
|
-
}
|
|
662
|
-
const defineMiddleware = (middleware) => middleware;
|
|
663
|
-
function registerRoute(router, route, middleware, prefix, opts) {
|
|
664
|
-
const handler = eventHandler(async (event) => {
|
|
665
|
-
const context = {
|
|
666
|
-
type: "route",
|
|
667
|
-
params: event.context.params,
|
|
668
|
-
query: void 0,
|
|
669
|
-
body: void 0
|
|
670
|
-
};
|
|
671
|
-
try {
|
|
672
|
-
if (middleware.length) {
|
|
673
|
-
for (const m of middleware) {
|
|
674
|
-
await m(context, event);
|
|
675
|
-
}
|
|
676
|
-
}
|
|
677
|
-
if (route.query) {
|
|
678
|
-
const result = await getValidatedQuery(
|
|
679
|
-
event,
|
|
680
|
-
typeboxSafeValidate(route.query, true)
|
|
681
|
-
);
|
|
682
|
-
if (!result.success) {
|
|
683
|
-
throw errorResponseFromValidationErrors(
|
|
684
|
-
result.errors,
|
|
685
|
-
"Missing or invalid query parameters"
|
|
686
|
-
);
|
|
687
|
-
}
|
|
688
|
-
context.query = result.value;
|
|
689
|
-
}
|
|
690
|
-
if (route.body && route.method !== "get" && route.method !== "head") {
|
|
691
|
-
const result = await readValidatedBody(
|
|
692
|
-
event,
|
|
693
|
-
typeboxSafeValidate(route.body)
|
|
694
|
-
);
|
|
695
|
-
if (!result.success) {
|
|
696
|
-
throw errorResponseFromValidationErrors(
|
|
697
|
-
result.errors,
|
|
698
|
-
"Missing or invalid body parameters"
|
|
699
|
-
);
|
|
700
|
-
}
|
|
701
|
-
context.body = result.value;
|
|
702
|
-
}
|
|
703
|
-
const response = await route.handler(context, event);
|
|
704
|
-
context.response = response;
|
|
705
|
-
if (opts?.onBeforeResponse) {
|
|
706
|
-
await opts.onBeforeResponse(context, event);
|
|
707
|
-
}
|
|
708
|
-
if (typeof response === "object") {
|
|
709
|
-
setResponseHeader(event, "Content-Type", "application/json");
|
|
710
|
-
await send(event, JSON.stringify(response));
|
|
711
|
-
} else {
|
|
712
|
-
await send(event, response ?? "");
|
|
713
|
-
}
|
|
714
|
-
if (opts?.onAfterResponse) {
|
|
715
|
-
await opts.onAfterResponse(context, event);
|
|
716
|
-
}
|
|
717
|
-
if (route.postHandler) {
|
|
718
|
-
await route.postHandler(context, event);
|
|
719
|
-
}
|
|
720
|
-
} catch (err) {
|
|
721
|
-
await handleH3Error(err, context, event, opts?.onError);
|
|
722
|
-
}
|
|
723
|
-
if (!event.handled) {
|
|
724
|
-
await send(event, "");
|
|
725
|
-
}
|
|
726
|
-
return "";
|
|
727
|
-
});
|
|
728
|
-
const finalPath = (prefix ? `/${prefix}${route.path}` : route.path).split("//").join("/");
|
|
729
|
-
switch (route.method) {
|
|
730
|
-
case "get":
|
|
731
|
-
router.get(finalPath, handler);
|
|
732
|
-
break;
|
|
733
|
-
case "head":
|
|
734
|
-
router.head(finalPath, handler);
|
|
735
|
-
break;
|
|
736
|
-
case "delete":
|
|
737
|
-
router.delete(finalPath, handler);
|
|
738
|
-
break;
|
|
739
|
-
case "patch":
|
|
740
|
-
router.patch(finalPath, handler);
|
|
741
|
-
break;
|
|
742
|
-
case "post":
|
|
743
|
-
router.post(finalPath, handler);
|
|
744
|
-
break;
|
|
745
|
-
case "put":
|
|
746
|
-
router.put(finalPath, handler);
|
|
747
|
-
break;
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
var __defProp = Object.defineProperty;
|
|
752
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
753
|
-
var __publicField = (obj, key, value) => {
|
|
754
|
-
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
755
|
-
return value;
|
|
756
|
-
};
|
|
757
|
-
const DEV_ENDPOINT_ROOT = `/__arri_dev__`;
|
|
758
|
-
const DEV_DEFINITION_ENDPOINT = `${DEV_ENDPOINT_ROOT}/definition`;
|
|
759
|
-
class Arri {
|
|
760
|
-
constructor(opts = {}) {
|
|
761
|
-
__publicField(this, "__isArri__", true);
|
|
762
|
-
__publicField(this, "h3App");
|
|
763
|
-
__publicField(this, "h3Router", createRouter());
|
|
764
|
-
__publicField(this, "rpcDefinitionPath");
|
|
765
|
-
__publicField(this, "rpcRoutePrefix");
|
|
766
|
-
__publicField(this, "appInfo");
|
|
767
|
-
__publicField(this, "procedures", {});
|
|
768
|
-
__publicField(this, "models", {});
|
|
769
|
-
__publicField(this, "middlewares", []);
|
|
770
|
-
__publicField(this, "onAfterResponse");
|
|
771
|
-
__publicField(this, "onBeforeResponse");
|
|
772
|
-
__publicField(this, "onError");
|
|
773
|
-
this.appInfo = opts?.appInfo;
|
|
774
|
-
this.h3App = createApp({
|
|
775
|
-
debug: opts?.debug,
|
|
776
|
-
onRequest: opts?.onRequest
|
|
777
|
-
});
|
|
778
|
-
this.onError = opts.onError;
|
|
779
|
-
this.onAfterResponse = opts.onAfterResponse;
|
|
780
|
-
this.onBeforeResponse = opts.onBeforeResponse;
|
|
781
|
-
this.rpcRoutePrefix = opts?.rpcRoutePrefix ?? "";
|
|
782
|
-
this.rpcDefinitionPath = opts?.rpcDefinitionPath ?? "__definition";
|
|
783
|
-
this.h3App.use(this.h3Router);
|
|
784
|
-
this.registerRoute({
|
|
785
|
-
path: this.rpcRoutePrefix ? `/${this.rpcRoutePrefix}/${this.rpcDefinitionPath}`.split("//").join("/") : `/${this.rpcDefinitionPath}`,
|
|
786
|
-
method: "get",
|
|
787
|
-
handler: () => this.getAppDefinition()
|
|
788
|
-
});
|
|
789
|
-
if (process.env.ARRI_DEV_MODE === "true") {
|
|
790
|
-
this.registerRoute({
|
|
791
|
-
path: DEV_DEFINITION_ENDPOINT,
|
|
792
|
-
method: "get",
|
|
793
|
-
handler: () => this.getAppDefinition()
|
|
794
|
-
});
|
|
795
|
-
}
|
|
796
|
-
this.h3Router.use(
|
|
797
|
-
"/**",
|
|
798
|
-
eventHandler(async (event) => {
|
|
799
|
-
setResponseStatus(event, 404);
|
|
800
|
-
const error = defineError(404);
|
|
801
|
-
const query = getQuery(event);
|
|
802
|
-
const disallowedBodyMethods = ["GET", "HEAD", "OPTION"];
|
|
803
|
-
const canBody = !disallowedBodyMethods.includes(event.method);
|
|
804
|
-
const context = {
|
|
805
|
-
type: "route",
|
|
806
|
-
params: event.context.params,
|
|
807
|
-
query,
|
|
808
|
-
// eslint-disable-next-line @typescript-eslint/no-confusing-void-expression
|
|
809
|
-
body: canBody ? await readBody(event).catch((_) => void 0) : void 0
|
|
810
|
-
};
|
|
811
|
-
try {
|
|
812
|
-
if (this.middlewares.length) {
|
|
813
|
-
for (const m of this.middlewares) {
|
|
814
|
-
await m(context, event);
|
|
815
|
-
}
|
|
816
|
-
}
|
|
817
|
-
} catch (err) {
|
|
818
|
-
await handleH3Error(err, context, event, this.onError);
|
|
819
|
-
}
|
|
820
|
-
if (event.handled) {
|
|
821
|
-
return;
|
|
822
|
-
}
|
|
823
|
-
if (this.onError) {
|
|
824
|
-
await this.onError(error, context, event);
|
|
825
|
-
}
|
|
826
|
-
if (event.handled) {
|
|
827
|
-
return;
|
|
828
|
-
}
|
|
829
|
-
sendError(event, error);
|
|
830
|
-
})
|
|
831
|
-
);
|
|
832
|
-
}
|
|
833
|
-
registerMiddleware(middleware) {
|
|
834
|
-
this.middlewares.push(middleware);
|
|
835
|
-
}
|
|
836
|
-
registerRpc(name, procedure) {
|
|
837
|
-
const path = getRpcPath(name, this.rpcRoutePrefix);
|
|
838
|
-
this.procedures[name] = createRpcDefinition(name, path, procedure);
|
|
839
|
-
if (TypeGuard.TObject(procedure.params)) {
|
|
840
|
-
const paramName = getRpcParamName(name, procedure);
|
|
841
|
-
if (paramName) {
|
|
842
|
-
this.models[paramName] = procedure.params;
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
if (TypeGuard.TObject(procedure.response)) {
|
|
846
|
-
const responseName = getRpcResponseName(name, procedure);
|
|
847
|
-
if (responseName) {
|
|
848
|
-
this.models[responseName] = procedure.response;
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
|
-
registerRpc(this.h3Router, path, procedure, this.middlewares, {
|
|
852
|
-
onError: this.onError,
|
|
853
|
-
onAfterResponse: this.onAfterResponse,
|
|
854
|
-
onBeforeResponse: this.onBeforeResponse
|
|
855
|
-
});
|
|
856
|
-
}
|
|
857
|
-
registerRoute(route) {
|
|
858
|
-
registerRoute(this.h3Router, route, this.middlewares);
|
|
859
|
-
}
|
|
860
|
-
getAppDefinition() {
|
|
861
|
-
const appDef = {
|
|
862
|
-
arriSchemaVersion: "0.0.1",
|
|
863
|
-
info: this.appInfo,
|
|
864
|
-
procedures: {},
|
|
865
|
-
models: this.models,
|
|
866
|
-
errors: ErrorResponse
|
|
867
|
-
};
|
|
868
|
-
Object.keys(this.procedures).forEach((key) => {
|
|
869
|
-
const rpc = this.procedures[key];
|
|
870
|
-
appDef.procedures[key] = rpc;
|
|
871
|
-
});
|
|
872
|
-
return appDef;
|
|
873
|
-
}
|
|
874
|
-
getH3Instance() {
|
|
875
|
-
return this.h3App;
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
const HttpMethodValues = [
|
|
879
|
-
"get",
|
|
880
|
-
"post",
|
|
881
|
-
"put",
|
|
882
|
-
"patch",
|
|
883
|
-
"delete",
|
|
884
|
-
"head"
|
|
885
|
-
];
|
|
886
|
-
const isHttpMethod = (input) => {
|
|
887
|
-
if (typeof input !== "string") {
|
|
888
|
-
return false;
|
|
889
|
-
}
|
|
890
|
-
return HttpMethodValues.includes(input);
|
|
891
|
-
};
|
|
892
|
-
|
|
893
|
-
export { Arri as A, getRpcParamDefinition as B, getRpcResponseName as C, DEV_DEFINITION_ENDPOINT as D, registerRpc as E, defineRoute as F, defineMiddleware as G, HttpMethodValues as H, registerRoute as I, JsonSchemaScalarTypeValues as J, ErrorResponse as K, defineError as L, errorResponseFromValidationErrors as M, handleH3Error as N, isProcedureDef as a, isJsonSchemaScalarType as b, isJsonSchemaNullType as c, isJsonSchemaObject as d, isJsonSchemaRecord as e, isJsonSchemaEnum as f, isJsonSchemaArray as g, unflattenProcedures as h, isServiceDef as i, camelCase as j, isApplicationDef as k, JsonSchemaNullTypeValues as l, JsonSchemaComplexTypeValues as m, normalizeWhitespace as n, kebabCase as o, pascalCase as p, DEV_ENDPOINT_ROOT as q, removeDisallowedChars as r, setNestedObjectProperty as s, isHttpMethod as t, unflattenObject as u, isRpc as v, defineRpc as w, createRpcDefinition as x, getRpcPath as y, getRpcParamName as z };
|