@m8t-stack/cli 0.2.24 → 0.2.26
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/cli.js +57 -18
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -604,6 +604,22 @@ async function authedJsonResult(args) {
|
|
|
604
604
|
async function authedJson(args) {
|
|
605
605
|
return (await authedJsonResult(args)).data;
|
|
606
606
|
}
|
|
607
|
+
async function authedJsonPagedValues(args) {
|
|
608
|
+
const maxPages = args.maxPages ?? 100;
|
|
609
|
+
const items = [];
|
|
610
|
+
let url = args.url;
|
|
611
|
+
for (let page = 0; url && page < maxPages; page++) {
|
|
612
|
+
const body = await authedJson({
|
|
613
|
+
credential: args.credential,
|
|
614
|
+
scope: args.scope,
|
|
615
|
+
method: "GET",
|
|
616
|
+
url
|
|
617
|
+
});
|
|
618
|
+
items.push(...body?.value ?? []);
|
|
619
|
+
url = body?.nextLink;
|
|
620
|
+
}
|
|
621
|
+
return items;
|
|
622
|
+
}
|
|
607
623
|
var init_http = __esm({
|
|
608
624
|
"src/lib/http.ts"() {
|
|
609
625
|
"use strict";
|
|
@@ -1231,7 +1247,7 @@ var init_enable_hosted_brain = __esm({
|
|
|
1231
1247
|
import { Builtins, Cli } from "clipanion";
|
|
1232
1248
|
|
|
1233
1249
|
// src/lib/package-version.ts
|
|
1234
|
-
var CLI_VERSION = "0.2.
|
|
1250
|
+
var CLI_VERSION = "0.2.26";
|
|
1235
1251
|
|
|
1236
1252
|
// src/lib/render-error.ts
|
|
1237
1253
|
init_errors();
|
|
@@ -13663,23 +13679,22 @@ var ACCOUNTS_API = "2024-10-01";
|
|
|
13663
13679
|
var PROJECTS_API = "2025-04-01-preview";
|
|
13664
13680
|
async function listProjectsForAccount(credential2, accountId) {
|
|
13665
13681
|
const url = `${ARM}${accountId}/projects?api-version=${PROJECTS_API}`;
|
|
13666
|
-
return await
|
|
13682
|
+
return await authedJsonPagedValues({ credential: credential2, scope: ARM_SCOPE2, url });
|
|
13667
13683
|
}
|
|
13668
13684
|
function formatProjectCandidate(c) {
|
|
13669
13685
|
return `${c.projectName} (account=${c.accountName}, ${c.region})`;
|
|
13670
13686
|
}
|
|
13671
13687
|
async function resolveFoundryProject(opts) {
|
|
13672
13688
|
const candidates = [];
|
|
13673
|
-
const accounts = await
|
|
13689
|
+
const accounts = await authedJsonPagedValues({
|
|
13674
13690
|
credential: opts.credential,
|
|
13675
13691
|
scope: ARM_SCOPE2,
|
|
13676
|
-
method: "GET",
|
|
13677
13692
|
url: `${ARM}/subscriptions/${opts.subscriptionId}/providers/Microsoft.CognitiveServices/accounts?api-version=${ACCOUNTS_API}`
|
|
13678
|
-
})
|
|
13679
|
-
for (const acc of accounts
|
|
13693
|
+
});
|
|
13694
|
+
for (const acc of accounts) {
|
|
13680
13695
|
if (acc.kind !== "AIServices" || !acc.name || !acc.id) continue;
|
|
13681
13696
|
const projects = await listProjectsForAccount(opts.credential, acc.id);
|
|
13682
|
-
for (const proj of projects
|
|
13697
|
+
for (const proj of projects) {
|
|
13683
13698
|
if (!proj.name) continue;
|
|
13684
13699
|
const projectName = proj.name.includes("/") ? proj.name.slice(proj.name.lastIndexOf("/") + 1) : proj.name;
|
|
13685
13700
|
candidates.push({
|
|
@@ -20645,6 +20660,19 @@ async function ensureAppReg(opts) {
|
|
|
20645
20660
|
await ensureExposeAnApi(created.appId, created.id);
|
|
20646
20661
|
return { tenantId: opts.tenantId, clientId: created.appId, appObjectId: created.id };
|
|
20647
20662
|
}
|
|
20663
|
+
async function ensureGatewayRedirectUri(gatewayClientId, fqdn) {
|
|
20664
|
+
const appObjectId = await azJson(
|
|
20665
|
+
["ad", "app", "show", "--id", gatewayClientId, "--query", "id", "--output", "json"]
|
|
20666
|
+
);
|
|
20667
|
+
if (!appObjectId) {
|
|
20668
|
+
throw new LocalCliError({
|
|
20669
|
+
code: "APP_REG_OBJECT_ID_MISSING",
|
|
20670
|
+
message: `Could not resolve the object ID for app registration ${gatewayClientId}.`,
|
|
20671
|
+
hint: "You need directory read access to the app registration the gateway signs in against."
|
|
20672
|
+
});
|
|
20673
|
+
}
|
|
20674
|
+
await patchRedirectUris(appObjectId, fqdn);
|
|
20675
|
+
}
|
|
20648
20676
|
async function patchRedirectUris(appObjectId, fqdn) {
|
|
20649
20677
|
const targetUri = `https://${fqdn}`;
|
|
20650
20678
|
const existing = await azJson(
|
|
@@ -24418,13 +24446,12 @@ var STORAGE_API2 = "2023-05-01";
|
|
|
24418
24446
|
var LA_API = "2023-09-01";
|
|
24419
24447
|
async function discoverLedgerResources(opts) {
|
|
24420
24448
|
const { credential: credential2, subscriptionId, resourceGroup } = opts;
|
|
24421
|
-
const storage = await
|
|
24449
|
+
const storage = await authedJsonPagedValues({
|
|
24422
24450
|
credential: credential2,
|
|
24423
24451
|
scope: ARM_SCOPE8,
|
|
24424
|
-
method: "GET",
|
|
24425
24452
|
url: `${ARM4}/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}/providers/Microsoft.Storage/storageAccounts?api-version=${STORAGE_API2}`
|
|
24426
|
-
})
|
|
24427
|
-
const accounts =
|
|
24453
|
+
});
|
|
24454
|
+
const accounts = storage.filter((a) => a.properties?.primaryEndpoints?.table);
|
|
24428
24455
|
const ledgerAcct = accounts.find((a) => (a.tags?.["m8t-stack:role"] ?? a.properties?.tags?.["m8t-stack:role"]) === "ledger") ?? (accounts.length === 1 ? accounts[0] : void 0);
|
|
24429
24456
|
const ledgerTableEndpoint = ledgerAcct?.properties?.primaryEndpoints?.table?.replace(/\/$/, "");
|
|
24430
24457
|
if (!ledgerTableEndpoint) {
|
|
@@ -24434,13 +24461,11 @@ async function discoverLedgerResources(opts) {
|
|
|
24434
24461
|
hint: `Found: ${accounts.map((a) => a.name).join(", ") || "(none)"}. Tag the ledger account 'm8t-stack:role=ledger'.`
|
|
24435
24462
|
});
|
|
24436
24463
|
}
|
|
24437
|
-
const
|
|
24464
|
+
const ws = await authedJsonPagedValues({
|
|
24438
24465
|
credential: credential2,
|
|
24439
24466
|
scope: ARM_SCOPE8,
|
|
24440
|
-
method: "GET",
|
|
24441
24467
|
url: `${ARM4}/subscriptions/${subscriptionId}/resourceGroups/${resourceGroup}/providers/Microsoft.OperationalInsights/workspaces?api-version=${LA_API}`
|
|
24442
|
-
})
|
|
24443
|
-
const ws = laList.value ?? [];
|
|
24468
|
+
});
|
|
24444
24469
|
const workspaceId = (ws.length === 1 ? ws[0] : ws.find((w) => w.properties?.customerId))?.properties?.customerId;
|
|
24445
24470
|
if (!workspaceId) {
|
|
24446
24471
|
throw new LocalCliError({
|
|
@@ -25653,7 +25678,7 @@ async function writeBootstrapState(state, home = os13.homedir()) {
|
|
|
25653
25678
|
// src/commands/bootstrap/launch.ts
|
|
25654
25679
|
var DEFAULT_RG = "rg-m8t-stack";
|
|
25655
25680
|
var DEFAULT_INSTALLER = "ghcr.io/m8t-labs/m8t-installer";
|
|
25656
|
-
var DEFAULT_INSTALLER_TAG = "v0.1.
|
|
25681
|
+
var DEFAULT_INSTALLER_TAG = "v0.1.32";
|
|
25657
25682
|
var ACI_NAME = "m8t-installer";
|
|
25658
25683
|
var MI_NAME = "m8t-installer-mi";
|
|
25659
25684
|
var BootstrapLaunchCommand = class extends M8tCommand {
|
|
@@ -25664,8 +25689,8 @@ var BootstrapLaunchCommand = class extends M8tCommand {
|
|
|
25664
25689
|
examples: [
|
|
25665
25690
|
["Launch in eastus2", "$0 bootstrap launch --location eastus2"],
|
|
25666
25691
|
["BYO app registration", "$0 bootstrap launch --location eastus2 --client-id <appId>"],
|
|
25667
|
-
["Pin a specific installer tag", "$0 bootstrap launch --location eastus2 --installer-tag v0.1.
|
|
25668
|
-
["Override the full installer image ref", "$0 bootstrap launch --location eastus2 --installer-image ghcr.io/m8t-labs/m8t-installer:v0.1.
|
|
25692
|
+
["Pin a specific installer tag", "$0 bootstrap launch --location eastus2 --installer-tag v0.1.32"],
|
|
25693
|
+
["Override the full installer image ref", "$0 bootstrap launch --location eastus2 --installer-image ghcr.io/m8t-labs/m8t-installer:v0.1.32"]
|
|
25669
25694
|
]
|
|
25670
25695
|
});
|
|
25671
25696
|
location = Option46.String("--location");
|
|
@@ -26461,6 +26486,20 @@ var BootstrapFinishCommand = class extends M8tCommand {
|
|
|
26461
26486
|
|
|
26462
26487
|
`
|
|
26463
26488
|
);
|
|
26489
|
+
try {
|
|
26490
|
+
await ensureGatewayRedirectUri(d.gatewayClientId, new URL(d.gatewayUrl).host);
|
|
26491
|
+
} catch (e) {
|
|
26492
|
+
const err = e;
|
|
26493
|
+
this.context.stderr.write(
|
|
26494
|
+
` ${colors.error("\u26A0 could not authorize sign-in for your webapp:")} ${err.message}
|
|
26495
|
+
${colors.hint(`Until this is fixed, opening ${d.gatewayUrl} will fail with AADSTS50011 (redirect URI mismatch).`)}
|
|
26496
|
+
${colors.hint("Ask a directory admin to run:")}
|
|
26497
|
+
${colors.hint(` m8t bootstrap finish --repo-root ${repoRoot} # (as an admin), or by hand:`)}
|
|
26498
|
+
${colors.hint(` az ad app update --id ${d.gatewayClientId} --set spa.redirectUris="['${d.gatewayUrl}']" # (merge, do not overwrite)`)}
|
|
26499
|
+
|
|
26500
|
+
`
|
|
26501
|
+
);
|
|
26502
|
+
}
|
|
26464
26503
|
} catch (e) {
|
|
26465
26504
|
const err = e;
|
|
26466
26505
|
this.context.stdout.write(`${colors.success("\u2705 The platform is live.")}
|