@upstart.gg/sdk 0.0.129 → 0.0.131

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 (529) hide show
  1. package/dist/shared/ai/schemas.d.ts +13 -0
  2. package/dist/shared/ai/schemas.d.ts.map +1 -0
  3. package/dist/shared/ai/schemas.js +3 -0
  4. package/dist/shared/ai/types.d.ts +164 -0
  5. package/dist/shared/ai/types.d.ts.map +1 -0
  6. package/dist/shared/{chunk-EJGNYD4V.js → ai/types.js} +0 -1
  7. package/dist/shared/ajv.d.ts +2 -1
  8. package/dist/shared/ajv.d.ts.map +1 -1
  9. package/dist/shared/ajv.js +1 -1
  10. package/dist/shared/attributes.d.ts +300 -12
  11. package/dist/shared/attributes.d.ts.map +1 -1
  12. package/dist/shared/attributes.js +1 -1
  13. package/dist/shared/brick-manifest.d.ts +3 -1
  14. package/dist/shared/brick-manifest.d.ts.map +1 -1
  15. package/dist/shared/brick-manifest.js +1 -1
  16. package/dist/shared/bricks/manifests/accordion.manifest.d.ts +4 -3
  17. package/dist/shared/bricks/manifests/accordion.manifest.d.ts.map +1 -1
  18. package/dist/shared/bricks/manifests/accordion.manifest.js +1 -1
  19. package/dist/shared/bricks/manifests/all-manifests.d.ts +4 -1
  20. package/dist/shared/bricks/manifests/all-manifests.d.ts.map +1 -1
  21. package/dist/shared/bricks/manifests/all-manifests.js +1 -1
  22. package/dist/shared/bricks/manifests/box.manifest.d.ts +6 -4
  23. package/dist/shared/bricks/manifests/box.manifest.d.ts.map +1 -1
  24. package/dist/shared/bricks/manifests/box.manifest.js +1 -1
  25. package/dist/shared/bricks/manifests/button.manifest.d.ts +4 -3
  26. package/dist/shared/bricks/manifests/button.manifest.d.ts.map +1 -1
  27. package/dist/shared/bricks/manifests/button.manifest.js +1 -1
  28. package/dist/shared/bricks/manifests/card.manifest.d.ts +6 -5
  29. package/dist/shared/bricks/manifests/card.manifest.d.ts.map +1 -1
  30. package/dist/shared/bricks/manifests/card.manifest.js +1 -1
  31. package/dist/shared/bricks/manifests/carousel.manifest.d.ts +6 -5
  32. package/dist/shared/bricks/manifests/carousel.manifest.d.ts.map +1 -1
  33. package/dist/shared/bricks/manifests/carousel.manifest.js +1 -1
  34. package/dist/shared/bricks/manifests/footer.manifest.d.ts +40 -5
  35. package/dist/shared/bricks/manifests/footer.manifest.d.ts.map +1 -1
  36. package/dist/shared/bricks/manifests/footer.manifest.js +1 -1
  37. package/dist/shared/bricks/manifests/form.manifest.d.ts +6 -5
  38. package/dist/shared/bricks/manifests/form.manifest.d.ts.map +1 -1
  39. package/dist/shared/bricks/manifests/form.manifest.js +1 -1
  40. package/dist/shared/bricks/manifests/hero.manifest.d.ts +4 -3
  41. package/dist/shared/bricks/manifests/hero.manifest.d.ts.map +1 -1
  42. package/dist/shared/bricks/manifests/hero.manifest.js +1 -1
  43. package/dist/shared/bricks/manifests/html.manifest.d.ts +3 -2
  44. package/dist/shared/bricks/manifests/html.manifest.d.ts.map +1 -1
  45. package/dist/shared/bricks/manifests/html.manifest.js +1 -1
  46. package/dist/shared/bricks/manifests/icon.manifest.d.ts +3 -2
  47. package/dist/shared/bricks/manifests/icon.manifest.d.ts.map +1 -1
  48. package/dist/shared/bricks/manifests/icon.manifest.js +1 -1
  49. package/dist/shared/bricks/manifests/image.manifest.d.ts +10 -6
  50. package/dist/shared/bricks/manifests/image.manifest.d.ts.map +1 -1
  51. package/dist/shared/bricks/manifests/image.manifest.js +1 -1
  52. package/dist/shared/bricks/manifests/images-gallery.manifest.d.ts +7 -6
  53. package/dist/shared/bricks/manifests/images-gallery.manifest.d.ts.map +1 -1
  54. package/dist/shared/bricks/manifests/images-gallery.manifest.js +1 -1
  55. package/dist/shared/bricks/manifests/map.manifest.d.ts +5 -4
  56. package/dist/shared/bricks/manifests/map.manifest.d.ts.map +1 -1
  57. package/dist/shared/bricks/manifests/map.manifest.js +1 -1
  58. package/dist/shared/bricks/manifests/navbar.manifest.d.ts +42 -8
  59. package/dist/shared/bricks/manifests/navbar.manifest.d.ts.map +1 -1
  60. package/dist/shared/bricks/manifests/navbar.manifest.js +1 -1
  61. package/dist/shared/bricks/manifests/sidebar.manifest.d.ts +4 -3
  62. package/dist/shared/bricks/manifests/sidebar.manifest.d.ts.map +1 -1
  63. package/dist/shared/bricks/manifests/sidebar.manifest.js +1 -1
  64. package/dist/shared/bricks/manifests/social-links.manifest.d.ts +5 -4
  65. package/dist/shared/bricks/manifests/social-links.manifest.d.ts.map +1 -1
  66. package/dist/shared/bricks/manifests/social-links.manifest.js +1 -1
  67. package/dist/shared/bricks/manifests/spacer.manifest.d.ts +3 -2
  68. package/dist/shared/bricks/manifests/spacer.manifest.d.ts.map +1 -1
  69. package/dist/shared/bricks/manifests/spacer.manifest.js +1 -1
  70. package/dist/shared/bricks/manifests/testimonials.manifest.d.ts +6 -5
  71. package/dist/shared/bricks/manifests/testimonials.manifest.d.ts.map +1 -1
  72. package/dist/shared/bricks/manifests/testimonials.manifest.js +1 -1
  73. package/dist/shared/bricks/manifests/text.manifest.d.ts +4 -3
  74. package/dist/shared/bricks/manifests/text.manifest.d.ts.map +1 -1
  75. package/dist/shared/bricks/manifests/text.manifest.js +1 -1
  76. package/dist/shared/bricks/manifests/video.manifest.d.ts +4 -3
  77. package/dist/shared/bricks/manifests/video.manifest.d.ts.map +1 -1
  78. package/dist/shared/bricks/manifests/video.manifest.js +1 -1
  79. package/dist/shared/bricks/props/align.d.ts.map +1 -1
  80. package/dist/shared/bricks/props/align.js +1 -1
  81. package/dist/shared/bricks/props/background.d.ts +6 -9
  82. package/dist/shared/bricks/props/background.d.ts.map +1 -1
  83. package/dist/shared/bricks/props/background.js +1 -1
  84. package/dist/shared/bricks/props/border.d.ts.map +1 -1
  85. package/dist/shared/bricks/props/border.js +1 -1
  86. package/dist/shared/bricks/props/color-preset.d.ts +3 -4
  87. package/dist/shared/bricks/props/color-preset.d.ts.map +1 -1
  88. package/dist/shared/bricks/props/color-preset.js +1 -1
  89. package/dist/shared/bricks/props/color.js +1 -1
  90. package/dist/shared/bricks/props/common.d.ts +6 -6
  91. package/dist/shared/bricks/props/common.d.ts.map +1 -1
  92. package/dist/shared/bricks/props/common.js +1 -1
  93. package/dist/shared/bricks/props/css-length.d.ts.map +1 -1
  94. package/dist/shared/bricks/props/css-length.js +1 -1
  95. package/dist/shared/bricks/props/datasource.d.ts +1 -1
  96. package/dist/shared/bricks/props/datasource.js +1 -1
  97. package/dist/shared/bricks/props/date.d.ts.map +1 -1
  98. package/dist/shared/bricks/props/date.js +1 -1
  99. package/dist/shared/bricks/props/direction.d.ts.map +1 -1
  100. package/dist/shared/bricks/props/direction.js +1 -1
  101. package/dist/shared/bricks/props/dynamic.d.ts.map +1 -1
  102. package/dist/shared/bricks/props/dynamic.js +1 -1
  103. package/dist/shared/bricks/props/effects.d.ts +0 -1
  104. package/dist/shared/bricks/props/effects.d.ts.map +1 -1
  105. package/dist/shared/bricks/props/effects.js +1 -1
  106. package/dist/shared/bricks/props/file.d.ts.map +1 -1
  107. package/dist/shared/bricks/props/file.js +1 -1
  108. package/dist/shared/bricks/props/geolocation.js +1 -1
  109. package/dist/shared/bricks/props/helpers.d.ts +2 -2
  110. package/dist/shared/bricks/props/helpers.js +1 -1
  111. package/dist/shared/bricks/props/image.d.ts +4 -4
  112. package/dist/shared/bricks/props/image.d.ts.map +1 -1
  113. package/dist/shared/bricks/props/image.js +1 -1
  114. package/dist/shared/bricks/props/position.d.ts +0 -2
  115. package/dist/shared/bricks/props/position.d.ts.map +1 -1
  116. package/dist/shared/bricks/props/position.js +1 -1
  117. package/dist/shared/bricks/props/string.js +1 -1
  118. package/dist/shared/bricks/props/tags.d.ts.map +1 -1
  119. package/dist/shared/bricks/props/tags.js +1 -1
  120. package/dist/shared/bricks/props/text.js +1 -1
  121. package/dist/shared/bricks/props/types.d.ts +1 -2
  122. package/dist/shared/bricks/props/types.d.ts.map +1 -1
  123. package/dist/shared/bricks.d.ts +189 -18
  124. package/dist/shared/bricks.d.ts.map +1 -1
  125. package/dist/shared/bricks.js +1 -1
  126. package/dist/shared/chunk-2CYAFF56.js +3 -0
  127. package/dist/shared/chunk-2NLDX5FG.js +3 -0
  128. package/dist/shared/chunk-3FPFR5RA.js +3 -0
  129. package/dist/shared/chunk-3P36LG6T.js +3 -0
  130. package/dist/shared/chunk-3QOAHMV4.js +5 -0
  131. package/dist/shared/chunk-4GIZ6WSG.js +3 -0
  132. package/dist/shared/chunk-5WY7LYXK.js +3 -0
  133. package/dist/shared/chunk-5X5SX5N7.js +4 -0
  134. package/dist/shared/chunk-6L3Z5SZQ.js +3 -0
  135. package/dist/shared/{chunk-UU2MSQXY.js → chunk-6PGAWO4H.js} +1 -1
  136. package/dist/shared/chunk-6R76KIHZ.js +3 -0
  137. package/dist/shared/chunk-7UBMXMNJ.js +3 -0
  138. package/dist/shared/chunk-AB3IMRXZ.js +3 -0
  139. package/dist/shared/chunk-AMQAGDFH.js +3 -0
  140. package/dist/shared/chunk-ARMM6B47.js +3 -0
  141. package/dist/shared/chunk-ARYG4XMX.js +3 -0
  142. package/dist/shared/chunk-AZHH3XJJ.js +3 -0
  143. package/dist/shared/chunk-COT2ROEH.js +34 -0
  144. package/dist/shared/chunk-DHSWVVMI.js +3 -0
  145. package/dist/shared/chunk-DKNOZLA6.js +3 -0
  146. package/dist/shared/chunk-EVDZ2KND.js +6 -0
  147. package/dist/shared/chunk-F4JNKU7J.js +3 -0
  148. package/dist/shared/chunk-GC5OWY2Z.js +3 -0
  149. package/dist/shared/chunk-GXNHF6J5.js +3 -0
  150. package/dist/shared/chunk-HP7CZB2F.js +3 -0
  151. package/dist/shared/chunk-HSRXUIVM.js +3 -0
  152. package/dist/shared/chunk-ILIWVWHC.js +8 -0
  153. package/dist/shared/chunk-JRCVYDCD.js +3 -0
  154. package/dist/shared/chunk-L2HOZVBC.js +3 -0
  155. package/dist/shared/chunk-LEWKHCRI.js +3 -0
  156. package/dist/shared/chunk-LT4CW2F7.js +3 -0
  157. package/dist/shared/chunk-MVCVVKBY.js +3 -0
  158. package/dist/shared/chunk-NKIEDT7V.js +3 -0
  159. package/dist/shared/chunk-NQKXDMQ5.js +3 -0
  160. package/dist/shared/chunk-NXIF3UMD.js +3 -0
  161. package/dist/shared/chunk-PW5HRVMD.js +3 -0
  162. package/dist/shared/chunk-PZYX3ACO.js +3 -0
  163. package/dist/shared/chunk-QDJQAZIA.js +8 -0
  164. package/dist/shared/chunk-QGFQA7OZ.js +4 -0
  165. package/dist/shared/chunk-RJZZWCBD.js +3 -0
  166. package/dist/shared/chunk-SAJY7H6N.js +3 -0
  167. package/dist/shared/chunk-SFDRAHYP.js +3 -0
  168. package/dist/shared/chunk-STDCM2KD.js +3 -0
  169. package/dist/shared/chunk-TCTVRT4O.js +3 -0
  170. package/dist/shared/chunk-TH5SONR6.js +3 -0
  171. package/dist/shared/chunk-UCR2UZOY.js +3 -0
  172. package/dist/shared/chunk-UDQWYGSO.js +3 -0
  173. package/dist/shared/{chunk-LSPN22SI.js → chunk-URRCKLAS.js} +3 -3
  174. package/dist/shared/{chunk-OIOYMECS.js → chunk-US53TNMK.js} +1 -1
  175. package/dist/shared/chunk-VDX2J22H.js +3 -0
  176. package/dist/shared/chunk-VE3S4LGT.js +3 -0
  177. package/dist/shared/chunk-VK26ZZFR.js +3 -0
  178. package/dist/shared/chunk-VLXZMESE.js +3 -0
  179. package/dist/shared/chunk-WAML3IGZ.js +3 -0
  180. package/dist/shared/chunk-WXKRIUTA.js +3 -0
  181. package/dist/shared/chunk-X62OEAE6.js +3 -0
  182. package/dist/shared/chunk-XED6ARVN.js +3 -0
  183. package/dist/shared/chunk-Y3X4F4YJ.js +3 -0
  184. package/dist/shared/chunk-Z4YKRLOX.js +3 -0
  185. package/dist/shared/context.d.ts +6 -15
  186. package/dist/shared/context.d.ts.map +1 -1
  187. package/dist/shared/datarecords/external/airtable/handler.d.ts +24 -7
  188. package/dist/shared/datarecords/external/airtable/handler.d.ts.map +1 -1
  189. package/dist/shared/datarecords/external/airtable/handler.js +3 -0
  190. package/dist/shared/datarecords/external/airtable/oauth/config.js +3 -0
  191. package/dist/shared/datarecords/external/airtable/types.d.ts +40 -0
  192. package/dist/shared/datarecords/external/airtable/types.d.ts.map +1 -0
  193. package/dist/shared/datarecords/external/airtable/types.js +3 -0
  194. package/dist/shared/datarecords/external/generic-webhook/handler.js +3 -0
  195. package/dist/shared/datarecords/external/generic-webhook/options.js +3 -0
  196. package/dist/shared/datarecords/external/google/sheets/client.d.ts +14 -0
  197. package/dist/shared/datarecords/external/google/sheets/client.d.ts.map +1 -0
  198. package/dist/shared/datarecords/external/google/sheets/client.js +3 -0
  199. package/dist/shared/datarecords/external/google/sheets/handler.d.ts +27 -5
  200. package/dist/shared/datarecords/external/google/sheets/handler.d.ts.map +1 -1
  201. package/dist/shared/datarecords/external/google/sheets/handler.js +7 -0
  202. package/dist/shared/datarecords/external/google/sheets/{options.d.ts → types.d.ts} +1 -1
  203. package/dist/shared/datarecords/external/google/sheets/types.d.ts.map +1 -0
  204. package/dist/shared/datarecords/external/google/sheets/types.js +3 -0
  205. package/dist/shared/datarecords/external/notion/handler.d.ts +31 -0
  206. package/dist/shared/datarecords/external/notion/handler.d.ts.map +1 -0
  207. package/dist/shared/datarecords/external/notion/handler.js +3 -0
  208. package/dist/shared/datarecords/external/notion/oauth/config.js +3 -0
  209. package/dist/shared/datarecords/external/notion/{options.d.ts → types.d.ts} +11 -1
  210. package/dist/shared/datarecords/external/notion/types.d.ts.map +1 -0
  211. package/dist/shared/datarecords/external/notion/types.js +3 -0
  212. package/dist/shared/datarecords/types.d.ts +17 -18
  213. package/dist/shared/datarecords/types.d.ts.map +1 -1
  214. package/dist/shared/datarecords/types.js +1 -1
  215. package/dist/shared/datarecords.d.ts +2 -2
  216. package/dist/shared/datarecords.d.ts.map +1 -1
  217. package/dist/shared/datarecords.js +1 -1
  218. package/dist/shared/datasources/external/facebook/posts/fetcher.js +3 -0
  219. package/dist/shared/datasources/external/facebook/posts/schema.js +3 -0
  220. package/dist/shared/datasources/external/http-json/fetcher.js +3 -0
  221. package/dist/shared/datasources/external/http-json/options.js +3 -0
  222. package/dist/shared/datasources/external/http-json/schema.js +3 -0
  223. package/dist/shared/datasources/external/instagram/feed/fetcher.js +3 -0
  224. package/dist/shared/datasources/external/instagram/feed/schema.js +3 -0
  225. package/dist/shared/datasources/external/mastodon/account/fetcher.js +3 -0
  226. package/dist/shared/datasources/external/mastodon/account/schema.js +3 -0
  227. package/dist/shared/datasources/external/mastodon/options.js +3 -0
  228. package/dist/shared/datasources/external/mastodon/status/fetcher.js +3 -0
  229. package/dist/shared/datasources/external/mastodon/status/sample.array.js +3 -0
  230. package/dist/shared/datasources/external/mastodon/status/sample.single.js +3 -0
  231. package/dist/shared/datasources/external/mastodon/status/schema.d.ts.map +1 -1
  232. package/dist/shared/datasources/external/mastodon/status/schema.js +3 -0
  233. package/dist/shared/datasources/external/meta/options.js +3 -0
  234. package/dist/shared/datasources/external/rss/fetcher.js +3 -0
  235. package/dist/shared/datasources/external/rss/options.js +3 -0
  236. package/dist/shared/datasources/external/rss/schema.js +3 -0
  237. package/dist/shared/datasources/external/threads/media/fetcher.js +3 -0
  238. package/dist/shared/datasources/external/threads/media/schema.js +3 -0
  239. package/dist/shared/datasources/external/tiktok/video/fetcher.js +3 -0
  240. package/dist/shared/datasources/external/tiktok/video/options.js +3 -0
  241. package/dist/shared/datasources/external/tiktok/video/schema.js +3 -0
  242. package/dist/shared/datasources/external/youtube/list/fetcher.js +3 -0
  243. package/dist/shared/datasources/external/youtube/list/options.js +3 -0
  244. package/dist/shared/datasources/external/youtube/list/schema.js +3 -0
  245. package/dist/shared/datasources/fetcher.js +2 -0
  246. package/dist/shared/datasources/internal/blog/schema.js +3 -0
  247. package/dist/shared/datasources/internal/changelog/schema.js +3 -0
  248. package/dist/shared/datasources/internal/contact-info/schema.js +3 -0
  249. package/dist/shared/datasources/internal/cv/schema.js +3 -0
  250. package/dist/shared/datasources/internal/faq/schema.js +3 -0
  251. package/dist/shared/datasources/internal/job-board/schema.js +3 -0
  252. package/dist/shared/datasources/internal/links/schema.js +3 -0
  253. package/dist/shared/datasources/internal/recipes/schema.js +3 -0
  254. package/dist/shared/datasources/internal/restaurant/schema.js +3 -0
  255. package/dist/shared/datasources/samples.js +3 -0
  256. package/dist/shared/datasources/schemas.d.ts +0 -49
  257. package/dist/shared/datasources/schemas.d.ts.map +1 -1
  258. package/dist/shared/datasources/schemas.js +1 -1
  259. package/dist/shared/datasources/types.d.ts +53 -130
  260. package/dist/shared/datasources/types.d.ts.map +1 -1
  261. package/dist/shared/datasources/types.js +1 -1
  262. package/dist/shared/datasources/utils.js +3 -0
  263. package/dist/shared/datasources.d.ts +7 -4
  264. package/dist/shared/datasources.d.ts.map +1 -1
  265. package/dist/shared/datasources.js +1 -1
  266. package/dist/shared/errors.js +1 -1
  267. package/dist/shared/images.d.ts +1 -12
  268. package/dist/shared/images.d.ts.map +1 -1
  269. package/dist/shared/images.js +1 -1
  270. package/dist/shared/index.js +3 -0
  271. package/dist/shared/manifest.js +3 -0
  272. package/dist/shared/page.d.ts +155 -50
  273. package/dist/shared/page.d.ts.map +1 -1
  274. package/dist/shared/page.js +1 -1
  275. package/dist/shared/site.d.ts +322 -113
  276. package/dist/shared/site.d.ts.map +1 -1
  277. package/dist/shared/site.js +1 -1
  278. package/dist/shared/sitemap.d.ts +313 -13
  279. package/dist/shared/sitemap.d.ts.map +1 -1
  280. package/dist/shared/sitemap.js +1 -1
  281. package/dist/shared/social-icons.js +3 -0
  282. package/dist/shared/theme.d.ts +41 -4
  283. package/dist/shared/theme.d.ts.map +1 -1
  284. package/dist/shared/theme.js +1 -1
  285. package/dist/shared/utils/invariant.js +1 -1
  286. package/dist/shared/utils/llm.d.ts +19 -0
  287. package/dist/shared/utils/llm.d.ts.map +1 -0
  288. package/dist/shared/utils/llm.js +3 -0
  289. package/dist/shared/utils/schema.d.ts +6 -1
  290. package/dist/shared/utils/schema.d.ts.map +1 -1
  291. package/dist/shared/utils/schema.js +1 -1
  292. package/dist/shared/utils/tests/schema.test.d.ts +2 -0
  293. package/dist/shared/utils/tests/schema.test.d.ts.map +1 -0
  294. package/dist/shared/utils/typed-ref.d.ts +1 -6
  295. package/dist/shared/utils/typed-ref.d.ts.map +1 -1
  296. package/dist/shared/utils/typed-ref.js +1 -1
  297. package/package.json +19 -19
  298. package/src/shared/ai/schemas.ts +33 -0
  299. package/src/shared/ai/types.ts +151 -0
  300. package/src/shared/ajv.ts +123 -0
  301. package/src/shared/analytics/init.ts +14 -0
  302. package/src/shared/analytics/track.ts +21 -0
  303. package/src/shared/analytics/types.ts +13 -0
  304. package/src/shared/attributes.ts +396 -0
  305. package/src/shared/brick-manifest.ts +119 -0
  306. package/src/shared/bricks/manifests/accordion.manifest.ts +482 -0
  307. package/src/shared/bricks/manifests/all-manifests.ts +121 -0
  308. package/src/shared/bricks/manifests/box.manifest.ts +551 -0
  309. package/src/shared/bricks/manifests/button.manifest.ts +208 -0
  310. package/src/shared/bricks/manifests/card.manifest.ts +320 -0
  311. package/src/shared/bricks/manifests/carousel.manifest.ts +708 -0
  312. package/src/shared/bricks/manifests/footer.manifest.ts +509 -0
  313. package/src/shared/bricks/manifests/form.manifest.ts +226 -0
  314. package/src/shared/bricks/manifests/hero.manifest.ts +365 -0
  315. package/src/shared/bricks/manifests/html.manifest.ts +127 -0
  316. package/src/shared/bricks/manifests/icon.manifest.ts +164 -0
  317. package/src/shared/bricks/manifests/image.manifest.ts +378 -0
  318. package/src/shared/bricks/manifests/images-gallery.manifest.ts +822 -0
  319. package/src/shared/bricks/manifests/map.manifest.ts +215 -0
  320. package/src/shared/bricks/manifests/navbar.manifest.ts +361 -0
  321. package/src/shared/bricks/manifests/sidebar.manifest.ts +88 -0
  322. package/src/shared/bricks/manifests/social-links.manifest.ts +497 -0
  323. package/src/shared/bricks/manifests/spacer.manifest.ts +54 -0
  324. package/src/shared/bricks/manifests/testimonials.manifest.ts +480 -0
  325. package/src/shared/bricks/manifests/tests/header.manifest.test.ts +10 -0
  326. package/src/shared/bricks/manifests/text.manifest.ts +245 -0
  327. package/src/shared/bricks/manifests/video.manifest.ts +115 -0
  328. package/src/shared/bricks/props/align.ts +63 -0
  329. package/src/shared/bricks/props/background.ts +79 -0
  330. package/src/shared/bricks/props/boolean.ts +7 -0
  331. package/src/shared/bricks/props/border.ts +86 -0
  332. package/src/shared/bricks/props/color-preset.ts +390 -0
  333. package/src/shared/bricks/props/color.ts +40 -0
  334. package/src/shared/bricks/props/common.ts +64 -0
  335. package/src/shared/bricks/props/css-length.ts +32 -0
  336. package/src/shared/bricks/props/datarecord.ts +11 -0
  337. package/src/shared/bricks/props/datasource.ts +82 -0
  338. package/src/shared/bricks/props/date.ts +21 -0
  339. package/src/shared/bricks/props/direction.ts +21 -0
  340. package/src/shared/bricks/props/dynamic.ts +112 -0
  341. package/src/shared/bricks/props/effects.ts +71 -0
  342. package/src/shared/bricks/props/enum.ts +38 -0
  343. package/src/shared/bricks/props/file.ts +10 -0
  344. package/src/shared/bricks/props/geolocation.ts +36 -0
  345. package/src/shared/bricks/props/helpers.ts +73 -0
  346. package/src/shared/bricks/props/image.ts +96 -0
  347. package/src/shared/bricks/props/number.ts +8 -0
  348. package/src/shared/bricks/props/position.ts +11 -0
  349. package/src/shared/bricks/props/string.ts +72 -0
  350. package/src/shared/bricks/props/tags.ts +26 -0
  351. package/src/shared/bricks/props/tests/background.test.ts +90 -0
  352. package/src/shared/bricks/props/tests/border.test.ts +12 -0
  353. package/src/shared/bricks/props/tests/effects.test.ts +37 -0
  354. package/src/shared/bricks/props/tests/helpers.test.ts +98 -0
  355. package/src/shared/bricks/props/tests/image.test.ts +71 -0
  356. package/src/shared/bricks/props/tests/string.test.ts +80 -0
  357. package/src/shared/bricks/props/text.ts +107 -0
  358. package/src/shared/bricks/props/types.ts +72 -0
  359. package/src/shared/bricks.ts +1237 -0
  360. package/src/shared/context.ts +32 -0
  361. package/src/shared/datarecords/external/airtable/handler.ts +501 -0
  362. package/src/shared/datarecords/external/airtable/oauth/config.ts +11 -0
  363. package/src/shared/datarecords/external/airtable/types.ts +63 -0
  364. package/src/shared/datarecords/external/generic-webhook/handler.ts +10 -0
  365. package/src/shared/datarecords/external/generic-webhook/options.ts +13 -0
  366. package/src/shared/datarecords/external/google/oauth/config.ts +30 -0
  367. package/src/shared/datarecords/external/google/sheets/client.ts +112 -0
  368. package/src/shared/datarecords/external/google/sheets/handler.ts +253 -0
  369. package/src/shared/datarecords/external/google/sheets/types.ts +10 -0
  370. package/src/shared/datarecords/external/notion/handler.ts +469 -0
  371. package/src/shared/datarecords/external/notion/oauth/config.ts +7 -0
  372. package/src/shared/datarecords/external/notion/types.ts +28 -0
  373. package/src/shared/datarecords/types.ts +165 -0
  374. package/src/shared/datarecords.ts +5 -0
  375. package/src/shared/datasources/README.md +3 -0
  376. package/src/shared/datasources/external/facebook/posts/fetcher.ts +52 -0
  377. package/src/shared/datasources/external/facebook/posts/sample.ts +35 -0
  378. package/src/shared/datasources/external/facebook/posts/schema.ts +33 -0
  379. package/src/shared/datasources/external/facebook/posts/tests/fetcher.test.ts +73 -0
  380. package/src/shared/datasources/external/http-json/fetcher.ts +31 -0
  381. package/src/shared/datasources/external/http-json/options.ts +8 -0
  382. package/src/shared/datasources/external/http-json/schema.ts +6 -0
  383. package/src/shared/datasources/external/http-json/tests/fetcher.test.ts +70 -0
  384. package/src/shared/datasources/external/instagram/feed/fetcher.ts +33 -0
  385. package/src/shared/datasources/external/instagram/feed/sample.ts +22 -0
  386. package/src/shared/datasources/external/instagram/feed/schema.ts +23 -0
  387. package/src/shared/datasources/external/instagram/feed/tests/fetcher.test.ts +64 -0
  388. package/src/shared/datasources/external/mastodon/account/fetcher.ts +24 -0
  389. package/src/shared/datasources/external/mastodon/account/sample.ts +33 -0
  390. package/src/shared/datasources/external/mastodon/account/schema.ts +45 -0
  391. package/src/shared/datasources/external/mastodon/account/tests/fetcher.test.ts +47 -0
  392. package/src/shared/datasources/external/mastodon/options.ts +6 -0
  393. package/src/shared/datasources/external/mastodon/status/fetcher.ts +35 -0
  394. package/src/shared/datasources/external/mastodon/status/sample.array.ts +59 -0
  395. package/src/shared/datasources/external/mastodon/status/sample.single.ts +55 -0
  396. package/src/shared/datasources/external/mastodon/status/schema.ts +125 -0
  397. package/src/shared/datasources/external/mastodon/status/tests/fetcher.test.ts +74 -0
  398. package/src/shared/datasources/external/meta/oauth/config.ts +16 -0
  399. package/src/shared/datasources/external/meta/options.ts +7 -0
  400. package/src/shared/datasources/external/rss/fetcher.ts +31 -0
  401. package/src/shared/datasources/external/rss/options.ts +7 -0
  402. package/src/shared/datasources/external/rss/sample.ts +22 -0
  403. package/src/shared/datasources/external/rss/schema.ts +42 -0
  404. package/src/shared/datasources/external/threads/media/fetcher.ts +53 -0
  405. package/src/shared/datasources/external/threads/media/sample.ts +44 -0
  406. package/src/shared/datasources/external/threads/media/schema.ts +37 -0
  407. package/src/shared/datasources/external/tiktok/oauth/config.ts +17 -0
  408. package/src/shared/datasources/external/tiktok/video/fetcher.ts +39 -0
  409. package/src/shared/datasources/external/tiktok/video/options.ts +8 -0
  410. package/src/shared/datasources/external/tiktok/video/sample.ts +26 -0
  411. package/src/shared/datasources/external/tiktok/video/schema.ts +27 -0
  412. package/src/shared/datasources/external/youtube/list/fetcher.ts +37 -0
  413. package/src/shared/datasources/external/youtube/list/options.ts +11 -0
  414. package/src/shared/datasources/external/youtube/list/sample.ts +33 -0
  415. package/src/shared/datasources/external/youtube/list/schema.ts +38 -0
  416. package/src/shared/datasources/external/youtube/oauth/config.ts +15 -0
  417. package/src/shared/datasources/fetcher.ts +16 -0
  418. package/src/shared/datasources/internal/blog/schema.ts +69 -0
  419. package/src/shared/datasources/internal/changelog/schema.ts +48 -0
  420. package/src/shared/datasources/internal/contact-info/schema.ts +20 -0
  421. package/src/shared/datasources/internal/cv/schema.ts +217 -0
  422. package/src/shared/datasources/internal/faq/schema.ts +27 -0
  423. package/src/shared/datasources/internal/job-board/schema.ts +228 -0
  424. package/src/shared/datasources/internal/links/schema.ts +15 -0
  425. package/src/shared/datasources/internal/recipes/schema.ts +42 -0
  426. package/src/shared/datasources/internal/restaurant/schema.ts +225 -0
  427. package/src/shared/datasources/samples.ts +26 -0
  428. package/src/shared/datasources/schemas.ts +48 -0
  429. package/src/shared/datasources/types.ts +490 -0
  430. package/src/shared/datasources/utils.ts +17 -0
  431. package/src/shared/datasources.ts +57 -0
  432. package/src/shared/env.ts +23 -0
  433. package/src/shared/errors.ts +1 -0
  434. package/src/shared/images.ts +44 -0
  435. package/src/shared/index.ts +3 -0
  436. package/src/shared/layout-constants.ts +19 -0
  437. package/src/shared/manifest.ts +50 -0
  438. package/src/shared/oauth.ts +16 -0
  439. package/src/shared/page.ts +36 -0
  440. package/src/shared/prompt.ts +9 -0
  441. package/src/shared/responsive.ts +5 -0
  442. package/src/shared/site.ts +59 -0
  443. package/src/shared/sitemap.ts +98 -0
  444. package/src/shared/social-icons.ts +307 -0
  445. package/src/shared/tests/attributes.test.ts +31 -0
  446. package/src/shared/theme.ts +244 -0
  447. package/src/shared/themes/README.md +34 -0
  448. package/src/shared/themes/color-system.ts +146 -0
  449. package/src/shared/themes/tests/color-system.test.ts +170 -0
  450. package/src/shared/utils/canvas-data-uri.ts +2 -0
  451. package/src/shared/utils/invariant.ts +25 -0
  452. package/src/shared/utils/json-date.ts +8 -0
  453. package/src/shared/utils/llm.ts +282 -0
  454. package/src/shared/utils/merge.ts +12 -0
  455. package/src/shared/utils/object-hash.ts +7 -0
  456. package/src/shared/utils/schema.ts +359 -0
  457. package/src/shared/utils/string-enum.ts +12 -0
  458. package/src/shared/utils/tests/schema.test.ts +724 -0
  459. package/src/shared/utils/try-catch.ts +12 -0
  460. package/src/shared/utils/typed-ref.ts +53 -0
  461. package/dist/shared/bricks/props/container.d.ts +0 -11
  462. package/dist/shared/bricks/props/container.d.ts.map +0 -1
  463. package/dist/shared/bricks/props/container.js +0 -3
  464. package/dist/shared/bricks/props/gap.d.ts +0 -9
  465. package/dist/shared/bricks/props/gap.d.ts.map +0 -1
  466. package/dist/shared/bricks/props/gap.js +0 -3
  467. package/dist/shared/bricks/props/padding.d.ts +0 -5
  468. package/dist/shared/bricks/props/padding.d.ts.map +0 -1
  469. package/dist/shared/bricks/props/padding.js +0 -3
  470. package/dist/shared/bricks/props/tests/padding.d.ts +0 -2
  471. package/dist/shared/bricks/props/tests/padding.d.ts.map +0 -1
  472. package/dist/shared/chunk-2IYSJYNE.js +0 -3
  473. package/dist/shared/chunk-3EM3B4DX.js +0 -3
  474. package/dist/shared/chunk-4TH3C76A.js +0 -3
  475. package/dist/shared/chunk-5N6MBJJ4.js +0 -3
  476. package/dist/shared/chunk-6FITVVZX.js +0 -3
  477. package/dist/shared/chunk-6K3KZDFC.js +0 -3
  478. package/dist/shared/chunk-6WCGUAQN.js +0 -3
  479. package/dist/shared/chunk-7DMUDZ4H.js +0 -3
  480. package/dist/shared/chunk-ACVLF55Q.js +0 -3
  481. package/dist/shared/chunk-AQPN5SE2.js +0 -3
  482. package/dist/shared/chunk-BZGNY7LB.js +0 -3
  483. package/dist/shared/chunk-C2S243PB.js +0 -8
  484. package/dist/shared/chunk-C3VGP4CA.js +0 -3
  485. package/dist/shared/chunk-CT3EI7YN.js +0 -3
  486. package/dist/shared/chunk-DQXDGV67.js +0 -3
  487. package/dist/shared/chunk-E22E4XWE.js +0 -3
  488. package/dist/shared/chunk-ETYYRWLK.js +0 -3
  489. package/dist/shared/chunk-EYPREFMH.js +0 -3
  490. package/dist/shared/chunk-FKNNTHWX.js +0 -5
  491. package/dist/shared/chunk-HHO3ONTQ.js +0 -3
  492. package/dist/shared/chunk-I46VBMLF.js +0 -3
  493. package/dist/shared/chunk-IIFTGWFZ.js +0 -3
  494. package/dist/shared/chunk-JS4K5JRM.js +0 -5
  495. package/dist/shared/chunk-KHFNN4P3.js +0 -3
  496. package/dist/shared/chunk-LFQZRGHS.js +0 -3
  497. package/dist/shared/chunk-LGP6GWIY.js +0 -3
  498. package/dist/shared/chunk-NLEWXPVM.js +0 -3
  499. package/dist/shared/chunk-NNI225RG.js +0 -3
  500. package/dist/shared/chunk-QISTDGPP.js +0 -3
  501. package/dist/shared/chunk-QSZWDE3D.js +0 -3
  502. package/dist/shared/chunk-RGLVKILY.js +0 -3
  503. package/dist/shared/chunk-SLRU4CT6.js +0 -4
  504. package/dist/shared/chunk-T3LIA4YB.js +0 -3
  505. package/dist/shared/chunk-T4LMBG2G.js +0 -3
  506. package/dist/shared/chunk-TATG6SFZ.js +0 -3
  507. package/dist/shared/chunk-TF3JVVRU.js +0 -3
  508. package/dist/shared/chunk-TTTXV7TJ.js +0 -6
  509. package/dist/shared/chunk-TWBY2GOR.js +0 -3
  510. package/dist/shared/chunk-UHF6IEKV.js +0 -3
  511. package/dist/shared/chunk-UMHXXXVP.js +0 -3
  512. package/dist/shared/chunk-VGRYSAXA.js +0 -3
  513. package/dist/shared/chunk-VPFCY4DH.js +0 -3
  514. package/dist/shared/chunk-VTBI7WX3.js +0 -3
  515. package/dist/shared/chunk-VZPXXFVX.js +0 -3
  516. package/dist/shared/chunk-WU6Q4WYD.js +0 -3
  517. package/dist/shared/chunk-X43MB5WD.js +0 -3
  518. package/dist/shared/chunk-YBGPPF7T.js +0 -3
  519. package/dist/shared/chunk-ZQGNYK5I.js +0 -8
  520. package/dist/shared/chunk-ZTDUXSWH.js +0 -3
  521. package/dist/shared/datarecords/external/airtable/elements.d.ts +0 -21
  522. package/dist/shared/datarecords/external/airtable/elements.d.ts.map +0 -1
  523. package/dist/shared/datarecords/external/airtable/options.d.ts +0 -10
  524. package/dist/shared/datarecords/external/airtable/options.d.ts.map +0 -1
  525. package/dist/shared/datarecords/external/google/sheets/options.d.ts.map +0 -1
  526. package/dist/shared/datarecords/external/notion/options.d.ts.map +0 -1
  527. package/dist/shared/utils/schema-resolver.d.ts +0 -3
  528. package/dist/shared/utils/schema-resolver.d.ts.map +0 -1
  529. package/dist/shared/utils/schema-resolver.js +0 -3
