@blamejs/core 0.4.27 → 0.4.28

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 CHANGED
@@ -8,6 +8,7 @@ upgrading across more than a few patches at a time.
8
8
 
9
9
  ## v0.4.x
10
10
 
11
+ - **0.4.27** (2026-04-30) — primitive-drift sweep: regex + escape consolidation, IPv6 completion
11
12
  - **0.4.26** (2026-04-30) — primitive-drift sweep: middleware audit context + safeUrl
12
13
  - **0.4.25** (2026-04-30) — b.objectStore.bucketOps: bucket-level operations (SigV4)
13
14
  - **0.4.24** (2026-04-30) — b.objectStore: multipart upload + server-side encryption
package/lib/api-key.js CHANGED
@@ -13,7 +13,7 @@
13
13
  * ownerId: "user-42",
14
14
  * scopes: ["read:users", "write:posts"],
15
15
  * metadata: { name: "Mobile app v3" },
16
- * expiresAt: Date.now() + 90 * 86400 * 1000,
16
+ * expiresAt: Date.now() + b.constants.TIME.days(90),
17
17
  * });
18
18
  * // issued.key — "bk_live_<idHex>_<secretHex>" (returned ONCE)
19
19
  * // issued.id — "<idHex>"
package/lib/cli.js CHANGED
@@ -34,6 +34,9 @@
34
34
  * before encryption or temporarily switch the file to plaintext.
35
35
  */
36
36
 
37
+ var fs = require("node:fs");
38
+ var nodeCrypto = require("node:crypto");
39
+ var os = require("node:os");
37
40
  var path = require("path");
38
41
  var apiSnapshot = require("./api-snapshot");
39
42
  var auditTools = require("./audit-tools");
@@ -898,11 +901,7 @@ async function _runBackup(args, ctx) {
898
901
  }
899
902
 
