@blamejs/core 0.15.32 → 0.15.34

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,10 @@ upgrading across more than a few patches at a time.
8
8
 
9
9
  ## v0.15.x
10
10
 
11
+ - v0.15.34 (2026-06-26) — **`b.mail.crypto.pgp.verify` now accepts every valid RSA OpenPGP signature — one whose value happened to have a high zero byte (about 1 in 256) was being rejected.** An OpenPGP RSA signature is an integer modulo the key's modulus, and ~1 in 256 signatures have a value that begins with a zero byte. The MPI encoding strips those leading zero bytes (RFC 9580 §3.2), but b.mail.crypto.pgp.verify passed the stripped value straight to the RSA verification, which requires a signature exactly the modulus byte length — so a perfectly valid signature was intermittently reported invalid. The signature is now left-padded back to the modulus width before verification, exactly as the Ed25519 path already pads its components. Verification of every valid RSA signature is now reliable, including signatures produced by other OpenPGP implementations. Also includes internal test-tooling: two more guard-suite suppression classes were re-verified and their tokens retired. **Fixed:** *RSA OpenPGP signatures with a high zero byte now verify reliably* — b.mail.crypto.pgp.verify read the RSA signature MPI (whose leading zero bytes the OpenPGP wire format strips) and handed it to the RSA verification without restoring the stripped bytes. Node's RSA verify requires the signature to be exactly the modulus byte length, so a signature whose value had one or more high zero bytes — about 1 in 256 of all signatures, for any key — was rejected as invalid even though it was correct. The signature is now left-padded to the modulus width before verification (the same correction the Ed25519 verification path already applied to its R/S components). This affects signatures the framework produces and signatures from other OpenPGP implementations alike. A deterministic regression test searches for a short-MPI signature and asserts it verifies. **Detectors:** *Two more suppression-marker classes re-verified and their tokens retired* — The raw-hash-compare and seal-without-aad guard classes were re-read and confirmed (a data-residency region tag compared with === — not a secret; and two intentional non-AEAD-bound seals — a non-regulated plain-mode column whose AAD is enforced by the posture seal-envelope floor where it matters, and a throwaway vault-readiness probe), then renamed to descriptive tokens with their old names added to the retired-token set. Test-suite tooling only.
12
+
13
+ - v0.15.33 (2026-06-26) — **Internal test-suite hardening only — the published library's runtime behavior and public API are unchanged (source-comment marker text aside).** Three more suppression classes in the codebase-patterns guard suite were re-verified from scratch and renamed to descriptive tokens, with their old names recorded as retired and their in-source marker comments updated to match. No runtime code, public API, or wire format changed. **Detectors:** *Three more suppression-marker classes re-verified and their tokens retired* — Continuing the re-verification pass: each marked site for the math-random-noncrypto, raw-new-url, and dynamic-require guard classes was re-read and confirmed (non-security jitter/sampling; URL parsing for shape/origin inspection or behind the safe wrapper; operator-supplied module loads), then the class was renamed to a descriptive token and its old name added to the retired-token set. This is test-suite tooling; no shipped framework behavior changed.
14
+
11
15
  - v0.15.32 (2026-06-26) — **Internal test-suite hardening only — the published library's runtime behavior and public API are unchanged (source-comment marker text aside).** Three more suppression classes in the codebase-patterns guard suite were re-verified from scratch and renamed to descriptive tokens, with their old names recorded as retired so the prior approval cannot be silently resurrected and their in-source marker comments updated to match. No runtime code, public API, or wire format changed. **Detectors:** *Three more suppression-marker classes re-verified and their tokens retired* — Continuing the re-verification pass: each marked site for the process-exit, hand-rolled buffer-collect, and raw-outbound-http guard classes was re-read and confirmed (operator-opt-in exits; bounded protocol-framing / TLV assembly; framework-routed outbound calls), then the class was renamed to a descriptive token and its old name added to the retired-token set. This is test-suite tooling; no shipped framework behavior changed.
12
16
 
