permdock 0.3.0 → 0.4.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 (323) hide show
  1. package/dist/a2a/index.d.ts +7 -5
  2. package/dist/a2a/index.js +14 -21
  3. package/dist/ai-sdk/index.d.ts +18 -6
  4. package/dist/ai-sdk/index.js +8 -5
  5. package/dist/app-data-CV8pqqMi.js +59 -0
  6. package/dist/approvals/index.d.ts +2 -2
  7. package/dist/approvals/index.js +3 -3
  8. package/dist/{approvals-DbYAuNkG.js → approvals-DZL76lKW.js} +35 -19
  9. package/dist/{approvers-DT4AVyIg.js → approvers-CqPOLD-o.js} +1 -1
  10. package/dist/{arazzo-BAgw9ap6.js → arazzo-C4BcskbX.js} +6 -5
  11. package/dist/{arazzo-CKwwqFWz.js → arazzo-CD8d0WLb.js} +2 -2
  12. package/dist/authzen/index.d.ts +3 -3
  13. package/dist/authzen/index.js +161 -23
  14. package/dist/better-auth/index.d.ts +2 -2
  15. package/dist/better-auth/index.js +6 -19
  16. package/dist/better-supabase/index.d.ts +112 -87
  17. package/dist/better-supabase/index.js +257 -156
  18. package/dist/{bind-C_ob3LKa.d.ts → bind-BzqG8SMb.d.ts} +16 -5
  19. package/dist/{bind-CuzGytRf.js → bind-kk-uyCwH.js} +14 -6
  20. package/dist/build-instance-DIIV9DbC.js +51 -0
  21. package/dist/{canonical-json-DemiK4Vp.js → canonical-json-CFKyFOke.js} +1 -3
  22. package/dist/{capability-2kYTMWDv.d.ts → capability-CksyCWDH.d.ts} +2 -2
  23. package/dist/{capability-4qPdO9gk.js → capability-txATtKV4.js} +3 -2
  24. package/dist/catalog/index.d.ts +1 -1
  25. package/dist/catalog/index.js +1 -1
  26. package/dist/catalog-6yWAX6Ps.js +2 -0
  27. package/dist/{catalog-dFZdWCGN.js → catalog-WHG4kBq7.js} +2 -2
  28. package/dist/{catalog-doc-DdGm82XT.js → catalog-doc-DWtg0gGR.js} +17 -10
  29. package/dist/{catalog-DWF5cYqB.js → catalog-tZUyOfOv.js} +4 -4
  30. package/dist/claude-agent/index.d.ts +4 -4
  31. package/dist/claude-agent/index.js +4 -5
  32. package/dist/clerk/index.d.ts +3 -3
  33. package/dist/clerk/index.js +8 -33
  34. package/dist/cli/bin.js +1 -1
  35. package/dist/cli/index.d.ts +3 -3
  36. package/dist/cli/index.js +3 -3
  37. package/dist/cloud/index.d.ts +4 -4
  38. package/dist/cloud/index.js +9 -15
  39. package/dist/{cloud-CB_ELYuX.js → cloud-C7bSDgX4.js} +2 -2
  40. package/dist/{cloud-DWLXO2af.js → cloud-PeBN3IEn.js} +5 -5
  41. package/dist/{collect-DSTE3ml9.js → collect-2SrB7lfk.js} +6 -8
  42. package/dist/collect-Bw2Jdq1q.js +2 -0
  43. package/dist/{collect-DClJsheJ.js → collect-CQx4hX4N.js} +3 -3
  44. package/dist/{commands-DSxCqG9A.js → commands-Cpip4ULx.js} +13 -13
  45. package/dist/{compact-y6vfu2_f.js → compact-CAf557ZB.js} +11 -1
  46. package/dist/compile/index.d.ts +1 -1
  47. package/dist/compile/index.js +1 -1
  48. package/dist/{compile-Ba4blROR.js → compile-CcEu2ZQ1.js} +6 -5
  49. package/dist/{compile-BkRyBDBw.d.ts → compile-CtTP7eur.d.ts} +2 -2
  50. package/dist/{config-BJiM-xAm.js → config-BIjREpyE.js} +4 -4
  51. package/dist/{config-Dnszbv-6.js → config-DLt6BvV7.js} +2 -2
  52. package/dist/{config-report-DMvWKUxL.js → config-report--Xb9APJS.js} +5 -6
  53. package/dist/{connection-CU8MQxRi.js → connection-DUsczpB5.js} +3 -2
  54. package/dist/constants-DcJABbLW.js +20 -0
  55. package/dist/{context-Bcy85rGi.js → context-DieZVJXu.js} +16 -5
  56. package/dist/convex/index.d.ts +4 -4
  57. package/dist/convex/index.js +14 -16
  58. package/dist/create-BBO24vj6.js +324 -0
  59. package/dist/{credential-8P81ff4u.js → credential-kue0qpbm.js} +4 -4
  60. package/dist/deciding-columns-Sq12mEA6.js +123 -0
  61. package/dist/delegation-input-FTxMK3ji.js +19 -0
  62. package/dist/denied-text-DfRk15uw.d.ts +19 -0
  63. package/dist/{describe-DMYiCjJV.d.ts → describe-C3ldA9os.d.ts} +11 -2
  64. package/dist/{describe-B_gVZEVi.js → describe-Cgkp7eP0.js} +5 -4
  65. package/dist/{diff-DBIhz_f2.js → diff-Cnghh_Ip.js} +2 -2
  66. package/dist/{diff-2VaeChzX.js → diff-rpqoe7Ag.js} +9 -9
  67. package/dist/{doctor-BwCAMLx_.js → doctor-CuVJvhV_.js} +2 -2
  68. package/dist/doctor-owlv6ddh.js +2166 -0
  69. package/dist/drizzle/index.d.ts +2 -2
  70. package/dist/drizzle/index.js +6 -14
  71. package/dist/elysia/index.d.ts +4 -4
  72. package/dist/elysia/index.js +7 -7
  73. package/dist/{errors-DPdqI50v.d.ts → errors-OD_4c__H.d.ts} +2 -2
  74. package/dist/{errors-Cz5zn0mW.js → errors-drnfxYtm.js} +3 -3
  75. package/dist/{evaluations-tz6D9A2G.js → evaluations-C9YJsv3H.js} +45 -7
  76. package/dist/eve/index.d.ts +5 -5
  77. package/dist/eve/index.js +5 -5
  78. package/dist/express/index.d.ts +4 -4
  79. package/dist/express/index.js +8 -7
  80. package/dist/fastify/index.d.ts +15 -5
  81. package/dist/fastify/index.js +9 -29
  82. package/dist/fields-fwfXN01n.js +1016 -0
  83. package/dist/{files-DWUN9PzI.js → files-D_JIzUrP.js} +12 -3
  84. package/dist/{fixtures-ht28Cplr.js → fixtures-h2eG2OZV.js} +5 -6
  85. package/dist/{from-snapshot-CTLijvdm.js → from-snapshot-7REQZe0H.js} +32 -22
  86. package/dist/{generate-CH7ThJ14.js → generate-CNU1pIOo.js} +1 -3
  87. package/dist/grantee-CXY-0C87.js +254 -0
  88. package/dist/grantee-conditions-MQs5NIuX.js +270 -0
  89. package/dist/grantee-match-fxYp9Nmt.js +141 -0
  90. package/dist/{helpers-H_KARDVC.js → helpers-C9YmyBIa.js} +7 -6
  91. package/dist/hono/index.d.ts +4 -4
  92. package/dist/hono/index.js +8 -8
  93. package/dist/hosted-CBHgkzDl.js +655 -0
  94. package/dist/{http-SO7qGttf.js → http-BBoKefeS.js} +35 -2
  95. package/dist/{http-BIhmLfCc.js → http-BEbdMZ05.js} +2 -24
  96. package/dist/{rls-import-BTFVk3jH.js → import-BFIlhetD.js} +86 -80
  97. package/dist/{openapi-import-cmwetbzw.js → import-UHk1N7vH.js} +6 -7
  98. package/dist/{index-C8z4RjQV.d.ts → index-BwMe94Xq.d.ts} +1 -1
  99. package/dist/{index-0nNqHspG.d.ts → index-DgM7w96K.d.ts} +2 -2
  100. package/dist/{index-C7Tw7MaW.d.ts → index-Dz7didpC.d.ts} +3 -3
  101. package/dist/{index-BNc7Wer_.d.ts → index-UdVQgq48.d.ts} +105 -38
  102. package/dist/index.d.ts +15 -13
  103. package/dist/index.js +22 -22
  104. package/dist/{instance-options-jARdwfPN.d.ts → instance-options-plkrsAog.d.ts} +1 -1
  105. package/dist/{json-schema-BsAflUGW.js → json-schema-DBkdUuCO.js} +1 -3
  106. package/dist/jwt/index.d.ts +4 -4
  107. package/dist/jwt/index.js +13 -13
  108. package/dist/{kernel-_RRHmnMY.js → kernel-CB3LrIJM.js} +81 -32
  109. package/dist/kysely/index.d.ts +2 -2
  110. package/dist/kysely/index.js +6 -14
  111. package/dist/{live-options-H2eG8dfJ.js → live-options-BaAFCIiu.js} +16 -3
  112. package/dist/load-B_shHrmd.js +2 -0
  113. package/dist/{load-DhWEB9P1.js → load-C3_oTHyO.js} +11 -3
  114. package/dist/{manifest-iaoBXHKc.js → manifest-BngWKryL.js} +5 -18
  115. package/dist/{map-claims-Z4QZOiFF.js → map-claims-AVlBaJoa.js} +7 -16
  116. package/dist/{map-error-pgUWNNtG.js → map-error-BE27PYkE.js} +5 -5
  117. package/dist/{markers-B0hYLvMD.js → markers-CiwAOZtO.js} +6 -2
  118. package/dist/{may-use-DndQ5tQ-.js → may-use-BOn_dR_w.js} +4 -3
  119. package/dist/mcp/index.d.ts +26 -9
  120. package/dist/mcp/index.js +456 -446
  121. package/dist/{rls-migrate-CN4TlJTO.js → migrate-BwlB5-Wk.js} +75 -15
  122. package/dist/nest/index.d.ts +4 -4
  123. package/dist/nest/index.js +11 -12
  124. package/dist/next/index.d.ts +31 -8
  125. package/dist/next/index.js +29 -33
  126. package/dist/next/plugin.d.ts +1 -1
  127. package/dist/next/plugin.js +1 -1
  128. package/dist/node/index.d.ts +4 -4
  129. package/dist/node/index.js +4 -4
  130. package/dist/ocsf-uYFXGVw2.js +115 -0
  131. package/dist/openai/index.d.ts +5 -5
  132. package/dist/openai/index.js +4 -4
  133. package/dist/openapi/index.d.ts +3 -3
  134. package/dist/openapi/index.js +1 -1
  135. package/dist/{openapi-CqqEbHsL.js → openapi-BJdBmYDG.js} +19 -23
  136. package/dist/{openapi-BqRBvAng.js → openapi-DBzHQbov.js} +2 -5
  137. package/dist/{openapi-l0xYHkcv.js → openapi-DcQ1Kg40.js} +3 -3
  138. package/dist/orpc/index.d.ts +5 -5
  139. package/dist/orpc/index.js +9 -11
  140. package/dist/otel/index.d.ts +2 -2
  141. package/dist/otel/index.js +26 -23
  142. package/dist/output-files-CgIsvdSa.js +140 -0
  143. package/dist/{rls-ownership-RuFqaqGz.js → ownership-BgnbOJFT.js} +387 -379
  144. package/dist/{package-root-zGkxO3oN.js → package-root-DtNnpmUd.js} +3 -2
  145. package/dist/{parse-BuyjxhZV.js → parse-CVFQHk6c.js} +3 -3
  146. package/dist/{parse-local-manifest-BrMozJCo.js → parse-local-manifest-C-q02Pal.js} +2 -4
  147. package/dist/{parse-local-manifest-JLnaBH0S.d.ts → parse-local-manifest-DvYUR0QL.d.ts} +1 -1
  148. package/dist/pdp/index.d.ts +2 -2
  149. package/dist/pdp/index.js +8 -9
  150. package/dist/{permdock-CbgvLnuo.js → permdock-L26udHSk.js} +1387 -1220
  151. package/dist/{rls-fields-74oZPXWL.js → permission-keys-B26jeyUv.js} +1289 -2066
  152. package/dist/permission-registry-BsblpB-z.js +385 -0
  153. package/dist/{permissions-DttnqqxC.d.ts → permission-types-Dg39z9Kv.d.ts} +59 -31
  154. package/dist/{permissions-RJrovw98.js → permissions-CCJ6lmxB.js} +3 -3
  155. package/dist/{permissions-CDgvKG5L.d.ts → permissions-COH-KRgT.d.ts} +2 -2
  156. package/dist/{policy-IB6yxpC3.d.ts → policy-types-sp9P1iIV.d.ts} +661 -582
  157. package/dist/{policy-D2W7uv19.d.ts → policy-ur0BBK_e.d.ts} +2 -2
  158. package/dist/{powersync-DliZK_-y.js → powersync-BFSbSElQ.js} +2 -2
  159. package/dist/powersync-DCDgZgfZ.js +2 -0
  160. package/dist/{powersync-BylawD_U.js → powersync-cZe4kzhL.js} +26 -27
  161. package/dist/prisma/index.d.ts +1 -1
  162. package/dist/prisma/index.js +6 -12
  163. package/dist/{problem-B43ztKIm.js → problem-CnWraVhC.js} +8 -7
  164. package/dist/{problem-details-_AMOYz-w.js → problem-details-DECUnXAn.js} +2 -2
  165. package/dist/{problem-details-DX075l9V.d.ts → problem-details-rIIo8B2C.d.ts} +1 -1
  166. package/dist/{protected-BdnIEFkY.d.ts → protected-B3_P7xuw.d.ts} +9 -6
  167. package/dist/{protected-utU-SLuy.js → protected-BN7BUdY1.js} +20 -8
  168. package/dist/{provider-CSQd7m92.js → provider-Bi-0HNL3.js} +23 -10
  169. package/dist/{provider-DZY281jO.d.ts → provider-kwHC9CZD.d.ts} +1 -1
  170. package/dist/{provider-store-Cfbvo4DE.js → provider-store-Ctt-81Ni.js} +6 -3
  171. package/dist/react/index.d.ts +7 -7
  172. package/dist/react/index.js +5 -5
  173. package/dist/react/provider-client.d.ts +1 -1
  174. package/dist/react/provider-client.js +1 -1
  175. package/dist/react-native/index.d.ts +20 -11
  176. package/dist/react-native/index.js +33 -17
  177. package/dist/{refs-KYb4ntaz.js → refs-f3imMjNW.js} +1 -1
  178. package/dist/relation-walk-BXnlLtg2.js +186 -0
  179. package/dist/relations-CvmSpG67.js +163 -0
  180. package/dist/{replay-CYyiLiwO.d.ts → replay-COpmZUfx.d.ts} +1 -1
  181. package/dist/request-context-BVM7aWNs.js +71 -0
  182. package/dist/request-context-C2_1lchh.d.ts +5 -0
  183. package/dist/resource-relations-D1Un3pcz.js +243 -0
  184. package/dist/retire-BFcxL6un.js +240 -0
  185. package/dist/{rls-B4ur8nKQ.js → rls-55DQTuf5.js} +14 -2
  186. package/dist/{rls-DQtdgTHB.js → rls-BEktUaqg.js} +884 -484
  187. package/dist/{policy-xyWg7QdR.js → role-builder-B4GbKM-i.js} +235 -541
  188. package/dist/{rpc-DL9Sqvb1.js → rpc-nYC3cR_u.js} +15 -5
  189. package/dist/{run-DKDbM4Du.js → run-DMcNW_8T.js} +3 -3
  190. package/dist/{runtime-CB8gQFvS.js → runtime-D_tMXnsq.js} +1 -1
  191. package/dist/{saas-DhpJjnBA.js → saas-DtaA4JuW.js} +9 -8
  192. package/dist/{openapi-schema--ARjyfQr.js → schema-Bol6gqXA.js} +3 -5
  193. package/dist/{schema-D3MnDMxa.js → schema-DjQBcAP9.js} +4 -2
  194. package/dist/scim/index.d.ts +1 -1
  195. package/dist/scim/index.js +1 -1
  196. package/dist/{scim-BFGBBAqR.js → scim-vFR1O5oG.js} +6 -12
  197. package/dist/{scopes-CVdPrWN-.js → scopes-tvpa34ep.js} +10 -2
  198. package/dist/server/index.d.ts +18 -8
  199. package/dist/server/index.js +8 -8
  200. package/dist/{server-DlZ28Oz5.js → server-ZYEHtNHS.js} +4 -4
  201. package/dist/{create-B1d519XK.d.ts → server-types-DdqBwZN_.d.ts} +69 -33
  202. package/dist/shared-1uhI-e-b.js +294 -0
  203. package/dist/{shared-DRu8VFVM.js → shared-JhMeOsDF.js} +1 -1
  204. package/dist/{sink-Bd9PSyfq.js → sink-BTtmfPnE.js} +1 -1
  205. package/dist/{sink-B1fZzIMf.d.ts → sink-CPN4zLfs.d.ts} +1 -1
  206. package/dist/{skills-Biq5uup3.js → skills-BZdRQkxs.js} +4 -3
  207. package/dist/{skills-Bx-U0irG.js → skills-Dle4ZoLF.js} +2 -2
  208. package/dist/{snapshot-Enxd0n-s.js → snapshot-Dc9CHPME.js} +116 -13
  209. package/dist/{snapshot-cache-D6jLelln.js → snapshot-cache-Cod40D-X.js} +1 -1
  210. package/dist/{snapshot-cache-B-LxUahj.d.ts → snapshot-cache-J5T7t_vD.d.ts} +1 -1
  211. package/dist/solid/index.d.ts +22 -22
  212. package/dist/solid/index.js +40 -10
  213. package/dist/{sources-4p0-4xQm.js → sources-B1-b-R0t.js} +25 -26
  214. package/dist/{sources-BdOYLw9j.d.ts → sources-Dljy06zL.d.ts} +6 -2
  215. package/dist/{sql-xdg5f4Fi.js → sql-t8teWOfo.js} +19 -3
  216. package/dist/{src-BDwEZWrZ.js → src-Bb7no-hS.js} +194 -123
  217. package/dist/ssf/index.d.ts +3 -3
  218. package/dist/ssf/index.js +58 -61
  219. package/dist/store-9KO4BlkB.d.ts +147 -0
  220. package/dist/{store-DMAWwAJV.js → store-ILkLUj_o.js} +4 -4
  221. package/dist/{store-options-ByhZq1jV.js → store-options-CbUHDoSe.js} +16 -7
  222. package/dist/{stores-BT2pSCub.js → stores-BHXdSbw9.js} +7 -3
  223. package/dist/stores-Cxz_80g-.d.ts +31 -0
  224. package/dist/{stream-DDpvynSB.js → stream-BMui98KK.js} +2 -1
  225. package/dist/{stream-D1RXubw2.d.ts → stream-Dwsg6WwE.d.ts} +2 -2
  226. package/dist/{subject-settings-BwBmCdTR.js → subject-settings-CkEwrw3W.js} +23 -5
  227. package/dist/supabase/index.d.ts +4 -4
  228. package/dist/supabase/index.js +3 -3
  229. package/dist/supabase/middleware.d.ts +11 -5
  230. package/dist/supabase/middleware.js +10 -7
  231. package/dist/{supabase-C0qESOa-.js → supabase-C1TWlnYt.js} +36 -52
  232. package/dist/{supabase-Boqb9a_Y.js → supabase-Dbqr141s.js} +2 -2
  233. package/dist/supabase-hook-BULg7Ut_.js +2 -0
  234. package/dist/{supabase-hook-CSLQ4zJ3.js → supabase-hook-Cva3ikXz.js} +731 -782
  235. package/dist/{supautils-Cn4R4cJ4.js → supautils-B6HYL9eL.js} +2 -2
  236. package/dist/svelte/Protected.svelte +9 -2
  237. package/dist/svelte/index.d.ts +6 -6
  238. package/dist/svelte/index.js +25 -11
  239. package/dist/svelte/runtime.d.ts +10 -3
  240. package/dist/svelte/runtime.js +4 -3
  241. package/dist/svelte/source.d.ts +6 -6
  242. package/dist/svelte/source.js +4 -4
  243. package/dist/{validity-uOp8UpYn.js → tenancy-DshjqY0n.js} +3 -39
  244. package/dist/terminal/index.d.ts +5 -5
  245. package/dist/terminal/index.js +18 -34
  246. package/dist/testing/index.d.ts +89 -77
  247. package/dist/testing/index.js +1276 -1262
  248. package/dist/testing/saas/index.d.ts +4 -4
  249. package/dist/testing/saas/index.js +2 -2
  250. package/dist/testing/saas/permissions.d.ts +1 -1
  251. package/dist/testing/saas/permissions.js +1 -1
  252. package/dist/thenable-QSmvt-vZ.js +65 -0
  253. package/dist/{token-CIWxJOCh.js → token-Bx9qy30p.js} +1 -1
  254. package/dist/tool-refusal-CQ7OEia9.js +41 -0
  255. package/dist/trpc/index.d.ts +5 -5
  256. package/dist/trpc/index.js +7 -8
  257. package/dist/{types-DbjRN55U.d.ts → types-7rJVLWe5.d.ts} +82 -4
  258. package/dist/{types-aqOHTHcp.d.ts → types-Br9IXUBG.d.ts} +1 -1
  259. package/dist/types-ByUo56un.d.ts +88 -0
  260. package/dist/{types-Cq_H8N_X.d.ts → types-C0dee0Qf.d.ts} +2 -2
  261. package/dist/{types-DxiCGmmd.d.ts → types-CIlTojhq.d.ts} +2 -2
  262. package/dist/{types-QCuYJh4q.d.ts → types-CUcFZfpU.d.ts} +1 -1
  263. package/dist/{types-C97IskBw.d.ts → types-CqrjB9o6.d.ts} +1 -1
  264. package/dist/{types-BnIEz1sU.d.ts → types-DHrmBJLH.d.ts} +24 -6
  265. package/dist/{types-Dnemwd77.d.ts → types-DpWfQdSh.d.ts} +5 -1
  266. package/dist/{types-Bvc4oWT6.d.ts → types-DvupZE0w.d.ts} +1 -1
  267. package/dist/unplugin/index.d.ts +1 -1
  268. package/dist/unplugin/index.js +1 -1
  269. package/dist/{usage-GTixvDDU.js → usage-4G6t643F.js} +2 -2
  270. package/dist/{usage-ItS7nLcl.js → usage-CG9nOYZw.js} +7 -7
  271. package/dist/usage-iFLJ0-rr.js +2 -0
  272. package/dist/{validation-error-Ba264OaJ.d.ts → validation-error-BSSw0l_8.d.ts} +1 -1
  273. package/dist/{validation-error-CnjZ4t92.js → validation-error-ZfUHbKvf.js} +1 -1
  274. package/dist/validity-dVrUEPJt.js +62 -0
  275. package/dist/{verifier-BxBo6I44.js → verifier-DMr_Zmb_.js} +51 -15
  276. package/dist/{rls-verify-CVQTHTh5.js → verify-BztUB3GX.js} +668 -239
  277. package/dist/{version-BvacVTZR.js → version-BEogC-rB.js} +1 -1
  278. package/dist/{views-Soe7bGSC.js → views-CJsrBS1f.js} +23 -1
  279. package/dist/{vocabulary-DA8a8zif.d.ts → vocabulary-hhEFLFoL.d.ts} +15 -6
  280. package/dist/vue/index.d.ts +24 -19
  281. package/dist/vue/index.js +24 -8
  282. package/dist/watch-C8TpsAl4.js +2 -0
  283. package/dist/{watch-DVBJ9cBq.js → watch-zeucB7eF.js} +6 -6
  284. package/dist/webmcp/index.d.ts +2 -2
  285. package/dist/webmcp/index.js +13 -37
  286. package/dist/wrap-Cr93qqdP.d.ts +14 -0
  287. package/dist/wrap-DWsU_5Bd.js +26 -0
  288. package/package.json +8 -8
  289. package/schemas/catalog-v1.json +6 -0
  290. package/skills/permdock-credentials/SKILL.md +1 -1
  291. package/skills/permdock-credentials/references/tokens-keys-links.md +7 -2
  292. package/skills/permdock-data/references/queries-and-rls.md +4 -0
  293. package/skills/permdock-tenancy/references/ownership-and-custom-roles.md +1 -0
  294. package/skills/permdock-wire/SKILL.md +2 -2
  295. package/skills/permdock-wire/references/adapters.md +9 -1
  296. package/skills/permdock-wire/references/policy-options.md +10 -1
  297. package/dist/catalog-CRW5Mx_B.js +0 -2
  298. package/dist/collect-DSWOk19R.js +0 -2
  299. package/dist/create-CMwIl-w2.js +0 -253
  300. package/dist/delegation-D8pUEuce.js +0 -103
  301. package/dist/doctor-collect-CHk6XWOA.js +0 -665
  302. package/dist/doctor-igIiM_Hl.js +0 -1194
  303. package/dist/evaluation-items-CfCCejQd.js +0 -40
  304. package/dist/fields-BMl1RxoX.js +0 -26
  305. package/dist/grantee-Cv5Sogfv.js +0 -602
  306. package/dist/hosted-DJQw46hn.js +0 -266
  307. package/dist/instance-options-Dhhcnm3y.js +0 -22
  308. package/dist/load-DwJUafYN.js +0 -2
  309. package/dist/map-AcxK9o_D.js +0 -147
  310. package/dist/permissions-DVoF6dMt.js +0 -662
  311. package/dist/powersync-e_AZrKbg.js +0 -2
  312. package/dist/protected-xAr24FEC.d.ts +0 -40
  313. package/dist/relations-cjOL01hZ.js +0 -505
  314. package/dist/rls-graph-CHwx0V8q.js +0 -435
  315. package/dist/rls-shared-Cewd_-zI.js +0 -495
  316. package/dist/store-jOBYpiXC.d.ts +0 -36
  317. package/dist/stores-C0IMQrGI.d.ts +0 -52
  318. package/dist/supabase-config-BpPXt3x1.js +0 -472
  319. package/dist/supabase-hook-6sYLXg_u.js +0 -2
  320. package/dist/thenable-okc2xDsj.js +0 -10
  321. package/dist/types-CKNSyIf_.d.ts +0 -52
  322. package/dist/usage-DorAJiU_.js +0 -2
  323. package/dist/watch-BwxLTYMZ.js +0 -2
