permdock 0.1.0 → 0.3.0

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 (350) hide show
  1. package/README.md +106 -47
  2. package/dist/a2a/index.d.ts +7 -16
  3. package/dist/a2a/index.js +59 -98
  4. package/dist/adapter-context-mlWsVGGg.js +23 -0
  5. package/dist/ai-sdk/index.d.ts +37 -16
  6. package/dist/ai-sdk/index.js +30 -13
  7. package/dist/approvals/index.d.ts +3 -3
  8. package/dist/approvals/index.js +5 -4
  9. package/dist/{approvals-DaxY-Bdg.js → approvals-DbYAuNkG.js} +17 -11
  10. package/dist/approvers-DT4AVyIg.js +52 -0
  11. package/dist/{arazzo-CTeVuXr5.js → arazzo-BAgw9ap6.js} +2 -2
  12. package/dist/{arazzo-aoTkqYsJ.js → arazzo-CKwwqFWz.js} +2 -2
  13. package/dist/authzen/index.d.ts +4 -13
  14. package/dist/authzen/index.js +16 -50
  15. package/dist/better-auth/index.d.ts +20 -3
  16. package/dist/better-auth/index.js +27 -7
  17. package/dist/better-supabase/index.d.ts +223 -0
  18. package/dist/better-supabase/index.js +648 -0
  19. package/dist/bind-C_ob3LKa.d.ts +25 -0
  20. package/dist/bind-CuzGytRf.js +97 -0
  21. package/dist/boundary-BM8a_P6E.js +13 -0
  22. package/dist/boundary-BmHxVH1J.d.ts +15 -0
  23. package/dist/canonical-json-DemiK4Vp.js +26 -0
  24. package/dist/{capability-BDG_nkxt.d.ts → capability-2kYTMWDv.d.ts} +2 -2
  25. package/dist/{capability-B68OFnZx.js → capability-4qPdO9gk.js} +7 -5
  26. package/dist/catalog/index.d.ts +1 -1
  27. package/dist/catalog/index.js +1 -1
  28. package/dist/catalog-CRW5Mx_B.js +2 -0
  29. package/dist/{catalog-H-vFGwWK.js → catalog-DWF5cYqB.js} +4 -4
  30. package/dist/{catalog-B0E6bggc.js → catalog-dFZdWCGN.js} +2 -2
  31. package/dist/{catalog-doc-BSo_Q_-6.js → catalog-doc-DdGm82XT.js} +20 -32
  32. package/dist/claude-agent/index.d.ts +5 -14
  33. package/dist/claude-agent/index.js +4 -10
  34. package/dist/clerk/index.d.ts +12 -3
  35. package/dist/clerk/index.js +26 -5
  36. package/dist/cli/bin.js +1 -1
  37. package/dist/cli/index.d.ts +3 -3
  38. package/dist/cli/index.js +2 -2
  39. package/dist/clients-C7zLFuWT.d.ts +12 -0
  40. package/dist/clients-DjU5ABMy.js +23 -0
  41. package/dist/cloud/index.d.ts +4 -5
  42. package/dist/cloud/index.js +20 -6
  43. package/dist/{cloud-BNQTrmrr.js → cloud-CB_ELYuX.js} +2 -2
  44. package/dist/{cloud-Cuxr6Czw.js → cloud-DWLXO2af.js} +7 -6
  45. package/dist/collect-DClJsheJ.js +83 -0
  46. package/dist/{collect-O-tOtbnk.js → collect-DSTE3ml9.js} +194 -42
  47. package/dist/collect-DSWOk19R.js +2 -0
  48. package/dist/{commands-BMh_Etm2.js → commands-DSxCqG9A.js} +16 -12
  49. package/dist/compile/index.d.ts +3 -0
  50. package/dist/compile/index.js +2 -0
  51. package/dist/{compile-D22iwvuV.js → compile-Ba4blROR.js} +85 -30
  52. package/dist/compile-BkRyBDBw.d.ts +94 -0
  53. package/dist/config-BJiM-xAm.js +157 -0
  54. package/dist/config-Dnszbv-6.js +36 -0
  55. package/dist/config-report-DMvWKUxL.js +44 -0
  56. package/dist/{connection-JvqwHODC.js → connection-CU8MQxRi.js} +1 -1
  57. package/dist/{context-CKEAabd7.js → context-Bcy85rGi.js} +36 -27
  58. package/dist/convex/index.d.ts +9 -4
  59. package/dist/convex/index.js +14 -4
  60. package/dist/create-B1d519XK.d.ts +245 -0
  61. package/dist/create-CMwIl-w2.js +253 -0
  62. package/dist/{credential-B_rkUNlY.js → credential-8P81ff4u.js} +26 -46
  63. package/dist/delegation-D8pUEuce.js +103 -0
  64. package/dist/{describe-Bt1YD5uS.js → describe-B_gVZEVi.js} +10 -15
  65. package/dist/{describe-DernyItf.d.ts → describe-DMYiCjJV.d.ts} +9 -10
  66. package/dist/{diff-x5Il8LVa.js → diff-2VaeChzX.js} +44 -11
  67. package/dist/{diff-BUzf5Poi.js → diff-DBIhz_f2.js} +2 -2
  68. package/dist/{doctor-Bqo6FwUa.js → doctor-BwCAMLx_.js} +2 -2
  69. package/dist/doctor-collect-CHk6XWOA.js +665 -0
  70. package/dist/doctor-igIiM_Hl.js +1194 -0
  71. package/dist/drizzle/index.d.ts +4 -3
  72. package/dist/drizzle/index.js +3 -3
  73. package/dist/elysia/index.d.ts +6 -28
  74. package/dist/elysia/index.js +16 -60
  75. package/dist/{errors-DSMnAVNa.js → errors-CWfoNg9N.js} +8 -4
  76. package/dist/{errors-Iy71s7Oj.js → errors-Cz5zn0mW.js} +17 -71
  77. package/dist/{errors-DbZ1YOnb.d.ts → errors-DPdqI50v.d.ts} +8 -21
  78. package/dist/{errors-m3u9TmDu.js → errors-DRnGZHzF.js} +4 -1
  79. package/dist/evaluation-items-CfCCejQd.js +40 -0
  80. package/dist/{evaluations-DsAU9ppl.js → evaluations-tz6D9A2G.js} +28 -46
  81. package/dist/eve/index.d.ts +6 -15
  82. package/dist/eve/index.js +7 -12
  83. package/dist/expiry-BoBJ8Tvc.js +7 -0
  84. package/dist/express/index.d.ts +6 -29
  85. package/dist/express/index.js +28 -58
  86. package/dist/fastify/index.d.ts +6 -29
  87. package/dist/fastify/index.js +16 -65
  88. package/dist/fields-BMl1RxoX.js +26 -0
  89. package/dist/{files-B_wAGYmt.js → files-DWUN9PzI.js} +5 -1
  90. package/dist/{fixtures-Cvaw0gDG.js → fixtures-ht28Cplr.js} +5 -2
  91. package/dist/{freeze-y1_jQL4v.js → freeze-CrU8nQeX.js} +31 -2
  92. package/dist/{from-snapshot-BMGnhmgv.js → from-snapshot-CTLijvdm.js} +66 -48
  93. package/dist/{grantee-Bv04_Vzf.js → grantee-Cv5Sogfv.js} +88 -7
  94. package/dist/graph-sql-B-dsAT6j.d.ts +29 -0
  95. package/dist/{headers-B5RRv3Xm.js → headers-BZSDieNT.js} +1 -1
  96. package/dist/{headers-C8SHQccD.d.ts → headers-Cf-zWvsO.d.ts} +1 -1
  97. package/dist/helpers-H_KARDVC.js +421 -0
  98. package/dist/hono/index.d.ts +6 -28
  99. package/dist/hono/index.js +11 -43
  100. package/dist/{hosted-BwKQ1BTA.js → hosted-DJQw46hn.js} +6 -5
  101. package/dist/{http-GgVApX1k.js → http-BIhmLfCc.js} +4 -20
  102. package/dist/http-SO7qGttf.js +44 -0
  103. package/dist/ids-DC4V4CFu.js +18 -0
  104. package/dist/index-0nNqHspG.d.ts +6 -0
  105. package/dist/{index-xIxJLwOQ.d.ts → index-BNc7Wer_.d.ts} +75 -7
  106. package/dist/{index-CltcQ4Bf.d.ts → index-C7Tw7MaW.d.ts} +68 -5
  107. package/dist/{index-LF_hS-yn.d.ts → index-C8z4RjQV.d.ts} +1 -1
  108. package/dist/index.d.ts +14 -9
  109. package/dist/index.js +22 -17
  110. package/dist/instance-options-Dhhcnm3y.js +22 -0
  111. package/dist/instance-options-jARdwfPN.d.ts +11 -0
  112. package/dist/{parse-DPfIvFMU.js → json-schema-BsAflUGW.js} +28 -57
  113. package/dist/jwt/index.d.ts +10 -6
  114. package/dist/jwt/index.js +32 -13
  115. package/dist/kernel-_RRHmnMY.js +208 -0
  116. package/dist/kysely/index.d.ts +4 -3
  117. package/dist/kysely/index.js +3 -3
  118. package/dist/live-options-H2eG8dfJ.js +60 -0
  119. package/dist/{load-BZ24CpZP.js → load-DhWEB9P1.js} +16 -10
  120. package/dist/load-DwJUafYN.js +2 -0
  121. package/dist/manifest-iaoBXHKc.js +783 -0
  122. package/dist/manifest-uDS9y5de.d.ts +206 -0
  123. package/dist/{map-DowSO96j.js → map-AcxK9o_D.js} +4 -15
  124. package/dist/{map-claims-B_6I1Rn-.js → map-claims-Z4QZOiFF.js} +13 -4
  125. package/dist/map-error-pgUWNNtG.js +23 -0
  126. package/dist/may-use-DndQ5tQ-.js +77 -0
  127. package/dist/mcp/index.d.ts +54 -22
  128. package/dist/mcp/index.js +218 -178
  129. package/dist/nest/index.d.ts +26 -31
  130. package/dist/nest/index.js +75 -84
  131. package/dist/next/client.d.ts +7 -8
  132. package/dist/next/client.js +11 -9
  133. package/dist/next/index.d.ts +30 -47
  134. package/dist/next/index.js +45 -60
  135. package/dist/next/plugin.d.ts +1 -1
  136. package/dist/next/plugin.js +32 -1
  137. package/dist/node/index.d.ts +9 -28
  138. package/dist/node/index.js +11 -43
  139. package/dist/openai/index.d.ts +6 -15
  140. package/dist/openai/index.js +7 -20
  141. package/dist/openapi/index.d.ts +87 -4
  142. package/dist/openapi/index.js +3 -3
  143. package/dist/{openapi-DcqM8nU7.js → openapi-BqRBvAng.js} +237 -5
  144. package/dist/{openapi-DWD0Uc_4.js → openapi-CqqEbHsL.js} +5 -5
  145. package/dist/{openapi-import-BWRUNNeW.js → openapi-import-cmwetbzw.js} +1 -1
  146. package/dist/{openapi-CwePaF7C.js → openapi-l0xYHkcv.js} +3 -3
  147. package/dist/{openapi-schema-D8j_T9tO.js → openapi-schema--ARjyfQr.js} +2 -2
  148. package/dist/orpc/index.d.ts +15 -28
  149. package/dist/orpc/index.js +74 -117
  150. package/dist/otel/index.d.ts +2 -2
  151. package/dist/parse-BuyjxhZV.js +53 -0
  152. package/dist/parse-local-manifest-BrMozJCo.js +36 -0
  153. package/dist/parse-local-manifest-JLnaBH0S.d.ts +10 -0
  154. package/dist/pdp/index.d.ts +2 -2
  155. package/dist/pdp/index.js +14 -127
  156. package/dist/{permdock-yoZ7EjxX.js → permdock-CbgvLnuo.js} +672 -149
  157. package/dist/{permissions-B8vCg_bI.d.ts → permissions-CDgvKG5L.d.ts} +2 -2
  158. package/dist/{permissions-DC7GROPA.js → permissions-DVoF6dMt.js} +77 -15
  159. package/dist/{permissions-B4apnahQ.d.ts → permissions-DttnqqxC.d.ts} +34 -5
  160. package/dist/{permissions-CofRqesP.js → permissions-RJrovw98.js} +3 -3
  161. package/dist/{pins-CqE1jZuF.js → pins-8ILTftC9.js} +2 -2
  162. package/dist/{policy-Cq2fB8Q5.d.ts → policy-D2W7uv19.d.ts} +2 -2
  163. package/dist/{policy-CInmNGkM.d.ts → policy-IB6yxpC3.d.ts} +351 -42
  164. package/dist/{policy-ANp36PnI.js → policy-xyWg7QdR.js} +173 -22
  165. package/dist/powersync-BylawD_U.js +540 -0
  166. package/dist/powersync-DliZK_-y.js +62 -0
  167. package/dist/powersync-e_AZrKbg.js +2 -0
  168. package/dist/prisma/index.d.ts +3 -2
  169. package/dist/prisma/index.js +45 -20
  170. package/dist/{problem-Cgp9-KZA.js → problem-B43ztKIm.js} +74 -109
  171. package/dist/problem-details-DX075l9V.d.ts +7 -0
  172. package/dist/problem-details-_AMOYz-w.js +144 -0
  173. package/dist/{protected-BuPAycJT.d.ts → protected-BdnIEFkY.d.ts} +5 -4
  174. package/dist/protected-utU-SLuy.js +100 -0
  175. package/dist/protected-xAr24FEC.d.ts +40 -0
  176. package/dist/provider-CSQd7m92.js +52 -0
  177. package/dist/{provider-wTAUda2v.d.ts → provider-DZY281jO.d.ts} +1 -1
  178. package/dist/provider-store-Cfbvo4DE.js +43 -0
  179. package/dist/react/index.d.ts +7 -5
  180. package/dist/react/index.js +5 -4
  181. package/dist/react/provider-client.d.ts +1 -1
  182. package/dist/react/provider-client.js +1 -1
  183. package/dist/react-native/index.d.ts +166 -10
  184. package/dist/react-native/index.js +607 -85
  185. package/dist/{refs-ChLSxbST.js → refs-KYb4ntaz.js} +4 -3
  186. package/dist/{relations-r4soIFZB.js → relations-cjOL01hZ.js} +110 -31
  187. package/dist/replay-BsOyTrdV.js +28 -0
  188. package/dist/replay-CYyiLiwO.d.ts +5 -0
  189. package/dist/resource-ref-CaS9yVPi.js +20 -0
  190. package/dist/revocations-Bhr0aMIC.js +27 -0
  191. package/dist/{rls-BOFU3chG.js → rls-B4ur8nKQ.js} +8 -3
  192. package/dist/rls-DQtdgTHB.js +2521 -0
  193. package/dist/rls-fields-74oZPXWL.js +3582 -0
  194. package/dist/{rls-graph-DxQ39PJj.js → rls-graph-CHwx0V8q.js} +100 -36
  195. package/dist/{rls-import-CXV6LBlS.js → rls-import-BTFVk3jH.js} +7 -6
  196. package/dist/{rls-migrate-DrFPbf8p.js → rls-migrate-CN4TlJTO.js} +6 -5
  197. package/dist/rls-ownership-RuFqaqGz.js +843 -0
  198. package/dist/rls-shared-Cewd_-zI.js +495 -0
  199. package/dist/rls-verify-CVQTHTh5.js +746 -0
  200. package/dist/{row-check-BajTgQZ-.d.ts → row-check-Dt35czLy.d.ts} +12 -15
  201. package/dist/row-conditions-h2HythXQ.js +27 -0
  202. package/dist/rpc-DL9Sqvb1.js +89 -0
  203. package/dist/{run-CJ6UvS3a.js → run-DKDbM4Du.js} +31 -12
  204. package/dist/runtime-CB8gQFvS.js +11 -0
  205. package/dist/{saas-BRrZzJkM.js → saas-DhpJjnBA.js} +17 -7
  206. package/dist/{schema-P8yoma__.js → schema-D3MnDMxa.js} +8 -4
  207. package/dist/scim/index.d.ts +1 -1
  208. package/dist/scim/index.js +1 -1
  209. package/dist/{scim-9NFa0XVZ.js → scim-BFGBBAqR.js} +1 -1
  210. package/dist/{scopes-cKVp_WTw.js → scopes-CVdPrWN-.js} +35 -8
  211. package/dist/server/index.d.ts +22 -11
  212. package/dist/server/index.js +11 -8
  213. package/dist/{credentials-BgRX3WEg.js → server-DlZ28Oz5.js} +1 -1
  214. package/dist/shared-DRu8VFVM.js +123 -0
  215. package/dist/{sink-Cfr9-7YC.d.ts → sink-B1fZzIMf.d.ts} +1 -1
  216. package/dist/skills-Biq5uup3.js +192 -0
  217. package/dist/{skills-C_lpV4Jx.js → skills-Bx-U0irG.js} +10 -4
  218. package/dist/{snapshot-DE8dE_hz.js → snapshot-Enxd0n-s.js} +138 -214
  219. package/dist/snapshot-cache-B-LxUahj.d.ts +45 -0
  220. package/dist/snapshot-cache-D6jLelln.js +44 -0
  221. package/dist/solid/index.d.ts +39 -9
  222. package/dist/solid/index.js +76 -85
  223. package/dist/sources-4p0-4xQm.js +545 -0
  224. package/dist/sources-BdOYLw9j.d.ts +192 -0
  225. package/dist/{sql-Bll1d7y0.js → sql-xdg5f4Fi.js} +6 -1
  226. package/dist/{src-CTNT-PBW.js → src-BDwEZWrZ.js} +149 -11
  227. package/dist/ssf/index.d.ts +3 -2
  228. package/dist/ssf/index.js +3 -29
  229. package/dist/store-DMAWwAJV.js +371 -0
  230. package/dist/{store-Bq90395i.d.ts → store-jOBYpiXC.d.ts} +13 -4
  231. package/dist/store-options-ByhZq1jV.js +716 -0
  232. package/dist/{stores-CkG2HrSg.js → stores-BT2pSCub.js} +10 -63
  233. package/dist/{stores-CvOnu_2T.d.ts → stores-C0IMQrGI.d.ts} +20 -9
  234. package/dist/{stream-BhMfZOwr.d.ts → stream-D1RXubw2.d.ts} +2 -2
  235. package/dist/{stream-Q_xlB6Ko.js → stream-DDpvynSB.js} +16 -2
  236. package/dist/subject-settings-BwBmCdTR.js +128 -0
  237. package/dist/supabase/index.d.ts +133 -6
  238. package/dist/supabase/index.js +4 -3
  239. package/dist/supabase/middleware.d.ts +32 -27
  240. package/dist/supabase/middleware.js +56 -22
  241. package/dist/{supabase-D8UlBA7Z.js → supabase-Boqb9a_Y.js} +3 -3
  242. package/dist/{supabase-DTxGtYdi.js → supabase-C0qESOa-.js} +347 -367
  243. package/dist/supabase-config-BpPXt3x1.js +472 -0
  244. package/dist/supabase-hook-6sYLXg_u.js +2 -0
  245. package/dist/{supabase-hook-D_OqGb_V.js → supabase-hook-CSLQ4zJ3.js} +1037 -705
  246. package/dist/supautils-Cn4R4cJ4.js +91 -0
  247. package/dist/svelte/PermissionBoundary.svelte +37 -0
  248. package/dist/svelte/Protected.svelte +8 -2
  249. package/dist/svelte/index.d.ts +9 -6
  250. package/dist/svelte/index.js +61 -7
  251. package/dist/svelte/runtime.d.ts +4 -3
  252. package/dist/svelte/runtime.js +4 -3
  253. package/dist/svelte/source.d.ts +9 -6
  254. package/dist/svelte/source.js +7 -4
  255. package/dist/terminal/index.d.ts +6 -14
  256. package/dist/terminal/index.js +44 -32
  257. package/dist/testing/index.d.ts +105 -16
  258. package/dist/testing/index.js +504 -40
  259. package/dist/testing/saas/index.d.ts +4 -4
  260. package/dist/testing/saas/index.js +2 -2
  261. package/dist/testing/saas/permissions.d.ts +1 -1
  262. package/dist/testing/saas/permissions.js +1 -1
  263. package/dist/token-CIWxJOCh.js +50 -0
  264. package/dist/trpc/index.d.ts +7 -26
  265. package/dist/trpc/index.js +17 -100
  266. package/dist/types-BnIEz1sU.d.ts +48 -0
  267. package/dist/{types-CxquUByI.d.ts → types-Bvc4oWT6.d.ts} +1 -1
  268. package/dist/{sources-DOpW5Ila.d.ts → types-C97IskBw.d.ts} +86 -127
  269. package/dist/types-CKNSyIf_.d.ts +52 -0
  270. package/dist/types-Cq_H8N_X.d.ts +197 -0
  271. package/dist/{types-D6Z6-rKJ.d.ts → types-DbjRN55U.d.ts} +273 -22
  272. package/dist/{types-BBK-exvJ.d.ts → types-Dnemwd77.d.ts} +7 -1
  273. package/dist/{types-BvBk1wgn.d.ts → types-DxiCGmmd.d.ts} +5 -3
  274. package/dist/{types-B9dmiiab.d.ts → types-QCuYJh4q.d.ts} +1 -1
  275. package/dist/{types-B8w5PFtS.d.ts → types-aqOHTHcp.d.ts} +17 -1
  276. package/dist/unplugin/index.d.ts +1 -1
  277. package/dist/unplugin/index.js +10 -9
  278. package/dist/usage-DorAJiU_.js +2 -0
  279. package/dist/{usage-1ozMubLY.js → usage-GTixvDDU.js} +2 -2
  280. package/dist/{usage-CUnK6Ou9.js → usage-ItS7nLcl.js} +225 -62
  281. package/dist/validation-error-Ba264OaJ.d.ts +26 -0
  282. package/dist/validation-error-CnjZ4t92.js +33 -0
  283. package/dist/{validity-D0uRmJKJ.js → validity-uOp8UpYn.js} +57 -36
  284. package/dist/{verifier-B90agnhl.js → verifier-BxBo6I44.js} +10 -5
  285. package/dist/version-BvacVTZR.js +17 -0
  286. package/dist/views-Soe7bGSC.js +95 -0
  287. package/dist/{vocabulary-Dk0fs-Jk.d.ts → vocabulary-DA8a8zif.d.ts} +1 -1
  288. package/dist/vue/index.d.ts +35 -13
  289. package/dist/vue/index.js +86 -93
  290. package/dist/watch-BwxLTYMZ.js +2 -0
  291. package/dist/watch-DVBJ9cBq.js +128 -0
  292. package/dist/webmcp/index.d.ts +2 -2
  293. package/dist/webmcp/index.js +7 -13
  294. package/package.json +62 -36
  295. package/schemas/approval-request-v1.json +175 -0
  296. package/schemas/catalog-v1.json +29 -1
  297. package/schemas/supabase-claims-v1.json +6 -1
  298. package/schemas/supabase-manifest-v1.json +150 -6
  299. package/skills/permdock/SKILL.md +7 -7
  300. package/skills/permdock-agents/SKILL.md +5 -5
  301. package/skills/permdock-agents/references/runtimes.md +12 -10
  302. package/skills/permdock-approvals/SKILL.md +4 -4
  303. package/skills/permdock-approvals/references/stores-and-resume.md +15 -4
  304. package/skills/permdock-audit/SKILL.md +3 -3
  305. package/skills/permdock-credentials/SKILL.md +4 -4
  306. package/skills/permdock-credentials/references/tokens-keys-links.md +7 -2
  307. package/skills/permdock-data/SKILL.md +4 -4
  308. package/skills/permdock-data/references/queries-and-rls.md +14 -6
  309. package/skills/permdock-data/references/relationships.md +5 -3
  310. package/skills/permdock-tenancy/SKILL.md +9 -6
  311. package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +14 -8
  312. package/skills/permdock-wire/SKILL.md +4 -4
  313. package/skills/permdock-wire/references/adapters.md +42 -30
  314. package/skills/permdock-wire/references/policy-options.md +5 -3
  315. package/dist/approvers-aH0PJkmf.js +0 -20
  316. package/dist/catalog-idsHc0vo.js +0 -2
  317. package/dist/collect-B7_TIfmg.js +0 -49
  318. package/dist/collect-fRPAQIWb.js +0 -2
  319. package/dist/compile-CQbvyIBr.d.ts +0 -30
  320. package/dist/config-BPYmjTOp.js +0 -26
  321. package/dist/context-gtAwAILx.js +0 -6
  322. package/dist/create-BKF3dgFk.d.ts +0 -162
  323. package/dist/create-CSkhDU9T.js +0 -222
  324. package/dist/doctor-BGle8Gqi.js +0 -1314
  325. package/dist/helpers-DnSOrhB9.js +0 -682
  326. package/dist/index-fG6NSXlc.d.ts +0 -9
  327. package/dist/kernel-YOGCWNLf.js +0 -211
  328. package/dist/load-QOOm1z70.js +0 -2
  329. package/dist/manifest-DDQbC6K0.d.ts +0 -118
  330. package/dist/map-error-RJ3ZsUyA.js +0 -16
  331. package/dist/may-use-CnFEjVEp.js +0 -37
  332. package/dist/pg-4GJWDUxG.js +0 -953
  333. package/dist/plugin-4gr7IxFJ.js +0 -65
  334. package/dist/protected-B4K3BKoX.js +0 -138
  335. package/dist/protected-wY7nXhY9.d.ts +0 -23
  336. package/dist/provider-_wx46HpB.js +0 -48
  337. package/dist/rls-CJVja9Ww.js +0 -2119
  338. package/dist/rls-helpers-BxRuif0l.js +0 -1346
  339. package/dist/runtime-DP9ttFh1.js +0 -27
  340. package/dist/skills-Dx3QLnMY.js +0 -110
  341. package/dist/source-DoBBYJi2.js +0 -6
  342. package/dist/sources-DVHM3Mwq.js +0 -284
  343. package/dist/store-C6hFW6ta.js +0 -508
  344. package/dist/subject-settings-xt7V845g.js +0 -82
  345. package/dist/supabase-hook-DW-xP4hU.js +0 -2
  346. package/dist/types-DbWdEfcm.d.ts +0 -87
  347. package/dist/types-bva3i4Gf.d.ts +0 -98
  348. package/dist/types-i4BAOvdb.d.ts +0 -97
  349. package/dist/usage-PyEor6GA.js +0 -2
  350. package/dist/version-CnSh33Fj.js +0 -16