13
17
  - v0.15.31 (2026-06-26) — **Internal test-suite hardening only — the published library's runtime behavior and public API are unchanged (source-comment marker text aside).** The codebase-patterns guard suite gains a gate that retires a renamed suppression-marker token: once a suppression class is re-verified and renamed, its old token cannot be silently re-registered, so a later suppression has to be re-examined under the new name instead of inheriting a stale approval. Eight suppression classes were re-verified and renamed to descriptive tokens this release, and their in-source marker comments were updated to match. No runtime code, public API, or wire format changed. **Detectors:** *Re-verification gate retires a renamed suppression-marker token* — A new guard refuses to re-register a retired suppression-marker token, and the orphan check points a stale marker at its current name. When a suppression class is re-verified, it is renamed to a descriptive token and the old name is recorded as retired, so the old approval cannot be quietly resurrected — a future suppression must be re-examined and re-stamped under the new name. This is test-suite tooling; no shipped framework behavior changed.
package/lib/acme.js CHANGED
@@ -1026,7 +1026,7 @@ function create(opts) {
1026
1026
  // Non-crypto: RFC 9773 §4.2 fleet-scheduling jitter inside the
1027
1027
  // CA-suggested renewal window. Predictability is not a threat
1028
1028
  // here; uniform distribution across the window is the goal.
1029
- renewAtMs = jLo + Math.floor(Math.random() * (jHi - jLo + 1)); // allow:math-random-noncrypto — RFC 9773 fleet jitter, predictability not a threat
1029
+ renewAtMs = jLo + Math.floor(Math.random() * (jHi - jLo + 1)); // allow:math-random-noncrypto-jitter-sampling — RFC 9773 fleet jitter, predictability not a threat
1030
1030
  } else {
1031
1031
  // Past-window — renew immediately, no jitter.
1032
1032
  renewAtMs = nowMs;
@@ -256,7 +256,7 @@ function _shouldSample(globalRate, perMethod, method, traceId) {
256
256
  // No trace-id supplied — start of a new trace. Operators wire
257
257
  // shouldSample(method, ctx.traceId) on every downstream hop so
258
258
  // children inherit the decision deterministically.
259
- return Math.random() < rate; // allow:math-random-noncrypto — start-of-trace seed only; downstream hops pass traceId for deterministic propagation
259
+ return Math.random() < rate; // allow:math-random-noncrypto-jitter-sampling — start-of-trace seed only; downstream hops pass traceId for deterministic propagation
260
260
  }
261
261
 
262
262
  function _formatAttributes(info) {
package/lib/auth/oauth.js CHANGED
@@ -282,7 +282,7 @@ function _validateUrl(url, allowHttp, label) {
282
282
  // global flag.
283
283
  var isLocalhostHttp = false;
284
284
  try {
285
- var parsed = new URL(url); // allow:raw-new-url — RFC 9700 §4.1.1 localhost-exception lookup; safeUrl re-validates below for non-localhost paths
285
+ var parsed = new URL(url); // allow:raw-new-url-parse-only — RFC 9700 §4.1.1 localhost-exception lookup; safeUrl re-validates below for non-localhost paths
286
286
  // Strip trailing root-zone dot before the localhost compare.
287
287
  // RFC 1034 §3.1 — `localhost.` resolves identically to `localhost`;
288
288
  // without the strip, an attacker who registers `evil.com` as a
@@ -2168,7 +2168,7 @@ function create(opts) {
2168
2168
  "parseFrontchannelLogoutRequest: req with url required");
2169
2169
  }
2170
2170
  var u;
2171
- try { u = new URL(req.url, "http://placeholder.invalid"); } // allow:raw-new-url — req.url is the framework-normalized path; placeholder base provides a synthetic origin for relative-path parse
2171
+ try { u = new URL(req.url, "http://placeholder.invalid"); } // allow:raw-new-url-parse-only — req.url is the framework-normalized path; placeholder base provides a synthetic origin for relative-path parse
2172
2172
  catch (_e) {
2173
2173
  throw new OAuthError("auth-oauth/bad-frontchannel-logout-url",
2174
2174
  "parseFrontchannelLogoutRequest: malformed request URL");
package/lib/cli.js CHANGED
@@ -455,11 +455,11 @@ function _resolveTargetModule(modulePath, ctx) {
455
455
  // code never reaches this nodePath.
456
456
  if (!modulePath) {
457
457
  var root = nodePath.resolve(__dirname, "..");
458
- return require(nodePath.join(root, "index.js")); // allow:dynamic-require — operator-extensibility entry point
458
+ return require(nodePath.join(root, "index.js")); // allow:dynamic-require-operator-module — operator-extensibility entry point
459
459
  }
460
460
  var abs = nodePath.isAbsolute(modulePath) ? modulePath : nodePath.resolve(ctx.cwd, modulePath);
461
461
  delete require.cache[require.resolve(abs)];
462
- return require(abs); // allow:dynamic-require — operator-extensibility entry point
462
+ return require(abs); // allow:dynamic-require-operator-module — operator-extensibility entry point
463
463
  }
464
464
 
465
465
  function _runApiSnapshot(args, ctx) {
package/lib/cluster.js CHANGED
@@ -750,7 +750,7 @@ async function _heartbeat() {
750
750
  // budget is in `leaseTtl - heartbeatMs`, not in the jitter
751
751
  // window).
752
752
  if (!lease) {
753
- var jitterMs = Math.floor(Math.random() * (heartbeatMs * 0.4)); // allow:math-random-noncrypto — heartbeat jitter, not security-bearing
753
+ var jitterMs = Math.floor(Math.random() * (heartbeatMs * 0.4)); // allow:math-random-noncrypto-jitter-sampling — heartbeat jitter, not security-bearing
754
754
  if (jitterMs > 0) {
755
755
  await safeAsync.sleep(jitterMs);
756
756
  }
@@ -1090,7 +1090,7 @@ function sealRow(table, row, opts) {
1090
1090
  out[field] = vaultAad.seal(_encodeTyped(out[field]),
1091
1091
  _aadParts(s, table, field, out));
1092
1092
  } else {
1093
- // allow:seal-without-aad — plain-mode legacy table; operator
1093
+ // allow:seal-without-aad-by-design — plain-mode legacy table; operator
1094
1094
  // opts into AAD via registerTable({aad:true})
1095
1095
  out[field] = vault.seal(_encodeTyped(out[field]));
1096
1096
  }
package/lib/db-schema.js CHANGED
@@ -605,7 +605,7 @@ function runMigrations(database, migrationDir) {
605
605
  // Operator-supplied migration file — by definition not statically
606
606
  // require-able by a bundler. Anyone bundling this surface into SEA
607
607
  // accepts that runtime migration loading won't resolve.
608
- mig = require(fullPath); // allow:dynamic-require — operator-supplied migration
608
+ mig = require(fullPath); // allow:dynamic-require-operator-module — operator-supplied migration
609
609
  } catch (e) {
610
610
  throw new Error("migration '" + file + "' failed to load: " + e.message);
611
611
  }
@@ -1709,7 +1709,7 @@ function _crossBorderRegulated(posture) {
1709
1709
 
1710
1710
  function _residencyCompatible(primaryTag, replicaTag) {
1711
1711
  if (!primaryTag || !replicaTag) return true;
1712
- if (primaryTag === replicaTag) return true; // allow:raw-hash-compare — residency tag string, not a secret hash
1712
+ if (primaryTag === replicaTag) return true; // allow:raw-hash-compare-nonsecret-tag — residency tag string, not a secret hash
1713
1713
  if (primaryTag === "unrestricted" || replicaTag === "unrestricted") return true;
1714
1714
  return false;
1715
1715
  }
@@ -940,7 +940,7 @@ function canaryGate(gate, opts) {
940
940
  name: opts.name || "canary",
941
941
  check: async function (ctx) {
942
942
  var d = await gate.check(ctx);
943
- if (d.action === "refuse" && Math.random() > rate) { // allow:math-random-noncrypto — canary sampling, non-security
943
+ if (d.action === "refuse" && Math.random() > rate) { // allow:math-random-noncrypto-jitter-sampling — canary sampling, non-security
944
944
  return Object.assign({}, d, { ok: true, action: "warn" });
945
945
  }
946
946
  return d;
@@ -104,7 +104,7 @@ function _resolveUri(ref, base) {
104
104
  // RFC 3986 relative→absolute resolution of a schema $id/$ref (operator-
105
105
  // trusted schema text, not request data); safeUrl.parse intentionally
106
106
  // rejects the relative refs and non-http schemes schemas legitimately use.
107
- try { return new URL(ref, base).href; } // allow:raw-new-url — schema $id/$ref URI resolution, not request-data URL handling
107
+ try { return new URL(ref, base).href; } // allow:raw-new-url-parse-only — schema $id/$ref URI resolution, not request-data URL handling
108
108
  catch (_e) {
109
109
  // Relative resolution against a non-URL base (e.g. "urn:..." or a
110
110
  // bare name). Fall back to fragment-aware concatenation.
@@ -730,7 +730,7 @@ function _checkFormat(format, value, type) {
730
730
  if (/\s/.test(value)) return false; // raw whitespace is not a valid URI
731
731
  if (/%(?![0-9A-Fa-f]{2})/.test(value)) return false; // malformed percent-escape
732
732
  if (!/^[A-Za-z][A-Za-z0-9+.-]*:/.test(value)) return false; // absolute URI requires a scheme // allow:regex-no-length-cap — linear scheme prefix
733
- try { new URL(value); return true; } catch (_e) { return false; } // allow:raw-new-url — string-shape check, no fetch / SSRF surface
733
+ try { new URL(value); return true; } catch (_e) { return false; } // allow:raw-new-url-parse-only — string-shape check, no fetch / SSRF surface
734
734
  }
735
735
  case "uuid": return /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(value); // allow:regex-no-length-cap — fixed-width UUID
736
736
  case "ipv4": return /^(\d{1,3}\.){3}\d{1,3}$/.test(value) && value.split(".").every(function (o) { return Number(o) <= 255; }); // allow:regex-no-length-cap — bounded dotted-quad
@@ -865,11 +865,22 @@ function verify(opts) {
865
865
  var ok;
866
866
  if (parsed.pubAlg === PUB_ALG_RSA) {
867
867
  var rsaMpi = _readMpi(parsed.sigMpisBytes, 0);
868
+ // The signature is an integer in [0, n); when its value has one or more
869
+ // high zero bytes (~1/256 of signatures) the OpenPGP MPI encoding strips
870
+ // them (RFC 9580 §3.2), but node's RSA verify requires a signature exactly
871
+ // the modulus byte length. Left-pad the stripped MPI back to the modulus
872
+ // width — the same correction the Ed25519 branch applies to its R/S
873
+ // components below — or a valid signature is rejected.
874
+ var rsaSigBytes = rsaMpi.value;
875
+ var modLen = rsaPub.n.length;
876
+ if (rsaSigBytes.length < modLen) {
877
+ rsaSigBytes = Buffer.concat([Buffer.alloc(modLen - rsaSigBytes.length), rsaSigBytes]);
878
+ }
868
879
  try {
869
880
  ok = nodeCrypto.verify(hashName, hashInput, {
870
881
  key: publicKey,
871
882
  padding: nodeCrypto.constants.RSA_PKCS1_PADDING,
872
- }, rsaMpi.value);
883
+ }, rsaSigBytes);
873
884
  } catch (e) {
874
885
  return _fail("mail-crypto/pgp/verify-error",
875
886
  "RSA verify threw: " + ((e && e.message) || String(e)));
package/lib/mcp.js CHANGED
@@ -510,7 +510,7 @@ function _toolResultSanitize(result, opts) {
510
510
  } else if (block.type === "image" || block.type === "resource_link" || block.type === "audio") {
511
511
  var url = block.url || (block.resource && block.resource.uri);
512
512
  if (typeof url === "string" && url.length > 0 && allowedHosts.length > 0) {
513
- var u; try { u = new URL(url); } catch (_e) { u = null; } // allow:raw-new-url — operator-supplied tool URL; allowlist enforced below
513
+ var u; try { u = new URL(url); } catch (_e) { u = null; } // allow:raw-new-url-parse-only — operator-supplied tool URL; allowlist enforced below
514
514
  if (!u || allowedHosts.indexOf(u.host) === -1) {
515
515
  issues.push({ kind: "off-allowlist-url", index: i, url: url });
516
516
  if (posture === "sanitize") continue; // drop the block in sanitize mode
@@ -194,7 +194,7 @@ function _checkOriginAllowed(req, allowedOrigins, isHttpsFn, requireOrigin) {
194
194
 
195
195
  function _originOf(rawUrl) {
196
196
  try {
197
- var u = new URL(rawUrl); // allow:raw-new-url — origin-shape inspection (NOT outbound). Intentionally tolerates file:// / data: which safeUrl.parse refuses.
197
+ var u = new URL(rawUrl); // allow:raw-new-url-parse-only — origin-shape inspection (NOT outbound). Intentionally tolerates file:// / data: which safeUrl.parse refuses.
198
198
  return u.origin; // "https://host:port" — no path / query / fragment
199
199
  } catch (_e) { return null; }
200
200
  }
@@ -290,7 +290,7 @@ function dbStore(opts) {
290
290
  var sealEnabled = false;
291
291
  if (sealReq) {
292
292
  try {
293
- // allow:seal-without-aad — vault-readiness probe; throwaway
293
+ // allow:seal-without-aad-by-design — vault-readiness probe; throwaway
294
294
  // sentinel value, not row-bound data
295
295
  vault.seal("__idempotency_seal_probe__");
296
296
  sealEnabled = true;
@@ -4,7 +4,7 @@
4
4
  * operator-supplied module file (a migration or a seed) by path.
5
5
  *
6
6
  * Operator modules execute arbitrary code on `require`, so the dynamic
7
- * `require()` lives here behind ONE `allow:dynamic-require` marker rather
7
+ * `require()` lives here behind ONE `allow:dynamic-require-operator-module` marker rather
8
8
  * than scattered across every host-CLI loader (`b.migrations`,
9
9
  * `b.seeders`, `b.externalDb.migrate`). The require cache is busted first
10
10
  * so a dev / test rewriting a fixture between calls picks up the new
@@ -33,7 +33,7 @@
33
33
  function requireFresh(absPath, onLoadError) {
34
34
  try { delete require.cache[require.resolve(absPath)]; } catch (_e) { /* not yet cached */ }
35
35
  try {
36
- return require(absPath); // allow:dynamic-require — operator-supplied module (migration / seed)
36
+ return require(absPath); // allow:dynamic-require-operator-module — operator-supplied module (migration / seed)
37
37
  } catch (e) {
38
38
  throw onLoadError(e);
39
39
  }
package/lib/retry.js CHANGED
@@ -284,7 +284,7 @@ function backoffDelay(attempt, opts) {
284
284
  // 30-50K randomInt/sec under a retry storm without any security
285
285
  // payoff. Math.random's PRNG is the right tool for
286
286
  // thundering-herd avoidance.
287
- var jitter = capped * opts.jitterFactor * Math.random(); // allow:math-random-noncrypto — jitter for thundering-herd, not a confidentiality primitive
287
+ var jitter = capped * opts.jitterFactor * Math.random(); // allow:math-random-noncrypto-jitter-sampling — jitter for thundering-herd, not a confidentiality primitive
288
288
  return Math.floor(capped - jitter);
289
289
  }
290
290
 
package/lib/safe-url.js CHANGED
@@ -444,7 +444,7 @@ function format(url) {
444
444
  }
445
445
  // Constructing URL() is the path that surfaces the IDN-crash on
446
446
  // older Node — wrap so the listener never crashes.
447
- var u = new URL(url); // allow:raw-new-url — safeUrl.format wraps URL ctor for CVE-2026-21712; this IS the safe wrapper.
447
+ var u = new URL(url); // allow:raw-new-url-parse-only — safeUrl.format wraps URL ctor for CVE-2026-21712; this IS the safe wrapper.
448
448
  return u.href;
449
449
  } catch (e) {
450
450
  if (e && e.isSafeUrlError) throw e;
package/lib/ssrf-guard.js CHANGED
@@ -754,7 +754,7 @@ function createAllowlist(opts) {
754
754
  }
755
755
  async function assertUrl(url) {
756
756
  var parsed;
757
- try { parsed = new URL(url); } // allow:raw-new-url — local URL parse for hostname extraction
757
+ try { parsed = new URL(url); } // allow:raw-new-url-parse-only — local URL parse for hostname extraction
758
758
  catch (_e) {
759
759
  throw new SsrfError("invalid URL", "ssrf-guard/bad-url", { url: url });
760
760
  }
@@ -176,8 +176,8 @@ function _loadAndVerify(name) {
176
176
  throw new VendorDataError("vendor-data/module-missing",
177
177
  "vendorData: '" + name + "' .data.js module not statically " +
178
178
  "require'd by lib/vendor-data.js. Add the literal-string require " +
179
- "to the _MODULES table at the top of the file — dynamic " + // allow:dynamic-require — diagnostic message text
180
- "require(variable) breaks SEA / esbuild bundling."); // allow:dynamic-require — diagnostic message text
179
+ "to the _MODULES table at the top of the file — dynamic " + // allow:dynamic-require-operator-module — diagnostic message text
180
+ "require(variable) breaks SEA / esbuild bundling."); // allow:dynamic-require-operator-module — diagnostic message text
181
181
  }
182
182
 
183
183
  // Module-shape gate
package/lib/websocket.js CHANGED
@@ -460,7 +460,7 @@ function isOriginAllowed(req, origins) {
460
460
  var host = (req.headers || {}).host;
461
461
  if (!host) return false;
462
462
  var originHost;
463
- try { originHost = new URL(origin).host; } // allow:raw-new-url — comparing browser-supplied Origin header against Host; safeUrl.parse adds policy filtering that isn't appropriate for exact host comparison
463
+ try { originHost = new URL(origin).host; } // allow:raw-new-url-parse-only — comparing browser-supplied Origin header against Host; safeUrl.parse adds policy filtering that isn't appropriate for exact host comparison
464
464
  catch (_e) { return false; }
465
465
  return originHost === host;
466
466
  }
package/lib/ws-client.js CHANGED
@@ -964,7 +964,7 @@ class WsClient extends EventEmitter {
964
964
  this._reconnectAttempt += 1;
965
965
  var attempt = Math.min(this._reconnectAttempt, 30); // clamp 2^attempt overflow
966
966
  var ceiling = Math.min(rOpts.maxMs, rOpts.baseMs * Math.pow(2, attempt - 1));
967
- var delay = Math.floor(Math.random() * ceiling); // allow:math-random-noncrypto — backoff jitter, not security
967
+ var delay = Math.floor(Math.random() * ceiling); // allow:math-random-noncrypto-jitter-sampling — backoff jitter, not security
968
968
  var self = this;
969
969
  this._reconnectTimer = setTimeout(function () {
970
970
  self._reconnectTimer = null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blamejs/core",
3
- "version": "0.15.32",
3
+ "version": "0.15.34",
4
4
  "description": "The Node framework that owns its stack.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "blamejs contributors",
package/sbom.cdx.json CHANGED
@@ -2,10 +2,10 @@
2
2
  "$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
3
3
  "bomFormat": "CycloneDX",
4
4
  "specVersion": "1.5",
5
- "serialNumber": "urn:uuid:c545cdae-c805-48ed-bc85-5ab5c993961a",
5
+ "serialNumber": "urn:uuid:4006bc32-7ae3-4f18-bad1-057410956255",
6
6
  "version": 1,
7
7
  "metadata": {
8
- "timestamp": "2026-06-26T20:40:06.256Z",
8
+ "timestamp": "2026-06-27T01:06:19.602Z",
9
9
  "lifecycles": [
10
10
  {
11
11
  "phase": "build"
@@ -19,14 +19,14 @@
19
19
  }
20
20
  ],
21
21
  "component": {
22
- "bom-ref": "@blamejs/core@0.15.32",
22
+ "bom-ref": "@blamejs/core@0.15.34",
23
23
  "type": "application",
24
24
  "name": "blamejs",
25
- "version": "0.15.32",
25
+ "version": "0.15.34",
26
26
  "scope": "required",
27
27
  "author": "blamejs contributors",
28
28
  "description": "The Node framework that owns its stack.",
29
- "purl": "pkg:npm/%40blamejs/core@0.15.32",
29
+ "purl": "pkg:npm/%40blamejs/core@0.15.34",
30
30
  "properties": [],
31
31
  "externalReferences": [
32
32
  {
@@ -54,7 +54,7 @@
54
54
  "components": [],
55
55
  "dependencies": [
56
56
  {
57
- "ref": "@blamejs/core@0.15.32",
57
+ "ref": "@blamejs/core@0.15.34",
58
58
  "dependsOn": []
59
59
  }
60
60
  ]