@blamejs/core 0.18.43 → 0.18.45

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.
@@ -59,6 +59,7 @@
59
59
  */
60
60
 
61
61
  var nodeUrl = require("node:url");
62
+ var codepointClass = require("./codepoint-class");
62
63
  var vendorData = require("./vendor-data");
63
64
  var pslDataModule = require("./vendor/public-suffix-list.data");
64
65
  var { PublicSuffixError } = require("./framework-error");
@@ -99,6 +100,32 @@ function _firstNonHostCharacter(name) {
99
100
  return -1;
100
101
  }
101
102
 
103
+ // The first character of an already-CONVERTED name that a domain may not
104
+ // contain, or -1.
105
+ //
106
+ // Run after `domainToASCII`, where the question has one answer: an
107
+ // internationalized label has become its `xn--` form by then, so a real name is
108
+ // letters, digits, hyphens and dots. `domainToASCII` is a UTS #46 MAPPER, not a
109
+ // hostname validator, and passes through 17 of the 31 non-LDH characters
110
+ // tested — `ex*ample.com`, `ex(ample.com` and `ex"ample.com` all came back as
111
+ // canonical domains, and a caller then compared one against a cookie domain, an
112
+ // SPF record or a residency table.
113
+ //
114
+ // Underscore is permitted. `_dmarc`, `_domainkey`, `_acme-challenge` and
115
+ // `_sip._tcp` are real DNS names, and whether to accept a service label is a
116
+ // POLICY question the framework already answers elsewhere — guardDomain's
117
+ // `underscorePolicy` refuses it at strict and allows it at permissive. This
118
+ // function normalizes a name; it does not judge one.
119
+ // Composed rather than hand-rolled: codepointClass owns the framework's
120
+ // character-set membership, caches the range table per distinct set, and reads
121
+ // as the rule it enforces. A charCodeAt loop here would be a fourth copy of a
122
+ // shape three files already have.
123
+ var _DOMAIN_CHARS = codepointClass.ASCII_ALNUM + "-._";
124
+
125
+ function _isLdhDomain(ascii) {
126
+ return codepointClass.isRunOf(ascii, _DOMAIN_CHARS, 1, ascii.length);
127
+ }
128
+
102
129
  // The characters UTS #46 treats as a label separator, and therefore the ones
103
130
  // that can mark the root of an absolute name. Scanned against Node's own
104
131
  // mapping and found to be exactly this set across the BMP and the SMP.
@@ -172,6 +199,14 @@ function _normalizeInput(domain) {
172
199
  throw _err("public-suffix/invalid-domain",
173
200
  "publicSuffix: domain contains empty label");
174
201
  }
202
+ // LDH, checked on the CONVERTED form — see _firstNonLdhCharacter for why the
203
+ // question only has one answer here.
204
+ if (!_isLdhDomain(ascii)) {
205
+ throw _err("public-suffix/invalid-domain",
206
+ "publicSuffix: domain contains a character that is not a letter, digit, " +
207
+ "hyphen, dot or underscore; domainToASCII MAPS such a name without " +
208
+ "validating it as a host, so `ex*ample.com` arrives here looking canonical");
209
+ }
175
210
  // RFC 1035 §2.3.4 — 253 octets max for the wire form (255 minus the leading
176
211
  // length byte and the root's null). This is the AUTHORITATIVE check, and it
177
212
  // has to run on the converted name: an internationalized label grows into its
@@ -190,6 +225,28 @@ function _normalizeInput(domain) {
190
225
  "publicSuffix: domain exceeds 253-octet RFC 1035 limit once converted " +
191
226
  "to A-labels (" + withoutRoot + " octets)");
192
227
  }