@@ -1,15 +1,13 @@
1
1
  import { n as isReadonlyArray, r as sole, t as compact } from "./compact-y6vfu2_f.js";
2
- import { n as freezeDeep } from "./freeze-y1_jQL4v.js";
3
- import { C as ownGet, S as isForbiddenKey, i as findPermission, o as formerScopes } from "./permissions-DC7GROPA.js";
4
- import { c as isConditionRef, i as resolveConditionRef, s as isConditionDate, u as parentHop } from "./refs-ChLSxbST.js";
5
- import { a as resolveScope, c as scopeChain, d as subjectMemberships, f as tenantOf, l as scopeIdOf, r as findScope, t as activeFor, u as scopeList } from "./scopes-cKVp_WTw.js";
6
- import { C as listPlans, h as resourceRoleCondition, l as matchGrantee, s as flattenGrantee, w as listRoles } from "./grantee-Bv04_Vzf.js";
7
- import { f as tenantsOf, i as isMembershipExpired, o as membershipField, r as inTeam, t as isActive } from "./validity-D0uRmJKJ.js";
8
- import { n as sha256, t as bytesToBase64Url } from "./sha256-BO0swRXL.js";
2
+ import { n as freezeDeep } from "./freeze-CrU8nQeX.js";
3
+ import { E as ownGet, T as isForbiddenKey, i as findPermission } from "./permissions-DVoF6dMt.js";
4
+ import { c as isConditionRef, i as resolveConditionRef, s as isConditionDate, u as parentHop } from "./refs-KYb4ntaz.js";
5
+ import { t as expiredAt } from "./expiry-BoBJ8Tvc.js";
6
+ import { n as sameId } from "./ids-DC4V4CFu.js";
7
+ import { d as scopeList, l as scopeChain, m as tenantOf, o as resolveScope, p as subjectMemberships, r as findScope, t as activeFor, u as scopeIdOf } from "./scopes-CVdPrWN-.js";
8
+ import { E as listRoles, T as listPlans, _ as resourceRoleCondition } from "./grantee-Cv5Sogfv.js";
9
+ import { a as isMembershipExpired, c as membershipField, g as tenantsOf, i as inTeam, t as isActive } from "./validity-uOp8UpYn.js";
9
10
  //#region src/conditions/evaluate.ts
