@abloatai/ablo 0.23.0 → 0.25.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 +33 -0
- package/README.md +42 -33
- package/dist/ai-sdk/coordinated-tool.d.ts +101 -0
- package/dist/ai-sdk/coordinated-tool.js +129 -0
- package/dist/ai-sdk/index.d.ts +42 -0
- package/dist/ai-sdk/index.js +42 -0
- package/dist/cli.cjs +948 -529
- package/dist/client/Ablo.js +4 -0
- package/dist/interfaces/index.d.ts +8 -0
- package/dist/sync/BootstrapHelper.d.ts +16 -0
- package/dist/sync/BootstrapHelper.js +27 -0
- package/dist/sync/schemas.d.ts +1 -0
- package/dist/sync/schemas.js +3 -0
- package/docs/data-sources.md +12 -5
- package/llms.txt +4 -2
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -4850,8 +4850,8 @@ var require_typescript = __commonJS({
|
|
|
4850
4850
|
let count = 0;
|
|
4851
4851
|
if (array !== void 0) {
|
|
4852
4852
|
for (let i = 0; i < array.length; i++) {
|
|
4853
|
-
const
|
|
4854
|
-
if (predicate(
|
|
4853
|
+
const v2 = array[i];
|
|
4854
|
+
if (predicate(v2, i)) {
|
|
4855
4855
|
count++;
|
|
4856
4856
|
}
|
|
4857
4857
|
}
|
|
@@ -4926,12 +4926,12 @@ var require_typescript = __commonJS({
|
|
|
4926
4926
|
function flatten(array) {
|
|
4927
4927
|
const result = [];
|
|
4928
4928
|
for (let i = 0; i < array.length; i++) {
|
|
4929
|
-
const
|
|
4930
|
-
if (
|
|
4931
|
-
if (isArray(
|
|
4932
|
-
addRange(result,
|
|
4929
|
+
const v2 = array[i];
|
|
4930
|
+
if (v2) {
|
|
4931
|
+
if (isArray(v2)) {
|
|
4932
|
+
addRange(result, v2);
|
|
4933
4933
|
} else {
|
|
4934
|
-
result.push(
|
|
4934
|
+
result.push(v2);
|
|
4935
4935
|
}
|
|
4936
4936
|
}
|
|
4937
4937
|
}
|
|
@@ -4941,12 +4941,12 @@ var require_typescript = __commonJS({
|
|
|
4941
4941
|
let result;
|
|
4942
4942
|
if (array !== void 0) {
|
|
4943
4943
|
for (let i = 0; i < array.length; i++) {
|
|
4944
|
-
const
|
|
4945
|
-
if (
|
|
4946
|
-
if (isArray(
|
|
4947
|
-
result = addRange(result,
|
|
4944
|
+
const v2 = mapfn(array[i], i);
|
|
4945
|
+
if (v2) {
|
|
4946
|
+
if (isArray(v2)) {
|
|
4947
|
+
result = addRange(result, v2);
|
|
4948
4948
|
} else {
|
|
4949
|
-
result = append(result,
|
|
4949
|
+
result = append(result, v2);
|
|
4950
4950
|
}
|
|
4951
4951
|
}
|
|
4952
4952
|
}
|
|
@@ -4957,12 +4957,12 @@ var require_typescript = __commonJS({
|
|
|
4957
4957
|
const result = [];
|
|
4958
4958
|
if (array !== void 0) {
|
|
4959
4959
|
for (let i = 0; i < array.length; i++) {
|
|
4960
|
-
const
|
|
4961
|
-
if (
|
|
4962
|
-
if (isArray(
|
|
4963
|
-
addRange(result,
|
|
4960
|
+
const v2 = mapfn(array[i], i);
|
|
4961
|
+
if (v2) {
|
|
4962
|
+
if (isArray(v2)) {
|
|
4963
|
+
addRange(result, v2);
|
|
4964
4964
|
} else {
|
|
4965
|
-
result.push(
|
|
4965
|
+
result.push(v2);
|
|
4966
4966
|
}
|
|
4967
4967
|
}
|
|
4968
4968
|
}
|
|
@@ -5066,9 +5066,9 @@ var require_typescript = __commonJS({
|
|
|
5066
5066
|
pos++;
|
|
5067
5067
|
}
|
|
5068
5068
|
if (start < pos) {
|
|
5069
|
-
const
|
|
5070
|
-
if (
|
|
5071
|
-
result.push(
|
|
5069
|
+
const v2 = mapfn(array.slice(start, pos), previousKey, start, pos);
|
|
5070
|
+
if (v2) {
|
|
5071
|
+
result.push(v2);
|
|
5072
5072
|
}
|
|
5073
5073
|
start = pos;
|
|
5074
5074
|
}
|
|
@@ -5224,11 +5224,11 @@ var require_typescript = __commonJS({
|
|
|
5224
5224
|
let result;
|
|
5225
5225
|
if (array !== void 0) {
|
|
5226
5226
|
for (let i = 0; i < array.length; i++) {
|
|
5227
|
-
const
|
|
5228
|
-
if (result ?? !
|
|
5227
|
+
const v2 = array[i];
|
|
5228
|
+
if (result ?? !v2) {
|
|
5229
5229
|
result ?? (result = array.slice(0, i));
|
|
5230
|
-
if (
|
|
5231
|
-
result.push(
|
|
5230
|
+
if (v2) {
|
|
5231
|
+
result.push(v2);
|
|
5232
5232
|
}
|
|
5233
5233
|
}
|
|
5234
5234
|
}
|
|
@@ -6055,11 +6055,11 @@ var require_typescript = __commonJS({
|
|
|
6055
6055
|
let matchedValue;
|
|
6056
6056
|
let longestMatchPrefixLength = -1;
|
|
6057
6057
|
for (let i = 0; i < values2.length; i++) {
|
|
6058
|
-
const
|
|
6059
|
-
const pattern = getPattern(
|
|
6058
|
+
const v2 = values2[i];
|
|
6059
|
+
const pattern = getPattern(v2);
|
|
6060
6060
|
if (pattern.prefix.length > longestMatchPrefixLength && isPatternMatch(pattern, candidate)) {
|
|
6061
6061
|
longestMatchPrefixLength = pattern.prefix.length;
|
|
6062
|
-
matchedValue =
|
|
6062
|
+
matchedValue = v2;
|
|
6063
6063
|
}
|
|
6064
6064
|
}
|
|
6065
6065
|
return matchedValue;
|
|
@@ -6323,8 +6323,8 @@ Node ${formatSyntaxKind(node.kind)} was unexpected.`,
|
|
|
6323
6323
|
}
|
|
6324
6324
|
Debug2.checkDefined = checkDefined;
|
|
6325
6325
|
function assertEachIsDefined(value, message, stackCrawlMark) {
|
|
6326
|
-
for (const
|
|
6327
|
-
assertIsDefined(
|
|
6326
|
+
for (const v2 of value) {
|
|
6327
|
+
assertIsDefined(v2, message, stackCrawlMark || assertEachIsDefined);
|
|
6328
6328
|
}
|
|
6329
6329
|
}
|
|
6330
6330
|
Debug2.assertEachIsDefined = assertEachIsDefined;
|
|
@@ -7695,7 +7695,7 @@ ${lanes.join("\n")}
|
|
|
7695
7695
|
const meta = { cat: "__metadata", ph: "M", ts: 1e3 * timestamp(), pid: 1, tid: 1 };
|
|
7696
7696
|
fs2.writeSync(
|
|
7697
7697
|
traceFd,
|
|
7698
|
-
"[\n" + [{ name: "process_name", args: { name: "tsc" }, ...meta }, { name: "thread_name", args: { name: "Main" }, ...meta }, { name: "TracingStartedInBrowser", ...meta, cat: "disabled-by-default-devtools.timeline" }].map((
|
|
7698
|
+
"[\n" + [{ name: "process_name", args: { name: "tsc" }, ...meta }, { name: "thread_name", args: { name: "Main" }, ...meta }, { name: "TracingStartedInBrowser", ...meta, cat: "disabled-by-default-devtools.timeline" }].map((v2) => JSON.stringify(v2)).join(",\n")
|
|
7699
7699
|
);
|
|
7700
7700
|
}
|
|
7701
7701
|
tracingEnabled2.startTracing = startTracing2;
|
|
@@ -21820,8 +21820,8 @@ ${lanes.join("\n")}
|
|
|
21820
21820
|
function getSingleInitializerOfVariableStatementOrPropertyDeclaration(node) {
|
|
21821
21821
|
switch (node.kind) {
|
|
21822
21822
|
case 243:
|
|
21823
|
-
const
|
|
21824
|
-
return
|
|
21823
|
+
const v2 = getSingleVariableOfVariableStatement(node);
|
|
21824
|
+
return v2 && v2.initializer;
|
|
21825
21825
|
case 172:
|
|
21826
21826
|
return node.initializer;
|
|
21827
21827
|
case 303:
|
|
@@ -47572,14 +47572,14 @@ ${lanes.join("\n")}
|
|
|
47572
47572
|
const values2 = value.split(",");
|
|
47573
47573
|
switch (opt.element.type) {
|
|
47574
47574
|
case "number":
|
|
47575
|
-
return mapDefined(values2, (
|
|
47575
|
+
return mapDefined(values2, (v2) => validateJsonOptionValue(opt.element, parseInt(v2), errors));
|
|
47576
47576
|
case "string":
|
|
47577
|
-
return mapDefined(values2, (
|
|
47577
|
+
return mapDefined(values2, (v2) => validateJsonOptionValue(opt.element, v2 || "", errors));
|
|
47578
47578
|
case "boolean":
|
|
47579
47579
|
case "object":
|
|
47580
47580
|
return Debug.fail(`List of ${opt.element.type} is not yet supported.`);
|
|
47581
47581
|
default:
|
|
47582
|
-
return mapDefined(values2, (
|
|
47582
|
+
return mapDefined(values2, (v2) => parseCustomTypeOption(opt.element, v2, errors));
|
|
47583
47583
|
}
|
|
47584
47584
|
}
|
|
47585
47585
|
function getOptionName(option) {
|
|
@@ -48060,7 +48060,7 @@ ${lanes.join("\n")}
|
|
|
48060
48060
|
elements.forEach((element) => convertPropertyValueToJson(element, elementOption));
|
|
48061
48061
|
return void 0;
|
|
48062
48062
|
}
|
|
48063
|
-
return filter(elements.map((element) => convertPropertyValueToJson(element, elementOption)), (
|
|
48063
|
+
return filter(elements.map((element) => convertPropertyValueToJson(element, elementOption)), (v2) => v2 !== void 0);
|
|
48064
48064
|
}
|
|
48065
48065
|
function convertPropertyValueToJson(valueExpression, option) {
|
|
48066
48066
|
switch (valueExpression.kind) {
|
|
@@ -48255,7 +48255,7 @@ ${lanes.join("\n")}
|
|
|
48255
48255
|
if (pathOptions && optionDefinition.isFilePath) {
|
|
48256
48256
|
result.set(name, getRelativePathFromFile(pathOptions.configFilePath, getNormalizedAbsolutePath(value, getDirectoryPath(pathOptions.configFilePath)), getCanonicalFileName));
|
|
48257
48257
|
} else if (pathOptions && optionDefinition.type === "list" && optionDefinition.element.isFilePath) {
|
|
48258
|
-
result.set(name, value.map((
|
|
48258
|
+
result.set(name, value.map((v2) => getRelativePathFromFile(pathOptions.configFilePath, getNormalizedAbsolutePath(v2, getDirectoryPath(pathOptions.configFilePath)), getCanonicalFileName)));
|
|
48259
48259
|
} else {
|
|
48260
48260
|
result.set(name, value);
|
|
48261
48261
|
}
|
|
@@ -49063,7 +49063,7 @@ ${lanes.join("\n")}
|
|
|
49063
49063
|
}
|
|
49064
49064
|
}
|
|
49065
49065
|
function convertJsonOptionOfListType(option, values2, basePath, errors, propertyAssignment, valueExpression, sourceFile) {
|
|
49066
|
-
return filter(map(values2, (
|
|
49066
|
+
return filter(map(values2, (v2, index) => convertJsonOption(option.element, v2, basePath, errors, propertyAssignment, valueExpression == null ? void 0 : valueExpression.elements[index], sourceFile)), (v2) => option.listPreserveFalsyValues ? true : !!v2);
|
|
49067
49067
|
}
|
|
49068
49068
|
var invalidTrailingRecursionPattern = /(?:^|\/)\*\*\/?$/;
|
|
49069
49069
|
var wildcardDirectoryPattern = /^[^*?]*(?=\/[^/]*[*?])/;
|
|
@@ -49325,7 +49325,7 @@ ${lanes.join("\n")}
|
|
|
49325
49325
|
// fall through to list
|
|
49326
49326
|
case "list":
|
|
49327
49327
|
const elementType = option.element;
|
|
49328
|
-
return isArray(value) ? mapDefined(value, (
|
|
49328
|
+
return isArray(value) ? mapDefined(value, (v2) => getOptionValueWithEmptyStrings(v2, elementType)) : "";
|
|
49329
49329
|
default:
|
|
49330
49330
|
return forEachEntry(option.type, (optionEnumValue, optionStringValue) => {
|
|
49331
49331
|
if (optionEnumValue === value) {
|
|
@@ -69653,9 +69653,9 @@ ${lanes.join("\n")}
|
|
|
69653
69653
|
return getBaseConstraint(getSubstitutionIntersection(t));
|
|
69654
69654
|
}
|
|
69655
69655
|
if (isGenericTupleType(t)) {
|
|
69656
|
-
const newElements = map(getElementTypes(t), (
|
|
69657
|
-
const constraint =
|
|
69658
|
-
return constraint !==
|
|
69656
|
+
const newElements = map(getElementTypes(t), (v2, i) => {
|
|
69657
|
+
const constraint = v2.flags & 262144 && t.target.elementFlags[i] & 8 && getBaseConstraint(v2) || v2;
|
|
69658
|
+
return constraint !== v2 && everyType(constraint, (c) => isArrayOrTupleType(c) && !isGenericTupleType(c)) ? constraint : v2;
|
|
69659
69659
|
});
|
|
69660
69660
|
return createTupleType(newElements, t.target.elementFlags, t.target.readonly, t.target.labeledElementDeclarations);
|
|
69661
69661
|
}
|
|
@@ -77429,7 +77429,7 @@ ${lanes.join("\n")}
|
|
|
77429
77429
|
if (result2 = typeArgumentsRelatedTo(sourceTypeArguments, targetTypeArguments, variances, reportErrors2, intersectionState2)) {
|
|
77430
77430
|
return result2;
|
|
77431
77431
|
}
|
|
77432
|
-
if (some(variances, (
|
|
77432
|
+
if (some(variances, (v2) => !!(v2 & 24))) {
|
|
77433
77433
|
originalErrorInfo = void 0;
|
|
77434
77434
|
resetErrorInfo(saveErrorInfo);
|
|
77435
77435
|
return void 0;
|
|
@@ -77439,7 +77439,7 @@ ${lanes.join("\n")}
|
|
|
77439
77439
|
if (variances !== emptyArray && !allowStructuralFallback) {
|
|
77440
77440
|
if (varianceCheckFailed && !(reportErrors2 && some(
|
|
77441
77441
|
variances,
|
|
77442
|
-
(
|
|
77442
|
+
(v2) => (v2 & 7) === 0
|
|
77443
77443
|
/* Invariant */
|
|
77444
77444
|
))) {
|
|
77445
77445
|
return 0;
|
|
@@ -140817,7 +140817,7 @@ ${lanes.join("\n")}
|
|
|
140817
140817
|
function createManyToManyPathMap() {
|
|
140818
140818
|
function create2(forward, reverse, deleted) {
|
|
140819
140819
|
const map2 = {
|
|
140820
|
-
getKeys: (
|
|
140820
|
+
getKeys: (v2) => reverse.get(v2),
|
|
140821
140821
|
getValues: (k3) => forward.get(k3),
|
|
140822
140822
|
keys: () => forward.keys(),
|
|
140823
140823
|
size: () => forward.size,
|
|
@@ -140827,7 +140827,7 @@ ${lanes.join("\n")}
|
|
|
140827
140827
|
if (!set) {
|
|
140828
140828
|
return false;
|
|
140829
140829
|
}
|
|
140830
|
-
set.forEach((
|
|
140830
|
+
set.forEach((v2) => deleteFromMultimap(reverse, v2, k3));
|
|
140831
140831
|
forward.delete(k3);
|
|
140832
140832
|
return true;
|
|
140833
140833
|
},
|
|
@@ -140835,14 +140835,14 @@ ${lanes.join("\n")}
|
|
|
140835
140835
|
deleted == null ? void 0 : deleted.delete(k3);
|
|
140836
140836
|
const existingVSet = forward.get(k3);
|
|
140837
140837
|
forward.set(k3, vSet);
|
|
140838
|
-
existingVSet == null ? void 0 : existingVSet.forEach((
|
|
140839
|
-
if (!vSet.has(
|
|
140840
|
-
deleteFromMultimap(reverse,
|
|
140838
|
+
existingVSet == null ? void 0 : existingVSet.forEach((v2) => {
|
|
140839
|
+
if (!vSet.has(v2)) {
|
|
140840
|
+
deleteFromMultimap(reverse, v2, k3);
|
|
140841
140841
|
}
|
|
140842
140842
|
});
|
|
140843
|
-
vSet.forEach((
|
|
140844
|
-
if (!(existingVSet == null ? void 0 : existingVSet.has(
|
|
140845
|
-
addToMultimap(reverse,
|
|
140843
|
+
vSet.forEach((v2) => {
|
|
140844
|
+
if (!(existingVSet == null ? void 0 : existingVSet.has(v2))) {
|
|
140845
|
+
addToMultimap(reverse, v2, k3);
|
|
140846
140846
|
}
|
|
140847
140847
|
});
|
|
140848
140848
|
return map2;
|
|
@@ -140858,17 +140858,17 @@ ${lanes.join("\n")}
|
|
|
140858
140858
|
);
|
|
140859
140859
|
}
|
|
140860
140860
|
BuilderState2.createManyToManyPathMap = createManyToManyPathMap;
|
|
140861
|
-
function addToMultimap(map2, k3,
|
|
140861
|
+
function addToMultimap(map2, k3, v2) {
|
|
140862
140862
|
let set = map2.get(k3);
|
|
140863
140863
|
if (!set) {
|
|
140864
140864
|
set = /* @__PURE__ */ new Set();
|
|
140865
140865
|
map2.set(k3, set);
|
|
140866
140866
|
}
|
|
140867
|
-
set.add(
|
|
140867
|
+
set.add(v2);
|
|
140868
140868
|
}
|
|
140869
|
-
function deleteFromMultimap(map2, k3,
|
|
140869
|
+
function deleteFromMultimap(map2, k3, v2) {
|
|
140870
140870
|
const set = map2.get(k3);
|
|
140871
|
-
if (set == null ? void 0 : set.delete(
|
|
140871
|
+
if (set == null ? void 0 : set.delete(v2)) {
|
|
140872
140872
|
if (!set.size) {
|
|
140873
140873
|
map2.delete(k3);
|
|
140874
140874
|
}
|
|
@@ -147186,7 +147186,7 @@ ${lanes.join("\n")}
|
|
|
147186
147186
|
return options.pretty;
|
|
147187
147187
|
}
|
|
147188
147188
|
function getOptionsForHelp(commandLine) {
|
|
147189
|
-
return !!commandLine.options.all ? toSorted(optionDeclarations.concat(tscBuildOption), (a, b4) => compareStringsCaseInsensitive(a.name, b4.name)) : filter(optionDeclarations.concat(tscBuildOption), (
|
|
147189
|
+
return !!commandLine.options.all ? toSorted(optionDeclarations.concat(tscBuildOption), (a, b4) => compareStringsCaseInsensitive(a.name, b4.name)) : filter(optionDeclarations.concat(tscBuildOption), (v2) => !!v2.showInSimplifiedHelpView);
|
|
147190
147190
|
}
|
|
147191
147191
|
function printVersion(sys2) {
|
|
147192
147192
|
sys2.write(getDiagnosticText(Diagnostics.Version_0, version) + sys2.newLine);
|
|
@@ -150589,8 +150589,8 @@ ${lanes.join("\n")}
|
|
|
150589
150589
|
default:
|
|
150590
150590
|
return "";
|
|
150591
150591
|
}
|
|
150592
|
-
function getKindOfVariableDeclaration(
|
|
150593
|
-
return isVarConst(
|
|
150592
|
+
function getKindOfVariableDeclaration(v2) {
|
|
150593
|
+
return isVarConst(v2) ? "const" : isLet(v2) ? "let" : "var";
|
|
150594
150594
|
}
|
|
150595
150595
|
}
|
|
150596
150596
|
function isThis(node) {
|
|
@@ -156679,7 +156679,7 @@ interface Symbol {
|
|
|
156679
156679
|
}
|
|
156680
156680
|
var commandLineOptionsStringToEnum;
|
|
156681
156681
|
function fixupCompilerOptions(options, diagnostics) {
|
|
156682
|
-
commandLineOptionsStringToEnum = commandLineOptionsStringToEnum || filter(optionDeclarations, (o2) => typeof o2.type === "object" && !forEachEntry(o2.type, (
|
|
156682
|
+
commandLineOptionsStringToEnum = commandLineOptionsStringToEnum || filter(optionDeclarations, (o2) => typeof o2.type === "object" && !forEachEntry(o2.type, (v2) => typeof v2 !== "number"));
|
|
156683
156683
|
options = cloneCompilerOptions(options);
|
|
156684
156684
|
for (const opt of commandLineOptionsStringToEnum) {
|
|
156685
156685
|
if (!hasProperty(options, opt.name)) {
|
|
@@ -156689,7 +156689,7 @@ interface Symbol {
|
|
|
156689
156689
|
if (isString(value)) {
|
|
156690
156690
|
options[opt.name] = parseCustomTypeOption(opt, value, diagnostics);
|
|
156691
156691
|
} else {
|
|
156692
|
-
if (!forEachEntry(opt.type, (
|
|
156692
|
+
if (!forEachEntry(opt.type, (v2) => v2 === value)) {
|
|
156693
156693
|
diagnostics.push(createCompilerDiagnosticForInvalidCustomType(opt));
|
|
156694
156694
|
}
|
|
156695
156695
|
}
|
|
@@ -162506,12 +162506,12 @@ ${newComment.split("\n").map((c) => ` * ${c}`).join("\n")}
|
|
|
162506
162506
|
}
|
|
162507
162507
|
}
|
|
162508
162508
|
function getPropertyAssignmentsForWritesAndVariableDeclarations(exposedVariableDeclarations, writes) {
|
|
162509
|
-
const variableAssignments = map(exposedVariableDeclarations, (
|
|
162509
|
+
const variableAssignments = map(exposedVariableDeclarations, (v2) => factory.createShorthandPropertyAssignment(v2.symbol.name));
|
|
162510
162510
|
const writeAssignments = map(writes, (w2) => factory.createShorthandPropertyAssignment(w2.symbol.name));
|
|
162511
162511
|
return variableAssignments === void 0 ? writeAssignments : writeAssignments === void 0 ? variableAssignments : variableAssignments.concat(writeAssignments);
|
|
162512
162512
|
}
|
|
162513
|
-
function isReadonlyArray(
|
|
162514
|
-
return isArray(
|
|
162513
|
+
function isReadonlyArray(v2) {
|
|
162514
|
+
return isArray(v2);
|
|
162515
162515
|
}
|
|
162516
162516
|
function getEnclosingTextRange(targetRange, sourceFile) {
|
|
162517
162517
|
return isReadonlyArray(targetRange.range) ? { pos: first(targetRange.range).getStart(sourceFile), end: last(targetRange.range).getEnd() } : targetRange.range;
|
|
@@ -200579,19 +200579,19 @@ ${options.prefix}` : "\n" : options.prefix
|
|
|
200579
200579
|
}
|
|
200580
200580
|
const set = /* @__PURE__ */ new Map();
|
|
200581
200581
|
let unique = 0;
|
|
200582
|
-
for (const
|
|
200583
|
-
if (set.get(
|
|
200584
|
-
set.set(
|
|
200582
|
+
for (const v2 of arr1) {
|
|
200583
|
+
if (set.get(v2) !== true) {
|
|
200584
|
+
set.set(v2, true);
|
|
200585
200585
|
unique++;
|
|
200586
200586
|
}
|
|
200587
200587
|
}
|
|
200588
|
-
for (const
|
|
200589
|
-
const isSet = set.get(
|
|
200588
|
+
for (const v2 of arr2) {
|
|
200589
|
+
const isSet = set.get(v2);
|
|
200590
200590
|
if (isSet === void 0) {
|
|
200591
200591
|
return false;
|
|
200592
200592
|
}
|
|
200593
200593
|
if (isSet === true) {
|
|
200594
|
-
set.set(
|
|
200594
|
+
set.set(v2, false);
|
|
200595
200595
|
unique--;
|
|
200596
200596
|
}
|
|
200597
200597
|
}
|
|
@@ -211969,10 +211969,10 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
|
|
|
211969
211969
|
}
|
|
211970
211970
|
})({ get exports() {
|
|
211971
211971
|
return ts;
|
|
211972
|
-
}, set exports(
|
|
211973
|
-
ts =
|
|
211972
|
+
}, set exports(v2) {
|
|
211973
|
+
ts = v2;
|
|
211974
211974
|
if (typeof module2 !== "undefined" && module2.exports) {
|
|
211975
|
-
module2.exports =
|
|
211975
|
+
module2.exports = v2;
|
|
211976
211976
|
}
|
|
211977
211977
|
} });
|
|
211978
211978
|
}
|
|
@@ -212120,17 +212120,19 @@ var require_commonjs2 = __commonJS({
|
|
|
212120
212120
|
}
|
|
212121
212121
|
function expand_(str, max, isTop) {
|
|
212122
212122
|
const expansions = [];
|
|
212123
|
-
|
|
212124
|
-
|
|
212125
|
-
|
|
212126
|
-
|
|
212127
|
-
|
|
212128
|
-
|
|
212129
|
-
|
|
212130
|
-
|
|
212131
|
-
|
|
212123
|
+
for (; ; ) {
|
|
212124
|
+
const m2 = (0, balanced_match_1.balanced)("{", "}", str);
|
|
212125
|
+
if (!m2)
|
|
212126
|
+
return [str];
|
|
212127
|
+
const pre = m2.pre;
|
|
212128
|
+
if (/\$$/.test(m2.pre)) {
|
|
212129
|
+
const post2 = m2.post.length ? expand_(m2.post, max, false) : [""];
|
|
212130
|
+
for (let k3 = 0; k3 < post2.length && k3 < max; k3++) {
|
|
212131
|
+
const expansion = pre + "{" + m2.body + "}" + post2[k3];
|
|
212132
|
+
expansions.push(expansion);
|
|
212133
|
+
}
|
|
212134
|
+
return expansions;
|
|
212132
212135
|
}
|
|
212133
|
-
} else {
|
|
212134
212136
|
const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m2.body);
|
|
212135
212137
|
const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m2.body);
|
|
212136
212138
|
const isSequence = isNumericSequence || isAlphaSequence;
|
|
@@ -212138,10 +212140,12 @@ var require_commonjs2 = __commonJS({
|
|
|
212138
212140
|
if (!isSequence && !isOptions) {
|
|
212139
212141
|
if (m2.post.match(/,(?!,).*\}/)) {
|
|
212140
212142
|
str = m2.pre + "{" + m2.body + escClose + m2.post;
|
|
212141
|
-
|
|
212143
|
+
isTop = true;
|
|
212144
|
+
continue;
|
|
212142
212145
|
}
|
|
212143
212146
|
return [str];
|
|
212144
212147
|
}
|
|
212148
|
+
const post = m2.post.length ? expand_(m2.post, max, false) : [""];
|
|
212145
212149
|
let n;
|
|
212146
212150
|
if (isSequence) {
|
|
212147
212151
|
n = m2.body.split(/\.\./);
|
|
@@ -212205,8 +212209,8 @@ var require_commonjs2 = __commonJS({
|
|
|
212205
212209
|
}
|
|
212206
212210
|
}
|
|
212207
212211
|
}
|
|
212212
|
+
return expansions;
|
|
212208
212213
|
}
|
|
212209
|
-
return expansions;
|
|
212210
212214
|
}
|
|
212211
212215
|
}
|
|
212212
212216
|
});
|
|
@@ -214992,10 +214996,10 @@ var require_fill_range = __commonJS({
|
|
|
214992
214996
|
let negatives = "";
|
|
214993
214997
|
let result;
|
|
214994
214998
|
if (parts.positives.length) {
|
|
214995
|
-
positives = parts.positives.map((
|
|
214999
|
+
positives = parts.positives.map((v2) => toMaxLen(String(v2), maxLen)).join("|");
|
|
214996
215000
|
}
|
|
214997
215001
|
if (parts.negatives.length) {
|
|
214998
|
-
negatives = `-(${prefix2}${parts.negatives.map((
|
|
215002
|
+
negatives = `-(${prefix2}${parts.negatives.map((v2) => toMaxLen(String(v2), maxLen)).join("|")})`;
|
|
214999
215003
|
}
|
|
215000
215004
|
if (positives && negatives) {
|
|
215001
215005
|
result = `${positives}|${negatives}`;
|
|
@@ -216301,7 +216305,7 @@ var require_parse2 = __commonJS({
|
|
|
216301
216305
|
try {
|
|
216302
216306
|
new RegExp(value);
|
|
216303
216307
|
} catch (ex) {
|
|
216304
|
-
return args.map((
|
|
216308
|
+
return args.map((v2) => utils.escapeRegex(v2)).join("..");
|
|
216305
216309
|
}
|
|
216306
216310
|
return value;
|
|
216307
216311
|
};
|
|
@@ -217441,10 +217445,10 @@ var require_micromatch = __commonJS({
|
|
|
217441
217445
|
var braces = require_braces();
|
|
217442
217446
|
var picomatch = require_picomatch2();
|
|
217443
217447
|
var utils = require_utils2();
|
|
217444
|
-
var isEmptyString = (
|
|
217445
|
-
var hasBraces = (
|
|
217446
|
-
const index =
|
|
217447
|
-
return index > -1 &&
|
|
217448
|
+
var isEmptyString = (v2) => v2 === "" || v2 === "./";
|
|
217449
|
+
var hasBraces = (v2) => {
|
|
217450
|
+
const index = v2.indexOf("{");
|
|
217451
|
+
return index > -1 && v2.indexOf("}", index) > -1;
|
|
217448
217452
|
};
|
|
217449
217453
|
var micromatch = (list, patterns, options) => {
|
|
217450
217454
|
patterns = [].concat(patterns);
|
|
@@ -217564,7 +217568,7 @@ var require_micromatch = __commonJS({
|
|
|
217564
217568
|
let regex = picomatch.makeRe(String(glob), { ...options, capture: true });
|
|
217565
217569
|
let match = regex.exec(posix ? utils.toPosixSlashes(input) : input);
|
|
217566
217570
|
if (match) {
|
|
217567
|
-
return match.slice(1).map((
|
|
217571
|
+
return match.slice(1).map((v2) => v2 === void 0 ? "" : v2);
|
|
217568
217572
|
}
|
|
217569
217573
|
};
|
|
217570
217574
|
micromatch.makeRe = (...args) => picomatch.makeRe(...args);
|
|
@@ -256143,7 +256147,7 @@ var require_ts_morph = __commonJS({
|
|
|
256143
256147
|
errors: result.errors.map((error) => new Diagnostic(void 0, error))
|
|
256144
256148
|
};
|
|
256145
256149
|
}
|
|
256146
|
-
var [tsMajor, tsMinor, tsPatch] = common.ts.version.split(".").map((
|
|
256150
|
+
var [tsMajor, tsMinor, tsPatch] = common.ts.version.split(".").map((v2) => parseInt(v2, 10));
|
|
256147
256151
|
var WriterUtils = class {
|
|
256148
256152
|
constructor() {
|
|
256149
256153
|
}
|
|
@@ -276124,6 +276128,7 @@ var import_node_process = require("process");
|
|
|
276124
276128
|
var g = __toESM(require("readline"), 1);
|
|
276125
276129
|
var import_node_readline = __toESM(require("readline"), 1);
|
|
276126
276130
|
var import_node_stream = require("stream");
|
|
276131
|
+
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
276127
276132
|
function DD({ onlyFirst: e2 = false } = {}) {
|
|
276128
276133
|
const t = ["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|");
|
|
276129
276134
|
return new RegExp(t, e2 ? void 0 : "g");
|
|
@@ -276492,10 +276497,26 @@ var LD = class extends x {
|
|
|
276492
276497
|
this.value = this._value.value;
|
|
276493
276498
|
}
|
|
276494
276499
|
};
|
|
276500
|
+
var RD = class extends x {
|
|
276501
|
+
get valueWithCursor() {
|
|
276502
|
+
if (this.state === "submit") return this.value;
|
|
276503
|
+
if (this.cursor >= this.value.length) return `${this.value}\u2588`;
|
|
276504
|
+
const u2 = this.value.slice(0, this.cursor), [t, ...F2] = this.value.slice(this.cursor);
|
|
276505
|
+
return `${u2}${import_picocolors.default.inverse(t)}${F2.join("")}`;
|
|
276506
|
+
}
|
|
276507
|
+
get cursor() {
|
|
276508
|
+
return this._cursor;
|
|
276509
|
+
}
|
|
276510
|
+
constructor(u2) {
|
|
276511
|
+
super(u2), this.on("finalize", () => {
|
|
276512
|
+
this.value || (this.value = u2.defaultValue);
|
|
276513
|
+
});
|
|
276514
|
+
}
|
|
276515
|
+
};
|
|
276495
276516
|
|
|
276496
276517
|
// node_modules/@clack/prompts/dist/index.mjs
|
|
276497
276518
|
var import_node_process2 = __toESM(require("process"), 1);
|
|
276498
|
-
var
|
|
276519
|
+
var import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
276499
276520
|
var import_sisteransi2 = __toESM(require_src(), 1);
|
|
276500
276521
|
function ce() {
|
|
276501
276522
|
return import_node_process2.default.platform !== "win32" ? import_node_process2.default.env.TERM !== "linux" : !!import_node_process2.default.env.CI || !!import_node_process2.default.env.WT_SESSION || !!import_node_process2.default.env.TERMINUS_SUBLIME || import_node_process2.default.env.ConEmuTask === "{cmd::Cmder}" || import_node_process2.default.env.TERM_PROGRAM === "Terminus-Sublime" || import_node_process2.default.env.TERM_PROGRAM === "vscode" || import_node_process2.default.env.TERM === "xterm-256color" || import_node_process2.default.env.TERM === "alacritty" || import_node_process2.default.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
@@ -276527,13 +276548,13 @@ var b2 = (t) => {
|
|
|
276527
276548
|
switch (t) {
|
|
276528
276549
|
case "initial":
|
|
276529
276550
|
case "active":
|
|
276530
|
-
return
|
|
276551
|
+
return import_picocolors2.default.cyan(le);
|
|
276531
276552
|
case "cancel":
|
|
276532
|
-
return
|
|
276553
|
+
return import_picocolors2.default.red(L2);
|
|
276533
276554
|
case "error":
|
|
276534
|
-
return
|
|
276555
|
+
return import_picocolors2.default.yellow(W2);
|
|
276535
276556
|
case "submit":
|
|
276536
|
-
return
|
|
276557
|
+
return import_picocolors2.default.green(C);
|
|
276537
276558
|
}
|
|
276538
276559
|
};
|
|
276539
276560
|
var G2 = (t) => {
|
|
@@ -276541,26 +276562,47 @@ var G2 = (t) => {
|
|
|
276541
276562
|
let l2 = 0;
|
|
276542
276563
|
n >= l2 + a - 3 ? l2 = Math.max(Math.min(n - a + 3, r2.length - a), 0) : n < l2 + 2 && (l2 = Math.max(n - 2, 0));
|
|
276543
276564
|
const $2 = a < r2.length && l2 > 0, g2 = a < r2.length && l2 + a < r2.length;
|
|
276544
|
-
return r2.slice(l2, l2 + a).map((p2,
|
|
276545
|
-
const j2 =
|
|
276546
|
-
return j2 || E ?
|
|
276565
|
+
return r2.slice(l2, l2 + a).map((p2, v2, f) => {
|
|
276566
|
+
const j2 = v2 === 0 && $2, E = v2 === f.length - 1 && g2;
|
|
276567
|
+
return j2 || E ? import_picocolors2.default.dim("...") : i(p2, v2 + l2 === n);
|
|
276547
276568
|
});
|
|
276548
276569
|
};
|
|
276570
|
+
var he = (t) => new RD({ validate: t.validate, placeholder: t.placeholder, defaultValue: t.defaultValue, initialValue: t.initialValue, render() {
|
|
276571
|
+
const n = `${import_picocolors2.default.gray(o)}
|
|
276572
|
+
${b2(this.state)} ${t.message}
|
|
276573
|
+
`, r2 = t.placeholder ? import_picocolors2.default.inverse(t.placeholder[0]) + import_picocolors2.default.dim(t.placeholder.slice(1)) : import_picocolors2.default.inverse(import_picocolors2.default.hidden("_")), i = this.value ? this.valueWithCursor : r2;
|
|
276574
|
+
switch (this.state) {
|
|
276575
|
+
case "error":
|
|
276576
|
+
return `${n.trim()}
|
|
276577
|
+
${import_picocolors2.default.yellow(o)} ${i}
|
|
276578
|
+
${import_picocolors2.default.yellow(d2)} ${import_picocolors2.default.yellow(this.error)}
|
|
276579
|
+
`;
|
|
276580
|
+
case "submit":
|
|
276581
|
+
return `${n}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.dim(this.value || t.placeholder)}`;
|
|
276582
|
+
case "cancel":
|
|
276583
|
+
return `${n}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(this.value ?? ""))}${this.value?.trim() ? `
|
|
276584
|
+
${import_picocolors2.default.gray(o)}` : ""}`;
|
|
276585
|
+
default:
|
|
276586
|
+
return `${n}${import_picocolors2.default.cyan(o)} ${i}
|
|
276587
|
+
${import_picocolors2.default.cyan(d2)}
|
|
276588
|
+
`;
|
|
276589
|
+
}
|
|
276590
|
+
} }).prompt();
|
|
276549
276591
|
var ye = (t) => {
|
|
276550
276592
|
const n = t.active ?? "Yes", r2 = t.inactive ?? "No";
|
|
276551
276593
|
return new dD({ active: n, inactive: r2, initialValue: t.initialValue ?? true, render() {
|
|
276552
|
-
const i = `${
|
|
276594
|
+
const i = `${import_picocolors2.default.gray(o)}
|
|
276553
276595
|
${b2(this.state)} ${t.message}
|
|
276554
276596
|
`, s = this.value ? n : r2;
|
|
276555
276597
|
switch (this.state) {
|
|
276556
276598
|
case "submit":
|
|
276557
|
-
return `${i}${
|
|
276599
|
+
return `${i}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.dim(s)}`;
|
|
276558
276600
|
case "cancel":
|
|
276559
|
-
return `${i}${
|
|
276560
|
-
${
|
|
276601
|
+
return `${i}${import_picocolors2.default.gray(o)} ${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(s))}
|
|
276602
|
+
${import_picocolors2.default.gray(o)}`;
|
|
276561
276603
|
default:
|
|
276562
|
-
return `${i}${
|
|
276563
|
-
${
|
|
276604
|
+
return `${i}${import_picocolors2.default.cyan(o)} ${this.value ? `${import_picocolors2.default.green(k2)} ${n}` : `${import_picocolors2.default.dim(P2)} ${import_picocolors2.default.dim(n)}`} ${import_picocolors2.default.dim("/")} ${this.value ? `${import_picocolors2.default.dim(P2)} ${import_picocolors2.default.dim(r2)}` : `${import_picocolors2.default.green(k2)} ${r2}`}
|
|
276605
|
+
${import_picocolors2.default.cyan(d2)}
|
|
276564
276606
|
`;
|
|
276565
276607
|
}
|
|
276566
276608
|
} }).prompt();
|
|
@@ -276570,29 +276612,29 @@ var ve = (t) => {
|
|
|
276570
276612
|
const s = r2.label ?? String(r2.value);
|
|
276571
276613
|
switch (i) {
|
|
276572
276614
|
case "selected":
|
|
276573
|
-
return `${
|
|
276615
|
+
return `${import_picocolors2.default.dim(s)}`;
|
|
276574
276616
|
case "active":
|
|
276575
|
-
return `${
|
|
276617
|
+
return `${import_picocolors2.default.green(k2)} ${s} ${r2.hint ? import_picocolors2.default.dim(`(${r2.hint})`) : ""}`;
|
|
276576
276618
|
case "cancelled":
|
|
276577
|
-
return `${
|
|
276619
|
+
return `${import_picocolors2.default.strikethrough(import_picocolors2.default.dim(s))}`;
|
|
276578
276620
|
default:
|
|
276579
|
-
return `${
|
|
276621
|
+
return `${import_picocolors2.default.dim(P2)} ${import_picocolors2.default.dim(s)}`;
|
|
276580
276622
|
}
|
|
276581
276623
|
};
|
|
276582
276624
|
return new LD({ options: t.options, initialValue: t.initialValue, render() {
|
|
276583
|
-
const r2 = `${
|
|
276625
|
+
const r2 = `${import_picocolors2.default.gray(o)}
|
|
276584
276626
|
${b2(this.state)} ${t.message}
|
|
276585
276627
|
`;
|
|
276586
276628
|
switch (this.state) {
|
|
276587
276629
|
case "submit":
|
|
276588
|
-
return `${r2}${
|
|
276630
|
+
return `${r2}${import_picocolors2.default.gray(o)} ${n(this.options[this.cursor], "selected")}`;
|
|
276589
276631
|
case "cancel":
|
|
276590
|
-
return `${r2}${
|
|
276591
|
-
${
|
|
276632
|
+
return `${r2}${import_picocolors2.default.gray(o)} ${n(this.options[this.cursor], "cancelled")}
|
|
276633
|
+
${import_picocolors2.default.gray(o)}`;
|
|
276592
276634
|
default:
|
|
276593
|
-
return `${r2}${
|
|
276594
|
-
${
|
|
276595
|
-
${
|
|
276635
|
+
return `${r2}${import_picocolors2.default.cyan(o)} ${G2({ cursor: this.cursor, options: this.options, maxItems: t.maxItems, style: (i, s) => n(i, s ? "active" : "inactive") }).join(`
|
|
276636
|
+
${import_picocolors2.default.cyan(o)} `)}
|
|
276637
|
+
${import_picocolors2.default.cyan(d2)}
|
|
276596
276638
|
`;
|
|
276597
276639
|
}
|
|
276598
276640
|
} }).prompt();
|
|
@@ -276604,63 +276646,63 @@ ${t}
|
|
|
276604
276646
|
`), i = (0, import_node_util.stripVTControlCharacters)(n).length, s = Math.max(r2.reduce((a, l2) => {
|
|
276605
276647
|
const $2 = (0, import_node_util.stripVTControlCharacters)(l2);
|
|
276606
276648
|
return $2.length > a ? $2.length : a;
|
|
276607
|
-
}, 0), i) + 2, c = r2.map((a) => `${
|
|
276649
|
+
}, 0), i) + 2, c = r2.map((a) => `${import_picocolors2.default.gray(o)} ${import_picocolors2.default.dim(a)}${" ".repeat(s - (0, import_node_util.stripVTControlCharacters)(a).length)}${import_picocolors2.default.gray(o)}`).join(`
|
|
276608
276650
|
`);
|
|
276609
|
-
process.stdout.write(`${
|
|
276610
|
-
${
|
|
276651
|
+
process.stdout.write(`${import_picocolors2.default.gray(o)}
|
|
276652
|
+
${import_picocolors2.default.green(C)} ${import_picocolors2.default.reset(n)} ${import_picocolors2.default.gray(_2.repeat(Math.max(s - i - 1, 1)) + me)}
|
|
276611
276653
|
${c}
|
|
276612
|
-
${
|
|
276654
|
+
${import_picocolors2.default.gray(de + _2.repeat(s + 2) + pe)}
|
|
276613
276655
|
`);
|
|
276614
276656
|
};
|
|
276615
276657
|
var xe = (t = "") => {
|
|
276616
|
-
process.stdout.write(`${
|
|
276658
|
+
process.stdout.write(`${import_picocolors2.default.gray(d2)} ${import_picocolors2.default.red(t)}
|
|
276617
276659
|
|
|
276618
276660
|
`);
|
|
276619
276661
|
};
|
|
276620
276662
|
var Ie = (t = "") => {
|
|
276621
|
-
process.stdout.write(`${
|
|
276663
|
+
process.stdout.write(`${import_picocolors2.default.gray(ue)} ${t}
|
|
276622
276664
|
`);
|
|
276623
276665
|
};
|
|
276624
276666
|
var Se = (t = "") => {
|
|
276625
|
-
process.stdout.write(`${
|
|
276626
|
-
${
|
|
276667
|
+
process.stdout.write(`${import_picocolors2.default.gray(o)}
|
|
276668
|
+
${import_picocolors2.default.gray(d2)} ${t}
|
|
276627
276669
|
|
|
276628
276670
|
`);
|
|
276629
276671
|
};
|
|
276630
|
-
var M2 = { message: (t = "", { symbol: n =
|
|
276631
|
-
const r2 = [`${
|
|
276672
|
+
var M2 = { message: (t = "", { symbol: n = import_picocolors2.default.gray(o) } = {}) => {
|
|
276673
|
+
const r2 = [`${import_picocolors2.default.gray(o)}`];
|
|
276632
276674
|
if (t) {
|
|
276633
276675
|
const [i, ...s] = t.split(`
|
|
276634
276676
|
`);
|
|
276635
|
-
r2.push(`${n} ${i}`, ...s.map((c) => `${
|
|
276677
|
+
r2.push(`${n} ${i}`, ...s.map((c) => `${import_picocolors2.default.gray(o)} ${c}`));
|
|
276636
276678
|
}
|
|
276637
276679
|
process.stdout.write(`${r2.join(`
|
|
276638
276680
|
`)}
|
|
276639
276681
|
`);
|
|
276640
276682
|
}, info: (t) => {
|
|
276641
|
-
M2.message(t, { symbol:
|
|
276683
|
+
M2.message(t, { symbol: import_picocolors2.default.blue(q) });
|
|
276642
276684
|
}, success: (t) => {
|
|
276643
|
-
M2.message(t, { symbol:
|
|
276685
|
+
M2.message(t, { symbol: import_picocolors2.default.green(D) });
|
|
276644
276686
|
}, step: (t) => {
|
|
276645
|
-
M2.message(t, { symbol:
|
|
276687
|
+
M2.message(t, { symbol: import_picocolors2.default.green(C) });
|
|
276646
276688
|
}, warn: (t) => {
|
|
276647
|
-
M2.message(t, { symbol:
|
|
276689
|
+
M2.message(t, { symbol: import_picocolors2.default.yellow(U) });
|
|
276648
276690
|
}, warning: (t) => {
|
|
276649
276691
|
M2.warn(t);
|
|
276650
276692
|
}, error: (t) => {
|
|
276651
|
-
M2.message(t, { symbol:
|
|
276693
|
+
M2.message(t, { symbol: import_picocolors2.default.red(K2) });
|
|
276652
276694
|
} };
|
|
276653
|
-
var J2 = `${
|
|
276695
|
+
var J2 = `${import_picocolors2.default.gray(o)} `;
|
|
276654
276696
|
var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
276655
276697
|
const n = V2 ? ["\u25D2", "\u25D0", "\u25D3", "\u25D1"] : ["\u2022", "o", "O", "0"], r2 = V2 ? 80 : 120, i = process.env.CI === "true";
|
|
276656
276698
|
let s, c, a = false, l2 = "", $2, g2 = performance.now();
|
|
276657
276699
|
const p2 = (m2) => {
|
|
276658
276700
|
const h2 = m2 > 1 ? "Something went wrong" : "Canceled";
|
|
276659
276701
|
a && N2(h2, m2);
|
|
276660
|
-
},
|
|
276661
|
-
process.on("uncaughtExceptionMonitor",
|
|
276702
|
+
}, v2 = () => p2(2), f = () => p2(1), j2 = () => {
|
|
276703
|
+
process.on("uncaughtExceptionMonitor", v2), process.on("unhandledRejection", v2), process.on("SIGINT", f), process.on("SIGTERM", f), process.on("exit", p2);
|
|
276662
276704
|
}, E = () => {
|
|
276663
|
-
process.removeListener("uncaughtExceptionMonitor",
|
|
276705
|
+
process.removeListener("uncaughtExceptionMonitor", v2), process.removeListener("unhandledRejection", v2), process.removeListener("SIGINT", f), process.removeListener("SIGTERM", f), process.removeListener("exit", p2);
|
|
276664
276706
|
}, B2 = () => {
|
|
276665
276707
|
if ($2 === void 0) return;
|
|
276666
276708
|
i && process.stdout.write(`
|
|
@@ -276672,13 +276714,13 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
276672
276714
|
const h2 = (performance.now() - m2) / 1e3, w2 = Math.floor(h2 / 60), I2 = Math.floor(h2 % 60);
|
|
276673
276715
|
return w2 > 0 ? `[${w2}m ${I2}s]` : `[${I2}s]`;
|
|
276674
276716
|
}, H = (m2 = "") => {
|
|
276675
|
-
a = true, s = fD(), l2 = R2(m2), g2 = performance.now(), process.stdout.write(`${
|
|
276717
|
+
a = true, s = fD(), l2 = R2(m2), g2 = performance.now(), process.stdout.write(`${import_picocolors2.default.gray(o)}
|
|
276676
276718
|
`);
|
|
276677
276719
|
let h2 = 0, w2 = 0;
|
|
276678
276720
|
j2(), c = setInterval(() => {
|
|
276679
276721
|
if (i && l2 === $2) return;
|
|
276680
276722
|
B2(), $2 = l2;
|
|
276681
|
-
const I2 =
|
|
276723
|
+
const I2 = import_picocolors2.default.magenta(n[h2]);
|
|
276682
276724
|
if (i) process.stdout.write(`${I2} ${l2}...`);
|
|
276683
276725
|
else if (t === "timer") process.stdout.write(`${I2} ${l2} ${O2(g2)}`);
|
|
276684
276726
|
else {
|
|
@@ -276689,7 +276731,7 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
276689
276731
|
}, r2);
|
|
276690
276732
|
}, N2 = (m2 = "", h2 = 0) => {
|
|
276691
276733
|
a = false, clearInterval(c), B2();
|
|
276692
|
-
const w2 = h2 === 0 ?
|
|
276734
|
+
const w2 = h2 === 0 ? import_picocolors2.default.green(C) : h2 === 1 ? import_picocolors2.default.red(L2) : import_picocolors2.default.red(W2);
|
|
276693
276735
|
l2 = R2(m2 ?? l2), t === "timer" ? process.stdout.write(`${w2} ${l2} ${O2(g2)}
|
|
276694
276736
|
`) : process.stdout.write(`${w2} ${l2}
|
|
276695
276737
|
`), E(), s();
|
|
@@ -276700,10 +276742,10 @@ var Y2 = ({ indicator: t = "dots" } = {}) => {
|
|
|
276700
276742
|
};
|
|
276701
276743
|
|
|
276702
276744
|
// src/cli/index.ts
|
|
276703
|
-
var
|
|
276745
|
+
var import_picocolors20 = __toESM(require_picocolors(), 1);
|
|
276704
276746
|
var import_fs12 = require("fs");
|
|
276705
276747
|
var import_path7 = require("path");
|
|
276706
|
-
var
|
|
276748
|
+
var import_child_process3 = require("child_process");
|
|
276707
276749
|
|
|
276708
276750
|
// src/cli/migrate.ts
|
|
276709
276751
|
init_cjs_shims();
|
|
@@ -277411,7 +277453,7 @@ var ErrorBodyShapeSchema = import_zod4.z.object({
|
|
|
277411
277453
|
}).passthrough();
|
|
277412
277454
|
|
|
277413
277455
|
// src/cli/migrate.ts
|
|
277414
|
-
var
|
|
277456
|
+
var import_picocolors4 = __toESM(require_picocolors(), 1);
|
|
277415
277457
|
var import_fs5 = require("fs");
|
|
277416
277458
|
|
|
277417
277459
|
// node_modules/postgres/src/index.js
|
|
@@ -277878,7 +277920,7 @@ var fromPascal = (x2) => (x2.slice(0, 1) + x2.slice(1).replace(/([A-Z])/g, "_$1"
|
|
|
277878
277920
|
var fromKebab = (x2) => x2.replace(/-/g, "_");
|
|
277879
277921
|
function createJsonTransform(fn) {
|
|
277880
277922
|
return function jsonTransform(x2, column) {
|
|
277881
|
-
return typeof x2 === "object" && x2 !== null && (column.type === 114 || column.type === 3802) ? Array.isArray(x2) ? x2.map((x3) => jsonTransform(x3, column)) : Object.entries(x2).reduce((acc, [k3,
|
|
277923
|
+
return typeof x2 === "object" && x2 !== null && (column.type === 114 || column.type === 3802) ? Array.isArray(x2) ? x2.map((x3) => jsonTransform(x3, column)) : Object.entries(x2).reduce((acc, [k3, v2]) => Object.assign(acc, { [fn(k3)]: jsonTransform(v2, column) }), {}) : x2;
|
|
277882
277924
|
};
|
|
277883
277925
|
}
|
|
277884
277926
|
toCamel.column = { from: toCamel };
|
|
@@ -277956,9 +277998,9 @@ init_cjs_shims();
|
|
|
277956
277998
|
var size = 256;
|
|
277957
277999
|
var buffer = Buffer.allocUnsafe(size);
|
|
277958
278000
|
var messages = "BCcDdEFfHPpQSX".split("").reduce((acc, x2) => {
|
|
277959
|
-
const
|
|
278001
|
+
const v2 = x2.charCodeAt(0);
|
|
277960
278002
|
acc[x2] = () => {
|
|
277961
|
-
buffer[0] =
|
|
278003
|
+
buffer[0] = v2;
|
|
277962
278004
|
b3.i = 5;
|
|
277963
278005
|
return b3;
|
|
277964
278006
|
};
|
|
@@ -278453,11 +278495,11 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
278453
278495
|
query.forEachFn ? query.forEachFn(transform.row.from ? transform.row.from(row) : row, result) : result[rows++] = transform.row.from ? transform.row.from(row) : row;
|
|
278454
278496
|
}
|
|
278455
278497
|
function ParameterStatus(x2) {
|
|
278456
|
-
const [k3,
|
|
278457
|
-
backendParameters[k3] =
|
|
278458
|
-
if (options.parameters[k3] !==
|
|
278459
|
-
options.parameters[k3] =
|
|
278460
|
-
onparameter && onparameter(k3,
|
|
278498
|
+
const [k3, v2] = x2.toString("utf8", 5, x2.length - 1).split(bytes_default.N);
|
|
278499
|
+
backendParameters[k3] = v2;
|
|
278500
|
+
if (options.parameters[k3] !== v2) {
|
|
278501
|
+
options.parameters[k3] = v2;
|
|
278502
|
+
onparameter && onparameter(k3, v2);
|
|
278461
278503
|
}
|
|
278462
278504
|
}
|
|
278463
278505
|
function ReadyForQuery(x2) {
|
|
@@ -278814,7 +278856,7 @@ function Connection(options, queues = {}, { onopen = noop, onend = noop, onclose
|
|
|
278814
278856
|
client_encoding: "UTF8"
|
|
278815
278857
|
},
|
|
278816
278858
|
options.connection
|
|
278817
|
-
)).filter(([,
|
|
278859
|
+
)).filter(([, v2]) => v2).map(([k3, v2]) => k3 + bytes_default.N + v2).join(bytes_default.N)
|
|
278818
278860
|
).z(2).end(0);
|
|
278819
278861
|
}
|
|
278820
278862
|
}
|
|
@@ -278979,7 +279021,7 @@ function Time(x2) {
|
|
|
278979
279021
|
return new Date(Date.UTC(2e3, 0, 1) + Number(x2 / BigInt(1e3)));
|
|
278980
279022
|
}
|
|
278981
279023
|
function parse(x2, state, parsers2, handle, transform) {
|
|
278982
|
-
const char = (acc, [k3,
|
|
279024
|
+
const char = (acc, [k3, v2]) => (acc[k3.charCodeAt(0)] = v2, acc);
|
|
278983
279025
|
Object.entries({
|
|
278984
279026
|
R: (x3) => {
|
|
278985
279027
|
let i = 1;
|
|
@@ -279476,7 +279518,7 @@ function parseOptions(a, b4) {
|
|
|
279476
279518
|
connection: {
|
|
279477
279519
|
application_name: env.PGAPPNAME || "postgres.js",
|
|
279478
279520
|
...o2.connection,
|
|
279479
|
-
...Object.entries(query).reduce((acc, [k3,
|
|
279521
|
+
...Object.entries(query).reduce((acc, [k3, v2]) => (k3 in defaults || (acc[k3] = v2), acc), {})
|
|
279480
279522
|
},
|
|
279481
279523
|
types: o2.types || {},
|
|
279482
279524
|
target_session_attrs: tsa(o2, url, env),
|
|
@@ -279580,7 +279622,7 @@ var import_source = require("@abloatai/ablo/source");
|
|
|
279580
279622
|
|
|
279581
279623
|
// src/cli/push.ts
|
|
279582
279624
|
init_cjs_shims();
|
|
279583
|
-
var
|
|
279625
|
+
var import_picocolors3 = __toESM(require_picocolors(), 1);
|
|
279584
279626
|
|
|
279585
279627
|
// src/auth/credentialPolicy.ts
|
|
279586
279628
|
init_cjs_shims();
|
|
@@ -279600,6 +279642,7 @@ function classifyCredentialKind(value) {
|
|
|
279600
279642
|
// src/cli/push.ts
|
|
279601
279643
|
var import_fs4 = require("fs");
|
|
279602
279644
|
var import_path3 = require("path");
|
|
279645
|
+
var import_child_process = require("child_process");
|
|
279603
279646
|
var import_schema2 = require("@abloatai/ablo/schema");
|
|
279604
279647
|
|
|
279605
279648
|
// src/cli/config.ts
|
|
@@ -279630,17 +279673,17 @@ function asKeyEntry(value) {
|
|
|
279630
279673
|
}
|
|
279631
279674
|
function asProfileKeys(value) {
|
|
279632
279675
|
if (!value || typeof value !== "object") return void 0;
|
|
279633
|
-
const
|
|
279634
|
-
const sandbox = asKeyEntry(
|
|
279635
|
-
const production = asKeyEntry(
|
|
279676
|
+
const v2 = value;
|
|
279677
|
+
const sandbox = asKeyEntry(v2.sandbox);
|
|
279678
|
+
const production = asKeyEntry(v2.production);
|
|
279636
279679
|
if (!sandbox && !production) return void 0;
|
|
279637
279680
|
return { ...sandbox ? { sandbox } : {}, ...production ? { production } : {} };
|
|
279638
279681
|
}
|
|
279639
279682
|
function asProfileMap(value) {
|
|
279640
279683
|
if (!value || typeof value !== "object") return {};
|
|
279641
279684
|
const out = {};
|
|
279642
|
-
for (const [name,
|
|
279643
|
-
const keys = asProfileKeys(
|
|
279685
|
+
for (const [name, v2] of Object.entries(value)) {
|
|
279686
|
+
const keys = asProfileKeys(v2);
|
|
279644
279687
|
if (keys) out[name] = keys;
|
|
279645
279688
|
}
|
|
279646
279689
|
return out;
|
|
@@ -279656,8 +279699,8 @@ function readJson(path) {
|
|
|
279656
279699
|
}
|
|
279657
279700
|
function asActiveProject(value) {
|
|
279658
279701
|
if (value && typeof value === "object" && typeof value.id === "string" && typeof value.slug === "string") {
|
|
279659
|
-
const
|
|
279660
|
-
return { id:
|
|
279702
|
+
const v2 = value;
|
|
279703
|
+
return { id: v2.id, slug: v2.slug };
|
|
279661
279704
|
}
|
|
279662
279705
|
return void 0;
|
|
279663
279706
|
}
|
|
@@ -279841,6 +279884,19 @@ function resolvePushPlan() {
|
|
|
279841
279884
|
return { flow: mode2, apiKey, source: apiKey ? "stored" : null };
|
|
279842
279885
|
}
|
|
279843
279886
|
|
|
279887
|
+
// src/cli/theme.ts
|
|
279888
|
+
init_cjs_shims();
|
|
279889
|
+
var RESET = "\x1B[0m";
|
|
279890
|
+
var PAPER_BG = "\x1B[48;2;250;250;250m";
|
|
279891
|
+
var BLACK_FG = "\x1B[38;2;0;0;0m";
|
|
279892
|
+
function colorEnabled() {
|
|
279893
|
+
return Boolean(process.stdout.isTTY) && !process.env.NO_COLOR;
|
|
279894
|
+
}
|
|
279895
|
+
function brand(label = "ablo") {
|
|
279896
|
+
if (!colorEnabled()) return label;
|
|
279897
|
+
return `${PAPER_BG}${BLACK_FG} ${label} ${RESET}`;
|
|
279898
|
+
}
|
|
279899
|
+
|
|
279844
279900
|
// src/cli/push.ts
|
|
279845
279901
|
function coerceBackfill(raw) {
|
|
279846
279902
|
if (raw === "true") return true;
|
|
@@ -279854,14 +279910,14 @@ var DEFAULT_URL = "https://api.abloatai.com";
|
|
|
279854
279910
|
function fmtSignal(s) {
|
|
279855
279911
|
const sig = s;
|
|
279856
279912
|
const where = sig.field ? `${sig.model}.${sig.field}` : sig.model;
|
|
279857
|
-
let line = ` \u2022 ${
|
|
279913
|
+
let line = ` \u2022 ${import_picocolors3.default.bold(where ?? "?")} \u2014 ${sig.detail ?? ""}`;
|
|
279858
279914
|
if (sig.shadowed) {
|
|
279859
279915
|
const env = sig.shadowed.environment ?? "production";
|
|
279860
279916
|
const ver = sig.shadowed.version != null ? `v${sig.shadowed.version}` : "active";
|
|
279861
279917
|
const when = sig.shadowed.pushedAt ? new Date(sig.shadowed.pushedAt).toISOString().slice(0, 10) : "unknown date";
|
|
279862
279918
|
const by = sig.shadowed.pushedBy ? ` by ${sig.shadowed.pushedBy}` : "";
|
|
279863
279919
|
line += `
|
|
279864
|
-
${
|
|
279920
|
+
${import_picocolors3.default.dim(`\u21B3 baseline: ${env} ${ver}, pushed ${when}${by}`)}`;
|
|
279865
279921
|
}
|
|
279866
279922
|
return line;
|
|
279867
279923
|
}
|
|
@@ -279893,6 +279949,9 @@ function parsePushArgs(argv) {
|
|
|
279893
279949
|
let exportName = DEFAULT_EXPORT;
|
|
279894
279950
|
let url = process.env.ABLO_API_URL ?? DEFAULT_URL;
|
|
279895
279951
|
let force = false;
|
|
279952
|
+
let yes = false;
|
|
279953
|
+
let allowDirty = false;
|
|
279954
|
+
let dryRun = false;
|
|
279896
279955
|
const renames = [];
|
|
279897
279956
|
const backfills = [];
|
|
279898
279957
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -279910,6 +279969,17 @@ function parsePushArgs(argv) {
|
|
|
279910
279969
|
case "--force":
|
|
279911
279970
|
force = true;
|
|
279912
279971
|
break;
|
|
279972
|
+
case "--yes":
|
|
279973
|
+
case "-y":
|
|
279974
|
+
yes = true;
|
|
279975
|
+
break;
|
|
279976
|
+
case "--allow-dirty":
|
|
279977
|
+
allowDirty = true;
|
|
279978
|
+
break;
|
|
279979
|
+
case "--dry-run":
|
|
279980
|
+
case "--plan":
|
|
279981
|
+
dryRun = true;
|
|
279982
|
+
break;
|
|
279913
279983
|
case "--rename": {
|
|
279914
279984
|
const spec = argv[++i] ?? "";
|
|
279915
279985
|
const [from, to] = spec.split(":");
|
|
@@ -279938,13 +280008,13 @@ function parsePushArgs(argv) {
|
|
|
279938
280008
|
}
|
|
279939
280009
|
}
|
|
279940
280010
|
url = url.replace(/\/+$/, "");
|
|
279941
|
-
return { schemaPath, exportName, url, apiKey: process.env.ABLO_API_KEY, force, renames, backfills };
|
|
280011
|
+
return { schemaPath, exportName, url, apiKey: process.env.ABLO_API_KEY, force, renames, backfills, yes, allowDirty, dryRun };
|
|
279942
280012
|
}
|
|
279943
280013
|
async function loadSchema(schemaPath, exportName) {
|
|
279944
280014
|
const abs = (0, import_path3.resolve)(process.cwd(), schemaPath);
|
|
279945
280015
|
if (!(0, import_fs4.existsSync)(abs)) {
|
|
279946
280016
|
throw new AbloValidationError(
|
|
279947
|
-
`schema not found at ${
|
|
280017
|
+
`schema not found at ${import_picocolors3.default.bold(schemaPath)}. Run ${import_picocolors3.default.bold("npx ablo init")} or pass ${import_picocolors3.default.bold("--schema <path>")}.`,
|
|
279948
280018
|
{ code: "cli_invalid_arguments" }
|
|
279949
280019
|
);
|
|
279950
280020
|
}
|
|
@@ -279955,7 +280025,7 @@ async function loadSchema(schemaPath, exportName) {
|
|
|
279955
280025
|
const schema = mod[exportName] ?? nested?.[exportName];
|
|
279956
280026
|
if (!schema || typeof schema !== "object" || !("models" in schema)) {
|
|
279957
280027
|
throw new AbloValidationError(
|
|
279958
|
-
`${
|
|
280028
|
+
`${import_picocolors3.default.bold(schemaPath)} has no \`${exportName}\` export that looks like a Schema. Did you \`export const ${exportName} = defineSchema({ ... })\`?`,
|
|
279959
280029
|
{ code: "cli_invalid_arguments" }
|
|
279960
280030
|
);
|
|
279961
280031
|
}
|
|
@@ -279964,6 +280034,124 @@ async function loadSchema(schemaPath, exportName) {
|
|
|
279964
280034
|
function maskKey(key) {
|
|
279965
280035
|
return key ? `${key.slice(0, 12)}\u2026` : "(none)";
|
|
279966
280036
|
}
|
|
280037
|
+
function schemaGitState(schemaPath) {
|
|
280038
|
+
try {
|
|
280039
|
+
const out = (0, import_child_process.execFileSync)("git", ["status", "--porcelain", "--", schemaPath], {
|
|
280040
|
+
cwd: process.cwd(),
|
|
280041
|
+
encoding: "utf8",
|
|
280042
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
280043
|
+
}).trim();
|
|
280044
|
+
if (out === "") return { dirty: false, untracked: false };
|
|
280045
|
+
return { dirty: true, untracked: out.startsWith("??") };
|
|
280046
|
+
} catch {
|
|
280047
|
+
return null;
|
|
280048
|
+
}
|
|
280049
|
+
}
|
|
280050
|
+
async function fetchActiveSchema(url, apiKey) {
|
|
280051
|
+
const ctrl = new AbortController();
|
|
280052
|
+
const t = setTimeout(() => ctrl.abort(), 3e3);
|
|
280053
|
+
try {
|
|
280054
|
+
const res = await fetch(`${url}/api/schema`, {
|
|
280055
|
+
headers: { authorization: `Bearer ${apiKey}` },
|
|
280056
|
+
signal: ctrl.signal
|
|
280057
|
+
});
|
|
280058
|
+
if (!res.ok) return null;
|
|
280059
|
+
return await res.json();
|
|
280060
|
+
} catch {
|
|
280061
|
+
return null;
|
|
280062
|
+
} finally {
|
|
280063
|
+
clearTimeout(t);
|
|
280064
|
+
}
|
|
280065
|
+
}
|
|
280066
|
+
function conflictStr(c) {
|
|
280067
|
+
if (!c) return "";
|
|
280068
|
+
const parts = ["user", "agent", "system"].flatMap((k3) => c[k3] ? [`${k3}:${c[k3]}`] : []);
|
|
280069
|
+
return parts.length ? `{${parts.join(",")}}` : "";
|
|
280070
|
+
}
|
|
280071
|
+
function localModels(schema) {
|
|
280072
|
+
const json = JSON.parse((0, import_schema2.serializeSchema)(schema));
|
|
280073
|
+
const out = /* @__PURE__ */ new Map();
|
|
280074
|
+
for (const [key, def] of Object.entries(json.models)) out.set(key, conflictStr(def.conflict));
|
|
280075
|
+
return out;
|
|
280076
|
+
}
|
|
280077
|
+
function printPlan(local, remote) {
|
|
280078
|
+
if (!remote?.models) {
|
|
280079
|
+
console.log(` ${import_picocolors3.default.dim("plan")} ${import_picocolors3.default.dim("(deployed schema unavailable \u2014 the server computes the diff on apply)")}
|
|
280080
|
+
`);
|
|
280081
|
+
return;
|
|
280082
|
+
}
|
|
280083
|
+
const remoteMap = /* @__PURE__ */ new Map();
|
|
280084
|
+
for (const m2 of remote.models) remoteMap.set(m2.key, conflictStr(m2.conflict));
|
|
280085
|
+
const added = [...local.keys()].filter((k3) => !remoteMap.has(k3));
|
|
280086
|
+
const removed = [...remoteMap.keys()].filter((k3) => !local.has(k3));
|
|
280087
|
+
const changed = [...local.keys()].filter((k3) => remoteMap.has(k3) && remoteMap.get(k3) !== local.get(k3));
|
|
280088
|
+
const verLabel = remote.version != null ? `v${remote.version}` : "active";
|
|
280089
|
+
if (added.length === 0 && removed.length === 0 && changed.length === 0) {
|
|
280090
|
+
console.log(` ${import_picocolors3.default.dim("plan")} ${import_picocolors3.default.dim(`no model-level changes vs deployed ${verLabel} (any field changes apply on push)`)}
|
|
280091
|
+
`);
|
|
280092
|
+
return;
|
|
280093
|
+
}
|
|
280094
|
+
console.log(` ${import_picocolors3.default.dim("plan")} ${import_picocolors3.default.dim(`vs deployed ${verLabel}:`)}`);
|
|
280095
|
+
for (const k3 of added) console.log(` ${import_picocolors3.default.green(`+ ${k3}`)} ${import_picocolors3.default.dim("(new model)")}`);
|
|
280096
|
+
for (const k3 of changed)
|
|
280097
|
+
console.log(` ${import_picocolors3.default.yellow(`~ ${k3}`)} ${import_picocolors3.default.dim(`conflict ${remoteMap.get(k3) || "(default)"} \u2192 ${local.get(k3) || "(default)"}`)}`);
|
|
280098
|
+
for (const k3 of removed) console.log(` ${import_picocolors3.default.red(`- ${k3}`)} ${import_picocolors3.default.dim("(removed \u2014 destructive, needs --force)")}`);
|
|
280099
|
+
console.log("");
|
|
280100
|
+
}
|
|
280101
|
+
async function confirmPush(args, env) {
|
|
280102
|
+
const isProd = env === "production";
|
|
280103
|
+
const tty = Boolean(process.stdout.isTTY && process.stdin.isTTY);
|
|
280104
|
+
if (isProd && !args.yes) {
|
|
280105
|
+
const git = schemaGitState(args.schemaPath);
|
|
280106
|
+
if (git?.dirty && !args.allowDirty) {
|
|
280107
|
+
console.error(` ${import_picocolors3.default.red("\u2717")} Refusing to deploy uncommitted schema to ${import_picocolors3.default.red(import_picocolors3.default.bold("production"))}.`);
|
|
280108
|
+
console.error(import_picocolors3.default.dim(` Commit ${import_picocolors3.default.bold(args.schemaPath)} first, or pass ${import_picocolors3.default.bold("--allow-dirty")} to override.`));
|
|
280109
|
+
process.exit(1);
|
|
280110
|
+
}
|
|
280111
|
+
if (!tty) {
|
|
280112
|
+
console.error(` ${import_picocolors3.default.red("\u2717")} Refusing to deploy to ${import_picocolors3.default.red(import_picocolors3.default.bold("production"))} non-interactively without confirmation.`);
|
|
280113
|
+
console.error(import_picocolors3.default.dim(` Re-run with ${import_picocolors3.default.bold("--yes")} to confirm in CI/scripts.`));
|
|
280114
|
+
process.exit(1);
|
|
280115
|
+
}
|
|
280116
|
+
const project = getActiveProject();
|
|
280117
|
+
const expected = project?.slug ?? "production";
|
|
280118
|
+
const typed = await he({
|
|
280119
|
+
message: `This deploys to ${import_picocolors3.default.red(import_picocolors3.default.bold("PRODUCTION"))}. Type ${import_picocolors3.default.bold(expected)} to confirm:`,
|
|
280120
|
+
placeholder: expected
|
|
280121
|
+
});
|
|
280122
|
+
if (pD(typed) || String(typed).trim() !== expected) {
|
|
280123
|
+
xe("Aborted \u2014 confirmation did not match.");
|
|
280124
|
+
process.exit(1);
|
|
280125
|
+
}
|
|
280126
|
+
return;
|
|
280127
|
+
}
|
|
280128
|
+
if (!isProd && !args.yes && tty) {
|
|
280129
|
+
const ok = await ye({ message: `Apply to ${import_picocolors3.default.green("sandbox")}?` });
|
|
280130
|
+
if (pD(ok) || !ok) {
|
|
280131
|
+
xe("Aborted.");
|
|
280132
|
+
process.exit(1);
|
|
280133
|
+
}
|
|
280134
|
+
}
|
|
280135
|
+
}
|
|
280136
|
+
function printPushTarget(opts) {
|
|
280137
|
+
const env = modeFromKey(opts.apiKey);
|
|
280138
|
+
const envLabel = env === "production" ? import_picocolors3.default.red(import_picocolors3.default.bold("production")) : env === "sandbox" ? import_picocolors3.default.green("sandbox") : import_picocolors3.default.yellow("unknown env");
|
|
280139
|
+
const project = getActiveProject();
|
|
280140
|
+
const projectLabel = project ? `${import_picocolors3.default.bold(project.slug)} ${import_picocolors3.default.dim(`(${project.id})`)}` : `${import_picocolors3.default.bold("default")} ${import_picocolors3.default.dim("(org-default \u2014 `ablo projects use <slug>` to scope)")}`;
|
|
280141
|
+
const cliMode = getMode();
|
|
280142
|
+
const modeNote = env && env !== cliMode ? ` ${import_picocolors3.default.yellow(`(CLI mode is ${cliMode} \u2014 this key targets ${env})`)}` : "";
|
|
280143
|
+
console.log(`
|
|
280144
|
+
${brand("ablo")} ${import_picocolors3.default.dim("push")} ${import_picocolors3.default.dim("\u2192")} ${envLabel}${modeNote}`);
|
|
280145
|
+
console.log(` ${import_picocolors3.default.dim("project")} ${projectLabel}`);
|
|
280146
|
+
console.log(` ${import_picocolors3.default.dim("target")} ${import_picocolors3.default.dim(opts.url)}`);
|
|
280147
|
+
console.log(
|
|
280148
|
+
` ${import_picocolors3.default.dim("key")} ${maskKey(opts.apiKey)} ${import_picocolors3.default.dim(`(${describeKeySource(opts.keySource)})`)}`
|
|
280149
|
+
);
|
|
280150
|
+
console.log(
|
|
280151
|
+
` ${import_picocolors3.default.dim("schema")} ${import_picocolors3.default.bold(opts.schemaPath)} ${import_picocolors3.default.dim(`\xB7 ${opts.modelCount} models \xB7 hash ${opts.hash}`)}
|
|
280152
|
+
`
|
|
280153
|
+
);
|
|
280154
|
+
}
|
|
279967
280155
|
function describeKeySource(source) {
|
|
279968
280156
|
switch (source) {
|
|
279969
280157
|
case "env":
|
|
@@ -279981,7 +280169,7 @@ async function push(argv) {
|
|
|
279981
280169
|
try {
|
|
279982
280170
|
args = parsePushArgs(argv);
|
|
279983
280171
|
} catch (err) {
|
|
279984
|
-
console.error(
|
|
280172
|
+
console.error(import_picocolors3.default.red(` ${err instanceof Error ? err.message : String(err)}`));
|
|
279985
280173
|
process.exit(1);
|
|
279986
280174
|
}
|
|
279987
280175
|
let keySource = "env";
|
|
@@ -279997,26 +280185,44 @@ async function push(argv) {
|
|
|
279997
280185
|
}
|
|
279998
280186
|
if (!args.apiKey) {
|
|
279999
280187
|
console.error(
|
|
280000
|
-
|
|
280001
|
-
` Run ${
|
|
280188
|
+
import_picocolors3.default.red(` No API key.`) + import_picocolors3.default.dim(
|
|
280189
|
+
` Run ${import_picocolors3.default.bold("npx ablo login")} for the sandbox dev loop \u2014 or set ${import_picocolors3.default.bold("ABLO_API_KEY")} (${import_picocolors3.default.bold("sk_test_")} = sandbox; ${import_picocolors3.default.bold("sk_live_")} = deliberate production deploy). Mode is currently '${getMode()}'.`
|
|
280002
280190
|
)
|
|
280003
280191
|
);
|
|
280004
280192
|
process.exit(1);
|
|
280005
280193
|
}
|
|
280006
280194
|
const schema = await loadSchema(args.schemaPath, args.exportName);
|
|
280007
280195
|
const hash = (0, import_schema2.schemaHash)(schema);
|
|
280008
|
-
|
|
280009
|
-
|
|
280010
|
-
|
|
280196
|
+
printPushTarget({
|
|
280197
|
+
schemaPath: args.schemaPath,
|
|
280198
|
+
url: args.url,
|
|
280199
|
+
apiKey: args.apiKey,
|
|
280200
|
+
keySource,
|
|
280201
|
+
modelCount: Object.keys(schema.models).length,
|
|
280202
|
+
hash
|
|
280203
|
+
});
|
|
280204
|
+
const remote = await fetchActiveSchema(args.url, args.apiKey);
|
|
280205
|
+
printPlan(localModels(schema), remote);
|
|
280206
|
+
const git = schemaGitState(args.schemaPath);
|
|
280207
|
+
if (git?.dirty) {
|
|
280208
|
+
const what = git.untracked ? "is untracked (not committed)" : "has uncommitted changes";
|
|
280209
|
+
console.log(` ${import_picocolors3.default.yellow("\u26A0")} ${import_picocolors3.default.bold(args.schemaPath)} ${what} \u2014 this deploy won't match a git commit.
|
|
280210
|
+
`);
|
|
280211
|
+
}
|
|
280212
|
+
if (args.dryRun) {
|
|
280213
|
+
console.log(` ${import_picocolors3.default.dim("\u25CB")} dry run \u2014 nothing applied. Re-run without ${import_picocolors3.default.bold("--dry-run")} to deploy.`);
|
|
280214
|
+
return;
|
|
280215
|
+
}
|
|
280216
|
+
await confirmPush(args, modeFromKey(args.apiKey));
|
|
280011
280217
|
const { ok: resOk, status: status2, body, bodyText } = await pushSchema(schema, args);
|
|
280012
280218
|
if (resOk) {
|
|
280013
280219
|
if (body.unchanged) {
|
|
280014
|
-
console.log(` ${
|
|
280220
|
+
console.log(` ${import_picocolors3.default.dim("\u25CB")} No changes \u2014 schema already active (v${body.version}).`);
|
|
280015
280221
|
} else {
|
|
280016
|
-
console.log(` ${
|
|
280222
|
+
console.log(` ${import_picocolors3.default.green("\u2713")} Activated ${import_picocolors3.default.bold(`v${body.version}`)} ${import_picocolors3.default.dim(`(hash ${body.hash})`)}`);
|
|
280017
280223
|
if (Array.isArray(body.warnings) && body.warnings.length > 0) {
|
|
280018
|
-
console.log(
|
|
280019
|
-
for (const w2 of body.warnings) console.log(
|
|
280224
|
+
console.log(import_picocolors3.default.yellow(` Applied ${body.warnings.length} destructive change(s):`));
|
|
280225
|
+
for (const w2 of body.warnings) console.log(import_picocolors3.default.yellow(fmtSignal(w2)));
|
|
280020
280226
|
}
|
|
280021
280227
|
}
|
|
280022
280228
|
return;
|
|
@@ -280024,63 +280230,69 @@ async function push(argv) {
|
|
|
280024
280230
|
if (status2 === 409) {
|
|
280025
280231
|
const unexecutable = Array.isArray(body.unexecutable) ? body.unexecutable : [];
|
|
280026
280232
|
const warnings = Array.isArray(body.warnings) ? body.warnings : [];
|
|
280027
|
-
console.error(
|
|
280233
|
+
console.error(import_picocolors3.default.red(" Incompatible change \u2014 this push is not safe to apply as-is."));
|
|
280028
280234
|
if (unexecutable.length > 0) {
|
|
280029
|
-
console.error(
|
|
280030
|
-
for (const u2 of unexecutable) console.error(
|
|
280235
|
+
console.error(import_picocolors3.default.red(` Unexecutable (would fail on existing rows):`));
|
|
280236
|
+
for (const u2 of unexecutable) console.error(import_picocolors3.default.red(fmtSignal(u2)));
|
|
280031
280237
|
}
|
|
280032
280238
|
if (warnings.length > 0) {
|
|
280033
|
-
console.error(
|
|
280034
|
-
for (const w2 of warnings) console.error(
|
|
280239
|
+
console.error(import_picocolors3.default.yellow(` Destructive (data loss):`));
|
|
280240
|
+
for (const w2 of warnings) console.error(import_picocolors3.default.yellow(fmtSignal(w2)));
|
|
280035
280241
|
}
|
|
280036
280242
|
const hasShadowed = [...unexecutable, ...warnings].some(
|
|
280037
280243
|
(s) => s.shadowed != null
|
|
280038
280244
|
);
|
|
280039
280245
|
if (hasShadowed) {
|
|
280040
280246
|
console.error(
|
|
280041
|
-
|
|
280247
|
+
import_picocolors3.default.dim(
|
|
280042
280248
|
" These models exist in the baseline above but not in your push. Sandbox readers fall"
|
|
280043
280249
|
)
|
|
280044
280250
|
);
|
|
280045
280251
|
console.error(
|
|
280046
|
-
|
|
280252
|
+
import_picocolors3.default.dim(
|
|
280047
280253
|
" back to the production schema until you push your own, so applying this drops them."
|
|
280048
280254
|
)
|
|
280049
280255
|
);
|
|
280050
280256
|
}
|
|
280051
|
-
console.error(
|
|
280257
|
+
console.error(import_picocolors3.default.dim(` Re-push with ${import_picocolors3.default.bold("--force")} to override, or use ${import_picocolors3.default.bold("--rename old:new")} if you renamed a model.`));
|
|
280052
280258
|
} else if (status2 === 403) {
|
|
280053
280259
|
const code = body.code ?? body.reason;
|
|
280054
280260
|
const serverMsg = body.message ?? body.reason;
|
|
280055
|
-
console.error(
|
|
280056
|
-
console.error(
|
|
280261
|
+
console.error(import_picocolors3.default.red(` Forbidden${code ? ` [${code}]` : ""}: ${serverMsg ?? "permission denied"}`));
|
|
280262
|
+
console.error(import_picocolors3.default.dim(` Push used ${import_picocolors3.default.bold(maskKey(args.apiKey))} from ${describeKeySource(keySource)}.`));
|
|
280057
280263
|
if (code === "database_role_cannot_enforce_rls") {
|
|
280058
280264
|
console.error(
|
|
280059
|
-
|
|
280060
|
-
` Your database role bypasses row-level security. Run ${
|
|
280265
|
+
import_picocolors3.default.dim(
|
|
280266
|
+
` Your database role bypasses row-level security. Run ${import_picocolors3.default.bold("npx ablo migrate")} to create a scoped (NOBYPASSRLS) role and repoint DATABASE_URL, then re-push.`
|
|
280061
280267
|
)
|
|
280062
280268
|
);
|
|
280063
280269
|
} else if (code === "database_tables_unforced_rls") {
|
|
280064
280270
|
console.error(
|
|
280065
|
-
|
|
280066
|
-
` One or more synced tables don't have FORCE ROW LEVEL SECURITY. Run ${
|
|
280271
|
+
import_picocolors3.default.dim(
|
|
280272
|
+
` One or more synced tables don't have FORCE ROW LEVEL SECURITY. Run ${import_picocolors3.default.bold("npx ablo migrate")} to (re)apply the tenant policies, then re-push.`
|
|
280273
|
+
)
|
|
280274
|
+
);
|
|
280275
|
+
} else if (code === "capability_scope_denied" || code === "capability_invalid") {
|
|
280276
|
+
console.error(
|
|
280277
|
+
import_picocolors3.default.dim(
|
|
280278
|
+
` This is a ${import_picocolors3.default.bold("database privilege")} error (Postgres 42501 / row-level security), not a key scope \u2014 a different API key won't help. The role behind this org's database can't write the target. Provision a writable, RLS-scoped role with ${import_picocolors3.default.bold("npx ablo migrate")}, or check the org's database registration. See docs/plans/read-path-logical-replication-vs-hosting.md.`
|
|
280067
280279
|
)
|
|
280068
280280
|
);
|
|
280069
280281
|
} else if (args.apiKey != null && classifyCredentialKind(args.apiKey) === "restricted") {
|
|
280070
280282
|
console.error(
|
|
280071
|
-
|
|
280072
|
-
` Schema pushes need a SECRET key: ${
|
|
280283
|
+
import_picocolors3.default.dim(
|
|
280284
|
+
` Schema pushes need a SECRET key: ${import_picocolors3.default.bold("sk_test_")} (sandbox dev loop) or a dashboard ${import_picocolors3.default.bold("sk_live_")} (production deploy: ${import_picocolors3.default.bold("ABLO_API_KEY=sk_live_\u2026 npx ablo push")}).`
|
|
280073
280285
|
)
|
|
280074
280286
|
);
|
|
280075
280287
|
} else {
|
|
280076
280288
|
console.error(
|
|
280077
|
-
|
|
280078
|
-
` This key isn't authorized to push schema (needs ${
|
|
280289
|
+
import_picocolors3.default.dim(
|
|
280290
|
+
` This key isn't authorized to push schema (needs ${import_picocolors3.default.bold("schema:push")}). ` + (keySource === "login" ? `It's your stored ${import_picocolors3.default.bold("ablo login")} sandbox key \u2014 a key in ${import_picocolors3.default.bold(".env.local")} or ${import_picocolors3.default.bold("ABLO_API_KEY")} takes precedence, so put a schema:push key there (sandbox ${import_picocolors3.default.bold("sk_test_")} or production ${import_picocolors3.default.bold("sk_live_")}) and re-push. ` : `Use a schema:push key \u2014 a sandbox ${import_picocolors3.default.bold("sk_test_")} or production ${import_picocolors3.default.bold("sk_live_")}. `) + `Manage keys at https://abloatai.com`
|
|
280079
280291
|
)
|
|
280080
280292
|
);
|
|
280081
280293
|
}
|
|
280082
280294
|
} else {
|
|
280083
|
-
console.error(
|
|
280295
|
+
console.error(import_picocolors3.default.red(` Push failed (${status2}): ${body.message ?? body.reason ?? bodyText}`));
|
|
280084
280296
|
}
|
|
280085
280297
|
process.exit(1);
|
|
280086
280298
|
}
|
|
@@ -280140,8 +280352,8 @@ function planFor(schema, targetSchema = "public") {
|
|
|
280140
280352
|
}
|
|
280141
280353
|
var log = {
|
|
280142
280354
|
info: (msg, fields) => console.log(`[migrate] ${msg}`, fields),
|
|
280143
|
-
warn: (msg, fields) => console.warn(
|
|
280144
|
-
error: (msg, fields) => console.error(
|
|
280355
|
+
warn: (msg, fields) => console.warn(import_picocolors4.default.yellow(`[migrate] ${msg}`), fields),
|
|
280356
|
+
error: (msg, fields) => console.error(import_picocolors4.default.red(`[migrate] ${msg}`), fields)
|
|
280145
280357
|
};
|
|
280146
280358
|
var PG_LOCK_NOT_AVAILABLE = "55P03";
|
|
280147
280359
|
var LOCK_TIMEOUT = process.env.ABLO_SCHEMA_LOCK_TIMEOUT ?? process.env.ABLO_DDL_LOCK_TIMEOUT ?? "5s";
|
|
@@ -280216,7 +280428,7 @@ async function migrate(argv) {
|
|
|
280216
280428
|
try {
|
|
280217
280429
|
args = parseMigrateArgs(argv);
|
|
280218
280430
|
} catch (err) {
|
|
280219
|
-
console.error(
|
|
280431
|
+
console.error(import_picocolors4.default.red(` ${err instanceof Error ? err.message : String(err)}`));
|
|
280220
280432
|
process.exit(1);
|
|
280221
280433
|
}
|
|
280222
280434
|
const schema = await loadSchema(args.schemaPath, args.exportName);
|
|
@@ -280227,11 +280439,11 @@ async function migrate(argv) {
|
|
|
280227
280439
|
].join("\n");
|
|
280228
280440
|
const totalStatements = plan.statements.length + plan.concurrent.length;
|
|
280229
280441
|
console.log(
|
|
280230
|
-
` ${
|
|
280442
|
+
` ${import_picocolors4.default.dim("Schema")} ${import_picocolors4.default.bold(args.schemaPath)} \u2192 ${import_picocolors4.default.dim(`${Object.keys(schema.models).length} models, ${totalStatements} statements`)}`
|
|
280231
280443
|
);
|
|
280232
280444
|
if (args.outputFile) {
|
|
280233
280445
|
(0, import_fs5.writeFileSync)(args.outputFile, sql + "\n");
|
|
280234
|
-
console.log(` ${
|
|
280446
|
+
console.log(` ${import_picocolors4.default.green("\u2713")} SQL written to ${import_picocolors4.default.bold(args.outputFile)}`);
|
|
280235
280447
|
return;
|
|
280236
280448
|
}
|
|
280237
280449
|
if (args.dryRun) {
|
|
@@ -280241,7 +280453,7 @@ async function migrate(argv) {
|
|
|
280241
280453
|
const dbUrl = readProjectDatabaseUrl();
|
|
280242
280454
|
if (!dbUrl) {
|
|
280243
280455
|
console.error(
|
|
280244
|
-
|
|
280456
|
+
import_picocolors4.default.red(
|
|
280245
280457
|
" No DATABASE_URL found (checked process env, .env.local, .env). Set it to apply, or use --dry-run to preview."
|
|
280246
280458
|
)
|
|
280247
280459
|
);
|
|
@@ -280249,7 +280461,7 @@ async function migrate(argv) {
|
|
|
280249
280461
|
}
|
|
280250
280462
|
try {
|
|
280251
280463
|
await applyStatements(dbUrl, args.targetSchema, plan.statements, plan.concurrent);
|
|
280252
|
-
console.log(` ${
|
|
280464
|
+
console.log(` ${import_picocolors4.default.green("\u2713")} Migration complete`);
|
|
280253
280465
|
} catch {
|
|
280254
280466
|
process.exit(1);
|
|
280255
280467
|
}
|
|
@@ -280257,26 +280469,13 @@ async function migrate(argv) {
|
|
|
280257
280469
|
|
|
280258
280470
|
// src/cli/connect.ts
|
|
280259
280471
|
init_cjs_shims();
|
|
280260
|
-
var
|
|
280261
|
-
|
|
280262
|
-
// src/cli/theme.ts
|
|
280263
|
-
init_cjs_shims();
|
|
280264
|
-
var RESET = "\x1B[0m";
|
|
280265
|
-
var PAPER_BG = "\x1B[48;2;250;250;250m";
|
|
280266
|
-
var BLACK_FG = "\x1B[38;2;0;0;0m";
|
|
280267
|
-
function colorEnabled() {
|
|
280268
|
-
return Boolean(process.stdout.isTTY) && !process.env.NO_COLOR;
|
|
280269
|
-
}
|
|
280270
|
-
function brand(label = "ablo") {
|
|
280271
|
-
if (!colorEnabled()) return label;
|
|
280272
|
-
return `${PAPER_BG}${BLACK_FG} ${label} ${RESET}`;
|
|
280273
|
-
}
|
|
280274
|
-
|
|
280275
|
-
// src/cli/connect.ts
|
|
280472
|
+
var import_picocolors5 = __toESM(require_picocolors(), 1);
|
|
280276
280473
|
var ABLO_PUBLICATION = "ablo_publication";
|
|
280277
280474
|
var ABLO_REPLICATION_ROLE = "ablo_replicator";
|
|
280278
280475
|
function parseConnectArgs(argv) {
|
|
280279
280476
|
let check2 = false;
|
|
280477
|
+
let register = false;
|
|
280478
|
+
let auditInfra = false;
|
|
280280
280479
|
let tables = [];
|
|
280281
280480
|
let role = ABLO_REPLICATION_ROLE;
|
|
280282
280481
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -280285,6 +280484,12 @@ function parseConnectArgs(argv) {
|
|
|
280285
280484
|
case "--check":
|
|
280286
280485
|
check2 = true;
|
|
280287
280486
|
break;
|
|
280487
|
+
case "--register":
|
|
280488
|
+
register = true;
|
|
280489
|
+
break;
|
|
280490
|
+
case "--audit-infra":
|
|
280491
|
+
auditInfra = true;
|
|
280492
|
+
break;
|
|
280288
280493
|
case "--tables": {
|
|
280289
280494
|
const value = argv[++i] ?? "";
|
|
280290
280495
|
tables = value.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
|
|
@@ -280297,7 +280502,7 @@ function parseConnectArgs(argv) {
|
|
|
280297
280502
|
throw new AbloValidationError(`unknown flag: ${arg}`, { code: "cli_invalid_arguments" });
|
|
280298
280503
|
}
|
|
280299
280504
|
}
|
|
280300
|
-
return { check: check2, tables, role };
|
|
280505
|
+
return { check: check2, register, auditInfra, tables, role };
|
|
280301
280506
|
}
|
|
280302
280507
|
function quoteIdent(id) {
|
|
280303
280508
|
return `"${id.replace(/"/g, '""')}"`;
|
|
@@ -280321,74 +280526,89 @@ function connectSetupSql(input) {
|
|
|
280321
280526
|
function printConnectRecipe(args) {
|
|
280322
280527
|
const sql = connectSetupSql({ tables: args.tables, role: args.role });
|
|
280323
280528
|
console.log(`
|
|
280324
|
-
${brand("ablo")} ${
|
|
280529
|
+
${brand("ablo")} ${import_picocolors5.default.dim("connect")} ${import_picocolors5.default.dim("logical replication \u2014 the read path (your writes stay on your own backend)")}
|
|
280325
280530
|
`);
|
|
280326
280531
|
console.log(
|
|
280327
|
-
` Ablo
|
|
280328
|
-
schema. Your app
|
|
280329
|
-
Run this once against your Postgres ${
|
|
280532
|
+
` Ablo consumes your write-ahead log (WAL) via logical replication and ${import_picocolors5.default.bold("never")} runs DDL,
|
|
280533
|
+
owns, hosts, or migrates your schema. Your app continues to own the write path \u2014 Ablo tails
|
|
280534
|
+
the changes and serves them as live shapes. Run this once against your Postgres ${import_picocolors5.default.dim("(as a superuser / DB owner)")}:
|
|
280330
280535
|
`
|
|
280331
280536
|
);
|
|
280332
|
-
console.log(` ${
|
|
280333
|
-
console.log(` ${
|
|
280537
|
+
console.log(` ${import_picocolors5.default.bold("1.")} Enable logical decoding ${import_picocolors5.default.dim("(then RESTART Postgres \u2014 wal_level is not reloadable)")}`);
|
|
280538
|
+
console.log(` ${import_picocolors5.default.cyan(sql[0])}`);
|
|
280334
280539
|
console.log(
|
|
280335
|
-
|
|
280336
|
-
` On Amazon RDS / Aurora you can't ALTER SYSTEM: set ${
|
|
280540
|
+
import_picocolors5.default.dim(
|
|
280541
|
+
` On Amazon RDS / Aurora you can't ALTER SYSTEM: set ${import_picocolors5.default.bold("rds.logical_replication = 1")} in the
|
|
280337
280542
|
instance's parameter group instead, then reboot.`
|
|
280338
280543
|
)
|
|
280339
280544
|
);
|
|
280340
280545
|
console.log(`
|
|
280341
|
-
${
|
|
280342
|
-
console.log(` ${
|
|
280546
|
+
${import_picocolors5.default.bold("2.")} Publish the tables Ablo should read`);
|
|
280547
|
+
console.log(` ${import_picocolors5.default.cyan(sql[1])}`);
|
|
280343
280548
|
if (args.tables.length === 0) {
|
|
280344
|
-
console.log(
|
|
280549
|
+
console.log(import_picocolors5.default.dim(` (Scope it with ${import_picocolors5.default.bold("ablo connect --tables a,b,c")} to publish a subset.)`));
|
|
280345
280550
|
}
|
|
280346
280551
|
console.log(`
|
|
280347
|
-
${
|
|
280348
|
-
console.log(` ${
|
|
280349
|
-
console.log(` ${
|
|
280350
|
-
console.log(` ${
|
|
280552
|
+
${import_picocolors5.default.bold("3.")} Create a least-privilege replication role ${import_picocolors5.default.dim("(pick your own password)")}`);
|
|
280553
|
+
console.log(` ${import_picocolors5.default.cyan(sql[2])}`);
|
|
280554
|
+
console.log(` ${import_picocolors5.default.cyan(sql[3])}`);
|
|
280555
|
+
console.log(` ${import_picocolors5.default.cyan(sql[4])}`);
|
|
280351
280556
|
console.log(
|
|
280352
|
-
|
|
280557
|
+
import_picocolors5.default.dim(
|
|
280353
280558
|
` On Amazon RDS, the REPLICATION attribute is granted, not set directly:
|
|
280354
|
-
${
|
|
280559
|
+
${import_picocolors5.default.bold(`GRANT rds_replication TO ${quoteIdent(args.role)};`)}`
|
|
280355
280560
|
)
|
|
280356
280561
|
);
|
|
280357
280562
|
console.log(
|
|
280358
280563
|
`
|
|
280359
|
-
${
|
|
280360
|
-
${
|
|
280564
|
+
${import_picocolors5.default.bold("4.")} Put the role's connection string in ${import_picocolors5.default.bold("DATABASE_URL")}, then verify:
|
|
280565
|
+
${import_picocolors5.default.cyan("npx ablo connect --check")}
|
|
280361
280566
|
`
|
|
280362
280567
|
);
|
|
280363
280568
|
console.log(
|
|
280364
|
-
|
|
280365
|
-
` Reminder: Ablo never writes to your database
|
|
280366
|
-
|
|
280569
|
+
import_picocolors5.default.dim(
|
|
280570
|
+
` Reminder: this is the READ path \u2014 Ablo tails your WAL and never writes to your database.
|
|
280571
|
+
Your writes keep going through your own backend. (Ablo HOSTING your rows, or dialing in via
|
|
280572
|
+
${import_picocolors5.default.bold("databaseUrl")}, is the deprecated posture \u2014 see the read-path decision doc.)`
|
|
280367
280573
|
)
|
|
280368
280574
|
);
|
|
280369
280575
|
console.log();
|
|
280370
280576
|
}
|
|
280577
|
+
var SYNC_INFRA_RELATIONS = [
|
|
280578
|
+
"sync_deltas",
|
|
280579
|
+
"sync_id_seq",
|
|
280580
|
+
"sync_metadata",
|
|
280581
|
+
"mutation_log"
|
|
280582
|
+
];
|
|
280583
|
+
var SYNC_INFRA_TYPES = [
|
|
280584
|
+
"participant_kind",
|
|
280585
|
+
"backfill_provenance",
|
|
280586
|
+
"confirmation_state"
|
|
280587
|
+
];
|
|
280371
280588
|
function printCheckItem(item) {
|
|
280372
280589
|
if (item.ok) {
|
|
280373
|
-
console.log(` ${
|
|
280590
|
+
console.log(` ${import_picocolors5.default.green("\u2713")} ${item.label}`);
|
|
280374
280591
|
} else {
|
|
280375
|
-
console.log(` ${
|
|
280592
|
+
console.log(` ${import_picocolors5.default.red("\u2717")} ${item.label}`);
|
|
280376
280593
|
if (item.fix) {
|
|
280377
|
-
for (const line of item.fix.split("\n")) console.log(` ${
|
|
280594
|
+
for (const line of item.fix.split("\n")) console.log(` ${import_picocolors5.default.red("\u2022")} ${line}`);
|
|
280378
280595
|
}
|
|
280379
280596
|
}
|
|
280380
280597
|
}
|
|
280381
280598
|
async function probeReadiness(sql, opts = {}) {
|
|
280382
280599
|
const publication = opts.publication ?? ABLO_PUBLICATION;
|
|
280383
280600
|
const items = [];
|
|
280384
|
-
const walRows = await sql.unsafe(
|
|
280601
|
+
const walRows = await sql.unsafe(
|
|
280602
|
+
`SELECT setting FROM pg_settings WHERE name = 'wal_level'`
|
|
280603
|
+
);
|
|
280385
280604
|
const walLevel = walRows[0]?.setting ?? "unknown";
|
|
280386
280605
|
items.push(
|
|
280387
|
-
walLevel === "logical" ? { ok: true, label: `wal_level is ${
|
|
280606
|
+
walLevel === "logical" ? { ok: true, label: `wal_level is ${import_picocolors5.default.bold("logical")}` } : {
|
|
280388
280607
|
ok: false,
|
|
280389
|
-
label: `wal_level is ${
|
|
280608
|
+
label: `wal_level is ${import_picocolors5.default.bold(walLevel)} (need ${import_picocolors5.default.bold("logical")})`,
|
|
280390
280609
|
fix: `ALTER SYSTEM SET wal_level = 'logical'; then RESTART Postgres.
|
|
280391
|
-
On RDS/Aurora set rds.logical_replication = 1 in the parameter group, then reboot
|
|
280610
|
+
On RDS/Aurora set rds.logical_replication = 1 in the parameter group, then reboot.
|
|
280611
|
+
On Neon enable Logical Replication in the project (Console \u2192 Settings \u2192 Logical Replication, or the API) \u2014 Neon forbids ALTER SYSTEM; the toggle sets wal_level=logical.`
|
|
280392
280612
|
}
|
|
280393
280613
|
);
|
|
280394
280614
|
const pubRows = await sql.unsafe(
|
|
@@ -280398,10 +280618,10 @@ On RDS/Aurora set rds.logical_replication = 1 in the parameter group, then reboo
|
|
|
280398
280618
|
items.push(
|
|
280399
280619
|
pubRows.length > 0 ? {
|
|
280400
280620
|
ok: true,
|
|
280401
|
-
label: `publication ${
|
|
280621
|
+
label: `publication ${import_picocolors5.default.bold(publication)} exists ${import_picocolors5.default.dim(pubRows[0].puballtables ? "(all tables)" : "(table subset)")}`
|
|
280402
280622
|
} : {
|
|
280403
280623
|
ok: false,
|
|
280404
|
-
label: `publication ${
|
|
280624
|
+
label: `publication ${import_picocolors5.default.bold(publication)} not found`,
|
|
280405
280625
|
fix: `CREATE PUBLICATION ${quoteIdent(publication)} FOR ALL TABLES;`
|
|
280406
280626
|
}
|
|
280407
280627
|
);
|
|
@@ -280411,9 +280631,9 @@ On RDS/Aurora set rds.logical_replication = 1 in the parameter group, then reboo
|
|
|
280411
280631
|
const role = roleRows[0];
|
|
280412
280632
|
const hasReplication = Boolean(role && (role.rolreplication || role.rolsuper));
|
|
280413
280633
|
items.push(
|
|
280414
|
-
hasReplication ? { ok: true, label: `DATABASE_URL role can stream replication ${
|
|
280634
|
+
hasReplication ? { ok: true, label: `DATABASE_URL role can stream replication ${import_picocolors5.default.dim("(REPLICATION)")}` } : {
|
|
280415
280635
|
ok: false,
|
|
280416
|
-
label: `DATABASE_URL role lacks the ${
|
|
280636
|
+
label: `DATABASE_URL role lacks the ${import_picocolors5.default.bold("REPLICATION")} attribute`,
|
|
280417
280637
|
fix: `ALTER ROLE current_user WITH REPLICATION;
|
|
280418
280638
|
On RDS: GRANT rds_replication TO <your_role>;`
|
|
280419
280639
|
}
|
|
@@ -280449,17 +280669,35 @@ On RDS: GRANT rds_replication TO <your_role>;`
|
|
|
280449
280669
|
}
|
|
280450
280670
|
return items;
|
|
280451
280671
|
}
|
|
280452
|
-
async function
|
|
280672
|
+
async function auditTenantSyncInfra(sql) {
|
|
280673
|
+
const artifacts = [];
|
|
280674
|
+
for (const name of SYNC_INFRA_RELATIONS) {
|
|
280675
|
+
const rows = await sql.unsafe(
|
|
280676
|
+
`SELECT to_regclass($1)::text AS reg`,
|
|
280677
|
+
[`public.${name}`]
|
|
280678
|
+
);
|
|
280679
|
+
artifacts.push({ kind: "relation", name, present: rows[0]?.reg != null });
|
|
280680
|
+
}
|
|
280681
|
+
for (const name of SYNC_INFRA_TYPES) {
|
|
280682
|
+
const rows = await sql.unsafe(
|
|
280683
|
+
`SELECT to_regtype($1)::text AS reg`,
|
|
280684
|
+
[`public.${name}`]
|
|
280685
|
+
);
|
|
280686
|
+
artifacts.push({ kind: "type", name, present: rows[0]?.reg != null });
|
|
280687
|
+
}
|
|
280688
|
+
return artifacts;
|
|
280689
|
+
}
|
|
280690
|
+
function requireDatabaseUrl(verb) {
|
|
280453
280691
|
const dbUrl = readProjectDatabaseUrl();
|
|
280454
280692
|
if (!dbUrl) {
|
|
280455
280693
|
console.error(
|
|
280456
|
-
|
|
280694
|
+
import_picocolors5.default.red(" No DATABASE_URL found (checked process env, .env.local, .env).") + import_picocolors5.default.dim(` Set it to the Postgres you want Ablo to read, then re-run ${import_picocolors5.default.bold(`ablo connect ${verb}`)}.`)
|
|
280457
280695
|
);
|
|
280458
280696
|
process.exit(1);
|
|
280459
280697
|
}
|
|
280460
|
-
|
|
280461
|
-
|
|
280462
|
-
|
|
280698
|
+
return dbUrl;
|
|
280699
|
+
}
|
|
280700
|
+
async function probeAndReport(dbUrl) {
|
|
280463
280701
|
const sql = src_default(dbUrl, { max: 1, prepare: false, onnotice: () => {
|
|
280464
280702
|
} });
|
|
280465
280703
|
let items;
|
|
@@ -280467,55 +280705,170 @@ async function runCheck() {
|
|
|
280467
280705
|
items = await probeReadiness(sql);
|
|
280468
280706
|
} catch (err) {
|
|
280469
280707
|
const pg = err ?? {};
|
|
280470
|
-
console.error(
|
|
280708
|
+
console.error(import_picocolors5.default.red(` Couldn't read the database: ${pg.message ?? String(err)}`));
|
|
280471
280709
|
await sql.end({ timeout: 2 });
|
|
280472
280710
|
process.exit(1);
|
|
280473
280711
|
}
|
|
280474
280712
|
await sql.end({ timeout: 2 });
|
|
280475
280713
|
for (const item of items) printCheckItem(item);
|
|
280476
|
-
|
|
280714
|
+
return items.filter((i) => !i.ok).length;
|
|
280715
|
+
}
|
|
280716
|
+
async function runCheck() {
|
|
280717
|
+
const dbUrl = requireDatabaseUrl("--check");
|
|
280718
|
+
console.log(`
|
|
280719
|
+
${brand("ablo")} ${import_picocolors5.default.dim("connect --check")} ${import_picocolors5.default.dim("logical-replication readiness")}
|
|
280720
|
+
`);
|
|
280721
|
+
const failures = await probeAndReport(dbUrl);
|
|
280477
280722
|
console.log();
|
|
280478
280723
|
if (failures === 0) {
|
|
280479
|
-
console.log(` ${
|
|
280724
|
+
console.log(` ${import_picocolors5.default.green("\u2713")} Ready \u2014 Ablo can connect and tail this database's WAL.
|
|
280480
280725
|
`);
|
|
280481
280726
|
process.exit(0);
|
|
280482
280727
|
}
|
|
280483
280728
|
console.log(
|
|
280484
|
-
` ${
|
|
280729
|
+
` ${import_picocolors5.default.red(`${failures} item${failures === 1 ? "" : "s"} to fix`)} ${import_picocolors5.default.dim(`\u2014 apply the fixes above, then re-run ${import_picocolors5.default.bold("ablo connect --check")}.`)}
|
|
280485
280730
|
`
|
|
280486
280731
|
);
|
|
280487
280732
|
process.exit(1);
|
|
280488
280733
|
}
|
|
280734
|
+
async function runRegister() {
|
|
280735
|
+
const dbUrl = requireDatabaseUrl("--register");
|
|
280736
|
+
const apiKey = resolveApiKey();
|
|
280737
|
+
if (!apiKey) {
|
|
280738
|
+
console.error(
|
|
280739
|
+
import_picocolors5.default.red(" Not logged in.") + import_picocolors5.default.dim(` Run ${import_picocolors5.default.bold("ablo login")} (or set ${import_picocolors5.default.bold("ABLO_API_KEY")}) so Ablo knows which project to register this database for.`)
|
|
280740
|
+
);
|
|
280741
|
+
process.exit(1);
|
|
280742
|
+
}
|
|
280743
|
+
console.log(`
|
|
280744
|
+
${brand("ablo")} ${import_picocolors5.default.dim("connect --register")} ${import_picocolors5.default.dim("register this database for replication")}
|
|
280745
|
+
`);
|
|
280746
|
+
const failures = await probeAndReport(dbUrl);
|
|
280747
|
+
if (failures > 0) {
|
|
280748
|
+
console.log(
|
|
280749
|
+
`
|
|
280750
|
+
${import_picocolors5.default.red(`${failures} item${failures === 1 ? "" : "s"} to fix`)} ${import_picocolors5.default.dim("\u2014 a database that isn\u2019t replication-ready can\u2019t stream. Fix the above, then re-run.")}
|
|
280751
|
+
`
|
|
280752
|
+
);
|
|
280753
|
+
process.exit(1);
|
|
280754
|
+
}
|
|
280755
|
+
const apiUrl2 = (process.env.ABLO_API_URL ?? DEFAULT_URL).replace(/\/+$/, "");
|
|
280756
|
+
let res;
|
|
280757
|
+
try {
|
|
280758
|
+
res = await fetch(`${apiUrl2}/v1/datasources`, {
|
|
280759
|
+
method: "POST",
|
|
280760
|
+
headers: { "content-type": "application/json", authorization: `Bearer ${apiKey}` },
|
|
280761
|
+
body: JSON.stringify({ connectionString: dbUrl })
|
|
280762
|
+
});
|
|
280763
|
+
} catch (err) {
|
|
280764
|
+
console.error(import_picocolors5.default.red(`
|
|
280765
|
+
Couldn't reach ${apiUrl2}: ${err instanceof Error ? err.message : String(err)}
|
|
280766
|
+
`));
|
|
280767
|
+
process.exit(1);
|
|
280768
|
+
}
|
|
280769
|
+
if (res.ok) {
|
|
280770
|
+
const body2 = await res.json().catch(() => ({}));
|
|
280771
|
+
console.log(
|
|
280772
|
+
`
|
|
280773
|
+
${import_picocolors5.default.green("\u2713")} Registered${body2.host ? ` ${import_picocolors5.default.dim(body2.host)}` : ""}${body2.id ? ` ${import_picocolors5.default.dim(`(${body2.id})`)}` : ""} \u2014 Ablo will replicate this database on the next sync.
|
|
280774
|
+
`
|
|
280775
|
+
);
|
|
280776
|
+
process.exit(0);
|
|
280777
|
+
}
|
|
280778
|
+
const body = await res.json().catch(() => ({}));
|
|
280779
|
+
const code = body.error?.code;
|
|
280780
|
+
const message = body.error?.message ?? `HTTP ${res.status}`;
|
|
280781
|
+
console.error(import_picocolors5.default.red(`
|
|
280782
|
+
Registration failed: ${message}`));
|
|
280783
|
+
if (code === "forbidden") {
|
|
280784
|
+
console.error(import_picocolors5.default.dim(` Registering a database needs a ${import_picocolors5.default.bold("secret")} key (sk_\u2026). Run ${import_picocolors5.default.bold("ablo login")} for one.`));
|
|
280785
|
+
} else if (code === "datasource_direct_deprecated") {
|
|
280786
|
+
console.error(
|
|
280787
|
+
import_picocolors5.default.dim(
|
|
280788
|
+
` This deployment doesn\u2019t accept new connection-string registrations yet. The operator must enable it (${import_picocolors5.default.bold("ABLO_ALLOW_DIRECT_DATASOURCE=true")}) \u2014 see ${import_picocolors5.default.bold("docs/runbooks/connect-customer-database-byo-replication.md")}.`
|
|
280789
|
+
)
|
|
280790
|
+
);
|
|
280791
|
+
} else if (code === "datasource_connection_unsupported") {
|
|
280792
|
+
console.error(
|
|
280793
|
+
import_picocolors5.default.dim(` This deployment can\u2019t accept connection strings \u2014 use a self-hosted/hosted engine, or the signed endpoint fallback.`)
|
|
280794
|
+
);
|
|
280795
|
+
}
|
|
280796
|
+
console.error();
|
|
280797
|
+
process.exit(1);
|
|
280798
|
+
}
|
|
280799
|
+
async function runAuditInfra() {
|
|
280800
|
+
const dbUrl = requireDatabaseUrl("--audit-infra");
|
|
280801
|
+
const sql = src_default(dbUrl, { max: 1, prepare: false, onnotice: () => {
|
|
280802
|
+
} });
|
|
280803
|
+
let artifacts;
|
|
280804
|
+
try {
|
|
280805
|
+
artifacts = await auditTenantSyncInfra(sql);
|
|
280806
|
+
} catch (err) {
|
|
280807
|
+
const pg = err ?? {};
|
|
280808
|
+
console.error(import_picocolors5.default.red(` Couldn't audit the database: ${pg.message ?? String(err)}`));
|
|
280809
|
+
await sql.end({ timeout: 2 });
|
|
280810
|
+
process.exit(1);
|
|
280811
|
+
}
|
|
280812
|
+
await sql.end({ timeout: 2 });
|
|
280813
|
+
console.log(`
|
|
280814
|
+
${brand("ablo")} ${import_picocolors5.default.dim("connect --audit-infra")} ${import_picocolors5.default.dim("Stage 5 tenant DB sync-infra audit")}
|
|
280815
|
+
`);
|
|
280816
|
+
const present = artifacts.filter((a) => a.present);
|
|
280817
|
+
if (present.length === 0) {
|
|
280818
|
+
console.log(` ${import_picocolors5.default.green("\u2713")} No deprecated Ablo sync infrastructure found in public.
|
|
280819
|
+
`);
|
|
280820
|
+
process.exit(0);
|
|
280821
|
+
}
|
|
280822
|
+
for (const artifact of present) {
|
|
280823
|
+
const label = artifact.kind === "type" ? "type" : "relation";
|
|
280824
|
+
console.log(` ${import_picocolors5.default.yellow("!")} ${label} ${import_picocolors5.default.bold(`public.${artifact.name}`)} exists`);
|
|
280825
|
+
}
|
|
280826
|
+
console.log(
|
|
280827
|
+
`
|
|
280828
|
+
${import_picocolors5.default.yellow(`${present.length} artifact${present.length === 1 ? "" : "s"} found`)} ` + import_picocolors5.default.dim("\u2014 do not drop automatically. Confirm the org/environment is log-authoritative, then follow ") + import_picocolors5.default.bold("docs/runbooks/wal-stage5-customer-db-infra-cleanup.md") + import_picocolors5.default.dim(".\n")
|
|
280829
|
+
);
|
|
280830
|
+
process.exit(1);
|
|
280831
|
+
}
|
|
280489
280832
|
async function connect(argv) {
|
|
280490
280833
|
let args;
|
|
280491
280834
|
try {
|
|
280492
280835
|
args = parseConnectArgs(argv);
|
|
280493
280836
|
} catch (err) {
|
|
280494
|
-
console.error(
|
|
280837
|
+
console.error(import_picocolors5.default.red(` ${err instanceof Error ? err.message : String(err)}`));
|
|
280495
280838
|
process.exit(1);
|
|
280496
280839
|
}
|
|
280497
280840
|
if (args.check) {
|
|
280498
280841
|
await runCheck();
|
|
280499
280842
|
return;
|
|
280500
280843
|
}
|
|
280844
|
+
if (args.register) {
|
|
280845
|
+
await runRegister();
|
|
280846
|
+
return;
|
|
280847
|
+
}
|
|
280848
|
+
if (args.auditInfra) {
|
|
280849
|
+
await runAuditInfra();
|
|
280850
|
+
return;
|
|
280851
|
+
}
|
|
280501
280852
|
printConnectRecipe(args);
|
|
280502
280853
|
}
|
|
280503
|
-
var CONNECT_USAGE = ` ablo connect \u2014 connect
|
|
280854
|
+
var CONNECT_USAGE = ` ablo connect \u2014 connect your database for the read path, via logical replication
|
|
280504
280855
|
|
|
280505
|
-
Ablo
|
|
280506
|
-
|
|
280856
|
+
The Electric/PowerSync/Zero model: Ablo consumes your WAL via logical replication and
|
|
280857
|
+
never runs DDL, owns, hosts, or migrates your schema. Your app continues to own the write path.
|
|
280507
280858
|
|
|
280508
280859
|
Usage:
|
|
280509
280860
|
npx ablo connect Print the exact setup SQL for your Postgres
|
|
280510
280861
|
npx ablo connect --tables a,b,c Publish only these tables (default: all tables)
|
|
280511
280862
|
npx ablo connect --role <name> Name the replication role (default: ablo_replicator)
|
|
280512
|
-
npx ablo connect --check Validate DATABASE_URL is replication-ready
|
|
280863
|
+
npx ablo connect --check Validate DATABASE_URL is replication-ready
|
|
280864
|
+
npx ablo connect --register Register DATABASE_URL so Ablo replicates it (one self-service step)
|
|
280865
|
+
npx ablo connect --audit-infra Read-only Stage 5 audit for deprecated Ablo sync tables/types`;
|
|
280513
280866
|
|
|
280514
280867
|
// src/cli/generate.ts
|
|
280515
280868
|
init_cjs_shims();
|
|
280516
280869
|
var import_fs6 = require("fs");
|
|
280517
280870
|
var import_path4 = require("path");
|
|
280518
|
-
var
|
|
280871
|
+
var import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
280519
280872
|
var import_schema4 = require("@abloatai/ablo/schema");
|
|
280520
280873
|
var DEFAULT_SCHEMA_PATH3 = "ablo/schema.ts";
|
|
280521
280874
|
var DEFAULT_EXPORT3 = "schema";
|
|
@@ -280547,7 +280900,7 @@ async function generate(argv) {
|
|
|
280547
280900
|
try {
|
|
280548
280901
|
args = parseGenerateArgs(argv);
|
|
280549
280902
|
} catch (err) {
|
|
280550
|
-
console.error(
|
|
280903
|
+
console.error(import_picocolors6.default.red(` ${err instanceof Error ? err.message : String(err)}`));
|
|
280551
280904
|
process.exit(1);
|
|
280552
280905
|
}
|
|
280553
280906
|
let source;
|
|
@@ -280556,18 +280909,18 @@ async function generate(argv) {
|
|
|
280556
280909
|
const schemaJson = JSON.parse((0, import_schema4.serializeSchema)(schema));
|
|
280557
280910
|
source = (0, import_schema4.generateTypes)(schemaJson);
|
|
280558
280911
|
} catch (err) {
|
|
280559
|
-
console.error(
|
|
280912
|
+
console.error(import_picocolors6.default.red(` ${err instanceof Error ? err.message : String(err)}`));
|
|
280560
280913
|
process.exit(1);
|
|
280561
280914
|
}
|
|
280562
280915
|
const abs = (0, import_path4.resolve)(process.cwd(), args.out);
|
|
280563
280916
|
(0, import_fs6.mkdirSync)((0, import_path4.dirname)(abs), { recursive: true });
|
|
280564
280917
|
(0, import_fs6.writeFileSync)(abs, source);
|
|
280565
|
-
console.log(` ${
|
|
280918
|
+
console.log(` ${import_picocolors6.default.green("\u2713")} Generated types \u2192 ${import_picocolors6.default.bold(args.out)}`);
|
|
280566
280919
|
}
|
|
280567
280920
|
|
|
280568
280921
|
// src/cli/dev.ts
|
|
280569
280922
|
init_cjs_shims();
|
|
280570
|
-
var
|
|
280923
|
+
var import_picocolors7 = __toESM(require_picocolors(), 1);
|
|
280571
280924
|
var import_fs7 = require("fs");
|
|
280572
280925
|
var import_path5 = require("path");
|
|
280573
280926
|
var import_schema5 = require("@abloatai/ablo/schema");
|
|
@@ -280605,25 +280958,25 @@ function classifyKey(apiKey, activeMode) {
|
|
|
280605
280958
|
if (!apiKey) {
|
|
280606
280959
|
return {
|
|
280607
280960
|
ok: false,
|
|
280608
|
-
reason: `No API key. Run ${
|
|
280961
|
+
reason: `No API key. Run ${import_picocolors7.default.bold("npx ablo login")} for the sandbox dev loop \u2014 or set ${import_picocolors7.default.bold("ABLO_API_KEY")} (${import_picocolors7.default.bold("sk_test_")} = sandbox; ${import_picocolors7.default.bold("sk_live_")} = deliberate production deploy). ` + import_picocolors7.default.dim(`Mode is currently '${activeMode}'.`)
|
|
280609
280962
|
};
|
|
280610
280963
|
}
|
|
280611
280964
|
if (apiKey.startsWith("sk_test_")) return { ok: true };
|
|
280612
280965
|
if (apiKey.startsWith("sk_live_")) {
|
|
280613
280966
|
return {
|
|
280614
280967
|
ok: false,
|
|
280615
|
-
reason: `Production schema deploys run one-shot: ${
|
|
280968
|
+
reason: `Production schema deploys run one-shot: ${import_picocolors7.default.bold("ABLO_API_KEY=sk_live_\u2026 npx ablo push")} (or ${import_picocolors7.default.bold("ablo mode production")}). ${import_picocolors7.default.bold("--watch")} is sandbox-only.`
|
|
280616
280969
|
};
|
|
280617
280970
|
}
|
|
280618
280971
|
if (classifyCredentialKind(apiKey) === "restricted") {
|
|
280619
280972
|
return {
|
|
280620
280973
|
ok: false,
|
|
280621
|
-
reason: `Restricted (${
|
|
280974
|
+
reason: `Restricted (${import_picocolors7.default.bold("rk_")}) keys can't push schema. Use a secret key: ${import_picocolors7.default.bold("sk_test_")} for the sandbox dev loop, or ${import_picocolors7.default.bold("sk_live_")} with ${import_picocolors7.default.bold("npx ablo push")} for a production deploy.`
|
|
280622
280975
|
};
|
|
280623
280976
|
}
|
|
280624
280977
|
return {
|
|
280625
280978
|
ok: false,
|
|
280626
|
-
reason: `${
|
|
280979
|
+
reason: `${import_picocolors7.default.bold("ABLO_API_KEY")} is not an Ablo key \u2014 expected ${import_picocolors7.default.bold("sk_test_\u2026")} (sandbox) or ${import_picocolors7.default.bold("sk_live_\u2026")} (production deploy via ${import_picocolors7.default.bold("npx ablo push")}).`
|
|
280627
280980
|
};
|
|
280628
280981
|
}
|
|
280629
280982
|
function wireEnvLocal(apiKey, cwd = process.cwd()) {
|
|
@@ -280633,19 +280986,19 @@ function wireEnvLocal(apiKey, cwd = process.cwd()) {
|
|
|
280633
280986
|
if (!(0, import_fs7.existsSync)(envPath)) {
|
|
280634
280987
|
(0, import_fs7.writeFileSync)(envPath, `${line}
|
|
280635
280988
|
`, { mode: 384 });
|
|
280636
|
-
action = `Created ${
|
|
280989
|
+
action = `Created ${import_picocolors7.default.bold(".env.local")} with ${import_picocolors7.default.bold("ABLO_API_KEY")}`;
|
|
280637
280990
|
} else {
|
|
280638
280991
|
const content = (0, import_fs7.readFileSync)(envPath, "utf8");
|
|
280639
280992
|
const match = content.match(/^ABLO_API_KEY=(.*)$/m);
|
|
280640
280993
|
if (!match) {
|
|
280641
280994
|
(0, import_fs7.appendFileSync)(envPath, `${content.endsWith("\n") || content.length === 0 ? "" : "\n"}${line}
|
|
280642
280995
|
`);
|
|
280643
|
-
action = `Added ${
|
|
280996
|
+
action = `Added ${import_picocolors7.default.bold("ABLO_API_KEY")} to ${import_picocolors7.default.bold(".env.local")}`;
|
|
280644
280997
|
} else if (match[1] === apiKey) {
|
|
280645
|
-
action = `${
|
|
280998
|
+
action = `${import_picocolors7.default.bold(".env.local")} already has this key`;
|
|
280646
280999
|
} else {
|
|
280647
281000
|
(0, import_fs7.writeFileSync)(envPath, content.replace(/^ABLO_API_KEY=.*$/m, line));
|
|
280648
|
-
action = `Updated ${
|
|
281001
|
+
action = `Updated ${import_picocolors7.default.bold("ABLO_API_KEY")} in ${import_picocolors7.default.bold(".env.local")} ${import_picocolors7.default.dim(`(was ${match[1].slice(0, 12)}\u2026)`)}`;
|
|
280649
281002
|
}
|
|
280650
281003
|
}
|
|
280651
281004
|
const gitignorePath = (0, import_path5.resolve)(cwd, ".gitignore");
|
|
@@ -280659,7 +281012,7 @@ function wireEnvLocal(apiKey, cwd = process.cwd()) {
|
|
|
280659
281012
|
`}.env.local
|
|
280660
281013
|
`
|
|
280661
281014
|
);
|
|
280662
|
-
gitignoreNote = ` Added ${
|
|
281015
|
+
gitignoreNote = ` Added ${import_picocolors7.default.bold(".env.local")} to ${import_picocolors7.default.bold(".gitignore")} so the key can't be committed.`;
|
|
280663
281016
|
}
|
|
280664
281017
|
return `${action}.${gitignoreNote}`;
|
|
280665
281018
|
}
|
|
@@ -280674,7 +281027,7 @@ async function runPush(schema, args) {
|
|
|
280674
281027
|
if (ok) {
|
|
280675
281028
|
return {
|
|
280676
281029
|
ok: true,
|
|
280677
|
-
message: body.unchanged ? `schema unchanged ${
|
|
281030
|
+
message: body.unchanged ? `schema unchanged ${import_picocolors7.default.dim(`(v${body.version})`)}` : `schema pushed (sandbox) ${import_picocolors7.default.dim(`(v${body.version}, hash ${body.hash})`)}`
|
|
280678
281031
|
};
|
|
280679
281032
|
}
|
|
280680
281033
|
if (status2 === 409) {
|
|
@@ -280684,33 +281037,33 @@ async function runPush(schema, args) {
|
|
|
280684
281037
|
(s) => s.shadowed != null
|
|
280685
281038
|
);
|
|
280686
281039
|
const lines = [
|
|
280687
|
-
|
|
281040
|
+
import_picocolors7.default.bold("Incompatible schema change \u2014 not safe to apply as-is."),
|
|
280688
281041
|
"",
|
|
280689
|
-
...unexecutable.map((u2) =>
|
|
280690
|
-
...warnings.map((w2) =>
|
|
281042
|
+
...unexecutable.map((u2) => import_picocolors7.default.red(fmtSignal(u2))),
|
|
281043
|
+
...warnings.map((w2) => import_picocolors7.default.yellow(fmtSignal(w2))),
|
|
280691
281044
|
"",
|
|
280692
281045
|
...hasShadowed ? [
|
|
280693
|
-
|
|
281046
|
+
import_picocolors7.default.dim(
|
|
280694
281047
|
" These models exist in the baseline above but not in your push. Sandbox readers"
|
|
280695
281048
|
),
|
|
280696
|
-
|
|
281049
|
+
import_picocolors7.default.dim(
|
|
280697
281050
|
" fall back to the production schema until you push your own, so applying this drops them."
|
|
280698
281051
|
),
|
|
280699
281052
|
""
|
|
280700
281053
|
] : [],
|
|
280701
|
-
|
|
280702
|
-
` Fix: ${
|
|
281054
|
+
import_picocolors7.default.dim(
|
|
281055
|
+
` Fix: ${import_picocolors7.default.bold("ablo push --force")} to apply anyway, or ${import_picocolors7.default.bold("--rename old:new")} if you renamed a model.`
|
|
280703
281056
|
)
|
|
280704
281057
|
];
|
|
280705
281058
|
return { ok: false, message: lines.join("\n") };
|
|
280706
281059
|
}
|
|
280707
281060
|
if (status2 === 403) {
|
|
280708
281061
|
const serverSays = body.message ?? body.reason;
|
|
280709
|
-
const hint = body.code === "database_role_cannot_enforce_rls" ? `Run ${
|
|
281062
|
+
const hint = body.code === "database_role_cannot_enforce_rls" ? `Run ${import_picocolors7.default.bold("npx ablo migrate")} \u2014 it creates the scoped role for you (your DB credential never leaves this machine).` : `Schema authoring needs a ${import_picocolors7.default.bold("sandbox")} key with ${import_picocolors7.default.bold("schema:push")} \u2014 manage keys at ${import_picocolors7.default.cyan("https://abloatai.com")}.`;
|
|
280710
281063
|
return {
|
|
280711
281064
|
ok: false,
|
|
280712
281065
|
message: `${serverSays ?? "This key can't author schema (missing schema:push scope)."}
|
|
280713
|
-
` +
|
|
281066
|
+
` + import_picocolors7.default.dim(hint)
|
|
280714
281067
|
};
|
|
280715
281068
|
}
|
|
280716
281069
|
return { ok: false, message: `Push failed (${status2}): ${body.message ?? body.reason ?? bodyText}` };
|
|
@@ -280720,25 +281073,25 @@ async function dev(argv) {
|
|
|
280720
281073
|
try {
|
|
280721
281074
|
args = parseDevArgs(argv);
|
|
280722
281075
|
} catch (err) {
|
|
280723
|
-
console.error(
|
|
281076
|
+
console.error(import_picocolors7.default.red(` ${err instanceof Error ? err.message : String(err)}`));
|
|
280724
281077
|
process.exit(1);
|
|
280725
281078
|
}
|
|
280726
281079
|
if (!args.apiKey) args.apiKey = resolveApiKey("sandbox");
|
|
280727
281080
|
const key = classifyKey(args.apiKey, getMode());
|
|
280728
281081
|
if (!key.ok) {
|
|
280729
|
-
console.error(
|
|
281082
|
+
console.error(import_picocolors7.default.red(` ${key.reason}`));
|
|
280730
281083
|
process.exit(1);
|
|
280731
281084
|
}
|
|
280732
281085
|
console.log(`
|
|
280733
|
-
${brand("ablo")} ${
|
|
281086
|
+
${brand("ablo")} ${import_picocolors7.default.dim("push")} ${import_picocolors7.default.dim("(sandbox)")}
|
|
280734
281087
|
`);
|
|
280735
281088
|
const schema = await loadSchema(args.schemaPath, args.exportName);
|
|
280736
281089
|
const modelCount = Object.keys(schema.models).length;
|
|
280737
281090
|
console.log(
|
|
280738
|
-
` ${
|
|
281091
|
+
` ${import_picocolors7.default.dim("schema")} ${import_picocolors7.default.bold(args.schemaPath)} ${import_picocolors7.default.dim(`(${modelCount} models, hash ${(0, import_schema5.schemaHash)(schema)})`)}`
|
|
280739
281092
|
);
|
|
280740
|
-
console.log(` ${
|
|
280741
|
-
console.log(` ${
|
|
281093
|
+
console.log(` ${import_picocolors7.default.dim("key")} ${args.apiKey.slice(0, 12)}\u2026`);
|
|
281094
|
+
console.log(` ${import_picocolors7.default.dim("api")} ${args.url}
|
|
280742
281095
|
`);
|
|
280743
281096
|
const s = Y2();
|
|
280744
281097
|
s.start("Pushing schema definition (sandbox)");
|
|
@@ -280747,16 +281100,16 @@ async function dev(argv) {
|
|
|
280747
281100
|
if (!first.ok) process.exit(1);
|
|
280748
281101
|
if (process.env.ABLO_API_KEY) {
|
|
280749
281102
|
console.log(`
|
|
280750
|
-
${
|
|
281103
|
+
${import_picocolors7.default.green("\u2713")} ${import_picocolors7.default.bold("ABLO_API_KEY")} is set in this shell \u2014 the SDK reads it directly.`);
|
|
280751
281104
|
} else {
|
|
280752
281105
|
console.log(`
|
|
280753
|
-
${
|
|
280754
|
-
console.log(` ${
|
|
281106
|
+
${import_picocolors7.default.green("\u2713")} ${wireEnvLocal(args.apiKey)}`);
|
|
281107
|
+
console.log(` ${import_picocolors7.default.dim("Frameworks load it automatically; plain Node: node --env-file=.env.local app.ts")}`);
|
|
280755
281108
|
}
|
|
280756
281109
|
console.log(` Your app is wired for the sandbox.`);
|
|
280757
281110
|
if (!args.watch) return;
|
|
280758
281111
|
const abs = (0, import_path5.resolve)(process.cwd(), args.schemaPath);
|
|
280759
|
-
console.log(` ${
|
|
281112
|
+
console.log(` ${import_picocolors7.default.dim(`watching ${args.schemaPath} \u2026 (Ctrl-C to stop)`)}
|
|
280760
281113
|
`);
|
|
280761
281114
|
let timer2 = null;
|
|
280762
281115
|
let pushing = false;
|
|
@@ -280776,7 +281129,7 @@ async function dev(argv) {
|
|
|
280776
281129
|
const r2 = await runPush(next, args);
|
|
280777
281130
|
s2.stop(r2.message, r2.ok ? 0 : 1);
|
|
280778
281131
|
} catch (err) {
|
|
280779
|
-
s2.stop(
|
|
281132
|
+
s2.stop(import_picocolors7.default.red(`schema reload failed: ${err instanceof Error ? err.message : String(err)}`), 1);
|
|
280780
281133
|
} finally {
|
|
280781
281134
|
pushing = false;
|
|
280782
281135
|
}
|
|
@@ -280784,7 +281137,7 @@ async function dev(argv) {
|
|
|
280784
281137
|
const stop = () => {
|
|
280785
281138
|
watcher.close();
|
|
280786
281139
|
console.log(`
|
|
280787
|
-
${
|
|
281140
|
+
${import_picocolors7.default.dim("stopped.")}`);
|
|
280788
281141
|
process.exit(0);
|
|
280789
281142
|
};
|
|
280790
281143
|
process.on("SIGINT", stop);
|
|
@@ -280795,8 +281148,8 @@ async function dev(argv) {
|
|
|
280795
281148
|
|
|
280796
281149
|
// src/cli/login.ts
|
|
280797
281150
|
init_cjs_shims();
|
|
280798
|
-
var
|
|
280799
|
-
var
|
|
281151
|
+
var import_child_process2 = require("child_process");
|
|
281152
|
+
var import_picocolors8 = __toESM(require_picocolors(), 1);
|
|
280800
281153
|
var CLIENT_ID = "ablo-cli";
|
|
280801
281154
|
var stripSlash = (u2) => u2.replace(/\/+$/, "");
|
|
280802
281155
|
var AUTH_URL = stripSlash(process.env.ABLO_AUTH_URL ?? "https://auth.abloatai.com");
|
|
@@ -280805,7 +281158,7 @@ var sleep = (ms) => new Promise((r2) => setTimeout(r2, ms));
|
|
|
280805
281158
|
function openBrowser(url) {
|
|
280806
281159
|
const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
280807
281160
|
try {
|
|
280808
|
-
const child = (0,
|
|
281161
|
+
const child = (0, import_child_process2.spawn)(cmd, [url], { stdio: "ignore", detached: true, shell: process.platform === "win32" });
|
|
280809
281162
|
child.on("error", () => {
|
|
280810
281163
|
});
|
|
280811
281164
|
child.unref();
|
|
@@ -280854,9 +281207,9 @@ async function deviceLogin(argv, deps = {}) {
|
|
|
280854
281207
|
const code = await codeRes.json();
|
|
280855
281208
|
const approvePath = `/cli?user_code=${code.user_code}`;
|
|
280856
281209
|
const url = account === "signup" ? `${DASHBOARD_URL}/signup?next=${encodeURIComponent(approvePath)}` : `${DASHBOARD_URL}${approvePath}`;
|
|
280857
|
-
Me(`${
|
|
281210
|
+
Me(`${import_picocolors8.default.bold(code.user_code)}
|
|
280858
281211
|
|
|
280859
|
-
${
|
|
281212
|
+
${import_picocolors8.default.dim(url)}`, "Approve in your browser");
|
|
280860
281213
|
openUrl(url);
|
|
280861
281214
|
const s = Y2();
|
|
280862
281215
|
s.start("Waiting for approval\u2026");
|
|
@@ -280923,7 +281276,7 @@ ${import_picocolors7.default.dim(url)}`, "Approve in your browser");
|
|
|
280923
281276
|
if (reason) M2.error(reason);
|
|
280924
281277
|
else if (provRes) M2.error(`Key provisioning returned ${provRes.status} from ${DASHBOARD_URL}/api/cli/provision-key.`);
|
|
280925
281278
|
M2.error(
|
|
280926
|
-
`The browser approval succeeded but the key handoff failed. Try again, or grab a ${
|
|
281279
|
+
`The browser approval succeeded but the key handoff failed. Try again, or grab a ${import_picocolors8.default.bold("sk_test_")} key from the dashboard and set ${import_picocolors8.default.bold("ABLO_API_KEY")}.`
|
|
280927
281280
|
);
|
|
280928
281281
|
process.exit(1);
|
|
280929
281282
|
}
|
|
@@ -280943,9 +281296,9 @@ ${import_picocolors7.default.dim(url)}`, "Approve in your browser");
|
|
|
280943
281296
|
{ mode: "sandbox", activeProject: prov.project ?? void 0 }
|
|
280944
281297
|
);
|
|
280945
281298
|
s.stop(`Saved keys to ${path}`);
|
|
280946
|
-
const where = prov.project ? ` ${
|
|
281299
|
+
const where = prov.project ? ` ${import_picocolors8.default.dim(`(project ${prov.project.slug})`)}` : "";
|
|
280947
281300
|
Se(
|
|
280948
|
-
`${
|
|
281301
|
+
`${import_picocolors8.default.green("\u2713")} Logged in ${import_picocolors8.default.dim("(sandbox)")}${where}. Run ${import_picocolors8.default.bold("npx ablo push")} to push your schema.`
|
|
280949
281302
|
);
|
|
280950
281303
|
}
|
|
280951
281304
|
async function login(argv = [], deps = {}) {
|
|
@@ -280954,20 +281307,20 @@ async function login(argv = [], deps = {}) {
|
|
|
280954
281307
|
function logout() {
|
|
280955
281308
|
const removed = clearCredential();
|
|
280956
281309
|
if (removed) {
|
|
280957
|
-
console.log(` ${
|
|
281310
|
+
console.log(` ${import_picocolors8.default.green("\u2713")} Logged out ${import_picocolors8.default.dim(`(credentials removed from ${configDir()})`)}`);
|
|
280958
281311
|
} else {
|
|
280959
|
-
console.log(` ${
|
|
281312
|
+
console.log(` ${import_picocolors8.default.dim("\u25CB")} Not logged in \u2014 nothing to remove.`);
|
|
280960
281313
|
}
|
|
280961
281314
|
if (process.env.ABLO_API_KEY) {
|
|
280962
281315
|
console.log(
|
|
280963
|
-
|
|
281316
|
+
import_picocolors8.default.dim(` Note: ${import_picocolors8.default.bold("ABLO_API_KEY")} is still set in this shell and takes precedence.`)
|
|
280964
281317
|
);
|
|
280965
281318
|
}
|
|
280966
281319
|
}
|
|
280967
281320
|
|
|
280968
281321
|
// src/cli/mode.ts
|
|
280969
281322
|
init_cjs_shims();
|
|
280970
|
-
var
|
|
281323
|
+
var import_picocolors9 = __toESM(require_picocolors(), 1);
|
|
280971
281324
|
var PREFIX = { sandbox: "sk_test_", production: "rk_live_" };
|
|
280972
281325
|
function hintFor(m2, current) {
|
|
280973
281326
|
const parts = [];
|
|
@@ -280977,10 +281330,10 @@ function hintFor(m2, current) {
|
|
|
280977
281330
|
}
|
|
280978
281331
|
function apply(m2) {
|
|
280979
281332
|
setMode(m2);
|
|
280980
|
-
console.log(` ${
|
|
281333
|
+
console.log(` ${import_picocolors9.default.green("\u2713")} now in ${import_picocolors9.default.bold(m2)}`);
|
|
280981
281334
|
if (!getKeyEntry(m2)) {
|
|
280982
281335
|
console.log(
|
|
280983
|
-
|
|
281336
|
+
import_picocolors9.default.dim(` No ${m2} key stored \u2014 run ${import_picocolors9.default.bold("ablo login")} or ${import_picocolors9.default.bold(`ablo login --api-key ${PREFIX[m2]}\u2026`)}.`)
|
|
280984
281337
|
);
|
|
280985
281338
|
}
|
|
280986
281339
|
}
|
|
@@ -280993,14 +281346,14 @@ async function mode(argv) {
|
|
|
280993
281346
|
}
|
|
280994
281347
|
if (arg) {
|
|
280995
281348
|
console.error(
|
|
280996
|
-
|
|
281349
|
+
import_picocolors9.default.red(` unknown mode: ${arg}`) + import_picocolors9.default.dim(` (expected ${import_picocolors9.default.bold("sandbox")} or ${import_picocolors9.default.bold("production")})`)
|
|
280997
281350
|
);
|
|
280998
281351
|
process.exit(1);
|
|
280999
281352
|
}
|
|
281000
281353
|
const current = getMode();
|
|
281001
281354
|
if (!process.stdin.isTTY || process.env.CI) {
|
|
281002
281355
|
console.error(
|
|
281003
|
-
|
|
281356
|
+
import_picocolors9.default.red(" `ablo mode` needs an argument without a TTY: ") + import_picocolors9.default.bold("ablo mode sandbox") + import_picocolors9.default.dim(" | ") + import_picocolors9.default.bold("ablo mode production") + import_picocolors9.default.dim(` (current: ${current})`)
|
|
281004
281357
|
);
|
|
281005
281358
|
process.exit(1);
|
|
281006
281359
|
}
|
|
@@ -281021,7 +281374,7 @@ async function mode(argv) {
|
|
|
281021
281374
|
|
|
281022
281375
|
// src/cli/projects.ts
|
|
281023
281376
|
init_cjs_shims();
|
|
281024
|
-
var
|
|
281377
|
+
var import_picocolors10 = __toESM(require_picocolors(), 1);
|
|
281025
281378
|
function apiUrl() {
|
|
281026
281379
|
return (process.env.ABLO_API_URL ?? DEFAULT_URL).replace(/\/+$/, "");
|
|
281027
281380
|
}
|
|
@@ -281029,8 +281382,8 @@ function requireKey() {
|
|
|
281029
281382
|
const apiKey = resolveApiKey();
|
|
281030
281383
|
if (!apiKey) {
|
|
281031
281384
|
console.error(
|
|
281032
|
-
|
|
281033
|
-
` Run ${
|
|
281385
|
+
import_picocolors10.default.red(" No API key.") + import_picocolors10.default.dim(
|
|
281386
|
+
` Run ${import_picocolors10.default.bold("npx ablo login")} \u2014 or set ${import_picocolors10.default.bold("ABLO_API_KEY")} (${import_picocolors10.default.bold("sk_test_")} = sandbox; ${import_picocolors10.default.bold("sk_live_")} = production).`
|
|
281034
281387
|
)
|
|
281035
281388
|
);
|
|
281036
281389
|
process.exit(1);
|
|
@@ -281065,7 +281418,7 @@ async function listProjects(apiKey) {
|
|
|
281065
281418
|
async function fetchProjects() {
|
|
281066
281419
|
const all = await listProjects(requireKey());
|
|
281067
281420
|
if (!all) {
|
|
281068
|
-
console.error(
|
|
281421
|
+
console.error(import_picocolors10.default.red(" Could not list projects \u2014 is the API reachable and the key valid?"));
|
|
281069
281422
|
process.exit(1);
|
|
281070
281423
|
}
|
|
281071
281424
|
return all;
|
|
@@ -281105,10 +281458,10 @@ function printList(projects2) {
|
|
|
281105
281458
|
const active = getActiveProject();
|
|
281106
281459
|
for (const p2 of projects2) {
|
|
281107
281460
|
const isActive = active ? active.id === p2.id : p2.default;
|
|
281108
|
-
const marker = isActive ?
|
|
281109
|
-
const tags = [p2.default ?
|
|
281461
|
+
const marker = isActive ? import_picocolors10.default.green("\u25CF") : import_picocolors10.default.dim("\u25CB");
|
|
281462
|
+
const tags = [p2.default ? import_picocolors10.default.dim("default") : "", isActive ? import_picocolors10.default.green("active") : ""].filter(Boolean).join(import_picocolors10.default.dim(", "));
|
|
281110
281463
|
console.log(
|
|
281111
|
-
` ${marker} ${p2.slug.padEnd(20)} ${
|
|
281464
|
+
` ${marker} ${p2.slug.padEnd(20)} ${import_picocolors10.default.dim(p2.id)}${tags ? ` ${tags}` : ""}`
|
|
281112
281465
|
);
|
|
281113
281466
|
}
|
|
281114
281467
|
}
|
|
@@ -281116,7 +281469,7 @@ async function projects(argv) {
|
|
|
281116
281469
|
const sub = argv[0];
|
|
281117
281470
|
if (sub === "list" || sub === void 0) {
|
|
281118
281471
|
console.log(`
|
|
281119
|
-
${brand("ablo")} ${
|
|
281472
|
+
${brand("ablo")} ${import_picocolors10.default.dim("projects")}
|
|
281120
281473
|
`);
|
|
281121
281474
|
printList(await fetchProjects());
|
|
281122
281475
|
console.log();
|
|
@@ -281125,7 +281478,7 @@ async function projects(argv) {
|
|
|
281125
281478
|
if (sub === "create") {
|
|
281126
281479
|
const slug = argv[1];
|
|
281127
281480
|
if (!slug || slug.startsWith("-")) {
|
|
281128
|
-
console.error(
|
|
281481
|
+
console.error(import_picocolors10.default.red(' usage: ablo projects create <slug> [--name "Display Name"]'));
|
|
281129
281482
|
process.exit(1);
|
|
281130
281483
|
}
|
|
281131
281484
|
const nameIdx = argv.indexOf("--name");
|
|
@@ -281136,17 +281489,17 @@ async function projects(argv) {
|
|
|
281136
281489
|
});
|
|
281137
281490
|
if (status2 !== 201) {
|
|
281138
281491
|
console.error(
|
|
281139
|
-
|
|
281492
|
+
import_picocolors10.default.red(` Create failed (${status2}): ${String(body.message ?? body.code ?? "")}`)
|
|
281140
281493
|
);
|
|
281141
281494
|
if (body.code === "project_slug_taken") {
|
|
281142
|
-
console.error(
|
|
281495
|
+
console.error(import_picocolors10.default.dim(` Pick another slug, or switch to it: ${import_picocolors10.default.bold(`ablo projects use ${slug}`)}`));
|
|
281143
281496
|
}
|
|
281144
281497
|
process.exit(1);
|
|
281145
281498
|
}
|
|
281146
281499
|
const created = body;
|
|
281147
|
-
console.log(` ${
|
|
281500
|
+
console.log(` ${import_picocolors10.default.green("\u2713")} Created project ${import_picocolors10.default.bold(created.slug)} ${import_picocolors10.default.dim(`(${created.id})`)}`);
|
|
281148
281501
|
console.log(
|
|
281149
|
-
|
|
281502
|
+
import_picocolors10.default.dim(` Make it active with ${import_picocolors10.default.bold(`ablo projects use ${created.slug}`)}; mint its keys in the dashboard.`)
|
|
281150
281503
|
);
|
|
281151
281504
|
return;
|
|
281152
281505
|
}
|
|
@@ -281154,17 +281507,17 @@ async function projects(argv) {
|
|
|
281154
281507
|
const ref = argv[1];
|
|
281155
281508
|
const name = argv.slice(2).join(" ").trim();
|
|
281156
281509
|
if (!ref || ref.startsWith("-") || !name) {
|
|
281157
|
-
console.error(
|
|
281510
|
+
console.error(import_picocolors10.default.red(" usage: ablo projects rename <slug|id> <new name>"));
|
|
281158
281511
|
process.exit(1);
|
|
281159
281512
|
}
|
|
281160
281513
|
const all = await fetchProjects();
|
|
281161
281514
|
const target = all.find((p2) => p2.slug === ref || p2.id === ref);
|
|
281162
281515
|
if (!target) {
|
|
281163
|
-
console.error(
|
|
281516
|
+
console.error(import_picocolors10.default.red(` No project "${ref}".`) + import_picocolors10.default.dim(" Run ablo projects list."));
|
|
281164
281517
|
process.exit(1);
|
|
281165
281518
|
}
|
|
281166
281519
|
if (target.default) {
|
|
281167
|
-
console.error(
|
|
281520
|
+
console.error(import_picocolors10.default.red(" The default project cannot be renamed."));
|
|
281168
281521
|
process.exit(1);
|
|
281169
281522
|
}
|
|
281170
281523
|
const { status: status2, body } = await request(`/api/v1/projects/${target.id}`, requireKey(), {
|
|
@@ -281173,47 +281526,47 @@ async function projects(argv) {
|
|
|
281173
281526
|
});
|
|
281174
281527
|
if (status2 !== 200) {
|
|
281175
281528
|
console.error(
|
|
281176
|
-
|
|
281529
|
+
import_picocolors10.default.red(` Rename failed (${status2}): ${String(body.message ?? body.code ?? "")}`)
|
|
281177
281530
|
);
|
|
281178
281531
|
process.exit(1);
|
|
281179
281532
|
}
|
|
281180
281533
|
const updated = body;
|
|
281181
281534
|
console.log(
|
|
281182
|
-
` ${
|
|
281535
|
+
` ${import_picocolors10.default.green("\u2713")} Renamed ${import_picocolors10.default.bold(updated.slug)} \u2192 ${import_picocolors10.default.bold(updated.name ?? updated.slug)} ${import_picocolors10.default.dim(`(${updated.id})`)}`
|
|
281183
281536
|
);
|
|
281184
281537
|
return;
|
|
281185
281538
|
}
|
|
281186
281539
|
if (sub === "use") {
|
|
281187
281540
|
const ref = argv[1];
|
|
281188
281541
|
if (!ref) {
|
|
281189
|
-
console.error(
|
|
281542
|
+
console.error(import_picocolors10.default.red(" usage: ablo projects use <slug|id|default>"));
|
|
281190
281543
|
process.exit(1);
|
|
281191
281544
|
}
|
|
281192
281545
|
const all = await fetchProjects();
|
|
281193
281546
|
const target = all.find((p2) => p2.slug === ref || p2.id === ref);
|
|
281194
281547
|
if (!target) {
|
|
281195
|
-
console.error(
|
|
281548
|
+
console.error(import_picocolors10.default.red(` No project "${ref}".`) + import_picocolors10.default.dim(" Run ablo projects list."));
|
|
281196
281549
|
process.exit(1);
|
|
281197
281550
|
}
|
|
281198
281551
|
if (target.default) {
|
|
281199
281552
|
setActiveProject(void 0);
|
|
281200
|
-
console.log(` ${
|
|
281553
|
+
console.log(` ${import_picocolors10.default.green("\u2713")} now targeting the ${import_picocolors10.default.bold("default")} project`);
|
|
281201
281554
|
} else {
|
|
281202
281555
|
setActiveProject({ id: target.id, slug: target.slug });
|
|
281203
|
-
console.log(` ${
|
|
281556
|
+
console.log(` ${import_picocolors10.default.green("\u2713")} now targeting project ${import_picocolors10.default.bold(target.slug)} ${import_picocolors10.default.dim(`(${target.id})`)}`);
|
|
281204
281557
|
}
|
|
281205
281558
|
const guard = guardActiveProjectKey();
|
|
281206
281559
|
if (!guard.ok) {
|
|
281207
281560
|
const loginCmd = guard.activeProfile === DEFAULT_PROFILE ? "ablo login" : `ablo login --project ${guard.activeProfile}`;
|
|
281208
281561
|
console.log(
|
|
281209
|
-
|
|
281562
|
+
import_picocolors10.default.dim(` No key stored for this project yet \u2014 run ${import_picocolors10.default.bold(loginCmd)} to mint one.`)
|
|
281210
281563
|
);
|
|
281211
281564
|
}
|
|
281212
281565
|
return;
|
|
281213
281566
|
}
|
|
281214
281567
|
console.error(
|
|
281215
|
-
|
|
281216
|
-
` (expected ${
|
|
281568
|
+
import_picocolors10.default.red(` unknown subcommand: ${sub}`) + import_picocolors10.default.dim(
|
|
281569
|
+
` (expected ${import_picocolors10.default.bold("list")}, ${import_picocolors10.default.bold("create")}, ${import_picocolors10.default.bold("rename")}, or ${import_picocolors10.default.bold("use")})`
|
|
281217
281570
|
)
|
|
281218
281571
|
);
|
|
281219
281572
|
process.exit(1);
|
|
@@ -281221,13 +281574,13 @@ async function projects(argv) {
|
|
|
281221
281574
|
|
|
281222
281575
|
// src/cli/status.ts
|
|
281223
281576
|
init_cjs_shims();
|
|
281224
|
-
var
|
|
281577
|
+
var import_picocolors11 = __toESM(require_picocolors(), 1);
|
|
281225
281578
|
function expiryLabel(iso) {
|
|
281226
281579
|
const ms = Date.parse(iso) - Date.now();
|
|
281227
281580
|
if (Number.isNaN(ms)) return "";
|
|
281228
|
-
if (ms <= 0) return
|
|
281581
|
+
if (ms <= 0) return import_picocolors11.default.red("expired");
|
|
281229
281582
|
const days = Math.floor(ms / (24 * 60 * 60 * 1e3));
|
|
281230
|
-
return
|
|
281583
|
+
return import_picocolors11.default.dim(days > 0 ? `expires in ${days}d` : "expires <1d");
|
|
281231
281584
|
}
|
|
281232
281585
|
async function ping(apiUrl2) {
|
|
281233
281586
|
const ctrl = new AbortController();
|
|
@@ -281258,6 +281611,45 @@ async function fetchPushedSchema(apiUrl2, apiKey) {
|
|
|
281258
281611
|
clearTimeout(t);
|
|
281259
281612
|
}
|
|
281260
281613
|
}
|
|
281614
|
+
async function sampleRead(apiUrl2, apiKey, modelTypename, n) {
|
|
281615
|
+
const ctrl = new AbortController();
|
|
281616
|
+
const t = setTimeout(() => ctrl.abort(), 4e3);
|
|
281617
|
+
try {
|
|
281618
|
+
const res = await fetch(
|
|
281619
|
+
`${apiUrl2}/v1/models/${encodeURIComponent(modelTypename)}/__ablo_health_probe_${n}__`,
|
|
281620
|
+
{ headers: { authorization: `Bearer ${apiKey}` }, signal: ctrl.signal }
|
|
281621
|
+
);
|
|
281622
|
+
if (res.ok) return "routed";
|
|
281623
|
+
let code;
|
|
281624
|
+
try {
|
|
281625
|
+
const body = await res.json();
|
|
281626
|
+
code = body.code ?? body.error?.code;
|
|
281627
|
+
} catch {
|
|
281628
|
+
}
|
|
281629
|
+
if (code === "entity_not_found") return "routed";
|
|
281630
|
+
if (code === "tenant_routing_failed") return "no_route";
|
|
281631
|
+
if (res.status === 401 || res.status === 403) return { forbidden: code };
|
|
281632
|
+
return { other: `${res.status}${code ? ` ${code}` : ""}` };
|
|
281633
|
+
} catch {
|
|
281634
|
+
return { other: "unreachable" };
|
|
281635
|
+
} finally {
|
|
281636
|
+
clearTimeout(t);
|
|
281637
|
+
}
|
|
281638
|
+
}
|
|
281639
|
+
async function probeDataPlane(apiUrl2, apiKey, modelTypename) {
|
|
281640
|
+
if (!apiKey) return { status: "skipped" };
|
|
281641
|
+
const samples = [];
|
|
281642
|
+
for (let i = 0; i < 3; i++) samples.push(await sampleRead(apiUrl2, apiKey, modelTypename, i));
|
|
281643
|
+
const forbidden = samples.find((s) => typeof s === "object" && "forbidden" in s);
|
|
281644
|
+
if (forbidden) return { status: "forbidden", detail: forbidden.forbidden };
|
|
281645
|
+
const routed = samples.filter((s) => s === "routed").length;
|
|
281646
|
+
const noRoute = samples.filter((s) => s === "no_route").length;
|
|
281647
|
+
if (routed === samples.length) return { status: "ok" };
|
|
281648
|
+
if (noRoute === samples.length) return { status: "no_database" };
|
|
281649
|
+
if (routed > 0 && noRoute > 0) return { status: "intermittent", ok: routed, failed: noRoute };
|
|
281650
|
+
const other = samples.find((s) => typeof s === "object" && "other" in s);
|
|
281651
|
+
return { status: "unknown", detail: other?.other ?? "inconclusive" };
|
|
281652
|
+
}
|
|
281261
281653
|
function formatConflict(conflict) {
|
|
281262
281654
|
if (!conflict) return "";
|
|
281263
281655
|
const parts = ["user", "agent", "system"].flatMap((k3) => conflict[k3] ? [`${k3}:${conflict[k3]}`] : []);
|
|
@@ -281309,59 +281701,81 @@ async function status(args = []) {
|
|
|
281309
281701
|
return;
|
|
281310
281702
|
}
|
|
281311
281703
|
console.log(`
|
|
281312
|
-
${brand("ablo")} ${
|
|
281704
|
+
${brand("ablo")} ${import_picocolors11.default.dim("status")}
|
|
281313
281705
|
`);
|
|
281314
281706
|
if (process.env.ABLO_API_KEY) {
|
|
281315
281707
|
console.log(
|
|
281316
|
-
` ${
|
|
281708
|
+
` ${import_picocolors11.default.dim("key")} ${process.env.ABLO_API_KEY.slice(0, 12)}\u2026 ${import_picocolors11.default.dim("(ABLO_API_KEY env \u2014 overrides stored)")}`
|
|
281317
281709
|
);
|
|
281318
281710
|
} else if (!cfg) {
|
|
281319
|
-
console.log(` ${
|
|
281711
|
+
console.log(` ${import_picocolors11.default.yellow("!")} Not logged in \u2014 run ${import_picocolors11.default.bold("ablo login")}.`);
|
|
281320
281712
|
}
|
|
281321
|
-
console.log(` ${
|
|
281713
|
+
console.log(` ${import_picocolors11.default.dim("mode")} ${import_picocolors11.default.bold(mode2)}`);
|
|
281322
281714
|
const activeEntry = getKeyEntry(mode2);
|
|
281323
281715
|
const key = describeEffectiveKey(mode2, process.env.ABLO_API_KEY, activeEntry);
|
|
281324
281716
|
if (key.keyMismatch) {
|
|
281325
|
-
console.log(` ${
|
|
281717
|
+
console.log(` ${import_picocolors11.default.yellow("!")} ${import_picocolors11.default.yellow(key.keyMismatch.message)}`);
|
|
281326
281718
|
}
|
|
281327
281719
|
const activeProject = getActiveProject();
|
|
281328
281720
|
console.log(
|
|
281329
|
-
` ${
|
|
281721
|
+
` ${import_picocolors11.default.dim("project")} ${activeProject ? `${import_picocolors11.default.bold(activeProject.slug)} ${import_picocolors11.default.dim(`(${activeProject.id})`)}` : import_picocolors11.default.bold("default")}`
|
|
281330
281722
|
);
|
|
281331
281723
|
for (const m2 of ["sandbox", "production"]) {
|
|
281332
281724
|
const entry = getKeyEntry(m2);
|
|
281333
|
-
const marker = m2 === mode2 ?
|
|
281725
|
+
const marker = m2 === mode2 ? import_picocolors11.default.green("\u25CF") : import_picocolors11.default.dim("\u25CB");
|
|
281334
281726
|
if (entry) {
|
|
281335
281727
|
const exp = entry.expiresAt ? ` ${expiryLabel(entry.expiresAt)}` : "";
|
|
281336
|
-
console.log(` ${marker} ${m2.padEnd(10)} ${
|
|
281728
|
+
console.log(` ${marker} ${m2.padEnd(10)} ${import_picocolors11.default.dim(`${entry.apiKey.slice(0, 12)}\u2026`)}${exp}`);
|
|
281337
281729
|
} else {
|
|
281338
|
-
console.log(` ${marker} ${m2.padEnd(10)} ${
|
|
281730
|
+
console.log(` ${marker} ${m2.padEnd(10)} ${import_picocolors11.default.dim("\u2014 no key")}`);
|
|
281339
281731
|
}
|
|
281340
281732
|
}
|
|
281341
281733
|
const org = activeEntry?.organizationId;
|
|
281342
|
-
if (org) console.log(` ${
|
|
281734
|
+
if (org) console.log(` ${import_picocolors11.default.dim("org")} ${org}`);
|
|
281343
281735
|
const plan = resolvePushPlan();
|
|
281344
281736
|
console.log(
|
|
281345
|
-
` ${
|
|
281737
|
+
` ${import_picocolors11.default.dim("push")} ${plan.apiKey ? `${import_picocolors11.default.bold(plan.flow)} ${import_picocolors11.default.dim(`with ${plan.apiKey.slice(0, 12)}\u2026 (${plan.source})`)}` : `${import_picocolors11.default.bold(plan.flow)} ${import_picocolors11.default.yellow("\u2014 no credential")} ${import_picocolors11.default.dim(`(run ${import_picocolors11.default.bold("ablo login")} or set ${import_picocolors11.default.bold("ABLO_API_KEY")})`)}`}`
|
|
281346
281738
|
);
|
|
281347
|
-
process.stdout.write(` ${
|
|
281739
|
+
process.stdout.write(` ${import_picocolors11.default.dim("api")} ${apiUrl2} `);
|
|
281348
281740
|
const reachable = await ping(apiUrl2);
|
|
281349
|
-
console.log(reachable ?
|
|
281741
|
+
console.log(reachable ? import_picocolors11.default.green("reachable") : import_picocolors11.default.red("unreachable"));
|
|
281350
281742
|
if (reachable) {
|
|
281351
281743
|
const introspectKey = process.env.ABLO_API_KEY ?? activeEntry?.apiKey;
|
|
281352
281744
|
const pushed = await fetchPushedSchema(apiUrl2, introspectKey);
|
|
281353
281745
|
if (pushed && pushed.active) {
|
|
281354
|
-
const when = pushed.pushedAt ? ` ${
|
|
281355
|
-
const ver = pushed.version != null ? ` ${
|
|
281356
|
-
console.log(` ${
|
|
281746
|
+
const when = pushed.pushedAt ? ` ${import_picocolors11.default.dim(`@ ${pushed.pushedAt.slice(0, 10)}`)}` : "";
|
|
281747
|
+
const ver = pushed.version != null ? ` ${import_picocolors11.default.dim(`(rev ${pushed.version})`)}` : "";
|
|
281748
|
+
console.log(` ${import_picocolors11.default.dim("schema")} ${import_picocolors11.default.bold(`${pushed.models.length} models pushed`)}${ver}${when}`);
|
|
281357
281749
|
for (const m2 of pushed.models) {
|
|
281358
|
-
const tn = m2.typename === m2.key ?
|
|
281750
|
+
const tn = m2.typename === m2.key ? import_picocolors11.default.dim(`typename=${m2.typename}`) : import_picocolors11.default.yellow(`typename=${m2.typename}`);
|
|
281359
281751
|
const conflict = formatConflict(m2.conflict);
|
|
281360
|
-
const
|
|
281361
|
-
console.log(` ${
|
|
281752
|
+
const conflictStr2 = conflict ? ` ${import_picocolors11.default.dim(`conflict=${conflict}`)}` : "";
|
|
281753
|
+
console.log(` ${import_picocolors11.default.dim("\u2022")} ${m2.key.padEnd(14)} ${tn}${conflictStr2}`);
|
|
281362
281754
|
}
|
|
281363
281755
|
} else if (pushed && !pushed.active) {
|
|
281364
|
-
console.log(` ${
|
|
281756
|
+
console.log(` ${import_picocolors11.default.dim("schema")} ${import_picocolors11.default.yellow("none pushed")} ${import_picocolors11.default.dim(`(run ${import_picocolors11.default.bold("ablo push")} or ${import_picocolors11.default.bold("ablo dev")})`)}`);
|
|
281757
|
+
}
|
|
281758
|
+
if (pushed && pushed.active && pushed.models.length > 0) {
|
|
281759
|
+
const probe = await probeDataPlane(apiUrl2, introspectKey, pushed.models[0].typename);
|
|
281760
|
+
if (probe.status === "no_database") {
|
|
281761
|
+
console.log(` ${import_picocolors11.default.dim("data")} ${import_picocolors11.default.red("\u2717 no database registered")}${org ? import_picocolors11.default.dim(` for org ${org}`) : ""}`);
|
|
281762
|
+
console.log(
|
|
281763
|
+
` ${import_picocolors11.default.dim(
|
|
281764
|
+
`reads/writes will fail with ${import_picocolors11.default.bold("tenant_routing_failed")}. Connect one with ${import_picocolors11.default.bold("ablo connect")}, or point ${import_picocolors11.default.bold("ABLO_API_KEY")} at an org that has a database.`
|
|
281765
|
+
)}`
|
|
281766
|
+
);
|
|
281767
|
+
} else if (probe.status === "intermittent") {
|
|
281768
|
+
console.log(` ${import_picocolors11.default.dim("data")} ${import_picocolors11.default.red(`\u2717 database routing is intermittent`)} ${import_picocolors11.default.dim(`(${probe.ok} ok / ${probe.failed} failed of ${probe.ok + probe.failed})`)}${org ? import_picocolors11.default.dim(` for org ${org}`) : ""}`);
|
|
281769
|
+
console.log(
|
|
281770
|
+
` ${import_picocolors11.default.dim(
|
|
281771
|
+
`some reads/writes fail with ${import_picocolors11.default.bold("tenant_routing_failed")} \u2014 the registration is unstable. Re-establish it with ${import_picocolors11.default.bold("ablo connect")} (or check for a recent server redeploy).`
|
|
281772
|
+
)}`
|
|
281773
|
+
);
|
|
281774
|
+
} else if (probe.status === "forbidden") {
|
|
281775
|
+
console.log(` ${import_picocolors11.default.dim("data")} ${import_picocolors11.default.yellow("? key not authorized to read")}${probe.detail ? import_picocolors11.default.dim(` (${probe.detail})`) : ""}`);
|
|
281776
|
+
} else if (probe.status === "unknown") {
|
|
281777
|
+
console.log(` ${import_picocolors11.default.dim("data")} ${import_picocolors11.default.yellow(`? data-plane check inconclusive (${probe.detail})`)}`);
|
|
281778
|
+
}
|
|
281365
281779
|
}
|
|
281366
281780
|
}
|
|
281367
281781
|
console.log();
|
|
@@ -281369,7 +281783,7 @@ async function status(args = []) {
|
|
|
281369
281783
|
|
|
281370
281784
|
// src/cli/logs.ts
|
|
281371
281785
|
init_cjs_shims();
|
|
281372
|
-
var
|
|
281786
|
+
var import_picocolors12 = __toESM(require_picocolors(), 1);
|
|
281373
281787
|
function parseLogsArgs(argv) {
|
|
281374
281788
|
const args = {
|
|
281375
281789
|
follow: true,
|
|
@@ -281433,10 +281847,10 @@ function resolveSince(since) {
|
|
|
281433
281847
|
var sleep2 = (ms) => new Promise((r2) => setTimeout(r2, ms));
|
|
281434
281848
|
function colorOp(op) {
|
|
281435
281849
|
const label = op.padEnd(6);
|
|
281436
|
-
if (op === "create") return
|
|
281437
|
-
if (op === "update") return
|
|
281438
|
-
if (op === "delete") return
|
|
281439
|
-
return
|
|
281850
|
+
if (op === "create") return import_picocolors12.default.green(label);
|
|
281851
|
+
if (op === "update") return import_picocolors12.default.yellow(label);
|
|
281852
|
+
if (op === "delete") return import_picocolors12.default.red(label);
|
|
281853
|
+
return import_picocolors12.default.dim(label);
|
|
281440
281854
|
}
|
|
281441
281855
|
function render(e2, json) {
|
|
281442
281856
|
if (json) {
|
|
@@ -281445,21 +281859,21 @@ function render(e2, json) {
|
|
|
281445
281859
|
return;
|
|
281446
281860
|
}
|
|
281447
281861
|
const t = new Date(e2.at).toLocaleTimeString();
|
|
281448
|
-
const actor = e2.actor ?
|
|
281449
|
-
console.log(` ${
|
|
281862
|
+
const actor = e2.actor ? import_picocolors12.default.dim(` ${e2.actor}`) : "";
|
|
281863
|
+
console.log(` ${import_picocolors12.default.dim(t)} ${colorOp(e2.op)} ${import_picocolors12.default.bold(e2.model)} ${import_picocolors12.default.dim(e2.recordId)}${actor}`);
|
|
281450
281864
|
}
|
|
281451
281865
|
async function logs(argv) {
|
|
281452
281866
|
let args;
|
|
281453
281867
|
try {
|
|
281454
281868
|
args = parseLogsArgs(argv);
|
|
281455
281869
|
} catch (err) {
|
|
281456
|
-
console.error(
|
|
281870
|
+
console.error(import_picocolors12.default.red(` ${err instanceof Error ? err.message : String(err)}`));
|
|
281457
281871
|
process.exit(1);
|
|
281458
281872
|
}
|
|
281459
281873
|
const apiKey = resolveApiKey(args.mode);
|
|
281460
281874
|
if (!apiKey) {
|
|
281461
281875
|
console.error(
|
|
281462
|
-
|
|
281876
|
+
import_picocolors12.default.red(` No API key.`) + import_picocolors12.default.dim(` Run ${import_picocolors12.default.bold("ablo login")} or set ${import_picocolors12.default.bold("ABLO_API_KEY")}.`)
|
|
281463
281877
|
);
|
|
281464
281878
|
process.exit(1);
|
|
281465
281879
|
}
|
|
@@ -281473,7 +281887,7 @@ async function logs(argv) {
|
|
|
281473
281887
|
if (!res) return null;
|
|
281474
281888
|
if (!res.ok) {
|
|
281475
281889
|
const body = await res.json().catch(() => ({}));
|
|
281476
|
-
console.error(
|
|
281890
|
+
console.error(import_picocolors12.default.red(` logs failed (${res.status}): ${body.reason ?? body.message ?? ""}`));
|
|
281477
281891
|
process.exit(1);
|
|
281478
281892
|
}
|
|
281479
281893
|
const json = await res.json();
|
|
@@ -281484,7 +281898,7 @@ async function logs(argv) {
|
|
|
281484
281898
|
}
|
|
281485
281899
|
if (!args.json) {
|
|
281486
281900
|
console.log(`
|
|
281487
|
-
${brand("ablo")} ${
|
|
281901
|
+
${brand("ablo")} ${import_picocolors12.default.dim("logs")} ${import_picocolors12.default.dim(`(${args.mode ?? "active"} mode)`)}
|
|
281488
281902
|
`);
|
|
281489
281903
|
}
|
|
281490
281904
|
const initial = await fetchPage({
|
|
@@ -281494,13 +281908,13 @@ async function logs(argv) {
|
|
|
281494
281908
|
...args.op ? { op: args.op } : {}
|
|
281495
281909
|
});
|
|
281496
281910
|
if (!initial) {
|
|
281497
|
-
console.error(
|
|
281911
|
+
console.error(import_picocolors12.default.red(` Couldn't reach ${baseUrl2}.`));
|
|
281498
281912
|
process.exit(1);
|
|
281499
281913
|
}
|
|
281500
281914
|
for (const e2 of initial.events) render(e2, args.json);
|
|
281501
281915
|
let cursor = initial.cursor;
|
|
281502
281916
|
if (!args.follow) return;
|
|
281503
|
-
if (!args.json) console.log(` ${
|
|
281917
|
+
if (!args.json) console.log(` ${import_picocolors12.default.dim("watching for new activity \u2026 (Ctrl-C to stop)")}
|
|
281504
281918
|
`);
|
|
281505
281919
|
for (; ; ) {
|
|
281506
281920
|
await sleep2(1500);
|
|
@@ -281518,7 +281932,7 @@ async function logs(argv) {
|
|
|
281518
281932
|
// src/cli/webhooks.ts
|
|
281519
281933
|
init_cjs_shims();
|
|
281520
281934
|
var import_fs8 = require("fs");
|
|
281521
|
-
var
|
|
281935
|
+
var import_picocolors13 = __toESM(require_picocolors(), 1);
|
|
281522
281936
|
var ENV_KEY = "ABLO_WEBHOOK_SECRET";
|
|
281523
281937
|
function flag(args, name) {
|
|
281524
281938
|
const inline = args.find((a) => a.startsWith(`${name}=`));
|
|
@@ -281545,12 +281959,12 @@ function requireKey2(mode2) {
|
|
|
281545
281959
|
const apiKey = resolveApiKey(mode2);
|
|
281546
281960
|
if (!apiKey) {
|
|
281547
281961
|
console.error(
|
|
281548
|
-
|
|
281962
|
+
import_picocolors13.default.red(" No API key.") + import_picocolors13.default.dim(` Run ${import_picocolors13.default.bold("ablo login")} or set ${import_picocolors13.default.bold("ABLO_API_KEY")}.`)
|
|
281549
281963
|
);
|
|
281550
281964
|
process.exit(1);
|
|
281551
281965
|
}
|
|
281552
281966
|
if (classifyCredentialKind(apiKey) !== "secret") {
|
|
281553
|
-
console.error(
|
|
281967
|
+
console.error(import_picocolors13.default.red(" Managing webhooks requires a secret key ") + import_picocolors13.default.dim("(sk_test_ / sk_live_)."));
|
|
281554
281968
|
process.exit(1);
|
|
281555
281969
|
}
|
|
281556
281970
|
return apiKey;
|
|
@@ -281566,12 +281980,12 @@ async function api(apiKey, method, path, body) {
|
|
|
281566
281980
|
...body ? { body: JSON.stringify(body) } : {}
|
|
281567
281981
|
}).catch(() => null);
|
|
281568
281982
|
if (!res) {
|
|
281569
|
-
console.error(
|
|
281983
|
+
console.error(import_picocolors13.default.red(` Couldn't reach ${baseUrl()}.`));
|
|
281570
281984
|
process.exit(1);
|
|
281571
281985
|
}
|
|
281572
281986
|
if (!res.ok) {
|
|
281573
281987
|
const err = await res.json().catch(() => ({}));
|
|
281574
|
-
console.error(
|
|
281988
|
+
console.error(import_picocolors13.default.red(` Request failed (${res.status}): ${err.message ?? err.reason ?? ""}`));
|
|
281575
281989
|
process.exit(1);
|
|
281576
281990
|
}
|
|
281577
281991
|
return await res.json();
|
|
@@ -281593,11 +282007,11 @@ ${line}
|
|
|
281593
282007
|
return file;
|
|
281594
282008
|
}
|
|
281595
282009
|
function printEndpoint(e2) {
|
|
281596
|
-
const dot = e2.status === "enabled" ?
|
|
281597
|
-
const health = e2.last_error ?
|
|
281598
|
-
console.log(` ${dot} ${
|
|
282010
|
+
const dot = e2.status === "enabled" ? import_picocolors13.default.green("\u25CF") : import_picocolors13.default.red("\u25CF");
|
|
282011
|
+
const health = e2.last_error ? import_picocolors13.default.red(` last error: ${e2.last_error}`) : "";
|
|
282012
|
+
console.log(` ${dot} ${import_picocolors13.default.bold(e2.id)} ${e2.url}`);
|
|
281599
282013
|
console.log(
|
|
281600
|
-
|
|
282014
|
+
import_picocolors13.default.dim(
|
|
281601
282015
|
` ${e2.status} \xB7 ${e2.environment} \xB7 events ${e2.enabled_events.join(",")} \xB7 cursor ${e2.cursor ?? "\u2014"}${health}`
|
|
281602
282016
|
)
|
|
281603
282017
|
);
|
|
@@ -281609,7 +282023,7 @@ async function webhooks(argv) {
|
|
|
281609
282023
|
if (sub === "create") {
|
|
281610
282024
|
const url = positional(rest);
|
|
281611
282025
|
if (!url) {
|
|
281612
|
-
console.error(
|
|
282026
|
+
console.error(import_picocolors13.default.red(" Usage: ") + brand("ablo webhooks create <url>"));
|
|
281613
282027
|
process.exit(1);
|
|
281614
282028
|
}
|
|
281615
282029
|
const apiKey = requireKey2(mode2);
|
|
@@ -281621,8 +282035,8 @@ async function webhooks(argv) {
|
|
|
281621
282035
|
});
|
|
281622
282036
|
const file = writeSecretToEnv(created.secret);
|
|
281623
282037
|
console.log(`
|
|
281624
|
-
${
|
|
281625
|
-
console.log(` ${
|
|
282038
|
+
${import_picocolors13.default.green("\u2713")} Registered ${import_picocolors13.default.bold(created.id)} \u2192 ${created.url}`);
|
|
282039
|
+
console.log(` ${import_picocolors13.default.green("\u2713")} Wrote ${import_picocolors13.default.bold(ENV_KEY)} to ${import_picocolors13.default.bold(file)} ${import_picocolors13.default.dim("(shown once)")}
|
|
281626
282040
|
`);
|
|
281627
282041
|
return;
|
|
281628
282042
|
}
|
|
@@ -281630,7 +282044,7 @@ async function webhooks(argv) {
|
|
|
281630
282044
|
const apiKey = requireKey2(mode2);
|
|
281631
282045
|
const { data } = await api(apiKey, "GET", "");
|
|
281632
282046
|
if (data.length === 0) {
|
|
281633
|
-
console.log(
|
|
282047
|
+
console.log(import_picocolors13.default.dim(" No webhook endpoints. ") + brand("ablo webhooks create <url>"));
|
|
281634
282048
|
return;
|
|
281635
282049
|
}
|
|
281636
282050
|
console.log();
|
|
@@ -281641,40 +282055,40 @@ async function webhooks(argv) {
|
|
|
281641
282055
|
if (sub === "roll") {
|
|
281642
282056
|
const id = positional(rest);
|
|
281643
282057
|
if (!id) {
|
|
281644
|
-
console.error(
|
|
282058
|
+
console.error(import_picocolors13.default.red(" Usage: ") + brand("ablo webhooks roll <id>"));
|
|
281645
282059
|
process.exit(1);
|
|
281646
282060
|
}
|
|
281647
282061
|
const apiKey = requireKey2(mode2);
|
|
281648
282062
|
const rolled = await api(apiKey, "POST", `/${id}/roll_secret`);
|
|
281649
282063
|
const file = writeSecretToEnv(rolled.secret);
|
|
281650
282064
|
console.log(`
|
|
281651
|
-
${
|
|
282065
|
+
${import_picocolors13.default.green("\u2713")} Rolled secret for ${import_picocolors13.default.bold(id)} \u2192 ${import_picocolors13.default.bold(file)} ${import_picocolors13.default.dim("(old secret now invalid)")}
|
|
281652
282066
|
`);
|
|
281653
282067
|
return;
|
|
281654
282068
|
}
|
|
281655
282069
|
if (sub === "enable") {
|
|
281656
282070
|
const id = positional(rest);
|
|
281657
282071
|
if (!id) {
|
|
281658
|
-
console.error(
|
|
282072
|
+
console.error(import_picocolors13.default.red(" Usage: ") + brand("ablo webhooks enable <id>"));
|
|
281659
282073
|
process.exit(1);
|
|
281660
282074
|
}
|
|
281661
282075
|
const apiKey = requireKey2(mode2);
|
|
281662
282076
|
const e2 = await api(apiKey, "POST", `/${id}/enable`);
|
|
281663
|
-
console.log(` ${
|
|
282077
|
+
console.log(` ${import_picocolors13.default.green("\u2713")} Re-enabled ${import_picocolors13.default.bold(e2.id)}`);
|
|
281664
282078
|
return;
|
|
281665
282079
|
}
|
|
281666
282080
|
if (sub === "rm" || sub === "delete") {
|
|
281667
282081
|
const id = positional(rest);
|
|
281668
282082
|
if (!id) {
|
|
281669
|
-
console.error(
|
|
282083
|
+
console.error(import_picocolors13.default.red(" Usage: ") + brand("ablo webhooks rm <id>"));
|
|
281670
282084
|
process.exit(1);
|
|
281671
282085
|
}
|
|
281672
282086
|
const apiKey = requireKey2(mode2);
|
|
281673
282087
|
await api(apiKey, "DELETE", `/${id}`);
|
|
281674
|
-
console.log(` ${
|
|
282088
|
+
console.log(` ${import_picocolors13.default.green("\u2713")} Removed ${import_picocolors13.default.bold(id)}`);
|
|
281675
282089
|
return;
|
|
281676
282090
|
}
|
|
281677
|
-
console.log(` ${
|
|
282091
|
+
console.log(` ${import_picocolors13.default.bold("Usage:")}`);
|
|
281678
282092
|
console.log(` ${brand("ablo webhooks create <url>")} Register an endpoint; writes ${ENV_KEY}`);
|
|
281679
282093
|
console.log(` ${brand("ablo webhooks list")} List endpoints + delivery health`);
|
|
281680
282094
|
console.log(` ${brand("ablo webhooks roll <id>")} Mint a fresh signing secret`);
|
|
@@ -281685,7 +282099,7 @@ async function webhooks(argv) {
|
|
|
281685
282099
|
|
|
281686
282100
|
// src/cli/check.ts
|
|
281687
282101
|
init_cjs_shims();
|
|
281688
|
-
var
|
|
282102
|
+
var import_picocolors14 = __toESM(require_picocolors(), 1);
|
|
281689
282103
|
var import_schema6 = require("@abloatai/ablo/schema");
|
|
281690
282104
|
var DEFAULT_SCHEMA_PATH4 = "ablo/schema.ts";
|
|
281691
282105
|
var DEFAULT_EXPORT4 = "schema";
|
|
@@ -281720,13 +282134,13 @@ async function check(argv) {
|
|
|
281720
282134
|
try {
|
|
281721
282135
|
args = parseCheckArgs(argv);
|
|
281722
282136
|
} catch (err) {
|
|
281723
|
-
console.error(
|
|
282137
|
+
console.error(import_picocolors14.default.red(` ${err instanceof Error ? err.message : String(err)}`));
|
|
281724
282138
|
process.exit(1);
|
|
281725
282139
|
}
|
|
281726
282140
|
const dbUrl = process.env.DATABASE_URL ?? process.env.ABLO_DATABASE_URL;
|
|
281727
282141
|
if (!dbUrl) {
|
|
281728
282142
|
console.error(
|
|
281729
|
-
|
|
282143
|
+
import_picocolors14.default.red(` No database.`) + import_picocolors14.default.dim(` Set ${import_picocolors14.default.bold("DATABASE_URL")} to the Postgres you want Ablo to adopt.`)
|
|
281730
282144
|
);
|
|
281731
282145
|
process.exit(1);
|
|
281732
282146
|
}
|
|
@@ -281741,7 +282155,7 @@ async function check(argv) {
|
|
|
281741
282155
|
[args.appSchema]
|
|
281742
282156
|
);
|
|
281743
282157
|
} catch (err) {
|
|
281744
|
-
console.error(
|
|
282158
|
+
console.error(import_picocolors14.default.red(` Couldn't read the database: ${err instanceof Error ? err.message : String(err)}`));
|
|
281745
282159
|
await sql.end({ timeout: 2 });
|
|
281746
282160
|
process.exit(1);
|
|
281747
282161
|
}
|
|
@@ -281756,7 +282170,7 @@ async function check(argv) {
|
|
|
281756
282170
|
set.add(r2.column_name);
|
|
281757
282171
|
}
|
|
281758
282172
|
console.log(`
|
|
281759
|
-
${brand("ablo")} ${
|
|
282173
|
+
${brand("ablo")} ${import_picocolors14.default.dim("check")} ${import_picocolors14.default.dim(`schema "${args.appSchema}"`)}
|
|
281760
282174
|
`);
|
|
281761
282175
|
const declaredTables = /* @__PURE__ */ new Set();
|
|
281762
282176
|
let errors = 0;
|
|
@@ -281766,7 +282180,7 @@ async function check(argv) {
|
|
|
281766
282180
|
declaredTables.add(table);
|
|
281767
282181
|
const present = colsByTable.get(table);
|
|
281768
282182
|
if (!present) {
|
|
281769
|
-
console.log(` ${
|
|
282183
|
+
console.log(` ${import_picocolors14.default.red("\u2717")} ${import_picocolors14.default.bold(key)} ${import_picocolors14.default.dim("\u2192")} table ${import_picocolors14.default.bold(table)} ${import_picocolors14.default.red("not found")}`);
|
|
281770
282184
|
errors++;
|
|
281771
282185
|
continue;
|
|
281772
282186
|
}
|
|
@@ -281788,26 +282202,26 @@ async function check(argv) {
|
|
|
281788
282202
|
if (!present.has(col)) problems.push(`missing column "${col}" (field ${fieldName})`);
|
|
281789
282203
|
}
|
|
281790
282204
|
if (problems.length > 0) {
|
|
281791
|
-
console.log(` ${
|
|
281792
|
-
for (const p2 of problems) console.log(` ${
|
|
281793
|
-
for (const w2 of warns) console.log(` ${
|
|
282205
|
+
console.log(` ${import_picocolors14.default.red("\u2717")} ${import_picocolors14.default.bold(key)} ${import_picocolors14.default.dim("\u2192")} ${table}`);
|
|
282206
|
+
for (const p2 of problems) console.log(` ${import_picocolors14.default.red("\u2022")} ${p2}`);
|
|
282207
|
+
for (const w2 of warns) console.log(` ${import_picocolors14.default.yellow("\u2022")} ${w2}`);
|
|
281794
282208
|
errors++;
|
|
281795
282209
|
} else if (warns.length > 0) {
|
|
281796
|
-
console.log(` ${
|
|
281797
|
-
for (const w2 of warns) console.log(` ${
|
|
282210
|
+
console.log(` ${import_picocolors14.default.yellow("!")} ${import_picocolors14.default.bold(key)} ${import_picocolors14.default.dim("\u2192")} ${table}`);
|
|
282211
|
+
for (const w2 of warns) console.log(` ${import_picocolors14.default.yellow("\u2022")} ${w2}`);
|
|
281798
282212
|
warnings++;
|
|
281799
282213
|
} else {
|
|
281800
|
-
console.log(` ${
|
|
282214
|
+
console.log(` ${import_picocolors14.default.green("\u2713")} ${import_picocolors14.default.bold(key)} ${import_picocolors14.default.dim(`\u2192 ${table} (id, ${orgCol ?? "no org"} ok)`)}`);
|
|
281801
282215
|
}
|
|
281802
282216
|
}
|
|
281803
282217
|
const modelCount = Object.keys(schemaJson.models).length;
|
|
281804
282218
|
const ignored = [...colsByTable.keys()].filter((t) => !declaredTables.has(t)).length;
|
|
281805
282219
|
console.log(
|
|
281806
282220
|
`
|
|
281807
|
-
${modelCount} model${modelCount === 1 ? "" : "s"} \xB7 ${
|
|
282221
|
+
${modelCount} model${modelCount === 1 ? "" : "s"} \xB7 ${import_picocolors14.default.green(`${modelCount - errors - warnings} ok`)}` + (warnings ? ` \xB7 ${import_picocolors14.default.yellow(`${warnings} warning${warnings === 1 ? "" : "s"}`)}` : "") + (errors ? ` \xB7 ${import_picocolors14.default.red(`${errors} error${errors === 1 ? "" : "s"}`)}` : "")
|
|
281808
282222
|
);
|
|
281809
282223
|
if (ignored > 0) {
|
|
281810
|
-
console.log(` ${
|
|
282224
|
+
console.log(` ${import_picocolors14.default.dim(`${ignored} other table${ignored === 1 ? "" : "s"} in your database \u2014 ignored by Ablo`)}`);
|
|
281811
282225
|
}
|
|
281812
282226
|
console.log();
|
|
281813
282227
|
process.exit(errors > 0 ? 1 : 0);
|
|
@@ -281815,7 +282229,7 @@ async function check(argv) {
|
|
|
281815
282229
|
|
|
281816
282230
|
// src/cli/upgrade.ts
|
|
281817
282231
|
init_cjs_shims();
|
|
281818
|
-
var
|
|
282232
|
+
var import_picocolors15 = __toESM(require_picocolors(), 1);
|
|
281819
282233
|
var import_ts_morph = __toESM(require_ts_morph(), 1);
|
|
281820
282234
|
var DEFAULT_GLOBS = ["app/**/*.{ts,tsx}", "src/**/*.{ts,tsx}", "ablo/**/*.{ts,tsx}", "lib/**/*.{ts,tsx}"];
|
|
281821
282235
|
var VERB_ARGS = {
|
|
@@ -281893,7 +282307,7 @@ async function upgrade(argv) {
|
|
|
281893
282307
|
project.addSourceFilesAtPaths(globs.length > 0 ? globs : DEFAULT_GLOBS);
|
|
281894
282308
|
const files = project.getSourceFiles();
|
|
281895
282309
|
if (files.length === 0) {
|
|
281896
|
-
console.log(
|
|
282310
|
+
console.log(import_picocolors15.default.yellow(' No .ts/.tsx files found. Pass a glob, e.g. `ablo upgrade "src/**/*.tsx"`.'));
|
|
281897
282311
|
return;
|
|
281898
282312
|
}
|
|
281899
282313
|
const edits = [];
|
|
@@ -281967,38 +282381,38 @@ async function upgrade(argv) {
|
|
|
281967
282381
|
const rel = (f) => f.replace(cwd + "/", "");
|
|
281968
282382
|
console.log();
|
|
281969
282383
|
if (edits.length === 0 && manual.length === 0) {
|
|
281970
|
-
console.log(
|
|
282384
|
+
console.log(import_picocolors15.default.green(" \u2713 Nothing to migrate \u2014 your code is already on the current API."));
|
|
281971
282385
|
return;
|
|
281972
282386
|
}
|
|
281973
282387
|
if (edits.length > 0) {
|
|
281974
|
-
console.log(
|
|
282388
|
+
console.log(import_picocolors15.default.bold(` ${write ? "Applied" : "Would apply"} ${edits.length} change${edits.length === 1 ? "" : "s"}:`));
|
|
281975
282389
|
for (const e2 of edits) {
|
|
281976
|
-
console.log(` ${
|
|
281977
|
-
console.log(` ${
|
|
281978
|
-
console.log(` ${
|
|
282390
|
+
console.log(` ${import_picocolors15.default.dim(`${rel(e2.file)}:${e2.line}`)} ${import_picocolors15.default.cyan(e2.rule)}`);
|
|
282391
|
+
console.log(` ${import_picocolors15.default.red("-")} ${e2.before}`);
|
|
282392
|
+
console.log(` ${import_picocolors15.default.green("+")} ${e2.after}`);
|
|
281979
282393
|
}
|
|
281980
282394
|
}
|
|
281981
282395
|
if (manual.length > 0) {
|
|
281982
282396
|
console.log();
|
|
281983
|
-
console.log(
|
|
282397
|
+
console.log(import_picocolors15.default.bold(import_picocolors15.default.yellow(` ${manual.length} spot${manual.length === 1 ? "" : "s"} need manual review (structural):`)));
|
|
281984
282398
|
for (const m2 of manual) {
|
|
281985
|
-
console.log(` ${
|
|
281986
|
-
console.log(` ${
|
|
282399
|
+
console.log(` ${import_picocolors15.default.dim(`${rel(m2.file)}:${m2.line}`)} ${import_picocolors15.default.yellow(m2.rule)}`);
|
|
282400
|
+
console.log(` ${import_picocolors15.default.dim(m2.snippet)}`);
|
|
281987
282401
|
console.log(` \u2192 ${m2.hint}`);
|
|
281988
282402
|
}
|
|
281989
282403
|
}
|
|
281990
282404
|
console.log();
|
|
281991
282405
|
if (write) {
|
|
281992
282406
|
await project.save();
|
|
281993
|
-
console.log(
|
|
282407
|
+
console.log(import_picocolors15.default.green(` \u2713 Wrote ${edits.length} change${edits.length === 1 ? "" : "s"}. Review the diff, run your typecheck.`));
|
|
281994
282408
|
} else {
|
|
281995
|
-
console.log(
|
|
282409
|
+
console.log(import_picocolors15.default.dim(" Dry run. Re-run with `--write` to apply the auto-fixes above (manual items are never auto-written)."));
|
|
281996
282410
|
}
|
|
281997
282411
|
}
|
|
281998
282412
|
|
|
281999
282413
|
// src/cli/pull.ts
|
|
282000
282414
|
init_cjs_shims();
|
|
282001
|
-
var
|
|
282415
|
+
var import_picocolors16 = __toESM(require_picocolors(), 1);
|
|
282002
282416
|
var import_fs9 = require("fs");
|
|
282003
282417
|
var DEFAULT_OUT2 = "ablo/schema.ts";
|
|
282004
282418
|
var DEFAULT_IMPORT = "@abloatai/ablo/schema";
|
|
@@ -282110,52 +282524,52 @@ async function pull(argv) {
|
|
|
282110
282524
|
try {
|
|
282111
282525
|
args = parsePullArgs(argv);
|
|
282112
282526
|
} catch (err) {
|
|
282113
|
-
console.error(
|
|
282527
|
+
console.error(import_picocolors16.default.red(` ${err instanceof Error ? err.message : String(err)}`));
|
|
282114
282528
|
process.exit(1);
|
|
282115
282529
|
}
|
|
282116
282530
|
const dbUrl = process.env.DATABASE_URL ?? process.env.ABLO_DATABASE_URL;
|
|
282117
282531
|
if (!dbUrl) {
|
|
282118
|
-
console.error(
|
|
282532
|
+
console.error(import_picocolors16.default.red(` No database.`) + import_picocolors16.default.dim(` Set ${import_picocolors16.default.bold("DATABASE_URL")} to the Postgres to pull from.`));
|
|
282119
282533
|
process.exit(1);
|
|
282120
282534
|
}
|
|
282121
282535
|
if ((0, import_fs9.existsSync)(args.out) && !args.force) {
|
|
282122
282536
|
console.error(
|
|
282123
|
-
|
|
282537
|
+
import_picocolors16.default.red(` ${args.out} already exists.`) + import_picocolors16.default.dim(` Re-run with ${import_picocolors16.default.bold("--force")} to overwrite.`)
|
|
282124
282538
|
);
|
|
282125
282539
|
process.exit(1);
|
|
282126
282540
|
}
|
|
282127
282541
|
console.log(`
|
|
282128
|
-
${brand("ablo")} ${
|
|
282542
|
+
${brand("ablo")} ${import_picocolors16.default.dim("pull")} ${import_picocolors16.default.dim(`schema "${args.appSchema}"`)}
|
|
282129
282543
|
`);
|
|
282130
282544
|
let result;
|
|
282131
282545
|
try {
|
|
282132
282546
|
result = await buildSchemaSourceFromDb({ dbUrl, appSchema: args.appSchema, importPath: args.importPath });
|
|
282133
282547
|
} catch (err) {
|
|
282134
|
-
console.error(
|
|
282548
|
+
console.error(import_picocolors16.default.red(` Couldn't read the database: ${err instanceof Error ? err.message : String(err)}`));
|
|
282135
282549
|
process.exit(1);
|
|
282136
282550
|
}
|
|
282137
282551
|
if (result.models.length === 0) {
|
|
282138
282552
|
console.error(
|
|
282139
|
-
|
|
282553
|
+
import_picocolors16.default.yellow(` No adoptable tables found`) + import_picocolors16.default.dim(` (a model needs an ${import_picocolors16.default.bold("id")} + ${import_picocolors16.default.bold("organization_id")} column).`)
|
|
282140
282554
|
);
|
|
282141
282555
|
process.exit(1);
|
|
282142
282556
|
}
|
|
282143
282557
|
(0, import_fs9.writeFileSync)(args.out, result.source);
|
|
282144
|
-
console.log(` ${
|
|
282145
|
-
console.log(` ${
|
|
282558
|
+
console.log(` ${import_picocolors16.default.green("\u2713")} wrote ${import_picocolors16.default.bold(args.out)} ${import_picocolors16.default.dim(`(${result.models.length} models)`)}`);
|
|
282559
|
+
console.log(` ${import_picocolors16.default.dim(`models: ${result.models.join(", ")}`)}`);
|
|
282146
282560
|
if (result.skipped > 0) {
|
|
282147
|
-
console.log(` ${
|
|
282561
|
+
console.log(` ${import_picocolors16.default.dim(`${result.skipped} table(s) skipped \u2014 no id/organization_id`)}`);
|
|
282148
282562
|
}
|
|
282149
282563
|
console.log(
|
|
282150
282564
|
`
|
|
282151
|
-
${
|
|
282565
|
+
${import_picocolors16.default.dim("Introspection is lossy (enums, JSON shape, relations). Review the file, then")} ${import_picocolors16.default.bold("ablo check")}.
|
|
282152
282566
|
`
|
|
282153
282567
|
);
|
|
282154
282568
|
}
|
|
282155
282569
|
|
|
282156
282570
|
// src/cli/prisma-pull.ts
|
|
282157
282571
|
init_cjs_shims();
|
|
282158
|
-
var
|
|
282572
|
+
var import_picocolors17 = __toESM(require_picocolors(), 1);
|
|
282159
282573
|
var import_fs10 = require("fs");
|
|
282160
282574
|
|
|
282161
282575
|
// src/cli/schema-ir.ts
|
|
@@ -282433,55 +282847,55 @@ async function prismaPull(argv) {
|
|
|
282433
282847
|
try {
|
|
282434
282848
|
args = parsePrismaPullArgs(argv);
|
|
282435
282849
|
} catch (err) {
|
|
282436
|
-
console.error(
|
|
282850
|
+
console.error(import_picocolors17.default.red(` ${err instanceof Error ? err.message : String(err)}`));
|
|
282437
282851
|
process.exit(1);
|
|
282438
282852
|
}
|
|
282439
282853
|
if (!(0, import_fs10.existsSync)(args.schema)) {
|
|
282440
282854
|
console.error(
|
|
282441
|
-
|
|
282855
|
+
import_picocolors17.default.red(` No Prisma schema at ${import_picocolors17.default.bold(args.schema)}.`) + import_picocolors17.default.dim(` Pass a path: ${import_picocolors17.default.bold("ablo pull prisma <path>")}.`)
|
|
282442
282856
|
);
|
|
282443
282857
|
process.exit(1);
|
|
282444
282858
|
}
|
|
282445
282859
|
if ((0, import_fs10.existsSync)(args.out) && !args.force) {
|
|
282446
282860
|
console.error(
|
|
282447
|
-
|
|
282861
|
+
import_picocolors17.default.red(` ${args.out} already exists.`) + import_picocolors17.default.dim(` Re-run with ${import_picocolors17.default.bold("--force")} to overwrite.`)
|
|
282448
282862
|
);
|
|
282449
282863
|
process.exit(1);
|
|
282450
282864
|
}
|
|
282451
282865
|
console.log(`
|
|
282452
|
-
${brand("ablo")} ${
|
|
282866
|
+
${brand("ablo")} ${import_picocolors17.default.dim("pull prisma")} ${import_picocolors17.default.dim(args.schema)}
|
|
282453
282867
|
`);
|
|
282454
282868
|
let result;
|
|
282455
282869
|
try {
|
|
282456
282870
|
const src = (0, import_fs10.readFileSync)(args.schema, "utf8");
|
|
282457
282871
|
result = buildSchemaSourceFromPrisma({ src, importPath: args.importPath });
|
|
282458
282872
|
} catch (err) {
|
|
282459
|
-
console.error(
|
|
282873
|
+
console.error(import_picocolors17.default.red(` Couldn't parse the schema: ${err instanceof Error ? err.message : String(err)}`));
|
|
282460
282874
|
process.exit(1);
|
|
282461
282875
|
}
|
|
282462
282876
|
if (result.models.length === 0) {
|
|
282463
282877
|
console.error(
|
|
282464
|
-
|
|
282878
|
+
import_picocolors17.default.yellow(` No adoptable models found`) + import_picocolors17.default.dim(` (a model needs an ${import_picocolors17.default.bold("id")} + ${import_picocolors17.default.bold("organizationId")} / ${import_picocolors17.default.bold("organization_id")}).`)
|
|
282465
282879
|
);
|
|
282466
282880
|
process.exit(1);
|
|
282467
282881
|
}
|
|
282468
282882
|
(0, import_fs10.writeFileSync)(args.out, result.source);
|
|
282469
|
-
console.log(` ${
|
|
282470
|
-
console.log(` ${
|
|
282883
|
+
console.log(` ${import_picocolors17.default.green("\u2713")} wrote ${import_picocolors17.default.bold(args.out)} ${import_picocolors17.default.dim(`(${result.models.length} models)`)}`);
|
|
282884
|
+
console.log(` ${import_picocolors17.default.dim(`models: ${result.models.join(", ")}`)}`);
|
|
282471
282885
|
if (result.skipped.length > 0) {
|
|
282472
|
-
console.log(` ${
|
|
282473
|
-
for (const s of result.skipped) console.log(` ${
|
|
282886
|
+
console.log(` ${import_picocolors17.default.dim(`${result.skipped.length} model(s) skipped:`)}`);
|
|
282887
|
+
for (const s of result.skipped) console.log(` ${import_picocolors17.default.dim(`- ${s.name}: ${s.reason}`)}`);
|
|
282474
282888
|
}
|
|
282475
282889
|
console.log(
|
|
282476
282890
|
`
|
|
282477
|
-
${
|
|
282891
|
+
${import_picocolors17.default.dim("Enums and relations were preserved. Review the file, then")} ${import_picocolors17.default.bold("ablo check")}.
|
|
282478
282892
|
`
|
|
282479
282893
|
);
|
|
282480
282894
|
}
|
|
282481
282895
|
|
|
282482
282896
|
// src/cli/drizzle-pull.ts
|
|
282483
282897
|
init_cjs_shims();
|
|
282484
|
-
var
|
|
282898
|
+
var import_picocolors18 = __toESM(require_picocolors(), 1);
|
|
282485
282899
|
var import_fs11 = require("fs");
|
|
282486
282900
|
var import_path6 = require("path");
|
|
282487
282901
|
var DEFAULT_OUT4 = "ablo/schema.ts";
|
|
@@ -282530,7 +282944,7 @@ async function loadDrizzle() {
|
|
|
282530
282944
|
}
|
|
282531
282945
|
async function lowerDrizzleModule(mod) {
|
|
282532
282946
|
const { is, getTableName, getTableColumns, PgTable, getTableConfig } = await loadDrizzle();
|
|
282533
|
-
const tables = Object.values(mod).filter((
|
|
282947
|
+
const tables = Object.values(mod).filter((v2) => is(v2, PgTable));
|
|
282534
282948
|
const models = [];
|
|
282535
282949
|
const skipped = [];
|
|
282536
282950
|
for (const table of tables) {
|
|
@@ -282617,27 +283031,27 @@ async function drizzlePull(argv) {
|
|
|
282617
283031
|
try {
|
|
282618
283032
|
args = parseDrizzlePullArgs(argv);
|
|
282619
283033
|
} catch (err) {
|
|
282620
|
-
console.error(
|
|
283034
|
+
console.error(import_picocolors18.default.red(` ${err instanceof Error ? err.message : String(err)}`));
|
|
282621
283035
|
process.exit(1);
|
|
282622
283036
|
}
|
|
282623
283037
|
if (!args.schema) {
|
|
282624
283038
|
console.error(
|
|
282625
|
-
|
|
283039
|
+
import_picocolors18.default.red(` No Drizzle schema given.`) + import_picocolors18.default.dim(` Pass the module: ${import_picocolors18.default.bold("ablo pull drizzle src/db/schema.ts")}.`)
|
|
282626
283040
|
);
|
|
282627
283041
|
process.exit(1);
|
|
282628
283042
|
}
|
|
282629
283043
|
if (!(0, import_fs11.existsSync)(args.schema)) {
|
|
282630
|
-
console.error(
|
|
283044
|
+
console.error(import_picocolors18.default.red(` No file at ${import_picocolors18.default.bold(args.schema)}.`));
|
|
282631
283045
|
process.exit(1);
|
|
282632
283046
|
}
|
|
282633
283047
|
if ((0, import_fs11.existsSync)(args.out) && !args.force) {
|
|
282634
283048
|
console.error(
|
|
282635
|
-
|
|
283049
|
+
import_picocolors18.default.red(` ${args.out} already exists.`) + import_picocolors18.default.dim(` Re-run with ${import_picocolors18.default.bold("--force")} to overwrite.`)
|
|
282636
283050
|
);
|
|
282637
283051
|
process.exit(1);
|
|
282638
283052
|
}
|
|
282639
283053
|
console.log(`
|
|
282640
|
-
${brand("ablo")} ${
|
|
283054
|
+
${brand("ablo")} ${import_picocolors18.default.dim("pull drizzle")} ${import_picocolors18.default.dim(args.schema)}
|
|
282641
283055
|
`);
|
|
282642
283056
|
let result;
|
|
282643
283057
|
try {
|
|
@@ -282645,33 +283059,33 @@ async function drizzlePull(argv) {
|
|
|
282645
283059
|
result = await buildSchemaSourceFromDrizzle({ mod, importPath: args.importPath });
|
|
282646
283060
|
} catch (err) {
|
|
282647
283061
|
const msg = err instanceof Error ? err.message : String(err);
|
|
282648
|
-
const hint = /Cannot find package 'drizzle-orm'/.test(msg) ?
|
|
282649
|
-
console.error(
|
|
283062
|
+
const hint = /Cannot find package 'drizzle-orm'/.test(msg) ? import_picocolors18.default.dim(` (install ${import_picocolors18.default.bold("drizzle-orm")} in this project)`) : "";
|
|
283063
|
+
console.error(import_picocolors18.default.red(` Couldn't load the schema: ${msg}`) + hint);
|
|
282650
283064
|
process.exit(1);
|
|
282651
283065
|
}
|
|
282652
283066
|
if (result.models.length === 0) {
|
|
282653
283067
|
console.error(
|
|
282654
|
-
|
|
283068
|
+
import_picocolors18.default.yellow(` No adoptable tables found`) + import_picocolors18.default.dim(` (a table needs an ${import_picocolors18.default.bold("id")} + ${import_picocolors18.default.bold("organization_id")} column).`)
|
|
282655
283069
|
);
|
|
282656
283070
|
process.exit(1);
|
|
282657
283071
|
}
|
|
282658
283072
|
(0, import_fs11.writeFileSync)(args.out, result.source);
|
|
282659
|
-
console.log(` ${
|
|
282660
|
-
console.log(` ${
|
|
283073
|
+
console.log(` ${import_picocolors18.default.green("\u2713")} wrote ${import_picocolors18.default.bold(args.out)} ${import_picocolors18.default.dim(`(${result.models.length} models)`)}`);
|
|
283074
|
+
console.log(` ${import_picocolors18.default.dim(`models: ${result.models.join(", ")}`)}`);
|
|
282661
283075
|
if (result.skipped.length > 0) {
|
|
282662
|
-
console.log(` ${
|
|
282663
|
-
for (const s of result.skipped) console.log(` ${
|
|
283076
|
+
console.log(` ${import_picocolors18.default.dim(`${result.skipped.length} table(s) skipped:`)}`);
|
|
283077
|
+
for (const s of result.skipped) console.log(` ${import_picocolors18.default.dim(`- ${s.name}: ${s.reason}`)}`);
|
|
282664
283078
|
}
|
|
282665
283079
|
console.log(
|
|
282666
283080
|
`
|
|
282667
|
-
${
|
|
283081
|
+
${import_picocolors18.default.dim("Enums and relations were preserved. Review the file, then")} ${import_picocolors18.default.bold("ablo check")}.
|
|
282668
283082
|
`
|
|
282669
283083
|
);
|
|
282670
283084
|
}
|
|
282671
283085
|
|
|
282672
283086
|
// src/cli/renderError.ts
|
|
282673
283087
|
init_cjs_shims();
|
|
282674
|
-
var
|
|
283088
|
+
var import_picocolors19 = __toESM(require_picocolors(), 1);
|
|
282675
283089
|
var RECOVERY_HINT = {
|
|
282676
283090
|
transient: "This looks transient \u2014 retry in a moment.",
|
|
282677
283091
|
permission: "Your key isn't allowed to do this \u2014 check its scopes or role.",
|
|
@@ -282685,21 +283099,21 @@ function titleForType(type) {
|
|
|
282685
283099
|
if (!spaced) return "Error";
|
|
282686
283100
|
return /error$/i.test(spaced) ? spaced : `${spaced} error`;
|
|
282687
283101
|
}
|
|
282688
|
-
function isStringArray(
|
|
282689
|
-
return Array.isArray(
|
|
283102
|
+
function isStringArray(v2) {
|
|
283103
|
+
return Array.isArray(v2) && v2.every((x2) => typeof x2 === "string");
|
|
282690
283104
|
}
|
|
282691
283105
|
function renderKnownDetails(details, line) {
|
|
282692
283106
|
if (!details) return;
|
|
282693
283107
|
const { retryAfterSeconds, missingIds, requiredCapability, unexecutable, errors } = details;
|
|
282694
|
-
if (typeof retryAfterSeconds === "number") line(` ${
|
|
283108
|
+
if (typeof retryAfterSeconds === "number") line(` ${import_picocolors19.default.dim("retry")} after ${retryAfterSeconds}s`);
|
|
282695
283109
|
if (isStringArray(missingIds) && missingIds.length > 0) {
|
|
282696
283110
|
const shown = missingIds.slice(0, 5).join(", ");
|
|
282697
283111
|
const more = missingIds.length > 5 ? ` (+${missingIds.length - 5} more)` : "";
|
|
282698
|
-
line(` ${
|
|
283112
|
+
line(` ${import_picocolors19.default.dim("missing")} ${shown}${more}`);
|
|
282699
283113
|
}
|
|
282700
|
-
if (typeof requiredCapability === "string") line(` ${
|
|
283114
|
+
if (typeof requiredCapability === "string") line(` ${import_picocolors19.default.dim("needs")} ${requiredCapability}`);
|
|
282701
283115
|
if (Array.isArray(unexecutable) && unexecutable.length > 0) {
|
|
282702
|
-
line(` ${
|
|
283116
|
+
line(` ${import_picocolors19.default.dim("blocked")} ${unexecutable.length} change(s) can't be applied \u2014 see \`unexecutable\` (--verbose)`);
|
|
282703
283117
|
}
|
|
282704
283118
|
if (Array.isArray(errors)) {
|
|
282705
283119
|
for (const e2 of errors.slice(0, 8)) {
|
|
@@ -282707,7 +283121,7 @@ function renderKnownDetails(details, line) {
|
|
|
282707
283121
|
const rec = e2;
|
|
282708
283122
|
const where = typeof rec.param === "string" ? `${rec.param}: ` : "";
|
|
282709
283123
|
const msg = typeof rec.message === "string" ? rec.message : "";
|
|
282710
|
-
if (msg) line(` ${
|
|
283124
|
+
if (msg) line(` ${import_picocolors19.default.dim("\xB7")} ${where}${msg}`);
|
|
282711
283125
|
}
|
|
282712
283126
|
}
|
|
282713
283127
|
}
|
|
@@ -282716,22 +283130,22 @@ function renderCliError(err, opts = {}) {
|
|
|
282716
283130
|
const line = opts.write ?? ((l2) => console.error(l2));
|
|
282717
283131
|
const verbose = opts.verbose ?? (process.argv.includes("--verbose") || process.env.ABLO_VERBOSE === "1");
|
|
282718
283132
|
if (err instanceof AbloError) {
|
|
282719
|
-
const codeTag = err.code ? ` ${
|
|
283133
|
+
const codeTag = err.code ? ` ${import_picocolors19.default.dim(`[${err.code}]`)}` : "";
|
|
282720
283134
|
line("");
|
|
282721
|
-
line(` ${brand("ablo")} ${
|
|
283135
|
+
line(` ${brand("ablo")} ${import_picocolors19.default.red("\u2717")} ${import_picocolors19.default.bold(titleForType(err.type))}${codeTag}`);
|
|
282722
283136
|
line("");
|
|
282723
283137
|
line(` ${err.message}`);
|
|
282724
|
-
if (err.param) line(` ${
|
|
283138
|
+
if (err.param) line(` ${import_picocolors19.default.dim("field")} ${err.param}`);
|
|
282725
283139
|
renderKnownDetails(err.details, line);
|
|
282726
283140
|
const hint = err.code ? RECOVERY_HINT[classifyRecovery(err.code)] : void 0;
|
|
282727
|
-
if (hint) line(` ${
|
|
282728
|
-
if (err.docUrl) line(` ${
|
|
282729
|
-
if (err.requestId) line(` ${
|
|
283141
|
+
if (hint) line(` ${import_picocolors19.default.dim(hint)}`);
|
|
283142
|
+
if (err.docUrl) line(` ${import_picocolors19.default.dim("docs")} ${err.docUrl}`);
|
|
283143
|
+
if (err.requestId) line(` ${import_picocolors19.default.dim("ref")} ${err.requestId}`);
|
|
282730
283144
|
if (verbose) {
|
|
282731
283145
|
if (err.details && Object.keys(err.details).length > 0) {
|
|
282732
|
-
line(` ${
|
|
283146
|
+
line(` ${import_picocolors19.default.dim("details")} ${JSON.stringify(err.details)}`);
|
|
282733
283147
|
}
|
|
282734
|
-
if (err.stack) line(
|
|
283148
|
+
if (err.stack) line(import_picocolors19.default.dim(err.stack));
|
|
282735
283149
|
}
|
|
282736
283150
|
line("");
|
|
282737
283151
|
process.exitCode = 1;
|
|
@@ -282739,16 +283153,16 @@ function renderCliError(err, opts = {}) {
|
|
|
282739
283153
|
}
|
|
282740
283154
|
const message = err instanceof Error ? err.message : String(err);
|
|
282741
283155
|
line("");
|
|
282742
|
-
line(` ${brand("ablo")} ${
|
|
282743
|
-
if (verbose && err instanceof Error && err.stack) line(
|
|
282744
|
-
else line(` ${
|
|
283156
|
+
line(` ${brand("ablo")} ${import_picocolors19.default.red("\u2717")} ${message}`);
|
|
283157
|
+
if (verbose && err instanceof Error && err.stack) line(import_picocolors19.default.dim(err.stack));
|
|
283158
|
+
else line(` ${import_picocolors19.default.dim("Run with --verbose for the full error.")}`);
|
|
282745
283159
|
line("");
|
|
282746
283160
|
process.exitCode = 1;
|
|
282747
283161
|
}
|
|
282748
283162
|
|
|
282749
283163
|
// src/cli/index.ts
|
|
282750
283164
|
var LOGO = `
|
|
282751
|
-
${brand("ablo")} ${
|
|
283165
|
+
${brand("ablo")} ${import_picocolors20.default.dim("sync engine")}
|
|
282752
283166
|
`;
|
|
282753
283167
|
var SUBCOMMAND_USAGE = {
|
|
282754
283168
|
connect: CONNECT_USAGE,
|
|
@@ -282783,7 +283197,7 @@ async function main() {
|
|
|
282783
283197
|
const devArgs = process.argv.slice(3);
|
|
282784
283198
|
const oneShot = devArgs.includes("--no-watch");
|
|
282785
283199
|
console.log(
|
|
282786
|
-
|
|
283200
|
+
import_picocolors20.default.dim(
|
|
282787
283201
|
oneShot ? " `ablo dev --no-watch` is `ablo push` (push once, no watcher) \u2014 running that." : " `ablo dev` is now `ablo push --watch` \u2014 running that."
|
|
282788
283202
|
)
|
|
282789
283203
|
);
|
|
@@ -282805,19 +283219,21 @@ async function main() {
|
|
|
282805
283219
|
await migrate(process.argv.slice(3));
|
|
282806
283220
|
} else if (command === "push") {
|
|
282807
283221
|
const rest = process.argv.slice(3);
|
|
282808
|
-
const advanced = rest.some(
|
|
283222
|
+
const advanced = rest.some(
|
|
283223
|
+
(a) => ["--force", "--rename", "--backfill", "--url", "--dry-run", "--plan", "--yes", "-y", "--allow-dirty"].includes(a)
|
|
283224
|
+
);
|
|
282809
283225
|
const watching = rest.includes("--watch");
|
|
282810
283226
|
const guard = guardActiveProjectKey();
|
|
282811
283227
|
if (!guard.ok && guard.available.length > 0 && !rest.includes("--url")) {
|
|
282812
283228
|
console.error(
|
|
282813
|
-
` ${
|
|
283229
|
+
` ${import_picocolors20.default.yellow("\u26A0")} active project ${import_picocolors20.default.bold(guard.activeProfile)} has no stored key ${import_picocolors20.default.dim(
|
|
282814
283230
|
`(you have keys for: ${guard.available.join(", ")})`
|
|
282815
283231
|
)}`
|
|
282816
283232
|
);
|
|
282817
283233
|
const loginCmd = guard.activeProfile === "default" ? "ablo login" : `ablo login --project ${guard.activeProfile}`;
|
|
282818
283234
|
console.error(
|
|
282819
|
-
|
|
282820
|
-
` Mint one with ${
|
|
283235
|
+
import_picocolors20.default.dim(
|
|
283236
|
+
` Mint one with ${import_picocolors20.default.bold(loginCmd)}, or switch with ${import_picocolors20.default.bold("ablo projects use <slug>")}.`
|
|
282821
283237
|
)
|
|
282822
283238
|
);
|
|
282823
283239
|
process.exitCode = 1;
|
|
@@ -282835,13 +283251,13 @@ async function main() {
|
|
|
282835
283251
|
await generate(process.argv.slice(3));
|
|
282836
283252
|
} else if (command === "schema") {
|
|
282837
283253
|
console.error(
|
|
282838
|
-
` ${
|
|
283254
|
+
` ${import_picocolors20.default.red("\u2717")} \`ablo schema push\` was renamed to \`${brand("ablo push")}\`.`
|
|
282839
283255
|
);
|
|
282840
283256
|
console.error(` Run \`ablo push${process.argv.slice(4).join(" ") ? " " + process.argv.slice(4).join(" ") : ""}\` instead.`);
|
|
282841
283257
|
process.exitCode = 1;
|
|
282842
283258
|
} else {
|
|
282843
283259
|
console.log(LOGO);
|
|
282844
|
-
console.log(` ${
|
|
283260
|
+
console.log(` ${import_picocolors20.default.bold("Usage:")}`);
|
|
282845
283261
|
console.log(` npx ablo init Scaffold ablo/ directory + starter schema`);
|
|
282846
283262
|
console.log(` npx ablo init --yes [--framework nextjs] Non-interactive (agents/CI): no prompts, flag-driven`);
|
|
282847
283263
|
console.log(` [--auth apikey] [--storage direct|endpoint] [--project <slug>] [--no-project]`);
|
|
@@ -282866,6 +283282,7 @@ async function main() {
|
|
|
282866
283282
|
console.log(` npx ablo check Check your existing database fits the schema (read-only, creates no tables)`);
|
|
282867
283283
|
console.log(` npx ablo connect Connect a real database \u2014 prints the logical-replication setup SQL (the one way)`);
|
|
282868
283284
|
console.log(` npx ablo connect --check Validate DATABASE_URL is replication-ready (wal_level, publication, role, replica identity)`);
|
|
283285
|
+
console.log(` npx ablo connect --audit-infra Read-only audit for deprecated Ablo sync infra in a customer DB`);
|
|
282869
283286
|
console.log(` npx ablo migrate Provision your synced-model tables in your own Postgres (optional escape hatch \u2014 \`connect\` is the way)`);
|
|
282870
283287
|
console.log(` npx ablo migrate --dry-run Print the SQL without executing (preview)`);
|
|
282871
283288
|
console.log(` npx ablo push Upload your schema definition to Ablo (metadata only \u2014 rows stay in your DB)`);
|
|
@@ -282876,10 +283293,10 @@ async function main() {
|
|
|
282876
283293
|
console.log(` npx ablo generate Emit TypeScript types from your schema`);
|
|
282877
283294
|
console.log(` npx ablo generate --out path.ts Write generated types to a path`);
|
|
282878
283295
|
console.log();
|
|
282879
|
-
console.log(` ${
|
|
283296
|
+
console.log(` ${import_picocolors20.default.bold("Schema workflow:")}`);
|
|
282880
283297
|
console.log(` The server holds its own copy of your schema \u2014 edit ${brand("ablo/schema.ts")}, then`);
|
|
282881
283298
|
console.log(` run ${brand("ablo push")} (or keep ${brand("ablo dev")} running) before the server will accept`);
|
|
282882
|
-
console.log(` writes to new or changed models. Skip it and writes fail with ${
|
|
283299
|
+
console.log(` writes to new or changed models. Skip it and writes fail with ${import_picocolors20.default.yellow("server_execute_unknown_model")}.`);
|
|
282883
283300
|
console.log();
|
|
282884
283301
|
}
|
|
282885
283302
|
}
|
|
@@ -282891,7 +283308,7 @@ function bailIfCancelled(value) {
|
|
|
282891
283308
|
}
|
|
282892
283309
|
var INIT_FRAMEWORKS = ["nextjs", "vite", "remix", "vanilla"];
|
|
282893
283310
|
var INIT_AUTHS = ["apikey", "firebase", "auth0", "clerk", "supabase", "betterauth", "jwt"];
|
|
282894
|
-
var INIT_STORAGES = ["endpoint", "direct", "datasource"];
|
|
283311
|
+
var INIT_STORAGES = ["replication", "endpoint", "direct", "datasource"];
|
|
282895
283312
|
function parseInitArgs(args) {
|
|
282896
283313
|
const has = (flag2) => args.includes(flag2);
|
|
282897
283314
|
const val = (flag2) => {
|
|
@@ -282930,7 +283347,7 @@ async function ensureInitProject(opts) {
|
|
|
282930
283347
|
const ensured = await ensureProject(slug);
|
|
282931
283348
|
if (ensured) {
|
|
282932
283349
|
console.log(
|
|
282933
|
-
` ${
|
|
283350
|
+
` ${import_picocolors20.default.green("\u2713")} ${ensured.created ? "Created" : "Using"} project ${import_picocolors20.default.bold(ensured.slug)} ${import_picocolors20.default.dim(`(${ensured.id})`)} \u2014 keys you mint for it are isolated from the org's other apps.`
|
|
282934
283351
|
);
|
|
282935
283352
|
}
|
|
282936
283353
|
}
|
|
@@ -282972,7 +283389,7 @@ async function chooseBool(flagValue, fallback, interactive, prompt) {
|
|
|
282972
283389
|
async function init(args = []) {
|
|
282973
283390
|
const opts = parseInitArgs(args);
|
|
282974
283391
|
const interactive = Boolean(process.stdin.isTTY) && !opts.yes && !process.env.CI;
|
|
282975
|
-
Ie(`${brand("ablo")} ${
|
|
283392
|
+
Ie(`${brand("ablo")} ${import_picocolors20.default.dim("sync engine")}`);
|
|
282976
283393
|
if (!(0, import_fs12.existsSync)("package.json")) {
|
|
282977
283394
|
xe("No package.json found. Run this from your project root.");
|
|
282978
283395
|
process.exit(1);
|
|
@@ -283017,16 +283434,16 @@ async function init(args = []) {
|
|
|
283017
283434
|
const storageChoice = await chooseOption(
|
|
283018
283435
|
"storage",
|
|
283019
283436
|
opts.storage,
|
|
283020
|
-
"
|
|
283437
|
+
"replication",
|
|
283021
283438
|
INIT_STORAGES,
|
|
283022
283439
|
false,
|
|
283023
|
-
() => Promise.resolve("
|
|
283440
|
+
() => Promise.resolve("replication")
|
|
283024
283441
|
);
|
|
283025
283442
|
const storage = storageChoice === "datasource" ? "endpoint" : storageChoice;
|
|
283026
283443
|
if (storage === "direct") {
|
|
283027
283444
|
Me(
|
|
283028
|
-
"`--storage direct` uses the deprecated databaseUrl connector.
|
|
283029
|
-
|
|
283445
|
+
"`--storage direct` uses the deprecated databaseUrl connector. Logical replication\n(`npx ablo connect`) is the supported path; a signed Data Source endpoint is the fallback.",
|
|
283446
|
+
import_picocolors20.default.yellow("Deprecated")
|
|
283030
283447
|
);
|
|
283031
283448
|
}
|
|
283032
283449
|
const agent = await chooseBool(
|
|
@@ -283056,7 +283473,7 @@ async function init(args = []) {
|
|
|
283056
283473
|
if (pullExisting) {
|
|
283057
283474
|
const dbUrl = process.env.DATABASE_URL ?? process.env.ABLO_DATABASE_URL;
|
|
283058
283475
|
if (!dbUrl) {
|
|
283059
|
-
schemaNote =
|
|
283476
|
+
schemaNote = import_picocolors20.default.dim(" (no DATABASE_URL \u2014 wrote starter; run `ablo pull` later)");
|
|
283060
283477
|
} else {
|
|
283061
283478
|
try {
|
|
283062
283479
|
const pulled = await buildSchemaSourceFromDb({
|
|
@@ -283066,12 +283483,12 @@ async function init(args = []) {
|
|
|
283066
283483
|
});
|
|
283067
283484
|
if (pulled.models.length > 0) {
|
|
283068
283485
|
schemaSource = pulled.source;
|
|
283069
|
-
schemaNote =
|
|
283486
|
+
schemaNote = import_picocolors20.default.dim(` (pulled ${pulled.models.length} models)`);
|
|
283070
283487
|
} else {
|
|
283071
|
-
schemaNote =
|
|
283488
|
+
schemaNote = import_picocolors20.default.dim(" (no adoptable tables \u2014 wrote starter)");
|
|
283072
283489
|
}
|
|
283073
283490
|
} catch {
|
|
283074
|
-
schemaNote =
|
|
283491
|
+
schemaNote = import_picocolors20.default.dim(" (pull failed \u2014 wrote starter)");
|
|
283075
283492
|
}
|
|
283076
283493
|
}
|
|
283077
283494
|
}
|
|
@@ -283097,14 +283514,14 @@ async function init(args = []) {
|
|
|
283097
283514
|
const existing = (0, import_fs12.readFileSync)(envFile, "utf-8");
|
|
283098
283515
|
if (!existing.includes("ABLO_")) {
|
|
283099
283516
|
(0, import_fs12.writeFileSync)(envFile, existing + "\n" + envBody);
|
|
283100
|
-
created.push(`${envFile} ${
|
|
283517
|
+
created.push(`${envFile} ${import_picocolors20.default.dim("(appended)")}`);
|
|
283101
283518
|
} else {
|
|
283102
|
-
created.push(`${envFile} ${
|
|
283519
|
+
created.push(`${envFile} ${import_picocolors20.default.dim("(already configured)")}`);
|
|
283103
283520
|
}
|
|
283104
283521
|
}
|
|
283105
283522
|
if (wireRealKey && resolvedKey) {
|
|
283106
283523
|
wireEnvLocal(resolvedKey);
|
|
283107
|
-
created.push(`.env.local ${
|
|
283524
|
+
created.push(`.env.local ${import_picocolors20.default.dim("(ABLO_API_KEY set from your login)")}`);
|
|
283108
283525
|
}
|
|
283109
283526
|
if (agent) {
|
|
283110
283527
|
(0, import_fs12.writeFileSync)((0, import_path7.join)(abloDir, "agent.ts"), generateAgent());
|
|
@@ -283119,64 +283536,66 @@ async function init(args = []) {
|
|
|
283119
283536
|
}
|
|
283120
283537
|
const providersPath = (0, import_path7.join)(layout.appBase, "providers.tsx");
|
|
283121
283538
|
(0, import_fs12.writeFileSync)(providersPath, generateProviders());
|
|
283122
|
-
created.push(`${providersPath} ${
|
|
283539
|
+
created.push(`${providersPath} ${import_picocolors20.default.dim(`(wrap ${(0, import_path7.join)(layout.appBase, "layout.tsx")} in <Providers>)`)}`);
|
|
283123
283540
|
const sessionDir = (0, import_path7.join)(layout.appBase, "api", "ablo-session");
|
|
283124
283541
|
(0, import_fs12.mkdirSync)(sessionDir, { recursive: true });
|
|
283125
283542
|
(0, import_fs12.writeFileSync)((0, import_path7.join)(sessionDir, "route.ts"), generateSessionRoute());
|
|
283126
|
-
created.push(`${(0, import_path7.join)(sessionDir, "route.ts")} ${
|
|
283543
|
+
created.push(`${(0, import_path7.join)(sessionDir, "route.ts")} ${import_picocolors20.default.dim("(wire your auth)")}`);
|
|
283127
283544
|
}
|
|
283128
283545
|
if (framework !== "vanilla") {
|
|
283129
283546
|
(0, import_fs12.writeFileSync)((0, import_path7.join)(abloDir, "TaskList.tsx"), generateComponent());
|
|
283130
283547
|
created.push(`${abloDir}/TaskList.tsx`);
|
|
283131
283548
|
}
|
|
283132
|
-
Me(created.map((f) => `${
|
|
283549
|
+
Me(created.map((f) => `${import_picocolors20.default.green("\u2713")} ${f}`).join("\n"), "Created");
|
|
283133
283550
|
const pm = detectPackageManager();
|
|
283134
283551
|
if (opts.install) {
|
|
283135
283552
|
const s = Y2();
|
|
283136
283553
|
s.start("Installing @abloatai/ablo");
|
|
283137
283554
|
try {
|
|
283138
|
-
(0,
|
|
283555
|
+
(0, import_child_process3.execSync)(`${pm} add @abloatai/ablo`, { stdio: "ignore" });
|
|
283139
283556
|
s.stop("Installed @abloatai/ablo");
|
|
283140
283557
|
} catch {
|
|
283141
|
-
s.stop(`${
|
|
283558
|
+
s.stop(`${import_picocolors20.default.yellow("!")} Couldn't auto-install \u2014 run ${import_picocolors20.default.bold(`${pm} install @abloatai/ablo`)}`);
|
|
283142
283559
|
}
|
|
283143
283560
|
}
|
|
283144
283561
|
const steps = [
|
|
283145
|
-
`Get a ${
|
|
283146
|
-
`Run ${
|
|
283147
|
-
`Set ${
|
|
283148
|
-
`Run ${
|
|
283149
|
-
...storage === "
|
|
283150
|
-
`
|
|
283562
|
+
`Get a ${import_picocolors20.default.bold("sk_test_")} key at ${import_picocolors20.default.cyan("https://abloatai.com")}`,
|
|
283563
|
+
`Run ${import_picocolors20.default.bold("npx ablo login")} (or add ${import_picocolors20.default.bold("ABLO_API_KEY")} to ${import_picocolors20.default.bold(envFile)})`,
|
|
283564
|
+
`Set ${import_picocolors20.default.bold("DATABASE_URL")} in ${import_picocolors20.default.bold(envFile)} \u2014 your Postgres is the system of record; rows live there, never with Ablo`,
|
|
283565
|
+
`Run ${import_picocolors20.default.bold("npx ablo dev")} \u2014 pushes your schema definition and watches for changes`,
|
|
283566
|
+
...storage === "replication" ? [
|
|
283567
|
+
`Connect your database: ${import_picocolors20.default.bold("npx ablo connect")} prints the logical-replication setup SQL (run it once on your Postgres), then ${import_picocolors20.default.bold("npx ablo connect --register")} tells Ablo to replicate it \u2014 your app keeps writing through your own backend, Ablo tails the WAL`
|
|
283568
|
+
] : storage === "direct" ? [
|
|
283569
|
+
`Provision your DB: ${import_picocolors20.default.bold("npx ablo migrate")} (creates your synced-model tables with row-level security; keep your own migrations for everything else)`
|
|
283151
283570
|
] : [
|
|
283152
|
-
`Provision your DB: ${
|
|
283571
|
+
`Provision your DB: ${import_picocolors20.default.bold("npx ablo migrate")} (creates your Ablo-model tables + the adapter tables; keep your own migrations for everything else), then mount ${import_picocolors20.default.bold(`${abloDir}/data-source.ts`)} at ${import_picocolors20.default.bold("/api/ablo/source")}`
|
|
283153
283572
|
],
|
|
283154
283573
|
...framework === "nextjs" ? [
|
|
283155
|
-
`Wrap ${
|
|
283574
|
+
`Wrap ${import_picocolors20.default.bold((0, import_path7.join)(layout.appBase, "layout.tsx"))} in ${import_picocolors20.default.bold("<Providers>")} (${(0, import_path7.join)(layout.appBase, "providers.tsx")}) and add your auth to ${import_picocolors20.default.bold((0, import_path7.join)(layout.appBase, "api", "ablo-session", "route.ts"))}`
|
|
283156
283575
|
] : [],
|
|
283157
|
-
`Run ${
|
|
283576
|
+
`Run ${import_picocolors20.default.bold(`${pm} run dev`)} and open two browser tabs \u2014 changes sync in real-time`,
|
|
283158
283577
|
...agent ? [
|
|
283159
|
-
`Run ${
|
|
283160
|
-
`Run ${
|
|
283578
|
+
`Run ${import_picocolors20.default.bold(`npx tsx ${abloDir}/agent.ts`)} \u2014 an AI teammate edits the same tasks`,
|
|
283579
|
+
`Run ${import_picocolors20.default.bold("npx ablo logs")} to watch human + agent commits stream by`
|
|
283161
283580
|
] : []
|
|
283162
283581
|
];
|
|
283163
283582
|
Me(steps.map((s, i) => `${i + 1}. ${s}`).join("\n"), "Next steps");
|
|
283164
283583
|
const existingKey = resolveApiKey("sandbox");
|
|
283165
283584
|
if (existingKey) {
|
|
283166
283585
|
await ensureInitProject(opts);
|
|
283167
|
-
Se(`Already authorized ${
|
|
283586
|
+
Se(`Already authorized ${import_picocolors20.default.dim(`(${existingKey.slice(0, 11)}\u2026)`)} \u2014 run ${import_picocolors20.default.bold("npx ablo push")} next. ${import_picocolors20.default.dim("Docs:")} https://abloatai.com/docs`);
|
|
283168
283587
|
return;
|
|
283169
283588
|
}
|
|
283170
283589
|
if (interactive && opts.login) {
|
|
283171
283590
|
const loginNow = await ye({ message: "Log in now? (opens your browser)", initialValue: true });
|
|
283172
283591
|
if (!pD(loginNow) && loginNow) {
|
|
283173
|
-
Se(`${
|
|
283592
|
+
Se(`${import_picocolors20.default.dim("Docs:")} https://abloatai.com/docs`);
|
|
283174
283593
|
await login();
|
|
283175
283594
|
await ensureInitProject(opts);
|
|
283176
283595
|
return;
|
|
283177
283596
|
}
|
|
283178
283597
|
}
|
|
283179
|
-
Se(`Run ${
|
|
283598
|
+
Se(`Run ${import_picocolors20.default.bold("npx ablo login")} when ready. ${import_picocolors20.default.dim("Docs:")} https://abloatai.com/docs`);
|
|
283180
283599
|
}
|
|
283181
283600
|
function generateSchema() {
|
|
283182
283601
|
return `import { defineSchema, model, relation, z } from '@abloatai/ablo/schema';
|
|
@@ -283251,7 +283670,7 @@ export {};
|
|
|
283251
283670
|
}
|
|
283252
283671
|
function generateEnv(storage, opts = {}) {
|
|
283253
283672
|
const { includeApiKey = true } = opts;
|
|
283254
|
-
const databaseBlock = storage === "direct" ? "# DEPRECATED direct connector. The client registers this connection (sent once\n# over TLS, stored sealed) so Ablo dials into your Postgres. Prefer
|
|
283673
|
+
const databaseBlock = storage === "direct" ? "# DEPRECATED direct connector. The client registers this connection (sent once\n# over TLS, stored sealed) so Ablo dials into your Postgres. Prefer logical\n# replication (`npx ablo connect`); to keep the transaction log in your infra too,\n# self-host the engine. Use a dedicated non-superuser role; the browser never sees this.\nDATABASE_URL=postgres://user:password@host:5432/db\n" : storage === "replication" ? "# Used by `npx ablo connect` to set up + register logical replication \u2014 the\n# DIRECT (un-pooled) endpoint. Ablo TAILS your WAL from here; it never writes.\n# The client never sees it; the browser never sees it. Your DB stays yours.\nDATABASE_URL=postgres://user:password@host:5432/db\n" : "# Used by ablo/data-source.ts (your DB endpoint) + `ablo migrate` \u2014 NOT the client.\n# Ablo never sees it; the browser never sees it. Your DB stays in your app.\nDATABASE_URL=postgres://user:password@host:5432/db\n";
|
|
283255
283674
|
const webhookBlock = storage === "endpoint" ? "# Signing secret for the webhook receiver (app/api/ablo/webhooks/route.ts).\n# Ablo mints this when you register the endpoint's URL (POST /v1/webhook_endpoints\n# or the dashboard) and returns it once \u2014 paste it here.\nABLO_WEBHOOK_SECRET=whsec_your_endpoint_secret_here\n" : "";
|
|
283256
283675
|
const apiKeyBlock = includeApiKey ? "# Ablo Sync Engine \u2014 use a sk_test_ key for local dev (`npx ablo push`)\nABLO_API_KEY=sk_test_your_key_here\n" : "";
|
|
283257
283676
|
return `${apiKeyBlock}${webhookBlock}${databaseBlock}`;
|