900
903
  if (sub === "verify") {
901
- var fs2 = require("node:fs");
902
- var os2 = require("node:os");
903
- var nodePath = require("node:path");
904
- var nodeCrypto = require("node:crypto");
905
- var stagingDir = nodePath.join(os2.tmpdir(),
904
+ var stagingDir = path.join(os.tmpdir(),
906
905
  "blamejs-backup-verify-" + nodeCrypto.randomBytes(8).toString("hex"));
907
906
  try {
908
907
  var r = await restoreBundle.extract({
@@ -917,7 +916,7 @@ async function _runBackup(args, ctx) {
917
916
  } catch (e) {
918
917
  return report.error((e && e.message) || String(e));
919
918
  } finally {
920
- try { fs2.rmSync(stagingDir, { recursive: true, force: true }); } catch (_e) { /* best-effort */ }
919
+ try { fs.rmSync(stagingDir, { recursive: true, force: true }); } catch (_e) { /* best-effort */ }
921
920
  }
922
921
  }
923
922
 
@@ -1118,7 +1117,7 @@ async function _runMtls(args, ctx) {
1118
1117
  validityDays: daysP,
1119
1118
  });
1120
1119
  if (outPath) {
1121
- require("node:fs").writeFileSync(outPath, p12.p12, { mode: 0o600 });
1120
+ fs.writeFileSync(outPath, p12.p12, { mode: 0o600 });
1122
1121
  report.write("p12 written: " + outPath);
1123
1122
  } else {
1124
1123
  // No --out: stream the bytes to stdout for piping. Operators
package/lib/db-query.js CHANGED
@@ -26,6 +26,7 @@
26
26
  * a derived hash throws (every encryption uses a fresh nonce — the lookup
27
27
  * would always return zero rows; failing loudly is safer).
28
28
  */
29
+ var { Readable } = require("node:stream");
29
30
  var cryptoField = require("./crypto-field");
30
31
  var { generateToken } = require("./crypto");
31
32
 
@@ -194,7 +195,6 @@ class Query {
194
195
  var stmt = this._db.prepare(sql);
195
196
  var table = this._table;
196
197
  var iter;
197
- var Readable = require("node:stream").Readable;
198
198
  try { iter = stmt.iterate.apply(stmt, this._whereParams); }
199
199
  catch (e) {
200
200
  var r = new Readable({ objectMode: true, read: function () {} });
package/lib/db.js CHANGED
@@ -42,6 +42,7 @@
42
42
  var fs = require("fs");
43
43
  var path = require("path");
44
44
  var { DatabaseSync } = require("node:sqlite");
45
+ var { Readable } = require("node:stream");
45
46
  var atomicFile = require("./atomic-file");
46
47
  var audit = require("./audit");
47
48
  var auditSign = require("./audit-sign");
@@ -796,7 +797,6 @@ function stream(sql) {
796
797
  var table = opts && typeof opts.table === "string" ? opts.table : null;
797
798
  var unseal = table ? cryptoField : null;
798
799
 
799
- var Readable = require("node:stream").Readable;
800
800
  var stmt;
801
801
  var iter;
802
802
  try {
@@ -64,6 +64,8 @@
64
64
  var http = require("http");
65
65
  var https = require("https");
66
66
  var http2 = require("http2");
67
+ var nodeCrypto = require("node:crypto");
68
+ var nodeStream = require("node:stream");
67
69
  var { URL } = require("url");
68
70
  var C = require("./constants");
69
71
  var pqcAgent = require("./pqc-agent");
@@ -321,7 +323,6 @@ function _attachJarCookie(headers, jar, url) {
321
323
  // parser accepts so round-trip from one blamejs app's outbound to
322
324
  // another's inbound is exact.
323
325
  function _buildMultipartBody(spec) {
324
- var nodeCrypto = require("node:crypto");
325
326
  var boundary = "----blamejs-mp-" + nodeCrypto.randomBytes(16).toString("hex");
326
327
  var CRLF = "\r\n";
327
328
  var parts = [];
@@ -701,7 +702,7 @@ function _requestH1(transport, u, opts) {
701
702
  // The framework's contract is to hand back the response stream
702
703
  // unmodified; fix-up via a passthrough keeps that contract while
703
704
  // observing the chunk sizes.
704
- var passthrough = new (require("node:stream").PassThrough)();
705
+ var passthrough = new nodeStream.PassThrough();
705
706
  res.on("data", function (chunk) { _emitDownload(chunk.length); passthrough.write(chunk); });
706
707
  res.on("end", function () { passthrough.end(); });
707
708
  res.on("error", function (e) { passthrough.destroy(e); });
@@ -26,23 +26,23 @@
26
26
  *
27
27
  * var bp = b.middleware.bodyParser({
28
28
  * json: {
29
- * limit: 1024 * 1024,
29
+ * limit: b.constants.BYTES.mib(1),
30
30
  * strict: true, // require the body to start with {/[
31
31
  * parseHook: function (parsed) { ... return validatedShape; },
32
32
  * },
33
33
  * urlencoded: {
34
- * limit: 1024 * 1024,
34
+ * limit: b.constants.BYTES.mib(1),
35
35
  * arrayLimit: 100, // for ?tag=a&tag=b → tag: ["a","b"]
36
36
  * },
37
- * text: { limit: 1024 * 1024, charset: "utf-8" },
38
- * raw: { limit: 10 * 1024 * 1024, contentTypes: ["application/octet-stream"] },
37
+ * text: { limit: b.constants.BYTES.mib(1), charset: "utf-8" },
38
+ * raw: { limit: b.constants.BYTES.mib(10), contentTypes: ["application/octet-stream"] },
39
39
  * multipart: {
40
40
  * tmpDir: os.tmpdir(),
41
- * fileSize: 10 * 1024 * 1024,
42
- * totalSize: 50 * 1024 * 1024,
41
+ * fileSize: b.constants.BYTES.mib(10),
42
+ * totalSize: b.constants.BYTES.mib(50),
43
43
  * fileCount: 20,
44
44
  * fieldCount: 100,
45
- * fieldSize: 1024 * 1024,
45
+ * fieldSize: b.constants.BYTES.mib(1),
46
46
  * mimeAllowlist: ["image/jpeg", "image/png", "application/pdf"], // null = any
47
47
  *
48
48
  * // Per-part predicate. Runs after sanitization + MIME checks but
@@ -64,8 +64,8 @@
64
64
  * // global mimeAllowlist for the named field; other fields still
65
65
  * // use the global list.
66
66
  * fields: {
67
- * avatar: { maxBytes: 2 * 1024 * 1024, mimeTypes: ["image/jpeg", "image/png"] },
68
- * document: { maxBytes: 25 * 1024 * 1024 },
67
+ * avatar: { maxBytes: b.constants.BYTES.mib(2), mimeTypes: ["image/jpeg", "image/png"] },
68
+ * document: { maxBytes: b.constants.BYTES.mib(25) },
69
69
  * },
70
70
  *
71
71
  * // When wired, fileFilter rejections emit body-parser.multipart.file_rejected
@@ -175,7 +175,7 @@ function create(config) {
175
175
  if (!tokenResp.access_token) {
176
176
  throw _err("AUTH_FAILED", "GCS token endpoint returned no access_token: " + res.body.toString("utf8"), true);
177
177
  }
178
- var expiresInMs = (tokenResp.expires_in || 3600) * 1000;
178
+ var expiresInMs = C.TIME.seconds(tokenResp.expires_in || 3600);
179
179
  cachedToken = {
180
180
  accessToken: tokenResp.access_token,
181
181
  expiresAt: Date.now() + expiresInMs,
@@ -33,8 +33,9 @@ var cluster = require("./cluster");
33
33
  var clusterStorage = require("./cluster-storage");
34
34
  var { generateToken } = require("./crypto");
35
35
  var cryptoField = require("./crypto-field");
36
- var safeJson = require("./safe-json");
37
36
  var lazyRequire = require("./lazy-require");
37
+ var safeJson = require("./safe-json");
38
+ var scheduler = require("./scheduler");
38
39
  var { QueueError } = require("./framework-error");
39
40
 
40
41
  var _err = QueueError.factory;
@@ -241,7 +242,6 @@ function create(_config) {
241
242
  if (row && row.repeatCron) {
242
243
  try {
243
244
  var unsealedRow = cryptoField.unsealRow("_blamejs_jobs", row);
244
- var scheduler = require("./scheduler");
245
245
  var cron = scheduler.parseCron(unsealedRow.repeatCron);
246
246
  var nextMs = scheduler.nextCronFire(cron, new Date(nowMs), unsealedRow.repeatTimezone || null);
247
247
  await enqueue(unsealedRow.queueName,
package/lib/queue.js CHANGED
@@ -31,12 +31,13 @@
31
31
  * failed (status='failed')
32
32
  */
33
33
  var C = require("./constants");
34
- var localProto = require("./queue-local");
35
- var retryHelper = require("./retry");
36
- var safeAsync = require("./safe-async");
37
34
  var lazyRequire = require("./lazy-require");
35
+ var nodeCrypto = require("node:crypto");
38
36
  var observability = require("./observability");
39
37
  var protocolDispatcher = require("./protocol-dispatcher");
38
+ var localProto = require("./queue-local");
39
+ var retryHelper = require("./retry");
40
+ var safeAsync = require("./safe-async");
40
41
  var { QueueError } = require("./framework-error");
41
42
 
42
43
  var dispatcher = protocolDispatcher.create({
@@ -565,7 +566,6 @@ function enqueueFlow(spec) {
565
566
  return Promise.reject(e);
566
567
  }
567
568
 
568
- var nodeCrypto = require("node:crypto");
569
569
  var flowId = "flow-" + nodeCrypto.randomBytes(8).toString("hex");
570
570
 
571
571
  return observability.tap("queue.enqueueFlow",
package/lib/router.js CHANGED
@@ -25,6 +25,7 @@ var fs = require("fs");
25
25
  var path = require("path");
26
26
  var { URL } = require("url");
27
27
  var C = require("./constants");
28
+ var safeAsync = require("./safe-async");
28
29
  var websocket = require("./websocket");
29
30
  var { boot } = require("./log");
30
31
 
@@ -217,12 +218,13 @@ class Router {
217
218
  });
218
219
  });
219
220
 
220
- var allClosed = Promise.all(closes);
221
- var timeout = new Promise(function (resolve) {
222
- var t = setTimeout(resolve, timeoutMs);
223
- t.unref();
224
- });
225
- await Promise.race([allClosed, timeout]);
221
+ // Wait up to `timeoutMs` for graceful WS closes, then force-destroy
222
+ // any laggards. `safeAsync.sleep({ unref: true })` matches the
223
+ // framework's outbound-timeout convention.
224
+ await Promise.race([
225
+ Promise.all(closes),
226
+ safeAsync.sleep(timeoutMs, { unref: true }),
227
+ ]);
226
228
  // Force-destroy any laggards — at this point we've waited the full
227
229
  // timeout and they didn't ack. The operator chose timeoutMs; honor it.
228
230
  this._activeWsConns.forEach(function (conn) {
package/lib/session.js CHANGED
@@ -35,12 +35,13 @@
35
35
  * verify / count
36
36
  * — anywhere (any node can read shared session state)
37
37
  */
38
- var { generateToken, sha3Hash } = require("./crypto");
39
- var safeJson = require("./safe-json");
40
- var cryptoField = require("./crypto-field");
41
- var clusterStorage = require("./cluster-storage");
38
+ var audit = require("./audit");
42
39
  var cluster = require("./cluster");
40
+ var clusterStorage = require("./cluster-storage");
43
41
  var C = require("./constants");
42
+ var { generateToken, sha3Hash } = require("./crypto");
43
+ var cryptoField = require("./crypto-field");
44
+ var safeJson = require("./safe-json");
44
45
  var { SessionError } = require("./framework-error");
45
46
 
46
47
  var _err = SessionError.factory;
@@ -260,13 +261,12 @@ async function rotate(oldToken, opts) {
260
261
  // privilege transition so post-incident review can trace which
261
262
  // session id covered which privilege state.
262
263
  try {
263
- var audit = require("./audit");
264
264
  audit.emit({
265
265
  action: "auth.session.rotate",
266
266
  outcome: "success",
267
267
  metadata: { reason: opts.reason || "explicit" },
268
268
  });
269
- } catch (_e) { /* boot-order tolerance */ }
269
+ } catch (_e) { /* audit emit best-effort never block rotate() */ }
270
270
 
271
271
  return { token: newSid, expiresAt: expiresAt };
272
272
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blamejs/core",
3
- "version": "0.4.27",
3
+ "version": "0.4.28",
4
4
  "description": "The Node framework that owns its stack.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "blamejs contributors",