@hasna/connectors 0.4.0 → 0.4.2

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 (390) hide show
  1. package/bin/index.js +189 -2
  2. package/bin/mcp.js +176 -1
  3. package/bin/serve.js +175 -0
  4. package/connectors/connect-airtable/.env.example +11 -0
  5. package/connectors/connect-airtable/CLAUDE.md +121 -0
  6. package/connectors/connect-airtable/README.md +193 -0
  7. package/connectors/connect-airtable/package.json +50 -0
  8. package/connectors/connect-airtable/src/api/client.ts +139 -0
  9. package/connectors/connect-airtable/src/api/index.ts +405 -0
  10. package/connectors/connect-airtable/src/cli/index.ts +637 -0
  11. package/connectors/connect-airtable/src/index.ts +20 -0
  12. package/connectors/connect-airtable/src/types/index.ts +349 -0
  13. package/connectors/connect-airtable/src/utils/config.ts +197 -0
  14. package/connectors/connect-airtable/tsconfig.json +16 -0
  15. package/connectors/connect-amplitude/.env.example +11 -0
  16. package/connectors/connect-amplitude/CLAUDE.md +121 -0
  17. package/connectors/connect-amplitude/README.md +193 -0
  18. package/connectors/connect-amplitude/package.json +51 -0
  19. package/connectors/connect-amplitude/src/api/client.ts +144 -0
  20. package/connectors/connect-amplitude/src/api/index.ts +215 -0
  21. package/connectors/connect-amplitude/src/cli/index.ts +532 -0
  22. package/connectors/connect-amplitude/src/index.ts +22 -0
  23. package/connectors/connect-amplitude/src/types/index.ts +329 -0
  24. package/connectors/connect-amplitude/src/utils/config.ts +208 -0
  25. package/connectors/connect-amplitude/tsconfig.json +16 -0
  26. package/connectors/connect-calendly/.env.example +11 -0
  27. package/connectors/connect-calendly/CLAUDE.md +272 -0
  28. package/connectors/connect-calendly/README.md +193 -0
  29. package/connectors/connect-calendly/package.json +51 -0
  30. package/connectors/connect-calendly/scripts/release.ts +179 -0
  31. package/connectors/connect-calendly/src/api/client.ts +213 -0
  32. package/connectors/connect-calendly/src/api/example.ts +48 -0
  33. package/connectors/connect-calendly/src/api/index.ts +51 -0
  34. package/connectors/connect-calendly/src/cli/index.ts +254 -0
  35. package/connectors/connect-calendly/src/index.ts +103 -0
  36. package/connectors/connect-calendly/src/types/index.ts +237 -0
  37. package/connectors/connect-calendly/src/utils/auth.ts +274 -0
  38. package/connectors/connect-calendly/src/utils/bulk.ts +212 -0
  39. package/connectors/connect-calendly/src/utils/config.ts +326 -0
  40. package/connectors/connect-calendly/src/utils/output.ts +175 -0
  41. package/connectors/connect-calendly/src/utils/settings.ts +114 -0
  42. package/connectors/connect-calendly/src/utils/storage.ts +198 -0
  43. package/connectors/connect-calendly/tsconfig.json +16 -0
  44. package/connectors/connect-convertkit/.env.example +11 -0
  45. package/connectors/connect-convertkit/CLAUDE.md +272 -0
  46. package/connectors/connect-convertkit/README.md +193 -0
  47. package/connectors/connect-convertkit/package.json +51 -0
  48. package/connectors/connect-convertkit/scripts/release.ts +179 -0
  49. package/connectors/connect-convertkit/src/api/client.ts +213 -0
  50. package/connectors/connect-convertkit/src/api/example.ts +48 -0
  51. package/connectors/connect-convertkit/src/api/index.ts +51 -0
  52. package/connectors/connect-convertkit/src/cli/index.ts +254 -0
  53. package/connectors/connect-convertkit/src/index.ts +103 -0
  54. package/connectors/connect-convertkit/src/types/index.ts +237 -0
  55. package/connectors/connect-convertkit/src/utils/auth.ts +274 -0
  56. package/connectors/connect-convertkit/src/utils/bulk.ts +212 -0
  57. package/connectors/connect-convertkit/src/utils/config.ts +326 -0
  58. package/connectors/connect-convertkit/src/utils/output.ts +175 -0
  59. package/connectors/connect-convertkit/src/utils/settings.ts +114 -0
  60. package/connectors/connect-convertkit/src/utils/storage.ts +198 -0
  61. package/connectors/connect-convertkit/tsconfig.json +16 -0
  62. package/connectors/connect-crisp/.env.example +11 -0
  63. package/connectors/connect-crisp/CLAUDE.md +272 -0
  64. package/connectors/connect-crisp/README.md +193 -0
  65. package/connectors/connect-crisp/package.json +51 -0
  66. package/connectors/connect-crisp/scripts/release.ts +179 -0
  67. package/connectors/connect-crisp/src/api/client.ts +213 -0
  68. package/connectors/connect-crisp/src/api/example.ts +48 -0
  69. package/connectors/connect-crisp/src/api/index.ts +51 -0
  70. package/connectors/connect-crisp/src/cli/index.ts +254 -0
  71. package/connectors/connect-crisp/src/index.ts +103 -0
  72. package/connectors/connect-crisp/src/types/index.ts +237 -0
  73. package/connectors/connect-crisp/src/utils/auth.ts +274 -0
  74. package/connectors/connect-crisp/src/utils/bulk.ts +212 -0
  75. package/connectors/connect-crisp/src/utils/config.ts +326 -0
  76. package/connectors/connect-crisp/src/utils/output.ts +175 -0
  77. package/connectors/connect-crisp/src/utils/settings.ts +114 -0
  78. package/connectors/connect-crisp/src/utils/storage.ts +198 -0
  79. package/connectors/connect-crisp/tsconfig.json +16 -0
  80. package/connectors/connect-docusign/.env.example +11 -0
  81. package/connectors/connect-docusign/CLAUDE.md +128 -0
  82. package/connectors/connect-docusign/README.md +193 -0
  83. package/connectors/connect-docusign/package.json +52 -0
  84. package/connectors/connect-docusign/src/api/client.ts +133 -0
  85. package/connectors/connect-docusign/src/api/index.ts +178 -0
  86. package/connectors/connect-docusign/src/cli/index.ts +381 -0
  87. package/connectors/connect-docusign/src/index.ts +23 -0
  88. package/connectors/connect-docusign/src/types/index.ts +208 -0
  89. package/connectors/connect-docusign/src/utils/config.ts +125 -0
  90. package/connectors/connect-docusign/src/utils/output.ts +119 -0
  91. package/connectors/connect-docusign/tsconfig.json +16 -0
  92. package/connectors/connect-drift/.env.example +11 -0
  93. package/connectors/connect-drift/CLAUDE.md +272 -0
  94. package/connectors/connect-drift/README.md +193 -0
  95. package/connectors/connect-drift/package.json +51 -0
  96. package/connectors/connect-drift/scripts/release.ts +179 -0
  97. package/connectors/connect-drift/src/api/client.ts +213 -0
  98. package/connectors/connect-drift/src/api/example.ts +48 -0
  99. package/connectors/connect-drift/src/api/index.ts +51 -0
  100. package/connectors/connect-drift/src/cli/index.ts +254 -0
  101. package/connectors/connect-drift/src/index.ts +103 -0
  102. package/connectors/connect-drift/src/types/index.ts +237 -0
  103. package/connectors/connect-drift/src/utils/auth.ts +274 -0
  104. package/connectors/connect-drift/src/utils/bulk.ts +212 -0
  105. package/connectors/connect-drift/src/utils/config.ts +326 -0
  106. package/connectors/connect-drift/src/utils/output.ts +175 -0
  107. package/connectors/connect-drift/src/utils/settings.ts +114 -0
  108. package/connectors/connect-drift/src/utils/storage.ts +198 -0
  109. package/connectors/connect-drift/tsconfig.json +16 -0
  110. package/connectors/connect-freshdesk/.env.example +11 -0
  111. package/connectors/connect-freshdesk/CLAUDE.md +272 -0
  112. package/connectors/connect-freshdesk/README.md +193 -0
  113. package/connectors/connect-freshdesk/package.json +51 -0
  114. package/connectors/connect-freshdesk/scripts/release.ts +179 -0
  115. package/connectors/connect-freshdesk/src/api/client.ts +213 -0
  116. package/connectors/connect-freshdesk/src/api/example.ts +48 -0
  117. package/connectors/connect-freshdesk/src/api/index.ts +51 -0
  118. package/connectors/connect-freshdesk/src/cli/index.ts +254 -0
  119. package/connectors/connect-freshdesk/src/index.ts +103 -0
  120. package/connectors/connect-freshdesk/src/types/index.ts +237 -0
  121. package/connectors/connect-freshdesk/src/utils/auth.ts +274 -0
  122. package/connectors/connect-freshdesk/src/utils/bulk.ts +212 -0
  123. package/connectors/connect-freshdesk/src/utils/config.ts +326 -0
  124. package/connectors/connect-freshdesk/src/utils/output.ts +175 -0
  125. package/connectors/connect-freshdesk/src/utils/settings.ts +114 -0
  126. package/connectors/connect-freshdesk/src/utils/storage.ts +198 -0
  127. package/connectors/connect-freshdesk/tsconfig.json +16 -0
  128. package/connectors/connect-gumroad/.env.example +11 -0
  129. package/connectors/connect-gumroad/CLAUDE.md +272 -0
  130. package/connectors/connect-gumroad/README.md +193 -0
  131. package/connectors/connect-gumroad/package.json +51 -0
  132. package/connectors/connect-gumroad/scripts/release.ts +179 -0
  133. package/connectors/connect-gumroad/src/api/client.ts +213 -0
  134. package/connectors/connect-gumroad/src/api/example.ts +48 -0
  135. package/connectors/connect-gumroad/src/api/index.ts +51 -0
  136. package/connectors/connect-gumroad/src/cli/index.ts +254 -0
  137. package/connectors/connect-gumroad/src/index.ts +103 -0
  138. package/connectors/connect-gumroad/src/types/index.ts +237 -0
  139. package/connectors/connect-gumroad/src/utils/auth.ts +274 -0
  140. package/connectors/connect-gumroad/src/utils/bulk.ts +212 -0
  141. package/connectors/connect-gumroad/src/utils/config.ts +326 -0
  142. package/connectors/connect-gumroad/src/utils/output.ts +175 -0
  143. package/connectors/connect-gumroad/src/utils/settings.ts +114 -0
  144. package/connectors/connect-gumroad/src/utils/storage.ts +198 -0
  145. package/connectors/connect-gumroad/tsconfig.json +16 -0
  146. package/connectors/connect-hubspot/.env.example +11 -0
  147. package/connectors/connect-hubspot/CLAUDE.md +128 -0
  148. package/connectors/connect-hubspot/README.md +193 -0
  149. package/connectors/connect-hubspot/package.json +52 -0
  150. package/connectors/connect-hubspot/src/api/client.ts +136 -0
  151. package/connectors/connect-hubspot/src/api/index.ts +379 -0
  152. package/connectors/connect-hubspot/src/cli/index.ts +589 -0
  153. package/connectors/connect-hubspot/src/index.ts +21 -0
  154. package/connectors/connect-hubspot/src/types/index.ts +285 -0
  155. package/connectors/connect-hubspot/src/utils/config.ts +205 -0
  156. package/connectors/connect-hubspot/src/utils/output.ts +119 -0
  157. package/connectors/connect-hubspot/tsconfig.json +16 -0
  158. package/connectors/connect-intercom/.env.example +11 -0
  159. package/connectors/connect-intercom/CLAUDE.md +131 -0
  160. package/connectors/connect-intercom/README.md +193 -0
  161. package/connectors/connect-intercom/package.json +52 -0
  162. package/connectors/connect-intercom/src/api/client.ts +132 -0
  163. package/connectors/connect-intercom/src/api/index.ts +366 -0
  164. package/connectors/connect-intercom/src/cli/index.ts +831 -0
  165. package/connectors/connect-intercom/src/index.ts +21 -0
  166. package/connectors/connect-intercom/src/types/index.ts +650 -0
  167. package/connectors/connect-intercom/src/utils/config.ts +157 -0
  168. package/connectors/connect-intercom/src/utils/output.ts +119 -0
  169. package/connectors/connect-intercom/tsconfig.json +16 -0
  170. package/connectors/connect-lemonsqueezy/.env.example +11 -0
  171. package/connectors/connect-lemonsqueezy/CLAUDE.md +128 -0
  172. package/connectors/connect-lemonsqueezy/README.md +193 -0
  173. package/connectors/connect-lemonsqueezy/package.json +52 -0
  174. package/connectors/connect-lemonsqueezy/src/api/client.ts +133 -0
  175. package/connectors/connect-lemonsqueezy/src/api/index.ts +502 -0
  176. package/connectors/connect-lemonsqueezy/src/cli/index.ts +723 -0
  177. package/connectors/connect-lemonsqueezy/src/index.ts +21 -0
  178. package/connectors/connect-lemonsqueezy/src/types/index.ts +353 -0
  179. package/connectors/connect-lemonsqueezy/src/utils/config.ts +205 -0
  180. package/connectors/connect-lemonsqueezy/src/utils/output.ts +119 -0
  181. package/connectors/connect-lemonsqueezy/tsconfig.json +16 -0
  182. package/connectors/connect-linkedin/.env.example +11 -0
  183. package/connectors/connect-linkedin/CLAUDE.md +124 -0
  184. package/connectors/connect-linkedin/README.md +193 -0
  185. package/connectors/connect-linkedin/package.json +52 -0
  186. package/connectors/connect-linkedin/src/api/client.ts +132 -0
  187. package/connectors/connect-linkedin/src/api/index.ts +313 -0
  188. package/connectors/connect-linkedin/src/cli/index.ts +548 -0
  189. package/connectors/connect-linkedin/src/index.ts +21 -0
  190. package/connectors/connect-linkedin/src/types/index.ts +472 -0
  191. package/connectors/connect-linkedin/src/utils/config.ts +157 -0
  192. package/connectors/connect-linkedin/src/utils/output.ts +119 -0
  193. package/connectors/connect-linkedin/tsconfig.json +16 -0
  194. package/connectors/connect-mailchimp/.env.example +11 -0
  195. package/connectors/connect-mailchimp/CLAUDE.md +127 -0
  196. package/connectors/connect-mailchimp/README.md +193 -0
  197. package/connectors/connect-mailchimp/package.json +52 -0
  198. package/connectors/connect-mailchimp/src/api/client.ts +162 -0
  199. package/connectors/connect-mailchimp/src/api/index.ts +580 -0
  200. package/connectors/connect-mailchimp/src/cli/index.ts +822 -0
  201. package/connectors/connect-mailchimp/src/index.ts +23 -0
  202. package/connectors/connect-mailchimp/src/types/index.ts +585 -0
  203. package/connectors/connect-mailchimp/src/utils/config.ts +208 -0
  204. package/connectors/connect-mailchimp/src/utils/output.ts +119 -0
  205. package/connectors/connect-mailchimp/tsconfig.json +16 -0
  206. package/connectors/connect-mongodb/.env.example +11 -0
  207. package/connectors/connect-mongodb/CLAUDE.md +272 -0
  208. package/connectors/connect-mongodb/README.md +193 -0
  209. package/connectors/connect-mongodb/package.json +51 -0
  210. package/connectors/connect-mongodb/scripts/release.ts +179 -0
  211. package/connectors/connect-mongodb/src/api/client.ts +213 -0
  212. package/connectors/connect-mongodb/src/api/example.ts +48 -0
  213. package/connectors/connect-mongodb/src/api/index.ts +51 -0
  214. package/connectors/connect-mongodb/src/cli/index.ts +254 -0
  215. package/connectors/connect-mongodb/src/index.ts +103 -0
  216. package/connectors/connect-mongodb/src/types/index.ts +237 -0
  217. package/connectors/connect-mongodb/src/utils/auth.ts +274 -0
  218. package/connectors/connect-mongodb/src/utils/bulk.ts +212 -0
  219. package/connectors/connect-mongodb/src/utils/config.ts +326 -0
  220. package/connectors/connect-mongodb/src/utils/output.ts +175 -0
  221. package/connectors/connect-mongodb/src/utils/settings.ts +114 -0
  222. package/connectors/connect-mongodb/src/utils/storage.ts +198 -0
  223. package/connectors/connect-mongodb/tsconfig.json +16 -0
  224. package/connectors/connect-netlify/.env.example +11 -0
  225. package/connectors/connect-netlify/CLAUDE.md +170 -0
  226. package/connectors/connect-netlify/README.md +193 -0
  227. package/connectors/connect-netlify/package.json +53 -0
  228. package/connectors/connect-netlify/src/api/client.ts +132 -0
  229. package/connectors/connect-netlify/src/api/index.ts +533 -0
  230. package/connectors/connect-netlify/src/cli/index.ts +985 -0
  231. package/connectors/connect-netlify/src/index.ts +22 -0
  232. package/connectors/connect-netlify/src/types/index.ts +423 -0
  233. package/connectors/connect-netlify/src/utils/config.ts +171 -0
  234. package/connectors/connect-netlify/src/utils/output.ts +119 -0
  235. package/connectors/connect-netlify/tsconfig.json +16 -0
  236. package/connectors/connect-paypal/.env.example +11 -0
  237. package/connectors/connect-paypal/CLAUDE.md +128 -0
  238. package/connectors/connect-paypal/README.md +193 -0
  239. package/connectors/connect-paypal/package.json +51 -0
  240. package/connectors/connect-paypal/src/api/client.ts +182 -0
  241. package/connectors/connect-paypal/src/api/index.ts +235 -0
  242. package/connectors/connect-paypal/src/cli/index.ts +559 -0
  243. package/connectors/connect-paypal/src/index.ts +23 -0
  244. package/connectors/connect-paypal/src/types/index.ts +377 -0
  245. package/connectors/connect-paypal/src/utils/config.ts +125 -0
  246. package/connectors/connect-paypal/src/utils/output.ts +119 -0
  247. package/connectors/connect-paypal/tsconfig.json +16 -0
  248. package/connectors/connect-pinterest/.env.example +11 -0
  249. package/connectors/connect-pinterest/CLAUDE.md +115 -0
  250. package/connectors/connect-pinterest/README.md +193 -0
  251. package/connectors/connect-pinterest/package.json +52 -0
  252. package/connectors/connect-pinterest/src/api/client.ts +125 -0
  253. package/connectors/connect-pinterest/src/api/index.ts +203 -0
  254. package/connectors/connect-pinterest/src/cli/index.ts +653 -0
  255. package/connectors/connect-pinterest/src/index.ts +21 -0
  256. package/connectors/connect-pinterest/src/types/index.ts +268 -0
  257. package/connectors/connect-pinterest/src/utils/config.ts +157 -0
  258. package/connectors/connect-pinterest/src/utils/output.ts +119 -0
  259. package/connectors/connect-pinterest/tsconfig.json +16 -0
  260. package/connectors/connect-posthog/.env.example +11 -0
  261. package/connectors/connect-posthog/CLAUDE.md +272 -0
  262. package/connectors/connect-posthog/README.md +193 -0
  263. package/connectors/connect-posthog/package.json +51 -0
  264. package/connectors/connect-posthog/scripts/release.ts +179 -0
  265. package/connectors/connect-posthog/src/api/client.ts +213 -0
  266. package/connectors/connect-posthog/src/api/example.ts +48 -0
  267. package/connectors/connect-posthog/src/api/index.ts +51 -0
  268. package/connectors/connect-posthog/src/cli/index.ts +254 -0
  269. package/connectors/connect-posthog/src/index.ts +103 -0
  270. package/connectors/connect-posthog/src/types/index.ts +237 -0
  271. package/connectors/connect-posthog/src/utils/auth.ts +274 -0
  272. package/connectors/connect-posthog/src/utils/bulk.ts +212 -0
  273. package/connectors/connect-posthog/src/utils/config.ts +326 -0
  274. package/connectors/connect-posthog/src/utils/output.ts +175 -0
  275. package/connectors/connect-posthog/src/utils/settings.ts +114 -0
  276. package/connectors/connect-posthog/src/utils/storage.ts +198 -0
  277. package/connectors/connect-posthog/tsconfig.json +16 -0
  278. package/connectors/connect-salesforce/.env.example +11 -0
  279. package/connectors/connect-salesforce/CLAUDE.md +128 -0
  280. package/connectors/connect-salesforce/README.md +193 -0
  281. package/connectors/connect-salesforce/package.json +53 -0
  282. package/connectors/connect-salesforce/src/api/client.ts +150 -0
  283. package/connectors/connect-salesforce/src/api/index.ts +367 -0
  284. package/connectors/connect-salesforce/src/cli/index.ts +594 -0
  285. package/connectors/connect-salesforce/src/index.ts +21 -0
  286. package/connectors/connect-salesforce/src/types/index.ts +292 -0
  287. package/connectors/connect-salesforce/src/utils/config.ts +208 -0
  288. package/connectors/connect-salesforce/src/utils/output.ts +119 -0
  289. package/connectors/connect-salesforce/tsconfig.json +16 -0
  290. package/connectors/connect-segment/.env.example +11 -0
  291. package/connectors/connect-segment/CLAUDE.md +272 -0
  292. package/connectors/connect-segment/README.md +193 -0
  293. package/connectors/connect-segment/package.json +51 -0
  294. package/connectors/connect-segment/scripts/release.ts +179 -0
  295. package/connectors/connect-segment/src/api/client.ts +213 -0
  296. package/connectors/connect-segment/src/api/example.ts +48 -0
  297. package/connectors/connect-segment/src/api/index.ts +51 -0
  298. package/connectors/connect-segment/src/cli/index.ts +254 -0
  299. package/connectors/connect-segment/src/index.ts +103 -0
  300. package/connectors/connect-segment/src/types/index.ts +237 -0
  301. package/connectors/connect-segment/src/utils/auth.ts +274 -0
  302. package/connectors/connect-segment/src/utils/bulk.ts +212 -0
  303. package/connectors/connect-segment/src/utils/config.ts +326 -0
  304. package/connectors/connect-segment/src/utils/output.ts +175 -0
  305. package/connectors/connect-segment/src/utils/settings.ts +114 -0
  306. package/connectors/connect-segment/src/utils/storage.ts +198 -0
  307. package/connectors/connect-segment/tsconfig.json +16 -0
  308. package/connectors/connect-sendgrid/.env.example +11 -0
  309. package/connectors/connect-sendgrid/CLAUDE.md +125 -0
  310. package/connectors/connect-sendgrid/README.md +193 -0
  311. package/connectors/connect-sendgrid/package.json +53 -0
  312. package/connectors/connect-sendgrid/src/api/client.ts +137 -0
  313. package/connectors/connect-sendgrid/src/api/index.ts +588 -0
  314. package/connectors/connect-sendgrid/src/cli/index.ts +764 -0
  315. package/connectors/connect-sendgrid/src/index.ts +21 -0
  316. package/connectors/connect-sendgrid/src/types/index.ts +403 -0
  317. package/connectors/connect-sendgrid/src/utils/config.ts +197 -0
  318. package/connectors/connect-sendgrid/src/utils/output.ts +119 -0
  319. package/connectors/connect-sendgrid/tsconfig.json +16 -0
  320. package/connectors/connect-supabase/.env.example +11 -0
  321. package/connectors/connect-supabase/CLAUDE.md +132 -0
  322. package/connectors/connect-supabase/README.md +193 -0
  323. package/connectors/connect-supabase/package.json +52 -0
  324. package/connectors/connect-supabase/src/api/client.ts +231 -0
  325. package/connectors/connect-supabase/src/api/index.ts +439 -0
  326. package/connectors/connect-supabase/src/cli/index.ts +691 -0
  327. package/connectors/connect-supabase/src/index.ts +24 -0
  328. package/connectors/connect-supabase/src/types/index.ts +215 -0
  329. package/connectors/connect-supabase/src/utils/config.ts +219 -0
  330. package/connectors/connect-supabase/tsconfig.json +16 -0
  331. package/connectors/connect-vercel/.env.example +11 -0
  332. package/connectors/connect-vercel/CLAUDE.md +142 -0
  333. package/connectors/connect-vercel/README.md +193 -0
  334. package/connectors/connect-vercel/package.json +52 -0
  335. package/connectors/connect-vercel/src/api/client.ts +139 -0
  336. package/connectors/connect-vercel/src/api/index.ts +384 -0
  337. package/connectors/connect-vercel/src/cli/index.ts +740 -0
  338. package/connectors/connect-vercel/src/index.ts +24 -0
  339. package/connectors/connect-vercel/src/types/index.ts +350 -0
  340. package/connectors/connect-vercel/src/utils/config.ts +182 -0
  341. package/connectors/connect-vercel/src/utils/output.ts +119 -0
  342. package/connectors/connect-vercel/tsconfig.json +16 -0
  343. package/connectors/connect-zendesk/.env.example +10 -0
  344. package/connectors/connect-zendesk/.github/workflows/deploy.yml +51 -0
  345. package/connectors/connect-zendesk/CLAUDE.md +78 -0
  346. package/connectors/connect-zendesk/Makefile +129 -0
  347. package/connectors/connect-zendesk/README.md +295 -0
  348. package/connectors/connect-zendesk/SCAFFOLD.md +178 -0
  349. package/connectors/connect-zendesk/nginx-connector.conf +218 -0
  350. package/connectors/connect-zendesk/nginx.conf +61 -0
  351. package/connectors/connect-zendesk/package.json +71 -0
  352. package/connectors/connect-zendesk/scripts/init.sh +62 -0
  353. package/connectors/connect-zendesk/scripts/publish.ts +210 -0
  354. package/connectors/connect-zendesk/server/index.js +142 -0
  355. package/connectors/connect-zendesk/src/api/automations.ts +95 -0
  356. package/connectors/connect-zendesk/src/api/brands.ts +80 -0
  357. package/connectors/connect-zendesk/src/api/bulk.ts +838 -0
  358. package/connectors/connect-zendesk/src/api/client.test.ts +315 -0
  359. package/connectors/connect-zendesk/src/api/client.ts +173 -0
  360. package/connectors/connect-zendesk/src/api/example.ts +59 -0
  361. package/connectors/connect-zendesk/src/api/groups.ts +60 -0
  362. package/connectors/connect-zendesk/src/api/index.test.ts +111 -0
  363. package/connectors/connect-zendesk/src/api/index.ts +131 -0
  364. package/connectors/connect-zendesk/src/api/macros.ts +124 -0
  365. package/connectors/connect-zendesk/src/api/organizations.ts +85 -0
  366. package/connectors/connect-zendesk/src/api/slas.ts +80 -0
  367. package/connectors/connect-zendesk/src/api/ticket-fields.ts +98 -0
  368. package/connectors/connect-zendesk/src/api/tickets.test.ts +215 -0
  369. package/connectors/connect-zendesk/src/api/tickets.ts +103 -0
  370. package/connectors/connect-zendesk/src/api/triggers.test.ts +204 -0
  371. package/connectors/connect-zendesk/src/api/triggers.ts +125 -0
  372. package/connectors/connect-zendesk/src/api/users.test.ts +180 -0
  373. package/connectors/connect-zendesk/src/api/users.ts +108 -0
  374. package/connectors/connect-zendesk/src/api/views.test.ts +223 -0
  375. package/connectors/connect-zendesk/src/api/views.ts +145 -0
  376. package/connectors/connect-zendesk/src/api/webhooks.test.ts +208 -0
  377. package/connectors/connect-zendesk/src/api/webhooks.ts +118 -0
  378. package/connectors/connect-zendesk/src/cli/index.ts +1478 -0
  379. package/connectors/connect-zendesk/src/index.ts +36 -0
  380. package/connectors/connect-zendesk/src/server/index.ts +204 -0
  381. package/connectors/connect-zendesk/src/types/index.ts +910 -0
  382. package/connectors/connect-zendesk/src/utils/config.test.ts +193 -0
  383. package/connectors/connect-zendesk/src/utils/config.ts +526 -0
  384. package/connectors/connect-zendesk/src/utils/export.ts +338 -0
  385. package/connectors/connect-zendesk/src/utils/logger.ts +105 -0
  386. package/connectors/connect-zendesk/src/utils/output.test.ts +137 -0
  387. package/connectors/connect-zendesk/src/utils/output.ts +119 -0
  388. package/connectors/connect-zendesk/tsconfig.json +31 -0
  389. package/dist/index.js +175 -0
  390. package/package.json +1 -1
