@htmless/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 (435) hide show
  1. package/dist/ai/content-operations.d.ts +26 -0
  2. package/dist/ai/content-operations.d.ts.map +1 -0
  3. package/dist/ai/content-operations.js +75 -0
  4. package/dist/ai/content-operations.js.map +1 -0
  5. package/dist/ai/image-analyzer.d.ts +18 -0
  6. package/dist/ai/image-analyzer.d.ts.map +1 -0
  7. package/dist/ai/image-analyzer.js +457 -0
  8. package/dist/ai/image-analyzer.js.map +1 -0
  9. package/dist/ai/json-to-schema.d.ts +6 -0
  10. package/dist/ai/json-to-schema.d.ts.map +1 -0
  11. package/dist/ai/json-to-schema.js +155 -0
  12. package/dist/ai/json-to-schema.js.map +1 -0
  13. package/dist/ai/schema-generator.d.ts +34 -0
  14. package/dist/ai/schema-generator.d.ts.map +1 -0
  15. package/dist/ai/schema-generator.js +307 -0
  16. package/dist/ai/schema-generator.js.map +1 -0
  17. package/dist/api/cda/assets.d.ts +4 -0
  18. package/dist/api/cda/assets.d.ts.map +1 -0
  19. package/dist/api/cda/assets.js +82 -0
  20. package/dist/api/cda/assets.js.map +1 -0
  21. package/dist/api/cda/blocks.d.ts +4 -0
  22. package/dist/api/cda/blocks.d.ts.map +1 -0
  23. package/dist/api/cda/blocks.js +92 -0
  24. package/dist/api/cda/blocks.js.map +1 -0
  25. package/dist/api/cda/content.d.ts +4 -0
  26. package/dist/api/cda/content.d.ts.map +1 -0
  27. package/dist/api/cda/content.js +192 -0
  28. package/dist/api/cda/content.js.map +1 -0
  29. package/dist/api/cda/index.d.ts +4 -0
  30. package/dist/api/cda/index.d.ts.map +1 -0
  31. package/dist/api/cda/index.js +21 -0
  32. package/dist/api/cda/index.js.map +1 -0
  33. package/dist/api/cda/media.d.ts +4 -0
  34. package/dist/api/cda/media.d.ts.map +1 -0
  35. package/dist/api/cda/media.js +114 -0
  36. package/dist/api/cda/media.js.map +1 -0
  37. package/dist/api/cda/redirects.d.ts +4 -0
  38. package/dist/api/cda/redirects.d.ts.map +1 -0
  39. package/dist/api/cda/redirects.js +69 -0
  40. package/dist/api/cda/redirects.js.map +1 -0
  41. package/dist/api/cda/schemas.d.ts +4 -0
  42. package/dist/api/cda/schemas.d.ts.map +1 -0
  43. package/dist/api/cda/schemas.js +113 -0
  44. package/dist/api/cda/schemas.js.map +1 -0
  45. package/dist/api/cda/taxonomies.d.ts +4 -0
  46. package/dist/api/cda/taxonomies.d.ts.map +1 -0
  47. package/dist/api/cda/taxonomies.js +79 -0
  48. package/dist/api/cda/taxonomies.js.map +1 -0
  49. package/dist/api/cma/ai.d.ts +4 -0
  50. package/dist/api/cma/ai.d.ts.map +1 -0
  51. package/dist/api/cma/ai.js +458 -0
  52. package/dist/api/cma/ai.js.map +1 -0
  53. package/dist/api/cma/assets.d.ts +4 -0
  54. package/dist/api/cma/assets.d.ts.map +1 -0
  55. package/dist/api/cma/assets.js +166 -0
  56. package/dist/api/cma/assets.js.map +1 -0
  57. package/dist/api/cma/audit.d.ts +4 -0
  58. package/dist/api/cma/audit.d.ts.map +1 -0
  59. package/dist/api/cma/audit.js +74 -0
  60. package/dist/api/cma/audit.js.map +1 -0
  61. package/dist/api/cma/auth.d.ts +4 -0
  62. package/dist/api/cma/auth.d.ts.map +1 -0
  63. package/dist/api/cma/auth.js +123 -0
  64. package/dist/api/cma/auth.js.map +1 -0
  65. package/dist/api/cma/blocks.d.ts +4 -0
  66. package/dist/api/cma/blocks.d.ts.map +1 -0
  67. package/dist/api/cma/blocks.js +249 -0
  68. package/dist/api/cma/blocks.js.map +1 -0
  69. package/dist/api/cma/bulk.d.ts +4 -0
  70. package/dist/api/cma/bulk.d.ts.map +1 -0
  71. package/dist/api/cma/bulk.js +258 -0
  72. package/dist/api/cma/bulk.js.map +1 -0
  73. package/dist/api/cma/cache.d.ts +4 -0
  74. package/dist/api/cma/cache.d.ts.map +1 -0
  75. package/dist/api/cma/cache.js +99 -0
  76. package/dist/api/cma/cache.js.map +1 -0
  77. package/dist/api/cma/codegen.d.ts +4 -0
  78. package/dist/api/cma/codegen.d.ts.map +1 -0
  79. package/dist/api/cma/codegen.js +22 -0
  80. package/dist/api/cma/codegen.js.map +1 -0
  81. package/dist/api/cma/comments.d.ts +4 -0
  82. package/dist/api/cma/comments.d.ts.map +1 -0
  83. package/dist/api/cma/comments.js +164 -0
  84. package/dist/api/cma/comments.js.map +1 -0
  85. package/dist/api/cma/diff.d.ts +4 -0
  86. package/dist/api/cma/diff.d.ts.map +1 -0
  87. package/dist/api/cma/diff.js +88 -0
  88. package/dist/api/cma/diff.js.map +1 -0
  89. package/dist/api/cma/entries.d.ts +4 -0
  90. package/dist/api/cma/entries.d.ts.map +1 -0
  91. package/dist/api/cma/entries.js +736 -0
  92. package/dist/api/cma/entries.js.map +1 -0
  93. package/dist/api/cma/environments.d.ts +4 -0
  94. package/dist/api/cma/environments.d.ts.map +1 -0
  95. package/dist/api/cma/environments.js +160 -0
  96. package/dist/api/cma/environments.js.map +1 -0
  97. package/dist/api/cma/extensions.d.ts +4 -0
  98. package/dist/api/cma/extensions.d.ts.map +1 -0
  99. package/dist/api/cma/extensions.js +82 -0
  100. package/dist/api/cma/extensions.js.map +1 -0
  101. package/dist/api/cma/importexport.d.ts +4 -0
  102. package/dist/api/cma/importexport.d.ts.map +1 -0
  103. package/dist/api/cma/importexport.js +496 -0
  104. package/dist/api/cma/importexport.js.map +1 -0
  105. package/dist/api/cma/index.d.ts +4 -0
  106. package/dist/api/cma/index.d.ts.map +1 -0
  107. package/dist/api/cma/index.js +69 -0
  108. package/dist/api/cma/index.js.map +1 -0
  109. package/dist/api/cma/live.d.ts +4 -0
  110. package/dist/api/cma/live.d.ts.map +1 -0
  111. package/dist/api/cma/live.js +64 -0
  112. package/dist/api/cma/live.js.map +1 -0
  113. package/dist/api/cma/locales.d.ts +4 -0
  114. package/dist/api/cma/locales.d.ts.map +1 -0
  115. package/dist/api/cma/locales.js +117 -0
  116. package/dist/api/cma/locales.js.map +1 -0
  117. package/dist/api/cma/marketplace.d.ts +4 -0
  118. package/dist/api/cma/marketplace.d.ts.map +1 -0
  119. package/dist/api/cma/marketplace.js +550 -0
  120. package/dist/api/cma/marketplace.js.map +1 -0
  121. package/dist/api/cma/redirects.d.ts +4 -0
  122. package/dist/api/cma/redirects.d.ts.map +1 -0
  123. package/dist/api/cma/redirects.js +120 -0
  124. package/dist/api/cma/redirects.js.map +1 -0
  125. package/dist/api/cma/relationships.d.ts +4 -0
  126. package/dist/api/cma/relationships.d.ts.map +1 -0
  127. package/dist/api/cma/relationships.js +47 -0
  128. package/dist/api/cma/relationships.js.map +1 -0
  129. package/dist/api/cma/schemas.d.ts +4 -0
  130. package/dist/api/cma/schemas.d.ts.map +1 -0
  131. package/dist/api/cma/schemas.js +248 -0
  132. package/dist/api/cma/schemas.js.map +1 -0
  133. package/dist/api/cma/search.d.ts +4 -0
  134. package/dist/api/cma/search.d.ts.map +1 -0
  135. package/dist/api/cma/search.js +149 -0
  136. package/dist/api/cma/search.js.map +1 -0
  137. package/dist/api/cma/spaces.d.ts +4 -0
  138. package/dist/api/cma/spaces.d.ts.map +1 -0
  139. package/dist/api/cma/spaces.js +119 -0
  140. package/dist/api/cma/spaces.js.map +1 -0
  141. package/dist/api/cma/taxonomies.d.ts +4 -0
  142. package/dist/api/cma/taxonomies.d.ts.map +1 -0
  143. package/dist/api/cma/taxonomies.js +296 -0
  144. package/dist/api/cma/taxonomies.js.map +1 -0
  145. package/dist/api/cma/templates.d.ts +13 -0
  146. package/dist/api/cma/templates.d.ts.map +1 -0
  147. package/dist/api/cma/templates.js +312 -0
  148. package/dist/api/cma/templates.js.map +1 -0
  149. package/dist/api/cma/uploads.d.ts +4 -0
  150. package/dist/api/cma/uploads.d.ts.map +1 -0
  151. package/dist/api/cma/uploads.js +148 -0
  152. package/dist/api/cma/uploads.js.map +1 -0
  153. package/dist/api/cma/webhooks.d.ts +4 -0
  154. package/dist/api/cma/webhooks.d.ts.map +1 -0
  155. package/dist/api/cma/webhooks.js +175 -0
  156. package/dist/api/cma/webhooks.js.map +1 -0
  157. package/dist/api/cma/white-label.d.ts +4 -0
  158. package/dist/api/cma/white-label.d.ts.map +1 -0
  159. package/dist/api/cma/white-label.js +47 -0
  160. package/dist/api/cma/white-label.js.map +1 -0
  161. package/dist/api/graphql/index.d.ts +4 -0
  162. package/dist/api/graphql/index.d.ts.map +1 -0
  163. package/dist/api/graphql/index.js +57 -0
  164. package/dist/api/graphql/index.js.map +1 -0
  165. package/dist/api/graphql/introspection.d.ts +31 -0
  166. package/dist/api/graphql/introspection.d.ts.map +1 -0
  167. package/dist/api/graphql/introspection.js +90 -0
  168. package/dist/api/graphql/introspection.js.map +1 -0
  169. package/dist/api/graphql/parser.d.ts +14 -0
  170. package/dist/api/graphql/parser.d.ts.map +1 -0
  171. package/dist/api/graphql/parser.js +140 -0
  172. package/dist/api/graphql/parser.js.map +1 -0
  173. package/dist/api/graphql/resolver.d.ts +3 -0
  174. package/dist/api/graphql/resolver.d.ts.map +1 -0
  175. package/dist/api/graphql/resolver.js +138 -0
  176. package/dist/api/graphql/resolver.js.map +1 -0
  177. package/dist/api/preview/content.d.ts +4 -0
  178. package/dist/api/preview/content.d.ts.map +1 -0
  179. package/dist/api/preview/content.js +207 -0
  180. package/dist/api/preview/content.js.map +1 -0
  181. package/dist/api/preview/index.d.ts +4 -0
  182. package/dist/api/preview/index.d.ts.map +1 -0
  183. package/dist/api/preview/index.js +11 -0
  184. package/dist/api/preview/index.js.map +1 -0
  185. package/dist/api/preview/live.d.ts +4 -0
  186. package/dist/api/preview/live.d.ts.map +1 -0
  187. package/dist/api/preview/live.js +41 -0
  188. package/dist/api/preview/live.js.map +1 -0
  189. package/dist/audit/logger.d.ts +13 -0
  190. package/dist/audit/logger.d.ts.map +1 -0
  191. package/dist/audit/logger.js +21 -0
  192. package/dist/audit/logger.js.map +1 -0
  193. package/dist/audit/middleware.d.ts +7 -0
  194. package/dist/audit/middleware.d.ts.map +1 -0
  195. package/dist/audit/middleware.js +39 -0
  196. package/dist/audit/middleware.js.map +1 -0
  197. package/dist/auth/jwt.d.ts +9 -0
  198. package/dist/auth/jwt.d.ts.map +1 -0
  199. package/dist/auth/jwt.js +15 -0
  200. package/dist/auth/jwt.js.map +1 -0
  201. package/dist/auth/middleware.d.ts +24 -0
  202. package/dist/auth/middleware.d.ts.map +1 -0
  203. package/dist/auth/middleware.js +99 -0
  204. package/dist/auth/middleware.js.map +1 -0
  205. package/dist/auth/password.d.ts +3 -0
  206. package/dist/auth/password.d.ts.map +1 -0
  207. package/dist/auth/password.js +9 -0
  208. package/dist/auth/password.js.map +1 -0
  209. package/dist/auth/rate-limit.d.ts +19 -0
  210. package/dist/auth/rate-limit.d.ts.map +1 -0
  211. package/dist/auth/rate-limit.js +77 -0
  212. package/dist/auth/rate-limit.js.map +1 -0
  213. package/dist/auth/rbac.d.ts +10 -0
  214. package/dist/auth/rbac.d.ts.map +1 -0
  215. package/dist/auth/rbac.js +61 -0
  216. package/dist/auth/rbac.js.map +1 -0
  217. package/dist/blocks/core-blocks.d.ts +13 -0
  218. package/dist/blocks/core-blocks.d.ts.map +1 -0
  219. package/dist/blocks/core-blocks.js +113 -0
  220. package/dist/blocks/core-blocks.js.map +1 -0
  221. package/dist/blocks/renderer-sdk.d.ts +75 -0
  222. package/dist/blocks/renderer-sdk.d.ts.map +1 -0
  223. package/dist/blocks/renderer-sdk.js +112 -0
  224. package/dist/blocks/renderer-sdk.js.map +1 -0
  225. package/dist/blocks/seed-core-blocks.d.ts +6 -0
  226. package/dist/blocks/seed-core-blocks.d.ts.map +1 -0
  227. package/dist/blocks/seed-core-blocks.js +37 -0
  228. package/dist/blocks/seed-core-blocks.js.map +1 -0
  229. package/dist/blocks/validator.d.ts +10 -0
  230. package/dist/blocks/validator.d.ts.map +1 -0
  231. package/dist/blocks/validator.js +111 -0
  232. package/dist/blocks/validator.js.map +1 -0
  233. package/dist/cache/cdn-purge.d.ts +41 -0
  234. package/dist/cache/cdn-purge.d.ts.map +1 -0
  235. package/dist/cache/cdn-purge.js +180 -0
  236. package/dist/cache/cdn-purge.js.map +1 -0
  237. package/dist/cache/observability.d.ts +36 -0
  238. package/dist/cache/observability.d.ts.map +1 -0
  239. package/dist/cache/observability.js +110 -0
  240. package/dist/cache/observability.js.map +1 -0
  241. package/dist/cache/tags.d.ts +28 -0
  242. package/dist/cache/tags.d.ts.map +1 -0
  243. package/dist/cache/tags.js +94 -0
  244. package/dist/cache/tags.js.map +1 -0
  245. package/dist/cli/commands/codegen.d.ts +2 -0
  246. package/dist/cli/commands/codegen.d.ts.map +1 -0
  247. package/dist/cli/commands/codegen.js +73 -0
  248. package/dist/cli/commands/codegen.js.map +1 -0
  249. package/dist/cli/commands/dev.d.ts +2 -0
  250. package/dist/cli/commands/dev.d.ts.map +1 -0
  251. package/dist/cli/commands/dev.js +60 -0
  252. package/dist/cli/commands/dev.js.map +1 -0
  253. package/dist/cli/commands/help.d.ts +2 -0
  254. package/dist/cli/commands/help.d.ts.map +1 -0
  255. package/dist/cli/commands/help.js +32 -0
  256. package/dist/cli/commands/help.js.map +1 -0
  257. package/dist/cli/commands/init.d.ts +2 -0
  258. package/dist/cli/commands/init.d.ts.map +1 -0
  259. package/dist/cli/commands/init.js +90 -0
  260. package/dist/cli/commands/init.js.map +1 -0
  261. package/dist/cli/commands/migrate.d.ts +2 -0
  262. package/dist/cli/commands/migrate.d.ts.map +1 -0
  263. package/dist/cli/commands/migrate.js +27 -0
  264. package/dist/cli/commands/migrate.js.map +1 -0
  265. package/dist/cli/commands/seed.d.ts +2 -0
  266. package/dist/cli/commands/seed.d.ts.map +1 -0
  267. package/dist/cli/commands/seed.js +28 -0
  268. package/dist/cli/commands/seed.js.map +1 -0
  269. package/dist/cli/index.d.ts +16 -0
  270. package/dist/cli/index.d.ts.map +1 -0
  271. package/dist/cli/index.js +120 -0
  272. package/dist/cli/index.js.map +1 -0
  273. package/dist/config.d.ts +11 -0
  274. package/dist/config.d.ts.map +1 -0
  275. package/dist/config.js +11 -0
  276. package/dist/config.js.map +1 -0
  277. package/dist/content/advanced-query.d.ts +37 -0
  278. package/dist/content/advanced-query.d.ts.map +1 -0
  279. package/dist/content/advanced-query.js +162 -0
  280. package/dist/content/advanced-query.js.map +1 -0
  281. package/dist/content/cache.d.ts +27 -0
  282. package/dist/content/cache.d.ts.map +1 -0
  283. package/dist/content/cache.js +100 -0
  284. package/dist/content/cache.js.map +1 -0
  285. package/dist/content/diff.d.ts +13 -0
  286. package/dist/content/diff.d.ts.map +1 -0
  287. package/dist/content/diff.js +80 -0
  288. package/dist/content/diff.js.map +1 -0
  289. package/dist/content/localization.d.ts +13 -0
  290. package/dist/content/localization.d.ts.map +1 -0
  291. package/dist/content/localization.js +42 -0
  292. package/dist/content/localization.js.map +1 -0
  293. package/dist/content/materializer.d.ts +26 -0
  294. package/dist/content/materializer.d.ts.map +1 -0
  295. package/dist/content/materializer.js +175 -0
  296. package/dist/content/materializer.js.map +1 -0
  297. package/dist/content/relationships.d.ts +30 -0
  298. package/dist/content/relationships.d.ts.map +1 -0
  299. package/dist/content/relationships.js +123 -0
  300. package/dist/content/relationships.js.map +1 -0
  301. package/dist/db.d.ts +5 -0
  302. package/dist/db.d.ts.map +1 -0
  303. package/dist/db.js +5 -0
  304. package/dist/db.js.map +1 -0
  305. package/dist/events/emitter.d.ts +16 -0
  306. package/dist/events/emitter.d.ts.map +1 -0
  307. package/dist/events/emitter.js +15 -0
  308. package/dist/events/emitter.js.map +1 -0
  309. package/dist/events/sse.d.ts +16 -0
  310. package/dist/events/sse.d.ts.map +1 -0
  311. package/dist/events/sse.js +37 -0
  312. package/dist/events/sse.js.map +1 -0
  313. package/dist/events/wire.d.ts +2 -0
  314. package/dist/events/wire.d.ts.map +1 -0
  315. package/dist/events/wire.js +27 -0
  316. package/dist/events/wire.js.map +1 -0
  317. package/dist/extensions/billing.d.ts +60 -0
  318. package/dist/extensions/billing.d.ts.map +1 -0
  319. package/dist/extensions/billing.js +98 -0
  320. package/dist/extensions/billing.js.map +1 -0
  321. package/dist/extensions/manifest.d.ts +43 -0
  322. package/dist/extensions/manifest.d.ts.map +1 -0
  323. package/dist/extensions/manifest.js +66 -0
  324. package/dist/extensions/manifest.js.map +1 -0
  325. package/dist/extensions/marketplace.d.ts +50 -0
  326. package/dist/extensions/marketplace.d.ts.map +1 -0
  327. package/dist/extensions/marketplace.js +676 -0
  328. package/dist/extensions/marketplace.js.map +1 -0
  329. package/dist/extensions/router.d.ts +4 -0
  330. package/dist/extensions/router.d.ts.map +1 -0
  331. package/dist/extensions/router.js +50 -0
  332. package/dist/extensions/router.js.map +1 -0
  333. package/dist/extensions/runtime.d.ts +29 -0
  334. package/dist/extensions/runtime.d.ts.map +1 -0
  335. package/dist/extensions/runtime.js +201 -0
  336. package/dist/extensions/runtime.js.map +1 -0
  337. package/dist/extensions/sdk.d.ts +146 -0
  338. package/dist/extensions/sdk.d.ts.map +1 -0
  339. package/dist/extensions/sdk.js +114 -0
  340. package/dist/extensions/sdk.js.map +1 -0
  341. package/dist/integrations/sheets.d.ts +41 -0
  342. package/dist/integrations/sheets.d.ts.map +1 -0
  343. package/dist/integrations/sheets.js +230 -0
  344. package/dist/integrations/sheets.js.map +1 -0
  345. package/dist/media/metadata.d.ts +9 -0
  346. package/dist/media/metadata.d.ts.map +1 -0
  347. package/dist/media/metadata.js +84 -0
  348. package/dist/media/metadata.js.map +1 -0
  349. package/dist/media/presets.d.ts +17 -0
  350. package/dist/media/presets.d.ts.map +1 -0
  351. package/dist/media/presets.js +21 -0
  352. package/dist/media/presets.js.map +1 -0
  353. package/dist/media/storage.d.ts +16 -0
  354. package/dist/media/storage.d.ts.map +1 -0
  355. package/dist/media/storage.js +39 -0
  356. package/dist/media/storage.js.map +1 -0
  357. package/dist/media/transforms-engine.d.ts +46 -0
  358. package/dist/media/transforms-engine.d.ts.map +1 -0
  359. package/dist/media/transforms-engine.js +91 -0
  360. package/dist/media/transforms-engine.js.map +1 -0
  361. package/dist/media/transforms.d.ts +15 -0
  362. package/dist/media/transforms.d.ts.map +1 -0
  363. package/dist/media/transforms.js +22 -0
  364. package/dist/media/transforms.js.map +1 -0
  365. package/dist/media/usage.d.ts +21 -0
  366. package/dist/media/usage.d.ts.map +1 -0
  367. package/dist/media/usage.js +105 -0
  368. package/dist/media/usage.js.map +1 -0
  369. package/dist/redis.d.ts +2 -0
  370. package/dist/redis.d.ts.map +1 -0
  371. package/dist/redis.js +9 -0
  372. package/dist/redis.js.map +1 -0
  373. package/dist/schema/codegen.d.ts +6 -0
  374. package/dist/schema/codegen.d.ts.map +1 -0
  375. package/dist/schema/codegen.js +95 -0
  376. package/dist/schema/codegen.js.map +1 -0
  377. package/dist/schema/json-schema.d.ts +42 -0
  378. package/dist/schema/json-schema.d.ts.map +1 -0
  379. package/dist/schema/json-schema.js +68 -0
  380. package/dist/schema/json-schema.js.map +1 -0
  381. package/dist/schema/validator.d.ts +14 -0
  382. package/dist/schema/validator.d.ts.map +1 -0
  383. package/dist/schema/validator.js +103 -0
  384. package/dist/schema/validator.js.map +1 -0
  385. package/dist/sdk/client.d.ts +86 -0
  386. package/dist/sdk/client.d.ts.map +1 -0
  387. package/dist/sdk/client.js +117 -0
  388. package/dist/sdk/client.js.map +1 -0
  389. package/dist/server.d.ts +2 -0
  390. package/dist/server.d.ts.map +1 -0
  391. package/dist/server.js +59 -0
  392. package/dist/server.js.map +1 -0
  393. package/dist/spaces/premium-templates.d.ts +37 -0
  394. package/dist/spaces/premium-templates.d.ts.map +1 -0
  395. package/dist/spaces/premium-templates.js +1603 -0
  396. package/dist/spaces/premium-templates.js.map +1 -0
  397. package/dist/spaces/provisioner.d.ts +16 -0
  398. package/dist/spaces/provisioner.d.ts.map +1 -0
  399. package/dist/spaces/provisioner.js +143 -0
  400. package/dist/spaces/provisioner.js.map +1 -0
  401. package/dist/spaces/template-registry.d.ts +34 -0
  402. package/dist/spaces/template-registry.d.ts.map +1 -0
  403. package/dist/spaces/template-registry.js +55 -0
  404. package/dist/spaces/template-registry.js.map +1 -0
  405. package/dist/spaces/templates.d.ts +44 -0
  406. package/dist/spaces/templates.d.ts.map +1 -0
  407. package/dist/spaces/templates.js +201 -0
  408. package/dist/spaces/templates.js.map +1 -0
  409. package/dist/spaces/white-label.d.ts +20 -0
  410. package/dist/spaces/white-label.d.ts.map +1 -0
  411. package/dist/spaces/white-label.js +32 -0
  412. package/dist/spaces/white-label.js.map +1 -0
  413. package/dist/utils/query-shaping.d.ts +27 -0
  414. package/dist/utils/query-shaping.d.ts.map +1 -0
  415. package/dist/utils/query-shaping.js +69 -0
  416. package/dist/utils/query-shaping.js.map +1 -0
  417. package/dist/utils/space.d.ts +4 -0
  418. package/dist/utils/space.d.ts.map +1 -0
  419. package/dist/utils/space.js +17 -0
  420. package/dist/utils/space.js.map +1 -0
  421. package/dist/webhooks/dispatcher.d.ts +9 -0
  422. package/dist/webhooks/dispatcher.d.ts.map +1 -0
  423. package/dist/webhooks/dispatcher.js +102 -0
  424. package/dist/webhooks/dispatcher.js.map +1 -0
  425. package/package.json +84 -0
  426. package/prisma/migrations/20260403025542_init/migration.sql +315 -0
  427. package/prisma/migrations/20260403034855_add_blocks_and_patterns/migration.sql +40 -0
  428. package/prisma/migrations/20260403041936_add_published_documents/migration.sql +30 -0
  429. package/prisma/migrations/20260403042809_add_locales_and_taxonomies/migration.sql +58 -0
  430. package/prisma/migrations/20260403043033_add_scheduled_unpublish_at/migration.sql +2 -0
  431. package/prisma/migrations/20260403052801_add_environments_and_whitelabel/migration.sql +65 -0
  432. package/prisma/migrations/20260403055920_add_marketplace_and_extension_config/migration.sql +73 -0
  433. package/prisma/migrations/migration_lock.toml +3 -0
  434. package/prisma/schema.prisma +530 -0
  435. package/prisma/seed.ts +154 -0
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Upserts all 7 core block definitions into a space.
3
+ * Marks them builtIn=true so they cannot be accidentally deleted via the API.
4
+ */
5
+ export declare function seedCoreBlocks(spaceId: string): Promise<void>;
6
+ //# sourceMappingURL=seed-core-blocks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed-core-blocks.d.ts","sourceRoot":"","sources":["../../src/blocks/seed-core-blocks.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA6BnE"}
@@ -0,0 +1,37 @@
1
+ import { prisma } from '../db.js';
2
+ import { coreBlocks } from './core-blocks.js';
3
+ /**
4
+ * Upserts all 7 core block definitions into a space.
5
+ * Marks them builtIn=true so they cannot be accidentally deleted via the API.
6
+ */
7
+ export async function seedCoreBlocks(spaceId) {
8
+ for (const block of coreBlocks) {
9
+ await prisma.blockDefinition.upsert({
10
+ where: {
11
+ spaceId_key_version: {
12
+ spaceId,
13
+ key: block.key,
14
+ version: '1.0.0',
15
+ },
16
+ },
17
+ update: {
18
+ title: block.title,
19
+ description: block.description,
20
+ icon: block.icon,
21
+ attributesSchema: JSON.parse(JSON.stringify(block.attributesSchema)),
22
+ builtIn: true,
23
+ },
24
+ create: {
25
+ spaceId,
26
+ key: block.key,
27
+ version: '1.0.0',
28
+ title: block.title,
29
+ description: block.description,
30
+ icon: block.icon,
31
+ attributesSchema: JSON.parse(JSON.stringify(block.attributesSchema)),
32
+ builtIn: true,
33
+ },
34
+ });
35
+ }
36
+ }
37
+ //# sourceMappingURL=seed-core-blocks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed-core-blocks.js","sourceRoot":"","sources":["../../src/blocks/seed-core-blocks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAe;IAClD,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAC/B,MAAM,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC;YAClC,KAAK,EAAE;gBACL,mBAAmB,EAAE;oBACnB,OAAO;oBACP,GAAG,EAAE,KAAK,CAAC,GAAG;oBACd,OAAO,EAAE,OAAO;iBACjB;aACF;YACD,MAAM,EAAE;gBACN,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;gBACpE,OAAO,EAAE,IAAI;aACd;YACD,MAAM,EAAE;gBACN,OAAO;gBACP,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,OAAO,EAAE,OAAO;gBAChB,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,gBAAgB,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;gBACpE,OAAO,EAAE,IAAI;aACd;SACF,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
@@ -0,0 +1,10 @@
1
+ export interface BlockValidationError {
2
+ path: string;
3
+ message: string;
4
+ }
5
+ /**
6
+ * Validates a block tree against registered block definitions for a space.
7
+ * Returns an array of errors (empty = valid).
8
+ */
9
+ export declare function validateBlockTree(blocks: unknown[], spaceId: string): Promise<BlockValidationError[]>;
10
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/blocks/validator.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,OAAO,EAAE,EACjB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAkBjC"}
@@ -0,0 +1,111 @@
1
+ import { prisma } from '../db.js';
2
+ /**
3
+ * Validates a block tree against registered block definitions for a space.
4
+ * Returns an array of errors (empty = valid).
5
+ */
6
+ export async function validateBlockTree(blocks, spaceId) {
7
+ // Load all block definitions for this space (keyed by latest version)
8
+ const definitions = await prisma.blockDefinition.findMany({
9
+ where: { spaceId },
10
+ orderBy: { version: 'desc' },
11
+ });
12
+ // Build a map of key -> latest definition
13
+ const defMap = new Map();
14
+ for (const def of definitions) {
15
+ if (!defMap.has(def.key)) {
16
+ defMap.set(def.key, def);
17
+ }
18
+ }
19
+ const errors = [];
20
+ validateNodes(blocks, defMap, errors, 'blocks');
21
+ return errors;
22
+ }
23
+ function validateNodes(nodes, defMap, errors, basePath) {
24
+ for (let i = 0; i < nodes.length; i++) {
25
+ const node = nodes[i];
26
+ const path = `${basePath}[${i}]`;
27
+ if (!node || typeof node !== 'object') {
28
+ errors.push({ path, message: 'Block must be an object' });
29
+ continue;
30
+ }
31
+ if (!node.typeKey || typeof node.typeKey !== 'string') {
32
+ errors.push({ path, message: 'Block must have a string "typeKey"' });
33
+ continue;
34
+ }
35
+ if (!node.attrs || typeof node.attrs !== 'object') {
36
+ errors.push({ path, message: 'Block must have an "attrs" object' });
37
+ continue;
38
+ }
39
+ const def = defMap.get(node.typeKey);
40
+ if (!def) {
41
+ errors.push({ path, message: `Unknown block type "${node.typeKey}"` });
42
+ continue;
43
+ }
44
+ // Validate attrs against attributesSchema
45
+ const schema = def.attributesSchema;
46
+ if (schema) {
47
+ validateAttrs(node.attrs, schema, errors, `${path}.attrs`);
48
+ }
49
+ // Recurse into children if present
50
+ if (node.children !== undefined) {
51
+ if (!Array.isArray(node.children)) {
52
+ errors.push({ path: `${path}.children`, message: 'Block children must be an array' });
53
+ }
54
+ else {
55
+ validateNodes(node.children, defMap, errors, `${path}.children`);
56
+ }
57
+ }
58
+ }
59
+ }
60
+ function validateAttrs(attrs, schema, errors, basePath) {
61
+ // Check required
62
+ if (schema.required) {
63
+ for (const key of schema.required) {
64
+ if (attrs[key] === undefined || attrs[key] === null) {
65
+ errors.push({ path: `${basePath}.${key}`, message: `"${key}" is required` });
66
+ }
67
+ }
68
+ }
69
+ // Check properties
70
+ if (schema.properties) {
71
+ for (const [key, propSchema] of Object.entries(schema.properties)) {
72
+ const value = attrs[key];
73
+ if (value === undefined || value === null)
74
+ continue;
75
+ validateValue(value, propSchema, errors, `${basePath}.${key}`);
76
+ }
77
+ }
78
+ }
79
+ function validateValue(value, schema, errors, path) {
80
+ // Type check
81
+ if (schema.type) {
82
+ const actualType = Array.isArray(value) ? 'array' : typeof value;
83
+ const expectedType = schema.type === 'integer' ? 'number' : schema.type;
84
+ if (actualType !== expectedType) {
85
+ errors.push({ path, message: `Expected ${schema.type}, got ${actualType}` });
86
+ return;
87
+ }
88
+ if (schema.type === 'integer' && !Number.isInteger(value)) {
89
+ errors.push({ path, message: 'Expected an integer' });
90
+ return;
91
+ }
92
+ }
93
+ // Enum check
94
+ if (schema.enum && !schema.enum.includes(value)) {
95
+ errors.push({ path, message: `Must be one of: ${schema.enum.join(', ')}` });
96
+ }
97
+ // Range checks
98
+ if (schema.minimum !== undefined && typeof value === 'number' && value < schema.minimum) {
99
+ errors.push({ path, message: `Must be >= ${schema.minimum}` });
100
+ }
101
+ if (schema.maximum !== undefined && typeof value === 'number' && value > schema.maximum) {
102
+ errors.push({ path, message: `Must be <= ${schema.maximum}` });
103
+ }
104
+ // Array items check
105
+ if (schema.type === 'array' && Array.isArray(value) && schema.items) {
106
+ for (let i = 0; i < value.length; i++) {
107
+ validateValue(value[i], schema.items, errors, `${path}[${i}]`);
108
+ }
109
+ }
110
+ }
111
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/blocks/validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ export interface CDNProvider {
2
+ /** Purge edge cache by Surrogate-Key / cache tags. */
3
+ purgeByTags(tags: string[]): Promise<void>;
4
+ /** Purge edge cache by exact URLs. */
5
+ purgeByUrl(urls: string[]): Promise<void>;
6
+ /** Nuclear: purge the entire edge cache. */
7
+ purgeAll(): Promise<void>;
8
+ }
9
+ export declare class FastlyCDNProvider implements CDNProvider {
10
+ private readonly apiToken;
11
+ private readonly serviceId;
12
+ constructor();
13
+ purgeByTags(tags: string[]): Promise<void>;
14
+ purgeByUrl(urls: string[]): Promise<void>;
15
+ purgeAll(): Promise<void>;
16
+ }
17
+ export declare class CloudflareCDNProvider implements CDNProvider {
18
+ private readonly apiToken;
19
+ private readonly zoneId;
20
+ constructor();
21
+ purgeByTags(tags: string[]): Promise<void>;
22
+ purgeByUrl(urls: string[]): Promise<void>;
23
+ purgeAll(): Promise<void>;
24
+ }
25
+ export declare class NullCDNProvider implements CDNProvider {
26
+ purgeByTags(_tags: string[]): Promise<void>;
27
+ purgeByUrl(_urls: string[]): Promise<void>;
28
+ purgeAll(): Promise<void>;
29
+ }
30
+ /**
31
+ * Get the configured CDN provider based on the CDN_PROVIDER env var.
32
+ * Defaults to NullCDNProvider when no CDN is configured.
33
+ *
34
+ * Supported values: 'fastly', 'cloudflare'
35
+ */
36
+ export declare function getCDNProvider(): CDNProvider;
37
+ /**
38
+ * Reset the cached provider (useful for testing or config reload).
39
+ */
40
+ export declare function resetCDNProvider(): void;
41
+ //# sourceMappingURL=cdn-purge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cdn-purge.d.ts","sourceRoot":"","sources":["../../src/cache/cdn-purge.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,WAAW;IAC1B,sDAAsD;IACtD,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,sCAAsC;IACtC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,4CAA4C;IAC5C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAID,qBAAa,iBAAkB,YAAW,WAAW;IACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;;IAgB7B,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB1C,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBzC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAahC;AAID,qBAAa,qBAAsB,YAAW,WAAW;IACvD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;;IAgB1B,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB1C,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BzC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAchC;AAID,qBAAa,eAAgB,YAAW,WAAW;IAC3C,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3C,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAI1C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAGhC;AAMD;;;;;GAKG;AACH,wBAAgB,cAAc,IAAI,WAAW,CAkB5C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC"}
@@ -0,0 +1,180 @@
1
+ // ─── CDN Purge Integration ──────────────────────────────────────────
2
+ // Provider-based CDN cache purge. Supports Fastly, Cloudflare, or a
3
+ // null provider (default when no CDN is configured).
4
+ // ─── Fastly CDN Provider ────────────────────────────────────────────
5
+ export class FastlyCDNProvider {
6
+ apiToken;
7
+ serviceId;
8
+ constructor() {
9
+ const apiToken = process.env.FASTLY_API_TOKEN;
10
+ const serviceId = process.env.FASTLY_SERVICE_ID;
11
+ if (!apiToken || !serviceId) {
12
+ throw new Error('FastlyCDNProvider requires FASTLY_API_TOKEN and FASTLY_SERVICE_ID environment variables');
13
+ }
14
+ this.apiToken = apiToken;
15
+ this.serviceId = serviceId;
16
+ }
17
+ async purgeByTags(tags) {
18
+ if (tags.length === 0)
19
+ return;
20
+ // Fastly supports purging by Surrogate-Key header (space-separated tags)
21
+ // POST /service/{service_id}/purge
22
+ try {
23
+ await fetch(`https://api.fastly.com/service/${this.serviceId}/purge`, {
24
+ method: 'POST',
25
+ headers: {
26
+ 'Fastly-Key': this.apiToken,
27
+ 'Surrogate-Key': tags.join(' '),
28
+ 'Accept': 'application/json',
29
+ },
30
+ });
31
+ }
32
+ catch (err) {
33
+ console.error('[CDN:Fastly] purgeByTags failed:', err);
34
+ }
35
+ }
36
+ async purgeByUrl(urls) {
37
+ if (urls.length === 0)
38
+ return;
39
+ // Fastly purges individual URLs via PURGE method
40
+ try {
41
+ await Promise.all(urls.map((url) => fetch(url, {
42
+ method: 'PURGE',
43
+ headers: {
44
+ 'Fastly-Key': this.apiToken,
45
+ },
46
+ })));
47
+ }
48
+ catch (err) {
49
+ console.error('[CDN:Fastly] purgeByUrl failed:', err);
50
+ }
51
+ }
52
+ async purgeAll() {
53
+ try {
54
+ await fetch(`https://api.fastly.com/service/${this.serviceId}/purge_all`, {
55
+ method: 'POST',
56
+ headers: {
57
+ 'Fastly-Key': this.apiToken,
58
+ 'Accept': 'application/json',
59
+ },
60
+ });
61
+ }
62
+ catch (err) {
63
+ console.error('[CDN:Fastly] purgeAll failed:', err);
64
+ }
65
+ }
66
+ }
67
+ // ─── Cloudflare CDN Provider ────────────────────────────────────────
68
+ export class CloudflareCDNProvider {
69
+ apiToken;
70
+ zoneId;
71
+ constructor() {
72
+ const apiToken = process.env.CF_API_TOKEN;
73
+ const zoneId = process.env.CF_ZONE_ID;
74
+ if (!apiToken || !zoneId) {
75
+ throw new Error('CloudflareCDNProvider requires CF_API_TOKEN and CF_ZONE_ID environment variables');
76
+ }
77
+ this.apiToken = apiToken;
78
+ this.zoneId = zoneId;
79
+ }
80
+ async purgeByTags(tags) {
81
+ if (tags.length === 0)
82
+ return;
83
+ // Cloudflare Enterprise supports Cache-Tag purge
84
+ // POST /zones/{zone_id}/purge_cache
85
+ try {
86
+ await fetch(`https://api.cloudflare.com/client/v4/zones/${this.zoneId}/purge_cache`, {
87
+ method: 'POST',
88
+ headers: {
89
+ 'Authorization': `Bearer ${this.apiToken}`,
90
+ 'Content-Type': 'application/json',
91
+ },
92
+ body: JSON.stringify({ tags }),
93
+ });
94
+ }
95
+ catch (err) {
96
+ console.error('[CDN:Cloudflare] purgeByTags failed:', err);
97
+ }
98
+ }
99
+ async purgeByUrl(urls) {
100
+ if (urls.length === 0)
101
+ return;
102
+ try {
103
+ // Cloudflare supports up to 30 URLs per request
104
+ const chunks = [];
105
+ for (let i = 0; i < urls.length; i += 30) {
106
+ chunks.push(urls.slice(i, i + 30));
107
+ }
108
+ await Promise.all(chunks.map((chunk) => fetch(`https://api.cloudflare.com/client/v4/zones/${this.zoneId}/purge_cache`, {
109
+ method: 'POST',
110
+ headers: {
111
+ 'Authorization': `Bearer ${this.apiToken}`,
112
+ 'Content-Type': 'application/json',
113
+ },
114
+ body: JSON.stringify({ files: chunk }),
115
+ })));
116
+ }
117
+ catch (err) {
118
+ console.error('[CDN:Cloudflare] purgeByUrl failed:', err);
119
+ }
120
+ }
121
+ async purgeAll() {
122
+ try {
123
+ await fetch(`https://api.cloudflare.com/client/v4/zones/${this.zoneId}/purge_cache`, {
124
+ method: 'POST',
125
+ headers: {
126
+ 'Authorization': `Bearer ${this.apiToken}`,
127
+ 'Content-Type': 'application/json',
128
+ },
129
+ body: JSON.stringify({ purge_everything: true }),
130
+ });
131
+ }
132
+ catch (err) {
133
+ console.error('[CDN:Cloudflare] purgeAll failed:', err);
134
+ }
135
+ }
136
+ }
137
+ // ─── Null CDN Provider ──────────────────────────────────────────────
138
+ export class NullCDNProvider {
139
+ async purgeByTags(_tags) {
140
+ // No CDN configured — nothing to purge
141
+ }
142
+ async purgeByUrl(_urls) {
143
+ // No CDN configured — nothing to purge
144
+ }
145
+ async purgeAll() {
146
+ // No CDN configured — nothing to purge
147
+ }
148
+ }
149
+ // ─── Factory ────────────────────────────────────────────────────────
150
+ let _provider;
151
+ /**
152
+ * Get the configured CDN provider based on the CDN_PROVIDER env var.
153
+ * Defaults to NullCDNProvider when no CDN is configured.
154
+ *
155
+ * Supported values: 'fastly', 'cloudflare'
156
+ */
157
+ export function getCDNProvider() {
158
+ if (_provider)
159
+ return _provider;
160
+ const providerName = (process.env.CDN_PROVIDER ?? '').toLowerCase();
161
+ switch (providerName) {
162
+ case 'fastly':
163
+ _provider = new FastlyCDNProvider();
164
+ break;
165
+ case 'cloudflare':
166
+ _provider = new CloudflareCDNProvider();
167
+ break;
168
+ default:
169
+ _provider = new NullCDNProvider();
170
+ break;
171
+ }
172
+ return _provider;
173
+ }
174
+ /**
175
+ * Reset the cached provider (useful for testing or config reload).
176
+ */
177
+ export function resetCDNProvider() {
178
+ _provider = undefined;
179
+ }
180
+ //# sourceMappingURL=cdn-purge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cdn-purge.js","sourceRoot":"","sources":["../../src/cache/cdn-purge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ export interface CacheStats {
2
+ hits: number;
3
+ misses: number;
4
+ evictions: number;
5
+ size: number;
6
+ hitRate: number;
7
+ }
8
+ export interface CacheTagInfo {
9
+ tag: string;
10
+ keyCount: number;
11
+ }
12
+ /**
13
+ * Record a cache hit. Call this from the CDA response flow
14
+ * when a Redis cache lookup succeeds.
15
+ */
16
+ export declare function trackCacheHit(): Promise<void>;
17
+ /**
18
+ * Record a cache miss. Call this from the CDA response flow
19
+ * when a Redis cache lookup returns null.
20
+ */
21
+ export declare function trackCacheMiss(): Promise<void>;
22
+ /**
23
+ * Retrieve aggregated cache statistics from Redis INFO and custom counters.
24
+ */
25
+ export declare function getCacheStats(): Promise<CacheStats>;
26
+ /**
27
+ * List cache keys matching a glob pattern using SCAN (non-blocking).
28
+ * Limits results to 1000 keys to prevent unbounded responses.
29
+ */
30
+ export declare function getCacheKeys(pattern: string): Promise<string[]>;
31
+ /**
32
+ * List all Surrogate-Key / cache tags for a space with key counts.
33
+ * Tags are stored in Redis sets with the pattern `cache-tag:{tag}`.
34
+ */
35
+ export declare function getCacheTags(spaceId: string): Promise<CacheTagInfo[]>;
36
+ //# sourceMappingURL=observability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observability.d.ts","sourceRoot":"","sources":["../../src/cache/observability.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;CAClB;AASD;;;GAGG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAMnD;AAED;;;GAGG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAMpD;AAID;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC,CA8BzD;AAID;;;GAGG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAiBrE;AAID;;;GAGG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAiB3E"}
@@ -0,0 +1,110 @@
1
+ // ─── Cache Observability & Metrics ──────────────────────────────────
2
+ // Provides cache hit/miss statistics, key listing, and tag inspection
3
+ // by reading from Redis INFO + custom counters.
4
+ import { redis } from '../redis.js';
5
+ // ─── Counter Keys ───────────────────────────────────────────────────
6
+ const COUNTER_HITS = 'cache-stats:hits';
7
+ const COUNTER_MISSES = 'cache-stats:misses';
8
+ // ─── Tracking ───────────────────────────────────────────────────────
9
+ /**
10
+ * Record a cache hit. Call this from the CDA response flow
11
+ * when a Redis cache lookup succeeds.
12
+ */
13
+ export async function trackCacheHit() {
14
+ try {
15
+ await redis.incr(COUNTER_HITS);
16
+ }
17
+ catch {
18
+ // Non-critical — swallow Redis errors
19
+ }
20
+ }
21
+ /**
22
+ * Record a cache miss. Call this from the CDA response flow
23
+ * when a Redis cache lookup returns null.
24
+ */
25
+ export async function trackCacheMiss() {
26
+ try {
27
+ await redis.incr(COUNTER_MISSES);
28
+ }
29
+ catch {
30
+ // Non-critical — swallow Redis errors
31
+ }
32
+ }
33
+ // ─── Stats ──────────────────────────────────────────────────────────
34
+ /**
35
+ * Retrieve aggregated cache statistics from Redis INFO and custom counters.
36
+ */
37
+ export async function getCacheStats() {
38
+ try {
39
+ const [hitsStr, missesStr, infoRaw] = await Promise.all([
40
+ redis.get(COUNTER_HITS),
41
+ redis.get(COUNTER_MISSES),
42
+ redis.info('stats'),
43
+ ]);
44
+ const hits = parseInt(hitsStr ?? '0', 10);
45
+ const misses = parseInt(missesStr ?? '0', 10);
46
+ const total = hits + misses;
47
+ const hitRate = total > 0 ? hits / total : 0;
48
+ // Parse evictions from Redis INFO stats section
49
+ const evictedMatch = infoRaw.match(/evicted_keys:(\d+)/);
50
+ const evictions = evictedMatch ? parseInt(evictedMatch[1], 10) : 0;
51
+ // Parse dbsize for total key count
52
+ const dbSize = await redis.dbsize();
53
+ return {
54
+ hits,
55
+ misses,
56
+ evictions,
57
+ size: dbSize,
58
+ hitRate: Math.round(hitRate * 10000) / 10000, // 4 decimal places
59
+ };
60
+ }
61
+ catch {
62
+ return { hits: 0, misses: 0, evictions: 0, size: 0, hitRate: 0 };
63
+ }
64
+ }
65
+ // ─── Key Inspection ─────────────────────────────────────────────────
66
+ /**
67
+ * List cache keys matching a glob pattern using SCAN (non-blocking).
68
+ * Limits results to 1000 keys to prevent unbounded responses.
69
+ */
70
+ export async function getCacheKeys(pattern) {
71
+ const keys = [];
72
+ const MAX_KEYS = 1000;
73
+ try {
74
+ let cursor = '0';
75
+ do {
76
+ const [nextCursor, batch] = await redis.scan(cursor, 'MATCH', pattern, 'COUNT', 200);
77
+ cursor = nextCursor;
78
+ keys.push(...batch);
79
+ if (keys.length >= MAX_KEYS)
80
+ break;
81
+ } while (cursor !== '0');
82
+ }
83
+ catch {
84
+ // Swallow — return whatever we collected
85
+ }
86
+ return keys.slice(0, MAX_KEYS);
87
+ }
88
+ // ─── Tag Inspection ─────────────────────────────────────────────────
89
+ /**
90
+ * List all Surrogate-Key / cache tags for a space with key counts.
91
+ * Tags are stored in Redis sets with the pattern `cache-tag:{tag}`.
92
+ */
93
+ export async function getCacheTags(spaceId) {
94
+ const tagKeys = await getCacheKeys(`cache-tag:${spaceId}:*`);
95
+ const tags = [];
96
+ for (const tagKey of tagKeys) {
97
+ try {
98
+ const keyCount = await redis.scard(tagKey);
99
+ // Extract the tag name from the Redis key: "cache-tag:spaceId:tagName" -> "tagName"
100
+ const parts = tagKey.split(':');
101
+ const tag = parts.slice(2).join(':');
102
+ tags.push({ tag, keyCount });
103
+ }
104
+ catch {
105
+ // Skip broken tags
106
+ }
107
+ }
108
+ return tags.sort((a, b) => b.keyCount - a.keyCount);
109
+ }
110
+ //# sourceMappingURL=observability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observability.js","sourceRoot":"","sources":["../../src/cache/observability.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Associate a cache key with one or more tags.
3
+ * Tags are stored as Redis sets: `cache-tag:{tag}` -> set of cache keys.
4
+ * Each association is given the same TTL as the cache key itself (or 1 hour
5
+ * as a fallback) so that stale tag associations self-clean.
6
+ */
7
+ export declare function addCacheTag(key: string, tags: string[]): Promise<void>;
8
+ /**
9
+ * Delete all cache keys associated with a tag, then remove the tag set itself.
10
+ * Returns the number of cache keys that were deleted.
11
+ */
12
+ export declare function invalidateByTag(tag: string): Promise<number>;
13
+ /**
14
+ * Invalidate multiple tags at once. Returns total number of cache keys deleted.
15
+ */
16
+ export declare function invalidateByTags(tags: string[]): Promise<number>;
17
+ /**
18
+ * Purge both Redis cache and CDN edge caches for the given tags.
19
+ * Calls invalidateByTag for each tag, then delegates to the configured
20
+ * CDN provider to purge edge caches.
21
+ */
22
+ export declare function purgeCDN(tags: string[]): Promise<void>;
23
+ /**
24
+ * Build standard Surrogate-Key tags for a CDA response.
25
+ * Used by the CDA content endpoints to register tags after caching.
26
+ */
27
+ export declare function buildSurrogateKeyTags(spaceId: string, contentTypeKey: string, entryId?: string): string[];
28
+ //# sourceMappingURL=tags.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tags.d.ts","sourceRoot":"","sources":["../../src/cache/tags.ts"],"names":[],"mappings":"AAWA;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB5E;AAID;;;GAGG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAqBlE;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAMtE;AAID;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAO5D;AAID;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,MAAM,EACtB,OAAO,CAAC,EAAE,MAAM,GACf,MAAM,EAAE,CAWV"}