228
+ // RFC 1035 §2.3.4 bounds a LABEL at 63 octets as well as the whole name at
229
+ // 253, and only the second was checked. The argument is the one written above
230
+ // for the total: a 64-octet label cannot be put on the wire, and a caller
231
+ // handed one back cannot tell it apart from a name that can — this function
232
+ // returned `<64 a's>.com` as an organizational domain, and every resolver
233
+ // would refuse it. The rest of the framework already enforces both bounds
234
+ // (b.guardDomain, b.guardEmail, b.mailAuth); this was the one place that
235
+ // enforced one and not the other.
236
+ //
237
+ // Measured on the CONVERTED form for the same reason the total is: a 30-
238
+ // character internationalized label is well under 63 going in and can exceed
239
+ // it as an `xn--` A-label. The root marker, if still present, is not a label.
240
+ var labelSpan = ascii.slice(0, withoutRoot);
241
+ var labels = labelSpan.split(".");
242
+ for (var li = 0; li < labels.length; li += 1) {
243
+ if (labels[li].length > 63) {
244
+ throw _err("public-suffix/invalid-domain",
245
+ "publicSuffix: label " + JSON.stringify(labels[li].slice(0, 16) + "...") +
246
+ " is " + labels[li].length + " octets once converted to an A-label, over " +
247
+ "the 63-octet RFC 1035 limit");
248
+ }
249
+ }
193
250
  // The root marker is stripped here when it was not an ASCII dot on the way
194
251
  // in. UTS #46 maps U+3002, U+FF0E and U+FF61 to ".", so `münchen.example。`
195
252
  // arrives with no trailing dot and leaves the conversion with one. Returning
package/lib/time.js CHANGED
@@ -34,8 +34,15 @@
34
34
  */
35
35
  var C = require("./constants");
36
36
  var codepointClass = require("./codepoint-class");
37
+ var lazyRequire = require("./lazy-require");
38
+ var validateOpts = require("./validate-opts");
37
39
  var { defineClass } = require("./framework-error");
38
40
 
41
+ // Lazy: the drift report is the only thing that needs it, and loading the
42
+ // observability stack at require-time would pull it into every consumer of a
43
+ // date formatter.
44
+ var observability = lazyRequire(function () { return require("./observability"); });
45
+
39
46
  var TimeError = defineClass("TimeError", { alwaysPermanent: true });
40
47
 
41
48
  var DEFAULT_TIMEZONE = "UTC";
@@ -821,6 +828,279 @@ function stripIsoMilliseconds(text) {
821
828
  return text.slice(0, at) + "Z";
822
829
  }
823
830
 
