@getmagical/cli 0.1.13 → 0.1.16
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/README.md +0 -4
- package/dist/index.js +160 -255
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -69,10 +69,6 @@ Once installed, users can update from the same channel with:
|
|
|
69
69
|
mgcl --update
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
Installed CLIs also check the configured npm dist-tag before running
|
|
73
|
-
subcommands. If the local version is behind, `mgcl` blocks the command and
|
|
74
|
-
asks the user to run `mgcl update` before rerunning it.
|
|
75
|
-
|
|
76
72
|
To remove the managed install:
|
|
77
73
|
|
|
78
74
|
```bash
|
package/dist/index.js
CHANGED
|
@@ -6885,6 +6885,7 @@ function getErrorMessage(error) {
|
|
|
6885
6885
|
}
|
|
6886
6886
|
|
|
6887
6887
|
// src/program.ts
|
|
6888
|
+
import { readFile as readFile4 } from "fs/promises";
|
|
6888
6889
|
import path6 from "path";
|
|
6889
6890
|
|
|
6890
6891
|
// ../common/dist/src/stdlib/json.util.js
|
|
@@ -7693,6 +7694,8 @@ var operationSpecs = [
|
|
|
7693
7694
|
query GetAgents($ids: [ID!]!) {
|
|
7694
7695
|
agents(ids: $ids) {
|
|
7695
7696
|
id
|
|
7697
|
+
agentVersionId
|
|
7698
|
+
automationVersionId
|
|
7696
7699
|
name
|
|
7697
7700
|
description
|
|
7698
7701
|
instructions
|
|
@@ -7714,6 +7717,7 @@ ${agentLimitationsSelection}
|
|
|
7714
7717
|
taskQueue
|
|
7715
7718
|
waitUponQueueing
|
|
7716
7719
|
queueableAgentIds
|
|
7720
|
+
systemPrompt
|
|
7717
7721
|
additionalSystemPrompt
|
|
7718
7722
|
ignoreUnstableSessionState
|
|
7719
7723
|
}
|
|
@@ -7777,6 +7781,7 @@ ${agentLimitationsSelection}
|
|
|
7777
7781
|
taskQueue
|
|
7778
7782
|
waitUponQueueing
|
|
7779
7783
|
queueableAgentIds
|
|
7784
|
+
systemPrompt
|
|
7780
7785
|
additionalSystemPrompt
|
|
7781
7786
|
ignoreUnstableSessionState
|
|
7782
7787
|
}
|
|
@@ -7939,7 +7944,9 @@ query GetAgentRun($id: ID!) {
|
|
|
7939
7944
|
query GetAutomationAgents($ids: [ID!]!) {
|
|
7940
7945
|
automationAgents(ids: $ids) {
|
|
7941
7946
|
automationId
|
|
7947
|
+
automationVersionId
|
|
7942
7948
|
agentId
|
|
7949
|
+
agentVersionId
|
|
7943
7950
|
isTrigger
|
|
7944
7951
|
agent {
|
|
7945
7952
|
id
|
|
@@ -8664,13 +8671,15 @@ mutation StopAutomationRun($automationRunId: ID!) {
|
|
|
8664
8671
|
jsonOption({
|
|
8665
8672
|
inputKey: "input",
|
|
8666
8673
|
flagName: "input-json",
|
|
8667
|
-
description: "UpdateAutomationInput payload.",
|
|
8674
|
+
description: "UpdateAutomationInput payload. Must include baseVersionId from a fresh automations get/list call.",
|
|
8668
8675
|
required: true
|
|
8669
8676
|
})
|
|
8670
8677
|
]
|
|
8671
8678
|
},
|
|
8672
8679
|
mcp: { fileName: "updateAutomation.graphql" },
|
|
8673
8680
|
document: `# Mutation to update an automation
|
|
8681
|
+
# Before calling, fetch the automation and agents again. Pass the fetched draftVersionId as input.baseVersionId.
|
|
8682
|
+
# If this mutation returns a draft-automation-version-conflict, discard the generated update, refetch the automation and agents, inspect what changed, then regenerate the update on top of the latest version.
|
|
8674
8683
|
# Returns only id and lastSavedAt for MCP tool simplicity
|
|
8675
8684
|
mutation UpdateAutomationById($id: ID!, $input: UpdateAutomationInput!) {
|
|
8676
8685
|
updateAutomation(id: $id, input: $input) {
|
|
@@ -8686,6 +8695,8 @@ import { Command as Command2, InvalidArgumentError as InvalidArgumentError2, Opt
|
|
|
8686
8695
|
|
|
8687
8696
|
// src/api.ts
|
|
8688
8697
|
import { z as z3 } from "zod";
|
|
8698
|
+
var OTTO_AUTHORIZATION_HEADER_NAME = "X-Otto-Authorization";
|
|
8699
|
+
var OTTO_AUTHORIZATION_ISSUER = "magical:otto";
|
|
8689
8700
|
var workosOrganizationsResponseSchema = z3.object({
|
|
8690
8701
|
organizations: z3.array(
|
|
8691
8702
|
z3.object({
|
|
@@ -8752,6 +8763,50 @@ function getApiErrorDetail(responseBody) {
|
|
|
8752
8763
|
function trimTrailingSlash(value) {
|
|
8753
8764
|
return value.replace(/\/+$/u, "");
|
|
8754
8765
|
}
|
|
8766
|
+
function isRecord2(value) {
|
|
8767
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8768
|
+
}
|
|
8769
|
+
function decodeJwtPayload(token) {
|
|
8770
|
+
const [, payloadSegment] = token.split(".");
|
|
8771
|
+
if (!payloadSegment) {
|
|
8772
|
+
return null;
|
|
8773
|
+
}
|
|
8774
|
+
const payloadResult = safeJsonParse(
|
|
8775
|
+
Buffer.from(payloadSegment, "base64url").toString("utf8")
|
|
8776
|
+
);
|
|
8777
|
+
if (isErr(payloadResult)) {
|
|
8778
|
+
return null;
|
|
8779
|
+
}
|
|
8780
|
+
return isRecord2(payloadResult.value) ? payloadResult.value : null;
|
|
8781
|
+
}
|
|
8782
|
+
function isOttoAuthorizationToken(token) {
|
|
8783
|
+
return decodeJwtPayload(token)?.["iss"] === OTTO_AUTHORIZATION_ISSUER;
|
|
8784
|
+
}
|
|
8785
|
+
function applyAuthenticationHeaders({
|
|
8786
|
+
accessToken,
|
|
8787
|
+
allowOttoAuthorization,
|
|
8788
|
+
headers,
|
|
8789
|
+
impersonatedOrganizationId,
|
|
8790
|
+
organizationId
|
|
8791
|
+
}) {
|
|
8792
|
+
if (!isOttoAuthorizationToken(accessToken)) {
|
|
8793
|
+
headers.set("authorization", `Bearer ${accessToken}`);
|
|
8794
|
+
if (impersonatedOrganizationId) {
|
|
8795
|
+
headers.set("x-organization-id", impersonatedOrganizationId);
|
|
8796
|
+
}
|
|
8797
|
+
return;
|
|
8798
|
+
}
|
|
8799
|
+
if (!allowOttoAuthorization) {
|
|
8800
|
+
throw new CliError(
|
|
8801
|
+
"Otto authorization is only supported for GraphQL requests."
|
|
8802
|
+
);
|
|
8803
|
+
}
|
|
8804
|
+
if (!organizationId) {
|
|
8805
|
+
throw new CliError("Otto authorization requires an organization ID.");
|
|
8806
|
+
}
|
|
8807
|
+
headers.set(OTTO_AUTHORIZATION_HEADER_NAME, `Bearer ${accessToken}`);
|
|
8808
|
+
headers.set("x-organization-id", organizationId);
|
|
8809
|
+
}
|
|
8755
8810
|
function createMagicalApiClient({
|
|
8756
8811
|
apiBaseUrl,
|
|
8757
8812
|
fetchFn = fetch
|
|
@@ -8759,12 +8814,21 @@ function createMagicalApiClient({
|
|
|
8759
8814
|
const resolveApiBaseUrl = typeof apiBaseUrl === "string" ? () => apiBaseUrl : apiBaseUrl;
|
|
8760
8815
|
async function fetchJson({
|
|
8761
8816
|
accessToken,
|
|
8817
|
+
impersonatedOrganizationId,
|
|
8818
|
+
allowOttoAuthorization,
|
|
8762
8819
|
path: path7,
|
|
8763
|
-
init
|
|
8820
|
+
init,
|
|
8821
|
+
organizationId
|
|
8764
8822
|
}) {
|
|
8765
8823
|
const url = `${trimTrailingSlash(await resolveApiBaseUrl())}${path7}`;
|
|
8766
8824
|
const headers = new Headers(init?.headers);
|
|
8767
|
-
|
|
8825
|
+
applyAuthenticationHeaders({
|
|
8826
|
+
accessToken,
|
|
8827
|
+
...allowOttoAuthorization ? { allowOttoAuthorization } : {},
|
|
8828
|
+
headers,
|
|
8829
|
+
...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
|
|
8830
|
+
...organizationId ? { organizationId } : {}
|
|
8831
|
+
});
|
|
8768
8832
|
const response = await fetchFn(url, {
|
|
8769
8833
|
...init,
|
|
8770
8834
|
headers
|
|
@@ -8801,6 +8865,8 @@ function createMagicalApiClient({
|
|
|
8801
8865
|
return {
|
|
8802
8866
|
async executeGraphQl({
|
|
8803
8867
|
accessToken,
|
|
8868
|
+
impersonatedOrganizationId,
|
|
8869
|
+
organizationId,
|
|
8804
8870
|
query,
|
|
8805
8871
|
resultKey,
|
|
8806
8872
|
variables
|
|
@@ -8810,6 +8876,9 @@ function createMagicalApiClient({
|
|
|
8810
8876
|
const parsedResponse = graphQlResponseSchema.safeParse(
|
|
8811
8877
|
await fetchJson({
|
|
8812
8878
|
accessToken,
|
|
8879
|
+
...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
|
|
8880
|
+
allowOttoAuthorization: true,
|
|
8881
|
+
...organizationId ? { organizationId } : {},
|
|
8813
8882
|
path: "/graphql",
|
|
8814
8883
|
init: {
|
|
8815
8884
|
method: "POST",
|
|
@@ -8849,11 +8918,13 @@ function createMagicalApiClient({
|
|
|
8849
8918
|
},
|
|
8850
8919
|
async fetchUser({
|
|
8851
8920
|
accessToken,
|
|
8921
|
+
organizationId,
|
|
8852
8922
|
userId
|
|
8853
8923
|
}) {
|
|
8854
8924
|
const parsedResponse = workosUserSchema.safeParse(
|
|
8855
8925
|
await fetchJson({
|
|
8856
8926
|
accessToken,
|
|
8927
|
+
...organizationId ? { organizationId } : {},
|
|
8857
8928
|
path: `/workos/user/${userId}`
|
|
8858
8929
|
})
|
|
8859
8930
|
);
|
|
@@ -8863,11 +8934,15 @@ function createMagicalApiClient({
|
|
|
8863
8934
|
return parsedResponse.data;
|
|
8864
8935
|
},
|
|
8865
8936
|
async listNangoIntegrations({
|
|
8866
|
-
accessToken
|
|
8937
|
+
accessToken,
|
|
8938
|
+
impersonatedOrganizationId,
|
|
8939
|
+
organizationId
|
|
8867
8940
|
}) {
|
|
8868
8941
|
const parsedResponse = nangoIntegrationsResponseSchema.safeParse(
|
|
8869
8942
|
await fetchJson({
|
|
8870
8943
|
accessToken,
|
|
8944
|
+
...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
|
|
8945
|
+
...organizationId ? { organizationId } : {},
|
|
8871
8946
|
path: "/nango/integrations"
|
|
8872
8947
|
})
|
|
8873
8948
|
);
|
|
@@ -8877,11 +8952,15 @@ function createMagicalApiClient({
|
|
|
8877
8952
|
return parsedResponse.data;
|
|
8878
8953
|
},
|
|
8879
8954
|
async listNangoAuthentications({
|
|
8880
|
-
accessToken
|
|
8955
|
+
accessToken,
|
|
8956
|
+
impersonatedOrganizationId,
|
|
8957
|
+
organizationId
|
|
8881
8958
|
}) {
|
|
8882
8959
|
const parsedResponse = organizationAuthenticationsResponseSchema.safeParse(
|
|
8883
8960
|
await fetchJson({
|
|
8884
8961
|
accessToken,
|
|
8962
|
+
...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
|
|
8963
|
+
...organizationId ? { organizationId } : {},
|
|
8885
8964
|
path: "/authentications/organization?type=nangoConnection"
|
|
8886
8965
|
})
|
|
8887
8966
|
);
|
|
@@ -9199,6 +9278,22 @@ function resolveOpenCommand(url) {
|
|
|
9199
9278
|
|
|
9200
9279
|
// src/program-session.ts
|
|
9201
9280
|
import { readFile as readFile2, rm as rm2 } from "fs/promises";
|
|
9281
|
+
|
|
9282
|
+
// ../common/dist/src/stdlib/url.utils.js
|
|
9283
|
+
var import_handlebars = __toESM(require_lib(), 1);
|
|
9284
|
+
function safeUrlConstructor(url, baseUrl) {
|
|
9285
|
+
try {
|
|
9286
|
+
return Ok(baseUrl ? new URL(url, baseUrl) : new URL(url));
|
|
9287
|
+
} catch {
|
|
9288
|
+
return Err({
|
|
9289
|
+
type: "invalid-url",
|
|
9290
|
+
message: `Invalid URL`,
|
|
9291
|
+
url
|
|
9292
|
+
});
|
|
9293
|
+
}
|
|
9294
|
+
}
|
|
9295
|
+
|
|
9296
|
+
// src/program-session.ts
|
|
9202
9297
|
async function withOrgScopedAccessToken({
|
|
9203
9298
|
dependencies,
|
|
9204
9299
|
organizationId,
|
|
@@ -9263,10 +9358,20 @@ async function loadDirectAccessToken({
|
|
|
9263
9358
|
if (!accessTokenFileContents) {
|
|
9264
9359
|
return null;
|
|
9265
9360
|
}
|
|
9266
|
-
const
|
|
9267
|
-
accessTokenFileContents
|
|
9361
|
+
const claimsResult = fromThrowable(
|
|
9362
|
+
() => dependencies.authClient.decodeAccessTokenClaims(accessTokenFileContents),
|
|
9363
|
+
"decode-otto-session-access-token-failed"
|
|
9268
9364
|
);
|
|
9365
|
+
if (isErr(claimsResult)) {
|
|
9366
|
+
return null;
|
|
9367
|
+
}
|
|
9368
|
+
const claims = claimsResult.value;
|
|
9269
9369
|
if (isExpiredAccessTokenClaims(claims)) {
|
|
9370
|
+
if (claims.iss === "magical:otto") {
|
|
9371
|
+
throw new CliError(
|
|
9372
|
+
"The Otto session authorization token expired. Start a new Otto session from Magical."
|
|
9373
|
+
);
|
|
9374
|
+
}
|
|
9270
9375
|
return null;
|
|
9271
9376
|
}
|
|
9272
9377
|
if (claims.org_id && claims.org_id !== organizationId) {
|
|
@@ -9288,29 +9393,10 @@ import { spawn as spawn2 } from "child_process";
|
|
|
9288
9393
|
import fs from "fs";
|
|
9289
9394
|
import path3 from "path";
|
|
9290
9395
|
import { fileURLToPath } from "url";
|
|
9291
|
-
|
|
9292
|
-
// ../common/dist/src/stdlib/url.utils.js
|
|
9293
|
-
var import_handlebars = __toESM(require_lib(), 1);
|
|
9294
|
-
function safeUrlConstructor(url, baseUrl) {
|
|
9295
|
-
try {
|
|
9296
|
-
return Ok(baseUrl ? new URL(url, baseUrl) : new URL(url));
|
|
9297
|
-
} catch {
|
|
9298
|
-
return Err({
|
|
9299
|
-
type: "invalid-url",
|
|
9300
|
-
message: `Invalid URL`,
|
|
9301
|
-
url
|
|
9302
|
-
});
|
|
9303
|
-
}
|
|
9304
|
-
}
|
|
9305
|
-
|
|
9306
|
-
// src/self-update.ts
|
|
9307
9396
|
var CLI_PACKAGE_NAME = "@getmagical/cli";
|
|
9308
9397
|
var DEFAULT_CLI_DIST_TAG2 = "latest";
|
|
9309
9398
|
var DEFAULT_NPM_REGISTRY_URL = "https://registry.npmjs.org/";
|
|
9310
9399
|
var MANAGED_NODE_SUBPATH = "runtime/node";
|
|
9311
|
-
function isRecord2(value) {
|
|
9312
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9313
|
-
}
|
|
9314
9400
|
function resolveInstalledPackageRoot({
|
|
9315
9401
|
entryFilePath,
|
|
9316
9402
|
packageName
|
|
@@ -9351,154 +9437,6 @@ function resolveInstallPrefixFromPackageRoot(packageRootPath) {
|
|
|
9351
9437
|
currentPath = parentPath;
|
|
9352
9438
|
}
|
|
9353
9439
|
}
|
|
9354
|
-
function readInstalledPackageVersion({
|
|
9355
|
-
packageName,
|
|
9356
|
-
packageRootPath
|
|
9357
|
-
}) {
|
|
9358
|
-
const packageManifestPath2 = path3.join(packageRootPath, "package.json");
|
|
9359
|
-
if (!fs.existsSync(packageManifestPath2)) {
|
|
9360
|
-
throw new CliError(
|
|
9361
|
-
`Installed package metadata was not found at ${packageManifestPath2}. Reinstall mgcl and try again.`
|
|
9362
|
-
);
|
|
9363
|
-
}
|
|
9364
|
-
const packageManifestResult2 = safeJsonParse(
|
|
9365
|
-
fs.readFileSync(packageManifestPath2, "utf8")
|
|
9366
|
-
);
|
|
9367
|
-
if (isErr(packageManifestResult2)) {
|
|
9368
|
-
throw new CliError(`Failed to parse ${packageManifestPath2}.`, {
|
|
9369
|
-
cause: packageManifestResult2.error.cause
|
|
9370
|
-
});
|
|
9371
|
-
}
|
|
9372
|
-
const packageManifest = packageManifestResult2.value;
|
|
9373
|
-
if (packageManifest.name !== packageName) {
|
|
9374
|
-
throw new CliError(
|
|
9375
|
-
`Expected installed package ${packageName} at ${packageManifestPath2}. Reinstall mgcl and try again.`
|
|
9376
|
-
);
|
|
9377
|
-
}
|
|
9378
|
-
if (typeof packageManifest.version !== "string" || !packageManifest.version) {
|
|
9379
|
-
throw new CliError(
|
|
9380
|
-
`Installed package version is missing from ${packageManifestPath2}. Reinstall mgcl and try again.`
|
|
9381
|
-
);
|
|
9382
|
-
}
|
|
9383
|
-
return packageManifest.version;
|
|
9384
|
-
}
|
|
9385
|
-
function parseVersionSegment(segment, version) {
|
|
9386
|
-
if (!/^\d+$/u.test(segment)) {
|
|
9387
|
-
throw new CliError(`Invalid CLI version "${version}".`);
|
|
9388
|
-
}
|
|
9389
|
-
return Number(segment);
|
|
9390
|
-
}
|
|
9391
|
-
function parseSemanticVersion(version) {
|
|
9392
|
-
const normalizedVersion = version.trim().replace(/^v/u, "");
|
|
9393
|
-
const [versionWithoutBuildMetadata = ""] = normalizedVersion.split("+");
|
|
9394
|
-
if (!versionWithoutBuildMetadata) {
|
|
9395
|
-
throw new CliError(`Invalid CLI version "${version}".`);
|
|
9396
|
-
}
|
|
9397
|
-
const [releasePart, prereleasePart] = versionWithoutBuildMetadata.split("-");
|
|
9398
|
-
if (!releasePart) {
|
|
9399
|
-
throw new CliError(`Invalid CLI version "${version}".`);
|
|
9400
|
-
}
|
|
9401
|
-
return {
|
|
9402
|
-
prerelease: prereleasePart ? prereleasePart.split(".") : null,
|
|
9403
|
-
release: releasePart.split(".").map((segment) => parseVersionSegment(segment, version))
|
|
9404
|
-
};
|
|
9405
|
-
}
|
|
9406
|
-
function comparePrereleaseIdentifiers(left, right) {
|
|
9407
|
-
const leftIsNumeric = /^\d+$/u.test(left);
|
|
9408
|
-
const rightIsNumeric = /^\d+$/u.test(right);
|
|
9409
|
-
if (leftIsNumeric && rightIsNumeric) {
|
|
9410
|
-
return Number(left) - Number(right);
|
|
9411
|
-
}
|
|
9412
|
-
if (leftIsNumeric) {
|
|
9413
|
-
return -1;
|
|
9414
|
-
}
|
|
9415
|
-
if (rightIsNumeric) {
|
|
9416
|
-
return 1;
|
|
9417
|
-
}
|
|
9418
|
-
return left.localeCompare(right);
|
|
9419
|
-
}
|
|
9420
|
-
function compareSemanticVersions(leftVersion, rightVersion) {
|
|
9421
|
-
const left = parseSemanticVersion(leftVersion);
|
|
9422
|
-
const right = parseSemanticVersion(rightVersion);
|
|
9423
|
-
const releaseLength = Math.max(left.release.length, right.release.length);
|
|
9424
|
-
for (let index = 0; index < releaseLength; index += 1) {
|
|
9425
|
-
const difference = (left.release[index] ?? 0) - (right.release[index] ?? 0);
|
|
9426
|
-
if (difference !== 0) {
|
|
9427
|
-
return difference;
|
|
9428
|
-
}
|
|
9429
|
-
}
|
|
9430
|
-
if (!left.prerelease && !right.prerelease) {
|
|
9431
|
-
return 0;
|
|
9432
|
-
}
|
|
9433
|
-
if (!left.prerelease) {
|
|
9434
|
-
return 1;
|
|
9435
|
-
}
|
|
9436
|
-
if (!right.prerelease) {
|
|
9437
|
-
return -1;
|
|
9438
|
-
}
|
|
9439
|
-
const prereleaseLength = Math.max(
|
|
9440
|
-
left.prerelease.length,
|
|
9441
|
-
right.prerelease.length
|
|
9442
|
-
);
|
|
9443
|
-
for (let index = 0; index < prereleaseLength; index += 1) {
|
|
9444
|
-
const leftIdentifier = left.prerelease[index];
|
|
9445
|
-
const rightIdentifier = right.prerelease[index];
|
|
9446
|
-
if (leftIdentifier === void 0) {
|
|
9447
|
-
return -1;
|
|
9448
|
-
}
|
|
9449
|
-
if (rightIdentifier === void 0) {
|
|
9450
|
-
return 1;
|
|
9451
|
-
}
|
|
9452
|
-
const difference = comparePrereleaseIdentifiers(
|
|
9453
|
-
leftIdentifier,
|
|
9454
|
-
rightIdentifier
|
|
9455
|
-
);
|
|
9456
|
-
if (difference !== 0) {
|
|
9457
|
-
return difference;
|
|
9458
|
-
}
|
|
9459
|
-
}
|
|
9460
|
-
return 0;
|
|
9461
|
-
}
|
|
9462
|
-
async function fetchPublishedPackageVersion({
|
|
9463
|
-
distTag,
|
|
9464
|
-
fetchFn = fetch,
|
|
9465
|
-
packageName,
|
|
9466
|
-
registryUrl
|
|
9467
|
-
}) {
|
|
9468
|
-
const distTagUrlResult = safeUrlConstructor(
|
|
9469
|
-
`${registryUrl.replace(/\/?$/u, "/")}-/package/${encodeURIComponent(packageName)}/dist-tags`
|
|
9470
|
-
);
|
|
9471
|
-
if (isErr(distTagUrlResult)) {
|
|
9472
|
-
throw new CliError(`Invalid npm registry URL "${registryUrl}".`);
|
|
9473
|
-
}
|
|
9474
|
-
const response = await fetchFn(distTagUrlResult.value, {
|
|
9475
|
-
headers: {
|
|
9476
|
-
accept: "application/json"
|
|
9477
|
-
}
|
|
9478
|
-
});
|
|
9479
|
-
if (!response.ok) {
|
|
9480
|
-
throw new CliError(
|
|
9481
|
-
`Could not check the latest published mgcl version (status ${response.status}).`
|
|
9482
|
-
);
|
|
9483
|
-
}
|
|
9484
|
-
const distTagsResult = safeJsonParse(await response.text());
|
|
9485
|
-
if (isErr(distTagsResult)) {
|
|
9486
|
-
throw new CliError("Could not parse the npm dist-tags response for mgcl.", {
|
|
9487
|
-
cause: distTagsResult.error.cause
|
|
9488
|
-
});
|
|
9489
|
-
}
|
|
9490
|
-
if (!isRecord2(distTagsResult.value)) {
|
|
9491
|
-
throw new CliError("Could not parse the npm dist-tags response for mgcl.");
|
|
9492
|
-
}
|
|
9493
|
-
const distTags = distTagsResult.value;
|
|
9494
|
-
const publishedVersion = distTags[distTag];
|
|
9495
|
-
if (typeof publishedVersion !== "string" || publishedVersion.length === 0) {
|
|
9496
|
-
throw new CliError(
|
|
9497
|
-
`Could not find npm dist-tag "${distTag}" for ${packageName}.`
|
|
9498
|
-
);
|
|
9499
|
-
}
|
|
9500
|
-
return publishedVersion;
|
|
9501
|
-
}
|
|
9502
9440
|
function resolveNpmCommandFromPath() {
|
|
9503
9441
|
return {
|
|
9504
9442
|
argsPrefix: [],
|
|
@@ -9612,45 +9550,6 @@ async function selfUpdateInstalledCli({
|
|
|
9612
9550
|
registryUrl
|
|
9613
9551
|
});
|
|
9614
9552
|
}
|
|
9615
|
-
async function getInstalledCliUpdateRequirement({
|
|
9616
|
-
distTag = DEFAULT_CLI_DIST_TAG2,
|
|
9617
|
-
entryFilePath = fileURLToPath(import.meta.url),
|
|
9618
|
-
fetchFn = fetch,
|
|
9619
|
-
packageName = CLI_PACKAGE_NAME,
|
|
9620
|
-
registryUrl = DEFAULT_NPM_REGISTRY_URL
|
|
9621
|
-
} = {}) {
|
|
9622
|
-
const packageRootPath = resolveInstalledPackageRoot({
|
|
9623
|
-
entryFilePath,
|
|
9624
|
-
packageName
|
|
9625
|
-
});
|
|
9626
|
-
if (!packageRootPath) {
|
|
9627
|
-
return null;
|
|
9628
|
-
}
|
|
9629
|
-
const installedVersion = readInstalledPackageVersion({
|
|
9630
|
-
packageName,
|
|
9631
|
-
packageRootPath
|
|
9632
|
-
});
|
|
9633
|
-
const publishedVersionResult = await fromThrowable(
|
|
9634
|
-
async () => fetchPublishedPackageVersion({
|
|
9635
|
-
distTag,
|
|
9636
|
-
fetchFn,
|
|
9637
|
-
packageName,
|
|
9638
|
-
registryUrl
|
|
9639
|
-
}),
|
|
9640
|
-
"cli-update-check-failed"
|
|
9641
|
-
);
|
|
9642
|
-
if (isErr(publishedVersionResult)) {
|
|
9643
|
-
return null;
|
|
9644
|
-
}
|
|
9645
|
-
const publishedVersion = publishedVersionResult.value;
|
|
9646
|
-
if (compareSemanticVersions(installedVersion, publishedVersion) >= 0) {
|
|
9647
|
-
return null;
|
|
9648
|
-
}
|
|
9649
|
-
return {
|
|
9650
|
-
installedVersion,
|
|
9651
|
-
latestVersion: publishedVersion
|
|
9652
|
-
};
|
|
9653
|
-
}
|
|
9654
9553
|
|
|
9655
9554
|
// src/settings-command.ts
|
|
9656
9555
|
import { Command, InvalidArgumentError, Option } from "commander";
|
|
@@ -9911,6 +9810,7 @@ var tokenErrorSchema = z6.object({
|
|
|
9911
9810
|
});
|
|
9912
9811
|
var accessTokenClaimsSchema = z6.object({
|
|
9913
9812
|
exp: z6.number().int().positive().optional(),
|
|
9813
|
+
iss: z6.string().min(1).optional(),
|
|
9914
9814
|
org_id: z6.string().min(1).optional(),
|
|
9915
9815
|
sid: z6.string().min(1).optional(),
|
|
9916
9816
|
sub: z6.string().min(1)
|
|
@@ -10251,39 +10151,16 @@ async function handleSelfUpdate(dependencies, options) {
|
|
|
10251
10151
|
`Updated mgcl via npm (${updateResult.packageSpecifier}) in ${updateResult.installPrefix}.`
|
|
10252
10152
|
);
|
|
10253
10153
|
}
|
|
10254
|
-
function isRootUpdateCommand(program2, actionCommand) {
|
|
10255
|
-
return actionCommand.parent === program2 && actionCommand.name() === "update";
|
|
10256
|
-
}
|
|
10257
|
-
async function enforceLatestCliVersionIfNeeded({
|
|
10258
|
-
dependencies,
|
|
10259
|
-
program: program2,
|
|
10260
|
-
actionCommand
|
|
10261
|
-
}) {
|
|
10262
|
-
if (actionCommand === program2 || isRootUpdateCommand(program2, actionCommand)) {
|
|
10263
|
-
return;
|
|
10264
|
-
}
|
|
10265
|
-
const updateRequirement = await dependencies.ensureLatestCliVersion?.();
|
|
10266
|
-
if (!updateRequirement) {
|
|
10267
|
-
return;
|
|
10268
|
-
}
|
|
10269
|
-
throw new CliError(
|
|
10270
|
-
`mgcl ${updateRequirement.installedVersion} is outdated. Upgrade to ${updateRequirement.latestVersion} with "mgcl update", then rerun your command.`
|
|
10271
|
-
);
|
|
10272
|
-
}
|
|
10273
10154
|
async function handleOperationCommand(dependencies, operationSpec, commandOptions) {
|
|
10274
|
-
const state =
|
|
10275
|
-
const organization = resolveSelectedOrganization({
|
|
10276
|
-
state,
|
|
10277
|
-
...commandOptions.org ? { organizationSelector: commandOptions.org } : {}
|
|
10278
|
-
});
|
|
10279
|
-
const variables = collectOperationVariables(operationSpec, commandOptions);
|
|
10280
|
-
const { accessToken } = await withOrgScopedAccessToken({
|
|
10155
|
+
const { accessToken, impersonatedOrganizationId, organization, state } = await withSelectedOrganizationAndAccessToken({
|
|
10281
10156
|
dependencies,
|
|
10282
|
-
|
|
10283
|
-
state
|
|
10157
|
+
options: commandOptions
|
|
10284
10158
|
});
|
|
10159
|
+
const variables = collectOperationVariables(operationSpec, commandOptions);
|
|
10285
10160
|
const result = await dependencies.apiClient.executeGraphQl({
|
|
10286
10161
|
accessToken,
|
|
10162
|
+
...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
|
|
10163
|
+
organizationId: organization.id,
|
|
10287
10164
|
query: operationSpec.document,
|
|
10288
10165
|
resultKey: operationSpec.cli.resultKey,
|
|
10289
10166
|
variables
|
|
@@ -10307,12 +10184,19 @@ async function withSelectedOrganizationAndAccessToken({
|
|
|
10307
10184
|
state,
|
|
10308
10185
|
...options.org ? { organizationSelector: options.org } : {}
|
|
10309
10186
|
});
|
|
10187
|
+
const authenticatedOrganizationId = await resolveDirectAccessTokenOrganizationId({ dependencies });
|
|
10188
|
+
const shouldImpersonateOrganization = authenticatedOrganizationId !== null && organization.id !== authenticatedOrganizationId;
|
|
10310
10189
|
const { accessToken } = await withOrgScopedAccessToken({
|
|
10311
10190
|
dependencies,
|
|
10312
|
-
organizationId: organization.id,
|
|
10191
|
+
organizationId: shouldImpersonateOrganization && authenticatedOrganizationId ? authenticatedOrganizationId : organization.id,
|
|
10313
10192
|
state
|
|
10314
10193
|
});
|
|
10315
|
-
return {
|
|
10194
|
+
return {
|
|
10195
|
+
accessToken,
|
|
10196
|
+
...shouldImpersonateOrganization ? { impersonatedOrganizationId: organization.id } : {},
|
|
10197
|
+
organization,
|
|
10198
|
+
state
|
|
10199
|
+
};
|
|
10316
10200
|
}
|
|
10317
10201
|
function writeCommandOutput({
|
|
10318
10202
|
dependencies,
|
|
@@ -10326,12 +10210,16 @@ function writeCommandOutput({
|
|
|
10326
10210
|
dependencies.io.info(formatHumanReadableOutput(result));
|
|
10327
10211
|
}
|
|
10328
10212
|
async function handleNangoIntegrationsListCommand(dependencies, options) {
|
|
10329
|
-
const { accessToken, organization, state } = await withSelectedOrganizationAndAccessToken({ dependencies, options });
|
|
10213
|
+
const { accessToken, impersonatedOrganizationId, organization, state } = await withSelectedOrganizationAndAccessToken({ dependencies, options });
|
|
10330
10214
|
const listNangoIntegrations = requireApiClientMethod(
|
|
10331
10215
|
dependencies.apiClient,
|
|
10332
10216
|
"listNangoIntegrations"
|
|
10333
10217
|
);
|
|
10334
|
-
const integrations = await listNangoIntegrations({
|
|
10218
|
+
const integrations = await listNangoIntegrations({
|
|
10219
|
+
accessToken,
|
|
10220
|
+
...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
|
|
10221
|
+
organizationId: organization.id
|
|
10222
|
+
});
|
|
10335
10223
|
await saveLastUsedOrganization({
|
|
10336
10224
|
dependencies,
|
|
10337
10225
|
organizationId: organization.id,
|
|
@@ -10354,13 +10242,15 @@ function normalizeListedNangoAuthentication(authentication) {
|
|
|
10354
10242
|
};
|
|
10355
10243
|
}
|
|
10356
10244
|
async function handleNangoAuthsListCommand(dependencies, options) {
|
|
10357
|
-
const { accessToken, organization, state } = await withSelectedOrganizationAndAccessToken({ dependencies, options });
|
|
10245
|
+
const { accessToken, impersonatedOrganizationId, organization, state } = await withSelectedOrganizationAndAccessToken({ dependencies, options });
|
|
10358
10246
|
const listNangoAuthentications = requireApiClientMethod(
|
|
10359
10247
|
dependencies.apiClient,
|
|
10360
10248
|
"listNangoAuthentications"
|
|
10361
10249
|
);
|
|
10362
10250
|
const organizationAuthentications = await listNangoAuthentications({
|
|
10363
|
-
accessToken
|
|
10251
|
+
accessToken,
|
|
10252
|
+
...impersonatedOrganizationId ? { impersonatedOrganizationId } : {},
|
|
10253
|
+
organizationId: organization.id
|
|
10364
10254
|
});
|
|
10365
10255
|
const authentications = organizationAuthentications.filter((authentication) => {
|
|
10366
10256
|
if (options.integration && authentication.providerConfigKey !== options.integration) {
|
|
@@ -10382,6 +10272,29 @@ async function handleNangoAuthsListCommand(dependencies, options) {
|
|
|
10382
10272
|
result: authentications
|
|
10383
10273
|
});
|
|
10384
10274
|
}
|
|
10275
|
+
async function resolveDirectAccessTokenOrganizationId({
|
|
10276
|
+
dependencies
|
|
10277
|
+
}) {
|
|
10278
|
+
const { accessTokenFilePath } = dependencies.runtimeConfig;
|
|
10279
|
+
if (!accessTokenFilePath) {
|
|
10280
|
+
return null;
|
|
10281
|
+
}
|
|
10282
|
+
const accessToken = await readFile4(accessTokenFilePath, "utf8").then((value) => value.trim()).catch((error) => {
|
|
10283
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
10284
|
+
return null;
|
|
10285
|
+
}
|
|
10286
|
+
throw error;
|
|
10287
|
+
});
|
|
10288
|
+
if (!accessToken) {
|
|
10289
|
+
return null;
|
|
10290
|
+
}
|
|
10291
|
+
try {
|
|
10292
|
+
const claims = dependencies.authClient.decodeAccessTokenClaims(accessToken);
|
|
10293
|
+
return claims.org_id ?? null;
|
|
10294
|
+
} catch {
|
|
10295
|
+
return null;
|
|
10296
|
+
}
|
|
10297
|
+
}
|
|
10385
10298
|
async function saveLastUsedOrganization({
|
|
10386
10299
|
dependencies,
|
|
10387
10300
|
organizationId,
|
|
@@ -10507,7 +10420,6 @@ function createDefaultDependencies() {
|
|
|
10507
10420
|
accessTokenFilePath
|
|
10508
10421
|
},
|
|
10509
10422
|
refreshTokenStore: runtimeConfig.refreshTokenStoreKind === "file" ? createFileRefreshTokenStore(refreshTokenFilePath) : createKeytarRefreshTokenStore(runtimeConfig.keychainServiceName),
|
|
10510
|
-
ensureLatestCliVersion: async () => getInstalledCliUpdateRequirement(selfUpdateOptions),
|
|
10511
10423
|
settingsStore,
|
|
10512
10424
|
selfUpdateCli: async () => selfUpdateInstalledCli(selfUpdateOptions),
|
|
10513
10425
|
stateStore: createFileStateStore(runtimeConfig.stateFilePath)
|
|
@@ -10542,13 +10454,6 @@ ${formatOutputModesNote()}`
|
|
|
10542
10454
|
}
|
|
10543
10455
|
this.outputHelp();
|
|
10544
10456
|
});
|
|
10545
|
-
program2.hook("preAction", async (_command, actionCommand) => {
|
|
10546
|
-
await enforceLatestCliVersionIfNeeded({
|
|
10547
|
-
actionCommand,
|
|
10548
|
-
dependencies,
|
|
10549
|
-
program: program2
|
|
10550
|
-
});
|
|
10551
|
-
});
|
|
10552
10457
|
const authCommand = configureCommandPresentation(
|
|
10553
10458
|
new Command2("auth").description("Manage CLI authentication.")
|
|
10554
10459
|
).helpGroup("Workspace:").addHelpText(
|