@@ -1,5 +1,5 @@
1
- import { existsSync, globSync, readdirSync, realpathSync, statSync } from "node:fs";
2
- import { basename, extname, join, relative, resolve } from "node:path";
1
+ import { existsSync, globSync, mkdirSync, readFileSync, readdirSync, realpathSync, statSync, writeFileSync } from "node:fs";
2
+ import { basename, dirname, extname, join, relative, resolve } from "node:path";
3
3
  //#region src/cli/files.ts
4
4
  const SOURCE_EXT = /* @__PURE__ */ new Set([
5
5
  ".ts",
@@ -121,5 +121,14 @@ function defaultSrcPath() {
121
121
  function doctorSrcPath(config) {
122
122
  return config.doctor?.srcPath ?? config.collect?.srcPath ?? defaultSrcPath();
123
123
  }
124
+ /** The parsed JSON at `path`; throws when it is unreadable or not JSON. */
125
+ function readJsonFile(path) {
126
+ return JSON.parse(readFileSync(path, "utf8"));
127
+ }
128
+ /** Writes `text` to `path`, creating its directory first. */
129
+ function writeFileEnsuringDir(path, text) {
130
+ mkdirSync(dirname(path), { recursive: true });
131
+ writeFileSync(path, text);
132
+ }
124
133
  //#endregion
125
- export { sqlFiles as a, rel as i, doctorSrcPath as n, listSourceFiles as r, defaultSrcPath as t };
134
+ export { rel as a, readJsonFile as i, doctorSrcPath as n, sqlFiles as o, listSourceFiles as r, writeFileEnsuringDir as s, defaultSrcPath as t };
@@ -1,10 +1,9 @@
1
- import { a as loadModule, o as pickNamed } from "./load-DhWEB9P1.js";
2
- import { existsSync, readFileSync } from "node:fs";
1
+ import { r as isRecord } from "./compact-CAf557ZB.js";
2
+ import { i as readJsonFile } from "./files-D_JIzUrP.js";
3
+ import { a as loadModule, s as pickNamed } from "./load-C3_oTHyO.js";
4
+ import { existsSync } from "node:fs";
3
5
  import { resolve } from "node:path";
4
6
  //#region src/cli/fixtures.ts
5
- function isRecord(value) {
6
- return value !== null && typeof value === "object" && !Array.isArray(value);
7
- }
8
7
  function asFixtures(value) {
9
8
  const list = Array.isArray(value) ? value : isRecord(value) && Array.isArray(value["fixtures"]) ? value["fixtures"] : void 0;
10
9
  if (list === void 0) throw new Error("PermDock CLI: fixtures must be an array or { fixtures }");
@@ -31,7 +30,7 @@ async function loadFixtures(cwd, path) {
31
30
  const abs = resolve(cwd, path);
32
31
  if (!existsSync(abs)) throw new Error(`PermDock CLI: fixtures not found: ${path}`);
33
32
  if (abs.endsWith(".json")) {
34
- const parsed = JSON.parse(readFileSync(abs, "utf8"));
33
+ const parsed = readJsonFile(abs);
35
34
  return {
36
35
  fixtures: asFixtures(parsed),
37
36
  customRoles: asCustomRoles(parsed)
@@ -1,17 +1,17 @@
1
- import { t as compact } from "./compact-y6vfu2_f.js";
1
+ import { t as compact } from "./compact-CAf557ZB.js";
2
2
  import { n as freezeDeep } from "./freeze-CrU8nQeX.js";
3
- import { _ as listPermissions } from "./permissions-DVoF6dMt.js";
4
- import { a as deniedMessage, i as approvalMessage, n as PermDockDeniedError, t as PermDockApprovalRequiredError } from "./errors-Cz5zn0mW.js";
3
+ import { a as deniedMessage, i as approvalMessage, n as PermDockDeniedError, t as PermDockApprovalRequiredError } from "./errors-drnfxYtm.js";
5
4
  import { n as sameId } from "./ids-DC4V4CFu.js";
6
- import { a as normalizeMemberships, d as scopeList, m as tenantOf, o as resolveScope, t as activeFor } from "./scopes-CVdPrWN-.js";
7
- import { a as whereFromGrants, c as rowIdOf, d as isArazzoSimulateInput, f as simulateArazzo, i as signSnapshot, l as rowValues, p as evaluateCondition } from "./snapshot-Enxd0n-s.js";
8
- import { D as synthesiseRole, E as listRoles, S as findRole, d as matchGrantee } from "./grantee-Cv5Sogfv.js";
9
- import { n as pickVisible, t as grantCoversField } from "./fields-BMl1RxoX.js";
10
- import { a as isMembershipExpired, i as inTeam, l as nestedAppliesWithoutRow, m as rowInScope, p as resolveActiveTenant, t as isActive, u as nowSeconds } from "./validity-uOp8UpYn.js";
5
+ import { a as normalizeMemberships, d as scopeList, m as tenantOf, o as resolveScope, t as activeFor } from "./scopes-tvpa34ep.js";
6
+ import { _ as evaluateCondition, a as whereFromGrants, f as rowIdOf, g as simulateArazzo, h as isArazzoSimulateInput, i as signSnapshot, p as rowValues, s as coveredByDelegation } from "./snapshot-Dc9CHPME.js";
7
+ import { c as listPermissions } from "./permission-registry-BsblpB-z.js";
8
+ import { b as synthesiseRole, m as findRole, v as listRoles } from "./grantee-CXY-0C87.js";
9
+ import { i as pickVisible, r as grantCoversField, t as isActive } from "./validity-dVrUEPJt.js";
10
+ import { c as nowSeconds, d as resolveActiveTenant, f as rowInScope, n as inTeam, r as isMembershipExpired, s as nestedAppliesWithoutRow } from "./tenancy-DshjqY0n.js";
11
11
  import { t as requiresApproval } from "./approval-required-TzNB9oQA.js";
12
- import { t as coveredByDelegation } from "./delegation-D8pUEuce.js";
12
+ import { n as matchGrantee } from "./grantee-match-fxYp9Nmt.js";
13
13
  import { t as resourceIdOf } from "./resource-ref-CaS9yVPi.js";
14
- import { n as payloadDigest, t as decisionToken } from "./token-CIWxJOCh.js";
14
+ import { n as payloadDigest, t as decisionToken } from "./token-Bx9qy30p.js";
15
15
  //#region src/core/snapshot-evaluate.ts
16
16
  function coveredByInclude(snapshot, permission) {
17
17
  const include = snapshot.include;
@@ -126,6 +126,8 @@ function matchedOf(grant) {
126
126
  return compact({
127
127
  role: grant.role,
128
128
  permission: grant.permission,
129
+ name: grant.name,
130
+ meta: grant.meta,
129
131
  to: grant.to,
130
132
  where: grant.where,
131
133
  check: grant.check,
@@ -141,15 +143,22 @@ function evaluateSnapshot(snapshot, subject, permission, data, team, options, ou
141
143
  denies: [],
142
144
  skipped: []
143
145
  } : void 0;
144
- const done = (decision) => outcomeOnly ? decision : freezeDeep(tracer === void 0 ? decision : {
145
- ...decision,
146
- trace: {
147
- evaluated: tracer.evaluated,
148
- allows: tracer.allows,
149
- denies: tracer.denies,
150
- skipped: tracer.skipped
151
- }
152
- });
146
+ const done = (raw) => {
147
+ if (outcomeOnly) return raw;
148
+ const decision = raw.outcome === "denied" ? {
149
+ ...raw,
150
+ permission: permission.key
151
+ } : raw;
152
+ return freezeDeep(tracer === void 0 ? decision : {
153
+ ...decision,
154
+ trace: {
155
+ evaluated: tracer.evaluated,
156
+ allows: tracer.allows,
157
+ denies: tracer.denies,
158
+ skipped: tracer.skipped
159
+ }
160
+ });
161
+ };
153
162
  const skip = (grant, why) => {
154
163
  tracer?.skipped.push({
155
164
  role: grant.role,
@@ -302,12 +311,13 @@ function evaluateSnapshot(snapshot, subject, permission, data, team, options, ou
302
311
  reason: "human",
303
312
  token
304
313
  });
305
- return done({
314
+ return done(compact({
306
315
  outcome: "granted",
307
316
  subject,
308
317
  matched: grant,
309
- token
310
- });
318
+ token,
319
+ obligations: matched.obligations
320
+ }));
311
321
  }
312
322
  function whereFromSnapshot(snapshot, subject, permission, team) {
313
323
  return whereFromGrants(snapshot.grants.filter((grant) => grant.permission === permission.key), {
@@ -1,3 +1,4 @@
1
+ import { r as isRecord } from "./compact-CAf557ZB.js";
1
2
  import { t as byCodePoint } from "./compare-pfyVnBjE.js";
2
3
  //#region src/cli/generate.ts
3
4
  const IDENTIFIER = /^[A-Za-z_$][A-Za-z0-9_$]*$/u;
@@ -19,9 +20,6 @@ function emptySchema(kind) {
19
20
  function propertyKey(name) {
20
21
  return IDENTIFIER.test(name) ? name : JSON.stringify(name);
21
22
  }
22
- function isRecord(value) {
23
- return value !== null && typeof value === "object" && !Array.isArray(value);
24
- }
25
23
  function literalEnum(schema) {
26
24
  const values = schema["enum"];
27
25
  if (!Array.isArray(values) || values.length === 0 || !values.every((value) => typeof value === "string")) return;
@@ -0,0 +1,254 @@
1
+ import { t as compact } from "./compact-CAf557ZB.js";
2
+ import { n as freezeDeep, t as freezeCopy } from "./freeze-CrU8nQeX.js";
3
+ import { a as assertSafeKey, c as ownKeys, o as isForbiddenKey } from "./thenable-QSmvt-vZ.js";
4
+ import { i as readAppData, r as parseAppData, t as assertAppData } from "./app-data-CV8pqqMi.js";
5
+ import { c as listPermissions, o as isPermission } from "./permission-registry-BsblpB-z.js";
6
+ //#region src/core/vocabulary.ts
7
+ const ROLE_KIND = "role";
8
+ const PLAN_KIND = "plan";
9
+ const TREE_X_SCHEMA = Symbol.for("permdock.x-schema");
10
+ function leafMeta(kind, key, meta, schema) {
11
+ if (meta === void 0) return freezeDeep({});
12
+ assertAppData(meta, `meta of ${kind} '${key}'`);
13
+ if (meta.x === void 0) return freezeDeep({ ...meta });
14
+ return freezeDeep({
15
+ ...meta,
16
+ x: parseAppData(schema, meta.x, `meta.x of ${kind} '${key}'`)
17
+ });
18
+ }
19
+ function makeRole(key, init, schema) {
20
+ assertSafeKey(key, "role");
21
+ const on = init.on;
22
+ const leaf = {
23
+ key,
24
+ assignable: init.assignable ?? on !== void 0,
25
+ meta: leafMeta("role", key, init.meta, schema)
26
+ };
27
+ if (on !== void 0) Object.assign(leaf, { on });
28
+ Object.defineProperty(leaf, "kind", {
29
+ value: ROLE_KIND,
30
+ enumerable: false,
31
+ writable: false,
32
+ configurable: false
33
+ });
34
+ return Object.freeze(leaf);
35
+ }
36
+ function makePlan(key, init, schema) {
37
+ assertSafeKey(key, "plan");
38
+ const leaf = {
39
+ key,
40
+ meta: leafMeta("plan", key, init.meta, schema)
41
+ };
42
+ Object.defineProperty(leaf, "kind", {
43
+ value: PLAN_KIND,
44
+ enumerable: false,
45
+ writable: false,
46
+ configurable: false
47
+ });
48
+ return Object.freeze(leaf);
49
+ }
50
+ function isRole(value) {
51
+ return value !== null && typeof value === "object" && "key" in value && typeof value.key === "string" && value.kind === "role";
52
+ }
53
+ function isPlan(value) {
54
+ return value !== null && typeof value === "object" && "key" in value && typeof value.key === "string" && value.kind === "plan";
55
+ }
56
+ function attachSchema(tree, schema) {
57
+ if (schema !== void 0) Object.defineProperty(tree, TREE_X_SCHEMA, {
58
+ value: schema,
59
+ enumerable: false,
60
+ writable: false,
61
+ configurable: false
62
+ });
63
+ }
64
+ /** The `x` schema a `defineRoles` or `definePlans` tree was built with. */
65
+ function treeXSchema(tree) {
66
+ if (tree === void 0 || !Object.hasOwn(tree, TREE_X_SCHEMA)) return;
67
+ return Reflect.get(tree, TREE_X_SCHEMA);
68
+ }
69
+ function defineRoles(input, options) {
70
+ const tree = {};
71
+ for (const key of Object.keys(input)) {
72
+ if (isForbiddenKey(key)) throw new Error(`PermDock: forbidden role key '${key}'`);
73
+ tree[key] = makeRole(key, input[key] ?? {}, options?.x);
74
+ }
75
+ attachSchema(tree, options?.x);
76
+ return freezeDeep(tree);
77
+ }
78
+ function definePlans(input, options) {
79
+ const tree = {};
80
+ for (const key of Object.keys(input)) {
81
+ if (isForbiddenKey(key)) throw new Error(`PermDock: forbidden plan key '${key}'`);
82
+ tree[key] = makePlan(key, input[key] ?? {}, options?.x);
83
+ }
84
+ attachSchema(tree, options?.x);
85
+ return freezeDeep(tree);
86
+ }
87
+ function listRoles(tree) {
88
+ if (tree === void 0) return [];
89
+ return ownKeys(tree).flatMap((key) => {
90
+ const leaf = tree[key];
91
+ return leaf === void 0 ? [] : [leaf];
92
+ });
93
+ }
94
+ function listPlans(tree) {
95
+ if (tree === void 0) return [];
96
+ return ownKeys(tree).flatMap((key) => {
97
+ const leaf = tree[key];
98
+ return leaf === void 0 ? [] : [leaf];
99
+ });
100
+ }
101
+ function findRole(tree, key) {
102
+ if (tree === void 0 || isForbiddenKey(key)) return;
103
+ return tree[key];
104
+ }
105
+ /**
106
+ * The meta of a role a source returned (a stored custom role): known string
107
+ * fields kept, `x` checked by the schema. Never throws; anything invalid is
108
+ * left out, and the role itself is never dropped for it.
109
+ */
110
+ function sourceRoleMeta(meta, schema) {
111
+ if (meta === null || typeof meta !== "object" || Array.isArray(meta)) return;
112
+ const text = (field) => {
113
+ const value = Object.hasOwn(meta, field) ? Reflect.get(meta, field) : void 0;
114
+ return typeof value === "string" ? value : void 0;
115
+ };
116
+ const rawX = Object.hasOwn(meta, "x") ? Reflect.get(meta, "x") : void 0;
117
+ const out = {};
118
+ for (const field of [
119
+ "title",
120
+ "description",
121
+ "audience"
122
+ ]) {
123
+ const value = text(field);
124
+ if (value !== void 0) out[field] = value;
125
+ }
126
+ if (rawX !== void 0) {
127
+ const x = readAppData(schema, rawX);
128
+ if (x !== void 0) out.x = x;
129
+ }
130
+ return Object.keys(out).length === 0 ? void 0 : freezeCopy(out);
131
+ }
132
+ function synthesiseRole(key, options) {
133
+ const on = options?.on;
134
+ const assignable = options?.assignable ?? false;
135
+ const meta = options?.meta;
136
+ if (on === void 0) return makeRole(key, meta === void 0 ? { assignable } : {
137
+ assignable,
138
+ meta
139
+ });
140
+ return makeRole(key, meta === void 0 ? {
141
+ on,
142
+ assignable
143
+ } : {
144
+ on,
145
+ assignable,
146
+ meta
147
+ });
148
+ }
149
+ function isGrantee(value) {
150
+ return value !== null && typeof value === "object" && "kind" in value && typeof value.kind === "string";
151
+ }
152
+ function anyone() {
153
+ return freezeDeep({ kind: "anyone" });
154
+ }
155
+ function authenticated() {
156
+ return freezeDeep({ kind: "authenticated" });
157
+ }
158
+ function relation(resource, name, options) {
159
+ const resourceName = listPermissions(resource)[0]?.resource;
160
+ if (resourceName === void 0) throw new Error("PermDock: relation() requires a resource tree");
161
+ const through = options?.through;
162
+ if (Array.isArray(through)) {
163
+ if (through.length === 0) throw new Error("PermDock: relation() through needs at least one link");
164
+ for (const link of through) if (typeof link !== "string" || link === "" || link === "parent") throw new Error("PermDock: relation() through lists link names; walk parents with through: 'parent' or depth");
165
+ } else if (through !== void 0 && through !== "parent") throw new Error(`PermDock: relation() through must be 'parent' or a list of link names (got '${String(through)}')`);
166
+ const depth = options?.depth;
167
+ if (depth !== void 0) {
168
+ if (through === void 0) throw new Error("PermDock: relation() depth needs through: 'parent' or a link list");
169
+ const hops = Array.isArray(through) ? through.length : 0;
170
+ if (!Number.isInteger(depth) || depth < 0 || depth + hops > 32) throw new Error(`PermDock: relation() depth must be an integer from 0 to 32, counting each link`);
171
+ }
172
+ return freezeDeep(compact({
173
+ kind: "relation",
174
+ resource: resourceName,
175
+ relation: name,
176
+ through: through === void 0 || through === "parent" ? through : [...through],
177
+ depth
178
+ }));
179
+ }
180
+ function inherit(permission, options) {
181
+ if (!isPermission(permission) || permission.kind === "collection") throw new Error("PermDock: inherit() takes an instance permission leaf");
182
+ const through = options.through;
183
+ const links = Array.isArray(through) ? through : void 0;
184
+ if (through !== "parent" && (links === void 0 || links.length === 0 || !links.every((link) => typeof link === "string" && link !== "" && link !== "parent"))) throw new Error("PermDock: inherit() through must be 'parent' or a non-empty list of link names");
185
+ return freezeDeep({
186
+ kind: "inherit",
187
+ permission: permission.key,
188
+ resource: permission.resource,
189
+ through: links === void 0 ? "parent" : links.map(String)
190
+ });
191
+ }
192
+ function plan(name) {
193
+ return freezeDeep({
194
+ kind: "plan",
195
+ plan: typeof name === "string" ? name : name.key
196
+ });
197
+ }
198
+ function actor(kind) {
199
+ return freezeDeep({
200
+ kind: "actor",
201
+ actor: kind
202
+ });
203
+ }
204
+ function assurance(options) {
205
+ const acr = options.acr === void 0 ? void 0 : typeof options.acr === "string" ? [options.acr] : options.acr;
206
+ const amr = options.amr === void 0 ? void 0 : typeof options.amr === "string" ? [options.amr] : options.amr;
207
+ return freezeDeep(compact({
208
+ kind: "assurance",
209
+ acr,
210
+ amr,
211
+ maxAge: options.maxAge
212
+ }));
213
+ }
214
+ function resolveRoleScope(on) {
215
+ return typeof on === "string" ? on : "global";
216
+ }
217
+ function asGrantee(input) {
218
+ if (Array.isArray(input)) {
219
+ const items = [];
220
+ for (const item of input) items.push(...flattenGrantee(asGrantee(item)));
221
+ return items;
222
+ }
223
+ if (typeof input === "string") return freezeDeep({
224
+ kind: "role",
225
+ role: input,
226
+ scope: "global"
227
+ });
228
+ if (isRole(input)) return freezeDeep({
229
+ kind: "role",
230
+ role: input.key,
231
+ scope: resolveRoleScope(input.on)
232
+ });
233
+ if (isPlan(input)) return freezeDeep({
234
+ kind: "plan",
235
+ plan: input.key
236
+ });
237
+ if (isGrantee(input)) return input;
238
+ throw new Error("PermDock: invalid grantee");
239
+ }
240
+ function flattenGrantee(input) {
241
+ if (input === void 0) return [];
242
+ if (Array.isArray(input)) return input;
243
+ return [input];
244
+ }
245
+ function roleNameOf(to) {
246
+ for (const item of flattenGrantee(to)) if (item.kind === "role") return item.role;
247
+ return null;
248
+ }
249
+ function roleScopeOf(to, fallback = "global") {
250
+ for (const item of flattenGrantee(to)) if (item.kind === "role") return item.scope;
251
+ return fallback;
252
+ }
253
+ //#endregion
254
+ export { listPlans as _, authenticated as a, synthesiseRole as b, plan as c, roleScopeOf as d, definePlans as f, isRole as g, isPlan as h, assurance as i, relation as l, findRole as m, anyone as n, flattenGrantee as o, defineRoles as p, asGrantee as r, inherit as s, actor as t, roleNameOf as u, listRoles as v, treeXSchema as x, sourceRoleMeta as y };
@@ -0,0 +1,270 @@
1
+ import { a as sole, t as compact } from "./compact-CAf557ZB.js";
2
+ import { c as rootScope, d as scopeList, o as resolveScope } from "./scopes-tvpa34ep.js";
3
+ import { a as expandRelation, c as isEdgeRelation, d as isSelfParented, l as isFieldRelation, m as restrictedStops, p as restrictedFor, s as isComputedRelation, u as isPrincipalRelation } from "./resource-relations-D1Un3pcz.js";
4
+ //#region src/core/grantee-conditions.ts
5
+ /**
6
+ * Where a graph relation starts on the row: its own id when the relation is
7
+ * on the row's resource, the parent field when it is on the parent resource.
8
+ * `undefined` when `through` cannot reach the relation's resource.
9
+ */
10
+ function relationStart(grantee, resource, target) {
11
+ if (resource === void 0 || target === void 0 || Array.isArray(grantee.through)) return;
12
+ const walks = grantee.through === "parent" && isSelfParented(target);
13
+ const requested = grantee.depth ?? 16;
14
+ const depth = walks ? Number.isInteger(requested) ? Math.min(Math.max(requested, 0), 32) : 0 : 0;
15
+ if (target.name === resource.name) return {
16
+ field: resource.id,
17
+ parent: false,
18
+ depth
19
+ };
20
+ if (grantee.through === "parent" && resource.parent?.resource === target.name) return {
21
+ field: resource.parent.field,
22
+ parent: true,
23
+ depth
24
+ };
25
+ }
26
+ /**
27
+ * A resource role held on self-parented `membershipResource` instances
28
+ * (`ids`) reaches rows below them: the row itself when it is of that
29
+ * resource, its parent field when its parent is, walked up to the default
30
+ * depth. `undefined` when the row is not on such a chain.
31
+ */
32
+ function resourceRoleCondition(resource, membershipResource, ids, resources) {
33
+ if (resource === void 0 || !isSelfParented(resources.get(membershipResource))) return;
34
+ const start = resource.name === membershipResource ? {
35
+ field: resource.id,
36
+ parent: false
37
+ } : resource.parent?.resource === membershipResource ? {
38
+ field: resource.parent.field,
39
+ parent: true
40
+ } : void 0;
41
+ if (start === void 0) return;
42
+ return compact({
43
+ op: "related",
44
+ resource: membershipResource,
45
+ relation: "",
46
+ ids: [...new Set(ids)].toSorted(),
47
+ field: start.field,
48
+ depth: 16,
49
+ parent: start.parent ? true : void 0,
50
+ restricted: restrictedFor(resource, "parent"),
51
+ passRestricted: passesRestricted(resources.get(membershipResource))
52
+ });
53
+ }
54
+ function passesRestricted(node) {
55
+ return node?.restricted !== void 0 && !restrictedStops(node, "parent") ? true : void 0;
56
+ }
57
+ function linkStop(resource, link) {
58
+ const restricted = restrictedFor(resource, link);
59
+ if (restricted === void 0) return {};
60
+ const parent = resource.parent;
61
+ if (parent === void 0 || !isSelfParented(resource)) return { restricted };
62
+ return {
63
+ restricted,
64
+ restrictedAncestors: {
65
+ resource: resource.name,
66
+ id: resource.id,
67
+ parent: parent.field,
68
+ field: restricted,
69
+ depth: 32
70
+ }
71
+ };
72
+ }
73
+ /**
74
+ * The link path from the row to the grantee's resource: the row field of
75
+ * the first link and each hop. `undefined` when a link is not declared or
76
+ * the path ends on another resource.
77
+ */
78
+ function relationHops(grantee, resource, resources) {
79
+ const through = grantee.through;
80
+ if (!Array.isArray(through) || resource === void 0) return;
81
+ const hops = [];
82
+ let current = resource;
83
+ let field;
84
+ for (const link of through) {
85
+ const spec = current !== void 0 && Object.hasOwn(current.links, link) ? current.links[link] : void 0;
86
+ if (spec === void 0) return;
87
+ field ??= spec.field;
88
+ hops.push({
89
+ link,
90
+ resource: spec.resource
91
+ });
92
+ current = resources?.get(spec.resource);
93
+ }
94
+ if (field === void 0 || current === void 0 || current.name !== grantee.resource) return;
95
+ const depth = grantee.depth ?? 0;
96
+ if (depth > 0 && !isSelfParented(current)) return;
97
+ return {
98
+ field,
99
+ hops,
100
+ depth
101
+ };
102
+ }
103
+ /**
104
+ * Whether the grantee needs the relation graph: a `through` walk, an edge
105
+ * table, or an `includes` that reaches one.
106
+ */
107
+ function isGraphRelation(grantee, resources) {
108
+ if (grantee.through !== void 0) return true;
109
+ const node = resources?.get(grantee.resource);
110
+ return expandRelation(node, grantee.relation).some((name) => isEdgeRelation(node?.relations[name]));
111
+ }
112
+ function periodConditions(spec, now) {
113
+ const out = [];
114
+ const startsAt = spec.period?.startsAt;
115
+ if (startsAt !== void 0) out.push({
116
+ op: "or",
117
+ conditions: [{
118
+ op: "isNull",
119
+ field: startsAt,
120
+ value: true
121
+ }, {
122
+ op: "lte",
123
+ field: startsAt,
124
+ value: now
125
+ }]
126
+ });
127
+ const expiresAt = spec.period?.expiresAt;
128
+ if (expiresAt !== void 0) out.push({
129
+ op: "or",
130
+ conditions: [{
131
+ op: "isNull",
132
+ field: expiresAt,
133
+ value: true
134
+ }, {
135
+ op: "gt",
136
+ field: expiresAt,
137
+ value: now
138
+ }]
139
+ });
140
+ return out;
141
+ }
142
+ function relationCondition(grantee, resource, scopes = scopeList(void 0), options = {}) {
143
+ const target = grantee.resource === resource?.name ? resource : options.resources?.get(grantee.resource);
144
+ if (isGraphRelation(grantee, options.resources ?? targetMap(target))) {
145
+ const spec = target?.relations[grantee.relation];
146
+ if (spec === void 0 || isFieldRelation(spec) && spec.memberOf !== void 0) return;
147
+ if (Array.isArray(grantee.through)) {
148
+ const path = relationHops(grantee, resource, options.resources);
149
+ if (path === void 0 || target === void 0) return;
150
+ return compact({
151
+ op: "related",
152
+ resource: target.name,
153
+ relation: grantee.relation,
154
+ field: path.field,
155
+ depth: path.depth,
156
+ hops: path.hops,
157
+ ...resource === void 0 ? {} : linkStop(resource, firstLink(path)),
158
+ passRestricted: path.depth > 0 ? passesRestricted(target) : void 0
159
+ });
160
+ }
161
+ const start = relationStart(grantee, resource, target);
162
+ if (start === void 0 || target === void 0) return;
163
+ return compact({
164
+ op: "related",
165
+ resource: target.name,
166
+ relation: grantee.relation,
167
+ field: start.field,
168
+ depth: start.depth,
169
+ parent: start.parent ? true : void 0,
170
+ restricted: start.parent || start.depth > 0 ? restrictedFor(resource, "parent") : void 0,
171
+ passRestricted: start.depth > 0 ? passesRestricted(target) : void 0
172
+ });
173
+ }
174
+ const spec = resource?.relations?.[grantee.relation];
175
+ if (spec === void 0 || isEdgeRelation(spec)) return;
176
+ if (spec.includes !== void 0 && options.includes !== false) {
177
+ const parts = expandRelation(resource, grantee.relation).flatMap((name) => {
178
+ const part = relationCondition({
179
+ ...grantee,
180
+ relation: name
181
+ }, resource, scopes, {
182
+ ...options,
183
+ includes: false
184
+ });
185
+ return part === void 0 ? [] : [part];
186
+ });
187
+ return sole(parts) ?? {
188
+ op: "or",
189
+ conditions: parts
190
+ };
191
+ }
192
+ if (isComputedRelation(spec)) return;
193
+ if (isPrincipalRelation(spec)) {
194
+ const owner = {
195
+ op: "eq",
196
+ field: spec.principal,
197
+ value: { ref: "principal.id" }
198
+ };
199
+ const period = periodConditions(spec, options.now ?? { date: (/* @__PURE__ */ new Date()).toISOString() });
200
+ return period.length === 0 ? owner : {
201
+ op: "and",
202
+ conditions: [owner, ...period]
203
+ };
204
+ }
205
+ if (spec.memberOf !== void 0) {
206
+ const scope = resolveScope(scopes, spec.memberOf);
207
+ if (scope === void 0) return {
208
+ op: "or",
209
+ conditions: []
210
+ };
211
+ if (scope === rootScope(scopes)) return {
212
+ op: "eq",
213
+ field: spec.field,
214
+ value: { ref: "principal.tenant" }
215
+ };
216
+ return {
217
+ op: "memberOf",
218
+ scope,
219
+ field: spec.field,
220
+ roles: []
221
+ };
222
+ }
223
+ return {
224
+ op: "eq",
225
+ field: spec.field,
226
+ value: { ref: "principal.id" }
227
+ };
228
+ }
229
+ function inheritCondition(grantee, resource, resources) {
230
+ if (resource === void 0) return;
231
+ if (grantee.through === "parent") {
232
+ const parent = resource.parent;
233
+ if (parent === void 0 || parent.resource !== grantee.resource) return;
234
+ return compact({
235
+ op: "related",
236
+ resource: grantee.resource,
237
+ relation: "",
238
+ permission: grantee.permission,
239
+ field: parent.field,
240
+ depth: 0,
241
+ parent: true,
242
+ restricted: restrictedFor(resource, "parent")
243
+ });
244
+ }
245
+ const path = relationHops({
246
+ kind: "relation",
247
+ resource: grantee.resource,
248
+ relation: "",
249
+ through: grantee.through
250
+ }, resource, resources);
251
+ if (path === void 0) return;
252
+ return compact({
253
+ op: "related",
254
+ resource: grantee.resource,
255
+ relation: "",
256
+ permission: grantee.permission,
257
+ field: path.field,
258
+ depth: 0,
259
+ hops: path.hops,
260
+ ...linkStop(resource, firstLink(path))
261
+ });
262
+ }
263
+ function firstLink(path) {
264
+ return path.hops[0]?.link ?? "";
265
+ }
266
+ function targetMap(target) {
267
+ return target === void 0 ? void 0 : /* @__PURE__ */ new Map([[target.name, target]]);
268
+ }
269
+ //#endregion
270
+ export { relationStart as a, relationHops as i, isGraphRelation as n, resourceRoleCondition as o, relationCondition as r, inheritCondition as t };