@blamejs/core 0.8.42 → 0.8.49

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.
Files changed (222) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/README.md +10 -10
  3. package/index.js +52 -0
  4. package/lib/a2a.js +159 -34
  5. package/lib/acme.js +762 -0
  6. package/lib/ai-pref.js +166 -43
  7. package/lib/api-key.js +108 -47
  8. package/lib/api-snapshot.js +157 -40
  9. package/lib/app-shutdown.js +113 -77
  10. package/lib/archive.js +337 -40
  11. package/lib/arg-parser.js +697 -0
  12. package/lib/asyncapi.js +99 -55
  13. package/lib/atomic-file.js +465 -104
  14. package/lib/audit-chain.js +123 -34
  15. package/lib/audit-daily-review.js +389 -0
  16. package/lib/audit-sign.js +302 -56
  17. package/lib/audit-tools.js +412 -63
  18. package/lib/audit.js +656 -35
  19. package/lib/auth/jwt-external.js +17 -0
  20. package/lib/auth/oauth.js +7 -0
  21. package/lib/auth-bot-challenge.js +505 -0
  22. package/lib/auth-header.js +92 -25
  23. package/lib/backup/bundle.js +26 -0
  24. package/lib/backup/index.js +512 -89
  25. package/lib/backup/manifest.js +168 -7
  26. package/lib/break-glass.js +415 -39
  27. package/lib/budr.js +103 -30
  28. package/lib/bundler.js +86 -66
  29. package/lib/cache.js +192 -72
  30. package/lib/chain-writer.js +65 -40
  31. package/lib/circuit-breaker.js +56 -33
  32. package/lib/cli-helpers.js +106 -75
  33. package/lib/cli.js +6 -30
  34. package/lib/cloud-events.js +99 -32
  35. package/lib/cluster-storage.js +162 -37
  36. package/lib/cluster.js +340 -49
  37. package/lib/codepoint-class.js +66 -0
  38. package/lib/compliance.js +424 -24
  39. package/lib/config-drift.js +111 -46
  40. package/lib/config.js +94 -40
  41. package/lib/consent.js +165 -18
  42. package/lib/constants.js +1 -0
  43. package/lib/content-credentials.js +153 -48
  44. package/lib/cookies.js +154 -62
  45. package/lib/credential-hash.js +133 -61
  46. package/lib/crypto-field.js +702 -18
  47. package/lib/crypto-hpke.js +256 -0
  48. package/lib/crypto.js +744 -22
  49. package/lib/csv.js +178 -35
  50. package/lib/daemon.js +456 -0
  51. package/lib/dark-patterns.js +186 -55
  52. package/lib/db-query.js +79 -2
  53. package/lib/db.js +1431 -60
  54. package/lib/ddl-change-control.js +523 -0
  55. package/lib/deprecate.js +195 -40
  56. package/lib/dev.js +82 -39
  57. package/lib/dora.js +67 -48
  58. package/lib/dr-runbook.js +368 -0
  59. package/lib/dsr.js +142 -11
  60. package/lib/dual-control.js +91 -56
  61. package/lib/events.js +120 -41
  62. package/lib/external-db-migrate.js +192 -2
  63. package/lib/external-db.js +795 -50
  64. package/lib/fapi2.js +122 -1
  65. package/lib/fda-21cfr11.js +395 -0
  66. package/lib/fdx.js +132 -2
  67. package/lib/file-type.js +87 -0
  68. package/lib/file-upload.js +93 -0
  69. package/lib/flag.js +82 -20
  70. package/lib/forms.js +132 -29
  71. package/lib/framework-error.js +169 -0
  72. package/lib/framework-schema.js +163 -35
  73. package/lib/gate-contract.js +849 -175
  74. package/lib/graphql-federation.js +68 -7
  75. package/lib/guard-all.js +172 -55
  76. package/lib/guard-archive.js +286 -124
  77. package/lib/guard-auth.js +194 -21
  78. package/lib/guard-cidr.js +190 -28
  79. package/lib/guard-csv.js +397 -51
  80. package/lib/guard-domain.js +213 -91
  81. package/lib/guard-email.js +236 -29
  82. package/lib/guard-filename.js +307 -75
  83. package/lib/guard-graphql.js +263 -30
  84. package/lib/guard-html.js +310 -116
  85. package/lib/guard-image.js +243 -30
  86. package/lib/guard-json.js +260 -54
  87. package/lib/guard-jsonpath.js +235 -23
  88. package/lib/guard-jwt.js +284 -30
  89. package/lib/guard-markdown.js +204 -22
  90. package/lib/guard-mime.js +190 -26
  91. package/lib/guard-oauth.js +277 -28
  92. package/lib/guard-pdf.js +251 -27
  93. package/lib/guard-regex.js +226 -18
  94. package/lib/guard-shell.js +229 -26
  95. package/lib/guard-svg.js +177 -10
  96. package/lib/guard-template.js +232 -21
  97. package/lib/guard-time.js +195 -29
  98. package/lib/guard-uuid.js +189 -30
  99. package/lib/guard-xml.js +259 -36
  100. package/lib/guard-yaml.js +241 -44
  101. package/lib/honeytoken.js +63 -27
  102. package/lib/html-balance.js +83 -0
  103. package/lib/http-client.js +486 -59
  104. package/lib/http-message-signature.js +582 -0
  105. package/lib/i18n.js +102 -49
  106. package/lib/iab-mspa.js +112 -32
  107. package/lib/iab-tcf.js +107 -2
  108. package/lib/inbox.js +90 -52
  109. package/lib/keychain.js +865 -0
  110. package/lib/legal-hold.js +374 -0
  111. package/lib/local-db-thin.js +320 -0
  112. package/lib/log-stream.js +281 -51
  113. package/lib/log.js +184 -86
  114. package/lib/mail-bounce.js +107 -62
  115. package/lib/mail.js +295 -58
  116. package/lib/mcp.js +108 -27
  117. package/lib/metrics.js +98 -89
  118. package/lib/middleware/age-gate.js +36 -0
  119. package/lib/middleware/ai-act-disclosure.js +37 -0
  120. package/lib/middleware/api-encrypt.js +45 -0
  121. package/lib/middleware/assetlinks.js +40 -0
  122. package/lib/middleware/asyncapi-serve.js +35 -0
  123. package/lib/middleware/attach-user.js +40 -0
  124. package/lib/middleware/bearer-auth.js +40 -0
  125. package/lib/middleware/body-parser.js +230 -0
  126. package/lib/middleware/bot-disclose.js +34 -0
  127. package/lib/middleware/bot-guard.js +39 -0
  128. package/lib/middleware/compression.js +37 -0
  129. package/lib/middleware/cookies.js +32 -0
  130. package/lib/middleware/cors.js +40 -0
  131. package/lib/middleware/csp-nonce.js +40 -0
  132. package/lib/middleware/csp-report.js +34 -0
  133. package/lib/middleware/csrf-protect.js +43 -0
  134. package/lib/middleware/daily-byte-quota.js +53 -85
  135. package/lib/middleware/db-role-for.js +40 -0
  136. package/lib/middleware/dpop.js +40 -0
  137. package/lib/middleware/error-handler.js +37 -14
  138. package/lib/middleware/fetch-metadata.js +39 -0
  139. package/lib/middleware/flag-context.js +34 -0
  140. package/lib/middleware/gpc.js +33 -0
  141. package/lib/middleware/headers.js +35 -0
  142. package/lib/middleware/health.js +46 -0
  143. package/lib/middleware/host-allowlist.js +30 -0
  144. package/lib/middleware/network-allowlist.js +38 -0
  145. package/lib/middleware/openapi-serve.js +34 -0
  146. package/lib/middleware/rate-limit.js +160 -18
  147. package/lib/middleware/request-id.js +36 -18
  148. package/lib/middleware/request-log.js +37 -0
  149. package/lib/middleware/require-aal.js +29 -0
  150. package/lib/middleware/require-auth.js +32 -0
  151. package/lib/middleware/require-bound-key.js +41 -0
  152. package/lib/middleware/require-content-type.js +32 -0
  153. package/lib/middleware/require-methods.js +27 -0
  154. package/lib/middleware/require-mtls.js +33 -0
  155. package/lib/middleware/require-step-up.js +37 -0
  156. package/lib/middleware/security-headers.js +44 -0
  157. package/lib/middleware/security-txt.js +38 -0
  158. package/lib/middleware/span-http-server.js +37 -0
  159. package/lib/middleware/sse.js +36 -0
  160. package/lib/middleware/trace-log-correlation.js +33 -0
  161. package/lib/middleware/trace-propagate.js +32 -0
  162. package/lib/middleware/tus-upload.js +90 -0
  163. package/lib/middleware/web-app-manifest.js +53 -0
  164. package/lib/mtls-ca.js +100 -70
  165. package/lib/network-byte-quota.js +308 -0
  166. package/lib/network-heartbeat.js +135 -0
  167. package/lib/network-tls.js +534 -4
  168. package/lib/network.js +103 -0
  169. package/lib/notify.js +114 -43
  170. package/lib/ntp-check.js +192 -51
  171. package/lib/observability.js +145 -47
  172. package/lib/openapi.js +90 -44
  173. package/lib/outbox.js +99 -1
  174. package/lib/pagination.js +168 -86
  175. package/lib/parsers/index.js +16 -5
  176. package/lib/permissions.js +93 -40
  177. package/lib/pqc-agent.js +84 -8
  178. package/lib/pqc-software.js +94 -60
  179. package/lib/process-spawn.js +95 -21
  180. package/lib/pubsub.js +96 -66
  181. package/lib/queue.js +375 -54
  182. package/lib/redact.js +793 -21
  183. package/lib/render.js +139 -47
  184. package/lib/request-helpers.js +485 -121
  185. package/lib/restore-bundle.js +142 -39
  186. package/lib/restore-rollback.js +136 -45
  187. package/lib/retention.js +178 -50
  188. package/lib/retry.js +116 -33
  189. package/lib/router.js +475 -23
  190. package/lib/safe-async.js +543 -94
  191. package/lib/safe-buffer.js +337 -41
  192. package/lib/safe-json.js +467 -62
  193. package/lib/safe-jsonpath.js +285 -0
  194. package/lib/safe-schema.js +631 -87
  195. package/lib/safe-sql.js +221 -59
  196. package/lib/safe-url.js +278 -46
  197. package/lib/sandbox-worker.js +135 -0
  198. package/lib/sandbox.js +358 -0
  199. package/lib/scheduler.js +135 -70
  200. package/lib/self-update.js +647 -0
  201. package/lib/session-device-binding.js +431 -0
  202. package/lib/session.js +259 -49
  203. package/lib/slug.js +138 -26
  204. package/lib/ssrf-guard.js +316 -56
  205. package/lib/storage.js +433 -70
  206. package/lib/subject.js +405 -23
  207. package/lib/template.js +148 -8
  208. package/lib/tenant-quota.js +545 -0
  209. package/lib/testing.js +440 -53
  210. package/lib/time.js +291 -23
  211. package/lib/tls-exporter.js +239 -0
  212. package/lib/tracing.js +90 -74
  213. package/lib/uuid.js +97 -22
  214. package/lib/vault/index.js +284 -22
  215. package/lib/vault/seal-pem-file.js +66 -0
  216. package/lib/watcher.js +368 -0
  217. package/lib/webhook.js +196 -63
  218. package/lib/websocket.js +393 -68
  219. package/lib/wiki-concepts.js +338 -0
  220. package/lib/worker-pool.js +464 -0
  221. package/package.json +3 -3
  222. package/sbom.cyclonedx.json +7 -7
