@web-ts-toolkit/access-router 0.3.0 → 0.4.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.mjs CHANGED
@@ -139,7 +139,7 @@ var clientErrors = JsonRouter.clientErrors;
139
139
  function parsePathParam(value, parameter) {
140
140
  const result = stringOrStringArray.safeParse(value);
141
141
  if (!result.success) {
142
- throwValidationError(result.error.issues, parameter, "parameter");
142
+ throwValidationError(normalizeIssues(result.error.issues), parameter, "parameter");
143
143
  }
144
144
  const param = Array.isArray(result.data) ? result.data[0] : result.data;
145
145
  if (!param) {
@@ -152,49 +152,333 @@ function parsePathParam(value, parameter) {
152
152
  function parseQuery(schema, value) {
153
153
  const result = schema.safeParse(value);
154
154
  if (!result.success) {
155
- throwValidationError(result.error.issues, void 0, "parameter");
155
+ throwValidationError(normalizeIssues(result.error.issues), void 0, "parameter");
156
156
  }
157
157
  return result.data;
158
158
  }
159
159
  function parseBody(schema, value) {
160
160
  const result = schema.safeParse(value ?? {});
161
161
  if (!result.success) {
162
- throwValidationError(result.error.issues, void 0, "pointer");
162
+ throwValidationError(normalizeIssues(result.error.issues), void 0, "pointer");
163
163
  }
164
164
  return result.data;
165
165
  }
166
166
  function parseBodyWithSchema(schema, value, userSchema) {
167
167
  const body = parseBody(schema, value);
168
- return isZodSchema(userSchema) ? parseUserSchema(userSchema, body) : body;
168
+ return isRequestSchema(userSchema) ? parseUserSchema(userSchema, body) : Promise.resolve(body);
169
169
  }
170
- function parseNestedBodyWithSchema(schema, value, nestedKey, userSchema) {
170
+ async function parseNestedBodyWithSchema(schema, value, nestedKey, userSchema) {
171
171
  const body = parseBody(schema, value);
172
- if (!isZodSchema(userSchema)) return body;
172
+ if (!isRequestSchema(userSchema)) return body;
173
173
  return {
174
174
  ...body,
175
- [nestedKey]: parseUserSchema(userSchema, body?.[nestedKey], [nestedKey])
175
+ [nestedKey]: await parseUserSchema(userSchema, body?.[nestedKey], [nestedKey])
176
176
  };
177
177
  }
178
178
  function throwValidationError(issues, key, location = "pointer") {
179
179
  const errors = issues.map((issue) => formatIssue(issue, key, location));
180
180
  throw new clientErrors.BadRequestError("Bad Request", { errors });
181
181
  }
182
- function parseUserSchema(schema, value, prefix = []) {
183
- const result = schema.safeParse(value);
184
- if (!result.success) {
185
- const issues = result.error.issues.map((issue) => ({
186
- ...issue,
187
- path: prefix.concat(issue.path.map(String))
188
- }));
189
- throwValidationError(issues, void 0, "pointer");
182
+ async function parseUserSchema(schema, value, prefix = []) {
183
+ const validator = toRequestSchemaValidator(schema);
184
+ const result = await validator(value);
185
+ if (!isRequestSchemaFailure(result)) {
186
+ return result.data;
190
187
  }
191
- return result.data;
188
+ const issues = result.issues.map((issue) => ({
189
+ ...issue,
190
+ path: prefix.concat((issue.path ?? []).map(String))
191
+ }));
192
+ throwValidationError(issues, void 0, "pointer");
192
193
  }
193
194
  function isZodSchema(schema) {
194
195
  return typeof schema === "object" && schema !== null && "safeParse" in schema && typeof schema.safeParse === "function";
195
196
  }
197
+ function isRequestSchema(schema) {
198
+ return isZodSchema(schema) || isStandardSchema(schema) || isRequestSchemaValidator(schema) || isRequestSchemaAdapter(schema);
199
+ }
200
+ function isRequestSchemaValidator(schema) {
201
+ return typeof schema === "function";
202
+ }
203
+ function isRequestSchemaAdapter(schema) {
204
+ return typeof schema === "object" && schema !== null && "validate" in schema && typeof schema.validate === "function";
205
+ }
206
+ function isStandardSchema(schema) {
207
+ 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";
208
+ }
209
+ function isRequestSchemaFailure(result) {
210
+ return result.success === false;
211
+ }
212
+ function toRequestSchemaValidator(schema) {
213
+ if (isZodSchema(schema)) return fromZod(schema);
214
+ if (isStandardSchema(schema)) return fromStandardSchema(schema);
215
+ if (isRequestSchemaValidator(schema)) return schema;
216
+ return schema.validate;
217
+ }
218
+ function defineRequestSchema(validator) {
219
+ return validator;
220
+ }
221
+ function fromZod(schema) {
222
+ return (value) => {
223
+ const result = schema.safeParse(value);
224
+ if (result.success) {
225
+ return {
226
+ success: true,
227
+ data: result.data
228
+ };
229
+ }
230
+ return {
231
+ success: false,
232
+ issues: normalizeIssues(result.error.issues)
233
+ };
234
+ };
235
+ }
236
+ function fromStandardSchema(schema) {
237
+ return async (value) => {
238
+ const result = await schema["~standard"].validate(value);
239
+ if (!isStandardSchemaFailure(result)) {
240
+ return {
241
+ success: true,
242
+ data: result.value
243
+ };
244
+ }
245
+ return {
246
+ success: false,
247
+ issues: normalizeIssues(result.issues)
248
+ };
249
+ };
250
+ }
251
+ function fromYup(schema) {
252
+ return async (value) => {
253
+ try {
254
+ const data = await schema.validate(value, { abortEarly: false });
255
+ return {
256
+ success: true,
257
+ data
258
+ };
259
+ } catch (error) {
260
+ return {
261
+ success: false,
262
+ issues: normalizeYupIssues(error)
263
+ };
264
+ }
265
+ };
266
+ }
267
+ function fromJoi(schema) {
268
+ return async (value) => {
269
+ const result = await schema.validate(value, { abortEarly: false });
270
+ if (!result.error?.details?.length) {
271
+ return {
272
+ success: true,
273
+ data: result.value
274
+ };
275
+ }
276
+ return {
277
+ success: false,
278
+ issues: normalizeJoiIssues(result.error.details)
279
+ };
280
+ };
281
+ }
282
+ function fromAjv(validator) {
283
+ return async (value) => {
284
+ const valid = await validator(value);
285
+ if (valid) {
286
+ return {
287
+ success: true,
288
+ data: value
289
+ };
290
+ }
291
+ return {
292
+ success: false,
293
+ issues: normalizeAjvIssues(validator.errors ?? [])
294
+ };
295
+ };
296
+ }
297
+ function fromValibot(schema, safeParse) {
298
+ return async (value) => {
299
+ const result = await safeParse(schema, value, { abortEarly: false });
300
+ if (result.success) {
301
+ return {
302
+ success: true,
303
+ data: result.output
304
+ };
305
+ }
306
+ return {
307
+ success: false,
308
+ issues: normalizeValibotIssues(result.issues)
309
+ };
310
+ };
311
+ }
312
+ function fromArkType(type) {
313
+ return async (value) => {
314
+ const result = await type(value);
315
+ if (!isArkTypeErrors(result)) {
316
+ return {
317
+ success: true,
318
+ data: result
319
+ };
320
+ }
321
+ return {
322
+ success: false,
323
+ issues: normalizeArkTypeIssues(result)
324
+ };
325
+ };
326
+ }
327
+ function fromIoTs(decoder) {
328
+ return async (value) => {
329
+ const result = decoder.decode(value);
330
+ if (result._tag === "Right") {
331
+ return {
332
+ success: true,
333
+ data: result.right
334
+ };
335
+ }
336
+ return {
337
+ success: false,
338
+ issues: normalizeIoTsIssues(result.left)
339
+ };
340
+ };
341
+ }
342
+ function fromSuperstruct(struct, validate) {
343
+ return async (value) => {
344
+ const [failure, output] = await validate(value, struct);
345
+ if (!failure) {
346
+ return {
347
+ success: true,
348
+ data: output
349
+ };
350
+ }
351
+ return {
352
+ success: false,
353
+ issues: normalizeSuperstructFailure(failure)
354
+ };
355
+ };
356
+ }
357
+ function fromVine(validator) {
358
+ return async (value) => {
359
+ try {
360
+ const output = await validator.validate(value);
361
+ return {
362
+ success: true,
363
+ data: output
364
+ };
365
+ } catch (error) {
366
+ return {
367
+ success: false,
368
+ issues: normalizeVineError(error)
369
+ };
370
+ }
371
+ };
372
+ }
373
+ function isStandardSchemaFailure(result) {
374
+ return Array.isArray(result.issues);
375
+ }
376
+ function normalizeIssues(issues) {
377
+ return issues.map((issue) => ({
378
+ message: issue.message,
379
+ path: issue.path?.flatMap((segment) => normalizePathSegment(segment))
380
+ }));
381
+ }
382
+ function normalizePathSegment(segment) {
383
+ const key = isStandardSchemaPathSegment(segment) ? segment.key : segment;
384
+ return typeof key === "string" || typeof key === "number" ? [key] : [];
385
+ }
386
+ function isStandardSchemaPathSegment(segment) {
387
+ return typeof segment === "object" && segment !== null && "key" in segment;
388
+ }
389
+ function normalizeYupIssues(error) {
390
+ if (!isYupValidationError(error)) {
391
+ return [{ message: "Validation failed" }];
392
+ }
393
+ const issues = error.inner?.length ? error.inner : [error];
394
+ return issues.map((issue) => ({
395
+ message: issue.message,
396
+ path: parsePathString(issue.path)
397
+ }));
398
+ }
399
+ function normalizeJoiIssues(issues) {
400
+ return issues.map((issue) => ({
401
+ message: issue.message,
402
+ path: issue.path ? [...issue.path] : void 0
403
+ }));
404
+ }
405
+ function normalizeAjvIssues(issues) {
406
+ return issues.map((issue) => ({
407
+ message: issue.message ?? "Validation failed",
408
+ path: parseAjvPath(issue)
409
+ }));
410
+ }
411
+ function normalizeValibotIssues(issues) {
412
+ return issues.map((issue) => ({
413
+ message: issue.message,
414
+ path: issue.path?.flatMap(
415
+ (item) => typeof item.key === "string" || typeof item.key === "number" ? [item.key] : []
416
+ )
417
+ }));
418
+ }
419
+ function normalizeArkTypeIssues(issues) {
420
+ const normalized = issues.map((issue) => ({
421
+ message: issue.message ?? issue.problem ?? issues.summary ?? "Validation failed",
422
+ path: issue.path ? [...issue.path] : void 0
423
+ }));
424
+ return normalized.length ? normalized : [{ message: issues.summary ?? "Validation failed" }];
425
+ }
426
+ function normalizeIoTsIssues(issues) {
427
+ return issues.map((issue) => ({
428
+ message: issue.message ?? "Validation failed",
429
+ path: issue.context.map((entry) => entry.key).filter(Boolean)
430
+ }));
431
+ }
432
+ function normalizeSuperstructFailure(failure) {
433
+ const failures = failure.failures?.() ?? [failure];
434
+ return failures.map((entry) => ({
435
+ message: entry.message ?? "Validation failed",
436
+ path: normalizeSuperstructPath(entry)
437
+ }));
438
+ }
439
+ function normalizeSuperstructPath(failure) {
440
+ if (failure.path?.length) return [...failure.path];
441
+ if (typeof failure.key === "string" || typeof failure.key === "number") return [failure.key];
442
+ return void 0;
443
+ }
444
+ function normalizeVineError(error) {
445
+ if (!isVineValidationError(error)) {
446
+ return [{ message: "Validation failed" }];
447
+ }
448
+ return error.messages.map((message) => ({
449
+ message: message.message,
450
+ path: normalizeVineField(message)
451
+ }));
452
+ }
453
+ function normalizeVineField(message) {
454
+ const path = message.field.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean).map((segment) => /^\d+$/.test(segment) ? Number(segment) : segment);
455
+ if (typeof message.index === "number" && path.length === 0) {
456
+ return [message.index];
457
+ }
458
+ return path.length ? path : void 0;
459
+ }
460
+ function parseAjvPath(issue) {
461
+ const path = issue.instancePath?.split("/").filter(Boolean).map((segment) => /^\d+$/.test(segment) ? Number(segment) : segment);
462
+ if (issue.params?.missingProperty) {
463
+ return (path ?? []).concat(issue.params.missingProperty);
464
+ }
465
+ return path;
466
+ }
467
+ function parsePathString(path) {
468
+ if (!path) return void 0;
469
+ return path.replace(/\[(\d+)\]/g, ".$1").split(".").filter(Boolean).map((segment) => /^\d+$/.test(segment) ? Number(segment) : segment);
470
+ }
471
+ function isYupValidationError(error) {
472
+ return typeof error === "object" && error !== null && "message" in error;
473
+ }
474
+ function isArkTypeErrors(value) {
475
+ return Array.isArray(value);
476
+ }
477
+ function isVineValidationError(error) {
478
+ return typeof error === "object" && error !== null && "messages" in error && Array.isArray(error.messages);
479
+ }
196
480
  function formatIssue(issue, key, location = "pointer") {
197
- const path = issue.path.map(String);
481
+ const path = (issue.path ?? []).map(String);
198
482
  const joinedPath = path.join(".");
199
483
  if (location === "parameter") {
200
484
  return {
@@ -623,7 +907,18 @@ export {
623
907
  dataListBodySchema,
624
908
  dataReadByIdBodySchema,
625
909
  dataReadFilterBodySchema,
910
+ defineRequestSchema,
626
911
  distinctBodySchema,
912
+ fromAjv,
913
+ fromArkType,
914
+ fromIoTs,
915
+ fromJoi,
916
+ fromStandardSchema,
917
+ fromSuperstruct,
918
+ fromValibot,
919
+ fromVine,
920
+ fromYup,
921
+ fromZod,
627
922
  listBodySchema,
628
923
  listQuerySchema,
629
924
  parseBody,
package/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import mongoose from 'mongoose';
2
2
  import { Response, NextFunction, Router } from 'express';
3
- import { _ as GlobalOptions, E as DefaultModelRouterOptions, N as ExtendedDefaultModelRouterOptions, ah as ModelRouterOptions, O as ExtendedModelRouterOptions, w as DataRouterOptions, M as ExtendedDataRouterOptions, A as AccessRouterBaseRequest, a0 as GuardHook, ag as ModelRequest, u as DataRequest, bi as DataService, bj as Model, bk as Service, bl as PublicService, bh as Validation, aX as RootRouterOptions } from './service-DLKAswCS.mjs';
4
- export { bm as AccessRouterPermissionMap, bn as AccessRouterPermissions, e as AccessRouterRequest, f as AccessRouterRequestExtensions, bo as Permissions } from './service-DLKAswCS.mjs';
3
+ import { a6 as GlobalOptions, P as DefaultModelRouterOptions, X as ExtendedDefaultModelRouterOptions, aw as ModelRouterOptions, Y as ExtendedModelRouterOptions, L as DataRouterOptions, W as ExtendedDataRouterOptions, A as AccessRouterBaseRequest, a8 as GuardHook, av as ModelRequest, J as DataRequest, cl as DataService, cm as Model, cn as Service, co as PublicService, b_ as Validation, bk as RootRouterOptions } from './parsers-CsyGHYQR.mjs';
4
+ export { cp as AccessRouterPermissionMap, cq as AccessRouterPermissions, c as AccessRouterRequest, d as AccessRouterRequestExtensions, l as AjvErrorObjectLike, m as AjvValidatorLike, n as ArkTypeErrorsLike, o as ArkTypeLike, ab as IoTsContextEntryLike, ac as IoTsDecodeErrorLike, ad as IoTsDecoderLike, ae as JoiSchemaLike, af as JoiValidationErrorDetailLike, cr as Permissions, aR as RequestSchemaAdapter, aS as RequestSchemaFailure, aT as RequestSchemaIssue, aU as RequestSchemaLike, aV as RequestSchemaResult, aW as RequestSchemaSuccess, aX as RequestSchemaValidator, bv as StandardSchemaFailure, bw as StandardSchemaInferOutput, bx as StandardSchemaIssue, by as StandardSchemaPathSegment, bz as StandardSchemaResult, bA as StandardSchemaSuccess, bB as StandardSchemaV1, bH as SuperstructFailureLike, bI as SuperstructValidateLike, bU as ValibotIssueLike, bV as ValibotPathItemLike, bW as ValibotSafeParseLike, bX as ValibotSafeParseResult, c0 as VineValidationErrorLike, c1 as VineValidationMessageLike, c2 as VineValidatorLike, c3 as YupSchemaLike, c4 as YupValidationErrorLike, c5 as defineRequestSchema, c6 as fromAjv, c7 as fromArkType, c8 as fromIoTs, c9 as fromJoi, ca as fromStandardSchema, cb as fromSuperstruct, cc as fromValibot, cd as fromVine, ce as fromYup, cf as fromZod } from './parsers-CsyGHYQR.mjs';
5
5
  import JsonRouter from '@web-ts-toolkit/express-json-router';
6
6
  import 'zod';
7
7
  import 'deep-diff';
package/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import mongoose from 'mongoose';
2
2
  import { Response, NextFunction, Router } from 'express';
3
- import { _ as GlobalOptions, E as DefaultModelRouterOptions, N as ExtendedDefaultModelRouterOptions, ah as ModelRouterOptions, O as ExtendedModelRouterOptions, w as DataRouterOptions, M as ExtendedDataRouterOptions, A as AccessRouterBaseRequest, a0 as GuardHook, ag as ModelRequest, u as DataRequest, bi as DataService, bj as Model, bk as Service, bl as PublicService, bh as Validation, aX as RootRouterOptions } from './service-DLKAswCS.js';
4
- export { bm as AccessRouterPermissionMap, bn as AccessRouterPermissions, e as AccessRouterRequest, f as AccessRouterRequestExtensions, bo as Permissions } from './service-DLKAswCS.js';
3
+ import { a6 as GlobalOptions, P as DefaultModelRouterOptions, X as ExtendedDefaultModelRouterOptions, aw as ModelRouterOptions, Y as ExtendedModelRouterOptions, L as DataRouterOptions, W as ExtendedDataRouterOptions, A as AccessRouterBaseRequest, a8 as GuardHook, av as ModelRequest, J as DataRequest, cl as DataService, cm as Model, cn as Service, co as PublicService, b_ as Validation, bk as RootRouterOptions } from './parsers-CsyGHYQR.js';
4
+ export { cp as AccessRouterPermissionMap, cq as AccessRouterPermissions, c as AccessRouterRequest, d as AccessRouterRequestExtensions, l as AjvErrorObjectLike, m as AjvValidatorLike, n as ArkTypeErrorsLike, o as ArkTypeLike, ab as IoTsContextEntryLike, ac as IoTsDecodeErrorLike, ad as IoTsDecoderLike, ae as JoiSchemaLike, af as JoiValidationErrorDetailLike, cr as Permissions, aR as RequestSchemaAdapter, aS as RequestSchemaFailure, aT as RequestSchemaIssue, aU as RequestSchemaLike, aV as RequestSchemaResult, aW as RequestSchemaSuccess, aX as RequestSchemaValidator, bv as StandardSchemaFailure, bw as StandardSchemaInferOutput, bx as StandardSchemaIssue, by as StandardSchemaPathSegment, bz as StandardSchemaResult, bA as StandardSchemaSuccess, bB as StandardSchemaV1, bH as SuperstructFailureLike, bI as SuperstructValidateLike, bU as ValibotIssueLike, bV as ValibotPathItemLike, bW as ValibotSafeParseLike, bX as ValibotSafeParseResult, c0 as VineValidationErrorLike, c1 as VineValidationMessageLike, c2 as VineValidatorLike, c3 as YupSchemaLike, c4 as YupValidationErrorLike, c5 as defineRequestSchema, c6 as fromAjv, c7 as fromArkType, c8 as fromIoTs, c9 as fromJoi, ca as fromStandardSchema, cb as fromSuperstruct, cc as fromValibot, cd as fromVine, ce as fromYup, cf as fromZod } from './parsers-CsyGHYQR.js';
5
5
  import JsonRouter from '@web-ts-toolkit/express-json-router';
6
6
  import 'zod';
7
7
  import 'deep-diff';