@blamejs/core 0.7.4 → 0.7.18
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 +423 -395
- package/README.md +150 -149
- package/bin/blamejs.js +0 -0
- package/index.js +308 -284
- package/lib/api-key.js +660 -663
- package/lib/api-snapshot.js +338 -338
- package/lib/app-shutdown.js +385 -385
- package/lib/app.js +365 -365
- package/lib/archive.js +250 -250
- package/lib/atomic-file.js +544 -544
- package/lib/audit-chain.js +177 -177
- package/lib/audit-sign.js +344 -344
- package/lib/audit-tools.js +677 -677
- package/lib/audit.js +766 -766
- package/lib/auth/jwt.js +311 -311
- package/lib/auth/lockout.js +436 -436
- package/lib/auth/oauth.js +721 -721
- package/lib/auth/passkey.js +181 -181
- package/lib/auth/password.js +594 -594
- package/lib/backup/bundle.js +217 -217
- package/lib/backup/crypto.js +176 -176
- package/lib/backup/index.js +515 -515
- package/lib/backup/manifest.js +282 -282
- package/lib/break-glass.js +1338 -1338
- package/lib/bundler.js +441 -441
- package/lib/cache-redis.js +256 -256
- package/lib/cache.js +1206 -1206
- package/lib/canonical-json.js +115 -115
- package/lib/chain-writer.js +234 -234
- package/lib/cli-helpers.js +206 -206
- package/lib/cli.js +2334 -2334
- package/lib/cluster-provider-db.js +317 -317
- package/lib/cluster-storage.js +226 -226
- package/lib/cluster.js +703 -703
- package/lib/codepoint-class.js +196 -0
- package/lib/config-drift.js +301 -301
- package/lib/consent.js +222 -222
- package/lib/constants.js +191 -191
- package/lib/cookies.js +315 -315
- package/lib/credential-hash.js +322 -322
- package/lib/crypto.js +266 -266
- package/lib/csv.js +275 -286
- package/lib/db-declare-row-policy.js +267 -267
- package/lib/db-declare-view.js +420 -421
- package/lib/db-query.js +406 -406
- package/lib/db-schema.js +319 -319
- package/lib/db.js +1288 -1288
- package/lib/deprecate.js +222 -222
- package/lib/dev.js +335 -335
- package/lib/dual-control.js +473 -473
- package/lib/error-page.js +420 -420
- package/lib/external-db-migrate.js +441 -441
- package/lib/external-db.js +1061 -1061
- package/lib/file-type.js +273 -273
- package/lib/file-upload.js +213 -10
- package/lib/forms.js +422 -422
- package/lib/framework-error.js +293 -215
- package/lib/framework-schema.js +717 -717
- package/lib/gate-contract.js +971 -0
- package/lib/guard-all.js +405 -0
- package/lib/guard-archive.js +739 -0
- package/lib/guard-csv.js +816 -0
- package/lib/guard-email.js +744 -0
- package/lib/guard-filename.js +724 -0
- package/lib/guard-html.js +976 -0
- package/lib/guard-json.js +729 -0
- package/lib/guard-markdown.js +586 -0
- package/lib/guard-svg.js +976 -0
- package/lib/guard-xml.js +405 -0
- package/lib/guard-yaml.js +529 -0
- package/lib/handlers.js +350 -350
- package/lib/http-client-cookie-jar.js +508 -508
- package/lib/http-client.js +1195 -1195
- package/lib/i18n.js +878 -878
- package/lib/jobs.js +185 -185
- package/lib/log-stream-cloudwatch.js +369 -369
- package/lib/log-stream-local.js +146 -146
- package/lib/log-stream-otlp-grpc.js +410 -410
- package/lib/log-stream-otlp.js +286 -286
- package/lib/log-stream-syslog.js +302 -302
- package/lib/log-stream-webhook.js +199 -199
- package/lib/log-stream.js +330 -330
- package/lib/log.js +500 -500
- package/lib/mail-bounce.js +528 -528
- package/lib/mail-dkim.js +369 -362
- package/lib/mail.js +981 -962
- package/lib/metrics.js +683 -683
- package/lib/middleware/api-encrypt.js +936 -936
- package/lib/middleware/attach-user.js +157 -157
- package/lib/middleware/body-parser.js +1170 -1091
- package/lib/middleware/bot-guard.js +178 -178
- package/lib/middleware/compression.js +452 -452
- package/lib/middleware/cors.js +314 -314
- package/lib/middleware/csp-nonce.js +348 -348
- package/lib/middleware/csrf-protect.js +316 -316
- package/lib/middleware/db-role-for.js +264 -264
- package/lib/middleware/health.js +392 -392
- package/lib/middleware/index.js +79 -79
- package/lib/middleware/rate-limit.js +358 -358
- package/lib/middleware/request-id.js +61 -61
- package/lib/middleware/request-log.js +168 -168
- package/lib/middleware/require-auth.js +104 -104
- package/lib/middleware/security-headers.js +116 -116
- package/lib/middleware/sse.js +166 -166
- package/lib/migrations.js +383 -383
- package/lib/mtls-ca.js +518 -518
- package/lib/mtls-engine-default.js +481 -481
- package/lib/network-dns.js +632 -632
- package/lib/network-heartbeat.js +290 -290
- package/lib/network-nts.js +574 -574
- package/lib/network-proxy.js +265 -265
- package/lib/network-tls.js +328 -328
- package/lib/network.js +233 -233
- package/lib/notify.js +612 -612
- package/lib/ntp-check.js +229 -229
- package/lib/numeric-bounds.js +111 -91
- package/lib/object-store/azure-blob-bucket-ops.js +349 -349
- package/lib/object-store/azure-blob.js +488 -488
- package/lib/object-store/gcs-bucket-ops.js +351 -351
- package/lib/object-store/gcs.js +519 -519
- package/lib/object-store/http-put.js +153 -153
- package/lib/object-store/index.js +197 -197
- package/lib/object-store/sigv4-bucket-ops.js +1092 -1092
- package/lib/object-store/sigv4.js +903 -903
- package/lib/observability.js +151 -151
- package/lib/otel-export.js +269 -269
- package/lib/pagination.js +464 -464
- package/lib/parsers/index.js +80 -80
- package/lib/parsers/safe-env.js +642 -642
- package/lib/parsers/safe-ini.js +292 -292
- package/lib/parsers/safe-toml.js +784 -784
- package/lib/parsers/safe-xml.js +390 -390
- package/lib/parsers/safe-yaml.js +1015 -1015
- package/lib/permissions.js +708 -708
- package/lib/pqc-agent.js +87 -87
- package/lib/pqc-gate.js +279 -279
- package/lib/protobuf-encoder.js +190 -190
- package/lib/protocol-dispatcher.js +161 -161
- package/lib/pubsub-redis.js +167 -167
- package/lib/pubsub.js +429 -429
- package/lib/queue-local.js +476 -476
- package/lib/queue-redis.js +745 -745
- package/lib/queue-sqs.js +319 -319
- package/lib/queue.js +695 -695
- package/lib/redis-client.js +519 -519
- package/lib/request-helpers.js +340 -340
- package/lib/restore-bundle.js +237 -237
- package/lib/restore-rollback.js +259 -259
- package/lib/restore.js +409 -409
- package/lib/retry.js +376 -376
- package/lib/router.js +748 -748
- package/lib/safe-async.js +735 -735
- package/lib/safe-buffer.js +237 -237
- package/lib/safe-json.js +541 -541
- package/lib/safe-schema.js +1266 -1266
- package/lib/safe-url.js +159 -159
- package/lib/scheduler.js +706 -706
- package/lib/security-assert.js +373 -373
- package/lib/seeders.js +618 -618
- package/lib/session.js +478 -478
- package/lib/slug.js +269 -269
- package/lib/ssrf-guard.js +401 -401
- package/lib/static.js +184 -4
- package/lib/storage.js +471 -471
- package/lib/subject.js +281 -281
- package/lib/template.js +791 -791
- package/lib/testing.js +798 -798
- package/lib/time.js +310 -310
- package/lib/totp.js +302 -302
- package/lib/tracing.js +494 -494
- package/lib/uuid.js +132 -132
- package/lib/validate-opts.js +340 -319
- package/lib/vault/index.js +308 -308
- package/lib/vault/rotate.js +784 -784
- package/lib/vault/wrap.js +296 -296
- package/lib/vendor/noble-ciphers.cjs +9 -9
- package/lib/webhook.js +595 -595
- package/lib/websocket.js +1048 -1048
- package/package.json +77 -77
- package/sbom.cyclonedx.json +7 -7
package/lib/log-stream-local.js
CHANGED
|
@@ -1,146 +1,146 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Local file-based log sink with append-only journaling + rotation.
|
|
4
|
-
*
|
|
5
|
-
* Each event is written as one JSON line (jsonl format — one row per
|
|
6
|
-
* event). Files rotate by size (default 100 MiB) and/or age (default
|
|
7
|
-
* 7 days). Old rotations are gzip-compressed automatically and capped at
|
|
8
|
-
* a configured count (default 30) — older rotations are deleted.
|
|
9
|
-
*
|
|
10
|
-
* The active log file is opened in append mode and never updated in place.
|
|
11
|
-
* Operators can apply OS-level immutability (Linux chattr +a) to the
|
|
12
|
-
* directory if they want stronger tamper-resistance — the framework
|
|
13
|
-
* doesn't fight that; appends still work.
|
|
14
|
-
*
|
|
15
|
-
* Config:
|
|
16
|
-
* {
|
|
17
|
-
* dir: './logs/operational'
|
|
18
|
-
* maxFileBytes: C.BYTES.mib(100)
|
|
19
|
-
* maxFileAgeMs: C.TIME.days(7)
|
|
20
|
-
* keepRotations: 30
|
|
21
|
-
* compressRotations: true
|
|
22
|
-
* fileMode: 0o600
|
|
23
|
-
* fileNamePrefix: 'blamejs'
|
|
24
|
-
* }
|
|
25
|
-
*/
|
|
26
|
-
var fs = require("fs");
|
|
27
|
-
var path = require("path");
|
|
28
|
-
var zlib = require("zlib");
|
|
29
|
-
var atomicFile = require("./atomic-file");
|
|
30
|
-
var C = require("./constants");
|
|
31
|
-
var { boot } = require("./log");
|
|
32
|
-
var time = require("./time");
|
|
33
|
-
var { LogStreamError } = require("./framework-error");
|
|
34
|
-
|
|
35
|
-
var log = boot("log-stream-local");
|
|
36
|
-
|
|
37
|
-
var DEFAULTS = {
|
|
38
|
-
maxFileBytes: C.BYTES.mib(100),
|
|
39
|
-
maxFileAgeMs: C.TIME.days(7),
|
|
40
|
-
keepRotations: 30,
|
|
41
|
-
compressRotations: true,
|
|
42
|
-
fileMode: 0o600,
|
|
43
|
-
fileNamePrefix: "blamejs",
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
var _err = LogStreamError.factory;
|
|
47
|
-
|
|
48
|
-
function create(config) {
|
|
49
|
-
if (!config || !config.dir) throw new Error("log-stream local requires { dir }");
|
|
50
|
-
var cfg = Object.assign({}, DEFAULTS, config);
|
|
51
|
-
var dir = path.resolve(cfg.dir);
|
|
52
|
-
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
53
|
-
|
|
54
|
-
var activePath = path.join(dir, cfg.fileNamePrefix + ".log");
|
|
55
|
-
var fd = null;
|
|
56
|
-
var openedAt = 0;
|
|
57
|
-
var bytesWritten = 0;
|
|
58
|
-
|
|
59
|
-
function _open() {
|
|
60
|
-
fd = fs.openSync(activePath, "a", cfg.fileMode);
|
|
61
|
-
openedAt = Date.now();
|
|
62
|
-
try {
|
|
63
|
-
var stat = fs.fstatSync(fd);
|
|
64
|
-
bytesWritten = stat.size;
|
|
65
|
-
} catch (_e) {
|
|
66
|
-
bytesWritten = 0;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
_open();
|
|
70
|
-
|
|
71
|
-
function _shouldRotate() {
|
|
72
|
-
if (cfg.maxFileBytes && bytesWritten >= cfg.maxFileBytes) return true;
|
|
73
|
-
if (cfg.maxFileAgeMs && (Date.now() - openedAt) >= cfg.maxFileAgeMs) return true;
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function _rotate() {
|
|
78
|
-
try {
|
|
79
|
-
if (fd != null) {
|
|
80
|
-
try { fs.closeSync(fd); }
|
|
81
|
-
catch (e) { log.warn("rotate-close-failed: " + e.message); }
|
|
82
|
-
fd = null;
|
|
83
|
-
}
|
|
84
|
-
// Build rotated filename: blamejs-YYYYMMDDTHHMMSSZ.log
|
|
85
|
-
var stamp = time.toIso8601NoMs(new Date()).replace(/[-:]/g, "");
|
|
86
|
-
var rotated = path.join(dir, cfg.fileNamePrefix + "-" + stamp + ".log");
|
|
87
|
-
if (fs.existsSync(activePath)) {
|
|
88
|
-
fs.renameSync(activePath, rotated);
|
|
89
|
-
if (cfg.compressRotations) {
|
|
90
|
-
var data = fs.readFileSync(rotated);
|
|
91
|
-
var gz = zlib.gzipSync(data);
|
|
92
|
-
atomicFile.writeSync(rotated + ".gz", gz, { fileMode: cfg.fileMode });
|
|
93
|
-
fs.unlinkSync(rotated);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
_pruneOld();
|
|
97
|
-
} finally {
|
|
98
|
-
_open();
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
function _pruneOld() {
|
|
103
|
-
if (!cfg.keepRotations || cfg.keepRotations <= 0) return;
|
|
104
|
-
var entries = atomicFile.listDir(dir, {
|
|
105
|
-
filter: function (f) {
|
|
106
|
-
return f.startsWith(cfg.fileNamePrefix + "-") &&
|
|
107
|
-
(f.endsWith(".log") || f.endsWith(".log.gz"));
|
|
108
|
-
},
|
|
109
|
-
includeStat: true,
|
|
110
|
-
}).sort(function (a, b) { return b.mtimeMs - a.mtimeMs; }); // newest first
|
|
111
|
-
for (var i = cfg.keepRotations; i < entries.length; i++) {
|
|
112
|
-
try { fs.unlinkSync(entries[i].fullPath); } catch (_e) { /* best effort */ }
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function emit(record) {
|
|
117
|
-
if (_shouldRotate()) _rotate();
|
|
118
|
-
var line = JSON.stringify(record) + "\n";
|
|
119
|
-
var buf = Buffer.from(line, "utf8");
|
|
120
|
-
fs.writeSync(fd, buf, 0, buf.length, null);
|
|
121
|
-
bytesWritten += buf.length;
|
|
122
|
-
return Promise.resolve({ bytes: buf.length });
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function close() {
|
|
126
|
-
if (fd != null) {
|
|
127
|
-
try { fs.fsyncSync(fd); } catch (_e) { /* best effort */ }
|
|
128
|
-
try { fs.closeSync(fd); }
|
|
129
|
-
catch (e) { log.warn("close-failed: " + e.message); }
|
|
130
|
-
fd = null;
|
|
131
|
-
}
|
|
132
|
-
return Promise.resolve();
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function getActivePath() { return activePath; }
|
|
136
|
-
|
|
137
|
-
return {
|
|
138
|
-
protocol: "local",
|
|
139
|
-
emit: emit,
|
|
140
|
-
close: close,
|
|
141
|
-
rotate: function () { _rotate(); return Promise.resolve(); },
|
|
142
|
-
getActivePath: getActivePath,
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
module.exports = { create: create };
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Local file-based log sink with append-only journaling + rotation.
|
|
4
|
+
*
|
|
5
|
+
* Each event is written as one JSON line (jsonl format — one row per
|
|
6
|
+
* event). Files rotate by size (default 100 MiB) and/or age (default
|
|
7
|
+
* 7 days). Old rotations are gzip-compressed automatically and capped at
|
|
8
|
+
* a configured count (default 30) — older rotations are deleted.
|
|
9
|
+
*
|
|
10
|
+
* The active log file is opened in append mode and never updated in place.
|
|
11
|
+
* Operators can apply OS-level immutability (Linux chattr +a) to the
|
|
12
|
+
* directory if they want stronger tamper-resistance — the framework
|
|
13
|
+
* doesn't fight that; appends still work.
|
|
14
|
+
*
|
|
15
|
+
* Config:
|
|
16
|
+
* {
|
|
17
|
+
* dir: './logs/operational'
|
|
18
|
+
* maxFileBytes: C.BYTES.mib(100)
|
|
19
|
+
* maxFileAgeMs: C.TIME.days(7)
|
|
20
|
+
* keepRotations: 30
|
|
21
|
+
* compressRotations: true
|
|
22
|
+
* fileMode: 0o600
|
|
23
|
+
* fileNamePrefix: 'blamejs'
|
|
24
|
+
* }
|
|
25
|
+
*/
|
|
26
|
+
var fs = require("fs");
|
|
27
|
+
var path = require("path");
|
|
28
|
+
var zlib = require("zlib");
|
|
29
|
+
var atomicFile = require("./atomic-file");
|
|
30
|
+
var C = require("./constants");
|
|
31
|
+
var { boot } = require("./log");
|
|
32
|
+
var time = require("./time");
|
|
33
|
+
var { LogStreamError } = require("./framework-error");
|
|
34
|
+
|
|
35
|
+
var log = boot("log-stream-local");
|
|
36
|
+
|
|
37
|
+
var DEFAULTS = {
|
|
38
|
+
maxFileBytes: C.BYTES.mib(100),
|
|
39
|
+
maxFileAgeMs: C.TIME.days(7),
|
|
40
|
+
keepRotations: 30,
|
|
41
|
+
compressRotations: true,
|
|
42
|
+
fileMode: 0o600,
|
|
43
|
+
fileNamePrefix: "blamejs",
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
var _err = LogStreamError.factory;
|
|
47
|
+
|
|
48
|
+
function create(config) {
|
|
49
|
+
if (!config || !config.dir) throw new Error("log-stream local requires { dir }");
|
|
50
|
+
var cfg = Object.assign({}, DEFAULTS, config);
|
|
51
|
+
var dir = path.resolve(cfg.dir);
|
|
52
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
53
|
+
|
|
54
|
+
var activePath = path.join(dir, cfg.fileNamePrefix + ".log");
|
|
55
|
+
var fd = null;
|
|
56
|
+
var openedAt = 0;
|
|
57
|
+
var bytesWritten = 0;
|
|
58
|
+
|
|
59
|
+
function _open() {
|
|
60
|
+
fd = fs.openSync(activePath, "a", cfg.fileMode);
|
|
61
|
+
openedAt = Date.now();
|
|
62
|
+
try {
|
|
63
|
+
var stat = fs.fstatSync(fd);
|
|
64
|
+
bytesWritten = stat.size;
|
|
65
|
+
} catch (_e) {
|
|
66
|
+
bytesWritten = 0;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
_open();
|
|
70
|
+
|
|
71
|
+
function _shouldRotate() {
|
|
72
|
+
if (cfg.maxFileBytes && bytesWritten >= cfg.maxFileBytes) return true;
|
|
73
|
+
if (cfg.maxFileAgeMs && (Date.now() - openedAt) >= cfg.maxFileAgeMs) return true;
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function _rotate() {
|
|
78
|
+
try {
|
|
79
|
+
if (fd != null) {
|
|
80
|
+
try { fs.closeSync(fd); }
|
|
81
|
+
catch (e) { log.warn("rotate-close-failed: " + e.message); }
|
|
82
|
+
fd = null;
|
|
83
|
+
}
|
|
84
|
+
// Build rotated filename: blamejs-YYYYMMDDTHHMMSSZ.log
|
|
85
|
+
var stamp = time.toIso8601NoMs(new Date()).replace(/[-:]/g, "");
|
|
86
|
+
var rotated = path.join(dir, cfg.fileNamePrefix + "-" + stamp + ".log");
|
|
87
|
+
if (fs.existsSync(activePath)) {
|
|
88
|
+
fs.renameSync(activePath, rotated);
|
|
89
|
+
if (cfg.compressRotations) {
|
|
90
|
+
var data = fs.readFileSync(rotated);
|
|
91
|
+
var gz = zlib.gzipSync(data);
|
|
92
|
+
atomicFile.writeSync(rotated + ".gz", gz, { fileMode: cfg.fileMode });
|
|
93
|
+
fs.unlinkSync(rotated);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
_pruneOld();
|
|
97
|
+
} finally {
|
|
98
|
+
_open();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function _pruneOld() {
|
|
103
|
+
if (!cfg.keepRotations || cfg.keepRotations <= 0) return;
|
|
104
|
+
var entries = atomicFile.listDir(dir, {
|
|
105
|
+
filter: function (f) {
|
|
106
|
+
return f.startsWith(cfg.fileNamePrefix + "-") &&
|
|
107
|
+
(f.endsWith(".log") || f.endsWith(".log.gz"));
|
|
108
|
+
},
|
|
109
|
+
includeStat: true,
|
|
110
|
+
}).sort(function (a, b) { return b.mtimeMs - a.mtimeMs; }); // newest first
|
|
111
|
+
for (var i = cfg.keepRotations; i < entries.length; i++) {
|
|
112
|
+
try { fs.unlinkSync(entries[i].fullPath); } catch (_e) { /* best effort */ }
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function emit(record) {
|
|
117
|
+
if (_shouldRotate()) _rotate();
|
|
118
|
+
var line = JSON.stringify(record) + "\n";
|
|
119
|
+
var buf = Buffer.from(line, "utf8");
|
|
120
|
+
fs.writeSync(fd, buf, 0, buf.length, null);
|
|
121
|
+
bytesWritten += buf.length;
|
|
122
|
+
return Promise.resolve({ bytes: buf.length });
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function close() {
|
|
126
|
+
if (fd != null) {
|
|
127
|
+
try { fs.fsyncSync(fd); } catch (_e) { /* best effort */ }
|
|
128
|
+
try { fs.closeSync(fd); }
|
|
129
|
+
catch (e) { log.warn("close-failed: " + e.message); }
|
|
130
|
+
fd = null;
|
|
131
|
+
}
|
|
132
|
+
return Promise.resolve();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function getActivePath() { return activePath; }
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
protocol: "local",
|
|
139
|
+
emit: emit,
|
|
140
|
+
close: close,
|
|
141
|
+
rotate: function () { _rotate(); return Promise.resolve(); },
|
|
142
|
+
getActivePath: getActivePath,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
module.exports = { create: create };
|