831
+ // ---------------------------------------------------------------------------
832
+ // Monotonic wall clock.
833
+ // ---------------------------------------------------------------------------
834
+
835
+ // How far ahead of the underlying source a clock may run before it says so.
836
+ // One second buys a thousand stamps inside a single millisecond — well past
837
+ // any realistic write burst — while keeping a recorded timestamp close enough
838
+ // to true time that an auditor reading it is not misled.
839
+ var DEFAULT_MAX_DRIFT_MS = C.TIME.seconds(1);
840
+
841
+ /**
842
+ * @primitive b.time.monotonicClock
843
+ * @signature b.time.monotonicClock(opts?)
844
+ * @since 0.18.44
845
+ * @status stable
846
+ * @related b.time.monotonicNow, b.chainWriter.create, b.ntpCheck.checkDrift
847
+ *
848
+ * An isolated clock whose `now()` never returns a value less than or equal to
849
+ * the one before it.
850
+ *
851
+ * `Date.now()` gives neither guarantee. It repeats when two writes land in the
852
+ * same millisecond, and it moves BACKWARDS when NTP steps the clock — the
853
+ * correction `b.ntpCheck` exists to detect. Anything that orders records by a
854
+ * timestamp inherits both problems: an append-only chain gets a row that
855
+ * appears to precede its predecessor, and keyset pagination over a timestamp
856
+ * column drops or repeats rows that share a millisecond.
857
+ *
858
+ * Three things the four-line hand-rolled version leaves out, and this settles:
859
+ *
860
+ * - **An injectable source.** `opts.source` defaults to `Date.now` but a test
861
+ * can hand over a scripted one, which a closure over `Date.now` cannot. It
862
+ * must return a SAFE-INTEGER count of milliseconds. A fractional clock such
863
+ * as `performance.timeOrigin + performance.now()` is refused rather than
864
+ * rounded: this primitive's whole promise is that the next value exceeds the
865
+ * last, and it keeps that promise by handing out `last + 1` when the source
866
+ * has not moved — arithmetic that needs an integer to stay exact.
867
+ * - **A floor that survives a restart.** Process memory resets to zero on
868
+ * restart or failover — precisely when a fresh node is syncing NTP and a
869
+ * backwards step is most likely. `observeFloor(ms)` seeds the guarantee from
870
+ * a value read back out of storage, and ignores anything below where the
871
+ * clock already is. It takes a NUMBER and refuses anything else, including
872
+ * the decimal string a Postgres `BIGINT` arrives as through most drivers:
873
+ * coercing a floor silently would accept `"abc"` as `NaN` and every later
874
+ * comparison against it as false, so the conversion is the caller's to make
875
+ * and to get wrong loudly.
876
+ * - **A ceiling on how far ahead of the source it may run.** A burst inside
877
+ * one millisecond walks the returned value into the future. Unbounded, that
878
+ * is a silently wrong timestamp; `maxDriftMs` is what makes it not silent.
879
+ *
880
+ * Passing the cap REPORTS — through `onDrift` when given, otherwise as the
881
+ * `time.monotonic.drift_exceeded` observability event — and keeps returning
882
+ * monotonic values. For the framework's own consumer, an append-only audit
883
+ * chain, a timestamp a few milliseconds optimistic is a smaller harm than a
884
+ * dropped row, and a dropped row is what an attacker who can step the clock
885
+ * would be aiming for. A caller whose property is timestamp ACCURACY rather
886
+ * than completeness asks for `strict: true` and gets a
887
+ * `time/monotonic-drift-cap` throw instead.
888
+ *
889
+ * The report never goes through `b.audit`: a clock that stamps audit rows and
890
+ * audits its own drift would call itself.
891
+ *
892
+ * @opts
893
+ * source: function, // default: Date.now — must return a SAFE-INTEGER number of ms
894
+ * maxDriftMs: number, // default: 1000 — lead over the source before it reports
895
+ * onDrift: function, // ({ driftMs, maxDriftMs, value, sourceMs, label }) — replaces the observability event
896
+ * strict: boolean, // default: false — true throws instead of reporting
897
+ * label: string, // default: "default" — names this clock in drift reports
898
+ *
899
+ * @example
900
+ * var clock = b.time.monotonicClock({ label: "device_event_log" });
901
+ * // Number(...) is not decoration: a Postgres BIGINT arrives as a decimal
902
+ * // STRING through most drivers, and observeFloor refuses one rather than
903
+ * // coercing it — a floor is too important to guess at.
904
+ * clock.observeFloor(Number(tipRow.recordedAt)); // durable, read from storage
905
+ * var recordedAt = clock.now();
906
+ * // → strictly greater than tipRow.recordedAt, whatever the wall clock did
907
+ */
908
+ function monotonicClock(opts) {
909
+ opts = opts || {};
910
+ validateOpts(opts, ["source", "maxDriftMs", "onDrift", "strict", "label"],
911
+ "b.time.monotonicClock");
912
+
913
+ validateOpts.shape(opts, {
914
+ source: { rule: "optional-function", code: "time/bad-source" },
915
+ maxDriftMs: { rule: "optional-non-negative", code: "time/bad-max-drift" },
916
+ onDrift: { rule: "optional-function", code: "time/bad-on-drift" },
917
+ strict: { rule: "optional-boolean", code: "time/bad-strict" },
918
+ label: { rule: "optional-string", code: "time/bad-label" },
919
+ }, "b.time.monotonicClock", TimeError, "time/bad-opts");
920
+
921
+ var source = opts.source == null ? Date.now : opts.source;
922
+ var maxDriftMs = opts.maxDriftMs == null ? DEFAULT_MAX_DRIFT_MS : opts.maxDriftMs;
923
+ var onDrift = opts.onDrift == null ? null : opts.onDrift;
924
+ var strict = opts.strict === true;
925
+ var label = opts.label == null ? "default" : opts.label;
926
+
927
+ var last = 0;
928
+ var lastSourceMs = 0;
929
+ var reporting = false;
930
+
931
+ function _report(info) {
932
+ // A reporter that calls now() re-enters here, and the re-entrant call drifts
933
+ // by construction - it is one millisecond further ahead than the call that
934
+ // triggered the report. Reporting that would recurse until the stack ran
935
+ // out, so the outermost report is the one that speaks for the burst.
936
+ if (reporting) return;
937
+ reporting = true;
938
+ try { _reportOnce(info); } finally { reporting = false; }
939
+ }
940
+
941
+ function _reportOnce(info) {
942
+ if (onDrift) {
943
+ // The caller's reporter is theirs to get wrong; a throw from it must not
944
+ // decide whether the timestamp was issued.
945
+ try { onDrift(info); } catch (_e) { /* drop-silent — see the block comment above */ }
946
+ return;
947
+ }
948
+ // Never b.audit: an audit row needs a timestamp, which needs this clock.
949
+ try {
950
+ observability().safeEvent("time.monotonic.drift_exceeded", info.driftMs, {
951
+ clock: info.label,
952
+ });
953
+ } catch (_e) { /* drop-silent — an observability failure must not stop the clock */ }
954
+ }
955
+
956
+ function now() {
957
+ // A drift report runs caller code in the middle of issuing a value. A
958
+ // reporter that asks this same clock for another one gets a HIGHER value
959
+ // and returns it BEFORE the call that triggered the report returns its
960
+ // lower one - so a callback that stamps its own log line records the drift
961
+ // at a later instant than the event it describes, which is time running
962
+ // backwards in the record this clock exists to keep straight.
963
+ //
964
+ // Refusing is the honest answer, and it costs the reporter nothing: the
965
+ // value being reported on is already in `info.value`. The throw is caught
966
+ // by _report's drop-silent wrapper, so it cannot fail the append that
967
+ // triggered the report. A DIFFERENT clock is unaffected - this is per
968
+ // instance, not a global lock.
969
+ if (reporting) {
970
+ throw new TimeError("time/monotonic-reentrant",
971
+ "b.time.monotonicClock(" + label + "): now() was called from this " +
972
+ "clock's own drift report. The value being reported on is in " +
973
+ "info.value; asking for a new one here would return a later " +
974
+ "timestamp than the event it describes.");
975
+ }
976
+ var t = source();
977
+ // Number.isSafeInteger, not isFinite: past 2^53 the value has ALREADY been
978
+ // rounded before it arrives, and `last + 1` stops increasing there - the
979
+ // addition saturates, two calls return the same number, and the one
980
+ // guarantee this primitive makes fails silently. Refuse instead.
981
+ if (typeof t !== "number" || !Number.isSafeInteger(t)) {
982
+ throw new TimeError("time/monotonic-bad-source",
983
+ "b.time.monotonicClock: the clock source returned " +
984
+ (typeof t === "number" ? String(t) : typeof t) +
985
+ " rather than a safe integer number of epoch milliseconds");
986
+ }
987
+ lastSourceMs = t;
988
+ var value = t > last ? t : last + 1;
989
+ // The invariant, checked rather than assumed. Reachable only at the
990
+ // safe-integer ceiling, which the input screens above already refuse - so
991
+ // this is the backstop that cannot be bypassed by a future caller finding
992
+ // another way to raise the floor.
993
+ if (!(value > last) || !Number.isSafeInteger(value)) {
994
+ throw new TimeError("time/monotonic-exhausted",
995
+ "b.time.monotonicClock(" + label + "): the next monotonic value would " +
996
+ "not exceed the last (" + last + "), so the guarantee cannot be kept. " +
997
+ "The clock has reached the safe-integer ceiling; a floor read from " +
998
+ "storage is the only way to get here.");
999
+ }
1000
+ var driftMs = value - t;
1001
+ if (driftMs > maxDriftMs) {
1002
+ var info = {
1003
+ driftMs: driftMs, maxDriftMs: maxDriftMs,
1004
+ value: value, sourceMs: t, label: label,
1005
+ };
1006
+ if (strict) {
1007
+ // Throw BEFORE advancing, so a caller that never received the value
1008
+ // cannot have it walk the floor further out of reach on every retry.
1009
+ throw new TimeError("time/monotonic-drift-cap",
1010
+ "b.time.monotonicClock(" + label + "): the monotonic value is " + driftMs +
1011
+ "ms ahead of the clock source, past the " + maxDriftMs + "ms cap. Either the " +
1012
+ "write rate exceeds one row per millisecond or the system clock stepped " +
1013
+ "backwards; b.ntpCheck.checkDrift() distinguishes them.");
1014
+ }
1015
+ // Advance BEFORE the reporter runs. _report hands control to caller code,
1016
+ // and a reporter that calls now() re-enters this function; if the floor
1017
+ // had not moved yet the re-entrant call would compute the SAME value from
1018
+ // the same `last` and two callers would hold one timestamp - exactly the
1019
+ // collision this clock exists to prevent. The strict throw above still
1020
+ // precedes the advance, because there the value is never issued at all.
1021
+ last = value;
1022
+ _report(info);
1023
+ return value;
1024
+ }
1025
+ last = value;
1026
+ return value;
1027
+ }
1028
+
1029
+ // Raise the floor to a value read back out of storage. Lower values are
1030
+ // ignored rather than refused: a stale replica or an out-of-order read must
1031
+ // not be able to rewind a clock that has already moved past it.
1032
+ function observeFloor(ms) {
1033
+ // A safe integer, not merely finite. This value comes from STORAGE - the
1034
+ // chain writer seeds it from a persisted recordedAt column - so it is the
1035
+ // one input a caller does not compose themselves, and a value past 2^53
1036
+ // would push the clock to a ceiling where `last + 1` saturates and the
1037
+ // monotonic guarantee quietly stops holding.
1038
+ if (typeof ms !== "number" || !Number.isSafeInteger(ms)) {
1039
+ throw new TimeError("time/bad-floor",
1040
+ "b.time.monotonicClock.observeFloor: expected a safe-integer number of " +
1041
+ "epoch milliseconds; got " + (typeof ms === "number" ? String(ms) : typeof ms));
1042
+ }
1043
+ if (ms < 0) {
1044
+ throw new TimeError("time/bad-floor",
1045
+ "b.time.monotonicClock.observeFloor: a floor cannot be negative; got " + ms);
1046
+ }
1047
+ // MAX_SAFE_INTEGER is itself a safe integer, so the check above admits it -
1048
+ // and a clock sitting exactly there has no next value: MAX + 1 is not
1049
+ // representable and rounds back to MAX. Refuse the boundary too, so the
1050
+ // guarantee never depends on there being one more tick available.
1051
+ if (ms >= Number.MAX_SAFE_INTEGER) {
1052
+ throw new TimeError("time/bad-floor",
1053
+ "b.time.monotonicClock.observeFloor: a floor at or past " +
1054
+ "Number.MAX_SAFE_INTEGER leaves no representable next value, so the " +
1055
+ "monotonic guarantee could not be kept; got " + ms);
1056
+ }
1057
+ if (ms > last) last = ms;
1058
+ return last;
1059
+ }
1060
+
1061
+ return {
1062
+ now: now,
1063
+ observeFloor: observeFloor,
1064
+ lastValue: function () { return last; },
1065
+ driftMs: function () { return last > lastSourceMs ? last - lastSourceMs : 0; },
1066
+ label: label,
1067
+ };
1068
+ }
1069
+
1070
+ var _sharedMonotonic = monotonicClock({ label: "shared" });
1071
+
1072
+ /**
1073
+ * @primitive b.time.monotonicNow
1074
+ * @signature b.time.monotonicNow()
1075
+ * @since 0.18.44
1076
+ * @status stable
1077
+ * @related b.time.monotonicClock
1078
+ *
1079
+ * The process-wide monotonic clock: epoch milliseconds that never repeat and
1080
+ * never move backwards, whatever `Date.now()` does. The shape most callers
1081
+ * want — one shared sequence, so two unrelated call sites in the same process
1082
+ * cannot mint the same value.
1083
+ *
1084
+ * Takes no arguments. A caller who needs an injectable source, a durable
1085
+ * floor, a different drift cap, or a sequence isolated from everyone else's
1086
+ * builds their own with `b.time.monotonicClock`; configuring a shared clock
1087
+ * from one call site would silently change every other site's behaviour.
1088
+ *
1089
+ * @example
1090
+ * var a = b.time.monotonicNow();
1091
+ * var b2 = b.time.monotonicNow();
1092
+ * // → b2 > a, even inside the same millisecond
1093
+ */
1094
+ function monotonicNow() {
1095
+ if (arguments.length > 0) {
1096
+ throw new TimeError("time/monotonic-now-takes-no-opts",
1097
+ "b.time.monotonicNow() takes no arguments — it is one shared sequence, and " +
1098
+ "configuring it from one call site would change every other. Use " +
1099
+ "b.time.monotonicClock(opts) for a clock of your own.");
1100
+ }
1101
+ return _sharedMonotonic.now();
1102
+ }
1103
+
824
1104
  module.exports = {
825
1105
  toParts: toParts,
826
1106
  format: format,
@@ -836,5 +1116,7 @@ module.exports = {
836
1116
  readDateTime: readDateTime,
837
1117
  toIso8601NoMs: toIso8601NoMs,
838
1118
  stripIsoMilliseconds: stripIsoMilliseconds,
1119
+ monotonicClock: monotonicClock,
1120
+ monotonicNow: monotonicNow,
839
1121
  TimeError: TimeError,
840
1122
  };
@@ -21,7 +21,7 @@
21
21
  "server": "sha256:f3325f480cb8eb814fcb0baaa19336cbbf2b993f48624c6aa9600ffd69d0be5e",
22
22
  "browser": "sha256:0ffd91540bcb586a29b56e52ee1c29df69097b50776beb4036a07558f7a4e12e"
23
23
  },