10
- function isExpired(membership, now) {
11
- return membership.expiresAt !== void 0 && membership.expiresAt <= now;
12
- }
13
11
  function resolveRef(ref, subject) {
14
12
  return resolveConditionRef(ref, subject);
15
13
  }
@@ -78,7 +76,7 @@ function matchesParentHop(data, parents, on) {
78
76
  for (const parent of parents ?? []) {
79
77
  const hop = parentHop(parent);
80
78
  if (hop.resource !== void 0 && hop.resource !== on.resource) continue;
81
- if (ownGet(data, hop.field) === on.id) return true;
79
+ if (sameId(ownGet(data, hop.field), on.id)) return true;
82
80
  }
83
81
  return false;
84
82
  }
@@ -92,10 +90,10 @@ function evaluateMemberOf(condition, data, subject, now, scopes) {
92
90
  const scope = condition.scope === "resource" ? void 0 : resolveScope(scopes, condition.scope);
93
91
  if (condition.scope !== "resource" && scope === void 0) return false;
94
92
  for (const membership of memberships) {
95
- if (isExpired(membership, now)) continue;
93
+ if (expiredAt(membership, now)) continue;
96
94
  if (wanted.size > 0 && !membership.roles.some((role) => wanted.has(role))) continue;
97
95
  if (scope !== void 0) {
98
- if (membership.scope !== scope || membership.id !== rowValue) continue;
96
+ if (membership.scope !== scope || !sameId(membership.id, rowValue)) continue;
99
97
  const tenant = tenantOf(membership, scopes);
100
98
  if (active !== void 0 && tenant !== void 0 && tenant !== active) continue;
101
99
  return true;
@@ -105,7 +103,7 @@ function evaluateMemberOf(condition, data, subject, now, scopes) {
105
103
  if (matchesParentHop(data, condition.parents, membership.on)) return true;
106
104
  continue;
107
105
  }
108
- if (membership.on.id === rowValue) return true;
106
+ if (sameId(membership.on.id, rowValue)) return true;
109
107
  if (matchesParentHop(data, condition.parents, membership.on)) return true;
110
108
  }
111
109
  return false;
@@ -146,6 +144,7 @@ function evaluateCondition(condition, data, subject, now = Date.now() / 1e3, sco
146
144
  case "opaque":
147
145
  onOpaque?.();
148
146
  return false;
147
+ case "liveSession": return subject.liveSession === true;
149
148
  default:
150
149
  /* v8 ignore next */
151
150
  return condition;
@@ -168,7 +167,7 @@ const denied = (reason) => freezeDeep({
168
167
  }],
169
168
  alternatives: []
170
169
  });
171
- function isRecord$1(value) {
170
+ function isRecord(value) {
172
171
  return value !== null && typeof value === "object" && !Array.isArray(value);
173
172
  }
174
173
  function asString(value) {
@@ -179,13 +178,13 @@ function parseParameters(raw, components, where) {
179
178
  if (!Array.isArray(raw)) return `${where}: parameters must be an array`;
180
179
  const out = [];
181
180
  for (const item of raw) {
182
- if (!isRecord$1(item)) return `${where}: a parameter is not an object`;
181
+ if (!isRecord(item)) return `${where}: a parameter is not an object`;
183
182
  const reference = asString(item["reference"]);
184
183
  if (reference !== void 0) {
185
184
  const match = /^\$components\.parameters\.(.+)$/u.exec(reference);
186
185
  const target = match?.[1] === void 0 ? void 0 : components[match[1]];
187
- const name = isRecord$1(target) ? asString(target["name"]) : void 0;
188
- if (!isRecord$1(target) || name === void 0 || !("value" in target)) return `${where}: unresolved parameter reference ${reference}`;
186
+ const name = isRecord(target) ? asString(target["name"]) : void 0;
187
+ if (!isRecord(target) || name === void 0 || !("value" in target)) return `${where}: unresolved parameter reference ${reference}`;
189
188
  out.push({
190
189
  name,
191
190
  value: "value" in item ? item["value"] : target["value"]
@@ -202,29 +201,29 @@ function parseParameters(raw, components, where) {
202
201
  return out;
203
202
  }
204
203
  function parseDocument(arazzo) {
205
- if (!isRecord$1(arazzo)) return "Arazzo document is not an object";
204
+ if (!isRecord(arazzo)) return "Arazzo document is not an object";
206
205
  const version = arazzo["arazzo"];
207
206
  if (typeof version !== "string" || !VERSION.test(version)) return "arazzo must be a 1.0.x or 1.1.x version";
208
- if (!isRecord$1(arazzo["info"])) return "info is required";
207
+ if (!isRecord(arazzo["info"])) return "info is required";
209
208
  const rawSources = arazzo["sourceDescriptions"];
210
209
  if (!Array.isArray(rawSources) || rawSources.length === 0) return "sourceDescriptions needs at least one entry";
211
210
  const sources = [];
212
211
  for (const source of rawSources) {
213
- const name = isRecord$1(source) ? asString(source["name"]) : void 0;
214
- if (!isRecord$1(source) || name === void 0 || asString(source["url"]) === void 0) return "a sourceDescription needs a name and a url";
212
+ const name = isRecord(source) ? asString(source["name"]) : void 0;
213
+ if (!isRecord(source) || name === void 0 || asString(source["url"]) === void 0) return "a sourceDescription needs a name and a url";
215
214
  if (sources.some((item) => item.name === name)) return `duplicate sourceDescription ${name}`;
216
215
  sources.push({
217
216
  name,
218
217
  type: asString(source["type"]) ?? "openapi"
219
218
  });
220
219
  }
221
- const components = isRecord$1(arazzo["components"]) && isRecord$1(arazzo["components"]["parameters"]) ? arazzo["components"]["parameters"] : {};
220
+ const components = isRecord(arazzo["components"]) && isRecord(arazzo["components"]["parameters"]) ? arazzo["components"]["parameters"] : {};
222
221
  const rawWorkflows = arazzo["workflows"];
223
222
  if (!Array.isArray(rawWorkflows) || rawWorkflows.length === 0) return "workflows needs at least one entry";
224
223
  const workflows = [];
225
224
  for (const item of rawWorkflows) {
226
- const workflowId = isRecord$1(item) ? asString(item["workflowId"]) : void 0;
227
- if (!isRecord$1(item) || workflowId === void 0) return "a workflow needs a workflowId";
225
+ const workflowId = isRecord(item) ? asString(item["workflowId"]) : void 0;
226
+ if (!isRecord(item) || workflowId === void 0) return "a workflow needs a workflowId";
228
227
  if (workflows.some((workflow) => workflow.workflowId === workflowId)) return `duplicate workflowId ${workflowId}`;
229
228
  const parameters = parseParameters(item["parameters"], components, workflowId);
230
229
  if (typeof parameters === "string") return parameters;
@@ -232,8 +231,8 @@ function parseDocument(arazzo) {
232
231
  if (!Array.isArray(rawSteps) || rawSteps.length === 0) return `${workflowId}: steps needs at least one entry`;
233
232
  const steps = [];
234
233
  for (const step of rawSteps) {
235
- const stepId = isRecord$1(step) ? asString(step["stepId"]) : void 0;
236
- if (!isRecord$1(step) || stepId === void 0) return `${workflowId}: a step needs a stepId`;
234
+ const stepId = isRecord(step) ? asString(step["stepId"]) : void 0;
235
+ if (!isRecord(step) || stepId === void 0) return `${workflowId}: a step needs a stepId`;
237
236
  if (steps.some((other) => other.stepId === stepId)) return `${workflowId}: duplicate stepId ${stepId}`;
238
237
  const targets = STEP_TARGETS.filter((field) => asString(step[field]) !== void 0);
239
238
  if (targets.length !== 1 && !(targets.length === 2 && targets.includes("operationId") && targets.includes("channelPath"))) return `${workflowId}.${stepId}: a step needs exactly one of operationId, operationPath or workflowId`;
@@ -266,7 +265,7 @@ function readPointer(doc, pointer) {
266
265
  if (!pointer.startsWith("#/")) return;
267
266
  let current = doc;
268
267
  for (const raw of pointer.slice(2).split("/")) {
269
- if (!isRecord$1(current)) return;
268
+ if (!isRecord(current)) return;
270
269
  let token;
271
270
  try {
272
271
  token = unescapePointer(decodeURIComponent(raw));
@@ -279,19 +278,19 @@ function readPointer(doc, pointer) {
279
278
  return current;
280
279
  }
281
280
  function findOperation(openapi, operationId) {
282
- if (!isRecord$1(openapi) || !isRecord$1(openapi["paths"])) return;
281
+ if (!isRecord(openapi) || !isRecord(openapi["paths"])) return;
283
282
  for (const pathItem of Object.values(openapi["paths"])) {
284
- if (!isRecord$1(pathItem)) continue;
285
- for (const [method, operation] of Object.entries(pathItem)) if (!method.startsWith("x-") && isRecord$1(operation) && operation["operationId"] === operationId) return operation;
283
+ if (!isRecord(pathItem)) continue;
284
+ for (const [method, operation] of Object.entries(pathItem)) if (!method.startsWith("x-") && isRecord(operation) && operation["operationId"] === operationId) return operation;
286
285
  }
287
286
  }
288
287
  /** One description, or a map of descriptions keyed by source `name`. */
289
288
  function descriptionFor(openapi, name) {
290
- if (isRecord$1(openapi) && !("openapi" in openapi) && !("paths" in openapi) && isRecord$1(openapi[name])) return openapi[name];
289
+ if (isRecord(openapi) && !("openapi" in openapi) && !("paths" in openapi) && isRecord(openapi[name])) return openapi[name];
291
290
  return openapi;
292
291
  }
293
292
  function permissionKeysOf(node) {
294
- if (!isRecord$1(node)) return [];
293
+ if (!isRecord(node)) return [];
295
294
  const raw = node["x-permdock-permissions"];
296
295
  if (!Array.isArray(raw)) return [];
297
296
  return raw.filter((item) => typeof item === "string");
@@ -309,7 +308,7 @@ function valueOf(value, inputs) {
309
308
  };
310
309
  let current = inputs;
311
310
  for (const part of match[1].split(".")) {
312
- if (!isRecord$1(current) || !Object.hasOwn(current, part)) return { known: false };
311
+ if (!isRecord(current) || !Object.hasOwn(current, part)) return { known: false };
313
312
  current = current[part];
314
313
  }
315
314
  return {
@@ -407,7 +406,7 @@ function locate(doc, openapi, step) {
407
406
  reason: "unsupported",
408
407
  detail: "AsyncAPI steps are not evaluated"
409
408
  };
410
- if (hit === void 0 || hit.source.type === "arazzo" || !isRecord$1(hit.node)) return {
409
+ if (hit === void 0 || hit.source.type === "arazzo" || !isRecord(hit.node)) return {
411
410
  reason: "undocumented",
412
411
  detail: "operation not found"
413
412
  };
@@ -535,180 +534,52 @@ function simulateArazzo(input, tree, decide) {
535
534
  });
536
535
  }
537
536
  function isArazzoSimulateInput(value) {
538
- return isRecord$1(value) && "arazzo" in value;
537
+ return isRecord(value) && "arazzo" in value;
539
538
  }
540
539
  //#endregion
541
- //#region src/core/delegation.ts
542
- /** The permission's scope and any scope it was renamed from: tokens issued before a rename keep working. */
543
- function scopeNames(permission) {
544
- return [permission.scope, ...formerScopes(permission)];
545
- }
546
- /**
547
- * Whether a delegated caller may use a permission its principal holds, through
548
- * OAuth `scopes`, RFC 9396 `authorizationDetails` or GNAP `access`.
549
- * `undefined` means covered; otherwise the denial reason `decide` would add.
550
- */
551
- function coveredByDelegation(permission, delegation, resourceId, hasActor = false) {
552
- const unscoped = hasActor ? "no-delegation" : void 0;
553
- if (delegation === void 0) return unscoped;
554
- const hasScopes = delegation.scopes !== void 0;
555
- const hasDetails = delegation.authorizationDetails !== void 0;
556
- const hasAccess = delegation.access !== void 0;
557
- if (!hasScopes && !hasDetails && !hasAccess) return unscoped;
558
- const emptyScopes = hasScopes && (delegation.scopes?.length ?? 0) === 0;
559
- const emptyAccess = hasAccess && (delegation.access?.length ?? 0) === 0;
560
- if (emptyScopes && !hasDetails && !hasAccess) return "no-delegation";
561
- if (emptyAccess && !hasScopes && !hasDetails) return "no-delegation";
562
- if (emptyScopes && emptyAccess && !hasDetails) return "no-delegation";
563
- const scopes = scopeNames(permission);
564
- const scopeOk = delegation.scopes?.some((scope) => scopes.includes(scope)) ?? false;
565
- const detailOk = delegation.authorizationDetails?.some((detail) => {
566
- if (detail.type !== permission.resource) return false;
567
- const identifier = detail["identifier"];
568
- if (identifier !== void 0 && (typeof identifier !== "string" || identifier !== resourceId)) return false;
569
- const actions = detail.actions;
570
- if (actions === void 0) return true;
571
- return Array.isArray(actions) && actions.includes(permission.action);
572
- }) ?? false;
573
- const accessOk = accessCovers(permission, delegation.access, resourceId);
574
- if (scopeOk || detailOk || accessOk) return;
575
- return "not-delegated";
576
- }
577
- function accessCovers(permission, access, resourceId) {
578
- if (access === void 0) return false;
579
- return access.some((entry) => {
580
- if (typeof entry === "string") return scopeNames(permission).includes(entry);
581
- if (entry === null || typeof entry !== "object") return false;
582
- const type = entry["type"];
583
- if (typeof type !== "string" || !typeMatches(type, permission.resource)) return false;
584
- const actions = entry["actions"];
585
- if (actions !== void 0 && (!Array.isArray(actions) || !actions.includes(permission.action))) return false;
586
- const identifier = entry["identifier"];
587
- if (identifier !== void 0 && (typeof identifier !== "string" || identifier !== resourceId)) return false;
588
- return true;
589
- });
590
- }
591
- function typeMatches(type, resource) {
592
- if (type === resource) return true;
593
- return type.endsWith(`/${resource}`);
594
- }
595
- function resourceIdOf(data) {
596
- if (data === null || typeof data !== "object" || !("id" in data)) return;
597
- const id = data.id;
598
- return typeof id === "string" || typeof id === "number" ? String(id) : void 0;
540
+ //#region src/core/row-pair.ts
541
+ function isRowPair(value) {
542
+ return value !== null && typeof value === "object" && "current" in value && "next" in value;
599
543
  }
600
544
  /**
601
- * Whether the subject's principal is a `from` of the delegation: every item
602
- * matches, with roles checked against the roles the principal holds here
603
- * (`matchGrantee` leaves role holding to the caller) and nothing that needs a
604
- * row.
545
+ * The row a `where` reads and the row a `check` reads. An instance check
546
+ * takes a `{ current, next }` pair or one row for both; a collection check
547
+ * has no current row, only the input it creates.
605
548
  */
606
- function handsOver(delegation, subject, heldRoles, now) {
607
- const items = flattenGrantee(delegation.from);
608
- if (items.length === 0 || subject.principal === null) return false;
609
- return items.every((item) => {
610
- if (item.kind === "role") return heldRoles.has(item.role);
611
- if (item.kind === "relation") return false;
612
- const match = matchGrantee(item, subject, now, void 0);
613
- return match.matched && match.where === void 0;
614
- });
615
- }
616
- /**
617
- * The permission keys the policy's delegations let `subject.actor` use for
618
- * `subject.principal` right now: the union over every active delegation whose
619
- * `to` matches the actor and whose `from` the principal holds. `undefined`
620
- * when none applies, so the call falls back to the token delegation alone.
621
- * An actor with `readOnly: true` gets only each delegation's read-only keys.
622
- * Attenuation only: a key here still needs a matching allow and no deny.
623
- */
624
- function delegatedPermissions(delegations, subject, heldRoles, now) {
625
- const actor = subject.actor;
626
- if (actor === void 0 || delegations === void 0) return;
627
- let keys;
628
- for (const delegation of delegations) {
629
- if (delegation.to.kind !== actor.kind || delegation.to.id !== void 0 && delegation.to.id !== actor.id || !isActive(delegation.validity, now) || !handsOver(delegation, subject, heldRoles, now)) continue;
630
- keys ??= /* @__PURE__ */ new Set();
631
- for (const key of actor.readOnly === true ? delegation.readOnly : delegation.permissions) keys.add(key);
632
- }
633
- return keys;
634
- }
635
- //#endregion
636
- //#region src/core/canonical-json.ts
637
- function isRecord(value) {
638
- return value !== null && typeof value === "object" && !Array.isArray(value);
639
- }
640
- /**
641
- * JSON with sorted keys and `undefined` members dropped, so equal values hash
642
- * equally. Dates become ISO strings, bigints `"<n>n"`, and a repeated object
643
- * on the current path `"[Circular]"`, so any validated row serialises.
644
- */
645
- function canonicalJson(value, path = /* @__PURE__ */ new Set()) {
646
- if (typeof value === "bigint") return JSON.stringify(`${value}n`);
647
- if (value instanceof Date) return JSON.stringify(Number.isNaN(value.getTime()) ? null : value.toISOString());
648
- if (value !== null && typeof value === "object") {
649
- if (path.has(value)) return "\"[Circular]\"";
650
- path.add(value);
651
- try {
652
- if (Array.isArray(value)) return `[${value.map((item) => canonicalJson(item === void 0 ? null : item, path)).join(",")}]`;
653
- if (isRecord(value)) return `{${Object.keys(value).toSorted().filter((key) => value[key] !== void 0).map((key) => `${JSON.stringify(key)}:${canonicalJson(value[key], path)}`).join(",")}}`;
654
- } finally {
655
- path.delete(value);
656
- }
657
- }
658
- return JSON.stringify(value) ?? "null";
659
- }
660
- //#endregion
661
- //#region src/core/token.ts
662
- /**
663
- * Only stable identity goes into the token, so refreshing a session (new
664
- * roles, assurance or claims) does not orphan an outstanding approval.
665
- */
666
- function principalIdentity(principal) {
667
- if (principal === null) return null;
549
+ function rowValues(permission, data) {
550
+ if (permission.kind === "collection") return {
551
+ current: void 0,
552
+ next: data
553
+ };
554
+ if (permission.kind === "instance" && isRowPair(data)) return {
555
+ current: data.current,
556
+ next: data.next
557
+ };
668
558
  return {
669
- id: principal.id,
670
- tenant: principal.tenant ?? null,
671
- issuer: principal.issuer ?? null
559
+ current: data,
560
+ next: data
672
561
  };
673
562
  }
674
- /** A row's `version` field as token input; `null` when it is missing or not a scalar. */
675
- function versionOf(row, field) {
676
- if (row === null || typeof row !== "object" || !Object.hasOwn(row, field)) return null;
677
- const value = row[field];
678
- if (value instanceof Date) return Number.isNaN(value.getTime()) ? null : value.toISOString();
679
- return typeof value === "string" || typeof value === "number" || typeof value === "bigint" || typeof value === "boolean" ? String(value) : null;
680
- }
681
- /** The digest that binds a token to the call's data when no row id does. */
682
- function payloadDigest(data) {
683
- return bytesToBase64Url(sha256(canonicalJson(data)));
684
- }
685
- /**
686
- * `version` is set only for an approval that goes stale on a resource
687
- * change; without it the payload, and so every other token, is unchanged.
688
- * `payload` is set when `resourceId` is `*` (a collection action or a row
689
- * without an id), so an approval covers the arguments it was given and no
690
- * others.
691
- */
692
- function decisionToken(input) {
693
- const payload = JSON.stringify({
694
- key: input.key,
695
- resourceId: input.resourceId,
696
- principal: principalIdentity(input.principal),
697
- actor: input.actor === void 0 ? null : {
698
- id: input.actor.id,
699
- kind: input.actor.kind
700
- },
701
- fingerprint: input.fingerprint,
702
- ...input.version === void 0 ? {} : { version: input.version },
703
- ...input.payload === void 0 ? {} : { payload: input.payload }
704
- });
705
- return `pd1.${bytesToBase64Url(sha256(payload))}`;
563
+ /** The row's id under `field` as a string, or `*` when the row has no string or number there. */
564
+ function rowIdOf(row, field = "id") {
565
+ if (row === null || typeof row !== "object" || !Object.hasOwn(row, field)) return "*";
566
+ const id = Reflect.get(row, field);
567
+ return typeof id === "string" || typeof id === "number" ? String(id) : "*";
706
568
  }
707
569
  //#endregion
708
570
  //#region src/conditions/bind.ts
709
571
  function isPrimitive(value) {
710
572
  return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
711
573
  }
574
+ const ALWAYS$1 = {
575
+ op: "eq",
576
+ field: "_",
577
+ value: true
578
+ };
579
+ const NEVER = {
580
+ op: "or",
581
+ conditions: []
582
+ };
712
583
  function bindValue(value, subject, only) {
713
584
  if (isConditionRef(value) && only !== void 0 && !only(value.ref)) return value;
714
585
  if (isConditionRef(value)) {
@@ -723,8 +594,9 @@ function bindArg(arg, subject, only) {
723
594
  return arg !== null && typeof arg === "object" && "field" in arg && !isConditionRef(arg) ? arg : bindValue(arg, subject, only);
724
595
  }
725
596
  /**
726
- * Replaces every `principal.*` / `context.*` ref with the subject's value, so
727
- * a `where()` result compiles the same without the subject. A ref the subject
597
+ * Replaces every `principal.*` / `context.*` ref with the subject's value, and
598
+ * a `liveSession` node with a constant, so a `where()` result compiles the
599
+ * same without the subject. A ref the subject
728
600
  * does not hold binds to `null` (or `[]` in a list), which never matches, as
729
601
  * in `evaluateCondition`. With `only`, refs it rejects stay refs.
730
602
  */
@@ -764,6 +636,7 @@ function bindConditionRefs(condition, subject, only) {
764
636
  args: condition.args.map((arg) => bindArg(arg, subject, only)),
765
637
  twin: bindConditionRefs(condition.twin, subject, only)
766
638
  };
639
+ case "liveSession": return subject.liveSession === true ? ALWAYS$1 : NEVER;
767
640
  case "isNull":
768
641
  case "memberOf":
769
642
  case "related":
@@ -793,7 +666,7 @@ function namedFilters(membership, scope) {
793
666
  if (findScope(scope.scopes, membership.scope ?? "") === void 0 || !inTeam(membership, scope.scopes, scope.team) || !activeFor(membership, scope.scopes, scope.tenant) || membership.scope === void 0) return null;
794
667
  const filters = [];
795
668
  for (const name of scopeChain(scope.scopes, membership.scope).toReversed()) {
796
- const key = findScope(scope.scopes, name)?.key;
669
+ const key = scope.fieldOf?.(name) ?? findScope(scope.scopes, name)?.key;
797
670
  if (key !== void 0 && scope.partitioned(name, key)) filters.push(eq(key, scopeIdOf(membership, name)));
798
671
  }
799
672
  return filters;
@@ -913,7 +786,44 @@ function whereFromGrants(grants, scope) {
913
786
  return freezeDeep(result);
914
787
  }
915
788
  //#endregion
789
+ //#region src/core/snapshot-sign.ts
790
+ async function signSnapshot(snapshot, signer, audience) {
791
+ const payload = { snapshot };
792
+ if (snapshot.subject.principal !== null) payload["sub"] = snapshot.subject.principal.id;
793
+ return await signer.sign(payload, compact({
794
+ typ: "permdock-snapshot+jwt",
795
+ audience,
796
+ expiresAt: snapshot.expiresAt
797
+ }));
798
+ }
799
+ //#endregion
916
800
  //#region src/core/snapshot.ts
801
+ function plainPermission(leaf) {
802
+ return {
803
+ key: leaf.key,
804
+ scope: leaf.scope,
805
+ resource: leaf.resource,
806
+ action: leaf.action,
807
+ meta: leaf.meta,
808
+ kind: leaf.kind
809
+ };
810
+ }
811
+ function plainRole(leaf) {
812
+ return compact({
813
+ key: leaf.key,
814
+ on: leaf.on,
815
+ assignable: leaf.assignable,
816
+ meta: leaf.meta,
817
+ kind: leaf.kind
818
+ });
819
+ }
820
+ function plainPlan(leaf) {
821
+ return {
822
+ key: leaf.key,
823
+ meta: leaf.meta,
824
+ kind: leaf.kind
825
+ };
826
+ }
917
827
  function snapshotGrant(grant, membership) {
918
828
  const scope = grant.scope === "global" ? void 0 : typeof grant.scope === "string" ? grant.scope : { resource: grant.scope.resource };
919
829
  const entry = compact({
@@ -932,9 +842,17 @@ function snapshotGrant(grant, membership) {
932
842
  });
933
843
  return freezeDeep(entry);
934
844
  }
935
- /** Claim refs: the snapshot principal does not carry `claims`, so they are bound to the subject's values. */
845
+ const CARRIED = /* @__PURE__ */ new Set([
846
+ "id",
847
+ "roles",
848
+ "plans",
849
+ "tenant",
850
+ "memberships"
851
+ ]);
852
+ /** Principal refs the snapshot principal does not carry (`claims`, `teamIds`, …) are bound to the subject's values. */
936
853
  function isClaimRef(ref) {
937
- return ref.startsWith("principal.claim.") || ref.startsWith("principal.claims.");
854
+ const [root, head] = ref.split(".", 2);
855
+ return root === "principal" && !CARRIED.has(String(head));
938
856
  }
939
857
  function bindClaims(grant, subject) {
940
858
  if (grant.where === void 0 && grant.check === void 0) return grant;
@@ -964,13 +882,27 @@ function buildSnapshot(input) {
964
882
  const include = input.include;
965
883
  const included = (permission) => include === void 0 || include.length === 0 || include.some((prefix) => permission.key === prefix || permission.key.startsWith(`${prefix}.`) || permission.resource === prefix);
966
884
  const grants = input.grants.filter((item) => included(item.grant.permission)).map((item) => bindClaims(snapshotGrant(item.grant, item.membership), input.subject));
885
+ const ids = {};
886
+ for (const item of input.grants) {
887
+ const name = item.grant.permission.resource;
888
+ const field = input.idOf?.(name);
889
+ if (field !== void 0 && field !== "id" && included(item.grant.permission)) ids[name] = field;
890
+ }
967
891
  const assignableFor = input.assignable;
968
892
  const assignable = assignableFor === void 0 ? [] : tenants.map((tenant) => {
969
893
  const entry = assignableFor(tenant);
970
- return {
894
+ const permissions = entry.permissions.filter(included).map(plainPermission);
895
+ if (entry.levels === void 0) return {
971
896
  ...entry,
972
- permissions: entry.permissions.filter(included)
897
+ permissions
973
898
  };
899
+ const keys = new Set(permissions.map((leaf) => leaf.key));
900
+ const levels = Object.fromEntries(Object.entries(entry.levels).filter(([key]) => keys.has(key)));
901
+ return compact({
902
+ ...entry,
903
+ permissions,
904
+ levels: Object.keys(levels).length === 0 ? void 0 : levels
905
+ });
974
906
  });
975
907
  return freezeDeep(compact({
976
908
  v: 1,
@@ -994,24 +926,16 @@ function buildSnapshot(input) {
994
926
  simulated: input.simulated === true ? true : void 0,
995
927
  expiresAt: input.subject.expiresAt,
996
928
  scopes: input.scopes,
929
+ ids: Object.keys(ids).length === 0 ? void 0 : ids,
997
930
  assignable: assignable.length > 0 ? assignable : void 0,
998
931
  delegated: input.delegated === void 0 ? void 0 : [...input.delegated].toSorted(),
999
932
  notEntitled: notEntitledOf((input.notEntitled ?? []).filter((item) => included(item.grant.permission))),
1000
933
  vocabulary: input.vocabulary === void 0 ? void 0 : compact({
1001
- roles: listRoles(input.vocabulary.roles).length === 0 ? void 0 : Object.fromEntries(listRoles(input.vocabulary.roles).map((leaf) => [leaf.key, leaf])),
1002
- plans: listPlans(input.vocabulary.plans).length === 0 ? void 0 : Object.fromEntries(listPlans(input.vocabulary.plans).map((leaf) => [leaf.key, leaf]))
934
+ roles: listRoles(input.vocabulary.roles).length === 0 ? void 0 : Object.fromEntries(listRoles(input.vocabulary.roles).map((leaf) => [leaf.key, plainRole(leaf)])),
935
+ plans: listPlans(input.vocabulary.plans).length === 0 ? void 0 : Object.fromEntries(listPlans(input.vocabulary.plans).map((leaf) => [leaf.key, plainPlan(leaf)]))
1003
936
  })
1004
937
  }));
1005
938
  }
1006
- async function signSnapshot(snapshot, signer, audience) {
1007
- const payload = { snapshot };
1008
- if (snapshot.subject.principal !== null) payload["sub"] = snapshot.subject.principal.id;
1009
- return await signer.sign(payload, compact({
1010
- typ: "permdock-snapshot+jwt",
1011
- audience,
1012
- expiresAt: snapshot.expiresAt
1013
- }));
1014
- }
1015
939
  /**
1016
940
  * The token delegation as the client sees it. An actor with no token
1017
941
  * delegation gets an empty `scopes` list so the client ceiling agrees with
@@ -1048,4 +972,4 @@ function parseSnapshot(json) {
1048
972
  return freezeDeep(value);
1049
973
  }
1050
974
  //#endregion
1051
- export { whereFromGrants as a, versionOf as c, delegatedPermissions as d, resourceIdOf as f, evaluateCondition as g, simulateArazzo as h, snapshotGrant as i, canonicalJson as l, isArazzoSimulateInput as m, parseSnapshot as n, decisionToken as o, arazzoFindings as p, signSnapshot as r, payloadDigest as s, buildSnapshot as t, coveredByDelegation as u };
975
+ export { whereFromGrants as a, rowIdOf as c, isArazzoSimulateInput as d, simulateArazzo as f, signSnapshot as i, rowValues as l, parseSnapshot as n, bindConditionRefs as o, evaluateCondition as p, snapshotGrant as r, isRowPair as s, buildSnapshot as t, arazzoFindings as u };
@@ -0,0 +1,45 @@
1
+ import { Tt as Snapshot } from "./policy-IB6yxpC3.js";
2
+ //#region src/core/snapshot-cache.d.ts
3
+ type CacheLifeForOptions = {
4
+ /** Lower bound in seconds. Next.js includes a private entry in per-link prefetches from 30. */
5
+ readonly min?: number;
6
+ /** Upper bound in seconds. Next.js keeps a per-session App Shell entry from 300. */
7
+ readonly max?: number;
8
+ /** Seconds since the epoch; defaults to the snapshot's `issuedAt`, then the clock. */
9
+ readonly now?: number;
10
+ };
11
+ /**
12
+ * `{ stale }` in seconds: `max` when the value never expires, otherwise the seconds left, clamped
13
+ * to `[min, max]`. A value with less than `min` seconds left gets its real remainder, so Next.js
14
+ * leaves it out of prefetches and an HTTP cache does not serve it past `expiresAt`.
15
+ */
16
+ declare function cacheLifeFor(value: {
17
+ readonly expiresAt?: number | null;
18
+ readonly issuedAt?: number;
19
+ } | null, options?: CacheLifeForOptions): {
20
+ readonly stale: number;
21
+ };
22
+ /**
23
+ * The `cacheTag` for one subject's cached snapshots: `permdock:<sub>`, or `permdock:anon`
24
+ * without a subject. Tag the private cache with it and pass it to `updateTag` or
25
+ * `revalidateTag` on every write that changes the subject's snapshot.
26
+ */
27
+ declare function snapshotTag(sub?: string | null): string;
28
+ type SnapshotHeadersOptions = CacheLifeForOptions & {
29
+ /** Sent in `Cache-Tag` after `snapshotTag(sub)`, such as the app's own organisation tag. */
30
+ readonly tags?: readonly string[];
31
+ };
32
+ type SnapshotHeaders = {
33
+ readonly "Cache-Control": string;
34
+ readonly Vary: string;
35
+ readonly ETag: string;
36
+ readonly "Cache-Tag": string;
37
+ };
38
+ /**
39
+ * Response headers for a loader or route that returns `snapshot`: `Cache-Control: private` with
40
+ * `max-age` from `cacheLifeFor`, `Vary: Authorization, Cookie`, an `ETag` over everything but
41
+ * `issuedAt`, and `Cache-Tag` with `snapshotTag(sub)` and `tags`.
42
+ */
43
+ declare function snapshotHeaders(snapshot: Snapshot, options?: SnapshotHeadersOptions): SnapshotHeaders;
44
+ //#endregion
45
+ export { snapshotHeaders as a, cacheLifeFor as i, SnapshotHeaders as n, snapshotTag as o, SnapshotHeadersOptions as r, CacheLifeForOptions as t };
@@ -0,0 +1,44 @@
1
+ import { n as payloadDigest } from "./token-CIWxJOCh.js";
2
+ //#region src/core/snapshot-cache.ts
3
+ /**
4
+ * `{ stale }` in seconds: `max` when the value never expires, otherwise the seconds left, clamped
5
+ * to `[min, max]`. A value with less than `min` seconds left gets its real remainder, so Next.js
6
+ * leaves it out of prefetches and an HTTP cache does not serve it past `expiresAt`.
7
+ */
8
+ function cacheLifeFor(value, options = {}) {
9
+ const min = options.min ?? 30;
10
+ const max = Math.max(options.max ?? 300, min);
11
+ const expiresAt = value?.expiresAt;
12
+ if (expiresAt === void 0 || expiresAt === null) return { stale: max };
13
+ const issuedAt = value?.issuedAt !== void 0 && value.issuedAt > 0 ? value.issuedAt : void 0;
14
+ const now = options.now ?? issuedAt ?? Math.floor(Date.now() / 1e3);
15
+ const remaining = Math.floor(expiresAt - now);
16
+ if (remaining < min) return { stale: Math.max(0, remaining) };
17
+ return { stale: Math.min(max, remaining) };
18
+ }
19
+ /**
20
+ * The `cacheTag` for one subject's cached snapshots: `permdock:<sub>`, or `permdock:anon`
21
+ * without a subject. Tag the private cache with it and pass it to `updateTag` or
22
+ * `revalidateTag` on every write that changes the subject's snapshot.
23
+ */
24
+ function snapshotTag(sub) {
25
+ return `permdock:${sub === void 0 || sub === null || sub === "" ? "anon" : sub}`;
26
+ }
27
+ /**
28
+ * Response headers for a loader or route that returns `snapshot`: `Cache-Control: private` with
29
+ * `max-age` from `cacheLifeFor`, `Vary: Authorization, Cookie`, an `ETag` over everything but
30
+ * `issuedAt`, and `Cache-Tag` with `snapshotTag(sub)` and `tags`.
31
+ */
32
+ function snapshotHeaders(snapshot, options = {}) {
33
+ const content = {};
34
+ for (const [key, value] of Object.entries(snapshot)) if (key !== "issuedAt") content[key] = value;
35
+ const { tags, ...life } = options;
36
+ return {
37
+ "Cache-Control": `private, max-age=${cacheLifeFor(snapshot, life).stale}`,
38
+ Vary: "Authorization, Cookie",
39
+ ETag: `"${payloadDigest(content)}"`,
40
+ "Cache-Tag": [snapshotTag(snapshot.subject.principal?.id), ...tags ?? []].join(",")
41
+ };
42
+ }
43
+ //#endregion
44
+ export { snapshotHeaders as n, snapshotTag as r, cacheLifeFor as t };