@erdoai/cli 0.40.2 → 0.42.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/index.js +85 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -127,9 +127,10 @@ function networkErrorFor(method, path, err) {
|
|
|
127
127
|
return new ErdoNetworkError(`${method} ${path} failed: ${detail}`, cause);
|
|
128
128
|
}
|
|
129
129
|
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
130
|
-
async function rawRequest(baseURL, token, orgId, method, path, body) {
|
|
130
|
+
async function rawRequest(baseURL, token, orgId, projectId, method, path, body) {
|
|
131
131
|
const headers = { Authorization: `Bearer ${token}` };
|
|
132
132
|
if (orgId) headers["X-Organization-ID"] = orgId;
|
|
133
|
+
if (projectId) headers["X-Project-ID"] = projectId;
|
|
133
134
|
if (body !== void 0) headers["Content-Type"] = "application/json";
|
|
134
135
|
const upper = method.toUpperCase();
|
|
135
136
|
const maxRetries = upper === "GET" || upper === "HEAD" ? 2 : 1;
|
|
@@ -178,13 +179,21 @@ function looksLikeHTML(text) {
|
|
|
178
179
|
return head.startsWith("<!doctype html") || head.startsWith("<html") || head.includes("<head>");
|
|
179
180
|
}
|
|
180
181
|
function fetchMe(token, orgId) {
|
|
181
|
-
return rawRequest(
|
|
182
|
+
return rawRequest(
|
|
183
|
+
resolveApiUrl(),
|
|
184
|
+
token,
|
|
185
|
+
orgId,
|
|
186
|
+
void 0,
|
|
187
|
+
"GET",
|
|
188
|
+
"/v1/me"
|
|
189
|
+
);
|
|
182
190
|
}
|
|
183
191
|
var announcedOrg = false;
|
|
184
192
|
var ErdoClient = class {
|
|
185
193
|
baseURL;
|
|
186
194
|
token;
|
|
187
195
|
orgId;
|
|
196
|
+
projectId;
|
|
188
197
|
orgPinned;
|
|
189
198
|
orgName;
|
|
190
199
|
constructor(orgOverride) {
|
|
@@ -196,6 +205,7 @@ var ErdoClient = class {
|
|
|
196
205
|
}
|
|
197
206
|
this.token = token;
|
|
198
207
|
this.orgId = resolveOrgId(acct, orgOverride);
|
|
208
|
+
this.projectId = process.env.ERDO_PROJECT?.trim() || void 0;
|
|
199
209
|
this.orgPinned = Boolean(orgOverride || process.env.ERDO_ORG);
|
|
200
210
|
this.orgName = acct?.organizationName;
|
|
201
211
|
}
|
|
@@ -217,7 +227,15 @@ var ErdoClient = class {
|
|
|
217
227
|
}
|
|
218
228
|
request(method, path, body) {
|
|
219
229
|
this.announceOrgOnce(method);
|
|
220
|
-
return rawRequest(
|
|
230
|
+
return rawRequest(
|
|
231
|
+
this.baseURL,
|
|
232
|
+
this.token,
|
|
233
|
+
this.orgId,
|
|
234
|
+
this.projectId,
|
|
235
|
+
method,
|
|
236
|
+
path,
|
|
237
|
+
body
|
|
238
|
+
);
|
|
221
239
|
}
|
|
222
240
|
me() {
|
|
223
241
|
return this.request("GET", "/v1/me");
|
|
@@ -694,6 +712,24 @@ var ErdoClient = class {
|
|
|
694
712
|
checkIntegrationConnection(app) {
|
|
695
713
|
return this.request("GET", `/v1/integrations-connect/${encodeURIComponent(app)}`);
|
|
696
714
|
}
|
|
715
|
+
// --- integration connect links ---
|
|
716
|
+
// A connect link is an unauthenticated, shareable URL that lets a third party
|
|
717
|
+
// (e.g. a client's IT admin) complete a native integration's OAuth / API-key
|
|
718
|
+
// setup without an Erdo account. It expires in 14 days and completes once — the
|
|
719
|
+
// returned link_url is a secret.
|
|
720
|
+
createConnectLink(body) {
|
|
721
|
+
return this.request("POST", "/v1/integration-connect-links", body);
|
|
722
|
+
}
|
|
723
|
+
listConnectLinks(app) {
|
|
724
|
+
const qs = app ? `?app=${encodeURIComponent(app)}` : "";
|
|
725
|
+
return this.request("GET", `/v1/integration-connect-links${qs}`);
|
|
726
|
+
}
|
|
727
|
+
revokeConnectLink(id) {
|
|
728
|
+
return this.request(
|
|
729
|
+
"POST",
|
|
730
|
+
`/v1/integration-connect-links/${encodeURIComponent(id)}/revoke`
|
|
731
|
+
);
|
|
732
|
+
}
|
|
697
733
|
// --- dataset filters ---
|
|
698
734
|
listDatasetFilters(datasetSlug) {
|
|
699
735
|
return this.request(
|
|
@@ -1150,10 +1186,12 @@ function summariseResults(results, cases = []) {
|
|
|
1150
1186
|
}
|
|
1151
1187
|
}
|
|
1152
1188
|
var program = new Command();
|
|
1153
|
-
program.name("erdo").description("Erdo CLI").version(pkg.version).option("--org <idOrSlug>", "org to target for this command (overrides the active org)");
|
|
1189
|
+
program.name("erdo").description("Erdo CLI").version(pkg.version).option("--org <idOrSlug>", "org to target for this command (overrides the active org)").option("--project <uuid>", "project context for this command (must belong to the active org)");
|
|
1154
1190
|
program.hook("preAction", (thisCommand) => {
|
|
1155
|
-
const
|
|
1191
|
+
const opts = thisCommand.opts();
|
|
1192
|
+
const org2 = opts.org;
|
|
1156
1193
|
if (org2) process.env.ERDO_ORG = org2;
|
|
1194
|
+
if (opts.project) process.env.ERDO_PROJECT = opts.project;
|
|
1157
1195
|
});
|
|
1158
1196
|
async function doLogin(opts) {
|
|
1159
1197
|
let token;
|
|
@@ -3000,6 +3038,48 @@ List tables with: erdo integrations tables ${app} <schema>`);
|
|
|
3000
3038
|
fail(e);
|
|
3001
3039
|
}
|
|
3002
3040
|
});
|
|
3041
|
+
var connectLinksCmd = integrationsCmd.command("connect-links").description("Generate shareable links so a third party can connect an app for you");
|
|
3042
|
+
connectLinksCmd.command("create <app>").description("Mint a shareable connect link for an app by slug \u2014 native (e.g. github, hubspot) or Pipedream (e.g. slack, notion); link_url is a secret").option("-n, --name <name>", "display name for the connection the recipient creates").option("--integration-id <id>", "re-authorize an existing, non-active native integration instead of creating a new one (native only)").action(async (app, opts) => {
|
|
3043
|
+
try {
|
|
3044
|
+
const res = await new ErdoClient().createConnectLink({
|
|
3045
|
+
app,
|
|
3046
|
+
name: opts.name,
|
|
3047
|
+
integration_id: opts.integrationId
|
|
3048
|
+
});
|
|
3049
|
+
print(res);
|
|
3050
|
+
process.stderr.write(
|
|
3051
|
+
`
|
|
3052
|
+
Share link_url with the person who holds the credentials. It expires ${res.expires_at} and completes once. Treat it as a secret \u2014 anyone with it can finish the connection.
|
|
3053
|
+
`
|
|
3054
|
+
);
|
|
3055
|
+
} catch (e) {
|
|
3056
|
+
fail(e);
|
|
3057
|
+
}
|
|
3058
|
+
});
|
|
3059
|
+
connectLinksCmd.command("list").description("List your connect links (id app status for_reauth expires_at link_url)").option("--app <app>", "filter by app slug \u2014 native (e.g. github) or Pipedream (e.g. slack)").action(async (opts) => {
|
|
3060
|
+
try {
|
|
3061
|
+
const { links } = await new ErdoClient().listConnectLinks(opts.app);
|
|
3062
|
+
if (links.length === 0) {
|
|
3063
|
+
console.log("No connect links. Create one with: erdo integrations connect-links create <app>");
|
|
3064
|
+
return;
|
|
3065
|
+
}
|
|
3066
|
+
for (const l of links) {
|
|
3067
|
+
console.log(
|
|
3068
|
+
`${l.id} ${l.app || "-"} ${l.status} ${l.for_reauth ? "reauth" : "new"} ${l.expires_at} ${l.link_url}`
|
|
3069
|
+
);
|
|
3070
|
+
}
|
|
3071
|
+
} catch (e) {
|
|
3072
|
+
fail(e);
|
|
3073
|
+
}
|
|
3074
|
+
});
|
|
3075
|
+
connectLinksCmd.command("revoke <id>").description("Revoke a pending connect link so its URL stops working").action(async (id) => {
|
|
3076
|
+
try {
|
|
3077
|
+
await new ErdoClient().revokeConnectLink(id);
|
|
3078
|
+
console.log(`revoked: ${id}`);
|
|
3079
|
+
} catch (e) {
|
|
3080
|
+
fail(e);
|
|
3081
|
+
}
|
|
3082
|
+
});
|
|
3003
3083
|
var pipelinesCmd = program.command("event-pipelines").description("Inspect event pipelines (lead-capture / webhook flows)");
|
|
3004
3084
|
pipelinesCmd.command("list").description("List event pipelines in the active org").option("-n, --limit <n>", "max rows", (v) => parseInt(v, 10)).action(async (opts) => {
|
|
3005
3085
|
try {
|