@dyrected/core 2.6.3 → 2.6.4

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 (352) 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.d.ts +35 -0
  122. package/dist/app.d.ts.map +1 -0
  123. package/dist/app.js +164 -0
  124. package/dist/app.js.map +1 -0
  125. package/dist/auth/access.d.ts +5 -0
  126. package/dist/auth/access.d.ts.map +1 -0
  127. package/dist/auth/access.js +59 -0
  128. package/dist/auth/access.js.map +1 -0
  129. package/dist/auth/jexl.d.ts +13 -0
  130. package/dist/auth/jexl.d.ts.map +1 -0
  131. package/dist/auth/jexl.js +30 -0
  132. package/dist/auth/jexl.js.map +1 -0
  133. package/dist/auth/lockout.d.ts +11 -0
  134. package/dist/auth/lockout.d.ts.map +1 -0
  135. package/dist/auth/lockout.js +37 -0
  136. package/dist/auth/lockout.js.map +1 -0
  137. package/dist/auth/password.d.ts +10 -0
  138. package/dist/auth/password.d.ts.map +1 -0
  139. package/dist/auth/password.js +28 -0
  140. package/dist/auth/password.js.map +1 -0
  141. package/dist/auth/sessions.d.ts +39 -0
  142. package/dist/auth/sessions.d.ts.map +1 -0
  143. package/dist/auth/sessions.js +126 -0
  144. package/dist/auth/sessions.js.map +1 -0
  145. package/dist/auth/token.d.ts +23 -0
  146. package/dist/auth/token.d.ts.map +1 -0
  147. package/dist/auth/token.js +40 -0
  148. package/dist/auth/token.js.map +1 -0
  149. package/dist/chunk-23NM4LDU.js +2883 -0
  150. package/dist/chunk-2TKDCCIR.js +2622 -0
  151. package/dist/chunk-3SFITPX4.js +2628 -0
  152. package/dist/chunk-CQVTQ67D.js +2632 -0
  153. package/dist/chunk-ELHRRPKX.js +2863 -0
  154. package/dist/chunk-HRLSFTLR.js +3061 -0
  155. package/dist/chunk-QTIAQBNH.js +3097 -0
  156. package/dist/chunk-T2DGC4MD.js +3008 -0
  157. package/dist/chunk-TLU77TLE.js +3203 -0
  158. package/dist/chunk-YEBCT77K.js +3269 -0
  159. package/dist/chunk-YXEKNN5X.js +3085 -0
  160. package/dist/controllers/admin-auth.controller.d.ts +71 -0
  161. package/dist/controllers/admin-auth.controller.d.ts.map +1 -0
  162. package/dist/controllers/admin-auth.controller.js +450 -0
  163. package/dist/controllers/admin-auth.controller.js.map +1 -0
  164. package/dist/controllers/audit.controller.d.ts +42 -0
  165. package/dist/controllers/audit.controller.d.ts.map +1 -0
  166. package/dist/controllers/audit.controller.js +149 -0
  167. package/dist/controllers/audit.controller.js.map +1 -0
  168. package/dist/controllers/auth.controller.d.ts +143 -0
  169. package/dist/controllers/auth.controller.d.ts.map +1 -0
  170. package/dist/controllers/auth.controller.js +572 -0
  171. package/dist/controllers/auth.controller.js.map +1 -0
  172. package/dist/controllers/collection.controller.d.ts +170 -0
  173. package/dist/controllers/collection.controller.d.ts.map +1 -0
  174. package/dist/controllers/collection.controller.js +1033 -0
  175. package/dist/controllers/collection.controller.js.map +1 -0
  176. package/dist/controllers/global.controller.d.ts +20 -0
  177. package/dist/controllers/global.controller.d.ts.map +1 -0
  178. package/dist/controllers/global.controller.js +182 -0
  179. package/dist/controllers/global.controller.js.map +1 -0
  180. package/dist/controllers/media.controller.d.ts +39 -0
  181. package/dist/controllers/media.controller.d.ts.map +1 -0
  182. package/dist/controllers/media.controller.js +178 -0
  183. package/dist/controllers/media.controller.js.map +1 -0
  184. package/dist/controllers/preview.controller.d.ts +37 -0
  185. package/dist/controllers/preview.controller.d.ts.map +1 -0
  186. package/dist/controllers/preview.controller.js +48 -0
  187. package/dist/controllers/preview.controller.js.map +1 -0
  188. package/dist/index.cjs +707 -27
  189. package/dist/index.d.cts +77 -5
  190. package/dist/index.d.ts +77 -5
  191. package/dist/index.d.ts.map +1 -0
  192. package/dist/index.js +37 -1
  193. package/dist/index.js.map +1 -0
  194. package/dist/middleware/auth.d.ts +19 -0
  195. package/dist/middleware/auth.d.ts.map +1 -0
  196. package/dist/middleware/auth.js +157 -0
  197. package/dist/middleware/auth.js.map +1 -0
  198. package/dist/middleware/rate-limit.d.ts +9 -0
  199. package/dist/middleware/rate-limit.d.ts.map +1 -0
  200. package/dist/middleware/rate-limit.js +75 -0
  201. package/dist/middleware/rate-limit.js.map +1 -0
  202. package/dist/network.d.ts +6 -0
  203. package/dist/network.d.ts.map +1 -0
  204. package/dist/network.js +70 -0
  205. package/dist/network.js.map +1 -0
  206. package/dist/observability.d.ts +113 -0
  207. package/dist/observability.d.ts.map +1 -0
  208. package/dist/observability.js +497 -0
  209. package/dist/observability.js.map +1 -0
  210. package/dist/router.d.ts +8 -0
  211. package/dist/router.d.ts.map +1 -0
  212. package/dist/router.js +704 -0
  213. package/dist/router.js.map +1 -0
  214. package/dist/server.cjs +861 -54
  215. package/dist/server.d.cts +9 -1
  216. package/dist/server.d.ts +9 -1
  217. package/dist/server.d.ts.map +1 -0
  218. package/dist/server.js +189 -26
  219. package/dist/server.js.map +1 -0
  220. package/dist/services/audit.service.d.ts +23 -0
  221. package/dist/services/audit.service.d.ts.map +1 -0
  222. package/dist/services/audit.service.js +39 -0
  223. package/dist/services/audit.service.js.map +1 -0
  224. package/dist/services/defaults.service.d.ts +8 -0
  225. package/dist/services/defaults.service.d.ts.map +1 -0
  226. package/dist/services/defaults.service.js +55 -0
  227. package/dist/services/defaults.service.js.map +1 -0
  228. package/dist/services/email-template.d.ts +46 -0
  229. package/dist/services/email-template.d.ts.map +1 -0
  230. package/dist/services/email-template.js +88 -0
  231. package/dist/services/email-template.js.map +1 -0
  232. package/dist/services/email.service.d.ts +34 -0
  233. package/dist/services/email.service.d.ts.map +1 -0
  234. package/dist/services/email.service.js +129 -0
  235. package/dist/services/email.service.js.map +1 -0
  236. package/dist/services/media.service.d.ts +20 -0
  237. package/dist/services/media.service.d.ts.map +1 -0
  238. package/dist/services/media.service.js +49 -0
  239. package/dist/services/media.service.js.map +1 -0
  240. package/dist/services/population.service.d.ts +20 -0
  241. package/dist/services/population.service.d.ts.map +1 -0
  242. package/dist/services/population.service.js +224 -0
  243. package/dist/services/population.service.js.map +1 -0
  244. package/dist/types/access.d.ts +48 -0
  245. package/dist/types/access.d.ts.map +1 -0
  246. package/dist/types/access.js +2 -0
  247. package/dist/types/access.js.map +1 -0
  248. package/dist/types/adapters.d.ts +152 -0
  249. package/dist/types/adapters.d.ts.map +1 -0
  250. package/dist/types/adapters.js +2 -0
  251. package/dist/types/adapters.js.map +1 -0
  252. package/dist/types/admin-auth.d.ts +132 -0
  253. package/dist/types/admin-auth.d.ts.map +1 -0
  254. package/dist/types/admin-auth.js +2 -0
  255. package/dist/types/admin-auth.js.map +1 -0
  256. package/dist/types/admin.d.ts +86 -0
  257. package/dist/types/admin.d.ts.map +1 -0
  258. package/dist/types/admin.js +2 -0
  259. package/dist/types/admin.js.map +1 -0
  260. package/dist/types/app-config.d.ts +279 -0
  261. package/dist/types/app-config.d.ts.map +1 -0
  262. package/dist/types/app-config.js +2 -0
  263. package/dist/types/app-config.js.map +1 -0
  264. package/dist/types/documents.d.ts +65 -0
  265. package/dist/types/documents.d.ts.map +1 -0
  266. package/dist/types/documents.js +2 -0
  267. package/dist/types/documents.js.map +1 -0
  268. package/dist/types/hooks.d.ts +122 -0
  269. package/dist/types/hooks.d.ts.map +1 -0
  270. package/dist/types/hooks.js +2 -0
  271. package/dist/types/hooks.js.map +1 -0
  272. package/dist/types/index.d.ts +13 -0
  273. package/dist/types/index.d.ts.map +1 -0
  274. package/dist/types/index.js +13 -0
  275. package/dist/types/index.js.map +1 -0
  276. package/dist/types/request.d.ts +42 -0
  277. package/dist/types/request.d.ts.map +1 -0
  278. package/dist/types/request.js +2 -0
  279. package/dist/types/request.js.map +1 -0
  280. package/dist/types/schema-config.d.ts +443 -0
  281. package/dist/types/schema-config.d.ts.map +1 -0
  282. package/dist/types/schema-config.js +2 -0
  283. package/dist/types/schema-config.js.map +1 -0
  284. package/dist/types/schema-core.d.ts +628 -0
  285. package/dist/types/schema-core.d.ts.map +1 -0
  286. package/dist/types/schema-core.js +2 -0
  287. package/dist/types/schema-core.js.map +1 -0
  288. package/dist/types/schema-inference.d.ts +73 -0
  289. package/dist/types/schema-inference.d.ts.map +1 -0
  290. package/dist/types/schema-inference.js +2 -0
  291. package/dist/types/schema-inference.js.map +1 -0
  292. package/dist/types/workflows.d.ts +121 -0
  293. package/dist/types/workflows.d.ts.map +1 -0
  294. package/dist/types/workflows.js +7 -0
  295. package/dist/types/workflows.js.map +1 -0
  296. package/dist/utils/access-control.d.ts +35 -0
  297. package/dist/utils/access-control.d.ts.map +1 -0
  298. package/dist/utils/access-control.js +161 -0
  299. package/dist/utils/access-control.js.map +1 -0
  300. package/dist/utils/admin-auth.d.ts +5 -0
  301. package/dist/utils/admin-auth.d.ts.map +1 -0
  302. package/dist/utils/admin-auth.js +39 -0
  303. package/dist/utils/admin-auth.js.map +1 -0
  304. package/dist/utils/block-references.d.ts +10 -0
  305. package/dist/utils/block-references.d.ts.map +1 -0
  306. package/dist/utils/block-references.js +100 -0
  307. package/dist/utils/block-references.js.map +1 -0
  308. package/dist/utils/collection-search.d.ts +11 -0
  309. package/dist/utils/collection-search.d.ts.map +1 -0
  310. package/dist/utils/collection-search.js +204 -0
  311. package/dist/utils/collection-search.js.map +1 -0
  312. package/dist/utils/config.d.ts +8 -0
  313. package/dist/utils/config.d.ts.map +1 -0
  314. package/dist/utils/config.js +336 -0
  315. package/dist/utils/config.js.map +1 -0
  316. package/dist/utils/hooks.d.ts +41 -0
  317. package/dist/utils/hooks.d.ts.map +1 -0
  318. package/dist/utils/hooks.js +177 -0
  319. package/dist/utils/hooks.js.map +1 -0
  320. package/dist/utils/openapi.d.ts +6 -0
  321. package/dist/utils/openapi.d.ts.map +1 -0
  322. package/dist/utils/openapi.js +981 -0
  323. package/dist/utils/openapi.js.map +1 -0
  324. package/dist/utils/parse-sort.d.ts +43 -0
  325. package/dist/utils/parse-sort.d.ts.map +1 -0
  326. package/dist/utils/parse-sort.js +70 -0
  327. package/dist/utils/parse-sort.js.map +1 -0
  328. package/dist/utils/parse-where.d.ts +69 -0
  329. package/dist/utils/parse-where.d.ts.map +1 -0
  330. package/dist/utils/parse-where.js +202 -0
  331. package/dist/utils/parse-where.js.map +1 -0
  332. package/dist/utils/readonly-db.d.ts +9 -0
  333. package/dist/utils/readonly-db.d.ts.map +1 -0
  334. package/dist/utils/readonly-db.js +21 -0
  335. package/dist/utils/readonly-db.js.map +1 -0
  336. package/dist/utils/swagger.d.ts +11 -0
  337. package/dist/utils/swagger.d.ts.map +1 -0
  338. package/dist/utils/swagger.js +62 -0
  339. package/dist/utils/swagger.js.map +1 -0
  340. package/dist/utils/upload-validation.d.ts +23 -0
  341. package/dist/utils/upload-validation.d.ts.map +1 -0
  342. package/dist/utils/upload-validation.js +46 -0
  343. package/dist/utils/upload-validation.js.map +1 -0
  344. package/dist/utils/where-sanitizer.d.ts +10 -0
  345. package/dist/utils/where-sanitizer.d.ts.map +1 -0
  346. package/dist/utils/where-sanitizer.js +67 -0
  347. package/dist/utils/where-sanitizer.js.map +1 -0
  348. package/dist/workflows.d.ts +86 -0
  349. package/dist/workflows.d.ts.map +1 -0
  350. package/dist/workflows.js +405 -0
  351. package/dist/workflows.js.map +1 -0
  352. package/package.json +1 -1
