@vertz/core 0.1.0 → 0.2.1
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/README.md +746 -0
- package/dist/index.d.ts +185 -67
- package/dist/index.js +197 -20
- package/dist/internals.d.ts +2 -2
- package/dist/internals.js +1 -1
- package/dist/shared/{chunk-c77pg5gx.js → chunk-k596zpc6.js} +21 -18
- package/package.json +10 -6
package/dist/index.js
CHANGED
|
@@ -18,7 +18,19 @@ import {
|
|
|
18
18
|
parseBody,
|
|
19
19
|
parseRequest,
|
|
20
20
|
runMiddlewareChain
|
|
21
|
-
} from "./shared/chunk-
|
|
21
|
+
} from "./shared/chunk-k596zpc6.js";
|
|
22
|
+
|
|
23
|
+
// src/result.ts
|
|
24
|
+
var RESULT_BRAND = Symbol.for("vertz.result");
|
|
25
|
+
function isOk(result) {
|
|
26
|
+
return result.ok === true;
|
|
27
|
+
}
|
|
28
|
+
function isResult(value) {
|
|
29
|
+
if (value === null || typeof value !== "object")
|
|
30
|
+
return false;
|
|
31
|
+
const obj = value;
|
|
32
|
+
return obj[RESULT_BRAND] === true;
|
|
33
|
+
}
|
|
22
34
|
|
|
23
35
|
// src/server/cors.ts
|
|
24
36
|
var DEFAULT_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"];
|
|
@@ -78,22 +90,37 @@ function applyCorsHeaders(config, request, response) {
|
|
|
78
90
|
}
|
|
79
91
|
|
|
80
92
|
// src/app/app-runner.ts
|
|
93
|
+
function createResponseWithCors(data, status, config, request) {
|
|
94
|
+
const response = createJsonResponse(data, status);
|
|
95
|
+
if (config.cors) {
|
|
96
|
+
return applyCorsHeaders(config.cors, request, response);
|
|
97
|
+
}
|
|
98
|
+
return response;
|
|
99
|
+
}
|
|
81
100
|
function validateSchema(schema, value, label) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
if (error instanceof BadRequestException)
|
|
86
|
-
throw error;
|
|
87
|
-
const message = error instanceof Error ? error.message : `Invalid ${label}`;
|
|
101
|
+
const result = schema.parse(value);
|
|
102
|
+
if (!result.ok) {
|
|
103
|
+
const message = result.error instanceof Error ? result.error.message : `Invalid ${label}`;
|
|
88
104
|
throw new BadRequestException(message);
|
|
89
105
|
}
|
|
106
|
+
return result.data;
|
|
90
107
|
}
|
|
91
108
|
function resolveServices(registrations) {
|
|
92
109
|
const serviceMap = new Map;
|
|
93
|
-
for (const { module } of registrations) {
|
|
110
|
+
for (const { module, options } of registrations) {
|
|
94
111
|
for (const service of module.services) {
|
|
95
112
|
if (!serviceMap.has(service)) {
|
|
96
|
-
|
|
113
|
+
let parsedOptions = {};
|
|
114
|
+
if (service.options && options) {
|
|
115
|
+
const parsed = service.options.safeParse(options);
|
|
116
|
+
if (parsed.ok) {
|
|
117
|
+
parsedOptions = parsed.data;
|
|
118
|
+
} else {
|
|
119
|
+
throw new Error(`Invalid options for service ${service.moduleName}: ${parsed.error.issues.map((i) => i.message).join(", ")}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
const env = {};
|
|
123
|
+
serviceMap.set(service, service.methods({}, undefined, parsedOptions, env));
|
|
97
124
|
}
|
|
98
125
|
}
|
|
99
126
|
}
|
|
@@ -123,14 +150,22 @@ function registerRoutes(trie, basePath, registrations, serviceMap) {
|
|
|
123
150
|
const resolvedServices = resolveRouterServices(router.inject, serviceMap);
|
|
124
151
|
for (const route of router.routes) {
|
|
125
152
|
const fullPath = basePath + router.prefix + route.path;
|
|
153
|
+
const routeMiddlewares = (route.config.middlewares ?? []).map((mw) => ({
|
|
154
|
+
name: mw.name,
|
|
155
|
+
handler: mw.handler,
|
|
156
|
+
resolvedInject: {}
|
|
157
|
+
}));
|
|
126
158
|
const entry = {
|
|
127
159
|
handler: route.config.handler,
|
|
128
160
|
options: options ?? {},
|
|
129
161
|
services: resolvedServices,
|
|
162
|
+
middlewares: routeMiddlewares,
|
|
130
163
|
paramsSchema: route.config.params,
|
|
131
164
|
bodySchema: route.config.body,
|
|
132
165
|
querySchema: route.config.query,
|
|
133
|
-
headersSchema: route.config.headers
|
|
166
|
+
headersSchema: route.config.headers,
|
|
167
|
+
responseSchema: route.config.response,
|
|
168
|
+
errorsSchema: route.config.errors
|
|
134
169
|
};
|
|
135
170
|
trie.add(route.method, fullPath, entry);
|
|
136
171
|
}
|
|
@@ -143,6 +178,17 @@ function buildHandler(config, registrations, globalMiddlewares) {
|
|
|
143
178
|
const resolvedMiddlewares = resolveMiddlewares(globalMiddlewares);
|
|
144
179
|
const serviceMap = resolveServices(registrations);
|
|
145
180
|
registerRoutes(trie, basePath, registrations, serviceMap);
|
|
181
|
+
if (config._entityRoutes) {
|
|
182
|
+
for (const route of config._entityRoutes) {
|
|
183
|
+
const entry = {
|
|
184
|
+
handler: route.handler,
|
|
185
|
+
options: {},
|
|
186
|
+
services: {},
|
|
187
|
+
middlewares: []
|
|
188
|
+
};
|
|
189
|
+
trie.add(route.method, route.path, entry);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
146
192
|
return async (request) => {
|
|
147
193
|
try {
|
|
148
194
|
if (config.cors) {
|
|
@@ -155,9 +201,9 @@ function buildHandler(config, registrations, globalMiddlewares) {
|
|
|
155
201
|
if (!match) {
|
|
156
202
|
const allowed = trie.getAllowedMethods(parsed.path);
|
|
157
203
|
if (allowed.length > 0) {
|
|
158
|
-
return createJsonResponse({ error: "MethodNotAllowed", message: "Method Not Allowed"
|
|
204
|
+
return createJsonResponse({ error: { code: "MethodNotAllowed", message: "Method Not Allowed" } }, 405, { allow: allowed.join(", ") });
|
|
159
205
|
}
|
|
160
|
-
return createJsonResponse({ error: "NotFound", message: "Not Found"
|
|
206
|
+
return createJsonResponse({ error: { code: "NotFound", message: "Not Found" } }, 404);
|
|
161
207
|
}
|
|
162
208
|
const body = await parseBody(request);
|
|
163
209
|
const raw = {
|
|
@@ -175,6 +221,11 @@ function buildHandler(config, registrations, globalMiddlewares) {
|
|
|
175
221
|
};
|
|
176
222
|
const middlewareState = await runMiddlewareChain(resolvedMiddlewares, requestCtx);
|
|
177
223
|
const entry = match.handler;
|
|
224
|
+
if (entry.middlewares.length > 0) {
|
|
225
|
+
const routeCtx = { ...requestCtx, ...middlewareState };
|
|
226
|
+
const routeState = await runMiddlewareChain(entry.middlewares, routeCtx);
|
|
227
|
+
Object.assign(middlewareState, routeState);
|
|
228
|
+
}
|
|
178
229
|
const validatedParams = entry.paramsSchema ? validateSchema(entry.paramsSchema, match.params, "params") : match.params;
|
|
179
230
|
const validatedBody = entry.bodySchema ? validateSchema(entry.bodySchema, body, "body") : body;
|
|
180
231
|
const validatedQuery = entry.querySchema ? validateSchema(entry.querySchema, parsed.query, "query") : parsed.query;
|
|
@@ -191,7 +242,41 @@ function buildHandler(config, registrations, globalMiddlewares) {
|
|
|
191
242
|
env: {}
|
|
192
243
|
});
|
|
193
244
|
const result = await entry.handler(ctx);
|
|
194
|
-
|
|
245
|
+
if (isResult(result)) {
|
|
246
|
+
if (isOk(result)) {
|
|
247
|
+
const data = result.data;
|
|
248
|
+
if (config.validateResponses && entry.responseSchema) {
|
|
249
|
+
const validation = entry.responseSchema.parse(data);
|
|
250
|
+
if (!validation.ok) {
|
|
251
|
+
const message = validation.error instanceof Error ? validation.error.message : "Response schema validation failed";
|
|
252
|
+
console.warn(`[vertz] Response validation warning: ${message}`);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return createResponseWithCors(data, 200, config, request);
|
|
256
|
+
} else {
|
|
257
|
+
const errorStatus = result.status;
|
|
258
|
+
const errorBody = result.body;
|
|
259
|
+
if (config.validateResponses && entry.errorsSchema) {
|
|
260
|
+
const errorSchema = entry.errorsSchema[errorStatus];
|
|
261
|
+
if (errorSchema) {
|
|
262
|
+
const validation = errorSchema.parse(errorBody);
|
|
263
|
+
if (!validation.ok) {
|
|
264
|
+
const message = validation.error instanceof Error ? `Error schema validation failed for status ${errorStatus}: ${validation.error.message}` : `Error schema validation failed for status ${errorStatus}`;
|
|
265
|
+
console.warn(`[vertz] Response validation warning: ${message}`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return createResponseWithCors(errorBody, errorStatus, config, request);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
if (config.validateResponses && entry.responseSchema) {
|
|
273
|
+
const validation = entry.responseSchema.parse(result);
|
|
274
|
+
if (!validation.ok) {
|
|
275
|
+
const message = validation.error instanceof Error ? validation.error.message : "Response schema validation failed";
|
|
276
|
+
console.warn(`[vertz] Response validation warning: ${message}`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
const response = result === undefined ? new Response(null, { status: 204 }) : result instanceof Response ? result : createJsonResponse(result);
|
|
195
280
|
if (config.cors) {
|
|
196
281
|
return applyCorsHeaders(config.cors, request, response);
|
|
197
282
|
}
|
|
@@ -234,19 +319,65 @@ function detectAdapter(hints) {
|
|
|
234
319
|
throw new Error("No supported server runtime detected. Vertz requires Bun to use app.listen().");
|
|
235
320
|
}
|
|
236
321
|
|
|
322
|
+
// src/app/route-log.ts
|
|
323
|
+
function normalizePath(path) {
|
|
324
|
+
let normalized = path.replace(/\/+/g, "/");
|
|
325
|
+
if (normalized.length > 1 && normalized.endsWith("/")) {
|
|
326
|
+
normalized = normalized.slice(0, -1);
|
|
327
|
+
}
|
|
328
|
+
return normalized || "/";
|
|
329
|
+
}
|
|
330
|
+
function collectRoutes(basePath, registrations) {
|
|
331
|
+
const routes = [];
|
|
332
|
+
for (const { module } of registrations) {
|
|
333
|
+
for (const router of module.routers) {
|
|
334
|
+
for (const route of router.routes) {
|
|
335
|
+
routes.push({
|
|
336
|
+
method: route.method,
|
|
337
|
+
path: normalizePath(basePath + router.prefix + route.path)
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
return routes;
|
|
343
|
+
}
|
|
344
|
+
function formatRouteLog(listenUrl, routes) {
|
|
345
|
+
const header = `vertz server listening on ${listenUrl}`;
|
|
346
|
+
if (routes.length === 0) {
|
|
347
|
+
return header;
|
|
348
|
+
}
|
|
349
|
+
const sorted = [...routes].sort((a, b) => a.path.localeCompare(b.path) || a.method.localeCompare(b.method));
|
|
350
|
+
const MIN_METHOD_WIDTH = 6;
|
|
351
|
+
const maxMethodLen = Math.max(MIN_METHOD_WIDTH, ...sorted.map((r) => r.method.length));
|
|
352
|
+
const lines = sorted.map((r) => {
|
|
353
|
+
const paddedMethod = r.method.padEnd(maxMethodLen);
|
|
354
|
+
return ` ${paddedMethod} ${r.path}`;
|
|
355
|
+
});
|
|
356
|
+
return [header, "", ...lines].join(`
|
|
357
|
+
`);
|
|
358
|
+
}
|
|
359
|
+
|
|
237
360
|
// src/app/app-builder.ts
|
|
238
361
|
var DEFAULT_PORT = 3000;
|
|
239
362
|
function createApp(config) {
|
|
240
363
|
const registrations = [];
|
|
241
364
|
let globalMiddlewares = [];
|
|
242
365
|
let cachedHandler = null;
|
|
366
|
+
const registeredRoutes = [];
|
|
367
|
+
const entityRoutes = [];
|
|
243
368
|
const builder = {
|
|
244
369
|
register(module, options) {
|
|
245
370
|
registrations.push({ module, options });
|
|
371
|
+
for (const router of module.routers) {
|
|
372
|
+
for (const route of router.routes) {
|
|
373
|
+
registeredRoutes.push({ method: route.method, path: router.prefix + route.path });
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
cachedHandler = null;
|
|
246
377
|
return builder;
|
|
247
378
|
},
|
|
248
379
|
middlewares(list) {
|
|
249
|
-
globalMiddlewares = list;
|
|
380
|
+
globalMiddlewares = [...list];
|
|
250
381
|
return builder;
|
|
251
382
|
},
|
|
252
383
|
get handler() {
|
|
@@ -255,17 +386,54 @@ function createApp(config) {
|
|
|
255
386
|
}
|
|
256
387
|
return cachedHandler;
|
|
257
388
|
},
|
|
389
|
+
get router() {
|
|
390
|
+
return { routes: registeredRoutes };
|
|
391
|
+
},
|
|
258
392
|
async listen(port, options) {
|
|
259
393
|
const adapter = detectAdapter();
|
|
260
|
-
|
|
394
|
+
const serverHandle = await adapter.listen(port ?? DEFAULT_PORT, builder.handler, options);
|
|
395
|
+
if (options?.logRoutes !== false) {
|
|
396
|
+
const moduleRoutes = collectRoutes(config.basePath ?? "", registrations);
|
|
397
|
+
const routes = [...moduleRoutes, ...entityRoutes];
|
|
398
|
+
const url = `http://${serverHandle.hostname}:${serverHandle.port}`;
|
|
399
|
+
console.log(formatRouteLog(url, routes));
|
|
400
|
+
}
|
|
401
|
+
return serverHandle;
|
|
261
402
|
}
|
|
262
403
|
};
|
|
404
|
+
if (config._entityRoutes) {
|
|
405
|
+
for (const route of config._entityRoutes) {
|
|
406
|
+
const info = { method: route.method, path: route.path };
|
|
407
|
+
registeredRoutes.push(info);
|
|
408
|
+
entityRoutes.push(info);
|
|
409
|
+
}
|
|
410
|
+
} else if (config.entities && config.entities.length > 0) {
|
|
411
|
+
const rawPrefix = config.apiPrefix === undefined ? "/api/" : config.apiPrefix;
|
|
412
|
+
for (const entity of config.entities) {
|
|
413
|
+
const entityPath = rawPrefix === "" ? `/${entity.name}` : (rawPrefix.endsWith("/") ? rawPrefix : `${rawPrefix}/`) + entity.name;
|
|
414
|
+
const routes = [
|
|
415
|
+
{ method: "GET", path: entityPath },
|
|
416
|
+
{ method: "GET", path: `${entityPath}/:id` },
|
|
417
|
+
{ method: "POST", path: entityPath },
|
|
418
|
+
{ method: "PATCH", path: `${entityPath}/:id` },
|
|
419
|
+
{ method: "DELETE", path: `${entityPath}/:id` }
|
|
420
|
+
];
|
|
421
|
+
if (entity.actions) {
|
|
422
|
+
for (const actionName of Object.keys(entity.actions)) {
|
|
423
|
+
routes.push({ method: "POST", path: `${entityPath}/:id/${actionName}` });
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
registeredRoutes.push(...routes);
|
|
427
|
+
entityRoutes.push(...routes);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
263
430
|
return builder;
|
|
264
431
|
}
|
|
265
432
|
// src/env/env-validator.ts
|
|
266
433
|
function createEnv(config) {
|
|
267
|
-
const
|
|
268
|
-
|
|
434
|
+
const envRecord = config.env ?? (typeof process !== "undefined" ? process.env : {});
|
|
435
|
+
const result = config.schema.safeParse(envRecord);
|
|
436
|
+
if (!result.ok) {
|
|
269
437
|
throw new Error(`Environment validation failed:
|
|
270
438
|
${result.error.message}`);
|
|
271
439
|
}
|
|
@@ -336,23 +504,32 @@ function createModuleDef(config) {
|
|
|
336
504
|
return deepFreeze(def);
|
|
337
505
|
}
|
|
338
506
|
// src/vertz.ts
|
|
339
|
-
var vertz = deepFreeze({
|
|
507
|
+
var vertz = /* @__PURE__ */ deepFreeze({
|
|
340
508
|
env: createEnv,
|
|
341
509
|
middleware: createMiddleware,
|
|
342
510
|
moduleDef: createModuleDef,
|
|
343
511
|
module: createModule,
|
|
344
|
-
app: createApp
|
|
512
|
+
app: createApp,
|
|
513
|
+
server: createApp
|
|
345
514
|
});
|
|
515
|
+
|
|
516
|
+
// src/index.ts
|
|
517
|
+
var createServer = createApp;
|
|
518
|
+
var createApp2 = (...args) => {
|
|
519
|
+
console.warn("⚠️ createApp() is deprecated. Use createServer() from @vertz/server instead.");
|
|
520
|
+
return createApp(...args);
|
|
521
|
+
};
|
|
346
522
|
export {
|
|
347
523
|
vertz,
|
|
348
524
|
makeImmutable,
|
|
349
525
|
deepFreeze,
|
|
526
|
+
createServer,
|
|
350
527
|
createModuleDef,
|
|
351
528
|
createModule,
|
|
352
529
|
createMiddleware,
|
|
353
530
|
createImmutableProxy,
|
|
354
531
|
createEnv,
|
|
355
|
-
createApp,
|
|
532
|
+
createApp2 as createApp,
|
|
356
533
|
VertzException,
|
|
357
534
|
ValidationException,
|
|
358
535
|
UnauthorizedException,
|
package/dist/internals.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ interface RawRequest {
|
|
|
7
7
|
interface HandlerCtx {
|
|
8
8
|
params: Record<string, unknown>;
|
|
9
9
|
body: unknown;
|
|
10
|
-
query: Record<string,
|
|
10
|
+
query: Record<string, string>;
|
|
11
11
|
headers: Record<string, unknown>;
|
|
12
12
|
raw: RawRequest;
|
|
13
13
|
options: Record<string, unknown>;
|
|
@@ -17,7 +17,7 @@ interface HandlerCtx {
|
|
|
17
17
|
interface CtxConfig {
|
|
18
18
|
params: Record<string, unknown>;
|
|
19
19
|
body: unknown;
|
|
20
|
-
query: Record<string,
|
|
20
|
+
query: Record<string, string>;
|
|
21
21
|
headers: Record<string, unknown>;
|
|
22
22
|
raw: RawRequest;
|
|
23
23
|
middlewareState: Record<string, unknown>;
|
package/dist/internals.js
CHANGED
|
@@ -41,7 +41,7 @@ function deepFreeze(obj, visited = new WeakSet) {
|
|
|
41
41
|
|
|
42
42
|
// src/immutability/make-immutable.ts
|
|
43
43
|
function makeImmutable(obj, contextName) {
|
|
44
|
-
if (true) {
|
|
44
|
+
if (typeof process !== "undefined" && true) {
|
|
45
45
|
return createImmutableProxy(obj, contextName);
|
|
46
46
|
}
|
|
47
47
|
return obj;
|
|
@@ -65,7 +65,7 @@ function validateCollisions(config) {
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
function buildCtx(config) {
|
|
68
|
-
if (true) {
|
|
68
|
+
if (typeof process !== "undefined" && true) {
|
|
69
69
|
validateCollisions(config);
|
|
70
70
|
}
|
|
71
71
|
return makeImmutable({
|
|
@@ -98,11 +98,11 @@ class VertzException extends Error {
|
|
|
98
98
|
}
|
|
99
99
|
toJSON() {
|
|
100
100
|
return {
|
|
101
|
-
error:
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
101
|
+
error: {
|
|
102
|
+
code: this.code,
|
|
103
|
+
message: this.message,
|
|
104
|
+
...this.details !== undefined && { details: this.details }
|
|
105
|
+
}
|
|
106
106
|
};
|
|
107
107
|
}
|
|
108
108
|
}
|
|
@@ -110,57 +110,60 @@ class VertzException extends Error {
|
|
|
110
110
|
// src/exceptions/http-exceptions.ts
|
|
111
111
|
class BadRequestException extends VertzException {
|
|
112
112
|
constructor(message, details) {
|
|
113
|
-
super(message, 400,
|
|
113
|
+
super(message, 400, "BadRequest", details);
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
class UnauthorizedException extends VertzException {
|
|
118
118
|
constructor(message, details) {
|
|
119
|
-
super(message, 401,
|
|
119
|
+
super(message, 401, "Unauthorized", details);
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
class ForbiddenException extends VertzException {
|
|
124
124
|
constructor(message, details) {
|
|
125
|
-
super(message, 403,
|
|
125
|
+
super(message, 403, "Forbidden", details);
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
class NotFoundException extends VertzException {
|
|
130
130
|
constructor(message, details) {
|
|
131
|
-
super(message, 404,
|
|
131
|
+
super(message, 404, "NotFound", details);
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
class ConflictException extends VertzException {
|
|
136
136
|
constructor(message, details) {
|
|
137
|
-
super(message, 409,
|
|
137
|
+
super(message, 409, "Conflict", details);
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
class ValidationException extends VertzException {
|
|
142
142
|
errors;
|
|
143
143
|
constructor(errors) {
|
|
144
|
-
super("Validation failed", 422,
|
|
144
|
+
super("Validation failed", 422, "ValidationError", undefined);
|
|
145
145
|
this.errors = errors;
|
|
146
146
|
}
|
|
147
147
|
toJSON() {
|
|
148
148
|
return {
|
|
149
|
-
|
|
150
|
-
|
|
149
|
+
error: {
|
|
150
|
+
code: this.code,
|
|
151
|
+
message: this.message,
|
|
152
|
+
details: this.errors
|
|
153
|
+
}
|
|
151
154
|
};
|
|
152
155
|
}
|
|
153
156
|
}
|
|
154
157
|
|
|
155
158
|
class InternalServerErrorException extends VertzException {
|
|
156
159
|
constructor(message, details) {
|
|
157
|
-
super(message, 500,
|
|
160
|
+
super(message, 500, "InternalError", details);
|
|
158
161
|
}
|
|
159
162
|
}
|
|
160
163
|
|
|
161
164
|
class ServiceUnavailableException extends VertzException {
|
|
162
165
|
constructor(message, details) {
|
|
163
|
-
super(message, 503,
|
|
166
|
+
super(message, 503, "ServiceUnavailable", details);
|
|
164
167
|
}
|
|
165
168
|
}
|
|
166
169
|
// src/middleware/middleware-runner.ts
|
|
@@ -334,7 +337,7 @@ function createErrorResponse(error) {
|
|
|
334
337
|
if (error instanceof VertzException) {
|
|
335
338
|
return createJsonResponse(error.toJSON(), error.statusCode);
|
|
336
339
|
}
|
|
337
|
-
return createJsonResponse({ error: "InternalServerError", message: "Internal Server Error"
|
|
340
|
+
return createJsonResponse({ error: { code: "InternalServerError", message: "Internal Server Error" } }, 500);
|
|
338
341
|
}
|
|
339
342
|
|
|
340
343
|
export { createImmutableProxy, deepFreeze, makeImmutable, buildCtx, VertzException, BadRequestException, UnauthorizedException, ForbiddenException, NotFoundException, ConflictException, ValidationException, InternalServerErrorException, ServiceUnavailableException, runMiddlewareChain, Trie, parseRequest, parseBody, createJsonResponse, createErrorResponse };
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vertz/core",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
|
+
"description": "Vertz core framework primitives",
|
|
6
7
|
"repository": {
|
|
7
8
|
"type": "git",
|
|
8
9
|
"url": "https://github.com/vertz-dev/vertz.git",
|
|
@@ -29,20 +30,23 @@
|
|
|
29
30
|
],
|
|
30
31
|
"scripts": {
|
|
31
32
|
"build": "bunup",
|
|
32
|
-
"test": "
|
|
33
|
+
"test": "bun test",
|
|
34
|
+
"test:coverage": "vitest run --coverage",
|
|
33
35
|
"test:watch": "vitest",
|
|
34
36
|
"typecheck": "tsc --noEmit"
|
|
35
37
|
},
|
|
36
38
|
"dependencies": {
|
|
37
|
-
"@vertz/schema": "
|
|
39
|
+
"@vertz/schema": "0.2.1"
|
|
38
40
|
},
|
|
39
41
|
"devDependencies": {
|
|
40
|
-
"@types/node": "^
|
|
42
|
+
"@types/node": "^25.3.1",
|
|
43
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
41
44
|
"bunup": "latest",
|
|
42
45
|
"typescript": "^5.7.0",
|
|
43
|
-
"vitest": "^
|
|
46
|
+
"vitest": "^4.0.18"
|
|
44
47
|
},
|
|
45
48
|
"engines": {
|
|
46
49
|
"node": ">=22"
|
|
47
|
-
}
|
|
50
|
+
},
|
|
51
|
+
"sideEffects": false
|
|
48
52
|
}
|