@blamejs/core 0.13.9 → 0.13.10
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 +2 -0
- package/lib/archive-read.js +17 -0
- package/lib/auth/fal.js +12 -0
- package/lib/auth/jwt-external.js +9 -8
- package/lib/auth/oauth.js +5 -4
- package/lib/auth/oid4vci.js +3 -3
- package/lib/auth/sd-jwt-vc.js +3 -3
- package/lib/calendar.js +8 -1
- package/lib/circuit-breaker.js +5 -4
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,8 @@ upgrading across more than a few patches at a time.
|
|
|
8
8
|
|
|
9
9
|
## v0.13.x
|
|
10
10
|
|
|
11
|
+
- v0.13.10 (2026-05-27) — **Documented-but-inert options wired up, a non-existent CVE reference removed, and a silent iCalendar cap-bypass fixed.** A sweep for places where a documented option or citation did not match what the code does. The most operator-relevant fix: b.calendar.fromIcal documented a safeIcalOpts option that forwards parser caps (byte size, RRULE limits, nesting depth) to b.safeIcal.parse, but the value was never forwarded — so an operator who set tight caps through it got the default profile instead, silently. That is corrected; the nested options now reach the parser. b.archive.read.zip documented an AbortSignal option that was never honored; it now aborts the read at the entry boundary. b.auth.fal documented a bearerOnly alias that had no effect; it now forces the no-proof-of-possession path and refuses the contradictory combination of bearerOnly:true with a holder-of-key binding. Separately, the auth verification paths cited CVE-2026-23993 (13 places) for the "reject an unknown alg before key lookup" guard — that CVE id does not exist (the registry has no record of it); the citation is replaced with the weakness class (CWE-347 / CWE-757) and the real, verifiable neighboring CVEs. The circuit-breaker error-code note that promised a rename "in v0.10" is corrected to the actual plan (v1.0), and the build gate that catches overdue version promises now also catches two-part version numbers. **Changed:** *`b.auth.fal` `bearerOnly` is now a real alias and refuses contradictions* — `bearerOnly: true` now forces the no-proof-of-possession path (equivalent to `hokBinding: null`), as documented. Passing `bearerOnly: true` together with a non-null `hokBinding` is a contradictory assurance request and is now refused at the call rather than silently resolved one way. **Fixed:** *`b.calendar.fromIcal` now forwards `safeIcalOpts` to the parser* — The documented `safeIcalOpts` option (parser caps: max bytes, RRULE COUNT/BYxxx limits, nesting depth) was not being passed to `b.safeIcal.parse` — when supplied under the documented nested key it was silently ignored and the parser ran with its default profile. Both forms now reach the parser: the documented nested `{ safeIcalOpts: { ... } }` and the top-level `{ profile, ... }` that earlier releases accepted, with the nested form winning on conflict. No caller regresses. · *`b.archive.read.zip` honors the documented `signal` (AbortSignal)* — The `signal` option was documented but never read. A large or slow archive read can now be aborted cooperatively — the reader checks the signal at each entry boundary (`inspect`, `entries`, `extractEntries`, `extract`) and rejects with an `archive-read/aborted` error. · *Removed a non-existent CVE reference from the JWT/JWE verification paths* — The "reject an unknown/unsupported `alg` before any key lookup" guard in `b.auth.jwt.verifyExternal`, `b.auth.oauth.verifyIdToken`, `b.auth.oid4vci`, and `b.auth.sd-jwt-vc` cited a CVE id that the registry has no record of. The behaviour is unchanged; the citation is now the weakness class it defends (CWE-347 improper signature verification / CWE-757 algorithm downgrade) alongside the real, verifiable alg-confusion / JWE-bypass CVEs already cited beside it. **Detectors:** *Overdue-version-promise gate now catches two-part version numbers* — The build gate that flags a deferral whose promised landing version has already shipped previously matched only three-part versions (`vN.N.N`); a two-part promise (`vN.N`) slipped past it. It now matches both. The `b.circuitBreaker` `CIRCUIT_OPEN` error-code note that pointed at a passed version is corrected to its actual plan (rename at v1.0, with a deprecation warning a minor ahead).
|
|
12
|
+
|
|
11
13
|
- v0.13.9 (2026-05-26) — **Corrected CVE citations in source threat annotations + a build gate that refuses malformed CVE identifiers.** Several source-comment threat annotations cited CVE identifiers that were rejected by the numbering authority (never assigned to a real issue), attributed to the wrong product, or structurally malformed (a placeholder with a non-numeric sequence). The annotated defenses are unchanged — every cap, refusal, and constant-time comparison behaves exactly as before; only the reference labels were corrected, each to a verifiable CVE or to the underlying weakness class (CWE / RFC) where no single CVE fits. Notable corrections: the S/MIME SHA-1 / MD5 certificate-signature refusal now cites the SHAttered collision and RFC 8551 §2.5 instead of a rejected candidate id; decompression-output caps cite CWE-409 and CVE-2025-0725 instead of a fabricated placeholder; the iCalendar RRULE / nesting / byte caps describe the calendar-bomb recursion-DoS class instead of an unrelated SSRF advisory; and the SAML signature-wrapping (XSW) defense now cites the actively-exploited CVE-2024-45409 (ruby-saml, CVSS 10.0) and CVE-2025-25291 / -25292 that the duplicate-element refusal defeats. A new build-time detector refuses any CVE token whose sequence number is not all-numeric, so a placeholder identifier can never reach a release again. **Fixed:** *Corrected rejected / misattributed / malformed CVE references in source threat annotations* — Threat-annotation comments across the mail, crypto, auth, guard, and safe modules carried CVE identifiers that were rejected by the CVE numbering authority, attributed to the wrong product, or written as non-numeric placeholders. Each was corrected to a verifiable CVE or to the weakness class (CWE / RFC) it defends. No runtime behaviour changed — the defenses these comments describe are unchanged. The S/MIME certificate check's SHA-1 / MD5 refusal message now names the SHAttered collision and RFC 8551 §2.5; the SAML XSW defense now names CVE-2024-45409 and CVE-2025-25291 / -25292. **Detectors:** *`malformed-cve-identifier` — refuses structurally-invalid CVE tokens at build time* — A CVE identifier's sequence number is always numeric (`CVE-<year>-<digits>`). The new detector refuses any CVE token whose post-year segment contains a letter — the placeholder shape that lets a fabricated reference slip past review. It cannot verify that a well-formed id is real or correctly attributed (that stays a review responsibility), but it makes the structurally-invalid class impossible to ship.
|
|
12
14
|
|
|
13
15
|
- v0.13.8 (2026-05-26) — **In-memory archive extraction for read-only / serverless filesystems.** Archive readers gain an in-memory extraction path so an uploaded archive can be opened and its contents read without writing anything to disk — the case a read-only or ephemeral serverless filesystem requires. b.archive.read.zip(...).extractEntries() and b.archive.read.tar(...).extractEntries() are async generators that yield each regular file entry as { name, bytes, size }, applying the same bomb-policy caps, b.guardArchive metadata cascade (which refuses a Zip-Slip / traversal archive wholesale), and entry-type-policy refusals as the disk extract() — only the disk realpath agreement check is omitted, since nothing is written and the caller owns where the returned bytes land. Directory and link entries carry no content and are not yielded. The guard cascade is factored into one shared path so disk and in-memory extraction refuse identically. Also a documentation fix: b.archive.gz no longer claims a b.archive.zip().toGzip() convenience exists — a ZIP is already DEFLATE-compressed per entry, so gzip-wrapping it gains nothing; gzip the uncompressed tar stream (the canonical .tar.gz) instead. **Added:** *`extractEntries()` — in-memory archive extraction (ZIP + tar)* — `b.archive.read.zip(source).extractEntries(opts?)` and `b.archive.read.tar(source).extractEntries(opts?)` are async generators yielding `{ name, bytes, size }` per regular file entry, never touching disk — for serverless / read-only filesystems where the disk `extract({ destination })` path cannot run. Same bomb-policy, guard-archive cascade, and entry-type-policy refusals as disk extraction; the bytes are byte-identical to what `extract()` writes. **Fixed:** *Removed the inaccurate `b.archive.zip().toGzip()` doc claim* — The `b.archive.gz` documentation described a `b.archive.zip().toGzip()` convenience method that does not (and should not) exist: a ZIP is already DEFLATE-compressed per entry, so gzip-wrapping it would compress already-compressed data for no benefit. `b.archive.tar().toGzip()` (the real `.tar.gz`) is unchanged.
|
package/lib/archive-read.js
CHANGED
|
@@ -503,6 +503,18 @@ function zip(adapter, opts) {
|
|
|
503
503
|
var entryTypePolicy = _normalizeEntryTypePolicy(opts.entryTypePolicy);
|
|
504
504
|
var cdCache = null;
|
|
505
505
|
|
|
506
|
+
// Cooperative cancellation — operators pass an AbortSignal to bound a
|
|
507
|
+
// large/slow archive read. Checked between entries (the natural yield
|
|
508
|
+
// point); a long single-entry decompress is already bounded by the
|
|
509
|
+
// bomb policy.
|
|
510
|
+
function _throwIfAborted() {
|
|
511
|
+
if (opts.signal && opts.signal.aborted) {
|
|
512
|
+
throw new ArchiveReadError("archive-read/aborted",
|
|
513
|
+
"archive read aborted via opts.signal" +
|
|
514
|
+
(opts.signal.reason !== undefined ? ": " + String(opts.signal.reason) : ""));
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
506
518
|
async function _loadCD() {
|
|
507
519
|
if (cdCache) return cdCache;
|
|
508
520
|
var eocd = await _locateEocd(adapter);
|
|
@@ -512,6 +524,7 @@ function zip(adapter, opts) {
|
|
|
512
524
|
}
|
|
513
525
|
|
|
514
526
|
async function inspect() {
|
|
527
|
+
_throwIfAborted();
|
|
515
528
|
var loaded = await _loadCD();
|
|
516
529
|
_enforceBombPolicy(loaded.entries, bombPolicy);
|
|
517
530
|
_emitAudit(opts, "archive.read.inspect", "success", {
|
|
@@ -539,9 +552,11 @@ function zip(adapter, opts) {
|
|
|
539
552
|
}
|
|
540
553
|
|
|
541
554
|
async function* entries() {
|
|
555
|
+
_throwIfAborted();
|
|
542
556
|
var loaded = await _loadCD();
|
|
543
557
|
_enforceBombPolicy(loaded.entries, bombPolicy);
|
|
544
558
|
for (var i = 0; i < loaded.entries.length; i += 1) {
|
|
559
|
+
_throwIfAborted();
|
|
545
560
|
yield loaded.entries[i];
|
|
546
561
|
}
|
|
547
562
|
}
|
|
@@ -593,6 +608,7 @@ function zip(adapter, opts) {
|
|
|
593
608
|
var totalDecompressed = 0;
|
|
594
609
|
var yielded = 0;
|
|
595
610
|
for (var i = 0; i < loaded.entries.length; i += 1) {
|
|
611
|
+
_throwIfAborted();
|
|
596
612
|
var entry = loaded.entries[i];
|
|
597
613
|
if (entry.isEncrypted && !extractOpts.allowEncrypted) {
|
|
598
614
|
throw new ArchiveReadError("archive-read/encrypted-entry",
|
|
@@ -644,6 +660,7 @@ function zip(adapter, opts) {
|
|
|
644
660
|
var totalDecompressed = 0;
|
|
645
661
|
try {
|
|
646
662
|
for (var i = 0; i < loaded.entries.length; i += 1) {
|
|
663
|
+
_throwIfAborted();
|
|
647
664
|
var entry = loaded.entries[i];
|
|
648
665
|
// Skip directory + dangerous-by-default entry types unless the
|
|
649
666
|
// entry-type policy opts in.
|
package/lib/auth/fal.js
CHANGED
|
@@ -155,6 +155,18 @@ function fromAssertion(opts) {
|
|
|
155
155
|
"fal.fromAssertion: channel must be 'front' or 'back'");
|
|
156
156
|
}
|
|
157
157
|
var hokBinding = opts.hokBinding;
|
|
158
|
+
// `bearerOnly: true` is the explicit alias for "no proof-of-possession
|
|
159
|
+
// binding" (hokBinding === null). It contradicts a non-null hokBinding;
|
|
160
|
+
// refuse the contradiction at the entry point rather than silently
|
|
161
|
+
// picking one — an operator who sets both has a config bug.
|
|
162
|
+
if (opts.bearerOnly === true) {
|
|
163
|
+
if (hokBinding !== undefined && hokBinding !== null) {
|
|
164
|
+
throw new AuthError("auth/bad-fal-opts",
|
|
165
|
+
"fal.fromAssertion: bearerOnly:true conflicts with hokBinding '" + hokBinding +
|
|
166
|
+
"' (bearerOnly forces no proof-of-possession binding)");
|
|
167
|
+
}
|
|
168
|
+
hokBinding = null;
|
|
169
|
+
}
|
|
158
170
|
if (hokBinding !== undefined && hokBinding !== null) {
|
|
159
171
|
if (hokBinding !== "mtls" && hokBinding !== "dpop" && hokBinding !== "saml-hok") {
|
|
160
172
|
throw new AuthError("auth/bad-fal-opts",
|
package/lib/auth/jwt-external.js
CHANGED
|
@@ -175,8 +175,8 @@ function _assertAlgKtyMatch(alg, jwk) {
|
|
|
175
175
|
else if (alg === "ML-DSA-65" || alg === "ML-DSA-87") { expectedKty = "AKP"; }
|
|
176
176
|
else {
|
|
177
177
|
// Unknown alg — caller's alg allowlist should have rejected first;
|
|
178
|
-
// refuse here defensively (
|
|
179
|
-
// that skip downstream verification).
|
|
178
|
+
// refuse here defensively (CWE-347 alg-confusion class — unknown-alg
|
|
179
|
+
// paths that skip downstream verification; cf. CVE-2026-22817).
|
|
180
180
|
throw new AuthError("auth-jwt-external/unsupported-alg",
|
|
181
181
|
"_assertAlgKtyMatch: alg '" + alg + "' has no defined key-type binding");
|
|
182
182
|
}
|
|
@@ -336,7 +336,7 @@ async function verifyExternal(token, opts) {
|
|
|
336
336
|
|
|
337
337
|
// Decode header + payload.
|
|
338
338
|
var parts = token.split(".");
|
|
339
|
-
// CVE-2026-29000 / CVE-2026-
|
|
339
|
+
// CVE-2026-29000 / CVE-2026-22817 / CVE-2026-34950 —
|
|
340
340
|
// JWE-bypass + alg-confusion. A 5-segment compact serialization is a
|
|
341
341
|
// JWE (RFC 7516); accepting it on a JWS verifier is the canonical
|
|
342
342
|
// confused-deputy shape. verifyExternal is JWS-only; refuse JWE
|
|
@@ -350,7 +350,7 @@ async function verifyExternal(token, opts) {
|
|
|
350
350
|
}); } catch (_e) { /* audit best-effort */ }
|
|
351
351
|
throw new AuthError("auth-jwt-external/jwe-refused",
|
|
352
352
|
"5-segment JWE token refused — verifyExternal only handles JWS " +
|
|
353
|
-
"(JWE bypass class — CVE-2026-29000 / CVE-2026-
|
|
353
|
+
"(JWE bypass class — CVE-2026-29000 / CVE-2026-22817 / CVE-2026-34950)");
|
|
354
354
|
}
|
|
355
355
|
if (parts.length !== 3) {
|
|
356
356
|
throw new AuthError("auth-jwt-external/malformed-jwt",
|
|
@@ -371,8 +371,9 @@ async function verifyExternal(token, opts) {
|
|
|
371
371
|
throw new AuthError("auth-jwt-external/unknown-crit",
|
|
372
372
|
"token declares 'crit' header — verifyExternal does not support critical extensions");
|
|
373
373
|
}
|
|
374
|
-
//
|
|
375
|
-
//
|
|
374
|
+
// Alg-allowlist gate (CWE-347 improper-sig-verification / CWE-757
|
|
375
|
+
// algorithm-downgrade) — refuse alg values outside the accepted list
|
|
376
|
+
// BEFORE any key lookup. The early refusal closes the class where an
|
|
376
377
|
// unknown / unsupported alg slips through to a downstream code path
|
|
377
378
|
// that interprets it permissively. The per-listed algorithm check
|
|
378
379
|
// above in the opts-validation loop refuses the OPERATOR'S allowlist
|
|
@@ -381,11 +382,11 @@ async function verifyExternal(token, opts) {
|
|
|
381
382
|
if (opts.algorithms.indexOf(header.alg) === -1) {
|
|
382
383
|
throw new AuthError("auth-jwt-external/alg-not-allowed",
|
|
383
384
|
"token alg='" + header.alg + "' not in allowed list [" + opts.algorithms.join(", ") +
|
|
384
|
-
"] (
|
|
385
|
+
"] (alg-allowlist gate — refused before key lookup)");
|
|
385
386
|
}
|
|
386
387
|
if (SUPPORTED_CLASSICAL_ALGS.indexOf(header.alg) === -1) {
|
|
387
388
|
throw new AuthError("auth-jwt-external/unsupported-alg",
|
|
388
|
-
"token alg='" + header.alg + "' is not in the verifier's supported set (
|
|
389
|
+
"token alg='" + header.alg + "' is not in the verifier's supported set (alg-allowlist gate)");
|
|
389
390
|
}
|
|
390
391
|
|
|
391
392
|
// Resolve key.
|
package/lib/auth/oauth.js
CHANGED
|
@@ -1008,7 +1008,7 @@ function create(opts) {
|
|
|
1008
1008
|
throw new OAuthError("auth-oauth/no-id-token", "verifyIdToken: idToken must be a string");
|
|
1009
1009
|
}
|
|
1010
1010
|
var parts = idToken.split(".");
|
|
1011
|
-
// CVE-2026-29000 / CVE-2026-22817
|
|
1011
|
+
// CVE-2026-29000 / CVE-2026-22817 — mirror
|
|
1012
1012
|
// jwt-external's 5-segment JWE refusal. A 5-segment compact
|
|
1013
1013
|
// serialization is a JWE (RFC 7516); verifyIdToken is a JWS verifier
|
|
1014
1014
|
// and a JWE shape reaching here is the confused-deputy class an OP
|
|
@@ -1023,7 +1023,7 @@ function create(opts) {
|
|
|
1023
1023
|
}); } catch (_e) { /* drop-silent — observability sink */ }
|
|
1024
1024
|
throw new OAuthError("auth-oauth/jwe-refused",
|
|
1025
1025
|
"5-segment JWE id_token refused — verifyIdToken only handles JWS " +
|
|
1026
|
-
"(CVE-2026-29000 / CVE-2026-
|
|
1026
|
+
"(CVE-2026-29000 / CVE-2026-22817 / CVE-2026-34950 JWE-bypass class)");
|
|
1027
1027
|
}
|
|
1028
1028
|
if (parts.length !== 3) {
|
|
1029
1029
|
throw new OAuthError("auth-oauth/malformed-jwt", "ID token does not have 3 parts");
|
|
@@ -1039,13 +1039,14 @@ function create(opts) {
|
|
|
1039
1039
|
if (!header || typeof header.alg !== "string") {
|
|
1040
1040
|
throw new OAuthError("auth-oauth/malformed-jwt", "ID token header missing 'alg'");
|
|
1041
1041
|
}
|
|
1042
|
-
//
|
|
1042
|
+
// Alg-allowlist gate (CWE-347 / CWE-757) — refuse unknown alg BEFORE
|
|
1043
|
+
// any key resolution.
|
|
1043
1044
|
// The acceptedAlgorithms list is the operator's posture; an alg
|
|
1044
1045
|
// outside it never reaches the JWKS lookup or node:crypto.verify.
|
|
1045
1046
|
if (acceptedAlgorithms.indexOf(header.alg) === -1) {
|
|
1046
1047
|
throw new OAuthError("auth-oauth/alg-not-accepted",
|
|
1047
1048
|
"ID token signed with '" + header.alg + "' which is not in the accepted-algorithm list " +
|
|
1048
|
-
"(
|
|
1049
|
+
"(alg-allowlist gate — refused before key lookup)");
|
|
1049
1050
|
}
|
|
1050
1051
|
// RFC 7515 §4.1.11 — refuse JWS with `crit` header. Every other
|
|
1051
1052
|
// verifier in the framework (jwt.js, jwt-external.js, dpop.js)
|
package/lib/auth/oid4vci.js
CHANGED
|
@@ -108,14 +108,14 @@ function _verifyProofJwt(proofJwt, expectedAud, expectedCNonce, expectedClientId
|
|
|
108
108
|
throw new AuthError("auth-oid4vci/wrong-proof-typ",
|
|
109
109
|
"credential issuance: proof JWT typ must be \"openid4vci-proof+jwt\" (got \"" + header.typ + "\")");
|
|
110
110
|
}
|
|
111
|
-
//
|
|
112
|
-
// verify-side work. The supportedAlgs list is the issuer's posture;
|
|
111
|
+
// Alg-allowlist gate (CWE-347 / CWE-757) — refuse unknown / unsupported
|
|
112
|
+
// alg BEFORE any verify-side work. The supportedAlgs list is the issuer's posture;
|
|
113
113
|
// refusing here mirrors the discipline in oauth.verifyIdToken /
|
|
114
114
|
// jwt-external.verifyExternal.
|
|
115
115
|
if (!header.alg || supportedAlgs.indexOf(header.alg) === -1) {
|
|
116
116
|
throw new AuthError("auth-oid4vci/unsupported-proof-alg",
|
|
117
117
|
"credential issuance: proof JWT alg \"" + header.alg + "\" not in issuer-supported set " +
|
|
118
|
-
"(
|
|
118
|
+
"(alg-allowlist gate — refused before key lookup)");
|
|
119
119
|
}
|
|
120
120
|
// AUTH-5 / RFC 7515 §4.1.11 — refuse non-empty `crit`. Pre-v0.9.x
|
|
121
121
|
// silently ignored, letting an attacker-controlled wallet declare
|
package/lib/auth/sd-jwt-vc.js
CHANGED
|
@@ -441,15 +441,15 @@ async function verify(presentation, opts) {
|
|
|
441
441
|
"verify: malformed JWT header: " + e.message);
|
|
442
442
|
}
|
|
443
443
|
var alg = headerObj.alg;
|
|
444
|
-
//
|
|
445
|
-
// resolution. The shared `_assertAlgKtyMatch` helper repeats this
|
|
444
|
+
// Alg-allowlist gate (CWE-347 / CWE-757) — refuse unknown / unsupported
|
|
445
|
+
// alg BEFORE any key resolution. The shared `_assertAlgKtyMatch` helper repeats this
|
|
446
446
|
// check after the issuer key is resolved; doing it here too closes
|
|
447
447
|
// the gap where an issuerKeyResolver with side effects (network
|
|
448
448
|
// fetch, audit emit) would run even when the alg is unsupported.
|
|
449
449
|
if (typeof alg !== "string" || SUPPORTED_ALGS.indexOf(alg) === -1) {
|
|
450
450
|
throw new AuthError("auth-sd-jwt-vc/unsupported-alg",
|
|
451
451
|
"verify: header alg \"" + alg + "\" not in supported set " +
|
|
452
|
-
"(
|
|
452
|
+
"(alg-allowlist gate — refused before key lookup)");
|
|
453
453
|
}
|
|
454
454
|
// draft-ietf-oauth-sd-jwt-vc §3.1 — typ MUST be `vc+sd-jwt` (or
|
|
455
455
|
// `dc+sd-jwt` for digital-credential profile). Pre-v0.9.x the absent-
|
package/lib/calendar.js
CHANGED
|
@@ -354,7 +354,14 @@ function validate(jsCal) {
|
|
|
354
354
|
* // → { "@type":"Event", uid:"a@b", updated:"2026-05-21T10:00:00Z", ... }
|
|
355
355
|
*/
|
|
356
356
|
function fromIcal(text, opts) {
|
|
357
|
-
|
|
357
|
+
// Forward parser options to b.safeIcal.parse. Accept BOTH the
|
|
358
|
+
// documented nested form (`{ safeIcalOpts: { profile, caps, ... } }`)
|
|
359
|
+
// AND the historically-working top-level form (`{ profile: "balanced" }`)
|
|
360
|
+
// so neither caller regresses; the nested form wins on conflict. The
|
|
361
|
+
// `safeIcalOpts` wrapper key itself is stripped before forwarding.
|
|
362
|
+
var icalOpts = Object.assign({}, opts || {}, (opts && opts.safeIcalOpts) || {});
|
|
363
|
+
delete icalOpts.safeIcalOpts;
|
|
364
|
+
var ast = safeIcal.parse(text, icalOpts);
|
|
358
365
|
var events = (ast && ast.vcalendar && ast.vcalendar.vevent) || [];
|
|
359
366
|
var todos = (ast && ast.vcalendar && ast.vcalendar.vtodo) || [];
|
|
360
367
|
var journals = (ast && ast.vcalendar && ast.vcalendar.vjournal) || [];
|
package/lib/circuit-breaker.js
CHANGED
|
@@ -42,10 +42,11 @@ var retryHelper = require("./retry");
|
|
|
42
42
|
* with the framework's `create(opts)` vocabulary.
|
|
43
43
|
*
|
|
44
44
|
* The `CIRCUIT_OPEN` error code is a pre-v1 artifact — every other
|
|
45
|
-
* framework error class uses namespaced codes (`retry/...`).
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
45
|
+
* framework error class uses namespaced codes (`retry/...`). It is
|
|
46
|
+
* kept through the pre-1.0 line so existing operators who match
|
|
47
|
+
* `err.code === "CIRCUIT_OPEN"` aren't broken in a patch; the rename
|
|
48
|
+
* to a namespaced code lands at v1.0 alongside the namespaced-error
|
|
49
|
+
* sweep, with a deprecation warning shipping a minor ahead.
|
|
49
50
|
*
|
|
50
51
|
* @opts
|
|
51
52
|
* name: string, // identifier used in audit + state-change events
|
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:62fe872e-bfa6-4982-9eb9-f37d3f139663",
|
|
6
6
|
"version": 1,
|
|
7
7
|
"metadata": {
|
|
8
|
-
"timestamp": "2026-05-
|
|
8
|
+
"timestamp": "2026-05-27T08:47:25.364Z",
|
|
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.13.
|
|
22
|
+
"bom-ref": "@blamejs/core@0.13.10",
|
|
23
23
|
"type": "application",
|
|
24
24
|
"name": "blamejs",
|
|
25
|
-
"version": "0.13.
|
|
25
|
+
"version": "0.13.10",
|
|
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.13.
|
|
29
|
+
"purl": "pkg:npm/%40blamejs/core@0.13.10",
|
|
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.13.
|
|
57
|
+
"ref": "@blamejs/core@0.13.10",
|
|
58
58
|
"dependsOn": []
|
|
59
59
|
}
|
|
60
60
|
]
|