@blamejs/core 0.8.43 → 0.8.50

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
@@ -1,38 +1,80 @@
1
1
  "use strict";
2
2
  /**
3
- * guard-graphql — GraphQL request-shape safety primitive
4
- * (b.guardGraphql).
3
+ * @module b.guardGraphql
4
+ * @nav Guards
5
+ * @title Guard Graphql
5
6
  *
6
- * Validates user-supplied GraphQL request bundles against the
7
- * canonical query-shape DoS catalog before the framework hands the
8
- * query to a schema-aware executor. KIND="graphql-request" consumes
9
- * `ctx.graphqlRequest` shape: { query, operationName?, variables? }.
7
+ * @intro
8
+ * GraphQL request-shape safety guard validates user-supplied
9
+ * request bundles against the canonical query-shape DoS catalog
10
+ * BEFORE the framework hands the query to a schema-aware
11
+ * executor. KIND is `graphql-request`; the gate consumes
12
+ * `ctx.graphqlRequest` (or `ctx.gql`) shape `{ query,
13
+ * operationName?, variables?, extensions? }`. Pair downstream
14
+ * with the operator's schema-aware parser — this layer is the
15
+ * shape / depth / breadth contract that runs before any
16
+ * schema-resolution work.
10
17
  *
11
- * Threat catalog:
12
- * - Query depth bombs — deeply-nested selection sets multiply N²
13
- * against schema depth, bypassing field-level rate limits.
14
- * - Query breadth / alias bombs — same field repeated under
15
- * different aliases (`a:friend b:friend c:friend ...`) bypasses
16
- * per-field limits.
17
- * - Variable type confusion — variables passed as the wrong shape
18
- * (string for ID expecting Int, object for scalar). Many
19
- * executors coerce silently; the guard refuses non-shape-matching
20
- * types when the operator declares variable shapes.
21
- * - Introspection in production — `__schema` / `__type` queries
22
- * leak schema details; refused unless operator opts in.
23
- * - Batch query DoS — operators supporting [{},{}] batch arrays
24
- * get N requests for one HTTP hit; the guard caps batch length.
25
- * - Persisted-query opt-in — when operatorRequiresPersistedQuery,
26
- * refuse free-form queries that don't carry a persisted-query
27
- * hash extension.
28
- * - Operation-name allowlist — operator may pin operationName to
29
- * a whitelist of named operations (denylist for ad-hoc queries).
30
- * - Excessive query / variable / total byte length — parser DoS.
31
- * - BIDI / null / control / zero-width universal refuse on the
32
- * query string.
18
+ * Query depth caps: deeply-nested selection sets multiply
19
+ * exponentially against schema depth, bypassing per-field rate
20
+ * limits. The gate's `_measureQueryShape` walker counts
21
+ * brace-depth without a full lex/parse (the operator's executor
22
+ * handles full parsing); strict caps at 8, balanced 12,
23
+ * permissive 24. The cap fires as `graphql.depth-exceeded`
24
+ * the canonical N²-amplification DoS class.
33
25
  *
34
- * var rv = b.guardGraphql.validate(req, { profile: "strict" });
35
- * var g = b.guardGraphql.gate({ profile: "strict" });
26
+ * Alias-amplification caps: the same field repeated under
27
+ * different aliases (`a:friend b:friend c:friend ...`) bypasses
28
+ * per-field limits because each alias is a separate selection.
29
+ * Strict caps at 8 aliases per selection-set, balanced 16,
30
+ * permissive 32. Fires as `graphql.alias-bomb` —
31
+ * breadth-amplification DoS class.
32
+ *
33
+ * Fragment-cycle defense: operator's executor handles cyclic
34
+ * fragment refs at parse time; the guard's contribution is the
35
+ * total-bytes cap (`maxBytes`) and per-query cap
36
+ * (`maxQueryBytes`), which bound the worst-case parser-DoS
37
+ * shape regardless of cycle structure.
38
+ *
39
+ * Introspection toggle: `__schema` / `__type` queries leak
40
+ * schema details and tooling expects them in development but
41
+ * not production. Strict refuses (production posture); balanced
42
+ * audits; permissive allows. Detection is substring-match on
43
+ * the query string — fast and impossible to evade with
44
+ * whitespace tricks.
45
+ *
46
+ * Persisted-query allowlist: when the operator opts in via
47
+ * `persistedQueryPolicy: "require"`, the request must carry
48
+ * `extensions.persistedQuery.sha256Hash`. Free-form queries
49
+ * are refused as `graphql.persisted-query-missing` — eliminates
50
+ * ad-hoc query attack surface entirely (operator pre-approves
51
+ * the catalog of permitted queries by hash).
52
+ *
53
+ * Operation-name allowlist: when `opts.allowedOperations` is
54
+ * set, the request `operationName` must be in the list.
55
+ * Complements the persisted-query approach for operators that
56
+ * keep free-form queries on but want a denylist for ad-hoc
57
+ * shapes.
58
+ *
59
+ * Variable shape validation: when `opts.variableShapes` declares
60
+ * `{ varName: "string"|"number"|"boolean"|"object" }`, the gate
61
+ * refuses any `variables` entry whose `typeof` doesn't match.
62
+ * Catches type-confusion exploits where executors silently
63
+ * coerce (string-for-ID-expecting-Int).
64
+ *
65
+ * Batch defense: operators supporting `[{},{}]` batch arrays get
66
+ * N requests for one HTTP hit. Strict refuses batches outright;
67
+ * balanced caps at 10; permissive 50. Each batch entry is
68
+ * validated with the same threat catalog applied recursively.
69
+ *
70
+ * Profiles: `strict` / `balanced` / `permissive`. Compliance
71
+ * postures: `hipaa` / `pci-dss` / `gdpr` / `soc2`. BIDI / null /
72
+ * control / zero-width universal-refuse applies on the query
73
+ * string at every profile so trojan-source codepoints can't
74
+ * ride inside a query identifier.
75
+ *
76
+ * @card
77
+ * GraphQL request-shape safety guard — validates user-supplied request bundles against the canonical query-shape DoS catalog BEFORE the framework hands the query to a schema-aware executor.
36
78
  */
