@dyrected/core 2.5.52 → 2.5.55
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.
- package/dist/{app-config-oOarB6Fw.d.cts → app-config-DqCipvSI.d.cts} +1 -1
- package/dist/{app-config-oOarB6Fw.d.ts → app-config-DqCipvSI.d.ts} +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/server.d.cts +1 -1
- package/dist/server.d.ts +1 -1
- package/package.json +1 -1
- package/dist/__tests__/admin-auth.test.d.ts +0 -2
- package/dist/__tests__/admin-auth.test.d.ts.map +0 -1
- package/dist/__tests__/admin-auth.test.js +0 -440
- package/dist/__tests__/admin-auth.test.js.map +0 -1
- package/dist/__tests__/app.test.d.ts +0 -2
- package/dist/__tests__/app.test.d.ts.map +0 -1
- package/dist/__tests__/app.test.js +0 -27
- package/dist/__tests__/app.test.js.map +0 -1
- package/dist/__tests__/config.test.d.ts +0 -2
- package/dist/__tests__/config.test.d.ts.map +0 -1
- package/dist/__tests__/config.test.js +0 -91
- package/dist/__tests__/config.test.js.map +0 -1
- package/dist/__tests__/deleteMany.test.d.ts +0 -2
- package/dist/__tests__/deleteMany.test.d.ts.map +0 -1
- package/dist/__tests__/deleteMany.test.js +0 -75
- package/dist/__tests__/deleteMany.test.js.map +0 -1
- package/dist/__tests__/depth.test.d.ts +0 -2
- package/dist/__tests__/depth.test.d.ts.map +0 -1
- package/dist/__tests__/depth.test.js +0 -81
- package/dist/__tests__/depth.test.js.map +0 -1
- package/dist/__tests__/dynamic-options.test.d.ts +0 -2
- package/dist/__tests__/dynamic-options.test.d.ts.map +0 -1
- package/dist/__tests__/dynamic-options.test.js +0 -132
- package/dist/__tests__/dynamic-options.test.js.map +0 -1
- package/dist/__tests__/email.service.test.d.ts +0 -2
- package/dist/__tests__/email.service.test.d.ts.map +0 -1
- package/dist/__tests__/email.service.test.js +0 -46
- package/dist/__tests__/email.service.test.js.map +0 -1
- package/dist/__tests__/field-inference.test-types.d.ts +0 -24
- package/dist/__tests__/field-inference.test-types.d.ts.map +0 -1
- package/dist/__tests__/field-inference.test-types.js +0 -87
- package/dist/__tests__/field-inference.test-types.js.map +0 -1
- package/dist/__tests__/fixtures/editorial-workflow.d.ts +0 -9
- package/dist/__tests__/fixtures/editorial-workflow.d.ts.map +0 -1
- package/dist/__tests__/fixtures/editorial-workflow.js +0 -12
- package/dist/__tests__/fixtures/editorial-workflow.js.map +0 -1
- package/dist/__tests__/hooks.test.d.ts +0 -2
- package/dist/__tests__/hooks.test.d.ts.map +0 -1
- package/dist/__tests__/hooks.test.js +0 -320
- package/dist/__tests__/hooks.test.js.map +0 -1
- package/dist/__tests__/mocks.d.ts +0 -74
- package/dist/__tests__/mocks.d.ts.map +0 -1
- package/dist/__tests__/mocks.js +0 -159
- package/dist/__tests__/mocks.js.map +0 -1
- package/dist/__tests__/openapi.test.d.ts +0 -2
- package/dist/__tests__/openapi.test.d.ts.map +0 -1
- package/dist/__tests__/openapi.test.js +0 -95
- package/dist/__tests__/openapi.test.js.map +0 -1
- package/dist/__tests__/parse-sort.test.d.ts +0 -2
- package/dist/__tests__/parse-sort.test.d.ts.map +0 -1
- package/dist/__tests__/parse-sort.test.js +0 -24
- package/dist/__tests__/parse-sort.test.js.map +0 -1
- package/dist/__tests__/preferences.test.d.ts +0 -2
- package/dist/__tests__/preferences.test.d.ts.map +0 -1
- package/dist/__tests__/preferences.test.js +0 -168
- package/dist/__tests__/preferences.test.js.map +0 -1
- package/dist/__tests__/router.test.d.ts +0 -2
- package/dist/__tests__/router.test.d.ts.map +0 -1
- package/dist/__tests__/router.test.js +0 -52
- package/dist/__tests__/router.test.js.map +0 -1
- package/dist/__tests__/where.test.d.ts +0 -2
- package/dist/__tests__/where.test.d.ts.map +0 -1
- package/dist/__tests__/where.test.js +0 -105
- package/dist/__tests__/where.test.js.map +0 -1
- package/dist/__tests__/workflow.test.d.ts +0 -2
- package/dist/__tests__/workflow.test.d.ts.map +0 -1
- package/dist/__tests__/workflow.test.js +0 -497
- package/dist/__tests__/workflow.test.js.map +0 -1
- package/dist/app-B2tg7Djj.d.cts +0 -1575
- package/dist/app-B2tg7Djj.d.ts +0 -1575
- package/dist/app-BElen1tP.d.cts +0 -1690
- package/dist/app-BElen1tP.d.ts +0 -1690
- package/dist/app-BOrsS7Tz.d.cts +0 -1771
- package/dist/app-BOrsS7Tz.d.ts +0 -1771
- package/dist/app-Bh4_Opv0.d.cts +0 -1522
- package/dist/app-Bh4_Opv0.d.ts +0 -1522
- package/dist/app-BibuoHQG.d.cts +0 -1764
- package/dist/app-BibuoHQG.d.ts +0 -1764
- package/dist/app-Bv9gaDAN.d.cts +0 -561
- package/dist/app-Bv9gaDAN.d.ts +0 -561
- package/dist/app-BvG3bRc8.d.cts +0 -419
- package/dist/app-BvG3bRc8.d.ts +0 -419
- package/dist/app-C-HgyliB.d.cts +0 -1694
- package/dist/app-C-HgyliB.d.ts +0 -1694
- package/dist/app-C3B9N1KR.d.cts +0 -1522
- package/dist/app-C3B9N1KR.d.ts +0 -1522
- package/dist/app-Cc2mG3zi.d.cts +0 -373
- package/dist/app-Cc2mG3zi.d.ts +0 -373
- package/dist/app-Ctfmo2Re.d.cts +0 -1692
- package/dist/app-Ctfmo2Re.d.ts +0 -1692
- package/dist/app-D0ffogDd.d.cts +0 -1690
- package/dist/app-D0ffogDd.d.ts +0 -1690
- package/dist/app-D2uR47gK.d.cts +0 -1690
- package/dist/app-D2uR47gK.d.ts +0 -1690
- package/dist/app-DDJJa0ep.d.cts +0 -1621
- package/dist/app-DDJJa0ep.d.ts +0 -1621
- package/dist/app-DO1s9YW1.d.cts +0 -1621
- package/dist/app-DO1s9YW1.d.ts +0 -1621
- package/dist/app-DTP3-9PJ.d.cts +0 -561
- package/dist/app-DTP3-9PJ.d.ts +0 -561
- package/dist/app-DZt5nslu.d.cts +0 -374
- package/dist/app-DZt5nslu.d.ts +0 -377
- package/dist/app-DbKDGYTI.d.cts +0 -566
- package/dist/app-DbKDGYTI.d.ts +0 -566
- package/dist/app-Dk3SzV1a.d.cts +0 -374
- package/dist/app-Dk3SzV1a.d.ts +0 -374
- package/dist/app-DnX9mNsh.d.cts +0 -374
- package/dist/app-DnX9mNsh.d.ts +0 -374
- package/dist/app-DqRO-CMi.d.cts +0 -1457
- package/dist/app-DqRO-CMi.d.ts +0 -1457
- package/dist/app-DvaFpOtj.d.cts +0 -398
- package/dist/app-DvaFpOtj.d.ts +0 -398
- package/dist/app-FGzip4XM.d.cts +0 -1563
- package/dist/app-FGzip4XM.d.ts +0 -1563
- package/dist/app-KApbf4XL.d.cts +0 -362
- package/dist/app-KApbf4XL.d.ts +0 -362
- package/dist/app-T0alZAE0.d.cts +0 -383
- package/dist/app-T0alZAE0.d.ts +0 -383
- package/dist/app-aW2FMuYM.d.cts +0 -1759
- package/dist/app-aW2FMuYM.d.ts +0 -1759
- package/dist/app-config-2vF6W56z.d.cts +0 -1335
- package/dist/app-config-2vF6W56z.d.ts +0 -1335
- package/dist/app-config-3XBnu9Xz.d.cts +0 -1379
- package/dist/app-config-3XBnu9Xz.d.ts +0 -1379
- package/dist/app-config-BLMX-9MN.d.cts +0 -1045
- package/dist/app-config-BLMX-9MN.d.ts +0 -1045
- package/dist/app-config-CaEQH0Kb.d.cts +0 -1383
- package/dist/app-config-CaEQH0Kb.d.ts +0 -1383
- package/dist/app-config-DLK6bCaP.d.cts +0 -1390
- package/dist/app-config-DLK6bCaP.d.ts +0 -1390
- package/dist/app-oQt5-9MU.d.cts +0 -1560
- package/dist/app-oQt5-9MU.d.ts +0 -1560
- package/dist/app-rZj1VFer.d.cts +0 -1621
- package/dist/app-rZj1VFer.d.ts +0 -1621
- package/dist/app-wo82JRHl.d.cts +0 -445
- package/dist/app-wo82JRHl.d.ts +0 -445
- package/dist/app.d.ts +0 -21
- package/dist/app.d.ts.map +0 -1
- package/dist/app.js +0 -56
- package/dist/app.js.map +0 -1
- package/dist/auth/jexl.d.ts +0 -10
- package/dist/auth/jexl.d.ts.map +0 -1
- package/dist/auth/jexl.js +0 -22
- package/dist/auth/jexl.js.map +0 -1
- package/dist/auth/password.d.ts +0 -10
- package/dist/auth/password.d.ts.map +0 -1
- package/dist/auth/password.js +0 -28
- package/dist/auth/password.js.map +0 -1
- package/dist/auth/token.d.ts +0 -22
- package/dist/auth/token.d.ts.map +0 -1
- package/dist/auth/token.js +0 -40
- package/dist/auth/token.js.map +0 -1
- package/dist/chunk-22JTWD74.js +0 -1784
- package/dist/chunk-23URSKPI.js +0 -2371
- package/dist/chunk-2JMA3M5S.js +0 -2475
- package/dist/chunk-3FZEUK36.js +0 -2470
- package/dist/chunk-3VUH2MNW.js +0 -1903
- package/dist/chunk-44O2LDPT.js +0 -1513
- package/dist/chunk-45JDQDA2.js +0 -1899
- package/dist/chunk-4C4L6SD2.js +0 -1524
- package/dist/chunk-4EDMZAM5.js +0 -2692
- package/dist/chunk-52T4RCFU.js +0 -1972
- package/dist/chunk-6ZXEGKT6.js +0 -619
- package/dist/chunk-7GGHK75W.js +0 -1835
- package/dist/chunk-ALNQINX7.js +0 -2496
- package/dist/chunk-B6KDKYXB.js +0 -2502
- package/dist/chunk-BEONZV6M.js +0 -1951
- package/dist/chunk-C4GEQ5RP.js +0 -1993
- package/dist/chunk-CQDVPMEU.js +0 -613
- package/dist/chunk-DOJHZ7XN.js +0 -2394
- package/dist/chunk-EH7G3LLL.js +0 -2065
- package/dist/chunk-EXXOPW3I.js +0 -2483
- package/dist/chunk-F4ZC6TXR.js +0 -2065
- package/dist/chunk-FCXE5CVC.js +0 -1528
- package/dist/chunk-FDQYPPG3.js +0 -2698
- package/dist/chunk-FURYJ254.mjs +0 -33
- package/dist/chunk-G2QQLBHW.js +0 -24
- package/dist/chunk-GM4WW6IE.js +0 -66
- package/dist/chunk-GZODLJ3C.js +0 -1861
- package/dist/chunk-IIY3E7Q7.js +0 -1996
- package/dist/chunk-JJN4J5NS.js +0 -2069
- package/dist/chunk-MRUHCNDM.js +0 -1940
- package/dist/chunk-NKDX67AW.js +0 -2698
- package/dist/chunk-NYUB4AHZ.js +0 -1951
- package/dist/chunk-OD4SLW7H.js +0 -1930
- package/dist/chunk-OE5MH3NB.js +0 -2070
- package/dist/chunk-PH36WQYS.js +0 -1875
- package/dist/chunk-PKNFV7KE.js +0 -2469
- package/dist/chunk-SUGK7UYL.js +0 -311
- package/dist/chunk-TIJHR54M.js +0 -1879
- package/dist/chunk-TUUHGLB5.js +0 -2609
- package/dist/chunk-UBTRANFX.js +0 -2476
- package/dist/chunk-VJWUG2XK.js +0 -1951
- package/dist/chunk-W6KURRMW.js +0 -2471
- package/dist/chunk-Y4AYI52W.js +0 -631
- package/dist/chunk-YDOBB7MY.js +0 -1457
- package/dist/chunk-YNJ3YC4N.js +0 -2483
- package/dist/chunk-ZFAOBRHT.js +0 -2709
- package/dist/controllers/admin-auth.controller.d.ts +0 -68
- package/dist/controllers/admin-auth.controller.d.ts.map +0 -1
- package/dist/controllers/admin-auth.controller.js +0 -414
- package/dist/controllers/admin-auth.controller.js.map +0 -1
- package/dist/controllers/auth.controller.d.ts +0 -125
- package/dist/controllers/auth.controller.d.ts.map +0 -1
- package/dist/controllers/auth.controller.js +0 -323
- package/dist/controllers/auth.controller.js.map +0 -1
- package/dist/controllers/collection.controller.d.ts +0 -157
- package/dist/controllers/collection.controller.d.ts.map +0 -1
- package/dist/controllers/collection.controller.js +0 -779
- package/dist/controllers/collection.controller.js.map +0 -1
- package/dist/controllers/global.controller.d.ts +0 -17
- package/dist/controllers/global.controller.d.ts.map +0 -1
- package/dist/controllers/global.controller.js +0 -132
- package/dist/controllers/global.controller.js.map +0 -1
- package/dist/controllers/media.controller.d.ts +0 -38
- package/dist/controllers/media.controller.d.ts.map +0 -1
- package/dist/controllers/media.controller.js +0 -162
- package/dist/controllers/media.controller.js.map +0 -1
- package/dist/controllers/preview.controller.d.ts +0 -37
- package/dist/controllers/preview.controller.d.ts.map +0 -1
- package/dist/controllers/preview.controller.js +0 -48
- package/dist/controllers/preview.controller.js.map +0 -1
- package/dist/index-BKYugiYp.d.cts +0 -1988
- package/dist/index-BKYugiYp.d.ts +0 -1988
- package/dist/index-BSWCiAen.d.cts +0 -1983
- package/dist/index-BSWCiAen.d.ts +0 -1983
- package/dist/index-BfLDb3b0.d.cts +0 -1467
- package/dist/index-BfLDb3b0.d.ts +0 -1467
- package/dist/index-Bi4sX_eC.d.cts +0 -1491
- package/dist/index-Bi4sX_eC.d.ts +0 -1491
- package/dist/index-Bp7PDOYG.d.cts +0 -1750
- package/dist/index-Bp7PDOYG.d.ts +0 -1750
- package/dist/index-ByXooLy-.d.cts +0 -1762
- package/dist/index-ByXooLy-.d.ts +0 -1762
- package/dist/index-C9Vp1DCT.d.cts +0 -1563
- package/dist/index-C9Vp1DCT.d.ts +0 -1563
- package/dist/index-CFezd8p1.d.cts +0 -1986
- package/dist/index-CFezd8p1.d.ts +0 -1986
- package/dist/index-CdQwnbfh.d.cts +0 -1889
- package/dist/index-CdQwnbfh.d.ts +0 -1889
- package/dist/index-D38_E0gf.d.cts +0 -336
- package/dist/index-D38_E0gf.d.ts +0 -336
- package/dist/index-DR2z1rrf.d.cts +0 -1503
- package/dist/index-DR2z1rrf.d.ts +0 -1503
- package/dist/index-DTrpTru7.d.cts +0 -1881
- package/dist/index-DTrpTru7.d.ts +0 -1881
- package/dist/index-DfAmTZXk.d.cts +0 -1749
- package/dist/index-DfAmTZXk.d.ts +0 -1749
- package/dist/index-DfkPT4NR.d.cts +0 -1584
- package/dist/index-DfkPT4NR.d.ts +0 -1584
- package/dist/index-DzUlE5Hc.d.cts +0 -1751
- package/dist/index-DzUlE5Hc.d.ts +0 -1751
- package/dist/index-M_m6dXZV.d.cts +0 -1889
- package/dist/index-M_m6dXZV.d.ts +0 -1889
- package/dist/index-RylhgOwj.d.cts +0 -340
- package/dist/index-RylhgOwj.d.ts +0 -340
- package/dist/index-qhLus8ZO.d.cts +0 -1881
- package/dist/index-qhLus8ZO.d.ts +0 -1881
- package/dist/index-xB1lMg79.d.cts +0 -1456
- package/dist/index-xB1lMg79.d.ts +0 -1456
- package/dist/index.d.mts +0 -417
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -1974
- package/dist/middleware/auth.d.ts +0 -18
- package/dist/middleware/auth.d.ts.map +0 -1
- package/dist/middleware/auth.js +0 -45
- package/dist/middleware/auth.js.map +0 -1
- package/dist/password-ACI2YUGZ.js +0 -8
- package/dist/router.d.ts +0 -8
- package/dist/router.d.ts.map +0 -1
- package/dist/router.js +0 -625
- package/dist/router.js.map +0 -1
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/services/audit.service.d.ts +0 -23
- package/dist/services/audit.service.d.ts.map +0 -1
- package/dist/services/audit.service.js +0 -28
- package/dist/services/audit.service.js.map +0 -1
- package/dist/services/defaults.service.d.ts +0 -8
- package/dist/services/defaults.service.d.ts.map +0 -1
- package/dist/services/defaults.service.js +0 -55
- package/dist/services/defaults.service.js.map +0 -1
- package/dist/services/email-template.d.ts +0 -46
- package/dist/services/email-template.d.ts.map +0 -1
- package/dist/services/email-template.js +0 -88
- package/dist/services/email-template.js.map +0 -1
- package/dist/services/email.service.d.ts +0 -33
- package/dist/services/email.service.d.ts.map +0 -1
- package/dist/services/email.service.js +0 -96
- package/dist/services/email.service.js.map +0 -1
- package/dist/services/media.service.d.ts +0 -20
- package/dist/services/media.service.d.ts.map +0 -1
- package/dist/services/media.service.js +0 -49
- package/dist/services/media.service.js.map +0 -1
- package/dist/services/population.service.d.ts +0 -20
- package/dist/services/population.service.d.ts.map +0 -1
- package/dist/services/population.service.js +0 -194
- package/dist/services/population.service.js.map +0 -1
- package/dist/token-7QG5DBME.mjs +0 -10
- package/dist/types/access.d.ts +0 -38
- package/dist/types/access.d.ts.map +0 -1
- package/dist/types/access.js +0 -2
- package/dist/types/access.js.map +0 -1
- package/dist/types/adapters.d.ts +0 -146
- package/dist/types/adapters.d.ts.map +0 -1
- package/dist/types/adapters.js +0 -2
- package/dist/types/adapters.js.map +0 -1
- package/dist/types/admin-auth.d.ts +0 -132
- package/dist/types/admin-auth.d.ts.map +0 -1
- package/dist/types/admin-auth.js +0 -2
- package/dist/types/admin-auth.js.map +0 -1
- package/dist/types/admin.d.ts +0 -65
- package/dist/types/admin.d.ts.map +0 -1
- package/dist/types/admin.js +0 -2
- package/dist/types/admin.js.map +0 -1
- package/dist/types/app-config.d.ts +0 -143
- package/dist/types/app-config.d.ts.map +0 -1
- package/dist/types/app-config.js +0 -2
- package/dist/types/app-config.js.map +0 -1
- package/dist/types/documents.d.ts +0 -65
- package/dist/types/documents.d.ts.map +0 -1
- package/dist/types/documents.js +0 -2
- package/dist/types/documents.js.map +0 -1
- package/dist/types/hooks.d.ts +0 -122
- package/dist/types/hooks.d.ts.map +0 -1
- package/dist/types/hooks.js +0 -2
- package/dist/types/hooks.js.map +0 -1
- package/dist/types/index.d.ts +0 -13
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -13
- package/dist/types/index.js.map +0 -1
- package/dist/types/request.d.ts +0 -42
- package/dist/types/request.d.ts.map +0 -1
- package/dist/types/request.js +0 -2
- package/dist/types/request.js.map +0 -1
- package/dist/types/schema-config.d.ts +0 -303
- package/dist/types/schema-config.d.ts.map +0 -1
- package/dist/types/schema-config.js +0 -2
- package/dist/types/schema-config.js.map +0 -1
- package/dist/types/schema-core.d.ts +0 -294
- package/dist/types/schema-core.d.ts.map +0 -1
- package/dist/types/schema-core.js +0 -2
- package/dist/types/schema-core.js.map +0 -1
- package/dist/types/schema-inference.d.ts +0 -73
- package/dist/types/schema-inference.d.ts.map +0 -1
- package/dist/types/schema-inference.js +0 -2
- package/dist/types/schema-inference.js.map +0 -1
- package/dist/types/workflows.d.ts +0 -84
- package/dist/types/workflows.d.ts.map +0 -1
- package/dist/types/workflows.js +0 -7
- package/dist/types/workflows.js.map +0 -1
- package/dist/utils/admin-auth.d.ts +0 -5
- package/dist/utils/admin-auth.d.ts.map +0 -1
- package/dist/utils/admin-auth.js +0 -39
- package/dist/utils/admin-auth.js.map +0 -1
- package/dist/utils/config.d.ts +0 -8
- package/dist/utils/config.d.ts.map +0 -1
- package/dist/utils/config.js +0 -238
- package/dist/utils/config.js.map +0 -1
- package/dist/utils/hooks.d.ts +0 -41
- package/dist/utils/hooks.d.ts.map +0 -1
- package/dist/utils/hooks.js +0 -173
- package/dist/utils/hooks.js.map +0 -1
- package/dist/utils/openapi.d.ts +0 -6
- package/dist/utils/openapi.d.ts.map +0 -1
- package/dist/utils/openapi.js +0 -842
- package/dist/utils/openapi.js.map +0 -1
- package/dist/utils/parse-sort.d.ts +0 -7
- package/dist/utils/parse-sort.d.ts.map +0 -1
- package/dist/utils/parse-sort.js +0 -23
- package/dist/utils/parse-sort.js.map +0 -1
- package/dist/utils/parse-where.d.ts +0 -63
- package/dist/utils/parse-where.d.ts.map +0 -1
- package/dist/utils/parse-where.js +0 -196
- package/dist/utils/parse-where.js.map +0 -1
- package/dist/utils/readonly-db.d.ts +0 -9
- package/dist/utils/readonly-db.d.ts.map +0 -1
- package/dist/utils/readonly-db.js +0 -21
- package/dist/utils/readonly-db.js.map +0 -1
- package/dist/utils/setup-prompt.d.ts +0 -11
- package/dist/utils/setup-prompt.d.ts.map +0 -1
- package/dist/utils/setup-prompt.js +0 -863
- package/dist/utils/setup-prompt.js.map +0 -1
- package/dist/utils/swagger.d.ts +0 -11
- package/dist/utils/swagger.d.ts.map +0 -1
- package/dist/utils/swagger.js +0 -62
- package/dist/utils/swagger.js.map +0 -1
- package/dist/utils/upload-validation.d.ts +0 -23
- package/dist/utils/upload-validation.d.ts.map +0 -1
- package/dist/utils/upload-validation.js +0 -44
- package/dist/utils/upload-validation.js.map +0 -1
- package/dist/utils/where-sanitizer.d.ts +0 -10
- package/dist/utils/where-sanitizer.d.ts.map +0 -1
- package/dist/utils/where-sanitizer.js +0 -67
- package/dist/utils/where-sanitizer.js.map +0 -1
- package/dist/where-sanitizer-7Q4JXMX6.js +0 -57
- package/dist/where-sanitizer-DQIWTQZW.js +0 -50
- package/dist/workflows.d.ts +0 -54
- package/dist/workflows.d.ts.map +0 -1
- package/dist/workflows.js +0 -282
- package/dist/workflows.js.map +0 -1
package/dist/index-DR2z1rrf.d.ts
DELETED
|
@@ -1,1503 +0,0 @@
|
|
|
1
|
-
import { icons } from 'lucide-react';
|
|
2
|
-
|
|
3
|
-
type AdminAuthProvisioningMode = "jit_only" | "jit_plus_membership_management" | "preprovisioned_only";
|
|
4
|
-
interface AdminAuthClaimMapping {
|
|
5
|
-
sub?: string;
|
|
6
|
-
email?: string;
|
|
7
|
-
name?: string;
|
|
8
|
-
roles?: string;
|
|
9
|
-
groups?: string;
|
|
10
|
-
siteIds?: string;
|
|
11
|
-
workspaceIds?: string;
|
|
12
|
-
}
|
|
13
|
-
interface AdminAuthResolvedIdentity {
|
|
14
|
-
sub: string;
|
|
15
|
-
email?: string;
|
|
16
|
-
name?: string;
|
|
17
|
-
roles?: string[];
|
|
18
|
-
groups?: string[];
|
|
19
|
-
siteIds?: string[];
|
|
20
|
-
workspaceIds?: string[];
|
|
21
|
-
rawClaims?: Record<string, unknown>;
|
|
22
|
-
}
|
|
23
|
-
interface AdminAuthAccessResolution {
|
|
24
|
-
allowed: boolean;
|
|
25
|
-
roles?: string[];
|
|
26
|
-
data?: Record<string, unknown>;
|
|
27
|
-
}
|
|
28
|
-
interface AdminAuthResolveAccessArgs {
|
|
29
|
-
identity: AdminAuthResolvedIdentity;
|
|
30
|
-
providerId: string;
|
|
31
|
-
siteId?: string;
|
|
32
|
-
workspaceId?: string;
|
|
33
|
-
req: {
|
|
34
|
-
method: string;
|
|
35
|
-
path: string;
|
|
36
|
-
url: string;
|
|
37
|
-
headers: Record<string, string | undefined>;
|
|
38
|
-
};
|
|
39
|
-
user: Record<string, unknown> | null;
|
|
40
|
-
}
|
|
41
|
-
interface BaseAdminAuthProvider {
|
|
42
|
-
id: string;
|
|
43
|
-
type: "oidc" | "custom" | "cloud";
|
|
44
|
-
displayName?: string;
|
|
45
|
-
autoRedirect?: boolean;
|
|
46
|
-
allowJitProvisioning?: boolean;
|
|
47
|
-
claimMapping?: AdminAuthClaimMapping;
|
|
48
|
-
}
|
|
49
|
-
interface OIDCAdminAuthProvider extends BaseAdminAuthProvider {
|
|
50
|
-
type: "oidc";
|
|
51
|
-
issuer: string;
|
|
52
|
-
clientId: string;
|
|
53
|
-
clientSecret: string;
|
|
54
|
-
redirectUri?: string;
|
|
55
|
-
scopes?: string[];
|
|
56
|
-
authorizationEndpoint?: string;
|
|
57
|
-
tokenEndpoint?: string;
|
|
58
|
-
userInfoEndpoint?: string;
|
|
59
|
-
}
|
|
60
|
-
interface CustomAdminAuthProvider extends BaseAdminAuthProvider {
|
|
61
|
-
type: "custom" | "cloud";
|
|
62
|
-
startUrl?: string;
|
|
63
|
-
issuer?: string;
|
|
64
|
-
audience?: string;
|
|
65
|
-
secret?: string;
|
|
66
|
-
jwksUri?: string;
|
|
67
|
-
tokenParam?: string;
|
|
68
|
-
}
|
|
69
|
-
type AdminAuthProvider = OIDCAdminAuthProvider | CustomAdminAuthProvider;
|
|
70
|
-
interface PublicAdminAuthProvider {
|
|
71
|
-
id: string;
|
|
72
|
-
type: AdminAuthProvider["type"];
|
|
73
|
-
displayName: string;
|
|
74
|
-
autoRedirect?: boolean;
|
|
75
|
-
}
|
|
76
|
-
interface PublicAdminAuthConfig {
|
|
77
|
-
mode: "local" | "external";
|
|
78
|
-
collectionSlug?: string;
|
|
79
|
-
provisioningMode?: AdminAuthProvisioningMode;
|
|
80
|
-
providers: PublicAdminAuthProvider[];
|
|
81
|
-
}
|
|
82
|
-
interface AdminAuthConfig {
|
|
83
|
-
mode: "local" | "external";
|
|
84
|
-
collectionSlug?: string;
|
|
85
|
-
provisioningMode?: AdminAuthProvisioningMode;
|
|
86
|
-
providers: AdminAuthProvider[];
|
|
87
|
-
resolveAccess?: (args: AdminAuthResolveAccessArgs) => Promise<AdminAuthAccessResolution> | AdminAuthAccessResolution;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/** A valid icon component name from the Lucide icon set bundled with Dyrected Admin. */
|
|
91
|
-
type AdminIconName = keyof typeof icons;
|
|
92
|
-
/** Ordered custom component keys rendered around the built-in Admin dashboard. */
|
|
93
|
-
interface AdminDashboardComponentSlots {
|
|
94
|
-
beforeDashboard?: string[];
|
|
95
|
-
afterDashboard?: string[];
|
|
96
|
-
}
|
|
97
|
-
/** Ordered custom component keys rendered around a collection's list content. */
|
|
98
|
-
interface CollectionListComponentSlots {
|
|
99
|
-
beforeList?: string[];
|
|
100
|
-
beforeListTable?: string[];
|
|
101
|
-
afterListTable?: string[];
|
|
102
|
-
afterList?: string[];
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Branding and metadata options for the Dyrected Admin UI.
|
|
106
|
-
*
|
|
107
|
-
* @example
|
|
108
|
-
* admin: {
|
|
109
|
-
* branding: {
|
|
110
|
-
* logo: '/logo.svg',
|
|
111
|
-
* primaryColor: '#6366f1',
|
|
112
|
-
* },
|
|
113
|
-
* meta: {
|
|
114
|
-
* titleSuffix: '- My App',
|
|
115
|
-
* },
|
|
116
|
-
* }
|
|
117
|
-
*/
|
|
118
|
-
interface AdminConfig {
|
|
119
|
-
/** Custom component slots around the built-in dashboard. */
|
|
120
|
-
components?: AdminDashboardComponentSlots;
|
|
121
|
-
branding?: {
|
|
122
|
-
/** Full logo image shown in the expanded sidebar. URL or imported image asset. */
|
|
123
|
-
logo?: string;
|
|
124
|
-
/** Compact logo mark used in the collapsed sidebar state. */
|
|
125
|
-
logoMark?: string;
|
|
126
|
-
/** Text alternative or addition to the logo image. */
|
|
127
|
-
logoText?: string;
|
|
128
|
-
/**
|
|
129
|
-
* Primary accent colour as any CSS colour value.
|
|
130
|
-
* @example '#6366f1'
|
|
131
|
-
* @example 'hsl(240 50% 60%)'
|
|
132
|
-
*/
|
|
133
|
-
primaryColor?: string;
|
|
134
|
-
/** Browser tab favicon URL. */
|
|
135
|
-
favicon?: string;
|
|
136
|
-
/** Font family for body and UI text. Must be loaded separately. */
|
|
137
|
-
fontSans?: string;
|
|
138
|
-
/** Font family for headings. Must be loaded separately. */
|
|
139
|
-
fontSerif?: string;
|
|
140
|
-
};
|
|
141
|
-
meta?: {
|
|
142
|
-
/**
|
|
143
|
-
* String appended to every Admin page's `<title>`.
|
|
144
|
-
* @default '- Dyrected'
|
|
145
|
-
*/
|
|
146
|
-
titleSuffix?: string;
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* The minimum shape of every document returned by the database layer.
|
|
152
|
-
*
|
|
153
|
-
* All documents have an `id` field assigned by the adapter. Additional fields
|
|
154
|
-
* are stored as `unknown` until you narrow them with your own interface.
|
|
155
|
-
*
|
|
156
|
-
* Use this as the base when declaring your collection document types:
|
|
157
|
-
* ```ts
|
|
158
|
-
* interface Post extends BaseDocument {
|
|
159
|
-
* title: string
|
|
160
|
-
* slug: string
|
|
161
|
-
* }
|
|
162
|
-
* ```
|
|
163
|
-
*/
|
|
164
|
-
interface BaseDocument {
|
|
165
|
-
/** The document's unique identifier, assigned by the database adapter. */
|
|
166
|
-
id: string;
|
|
167
|
-
[key: string]: any;
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* The envelope returned by collection list endpoints (`GET /api/collections/:slug`).
|
|
171
|
-
*
|
|
172
|
-
* @template T The document type.
|
|
173
|
-
*/
|
|
174
|
-
interface PaginatedResult<T = Record<string, any>> {
|
|
175
|
-
/** The documents on the current page. */
|
|
176
|
-
docs: T[];
|
|
177
|
-
/** Total number of documents matching the query (across all pages). */
|
|
178
|
-
total: number;
|
|
179
|
-
/** Maximum number of documents per page as requested. */
|
|
180
|
-
limit: number;
|
|
181
|
-
/** The current page number (1-indexed). */
|
|
182
|
-
page: number;
|
|
183
|
-
/** Total number of pages given the current `limit`. */
|
|
184
|
-
totalPages: number;
|
|
185
|
-
/** Whether a next page exists. */
|
|
186
|
-
hasNextPage: boolean;
|
|
187
|
-
/** Whether a previous page exists. */
|
|
188
|
-
hasPrevPage: boolean;
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* Metadata returned after a file is uploaded and stored.
|
|
192
|
-
* Stored on the document in upload collections.
|
|
193
|
-
*/
|
|
194
|
-
interface FileData {
|
|
195
|
-
filename: string;
|
|
196
|
-
filesize?: number;
|
|
197
|
-
mimeType: string;
|
|
198
|
-
/** Public URL of the stored file. */
|
|
199
|
-
url: string;
|
|
200
|
-
width?: number;
|
|
201
|
-
height?: number;
|
|
202
|
-
focalPoint?: {
|
|
203
|
-
x: number;
|
|
204
|
-
y: number;
|
|
205
|
-
};
|
|
206
|
-
/** Base64-encoded BlurHash string for progressive image loading. */
|
|
207
|
-
blurhash?: string;
|
|
208
|
-
/** `'upload'` for server-stored files; `'external'` for provider-managed files. */
|
|
209
|
-
type?: "upload" | "external";
|
|
210
|
-
provider?: string;
|
|
211
|
-
provider_metadata?: unknown;
|
|
212
|
-
[key: string]: unknown;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Minimum HTTP request context passed to every server-side hook and resolver.
|
|
217
|
-
*
|
|
218
|
-
* The full Web Standard `Request` is available as `raw` when you need it, but
|
|
219
|
-
* most hooks only need `query` (URL search parameters).
|
|
220
|
-
*/
|
|
221
|
-
interface HookRequestContext {
|
|
222
|
-
/** Parsed URL query-string parameters, e.g. `{ page: '2', search: 'hello' }`. */
|
|
223
|
-
query: Record<string, string>;
|
|
224
|
-
/** Incoming HTTP headers, lowercased. */
|
|
225
|
-
headers: Record<string, string>;
|
|
226
|
-
/** The raw Web Standard `Request` object. Useful for streaming or advanced header inspection. */
|
|
227
|
-
raw?: Request;
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* Base shape of an authenticated user as decoded from the JWT.
|
|
231
|
-
*
|
|
232
|
-
* The actual shape will include every field on your auth collection — this
|
|
233
|
-
* interface only guarantees the properties that Dyrected always stamps on the
|
|
234
|
-
* token. Extend it in your own codebase for stronger typing:
|
|
235
|
-
*
|
|
236
|
-
* @example
|
|
237
|
-
* declare module '@dyrected/core' {
|
|
238
|
-
* interface AuthenticatedUser {
|
|
239
|
-
* role: 'admin' | 'editor'
|
|
240
|
-
* organizationId: string
|
|
241
|
-
* }
|
|
242
|
-
* }
|
|
243
|
-
*/
|
|
244
|
-
interface AuthenticatedUser {
|
|
245
|
-
/** The user's document ID in the database. */
|
|
246
|
-
sub: string;
|
|
247
|
-
/** The user's email address. */
|
|
248
|
-
email?: string;
|
|
249
|
-
/** Slug of the collection this user was authenticated against. */
|
|
250
|
-
collection: string;
|
|
251
|
-
/** Array of role strings, if your auth collection has a `roles` field. */
|
|
252
|
-
roles?: string[];
|
|
253
|
-
/** Any additional fields from the auth collection document. */
|
|
254
|
-
[key: string]: unknown;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
type FieldType = "text" | "textarea" | "richText" | "number" | "boolean" | "date" | "datetime" | "time" | "select" | "multiSelect" | "radio" | "relationship" | "array" | "object" | "json" | "blocks" | "image" | "email" | "url" | "icon" | "join" | "row";
|
|
258
|
-
interface DynamicOptionsResolverArgs {
|
|
259
|
-
db?: DatabaseAdapter;
|
|
260
|
-
user?: AuthenticatedUser;
|
|
261
|
-
req: HookRequestContext;
|
|
262
|
-
}
|
|
263
|
-
type DynamicOptionsResolver = (args: DynamicOptionsResolverArgs) => Promise<DynamicOptionItem[]> | DynamicOptionItem[];
|
|
264
|
-
interface DynamicOptionsConfig {
|
|
265
|
-
resolve: DynamicOptionsResolver;
|
|
266
|
-
cacheTTL?: number;
|
|
267
|
-
}
|
|
268
|
-
type DynamicOptionItem = string | {
|
|
269
|
-
label: string;
|
|
270
|
-
value: unknown;
|
|
271
|
-
};
|
|
272
|
-
interface Block {
|
|
273
|
-
slug: string;
|
|
274
|
-
labels?: {
|
|
275
|
-
singular: string;
|
|
276
|
-
plural: string;
|
|
277
|
-
};
|
|
278
|
-
fields: Field[];
|
|
279
|
-
}
|
|
280
|
-
interface FieldBase {
|
|
281
|
-
name?: string;
|
|
282
|
-
label?: string;
|
|
283
|
-
required?: boolean;
|
|
284
|
-
unique?: boolean;
|
|
285
|
-
defaultValue?: unknown;
|
|
286
|
-
options?: string[] | {
|
|
287
|
-
label: string;
|
|
288
|
-
value: unknown;
|
|
289
|
-
}[] | DynamicOptionsResolver | DynamicOptionsConfig;
|
|
290
|
-
relationTo?: string;
|
|
291
|
-
hasMany?: boolean;
|
|
292
|
-
fields?: Field[];
|
|
293
|
-
blocks?: Block[];
|
|
294
|
-
collection?: string;
|
|
295
|
-
on?: string;
|
|
296
|
-
limit?: number;
|
|
297
|
-
access?: {
|
|
298
|
-
read?: AccessFunction | string;
|
|
299
|
-
update?: AccessFunction | string;
|
|
300
|
-
};
|
|
301
|
-
admin?: BaseFieldAdmin;
|
|
302
|
-
renameTo?: string;
|
|
303
|
-
promoted?: boolean;
|
|
304
|
-
}
|
|
305
|
-
interface BaseFieldAdmin {
|
|
306
|
-
placeholder?: string;
|
|
307
|
-
component?: string;
|
|
308
|
-
description?: string;
|
|
309
|
-
hidden?: boolean;
|
|
310
|
-
filterable?: boolean;
|
|
311
|
-
readOnly?: boolean;
|
|
312
|
-
condition?: ((data: Record<string, unknown>, siblingData: Record<string, unknown>) => boolean) | string;
|
|
313
|
-
tab?: string;
|
|
314
|
-
width?: string;
|
|
315
|
-
}
|
|
316
|
-
type FieldHooks<TValue> = {
|
|
317
|
-
hooks?: {
|
|
318
|
-
beforeChange?: Array<(args: {
|
|
319
|
-
value: TValue;
|
|
320
|
-
originalDoc?: Record<string, unknown>;
|
|
321
|
-
data: Record<string, unknown>;
|
|
322
|
-
user?: AuthenticatedUser;
|
|
323
|
-
db: ReadonlyDatabaseAdapter;
|
|
324
|
-
}) => unknown>;
|
|
325
|
-
afterRead?: Array<(args: {
|
|
326
|
-
value: TValue;
|
|
327
|
-
doc: Record<string, unknown>;
|
|
328
|
-
user?: AuthenticatedUser;
|
|
329
|
-
db: ReadonlyDatabaseAdapter;
|
|
330
|
-
}) => unknown>;
|
|
331
|
-
};
|
|
332
|
-
};
|
|
333
|
-
type FieldAdminHooks<TValue> = {
|
|
334
|
-
admin?: {
|
|
335
|
-
hooks?: {
|
|
336
|
-
onChange?: (args: {
|
|
337
|
-
value: TValue;
|
|
338
|
-
siblingData: Record<string, unknown>;
|
|
339
|
-
data: Record<string, unknown>;
|
|
340
|
-
setValue: (value: unknown) => void;
|
|
341
|
-
}) => unknown;
|
|
342
|
-
};
|
|
343
|
-
};
|
|
344
|
-
};
|
|
345
|
-
type TypedField<TType extends FieldType, TValue, TAdminExtra = Record<never, never>> = Omit<FieldBase, "admin"> & {
|
|
346
|
-
type: TType;
|
|
347
|
-
admin?: BaseFieldAdmin & TAdminExtra;
|
|
348
|
-
} & FieldHooks<TValue> & FieldAdminHooks<TValue>;
|
|
349
|
-
type BooleanFieldAdmin = {
|
|
350
|
-
layout?: "checkbox" | "switch";
|
|
351
|
-
};
|
|
352
|
-
type SelectFieldAdmin = {
|
|
353
|
-
layout?: "radio" | "select";
|
|
354
|
-
direction?: "horizontal" | "vertical";
|
|
355
|
-
hooks?: {
|
|
356
|
-
options?: (args: {
|
|
357
|
-
siblingData: Record<string, unknown>;
|
|
358
|
-
data: Record<string, unknown>;
|
|
359
|
-
}) => Array<string | {
|
|
360
|
-
label: string;
|
|
361
|
-
value: unknown;
|
|
362
|
-
}> | Promise<Array<string | {
|
|
363
|
-
label: string;
|
|
364
|
-
value: unknown;
|
|
365
|
-
}>>;
|
|
366
|
-
};
|
|
367
|
-
};
|
|
368
|
-
type RadioFieldAdmin = {
|
|
369
|
-
direction?: "horizontal" | "vertical";
|
|
370
|
-
hooks?: {
|
|
371
|
-
options?: (args: {
|
|
372
|
-
siblingData: Record<string, unknown>;
|
|
373
|
-
data: Record<string, unknown>;
|
|
374
|
-
}) => Array<string | {
|
|
375
|
-
label: string;
|
|
376
|
-
value: unknown;
|
|
377
|
-
}> | Promise<Array<string | {
|
|
378
|
-
label: string;
|
|
379
|
-
value: unknown;
|
|
380
|
-
}>>;
|
|
381
|
-
};
|
|
382
|
-
};
|
|
383
|
-
type MultiSelectFieldAdmin = {
|
|
384
|
-
hooks?: {
|
|
385
|
-
options?: (args: {
|
|
386
|
-
siblingData: Record<string, unknown>;
|
|
387
|
-
data: Record<string, unknown>;
|
|
388
|
-
}) => Array<string | {
|
|
389
|
-
label: string;
|
|
390
|
-
value: unknown;
|
|
391
|
-
}> | Promise<Array<string | {
|
|
392
|
-
label: string;
|
|
393
|
-
value: unknown;
|
|
394
|
-
}>>;
|
|
395
|
-
};
|
|
396
|
-
};
|
|
397
|
-
type TextField = TypedField<"text", string>;
|
|
398
|
-
type TextareaField = TypedField<"textarea", string>;
|
|
399
|
-
type EmailField = TypedField<"email", string>;
|
|
400
|
-
type UrlField = TypedField<"url", string>;
|
|
401
|
-
type IconField = TypedField<"icon", string>;
|
|
402
|
-
type DateField = TypedField<"date", string>;
|
|
403
|
-
type DateTimeField = TypedField<"datetime", string>;
|
|
404
|
-
type TimeField = TypedField<"time", string>;
|
|
405
|
-
type SelectField = TypedField<"select", string, SelectFieldAdmin>;
|
|
406
|
-
type RadioField = TypedField<"radio", string, RadioFieldAdmin>;
|
|
407
|
-
type NumberField = TypedField<"number", number>;
|
|
408
|
-
type BooleanField = TypedField<"boolean", boolean, BooleanFieldAdmin>;
|
|
409
|
-
type MultiSelectField = TypedField<"multiSelect", string[], MultiSelectFieldAdmin>;
|
|
410
|
-
type RelationshipField = TypedField<"relationship", string | string[]>;
|
|
411
|
-
type ImageField = TypedField<"image", string | string[]>;
|
|
412
|
-
type RichTextField = TypedField<"richText", Record<string, unknown>>;
|
|
413
|
-
type JsonField = TypedField<"json", Record<string, unknown>>;
|
|
414
|
-
type ObjectField = TypedField<"object", unknown>;
|
|
415
|
-
type ArrayField = TypedField<"array", unknown>;
|
|
416
|
-
type BlocksField = TypedField<"blocks", unknown>;
|
|
417
|
-
type JoinField = TypedField<"join", unknown>;
|
|
418
|
-
type RowField = TypedField<"row", unknown>;
|
|
419
|
-
type Field = TextField | TextareaField | EmailField | UrlField | IconField | DateField | DateTimeField | TimeField | SelectField | RadioField | NumberField | BooleanField | MultiSelectField | RelationshipField | ImageField | RichTextField | JsonField | ObjectField | ArrayField | BlocksField | JoinField | RowField;
|
|
420
|
-
interface UploadConfig {
|
|
421
|
-
allowedMimeTypes?: string[];
|
|
422
|
-
maxFileSize?: number;
|
|
423
|
-
staticDir?: string;
|
|
424
|
-
staticURL?: string;
|
|
425
|
-
adminThumbnail?: string;
|
|
426
|
-
imageSizes?: {
|
|
427
|
-
name: string;
|
|
428
|
-
width?: number;
|
|
429
|
-
height?: number;
|
|
430
|
-
crop?: string;
|
|
431
|
-
fit?: string;
|
|
432
|
-
withoutEnlargement?: boolean;
|
|
433
|
-
formatOptions?: Record<string, unknown>;
|
|
434
|
-
}[];
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
declare const LIFECYCLE_EVENT_NAMES: readonly ["revision.created", "workflow.transitioned", "entry.published", "entry.unpublished"];
|
|
438
|
-
type LifecycleEventName = (typeof LIFECYCLE_EVENT_NAMES)[number];
|
|
439
|
-
interface WorkflowState {
|
|
440
|
-
/** Stable machine-readable state key. */
|
|
441
|
-
name: string;
|
|
442
|
-
/** Label rendered in the Admin UI. */
|
|
443
|
-
label: string;
|
|
444
|
-
/** Marks the state whose revision is visible to public readers. */
|
|
445
|
-
published?: boolean;
|
|
446
|
-
/** Optional visual tone used by the Admin UI. */
|
|
447
|
-
color?: "neutral" | "warning" | "success" | "danger" | "info";
|
|
448
|
-
}
|
|
449
|
-
interface WorkflowTransition {
|
|
450
|
-
/** Stable transition key used by the REST and SDK APIs. */
|
|
451
|
-
name: string;
|
|
452
|
-
label: string;
|
|
453
|
-
from: string | string[];
|
|
454
|
-
to: string;
|
|
455
|
-
/** Every listed capability is required. */
|
|
456
|
-
requiredCapabilities?: string[];
|
|
457
|
-
/** Require a non-empty comment when performing the transition. */
|
|
458
|
-
requireComment?: boolean;
|
|
459
|
-
/** Remove the public snapshot after this transition commits. */
|
|
460
|
-
unpublish?: boolean;
|
|
461
|
-
}
|
|
462
|
-
interface WorkflowRole {
|
|
463
|
-
/** Existing user role value, for example `editor` or `publisher`. */
|
|
464
|
-
role: string;
|
|
465
|
-
capabilities: string[];
|
|
466
|
-
}
|
|
467
|
-
interface WorkflowConfig<TDoc extends object = Record<string, unknown>> {
|
|
468
|
-
initialState: string;
|
|
469
|
-
/** State used for a new working revision created from published content. */
|
|
470
|
-
draftState?: string;
|
|
471
|
-
states: WorkflowState[];
|
|
472
|
-
transitions: WorkflowTransition[];
|
|
473
|
-
/** Maps values in `user.roles` to workflow capabilities. */
|
|
474
|
-
roles?: WorkflowRole[];
|
|
475
|
-
hooks?: {
|
|
476
|
-
beforeTransition?: CollectionBeforeTransitionHook<TDoc>[];
|
|
477
|
-
afterTransition?: CollectionAfterTransitionHook<TDoc>[];
|
|
478
|
-
};
|
|
479
|
-
}
|
|
480
|
-
interface WorkflowMetadata {
|
|
481
|
-
state: string;
|
|
482
|
-
revision: number;
|
|
483
|
-
publishedRevision?: number;
|
|
484
|
-
publishedAt?: string;
|
|
485
|
-
publishedBy?: string;
|
|
486
|
-
/** Transitions currently allowed for the requesting user. Response-only. */
|
|
487
|
-
availableTransitions?: string[];
|
|
488
|
-
}
|
|
489
|
-
interface WorkflowTransitionContext<TDoc extends object = Record<string, unknown>> {
|
|
490
|
-
transition: WorkflowTransition;
|
|
491
|
-
from: string;
|
|
492
|
-
to: string;
|
|
493
|
-
doc: TDoc;
|
|
494
|
-
user?: AuthenticatedUser;
|
|
495
|
-
comment?: string;
|
|
496
|
-
req: HookRequestContext;
|
|
497
|
-
db: DatabaseAdapter;
|
|
498
|
-
}
|
|
499
|
-
type CollectionBeforeTransitionHook<TDoc extends object = Record<string, unknown>> = (args: WorkflowTransitionContext<TDoc>) => void | Promise<void>;
|
|
500
|
-
type CollectionAfterTransitionHook<TDoc extends object = Record<string, unknown>> = (args: WorkflowTransitionContext<TDoc> & {
|
|
501
|
-
event: LifecycleEvent;
|
|
502
|
-
}) => void | Promise<void>;
|
|
503
|
-
interface LifecycleEvent<TPayload = Record<string, unknown>> {
|
|
504
|
-
id: string;
|
|
505
|
-
name: LifecycleEventName;
|
|
506
|
-
collection: string;
|
|
507
|
-
documentId: string;
|
|
508
|
-
occurredAt: string;
|
|
509
|
-
actorId?: string;
|
|
510
|
-
payload: TPayload;
|
|
511
|
-
attempts: number;
|
|
512
|
-
status: "pending" | "processing" | "delivered" | "failed";
|
|
513
|
-
nextAttemptAt?: string;
|
|
514
|
-
deliveredAt?: string;
|
|
515
|
-
lastError?: string;
|
|
516
|
-
}
|
|
517
|
-
type LifecycleEventHandler = (event: LifecycleEvent) => void | Promise<void>;
|
|
518
|
-
|
|
519
|
-
/**
|
|
520
|
-
* A hook that runs **before a field value is saved** to the database.
|
|
521
|
-
*
|
|
522
|
-
* Return the transformed value to persist. Return `undefined` to leave the
|
|
523
|
-
* value unchanged (same as returning the original `value`).
|
|
524
|
-
*
|
|
525
|
-
* Field `beforeChange` hooks run recursively inside `array`, `object`, and
|
|
526
|
-
* `blocks` fields — every nested item is processed automatically.
|
|
527
|
-
*
|
|
528
|
-
* @template TValue The TypeScript type of this field's value.
|
|
529
|
-
* @template TDoc The document shape of the parent collection/global.
|
|
530
|
-
*
|
|
531
|
-
* @example
|
|
532
|
-
* // Normalise email to lowercase
|
|
533
|
-
* const normaliseEmail: FieldBeforeChangeHook<string> = ({ value }) =>
|
|
534
|
-
* value?.toLowerCase().trim()
|
|
535
|
-
*
|
|
536
|
-
* @example
|
|
537
|
-
* // Hash a password with bcrypt
|
|
538
|
-
* const hashPassword: FieldBeforeChangeHook<string> = async ({ value }) =>
|
|
539
|
-
* value ? bcrypt.hash(value, 10) : value
|
|
540
|
-
*/
|
|
541
|
-
type FieldBeforeChangeHook<TValue = unknown, TDoc extends object = Record<string, unknown>> = (args: {
|
|
542
|
-
/** The current value of this field (after any previous hooks in the chain). */
|
|
543
|
-
value: TValue;
|
|
544
|
-
/** The full document as it existed before this update. `undefined` on create. */
|
|
545
|
-
originalDoc?: TDoc;
|
|
546
|
-
/** The full incoming data payload being written. */
|
|
547
|
-
data: Partial<TDoc>;
|
|
548
|
-
/** The authenticated user, or `undefined` for unauthenticated requests. */
|
|
549
|
-
user?: AuthenticatedUser;
|
|
550
|
-
/**
|
|
551
|
-
* Database adapter for cross-collection reads. Write operations (create,
|
|
552
|
-
* update, delete) will throw — use `afterChange`/`afterDelete` for writes.
|
|
553
|
-
*/
|
|
554
|
-
db: ReadonlyDatabaseAdapter;
|
|
555
|
-
}) => TValue | undefined | Promise<TValue | undefined>;
|
|
556
|
-
/**
|
|
557
|
-
* A hook that runs **after a field value is read** from the database, before
|
|
558
|
-
* the response is sent to the client.
|
|
559
|
-
*
|
|
560
|
-
* Return the transformed value to return to the client. Use this for masking,
|
|
561
|
-
* formatting, or adding computed properties.
|
|
562
|
-
*
|
|
563
|
-
* @template TValue The TypeScript type of this field's value.
|
|
564
|
-
* @template TDoc The document shape of the parent collection/global.
|
|
565
|
-
*
|
|
566
|
-
* @example
|
|
567
|
-
* // Mask sensitive value for non-admins
|
|
568
|
-
* const maskForPublic: FieldAfterReadHook<string> = ({ value, user }) =>
|
|
569
|
-
* user?.role === 'admin' ? value : '••••••••'
|
|
570
|
-
*/
|
|
571
|
-
type FieldAfterReadHook<TValue = unknown, TDoc extends object = Record<string, unknown>> = (args: {
|
|
572
|
-
/** The raw field value as stored in the database. */
|
|
573
|
-
value: TValue;
|
|
574
|
-
/** The full document being returned (with defaults applied). */
|
|
575
|
-
doc: TDoc;
|
|
576
|
-
/** The authenticated user, or `undefined` for unauthenticated requests. */
|
|
577
|
-
user?: AuthenticatedUser;
|
|
578
|
-
/**
|
|
579
|
-
* Database adapter for cross-collection reads. Write operations (create,
|
|
580
|
-
* update, delete) will throw — use `afterChange`/`afterDelete` for writes.
|
|
581
|
-
*/
|
|
582
|
-
db: ReadonlyDatabaseAdapter;
|
|
583
|
-
}) => TValue | undefined | Promise<TValue | undefined>;
|
|
584
|
-
/**
|
|
585
|
-
* @deprecated Use {@link FieldBeforeChangeHook} or {@link FieldAfterReadHook} instead.
|
|
586
|
-
* This alias remains for backwards compatibility.
|
|
587
|
-
*/
|
|
588
|
-
type FieldHook<TDoc extends object = Record<string, unknown>, TValue = unknown> = FieldBeforeChangeHook<TValue, TDoc>;
|
|
589
|
-
/**
|
|
590
|
-
* Runs before Dyrected queries the database for a list or single-document fetch.
|
|
591
|
-
*
|
|
592
|
-
* Return a new `where` query object to override or extend the current filter.
|
|
593
|
-
* Return `undefined` (or nothing) to leave the query unchanged.
|
|
594
|
-
*
|
|
595
|
-
* @example
|
|
596
|
-
* // Scope all reads to the current user's own documents
|
|
597
|
-
* const scopeToUser: CollectionBeforeReadHook = ({ user, query }) => ({
|
|
598
|
-
* ...query,
|
|
599
|
-
* owner: { equals: user?.sub },
|
|
600
|
-
* })
|
|
601
|
-
*/
|
|
602
|
-
type CollectionBeforeReadHook = (args: {
|
|
603
|
-
/** The HTTP request context. */
|
|
604
|
-
req: HookRequestContext;
|
|
605
|
-
/** The current `where` query filter. Modify and return to override. */
|
|
606
|
-
query?: Record<string, unknown>;
|
|
607
|
-
/** The authenticated user, or `undefined` for unauthenticated requests. */
|
|
608
|
-
user?: AuthenticatedUser;
|
|
609
|
-
/**
|
|
610
|
-
* Database adapter for cross-collection reads. Write operations (create,
|
|
611
|
-
* update, delete) will throw — use `afterChange`/`afterDelete` for writes.
|
|
612
|
-
*/
|
|
613
|
-
db: ReadonlyDatabaseAdapter;
|
|
614
|
-
}) => Record<string, unknown> | void | Promise<Record<string, unknown> | void>;
|
|
615
|
-
/**
|
|
616
|
-
* Runs after a document (or list of documents) is fetched from the database,
|
|
617
|
-
* before the response is sent to the client.
|
|
618
|
-
*
|
|
619
|
-
* Return a modified document to send instead. Useful for adding computed
|
|
620
|
-
* virtual fields or transforming the shape of the response.
|
|
621
|
-
*
|
|
622
|
-
* @template TDoc The shape of the collection's document.
|
|
623
|
-
*
|
|
624
|
-
* @example
|
|
625
|
-
* // Add a computed fullName field
|
|
626
|
-
* const addFullName: CollectionAfterReadHook<User> = ({ doc }) => ({
|
|
627
|
-
* ...doc,
|
|
628
|
-
* fullName: `${doc.firstName} ${doc.lastName}`.trim(),
|
|
629
|
-
* })
|
|
630
|
-
*/
|
|
631
|
-
type CollectionAfterReadHook<TDoc extends object = Record<string, unknown>> = (args: {
|
|
632
|
-
/** The document as fetched from the database (with defaults applied). */
|
|
633
|
-
doc: TDoc;
|
|
634
|
-
/** The HTTP request context. */
|
|
635
|
-
req: HookRequestContext;
|
|
636
|
-
/** The authenticated user, or `undefined` for unauthenticated requests. */
|
|
637
|
-
user?: AuthenticatedUser;
|
|
638
|
-
/**
|
|
639
|
-
* Database adapter for cross-collection reads. Write operations (create,
|
|
640
|
-
* update, delete) will throw — use `afterChange`/`afterDelete` for writes.
|
|
641
|
-
*/
|
|
642
|
-
db: ReadonlyDatabaseAdapter;
|
|
643
|
-
}) => TDoc | Promise<TDoc>;
|
|
644
|
-
/**
|
|
645
|
-
* Runs **before** a document is created or updated in the database.
|
|
646
|
-
*
|
|
647
|
-
* Return a modified data object to write instead of the original. This is the
|
|
648
|
-
* right place for data transformation, normalisation, slug generation, and
|
|
649
|
-
* validation (throw to abort the write).
|
|
650
|
-
*
|
|
651
|
-
* @template TDoc The shape of the collection's document.
|
|
652
|
-
*
|
|
653
|
-
* @example
|
|
654
|
-
* // Auto-generate a slug on create
|
|
655
|
-
* const generateSlug: CollectionBeforeChangeHook<Post> = ({ data, operation }) => {
|
|
656
|
-
* if (operation === 'create' || data.title !== undefined) {
|
|
657
|
-
* return { ...data, slug: slugify(data.title ?? '') }
|
|
658
|
-
* }
|
|
659
|
-
* return data
|
|
660
|
-
* }
|
|
661
|
-
*
|
|
662
|
-
* @example
|
|
663
|
-
* // Abort the write with a validation error
|
|
664
|
-
* const validateStock: CollectionBeforeChangeHook<Product> = ({ data }) => {
|
|
665
|
-
* if ((data.stock ?? 0) < 0) throw new Error('Stock cannot be negative.')
|
|
666
|
-
* return data
|
|
667
|
-
* }
|
|
668
|
-
*/
|
|
669
|
-
type CollectionBeforeChangeHook<TDoc extends object = Record<string, unknown>> = (args: {
|
|
670
|
-
/** The incoming data payload being written. */
|
|
671
|
-
data: Partial<TDoc>;
|
|
672
|
-
/**
|
|
673
|
-
* The existing document before this update. Only present on `'update'`
|
|
674
|
-
* operations; `undefined` on `'create'`.
|
|
675
|
-
*/
|
|
676
|
-
doc?: TDoc;
|
|
677
|
-
/** The HTTP request context. */
|
|
678
|
-
req: HookRequestContext;
|
|
679
|
-
/** The authenticated user, or `undefined` for unauthenticated requests. */
|
|
680
|
-
user?: AuthenticatedUser;
|
|
681
|
-
/** Whether this is a new document or an update to an existing one. */
|
|
682
|
-
operation: "create" | "update";
|
|
683
|
-
/**
|
|
684
|
-
* Database adapter for cross-collection reads. Write operations (create,
|
|
685
|
-
* update, delete) will throw — use `afterChange`/`afterDelete` for writes.
|
|
686
|
-
*/
|
|
687
|
-
db: ReadonlyDatabaseAdapter;
|
|
688
|
-
}) => Partial<TDoc> | void | Promise<Partial<TDoc> | void>;
|
|
689
|
-
/**
|
|
690
|
-
* Runs **after** a document is created or updated in the database.
|
|
691
|
-
*
|
|
692
|
-
* **Isolation**: errors thrown inside this hook are caught by the framework,
|
|
693
|
-
* logged to the console, and then discarded. The HTTP response returns the
|
|
694
|
-
* saved document as if nothing went wrong — because from the database's
|
|
695
|
-
* perspective, nothing did. This means a transient email failure or webhook
|
|
696
|
-
* timeout will never turn a successful write into a 500 for the caller.
|
|
697
|
-
*
|
|
698
|
-
* The return value is ignored — this hook is for side-effects only (emails,
|
|
699
|
-
* webhooks, cache revalidation, search index updates, etc.).
|
|
700
|
-
*
|
|
701
|
-
* **Awaiting vs fire-and-forget**: `await`ing inside this hook is fine for
|
|
702
|
-
* fast, reliable calls. For slow or unreliable external services prefer
|
|
703
|
-
* fire-and-forget with your own `.catch()` so the response doesn't block:
|
|
704
|
-
*
|
|
705
|
-
* ```ts
|
|
706
|
-
* // ✓ fast & reliable — safe to await
|
|
707
|
-
* afterChange: [async ({ doc }) => {
|
|
708
|
-
* await revalidatePath(`/posts/${doc.slug}`)
|
|
709
|
-
* }]
|
|
710
|
-
*
|
|
711
|
-
* // ✓ slow or unreliable — fire-and-forget
|
|
712
|
-
* afterChange: [({ doc }) => {
|
|
713
|
-
* sendEmail({ to: doc.email, ... }).catch(console.error)
|
|
714
|
-
* }]
|
|
715
|
-
* ```
|
|
716
|
-
*
|
|
717
|
-
* @template TDoc The shape of the collection's document.
|
|
718
|
-
*
|
|
719
|
-
* @example
|
|
720
|
-
* // Send a webhook after every save
|
|
721
|
-
* const sendWebhook: CollectionAfterChangeHook<Post> = async ({ doc, operation }) => {
|
|
722
|
-
* await fetch('https://hooks.example.com/content', {
|
|
723
|
-
* method: 'POST',
|
|
724
|
-
* body: JSON.stringify({ event: operation, doc }),
|
|
725
|
-
* })
|
|
726
|
-
* }
|
|
727
|
-
*
|
|
728
|
-
* @example
|
|
729
|
-
* // Only act when a specific field changed
|
|
730
|
-
* const onStatusChange: CollectionAfterChangeHook<Post> = async ({ doc, previousDoc, operation }) => {
|
|
731
|
-
* if (operation === 'update' && doc.status !== previousDoc?.status) {
|
|
732
|
-
* await notifySubscribers(doc)
|
|
733
|
-
* }
|
|
734
|
-
* }
|
|
735
|
-
*/
|
|
736
|
-
type CollectionAfterChangeHook<TDoc extends object = Record<string, unknown>> = (args: {
|
|
737
|
-
/** The document as it was written to the database. */
|
|
738
|
-
doc: TDoc;
|
|
739
|
-
/**
|
|
740
|
-
* Snapshot of the document before the write. Only present on `'update'`
|
|
741
|
-
* operations; `undefined` on `'create'`.
|
|
742
|
-
*/
|
|
743
|
-
previousDoc?: TDoc;
|
|
744
|
-
/** The HTTP request context. */
|
|
745
|
-
req: HookRequestContext;
|
|
746
|
-
/** The authenticated user, or `undefined` for unauthenticated requests. */
|
|
747
|
-
user?: AuthenticatedUser;
|
|
748
|
-
/** Whether this was a new document or an update. */
|
|
749
|
-
operation: "create" | "update";
|
|
750
|
-
/**
|
|
751
|
-
* Database adapter with full read/write access. The DB write for this
|
|
752
|
-
* operation has already committed — safe for side-effect writes.
|
|
753
|
-
*/
|
|
754
|
-
db: DatabaseAdapter;
|
|
755
|
-
}) => void | Promise<void>;
|
|
756
|
-
/**
|
|
757
|
-
* Runs **before** a document is deleted from the database.
|
|
758
|
-
*
|
|
759
|
-
* Throw an error to cancel the deletion — the document will not be removed
|
|
760
|
-
* and the API will return a `500` with your error message.
|
|
761
|
-
*
|
|
762
|
-
* @template TDoc The shape of the collection's document.
|
|
763
|
-
*
|
|
764
|
-
* @example
|
|
765
|
-
* // Prevent deletion when other documents reference this one
|
|
766
|
-
* const guardReferences: CollectionBeforeDeleteHook<Category> = async ({ id, doc }) => {
|
|
767
|
-
* const refs = await db.find({ collection: 'posts', where: { category: { equals: id } } })
|
|
768
|
-
* if (refs.total > 0) throw new Error(`${refs.total} post(s) still reference this category.`)
|
|
769
|
-
* }
|
|
770
|
-
*/
|
|
771
|
-
type CollectionBeforeDeleteHook<TDoc extends object = Record<string, unknown>> = (args: {
|
|
772
|
-
/** The ID of the document about to be deleted. */
|
|
773
|
-
id: string;
|
|
774
|
-
/** The full document about to be deleted. */
|
|
775
|
-
doc: TDoc;
|
|
776
|
-
/** The HTTP request context. */
|
|
777
|
-
req: HookRequestContext;
|
|
778
|
-
/** The authenticated user, or `undefined` for unauthenticated requests. */
|
|
779
|
-
user?: AuthenticatedUser;
|
|
780
|
-
/**
|
|
781
|
-
* Database adapter for cross-collection reads. Write operations (create,
|
|
782
|
-
* update, delete) will throw — use `afterDelete` for post-deletion writes.
|
|
783
|
-
*/
|
|
784
|
-
db: ReadonlyDatabaseAdapter;
|
|
785
|
-
}) => void | Promise<void>;
|
|
786
|
-
/**
|
|
787
|
-
* Runs **after** a document has been deleted from the database.
|
|
788
|
-
*
|
|
789
|
-
* **Isolation**: same as {@link CollectionAfterChangeHook} — errors are caught,
|
|
790
|
-
* logged, and discarded. The deletion is already committed; a hook failure will
|
|
791
|
-
* never cause the deleted ID to appear in the `failed` list of a bulk delete or
|
|
792
|
-
* turn a successful single delete into a 500.
|
|
793
|
-
*
|
|
794
|
-
* Use for cleanup side-effects — removing related media, invalidating caches,
|
|
795
|
-
* notifying downstream services, etc.
|
|
796
|
-
*
|
|
797
|
-
* @template TDoc The shape of the collection's document.
|
|
798
|
-
*/
|
|
799
|
-
type CollectionAfterDeleteHook<TDoc extends object = Record<string, unknown>> = (args: {
|
|
800
|
-
/** The ID of the deleted document. */
|
|
801
|
-
id: string;
|
|
802
|
-
/** The document as it was just before deletion. */
|
|
803
|
-
doc: TDoc;
|
|
804
|
-
/** The HTTP request context. */
|
|
805
|
-
req: HookRequestContext;
|
|
806
|
-
/** The authenticated user, or `undefined` for unauthenticated requests. */
|
|
807
|
-
user?: AuthenticatedUser;
|
|
808
|
-
/**
|
|
809
|
-
* Database adapter with full read/write access. The deletion has already
|
|
810
|
-
* committed — safe for cascade deletes or cleanup writes.
|
|
811
|
-
*/
|
|
812
|
-
db: DatabaseAdapter;
|
|
813
|
-
}) => void | Promise<void>;
|
|
814
|
-
/** @see {@link CollectionBeforeReadHook} */
|
|
815
|
-
type GlobalBeforeReadHook = CollectionBeforeReadHook;
|
|
816
|
-
/**
|
|
817
|
-
* Runs after the global document is fetched, before the response is sent.
|
|
818
|
-
* @see {@link CollectionAfterReadHook}
|
|
819
|
-
*/
|
|
820
|
-
type GlobalAfterReadHook<TDoc extends object = Record<string, unknown>> = (args: {
|
|
821
|
-
doc: TDoc;
|
|
822
|
-
req: HookRequestContext;
|
|
823
|
-
user?: AuthenticatedUser;
|
|
824
|
-
/**
|
|
825
|
-
* Database adapter for cross-collection reads. Write operations (create,
|
|
826
|
-
* update, delete) will throw — use `afterChange` for writes.
|
|
827
|
-
*/
|
|
828
|
-
db: ReadonlyDatabaseAdapter;
|
|
829
|
-
}) => TDoc | Promise<TDoc>;
|
|
830
|
-
/**
|
|
831
|
-
* Runs before the global document is updated.
|
|
832
|
-
* Operation is always `'update'` (globals cannot be created or deleted).
|
|
833
|
-
* @see {@link CollectionBeforeChangeHook}
|
|
834
|
-
*/
|
|
835
|
-
type GlobalBeforeChangeHook<TDoc extends object = Record<string, unknown>> = (args: {
|
|
836
|
-
data: Partial<TDoc>;
|
|
837
|
-
doc?: TDoc;
|
|
838
|
-
req: HookRequestContext;
|
|
839
|
-
user?: AuthenticatedUser;
|
|
840
|
-
operation: "update";
|
|
841
|
-
/**
|
|
842
|
-
* Database adapter for cross-collection reads. Write operations (create,
|
|
843
|
-
* update, delete) will throw — use `afterChange` for writes.
|
|
844
|
-
*/
|
|
845
|
-
db: ReadonlyDatabaseAdapter;
|
|
846
|
-
}) => Partial<TDoc> | void | Promise<Partial<TDoc> | void>;
|
|
847
|
-
/**
|
|
848
|
-
* Runs after the global document is updated. Side-effects only.
|
|
849
|
-
*
|
|
850
|
-
* **Isolation**: errors are caught, logged, and discarded — same behaviour as
|
|
851
|
-
* {@link CollectionAfterChangeHook}. The update is already committed.
|
|
852
|
-
*
|
|
853
|
-
* @see {@link CollectionAfterChangeHook}
|
|
854
|
-
*/
|
|
855
|
-
type GlobalAfterChangeHook<TDoc extends object = Record<string, unknown>> = (args: {
|
|
856
|
-
doc: TDoc;
|
|
857
|
-
previousDoc?: TDoc;
|
|
858
|
-
req: HookRequestContext;
|
|
859
|
-
user?: AuthenticatedUser;
|
|
860
|
-
operation: "update";
|
|
861
|
-
/**
|
|
862
|
-
* Database adapter with full read/write access. The DB write for this
|
|
863
|
-
* operation has already committed — safe for side-effect writes.
|
|
864
|
-
*/
|
|
865
|
-
db: DatabaseAdapter;
|
|
866
|
-
}) => void | Promise<void>;
|
|
867
|
-
/**
|
|
868
|
-
* @deprecated Use the specific hook types instead:
|
|
869
|
-
* {@link CollectionBeforeChangeHook}, {@link CollectionAfterReadHook}, etc.
|
|
870
|
-
*
|
|
871
|
-
* This broad type remains for backwards compatibility with the internal hook runner.
|
|
872
|
-
*/
|
|
873
|
-
type HookFunction<TDoc extends object = Record<string, unknown>> = (args: {
|
|
874
|
-
data?: Partial<TDoc>;
|
|
875
|
-
doc?: TDoc;
|
|
876
|
-
user?: AuthenticatedUser;
|
|
877
|
-
req?: HookRequestContext;
|
|
878
|
-
operation?: "create" | "update" | "delete";
|
|
879
|
-
db?: DatabaseAdapter;
|
|
880
|
-
[key: string]: unknown;
|
|
881
|
-
}) => unknown | Promise<unknown>;
|
|
882
|
-
/**
|
|
883
|
-
* A function that determines whether the current user can perform an operation.
|
|
884
|
-
*
|
|
885
|
-
* Return `true` to allow, `false` to deny.
|
|
886
|
-
* Return a `where`-style object to allow access only to matching documents
|
|
887
|
-
* (useful for multi-tenant setups where users can only see their own data).
|
|
888
|
-
*
|
|
889
|
-
* Can also be expressed as a Jexl expression **string** for simple role checks
|
|
890
|
-
* that need to be serialised (e.g. stored in the database or sent to the Admin UI).
|
|
891
|
-
*
|
|
892
|
-
* @template TDoc The shape of the collection's document.
|
|
893
|
-
*
|
|
894
|
-
* @example
|
|
895
|
-
* // Simple role check
|
|
896
|
-
* access: {
|
|
897
|
-
* delete: ({ user }) => user?.roles?.includes('admin') ?? false,
|
|
898
|
-
* }
|
|
899
|
-
*
|
|
900
|
-
* @example
|
|
901
|
-
* // Row-level: users can only read their own documents
|
|
902
|
-
* access: {
|
|
903
|
-
* read: ({ user }) => ({ owner: { equals: user?.sub } }),
|
|
904
|
-
* }
|
|
905
|
-
*
|
|
906
|
-
* @example
|
|
907
|
-
* // Jexl string — evaluated server-side
|
|
908
|
-
* access: {
|
|
909
|
-
* update: "user.roles contains 'editor'",
|
|
910
|
-
* }
|
|
911
|
-
*/
|
|
912
|
-
type AccessFunction<TDoc extends object = Record<string, unknown>> = (args: {
|
|
913
|
-
user: AuthenticatedUser | undefined;
|
|
914
|
-
doc?: TDoc;
|
|
915
|
-
data?: Partial<TDoc>;
|
|
916
|
-
req: HookRequestContext;
|
|
917
|
-
}) => boolean | Record<string, unknown> | Promise<boolean | Record<string, unknown>>;
|
|
918
|
-
/**
|
|
919
|
-
* Defines a Dyrected collection — a named set of documents with a shared schema.
|
|
920
|
-
*
|
|
921
|
-
* Pass your document's TypeScript type as the generic parameter `TDoc` to get
|
|
922
|
-
* fully typed hooks and access functions:
|
|
923
|
-
*
|
|
924
|
-
* ```ts
|
|
925
|
-
* interface Post {
|
|
926
|
-
* id: string
|
|
927
|
-
* title: string
|
|
928
|
-
* slug: string
|
|
929
|
-
* status: 'draft' | 'published'
|
|
930
|
-
* publishedAt?: string
|
|
931
|
-
* }
|
|
932
|
-
*
|
|
933
|
-
* export const Posts = defineCollection<Post>({
|
|
934
|
-
* slug: 'posts',
|
|
935
|
-
* hooks: {
|
|
936
|
-
* beforeChange: [({ data, operation }) => {
|
|
937
|
-
* // `data` is typed as Partial<Post>
|
|
938
|
-
* if (operation === 'create') return { ...data, status: 'draft' }
|
|
939
|
-
* return data
|
|
940
|
-
* }],
|
|
941
|
-
* afterChange: [({ doc, previousDoc }) => {
|
|
942
|
-
* // `doc` and `previousDoc` are typed as Post
|
|
943
|
-
* if (doc.status !== previousDoc?.status) notifySubscribers(doc)
|
|
944
|
-
* }],
|
|
945
|
-
* },
|
|
946
|
-
* fields: [...],
|
|
947
|
-
* })
|
|
948
|
-
* ```
|
|
949
|
-
*
|
|
950
|
-
* @template TDoc The TypeScript shape of a document in this collection.
|
|
951
|
-
* Defaults to `Record<string, unknown>` for untyped usage.
|
|
952
|
-
*/
|
|
953
|
-
interface CollectionConfig<TDoc extends object = Record<string, unknown>> {
|
|
954
|
-
/**
|
|
955
|
-
* Unique identifier for this collection.
|
|
956
|
-
* Used as the URL segment (`/api/collections/:slug`) and the database table/collection name.
|
|
957
|
-
* Use kebab-case, e.g. `'blog-posts'`.
|
|
958
|
-
*/
|
|
959
|
-
slug: string;
|
|
960
|
-
/**
|
|
961
|
-
* Restricts this collection to a specific site in a multi-tenant deployment.
|
|
962
|
-
* When set, only requests bearing a matching `X-Site-Id` header can access it.
|
|
963
|
-
*/
|
|
964
|
-
siteId?: string;
|
|
965
|
-
/**
|
|
966
|
-
* If `true`, this collection is shared across all sites in a multi-tenant
|
|
967
|
-
* deployment and accessible regardless of the `X-Site-Id` header.
|
|
968
|
-
*/
|
|
969
|
-
shared?: boolean;
|
|
970
|
-
/** Human-readable names for documents in this collection, shown in the Admin UI. */
|
|
971
|
-
labels?: {
|
|
972
|
-
singular: string;
|
|
973
|
-
plural: string;
|
|
974
|
-
};
|
|
975
|
-
/**
|
|
976
|
-
* If `true`, this collection is an **auth collection** — it gains
|
|
977
|
-
* `POST /api/collections/:slug/login` and `POST /api/collections/:slug/logout`
|
|
978
|
-
* endpoints, and documents are expected to have a `password` field.
|
|
979
|
-
*/
|
|
980
|
-
auth?: boolean;
|
|
981
|
-
/**
|
|
982
|
-
* If `true` (or a config object), this collection supports **file uploads**.
|
|
983
|
-
* Documents gain file-related fields (`url`, `filename`, `mimeType`, etc.)
|
|
984
|
-
* and the create endpoint accepts `multipart/form-data`.
|
|
985
|
-
*/
|
|
986
|
-
upload?: boolean | UploadConfig;
|
|
987
|
-
/** Field definitions that make up the document schema for this collection. */
|
|
988
|
-
fields: Field[];
|
|
989
|
-
/**
|
|
990
|
-
* If `true`, Dyrected automatically adds `createdAt` and `updatedAt`
|
|
991
|
-
* timestamp fields to every document. Defaults to `true`.
|
|
992
|
-
*/
|
|
993
|
-
timestamps?: boolean;
|
|
994
|
-
/**
|
|
995
|
-
* Initial documents to seed into this collection the first time it is
|
|
996
|
-
* fetched and found to be empty (e.g. for demo data or defaults).
|
|
997
|
-
*/
|
|
998
|
-
initialData?: Partial<TDoc>[];
|
|
999
|
-
/**
|
|
1000
|
-
* If `true`, every create, update, and delete operation on this collection
|
|
1001
|
-
* is logged to the `__audit` collection with before/after snapshots and the
|
|
1002
|
-
* acting user's identity.
|
|
1003
|
-
*/
|
|
1004
|
-
audit?: boolean;
|
|
1005
|
-
/**
|
|
1006
|
-
* Optional state-machine workflow for this collection. Workflow-enabled
|
|
1007
|
-
* entries keep an editable working revision and an independent public
|
|
1008
|
-
* snapshot, so editing published content never changes the live response.
|
|
1009
|
-
*/
|
|
1010
|
-
workflow?: WorkflowConfig<TDoc>;
|
|
1011
|
-
/**
|
|
1012
|
-
* Collection-level access control.
|
|
1013
|
-
*
|
|
1014
|
-
* Each key is an operation; the value is a function (or Jexl string) that
|
|
1015
|
-
* returns `true` to allow or `false` to deny. Returning a `where`-style
|
|
1016
|
-
* object grants access only to matching documents.
|
|
1017
|
-
*
|
|
1018
|
-
* @example
|
|
1019
|
-
* access: {
|
|
1020
|
-
* read: () => true, // public read
|
|
1021
|
-
* create: ({ user }) => !!user, // logged-in users only
|
|
1022
|
-
* update: ({ user }) => user?.roles?.includes('editor') ?? false,
|
|
1023
|
-
* delete: ({ user }) => user?.roles?.includes('admin') ?? false,
|
|
1024
|
-
* }
|
|
1025
|
-
*/
|
|
1026
|
-
access?: {
|
|
1027
|
-
read?: AccessFunction<TDoc> | string;
|
|
1028
|
-
create?: AccessFunction<TDoc> | string;
|
|
1029
|
-
update?: AccessFunction<TDoc> | string;
|
|
1030
|
-
delete?: AccessFunction<TDoc> | string;
|
|
1031
|
-
};
|
|
1032
|
-
/**
|
|
1033
|
-
* Collection-level lifecycle hooks.
|
|
1034
|
-
*
|
|
1035
|
-
* Hooks run in the order they appear in the array. The return value of each
|
|
1036
|
-
* hook is passed as the input to the next. Throwing inside any hook aborts
|
|
1037
|
-
* the operation and returns a `500` error.
|
|
1038
|
-
*
|
|
1039
|
-
* See the [Hooks reference](/docs/concepts/hooks) for the full lifecycle diagram.
|
|
1040
|
-
*/
|
|
1041
|
-
hooks?: {
|
|
1042
|
-
/**
|
|
1043
|
-
* Runs before the database is queried. Return a modified `where` object
|
|
1044
|
-
* to override the query filter.
|
|
1045
|
-
*/
|
|
1046
|
-
beforeRead?: CollectionBeforeReadHook[];
|
|
1047
|
-
/**
|
|
1048
|
-
* Runs after documents are fetched. Return a modified doc to change what
|
|
1049
|
-
* the client receives. Runs on every document in a list response.
|
|
1050
|
-
*/
|
|
1051
|
-
afterRead?: CollectionAfterReadHook<TDoc>[];
|
|
1052
|
-
/**
|
|
1053
|
-
* Runs before create or update. Return modified data to change what is
|
|
1054
|
-
* written to the database. Throw to abort the write entirely.
|
|
1055
|
-
*/
|
|
1056
|
-
beforeChange?: CollectionBeforeChangeHook<TDoc>[];
|
|
1057
|
-
/**
|
|
1058
|
-
* Runs after create or update is committed. For side-effects only —
|
|
1059
|
-
* webhooks, cache busting, notifications. Return value is ignored.
|
|
1060
|
-
*
|
|
1061
|
-
* Errors are **isolated**: caught, logged, and discarded so a failing
|
|
1062
|
-
* side-effect never turns a successful write into an HTTP 500.
|
|
1063
|
-
* See {@link CollectionAfterChangeHook} for the await-vs-fire-and-forget guidance.
|
|
1064
|
-
*/
|
|
1065
|
-
afterChange?: CollectionAfterChangeHook<TDoc>[];
|
|
1066
|
-
/**
|
|
1067
|
-
* Runs before a document is deleted. Throw to cancel the deletion.
|
|
1068
|
-
*/
|
|
1069
|
-
beforeDelete?: CollectionBeforeDeleteHook<TDoc>[];
|
|
1070
|
-
/**
|
|
1071
|
-
* Runs after a document has been deleted. For cleanup side-effects only.
|
|
1072
|
-
*
|
|
1073
|
-
* Errors are **isolated**: caught, logged, and discarded — the deletion is
|
|
1074
|
-
* already committed and will not be undone.
|
|
1075
|
-
*/
|
|
1076
|
-
afterDelete?: CollectionAfterDeleteHook<TDoc>[];
|
|
1077
|
-
};
|
|
1078
|
-
/** Admin UI configuration for this collection. */
|
|
1079
|
-
admin?: {
|
|
1080
|
-
/**
|
|
1081
|
-
* Lucide icon displayed beside this collection in the Admin sidebar.
|
|
1082
|
-
* Uses Lucide component names, e.g. `'Newspaper'` or `'ShoppingBag'`.
|
|
1083
|
-
*/
|
|
1084
|
-
icon?: AdminIconName;
|
|
1085
|
-
/** Custom component slots for this collection's list view. */
|
|
1086
|
-
components?: CollectionListComponentSlots;
|
|
1087
|
-
/**
|
|
1088
|
-
* The field name used as the document's display title in the Admin list
|
|
1089
|
-
* view and breadcrumbs. Defaults to `'title'` if the field exists.
|
|
1090
|
-
*/
|
|
1091
|
-
useAsTitle?: string;
|
|
1092
|
-
/**
|
|
1093
|
-
* Field names to show as columns in the Admin list view.
|
|
1094
|
-
* Defaults to a sensible set of the first few non-structural fields.
|
|
1095
|
-
*/
|
|
1096
|
-
defaultColumns?: string[];
|
|
1097
|
-
/**
|
|
1098
|
-
* Groups this collection under a named section in the Admin sidebar.
|
|
1099
|
-
* Collections with the same `group` are visually grouped together.
|
|
1100
|
-
*/
|
|
1101
|
-
group?: string;
|
|
1102
|
-
/** If `true`, this collection is not shown in the Admin UI sidebar. */
|
|
1103
|
-
hidden?: boolean;
|
|
1104
|
-
/** If `false`, disables the filter UI entirely for this collection. Defaults to `true`. */
|
|
1105
|
-
filterable?: boolean;
|
|
1106
|
-
/**
|
|
1107
|
-
* URL to open in the Live Preview pane when editing a document.
|
|
1108
|
-
* Pass a function to derive the URL from the document's fields.
|
|
1109
|
-
*
|
|
1110
|
-
* @example
|
|
1111
|
-
* previewUrl: (doc) => `https://mysite.com/blog/${doc.slug}`
|
|
1112
|
-
*/
|
|
1113
|
-
previewUrl?: string | ((doc: TDoc, opts: {
|
|
1114
|
-
locale?: string;
|
|
1115
|
-
}) => string | null);
|
|
1116
|
-
/**
|
|
1117
|
-
* How the Live Preview pane communicates with the frontend.
|
|
1118
|
-
* - `'postMessage'` (default) — sends a `postMessage` with the current doc data.
|
|
1119
|
-
* - `'token'` — passes a short-lived preview token as a query parameter.
|
|
1120
|
-
*/
|
|
1121
|
-
previewMode?: "postMessage" | "token";
|
|
1122
|
-
/**
|
|
1123
|
-
* Frontend URL pattern for this collection, used by `url` fields to
|
|
1124
|
-
* resolve internal links. Use `{fieldName}` placeholders.
|
|
1125
|
-
*
|
|
1126
|
-
* @example
|
|
1127
|
-
* urlPattern: '/blog/{slug}' // → /blog/my-post
|
|
1128
|
-
* urlPattern: '/{slug}' // → /about
|
|
1129
|
-
*/
|
|
1130
|
-
urlPattern?: string;
|
|
1131
|
-
};
|
|
1132
|
-
}
|
|
1133
|
-
/**
|
|
1134
|
-
* Defines a Dyrected global — a singleton document without pagination or IDs.
|
|
1135
|
-
*
|
|
1136
|
-
* Globals are ideal for site-wide settings, feature flags, or any data where
|
|
1137
|
-
* there is always exactly one record (e.g. `site-settings`, `navigation`, `theme`).
|
|
1138
|
-
*
|
|
1139
|
-
* Pass your document's TypeScript type as the generic parameter `TDoc` to get
|
|
1140
|
-
* fully typed hooks:
|
|
1141
|
-
*
|
|
1142
|
-
* ```ts
|
|
1143
|
-
* interface SiteSettings {
|
|
1144
|
-
* siteName: string
|
|
1145
|
-
* tagline: string
|
|
1146
|
-
* maintenanceMode: boolean
|
|
1147
|
-
* }
|
|
1148
|
-
*
|
|
1149
|
-
* export const Settings = defineGlobal<SiteSettings>({
|
|
1150
|
-
* slug: 'site-settings',
|
|
1151
|
-
* hooks: {
|
|
1152
|
-
* afterChange: [({ doc }) => {
|
|
1153
|
-
* // `doc` is typed as SiteSettings
|
|
1154
|
-
* if (doc.maintenanceMode) alertOnCall()
|
|
1155
|
-
* }],
|
|
1156
|
-
* },
|
|
1157
|
-
* fields: [...],
|
|
1158
|
-
* })
|
|
1159
|
-
* ```
|
|
1160
|
-
*
|
|
1161
|
-
* @template TDoc The TypeScript shape of this global's document.
|
|
1162
|
-
*/
|
|
1163
|
-
interface GlobalConfig<TDoc extends object = Record<string, unknown>> {
|
|
1164
|
-
/**
|
|
1165
|
-
* Unique identifier for this global.
|
|
1166
|
-
* Used as the URL segment (`/api/globals/:slug`) and the storage key.
|
|
1167
|
-
*/
|
|
1168
|
-
slug: string;
|
|
1169
|
-
/** Restricts this global to a specific site in a multi-tenant deployment. */
|
|
1170
|
-
siteId?: string;
|
|
1171
|
-
/**
|
|
1172
|
-
* If `true`, this global is shared across all sites in a multi-tenant
|
|
1173
|
-
* deployment.
|
|
1174
|
-
*/
|
|
1175
|
-
shared?: boolean;
|
|
1176
|
-
/** Human-readable label shown in the Admin UI sidebar. */
|
|
1177
|
-
label?: string;
|
|
1178
|
-
/** Field definitions for this global's document schema. */
|
|
1179
|
-
fields: Field[];
|
|
1180
|
-
/** Access control for reading and updating this global. */
|
|
1181
|
-
access?: {
|
|
1182
|
-
read?: AccessFunction<TDoc>;
|
|
1183
|
-
update?: AccessFunction<TDoc>;
|
|
1184
|
-
};
|
|
1185
|
-
/**
|
|
1186
|
-
* Global-level lifecycle hooks.
|
|
1187
|
-
* Globals support `beforeRead`, `afterRead`, `beforeChange`, and `afterChange`.
|
|
1188
|
-
* There are no delete hooks since globals cannot be deleted.
|
|
1189
|
-
*/
|
|
1190
|
-
hooks?: {
|
|
1191
|
-
beforeRead?: GlobalBeforeReadHook[];
|
|
1192
|
-
afterRead?: GlobalAfterReadHook<TDoc>[];
|
|
1193
|
-
beforeChange?: GlobalBeforeChangeHook<TDoc>[];
|
|
1194
|
-
afterChange?: GlobalAfterChangeHook<TDoc>[];
|
|
1195
|
-
};
|
|
1196
|
-
/** Admin UI configuration for this global. */
|
|
1197
|
-
admin?: {
|
|
1198
|
-
/**
|
|
1199
|
-
* Lucide icon displayed beside this global in the Admin sidebar.
|
|
1200
|
-
* Uses Lucide component names, e.g. `'Settings2'` or `'Palette'`.
|
|
1201
|
-
*/
|
|
1202
|
-
icon?: AdminIconName;
|
|
1203
|
-
/** Groups this global under a named section in the Admin sidebar. */
|
|
1204
|
-
group?: string;
|
|
1205
|
-
/** If `true`, this global is not shown in the Admin UI sidebar. */
|
|
1206
|
-
hidden?: boolean;
|
|
1207
|
-
};
|
|
1208
|
-
/**
|
|
1209
|
-
* Initial data to seed this global with the first time it is fetched and
|
|
1210
|
-
* found to be empty.
|
|
1211
|
-
*/
|
|
1212
|
-
initialData?: Partial<TDoc>;
|
|
1213
|
-
}
|
|
1214
|
-
/**
|
|
1215
|
-
* The interface every database adapter must implement.
|
|
1216
|
-
*
|
|
1217
|
-
* Dyrected ships adapters for PostgreSQL, MySQL, SQLite, and MongoDB.
|
|
1218
|
-
* Implement this interface to connect any other database.
|
|
1219
|
-
*/
|
|
1220
|
-
interface DatabaseAdapter {
|
|
1221
|
-
/** Find a paginated list of documents in a collection. */
|
|
1222
|
-
find(args: {
|
|
1223
|
-
collection: string;
|
|
1224
|
-
where?: Record<string, unknown>;
|
|
1225
|
-
limit?: number;
|
|
1226
|
-
page?: number;
|
|
1227
|
-
sort?: string;
|
|
1228
|
-
}): Promise<PaginatedResult>;
|
|
1229
|
-
/** Find a single document by its ID. Returns `null` if not found. */
|
|
1230
|
-
findOne(args: {
|
|
1231
|
-
collection: string;
|
|
1232
|
-
id: string;
|
|
1233
|
-
}): Promise<BaseDocument | null>;
|
|
1234
|
-
/** Insert a new document and return it with its generated `id`. */
|
|
1235
|
-
create(args: {
|
|
1236
|
-
collection: string;
|
|
1237
|
-
data: Record<string, unknown>;
|
|
1238
|
-
}): Promise<BaseDocument>;
|
|
1239
|
-
/** Update a document by ID and return the updated document. */
|
|
1240
|
-
update(args: {
|
|
1241
|
-
collection: string;
|
|
1242
|
-
id: string;
|
|
1243
|
-
data: Record<string, unknown>;
|
|
1244
|
-
}): Promise<BaseDocument>;
|
|
1245
|
-
/** Delete a document by ID. Return value is intentionally untyped — callers do not use it. */
|
|
1246
|
-
delete(args: {
|
|
1247
|
-
collection: string;
|
|
1248
|
-
id: string;
|
|
1249
|
-
}): Promise<unknown>;
|
|
1250
|
-
/** Fetch the singleton document for a global. Returns an empty object if not yet initialised. */
|
|
1251
|
-
getGlobal(args: {
|
|
1252
|
-
slug: string;
|
|
1253
|
-
}): Promise<Record<string, unknown>>;
|
|
1254
|
-
/** Create or replace the singleton document for a global. */
|
|
1255
|
-
updateGlobal(args: {
|
|
1256
|
-
slug: string;
|
|
1257
|
-
data: Record<string, unknown>;
|
|
1258
|
-
}): Promise<Record<string, unknown>>;
|
|
1259
|
-
/**
|
|
1260
|
-
* Sync the database schema with the current collection and global configs.
|
|
1261
|
-
* Called on startup to create tables/collections that don't exist yet.
|
|
1262
|
-
* Not all adapters implement this (e.g. MongoDB is schema-less).
|
|
1263
|
-
*/
|
|
1264
|
-
sync?(collections: CollectionConfig[], globals: GlobalConfig[]): Promise<void>;
|
|
1265
|
-
/**
|
|
1266
|
-
* Execute a raw SQL query or database command.
|
|
1267
|
-
* Optional — not all adapters support raw access.
|
|
1268
|
-
*/
|
|
1269
|
-
execute?(query: string, params?: unknown[]): Promise<unknown>;
|
|
1270
|
-
/**
|
|
1271
|
-
* Run all adapter operations in `callback` as one atomic transaction.
|
|
1272
|
-
* Shipped adapters implement this; workflow transitions require it.
|
|
1273
|
-
*/
|
|
1274
|
-
transaction?<T>(callback: (db: DatabaseAdapter) => Promise<T>): Promise<T>;
|
|
1275
|
-
}
|
|
1276
|
-
/**
|
|
1277
|
-
* Read-only view of the database adapter. Exposes only `find`, `findOne`,
|
|
1278
|
-
* and `getGlobal` — no write operations.
|
|
1279
|
-
*
|
|
1280
|
-
* Passed to `beforeChange`, `beforeDelete`, `beforeRead`, `afterRead`,
|
|
1281
|
-
* and field-level hooks. Write operations are available in `afterChange`
|
|
1282
|
-
* and `afterDelete` hooks where the full {@link DatabaseAdapter} is provided.
|
|
1283
|
-
*/
|
|
1284
|
-
type ReadonlyDatabaseAdapter = Pick<DatabaseAdapter, "find" | "findOne" | "getGlobal">;
|
|
1285
|
-
/**
|
|
1286
|
-
* The interface every storage adapter must implement.
|
|
1287
|
-
*
|
|
1288
|
-
* Dyrected ships adapters for local disk, S3, Cloudflare R2, Cloudinary, and
|
|
1289
|
-
* Backblaze B2. Implement this interface to use any other storage provider.
|
|
1290
|
-
*/
|
|
1291
|
-
interface StorageAdapter {
|
|
1292
|
-
/**
|
|
1293
|
-
* Upload a file and return its metadata (URL, dimensions, etc.).
|
|
1294
|
-
* The `prefix` is a path prefix used for multi-tenant setups.
|
|
1295
|
-
*/
|
|
1296
|
-
upload(args: {
|
|
1297
|
-
filename: string;
|
|
1298
|
-
buffer: Uint8Array;
|
|
1299
|
-
mimeType: string;
|
|
1300
|
-
prefix?: string;
|
|
1301
|
-
}): Promise<FileData>;
|
|
1302
|
-
/** Delete a file by its stored filename. */
|
|
1303
|
-
delete(args: {
|
|
1304
|
-
filename: string;
|
|
1305
|
-
}): Promise<void>;
|
|
1306
|
-
/** Return the public URL for a stored file. */
|
|
1307
|
-
getURL(args: {
|
|
1308
|
-
filename: string;
|
|
1309
|
-
}): string;
|
|
1310
|
-
/**
|
|
1311
|
-
* Retrieve the file's raw bytes and MIME type for serving via the API.
|
|
1312
|
-
* Only needed by adapters that serve files through the Dyrected API
|
|
1313
|
-
* (e.g. `LocalStorage`). Cloud adapters return `null` here and rely on
|
|
1314
|
-
* direct CDN URLs instead.
|
|
1315
|
-
*/
|
|
1316
|
-
resolve?(args: {
|
|
1317
|
-
filename: string;
|
|
1318
|
-
}): Promise<{
|
|
1319
|
-
buffer: Uint8Array;
|
|
1320
|
-
mimeType: string;
|
|
1321
|
-
} | null>;
|
|
1322
|
-
}
|
|
1323
|
-
/**
|
|
1324
|
-
* Processes uploaded images — generates metadata (dimensions, BlurHash) and
|
|
1325
|
-
* produces resized variants defined in `UploadConfig.imageSizes`.
|
|
1326
|
-
*
|
|
1327
|
-
* @example
|
|
1328
|
-
* import { SharpImageService } from '@dyrected/image-sharp'
|
|
1329
|
-
* defineConfig({ image: new SharpImageService(), ... })
|
|
1330
|
-
*/
|
|
1331
|
-
interface ImageService {
|
|
1332
|
-
process(args: {
|
|
1333
|
-
buffer: Uint8Array;
|
|
1334
|
-
mimeType: string;
|
|
1335
|
-
config?: boolean | UploadConfig;
|
|
1336
|
-
focalPoint?: {
|
|
1337
|
-
x: number;
|
|
1338
|
-
y: number;
|
|
1339
|
-
};
|
|
1340
|
-
}): Promise<{
|
|
1341
|
-
metadata: {
|
|
1342
|
-
width?: number;
|
|
1343
|
-
height?: number;
|
|
1344
|
-
/** Base64-encoded BlurHash for progressive loading. */
|
|
1345
|
-
blurhash?: string;
|
|
1346
|
-
};
|
|
1347
|
-
/** Generated image sizes keyed by their `name`. */
|
|
1348
|
-
sizes?: Record<string, {
|
|
1349
|
-
buffer: Uint8Array;
|
|
1350
|
-
width: number;
|
|
1351
|
-
height: number;
|
|
1352
|
-
filename: string;
|
|
1353
|
-
}>;
|
|
1354
|
-
}>;
|
|
1355
|
-
}
|
|
1356
|
-
/**
|
|
1357
|
-
* The root configuration object passed to `createDyrectedApp`.
|
|
1358
|
-
*
|
|
1359
|
-
* This is the single source of truth for your entire Dyrected instance —
|
|
1360
|
-
* collections, globals, database adapter, storage, email, and more.
|
|
1361
|
-
*
|
|
1362
|
-
* @example
|
|
1363
|
-
* import { defineConfig } from '@dyrected/core'
|
|
1364
|
-
* import { SQLiteAdapter } from '@dyrected/db-sqlite'
|
|
1365
|
-
*
|
|
1366
|
-
* export default defineConfig({
|
|
1367
|
-
* db: new SQLiteAdapter({ filename: './db.sqlite' }),
|
|
1368
|
-
* collections: [Posts, Users],
|
|
1369
|
-
* globals: [SiteSettings],
|
|
1370
|
-
* })
|
|
1371
|
-
*/
|
|
1372
|
-
interface DyrectedConfig {
|
|
1373
|
-
/** Collection definitions. Each collection maps to a database table/collection. */
|
|
1374
|
-
collections: CollectionConfig<any>[];
|
|
1375
|
-
/** Global (singleton) definitions. Each global maps to a single document. */
|
|
1376
|
-
globals: GlobalConfig<any>[];
|
|
1377
|
-
/**
|
|
1378
|
-
* The database adapter. Required for all data operations.
|
|
1379
|
-
* @see {@link DatabaseAdapter}
|
|
1380
|
-
*/
|
|
1381
|
-
db?: DatabaseAdapter;
|
|
1382
|
-
/**
|
|
1383
|
-
* The storage adapter for file uploads.
|
|
1384
|
-
* Required when any collection has `upload: true`.
|
|
1385
|
-
* @see {@link StorageAdapter}
|
|
1386
|
-
*/
|
|
1387
|
-
storage?: StorageAdapter;
|
|
1388
|
-
/**
|
|
1389
|
-
* The image processing service. Required when any upload collection
|
|
1390
|
-
* defines `imageSizes`.
|
|
1391
|
-
* @see {@link ImageService}
|
|
1392
|
-
*/
|
|
1393
|
-
image?: ImageService;
|
|
1394
|
-
/** Admin UI branding and metadata. */
|
|
1395
|
-
admin?: AdminConfig;
|
|
1396
|
-
/**
|
|
1397
|
-
* Deployment-level authentication strategy for the CMS dashboard (`/admin`).
|
|
1398
|
-
* This is separate from collection-level `auth: true`, which continues to
|
|
1399
|
-
* power application/customer auth independently.
|
|
1400
|
-
*/
|
|
1401
|
-
adminAuth?: AdminAuthConfig;
|
|
1402
|
-
/**
|
|
1403
|
-
* Email transport configuration. Required for welcome emails, password
|
|
1404
|
-
* resets, and invite links.
|
|
1405
|
-
*
|
|
1406
|
-
* @example
|
|
1407
|
-
* email: {
|
|
1408
|
-
* from: 'no-reply@myapp.com',
|
|
1409
|
-
* send: async ({ to, subject, html }) => {
|
|
1410
|
-
* await resend.emails.send({ from, to, subject, html })
|
|
1411
|
-
* },
|
|
1412
|
-
* }
|
|
1413
|
-
*/
|
|
1414
|
-
email?: {
|
|
1415
|
-
/** The `From` address for all outbound emails. */
|
|
1416
|
-
from: string;
|
|
1417
|
-
/** The send function. Wire in any email provider (Resend, SendGrid, SES, etc.). */
|
|
1418
|
-
send: (args: {
|
|
1419
|
-
to: string;
|
|
1420
|
-
subject: string;
|
|
1421
|
-
html: string;
|
|
1422
|
-
}) => Promise<void>;
|
|
1423
|
-
/** Override the default email templates. */
|
|
1424
|
-
templates?: {
|
|
1425
|
-
welcome?: (args: {
|
|
1426
|
-
email: string;
|
|
1427
|
-
}) => {
|
|
1428
|
-
subject?: string;
|
|
1429
|
-
html: string;
|
|
1430
|
-
};
|
|
1431
|
-
invite?: (args: {
|
|
1432
|
-
token: string;
|
|
1433
|
-
invitedByEmail?: string;
|
|
1434
|
-
}) => {
|
|
1435
|
-
subject?: string;
|
|
1436
|
-
html: string;
|
|
1437
|
-
};
|
|
1438
|
-
resetPassword?: (args: {
|
|
1439
|
-
token: string;
|
|
1440
|
-
url?: string;
|
|
1441
|
-
}) => {
|
|
1442
|
-
subject?: string;
|
|
1443
|
-
html: string;
|
|
1444
|
-
};
|
|
1445
|
-
passwordChanged?: (args: {
|
|
1446
|
-
email: string;
|
|
1447
|
-
}) => {
|
|
1448
|
-
subject?: string;
|
|
1449
|
-
html: string;
|
|
1450
|
-
};
|
|
1451
|
-
};
|
|
1452
|
-
};
|
|
1453
|
-
/**
|
|
1454
|
-
* Redis connection URL. Required for distributed caching of dynamic option
|
|
1455
|
-
* resolvers and other server-side caches in multi-instance deployments.
|
|
1456
|
-
*
|
|
1457
|
-
* @example
|
|
1458
|
-
* redis: { url: process.env.REDIS_URL }
|
|
1459
|
-
*/
|
|
1460
|
-
redis?: {
|
|
1461
|
-
url: string;
|
|
1462
|
-
};
|
|
1463
|
-
/** Durable lifecycle-event delivery configuration. */
|
|
1464
|
-
events?: {
|
|
1465
|
-
handlers: LifecycleEventHandler[];
|
|
1466
|
-
/** Maximum delivery attempts before an event remains failed. Defaults to 8. */
|
|
1467
|
-
maxAttempts?: number;
|
|
1468
|
-
/** Initial exponential-backoff delay in milliseconds. Defaults to 1000. */
|
|
1469
|
-
retryDelayMs?: number;
|
|
1470
|
-
};
|
|
1471
|
-
/**
|
|
1472
|
-
* Cross-Origin Resource Sharing (CORS) configuration.
|
|
1473
|
-
* List all origins that are allowed to call the Dyrected API.
|
|
1474
|
-
*
|
|
1475
|
-
* @example
|
|
1476
|
-
* cors: { origins: ['https://myapp.com', 'https://www.myapp.com'] }
|
|
1477
|
-
*/
|
|
1478
|
-
cors?: {
|
|
1479
|
-
origins: string[];
|
|
1480
|
-
};
|
|
1481
|
-
/**
|
|
1482
|
-
* Callback to dynamically fetch additional collections and globals for a
|
|
1483
|
-
* given site ID at request time. Used in multi-tenant deployments where each
|
|
1484
|
-
* site has its own schema stored in the database.
|
|
1485
|
-
*
|
|
1486
|
-
* @param siteId The `X-Site-Id` header value from the incoming request.
|
|
1487
|
-
* @returns Extra collections and globals to merge into the config for this request.
|
|
1488
|
-
*
|
|
1489
|
-
* @example
|
|
1490
|
-
* onSchemaFetch: async (siteId) => {
|
|
1491
|
-
* const site = await db.findOne({ collection: 'sites', id: siteId })
|
|
1492
|
-
* return buildSchemaFromSiteConfig(site)
|
|
1493
|
-
* }
|
|
1494
|
-
*/
|
|
1495
|
-
onSchemaFetch?: (siteId: string) => Promise<{
|
|
1496
|
-
collections?: CollectionConfig<any>[];
|
|
1497
|
-
globals?: GlobalConfig<any>[];
|
|
1498
|
-
admin?: AdminConfig;
|
|
1499
|
-
adminAuth?: AdminAuthConfig;
|
|
1500
|
-
}>;
|
|
1501
|
-
}
|
|
1502
|
-
|
|
1503
|
-
export { type GlobalBeforeChangeHook as $, type AdminAuthConfig as A, type Block as B, type CollectionConfig as C, type DyrectedConfig as D, type CollectionListComponentSlots as E, type Field as F, type GlobalConfig as G, type HookRequestContext as H, type CustomAdminAuthProvider as I, type DatabaseAdapter as J, type DateField as K, type LifecycleEventName as L, type DateTimeField as M, type DynamicOptionItem as N, type DynamicOptionsConfig as O, type PublicAdminAuthConfig as P, type DynamicOptionsResolver as Q, type DynamicOptionsResolverArgs as R, type EmailField as S, type FieldAfterReadHook as T, type FieldBeforeChangeHook as U, type FieldHook as V, type WorkflowConfig as W, type FieldType as X, type FileData as Y, type GlobalAfterChangeHook as Z, type GlobalAfterReadHook as _, type AuthenticatedUser as a, type GlobalBeforeReadHook as a0, type HookFunction as a1, type IconField as a2, type ImageField as a3, type ImageService as a4, type JoinField as a5, type JsonField as a6, LIFECYCLE_EVENT_NAMES as a7, type LifecycleEventHandler as a8, type MultiSelectField as a9, type NumberField as aa, type OIDCAdminAuthProvider as ab, type ObjectField as ac, type PaginatedResult as ad, type PublicAdminAuthProvider as ae, type RadioField as af, type ReadonlyDatabaseAdapter as ag, type RelationshipField as ah, type RichTextField as ai, type RowField as aj, type SelectField as ak, type StorageAdapter as al, type TextField as am, type TextareaField as an, type TimeField as ao, type UploadConfig as ap, type UrlField as aq, type WorkflowMetadata as ar, type WorkflowRole as as, type WorkflowState as at, type WorkflowTransitionContext as au, type WorkflowTransition as b, type LifecycleEvent as c, type BaseDocument as d, type AccessFunction as e, type AdminAuthAccessResolution as f, type AdminAuthClaimMapping as g, type AdminAuthProvider as h, type AdminAuthProvisioningMode as i, type AdminAuthResolveAccessArgs as j, type AdminAuthResolvedIdentity as k, type AdminConfig as l, type AdminDashboardComponentSlots as m, type AdminIconName as n, type ArrayField as o, type BaseAdminAuthProvider as p, type BlocksField as q, type BooleanField as r, type CollectionAfterChangeHook as s, type CollectionAfterDeleteHook as t, type CollectionAfterReadHook as u, type CollectionAfterTransitionHook as v, type CollectionBeforeChangeHook as w, type CollectionBeforeDeleteHook as x, type CollectionBeforeReadHook as y, type CollectionBeforeTransitionHook as z };
|