@@ -0,0 +1,402 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { defineBlock, defineBlocksField, defineConfig, defineCollection, defineGlobal, defineRichTextField, defineTextField, normalizeConfig, } from "../index.js";
3
+ import { MockDatabaseAdapter } from "./mocks.js";
4
+ describe("Configuration Helpers", () => {
5
+ it("only accepts valid Lucide names for admin navigation icons", () => {
6
+ const icon = "Newspaper";
7
+ // @ts-expect-error — invalid names must fail during configuration authoring.
8
+ const invalidIcon = "DefinitelyNotALucideIcon";
9
+ expect(icon).toBe("Newspaper");
10
+ expect(invalidIcon).toBe("DefinitelyNotALucideIcon");
11
+ });
12
+ it("should define a collection correctly", () => {
13
+ const posts = defineCollection({
14
+ slug: "posts",
15
+ fields: [{ name: "title", type: "text", label: "Title", required: true }],
16
+ });
17
+ expect(posts.slug).toBe("posts");
18
+ expect(posts.fields[0].name).toBe("title");
19
+ });
20
+ it("should define a global correctly", () => {
21
+ const navbar = defineGlobal({
22
+ slug: "navbar",
23
+ fields: [{ name: "logo", type: "text", label: "Logo" }],
24
+ });
25
+ expect(navbar.slug).toBe("navbar");
26
+ });
27
+ it("should define a main config correctly", () => {
28
+ const config = defineConfig({
29
+ collections: [],
30
+ globals: [],
31
+ db: new MockDatabaseAdapter(),
32
+ });
33
+ expect(config.collections).toEqual([]);
34
+ expect(config.db).toBeInstanceOf(MockDatabaseAdapter);
35
+ });
36
+ it("re-asserts email/password integrity constraints on an auth collection even when redefined", () => {
37
+ const normalized = normalizeConfig(defineConfig({
38
+ collections: [
39
+ defineCollection({
40
+ slug: "users",
41
+ auth: true,
42
+ fields: [
43
+ // Developer redefines email without `unique` — it must not be silently dropped.
44
+ { name: "email", type: "email", label: "Work email" },
45
+ { name: "password", type: "text" },
46
+ ],
47
+ }),
48
+ ],
49
+ globals: [],
50
+ db: new MockDatabaseAdapter(),
51
+ }));
52
+ const users = normalized.collections.find((c) => c.slug === "users");
53
+ const email = users.fields.find((f) => f.name === "email");
54
+ const password = users.fields.find((f) => f.name === "password");
55
+ expect(email.unique).toBe(true);
56
+ expect(email.required).toBe(true);
57
+ expect(email.promoted).toBe(true);
58
+ expect(email.access?.update).toBe("!id");
59
+ // Developer customization (label) is preserved.
60
+ expect(email.label).toBe("Work email");
61
+ expect(password.required).toBe(true);
62
+ expect(password.access?.update).toBe("!id || user.id == id");
63
+ });
64
+ it("rejects components passed directly into admin.components configuration (type test)", () => {
65
+ const FakeComponent = () => "div";
66
+ const validDashboard = defineConfig({
67
+ collections: [],
68
+ globals: [],
69
+ db: new MockDatabaseAdapter(),
70
+ admin: {
71
+ components: {
72
+ beforeDashboard: ["custom-banner"],
73
+ },
74
+ },
75
+ });
76
+ const invalidDashboard = defineConfig({
77
+ collections: [],
78
+ globals: [],
79
+ db: new MockDatabaseAdapter(),
80
+ admin: {
81
+ components: {
82
+ // @ts-expect-error — must be an array of strings
83
+ beforeDashboard: [FakeComponent],
84
+ // @ts-expect-error — must be an array of strings
85
+ afterDashboard: FakeComponent,
86
+ },
87
+ },
88
+ });
89
+ const validCollection = defineCollection({
90
+ slug: "posts",
91
+ fields: [],
92
+ admin: {
93
+ components: {
94
+ beforeList: ["custom-header"],
95
+ beforeListTable: ["custom-filters"],
96
+ afterListTable: ["custom-footer"],
97
+ afterList: ["custom-pagination"],
98
+ },
99
+ },
100
+ });
101
+ const invalidCollection = defineCollection({
102
+ slug: "posts",
103
+ fields: [],
104
+ admin: {
105
+ components: {
106
+ // @ts-expect-error — must be an array of strings
107
+ beforeList: [FakeComponent],
108
+ },
109
+ },
110
+ });
111
+ expect(validDashboard.admin?.components?.beforeDashboard).toEqual([
112
+ "custom-banner",
113
+ ]);
114
+ expect(validCollection.admin?.components?.beforeList).toEqual([
115
+ "custom-header",
116
+ ]);
117
+ });
118
+ it("type-checks collection admin field references against declared top-level fields", () => {
119
+ const valid = defineCollection({
120
+ slug: "articles",
121
+ fields: [
122
+ { name: "title", type: "text", label: "Title" },
123
+ { name: "summary", type: "textarea", label: "Summary" },
124
+ { name: "author", type: "relationship", label: "Author", relationTo: "authors" },
125
+ ],
126
+ admin: {
127
+ useAsTitle: "title",
128
+ defaultColumns: ["title", "summary"],
129
+ searchableFields: ["title", "summary", "author"],
130
+ },
131
+ });
132
+ const invalid = defineCollection({
133
+ slug: "articles-invalid",
134
+ fields: [
135
+ { name: "title", type: "text", label: "Title" },
136
+ { name: "summary", type: "textarea", label: "Summary" },
137
+ ],
138
+ admin: {
139
+ // @ts-expect-error -- must match a declared top-level field name
140
+ useAsTitle: "headline",
141
+ // @ts-expect-error -- every column must match a declared top-level field name
142
+ defaultColumns: ["title", "headline"],
143
+ // @ts-expect-error -- every searchable field must match a declared top-level field name
144
+ searchableFields: ["summary", "seoTitle"],
145
+ },
146
+ });
147
+ expect(valid.admin?.useAsTitle).toBe("title");
148
+ expect(valid.admin?.defaultColumns).toEqual(["title", "summary"]);
149
+ expect(valid.admin?.searchableFields).toEqual(["title", "summary", "author"]);
150
+ expect(invalid.admin?.useAsTitle).toBe("headline");
151
+ });
152
+ it("type-checks nested array/object admin.useAsTitle against declared child fields", () => {
153
+ const valid = defineCollection({
154
+ slug: "pages",
155
+ fields: [
156
+ {
157
+ name: "links",
158
+ type: "array",
159
+ label: "Links",
160
+ admin: { useAsTitle: "label" },
161
+ fields: [
162
+ { name: "label", type: "text", label: "Label" },
163
+ { name: "url", type: "text", label: "URL" },
164
+ ],
165
+ },
166
+ {
167
+ name: "seo",
168
+ type: "object",
169
+ label: "SEO",
170
+ admin: { useAsTitle: "title" },
171
+ fields: [
172
+ { name: "title", type: "text", label: "Meta title" },
173
+ { name: "description", type: "textarea", label: "Meta description" },
174
+ ],
175
+ },
176
+ ],
177
+ });
178
+ const invalid = defineCollection({
179
+ slug: "pages-invalid",
180
+ fields: [
181
+ {
182
+ name: "links",
183
+ type: "array",
184
+ label: "Links",
185
+ // @ts-expect-error -- nested admin.useAsTitle must match a declared child field name
186
+ admin: { useAsTitle: "headline" },
187
+ fields: [
188
+ { name: "label", type: "text", label: "Label" },
189
+ { name: "url", type: "text", label: "URL" },
190
+ ],
191
+ },
192
+ ],
193
+ });
194
+ expect(valid.fields[0].admin?.useAsTitle).toBe("label");
195
+ expect(valid.fields[1].admin?.useAsTitle).toBe("title");
196
+ expect(invalid.fields[0].admin?.useAsTitle).toBe("headline");
197
+ });
198
+ it("normalizes drafts: true to simplePublishingWorkflow", () => {
199
+ const normalized = normalizeConfig(defineConfig({
200
+ collections: [
201
+ defineCollection({
202
+ slug: "posts",
203
+ drafts: true,
204
+ fields: [],
205
+ }),
206
+ ],
207
+ globals: [],
208
+ db: new MockDatabaseAdapter(),
209
+ }));
210
+ const posts = normalized.collections.find((c) => c.slug === "posts");
211
+ expect(posts.workflow).toBeDefined();
212
+ expect(posts.workflow?.initialState).toBe("draft");
213
+ expect(posts.workflow?.states.map((s) => s.name)).toEqual([
214
+ "draft",
215
+ "published",
216
+ ]);
217
+ });
218
+ it("resolves blockReferences from the root reusable block registry", () => {
219
+ const HeroBlock = defineBlock({
220
+ slug: "hero",
221
+ fields: [defineTextField({ name: "heading", label: "Heading" })],
222
+ });
223
+ const normalized = normalizeConfig(defineConfig({
224
+ blocks: [HeroBlock],
225
+ collections: [
226
+ defineCollection({
227
+ slug: "pages",
228
+ fields: [
229
+ defineBlocksField({
230
+ name: "layout",
231
+ label: "Layout",
232
+ blockReferences: ["hero"],
233
+ }),
234
+ ],
235
+ }),
236
+ ],
237
+ globals: [],
238
+ db: new MockDatabaseAdapter(),
239
+ }));
240
+ const layoutField = normalized.collections
241
+ .find((c) => c.slug === "pages")
242
+ ?.fields.find((f) => f.name === "layout");
243
+ expect(layoutField?.type).toBe("blocks");
244
+ expect(layoutField?.blockReferences).toEqual(["hero"]);
245
+ expect(layoutField?.blocks?.map((block) => block.slug)).toEqual(["hero"]);
246
+ expect(layoutField?.blocks?.[0]?.fields[0]?.name).toBe("heading");
247
+ });
248
+ it("type-checks named access policies and cross-config string references", () => {
249
+ const HeroBlock = defineBlock({
250
+ slug: "hero",
251
+ fields: [
252
+ defineTextField({ name: "heading", label: "Heading" }),
253
+ defineRichTextField({
254
+ name: "content",
255
+ label: "Content",
256
+ uploadCollection: "media",
257
+ }),
258
+ ],
259
+ });
260
+ const Users = defineCollection({
261
+ slug: "users",
262
+ auth: true,
263
+ fields: [{ name: "name", type: "text", label: "Name" }],
264
+ });
265
+ const Media = defineCollection({
266
+ slug: "media",
267
+ upload: true,
268
+ fields: [{ name: "alt", type: "text", label: "Alt" }],
269
+ });
270
+ const Posts = defineCollection({
271
+ slug: "posts",
272
+ access: {
273
+ read: { policy: "canReadPosts" },
274
+ },
275
+ workflow: {
276
+ initialState: "draft",
277
+ states: [
278
+ { name: "draft", label: "Draft" },
279
+ { name: "published", label: "Published", published: true },
280
+ ],
281
+ transitions: [
282
+ {
283
+ name: "publish",
284
+ label: "Publish",
285
+ from: "draft",
286
+ to: "published",
287
+ },
288
+ ],
289
+ },
290
+ fields: [
291
+ {
292
+ name: "title",
293
+ type: "text",
294
+ label: "Title",
295
+ access: { read: { policy: "canReadPosts" } },
296
+ },
297
+ {
298
+ name: "author",
299
+ type: "relationship",
300
+ label: "Author",
301
+ relationTo: "users",
302
+ },
303
+ defineBlocksField({
304
+ name: "layout",
305
+ label: "Layout",
306
+ blockReferences: ["hero"],
307
+ }),
308
+ ],
309
+ });
310
+ const valid = defineConfig({
311
+ blocks: [HeroBlock],
312
+ collections: [Users, Media, Posts],
313
+ globals: [
314
+ defineGlobal({
315
+ slug: "settings",
316
+ access: { read: { policy: "canReadPosts" } },
317
+ fields: [
318
+ defineRichTextField({
319
+ name: "homepageBody",
320
+ label: "Homepage body",
321
+ uploadCollection: "media",
322
+ }),
323
+ ],
324
+ }),
325
+ ],
326
+ adminAuth: {
327
+ mode: "local",
328
+ collectionSlug: "users",
329
+ providers: [],
330
+ },
331
+ accessPolicies: {
332
+ canReadPosts: true,
333
+ },
334
+ db: new MockDatabaseAdapter(),
335
+ });
336
+ const invalid = defineConfig({
337
+ blocks: [HeroBlock],
338
+ collections: [
339
+ Users,
340
+ Media,
341
+ defineCollection({
342
+ slug: "articles",
343
+ access: {
344
+ // @ts-expect-error -- policy names must exist on accessPolicies
345
+ read: { policy: "missingPolicy" },
346
+ },
347
+ workflow: {
348
+ // @ts-expect-error -- initialState must exist in workflow.states
349
+ initialState: "queued",
350
+ states: [{ name: "draft", label: "Draft" }],
351
+ transitions: [
352
+ {
353
+ name: "publish",
354
+ label: "Publish",
355
+ // @ts-expect-error -- transition from/to values must reference workflow.states
356
+ from: "queued",
357
+ // @ts-expect-error -- transition from/to values must reference workflow.states
358
+ to: "published",
359
+ },
360
+ ],
361
+ },
362
+ fields: [
363
+ {
364
+ name: "author",
365
+ type: "relationship",
366
+ label: "Author",
367
+ // @ts-expect-error -- relationTo must match a configured collection slug
368
+ relationTo: "people",
369
+ },
370
+ defineBlocksField({
371
+ name: "layout",
372
+ label: "Layout",
373
+ // @ts-expect-error -- blockReferences must match defineConfig({ blocks })
374
+ blockReferences: ["cta"],
375
+ }),
376
+ defineRichTextField({
377
+ name: "body",
378
+ label: "Body",
379
+ // @ts-expect-error -- uploadCollection must reference an upload-enabled collection
380
+ uploadCollection: "users",
381
+ }),
382
+ ],
383
+ }),
384
+ ],
385
+ globals: [],
386
+ adminAuth: {
387
+ mode: "local",
388
+ // @ts-expect-error -- admin auth collectionSlug must reference an auth-enabled collection
389
+ collectionSlug: "media",
390
+ providers: [],
391
+ },
392
+ accessPolicies: {
393
+ canReadPosts: true,
394
+ },
395
+ db: new MockDatabaseAdapter(),
396
+ });
397
+ expect(valid.collections).toHaveLength(3);
398
+ expect(valid.adminAuth?.collectionSlug).toBe("users");
399
+ expect(invalid.adminAuth?.collectionSlug).toBe("media");
400
+ });
401
+ });
402
+ //# sourceMappingURL=config.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../src/__tests__/config.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=define-field.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-field.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/define-field.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,121 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { defineField, defineTextField, defineNumberField, defineBooleanField, defineRelationshipField, defineRichTextField, defineRowField, defineTab, defineBlock, defineBlocksField, defineCollection, } from "../index.js";
3
+ describe("define<Type>Field helpers", () => {
4
+ it("inject the field type at runtime and pass config through untouched", () => {
5
+ expect(defineTextField({ name: "title", required: true })).toEqual({
6
+ name: "title",
7
+ required: true,
8
+ type: "text",
9
+ });
10
+ expect(defineNumberField({ name: "price" })).toEqual({
11
+ name: "price",
12
+ type: "number",
13
+ });
14
+ expect(defineNumberField({ name: "rating", min: 1, max: 5 })).toEqual({
15
+ name: "rating",
16
+ type: "number",
17
+ min: 1,
18
+ max: 5,
19
+ });
20
+ expect(defineRichTextField({
21
+ name: "body",
22
+ features: ["bold", "italic", "link"],
23
+ })).toEqual({
24
+ name: "body",
25
+ type: "richText",
26
+ features: ["bold", "italic", "link"],
27
+ });
28
+ // layout-only field with no name
29
+ expect(defineRowField({ fields: [] })).toEqual({ type: "row", fields: [] });
30
+ });
31
+ it("defineTab stamps admin.tab on every field and preserves existing admin options", () => {
32
+ expect(defineTab({
33
+ label: "SEO",
34
+ fields: [
35
+ defineTextField({ name: "metaTitle" }),
36
+ defineTextField({
37
+ name: "metaDescription",
38
+ admin: { placeholder: "Summary" },
39
+ }),
40
+ ],
41
+ })).toEqual([
42
+ { name: "metaTitle", type: "text", admin: { tab: "SEO" } },
43
+ {
44
+ name: "metaDescription",
45
+ type: "text",
46
+ admin: { placeholder: "Summary", tab: "SEO" },
47
+ },
48
+ ]);
49
+ });
50
+ it("defineField returns the field unchanged (identity)", () => {
51
+ const field = { name: "slug", type: "text", required: true };
52
+ expect(defineField(field)).toBe(field);
53
+ });
54
+ it("defineBlock returns the block unchanged (identity)", () => {
55
+ const block = { slug: "hero", fields: [] };
56
+ expect(defineBlock(block)).toBe(block);
57
+ });
58
+ it("compose with defineCollection", () => {
59
+ const Posts = defineCollection({
60
+ slug: "posts",
61
+ fields: [
62
+ defineTextField({ name: "title", required: true }),
63
+ defineRichTextField({ name: "body" }),
64
+ defineBlocksField({
65
+ name: "layout",
66
+ blocks: [
67
+ defineBlock({
68
+ slug: "hero",
69
+ fields: [defineTextField({ name: "heading" })],
70
+ }),
71
+ ],
72
+ }),
73
+ ],
74
+ });
75
+ expect(Posts.slug).toBe("posts");
76
+ expect(Posts.fields.map((f) => f.type)).toEqual([
77
+ "text",
78
+ "richText",
79
+ "blocks",
80
+ ]);
81
+ });
82
+ });
83
+ /**
84
+ * Compile-time guards: these assignments only type-check if the per-type helpers
85
+ * preserve literal inference (name, required, hasMany, type) so that
86
+ * {@link InferDocShape} still derives the document shape correctly. A regression
87
+ * in the helper signatures would surface as a `tsc` error here.
88
+ */
89
+ const inferredFields = [
90
+ defineTextField({ name: "title", required: true }),
91
+ defineNumberField({ name: "views" }),
92
+ defineBooleanField({ name: "featured" }),
93
+ defineRelationshipField({
94
+ name: "authors",
95
+ relationTo: "users",
96
+ hasMany: true,
97
+ }),
98
+ defineRichTextField({ name: "body", required: true }),
99
+ ];
100
+ const _shapeOk = {
101
+ title: "hello", // required text -> string
102
+ views: 3, // optional number
103
+ featured: true, // optional boolean
104
+ authors: ["author-1"], // hasMany relationship -> string[]
105
+ body: "<p>hello</p>", // required richText -> HTML string
106
+ };
107
+ // @ts-expect-error `title` is required and cannot be omitted
108
+ const _requiredEnforced = {
109
+ views: 1,
110
+ body: "<p>hi</p>",
111
+ };
112
+ // `defineField` must preserve literals well enough for inference too.
113
+ const genericField = defineField({
114
+ name: "slug",
115
+ type: "text",
116
+ required: true,
117
+ });
118
+ const _genericOk = {
119
+ slug: "posts-are-great",
120
+ };
121
+ //# sourceMappingURL=define-field.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-field.test.js","sourceRoot":"","sources":["../../src/__tests__/define-field.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=deleteMany.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deleteMany.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/deleteMany.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,75 @@
1
+ import { describe, it, expect, beforeEach } from 'vitest';
2
+ import { createDyrectedApp } from '../app.js';
3
+ import { defineConfig, defineCollection } from '../index.js';
4
+ import { InMemoryAdapter } from './mocks.js';
5
+ describe('DELETE /delete-many', () => {
6
+ let db;
7
+ let app;
8
+ beforeEach(async () => {
9
+ db = new InMemoryAdapter();
10
+ db.seed('posts', [
11
+ { id: '1', title: 'Post 1' },
12
+ { id: '2', title: 'Post 2' },
13
+ { id: '3', title: 'Post 3' },
14
+ ]);
15
+ const config = defineConfig({
16
+ collections: [
17
+ defineCollection({ slug: 'posts', fields: [{ name: 'title', type: 'text' }] }),
18
+ ],
19
+ globals: [],
20
+ db,
21
+ });
22
+ app = await createDyrectedApp(config);
23
+ });
24
+ it('deletes all provided ids and returns the deleted list', async () => {
25
+ const res = await app.request('/api/collections/posts/delete-many', {
26
+ method: 'DELETE',
27
+ headers: { 'Content-Type': 'application/json' },
28
+ body: JSON.stringify({ ids: ['1', '2'] }),
29
+ });
30
+ const data = await res.json();
31
+ expect(res.status).toBe(200);
32
+ expect(data.deleted).toEqual(expect.arrayContaining(['1', '2']));
33
+ expect(data.deleted).toHaveLength(2);
34
+ // Verify docs are actually gone
35
+ const listRes = await app.request('/api/collections/posts');
36
+ const list = await listRes.json();
37
+ expect(list.total).toBe(1);
38
+ expect(list.docs[0].id).toBe('3');
39
+ });
40
+ it('returns 400 when no ids are provided', async () => {
41
+ const res = await app.request('/api/collections/posts/delete-many', {
42
+ method: 'DELETE',
43
+ headers: { 'Content-Type': 'application/json' },
44
+ body: JSON.stringify({ ids: [] }),
45
+ });
46
+ expect(res.status).toBe(400);
47
+ });
48
+ it('returns 400 when body is missing', async () => {
49
+ const res = await app.request('/api/collections/posts/delete-many', {
50
+ method: 'DELETE',
51
+ });
52
+ expect(res.status).toBe(400);
53
+ });
54
+ it('response shape includes deleted array and no failed key on full success', async () => {
55
+ const res = await app.request('/api/collections/posts/delete-many', {
56
+ method: 'DELETE',
57
+ headers: { 'Content-Type': 'application/json' },
58
+ body: JSON.stringify({ ids: ['1'] }),
59
+ });
60
+ const data = await res.json();
61
+ expect(data).toHaveProperty('message');
62
+ expect(data).toHaveProperty('deleted');
63
+ expect(data.failed).toBeUndefined();
64
+ });
65
+ it('deletes a single id', async () => {
66
+ const res = await app.request('/api/collections/posts/delete-many', {
67
+ method: 'DELETE',
68
+ headers: { 'Content-Type': 'application/json' },
69
+ body: JSON.stringify({ ids: ['3'] }),
70
+ });
71
+ const data = await res.json();
72
+ expect(data.deleted).toContain('3');
73
+ });
74
+ });
75
+ //# sourceMappingURL=deleteMany.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deleteMany.test.js","sourceRoot":"","sources":["../../src/__tests__/deleteMany.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=depth.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"depth.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/depth.test.ts"],"names":[],"mappings":""}