express-version-api 1.0.1 β†’ 2.0.4

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/CHANGELOG.md ADDED
@@ -0,0 +1,40 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [2.0.0] - 2026-02-27
11
+
12
+ ### Removed
13
+
14
+ - Removed deprecated `createVersionMiddleware` API.
15
+ - Removed CommonJS default export path; CJS now uses named exports only.
16
+
17
+ ### Changed
18
+
19
+ - `test:types` now validates `test-types/**/*.test-d.ts` and runs in `validate`/CI.
20
+ - CI now targets `develop` and `main`, and PR checks use the actual base branch.
21
+ - `npm test` no longer writes coverage artifacts by default.
22
+ - Pre-commit hook now runs `lint-staged`.
23
+ - TypeScript incremental metadata moved outside publish output.
24
+ - Removed unused dev dependencies: `@types/semver`, `ts-node`.
25
+ - Updated README and package docs to match runtime behavior.
26
+
27
+ ### Fixed
28
+
29
+ - `fallbackStrategy` is now validated at config resolution.
30
+ - Async `defaultHandler` errors are forwarded to Express `next(error)`.
31
+ - Caret matching for `0.x` follows semver-compatible constraints.
32
+ - `missingVersionMessage` from config is now applied in responses.
33
+ - Path extraction is stable with global/sticky regex (`lastIndex` handling).
34
+ - `req.versionInfo.source` now preserves the original extraction source in fallback paths.
35
+
36
+ ## [1.0.6] - 2025-02-01
37
+
38
+ ### Added
39
+
40
+ - Stable baseline release published to npm.
package/LICENSE CHANGED
@@ -1,21 +1,23 @@
1
- MIT License
2
-
3
- Copyright (c) 2024 Braian Quintian
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ # MIT License
2
+
3
+ Copyright (c) 2025 Braian Quintian
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ For more information, see <https://github.com/Braian-Quintian/express-version-api>
package/README.md CHANGED
@@ -1,146 +1,224 @@
1
- # Express version api
2
-
3
- [![MIT License](https://img.shields.io/badge/License-MIT-green.svg)](https://github.com/Braian-Quintian/express-version-routes?tab=MIT-1-ov-file#readme)
4
-
5
- Express version api is a simple library that allows you to create versioned routes in your Express.js application. It provides a middleware function that allows you to define different route handlers based on the requested API version. This can be useful when you need to maintain multiple versions of an API and serve different responses based on the version number specified by the client.
6
-
7
- **πŸ›‘Note:** This library is intended for personal use and experimentation, and is **_not recommended_** for production environments or widespread adoption.
8
-
9
- # 🚧 Under Development 🚧
10
-
11
- **This library is actively being developed. Improvements and new features are added regularly. As such, there's no stable version and changes are frequent. Please consider this when using the library.**
12
-
13
- ## Installation
14
-
15
- ```bash
16
- npm install express-version-api
17
- ```
18
-
19
- ## Disclaimer
20
-
21
- **⚠️ Disclaimer: This library is intended for personal use and experimentation. While it is released under the MIT license, allowing anyone to use and modify it, please note the following considerations:**
22
-
23
- - **Not Recommended for Production:** This library is designed for educational and personal use. It is not optimized for production environments or widespread adoption. Use in production settings is discouraged.
24
-
25
- - **Limited Support and Maintenance:** As this is a personal project, there may be limited ongoing support or maintenance. Contributors are welcome, but please manage expectations accordingly.
26
-
27
- - **Not a Replacement for Established Libraries:** This library is not intended to replace established or widely used libraries for API versioning in production applications. Consider using dedicated solutions with robust community support for production environments.
28
-
29
- ---
30
-
31
- ## Usage
32
-
33
- > You can use the `versionApi` middleware to create versioned routes in your Express.js application. The `versionApi` middleware accepts an object with the following properties:
34
-
35
- - `version` (string): The version of the API.
36
- - `function` (function): The function that will be called when the route is accessed.
37
-
38
- > Follows semver versioning format. Supports '^, ~' symbols for matching version numbers.
39
-
40
- ### Example basic:
41
-
42
- ```javascript
43
- const express = require("express");
44
- const versionApi = require("express-version-api");
45
- const app = express();
46
-
47
- // Define your route with versioned handlers
48
- app.get(
49
- "/api",
50
- versionApi({
51
- "1.0.0": functionV1, // Route handler for API version 1.0.0
52
- "2.0.0": functionV2, // Route handler for API version 2.0.0
53
- })
54
- );
55
-
56
- // Handler for version 1.0.0
57
- function functionV1(req, res) {
58
- res.send("This is version 1.0.0"); // Sends a response for API version 1.0.0
59
- }
60
-
61
- // Handler for version 2.0.0
62
- function functionV2(req, res) {
63
- res.send("This is version 2.0.0"); // Sends a response for API version 2.0.0
64
- }
65
-
66
- app.listen(3000, () => {
67
- console.log("Server is running on port 3000");
68
- });
69
- ```
70
-
71
- ### Example using '^, ~' semver symbols:
72
-
73
- > The `^` symbol is used to match the specified version and any minor or patch updates. The `~` symbol is used to match the specified version and any patch updates.
74
-
75
- **Caret Operator** **_(^)_**: Matches the specified version and any minor or patch updates. For example, `^1.0.0` will match `1.0.0`, `1.1.0`, `1.1.1`, etc., but not `2.0.0`.
76
-
77
- **Tilde Operator** **_(~)_**: Matches the specified version and any patch updates. For example, ~1.0.0 will match `1.0.0`, `1.0.1`, `1.0.2`, etc., but not `1.1.0`.
78
-
79
- ```javascript
80
- const express = require("express");
81
- const versionApi = require("express-version-api");
82
- const app = express();
83
-
84
- // Define your route with versioned handlers
85
- app.get(
86
- "/api",
87
- versionApi({
88
- "^1.0.0": functionV1, // Route handler for API version 1.X.X Caret Operator
89
- "~2.0.0": functionV2, // Route handler for API version 2.0.X Tilde Operator
90
- })
91
- );
92
-
93
- // Handler for version 1.0.0
94
- function functionV1(req, res) {
95
- res.send("This is version 1.0.0"); // Sends a response for API version 1.X.X
96
- }
97
-
98
- // Handler for version 2.0.0
99
- function functionV2(req, res) {
100
- res.send("This is version 2.0.0"); // Sends a response for API version 2.0.X
101
- }
102
-
103
- app.listen(3000, () => {
104
- console.log("Server is running on port 3000");
105
- });
106
- ```
107
-
108
- ### Versioning via Headers
109
-
110
- To specify the desired API version, clients should include the `Accept-Version` header in their requests with the version number they want to access. Here's an example of how to set the Accept-Version header using curl:
111
-
112
- ```bash
113
- curl -H "Accept-Version: 1.0.0" http://localhost:3000/api
114
- ```
115
-
116
- In this example, the server will invoke functionV1 when the request specifies Accept-Version: 1.0.0 and functionV2 when Accept-Version: 2.0.0 is specified.
117
-
118
- Make sure to handle the Accept-Version header appropriately in your middleware or route handlers to serve the correct API version based on client preferences.
119
-
120
- ## Running Tests
121
-
122
- This library uses Jest for testing. To run the tests, you can use the following command:
123
-
124
- ```bash
125
- npm run test
126
- ```
127
-
128
- ---
129
-
130
- ## Roadmap
131
-
132
- - Added support for semver features🌟
133
- - Enhanced support for APIs starting with v1🌟
134
- - Add more integrations and examples🌟
135
-
136
- ### Development Status
137
-
138
- This library is currently under active development. We are continuously working on improving and adding new features to enhance its functionality.
139
-
140
- ## Contributing
141
-
142
- We welcome contributions! If you're interested in improving this library or adding new features, we'd love to receive your contributions.
143
-
144
- ## Feedback
145
-
146
- If you have any feedback, please reach out to us at bquintian.developer@gmail.com
1
+ # express-version-api
2
+
3
+ [![npm version](https://img.shields.io/npm/v/express-version-api.svg)](https://www.npmjs.com/package/express-version-api)
4
+ [![npm downloads](https://img.shields.io/npm/dm/express-version-api.svg)](https://www.npmjs.com/package/express-version-api)
5
+ [![Build Status](https://img.shields.io/github/actions/workflow/status/Braian-Quintian/express-version-api/ci.yml?branch=develop)](https://github.com/Braian-Quintian/express-version-api/actions)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](./LICENSE)
7
+
8
+ Version-aware middleware for Express.js with semantic version matching.
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ npm install express-version-api
14
+ ```
15
+
16
+ Requirements:
17
+
18
+ - Node.js >= 18
19
+ - Express >= 4
20
+
21
+ ## Quick Start
22
+
23
+ ```ts
24
+ import express from 'express';
25
+ import { versioningMiddleware } from 'express-version-api';
26
+
27
+ const app = express();
28
+
29
+ app.use(
30
+ '/api',
31
+ versioningMiddleware({
32
+ '^1': (_req, res) => {
33
+ res.json({ version: '1.x' });
34
+ },
35
+ '^2': (_req, res) => {
36
+ res.json({ version: '2.x' });
37
+ },
38
+ '3.0.0': (_req, res) => {
39
+ res.json({ version: '3.0.0' });
40
+ },
41
+ })
42
+ );
43
+ ```
44
+
45
+ Request examples:
46
+
47
+ ```bash
48
+ curl -H "Accept-Version: 1.2.0" http://localhost:3000/api
49
+ curl -H "Accept-Version: 2.5.1" http://localhost:3000/api
50
+ curl -H "Accept-Version: 3.0.0" http://localhost:3000/api
51
+ ```
52
+
53
+ ## Import Modes
54
+
55
+ ESM:
56
+
57
+ ```ts
58
+ import versioningMiddleware, { parseVersion } from 'express-version-api';
59
+ ```
60
+
61
+ CommonJS:
62
+
63
+ ```js
64
+ const { versioningMiddleware, parseVersion } = require('express-version-api');
65
+ ```
66
+
67
+ ## Matching Rules
68
+
69
+ Supported handler keys:
70
+
71
+ - Exact: `1.2.3`
72
+ - Caret: `^1.2.3`
73
+ - Tilde: `~1.2.3`
74
+
75
+ Priority when multiple handlers match:
76
+
77
+ 1. Exact
78
+ 2. Tilde
79
+ 3. Caret
80
+
81
+ Notes:
82
+
83
+ - Caret behavior for `0.x` follows semver-compatible constraints.
84
+ - Versions like `1`, `1.2`, and `1.2.3` are accepted.
85
+
86
+ ## Version Extraction
87
+
88
+ Default extraction order:
89
+
90
+ 1. Header: `accept-version`
91
+ 2. Query: `v`
92
+
93
+ You can configure `header`, `query`, `path`, or `custom` sources.
94
+
95
+ ```ts
96
+ versioningMiddleware(
97
+ {
98
+ '^1': v1Handler,
99
+ '^2': v2Handler,
100
+ },
101
+ {
102
+ extraction: {
103
+ sources: ['header', 'query', 'path', 'custom'],
104
+ header: { name: 'x-api-version' },
105
+ query: { name: 'version' },
106
+ path: { pattern: /\/api\/v(\d+(?:\.\d+)?(?:\.\d+)?)\// },
107
+ custom: (req) => (req.hostname.startsWith('v2.') ? '2.0.0' : undefined),
108
+ },
109
+ }
110
+ );
111
+ ```
112
+
113
+ ## Configuration
114
+
115
+ Defaults:
116
+
117
+ - `requireVersion: true`
118
+ - `fallbackStrategy: 'default'`
119
+ - `attachVersionInfo: true`
120
+ - `validateHandlers: true`
121
+ - `errorResponse.missingVersionStatus: 422`
122
+ - `errorResponse.versionNotFoundStatus: 422`
123
+ - `errorResponse.missingVersionMessage: 'API version is required'`
124
+
125
+ ```ts
126
+ interface VersioningOptions {
127
+ extraction?: {
128
+ sources?: Array<'header' | 'query' | 'path' | 'custom'>;
129
+ header?: { name?: string };
130
+ query?: { name?: string };
131
+ path?: { pattern?: RegExp };
132
+ custom?: (req: Request) => string | undefined;
133
+ };
134
+ requireVersion?: boolean;
135
+ fallbackStrategy?: 'latest' | 'none' | 'default';
136
+ defaultHandler?: RequestHandler;
137
+ validateHandlers?: boolean;
138
+ attachVersionInfo?: boolean;
139
+ errorResponse?: {
140
+ missingVersionStatus?: number;
141
+ versionNotFoundStatus?: number;
142
+ missingVersionMessage?: string;
143
+ versionNotFoundMessage?: string | ((version: string) => string);
144
+ includeRequestedVersion?: boolean;
145
+ onError?: (
146
+ error: VersioningError,
147
+ req: Request,
148
+ res: Response,
149
+ next: NextFunction
150
+ ) => boolean | undefined;
151
+ };
152
+ }
153
+ ```
154
+
155
+ ## Fallback Strategies
156
+
157
+ - `none`: return `VERSION_NOT_FOUND` error.
158
+ - `latest`: execute the highest available version handler.
159
+ - `default`: execute `defaultHandler` when provided; otherwise falls back to `latest`.
160
+
161
+ ## Error Handling
162
+
163
+ Error codes:
164
+
165
+ - `MISSING_VERSION`
166
+ - `INVALID_VERSION_FORMAT`
167
+ - `VERSION_NOT_FOUND`
168
+ - `INVALID_CONFIGURATION`
169
+ - `INVALID_HANDLER`
170
+
171
+ Default error response shape:
172
+
173
+ ```json
174
+ {
175
+ "error": "VERSION_NOT_FOUND",
176
+ "message": "No handler found for the requested API version",
177
+ "requestedVersion": "99.0.0",
178
+ "availableVersions": ["^1", "^2"]
179
+ }
180
+ ```
181
+
182
+ ## Version Info Metadata
183
+
184
+ When `attachVersionInfo` is enabled, the middleware sets `req.versionInfo`:
185
+
186
+ ```ts
187
+ {
188
+ requested: string;
189
+ matched: string;
190
+ source: 'header' | 'query' | 'path' | 'custom';
191
+ }
192
+ ```
193
+
194
+ ## API
195
+
196
+ Main exports:
197
+
198
+ - `versioningMiddleware`
199
+ - `parseVersion`
200
+ - `parseVersionRange`
201
+ - `versionSatisfies`
202
+ - `compareVersions`
203
+ - `findLatestVersion`
204
+ - `isValidVersion`
205
+ - `isValidVersionRange`
206
+ - `normalizeVersion`
207
+ - `VersioningError`
208
+ - `DEFAULT_CONFIG`
209
+
210
+ ## Breaking Changes (v2.0.0)
211
+
212
+ - Removed legacy `createVersionMiddleware` API.
213
+ - CommonJS consumers must use named exports (no default export in CJS).
214
+
215
+ ## Development
216
+
217
+ ```bash
218
+ npm install
219
+ npm run validate
220
+ ```
221
+
222
+ ## License
223
+
224
+ MIT