@pithy-sh/core 0.1.2 → 0.1.3

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 (393) hide show
  1. package/dist/address/address.d.ts +57 -0
  2. package/dist/address/address.d.ts.map +1 -0
  3. package/dist/address/address.js +71 -0
  4. package/dist/audit/auditEvent.d.ts +89 -0
  5. package/dist/audit/auditEvent.d.ts.map +1 -0
  6. package/dist/audit/auditEvent.js +69 -0
  7. package/dist/audit/recorder.d.ts +18 -0
  8. package/dist/audit/recorder.d.ts.map +1 -0
  9. package/dist/audit/recorder.js +8 -0
  10. package/dist/capability/bindings.d.ts +62 -0
  11. package/dist/capability/bindings.d.ts.map +1 -0
  12. package/dist/capability/bindings.js +97 -0
  13. package/dist/capability/capability.d.ts +501 -0
  14. package/dist/capability/capability.d.ts.map +1 -0
  15. package/dist/capability/capability.js +16 -0
  16. package/dist/capability/client.d.ts +70 -0
  17. package/dist/capability/client.d.ts.map +1 -0
  18. package/dist/capability/client.js +86 -0
  19. package/dist/capability/compose.d.ts +25 -0
  20. package/dist/capability/compose.d.ts.map +1 -0
  21. package/dist/capability/compose.js +54 -0
  22. package/dist/capability/composition.d.ts +26 -0
  23. package/dist/capability/composition.d.ts.map +1 -0
  24. package/dist/capability/composition.js +84 -0
  25. package/dist/capability/config.d.ts +7 -0
  26. package/dist/capability/config.d.ts.map +1 -0
  27. package/dist/capability/config.js +14 -0
  28. package/dist/capability/devSecret.d.ts +32 -0
  29. package/dist/capability/devSecret.d.ts.map +1 -0
  30. package/dist/capability/devSecret.js +28 -0
  31. package/dist/capability/manifest.d.ts +298 -0
  32. package/dist/capability/manifest.d.ts.map +1 -0
  33. package/dist/capability/manifest.js +356 -0
  34. package/dist/capability/secretOrigin.d.ts +121 -0
  35. package/dist/capability/secretOrigin.d.ts.map +1 -0
  36. package/dist/capability/secretOrigin.js +134 -0
  37. package/dist/capability/settings.d.ts +119 -0
  38. package/dist/capability/settings.d.ts.map +1 -0
  39. package/dist/capability/settings.js +66 -0
  40. package/dist/capability/validateBindings.d.ts +4 -0
  41. package/dist/capability/validateBindings.d.ts.map +1 -0
  42. package/dist/capability/validateBindings.js +34 -0
  43. package/dist/capability/vanishingKey.d.ts +31 -0
  44. package/dist/capability/vanishingKey.d.ts.map +1 -0
  45. package/dist/capability/vanishingKey.js +79 -0
  46. package/dist/controlPlane/audit/actions.d.ts +70 -0
  47. package/dist/controlPlane/audit/actions.d.ts.map +1 -0
  48. package/dist/controlPlane/audit/actions.js +76 -0
  49. package/dist/controlPlane/capability.d.ts +47 -0
  50. package/dist/controlPlane/capability.d.ts.map +1 -0
  51. package/dist/controlPlane/capability.js +138 -0
  52. package/dist/controlPlane/config/config.d.ts +19 -0
  53. package/dist/controlPlane/config/config.d.ts.map +1 -0
  54. package/dist/controlPlane/config/config.js +85 -0
  55. package/dist/controlPlane/context.d.ts +27 -0
  56. package/dist/controlPlane/context.d.ts.map +1 -0
  57. package/dist/controlPlane/context.js +29 -0
  58. package/dist/controlPlane/data/connection.d.ts +79 -0
  59. package/dist/controlPlane/data/connection.d.ts.map +1 -0
  60. package/dist/controlPlane/data/connection.js +55 -0
  61. package/dist/controlPlane/data/keyLifecycle.d.ts +62 -0
  62. package/dist/controlPlane/data/keyLifecycle.d.ts.map +1 -0
  63. package/dist/controlPlane/data/keyLifecycle.js +126 -0
  64. package/dist/controlPlane/data/replay.d.ts +18 -0
  65. package/dist/controlPlane/data/replay.d.ts.map +1 -0
  66. package/dist/controlPlane/data/replay.js +20 -0
  67. package/dist/controlPlane/data/tables.d.ts +34 -0
  68. package/dist/controlPlane/data/tables.d.ts.map +1 -0
  69. package/dist/controlPlane/data/tables.js +37 -0
  70. package/dist/controlPlane/discovery/adminRoute.d.ts +313 -0
  71. package/dist/controlPlane/discovery/adminRoute.d.ts.map +1 -0
  72. package/dist/controlPlane/discovery/adminRoute.js +136 -0
  73. package/dist/controlPlane/discovery/configuration.d.ts +108 -0
  74. package/dist/controlPlane/discovery/configuration.d.ts.map +1 -0
  75. package/dist/controlPlane/discovery/configuration.js +187 -0
  76. package/dist/controlPlane/discovery/drift.d.ts +64 -0
  77. package/dist/controlPlane/discovery/drift.d.ts.map +1 -0
  78. package/dist/controlPlane/discovery/drift.js +58 -0
  79. package/dist/controlPlane/discovery/health.d.ts +99 -0
  80. package/dist/controlPlane/discovery/health.d.ts.map +1 -0
  81. package/dist/controlPlane/discovery/health.js +151 -0
  82. package/dist/controlPlane/discovery/healthSummary.d.ts +236 -0
  83. package/dist/controlPlane/discovery/healthSummary.d.ts.map +1 -0
  84. package/dist/controlPlane/discovery/healthSummary.js +278 -0
  85. package/dist/controlPlane/error/errors.d.ts +67 -0
  86. package/dist/controlPlane/error/errors.d.ts.map +1 -0
  87. package/dist/controlPlane/error/errors.js +79 -0
  88. package/dist/controlPlane/http/cors.d.ts +112 -0
  89. package/dist/controlPlane/http/cors.d.ts.map +1 -0
  90. package/dist/controlPlane/http/cors.js +192 -0
  91. package/dist/controlPlane/http/guard.d.ts +77 -0
  92. package/dist/controlPlane/http/guard.d.ts.map +1 -0
  93. package/dist/controlPlane/http/guard.js +142 -0
  94. package/dist/controlPlane/http/handlers.d.ts +179 -0
  95. package/dist/controlPlane/http/handlers.d.ts.map +1 -0
  96. package/dist/controlPlane/http/handlers.js +245 -0
  97. package/dist/controlPlane/http/responses.d.ts +99 -0
  98. package/dist/controlPlane/http/responses.d.ts.map +1 -0
  99. package/dist/controlPlane/http/responses.js +63 -0
  100. package/dist/controlPlane/http/routes.d.ts +40 -0
  101. package/dist/controlPlane/http/routes.d.ts.map +1 -0
  102. package/dist/controlPlane/http/routes.js +83 -0
  103. package/dist/controlPlane/http/schemas.d.ts +39 -0
  104. package/dist/controlPlane/http/schemas.d.ts.map +1 -0
  105. package/dist/controlPlane/http/schemas.js +31 -0
  106. package/dist/controlPlane/http/verify.d.ts +84 -0
  107. package/dist/controlPlane/http/verify.d.ts.map +1 -0
  108. package/dist/controlPlane/http/verify.js +65 -0
  109. package/dist/controlPlane/migrations/0001_init.d.ts +51 -0
  110. package/dist/controlPlane/migrations/0001_init.d.ts.map +1 -0
  111. package/dist/controlPlane/migrations/0001_init.js +65 -0
  112. package/dist/controlPlane/replay/d1Guard.d.ts +29 -0
  113. package/dist/controlPlane/replay/d1Guard.d.ts.map +1 -0
  114. package/dist/controlPlane/replay/d1Guard.js +39 -0
  115. package/dist/controlPlane/replay/guard.d.ts +52 -0
  116. package/dist/controlPlane/replay/guard.d.ts.map +1 -0
  117. package/dist/controlPlane/replay/guard.js +0 -0
  118. package/dist/controlPlane/replay/kvGuard.d.ts +99 -0
  119. package/dist/controlPlane/replay/kvGuard.d.ts.map +1 -0
  120. package/dist/controlPlane/replay/kvGuard.js +101 -0
  121. package/dist/controlPlane/scope/scope.d.ts +68 -0
  122. package/dist/controlPlane/scope/scope.d.ts.map +1 -0
  123. package/dist/controlPlane/scope/scope.js +63 -0
  124. package/dist/controlPlane/token/base64url.d.ts +10 -0
  125. package/dist/controlPlane/token/base64url.d.ts.map +1 -0
  126. package/dist/controlPlane/token/base64url.js +48 -0
  127. package/dist/controlPlane/token/claims.d.ts +83 -0
  128. package/dist/controlPlane/token/claims.d.ts.map +1 -0
  129. package/dist/controlPlane/token/claims.js +86 -0
  130. package/dist/controlPlane/token/digest.d.ts +44 -0
  131. package/dist/controlPlane/token/digest.d.ts.map +1 -0
  132. package/dist/controlPlane/token/digest.js +56 -0
  133. package/dist/controlPlane/token/jws.d.ts +52 -0
  134. package/dist/controlPlane/token/jws.d.ts.map +1 -0
  135. package/dist/controlPlane/token/jws.js +65 -0
  136. package/dist/controlPlane/token/mint.d.ts +56 -0
  137. package/dist/controlPlane/token/mint.d.ts.map +1 -0
  138. package/dist/controlPlane/token/mint.js +55 -0
  139. package/dist/controlPlane/wire.d.ts +122 -0
  140. package/dist/controlPlane/wire.d.ts.map +1 -0
  141. package/dist/controlPlane/wire.js +123 -0
  142. package/dist/createBackend.d.ts +58 -0
  143. package/dist/createBackend.d.ts.map +1 -0
  144. package/dist/createBackend.js +170 -0
  145. package/dist/createEntrypoint.d.ts +53 -0
  146. package/dist/createEntrypoint.d.ts.map +1 -0
  147. package/dist/createEntrypoint.js +52 -0
  148. package/dist/data/boundParameters.d.ts +83 -0
  149. package/dist/data/boundParameters.d.ts.map +1 -0
  150. package/dist/data/boundParameters.js +162 -0
  151. package/dist/data/codecs.d.ts +34 -0
  152. package/dist/data/codecs.d.ts.map +1 -0
  153. package/dist/data/codecs.js +135 -0
  154. package/dist/data/cursor.d.ts +81 -0
  155. package/dist/data/cursor.d.ts.map +1 -0
  156. package/dist/data/cursor.js +104 -0
  157. package/dist/data/databases.d.ts +55 -0
  158. package/dist/data/databases.d.ts.map +1 -0
  159. package/dist/data/databases.js +32 -0
  160. package/dist/data/db.d.ts +42 -0
  161. package/dist/data/db.d.ts.map +1 -0
  162. package/dist/data/db.js +24 -0
  163. package/dist/data/withD1Retry.d.ts +91 -0
  164. package/dist/data/withD1Retry.d.ts.map +1 -0
  165. package/dist/data/withD1Retry.js +152 -0
  166. package/dist/entitlement/entitlement.d.ts +118 -0
  167. package/dist/entitlement/entitlement.d.ts.map +1 -0
  168. package/dist/entitlement/entitlement.js +59 -0
  169. package/dist/entitlement/gateScan.d.ts +26 -0
  170. package/dist/entitlement/gateScan.d.ts.map +1 -0
  171. package/dist/entitlement/gateScan.js +96 -0
  172. package/dist/entitlement/require.d.ts +12 -0
  173. package/dist/entitlement/require.d.ts.map +1 -0
  174. package/dist/entitlement/require.js +123 -0
  175. package/dist/env/ambient.d.ts +52 -0
  176. package/dist/env/ambient.d.ts.map +1 -0
  177. package/dist/env/ambient.js +35 -0
  178. package/dist/env/ci.d.ts +36 -0
  179. package/dist/env/ci.d.ts.map +1 -0
  180. package/dist/env/ci.js +40 -0
  181. package/dist/env/stem.d.ts +23 -0
  182. package/dist/env/stem.d.ts.map +1 -0
  183. package/dist/env/stem.js +29 -0
  184. package/dist/error/cause.d.ts +143 -0
  185. package/dist/error/cause.d.ts.map +1 -0
  186. package/dist/error/cause.js +192 -0
  187. package/dist/error/client.d.ts +35 -0
  188. package/dist/error/client.d.ts.map +1 -0
  189. package/dist/error/client.js +38 -0
  190. package/dist/error/extend.d.ts +101 -0
  191. package/dist/error/extend.d.ts.map +1 -0
  192. package/dist/error/extend.js +76 -0
  193. package/dist/error/http.d.ts +1516 -0
  194. package/dist/error/http.d.ts.map +1 -0
  195. package/dist/error/http.js +72 -0
  196. package/dist/error/payload.d.ts +3034 -0
  197. package/dist/error/payload.d.ts.map +1 -0
  198. package/dist/error/payload.js +1110 -0
  199. package/dist/error/pithyError.d.ts +154 -0
  200. package/dist/error/pithyError.d.ts.map +1 -0
  201. package/dist/error/pithyError.js +197 -0
  202. package/dist/error/terminal.d.ts +28 -0
  203. package/dist/error/terminal.d.ts.map +1 -0
  204. package/dist/error/terminal.js +33 -0
  205. package/dist/http/authContext.d.ts +21 -0
  206. package/dist/http/authContext.d.ts.map +1 -0
  207. package/dist/http/authContext.js +23 -0
  208. package/dist/http/routeContract.d.ts +39 -0
  209. package/dist/http/routeContract.d.ts.map +1 -0
  210. package/dist/http/routeContract.js +82 -0
  211. package/dist/http/sameOrigin.d.ts +47 -0
  212. package/dist/http/sameOrigin.d.ts.map +1 -0
  213. package/dist/http/sameOrigin.js +24 -0
  214. package/dist/http/signedWebhook.d.ts +225 -0
  215. package/dist/http/signedWebhook.d.ts.map +1 -0
  216. package/dist/http/signedWebhook.js +247 -0
  217. package/dist/http/validation.d.ts +37 -0
  218. package/dist/http/validation.d.ts.map +1 -0
  219. package/dist/http/validation.js +14 -0
  220. package/dist/http/verification.d.ts +10 -0
  221. package/dist/http/verification.d.ts.map +1 -0
  222. package/dist/http/verification.js +17 -0
  223. package/dist/i18n/acceptLanguage.d.ts +22 -0
  224. package/dist/i18n/acceptLanguage.d.ts.map +1 -0
  225. package/dist/i18n/acceptLanguage.js +55 -0
  226. package/dist/i18n/catalog.d.ts +39 -0
  227. package/dist/i18n/catalog.d.ts.map +1 -0
  228. package/dist/i18n/catalog.js +57 -0
  229. package/dist/i18n/locale.d.ts +74 -0
  230. package/dist/i18n/locale.d.ts.map +1 -0
  231. package/dist/i18n/locale.js +109 -0
  232. package/dist/i18n/localeMarker.d.ts +29 -0
  233. package/dist/i18n/localeMarker.d.ts.map +1 -0
  234. package/dist/i18n/localeMarker.js +112 -0
  235. package/dist/i18n/match.d.ts +26 -0
  236. package/dist/i18n/match.d.ts.map +1 -0
  237. package/dist/i18n/match.js +88 -0
  238. package/dist/i18n/registry.d.ts +25 -0
  239. package/dist/i18n/registry.d.ts.map +1 -0
  240. package/dist/i18n/registry.js +51 -0
  241. package/dist/i18n/translator.d.ts +107 -0
  242. package/dist/i18n/translator.d.ts.map +1 -0
  243. package/dist/i18n/translator.js +80 -0
  244. package/dist/index.d.ts +32 -0
  245. package/dist/index.d.ts.map +1 -0
  246. package/dist/index.js +17 -0
  247. package/dist/kv/kv.d.ts +166 -0
  248. package/dist/kv/kv.d.ts.map +1 -0
  249. package/dist/kv/kv.js +261 -0
  250. package/dist/kv/namespaces.d.ts +58 -0
  251. package/dist/kv/namespaces.d.ts.map +1 -0
  252. package/dist/kv/namespaces.js +40 -0
  253. package/dist/logger/local.d.ts +41 -0
  254. package/dist/logger/local.d.ts.map +1 -0
  255. package/dist/logger/local.js +45 -0
  256. package/dist/logger/logger.d.ts +56 -0
  257. package/dist/logger/logger.d.ts.map +1 -0
  258. package/dist/logger/logger.js +83 -0
  259. package/dist/logger/record.d.ts +919 -0
  260. package/dist/logger/record.d.ts.map +1 -0
  261. package/dist/logger/record.js +79 -0
  262. package/dist/logger/worker.d.ts +74 -0
  263. package/dist/logger/worker.d.ts.map +1 -0
  264. package/dist/logger/worker.js +54 -0
  265. package/dist/migrations/batch.d.ts +10 -0
  266. package/dist/migrations/batch.d.ts.map +1 -0
  267. package/dist/migrations/batch.js +193 -0
  268. package/dist/migrations/bookkeeping.d.ts +24 -0
  269. package/dist/migrations/bookkeeping.d.ts.map +1 -0
  270. package/dist/migrations/bookkeeping.js +57 -0
  271. package/dist/migrations/owner.d.ts +41 -0
  272. package/dist/migrations/owner.d.ts.map +1 -0
  273. package/dist/migrations/owner.js +105 -0
  274. package/dist/migrations/registry.d.ts +36 -0
  275. package/dist/migrations/registry.d.ts.map +1 -0
  276. package/dist/migrations/registry.js +70 -0
  277. package/dist/migrations/runner.d.ts +67 -0
  278. package/dist/migrations/runner.d.ts.map +1 -0
  279. package/dist/migrations/runner.js +218 -0
  280. package/dist/naming/domains.d.ts +108 -0
  281. package/dist/naming/domains.d.ts.map +1 -0
  282. package/dist/naming/domains.js +156 -0
  283. package/dist/naming/environment.d.ts +118 -0
  284. package/dist/naming/environment.d.ts.map +1 -0
  285. package/dist/naming/environment.js +190 -0
  286. package/dist/naming/feature.d.ts +68 -0
  287. package/dist/naming/feature.d.ts.map +1 -0
  288. package/dist/naming/feature.js +106 -0
  289. package/dist/naming/limits.d.ts +229 -0
  290. package/dist/naming/limits.d.ts.map +1 -0
  291. package/dist/naming/limits.js +187 -0
  292. package/dist/naming/provisionScope.d.ts +91 -0
  293. package/dist/naming/provisionScope.d.ts.map +1 -0
  294. package/dist/naming/provisionScope.js +65 -0
  295. package/dist/naming/resource.d.ts +169 -0
  296. package/dist/naming/resource.d.ts.map +1 -0
  297. package/dist/naming/resource.js +220 -0
  298. package/dist/naming/resourceNames.d.ts +83 -0
  299. package/dist/naming/resourceNames.d.ts.map +1 -0
  300. package/dist/naming/resourceNames.js +102 -0
  301. package/dist/naming/segment.d.ts +29 -0
  302. package/dist/naming/segment.d.ts.map +1 -0
  303. package/dist/naming/segment.js +31 -0
  304. package/dist/projection/asRead.d.ts +72 -0
  305. package/dist/projection/asRead.d.ts.map +1 -0
  306. package/dist/projection/asRead.js +169 -0
  307. package/dist/projection/published.d.ts +95 -0
  308. package/dist/projection/published.d.ts.map +1 -0
  309. package/dist/projection/published.js +114 -0
  310. package/dist/schema/describedness.d.ts +55 -0
  311. package/dist/schema/describedness.d.ts.map +1 -0
  312. package/dist/schema/describedness.js +180 -0
  313. package/dist/seed/compose.d.ts +41 -0
  314. package/dist/seed/compose.d.ts.map +1 -0
  315. package/dist/seed/compose.js +51 -0
  316. package/dist/seed/devLogin.d.ts +50 -0
  317. package/dist/seed/devLogin.d.ts.map +1 -0
  318. package/dist/seed/devLogin.js +52 -0
  319. package/dist/seed/exampleIdentities.d.ts +58 -0
  320. package/dist/seed/exampleIdentities.d.ts.map +1 -0
  321. package/dist/seed/exampleIdentities.js +26 -0
  322. package/dist/seed/metadata.d.ts +20 -0
  323. package/dist/seed/metadata.d.ts.map +1 -0
  324. package/dist/seed/metadata.js +27 -0
  325. package/dist/seed/seed.d.ts +264 -0
  326. package/dist/seed/seed.d.ts.map +1 -0
  327. package/dist/seed/seed.js +37 -0
  328. package/dist/seed/seededRows.d.ts +26 -0
  329. package/dist/seed/seededRows.d.ts.map +1 -0
  330. package/dist/seed/seededRows.js +20 -0
  331. package/dist/seed/writeD1.d.ts +43 -0
  332. package/dist/seed/writeD1.d.ts.map +1 -0
  333. package/dist/seed/writeD1.js +73 -0
  334. package/dist/seed/writeKv.d.ts +29 -0
  335. package/dist/seed/writeKv.d.ts.map +1 -0
  336. package/dist/seed/writeKv.js +63 -0
  337. package/dist/semver/semver.d.ts +62 -0
  338. package/dist/semver/semver.d.ts.map +1 -0
  339. package/dist/semver/semver.js +137 -0
  340. package/dist/text/comments.d.ts +62 -0
  341. package/dist/text/comments.d.ts.map +1 -0
  342. package/dist/text/comments.js +161 -0
  343. package/dist/version.generated.d.ts +5 -0
  344. package/dist/version.generated.d.ts.map +1 -0
  345. package/dist/version.generated.js +7 -0
  346. package/dist/worker/health.d.ts +39 -0
  347. package/dist/worker/health.d.ts.map +1 -0
  348. package/dist/worker/health.js +41 -0
  349. package/dist/worker/identity.d.ts +191 -0
  350. package/dist/worker/identity.d.ts.map +1 -0
  351. package/dist/worker/identity.js +162 -0
  352. package/dist/workflow/bindings.d.ts +41 -0
  353. package/dist/workflow/bindings.d.ts.map +1 -0
  354. package/dist/workflow/bindings.js +53 -0
  355. package/dist/workflow/dispatch.d.ts +98 -0
  356. package/dist/workflow/dispatch.d.ts.map +1 -0
  357. package/dist/workflow/dispatch.js +148 -0
  358. package/dist/workflow/dispatchRoute.d.ts +80 -0
  359. package/dist/workflow/dispatchRoute.d.ts.map +1 -0
  360. package/dist/workflow/dispatchRoute.js +134 -0
  361. package/dist/workflow/faults.d.ts +97 -0
  362. package/dist/workflow/faults.d.ts.map +1 -0
  363. package/dist/workflow/faults.js +111 -0
  364. package/dist/workflow/host.d.ts +176 -0
  365. package/dist/workflow/host.d.ts.map +1 -0
  366. package/dist/workflow/host.js +116 -0
  367. package/dist/workflow/hostEntry.d.ts +50 -0
  368. package/dist/workflow/hostEntry.d.ts.map +1 -0
  369. package/dist/workflow/hostEntry.js +24 -0
  370. package/dist/workflow/hostEnv.d.ts +143 -0
  371. package/dist/workflow/hostEnv.d.ts.map +1 -0
  372. package/dist/workflow/hostEnv.js +170 -0
  373. package/dist/workflow/loopback.d.ts +52 -0
  374. package/dist/workflow/loopback.d.ts.map +1 -0
  375. package/dist/workflow/loopback.js +76 -0
  376. package/dist/workflow/naming.d.ts +79 -0
  377. package/dist/workflow/naming.d.ts.map +1 -0
  378. package/dist/workflow/naming.js +138 -0
  379. package/dist/workflow/register.d.ts +19 -0
  380. package/dist/workflow/register.d.ts.map +1 -0
  381. package/dist/workflow/register.js +40 -0
  382. package/dist/workflow/schemas.d.ts +44 -0
  383. package/dist/workflow/schemas.d.ts.map +1 -0
  384. package/dist/workflow/schemas.js +43 -0
  385. package/dist/workflow/spec.d.ts +81 -0
  386. package/dist/workflow/spec.d.ts.map +1 -0
  387. package/dist/workflow/spec.js +0 -0
  388. package/dist/workflow/stepMessage.d.ts +122 -0
  389. package/dist/workflow/stepMessage.d.ts.map +1 -0
  390. package/dist/workflow/stepMessage.js +152 -0
  391. package/package.json +20 -9
  392. package/src/capability/manifest.ts +21 -0
  393. package/src/version.generated.ts +1 -1
