@apteva/integrations 0.3.61 โ†’ 0.15.3

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 (434) hide show
  1. package/dist/aws-sigv4.d.ts +32 -0
  2. package/dist/aws-sigv4.d.ts.map +1 -0
  3. package/dist/aws-sigv4.js +126 -0
  4. package/dist/aws-sigv4.js.map +1 -0
  5. package/dist/explorer/main.js +21617 -0
  6. package/dist/explorer/main.js.map +90 -0
  7. package/dist/explorer/style.css +2 -0
  8. package/dist/http-executor.d.ts.map +1 -1
  9. package/dist/http-executor.js +145 -12
  10. package/dist/http-executor.js.map +1 -1
  11. package/dist/index.d.ts +1 -1
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js.map +1 -1
  14. package/dist/mcp-generator.d.ts +7 -2
  15. package/dist/mcp-generator.d.ts.map +1 -1
  16. package/dist/mcp-generator.js +46 -5
  17. package/dist/mcp-generator.js.map +1 -1
  18. package/dist/oauth.js +1 -1
  19. package/dist/oauth.js.map +1 -1
  20. package/dist/types.d.ts +251 -3
  21. package/dist/types.d.ts.map +1 -1
  22. package/dist/ui/github/ActivityFeed.d.ts +24 -0
  23. package/dist/ui/github/ActivityFeed.d.ts.map +1 -0
  24. package/dist/ui/github/ActivityFeed.js +106 -0
  25. package/dist/ui/github/ActivityFeed.js.map +1 -0
  26. package/dist/ui/github/ActivityFeed.mjs +3 -0
  27. package/dist/ui/github/ActivityFeed.mjs.map +29 -0
  28. package/dist/ui/github/CommitCard.d.ts +24 -0
  29. package/dist/ui/github/CommitCard.d.ts.map +1 -0
  30. package/dist/ui/github/CommitCard.js +102 -0
  31. package/dist/ui/github/CommitCard.js.map +1 -0
  32. package/dist/ui/github/CommitCard.mjs +5 -0
  33. package/dist/ui/github/CommitCard.mjs.map +11 -0
  34. package/dist/ui/github/IssueCard.d.ts +33 -0
  35. package/dist/ui/github/IssueCard.d.ts.map +1 -0
  36. package/dist/ui/github/IssueCard.js +131 -0
  37. package/dist/ui/github/IssueCard.js.map +1 -0
  38. package/dist/ui/github/IssueCard.mjs +3 -0
  39. package/dist/ui/github/IssueCard.mjs.map +21 -0
  40. package/dist/ui/github/PullRequestCard.d.ts +36 -0
  41. package/dist/ui/github/PullRequestCard.d.ts.map +1 -0
  42. package/dist/ui/github/PullRequestCard.js +158 -0
  43. package/dist/ui/github/PullRequestCard.js.map +1 -0
  44. package/dist/ui/github/PullRequestCard.mjs +3 -0
  45. package/dist/ui/github/PullRequestCard.mjs.map +22 -0
  46. package/dist/ui/github/WorkflowRunCard.d.ts +30 -0
  47. package/dist/ui/github/WorkflowRunCard.d.ts.map +1 -0
  48. package/dist/ui/github/WorkflowRunCard.js +124 -0
  49. package/dist/ui/github/WorkflowRunCard.js.map +1 -0
  50. package/dist/ui/github/WorkflowRunCard.mjs +3 -0
  51. package/dist/ui/github/WorkflowRunCard.mjs.map +11 -0
  52. package/dist/ui/github/lib/github.d.ts +43 -0
  53. package/dist/ui/github/lib/github.d.ts.map +1 -0
  54. package/dist/ui/github/lib/github.js +151 -0
  55. package/dist/ui/github/lib/github.js.map +1 -0
  56. package/dist/ui/hubspot/ActivityFeed.d.ts +22 -0
  57. package/dist/ui/hubspot/ActivityFeed.d.ts.map +1 -0
  58. package/dist/ui/hubspot/ActivityFeed.js +52 -0
  59. package/dist/ui/hubspot/ActivityFeed.js.map +1 -0
  60. package/dist/ui/hubspot/ActivityFeed.mjs +3 -0
  61. package/dist/ui/hubspot/ActivityFeed.mjs.map +26 -0
  62. package/dist/ui/hubspot/CompanyCard.d.ts +22 -0
  63. package/dist/ui/hubspot/CompanyCard.d.ts.map +1 -0
  64. package/dist/ui/hubspot/CompanyCard.js +63 -0
  65. package/dist/ui/hubspot/CompanyCard.js.map +1 -0
  66. package/dist/ui/hubspot/CompanyCard.mjs +3 -0
  67. package/dist/ui/hubspot/CompanyCard.mjs.map +11 -0
  68. package/dist/ui/hubspot/ContactCard.d.ts +22 -0
  69. package/dist/ui/hubspot/ContactCard.d.ts.map +1 -0
  70. package/dist/ui/hubspot/ContactCard.js +62 -0
  71. package/dist/ui/hubspot/ContactCard.js.map +1 -0
  72. package/dist/ui/hubspot/ContactCard.mjs +3 -0
  73. package/dist/ui/hubspot/ContactCard.mjs.map +11 -0
  74. package/dist/ui/hubspot/ContactList.d.ts +21 -0
  75. package/dist/ui/hubspot/ContactList.d.ts.map +1 -0
  76. package/dist/ui/hubspot/ContactList.js +31 -0
  77. package/dist/ui/hubspot/ContactList.js.map +1 -0
  78. package/dist/ui/hubspot/ContactList.mjs +3 -0
  79. package/dist/ui/hubspot/ContactList.mjs.map +11 -0
  80. package/dist/ui/hubspot/DealCard.d.ts +23 -0
  81. package/dist/ui/hubspot/DealCard.d.ts.map +1 -0
  82. package/dist/ui/hubspot/DealCard.js +63 -0
  83. package/dist/ui/hubspot/DealCard.js.map +1 -0
  84. package/dist/ui/hubspot/DealCard.mjs +3 -0
  85. package/dist/ui/hubspot/DealCard.mjs.map +11 -0
  86. package/dist/ui/hubspot/DealList.d.ts +24 -0
  87. package/dist/ui/hubspot/DealList.d.ts.map +1 -0
  88. package/dist/ui/hubspot/DealList.js +35 -0
  89. package/dist/ui/hubspot/DealList.js.map +1 -0
  90. package/dist/ui/hubspot/DealList.mjs +3 -0
  91. package/dist/ui/hubspot/DealList.mjs.map +11 -0
  92. package/dist/ui/hubspot/EmailCard.d.ts +25 -0
  93. package/dist/ui/hubspot/EmailCard.d.ts.map +1 -0
  94. package/dist/ui/hubspot/EmailCard.js +62 -0
  95. package/dist/ui/hubspot/EmailCard.js.map +1 -0
  96. package/dist/ui/hubspot/EmailCard.mjs +5 -0
  97. package/dist/ui/hubspot/EmailCard.mjs.map +11 -0
  98. package/dist/ui/hubspot/InboxStrip.d.ts +23 -0
  99. package/dist/ui/hubspot/InboxStrip.d.ts.map +1 -0
  100. package/dist/ui/hubspot/InboxStrip.js +36 -0
  101. package/dist/ui/hubspot/InboxStrip.js.map +1 -0
  102. package/dist/ui/hubspot/InboxStrip.mjs +3 -0
  103. package/dist/ui/hubspot/InboxStrip.mjs.map +11 -0
  104. package/dist/ui/hubspot/PipelineStrip.d.ts +22 -0
  105. package/dist/ui/hubspot/PipelineStrip.d.ts.map +1 -0
  106. package/dist/ui/hubspot/PipelineStrip.js +54 -0
  107. package/dist/ui/hubspot/PipelineStrip.js.map +1 -0
  108. package/dist/ui/hubspot/PipelineStrip.mjs +3 -0
  109. package/dist/ui/hubspot/PipelineStrip.mjs.map +11 -0
  110. package/dist/ui/hubspot/TicketCard.d.ts +25 -0
  111. package/dist/ui/hubspot/TicketCard.d.ts.map +1 -0
  112. package/dist/ui/hubspot/TicketCard.js +53 -0
  113. package/dist/ui/hubspot/TicketCard.js.map +1 -0
  114. package/dist/ui/hubspot/TicketCard.mjs +3 -0
  115. package/dist/ui/hubspot/TicketCard.mjs.map +21 -0
  116. package/dist/ui/hubspot/TicketList.d.ts +21 -0
  117. package/dist/ui/hubspot/TicketList.d.ts.map +1 -0
  118. package/dist/ui/hubspot/TicketList.js +33 -0
  119. package/dist/ui/hubspot/TicketList.js.map +1 -0
  120. package/dist/ui/hubspot/TicketList.mjs +3 -0
  121. package/dist/ui/hubspot/TicketList.mjs.map +11 -0
  122. package/dist/ui/hubspot/lib/hubspot.d.ts +24 -0
  123. package/dist/ui/hubspot/lib/hubspot.d.ts.map +1 -0
  124. package/dist/ui/hubspot/lib/hubspot.js +176 -0
  125. package/dist/ui/hubspot/lib/hubspot.js.map +1 -0
  126. package/dist/ui/notion/DatabaseCard.d.ts +24 -0
  127. package/dist/ui/notion/DatabaseCard.d.ts.map +1 -0
  128. package/dist/ui/notion/DatabaseCard.js +86 -0
  129. package/dist/ui/notion/DatabaseCard.js.map +1 -0
  130. package/dist/ui/notion/DatabaseCard.mjs +3 -0
  131. package/dist/ui/notion/DatabaseCard.mjs.map +11 -0
  132. package/dist/ui/notion/DatabaseRowList.d.ts +36 -0
  133. package/dist/ui/notion/DatabaseRowList.d.ts.map +1 -0
  134. package/dist/ui/notion/DatabaseRowList.js +87 -0
  135. package/dist/ui/notion/DatabaseRowList.js.map +1 -0
  136. package/dist/ui/notion/DatabaseRowList.mjs +3 -0
  137. package/dist/ui/notion/DatabaseRowList.mjs.map +11 -0
  138. package/dist/ui/notion/PageCard.d.ts +27 -0
  139. package/dist/ui/notion/PageCard.d.ts.map +1 -0
  140. package/dist/ui/notion/PageCard.js +80 -0
  141. package/dist/ui/notion/PageCard.js.map +1 -0
  142. package/dist/ui/notion/PageCard.mjs +3 -0
  143. package/dist/ui/notion/PageCard.mjs.map +11 -0
  144. package/dist/ui/notion/PageList.d.ts +24 -0
  145. package/dist/ui/notion/PageList.d.ts.map +1 -0
  146. package/dist/ui/notion/PageList.js +51 -0
  147. package/dist/ui/notion/PageList.js.map +1 -0
  148. package/dist/ui/notion/PageList.mjs +3 -0
  149. package/dist/ui/notion/PageList.mjs.map +11 -0
  150. package/dist/ui/notion/lib/notion.d.ts +35 -0
  151. package/dist/ui/notion/lib/notion.d.ts.map +1 -0
  152. package/dist/ui/notion/lib/notion.js +119 -0
  153. package/dist/ui/notion/lib/notion.js.map +1 -0
  154. package/dist/xml-to-json.d.ts +20 -0
  155. package/dist/xml-to-json.d.ts.map +1 -0
  156. package/dist/xml-to-json.js +256 -0
  157. package/dist/xml-to-json.js.map +1 -0
  158. package/package.json +12 -1
  159. package/src/apps/adroll.json +254 -0
  160. package/src/apps/ahrefs.json +156 -0
  161. package/src/apps/airtable.json +4 -13
  162. package/src/apps/algolia.json +115 -0
  163. package/src/apps/alibaba-cloud.json +211 -0
  164. package/src/apps/aliexpress.json +369 -0
  165. package/src/apps/alpaca-market-data.json +699 -0
  166. package/src/apps/alpaca-trading.json +214 -989
  167. package/src/apps/amazon-ads.json +249 -0
  168. package/src/apps/amazon-associates.json +102 -0
  169. package/src/apps/amplitude.json +86 -0
  170. package/src/apps/anchor-browser.json +173 -0
  171. package/src/apps/anthropic-api.json +9 -4
  172. package/src/apps/api-sports.json +180 -0
  173. package/src/apps/apple-search-ads.json +266 -0
  174. package/src/apps/auth0.json +126 -0
  175. package/src/apps/awin.json +111 -0
  176. package/src/apps/aws-codebuild.json +139 -0
  177. package/src/apps/aws-mediaconvert.json +196 -0
  178. package/src/apps/aws-s3.json +108 -192
  179. package/src/apps/aws-ses.json +666 -303
  180. package/src/apps/aws-sns.json +128 -106
  181. package/src/apps/azure-container-apps.json +116 -0
  182. package/src/apps/backblaze-b2.json +175 -0
  183. package/src/apps/bamboohr.json +303 -0
  184. package/src/apps/basiq.json +308 -0
  185. package/src/apps/bigcommerce.json +366 -0
  186. package/src/apps/bigquery.json +121 -0
  187. package/src/apps/binance-trading.json +7 -4
  188. package/src/apps/bing-webmaster-tools.json +158 -0
  189. package/src/apps/bitbucket.json +163 -0
  190. package/src/apps/blacksmith.json +81 -0
  191. package/src/apps/bls.json +104 -0
  192. package/src/apps/bluesky.json +74 -0
  193. package/src/apps/braze.json +103 -0
  194. package/src/apps/brevo.json +4 -1
  195. package/src/apps/brightdata.json +94 -0
  196. package/src/apps/browserbase.json +237 -0
  197. package/src/apps/bscscan.json +150 -0
  198. package/src/apps/buffer.json +121 -0
  199. package/src/apps/buildjet.json +80 -0
  200. package/src/apps/builtwith.json +101 -0
  201. package/src/apps/bunny-cdn.json +104 -0
  202. package/src/apps/bunny-stream.json +205 -3
  203. package/src/apps/byrd.json +585 -0
  204. package/src/apps/calendly.json +10 -7
  205. package/src/apps/campaign-manager-360.json +264 -0
  206. package/src/apps/capturekit.json +51 -0
  207. package/src/apps/circleci.json +212 -0
  208. package/src/apps/cirrus-runners.json +75 -0
  209. package/src/apps/cj-affiliate.json +101 -0
  210. package/src/apps/cjdropshipping.json +278 -0
  211. package/src/apps/clerk.json +153 -0
  212. package/src/apps/cloudflare-containers.json +98 -0
  213. package/src/apps/cloudflare-r2.json +180 -0
  214. package/src/apps/cloudflare.json +474 -157
  215. package/src/apps/cloudinary.json +119 -97
  216. package/src/apps/coconut.json +94 -0
  217. package/src/apps/contentful.json +157 -0
  218. package/src/apps/criteo.json +222 -0
  219. package/src/apps/crunchbase.json +104 -0
  220. package/src/apps/customer-io.json +106 -0
  221. package/src/apps/databricks.json +94 -0
  222. package/src/apps/deepgram.json +3 -0
  223. package/src/apps/deepl.json +113 -0
  224. package/src/apps/deepseek.json +5 -2
  225. package/src/apps/depot.json +102 -0
  226. package/src/apps/digitalocean-spaces.json +121 -0
  227. package/src/apps/digitalocean.json +115 -0
  228. package/src/apps/discord.json +90 -1
  229. package/src/apps/docker-build-cloud.json +68 -0
  230. package/src/apps/duffel.json +193 -77
  231. package/src/apps/dux-soup.json +4 -1
  232. package/src/apps/dv360.json +287 -0
  233. package/src/apps/earthly-cloud.json +84 -0
  234. package/src/apps/eia.json +121 -0
  235. package/src/apps/elasticsearch.json +282 -0
  236. package/src/apps/elevenlabs.json +336 -192
  237. package/src/apps/etherscan.json +162 -0
  238. package/src/apps/etsy.json +484 -0
  239. package/src/apps/eventbrite-events.json +5 -2
  240. package/src/apps/exa.json +101 -0
  241. package/src/apps/facebook-ads.json +3 -3
  242. package/src/apps/facebook-api.json +1484 -37
  243. package/src/apps/finnhub.json +232 -0
  244. package/src/apps/flightapi.json +248 -0
  245. package/src/apps/fly-io.json +134 -0
  246. package/src/apps/fred.json +156 -0
  247. package/src/apps/gdelt.json +96 -0
  248. package/src/apps/gelato.json +123 -0
  249. package/src/apps/gemini.json +143 -49
  250. package/src/apps/getscreenshot.json +52 -0
  251. package/src/apps/github.json +355 -39
  252. package/src/apps/gmail.json +151 -2
  253. package/src/apps/gnews.json +71 -0
  254. package/src/apps/google-analytics.json +311 -0
  255. package/src/apps/google-cloud-storage.json +484 -0
  256. package/src/apps/google-docs.json +2 -2
  257. package/src/apps/google-drive.json +2 -2
  258. package/src/apps/google-places.json +127 -0
  259. package/src/apps/google-search-console.json +126 -0
  260. package/src/apps/google-sheets.json +2 -2
  261. package/src/apps/grafana-cloud.json +98 -0
  262. package/src/apps/groq.json +119 -0
  263. package/src/apps/hetzner-object-storage.json +177 -0
  264. package/src/apps/hetzner.json +255 -367
  265. package/src/apps/heygen.json +828 -141
  266. package/src/apps/hive-fulfillment.json +559 -0
  267. package/src/apps/hotjar.json +91 -0
  268. package/src/apps/huawei-cloud.json +189 -0
  269. package/src/apps/huboo.json +286 -0
  270. package/src/apps/hubspot.json +253 -637
  271. package/src/apps/huggingface.json +5 -2
  272. package/src/apps/hunter.json +5 -2
  273. package/src/apps/hyperbrowser.json +205 -0
  274. package/src/apps/idrive-e2.json +128 -0
  275. package/src/apps/impact.json +106 -0
  276. package/src/apps/instagram-api.json +185 -11
  277. package/src/apps/instantly.json +169 -0
  278. package/src/apps/ionos.json +250 -0
  279. package/src/apps/{learning-platform.json โ†’ kalio.json} +162 -3
  280. package/src/apps/kalshi.json +144 -0
  281. package/src/apps/keywords-everywhere.json +86 -0
  282. package/src/apps/kickbox.json +71 -0
  283. package/src/apps/launchdarkly.json +111 -0
  284. package/src/apps/leadbyte.json +600 -0
  285. package/src/apps/leadfeeder.json +89 -0
  286. package/src/apps/lemlist.json +109 -0
  287. package/src/apps/linkedin-ads.json +279 -0
  288. package/src/apps/linkedin.json +96 -2
  289. package/src/apps/linode-object-storage.json +183 -0
  290. package/src/apps/linode.json +160 -0
  291. package/src/apps/lnk-bio.json +5 -2
  292. package/src/apps/loom.json +5 -2
  293. package/src/apps/lusha.json +104 -0
  294. package/src/apps/magalu-cloud.json +187 -0
  295. package/src/apps/majestic.json +117 -0
  296. package/src/apps/manifold-markets.json +144 -0
  297. package/src/apps/mapbox.json +118 -0
  298. package/src/apps/microsoft-ads.json +246 -0
  299. package/src/apps/microsoft-onedrive.json +380 -0
  300. package/src/apps/microsoft-teams.json +315 -96
  301. package/src/apps/millionverifier.json +85 -0
  302. package/src/apps/mindee.json +246 -0
  303. package/src/apps/miro.json +138 -0
  304. package/src/apps/mistral.json +129 -0
  305. package/src/apps/mixpanel.json +95 -0
  306. package/src/apps/moz.json +127 -0
  307. package/src/apps/mux.json +201 -0
  308. package/src/apps/namecheap.json +321 -123
  309. package/src/apps/namespace-cloud.json +84 -0
  310. package/src/apps/naver-cloud.json +184 -0
  311. package/src/apps/neon.json +122 -0
  312. package/src/apps/netlify.json +124 -0
  313. package/src/apps/neverbounce.json +92 -0
  314. package/src/apps/newrelic.json +80 -0
  315. package/src/apps/newsapi.json +86 -0
  316. package/src/apps/ngrok.json +29 -0
  317. package/src/apps/nixbuild.json +116 -0
  318. package/src/apps/northflank.json +161 -0
  319. package/src/apps/notion.json +3 -0
  320. package/src/apps/okta.json +131 -0
  321. package/src/apps/omnikit-analytics.json +73 -1
  322. package/src/apps/omnikit-api-gateway.json +74 -2
  323. package/src/apps/omnikit-billing.json +73 -1
  324. package/src/apps/omnikit-cms.json +73 -1
  325. package/src/apps/omnikit-code-ops.json +76 -4
  326. package/src/apps/omnikit-functions.json +74 -2
  327. package/src/apps/omnikit-intelligence.json +176 -33
  328. package/src/apps/omnikit-management.json +73 -1
  329. package/src/apps/omnikit-media.json +73 -1
  330. package/src/apps/omnikit-messaging.json +72 -0
  331. package/src/apps/omnikit-redirects.json +73 -1
  332. package/src/apps/omnikit-sites.json +325 -66
  333. package/src/apps/omnikit-storage.json +105 -8
  334. package/src/apps/omnikit-webhooks.json +73 -1
  335. package/src/apps/omnikit-workflows.json +73 -1
  336. package/src/apps/onesignal.json +108 -0
  337. package/src/apps/openai-api.json +176 -30
  338. package/src/apps/openai-codex.json +187 -0
  339. package/src/apps/opencode-go.json +113 -0
  340. package/src/apps/optinmonster.json +7 -4
  341. package/src/apps/outlook-calendar.json +350 -0
  342. package/src/apps/outlook-mail.json +337 -0
  343. package/src/apps/outscraper.json +118 -0
  344. package/src/apps/ovhcloud.json +209 -0
  345. package/src/apps/paddle.json +170 -0
  346. package/src/apps/pagerduty.json +151 -0
  347. package/src/apps/partnerstack.json +118 -0
  348. package/src/apps/perplexity.json +37 -0
  349. package/src/apps/phantombuster.json +85 -0
  350. package/src/apps/pinecone.json +129 -0
  351. package/src/apps/pinterest-ads.json +261 -0
  352. package/src/apps/pinterest.json +217 -0
  353. package/src/apps/planetscale.json +139 -0
  354. package/src/apps/polygonscan.json +157 -0
  355. package/src/apps/polymarket-clob.json +184 -0
  356. package/src/apps/polymarket-data.json +153 -0
  357. package/src/apps/porkbun.json +609 -145
  358. package/src/apps/posthog.json +107 -0
  359. package/src/apps/pushover.json +28 -0
  360. package/src/apps/quora-ads.json +251 -0
  361. package/src/apps/railway.json +57 -0
  362. package/src/apps/reddit-ads.json +238 -0
  363. package/src/apps/reddit.json +274 -0
  364. package/src/apps/render.json +124 -0
  365. package/src/apps/replicate.json +5 -2
  366. package/src/apps/reply-io.json +111 -0
  367. package/src/apps/resend.json +110 -0
  368. package/src/apps/ringover.json +1144 -0
  369. package/src/apps/rocketreach.json +158 -0
  370. package/src/apps/rollbar.json +88 -0
  371. package/src/apps/runs-on.json +70 -0
  372. package/src/apps/sanity.json +89 -0
  373. package/src/apps/scaleway-object-storage.json +175 -0
  374. package/src/apps/scrapingbee.json +75 -0
  375. package/src/apps/screenshotlayer.json +49 -0
  376. package/src/apps/screenshotmachine.json +49 -0
  377. package/src/apps/se-ranking.json +239 -0
  378. package/src/apps/seamless-ai.json +91 -0
  379. package/src/apps/sec-edgar.json +107 -0
  380. package/src/apps/segment.json +104 -0
  381. package/src/apps/semrush.json +153 -0
  382. package/src/apps/sentry.json +109 -0
  383. package/src/apps/serpapi.json +95 -0
  384. package/src/apps/serper.json +139 -0
  385. package/src/apps/shareasale.json +130 -0
  386. package/src/apps/skimlinks.json +48 -0
  387. package/src/apps/slack.json +101 -0
  388. package/src/apps/smartlead.json +146 -0
  389. package/src/apps/snapchat-ads.json +238 -0
  390. package/src/apps/snaprender.json +64 -0
  391. package/src/apps/snowflake.json +70 -0
  392. package/src/apps/snyk.json +108 -0
  393. package/src/apps/socialcast.json +74 -8
  394. package/src/apps/sovrn.json +125 -0
  395. package/src/apps/spotify-ads.json +231 -0
  396. package/src/apps/steel.json +239 -0
  397. package/src/apps/stocktwits.json +120 -0
  398. package/src/apps/stripe.json +153 -0
  399. package/src/apps/target-circle.json +348 -0
  400. package/src/apps/tavily.json +104 -0
  401. package/src/apps/tavus.json +403 -0
  402. package/src/apps/telegram.json +5 -2
  403. package/src/apps/teller.json +187 -0
  404. package/src/apps/tencent-cloud.json +214 -0
  405. package/src/apps/tennis-abstract.json +108 -0
  406. package/src/apps/the-odds-api.json +132 -0
  407. package/src/apps/the-sports-db.json +163 -0
  408. package/src/apps/tiktok-ads.json +295 -0
  409. package/src/apps/tiktok-api.json +181 -7
  410. package/src/apps/together.json +5 -2
  411. package/src/apps/trade-desk.json +237 -0
  412. package/src/apps/trading212.json +26 -29
  413. package/src/apps/transloadit.json +138 -0
  414. package/src/apps/truelayer.json +318 -0
  415. package/src/apps/twilio.json +313 -42
  416. package/src/apps/twitter-api.json +216 -33
  417. package/src/apps/ubicloud.json +82 -0
  418. package/src/apps/uplead.json +105 -0
  419. package/src/apps/upstash.json +90 -0
  420. package/src/apps/valueserp.json +63 -0
  421. package/src/apps/venice-ai.json +685 -0
  422. package/src/apps/vercel.json +137 -0
  423. package/src/apps/wappalyzer.json +65 -0
  424. package/src/apps/wasabi.json +175 -0
  425. package/src/apps/whale-alert.json +74 -0
  426. package/src/apps/whatsapp-business.json +131 -0
  427. package/src/apps/wikipedia.json +112 -0
  428. package/src/apps/workos.json +123 -0
  429. package/src/apps/yahoo-dsp.json +265 -0
  430. package/src/apps/yahoo-finance.json +60 -0
  431. package/src/apps/youtube-api.json +520 -142
  432. package/src/apps/zenrows.json +47 -0
  433. package/src/apps/zenserp.json +99 -0
  434. package/src/apps/zerobounce.json +80 -0
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/ui/notion/DatabaseCard.tsx", "../../../src/ui/notion/lib/notion.tsx"],
4
+ "sourcesContent": [
5
+ "// DatabaseCard โ€” overview of a Notion database. Useful when the\n// agent is referencing or about to query a database the operator\n// hasn't seen before.\n//\n// Surfaces:\n// - icon + title + breadcrumb\n// - optional description block\n// - schema as small typed pills (Status: select ยท Owner: person ยท โ€ฆ)\n// - item count + last-edited byline\n\nimport { Avatar, Card, CardHeader, DataList } from \"@apteva/ui-kit\";\nimport {\n databaseUrl, notionVendor, PageIcon, parseSchema, propTone, timeAgo,\n} from \"./lib/notion\";\n\ninterface Props {\n database_id: string;\n title?: string;\n /** Emoji or https URL. */\n icon?: string;\n description?: string;\n parent_path?: string;\n workspace?: string;\n url?: string;\n /** Total rows in the database. */\n item_count?: number;\n /** Comma-separated\"Name:type\" pairs. */\n schema?: string;\n /** Comma-separated view names. */\n views?: string;\n last_edited_at?: string;\n last_edited_by?: string;\n last_edited_by_avatar?: string;\n preview?: boolean;\n projectId?: string;\n}\n\nconst previewSample = {\n database_id: \"f1e2d3c4-b5a6-7890-1234-567890abcdef\",\n title: \"Q4 Sprint Tasks\",\n icon: \"๐Ÿ—‚\",\n description: \"Tasks tracked for the Q4 engineering sprint.\",\n parent_path: \"Apteva โ€บ Engineering\",\n workspace: \"apteva\",\n item_count: 38,\n schema: \"Title:title, Status:status, Owner:person, Due:date, Sprint:select, Priority:select\",\n views: \"Board ยท Calendar ยท Table ยท By owner\",\n last_edited_at: new Date(Date.now() - 12 * 60 * 1000).toISOString(),\n last_edited_by: \"marc-olivier\",\n last_edited_by_avatar: \"\",\n};\n\nexport default function DatabaseCard(props: Props) {\n const p = props.preview\n ? previewSample\n : {\n database_id: props.database_id,\n title: props.title || \"Untitled database\",\n icon: props.icon ?? \"\",\n description: props.description || \"\",\n parent_path: props.parent_path || \"\",\n workspace: props.workspace || \"\",\n item_count: props.item_count ?? 0,\n schema: props.schema || \"\",\n views: props.views || \"\",\n last_edited_at: props.last_edited_at || new Date().toISOString(),\n last_edited_by: props.last_edited_by || \"\",\n last_edited_by_avatar: props.last_edited_by_avatar || \"\",\n };\n\n const url = props.url || databaseUrl(p.database_id, p.workspace);\n const schemaProps = parseSchema(p.schema);\n\n return (\n <Card>\n <CardHeader\n vendor={notionVendor}\n title={\n <span className=\"inline-flex items-center gap-2\">\n <PageIcon icon={p.icon} fallback={p.title} size={16} />\n <span className=\"truncate\">{p.title}</span>\n </span>\n }\n subtitle={p.parent_path || undefined}\n action={{ label: \"Open database\", href: url }}\n />\n\n <div className=\"px-4 py-3 flex flex-col gap-3\">\n {p.description && (\n <p className=\"text-sm text-text leading-relaxed line-clamp-2\">\n {p.description}\n </p>\n )}\n\n <DataList\n items={[\n {\n label: \"Items\",\n value: (\n <span className=\"tabular-nums\">{p.item_count.toLocaleString()}</span>\n ),\n },\n ...(schemaProps.length > 0\n ? [{\n label: \"Schema\",\n value: (\n <span className=\"inline-flex flex-wrap gap-1\">\n {schemaProps.map((s) => (\n <span\n key={s.name}\n className={`text-[11px] font-medium px-1.5 py-0.5 rounded-md ${propTone(s.type)}`}\n >\n {s.name}\n <span className=\"opacity-60 ml-1\">{s.type}</span>\n </span>\n ))}\n </span>\n ),\n }]\n : []),\n ...(p.views\n ? [{ label: \"Views\", value: <span className=\"text-sm text-text\">{p.views}</span> }]\n : []),\n ]}\n />\n\n {/* last-edited byline */}\n <div className=\"flex items-center gap-2 text-xs pt-1\">\n {p.last_edited_by && (\n <Avatar src={p.last_edited_by_avatar} name={p.last_edited_by} size={18} />\n )}\n {p.last_edited_by && (\n <span className=\"text-text font-medium\">{p.last_edited_by}</span>\n )}\n <span className=\"text-text-dim\">edited {timeAgo(p.last_edited_at)}</span>\n </div>\n </div>\n </Card>\n );\n}\n",
6
+ "// Shared helpers for every Notion UI component.\n//\n// * notionVendor โ€” CardHeader brand pill (logo + name + color)\n// * URL builders โ€” page, database, search, comment\n// * formatters โ€” relative time, page-icon resolver, property-value\n// pretty-printer for typed Notion properties\n//\n// Mirrors the lib/hubspot.tsx / lib/github.tsx pattern: every vendor\n// lib has the same shape (logo + vendor + URLs + helpers).\n\nimport type { ReactNode } from \"react\";\nimport type { CardVendor } from \"@apteva/ui-kit\";\n\n// โ”€โ”€โ”€ Brand mark โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n//\n// Notion's mark is famously a stylized\"N\". currentColor so\n// CardHeader's vendor pill recolors it via inline `style.color`.\n\nexport const notionLogo: ReactNode = (\n <svg viewBox=\"0 0 32 32\" width=\"14\" height=\"14\" fill=\"currentColor\" aria-hidden>\n <path d=\"M5 4.7l3.4 2.3a1 1 0 00.8.2l16-1.6c.5-.1 1 .2 1 .7v18.4c0 .5-.4.9-.9.9L8 26.2c-.5 0-1-.3-1.2-.7l-1.7-3.4V4.7zm4 4.5v15l16-.9V8.3l-16 .9zm3.4 2.3v9.3l1.7.1V13l4.7 7.7 1.6.1v-9.4l-1.7-.1v6.6l-4.6-7.4-1.7.1z\" />\n </svg>\n);\n\n// Notion's brand is famously monochrome โ€” black on light surfaces,\n// white on dark. The single-color form would render unreadable on\n// a dark card (#191919 text on #1c1c1f bg), so we ship a {light,\n// dark} pair and CardHeader picks per active mode.\nexport const NOTION_BRAND_COLOR = { light: \"#191919\", dark: \"#e8e8e8\" };\n\nexport const notionVendor: CardVendor = {\n name: \"Notion\",\n logo: notionLogo,\n color: NOTION_BRAND_COLOR,\n};\n\n// โ”€โ”€โ”€ URL builders โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n//\n// Notion pages are addressable by id with dashes stripped. A page or\n// database canonical URL is `https://www.notion.so/<id-no-dashes>`.\n// When a workspace slug is known (e.g.\"apteva\"), the URL becomes\n// `https://www.notion.so/apteva/<id>` โ€” same target, prettier link.\n\nfunction bareId(id: string | undefined | null): string {\n if (!id) return \"\";\n return id.replace(/-/g,\"\");\n}\n\nexport function pageUrl(id: string, workspace?: string): string {\n const slug = workspace ? `${encodeURIComponent(workspace)}/` :\"\";\n return `https://www.notion.so/${slug}${bareId(id)}`;\n}\n\nexport function databaseUrl(id: string, workspace?: string): string {\n return pageUrl(id, workspace);\n}\n\nexport function searchUrl(query: string): string {\n return `https://www.notion.so/search?query=${encodeURIComponent(query)}`;\n}\n\n// โ”€โ”€โ”€ Formatters โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n\n/**\"3d ago\" /\"12m ago\" /\"just now\". */\nexport function timeAgo(iso?: string): string {\n if (!iso) return \"\";\n const t = new Date(iso).getTime();\n if (!Number.isFinite(t)) return \"\";\n const s = Math.max(0, (Date.now() - t) / 1000);\n if (s < 60) return \"just now\";\n const m = s / 60; if (m < 60) return `${Math.round(m)}m ago`;\n const h = m / 60; if (h < 24) return `${Math.round(h)}h ago`;\n const d = h / 24; if (d < 30) return `${Math.round(d)}d ago`;\n const mo = d / 30; if (mo < 12) return `${Math.round(mo)}mo ago`;\n return `${Math.round(mo / 12)}y ago`;\n}\n\n/** Test fixture helper โ€” same shape as the other libs. */\nexport function minusHoursISO(h: number): string {\n return new Date(Date.now() - h * 60 * 60 * 1000).toISOString();\n}\n\n// โ”€โ”€โ”€ Page icon โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n//\n// Notion pages can have:\n// - an emoji icon (single grapheme, e.g.\"๐Ÿ“‹\")\n// - an image icon (https URL)\n// - nothing โ€” fall back to a generic doc glyph\n//\n// `PageIcon` covers all three. Sized via the `size` prop in pixels.\n\ninterface PageIconProps {\n /** Emoji string OR https URL. Anything else is treated as nothing. */\n icon?: string | null;\n /** Optional: render this letter when there's no icon (page title's\n * initial usually). Falls back to a generic doc glyph if absent. */\n fallback?: string;\n size?: number;\n className?: string;\n}\n\nexport function PageIcon({ icon, fallback, size = 18, className = \"\" }: PageIconProps) {\n const style = { width: size, height: size, fontSize: Math.round(size * 0.66) };\n const isUrl = !!icon && /^https?:\\/\\//i.test(icon);\n const isEmoji = !!icon && !isUrl && Array.from(icon).length <= 3;\n\n if (isUrl) {\n return (\n <img\n src={icon!}\n alt=\"\"\n className={`rounded-sm flex-shrink-0 object-cover ${className}`}\n style={style}\n />\n );\n }\n if (isEmoji) {\n return (\n <span\n aria-hidden\n className={`flex-shrink-0 inline-flex items-center justify-center leading-none ${className}`}\n style={style}\n >\n {icon}\n </span>\n );\n }\n // Generic doc fallback โ€” minimal page glyph, monochrome.\n return (\n <span\n aria-hidden\n className={`flex-shrink-0 inline-flex items-center justify-center rounded-sm bg-bg-hover text-text-dim font-medium ${className}`}\n style={style}\n >\n {fallback ? fallback.charAt(0).toUpperCase() : \"ยท\"}\n </span>\n );\n}\n\n// โ”€โ”€โ”€ Schema parsing โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n//\n// Agents pass database schemas as a comma-separated\"name:type\"\n// list (e.g.\"Status:select,Owner:person,Due:date\"). This parses\n// into a typed array; the cards then render each entry as a small\n// pill with type-specific tint.\n\nexport type NotionPropType =\n |\"title\" |\"rich_text\" |\"select\" |\"multi_select\"\n |\"person\" |\"date\" |\"checkbox\" |\"number\"\n |\"url\" |\"email\" |\"phone\" |\"files\" |\"formula\" |\"relation\"\n |\"rollup\" |\"status\" |\"created_time\" |\"last_edited_time\"\n |\"created_by\" |\"last_edited_by\";\n\nexport interface NotionPropDef { name: string; type: NotionPropType }\n\nexport function parseSchema(raw?: string): NotionPropDef[] {\n if (!raw) return [];\n return raw.split(\",\").map((s) => {\n const [name, type] = s.split(\":\").map((x) => x.trim());\n return { name: name || \"โ€”\", type: ((type || \"rich_text\") as NotionPropType) };\n });\n}\n\n/** Type โ†’ tone class for the schema pills. */\nexport function propTone(type: NotionPropType): string {\n switch (type) {\n case \"select\":\n case \"status\": return \"bg-accent/10 text-blue-700 dark:bg-accent/15 dark:text-blue-400\";\n case \"multi_select\": return \"bg-purple-500/10 text-purple-700 dark:bg-purple-500/15 dark:text-purple-400\";\n case \"person\":\n case \"created_by\":\n case \"last_edited_by\": return \"bg-emerald-500/10 text-emerald-700 dark:bg-emerald-500/15 dark:text-emerald-400\";\n case \"date\":\n case \"created_time\":\n case \"last_edited_time\": return \"bg-warn/10 text-amber-700 dark:bg-warn/15 dark:text-amber-400\";\n case \"checkbox\": return \"bg-bg-hover text-text dark:bg-bg-hover dark:text-zinc-300\";\n case \"number\": return \"bg-cyan-500/10 text-cyan-700 dark:bg-cyan-500/15 dark:text-cyan-400\";\n default: return \"bg-zinc-100 text-text dark:bg-bg-hover dark:text-zinc-300\";\n }\n}\n"
7
+ ],
8
+ "mappings": "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",
9
+ "debugId": "5B09CB78B0AB322664756E2164756E21",
10
+ "names": []
11
+ }
@@ -0,0 +1,36 @@
1
+ interface RowItem {
2
+ page_id: string;
3
+ title: string;
4
+ icon?: string;
5
+ /** Status select-option label (any select prop the agent picks). */
6
+ status?: string;
7
+ /** Status color hint โ€” Notion's option colors. */
8
+ status_color?: "default" | "gray" | "brown" | "orange" | "yellow" | "green" | "blue" | "purple" | "pink" | "red";
9
+ /** Person property โ€” first assignee's display name. */
10
+ owner?: string;
11
+ owner_avatar?: string;
12
+ /** Date property โ€” pre-formatted like"May 11" or ISO. */
13
+ due?: string;
14
+ /** Plain-text excerpt of the row's first content block. */
15
+ excerpt?: string;
16
+ /** Last-edit timestamp for sorting / display. */
17
+ last_edited_at?: string;
18
+ }
19
+ interface Props {
20
+ database_id: string;
21
+ database_title?: string;
22
+ database_icon?: string;
23
+ workspace?: string;
24
+ url?: string;
25
+ /** Optional view / filter label โ€”"In progress","This sprint", โ€ฆ */
26
+ view_label?: string;
27
+ /** Either an array (preferred) or JSON-encoded string. */
28
+ rows?: RowItem[] | string;
29
+ /** Cap rendered rows; rest collapses into"+N more". Default 10. */
30
+ max?: number;
31
+ preview?: boolean;
32
+ projectId?: string;
33
+ }
34
+ export default function DatabaseRowList(props: Props): import("react").JSX.Element;
35
+ export {};
36
+ //# sourceMappingURL=DatabaseRowList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DatabaseRowList.d.ts","sourceRoot":"","sources":["../../../src/ui/notion/DatabaseRowList.tsx"],"names":[],"mappings":"AAkBA,UAAU,OAAO;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,YAAY,CAAC,EAAC,SAAS,GAAE,MAAM,GAAE,OAAO,GAAE,QAAQ,GAAE,QAAQ,GAAE,OAAO,GAAE,MAAM,GAAE,QAAQ,GAAE,MAAM,GAAE,KAAK,CAAC;IACvG,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yDAAyD;IACzD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,KAAK;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,IAAI,CAAC,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAC1B,mEAAmE;IACnE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAUD,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,KAAK,EAAE,KAAK,+BAyEnD"}
@@ -0,0 +1,87 @@
1
+ // DatabaseRowList โ€” rows from a Notion database query.
2
+ //
3
+ // The most operationally useful Notion card. Agents that fetch
4
+ //"all open tasks" or"this week's design reviews" hand the
5
+ // resulting page list here; each row gets a dense one-line render:
6
+ //
7
+ // [icon] Title status ยท owner ยท due
8
+ //
9
+ // Status / owner / due are pulled from common Notion property
10
+ // shapes; the agent passes them as flat fields per row so the
11
+ // component doesn't have to know about Notion's typed-property API.
12
+ import { Avatar, Card, CardHeader, Row, StatusPill } from "@apteva/ui-kit";
13
+ import { databaseUrl, notionVendor, PageIcon, timeAgo, } from "./lib/notion";
14
+ const previewRows = [
15
+ { page_id: "p1", title: "Fix retry loop on 5xx", icon: "๐Ÿ›", status: "In progress", status_color: "blue", owner: "ari", due: "May 11", last_edited_at: new Date(Date.now() - 30 * 60 * 1000).toISOString() },
16
+ { page_id: "p2", title: "Add idempotency keys", icon: "โœจ", status: "In progress", status_color: "blue", owner: "maya", due: "May 13", last_edited_at: new Date(Date.now() - 1 * 60 * 60 * 1000).toISOString() },
17
+ { page_id: "p3", title: "Quarterly metrics dashboard", icon: "๐Ÿ“Š", status: "Todo", status_color: "gray", owner: "lin", due: "May 18", last_edited_at: new Date(Date.now() - 4 * 60 * 60 * 1000).toISOString() },
18
+ { page_id: "p4", title: "Migrate retry queue to bullmq", icon: "โš™๏ธ", status: "In review", status_color: "yellow", owner: "ari", due: "May 14", last_edited_at: new Date(Date.now() - 5 * 60 * 60 * 1000).toISOString() },
19
+ { page_id: "p5", title: "Engineering offsite agenda", icon: "๐Ÿ“", status: "Todo", status_color: "gray", owner: "maya", due: "May 20", last_edited_at: new Date(Date.now() - 6 * 60 * 60 * 1000).toISOString() },
20
+ ];
21
+ export default function DatabaseRowList(props) {
22
+ const rows = props.preview
23
+ ? previewRows
24
+ : (parseRows(props.rows) ?? []);
25
+ const max = props.max ?? 10;
26
+ const visible = rows.slice(0, max);
27
+ const overflow = rows.length - visible.length;
28
+ const dbTitle = props.database_title ?? (props.preview ? "Q4 Sprint Tasks" : "Database");
29
+ const dbIcon = props.database_icon ?? (props.preview ? "๐Ÿ—‚" : undefined);
30
+ const dbId = props.database_id || (props.preview ? "f1e2d3c4-b5a6-7890-1234-567890abcdef" : "");
31
+ const url = props.url || (dbId ? databaseUrl(dbId, props.workspace) : "");
32
+ const subtitle = rows.length === 0
33
+ ? props.view_label || "No rows"
34
+ : `${rows.length} item${rows.length === 1 ? "" : "s"}` +
35
+ (props.view_label ? ` in view: ${props.view_label}` : "");
36
+ return (<Card fullWidth>
37
+ <CardHeader vendor={notionVendor} title={<span className="inline-flex items-center gap-2">
38
+ <PageIcon icon={dbIcon} fallback={dbTitle} size={16}/>
39
+ <span className="truncate">{dbTitle}</span>
40
+ </span>} subtitle={subtitle} action={{ label: "Open database", href: url }}/>
41
+
42
+ <div className="flex flex-col">
43
+ {visible.map((r, i) => (<Row key={r.page_id} flush={i === 0} leading={<PageIcon icon={r.icon} fallback={r.title} size={18}/>} title={r.title} subtitle={r.excerpt} trailing={<span className="inline-flex items-center gap-2">
44
+ {r.status && (<StatusPill variant={statusPillVariant(r.status_color)}>
45
+ {r.status}
46
+ </StatusPill>)}
47
+ {r.owner && (<span className="inline-flex items-center gap-1 text-text-dim">
48
+ <Avatar src={r.owner_avatar} name={r.owner} size={16}/>
49
+ <span className="hidden sm:inline">{r.owner}</span>
50
+ </span>)}
51
+ {r.due && (<span className="text-text-dim tabular-nums">{r.due}</span>)}
52
+ {!r.due && r.last_edited_at && (<span className="text-text-dim tabular-nums">{timeAgo(r.last_edited_at)}</span>)}
53
+ </span>}/>))}
54
+ {overflow > 0 && (<div className="px-4 py-2 text-xs text-text-dim border-t border-border">
55
+ +{overflow} more
56
+ </div>)}
57
+ </div>
58
+ </Card>);
59
+ }
60
+ // Map Notion's option color โ†’ ui-kit StatusPill variant. Notion has
61
+ // 9 colors; the ui-kit pill has 5 variants. We collapse the
62
+ // long-tail to"neutral" so agents that pass weird colors don't
63
+ // crash; status/blue/green variants get their natural mapping.
64
+ function statusPillVariant(color) {
65
+ switch (color) {
66
+ case "green": return "success";
67
+ case "blue": return "info";
68
+ case "yellow":
69
+ case "orange": return "warn";
70
+ case "red": return "error";
71
+ default: return "neutral";
72
+ }
73
+ }
74
+ function parseRows(raw) {
75
+ if (!raw)
76
+ return null;
77
+ if (Array.isArray(raw))
78
+ return raw;
79
+ try {
80
+ const parsed = JSON.parse(raw);
81
+ return Array.isArray(parsed) ? parsed : null;
82
+ }
83
+ catch {
84
+ return null;
85
+ }
86
+ }
87
+ //# sourceMappingURL=DatabaseRowList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DatabaseRowList.js","sourceRoot":"","sources":["../../../src/ui/notion/DatabaseRowList.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import{Avatar as P,Card as T,CardHeader as U,Row as R,StatusPill as z}from"@apteva/ui-kit";import{jsx as $}from"react/jsx-runtime";var _=$("svg",{viewBox:"0 0 32 32",width:"14",height:"14",fill:"currentColor","aria-hidden":!0,children:$("path",{d:"M5 4.7l3.4 2.3a1 1 0 00.8.2l16-1.6c.5-.1 1 .2 1 .7v18.4c0 .5-.4.9-.9.9L8 26.2c-.5 0-1-.3-1.2-.7l-1.7-3.4V4.7zm4 4.5v15l16-.9V8.3l-16 .9zm3.4 2.3v9.3l1.7.1V13l4.7 7.7 1.6.1v-9.4l-1.7-.1v6.6l-4.6-7.4-1.7.1z"})}),A={light:"#191919",dark:"#e8e8e8"},E={name:"Notion",logo:_,color:A};function C(F){if(!F)return"";return F.replace(/-/g,"")}function O(F,G){return`https://www.notion.so/${G?`${encodeURIComponent(G)}/`:""}${C(F)}`}function H(F,G){return O(F,G)}function S(F){if(!F)return"";let G=new Date(F).getTime();if(!Number.isFinite(G))return"";let W=Math.max(0,(Date.now()-G)/1000);if(W<60)return"just now";let K=W/60;if(K<60)return`${Math.round(K)}m ago`;let M=K/60;if(M<24)return`${Math.round(M)}h ago`;let X=M/24;if(X<30)return`${Math.round(X)}d ago`;let Y=X/30;if(Y<12)return`${Math.round(Y)}mo ago`;return`${Math.round(Y/12)}y ago`}function B({icon:F,fallback:G,size:W=18,className:K=""}){let M={width:W,height:W,fontSize:Math.round(W*0.66)},X=!!F&&/^https?:\/\//i.test(F),Y=!!F&&!X&&Array.from(F).length<=3;if(X)return $("img",{src:F,alt:"",className:`rounded-sm flex-shrink-0 object-cover ${K}`,style:M});if(Y)return $("span",{"aria-hidden":!0,className:`flex-shrink-0 inline-flex items-center justify-center leading-none ${K}`,style:M,children:F});return $("span",{"aria-hidden":!0,className:`flex-shrink-0 inline-flex items-center justify-center rounded-sm bg-bg-hover text-text-dim font-medium ${K}`,style:M,children:G?G.charAt(0).toUpperCase():"ยท"})}import{jsx as Q,jsxs as Z}from"react/jsx-runtime";var f=[{page_id:"p1",title:"Fix retry loop on 5xx",icon:"\uD83D\uDC1B",status:"In progress",status_color:"blue",owner:"ari",due:"May 11",last_edited_at:new Date(Date.now()-1800000).toISOString()},{page_id:"p2",title:"Add idempotency keys",icon:"โœจ",status:"In progress",status_color:"blue",owner:"maya",due:"May 13",last_edited_at:new Date(Date.now()-3600000).toISOString()},{page_id:"p3",title:"Quarterly metrics dashboard",icon:"\uD83D\uDCCA",status:"Todo",status_color:"gray",owner:"lin",due:"May 18",last_edited_at:new Date(Date.now()-14400000).toISOString()},{page_id:"p4",title:"Migrate retry queue to bullmq",icon:"โš™๏ธ",status:"In review",status_color:"yellow",owner:"ari",due:"May 14",last_edited_at:new Date(Date.now()-18000000).toISOString()},{page_id:"p5",title:"Engineering offsite agenda",icon:"\uD83D\uDCDD",status:"Todo",status_color:"gray",owner:"maya",due:"May 20",last_edited_at:new Date(Date.now()-21600000).toISOString()}];function I(F){let G=F.preview?f:v(F.rows)??[],W=F.max??10,K=G.slice(0,W),M=G.length-K.length,X=F.database_title??(F.preview?"Q4 Sprint Tasks":"Database"),Y=F.database_icon??(F.preview?"\uD83D\uDDC2":void 0),D=F.database_id||(F.preview?"f1e2d3c4-b5a6-7890-1234-567890abcdef":""),q=F.url||(D?H(D,F.workspace):""),L=G.length===0?F.view_label||"No rows":`${G.length} item${G.length===1?"":"s"}`+(F.view_label?` in view: ${F.view_label}`:"");return Z(T,{fullWidth:!0,children:[Q(U,{vendor:E,title:Z("span",{className:"inline-flex items-center gap-2",children:[Q(B,{icon:Y,fallback:X,size:16}),Q("span",{className:"truncate",children:X})]}),subtitle:L,action:{label:"Open database",href:q}}),Z("div",{className:"flex flex-col",children:[K.map((J,V)=>Q(R,{flush:V===0,leading:Q(B,{icon:J.icon,fallback:J.title,size:18}),title:J.title,subtitle:J.excerpt,trailing:Z("span",{className:"inline-flex items-center gap-2",children:[J.status&&Q(z,{variant:g(J.status_color),children:J.status}),J.owner&&Z("span",{className:"inline-flex items-center gap-1 text-text-dim",children:[Q(P,{src:J.owner_avatar,name:J.owner,size:16}),Q("span",{className:"hidden sm:inline",children:J.owner})]}),J.due&&Q("span",{className:"text-text-dim tabular-nums",children:J.due}),!J.due&&J.last_edited_at&&Q("span",{className:"text-text-dim tabular-nums",children:S(J.last_edited_at)})]})},J.page_id)),M>0&&Z("div",{className:"px-4 py-2 text-xs text-text-dim border-t border-border",children:["+",M," more"]})]})]})}function g(F){switch(F){case"green":return"success";case"blue":return"info";case"yellow":case"orange":return"warn";case"red":return"error";default:return"neutral"}}function v(F){if(!F)return null;if(Array.isArray(F))return F;try{let G=JSON.parse(F);return Array.isArray(G)?G:null}catch{return null}}export{I as default};
2
+
3
+ //# debugId=76FE666CE1325A7264756E2164756E21
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/ui/notion/DatabaseRowList.tsx", "../../../src/ui/notion/lib/notion.tsx"],
4
+ "sourcesContent": [
5
+ "// DatabaseRowList โ€” rows from a Notion database query.\n//\n// The most operationally useful Notion card. Agents that fetch\n//\"all open tasks\" or\"this week's design reviews\" hand the\n// resulting page list here; each row gets a dense one-line render:\n//\n// [icon] Title status ยท owner ยท due\n//\n// Status / owner / due are pulled from common Notion property\n// shapes; the agent passes them as flat fields per row so the\n// component doesn't have to know about Notion's typed-property API.\n\nimport { Avatar, Card, CardHeader, Row, StatusPill } from \"@apteva/ui-kit\";\nimport type { StatusPillVariant } from \"@apteva/ui-kit\";\nimport {\n databaseUrl, notionVendor, PageIcon, timeAgo,\n} from \"./lib/notion\";\n\ninterface RowItem {\n page_id: string;\n title: string;\n icon?: string;\n /** Status select-option label (any select prop the agent picks). */\n status?: string;\n /** Status color hint โ€” Notion's option colors. */\n status_color?:\"default\" |\"gray\" |\"brown\" |\"orange\" |\"yellow\" |\"green\" |\"blue\" |\"purple\" |\"pink\" |\"red\";\n /** Person property โ€” first assignee's display name. */\n owner?: string;\n owner_avatar?: string;\n /** Date property โ€” pre-formatted like\"May 11\" or ISO. */\n due?: string;\n /** Plain-text excerpt of the row's first content block. */\n excerpt?: string;\n /** Last-edit timestamp for sorting / display. */\n last_edited_at?: string;\n}\n\ninterface Props {\n database_id: string;\n database_title?: string;\n database_icon?: string;\n workspace?: string;\n url?: string;\n /** Optional view / filter label โ€”\"In progress\",\"This sprint\", โ€ฆ */\n view_label?: string;\n /** Either an array (preferred) or JSON-encoded string. */\n rows?: RowItem[] | string;\n /** Cap rendered rows; rest collapses into\"+N more\". Default 10. */\n max?: number;\n preview?: boolean;\n projectId?: string;\n}\n\nconst previewRows: RowItem[] = [\n { page_id: \"p1\", title: \"Fix retry loop on 5xx\", icon: \"๐Ÿ›\", status: \"In progress\", status_color: \"blue\", owner: \"ari\", due: \"May 11\", last_edited_at: new Date(Date.now() - 30 * 60 * 1000).toISOString() },\n { page_id: \"p2\", title: \"Add idempotency keys\", icon: \"โœจ\", status: \"In progress\", status_color: \"blue\", owner: \"maya\", due: \"May 13\", last_edited_at: new Date(Date.now() - 1 * 60 * 60 * 1000).toISOString() },\n { page_id: \"p3\", title: \"Quarterly metrics dashboard\", icon: \"๐Ÿ“Š\", status: \"Todo\", status_color: \"gray\", owner: \"lin\", due: \"May 18\", last_edited_at: new Date(Date.now() - 4 * 60 * 60 * 1000).toISOString() },\n { page_id: \"p4\", title: \"Migrate retry queue to bullmq\", icon: \"โš™๏ธ\", status: \"In review\", status_color: \"yellow\", owner: \"ari\", due: \"May 14\", last_edited_at: new Date(Date.now() - 5 * 60 * 60 * 1000).toISOString() },\n { page_id: \"p5\", title: \"Engineering offsite agenda\", icon: \"๐Ÿ“\", status: \"Todo\", status_color: \"gray\", owner: \"maya\", due: \"May 20\", last_edited_at: new Date(Date.now() - 6 * 60 * 60 * 1000).toISOString() },\n];\n\nexport default function DatabaseRowList(props: Props) {\n const rows = props.preview\n ? previewRows\n : (parseRows(props.rows) ?? []);\n\n const max = props.max ?? 10;\n const visible = rows.slice(0, max);\n const overflow = rows.length - visible.length;\n\n const dbTitle = props.database_title ?? (props.preview ? \"Q4 Sprint Tasks\" :\"Database\");\n const dbIcon = props.database_icon ?? (props.preview ? \"๐Ÿ—‚\" : undefined);\n const dbId = props.database_id || (props.preview ? \"f1e2d3c4-b5a6-7890-1234-567890abcdef\" :\"\");\n const url = props.url || (dbId ? databaseUrl(dbId, props.workspace) : \"\");\n\n const subtitle =\n rows.length === 0\n ? props.view_label || \"No rows\"\n : `${rows.length} item${rows.length === 1 ? \"\" :\"s\"}` +\n (props.view_label ? ` in view: ${props.view_label}` :\"\");\n\n return (\n <Card fullWidth>\n <CardHeader\n vendor={notionVendor}\n title={\n <span className=\"inline-flex items-center gap-2\">\n <PageIcon icon={dbIcon} fallback={dbTitle} size={16} />\n <span className=\"truncate\">{dbTitle}</span>\n </span>\n }\n subtitle={subtitle}\n action={{ label: \"Open database\", href: url }}\n />\n\n <div className=\"flex flex-col\">\n {visible.map((r, i) => (\n <Row\n key={r.page_id}\n flush={i === 0}\n leading={<PageIcon icon={r.icon} fallback={r.title} size={18} />}\n title={r.title}\n subtitle={r.excerpt}\n trailing={\n <span className=\"inline-flex items-center gap-2\">\n {r.status && (\n <StatusPill variant={statusPillVariant(r.status_color)}>\n {r.status}\n </StatusPill>\n )}\n {r.owner && (\n <span className=\"inline-flex items-center gap-1 text-text-dim\">\n <Avatar src={r.owner_avatar} name={r.owner} size={16} />\n <span className=\"hidden sm:inline\">{r.owner}</span>\n </span>\n )}\n {r.due && (\n <span className=\"text-text-dim tabular-nums\">{r.due}</span>\n )}\n {!r.due && r.last_edited_at && (\n <span className=\"text-text-dim tabular-nums\">{timeAgo(r.last_edited_at)}</span>\n )}\n </span>\n }\n />\n ))}\n {overflow > 0 && (\n <div className=\"px-4 py-2 text-xs text-text-dim border-t border-border\">\n +{overflow} more\n </div>\n )}\n </div>\n </Card>\n );\n}\n\n// Map Notion's option color โ†’ ui-kit StatusPill variant. Notion has\n// 9 colors; the ui-kit pill has 5 variants. We collapse the\n// long-tail to\"neutral\" so agents that pass weird colors don't\n// crash; status/blue/green variants get their natural mapping.\nfunction statusPillVariant(color?: RowItem[\"status_color\"]): StatusPillVariant {\n switch (color) {\n case \"green\": return \"success\";\n case \"blue\": return \"info\";\n case \"yellow\":\n case \"orange\": return \"warn\";\n case \"red\": return \"error\";\n default: return \"neutral\";\n }\n}\n\nfunction parseRows(raw: RowItem[] | string | undefined): RowItem[] | null {\n if (!raw) return null;\n if (Array.isArray(raw)) return raw;\n try {\n const parsed = JSON.parse(raw);\n return Array.isArray(parsed) ? parsed : null;\n } catch {\n return null;\n }\n}\n",
6
+ "// Shared helpers for every Notion UI component.\n//\n// * notionVendor โ€” CardHeader brand pill (logo + name + color)\n// * URL builders โ€” page, database, search, comment\n// * formatters โ€” relative time, page-icon resolver, property-value\n// pretty-printer for typed Notion properties\n//\n// Mirrors the lib/hubspot.tsx / lib/github.tsx pattern: every vendor\n// lib has the same shape (logo + vendor + URLs + helpers).\n\nimport type { ReactNode } from \"react\";\nimport type { CardVendor } from \"@apteva/ui-kit\";\n\n// โ”€โ”€โ”€ Brand mark โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n//\n// Notion's mark is famously a stylized\"N\". currentColor so\n// CardHeader's vendor pill recolors it via inline `style.color`.\n\nexport const notionLogo: ReactNode = (\n <svg viewBox=\"0 0 32 32\" width=\"14\" height=\"14\" fill=\"currentColor\" aria-hidden>\n <path d=\"M5 4.7l3.4 2.3a1 1 0 00.8.2l16-1.6c.5-.1 1 .2 1 .7v18.4c0 .5-.4.9-.9.9L8 26.2c-.5 0-1-.3-1.2-.7l-1.7-3.4V4.7zm4 4.5v15l16-.9V8.3l-16 .9zm3.4 2.3v9.3l1.7.1V13l4.7 7.7 1.6.1v-9.4l-1.7-.1v6.6l-4.6-7.4-1.7.1z\" />\n </svg>\n);\n\n// Notion's brand is famously monochrome โ€” black on light surfaces,\n// white on dark. The single-color form would render unreadable on\n// a dark card (#191919 text on #1c1c1f bg), so we ship a {light,\n// dark} pair and CardHeader picks per active mode.\nexport const NOTION_BRAND_COLOR = { light: \"#191919\", dark: \"#e8e8e8\" };\n\nexport const notionVendor: CardVendor = {\n name: \"Notion\",\n logo: notionLogo,\n color: NOTION_BRAND_COLOR,\n};\n\n// โ”€โ”€โ”€ URL builders โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n//\n// Notion pages are addressable by id with dashes stripped. A page or\n// database canonical URL is `https://www.notion.so/<id-no-dashes>`.\n// When a workspace slug is known (e.g.\"apteva\"), the URL becomes\n// `https://www.notion.so/apteva/<id>` โ€” same target, prettier link.\n\nfunction bareId(id: string | undefined | null): string {\n if (!id) return \"\";\n return id.replace(/-/g,\"\");\n}\n\nexport function pageUrl(id: string, workspace?: string): string {\n const slug = workspace ? `${encodeURIComponent(workspace)}/` :\"\";\n return `https://www.notion.so/${slug}${bareId(id)}`;\n}\n\nexport function databaseUrl(id: string, workspace?: string): string {\n return pageUrl(id, workspace);\n}\n\nexport function searchUrl(query: string): string {\n return `https://www.notion.so/search?query=${encodeURIComponent(query)}`;\n}\n\n// โ”€โ”€โ”€ Formatters โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n\n/**\"3d ago\" /\"12m ago\" /\"just now\". */\nexport function timeAgo(iso?: string): string {\n if (!iso) return \"\";\n const t = new Date(iso).getTime();\n if (!Number.isFinite(t)) return \"\";\n const s = Math.max(0, (Date.now() - t) / 1000);\n if (s < 60) return \"just now\";\n const m = s / 60; if (m < 60) return `${Math.round(m)}m ago`;\n const h = m / 60; if (h < 24) return `${Math.round(h)}h ago`;\n const d = h / 24; if (d < 30) return `${Math.round(d)}d ago`;\n const mo = d / 30; if (mo < 12) return `${Math.round(mo)}mo ago`;\n return `${Math.round(mo / 12)}y ago`;\n}\n\n/** Test fixture helper โ€” same shape as the other libs. */\nexport function minusHoursISO(h: number): string {\n return new Date(Date.now() - h * 60 * 60 * 1000).toISOString();\n}\n\n// โ”€โ”€โ”€ Page icon โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n//\n// Notion pages can have:\n// - an emoji icon (single grapheme, e.g.\"๐Ÿ“‹\")\n// - an image icon (https URL)\n// - nothing โ€” fall back to a generic doc glyph\n//\n// `PageIcon` covers all three. Sized via the `size` prop in pixels.\n\ninterface PageIconProps {\n /** Emoji string OR https URL. Anything else is treated as nothing. */\n icon?: string | null;\n /** Optional: render this letter when there's no icon (page title's\n * initial usually). Falls back to a generic doc glyph if absent. */\n fallback?: string;\n size?: number;\n className?: string;\n}\n\nexport function PageIcon({ icon, fallback, size = 18, className = \"\" }: PageIconProps) {\n const style = { width: size, height: size, fontSize: Math.round(size * 0.66) };\n const isUrl = !!icon && /^https?:\\/\\//i.test(icon);\n const isEmoji = !!icon && !isUrl && Array.from(icon).length <= 3;\n\n if (isUrl) {\n return (\n <img\n src={icon!}\n alt=\"\"\n className={`rounded-sm flex-shrink-0 object-cover ${className}`}\n style={style}\n />\n );\n }\n if (isEmoji) {\n return (\n <span\n aria-hidden\n className={`flex-shrink-0 inline-flex items-center justify-center leading-none ${className}`}\n style={style}\n >\n {icon}\n </span>\n );\n }\n // Generic doc fallback โ€” minimal page glyph, monochrome.\n return (\n <span\n aria-hidden\n className={`flex-shrink-0 inline-flex items-center justify-center rounded-sm bg-bg-hover text-text-dim font-medium ${className}`}\n style={style}\n >\n {fallback ? fallback.charAt(0).toUpperCase() : \"ยท\"}\n </span>\n );\n}\n\n// โ”€โ”€โ”€ Schema parsing โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n//\n// Agents pass database schemas as a comma-separated\"name:type\"\n// list (e.g.\"Status:select,Owner:person,Due:date\"). This parses\n// into a typed array; the cards then render each entry as a small\n// pill with type-specific tint.\n\nexport type NotionPropType =\n |\"title\" |\"rich_text\" |\"select\" |\"multi_select\"\n |\"person\" |\"date\" |\"checkbox\" |\"number\"\n |\"url\" |\"email\" |\"phone\" |\"files\" |\"formula\" |\"relation\"\n |\"rollup\" |\"status\" |\"created_time\" |\"last_edited_time\"\n |\"created_by\" |\"last_edited_by\";\n\nexport interface NotionPropDef { name: string; type: NotionPropType }\n\nexport function parseSchema(raw?: string): NotionPropDef[] {\n if (!raw) return [];\n return raw.split(\",\").map((s) => {\n const [name, type] = s.split(\":\").map((x) => x.trim());\n return { name: name || \"โ€”\", type: ((type || \"rich_text\") as NotionPropType) };\n });\n}\n\n/** Type โ†’ tone class for the schema pills. */\nexport function propTone(type: NotionPropType): string {\n switch (type) {\n case \"select\":\n case \"status\": return \"bg-accent/10 text-blue-700 dark:bg-accent/15 dark:text-blue-400\";\n case \"multi_select\": return \"bg-purple-500/10 text-purple-700 dark:bg-purple-500/15 dark:text-purple-400\";\n case \"person\":\n case \"created_by\":\n case \"last_edited_by\": return \"bg-emerald-500/10 text-emerald-700 dark:bg-emerald-500/15 dark:text-emerald-400\";\n case \"date\":\n case \"created_time\":\n case \"last_edited_time\": return \"bg-warn/10 text-amber-700 dark:bg-warn/15 dark:text-amber-400\";\n case \"checkbox\": return \"bg-bg-hover text-text dark:bg-bg-hover dark:text-zinc-300\";\n case \"number\": return \"bg-cyan-500/10 text-cyan-700 dark:bg-cyan-500/15 dark:text-cyan-400\";\n default: return \"bg-zinc-100 text-text dark:bg-bg-hover dark:text-zinc-300\";\n }\n}\n"
7
+ ],
8
+ "mappings": "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",
9
+ "debugId": "76FE666CE1325A7264756E2164756E21",
10
+ "names": []
11
+ }
@@ -0,0 +1,27 @@
1
+ interface Props {
2
+ page_id: string;
3
+ title?: string;
4
+ /** Emoji or https URL โ€” see PageIcon. */
5
+ icon?: string;
6
+ /** Breadcrumb path (workspace โ€บ database โ€บ parent). One string. */
7
+ parent_path?: string;
8
+ /** Optional cover image URL (currently unused โ€” kept for API parity). */
9
+ cover?: string;
10
+ /** Workspace slug, used to build the canonical URL. */
11
+ workspace?: string;
12
+ url?: string;
13
+ archived?: boolean;
14
+ last_edited_at?: string;
15
+ last_edited_by?: string;
16
+ last_edited_by_avatar?: string;
17
+ /** Plain-text excerpt of the first content block (โ‰ค 240 chars). */
18
+ excerpt?: string;
19
+ /** Comma-separated"label=value" pairs for database-row properties.
20
+ * Example:"Status=In progress, Owner=ari, Due=May 11". */
21
+ properties?: string;
22
+ preview?: boolean;
23
+ projectId?: string;
24
+ }
25
+ export default function PageCard(props: Props): import("react").JSX.Element;
26
+ export {};
27
+ //# sourceMappingURL=PageCard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageCard.d.ts","sourceRoot":"","sources":["../../../src/ui/notion/PageCard.tsx"],"names":[],"mappings":"AAaA,UAAU,KAAK;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;6DACyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAgBD,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,KAAK,EAAE,KAAK,+BA6D5C"}
@@ -0,0 +1,80 @@
1
+ // PageCard โ€” single Notion page. Title + icon up top, optional
2
+ // breadcrumb above the title, optional excerpt below, properties as
3
+ // a compact DataList when the page is a database row.
4
+ //
5
+ // Notion's"page" is the universal unit โ€” a free-form doc, a
6
+ // database row, a sub-page. Same card renders all three; the
7
+ // presence of `properties` distinguishes a row from a free doc.
8
+ import { Avatar, Card, CardHeader, DataList } from "@apteva/ui-kit";
9
+ import { notionVendor, pageUrl, PageIcon, timeAgo, } from "./lib/notion";
10
+ const previewSample = {
11
+ page_id: "abc-123-def",
12
+ title: "Q4 engineering roadmap",
13
+ icon: "๐Ÿ“‹",
14
+ parent_path: "Apteva โ€บ Engineering",
15
+ workspace: "apteva",
16
+ archived: false,
17
+ last_edited_at: new Date(Date.now() - 2 * 60 * 60 * 1000).toISOString(),
18
+ last_edited_by: "marc-olivier",
19
+ last_edited_by_avatar: "",
20
+ excerpt: "We need to deliver three things in Q4: reliability work on the" + "retry path, a 30% reduction in agent latency, and the v2 API" + "gateway behind a feature flag.",
21
+ properties: "Status=In progress, Owner=marc-olivier, Due=May 11, Sprint=Q4-S2",
22
+ };
23
+ export default function PageCard(props) {
24
+ const p = props.preview
25
+ ? previewSample
26
+ : {
27
+ page_id: props.page_id,
28
+ title: props.title || "Untitled",
29
+ icon: props.icon ?? "",
30
+ parent_path: props.parent_path || "",
31
+ workspace: props.workspace || "",
32
+ archived: !!props.archived,
33
+ last_edited_at: props.last_edited_at || new Date().toISOString(),
34
+ last_edited_by: props.last_edited_by || "",
35
+ last_edited_by_avatar: props.last_edited_by_avatar || "",
36
+ excerpt: props.excerpt || "",
37
+ properties: props.properties || "",
38
+ };
39
+ const url = props.url || pageUrl(p.page_id, p.workspace);
40
+ const props_kv = parseProperties(p.properties);
41
+ return (<Card>
42
+ <CardHeader vendor={notionVendor} title={<span className="inline-flex items-center gap-2">
43
+ <PageIcon icon={p.icon} fallback={p.title} size={16}/>
44
+ <span className="truncate">{p.title}</span>
45
+ </span>} subtitle={p.parent_path || undefined} status={p.archived ? { label: "archived", variant: "muted" } : undefined} action={{ label: "Open in Notion", href: url }}/>
46
+
47
+ <div className="px-4 py-3 flex flex-col gap-3">
48
+ {/* last-edited byline โ€” always shown */}
49
+ <div className="flex items-center gap-2 text-xs">
50
+ {p.last_edited_by && (<Avatar src={p.last_edited_by_avatar} name={p.last_edited_by} size={18}/>)}
51
+ {p.last_edited_by && (<span className="text-text font-medium">{p.last_edited_by}</span>)}
52
+ <span className="text-text-dim">edited {timeAgo(p.last_edited_at)}</span>
53
+ </div>
54
+
55
+ {/* properties โ€” only when it's a database row */}
56
+ {props_kv.length > 0 && (<DataList items={props_kv}/>)}
57
+
58
+ {/* excerpt โ€” first block of page content if available */}
59
+ {p.excerpt && (<p className="text-sm text-text whitespace-pre-wrap break-words leading-relaxed line-clamp-4">
60
+ {p.excerpt}
61
+ </p>)}
62
+ </div>
63
+ </Card>);
64
+ }
65
+ //"Status=In progress, Owner=ari" โ†’ DataList items
66
+ function parseProperties(raw) {
67
+ if (!raw)
68
+ return [];
69
+ return raw
70
+ .split(",")
71
+ .map((entry) => entry.trim())
72
+ .filter(Boolean)
73
+ .map((entry) => {
74
+ const eq = entry.indexOf("= ");
75
+ if (eq === -1)
76
+ return { label: entry, value: "" };
77
+ return { label: entry.slice(0, eq).trim(), value: entry.slice(eq + 1).trim() };
78
+ });
79
+ }
80
+ //# sourceMappingURL=PageCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageCard.js","sourceRoot":"","sources":["../../../src/ui/notion/PageCard.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import{Avatar as S,Card as T,CardHeader as A,DataList as C}from"@apteva/ui-kit";import{jsx as Y}from"react/jsx-runtime";var V=Y("svg",{viewBox:"0 0 32 32",width:"14",height:"14",fill:"currentColor","aria-hidden":!0,children:Y("path",{d:"M5 4.7l3.4 2.3a1 1 0 00.8.2l16-1.6c.5-.1 1 .2 1 .7v18.4c0 .5-.4.9-.9.9L8 26.2c-.5 0-1-.3-1.2-.7l-1.7-3.4V4.7zm4 4.5v15l16-.9V8.3l-16 .9zm3.4 2.3v9.3l1.7.1V13l4.7 7.7 1.6.1v-9.4l-1.7-.1v6.6l-4.6-7.4-1.7.1z"})}),P={light:"#191919",dark:"#e8e8e8"},$={name:"Notion",logo:V,color:P};function R(G){if(!G)return"";return G.replace(/-/g,"")}function B(G,F){return`https://www.notion.so/${F?`${encodeURIComponent(F)}/`:""}${R(G)}`}function E(G){if(!G)return"";let F=new Date(G).getTime();if(!Number.isFinite(F))return"";let J=Math.max(0,(Date.now()-F)/1000);if(J<60)return"just now";let K=J/60;if(K<60)return`${Math.round(K)}m ago`;let M=K/60;if(M<24)return`${Math.round(M)}h ago`;let W=M/24;if(W<30)return`${Math.round(W)}d ago`;let X=W/30;if(X<12)return`${Math.round(X)}mo ago`;return`${Math.round(X/12)}y ago`}function H({icon:G,fallback:F,size:J=18,className:K=""}){let M={width:J,height:J,fontSize:Math.round(J*0.66)},W=!!G&&/^https?:\/\//i.test(G),X=!!G&&!W&&Array.from(G).length<=3;if(W)return Y("img",{src:G,alt:"",className:`rounded-sm flex-shrink-0 object-cover ${K}`,style:M});if(X)return Y("span",{"aria-hidden":!0,className:`flex-shrink-0 inline-flex items-center justify-center leading-none ${K}`,style:M,children:G});return Y("span",{"aria-hidden":!0,className:`flex-shrink-0 inline-flex items-center justify-center rounded-sm bg-bg-hover text-text-dim font-medium ${K}`,style:M,children:F?F.charAt(0).toUpperCase():"ยท"})}import{jsx as Q,jsxs as Z}from"react/jsx-runtime";var D={page_id:"abc-123-def",title:"Q4 engineering roadmap",icon:"\uD83D\uDCCB",parent_path:"Apteva โ€บ Engineering",workspace:"apteva",archived:!1,last_edited_at:new Date(Date.now()-7200000).toISOString(),last_edited_by:"marc-olivier",last_edited_by_avatar:"",excerpt:"We need to deliver three things in Q4: reliability work on theretry path, a 30% reduction in agent latency, and the v2 APIgateway behind a feature flag.",properties:"Status=In progress, Owner=marc-olivier, Due=May 11, Sprint=Q4-S2"};function I(G){let F=G.preview?D:{page_id:G.page_id,title:G.title||"Untitled",icon:G.icon??"",parent_path:G.parent_path||"",workspace:G.workspace||"",archived:!!G.archived,last_edited_at:G.last_edited_at||new Date().toISOString(),last_edited_by:G.last_edited_by||"",last_edited_by_avatar:G.last_edited_by_avatar||"",excerpt:G.excerpt||"",properties:G.properties||""},J=G.url||B(F.page_id,F.workspace),K=L(F.properties);return Z(T,{children:[Q(A,{vendor:$,title:Z("span",{className:"inline-flex items-center gap-2",children:[Q(H,{icon:F.icon,fallback:F.title,size:16}),Q("span",{className:"truncate",children:F.title})]}),subtitle:F.parent_path||void 0,status:F.archived?{label:"archived",variant:"muted"}:void 0,action:{label:"Open in Notion",href:J}}),Z("div",{className:"px-4 py-3 flex flex-col gap-3",children:[Z("div",{className:"flex items-center gap-2 text-xs",children:[F.last_edited_by&&Q(S,{src:F.last_edited_by_avatar,name:F.last_edited_by,size:18}),F.last_edited_by&&Q("span",{className:"text-text font-medium",children:F.last_edited_by}),Z("span",{className:"text-text-dim",children:["edited ",E(F.last_edited_at)]})]}),K.length>0&&Q(C,{items:K}),F.excerpt&&Q("p",{className:"text-sm text-text whitespace-pre-wrap break-words leading-relaxed line-clamp-4",children:F.excerpt})]})]})}function L(G){if(!G)return[];return G.split(",").map((F)=>F.trim()).filter(Boolean).map((F)=>{let J=F.indexOf("= ");if(J===-1)return{label:F,value:""};return{label:F.slice(0,J).trim(),value:F.slice(J+1).trim()}})}export{I as default};
2
+
3
+ //# debugId=6AC199DED57DE0CD64756E2164756E21
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/ui/notion/PageCard.tsx", "../../../src/ui/notion/lib/notion.tsx"],
4
+ "sourcesContent": [
5
+ "// PageCard โ€” single Notion page. Title + icon up top, optional\n// breadcrumb above the title, optional excerpt below, properties as\n// a compact DataList when the page is a database row.\n//\n// Notion's\"page\" is the universal unit โ€” a free-form doc, a\n// database row, a sub-page. Same card renders all three; the\n// presence of `properties` distinguishes a row from a free doc.\n\nimport { Avatar, Card, CardHeader, DataList } from \"@apteva/ui-kit\";\nimport {\n notionVendor, pageUrl, PageIcon, timeAgo,\n} from \"./lib/notion\";\n\ninterface Props {\n page_id: string;\n title?: string;\n /** Emoji or https URL โ€” see PageIcon. */\n icon?: string;\n /** Breadcrumb path (workspace โ€บ database โ€บ parent). One string. */\n parent_path?: string;\n /** Optional cover image URL (currently unused โ€” kept for API parity). */\n cover?: string;\n /** Workspace slug, used to build the canonical URL. */\n workspace?: string;\n url?: string;\n archived?: boolean;\n last_edited_at?: string;\n last_edited_by?: string;\n last_edited_by_avatar?: string;\n /** Plain-text excerpt of the first content block (โ‰ค 240 chars). */\n excerpt?: string;\n /** Comma-separated\"label=value\" pairs for database-row properties.\n * Example:\"Status=In progress, Owner=ari, Due=May 11\". */\n properties?: string;\n preview?: boolean;\n projectId?: string;\n}\n\nconst previewSample = {\n page_id: \"abc-123-def\",\n title: \"Q4 engineering roadmap\",\n icon: \"๐Ÿ“‹\",\n parent_path: \"Apteva โ€บ Engineering\",\n workspace: \"apteva\",\n archived: false,\n last_edited_at: new Date(Date.now() - 2 * 60 * 60 * 1000).toISOString(),\n last_edited_by: \"marc-olivier\",\n last_edited_by_avatar: \"\",\n excerpt: \"We need to deliver three things in Q4: reliability work on the\" +\"retry path, a 30% reduction in agent latency, and the v2 API\" +\"gateway behind a feature flag.\",\n properties: \"Status=In progress, Owner=marc-olivier, Due=May 11, Sprint=Q4-S2\",\n};\n\nexport default function PageCard(props: Props) {\n const p = props.preview\n ? previewSample\n : {\n page_id: props.page_id,\n title: props.title || \"Untitled\",\n icon: props.icon ?? \"\",\n parent_path: props.parent_path || \"\",\n workspace: props.workspace || \"\",\n archived: !!props.archived,\n last_edited_at: props.last_edited_at || new Date().toISOString(),\n last_edited_by: props.last_edited_by || \"\",\n last_edited_by_avatar: props.last_edited_by_avatar || \"\",\n excerpt: props.excerpt || \"\",\n properties: props.properties || \"\",\n };\n\n const url = props.url || pageUrl(p.page_id, p.workspace);\n const props_kv = parseProperties(p.properties);\n\n return (\n <Card>\n <CardHeader\n vendor={notionVendor}\n title={\n <span className=\"inline-flex items-center gap-2\">\n <PageIcon icon={p.icon} fallback={p.title} size={16} />\n <span className=\"truncate\">{p.title}</span>\n </span>\n }\n subtitle={p.parent_path || undefined}\n status={p.archived ? { label: \"archived\", variant: \"muted\" } : undefined}\n action={{ label: \"Open in Notion\", href: url }}\n />\n\n <div className=\"px-4 py-3 flex flex-col gap-3\">\n {/* last-edited byline โ€” always shown */}\n <div className=\"flex items-center gap-2 text-xs\">\n {p.last_edited_by && (\n <Avatar src={p.last_edited_by_avatar} name={p.last_edited_by} size={18} />\n )}\n {p.last_edited_by && (\n <span className=\"text-text font-medium\">{p.last_edited_by}</span>\n )}\n <span className=\"text-text-dim\">edited {timeAgo(p.last_edited_at)}</span>\n </div>\n\n {/* properties โ€” only when it's a database row */}\n {props_kv.length > 0 && (\n <DataList items={props_kv} />\n )}\n\n {/* excerpt โ€” first block of page content if available */}\n {p.excerpt && (\n <p className=\"text-sm text-text whitespace-pre-wrap break-words leading-relaxed line-clamp-4\">\n {p.excerpt}\n </p>\n )}\n </div>\n </Card>\n );\n}\n\n//\"Status=In progress, Owner=ari\" โ†’ DataList items\nfunction parseProperties(raw: string): { label: string; value: string }[] {\n if (!raw) return [];\n return raw\n .split(\",\")\n .map((entry) => entry.trim())\n .filter(Boolean)\n .map((entry) => {\n const eq = entry.indexOf(\"= \");\n if (eq === -1) return { label: entry, value: \"\" };\n return { label: entry.slice(0, eq).trim(), value: entry.slice(eq + 1).trim() };\n });\n}\n",
6
+ "// Shared helpers for every Notion UI component.\n//\n// * notionVendor โ€” CardHeader brand pill (logo + name + color)\n// * URL builders โ€” page, database, search, comment\n// * formatters โ€” relative time, page-icon resolver, property-value\n// pretty-printer for typed Notion properties\n//\n// Mirrors the lib/hubspot.tsx / lib/github.tsx pattern: every vendor\n// lib has the same shape (logo + vendor + URLs + helpers).\n\nimport type { ReactNode } from \"react\";\nimport type { CardVendor } from \"@apteva/ui-kit\";\n\n// โ”€โ”€โ”€ Brand mark โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n//\n// Notion's mark is famously a stylized\"N\". currentColor so\n// CardHeader's vendor pill recolors it via inline `style.color`.\n\nexport const notionLogo: ReactNode = (\n <svg viewBox=\"0 0 32 32\" width=\"14\" height=\"14\" fill=\"currentColor\" aria-hidden>\n <path d=\"M5 4.7l3.4 2.3a1 1 0 00.8.2l16-1.6c.5-.1 1 .2 1 .7v18.4c0 .5-.4.9-.9.9L8 26.2c-.5 0-1-.3-1.2-.7l-1.7-3.4V4.7zm4 4.5v15l16-.9V8.3l-16 .9zm3.4 2.3v9.3l1.7.1V13l4.7 7.7 1.6.1v-9.4l-1.7-.1v6.6l-4.6-7.4-1.7.1z\" />\n </svg>\n);\n\n// Notion's brand is famously monochrome โ€” black on light surfaces,\n// white on dark. The single-color form would render unreadable on\n// a dark card (#191919 text on #1c1c1f bg), so we ship a {light,\n// dark} pair and CardHeader picks per active mode.\nexport const NOTION_BRAND_COLOR = { light: \"#191919\", dark: \"#e8e8e8\" };\n\nexport const notionVendor: CardVendor = {\n name: \"Notion\",\n logo: notionLogo,\n color: NOTION_BRAND_COLOR,\n};\n\n// โ”€โ”€โ”€ URL builders โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n//\n// Notion pages are addressable by id with dashes stripped. A page or\n// database canonical URL is `https://www.notion.so/<id-no-dashes>`.\n// When a workspace slug is known (e.g.\"apteva\"), the URL becomes\n// `https://www.notion.so/apteva/<id>` โ€” same target, prettier link.\n\nfunction bareId(id: string | undefined | null): string {\n if (!id) return \"\";\n return id.replace(/-/g,\"\");\n}\n\nexport function pageUrl(id: string, workspace?: string): string {\n const slug = workspace ? `${encodeURIComponent(workspace)}/` :\"\";\n return `https://www.notion.so/${slug}${bareId(id)}`;\n}\n\nexport function databaseUrl(id: string, workspace?: string): string {\n return pageUrl(id, workspace);\n}\n\nexport function searchUrl(query: string): string {\n return `https://www.notion.so/search?query=${encodeURIComponent(query)}`;\n}\n\n// โ”€โ”€โ”€ Formatters โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n\n/**\"3d ago\" /\"12m ago\" /\"just now\". */\nexport function timeAgo(iso?: string): string {\n if (!iso) return \"\";\n const t = new Date(iso).getTime();\n if (!Number.isFinite(t)) return \"\";\n const s = Math.max(0, (Date.now() - t) / 1000);\n if (s < 60) return \"just now\";\n const m = s / 60; if (m < 60) return `${Math.round(m)}m ago`;\n const h = m / 60; if (h < 24) return `${Math.round(h)}h ago`;\n const d = h / 24; if (d < 30) return `${Math.round(d)}d ago`;\n const mo = d / 30; if (mo < 12) return `${Math.round(mo)}mo ago`;\n return `${Math.round(mo / 12)}y ago`;\n}\n\n/** Test fixture helper โ€” same shape as the other libs. */\nexport function minusHoursISO(h: number): string {\n return new Date(Date.now() - h * 60 * 60 * 1000).toISOString();\n}\n\n// โ”€โ”€โ”€ Page icon โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n//\n// Notion pages can have:\n// - an emoji icon (single grapheme, e.g.\"๐Ÿ“‹\")\n// - an image icon (https URL)\n// - nothing โ€” fall back to a generic doc glyph\n//\n// `PageIcon` covers all three. Sized via the `size` prop in pixels.\n\ninterface PageIconProps {\n /** Emoji string OR https URL. Anything else is treated as nothing. */\n icon?: string | null;\n /** Optional: render this letter when there's no icon (page title's\n * initial usually). Falls back to a generic doc glyph if absent. */\n fallback?: string;\n size?: number;\n className?: string;\n}\n\nexport function PageIcon({ icon, fallback, size = 18, className = \"\" }: PageIconProps) {\n const style = { width: size, height: size, fontSize: Math.round(size * 0.66) };\n const isUrl = !!icon && /^https?:\\/\\//i.test(icon);\n const isEmoji = !!icon && !isUrl && Array.from(icon).length <= 3;\n\n if (isUrl) {\n return (\n <img\n src={icon!}\n alt=\"\"\n className={`rounded-sm flex-shrink-0 object-cover ${className}`}\n style={style}\n />\n );\n }\n if (isEmoji) {\n return (\n <span\n aria-hidden\n className={`flex-shrink-0 inline-flex items-center justify-center leading-none ${className}`}\n style={style}\n >\n {icon}\n </span>\n );\n }\n // Generic doc fallback โ€” minimal page glyph, monochrome.\n return (\n <span\n aria-hidden\n className={`flex-shrink-0 inline-flex items-center justify-center rounded-sm bg-bg-hover text-text-dim font-medium ${className}`}\n style={style}\n >\n {fallback ? fallback.charAt(0).toUpperCase() : \"ยท\"}\n </span>\n );\n}\n\n// โ”€โ”€โ”€ Schema parsing โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n//\n// Agents pass database schemas as a comma-separated\"name:type\"\n// list (e.g.\"Status:select,Owner:person,Due:date\"). This parses\n// into a typed array; the cards then render each entry as a small\n// pill with type-specific tint.\n\nexport type NotionPropType =\n |\"title\" |\"rich_text\" |\"select\" |\"multi_select\"\n |\"person\" |\"date\" |\"checkbox\" |\"number\"\n |\"url\" |\"email\" |\"phone\" |\"files\" |\"formula\" |\"relation\"\n |\"rollup\" |\"status\" |\"created_time\" |\"last_edited_time\"\n |\"created_by\" |\"last_edited_by\";\n\nexport interface NotionPropDef { name: string; type: NotionPropType }\n\nexport function parseSchema(raw?: string): NotionPropDef[] {\n if (!raw) return [];\n return raw.split(\",\").map((s) => {\n const [name, type] = s.split(\":\").map((x) => x.trim());\n return { name: name || \"โ€”\", type: ((type || \"rich_text\") as NotionPropType) };\n });\n}\n\n/** Type โ†’ tone class for the schema pills. */\nexport function propTone(type: NotionPropType): string {\n switch (type) {\n case \"select\":\n case \"status\": return \"bg-accent/10 text-blue-700 dark:bg-accent/15 dark:text-blue-400\";\n case \"multi_select\": return \"bg-purple-500/10 text-purple-700 dark:bg-purple-500/15 dark:text-purple-400\";\n case \"person\":\n case \"created_by\":\n case \"last_edited_by\": return \"bg-emerald-500/10 text-emerald-700 dark:bg-emerald-500/15 dark:text-emerald-400\";\n case \"date\":\n case \"created_time\":\n case \"last_edited_time\": return \"bg-warn/10 text-amber-700 dark:bg-warn/15 dark:text-amber-400\";\n case \"checkbox\": return \"bg-bg-hover text-text dark:bg-bg-hover dark:text-zinc-300\";\n case \"number\": return \"bg-cyan-500/10 text-cyan-700 dark:bg-cyan-500/15 dark:text-cyan-400\";\n default: return \"bg-zinc-100 text-text dark:bg-bg-hover dark:text-zinc-300\";\n }\n}\n"
7
+ ],
8
+ "mappings": "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",
9
+ "debugId": "6AC199DED57DE0CD64756E2164756E21",
10
+ "names": []
11
+ }
@@ -0,0 +1,24 @@
1
+ interface PageItem {
2
+ page_id: string;
3
+ title: string;
4
+ icon?: string;
5
+ /** Breadcrumb up to the page โ€”"Apteva โ€บ Engineering". */
6
+ parent_path?: string;
7
+ last_edited_at?: string;
8
+ last_edited_by?: string;
9
+ }
10
+ interface Props {
11
+ /** Optional title for the strip โ€”"Recent pages","Search results". */
12
+ label?: string;
13
+ workspace?: string;
14
+ /** Where the"Open in Notion" link goes (search-results URL,
15
+ * workspace home, etc.). When omitted, no header action. */
16
+ url?: string;
17
+ pages?: PageItem[] | string;
18
+ max?: number;
19
+ preview?: boolean;
20
+ projectId?: string;
21
+ }
22
+ export default function PageList(props: Props): import("react").JSX.Element;
23
+ export {};
24
+ //# sourceMappingURL=PageList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageList.d.ts","sourceRoot":"","sources":["../../../src/ui/notion/PageList.tsx"],"names":[],"mappings":"AAOA,UAAU,QAAQ;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,KAAK;IACd,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;+DAC2D;IAC3D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAUD,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,KAAK,EAAE,KAAK,+BAiD5C"}
@@ -0,0 +1,51 @@
1
+ // PageList โ€” search results / recent pages, simpler than
2
+ // DatabaseRowList because pages aren't typed. Each row is just
3
+ // title + parent breadcrumb + last-edited byline.
4
+ import { Card, CardHeader, Row } from "@apteva/ui-kit";
5
+ import { notionVendor, pageUrl, PageIcon, timeAgo } from "./lib/notion";
6
+ const previewPages = [
7
+ { page_id: "abc1", title: "Q4 engineering roadmap", icon: "๐Ÿ“‹", parent_path: "Apteva โ€บ Engineering", last_edited_at: new Date(Date.now() - 12 * 60 * 1000).toISOString(), last_edited_by: "marc-olivier" },
8
+ { page_id: "abc2", title: "Bug triage โ€” Sprint 23", icon: "๐Ÿ›", parent_path: "Apteva โ€บ Engineering", last_edited_at: new Date(Date.now() - 1 * 60 * 60 * 1000).toISOString(), last_edited_by: "ari" },
9
+ { page_id: "abc3", title: "Quarterly metrics dashboard", icon: "๐Ÿ“Š", parent_path: "Apteva โ€บ Analytics", last_edited_at: new Date(Date.now() - 3 * 60 * 60 * 1000).toISOString(), last_edited_by: "lin" },
10
+ { page_id: "abc4", title: "Feature kickoff โ€” idempotency", icon: "โœจ", parent_path: "Apteva โ€บ Engineering โ€บ Specs", last_edited_at: new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString(), last_edited_by: "maya" },
11
+ { page_id: "abc5", title: "Engineering offsite agenda", icon: "๐Ÿ“", parent_path: "Apteva โ€บ Team", last_edited_at: new Date(Date.now() - 48 * 60 * 60 * 1000).toISOString(), last_edited_by: "ari" },
12
+ ];
13
+ export default function PageList(props) {
14
+ const pages = props.preview
15
+ ? previewPages
16
+ : (parseList(props.pages) ?? []);
17
+ const max = props.max ?? 10;
18
+ const visible = pages.slice(0, max);
19
+ const overflow = pages.length - visible.length;
20
+ const label = props.label ?? (props.preview ? "Recent pages" : "Pages");
21
+ const subtitle = pages.length === 0
22
+ ? "No pages"
23
+ : `${pages.length} page${pages.length === 1 ? "" : "s"}`;
24
+ return (<Card fullWidth>
25
+ <CardHeader vendor={notionVendor} title={label} subtitle={subtitle} action={props.url ? { label: "Open in Notion", href: props.url } : undefined}/>
26
+
27
+ <div className="flex flex-col">
28
+ {visible.map((page, i) => (<Row key={page.page_id} flush={i === 0} href={pageUrl(page.page_id, props.workspace)} leading={<PageIcon icon={page.icon} fallback={page.title} size={18}/>} title={page.title} subtitle={page.parent_path} trailing={<span className="inline-flex items-center gap-1.5 text-text-dim">
29
+ {page.last_edited_by && <span>{page.last_edited_by}</span>}
30
+ {page.last_edited_at && (<span className="tabular-nums">ยท {timeAgo(page.last_edited_at)}</span>)}
31
+ </span>}/>))}
32
+ {overflow > 0 && (<div className="px-4 py-2 text-xs text-text-dim border-t border-border">
33
+ +{overflow} more
34
+ </div>)}
35
+ </div>
36
+ </Card>);
37
+ }
38
+ function parseList(raw) {
39
+ if (!raw)
40
+ return null;
41
+ if (Array.isArray(raw))
42
+ return raw;
43
+ try {
44
+ const parsed = JSON.parse(raw);
45
+ return Array.isArray(parsed) ? parsed : null;
46
+ }
47
+ catch {
48
+ return null;
49
+ }
50
+ }
51
+ //# sourceMappingURL=PageList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PageList.js","sourceRoot":"","sources":["../../../src/ui/notion/PageList.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import{Card as T,CardHeader as W,Row as _}from"@apteva/ui-kit";import{jsx as Y}from"react/jsx-runtime";var q=Y("svg",{viewBox:"0 0 32 32",width:"14",height:"14",fill:"currentColor","aria-hidden":!0,children:Y("path",{d:"M5 4.7l3.4 2.3a1 1 0 00.8.2l16-1.6c.5-.1 1 .2 1 .7v18.4c0 .5-.4.9-.9.9L8 26.2c-.5 0-1-.3-1.2-.7l-1.7-3.4V4.7zm4 4.5v15l16-.9V8.3l-16 .9zm3.4 2.3v9.3l1.7.1V13l4.7 7.7 1.6.1v-9.4l-1.7-.1v6.6l-4.6-7.4-1.7.1z"})}),A={light:"#191919",dark:"#e8e8e8"},B={name:"Notion",logo:q,color:A};function P(F){if(!F)return"";return F.replace(/-/g,"")}function D(F,G){return`https://www.notion.so/${G?`${encodeURIComponent(G)}/`:""}${P(F)}`}function E(F){if(!F)return"";let G=new Date(F).getTime();if(!Number.isFinite(G))return"";let Q=Math.max(0,(Date.now()-G)/1000);if(Q<60)return"just now";let J=Q/60;if(J<60)return`${Math.round(J)}m ago`;let K=J/60;if(K<24)return`${Math.round(K)}h ago`;let S=K/24;if(S<30)return`${Math.round(S)}d ago`;let X=S/30;if(X<12)return`${Math.round(X)}mo ago`;return`${Math.round(X/12)}y ago`}function H({icon:F,fallback:G,size:Q=18,className:J=""}){let K={width:Q,height:Q,fontSize:Math.round(Q*0.66)},S=!!F&&/^https?:\/\//i.test(F),X=!!F&&!S&&Array.from(F).length<=3;if(S)return Y("img",{src:F,alt:"",className:`rounded-sm flex-shrink-0 object-cover ${J}`,style:K});if(X)return Y("span",{"aria-hidden":!0,className:`flex-shrink-0 inline-flex items-center justify-center leading-none ${J}`,style:K,children:F});return Y("span",{"aria-hidden":!0,className:`flex-shrink-0 inline-flex items-center justify-center rounded-sm bg-bg-hover text-text-dim font-medium ${J}`,style:K,children:G?G.charAt(0).toUpperCase():"ยท"})}import{jsx as $,jsxs as Z}from"react/jsx-runtime";var C=[{page_id:"abc1",title:"Q4 engineering roadmap",icon:"\uD83D\uDCCB",parent_path:"Apteva โ€บ Engineering",last_edited_at:new Date(Date.now()-720000).toISOString(),last_edited_by:"marc-olivier"},{page_id:"abc2",title:"Bug triage โ€” Sprint 23",icon:"\uD83D\uDC1B",parent_path:"Apteva โ€บ Engineering",last_edited_at:new Date(Date.now()-3600000).toISOString(),last_edited_by:"ari"},{page_id:"abc3",title:"Quarterly metrics dashboard",icon:"\uD83D\uDCCA",parent_path:"Apteva โ€บ Analytics",last_edited_at:new Date(Date.now()-10800000).toISOString(),last_edited_by:"lin"},{page_id:"abc4",title:"Feature kickoff โ€” idempotency",icon:"โœจ",parent_path:"Apteva โ€บ Engineering โ€บ Specs",last_edited_at:new Date(Date.now()-86400000).toISOString(),last_edited_by:"maya"},{page_id:"abc5",title:"Engineering offsite agenda",icon:"\uD83D\uDCDD",parent_path:"Apteva โ€บ Team",last_edited_at:new Date(Date.now()-172800000).toISOString(),last_edited_by:"ari"}];function I(F){let G=F.preview?C:L(F.pages)??[],Q=F.max??10,J=G.slice(0,Q),K=G.length-J.length,S=F.label??(F.preview?"Recent pages":"Pages"),X=G.length===0?"No pages":`${G.length} page${G.length===1?"":"s"}`;return Z(T,{fullWidth:!0,children:[$(W,{vendor:B,title:S,subtitle:X,action:F.url?{label:"Open in Notion",href:F.url}:void 0}),Z("div",{className:"flex flex-col",children:[J.map((M,V)=>$(_,{flush:V===0,href:D(M.page_id,F.workspace),leading:$(H,{icon:M.icon,fallback:M.title,size:18}),title:M.title,subtitle:M.parent_path,trailing:Z("span",{className:"inline-flex items-center gap-1.5 text-text-dim",children:[M.last_edited_by&&$("span",{children:M.last_edited_by}),M.last_edited_at&&Z("span",{className:"tabular-nums",children:["ยท ",E(M.last_edited_at)]})]})},M.page_id)),K>0&&Z("div",{className:"px-4 py-2 text-xs text-text-dim border-t border-border",children:["+",K," more"]})]})]})}function L(F){if(!F)return null;if(Array.isArray(F))return F;try{let G=JSON.parse(F);return Array.isArray(G)?G:null}catch{return null}}export{I as default};
2
+
3
+ //# debugId=66F38D421DFA1CDA64756E2164756E21
@@ -0,0 +1,11 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/ui/notion/PageList.tsx", "../../../src/ui/notion/lib/notion.tsx"],
4
+ "sourcesContent": [
5
+ "// PageList โ€” search results / recent pages, simpler than\n// DatabaseRowList because pages aren't typed. Each row is just\n// title + parent breadcrumb + last-edited byline.\n\nimport { Card, CardHeader, Row } from \"@apteva/ui-kit\";\nimport { notionVendor, pageUrl, PageIcon, timeAgo } from \"./lib/notion\";\n\ninterface PageItem {\n page_id: string;\n title: string;\n icon?: string;\n /** Breadcrumb up to the page โ€”\"Apteva โ€บ Engineering\". */\n parent_path?: string;\n last_edited_at?: string;\n last_edited_by?: string;\n}\n\ninterface Props {\n /** Optional title for the strip โ€”\"Recent pages\",\"Search results\". */\n label?: string;\n workspace?: string;\n /** Where the\"Open in Notion\" link goes (search-results URL,\n * workspace home, etc.). When omitted, no header action. */\n url?: string;\n pages?: PageItem[] | string;\n max?: number;\n preview?: boolean;\n projectId?: string;\n}\n\nconst previewPages: PageItem[] = [\n { page_id: \"abc1\", title: \"Q4 engineering roadmap\", icon: \"๐Ÿ“‹\", parent_path: \"Apteva โ€บ Engineering\", last_edited_at: new Date(Date.now() - 12 * 60 * 1000).toISOString(), last_edited_by: \"marc-olivier\" },\n { page_id: \"abc2\", title: \"Bug triage โ€” Sprint 23\", icon: \"๐Ÿ›\", parent_path: \"Apteva โ€บ Engineering\", last_edited_at: new Date(Date.now() - 1 * 60 * 60 * 1000).toISOString(), last_edited_by: \"ari\" },\n { page_id: \"abc3\", title: \"Quarterly metrics dashboard\", icon: \"๐Ÿ“Š\", parent_path: \"Apteva โ€บ Analytics\", last_edited_at: new Date(Date.now() - 3 * 60 * 60 * 1000).toISOString(), last_edited_by: \"lin\" },\n { page_id: \"abc4\", title: \"Feature kickoff โ€” idempotency\", icon: \"โœจ\", parent_path: \"Apteva โ€บ Engineering โ€บ Specs\", last_edited_at: new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString(), last_edited_by: \"maya\" },\n { page_id: \"abc5\", title: \"Engineering offsite agenda\", icon: \"๐Ÿ“\", parent_path: \"Apteva โ€บ Team\", last_edited_at: new Date(Date.now() - 48 * 60 * 60 * 1000).toISOString(), last_edited_by: \"ari\" },\n];\n\nexport default function PageList(props: Props) {\n const pages = props.preview\n ? previewPages\n : (parseList(props.pages) ?? []);\n const max = props.max ?? 10;\n const visible = pages.slice(0, max);\n const overflow = pages.length - visible.length;\n\n const label = props.label ?? (props.preview ? \"Recent pages\" :\"Pages\");\n const subtitle = pages.length === 0\n ? \"No pages\"\n : `${pages.length} page${pages.length === 1 ? \"\" :\"s\"}`;\n\n return (\n <Card fullWidth>\n <CardHeader\n vendor={notionVendor}\n title={label}\n subtitle={subtitle}\n action={props.url ? { label: \"Open in Notion\", href: props.url } : undefined}\n />\n\n <div className=\"flex flex-col\">\n {visible.map((page, i) => (\n <Row\n key={page.page_id}\n flush={i === 0}\n href={pageUrl(page.page_id, props.workspace)}\n leading={<PageIcon icon={page.icon} fallback={page.title} size={18} />}\n title={page.title}\n subtitle={page.parent_path}\n trailing={\n <span className=\"inline-flex items-center gap-1.5 text-text-dim\">\n {page.last_edited_by && <span>{page.last_edited_by}</span>}\n {page.last_edited_at && (\n <span className=\"tabular-nums\">ยท {timeAgo(page.last_edited_at)}</span>\n )}\n </span>\n }\n />\n ))}\n {overflow > 0 && (\n <div className=\"px-4 py-2 text-xs text-text-dim border-t border-border\">\n +{overflow} more\n </div>\n )}\n </div>\n </Card>\n );\n}\n\nfunction parseList(raw: PageItem[] | string | undefined): PageItem[] | null {\n if (!raw) return null;\n if (Array.isArray(raw)) return raw;\n try {\n const parsed = JSON.parse(raw);\n return Array.isArray(parsed) ? parsed : null;\n } catch {\n return null;\n }\n}\n",
6
+ "// Shared helpers for every Notion UI component.\n//\n// * notionVendor โ€” CardHeader brand pill (logo + name + color)\n// * URL builders โ€” page, database, search, comment\n// * formatters โ€” relative time, page-icon resolver, property-value\n// pretty-printer for typed Notion properties\n//\n// Mirrors the lib/hubspot.tsx / lib/github.tsx pattern: every vendor\n// lib has the same shape (logo + vendor + URLs + helpers).\n\nimport type { ReactNode } from \"react\";\nimport type { CardVendor } from \"@apteva/ui-kit\";\n\n// โ”€โ”€โ”€ Brand mark โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n//\n// Notion's mark is famously a stylized\"N\". currentColor so\n// CardHeader's vendor pill recolors it via inline `style.color`.\n\nexport const notionLogo: ReactNode = (\n <svg viewBox=\"0 0 32 32\" width=\"14\" height=\"14\" fill=\"currentColor\" aria-hidden>\n <path d=\"M5 4.7l3.4 2.3a1 1 0 00.8.2l16-1.6c.5-.1 1 .2 1 .7v18.4c0 .5-.4.9-.9.9L8 26.2c-.5 0-1-.3-1.2-.7l-1.7-3.4V4.7zm4 4.5v15l16-.9V8.3l-16 .9zm3.4 2.3v9.3l1.7.1V13l4.7 7.7 1.6.1v-9.4l-1.7-.1v6.6l-4.6-7.4-1.7.1z\" />\n </svg>\n);\n\n// Notion's brand is famously monochrome โ€” black on light surfaces,\n// white on dark. The single-color form would render unreadable on\n// a dark card (#191919 text on #1c1c1f bg), so we ship a {light,\n// dark} pair and CardHeader picks per active mode.\nexport const NOTION_BRAND_COLOR = { light: \"#191919\", dark: \"#e8e8e8\" };\n\nexport const notionVendor: CardVendor = {\n name: \"Notion\",\n logo: notionLogo,\n color: NOTION_BRAND_COLOR,\n};\n\n// โ”€โ”€โ”€ URL builders โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n//\n// Notion pages are addressable by id with dashes stripped. A page or\n// database canonical URL is `https://www.notion.so/<id-no-dashes>`.\n// When a workspace slug is known (e.g.\"apteva\"), the URL becomes\n// `https://www.notion.so/apteva/<id>` โ€” same target, prettier link.\n\nfunction bareId(id: string | undefined | null): string {\n if (!id) return \"\";\n return id.replace(/-/g,\"\");\n}\n\nexport function pageUrl(id: string, workspace?: string): string {\n const slug = workspace ? `${encodeURIComponent(workspace)}/` :\"\";\n return `https://www.notion.so/${slug}${bareId(id)}`;\n}\n\nexport function databaseUrl(id: string, workspace?: string): string {\n return pageUrl(id, workspace);\n}\n\nexport function searchUrl(query: string): string {\n return `https://www.notion.so/search?query=${encodeURIComponent(query)}`;\n}\n\n// โ”€โ”€โ”€ Formatters โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n\n/**\"3d ago\" /\"12m ago\" /\"just now\". */\nexport function timeAgo(iso?: string): string {\n if (!iso) return \"\";\n const t = new Date(iso).getTime();\n if (!Number.isFinite(t)) return \"\";\n const s = Math.max(0, (Date.now() - t) / 1000);\n if (s < 60) return \"just now\";\n const m = s / 60; if (m < 60) return `${Math.round(m)}m ago`;\n const h = m / 60; if (h < 24) return `${Math.round(h)}h ago`;\n const d = h / 24; if (d < 30) return `${Math.round(d)}d ago`;\n const mo = d / 30; if (mo < 12) return `${Math.round(mo)}mo ago`;\n return `${Math.round(mo / 12)}y ago`;\n}\n\n/** Test fixture helper โ€” same shape as the other libs. */\nexport function minusHoursISO(h: number): string {\n return new Date(Date.now() - h * 60 * 60 * 1000).toISOString();\n}\n\n// โ”€โ”€โ”€ Page icon โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n//\n// Notion pages can have:\n// - an emoji icon (single grapheme, e.g.\"๐Ÿ“‹\")\n// - an image icon (https URL)\n// - nothing โ€” fall back to a generic doc glyph\n//\n// `PageIcon` covers all three. Sized via the `size` prop in pixels.\n\ninterface PageIconProps {\n /** Emoji string OR https URL. Anything else is treated as nothing. */\n icon?: string | null;\n /** Optional: render this letter when there's no icon (page title's\n * initial usually). Falls back to a generic doc glyph if absent. */\n fallback?: string;\n size?: number;\n className?: string;\n}\n\nexport function PageIcon({ icon, fallback, size = 18, className = \"\" }: PageIconProps) {\n const style = { width: size, height: size, fontSize: Math.round(size * 0.66) };\n const isUrl = !!icon && /^https?:\\/\\//i.test(icon);\n const isEmoji = !!icon && !isUrl && Array.from(icon).length <= 3;\n\n if (isUrl) {\n return (\n <img\n src={icon!}\n alt=\"\"\n className={`rounded-sm flex-shrink-0 object-cover ${className}`}\n style={style}\n />\n );\n }\n if (isEmoji) {\n return (\n <span\n aria-hidden\n className={`flex-shrink-0 inline-flex items-center justify-center leading-none ${className}`}\n style={style}\n >\n {icon}\n </span>\n );\n }\n // Generic doc fallback โ€” minimal page glyph, monochrome.\n return (\n <span\n aria-hidden\n className={`flex-shrink-0 inline-flex items-center justify-center rounded-sm bg-bg-hover text-text-dim font-medium ${className}`}\n style={style}\n >\n {fallback ? fallback.charAt(0).toUpperCase() : \"ยท\"}\n </span>\n );\n}\n\n// โ”€โ”€โ”€ Schema parsing โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€\n//\n// Agents pass database schemas as a comma-separated\"name:type\"\n// list (e.g.\"Status:select,Owner:person,Due:date\"). This parses\n// into a typed array; the cards then render each entry as a small\n// pill with type-specific tint.\n\nexport type NotionPropType =\n |\"title\" |\"rich_text\" |\"select\" |\"multi_select\"\n |\"person\" |\"date\" |\"checkbox\" |\"number\"\n |\"url\" |\"email\" |\"phone\" |\"files\" |\"formula\" |\"relation\"\n |\"rollup\" |\"status\" |\"created_time\" |\"last_edited_time\"\n |\"created_by\" |\"last_edited_by\";\n\nexport interface NotionPropDef { name: string; type: NotionPropType }\n\nexport function parseSchema(raw?: string): NotionPropDef[] {\n if (!raw) return [];\n return raw.split(\",\").map((s) => {\n const [name, type] = s.split(\":\").map((x) => x.trim());\n return { name: name || \"โ€”\", type: ((type || \"rich_text\") as NotionPropType) };\n });\n}\n\n/** Type โ†’ tone class for the schema pills. */\nexport function propTone(type: NotionPropType): string {\n switch (type) {\n case \"select\":\n case \"status\": return \"bg-accent/10 text-blue-700 dark:bg-accent/15 dark:text-blue-400\";\n case \"multi_select\": return \"bg-purple-500/10 text-purple-700 dark:bg-purple-500/15 dark:text-purple-400\";\n case \"person\":\n case \"created_by\":\n case \"last_edited_by\": return \"bg-emerald-500/10 text-emerald-700 dark:bg-emerald-500/15 dark:text-emerald-400\";\n case \"date\":\n case \"created_time\":\n case \"last_edited_time\": return \"bg-warn/10 text-amber-700 dark:bg-warn/15 dark:text-amber-400\";\n case \"checkbox\": return \"bg-bg-hover text-text dark:bg-bg-hover dark:text-zinc-300\";\n case \"number\": return \"bg-cyan-500/10 text-cyan-700 dark:bg-cyan-500/15 dark:text-cyan-400\";\n default: return \"bg-zinc-100 text-text dark:bg-bg-hover dark:text-zinc-300\";\n }\n}\n"
7
+ ],
8
+ "mappings": "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",
9
+ "debugId": "66F38D421DFA1CDA64756E2164756E21",
10
+ "names": []
11
+ }