@blamejs/core 0.14.6 → 0.14.8
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 +4 -0
- package/README.md +3 -2
- package/lib/a2a-tasks.js +6 -6
- package/lib/agent-event-bus.js +4 -4
- package/lib/agent-idempotency.js +6 -6
- package/lib/agent-orchestrator.js +9 -9
- package/lib/agent-posture-chain.js +10 -10
- package/lib/agent-saga.js +6 -7
- package/lib/agent-snapshot.js +8 -8
- package/lib/agent-stream.js +3 -3
- package/lib/agent-tenant.js +4 -4
- package/lib/agent-trace.js +5 -5
- package/lib/ai-disclosure.js +3 -3
- package/lib/ai-input.js +1 -1
- package/lib/app.js +2 -2
- package/lib/archive-read.js +1 -1
- package/lib/archive-tar-read.js +1 -1
- package/lib/archive-wrap.js +5 -5
- package/lib/audit-tools.js +65 -5
- package/lib/audit.js +2 -2
- package/lib/auth/acr-vocabulary.js +1 -1
- package/lib/auth/ciba.js +4 -4
- package/lib/auth/dpop.js +1 -1
- package/lib/auth/fal.js +1 -1
- package/lib/auth/fido-mds3.js +2 -3
- package/lib/auth/jwt-external.js +2 -2
- package/lib/auth/oauth.js +10 -10
- package/lib/auth/oid4vci.js +8 -8
- package/lib/auth/oid4vp.js +1 -1
- package/lib/auth/openid-federation.js +6 -6
- package/lib/auth/passkey.js +6 -6
- package/lib/auth/saml.js +1 -1
- package/lib/auth/sd-jwt-vc.js +3 -6
- package/lib/backup/index.js +18 -18
- package/lib/breach-deadline.js +3 -3
- package/lib/cache.js +4 -4
- package/lib/calendar.js +7 -7
- package/lib/circuit-breaker.js +1 -1
- package/lib/cms-codec.js +2 -2
- package/lib/compliance.js +14 -14
- package/lib/content-credentials.js +3 -3
- package/lib/crypto-field.js +58 -21
- package/lib/crypto.js +5 -6
- package/lib/db-query.js +131 -9
- package/lib/db.js +106 -22
- package/lib/ddl-change-control.js +2 -2
- package/lib/did.js +2 -2
- package/lib/dsr.js +4 -4
- package/lib/external-db.js +65 -17
- package/lib/framework-schema.js +4 -4
- package/lib/guard-cidr.js +1 -1
- package/lib/guard-image.js +1 -1
- package/lib/guard-list-id.js +2 -2
- package/lib/guard-list-unsubscribe.js +2 -3
- package/lib/guard-time.js +1 -1
- package/lib/guard-xml.js +1 -1
- package/lib/http-client-cache.js +1 -1
- package/lib/iab-tcf.js +4 -4
- package/lib/incident-report.js +150 -0
- package/lib/json-schema.js +1 -1
- package/lib/jtd.js +1 -1
- package/lib/mail-auth.js +1 -1
- package/lib/mail-bimi.js +1 -1
- package/lib/mail-crypto-smime.js +2 -2
- package/lib/mail-deploy.js +3 -3
- package/lib/mail-server-managesieve.js +2 -2
- package/lib/mail-server-mx.js +1 -1
- package/lib/mail-server-pop3.js +2 -2
- package/lib/mail-server-rate-limit.js +1 -1
- package/lib/mail-server-submission.js +1 -1
- package/lib/mail-store.js +1 -1
- package/lib/mcp.js +7 -7
- package/lib/mdoc.js +1 -1
- package/lib/metrics.js +10 -10
- package/lib/middleware/compose-pipeline.js +1 -1
- package/lib/middleware/csrf-protect.js +1 -1
- package/lib/middleware/dpop.js +5 -5
- package/lib/middleware/idempotency-key.js +21 -22
- package/lib/middleware/protected-resource-metadata.js +2 -2
- package/lib/network-dns-resolver.js +2 -2
- package/lib/network-dns.js +1 -2
- package/lib/network-dnssec.js +2 -2
- package/lib/network-smtp-policy.js +1 -1
- package/lib/network-tls.js +1 -2
- package/lib/network-tsig.js +3 -3
- package/lib/outbox.js +1 -1
- package/lib/pqc-agent.js +1 -1
- package/lib/retention.js +1 -1
- package/lib/retry.js +1 -1
- package/lib/rfc3339.js +2 -2
- package/lib/safe-archive.js +2 -2
- package/lib/safe-decompress.js +1 -1
- package/lib/safe-ical.js +2 -2
- package/lib/safe-mime.js +1 -1
- package/lib/self-update-standalone-verifier.js +1 -1
- package/lib/self-update.js +2 -2
- package/lib/standard-webhooks.js +3 -3
- package/lib/static.js +1 -1
- package/lib/stream-throttle.js +2 -2
- package/lib/structured-fields.js +1 -1
- package/lib/subject.js +2 -2
- package/lib/vault/index.js +64 -1
- package/lib/vault/rotate.js +19 -0
- package/lib/vault/seal-pem-file.js +1 -1
- package/lib/vendor-data.js +1 -1
- package/lib/web-push-vapid.js +1 -1
- package/lib/webhook.js +1 -1
- package/lib/websocket.js +1 -1
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/lib/standard-webhooks.js
CHANGED
|
@@ -32,7 +32,7 @@ var { defineClass } = require("./framework-error");
|
|
|
32
32
|
|
|
33
33
|
var StandardWebhooksError = defineClass("StandardWebhooksError", { alwaysPermanent: true });
|
|
34
34
|
|
|
35
|
-
var DEFAULT_TOLERANCE_SEC = 300;
|
|
35
|
+
var DEFAULT_TOLERANCE_SEC = 300;
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
38
|
* @primitive b.standardWebhooks.sign
|
|
@@ -70,7 +70,7 @@ function sign(opts) {
|
|
|
70
70
|
var id = opts.id || ("msg_" + bCrypto.generateToken(32)); // 32-char id token
|
|
71
71
|
var timestamp = typeof opts.timestamp === "number"
|
|
72
72
|
? opts.timestamp
|
|
73
|
-
: Math.floor(Date.now() / 1000);
|
|
73
|
+
: Math.floor(Date.now() / 1000);
|
|
74
74
|
if (timestamp <= 0 || !isFinite(timestamp)) {
|
|
75
75
|
throw new StandardWebhooksError("standard-webhooks/bad-timestamp",
|
|
76
76
|
"sign: timestamp must be a positive finite integer");
|
|
@@ -148,7 +148,7 @@ function verify(opts) {
|
|
|
148
148
|
numericBounds.requirePositiveFiniteIntIfPresent(opts.toleranceSec, "toleranceSec",
|
|
149
149
|
StandardWebhooksError, "standard-webhooks/bad-tolerance");
|
|
150
150
|
var tolerance = typeof opts.toleranceSec === "number" ? opts.toleranceSec : DEFAULT_TOLERANCE_SEC;
|
|
151
|
-
var nowSec = Math.floor(Date.now() / 1000);
|
|
151
|
+
var nowSec = Math.floor(Date.now() / 1000);
|
|
152
152
|
if (Math.abs(nowSec - ts) > tolerance) {
|
|
153
153
|
throw new StandardWebhooksError("standard-webhooks/timestamp-skew",
|
|
154
154
|
"verify: timestamp skew " + Math.abs(nowSec - ts) + "s exceeds tolerance " + tolerance + "s");
|
package/lib/static.js
CHANGED
|
@@ -216,7 +216,7 @@ function _resolveSafe(root, requestedPath) {
|
|
|
216
216
|
// deposited disk content: shell-exec extensions (.exe / .bin / .so /
|
|
217
217
|
// legitimate `<name>.<hash>.js` bundler output) are valid here. The
|
|
218
218
|
// other balanced checks still reject the traversal + smuggling
|
|
219
|
-
// surface
|
|
219
|
+
// surface.
|
|
220
220
|
var fname = nodePath.basename(resolved);
|
|
221
221
|
var rv = guardFilename().validate(fname, {
|
|
222
222
|
profile: "balanced",
|
package/lib/stream-throttle.js
CHANGED
|
@@ -71,9 +71,9 @@ var StreamThrottleError = defineClass("StreamThrottleError", { alwaysPermanent:
|
|
|
71
71
|
// (bytes/sec ↔ wait-ms). This is a unit-conversion constant, not a
|
|
72
72
|
// memory cap or protocol-byte literal; the framework's C.TIME / C.BYTES
|
|
73
73
|
// helpers don't apply.
|
|
74
|
-
var MS_PER_SECOND = 1000;
|
|
74
|
+
var MS_PER_SECOND = 1000;
|
|
75
75
|
var NS_PER_MS = 1e6; // ns/ms unit conversion
|
|
76
|
-
var MS_PER_SECOND_HRTIME = 1000;
|
|
76
|
+
var MS_PER_SECOND_HRTIME = 1000;
|
|
77
77
|
|
|
78
78
|
/**
|
|
79
79
|
* @primitive b.streamThrottle.create
|
package/lib/structured-fields.js
CHANGED
|
@@ -542,7 +542,7 @@ function parse(input, type, opts) {
|
|
|
542
542
|
|
|
543
543
|
function _serDecimal(v, E) {
|
|
544
544
|
if (!isFinite(v)) throw E("structured-fields/serialize", "cannot serialize a non-finite decimal");
|
|
545
|
-
var n = Math.round(v * 1000) / 1000; // allow:raw-time-literal — RFC 8941
|
|
545
|
+
var n = Math.round(v * 1000) / 1000; // allow:raw-time-literal — RFC 8941 4.1.5 decimal-scale 10^3 rounding; coincidental * 1000, not a duration, C.TIME N/A
|
|
546
546
|
if (Math.abs(Math.trunc(n)).toString().length > 12) throw E("structured-fields/serialize", "decimal integer part exceeds 12 digits"); // §4.1.5 cap
|
|
547
547
|
var s = n.toString();
|
|
548
548
|
if (s.indexOf(".") === -1) s += ".0"; // a Decimal must carry a fractional part
|
package/lib/subject.js
CHANGED
|
@@ -362,7 +362,7 @@ function erase(subjectId, opts) {
|
|
|
362
362
|
|
|
363
363
|
// ---- Crypto-shred erase (Art. 17 + WAL/replica residual closure) ----
|
|
364
364
|
//
|
|
365
|
-
//
|
|
365
|
+
// When a table opts into per-row keying via
|
|
366
366
|
// b.cryptoField.declarePerRowKey, this primitive deletes the
|
|
367
367
|
// per-row K_row entries from _blamejs_per_row_keys, leaving any
|
|
368
368
|
// residual ciphertext in WAL / replica / backup storage
|
|
@@ -477,7 +477,7 @@ function eraseHard(subjectId, opts) {
|
|
|
477
477
|
totalDeleted += deleted;
|
|
478
478
|
perTable[spec.name] = deleted;
|
|
479
479
|
// REINDEX the table so B-tree pages holding the deleted row's
|
|
480
|
-
// index entries are rebuilt — closes the
|
|
480
|
+
// index entries are rebuilt — closes the erase-vacuum residual class.
|
|
481
481
|
try { db().runSql('REINDEX "' + spec.name + '"'); } // table name comes from FRAMEWORK_SCHEMA
|
|
482
482
|
catch (_e) { /* cluster mode / unsupported dialect */ }
|
|
483
483
|
}
|
package/lib/vault/index.js
CHANGED
|
@@ -102,11 +102,12 @@ function resolvePaths(dataDir) {
|
|
|
102
102
|
plaintext: nodePath.join(dataDir, "vault.key"),
|
|
103
103
|
sealed: nodePath.join(dataDir, "vault.key.sealed"),
|
|
104
104
|
derivedHashSalt: nodePath.join(dataDir, "vault.derived-hash-salt"),
|
|
105
|
+
derivedHashMacKey: nodePath.join(dataDir, "vault.derived-hash-mac.sealed"),
|
|
105
106
|
};
|
|
106
107
|
}
|
|
107
108
|
|
|
108
109
|
// derivedHashSalt — per-deployment salt for crypto-field
|
|
109
|
-
// derivedHashes
|
|
110
|
+
// derivedHashes. Pre-v0.8.42 the deterministic
|
|
110
111
|
// sha3(namespace + plaintext) shape allowed cross-deployment
|
|
111
112
|
// rainbow + cross-table correlation; binding a 32-byte
|
|
112
113
|
// per-deployment salt closes that class without breaking
|
|
@@ -175,6 +176,66 @@ function getDerivedHashSalt() {
|
|
|
175
176
|
return _cachedDerivedHashSalt;
|
|
176
177
|
}
|
|
177
178
|
|
|
179
|
+
// derivedHashMacKey — per-deployment SECRET key for crypto-field's
|
|
180
|
+
// keyed (hmac-shake256) derived-hash mode. Unlike the salt, this is
|
|
181
|
+
// SEALED at rest (vault.derived-hash-mac.sealed), so an attacker with
|
|
182
|
+
// disk access alone cannot recompute the keyed digest and correlate
|
|
183
|
+
// low-entropy plaintexts. Like the salt, it is keypair-bound and
|
|
184
|
+
// survives a passphrase-only rotation; an ENVELOPE rotation re-seals it
|
|
185
|
+
// because it is registered in rotate's additionalSealed sweep.
|
|
186
|
+
function _readOrCreateDerivedHashMacKey() {
|
|
187
|
+
if (!paths) {
|
|
188
|
+
throw new VaultError("vault/not-initialized",
|
|
189
|
+
"vault.getDerivedHashMacKey() requires init()");
|
|
190
|
+
}
|
|
191
|
+
if (nodeFs.existsSync(paths.derivedHashMacKey)) {
|
|
192
|
+
var sealed = atomicFile.readSync(paths.derivedHashMacKey, { encoding: "utf8" }).trim();
|
|
193
|
+
var b64 = unseal(sealed);
|
|
194
|
+
var key = Buffer.from(b64, "base64");
|
|
195
|
+
if (key.length !== 32) { // 32-byte (256-bit) MAC key
|
|
196
|
+
throw new VaultError("vault/derived-hash-mac-key-corrupted",
|
|
197
|
+
"vault.derived-hash-mac key must unseal to exactly 32 bytes; got " + key.length);
|
|
198
|
+
}
|
|
199
|
+
return key;
|
|
200
|
+
}
|
|
201
|
+
var nodeCrypto = require("node:crypto");
|
|
202
|
+
var raw = nodeCrypto.randomBytes(32); // 32-byte MAC key
|
|
203
|
+
atomicFile.writeSync(paths.derivedHashMacKey, seal(raw.toString("base64")), { fileMode: 0o600 });
|
|
204
|
+
log("generated per-deployment derivedHash MAC key at " + paths.derivedHashMacKey);
|
|
205
|
+
return raw;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
var _cachedDerivedHashMacKey = null;
|
|
209
|
+
/**
|
|
210
|
+
* @primitive b.vault.getDerivedHashMacKey
|
|
211
|
+
* @signature b.vault.getDerivedHashMacKey()
|
|
212
|
+
* @since 0.14.7
|
|
213
|
+
* @related b.vault.getDerivedHashSalt, b.cryptoField.registerTable
|
|
214
|
+
*
|
|
215
|
+
* Returns the 32-byte per-deployment SECRET key that backs crypto-
|
|
216
|
+
* field's keyed (`hmac-shake256`) derived-hash mode. Generated once on
|
|
217
|
+
* first use, SEALED at rest (`vault.derived-hash-mac.sealed`, mode
|
|
218
|
+
* `0o600`) so disk access alone does not expose it, and re-sealed by an
|
|
219
|
+
* envelope vault rotation. Distinct from `getDerivedHashSalt`, which is
|
|
220
|
+
* a non-secret salt stored in plaintext.
|
|
221
|
+
*
|
|
222
|
+
* Throws `VaultError("vault/not-initialized")` before `init()`, or
|
|
223
|
+
* `vault/derived-hash-mac-key-corrupted` if the sealed file does not
|
|
224
|
+
* unseal to exactly 32 bytes.
|
|
225
|
+
*
|
|
226
|
+
* @example
|
|
227
|
+
* await b.vault.init({ dataDir: "/var/lib/blamejs", mode: "plaintext" });
|
|
228
|
+
* var k = b.vault.getDerivedHashMacKey();
|
|
229
|
+
* k.length; // → 32
|
|
230
|
+
* Buffer.isBuffer(k); // → true
|
|
231
|
+
*/
|
|
232
|
+
function getDerivedHashMacKey() {
|
|
233
|
+
if (_cachedDerivedHashMacKey === null) {
|
|
234
|
+
_cachedDerivedHashMacKey = _readOrCreateDerivedHashMacKey();
|
|
235
|
+
}
|
|
236
|
+
return _cachedDerivedHashMacKey;
|
|
237
|
+
}
|
|
238
|
+
|
|
178
239
|
// ---- Init dispatch ----
|
|
179
240
|
|
|
180
241
|
/**
|
|
@@ -620,6 +681,7 @@ module.exports = {
|
|
|
620
681
|
seal: seal,
|
|
621
682
|
unseal: unseal,
|
|
622
683
|
getDerivedHashSalt: getDerivedHashSalt,
|
|
684
|
+
getDerivedHashMacKey: getDerivedHashMacKey,
|
|
623
685
|
_zeroizeAndReplace: _zeroizeAndReplace,
|
|
624
686
|
aad: vaultAad,
|
|
625
687
|
getKeysJson: getKeysJson,
|
|
@@ -633,6 +695,7 @@ module.exports = {
|
|
|
633
695
|
_resetForTest: function () {
|
|
634
696
|
if (currentPassphrase) safeBuffer.secureZero(currentPassphrase);
|
|
635
697
|
keys = null; initialized = false; currentPassphrase = null; paths = null; currentMode = null;
|
|
698
|
+
_cachedDerivedHashSalt = null; _cachedDerivedHashMacKey = null;
|
|
636
699
|
},
|
|
637
700
|
_getKeysForTest: function () { return keys; },
|
|
638
701
|
_getPathsForTest: function () { return paths; },
|
package/lib/vault/rotate.js
CHANGED
|
@@ -651,6 +651,25 @@ async function rotate(opts) {
|
|
|
651
651
|
_reSealValue(current, oldKeys, newKeys), { mode: 0o600 });
|
|
652
652
|
}
|
|
653
653
|
|
|
654
|
+
// 3b. Framework-managed crypto-field derived-hash files — always
|
|
655
|
+
// rotated regardless of operator opts.paths, so the staging copy is
|
|
656
|
+
// complete. The plaintext salt is copied verbatim; the SEALED MAC key
|
|
657
|
+
// (keyed hmac-shake256 mode) is re-sealed under the new keypair so an
|
|
658
|
+
// envelope rotation doesn't orphan it (a passphrase-only rotation
|
|
659
|
+
// re-seals to the same value since the keypair is unchanged).
|
|
660
|
+
var saltSrc = nodePath.join(dataDir, "vault.derived-hash-salt");
|
|
661
|
+
if (nodeFs.existsSync(saltSrc)) {
|
|
662
|
+
nodeFs.copyFileSync(saltSrc, nodePath.join(stagingDir, "vault.derived-hash-salt"));
|
|
663
|
+
}
|
|
664
|
+
var macSrc = nodePath.join(dataDir, "vault.derived-hash-mac.sealed");
|
|
665
|
+
if (nodeFs.existsSync(macSrc)) {
|
|
666
|
+
var macCurrent = nodeFs.readFileSync(macSrc, "utf8").trim();
|
|
667
|
+
if (macCurrent.indexOf(C.VAULT_PREFIX) === 0) {
|
|
668
|
+
nodeFs.writeFileSync(nodePath.join(stagingDir, "vault.derived-hash-mac.sealed"),
|
|
669
|
+
_reSealValue(macCurrent, oldKeys, newKeys), { mode: 0o600 });
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
|
|
654
673
|
// 4. decrypt + rotate + re-encrypt db.enc
|
|
655
674
|
_emit(progress, { phase: "rotate_db" });
|
|
656
675
|
var encDbPath = nodePath.join(dataDir, paths.encryptedDb);
|
|
@@ -81,7 +81,7 @@ var SealPemFileError = defineClass("SealPemFileError", { alwaysPermanent: true }
|
|
|
81
81
|
// doesn't sneak past the watcher. Operators with extremely-quiet
|
|
82
82
|
// renewal cycles can override via opts.pollInterval; the cost of
|
|
83
83
|
// 500ms polling on an idle PEM file is ~2 stat() syscalls/sec.
|
|
84
|
-
var DEFAULT_POLL_MS = 500;
|
|
84
|
+
var DEFAULT_POLL_MS = 500;
|
|
85
85
|
|
|
86
86
|
// PEM files are tiny — 4 KiB for an ECDSA key, ~8 KiB for a 4096-bit
|
|
87
87
|
// RSA key, ~64 KiB for a long cert chain. Cap at 1 MiB so an operator
|
package/lib/vendor-data.js
CHANGED
|
@@ -306,7 +306,7 @@ function _loadAndVerify(name) {
|
|
|
306
306
|
// Memoized — "sha256:" + sha256(pemToRaw(PUBKEY_PEM)). Matches the
|
|
307
307
|
// canonical fingerprint shape `scripts/vendor-data-gen.js` writes into
|
|
308
308
|
// each .data.js's `metadata.publicKeyFingerprint`. Computed lazily on
|
|
309
|
-
// first verify (also lazily by verifyAll at boot).
|
|
309
|
+
// first verify (also lazily by verifyAll at boot). Every
|
|
310
310
|
// per-entry verify cross-checks this against the entry's declared
|
|
311
311
|
// `meta.publicKeyFingerprint` so a pubkey-swap attack fails before
|
|
312
312
|
// signature verify even runs.
|
package/lib/web-push-vapid.js
CHANGED
|
@@ -134,7 +134,7 @@ function buildVapidAuthHeader(opts) {
|
|
|
134
134
|
"buildVapidAuthHeader: subscription.endpoint is not a parseable URL");
|
|
135
135
|
}
|
|
136
136
|
var aud = endpointUrl.origin;
|
|
137
|
-
var now = Math.floor(Date.now() / 1000);
|
|
137
|
+
var now = Math.floor(Date.now() / 1000);
|
|
138
138
|
// Inline JWT sign with ES256 — VAPID strictly mandates ECDSA-P256
|
|
139
139
|
// (RFC 8292 §3.1). The framework jwt.sign is PQC-first and refuses
|
|
140
140
|
// ES256 by design; VAPID is a wire-protocol constraint outside
|
package/lib/webhook.js
CHANGED
|
@@ -955,7 +955,7 @@ function sign(input) {
|
|
|
955
955
|
}
|
|
956
956
|
ts = Math.floor(input.timestamp);
|
|
957
957
|
} else {
|
|
958
|
-
ts = Math.floor(Date.now() / 1000);
|
|
958
|
+
ts = Math.floor(Date.now() / 1000);
|
|
959
959
|
}
|
|
960
960
|
var hex = _hmacSha256Hex(secretBytes, ts + "." + bodyStr);
|
|
961
961
|
return "t=" + ts + ",v1=" + hex;
|
package/lib/websocket.js
CHANGED
|
@@ -191,7 +191,7 @@ var CLOSE_GRACE_MS = C.TIME.seconds(2);
|
|
|
191
191
|
function _isValidCloseCode(code) {
|
|
192
192
|
if (code === 1004 || code === 1005 || code === 1006 || code === 1015) return false; // RFC 6455 §7.4.2 reserved codes
|
|
193
193
|
if (code >= 1000 && code <= 1011) return true; // allow:raw-time-literal — code is a numeric, not seconds
|
|
194
|
-
if (code >= 3000 && code <= 4999) return true; // allow:raw-time-literal — code
|
|
194
|
+
if (code >= 3000 && code <= 4999) return true; // allow:raw-time-literal — WebSocket close-code range bound (RFC 6455 7.4.2); coincidental multiple-of-60, C.TIME N/A
|
|
195
195
|
return false;
|
|
196
196
|
}
|
|
197
197
|
|
package/package.json
CHANGED
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:
|
|
5
|
+
"serialNumber": "urn:uuid:013c541c-8703-45e9-9154-89bc05b3998c",
|
|
6
6
|
"version": 1,
|
|
7
7
|
"metadata": {
|
|
8
|
-
"timestamp": "2026-05-
|
|
8
|
+
"timestamp": "2026-05-30T23:34:15.711Z",
|
|
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.14.
|
|
22
|
+
"bom-ref": "@blamejs/core@0.14.8",
|
|
23
23
|
"type": "application",
|
|
24
24
|
"name": "blamejs",
|
|
25
|
-
"version": "0.14.
|
|
25
|
+
"version": "0.14.8",
|
|
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.14.
|
|
29
|
+
"purl": "pkg:npm/%40blamejs/core@0.14.8",
|
|
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.14.
|
|
57
|
+
"ref": "@blamejs/core@0.14.8",
|
|
58
58
|
"dependsOn": []
|
|
59
59
|
}
|
|
60
60
|
]
|