@dyrected/core 2.6.3 → 2.7.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 (354) hide show
  1. package/dist/__tests__/access-features.test.d.ts +2 -0
  2. package/dist/__tests__/access-features.test.d.ts.map +1 -0
  3. package/dist/__tests__/access-features.test.js +159 -0
  4. package/dist/__tests__/access-features.test.js.map +1 -0
  5. package/dist/__tests__/access-parity.test.d.ts +2 -0
  6. package/dist/__tests__/access-parity.test.d.ts.map +1 -0
  7. package/dist/__tests__/access-parity.test.js +338 -0
  8. package/dist/__tests__/access-parity.test.js.map +1 -0
  9. package/dist/__tests__/access.test.d.ts +2 -0
  10. package/dist/__tests__/access.test.d.ts.map +1 -0
  11. package/dist/__tests__/access.test.js +137 -0
  12. package/dist/__tests__/access.test.js.map +1 -0
  13. package/dist/__tests__/admin-auth.test.d.ts +2 -0
  14. package/dist/__tests__/admin-auth.test.d.ts.map +1 -0
  15. package/dist/__tests__/admin-auth.test.js +440 -0
  16. package/dist/__tests__/admin-auth.test.js.map +1 -0
  17. package/dist/__tests__/app.test.d.ts +2 -0
  18. package/dist/__tests__/app.test.d.ts.map +1 -0
  19. package/dist/__tests__/app.test.js +112 -0
  20. package/dist/__tests__/app.test.js.map +1 -0
  21. package/dist/__tests__/audit.test.d.ts +2 -0
  22. package/dist/__tests__/audit.test.d.ts.map +1 -0
  23. package/dist/__tests__/audit.test.js +125 -0
  24. package/dist/__tests__/audit.test.js.map +1 -0
  25. package/dist/__tests__/auth-hydration.test.d.ts +2 -0
  26. package/dist/__tests__/auth-hydration.test.d.ts.map +1 -0
  27. package/dist/__tests__/auth-hydration.test.js +90 -0
  28. package/dist/__tests__/auth-hydration.test.js.map +1 -0
  29. package/dist/__tests__/auth-invite.test.d.ts +2 -0
  30. package/dist/__tests__/auth-invite.test.d.ts.map +1 -0
  31. package/dist/__tests__/auth-invite.test.js +152 -0
  32. package/dist/__tests__/auth-invite.test.js.map +1 -0
  33. package/dist/__tests__/auth-lockout.test.d.ts +2 -0
  34. package/dist/__tests__/auth-lockout.test.d.ts.map +1 -0
  35. package/dist/__tests__/auth-lockout.test.js +154 -0
  36. package/dist/__tests__/auth-lockout.test.js.map +1 -0
  37. package/dist/__tests__/auth-sessions.test.d.ts +2 -0
  38. package/dist/__tests__/auth-sessions.test.d.ts.map +1 -0
  39. package/dist/__tests__/auth-sessions.test.js +118 -0
  40. package/dist/__tests__/auth-sessions.test.js.map +1 -0
  41. package/dist/__tests__/config.test.d.ts +2 -0
  42. package/dist/__tests__/config.test.d.ts.map +1 -0
  43. package/dist/__tests__/config.test.js +402 -0
  44. package/dist/__tests__/config.test.js.map +1 -0
  45. package/dist/__tests__/define-field.test.d.ts +2 -0
  46. package/dist/__tests__/define-field.test.d.ts.map +1 -0
  47. package/dist/__tests__/define-field.test.js +121 -0
  48. package/dist/__tests__/define-field.test.js.map +1 -0
  49. package/dist/__tests__/deleteMany.test.d.ts +2 -0
  50. package/dist/__tests__/deleteMany.test.d.ts.map +1 -0
  51. package/dist/__tests__/deleteMany.test.js +75 -0
  52. package/dist/__tests__/deleteMany.test.js.map +1 -0
  53. package/dist/__tests__/depth.test.d.ts +2 -0
  54. package/dist/__tests__/depth.test.d.ts.map +1 -0
  55. package/dist/__tests__/depth.test.js +115 -0
  56. package/dist/__tests__/depth.test.js.map +1 -0
  57. package/dist/__tests__/dynamic-options.test.d.ts +2 -0
  58. package/dist/__tests__/dynamic-options.test.d.ts.map +1 -0
  59. package/dist/__tests__/dynamic-options.test.js +168 -0
  60. package/dist/__tests__/dynamic-options.test.js.map +1 -0
  61. package/dist/__tests__/email.service.test.d.ts +2 -0
  62. package/dist/__tests__/email.service.test.d.ts.map +1 -0
  63. package/dist/__tests__/email.service.test.js +52 -0
  64. package/dist/__tests__/email.service.test.js.map +1 -0
  65. package/dist/__tests__/field-inference.test-types.d.ts +161 -0
  66. package/dist/__tests__/field-inference.test-types.d.ts.map +1 -0
  67. package/dist/__tests__/field-inference.test-types.js +87 -0
  68. package/dist/__tests__/field-inference.test-types.js.map +1 -0
  69. package/dist/__tests__/fixtures/editorial-workflow.d.ts +14 -0
  70. package/dist/__tests__/fixtures/editorial-workflow.d.ts.map +1 -0
  71. package/dist/__tests__/fixtures/editorial-workflow.js +12 -0
  72. package/dist/__tests__/fixtures/editorial-workflow.js.map +1 -0
  73. package/dist/__tests__/hooks.test.d.ts +2 -0
  74. package/dist/__tests__/hooks.test.d.ts.map +1 -0
  75. package/dist/__tests__/hooks.test.js +320 -0
  76. package/dist/__tests__/hooks.test.js.map +1 -0
  77. package/dist/__tests__/mocks.d.ts +75 -0
  78. package/dist/__tests__/mocks.d.ts.map +1 -0
  79. package/dist/__tests__/mocks.js +170 -0
  80. package/dist/__tests__/mocks.js.map +1 -0
  81. package/dist/__tests__/observability.test.d.ts +2 -0
  82. package/dist/__tests__/observability.test.d.ts.map +1 -0
  83. package/dist/__tests__/observability.test.js +233 -0
  84. package/dist/__tests__/observability.test.js.map +1 -0
  85. package/dist/__tests__/openapi.test.d.ts +2 -0
  86. package/dist/__tests__/openapi.test.d.ts.map +1 -0
  87. package/dist/__tests__/openapi.test.js +105 -0
  88. package/dist/__tests__/openapi.test.js.map +1 -0
  89. package/dist/__tests__/parse-sort.test.d.ts +2 -0
  90. package/dist/__tests__/parse-sort.test.d.ts.map +1 -0
  91. package/dist/__tests__/parse-sort.test.js +24 -0
  92. package/dist/__tests__/parse-sort.test.js.map +1 -0
  93. package/dist/__tests__/preferences.test.d.ts +2 -0
  94. package/dist/__tests__/preferences.test.d.ts.map +1 -0
  95. package/dist/__tests__/preferences.test.js +168 -0
  96. package/dist/__tests__/preferences.test.js.map +1 -0
  97. package/dist/__tests__/router.test.d.ts +2 -0
  98. package/dist/__tests__/router.test.d.ts.map +1 -0
  99. package/dist/__tests__/router.test.js +70 -0
  100. package/dist/__tests__/router.test.js.map +1 -0
  101. package/dist/__tests__/search.test.d.ts +2 -0
  102. package/dist/__tests__/search.test.d.ts.map +1 -0
  103. package/dist/__tests__/search.test.js +174 -0
  104. package/dist/__tests__/search.test.js.map +1 -0
  105. package/dist/__tests__/upload-validation.test.d.ts +2 -0
  106. package/dist/__tests__/upload-validation.test.d.ts.map +1 -0
  107. package/dist/__tests__/upload-validation.test.js +41 -0
  108. package/dist/__tests__/upload-validation.test.js.map +1 -0
  109. package/dist/__tests__/where.test.d.ts +2 -0
  110. package/dist/__tests__/where.test.d.ts.map +1 -0
  111. package/dist/__tests__/where.test.js +105 -0
  112. package/dist/__tests__/where.test.js.map +1 -0
  113. package/dist/__tests__/workflow.test.d.ts +2 -0
  114. package/dist/__tests__/workflow.test.d.ts.map +1 -0
  115. package/dist/__tests__/workflow.test.js +684 -0
  116. package/dist/__tests__/workflow.test.js.map +1 -0
  117. package/dist/app-config-C9VJ6rTv.d.cts +2092 -0
  118. package/dist/app-config-C9VJ6rTv.d.ts +2092 -0
  119. package/dist/app-config-CYV70eoF.d.cts +2100 -0
  120. package/dist/app-config-CYV70eoF.d.ts +2100 -0
  121. package/dist/app-config-ChsrBB7p.d.cts +2100 -0
  122. package/dist/app-config-ChsrBB7p.d.ts +2100 -0
  123. package/dist/app.d.ts +35 -0
  124. package/dist/app.d.ts.map +1 -0
  125. package/dist/app.js +164 -0
  126. package/dist/app.js.map +1 -0
  127. package/dist/auth/access.d.ts +5 -0
  128. package/dist/auth/access.d.ts.map +1 -0
  129. package/dist/auth/access.js +59 -0
  130. package/dist/auth/access.js.map +1 -0
  131. package/dist/auth/jexl.d.ts +13 -0
  132. package/dist/auth/jexl.d.ts.map +1 -0
  133. package/dist/auth/jexl.js +30 -0
  134. package/dist/auth/jexl.js.map +1 -0
  135. package/dist/auth/lockout.d.ts +11 -0
  136. package/dist/auth/lockout.d.ts.map +1 -0
  137. package/dist/auth/lockout.js +37 -0
  138. package/dist/auth/lockout.js.map +1 -0
  139. package/dist/auth/password.d.ts +10 -0
  140. package/dist/auth/password.d.ts.map +1 -0
  141. package/dist/auth/password.js +28 -0
  142. package/dist/auth/password.js.map +1 -0
  143. package/dist/auth/sessions.d.ts +39 -0
  144. package/dist/auth/sessions.d.ts.map +1 -0
  145. package/dist/auth/sessions.js +126 -0
  146. package/dist/auth/sessions.js.map +1 -0
  147. package/dist/auth/token.d.ts +23 -0
  148. package/dist/auth/token.d.ts.map +1 -0
  149. package/dist/auth/token.js +40 -0
  150. package/dist/auth/token.js.map +1 -0
  151. package/dist/chunk-23NM4LDU.js +2883 -0
  152. package/dist/chunk-2TKDCCIR.js +2622 -0
  153. package/dist/chunk-3SFITPX4.js +2628 -0
  154. package/dist/chunk-CQVTQ67D.js +2632 -0
  155. package/dist/chunk-ELHRRPKX.js +2863 -0
  156. package/dist/chunk-HRLSFTLR.js +3061 -0
  157. package/dist/chunk-QTIAQBNH.js +3097 -0
  158. package/dist/chunk-T2DGC4MD.js +3008 -0
  159. package/dist/chunk-TLU77TLE.js +3203 -0
  160. package/dist/chunk-YEBCT77K.js +3269 -0
  161. package/dist/chunk-YXEKNN5X.js +3085 -0
  162. package/dist/controllers/admin-auth.controller.d.ts +71 -0
  163. package/dist/controllers/admin-auth.controller.d.ts.map +1 -0
  164. package/dist/controllers/admin-auth.controller.js +450 -0
  165. package/dist/controllers/admin-auth.controller.js.map +1 -0
  166. package/dist/controllers/audit.controller.d.ts +42 -0
  167. package/dist/controllers/audit.controller.d.ts.map +1 -0
  168. package/dist/controllers/audit.controller.js +149 -0
  169. package/dist/controllers/audit.controller.js.map +1 -0
  170. package/dist/controllers/auth.controller.d.ts +143 -0
  171. package/dist/controllers/auth.controller.d.ts.map +1 -0
  172. package/dist/controllers/auth.controller.js +572 -0
  173. package/dist/controllers/auth.controller.js.map +1 -0
  174. package/dist/controllers/collection.controller.d.ts +170 -0
  175. package/dist/controllers/collection.controller.d.ts.map +1 -0
  176. package/dist/controllers/collection.controller.js +1033 -0
  177. package/dist/controllers/collection.controller.js.map +1 -0
  178. package/dist/controllers/global.controller.d.ts +20 -0
  179. package/dist/controllers/global.controller.d.ts.map +1 -0
  180. package/dist/controllers/global.controller.js +182 -0
  181. package/dist/controllers/global.controller.js.map +1 -0
  182. package/dist/controllers/media.controller.d.ts +39 -0
  183. package/dist/controllers/media.controller.d.ts.map +1 -0
  184. package/dist/controllers/media.controller.js +178 -0
  185. package/dist/controllers/media.controller.js.map +1 -0
  186. package/dist/controllers/preview.controller.d.ts +37 -0
  187. package/dist/controllers/preview.controller.d.ts.map +1 -0
  188. package/dist/controllers/preview.controller.js +48 -0
  189. package/dist/controllers/preview.controller.js.map +1 -0
  190. package/dist/index.cjs +707 -27
  191. package/dist/index.d.cts +77 -5
  192. package/dist/index.d.ts +77 -5
  193. package/dist/index.d.ts.map +1 -0
  194. package/dist/index.js +37 -1
  195. package/dist/index.js.map +1 -0
  196. package/dist/middleware/auth.d.ts +19 -0
  197. package/dist/middleware/auth.d.ts.map +1 -0
  198. package/dist/middleware/auth.js +157 -0
  199. package/dist/middleware/auth.js.map +1 -0
  200. package/dist/middleware/rate-limit.d.ts +9 -0
  201. package/dist/middleware/rate-limit.d.ts.map +1 -0
  202. package/dist/middleware/rate-limit.js +75 -0
  203. package/dist/middleware/rate-limit.js.map +1 -0
  204. package/dist/network.d.ts +6 -0
  205. package/dist/network.d.ts.map +1 -0
  206. package/dist/network.js +70 -0
  207. package/dist/network.js.map +1 -0
  208. package/dist/observability.d.ts +113 -0
  209. package/dist/observability.d.ts.map +1 -0
  210. package/dist/observability.js +497 -0
  211. package/dist/observability.js.map +1 -0
  212. package/dist/router.d.ts +8 -0
  213. package/dist/router.d.ts.map +1 -0
  214. package/dist/router.js +704 -0
  215. package/dist/router.js.map +1 -0
  216. package/dist/server.cjs +861 -54
  217. package/dist/server.d.cts +9 -1
  218. package/dist/server.d.ts +9 -1
  219. package/dist/server.d.ts.map +1 -0
  220. package/dist/server.js +189 -26
  221. package/dist/server.js.map +1 -0
  222. package/dist/services/audit.service.d.ts +23 -0
  223. package/dist/services/audit.service.d.ts.map +1 -0
  224. package/dist/services/audit.service.js +39 -0
  225. package/dist/services/audit.service.js.map +1 -0
  226. package/dist/services/defaults.service.d.ts +8 -0
  227. package/dist/services/defaults.service.d.ts.map +1 -0
  228. package/dist/services/defaults.service.js +55 -0
  229. package/dist/services/defaults.service.js.map +1 -0
  230. package/dist/services/email-template.d.ts +46 -0
  231. package/dist/services/email-template.d.ts.map +1 -0
  232. package/dist/services/email-template.js +88 -0
  233. package/dist/services/email-template.js.map +1 -0
  234. package/dist/services/email.service.d.ts +34 -0
  235. package/dist/services/email.service.d.ts.map +1 -0
  236. package/dist/services/email.service.js +129 -0
  237. package/dist/services/email.service.js.map +1 -0
  238. package/dist/services/media.service.d.ts +20 -0
  239. package/dist/services/media.service.d.ts.map +1 -0
  240. package/dist/services/media.service.js +49 -0
  241. package/dist/services/media.service.js.map +1 -0
  242. package/dist/services/population.service.d.ts +20 -0
  243. package/dist/services/population.service.d.ts.map +1 -0
  244. package/dist/services/population.service.js +224 -0
  245. package/dist/services/population.service.js.map +1 -0
  246. package/dist/types/access.d.ts +48 -0
  247. package/dist/types/access.d.ts.map +1 -0
  248. package/dist/types/access.js +2 -0
  249. package/dist/types/access.js.map +1 -0
  250. package/dist/types/adapters.d.ts +152 -0
  251. package/dist/types/adapters.d.ts.map +1 -0
  252. package/dist/types/adapters.js +2 -0
  253. package/dist/types/adapters.js.map +1 -0
  254. package/dist/types/admin-auth.d.ts +132 -0
  255. package/dist/types/admin-auth.d.ts.map +1 -0
  256. package/dist/types/admin-auth.js +2 -0
  257. package/dist/types/admin-auth.js.map +1 -0
  258. package/dist/types/admin.d.ts +86 -0
  259. package/dist/types/admin.d.ts.map +1 -0
  260. package/dist/types/admin.js +2 -0
  261. package/dist/types/admin.js.map +1 -0
  262. package/dist/types/app-config.d.ts +279 -0
  263. package/dist/types/app-config.d.ts.map +1 -0
  264. package/dist/types/app-config.js +2 -0
  265. package/dist/types/app-config.js.map +1 -0
  266. package/dist/types/documents.d.ts +65 -0
  267. package/dist/types/documents.d.ts.map +1 -0
  268. package/dist/types/documents.js +2 -0
  269. package/dist/types/documents.js.map +1 -0
  270. package/dist/types/hooks.d.ts +122 -0
  271. package/dist/types/hooks.d.ts.map +1 -0
  272. package/dist/types/hooks.js +2 -0
  273. package/dist/types/hooks.js.map +1 -0
  274. package/dist/types/index.d.ts +13 -0
  275. package/dist/types/index.d.ts.map +1 -0
  276. package/dist/types/index.js +13 -0
  277. package/dist/types/index.js.map +1 -0
  278. package/dist/types/request.d.ts +42 -0
  279. package/dist/types/request.d.ts.map +1 -0
  280. package/dist/types/request.js +2 -0
  281. package/dist/types/request.js.map +1 -0
  282. package/dist/types/schema-config.d.ts +443 -0
  283. package/dist/types/schema-config.d.ts.map +1 -0
  284. package/dist/types/schema-config.js +2 -0
  285. package/dist/types/schema-config.js.map +1 -0
  286. package/dist/types/schema-core.d.ts +628 -0
  287. package/dist/types/schema-core.d.ts.map +1 -0
  288. package/dist/types/schema-core.js +2 -0
  289. package/dist/types/schema-core.js.map +1 -0
  290. package/dist/types/schema-inference.d.ts +73 -0
  291. package/dist/types/schema-inference.d.ts.map +1 -0
  292. package/dist/types/schema-inference.js +2 -0
  293. package/dist/types/schema-inference.js.map +1 -0
  294. package/dist/types/workflows.d.ts +121 -0
  295. package/dist/types/workflows.d.ts.map +1 -0
  296. package/dist/types/workflows.js +7 -0
  297. package/dist/types/workflows.js.map +1 -0
  298. package/dist/utils/access-control.d.ts +35 -0
  299. package/dist/utils/access-control.d.ts.map +1 -0
  300. package/dist/utils/access-control.js +161 -0
  301. package/dist/utils/access-control.js.map +1 -0
  302. package/dist/utils/admin-auth.d.ts +5 -0
  303. package/dist/utils/admin-auth.d.ts.map +1 -0
  304. package/dist/utils/admin-auth.js +39 -0
  305. package/dist/utils/admin-auth.js.map +1 -0
  306. package/dist/utils/block-references.d.ts +10 -0
  307. package/dist/utils/block-references.d.ts.map +1 -0
  308. package/dist/utils/block-references.js +100 -0
  309. package/dist/utils/block-references.js.map +1 -0
  310. package/dist/utils/collection-search.d.ts +11 -0
  311. package/dist/utils/collection-search.d.ts.map +1 -0
  312. package/dist/utils/collection-search.js +204 -0
  313. package/dist/utils/collection-search.js.map +1 -0
  314. package/dist/utils/config.d.ts +8 -0
  315. package/dist/utils/config.d.ts.map +1 -0
  316. package/dist/utils/config.js +336 -0
  317. package/dist/utils/config.js.map +1 -0
  318. package/dist/utils/hooks.d.ts +41 -0
  319. package/dist/utils/hooks.d.ts.map +1 -0
  320. package/dist/utils/hooks.js +177 -0
  321. package/dist/utils/hooks.js.map +1 -0
  322. package/dist/utils/openapi.d.ts +6 -0
  323. package/dist/utils/openapi.d.ts.map +1 -0
  324. package/dist/utils/openapi.js +981 -0
  325. package/dist/utils/openapi.js.map +1 -0
  326. package/dist/utils/parse-sort.d.ts +43 -0
  327. package/dist/utils/parse-sort.d.ts.map +1 -0
  328. package/dist/utils/parse-sort.js +70 -0
  329. package/dist/utils/parse-sort.js.map +1 -0
  330. package/dist/utils/parse-where.d.ts +69 -0
  331. package/dist/utils/parse-where.d.ts.map +1 -0
  332. package/dist/utils/parse-where.js +202 -0
  333. package/dist/utils/parse-where.js.map +1 -0
  334. package/dist/utils/readonly-db.d.ts +9 -0
  335. package/dist/utils/readonly-db.d.ts.map +1 -0
  336. package/dist/utils/readonly-db.js +21 -0
  337. package/dist/utils/readonly-db.js.map +1 -0
  338. package/dist/utils/swagger.d.ts +11 -0
  339. package/dist/utils/swagger.d.ts.map +1 -0
  340. package/dist/utils/swagger.js +62 -0
  341. package/dist/utils/swagger.js.map +1 -0
  342. package/dist/utils/upload-validation.d.ts +23 -0
  343. package/dist/utils/upload-validation.d.ts.map +1 -0
  344. package/dist/utils/upload-validation.js +46 -0
  345. package/dist/utils/upload-validation.js.map +1 -0
  346. package/dist/utils/where-sanitizer.d.ts +10 -0
  347. package/dist/utils/where-sanitizer.d.ts.map +1 -0
  348. package/dist/utils/where-sanitizer.js +67 -0
  349. package/dist/utils/where-sanitizer.js.map +1 -0
  350. package/dist/workflows.d.ts +86 -0
  351. package/dist/workflows.d.ts.map +1 -0
  352. package/dist/workflows.js +405 -0
  353. package/dist/workflows.js.map +1 -0
  354. package/package.json +1 -1
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=access-features.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access-features.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/access-features.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,159 @@
1
+ import { beforeAll, describe, expect, it } from "vitest";
2
+ import { createDyrectedApp } from "../app.js";
3
+ import { signCollectionToken } from "../auth/token.js";
4
+ import { defineCollection, defineConfig } from "../index.js";
5
+ import { InMemoryAdapter } from "./mocks.js";
6
+ beforeAll(() => {
7
+ process.env.DYRECTED_JWT_SECRET = "test-secret";
8
+ });
9
+ async function adminHeaders(sub = "admin-1") {
10
+ const token = await signCollectionToken({ sub, email: `${sub}@example.com`, collection: "users" });
11
+ return { Authorization: `Bearer ${token}` };
12
+ }
13
+ describe("readAudit access", () => {
14
+ it("gates the audit log independently of read", async () => {
15
+ const db = new InMemoryAdapter();
16
+ db.seed("users", [{ id: "admin-1", email: "admin-1@example.com", roles: ["admin"] }]);
17
+ const app = await createDyrectedApp(defineConfig({
18
+ db,
19
+ globals: [],
20
+ collections: [
21
+ defineCollection({ slug: "users", auth: true, fields: [{ name: "email", type: "email" }, { name: "roles", type: "select", hasMany: true, options: ["admin"] }] }),
22
+ defineCollection({
23
+ slug: "posts",
24
+ audit: true,
25
+ access: {
26
+ read: true, // anyone can read documents
27
+ readAudit: "'admin' in user.roles", // but only admins can read the audit trail
28
+ },
29
+ fields: [{ name: "title", type: "text" }],
30
+ }),
31
+ ],
32
+ }));
33
+ // Anyone can read documents...
34
+ const listRes = await app.request("/api/collections/posts");
35
+ expect(listRes.status).toBe(200);
36
+ // ...but an anonymous caller cannot read the audit log.
37
+ const anonAudit = await app.request("/api/collections/posts/__audit");
38
+ expect(anonAudit.status).toBe(403);
39
+ // An admin can.
40
+ const adminAudit = await app.request("/api/collections/posts/__audit", { headers: await adminHeaders() });
41
+ expect(adminAudit.status).toBe(200);
42
+ });
43
+ it("falls back to the read rule when readAudit is not set", async () => {
44
+ const db = new InMemoryAdapter();
45
+ const app = await createDyrectedApp(defineConfig({
46
+ db,
47
+ globals: [],
48
+ collections: [
49
+ defineCollection({
50
+ slug: "posts",
51
+ audit: true,
52
+ access: { read: "user != null" }, // audit inherits this
53
+ fields: [{ name: "title", type: "text" }],
54
+ }),
55
+ ],
56
+ }));
57
+ const anon = await app.request("/api/collections/posts/__audit");
58
+ expect(anon.status).toBe(403);
59
+ });
60
+ });
61
+ describe("field create access", () => {
62
+ it("applies the create rule on create and the update rule on update", async () => {
63
+ const db = new InMemoryAdapter();
64
+ const app = await createDyrectedApp(defineConfig({
65
+ db,
66
+ globals: [],
67
+ collections: [
68
+ defineCollection({
69
+ slug: "posts",
70
+ fields: [
71
+ { name: "title", type: "text" },
72
+ // Settable only at creation time; ignored on later updates.
73
+ { name: "refCode", type: "text", access: { create: true, update: false } },
74
+ // Cannot be set at creation; editable afterward.
75
+ { name: "reviewNote", type: "text", access: { create: false } },
76
+ ],
77
+ }),
78
+ ],
79
+ }));
80
+ const createRes = await app.request("/api/collections/posts", {
81
+ method: "POST",
82
+ headers: { "Content-Type": "application/json" },
83
+ body: JSON.stringify({ title: "T", refCode: "ABC", reviewNote: "should be dropped" }),
84
+ });
85
+ expect(createRes.status).toBe(201);
86
+ const created = await createRes.json();
87
+ expect(created.refCode).toBe("ABC"); // create allowed
88
+ expect(created.reviewNote).toBeUndefined(); // create denied → dropped
89
+ const updateRes = await app.request(`/api/collections/posts/${created.id}`, {
90
+ method: "PATCH",
91
+ headers: { "Content-Type": "application/json" },
92
+ body: JSON.stringify({ refCode: "CHANGED", reviewNote: "now allowed" }),
93
+ });
94
+ expect(updateRes.status).toBe(200);
95
+ const stored = await db.findOne({ collection: "posts", id: created.id });
96
+ expect(stored?.refCode).toBe("ABC"); // update denied → unchanged
97
+ expect(stored?.reviewNote).toBe("now allowed"); // update allowed (no update rule)
98
+ });
99
+ });
100
+ describe("string-valued named policies", () => {
101
+ it("resolves a Jexl-string policy for row-level access", async () => {
102
+ const db = new InMemoryAdapter();
103
+ db.seed("users", [{ id: "user-1", email: "user1@example.com", roles: [] }]);
104
+ db.seed("posts", [
105
+ { id: "post-1", title: "Mine", owner: "user-1" },
106
+ { id: "post-2", title: "Theirs", owner: "user-2" },
107
+ ]);
108
+ const app = await createDyrectedApp(defineConfig({
109
+ db,
110
+ accessPolicies: {
111
+ ownDocs: "{ owner: { equals: user.sub } }",
112
+ },
113
+ globals: [],
114
+ collections: [
115
+ defineCollection({ slug: "users", auth: true, fields: [{ name: "email", type: "email" }] }),
116
+ defineCollection({
117
+ slug: "posts",
118
+ access: { read: { policy: "ownDocs" } },
119
+ fields: [{ name: "title", type: "text" }, { name: "owner", type: "text" }],
120
+ }),
121
+ ],
122
+ }));
123
+ const token = await signCollectionToken({ sub: "user-1", email: "user1@example.com", collection: "users" });
124
+ const headers = { Authorization: `Bearer ${token}` };
125
+ const listRes = await app.request("/api/collections/posts", { headers });
126
+ const list = await listRes.json();
127
+ expect(list.docs).toHaveLength(1);
128
+ expect(list.docs[0].id).toBe("post-1");
129
+ });
130
+ it("inlines a string policy into the admin schema so it can be evaluated live", async () => {
131
+ const db = new InMemoryAdapter();
132
+ const app = await createDyrectedApp(defineConfig({
133
+ db,
134
+ accessPolicies: {
135
+ isAdmin: "'admin' in user.roles",
136
+ alwaysDeny: false,
137
+ },
138
+ globals: [],
139
+ collections: [
140
+ defineCollection({
141
+ slug: "posts",
142
+ access: { create: { policy: "isAdmin" } },
143
+ fields: [
144
+ { name: "title", type: "text" },
145
+ { name: "secret", type: "text", access: { read: { policy: "alwaysDeny" } } },
146
+ ],
147
+ }),
148
+ ],
149
+ }));
150
+ const res = await app.request("/api/schemas");
151
+ const data = await res.json();
152
+ // The string policy is inlined as its Jexl expression, not collapsed to a boolean.
153
+ expect(data.collections[0].access.create).toBe("'admin' in user.roles");
154
+ // The boolean policy resolves to its literal value.
155
+ const secret = data.collections[0].fields.find((f) => f.name === "secret");
156
+ expect(secret.access.read).toBe(false);
157
+ });
158
+ });
159
+ //# sourceMappingURL=access-features.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access-features.test.js","sourceRoot":"","sources":["../../src/__tests__/access-features.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,SAAS,CAAC,GAAG,EAAE;IACb,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,aAAa,CAAC;AAClD,CAAC,CAAC,CAAC;AAEH,KAAK,UAAU,YAAY,CAAC,GAAG,GAAG,SAAS;IACzC,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,GAAG,cAAc,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;IACnG,OAAO,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,CAAC;AAC9C,CAAC;AAED,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,2CAA2C,EAAE,KAAK,IAAI,EAAE;QACzD,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;QACjC,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,qBAAqB,EAAE,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QAEtF,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,YAAY,CAAC;YAC/C,EAAE;YACF,OAAO,EAAE,EAAE;YACX,WAAW,EAAE;gBACX,gBAAgB,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;gBACjK,gBAAgB,CAAC;oBACf,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE,IAAI;oBACX,MAAM,EAAE;wBACN,IAAI,EAAE,IAAI,EAAE,4BAA4B;wBACxC,SAAS,EAAE,uBAAuB,EAAE,2CAA2C;qBAChF;oBACD,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;iBAC1C,CAAC;aACH;SACF,CAAC,CAAC,CAAC;QAEJ,+BAA+B;QAC/B,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC;QAC5D,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEjC,wDAAwD;QACxD,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC;QACtE,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEnC,gBAAgB;QAChB,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,gCAAgC,EAAE,EAAE,OAAO,EAAE,MAAM,YAAY,EAAE,EAAE,CAAC,CAAC;QAC1G,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,YAAY,CAAC;YAC/C,EAAE;YACF,OAAO,EAAE,EAAE;YACX,WAAW,EAAE;gBACX,gBAAgB,CAAC;oBACf,IAAI,EAAE,OAAO;oBACb,KAAK,EAAE,IAAI;oBACX,MAAM,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,sBAAsB;oBACxD,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;iBAC1C,CAAC;aACH;SACF,CAAC,CAAC,CAAC;QAEJ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC;QACjE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC/E,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,YAAY,CAAC;YAC/C,EAAE;YACF,OAAO,EAAE,EAAE;YACX,WAAW,EAAE;gBACX,gBAAgB,CAAC;oBACf,IAAI,EAAE,OAAO;oBACb,MAAM,EAAE;wBACN,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE;wBAC/B,4DAA4D;wBAC5D,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;wBAC1E,iDAAiD;wBACjD,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;qBAChE;iBACF,CAAC;aACH;SACF,CAAC,CAAC,CAAC;QAEJ,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,wBAAwB,EAAE;YAC5D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAE,CAAC;SACtF,CAAC,CAAC;QACH,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;QACvC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,iBAAiB;QACtD,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,0BAA0B;QAEtE,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,0BAA0B,OAAO,CAAC,EAAE,EAAE,EAAE;YAC1E,MAAM,EAAE,OAAO;YACf,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,CAAC;SACxE,CAAC,CAAC;QACH,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;QACzE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,4BAA4B;QACjE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,kCAAkC;IACpF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,8BAA8B,EAAE,GAAG,EAAE;IAC5C,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QAClE,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;QACjC,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5E,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE;YACf,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE;YAChD,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;SACnD,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,YAAY,CAAC;YAC/C,EAAE;YACF,cAAc,EAAE;gBACd,OAAO,EAAE,iCAAiC;aAC3C;YACD,OAAO,EAAE,EAAE;YACX,WAAW,EAAE;gBACX,gBAAgB,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;gBAC3F,gBAAgB,CAAC;oBACf,IAAI,EAAE,OAAO;oBACb,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE;oBACvC,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;iBAC3E,CAAC;aACH;SACF,CAAC,CAAC,CAAC;QAEJ,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;QAC5G,MAAM,OAAO,GAAG,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,CAAC;QAErD,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,wBAAwB,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QACzE,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2EAA2E,EAAE,KAAK,IAAI,EAAE;QACzF,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,YAAY,CAAC;YAC/C,EAAE;YACF,cAAc,EAAE;gBACd,OAAO,EAAE,uBAAuB;gBAChC,UAAU,EAAE,KAAK;aAClB;YACD,OAAO,EAAE,EAAE;YACX,WAAW,EAAE;gBACX,gBAAgB,CAAC;oBACf,IAAI,EAAE,OAAO;oBACb,MAAM,EAAE,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE;oBACzC,MAAM,EAAE;wBACN,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE;wBAC/B,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,EAAE;qBAC7E;iBACF,CAAC;aACH;SACF,CAAC,CAAC,CAAC;QAEJ,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,mFAAmF;QACnF,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACxE,oDAAoD;QACpD,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;QAChF,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=access-parity.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access-parity.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/access-parity.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,338 @@
1
+ import { beforeAll, describe, expect, it } from "vitest";
2
+ import { createDyrectedApp } from "../app.js";
3
+ import { signCollectionToken } from "../auth/token.js";
4
+ import { defineCollection, defineConfig, defineGlobal } from "../index.js";
5
+ import { InMemoryAdapter } from "./mocks.js";
6
+ beforeAll(() => {
7
+ process.env.DYRECTED_JWT_SECRET = "test-secret";
8
+ });
9
+ describe("access-control parity", () => {
10
+ it("enforces row-level collection access on list, read, update, and delete", async () => {
11
+ const db = new InMemoryAdapter();
12
+ db.seed("users", [
13
+ { id: "user-1", email: "user1@example.com", roles: ["editor"] },
14
+ { id: "user-2", email: "user2@example.com", roles: ["editor"] },
15
+ ]);
16
+ db.seed("posts", [
17
+ { id: "post-1", title: "Mine", owner: "user-1" },
18
+ { id: "post-2", title: "Theirs", owner: "user-2" },
19
+ ]);
20
+ const app = await createDyrectedApp(defineConfig({
21
+ db,
22
+ collections: [
23
+ defineCollection({
24
+ slug: "users",
25
+ auth: true,
26
+ fields: [{ name: "email", type: "email" }, { name: "roles", type: "select", hasMany: true, options: ["editor"] }],
27
+ }),
28
+ defineCollection({
29
+ slug: "posts",
30
+ access: {
31
+ read: ({ user }) => ({ owner: { equals: user?.sub } }),
32
+ update: ({ user }) => ({ owner: { equals: user?.sub } }),
33
+ delete: ({ user }) => ({ owner: { equals: user?.sub } }),
34
+ },
35
+ fields: [
36
+ { name: "title", type: "text" },
37
+ { name: "owner", type: "text" },
38
+ ],
39
+ }),
40
+ ],
41
+ globals: [],
42
+ }));
43
+ const token = await signCollectionToken({
44
+ sub: "user-1",
45
+ email: "user1@example.com",
46
+ collection: "users",
47
+ });
48
+ const headers = { Authorization: `Bearer ${token}` };
49
+ const listRes = await app.request("/api/collections/posts", { headers });
50
+ expect(listRes.status).toBe(200);
51
+ const listData = await listRes.json();
52
+ expect(listData.docs).toHaveLength(1);
53
+ expect(listData.docs[0].id).toBe("post-1");
54
+ const ownRes = await app.request("/api/collections/posts/post-1", { headers });
55
+ expect(ownRes.status).toBe(200);
56
+ const otherRes = await app.request("/api/collections/posts/post-2", { headers });
57
+ expect(otherRes.status).toBe(403);
58
+ const updateOtherRes = await app.request("/api/collections/posts/post-2", {
59
+ method: "PATCH",
60
+ headers: { ...headers, "Content-Type": "application/json" },
61
+ body: JSON.stringify({ title: "Nope" }),
62
+ });
63
+ expect(updateOtherRes.status).toBe(403);
64
+ const deleteOtherRes = await app.request("/api/collections/posts/post-2", {
65
+ method: "DELETE",
66
+ headers,
67
+ });
68
+ expect(deleteOtherRes.status).toBe(403);
69
+ const updateOwnRes = await app.request("/api/collections/posts/post-1", {
70
+ method: "PATCH",
71
+ headers: { ...headers, "Content-Type": "application/json" },
72
+ body: JSON.stringify({ title: "Updated" }),
73
+ });
74
+ expect(updateOwnRes.status).toBe(200);
75
+ const updated = await db.findOne({ collection: "posts", id: "post-1" });
76
+ expect(updated?.title).toBe("Updated");
77
+ });
78
+ it("enforces row-level collection access from Jexl filter strings", async () => {
79
+ const db = new InMemoryAdapter();
80
+ db.seed("users", [
81
+ { id: "user-1", email: "user1@example.com", roles: ["editor"] },
82
+ { id: "user-2", email: "user2@example.com", roles: ["editor"] },
83
+ ]);
84
+ db.seed("posts", [
85
+ { id: "post-1", title: "Mine", owner: "user-1" },
86
+ { id: "post-2", title: "Theirs", owner: "user-2" },
87
+ ]);
88
+ const app = await createDyrectedApp(defineConfig({
89
+ db,
90
+ collections: [
91
+ defineCollection({
92
+ slug: "users",
93
+ auth: true,
94
+ fields: [{ name: "email", type: "email" }, { name: "roles", type: "select", hasMany: true, options: ["editor"] }],
95
+ }),
96
+ defineCollection({
97
+ slug: "posts",
98
+ access: {
99
+ read: "{ owner: { equals: user.sub } }",
100
+ update: "{ owner: { equals: user.sub } }",
101
+ delete: "{ owner: { equals: user.sub } }",
102
+ },
103
+ fields: [
104
+ { name: "title", type: "text" },
105
+ { name: "owner", type: "text" },
106
+ ],
107
+ }),
108
+ ],
109
+ globals: [],
110
+ }));
111
+ const token = await signCollectionToken({
112
+ sub: "user-1",
113
+ email: "user1@example.com",
114
+ collection: "users",
115
+ });
116
+ const headers = { Authorization: `Bearer ${token}` };
117
+ const listRes = await app.request("/api/collections/posts", { headers });
118
+ expect(listRes.status).toBe(200);
119
+ const listData = await listRes.json();
120
+ expect(listData.docs).toHaveLength(1);
121
+ expect(listData.docs[0].id).toBe("post-1");
122
+ const ownRes = await app.request("/api/collections/posts/post-1", { headers });
123
+ expect(ownRes.status).toBe(200);
124
+ const otherRes = await app.request("/api/collections/posts/post-2", { headers });
125
+ expect(otherRes.status).toBe(403);
126
+ });
127
+ it("enforces field read and write access on the API", async () => {
128
+ const db = new InMemoryAdapter();
129
+ const app = await createDyrectedApp(defineConfig({
130
+ db,
131
+ collections: [
132
+ defineCollection({
133
+ slug: "posts",
134
+ fields: [
135
+ { name: "title", type: "text" },
136
+ {
137
+ name: "secret",
138
+ type: "text",
139
+ access: {
140
+ read: false,
141
+ update: false,
142
+ },
143
+ },
144
+ {
145
+ name: "settings",
146
+ type: "object",
147
+ fields: [
148
+ { name: "visible", type: "text" },
149
+ { name: "hidden", type: "text", access: { read: false, update: false } },
150
+ ],
151
+ },
152
+ ],
153
+ }),
154
+ ],
155
+ globals: [],
156
+ }));
157
+ const createRes = await app.request("/api/collections/posts", {
158
+ method: "POST",
159
+ headers: { "Content-Type": "application/json" },
160
+ body: JSON.stringify({
161
+ title: "Post",
162
+ secret: "top-secret",
163
+ settings: { visible: "ok", hidden: "blocked" },
164
+ }),
165
+ });
166
+ expect(createRes.status).toBe(201);
167
+ const created = await createRes.json();
168
+ expect(created.secret).toBeUndefined();
169
+ expect(created.settings).toEqual({ visible: "ok" });
170
+ const stored = await db.find({ collection: "posts", limit: 10 });
171
+ expect(stored.docs[0].secret).toBeUndefined();
172
+ expect(stored.docs[0].settings).toEqual({ visible: "ok" });
173
+ const updateRes = await app.request(`/api/collections/posts/${stored.docs[0].id}`, {
174
+ method: "PATCH",
175
+ headers: { "Content-Type": "application/json" },
176
+ body: JSON.stringify({
177
+ secret: "changed",
178
+ settings: { visible: "still-ok", hidden: "still-blocked" },
179
+ }),
180
+ });
181
+ expect(updateRes.status).toBe(200);
182
+ const updated = await updateRes.json();
183
+ expect(updated.secret).toBeUndefined();
184
+ expect(updated.settings).toEqual({ visible: "still-ok" });
185
+ const fetchedRes = await app.request(`/api/collections/posts/${stored.docs[0].id}`);
186
+ expect(fetchedRes.status).toBe(200);
187
+ const fetched = await fetchedRes.json();
188
+ expect(fetched.secret).toBeUndefined();
189
+ expect(fetched.settings).toEqual({ visible: "still-ok" });
190
+ });
191
+ it("passes document id into field access rules on API updates", async () => {
192
+ const db = new InMemoryAdapter();
193
+ const app = await createDyrectedApp(defineConfig({
194
+ db,
195
+ collections: [
196
+ defineCollection({
197
+ slug: "posts",
198
+ fields: [
199
+ { name: "title", type: "text" },
200
+ {
201
+ name: "slug",
202
+ type: "text",
203
+ access: {
204
+ update: "!id",
205
+ },
206
+ },
207
+ ],
208
+ }),
209
+ ],
210
+ globals: [],
211
+ }));
212
+ const createRes = await app.request("/api/collections/posts", {
213
+ method: "POST",
214
+ headers: { "Content-Type": "application/json" },
215
+ body: JSON.stringify({
216
+ title: "Post",
217
+ slug: "original",
218
+ }),
219
+ });
220
+ expect(createRes.status).toBe(201);
221
+ const created = await createRes.json();
222
+ expect(created.slug).toBe("original");
223
+ const updateRes = await app.request(`/api/collections/posts/${created.id}`, {
224
+ method: "PATCH",
225
+ headers: { "Content-Type": "application/json" },
226
+ body: JSON.stringify({
227
+ slug: "changed",
228
+ }),
229
+ });
230
+ expect(updateRes.status).toBe(200);
231
+ const updated = await updateRes.json();
232
+ expect(updated.slug).toBe("original");
233
+ const stored = await db.findOne({ collection: "posts", id: created.id });
234
+ expect(stored?.slug).toBe("original");
235
+ });
236
+ it("evaluates global access against doc and incoming data", async () => {
237
+ const db = new InMemoryAdapter();
238
+ await db.updateGlobal({
239
+ slug: "settings",
240
+ data: { siteName: "Public", visibility: "public", locked: true },
241
+ });
242
+ const app = await createDyrectedApp(defineConfig({
243
+ db,
244
+ collections: [],
245
+ globals: [
246
+ defineGlobal({
247
+ slug: "settings",
248
+ access: {
249
+ read: ({ doc }) => doc?.visibility === "public",
250
+ update: ({ data }) => data?.locked !== false,
251
+ },
252
+ fields: [
253
+ { name: "siteName", type: "text" },
254
+ { name: "visibility", type: "text" },
255
+ { name: "locked", type: "boolean" },
256
+ ],
257
+ }),
258
+ ],
259
+ }));
260
+ const getRes = await app.request("/api/globals/settings");
261
+ expect(getRes.status).toBe(200);
262
+ const deniedUpdateRes = await app.request("/api/globals/settings", {
263
+ method: "PATCH",
264
+ headers: { "Content-Type": "application/json" },
265
+ body: JSON.stringify({ locked: false }),
266
+ });
267
+ expect(deniedUpdateRes.status).toBe(403);
268
+ const allowedUpdateRes = await app.request("/api/globals/settings", {
269
+ method: "PATCH",
270
+ headers: { "Content-Type": "application/json" },
271
+ body: JSON.stringify({ siteName: "Updated", locked: true }),
272
+ });
273
+ expect(allowedUpdateRes.status).toBe(200);
274
+ const global = await db.getGlobal({ slug: "settings" });
275
+ expect(global).toMatchObject({ siteName: "Updated", locked: true });
276
+ });
277
+ it("evaluates global access from Jexl against doc and incoming data", async () => {
278
+ const db = new InMemoryAdapter();
279
+ await db.updateGlobal({
280
+ slug: "settings",
281
+ data: { siteName: "Public", visibility: "public", locked: true },
282
+ });
283
+ const app = await createDyrectedApp(defineConfig({
284
+ db,
285
+ collections: [],
286
+ globals: [
287
+ defineGlobal({
288
+ slug: "settings",
289
+ access: {
290
+ read: "doc.visibility == 'public'",
291
+ update: "data.locked != false",
292
+ },
293
+ fields: [
294
+ { name: "siteName", type: "text" },
295
+ { name: "visibility", type: "text" },
296
+ { name: "locked", type: "boolean" },
297
+ ],
298
+ }),
299
+ ],
300
+ }));
301
+ const getRes = await app.request("/api/globals/settings");
302
+ expect(getRes.status).toBe(200);
303
+ const deniedUpdateRes = await app.request("/api/globals/settings", {
304
+ method: "PATCH",
305
+ headers: { "Content-Type": "application/json" },
306
+ body: JSON.stringify({ locked: false }),
307
+ });
308
+ expect(deniedUpdateRes.status).toBe(403);
309
+ const allowedUpdateRes = await app.request("/api/globals/settings", {
310
+ method: "PATCH",
311
+ headers: { "Content-Type": "application/json" },
312
+ body: JSON.stringify({ siteName: "Updated", locked: true }),
313
+ });
314
+ expect(allowedUpdateRes.status).toBe(200);
315
+ });
316
+ it("collapses document-scoped schema access to false", async () => {
317
+ const app = await createDyrectedApp(defineConfig({
318
+ db: new InMemoryAdapter(),
319
+ collections: [
320
+ defineCollection({
321
+ slug: "posts",
322
+ access: {
323
+ read: ({ user }) => ({ owner: { equals: user?.sub } }),
324
+ create: "user != null",
325
+ },
326
+ fields: [{ name: "title", type: "text" }],
327
+ }),
328
+ ],
329
+ globals: [],
330
+ }));
331
+ const res = await app.request("/api/schemas");
332
+ expect(res.status).toBe(200);
333
+ const data = await res.json();
334
+ expect(data.collections[0].access.read).toBe(false);
335
+ expect(data.collections[0].access.create).toBe("user != null");
336
+ });
337
+ });
338
+ //# sourceMappingURL=access-parity.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access-parity.test.js","sourceRoot":"","sources":["../../src/__tests__/access-parity.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,SAAS,CAAC,GAAG,EAAE;IACb,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,aAAa,CAAC;AAClD,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,uBAAuB,EAAE,GAAG,EAAE;IACrC,EAAE,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;QACtF,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;QACjC,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE;YACf,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE;YAC/D,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE;SAChE,CAAC,CAAC;QACH,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE;YACf,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE;YAChD,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;SACnD,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,YAAY,CAAC;YAC/C,EAAE;YACF,WAAW,EAAE;gBACX,gBAAgB,CAAC;oBACf,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,IAAI;oBACV,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC;iBAClH,CAAC;gBACF,gBAAgB,CAAC;oBACf,IAAI,EAAE,OAAO;oBACb,MAAM,EAAE;wBACN,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;wBACtD,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;wBACxD,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;qBACzD;oBACD,MAAM,EAAE;wBACN,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE;wBAC/B,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE;qBAChC;iBACF,CAAC;aACH;YACD,OAAO,EAAE,EAAE;SACZ,CAAC,CAAC,CAAC;QAEJ,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC;YACtC,GAAG,EAAE,QAAQ;YACb,KAAK,EAAE,mBAAmB;YAC1B,UAAU,EAAE,OAAO;SACpB,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,CAAC;QAErD,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,wBAAwB,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QACzE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;QACtC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACtC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAE3C,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,+BAA+B,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAC/E,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEhC,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,+BAA+B,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QACjF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAElC,MAAM,cAAc,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,+BAA+B,EAAE;YACxE,MAAM,EAAE,OAAO;YACf,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC3D,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;SACxC,CAAC,CAAC;QACH,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAExC,MAAM,cAAc,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,+BAA+B,EAAE;YACxE,MAAM,EAAE,QAAQ;YAChB,OAAO;SACR,CAAC,CAAC;QACH,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAExC,MAAM,YAAY,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,+BAA+B,EAAE;YACtE,MAAM,EAAE,OAAO;YACf,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC3D,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;SAC3C,CAAC,CAAC;QACH,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEtC,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;QACxE,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC7E,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;QACjC,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE;YACf,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE;YAC/D,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE;SAChE,CAAC,CAAC;QACH,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE;YACf,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE;YAChD,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;SACnD,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,YAAY,CAAC;YAC/C,EAAE;YACF,WAAW,EAAE;gBACX,gBAAgB,CAAC;oBACf,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,IAAI;oBACV,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC;iBAClH,CAAC;gBACF,gBAAgB,CAAC;oBACf,IAAI,EAAE,OAAO;oBACb,MAAM,EAAE;wBACN,IAAI,EAAE,iCAAiC;wBACvC,MAAM,EAAE,iCAAiC;wBACzC,MAAM,EAAE,iCAAiC;qBAC1C;oBACD,MAAM,EAAE;wBACN,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE;wBAC/B,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE;qBAChC;iBACF,CAAC;aACH;YACD,OAAO,EAAE,EAAE;SACZ,CAAC,CAAC,CAAC;QAEJ,MAAM,KAAK,GAAG,MAAM,mBAAmB,CAAC;YACtC,GAAG,EAAE,QAAQ;YACb,KAAK,EAAE,mBAAmB;YAC1B,UAAU,EAAE,OAAO;SACpB,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,aAAa,EAAE,UAAU,KAAK,EAAE,EAAE,CAAC;QAErD,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,wBAAwB,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QACzE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;QACtC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACtC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAE3C,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,+BAA+B,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QAC/E,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEhC,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,+BAA+B,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;QACjF,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;QAC/D,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;QAEjC,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,YAAY,CAAC;YAC/C,EAAE;YACF,WAAW,EAAE;gBACX,gBAAgB,CAAC;oBACf,IAAI,EAAE,OAAO;oBACb,MAAM,EAAE;wBACN,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE;wBAC/B;4BACE,IAAI,EAAE,QAAQ;4BACd,IAAI,EAAE,MAAM;4BACZ,MAAM,EAAE;gCACN,IAAI,EAAE,KAAK;gCACX,MAAM,EAAE,KAAK;6BACd;yBACF;wBACD;4BACE,IAAI,EAAE,UAAU;4BAChB,IAAI,EAAE,QAAQ;4BACd,MAAM,EAAE;gCACN,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE;gCACjC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;6BACzE;yBACF;qBACF;iBACF,CAAC;aACH;YACD,OAAO,EAAE,EAAE;SACZ,CAAC,CAAC,CAAC;QAEJ,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,wBAAwB,EAAE;YAC5D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,MAAM;gBACb,MAAM,EAAE,YAAY;gBACpB,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE;aAC/C,CAAC;SACH,CAAC,CAAC;QACH,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;QACvC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,aAAa,EAAE,CAAC;QACvC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAEpD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QACjE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,aAAa,EAAE,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAE3D,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,0BAA0B,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE;YACjF,MAAM,EAAE,OAAO;YACf,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,MAAM,EAAE,SAAS;gBACjB,QAAQ,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,eAAe,EAAE;aAC3D,CAAC;SACH,CAAC,CAAC;QACH,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;QACvC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,aAAa,EAAE,CAAC;QACvC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;QAE1D,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,0BAA0B,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACpF,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,CAAC;QACxC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,aAAa,EAAE,CAAC;QACvC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;QAEjC,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,YAAY,CAAC;YAC/C,EAAE;YACF,WAAW,EAAE;gBACX,gBAAgB,CAAC;oBACf,IAAI,EAAE,OAAO;oBACb,MAAM,EAAE;wBACN,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE;wBAC/B;4BACE,IAAI,EAAE,MAAM;4BACZ,IAAI,EAAE,MAAM;4BACZ,MAAM,EAAE;gCACN,MAAM,EAAE,KAAK;6BACd;yBACF;qBACF;iBACF,CAAC;aACH;YACD,OAAO,EAAE,EAAE;SACZ,CAAC,CAAC,CAAC;QAEJ,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,wBAAwB,EAAE;YAC5D,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,MAAM;gBACb,IAAI,EAAE,UAAU;aACjB,CAAC;SACH,CAAC,CAAC;QACH,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;QACvC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAEtC,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,0BAA0B,OAAO,CAAC,EAAE,EAAE,EAAE;YAC1E,MAAM,EAAE,OAAO;YACf,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,IAAI,EAAE,SAAS;aAChB,CAAC;SACH,CAAC,CAAC;QACH,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,CAAC;QACvC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAEtC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;QACzE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;QACjC,MAAM,EAAE,CAAC,YAAY,CAAC;YACpB,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE;SACjE,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,YAAY,CAAC;YAC/C,EAAE;YACF,WAAW,EAAE,EAAE;YACf,OAAO,EAAE;gBACP,YAAY,CAAC;oBACX,IAAI,EAAE,UAAU;oBAChB,MAAM,EAAE;wBACN,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,QAAQ;wBAC/C,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK;qBAC7C;oBACD,MAAM,EAAE;wBACN,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE;wBAClC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE;wBACpC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE;qBACpC;iBACF,CAAC;aACH;SACF,CAAC,CAAC,CAAC;QAEJ,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;QAC1D,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEhC,MAAM,eAAe,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,uBAAuB,EAAE;YACjE,MAAM,EAAE,OAAO;YACf,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;SACxC,CAAC,CAAC;QACH,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEzC,MAAM,gBAAgB,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,uBAAuB,EAAE;YAClE,MAAM,EAAE,OAAO;YACf,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;SAC5D,CAAC,CAAC;QACH,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC/E,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;QACjC,MAAM,EAAE,CAAC,YAAY,CAAC;YACpB,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE;SACjE,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,YAAY,CAAC;YAC/C,EAAE;YACF,WAAW,EAAE,EAAE;YACf,OAAO,EAAE;gBACP,YAAY,CAAC;oBACX,IAAI,EAAE,UAAU;oBAChB,MAAM,EAAE;wBACN,IAAI,EAAE,4BAA4B;wBAClC,MAAM,EAAE,sBAAsB;qBAC/B;oBACD,MAAM,EAAE;wBACN,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE;wBAClC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE;wBACpC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE;qBACpC;iBACF,CAAC;aACH;SACF,CAAC,CAAC,CAAC;QAEJ,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC;QAC1D,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEhC,MAAM,eAAe,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,uBAAuB,EAAE;YACjE,MAAM,EAAE,OAAO;YACf,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;SACxC,CAAC,CAAC;QACH,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEzC,MAAM,gBAAgB,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,uBAAuB,EAAE;YAClE,MAAM,EAAE,OAAO;YACf,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;SAC5D,CAAC,CAAC;QACH,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;QAChE,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,YAAY,CAAC;YAC/C,EAAE,EAAE,IAAI,eAAe,EAAE;YACzB,WAAW,EAAE;gBACX,gBAAgB,CAAC;oBACf,IAAI,EAAE,OAAO;oBACb,MAAM,EAAE;wBACN,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;wBACtD,MAAM,EAAE,cAAc;qBACvB;oBACD,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;iBAC1C,CAAC;aACH;YACD,OAAO,EAAE,EAAE;SACZ,CAAC,CAAC,CAAC;QAEJ,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAC9C,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpD,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=access.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/access.test.ts"],"names":[],"mappings":""}