package/lib/render.js CHANGED
@@ -1,52 +1,31 @@
1
1
  "use strict";
2
2
  /**
3
- * Response helpers — render a value into an HTTP response with the
4
- * right Content-Type, status, and body shape, in one call.
5
- *
6
- * Without these helpers every route handler reimplements the same
7
- * five lines: pick a status code, set Content-Type, JSON.stringify
8
- * (or render a template), set Content-Length, end the response. With
9
- * them, each response shape is a single call:
10
- *
11
- * render.json(res, { ok: true })
12
- * render.text(res, "OK")
13
- * render.redirect(res, "/login")
14
- * render.htmlString(res, "<h1>Hi</h1>")
15
- * r.html(res, "home", { user: req.user }) // engine-bound (see create())
16
- *
17
- * The template engine isn't required to use any of the non-HTML
18
- * helpers. Operators who never render server-side HTML just import
19
- * the module-level json/text/redirect.
20
- *
21
- * Public API:
22
- *
23
- * render.json(res, body, opts?)
24
- * JSON-stringifies body, sets Content-Type application/json;
25
- * opts.status (default 200) + opts.headers merged.
26
- *
27
- * render.text(res, body, opts?)
28
- * text/plain. opts.status / opts.headers / opts.charset (default utf-8).
29
- *
30
- * render.htmlString(res, htmlString, opts?)
31
- * → text/html for a pre-rendered string; same opts shape.
32
- *
33
- * render.redirect(res, location, opts?)
34
- * → opts.status (default 302; 301/303/307/308 also valid).
35
- * Location is set; body empty.
36
- *
37
- * render.create({ engine }) → {
38
- * html(res, viewName, data?, opts?) engine-rendered HTML
39
- * json, text, htmlString, redirect re-exported for one-import ergonomics
40
- * }
41
- * engine is a template engine instance from
42
- * b.template.create({ viewsDir }). html() throws if rendering
43
- * fails — wire b.middleware.errorHandler downstream to convert
44
- * to a sanitized 500 response.
45
- *
46
- * All helpers fall through silently when res is already finished
47
- * (`writableEnded === true`). Mid-stream double-writes from a route
48
- * that already sent a response (e.g. a Promise rejection after
49
- * res.end) won't corrupt the wire.
3
+ * @module b.render
4
+ * @nav HTTP
5
+ * @title Render
6
+ *
7
+ * @intro
8
+ * Server-side HTML / JSON / XML response helpers. Each helper picks
9
+ * the right Content-Type, sets a sensible Cache-Control + security
10
+ * header default, and ends the response in one call — replacing the
11
+ * five-line writeHead / stringify / Content-Length / end ritual that
12
+ * every route handler otherwise reimplements.
13
+ *
14
+ * Module-level helpers (`json` / `text` / `htmlString` / `redirect`)
15
+ * work without a template engine. `create({ engine })` wraps a
16
+ * `b.template.create` instance and returns the same helpers plus
17
+ * `html(res, viewName, data?)` for engine-rendered pages. Operators
18
+ * who never render server-side HTML import only the module-level
19
+ * helpers and skip the engine wiring entirely.
20
+ *
21
+ * All helpers fall through silently when `res.writableEnded === true`,
22
+ * so a late Promise rejection after `res.end` can't corrupt the wire
23
+ * with a half-written second body. The default `Cache-Control` is
24
+ * `private, no-cache, must-revalidate` — overridable via
25
+ * `opts.headers["Cache-Control"]` for CDN-cacheable responses.
26
+ *
27
+ * @card
28
+ * Server-side HTML / JSON / XML response helpers.
50
29
  */