24
- "refreshedAt": "2026-08-20T15:14:48.311Z"
24
+ "refreshedAt": "2026-08-22T03:19:31.188Z"
25
25
  },
26
26
  "@noble/hashes": {
27
27
  "version": "2.3.0",
@@ -48,7 +48,7 @@
48
48
  "hashes": {
49
49
  "browser": "sha256:dfe4b7ae3c9880e388c8da4b68f44742b229b53afacd1e674179527e33da62b0"
50
50
  },
51
- "refreshedAt": "2026-08-20T15:14:48.311Z"
51
+ "refreshedAt": "2026-08-22T03:19:31.188Z"
52
52
  },
53
53
  "@noble/curves": {
54
54
  "version": "2.3.0",
@@ -65,12 +65,12 @@
65
65
  "server": "lib/vendor/noble-curves.cjs"
66
66
  },
67
67
  "bundler": "esbuild --format=cjs --platform=node",
68
- "bundledAt": "2026-08-06T00:00:00Z",
68
+ "bundledAt": "2026-08-21T00:00:00Z",
69
69
  "cpe": "cpe:2.3:a:paulmillr:noble-curves:2.3.0:*:*:*:*:node.js:*:*",
70
70
  "hashes": {
71
71
  "server": "sha256:b5fe88d1ea780d0581dee6145d666f89d46fc9531b5db35db2e5b16627840890"
72
72
  },