37
79
 
38
80
  var codepointClass = require("./codepoint-class");
@@ -370,6 +412,59 @@ function _detectIssues(req, opts) {
370
412
  return issues;
371
413
  }
372
414
 
415
+ /**
416
+ * @primitive b.guardGraphql.validate
417
+ * @signature b.guardGraphql.validate(input, opts?)
418
+ * @since 0.7.49
419
+ * @status stable
420
+ * @compliance hipaa, pci-dss, gdpr, soc2
421
+ * @related b.guardGraphql.sanitize, b.guardGraphql.gate
422
+ *
423
+ * Apply the full guard-graphql threat catalog to a request bundle
424
+ * (or batch array). Returns `{ ok, issues, refusal? }` per
425
+ * `gateContract.aggregateIssues`. Detected classes include
426
+ * `query-missing`, `query-cap`, `variables-cap`, `request-cap`,
427
+ * `batch-size`, `introspection`, `persisted-query-missing`,
428
+ * `operation-not-allowed`, `depth-exceeded`, `alias-bomb`,
429
+ * `variable-type-confusion`, plus codepoint-class issues on the
430
+ * query string. Operator-supplied opts are bounds-checked; bad
431
+ * opts throw `GuardGraphqlError("graphql.bad-opt")`.
432
+ *
433
+ * @opts
434
+ * profile: "strict"|"balanced"|"permissive",
435
+ * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
436
+ * introspectionPolicy: "reject"|"audit"|"allow",
437
+ * persistedQueryPolicy: "require"|"audit"|"allow",
438
+ * operationNamePolicy: "reject"|"audit"|"allow",
439
+ * batchPolicy: "reject"|"audit"|"allow",
440
+ * aliasBombPolicy: "reject"|"audit"|"allow",
441
+ * depthPolicy: "reject"|"audit"|"allow",
442
+ * variableShapePolicy: "reject"|"audit"|"allow",
443
+ * allowedOperations: string[],
444
+ * variableShapes: { [name: string]: "string"|"number"|"boolean"|"object" },
445
+ * maxDepth: number,
446
+ * maxAliasesPerSelection: number,
447
+ * maxBatchSize: number,
448
+ * maxQueryBytes: number,
449
+ * maxVariableBytes: number,
450
+ * maxBytes: number,
451
+ *
452
+ * @example
453
+ * var hostile = {
454
+ * query: "query Inspect { __schema { types { name } } }",
455
+ * operationName: "Inspect",
456
+ * };
457
+ * var rv = b.guardGraphql.validate(hostile, { profile: "strict" });
458
+ * rv.ok; // → false
459
+ * rv.issues[0].ruleId; // → "graphql.introspection"
460
+ *
461
+ * var benign = {
462
+ * query: "query GetMe { me { id name } }",
463
+ * operationName: "GetMe",
464
+ * };
465
+ * var ok = b.guardGraphql.validate(benign, { profile: "strict" });
466
+ * ok.ok; // → true
467
+ */
373
468
  function validate(input, opts) {
374
469
  opts = _resolveOpts(opts);
375
470
  numericBounds.requireAllPositiveFiniteIntIfPresent(opts,
@@ -379,6 +474,36 @@ function validate(input, opts) {
379
474
  return gateContract.aggregateIssues(_detectIssues(input, opts));
380
475
  }
381
476
 
477
+ /**
478
+ * @primitive b.guardGraphql.sanitize
479
+ * @signature b.guardGraphql.sanitize(input, opts?)
480
+ * @since 0.7.49
481
+ * @status stable
482
+ * @related b.guardGraphql.validate, b.guardGraphql.gate
483
+ *
484
+ * Pass-through-or-throw form of `validate`. GraphQL request
485
+ * bundles can't be partially repaired — depth bombs, alias
486
+ * amplification, and introspection leaks are refuse-class
487
+ * outcomes, not something the guard can patch up safely.
488
+ * Returns the input unchanged when the issue list contains no
489
+ * `critical` / `high` entries; throws `GuardGraphqlError`
490
+ * carrying the offending `ruleId` otherwise.
491
+ *
492
+ * @opts
493
+ * profile: "strict"|"balanced"|"permissive",
494
+ * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
495
+ * ...: every guardGraphql.validate opt is honored,
496
+ *
497
+ * @example
498
+ * try {
499
+ * b.guardGraphql.sanitize({
500
+ * query: "query Inspect { __schema { types { name } } }",
501
+ * operationName: "Inspect",
502
+ * }, { profile: "strict" });
503
+ * } catch (e) {
504
+ * e.code; // → "graphql.introspection"
505
+ * }
506
+ */
382
507
  function sanitize(input, opts) {
383
508
  opts = _resolveOpts(opts);
384
509
  var issues = _detectIssues(input, opts);
@@ -391,6 +516,42 @@ function sanitize(input, opts) {
391
516
  return input;
392
517
  }
393
518
 
519
+ /**
520
+ * @primitive b.guardGraphql.gate
521
+ * @signature b.guardGraphql.gate(opts?)
522
+ * @since 0.7.49
523
+ * @status stable
524
+ * @compliance hipaa, pci-dss, gdpr, soc2
525
+ * @related b.guardGraphql.validate, b.guardGraphql.sanitize
526
+ *
527
+ * Build a `gateContract.buildGuardGate`-shaped gate that pulls
528
+ * `ctx.graphqlRequest` (or `ctx.gql`) and dispatches to
529
+ * `validate`. Returns `{ ok: true, action: "serve" }` when the
530
+ * issue list is empty, `{ ok: true, action: "audit-only", issues }`
531
+ * when only low-severity issues fire, and `{ ok: false, action:
532
+ * "refuse", issues }` on any `critical` / `high` issue. Compose
533
+ * into the GraphQL request handler before any schema-resolution
534
+ * work — refusal short-circuits hostile depth / alias / batch
535
+ * shapes before they reach the executor.
536
+ *
537
+ * @opts
538
+ * profile: "strict"|"balanced"|"permissive",
539
+ * compliance: "hipaa"|"pci-dss"|"gdpr"|"soc2",
540
+ * name: string, // gate label for audit trails
541
+ * ...: every guardGraphql.validate opt is honored,
542
+ *
543
+ * @example
544
+ * var gqlGate = b.guardGraphql.gate({ profile: "strict" });
545
+ * var rv = await gqlGate.run({
546
+ * graphqlRequest: {
547
+ * query: "{ a:me { id } b:me { id } c:me { id } d:me { id } " +
548
+ * "e:me { id } f:me { id } g:me { id } h:me { id } " +
549
+ * "i:me { id } }",
550
+ * },
551
+ * });
552
+ * rv.action; // → "refuse"
553
+ * rv.issues[0].ruleId; // → "graphql.alias-bomb"
554
+ */
394
555
  function gate(opts) {
395
556
  opts = _resolveOpts(opts);
396
557
  return gateContract.buildGuardGate(
@@ -414,14 +575,86 @@ function gate(opts) {
414
575
  });
415
576
  }
416
577
 
578
+ /**
579
+ * @primitive b.guardGraphql.buildProfile
580
+ * @signature b.guardGraphql.buildProfile(opts)
581
+ * @since 0.7.49
582
+ * @status stable
583
+ * @related b.guardGraphql.gate, b.guardGraphql.compliancePosture
584
+ *
585
+ * Compose a derived profile from one or more named bases plus
586
+ * inline overrides. `opts.extends` is a profile name (`"strict"` /
587
+ * `"balanced"` / `"permissive"`) or an array of names; later
588
+ * entries shadow earlier ones, and inline `opts` keys win last.
589
+ * Operators stage profile overlays here so the final shape is
590
+ * traceable to a baseline rather than a hand-typed dictionary.
591
+ *
592
+ * @opts
593
+ * extends: string|string[], // base profile name(s) to compose
594
+ * ...: any guardGraphql key, // inline override of resolved keys
595
+ *
596
+ * @example
597
+ * var custom = b.guardGraphql.buildProfile({
598
+ * extends: "balanced",
599
+ * introspectionPolicy: "reject",
600
+ * maxDepth: 6,
601
+ * });
602
+ * custom.introspectionPolicy; // → "reject"
603
+ * custom.maxDepth; // → 6
604
+ */
417
605
  var buildProfile = gateContract.makeProfileBuilder(PROFILES);
418
606
 
607
+ /**
608
+ * @primitive b.guardGraphql.compliancePosture
609
+ * @signature b.guardGraphql.compliancePosture(name)
610
+ * @since 0.7.49
611
+ * @status stable
612
+ * @compliance hipaa, pci-dss, gdpr, soc2
613
+ * @related b.guardGraphql.gate, b.guardGraphql.buildProfile
614
+ *
615
+ * Look up a compliance-posture overlay by name (`"hipaa"` /
616
+ * `"pci-dss"` / `"gdpr"` / `"soc2"`). Returns a shallow clone of
617
+ * the posture object — the caller may mutate freely. Throws
618
+ * `GuardGraphqlError("graphql.bad-posture")` on unknown name.
619
+ * Postures extend the strict profile (or balanced for `gdpr`)
620
+ * with a `forensicSnippetBytes` cap appropriate to the regime.
621
+ *
622
+ * @example
623
+ * var posture = b.guardGraphql.compliancePosture("soc2");
624
+ * posture.introspectionPolicy; // → "reject"
625
+ * posture.forensicSnippetBytes; // → 1024
626
+ */
419
627
  function compliancePosture(name) {
420
628
  return gateContract.lookupCompliancePosture(name, COMPLIANCE_POSTURES,
421
629
  _err, "graphql");
422
630
  }
423
631
 
424
632
  var _gqlRulePacks = gateContract.makeRulePackLoader(GuardGraphqlError, "graphql");
633
+ /**
634
+ * @primitive b.guardGraphql.loadRulePack
635
+ * @signature b.guardGraphql.loadRulePack(pack)
636
+ * @since 0.7.49
637
+ * @status stable
638
+ * @related b.guardGraphql.gate
639
+ *
640
+ * Register an operator-supplied rule pack with the guard-graphql
641
+ * registry. The pack is identified by `pack.id` (non-empty
642
+ * string) and stored for later inspection / dispatch by gates
643
+ * that opt in via `opts.rulePackId`. Returns the pack object
644
+ * unchanged on success; throws `GuardGraphqlError("graphql.bad-opt")`
645
+ * when `pack` is missing or `pack.id` is not a non-empty string.
646
+ *
647
+ * @example
648
+ * var pack = b.guardGraphql.loadRulePack({
649
+ * id: "no-mutation-on-read-replica",
650
+ * rules: [
651
+ * { id: "no-mutation", severity: "high",
652
+ * detect: function (req) { return /^\s*mutation\b/.test(req.query || ""); },
653
+ * reason: "read-replica refuses mutation operations" },
654
+ * ],
655
+ * });
656
+ * pack.id; // → "no-mutation-on-read-replica"
657
+ */
425
658
  var loadRulePack = _gqlRulePacks.load;
426
659
 
427
660
  module.exports = {