@dashai/cli 0.11.0 → 0.12.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/bin.js +124 -14
- package/dist/bin.js.map +1 -1
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -1382,8 +1382,13 @@ import { NextResponse } from 'next/server';
|
|
|
1382
1382
|
import { db } from '@dashai/generated';
|
|
1383
1383
|
|
|
1384
1384
|
export async function GET() {
|
|
1385
|
-
|
|
1386
|
-
|
|
1385
|
+
// \`db.<table>.list()\` resolves to the rows array itself \u2014 the typed
|
|
1386
|
+
// client unwraps the \`{ rows, total, ... }\` page envelope (see the
|
|
1387
|
+
// generated \`client/tables.d.ts\`: \`list(): Promise<ItemsRow[]>\`).
|
|
1388
|
+
// Don't reach for \`.rows\` here: it's \`undefined\` on an array, and
|
|
1389
|
+
// \`NextResponse.json(undefined)\` throws "Value is not JSON serializable".
|
|
1390
|
+
const rows = await db.items.list({ limit: 50 });
|
|
1391
|
+
return NextResponse.json(rows);
|
|
1387
1392
|
}
|
|
1388
1393
|
|
|
1389
1394
|
export async function POST(request: Request) {
|
|
@@ -2504,6 +2509,9 @@ async function tryProvisionDevInstall(args) {
|
|
|
2504
2509
|
apiKey: response.api_key,
|
|
2505
2510
|
apiKeyId: response.api_key_id,
|
|
2506
2511
|
installationId: response.installation.id,
|
|
2512
|
+
// Cache the workspace so `dashwise dev` can default its dev-SSO-session
|
|
2513
|
+
// workspace to it — no re-passing `--workspace` for multi-workspace users.
|
|
2514
|
+
workspaceId: workspace2.id,
|
|
2507
2515
|
expiresAt: response.api_key_expires_at
|
|
2508
2516
|
});
|
|
2509
2517
|
} catch (err) {
|
|
@@ -3427,9 +3435,14 @@ async function devCommand(options) {
|
|
|
3427
3435
|
if (explicitInstallationId && explicitInstallationId !== "local") {
|
|
3428
3436
|
installationIdEnv = explicitInstallationId;
|
|
3429
3437
|
} else if (reuseDevSessionId) ; else {
|
|
3438
|
+
const effectiveWorkspace = options.workspace ?? moduleEntry?.workspaceId?.toString();
|
|
3430
3439
|
let workspaceContext;
|
|
3431
3440
|
try {
|
|
3432
|
-
workspaceContext = await resolveTargetWorkspace(
|
|
3441
|
+
workspaceContext = await resolveTargetWorkspace(
|
|
3442
|
+
apiUrl,
|
|
3443
|
+
apiToken,
|
|
3444
|
+
effectiveWorkspace
|
|
3445
|
+
);
|
|
3433
3446
|
} catch (err) {
|
|
3434
3447
|
fail(err.message);
|
|
3435
3448
|
return 1;
|
|
@@ -5522,7 +5535,11 @@ async function modulePublishCommand(options) {
|
|
|
5522
5535
|
method: "POST",
|
|
5523
5536
|
headers: {
|
|
5524
5537
|
Accept: "application/json",
|
|
5525
|
-
Authorization: `Bearer ${cfg.token}
|
|
5538
|
+
Authorization: `Bearer ${cfg.token}`,
|
|
5539
|
+
// Opt into the async (202 + poll) contract. On the CodeBuild backend a
|
|
5540
|
+
// markerless client is rejected with 426; the E2B backend ignores it
|
|
5541
|
+
// and still responds synchronously (201).
|
|
5542
|
+
"X-Dashwise-CLI-Async": "1"
|
|
5526
5543
|
},
|
|
5527
5544
|
body: form
|
|
5528
5545
|
});
|
|
@@ -5533,6 +5550,12 @@ async function modulePublishCommand(options) {
|
|
|
5533
5550
|
const body = await res.json().catch(() => null);
|
|
5534
5551
|
if (!res.ok) {
|
|
5535
5552
|
const env = body && typeof body === "object" ? body : null;
|
|
5553
|
+
if (res.status === 426) {
|
|
5554
|
+
fail(
|
|
5555
|
+
`Your @dashai/cli is out of date for this backend. Upgrade with ${code("npm i -g @dashai/cli@latest")}, then re-run ${code("dashwise module publish")}.`
|
|
5556
|
+
);
|
|
5557
|
+
return 1;
|
|
5558
|
+
}
|
|
5536
5559
|
fail(
|
|
5537
5560
|
`Publish failed (${res.status}${env?.code ? ` ${env.code}` : ""}): ${env?.message ?? "(no message)"}`
|
|
5538
5561
|
);
|
|
@@ -5541,16 +5564,40 @@ async function modulePublishCommand(options) {
|
|
|
5541
5564
|
}
|
|
5542
5565
|
return 1;
|
|
5543
5566
|
}
|
|
5567
|
+
if (options.dryRun) {
|
|
5568
|
+
const dr = body;
|
|
5569
|
+
const target = dr.target_version ?? dr.version;
|
|
5570
|
+
if (options.json) out(JSON.stringify(body));
|
|
5571
|
+
else success(`Dry run OK \u2014 would publish ${code(`v${target ?? "?"}`)}`);
|
|
5572
|
+
return 0;
|
|
5573
|
+
}
|
|
5574
|
+
if (res.status === 202) {
|
|
5575
|
+
const enq = body;
|
|
5576
|
+
if (!enq?.build_id) {
|
|
5577
|
+
fail("Publish enqueued but the response was missing a build id.");
|
|
5578
|
+
return 1;
|
|
5579
|
+
}
|
|
5580
|
+
if (options.noWait) {
|
|
5581
|
+
success(`Build ${code(`#${enq.build_id}`)} queued for ${code(mod.slug)}.`);
|
|
5582
|
+
info(`Not waiting (${code("--no-wait")}). Re-run publish or poll the build to check.`);
|
|
5583
|
+
if (options.json) out(JSON.stringify(enq));
|
|
5584
|
+
return 0;
|
|
5585
|
+
}
|
|
5586
|
+
if (!options.json) {
|
|
5587
|
+
info(`Build ${code(`#${enq.build_id}`)} queued \u2014 building on the platform\u2026`);
|
|
5588
|
+
}
|
|
5589
|
+
return pollBuild(enq.build_id, enq.module_id, mod.slug, options);
|
|
5590
|
+
}
|
|
5544
5591
|
const result = body;
|
|
5545
5592
|
if (!result) {
|
|
5546
5593
|
fail("Publish succeeded but the response body was empty or malformed.");
|
|
5547
5594
|
return 1;
|
|
5548
5595
|
}
|
|
5549
|
-
if (options.
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
success(`Published ${code(mod.slug)} ${code(`v${result.version}`)}`);
|
|
5596
|
+
if (options.json) {
|
|
5597
|
+
out(JSON.stringify(result));
|
|
5598
|
+
return 0;
|
|
5553
5599
|
}
|
|
5600
|
+
success(`Published ${code(mod.slug)} ${code(`v${result.version}`)}`);
|
|
5554
5601
|
info(`Bundle: ${code(result.bundle_url)}`);
|
|
5555
5602
|
info(`Hash: ${dim(result.bundle_hash)}`);
|
|
5556
5603
|
info(`Size: ${formatBytes2(result.bytes_uploaded)}`);
|
|
@@ -5560,9 +5607,61 @@ async function modulePublishCommand(options) {
|
|
|
5560
5607
|
out(` ${dim("\u2022")} ${w}`);
|
|
5561
5608
|
}
|
|
5562
5609
|
}
|
|
5563
|
-
if (process.stdout.isTTY
|
|
5610
|
+
if (process.stdout.isTTY) outro("Done.");
|
|
5611
|
+
return 0;
|
|
5612
|
+
}
|
|
5613
|
+
async function pollBuild(buildId, moduleId, slug, options) {
|
|
5614
|
+
const timeoutMs = (options.timeoutSec ?? 360) * 1e3;
|
|
5615
|
+
const intervalMs = options.pollIntervalMs ?? 4e3;
|
|
5616
|
+
const deadline = Date.now() + timeoutMs;
|
|
5617
|
+
let lastStatus = "";
|
|
5618
|
+
while (Date.now() < deadline) {
|
|
5619
|
+
let build;
|
|
5620
|
+
try {
|
|
5621
|
+
build = await apiRequest(
|
|
5622
|
+
"GET",
|
|
5623
|
+
`/api/modules/${moduleId}/builds/${buildId}`
|
|
5624
|
+
);
|
|
5625
|
+
} catch {
|
|
5626
|
+
await sleep2(intervalMs);
|
|
5627
|
+
continue;
|
|
5628
|
+
}
|
|
5629
|
+
if (!options.json && build.status !== lastStatus) {
|
|
5630
|
+
info(`Build ${code(`#${buildId}`)}: ${build.status}`);
|
|
5631
|
+
lastStatus = build.status;
|
|
5632
|
+
}
|
|
5633
|
+
if (build.status === "succeeded") {
|
|
5634
|
+
if (options.json) {
|
|
5635
|
+
out(JSON.stringify(build));
|
|
5636
|
+
} else {
|
|
5637
|
+
success(`Published ${code(slug)} ${code(`v${build.version ?? "?"}`)}`);
|
|
5638
|
+
info(`Build: ${dim(`#${buildId}`)}`);
|
|
5639
|
+
if (process.stdout.isTTY) outro("Done.");
|
|
5640
|
+
}
|
|
5641
|
+
return 0;
|
|
5642
|
+
}
|
|
5643
|
+
if (build.status === "failed") {
|
|
5644
|
+
if (options.json) {
|
|
5645
|
+
out(JSON.stringify(build));
|
|
5646
|
+
} else {
|
|
5647
|
+
fail(
|
|
5648
|
+
`Build ${code(`#${buildId}`)} failed (${build.error_code ?? "BUILD_FAILED"}): ${build.error_message ?? "(no detail)"}`
|
|
5649
|
+
);
|
|
5650
|
+
if (build.log_url) info(`Logs: ${code(build.log_url)}`);
|
|
5651
|
+
info(`Re-run ${code("dashwise module publish")} to try again.`);
|
|
5652
|
+
}
|
|
5653
|
+
return 1;
|
|
5654
|
+
}
|
|
5655
|
+
await sleep2(intervalMs);
|
|
5656
|
+
}
|
|
5657
|
+
warn(
|
|
5658
|
+
`Still building after ${options.timeoutSec ?? 360}s \u2014 the build is likely still running. Re-run ${code("dashwise module publish")} to check, or inspect build ${code(`#${buildId}`)}.`
|
|
5659
|
+
);
|
|
5564
5660
|
return 0;
|
|
5565
5661
|
}
|
|
5662
|
+
function sleep2(ms) {
|
|
5663
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
5664
|
+
}
|
|
5566
5665
|
function formatBytes2(n) {
|
|
5567
5666
|
if (n < 1024) return `${n}B`;
|
|
5568
5667
|
if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)}KB`;
|
|
@@ -8347,7 +8446,7 @@ async function runTail(moduleId, options) {
|
|
|
8347
8446
|
} catch (err) {
|
|
8348
8447
|
info(dim(`(tail poll error: ${err.message})`));
|
|
8349
8448
|
}
|
|
8350
|
-
await
|
|
8449
|
+
await sleep3(POLL_INTERVAL_MS);
|
|
8351
8450
|
}
|
|
8352
8451
|
}
|
|
8353
8452
|
function buildTailParams(options) {
|
|
@@ -8460,7 +8559,7 @@ function formatRow(row) {
|
|
|
8460
8559
|
function formatTimestamp(iso) {
|
|
8461
8560
|
return iso.slice(0, 19).replace("T", " ");
|
|
8462
8561
|
}
|
|
8463
|
-
function
|
|
8562
|
+
function sleep3(ms) {
|
|
8464
8563
|
return new Promise((resolve13) => setTimeout(resolve13, ms));
|
|
8465
8564
|
}
|
|
8466
8565
|
|
|
@@ -9083,14 +9182,25 @@ envCmd.command("export").description(
|
|
|
9083
9182
|
moduleCmd.command("publish").description("Pack the current directory + upload it as a new module version.").option("--dir <path>", "Project root (default: current directory).").option("--bump <direction>", "Semver bump: patch | minor | major.").option("--dry-run", "Validate + upload but do not persist the version row.").option("-y, --yes", "Skip the confirmation prompt (for CI / scripted use).").option(
|
|
9084
9183
|
"--exclude <pattern...>",
|
|
9085
9184
|
"Extra exclude patterns (segment-matched) appended to the defaults."
|
|
9086
|
-
).
|
|
9185
|
+
).option(
|
|
9186
|
+
"--no-wait",
|
|
9187
|
+
"Enqueue the build and exit immediately (print the build id) instead of polling to completion."
|
|
9188
|
+
).option(
|
|
9189
|
+
"--timeout <seconds>",
|
|
9190
|
+
"Max seconds to wait for an async build before giving up polling (default 360)."
|
|
9191
|
+
).option("--json", "Emit the final build result as machine-readable JSON.").action(
|
|
9087
9192
|
async (cmdOpts) => {
|
|
9193
|
+
const timeoutSec = cmdOpts.timeout !== void 0 ? Number(cmdOpts.timeout) : void 0;
|
|
9088
9194
|
process.exitCode = await modulePublishCommand({
|
|
9089
9195
|
...cmdOpts.dir !== void 0 ? { dir: cmdOpts.dir } : {},
|
|
9090
9196
|
...cmdOpts.bump !== void 0 ? { bump: cmdOpts.bump } : {},
|
|
9091
9197
|
...cmdOpts.dryRun !== void 0 ? { dryRun: cmdOpts.dryRun } : {},
|
|
9092
9198
|
...cmdOpts.yes !== void 0 ? { yes: cmdOpts.yes } : {},
|
|
9093
|
-
...cmdOpts.exclude !== void 0 ? { exclude: cmdOpts.exclude } : {}
|
|
9199
|
+
...cmdOpts.exclude !== void 0 ? { exclude: cmdOpts.exclude } : {},
|
|
9200
|
+
// commander maps `--no-wait` to `wait === false`.
|
|
9201
|
+
...cmdOpts.wait === false ? { noWait: true } : {},
|
|
9202
|
+
...timeoutSec !== void 0 && Number.isFinite(timeoutSec) ? { timeoutSec } : {},
|
|
9203
|
+
...cmdOpts.json !== void 0 ? { json: cmdOpts.json } : {}
|
|
9094
9204
|
});
|
|
9095
9205
|
}
|
|
9096
9206
|
);
|
|
@@ -9271,7 +9381,7 @@ fieldCmd.command("set-type <table-slug> <field-slug> <new-type>").description(
|
|
|
9271
9381
|
}
|
|
9272
9382
|
})();
|
|
9273
9383
|
function getVersion() {
|
|
9274
|
-
return "0.
|
|
9384
|
+
return "0.12.0";
|
|
9275
9385
|
}
|
|
9276
9386
|
function parseIntOption(value) {
|
|
9277
9387
|
const n = Number.parseInt(value, 10);
|