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.
- package/dist/commands/auth.d.ts +7 -0
- package/dist/commands/auth.js +96 -0
- package/dist/config/loader.d.ts +11 -0
- package/dist/config/loader.js +46 -0
- package/dist/core/engine.js +7 -1
- package/dist/core/oauth.d.ts +46 -0
- package/dist/core/oauth.js +145 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +2 -1
- package/dist/main.js +28 -0
- package/dist/plugin/api.d.ts +7 -1
- package/dist/plugin/api.js +7 -0
- package/dist/plugin/types.d.ts +47 -0
- package/dist/plugins/actionNetwork/src/index.js +118 -25
- package/dist/plugins/activeCampaign/src/index.js +184 -38
- package/dist/plugins/adalo/src/index.js +40 -8
- package/dist/plugins/affinity/src/index.js +100 -20
- package/dist/plugins/agileCrm/src/index.js +115 -27
- package/dist/plugins/airtable/src/index.js +94 -19
- package/dist/plugins/airtop/src/index.js +266 -62
- package/dist/plugins/apiTemplateIo/src/index.js +25 -5
- package/dist/plugins/asana/src/index.js +195 -41
- package/dist/plugins/autopilot/src/index.js +39 -8
- package/dist/plugins/bambooHr/src/index.js +109 -22
- package/dist/plugins/bannerbear/src/index.js +36 -8
- package/dist/plugins/baserow/src/index.js +35 -7
- package/dist/plugins/beeminder/src/index.js +198 -40
- package/dist/plugins/bitly/src/index.js +46 -10
- package/dist/plugins/bitwarden/src/index.js +167 -36
- package/dist/plugins/box/src/index.js +172 -37
- package/dist/plugins/brandfetch/src/index.js +5 -1
- package/dist/plugins/brevo/src/index.js +136 -29
- package/dist/plugins/bubble/src/index.js +76 -17
- package/dist/plugins/chargebee/src/index.js +35 -7
- package/dist/plugins/circleci/src/index.js +50 -10
- package/dist/plugins/ciscoWebex/src/index.js +131 -27
- package/dist/plugins/clearbit/src/index.js +76 -17
- package/dist/plugins/clickup/src/index.js +500 -107
- package/dist/plugins/clockify/src/index.js +229 -47
- package/dist/plugins/cloudflare/src/index.js +28 -6
- package/dist/plugins/cockpit/src/index.js +54 -12
- package/dist/plugins/coda/src/index.js +81 -19
- package/dist/plugins/coingecko/src/index.js +157 -33
- package/dist/plugins/contentful/src/index.js +85 -17
- package/dist/plugins/convertkit/src/index.js +74 -18
- package/dist/plugins/copper/src/index.js +59 -11
- package/dist/plugins/cortex/src/index.js +55 -13
- package/dist/plugins/currents/src/index.js +310 -71
- package/dist/plugins/customerIo/src/index.js +112 -23
- package/dist/plugins/databricks/src/index.js +549 -115
- package/dist/plugins/deepl/src/index.js +26 -6
- package/dist/plugins/demio/src/index.js +56 -11
- package/dist/plugins/dhl/src/index.js +16 -3
- package/dist/plugins/discord/src/index.js +141 -31
- package/dist/plugins/discourse/src/index.js +136 -31
- package/dist/plugins/disqus/src/index.js +96 -20
- package/dist/plugins/docker/src/index.js +20 -4
- package/dist/plugins/drift/src/index.js +19 -5
- package/dist/plugins/dropbox/src/index.js +139 -30
- package/dist/plugins/dropcontact/src/index.js +21 -4
- package/dist/plugins/egoi/src/index.js +61 -15
- package/dist/plugins/elasticsearch/src/index.js +59 -13
- package/dist/plugins/emelia/src/index.js +95 -19
- package/dist/plugins/erpnext/src/index.js +74 -15
- package/dist/plugins/facebookGraph/src/index.js +52 -11
- package/dist/plugins/freshdesk/src/index.js +220 -48
- package/dist/plugins/freshservice/src/index.js +39 -9
- package/dist/plugins/freshworksCrm/src/index.js +58 -12
- package/dist/plugins/getresponse/src/index.js +87 -18
- package/dist/plugins/ghost/src/index.js +114 -26
- package/dist/plugins/github/src/index.js +483 -109
- package/dist/plugins/gitlab/src/index.js +193 -45
- package/dist/plugins/gmail/src/index.js +1075 -0
- package/dist/plugins/gong/src/index.js +68 -14
- package/dist/plugins/gotify/src/index.js +43 -9
- package/dist/plugins/gotowebinar/src/index.js +233 -47
- package/dist/plugins/grafana/src/index.js +92 -21
- package/dist/plugins/graphql/src/index.js +38 -8
- package/dist/plugins/grist/src/index.js +52 -10
- package/dist/plugins/hackernews/src/index.js +32 -6
- package/dist/plugins/halopsa/src/index.js +131 -26
- package/dist/plugins/harvest/src/index.js +182 -42
- package/dist/plugins/helpscout/src/index.js +153 -31
- package/dist/plugins/highlevel/src/index.js +291 -58
- package/dist/plugins/homeAssistant/src/index.js +124 -26
- package/dist/plugins/hubspot/src/index.js +163 -29
- package/dist/plugins/humanticAi/src/index.js +54 -5
- package/dist/plugins/hunter/src/index.js +21 -4
- package/dist/plugins/intercom/src/index.js +95 -20
- package/dist/plugins/iterable/src/index.js +96 -20
- package/dist/plugins/jenkins/src/index.js +75 -17
- package/dist/plugins/jira/src/index.js +193 -43
- package/dist/plugins/keap/src/index.js +222 -56
- package/dist/plugins/kobotoolbox/src/index.js +113 -25
- package/dist/plugins/lemlist/src/index.js +79 -18
- package/dist/plugins/linear/src/index.js +86 -19
- package/dist/plugins/lingvanex/src/index.js +38 -8
- package/dist/plugins/linkedin/src/index.js +37 -8
- package/dist/plugins/lonescale/src/index.js +41 -9
- package/dist/plugins/magento/src/index.js +98 -27
- package/dist/plugins/mailcheck/src/index.js +11 -2
- package/dist/plugins/mailchimp/src/index.js +193 -42
- package/dist/plugins/mailerlite/src/index.js +61 -12
- package/dist/plugins/mailgun/src/index.js +39 -7
- package/dist/plugins/mailjet/src/index.js +141 -30
- package/dist/plugins/mandrill/src/index.js +67 -14
- package/dist/plugins/marketstack/src/index.js +56 -10
- package/dist/plugins/matrix/src/index.js +97 -20
- package/dist/plugins/mattermost/src/index.js +124 -26
- package/dist/plugins/mautic/src/index.js +129 -26
- package/dist/plugins/medium/src/index.js +64 -13
- package/dist/plugins/messagebird/src/index.js +80 -15
- package/dist/plugins/metabase/src/index.js +57 -12
- package/dist/plugins/misp/src/index.js +135 -33
- package/dist/plugins/mocean/src/index.js +33 -7
- package/dist/plugins/monday/src/index.js +97 -23
- package/dist/plugins/monicaCrm/src/index.js +112 -23
- package/dist/plugins/msg91/src/index.js +11 -2
- package/dist/plugins/nasa/src/index.js +108 -21
- package/dist/plugins/netlify/src/index.js +28 -6
- package/dist/plugins/netscalerAdc/src/index.js +144 -29
- package/dist/plugins/nextcloud/src/index.js +103 -20
- package/dist/plugins/nocodb/src/index.js +57 -11
- package/dist/plugins/notion/src/index.js +148 -37
- package/dist/plugins/npm/src/index.js +59 -12
- package/dist/plugins/odoo/src/index.js +102 -20
- package/dist/plugins/okta/src/index.js +50 -10
- package/dist/plugins/oneSimpleApi/src/index.js +84 -17
- package/dist/plugins/onfleet/src/index.js +139 -32
- package/dist/plugins/openThesaurus/src/index.js +46 -9
- package/dist/plugins/openweathermap/src/index.js +31 -6
- package/dist/plugins/oura/src/index.js +36 -7
- package/dist/plugins/paddle/src/index.js +80 -17
- package/dist/plugins/pagerduty/src/index.js +53 -12
- package/dist/plugins/paypal/src/index.js +51 -11
- package/dist/plugins/peekalink/src/index.js +12 -3
- package/dist/plugins/phantombuster/src/index.js +39 -8
- package/dist/plugins/philipsHue/src/index.js +64 -13
- package/dist/plugins/pipedrive/src/index.js +167 -45
- package/dist/plugins/plivo/src/index.js +43 -8
- package/dist/plugins/postbin/src/index.js +9 -2
- package/dist/plugins/posthog/src/index.js +50 -13
- package/dist/plugins/profitwell/src/index.js +24 -5
- package/dist/plugins/pushbullet/src/index.js +45 -9
- package/dist/plugins/pushcut/src/index.js +31 -6
- package/dist/plugins/pushover/src/index.js +51 -10
- package/dist/plugins/quickbase/src/index.js +66 -13
- package/dist/plugins/quickbooks/src/index.js +86 -19
- package/dist/plugins/quickchart/src/index.js +35 -7
- package/dist/plugins/raindrop/src/index.js +54 -13
- package/dist/plugins/reddit/src/index.js +73 -18
- package/dist/plugins/rocketchat/src/index.js +47 -9
- package/dist/plugins/rundeck/src/index.js +26 -5
- package/dist/plugins/salesforce/src/index.js +161 -31
- package/dist/plugins/salesmate/src/index.js +75 -16
- package/dist/plugins/securityScorecard/src/index.js +73 -15
- package/dist/plugins/segment/src/index.js +21 -4
- package/dist/plugins/sendgrid/src/index.js +102 -24
- package/dist/plugins/sendy/src/index.js +54 -11
- package/dist/plugins/sentry/src/index.js +174 -34
- package/dist/plugins/servicenow/src/index.js +120 -27
- package/dist/plugins/shopify/src/index.js +53 -12
- package/dist/plugins/signl4/src/index.js +16 -3
- package/dist/plugins/slack/src/index.js +407 -105
- package/dist/plugins/sms77/src/index.js +26 -5
- package/dist/plugins/splunk/src/index.js +186 -45
- package/dist/plugins/spotify/src/index.js +265 -66
- package/dist/plugins/stackby/src/index.js +18 -6
- package/dist/plugins/storyblok/src/index.js +57 -11
- package/dist/plugins/strapi/src/index.js +63 -12
- package/dist/plugins/strava/src/index.js +58 -13
- package/dist/plugins/stripe/src/index.js +143 -30
- package/dist/plugins/supabase/src/index.js +49 -10
- package/dist/plugins/syncromsp/src/index.js +245 -67
- package/dist/plugins/tapfiliate/src/index.js +57 -14
- package/dist/plugins/telegram/src/index.js +202 -39
- package/dist/plugins/thehive/src/index.js +271 -66
- package/dist/plugins/thehiveProject/src/index.js +457 -89
- package/dist/plugins/todoist/src/index.js +326 -77
- package/dist/plugins/travisci/src/index.js +35 -8
- package/dist/plugins/trello/src/index.js +204 -46
- package/dist/plugins/twake/src/index.js +10 -2
- package/dist/plugins/twilio/src/index.js +56 -11
- package/dist/plugins/twist/src/index.js +241 -48
- package/dist/plugins/twitter/src/index.js +128 -30
- package/dist/plugins/unleashedSoftware/src/index.js +30 -6
- package/dist/plugins/uplead/src/index.js +9 -2
- package/dist/plugins/uproc/src/index.js +31 -6
- package/dist/plugins/uptimerobot/src/index.js +119 -25
- package/dist/plugins/urlscanio/src/index.js +25 -6
- package/dist/plugins/vero/src/index.js +68 -13
- package/dist/plugins/vonage/src/index.js +32 -6
- package/dist/plugins/wekan/src/index.js +297 -52
- package/dist/plugins/woocommerce/src/index.js +57 -12
- package/dist/plugins/wordpress/src/index.js +94 -18
- package/dist/plugins/xero/src/index.js +79 -13
- package/dist/plugins/yourls/src/index.js +33 -6
- package/dist/plugins/zammad/src/index.js +139 -36
- package/dist/plugins/zendesk/src/index.js +201 -48
- package/dist/plugins/zoho/src/index.js +88 -21
- package/dist/plugins/zoom/src/index.js +41 -7
- package/dist/plugins/zulip/src/index.js +101 -20
- package/package.json +3 -1
|
@@ -8,9 +8,15 @@ async function apiRequest(baseUrl, apiKey, method, endpoint, body, qs) {
|
|
|
8
8
|
}
|
|
9
9
|
const opts = {
|
|
10
10
|
method,
|
|
11
|
-
headers: {
|
|
11
|
+
headers: {
|
|
12
|
+
Authorization: `Bearer ${apiKey}`,
|
|
13
|
+
"Content-Type": "application/json",
|
|
14
|
+
},
|
|
12
15
|
};
|
|
13
|
-
if (body &&
|
|
16
|
+
if (body &&
|
|
17
|
+
Object.keys(body).length > 0 &&
|
|
18
|
+
method !== "GET" &&
|
|
19
|
+
method !== "DELETE") {
|
|
14
20
|
opts.body = JSON.stringify(body);
|
|
15
21
|
}
|
|
16
22
|
const res = await fetch(url.toString(), opts);
|
|
@@ -34,16 +40,34 @@ export default function grafana(rl) {
|
|
|
34
40
|
rl.setName("grafana");
|
|
35
41
|
rl.setVersion("0.1.0");
|
|
36
42
|
rl.setConnectionSchema({
|
|
37
|
-
baseUrl: {
|
|
38
|
-
|
|
43
|
+
baseUrl: {
|
|
44
|
+
type: "string",
|
|
45
|
+
required: true,
|
|
46
|
+
description: "Grafana base URL (e.g. https://grafana.example.com)",
|
|
47
|
+
env: "GRAFANA_URL",
|
|
48
|
+
},
|
|
49
|
+
apiKey: {
|
|
50
|
+
type: "string",
|
|
51
|
+
required: true,
|
|
52
|
+
description: "Grafana API key or service account token",
|
|
53
|
+
env: "GRAFANA_API_KEY",
|
|
54
|
+
},
|
|
39
55
|
});
|
|
40
56
|
// ── Dashboard ───────────────────────────────────────
|
|
41
57
|
rl.registerAction("dashboard.create", {
|
|
42
58
|
description: "Create or save a dashboard",
|
|
43
59
|
inputSchema: {
|
|
44
|
-
dashboard: {
|
|
60
|
+
dashboard: {
|
|
61
|
+
type: "object",
|
|
62
|
+
required: true,
|
|
63
|
+
description: "Dashboard JSON model",
|
|
64
|
+
},
|
|
45
65
|
folderId: { type: "number", required: false, description: "Folder ID" },
|
|
46
|
-
overwrite: {
|
|
66
|
+
overwrite: {
|
|
67
|
+
type: "boolean",
|
|
68
|
+
required: false,
|
|
69
|
+
description: "Overwrite existing",
|
|
70
|
+
},
|
|
47
71
|
message: { type: "string", required: false, description: "Save message" },
|
|
48
72
|
},
|
|
49
73
|
async execute(input, ctx) {
|
|
@@ -60,7 +84,9 @@ export default function grafana(rl) {
|
|
|
60
84
|
});
|
|
61
85
|
rl.registerAction("dashboard.get", {
|
|
62
86
|
description: "Get a dashboard by UID",
|
|
63
|
-
inputSchema: {
|
|
87
|
+
inputSchema: {
|
|
88
|
+
uid: { type: "string", required: true, description: "Dashboard UID" },
|
|
89
|
+
},
|
|
64
90
|
async execute(input, ctx) {
|
|
65
91
|
return gf(ctx, "GET", `/dashboards/uid/${input.uid}`);
|
|
66
92
|
},
|
|
@@ -70,8 +96,16 @@ export default function grafana(rl) {
|
|
|
70
96
|
inputSchema: {
|
|
71
97
|
query: { type: "string", required: false, description: "Search query" },
|
|
72
98
|
tag: { type: "string", required: false, description: "Filter by tag" },
|
|
73
|
-
type: {
|
|
74
|
-
|
|
99
|
+
type: {
|
|
100
|
+
type: "string",
|
|
101
|
+
required: false,
|
|
102
|
+
description: "dash-db or dash-folder",
|
|
103
|
+
},
|
|
104
|
+
folderId: {
|
|
105
|
+
type: "number",
|
|
106
|
+
required: false,
|
|
107
|
+
description: "Filter by folder ID",
|
|
108
|
+
},
|
|
75
109
|
limit: { type: "number", required: false, description: "Max results" },
|
|
76
110
|
},
|
|
77
111
|
async execute(input, ctx) {
|
|
@@ -92,7 +126,9 @@ export default function grafana(rl) {
|
|
|
92
126
|
});
|
|
93
127
|
rl.registerAction("dashboard.delete", {
|
|
94
128
|
description: "Delete a dashboard by UID",
|
|
95
|
-
inputSchema: {
|
|
129
|
+
inputSchema: {
|
|
130
|
+
uid: { type: "string", required: true, description: "Dashboard UID" },
|
|
131
|
+
},
|
|
96
132
|
async execute(input, ctx) {
|
|
97
133
|
return gf(ctx, "DELETE", `/dashboards/uid/${input.uid}`);
|
|
98
134
|
},
|
|
@@ -100,14 +136,25 @@ export default function grafana(rl) {
|
|
|
100
136
|
rl.registerAction("dashboard.update", {
|
|
101
137
|
description: "Update an existing dashboard",
|
|
102
138
|
inputSchema: {
|
|
103
|
-
uid: {
|
|
104
|
-
|
|
139
|
+
uid: {
|
|
140
|
+
type: "string",
|
|
141
|
+
required: true,
|
|
142
|
+
description: "Dashboard UID to update",
|
|
143
|
+
},
|
|
144
|
+
dashboard: {
|
|
145
|
+
type: "object",
|
|
146
|
+
required: true,
|
|
147
|
+
description: "Updated dashboard JSON model",
|
|
148
|
+
},
|
|
105
149
|
folderId: { type: "number", required: false, description: "Folder ID" },
|
|
106
150
|
message: { type: "string", required: false, description: "Save message" },
|
|
107
151
|
},
|
|
108
152
|
async execute(input, ctx) {
|
|
109
153
|
const { uid, dashboard, folderId, message } = input;
|
|
110
|
-
const body = {
|
|
154
|
+
const body = {
|
|
155
|
+
dashboard: { ...dashboard, uid },
|
|
156
|
+
overwrite: true,
|
|
157
|
+
};
|
|
111
158
|
if (folderId !== undefined)
|
|
112
159
|
body.folderId = folderId;
|
|
113
160
|
if (message)
|
|
@@ -132,7 +179,9 @@ export default function grafana(rl) {
|
|
|
132
179
|
});
|
|
133
180
|
rl.registerAction("team.get", {
|
|
134
181
|
description: "Get a team by ID",
|
|
135
|
-
inputSchema: {
|
|
182
|
+
inputSchema: {
|
|
183
|
+
teamId: { type: "number", required: true, description: "Team ID" },
|
|
184
|
+
},
|
|
136
185
|
async execute(input, ctx) {
|
|
137
186
|
return gf(ctx, "GET", `/teams/${input.teamId}`);
|
|
138
187
|
},
|
|
@@ -176,7 +225,9 @@ export default function grafana(rl) {
|
|
|
176
225
|
});
|
|
177
226
|
rl.registerAction("team.delete", {
|
|
178
227
|
description: "Delete a team",
|
|
179
|
-
inputSchema: {
|
|
228
|
+
inputSchema: {
|
|
229
|
+
teamId: { type: "number", required: true, description: "Team ID" },
|
|
230
|
+
},
|
|
180
231
|
async execute(input, ctx) {
|
|
181
232
|
return gf(ctx, "DELETE", `/teams/${input.teamId}`);
|
|
182
233
|
},
|
|
@@ -197,7 +248,11 @@ export default function grafana(rl) {
|
|
|
197
248
|
description: "Remove a user from a team",
|
|
198
249
|
inputSchema: {
|
|
199
250
|
teamId: { type: "number", required: true, description: "Team ID" },
|
|
200
|
-
userId: {
|
|
251
|
+
userId: {
|
|
252
|
+
type: "number",
|
|
253
|
+
required: true,
|
|
254
|
+
description: "User ID to remove",
|
|
255
|
+
},
|
|
201
256
|
},
|
|
202
257
|
async execute(input, ctx) {
|
|
203
258
|
const { teamId, userId } = input;
|
|
@@ -206,7 +261,9 @@ export default function grafana(rl) {
|
|
|
206
261
|
});
|
|
207
262
|
rl.registerAction("teamMember.list", {
|
|
208
263
|
description: "List members of a team",
|
|
209
|
-
inputSchema: {
|
|
264
|
+
inputSchema: {
|
|
265
|
+
teamId: { type: "number", required: true, description: "Team ID" },
|
|
266
|
+
},
|
|
210
267
|
async execute(input, ctx) {
|
|
211
268
|
return gf(ctx, "GET", `/teams/${input.teamId}/members`);
|
|
212
269
|
},
|
|
@@ -215,8 +272,16 @@ export default function grafana(rl) {
|
|
|
215
272
|
rl.registerAction("user.create", {
|
|
216
273
|
description: "Add a user to the current organization",
|
|
217
274
|
inputSchema: {
|
|
218
|
-
loginOrEmail: {
|
|
219
|
-
|
|
275
|
+
loginOrEmail: {
|
|
276
|
+
type: "string",
|
|
277
|
+
required: true,
|
|
278
|
+
description: "Login name or email",
|
|
279
|
+
},
|
|
280
|
+
role: {
|
|
281
|
+
type: "string",
|
|
282
|
+
required: true,
|
|
283
|
+
description: "Viewer, Editor, or Admin",
|
|
284
|
+
},
|
|
220
285
|
},
|
|
221
286
|
async execute(input, ctx) {
|
|
222
287
|
const { loginOrEmail, role } = input;
|
|
@@ -233,7 +298,11 @@ export default function grafana(rl) {
|
|
|
233
298
|
description: "Update a user's role in the organization",
|
|
234
299
|
inputSchema: {
|
|
235
300
|
userId: { type: "number", required: true, description: "User ID" },
|
|
236
|
-
role: {
|
|
301
|
+
role: {
|
|
302
|
+
type: "string",
|
|
303
|
+
required: true,
|
|
304
|
+
description: "Viewer, Editor, or Admin",
|
|
305
|
+
},
|
|
237
306
|
},
|
|
238
307
|
async execute(input, ctx) {
|
|
239
308
|
const { userId, role } = input;
|
|
@@ -242,7 +311,9 @@ export default function grafana(rl) {
|
|
|
242
311
|
});
|
|
243
312
|
rl.registerAction("user.delete", {
|
|
244
313
|
description: "Remove a user from the organization",
|
|
245
|
-
inputSchema: {
|
|
314
|
+
inputSchema: {
|
|
315
|
+
userId: { type: "number", required: true, description: "User ID" },
|
|
316
|
+
},
|
|
246
317
|
async execute(input, ctx) {
|
|
247
318
|
return gf(ctx, "DELETE", `/org/users/${input.userId}`);
|
|
248
319
|
},
|
|
@@ -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: {
|
|
6
|
-
|
|
7
|
-
|
|
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: {
|
|
13
|
-
|
|
14
|
-
|
|
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 = {
|
|
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 = {
|
|
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: {
|
|
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: {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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: {
|
|
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: {
|
|
64
|
-
|
|
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: {
|
|
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: {
|
|
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: {
|
|
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: {
|
|
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: {
|
|
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: {
|
|
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: {
|
|
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: {
|
|
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({
|
|
7
|
-
|
|
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 = {
|
|
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 = {
|
|
23
|
-
|
|
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"
|
|
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}`,
|
|
41
|
-
|
|
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}`,
|
|
45
|
-
|
|
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`,
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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}`,
|
|
55
|
-
|
|
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}`,
|
|
59
|
-
|
|
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: {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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");
|