@actuate-media/cms-core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (431) hide show
  1. package/dist/__tests__/actions/document-crud.test.d.ts +2 -0
  2. package/dist/__tests__/actions/document-crud.test.d.ts.map +1 -0
  3. package/dist/__tests__/actions/document-crud.test.js +156 -0
  4. package/dist/__tests__/actions/document-crud.test.js.map +1 -0
  5. package/dist/__tests__/auth/password.test.d.ts +2 -0
  6. package/dist/__tests__/auth/password.test.d.ts.map +1 -0
  7. package/dist/__tests__/auth/password.test.js +102 -0
  8. package/dist/__tests__/auth/password.test.js.map +1 -0
  9. package/dist/__tests__/auth/session.test.d.ts +2 -0
  10. package/dist/__tests__/auth/session.test.d.ts.map +1 -0
  11. package/dist/__tests__/auth/session.test.js +66 -0
  12. package/dist/__tests__/auth/session.test.js.map +1 -0
  13. package/dist/__tests__/codegen/generate-types.test.d.ts +2 -0
  14. package/dist/__tests__/codegen/generate-types.test.d.ts.map +1 -0
  15. package/dist/__tests__/codegen/generate-types.test.js +173 -0
  16. package/dist/__tests__/codegen/generate-types.test.js.map +1 -0
  17. package/dist/__tests__/scheduling/scheduling.test.d.ts +2 -0
  18. package/dist/__tests__/scheduling/scheduling.test.d.ts.map +1 -0
  19. package/dist/__tests__/scheduling/scheduling.test.js +84 -0
  20. package/dist/__tests__/scheduling/scheduling.test.js.map +1 -0
  21. package/dist/__tests__/security/access.test.d.ts +2 -0
  22. package/dist/__tests__/security/access.test.d.ts.map +1 -0
  23. package/dist/__tests__/security/access.test.js +181 -0
  24. package/dist/__tests__/security/access.test.js.map +1 -0
  25. package/dist/__tests__/security/csrf.test.d.ts +2 -0
  26. package/dist/__tests__/security/csrf.test.d.ts.map +1 -0
  27. package/dist/__tests__/security/csrf.test.js +40 -0
  28. package/dist/__tests__/security/csrf.test.js.map +1 -0
  29. package/dist/__tests__/security/rate-limit.test.d.ts +2 -0
  30. package/dist/__tests__/security/rate-limit.test.d.ts.map +1 -0
  31. package/dist/__tests__/security/rate-limit.test.js +62 -0
  32. package/dist/__tests__/security/rate-limit.test.js.map +1 -0
  33. package/dist/__tests__/security/reauth.test.d.ts +2 -0
  34. package/dist/__tests__/security/reauth.test.d.ts.map +1 -0
  35. package/dist/__tests__/security/reauth.test.js +30 -0
  36. package/dist/__tests__/security/reauth.test.js.map +1 -0
  37. package/dist/__tests__/security/sanitize.test.d.ts +2 -0
  38. package/dist/__tests__/security/sanitize.test.d.ts.map +1 -0
  39. package/dist/__tests__/security/sanitize.test.js +75 -0
  40. package/dist/__tests__/security/sanitize.test.js.map +1 -0
  41. package/dist/__tests__/webhooks/webhooks.test.d.ts +2 -0
  42. package/dist/__tests__/webhooks/webhooks.test.d.ts.map +1 -0
  43. package/dist/__tests__/webhooks/webhooks.test.js +96 -0
  44. package/dist/__tests__/webhooks/webhooks.test.js.map +1 -0
  45. package/dist/a11y/index.d.ts +25 -0
  46. package/dist/a11y/index.d.ts.map +1 -0
  47. package/dist/a11y/index.js +88 -0
  48. package/dist/a11y/index.js.map +1 -0
  49. package/dist/actions.d.ts +42 -0
  50. package/dist/actions.d.ts.map +1 -0
  51. package/dist/actions.js +391 -0
  52. package/dist/actions.js.map +1 -0
  53. package/dist/api/handler-factory.d.ts +7 -0
  54. package/dist/api/handler-factory.d.ts.map +1 -0
  55. package/dist/api/handler-factory.js +120 -0
  56. package/dist/api/handler-factory.js.map +1 -0
  57. package/dist/api/handlers.d.ts +4 -0
  58. package/dist/api/handlers.d.ts.map +1 -0
  59. package/dist/api/handlers.js +2119 -0
  60. package/dist/api/handlers.js.map +1 -0
  61. package/dist/api/index.d.ts +23 -0
  62. package/dist/api/index.d.ts.map +1 -0
  63. package/dist/api/index.js +57 -0
  64. package/dist/api/index.js.map +1 -0
  65. package/dist/api/openapi.d.ts +3 -0
  66. package/dist/api/openapi.d.ts.map +1 -0
  67. package/dist/api/openapi.js +348 -0
  68. package/dist/api/openapi.js.map +1 -0
  69. package/dist/auth/index.d.ts +11 -0
  70. package/dist/auth/index.d.ts.map +1 -0
  71. package/dist/auth/index.js +9 -0
  72. package/dist/auth/index.js.map +1 -0
  73. package/dist/auth/oauth.d.ts +84 -0
  74. package/dist/auth/oauth.d.ts.map +1 -0
  75. package/dist/auth/oauth.js +201 -0
  76. package/dist/auth/oauth.js.map +1 -0
  77. package/dist/auth/password.d.ts +13 -0
  78. package/dist/auth/password.d.ts.map +1 -0
  79. package/dist/auth/password.js +47 -0
  80. package/dist/auth/password.js.map +1 -0
  81. package/dist/auth/providers/github.d.ts +9 -0
  82. package/dist/auth/providers/github.d.ts.map +1 -0
  83. package/dist/auth/providers/github.js +10 -0
  84. package/dist/auth/providers/github.js.map +1 -0
  85. package/dist/auth/providers/google.d.ts +9 -0
  86. package/dist/auth/providers/google.d.ts.map +1 -0
  87. package/dist/auth/providers/google.js +10 -0
  88. package/dist/auth/providers/google.js.map +1 -0
  89. package/dist/auth/providers/microsoft.d.ts +9 -0
  90. package/dist/auth/providers/microsoft.d.ts.map +1 -0
  91. package/dist/auth/providers/microsoft.js +11 -0
  92. package/dist/auth/providers/microsoft.js.map +1 -0
  93. package/dist/auth/session.d.ts +21 -0
  94. package/dist/auth/session.d.ts.map +1 -0
  95. package/dist/auth/session.js +35 -0
  96. package/dist/auth/session.js.map +1 -0
  97. package/dist/auth/totp.d.ts +5 -0
  98. package/dist/auth/totp.d.ts.map +1 -0
  99. package/dist/auth/totp.js +86 -0
  100. package/dist/auth/totp.js.map +1 -0
  101. package/dist/backup/index.d.ts +19 -0
  102. package/dist/backup/index.d.ts.map +1 -0
  103. package/dist/backup/index.js +22 -0
  104. package/dist/backup/index.js.map +1 -0
  105. package/dist/cache/index.d.ts +15 -0
  106. package/dist/cache/index.d.ts.map +1 -0
  107. package/dist/cache/index.js +32 -0
  108. package/dist/cache/index.js.map +1 -0
  109. package/dist/client.d.ts +30 -0
  110. package/dist/client.d.ts.map +1 -0
  111. package/dist/client.js +50 -0
  112. package/dist/client.js.map +1 -0
  113. package/dist/codegen/index.d.ts +4 -0
  114. package/dist/codegen/index.d.ts.map +1 -0
  115. package/dist/codegen/index.js +370 -0
  116. package/dist/codegen/index.js.map +1 -0
  117. package/dist/collections/index.d.ts +17 -0
  118. package/dist/collections/index.d.ts.map +1 -0
  119. package/dist/collections/index.js +29 -0
  120. package/dist/collections/index.js.map +1 -0
  121. package/dist/config/index.d.ts +6 -0
  122. package/dist/config/index.d.ts.map +1 -0
  123. package/dist/config/index.js +74 -0
  124. package/dist/config/index.js.map +1 -0
  125. package/dist/config/types.d.ts +307 -0
  126. package/dist/config/types.d.ts.map +1 -0
  127. package/dist/config/types.js +3 -0
  128. package/dist/config/types.js.map +1 -0
  129. package/dist/content/ai-api.d.ts +21 -0
  130. package/dist/content/ai-api.d.ts.map +1 -0
  131. package/dist/content/ai-api.js +19 -0
  132. package/dist/content/ai-api.js.map +1 -0
  133. package/dist/content/content-graph.d.ts +25 -0
  134. package/dist/content/content-graph.d.ts.map +1 -0
  135. package/dist/content/content-graph.js +40 -0
  136. package/dist/content/content-graph.js.map +1 -0
  137. package/dist/content/extract.d.ts +7 -0
  138. package/dist/content/extract.d.ts.map +1 -0
  139. package/dist/content/extract.js +33 -0
  140. package/dist/content/extract.js.map +1 -0
  141. package/dist/content/index.d.ts +8 -0
  142. package/dist/content/index.d.ts.map +1 -0
  143. package/dist/content/index.js +5 -0
  144. package/dist/content/index.js.map +1 -0
  145. package/dist/content/structured-data.d.ts +80 -0
  146. package/dist/content/structured-data.d.ts.map +1 -0
  147. package/dist/content/structured-data.js +295 -0
  148. package/dist/content/structured-data.js.map +1 -0
  149. package/dist/db/adapters/mysql.d.ts +5 -0
  150. package/dist/db/adapters/mysql.d.ts.map +1 -0
  151. package/dist/db/adapters/mysql.js +18 -0
  152. package/dist/db/adapters/mysql.js.map +1 -0
  153. package/dist/db/adapters/postgres.d.ts +7 -0
  154. package/dist/db/adapters/postgres.d.ts.map +1 -0
  155. package/dist/db/adapters/postgres.js +20 -0
  156. package/dist/db/adapters/postgres.js.map +1 -0
  157. package/dist/db/adapters/sqlite.d.ts +5 -0
  158. package/dist/db/adapters/sqlite.d.ts.map +1 -0
  159. package/dist/db/adapters/sqlite.js +19 -0
  160. package/dist/db/adapters/sqlite.js.map +1 -0
  161. package/dist/db/create-adapter.d.ts +11 -0
  162. package/dist/db/create-adapter.d.ts.map +1 -0
  163. package/dist/db/create-adapter.js +43 -0
  164. package/dist/db/create-adapter.js.map +1 -0
  165. package/dist/db/index.d.ts +9 -0
  166. package/dist/db/index.d.ts.map +1 -0
  167. package/dist/db/index.js +5 -0
  168. package/dist/db/index.js.map +1 -0
  169. package/dist/db.d.ts +20 -0
  170. package/dist/db.d.ts.map +1 -0
  171. package/dist/db.js +35 -0
  172. package/dist/db.js.map +1 -0
  173. package/dist/fields/index.d.ts +15 -0
  174. package/dist/fields/index.d.ts.map +1 -0
  175. package/dist/fields/index.js +87 -0
  176. package/dist/fields/index.js.map +1 -0
  177. package/dist/forms/analytics.d.ts +62 -0
  178. package/dist/forms/analytics.d.ts.map +1 -0
  179. package/dist/forms/analytics.js +95 -0
  180. package/dist/forms/analytics.js.map +1 -0
  181. package/dist/forms/attribution.d.ts +29 -0
  182. package/dist/forms/attribution.d.ts.map +1 -0
  183. package/dist/forms/attribution.js +216 -0
  184. package/dist/forms/attribution.js.map +1 -0
  185. package/dist/forms/index.d.ts +5 -0
  186. package/dist/forms/index.d.ts.map +1 -0
  187. package/dist/forms/index.js +3 -0
  188. package/dist/forms/index.js.map +1 -0
  189. package/dist/graphql/index.d.ts +11 -0
  190. package/dist/graphql/index.d.ts.map +1 -0
  191. package/dist/graphql/index.js +58 -0
  192. package/dist/graphql/index.js.map +1 -0
  193. package/dist/graphql/resolvers.d.ts +8 -0
  194. package/dist/graphql/resolvers.d.ts.map +1 -0
  195. package/dist/graphql/resolvers.js +93 -0
  196. package/dist/graphql/resolvers.js.map +1 -0
  197. package/dist/graphql/schema-builder.d.ts +3 -0
  198. package/dist/graphql/schema-builder.d.ts.map +1 -0
  199. package/dist/graphql/schema-builder.js +103 -0
  200. package/dist/graphql/schema-builder.js.map +1 -0
  201. package/dist/health/index.d.ts +27 -0
  202. package/dist/health/index.d.ts.map +1 -0
  203. package/dist/health/index.js +43 -0
  204. package/dist/health/index.js.map +1 -0
  205. package/dist/i18n/index.d.ts +22 -0
  206. package/dist/i18n/index.d.ts.map +1 -0
  207. package/dist/i18n/index.js +37 -0
  208. package/dist/i18n/index.js.map +1 -0
  209. package/dist/index.d.ts +73 -0
  210. package/dist/index.d.ts.map +1 -0
  211. package/dist/index.js +81 -0
  212. package/dist/index.js.map +1 -0
  213. package/dist/media/index.d.ts +3 -0
  214. package/dist/media/index.d.ts.map +1 -0
  215. package/dist/media/index.js +2 -0
  216. package/dist/media/index.js.map +1 -0
  217. package/dist/media/optimize.d.ts +40 -0
  218. package/dist/media/optimize.d.ts.map +1 -0
  219. package/dist/media/optimize.js +137 -0
  220. package/dist/media/optimize.js.map +1 -0
  221. package/dist/middleware.d.ts +7 -0
  222. package/dist/middleware.d.ts.map +1 -0
  223. package/dist/middleware.js +86 -0
  224. package/dist/middleware.js.map +1 -0
  225. package/dist/multisite/index.d.ts +20 -0
  226. package/dist/multisite/index.d.ts.map +1 -0
  227. package/dist/multisite/index.js +26 -0
  228. package/dist/multisite/index.js.map +1 -0
  229. package/dist/next/preview.d.ts +10 -0
  230. package/dist/next/preview.d.ts.map +1 -0
  231. package/dist/next/preview.js +17 -0
  232. package/dist/next/preview.js.map +1 -0
  233. package/dist/next.d.ts +9 -0
  234. package/dist/next.d.ts.map +1 -0
  235. package/dist/next.js +35 -0
  236. package/dist/next.js.map +1 -0
  237. package/dist/notifications/index.d.ts +20 -0
  238. package/dist/notifications/index.d.ts.map +1 -0
  239. package/dist/notifications/index.js +22 -0
  240. package/dist/notifications/index.js.map +1 -0
  241. package/dist/presence/index.d.ts +24 -0
  242. package/dist/presence/index.d.ts.map +1 -0
  243. package/dist/presence/index.js +99 -0
  244. package/dist/presence/index.js.map +1 -0
  245. package/dist/preview/index.d.ts +14 -0
  246. package/dist/preview/index.d.ts.map +1 -0
  247. package/dist/preview/index.js +45 -0
  248. package/dist/preview/index.js.map +1 -0
  249. package/dist/privacy/index.d.ts +33 -0
  250. package/dist/privacy/index.d.ts.map +1 -0
  251. package/dist/privacy/index.js +15 -0
  252. package/dist/privacy/index.js.map +1 -0
  253. package/dist/relationships/index.d.ts +13 -0
  254. package/dist/relationships/index.d.ts.map +1 -0
  255. package/dist/relationships/index.js +12 -0
  256. package/dist/relationships/index.js.map +1 -0
  257. package/dist/scheduling/index.d.ts +44 -0
  258. package/dist/scheduling/index.d.ts.map +1 -0
  259. package/dist/scheduling/index.js +119 -0
  260. package/dist/scheduling/index.js.map +1 -0
  261. package/dist/search/index.d.ts +25 -0
  262. package/dist/search/index.d.ts.map +1 -0
  263. package/dist/search/index.js +168 -0
  264. package/dist/search/index.js.map +1 -0
  265. package/dist/security/access.d.ts +26 -0
  266. package/dist/security/access.d.ts.map +1 -0
  267. package/dist/security/access.js +92 -0
  268. package/dist/security/access.js.map +1 -0
  269. package/dist/security/anomaly-detection.d.ts +17 -0
  270. package/dist/security/anomaly-detection.d.ts.map +1 -0
  271. package/dist/security/anomaly-detection.js +17 -0
  272. package/dist/security/anomaly-detection.js.map +1 -0
  273. package/dist/security/api-key-enhanced.d.ts +25 -0
  274. package/dist/security/api-key-enhanced.d.ts.map +1 -0
  275. package/dist/security/api-key-enhanced.js +25 -0
  276. package/dist/security/api-key-enhanced.js.map +1 -0
  277. package/dist/security/audit.d.ts +39 -0
  278. package/dist/security/audit.d.ts.map +1 -0
  279. package/dist/security/audit.js +40 -0
  280. package/dist/security/audit.js.map +1 -0
  281. package/dist/security/breach-check.d.ts +3 -0
  282. package/dist/security/breach-check.d.ts.map +1 -0
  283. package/dist/security/breach-check.js +27 -0
  284. package/dist/security/breach-check.js.map +1 -0
  285. package/dist/security/cors.d.ts +11 -0
  286. package/dist/security/cors.d.ts.map +1 -0
  287. package/dist/security/cors.js +33 -0
  288. package/dist/security/cors.js.map +1 -0
  289. package/dist/security/csp-nonces.d.ts +5 -0
  290. package/dist/security/csp-nonces.d.ts.map +1 -0
  291. package/dist/security/csp-nonces.js +24 -0
  292. package/dist/security/csp-nonces.js.map +1 -0
  293. package/dist/security/csrf.d.ts +5 -0
  294. package/dist/security/csrf.d.ts.map +1 -0
  295. package/dist/security/csrf.js +20 -0
  296. package/dist/security/csrf.js.map +1 -0
  297. package/dist/security/encrypted-fields.d.ts +5 -0
  298. package/dist/security/encrypted-fields.d.ts.map +1 -0
  299. package/dist/security/encrypted-fields.js +40 -0
  300. package/dist/security/encrypted-fields.js.map +1 -0
  301. package/dist/security/headers.d.ts +11 -0
  302. package/dist/security/headers.d.ts.map +1 -0
  303. package/dist/security/headers.js +32 -0
  304. package/dist/security/headers.js.map +1 -0
  305. package/dist/security/index.d.ts +31 -0
  306. package/dist/security/index.d.ts.map +1 -0
  307. package/dist/security/index.js +20 -0
  308. package/dist/security/index.js.map +1 -0
  309. package/dist/security/ip-allowlist.d.ts +3 -0
  310. package/dist/security/ip-allowlist.d.ts.map +1 -0
  311. package/dist/security/ip-allowlist.js +35 -0
  312. package/dist/security/ip-allowlist.js.map +1 -0
  313. package/dist/security/middleware.d.ts +20 -0
  314. package/dist/security/middleware.d.ts.map +1 -0
  315. package/dist/security/middleware.js +45 -0
  316. package/dist/security/middleware.js.map +1 -0
  317. package/dist/security/rate-limit.d.ts +24 -0
  318. package/dist/security/rate-limit.d.ts.map +1 -0
  319. package/dist/security/rate-limit.js +84 -0
  320. package/dist/security/rate-limit.js.map +1 -0
  321. package/dist/security/reauth.d.ts +15 -0
  322. package/dist/security/reauth.d.ts.map +1 -0
  323. package/dist/security/reauth.js +38 -0
  324. package/dist/security/reauth.js.map +1 -0
  325. package/dist/security/sanitize.d.ts +13 -0
  326. package/dist/security/sanitize.d.ts.map +1 -0
  327. package/dist/security/sanitize.js +34 -0
  328. package/dist/security/sanitize.js.map +1 -0
  329. package/dist/security/security-txt.d.ts +12 -0
  330. package/dist/security/security-txt.d.ts.map +1 -0
  331. package/dist/security/security-txt.js +19 -0
  332. package/dist/security/security-txt.js.map +1 -0
  333. package/dist/security/session-limits.d.ts +17 -0
  334. package/dist/security/session-limits.d.ts.map +1 -0
  335. package/dist/security/session-limits.js +14 -0
  336. package/dist/security/session-limits.js.map +1 -0
  337. package/dist/security/upload.d.ts +13 -0
  338. package/dist/security/upload.d.ts.map +1 -0
  339. package/dist/security/upload.js +34 -0
  340. package/dist/security/upload.js.map +1 -0
  341. package/dist/security/webhook.d.ts +12 -0
  342. package/dist/security/webhook.d.ts.map +1 -0
  343. package/dist/security/webhook.js +38 -0
  344. package/dist/security/webhook.js.map +1 -0
  345. package/dist/seo/analysis.d.ts +66 -0
  346. package/dist/seo/analysis.d.ts.map +1 -0
  347. package/dist/seo/analysis.js +594 -0
  348. package/dist/seo/analysis.js.map +1 -0
  349. package/dist/seo/index.d.ts +9 -0
  350. package/dist/seo/index.d.ts.map +1 -0
  351. package/dist/seo/index.js +5 -0
  352. package/dist/seo/index.js.map +1 -0
  353. package/dist/seo/llms-txt.d.ts +16 -0
  354. package/dist/seo/llms-txt.d.ts.map +1 -0
  355. package/dist/seo/llms-txt.js +70 -0
  356. package/dist/seo/llms-txt.js.map +1 -0
  357. package/dist/seo/meta-tags.d.ts +33 -0
  358. package/dist/seo/meta-tags.d.ts.map +1 -0
  359. package/dist/seo/meta-tags.js +159 -0
  360. package/dist/seo/meta-tags.js.map +1 -0
  361. package/dist/seo/title-templates.d.ts +17 -0
  362. package/dist/seo/title-templates.d.ts.map +1 -0
  363. package/dist/seo/title-templates.js +28 -0
  364. package/dist/seo/title-templates.js.map +1 -0
  365. package/dist/setup/index.d.ts +38 -0
  366. package/dist/setup/index.d.ts.map +1 -0
  367. package/dist/setup/index.js +77 -0
  368. package/dist/setup/index.js.map +1 -0
  369. package/dist/storage/index.d.ts +11 -0
  370. package/dist/storage/index.d.ts.map +1 -0
  371. package/dist/storage/index.js +11 -0
  372. package/dist/storage/index.js.map +1 -0
  373. package/dist/templates/index.d.ts +16 -0
  374. package/dist/templates/index.d.ts.map +1 -0
  375. package/dist/templates/index.js +23 -0
  376. package/dist/templates/index.js.map +1 -0
  377. package/dist/upgrade/changelog.d.ts +13 -0
  378. package/dist/upgrade/changelog.d.ts.map +1 -0
  379. package/dist/upgrade/changelog.js +54 -0
  380. package/dist/upgrade/changelog.js.map +1 -0
  381. package/dist/upgrade/index.d.ts +7 -0
  382. package/dist/upgrade/index.d.ts.map +1 -0
  383. package/dist/upgrade/index.js +4 -0
  384. package/dist/upgrade/index.js.map +1 -0
  385. package/dist/upgrade/upgrade-pr.d.ts +16 -0
  386. package/dist/upgrade/upgrade-pr.d.ts.map +1 -0
  387. package/dist/upgrade/upgrade-pr.js +38 -0
  388. package/dist/upgrade/upgrade-pr.js.map +1 -0
  389. package/dist/upgrade/version-check.d.ts +17 -0
  390. package/dist/upgrade/version-check.d.ts.map +1 -0
  391. package/dist/upgrade/version-check.js +30 -0
  392. package/dist/upgrade/version-check.js.map +1 -0
  393. package/dist/webhooks/index.d.ts +46 -0
  394. package/dist/webhooks/index.d.ts.map +1 -0
  395. package/dist/webhooks/index.js +245 -0
  396. package/dist/webhooks/index.js.map +1 -0
  397. package/dist/workflow/index.d.ts +8 -0
  398. package/dist/workflow/index.d.ts.map +1 -0
  399. package/dist/workflow/index.js +56 -0
  400. package/dist/workflow/index.js.map +1 -0
  401. package/dist/workflows/index.d.ts +30 -0
  402. package/dist/workflows/index.d.ts.map +1 -0
  403. package/dist/workflows/index.js +14 -0
  404. package/dist/workflows/index.js.map +1 -0
  405. package/generated/browser.ts +109 -0
  406. package/generated/client.ts +133 -0
  407. package/generated/commonInputTypes.ts +709 -0
  408. package/generated/enums.ts +125 -0
  409. package/generated/internal/class.ts +376 -0
  410. package/generated/internal/prismaNamespace.ts +2617 -0
  411. package/generated/internal/prismaNamespaceBrowser.ts +611 -0
  412. package/generated/models/ApiKey.ts +1550 -0
  413. package/generated/models/AuditLog.ts +1206 -0
  414. package/generated/models/BackupRecord.ts +1250 -0
  415. package/generated/models/ContentLock.ts +1472 -0
  416. package/generated/models/ContentTemplate.ts +1416 -0
  417. package/generated/models/Document.ts +3005 -0
  418. package/generated/models/Folder.ts +1904 -0
  419. package/generated/models/FormSubmission.ts +1200 -0
  420. package/generated/models/InAppNotification.ts +1457 -0
  421. package/generated/models/Media.ts +2340 -0
  422. package/generated/models/MediaUsage.ts +1472 -0
  423. package/generated/models/OAuthAccount.ts +1463 -0
  424. package/generated/models/Redirect.ts +1284 -0
  425. package/generated/models/Session.ts +1492 -0
  426. package/generated/models/Site.ts +1206 -0
  427. package/generated/models/User.ts +3513 -0
  428. package/generated/models/Version.ts +1511 -0
  429. package/generated/models/WorkflowState.ts +1514 -0
  430. package/generated/models.ts +29 -0
  431. package/package.json +83 -0
