beavuck-time 2.5.4 → 3.0.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 +4 -2
- package/build/config/corsOptions.js +2 -13
- package/build/config/logger.js +0 -9
- package/build/errors/beavuckTimeServerError.js +1 -1
- package/build/middlewares/corsMiddleware.js +1 -2
- package/build/middlewares/rateLimiter.js +1 -3
- package/build/server.js +8 -13
- package/openapi/swagger.json +1 -1
- package/package.json +13 -14
package/README.md
CHANGED
|
@@ -68,7 +68,7 @@ projects. On Docker Hub, while you're developing, you should use the `beavuck/ti
|
|
|
68
68
|
version.
|
|
69
69
|
|
|
70
70
|
When the time comes to go to production, to protect yourself from surprise breaking changes, you should instead point to
|
|
71
|
-
specific minor version tags, such as `beavuck/time:
|
|
71
|
+
specific minor version tags, such as `beavuck/time:3.0` : those will not get breaking changes, but they will get
|
|
72
72
|
security upgrades and bug fixes while they're active.
|
|
73
73
|
|
|
74
74
|
### Ⓝ NPM
|
|
@@ -115,6 +115,8 @@ Refer to the Docker Compose example below to see an exhaustive list of available
|
|
|
115
115
|
(The section below supposes you're using a Docker image. If using the npm package, you can set those environment variable
|
|
116
116
|
on the host directly, instead of doing so in the container like detailed below)
|
|
117
117
|
|
|
118
|
+
> **Note:** The Docker image does not include a `.env` file. All configuration must be passed via environment variables at runtime.
|
|
119
|
+
|
|
118
120
|
To run the service in a docker-compose environment, add this in your `docker-compose.yml`'s services section:
|
|
119
121
|
|
|
120
122
|
```yaml
|
|
@@ -164,7 +166,7 @@ docker compose up -d
|
|
|
164
166
|
|
|
165
167
|
Now, when you run:
|
|
166
168
|
|
|
167
|
-
```
|
|
169
|
+
```
|
|
168
170
|
curl --location 'http://localhost:{{SOME_PORT_NUMBER}}/now' \
|
|
169
171
|
--header 'Origin: {{SOME_TRUSTED_ORIGIN}}'
|
|
170
172
|
```
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// src/config/corsOptions.ts
|
|
3
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
-
};
|
|
6
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
4
|
exports.corsOptions = void 0;
|
|
8
5
|
exports.getHostUrl = getHostUrl;
|
|
@@ -14,20 +11,12 @@ exports.isOriginAbsentOrTrusted = isOriginAbsentOrTrusted;
|
|
|
14
11
|
const corsError_1 = require("../errors/corsError");
|
|
15
12
|
const urlUtil_1 = require("../utils/urlUtil");
|
|
16
13
|
const http_status_codes_1 = require("http-status-codes");
|
|
17
|
-
const dotenvx_1 = __importDefault(require("@dotenvx/dotenvx"));
|
|
18
|
-
// Load environment variables from .env file, if available
|
|
19
|
-
// but don't error if the file is missing
|
|
20
|
-
dotenvx_1.default.config({
|
|
21
|
-
ignore: ['MISSING_ENV_FILE'],
|
|
22
|
-
});
|
|
23
14
|
exports.corsOptions = {
|
|
24
15
|
methods: ['GET', 'OPTIONS'],
|
|
25
16
|
optionsSuccessStatus: http_status_codes_1.StatusCodes.OK,
|
|
26
17
|
origin: (origin, callback) => {
|
|
27
|
-
if (isAllTrusted() ||
|
|
28
|
-
|
|
29
|
-
isOriginAbsentOrTrusted(origin)) {
|
|
30
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
18
|
+
if (isAllTrusted() || (0, urlUtil_1.isSameOrigin)(getHostUrl(), (0, urlUtil_1.tryParseUrl)(origin)) || isOriginAbsentOrTrusted(origin)) {
|
|
19
|
+
// eslint-disable-next-line no-restricted-syntax -- the http external library expects null
|
|
31
20
|
callback(null, true);
|
|
32
21
|
}
|
|
33
22
|
else {
|
package/build/config/logger.js
CHANGED
|
@@ -1,18 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
// src/config/logger.ts
|
|
3
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
-
};
|
|
6
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
4
|
exports.logger = void 0;
|
|
8
5
|
const winston_1 = require("winston");
|
|
9
6
|
require("winston-daily-rotate-file");
|
|
10
|
-
const dotenvx_1 = __importDefault(require("@dotenvx/dotenvx"));
|
|
11
|
-
// Load environment variables from .env file, if available
|
|
12
|
-
// but don't error if the file is missing
|
|
13
|
-
dotenvx_1.default.config({
|
|
14
|
-
ignore: ['MISSING_ENV_FILE'],
|
|
15
|
-
});
|
|
16
7
|
const LOGS_DIR = 'beavuck-time-logs';
|
|
17
8
|
const LOG_LEVEL = process.env.BEAVUCK_TIME_LOG_LEVEL ?? 'info';
|
|
18
9
|
const MAX_LOG_FILES = process.env.BEAVUCK_TIME_MAX_LOG_FILES ?? 64;
|
|
@@ -10,7 +10,7 @@ class BeavuckTimeServerError extends beavuckTimeError_1.BeavuckTimeError {
|
|
|
10
10
|
super(`${BeavuckTimeServerError.baseMessage}: ${message}`, code);
|
|
11
11
|
}
|
|
12
12
|
static fromError(error) {
|
|
13
|
-
return error instanceof BeavuckTimeServerError ? error :
|
|
13
|
+
return error instanceof BeavuckTimeServerError ? error : new BeavuckTimeServerError(error.message);
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
exports.BeavuckTimeServerError = BeavuckTimeServerError;
|
|
@@ -20,8 +20,7 @@ const corsMiddleware = (req, res, next) => {
|
|
|
20
20
|
(0, cors_1.default)(corsOptions_1.corsOptions)(req, res, next);
|
|
21
21
|
}
|
|
22
22
|
else if (!HOST_URL) {
|
|
23
|
-
|
|
24
|
-
next(new beavuckTimeServerError_1.BeavuckTimeServerError(noHostUrl));
|
|
23
|
+
next(new beavuckTimeServerError_1.BeavuckTimeServerError('Host URL not set'));
|
|
25
24
|
}
|
|
26
25
|
else if ((0, urlUtil_1.isSameOrigin)(HOST_URL, (0, urlUtil_1.tryParseUrl)(referrerHeader ?? ''))) {
|
|
27
26
|
next();
|
|
@@ -11,6 +11,4 @@ const RATE_LIMIT = Number.parseInt(process.env.BEAVUCK_TIME_RATE_LIMIT ?? NO_RAT
|
|
|
11
11
|
const SECONDS_IN_ONE_MINUTE = 60;
|
|
12
12
|
const MILLISECONDS_IN_ONE_SECOND = 1000;
|
|
13
13
|
const ONE_MINUTE = SECONDS_IN_ONE_MINUTE * MILLISECONDS_IN_ONE_SECOND;
|
|
14
|
-
exports.rateLimiter = RATE_LIMIT > 0 ?
|
|
15
|
-
(0, express_rate_limit_1.default)({ windowMs: ONE_MINUTE, limit: RATE_LIMIT })
|
|
16
|
-
: (_req, _res, next) => next();
|
|
14
|
+
exports.rateLimiter = RATE_LIMIT > 0 ? (0, express_rate_limit_1.default)({ windowMs: ONE_MINUTE, limit: RATE_LIMIT }) : (_req, _res, next) => next();
|
package/build/server.js
CHANGED
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
3
|
// src/server.ts
|
|
4
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
5
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
6
|
-
};
|
|
7
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
5
|
exports.startServer = startServer;
|
|
9
6
|
const api_1 = require("./api");
|
|
10
7
|
const logger_1 = require("./config/logger");
|
|
11
8
|
const urlUtil_1 = require("./utils/urlUtil");
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
9
|
+
try {
|
|
10
|
+
process.loadEnvFile();
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
// .env file is optional
|
|
14
|
+
}
|
|
18
15
|
function startServer(options = {}) {
|
|
19
16
|
manageEnvVars(options);
|
|
20
17
|
const server = api_1.api.listen(process.env.BEAVUCK_TIME_API_PORT, () => {
|
|
@@ -50,13 +47,11 @@ function startServer(options = {}) {
|
|
|
50
47
|
}
|
|
51
48
|
function manageEnvVars(options) {
|
|
52
49
|
logger_1.logger.info('serverOptions: ' + JSON.stringify(options));
|
|
53
|
-
process.env.BEAVUCK_TIME_API_PORT =
|
|
54
|
-
options.apiPort === undefined ? '3000' : String(options.apiPort);
|
|
50
|
+
process.env.BEAVUCK_TIME_API_PORT = options.apiPort === undefined ? '3000' : String(options.apiPort);
|
|
55
51
|
logger_1.logger.debug('API_PORT: ' + process.env.BEAVUCK_TIME_API_PORT);
|
|
56
52
|
process.env.BEAVUCK_TIME_HOST_URL = options.hostUrl ?? process.env.BEAVUCK_TIME_HOST_URL;
|
|
57
53
|
logger_1.logger.debug('HOST_URL: ' + process.env.BEAVUCK_TIME_HOST_URL);
|
|
58
|
-
process.env.BEAVUCK_TIME_TRUSTED_ORIGINS =
|
|
59
|
-
options.trustedOrigins ?? process.env.BEAVUCK_TIME_TRUSTED_ORIGINS;
|
|
54
|
+
process.env.BEAVUCK_TIME_TRUSTED_ORIGINS = options.trustedOrigins ?? process.env.BEAVUCK_TIME_TRUSTED_ORIGINS;
|
|
60
55
|
logger_1.logger.debug('TRUSTED_ORIGINS: ' + process.env.BEAVUCK_TIME_TRUSTED_ORIGINS);
|
|
61
56
|
validateEnv();
|
|
62
57
|
}
|
package/openapi/swagger.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "beavuck-time",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.1",
|
|
4
4
|
"description": "Get time in ISO format, in UTC timezone, from a simple, lightweight node server",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"time",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"beavuck-time": "build/server.js"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
|
-
"run-integration-tests": "cd api-tests/bruno &&
|
|
36
|
+
"run-integration-tests": "cd api-tests/bruno && npx --yes @usebruno/cli run --env local --bail",
|
|
37
37
|
"up-patch": "npm version patch --no-git-tag-version",
|
|
38
38
|
"up-minor": "npm version minor --no-git-tag-version",
|
|
39
39
|
"up-major": "npm version major --no-git-tag-version",
|
|
@@ -43,13 +43,12 @@
|
|
|
43
43
|
"typecheck": "tsc --noEmit",
|
|
44
44
|
"format": "prettier --write src/ --log-level warn",
|
|
45
45
|
"clean": "npm run lint && npm run typecheck && npm run format",
|
|
46
|
-
"test": "
|
|
46
|
+
"test": "node --env-file=.env.test node_modules/.bin/jest --coverage",
|
|
47
47
|
"build": "tsoa spec-and-routes && tsc",
|
|
48
48
|
"start": "node build/server.js",
|
|
49
49
|
"go": "rm -rf build && npm install && npm run build && npm run clean && npm run test && npm run start"
|
|
50
50
|
},
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@dotenvx/dotenvx": "^1.52.0",
|
|
53
52
|
"cors": "^2.8.6",
|
|
54
53
|
"express": "^5.2.1",
|
|
55
54
|
"express-rate-limit": "^8.2.1",
|
|
@@ -60,31 +59,31 @@
|
|
|
60
59
|
"winston-daily-rotate-file": "^5.0.0"
|
|
61
60
|
},
|
|
62
61
|
"devDependencies": {
|
|
63
|
-
"@eslint/js": "^
|
|
62
|
+
"@eslint/js": "^10.0.1",
|
|
64
63
|
"@types/cors": "^2.8.19",
|
|
65
64
|
"@types/express": "^5.0.6",
|
|
66
65
|
"@types/jest": "^30.0.0",
|
|
67
|
-
"@types/node": "^25.
|
|
68
|
-
"@types/supertest": "^
|
|
69
|
-
"eslint": "^
|
|
70
|
-
"globals": "^17.
|
|
66
|
+
"@types/node": "^25.3.2",
|
|
67
|
+
"@types/supertest": "^7.2.0",
|
|
68
|
+
"eslint": "^10.0.2",
|
|
69
|
+
"globals": "^17.3.0",
|
|
71
70
|
"jest": "^30.2.0",
|
|
72
|
-
"nodemon": "^3.1.
|
|
73
|
-
"npm-check-updates": "^19.
|
|
71
|
+
"nodemon": "^3.1.14",
|
|
72
|
+
"npm-check-updates": "^19.6.2",
|
|
74
73
|
"prettier": "3.8.1",
|
|
75
74
|
"supertest": "^7.2.2",
|
|
76
75
|
"ts-jest": "^29.4.6",
|
|
77
76
|
"ts-node": "^10.9.2",
|
|
78
77
|
"typescript": "^5.9.3",
|
|
79
|
-
"typescript-eslint": "^8.
|
|
78
|
+
"typescript-eslint": "^8.56.1"
|
|
80
79
|
},
|
|
81
80
|
"engines": {
|
|
82
|
-
"node": ">=
|
|
81
|
+
"node": ">=20.12.0"
|
|
83
82
|
},
|
|
84
83
|
"prettier": {
|
|
85
84
|
"experimentalTernaries": true,
|
|
86
85
|
"semi": false,
|
|
87
|
-
"printWidth":
|
|
86
|
+
"printWidth": 120,
|
|
88
87
|
"tabWidth": 2,
|
|
89
88
|
"useTabs": false,
|
|
90
89
|
"singleQuote": true,
|