runline 0.2.0 → 0.2.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 (190) hide show
  1. package/README.md +1 -1
  2. package/dist/plugins/actionNetwork/src/index.js +118 -25
  3. package/dist/plugins/activeCampaign/src/index.js +184 -38
  4. package/dist/plugins/adalo/src/index.js +40 -8
  5. package/dist/plugins/affinity/src/index.js +100 -20
  6. package/dist/plugins/agileCrm/src/index.js +115 -27
  7. package/dist/plugins/airtable/src/index.js +94 -19
  8. package/dist/plugins/airtop/src/index.js +266 -62
  9. package/dist/plugins/apiTemplateIo/src/index.js +25 -5
  10. package/dist/plugins/asana/src/index.js +195 -41
  11. package/dist/plugins/autopilot/src/index.js +39 -8
  12. package/dist/plugins/bambooHr/src/index.js +109 -22
  13. package/dist/plugins/bannerbear/src/index.js +36 -8
  14. package/dist/plugins/baserow/src/index.js +35 -7
  15. package/dist/plugins/beeminder/src/index.js +198 -40
  16. package/dist/plugins/bitly/src/index.js +46 -10
  17. package/dist/plugins/bitwarden/src/index.js +167 -36
  18. package/dist/plugins/box/src/index.js +172 -37
  19. package/dist/plugins/brandfetch/src/index.js +5 -1
  20. package/dist/plugins/brevo/src/index.js +136 -29
  21. package/dist/plugins/bubble/src/index.js +76 -17
  22. package/dist/plugins/chargebee/src/index.js +35 -7
  23. package/dist/plugins/circleci/src/index.js +50 -10
  24. package/dist/plugins/ciscoWebex/src/index.js +131 -27
  25. package/dist/plugins/clearbit/src/index.js +76 -17
  26. package/dist/plugins/clickup/src/index.js +500 -107
  27. package/dist/plugins/clockify/src/index.js +229 -47
  28. package/dist/plugins/cloudflare/src/index.js +28 -6
  29. package/dist/plugins/cockpit/src/index.js +54 -12
  30. package/dist/plugins/coda/src/index.js +81 -19
  31. package/dist/plugins/coingecko/src/index.js +157 -33
  32. package/dist/plugins/contentful/src/index.js +85 -17
  33. package/dist/plugins/convertkit/src/index.js +74 -18
  34. package/dist/plugins/copper/src/index.js +59 -11
  35. package/dist/plugins/cortex/src/index.js +55 -13
  36. package/dist/plugins/currents/src/index.js +310 -71
  37. package/dist/plugins/customerIo/src/index.js +112 -23
  38. package/dist/plugins/databricks/src/index.js +549 -115
  39. package/dist/plugins/deepl/src/index.js +26 -6
  40. package/dist/plugins/demio/src/index.js +56 -11
  41. package/dist/plugins/dhl/src/index.js +16 -3
  42. package/dist/plugins/discord/src/index.js +141 -31
  43. package/dist/plugins/discourse/src/index.js +136 -31
  44. package/dist/plugins/disqus/src/index.js +96 -20
  45. package/dist/plugins/docker/src/index.js +20 -4
  46. package/dist/plugins/drift/src/index.js +19 -5
  47. package/dist/plugins/dropbox/src/index.js +139 -30
  48. package/dist/plugins/dropcontact/src/index.js +21 -4
  49. package/dist/plugins/egoi/src/index.js +61 -15
  50. package/dist/plugins/elasticsearch/src/index.js +59 -13
  51. package/dist/plugins/emelia/src/index.js +95 -19
  52. package/dist/plugins/erpnext/src/index.js +74 -15
  53. package/dist/plugins/facebookGraph/src/index.js +52 -11
  54. package/dist/plugins/freshdesk/src/index.js +220 -48
  55. package/dist/plugins/freshservice/src/index.js +39 -9
  56. package/dist/plugins/freshworksCrm/src/index.js +58 -12
  57. package/dist/plugins/getresponse/src/index.js +87 -18
  58. package/dist/plugins/ghost/src/index.js +114 -26
  59. package/dist/plugins/github/src/index.js +483 -109
  60. package/dist/plugins/gitlab/src/index.js +193 -45
  61. package/dist/plugins/gong/src/index.js +68 -14
  62. package/dist/plugins/gotify/src/index.js +43 -9
  63. package/dist/plugins/gotowebinar/src/index.js +233 -47
  64. package/dist/plugins/grafana/src/index.js +92 -21
  65. package/dist/plugins/graphql/src/index.js +38 -8
  66. package/dist/plugins/grist/src/index.js +52 -10
  67. package/dist/plugins/hackernews/src/index.js +32 -6
  68. package/dist/plugins/halopsa/src/index.js +131 -26
  69. package/dist/plugins/harvest/src/index.js +182 -42
  70. package/dist/plugins/helpscout/src/index.js +153 -31
  71. package/dist/plugins/highlevel/src/index.js +291 -58
  72. package/dist/plugins/homeAssistant/src/index.js +124 -26
  73. package/dist/plugins/hubspot/src/index.js +163 -29
  74. package/dist/plugins/humanticAi/src/index.js +54 -5
  75. package/dist/plugins/hunter/src/index.js +21 -4
  76. package/dist/plugins/intercom/src/index.js +95 -20
  77. package/dist/plugins/iterable/src/index.js +96 -20
  78. package/dist/plugins/jenkins/src/index.js +75 -17
  79. package/dist/plugins/jira/src/index.js +193 -43
  80. package/dist/plugins/keap/src/index.js +222 -56
  81. package/dist/plugins/kobotoolbox/src/index.js +113 -25
  82. package/dist/plugins/lemlist/src/index.js +79 -18
  83. package/dist/plugins/linear/src/index.js +86 -19
  84. package/dist/plugins/lingvanex/src/index.js +38 -8
  85. package/dist/plugins/linkedin/src/index.js +37 -8
  86. package/dist/plugins/lonescale/src/index.js +41 -9
  87. package/dist/plugins/magento/src/index.js +98 -27
  88. package/dist/plugins/mailcheck/src/index.js +11 -2
  89. package/dist/plugins/mailchimp/src/index.js +193 -42
  90. package/dist/plugins/mailerlite/src/index.js +61 -12
  91. package/dist/plugins/mailgun/src/index.js +39 -7
  92. package/dist/plugins/mailjet/src/index.js +141 -30
  93. package/dist/plugins/mandrill/src/index.js +67 -14
  94. package/dist/plugins/marketstack/src/index.js +56 -10
  95. package/dist/plugins/matrix/src/index.js +97 -20
  96. package/dist/plugins/mattermost/src/index.js +124 -26
  97. package/dist/plugins/mautic/src/index.js +129 -26
  98. package/dist/plugins/medium/src/index.js +64 -13
  99. package/dist/plugins/messagebird/src/index.js +80 -15
  100. package/dist/plugins/metabase/src/index.js +57 -12
  101. package/dist/plugins/misp/src/index.js +135 -33
  102. package/dist/plugins/mocean/src/index.js +33 -7
  103. package/dist/plugins/monday/src/index.js +97 -23
  104. package/dist/plugins/monicaCrm/src/index.js +112 -23
  105. package/dist/plugins/msg91/src/index.js +11 -2
  106. package/dist/plugins/nasa/src/index.js +108 -21
  107. package/dist/plugins/netlify/src/index.js +28 -6
  108. package/dist/plugins/netscalerAdc/src/index.js +144 -29
  109. package/dist/plugins/nextcloud/src/index.js +103 -20
  110. package/dist/plugins/nocodb/src/index.js +57 -11
  111. package/dist/plugins/notion/src/index.js +148 -37
  112. package/dist/plugins/npm/src/index.js +59 -12
  113. package/dist/plugins/odoo/src/index.js +102 -20
  114. package/dist/plugins/okta/src/index.js +50 -10
  115. package/dist/plugins/oneSimpleApi/src/index.js +84 -17
  116. package/dist/plugins/onfleet/src/index.js +139 -32
  117. package/dist/plugins/openThesaurus/src/index.js +46 -9
  118. package/dist/plugins/openweathermap/src/index.js +31 -6
  119. package/dist/plugins/oura/src/index.js +36 -7
  120. package/dist/plugins/paddle/src/index.js +80 -17
  121. package/dist/plugins/pagerduty/src/index.js +53 -12
  122. package/dist/plugins/paypal/src/index.js +51 -11
  123. package/dist/plugins/peekalink/src/index.js +12 -3
  124. package/dist/plugins/phantombuster/src/index.js +39 -8
  125. package/dist/plugins/philipsHue/src/index.js +64 -13
  126. package/dist/plugins/pipedrive/src/index.js +167 -45
  127. package/dist/plugins/plivo/src/index.js +43 -8
  128. package/dist/plugins/postbin/src/index.js +9 -2
  129. package/dist/plugins/posthog/src/index.js +50 -13
  130. package/dist/plugins/profitwell/src/index.js +24 -5
  131. package/dist/plugins/pushbullet/src/index.js +45 -9
  132. package/dist/plugins/pushcut/src/index.js +31 -6
  133. package/dist/plugins/pushover/src/index.js +51 -10
  134. package/dist/plugins/quickbase/src/index.js +66 -13
  135. package/dist/plugins/quickbooks/src/index.js +86 -19
  136. package/dist/plugins/quickchart/src/index.js +35 -7
  137. package/dist/plugins/raindrop/src/index.js +54 -13
  138. package/dist/plugins/reddit/src/index.js +73 -18
  139. package/dist/plugins/rocketchat/src/index.js +47 -9
  140. package/dist/plugins/rundeck/src/index.js +26 -5
  141. package/dist/plugins/salesforce/src/index.js +161 -31
  142. package/dist/plugins/salesmate/src/index.js +75 -16
  143. package/dist/plugins/securityScorecard/src/index.js +73 -15
  144. package/dist/plugins/segment/src/index.js +21 -4
  145. package/dist/plugins/sendgrid/src/index.js +102 -24
  146. package/dist/plugins/sendy/src/index.js +54 -11
  147. package/dist/plugins/sentry/src/index.js +174 -34
  148. package/dist/plugins/servicenow/src/index.js +120 -27
  149. package/dist/plugins/shopify/src/index.js +53 -12
  150. package/dist/plugins/signl4/src/index.js +16 -3
  151. package/dist/plugins/slack/src/index.js +407 -105
  152. package/dist/plugins/sms77/src/index.js +26 -5
  153. package/dist/plugins/splunk/src/index.js +186 -45
  154. package/dist/plugins/spotify/src/index.js +265 -66
  155. package/dist/plugins/stackby/src/index.js +18 -6
  156. package/dist/plugins/storyblok/src/index.js +57 -11
  157. package/dist/plugins/strapi/src/index.js +63 -12
  158. package/dist/plugins/strava/src/index.js +58 -13
  159. package/dist/plugins/stripe/src/index.js +143 -30
  160. package/dist/plugins/supabase/src/index.js +49 -10
  161. package/dist/plugins/syncromsp/src/index.js +245 -67
  162. package/dist/plugins/tapfiliate/src/index.js +57 -14
  163. package/dist/plugins/telegram/src/index.js +202 -39
  164. package/dist/plugins/thehive/src/index.js +271 -66
  165. package/dist/plugins/thehiveProject/src/index.js +457 -89
  166. package/dist/plugins/todoist/src/index.js +326 -77
  167. package/dist/plugins/travisci/src/index.js +35 -8
  168. package/dist/plugins/trello/src/index.js +204 -46
  169. package/dist/plugins/twake/src/index.js +10 -2
  170. package/dist/plugins/twilio/src/index.js +56 -11
  171. package/dist/plugins/twist/src/index.js +241 -48
  172. package/dist/plugins/twitter/src/index.js +128 -30
  173. package/dist/plugins/unleashedSoftware/src/index.js +30 -6
  174. package/dist/plugins/uplead/src/index.js +9 -2
  175. package/dist/plugins/uproc/src/index.js +31 -6
  176. package/dist/plugins/uptimerobot/src/index.js +119 -25
  177. package/dist/plugins/urlscanio/src/index.js +25 -6
  178. package/dist/plugins/vero/src/index.js +68 -13
  179. package/dist/plugins/vonage/src/index.js +32 -6
  180. package/dist/plugins/wekan/src/index.js +297 -52
  181. package/dist/plugins/woocommerce/src/index.js +57 -12
  182. package/dist/plugins/wordpress/src/index.js +94 -18
  183. package/dist/plugins/xero/src/index.js +79 -13
  184. package/dist/plugins/yourls/src/index.js +33 -6
  185. package/dist/plugins/zammad/src/index.js +139 -36
  186. package/dist/plugins/zendesk/src/index.js +201 -48
  187. package/dist/plugins/zoho/src/index.js +88 -21
  188. package/dist/plugins/zoom/src/index.js +41 -7
  189. package/dist/plugins/zulip/src/index.js +101 -20
  190. package/package.json +1 -1