73
- "refreshedAt": "2026-08-20T15:14:48.311Z",
73
+ "refreshedAt": "2026-08-22T03:19:31.188Z",
74
74
  "components": {
75
75
  "@noble/hashes": {
76
76
  "url": "https://github.com/paulmillr/noble-hashes",
@@ -114,7 +114,7 @@
114
114
  "server": "sha256:fab7ebe5737793862c473444f4ee5912f79dd1edec86683acbb4eecbca0f5892",
115
115
  "browser": "sha256:cae1d5bbdc7184b202b6ca68df6e1db7b0d0f668c77809ded189ca7f271accc9"
116
116
  },
117
- "refreshedAt": "2026-08-20T15:14:48.311Z",
117
+ "refreshedAt": "2026-08-22T03:19:31.188Z",
118
118
  "components": {
119
119
  "@noble/hashes": {
120
120
  "url": "https://github.com/paulmillr/noble-hashes",
@@ -148,7 +148,7 @@
148
148
  },
149
149
  "runtime_artifact": "lib/vendor/common-passwords-top-10000.data.js",
150
150
  "integrity_layers": "sha256 + sha3-512 + SLH-DSA-SHAKE-256f signature + in-payload canary (where applicable)",
151
- "refreshedAt": "2026-08-20T15:14:48.311Z"
151
+ "refreshedAt": "2026-08-22T03:19:31.188Z"
152
152
  },
153
153
  "bimi-trust-anchors": {
154
154
  "version": "operator-managed",
@@ -173,7 +173,7 @@
173
173
  },
174
174
  "runtime_artifact": "lib/vendor/bimi-trust-anchors.data.js",
175
175
  "integrity_layers": "sha256 + sha3-512 + SLH-DSA-SHAKE-256f signature + in-payload canary (where applicable)",
176
- "refreshedAt": "2026-08-20T15:14:48.311Z"
176
+ "refreshedAt": "2026-08-22T03:19:31.188Z"
177
177
  },