51
30
 
52
31
  var DEFAULT_CHARSET = "utf-8";
@@ -88,6 +67,29 @@ function _mergedHeaders(base, extra) {
88
67
  // response override via `opts.headers["Cache-Control"]`.
89
68
  var DEFAULT_DYNAMIC_CACHE_CONTROL = "private, no-cache, must-revalidate";
90
69
 
70
+ /**
71
+ * @primitive b.render.json
72
+ * @signature b.render.json(res, body, opts)
73
+ * @since 0.1.0
74
+ * @status stable
75
+ * @related b.render.text, b.render.htmlString, b.render.create
76
+ *
77
+ * JSON-stringifies `body` and writes it to `res` with Content-Type
78
+ * `application/json; charset=utf-8`, an explicit `Content-Length`,
79
+ * and the dynamic-response Cache-Control. Status defaults to 200;
80
+ * any custom headers in `opts.headers` merge over the defaults so
81
+ * operators can pin a different Cache-Control or add CORS headers
82
+ * without losing Content-Type. Returns `undefined` — the response
83
+ * is fully written by the time the call returns.
84
+ *
85
+ * @opts
86
+ * status: 200, // numeric HTTP status (200/201/202/4xx/5xx)
87
+ * headers: {}, // merged over defaults; later wins
88
+ *
89
+ * @example
90
+ * b.render.json(res, { ok: true, id: 42 }, { status: 201 });
91
+ * // → response: 201, application/json, body `{"ok":true,"id":42}`
92
+ */
91
93
  function json(res, body, opts) {
92
94
  opts = opts || {};
93
95
  var encoded = JSON.stringify(body);
@@ -99,6 +101,27 @@ function json(res, body, opts) {
99
101
  _writeResponse(res, opts.status || 200, headers, encoded);
100
102
  }
101
103
 
104
+ /**
105
+ * @primitive b.render.text
106
+ * @signature b.render.text(res, body, opts)
107
+ * @since 0.1.0
108
+ * @status stable
109
+ * @related b.render.json, b.render.htmlString
110
+ *
111
+ * Coerces `body` to a string and writes it as `text/plain` with the
112
+ * supplied charset (default `utf-8`). `null` / `undefined` body
113
+ * becomes the empty string rather than the literal text `"null"` —
114
+ * a common gotcha when forwarding a value-or-nothing handler result.
115
+ *
116
+ * @opts
117
+ * status: 200,
118
+ * headers: {},
119
+ * charset: "utf-8",
120
+ *
121
+ * @example
122
+ * b.render.text(res, "OK");
123
+ * // → 200, Content-Type "text/plain; charset=utf-8", body "OK"
124
+ */
102
125
  function text(res, body, opts) {
103
126
  opts = opts || {};
104
127
  var encoded = body == null ? "" : String(body);
@@ -111,6 +134,28 @@ function text(res, body, opts) {
111
134
  _writeResponse(res, opts.status || 200, headers, encoded);
112
135
  }
113
136
 
137
+ /**
138
+ * @primitive b.render.htmlString
139
+ * @signature b.render.htmlString(res, htmlBody, opts)
140
+ * @since 0.1.0
141
+ * @status stable
142
+ * @related b.render.json, b.render.create
143
+ *
144
+ * Writes a pre-rendered HTML string with `Content-Type: text/html;
145
+ * charset=<charset>`. Use when an HTML body is already in hand — for
146
+ * engine-bound view rendering, prefer `b.render.create({ engine })`
147
+ * and the returned `html(res, viewName, data)` helper which threads
148
+ * `res.locals` (CSP nonce, request id, current user) into the view.
149
+ *
150
+ * @opts
151
+ * status: 200,
152
+ * headers: {},
153
+ * charset: "utf-8",
154
+ *
155
+ * @example
156
+ * b.render.htmlString(res, "<h1>Hi</h1>");
157
+ * // → 200, text/html; charset=utf-8, body "<h1>Hi</h1>"
158
+ */
114
159
  function htmlString(res, htmlBody, opts) {
115
160
  opts = opts || {};
116
161
  var encoded = htmlBody == null ? "" : String(htmlBody);
@@ -123,6 +168,28 @@ function htmlString(res, htmlBody, opts) {
123
168
  _writeResponse(res, opts.status || 200, headers, encoded);
124
169
  }
125
170
 
171
+ /**
172
+ * @primitive b.render.redirect
173
+ * @signature b.render.redirect(res, location, opts)
174
+ * @since 0.1.0
175
+ * @status stable
176
+ * @related b.safeRedirect, b.render.json
177
+ *
178
+ * Sends a 3xx response with the given `Location` header and an empty
179
+ * body. Throws when `location` is empty or when `opts.status` falls
180
+ * outside the 300–399 range. Default status is 302; pass 301 / 303 /
181
+ * 307 / 308 for the other RFC 7231 / 7538 redirect semantics. For
182
+ * untrusted user-supplied destinations, validate first via
183
+ * `b.safeRedirect` before passing the result here.
184
+ *
185
+ * @opts
186
+ * status: 302, // 301 / 302 / 303 / 307 / 308
187
+ * headers: {},
188
+ *
189
+ * @example
190
+ * b.render.redirect(res, "/login", { status: 303 });
191
+ * // → 303, Location "/login", empty body
192
+ */
126
193
  function redirect(res, location, opts) {
127
194
  opts = opts || {};
128
195
  if (typeof location !== "string" || location.length === 0) {
@@ -142,6 +209,31 @@ function redirect(res, location, opts) {
142
209
 
143
210
  // ---- Engine-bound instance ----
144
211
 
212
+ /**
213
+ * @primitive b.render.create
214
+ * @signature b.render.create(opts)
215
+ * @since 0.1.0
216
+ * @status stable
217
+ * @related b.template.create, b.render.htmlString
218
+ *
219
+ * Binds a template engine to a renderer and returns the module-level
220
+ * helpers (`json` / `text` / `htmlString` / `redirect`) plus
221
+ * `html(res, viewName, data?, opts?)`. The `html` helper auto-merges
222
+ * `res.locals` into the template data so request-scoped values
223
+ * (CSP nonce, request id, current user) thread through every render
224
+ * without per-route plumbing. Operator-supplied `data` keys take
225
+ * precedence over locals — explicit beats implicit. Throws when
226
+ * `opts.engine.render` is not a function.
227
+ *
228
+ * @opts
229
+ * engine: <required>, // a template engine instance from b.template.create({ viewsDir })
230
+ *
231
+ * @example
232
+ * var engine = b.template.create({ viewsDir: "/srv/views" });
233
+ * var r = b.render.create({ engine: engine });
234
+ * r.html(res, "home", { user: "ada" });
235
+ * // → 200, text/html; charset=utf-8, body = engine.render("home", merged-locals)
236
+ */
145
237
  function create(opts) {
146
238
  opts = opts || {};
147
239
  if (!opts.engine || typeof opts.engine.render !== "function") {