@@ -0,0 +1,72 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * The reader's contract: a capability's own response object, restated for a client that does not
4
+ * control the Worker that wrote the response.
5
+ *
6
+ * ## One schema, two consumers, two obligations
7
+ *
8
+ * A capability states each projection once, in its `http/responses.ts`, and both consumers validate
9
+ * against it — the Worker's own tests and every management client. That is right for the fields and
10
+ * wrong for the enums, because the two consumers are answering different questions.
11
+ *
12
+ * A **Worker validating its own projection is checking itself.** It must be strict: an enum there is
13
+ * what the ingest path branches on and what D1 holds, and a tolerated-unknown member would license the
14
+ * capability to *store* a value it cannot handle. Nothing here loosens that, and nothing here should:
15
+ * the producer's enums are untouched, and this module never sees them at parse time.
16
+ *
17
+ * A **management client reading that response is crossing a trust boundary.** The system that wrote it
18
+ * is a fork, a bug, a half-finished deploy, or hostile — none of which is downstream of how anybody's
19
+ * releases are cut — and one member it has never heard of currently costs it the whole response rather
20
+ * than the one row that carried it. A support console rendered zero of twenty-five conversations that
21
+ * way (`pithy-sh/dashboard#15`), and the client that fixed it had to widen the kit's shape locally,
22
+ * which is the mirror-of-a-projection that `#113` exists to forbid.
23
+ *
24
+ * So the tolerance is published **beside** the producer's shape rather than inside it. `asRead(X)` is
25
+ * the whole pattern: the same object, with every enum reachable through it read as a string.
26
+ *
27
+ * ## What it is not
28
+ *
29
+ * **It is not a loosening.** A missing field, a number where a string belongs, a value outside a
30
+ * numeric bound, a body that is not an object — all still refuse the whole response, exactly as before.
31
+ * The only thing that changes is which *members* an enum-shaped field admits.
32
+ *
33
+ * **It is not a mapping.** The token is handed back verbatim. The enum stays the authority on what a
34
+ * value means — `SupportChannel.safeParse(value).success` is the question, and the answer is the
35
+ * client's license to *mark* the row. Reading an unrecognized value as the nearest one you know is a
36
+ * lie about a fact somebody is about to act on, and this pattern exists to make marking cheap enough
37
+ * that nobody reaches for mapping.
38
+ *
39
+ * **It is not selective.** A reader's obligation does not vary field by field: it does not control the
40
+ * writer, so *any* unknown member costs it the response. Widening two enums and leaving a third is how
41
+ * the same blank pane returns one field over.
42
+ *
43
+ * ## What it refuses to do
44
+ *
45
+ * It rewrites what it can see through — objects, arrays, `nullable`, `optional` — and returns anything
46
+ * with no enum under it as the **identical schema instance**, so a reader's view and its producer share
47
+ * every untouched field rather than copying it. Everything else throws at construction:
48
+ * {@link asRead} either produces a view with no enum left in it or refuses to produce one, because a
49
+ * shape that silently passed a union through would publish a "reader's contract" that still refuses an
50
+ * unknown member — the original defect, wearing a name that says it was handled.
51
+ */
52
+ /** What a widened field says about itself, appended to the description the enum already carried. */
53
+ export declare const TOLERATED_MEMBER = "Read as a string rather than as the enum it comes from: a client does not control the Worker that wrote this, so a member the enum does not declare is handed back verbatim instead of refusing the whole response. Ask the enum what a value means, mark what it does not declare, and never map it to the nearest value you know.";
54
+ /**
55
+ * The producer's schema with every enum under it read as a string.
56
+ *
57
+ * Enum in, string out; a wrapper keeps its own description and the widened member carries the enum's,
58
+ * with {@link TOLERATED_MEMBER} appended so the schema still documents itself. Everything else is the
59
+ * schema the capability declared, by identity.
60
+ */
61
+ export type AsRead<T> = T extends z.ZodEnum ? z.ZodString : T extends z.ZodNullable<infer Inner> ? z.ZodNullable<Extract<AsRead<Inner>, z.ZodType>> : T extends z.ZodOptional<infer Inner> ? z.ZodOptional<Extract<AsRead<Inner>, z.ZodType>> : T extends z.ZodArray<infer Element> ? z.ZodArray<Extract<AsRead<Element>, z.ZodType>> : T extends z.ZodObject<infer Shape> ? z.ZodObject<{
62
+ [K in keyof Shape]: Extract<AsRead<Shape[K]>, z.ZodType>;
63
+ }> : T;
64
+ /**
65
+ * A capability's response object, as a client that does not control the writer must read it.
66
+ *
67
+ * Export the result beside the producer's schema — `XAsRead` beside `X` — so a client imports tolerance
68
+ * rather than building it. Throws if the projection holds a shape this cannot see through; see the
69
+ * module docstring for why that is a refusal rather than a pass-through.
70
+ */
71
+ export declare function asRead<T extends z.ZodType>(schema: T): AsRead<T>;
72
+ //# sourceMappingURL=asRead.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asRead.d.ts","sourceRoot":"","sources":["../../src/projection/asRead.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AAEH,oGAAoG;AACpG,eAAO,MAAM,gBAAgB,wUAC0S,CAAC;AA2HxU;;;;;;GAMG;AACH,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,GACvC,CAAC,CAAC,SAAS,GACX,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,GAClC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,GAChD,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC,GAClC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,GAChD,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,MAAM,OAAO,CAAC,GACjC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,GAC/C,CAAC,SAAS,CAAC,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,GAChC,CAAC,CAAC,SAAS,CAAC;KAAG,CAAC,IAAI,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC;CAAE,CAAC,GACzE,CAAC,CAAC;AAEd;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAEhE"}
@@ -0,0 +1,169 @@
1
+ import { InternalError } from "../error/pithyError.js";
2
+ import { z } from "zod";
3
+ //#region src/projection/asRead.ts
4
+ /**
5
+ * The reader's contract: a capability's own response object, restated for a client that does not
6
+ * control the Worker that wrote the response.
7
+ *
8
+ * ## One schema, two consumers, two obligations
9
+ *
10
+ * A capability states each projection once, in its `http/responses.ts`, and both consumers validate
11
+ * against it — the Worker's own tests and every management client. That is right for the fields and
12
+ * wrong for the enums, because the two consumers are answering different questions.
13
+ *
14
+ * A **Worker validating its own projection is checking itself.** It must be strict: an enum there is
15
+ * what the ingest path branches on and what D1 holds, and a tolerated-unknown member would license the
16
+ * capability to *store* a value it cannot handle. Nothing here loosens that, and nothing here should:
17
+ * the producer's enums are untouched, and this module never sees them at parse time.
18
+ *
19
+ * A **management client reading that response is crossing a trust boundary.** The system that wrote it
20
+ * is a fork, a bug, a half-finished deploy, or hostile — none of which is downstream of how anybody's
21
+ * releases are cut — and one member it has never heard of currently costs it the whole response rather
22
+ * than the one row that carried it. A support console rendered zero of twenty-five conversations that
23
+ * way (`pithy-sh/dashboard#15`), and the client that fixed it had to widen the kit's shape locally,
24
+ * which is the mirror-of-a-projection that `#113` exists to forbid.
25
+ *
26
+ * So the tolerance is published **beside** the producer's shape rather than inside it. `asRead(X)` is
27
+ * the whole pattern: the same object, with every enum reachable through it read as a string.
28
+ *
29
+ * ## What it is not
30
+ *
31
+ * **It is not a loosening.** A missing field, a number where a string belongs, a value outside a
32
+ * numeric bound, a body that is not an object — all still refuse the whole response, exactly as before.
33
+ * The only thing that changes is which *members* an enum-shaped field admits.
34
+ *
35
+ * **It is not a mapping.** The token is handed back verbatim. The enum stays the authority on what a
36
+ * value means — `SupportChannel.safeParse(value).success` is the question, and the answer is the
37
+ * client's license to *mark* the row. Reading an unrecognized value as the nearest one you know is a
38
+ * lie about a fact somebody is about to act on, and this pattern exists to make marking cheap enough
39
+ * that nobody reaches for mapping.
40
+ *
41
+ * **It is not selective.** A reader's obligation does not vary field by field: it does not control the
42
+ * writer, so *any* unknown member costs it the response. Widening two enums and leaving a third is how
43
+ * the same blank pane returns one field over.
44
+ *
45
+ * ## What it refuses to do
46
+ *
47
+ * It rewrites what it can see through — objects, arrays, `nullable`, `optional` — and returns anything
48
+ * with no enum under it as the **identical schema instance**, so a reader's view and its producer share
49
+ * every untouched field rather than copying it. Everything else throws at construction:
50
+ * {@link asRead} either produces a view with no enum left in it or refuses to produce one, because a
51
+ * shape that silently passed a union through would publish a "reader's contract" that still refuses an
52
+ * unknown member — the original defect, wearing a name that says it was handled.
53
+ */
54
+ /** What a widened field says about itself, appended to the description the enum already carried. */
55
+ const TOLERATED_MEMBER = "Read as a string rather than as the enum it comes from: a client does not control the Worker that wrote this, so a member the enum does not declare is handed back verbatim instead of refusing the whole response. Ask the enum what a value means, mark what it does not declare, and never map it to the nearest value you know.";
56
+ /** Read a schema's internal def, tolerating both the `_zod.def` and `.def` shapes across Zod builds. */
57
+ function defOf(schema) {
58
+ const internal = schema;
59
+ return internal._zod?.def ?? internal.def ?? {};
60
+ }
61
+ /**
62
+ * The type tags that hold no other schema, so nothing inside one can be an enum.
63
+ *
64
+ * **Written out, never derived.** A permitted set computed from what the walk happens to handle would
65
+ * grant an exemption to every kind somebody adds later, silently, which is the failure this roster is
66
+ * here to prevent. A tag not on this list and not rewritten below is refused.
67
+ *
68
+ * `literal` is on it deliberately. A literal is not a vocabulary a capability might extend — it is how
69
+ * a discriminated union tells its arms apart, and widening one would destroy the union rather than
70
+ * tolerate anything.
71
+ */
72
+ const LEAF_TYPES = /* @__PURE__ */ new Set([
73
+ "string",
74
+ "number",
75
+ "int",
76
+ "bigint",
77
+ "boolean",
78
+ "date",
79
+ "literal",
80
+ "template_literal",
81
+ "file",
82
+ "symbol",
83
+ "null",
84
+ "undefined",
85
+ "void",
86
+ "any",
87
+ "unknown",
88
+ "never",
89
+ "nan"
90
+ ]);
91
+ /**
92
+ * The refusal, with the offending schema's *path* in it and never a value.
93
+ *
94
+ * Thrown while a module is being evaluated, which is exactly where it belongs: a reader's contract is
95
+ * built once at import, so a capability that cannot state one finds out in its own test run rather
96
+ * than in front of a client.
97
+ */
98
+ function unreadable(path, kind) {
99
+ return new InternalError({
100
+ message: "This projection has no reader's contract.",
101
+ action: `State the reader's view of ${path} by hand, or reshape it so \`asRead\` can see through it.`,
102
+ detail: `asRead met a \`${kind}\` at ${path}. It rewrites objects, arrays, nullable and optional wrappers, and refuses anything else rather than return a view that may still hold an enum a reader cannot survive.`
103
+ });
104
+ }
105
+ /** The refusal for an object whose unknown-key rule a rebuild would change. */
106
+ function unrebuildable(path) {
107
+ return new InternalError({
108
+ message: "This projection has no reader's contract.",
109
+ action: `Drop the unknown-key rule on ${path}, or state its reader's view by hand.`,
110
+ detail: `asRead met an object at ${path} that both holds an enum and declares its own unknown-key rule. Rebuilding it would silently change what it refuses, so it refuses to guess.`
111
+ });
112
+ }
113
+ /** A rebuilt schema wearing the description the original carried. Nothing is described twice. */
114
+ function describedLike(rebuilt, original) {
115
+ return original.description === void 0 ? rebuilt : rebuilt.describe(original.description);
116
+ }
117
+ /**
118
+ * One node of the rewrite. Returns the identical instance when nothing under it is an enum.
119
+ *
120
+ * The identity is not an optimization. It is what keeps a reader's view from becoming a second opinion
121
+ * about the fields it did not widen: a field it shares with the producer is the *same object*, so a
122
+ * change upstream lands in both, and a client can assert that field by field.
123
+ */
124
+ function readerOf(schema, path) {
125
+ const { type, catchall } = defOf(schema);
126
+ if (type === "enum") {
127
+ const said = schema.description;
128
+ return z.string().describe(said === void 0 ? TOLERATED_MEMBER : `${said} ${TOLERATED_MEMBER}`);
129
+ }
130
+ if (schema instanceof z.ZodNullable || schema instanceof z.ZodOptional) {
131
+ const inner = schema.unwrap();
132
+ const read = readerOf(inner, path);
133
+ if (read === inner) return schema;
134
+ return describedLike(schema instanceof z.ZodNullable ? z.nullable(read) : z.optional(read), schema);
135
+ }
136
+ if (schema instanceof z.ZodArray) {
137
+ const element = schema.element;
138
+ const read = readerOf(element, `${path}[]`);
139
+ if (read === element) return schema;
140
+ return describedLike(z.array(read), schema);
141
+ }
142
+ if (schema instanceof z.ZodObject) {
143
+ const shape = {};
144
+ let widened = false;
145
+ for (const [key, field] of Object.entries(schema.shape)) {
146
+ const original = field;
147
+ const read = readerOf(original, `${path}.${key}`);
148
+ shape[key] = read;
149
+ if (read !== original) widened = true;
150
+ }
151
+ if (!widened) return schema;
152
+ if (catchall !== void 0) throw unrebuildable(path);
153
+ return describedLike(z.object(shape), schema);
154
+ }
155
+ if (type !== void 0 && LEAF_TYPES.has(type)) return schema;
156
+ throw unreadable(path, type ?? "schema of no stated type");
157
+ }
158
+ /**
159
+ * A capability's response object, as a client that does not control the writer must read it.
160
+ *
161
+ * Export the result beside the producer's schema — `XAsRead` beside `X` — so a client imports tolerance
162
+ * rather than building it. Throws if the projection holds a shape this cannot see through; see the
163
+ * module docstring for why that is a refusal rather than a pass-through.
164
+ */
165
+ function asRead(schema) {
166
+ return readerOf(schema, "response");
167
+ }
168
+ //#endregion
169
+ export { TOLERATED_MEMBER, asRead };
@@ -0,0 +1,95 @@
1
+ /**
2
+ * The gate primitive for a projection that crosses a trust boundary: **nothing left this surface but the
3
+ * facts it publishes.**
4
+ *
5
+ * Every such gate in this kit was first written as its negative — a list of strings that must not appear
6
+ * in the response. A negative list is complete only against the values somebody thought of, and a
7
+ * projection widens by gaining a *field*, which is exactly the event a value list cannot observe. The
8
+ * same argument has been lost here three times over: a tripwire banning `access` while `stat` followed
9
+ * links identically, an escape class that arrived as three different verbs, and a bundle sweep seeded
10
+ * with the credential shapes of the day.
11
+ *
12
+ * So the rule is stated positively and computed rather than enumerated. Two halves, and **both are
13
+ * required, because either alone lets the mistake through**:
14
+ *
15
+ * 1. **Every leaf must be a published fact.** This is what catches a forbidden value arriving under a
16
+ * field name nobody predicted.
17
+ * 2. **Every key must be a published key.** This is what catches a leaf whose *type* has no vocabulary —
18
+ * `true`, `false` and `null` belong to every JSON document, so the first half can never police them,
19
+ * and a new `boolean` field is the cheapest way to widen a projection.
20
+ *
21
+ * ## Two rules for the caller, and both were paid for
22
+ *
23
+ * **Write the permitted key set out by hand.** Deriving it from `Object.keys(Schema.shape)` makes the
24
+ * gate read its own subject: the edit that widens the schema widens the permission, in the same commit,
25
+ * and the test whose entire job is to catch that passes. That happened, on the catalog read.
26
+ *
27
+ * **Seed the source with something forbidden of every JSON type.** A sweep over a document that never
28
+ * held anything secret passes perfectly and proves nothing. The leaf walk below once returned `[]` for
29
+ * every type that was not a string or a number, so booleans and nulls crossed untouched — nothing
30
+ * forbidden happened to be a boolean that day, which is what kept it from being a live leak, not what
31
+ * made it safe.
32
+ *
33
+ * ## Why it throws
34
+ *
35
+ * A value this walk cannot name is a silent exemption for a whole JSON type, granted by a fallthrough.
36
+ * That is the defect above, restated. So {@link unpublishedIn} refuses the document instead: a value the
37
+ * caller hands it must be an array, a plain object, or a JSON leaf, and anything else means a live
38
+ * JavaScript object rather than what a client receives. Round-trip through
39
+ * `JSON.parse(JSON.stringify(...))` first: that is what crosses, and what crosses is what a gate is about.
40
+ *
41
+ * **The rule is what the walk can *see*, not a list of types it distrusts.** `typeof` answers "object"
42
+ * for a `Date`, a `Map`, a `Set` and every class instance, and each of those descends to no keys and no
43
+ * leaves — a `Map`'s entries are not own properties and a getter lives on the prototype — so the descent
44
+ * itself was handing out the same exemption through the one branch that looked safe. So a container is
45
+ * one whose whole contents `Object.entries` returns: prototype `Object.prototype`, `Array.prototype`, or
46
+ * `null`. The first two are what `JSON.parse` produces and the third holds nothing anywhere else to
47
+ * find. Naming the unnameable types instead would be the enumeration this module exists to refuse, and
48
+ * the next class nobody thought of would walk straight through.
49
+ *
50
+ * **And `Object.entries` is then what descends, arrays included.** The rule above was stated once and only
51
+ * half run: the array branch still walked by position, so an own property on a plain array — a prototype
52
+ * this walk accepts, nothing to refuse — was contents the walk could not see. A rule the code disagrees
53
+ * with is a rule in a comment.
54
+ */
55
+ /** Anything a JSON document holds that is not an object or an array. */
56
+ export type JsonLeaf = string | number | boolean | null;
57
+ /**
58
+ * What one surface is allowed to publish: the facts, and the field names they may sit under.
59
+ *
60
+ * `keys` is a literal written at the call site. Never `Object.keys` of the schema being policed — see
61
+ * the note above.
62
+ */
63
+ export interface PublishedFacts {
64
+ /** Every value this surface may disclose, from wherever it legitimately came. */
65
+ readonly leaves: Iterable<JsonLeaf>;
66
+ /** Every object key this surface may carry, at any depth. Written out by hand. */
67
+ readonly keys: Iterable<string>;
68
+ }
69
+ /**
70
+ * Everything in `document` that {@link PublishedFacts} does not permit, as lines naming what and where.
71
+ *
72
+ * Empty means the projection published only what it declared. A non-empty result is the message: each
73
+ * line carries the offending key or value and its JSON path, so a failure says which field widened
74
+ * rather than that some string was present.
75
+ *
76
+ * @param document A JSON document — what a client actually receives, not a live object.
77
+ * @param published The facts and keys this surface declares.
78
+ * @throws If `document` holds a value JSON cannot express.
79
+ */
80
+ export declare function unpublishedIn(document: unknown, published: PublishedFacts): string[];
81
+ /**
82
+ * Every leaf in a JSON document, wherever it sits, of every JSON type. Object keys are collected separately.
83
+ *
84
+ * @throws If `document` holds a value JSON cannot express, on the same terms as {@link unpublishedIn} —
85
+ * a caller builds its declaration from this, and a value walked to nothing becomes a permitted set that
86
+ * omits a field.
87
+ */
88
+ export declare function leavesIn(document: unknown): JsonLeaf[];
89
+ /**
90
+ * Every object key in a JSON document, wherever it sits.
91
+ *
92
+ * @throws If `document` holds a value JSON cannot express, on the same terms as {@link unpublishedIn}.
93
+ */
94
+ export declare function keysIn(document: unknown): string[];
95
+ //# sourceMappingURL=published.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"published.d.ts","sourceRoot":"","sources":["../../src/projection/published.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAEH,wEAAwE;AACxE,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAExD;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,iFAAiF;IACjF,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACpC,kFAAkF;IAClF,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;CACjC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,GAAG,MAAM,EAAE,CAMpF;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,OAAO,GAAG,QAAQ,EAAE,CAEtD;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,EAAE,CAElD"}
@@ -0,0 +1,114 @@
1
+ //#region src/projection/published.ts
2
+ /**
3
+ * Everything in `document` that {@link PublishedFacts} does not permit, as lines naming what and where.
4
+ *
5
+ * Empty means the projection published only what it declared. A non-empty result is the message: each
6
+ * line carries the offending key or value and its JSON path, so a failure says which field widened
7
+ * rather than that some string was present.
8
+ *
9
+ * @param document A JSON document — what a client actually receives, not a live object.
10
+ * @param published The facts and keys this surface declares.
11
+ * @throws If `document` holds a value JSON cannot express.
12
+ */
13
+ function unpublishedIn(document, published) {
14
+ const leaves = new Set(published.leaves);
15
+ const keys = new Set(published.keys);
16
+ const found = [];
17
+ walk(document, "", leaves, keys, found);
18
+ return found;
19
+ }
20
+ /**
21
+ * Every leaf in a JSON document, wherever it sits, of every JSON type. Object keys are collected separately.
22
+ *
23
+ * @throws If `document` holds a value JSON cannot express, on the same terms as {@link unpublishedIn} —
24
+ * a caller builds its declaration from this, and a value walked to nothing becomes a permitted set that
25
+ * omits a field.
26
+ */
27
+ function leavesIn(document) {
28
+ return collectLeaves(document, "");
29
+ }
30
+ /**
31
+ * Every object key in a JSON document, wherever it sits.
32
+ *
33
+ * @throws If `document` holds a value JSON cannot express, on the same terms as {@link unpublishedIn}.
34
+ */
35
+ function keysIn(document) {
36
+ return collectKeys(document, "");
37
+ }
38
+ function collectLeaves(value, path) {
39
+ const inside = descend(value, path);
40
+ if (inside === void 0) return [asLeaf(value, path)];
41
+ return inside.flatMap(({ nested, here }) => collectLeaves(nested, here));
42
+ }
43
+ function collectKeys(value, path) {
44
+ const inside = descend(value, path);
45
+ if (inside === void 0) return [];
46
+ return inside.flatMap(({ key, nested, here }) => (key === void 0 ? [] : [key]).concat(collectKeys(nested, here)));
47
+ }
48
+ function walk(value, path, leaves, keys, found) {
49
+ const inside = descend(value, path);
50
+ if (inside === void 0) {
51
+ const leaf = asLeaf(value, path);
52
+ if (!leaves.has(leaf)) found.push(`value ${JSON.stringify(leaf)} at ${where(path)}`);
53
+ return;
54
+ }
55
+ for (const { key, nested, here } of inside) {
56
+ if (key !== void 0 && !keys.has(key)) found.push(`key ${JSON.stringify(key)} at ${here}`);
57
+ walk(nested, here, leaves, keys, found);
58
+ }
59
+ }
60
+ /**
61
+ * The contents of a container, or `undefined` for a leaf — and a refusal for anything else.
62
+ *
63
+ * This is the single place the walk decides what it can see, so the gate, {@link leavesIn} and
64
+ * {@link keysIn} all descend on identical terms. A value is a container only if its prototype is one
65
+ * `JSON.parse` produces; a `Date`, a `Map`, a `Set` or a class instance answers `"object"` to `typeof`
66
+ * and yields nothing to `Object.entries`, and treating that as an empty container is the exemption this
67
+ * module exists to refuse.
68
+ *
69
+ * So **`Object.entries` is what descends, arrays included**. An array walked by `value.map` is walked by
70
+ * position, and a position is not the whole of what an array holds: `rows.cursor = "…"` is an own property
71
+ * on a prototype this walk accepts, and the index walk went straight past it. The rule the module states and
72
+ * the code it runs have to be the same rule, or the exemption comes back through whichever branch still
73
+ * disagrees. An index key stays a position — reported as `[0]`, never as a key a caller must permit — and
74
+ * every other own key is a key.
75
+ */
76
+ function descend(value, path) {
77
+ if (value === null || typeof value !== "object") return void 0;
78
+ const proto = Object.getPrototypeOf(value);
79
+ if (proto !== Object.prototype && proto !== Array.prototype && proto !== null) refuse(value, path);
80
+ const array = Array.isArray(value);
81
+ return Object.entries(value).map(([key, nested]) => array && isIndex(key) ? {
82
+ key: void 0,
83
+ nested,
84
+ here: `${path}[${key}]`
85
+ } : {
86
+ key,
87
+ nested,
88
+ here: path === "" ? key : `${path}.${key}`
89
+ });
90
+ }
91
+ /** Whether an own key of an array is one of its positions — the canonical decimal form `Object.entries` gives. */
92
+ function isIndex(key) {
93
+ return /^(?:0|[1-9]\d*)$/.test(key);
94
+ }
95
+ /** Narrow to a JSON leaf, or refuse the document. A type this walk cannot name is not a type it may skip. */
96
+ function asLeaf(value, path) {
97
+ if (value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
98
+ return refuse(value, path);
99
+ }
100
+ function refuse(value, path) {
101
+ throw new Error(`A ${nameOf(value)} sits at ${where(path)}. JSON cannot express it, so this is a live object rather than what a client receives — round-trip it through JSON first.`);
102
+ }
103
+ /** What to call the thing in the refusal — its class where it has one, so the message names what was found. */
104
+ function nameOf(value) {
105
+ if (value === null || typeof value !== "object") return typeof value;
106
+ const named = value.constructor;
107
+ if (typeof named === "function" && named.name !== "") return named.name;
108
+ return "object";
109
+ }
110
+ function where(path) {
111
+ return path === "" ? "(root)" : path;
112
+ }
113
+ //#endregion
114
+ export { keysIn, leavesIn, unpublishedIn };
@@ -0,0 +1,55 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * The children of one schema, by kind. **Throws for a kind this walk has never been taught** — a
4
+ * walker whose unknown case is silently empty cannot report the thing it exists to report.
5
+ *
6
+ * A `pipe` is stepped through; a **codec** is not. This gate reads the schema tree, so wrapping an
7
+ * object in a guard — `refusesVanishingKey`, and anything else that pipes into a schema — would turn
8
+ * an export it checks into an export it silently skips, and losing coverage as a side effect of adding
9
+ * a guard is the wrong direction. A codec is the §Zod exemption spelled as a type rather than as an
10
+ * accident: `z.codec` builds a `ZodCodec`, so the exemption names codec helpers and nothing else.
11
+ * Measured in #326 — stepping through codecs too reports seven fields whose union sides carry no
12
+ * description, every one of them a `SQLiteDate` or a `sqliteJson`.
13
+ */
14
+ export declare function childSchemas(schema: z.ZodType, path: string): z.ZodType[];
15
+ /**
16
+ * Whether a description sits anywhere in a field's transparent-wrapper chain.
17
+ *
18
+ * `.describe("…").optional()` puts it on the inner type and `.optional().describe("…")` puts it on the
19
+ * wrapper. Both are one described field. Only {@link TRANSPARENT} wrappers are followed — an `array`
20
+ * or a `pipe` describes something other than what it holds.
21
+ */
22
+ export declare function describedInChain(schema: z.ZodType): boolean;
23
+ /** What one walk found: the complaints, and how much it actually looked at. */
24
+ export interface SchemaWalk {
25
+ /** One line per object, enum, union or field with no `.describe()` anywhere that documents it. */
26
+ missing: string[];
27
+ /** Every field of every object reached, so an empty walk is visible as an empty walk. */
28
+ fields: number;
29
+ }
30
+ /**
31
+ * Record any object/enum/union missing a `.describe()` — on the schema itself or on any of its
32
+ * fields — following every container Zod has. Codec-helper primitives are exempt (CLAUDE.md §Zod) and
33
+ * are not objects/enums/unions, so they are skipped.
34
+ *
35
+ * `described` carries a transparent wrapper's own description inward; see {@link TRANSPARENT}.
36
+ */
37
+ export declare function collectMissing(schema: z.ZodType, path: string, walk: SchemaWalk, seen: Set<z.ZodType>, described?: boolean): void;
38
+ /** One schema, walked. The entry point a unit test reaches for. */
39
+ export declare function undescribed(schema: z.ZodType, path?: string): SchemaWalk;
40
+ /** What a package-wide sweep found, including the size of the population it swept. */
41
+ export interface ExportWalk extends SchemaWalk {
42
+ /** Modules the glob handed over. Zero is a broken pattern, not a clean package. */
43
+ modules: number;
44
+ /** Exports that resolved to a Zod schema. */
45
+ schemas: number;
46
+ }
47
+ /**
48
+ * Every exported Zod schema in a package, walked.
49
+ *
50
+ * Takes the result of `import.meta.glob([...], { eager: true })`. The counts come back with the
51
+ * findings **because a sweep that found nothing and a sweep that looked at nothing are the same green
52
+ * run otherwise** — the caller pins all three against literals of its own.
53
+ */
54
+ export declare function undescribedExports(modules: Record<string, Record<string, unknown>>): ExportWalk;
55
+ //# sourceMappingURL=describedness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describedness.d.ts","sourceRoot":"","sources":["../../src/schema/describedness.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAgGxB;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC,OAAO,EAAE,CAsCzE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,OAAO,CAU3D;AAED,+EAA+E;AAC/E,MAAM,WAAW,UAAU;IACzB,kGAAkG;IAClG,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,yFAAyF;IACzF,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,CAAC,CAAC,OAAO,EACjB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EACpB,SAAS,UAAQ,GAChB,IAAI,CAsBN;AAED,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,SAAW,GAAG,UAAU,CAI1E;AAED,sFAAsF;AACtF,MAAM,WAAW,UAAW,SAAQ,UAAU;IAC5C,mFAAmF;IACnF,OAAO,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,UAAU,CAY/F"}