@@ -0,0 +1,193 @@
1
+ import { describe, test, expect, beforeEach, afterEach } from 'bun:test';
2
+ import { existsSync, rmSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
3
+ import { homedir } from 'os';
4
+ import { join } from 'path';
5
+
6
+ // We need to test the config module with a custom config dir
7
+ // to avoid messing with actual user config
8
+ const TEST_CONFIG_DIR = join(homedir(), '.connect-zendesk-test');
9
+ const TEST_CONFIG_FILE = join(TEST_CONFIG_DIR, 'config.json');
10
+
11
+ describe('Config utilities', () => {
12
+ beforeEach(() => {
13
+ // Clean up test directory before each test
14
+ if (existsSync(TEST_CONFIG_DIR)) {
15
+ rmSync(TEST_CONFIG_DIR, { recursive: true });
16
+ }
17
+ });
18
+
19
+ afterEach(() => {
20
+ // Clean up test directory after each test
21
+ if (existsSync(TEST_CONFIG_DIR)) {
22
+ rmSync(TEST_CONFIG_DIR, { recursive: true });
23
+ }
24
+ });
25
+
26
+ describe('ensureConfigDir', () => {
27
+ test('creates directory if it does not exist', () => {
28
+ expect(existsSync(TEST_CONFIG_DIR)).toBe(false);
29
+ mkdirSync(TEST_CONFIG_DIR, { recursive: true });
30
+ expect(existsSync(TEST_CONFIG_DIR)).toBe(true);
31
+ });
32
+
33
+ test('does nothing if directory already exists', () => {
34
+ mkdirSync(TEST_CONFIG_DIR, { recursive: true });
35
+ mkdirSync(TEST_CONFIG_DIR, { recursive: true }); // Should not throw
36
+ expect(existsSync(TEST_CONFIG_DIR)).toBe(true);
37
+ });
38
+ });
39
+
40
+ describe('loadConfig', () => {
41
+ test('returns empty object if config file does not exist', () => {
42
+ // Using inline logic since we can't modify the actual module's paths
43
+ const loadTestConfig = () => {
44
+ if (!existsSync(TEST_CONFIG_FILE)) {
45
+ return {};
46
+ }
47
+ try {
48
+ const content = readFileSync(TEST_CONFIG_FILE, 'utf-8');
49
+ return JSON.parse(content);
50
+ } catch {
51
+ return {};
52
+ }
53
+ };
54
+
55
+ expect(loadTestConfig()).toEqual({});
56
+ });
57
+
58
+ test('returns parsed config from file', () => {
59
+ mkdirSync(TEST_CONFIG_DIR, { recursive: true });
60
+ const testConfig = { email: 'test@example.com', apiToken: 'token123' };
61
+ writeFileSync(TEST_CONFIG_FILE, JSON.stringify(testConfig));
62
+
63
+ const content = readFileSync(TEST_CONFIG_FILE, 'utf-8');
64
+ const parsed = JSON.parse(content);
65
+
66
+ expect(parsed).toEqual(testConfig);
67
+ });
68
+
69
+ test('returns empty object on invalid JSON', () => {
70
+ mkdirSync(TEST_CONFIG_DIR, { recursive: true });
71
+ writeFileSync(TEST_CONFIG_FILE, 'not valid json');
72
+
73
+ const loadTestConfig = () => {
74
+ try {
75
+ const content = readFileSync(TEST_CONFIG_FILE, 'utf-8');
76
+ return JSON.parse(content);
77
+ } catch {
78
+ return {};
79
+ }
80
+ };
81
+
82
+ expect(loadTestConfig()).toEqual({});
83
+ });
84
+ });
85
+
86
+ describe('saveConfig', () => {
87
+ test('saves config to file', () => {
88
+ mkdirSync(TEST_CONFIG_DIR, { recursive: true });
89
+ const testConfig = { email: 'new@example.com' };
90
+ writeFileSync(TEST_CONFIG_FILE, JSON.stringify(testConfig, null, 2));
91
+
92
+ const content = readFileSync(TEST_CONFIG_FILE, 'utf-8');
93
+ const parsed = JSON.parse(content);
94
+
95
+ expect(parsed.email).toBe('new@example.com');
96
+ });
97
+
98
+ test('creates directory if it does not exist', () => {
99
+ expect(existsSync(TEST_CONFIG_DIR)).toBe(false);
100
+ mkdirSync(TEST_CONFIG_DIR, { recursive: true });
101
+ writeFileSync(TEST_CONFIG_FILE, JSON.stringify({ email: 'test@example.com' }));
102
+
103
+ expect(existsSync(TEST_CONFIG_FILE)).toBe(true);
104
+ });
105
+ });
106
+
107
+ describe('getters and setters', () => {
108
+ test('setEmail and getEmail work correctly', () => {
109
+ mkdirSync(TEST_CONFIG_DIR, { recursive: true });
110
+
111
+ // Set
112
+ const config = { email: 'user@example.com' };
113
+ writeFileSync(TEST_CONFIG_FILE, JSON.stringify(config));
114
+
115
+ // Get
116
+ const content = readFileSync(TEST_CONFIG_FILE, 'utf-8');
117
+ const parsed = JSON.parse(content);
118
+
119
+ expect(parsed.email).toBe('user@example.com');
120
+ });
121
+
122
+ test('setApiToken and getApiToken work correctly', () => {
123
+ mkdirSync(TEST_CONFIG_DIR, { recursive: true });
124
+
125
+ const config = { apiToken: 'secret-token' };
126
+ writeFileSync(TEST_CONFIG_FILE, JSON.stringify(config));
127
+
128
+ const content = readFileSync(TEST_CONFIG_FILE, 'utf-8');
129
+ const parsed = JSON.parse(content);
130
+
131
+ expect(parsed.apiToken).toBe('secret-token');
132
+ });
133
+
134
+ test('setBaseUrl and getBaseUrl work correctly', () => {
135
+ mkdirSync(TEST_CONFIG_DIR, { recursive: true });
136
+
137
+ const config = { baseUrl: 'https://custom.zendesk.com/api/v2' };
138
+ writeFileSync(TEST_CONFIG_FILE, JSON.stringify(config));
139
+
140
+ const content = readFileSync(TEST_CONFIG_FILE, 'utf-8');
141
+ const parsed = JSON.parse(content);
142
+
143
+ expect(parsed.baseUrl).toBe('https://custom.zendesk.com/api/v2');
144
+ });
145
+
146
+ test('setDefaultAccount and getDefaultAccount work correctly', () => {
147
+ mkdirSync(TEST_CONFIG_DIR, { recursive: true });
148
+
149
+ const config = { defaultAccount: 'production' };
150
+ writeFileSync(TEST_CONFIG_FILE, JSON.stringify(config));
151
+
152
+ const content = readFileSync(TEST_CONFIG_FILE, 'utf-8');
153
+ const parsed = JSON.parse(content);
154
+
155
+ expect(parsed.defaultAccount).toBe('production');
156
+ });
157
+ });
158
+
159
+ describe('clearConfig', () => {
160
+ test('clears all config values', () => {
161
+ mkdirSync(TEST_CONFIG_DIR, { recursive: true });
162
+ writeFileSync(TEST_CONFIG_FILE, JSON.stringify({ email: 'test@example.com', apiToken: 'token' }));
163
+
164
+ // Clear
165
+ writeFileSync(TEST_CONFIG_FILE, JSON.stringify({}));
166
+
167
+ const content = readFileSync(TEST_CONFIG_FILE, 'utf-8');
168
+ const parsed = JSON.parse(content);
169
+
170
+ expect(parsed).toEqual({});
171
+ });
172
+ });
173
+
174
+ describe('environment variable priority', () => {
175
+ test('environment variables take precedence over config file', () => {
176
+ const originalEnv = process.env.ZENDESK_EMAIL;
177
+
178
+ mkdirSync(TEST_CONFIG_DIR, { recursive: true });
179
+ writeFileSync(TEST_CONFIG_FILE, JSON.stringify({ email: 'config@example.com' }));
180
+
181
+ process.env.ZENDESK_EMAIL = 'env@example.com';
182
+
183
+ // Simulating the priority logic
184
+ const getEmail = () => process.env.ZENDESK_EMAIL || JSON.parse(readFileSync(TEST_CONFIG_FILE, 'utf-8')).email;
185
+
186
+ expect(getEmail()).toBe('env@example.com');
187
+
188
+ // Restore
189
+ if (originalEnv) process.env.ZENDESK_EMAIL = originalEnv;
190
+ else delete process.env.ZENDESK_EMAIL;
191
+ });
192
+ });
193
+ });
@@ -0,0 +1,526 @@
1
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, readdirSync, rmSync } from 'fs';
2
+ import { homedir } from 'os';
3
+ import { join } from 'path';
4
+
5
+ interface ZendeskCliConfig {
6
+ email?: string;
7
+ apiToken?: string;
8
+ baseUrl?: string;
9
+ defaultAccount?: string;
10
+ remoteApiUrl?: string;
11
+ }
12
+
13
+ const CONNECTOR_NAME = 'connect-zendesk';
14
+ const DEFAULT_PROFILE = 'default';
15
+ const CURRENT_PROFILE_FILE = 'current_profile';
16
+ const PROFILES_DIR = 'profiles';
17
+
18
+ // Store for --profile flag override
19
+ let profileOverride: string | undefined;
20
+
21
+ // Config directory: ~/.connect/connect-zendesk/
22
+ const BASE_CONFIG_DIR = join(homedir(), '.connect', CONNECTOR_NAME);
23
+
24
+ // Old config directory for migration
25
+ const OLD_CONFIG_DIR = join(homedir(), '.connect-zendesk');
26
+
27
+ // ============================================
28
+ // Profile Management
29
+ // ============================================
30
+
31
+ export function setProfileOverride(profile: string | undefined): void {
32
+ profileOverride = profile;
33
+ }
34
+
35
+ export function getProfileOverride(): string | undefined {
36
+ return profileOverride;
37
+ }
38
+
39
+ function ensureBaseConfigDir(): void {
40
+ if (!existsSync(BASE_CONFIG_DIR)) {
41
+ mkdirSync(BASE_CONFIG_DIR, { recursive: true });
42
+ }
43
+ }
44
+
45
+ function getProfilesDir(): string {
46
+ return join(BASE_CONFIG_DIR, PROFILES_DIR);
47
+ }
48
+
49
+ function getCurrentProfileFile(): string {
50
+ return join(BASE_CONFIG_DIR, CURRENT_PROFILE_FILE);
51
+ }
52
+
53
+ /**
54
+ * Get the current active profile name
55
+ */
56
+ export function getCurrentProfile(): string {
57
+ if (profileOverride) {
58
+ return profileOverride;
59
+ }
60
+
61
+ ensureBaseConfigDir();
62
+
63
+ const profilesDir = getProfilesDir();
64
+ if (!existsSync(profilesDir)) {
65
+ mkdirSync(profilesDir, { recursive: true });
66
+ }
67
+
68
+ const currentProfileFile = getCurrentProfileFile();
69
+ if (existsSync(currentProfileFile)) {
70
+ try {
71
+ const profile = readFileSync(currentProfileFile, 'utf-8').trim();
72
+ if (profile && profileExists(profile)) {
73
+ return profile;
74
+ }
75
+ } catch {
76
+ // Fall through to default
77
+ }
78
+ }
79
+
80
+ return DEFAULT_PROFILE;
81
+ }
82
+
83
+ /**
84
+ * Set the current active profile
85
+ */
86
+ export function setCurrentProfile(profile: string): void {
87
+ ensureBaseConfigDir();
88
+
89
+ if (!profileExists(profile) && profile !== DEFAULT_PROFILE) {
90
+ throw new Error(`Profile "${profile}" does not exist. Create it first with "profile create ${profile}"`);
91
+ }
92
+
93
+ writeFileSync(getCurrentProfileFile(), profile);
94
+ }
95
+
96
+ /**
97
+ * Check if a profile exists
98
+ */
99
+ export function profileExists(profile: string): boolean {
100
+ const profileDir = join(getProfilesDir(), profile);
101
+ return existsSync(profileDir);
102
+ }
103
+
104
+ /**
105
+ * List all available profiles
106
+ */
107
+ export function listProfiles(): string[] {
108
+ ensureBaseConfigDir();
109
+
110
+ const profilesDir = getProfilesDir();
111
+ if (!existsSync(profilesDir)) {
112
+ return [];
113
+ }
114
+
115
+ return readdirSync(profilesDir, { withFileTypes: true })
116
+ .filter(dirent => dirent.isDirectory())
117
+ .map(dirent => dirent.name)
118
+ .sort();
119
+ }
120
+
121
+ /**
122
+ * Create a new profile
123
+ */
124
+ export function createProfile(profile: string): void {
125
+ ensureBaseConfigDir();
126
+
127
+ if (profileExists(profile)) {
128
+ throw new Error(`Profile "${profile}" already exists`);
129
+ }
130
+
131
+ // Validate profile name
132
+ if (!/^[a-zA-Z0-9_-]+$/.test(profile)) {
133
+ throw new Error('Profile name can only contain letters, numbers, hyphens, and underscores');
134
+ }
135
+
136
+ const profileDir = join(getProfilesDir(), profile);
137
+ mkdirSync(profileDir, { recursive: true });
138
+ }
139
+
140
+ /**
141
+ * Delete a profile
142
+ */
143
+ export function deleteProfile(profile: string): void {
144
+ if (profile === DEFAULT_PROFILE) {
145
+ throw new Error('Cannot delete the default profile');
146
+ }
147
+
148
+ if (!profileExists(profile)) {
149
+ throw new Error(`Profile "${profile}" does not exist`);
150
+ }
151
+
152
+ const currentProfile = getCurrentProfile();
153
+ if (currentProfile === profile) {
154
+ setCurrentProfile(DEFAULT_PROFILE);
155
+ }
156
+
157
+ const profileDir = join(getProfilesDir(), profile);
158
+ rmSync(profileDir, { recursive: true });
159
+ }
160
+
161
+ /**
162
+ * Get the config directory for the current profile
163
+ */
164
+ function getProfileDir(): string {
165
+ ensureBaseConfigDir();
166
+
167
+ const profilesDir = getProfilesDir();
168
+ if (!existsSync(profilesDir)) {
169
+ mkdirSync(profilesDir, { recursive: true });
170
+ }
171
+
172
+ const profile = getCurrentProfile();
173
+ const profileDir = join(profilesDir, profile);
174
+
175
+ if (!existsSync(profileDir)) {
176
+ mkdirSync(profileDir, { recursive: true });
177
+ }
178
+
179
+ return profileDir;
180
+ }
181
+
182
+ export function getConfigDir(): string {
183
+ return getProfileDir();
184
+ }
185
+
186
+ export function getBaseConfigDir(): string {
187
+ return BASE_CONFIG_DIR;
188
+ }
189
+
190
+ export function ensureConfigDir(): void {
191
+ getProfileDir();
192
+ }
193
+
194
+ // ============================================
195
+ // Migration from old config directory
196
+ // ============================================
197
+
198
+ /**
199
+ * Check if migration from old config directory is needed
200
+ */
201
+ export function needsMigration(): boolean {
202
+ const oldConfigFile = join(OLD_CONFIG_DIR, 'config.json');
203
+ const defaultProfileDir = join(getProfilesDir(), DEFAULT_PROFILE);
204
+ const newConfigFile = join(defaultProfileDir, 'config.json');
205
+
206
+ // Need migration if old config exists and new config doesn't
207
+ return existsSync(oldConfigFile) && !existsSync(newConfigFile);
208
+ }
209
+
210
+ /**
211
+ * Migrate from old ~/.connect-zendesk/ to new ~/.connect/connect-zendesk/ structure
212
+ */
213
+ export function migrateFromOldConfig(): { migrated: boolean; message: string } {
214
+ if (!needsMigration()) {
215
+ return { migrated: false, message: 'No migration needed' };
216
+ }
217
+
218
+ try {
219
+ // Ensure new directory structure exists
220
+ ensureBaseConfigDir();
221
+ const defaultProfileDir = join(getProfilesDir(), DEFAULT_PROFILE);
222
+ if (!existsSync(defaultProfileDir)) {
223
+ mkdirSync(defaultProfileDir, { recursive: true });
224
+ }
225
+
226
+ // Migrate config.json
227
+ const oldConfigFile = join(OLD_CONFIG_DIR, 'config.json');
228
+ if (existsSync(oldConfigFile)) {
229
+ const configContent = readFileSync(oldConfigFile, 'utf-8');
230
+ const newConfigFile = join(defaultProfileDir, 'config.json');
231
+ writeFileSync(newConfigFile, configContent);
232
+ }
233
+
234
+ // Set default profile as current
235
+ writeFileSync(getCurrentProfileFile(), DEFAULT_PROFILE);
236
+
237
+ return {
238
+ migrated: true,
239
+ message: `Migrated config from ${OLD_CONFIG_DIR} to ${BASE_CONFIG_DIR}`
240
+ };
241
+ } catch (err) {
242
+ return {
243
+ migrated: false,
244
+ message: `Migration failed: ${String(err)}`
245
+ };
246
+ }
247
+ }
248
+
249
+ // ============================================
250
+ // Exports Directory (shared across profiles)
251
+ // ============================================
252
+
253
+ const EXPORTS_DIR = join(BASE_CONFIG_DIR, 'exports');
254
+ const LOG_FILE = join(BASE_CONFIG_DIR, 'connect-zendesk.log');
255
+
256
+ /**
257
+ * Get the exports directory path (shared across profiles)
258
+ */
259
+ export function getExportsDir(): string {
260
+ ensureBaseConfigDir();
261
+ if (!existsSync(EXPORTS_DIR)) {
262
+ mkdirSync(EXPORTS_DIR, { recursive: true });
263
+ }
264
+ return EXPORTS_DIR;
265
+ }
266
+
267
+ /**
268
+ * Get the log file path
269
+ */
270
+ export function getLogFile(): string {
271
+ return LOG_FILE;
272
+ }
273
+
274
+ // ============================================
275
+ // Init Command Support
276
+ // ============================================
277
+
278
+ const README_CONTENT = `# connect-zendesk Configuration Directory
279
+
280
+ This directory contains configuration and data for the connect-zendesk CLI.
281
+
282
+ ## Directory Structure
283
+
284
+ \`\`\`
285
+ ~/.connect/connect-zendesk/
286
+ ├── current_profile # Current active profile name
287
+ ├── profiles/
288
+ │ ├── default/
289
+ │ │ └── config.json # Default profile configuration
290
+ │ └── <profile-name>/
291
+ │ └── config.json # Named profile configuration
292
+ ├── exports/ # Exported CSV/JSON data (shared)
293
+ └── connect-zendesk.log # Activity logs (shared)
294
+ \`\`\`
295
+
296
+ ## Profile Management
297
+
298
+ \`\`\`bash
299
+ connect-zendesk profile list # List all profiles
300
+ connect-zendesk profile create <name> # Create a new profile
301
+ connect-zendesk profile use <name> # Switch to a profile
302
+ connect-zendesk profile delete <name> # Delete a profile
303
+ connect-zendesk profile show # Show current profile
304
+ connect-zendesk --profile <name> <cmd> # Use profile for single command
305
+ \`\`\`
306
+
307
+ ## Configuration
308
+
309
+ Set your Zendesk credentials using the CLI:
310
+
311
+ \`\`\`bash
312
+ connect-zendesk config set-email your-email@example.com
313
+ connect-zendesk config set-token your-api-token
314
+ connect-zendesk config set-base-url https://your-subdomain.zendesk.com/api/v2
315
+ \`\`\`
316
+
317
+ Or use environment variables:
318
+
319
+ \`\`\`bash
320
+ export ZENDESK_EMAIL=your-email@example.com
321
+ export ZENDESK_API_TOKEN=your-api-token
322
+ export ZENDESK_BASE_URL=https://your-subdomain.zendesk.com/api/v2
323
+ \`\`\`
324
+
325
+ ## Exports
326
+
327
+ Export data using:
328
+
329
+ \`\`\`bash
330
+ connect-zendesk tickets export --format csv -o tickets.csv
331
+ connect-zendesk users export --format csv -o users.csv
332
+ connect-zendesk organizations export --format csv -o orgs.csv
333
+ \`\`\`
334
+
335
+ Exported files are saved to the \`exports/\` directory.
336
+
337
+ ## More Information
338
+
339
+ - CLI Help: \`connect-zendesk --help\`
340
+ - Documentation: https://github.com/hasna/connect-zendesk
341
+ - Zendesk API: https://developer.zendesk.com/api-reference/
342
+ `;
343
+
344
+ /**
345
+ * Initialize the full config directory structure
346
+ */
347
+ export function initConfigDir(): { created: string[]; existing: string[] } {
348
+ const created: string[] = [];
349
+ const existing: string[] = [];
350
+
351
+ // Check for migration first
352
+ const migration = migrateFromOldConfig();
353
+ if (migration.migrated) {
354
+ created.push(`[Migrated] ${migration.message}`);
355
+ }
356
+
357
+ // Base config directory
358
+ if (!existsSync(BASE_CONFIG_DIR)) {
359
+ mkdirSync(BASE_CONFIG_DIR, { recursive: true });
360
+ created.push(BASE_CONFIG_DIR);
361
+ } else {
362
+ existing.push(BASE_CONFIG_DIR);
363
+ }
364
+
365
+ // Profiles directory
366
+ const profilesDir = getProfilesDir();
367
+ if (!existsSync(profilesDir)) {
368
+ mkdirSync(profilesDir, { recursive: true });
369
+ created.push(profilesDir);
370
+ } else {
371
+ existing.push(profilesDir);
372
+ }
373
+
374
+ // Default profile directory
375
+ const defaultProfileDir = join(profilesDir, DEFAULT_PROFILE);
376
+ if (!existsSync(defaultProfileDir)) {
377
+ mkdirSync(defaultProfileDir, { recursive: true });
378
+ created.push(defaultProfileDir);
379
+ } else {
380
+ existing.push(defaultProfileDir);
381
+ }
382
+
383
+ // Default profile config file
384
+ const configFile = join(defaultProfileDir, 'config.json');
385
+ if (!existsSync(configFile)) {
386
+ writeFileSync(configFile, JSON.stringify({}, null, 2));
387
+ created.push(configFile);
388
+ } else {
389
+ existing.push(configFile);
390
+ }
391
+
392
+ // Exports directory
393
+ if (!existsSync(EXPORTS_DIR)) {
394
+ mkdirSync(EXPORTS_DIR, { recursive: true });
395
+ created.push(EXPORTS_DIR);
396
+ } else {
397
+ existing.push(EXPORTS_DIR);
398
+ }
399
+
400
+ // Log file
401
+ if (!existsSync(LOG_FILE)) {
402
+ writeFileSync(LOG_FILE, `# connect-zendesk log\n# Created: ${new Date().toISOString()}\n\n`);
403
+ created.push(LOG_FILE);
404
+ } else {
405
+ existing.push(LOG_FILE);
406
+ }
407
+
408
+ // README file
409
+ const readmeFile = join(BASE_CONFIG_DIR, 'README.md');
410
+ if (!existsSync(readmeFile)) {
411
+ writeFileSync(readmeFile, README_CONTENT);
412
+ created.push(readmeFile);
413
+ } else {
414
+ existing.push(readmeFile);
415
+ }
416
+
417
+ // Current profile file
418
+ const currentProfileFile = getCurrentProfileFile();
419
+ if (!existsSync(currentProfileFile)) {
420
+ writeFileSync(currentProfileFile, DEFAULT_PROFILE);
421
+ created.push(currentProfileFile);
422
+ } else {
423
+ existing.push(currentProfileFile);
424
+ }
425
+
426
+ return { created, existing };
427
+ }
428
+
429
+ // ============================================
430
+ // Config Management
431
+ // ============================================
432
+
433
+ export function loadConfig(): ZendeskCliConfig {
434
+ ensureConfigDir();
435
+ const configFile = join(getProfileDir(), 'config.json');
436
+
437
+ if (!existsSync(configFile)) {
438
+ return {};
439
+ }
440
+
441
+ try {
442
+ const content = readFileSync(configFile, 'utf-8');
443
+ return JSON.parse(content);
444
+ } catch {
445
+ return {};
446
+ }
447
+ }
448
+
449
+ export function saveConfig(config: ZendeskCliConfig): void {
450
+ ensureConfigDir();
451
+ const configFile = join(getProfileDir(), 'config.json');
452
+ writeFileSync(configFile, JSON.stringify(config, null, 2));
453
+ }
454
+
455
+ export function getEmail(): string | undefined {
456
+ // Priority: environment variable > config file
457
+ return process.env.ZENDESK_EMAIL || loadConfig().email;
458
+ }
459
+
460
+ export function setEmail(email: string): void {
461
+ const config = loadConfig();
462
+ config.email = email;
463
+ saveConfig(config);
464
+ }
465
+
466
+ export function getApiToken(): string | undefined {
467
+ // Priority: environment variable > config file
468
+ return process.env.ZENDESK_API_TOKEN || loadConfig().apiToken;
469
+ }
470
+
471
+ export function setApiToken(apiToken: string): void {
472
+ const config = loadConfig();
473
+ config.apiToken = apiToken;
474
+ saveConfig(config);
475
+ }
476
+
477
+ export function getBaseUrl(): string | undefined {
478
+ // Priority: environment variable > config file
479
+ return process.env.ZENDESK_BASE_URL || loadConfig().baseUrl;
480
+ }
481
+
482
+ export function setBaseUrl(baseUrl: string): void {
483
+ const config = loadConfig();
484
+ config.baseUrl = baseUrl;
485
+ saveConfig(config);
486
+ }
487
+
488
+ export function getDefaultAccount(): string | undefined {
489
+ return loadConfig().defaultAccount;
490
+ }
491
+
492
+ export function setDefaultAccount(account: string): void {
493
+ const config = loadConfig();
494
+ config.defaultAccount = account;
495
+ saveConfig(config);
496
+ }
497
+
498
+ export function clearConfig(): void {
499
+ saveConfig({});
500
+ }
501
+
502
+ const DEFAULT_REMOTE_API_URL = 'https://connect.hasna.com/zendesk';
503
+
504
+ export function getRemoteApiUrl(): string {
505
+ return process.env.ZENDESK_REMOTE_API_URL || loadConfig().remoteApiUrl || DEFAULT_REMOTE_API_URL;
506
+ }
507
+
508
+ export function setRemoteApiUrl(url: string): void {
509
+ const config = loadConfig();
510
+ config.remoteApiUrl = url;
511
+ saveConfig(config);
512
+ }
513
+
514
+ // ============================================
515
+ // Utility Functions
516
+ // ============================================
517
+
518
+ export function isAuthenticated(): boolean {
519
+ const email = getEmail();
520
+ const token = getApiToken();
521
+ return email !== undefined && email !== '' && token !== undefined && token !== '';
522
+ }
523
+
524
+ export function getActiveProfileName(): string {
525
+ return getCurrentProfile();
526
+ }