@blamejs/blamejs-shop 0.0.83 → 0.0.85
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/lib/email-campaigns.js +1 -1
- package/lib/vendor/MANIFEST.json +2 -2
- package/lib/vendor/blamejs/CHANGELOG.md +4 -0
- package/lib/vendor/blamejs/README.md +1 -1
- package/lib/vendor/blamejs/SECURITY.md +1 -0
- package/lib/vendor/blamejs/api-snapshot.json +151 -2
- package/lib/vendor/blamejs/fuzz/safe-archive.fuzz.js +37 -0
- package/lib/vendor/blamejs/index.js +15 -1
- package/lib/vendor/blamejs/lib/archive-adapters.js +629 -0
- package/lib/vendor/blamejs/lib/archive-read.js +781 -0
- package/lib/vendor/blamejs/lib/archive-tar-read.js +418 -0
- package/lib/vendor/blamejs/lib/archive-tar.js +557 -0
- package/lib/vendor/blamejs/lib/archive.js +17 -0
- package/lib/vendor/blamejs/lib/audit.js +22 -7
- package/lib/vendor/blamejs/lib/backup/index.js +429 -0
- package/lib/vendor/blamejs/lib/guard-archive.js +180 -0
- package/lib/vendor/blamejs/lib/guard-filename.js +205 -0
- package/lib/vendor/blamejs/lib/safe-archive.js +295 -0
- package/lib/vendor/blamejs/package.json +1 -1
- package/lib/vendor/blamejs/release-notes/v0.12.7.json +86 -0
- package/lib/vendor/blamejs/release-notes/v0.12.8.json +81 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-read.test.js +247 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/archive-tar.test.js +228 -0
- package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +127 -0
- package/package.json +2 -2
|
@@ -2185,6 +2185,76 @@ async function testNoDuplicateCodeBlocks() {
|
|
|
2185
2185
|
files: ["lib/api-key.js:issue", "lib/db-query.js:<top>", "lib/session.js:create"],
|
|
2186
2186
|
reason: "Generic JS array helper / lambda shape — Object.keys(...).map(fn) + similar functional idioms appearing in any code that walks a column-or-key list.",
|
|
2187
2187
|
},
|
|
2188
|
+
{
|
|
2189
|
+
mode: "family-subset",
|
|
2190
|
+
files: [
|
|
2191
|
+
"lib/archive-read.js:_emitAudit",
|
|
2192
|
+
"lib/archive-tar-read.js:_emitAudit",
|
|
2193
|
+
"lib/archive.js:_emitAudit",
|
|
2194
|
+
"lib/http-client.js:_emitAudit",
|
|
2195
|
+
],
|
|
2196
|
+
reason: "v0.12.7 + v0.12.8 — Per-module `_emitAudit(opts, action, outcome, metadata)` shape repeats across primitives that drop-silently emit to opts.audit.safeEmit if present. Each module's audit events carry a primitive-specific `action:` namespace (archive.read.*, archive.zip.*, archive.read.tar.*, http-client.*) + per-primitive metadata fields; consolidating would lose the namespace + force every consumer to import the same audit helper. Four-file repetition is the expected shape per `feedback_audit_safeEmit_per_module_emitAudit_shape`. archive-tar.js (write) does NOT carry _emitAudit — the read side lives in sibling archive-tar-read.js so the @primitive validator can pair both `b.archive.tar` (write) and `b.archive.read.tar` (read) cleanly.",
|
|
2197
|
+
},
|
|
2198
|
+
{
|
|
2199
|
+
mode: "family-subset",
|
|
2200
|
+
files: [
|
|
2201
|
+
"lib/archive-adapters.js:fs",
|
|
2202
|
+
"lib/archive-adapters.js:http",
|
|
2203
|
+
"lib/network-smtp-policy.js:mtaStsFetch",
|
|
2204
|
+
"lib/parsers/safe-env.js:readVar",
|
|
2205
|
+
],
|
|
2206
|
+
reason: "v0.12.7 — `if (typeof <opt> !== \"string\" || <opt>.length === 0) throw new <Error>(...)` shape repeats across primitives validating REQUIRED string opts. validateOpts.requireNonEmptyString covers most call sites; the four flagged here are inline because they each carry a primitive-specific error CODE (adapter/bad-arg, smtp-policy/bad-arg, safe-env/bad-arg) that the helper's caller-error-class shape doesn't compose cleanly across — each primitive's typed-error class is module-local + the message string names the local opt. The duplicated shape is the symptom, not the cause; the cause is that JS doesn't have a way to throw an instance of caller-namespaced ErrorClass without the local closure.",
|
|
2207
|
+
},
|
|
2208
|
+
{
|
|
2209
|
+
mode: "family-subset",
|
|
2210
|
+
files: [
|
|
2211
|
+
"lib/archive-read.js:extract",
|
|
2212
|
+
"lib/archive-tar-read.js:extract",
|
|
2213
|
+
"lib/auth/ciba.js:pollToken",
|
|
2214
|
+
"lib/auth/oid4vci.js:exchangePreAuthorizedCode",
|
|
2215
|
+
"lib/auth/oid4vci.js:issueCredential",
|
|
2216
|
+
],
|
|
2217
|
+
reason: "v0.12.7 + v0.12.8 — `try { ... await ... } catch (e) { /* per-step cleanup */ throw e; }` shape repeats across primitives doing multi-step async work with per-step rollback. archive-read.extract + archive-tar.extract both clean up partial-extract files; ciba.pollToken cleans up rate-limit + retry state; oid4vci.exchange/issueCredential clean up partial credential-state. Each catch body is primitive-specific (the cleanup it does is the primitive's responsibility) — extraction would require a generic transaction-style helper which is itself a v1.0+ surface decision. Five-file repetition with primitive-specific cleanup bodies stays as the documented exception.",
|
|
2218
|
+
},
|
|
2219
|
+
{
|
|
2220
|
+
mode: "family-subset",
|
|
2221
|
+
files: [
|
|
2222
|
+
"lib/archive-tar-read.js:_classifyTypeflag",
|
|
2223
|
+
"lib/archive-tar-read.js:inspect",
|
|
2224
|
+
"lib/auth/ciba.js:_registerInitialInterval",
|
|
2225
|
+
"lib/auth/oauth.js:exchangeToken",
|
|
2226
|
+
"lib/auth/oauth.js:pollDeviceCode",
|
|
2227
|
+
"lib/auth/oid4vci.js:createCredentialOffer",
|
|
2228
|
+
"lib/auth/oid4vci.js:exchangePreAuthorizedCode",
|
|
2229
|
+
"lib/restore-rollback.js:swap",
|
|
2230
|
+
],
|
|
2231
|
+
reason: "v0.12.8 — Compact branching helpers (`if (x === A) return ...; if (x === B) return ...;` switch-style) repeat across primitives that map operator-supplied enum values to internal labels. archive-tar-read._classifyTypeflag maps single-char tar typeflags (0/1/2/3/4/5/6/7/x/g) to entry-type labels (file/symlink/hardlink/device/fifo/directory/etc.); archive-tar-read.inspect dispatches on the same typeflag set per-entry — distinct vocabulary from oauth.exchangeToken / oid4vci.createCredentialOffer / etc. which dispatch on grant_type / credential_format / step. The match is shape (chain of if-equals-return), not semantic. Extraction would require a generic enum-dispatch helper for trivially-different enums — that's an obscured abstraction. Each call site's enum + label set is primitive-specific.",
|
|
2232
|
+
},
|
|
2233
|
+
{
|
|
2234
|
+
mode: "family-subset",
|
|
2235
|
+
files: [
|
|
2236
|
+
"lib/archive-read.js:_normalizeEntryTypePolicy",
|
|
2237
|
+
"lib/archive-tar-read.js:_normalizeEntryTypePolicy",
|
|
2238
|
+
"lib/archive.js:writeTo",
|
|
2239
|
+
],
|
|
2240
|
+
reason: "v0.12.8 — `_normalizeEntryTypePolicy` shape is genuinely duplicated between archive-read.js + archive-tar-read.js — both copy DEFAULT_ENTRY_TYPE_POLICY and merge with operator opts. Could extract to a shared lib/_archive-policy.js helper in a future patch; for v0.12.8 keeping the duplication so the format-specific entry-type vocabulary (zip's external-attrs vs tar's typeflag) stays close to the reader that uses it. archive.js:writeTo is the unrelated third file in the dup cluster — its toBuffer + writeFileSync shape happens to share the 50-token shingle by coincidence (writeTo is the legacy ZIP write-to-path helper, not policy-related).",
|
|
2241
|
+
},
|
|
2242
|
+
{
|
|
2243
|
+
mode: "family-subset",
|
|
2244
|
+
files: [
|
|
2245
|
+
"lib/agent-idempotency.js:_checkArgs",
|
|
2246
|
+
"lib/agent-tenant.js:_sealField",
|
|
2247
|
+
"lib/atomic-file.js:copyDirRecursive",
|
|
2248
|
+
"lib/ddl-change-control.js:approve",
|
|
2249
|
+
"lib/ddl-change-control.js:reject",
|
|
2250
|
+
"lib/deprecate.js:alias",
|
|
2251
|
+
"lib/guard-filename.js:verifyExtractionPath",
|
|
2252
|
+
"lib/jose-jwe-experimental.js:decrypt",
|
|
2253
|
+
"lib/mail-deploy.js:_validateTlsRptReport",
|
|
2254
|
+
"lib/totp.js:uri",
|
|
2255
|
+
],
|
|
2256
|
+
reason: "v0.12.7 — Generic string-argument validation shape: `if (typeof X !== \"string\" || X.length === 0) throw new <ErrorClass>(<code>, ...)` repeats across primitives validating REQUIRED non-empty string opts. Each call site emits a primitive-specific typed error class (BackupError, GuardFilenameError, IdempotencyError, AgentTenantError, AtomicFileError, DdlError, DeprecateError, JoseError, MailDeployError, TotpError) so extracting to a shared helper would lose the per-primitive error namespace. validateOpts.requireNonEmptyString covers most call sites where the caller's typed-error class composes with the helper's caller-error-class shape; the 9 file paths here are inline because each one's typed error has a primitive-local code namespace + message string the helper can't compose cleanly. Same shape as the v0.10.16 client-hints/csp/sandbox family-subset reason (inline for per-primitive typed errors). 5/9/3-file subsets at smaller token windows are the same family — one entry covers all of them.",
|
|
2257
|
+
},
|
|
2188
2258
|
{
|
|
2189
2259
|
mode: "family-subset",
|
|
2190
2260
|
files: [
|
|
@@ -5391,7 +5461,10 @@ var KNOWN_ANTIPATTERNS = [
|
|
|
5391
5461
|
"lib/observability-otlp-exporter.js", // byResource grouping (Map<resKey, bucket>) — object-literal factory
|
|
5392
5462
|
"lib/otel-export.js", // counters / observations (2 sites) — object-literal factory
|
|
5393
5463
|
"lib/pubsub.js", // exactSubs (Map<channel, Set<sub>>) — Set factory
|
|
5464
|
+
"lib/backup/index.js", // bundleAdapterStorage.listBundles: byBundle (Map<bundleId, stats>) — object-literal factory
|
|
5394
5465
|
],
|
|
5466
|
+
// Strong-dup allowlists added with v0.12.7 archive substrate
|
|
5467
|
+
// — see KNOWN_CLUSTERS additions below for structural reasons.
|
|
5395
5468
|
reason: "Node 26 ships Map.prototype.getOrInsertComputed(key, factory) — a single-lookup get-or-insert that replaces the two-step `var v = m.get(k); if (!v) { v = factory(); m.set(k, v); }` pattern. The sweep is deferred to the Node 26 floor-bump (eligible Oct 2026); engines.node is `>=24` today. Allowlist above is the survey ground truth from memory/specs/node-26-map-getorinsert-migration.md. New code post-this-patch trips the detector — either wait for the floor bump, or add the call site to BOTH the allowlist AND the migration spec in the same patch. When the floor moves, the bump commit walks the allowlist, rewrites each call site, drops the allowlist + flips the detector to enforce.",
|
|
5396
5469
|
},
|
|
5397
5470
|
{
|
|
@@ -5512,6 +5585,60 @@ var KNOWN_ANTIPATTERNS = [
|
|
|
5512
5585
|
reason: "Codex P1 on v0.12.6 PR #157 — `_anyValueToProto` negative-int path wrapped a varint payload in `embeddedMessage` (wire-type 2) instead of using `int64` (wire-type 0 varint). The wire-type mismatch poisons the whole OTLP batch; the `v >>> 0` truncation also dropped sign + high bits. Fixed by adding `pb.int64` + `pb.sint64` to the encoder + routing the negative-int branch through `pb.int64`. Detector locks the shape: `embeddedMessage(N, _writeVarint(...))` cannot recur.",
|
|
5513
5586
|
},
|
|
5514
5587
|
|
|
5588
|
+
{
|
|
5589
|
+
// Codex P1 on v0.12.7 PR #158 — archive-read.extract's rollback
|
|
5590
|
+
// cleanup deleted PRE-EXISTING destination files when a later
|
|
5591
|
+
// entry failed. The renameSync(tmpPath, resolvedPath) silently
|
|
5592
|
+
// overwrote operator files at the destination, then on abort the
|
|
5593
|
+
// catch-block rmSync wiped them out — permanent data loss
|
|
5594
|
+
// disguised as atomic rollback. Fix: refuse to write when the
|
|
5595
|
+
// destination path already exists; force operators to extract
|
|
5596
|
+
// into a fresh / empty subtree.
|
|
5597
|
+
//
|
|
5598
|
+
// Detector scope: any lib/archive*.js or lib/safe-archive.js file
|
|
5599
|
+
// that calls renameSync into a path it ALSO tracks for cleanup
|
|
5600
|
+
// MUST refuse overwrite up-front. Codify as a file-scoped invariant:
|
|
5601
|
+
// archive-read.js must contain "destination-exists" refusal code.
|
|
5602
|
+
id: "archive-extract-overwrite-without-refusal",
|
|
5603
|
+
primitive: "extract loops in lib/archive-read.js MUST refuse to write to a destination path that already exists — atomic rollback via tmp-rename + tracked-path cleanup is only safe when every tracked path was newly created. Pre-existing files at the destination + catch-block rmSync = data loss.",
|
|
5604
|
+
// File-scoped: only fires on archive-read.js / safe-archive.js
|
|
5605
|
+
// shape. The pattern is renameSync of a tmpPath onto resolvedPath
|
|
5606
|
+
// (the canonical destination variable) — atomic-file.js's
|
|
5607
|
+
// operator-file rename is a different shape (operator already
|
|
5608
|
+
// owns the destination context); http-client.js's atomic-tmp
|
|
5609
|
+
// rename writes operator-supplied paths under operator-supplied
|
|
5610
|
+
// tmp dirs, also a different concern.
|
|
5611
|
+
regex: /written\.push\s*\(\s*\{[^}]*path:\s*resolvedPath/,
|
|
5612
|
+
requires: /destination-exists/,
|
|
5613
|
+
skipCommentLines: true,
|
|
5614
|
+
allowlist: [],
|
|
5615
|
+
reason: "Codex P1 on v0.12.7 PR #158 — archive-read.extract used renameSync to atomically place each decompressed entry at its canonical destination + tracked written[].path for catch-block cleanup. When the destination directory was non-empty, the rename silently overwrote operator files; on extract abort, the cleanup deleted them. Fix: refuse upfront if destination path exists, force operators to use a fresh / empty subtree. Detector locks the shape: any extract code that tracks resolvedPath for catch-block cleanup MUST carry a `destination-exists` refusal in the same file.",
|
|
5616
|
+
},
|
|
5617
|
+
|
|
5618
|
+
{
|
|
5619
|
+
// Codex P1 on v0.12.8 PR #159 — archive-tar-read.js's walker
|
|
5620
|
+
// advanced `pos` by the declared padded block size without
|
|
5621
|
+
// checking that those bytes existed in the buffer. A truncated
|
|
5622
|
+
// archive (header says 11 bytes, buffer holds 8) silently
|
|
5623
|
+
// produced an entry whose extract() sliced the 8-byte prefix
|
|
5624
|
+
// and wrote it as if it were the complete file. Fix: refuse
|
|
5625
|
+
// upfront with a `truncated-entry` typed error when
|
|
5626
|
+
// `bodyStart + paddedSize > bytes.length`. Same shape applies
|
|
5627
|
+
// to the pax-extended-header path (its `bodyEnd` advance was
|
|
5628
|
+
// the same uncapped arithmetic).
|
|
5629
|
+
id: "archive-tar-walker-without-truncation-check",
|
|
5630
|
+
primitive: "tar walkers in lib/archive-tar-read.js MUST verify that the declared block size fits within the remaining buffer before advancing `pos` — a header that claims more bytes than the buffer holds is a truncated archive, not a valid entry. The refusal carries `truncated-entry` code so operators can distinguish wire-format-bad input from policy-bad input.",
|
|
5631
|
+
// File-scoped: only fires on archive-tar-read.js. The walker
|
|
5632
|
+
// advances pos by paddedSize (Math.ceil(hdr.size / BLOCK_SIZE)
|
|
5633
|
+
// * BLOCK_SIZE) — any code that adds paddedSize to pos without
|
|
5634
|
+
// a preceding bounds check is the smell.
|
|
5635
|
+
regex: /pos\s*\+=\s*paddedSize/,
|
|
5636
|
+
requires: /truncated-entry/,
|
|
5637
|
+
skipCommentLines: true,
|
|
5638
|
+
allowlist: [],
|
|
5639
|
+
reason: "Codex P1 on v0.12.8 PR #159 — archive-tar-read.js's tar walker recorded each entry and advanced pos by paddedSize without verifying the declared bytes existed in the buffer. A truncated archive silently produced a partial-content entry on extract — exact reproducer in the Codex thread: declared 11-byte file backed by 8 bytes of buffer produced an 8-byte output. Fix: refuse upfront with `archive-tar/truncated-entry` typed error. Detector locks the shape: any code path that advances pos by paddedSize in archive-tar-read.js MUST carry a `truncated-entry` refusal in the same file.",
|
|
5640
|
+
},
|
|
5641
|
+
|
|
5515
5642
|
{
|
|
5516
5643
|
// Codex P2 on v0.11.22 PR #126 — `b.cert.create`'s SNI dispatch
|
|
5517
5644
|
// wildcard-matched `*.example.com` against `foo.bar.example.com`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blamejs/blamejs-shop",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.85",
|
|
4
4
|
"description": "Open-source framework built on blamejs. Vendored stack, zero npm runtime deps, PQC-first crypto, security-on by default.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"type": "git",
|
|
36
36
|
"url": "git+https://github.com/blamejs/blamejs.shop.git"
|
|
37
37
|
},
|
|
38
|
-
"homepage": "https://
|
|
38
|
+
"homepage": "https://blamejs.shop",
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@cloudflare/containers": "^0.3.4",
|
|
41
41
|
"wrangler": "^4.93.0"
|