@@ -0,0 +1,32 @@
1
+ import type { ImageSearchResultsType } from "./images";
2
+ import type { VersionedPage } from "./page";
3
+ import type { Site } from "./site";
4
+
5
+ export type GenerationState = {
6
+ isReady: boolean;
7
+ isSetup: boolean;
8
+ hasSitemap: boolean;
9
+ hasThemesGenerated: boolean;
10
+ };
11
+
12
+ export type CallContextProps = {
13
+ /**
14
+ * The site object
15
+ */
16
+ site: Site;
17
+ /**
18
+ * Current page. Undefined if flow is "setup" and no page has been created yet.
19
+ */
20
+ page: VersionedPage;
21
+
22
+ /**
23
+ * The current generation state of the site. Only used when flow is "setup".
24
+ */
25
+ generationState?: GenerationState;
26
+ /**
27
+ * The user language guessed from the sitePrompt, if available.
28
+ */
29
+ userLanguage?: string;
30
+
31
+ assets: ImageSearchResultsType;
32
+ };
@@ -0,0 +1,501 @@
1
+ import type { TObject, TProperties } from "@sinclair/typebox";
2
+ import type { AirtableBases, AirtableFieldType, AirtableOptions } from "./types";
3
+
4
+ const sleep = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));
5
+
6
+ function getClient(token: string) {
7
+ if (!token) {
8
+ throw new Error("Missing Airtable API token");
9
+ }
10
+
11
+ return {
12
+ async callApi<R, P extends Record<string, unknown> = Record<string, unknown>>(
13
+ path: string,
14
+ method: "GET" | "POST" | "DELETE" | "PUT" | "PATCH" = "GET",
15
+ body: P | null = null,
16
+ ) {
17
+ const url = `https://api.airtable.com/${path}`;
18
+ const maxRetries = 5;
19
+ const retryDelay = 30000; // 30 seconds
20
+
21
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
22
+ try {
23
+ const res = await fetch(url, {
24
+ method,
25
+ headers: {
26
+ Authorization: `Bearer ${token}`,
27
+ "Content-Type": "application/json",
28
+ },
29
+ body: body ? JSON.stringify(body) : undefined,
30
+ });
31
+
32
+ // if 429 is rate limit exceeded
33
+ if (res.status === 429 && attempt < maxRetries) {
34
+ console.warn(
35
+ `Airtable rate limit hit (429) on attempt ${attempt}/${maxRetries}. Waiting ${retryDelay / 1000}s before retry...`,
36
+ );
37
+ await sleep(retryDelay);
38
+ continue; // Retry
39
+ }
40
+
41
+ const data = await res.json();
42
+
43
+ // for any other response (success or definitive error)
44
+ return {
45
+ status: res.status,
46
+ success: res.ok,
47
+ data: data as R,
48
+ };
49
+ } catch (error) {
50
+ // In case of network error, we also retry except on the last attempt
51
+ if (attempt < maxRetries) {
52
+ console.warn(
53
+ `Network error on attempt ${attempt}/${maxRetries}. Waiting ${retryDelay / 1000}s before retry...`,
54
+ error,
55
+ );
56
+ await sleep(retryDelay);
57
+ continue;
58
+ }
59
+ // On the last attempt, we rethrow the error
60
+ console.error(`Error on attempt ${attempt}/${maxRetries}:`, error);
61
+ throw error;
62
+ }
63
+ }
64
+
65
+ // If we reach here, it means we exhausted all attempts with 429
66
+ throw new Error(`Airtable API rate limit exceeded after ${maxRetries} attempts`);
67
+ },
68
+ };
69
+ }
70
+
71
+ /**
72
+ * Convert a FormData value based on Airtable field type
73
+ */
74
+ function convertValueForAirtableField(value: string, fieldType: AirtableFieldType): unknown {
75
+ switch (fieldType) {
76
+ case "checkbox":
77
+ return value === "true" || value === "1" || value.toLowerCase() === "on";
78
+
79
+ case "number": {
80
+ const numValue = Number(value);
81
+ return Number.isNaN(numValue) ? value : numValue;
82
+ }
83
+
84
+ case "date":
85
+ case "dateTime":
86
+ // Airtable expects ISO format strings
87
+ return value;
88
+
89
+ case "email":
90
+ case "url":
91
+ case "singleLineText":
92
+ case "multilineText":
93
+ return value;
94
+
95
+ case "singleSelect":
96
+ return value;
97
+
98
+ case "multipleSelects": {
99
+ // Handle comma-separated values or JSON array strings
100
+ if (value.startsWith("[") && value.endsWith("]")) {
101
+ try {
102
+ return JSON.parse(value);
103
+ } catch {
104
+ return [value];
105
+ }
106
+ }
107
+ if (value.includes(",")) {
108
+ return value
109
+ .split(",")
110
+ .map((v) => v.trim())
111
+ .filter((v) => v.length > 0);
112
+ }
113
+ return [value];
114
+ }
115
+
116
+ default:
117
+ console.warn(`Unknown Airtable field type: ${fieldType}, treating as text`);
118
+ return value;
119
+ }
120
+ }
121
+
122
+ /**
123
+ * Fallback conversion based on value patterns (when field type is unknown)
124
+ */
125
+ function convertValueByPattern(value: string): unknown {
126
+ // Handle boolean-like values
127
+ if (value === "true" || value === "false") {
128
+ return value === "true";
129
+ }
130
+
131
+ // Handle number-like values
132
+ if (/^\d+\.?\d*$/.test(value)) {
133
+ const numValue = Number(value);
134
+ if (!Number.isNaN(numValue)) {
135
+ return numValue;
136
+ }
137
+ }
138
+
139
+ // Handle date formats
140
+ if (/^\d{4}-\d{2}-\d{2}$/.test(value) || /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(value)) {
141
+ return value;
142
+ }
143
+
144
+ // Handle comma-separated values (potential multiple select)
145
+ if (value.includes(",")) {
146
+ const values = value
147
+ .split(",")
148
+ .map((v) => v.trim())
149
+ .filter((v) => v.length > 0);
150
+ if (values.length > 1) {
151
+ return values;
152
+ }
153
+ }
154
+
155
+ // Default to string
156
+ return value;
157
+ }
158
+
159
+ export async function saveRecord({
160
+ formData,
161
+ options,
162
+ properties,
163
+ accessToken,
164
+ }: {
165
+ formData: FormData;
166
+ options: AirtableOptions;
167
+ properties: TProperties;
168
+ accessToken: string;
169
+ }): Promise<{ id: string } | null> {
170
+ try {
171
+ const client = getClient(accessToken);
172
+ const records: Record<string, unknown> = {};
173
+
174
+ for (const [key, value] of formData.entries()) {
175
+ // Skip empty values
176
+ if (value === null || value === undefined || value === "") continue;
177
+
178
+ // Skip Files for now as they need special handling
179
+ if (value instanceof File) {
180
+ console.warn(`File upload not yet supported for field: ${key}`);
181
+ continue;
182
+ }
183
+
184
+ // Find the field definition in options.fields
185
+ const fieldDef = options.fields?.find((field) => field.name === key);
186
+
187
+ if (fieldDef) {
188
+ // Use field type information for precise conversion
189
+ records[key] = convertValueForAirtableField(value, fieldDef.type as AirtableFieldType);
190
+ } else {
191
+ // Fallback to pattern-based conversion if field definition not found
192
+ records[key] = convertValueByPattern(value);
193
+ }
194
+ }
195
+ const response = await client.callApi<{
196
+ records: Array<{ id: string; fields: Record<string, unknown> }>;
197
+ }>(`v0/${options.baseId}/${options.tableId}`, "POST", {
198
+ records: [
199
+ {
200
+ fields: records,
201
+ },
202
+ ],
203
+ });
204
+
205
+ if (!response.success) {
206
+ throw new Error(
207
+ `Failed to push data to Airtable: ${response.status} - ${JSON.stringify(response.data)}`,
208
+ );
209
+ }
210
+
211
+ return response.data.records[0] ? { id: response.data.records[0].id } : null;
212
+ } catch (error) {
213
+ console.error("Error pushing data to Airtable:", error);
214
+ }
215
+
216
+ return null;
217
+ }
218
+
219
+ /**
220
+ * Build Airtable table creation data from schema
221
+ */
222
+ function buildAirtableTableData(properties: TProperties) {
223
+ // Sort fields by metadata.order (ascending), then fields without order
224
+ const sortedEntries = Object.entries(properties).sort(([, fieldA], [, fieldB]) => {
225
+ const orderA = fieldA.metadata?.order;
226
+ const orderB = fieldB.metadata?.order;
227
+
228
+ // If both have order, sort by order value
229
+ if (orderA !== undefined && orderB !== undefined) {
230
+ return orderA - orderB;
231
+ }
232
+
233
+ // Fields with order come first
234
+ if (orderA !== undefined && orderB === undefined) {
235
+ return -1;
236
+ }
237
+
238
+ if (orderA === undefined && orderB !== undefined) {
239
+ return 1;
240
+ }
241
+
242
+ // Both without order, maintain original order
243
+ return 0;
244
+ });
245
+
246
+ const fields = sortedEntries.map(([fieldName, field]) => {
247
+ // Seulement 3 cas : string, number, boolean
248
+ if (field.type === "string") {
249
+ if (field.format === "email") {
250
+ return {
251
+ name: fieldName,
252
+ type: "email",
253
+ };
254
+ }
255
+ if (field.format === "uri") {
256
+ return {
257
+ name: fieldName,
258
+ type: "url",
259
+ };
260
+ }
261
+ if (field.format === "date") {
262
+ return {
263
+ name: fieldName,
264
+ type: "date",
265
+ options: {
266
+ dateFormat: {
267
+ name: "local",
268
+ },
269
+ },
270
+ };
271
+ }
272
+ if (field.format === "date-time") {
273
+ return {
274
+ name: fieldName,
275
+ type: "dateTime",
276
+ options: {
277
+ dateFormat: {
278
+ name: "local",
279
+ },
280
+ timeFormat: {
281
+ name: "24hour",
282
+ },
283
+ timeZone: "client",
284
+ },
285
+ };
286
+ }
287
+ if (field.metadata?.["ui:multiline"]) {
288
+ return {
289
+ name: fieldName,
290
+ type: "multilineText",
291
+ };
292
+ }
293
+ if (field.enum) {
294
+ if (field.metadata?.["ui:widget"] === "checkbox") {
295
+ return {
296
+ name: fieldName,
297
+ type: "multipleSelects",
298
+ options: {
299
+ choices: (field.enum as Array<string>).map((value) => ({
300
+ name: value,
301
+ })),
302
+ },
303
+ };
304
+ }
305
+ return {
306
+ name: fieldName,
307
+ type: "singleSelect",
308
+ options: {
309
+ choices: (field.enum as Array<string>).map((value) => ({
310
+ name: value,
311
+ })),
312
+ },
313
+ };
314
+ }
315
+ return {
316
+ name: fieldName,
317
+ type: "singleLineText",
318
+ };
319
+ }
320
+ if (field.type === "boolean") {
321
+ return {
322
+ name: fieldName,
323
+ type: "checkbox",
324
+ options: {
325
+ icon: "check",
326
+ color: "grayBright",
327
+ },
328
+ };
329
+ }
330
+ if (field.type === "number") {
331
+ return {
332
+ name: fieldName,
333
+ type: "number",
334
+ options: {
335
+ precision: 8,
336
+ },
337
+ };
338
+ }
339
+ });
340
+
341
+ return fields;
342
+ }
343
+
344
+ export async function createTable({
345
+ name,
346
+ schema,
347
+ baseId,
348
+ accessToken,
349
+ }: {
350
+ name: string;
351
+ schema: TObject;
352
+ baseId: string;
353
+ accessToken: string;
354
+ }): Promise<AirtableOptions | null> {
355
+ const fields = buildAirtableTableData(schema.properties);
356
+ const tableCreationData = {
357
+ name,
358
+ description: `Table created by Upstart for ${name}`,
359
+ fields: fields,
360
+ };
361
+ // console.dir(data);
362
+ try {
363
+ const client = getClient(accessToken);
364
+ const response = await client.callApi<{
365
+ id: string;
366
+ name: string;
367
+ description: string;
368
+ primaryFieldId: string;
369
+ fields: Array<{
370
+ id: string;
371
+ name: string;
372
+ type: string;
373
+ }>;
374
+ }>(`v0/meta/bases/${baseId}/tables`, "POST", tableCreationData);
375
+
376
+ if (!response.success) {
377
+ console.error(
378
+ "Error while creating Airtable table with:",
379
+ JSON.stringify(tableCreationData, null, 2),
380
+ "from schema: ",
381
+ JSON.stringify(schema, null, 2),
382
+ );
383
+ throw new Error(
384
+ `Failed to create Airtable table: ${response.status} - ${JSON.stringify(response.data)}`,
385
+ );
386
+ }
387
+
388
+ return {
389
+ tableId: response.data.id,
390
+ fields: response.data.fields,
391
+ tableName: response.data.name,
392
+ externalUrl: `https://airtable.com/${baseId}/${response.data.id}`,
393
+ } as AirtableOptions;
394
+ } catch (error) {
395
+ if (error instanceof Error) {
396
+ console.error(error.message);
397
+ } else {
398
+ console.error("Unknown error occurred while creating Airtable table", error);
399
+ }
400
+ throw error;
401
+ }
402
+ }
403
+
404
+ export async function updateTable({
405
+ baseId,
406
+ tableId,
407
+ newName,
408
+ newProperties,
409
+ accessToken,
410
+ }: {
411
+ baseId: string;
412
+ tableId: string;
413
+ newName: string;
414
+ newProperties?: TProperties;
415
+ accessToken: string;
416
+ }): Promise<AirtableOptions | null> {
417
+ const client = getClient(accessToken);
418
+ if (newProperties) {
419
+ try {
420
+ const fields = buildAirtableTableData(newProperties);
421
+ for (const field of fields) {
422
+ const response = await client.callApi<{
423
+ id: string;
424
+ name: string;
425
+ description: string;
426
+ type: string;
427
+ }>(`v0/meta/bases/${baseId}/tables/${tableId}/fields`, "POST", field);
428
+ if (!response.success) {
429
+ console.error("Error while adding field to Airtable table with:", JSON.stringify(field, null, 2));
430
+ throw new Error(
431
+ `Failed to update Airtable table: ${response.status} - ${JSON.stringify(response.data)}`,
432
+ );
433
+ }
434
+ }
435
+ } catch (error) {
436
+ if (error instanceof Error) {
437
+ console.error(error.message);
438
+ } else {
439
+ console.error("Unknown error occurred while updating Airtable table", error);
440
+ }
441
+ throw error;
442
+ }
443
+ }
444
+
445
+ try {
446
+ const tableUpdateData = {
447
+ name: newName,
448
+ description: `Table updated by Upstart for ${newName}`,
449
+ };
450
+ const response = await client.callApi<{
451
+ id: string;
452
+ name: string;
453
+ description: string;
454
+ primaryFieldId: string;
455
+ fields: Array<{
456
+ id: string;
457
+ name: string;
458
+ type: string;
459
+ }>;
460
+ }>(`v0/meta/bases/${baseId}/tables/${tableId}`, "PATCH", tableUpdateData);
461
+
462
+ if (!response.success) {
463
+ console.error("Error while updating Airtable table with:", JSON.stringify(tableUpdateData, null, 2));
464
+ throw new Error(
465
+ `Failed to update Airtable table: ${response.status} - ${JSON.stringify(response.data)}`,
466
+ );
467
+ }
468
+
469
+ return {
470
+ tableId: response.data.id,
471
+ fields: response.data.fields,
472
+ tableName: response.data.name,
473
+ externalUrl: `https://airtable.com/${baseId}/${response.data.id}`,
474
+ } as AirtableOptions;
475
+ } catch (error) {
476
+ if (error instanceof Error) {
477
+ console.error(error.message);
478
+ } else {
479
+ console.error("Unknown error occurred while creating Airtable table", error);
480
+ }
481
+ throw error;
482
+ }
483
+ }
484
+
485
+ export async function fetchAirtableBases(accessToken: string): Promise<AirtableBases> {
486
+ try {
487
+ const client = getClient(accessToken);
488
+ const response = await client.callApi<{
489
+ bases: AirtableBases;
490
+ }>("v0/meta/bases");
491
+
492
+ if (response.success) {
493
+ return response.data.bases;
494
+ } else {
495
+ throw new Error(`Failed to fetch bases: ${response.status}`);
496
+ }
497
+ } catch (error) {
498
+ console.error("Error fetching Airtable bases:", error);
499
+ return [];
500
+ }
501
+ }
@@ -0,0 +1,11 @@
1
+ import { Type, type Static } from "@sinclair/typebox";
2
+
3
+ export const airtableOAuthTokenSchema = Type.Object({
4
+ scope: Type.String(),
5
+ token_type: Type.String(),
6
+ expires_in: Type.Number(),
7
+ access_token: Type.String(),
8
+ refresh_token: Type.String(),
9
+ refresh_expires_in: Type.Number(),
10
+ });
11
+ export type AirtableOAuthToken = Static<typeof airtableOAuthTokenSchema>;
@@ -0,0 +1,63 @@
1
+ import { Type, type Static } from "@sinclair/typebox";
2
+
3
+ export const airtableFields = Type.Array(
4
+ Type.Object({
5
+ id: Type.String(),
6
+ name: Type.String(),
7
+ type: Type.String(),
8
+ }),
9
+ );
10
+ export type AirtableFields = Static<typeof airtableFields>;
11
+
12
+ const createAirtableTableResponseSchema = Type.Object({
13
+ id: Type.String(),
14
+ name: Type.String(),
15
+ description: Type.String(),
16
+ primaryFieldId: Type.String(),
17
+ fields: airtableFields,
18
+ });
19
+
20
+ export type CreateAirtableTableResponse = Static<typeof createAirtableTableResponseSchema>;
21
+
22
+ export const airtableOptions = Type.Object({
23
+ externalUrl: Type.Optional(Type.String()),
24
+ baseId: Type.String({
25
+ pattern: "^app[A-Za-z0-9]+$",
26
+ description: 'Airtable Base ID starting with "app"',
27
+ }),
28
+ baseName: Type.Optional(
29
+ Type.String({
30
+ description: "Airtable Base Name",
31
+ }),
32
+ ),
33
+ tableId: Type.String({
34
+ pattern: "^tbl[A-Za-z0-9]+$",
35
+ description: 'Airtable Table ID starting with "tbl"',
36
+ }),
37
+ tableName: Type.Optional(
38
+ Type.String({
39
+ description: "Table name as shown in Airtable interface",
40
+ }),
41
+ ),
42
+ fields: Type.Optional(airtableFields),
43
+ });
44
+ export type AirtableOptions = Static<typeof airtableOptions>;
45
+
46
+ export type AirtableBases = {
47
+ id: string;
48
+ name: string;
49
+ }[];
50
+
51
+ export const AirtableFieldTypes = Type.Union([
52
+ Type.Literal("number"),
53
+ Type.Literal("checkbox"),
54
+ Type.Literal("date"),
55
+ Type.Literal("dateTime"),
56
+ Type.Literal("email"),
57
+ Type.Literal("url"),
58
+ Type.Literal("singleLineText"),
59
+ Type.Literal("multilineText"),
60
+ Type.Literal("singleSelect"),
61
+ Type.Literal("multipleSelects"),
62
+ ]);
63
+ export type AirtableFieldType = Static<typeof AirtableFieldTypes>;
@@ -0,0 +1,10 @@
1
+ import type { GenericWebhookOptions } from "./options";
2
+
3
+ export default async function genericWebhookHandler(formData: FormData, options: GenericWebhookOptions) {
4
+ const result = await fetch(options.url, {
5
+ method: "POST",
6
+ body: JSON.stringify(formData),
7
+ headers: options.headers,
8
+ });
9
+ return result.ok;
10
+ }
@@ -0,0 +1,13 @@
1
+ import { Type, type Static } from "@sinclair/typebox";
2
+
3
+ export const genericWebhookOptions = Type.Object({
4
+ url: Type.String({ format: "uri", title: "Webhook URL" }),
5
+ headers: Type.Optional(
6
+ Type.Record(Type.String(), Type.String(), {
7
+ title: "Headers",
8
+ description: "Additional headers to include in the webhook request",
9
+ }),
10
+ ),
11
+ });
12
+
13
+ export type GenericWebhookOptions = Static<typeof genericWebhookOptions>;
@@ -0,0 +1,30 @@
1
+ import { Type, type Static } from "@sinclair/typebox";
2
+
3
+ const googleOAuthTokenSchema = Type.Object({
4
+ access_token: Type.String(),
5
+ token_type: Type.String(), // Usually "Bearer"
6
+ expires_in: Type.Number(), // Seconds until token expires, typically 3600 (1 hour)
7
+ refresh_token: Type.Optional(Type.String()), // Only present in first OAuth exchange
8
+ scope: Type.String(), // Space-separated list of granted scopes
9
+ id_token: Type.Optional(Type.String()), // JWT token containing user info, if requested
10
+ });
11
+
12
+ export type GoogleOAuthToken = Static<typeof googleOAuthTokenSchema>;
13
+
14
+ // You might also want to define the decoded id_token structure:
15
+ const googleIdTokenSchema = Type.Object({
16
+ iss: Type.String(), // Issuer (usually 'https://accounts.google.com')
17
+ sub: Type.String(), // Unique Google ID for the user
18
+ aud: Type.String(), // Your client ID
19
+ iat: Type.Number(), // Issued at (timestamp)
20
+ exp: Type.Number(), // Expiration time (timestamp)
21
+ email: Type.Optional(Type.String()),
22
+ email_verified: Type.Optional(Type.Boolean()),
23
+ name: Type.Optional(Type.String()),
24
+ picture: Type.Optional(Type.String()),
25
+ given_name: Type.Optional(Type.String()),
26
+ family_name: Type.Optional(Type.String()),
27
+ locale: Type.Optional(Type.String()),
28
+ });
29
+
30
+ export type GoogleIdToken = Static<typeof googleIdTokenSchema>;