express-version-api 1.0.6 → 2.0.5

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.js ADDED
@@ -0,0 +1,689 @@
1
+ /* express-version-api - MIT License - https://github.com/Braian-Quintian/express-version-api */
2
+
3
+ // src/types.ts
4
+ var VersioningError = class _VersioningError extends Error {
5
+ code;
6
+ requestedVersion;
7
+ availableVersions;
8
+ statusCode;
9
+ constructor(details, statusCode = 422) {
10
+ super(details.message);
11
+ this.name = "VersioningError";
12
+ this.code = details.code;
13
+ this.requestedVersion = details.requestedVersion;
14
+ this.availableVersions = details.availableVersions;
15
+ this.statusCode = statusCode;
16
+ Error.captureStackTrace(this, _VersioningError);
17
+ }
18
+ /**
19
+ * Converts the error to a JSON-serializable object.
20
+ */
21
+ toJSON() {
22
+ return {
23
+ code: this.code,
24
+ message: this.message,
25
+ statusCode: this.statusCode,
26
+ ...this.requestedVersion !== void 0 && { requestedVersion: this.requestedVersion },
27
+ ...this.availableVersions !== void 0 && { availableVersions: this.availableVersions }
28
+ };
29
+ }
30
+ };
31
+
32
+ // src/errors.ts
33
+ function createMissingVersionError(statusCode = 422, message = "API version is required") {
34
+ return new VersioningError(
35
+ {
36
+ code: "MISSING_VERSION",
37
+ message
38
+ },
39
+ statusCode
40
+ );
41
+ }
42
+ function createVersionNotFoundError(requestedVersion, availableVersions, statusCode = 422) {
43
+ return new VersioningError(
44
+ {
45
+ code: "VERSION_NOT_FOUND",
46
+ message: `No handler found for API version '${requestedVersion}'`,
47
+ requestedVersion,
48
+ availableVersions
49
+ },
50
+ statusCode
51
+ );
52
+ }
53
+ function createInvalidVersionFormatError(version, statusCode = 400) {
54
+ return new VersioningError(
55
+ {
56
+ code: "INVALID_VERSION_FORMAT",
57
+ message: `Invalid version format: '${version}'`,
58
+ requestedVersion: version
59
+ },
60
+ statusCode
61
+ );
62
+ }
63
+ function createInvalidHandlerError(key, reason) {
64
+ return new VersioningError(
65
+ {
66
+ code: "INVALID_HANDLER",
67
+ message: `Invalid handler for version '${key}': ${reason}`
68
+ },
69
+ 500
70
+ );
71
+ }
72
+ function createInvalidConfigurationError(reason) {
73
+ return new VersioningError(
74
+ {
75
+ code: "INVALID_CONFIGURATION",
76
+ message: `Invalid configuration: ${reason}`
77
+ },
78
+ 500
79
+ );
80
+ }
81
+ function isVersioningError(error) {
82
+ return error instanceof VersioningError;
83
+ }
84
+ function hasErrorCode(error, code) {
85
+ return isVersioningError(error) && error.code === code;
86
+ }
87
+
88
+ // src/config.ts
89
+ var DEFAULT_CONFIG = {
90
+ extraction: {
91
+ sources: ["header", "query"],
92
+ header: {
93
+ name: "accept-version"
94
+ },
95
+ query: {
96
+ name: "v"
97
+ },
98
+ path: {
99
+ pattern: /\/v(\d+(?:\.\d+)?(?:\.\d+)?)\//
100
+ },
101
+ custom: void 0
102
+ },
103
+ errorResponse: {
104
+ missingVersionStatus: 422,
105
+ versionNotFoundStatus: 422,
106
+ missingVersionMessage: "API version is required",
107
+ versionNotFoundMessage: "No handler found for the requested API version",
108
+ includeRequestedVersion: true,
109
+ onError: void 0
110
+ },
111
+ fallbackStrategy: "default",
112
+ defaultHandler: void 0,
113
+ validateHandlers: true,
114
+ attachVersionInfo: true,
115
+ requireVersion: true
116
+ };
117
+ function resolveConfig(options) {
118
+ if (!options) {
119
+ return DEFAULT_CONFIG;
120
+ }
121
+ if (options.fallbackStrategy !== void 0) {
122
+ const validStrategies = /* @__PURE__ */ new Set(["latest", "none", "default"]);
123
+ if (!validStrategies.has(options.fallbackStrategy)) {
124
+ throw createInvalidConfigurationError(
125
+ `Invalid fallback strategy: '${options.fallbackStrategy}'. Valid strategies: latest, none, default`
126
+ );
127
+ }
128
+ }
129
+ if (options.extraction?.sources) {
130
+ const validSources = /* @__PURE__ */ new Set(["header", "query", "path", "custom"]);
131
+ for (const source of options.extraction.sources) {
132
+ if (!validSources.has(source)) {
133
+ throw createInvalidConfigurationError(
134
+ `Invalid version source: '${source}'. Valid sources: header, query, path, custom`
135
+ );
136
+ }
137
+ }
138
+ if (options.extraction.sources.includes("custom") && !options.extraction.custom) {
139
+ throw createInvalidConfigurationError(
140
+ "Custom extractor function is required when 'custom' source is used"
141
+ );
142
+ }
143
+ }
144
+ if (options.extraction?.path?.pattern && !(options.extraction.path.pattern instanceof RegExp)) {
145
+ throw createInvalidConfigurationError("Path pattern must be a RegExp instance");
146
+ }
147
+ if (options.errorResponse?.missingVersionStatus !== void 0) {
148
+ const status = options.errorResponse.missingVersionStatus;
149
+ if (!Number.isInteger(status) || status < 100 || status > 599) {
150
+ throw createInvalidConfigurationError(
151
+ "missingVersionStatus must be a valid HTTP status code (100-599)"
152
+ );
153
+ }
154
+ }
155
+ if (options.errorResponse?.versionNotFoundStatus !== void 0) {
156
+ const status = options.errorResponse.versionNotFoundStatus;
157
+ if (!Number.isInteger(status) || status < 100 || status > 599) {
158
+ throw createInvalidConfigurationError(
159
+ "versionNotFoundStatus must be a valid HTTP status code (100-599)"
160
+ );
161
+ }
162
+ }
163
+ return {
164
+ extraction: {
165
+ sources: options.extraction?.sources ?? DEFAULT_CONFIG.extraction.sources,
166
+ header: {
167
+ name: options.extraction?.header?.name ?? DEFAULT_CONFIG.extraction.header.name
168
+ },
169
+ query: {
170
+ name: options.extraction?.query?.name ?? DEFAULT_CONFIG.extraction.query.name
171
+ },
172
+ path: {
173
+ pattern: options.extraction?.path?.pattern ?? DEFAULT_CONFIG.extraction.path.pattern
174
+ },
175
+ custom: options.extraction?.custom
176
+ },
177
+ errorResponse: {
178
+ missingVersionStatus: options.errorResponse?.missingVersionStatus ?? DEFAULT_CONFIG.errorResponse.missingVersionStatus,
179
+ versionNotFoundStatus: options.errorResponse?.versionNotFoundStatus ?? DEFAULT_CONFIG.errorResponse.versionNotFoundStatus,
180
+ missingVersionMessage: options.errorResponse?.missingVersionMessage ?? DEFAULT_CONFIG.errorResponse.missingVersionMessage,
181
+ versionNotFoundMessage: options.errorResponse?.versionNotFoundMessage ?? DEFAULT_CONFIG.errorResponse.versionNotFoundMessage,
182
+ includeRequestedVersion: options.errorResponse?.includeRequestedVersion ?? DEFAULT_CONFIG.errorResponse.includeRequestedVersion,
183
+ onError: options.errorResponse?.onError
184
+ },
185
+ fallbackStrategy: options.fallbackStrategy ?? DEFAULT_CONFIG.fallbackStrategy,
186
+ defaultHandler: options.defaultHandler ?? DEFAULT_CONFIG.defaultHandler,
187
+ validateHandlers: options.validateHandlers ?? DEFAULT_CONFIG.validateHandlers,
188
+ attachVersionInfo: options.attachVersionInfo ?? DEFAULT_CONFIG.attachVersionInfo,
189
+ requireVersion: options.requireVersion ?? DEFAULT_CONFIG.requireVersion
190
+ };
191
+ }
192
+ function freezeConfig(config) {
193
+ return Object.freeze({
194
+ ...config,
195
+ extraction: Object.freeze({
196
+ ...config.extraction,
197
+ sources: Object.freeze([...config.extraction.sources]),
198
+ header: Object.freeze({ ...config.extraction.header }),
199
+ query: Object.freeze({ ...config.extraction.query }),
200
+ path: Object.freeze({ ...config.extraction.path })
201
+ }),
202
+ errorResponse: Object.freeze({ ...config.errorResponse })
203
+ });
204
+ }
205
+
206
+ // src/version-extractor.ts
207
+ function extractFromHeader(req, headerName) {
208
+ const value = req.headers[headerName.toLowerCase()];
209
+ if (typeof value === "string" && value.trim().length > 0) {
210
+ return value.trim();
211
+ }
212
+ if (Array.isArray(value) && value.length > 0 && value[0]) {
213
+ return value[0].trim();
214
+ }
215
+ return void 0;
216
+ }
217
+ function extractFromQuery(req, paramName) {
218
+ const value = req.query[paramName];
219
+ if (typeof value === "string" && value.trim().length > 0) {
220
+ return value.trim();
221
+ }
222
+ return void 0;
223
+ }
224
+ function extractFromPath(req, pattern) {
225
+ const path = req.path || req.url;
226
+ const isStatefulPattern = pattern.global || pattern.sticky;
227
+ if (isStatefulPattern) {
228
+ pattern.lastIndex = 0;
229
+ }
230
+ const match = pattern.exec(path);
231
+ if (isStatefulPattern) {
232
+ pattern.lastIndex = 0;
233
+ }
234
+ if (match?.[1]) {
235
+ return match[1].trim();
236
+ }
237
+ return void 0;
238
+ }
239
+ function extractFromRequest(req) {
240
+ if (typeof req.version === "string" && req.version.trim().length > 0) {
241
+ return req.version.trim();
242
+ }
243
+ return void 0;
244
+ }
245
+ function createVersionExtractor(config) {
246
+ const { sources, header, query, path, custom } = config.extraction;
247
+ return (req) => {
248
+ const requestVersion = extractFromRequest(req);
249
+ if (requestVersion) {
250
+ return { version: requestVersion, source: "custom" };
251
+ }
252
+ for (const source of sources) {
253
+ let version;
254
+ switch (source) {
255
+ case "header":
256
+ version = extractFromHeader(req, header.name);
257
+ break;
258
+ case "query":
259
+ version = extractFromQuery(req, query.name);
260
+ break;
261
+ case "path":
262
+ version = extractFromPath(req, path.pattern);
263
+ break;
264
+ case "custom":
265
+ version = custom?.(req);
266
+ break;
267
+ }
268
+ if (version) {
269
+ return { version, source };
270
+ }
271
+ }
272
+ return void 0;
273
+ };
274
+ }
275
+
276
+ // src/version-parser.ts
277
+ var VERSION_REGEX = /^(\^|~)?(\d+)(?:\.(\d+))?(?:\.(\d+))?$/;
278
+ function getSpecifiedComponentCount(rawRange) {
279
+ const withoutPrefix = rawRange.replace(/^[\^~]/, "");
280
+ const count = withoutPrefix.split(".").length;
281
+ if (count <= 1) {
282
+ return 1;
283
+ }
284
+ if (count === 2) {
285
+ return 2;
286
+ }
287
+ return 3;
288
+ }
289
+ function parseVersion(version) {
290
+ const trimmed = version.trim();
291
+ const match = VERSION_REGEX.exec(trimmed);
292
+ if (!match) {
293
+ return null;
294
+ }
295
+ const [, , majorStr, minorStr, patchStr] = match;
296
+ const major = parseInt(majorStr ?? "0", 10);
297
+ const minor = parseInt(minorStr ?? "0", 10);
298
+ const patch = parseInt(patchStr ?? "0", 10);
299
+ if (isNaN(major) || isNaN(minor) || isNaN(patch)) {
300
+ return null;
301
+ }
302
+ if (major < 0 || minor < 0 || patch < 0) {
303
+ return null;
304
+ }
305
+ return {
306
+ major,
307
+ minor,
308
+ patch,
309
+ raw: trimmed
310
+ };
311
+ }
312
+ function parseVersionRange(range) {
313
+ const trimmed = range.trim();
314
+ const match = VERSION_REGEX.exec(trimmed);
315
+ if (!match) {
316
+ return null;
317
+ }
318
+ const [, prefix, majorStr, minorStr, patchStr] = match;
319
+ const major = parseInt(majorStr ?? "0", 10);
320
+ const minor = parseInt(minorStr ?? "0", 10);
321
+ const patch = parseInt(patchStr ?? "0", 10);
322
+ if (isNaN(major) || isNaN(minor) || isNaN(patch)) {
323
+ return null;
324
+ }
325
+ let type;
326
+ if (prefix === "^") {
327
+ type = "caret";
328
+ } else if (prefix === "~") {
329
+ type = "tilde";
330
+ } else {
331
+ type = "exact";
332
+ }
333
+ return {
334
+ type,
335
+ version: { major, minor, patch, raw: trimmed.replace(/^[\^~]/, "") },
336
+ raw: trimmed
337
+ };
338
+ }
339
+ function versionSatisfies(clientVersion, range) {
340
+ const { major: cMajor, minor: cMinor, patch: cPatch } = clientVersion;
341
+ const { major: rMajor, minor: rMinor, patch: rPatch } = range.version;
342
+ switch (range.type) {
343
+ case "caret": {
344
+ if (cMajor !== rMajor) {
345
+ return false;
346
+ }
347
+ if (rMajor > 0) {
348
+ if (cMinor < rMinor) {
349
+ return false;
350
+ }
351
+ if (cMinor === rMinor && cPatch < rPatch) {
352
+ return false;
353
+ }
354
+ return true;
355
+ }
356
+ if (rMinor > 0) {
357
+ return cMinor === rMinor && cPatch >= rPatch;
358
+ }
359
+ const componentCount = getSpecifiedComponentCount(range.raw);
360
+ if (componentCount === 1) {
361
+ return true;
362
+ }
363
+ if (componentCount === 2) {
364
+ return cMinor === 0;
365
+ }
366
+ return cMinor === 0 && cPatch === rPatch;
367
+ }
368
+ case "tilde": {
369
+ if (cMajor !== rMajor || cMinor !== rMinor) {
370
+ return false;
371
+ }
372
+ return cPatch >= rPatch;
373
+ }
374
+ case "exact": {
375
+ return cMajor === rMajor && cMinor === rMinor && cPatch === rPatch;
376
+ }
377
+ }
378
+ }
379
+ function compareVersions(a, b) {
380
+ if (a.major !== b.major) {
381
+ return a.major > b.major ? 1 : -1;
382
+ }
383
+ if (a.minor !== b.minor) {
384
+ return a.minor > b.minor ? 1 : -1;
385
+ }
386
+ if (a.patch !== b.patch) {
387
+ return a.patch > b.patch ? 1 : -1;
388
+ }
389
+ return 0;
390
+ }
391
+ function findLatestVersion(versions) {
392
+ if (versions.length === 0) {
393
+ return null;
394
+ }
395
+ let latest = null;
396
+ let latestRaw = "";
397
+ for (const version of versions) {
398
+ const range = parseVersionRange(version);
399
+ if (!range) {
400
+ continue;
401
+ }
402
+ if (!latest || compareVersions(range.version, latest) > 0) {
403
+ latest = range.version;
404
+ latestRaw = range.version.raw;
405
+ }
406
+ }
407
+ return latestRaw || null;
408
+ }
409
+ function isValidVersion(version) {
410
+ return parseVersion(version) !== null;
411
+ }
412
+ function isValidVersionRange(range) {
413
+ return parseVersionRange(range) !== null;
414
+ }
415
+ function normalizeVersion(version) {
416
+ const range = parseVersionRange(version);
417
+ if (!range) {
418
+ return null;
419
+ }
420
+ const { major, minor, patch } = range.version;
421
+ return `${major.toString()}.${minor.toString()}.${patch.toString()}`;
422
+ }
423
+
424
+ // src/handler-compiler.ts
425
+ function calculatePriority(handler) {
426
+ const { range } = handler;
427
+ const { major, minor, patch } = range.version;
428
+ const versionValue = major * 1e6 + minor * 1e3 + patch;
429
+ switch (range.type) {
430
+ case "exact":
431
+ return 1e9 + versionValue;
432
+ case "tilde":
433
+ return 5e8 + versionValue;
434
+ case "caret":
435
+ return versionValue;
436
+ }
437
+ }
438
+ function compileHandlers(handlers, validate = true) {
439
+ const compiled = [];
440
+ for (const [key, handler] of Object.entries(handlers)) {
441
+ if (validate && typeof handler !== "function") {
442
+ throw createInvalidHandlerError(key, "handler must be a function");
443
+ }
444
+ const range = parseVersionRange(key);
445
+ if (!range) {
446
+ if (validate) {
447
+ throw createInvalidHandlerError(
448
+ key,
449
+ 'invalid version format. Expected: "1.0.0", "^1.0", "~1.2", etc.'
450
+ );
451
+ }
452
+ continue;
453
+ }
454
+ const compiledHandler = {
455
+ key,
456
+ range,
457
+ handler,
458
+ priority: 0
459
+ // Will be calculated after
460
+ };
461
+ compiledHandler.priority = calculatePriority(compiledHandler);
462
+ compiled.push(compiledHandler);
463
+ }
464
+ compiled.sort((a, b) => b.priority - a.priority);
465
+ return compiled;
466
+ }
467
+ function findMatchingHandler(clientVersion, compiledHandlers) {
468
+ for (const handler of compiledHandlers) {
469
+ if (versionSatisfies(clientVersion, handler.range)) {
470
+ return handler;
471
+ }
472
+ }
473
+ return void 0;
474
+ }
475
+ function findLatestHandler(compiledHandlers) {
476
+ if (compiledHandlers.length === 0) {
477
+ return void 0;
478
+ }
479
+ let latest;
480
+ for (const handler of compiledHandlers) {
481
+ if (!latest || compareVersions(handler.range.version, latest.range.version) > 0) {
482
+ latest = handler;
483
+ }
484
+ }
485
+ return latest;
486
+ }
487
+ function getAvailableVersions(compiledHandlers) {
488
+ return compiledHandlers.map((h) => h.key);
489
+ }
490
+
491
+ // src/middleware.ts
492
+ function sendErrorResponse(error, req, res, next, config) {
493
+ if (config.errorResponse.onError) {
494
+ const handled = config.errorResponse.onError(error, req, res, next);
495
+ if (handled === true) {
496
+ return;
497
+ }
498
+ }
499
+ const response = {
500
+ error: error.code,
501
+ message: error.message
502
+ };
503
+ if (config.errorResponse.includeRequestedVersion && error.requestedVersion) {
504
+ response["requestedVersion"] = error.requestedVersion;
505
+ }
506
+ if (error.availableVersions && error.availableVersions.length > 0) {
507
+ response["availableVersions"] = error.availableVersions;
508
+ }
509
+ res.status(error.statusCode).json(response);
510
+ }
511
+ function getVersionNotFoundMessage(version, config) {
512
+ const message = config.errorResponse.versionNotFoundMessage;
513
+ if (typeof message === "function") {
514
+ return message(version);
515
+ }
516
+ return message;
517
+ }
518
+ function getMissingVersionMessage(config) {
519
+ return config.errorResponse.missingVersionMessage;
520
+ }
521
+ function versioningMiddleware(handlers, options) {
522
+ if (Array.isArray(handlers)) {
523
+ throw createInvalidConfigurationError("'handlers' must be a non-null, non-array object");
524
+ }
525
+ const config = freezeConfig(resolveConfig(options));
526
+ const compiledHandlers = compileHandlers(handlers, config.validateHandlers);
527
+ if (compiledHandlers.length === 0) {
528
+ throw createInvalidConfigurationError(
529
+ "No valid handlers provided. At least one handler is required."
530
+ );
531
+ }
532
+ const extractVersion = createVersionExtractor(config);
533
+ const availableVersions = getAvailableVersions(compiledHandlers);
534
+ return (req, res, next) => {
535
+ const extraction = extractVersion(req);
536
+ if (!extraction) {
537
+ if (!config.requireVersion) {
538
+ handleFallback(
539
+ void 0,
540
+ void 0,
541
+ compiledHandlers,
542
+ config,
543
+ availableVersions,
544
+ req,
545
+ res,
546
+ next
547
+ );
548
+ return;
549
+ }
550
+ const error = createMissingVersionError(
551
+ config.errorResponse.missingVersionStatus,
552
+ getMissingVersionMessage(config)
553
+ );
554
+ sendErrorResponse(error, req, res, next, config);
555
+ return;
556
+ }
557
+ const { version: versionString, source } = extraction;
558
+ const clientVersion = parseVersion(versionString);
559
+ if (!clientVersion) {
560
+ const error = createInvalidVersionFormatError(versionString);
561
+ sendErrorResponse(error, req, res, next, config);
562
+ return;
563
+ }
564
+ const matchedHandler = findMatchingHandler(clientVersion, compiledHandlers);
565
+ if (matchedHandler) {
566
+ if (config.attachVersionInfo) {
567
+ req.versionInfo = {
568
+ requested: versionString,
569
+ matched: matchedHandler.key,
570
+ source
571
+ };
572
+ }
573
+ executeHandler(matchedHandler, req, res, next);
574
+ return;
575
+ }
576
+ handleFallback(
577
+ versionString,
578
+ source,
579
+ compiledHandlers,
580
+ config,
581
+ availableVersions,
582
+ req,
583
+ res,
584
+ next
585
+ );
586
+ };
587
+ }
588
+ function handleFallback(requestedVersion, requestedSource, compiledHandlers, config, availableVersions, req, res, next) {
589
+ switch (config.fallbackStrategy) {
590
+ case "none": {
591
+ const error = createVersionNotFoundError(
592
+ requestedVersion ?? "unknown",
593
+ availableVersions,
594
+ config.errorResponse.versionNotFoundStatus
595
+ );
596
+ error.message = getVersionNotFoundMessage(requestedVersion ?? "unknown", config);
597
+ sendErrorResponse(error, req, res, next, config);
598
+ break;
599
+ }
600
+ case "latest": {
601
+ const latestHandler = findLatestHandler(compiledHandlers);
602
+ if (latestHandler) {
603
+ if (config.attachVersionInfo && requestedVersion) {
604
+ req.versionInfo = {
605
+ requested: requestedVersion,
606
+ matched: latestHandler.key,
607
+ source: requestedSource ?? "custom"
608
+ };
609
+ }
610
+ executeHandler(latestHandler, req, res, next);
611
+ } else {
612
+ const error = createVersionNotFoundError(
613
+ requestedVersion ?? "unknown",
614
+ availableVersions,
615
+ config.errorResponse.versionNotFoundStatus
616
+ );
617
+ sendErrorResponse(error, req, res, next, config);
618
+ }
619
+ break;
620
+ }
621
+ case "default": {
622
+ if (config.defaultHandler) {
623
+ if (config.attachVersionInfo && requestedVersion) {
624
+ req.versionInfo = {
625
+ requested: requestedVersion,
626
+ matched: "default",
627
+ source: requestedSource ?? "custom"
628
+ };
629
+ }
630
+ executeRequestHandler(config.defaultHandler, req, res, next);
631
+ } else {
632
+ const latestHandler = findLatestHandler(compiledHandlers);
633
+ if (latestHandler) {
634
+ if (config.attachVersionInfo && requestedVersion) {
635
+ req.versionInfo = {
636
+ requested: requestedVersion,
637
+ matched: latestHandler.key,
638
+ source: requestedSource ?? "custom"
639
+ };
640
+ }
641
+ executeHandler(latestHandler, req, res, next);
642
+ } else {
643
+ const error = createVersionNotFoundError(
644
+ requestedVersion ?? "unknown",
645
+ availableVersions,
646
+ config.errorResponse.versionNotFoundStatus
647
+ );
648
+ sendErrorResponse(error, req, res, next, config);
649
+ }
650
+ }
651
+ break;
652
+ }
653
+ default: {
654
+ const error = createInvalidConfigurationError(
655
+ "Unsupported fallback strategy. Valid strategies: latest, none, default"
656
+ );
657
+ sendErrorResponse(error, req, res, next, config);
658
+ break;
659
+ }
660
+ }
661
+ }
662
+ function executeHandler(handler, req, res, next) {
663
+ try {
664
+ const result = handler.handler(req, res, next);
665
+ if (result instanceof Promise) {
666
+ result.catch((error) => {
667
+ next(error);
668
+ });
669
+ }
670
+ } catch (error) {
671
+ next(error);
672
+ }
673
+ }
674
+ function executeRequestHandler(handler, req, res, next) {
675
+ try {
676
+ const result = handler(req, res, next);
677
+ if (result instanceof Promise) {
678
+ void result.catch((error) => {
679
+ next(error);
680
+ });
681
+ }
682
+ } catch (error) {
683
+ next(error);
684
+ }
685
+ }
686
+
687
+ export { DEFAULT_CONFIG, VersioningError, compareVersions, createInvalidConfigurationError, createInvalidHandlerError, createInvalidVersionFormatError, createMissingVersionError, createVersionNotFoundError, versioningMiddleware as default, findLatestVersion, hasErrorCode, isValidVersion, isValidVersionRange, isVersioningError, normalizeVersion, parseVersion, parseVersionRange, versionSatisfies, versioningMiddleware };
688
+ //# sourceMappingURL=index.js.map
689
+ //# sourceMappingURL=index.js.map