@@ -2,22 +2,50 @@ export default function graphql(rl) {
2
2
  rl.setName("graphql");
3
3
  rl.setVersion("0.1.0");
4
4
  rl.setConnectionSchema({
5
- endpoint: { type: "string", required: true, description: "GraphQL endpoint URL", env: "GRAPHQL_ENDPOINT" },
6
- headerAuth: { type: "string", required: false, description: "Authorization header value (e.g. 'Bearer xxx')", env: "GRAPHQL_AUTH_HEADER" },
7
- headers: { type: "object", required: false, description: "Additional headers as key-value pairs" },
5
+ endpoint: {
6
+ type: "string",
7
+ required: true,
8
+ description: "GraphQL endpoint URL",
9
+ env: "GRAPHQL_ENDPOINT",
10
+ },
11
+ headerAuth: {
12
+ type: "string",
13
+ required: false,
14
+ description: "Authorization header value (e.g. 'Bearer xxx')",
15
+ env: "GRAPHQL_AUTH_HEADER",
16
+ },
17
+ headers: {
18
+ type: "object",
19
+ required: false,
20
+ description: "Additional headers as key-value pairs",
21
+ },
8
22
  });
9
23
  rl.registerAction("query", {
10
24
  description: "Execute a GraphQL query",
11
25
  inputSchema: {
12
- query: { type: "string", required: true, description: "GraphQL query or mutation string" },
13
- variables: { type: "object", required: false, description: "Query variables" },
14
- operationName: { type: "string", required: false, description: "Operation name (if query contains multiple)" },
26
+ query: {
27
+ type: "string",
28
+ required: true,
29
+ description: "GraphQL query or mutation string",
30
+ },
31
+ variables: {
32
+ type: "object",
33
+ required: false,
34
+ description: "Query variables",
35
+ },
36
+ operationName: {
37
+ type: "string",
38
+ required: false,
39
+ description: "Operation name (if query contains multiple)",
40
+ },
15
41
  },
16
42
  async execute(input, ctx) {
17
43
  const { query, variables, operationName } = input;
18
44
  const cfg = ctx.connection.config;
19
45
  const endpoint = cfg.endpoint;
20
- const hdrs = { "Content-Type": "application/json" };
46
+ const hdrs = {
47
+ "Content-Type": "application/json",
48
+ };
21
49
  if (cfg.headerAuth)
22
50
  hdrs.Authorization = cfg.headerAuth;
23
51
  if (cfg.headers) {
@@ -48,7 +76,9 @@ export default function graphql(rl) {
48
76
  async execute(_input, ctx) {
49
77
  const cfg = ctx.connection.config;
50
78
  const endpoint = cfg.endpoint;
51
- const hdrs = { "Content-Type": "application/json" };
79
+ const hdrs = {
80
+ "Content-Type": "application/json",
81
+ };
52
82
  if (cfg.headerAuth)
53
83
  hdrs.Authorization = cfg.headerAuth;
54
84
  if (cfg.headers) {
@@ -8,7 +8,10 @@ async function apiRequest(baseUrl, apiKey, method, endpoint, body, qs) {
8
8
  }
9
9
  const opts = {
10
10
  method,
11
- headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json" },
11
+ headers: {
12
+ Authorization: `Bearer ${apiKey}`,
13
+ "Content-Type": "application/json",
14
+ },
12
15
  };
13
16
  if (body !== undefined && method !== "GET" && method !== "DELETE") {
14
17
  opts.body = JSON.stringify(body);
@@ -36,17 +39,40 @@ export default function grist(rl) {
36
39
  rl.setName("grist");
37
40
  rl.setVersion("0.1.0");
38
41
  rl.setConnectionSchema({
39
- apiKey: { type: "string", required: true, description: "Grist API key", env: "GRIST_API_KEY" },
40
- planType: { type: "string", required: false, description: "free (default), paid, or selfHosted", default: "free" },
41
- subdomain: { type: "string", required: false, description: "Subdomain for paid plan" },
42
- selfHostedUrl: { type: "string", required: false, description: "Full URL for self-hosted", env: "GRIST_URL" },
42
+ apiKey: {
43
+ type: "string",
44
+ required: true,
45
+ description: "Grist API key",
46
+ env: "GRIST_API_KEY",
47
+ },
48
+ planType: {
49
+ type: "string",
50
+ required: false,
51
+ description: "free (default), paid, or selfHosted",
52
+ default: "free",
53
+ },
54
+ subdomain: {
55
+ type: "string",
56
+ required: false,
57
+ description: "Subdomain for paid plan",
58
+ },
59
+ selfHostedUrl: {
60
+ type: "string",
61
+ required: false,
62
+ description: "Full URL for self-hosted",
63
+ env: "GRIST_URL",
64
+ },
43
65
  });
44
66
  rl.registerAction("record.create", {
45
67
  description: "Create records in a table",
46
68
  inputSchema: {
47
69
  docId: { type: "string", required: true, description: "Document ID" },
48
70
  tableId: { type: "string", required: true, description: "Table ID" },
49
- records: { type: "array", required: true, description: "Array of {fields: {col: value}} objects" },
71
+ records: {
72
+ type: "array",
73
+ required: true,
74
+ description: "Array of {fields: {col: value}} objects",
75
+ },
50
76
  },
51
77
  async execute(input, ctx) {
52
78
  const { docId, tableId, records } = input;
@@ -60,8 +86,16 @@ export default function grist(rl) {
60
86
  docId: { type: "string", required: true, description: "Document ID" },
61
87
  tableId: { type: "string", required: true, description: "Table ID" },
62
88
  limit: { type: "number", required: false, description: "Max results" },
63
- sort: { type: "string", required: false, description: "Sort columns (e.g. 'Name,-Age')" },
64
- filter: { type: "object", required: false, description: "Filter as {column: [values]}" },
89
+ sort: {
90
+ type: "string",
91
+ required: false,
92
+ description: "Sort columns (e.g. 'Name,-Age')",
93
+ },
94
+ filter: {
95
+ type: "object",
96
+ required: false,
97
+ description: "Filter as {column: [values]}",
98
+ },
65
99
  },
66
100
  async execute(input, ctx) {
67
101
  const { docId, tableId, limit, sort, filter } = (input ?? {});
@@ -82,7 +116,11 @@ export default function grist(rl) {
82
116
  inputSchema: {
83
117
  docId: { type: "string", required: true, description: "Document ID" },
84
118
  tableId: { type: "string", required: true, description: "Table ID" },
85
- records: { type: "array", required: true, description: "Array of {id, fields: {col: value}} objects" },
119
+ records: {
120
+ type: "array",
121
+ required: true,
122
+ description: "Array of {id, fields: {col: value}} objects",
123
+ },
86
124
  },
87
125
  async execute(input, ctx) {
88
126
  const { docId, tableId, records } = input;
@@ -95,7 +133,11 @@ export default function grist(rl) {
95
133
  inputSchema: {
96
134
  docId: { type: "string", required: true, description: "Document ID" },
97
135
  tableId: { type: "string", required: true, description: "Table ID" },
98
- rowIds: { type: "array", required: true, description: "Array of row IDs to delete" },
136
+ rowIds: {
137
+ type: "array",
138
+ required: true,
139
+ description: "Array of row IDs to delete",
140
+ },
99
141
  },
100
142
  async execute(input, ctx) {
101
143
  const { docId, tableId, rowIds } = input;
@@ -26,7 +26,9 @@ export default function hackernews(rl) {
26
26
  rl.setConnectionSchema({});
27
27
  rl.registerAction("article.get", {
28
28
  description: "Get a Hacker News article/item by ID",
29
- inputSchema: { articleId: { type: "string", required: true, description: "Item ID" } },
29
+ inputSchema: {
30
+ articleId: { type: "string", required: true, description: "Item ID" },
31
+ },
30
32
  async execute(input) {
31
33
  return firebaseRequest(`item/${input.articleId}`);
32
34
  },
@@ -35,7 +37,11 @@ export default function hackernews(rl) {
35
37
  description: "Search Hacker News articles",
36
38
  inputSchema: {
37
39
  query: { type: "string", required: true, description: "Search query" },
38
- tags: { type: "string", required: false, description: "Filter tags: story, comment, ask_hn, show_hn, poll, front_page" },
40
+ tags: {
41
+ type: "string",
42
+ required: false,
43
+ description: "Filter tags: story, comment, ask_hn, show_hn, poll, front_page",
44
+ },
39
45
  limit: { type: "number", required: false, description: "Max results" },
40
46
  },
41
47
  async execute(input) {
@@ -51,14 +57,22 @@ export default function hackernews(rl) {
51
57
  });
52
58
  rl.registerAction("user.get", {
53
59
  description: "Get a Hacker News user by username",
54
- inputSchema: { username: { type: "string", required: true, description: "Username" } },
60
+ inputSchema: {
61
+ username: { type: "string", required: true, description: "Username" },
62
+ },
55
63
  async execute(input) {
56
64
  return firebaseRequest(`user/${input.username}`);
57
65
  },
58
66
  });
59
67
  rl.registerAction("all.top", {
60
68
  description: "Get top stories",
61
- inputSchema: { limit: { type: "number", required: false, description: "Max results (default: 30)" } },
69
+ inputSchema: {
70
+ limit: {
71
+ type: "number",
72
+ required: false,
73
+ description: "Max results (default: 30)",
74
+ },
75
+ },
62
76
  async execute(input) {
63
77
  const { limit = 30 } = (input ?? {});
64
78
  const ids = (await firebaseRequest("topstories"));
@@ -68,7 +82,13 @@ export default function hackernews(rl) {
68
82
  });
69
83
  rl.registerAction("all.new", {
70
84
  description: "Get newest stories",
71
- inputSchema: { limit: { type: "number", required: false, description: "Max results (default: 30)" } },
85
+ inputSchema: {
86
+ limit: {
87
+ type: "number",
88
+ required: false,
89
+ description: "Max results (default: 30)",
90
+ },
91
+ },
72
92
  async execute(input) {
73
93
  const { limit = 30 } = (input ?? {});
74
94
  const ids = (await firebaseRequest("newstories"));
@@ -78,7 +98,13 @@ export default function hackernews(rl) {
78
98
  });
79
99
  rl.registerAction("all.best", {
80
100
  description: "Get best stories",
81
- inputSchema: { limit: { type: "number", required: false, description: "Max results (default: 30)" } },
101
+ inputSchema: {
102
+ limit: {
103
+ type: "number",
104
+ required: false,
105
+ description: "Max results (default: 30)",
106
+ },
107
+ },
82
108
  async execute(input) {
83
109
  const { limit = 30 } = (input ?? {});
84
110
  const ids = (await firebaseRequest("beststories"));
@@ -3,12 +3,24 @@ async function getToken(authUrl, clientId, clientSecret, scope, tenant) {
3
3
  if (cachedToken && Date.now() < cachedToken.expiresAt)
4
4
  return cachedToken.token;
5
5
  const url = tenant ? `${authUrl}?tenant=${tenant}` : authUrl;
6
- const body = new URLSearchParams({ grant_type: "client_credentials", client_id: clientId, client_secret: clientSecret, scope });
7
- const res = await fetch(url, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: body.toString() });
6
+ const body = new URLSearchParams({
7
+ grant_type: "client_credentials",
8
+ client_id: clientId,
9
+ client_secret: clientSecret,
10
+ scope,
11
+ });
12
+ const res = await fetch(url, {
13
+ method: "POST",
14
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
15
+ body: body.toString(),
16
+ });
8
17
  if (!res.ok)
9
18
  throw new Error(`HaloPSA auth error ${res.status}: ${await res.text()}`);
10
19
  const data = (await res.json());
11
- cachedToken = { token: data.access_token, expiresAt: Date.now() + (data.expires_in - 60) * 1000 };
20
+ cachedToken = {
21
+ token: data.access_token,
22
+ expiresAt: Date.now() + (data.expires_in - 60) * 1000,
23
+ };
12
24
  return cachedToken.token;
13
25
  }
14
26
  async function apiRequest(apiUrl, token, method, endpoint, body, qs) {
@@ -19,8 +31,17 @@ async function apiRequest(apiUrl, token, method, endpoint, body, qs) {
19
31
  url.searchParams.set(k, String(v));
20
32
  }
21
33
  }
22
- const opts = { method, headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json" } };
23
- if (body && Object.keys(body).length > 0 && method !== "GET" && method !== "DELETE")
34
+ const opts = {
35
+ method,
36
+ headers: {
37
+ Authorization: `Bearer ${token}`,
38
+ "Content-Type": "application/json",
39
+ },
40
+ };
41
+ if (body &&
42
+ Object.keys(body).length > 0 &&
43
+ method !== "GET" &&
44
+ method !== "DELETE")
24
45
  opts.body = JSON.stringify(body);
25
46
  const res = await fetch(url.toString(), opts);
26
47
  if (!res.ok)
@@ -31,46 +52,130 @@ async function apiRequest(apiUrl, token, method, endpoint, body, qs) {
31
52
  }
32
53
  async function req(ctx, method, endpoint, body, qs) {
33
54
  const cfg = ctx.connection.config;
34
- const authUrl = cfg.hostingType === "on-premise" ? `${cfg.appUrl}/auth/token` : `${cfg.authUrl}/token`;
55
+ const authUrl = cfg.hostingType === "on-premise"
56
+ ? `${cfg.appUrl}/auth/token`
57
+ : `${cfg.authUrl}/token`;
35
58
  const token = await getToken(authUrl, cfg.clientId, cfg.clientSecret, cfg.scope ?? "all", cfg.tenant);
36
59
  return apiRequest(cfg.resourceApiUrl.replace(/\/$/, ""), token, method, endpoint, body, qs);
37
60
  }
38
61
  function registerCrud(rl, resource, apiPath) {
39
62
  rl.registerAction(`${resource}.create`, {
40
- description: `Create a ${resource}`, inputSchema: { properties: { type: "object", required: true, description: `${resource} data` } },
41
- async execute(input, ctx) { return req(ctx, "POST", apiPath, { ...input.properties }); },
63
+ description: `Create a ${resource}`,
64
+ inputSchema: {
65
+ properties: {
66
+ type: "object",
67
+ required: true,
68
+ description: `${resource} data`,
69
+ },
70
+ },
71
+ async execute(input, ctx) {
72
+ return req(ctx, "POST", apiPath, {
73
+ ...input.properties,
74
+ });
75
+ },
42
76
  });
43
77
  rl.registerAction(`${resource}.get`, {
44
- description: `Get a ${resource}`, inputSchema: { id: { type: "number", required: true, description: `${resource} ID` } },
45
- async execute(input, ctx) { return req(ctx, "GET", `${apiPath}/${input.id}`); },
78
+ description: `Get a ${resource}`,
79
+ inputSchema: {
80
+ id: { type: "number", required: true, description: `${resource} ID` },
81
+ },
82
+ async execute(input, ctx) {
83
+ return req(ctx, "GET", `${apiPath}/${input.id}`);
84
+ },
46
85
  });
47
86
  rl.registerAction(`${resource}.list`, {
48
- description: `List ${resource}s`, inputSchema: { limit: { type: "number", required: false, description: "Max results" }, page: { type: "number", required: false, description: "Page" } },
49
- async execute(input, ctx) { const { limit, page } = (input ?? {}); const qs = {}; if (limit)
50
- qs.count = limit; if (page)
51
- qs.page_no = page; return req(ctx, "GET", apiPath, undefined, qs); },
87
+ description: `List ${resource}s`,
88
+ inputSchema: {
89
+ limit: { type: "number", required: false, description: "Max results" },
90
+ page: { type: "number", required: false, description: "Page" },
91
+ },
92
+ async execute(input, ctx) {
93
+ const { limit, page } = (input ?? {});
94
+ const qs = {};
95
+ if (limit)
96
+ qs.count = limit;
97
+ if (page)
98
+ qs.page_no = page;
99
+ return req(ctx, "GET", apiPath, undefined, qs);
100
+ },
52
101
  });
53
102
  rl.registerAction(`${resource}.update`, {
54
- description: `Update a ${resource}`, inputSchema: { id: { type: "number", required: true, description: `${resource} ID` }, properties: { type: "object", required: true, description: "Fields to update" } },
55
- async execute(input, ctx) { const { id, properties } = input; return req(ctx, "PUT", apiPath, { id, ...properties }); },
103
+ description: `Update a ${resource}`,
104
+ inputSchema: {
105
+ id: { type: "number", required: true, description: `${resource} ID` },
106
+ properties: {
107
+ type: "object",
108
+ required: true,
109
+ description: "Fields to update",
110
+ },
111
+ },
112
+ async execute(input, ctx) {
113
+ const { id, properties } = input;
114
+ return req(ctx, "PUT", apiPath, { id, ...properties });
115
+ },
56
116
  });
57
117
  rl.registerAction(`${resource}.delete`, {
58
- description: `Delete a ${resource}`, inputSchema: { id: { type: "number", required: true, description: `${resource} ID` } },
59
- async execute(input, ctx) { await req(ctx, "DELETE", `${apiPath}/${input.id}`); return { success: true }; },
118
+ description: `Delete a ${resource}`,
119
+ inputSchema: {
120
+ id: { type: "number", required: true, description: `${resource} ID` },
121
+ },
122
+ async execute(input, ctx) {
123
+ await req(ctx, "DELETE", `${apiPath}/${input.id}`);
124
+ return { success: true };
125
+ },
60
126
  });
61
127
  }
62
128
  export default function halopsa(rl) {
63
129
  rl.setName("halopsa");
64
130
  rl.setVersion("0.1.0");
65
131
  rl.setConnectionSchema({
66
- hostingType: { type: "string", required: false, description: "cloud (default) or on-premise", default: "cloud" },
67
- authUrl: { type: "string", required: false, description: "Auth server URL (cloud)", env: "HALOPSA_AUTH_URL" },
68
- appUrl: { type: "string", required: false, description: "App URL (on-premise)", env: "HALOPSA_APP_URL" },
69
- resourceApiUrl: { type: "string", required: true, description: "Resource API URL", env: "HALOPSA_API_URL" },
70
- clientId: { type: "string", required: true, description: "OAuth2 client ID", env: "HALOPSA_CLIENT_ID" },
71
- clientSecret: { type: "string", required: true, description: "OAuth2 client secret", env: "HALOPSA_CLIENT_SECRET" },
72
- scope: { type: "string", required: false, description: "OAuth2 scope (default: all)", default: "all" },
73
- tenant: { type: "string", required: false, description: "Tenant (cloud only)" },
132
+ hostingType: {
133
+ type: "string",
134
+ required: false,
135
+ description: "cloud (default) or on-premise",
136
+ default: "cloud",
137
+ },
138
+ authUrl: {
139
+ type: "string",
140
+ required: false,
141
+ description: "Auth server URL (cloud)",
142
+ env: "HALOPSA_AUTH_URL",
143
+ },
144
+ appUrl: {
145
+ type: "string",
146
+ required: false,
147
+ description: "App URL (on-premise)",
148
+ env: "HALOPSA_APP_URL",
149
+ },
150
+ resourceApiUrl: {
151
+ type: "string",
152
+ required: true,
153
+ description: "Resource API URL",
154
+ env: "HALOPSA_API_URL",
155
+ },
156
+ clientId: {
157
+ type: "string",
158
+ required: true,
159
+ description: "OAuth2 client ID",
160
+ env: "HALOPSA_CLIENT_ID",
161
+ },
162
+ clientSecret: {
163
+ type: "string",
164
+ required: true,
165
+ description: "OAuth2 client secret",
166
+ env: "HALOPSA_CLIENT_SECRET",
167
+ },
168
+ scope: {
169
+ type: "string",
170
+ required: false,
171
+ description: "OAuth2 scope (default: all)",
172
+ default: "all",
173
+ },
174
+ tenant: {
175
+ type: "string",
176
+ required: false,
177
+ description: "Tenant (cloud only)",
178
+ },
74
179
  });
75
180
  registerCrud(rl, "client", "/client");
76
181
  registerCrud(rl, "site", "/site");