178
178
  "publicsuffix-list": {
179
179
  "version": "master",
@@ -193,10 +193,10 @@
193
193
  },
194
194
  "runtime_artifact": "lib/vendor/public-suffix-list.data.js",
195
195
  "integrity_layers": "sha256 + sha3-512 + SLH-DSA-SHAKE-256f signature + in-payload canary (where applicable)",
196
- "refreshedAt": "2026-08-20T15:14:48.311Z"
196
+ "refreshedAt": "2026-08-22T03:19:31.188Z"
197
197
  },
198
198
  "@blamejs/pki": {
199
- "version": "0.5.17",
199
+ "version": "0.5.25",
200
200
  "license": "Apache-2.0",
201
201
  "author": "blamejs",
202
202
  "source": "https://github.com/blamejs/pki",
@@ -216,12 +216,12 @@
216
216
  "server": "lib/vendor/blamejs-pki.cjs"
217
217
  },
218
218
  "bundler": "esbuild --format=cjs --platform=node --external:crypto --external:node:crypto",
219
- "bundledAt": "2026-08-20T00:00:00Z",
220
- "cpe": "cpe:2.3:a:blamejs:pki:0.5.17:*:*:*:*:node.js:*:*",
219
+ "bundledAt": "2026-08-21T00:00:00Z",
220
+ "cpe": "cpe:2.3:a:blamejs:pki:0.5.25:*:*:*:*:node.js:*:*",
221
221
  "hashes": {
222
- "server": "sha256:dbedb80e1725747a24fdbd3dec9fcab31b507ac048b923462382b6ac117937a0"
222
+ "server": "sha256:4e64654dfddb16742f615f24a4e8892286495d94ae29597cdc3e988122f3ef4a"
223
223
  },
224
- "refreshedAt": "2026-08-20T15:14:48.311Z"
224
+ "refreshedAt": "2026-08-22T03:19:31.188Z"
225
225
  }
226
226
  }
227
227
  }