runline 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) hide show
  1. package/dist/commands/auth.d.ts +7 -0
  2. package/dist/commands/auth.js +96 -0
  3. package/dist/config/loader.d.ts +11 -0
  4. package/dist/config/loader.js +46 -0
  5. package/dist/core/engine.js +7 -1
  6. package/dist/core/oauth.d.ts +46 -0
  7. package/dist/core/oauth.js +145 -0
  8. package/dist/index.d.ts +4 -2
  9. package/dist/index.js +2 -1
  10. package/dist/main.js +28 -0
  11. package/dist/plugin/api.d.ts +7 -1
  12. package/dist/plugin/api.js +7 -0
  13. package/dist/plugin/types.d.ts +47 -0
  14. package/dist/plugins/actionNetwork/src/index.js +118 -25
  15. package/dist/plugins/activeCampaign/src/index.js +184 -38
  16. package/dist/plugins/adalo/src/index.js +40 -8
  17. package/dist/plugins/affinity/src/index.js +100 -20
  18. package/dist/plugins/agileCrm/src/index.js +115 -27
  19. package/dist/plugins/airtable/src/index.js +94 -19
  20. package/dist/plugins/airtop/src/index.js +266 -62
  21. package/dist/plugins/apiTemplateIo/src/index.js +25 -5
  22. package/dist/plugins/asana/src/index.js +195 -41
  23. package/dist/plugins/autopilot/src/index.js +39 -8
  24. package/dist/plugins/bambooHr/src/index.js +109 -22
  25. package/dist/plugins/bannerbear/src/index.js +36 -8
  26. package/dist/plugins/baserow/src/index.js +35 -7
  27. package/dist/plugins/beeminder/src/index.js +198 -40
  28. package/dist/plugins/bitly/src/index.js +46 -10
  29. package/dist/plugins/bitwarden/src/index.js +167 -36
  30. package/dist/plugins/box/src/index.js +172 -37
  31. package/dist/plugins/brandfetch/src/index.js +5 -1
  32. package/dist/plugins/brevo/src/index.js +136 -29
  33. package/dist/plugins/bubble/src/index.js +76 -17
  34. package/dist/plugins/chargebee/src/index.js +35 -7
  35. package/dist/plugins/circleci/src/index.js +50 -10
  36. package/dist/plugins/ciscoWebex/src/index.js +131 -27
  37. package/dist/plugins/clearbit/src/index.js +76 -17
  38. package/dist/plugins/clickup/src/index.js +500 -107
  39. package/dist/plugins/clockify/src/index.js +229 -47
  40. package/dist/plugins/cloudflare/src/index.js +28 -6
  41. package/dist/plugins/cockpit/src/index.js +54 -12
  42. package/dist/plugins/coda/src/index.js +81 -19
  43. package/dist/plugins/coingecko/src/index.js +157 -33
  44. package/dist/plugins/contentful/src/index.js +85 -17
  45. package/dist/plugins/convertkit/src/index.js +74 -18
  46. package/dist/plugins/copper/src/index.js +59 -11
  47. package/dist/plugins/cortex/src/index.js +55 -13
  48. package/dist/plugins/currents/src/index.js +310 -71
  49. package/dist/plugins/customerIo/src/index.js +112 -23
  50. package/dist/plugins/databricks/src/index.js +549 -115
  51. package/dist/plugins/deepl/src/index.js +26 -6
  52. package/dist/plugins/demio/src/index.js +56 -11
  53. package/dist/plugins/dhl/src/index.js +16 -3
  54. package/dist/plugins/discord/src/index.js +141 -31
  55. package/dist/plugins/discourse/src/index.js +136 -31
  56. package/dist/plugins/disqus/src/index.js +96 -20
  57. package/dist/plugins/docker/src/index.js +20 -4
  58. package/dist/plugins/drift/src/index.js +19 -5
  59. package/dist/plugins/dropbox/src/index.js +139 -30
  60. package/dist/plugins/dropcontact/src/index.js +21 -4
  61. package/dist/plugins/egoi/src/index.js +61 -15
  62. package/dist/plugins/elasticsearch/src/index.js +59 -13
  63. package/dist/plugins/emelia/src/index.js +95 -19
  64. package/dist/plugins/erpnext/src/index.js +74 -15
  65. package/dist/plugins/facebookGraph/src/index.js +52 -11
  66. package/dist/plugins/freshdesk/src/index.js +220 -48
  67. package/dist/plugins/freshservice/src/index.js +39 -9
  68. package/dist/plugins/freshworksCrm/src/index.js +58 -12
  69. package/dist/plugins/getresponse/src/index.js +87 -18
  70. package/dist/plugins/ghost/src/index.js +114 -26
  71. package/dist/plugins/github/src/index.js +483 -109
  72. package/dist/plugins/gitlab/src/index.js +193 -45
  73. package/dist/plugins/gmail/src/index.js +1075 -0
  74. package/dist/plugins/gong/src/index.js +68 -14
  75. package/dist/plugins/gotify/src/index.js +43 -9
  76. package/dist/plugins/gotowebinar/src/index.js +233 -47
  77. package/dist/plugins/grafana/src/index.js +92 -21
  78. package/dist/plugins/graphql/src/index.js +38 -8
  79. package/dist/plugins/grist/src/index.js +52 -10
  80. package/dist/plugins/hackernews/src/index.js +32 -6
  81. package/dist/plugins/halopsa/src/index.js +131 -26
  82. package/dist/plugins/harvest/src/index.js +182 -42
  83. package/dist/plugins/helpscout/src/index.js +153 -31
  84. package/dist/plugins/highlevel/src/index.js +291 -58
  85. package/dist/plugins/homeAssistant/src/index.js +124 -26
  86. package/dist/plugins/hubspot/src/index.js +163 -29
  87. package/dist/plugins/humanticAi/src/index.js +54 -5
  88. package/dist/plugins/hunter/src/index.js +21 -4
  89. package/dist/plugins/intercom/src/index.js +95 -20
  90. package/dist/plugins/iterable/src/index.js +96 -20
  91. package/dist/plugins/jenkins/src/index.js +75 -17
  92. package/dist/plugins/jira/src/index.js +193 -43
  93. package/dist/plugins/keap/src/index.js +222 -56
  94. package/dist/plugins/kobotoolbox/src/index.js +113 -25
  95. package/dist/plugins/lemlist/src/index.js +79 -18
  96. package/dist/plugins/linear/src/index.js +86 -19
  97. package/dist/plugins/lingvanex/src/index.js +38 -8
  98. package/dist/plugins/linkedin/src/index.js +37 -8
  99. package/dist/plugins/lonescale/src/index.js +41 -9
  100. package/dist/plugins/magento/src/index.js +98 -27
  101. package/dist/plugins/mailcheck/src/index.js +11 -2
  102. package/dist/plugins/mailchimp/src/index.js +193 -42
  103. package/dist/plugins/mailerlite/src/index.js +61 -12
  104. package/dist/plugins/mailgun/src/index.js +39 -7
  105. package/dist/plugins/mailjet/src/index.js +141 -30
  106. package/dist/plugins/mandrill/src/index.js +67 -14
  107. package/dist/plugins/marketstack/src/index.js +56 -10
  108. package/dist/plugins/matrix/src/index.js +97 -20
  109. package/dist/plugins/mattermost/src/index.js +124 -26
  110. package/dist/plugins/mautic/src/index.js +129 -26
  111. package/dist/plugins/medium/src/index.js +64 -13
  112. package/dist/plugins/messagebird/src/index.js +80 -15
  113. package/dist/plugins/metabase/src/index.js +57 -12
  114. package/dist/plugins/misp/src/index.js +135 -33
  115. package/dist/plugins/mocean/src/index.js +33 -7
  116. package/dist/plugins/monday/src/index.js +97 -23
  117. package/dist/plugins/monicaCrm/src/index.js +112 -23
  118. package/dist/plugins/msg91/src/index.js +11 -2
  119. package/dist/plugins/nasa/src/index.js +108 -21
  120. package/dist/plugins/netlify/src/index.js +28 -6
  121. package/dist/plugins/netscalerAdc/src/index.js +144 -29
  122. package/dist/plugins/nextcloud/src/index.js +103 -20
  123. package/dist/plugins/nocodb/src/index.js +57 -11
  124. package/dist/plugins/notion/src/index.js +148 -37
  125. package/dist/plugins/npm/src/index.js +59 -12
  126. package/dist/plugins/odoo/src/index.js +102 -20
  127. package/dist/plugins/okta/src/index.js +50 -10
  128. package/dist/plugins/oneSimpleApi/src/index.js +84 -17
  129. package/dist/plugins/onfleet/src/index.js +139 -32
  130. package/dist/plugins/openThesaurus/src/index.js +46 -9
  131. package/dist/plugins/openweathermap/src/index.js +31 -6
  132. package/dist/plugins/oura/src/index.js +36 -7
  133. package/dist/plugins/paddle/src/index.js +80 -17
  134. package/dist/plugins/pagerduty/src/index.js +53 -12
  135. package/dist/plugins/paypal/src/index.js +51 -11
  136. package/dist/plugins/peekalink/src/index.js +12 -3
  137. package/dist/plugins/phantombuster/src/index.js +39 -8
  138. package/dist/plugins/philipsHue/src/index.js +64 -13
  139. package/dist/plugins/pipedrive/src/index.js +167 -45
  140. package/dist/plugins/plivo/src/index.js +43 -8
  141. package/dist/plugins/postbin/src/index.js +9 -2
  142. package/dist/plugins/posthog/src/index.js +50 -13
  143. package/dist/plugins/profitwell/src/index.js +24 -5
  144. package/dist/plugins/pushbullet/src/index.js +45 -9
  145. package/dist/plugins/pushcut/src/index.js +31 -6
  146. package/dist/plugins/pushover/src/index.js +51 -10
  147. package/dist/plugins/quickbase/src/index.js +66 -13
  148. package/dist/plugins/quickbooks/src/index.js +86 -19
  149. package/dist/plugins/quickchart/src/index.js +35 -7
  150. package/dist/plugins/raindrop/src/index.js +54 -13
  151. package/dist/plugins/reddit/src/index.js +73 -18
  152. package/dist/plugins/rocketchat/src/index.js +47 -9
  153. package/dist/plugins/rundeck/src/index.js +26 -5
  154. package/dist/plugins/salesforce/src/index.js +161 -31
  155. package/dist/plugins/salesmate/src/index.js +75 -16
  156. package/dist/plugins/securityScorecard/src/index.js +73 -15
  157. package/dist/plugins/segment/src/index.js +21 -4
  158. package/dist/plugins/sendgrid/src/index.js +102 -24
  159. package/dist/plugins/sendy/src/index.js +54 -11
  160. package/dist/plugins/sentry/src/index.js +174 -34
  161. package/dist/plugins/servicenow/src/index.js +120 -27
  162. package/dist/plugins/shopify/src/index.js +53 -12
  163. package/dist/plugins/signl4/src/index.js +16 -3
  164. package/dist/plugins/slack/src/index.js +407 -105
  165. package/dist/plugins/sms77/src/index.js +26 -5
  166. package/dist/plugins/splunk/src/index.js +186 -45
  167. package/dist/plugins/spotify/src/index.js +265 -66
  168. package/dist/plugins/stackby/src/index.js +18 -6
  169. package/dist/plugins/storyblok/src/index.js +57 -11
  170. package/dist/plugins/strapi/src/index.js +63 -12
  171. package/dist/plugins/strava/src/index.js +58 -13
  172. package/dist/plugins/stripe/src/index.js +143 -30
  173. package/dist/plugins/supabase/src/index.js +49 -10
  174. package/dist/plugins/syncromsp/src/index.js +245 -67
  175. package/dist/plugins/tapfiliate/src/index.js +57 -14
  176. package/dist/plugins/telegram/src/index.js +202 -39
  177. package/dist/plugins/thehive/src/index.js +271 -66
  178. package/dist/plugins/thehiveProject/src/index.js +457 -89
  179. package/dist/plugins/todoist/src/index.js +326 -77
  180. package/dist/plugins/travisci/src/index.js +35 -8
  181. package/dist/plugins/trello/src/index.js +204 -46
  182. package/dist/plugins/twake/src/index.js +10 -2
  183. package/dist/plugins/twilio/src/index.js +56 -11
  184. package/dist/plugins/twist/src/index.js +241 -48
  185. package/dist/plugins/twitter/src/index.js +128 -30
  186. package/dist/plugins/unleashedSoftware/src/index.js +30 -6
  187. package/dist/plugins/uplead/src/index.js +9 -2
  188. package/dist/plugins/uproc/src/index.js +31 -6
  189. package/dist/plugins/uptimerobot/src/index.js +119 -25
  190. package/dist/plugins/urlscanio/src/index.js +25 -6
  191. package/dist/plugins/vero/src/index.js +68 -13
  192. package/dist/plugins/vonage/src/index.js +32 -6
  193. package/dist/plugins/wekan/src/index.js +297 -52
  194. package/dist/plugins/woocommerce/src/index.js +57 -12
  195. package/dist/plugins/wordpress/src/index.js +94 -18
  196. package/dist/plugins/xero/src/index.js +79 -13
  197. package/dist/plugins/yourls/src/index.js +33 -6
  198. package/dist/plugins/zammad/src/index.js +139 -36
  199. package/dist/plugins/zendesk/src/index.js +201 -48
  200. package/dist/plugins/zoho/src/index.js +88 -21
  201. package/dist/plugins/zoom/src/index.js +41 -7
  202. package/dist/plugins/zulip/src/index.js +101 -20
  203. package/package.json +3 -1
