@abloatai/cli 0.57.0 → 0.58.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/cli.cjs +1074 -559
- package/package.json +4 -3
package/dist/cli.cjs
CHANGED
|
@@ -827,9 +827,9 @@ var init_query = __esm({
|
|
|
827
827
|
CLOSE = {};
|
|
828
828
|
Query = class extends Promise {
|
|
829
829
|
constructor(strings, args, handler, canceller, options = {}) {
|
|
830
|
-
let
|
|
830
|
+
let resolve11, reject;
|
|
831
831
|
super((a, b4) => {
|
|
832
|
-
|
|
832
|
+
resolve11 = a;
|
|
833
833
|
reject = b4;
|
|
834
834
|
});
|
|
835
835
|
this.tagged = Array.isArray(strings.raw);
|
|
@@ -840,7 +840,7 @@ var init_query = __esm({
|
|
|
840
840
|
this.options = options;
|
|
841
841
|
this.state = null;
|
|
842
842
|
this.statement = null;
|
|
843
|
-
this.resolve = (x2) => (this.active = false,
|
|
843
|
+
this.resolve = (x2) => (this.active = false, resolve11(x2));
|
|
844
844
|
this.reject = (x2) => (this.active = false, reject(x2));
|
|
845
845
|
this.active = false;
|
|
846
846
|
this.cancelled = null;
|
|
@@ -888,12 +888,12 @@ var init_query = __esm({
|
|
|
888
888
|
if (this.executed && !this.active)
|
|
889
889
|
return { done: true };
|
|
890
890
|
prev && prev();
|
|
891
|
-
const promise = new Promise((
|
|
891
|
+
const promise = new Promise((resolve11, reject) => {
|
|
892
892
|
this.cursorFn = (value) => {
|
|
893
|
-
|
|
893
|
+
resolve11({ value, done: false });
|
|
894
894
|
return new Promise((r2) => prev = r2);
|
|
895
895
|
};
|
|
896
|
-
this.resolve = () => (this.active = false,
|
|
896
|
+
this.resolve = () => (this.active = false, resolve11({ done: true }));
|
|
897
897
|
this.reject = (x2) => (this.active = false, reject(x2));
|
|
898
898
|
});
|
|
899
899
|
this.execute();
|
|
@@ -1491,12 +1491,12 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
1491
1491
|
x2.on("drain", drain);
|
|
1492
1492
|
return x2;
|
|
1493
1493
|
}
|
|
1494
|
-
async function cancel({ pid, secret },
|
|
1494
|
+
async function cancel({ pid, secret }, resolve11, reject) {
|
|
1495
1495
|
try {
|
|
1496
1496
|
cancelMessage = bytes_default().i32(16).i32(80877102).i32(pid).i32(secret).end(16);
|
|
1497
1497
|
await connect2();
|
|
1498
1498
|
socket.once("error", reject);
|
|
1499
|
-
socket.once("close",
|
|
1499
|
+
socket.once("close", resolve11);
|
|
1500
1500
|
} catch (error2) {
|
|
1501
1501
|
reject(error2);
|
|
1502
1502
|
}
|
|
@@ -2519,7 +2519,7 @@ var init_subscribe = __esm({
|
|
|
2519
2519
|
|
|
2520
2520
|
// ../../node_modules/postgres/src/large.js
|
|
2521
2521
|
function largeObject(sql, oid, mode = 131072 | 262144) {
|
|
2522
|
-
return new Promise(async (
|
|
2522
|
+
return new Promise(async (resolve11, reject) => {
|
|
2523
2523
|
await sql.begin(async (sql2) => {
|
|
2524
2524
|
let finish;
|
|
2525
2525
|
!oid && ([{ oid }] = await sql2`select lo_creat(-1) as oid`);
|
|
@@ -2545,7 +2545,7 @@ function largeObject(sql, oid, mode = 131072 | 262144) {
|
|
|
2545
2545
|
) seek
|
|
2546
2546
|
`
|
|
2547
2547
|
};
|
|
2548
|
-
|
|
2548
|
+
resolve11(lo);
|
|
2549
2549
|
return new Promise(async (r2) => finish = r2);
|
|
2550
2550
|
async function readable({
|
|
2551
2551
|
highWaterMark = 2048 * 8,
|
|
@@ -2707,8 +2707,8 @@ function Postgres(a, b4) {
|
|
|
2707
2707
|
}
|
|
2708
2708
|
async function reserve() {
|
|
2709
2709
|
const queue = queue_default();
|
|
2710
|
-
const c = open.length ? open.shift() : await new Promise((
|
|
2711
|
-
const query = { reserve:
|
|
2710
|
+
const c = open.length ? open.shift() : await new Promise((resolve11, reject) => {
|
|
2711
|
+
const query = { reserve: resolve11, reject };
|
|
2712
2712
|
queries.push(query);
|
|
2713
2713
|
closed.length && connect2(closed.shift(), query);
|
|
2714
2714
|
});
|
|
@@ -2745,9 +2745,9 @@ function Postgres(a, b4) {
|
|
|
2745
2745
|
let uncaughtError, result;
|
|
2746
2746
|
name && await sql2`savepoint ${sql2(name)}`;
|
|
2747
2747
|
try {
|
|
2748
|
-
result = await new Promise((
|
|
2748
|
+
result = await new Promise((resolve11, reject) => {
|
|
2749
2749
|
const x2 = fn2(sql2);
|
|
2750
|
-
Promise.resolve(Array.isArray(x2) ? Promise.all(x2) : x2).then(
|
|
2750
|
+
Promise.resolve(Array.isArray(x2) ? Promise.all(x2) : x2).then(resolve11, reject);
|
|
2751
2751
|
});
|
|
2752
2752
|
if (uncaughtError)
|
|
2753
2753
|
throw uncaughtError;
|
|
@@ -2804,8 +2804,8 @@ function Postgres(a, b4) {
|
|
|
2804
2804
|
return c.execute(query) ? move(c, busy) : move(c, full);
|
|
2805
2805
|
}
|
|
2806
2806
|
function cancel(query) {
|
|
2807
|
-
return new Promise((
|
|
2808
|
-
query.state ? query.active ? connection_default(options).cancel(query.state,
|
|
2807
|
+
return new Promise((resolve11, reject) => {
|
|
2808
|
+
query.state ? query.active ? connection_default(options).cancel(query.state, resolve11, reject) : query.cancelled = { resolve: resolve11, reject } : (queries.remove(query), query.cancelled = true, query.reject(Errors.generic("57014", "canceling statement due to user request")), resolve11());
|
|
2809
2809
|
});
|
|
2810
2810
|
}
|
|
2811
2811
|
async function end({ timeout = null } = {}) {
|
|
@@ -2824,11 +2824,11 @@ function Postgres(a, b4) {
|
|
|
2824
2824
|
async function close() {
|
|
2825
2825
|
await Promise.all(connections.map((c) => c.end()));
|
|
2826
2826
|
}
|
|
2827
|
-
async function destroy(
|
|
2827
|
+
async function destroy(resolve11) {
|
|
2828
2828
|
await Promise.all(connections.map((c) => c.terminate()));
|
|
2829
2829
|
while (queries.length)
|
|
2830
2830
|
queries.shift().reject(Errors.connection("CONNECTION_DESTROYED", options));
|
|
2831
|
-
|
|
2831
|
+
resolve11();
|
|
2832
2832
|
}
|
|
2833
2833
|
function connect2(c, query) {
|
|
2834
2834
|
move(c, connecting);
|
|
@@ -3349,7 +3349,7 @@ function ambientEnvKeyNote(cwd) {
|
|
|
3349
3349
|
return `Note: ${ambient.source} in this directory holds an ABLO_API_KEY, which this command does not load \u2014 it reads only the process environment and your stored login, so a file cannot silently choose a branch. Export the variable, or pass \`--env-file ` + ambient.source + "` to a connect command, to choose it explicitly.";
|
|
3350
3350
|
}
|
|
3351
3351
|
function resolveManagementKey() {
|
|
3352
|
-
if (process.env.
|
|
3352
|
+
if (process.env.ABLO_API_KEY?.startsWith("mk_")) return process.env.ABLO_API_KEY;
|
|
3353
3353
|
const cfg = readConfig();
|
|
3354
3354
|
if (!cfg) return void 0;
|
|
3355
3355
|
const entry = cfg.profiles[activeProfileName(cfg)]?.management;
|
|
@@ -3358,7 +3358,7 @@ function resolveManagementKey() {
|
|
|
3358
3358
|
return entry.apiKey;
|
|
3359
3359
|
}
|
|
3360
3360
|
function resolveOrgManagementKey(options = {}) {
|
|
3361
|
-
if (process.env.
|
|
3361
|
+
if (process.env.ABLO_API_KEY?.startsWith("mk_")) return process.env.ABLO_API_KEY;
|
|
3362
3362
|
const cfg = readConfig({ persistMigrations: options.persistConfigMigrations });
|
|
3363
3363
|
if (!cfg) return void 0;
|
|
3364
3364
|
const profiles = [.../* @__PURE__ */ new Set([
|
|
@@ -3458,7 +3458,7 @@ function requireKey() {
|
|
|
3458
3458
|
if (!apiKey) {
|
|
3459
3459
|
console.error(
|
|
3460
3460
|
import_picocolors3.default.red(" No project management credential.") + import_picocolors3.default.dim(
|
|
3461
|
-
` Run ${import_picocolors3.default.bold("npx ablo login")} \u2014 or set ${import_picocolors3.default.bold("
|
|
3461
|
+
` Run ${import_picocolors3.default.bold("npx ablo login")} \u2014 or set ${import_picocolors3.default.bold("ABLO_API_KEY")} to an ${import_picocolors3.default.bold("mk_")} credential.`
|
|
3462
3462
|
)
|
|
3463
3463
|
);
|
|
3464
3464
|
process.exit(1);
|
|
@@ -3481,15 +3481,18 @@ async function request(path, apiKey, init3 = {}, baseUrl2) {
|
|
|
3481
3481
|
}
|
|
3482
3482
|
return { status: res.status, body };
|
|
3483
3483
|
}
|
|
3484
|
+
function projectListResult(status2, body) {
|
|
3485
|
+
if (status2 !== 200) {
|
|
3486
|
+
const code = typeof body === "object" && body !== null && "code" in body ? body.code : void 0;
|
|
3487
|
+
return { ok: false, reason: typeof code === "string" ? code : `HTTP ${status2}` };
|
|
3488
|
+
}
|
|
3489
|
+
const parsed = import_wire.projectListResponseSchema.safeParse(body);
|
|
3490
|
+
return parsed.success ? { ok: true, projects: parsed.data.data } : { ok: false, reason: "the response did not match the project list" };
|
|
3491
|
+
}
|
|
3484
3492
|
async function listProjects(apiKey, baseUrl2) {
|
|
3485
3493
|
try {
|
|
3486
3494
|
const { status: status2, body } = await request("/api/v1/projects", apiKey, {}, baseUrl2);
|
|
3487
|
-
|
|
3488
|
-
const code = body?.code;
|
|
3489
|
-
return { ok: false, reason: typeof code === "string" ? code : `HTTP ${status2}` };
|
|
3490
|
-
}
|
|
3491
|
-
const parsed = import_wire.projectListResponseSchema.safeParse(body);
|
|
3492
|
-
return parsed.success ? { ok: true, projects: parsed.data.data } : { ok: false, reason: "the response did not match the project list" };
|
|
3495
|
+
return projectListResult(status2, body);
|
|
3493
3496
|
} catch (err) {
|
|
3494
3497
|
return { ok: false, reason: err instanceof Error ? err.message : "the request failed" };
|
|
3495
3498
|
}
|
|
@@ -3538,6 +3541,10 @@ async function ensureProject(slug, name) {
|
|
|
3538
3541
|
return null;
|
|
3539
3542
|
}
|
|
3540
3543
|
}
|
|
3544
|
+
function projectDisplayName(p2) {
|
|
3545
|
+
const spelling = (s) => s.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
3546
|
+
return p2.name && spelling(p2.name) !== spelling(p2.slug) ? p2.name : void 0;
|
|
3547
|
+
}
|
|
3541
3548
|
function describeKeys(profile) {
|
|
3542
3549
|
const now = Date.now();
|
|
3543
3550
|
let usable = 0;
|
|
@@ -3566,8 +3573,7 @@ function describeAge(createdAt) {
|
|
|
3566
3573
|
function printList(projects2) {
|
|
3567
3574
|
const active = getActiveProject();
|
|
3568
3575
|
const profiles = readConfig()?.profiles ?? {};
|
|
3569
|
-
const
|
|
3570
|
-
const nameOf = (p2) => p2.name && spelling(p2.name) !== spelling(p2.slug) ? p2.name : "";
|
|
3576
|
+
const nameOf = (p2) => projectDisplayName(p2) ?? "";
|
|
3571
3577
|
const showNames = projects2.some((p2) => nameOf(p2) !== "");
|
|
3572
3578
|
const slugWidth = Math.max(...projects2.map((p2) => p2.slug.length));
|
|
3573
3579
|
const nameWidth = showNames ? Math.max(...projects2.map((p2) => nameOf(p2).length)) : 0;
|
|
@@ -3970,7 +3976,7 @@ var init_observeCliError = __esm({
|
|
|
3970
3976
|
import_errorObservation = require("@abloatai/transaction/errorObservation");
|
|
3971
3977
|
import_errors5 = require("@abloatai/transaction/errors");
|
|
3972
3978
|
dsn = process.env.ABLO_CLI_SENTRY_DSN ?? "https://1ac154bff10b06836e1ea9de9e0d92f0@o4510928209772544.ingest.de.sentry.io/4511660691423312" ?? "";
|
|
3973
|
-
release = process.env.ABLO_CLI_RELEASE ?? "@abloatai/cli@0.
|
|
3979
|
+
release = process.env.ABLO_CLI_RELEASE ?? "@abloatai/cli@0.58.0";
|
|
3974
3980
|
initialized = false;
|
|
3975
3981
|
nativeProcessExit = process.exit.bind(process);
|
|
3976
3982
|
exitBoundaryInstalled = false;
|
|
@@ -4297,7 +4303,7 @@ var init_src2 = __esm({
|
|
|
4297
4303
|
|
|
4298
4304
|
// src/cliEnvironment.ts
|
|
4299
4305
|
function cliVersion() {
|
|
4300
|
-
return "0.
|
|
4306
|
+
return "0.58.0";
|
|
4301
4307
|
}
|
|
4302
4308
|
function cliOs() {
|
|
4303
4309
|
const value = (0, import_node_os.platform)();
|
|
@@ -4729,16 +4735,9 @@ async function fetchActiveSchema(url, apiKey) {
|
|
|
4729
4735
|
clearTimeout(t);
|
|
4730
4736
|
}
|
|
4731
4737
|
}
|
|
4732
|
-
function conflictStr(c) {
|
|
4733
|
-
if (!c) return "";
|
|
4734
|
-
const parts = import_schema2.participantKindSchema.options.flatMap((k3) => c[k3] ? [`${k3}:${c[k3]}`] : []);
|
|
4735
|
-
return parts.length ? `{${parts.join(",")}}` : "";
|
|
4736
|
-
}
|
|
4737
4738
|
function localModels(schema) {
|
|
4738
4739
|
const json = JSON.parse((0, import_schema.serializeSchema)(schema));
|
|
4739
|
-
|
|
4740
|
-
for (const [key, def] of Object.entries(json.models)) out.set(key, conflictStr(def.conflict));
|
|
4741
|
-
return out;
|
|
4740
|
+
return new Set(Object.keys(json.models));
|
|
4742
4741
|
}
|
|
4743
4742
|
function printPlan(local, remote) {
|
|
4744
4743
|
if (!remote?.models) {
|
|
@@ -4746,21 +4745,17 @@ function printPlan(local, remote) {
|
|
|
4746
4745
|
`);
|
|
4747
4746
|
return;
|
|
4748
4747
|
}
|
|
4749
|
-
const
|
|
4750
|
-
|
|
4751
|
-
const
|
|
4752
|
-
const removed = [...remoteMap.keys()].filter((k3) => !local.has(k3));
|
|
4753
|
-
const changed = [...local.keys()].filter((k3) => remoteMap.has(k3) && remoteMap.get(k3) !== local.get(k3));
|
|
4748
|
+
const remoteKeys = new Set(remote.models.map((model) => model.key));
|
|
4749
|
+
const added = [...local].filter((key) => !remoteKeys.has(key));
|
|
4750
|
+
const removed = [...remoteKeys].filter((key) => !local.has(key));
|
|
4754
4751
|
const verLabel = remote.version != null ? `v${remote.version}` : "active";
|
|
4755
|
-
if (added.length === 0 && removed.length === 0
|
|
4752
|
+
if (added.length === 0 && removed.length === 0) {
|
|
4756
4753
|
console.log(` ${import_picocolors5.default.dim("plan")} ${import_picocolors5.default.dim(`no model-level changes vs deployed ${verLabel} (any field changes apply on push)`)}
|
|
4757
4754
|
`);
|
|
4758
4755
|
return;
|
|
4759
4756
|
}
|
|
4760
4757
|
console.log(` ${import_picocolors5.default.dim("plan")} ${import_picocolors5.default.dim(`vs deployed ${verLabel}:`)}`);
|
|
4761
4758
|
for (const k3 of added) console.log(` ${import_picocolors5.default.green(`+ ${k3}`)} ${import_picocolors5.default.dim("(new model)")}`);
|
|
4762
|
-
for (const k3 of changed)
|
|
4763
|
-
console.log(` ${import_picocolors5.default.yellow(`~ ${k3}`)} ${import_picocolors5.default.dim(`conflict ${remoteMap.get(k3) || "(default)"} \u2192 ${local.get(k3) || "(default)"}`)}`);
|
|
4764
4759
|
for (const k3 of removed) console.log(` ${import_picocolors5.default.red(`- ${k3}`)} ${import_picocolors5.default.dim("(removed \u2014 destructive, needs --force)")}`);
|
|
4765
4760
|
console.log("");
|
|
4766
4761
|
}
|
|
@@ -5051,7 +5046,7 @@ async function push(argv) {
|
|
|
5051
5046
|
}
|
|
5052
5047
|
process.exit(1);
|
|
5053
5048
|
}
|
|
5054
|
-
var import_picocolors5, import_errors7, import_credentialPolicy, import_fs4, import_path3, import_child_process, import_schema,
|
|
5049
|
+
var import_picocolors5, import_errors7, import_credentialPolicy, import_fs4, import_path3, import_child_process, import_schema, DEFAULT_SCHEMA_PATH, DEFAULT_EXPORT, PUSH_USAGE;
|
|
5055
5050
|
var init_push = __esm({
|
|
5056
5051
|
"src/push.ts"() {
|
|
5057
5052
|
"use strict";
|
|
@@ -5069,7 +5064,6 @@ var init_push = __esm({
|
|
|
5069
5064
|
init_target();
|
|
5070
5065
|
init_theme();
|
|
5071
5066
|
init_renderError();
|
|
5072
|
-
import_schema2 = require("@abloatai/transaction/coordination/schema");
|
|
5073
5067
|
init_telemetry();
|
|
5074
5068
|
DEFAULT_SCHEMA_PATH = "ablo/schema.ts";
|
|
5075
5069
|
DEFAULT_EXPORT = "schema";
|
|
@@ -5096,6 +5090,84 @@ var init_push = __esm({
|
|
|
5096
5090
|
}
|
|
5097
5091
|
});
|
|
5098
5092
|
|
|
5093
|
+
// src/dbProvider.ts
|
|
5094
|
+
function hostAndPort(hostOrTarget) {
|
|
5095
|
+
const withoutScheme = hostOrTarget.trim().replace(/^[a-z0-9+.-]+:\/\//i, "");
|
|
5096
|
+
const at = withoutScheme.lastIndexOf("@");
|
|
5097
|
+
const withoutUserinfo = at === -1 ? withoutScheme : withoutScheme.slice(at + 1);
|
|
5098
|
+
const authority = withoutUserinfo.split("/")[0] ?? "";
|
|
5099
|
+
const parts = /^(\[[^\]]*\]|[^:]*)(?::(\d+))?$/.exec(authority);
|
|
5100
|
+
return { hostname: (parts?.[1] ?? authority).toLowerCase(), port: parts?.[2] ?? "" };
|
|
5101
|
+
}
|
|
5102
|
+
function inDomain(hostname, domain) {
|
|
5103
|
+
return hostname === domain || hostname.endsWith(`.${domain}`);
|
|
5104
|
+
}
|
|
5105
|
+
function detectProvider(hostOrTarget) {
|
|
5106
|
+
const { hostname } = hostAndPort(hostOrTarget);
|
|
5107
|
+
const spec = PROVIDERS.find((p2) => p2.domains.some((domain) => inDomain(hostname, domain)));
|
|
5108
|
+
return spec?.id ?? "generic";
|
|
5109
|
+
}
|
|
5110
|
+
function detectPooler(hostOrTarget) {
|
|
5111
|
+
const { hostname, port } = hostAndPort(hostOrTarget);
|
|
5112
|
+
const provider = detectProvider(hostOrTarget);
|
|
5113
|
+
const spec = PROVIDERS.find((p2) => p2.id === provider);
|
|
5114
|
+
if (spec?.isPooledHost?.(hostname)) {
|
|
5115
|
+
const direct = spec.directTarget?.(hostOrTarget);
|
|
5116
|
+
return direct === void 0 ? { provider, confidence: "host" } : { provider, direct, confidence: "host" };
|
|
5117
|
+
}
|
|
5118
|
+
if (POOLER_PORTS.has(port)) return { provider, confidence: "port" };
|
|
5119
|
+
return null;
|
|
5120
|
+
}
|
|
5121
|
+
function replicationGrantRole(provider) {
|
|
5122
|
+
const specs = PROVIDERS;
|
|
5123
|
+
const spec = specs.find((candidate) => candidate.id === provider);
|
|
5124
|
+
return spec?.replicationGrantRole ?? null;
|
|
5125
|
+
}
|
|
5126
|
+
function logicalReplicationGuidance(provider) {
|
|
5127
|
+
const spec = PROVIDERS.find((p2) => p2.id === provider);
|
|
5128
|
+
if (spec) return spec.logicalReplication;
|
|
5129
|
+
return `run the ALTER SYSTEM above, then restart Postgres (wal_level is not reloadable). On a managed host that refuses ALTER SYSTEM, set wal_level to logical in its dashboard instead`;
|
|
5130
|
+
}
|
|
5131
|
+
var PROVIDERS, POOLER_PORTS;
|
|
5132
|
+
var init_dbProvider = __esm({
|
|
5133
|
+
"src/dbProvider.ts"() {
|
|
5134
|
+
"use strict";
|
|
5135
|
+
init_cjs_shims();
|
|
5136
|
+
PROVIDERS = [
|
|
5137
|
+
{
|
|
5138
|
+
id: "neon",
|
|
5139
|
+
domains: ["neon.tech"],
|
|
5140
|
+
logicalReplication: `enable logical replication in your Neon project settings \u2014 it can't be set over SQL`,
|
|
5141
|
+
// Neon encodes pooling in the endpoint id, so the direct host is the same
|
|
5142
|
+
// name with the marker removed: a fix the reader applies without a lookup.
|
|
5143
|
+
isPooledHost: (hostname) => hostname.includes("-pooler"),
|
|
5144
|
+
directTarget: (hostOrTarget) => hostOrTarget.replace(/-pooler/i, "")
|
|
5145
|
+
},
|
|
5146
|
+
{
|
|
5147
|
+
id: "supabase",
|
|
5148
|
+
domains: ["supabase.co", "supabase.com"],
|
|
5149
|
+
logicalReplication: `raise wal_level to logical in your Supabase project's database settings`,
|
|
5150
|
+
// Supavisor is a separate host entirely (`aws-0-<region>.pooler.supabase.com`),
|
|
5151
|
+
// so there is no direct host to derive from it.
|
|
5152
|
+
isPooledHost: (hostname) => hostname.endsWith(".pooler.supabase.com")
|
|
5153
|
+
},
|
|
5154
|
+
{
|
|
5155
|
+
id: "rds",
|
|
5156
|
+
// Anchored to the real RDS domains, including the China partition, rather
|
|
5157
|
+
// than a bare `.rds.` anywhere in the name.
|
|
5158
|
+
domains: ["rds.amazonaws.com", "rds.amazonaws.com.cn"],
|
|
5159
|
+
logicalReplication: `set rds.logical_replication = 1 in the instance's parameter group, then reboot`,
|
|
5160
|
+
// RDS Proxy fronts the instance under a `.proxy-` subdomain.
|
|
5161
|
+
isPooledHost: (hostname) => hostname.includes(".proxy-"),
|
|
5162
|
+
// Neither the master user nor rds_superuser carries REPLICATION; AWS keeps
|
|
5163
|
+
// it on rdsadmin and exposes it through this role.
|
|
5164
|
+
replicationGrantRole: "rds_replication"
|
|
5165
|
+
}
|
|
5166
|
+
];
|
|
5167
|
+
POOLER_PORTS = /* @__PURE__ */ new Set(["6432", "6543"]);
|
|
5168
|
+
}
|
|
5169
|
+
});
|
|
5170
|
+
|
|
5099
5171
|
// src/remoteValidation.ts
|
|
5100
5172
|
function dialFailureReason(err) {
|
|
5101
5173
|
if (err === null || typeof err !== "object") return null;
|
|
@@ -5192,76 +5264,6 @@ var init_remoteValidation = __esm({
|
|
|
5192
5264
|
}
|
|
5193
5265
|
});
|
|
5194
5266
|
|
|
5195
|
-
// src/dbProvider.ts
|
|
5196
|
-
function hostAndPort(hostOrTarget) {
|
|
5197
|
-
const withoutScheme = hostOrTarget.trim().replace(/^[a-z0-9+.-]+:\/\//i, "");
|
|
5198
|
-
const at = withoutScheme.lastIndexOf("@");
|
|
5199
|
-
const withoutUserinfo = at === -1 ? withoutScheme : withoutScheme.slice(at + 1);
|
|
5200
|
-
const authority = withoutUserinfo.split("/")[0] ?? "";
|
|
5201
|
-
const parts = /^(\[[^\]]*\]|[^:]*)(?::(\d+))?$/.exec(authority);
|
|
5202
|
-
return { hostname: (parts?.[1] ?? authority).toLowerCase(), port: parts?.[2] ?? "" };
|
|
5203
|
-
}
|
|
5204
|
-
function inDomain(hostname, domain) {
|
|
5205
|
-
return hostname === domain || hostname.endsWith(`.${domain}`);
|
|
5206
|
-
}
|
|
5207
|
-
function detectProvider(hostOrTarget) {
|
|
5208
|
-
const { hostname } = hostAndPort(hostOrTarget);
|
|
5209
|
-
const spec = PROVIDERS.find((p2) => p2.domains.some((domain) => inDomain(hostname, domain)));
|
|
5210
|
-
return spec?.id ?? "generic";
|
|
5211
|
-
}
|
|
5212
|
-
function detectPooler(hostOrTarget) {
|
|
5213
|
-
const { hostname, port } = hostAndPort(hostOrTarget);
|
|
5214
|
-
const provider = detectProvider(hostOrTarget);
|
|
5215
|
-
const spec = PROVIDERS.find((p2) => p2.id === provider);
|
|
5216
|
-
if (spec?.isPooledHost?.(hostname)) {
|
|
5217
|
-
const direct = spec.directTarget?.(hostOrTarget);
|
|
5218
|
-
return direct === void 0 ? { provider, confidence: "host" } : { provider, direct, confidence: "host" };
|
|
5219
|
-
}
|
|
5220
|
-
if (POOLER_PORTS.has(port)) return { provider, confidence: "port" };
|
|
5221
|
-
return null;
|
|
5222
|
-
}
|
|
5223
|
-
function logicalReplicationGuidance(provider) {
|
|
5224
|
-
const spec = PROVIDERS.find((p2) => p2.id === provider);
|
|
5225
|
-
if (spec) return spec.logicalReplication;
|
|
5226
|
-
return `run the ALTER SYSTEM above, then restart Postgres (wal_level is not reloadable). On a managed host that refuses ALTER SYSTEM, set wal_level to logical in its dashboard instead`;
|
|
5227
|
-
}
|
|
5228
|
-
var PROVIDERS, POOLER_PORTS;
|
|
5229
|
-
var init_dbProvider = __esm({
|
|
5230
|
-
"src/dbProvider.ts"() {
|
|
5231
|
-
"use strict";
|
|
5232
|
-
init_cjs_shims();
|
|
5233
|
-
PROVIDERS = [
|
|
5234
|
-
{
|
|
5235
|
-
id: "neon",
|
|
5236
|
-
domains: ["neon.tech"],
|
|
5237
|
-
logicalReplication: `enable logical replication in your Neon project settings \u2014 it can't be set over SQL`,
|
|
5238
|
-
// Neon encodes pooling in the endpoint id, so the direct host is the same
|
|
5239
|
-
// name with the marker removed: a fix the reader applies without a lookup.
|
|
5240
|
-
isPooledHost: (hostname) => hostname.includes("-pooler"),
|
|
5241
|
-
directTarget: (hostOrTarget) => hostOrTarget.replace(/-pooler/i, "")
|
|
5242
|
-
},
|
|
5243
|
-
{
|
|
5244
|
-
id: "supabase",
|
|
5245
|
-
domains: ["supabase.co", "supabase.com"],
|
|
5246
|
-
logicalReplication: `raise wal_level to logical in your Supabase project's database settings`,
|
|
5247
|
-
// Supavisor is a separate host entirely (`aws-0-<region>.pooler.supabase.com`),
|
|
5248
|
-
// so there is no direct host to derive from it.
|
|
5249
|
-
isPooledHost: (hostname) => hostname.endsWith(".pooler.supabase.com")
|
|
5250
|
-
},
|
|
5251
|
-
{
|
|
5252
|
-
id: "rds",
|
|
5253
|
-
// Anchored to the real RDS domains, including the China partition, rather
|
|
5254
|
-
// than a bare `.rds.` anywhere in the name.
|
|
5255
|
-
domains: ["rds.amazonaws.com", "rds.amazonaws.com.cn"],
|
|
5256
|
-
logicalReplication: `set rds.logical_replication = 1 in the instance's parameter group, then reboot`,
|
|
5257
|
-
// RDS Proxy fronts the instance under a `.proxy-` subdomain.
|
|
5258
|
-
isPooledHost: (hostname) => hostname.includes(".proxy-")
|
|
5259
|
-
}
|
|
5260
|
-
];
|
|
5261
|
-
POOLER_PORTS = /* @__PURE__ */ new Set(["6432", "6543"]);
|
|
5262
|
-
}
|
|
5263
|
-
});
|
|
5264
|
-
|
|
5265
5267
|
// src/connectSetup.ts
|
|
5266
5268
|
function hostLabel(connectionString) {
|
|
5267
5269
|
try {
|
|
@@ -5293,12 +5295,26 @@ BEGIN
|
|
|
5293
5295
|
END LOOP;
|
|
5294
5296
|
END $$;`;
|
|
5295
5297
|
}
|
|
5298
|
+
function replicationBypassSql(input) {
|
|
5299
|
+
if (input.canGrantBypassRls) return [];
|
|
5300
|
+
return input.tables.flatMap((table) => {
|
|
5301
|
+
const qualified = `${quoteIdent(input.schema)}.${quoteIdent(table)}`;
|
|
5302
|
+
const policy = quoteIdent(`${input.role}_snapshot`);
|
|
5303
|
+
return [
|
|
5304
|
+
// CREATE POLICY has no IF NOT EXISTS, and every step here is safe to
|
|
5305
|
+
// re-run, so the drop carries the idempotency.
|
|
5306
|
+
`DROP POLICY IF EXISTS ${policy} ON ${qualified};`,
|
|
5307
|
+
`CREATE POLICY ${policy} ON ${qualified} FOR SELECT TO ${quoteIdent(input.role)} USING (true);`
|
|
5308
|
+
];
|
|
5309
|
+
});
|
|
5310
|
+
}
|
|
5296
5311
|
function connectSetupSql(input) {
|
|
5297
5312
|
const role = input.role && input.role.length > 0 ? input.role : import_footprint.ABLO_REPLICATION_ROLE;
|
|
5298
5313
|
const writeRole = input.writeRole && input.writeRole.length > 0 ? input.writeRole : import_footprint.ABLO_WRITE_ROLE;
|
|
5299
5314
|
const tables = input.tables ?? [];
|
|
5300
5315
|
const schema = input.schema ?? "public";
|
|
5301
5316
|
const publication = input.publication;
|
|
5317
|
+
const canGrantBypassRls = input.canGrantBypassRls !== false;
|
|
5302
5318
|
const qualifiedTables = tables.map((table) => `${quoteIdent(schema)}.${quoteIdent(table)}`);
|
|
5303
5319
|
const publicationTarget = tables.length > 0 ? `FOR TABLE ${qualifiedTables.join(", ")}` : "FOR ALL TABLES";
|
|
5304
5320
|
const tableList = qualifiedTables.join(", ");
|
|
@@ -5318,9 +5334,11 @@ function connectSetupSql(input) {
|
|
|
5318
5334
|
// 3. A least-privilege role: it can stream replication and SELECT the
|
|
5319
5335
|
// published tables, including the initial snapshot of RLS-protected tables.
|
|
5320
5336
|
// Logical decoding already exposes every published row independently of
|
|
5321
|
-
// RLS
|
|
5322
|
-
|
|
5337
|
+
// RLS, so the reader needs the ordinary SELECT snapshot to match that same
|
|
5338
|
+
// scope. How it gets there depends on what this admin may grant.
|
|
5339
|
+
`CREATE ROLE ${quoteIdent(role)} WITH NOSUPERUSER ${canGrantBypassRls ? "BYPASSRLS " : ""}NOCREATEDB NOCREATEROLE ${canGrantBypassRls ? "REPLICATION NOINHERIT" : "NOREPLICATION INHERIT"} LOGIN PASSWORD '<password>';`,
|
|
5323
5340
|
...replicationReadGrants,
|
|
5341
|
+
...replicationBypassSql({ role, tables, schema, canGrantBypassRls }),
|
|
5324
5342
|
// 4. A distinct DML role: no replication, role administration, ownership,
|
|
5325
5343
|
// schema creation, or DDL. It runs NOBYPASSRLS with row_security on, so on a
|
|
5326
5344
|
// table that HAS row-level-security policies they govern its writes and it
|
|
@@ -5466,7 +5484,15 @@ On Neon enable Logical Replication in the project (Console \u2192 Settings \u219
|
|
|
5466
5484
|
`SELECT rolreplication, rolsuper, rolbypassrls FROM pg_roles WHERE rolname = current_user`
|
|
5467
5485
|
);
|
|
5468
5486
|
const role = roleRows[0];
|
|
5469
|
-
const
|
|
5487
|
+
const grantRole = opts.replicationGrantRole ?? null;
|
|
5488
|
+
const viaGrant = grantRole ? (await sql.unsafe(
|
|
5489
|
+
`SELECT EXISTS (
|
|
5490
|
+
SELECT 1 FROM pg_roles r
|
|
5491
|
+
WHERE r.rolname = $1 AND pg_has_role(current_user, r.oid, 'MEMBER')
|
|
5492
|
+
) AS member`,
|
|
5493
|
+
[grantRole]
|
|
5494
|
+
))[0]?.member === true : false;
|
|
5495
|
+
const hasReplication = Boolean(role && (role.rolreplication || role.rolsuper)) || viaGrant;
|
|
5470
5496
|
items.push(
|
|
5471
5497
|
hasReplication ? {
|
|
5472
5498
|
ok: true,
|
|
@@ -5486,6 +5512,20 @@ On RDS: GRANT rds_replication TO <your_role>;`
|
|
|
5486
5512
|
JOIN pg_class c ON c.relnamespace = n.oid AND c.relname = pt.tablename
|
|
5487
5513
|
WHERE pt.pubname = $1 AND pt.schemaname = $2
|
|
5488
5514
|
AND row_security_active(c.oid)
|
|
5515
|
+
AND NOT EXISTS (
|
|
5516
|
+
SELECT 1 FROM pg_policies p
|
|
5517
|
+
WHERE p.schemaname = pt.schemaname
|
|
5518
|
+
AND p.tablename = pt.tablename
|
|
5519
|
+
AND p.permissive = 'PERMISSIVE'
|
|
5520
|
+
AND p.cmd IN ('ALL', 'SELECT')
|
|
5521
|
+
AND p.qual = 'true'
|
|
5522
|
+
-- Membership, not containment: pg_policies.roles is name[], while
|
|
5523
|
+
-- ARRAY['public'] is text[]. Postgres has no name[] @> text[] operator, so
|
|
5524
|
+
-- the containment spelling fails at execution rather than at parse time:
|
|
5525
|
+
-- the probe threw instead of reporting, which reads as an unreachable
|
|
5526
|
+
-- database rather than a readable one.
|
|
5527
|
+
AND ('public' = ANY(p.roles) OR current_user = ANY(p.roles))
|
|
5528
|
+
)
|
|
5489
5529
|
ORDER BY table_name`,
|
|
5490
5530
|
[publication, schema]
|
|
5491
5531
|
);
|
|
@@ -5495,7 +5535,9 @@ On RDS: GRANT rds_replication TO <your_role>;`
|
|
|
5495
5535
|
ok: false,
|
|
5496
5536
|
label: `${rlsRelevant.length} published table${rlsRelevant.length === 1 ? "" : "s"} hide historical rows behind RLS`,
|
|
5497
5537
|
fix: `ALTER ROLE current_user WITH BYPASSRLS;
|
|
5498
|
-
|
|
5538
|
+
Where the provider reserves that attribute (Amazon RDS, Aurora), give the reader a policy instead:
|
|
5539
|
+
CREATE POLICY <reader>_snapshot ON <table> FOR SELECT TO <reader> USING (true);
|
|
5540
|
+
Logical replication already exposes every published row; either lets the ordinary initial SELECT read that same scope.`
|
|
5499
5541
|
}
|
|
5500
5542
|
);
|
|
5501
5543
|
const badRows = await sql.unsafe(
|
|
@@ -6033,7 +6075,7 @@ async function fetchDataSourceState(apiUrl3, apiKey, timeoutMs = 4e3) {
|
|
|
6033
6075
|
async function readLocalSchemaHash(schemaPath = DEFAULT_SCHEMA_PATH) {
|
|
6034
6076
|
try {
|
|
6035
6077
|
const schema = await loadSchema(schemaPath, DEFAULT_EXPORT);
|
|
6036
|
-
return (0,
|
|
6078
|
+
return (0, import_schema3.schemaHash)(schema);
|
|
6037
6079
|
} catch {
|
|
6038
6080
|
return null;
|
|
6039
6081
|
}
|
|
@@ -6104,7 +6146,7 @@ function blockers(input) {
|
|
|
6104
6146
|
}
|
|
6105
6147
|
return found;
|
|
6106
6148
|
}
|
|
6107
|
-
var import_wire5,
|
|
6149
|
+
var import_wire5, import_schema3, WRITE_READY_VERDICT;
|
|
6108
6150
|
var init_readiness = __esm({
|
|
6109
6151
|
"src/readiness.ts"() {
|
|
6110
6152
|
"use strict";
|
|
@@ -6113,7 +6155,7 @@ var init_readiness = __esm({
|
|
|
6113
6155
|
init_push();
|
|
6114
6156
|
init_dbProvider();
|
|
6115
6157
|
init_remoteValidation();
|
|
6116
|
-
|
|
6158
|
+
import_schema3 = require("@abloatai/transaction/schema");
|
|
6117
6159
|
WRITE_READY_VERDICT = "write infrastructure is ready. Your database constraints and row-level policies still apply.";
|
|
6118
6160
|
}
|
|
6119
6161
|
});
|
|
@@ -6141,7 +6183,17 @@ function connectApplyPlan(input) {
|
|
|
6141
6183
|
const schema = input.schema ?? "public";
|
|
6142
6184
|
const publication = input.publication;
|
|
6143
6185
|
const provider = input.provider ?? "generic";
|
|
6144
|
-
const
|
|
6186
|
+
const canGrantBypassRls = input.canGrantBypassRls !== false;
|
|
6187
|
+
const canGrantReplication = input.canGrantReplication !== false;
|
|
6188
|
+
const grantedReplicationRole = canGrantReplication ? null : replicationGrantRole(provider);
|
|
6189
|
+
const recipe = connectSetupSql({
|
|
6190
|
+
tables,
|
|
6191
|
+
role,
|
|
6192
|
+
writeRole,
|
|
6193
|
+
schema,
|
|
6194
|
+
publication,
|
|
6195
|
+
canGrantBypassRls
|
|
6196
|
+
});
|
|
6145
6197
|
const isWal = (s) => s.startsWith("ALTER SYSTEM SET wal_level");
|
|
6146
6198
|
const isPublication = (s) => s.startsWith("CREATE PUBLICATION");
|
|
6147
6199
|
const isRoleCreate = (s) => s.startsWith("CREATE ROLE ");
|
|
@@ -6189,19 +6241,46 @@ END $$;`
|
|
|
6189
6241
|
{
|
|
6190
6242
|
key: "replication-role",
|
|
6191
6243
|
title: "Create the read-only login Ablo reads with",
|
|
6192
|
-
detail: `${role} \u2014 it can follow your changes and snapshot the same published rows, including through RLS`,
|
|
6244
|
+
detail: canGrantBypassRls ? `${role} \u2014 it can follow your changes and snapshot the same published rows, including through RLS` : `${role} \u2014 it can follow your changes, and reads the published rows through a SELECT policy of its own, because this provider reserves BYPASSRLS`,
|
|
6193
6245
|
sql: [
|
|
6194
6246
|
idempotentRole(
|
|
6195
6247
|
role,
|
|
6196
|
-
|
|
6248
|
+
// NOINHERIT everywhere the capability is an attribute: the reader
|
|
6249
|
+
// should hold what it was given and nothing that arrives later.
|
|
6250
|
+
// Where the provider lends REPLICATION as a role instead, the
|
|
6251
|
+
// membership only confers it by inheriting — a NOINHERIT member holds
|
|
6252
|
+
// it in name, `pg_has_role(..., 'USAGE')` is false, and replication
|
|
6253
|
+
// fails while every "was it granted" check says yes. So the grant
|
|
6254
|
+
// path inherits, and its only membership is the one granted below.
|
|
6255
|
+
`NOSUPERUSER ${canGrantBypassRls ? "BYPASSRLS " : ""}NOCREATEDB NOCREATEROLE ${canGrantReplication ? "REPLICATION" : "NOREPLICATION"} ${grantedReplicationRole ? "INHERIT" : "NOINHERIT"}`,
|
|
6197
6256
|
input.credentials.replicationClause,
|
|
6198
6257
|
input.rotate === true
|
|
6199
6258
|
),
|
|
6200
6259
|
// Unlike a password, this is a required invariant rather than secret
|
|
6201
6260
|
// material owned by one plane. Re-assert it for an existing pre-snapshot
|
|
6202
6261
|
// role so `connect apply` repairs the exact upgrade gap that otherwise
|
|
6203
|
-
// certifies an RLS-filtered empty snapshot as complete.
|
|
6204
|
-
|
|
6262
|
+
// certifies an RLS-filtered empty snapshot as complete. Where the
|
|
6263
|
+
// attribute cannot be granted at all, the policies in the grants step
|
|
6264
|
+
// carry the same invariant.
|
|
6265
|
+
...canGrantBypassRls ? [`ALTER ROLE ${quoteIdent(role)} WITH BYPASSRLS;`] : [],
|
|
6266
|
+
// The provider keeps REPLICATION on an internal superuser and lends it
|
|
6267
|
+
// through a role. Without this the reader authenticates and then cannot
|
|
6268
|
+
// open a replication slot, which surfaces far from its cause.
|
|
6269
|
+
...grantedReplicationRole ? [
|
|
6270
|
+
// WITH INHERIT TRUE, because Postgres 16 records inheritance on
|
|
6271
|
+
// the MEMBERSHIP rather than only on the role. A member that does
|
|
6272
|
+
// not inherit holds the grant without holding what it carries:
|
|
6273
|
+
// `pg_has_role(..., 'MEMBER')` is true, `USAGE` is false, and
|
|
6274
|
+
// replication does not work while every "was it granted" check
|
|
6275
|
+
// says yes.
|
|
6276
|
+
//
|
|
6277
|
+
// Stated on the grant rather than left to the role's default so
|
|
6278
|
+
// it also repairs a reader created before this path existed.
|
|
6279
|
+
// `ALTER ROLE ... INHERIT` does not: it changes the default for
|
|
6280
|
+
// FUTURE memberships and leaves the recorded one untouched, which
|
|
6281
|
+
// is a fix that reports success and changes nothing.
|
|
6282
|
+
`GRANT ${quoteIdent(grantedReplicationRole)} TO ${quoteIdent(role)} WITH INHERIT TRUE;`
|
|
6283
|
+
] : []
|
|
6205
6284
|
]
|
|
6206
6285
|
},
|
|
6207
6286
|
{
|
|
@@ -6301,14 +6380,14 @@ function reapplyBlocker(input) {
|
|
|
6301
6380
|
}
|
|
6302
6381
|
async function adminCanCreateRoles(sql) {
|
|
6303
6382
|
const rows = await sql.unsafe(
|
|
6304
|
-
`SELECT rolname, rolsuper, rolcreaterole FROM pg_roles WHERE rolname = current_user`
|
|
6383
|
+
`SELECT rolname, rolsuper, rolcreaterole, rolbypassrls, rolreplication FROM pg_roles WHERE rolname = current_user`
|
|
6305
6384
|
);
|
|
6306
6385
|
return rows[0] ?? null;
|
|
6307
6386
|
}
|
|
6308
6387
|
async function schemaDeclaredTables() {
|
|
6309
6388
|
try {
|
|
6310
6389
|
const schema = await loadSchema(DEFAULT_SCHEMA_PATH, DEFAULT_EXPORT);
|
|
6311
|
-
const json = JSON.parse((0,
|
|
6390
|
+
const json = JSON.parse((0, import_schema4.serializeSchema)(schema));
|
|
6312
6391
|
const tables = Object.entries(json.models).map(([key, model]) => model.tableName ?? key);
|
|
6313
6392
|
return tables.length > 0 ? tables : null;
|
|
6314
6393
|
} catch {
|
|
@@ -6381,7 +6460,7 @@ function alreadyConnectedElsewhere(held) {
|
|
|
6381
6460
|
const where = held.project ? `project ${held.project}, branch ${held.branch}` : `branch ${held.branch}`;
|
|
6382
6461
|
return `This database schema is already connected to ${where}. A (database, schema) binding belongs to one plane at a time.`;
|
|
6383
6462
|
}
|
|
6384
|
-
var import_wire6,
|
|
6463
|
+
var import_wire6, import_schema4;
|
|
6385
6464
|
var init_connectPreflight = __esm({
|
|
6386
6465
|
"src/connectPreflight.ts"() {
|
|
6387
6466
|
"use strict";
|
|
@@ -6390,7 +6469,7 @@ var init_connectPreflight = __esm({
|
|
|
6390
6469
|
import_wire6 = require("@abloatai/transaction/wire");
|
|
6391
6470
|
init_controlPlane();
|
|
6392
6471
|
init_push();
|
|
6393
|
-
|
|
6472
|
+
import_schema4 = require("@abloatai/transaction/schema");
|
|
6394
6473
|
init_readiness();
|
|
6395
6474
|
}
|
|
6396
6475
|
});
|
|
@@ -6722,7 +6801,16 @@ ${ambient}` : ""}`,
|
|
|
6722
6801
|
walAlreadyLogical: walReady,
|
|
6723
6802
|
provider,
|
|
6724
6803
|
existingPublication,
|
|
6725
|
-
inheritGrants
|
|
6804
|
+
inheritGrants,
|
|
6805
|
+
// Read off the connected admin rather than guessed from the hostname. A
|
|
6806
|
+
// role can only hand out an attribute it holds, and on RDS and Aurora
|
|
6807
|
+
// BYPASSRLS is reserved to `rdsadmin`, so the recipe substitutes explicit
|
|
6808
|
+
// SELECT policies for the reader.
|
|
6809
|
+
canGrantBypassRls: capability?.rolbypassrls === true,
|
|
6810
|
+
// Same rule, second attribute: RDS and Aurora keep REPLICATION on
|
|
6811
|
+
// rdsadmin and lend it as `rds_replication`, so the recipe grants that
|
|
6812
|
+
// role rather than setting an attribute this admin cannot pass on.
|
|
6813
|
+
canGrantReplication: capability?.rolreplication === true
|
|
6726
6814
|
});
|
|
6727
6815
|
const steps = buildPlan("scram-verifier");
|
|
6728
6816
|
if (pubReconcile.removed.length > 0 || pubReconcile.recreated) {
|
|
@@ -6804,7 +6892,14 @@ ${ambient}` : ""}`,
|
|
|
6804
6892
|
}
|
|
6805
6893
|
const replicationProbe = await probeAsRole(
|
|
6806
6894
|
replicationUrl,
|
|
6807
|
-
(sql) => probeReadiness(sql, {
|
|
6895
|
+
(sql) => probeReadiness(sql, {
|
|
6896
|
+
coordinatedTables,
|
|
6897
|
+
schema: args.schema,
|
|
6898
|
+
publication,
|
|
6899
|
+
// The reader may hold REPLICATION through the provider's role rather than
|
|
6900
|
+
// the attribute, which is the only shape available on RDS and Aurora.
|
|
6901
|
+
replicationGrantRole: replicationGrantRole(provider)
|
|
6902
|
+
})
|
|
6808
6903
|
);
|
|
6809
6904
|
const writeProbe = await probeAsRole(
|
|
6810
6905
|
writeUrl,
|
|
@@ -7454,7 +7549,11 @@ ${ambient}` : ""}`,
|
|
|
7454
7549
|
`);
|
|
7455
7550
|
const replication = await probeAndReport(dbUrl, "replication", {
|
|
7456
7551
|
schema: args.schema,
|
|
7457
|
-
publication
|
|
7552
|
+
publication,
|
|
7553
|
+
// Derived from the host being dialled: where the provider lends REPLICATION
|
|
7554
|
+
// as a role rather than granting the attribute, membership is what the
|
|
7555
|
+
// reader actually holds.
|
|
7556
|
+
replicationGrantRole: replicationGrantRole(detectProvider(dbUrl))
|
|
7458
7557
|
});
|
|
7459
7558
|
console.log(`
|
|
7460
7559
|
${import_picocolors12.default.bold("Direct-write role")}
|
|
@@ -7747,6 +7846,7 @@ var init_connect = __esm({
|
|
|
7747
7846
|
init_cjs_shims();
|
|
7748
7847
|
import_errors11 = require("@abloatai/transaction/errors");
|
|
7749
7848
|
import_picocolors12 = __toESM(require_picocolors(), 1);
|
|
7849
|
+
init_dbProvider();
|
|
7750
7850
|
init_src();
|
|
7751
7851
|
import_footprint3 = require("@abloatai/transaction/footprint");
|
|
7752
7852
|
init_dbRole();
|
|
@@ -7993,7 +8093,7 @@ var require_util = __commonJS({
|
|
|
7993
8093
|
return path;
|
|
7994
8094
|
}
|
|
7995
8095
|
exports2.normalize = normalize;
|
|
7996
|
-
function
|
|
8096
|
+
function join9(aRoot, aPath) {
|
|
7997
8097
|
if (aRoot === "") {
|
|
7998
8098
|
aRoot = ".";
|
|
7999
8099
|
}
|
|
@@ -8025,7 +8125,7 @@ var require_util = __commonJS({
|
|
|
8025
8125
|
}
|
|
8026
8126
|
return joined;
|
|
8027
8127
|
}
|
|
8028
|
-
exports2.join =
|
|
8128
|
+
exports2.join = join9;
|
|
8029
8129
|
exports2.isAbsolute = function(aPath) {
|
|
8030
8130
|
return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
|
|
8031
8131
|
};
|
|
@@ -8198,7 +8298,7 @@ var require_util = __commonJS({
|
|
|
8198
8298
|
parsed.path = parsed.path.substring(0, index + 1);
|
|
8199
8299
|
}
|
|
8200
8300
|
}
|
|
8201
|
-
sourceURL =
|
|
8301
|
+
sourceURL = join9(urlGenerate(parsed), sourceURL);
|
|
8202
8302
|
}
|
|
8203
8303
|
return normalize(sourceURL);
|
|
8204
8304
|
}
|
|
@@ -28218,9 +28318,9 @@ ${lanes.join("\n")}
|
|
|
28218
28318
|
return getSpanOfTokenAtPosition(sourceFile, node.pos);
|
|
28219
28319
|
}
|
|
28220
28320
|
Debug.assert(!isJSDoc(errorNode));
|
|
28221
|
-
const
|
|
28222
|
-
const pos =
|
|
28223
|
-
if (
|
|
28321
|
+
const isMissing2 = nodeIsMissing(errorNode);
|
|
28322
|
+
const pos = isMissing2 || isJsxText(node) ? errorNode.pos : skipTrivia(sourceFile.text, errorNode.pos);
|
|
28323
|
+
if (isMissing2) {
|
|
28224
28324
|
Debug.assert(pos === errorNode.pos, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
|
|
28225
28325
|
Debug.assert(pos === errorNode.end, "This failure could trigger https://github.com/Microsoft/TypeScript/issues/20809");
|
|
28226
28326
|
} else {
|
|
@@ -132697,7 +132797,7 @@ ${lanes.join("\n")}
|
|
|
132697
132797
|
}
|
|
132698
132798
|
}
|
|
132699
132799
|
function createImportCallExpressionAMD(arg, containsLexicalThis) {
|
|
132700
|
-
const
|
|
132800
|
+
const resolve11 = factory2.createUniqueName("resolve");
|
|
132701
132801
|
const reject = factory2.createUniqueName("reject");
|
|
132702
132802
|
const parameters = [
|
|
132703
132803
|
factory2.createParameterDeclaration(
|
|
@@ -132706,7 +132806,7 @@ ${lanes.join("\n")}
|
|
|
132706
132806
|
/*dotDotDotToken*/
|
|
132707
132807
|
void 0,
|
|
132708
132808
|
/*name*/
|
|
132709
|
-
|
|
132809
|
+
resolve11
|
|
132710
132810
|
),
|
|
132711
132811
|
factory2.createParameterDeclaration(
|
|
132712
132812
|
/*modifiers*/
|
|
@@ -132723,7 +132823,7 @@ ${lanes.join("\n")}
|
|
|
132723
132823
|
factory2.createIdentifier("require"),
|
|
132724
132824
|
/*typeArguments*/
|
|
132725
132825
|
void 0,
|
|
132726
|
-
[factory2.createArrayLiteralExpression([arg || factory2.createOmittedExpression()]),
|
|
132826
|
+
[factory2.createArrayLiteralExpression([arg || factory2.createOmittedExpression()]), resolve11, reject]
|
|
132727
132827
|
)
|
|
132728
132828
|
)
|
|
132729
132829
|
]);
|
|
@@ -172646,9 +172746,9 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
172646
172746
|
const sourceFile = getValidSourceFile(fileName);
|
|
172647
172747
|
const span = createTextSpanFromBounds(start, end);
|
|
172648
172748
|
const formatContext = ts_formatting_exports.getFormatContext(formatOptions, host);
|
|
172649
|
-
return flatMap(deduplicate(errorCodes68, equateValues, compareValues), (
|
|
172749
|
+
return flatMap(deduplicate(errorCodes68, equateValues, compareValues), (errorCode2) => {
|
|
172650
172750
|
cancellationToken.throwIfCancellationRequested();
|
|
172651
|
-
return ts_codefix_exports.getFixes({ errorCode, sourceFile, span, program, host, cancellationToken, formatContext, preferences });
|
|
172751
|
+
return ts_codefix_exports.getFixes({ errorCode: errorCode2, sourceFile, span, program, host, cancellationToken, formatContext, preferences });
|
|
172652
172752
|
});
|
|
172653
172753
|
}
|
|
172654
172754
|
function getCombinedCodeFix(scope, fixId56, formatOptions, preferences = emptyOptions) {
|
|
@@ -174486,8 +174586,8 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
174486
174586
|
fixIds: [fixId2],
|
|
174487
174587
|
errorCodes: errorCodes2,
|
|
174488
174588
|
getCodeActions: function getCodeActionsToAddMissingAsync(context) {
|
|
174489
|
-
const { sourceFile, errorCode, cancellationToken, program, span } = context;
|
|
174490
|
-
const diagnostic = find(program.getTypeChecker().getDiagnostics(sourceFile, cancellationToken), getIsMatchingAsyncError(span,
|
|
174589
|
+
const { sourceFile, errorCode: errorCode2, cancellationToken, program, span } = context;
|
|
174590
|
+
const diagnostic = find(program.getTypeChecker().getDiagnostics(sourceFile, cancellationToken), getIsMatchingAsyncError(span, errorCode2));
|
|
174491
174591
|
const directSpan = diagnostic && diagnostic.relatedInformation && find(diagnostic.relatedInformation, (r2) => r2.code === Diagnostics.Did_you_mean_to_mark_this_function_as_async.code);
|
|
174492
174592
|
const decl = getFixableErrorSpanDeclaration(sourceFile, directSpan);
|
|
174493
174593
|
if (!decl) {
|
|
@@ -174549,8 +174649,8 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
174549
174649
|
});
|
|
174550
174650
|
return decl;
|
|
174551
174651
|
}
|
|
174552
|
-
function getIsMatchingAsyncError(span,
|
|
174553
|
-
return ({ start, length: length2, relatedInformation, code }) => isNumber(start) && isNumber(length2) && textSpansEqual({ start, length: length2 }, span) && code ===
|
|
174652
|
+
function getIsMatchingAsyncError(span, errorCode2) {
|
|
174653
|
+
return ({ start, length: length2, relatedInformation, code }) => isNumber(start) && isNumber(length2) && textSpansEqual({ start, length: length2 }, span) && code === errorCode2 && !!relatedInformation && some(relatedInformation, (related) => related.code === Diagnostics.Did_you_mean_to_mark_this_function_as_async.code);
|
|
174554
174654
|
}
|
|
174555
174655
|
var fixId3 = "addMissingAwait";
|
|
174556
174656
|
var propertyAccessCode = Diagnostics.Property_0_does_not_exist_on_type_1.code;
|
|
@@ -174581,16 +174681,16 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
174581
174681
|
fixIds: [fixId3],
|
|
174582
174682
|
errorCodes: errorCodes3,
|
|
174583
174683
|
getCodeActions: function getCodeActionsToAddMissingAwait(context) {
|
|
174584
|
-
const { sourceFile, errorCode, span, cancellationToken, program } = context;
|
|
174585
|
-
const expression = getAwaitErrorSpanExpression(sourceFile,
|
|
174684
|
+
const { sourceFile, errorCode: errorCode2, span, cancellationToken, program } = context;
|
|
174685
|
+
const expression = getAwaitErrorSpanExpression(sourceFile, errorCode2, span, cancellationToken, program);
|
|
174586
174686
|
if (!expression) {
|
|
174587
174687
|
return;
|
|
174588
174688
|
}
|
|
174589
174689
|
const checker = context.program.getTypeChecker();
|
|
174590
174690
|
const trackChanges = (cb) => ts_textChanges_exports.ChangeTracker.with(context, cb);
|
|
174591
174691
|
return compact([
|
|
174592
|
-
getDeclarationSiteFix(context, expression,
|
|
174593
|
-
getUseSiteFix(context, expression,
|
|
174692
|
+
getDeclarationSiteFix(context, expression, errorCode2, checker, trackChanges),
|
|
174693
|
+
getUseSiteFix(context, expression, errorCode2, checker, trackChanges)
|
|
174594
174694
|
]);
|
|
174595
174695
|
},
|
|
174596
174696
|
getAllCodeActions: (context) => {
|
|
@@ -174607,18 +174707,18 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
174607
174707
|
});
|
|
174608
174708
|
}
|
|
174609
174709
|
});
|
|
174610
|
-
function getAwaitErrorSpanExpression(sourceFile,
|
|
174710
|
+
function getAwaitErrorSpanExpression(sourceFile, errorCode2, span, cancellationToken, program) {
|
|
174611
174711
|
const expression = getFixableErrorSpanExpression(sourceFile, span);
|
|
174612
|
-
return expression && isMissingAwaitError(sourceFile,
|
|
174712
|
+
return expression && isMissingAwaitError(sourceFile, errorCode2, span, cancellationToken, program) && isInsideAwaitableBody(expression) ? expression : void 0;
|
|
174613
174713
|
}
|
|
174614
|
-
function getDeclarationSiteFix(context, expression,
|
|
174714
|
+
function getDeclarationSiteFix(context, expression, errorCode2, checker, trackChanges, fixedDeclarations) {
|
|
174615
174715
|
const { sourceFile, program, cancellationToken } = context;
|
|
174616
174716
|
const awaitableInitializers = findAwaitableInitializers(expression, sourceFile, cancellationToken, program, checker);
|
|
174617
174717
|
if (awaitableInitializers) {
|
|
174618
174718
|
const initializerChanges = trackChanges((t) => {
|
|
174619
|
-
forEach(awaitableInitializers.initializers, ({ expression: expression2 }) => makeChange3(t,
|
|
174719
|
+
forEach(awaitableInitializers.initializers, ({ expression: expression2 }) => makeChange3(t, errorCode2, sourceFile, checker, expression2, fixedDeclarations));
|
|
174620
174720
|
if (fixedDeclarations && awaitableInitializers.needsSecondPassForFixAll) {
|
|
174621
|
-
makeChange3(t,
|
|
174721
|
+
makeChange3(t, errorCode2, sourceFile, checker, expression, fixedDeclarations);
|
|
174622
174722
|
}
|
|
174623
174723
|
});
|
|
174624
174724
|
return createCodeFixActionWithoutFixAll(
|
|
@@ -174628,14 +174728,14 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
174628
174728
|
);
|
|
174629
174729
|
}
|
|
174630
174730
|
}
|
|
174631
|
-
function getUseSiteFix(context, expression,
|
|
174632
|
-
const changes = trackChanges((t) => makeChange3(t,
|
|
174731
|
+
function getUseSiteFix(context, expression, errorCode2, checker, trackChanges, fixedDeclarations) {
|
|
174732
|
+
const changes = trackChanges((t) => makeChange3(t, errorCode2, context.sourceFile, checker, expression, fixedDeclarations));
|
|
174633
174733
|
return createCodeFixAction(fixId3, changes, Diagnostics.Add_await, fixId3, Diagnostics.Fix_all_expressions_possibly_missing_await);
|
|
174634
174734
|
}
|
|
174635
|
-
function isMissingAwaitError(sourceFile,
|
|
174735
|
+
function isMissingAwaitError(sourceFile, errorCode2, span, cancellationToken, program) {
|
|
174636
174736
|
const checker = program.getTypeChecker();
|
|
174637
174737
|
const diagnostics = checker.getDiagnostics(sourceFile, cancellationToken);
|
|
174638
|
-
return some(diagnostics, ({ start, length: length2, relatedInformation, code }) => isNumber(start) && isNumber(length2) && textSpansEqual({ start, length: length2 }, span) && code ===
|
|
174738
|
+
return some(diagnostics, ({ start, length: length2, relatedInformation, code }) => isNumber(start) && isNumber(length2) && textSpansEqual({ start, length: length2 }, span) && code === errorCode2 && !!relatedInformation && some(relatedInformation, (related) => related.code === Diagnostics.Did_you_forget_to_use_await.code));
|
|
174639
174739
|
}
|
|
174640
174740
|
function findAwaitableInitializers(expression, sourceFile, cancellationToken, program, checker) {
|
|
174641
174741
|
const identifiers = getIdentifiersFromErrorSpanExpression(expression, checker);
|
|
@@ -174720,7 +174820,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
174720
174820
|
function isInsideAwaitableBody(node) {
|
|
174721
174821
|
return node.flags & 65536 || !!findAncestor(node, (ancestor) => ancestor.parent && isArrowFunction(ancestor.parent) && ancestor.parent.body === ancestor || isBlock(ancestor) && (ancestor.parent.kind === 262 || ancestor.parent.kind === 218 || ancestor.parent.kind === 219 || ancestor.parent.kind === 174));
|
|
174722
174822
|
}
|
|
174723
|
-
function makeChange3(changeTracker,
|
|
174823
|
+
function makeChange3(changeTracker, errorCode2, sourceFile, checker, insertionSite, fixedDeclarations) {
|
|
174724
174824
|
if (isForOfStatement(insertionSite.parent) && !insertionSite.parent.awaitModifier) {
|
|
174725
174825
|
const exprType = checker.getTypeAtLocation(insertionSite);
|
|
174726
174826
|
const asyncIter = checker.getAnyAsyncIterableType();
|
|
@@ -174745,7 +174845,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
174745
174845
|
const newNode = checker.getPromisedTypeOfPromise(type) ? factory.createAwaitExpression(side) : side;
|
|
174746
174846
|
changeTracker.replaceNode(sourceFile, side, newNode);
|
|
174747
174847
|
}
|
|
174748
|
-
} else if (
|
|
174848
|
+
} else if (errorCode2 === propertyAccessCode && isPropertyAccessExpression(insertionSite.parent)) {
|
|
174749
174849
|
if (fixedDeclarations && isIdentifier2(insertionSite.parent.expression)) {
|
|
174750
174850
|
const symbol = checker.getSymbolAtLocation(insertionSite.parent.expression);
|
|
174751
174851
|
if (symbol && fixedDeclarations.has(getSymbolId(symbol))) {
|
|
@@ -174758,7 +174858,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
174758
174858
|
factory.createParenthesizedExpression(factory.createAwaitExpression(insertionSite.parent.expression))
|
|
174759
174859
|
);
|
|
174760
174860
|
insertLeadingSemicolonIfNeeded(changeTracker, insertionSite.parent.expression, sourceFile);
|
|
174761
|
-
} else if (contains(callableConstructableErrorCodes,
|
|
174861
|
+
} else if (contains(callableConstructableErrorCodes, errorCode2) && isCallOrNewExpression(insertionSite.parent)) {
|
|
174762
174862
|
if (fixedDeclarations && isIdentifier2(insertionSite)) {
|
|
174763
174863
|
const symbol = checker.getSymbolAtLocation(insertionSite);
|
|
174764
174864
|
if (symbol && fixedDeclarations.has(getSymbolId(symbol))) {
|
|
@@ -177531,10 +177631,10 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
177531
177631
|
registerCodeFix({
|
|
177532
177632
|
errorCodes: errorCodes19,
|
|
177533
177633
|
getCodeActions(context) {
|
|
177534
|
-
const { errorCode, preferences, sourceFile, span, program } = context;
|
|
177634
|
+
const { errorCode: errorCode2, preferences, sourceFile, span, program } = context;
|
|
177535
177635
|
const info = getFixInfos(
|
|
177536
177636
|
context,
|
|
177537
|
-
|
|
177637
|
+
errorCode2,
|
|
177538
177638
|
span.start,
|
|
177539
177639
|
/*useAutoImportProvider*/
|
|
177540
177640
|
true
|
|
@@ -178472,14 +178572,14 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
178472
178572
|
return { kind: 3, moduleSpecifierKind: void 0, moduleSpecifier, importKind, addAsTypeOnly, useRequire };
|
|
178473
178573
|
}
|
|
178474
178574
|
}
|
|
178475
|
-
function getFixInfos(context,
|
|
178575
|
+
function getFixInfos(context, errorCode2, pos, useAutoImportProvider) {
|
|
178476
178576
|
const symbolToken = getTokenAtPosition(context.sourceFile, pos);
|
|
178477
178577
|
let info;
|
|
178478
|
-
if (
|
|
178578
|
+
if (errorCode2 === Diagnostics._0_refers_to_a_UMD_global_but_the_current_file_is_a_module_Consider_adding_an_import_instead.code) {
|
|
178479
178579
|
info = getFixesInfoForUMDImport(context, symbolToken);
|
|
178480
178580
|
} else if (!isIdentifier2(symbolToken)) {
|
|
178481
178581
|
return void 0;
|
|
178482
|
-
} else if (
|
|
178582
|
+
} else if (errorCode2 === Diagnostics._0_cannot_be_used_as_a_value_because_it_was_imported_using_import_type.code) {
|
|
178483
178583
|
const symbolName2 = single(getSymbolNamesToImport(context.sourceFile, context.program.getTypeChecker(), symbolToken, context.program.getCompilerOptions()));
|
|
178484
178584
|
const fix = getTypeOnlyPromotionFix(context.sourceFile, symbolToken, symbolName2, context.program);
|
|
178485
178585
|
return fix && [{ fix, symbolName: symbolName2, errorIdentifierText: symbolToken.text }];
|
|
@@ -179309,11 +179409,11 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
179309
179409
|
registerCodeFix({
|
|
179310
179410
|
errorCodes: errorCodes21,
|
|
179311
179411
|
getCodeActions: function getCodeActionsToFixOverrideModifierIssues(context) {
|
|
179312
|
-
const { errorCode, span } = context;
|
|
179313
|
-
const info = errorCodeFixIdMap[
|
|
179412
|
+
const { errorCode: errorCode2, span } = context;
|
|
179413
|
+
const info = errorCodeFixIdMap[errorCode2];
|
|
179314
179414
|
if (!info) return emptyArray;
|
|
179315
179415
|
const { descriptions, fixId: fixId56, fixAllDescriptions } = info;
|
|
179316
|
-
const changes = ts_textChanges_exports.ChangeTracker.with(context, (changes2) => dispatchChanges(changes2, context,
|
|
179416
|
+
const changes = ts_textChanges_exports.ChangeTracker.with(context, (changes2) => dispatchChanges(changes2, context, errorCode2, span.start));
|
|
179317
179417
|
return [
|
|
179318
179418
|
createCodeFixActionMaybeFixAll(fixName, changes, descriptions, fixId56, fixAllDescriptions)
|
|
179319
179419
|
];
|
|
@@ -179328,8 +179428,8 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
179328
179428
|
dispatchChanges(changes, context, code, start);
|
|
179329
179429
|
})
|
|
179330
179430
|
});
|
|
179331
|
-
function dispatchChanges(changeTracker, context,
|
|
179332
|
-
switch (
|
|
179431
|
+
function dispatchChanges(changeTracker, context, errorCode2, pos) {
|
|
179432
|
+
switch (errorCode2) {
|
|
179333
179433
|
case Diagnostics.This_member_must_have_an_override_modifier_because_it_overrides_a_member_in_the_base_class_0.code:
|
|
179334
179434
|
case Diagnostics.This_member_must_have_a_JSDoc_comment_with_an_override_tag_because_it_overrides_a_member_in_the_base_class_0.code:
|
|
179335
179435
|
case Diagnostics.This_member_must_have_an_override_modifier_because_it_overrides_an_abstract_method_that_is_declared_in_the_base_class_0.code:
|
|
@@ -179342,7 +179442,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
179342
179442
|
case Diagnostics.This_member_cannot_have_a_JSDoc_comment_with_an_override_tag_because_its_containing_class_0_does_not_extend_another_class.code:
|
|
179343
179443
|
return doRemoveOverrideModifierChange(changeTracker, context.sourceFile, pos);
|
|
179344
179444
|
default:
|
|
179345
|
-
Debug.fail("Unexpected error code: " +
|
|
179445
|
+
Debug.fail("Unexpected error code: " + errorCode2);
|
|
179346
179446
|
}
|
|
179347
179447
|
}
|
|
179348
179448
|
function doAddOverrideModifierChange(changeTracker, sourceFile, pos) {
|
|
@@ -179715,8 +179815,8 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
179715
179815
|
registerCodeFix({
|
|
179716
179816
|
errorCodes: errorCodes26,
|
|
179717
179817
|
getCodeActions(context) {
|
|
179718
|
-
const { sourceFile, errorCode } = context;
|
|
179719
|
-
const info = getInfo8(sourceFile, context.span.start, context,
|
|
179818
|
+
const { sourceFile, errorCode: errorCode2 } = context;
|
|
179819
|
+
const info = getInfo8(sourceFile, context.span.start, context, errorCode2);
|
|
179720
179820
|
if (!info) return void 0;
|
|
179721
179821
|
const { node, suggestedSymbol } = info;
|
|
179722
179822
|
const target = getEmitScriptTarget(context.host.getCompilationSettings());
|
|
@@ -179730,10 +179830,10 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
179730
179830
|
if (info) doChange18(changes, context.sourceFile, info.node, info.suggestedSymbol, target);
|
|
179731
179831
|
})
|
|
179732
179832
|
});
|
|
179733
|
-
function getInfo8(sourceFile, pos, context,
|
|
179833
|
+
function getInfo8(sourceFile, pos, context, errorCode2) {
|
|
179734
179834
|
const node = getTokenAtPosition(sourceFile, pos);
|
|
179735
179835
|
const parent2 = node.parent;
|
|
179736
|
-
if ((
|
|
179836
|
+
if ((errorCode2 === Diagnostics.No_overload_matches_this_call.code || errorCode2 === Diagnostics.Type_0_is_not_assignable_to_type_1.code) && !isJsxAttribute(parent2)) return void 0;
|
|
179737
179837
|
const checker = context.program.getTypeChecker();
|
|
179738
179838
|
let suggestedSymbol;
|
|
179739
179839
|
if (isPropertyAccessExpression(parent2) && parent2.name === node) {
|
|
@@ -179824,8 +179924,8 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
179824
179924
|
errorCodes: errorCodes27,
|
|
179825
179925
|
fixIds: [fixIdAddReturnStatement, fixRemoveBracesFromArrowFunctionBody, fixIdWrapTheBlockWithParen],
|
|
179826
179926
|
getCodeActions: function getCodeActionsToCorrectReturnValue(context) {
|
|
179827
|
-
const { program, sourceFile, span: { start }, errorCode } = context;
|
|
179828
|
-
const info = getInfo9(program.getTypeChecker(), sourceFile, start,
|
|
179927
|
+
const { program, sourceFile, span: { start }, errorCode: errorCode2 } = context;
|
|
179928
|
+
const info = getInfo9(program.getTypeChecker(), sourceFile, start, errorCode2);
|
|
179829
179929
|
if (!info) return void 0;
|
|
179830
179930
|
if (info.kind === 0) {
|
|
179831
179931
|
return append(
|
|
@@ -179960,11 +180060,11 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
179960
180060
|
}
|
|
179961
180061
|
return checker.isTypeAssignableTo(exprType, type);
|
|
179962
180062
|
}
|
|
179963
|
-
function getInfo9(checker, sourceFile, position,
|
|
180063
|
+
function getInfo9(checker, sourceFile, position, errorCode2) {
|
|
179964
180064
|
const node = getTokenAtPosition(sourceFile, position);
|
|
179965
180065
|
if (!node.parent) return void 0;
|
|
179966
180066
|
const declaration = findAncestor(node.parent, isFunctionLikeDeclaration);
|
|
179967
|
-
switch (
|
|
180067
|
+
switch (errorCode2) {
|
|
179968
180068
|
case Diagnostics.A_function_whose_declared_type_is_neither_undefined_void_nor_any_must_return_a_value.code:
|
|
179969
180069
|
if (!declaration || !declaration.body || !declaration.type || !rangeContainsRange(declaration.type, node)) return void 0;
|
|
179970
180070
|
return getFixInfo(
|
|
@@ -180159,11 +180259,11 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
180159
180259
|
}));
|
|
180160
180260
|
}
|
|
180161
180261
|
});
|
|
180162
|
-
function getInfo10(sourceFile, tokenPos,
|
|
180262
|
+
function getInfo10(sourceFile, tokenPos, errorCode2, checker, program) {
|
|
180163
180263
|
var _a, _b;
|
|
180164
180264
|
const token = getTokenAtPosition(sourceFile, tokenPos);
|
|
180165
180265
|
const parent2 = token.parent;
|
|
180166
|
-
if (
|
|
180266
|
+
if (errorCode2 === Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1.code) {
|
|
180167
180267
|
if (!(token.kind === 19 && isObjectLiteralExpression(parent2) && isCallExpression(parent2.parent))) return void 0;
|
|
180168
180268
|
const argIndex = findIndex(parent2.parent.arguments, (arg) => arg === parent2);
|
|
180169
180269
|
if (argIndex < 0) return void 0;
|
|
@@ -181020,10 +181120,10 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
181020
181120
|
registerCodeFix({
|
|
181021
181121
|
errorCodes: errorCodes31,
|
|
181022
181122
|
getCodeActions: function getCodeActionsToFixNotFoundModule(context) {
|
|
181023
|
-
const { host, sourceFile, span: { start }, errorCode } = context;
|
|
181024
|
-
const packageName =
|
|
181123
|
+
const { host, sourceFile, span: { start }, errorCode: errorCode2 } = context;
|
|
181124
|
+
const packageName = errorCode2 === errorCannotFindImplicitJsxImport ? getJSXImplicitImportBase(context.program.getCompilerOptions(), sourceFile) : tryGetImportedPackageName(sourceFile, start);
|
|
181025
181125
|
if (packageName === void 0) return void 0;
|
|
181026
|
-
const typesPackageName = getTypesPackageNameToInstall(packageName, host,
|
|
181126
|
+
const typesPackageName = getTypesPackageNameToInstall(packageName, host, errorCode2);
|
|
181027
181127
|
return typesPackageName === void 0 ? [] : [createCodeFixAction(
|
|
181028
181128
|
fixName2,
|
|
181029
181129
|
/*changes*/
|
|
@@ -181595,7 +181695,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
181595
181695
|
registerCodeFix({
|
|
181596
181696
|
errorCodes: errorCodes43,
|
|
181597
181697
|
getCodeActions(context) {
|
|
181598
|
-
const { errorCode, sourceFile, program, cancellationToken } = context;
|
|
181698
|
+
const { errorCode: errorCode2, sourceFile, program, cancellationToken } = context;
|
|
181599
181699
|
const checker = program.getTypeChecker();
|
|
181600
181700
|
const sourceFiles = program.getSourceFiles();
|
|
181601
181701
|
const token = getTokenAtPosition(sourceFile, context.span.start);
|
|
@@ -181671,7 +181771,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
181671
181771
|
result.push(createDeleteFix(deletion, [Diagnostics.Remove_unused_declaration_for_Colon_0, name.getText(sourceFile)]));
|
|
181672
181772
|
}
|
|
181673
181773
|
}
|
|
181674
|
-
const prefix = ts_textChanges_exports.ChangeTracker.with(context, (t) => tryPrefixDeclaration(t,
|
|
181774
|
+
const prefix = ts_textChanges_exports.ChangeTracker.with(context, (t) => tryPrefixDeclaration(t, errorCode2, sourceFile, token));
|
|
181675
181775
|
if (prefix.length) {
|
|
181676
181776
|
result.push(createCodeFixAction(fixName3, prefix, [Diagnostics.Prefix_0_with_an_underscore, token.getText(sourceFile)], fixIdPrefix, Diagnostics.Prefix_all_unused_declarations_with_where_possible));
|
|
181677
181777
|
}
|
|
@@ -181797,8 +181897,8 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
181797
181897
|
changes.delete(sourceFile, parent2);
|
|
181798
181898
|
}
|
|
181799
181899
|
}
|
|
181800
|
-
function tryPrefixDeclaration(changes,
|
|
181801
|
-
if (
|
|
181900
|
+
function tryPrefixDeclaration(changes, errorCode2, sourceFile, token) {
|
|
181901
|
+
if (errorCode2 === Diagnostics.Property_0_is_declared_but_its_value_is_never_read.code) return;
|
|
181802
181902
|
if (token.kind === 140) {
|
|
181803
181903
|
token = cast(token.parent, isInferTypeNode).typeParameter.name;
|
|
181804
181904
|
}
|
|
@@ -181938,14 +182038,14 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
181938
182038
|
fixIds: [fixId34],
|
|
181939
182039
|
getAllCodeActions: (context) => codeFixAll(context, errorCodes44, (changes, diag2) => doChange27(changes, diag2.file, diag2.start, diag2.length, diag2.code))
|
|
181940
182040
|
});
|
|
181941
|
-
function doChange27(changes, sourceFile, start, length2,
|
|
182041
|
+
function doChange27(changes, sourceFile, start, length2, errorCode2) {
|
|
181942
182042
|
const token = getTokenAtPosition(sourceFile, start);
|
|
181943
182043
|
const statement = findAncestor(token, isStatement);
|
|
181944
182044
|
if (statement.getStart(sourceFile) !== token.getStart(sourceFile)) {
|
|
181945
182045
|
const logData = JSON.stringify({
|
|
181946
182046
|
statementKind: Debug.formatSyntaxKind(statement.kind),
|
|
181947
182047
|
tokenKind: Debug.formatSyntaxKind(token.kind),
|
|
181948
|
-
errorCode,
|
|
182048
|
+
errorCode: errorCode2,
|
|
181949
182049
|
start,
|
|
181950
182050
|
length: length2
|
|
181951
182051
|
});
|
|
@@ -183268,7 +183368,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
183268
183368
|
registerCodeFix({
|
|
183269
183369
|
errorCodes: errorCodes51,
|
|
183270
183370
|
getCodeActions(context) {
|
|
183271
|
-
const { sourceFile, program, span: { start }, errorCode, cancellationToken, host, preferences } = context;
|
|
183371
|
+
const { sourceFile, program, span: { start }, errorCode: errorCode2, cancellationToken, host, preferences } = context;
|
|
183272
183372
|
const token = getTokenAtPosition(sourceFile, start);
|
|
183273
183373
|
let declaration;
|
|
183274
183374
|
const changes = ts_textChanges_exports.ChangeTracker.with(context, (changes2) => {
|
|
@@ -183276,7 +183376,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
183276
183376
|
changes2,
|
|
183277
183377
|
sourceFile,
|
|
183278
183378
|
token,
|
|
183279
|
-
|
|
183379
|
+
errorCode2,
|
|
183280
183380
|
program,
|
|
183281
183381
|
cancellationToken,
|
|
183282
183382
|
/*markSeen*/
|
|
@@ -183286,7 +183386,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
183286
183386
|
);
|
|
183287
183387
|
});
|
|
183288
183388
|
const name = declaration && getNameOfDeclaration(declaration);
|
|
183289
|
-
return !name || changes.length === 0 ? void 0 : [createCodeFixAction(fixId40, changes, [getDiagnostic(
|
|
183389
|
+
return !name || changes.length === 0 ? void 0 : [createCodeFixAction(fixId40, changes, [getDiagnostic(errorCode2, token), getTextOfNode(name)], fixId40, Diagnostics.Infer_all_types_from_usage)];
|
|
183290
183390
|
},
|
|
183291
183391
|
fixIds: [fixId40],
|
|
183292
183392
|
getAllCodeActions(context) {
|
|
@@ -183297,8 +183397,8 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
183297
183397
|
});
|
|
183298
183398
|
}
|
|
183299
183399
|
});
|
|
183300
|
-
function getDiagnostic(
|
|
183301
|
-
switch (
|
|
183400
|
+
function getDiagnostic(errorCode2, token) {
|
|
183401
|
+
switch (errorCode2) {
|
|
183302
183402
|
case Diagnostics.Parameter_0_implicitly_has_an_1_type.code:
|
|
183303
183403
|
case Diagnostics.Parameter_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage.code:
|
|
183304
183404
|
return isSetAccessorDeclaration(getContainingFunction(token)) ? Diagnostics.Infer_type_of_0_from_usage : Diagnostics.Infer_parameter_types_from_usage;
|
|
@@ -183312,8 +183412,8 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
183312
183412
|
return Diagnostics.Infer_type_of_0_from_usage;
|
|
183313
183413
|
}
|
|
183314
183414
|
}
|
|
183315
|
-
function mapSuggestionDiagnostic(
|
|
183316
|
-
switch (
|
|
183415
|
+
function mapSuggestionDiagnostic(errorCode2) {
|
|
183416
|
+
switch (errorCode2) {
|
|
183317
183417
|
case Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_but_a_better_type_may_be_inferred_from_usage.code:
|
|
183318
183418
|
return Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined.code;
|
|
183319
183419
|
case Diagnostics.Variable_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage.code:
|
|
@@ -183331,16 +183431,16 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
183331
183431
|
case Diagnostics.Member_0_implicitly_has_an_1_type_but_a_better_type_may_be_inferred_from_usage.code:
|
|
183332
183432
|
return Diagnostics.Member_0_implicitly_has_an_1_type.code;
|
|
183333
183433
|
}
|
|
183334
|
-
return
|
|
183434
|
+
return errorCode2;
|
|
183335
183435
|
}
|
|
183336
|
-
function doChange33(changes, sourceFile, token,
|
|
183436
|
+
function doChange33(changes, sourceFile, token, errorCode2, program, cancellationToken, markSeen, host, preferences) {
|
|
183337
183437
|
if (!isParameterPropertyModifier(token.kind) && token.kind !== 80 && token.kind !== 26 && token.kind !== 110) {
|
|
183338
183438
|
return void 0;
|
|
183339
183439
|
}
|
|
183340
183440
|
const { parent: parent2 } = token;
|
|
183341
183441
|
const importAdder = createImportAdder(sourceFile, program, preferences, host);
|
|
183342
|
-
|
|
183343
|
-
switch (
|
|
183442
|
+
errorCode2 = mapSuggestionDiagnostic(errorCode2);
|
|
183443
|
+
switch (errorCode2) {
|
|
183344
183444
|
// Variable and Property declarations
|
|
183345
183445
|
case Diagnostics.Member_0_implicitly_has_an_1_type.code:
|
|
183346
183446
|
case Diagnostics.Variable_0_implicitly_has_type_1_in_some_locations_where_its_type_cannot_be_determined.code:
|
|
@@ -183381,7 +183481,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
183381
183481
|
return void 0;
|
|
183382
183482
|
}
|
|
183383
183483
|
let declaration;
|
|
183384
|
-
switch (
|
|
183484
|
+
switch (errorCode2) {
|
|
183385
183485
|
// Parameter declarations
|
|
183386
183486
|
case Diagnostics.Parameter_0_implicitly_has_an_1_type.code:
|
|
183387
183487
|
if (isSetAccessorDeclaration(containingFunction)) {
|
|
@@ -183420,7 +183520,7 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
183420
183520
|
}
|
|
183421
183521
|
break;
|
|
183422
183522
|
default:
|
|
183423
|
-
return Debug.fail(String(
|
|
183523
|
+
return Debug.fail(String(errorCode2));
|
|
183424
183524
|
}
|
|
183425
183525
|
importAdder.writeFixes(changes);
|
|
183426
183526
|
return declaration;
|
|
@@ -219332,8 +219432,8 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
|
|
|
219332
219432
|
installPackage(options) {
|
|
219333
219433
|
this.packageInstallId++;
|
|
219334
219434
|
const request3 = { kind: "installPackage", ...options, id: this.packageInstallId };
|
|
219335
|
-
const promise = new Promise((
|
|
219336
|
-
(this.packageInstalledPromise ?? (this.packageInstalledPromise = /* @__PURE__ */ new Map())).set(this.packageInstallId, { resolve:
|
|
219435
|
+
const promise = new Promise((resolve11, reject) => {
|
|
219436
|
+
(this.packageInstalledPromise ?? (this.packageInstalledPromise = /* @__PURE__ */ new Map())).set(this.packageInstallId, { resolve: resolve11, reject });
|
|
219337
219437
|
});
|
|
219338
219438
|
this.installer.send(request3);
|
|
219339
219439
|
return promise;
|
|
@@ -221634,7 +221734,7 @@ var require_path_browserify = __commonJS({
|
|
|
221634
221734
|
}
|
|
221635
221735
|
var posix = {
|
|
221636
221736
|
// path.resolve([from ...], to)
|
|
221637
|
-
resolve: function
|
|
221737
|
+
resolve: function resolve11() {
|
|
221638
221738
|
var resolvedPath = "";
|
|
221639
221739
|
var resolvedAbsolute = false;
|
|
221640
221740
|
var cwd;
|
|
@@ -221681,7 +221781,7 @@ var require_path_browserify = __commonJS({
|
|
|
221681
221781
|
assertPath(path);
|
|
221682
221782
|
return path.length > 0 && path.charCodeAt(0) === 47;
|
|
221683
221783
|
},
|
|
221684
|
-
join: function
|
|
221784
|
+
join: function join9() {
|
|
221685
221785
|
if (arguments.length === 0)
|
|
221686
221786
|
return ".";
|
|
221687
221787
|
var joined;
|
|
@@ -226534,41 +226634,41 @@ var require_queue = __commonJS({
|
|
|
226534
226634
|
queue.drained = drained;
|
|
226535
226635
|
return queue;
|
|
226536
226636
|
function push2(value) {
|
|
226537
|
-
var p2 = new Promise(function(
|
|
226637
|
+
var p2 = new Promise(function(resolve11, reject) {
|
|
226538
226638
|
pushCb(value, function(err, result) {
|
|
226539
226639
|
if (err) {
|
|
226540
226640
|
reject(err);
|
|
226541
226641
|
return;
|
|
226542
226642
|
}
|
|
226543
|
-
|
|
226643
|
+
resolve11(result);
|
|
226544
226644
|
});
|
|
226545
226645
|
});
|
|
226546
226646
|
p2.catch(noop3);
|
|
226547
226647
|
return p2;
|
|
226548
226648
|
}
|
|
226549
226649
|
function unshift(value) {
|
|
226550
|
-
var p2 = new Promise(function(
|
|
226650
|
+
var p2 = new Promise(function(resolve11, reject) {
|
|
226551
226651
|
unshiftCb(value, function(err, result) {
|
|
226552
226652
|
if (err) {
|
|
226553
226653
|
reject(err);
|
|
226554
226654
|
return;
|
|
226555
226655
|
}
|
|
226556
|
-
|
|
226656
|
+
resolve11(result);
|
|
226557
226657
|
});
|
|
226558
226658
|
});
|
|
226559
226659
|
p2.catch(noop3);
|
|
226560
226660
|
return p2;
|
|
226561
226661
|
}
|
|
226562
226662
|
function drained() {
|
|
226563
|
-
var p2 = new Promise(function(
|
|
226663
|
+
var p2 = new Promise(function(resolve11) {
|
|
226564
226664
|
process.nextTick(function() {
|
|
226565
226665
|
if (queue.idle()) {
|
|
226566
|
-
|
|
226666
|
+
resolve11();
|
|
226567
226667
|
} else {
|
|
226568
226668
|
var previousDrain = queue.drain;
|
|
226569
226669
|
queue.drain = function() {
|
|
226570
226670
|
if (typeof previousDrain === "function") previousDrain();
|
|
226571
|
-
|
|
226671
|
+
resolve11();
|
|
226572
226672
|
queue.drain = previousDrain;
|
|
226573
226673
|
};
|
|
226574
226674
|
}
|
|
@@ -227065,9 +227165,9 @@ var require_stream3 = __commonJS({
|
|
|
227065
227165
|
});
|
|
227066
227166
|
}
|
|
227067
227167
|
_getStat(filepath) {
|
|
227068
|
-
return new Promise((
|
|
227168
|
+
return new Promise((resolve11, reject) => {
|
|
227069
227169
|
this._stat(filepath, this._fsStatSettings, (error, stats) => {
|
|
227070
|
-
return error === null ?
|
|
227170
|
+
return error === null ? resolve11(stats) : reject(error);
|
|
227071
227171
|
});
|
|
227072
227172
|
});
|
|
227073
227173
|
}
|
|
@@ -227092,10 +227192,10 @@ var require_async5 = __commonJS({
|
|
|
227092
227192
|
this._readerStream = new stream_1.default(this._settings);
|
|
227093
227193
|
}
|
|
227094
227194
|
dynamic(root, options) {
|
|
227095
|
-
return new Promise((
|
|
227195
|
+
return new Promise((resolve11, reject) => {
|
|
227096
227196
|
this._walkAsync(root, options, (error, entries) => {
|
|
227097
227197
|
if (error === null) {
|
|
227098
|
-
|
|
227198
|
+
resolve11(entries);
|
|
227099
227199
|
} else {
|
|
227100
227200
|
reject(error);
|
|
227101
227201
|
}
|
|
@@ -227105,10 +227205,10 @@ var require_async5 = __commonJS({
|
|
|
227105
227205
|
async static(patterns, options) {
|
|
227106
227206
|
const entries = [];
|
|
227107
227207
|
const stream = this._readerStream.static(patterns, options);
|
|
227108
|
-
return new Promise((
|
|
227208
|
+
return new Promise((resolve11, reject) => {
|
|
227109
227209
|
stream.once("error", reject);
|
|
227110
227210
|
stream.on("data", (entry) => entries.push(entry));
|
|
227111
|
-
stream.once("end", () =>
|
|
227211
|
+
stream.once("end", () => resolve11(entries));
|
|
227112
227212
|
});
|
|
227113
227213
|
}
|
|
227114
227214
|
};
|
|
@@ -260014,12 +260114,12 @@ type XMLHttpRequestResponseType = "" | "arraybuffer" | "blob" | "document" | "js
|
|
|
260014
260114
|
};
|
|
260015
260115
|
var NodeRuntimeFileSystem = class {
|
|
260016
260116
|
delete(path2) {
|
|
260017
|
-
return new Promise((
|
|
260117
|
+
return new Promise((resolve11, reject) => {
|
|
260018
260118
|
fs__namespace.rm(path2, { recursive: true }, (err) => {
|
|
260019
260119
|
if (err)
|
|
260020
260120
|
reject(err);
|
|
260021
260121
|
else
|
|
260022
|
-
|
|
260122
|
+
resolve11();
|
|
260023
260123
|
});
|
|
260024
260124
|
});
|
|
260025
260125
|
}
|
|
@@ -260038,12 +260138,12 @@ type XMLHttpRequestResponseType = "" | "arraybuffer" | "blob" | "document" | "js
|
|
|
260038
260138
|
}));
|
|
260039
260139
|
}
|
|
260040
260140
|
readFile(filePath, encoding = "utf-8") {
|
|
260041
|
-
return new Promise((
|
|
260141
|
+
return new Promise((resolve11, reject) => {
|
|
260042
260142
|
fs__namespace.readFile(filePath, encoding, (err, data) => {
|
|
260043
260143
|
if (err)
|
|
260044
260144
|
reject(err);
|
|
260045
260145
|
else
|
|
260046
|
-
|
|
260146
|
+
resolve11(data);
|
|
260047
260147
|
});
|
|
260048
260148
|
});
|
|
260049
260149
|
}
|
|
@@ -260051,12 +260151,12 @@ type XMLHttpRequestResponseType = "" | "arraybuffer" | "blob" | "document" | "js
|
|
|
260051
260151
|
return fs__namespace.readFileSync(filePath, encoding);
|
|
260052
260152
|
}
|
|
260053
260153
|
async writeFile(filePath, fileText) {
|
|
260054
|
-
await new Promise((
|
|
260154
|
+
await new Promise((resolve11, reject) => {
|
|
260055
260155
|
fs__namespace.writeFile(filePath, fileText, (err) => {
|
|
260056
260156
|
if (err)
|
|
260057
260157
|
reject(err);
|
|
260058
260158
|
else
|
|
260059
|
-
|
|
260159
|
+
resolve11();
|
|
260060
260160
|
});
|
|
260061
260161
|
});
|
|
260062
260162
|
}
|
|
@@ -260070,12 +260170,12 @@ type XMLHttpRequestResponseType = "" | "arraybuffer" | "blob" | "document" | "js
|
|
|
260070
260170
|
fs__namespace.mkdirSync(dirPath, { recursive: true });
|
|
260071
260171
|
}
|
|
260072
260172
|
move(srcPath, destPath) {
|
|
260073
|
-
return new Promise((
|
|
260173
|
+
return new Promise((resolve11, reject) => {
|
|
260074
260174
|
fs__namespace.rename(srcPath, destPath, (err) => {
|
|
260075
260175
|
if (err)
|
|
260076
260176
|
reject(err);
|
|
260077
260177
|
else
|
|
260078
|
-
|
|
260178
|
+
resolve11();
|
|
260079
260179
|
});
|
|
260080
260180
|
});
|
|
260081
260181
|
}
|
|
@@ -260083,12 +260183,12 @@ type XMLHttpRequestResponseType = "" | "arraybuffer" | "blob" | "document" | "js
|
|
|
260083
260183
|
fs__namespace.renameSync(srcPath, destPath);
|
|
260084
260184
|
}
|
|
260085
260185
|
copy(srcPath, destPath) {
|
|
260086
|
-
return new Promise((
|
|
260186
|
+
return new Promise((resolve11, reject) => {
|
|
260087
260187
|
fs__namespace.copyFile(srcPath, destPath, (err) => {
|
|
260088
260188
|
if (err)
|
|
260089
260189
|
reject(err);
|
|
260090
260190
|
else
|
|
260091
|
-
|
|
260191
|
+
resolve11();
|
|
260092
260192
|
});
|
|
260093
260193
|
});
|
|
260094
260194
|
}
|
|
@@ -260096,15 +260196,15 @@ type XMLHttpRequestResponseType = "" | "arraybuffer" | "blob" | "document" | "js
|
|
|
260096
260196
|
fs__namespace.copyFileSync(srcPath, destPath);
|
|
260097
260197
|
}
|
|
260098
260198
|
stat(path2) {
|
|
260099
|
-
return new Promise((
|
|
260199
|
+
return new Promise((resolve11, reject) => {
|
|
260100
260200
|
fs__namespace.stat(path2, (err, stat) => {
|
|
260101
260201
|
if (err) {
|
|
260102
260202
|
if (err.code === "ENOENT" || err.code === "ENOTDIR")
|
|
260103
|
-
|
|
260203
|
+
resolve11(void 0);
|
|
260104
260204
|
else
|
|
260105
260205
|
reject(err);
|
|
260106
260206
|
} else {
|
|
260107
|
-
|
|
260207
|
+
resolve11(stat);
|
|
260108
260208
|
}
|
|
260109
260209
|
});
|
|
260110
260210
|
});
|
|
@@ -283781,7 +283881,7 @@ Node text: ${this.#forgottenText}`;
|
|
|
283781
283881
|
|
|
283782
283882
|
// src/index.ts
|
|
283783
283883
|
init_cjs_shims();
|
|
283784
|
-
var
|
|
283884
|
+
var import_picocolors32 = __toESM(require_picocolors(), 1);
|
|
283785
283885
|
|
|
283786
283886
|
// src/migrate.ts
|
|
283787
283887
|
init_cjs_shims();
|
|
@@ -283791,7 +283891,7 @@ var import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
|
283791
283891
|
var import_fs5 = require("fs");
|
|
283792
283892
|
init_src();
|
|
283793
283893
|
init_dbRole();
|
|
283794
|
-
var
|
|
283894
|
+
var import_schema2 = require("@abloatai/transaction/schema");
|
|
283795
283895
|
var import_source = require("@abloatai/transaction/source");
|
|
283796
283896
|
init_push();
|
|
283797
283897
|
var MIGRATE_USAGE = ` ablo migrate \u2014 create the tables your schema needs in your own database (DATABASE_URL)
|
|
@@ -283838,8 +283938,8 @@ function parseMigrateArgs(argv) {
|
|
|
283838
283938
|
return { schemaPath, exportName, targetSchema, dryRun, outputFile };
|
|
283839
283939
|
}
|
|
283840
283940
|
function planFor(schema, targetSchema = "public") {
|
|
283841
|
-
const schemaJson = JSON.parse((0,
|
|
283842
|
-
const plan = (0,
|
|
283941
|
+
const schemaJson = JSON.parse((0, import_schema2.serializeSchema)(schema));
|
|
283942
|
+
const plan = (0, import_schema2.generateProvisionPlan)(schemaJson, targetSchema, {
|
|
283843
283943
|
foreignKeys: targetSchema === "public"
|
|
283844
283944
|
});
|
|
283845
283945
|
const adapterTables = (0, import_source.adapterTableMigrations)().map((m2) => m2.up);
|
|
@@ -283861,8 +283961,8 @@ async function applyStatements(dbUrl, targetSchema, statements, concurrent = [],
|
|
|
283861
283961
|
} });
|
|
283862
283962
|
const total = statements.length;
|
|
283863
283963
|
const startedAt = Date.now();
|
|
283864
|
-
const lockTimeout = (0,
|
|
283865
|
-
const maxLockAttempts = (0,
|
|
283964
|
+
const lockTimeout = (0, import_schema2.resolveDdlLockTimeout)();
|
|
283965
|
+
const maxLockAttempts = (0, import_schema2.resolveDdlMaxLockAttempts)();
|
|
283866
283966
|
if (!observer.quiet) log.info("applying migration plan", { targetSchema, statements: total });
|
|
283867
283967
|
try {
|
|
283868
283968
|
for (let attempt = 1; ; attempt++) {
|
|
@@ -283876,7 +283976,7 @@ async function applyStatements(dbUrl, targetSchema, statements, concurrent = [],
|
|
|
283876
283976
|
observer.onStatement?.(index + 1, total);
|
|
283877
283977
|
} catch (err) {
|
|
283878
283978
|
const pg = err ?? {};
|
|
283879
|
-
if (pg.code ===
|
|
283979
|
+
if (pg.code === import_schema2.PG_LOCK_NOT_AVAILABLE) throw err;
|
|
283880
283980
|
log.error("migration plan failed", {
|
|
283881
283981
|
code: "migration_failed",
|
|
283882
283982
|
durationMs: Date.now() - startedAt,
|
|
@@ -283894,10 +283994,10 @@ async function applyStatements(dbUrl, targetSchema, statements, concurrent = [],
|
|
|
283894
283994
|
break;
|
|
283895
283995
|
} catch (err) {
|
|
283896
283996
|
const pg = err ?? {};
|
|
283897
|
-
if (pg.code ===
|
|
283898
|
-
const backoffMs = (0,
|
|
283997
|
+
if (pg.code === import_schema2.PG_LOCK_NOT_AVAILABLE && attempt < maxLockAttempts) {
|
|
283998
|
+
const backoffMs = (0, import_schema2.ddlLockRetryBackoffMs)(attempt);
|
|
283899
283999
|
log.warn("schema change blocked by a lock; backing off and retrying", { targetSchema, attempt, backoffMs });
|
|
283900
|
-
await new Promise((
|
|
284000
|
+
await new Promise((resolve11) => setTimeout(resolve11, backoffMs));
|
|
283901
284001
|
continue;
|
|
283902
284002
|
}
|
|
283903
284003
|
throw err;
|
|
@@ -284239,11 +284339,11 @@ function parseFeedbackArgs(argv) {
|
|
|
284239
284339
|
const positional2 = [];
|
|
284240
284340
|
let detail;
|
|
284241
284341
|
let command;
|
|
284242
|
-
let
|
|
284342
|
+
let errorCode2;
|
|
284243
284343
|
let from;
|
|
284244
284344
|
let yes = false;
|
|
284245
284345
|
let json = false;
|
|
284246
|
-
const
|
|
284346
|
+
const flagValue2 = (flag2, value) => {
|
|
284247
284347
|
if (value === void 0 || value.startsWith("--")) {
|
|
284248
284348
|
throw new import_errors12.AbloValidationError(`\`${flag2}\` needs a value.`, {
|
|
284249
284349
|
code: "cli_invalid_arguments"
|
|
@@ -284255,16 +284355,16 @@ function parseFeedbackArgs(argv) {
|
|
|
284255
284355
|
const arg = argv[i];
|
|
284256
284356
|
switch (arg) {
|
|
284257
284357
|
case "--detail":
|
|
284258
|
-
detail =
|
|
284358
|
+
detail = flagValue2("--detail", argv[++i]);
|
|
284259
284359
|
break;
|
|
284260
284360
|
case "--command":
|
|
284261
|
-
command =
|
|
284361
|
+
command = flagValue2("--command", argv[++i]);
|
|
284262
284362
|
break;
|
|
284263
284363
|
case "--error-code":
|
|
284264
|
-
|
|
284364
|
+
errorCode2 = flagValue2("--error-code", argv[++i]);
|
|
284265
284365
|
break;
|
|
284266
284366
|
case "--from":
|
|
284267
|
-
from =
|
|
284367
|
+
from = flagValue2("--from", argv[++i]);
|
|
284268
284368
|
break;
|
|
284269
284369
|
case "--yes":
|
|
284270
284370
|
yes = true;
|
|
@@ -284299,7 +284399,7 @@ function parseFeedbackArgs(argv) {
|
|
|
284299
284399
|
summary,
|
|
284300
284400
|
...detail !== void 0 ? { detail } : {},
|
|
284301
284401
|
...command !== void 0 ? { command } : {},
|
|
284302
|
-
...
|
|
284402
|
+
...errorCode2 !== void 0 ? { errorCode: errorCode2 } : {},
|
|
284303
284403
|
...from !== void 0 ? { from } : {},
|
|
284304
284404
|
yes,
|
|
284305
284405
|
json
|
|
@@ -284420,8 +284520,8 @@ init_controlPlane();
|
|
|
284420
284520
|
init_config();
|
|
284421
284521
|
var BRANCH_USAGE = `Usage:
|
|
284422
284522
|
ablo branch list [--json]
|
|
284423
|
-
ablo branch create <slug> [--from <id|slug>] [--kind dev|preview|test|long_lived] [--credential]
|
|
284424
|
-
ablo branch ensure <slug> [--from <id|slug>] [--kind dev|preview|test|long_lived] [--credential]
|
|
284523
|
+
ablo branch create <slug> [--from <id|slug>] [--kind dev|preview|test|long_lived] [--hosted] [--credential]
|
|
284524
|
+
ablo branch ensure <slug> [--from <id|slug>] [--kind dev|preview|test|long_lived] [--hosted] [--credential]
|
|
284425
284525
|
ablo branch credential <id|slug> [--ttl-hours <1-168>] [--json]
|
|
284426
284526
|
ablo branch status <branch-id|slug> [--json]
|
|
284427
284527
|
ablo branch check <branch-id|slug> [--json]
|
|
@@ -284434,7 +284534,7 @@ function requireKey2(explicit) {
|
|
|
284434
284534
|
const key = explicit ?? resolveManagementKey();
|
|
284435
284535
|
if (!key) {
|
|
284436
284536
|
throw new Error(
|
|
284437
|
-
"No project management credential. Run `npx ablo login` or set
|
|
284537
|
+
"No project management credential. Run `npx ablo login` or set ABLO_API_KEY to an mk_ credential."
|
|
284438
284538
|
);
|
|
284439
284539
|
}
|
|
284440
284540
|
return key;
|
|
@@ -284574,7 +284674,8 @@ async function create(slug, argv, idempotent, context = {}) {
|
|
|
284574
284674
|
slug: parsedSlug.data,
|
|
284575
284675
|
...parentId ? { parent_branch_id: parentId } : {},
|
|
284576
284676
|
...valueAfter(argv, "--kind") ? { kind: valueAfter(argv, "--kind") } : {},
|
|
284577
|
-
...valueAfter(argv, "--expires-at") ? { expires_at: valueAfter(argv, "--expires-at") } : {}
|
|
284677
|
+
...valueAfter(argv, "--expires-at") ? { expires_at: valueAfter(argv, "--expires-at") } : {},
|
|
284678
|
+
...argv.includes("--hosted") ? { storage: "hosted" } : {}
|
|
284578
284679
|
}
|
|
284579
284680
|
}, context);
|
|
284580
284681
|
if (response.status !== 201) {
|
|
@@ -284672,29 +284773,118 @@ async function branches(argv) {
|
|
|
284672
284773
|
|
|
284673
284774
|
// src/branchDev.ts
|
|
284674
284775
|
init_cjs_shims();
|
|
284675
|
-
var
|
|
284776
|
+
var import_node_crypto6 = require("crypto");
|
|
284676
284777
|
var import_node_child_process = require("child_process");
|
|
284677
284778
|
var import_branches2 = require("@abloatai/transaction/branches");
|
|
284678
|
-
var
|
|
284779
|
+
var import_errors15 = require("@abloatai/transaction/errors");
|
|
284679
284780
|
init_config();
|
|
284680
284781
|
init_telemetry();
|
|
284681
284782
|
|
|
284682
284783
|
// src/dev.ts
|
|
284683
284784
|
init_cjs_shims();
|
|
284684
|
-
var
|
|
284785
|
+
var import_errors14 = require("@abloatai/transaction/errors");
|
|
284685
284786
|
var import_credentialPolicy2 = require("@abloatai/transaction/auth/credentialPolicy");
|
|
284686
284787
|
var import_picocolors16 = __toESM(require_picocolors(), 1);
|
|
284687
284788
|
init_dist2();
|
|
284688
284789
|
var import_fs7 = require("fs");
|
|
284689
284790
|
var import_path5 = require("path");
|
|
284690
|
-
var
|
|
284791
|
+
var import_schema5 = require("@abloatai/transaction/schema");
|
|
284691
284792
|
init_push();
|
|
284692
284793
|
init_controlPlane();
|
|
284794
|
+
var import_wire8 = require("@abloatai/transaction/wire");
|
|
284693
284795
|
init_config();
|
|
284694
284796
|
init_readiness();
|
|
284695
284797
|
init_theme();
|
|
284696
284798
|
init_dbRole();
|
|
284697
284799
|
var import_source3 = require("@abloatai/transaction/source");
|
|
284800
|
+
|
|
284801
|
+
// src/localConnectorLease.ts
|
|
284802
|
+
init_cjs_shims();
|
|
284803
|
+
var import_node_crypto5 = require("crypto");
|
|
284804
|
+
var import_node_fs3 = require("fs");
|
|
284805
|
+
var import_node_os2 = require("os");
|
|
284806
|
+
var import_node_path2 = require("path");
|
|
284807
|
+
var import_errors13 = require("@abloatai/transaction/errors");
|
|
284808
|
+
function acquireLocalConnectorLease(identity, options = {}) {
|
|
284809
|
+
const directory = options.directory ?? (0, import_node_path2.join)((0, import_node_os2.tmpdir)(), "ablo-source-connectors");
|
|
284810
|
+
const pid = options.pid ?? process.pid;
|
|
284811
|
+
const isProcessAlive = options.isProcessAlive ?? processIsAlive;
|
|
284812
|
+
const key = (0, import_node_crypto5.createHash)("sha256").update(`${(0, import_node_path2.resolve)(identity.cwd)}\0${identity.baseUrl}\0${identity.branch}`).digest("hex").slice(0, 24);
|
|
284813
|
+
const path = (0, import_node_path2.join)(directory, `${key}.lock`);
|
|
284814
|
+
const token = (0, import_node_crypto5.randomUUID)();
|
|
284815
|
+
const record = { pid, token };
|
|
284816
|
+
(0, import_node_fs3.mkdirSync)(directory, { recursive: true, mode: 448 });
|
|
284817
|
+
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
284818
|
+
try {
|
|
284819
|
+
const fd = (0, import_node_fs3.openSync)(path, "wx", 384);
|
|
284820
|
+
try {
|
|
284821
|
+
(0, import_node_fs3.writeFileSync)(fd, JSON.stringify(record));
|
|
284822
|
+
} finally {
|
|
284823
|
+
(0, import_node_fs3.closeSync)(fd);
|
|
284824
|
+
}
|
|
284825
|
+
let released = false;
|
|
284826
|
+
return {
|
|
284827
|
+
release() {
|
|
284828
|
+
if (released) return;
|
|
284829
|
+
released = true;
|
|
284830
|
+
try {
|
|
284831
|
+
const current = readLease(path);
|
|
284832
|
+
if (current?.token === token) (0, import_node_fs3.unlinkSync)(path);
|
|
284833
|
+
} catch {
|
|
284834
|
+
}
|
|
284835
|
+
}
|
|
284836
|
+
};
|
|
284837
|
+
} catch (error) {
|
|
284838
|
+
if (!isAlreadyExists(error)) throw error;
|
|
284839
|
+
const owner = readLease(path);
|
|
284840
|
+
if (owner && isProcessAlive(owner.pid)) {
|
|
284841
|
+
throw new import_errors13.AbloValidationError(
|
|
284842
|
+
`Another ablo dev --local process (PID ${owner.pid}) already owns this branch's local Data Source. Stop it before starting another connector.`,
|
|
284843
|
+
{ code: "cli_invalid_arguments" }
|
|
284844
|
+
);
|
|
284845
|
+
}
|
|
284846
|
+
try {
|
|
284847
|
+
(0, import_node_fs3.unlinkSync)(path);
|
|
284848
|
+
} catch (unlinkError) {
|
|
284849
|
+
if (!isMissing(unlinkError)) throw unlinkError;
|
|
284850
|
+
}
|
|
284851
|
+
}
|
|
284852
|
+
}
|
|
284853
|
+
throw new import_errors13.AbloValidationError(
|
|
284854
|
+
"Could not acquire this branch's local Data Source connector lease. Retry after the other connector exits.",
|
|
284855
|
+
{ code: "cli_invalid_arguments" }
|
|
284856
|
+
);
|
|
284857
|
+
}
|
|
284858
|
+
function readLease(path) {
|
|
284859
|
+
try {
|
|
284860
|
+
const parsed = JSON.parse((0, import_node_fs3.readFileSync)(path, "utf8"));
|
|
284861
|
+
return typeof parsed.pid === "number" && typeof parsed.token === "string" ? { pid: parsed.pid, token: parsed.token } : void 0;
|
|
284862
|
+
} catch {
|
|
284863
|
+
return void 0;
|
|
284864
|
+
}
|
|
284865
|
+
}
|
|
284866
|
+
function processIsAlive(pid) {
|
|
284867
|
+
try {
|
|
284868
|
+
process.kill(pid, 0);
|
|
284869
|
+
return true;
|
|
284870
|
+
} catch (error) {
|
|
284871
|
+
return !isNoSuchProcess(error);
|
|
284872
|
+
}
|
|
284873
|
+
}
|
|
284874
|
+
function errorCode(error) {
|
|
284875
|
+
return error && typeof error === "object" && "code" in error ? String(error.code) : void 0;
|
|
284876
|
+
}
|
|
284877
|
+
function isAlreadyExists(error) {
|
|
284878
|
+
return errorCode(error) === "EEXIST";
|
|
284879
|
+
}
|
|
284880
|
+
function isMissing(error) {
|
|
284881
|
+
return errorCode(error) === "ENOENT";
|
|
284882
|
+
}
|
|
284883
|
+
function isNoSuchProcess(error) {
|
|
284884
|
+
return errorCode(error) === "ESRCH";
|
|
284885
|
+
}
|
|
284886
|
+
|
|
284887
|
+
// src/dev.ts
|
|
284698
284888
|
function parseDevArgs(argv) {
|
|
284699
284889
|
let schemaPath = DEFAULT_SCHEMA_PATH;
|
|
284700
284890
|
let exportName = DEFAULT_EXPORT;
|
|
@@ -284727,7 +284917,7 @@ function parseDevArgs(argv) {
|
|
|
284727
284917
|
sourcePath = argv[++i] ?? sourcePath;
|
|
284728
284918
|
break;
|
|
284729
284919
|
default:
|
|
284730
|
-
throw new
|
|
284920
|
+
throw new import_errors14.AbloValidationError(`unknown flag: ${arg}`, { code: "cli_invalid_arguments" });
|
|
284731
284921
|
}
|
|
284732
284922
|
}
|
|
284733
284923
|
url = apiBaseUrl(url);
|
|
@@ -284745,7 +284935,7 @@ function parseDevArgs(argv) {
|
|
|
284745
284935
|
async function loadLocalSourceHandler(sourcePath) {
|
|
284746
284936
|
const abs = (0, import_path5.resolve)(process.cwd(), sourcePath);
|
|
284747
284937
|
if (!(0, import_fs7.existsSync)(abs)) {
|
|
284748
|
-
throw new
|
|
284938
|
+
throw new import_errors14.AbloValidationError(
|
|
284749
284939
|
`local Data Source not found at ${import_picocolors16.default.bold(sourcePath)}. Add the signed Data Source handler described by ${import_picocolors16.default.bold("npx ablo docs data-sources")}, or pass ${import_picocolors16.default.bold("--source <path>")}.`,
|
|
284750
284940
|
{ code: "cli_invalid_arguments" }
|
|
284751
284941
|
);
|
|
@@ -284756,7 +284946,7 @@ async function loadLocalSourceHandler(sourcePath) {
|
|
|
284756
284946
|
const nested = mod.default && typeof mod.default === "object" ? mod.default : void 0;
|
|
284757
284947
|
const handler = mod.POST ?? nested?.POST;
|
|
284758
284948
|
if (typeof handler !== "function") {
|
|
284759
|
-
throw new
|
|
284949
|
+
throw new import_errors14.AbloValidationError(
|
|
284760
284950
|
`${import_picocolors16.default.bold(sourcePath)} must export a ${import_picocolors16.default.bold("POST(request)")} Data Source handler.`,
|
|
284761
284951
|
{ code: "cli_invalid_arguments" }
|
|
284762
284952
|
);
|
|
@@ -284764,27 +284954,20 @@ async function loadLocalSourceHandler(sourcePath) {
|
|
|
284764
284954
|
return handler;
|
|
284765
284955
|
}
|
|
284766
284956
|
async function registerLocalSource(args) {
|
|
284767
|
-
|
|
284957
|
+
await requestControlPlane({
|
|
284958
|
+
path: "/v1/datasources",
|
|
284768
284959
|
method: "POST",
|
|
284769
|
-
|
|
284770
|
-
|
|
284771
|
-
|
|
284772
|
-
},
|
|
284773
|
-
body: JSON.stringify({
|
|
284960
|
+
...args.apiKey ? { apiKey: args.apiKey } : {},
|
|
284961
|
+
baseUrl: args.url,
|
|
284962
|
+
body: {
|
|
284774
284963
|
connection: "endpoint",
|
|
284775
284964
|
endpoint: "http://localhost/ablo-dev/reverse-channel",
|
|
284776
284965
|
signingKey: args.apiKey,
|
|
284777
284966
|
reverseChannel: true,
|
|
284778
284967
|
metadata: { managed_by: "ablo dev --local" }
|
|
284779
|
-
}
|
|
284968
|
+
},
|
|
284969
|
+
responseSchema: import_wire8.datasourceSummarySchema
|
|
284780
284970
|
});
|
|
284781
|
-
if (!response.ok) {
|
|
284782
|
-
const body = await response.text();
|
|
284783
|
-
throw new import_errors13.AbloValidationError(
|
|
284784
|
-
`Could not register the local Data Source (${response.status}): ${body}`,
|
|
284785
|
-
{ code: "cli_invalid_arguments" }
|
|
284786
|
-
);
|
|
284787
|
-
}
|
|
284788
284971
|
}
|
|
284789
284972
|
function classifyKey(apiKey) {
|
|
284790
284973
|
if (!apiKey) {
|
|
@@ -284941,7 +285124,7 @@ async function dev(argv, runtime = {}) {
|
|
|
284941
285124
|
else if (!args.apiKey) args.apiKey = resolveRuntimeApiKey("sandbox").key;
|
|
284942
285125
|
if (runtime.branch) args.planeLabel = runtime.branch.slug;
|
|
284943
285126
|
if (args.local && !args.watch) {
|
|
284944
|
-
throw new
|
|
285127
|
+
throw new import_errors14.AbloValidationError(
|
|
284945
285128
|
`${import_picocolors16.default.bold("--local")} opens a long-lived secure connector and cannot be combined with ${import_picocolors16.default.bold("--no-watch")}.`,
|
|
284946
285129
|
{ code: "cli_invalid_arguments" }
|
|
284947
285130
|
);
|
|
@@ -284963,6 +285146,7 @@ async function dev(argv, runtime = {}) {
|
|
|
284963
285146
|
);
|
|
284964
285147
|
}
|
|
284965
285148
|
let localAbort = null;
|
|
285149
|
+
let localLease = null;
|
|
284966
285150
|
if (args.local) {
|
|
284967
285151
|
process.env.ABLO_API_KEY = args.apiKey;
|
|
284968
285152
|
if (!process.env.DATABASE_URL) {
|
|
@@ -284970,7 +285154,18 @@ async function dev(argv, runtime = {}) {
|
|
|
284970
285154
|
if (databaseUrl) process.env.DATABASE_URL = databaseUrl.value;
|
|
284971
285155
|
}
|
|
284972
285156
|
const handler = await loadLocalSourceHandler(args.sourcePath);
|
|
284973
|
-
|
|
285157
|
+
localLease = acquireLocalConnectorLease({
|
|
285158
|
+
cwd: process.cwd(),
|
|
285159
|
+
baseUrl: args.url,
|
|
285160
|
+
branch: args.planeLabel
|
|
285161
|
+
});
|
|
285162
|
+
try {
|
|
285163
|
+
await registerLocalSource(args);
|
|
285164
|
+
} catch (error) {
|
|
285165
|
+
localLease.release();
|
|
285166
|
+
localLease = null;
|
|
285167
|
+
throw error;
|
|
285168
|
+
}
|
|
284974
285169
|
localAbort = new AbortController();
|
|
284975
285170
|
const connector = (0, import_source3.createSourceConnector)({
|
|
284976
285171
|
apiKey: args.apiKey,
|
|
@@ -284988,13 +285183,16 @@ async function dev(argv, runtime = {}) {
|
|
|
284988
285183
|
});
|
|
284989
285184
|
void connector.run(localAbort.signal).catch((error) => {
|
|
284990
285185
|
console.error(import_picocolors16.default.red(` local connector stopped: ${error instanceof Error ? error.message : String(error)}`));
|
|
285186
|
+
}).finally(() => {
|
|
285187
|
+
localLease?.release();
|
|
285188
|
+
localLease = null;
|
|
284991
285189
|
});
|
|
284992
285190
|
console.log(` ${import_picocolors16.default.dim("source")} ${args.sourcePath} ${import_picocolors16.default.dim("(outbound connector; no public URL)")}`);
|
|
284993
285191
|
}
|
|
284994
285192
|
const schema = await loadSchema(args.schemaPath, args.exportName);
|
|
284995
285193
|
const modelCount = Object.keys(schema.models).length;
|
|
284996
285194
|
console.log(
|
|
284997
|
-
` ${import_picocolors16.default.dim("schema")} ${import_picocolors16.default.bold(args.schemaPath)} ${import_picocolors16.default.dim(`(${modelCount} models, hash ${(0,
|
|
285195
|
+
` ${import_picocolors16.default.dim("schema")} ${import_picocolors16.default.bold(args.schemaPath)} ${import_picocolors16.default.dim(`(${modelCount} models, hash ${(0, import_schema5.schemaHash)(schema)})`)}`
|
|
284998
285196
|
);
|
|
284999
285197
|
if (!runtime.branch) {
|
|
285000
285198
|
console.log(` ${import_picocolors16.default.dim("key")} ${args.apiKey.slice(0, 12)}\u2026`);
|
|
@@ -285007,6 +285205,7 @@ async function dev(argv, runtime = {}) {
|
|
|
285007
285205
|
s.stop(first.message, first.ok ? 0 : 1);
|
|
285008
285206
|
if (!first.ok) {
|
|
285009
285207
|
localAbort?.abort();
|
|
285208
|
+
localLease?.release();
|
|
285010
285209
|
process.exit(1);
|
|
285011
285210
|
}
|
|
285012
285211
|
if (runtime.branch) {
|
|
@@ -285063,6 +285262,7 @@ async function dev(argv, runtime = {}) {
|
|
|
285063
285262
|
const stop = () => {
|
|
285064
285263
|
watcher.close();
|
|
285065
285264
|
localAbort?.abort();
|
|
285265
|
+
localLease?.release();
|
|
285066
285266
|
console.log(`
|
|
285067
285267
|
${import_picocolors16.default.dim("stopped.")}`);
|
|
285068
285268
|
process.exit(0);
|
|
@@ -285092,7 +285292,7 @@ function parseBranchDevArgs(argv) {
|
|
|
285092
285292
|
const arg = argv[index];
|
|
285093
285293
|
if (!arg) continue;
|
|
285094
285294
|
if (arg === "--no-branch") {
|
|
285095
|
-
throw new
|
|
285295
|
+
throw new import_errors15.AbloValidationError(
|
|
285096
285296
|
"--no-branch was removed: development is branch-isolated. Use --branch <slug> to select explicitly.",
|
|
285097
285297
|
{ code: "cli_invalid_arguments" }
|
|
285098
285298
|
);
|
|
@@ -285100,7 +285300,7 @@ function parseBranchDevArgs(argv) {
|
|
|
285100
285300
|
if (arg === "--branch") {
|
|
285101
285301
|
branchSlug = argv[++index];
|
|
285102
285302
|
if (!branchSlug) {
|
|
285103
|
-
throw new
|
|
285303
|
+
throw new import_errors15.AbloValidationError("--branch requires a slug", {
|
|
285104
285304
|
code: "cli_invalid_arguments"
|
|
285105
285305
|
});
|
|
285106
285306
|
}
|
|
@@ -285109,7 +285309,7 @@ function parseBranchDevArgs(argv) {
|
|
|
285109
285309
|
if (arg === "--branch-ttl-hours") {
|
|
285110
285310
|
const value = Number(argv[++index]);
|
|
285111
285311
|
if (!Number.isInteger(value) || value < 1 || value > 168) {
|
|
285112
|
-
throw new
|
|
285312
|
+
throw new import_errors15.AbloValidationError("--branch-ttl-hours must be between 1 and 168", {
|
|
285113
285313
|
code: "cli_invalid_arguments"
|
|
285114
285314
|
});
|
|
285115
285315
|
}
|
|
@@ -285127,12 +285327,12 @@ function parseBranchDevArgs(argv) {
|
|
|
285127
285327
|
function branchSlugFromRef(ref) {
|
|
285128
285328
|
const base = ref.normalize("NFKD").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
285129
285329
|
if (!base) {
|
|
285130
|
-
throw new
|
|
285330
|
+
throw new import_errors15.AbloValidationError(`cannot derive an Ablo branch slug from "${ref}"`, {
|
|
285131
285331
|
code: "cli_invalid_arguments"
|
|
285132
285332
|
});
|
|
285133
285333
|
}
|
|
285134
285334
|
const nonRoot = base === "production" ? "production-dev" : base;
|
|
285135
|
-
const shortened = nonRoot.length <= 40 ? nonRoot : `${nonRoot.slice(0, 31).replace(/-+$/g, "")}-${(0,
|
|
285335
|
+
const shortened = nonRoot.length <= 40 ? nonRoot : `${nonRoot.slice(0, 31).replace(/-+$/g, "")}-${(0, import_node_crypto6.createHash)("sha256").update(nonRoot).digest("hex").slice(0, 8)}`;
|
|
285136
285336
|
return import_branches2.branchSlugSchema.parse(shortened);
|
|
285137
285337
|
}
|
|
285138
285338
|
function gitBranch() {
|
|
@@ -285149,7 +285349,7 @@ function gitBranch() {
|
|
|
285149
285349
|
function discoverBranchRef(explicit, env = process.env, readGitBranch = gitBranch) {
|
|
285150
285350
|
const value = explicit ?? env.ABLO_BRANCH ?? env.GITHUB_HEAD_REF ?? env.GITHUB_REF_NAME ?? env.VERCEL_GIT_COMMIT_REF ?? env.CI_COMMIT_REF_NAME ?? readGitBranch();
|
|
285151
285351
|
if (!value) {
|
|
285152
|
-
throw new
|
|
285352
|
+
throw new import_errors15.AbloValidationError(
|
|
285153
285353
|
"Could not determine the Git branch. Pass --branch <slug> or set ABLO_BRANCH.",
|
|
285154
285354
|
{ code: "cli_invalid_arguments" }
|
|
285155
285355
|
);
|
|
@@ -285167,13 +285367,13 @@ async function runBranchDev(argv, dependencies = {}) {
|
|
|
285167
285367
|
const slug = branchSlugFromRef(ref);
|
|
285168
285368
|
const managementKey = dependencies.resolveManagementKey?.() ?? resolveManagementKey();
|
|
285169
285369
|
if (!managementKey) {
|
|
285170
|
-
throw new
|
|
285171
|
-
"Creating a development branch needs a project management credential. Run `npx ablo login` or set
|
|
285370
|
+
throw new import_errors15.AbloValidationError(
|
|
285371
|
+
"Creating a development branch needs a project management credential. Run `npx ablo login` or set ABLO_API_KEY to an mk_ credential.",
|
|
285172
285372
|
{ code: "cli_invalid_arguments" }
|
|
285173
285373
|
);
|
|
285174
285374
|
}
|
|
285175
285375
|
if (!managementKey.startsWith("mk_")) {
|
|
285176
|
-
throw new
|
|
285376
|
+
throw new import_errors15.AbloValidationError(
|
|
285177
285377
|
"Branch creation needs the active project management credential (mk_\u2026). Run `npx ablo login` to refresh it.",
|
|
285178
285378
|
{ code: "cli_invalid_arguments" }
|
|
285179
285379
|
);
|
|
@@ -285202,7 +285402,7 @@ async function runBranchDev(argv, dependencies = {}) {
|
|
|
285202
285402
|
// src/whoami.ts
|
|
285203
285403
|
init_cjs_shims();
|
|
285204
285404
|
var import_picocolors17 = __toESM(require_picocolors(), 1);
|
|
285205
|
-
var
|
|
285405
|
+
var import_errors16 = require("@abloatai/transaction/errors");
|
|
285206
285406
|
init_config();
|
|
285207
285407
|
init_controlPlane();
|
|
285208
285408
|
|
|
@@ -285277,7 +285477,7 @@ function parseWhoamiArgs(argv) {
|
|
|
285277
285477
|
case "--key": {
|
|
285278
285478
|
const value = argv[++i];
|
|
285279
285479
|
if (!value || value.startsWith("--")) {
|
|
285280
|
-
throw new
|
|
285480
|
+
throw new import_errors16.AbloValidationError("`--key` needs a credential value.", {
|
|
285281
285481
|
code: "cli_invalid_arguments"
|
|
285282
285482
|
});
|
|
285283
285483
|
}
|
|
@@ -285287,12 +285487,12 @@ function parseWhoamiArgs(argv) {
|
|
|
285287
285487
|
case "--key-env": {
|
|
285288
285488
|
const value = argv[++i];
|
|
285289
285489
|
if (!value || value.startsWith("--")) {
|
|
285290
|
-
throw new
|
|
285490
|
+
throw new import_errors16.AbloValidationError("`--key-env` needs an environment variable name.", {
|
|
285291
285491
|
code: "cli_invalid_arguments"
|
|
285292
285492
|
});
|
|
285293
285493
|
}
|
|
285294
285494
|
if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(value)) {
|
|
285295
|
-
throw new
|
|
285495
|
+
throw new import_errors16.AbloValidationError(
|
|
285296
285496
|
`\`${value}\` is not a valid environment variable name.`,
|
|
285297
285497
|
{ code: "cli_invalid_arguments" }
|
|
285298
285498
|
);
|
|
@@ -285301,13 +285501,13 @@ function parseWhoamiArgs(argv) {
|
|
|
285301
285501
|
break;
|
|
285302
285502
|
}
|
|
285303
285503
|
default:
|
|
285304
|
-
throw new
|
|
285504
|
+
throw new import_errors16.AbloValidationError(`unknown whoami flag: ${arg}`, {
|
|
285305
285505
|
code: "cli_invalid_arguments"
|
|
285306
285506
|
});
|
|
285307
285507
|
}
|
|
285308
285508
|
}
|
|
285309
285509
|
if (key && keyEnv) {
|
|
285310
|
-
throw new
|
|
285510
|
+
throw new import_errors16.AbloValidationError("Choose one credential source: `--key` or `--key-env`.", {
|
|
285311
285511
|
code: "cli_invalid_arguments"
|
|
285312
285512
|
});
|
|
285313
285513
|
}
|
|
@@ -285318,7 +285518,7 @@ function selectWhoamiCredential(args, cwd = process.cwd()) {
|
|
|
285318
285518
|
if (args.keyEnv) {
|
|
285319
285519
|
const found = readProjectEnvVariable(args.keyEnv, cwd);
|
|
285320
285520
|
if (!found) {
|
|
285321
|
-
throw new
|
|
285521
|
+
throw new import_errors16.AbloAuthenticationError(
|
|
285322
285522
|
`${args.keyEnv} is not set in the process environment, .env.local, or .env.`,
|
|
285323
285523
|
{ code: "cli_api_key_missing" }
|
|
285324
285524
|
);
|
|
@@ -285342,12 +285542,12 @@ function selectWhoamiCredential(args, cwd = process.cwd()) {
|
|
|
285342
285542
|
if (managementKey) {
|
|
285343
285543
|
return {
|
|
285344
285544
|
key: managementKey,
|
|
285345
|
-
source:
|
|
285346
|
-
targetSource:
|
|
285545
|
+
source: "stored login",
|
|
285546
|
+
targetSource: "stored"
|
|
285347
285547
|
};
|
|
285348
285548
|
}
|
|
285349
285549
|
const ambient = ambientEnvKeyNote();
|
|
285350
|
-
throw new
|
|
285550
|
+
throw new import_errors16.AbloAuthenticationError(
|
|
285351
285551
|
`No credential found. Run \`ablo login\`, set ABLO_API_KEY, or pass \`--key-env <NAME>\`.${ambient ? `
|
|
285352
285552
|
|
|
285353
285553
|
${ambient}` : ""}`,
|
|
@@ -285365,7 +285565,7 @@ async function whoami(argv) {
|
|
|
285365
285565
|
});
|
|
285366
285566
|
const confirmed = target.confirmed;
|
|
285367
285567
|
if (!confirmed) {
|
|
285368
|
-
throw new
|
|
285568
|
+
throw new import_errors16.AbloAuthenticationError(
|
|
285369
285569
|
"The server did not confirm an identity for this credential.",
|
|
285370
285570
|
{ code: "identity_resolve_failed" }
|
|
285371
285571
|
);
|
|
@@ -285423,15 +285623,15 @@ init_push();
|
|
|
285423
285623
|
// src/setup/run.ts
|
|
285424
285624
|
init_cjs_shims();
|
|
285425
285625
|
var import_picocolors19 = __toESM(require_picocolors(), 1);
|
|
285426
|
-
var
|
|
285626
|
+
var import_errors17 = require("@abloatai/transaction/errors");
|
|
285427
285627
|
init_theme();
|
|
285428
285628
|
|
|
285429
285629
|
// src/setup/discover.ts
|
|
285430
285630
|
init_cjs_shims();
|
|
285431
|
-
var
|
|
285432
|
-
var
|
|
285631
|
+
var import_node_fs4 = require("fs");
|
|
285632
|
+
var import_node_crypto7 = require("crypto");
|
|
285433
285633
|
var import_node_child_process2 = require("child_process");
|
|
285434
|
-
var
|
|
285634
|
+
var import_node_path3 = require("path");
|
|
285435
285635
|
init_controlPlane();
|
|
285436
285636
|
init_config();
|
|
285437
285637
|
|
|
@@ -286490,7 +286690,7 @@ function tryGit(cwd, args) {
|
|
|
286490
286690
|
}
|
|
286491
286691
|
}
|
|
286492
286692
|
function resolveRepositoryRoot(cwd = process.cwd()) {
|
|
286493
|
-
return (0,
|
|
286693
|
+
return (0, import_node_path3.resolve)(tryGit(cwd, ["rev-parse", "--show-toplevel"]) || cwd);
|
|
286494
286694
|
}
|
|
286495
286695
|
function walkFiles(root, maxDepth = 5) {
|
|
286496
286696
|
const files = [];
|
|
@@ -286499,13 +286699,13 @@ function walkFiles(root, maxDepth = 5) {
|
|
|
286499
286699
|
const current = stack.pop();
|
|
286500
286700
|
let entries;
|
|
286501
286701
|
try {
|
|
286502
|
-
entries = (0,
|
|
286702
|
+
entries = (0, import_node_fs4.readdirSync)(current.path, { withFileTypes: true });
|
|
286503
286703
|
} catch {
|
|
286504
286704
|
continue;
|
|
286505
286705
|
}
|
|
286506
286706
|
for (const entry of entries.slice(0, 1e4)) {
|
|
286507
286707
|
if (files.length >= MAX_DISCOVERY_FILES) break;
|
|
286508
|
-
const path = (0,
|
|
286708
|
+
const path = (0, import_node_path3.join)(current.path, entry.name);
|
|
286509
286709
|
if (entry.isDirectory()) {
|
|
286510
286710
|
if (current.depth < maxDepth && !IGNORED_DIRECTORIES.has(entry.name)) {
|
|
286511
286711
|
stack.push({ path, depth: current.depth + 1 });
|
|
@@ -286519,9 +286719,9 @@ function walkFiles(root, maxDepth = 5) {
|
|
|
286519
286719
|
}
|
|
286520
286720
|
function readManifest(path) {
|
|
286521
286721
|
try {
|
|
286522
|
-
const parsed = JSON.parse((0,
|
|
286722
|
+
const parsed = JSON.parse((0, import_node_fs4.readFileSync)(path, "utf8"));
|
|
286523
286723
|
return {
|
|
286524
|
-
root: (0,
|
|
286724
|
+
root: (0, import_node_path3.resolve)(path, ".."),
|
|
286525
286725
|
name: typeof parsed.name === "string" ? parsed.name : null,
|
|
286526
286726
|
dependencies: { ...parsed.dependencies, ...parsed.devDependencies },
|
|
286527
286727
|
scripts: { ...parsed.scripts }
|
|
@@ -286531,14 +286731,14 @@ function readManifest(path) {
|
|
|
286531
286731
|
}
|
|
286532
286732
|
}
|
|
286533
286733
|
function packageManifests(root, files) {
|
|
286534
|
-
return files.filter((path) => (0,
|
|
286734
|
+
return files.filter((path) => (0, import_node_path3.basename)(path) === "package.json").flatMap((path) => {
|
|
286535
286735
|
const manifest = readManifest(path);
|
|
286536
286736
|
return manifest ? [manifest] : [];
|
|
286537
286737
|
}).sort((a, b4) => a.root.localeCompare(b4.root));
|
|
286538
286738
|
}
|
|
286539
286739
|
function pathInside(root, target) {
|
|
286540
|
-
const fromRoot = (0,
|
|
286541
|
-
return fromRoot === "" || fromRoot !== ".." && !fromRoot.startsWith(`..${
|
|
286740
|
+
const fromRoot = (0, import_node_path3.relative)(root, target);
|
|
286741
|
+
return fromRoot === "" || fromRoot !== ".." && !fromRoot.startsWith(`..${import_node_path3.sep}`);
|
|
286542
286742
|
}
|
|
286543
286743
|
function packageOwnedFiles(manifest, manifests, files) {
|
|
286544
286744
|
const nestedPackageRoots = manifests.filter(({ root }) => root !== manifest.root && pathInside(manifest.root, root));
|
|
@@ -286596,8 +286796,8 @@ function detectedPersistence(manifest, files) {
|
|
|
286596
286796
|
if (!SOURCE_EXTENSIONS.has(sourceExtension(path))) continue;
|
|
286597
286797
|
let source;
|
|
286598
286798
|
try {
|
|
286599
|
-
if ((0,
|
|
286600
|
-
source = (0,
|
|
286799
|
+
if ((0, import_node_fs4.lstatSync)(path).size > MAX_SOURCE_BYTES) continue;
|
|
286800
|
+
source = (0, import_node_fs4.readFileSync)(path, "utf8");
|
|
286601
286801
|
} catch {
|
|
286602
286802
|
continue;
|
|
286603
286803
|
}
|
|
@@ -286625,17 +286825,17 @@ function coordinationAdoptionReason(disposition, persistence) {
|
|
|
286625
286825
|
}
|
|
286626
286826
|
}
|
|
286627
286827
|
function packageManager(root) {
|
|
286628
|
-
if ((0,
|
|
286629
|
-
if ((0,
|
|
286630
|
-
if ((0,
|
|
286828
|
+
if ((0, import_node_fs4.existsSync)((0, import_node_path3.join)(root, "pnpm-lock.yaml"))) return "pnpm";
|
|
286829
|
+
if ((0, import_node_fs4.existsSync)((0, import_node_path3.join)(root, "yarn.lock"))) return "yarn";
|
|
286830
|
+
if ((0, import_node_fs4.existsSync)((0, import_node_path3.join)(root, "bun.lockb")) || (0, import_node_fs4.existsSync)((0, import_node_path3.join)(root, "bun.lock"))) return "bun";
|
|
286631
286831
|
return "npm";
|
|
286632
286832
|
}
|
|
286633
286833
|
function environmentKeyNames(root) {
|
|
286634
286834
|
const names = [".env.local", ".env.development.local", ".env.development", ".env"];
|
|
286635
286835
|
return names.flatMap((name) => {
|
|
286636
|
-
const path = (0,
|
|
286637
|
-
if (!(0,
|
|
286638
|
-
const keys = (0,
|
|
286836
|
+
const path = (0, import_node_path3.join)(root, name);
|
|
286837
|
+
if (!(0, import_node_fs4.existsSync)(path)) return [];
|
|
286838
|
+
const keys = (0, import_node_fs4.readFileSync)(path, "utf8").split(/\r?\n/).flatMap((line) => {
|
|
286639
286839
|
const match = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=/.exec(line);
|
|
286640
286840
|
return match ? [match[1]] : [];
|
|
286641
286841
|
});
|
|
@@ -286650,8 +286850,8 @@ function abloSourceFiles(root, files) {
|
|
|
286650
286850
|
return files.flatMap((path) => {
|
|
286651
286851
|
if (!SOURCE_EXTENSIONS.has(sourceExtension(path))) return [];
|
|
286652
286852
|
try {
|
|
286653
|
-
if ((0,
|
|
286654
|
-
return (0,
|
|
286853
|
+
if ((0, import_node_fs4.lstatSync)(path).size > MAX_SOURCE_BYTES) return [];
|
|
286854
|
+
return (0, import_node_fs4.readFileSync)(path, "utf8").includes("@abloatai/") ? [(0, import_node_path3.relative)(root, path) || "."] : [];
|
|
286655
286855
|
} catch {
|
|
286656
286856
|
return [];
|
|
286657
286857
|
}
|
|
@@ -286678,12 +286878,12 @@ function discoverMutationSites(root, files) {
|
|
|
286678
286878
|
if (!SOURCE_EXTENSIONS.has(sourceExtension(path))) continue;
|
|
286679
286879
|
let source;
|
|
286680
286880
|
try {
|
|
286681
|
-
if ((0,
|
|
286682
|
-
source = (0,
|
|
286881
|
+
if ((0, import_node_fs4.lstatSync)(path).size > MAX_SOURCE_BYTES) continue;
|
|
286882
|
+
source = (0, import_node_fs4.readFileSync)(path, "utf8");
|
|
286683
286883
|
} catch {
|
|
286684
286884
|
continue;
|
|
286685
286885
|
}
|
|
286686
|
-
const locator = (0,
|
|
286886
|
+
const locator = (0, import_node_path3.relative)(root, path) || ".";
|
|
286687
286887
|
for (const match of source.matchAll(/\b(?:(?:[A-Za-z_$][\w$]*)\.query|query|q)\s*\(\s*(?:`|['"])\s*(INSERT\s+INTO|UPDATE|DELETE\s+FROM)\s+([A-Za-z_$][\w$.[\]"`]*|"[^"]+"|`[^`]+`)/gi)) {
|
|
286688
286888
|
const rawTable = match[2] ?? "";
|
|
286689
286889
|
const modelHint = rawTable.replace(/["`\[\]]/g, "").split(".").at(-1)?.toLowerCase() || null;
|
|
@@ -286715,13 +286915,13 @@ function discoverMutationSites(root, files) {
|
|
|
286715
286915
|
return sites.sort((a, b4) => a.path.localeCompare(b4.path) || a.line - b4.line);
|
|
286716
286916
|
}
|
|
286717
286917
|
function isProductionMutationFile(root, path) {
|
|
286718
|
-
const locator = (0,
|
|
286918
|
+
const locator = (0, import_node_path3.relative)(root, path).replaceAll("\\", "/");
|
|
286719
286919
|
return !/(?:^|\/)(?:test|tests|__tests__|scripts)(?:\/|$)/.test(locator) && !/\.(?:test|spec)\.[cm]?[jt]sx?$/.test(locator);
|
|
286720
286920
|
}
|
|
286721
286921
|
function digestFile(path) {
|
|
286722
|
-
if (!(0,
|
|
286922
|
+
if (!(0, import_node_fs4.existsSync)(path)) return null;
|
|
286723
286923
|
try {
|
|
286724
|
-
return (0,
|
|
286924
|
+
return (0, import_node_crypto7.createHash)("sha256").update((0, import_node_fs4.readFileSync)(path)).digest("hex");
|
|
286725
286925
|
} catch {
|
|
286726
286926
|
return null;
|
|
286727
286927
|
}
|
|
@@ -286752,7 +286952,7 @@ function localDiscoveryStep(state) {
|
|
|
286752
286952
|
const appFiles = selected ? packageOwnedFiles(selected, state.packageManifests, files) : files.filter((path) => pathInside(envRoot, path));
|
|
286753
286953
|
const persistence = selected ? detectedPersistence(selected, appFiles) : [];
|
|
286754
286954
|
const coordinationAdoption = coordinationAdoptionDisposition(persistence);
|
|
286755
|
-
const excludedNestedPackages = selected ? state.packageManifests.filter(({ root: packageRoot2 }) => packageRoot2 !== selected.root && pathInside(selected.root, packageRoot2)).map(({ root: packageRoot2, name }) => ({ root: (0,
|
|
286955
|
+
const excludedNestedPackages = selected ? state.packageManifests.filter(({ root: packageRoot2 }) => packageRoot2 !== selected.root && pathInside(selected.root, packageRoot2)).map(({ root: packageRoot2, name }) => ({ root: (0, import_node_path3.relative)(root, packageRoot2), name })) : [];
|
|
286756
286956
|
const mutationSites = discoverMutationSites(
|
|
286757
286957
|
envRoot,
|
|
286758
286958
|
appFiles.filter((path) => isProductionMutationFile(envRoot, path))
|
|
@@ -286765,17 +286965,17 @@ function localDiscoveryStep(state) {
|
|
|
286765
286965
|
if (!SOURCE_EXTENSIONS.has(sourceExtension(path))) continue;
|
|
286766
286966
|
let source;
|
|
286767
286967
|
try {
|
|
286768
|
-
if ((0,
|
|
286769
|
-
source = (0,
|
|
286968
|
+
if ((0, import_node_fs4.lstatSync)(path).size > MAX_SOURCE_BYTES) continue;
|
|
286969
|
+
source = (0, import_node_fs4.readFileSync)(path, "utf8");
|
|
286770
286970
|
} catch {
|
|
286771
286971
|
continue;
|
|
286772
286972
|
}
|
|
286773
286973
|
databaseColumns.push(...discoverDatabaseColumnsFromSqlSource({
|
|
286774
|
-
path: (0,
|
|
286974
|
+
path: (0, import_node_path3.relative)(envRoot, path),
|
|
286775
286975
|
source
|
|
286776
286976
|
}));
|
|
286777
286977
|
transactionalRequirements.push(...discoverTransactionalRequirementsFromSqlSource({
|
|
286778
|
-
path: (0,
|
|
286978
|
+
path: (0, import_node_path3.relative)(envRoot, path),
|
|
286779
286979
|
source
|
|
286780
286980
|
}));
|
|
286781
286981
|
}
|
|
@@ -286807,8 +287007,8 @@ function localDiscoveryStep(state) {
|
|
|
286807
287007
|
"src/app/providers.tsx",
|
|
286808
287008
|
"app/api/ablo-session/route.ts",
|
|
286809
287009
|
"src/app/api/ablo-session/route.ts"
|
|
286810
|
-
].filter((path) => (0,
|
|
286811
|
-
const localSchemaPath = [(0,
|
|
287010
|
+
].filter((path) => (0, import_node_fs4.existsSync)((0, import_node_path3.join)(envRoot, path)));
|
|
287011
|
+
const localSchemaPath = [(0, import_node_path3.join)(envRoot, "ablo", "schema.ts"), (0, import_node_path3.join)(envRoot, "src", "ablo", "schema.ts")].find((path) => (0, import_node_fs4.existsSync)(path)) ?? (0, import_node_path3.join)(envRoot, "ablo", "schema.ts");
|
|
286812
287012
|
state.localSchemaDigest = digestFile(localSchemaPath);
|
|
286813
287013
|
const facts = [
|
|
286814
287014
|
fact("repository.root", root, "git", tryGit(root, ["rev-parse", "--show-toplevel"]) ? "Resolved from Git." : "No Git root was available; using the requested directory.", root),
|
|
@@ -286817,9 +287017,9 @@ function localDiscoveryStep(state) {
|
|
|
286817
287017
|
fact("repository.dirtyPathCount", dirtyEntries.length, "git", "Count from porcelain status; path names are intentionally omitted.", root),
|
|
286818
287018
|
fact("repository.scanTruncated", files.length >= MAX_DISCOVERY_FILES, "filesystem", `Scanned at most ${MAX_DISCOVERY_FILES} files to depth 5.`, root),
|
|
286819
287019
|
fact("package.manager", packageManager(root), "filesystem", "Detected from the repository lockfile.", root),
|
|
286820
|
-
fact("application.candidates", candidates.map(({ manifest, frameworks, dataAccess, runtimeEntrypoint }) => ({ root: (0,
|
|
286821
|
-
fact("application.selectedRoot", state.applicationRoot ? (0,
|
|
286822
|
-
fact("application.packageName", state.packageName, "package_manifest", "Read from the selected package manifest.", state.applicationRoot ? (0,
|
|
287020
|
+
fact("application.candidates", candidates.map(({ manifest, frameworks, dataAccess, runtimeEntrypoint }) => ({ root: (0, import_node_path3.relative)(root, manifest.root) || ".", name: manifest.name, frameworks, dataAccess, runtimeEntrypoint })), "package_manifest", `${candidates.length} runnable application candidate(s) found.`, root),
|
|
287021
|
+
fact("application.selectedRoot", state.applicationRoot ? (0, import_node_path3.relative)(root, state.applicationRoot) || "." : null, "inference", state.applicationRoot ? "Exactly one usable application root was selected." : "Application selection is ambiguous.", root, state.applicationRoot ? "high" : "low"),
|
|
287022
|
+
fact("application.packageName", state.packageName, "package_manifest", "Read from the selected package manifest.", state.applicationRoot ? (0, import_node_path3.join)((0, import_node_path3.relative)(root, state.applicationRoot), "package.json") : "package.json"),
|
|
286823
287023
|
fact("application.frameworks", selected ? selectedFrameworks : candidates.flatMap(({ frameworks }) => frameworks), "package_manifest", "Detected only from declared package dependencies.", root),
|
|
286824
287024
|
fact("application.kinds", selectedApplicationKinds, "package_manifest", "Detected from runtime scripts and declared framework or database dependencies.", root),
|
|
286825
287025
|
fact("application.excludedNestedPackages", excludedNestedPackages, "package_manifest", "Independently manifested nested packages are excluded from the selected package's lexical mutation inventory; an agent may still follow application imports across that boundary.", root),
|
|
@@ -286840,16 +287040,16 @@ function localDiscoveryStep(state) {
|
|
|
286840
287040
|
fact("application.databaseSchemaEvidence", uniqueDatabaseColumns, "filesystem", "Conservative database-column evidence derived from application-owned CREATE TABLE statements. Database catalogs remain authoritative.", envRoot, "medium"),
|
|
286841
287041
|
fact("application.transactionalRequirements", uniqueRequirements, "filesystem", "Transaction shapes whose atomic predicates or exact RETURNING rows must be preserved.", envRoot, "medium"),
|
|
286842
287042
|
fact("application.compatibilityDisposition", state.compatibility, "inference", "Compared database and transaction evidence with the current canonical Ablo contracts.", envRoot, uniqueDatabaseColumns.length > 0 ? "medium" : "low"),
|
|
286843
|
-
fact("application.localSchemaDigest", state.localSchemaDigest, "filesystem", state.localSchemaDigest ? "SHA-256 of the local schema source file." : "No local ablo/schema.ts was found.", (0,
|
|
287043
|
+
fact("application.localSchemaDigest", state.localSchemaDigest, "filesystem", state.localSchemaDigest ? "SHA-256 of the local schema source file." : "No local ablo/schema.ts was found.", (0, import_node_path3.relative)(root, localSchemaPath))
|
|
286844
287044
|
];
|
|
286845
287045
|
const applicationChoices = candidates.map(({ manifest, frameworks, dataAccess }) => ({
|
|
286846
|
-
value: (0,
|
|
286847
|
-
label: manifest.name ?? ((0,
|
|
287046
|
+
value: (0, import_node_path3.relative)(root, manifest.root) || ".",
|
|
287047
|
+
label: manifest.name ?? ((0, import_node_path3.relative)(root, manifest.root) || "."),
|
|
286848
287048
|
consequence: `Setup will modify only this ${[...frameworks, ...dataAccess].join("/")} application.`
|
|
286849
287049
|
}));
|
|
286850
|
-
if (state.applicationRoot && !applicationChoices.some(({ value }) => value === ((0,
|
|
287050
|
+
if (state.applicationRoot && !applicationChoices.some(({ value }) => value === ((0, import_node_path3.relative)(root, state.applicationRoot) || "."))) {
|
|
286851
287051
|
applicationChoices.push({
|
|
286852
|
-
value: (0,
|
|
287052
|
+
value: (0, import_node_path3.relative)(root, state.applicationRoot) || ".",
|
|
286853
287053
|
label: state.packageName ?? ".",
|
|
286854
287054
|
consequence: "Setup will treat this package as the application root; framework support remains unconfirmed."
|
|
286855
287055
|
});
|
|
@@ -286860,7 +287060,7 @@ function localDiscoveryStep(state) {
|
|
|
286860
287060
|
question: "Which application should Ablo set up?",
|
|
286861
287061
|
status: state.applicationRoot ? "resolved" : "unresolved",
|
|
286862
287062
|
choices: applicationChoices,
|
|
286863
|
-
...state.applicationRoot ? { selected: (0,
|
|
287063
|
+
...state.applicationRoot ? { selected: (0, import_node_path3.relative)(root, state.applicationRoot) || "." } : {},
|
|
286864
287064
|
reason: state.applicationRoot ? dataApplications.length === 1 ? "Exactly one runnable package owns database access, so it is the coordination boundary." : runtimeOwners.length === 1 ? "Exactly one package owns a concrete runtime entrypoint, so it is the application boundary." : "The repository has one unambiguous application target." : "More than one or no runnable application was identified."
|
|
286865
287065
|
},
|
|
286866
287066
|
{
|
|
@@ -287210,7 +287410,7 @@ function parseSetupArgs(args) {
|
|
|
287210
287410
|
if (arg === "--root") {
|
|
287211
287411
|
const next = args[index + 1];
|
|
287212
287412
|
if (!next || next.startsWith("-")) {
|
|
287213
|
-
throw new
|
|
287413
|
+
throw new import_errors17.AbloValidationError("`--root` requires a directory.", {
|
|
287214
287414
|
code: "cli_invalid_arguments"
|
|
287215
287415
|
});
|
|
287216
287416
|
}
|
|
@@ -287219,7 +287419,7 @@ function parseSetupArgs(args) {
|
|
|
287219
287419
|
continue;
|
|
287220
287420
|
}
|
|
287221
287421
|
if (!allowedFlags.has(arg)) {
|
|
287222
|
-
throw new
|
|
287422
|
+
throw new import_errors17.AbloValidationError(`Unknown setup option: ${arg}`, {
|
|
287223
287423
|
code: "cli_invalid_arguments"
|
|
287224
287424
|
});
|
|
287225
287425
|
}
|
|
@@ -287305,7 +287505,7 @@ function renderHumanPlan(plan) {
|
|
|
287305
287505
|
async function runSetup(args) {
|
|
287306
287506
|
const options = parseSetupArgs(args);
|
|
287307
287507
|
if (options.json && !options.plan) {
|
|
287308
|
-
throw new
|
|
287508
|
+
throw new import_errors17.AbloValidationError(
|
|
287309
287509
|
"`--json` is a plan renderer. Use `ablo setup --plan --json`.",
|
|
287310
287510
|
{ code: "cli_invalid_arguments" }
|
|
287311
287511
|
);
|
|
@@ -287319,11 +287519,13 @@ async function runSetup(args) {
|
|
|
287319
287519
|
}
|
|
287320
287520
|
|
|
287321
287521
|
// src/commands.ts
|
|
287522
|
+
init_theme();
|
|
287322
287523
|
var CORE_GROUPS = ["Start", "Every day", "More"];
|
|
287323
287524
|
var FULL_GROUPS = [
|
|
287324
287525
|
"Set up",
|
|
287325
287526
|
"Your database",
|
|
287326
287527
|
"Your schema",
|
|
287528
|
+
"Your writes",
|
|
287327
287529
|
"Read the docs",
|
|
287328
287530
|
"See what's happening",
|
|
287329
287531
|
"Workspace"
|
|
@@ -287362,8 +287564,8 @@ var COMMANDS = [
|
|
|
287362
287564
|
full: {
|
|
287363
287565
|
group: "Set up",
|
|
287364
287566
|
rows: [
|
|
287365
|
-
{ run: "login", does: "Authorize in your browser \u2014 stores
|
|
287366
|
-
{ run: "login --project <slug>", does: "Same,
|
|
287567
|
+
{ run: "login", does: "Authorize in your browser, pick a project \u2014 stores its mk_ management credential" },
|
|
287568
|
+
{ run: "login --project <slug>", does: "Same, without the picker \u2014 the named project becomes active" }
|
|
287367
287569
|
]
|
|
287368
287570
|
}
|
|
287369
287571
|
},
|
|
@@ -287454,6 +287656,28 @@ var COMMANDS = [
|
|
|
287454
287656
|
]
|
|
287455
287657
|
}
|
|
287456
287658
|
},
|
|
287659
|
+
{
|
|
287660
|
+
name: "claims",
|
|
287661
|
+
core: {
|
|
287662
|
+
group: "Every day",
|
|
287663
|
+
does: "Say what you are editing, so another writer waits instead of clobbering it"
|
|
287664
|
+
},
|
|
287665
|
+
full: {
|
|
287666
|
+
group: "Your writes",
|
|
287667
|
+
rows: [
|
|
287668
|
+
{ run: "claims acquire <model> <id>", does: "Take the lease on one row" },
|
|
287669
|
+
{ run: "claims acquire <model> <id> -- <cmd>", does: "Hold it only while <cmd> runs, then release" },
|
|
287670
|
+
{ run: "claims acquire <model> <id> --queue", does: "Wait in line when it is held, instead of failing" },
|
|
287671
|
+
{ run: "claims acquire <model> <id> --ttl 5m", does: "Lease length: 30s, 5m, 2h (default 60s)" },
|
|
287672
|
+
{ run: "claims acquire <model> <id> --description <t>", does: "What you are doing, shown to whoever waits" },
|
|
287673
|
+
{ run: "claims release <model> <id>", does: "Give the lease back" },
|
|
287674
|
+
{ run: "claims heartbeat <model> <id>", does: "Extend a lease you already hold" },
|
|
287675
|
+
{ run: "claims list [<model> [<id>]]", does: "Who holds what, and who waits" },
|
|
287676
|
+
{ run: "claims list --actor <id>", does: "Narrow a listing to one holder" },
|
|
287677
|
+
{ run: "claims list --json", does: "Same, machine-readable" }
|
|
287678
|
+
]
|
|
287679
|
+
}
|
|
287680
|
+
},
|
|
287457
287681
|
{
|
|
287458
287682
|
name: "generate",
|
|
287459
287683
|
full: {
|
|
@@ -287599,7 +287823,9 @@ var REDIRECTS = /* @__PURE__ */ new Map([
|
|
|
287599
287823
|
["disconnect", "connect deregister"],
|
|
287600
287824
|
["deregister", "connect deregister"],
|
|
287601
287825
|
["register", "connect register"],
|
|
287602
|
-
["rotate", "connect rotate"]
|
|
287826
|
+
["rotate", "connect rotate"],
|
|
287827
|
+
["claim", "claims acquire"],
|
|
287828
|
+
["release", "claims release"]
|
|
287603
287829
|
]);
|
|
287604
287830
|
function editDistance(a, b4) {
|
|
287605
287831
|
const cols = b4.length + 1;
|
|
@@ -287636,7 +287862,22 @@ function suggestCommand(raw) {
|
|
|
287636
287862
|
return REDIRECTS.get(best.name) ?? best.name;
|
|
287637
287863
|
}
|
|
287638
287864
|
function usageFor(name) {
|
|
287639
|
-
|
|
287865
|
+
const command = BY_NAME.get(name);
|
|
287866
|
+
if (command === void 0) return void 0;
|
|
287867
|
+
if (command.usage !== void 0) return command.usage;
|
|
287868
|
+
const rows = command.full?.rows ?? [];
|
|
287869
|
+
const described = rows.filter((row) => row.does !== void 0);
|
|
287870
|
+
if (described.length === 0) return void 0;
|
|
287871
|
+
const width = Math.max(...described.map((row) => row.run.length)) + 2;
|
|
287872
|
+
const headline = command.core?.does;
|
|
287873
|
+
return [
|
|
287874
|
+
` ${brand(`ablo ${name}`)}${headline !== void 0 ? ` \u2014 ${headline}` : ""}`,
|
|
287875
|
+
"",
|
|
287876
|
+
...rows.map(
|
|
287877
|
+
(row) => row.does === void 0 ? ` ${row.run}` : ` ablo ${row.run.padEnd(width)}${row.does}`
|
|
287878
|
+
),
|
|
287879
|
+
""
|
|
287880
|
+
].join("\n");
|
|
287640
287881
|
}
|
|
287641
287882
|
function coreRows(group) {
|
|
287642
287883
|
return ALL.filter((c) => c.core?.group === group).map((c) => ({
|
|
@@ -287649,16 +287890,16 @@ function fullRows(group) {
|
|
|
287649
287890
|
}
|
|
287650
287891
|
|
|
287651
287892
|
// src/index.ts
|
|
287652
|
-
var
|
|
287893
|
+
var import_errors26 = require("@abloatai/transaction/errors");
|
|
287653
287894
|
init_push();
|
|
287654
287895
|
|
|
287655
287896
|
// src/generate.ts
|
|
287656
287897
|
init_cjs_shims();
|
|
287657
|
-
var
|
|
287898
|
+
var import_errors18 = require("@abloatai/transaction/errors");
|
|
287658
287899
|
var import_fs8 = require("fs");
|
|
287659
287900
|
var import_path6 = require("path");
|
|
287660
287901
|
var import_picocolors20 = __toESM(require_picocolors(), 1);
|
|
287661
|
-
var
|
|
287902
|
+
var import_schema6 = require("@abloatai/transaction/schema");
|
|
287662
287903
|
init_push();
|
|
287663
287904
|
var DEFAULT_SCHEMA_PATH4 = "ablo/schema.ts";
|
|
287664
287905
|
var DEFAULT_EXPORT3 = "schema";
|
|
@@ -287680,7 +287921,7 @@ function parseGenerateArgs(argv) {
|
|
|
287680
287921
|
out = argv[++i] ?? out;
|
|
287681
287922
|
break;
|
|
287682
287923
|
default:
|
|
287683
|
-
throw new
|
|
287924
|
+
throw new import_errors18.AbloValidationError(`unknown flag: ${arg}`, { code: "cli_invalid_arguments" });
|
|
287684
287925
|
}
|
|
287685
287926
|
}
|
|
287686
287927
|
return { schemaPath, exportName, out };
|
|
@@ -287696,8 +287937,8 @@ async function generate(argv) {
|
|
|
287696
287937
|
let source;
|
|
287697
287938
|
try {
|
|
287698
287939
|
const schema = await loadSchema(args.schemaPath, args.exportName);
|
|
287699
|
-
const schemaJson = JSON.parse((0,
|
|
287700
|
-
source = (0,
|
|
287940
|
+
const schemaJson = JSON.parse((0, import_schema6.serializeSchema)(schema));
|
|
287941
|
+
source = (0, import_schema6.generateTypes)(schemaJson);
|
|
287701
287942
|
} catch (err) {
|
|
287702
287943
|
console.error(import_picocolors20.default.red(` ${err instanceof Error ? err.message : String(err)}`));
|
|
287703
287944
|
process.exit(1);
|
|
@@ -287713,9 +287954,10 @@ init_cjs_shims();
|
|
|
287713
287954
|
var import_child_process2 = require("child_process");
|
|
287714
287955
|
var import_picocolors21 = __toESM(require_picocolors(), 1);
|
|
287715
287956
|
init_dist2();
|
|
287716
|
-
var
|
|
287717
|
-
var
|
|
287957
|
+
var import_errors19 = require("@abloatai/transaction/errors");
|
|
287958
|
+
var import_wire9 = require("@abloatai/transaction/wire");
|
|
287718
287959
|
init_config();
|
|
287960
|
+
init_projects();
|
|
287719
287961
|
init_theme();
|
|
287720
287962
|
var CLIENT_ID = "ablo-cli";
|
|
287721
287963
|
var stripSlash = (u2) => u2.replace(/\/+$/, "");
|
|
@@ -287741,11 +287983,52 @@ function parseSlugFlag(argv, flag2) {
|
|
|
287741
287983
|
const eq = argv.find((a) => a.startsWith(`${flag2}=`));
|
|
287742
287984
|
return eq ? eq.slice(flag2.length + 1) || void 0 : void 0;
|
|
287743
287985
|
}
|
|
287986
|
+
function projectSlugOrDefault(slug) {
|
|
287987
|
+
return slug === DEFAULT_PROFILE ? void 0 : slug;
|
|
287988
|
+
}
|
|
287989
|
+
async function listProjectsForSession(accessToken) {
|
|
287990
|
+
const res = await fetch(`${DASHBOARD_URL}/api/cli/projects`, {
|
|
287991
|
+
headers: { authorization: `Bearer ${accessToken}`, accept: "application/json" }
|
|
287992
|
+
}).catch(() => null);
|
|
287993
|
+
if (!res) return { ok: false, reason: `${DASHBOARD_URL} could not be reached` };
|
|
287994
|
+
return projectListResult(res.status, await res.json().catch(() => null));
|
|
287995
|
+
}
|
|
287996
|
+
async function pickProject(accessToken) {
|
|
287997
|
+
const active = getActiveProject();
|
|
287998
|
+
const s = Y2();
|
|
287999
|
+
s.start("Listing projects\u2026");
|
|
288000
|
+
const listed = await listProjectsForSession(accessToken);
|
|
288001
|
+
if (!listed.ok) {
|
|
288002
|
+
const fallback = projectSlugOrDefault(active?.slug);
|
|
288003
|
+
s.stop(
|
|
288004
|
+
`Couldn't list projects (${listed.reason}); continuing with ${fallback ? `project ${import_picocolors21.default.bold(fallback)}` : "the organization default"}.`
|
|
288005
|
+
);
|
|
288006
|
+
return fallback;
|
|
288007
|
+
}
|
|
288008
|
+
if (listed.projects.every((p2) => p2.default)) {
|
|
288009
|
+
s.stop("One project, the organization default.");
|
|
288010
|
+
return void 0;
|
|
288011
|
+
}
|
|
288012
|
+
s.stop(`${listed.projects.length} projects`);
|
|
288013
|
+
const current = active ? listed.projects.find((p2) => p2.id === active.id) : void 0;
|
|
288014
|
+
const choice = await ve({
|
|
288015
|
+
message: "Project",
|
|
288016
|
+
options: listed.projects.map((p2) => {
|
|
288017
|
+
const hint = projectDisplayName(p2) ?? (p2.default ? "organization default" : void 0);
|
|
288018
|
+
return { value: p2, label: p2.slug, ...hint ? { hint } : {} };
|
|
288019
|
+
}),
|
|
288020
|
+
...current ? { initialValue: current } : {}
|
|
288021
|
+
});
|
|
288022
|
+
if (pD(choice)) {
|
|
288023
|
+
xe("Cancelled.");
|
|
288024
|
+
process.exit(0);
|
|
288025
|
+
}
|
|
288026
|
+
return choice.default ? void 0 : choice.slug;
|
|
288027
|
+
}
|
|
287744
288028
|
async function deviceLogin(argv, deps = {}) {
|
|
287745
288029
|
const openUrl = deps.openUrl ?? openBrowser;
|
|
287746
288030
|
Ie(`${brand("ablo")} login`);
|
|
287747
|
-
const
|
|
287748
|
-
const targetProject = requested === DEFAULT_PROFILE ? void 0 : requested;
|
|
288031
|
+
const flagged = parseSlugFlag(argv, "--project");
|
|
287749
288032
|
const targetOrg = parseSlugFlag(argv, "--org");
|
|
287750
288033
|
const interactive = Boolean(process.stdout.isTTY && process.stdin.isTTY);
|
|
287751
288034
|
let account = "login";
|
|
@@ -287824,30 +288107,33 @@ ${import_picocolors21.default.dim(url)}`, "Approve in your browser");
|
|
|
287824
288107
|
s.stop("Timed out waiting for approval.");
|
|
287825
288108
|
process.exit(1);
|
|
287826
288109
|
}
|
|
287827
|
-
s.
|
|
288110
|
+
s.stop("Approved.");
|
|
288111
|
+
const targetProject = flagged !== void 0 ? projectSlugOrDefault(flagged) : interactive ? await pickProject(accessToken) : projectSlugOrDefault(getActiveProject()?.slug);
|
|
288112
|
+
const mint = Y2();
|
|
288113
|
+
mint.start(
|
|
287828
288114
|
targetProject ? `Provisioning project access for ${targetProject}\u2026` : "Provisioning project access\u2026"
|
|
287829
288115
|
);
|
|
287830
288116
|
const provRes = await fetch(`${DASHBOARD_URL}/api/cli/provision-key`, {
|
|
287831
288117
|
method: "POST",
|
|
287832
288118
|
headers: { authorization: `Bearer ${accessToken}`, "content-type": "application/json" },
|
|
287833
|
-
// Scope the minted keys to the chosen project
|
|
287834
|
-
//
|
|
287835
|
-
//
|
|
288119
|
+
// Scope the minted keys to the chosen project, with the device_code as a
|
|
288120
|
+
// legacy fallback for the /cli picker. Both harmless if absent →
|
|
288121
|
+
// org-default keys.
|
|
287836
288122
|
body: JSON.stringify({
|
|
287837
288123
|
device_code: code.device_code,
|
|
287838
288124
|
...targetProject ? { project_slug: targetProject } : {}
|
|
287839
288125
|
})
|
|
287840
288126
|
}).catch(() => null);
|
|
287841
288127
|
if (!provRes) {
|
|
287842
|
-
|
|
288128
|
+
mint.stop("Could not provision a key.");
|
|
287843
288129
|
M2.error(
|
|
287844
288130
|
`Could not reach ${DASHBOARD_URL} to finish the handoff. Check your connection and run \`ablo login\` again.`
|
|
287845
288131
|
);
|
|
287846
288132
|
process.exit(1);
|
|
287847
288133
|
}
|
|
287848
288134
|
if (!provRes.ok) {
|
|
287849
|
-
|
|
287850
|
-
const err = (0,
|
|
288135
|
+
mint.stop("Could not provision a key.");
|
|
288136
|
+
const err = (0, import_errors19.translateHttpError)(
|
|
287851
288137
|
provRes.status,
|
|
287852
288138
|
await provRes.json().catch(() => null),
|
|
287853
288139
|
provRes.headers.get("x-request-id") ?? void 0
|
|
@@ -287864,11 +288150,11 @@ ${import_picocolors21.default.dim(url)}`, "Approve in your browser");
|
|
|
287864
288150
|
}
|
|
287865
288151
|
process.exit(1);
|
|
287866
288152
|
}
|
|
287867
|
-
const parsedProv =
|
|
288153
|
+
const parsedProv = import_wire9.provisionKeyResponseSchema.safeParse(
|
|
287868
288154
|
await provRes.json().catch(() => null)
|
|
287869
288155
|
);
|
|
287870
288156
|
if (!parsedProv.success) {
|
|
287871
|
-
|
|
288157
|
+
mint.stop("Could not provision a key.");
|
|
287872
288158
|
M2.error("The key handoff returned something this version does not recognize.");
|
|
287873
288159
|
M2.error(`Try again, or upgrade with ${import_picocolors21.default.bold("npm i -g @abloatai/ablo")}.`);
|
|
287874
288160
|
process.exit(1);
|
|
@@ -287893,7 +288179,7 @@ ${import_picocolors21.default.dim(url)}`, "Approve in your browser");
|
|
|
287893
288179
|
},
|
|
287894
288180
|
{ mode: "sandbox", activeProject: prov.project ?? void 0 }
|
|
287895
288181
|
);
|
|
287896
|
-
|
|
288182
|
+
mint.stop(`Saved project credential to ${path}`);
|
|
287897
288183
|
const orgLabel = prov.organizationSlug ? ` to ${import_picocolors21.default.bold(prov.organizationSlug)}` : "";
|
|
287898
288184
|
const where = prov.project ? ` ${import_picocolors21.default.dim(`(project ${prov.project.slug})`)}` : "";
|
|
287899
288185
|
Se(
|
|
@@ -287910,10 +288196,10 @@ function logout() {
|
|
|
287910
288196
|
} else {
|
|
287911
288197
|
console.log(` ${import_picocolors21.default.dim("\u25CB")} Not logged in \u2014 nothing to remove.`);
|
|
287912
288198
|
}
|
|
287913
|
-
if (process.env.
|
|
288199
|
+
if (process.env.ABLO_API_KEY?.startsWith("mk_")) {
|
|
287914
288200
|
console.log(
|
|
287915
288201
|
import_picocolors21.default.dim(
|
|
287916
|
-
` Note: ${import_picocolors21.default.bold("
|
|
288202
|
+
` Note: ${import_picocolors21.default.bold("ABLO_API_KEY")} still contains an ${import_picocolors21.default.bold("mk_")} credential in this shell and takes precedence.`
|
|
287917
288203
|
)
|
|
287918
288204
|
);
|
|
287919
288205
|
}
|
|
@@ -287929,7 +288215,6 @@ init_config();
|
|
|
287929
288215
|
init_target();
|
|
287930
288216
|
init_theme();
|
|
287931
288217
|
init_controlPlane();
|
|
287932
|
-
var import_schema8 = require("@abloatai/transaction/coordination/schema");
|
|
287933
288218
|
init_readiness();
|
|
287934
288219
|
function expiryLabel(iso) {
|
|
287935
288220
|
const ms = Date.parse(iso) - Date.now();
|
|
@@ -287952,13 +288237,6 @@ async function ping2(apiUrl3) {
|
|
|
287952
288237
|
clearTimeout(t);
|
|
287953
288238
|
}
|
|
287954
288239
|
}
|
|
287955
|
-
function formatConflict(conflict) {
|
|
287956
|
-
if (!conflict) return "";
|
|
287957
|
-
const parts = import_schema8.participantKindSchema.options.flatMap(
|
|
287958
|
-
(k3) => conflict[k3] ? [`${k3}:${conflict[k3]}`] : []
|
|
287959
|
-
);
|
|
287960
|
-
return parts.length ? `{${parts.join(",")}}` : "";
|
|
287961
|
-
}
|
|
287962
288240
|
function printTargetLines(target, localProject, storedOrganizationId, storedOrganizationSlug) {
|
|
287963
288241
|
const confirmed = target?.confirmed ?? null;
|
|
287964
288242
|
const org = confirmed?.organizationId ?? storedOrganizationId;
|
|
@@ -288179,9 +288457,7 @@ async function status(args = []) {
|
|
|
288179
288457
|
);
|
|
288180
288458
|
for (const m2 of pushed.models) {
|
|
288181
288459
|
const tn = m2.typename === m2.key ? import_picocolors22.default.dim(`typename=${m2.typename}`) : import_picocolors22.default.yellow(`typename=${m2.typename}`);
|
|
288182
|
-
|
|
288183
|
-
const conflictStr2 = conflict ? ` ${import_picocolors22.default.dim(`conflict=${conflict}`)}` : "";
|
|
288184
|
-
console.log(` ${import_picocolors22.default.dim("\u2022")} ${m2.key.padEnd(14)} ${tn}${conflictStr2}`);
|
|
288460
|
+
console.log(` ${import_picocolors22.default.dim("\u2022")} ${m2.key.padEnd(14)} ${tn}`);
|
|
288185
288461
|
}
|
|
288186
288462
|
} else if (pushed && !pushed.active) {
|
|
288187
288463
|
console.log(
|
|
@@ -288223,8 +288499,8 @@ async function status(args = []) {
|
|
|
288223
288499
|
|
|
288224
288500
|
// src/logs.ts
|
|
288225
288501
|
init_cjs_shims();
|
|
288226
|
-
var
|
|
288227
|
-
var
|
|
288502
|
+
var import_errors20 = require("@abloatai/transaction/errors");
|
|
288503
|
+
var import_wire10 = require("@abloatai/transaction/wire");
|
|
288228
288504
|
var import_picocolors23 = __toESM(require_picocolors(), 1);
|
|
288229
288505
|
init_config();
|
|
288230
288506
|
init_theme();
|
|
@@ -288265,12 +288541,12 @@ function parseLogsArgs(argv) {
|
|
|
288265
288541
|
args.json = true;
|
|
288266
288542
|
break;
|
|
288267
288543
|
case "--mode":
|
|
288268
|
-
throw new
|
|
288544
|
+
throw new import_errors20.AbloValidationError(
|
|
288269
288545
|
"--mode was removed. Logs follow the branch bound to ABLO_API_KEY; select a different branch by supplying its key.",
|
|
288270
288546
|
{ code: "cli_invalid_arguments" }
|
|
288271
288547
|
);
|
|
288272
288548
|
default:
|
|
288273
|
-
throw new
|
|
288549
|
+
throw new import_errors20.AbloValidationError(`unknown flag: ${arg}`, { code: "cli_invalid_arguments" });
|
|
288274
288550
|
}
|
|
288275
288551
|
}
|
|
288276
288552
|
return args;
|
|
@@ -288335,7 +288611,7 @@ async function logs(argv) {
|
|
|
288335
288611
|
const json = await res.json();
|
|
288336
288612
|
return {
|
|
288337
288613
|
events: json.data ?? json.events ?? [],
|
|
288338
|
-
cursor: json.next_cursor ?? (json.cursor != null ? (0,
|
|
288614
|
+
cursor: json.next_cursor ?? (json.cursor != null ? (0, import_wire10.formatFeedCursor)({ log: json.cursor, claims: 0 }) : (0, import_wire10.formatFeedCursor)(import_wire10.FEED_CURSOR_START))
|
|
288339
288615
|
};
|
|
288340
288616
|
}
|
|
288341
288617
|
if (!args.json) {
|
|
@@ -288367,9 +288643,9 @@ async function logs(argv) {
|
|
|
288367
288643
|
});
|
|
288368
288644
|
if (!page) continue;
|
|
288369
288645
|
for (const e2 of page.events) render2(e2, args.json);
|
|
288370
|
-
const prev = (0,
|
|
288371
|
-
const next = (0,
|
|
288372
|
-
if (prev && next && (0,
|
|
288646
|
+
const prev = (0, import_wire10.parseFeedCursor)(cursor);
|
|
288647
|
+
const next = (0, import_wire10.parseFeedCursor)(page.cursor);
|
|
288648
|
+
if (prev && next && (0, import_wire10.feedCursorAdvanced)(prev, next)) cursor = page.cursor;
|
|
288373
288649
|
}
|
|
288374
288650
|
}
|
|
288375
288651
|
|
|
@@ -288549,10 +288825,10 @@ async function webhooks(argv) {
|
|
|
288549
288825
|
|
|
288550
288826
|
// src/check.ts
|
|
288551
288827
|
init_cjs_shims();
|
|
288552
|
-
var
|
|
288828
|
+
var import_errors21 = require("@abloatai/transaction/errors");
|
|
288553
288829
|
var import_picocolors25 = __toESM(require_picocolors(), 1);
|
|
288554
288830
|
init_src();
|
|
288555
|
-
var
|
|
288831
|
+
var import_schema8 = require("@abloatai/transaction/schema");
|
|
288556
288832
|
init_push();
|
|
288557
288833
|
|
|
288558
288834
|
// src/schemaIr.ts
|
|
@@ -288627,14 +288903,15 @@ function emitSchemaSource(schema, importPath) {
|
|
|
288627
288903
|
|
|
288628
288904
|
// src/schemaSource.ts
|
|
288629
288905
|
init_cjs_shims();
|
|
288906
|
+
var import_schema7 = require("@abloatai/transaction/schema");
|
|
288630
288907
|
var TENANCY_COLUMN = "organization_id";
|
|
288631
|
-
var BASE_FIELDS = /* @__PURE__ */ new Set([
|
|
288908
|
+
var BASE_FIELDS = /* @__PURE__ */ new Set([
|
|
288909
|
+
...import_schema7.BASE_FIELDS,
|
|
288910
|
+
"organizationId"
|
|
288911
|
+
]);
|
|
288632
288912
|
var BASE_COLUMNS = /* @__PURE__ */ new Set([
|
|
288633
|
-
|
|
288634
|
-
|
|
288635
|
-
"created_by",
|
|
288636
|
-
"created_at",
|
|
288637
|
-
"updated_at"
|
|
288913
|
+
...import_schema7.BASE_FIELDS.map(camelToSnake),
|
|
288914
|
+
TENANCY_COLUMN
|
|
288638
288915
|
]);
|
|
288639
288916
|
function fieldNameForColumn(column) {
|
|
288640
288917
|
const camel2 = column.replace(/_([a-z0-9])/g, (_3, c) => c.toUpperCase());
|
|
@@ -288697,7 +288974,7 @@ function parseCheckArgs(argv) {
|
|
|
288697
288974
|
appSchema = argv[++i] ?? appSchema;
|
|
288698
288975
|
break;
|
|
288699
288976
|
default:
|
|
288700
|
-
throw new
|
|
288977
|
+
throw new import_errors21.AbloValidationError(`unknown flag: ${arg}`, { code: "cli_invalid_arguments" });
|
|
288701
288978
|
}
|
|
288702
288979
|
}
|
|
288703
288980
|
return { schemaPath, exportName, appSchema };
|
|
@@ -288779,9 +289056,9 @@ async function check(argv) {
|
|
|
288779
289056
|
process.exit(1);
|
|
288780
289057
|
}
|
|
288781
289058
|
const schema = await loadSchema(args.schemaPath, args.exportName);
|
|
288782
|
-
const schemaJson = JSON.parse((0,
|
|
289059
|
+
const schemaJson = JSON.parse((0, import_schema8.serializeSchema)(schema));
|
|
288783
289060
|
const accessFindings = new Map(
|
|
288784
|
-
(0,
|
|
289061
|
+
(0, import_schema8.auditSchemaAccessPolicies)(schemaJson).map((finding) => [finding.model, finding])
|
|
288785
289062
|
);
|
|
288786
289063
|
console.log(`
|
|
288787
289064
|
${brand("ablo")} ${import_picocolors25.default.dim("check")} ${import_picocolors25.default.dim(`schema "${args.appSchema}"`)}
|
|
@@ -288830,7 +289107,7 @@ async function check(argv) {
|
|
|
288830
289107
|
);
|
|
288831
289108
|
}
|
|
288832
289109
|
if (!present.has("id")) problems.push('missing primary key "id"');
|
|
288833
|
-
const orgCol = (0,
|
|
289110
|
+
const orgCol = (0, import_schema8.tenancyColumn)((0, import_schema8.resolveTenancy)(model));
|
|
288834
289111
|
if (orgCol && !present.has(orgCol)) {
|
|
288835
289112
|
problems.push(
|
|
288836
289113
|
`missing "${orgCol}" \u2014 Ablo isolates tenants (RLS) and routes realtime by it, so a table without it has no safe boundary. Add the column, or use a Data Source endpoint.`
|
|
@@ -288880,9 +289157,244 @@ async function check(argv) {
|
|
|
288880
289157
|
process.exit(errors > 0 ? 1 : 0);
|
|
288881
289158
|
}
|
|
288882
289159
|
|
|
288883
|
-
// src/
|
|
289160
|
+
// src/claims.ts
|
|
288884
289161
|
init_cjs_shims();
|
|
289162
|
+
var import_node_child_process3 = require("child_process");
|
|
288885
289163
|
var import_picocolors26 = __toESM(require_picocolors(), 1);
|
|
289164
|
+
var import_contract = require("@abloatai/transaction/claims/contract");
|
|
289165
|
+
var import_routes = require("@abloatai/transaction/claims/routes");
|
|
289166
|
+
init_controlPlane();
|
|
289167
|
+
init_config();
|
|
289168
|
+
function requireRuntimeKey() {
|
|
289169
|
+
const { key } = resolveRuntimeApiKey();
|
|
289170
|
+
if (!key) {
|
|
289171
|
+
console.error(
|
|
289172
|
+
import_picocolors26.default.red(" No runtime credential.") + import_picocolors26.default.dim(
|
|
289173
|
+
` Run ${import_picocolors26.default.bold("npx ablo login")}, or set ${import_picocolors26.default.bold("ABLO_API_KEY")} to a runtime key.`
|
|
289174
|
+
)
|
|
289175
|
+
);
|
|
289176
|
+
process.exit(1);
|
|
289177
|
+
}
|
|
289178
|
+
return key;
|
|
289179
|
+
}
|
|
289180
|
+
var VALUE_FLAGS = /* @__PURE__ */ new Set(["--ttl", "--description", "--actor"]);
|
|
289181
|
+
function flagValue(argv, name) {
|
|
289182
|
+
const at = argv.indexOf(`--${name}`);
|
|
289183
|
+
return at === -1 ? void 0 : argv[at + 1];
|
|
289184
|
+
}
|
|
289185
|
+
function parseFlags(argv) {
|
|
289186
|
+
return {
|
|
289187
|
+
json: argv.includes("--json") || process.env.ABLO_JSON === "1",
|
|
289188
|
+
queue: argv.includes("--queue"),
|
|
289189
|
+
ttl: flagValue(argv, "ttl"),
|
|
289190
|
+
description: flagValue(argv, "description"),
|
|
289191
|
+
actor: flagValue(argv, "actor")
|
|
289192
|
+
};
|
|
289193
|
+
}
|
|
289194
|
+
function splitAtCommand(argv) {
|
|
289195
|
+
const at = argv.indexOf("--");
|
|
289196
|
+
return at === -1 ? { args: argv, command: [] } : { args: argv.slice(0, at), command: argv.slice(at + 1) };
|
|
289197
|
+
}
|
|
289198
|
+
function positionals(args) {
|
|
289199
|
+
const out = [];
|
|
289200
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
289201
|
+
const arg = args[i];
|
|
289202
|
+
if (arg === void 0) continue;
|
|
289203
|
+
if (VALUE_FLAGS.has(arg)) {
|
|
289204
|
+
i += 1;
|
|
289205
|
+
continue;
|
|
289206
|
+
}
|
|
289207
|
+
if (arg.startsWith("-")) continue;
|
|
289208
|
+
out.push(arg);
|
|
289209
|
+
}
|
|
289210
|
+
return out;
|
|
289211
|
+
}
|
|
289212
|
+
async function acquireClaim(model, id, flags, apiKey) {
|
|
289213
|
+
return requestControlPlane({
|
|
289214
|
+
path: (0, import_routes.claimOnModelPath)({ model, id }),
|
|
289215
|
+
method: "POST",
|
|
289216
|
+
apiKey,
|
|
289217
|
+
body: {
|
|
289218
|
+
...flags.ttl !== void 0 ? { ttl: flags.ttl } : {},
|
|
289219
|
+
...flags.description !== void 0 ? { description: flags.description } : {},
|
|
289220
|
+
...flags.queue ? { queue: true } : {}
|
|
289221
|
+
},
|
|
289222
|
+
responseSchema: import_contract.claimAcquireResponseSchema
|
|
289223
|
+
});
|
|
289224
|
+
}
|
|
289225
|
+
async function releaseClaim(model, id, apiKey) {
|
|
289226
|
+
const reply = await requestControlPlane({
|
|
289227
|
+
path: (0, import_routes.claimOnModelPath)({ model, id }),
|
|
289228
|
+
method: "DELETE",
|
|
289229
|
+
apiKey,
|
|
289230
|
+
responseSchema: import_contract.claimReleaseReplySchema
|
|
289231
|
+
});
|
|
289232
|
+
return reply.released;
|
|
289233
|
+
}
|
|
289234
|
+
async function beat(model, id, ttl, apiKey) {
|
|
289235
|
+
await requestControlPlane({
|
|
289236
|
+
path: (0, import_routes.claimHeartbeatOnModelPath)({ model, id }),
|
|
289237
|
+
method: "POST",
|
|
289238
|
+
apiKey,
|
|
289239
|
+
body: ttl !== void 0 ? { ttl } : {},
|
|
289240
|
+
responseSchema: import_contract.claimHeartbeatReplySchema
|
|
289241
|
+
});
|
|
289242
|
+
}
|
|
289243
|
+
async function pollClaim(claimId, apiKey) {
|
|
289244
|
+
return requestControlPlane({
|
|
289245
|
+
path: (0, import_routes.claimByIdPath)(claimId),
|
|
289246
|
+
apiKey,
|
|
289247
|
+
responseSchema: import_contract.claimStateSchema
|
|
289248
|
+
});
|
|
289249
|
+
}
|
|
289250
|
+
async function waitForGrant(claimId, ttl, apiKey) {
|
|
289251
|
+
const everyMs = Math.max(1e3, Math.floor((0, import_contract.claimTtlMs)(ttl) / 4));
|
|
289252
|
+
for (; ; ) {
|
|
289253
|
+
await new Promise((resolve11) => setTimeout(resolve11, everyMs));
|
|
289254
|
+
const state = await pollClaim(claimId, apiKey);
|
|
289255
|
+
if (state.status === "active") return;
|
|
289256
|
+
if (state.status !== "queued") {
|
|
289257
|
+
throw new Error(`the wait ended without the lease (${state.status})`);
|
|
289258
|
+
}
|
|
289259
|
+
}
|
|
289260
|
+
}
|
|
289261
|
+
function describeAcquired(model, id, granted) {
|
|
289262
|
+
if (granted.status === "queued") {
|
|
289263
|
+
const ahead = granted.position;
|
|
289264
|
+
return ` ${import_picocolors26.default.yellow("\xB7")} Waiting for ${import_picocolors26.default.bold(`${model} ${id}`)}. ` + import_picocolors26.default.dim(ahead === 0 ? "Next in line." : `${ahead} ahead of you.`);
|
|
289265
|
+
}
|
|
289266
|
+
return ` ${import_picocolors26.default.green("\u2713")} Holding ${import_picocolors26.default.bold(`${model} ${id}`)}.`;
|
|
289267
|
+
}
|
|
289268
|
+
async function holdWhile(model, id, flags, apiKey, command) {
|
|
289269
|
+
const granted = await acquireClaim(model, id, flags, apiKey);
|
|
289270
|
+
if (granted.status === "queued") {
|
|
289271
|
+
if (!flags.json) console.error(describeAcquired(model, id, granted));
|
|
289272
|
+
await waitForGrant(granted.id, flags.ttl, apiKey);
|
|
289273
|
+
}
|
|
289274
|
+
if (!flags.json) console.error(` ${import_picocolors26.default.green("\u2713")} Holding ${import_picocolors26.default.bold(`${model} ${id}`)}.`);
|
|
289275
|
+
const everyMs = Math.max(1e3, Math.floor((0, import_contract.claimTtlMs)(flags.ttl) / 3));
|
|
289276
|
+
const timer2 = setInterval(() => {
|
|
289277
|
+
void beat(model, id, flags.ttl, apiKey).catch(() => {
|
|
289278
|
+
});
|
|
289279
|
+
}, everyMs);
|
|
289280
|
+
let released = false;
|
|
289281
|
+
const giveBack = async () => {
|
|
289282
|
+
if (released) return;
|
|
289283
|
+
released = true;
|
|
289284
|
+
clearInterval(timer2);
|
|
289285
|
+
try {
|
|
289286
|
+
await releaseClaim(model, id, apiKey);
|
|
289287
|
+
} catch {
|
|
289288
|
+
}
|
|
289289
|
+
};
|
|
289290
|
+
const [head, ...rest] = command;
|
|
289291
|
+
if (head === void 0) {
|
|
289292
|
+
await giveBack();
|
|
289293
|
+
throw new Error("no command was given after `--`");
|
|
289294
|
+
}
|
|
289295
|
+
const code = await new Promise((resolve11) => {
|
|
289296
|
+
const child = (0, import_node_child_process3.spawn)(head, rest, { stdio: "inherit" });
|
|
289297
|
+
const forward = (signal) => {
|
|
289298
|
+
child.kill(signal);
|
|
289299
|
+
};
|
|
289300
|
+
process.on("SIGINT", forward);
|
|
289301
|
+
process.on("SIGTERM", forward);
|
|
289302
|
+
child.on("error", () => {
|
|
289303
|
+
process.off("SIGINT", forward);
|
|
289304
|
+
process.off("SIGTERM", forward);
|
|
289305
|
+
resolve11(127);
|
|
289306
|
+
});
|
|
289307
|
+
child.on("close", (status2) => {
|
|
289308
|
+
process.off("SIGINT", forward);
|
|
289309
|
+
process.off("SIGTERM", forward);
|
|
289310
|
+
resolve11(status2 ?? 1);
|
|
289311
|
+
});
|
|
289312
|
+
});
|
|
289313
|
+
await giveBack();
|
|
289314
|
+
if (!flags.json) console.error(` ${import_picocolors26.default.dim("\xB7")} ${import_picocolors26.default.dim(`Released ${model} ${id}.`)}`);
|
|
289315
|
+
return code;
|
|
289316
|
+
}
|
|
289317
|
+
function renderList(rows) {
|
|
289318
|
+
if (rows.length === 0) {
|
|
289319
|
+
console.log(` ${import_picocolors26.default.dim("Nothing is held right now.")}`);
|
|
289320
|
+
return;
|
|
289321
|
+
}
|
|
289322
|
+
const held = rows.filter((row) => row.status !== "queued").length;
|
|
289323
|
+
const waiting = rows.length - held;
|
|
289324
|
+
console.log();
|
|
289325
|
+
for (const row of rows) {
|
|
289326
|
+
const where = `${row.target.model} ${row.target.id}`;
|
|
289327
|
+
const state = row.status === "queued" ? import_picocolors26.default.yellow(row.position === void 0 ? "waiting" : `waiting (${row.position} ahead)`) : import_picocolors26.default.green("held");
|
|
289328
|
+
console.log(
|
|
289329
|
+
` ${import_picocolors26.default.bold(where.padEnd(28))} ${state.padEnd(28)} ${import_picocolors26.default.dim(row.description ?? row.actor)}`
|
|
289330
|
+
);
|
|
289331
|
+
}
|
|
289332
|
+
console.log();
|
|
289333
|
+
console.log(import_picocolors26.default.dim(` ${held} held, ${waiting} waiting.`));
|
|
289334
|
+
console.log();
|
|
289335
|
+
}
|
|
289336
|
+
async function claims(argv = []) {
|
|
289337
|
+
const { args, command } = splitAtCommand(argv);
|
|
289338
|
+
const flags = parseFlags(args);
|
|
289339
|
+
const [verb, ...rest] = positionals(args);
|
|
289340
|
+
if (verb === void 0 || verb === "help" || args.includes("--help")) {
|
|
289341
|
+
console.log(usageFor("claims"));
|
|
289342
|
+
return;
|
|
289343
|
+
}
|
|
289344
|
+
const apiKey = requireRuntimeKey();
|
|
289345
|
+
if (verb === "list") {
|
|
289346
|
+
const [model2, id2] = rest;
|
|
289347
|
+
const query = new URLSearchParams();
|
|
289348
|
+
if (model2 !== void 0) query.set("model", model2);
|
|
289349
|
+
if (id2 !== void 0) query.set("id", id2);
|
|
289350
|
+
if (flags.actor !== void 0) query.set("actorId", flags.actor);
|
|
289351
|
+
const suffix = query.toString();
|
|
289352
|
+
const page = await requestControlPlane({
|
|
289353
|
+
path: `${import_routes.CLAIM_ROUTES.collection}${suffix ? `?${suffix}` : ""}`,
|
|
289354
|
+
apiKey,
|
|
289355
|
+
responseSchema: import_contract.claimListResponseSchema
|
|
289356
|
+
});
|
|
289357
|
+
if (flags.json) console.log(JSON.stringify(page, null, 2));
|
|
289358
|
+
else renderList(page.data);
|
|
289359
|
+
return;
|
|
289360
|
+
}
|
|
289361
|
+
const [model, id] = rest;
|
|
289362
|
+
if (model === void 0 || id === void 0) {
|
|
289363
|
+
console.error(` ${import_picocolors26.default.red("\u2717")} Name the row: ${import_picocolors26.default.bold(`ablo claims ${verb} <model> <id>`)}.`);
|
|
289364
|
+
process.exitCode = 1;
|
|
289365
|
+
return;
|
|
289366
|
+
}
|
|
289367
|
+
if (verb === "acquire") {
|
|
289368
|
+
if (command.length > 0) {
|
|
289369
|
+
process.exitCode = await holdWhile(model, id, flags, apiKey, command);
|
|
289370
|
+
return;
|
|
289371
|
+
}
|
|
289372
|
+
const granted = await acquireClaim(model, id, flags, apiKey);
|
|
289373
|
+
if (flags.json) console.log(JSON.stringify(granted, null, 2));
|
|
289374
|
+
else console.log(describeAcquired(model, id, granted));
|
|
289375
|
+
return;
|
|
289376
|
+
}
|
|
289377
|
+
if (verb === "release") {
|
|
289378
|
+
const released = await releaseClaim(model, id, apiKey);
|
|
289379
|
+
if (flags.json) console.log(JSON.stringify({ object: "claim_release", released }, null, 2));
|
|
289380
|
+
else if (released) console.log(` ${import_picocolors26.default.green("\u2713")} Released ${import_picocolors26.default.bold(`${model} ${id}`)}.`);
|
|
289381
|
+
else console.log(` ${import_picocolors26.default.dim("\xB7")} ${import_picocolors26.default.dim(`You were not holding ${model} ${id}.`)}`);
|
|
289382
|
+
return;
|
|
289383
|
+
}
|
|
289384
|
+
if (verb === "heartbeat") {
|
|
289385
|
+
await beat(model, id, flags.ttl, apiKey);
|
|
289386
|
+
if (flags.json) console.log(JSON.stringify({ object: "claim_heartbeat", ok: true }, null, 2));
|
|
289387
|
+
else console.log(` ${import_picocolors26.default.green("\u2713")} Still holding ${import_picocolors26.default.bold(`${model} ${id}`)}.`);
|
|
289388
|
+
return;
|
|
289389
|
+
}
|
|
289390
|
+
console.error(` ${import_picocolors26.default.red("\u2717")} Unknown: ${import_picocolors26.default.bold(`ablo claims ${verb}`)}.`);
|
|
289391
|
+
console.error(usageFor("claims"));
|
|
289392
|
+
process.exitCode = 1;
|
|
289393
|
+
}
|
|
289394
|
+
|
|
289395
|
+
// src/upgrade.ts
|
|
289396
|
+
init_cjs_shims();
|
|
289397
|
+
var import_picocolors27 = __toESM(require_picocolors(), 1);
|
|
288886
289398
|
var import_ts_morph = __toESM(require_ts_morph(), 1);
|
|
288887
289399
|
var DEFAULT_GLOBS = ["app/**/*.{ts,tsx}", "src/**/*.{ts,tsx}", "ablo/**/*.{ts,tsx}", "lib/**/*.{ts,tsx}"];
|
|
288888
289400
|
var VERB_ARGS = {
|
|
@@ -288924,12 +289436,14 @@ function verbRewrite(call, verb) {
|
|
|
288924
289436
|
const args = call.getArguments();
|
|
288925
289437
|
const first = args[0];
|
|
288926
289438
|
if (first === void 0) return null;
|
|
288927
|
-
const calleeText = call.getExpression().getText();
|
|
289439
|
+
const calleeText = verb === "retrieve" ? `${call.getExpression().getText().slice(0, -"retrieve".length)}get` : call.getExpression().getText();
|
|
288928
289440
|
if (verb === "create") {
|
|
288929
289441
|
if (import_ts_morph.Node.isObjectLiteralExpression(first) && hasKey2(first, "data")) return null;
|
|
288930
289442
|
return `${calleeText}({ data: ${first.getText()}${spreadOpts(args[1])} })`;
|
|
288931
289443
|
}
|
|
288932
|
-
if (import_ts_morph.Node.isObjectLiteralExpression(first))
|
|
289444
|
+
if (import_ts_morph.Node.isObjectLiteralExpression(first)) {
|
|
289445
|
+
return verb === "retrieve" ? `${calleeText}(${first.getText()})` : null;
|
|
289446
|
+
}
|
|
288933
289447
|
const keyed = params.map((key, i) => args[i] ? `${key}: ${args[i].getText()}` : null).filter(Boolean);
|
|
288934
289448
|
return `${calleeText}({ ${keyed.join(", ")}${spreadOpts(args[params.length])} })`;
|
|
288935
289449
|
}
|
|
@@ -288945,7 +289459,7 @@ function loadRewrite(call) {
|
|
|
288945
289459
|
if (import_ts_morph.Node.isObjectLiteralExpression(whereVal)) {
|
|
288946
289460
|
const idProp = whereVal.getProperty("id");
|
|
288947
289461
|
if (idProp && whereVal.getProperties().length === 1 && import_ts_morph.Node.isPropertyAssignment(idProp)) {
|
|
288948
|
-
return `${base}.
|
|
289462
|
+
return `${base}.get({ id: ${idProp.getInitializerOrThrow().getText()} })`;
|
|
288949
289463
|
}
|
|
288950
289464
|
}
|
|
288951
289465
|
return `${base}.list({ where: ${whereVal.getText()} })`;
|
|
@@ -288960,7 +289474,7 @@ async function upgrade(argv) {
|
|
|
288960
289474
|
project.addSourceFilesAtPaths(globs.length > 0 ? globs : DEFAULT_GLOBS);
|
|
288961
289475
|
const files = project.getSourceFiles();
|
|
288962
289476
|
if (files.length === 0) {
|
|
288963
|
-
console.log(
|
|
289477
|
+
console.log(import_picocolors27.default.yellow(' No .ts/.tsx files found. Pass a glob, e.g. `ablo upgrade "src/**/*.tsx"`.'));
|
|
288964
289478
|
return;
|
|
288965
289479
|
}
|
|
288966
289480
|
const edits = [];
|
|
@@ -289008,7 +289522,7 @@ async function upgrade(argv) {
|
|
|
289008
289522
|
} else if (method === "load") {
|
|
289009
289523
|
const next = loadRewrite(call);
|
|
289010
289524
|
if (next) {
|
|
289011
|
-
record(call, "load\
|
|
289525
|
+
record(call, "load\u2192get/list", (call.getText().split("\n")[0] ?? "").slice(0, 80), next.slice(0, 80));
|
|
289012
289526
|
call.replaceWithText(next);
|
|
289013
289527
|
}
|
|
289014
289528
|
}
|
|
@@ -289034,39 +289548,39 @@ async function upgrade(argv) {
|
|
|
289034
289548
|
const rel = (f) => f.replace(cwd + "/", "");
|
|
289035
289549
|
console.log();
|
|
289036
289550
|
if (edits.length === 0 && manual.length === 0) {
|
|
289037
|
-
console.log(
|
|
289551
|
+
console.log(import_picocolors27.default.green(" \u2713 Nothing to migrate \u2014 your code is already on the current API."));
|
|
289038
289552
|
return;
|
|
289039
289553
|
}
|
|
289040
289554
|
if (edits.length > 0) {
|
|
289041
|
-
console.log(
|
|
289555
|
+
console.log(import_picocolors27.default.bold(` ${write ? "Applied" : "Would apply"} ${edits.length} change${edits.length === 1 ? "" : "s"}:`));
|
|
289042
289556
|
for (const e2 of edits) {
|
|
289043
|
-
console.log(` ${
|
|
289044
|
-
console.log(` ${
|
|
289045
|
-
console.log(` ${
|
|
289557
|
+
console.log(` ${import_picocolors27.default.dim(`${rel(e2.file)}:${e2.line}`)} ${import_picocolors27.default.cyan(e2.rule)}`);
|
|
289558
|
+
console.log(` ${import_picocolors27.default.red("-")} ${e2.before}`);
|
|
289559
|
+
console.log(` ${import_picocolors27.default.green("+")} ${e2.after}`);
|
|
289046
289560
|
}
|
|
289047
289561
|
}
|
|
289048
289562
|
if (manual.length > 0) {
|
|
289049
289563
|
console.log();
|
|
289050
|
-
console.log(
|
|
289564
|
+
console.log(import_picocolors27.default.bold(import_picocolors27.default.yellow(` ${manual.length} spot${manual.length === 1 ? "" : "s"} need manual review (structural):`)));
|
|
289051
289565
|
for (const m2 of manual) {
|
|
289052
|
-
console.log(` ${
|
|
289053
|
-
console.log(` ${
|
|
289566
|
+
console.log(` ${import_picocolors27.default.dim(`${rel(m2.file)}:${m2.line}`)} ${import_picocolors27.default.yellow(m2.rule)}`);
|
|
289567
|
+
console.log(` ${import_picocolors27.default.dim(m2.snippet)}`);
|
|
289054
289568
|
console.log(` \u2192 ${m2.hint}`);
|
|
289055
289569
|
}
|
|
289056
289570
|
}
|
|
289057
289571
|
console.log();
|
|
289058
289572
|
if (write) {
|
|
289059
289573
|
await project.save();
|
|
289060
|
-
console.log(
|
|
289574
|
+
console.log(import_picocolors27.default.green(` \u2713 Wrote ${edits.length} change${edits.length === 1 ? "" : "s"}. Review the diff, run your typecheck.`));
|
|
289061
289575
|
} else {
|
|
289062
|
-
console.log(
|
|
289576
|
+
console.log(import_picocolors27.default.dim(" Dry run. Re-run with `--write` to apply the auto-fixes above (manual items are never auto-written)."));
|
|
289063
289577
|
}
|
|
289064
289578
|
}
|
|
289065
289579
|
|
|
289066
289580
|
// src/pull.ts
|
|
289067
289581
|
init_cjs_shims();
|
|
289068
|
-
var
|
|
289069
|
-
var
|
|
289582
|
+
var import_errors22 = require("@abloatai/transaction/errors");
|
|
289583
|
+
var import_picocolors28 = __toESM(require_picocolors(), 1);
|
|
289070
289584
|
init_src();
|
|
289071
289585
|
var import_fs10 = require("fs");
|
|
289072
289586
|
init_theme();
|
|
@@ -289094,7 +289608,7 @@ function parsePullArgs(argv) {
|
|
|
289094
289608
|
force = true;
|
|
289095
289609
|
break;
|
|
289096
289610
|
default:
|
|
289097
|
-
throw new
|
|
289611
|
+
throw new import_errors22.AbloValidationError(`unknown flag: ${arg}`, { code: "cli_invalid_arguments" });
|
|
289098
289612
|
}
|
|
289099
289613
|
}
|
|
289100
289614
|
return { out, appSchema, importPath, force };
|
|
@@ -289164,56 +289678,56 @@ async function pull(argv) {
|
|
|
289164
289678
|
try {
|
|
289165
289679
|
args = parsePullArgs(argv);
|
|
289166
289680
|
} catch (err) {
|
|
289167
|
-
console.error(
|
|
289681
|
+
console.error(import_picocolors28.default.red(` ${err instanceof Error ? err.message : String(err)}`));
|
|
289168
289682
|
process.exit(1);
|
|
289169
289683
|
}
|
|
289170
289684
|
const dbUrl = readProjectAdminDatabaseUrl();
|
|
289171
289685
|
if (!dbUrl) {
|
|
289172
289686
|
console.error(
|
|
289173
|
-
|
|
289687
|
+
import_picocolors28.default.red(` No database.`) + import_picocolors28.default.dim(` Set ${import_picocolors28.default.bold(ADMIN_URL_VAR)} to the Postgres to pull from.`)
|
|
289174
289688
|
);
|
|
289175
289689
|
process.exit(1);
|
|
289176
289690
|
}
|
|
289177
289691
|
if ((0, import_fs10.existsSync)(args.out) && !args.force) {
|
|
289178
289692
|
console.error(
|
|
289179
|
-
|
|
289693
|
+
import_picocolors28.default.red(` ${args.out} already exists.`) + import_picocolors28.default.dim(` Re-run with ${import_picocolors28.default.bold("--force")} to overwrite.`)
|
|
289180
289694
|
);
|
|
289181
289695
|
process.exit(1);
|
|
289182
289696
|
}
|
|
289183
289697
|
console.log(`
|
|
289184
|
-
${brand("ablo")} ${
|
|
289698
|
+
${brand("ablo")} ${import_picocolors28.default.dim("pull")} ${import_picocolors28.default.dim(`schema "${args.appSchema}"`)}
|
|
289185
289699
|
`);
|
|
289186
289700
|
let result;
|
|
289187
289701
|
try {
|
|
289188
289702
|
result = await buildSchemaSourceFromDb({ dbUrl, appSchema: args.appSchema, importPath: args.importPath });
|
|
289189
289703
|
} catch (err) {
|
|
289190
|
-
console.error(
|
|
289704
|
+
console.error(import_picocolors28.default.red(` Couldn't read the database: ${err instanceof Error ? err.message : String(err)}`));
|
|
289191
289705
|
process.exit(1);
|
|
289192
289706
|
}
|
|
289193
289707
|
if (result.models.length === 0) {
|
|
289194
289708
|
console.error(
|
|
289195
|
-
|
|
289709
|
+
import_picocolors28.default.yellow(` No adoptable tables found`) + import_picocolors28.default.dim(` (a model needs an ${import_picocolors28.default.bold("id")} + ${import_picocolors28.default.bold("organization_id")} column).`)
|
|
289196
289710
|
);
|
|
289197
289711
|
process.exit(1);
|
|
289198
289712
|
}
|
|
289199
289713
|
(0, import_fs10.writeFileSync)(args.out, result.source);
|
|
289200
|
-
console.log(` ${
|
|
289201
|
-
console.log(` ${
|
|
289714
|
+
console.log(` ${import_picocolors28.default.green("\u2713")} wrote ${import_picocolors28.default.bold(args.out)} ${import_picocolors28.default.dim(`(${result.models.length} models)`)}`);
|
|
289715
|
+
console.log(` ${import_picocolors28.default.dim(`models: ${result.models.join(", ")}`)}`);
|
|
289202
289716
|
if (result.skipped.length > 0) {
|
|
289203
|
-
console.log(` ${
|
|
289204
|
-
for (const s of result.skipped) console.log(` ${
|
|
289717
|
+
console.log(` ${import_picocolors28.default.dim(`${result.skipped.length} table(s) skipped:`)}`);
|
|
289718
|
+
for (const s of result.skipped) console.log(` ${import_picocolors28.default.dim(`- ${s.name}: ${s.reason}`)}`);
|
|
289205
289719
|
}
|
|
289206
289720
|
console.log(
|
|
289207
289721
|
`
|
|
289208
|
-
${
|
|
289722
|
+
${import_picocolors28.default.dim("Introspection is lossy (enums, JSON shape, relations). Review the file, then")} ${import_picocolors28.default.bold("ablo check")}.
|
|
289209
289723
|
`
|
|
289210
289724
|
);
|
|
289211
289725
|
}
|
|
289212
289726
|
|
|
289213
289727
|
// src/prismaPull.ts
|
|
289214
289728
|
init_cjs_shims();
|
|
289215
|
-
var
|
|
289216
|
-
var
|
|
289729
|
+
var import_errors23 = require("@abloatai/transaction/errors");
|
|
289730
|
+
var import_picocolors29 = __toESM(require_picocolors(), 1);
|
|
289217
289731
|
var import_fs11 = require("fs");
|
|
289218
289732
|
init_theme();
|
|
289219
289733
|
var DEFAULT_SCHEMA = "prisma/schema.prisma";
|
|
@@ -289410,7 +289924,7 @@ function parsePrismaPullArgs(argv) {
|
|
|
289410
289924
|
force = true;
|
|
289411
289925
|
break;
|
|
289412
289926
|
default:
|
|
289413
|
-
if (arg.startsWith("--")) throw new
|
|
289927
|
+
if (arg.startsWith("--")) throw new import_errors23.AbloValidationError(`unknown flag: ${arg}`, { code: "cli_invalid_arguments" });
|
|
289414
289928
|
schema = arg;
|
|
289415
289929
|
}
|
|
289416
289930
|
}
|
|
@@ -289421,56 +289935,56 @@ async function prismaPull(argv) {
|
|
|
289421
289935
|
try {
|
|
289422
289936
|
args = parsePrismaPullArgs(argv);
|
|
289423
289937
|
} catch (err) {
|
|
289424
|
-
console.error(
|
|
289938
|
+
console.error(import_picocolors29.default.red(` ${err instanceof Error ? err.message : String(err)}`));
|
|
289425
289939
|
process.exit(1);
|
|
289426
289940
|
}
|
|
289427
289941
|
if (!(0, import_fs11.existsSync)(args.schema)) {
|
|
289428
289942
|
console.error(
|
|
289429
|
-
|
|
289943
|
+
import_picocolors29.default.red(` No Prisma schema at ${import_picocolors29.default.bold(args.schema)}.`) + import_picocolors29.default.dim(` Pass a path: ${import_picocolors29.default.bold("ablo pull prisma <path>")}.`)
|
|
289430
289944
|
);
|
|
289431
289945
|
process.exit(1);
|
|
289432
289946
|
}
|
|
289433
289947
|
if ((0, import_fs11.existsSync)(args.out) && !args.force) {
|
|
289434
289948
|
console.error(
|
|
289435
|
-
|
|
289949
|
+
import_picocolors29.default.red(` ${args.out} already exists.`) + import_picocolors29.default.dim(` Re-run with ${import_picocolors29.default.bold("--force")} to overwrite.`)
|
|
289436
289950
|
);
|
|
289437
289951
|
process.exit(1);
|
|
289438
289952
|
}
|
|
289439
289953
|
console.log(`
|
|
289440
|
-
${brand("ablo")} ${
|
|
289954
|
+
${brand("ablo")} ${import_picocolors29.default.dim("pull prisma")} ${import_picocolors29.default.dim(args.schema)}
|
|
289441
289955
|
`);
|
|
289442
289956
|
let result;
|
|
289443
289957
|
try {
|
|
289444
289958
|
const src = (0, import_fs11.readFileSync)(args.schema, "utf8");
|
|
289445
289959
|
result = buildSchemaSourceFromPrisma({ src, importPath: args.importPath });
|
|
289446
289960
|
} catch (err) {
|
|
289447
|
-
console.error(
|
|
289961
|
+
console.error(import_picocolors29.default.red(` Couldn't parse the schema: ${err instanceof Error ? err.message : String(err)}`));
|
|
289448
289962
|
process.exit(1);
|
|
289449
289963
|
}
|
|
289450
289964
|
if (result.models.length === 0) {
|
|
289451
289965
|
console.error(
|
|
289452
|
-
|
|
289966
|
+
import_picocolors29.default.yellow(` No adoptable models found`) + import_picocolors29.default.dim(` (a model needs an ${import_picocolors29.default.bold("id")} + ${import_picocolors29.default.bold("organizationId")} / ${import_picocolors29.default.bold("organization_id")}).`)
|
|
289453
289967
|
);
|
|
289454
289968
|
process.exit(1);
|
|
289455
289969
|
}
|
|
289456
289970
|
(0, import_fs11.writeFileSync)(args.out, result.source);
|
|
289457
|
-
console.log(` ${
|
|
289458
|
-
console.log(` ${
|
|
289971
|
+
console.log(` ${import_picocolors29.default.green("\u2713")} wrote ${import_picocolors29.default.bold(args.out)} ${import_picocolors29.default.dim(`(${result.models.length} models)`)}`);
|
|
289972
|
+
console.log(` ${import_picocolors29.default.dim(`models: ${result.models.join(", ")}`)}`);
|
|
289459
289973
|
if (result.skipped.length > 0) {
|
|
289460
|
-
console.log(` ${
|
|
289461
|
-
for (const s of result.skipped) console.log(` ${
|
|
289974
|
+
console.log(` ${import_picocolors29.default.dim(`${result.skipped.length} model(s) skipped:`)}`);
|
|
289975
|
+
for (const s of result.skipped) console.log(` ${import_picocolors29.default.dim(`- ${s.name}: ${s.reason}`)}`);
|
|
289462
289976
|
}
|
|
289463
289977
|
console.log(
|
|
289464
289978
|
`
|
|
289465
|
-
${
|
|
289979
|
+
${import_picocolors29.default.dim("Enums and relations were preserved. Review the file, then")} ${import_picocolors29.default.bold("ablo check")}.
|
|
289466
289980
|
`
|
|
289467
289981
|
);
|
|
289468
289982
|
}
|
|
289469
289983
|
|
|
289470
289984
|
// src/drizzlePull.ts
|
|
289471
289985
|
init_cjs_shims();
|
|
289472
|
-
var
|
|
289473
|
-
var
|
|
289986
|
+
var import_picocolors30 = __toESM(require_picocolors(), 1);
|
|
289987
|
+
var import_errors24 = require("@abloatai/transaction/errors");
|
|
289474
289988
|
var import_fs12 = require("fs");
|
|
289475
289989
|
var import_path7 = require("path");
|
|
289476
289990
|
init_theme();
|
|
@@ -289577,7 +290091,7 @@ function parseDrizzlePullArgs(argv) {
|
|
|
289577
290091
|
force = true;
|
|
289578
290092
|
break;
|
|
289579
290093
|
default:
|
|
289580
|
-
if (arg.startsWith("--")) throw new
|
|
290094
|
+
if (arg.startsWith("--")) throw new import_errors24.AbloValidationError(`unknown flag: ${arg}`, { code: "cli_invalid_arguments" });
|
|
289581
290095
|
schema = arg;
|
|
289582
290096
|
}
|
|
289583
290097
|
}
|
|
@@ -289594,27 +290108,27 @@ async function drizzlePull(argv) {
|
|
|
289594
290108
|
try {
|
|
289595
290109
|
args = parseDrizzlePullArgs(argv);
|
|
289596
290110
|
} catch (err) {
|
|
289597
|
-
console.error(
|
|
290111
|
+
console.error(import_picocolors30.default.red(` ${err instanceof Error ? err.message : String(err)}`));
|
|
289598
290112
|
process.exit(1);
|
|
289599
290113
|
}
|
|
289600
290114
|
if (!args.schema) {
|
|
289601
290115
|
console.error(
|
|
289602
|
-
|
|
290116
|
+
import_picocolors30.default.red(` No Drizzle schema given.`) + import_picocolors30.default.dim(` Pass the module: ${import_picocolors30.default.bold("ablo pull drizzle src/db/schema.ts")}.`)
|
|
289603
290117
|
);
|
|
289604
290118
|
process.exit(1);
|
|
289605
290119
|
}
|
|
289606
290120
|
if (!(0, import_fs12.existsSync)(args.schema)) {
|
|
289607
|
-
console.error(
|
|
290121
|
+
console.error(import_picocolors30.default.red(` No file at ${import_picocolors30.default.bold(args.schema)}.`));
|
|
289608
290122
|
process.exit(1);
|
|
289609
290123
|
}
|
|
289610
290124
|
if ((0, import_fs12.existsSync)(args.out) && !args.force) {
|
|
289611
290125
|
console.error(
|
|
289612
|
-
|
|
290126
|
+
import_picocolors30.default.red(` ${args.out} already exists.`) + import_picocolors30.default.dim(` Re-run with ${import_picocolors30.default.bold("--force")} to overwrite.`)
|
|
289613
290127
|
);
|
|
289614
290128
|
process.exit(1);
|
|
289615
290129
|
}
|
|
289616
290130
|
console.log(`
|
|
289617
|
-
${brand("ablo")} ${
|
|
290131
|
+
${brand("ablo")} ${import_picocolors30.default.dim("pull drizzle")} ${import_picocolors30.default.dim(args.schema)}
|
|
289618
290132
|
`);
|
|
289619
290133
|
let result;
|
|
289620
290134
|
try {
|
|
@@ -289622,26 +290136,26 @@ async function drizzlePull(argv) {
|
|
|
289622
290136
|
result = await buildSchemaSourceFromDrizzle({ mod, importPath: args.importPath });
|
|
289623
290137
|
} catch (err) {
|
|
289624
290138
|
const msg = err instanceof Error ? err.message : String(err);
|
|
289625
|
-
const hint = msg.includes("Cannot find package 'drizzle-orm'") ?
|
|
289626
|
-
console.error(
|
|
290139
|
+
const hint = msg.includes("Cannot find package 'drizzle-orm'") ? import_picocolors30.default.dim(` (install ${import_picocolors30.default.bold("drizzle-orm")} in this project)`) : "";
|
|
290140
|
+
console.error(import_picocolors30.default.red(` Couldn't load the schema: ${msg}`) + hint);
|
|
289627
290141
|
process.exit(1);
|
|
289628
290142
|
}
|
|
289629
290143
|
if (result.models.length === 0) {
|
|
289630
290144
|
console.error(
|
|
289631
|
-
|
|
290145
|
+
import_picocolors30.default.yellow(` No adoptable tables found`) + import_picocolors30.default.dim(` (a table needs an ${import_picocolors30.default.bold("id")} + ${import_picocolors30.default.bold("organization_id")} column).`)
|
|
289632
290146
|
);
|
|
289633
290147
|
process.exit(1);
|
|
289634
290148
|
}
|
|
289635
290149
|
(0, import_fs12.writeFileSync)(args.out, result.source);
|
|
289636
|
-
console.log(` ${
|
|
289637
|
-
console.log(` ${
|
|
290150
|
+
console.log(` ${import_picocolors30.default.green("\u2713")} wrote ${import_picocolors30.default.bold(args.out)} ${import_picocolors30.default.dim(`(${result.models.length} models)`)}`);
|
|
290151
|
+
console.log(` ${import_picocolors30.default.dim(`models: ${result.models.join(", ")}`)}`);
|
|
289638
290152
|
if (result.skipped.length > 0) {
|
|
289639
|
-
console.log(` ${
|
|
289640
|
-
for (const s of result.skipped) console.log(` ${
|
|
290153
|
+
console.log(` ${import_picocolors30.default.dim(`${result.skipped.length} table(s) skipped:`)}`);
|
|
290154
|
+
for (const s of result.skipped) console.log(` ${import_picocolors30.default.dim(`- ${s.name}: ${s.reason}`)}`);
|
|
289641
290155
|
}
|
|
289642
290156
|
console.log(
|
|
289643
290157
|
`
|
|
289644
|
-
${
|
|
290158
|
+
${import_picocolors30.default.dim("Enums and relations were preserved. Review the file, then")} ${import_picocolors30.default.bold("ablo check")}.
|
|
289645
290159
|
`
|
|
289646
290160
|
);
|
|
289647
290161
|
}
|
|
@@ -289654,8 +290168,8 @@ init_telemetry();
|
|
|
289654
290168
|
|
|
289655
290169
|
// src/init/options.ts
|
|
289656
290170
|
init_cjs_shims();
|
|
289657
|
-
var
|
|
289658
|
-
var
|
|
290171
|
+
var import_node_fs5 = require("fs");
|
|
290172
|
+
var import_node_path4 = require("path");
|
|
289659
290173
|
var INIT_FRAMEWORKS = ["nextjs", "vite", "remix", "vanilla"];
|
|
289660
290174
|
var INIT_AUTHS = [
|
|
289661
290175
|
"apikey",
|
|
@@ -289694,7 +290208,7 @@ function parseInitArgs(args) {
|
|
|
289694
290208
|
function detectOrm(override, root = process.cwd()) {
|
|
289695
290209
|
if (override === "prisma" || override === "drizzle" || override === "none") return override;
|
|
289696
290210
|
try {
|
|
289697
|
-
const pkg = JSON.parse((0,
|
|
290211
|
+
const pkg = JSON.parse((0, import_node_fs5.readFileSync)((0, import_node_path4.resolve)(root, "package.json"), "utf8"));
|
|
289698
290212
|
const dependencies = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
289699
290213
|
if (dependencies["@prisma/client"] || dependencies.prisma) return "prisma";
|
|
289700
290214
|
if (dependencies["drizzle-orm"]) return "drizzle";
|
|
@@ -289703,24 +290217,24 @@ function detectOrm(override, root = process.cwd()) {
|
|
|
289703
290217
|
return "none";
|
|
289704
290218
|
}
|
|
289705
290219
|
function detectNextLayout(root = process.cwd()) {
|
|
289706
|
-
const useSrc = (0,
|
|
289707
|
-
return useSrc ? { appBase: (0,
|
|
290220
|
+
const useSrc = (0, import_node_fs5.existsSync)((0, import_node_path4.resolve)(root, "src", "app")) || !(0, import_node_fs5.existsSync)((0, import_node_path4.resolve)(root, "app")) && (0, import_node_fs5.existsSync)((0, import_node_path4.resolve)(root, "src"));
|
|
290221
|
+
return useSrc ? { appBase: (0, import_node_path4.join)("src", "app"), aliasBase: "src" } : { appBase: "app", aliasBase: "." };
|
|
289708
290222
|
}
|
|
289709
290223
|
function detectPackageManager(root = process.cwd()) {
|
|
289710
|
-
if ((0,
|
|
289711
|
-
if ((0,
|
|
289712
|
-
if ((0,
|
|
290224
|
+
if ((0, import_node_fs5.existsSync)((0, import_node_path4.resolve)(root, "pnpm-lock.yaml"))) return "pnpm";
|
|
290225
|
+
if ((0, import_node_fs5.existsSync)((0, import_node_path4.resolve)(root, "yarn.lock"))) return "yarn";
|
|
290226
|
+
if ((0, import_node_fs5.existsSync)((0, import_node_path4.resolve)(root, "bun.lockb"))) return "bun";
|
|
289713
290227
|
return "npm";
|
|
289714
290228
|
}
|
|
289715
290229
|
|
|
289716
290230
|
// src/init/run.ts
|
|
289717
290231
|
init_cjs_shims();
|
|
289718
|
-
var
|
|
289719
|
-
var
|
|
289720
|
-
var
|
|
290232
|
+
var import_node_child_process4 = require("child_process");
|
|
290233
|
+
var import_node_fs7 = require("fs");
|
|
290234
|
+
var import_node_path6 = require("path");
|
|
289721
290235
|
init_dist2();
|
|
289722
|
-
var
|
|
289723
|
-
var
|
|
290236
|
+
var import_picocolors31 = __toESM(require_picocolors(), 1);
|
|
290237
|
+
var import_errors25 = require("@abloatai/transaction/errors");
|
|
289724
290238
|
init_dbRole();
|
|
289725
290239
|
init_config();
|
|
289726
290240
|
init_projects();
|
|
@@ -290105,12 +290619,12 @@ async function main() {
|
|
|
290105
290619
|
// Triage the urgent one to the top. We write based on the version we just
|
|
290106
290620
|
// read (\`readAt\`), so if a human edits the same row at the same moment the
|
|
290107
290621
|
// write is rejected instead of silently clobbering them.
|
|
290108
|
-
const
|
|
290622
|
+
const current = await ablo.records.read({ id: urgent.id });
|
|
290623
|
+
if (!current) throw new Error('urgent record was not found');
|
|
290109
290624
|
await ablo.records.update({
|
|
290110
290625
|
id: urgent.id,
|
|
290111
290626
|
data: { priority: 10 },
|
|
290112
|
-
|
|
290113
|
-
onStale: 'reject',
|
|
290627
|
+
reads: [current],
|
|
290114
290628
|
});
|
|
290115
290629
|
console.log('prioritized:', urgent.title);
|
|
290116
290630
|
|
|
@@ -290180,9 +290694,9 @@ export function RecordList() {
|
|
|
290180
290694
|
|
|
290181
290695
|
// src/init/writer.ts
|
|
290182
290696
|
init_cjs_shims();
|
|
290183
|
-
var
|
|
290184
|
-
var
|
|
290185
|
-
var
|
|
290697
|
+
var import_node_fs6 = require("fs");
|
|
290698
|
+
var import_node_path5 = require("path");
|
|
290699
|
+
var import_node_crypto8 = require("crypto");
|
|
290186
290700
|
function projectInitWritePlan(plan) {
|
|
290187
290701
|
return setupInitPlanProjectionSchema.parse({
|
|
290188
290702
|
root: plan.root,
|
|
@@ -290196,18 +290710,18 @@ function projectInitWritePlan(plan) {
|
|
|
290196
290710
|
});
|
|
290197
290711
|
}
|
|
290198
290712
|
function absolute(root, path) {
|
|
290199
|
-
const target = (0,
|
|
290200
|
-
const fromRoot = (0,
|
|
290201
|
-
if (fromRoot === "" || fromRoot === ".." || fromRoot.startsWith(`..${
|
|
290713
|
+
const target = (0, import_node_path5.resolve)(root, path);
|
|
290714
|
+
const fromRoot = (0, import_node_path5.relative)(root, target);
|
|
290715
|
+
if (fromRoot === "" || fromRoot === ".." || fromRoot.startsWith(`..${import_node_path5.sep}`) || (0, import_node_path5.isAbsolute)(fromRoot)) {
|
|
290202
290716
|
throw new Error(`Init target must stay inside the project root: ${path}`);
|
|
290203
290717
|
}
|
|
290204
290718
|
return target;
|
|
290205
290719
|
}
|
|
290206
290720
|
function sha2562(content) {
|
|
290207
|
-
return (0,
|
|
290721
|
+
return (0, import_node_crypto8.createHash)("sha256").update(content).digest("hex");
|
|
290208
290722
|
}
|
|
290209
290723
|
function readIfPresent(path) {
|
|
290210
|
-
return (0,
|
|
290724
|
+
return (0, import_node_fs6.existsSync)(path) ? (0, import_node_fs6.readFileSync)(path, "utf8") : void 0;
|
|
290211
290725
|
}
|
|
290212
290726
|
function mergeEnvironmentTemplate(existing, template) {
|
|
290213
290727
|
const assignments = template.split(/\r?\n/).map((line) => {
|
|
@@ -290231,7 +290745,7 @@ function mergeEnvironmentTemplate(existing, template) {
|
|
|
290231
290745
|
};
|
|
290232
290746
|
}
|
|
290233
290747
|
function planInitWrites(input) {
|
|
290234
|
-
const root = (0,
|
|
290748
|
+
const root = (0, import_node_path5.resolve)(input.root ?? process.cwd());
|
|
290235
290749
|
const actions = [];
|
|
290236
290750
|
const conflicts = [];
|
|
290237
290751
|
for (const file of input.files) {
|
|
@@ -290276,18 +290790,18 @@ function planInitWrites(input) {
|
|
|
290276
290790
|
return { root, actions, conflicts };
|
|
290277
290791
|
}
|
|
290278
290792
|
function writeAtomic(path, content, kind) {
|
|
290279
|
-
(0,
|
|
290280
|
-
const temporary = (0,
|
|
290281
|
-
(0,
|
|
290793
|
+
(0, import_node_fs6.mkdirSync)((0, import_node_path5.dirname)(path), { recursive: true });
|
|
290794
|
+
const temporary = (0, import_node_path5.join)((0, import_node_path5.dirname)(path), `.${(0, import_node_crypto8.randomUUID)()}.ablo-init.tmp`);
|
|
290795
|
+
(0, import_node_fs6.writeFileSync)(temporary, content, { flag: "wx" });
|
|
290282
290796
|
try {
|
|
290283
290797
|
if (kind === "create") {
|
|
290284
|
-
(0,
|
|
290285
|
-
(0,
|
|
290798
|
+
(0, import_node_fs6.linkSync)(temporary, path);
|
|
290799
|
+
(0, import_node_fs6.unlinkSync)(temporary);
|
|
290286
290800
|
} else {
|
|
290287
|
-
(0,
|
|
290801
|
+
(0, import_node_fs6.renameSync)(temporary, path);
|
|
290288
290802
|
}
|
|
290289
290803
|
} catch (error) {
|
|
290290
|
-
if ((0,
|
|
290804
|
+
if ((0, import_node_fs6.existsSync)(temporary)) (0, import_node_fs6.unlinkSync)(temporary);
|
|
290291
290805
|
throw error;
|
|
290292
290806
|
}
|
|
290293
290807
|
}
|
|
@@ -290318,23 +290832,23 @@ function bailIfCancelled(value) {
|
|
|
290318
290832
|
process.exit(0);
|
|
290319
290833
|
}
|
|
290320
290834
|
}
|
|
290321
|
-
async function chooseOption(name,
|
|
290322
|
-
if (
|
|
290323
|
-
if (!allowed.includes(
|
|
290324
|
-
throw new
|
|
290325
|
-
`Invalid --${name} "${
|
|
290835
|
+
async function chooseOption(name, flagValue2, fallback, allowed, interactive, prompt) {
|
|
290836
|
+
if (flagValue2 !== void 0) {
|
|
290837
|
+
if (!allowed.includes(flagValue2)) {
|
|
290838
|
+
throw new import_errors25.AbloValidationError(
|
|
290839
|
+
`Invalid --${name} "${flagValue2}". Allowed: ${allowed.join(", ")}`,
|
|
290326
290840
|
{ code: "cli_invalid_arguments" }
|
|
290327
290841
|
);
|
|
290328
290842
|
}
|
|
290329
|
-
return
|
|
290843
|
+
return flagValue2;
|
|
290330
290844
|
}
|
|
290331
290845
|
if (!interactive) return fallback;
|
|
290332
290846
|
const value = await prompt();
|
|
290333
290847
|
bailIfCancelled(value);
|
|
290334
290848
|
return value;
|
|
290335
290849
|
}
|
|
290336
|
-
async function chooseBool(
|
|
290337
|
-
if (
|
|
290850
|
+
async function chooseBool(flagValue2, fallback, interactive, prompt) {
|
|
290851
|
+
if (flagValue2 !== void 0) return flagValue2;
|
|
290338
290852
|
if (!interactive) return fallback;
|
|
290339
290853
|
const value = await prompt();
|
|
290340
290854
|
bailIfCancelled(value);
|
|
@@ -290345,7 +290859,7 @@ async function ensureInitProject(opts) {
|
|
|
290345
290859
|
const slug = opts.project ?? projectSlugFromPackageName(
|
|
290346
290860
|
(() => {
|
|
290347
290861
|
try {
|
|
290348
|
-
return JSON.parse((0,
|
|
290862
|
+
return JSON.parse((0, import_node_fs7.readFileSync)("package.json", "utf8")).name;
|
|
290349
290863
|
} catch {
|
|
290350
290864
|
return void 0;
|
|
290351
290865
|
}
|
|
@@ -290355,7 +290869,7 @@ async function ensureInitProject(opts) {
|
|
|
290355
290869
|
const ensured = await ensureProject(slug);
|
|
290356
290870
|
if (ensured) {
|
|
290357
290871
|
console.log(
|
|
290358
|
-
` ${
|
|
290872
|
+
` ${import_picocolors31.default.green("\u2713")} ${ensured.created ? "Created" : "Using"} project ${import_picocolors31.default.bold(ensured.slug)} ${import_picocolors31.default.dim(`(${ensured.id})`)} \u2014 keys you mint for it are isolated from the org's other apps.`
|
|
290359
290873
|
);
|
|
290360
290874
|
}
|
|
290361
290875
|
}
|
|
@@ -290367,16 +290881,16 @@ function renderWritePlan(actions) {
|
|
|
290367
290881
|
}
|
|
290368
290882
|
function renderAppliedWrites(actions) {
|
|
290369
290883
|
return actions.map((action) => {
|
|
290370
|
-
const status2 = action.kind === "create" ?
|
|
290371
|
-
return `${
|
|
290884
|
+
const status2 = action.kind === "create" ? import_picocolors31.default.green("created") : action.kind === "update" ? import_picocolors31.default.yellow("updated") : import_picocolors31.default.dim("unchanged");
|
|
290885
|
+
return `${import_picocolors31.default.green("\u2713")} ${action.path}${action.note ?? ""} ${import_picocolors31.default.dim(`(${status2})`)}`;
|
|
290372
290886
|
}).join("\n");
|
|
290373
290887
|
}
|
|
290374
290888
|
async function runInit(args = []) {
|
|
290375
290889
|
const opts = parseInitArgs(args);
|
|
290376
290890
|
const interactive = Boolean(process.stdin.isTTY) && !opts.yes && !process.env.CI;
|
|
290377
|
-
Ie(`${brand("ablo")} ${
|
|
290378
|
-
if (!(0,
|
|
290379
|
-
throw new
|
|
290891
|
+
Ie(`${brand("ablo")} ${import_picocolors31.default.dim("sync engine")}`);
|
|
290892
|
+
if (!(0, import_node_fs7.existsSync)("package.json")) {
|
|
290893
|
+
throw new import_errors25.AbloValidationError("No package.json found. Run this from your project root.", {
|
|
290380
290894
|
code: "cli_invalid_arguments"
|
|
290381
290895
|
});
|
|
290382
290896
|
}
|
|
@@ -290445,14 +290959,14 @@ async function runInit(args = []) {
|
|
|
290445
290959
|
);
|
|
290446
290960
|
}
|
|
290447
290961
|
const layout = framework === "nextjs" ? detectNextLayout() : { appBase: "app", aliasBase: "." };
|
|
290448
|
-
const abloDir = (0,
|
|
290962
|
+
const abloDir = (0, import_node_path6.join)(layout.aliasBase, "ablo");
|
|
290449
290963
|
const files = [];
|
|
290450
290964
|
let schemaSource = generateSchema();
|
|
290451
290965
|
let schemaNote = "";
|
|
290452
290966
|
if (pullExisting) {
|
|
290453
290967
|
const dbUrl = readProjectAdminDatabaseUrl();
|
|
290454
290968
|
if (!dbUrl) {
|
|
290455
|
-
schemaNote =
|
|
290969
|
+
schemaNote = import_picocolors31.default.dim(` (no ${ADMIN_URL_VAR} \u2014 wrote starter; run \`ablo pull\` later)`);
|
|
290456
290970
|
} else {
|
|
290457
290971
|
try {
|
|
290458
290972
|
const pulled = await buildSchemaSourceFromDb({
|
|
@@ -290462,59 +290976,59 @@ async function runInit(args = []) {
|
|
|
290462
290976
|
});
|
|
290463
290977
|
if (pulled.models.length > 0) {
|
|
290464
290978
|
schemaSource = pulled.source;
|
|
290465
|
-
schemaNote =
|
|
290979
|
+
schemaNote = import_picocolors31.default.dim(` (pulled ${pulled.models.length} models)`);
|
|
290466
290980
|
} else {
|
|
290467
|
-
schemaNote =
|
|
290981
|
+
schemaNote = import_picocolors31.default.dim(" (no adoptable tables \u2014 wrote starter)");
|
|
290468
290982
|
}
|
|
290469
290983
|
} catch {
|
|
290470
|
-
schemaNote =
|
|
290984
|
+
schemaNote = import_picocolors31.default.dim(" (pull failed \u2014 wrote starter)");
|
|
290471
290985
|
}
|
|
290472
290986
|
}
|
|
290473
290987
|
}
|
|
290474
|
-
files.push({ path: (0,
|
|
290988
|
+
files.push({ path: (0, import_node_path6.join)(abloDir, "schema.ts"), content: schemaSource, note: schemaNote });
|
|
290475
290989
|
files.push({
|
|
290476
|
-
path: (0,
|
|
290990
|
+
path: (0, import_node_path6.join)(abloDir, "index.ts"),
|
|
290477
290991
|
content: generateSyncConfig(auth, { serverOnly: framework === "nextjs" })
|
|
290478
290992
|
});
|
|
290479
|
-
files.push({ path: (0,
|
|
290993
|
+
files.push({ path: (0, import_node_path6.join)(abloDir, "register.ts"), content: generateRegister() });
|
|
290480
290994
|
const orm = detectOrm(opts.orm);
|
|
290481
290995
|
if (storage === "endpoint") {
|
|
290482
290996
|
files.push({
|
|
290483
|
-
path: (0,
|
|
290997
|
+
path: (0, import_node_path6.join)(abloDir, "data-source.ts"),
|
|
290484
290998
|
content: generateDataSource(orm),
|
|
290485
290999
|
note: orm === "drizzle" ? " (Drizzle)" : " (Prisma)"
|
|
290486
291000
|
});
|
|
290487
291001
|
}
|
|
290488
291002
|
const envFile = framework === "nextjs" ? ".env.local" : ".env";
|
|
290489
291003
|
const envBody = generateEnv(storage);
|
|
290490
|
-
if (agent) files.push({ path: (0,
|
|
291004
|
+
if (agent) files.push({ path: (0, import_node_path6.join)(abloDir, "agent.ts"), content: generateAgent() });
|
|
290491
291005
|
if (framework === "nextjs") {
|
|
290492
291006
|
if (storage === "endpoint") {
|
|
290493
|
-
const webhookDir = (0,
|
|
291007
|
+
const webhookDir = (0, import_node_path6.join)(layout.appBase, "api", "ablo", "webhooks");
|
|
290494
291008
|
files.push({
|
|
290495
|
-
path: (0,
|
|
291009
|
+
path: (0, import_node_path6.join)(webhookDir, "route.ts"),
|
|
290496
291010
|
content: generateWebhookRoute(orm),
|
|
290497
291011
|
note: orm === "prisma" ? " (Prisma mirror)" : " (add your database write)"
|
|
290498
291012
|
});
|
|
290499
291013
|
}
|
|
290500
291014
|
files.push({
|
|
290501
|
-
path: (0,
|
|
291015
|
+
path: (0, import_node_path6.join)(layout.appBase, "providers.tsx"),
|
|
290502
291016
|
content: generateProviders(),
|
|
290503
|
-
note: ` (wrap ${(0,
|
|
291017
|
+
note: ` (wrap ${(0, import_node_path6.join)(layout.appBase, "layout.tsx")} in <Providers>)`
|
|
290504
291018
|
});
|
|
290505
291019
|
files.push({
|
|
290506
|
-
path: (0,
|
|
291020
|
+
path: (0, import_node_path6.join)(layout.appBase, "api", "ablo-session", "route.ts"),
|
|
290507
291021
|
content: generateSessionRoute(),
|
|
290508
291022
|
note: " (wire your auth)"
|
|
290509
291023
|
});
|
|
290510
291024
|
}
|
|
290511
291025
|
if (framework !== "vanilla") {
|
|
290512
|
-
files.push({ path: (0,
|
|
291026
|
+
files.push({ path: (0, import_node_path6.join)(abloDir, "RecordList.tsx"), content: generateComponent() });
|
|
290513
291027
|
}
|
|
290514
291028
|
const writePlan = planInitWrites({ files, environment: { path: envFile, template: envBody } });
|
|
290515
291029
|
if (writePlan.conflicts.length > 0) {
|
|
290516
291030
|
const occupied = writePlan.conflicts.map(({ path }) => ` - ${path}`).join("\n");
|
|
290517
|
-
throw new
|
|
291031
|
+
throw new import_errors25.AbloValidationError(
|
|
290518
291032
|
`Ablo init did not change any files because these application-owned paths already contain different contents:
|
|
290519
291033
|
${occupied}
|
|
290520
291034
|
|
|
@@ -290524,7 +291038,7 @@ Move them, reconcile Ablo manually, or rerun after they match the generated scaf
|
|
|
290524
291038
|
}
|
|
290525
291039
|
if (opts.plan) {
|
|
290526
291040
|
Me(renderWritePlan(writePlan.actions), "Plan (no files changed)");
|
|
290527
|
-
Se(`Dry run complete. Re-run without ${
|
|
291041
|
+
Se(`Dry run complete. Re-run without ${import_picocolors31.default.bold("--plan")} to apply it.`);
|
|
290528
291042
|
return setupInitResultSchema.parse({
|
|
290529
291043
|
status: "planned",
|
|
290530
291044
|
plan: projectInitWritePlan(writePlan)
|
|
@@ -290541,32 +291055,32 @@ Move them, reconcile Ablo manually, or rerun after they match the generated scaf
|
|
|
290541
291055
|
const progress = Y2();
|
|
290542
291056
|
progress.start("Installing @abloatai/ablo");
|
|
290543
291057
|
try {
|
|
290544
|
-
(0,
|
|
291058
|
+
(0, import_node_child_process4.execFileSync)(packageManager2, ["add", "@abloatai/ablo"], { stdio: "ignore" });
|
|
290545
291059
|
progress.stop("Installed @abloatai/ablo");
|
|
290546
291060
|
} catch {
|
|
290547
291061
|
progress.stop(
|
|
290548
|
-
`${
|
|
291062
|
+
`${import_picocolors31.default.yellow("!")} Couldn't auto-install \u2014 run ${import_picocolors31.default.bold(`${packageManager2} install @abloatai/ablo`)}`
|
|
290549
291063
|
);
|
|
290550
291064
|
}
|
|
290551
291065
|
}
|
|
290552
291066
|
const steps = [
|
|
290553
|
-
`Run ${
|
|
290554
|
-
`Set ${
|
|
290555
|
-
`Run ${
|
|
291067
|
+
`Run ${import_picocolors31.default.bold("npx ablo login")} to authorize branch management`,
|
|
291068
|
+
`Set ${import_picocolors31.default.bold("DATABASE_URL")} in ${import_picocolors31.default.bold(envFile)} \u2014 your Postgres is the system of record; rows live there, never with Ablo`,
|
|
291069
|
+
`Run ${import_picocolors31.default.bold("npx ablo dev")} \u2014 pushes your schema definition and watches for changes`,
|
|
290556
291070
|
...storage === "replication" ? [
|
|
290557
|
-
`Connect your database \u2014 ${
|
|
290558
|
-
`Verify it \u2014 ${
|
|
290559
|
-
`Register it \u2014 ${
|
|
291071
|
+
`Connect your database \u2014 ${import_picocolors31.default.bold("npx ablo connect")} prints the one-time logical-replication setup SQL to run on your Postgres`,
|
|
291072
|
+
`Verify it \u2014 ${import_picocolors31.default.bold("npx ablo connect check")} walks wal_level, the publication, the role, and replica identity, with the exact fix for anything missing`,
|
|
291073
|
+
`Register it \u2014 ${import_picocolors31.default.bold("npx ablo connect register")} tells Ablo to start replicating; your app keeps writing through your own backend while Ablo tails the WAL`
|
|
290560
291074
|
] : [
|
|
290561
|
-
`Provision your DB: ${
|
|
291075
|
+
`Provision your DB: ${import_picocolors31.default.bold("npx ablo migrate")} (creates your Ablo-model tables + the adapter tables; keep your own migrations for everything else), then mount ${import_picocolors31.default.bold(`${abloDir}/data-source.ts`)} at ${import_picocolors31.default.bold("/api/ablo/source")}`
|
|
290562
291076
|
],
|
|
290563
291077
|
...framework === "nextjs" ? [
|
|
290564
|
-
`Wrap ${
|
|
291078
|
+
`Wrap ${import_picocolors31.default.bold((0, import_node_path6.join)(layout.appBase, "layout.tsx"))} in ${import_picocolors31.default.bold("<Providers>")} (${(0, import_node_path6.join)(layout.appBase, "providers.tsx")}) and add your auth to ${import_picocolors31.default.bold((0, import_node_path6.join)(layout.appBase, "api", "ablo-session", "route.ts"))}`
|
|
290565
291079
|
] : [],
|
|
290566
|
-
`Run ${
|
|
291080
|
+
`Run ${import_picocolors31.default.bold(`${packageManager2} run dev`)} and open two browser tabs \u2014 changes sync in real-time`,
|
|
290567
291081
|
...agent ? [
|
|
290568
|
-
`Run ${
|
|
290569
|
-
`Run ${
|
|
291082
|
+
`Run ${import_picocolors31.default.bold(`npx tsx ${abloDir}/agent.ts`)} \u2014 an AI teammate edits the same records`,
|
|
291083
|
+
`Run ${import_picocolors31.default.bold("npx ablo logs")} to watch human + agent commits stream by`
|
|
290570
291084
|
] : []
|
|
290571
291085
|
];
|
|
290572
291086
|
Me(steps.map((step, index) => `${index + 1}. ${step}`).join("\n"), "Next steps");
|
|
@@ -290574,26 +291088,26 @@ Move them, reconcile Ablo manually, or rerun after they match the generated scaf
|
|
|
290574
291088
|
if (existingKey) {
|
|
290575
291089
|
await ensureInitProject(opts);
|
|
290576
291090
|
Se(
|
|
290577
|
-
`Already authorized ${
|
|
291091
|
+
`Already authorized ${import_picocolors31.default.dim(`(${existingKey.slice(0, 11)}\u2026)`)}. Run ${import_picocolors31.default.bold("npx ablo dev")} next. ${import_picocolors31.default.dim("Docs:")} https://abloatai.com/docs`
|
|
290578
291092
|
);
|
|
290579
291093
|
return initResult;
|
|
290580
291094
|
}
|
|
290581
291095
|
if (interactive && opts.login) {
|
|
290582
291096
|
const loginNow = await ye({ message: "Log in now? (opens your browser)", initialValue: true });
|
|
290583
291097
|
if (!pD(loginNow) && loginNow) {
|
|
290584
|
-
Se(`${
|
|
291098
|
+
Se(`${import_picocolors31.default.dim("Docs:")} https://abloatai.com/docs`);
|
|
290585
291099
|
await login();
|
|
290586
291100
|
await ensureInitProject(opts);
|
|
290587
291101
|
return initResult;
|
|
290588
291102
|
}
|
|
290589
291103
|
}
|
|
290590
|
-
Se(`Run ${
|
|
291104
|
+
Se(`Run ${import_picocolors31.default.bold("npx ablo login")} when ready. ${import_picocolors31.default.dim("Docs:")} https://abloatai.com/docs`);
|
|
290591
291105
|
return initResult;
|
|
290592
291106
|
}
|
|
290593
291107
|
|
|
290594
291108
|
// src/index.ts
|
|
290595
291109
|
var LOGO = `
|
|
290596
|
-
${brand("ablo")} ${
|
|
291110
|
+
${brand("ablo")} ${import_picocolors32.default.dim("sync engine")}
|
|
290597
291111
|
`;
|
|
290598
291112
|
var HANDLERS = {
|
|
290599
291113
|
setup: (argv) => runSetup(argv),
|
|
@@ -290609,6 +291123,7 @@ var HANDLERS = {
|
|
|
290609
291123
|
whoami: (argv) => whoami([...argv]),
|
|
290610
291124
|
doctor: (argv) => doctor([...argv]),
|
|
290611
291125
|
logs: (argv) => logs([...argv]),
|
|
291126
|
+
claims: (argv) => claims([...argv]),
|
|
290612
291127
|
webhooks: (argv) => webhooks([...argv]),
|
|
290613
291128
|
check: (argv) => check([...argv]),
|
|
290614
291129
|
docs: (argv) => docs([...argv]),
|
|
@@ -290626,7 +291141,7 @@ async function runDev(argv) {
|
|
|
290626
291141
|
const devArgs = [...argv];
|
|
290627
291142
|
const oneShot = devArgs.includes("--no-watch");
|
|
290628
291143
|
console.log(
|
|
290629
|
-
|
|
291144
|
+
import_picocolors32.default.dim(
|
|
290630
291145
|
oneShot ? " `ablo dev --no-watch` prepares this Git branch and pushes once." : " `ablo dev` prepares this Git branch and watches the schema."
|
|
290631
291146
|
)
|
|
290632
291147
|
);
|
|
@@ -290644,7 +291159,7 @@ async function runPush2(argv) {
|
|
|
290644
291159
|
}
|
|
290645
291160
|
function runRenamedSchema(argv) {
|
|
290646
291161
|
const forwarded = argv.slice(1).join(" ");
|
|
290647
|
-
console.error(` ${
|
|
291162
|
+
console.error(` ${import_picocolors32.default.red("\u2717")} \`ablo schema push\` was renamed to \`${brand("ablo push")}\`.`);
|
|
290648
291163
|
console.error(` Run \`ablo push${forwarded ? " " + forwarded : ""}\` instead.`);
|
|
290649
291164
|
process.exitCode = 1;
|
|
290650
291165
|
}
|
|
@@ -290654,7 +291169,7 @@ async function main() {
|
|
|
290654
291169
|
const argv = process.argv.slice(3);
|
|
290655
291170
|
if (!command && raw !== void 0 && raw !== "help" && !raw.startsWith("-")) {
|
|
290656
291171
|
const suggestion = suggestCommand(raw);
|
|
290657
|
-
throw new
|
|
291172
|
+
throw new import_errors26.AbloValidationError(
|
|
290658
291173
|
`\`${raw}\` isn't an ablo command.` + (suggestion ? ` Did you mean \`ablo ${suggestion}\`?` : " Run `ablo help --all` to see every command."),
|
|
290659
291174
|
{ code: "cli_invalid_arguments" }
|
|
290660
291175
|
);
|
|
@@ -290695,7 +291210,7 @@ function printCoreHelp() {
|
|
|
290695
291210
|
const width = Math.max(...rows.map((r2) => r2.run.length)) + 4;
|
|
290696
291211
|
console.log(LOGO);
|
|
290697
291212
|
for (const group of CORE_GROUPS) {
|
|
290698
|
-
console.log(` ${
|
|
291213
|
+
console.log(` ${import_picocolors32.default.bold(group)}`);
|
|
290699
291214
|
const printed = group === "More" ? [...coreRows(group), ...extra] : coreRows(group);
|
|
290700
291215
|
for (const row of printed) console.log(` npx ablo ${row.run.padEnd(width)}${row.does}`);
|
|
290701
291216
|
console.log();
|
|
@@ -290704,7 +291219,7 @@ function printCoreHelp() {
|
|
|
290704
291219
|
}
|
|
290705
291220
|
function printSchemaReminder() {
|
|
290706
291221
|
console.log(
|
|
290707
|
-
|
|
291222
|
+
import_picocolors32.default.dim(` Edit ${import_picocolors32.default.bold("ablo/schema.ts")}, then push \u2014 writes to models you haven't pushed fail with `) + import_picocolors32.default.yellow("server_execute_unknown_model") + import_picocolors32.default.dim(".")
|
|
290708
291223
|
);
|
|
290709
291224
|
console.log();
|
|
290710
291225
|
}
|
|
@@ -290714,7 +291229,7 @@ function printFullHelp() {
|
|
|
290714
291229
|
) + 2;
|
|
290715
291230
|
console.log(LOGO);
|
|
290716
291231
|
for (const group of FULL_GROUPS) {
|
|
290717
|
-
console.log(` ${
|
|
291232
|
+
console.log(` ${import_picocolors32.default.bold(group)}`);
|
|
290718
291233
|
for (const row of fullRows(group)) {
|
|
290719
291234
|
console.log(row.does === void 0 ? ` ${" ".repeat(9)}${row.run}` : ` npx ablo ${row.run.padEnd(width)}${row.does}`);
|
|
290720
291235
|
}
|