@abloatai/ablo 0.30.2 → 0.31.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/CHANGELOG.md +26 -12
- package/README.md +12 -14
- package/dist/cli.cjs +277 -214
- package/docs/data-sources.md +133 -96
- package/docs/integration-guide.md +6 -5
- package/docs/quickstart.md +37 -30
- package/docs/schema-contract.md +7 -5
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -1755,9 +1755,9 @@ var init_query = __esm({
|
|
|
1755
1755
|
CLOSE = {};
|
|
1756
1756
|
Query = class extends Promise {
|
|
1757
1757
|
constructor(strings, args, handler, canceller, options = {}) {
|
|
1758
|
-
let
|
|
1758
|
+
let resolve6, reject;
|
|
1759
1759
|
super((a, b4) => {
|
|
1760
|
-
|
|
1760
|
+
resolve6 = a;
|
|
1761
1761
|
reject = b4;
|
|
1762
1762
|
});
|
|
1763
1763
|
this.tagged = Array.isArray(strings.raw);
|
|
@@ -1768,7 +1768,7 @@ var init_query = __esm({
|
|
|
1768
1768
|
this.options = options;
|
|
1769
1769
|
this.state = null;
|
|
1770
1770
|
this.statement = null;
|
|
1771
|
-
this.resolve = (x2) => (this.active = false,
|
|
1771
|
+
this.resolve = (x2) => (this.active = false, resolve6(x2));
|
|
1772
1772
|
this.reject = (x2) => (this.active = false, reject(x2));
|
|
1773
1773
|
this.active = false;
|
|
1774
1774
|
this.cancelled = null;
|
|
@@ -1816,12 +1816,12 @@ var init_query = __esm({
|
|
|
1816
1816
|
if (this.executed && !this.active)
|
|
1817
1817
|
return { done: true };
|
|
1818
1818
|
prev && prev();
|
|
1819
|
-
const promise = new Promise((
|
|
1819
|
+
const promise = new Promise((resolve6, reject) => {
|
|
1820
1820
|
this.cursorFn = (value) => {
|
|
1821
|
-
|
|
1821
|
+
resolve6({ value, done: false });
|
|
1822
1822
|
return new Promise((r2) => prev = r2);
|
|
1823
1823
|
};
|
|
1824
|
-
this.resolve = () => (this.active = false,
|
|
1824
|
+
this.resolve = () => (this.active = false, resolve6({ done: true }));
|
|
1825
1825
|
this.reject = (x2) => (this.active = false, reject(x2));
|
|
1826
1826
|
});
|
|
1827
1827
|
this.execute();
|
|
@@ -2419,12 +2419,12 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
2419
2419
|
x2.on("drain", drain);
|
|
2420
2420
|
return x2;
|
|
2421
2421
|
}
|
|
2422
|
-
async function cancel({ pid, secret },
|
|
2422
|
+
async function cancel({ pid, secret }, resolve6, reject) {
|
|
2423
2423
|
try {
|
|
2424
2424
|
cancelMessage = bytes_default().i32(16).i32(80877102).i32(pid).i32(secret).end(16);
|
|
2425
2425
|
await connect2();
|
|
2426
2426
|
socket.once("error", reject);
|
|
2427
|
-
socket.once("close",
|
|
2427
|
+
socket.once("close", resolve6);
|
|
2428
2428
|
} catch (error2) {
|
|
2429
2429
|
reject(error2);
|
|
2430
2430
|
}
|
|
@@ -3447,7 +3447,7 @@ var init_subscribe = __esm({
|
|
|
3447
3447
|
|
|
3448
3448
|
// node_modules/postgres/src/large.js
|
|
3449
3449
|
function largeObject(sql, oid, mode2 = 131072 | 262144) {
|
|
3450
|
-
return new Promise(async (
|
|
3450
|
+
return new Promise(async (resolve6, reject) => {
|
|
3451
3451
|
await sql.begin(async (sql2) => {
|
|
3452
3452
|
let finish;
|
|
3453
3453
|
!oid && ([{ oid }] = await sql2`select lo_creat(-1) as oid`);
|
|
@@ -3473,7 +3473,7 @@ function largeObject(sql, oid, mode2 = 131072 | 262144) {
|
|
|
3473
3473
|
) seek
|
|
3474
3474
|
`
|
|
3475
3475
|
};
|
|
3476
|
-
|
|
3476
|
+
resolve6(lo);
|
|
3477
3477
|
return new Promise(async (r2) => finish = r2);
|
|
3478
3478
|
async function readable({
|
|
3479
3479
|
highWaterMark = 2048 * 8,
|
|
@@ -3635,8 +3635,8 @@ function Postgres(a, b4) {
|
|
|
3635
3635
|
}
|
|
3636
3636
|
async function reserve() {
|
|
3637
3637
|
const queue = queue_default();
|
|
3638
|
-
const c = open.length ? open.shift() : await new Promise((
|
|
3639
|
-
const query = { reserve:
|
|
3638
|
+
const c = open.length ? open.shift() : await new Promise((resolve6, reject) => {
|
|
3639
|
+
const query = { reserve: resolve6, reject };
|
|
3640
3640
|
queries.push(query);
|
|
3641
3641
|
closed.length && connect2(closed.shift(), query);
|
|
3642
3642
|
});
|
|
@@ -3673,9 +3673,9 @@ function Postgres(a, b4) {
|
|
|
3673
3673
|
let uncaughtError, result;
|
|
3674
3674
|
name && await sql2`savepoint ${sql2(name)}`;
|
|
3675
3675
|
try {
|
|
3676
|
-
result = await new Promise((
|
|
3676
|
+
result = await new Promise((resolve6, reject) => {
|
|
3677
3677
|
const x2 = fn2(sql2);
|
|
3678
|
-
Promise.resolve(Array.isArray(x2) ? Promise.all(x2) : x2).then(
|
|
3678
|
+
Promise.resolve(Array.isArray(x2) ? Promise.all(x2) : x2).then(resolve6, reject);
|
|
3679
3679
|
});
|
|
3680
3680
|
if (uncaughtError)
|
|
3681
3681
|
throw uncaughtError;
|
|
@@ -3732,8 +3732,8 @@ function Postgres(a, b4) {
|
|
|
3732
3732
|
return c.execute(query) ? move(c, busy) : move(c, full);
|
|
3733
3733
|
}
|
|
3734
3734
|
function cancel(query) {
|
|
3735
|
-
return new Promise((
|
|
3736
|
-
query.state ? query.active ? connection_default(options).cancel(query.state,
|
|
3735
|
+
return new Promise((resolve6, reject) => {
|
|
3736
|
+
query.state ? query.active ? connection_default(options).cancel(query.state, resolve6, reject) : query.cancelled = { resolve: resolve6, reject } : (queries.remove(query), query.cancelled = true, query.reject(Errors.generic("57014", "canceling statement due to user request")), resolve6());
|
|
3737
3737
|
});
|
|
3738
3738
|
}
|
|
3739
3739
|
async function end({ timeout = null } = {}) {
|
|
@@ -3752,11 +3752,11 @@ function Postgres(a, b4) {
|
|
|
3752
3752
|
async function close() {
|
|
3753
3753
|
await Promise.all(connections.map((c) => c.end()));
|
|
3754
3754
|
}
|
|
3755
|
-
async function destroy(
|
|
3755
|
+
async function destroy(resolve6) {
|
|
3756
3756
|
await Promise.all(connections.map((c) => c.terminate()));
|
|
3757
3757
|
while (queries.length)
|
|
3758
3758
|
queries.shift().reject(Errors.connection("CONNECTION_DESTROYED", options));
|
|
3759
|
-
|
|
3759
|
+
resolve6();
|
|
3760
3760
|
}
|
|
3761
3761
|
function connect2(c, query) {
|
|
3762
3762
|
move(c, connecting);
|
|
@@ -3955,10 +3955,22 @@ function rewriteDatabaseUrl(ownerUrl, role, password) {
|
|
|
3955
3955
|
url.password = password;
|
|
3956
3956
|
return url.toString();
|
|
3957
3957
|
}
|
|
3958
|
+
function readProjectReplicationUrlWithSource(cwd = process.cwd()) {
|
|
3959
|
+
for (const variable of REPLICATION_URL_VARS) {
|
|
3960
|
+
const value = process.env[variable];
|
|
3961
|
+
if (value) return { url: value, variable };
|
|
3962
|
+
}
|
|
3963
|
+
for (const variable of REPLICATION_URL_VARS) {
|
|
3964
|
+
const value = readProjectEnvValue(variable, cwd);
|
|
3965
|
+
if (value) return { url: value, variable };
|
|
3966
|
+
}
|
|
3967
|
+
return null;
|
|
3968
|
+
}
|
|
3958
3969
|
function readProjectDatabaseUrl(cwd = process.cwd()) {
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3970
|
+
return readProjectReplicationUrlWithSource(cwd)?.url ?? null;
|
|
3971
|
+
}
|
|
3972
|
+
function readProjectAdminDatabaseUrl(cwd = process.cwd()) {
|
|
3973
|
+
return process.env.DATABASE_URL ?? readProjectEnvValue("DATABASE_URL", cwd);
|
|
3962
3974
|
}
|
|
3963
3975
|
function readProjectWriteDatabaseUrl(cwd = process.cwd()) {
|
|
3964
3976
|
const fromEnv = process.env.ABLO_WRITE_DATABASE_URL;
|
|
@@ -3984,7 +3996,7 @@ function readProjectApiKey(cwd = process.cwd()) {
|
|
|
3984
3996
|
}
|
|
3985
3997
|
return null;
|
|
3986
3998
|
}
|
|
3987
|
-
var import_crypto2, import_fs2, import_path;
|
|
3999
|
+
var import_crypto2, import_fs2, import_path, REPLICATION_URL_VARS, DATABASE_URL_REMOVAL_VERSION;
|
|
3988
4000
|
var init_dbRole = __esm({
|
|
3989
4001
|
"src/cli/dbRole.ts"() {
|
|
3990
4002
|
"use strict";
|
|
@@ -3994,6 +4006,8 @@ var init_dbRole = __esm({
|
|
|
3994
4006
|
init_dist2();
|
|
3995
4007
|
import_fs2 = require("fs");
|
|
3996
4008
|
import_path = require("path");
|
|
4009
|
+
REPLICATION_URL_VARS = ["ABLO_REPLICATION_DATABASE_URL", "DATABASE_URL"];
|
|
4010
|
+
DATABASE_URL_REMOVAL_VERSION = "0.32.0";
|
|
3997
4011
|
}
|
|
3998
4012
|
});
|
|
3999
4013
|
|
|
@@ -5426,8 +5440,17 @@ var connectApply_exports = {};
|
|
|
5426
5440
|
__export(connectApply_exports, {
|
|
5427
5441
|
connectApplyPlan: () => connectApplyPlan,
|
|
5428
5442
|
passwordClause: () => passwordClause,
|
|
5443
|
+
postRegistrationOutcome: () => postRegistrationOutcome,
|
|
5429
5444
|
runConnectApply: () => runConnectApply
|
|
5430
5445
|
});
|
|
5446
|
+
function postRegistrationOutcome(input) {
|
|
5447
|
+
if (input.registered) return { exitCode: 0, notice: null };
|
|
5448
|
+
if (!input.rotating) return { exitCode: 1, notice: null };
|
|
5449
|
+
return {
|
|
5450
|
+
exitCode: 1,
|
|
5451
|
+
notice: "The new passwords are set in your database, but Ablo could not be updated with them.\nAblo still holds the previous password, which no longer works \u2014 writes will fail until\nyou re-run `ablo connect --rotate` (each run is idempotent and rotates a fresh password)."
|
|
5452
|
+
};
|
|
5453
|
+
}
|
|
5431
5454
|
function passwordClause(password, mode2) {
|
|
5432
5455
|
return mode2 === "scram-verifier" ? scramSha256Verifier(password) : password.replace(/'/g, "''");
|
|
5433
5456
|
}
|
|
@@ -5496,38 +5519,6 @@ function isPlaintextRefusal(err) {
|
|
|
5496
5519
|
const message = err instanceof Error ? err.message : String(err);
|
|
5497
5520
|
return /plaintext password/i.test(message);
|
|
5498
5521
|
}
|
|
5499
|
-
function persistScopedUrls(vars, cwd = process.cwd()) {
|
|
5500
|
-
const targets = [".env.local", ".env"];
|
|
5501
|
-
const existing = targets.find((name) => (0, import_fs6.existsSync)((0, import_path4.resolve)(cwd, name)));
|
|
5502
|
-
const file = existing ?? ".env.local";
|
|
5503
|
-
const path = (0, import_path4.resolve)(cwd, file);
|
|
5504
|
-
let content = (0, import_fs6.existsSync)(path) ? (0, import_fs6.readFileSync)(path, "utf8") : "";
|
|
5505
|
-
for (const [name, value] of Object.entries(vars)) {
|
|
5506
|
-
const line = `${name}=${value}`;
|
|
5507
|
-
const pattern = new RegExp(`^${name}=.*$`, "m");
|
|
5508
|
-
if (pattern.test(content)) {
|
|
5509
|
-
content = content.replace(pattern, line);
|
|
5510
|
-
} else {
|
|
5511
|
-
content = `${content}${content.endsWith("\n") || content.length === 0 ? "" : "\n"}${line}
|
|
5512
|
-
`;
|
|
5513
|
-
}
|
|
5514
|
-
}
|
|
5515
|
-
if (!(0, import_fs6.existsSync)(path)) {
|
|
5516
|
-
(0, import_fs6.writeFileSync)(path, content, { mode: 384 });
|
|
5517
|
-
} else {
|
|
5518
|
-
(0, import_fs6.writeFileSync)(path, content);
|
|
5519
|
-
}
|
|
5520
|
-
const gitignorePath = (0, import_path4.resolve)(cwd, ".gitignore");
|
|
5521
|
-
const gitignore = (0, import_fs6.existsSync)(gitignorePath) ? (0, import_fs6.readFileSync)(gitignorePath, "utf8") : "";
|
|
5522
|
-
if (!/^\.env(\.local|\*|\.\*)?$/m.test(gitignore)) {
|
|
5523
|
-
(0, import_fs6.appendFileSync)(
|
|
5524
|
-
gitignorePath,
|
|
5525
|
-
`${gitignore.endsWith("\n") || gitignore.length === 0 ? "" : "\n"}.env.local
|
|
5526
|
-
`
|
|
5527
|
-
);
|
|
5528
|
-
}
|
|
5529
|
-
return file;
|
|
5530
|
-
}
|
|
5531
5522
|
function printPlan2(steps, showSql) {
|
|
5532
5523
|
console.log(` This sets up your database for Ablo:
|
|
5533
5524
|
`);
|
|
@@ -5578,16 +5569,38 @@ async function executePlan(sql, steps, rebuildPlaintext) {
|
|
|
5578
5569
|
return { walDeferred };
|
|
5579
5570
|
}
|
|
5580
5571
|
async function runConnectApply(args) {
|
|
5581
|
-
const
|
|
5572
|
+
const rotating = args.rotate;
|
|
5573
|
+
const verb = rotating ? "connect --rotate" : "connect --apply";
|
|
5574
|
+
const adminUrl = args.url ?? readProjectAdminDatabaseUrl();
|
|
5582
5575
|
if (!adminUrl) {
|
|
5583
5576
|
console.error(
|
|
5584
|
-
import_picocolors6.default.red(" No
|
|
5577
|
+
import_picocolors6.default.red(" No admin connection string.") + import_picocolors6.default.dim(` Pass ${import_picocolors6.default.bold("--url <admin-conn>")} (or set ${import_picocolors6.default.bold("DATABASE_URL")}) and re-run.`)
|
|
5578
|
+
);
|
|
5579
|
+
process.exit(1);
|
|
5580
|
+
}
|
|
5581
|
+
const adminSource = args.url ? "--url" : "DATABASE_URL";
|
|
5582
|
+
let target = "your database";
|
|
5583
|
+
try {
|
|
5584
|
+
const parsed = new URL(adminUrl);
|
|
5585
|
+
target = `${parsed.host}${parsed.pathname === "/" ? "" : parsed.pathname}`;
|
|
5586
|
+
} catch {
|
|
5587
|
+
}
|
|
5588
|
+
const apiKey = resolveApiKey();
|
|
5589
|
+
if (!apiKey) {
|
|
5590
|
+
console.error(
|
|
5591
|
+
import_picocolors6.default.red(" Not logged in.") + import_picocolors6.default.dim(
|
|
5592
|
+
` Run ${import_picocolors6.default.bold("ablo login")} (or set ${import_picocolors6.default.bold("ABLO_API_KEY")}) so Ablo knows which project to register this database for.`
|
|
5593
|
+
)
|
|
5585
5594
|
);
|
|
5586
5595
|
process.exit(1);
|
|
5587
5596
|
}
|
|
5588
5597
|
console.log(
|
|
5589
5598
|
`
|
|
5590
|
-
${brand("ablo")} ${import_picocolors6.default.dim(
|
|
5599
|
+
${brand("ablo")} ${import_picocolors6.default.dim(verb)} ${import_picocolors6.default.dim(rotating ? "re-key the scoped roles" : "set up your database for Ablo")}
|
|
5600
|
+
`
|
|
5601
|
+
);
|
|
5602
|
+
console.log(
|
|
5603
|
+
` ${import_picocolors6.default.dim("\u2192")} ${import_picocolors6.default.bold(target)}${adminSource === "DATABASE_URL" ? import_picocolors6.default.dim(" (admin via DATABASE_URL)") : ""}
|
|
5591
5604
|
`
|
|
5592
5605
|
);
|
|
5593
5606
|
const admin = src_default(adminUrl, { max: 1, prepare: false, connect_timeout: 10, onnotice: () => {
|
|
@@ -5604,7 +5617,7 @@ async function runConnectApply(args) {
|
|
|
5604
5617
|
if (!capability || !(capability.rolsuper || capability.rolcreaterole)) {
|
|
5605
5618
|
await admin.end({ timeout: 2 });
|
|
5606
5619
|
console.error(
|
|
5607
|
-
import_picocolors6.default.red(` ${capability?.rolname ?? "This role"} can't create roles.`) + import_picocolors6.default.dim(` Point
|
|
5620
|
+
import_picocolors6.default.red(` ${capability?.rolname ?? "This role"} can't create roles.`) + import_picocolors6.default.dim(` Point ${import_picocolors6.default.bold("--url")} at your owner/admin connection and re-run.`)
|
|
5608
5621
|
);
|
|
5609
5622
|
process.exit(1);
|
|
5610
5623
|
}
|
|
@@ -5631,7 +5644,7 @@ async function runConnectApply(args) {
|
|
|
5631
5644
|
process.exit(1);
|
|
5632
5645
|
}
|
|
5633
5646
|
const proceed = await ye({
|
|
5634
|
-
message: `
|
|
5647
|
+
message: rotating ? `Re-key Ablo's roles on ${target}?` : `Provision Ablo on ${target}?`,
|
|
5635
5648
|
initialValue: true
|
|
5636
5649
|
});
|
|
5637
5650
|
if (pD(proceed) || !proceed) {
|
|
@@ -5659,49 +5672,55 @@ async function runConnectApply(args) {
|
|
|
5659
5672
|
const writeRole = args.writeRole && args.writeRole.length > 0 ? args.writeRole : ABLO_WRITE_ROLE;
|
|
5660
5673
|
const replicationUrl = rewriteDatabaseUrl(adminUrl, role, replicationPassword);
|
|
5661
5674
|
const writeUrl = rewriteDatabaseUrl(adminUrl, writeRole, writePassword);
|
|
5662
|
-
|
|
5663
|
-
|
|
5664
|
-
|
|
5665
|
-
});
|
|
5666
|
-
console.log(
|
|
5667
|
-
`
|
|
5668
|
-
${import_picocolors6.default.green("\u2713")} Roles created \u2014 ${import_picocolors6.default.bold("DATABASE_URL")} + ${import_picocolors6.default.bold("ABLO_WRITE_DATABASE_URL")} updated in ${import_picocolors6.default.bold(where)}.
|
|
5669
|
-
`
|
|
5670
|
-
);
|
|
5671
|
-
const verifier = src_default(replicationUrl, { max: 1, prepare: false, connect_timeout: 10, onnotice: () => {
|
|
5672
|
-
} });
|
|
5673
|
-
let items;
|
|
5674
|
-
try {
|
|
5675
|
-
items = await probeReadiness(verifier);
|
|
5676
|
-
} catch {
|
|
5677
|
-
await verifier.end({ timeout: 2 }).catch(() => void 0);
|
|
5678
|
-
console.log(import_picocolors6.default.dim(` Verify when reachable: `) + import_picocolors6.default.cyan("npx ablo connect --check") + "\n");
|
|
5679
|
-
process.exit(0);
|
|
5680
|
-
}
|
|
5681
|
-
await verifier.end({ timeout: 2 });
|
|
5682
|
-
const failed = items.filter((i) => !i.ok);
|
|
5675
|
+
console.log(`
|
|
5676
|
+
${import_picocolors6.default.green("\u2713")} Roles ${rotating ? "re-keyed" : "created"}.
|
|
5677
|
+
`);
|
|
5683
5678
|
if (walDeferred) {
|
|
5684
5679
|
console.log(
|
|
5685
5680
|
` ${import_picocolors6.default.yellow("!")} One step left \u2014 logical replication needs a restart.
|
|
5686
5681
|
` + import_picocolors6.default.dim(` RDS/Aurora: set rds.logical_replication=1, reboot. Neon: enable it in settings.
|
|
5687
5682
|
`) + `
|
|
5688
|
-
Then: ${import_picocolors6.default.cyan(
|
|
5683
|
+
Then re-run: ${import_picocolors6.default.cyan(`npx ablo ${verb}`)}
|
|
5689
5684
|
`
|
|
5690
5685
|
);
|
|
5691
5686
|
process.exit(0);
|
|
5692
5687
|
}
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5688
|
+
const verifier = src_default(replicationUrl, { max: 1, prepare: false, connect_timeout: 10, onnotice: () => {
|
|
5689
|
+
} });
|
|
5690
|
+
let items;
|
|
5691
|
+
try {
|
|
5692
|
+
items = await probeReadiness(verifier);
|
|
5693
|
+
} catch {
|
|
5694
|
+
items = null;
|
|
5695
|
+
console.log(import_picocolors6.default.dim(` Couldn't verify from here; Ablo will validate from its own network.
|
|
5696
|
+
`));
|
|
5697
|
+
}
|
|
5698
|
+
await verifier.end({ timeout: 2 }).catch(() => void 0);
|
|
5699
|
+
const failed = items?.filter((i) => !i.ok) ?? [];
|
|
5700
|
+
if (failed.length > 0) {
|
|
5697
5701
|
for (const item of failed) console.log(` ${import_picocolors6.default.yellow("!")} ${item.label}`);
|
|
5698
5702
|
console.log(`
|
|
5699
|
-
${import_picocolors6.default.dim("Resolve, then")} ${import_picocolors6.default.cyan(
|
|
5703
|
+
${import_picocolors6.default.dim("Resolve, then re-run")} ${import_picocolors6.default.cyan(`npx ablo ${verb}`)}
|
|
5700
5704
|
`);
|
|
5705
|
+
process.exit(1);
|
|
5701
5706
|
}
|
|
5702
|
-
process.
|
|
5707
|
+
const apiUrl2 = (process.env.ABLO_API_URL ?? DEFAULT_URL).replace(/\/+$/, "");
|
|
5708
|
+
const registered = await registerDirectDataSource({
|
|
5709
|
+
apiUrl: apiUrl2,
|
|
5710
|
+
apiKey,
|
|
5711
|
+
replicationUrl,
|
|
5712
|
+
writeUrl,
|
|
5713
|
+
route: args.route
|
|
5714
|
+
});
|
|
5715
|
+
const outcome = postRegistrationOutcome({ rotating, registered });
|
|
5716
|
+
if (outcome.notice) {
|
|
5717
|
+
console.error(`
|
|
5718
|
+
${import_picocolors6.default.red(outcome.notice.split("\n").join("\n "))}
|
|
5719
|
+
`);
|
|
5720
|
+
}
|
|
5721
|
+
process.exit(outcome.exitCode);
|
|
5703
5722
|
}
|
|
5704
|
-
var import_picocolors6
|
|
5723
|
+
var import_picocolors6;
|
|
5705
5724
|
var init_connectApply = __esm({
|
|
5706
5725
|
"src/cli/connectApply.ts"() {
|
|
5707
5726
|
"use strict";
|
|
@@ -5709,10 +5728,10 @@ var init_connectApply = __esm({
|
|
|
5709
5728
|
import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
5710
5729
|
init_src();
|
|
5711
5730
|
init_dist2();
|
|
5712
|
-
import_fs6 = require("fs");
|
|
5713
|
-
import_path4 = require("path");
|
|
5714
5731
|
init_connect();
|
|
5715
5732
|
init_dbRole();
|
|
5733
|
+
init_config();
|
|
5734
|
+
init_push();
|
|
5716
5735
|
init_theme();
|
|
5717
5736
|
}
|
|
5718
5737
|
});
|
|
@@ -5722,6 +5741,8 @@ function parseConnectArgs(argv) {
|
|
|
5722
5741
|
let check2 = false;
|
|
5723
5742
|
let register = false;
|
|
5724
5743
|
let apply2 = false;
|
|
5744
|
+
let rotate = false;
|
|
5745
|
+
let url;
|
|
5725
5746
|
let yes = false;
|
|
5726
5747
|
let showSql = false;
|
|
5727
5748
|
let auditInfra = false;
|
|
@@ -5741,6 +5762,12 @@ function parseConnectArgs(argv) {
|
|
|
5741
5762
|
case "--apply":
|
|
5742
5763
|
apply2 = true;
|
|
5743
5764
|
break;
|
|
5765
|
+
case "--rotate":
|
|
5766
|
+
rotate = true;
|
|
5767
|
+
break;
|
|
5768
|
+
case "--url":
|
|
5769
|
+
url = argv[++i] ?? url;
|
|
5770
|
+
break;
|
|
5744
5771
|
case "--yes":
|
|
5745
5772
|
case "-y":
|
|
5746
5773
|
yes = true;
|
|
@@ -5782,7 +5809,7 @@ function parseConnectArgs(argv) {
|
|
|
5782
5809
|
code: "cli_invalid_arguments"
|
|
5783
5810
|
});
|
|
5784
5811
|
}
|
|
5785
|
-
return { check: check2, register, apply: apply2, yes, showSql, auditInfra, tables, role, writeRole, route };
|
|
5812
|
+
return { check: check2, register, apply: apply2, rotate, url, yes, showSql, auditInfra, tables, role, writeRole, route };
|
|
5786
5813
|
}
|
|
5787
5814
|
function quoteIdent(id) {
|
|
5788
5815
|
return `"${id.replace(/"/g, '""')}"`;
|
|
@@ -6086,15 +6113,36 @@ async function auditTenantSyncInfra(sql) {
|
|
|
6086
6113
|
}
|
|
6087
6114
|
return artifacts;
|
|
6088
6115
|
}
|
|
6089
|
-
function requireDatabaseUrl(verb) {
|
|
6090
|
-
const
|
|
6091
|
-
if (!
|
|
6116
|
+
function requireDatabaseUrl(verb, opts) {
|
|
6117
|
+
const resolved = readProjectReplicationUrlWithSource();
|
|
6118
|
+
if (!resolved) {
|
|
6092
6119
|
console.error(
|
|
6093
|
-
import_picocolors7.default.red(" No
|
|
6120
|
+
import_picocolors7.default.red(" No replication connection found (checked process env, .env.local, .env).") + import_picocolors7.default.dim(
|
|
6121
|
+
` Set ${import_picocolors7.default.bold("ABLO_REPLICATION_DATABASE_URL")} to the ${ABLO_REPLICATION_ROLE} connection printed by ${import_picocolors7.default.bold("ablo connect")}, then re-run ${import_picocolors7.default.bold(`ablo connect ${verb}`)}.`
|
|
6122
|
+
)
|
|
6094
6123
|
);
|
|
6095
6124
|
process.exit(1);
|
|
6096
6125
|
}
|
|
6097
|
-
|
|
6126
|
+
if (resolved.variable === "DATABASE_URL") {
|
|
6127
|
+
console.warn(
|
|
6128
|
+
import_picocolors7.default.yellow(` ! Falling back to ${import_picocolors7.default.bold("DATABASE_URL")} for the replication role \u2014 deprecated,`) + import_picocolors7.default.dim(
|
|
6129
|
+
` removed in ${DATABASE_URL_REMOVAL_VERSION}.
|
|
6130
|
+
If this is your app's own connection string, this is NOT validating the ${import_picocolors7.default.bold(ABLO_REPLICATION_ROLE)} role.
|
|
6131
|
+
Set ${import_picocolors7.default.bold("ABLO_REPLICATION_DATABASE_URL")} to the connection ${import_picocolors7.default.bold("ablo connect")} printed.
|
|
6132
|
+
`
|
|
6133
|
+
)
|
|
6134
|
+
);
|
|
6135
|
+
if (!(opts?.allowDeprecatedFallback ?? false)) {
|
|
6136
|
+
console.error(
|
|
6137
|
+
import_picocolors7.default.red(` Refusing to ${verb.replace(/^--/, "")} against a ${import_picocolors7.default.bold("DATABASE_URL")} fallback.`) + import_picocolors7.default.dim(
|
|
6138
|
+
` Set ${import_picocolors7.default.bold("ABLO_REPLICATION_DATABASE_URL")} explicitly and re-run. (${import_picocolors7.default.bold("ablo connect --check")} still accepts the fallback so you can inspect it.)
|
|
6139
|
+
`
|
|
6140
|
+
)
|
|
6141
|
+
);
|
|
6142
|
+
process.exit(1);
|
|
6143
|
+
}
|
|
6144
|
+
}
|
|
6145
|
+
return resolved.url;
|
|
6098
6146
|
}
|
|
6099
6147
|
function requireWriteDatabaseUrl(verb) {
|
|
6100
6148
|
const dbUrl = readProjectWriteDatabaseUrl();
|
|
@@ -6192,7 +6240,7 @@ async function runRemoteCheck(dbUrl, writeDbUrl, localReason) {
|
|
|
6192
6240
|
process.exit(1);
|
|
6193
6241
|
}
|
|
6194
6242
|
async function runCheck() {
|
|
6195
|
-
const dbUrl = requireDatabaseUrl("--check");
|
|
6243
|
+
const dbUrl = requireDatabaseUrl("--check", { allowDeprecatedFallback: true });
|
|
6196
6244
|
const writeDbUrl = requireWriteDatabaseUrl("--check");
|
|
6197
6245
|
console.log(`
|
|
6198
6246
|
${brand("ablo")} ${import_picocolors7.default.dim("connect --check")} ${import_picocolors7.default.dim("direct-write + WAL readiness")}
|
|
@@ -6269,34 +6317,44 @@ async function runRegister(args) {
|
|
|
6269
6317
|
process.exit(1);
|
|
6270
6318
|
}
|
|
6271
6319
|
const apiUrl2 = (process.env.ABLO_API_URL ?? DEFAULT_URL).replace(/\/+$/, "");
|
|
6320
|
+
const registered = await registerDirectDataSource({
|
|
6321
|
+
apiUrl: apiUrl2,
|
|
6322
|
+
apiKey,
|
|
6323
|
+
replicationUrl: dbUrl,
|
|
6324
|
+
writeUrl: writeDbUrl,
|
|
6325
|
+
route: args.route
|
|
6326
|
+
});
|
|
6327
|
+
process.exit(registered ? 0 : 1);
|
|
6328
|
+
}
|
|
6329
|
+
async function registerDirectDataSource(opts) {
|
|
6272
6330
|
let res;
|
|
6273
6331
|
try {
|
|
6274
|
-
res = await fetch(registerEndpoint(
|
|
6332
|
+
res = await fetch(registerEndpoint(opts.apiUrl), {
|
|
6275
6333
|
method: "POST",
|
|
6276
|
-
headers: { "content-type": "application/json", authorization: `Bearer ${apiKey}` },
|
|
6334
|
+
headers: { "content-type": "application/json", authorization: `Bearer ${opts.apiKey}` },
|
|
6277
6335
|
body: JSON.stringify({
|
|
6278
6336
|
connection: "direct",
|
|
6279
|
-
connectionString:
|
|
6280
|
-
writeConnectionString:
|
|
6281
|
-
route:
|
|
6337
|
+
connectionString: opts.replicationUrl,
|
|
6338
|
+
writeConnectionString: opts.writeUrl,
|
|
6339
|
+
route: opts.route
|
|
6282
6340
|
})
|
|
6283
6341
|
});
|
|
6284
6342
|
} catch (err) {
|
|
6285
6343
|
console.error(import_picocolors7.default.red(`
|
|
6286
|
-
Couldn't reach ${
|
|
6344
|
+
Couldn't reach ${opts.apiUrl}: ${err instanceof Error ? err.message : String(err)}
|
|
6287
6345
|
`));
|
|
6288
|
-
|
|
6346
|
+
return false;
|
|
6289
6347
|
}
|
|
6290
6348
|
if (res.ok) {
|
|
6291
6349
|
const body2 = await res.json().catch(() => ({}));
|
|
6292
|
-
const statusNote = body2.status === "active" ? `${
|
|
6350
|
+
const statusNote = body2.status === "active" ? `${opts.route}, active` : opts.route;
|
|
6293
6351
|
console.log(
|
|
6294
6352
|
`
|
|
6295
6353
|
${import_picocolors7.default.green("\u2713")} Registered${body2.host ? ` ${import_picocolors7.default.dim(body2.host)}` : ""}${body2.id ? ` ${import_picocolors7.default.dim(`(${body2.id})`)}` : ""} as a direct DataSource (${statusNote}).
|
|
6296
6354
|
Customer COMMIT is durable acceptance; correlated WAL promotes queued writes to confirmed.
|
|
6297
6355
|
`
|
|
6298
6356
|
);
|
|
6299
|
-
|
|
6357
|
+
return true;
|
|
6300
6358
|
}
|
|
6301
6359
|
const body = await res.json().catch(() => ({}));
|
|
6302
6360
|
const code = body.code ?? body.error?.code;
|
|
@@ -6327,10 +6385,10 @@ async function runRegister(args) {
|
|
|
6327
6385
|
);
|
|
6328
6386
|
}
|
|
6329
6387
|
console.error();
|
|
6330
|
-
|
|
6388
|
+
return false;
|
|
6331
6389
|
}
|
|
6332
6390
|
async function runAuditInfra() {
|
|
6333
|
-
const dbUrl = requireDatabaseUrl("--audit-infra");
|
|
6391
|
+
const dbUrl = requireDatabaseUrl("--audit-infra", { allowDeprecatedFallback: true });
|
|
6334
6392
|
const sql = src_default(dbUrl, { max: 1, prepare: false, onnotice: () => {
|
|
6335
6393
|
} });
|
|
6336
6394
|
let artifacts;
|
|
@@ -6370,7 +6428,7 @@ async function connect(argv) {
|
|
|
6370
6428
|
console.error(import_picocolors7.default.red(` ${err instanceof Error ? err.message : String(err)}`));
|
|
6371
6429
|
process.exit(1);
|
|
6372
6430
|
}
|
|
6373
|
-
if (args.apply) {
|
|
6431
|
+
if (args.apply || args.rotate) {
|
|
6374
6432
|
const { runConnectApply: runConnectApply2 } = await Promise.resolve().then(() => (init_connectApply(), connectApply_exports));
|
|
6375
6433
|
await runConnectApply2(args);
|
|
6376
6434
|
return;
|
|
@@ -6429,16 +6487,21 @@ var init_connect = __esm({
|
|
|
6429
6487
|
orders it with external changes, and confirms it. Your Postgres remains authoritative.
|
|
6430
6488
|
|
|
6431
6489
|
Usage:
|
|
6432
|
-
npx ablo connect --apply Set it up
|
|
6490
|
+
npx ablo connect --apply Set it up end to end: create the roles, publish, register
|
|
6491
|
+
npx ablo connect --url <admin-conn> Admin connection for --apply/--rotate (else DATABASE_URL)
|
|
6492
|
+
npx ablo connect --rotate New passwords for both scoped roles, then re-register
|
|
6433
6493
|
npx ablo connect Print the exact setup SQL instead of running it
|
|
6434
6494
|
npx ablo connect --tables a,b,c Publish only these tables (default: all tables)
|
|
6435
6495
|
npx ablo connect --role <name> Name the replication role (default: ablo_replicator)
|
|
6436
6496
|
npx ablo connect --write-role <name> Name the DML role (default: ablo_writer)
|
|
6437
6497
|
npx ablo connect --route <route> public-allowlist | privatelink | peering | vpn
|
|
6438
|
-
npx ablo connect --check Validate
|
|
6498
|
+
npx ablo connect --check Validate the scoped roles (ABLO_REPLICATION_DATABASE_URL + ABLO_WRITE_DATABASE_URL)
|
|
6439
6499
|
npx ablo connect --register Register both scoped credentials as one direct DataSource
|
|
6440
6500
|
npx ablo connect --audit-infra Read-only Stage 5 audit for deprecated Ablo sync tables/types
|
|
6441
6501
|
|
|
6502
|
+
--apply registers with Ablo directly; the admin credential is used only on this
|
|
6503
|
+
machine and never persisted. Your app holds only ABLO_API_KEY.
|
|
6504
|
+
|
|
6442
6505
|
--apply also takes --yes (skip the confirm) and --show-sql (show the exact statements).`;
|
|
6443
6506
|
}
|
|
6444
6507
|
});
|
|
@@ -131336,7 +131399,7 @@ ${lanes.join("\n")}
|
|
|
131336
131399
|
}
|
|
131337
131400
|
}
|
|
131338
131401
|
function createImportCallExpressionAMD(arg, containsLexicalThis) {
|
|
131339
|
-
const
|
|
131402
|
+
const resolve6 = factory2.createUniqueName("resolve");
|
|
131340
131403
|
const reject = factory2.createUniqueName("reject");
|
|
131341
131404
|
const parameters = [
|
|
131342
131405
|
factory2.createParameterDeclaration(
|
|
@@ -131345,7 +131408,7 @@ ${lanes.join("\n")}
|
|
|
131345
131408
|
/*dotDotDotToken*/
|
|
131346
131409
|
void 0,
|
|
131347
131410
|
/*name*/
|
|
131348
|
-
|
|
131411
|
+
resolve6
|
|
131349
131412
|
),
|
|
131350
131413
|
factory2.createParameterDeclaration(
|
|
131351
131414
|
/*modifiers*/
|
|
@@ -131362,7 +131425,7 @@ ${lanes.join("\n")}
|
|
|
131362
131425
|
factory2.createIdentifier("require"),
|
|
131363
131426
|
/*typeArguments*/
|
|
131364
131427
|
void 0,
|
|
131365
|
-
[factory2.createArrayLiteralExpression([arg || factory2.createOmittedExpression()]),
|
|
131428
|
+
[factory2.createArrayLiteralExpression([arg || factory2.createOmittedExpression()]), resolve6, reject]
|
|
131366
131429
|
)
|
|
131367
131430
|
)
|
|
131368
131431
|
]);
|
|
@@ -217971,8 +218034,8 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
|
|
|
217971
218034
|
installPackage(options) {
|
|
217972
218035
|
this.packageInstallId++;
|
|
217973
218036
|
const request2 = { kind: "installPackage", ...options, id: this.packageInstallId };
|
|
217974
|
-
const promise = new Promise((
|
|
217975
|
-
(this.packageInstalledPromise ?? (this.packageInstalledPromise = /* @__PURE__ */ new Map())).set(this.packageInstallId, { resolve:
|
|
218037
|
+
const promise = new Promise((resolve6, reject) => {
|
|
218038
|
+
(this.packageInstalledPromise ?? (this.packageInstalledPromise = /* @__PURE__ */ new Map())).set(this.packageInstallId, { resolve: resolve6, reject });
|
|
217976
218039
|
});
|
|
217977
218040
|
this.installer.send(request2);
|
|
217978
218041
|
return promise;
|
|
@@ -220245,7 +220308,7 @@ var require_path_browserify = __commonJS({
|
|
|
220245
220308
|
}
|
|
220246
220309
|
var posix = {
|
|
220247
220310
|
// path.resolve([from ...], to)
|
|
220248
|
-
resolve: function
|
|
220311
|
+
resolve: function resolve6() {
|
|
220249
220312
|
var resolvedPath = "";
|
|
220250
220313
|
var resolvedAbsolute = false;
|
|
220251
220314
|
var cwd;
|
|
@@ -225145,41 +225208,41 @@ var require_queue = __commonJS({
|
|
|
225145
225208
|
queue.drained = drained;
|
|
225146
225209
|
return queue;
|
|
225147
225210
|
function push2(value) {
|
|
225148
|
-
var p2 = new Promise(function(
|
|
225211
|
+
var p2 = new Promise(function(resolve6, reject) {
|
|
225149
225212
|
pushCb(value, function(err, result) {
|
|
225150
225213
|
if (err) {
|
|
225151
225214
|
reject(err);
|
|
225152
225215
|
return;
|
|
225153
225216
|
}
|
|
225154
|
-
|
|
225217
|
+
resolve6(result);
|
|
225155
225218
|
});
|
|
225156
225219
|
});
|
|
225157
225220
|
p2.catch(noop3);
|
|
225158
225221
|
return p2;
|
|
225159
225222
|
}
|
|
225160
225223
|
function unshift(value) {
|
|
225161
|
-
var p2 = new Promise(function(
|
|
225224
|
+
var p2 = new Promise(function(resolve6, reject) {
|
|
225162
225225
|
unshiftCb(value, function(err, result) {
|
|
225163
225226
|
if (err) {
|
|
225164
225227
|
reject(err);
|
|
225165
225228
|
return;
|
|
225166
225229
|
}
|
|
225167
|
-
|
|
225230
|
+
resolve6(result);
|
|
225168
225231
|
});
|
|
225169
225232
|
});
|
|
225170
225233
|
p2.catch(noop3);
|
|
225171
225234
|
return p2;
|
|
225172
225235
|
}
|
|
225173
225236
|
function drained() {
|
|
225174
|
-
var p2 = new Promise(function(
|
|
225237
|
+
var p2 = new Promise(function(resolve6) {
|
|
225175
225238
|
process.nextTick(function() {
|
|
225176
225239
|
if (queue.idle()) {
|
|
225177
|
-
|
|
225240
|
+
resolve6();
|
|
225178
225241
|
} else {
|
|
225179
225242
|
var previousDrain = queue.drain;
|
|
225180
225243
|
queue.drain = function() {
|
|
225181
225244
|
if (typeof previousDrain === "function") previousDrain();
|
|
225182
|
-
|
|
225245
|
+
resolve6();
|
|
225183
225246
|
queue.drain = previousDrain;
|
|
225184
225247
|
};
|
|
225185
225248
|
}
|
|
@@ -225676,9 +225739,9 @@ var require_stream3 = __commonJS({
|
|
|
225676
225739
|
});
|
|
225677
225740
|
}
|
|
225678
225741
|
_getStat(filepath) {
|
|
225679
|
-
return new Promise((
|
|
225742
|
+
return new Promise((resolve6, reject) => {
|
|
225680
225743
|
this._stat(filepath, this._fsStatSettings, (error, stats) => {
|
|
225681
|
-
return error === null ?
|
|
225744
|
+
return error === null ? resolve6(stats) : reject(error);
|
|
225682
225745
|
});
|
|
225683
225746
|
});
|
|
225684
225747
|
}
|
|
@@ -225703,10 +225766,10 @@ var require_async5 = __commonJS({
|
|
|
225703
225766
|
this._readerStream = new stream_1.default(this._settings);
|
|
225704
225767
|
}
|
|
225705
225768
|
dynamic(root, options) {
|
|
225706
|
-
return new Promise((
|
|
225769
|
+
return new Promise((resolve6, reject) => {
|
|
225707
225770
|
this._walkAsync(root, options, (error, entries) => {
|
|
225708
225771
|
if (error === null) {
|
|
225709
|
-
|
|
225772
|
+
resolve6(entries);
|
|
225710
225773
|
} else {
|
|
225711
225774
|
reject(error);
|
|
225712
225775
|
}
|
|
@@ -225716,10 +225779,10 @@ var require_async5 = __commonJS({
|
|
|
225716
225779
|
async static(patterns, options) {
|
|
225717
225780
|
const entries = [];
|
|
225718
225781
|
const stream = this._readerStream.static(patterns, options);
|
|
225719
|
-
return new Promise((
|
|
225782
|
+
return new Promise((resolve6, reject) => {
|
|
225720
225783
|
stream.once("error", reject);
|
|
225721
225784
|
stream.on("data", (entry) => entries.push(entry));
|
|
225722
|
-
stream.once("end", () =>
|
|
225785
|
+
stream.once("end", () => resolve6(entries));
|
|
225723
225786
|
});
|
|
225724
225787
|
}
|
|
225725
225788
|
};
|
|
@@ -258625,12 +258688,12 @@ type XMLHttpRequestResponseType = "" | "arraybuffer" | "blob" | "document" | "js
|
|
|
258625
258688
|
};
|
|
258626
258689
|
var NodeRuntimeFileSystem = class {
|
|
258627
258690
|
delete(path2) {
|
|
258628
|
-
return new Promise((
|
|
258691
|
+
return new Promise((resolve6, reject) => {
|
|
258629
258692
|
fs__namespace.rm(path2, { recursive: true }, (err) => {
|
|
258630
258693
|
if (err)
|
|
258631
258694
|
reject(err);
|
|
258632
258695
|
else
|
|
258633
|
-
|
|
258696
|
+
resolve6();
|
|
258634
258697
|
});
|
|
258635
258698
|
});
|
|
258636
258699
|
}
|
|
@@ -258649,12 +258712,12 @@ type XMLHttpRequestResponseType = "" | "arraybuffer" | "blob" | "document" | "js
|
|
|
258649
258712
|
}));
|
|
258650
258713
|
}
|
|
258651
258714
|
readFile(filePath, encoding = "utf-8") {
|
|
258652
|
-
return new Promise((
|
|
258715
|
+
return new Promise((resolve6, reject) => {
|
|
258653
258716
|
fs__namespace.readFile(filePath, encoding, (err, data) => {
|
|
258654
258717
|
if (err)
|
|
258655
258718
|
reject(err);
|
|
258656
258719
|
else
|
|
258657
|
-
|
|
258720
|
+
resolve6(data);
|
|
258658
258721
|
});
|
|
258659
258722
|
});
|
|
258660
258723
|
}
|
|
@@ -258662,12 +258725,12 @@ type XMLHttpRequestResponseType = "" | "arraybuffer" | "blob" | "document" | "js
|
|
|
258662
258725
|
return fs__namespace.readFileSync(filePath, encoding);
|
|
258663
258726
|
}
|
|
258664
258727
|
async writeFile(filePath, fileText) {
|
|
258665
|
-
await new Promise((
|
|
258728
|
+
await new Promise((resolve6, reject) => {
|
|
258666
258729
|
fs__namespace.writeFile(filePath, fileText, (err) => {
|
|
258667
258730
|
if (err)
|
|
258668
258731
|
reject(err);
|
|
258669
258732
|
else
|
|
258670
|
-
|
|
258733
|
+
resolve6();
|
|
258671
258734
|
});
|
|
258672
258735
|
});
|
|
258673
258736
|
}
|
|
@@ -258681,12 +258744,12 @@ type XMLHttpRequestResponseType = "" | "arraybuffer" | "blob" | "document" | "js
|
|
|
258681
258744
|
fs__namespace.mkdirSync(dirPath, { recursive: true });
|
|
258682
258745
|
}
|
|
258683
258746
|
move(srcPath, destPath) {
|
|
258684
|
-
return new Promise((
|
|
258747
|
+
return new Promise((resolve6, reject) => {
|
|
258685
258748
|
fs__namespace.rename(srcPath, destPath, (err) => {
|
|
258686
258749
|
if (err)
|
|
258687
258750
|
reject(err);
|
|
258688
258751
|
else
|
|
258689
|
-
|
|
258752
|
+
resolve6();
|
|
258690
258753
|
});
|
|
258691
258754
|
});
|
|
258692
258755
|
}
|
|
@@ -258694,12 +258757,12 @@ type XMLHttpRequestResponseType = "" | "arraybuffer" | "blob" | "document" | "js
|
|
|
258694
258757
|
fs__namespace.renameSync(srcPath, destPath);
|
|
258695
258758
|
}
|
|
258696
258759
|
copy(srcPath, destPath) {
|
|
258697
|
-
return new Promise((
|
|
258760
|
+
return new Promise((resolve6, reject) => {
|
|
258698
258761
|
fs__namespace.copyFile(srcPath, destPath, (err) => {
|
|
258699
258762
|
if (err)
|
|
258700
258763
|
reject(err);
|
|
258701
258764
|
else
|
|
258702
|
-
|
|
258765
|
+
resolve6();
|
|
258703
258766
|
});
|
|
258704
258767
|
});
|
|
258705
258768
|
}
|
|
@@ -258707,15 +258770,15 @@ type XMLHttpRequestResponseType = "" | "arraybuffer" | "blob" | "document" | "js
|
|
|
258707
258770
|
fs__namespace.copyFileSync(srcPath, destPath);
|
|
258708
258771
|
}
|
|
258709
258772
|
stat(path2) {
|
|
258710
|
-
return new Promise((
|
|
258773
|
+
return new Promise((resolve6, reject) => {
|
|
258711
258774
|
fs__namespace.stat(path2, (err, stat) => {
|
|
258712
258775
|
if (err) {
|
|
258713
258776
|
if (err.code === "ENOENT" || err.code === "ENOTDIR")
|
|
258714
|
-
|
|
258777
|
+
resolve6(void 0);
|
|
258715
258778
|
else
|
|
258716
258779
|
reject(err);
|
|
258717
258780
|
} else {
|
|
258718
|
-
|
|
258781
|
+
resolve6(stat);
|
|
258719
258782
|
}
|
|
258720
258783
|
});
|
|
258721
258784
|
});
|
|
@@ -282394,8 +282457,8 @@ Node text: ${this.#forgottenText}`;
|
|
|
282394
282457
|
init_cjs_shims();
|
|
282395
282458
|
init_dist2();
|
|
282396
282459
|
var import_picocolors21 = __toESM(require_picocolors(), 1);
|
|
282397
|
-
var
|
|
282398
|
-
var
|
|
282460
|
+
var import_fs12 = require("fs");
|
|
282461
|
+
var import_path7 = require("path");
|
|
282399
282462
|
var import_child_process3 = require("child_process");
|
|
282400
282463
|
|
|
282401
282464
|
// src/cli/migrate.ts
|
|
@@ -282511,7 +282574,7 @@ async function applyStatements(dbUrl, targetSchema, statements, concurrent = [])
|
|
|
282511
282574
|
if (pg.code === import_schema3.PG_LOCK_NOT_AVAILABLE && attempt < maxLockAttempts) {
|
|
282512
282575
|
const backoffMs = (0, import_schema3.ddlLockRetryBackoffMs)(attempt);
|
|
282513
282576
|
log.warn("schema change blocked by a lock; backing off and retrying", { targetSchema, attempt, backoffMs });
|
|
282514
|
-
await new Promise((
|
|
282577
|
+
await new Promise((resolve6) => setTimeout(resolve6, backoffMs));
|
|
282515
282578
|
continue;
|
|
282516
282579
|
}
|
|
282517
282580
|
throw err;
|
|
@@ -282588,8 +282651,8 @@ init_push();
|
|
|
282588
282651
|
// src/cli/generate.ts
|
|
282589
282652
|
init_cjs_shims();
|
|
282590
282653
|
init_errors();
|
|
282591
|
-
var
|
|
282592
|
-
var
|
|
282654
|
+
var import_fs6 = require("fs");
|
|
282655
|
+
var import_path4 = require("path");
|
|
282593
282656
|
var import_picocolors8 = __toESM(require_picocolors(), 1);
|
|
282594
282657
|
var import_schema4 = require("@abloatai/ablo/schema");
|
|
282595
282658
|
init_push();
|
|
@@ -282635,9 +282698,9 @@ async function generate(argv) {
|
|
|
282635
282698
|
console.error(import_picocolors8.default.red(` ${err instanceof Error ? err.message : String(err)}`));
|
|
282636
282699
|
process.exit(1);
|
|
282637
282700
|
}
|
|
282638
|
-
const abs = (0,
|
|
282639
|
-
(0,
|
|
282640
|
-
(0,
|
|
282701
|
+
const abs = (0, import_path4.resolve)(process.cwd(), args.out);
|
|
282702
|
+
(0, import_fs6.mkdirSync)((0, import_path4.dirname)(abs), { recursive: true });
|
|
282703
|
+
(0, import_fs6.writeFileSync)(abs, source);
|
|
282641
282704
|
console.log(` ${import_picocolors8.default.green("\u2713")} Generated types \u2192 ${import_picocolors8.default.bold(args.out)}`);
|
|
282642
282705
|
}
|
|
282643
282706
|
|
|
@@ -282647,8 +282710,8 @@ init_errors();
|
|
|
282647
282710
|
init_credentialPolicy();
|
|
282648
282711
|
var import_picocolors9 = __toESM(require_picocolors(), 1);
|
|
282649
282712
|
init_dist2();
|
|
282650
|
-
var
|
|
282651
|
-
var
|
|
282713
|
+
var import_fs7 = require("fs");
|
|
282714
|
+
var import_path5 = require("path");
|
|
282652
282715
|
var import_schema5 = require("@abloatai/ablo/schema");
|
|
282653
282716
|
init_push();
|
|
282654
282717
|
init_config();
|
|
@@ -282709,34 +282772,34 @@ function classifyKey(apiKey, activeMode) {
|
|
|
282709
282772
|
};
|
|
282710
282773
|
}
|
|
282711
282774
|
function wireEnvLocal(apiKey, cwd = process.cwd()) {
|
|
282712
|
-
const envPath = (0,
|
|
282775
|
+
const envPath = (0, import_path5.resolve)(cwd, ".env.local");
|
|
282713
282776
|
const line = `ABLO_API_KEY=${apiKey}`;
|
|
282714
282777
|
let action;
|
|
282715
|
-
if (!(0,
|
|
282716
|
-
(0,
|
|
282778
|
+
if (!(0, import_fs7.existsSync)(envPath)) {
|
|
282779
|
+
(0, import_fs7.writeFileSync)(envPath, `${line}
|
|
282717
282780
|
`, { mode: 384 });
|
|
282718
282781
|
action = `Created ${import_picocolors9.default.bold(".env.local")} with ${import_picocolors9.default.bold("ABLO_API_KEY")}`;
|
|
282719
282782
|
} else {
|
|
282720
|
-
const content = (0,
|
|
282783
|
+
const content = (0, import_fs7.readFileSync)(envPath, "utf8");
|
|
282721
282784
|
const match = /^ABLO_API_KEY=(.*)$/m.exec(content);
|
|
282722
282785
|
const existing = match?.[1] ?? "";
|
|
282723
282786
|
if (!match) {
|
|
282724
|
-
(0,
|
|
282787
|
+
(0, import_fs7.appendFileSync)(envPath, `${content.endsWith("\n") || content.length === 0 ? "" : "\n"}${line}
|
|
282725
282788
|
`);
|
|
282726
282789
|
action = `Added ${import_picocolors9.default.bold("ABLO_API_KEY")} to ${import_picocolors9.default.bold(".env.local")}`;
|
|
282727
282790
|
} else if (existing === apiKey) {
|
|
282728
282791
|
action = `${import_picocolors9.default.bold(".env.local")} already has this key`;
|
|
282729
282792
|
} else {
|
|
282730
|
-
(0,
|
|
282793
|
+
(0, import_fs7.writeFileSync)(envPath, content.replace(/^ABLO_API_KEY=.*$/m, line));
|
|
282731
282794
|
action = `Updated ${import_picocolors9.default.bold("ABLO_API_KEY")} in ${import_picocolors9.default.bold(".env.local")} ${import_picocolors9.default.dim(`(was ${existing.slice(0, 12)}\u2026)`)}`;
|
|
282732
282795
|
}
|
|
282733
282796
|
}
|
|
282734
|
-
const gitignorePath = (0,
|
|
282735
|
-
const gitignore = (0,
|
|
282797
|
+
const gitignorePath = (0, import_path5.resolve)(cwd, ".gitignore");
|
|
282798
|
+
const gitignore = (0, import_fs7.existsSync)(gitignorePath) ? (0, import_fs7.readFileSync)(gitignorePath, "utf8") : "";
|
|
282736
282799
|
const ignored = /^(\.env\.local|\.env\*|\.env\.\*|\.env.*)$/m.test(gitignore);
|
|
282737
282800
|
let gitignoreNote = "";
|
|
282738
282801
|
if (!ignored) {
|
|
282739
|
-
(0,
|
|
282802
|
+
(0, import_fs7.writeFileSync)(
|
|
282740
282803
|
gitignorePath,
|
|
282741
282804
|
`${gitignore.endsWith("\n") || gitignore.length === 0 ? gitignore : `${gitignore}
|
|
282742
282805
|
`}.env.local
|
|
@@ -282838,12 +282901,12 @@ async function dev(argv) {
|
|
|
282838
282901
|
}
|
|
282839
282902
|
console.log(` Your app is wired for the sandbox.`);
|
|
282840
282903
|
if (!args.watch) return;
|
|
282841
|
-
const abs = (0,
|
|
282904
|
+
const abs = (0, import_path5.resolve)(process.cwd(), args.schemaPath);
|
|
282842
282905
|
console.log(` ${import_picocolors9.default.dim(`watching ${args.schemaPath} \u2026 (Ctrl-C to stop)`)}
|
|
282843
282906
|
`);
|
|
282844
282907
|
let timer2 = null;
|
|
282845
282908
|
let pushing = false;
|
|
282846
|
-
const watcher = (0,
|
|
282909
|
+
const watcher = (0, import_fs7.watch)(abs, () => {
|
|
282847
282910
|
if (timer2) clearTimeout(timer2);
|
|
282848
282911
|
timer2 = setTimeout(() => {
|
|
282849
282912
|
void rePush();
|
|
@@ -283534,7 +283597,7 @@ async function logs(argv) {
|
|
|
283534
283597
|
|
|
283535
283598
|
// src/cli/webhooks.ts
|
|
283536
283599
|
init_cjs_shims();
|
|
283537
|
-
var
|
|
283600
|
+
var import_fs8 = require("fs");
|
|
283538
283601
|
var import_picocolors14 = __toESM(require_picocolors(), 1);
|
|
283539
283602
|
init_credentialPolicy();
|
|
283540
283603
|
init_config();
|
|
@@ -283600,11 +283663,11 @@ async function api(apiKey, method, path, body) {
|
|
|
283600
283663
|
return await res.json();
|
|
283601
283664
|
}
|
|
283602
283665
|
function writeSecretToEnv(secret) {
|
|
283603
|
-
const file = (0,
|
|
283666
|
+
const file = (0, import_fs8.existsSync)(".env.local") ? ".env.local" : (0, import_fs8.existsSync)(".env") ? ".env" : ".env.local";
|
|
283604
283667
|
const line = `${ENV_KEY}=${secret}`;
|
|
283605
283668
|
let next;
|
|
283606
|
-
if ((0,
|
|
283607
|
-
const existing = (0,
|
|
283669
|
+
if ((0, import_fs8.existsSync)(file)) {
|
|
283670
|
+
const existing = (0, import_fs8.readFileSync)(file, "utf-8");
|
|
283608
283671
|
next = new RegExp(`^${ENV_KEY}=.*$`, "m").test(existing) ? existing.replace(new RegExp(`^${ENV_KEY}=.*$`, "m"), line) : `${existing.replace(/\n*$/, "")}
|
|
283609
283672
|
${line}
|
|
283610
283673
|
`;
|
|
@@ -283612,7 +283675,7 @@ ${line}
|
|
|
283612
283675
|
next = `${line}
|
|
283613
283676
|
`;
|
|
283614
283677
|
}
|
|
283615
|
-
(0,
|
|
283678
|
+
(0, import_fs8.writeFileSync)(file, next);
|
|
283616
283679
|
return file;
|
|
283617
283680
|
}
|
|
283618
283681
|
function printEndpoint(e2) {
|
|
@@ -284028,7 +284091,7 @@ init_cjs_shims();
|
|
|
284028
284091
|
init_errors();
|
|
284029
284092
|
var import_picocolors17 = __toESM(require_picocolors(), 1);
|
|
284030
284093
|
init_src();
|
|
284031
|
-
var
|
|
284094
|
+
var import_fs9 = require("fs");
|
|
284032
284095
|
init_theme();
|
|
284033
284096
|
var DEFAULT_OUT2 = "ablo/schema.ts";
|
|
284034
284097
|
var DEFAULT_IMPORT = "@abloatai/ablo/schema";
|
|
@@ -284148,7 +284211,7 @@ async function pull(argv) {
|
|
|
284148
284211
|
console.error(import_picocolors17.default.red(` No database.`) + import_picocolors17.default.dim(` Set ${import_picocolors17.default.bold("DATABASE_URL")} to the Postgres to pull from.`));
|
|
284149
284212
|
process.exit(1);
|
|
284150
284213
|
}
|
|
284151
|
-
if ((0,
|
|
284214
|
+
if ((0, import_fs9.existsSync)(args.out) && !args.force) {
|
|
284152
284215
|
console.error(
|
|
284153
284216
|
import_picocolors17.default.red(` ${args.out} already exists.`) + import_picocolors17.default.dim(` Re-run with ${import_picocolors17.default.bold("--force")} to overwrite.`)
|
|
284154
284217
|
);
|
|
@@ -284170,7 +284233,7 @@ async function pull(argv) {
|
|
|
284170
284233
|
);
|
|
284171
284234
|
process.exit(1);
|
|
284172
284235
|
}
|
|
284173
|
-
(0,
|
|
284236
|
+
(0, import_fs9.writeFileSync)(args.out, result.source);
|
|
284174
284237
|
console.log(` ${import_picocolors17.default.green("\u2713")} wrote ${import_picocolors17.default.bold(args.out)} ${import_picocolors17.default.dim(`(${result.models.length} models)`)}`);
|
|
284175
284238
|
console.log(` ${import_picocolors17.default.dim(`models: ${result.models.join(", ")}`)}`);
|
|
284176
284239
|
if (result.skipped > 0) {
|
|
@@ -284187,7 +284250,7 @@ async function pull(argv) {
|
|
|
284187
284250
|
init_cjs_shims();
|
|
284188
284251
|
init_errors();
|
|
284189
284252
|
var import_picocolors18 = __toESM(require_picocolors(), 1);
|
|
284190
|
-
var
|
|
284253
|
+
var import_fs10 = require("fs");
|
|
284191
284254
|
init_theme();
|
|
284192
284255
|
|
|
284193
284256
|
// src/cli/schemaIr.ts
|
|
@@ -284474,13 +284537,13 @@ async function prismaPull(argv) {
|
|
|
284474
284537
|
console.error(import_picocolors18.default.red(` ${err instanceof Error ? err.message : String(err)}`));
|
|
284475
284538
|
process.exit(1);
|
|
284476
284539
|
}
|
|
284477
|
-
if (!(0,
|
|
284540
|
+
if (!(0, import_fs10.existsSync)(args.schema)) {
|
|
284478
284541
|
console.error(
|
|
284479
284542
|
import_picocolors18.default.red(` No Prisma schema at ${import_picocolors18.default.bold(args.schema)}.`) + import_picocolors18.default.dim(` Pass a path: ${import_picocolors18.default.bold("ablo pull prisma <path>")}.`)
|
|
284480
284543
|
);
|
|
284481
284544
|
process.exit(1);
|
|
284482
284545
|
}
|
|
284483
|
-
if ((0,
|
|
284546
|
+
if ((0, import_fs10.existsSync)(args.out) && !args.force) {
|
|
284484
284547
|
console.error(
|
|
284485
284548
|
import_picocolors18.default.red(` ${args.out} already exists.`) + import_picocolors18.default.dim(` Re-run with ${import_picocolors18.default.bold("--force")} to overwrite.`)
|
|
284486
284549
|
);
|
|
@@ -284491,7 +284554,7 @@ async function prismaPull(argv) {
|
|
|
284491
284554
|
`);
|
|
284492
284555
|
let result;
|
|
284493
284556
|
try {
|
|
284494
|
-
const src = (0,
|
|
284557
|
+
const src = (0, import_fs10.readFileSync)(args.schema, "utf8");
|
|
284495
284558
|
result = buildSchemaSourceFromPrisma({ src, importPath: args.importPath });
|
|
284496
284559
|
} catch (err) {
|
|
284497
284560
|
console.error(import_picocolors18.default.red(` Couldn't parse the schema: ${err instanceof Error ? err.message : String(err)}`));
|
|
@@ -284503,7 +284566,7 @@ async function prismaPull(argv) {
|
|
|
284503
284566
|
);
|
|
284504
284567
|
process.exit(1);
|
|
284505
284568
|
}
|
|
284506
|
-
(0,
|
|
284569
|
+
(0, import_fs10.writeFileSync)(args.out, result.source);
|
|
284507
284570
|
console.log(` ${import_picocolors18.default.green("\u2713")} wrote ${import_picocolors18.default.bold(args.out)} ${import_picocolors18.default.dim(`(${result.models.length} models)`)}`);
|
|
284508
284571
|
console.log(` ${import_picocolors18.default.dim(`models: ${result.models.join(", ")}`)}`);
|
|
284509
284572
|
if (result.skipped.length > 0) {
|
|
@@ -284521,8 +284584,8 @@ async function prismaPull(argv) {
|
|
|
284521
284584
|
init_cjs_shims();
|
|
284522
284585
|
var import_picocolors19 = __toESM(require_picocolors(), 1);
|
|
284523
284586
|
init_errors();
|
|
284524
|
-
var
|
|
284525
|
-
var
|
|
284587
|
+
var import_fs11 = require("fs");
|
|
284588
|
+
var import_path6 = require("path");
|
|
284526
284589
|
init_theme();
|
|
284527
284590
|
var DEFAULT_OUT4 = "ablo/schema.ts";
|
|
284528
284591
|
var DEFAULT_IMPORT3 = "@abloatai/ablo/schema";
|
|
@@ -284650,7 +284713,7 @@ function parseDrizzlePullArgs(argv) {
|
|
|
284650
284713
|
async function loadModule(path) {
|
|
284651
284714
|
const { createJiti } = await import("jiti");
|
|
284652
284715
|
const jiti = createJiti(process.cwd());
|
|
284653
|
-
const mod = await jiti.import((0,
|
|
284716
|
+
const mod = await jiti.import((0, import_path6.resolve)(path));
|
|
284654
284717
|
return mod;
|
|
284655
284718
|
}
|
|
284656
284719
|
async function drizzlePull(argv) {
|
|
@@ -284667,11 +284730,11 @@ async function drizzlePull(argv) {
|
|
|
284667
284730
|
);
|
|
284668
284731
|
process.exit(1);
|
|
284669
284732
|
}
|
|
284670
|
-
if (!(0,
|
|
284733
|
+
if (!(0, import_fs11.existsSync)(args.schema)) {
|
|
284671
284734
|
console.error(import_picocolors19.default.red(` No file at ${import_picocolors19.default.bold(args.schema)}.`));
|
|
284672
284735
|
process.exit(1);
|
|
284673
284736
|
}
|
|
284674
|
-
if ((0,
|
|
284737
|
+
if ((0, import_fs11.existsSync)(args.out) && !args.force) {
|
|
284675
284738
|
console.error(
|
|
284676
284739
|
import_picocolors19.default.red(` ${args.out} already exists.`) + import_picocolors19.default.dim(` Re-run with ${import_picocolors19.default.bold("--force")} to overwrite.`)
|
|
284677
284740
|
);
|
|
@@ -284696,7 +284759,7 @@ async function drizzlePull(argv) {
|
|
|
284696
284759
|
);
|
|
284697
284760
|
process.exit(1);
|
|
284698
284761
|
}
|
|
284699
|
-
(0,
|
|
284762
|
+
(0, import_fs11.writeFileSync)(args.out, result.source);
|
|
284700
284763
|
console.log(` ${import_picocolors19.default.green("\u2713")} wrote ${import_picocolors19.default.bold(args.out)} ${import_picocolors19.default.dim(`(${result.models.length} models)`)}`);
|
|
284701
284764
|
console.log(` ${import_picocolors19.default.dim(`models: ${result.models.join(", ")}`)}`);
|
|
284702
284765
|
if (result.skipped.length > 0) {
|
|
@@ -284971,7 +285034,7 @@ async function ensureInitProject(opts) {
|
|
|
284971
285034
|
const slug = opts.project ?? projectSlugFromPackageName(
|
|
284972
285035
|
(() => {
|
|
284973
285036
|
try {
|
|
284974
|
-
return JSON.parse((0,
|
|
285037
|
+
return JSON.parse((0, import_fs12.readFileSync)("package.json", "utf-8")).name;
|
|
284975
285038
|
} catch {
|
|
284976
285039
|
return void 0;
|
|
284977
285040
|
}
|
|
@@ -284988,7 +285051,7 @@ async function ensureInitProject(opts) {
|
|
|
284988
285051
|
function detectOrm(override) {
|
|
284989
285052
|
if (override === "prisma" || override === "drizzle" || override === "none") return override;
|
|
284990
285053
|
try {
|
|
284991
|
-
const pkg = JSON.parse((0,
|
|
285054
|
+
const pkg = JSON.parse((0, import_fs12.readFileSync)("package.json", "utf-8"));
|
|
284992
285055
|
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
284993
285056
|
if (deps["@prisma/client"] || deps.prisma) return "prisma";
|
|
284994
285057
|
if (deps["drizzle-orm"]) return "drizzle";
|
|
@@ -284997,8 +285060,8 @@ function detectOrm(override) {
|
|
|
284997
285060
|
return "none";
|
|
284998
285061
|
}
|
|
284999
285062
|
function detectNextLayout() {
|
|
285000
|
-
const useSrc = (0,
|
|
285001
|
-
return useSrc ? { appBase: (0,
|
|
285063
|
+
const useSrc = (0, import_fs12.existsSync)((0, import_path7.join)("src", "app")) || !(0, import_fs12.existsSync)("app") && (0, import_fs12.existsSync)("src");
|
|
285064
|
+
return useSrc ? { appBase: (0, import_path7.join)("src", "app"), aliasBase: "src" } : { appBase: "app", aliasBase: "." };
|
|
285002
285065
|
}
|
|
285003
285066
|
async function chooseOption(name, flagValue, fallback, allowed, interactive, prompt) {
|
|
285004
285067
|
if (flagValue !== void 0) {
|
|
@@ -285024,7 +285087,7 @@ async function init(args = []) {
|
|
|
285024
285087
|
const opts = parseInitArgs(args);
|
|
285025
285088
|
const interactive = Boolean(process.stdin.isTTY) && !opts.yes && !process.env.CI;
|
|
285026
285089
|
Ie(`${brand("ablo")} ${import_picocolors21.default.dim("sync engine")}`);
|
|
285027
|
-
if (!(0,
|
|
285090
|
+
if (!(0, import_fs12.existsSync)("package.json")) {
|
|
285028
285091
|
xe("No package.json found. Run this from your project root.");
|
|
285029
285092
|
process.exit(1);
|
|
285030
285093
|
}
|
|
@@ -285093,8 +285156,8 @@ async function init(args = []) {
|
|
|
285093
285156
|
);
|
|
285094
285157
|
}
|
|
285095
285158
|
const layout = framework === "nextjs" ? detectNextLayout() : { appBase: "app", aliasBase: "." };
|
|
285096
|
-
const abloDir = (0,
|
|
285097
|
-
(0,
|
|
285159
|
+
const abloDir = (0, import_path7.join)(layout.aliasBase, "ablo");
|
|
285160
|
+
(0, import_fs12.mkdirSync)(abloDir, { recursive: true });
|
|
285098
285161
|
const created = [];
|
|
285099
285162
|
let schemaSource = generateSchema();
|
|
285100
285163
|
let schemaNote = "";
|
|
@@ -285120,28 +285183,28 @@ async function init(args = []) {
|
|
|
285120
285183
|
}
|
|
285121
285184
|
}
|
|
285122
285185
|
}
|
|
285123
|
-
(0,
|
|
285186
|
+
(0, import_fs12.writeFileSync)((0, import_path7.join)(abloDir, "schema.ts"), schemaSource);
|
|
285124
285187
|
created.push(`${abloDir}/schema.ts${schemaNote}`);
|
|
285125
|
-
(0,
|
|
285188
|
+
(0, import_fs12.writeFileSync)((0, import_path7.join)(abloDir, "index.ts"), generateSyncConfig(auth));
|
|
285126
285189
|
created.push(`${abloDir}/index.ts`);
|
|
285127
|
-
(0,
|
|
285190
|
+
(0, import_fs12.writeFileSync)((0, import_path7.join)(abloDir, "register.ts"), generateRegister());
|
|
285128
285191
|
created.push(`${abloDir}/register.ts`);
|
|
285129
285192
|
const orm = detectOrm(opts.orm);
|
|
285130
285193
|
if (storage === "endpoint") {
|
|
285131
|
-
(0,
|
|
285194
|
+
(0, import_fs12.writeFileSync)((0, import_path7.join)(abloDir, "data-source.ts"), generateDataSource(orm));
|
|
285132
285195
|
created.push(`${abloDir}/data-source.ts${orm === "drizzle" ? " (Drizzle)" : " (Prisma)"}`);
|
|
285133
285196
|
}
|
|
285134
285197
|
const envFile = framework === "nextjs" ? ".env.local" : ".env";
|
|
285135
285198
|
const resolvedKey = process.env.ABLO_API_KEY ? void 0 : resolveApiKey("sandbox");
|
|
285136
285199
|
const wireRealKey = envFile === ".env.local" && Boolean(resolvedKey);
|
|
285137
285200
|
const envBody = generateEnv(storage, { includeApiKey: !wireRealKey });
|
|
285138
|
-
if (!(0,
|
|
285139
|
-
(0,
|
|
285201
|
+
if (!(0, import_fs12.existsSync)(envFile)) {
|
|
285202
|
+
(0, import_fs12.writeFileSync)(envFile, envBody);
|
|
285140
285203
|
created.push(envFile);
|
|
285141
285204
|
} else {
|
|
285142
|
-
const existing = (0,
|
|
285205
|
+
const existing = (0, import_fs12.readFileSync)(envFile, "utf-8");
|
|
285143
285206
|
if (!existing.includes("ABLO_")) {
|
|
285144
|
-
(0,
|
|
285207
|
+
(0, import_fs12.writeFileSync)(envFile, existing + "\n" + envBody);
|
|
285145
285208
|
created.push(`${envFile} ${import_picocolors21.default.dim("(appended)")}`);
|
|
285146
285209
|
} else {
|
|
285147
285210
|
created.push(`${envFile} ${import_picocolors21.default.dim("(already configured)")}`);
|
|
@@ -285152,26 +285215,26 @@ async function init(args = []) {
|
|
|
285152
285215
|
created.push(`.env.local ${import_picocolors21.default.dim("(ABLO_API_KEY set from your login)")}`);
|
|
285153
285216
|
}
|
|
285154
285217
|
if (agent) {
|
|
285155
|
-
(0,
|
|
285218
|
+
(0, import_fs12.writeFileSync)((0, import_path7.join)(abloDir, "agent.ts"), generateAgent());
|
|
285156
285219
|
created.push(`${abloDir}/agent.ts`);
|
|
285157
285220
|
}
|
|
285158
285221
|
if (framework === "nextjs") {
|
|
285159
285222
|
if (storage === "endpoint") {
|
|
285160
|
-
const webhookDir = (0,
|
|
285161
|
-
(0,
|
|
285162
|
-
(0,
|
|
285223
|
+
const webhookDir = (0, import_path7.join)(layout.appBase, "api", "ablo", "webhooks");
|
|
285224
|
+
(0, import_fs12.mkdirSync)(webhookDir, { recursive: true });
|
|
285225
|
+
(0, import_fs12.writeFileSync)((0, import_path7.join)(webhookDir, "route.ts"), generateWebhookRoute(orm));
|
|
285163
285226
|
created.push(`${webhookDir}/route.ts${orm === "prisma" ? " (Prisma mirror)" : " (add your database write)"}`);
|
|
285164
285227
|
}
|
|
285165
|
-
const providersPath = (0,
|
|
285166
|
-
(0,
|
|
285167
|
-
created.push(`${providersPath} ${import_picocolors21.default.dim(`(wrap ${(0,
|
|
285168
|
-
const sessionDir = (0,
|
|
285169
|
-
(0,
|
|
285170
|
-
(0,
|
|
285171
|
-
created.push(`${(0,
|
|
285228
|
+
const providersPath = (0, import_path7.join)(layout.appBase, "providers.tsx");
|
|
285229
|
+
(0, import_fs12.writeFileSync)(providersPath, generateProviders());
|
|
285230
|
+
created.push(`${providersPath} ${import_picocolors21.default.dim(`(wrap ${(0, import_path7.join)(layout.appBase, "layout.tsx")} in <Providers>)`)}`);
|
|
285231
|
+
const sessionDir = (0, import_path7.join)(layout.appBase, "api", "ablo-session");
|
|
285232
|
+
(0, import_fs12.mkdirSync)(sessionDir, { recursive: true });
|
|
285233
|
+
(0, import_fs12.writeFileSync)((0, import_path7.join)(sessionDir, "route.ts"), generateSessionRoute());
|
|
285234
|
+
created.push(`${(0, import_path7.join)(sessionDir, "route.ts")} ${import_picocolors21.default.dim("(wire your auth)")}`);
|
|
285172
285235
|
}
|
|
285173
285236
|
if (framework !== "vanilla") {
|
|
285174
|
-
(0,
|
|
285237
|
+
(0, import_fs12.writeFileSync)((0, import_path7.join)(abloDir, "TaskList.tsx"), generateComponent());
|
|
285175
285238
|
created.push(`${abloDir}/TaskList.tsx`);
|
|
285176
285239
|
}
|
|
285177
285240
|
Me(created.map((f) => `${import_picocolors21.default.green("\u2713")} ${f}`).join("\n"), "Created");
|
|
@@ -285199,7 +285262,7 @@ async function init(args = []) {
|
|
|
285199
285262
|
`Provision your DB: ${import_picocolors21.default.bold("npx ablo migrate")} (creates your Ablo-model tables + the adapter tables; keep your own migrations for everything else), then mount ${import_picocolors21.default.bold(`${abloDir}/data-source.ts`)} at ${import_picocolors21.default.bold("/api/ablo/source")}`
|
|
285200
285263
|
],
|
|
285201
285264
|
...framework === "nextjs" ? [
|
|
285202
|
-
`Wrap ${import_picocolors21.default.bold((0,
|
|
285265
|
+
`Wrap ${import_picocolors21.default.bold((0, import_path7.join)(layout.appBase, "layout.tsx"))} in ${import_picocolors21.default.bold("<Providers>")} (${(0, import_path7.join)(layout.appBase, "providers.tsx")}) and add your auth to ${import_picocolors21.default.bold((0, import_path7.join)(layout.appBase, "api", "ablo-session", "route.ts"))}`
|
|
285203
285266
|
] : [],
|
|
285204
285267
|
`Run ${import_picocolors21.default.bold(`${pm} run dev`)} and open two browser tabs \u2014 changes sync in real-time`,
|
|
285205
285268
|
...agent ? [
|
|
@@ -285607,9 +285670,9 @@ async function getCurrentUser(): Promise<{ id: string } | null> {
|
|
|
285607
285670
|
`;
|
|
285608
285671
|
}
|
|
285609
285672
|
function detectPackageManager() {
|
|
285610
|
-
if ((0,
|
|
285611
|
-
if ((0,
|
|
285612
|
-
if ((0,
|
|
285673
|
+
if ((0, import_fs12.existsSync)("pnpm-lock.yaml")) return "pnpm";
|
|
285674
|
+
if ((0, import_fs12.existsSync)("yarn.lock")) return "yarn";
|
|
285675
|
+
if ((0, import_fs12.existsSync)("bun.lockb")) return "bun";
|
|
285613
285676
|
return "npm";
|
|
285614
285677
|
}
|
|
285615
285678
|
main().catch((err) => {
|