@@ -1,6 +1,10 @@
1
1
  function getConn(ctx) {
2
2
  const c = ctx.connection.config;
3
- return { url: c.url.replace(/\/$/, ""), username: c.username, password: c.password };
3
+ return {
4
+ url: c.url.replace(/\/$/, ""),
5
+ username: c.username,
6
+ password: c.password,
7
+ };
4
8
  }
5
9
  async function apiRequest(conn, method, endpoint, body, qs) {
6
10
  const url = new URL(`${conn.url}/wp-json/wp/v2${endpoint}`);
@@ -12,7 +16,11 @@ async function apiRequest(conn, method, endpoint, body, qs) {
12
16
  }
13
17
  const init = {
14
18
  method,
15
- headers: { Authorization: `Basic ${btoa(`${conn.username}:${conn.password}`)}`, "Content-Type": "application/json", Accept: "application/json" },
19
+ headers: {
20
+ Authorization: `Basic ${btoa(`${conn.username}:${conn.password}`)}`,
21
+ "Content-Type": "application/json",
22
+ Accept: "application/json",
23
+ },
16
24
  };
17
25
  if (body && Object.keys(body).length > 0)
18
26
  init.body = JSON.stringify(body);
@@ -24,17 +32,35 @@ async function apiRequest(conn, method, endpoint, body, qs) {
24
32
  function registerContentCrud(rl, resource, plural, conn) {
25
33
  rl.registerAction(`${resource}.create`, {
26
34
  description: `Create a ${resource}`,
27
- inputSchema: { title: { type: "string", required: true }, content: { type: "string", required: false }, status: { type: "string", required: false, description: "publish, draft, pending, private" }, slug: { type: "string", required: false } },
28
- async execute(input, ctx) { return apiRequest(conn(ctx), "POST", `/${plural}`, input); },
35
+ inputSchema: {
36
+ title: { type: "string", required: true },
37
+ content: { type: "string", required: false },
38
+ status: {
39
+ type: "string",
40
+ required: false,
41
+ description: "publish, draft, pending, private",
42
+ },
43
+ slug: { type: "string", required: false },
44
+ },
45
+ async execute(input, ctx) {
46
+ return apiRequest(conn(ctx), "POST", `/${plural}`, input);
47
+ },
29
48
  });
30
49
  rl.registerAction(`${resource}.get`, {
31
50
  description: `Get a ${resource} by ID`,
32
51
  inputSchema: { id: { type: "string", required: true } },
33
- async execute(input, ctx) { return apiRequest(conn(ctx), "GET", `/${plural}/${input.id}`); },
52
+ async execute(input, ctx) {
53
+ return apiRequest(conn(ctx), "GET", `/${plural}/${input.id}`);
54
+ },
34
55
  });
35
56
  rl.registerAction(`${resource}.list`, {
36
57
  description: `List ${plural}`,
37
- inputSchema: { limit: { type: "number", required: false }, search: { type: "string", required: false }, status: { type: "string", required: false }, orderby: { type: "string", required: false } },
58
+ inputSchema: {
59
+ limit: { type: "number", required: false },
60
+ search: { type: "string", required: false },
61
+ status: { type: "string", required: false },
62
+ orderby: { type: "string", required: false },
63
+ },
38
64
  async execute(input, ctx) {
39
65
  const p = (input ?? {});
40
66
  const qs = {};
@@ -51,7 +77,13 @@ function registerContentCrud(rl, resource, plural, conn) {
51
77
  });
52
78
  rl.registerAction(`${resource}.update`, {
53
79
  description: `Update a ${resource}`,
54
- inputSchema: { id: { type: "string", required: true }, title: { type: "string", required: false }, content: { type: "string", required: false }, status: { type: "string", required: false }, slug: { type: "string", required: false } },
80
+ inputSchema: {
81
+ id: { type: "string", required: true },
82
+ title: { type: "string", required: false },
83
+ content: { type: "string", required: false },
84
+ status: { type: "string", required: false },
85
+ slug: { type: "string", required: false },
86
+ },
55
87
  async execute(input, ctx) {
56
88
  const { id, ...fields } = input;
57
89
  return apiRequest(conn(ctx), "POST", `/${plural}/${id}`, fields);
@@ -59,7 +91,10 @@ function registerContentCrud(rl, resource, plural, conn) {
59
91
  });
60
92
  rl.registerAction(`${resource}.delete`, {
61
93
  description: `Delete a ${resource}`,
62
- inputSchema: { id: { type: "string", required: true }, force: { type: "boolean", required: false } },
94
+ inputSchema: {
95
+ id: { type: "string", required: true },
96
+ force: { type: "boolean", required: false },
97
+ },
63
98
  async execute(input, ctx) {
64
99
  const p = input;
65
100
  const qs = {};
@@ -73,26 +108,53 @@ export default function wordpress(rl) {
73
108
  rl.setName("wordpress");
74
109
  rl.setVersion("0.1.0");
75
110
  rl.setConnectionSchema({
76
- url: { type: "string", required: true, description: "WordPress site URL", env: "WORDPRESS_URL" },
77
- username: { type: "string", required: true, description: "WordPress username", env: "WORDPRESS_USERNAME" },
78
- password: { type: "string", required: true, description: "WordPress application password", env: "WORDPRESS_PASSWORD" },
111
+ url: {
112
+ type: "string",
113
+ required: true,
114
+ description: "WordPress site URL",
115
+ env: "WORDPRESS_URL",
116
+ },
117
+ username: {
118
+ type: "string",
119
+ required: true,
120
+ description: "WordPress username",
121
+ env: "WORDPRESS_USERNAME",
122
+ },
123
+ password: {
124
+ type: "string",
125
+ required: true,
126
+ description: "WordPress application password",
127
+ env: "WORDPRESS_PASSWORD",
128
+ },
79
129
  });
80
130
  registerContentCrud(rl, "post", "posts", getConn);
81
131
  registerContentCrud(rl, "page", "pages", getConn);
82
132
  // ── User ────────────────────────────────────────────
83
133
  rl.registerAction("user.create", {
84
134
  description: "Create a user",
85
- inputSchema: { username: { type: "string", required: true }, email: { type: "string", required: true }, password: { type: "string", required: true }, name: { type: "string", required: false } },
86
- async execute(input, ctx) { return apiRequest(getConn(ctx), "POST", "/users", input); },
135
+ inputSchema: {
136
+ username: { type: "string", required: true },
137
+ email: { type: "string", required: true },
138
+ password: { type: "string", required: true },
139
+ name: { type: "string", required: false },
140
+ },
141
+ async execute(input, ctx) {
142
+ return apiRequest(getConn(ctx), "POST", "/users", input);
143
+ },
87
144
  });
88
145
  rl.registerAction("user.get", {
89
146
  description: "Get a user by ID",
90
147
  inputSchema: { id: { type: "string", required: true } },
91
- async execute(input, ctx) { return apiRequest(getConn(ctx), "GET", `/users/${input.id}`); },
148
+ async execute(input, ctx) {
149
+ return apiRequest(getConn(ctx), "GET", `/users/${input.id}`);
150
+ },
92
151
  });
93
152
  rl.registerAction("user.list", {
94
153
  description: "List users",
95
- inputSchema: { limit: { type: "number", required: false }, search: { type: "string", required: false } },
154
+ inputSchema: {
155
+ limit: { type: "number", required: false },
156
+ search: { type: "string", required: false },
157
+ },
96
158
  async execute(input, ctx) {
97
159
  const p = (input ?? {});
98
160
  const qs = {};
@@ -105,7 +167,12 @@ export default function wordpress(rl) {
105
167
  });
106
168
  rl.registerAction("user.update", {
107
169
  description: "Update a user",
108
- inputSchema: { id: { type: "string", required: true }, name: { type: "string", required: false }, email: { type: "string", required: false }, description: { type: "string", required: false } },
170
+ inputSchema: {
171
+ id: { type: "string", required: true },
172
+ name: { type: "string", required: false },
173
+ email: { type: "string", required: false },
174
+ description: { type: "string", required: false },
175
+ },
109
176
  async execute(input, ctx) {
110
177
  const { id, ...fields } = input;
111
178
  return apiRequest(getConn(ctx), "POST", `/users/${id}`, fields);
@@ -113,9 +180,18 @@ export default function wordpress(rl) {
113
180
  });
114
181
  rl.registerAction("user.delete", {
115
182
  description: "Delete the current user",
116
- inputSchema: { reassign: { type: "string", required: true, description: "User ID to reassign content to" } },
183
+ inputSchema: {
184
+ reassign: {
185
+ type: "string",
186
+ required: true,
187
+ description: "User ID to reassign content to",
188
+ },
189
+ },
117
190
  async execute(input, ctx) {
118
- return apiRequest(getConn(ctx), "DELETE", "/users/me", undefined, { reassign: input.reassign, force: "true" });
191
+ return apiRequest(getConn(ctx), "DELETE", "/users/me", undefined, {
192
+ reassign: input.reassign,
193
+ force: "true",
194
+ });
119
195
  },
120
196
  });
121
197
  }
@@ -1,6 +1,9 @@
1
1
  const BASE = "https://api.xero.com/api.xro/2.0";
2
2
  function getConn(ctx) {
3
- return { accessToken: ctx.connection.config.accessToken, tenantId: ctx.connection.config.tenantId };
3
+ return {
4
+ accessToken: ctx.connection.config.accessToken,
5
+ tenantId: ctx.connection.config.tenantId,
6
+ };
4
7
  }
5
8
  async function api(conn, method, endpoint, body, qs) {
6
9
  const url = new URL(`${BASE}${endpoint}`);
@@ -10,7 +13,14 @@ async function api(conn, method, endpoint, body, qs) {
10
13
  url.searchParams.set(k, String(v));
11
14
  }
12
15
  }
13
- const init = { method, headers: { Authorization: `Bearer ${conn.accessToken}`, "Xero-tenant-id": conn.tenantId, "Content-Type": "application/json" } };
16
+ const init = {
17
+ method,
18
+ headers: {
19
+ Authorization: `Bearer ${conn.accessToken}`,
20
+ "Xero-tenant-id": conn.tenantId,
21
+ "Content-Type": "application/json",
22
+ },
23
+ };
14
24
  if (body && Object.keys(body).length > 0)
15
25
  init.body = JSON.stringify(body);
16
26
  const res = await fetch(url.toString(), init);
@@ -22,17 +32,39 @@ export default function xero(rl) {
22
32
  rl.setName("xero");
23
33
  rl.setVersion("0.1.0");
24
34
  rl.setConnectionSchema({
25
- accessToken: { type: "string", required: true, description: "Xero OAuth2 access token", env: "XERO_ACCESS_TOKEN" },
26
- tenantId: { type: "string", required: true, description: "Xero tenant/organization ID", env: "XERO_TENANT_ID" },
35
+ accessToken: {
36
+ type: "string",
37
+ required: true,
38
+ description: "Xero OAuth2 access token",
39
+ env: "XERO_ACCESS_TOKEN",
40
+ },
41
+ tenantId: {
42
+ type: "string",
43
+ required: true,
44
+ description: "Xero tenant/organization ID",
45
+ env: "XERO_TENANT_ID",
46
+ },
27
47
  });
28
48
  // ── Invoice ─────────────────────────────────────────
29
49
  rl.registerAction("invoice.create", {
30
50
  description: "Create an invoice",
31
51
  inputSchema: {
32
- Type: { type: "string", required: true, description: "ACCREC (sales) or ACCPAY (bills)" },
52
+ Type: {
53
+ type: "string",
54
+ required: true,
55
+ description: "ACCREC (sales) or ACCPAY (bills)",
56
+ },
33
57
  ContactID: { type: "string", required: true },
34
- LineItems: { type: "object", required: false, description: "Array of line items" },
35
- Status: { type: "string", required: false, description: "DRAFT, SUBMITTED, AUTHORISED" },
58
+ LineItems: {
59
+ type: "object",
60
+ required: false,
61
+ description: "Array of line items",
62
+ },
63
+ Status: {
64
+ type: "string",
65
+ required: false,
66
+ description: "DRAFT, SUBMITTED, AUTHORISED",
67
+ },
36
68
  Date: { type: "string", required: false },
37
69
  DueDate: { type: "string", required: false },
38
70
  Reference: { type: "string", required: false },
@@ -40,7 +72,10 @@ export default function xero(rl) {
40
72
  },
41
73
  async execute(input, ctx) {
42
74
  const p = input;
43
- const body = { Type: p.Type, Contact: { ContactID: p.ContactID } };
75
+ const body = {
76
+ Type: p.Type,
77
+ Contact: { ContactID: p.ContactID },
78
+ };
44
79
  if (p.LineItems)
45
80
  body.LineItems = p.LineItems;
46
81
  if (p.Status)
@@ -67,7 +102,15 @@ export default function xero(rl) {
67
102
  });
68
103
  rl.registerAction("invoice.list", {
69
104
  description: "List invoices",
70
- inputSchema: { limit: { type: "number", required: false }, statuses: { type: "string", required: false, description: "Comma-separated statuses" }, where: { type: "string", required: false } },
105
+ inputSchema: {
106
+ limit: { type: "number", required: false },
107
+ statuses: {
108
+ type: "string",
109
+ required: false,
110
+ description: "Comma-separated statuses",
111
+ },
112
+ where: { type: "string", required: false },
113
+ },
71
114
  async execute(input, ctx) {
72
115
  const p = (input ?? {});
73
116
  const qs = {};
@@ -82,7 +125,14 @@ export default function xero(rl) {
82
125
  });
83
126
  rl.registerAction("invoice.update", {
84
127
  description: "Update an invoice",
85
- inputSchema: { invoiceId: { type: "string", required: true }, data: { type: "object", required: true, description: "Fields to update (Xero API format)" } },
128
+ inputSchema: {
129
+ invoiceId: { type: "string", required: true },
130
+ data: {
131
+ type: "object",
132
+ required: true,
133
+ description: "Fields to update (Xero API format)",
134
+ },
135
+ },
86
136
  async execute(input, ctx) {
87
137
  const p = input;
88
138
  const result = (await api(getConn(ctx), "POST", `/Invoices/${p.invoiceId}`, p.data));
@@ -92,7 +142,12 @@ export default function xero(rl) {
92
142
  // ── Contact ─────────────────────────────────────────
93
143
  rl.registerAction("contact.create", {
94
144
  description: "Create a contact",
95
- inputSchema: { Name: { type: "string", required: true }, EmailAddress: { type: "string", required: false }, FirstName: { type: "string", required: false }, LastName: { type: "string", required: false } },
145
+ inputSchema: {
146
+ Name: { type: "string", required: true },
147
+ EmailAddress: { type: "string", required: false },
148
+ FirstName: { type: "string", required: false },
149
+ LastName: { type: "string", required: false },
150
+ },
96
151
  async execute(input, ctx) {
97
152
  const p = input;
98
153
  const body = { Contacts: [p] };
@@ -110,7 +165,11 @@ export default function xero(rl) {
110
165
  });
111
166
  rl.registerAction("contact.list", {
112
167
  description: "List contacts",
113
- inputSchema: { limit: { type: "number", required: false }, where: { type: "string", required: false }, includeArchived: { type: "boolean", required: false } },
168
+ inputSchema: {
169
+ limit: { type: "number", required: false },
170
+ where: { type: "string", required: false },
171
+ includeArchived: { type: "boolean", required: false },
172
+ },
114
173
  async execute(input, ctx) {
115
174
  const p = (input ?? {});
116
175
  const qs = {};
@@ -125,7 +184,14 @@ export default function xero(rl) {
125
184
  });
126
185
  rl.registerAction("contact.update", {
127
186
  description: "Update a contact",
128
- inputSchema: { contactId: { type: "string", required: true }, data: { type: "object", required: true, description: "Fields to update (Xero API format)" } },
187
+ inputSchema: {
188
+ contactId: { type: "string", required: true },
189
+ data: {
190
+ type: "object",
191
+ required: true,
192
+ description: "Fields to update (Xero API format)",
193
+ },
194
+ },
129
195
  async execute(input, ctx) {
130
196
  const p = input;
131
197
  const body = { Contacts: [p.data] };
@@ -1,6 +1,9 @@
1
1
  function getConn(ctx) {
2
2
  const c = ctx.connection.config;
3
- return { url: c.url.replace(/\/$/, ""), signature: c.signature };
3
+ return {
4
+ url: c.url.replace(/\/$/, ""),
5
+ signature: c.signature,
6
+ };
4
7
  }
5
8
  async function apiRequest(conn, qs) {
6
9
  const url = new URL(`${conn.url}/yourls-api.php`);
@@ -22,12 +25,30 @@ export default function yourls(rl) {
22
25
  rl.setName("yourls");
23
26
  rl.setVersion("0.1.0");
24
27
  rl.setConnectionSchema({
25
- url: { type: "string", required: true, description: "Yourls installation URL", env: "YOURLS_URL" },
26
- signature: { type: "string", required: true, description: "Yourls signature token", env: "YOURLS_SIGNATURE" },
28
+ url: {
29
+ type: "string",
30
+ required: true,
31
+ description: "Yourls installation URL",
32
+ env: "YOURLS_URL",
33
+ },
34
+ signature: {
35
+ type: "string",
36
+ required: true,
37
+ description: "Yourls signature token",
38
+ env: "YOURLS_SIGNATURE",
39
+ },
27
40
  });
28
41
  rl.registerAction("url.shorten", {
29
42
  description: "Shorten a URL",
30
- inputSchema: { url: { type: "string", required: true }, keyword: { type: "string", required: false, description: "Custom short URL keyword" }, title: { type: "string", required: false } },
43
+ inputSchema: {
44
+ url: { type: "string", required: true },
45
+ keyword: {
46
+ type: "string",
47
+ required: false,
48
+ description: "Custom short URL keyword",
49
+ },
50
+ title: { type: "string", required: false },
51
+ },
31
52
  async execute(input, ctx) {
32
53
  const p = input;
33
54
  const qs = { action: "shorturl", url: p.url };
@@ -42,14 +63,20 @@ export default function yourls(rl) {
42
63
  description: "Expand a short URL to its original",
43
64
  inputSchema: { shortUrl: { type: "string", required: true } },
44
65
  async execute(input, ctx) {
45
- return apiRequest(getConn(ctx), { action: "expand", shorturl: input.shortUrl });
66
+ return apiRequest(getConn(ctx), {
67
+ action: "expand",
68
+ shorturl: input.shortUrl,
69
+ });
46
70
  },
47
71
  });
48
72
  rl.registerAction("url.stats", {
49
73
  description: "Get stats for a short URL",
50
74
  inputSchema: { shortUrl: { type: "string", required: true } },
51
75
  async execute(input, ctx) {
52
- const data = (await apiRequest(getConn(ctx), { action: "url-stats", shorturl: input.shortUrl }));
76
+ const data = (await apiRequest(getConn(ctx), {
77
+ action: "url-stats",
78
+ shorturl: input.shortUrl,
79
+ }));
53
80
  return data.link;
54
81
  },
55
82
  });
@@ -1,6 +1,9 @@
1
1
  function getConn(ctx) {
2
2
  const c = ctx.connection.config;
3
- return { url: c.url.replace(/\/$/, ""), token: c.token };
3
+ return {
4
+ url: c.url.replace(/\/$/, ""),
5
+ token: c.token,
6
+ };
4
7
  }
5
8
  async function api(conn, method, endpoint, body, qs) {
6
9
  const url = new URL(`${conn.url}/api/v1${endpoint}`);
@@ -10,7 +13,13 @@ async function api(conn, method, endpoint, body, qs) {
10
13
  url.searchParams.set(k, String(v));
11
14
  }
12
15
  }
13
- const init = { method, headers: { Authorization: `Token token=${conn.token}`, "Content-Type": "application/json" } };
16
+ const init = {
17
+ method,
18
+ headers: {
19
+ Authorization: `Token token=${conn.token}`,
20
+ "Content-Type": "application/json",
21
+ },
22
+ };
14
23
  if (body && Object.keys(body).length > 0)
15
24
  init.body = JSON.stringify(body);
16
25
  const res = await fetch(url.toString(), init);
@@ -21,71 +30,165 @@ async function api(conn, method, endpoint, body, qs) {
21
30
  return res.json();
22
31
  }
23
32
  function registerCrud(rl, resource, plural, conn, createSchema) {
24
- rl.registerAction(`${resource}.create`, { description: `Create a ${resource}`, inputSchema: createSchema,
25
- async execute(input, ctx) { return api(conn(ctx), "POST", `/${plural}`, input); } });
26
- rl.registerAction(`${resource}.get`, { description: `Get a ${resource} by ID`, inputSchema: { id: { type: "string", required: true } },
27
- async execute(input, ctx) { return api(conn(ctx), "GET", `/${plural}/${input.id}`); } });
28
- rl.registerAction(`${resource}.list`, { description: `List ${plural}`, inputSchema: { limit: { type: "number", required: false } },
33
+ rl.registerAction(`${resource}.create`, {
34
+ description: `Create a ${resource}`,
35
+ inputSchema: createSchema,
36
+ async execute(input, ctx) {
37
+ return api(conn(ctx), "POST", `/${plural}`, input);
38
+ },
39
+ });
40
+ rl.registerAction(`${resource}.get`, {
41
+ description: `Get a ${resource} by ID`,
42
+ inputSchema: { id: { type: "string", required: true } },
43
+ async execute(input, ctx) {
44
+ return api(conn(ctx), "GET", `/${plural}/${input.id}`);
45
+ },
46
+ });
47
+ rl.registerAction(`${resource}.list`, {
48
+ description: `List ${plural}`,
49
+ inputSchema: { limit: { type: "number", required: false } },
29
50
  async execute(input, ctx) {
30
51
  const p = (input ?? {});
31
52
  const qs = { per_page: p.limit ?? 100 };
32
53
  return api(conn(ctx), "GET", `/${plural}`, undefined, qs);
33
- } });
34
- rl.registerAction(`${resource}.update`, { description: `Update a ${resource}`, inputSchema: { id: { type: "string", required: true }, data: { type: "object", required: true } },
35
- async execute(input, ctx) { const p = input; return api(conn(ctx), "PUT", `/${plural}/${p.id}`, p.data); } });
36
- rl.registerAction(`${resource}.delete`, { description: `Delete a ${resource}`, inputSchema: { id: { type: "string", required: true } },
37
- async execute(input, ctx) { await api(conn(ctx), "DELETE", `/${plural}/${input.id}`); return { success: true }; } });
54
+ },
55
+ });
56
+ rl.registerAction(`${resource}.update`, {
57
+ description: `Update a ${resource}`,
58
+ inputSchema: {
59
+ id: { type: "string", required: true },
60
+ data: { type: "object", required: true },
61
+ },
62
+ async execute(input, ctx) {
63
+ const p = input;
64
+ return api(conn(ctx), "PUT", `/${plural}/${p.id}`, p.data);
65
+ },
66
+ });
67
+ rl.registerAction(`${resource}.delete`, {
68
+ description: `Delete a ${resource}`,
69
+ inputSchema: { id: { type: "string", required: true } },
70
+ async execute(input, ctx) {
71
+ await api(conn(ctx), "DELETE", `/${plural}/${input.id}`);
72
+ return { success: true };
73
+ },
74
+ });
38
75
  }
39
76
  export default function zammad(rl) {
40
77
  rl.setName("zammad");
41
78
  rl.setVersion("0.1.0");
42
79
  rl.setConnectionSchema({
43
- url: { type: "string", required: true, description: "Zammad instance URL", env: "ZAMMAD_URL" },
44
- token: { type: "string", required: true, description: "Zammad access token", env: "ZAMMAD_TOKEN" },
80
+ url: {
81
+ type: "string",
82
+ required: true,
83
+ description: "Zammad instance URL",
84
+ env: "ZAMMAD_URL",
85
+ },
86
+ token: {
87
+ type: "string",
88
+ required: true,
89
+ description: "Zammad access token",
90
+ env: "ZAMMAD_TOKEN",
91
+ },
92
+ });
93
+ registerCrud(rl, "user", "users", getConn, {
94
+ firstname: { type: "string", required: true },
95
+ lastname: { type: "string", required: true },
96
+ email: { type: "string", required: false },
97
+ });
98
+ registerCrud(rl, "organization", "organizations", getConn, {
99
+ name: { type: "string", required: true },
100
+ });
101
+ registerCrud(rl, "group", "groups", getConn, {
102
+ name: { type: "string", required: true },
45
103
  });
46
- registerCrud(rl, "user", "users", getConn, { firstname: { type: "string", required: true }, lastname: { type: "string", required: true }, email: { type: "string", required: false } });
47
- registerCrud(rl, "organization", "organizations", getConn, { name: { type: "string", required: true } });
48
- registerCrud(rl, "group", "groups", getConn, { name: { type: "string", required: true } });
49
104
  // ── Ticket (special: includes article) ──────────────
50
- rl.registerAction("ticket.create", { description: "Create a ticket", inputSchema: {
51
- title: { type: "string", required: true }, group: { type: "string", required: true },
52
- customer: { type: "string", required: true, description: "Customer email" },
53
- articleBody: { type: "string", required: true }, articleSubject: { type: "string", required: false },
105
+ rl.registerAction("ticket.create", {
106
+ description: "Create a ticket",
107
+ inputSchema: {
108
+ title: { type: "string", required: true },
109
+ group: { type: "string", required: true },
110
+ customer: {
111
+ type: "string",
112
+ required: true,
113
+ description: "Customer email",
114
+ },
115
+ articleBody: { type: "string", required: true },
116
+ articleSubject: { type: "string", required: false },
54
117
  articleInternal: { type: "boolean", required: false },
55
118
  },
56
119
  async execute(input, ctx) {
57
120
  const p = input;
58
- const body = { title: p.title, group: p.group, customer: p.customer, article: { body: p.articleBody, internal: p.articleInternal ?? false } };
121
+ const body = {
122
+ title: p.title,
123
+ group: p.group,
124
+ customer: p.customer,
125
+ article: { body: p.articleBody, internal: p.articleInternal ?? false },
126
+ };
59
127
  if (p.articleSubject)
60
128
  body.article.subject = p.articleSubject;
61
129
  return api(getConn(ctx), "POST", "/tickets", body);
62
- } });
63
- rl.registerAction("ticket.get", { description: "Get a ticket with articles", inputSchema: { id: { type: "string", required: true } },
130
+ },
131
+ });
132
+ rl.registerAction("ticket.get", {
133
+ description: "Get a ticket with articles",
134
+ inputSchema: { id: { type: "string", required: true } },
64
135
  async execute(input, ctx) {
65
136
  const c = getConn(ctx);
66
137
  const id = input.id;
67
138
  const ticket = (await api(c, "GET", `/tickets/${id}`));
68
139
  ticket.articles = await api(c, "GET", `/ticket_articles/by_ticket/${id}`);
69
140
  return ticket;
70
- } });
71
- rl.registerAction("ticket.list", { description: "List tickets", inputSchema: { limit: { type: "number", required: false } },
141
+ },
142
+ });
143
+ rl.registerAction("ticket.list", {
144
+ description: "List tickets",
145
+ inputSchema: { limit: { type: "number", required: false } },
72
146
  async execute(input, ctx) {
73
- const qs = { per_page: (input ?? {}).limit ?? 100 };
147
+ const qs = {
148
+ per_page: (input ?? {}).limit ?? 100,
149
+ };
74
150
  return api(getConn(ctx), "GET", "/tickets", undefined, qs);
75
- } });
76
- rl.registerAction("ticket.update", { description: "Update a ticket", inputSchema: { id: { type: "string", required: true }, data: { type: "object", required: true } },
77
- async execute(input, ctx) { const p = input; return api(getConn(ctx), "PUT", `/tickets/${p.id}`, p.data); } });
78
- rl.registerAction("ticket.delete", { description: "Delete a ticket", inputSchema: { id: { type: "string", required: true } },
79
- async execute(input, ctx) { await api(getConn(ctx), "DELETE", `/tickets/${input.id}`); return { success: true }; } });
151
+ },
152
+ });
153
+ rl.registerAction("ticket.update", {
154
+ description: "Update a ticket",
155
+ inputSchema: {
156
+ id: { type: "string", required: true },
157
+ data: { type: "object", required: true },
158
+ },
159
+ async execute(input, ctx) {
160
+ const p = input;
161
+ return api(getConn(ctx), "PUT", `/tickets/${p.id}`, p.data);
162
+ },
163
+ });
164
+ rl.registerAction("ticket.delete", {
165
+ description: "Delete a ticket",
166
+ inputSchema: { id: { type: "string", required: true } },
167
+ async execute(input, ctx) {
168
+ await api(getConn(ctx), "DELETE", `/tickets/${input.id}`);
169
+ return { success: true };
170
+ },
171
+ });
80
172
  // ── User extras ─────────────────────────────────────
81
- rl.registerAction("user.getSelf", { description: "Get the current user", inputSchema: {},
82
- async execute(_input, ctx) { return api(getConn(ctx), "GET", "/users/me"); } });
83
- rl.registerAction("user.search", { description: "Search users", inputSchema: { query: { type: "string", required: true }, limit: { type: "number", required: false } },
173
+ rl.registerAction("user.getSelf", {
174
+ description: "Get the current user",
175
+ inputSchema: {},
176
+ async execute(_input, ctx) {
177
+ return api(getConn(ctx), "GET", "/users/me");
178
+ },
179
+ });
180
+ rl.registerAction("user.search", {
181
+ description: "Search users",
182
+ inputSchema: {
183
+ query: { type: "string", required: true },
184
+ limit: { type: "number", required: false },
185
+ },
84
186
  async execute(input, ctx) {
85
187
  const p = input;
86
188
  const qs = { query: p.query };
87
189
  if (p.limit)
88
190
  qs.per_page = p.limit;
89
191
  return api(getConn(ctx), "GET", "/users/search", undefined, qs);
90
- } });
192
+ },
193
+ });
91
194
  }