@web-ts-toolkit/access-router 0.3.0 → 0.5.0

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/advanced.js CHANGED
@@ -29,7 +29,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  // src/advanced.ts
30
30
  var advanced_exports = {};
31
31
  __export(advanced_exports, {
32
- CORE: () => CORE,
33
32
  Codes: () => Codes,
34
33
  CustomHeaders: () => CustomHeaders,
35
34
  DATA_MIDDLEWARE: () => DATA_MIDDLEWARE,
@@ -47,7 +46,18 @@ __export(advanced_exports, {
47
46
  dataListBodySchema: () => dataListBodySchema,
48
47
  dataReadByIdBodySchema: () => dataReadByIdBodySchema,
49
48
  dataReadFilterBodySchema: () => dataReadFilterBodySchema,
49
+ defineRequestSchema: () => defineRequestSchema,
50
50
  distinctBodySchema: () => distinctBodySchema,
51
+ fromAjv: () => fromAjv,
52
+ fromArkType: () => fromArkType,
53
+ fromIoTs: () => fromIoTs,
54
+ fromJoi: () => fromJoi,
55
+ fromStandardSchema: () => fromStandardSchema,
56
+ fromSuperstruct: () => fromSuperstruct,
57
+ fromValibot: () => fromValibot,
58
+ fromVine: () => fromVine,
59
+ fromYup: () => fromYup,
60
+ fromZod: () => fromZod,
51
61
  listBodySchema: () => listBodySchema,
52
62
  listQuerySchema: () => listQuerySchema,
53
63
  parseBody: () => parseBody,
@@ -73,7 +83,6 @@ module.exports = __toCommonJS(advanced_exports);
73
83
  // src/symbols.ts
74
84
  var MIDDLEWARE = /* @__PURE__ */ Symbol.for("@web-ts-toolkit/access-router/middleware");
75
85
  var DATA_MIDDLEWARE = /* @__PURE__ */ Symbol.for("@web-ts-toolkit/access-router/data-middleware");
76
- var CORE = /* @__PURE__ */ Symbol.for("@web-ts-toolkit/access-router/core");
77
86
  var PERMISSIONS = /* @__PURE__ */ Symbol.for("@web-ts-toolkit/access-router/permissions");
78
87
  var PERMISSION_KEYS = /* @__PURE__ */ Symbol.for("@web-ts-toolkit/access-router/permission-keys");
79
88
 
@@ -211,7 +220,7 @@ var clientErrors = import_express_json_router.default.clientErrors;
211
220
  function parsePathParam(value, parameter) {
212
221
  const result = stringOrStringArray.safeParse(value);
213
222
  if (!result.success) {
214
- throwValidationError(result.error.issues, parameter, "parameter");
223
+ throwValidationError(normalizeIssues(result.error.issues), parameter, "parameter");
215
224
  }
216
225
  const param = Array.isArray(result.data) ? result.data[0] : result.data;
217
226
  if (!param) {
@@ -224,49 +233,336 @@ function parsePathParam(value, parameter) {
224
233
  function parseQuery(schema, value) {
225
234
  const result = schema.safeParse(value);
226
235
  if (!result.success) {
227
- throwValidationError(result.error.issues, void 0, "parameter");
236
+ throwValidationError(normalizeIssues(result.error.issues), void 0, "parameter");
228
237
  }
229
238
  return result.data;
230
239
  }
231
240
  function parseBody(schema, value) {
232
241
  const result = schema.safeParse(value ?? {});
233
242
  if (!result.success) {
234
- throwValidationError(result.error.issues, void 0, "pointer");
243
+ throwValidationError(normalizeIssues(result.error.issues), void 0, "pointer");
235
244
  }
236
245
  return result.data;
237
246
  }
238
247
  function parseBodyWithSchema(schema, value, userSchema) {
239
248
  const body = parseBody(schema, value);
240
- return isZodSchema(userSchema) ? parseUserSchema(userSchema, body) : body;
249
+ return isRequestSchema(userSchema) ? parseUserSchema(userSchema, body) : Promise.resolve(body);
241
250
  }
242
- function parseNestedBodyWithSchema(schema, value, nestedKey, userSchema) {
251
+ async function parseNestedBodyWithSchema(schema, value, nestedKey, userSchema) {
243
252
  const body = parseBody(schema, value);
244
- if (!isZodSchema(userSchema)) return body;
253
+ if (!isRequestSchema(userSchema)) return body;
245
254
  return {
246
255
  ...body,
247
- [nestedKey]: parseUserSchema(userSchema, body?.[nestedKey], [nestedKey])
256
+ [nestedKey]: await parseUserSchema(userSchema, body?.[nestedKey], [nestedKey])
248
257
  };
249
258
  }
250
259
  function throwValidationError(issues, key, location = "pointer") {
251
260
  const errors = issues.map((issue) => formatIssue(issue, key, location));
252
261
  throw new clientErrors.BadRequestError("Bad Request", { errors });
253
262
  }
254
- function parseUserSchema(schema, value, prefix = []) {
255
- const result = schema.safeParse(value);
256
- if (!result.success) {
257
- const issues = result.error.issues.map((issue) => ({
258
- ...issue,
259
- path: prefix.concat(issue.path.map(String))
260
- }));
261
- throwValidationError(issues, void 0, "pointer");
263
+ async function parseUserSchema(schema, value, prefix = []) {
264
+ const validator = toRequestSchemaValidator(schema);
265
+ const result = await validator(value);
266
+ if (!isRequestSchemaFailure(result)) {
267
+ return result.data;
262
268
  }
263
- return result.data;
269
+ const issues = result.issues.map((issue) => ({
270
+ ...issue,
271
+ path: prefix.concat((issue.path ?? []).map(String))
272
+ }));
273
+ throwValidationError(issues, void 0, "pointer");
264
274
  }
265
275
  function isZodSchema(schema) {
266
276
  return typeof schema === "object" && schema !== null && "safeParse" in schema && typeof schema.safeParse === "function";
267
277
  }
278
+ function isRequestSchema(schema) {
279
+ return isZodSchema(schema) || isStandardSchema(schema) || isRequestSchemaValidator(schema) || isRequestSchemaAdapter(schema);
280
+ }
281
+ function isRequestSchemaValidator(schema) {
282
+ return typeof schema === "function";
283
+ }
284
+ function isRequestSchemaAdapter(schema) {
285
+ return typeof schema === "object" && schema !== null && "validate" in schema && typeof schema.validate === "function";
286
+ }
287
+ function isStandardSchema(schema) {
288
+ return typeof schema === "object" && schema !== null && "~standard" in schema && typeof schema["~standard"] === "object" && schema["~standard"] !== null && "validate" in schema["~standard"] && typeof schema["~standard"].validate === "function";
289
+ }
290
+ function isRequestSchemaFailure(result) {
291
+ return result.success === false;
292
+ }
293
+ function toRequestSchemaValidator(schema) {
294
+ if (isZodSchema(schema)) return fromZod(schema);
295
+ if (isStandardSchema(schema)) return fromStandardSchema(schema);
296
+ if (isRequestSchemaValidator(schema)) return schema;
297
+ return schema.validate;
298
+ }
299
+ function defineRequestSchema(validator, options = {}) {
300
+ return {
301
+ validate: validator,
302
+ openapi: options.openapi
303
+ };
304
+ }
305
+ function fromZod(schema) {
306
+ return (value) => {
307
+ const result = schema.safeParse(value);
308
+ if (result.success) {
309
+ return {
310
+ success: true,
311
+ data: result.data
312
+ };
313
+ }
314
+ return {
315
+ success: false,
316
+ issues: normalizeIssues(result.error.issues)
317
+ };
318
+ };
319
+ }
320
+ function fromStandardSchema(schema) {
321
+ return async (value) => {
322
+ const result = await schema["~standard"].validate(value);
323
+ if (!isStandardSchemaFailure(result)) {
324
+ return {
325
+ success: true,
326
+ data: result.value
327
+ };
328
+ }
329
+ return {
330
+ success: false,
331
+ issues: normalizeIssues(result.issues)
332
+ };
333
+ };
334
+ }
335
+ function fromYup(schema) {
336
+ return async (value) => {
337
+ try {
338
+ const data = await schema.validate(value, { abortEarly: false });
339
+ return {
340
+ success: true,
341
+ data
342
+ };
343
+ } catch (error) {
344
+ return {
345
+ success: false,
346
+ issues: normalizeYupIssues(error)
347
+ };
348
+ }
349
+ };
350
+ }
351
+ function fromJoi(schema) {
352
+ return async (value) => {
353
+ const result = await schema.validate(value, { abortEarly: false });
354
+ if (!result.error?.details?.length) {
355
+ return {
356
+ success: true,
357
+ data: result.value
358
+ };
359
+ }
360
+ return {
361
+ success: false,
362
+ issues: normalizeJoiIssues(result.error.details)
363
+ };
364
+ };
365
+ }
366
+ function fromAjv(validator) {
367
+ return async (value) => {
368
+ const valid = await validator(value);
369
+ if (valid) {
370
+ return {
371
+ success: true,
372
+ data: value
373
+ };
374
+ }
375
+ return {
376
+ success: false,
377
+ issues: normalizeAjvIssues(validator.errors ?? [])
378
+ };
379
+ };
380
+ }
381
+ function fromValibot(schema, safeParse) {
382
+ return async (value) => {
383
+ const result = await safeParse(schema, value, { abortEarly: false });
384
+ if (result.success) {
385
+ return {
386
+ success: true,
387
+ data: result.output
388
+ };
389
+ }
390
+ return {
391
+ success: false,
392
+ issues: normalizeValibotIssues(result.issues)
393
+ };
394
+ };
395
+ }
396
+ function fromArkType(type) {
397
+ return async (value) => {
398
+ const result = await type(value);
399
+ if (!isArkTypeErrors(result)) {
400
+ return {
401
+ success: true,
402
+ data: result
403
+ };
404
+ }
405
+ return {
406
+ success: false,
407
+ issues: normalizeArkTypeIssues(result)
408
+ };
409
+ };
410
+ }
411
+ function fromIoTs(decoder) {
412
+ return async (value) => {
413
+ const result = decoder.decode(value);
414
+ if (result._tag === "Right") {
415
+ return {
416
+ success: true,
417
+ data: result.right
418
+ };
419
+ }
420
+ return {
421
+ success: false,
422
+ issues: normalizeIoTsIssues(result.left)
423
+ };
424
+ };
425
+ }
426
+ function fromSuperstruct(struct, validate) {
427
+ return async (value) => {
428
+ const [failure, output] = await validate(value, struct);
429
+ if (!failure) {
430
+ return {
431
+ success: true,
432
+ data: output
433
+ };
434
+ }
435
+ return {
436
+ success: false,
437
+ issues: normalizeSuperstructFailure(failure)
438
+ };
439
+ };
440
+ }
441
+ function fromVine(validator) {
442
+ return async (value) => {
443
+ try {
444
+ const output = await validator.validate(value);
445
+ return {
446
+ success: true,
447
+ data: output
448
+ };
449
+ } catch (error) {
450
+ return {
451
+ success: false,
452
+ issues: normalizeVineError(error)
453
+ };
454
+ }
455
+ };
456
+ }
457
+ function isStandardSchemaFailure(result) {
458
+ return Array.isArray(result.issues);
459
+ }
460
+ function normalizeIssues(issues) {
461
+ return issues.map((issue) => ({
462
+ message: issue.message,
463
+ path: issue.path?.flatMap((segment) => normalizePathSegment(segment))
464
+ }));
465
+ }
466
+ function normalizePathSegment(segment) {
467
+ const key = isStandardSchemaPathSegment(segment) ? segment.key : segment;
468
+ return typeof key === "string" || typeof key === "number" ? [key] : [];
469
+ }
470
+ function isStandardSchemaPathSegment(segment) {
471
+ return typeof segment === "object" && segment !== null && "key" in segment;
472
+ }
473
+ function normalizeYupIssues(error) {
474
+ if (!isYupValidationError(error)) {
475
+ return [{ message: "Validation failed" }];
476
+ }
477
+ const issues = error.inner?.length ? error.inner : [error];
478
+ return issues.map((issue) => ({
479
+ message: issue.message,
480
+ path: parsePathString(issue.path)
481
+ }));
482
+ }
483
+ function normalizeJoiIssues(issues) {
484
+ return issues.map((issue) => ({
485
+ message: issue.message,
486
+ path: issue.path ? [...issue.path] : void 0
487
+ }));
488
+ }
489
+ function normalizeAjvIssues(issues) {
490
+ return issues.map((issue) => ({
491
+ message: issue.message ?? "Validation failed",
492
+ path: parseAjvPath(issue)
493
+ }));
494
+ }
495
+ function normalizeValibotIssues(issues) {
496
+ return issues.map((issue) => ({
497
+ message: issue.message,
498
+ path: issue.path?.flatMap(
499
+ (item) => typeof item.key === "string" || typeof item.key === "number" ? [item.key] : []
500
+ )
501
+ }));
502
+ }
503
+ function normalizeArkTypeIssues(issues) {
504
+ const normalized = issues.map((issue) => ({
505
+ message: issue.message ?? issue.problem ?? issues.summary ?? "Validation failed",
506
+ path: issue.path ? [...issue.path] : void 0
507
+ }));
508
+ return normalized.length ? normalized : [{ message: issues.summary ?? "Validation failed" }];
509
+ }
510
+ function normalizeIoTsIssues(issues) {
511
+ return issues.map((issue) => ({
512
+ message: issue.message ?? "Validation failed",
513
+ path: issue.context.map((entry) => entry.key).filter(Boolean)
514
+ }));
515
+ }
516
+ function normalizeSuperstructFailure(failure) {
517
+ const failures = failure.failures?.() ?? [failure];
518
+ return failures.map((entry) => ({
519
+ message: entry.message ?? "Validation failed",
520
+ path: normalizeSuperstructPath(entry)
521
+ }));
522
+ }
523
+ function normalizeSuperstructPath(failure) {
524
+ if (failure.path?.length) return [...failure.path];
525
+ if (typeof failure.key === "string" || typeof failure.key === "number") return [failure.key];
526
+ return void 0;
527
+ }
528
+ function normalizeVineError(error) {
529
+ if (!isVineValidationError(error)) {
530
+ return [{ message: "Validation failed" }];
531
+ }
532
+ return error.messages.map((message) => ({
533
+ message: message.message,
534
+ path: normalizeVineField(message)
535
+ }));
536
+ }
537
+ function normalizeVineField(message) {
538
+ const path = message.field.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean).map((segment) => /^\d+$/.test(segment) ? Number(segment) : segment);
539
+ if (typeof message.index === "number" && path.length === 0) {
540
+ return [message.index];
541
+ }
542
+ return path.length ? path : void 0;
543
+ }
544
+ function parseAjvPath(issue) {
545
+ const path = issue.instancePath?.split("/").filter(Boolean).map((segment) => /^\d+$/.test(segment) ? Number(segment) : segment);
546
+ if (issue.params?.missingProperty) {
547
+ return (path ?? []).concat(issue.params.missingProperty);
548
+ }
549
+ return path;
550
+ }
551
+ function parsePathString(path) {
552
+ if (!path) return void 0;
553
+ return path.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean).map((segment) => /^\d+$/.test(segment) ? Number(segment) : segment);
554
+ }
555
+ function isYupValidationError(error) {
556
+ return typeof error === "object" && error !== null && "message" in error;
557
+ }
558
+ function isArkTypeErrors(value) {
559
+ return Array.isArray(value);
560
+ }
561
+ function isVineValidationError(error) {
562
+ return typeof error === "object" && error !== null && "messages" in error && Array.isArray(error.messages);
563
+ }
268
564
  function formatIssue(issue, key, location = "pointer") {
269
- const path = issue.path.map(String);
565
+ const path = (issue.path ?? []).map(String);
270
566
  const joinedPath = path.join(".");
271
567
  if (location === "parameter") {
272
568
  return {
@@ -678,7 +974,6 @@ var rootDataQueryEntrySchema = import_zod4.z.union([
678
974
  var rootQuerySchema = import_zod4.z.array(import_zod4.z.union([rootModelQueryEntrySchema, rootDataQueryEntrySchema]));
679
975
  // Annotate the CommonJS export names for ESM import in node:
680
976
  0 && (module.exports = {
681
- CORE,
682
977
  Codes,
683
978
  CustomHeaders,
684
979
  DATA_MIDDLEWARE,
@@ -696,7 +991,18 @@ var rootQuerySchema = import_zod4.z.array(import_zod4.z.union([rootModelQueryEnt
696
991
  dataListBodySchema,
697
992
  dataReadByIdBodySchema,
698
993
  dataReadFilterBodySchema,
994
+ defineRequestSchema,
699
995
  distinctBodySchema,
996
+ fromAjv,
997
+ fromArkType,
998
+ fromIoTs,
999
+ fromJoi,
1000
+ fromStandardSchema,
1001
+ fromSuperstruct,
1002
+ fromValibot,
1003
+ fromVine,
1004
+ fromYup,
1005
+ fromZod,
700
1006
  listBodySchema,
701
1007
  listQuerySchema,
702
1008
  parseBody,