@@ -0,0 +1,84 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { processScheduledPublish, processScheduledUnpublish, getScheduleCalendar, } from '../../scheduling/index';
3
+ function createMockDB(docs = []) {
4
+ return {
5
+ document: {
6
+ findMany: vi.fn(async () => docs),
7
+ update: vi.fn(async ({ where, data }) => {
8
+ const doc = docs.find((d) => d.id === where.id);
9
+ if (doc)
10
+ Object.assign(doc, data);
11
+ return doc;
12
+ }),
13
+ },
14
+ };
15
+ }
16
+ describe('processScheduledPublish', () => {
17
+ it('publishes documents with scheduledAt in the past', async () => {
18
+ const docs = [
19
+ { id: 'doc-1', status: 'SCHEDULED', scheduledAt: new Date(Date.now() - 10000) },
20
+ { id: 'doc-2', status: 'SCHEDULED', scheduledAt: new Date(Date.now() - 5000) },
21
+ ];
22
+ const db = createMockDB(docs);
23
+ const result = await processScheduledPublish(db);
24
+ expect(result.published).toBe(2);
25
+ expect(result.errors).toHaveLength(0);
26
+ expect(db.document.update).toHaveBeenCalledTimes(2);
27
+ });
28
+ it('returns empty when no documents are due', async () => {
29
+ const db = createMockDB([]);
30
+ const result = await processScheduledPublish(db);
31
+ expect(result.published).toBe(0);
32
+ expect(result.errors).toHaveLength(0);
33
+ });
34
+ it('captures errors for individual documents', async () => {
35
+ const docs = [{ id: 'doc-1', status: 'SCHEDULED', scheduledAt: new Date(Date.now() - 10000) }];
36
+ const db = createMockDB(docs);
37
+ db.document.update.mockRejectedValueOnce(new Error('DB error'));
38
+ const result = await processScheduledPublish(db);
39
+ expect(result.published).toBe(0);
40
+ expect(result.errors).toHaveLength(1);
41
+ expect(result.errors[0].documentId).toBe('doc-1');
42
+ });
43
+ });
44
+ describe('processScheduledUnpublish', () => {
45
+ it('unpublishes documents with scheduledUnpublishAt in the past', async () => {
46
+ const docs = [
47
+ { id: 'doc-1', status: 'PUBLISHED', scheduledUnpublishAt: new Date(Date.now() - 10000) },
48
+ ];
49
+ const db = createMockDB(docs);
50
+ const result = await processScheduledUnpublish(db);
51
+ expect(result.unpublished).toBe(1);
52
+ expect(result.errors).toHaveLength(0);
53
+ });
54
+ });
55
+ describe('getScheduleCalendar', () => {
56
+ it('returns entries for scheduled publish and unpublish', async () => {
57
+ const now = new Date();
58
+ const future = new Date(Date.now() + 86_400_000);
59
+ const docs = [
60
+ { id: 'doc-1', collection: 'pages', title: 'Page 1', scheduledAt: future, scheduledUnpublishAt: null },
61
+ { id: 'doc-2', collection: 'posts', title: 'Post 1', scheduledAt: null, scheduledUnpublishAt: future },
62
+ ];
63
+ const db = createMockDB(docs);
64
+ const from = new Date(Date.now() - 86_400_000);
65
+ const to = new Date(Date.now() + 86_400_000 * 2);
66
+ const entries = await getScheduleCalendar(from, to, db);
67
+ expect(entries).toHaveLength(2);
68
+ expect(entries[0].action).toBe('publish');
69
+ expect(entries[1].action).toBe('unpublish');
70
+ });
71
+ it('returns sorted entries', async () => {
72
+ const earlier = new Date(Date.now() + 10_000);
73
+ const later = new Date(Date.now() + 86_400_000);
74
+ const docs = [
75
+ { id: 'doc-1', collection: 'pages', title: 'Later', scheduledAt: later, scheduledUnpublishAt: null },
76
+ { id: 'doc-2', collection: 'pages', title: 'Earlier', scheduledAt: earlier, scheduledUnpublishAt: null },
77
+ ];
78
+ const db = createMockDB(docs);
79
+ const entries = await getScheduleCalendar(new Date(), new Date(Date.now() + 86_400_000 * 2), db);
80
+ expect(entries[0].title).toBe('Earlier');
81
+ expect(entries[1].title).toBe('Later');
82
+ });
83
+ });
84
+ //# sourceMappingURL=scheduling.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduling.test.js","sourceRoot":"","sources":["../../../src/__tests__/scheduling/scheduling.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=access.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/security/access.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,181 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { checkAccess, getPermissionsForRole, filterFieldsByRole, applyFieldAccess } from '../../security/access';
3
+ describe('checkAccess', () => {
4
+ it('ADMIN can access everything', () => {
5
+ expect(checkAccess('ADMIN', 'ADMIN')).toBe(true);
6
+ expect(checkAccess('ADMIN', 'EDITOR')).toBe(true);
7
+ expect(checkAccess('ADMIN', 'AUTHOR')).toBe(true);
8
+ expect(checkAccess('ADMIN', 'CLIENT')).toBe(true);
9
+ });
10
+ it('EDITOR can access AUTHOR level', () => {
11
+ expect(checkAccess('EDITOR', 'AUTHOR')).toBe(true);
12
+ expect(checkAccess('EDITOR', 'CLIENT')).toBe(true);
13
+ expect(checkAccess('EDITOR', 'EDITOR')).toBe(true);
14
+ });
15
+ it('EDITOR cannot access ADMIN level', () => {
16
+ expect(checkAccess('EDITOR', 'ADMIN')).toBe(false);
17
+ });
18
+ it('AUTHOR cannot access EDITOR level', () => {
19
+ expect(checkAccess('AUTHOR', 'EDITOR')).toBe(false);
20
+ expect(checkAccess('AUTHOR', 'ADMIN')).toBe(false);
21
+ });
22
+ it('AUTHOR can access AUTHOR and CLIENT levels', () => {
23
+ expect(checkAccess('AUTHOR', 'AUTHOR')).toBe(true);
24
+ expect(checkAccess('AUTHOR', 'CLIENT')).toBe(true);
25
+ });
26
+ it('CLIENT cannot access AUTHOR level', () => {
27
+ expect(checkAccess('CLIENT', 'AUTHOR')).toBe(false);
28
+ expect(checkAccess('CLIENT', 'EDITOR')).toBe(false);
29
+ expect(checkAccess('CLIENT', 'ADMIN')).toBe(false);
30
+ });
31
+ it('CLIENT can access CLIENT level', () => {
32
+ expect(checkAccess('CLIENT', 'CLIENT')).toBe(true);
33
+ });
34
+ });
35
+ describe('getPermissionsForRole', () => {
36
+ it('ADMIN gets delete permission', () => {
37
+ const perms = getPermissionsForRole('ADMIN');
38
+ const actions = perms.map((p) => p.action);
39
+ expect(actions).toContain('delete');
40
+ expect(actions).toContain('create');
41
+ expect(actions).toContain('read');
42
+ expect(actions).toContain('update');
43
+ expect(actions).toContain('publish');
44
+ });
45
+ it('EDITOR gets publish but not delete', () => {
46
+ const perms = getPermissionsForRole('EDITOR');
47
+ const actions = perms.map((p) => p.action);
48
+ expect(actions).toContain('publish');
49
+ expect(actions).toContain('read');
50
+ expect(actions).toContain('create');
51
+ expect(actions).not.toContain('delete');
52
+ });
53
+ it('AUTHOR gets create but not delete', () => {
54
+ const perms = getPermissionsForRole('AUTHOR');
55
+ const actions = perms.map((p) => p.action);
56
+ expect(actions).toContain('read');
57
+ expect(actions).toContain('create');
58
+ expect(actions).not.toContain('delete');
59
+ expect(actions).not.toContain('publish');
60
+ });
61
+ it('CLIENT only gets read permission', () => {
62
+ const perms = getPermissionsForRole('CLIENT');
63
+ const actions = perms.map((p) => p.action);
64
+ expect(actions).toEqual(['read']);
65
+ });
66
+ it('AUTHOR has "update own" but not "update *"', () => {
67
+ const perms = getPermissionsForRole('AUTHOR');
68
+ const updatePerms = perms.filter((p) => p.action === 'update');
69
+ expect(updatePerms).toHaveLength(1);
70
+ expect(updatePerms[0].resource).toBe('own');
71
+ });
72
+ it('EDITOR has "update *" (all resources)', () => {
73
+ const perms = getPermissionsForRole('EDITOR');
74
+ const updatePerms = perms.filter((p) => p.action === 'update');
75
+ const resources = updatePerms.map((p) => p.resource);
76
+ expect(resources).toContain('*');
77
+ });
78
+ });
79
+ describe('filterFieldsByRole', () => {
80
+ const adminUser = { id: 'admin-1', role: 'ADMIN' };
81
+ const clientUser = { id: 'client-1', role: 'CLIENT' };
82
+ it('returns all fields when no access control is defined', async () => {
83
+ const fields = {
84
+ title: { type: 'text', label: 'Title', required: true },
85
+ body: { type: 'richText', label: 'Body' },
86
+ };
87
+ const filtered = await filterFieldsByRole(fields, clientUser);
88
+ expect(Object.keys(filtered)).toEqual(['title', 'body']);
89
+ });
90
+ it('returns a shallow copy, not the same reference', async () => {
91
+ const fields = {
92
+ name: { type: 'text', label: 'Name' },
93
+ };
94
+ const filtered = await filterFieldsByRole(fields, adminUser);
95
+ expect(filtered).not.toBe(fields);
96
+ expect(filtered).toEqual(fields);
97
+ });
98
+ it('filters out fields the user cannot read', async () => {
99
+ const fields = {
100
+ title: { type: 'text', label: 'Title' },
101
+ secret: {
102
+ type: 'text',
103
+ label: 'Secret',
104
+ access: {
105
+ read: async ({ user }) => user?.role === 'ADMIN',
106
+ },
107
+ },
108
+ };
109
+ const clientFiltered = await filterFieldsByRole(fields, clientUser);
110
+ expect(Object.keys(clientFiltered)).toEqual(['title']);
111
+ const adminFiltered = await filterFieldsByRole(fields, adminUser);
112
+ expect(Object.keys(adminFiltered)).toEqual(['title', 'secret']);
113
+ });
114
+ });
115
+ describe('applyFieldAccess', () => {
116
+ const adminUser = { id: 'admin-1', role: 'ADMIN' };
117
+ const clientUser = { id: 'client-1', role: 'CLIENT' };
118
+ it('read mode: strips fields the user cannot read', async () => {
119
+ const fields = {
120
+ title: { type: 'text', label: 'Title' },
121
+ internal: {
122
+ type: 'text',
123
+ label: 'Internal',
124
+ access: {
125
+ read: async ({ user }) => user?.role === 'ADMIN',
126
+ },
127
+ },
128
+ };
129
+ const data = { title: 'Hello', internal: 'secret-value', extra: 'kept' };
130
+ const clientResult = await applyFieldAccess('read', fields, data, clientUser);
131
+ expect(clientResult).toEqual({ title: 'Hello', extra: 'kept' });
132
+ const adminResult = await applyFieldAccess('read', fields, data, adminUser);
133
+ expect(adminResult).toEqual({ title: 'Hello', internal: 'secret-value', extra: 'kept' });
134
+ });
135
+ it('write mode: strips fields the user cannot update', async () => {
136
+ const fields = {
137
+ title: { type: 'text', label: 'Title' },
138
+ locked: {
139
+ type: 'text',
140
+ label: 'Locked',
141
+ access: {
142
+ update: async ({ user }) => user?.role === 'ADMIN',
143
+ },
144
+ },
145
+ };
146
+ const data = { title: 'New Title', locked: 'overwrite-attempt' };
147
+ const clientResult = await applyFieldAccess('write', fields, data, clientUser);
148
+ expect(clientResult).toEqual({ title: 'New Title' });
149
+ const adminResult = await applyFieldAccess('write', fields, data, adminUser);
150
+ expect(adminResult).toEqual({ title: 'New Title', locked: 'overwrite-attempt' });
151
+ });
152
+ it('passes through unknown keys on read', async () => {
153
+ const fields = {
154
+ title: { type: 'text', label: 'Title' },
155
+ };
156
+ const data = { title: 'Hello', unknownField: 'value' };
157
+ const result = await applyFieldAccess('read', fields, data, clientUser);
158
+ expect(result).toEqual({ title: 'Hello', unknownField: 'value' });
159
+ });
160
+ it('strips unknown keys on write (mass assignment prevention)', async () => {
161
+ const fields = {
162
+ title: { type: 'text', label: 'Title' },
163
+ };
164
+ const data = { title: 'Hello', isAdmin: true, role: 'ADMIN' };
165
+ const result = await applyFieldAccess('write', fields, data, clientUser);
166
+ expect(result).toEqual({ title: 'Hello' });
167
+ expect(result).not.toHaveProperty('isAdmin');
168
+ expect(result).not.toHaveProperty('role');
169
+ });
170
+ it('allows system keys on write', async () => {
171
+ const fields = {
172
+ body: { type: 'richText', label: 'Body' },
173
+ };
174
+ const data = { body: '<p>Hi</p>', title: 'My Page', slug: 'my-page', status: 'PUBLISHED' };
175
+ const result = await applyFieldAccess('write', fields, data, clientUser);
176
+ expect(result).toHaveProperty('title');
177
+ expect(result).toHaveProperty('slug');
178
+ expect(result).toHaveProperty('status');
179
+ });
180
+ });
181
+ //# sourceMappingURL=access.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access.test.js","sourceRoot":"","sources":["../../../src/__tests__/security/access.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=csrf.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csrf.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/security/csrf.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,40 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { generateToken, validateToken } from '../../security/csrf.js';
3
+ describe('generateToken', () => {
4
+ it('returns a 64-char hex string', async () => {
5
+ const token = await generateToken();
6
+ expect(token).toHaveLength(64);
7
+ expect(token).toMatch(/^[0-9a-f]{64}$/);
8
+ });
9
+ it('generates unique tokens on each call', async () => {
10
+ const token1 = await generateToken();
11
+ const token2 = await generateToken();
12
+ expect(token1).not.toBe(token2);
13
+ });
14
+ });
15
+ describe('validateToken', () => {
16
+ it('returns true for matching tokens', async () => {
17
+ const token = await generateToken();
18
+ expect(validateToken(token, token)).toBe(true);
19
+ });
20
+ it('returns true for identical manually-constructed tokens', () => {
21
+ const token = 'a'.repeat(64);
22
+ expect(validateToken(token, token)).toBe(true);
23
+ });
24
+ it('returns false for different tokens of the same length', async () => {
25
+ const token1 = await generateToken();
26
+ const token2 = await generateToken();
27
+ expect(validateToken(token1, token2)).toBe(false);
28
+ });
29
+ it('returns false for tokens of different lengths', () => {
30
+ const short = 'abcdef';
31
+ const long = 'abcdefabcdef';
32
+ expect(validateToken(short, long)).toBe(false);
33
+ });
34
+ it('returns false when one token is empty', async () => {
35
+ const token = await generateToken();
36
+ expect(validateToken(token, '')).toBe(false);
37
+ expect(validateToken('', token)).toBe(false);
38
+ });
39
+ });
40
+ //# sourceMappingURL=csrf.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"csrf.test.js","sourceRoot":"","sources":["../../../src/__tests__/security/csrf.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEtE,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5C,MAAM,KAAK,GAAG,MAAM,aAAa,EAAE,CAAC;QACpC,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QAC/B,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,MAAM,GAAG,MAAM,aAAa,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,aAAa,EAAE,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAChD,MAAM,KAAK,GAAG,MAAM,aAAa,EAAE,CAAC;QACpC,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC7B,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,MAAM,GAAG,MAAM,aAAa,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,aAAa,EAAE,CAAC;QACrC,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,KAAK,GAAG,QAAQ,CAAC;QACvB,MAAM,IAAI,GAAG,cAAc,CAAC;QAC5B,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,KAAK,GAAG,MAAM,aAAa,EAAE,CAAC;QACpC,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7C,MAAM,CAAC,aAAa,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=rate-limit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/security/rate-limit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,62 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { createRateLimiter } from '../../security/rate-limit.js';
3
+ describe('createRateLimiter', () => {
4
+ beforeEach(() => {
5
+ vi.useFakeTimers();
6
+ });
7
+ afterEach(() => {
8
+ vi.useRealTimers();
9
+ });
10
+ it('allows requests under the limit', async () => {
11
+ const limiter = createRateLimiter({ windowMs: 60_000, maxRequests: 5 });
12
+ const r1 = await limiter.check('ip:127.0.0.1');
13
+ expect(r1.allowed).toBe(true);
14
+ expect(r1.remaining).toBe(4);
15
+ const r2 = await limiter.check('ip:127.0.0.1');
16
+ expect(r2.allowed).toBe(true);
17
+ expect(r2.remaining).toBe(3);
18
+ });
19
+ it('blocks requests over the limit', async () => {
20
+ const limiter = createRateLimiter({ windowMs: 60_000, maxRequests: 3 });
21
+ await limiter.check('ip:test');
22
+ await limiter.check('ip:test');
23
+ await limiter.check('ip:test');
24
+ const blocked = await limiter.check('ip:test');
25
+ expect(blocked.allowed).toBe(false);
26
+ expect(blocked.remaining).toBe(0);
27
+ expect(blocked.retryAfter).toBeDefined();
28
+ expect(blocked.retryAfter).toBeGreaterThan(0);
29
+ });
30
+ it('resets after window expires', async () => {
31
+ const limiter = createRateLimiter({ windowMs: 10_000, maxRequests: 2 });
32
+ await limiter.check('ip:expire');
33
+ await limiter.check('ip:expire');
34
+ const blocked = await limiter.check('ip:expire');
35
+ expect(blocked.allowed).toBe(false);
36
+ vi.advanceTimersByTime(11_000);
37
+ const afterReset = await limiter.check('ip:expire');
38
+ expect(afterReset.allowed).toBe(true);
39
+ expect(afterReset.remaining).toBe(1);
40
+ });
41
+ it('reset() clears the counter', async () => {
42
+ const limiter = createRateLimiter({ windowMs: 60_000, maxRequests: 2 });
43
+ await limiter.check('ip:reset');
44
+ await limiter.check('ip:reset');
45
+ const blocked = await limiter.check('ip:reset');
46
+ expect(blocked.allowed).toBe(false);
47
+ await limiter.reset('ip:reset');
48
+ const afterReset = await limiter.check('ip:reset');
49
+ expect(afterReset.allowed).toBe(true);
50
+ expect(afterReset.remaining).toBe(1);
51
+ });
52
+ it('tracks different keys independently', async () => {
53
+ const limiter = createRateLimiter({ windowMs: 60_000, maxRequests: 1 });
54
+ const r1 = await limiter.check('key-a');
55
+ expect(r1.allowed).toBe(true);
56
+ const r2 = await limiter.check('key-b');
57
+ expect(r2.allowed).toBe(true);
58
+ const r3 = await limiter.check('key-a');
59
+ expect(r3.allowed).toBe(false);
60
+ });
61
+ });
62
+ //# sourceMappingURL=rate-limit.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.test.js","sourceRoot":"","sources":["../../../src/__tests__/security/rate-limit.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=reauth.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reauth.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/security/reauth.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,30 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { requiresReauth, DEFAULT_REAUTH_CONFIG } from '../../security/reauth';
3
+ describe('requiresReauth', () => {
4
+ it('returns false for actions not in the required list', () => {
5
+ const result = requiresReauth({ lastAuthAt: new Date(0), action: 'view_dashboard' }, DEFAULT_REAUTH_CONFIG);
6
+ expect(result).toBe(false);
7
+ });
8
+ it('returns false when recently authenticated', () => {
9
+ const result = requiresReauth({ lastAuthAt: new Date(), action: 'delete_user' }, DEFAULT_REAUTH_CONFIG);
10
+ expect(result).toBe(false);
11
+ });
12
+ it('returns true when authentication is stale', () => {
13
+ const staleDate = new Date(Date.now() - 600_000);
14
+ const result = requiresReauth({ lastAuthAt: staleDate, action: 'delete_user' }, DEFAULT_REAUTH_CONFIG);
15
+ expect(result).toBe(true);
16
+ });
17
+ it('returns true for change_settings when stale', () => {
18
+ const staleDate = new Date(Date.now() - 600_000);
19
+ const result = requiresReauth({ lastAuthAt: staleDate, action: 'change_settings' }, DEFAULT_REAUTH_CONFIG);
20
+ expect(result).toBe(true);
21
+ });
22
+ it('respects custom maxAgeSeconds', () => {
23
+ const config = { maxAgeSeconds: 10, requiredForActions: ['test_action'] };
24
+ const recentEnough = new Date(Date.now() - 5_000);
25
+ expect(requiresReauth({ lastAuthAt: recentEnough, action: 'test_action' }, config)).toBe(false);
26
+ const tooOld = new Date(Date.now() - 15_000);
27
+ expect(requiresReauth({ lastAuthAt: tooOld, action: 'test_action' }, config)).toBe(true);
28
+ });
29
+ });
30
+ //# sourceMappingURL=reauth.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reauth.test.js","sourceRoot":"","sources":["../../../src/__tests__/security/reauth.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9E,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;IAC9B,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,MAAM,GAAG,cAAc,CAC3B,EAAE,UAAU,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,gBAAgB,EAAE,EACrD,qBAAqB,CACtB,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,MAAM,GAAG,cAAc,CAC3B,EAAE,UAAU,EAAE,IAAI,IAAI,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,EACjD,qBAAqB,CACtB,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,cAAc,CAC3B,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,EAChD,qBAAqB,CACtB,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,cAAc,CAC3B,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,iBAAiB,EAAE,EACpD,qBAAqB,CACtB,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,MAAM,GAAG,EAAE,aAAa,EAAE,EAAE,EAAE,kBAAkB,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC;QAC1E,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,CAAC;QAClD,MAAM,CAAC,cAAc,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAEhG,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,CAAC;QAC7C,MAAM,CAAC,cAAc,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3F,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sanitize.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/security/sanitize.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,75 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { sanitizeHtml, stripHtml } from '../../security/sanitize';
3
+ describe('sanitizeHtml', () => {
4
+ it('strips script tags', () => {
5
+ const input = '<p>Hello</p><script>alert("xss")</script>';
6
+ const result = sanitizeHtml(input);
7
+ expect(result).not.toContain('<script');
8
+ expect(result).toContain('<p>Hello</p>');
9
+ });
10
+ it('strips onerror attributes', () => {
11
+ const input = '<img src="x" onerror="alert(1)" alt="test" />';
12
+ const result = sanitizeHtml(input);
13
+ expect(result).not.toContain('onerror');
14
+ expect(result).toContain('alt="test"');
15
+ });
16
+ it('strips javascript: URLs from hrefs', () => {
17
+ const input = '<a href="javascript:alert(1)">click</a>';
18
+ const result = sanitizeHtml(input);
19
+ expect(result).not.toContain('javascript:');
20
+ });
21
+ it('preserves safe HTML', () => {
22
+ const input = '<h1>Title</h1><p>Text with <strong>bold</strong> and <a href="https://example.com">link</a></p>';
23
+ const result = sanitizeHtml(input);
24
+ expect(result).toContain('<h1>');
25
+ expect(result).toContain('<strong>bold</strong>');
26
+ expect(result).toContain('href="https://example.com"');
27
+ });
28
+ it('preserves image tags with allowed attributes', () => {
29
+ const input = '<img src="https://example.com/img.jpg" alt="photo" width="100" />';
30
+ const result = sanitizeHtml(input);
31
+ expect(result).toContain('src="https://example.com/img.jpg"');
32
+ expect(result).toContain('alt="photo"');
33
+ });
34
+ it('preserves tables', () => {
35
+ const input = '<table><thead><tr><th>Header</th></tr></thead><tbody><tr><td>Cell</td></tr></tbody></table>';
36
+ const result = sanitizeHtml(input);
37
+ expect(result).toContain('<table>');
38
+ expect(result).toContain('<th>Header</th>');
39
+ expect(result).toContain('<td>Cell</td>');
40
+ });
41
+ it('strips everything with stripAll option', () => {
42
+ const input = '<p>Hello <strong>world</strong></p>';
43
+ const result = sanitizeHtml(input, { stripAll: true });
44
+ expect(result).toBe('Hello world');
45
+ });
46
+ it('strips style tags', () => {
47
+ const input = '<style>body{display:none}</style><p>visible</p>';
48
+ const result = sanitizeHtml(input);
49
+ expect(result).not.toContain('<style');
50
+ expect(result).toContain('<p>visible</p>');
51
+ });
52
+ it('strips iframe tags', () => {
53
+ const input = '<iframe src="https://evil.com"></iframe><p>safe</p>';
54
+ const result = sanitizeHtml(input);
55
+ expect(result).not.toContain('<iframe');
56
+ expect(result).toContain('<p>safe</p>');
57
+ });
58
+ });
59
+ describe('stripHtml', () => {
60
+ it('returns plain text from HTML', () => {
61
+ const input = '<p>Hello <strong>world</strong></p>';
62
+ expect(stripHtml(input)).toBe('Hello world');
63
+ });
64
+ it('handles empty string', () => {
65
+ expect(stripHtml('')).toBe('');
66
+ });
67
+ it('strips nested tags', () => {
68
+ const input = '<div><ul><li>Item 1</li><li>Item 2</li></ul></div>';
69
+ const result = stripHtml(input);
70
+ expect(result).toContain('Item 1');
71
+ expect(result).toContain('Item 2');
72
+ expect(result).not.toContain('<');
73
+ });
74
+ });
75
+ //# sourceMappingURL=sanitize.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.test.js","sourceRoot":"","sources":["../../../src/__tests__/security/sanitize.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=webhooks.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhooks.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/webhooks/webhooks.test.ts"],"names":[],"mappings":""}