postgresai 0.14.0-beta.11 → 0.14.0-beta.13
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/README.md +32 -0
- package/bin/postgres-ai.ts +928 -170
- package/dist/bin/postgres-ai.js +2252 -493
- package/lib/checkup.ts +69 -3
- package/lib/init.ts +76 -19
- package/lib/issues.ts +453 -7
- package/lib/mcp-server.ts +180 -3
- package/lib/metrics-embedded.ts +3 -3
- package/lib/supabase.ts +824 -0
- package/package.json +1 -1
- package/test/checkup.test.ts +240 -14
- package/test/config-consistency.test.ts +36 -0
- package/test/init.integration.test.ts +80 -71
- package/test/init.test.ts +266 -1
- package/test/issues.cli.test.ts +224 -0
- package/test/mcp-server.test.ts +551 -12
- package/test/supabase.test.ts +568 -0
- package/test/test-utils.ts +6 -0
package/dist/bin/postgres-ai.js
CHANGED
|
@@ -29,7 +29,7 @@ var __export = (target, all) => {
|
|
|
29
29
|
};
|
|
30
30
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
31
31
|
|
|
32
|
-
//
|
|
32
|
+
// node_modules/commander/lib/error.js
|
|
33
33
|
var require_error = __commonJS((exports) => {
|
|
34
34
|
class CommanderError extends Error {
|
|
35
35
|
constructor(exitCode, code, message) {
|
|
@@ -53,7 +53,7 @@ var require_error = __commonJS((exports) => {
|
|
|
53
53
|
exports.InvalidArgumentError = InvalidArgumentError;
|
|
54
54
|
});
|
|
55
55
|
|
|
56
|
-
//
|
|
56
|
+
// node_modules/commander/lib/argument.js
|
|
57
57
|
var require_argument = __commonJS((exports) => {
|
|
58
58
|
var { InvalidArgumentError } = require_error();
|
|
59
59
|
|
|
@@ -132,7 +132,7 @@ var require_argument = __commonJS((exports) => {
|
|
|
132
132
|
exports.humanReadableArgName = humanReadableArgName;
|
|
133
133
|
});
|
|
134
134
|
|
|
135
|
-
//
|
|
135
|
+
// node_modules/commander/lib/help.js
|
|
136
136
|
var require_help = __commonJS((exports) => {
|
|
137
137
|
var { humanReadableArgName } = require_argument();
|
|
138
138
|
|
|
@@ -381,7 +381,7 @@ var require_help = __commonJS((exports) => {
|
|
|
381
381
|
exports.Help = Help;
|
|
382
382
|
});
|
|
383
383
|
|
|
384
|
-
//
|
|
384
|
+
// node_modules/commander/lib/option.js
|
|
385
385
|
var require_option = __commonJS((exports) => {
|
|
386
386
|
var { InvalidArgumentError } = require_error();
|
|
387
387
|
|
|
@@ -532,7 +532,7 @@ var require_option = __commonJS((exports) => {
|
|
|
532
532
|
exports.DualOptions = DualOptions;
|
|
533
533
|
});
|
|
534
534
|
|
|
535
|
-
//
|
|
535
|
+
// node_modules/commander/lib/suggestSimilar.js
|
|
536
536
|
var require_suggestSimilar = __commonJS((exports) => {
|
|
537
537
|
var maxDistance = 3;
|
|
538
538
|
function editDistance(a, b) {
|
|
@@ -605,7 +605,7 @@ var require_suggestSimilar = __commonJS((exports) => {
|
|
|
605
605
|
exports.suggestSimilar = suggestSimilar;
|
|
606
606
|
});
|
|
607
607
|
|
|
608
|
-
//
|
|
608
|
+
// node_modules/commander/lib/command.js
|
|
609
609
|
var require_command = __commonJS((exports) => {
|
|
610
610
|
var EventEmitter = __require("node:events").EventEmitter;
|
|
611
611
|
var childProcess = __require("node:child_process");
|
|
@@ -1848,7 +1848,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1848
1848
|
exports.Command = Command;
|
|
1849
1849
|
});
|
|
1850
1850
|
|
|
1851
|
-
//
|
|
1851
|
+
// node_modules/commander/index.js
|
|
1852
1852
|
var require_commander = __commonJS((exports) => {
|
|
1853
1853
|
var { Argument } = require_argument();
|
|
1854
1854
|
var { Command } = require_command();
|
|
@@ -1868,7 +1868,7 @@ var require_commander = __commonJS((exports) => {
|
|
|
1868
1868
|
exports.InvalidOptionArgumentError = InvalidArgumentError;
|
|
1869
1869
|
});
|
|
1870
1870
|
|
|
1871
|
-
//
|
|
1871
|
+
// node_modules/postgres-array/index.js
|
|
1872
1872
|
var require_postgres_array = __commonJS((exports) => {
|
|
1873
1873
|
exports.parse = function(source, transform) {
|
|
1874
1874
|
return new ArrayParser(source, transform).parse();
|
|
@@ -1964,7 +1964,7 @@ var require_postgres_array = __commonJS((exports) => {
|
|
|
1964
1964
|
}
|
|
1965
1965
|
});
|
|
1966
1966
|
|
|
1967
|
-
//
|
|
1967
|
+
// node_modules/pg-types/lib/arrayParser.js
|
|
1968
1968
|
var require_arrayParser = __commonJS((exports, module) => {
|
|
1969
1969
|
var array = require_postgres_array();
|
|
1970
1970
|
module.exports = {
|
|
@@ -1978,7 +1978,7 @@ var require_arrayParser = __commonJS((exports, module) => {
|
|
|
1978
1978
|
};
|
|
1979
1979
|
});
|
|
1980
1980
|
|
|
1981
|
-
//
|
|
1981
|
+
// node_modules/postgres-date/index.js
|
|
1982
1982
|
var require_postgres_date = __commonJS((exports, module) => {
|
|
1983
1983
|
var DATE_TIME = /(\d{1,})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})(\.\d{1,})?.*?( BC)?$/;
|
|
1984
1984
|
var DATE = /^(\d{1,})-(\d{2})-(\d{2})( BC)?$/;
|
|
@@ -2063,7 +2063,7 @@ var require_postgres_date = __commonJS((exports, module) => {
|
|
|
2063
2063
|
}
|
|
2064
2064
|
});
|
|
2065
2065
|
|
|
2066
|
-
//
|
|
2066
|
+
// node_modules/xtend/mutable.js
|
|
2067
2067
|
var require_mutable = __commonJS((exports, module) => {
|
|
2068
2068
|
module.exports = extend3;
|
|
2069
2069
|
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
@@ -2080,7 +2080,7 @@ var require_mutable = __commonJS((exports, module) => {
|
|
|
2080
2080
|
}
|
|
2081
2081
|
});
|
|
2082
2082
|
|
|
2083
|
-
//
|
|
2083
|
+
// node_modules/postgres-interval/index.js
|
|
2084
2084
|
var require_postgres_interval = __commonJS((exports, module) => {
|
|
2085
2085
|
var extend3 = require_mutable();
|
|
2086
2086
|
module.exports = PostgresInterval;
|
|
@@ -2172,12 +2172,11 @@ var require_postgres_interval = __commonJS((exports, module) => {
|
|
|
2172
2172
|
}
|
|
2173
2173
|
});
|
|
2174
2174
|
|
|
2175
|
-
//
|
|
2175
|
+
// node_modules/postgres-bytea/index.js
|
|
2176
2176
|
var require_postgres_bytea = __commonJS((exports, module) => {
|
|
2177
|
-
var bufferFrom = Buffer.from || Buffer;
|
|
2178
2177
|
module.exports = function parseBytea(input) {
|
|
2179
2178
|
if (/^\\x/.test(input)) {
|
|
2180
|
-
return
|
|
2179
|
+
return new Buffer(input.substr(2), "hex");
|
|
2181
2180
|
}
|
|
2182
2181
|
var output = "";
|
|
2183
2182
|
var i2 = 0;
|
|
@@ -2201,11 +2200,11 @@ var require_postgres_bytea = __commonJS((exports, module) => {
|
|
|
2201
2200
|
}
|
|
2202
2201
|
}
|
|
2203
2202
|
}
|
|
2204
|
-
return
|
|
2203
|
+
return new Buffer(output, "binary");
|
|
2205
2204
|
};
|
|
2206
2205
|
});
|
|
2207
2206
|
|
|
2208
|
-
//
|
|
2207
|
+
// node_modules/pg-types/lib/textParsers.js
|
|
2209
2208
|
var require_textParsers = __commonJS((exports, module) => {
|
|
2210
2209
|
var array = require_postgres_array();
|
|
2211
2210
|
var arrayParser = require_arrayParser();
|
|
@@ -2408,7 +2407,7 @@ var require_textParsers = __commonJS((exports, module) => {
|
|
|
2408
2407
|
};
|
|
2409
2408
|
});
|
|
2410
2409
|
|
|
2411
|
-
//
|
|
2410
|
+
// node_modules/pg-int8/index.js
|
|
2412
2411
|
var require_pg_int8 = __commonJS((exports, module) => {
|
|
2413
2412
|
var BASE = 1e6;
|
|
2414
2413
|
function readInt8(buffer) {
|
|
@@ -2485,7 +2484,7 @@ var require_pg_int8 = __commonJS((exports, module) => {
|
|
|
2485
2484
|
module.exports = readInt8;
|
|
2486
2485
|
});
|
|
2487
2486
|
|
|
2488
|
-
//
|
|
2487
|
+
// node_modules/pg-types/lib/binaryParsers.js
|
|
2489
2488
|
var require_binaryParsers = __commonJS((exports, module) => {
|
|
2490
2489
|
var parseInt64 = require_pg_int8();
|
|
2491
2490
|
var parseBits = function(data, bits, offset, invert, callback) {
|
|
@@ -2684,7 +2683,7 @@ var require_binaryParsers = __commonJS((exports, module) => {
|
|
|
2684
2683
|
};
|
|
2685
2684
|
});
|
|
2686
2685
|
|
|
2687
|
-
//
|
|
2686
|
+
// node_modules/pg-types/lib/builtins.js
|
|
2688
2687
|
var require_builtins = __commonJS((exports, module) => {
|
|
2689
2688
|
module.exports = {
|
|
2690
2689
|
BOOL: 16,
|
|
@@ -2750,7 +2749,7 @@ var require_builtins = __commonJS((exports, module) => {
|
|
|
2750
2749
|
};
|
|
2751
2750
|
});
|
|
2752
2751
|
|
|
2753
|
-
//
|
|
2752
|
+
// node_modules/pg-types/index.js
|
|
2754
2753
|
var require_pg_types = __commonJS((exports) => {
|
|
2755
2754
|
var textParsers = require_textParsers();
|
|
2756
2755
|
var binaryParsers = require_binaryParsers();
|
|
@@ -2789,7 +2788,7 @@ var require_pg_types = __commonJS((exports) => {
|
|
|
2789
2788
|
});
|
|
2790
2789
|
});
|
|
2791
2790
|
|
|
2792
|
-
//
|
|
2791
|
+
// node_modules/pg/lib/defaults.js
|
|
2793
2792
|
var require_defaults = __commonJS((exports, module) => {
|
|
2794
2793
|
module.exports = {
|
|
2795
2794
|
host: "localhost",
|
|
@@ -2825,7 +2824,7 @@ var require_defaults = __commonJS((exports, module) => {
|
|
|
2825
2824
|
});
|
|
2826
2825
|
});
|
|
2827
2826
|
|
|
2828
|
-
//
|
|
2827
|
+
// node_modules/pg/lib/utils.js
|
|
2829
2828
|
var require_utils = __commonJS((exports, module) => {
|
|
2830
2829
|
var defaults = require_defaults();
|
|
2831
2830
|
var util = __require("util");
|
|
@@ -2984,7 +2983,7 @@ var require_utils = __commonJS((exports, module) => {
|
|
|
2984
2983
|
};
|
|
2985
2984
|
});
|
|
2986
2985
|
|
|
2987
|
-
//
|
|
2986
|
+
// node_modules/pg/lib/crypto/utils-legacy.js
|
|
2988
2987
|
var require_utils_legacy = __commonJS((exports, module) => {
|
|
2989
2988
|
var nodeCrypto = __require("crypto");
|
|
2990
2989
|
function md5(string) {
|
|
@@ -3019,7 +3018,7 @@ var require_utils_legacy = __commonJS((exports, module) => {
|
|
|
3019
3018
|
};
|
|
3020
3019
|
});
|
|
3021
3020
|
|
|
3022
|
-
//
|
|
3021
|
+
// node_modules/pg/lib/crypto/utils-webcrypto.js
|
|
3023
3022
|
var require_utils_webcrypto = __commonJS((exports, module) => {
|
|
3024
3023
|
var nodeCrypto = __require("crypto");
|
|
3025
3024
|
module.exports = {
|
|
@@ -3068,7 +3067,7 @@ var require_utils_webcrypto = __commonJS((exports, module) => {
|
|
|
3068
3067
|
}
|
|
3069
3068
|
});
|
|
3070
3069
|
|
|
3071
|
-
//
|
|
3070
|
+
// node_modules/pg/lib/crypto/utils.js
|
|
3072
3071
|
var require_utils2 = __commonJS((exports, module) => {
|
|
3073
3072
|
var useLegacyCrypto = parseInt(process.versions && process.versions.node && process.versions.node.split(".")[0]) < 15;
|
|
3074
3073
|
if (useLegacyCrypto) {
|
|
@@ -3078,7 +3077,7 @@ var require_utils2 = __commonJS((exports, module) => {
|
|
|
3078
3077
|
}
|
|
3079
3078
|
});
|
|
3080
3079
|
|
|
3081
|
-
//
|
|
3080
|
+
// node_modules/pg/lib/crypto/cert-signatures.js
|
|
3082
3081
|
var require_cert_signatures = __commonJS((exports, module) => {
|
|
3083
3082
|
function x509Error(msg, cert) {
|
|
3084
3083
|
return new Error("SASL channel binding: " + msg + " when parsing public certificate " + cert.toString("base64"));
|
|
@@ -3190,7 +3189,7 @@ var require_cert_signatures = __commonJS((exports, module) => {
|
|
|
3190
3189
|
module.exports = { signatureAlgorithmHashFromCertificate };
|
|
3191
3190
|
});
|
|
3192
3191
|
|
|
3193
|
-
//
|
|
3192
|
+
// node_modules/pg/lib/crypto/sasl.js
|
|
3194
3193
|
var require_sasl = __commonJS((exports, module) => {
|
|
3195
3194
|
var crypto = require_utils2();
|
|
3196
3195
|
var { signatureAlgorithmHashFromCertificate } = require_cert_signatures();
|
|
@@ -3354,7 +3353,7 @@ var require_sasl = __commonJS((exports, module) => {
|
|
|
3354
3353
|
};
|
|
3355
3354
|
});
|
|
3356
3355
|
|
|
3357
|
-
//
|
|
3356
|
+
// node_modules/pg/lib/type-overrides.js
|
|
3358
3357
|
var require_type_overrides = __commonJS((exports, module) => {
|
|
3359
3358
|
var types = require_pg_types();
|
|
3360
3359
|
function TypeOverrides(userTypes) {
|
|
@@ -3386,7 +3385,7 @@ var require_type_overrides = __commonJS((exports, module) => {
|
|
|
3386
3385
|
module.exports = TypeOverrides;
|
|
3387
3386
|
});
|
|
3388
3387
|
|
|
3389
|
-
//
|
|
3388
|
+
// node_modules/pg-connection-string/index.js
|
|
3390
3389
|
var require_pg_connection_string = __commonJS((exports, module) => {
|
|
3391
3390
|
function parse(str2, options = {}) {
|
|
3392
3391
|
if (str2.charAt(0) === "/") {
|
|
@@ -3547,7 +3546,7 @@ var require_pg_connection_string = __commonJS((exports, module) => {
|
|
|
3547
3546
|
parse.parseIntoClientConfig = parseIntoClientConfig;
|
|
3548
3547
|
});
|
|
3549
3548
|
|
|
3550
|
-
//
|
|
3549
|
+
// node_modules/pg/lib/connection-parameters.js
|
|
3551
3550
|
var require_connection_parameters = __commonJS((exports, module) => {
|
|
3552
3551
|
var dns = __require("dns");
|
|
3553
3552
|
var defaults = require_defaults();
|
|
@@ -3683,7 +3682,7 @@ var require_connection_parameters = __commonJS((exports, module) => {
|
|
|
3683
3682
|
module.exports = ConnectionParameters;
|
|
3684
3683
|
});
|
|
3685
3684
|
|
|
3686
|
-
//
|
|
3685
|
+
// node_modules/pg/lib/result.js
|
|
3687
3686
|
var require_result = __commonJS((exports, module) => {
|
|
3688
3687
|
var types = require_pg_types();
|
|
3689
3688
|
var matchRegexp = /^([A-Za-z]+)(?: (\d+))?(?: (\d+))?/;
|
|
@@ -3771,7 +3770,7 @@ var require_result = __commonJS((exports, module) => {
|
|
|
3771
3770
|
module.exports = Result;
|
|
3772
3771
|
});
|
|
3773
3772
|
|
|
3774
|
-
//
|
|
3773
|
+
// node_modules/pg/lib/query.js
|
|
3775
3774
|
var require_query = __commonJS((exports, module) => {
|
|
3776
3775
|
var { EventEmitter } = __require("events");
|
|
3777
3776
|
var Result = require_result();
|
|
@@ -3957,7 +3956,7 @@ var require_query = __commonJS((exports, module) => {
|
|
|
3957
3956
|
module.exports = Query;
|
|
3958
3957
|
});
|
|
3959
3958
|
|
|
3960
|
-
//
|
|
3959
|
+
// node_modules/pg-protocol/dist/messages.js
|
|
3961
3960
|
var require_messages = __commonJS((exports) => {
|
|
3962
3961
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3963
3962
|
exports.NoticeMessage = exports.DataRowMessage = exports.CommandCompleteMessage = exports.ReadyForQueryMessage = exports.NotificationResponseMessage = exports.BackendKeyDataMessage = exports.AuthenticationMD5Password = exports.ParameterStatusMessage = exports.ParameterDescriptionMessage = exports.RowDescriptionMessage = exports.Field = exports.CopyResponse = exports.CopyDataMessage = exports.DatabaseError = exports.copyDone = exports.emptyQuery = exports.replicationStart = exports.portalSuspended = exports.noData = exports.closeComplete = exports.bindComplete = exports.parseComplete = undefined;
|
|
@@ -4133,7 +4132,7 @@ var require_messages = __commonJS((exports) => {
|
|
|
4133
4132
|
exports.NoticeMessage = NoticeMessage;
|
|
4134
4133
|
});
|
|
4135
4134
|
|
|
4136
|
-
//
|
|
4135
|
+
// node_modules/pg-protocol/dist/buffer-writer.js
|
|
4137
4136
|
var require_buffer_writer = __commonJS((exports) => {
|
|
4138
4137
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4139
4138
|
exports.Writer = undefined;
|
|
@@ -4212,7 +4211,7 @@ var require_buffer_writer = __commonJS((exports) => {
|
|
|
4212
4211
|
exports.Writer = Writer;
|
|
4213
4212
|
});
|
|
4214
4213
|
|
|
4215
|
-
//
|
|
4214
|
+
// node_modules/pg-protocol/dist/serializer.js
|
|
4216
4215
|
var require_serializer = __commonJS((exports) => {
|
|
4217
4216
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4218
4217
|
exports.serialize = undefined;
|
|
@@ -4375,7 +4374,7 @@ var require_serializer = __commonJS((exports) => {
|
|
|
4375
4374
|
exports.serialize = serialize;
|
|
4376
4375
|
});
|
|
4377
4376
|
|
|
4378
|
-
//
|
|
4377
|
+
// node_modules/pg-protocol/dist/buffer-reader.js
|
|
4379
4378
|
var require_buffer_reader = __commonJS((exports) => {
|
|
4380
4379
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4381
4380
|
exports.BufferReader = undefined;
|
|
@@ -4432,7 +4431,7 @@ var require_buffer_reader = __commonJS((exports) => {
|
|
|
4432
4431
|
exports.BufferReader = BufferReader;
|
|
4433
4432
|
});
|
|
4434
4433
|
|
|
4435
|
-
//
|
|
4434
|
+
// node_modules/pg-protocol/dist/parser.js
|
|
4436
4435
|
var require_parser = __commonJS((exports) => {
|
|
4437
4436
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4438
4437
|
exports.Parser = undefined;
|
|
@@ -4723,7 +4722,7 @@ var require_parser = __commonJS((exports) => {
|
|
|
4723
4722
|
exports.Parser = Parser;
|
|
4724
4723
|
});
|
|
4725
4724
|
|
|
4726
|
-
//
|
|
4725
|
+
// node_modules/pg-protocol/dist/index.js
|
|
4727
4726
|
var require_dist = __commonJS((exports) => {
|
|
4728
4727
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4729
4728
|
exports.DatabaseError = exports.serialize = exports.parse = undefined;
|
|
@@ -4744,13 +4743,13 @@ var require_dist = __commonJS((exports) => {
|
|
|
4744
4743
|
exports.parse = parse;
|
|
4745
4744
|
});
|
|
4746
4745
|
|
|
4747
|
-
//
|
|
4746
|
+
// node_modules/pg-cloudflare/dist/empty.js
|
|
4748
4747
|
var require_empty = __commonJS((exports) => {
|
|
4749
4748
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4750
4749
|
exports.default = {};
|
|
4751
4750
|
});
|
|
4752
4751
|
|
|
4753
|
-
//
|
|
4752
|
+
// node_modules/pg/lib/stream.js
|
|
4754
4753
|
var require_stream = __commonJS((exports, module) => {
|
|
4755
4754
|
var { getStream, getSecureStream } = getStreamFuncs();
|
|
4756
4755
|
module.exports = {
|
|
@@ -4805,7 +4804,7 @@ var require_stream = __commonJS((exports, module) => {
|
|
|
4805
4804
|
}
|
|
4806
4805
|
});
|
|
4807
4806
|
|
|
4808
|
-
//
|
|
4807
|
+
// node_modules/pg/lib/connection.js
|
|
4809
4808
|
var require_connection = __commonJS((exports, module) => {
|
|
4810
4809
|
var EventEmitter = __require("events").EventEmitter;
|
|
4811
4810
|
var { parse, serialize } = require_dist();
|
|
@@ -4984,7 +4983,7 @@ var require_connection = __commonJS((exports, module) => {
|
|
|
4984
4983
|
module.exports = Connection;
|
|
4985
4984
|
});
|
|
4986
4985
|
|
|
4987
|
-
//
|
|
4986
|
+
// node_modules/split2/index.js
|
|
4988
4987
|
var require_split2 = __commonJS((exports, module) => {
|
|
4989
4988
|
var { Transform } = __require("stream");
|
|
4990
4989
|
var { StringDecoder } = __require("string_decoder");
|
|
@@ -5083,7 +5082,7 @@ var require_split2 = __commonJS((exports, module) => {
|
|
|
5083
5082
|
module.exports = split;
|
|
5084
5083
|
});
|
|
5085
5084
|
|
|
5086
|
-
//
|
|
5085
|
+
// node_modules/pgpass/lib/helper.js
|
|
5087
5086
|
var require_helper = __commonJS((exports, module) => {
|
|
5088
5087
|
var path2 = __require("path");
|
|
5089
5088
|
var Stream = __require("stream").Stream;
|
|
@@ -5247,7 +5246,7 @@ var require_helper = __commonJS((exports, module) => {
|
|
|
5247
5246
|
};
|
|
5248
5247
|
});
|
|
5249
5248
|
|
|
5250
|
-
//
|
|
5249
|
+
// node_modules/pgpass/lib/index.js
|
|
5251
5250
|
var require_lib = __commonJS((exports, module) => {
|
|
5252
5251
|
var path2 = __require("path");
|
|
5253
5252
|
var fs2 = __require("fs");
|
|
@@ -5265,7 +5264,7 @@ var require_lib = __commonJS((exports, module) => {
|
|
|
5265
5264
|
module.exports.warnTo = helper.warnTo;
|
|
5266
5265
|
});
|
|
5267
5266
|
|
|
5268
|
-
//
|
|
5267
|
+
// node_modules/pg/lib/client.js
|
|
5269
5268
|
var require_client = __commonJS((exports, module) => {
|
|
5270
5269
|
var EventEmitter = __require("events").EventEmitter;
|
|
5271
5270
|
var utils = require_utils();
|
|
@@ -5773,7 +5772,7 @@ var require_client = __commonJS((exports, module) => {
|
|
|
5773
5772
|
module.exports = Client;
|
|
5774
5773
|
});
|
|
5775
5774
|
|
|
5776
|
-
//
|
|
5775
|
+
// node_modules/pg-pool/index.js
|
|
5777
5776
|
var require_pg_pool = __commonJS((exports, module) => {
|
|
5778
5777
|
var EventEmitter = __require("events").EventEmitter;
|
|
5779
5778
|
var NOOP = function() {};
|
|
@@ -6153,7 +6152,7 @@ var require_pg_pool = __commonJS((exports, module) => {
|
|
|
6153
6152
|
module.exports = Pool;
|
|
6154
6153
|
});
|
|
6155
6154
|
|
|
6156
|
-
//
|
|
6155
|
+
// node_modules/pg/lib/native/query.js
|
|
6157
6156
|
var require_query2 = __commonJS((exports, module) => {
|
|
6158
6157
|
var EventEmitter = __require("events").EventEmitter;
|
|
6159
6158
|
var util = __require("util");
|
|
@@ -6289,7 +6288,7 @@ var require_query2 = __commonJS((exports, module) => {
|
|
|
6289
6288
|
};
|
|
6290
6289
|
});
|
|
6291
6290
|
|
|
6292
|
-
//
|
|
6291
|
+
// node_modules/pg/lib/native/client.js
|
|
6293
6292
|
var require_client2 = __commonJS((exports, module) => {
|
|
6294
6293
|
var Native;
|
|
6295
6294
|
try {
|
|
@@ -6526,7 +6525,7 @@ var require_client2 = __commonJS((exports, module) => {
|
|
|
6526
6525
|
};
|
|
6527
6526
|
});
|
|
6528
6527
|
|
|
6529
|
-
//
|
|
6528
|
+
// node_modules/pg/lib/index.js
|
|
6530
6529
|
var require_lib2 = __commonJS((exports, module) => {
|
|
6531
6530
|
var Client = require_client();
|
|
6532
6531
|
var defaults = require_defaults();
|
|
@@ -6584,7 +6583,7 @@ var require_lib2 = __commonJS((exports, module) => {
|
|
|
6584
6583
|
}
|
|
6585
6584
|
});
|
|
6586
6585
|
|
|
6587
|
-
//
|
|
6586
|
+
// node_modules/ajv/dist/compile/codegen/code.js
|
|
6588
6587
|
var require_code = __commonJS((exports) => {
|
|
6589
6588
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6590
6589
|
exports.regexpCode = exports.getEsmExportName = exports.getProperty = exports.safeStringify = exports.stringify = exports.strConcat = exports.addCodeArg = exports.str = exports._ = exports.nil = exports._Code = exports.Name = exports.IDENTIFIER = exports._CodeOrName = undefined;
|
|
@@ -6738,7 +6737,7 @@ var require_code = __commonJS((exports) => {
|
|
|
6738
6737
|
exports.regexpCode = regexpCode;
|
|
6739
6738
|
});
|
|
6740
6739
|
|
|
6741
|
-
//
|
|
6740
|
+
// node_modules/ajv/dist/compile/codegen/scope.js
|
|
6742
6741
|
var require_scope = __commonJS((exports) => {
|
|
6743
6742
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6744
6743
|
exports.ValueScope = exports.ValueScopeName = exports.Scope = exports.varKinds = exports.UsedValueState = undefined;
|
|
@@ -6884,7 +6883,7 @@ var require_scope = __commonJS((exports) => {
|
|
|
6884
6883
|
exports.ValueScope = ValueScope;
|
|
6885
6884
|
});
|
|
6886
6885
|
|
|
6887
|
-
//
|
|
6886
|
+
// node_modules/ajv/dist/compile/codegen/index.js
|
|
6888
6887
|
var require_codegen = __commonJS((exports) => {
|
|
6889
6888
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6890
6889
|
exports.or = exports.and = exports.not = exports.CodeGen = exports.operators = exports.varKinds = exports.ValueScopeName = exports.ValueScope = exports.Scope = exports.Name = exports.regexpCode = exports.stringify = exports.getProperty = exports.nil = exports.strConcat = exports.str = exports._ = undefined;
|
|
@@ -7594,7 +7593,7 @@ var require_codegen = __commonJS((exports) => {
|
|
|
7594
7593
|
}
|
|
7595
7594
|
});
|
|
7596
7595
|
|
|
7597
|
-
//
|
|
7596
|
+
// node_modules/ajv/dist/compile/util.js
|
|
7598
7597
|
var require_util = __commonJS((exports) => {
|
|
7599
7598
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7600
7599
|
exports.checkStrictMode = exports.getErrorPath = exports.Type = exports.useFunc = exports.setEvaluated = exports.evaluatedPropsToName = exports.mergeEvaluated = exports.eachItem = exports.unescapeJsonPointer = exports.escapeJsonPointer = exports.escapeFragment = exports.unescapeFragment = exports.schemaRefOrVal = exports.schemaHasRulesButRef = exports.schemaHasRules = exports.checkUnknownRules = exports.alwaysValidSchema = exports.toHash = undefined;
|
|
@@ -7758,7 +7757,7 @@ var require_util = __commonJS((exports) => {
|
|
|
7758
7757
|
exports.checkStrictMode = checkStrictMode;
|
|
7759
7758
|
});
|
|
7760
7759
|
|
|
7761
|
-
//
|
|
7760
|
+
// node_modules/ajv/dist/compile/names.js
|
|
7762
7761
|
var require_names = __commonJS((exports) => {
|
|
7763
7762
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7764
7763
|
var codegen_1 = require_codegen();
|
|
@@ -7783,7 +7782,7 @@ var require_names = __commonJS((exports) => {
|
|
|
7783
7782
|
exports.default = names;
|
|
7784
7783
|
});
|
|
7785
7784
|
|
|
7786
|
-
//
|
|
7785
|
+
// node_modules/ajv/dist/compile/errors.js
|
|
7787
7786
|
var require_errors = __commonJS((exports) => {
|
|
7788
7787
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7789
7788
|
exports.extendErrors = exports.resetErrorsCount = exports.reportExtraError = exports.reportError = exports.keyword$DataError = exports.keywordError = undefined;
|
|
@@ -7901,7 +7900,7 @@ var require_errors = __commonJS((exports) => {
|
|
|
7901
7900
|
}
|
|
7902
7901
|
});
|
|
7903
7902
|
|
|
7904
|
-
//
|
|
7903
|
+
// node_modules/ajv/dist/compile/validate/boolSchema.js
|
|
7905
7904
|
var require_boolSchema = __commonJS((exports) => {
|
|
7906
7905
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7907
7906
|
exports.boolOrEmptySchema = exports.topBoolOrEmptySchema = undefined;
|
|
@@ -7949,7 +7948,7 @@ var require_boolSchema = __commonJS((exports) => {
|
|
|
7949
7948
|
}
|
|
7950
7949
|
});
|
|
7951
7950
|
|
|
7952
|
-
//
|
|
7951
|
+
// node_modules/ajv/dist/compile/rules.js
|
|
7953
7952
|
var require_rules = __commonJS((exports) => {
|
|
7954
7953
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7955
7954
|
exports.getRules = exports.isJSONType = undefined;
|
|
@@ -7977,7 +7976,7 @@ var require_rules = __commonJS((exports) => {
|
|
|
7977
7976
|
exports.getRules = getRules;
|
|
7978
7977
|
});
|
|
7979
7978
|
|
|
7980
|
-
//
|
|
7979
|
+
// node_modules/ajv/dist/compile/validate/applicability.js
|
|
7981
7980
|
var require_applicability = __commonJS((exports) => {
|
|
7982
7981
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7983
7982
|
exports.shouldUseRule = exports.shouldUseGroup = exports.schemaHasRulesForType = undefined;
|
|
@@ -7997,7 +7996,7 @@ var require_applicability = __commonJS((exports) => {
|
|
|
7997
7996
|
exports.shouldUseRule = shouldUseRule;
|
|
7998
7997
|
});
|
|
7999
7998
|
|
|
8000
|
-
//
|
|
7999
|
+
// node_modules/ajv/dist/compile/validate/dataType.js
|
|
8001
8000
|
var require_dataType = __commonJS((exports) => {
|
|
8002
8001
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8003
8002
|
exports.reportTypeError = exports.checkDataTypes = exports.checkDataType = exports.coerceAndCheckDataType = exports.getJSONTypes = exports.getSchemaTypes = exports.DataType = undefined;
|
|
@@ -8178,7 +8177,7 @@ var require_dataType = __commonJS((exports) => {
|
|
|
8178
8177
|
}
|
|
8179
8178
|
});
|
|
8180
8179
|
|
|
8181
|
-
//
|
|
8180
|
+
// node_modules/ajv/dist/compile/validate/defaults.js
|
|
8182
8181
|
var require_defaults2 = __commonJS((exports) => {
|
|
8183
8182
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8184
8183
|
exports.assignDefaults = undefined;
|
|
@@ -8212,7 +8211,7 @@ var require_defaults2 = __commonJS((exports) => {
|
|
|
8212
8211
|
}
|
|
8213
8212
|
});
|
|
8214
8213
|
|
|
8215
|
-
//
|
|
8214
|
+
// node_modules/ajv/dist/vocabularies/code.js
|
|
8216
8215
|
var require_code2 = __commonJS((exports) => {
|
|
8217
8216
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8218
8217
|
exports.validateUnion = exports.validateArray = exports.usePattern = exports.callValidateCode = exports.schemaProperties = exports.allSchemaProperties = exports.noPropertyInData = exports.propertyInData = exports.isOwnProperty = exports.hasPropFunc = exports.reportMissingProp = exports.checkMissingProp = exports.checkReportMissingProp = undefined;
|
|
@@ -8341,7 +8340,7 @@ var require_code2 = __commonJS((exports) => {
|
|
|
8341
8340
|
exports.validateUnion = validateUnion;
|
|
8342
8341
|
});
|
|
8343
8342
|
|
|
8344
|
-
//
|
|
8343
|
+
// node_modules/ajv/dist/compile/validate/keyword.js
|
|
8345
8344
|
var require_keyword = __commonJS((exports) => {
|
|
8346
8345
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8347
8346
|
exports.validateKeywordUsage = exports.validSchemaType = exports.funcKeywordCode = exports.macroKeywordCode = undefined;
|
|
@@ -8456,7 +8455,7 @@ var require_keyword = __commonJS((exports) => {
|
|
|
8456
8455
|
exports.validateKeywordUsage = validateKeywordUsage;
|
|
8457
8456
|
});
|
|
8458
8457
|
|
|
8459
|
-
//
|
|
8458
|
+
// node_modules/ajv/dist/compile/validate/subschema.js
|
|
8460
8459
|
var require_subschema = __commonJS((exports) => {
|
|
8461
8460
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8462
8461
|
exports.extendSubschemaMode = exports.extendSubschemaData = exports.getSubschema = undefined;
|
|
@@ -8536,7 +8535,7 @@ var require_subschema = __commonJS((exports) => {
|
|
|
8536
8535
|
exports.extendSubschemaMode = extendSubschemaMode;
|
|
8537
8536
|
});
|
|
8538
8537
|
|
|
8539
|
-
//
|
|
8538
|
+
// node_modules/fast-deep-equal/index.js
|
|
8540
8539
|
var require_fast_deep_equal = __commonJS((exports, module) => {
|
|
8541
8540
|
module.exports = function equal(a, b) {
|
|
8542
8541
|
if (a === b)
|
|
@@ -8578,7 +8577,7 @@ var require_fast_deep_equal = __commonJS((exports, module) => {
|
|
|
8578
8577
|
};
|
|
8579
8578
|
});
|
|
8580
8579
|
|
|
8581
|
-
//
|
|
8580
|
+
// node_modules/json-schema-traverse/index.js
|
|
8582
8581
|
var require_json_schema_traverse = __commonJS((exports, module) => {
|
|
8583
8582
|
var traverse = module.exports = function(schema2, opts, cb) {
|
|
8584
8583
|
if (typeof opts == "function") {
|
|
@@ -8661,7 +8660,7 @@ var require_json_schema_traverse = __commonJS((exports, module) => {
|
|
|
8661
8660
|
}
|
|
8662
8661
|
});
|
|
8663
8662
|
|
|
8664
|
-
//
|
|
8663
|
+
// node_modules/ajv/dist/compile/resolve.js
|
|
8665
8664
|
var require_resolve = __commonJS((exports) => {
|
|
8666
8665
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8667
8666
|
exports.getSchemaRefs = exports.resolveUrl = exports.normalizeId = exports._getFullPath = exports.getFullPath = exports.inlineRef = undefined;
|
|
@@ -8814,7 +8813,7 @@ var require_resolve = __commonJS((exports) => {
|
|
|
8814
8813
|
exports.getSchemaRefs = getSchemaRefs;
|
|
8815
8814
|
});
|
|
8816
8815
|
|
|
8817
|
-
//
|
|
8816
|
+
// node_modules/ajv/dist/compile/validate/index.js
|
|
8818
8817
|
var require_validate = __commonJS((exports) => {
|
|
8819
8818
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8820
8819
|
exports.getData = exports.KeywordCxt = exports.validateFunctionCode = undefined;
|
|
@@ -9319,7 +9318,7 @@ var require_validate = __commonJS((exports) => {
|
|
|
9319
9318
|
exports.getData = getData;
|
|
9320
9319
|
});
|
|
9321
9320
|
|
|
9322
|
-
//
|
|
9321
|
+
// node_modules/ajv/dist/runtime/validation_error.js
|
|
9323
9322
|
var require_validation_error = __commonJS((exports) => {
|
|
9324
9323
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9325
9324
|
|
|
@@ -9333,7 +9332,7 @@ var require_validation_error = __commonJS((exports) => {
|
|
|
9333
9332
|
exports.default = ValidationError;
|
|
9334
9333
|
});
|
|
9335
9334
|
|
|
9336
|
-
//
|
|
9335
|
+
// node_modules/ajv/dist/compile/ref_error.js
|
|
9337
9336
|
var require_ref_error = __commonJS((exports) => {
|
|
9338
9337
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9339
9338
|
var resolve_1 = require_resolve();
|
|
@@ -9348,7 +9347,7 @@ var require_ref_error = __commonJS((exports) => {
|
|
|
9348
9347
|
exports.default = MissingRefError;
|
|
9349
9348
|
});
|
|
9350
9349
|
|
|
9351
|
-
//
|
|
9350
|
+
// node_modules/ajv/dist/compile/index.js
|
|
9352
9351
|
var require_compile = __commonJS((exports) => {
|
|
9353
9352
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9354
9353
|
exports.resolveSchema = exports.getCompilingSchema = exports.resolveRef = exports.compileSchema = exports.SchemaEnv = undefined;
|
|
@@ -9569,7 +9568,7 @@ var require_compile = __commonJS((exports) => {
|
|
|
9569
9568
|
}
|
|
9570
9569
|
});
|
|
9571
9570
|
|
|
9572
|
-
//
|
|
9571
|
+
// node_modules/ajv/dist/refs/data.json
|
|
9573
9572
|
var require_data = __commonJS((exports, module) => {
|
|
9574
9573
|
module.exports = {
|
|
9575
9574
|
$id: "https://raw.githubusercontent.com/ajv-validator/ajv/master/lib/refs/data.json#",
|
|
@@ -9586,7 +9585,7 @@ var require_data = __commonJS((exports, module) => {
|
|
|
9586
9585
|
};
|
|
9587
9586
|
});
|
|
9588
9587
|
|
|
9589
|
-
//
|
|
9588
|
+
// node_modules/fast-uri/lib/utils.js
|
|
9590
9589
|
var require_utils3 = __commonJS((exports, module) => {
|
|
9591
9590
|
var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
|
|
9592
9591
|
var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
|
|
@@ -9841,7 +9840,7 @@ var require_utils3 = __commonJS((exports, module) => {
|
|
|
9841
9840
|
};
|
|
9842
9841
|
});
|
|
9843
9842
|
|
|
9844
|
-
//
|
|
9843
|
+
// node_modules/fast-uri/lib/schemes.js
|
|
9845
9844
|
var require_schemes = __commonJS((exports, module) => {
|
|
9846
9845
|
var { isUUID } = require_utils3();
|
|
9847
9846
|
var URN_REG = /([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-.:;=@]|%[\da-f]{2})+)/iu;
|
|
@@ -10015,7 +10014,7 @@ var require_schemes = __commonJS((exports, module) => {
|
|
|
10015
10014
|
};
|
|
10016
10015
|
});
|
|
10017
10016
|
|
|
10018
|
-
//
|
|
10017
|
+
// node_modules/fast-uri/index.js
|
|
10019
10018
|
var require_fast_uri = __commonJS((exports, module) => {
|
|
10020
10019
|
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizeComponentEncoding, isIPv4, nonSimpleDomain } = require_utils3();
|
|
10021
10020
|
var { SCHEMES, getSchemeHandler } = require_schemes();
|
|
@@ -10266,7 +10265,7 @@ var require_fast_uri = __commonJS((exports, module) => {
|
|
|
10266
10265
|
module.exports.fastUri = fastUri;
|
|
10267
10266
|
});
|
|
10268
10267
|
|
|
10269
|
-
//
|
|
10268
|
+
// node_modules/ajv/dist/runtime/uri.js
|
|
10270
10269
|
var require_uri = __commonJS((exports) => {
|
|
10271
10270
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10272
10271
|
var uri = require_fast_uri();
|
|
@@ -10274,7 +10273,7 @@ var require_uri = __commonJS((exports) => {
|
|
|
10274
10273
|
exports.default = uri;
|
|
10275
10274
|
});
|
|
10276
10275
|
|
|
10277
|
-
//
|
|
10276
|
+
// node_modules/ajv/dist/core.js
|
|
10278
10277
|
var require_core = __commonJS((exports) => {
|
|
10279
10278
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10280
10279
|
exports.CodeGen = exports.Name = exports.nil = exports.stringify = exports.str = exports._ = exports.KeywordCxt = undefined;
|
|
@@ -10867,7 +10866,7 @@ var require_core = __commonJS((exports) => {
|
|
|
10867
10866
|
}
|
|
10868
10867
|
});
|
|
10869
10868
|
|
|
10870
|
-
//
|
|
10869
|
+
// node_modules/ajv/dist/vocabularies/core/id.js
|
|
10871
10870
|
var require_id = __commonJS((exports) => {
|
|
10872
10871
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10873
10872
|
var def = {
|
|
@@ -10879,7 +10878,7 @@ var require_id = __commonJS((exports) => {
|
|
|
10879
10878
|
exports.default = def;
|
|
10880
10879
|
});
|
|
10881
10880
|
|
|
10882
|
-
//
|
|
10881
|
+
// node_modules/ajv/dist/vocabularies/core/ref.js
|
|
10883
10882
|
var require_ref = __commonJS((exports) => {
|
|
10884
10883
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10885
10884
|
exports.callRef = exports.getValidate = undefined;
|
|
@@ -10998,7 +10997,7 @@ var require_ref = __commonJS((exports) => {
|
|
|
10998
10997
|
exports.default = def;
|
|
10999
10998
|
});
|
|
11000
10999
|
|
|
11001
|
-
//
|
|
11000
|
+
// node_modules/ajv/dist/vocabularies/core/index.js
|
|
11002
11001
|
var require_core2 = __commonJS((exports) => {
|
|
11003
11002
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11004
11003
|
var id_1 = require_id();
|
|
@@ -11016,7 +11015,7 @@ var require_core2 = __commonJS((exports) => {
|
|
|
11016
11015
|
exports.default = core3;
|
|
11017
11016
|
});
|
|
11018
11017
|
|
|
11019
|
-
//
|
|
11018
|
+
// node_modules/ajv/dist/vocabularies/validation/limitNumber.js
|
|
11020
11019
|
var require_limitNumber = __commonJS((exports) => {
|
|
11021
11020
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11022
11021
|
var codegen_1 = require_codegen();
|
|
@@ -11045,7 +11044,7 @@ var require_limitNumber = __commonJS((exports) => {
|
|
|
11045
11044
|
exports.default = def;
|
|
11046
11045
|
});
|
|
11047
11046
|
|
|
11048
|
-
//
|
|
11047
|
+
// node_modules/ajv/dist/vocabularies/validation/multipleOf.js
|
|
11049
11048
|
var require_multipleOf = __commonJS((exports) => {
|
|
11050
11049
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11051
11050
|
var codegen_1 = require_codegen();
|
|
@@ -11070,7 +11069,7 @@ var require_multipleOf = __commonJS((exports) => {
|
|
|
11070
11069
|
exports.default = def;
|
|
11071
11070
|
});
|
|
11072
11071
|
|
|
11073
|
-
//
|
|
11072
|
+
// node_modules/ajv/dist/runtime/ucs2length.js
|
|
11074
11073
|
var require_ucs2length = __commonJS((exports) => {
|
|
11075
11074
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11076
11075
|
function ucs2length(str2) {
|
|
@@ -11093,7 +11092,7 @@ var require_ucs2length = __commonJS((exports) => {
|
|
|
11093
11092
|
ucs2length.code = 'require("ajv/dist/runtime/ucs2length").default';
|
|
11094
11093
|
});
|
|
11095
11094
|
|
|
11096
|
-
//
|
|
11095
|
+
// node_modules/ajv/dist/vocabularies/validation/limitLength.js
|
|
11097
11096
|
var require_limitLength = __commonJS((exports) => {
|
|
11098
11097
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11099
11098
|
var codegen_1 = require_codegen();
|
|
@@ -11122,7 +11121,7 @@ var require_limitLength = __commonJS((exports) => {
|
|
|
11122
11121
|
exports.default = def;
|
|
11123
11122
|
});
|
|
11124
11123
|
|
|
11125
|
-
//
|
|
11124
|
+
// node_modules/ajv/dist/vocabularies/validation/pattern.js
|
|
11126
11125
|
var require_pattern = __commonJS((exports) => {
|
|
11127
11126
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11128
11127
|
var code_1 = require_code2();
|
|
@@ -11147,7 +11146,7 @@ var require_pattern = __commonJS((exports) => {
|
|
|
11147
11146
|
exports.default = def;
|
|
11148
11147
|
});
|
|
11149
11148
|
|
|
11150
|
-
//
|
|
11149
|
+
// node_modules/ajv/dist/vocabularies/validation/limitProperties.js
|
|
11151
11150
|
var require_limitProperties = __commonJS((exports) => {
|
|
11152
11151
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11153
11152
|
var codegen_1 = require_codegen();
|
|
@@ -11173,7 +11172,7 @@ var require_limitProperties = __commonJS((exports) => {
|
|
|
11173
11172
|
exports.default = def;
|
|
11174
11173
|
});
|
|
11175
11174
|
|
|
11176
|
-
//
|
|
11175
|
+
// node_modules/ajv/dist/vocabularies/validation/required.js
|
|
11177
11176
|
var require_required = __commonJS((exports) => {
|
|
11178
11177
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11179
11178
|
var code_1 = require_code2();
|
|
@@ -11252,7 +11251,7 @@ var require_required = __commonJS((exports) => {
|
|
|
11252
11251
|
exports.default = def;
|
|
11253
11252
|
});
|
|
11254
11253
|
|
|
11255
|
-
//
|
|
11254
|
+
// node_modules/ajv/dist/vocabularies/validation/limitItems.js
|
|
11256
11255
|
var require_limitItems = __commonJS((exports) => {
|
|
11257
11256
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11258
11257
|
var codegen_1 = require_codegen();
|
|
@@ -11278,7 +11277,7 @@ var require_limitItems = __commonJS((exports) => {
|
|
|
11278
11277
|
exports.default = def;
|
|
11279
11278
|
});
|
|
11280
11279
|
|
|
11281
|
-
//
|
|
11280
|
+
// node_modules/ajv/dist/runtime/equal.js
|
|
11282
11281
|
var require_equal = __commonJS((exports) => {
|
|
11283
11282
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11284
11283
|
var equal = require_fast_deep_equal();
|
|
@@ -11286,7 +11285,7 @@ var require_equal = __commonJS((exports) => {
|
|
|
11286
11285
|
exports.default = equal;
|
|
11287
11286
|
});
|
|
11288
11287
|
|
|
11289
|
-
//
|
|
11288
|
+
// node_modules/ajv/dist/vocabularies/validation/uniqueItems.js
|
|
11290
11289
|
var require_uniqueItems = __commonJS((exports) => {
|
|
11291
11290
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11292
11291
|
var dataType_1 = require_dataType();
|
|
@@ -11350,7 +11349,7 @@ var require_uniqueItems = __commonJS((exports) => {
|
|
|
11350
11349
|
exports.default = def;
|
|
11351
11350
|
});
|
|
11352
11351
|
|
|
11353
|
-
//
|
|
11352
|
+
// node_modules/ajv/dist/vocabularies/validation/const.js
|
|
11354
11353
|
var require_const = __commonJS((exports) => {
|
|
11355
11354
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11356
11355
|
var codegen_1 = require_codegen();
|
|
@@ -11376,7 +11375,7 @@ var require_const = __commonJS((exports) => {
|
|
|
11376
11375
|
exports.default = def;
|
|
11377
11376
|
});
|
|
11378
11377
|
|
|
11379
|
-
//
|
|
11378
|
+
// node_modules/ajv/dist/vocabularies/validation/enum.js
|
|
11380
11379
|
var require_enum = __commonJS((exports) => {
|
|
11381
11380
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11382
11381
|
var codegen_1 = require_codegen();
|
|
@@ -11422,7 +11421,7 @@ var require_enum = __commonJS((exports) => {
|
|
|
11422
11421
|
exports.default = def;
|
|
11423
11422
|
});
|
|
11424
11423
|
|
|
11425
|
-
//
|
|
11424
|
+
// node_modules/ajv/dist/vocabularies/validation/index.js
|
|
11426
11425
|
var require_validation = __commonJS((exports) => {
|
|
11427
11426
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11428
11427
|
var limitNumber_1 = require_limitNumber();
|
|
@@ -11452,7 +11451,7 @@ var require_validation = __commonJS((exports) => {
|
|
|
11452
11451
|
exports.default = validation;
|
|
11453
11452
|
});
|
|
11454
11453
|
|
|
11455
|
-
//
|
|
11454
|
+
// node_modules/ajv/dist/vocabularies/applicator/additionalItems.js
|
|
11456
11455
|
var require_additionalItems = __commonJS((exports) => {
|
|
11457
11456
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11458
11457
|
exports.validateAdditionalItems = undefined;
|
|
@@ -11502,7 +11501,7 @@ var require_additionalItems = __commonJS((exports) => {
|
|
|
11502
11501
|
exports.default = def;
|
|
11503
11502
|
});
|
|
11504
11503
|
|
|
11505
|
-
//
|
|
11504
|
+
// node_modules/ajv/dist/vocabularies/applicator/items.js
|
|
11506
11505
|
var require_items = __commonJS((exports) => {
|
|
11507
11506
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11508
11507
|
exports.validateTuple = undefined;
|
|
@@ -11556,7 +11555,7 @@ var require_items = __commonJS((exports) => {
|
|
|
11556
11555
|
exports.default = def;
|
|
11557
11556
|
});
|
|
11558
11557
|
|
|
11559
|
-
//
|
|
11558
|
+
// node_modules/ajv/dist/vocabularies/applicator/prefixItems.js
|
|
11560
11559
|
var require_prefixItems = __commonJS((exports) => {
|
|
11561
11560
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11562
11561
|
var items_1 = require_items();
|
|
@@ -11570,7 +11569,7 @@ var require_prefixItems = __commonJS((exports) => {
|
|
|
11570
11569
|
exports.default = def;
|
|
11571
11570
|
});
|
|
11572
11571
|
|
|
11573
|
-
//
|
|
11572
|
+
// node_modules/ajv/dist/vocabularies/applicator/items2020.js
|
|
11574
11573
|
var require_items2020 = __commonJS((exports) => {
|
|
11575
11574
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11576
11575
|
var codegen_1 = require_codegen();
|
|
@@ -11602,7 +11601,7 @@ var require_items2020 = __commonJS((exports) => {
|
|
|
11602
11601
|
exports.default = def;
|
|
11603
11602
|
});
|
|
11604
11603
|
|
|
11605
|
-
//
|
|
11604
|
+
// node_modules/ajv/dist/vocabularies/applicator/contains.js
|
|
11606
11605
|
var require_contains = __commonJS((exports) => {
|
|
11607
11606
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11608
11607
|
var codegen_1 = require_codegen();
|
|
@@ -11693,7 +11692,7 @@ var require_contains = __commonJS((exports) => {
|
|
|
11693
11692
|
exports.default = def;
|
|
11694
11693
|
});
|
|
11695
11694
|
|
|
11696
|
-
//
|
|
11695
|
+
// node_modules/ajv/dist/vocabularies/applicator/dependencies.js
|
|
11697
11696
|
var require_dependencies = __commonJS((exports) => {
|
|
11698
11697
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11699
11698
|
exports.validateSchemaDeps = exports.validatePropertyDeps = exports.error = undefined;
|
|
@@ -11778,7 +11777,7 @@ var require_dependencies = __commonJS((exports) => {
|
|
|
11778
11777
|
exports.default = def;
|
|
11779
11778
|
});
|
|
11780
11779
|
|
|
11781
|
-
//
|
|
11780
|
+
// node_modules/ajv/dist/vocabularies/applicator/propertyNames.js
|
|
11782
11781
|
var require_propertyNames = __commonJS((exports) => {
|
|
11783
11782
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11784
11783
|
var codegen_1 = require_codegen();
|
|
@@ -11818,7 +11817,7 @@ var require_propertyNames = __commonJS((exports) => {
|
|
|
11818
11817
|
exports.default = def;
|
|
11819
11818
|
});
|
|
11820
11819
|
|
|
11821
|
-
//
|
|
11820
|
+
// node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js
|
|
11822
11821
|
var require_additionalProperties = __commonJS((exports) => {
|
|
11823
11822
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11824
11823
|
var code_1 = require_code2();
|
|
@@ -11921,7 +11920,7 @@ var require_additionalProperties = __commonJS((exports) => {
|
|
|
11921
11920
|
exports.default = def;
|
|
11922
11921
|
});
|
|
11923
11922
|
|
|
11924
|
-
//
|
|
11923
|
+
// node_modules/ajv/dist/vocabularies/applicator/properties.js
|
|
11925
11924
|
var require_properties = __commonJS((exports) => {
|
|
11926
11925
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11927
11926
|
var validate_1 = require_validate();
|
|
@@ -11976,7 +11975,7 @@ var require_properties = __commonJS((exports) => {
|
|
|
11976
11975
|
exports.default = def;
|
|
11977
11976
|
});
|
|
11978
11977
|
|
|
11979
|
-
//
|
|
11978
|
+
// node_modules/ajv/dist/vocabularies/applicator/patternProperties.js
|
|
11980
11979
|
var require_patternProperties = __commonJS((exports) => {
|
|
11981
11980
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11982
11981
|
var code_1 = require_code2();
|
|
@@ -12047,7 +12046,7 @@ var require_patternProperties = __commonJS((exports) => {
|
|
|
12047
12046
|
exports.default = def;
|
|
12048
12047
|
});
|
|
12049
12048
|
|
|
12050
|
-
//
|
|
12049
|
+
// node_modules/ajv/dist/vocabularies/applicator/not.js
|
|
12051
12050
|
var require_not = __commonJS((exports) => {
|
|
12052
12051
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12053
12052
|
var util_1 = require_util();
|
|
@@ -12075,7 +12074,7 @@ var require_not = __commonJS((exports) => {
|
|
|
12075
12074
|
exports.default = def;
|
|
12076
12075
|
});
|
|
12077
12076
|
|
|
12078
|
-
//
|
|
12077
|
+
// node_modules/ajv/dist/vocabularies/applicator/anyOf.js
|
|
12079
12078
|
var require_anyOf = __commonJS((exports) => {
|
|
12080
12079
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12081
12080
|
var code_1 = require_code2();
|
|
@@ -12089,7 +12088,7 @@ var require_anyOf = __commonJS((exports) => {
|
|
|
12089
12088
|
exports.default = def;
|
|
12090
12089
|
});
|
|
12091
12090
|
|
|
12092
|
-
//
|
|
12091
|
+
// node_modules/ajv/dist/vocabularies/applicator/oneOf.js
|
|
12093
12092
|
var require_oneOf = __commonJS((exports) => {
|
|
12094
12093
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12095
12094
|
var codegen_1 = require_codegen();
|
|
@@ -12144,7 +12143,7 @@ var require_oneOf = __commonJS((exports) => {
|
|
|
12144
12143
|
exports.default = def;
|
|
12145
12144
|
});
|
|
12146
12145
|
|
|
12147
|
-
//
|
|
12146
|
+
// node_modules/ajv/dist/vocabularies/applicator/allOf.js
|
|
12148
12147
|
var require_allOf = __commonJS((exports) => {
|
|
12149
12148
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12150
12149
|
var util_1 = require_util();
|
|
@@ -12168,7 +12167,7 @@ var require_allOf = __commonJS((exports) => {
|
|
|
12168
12167
|
exports.default = def;
|
|
12169
12168
|
});
|
|
12170
12169
|
|
|
12171
|
-
//
|
|
12170
|
+
// node_modules/ajv/dist/vocabularies/applicator/if.js
|
|
12172
12171
|
var require_if = __commonJS((exports) => {
|
|
12173
12172
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12174
12173
|
var codegen_1 = require_codegen();
|
|
@@ -12234,7 +12233,7 @@ var require_if = __commonJS((exports) => {
|
|
|
12234
12233
|
exports.default = def;
|
|
12235
12234
|
});
|
|
12236
12235
|
|
|
12237
|
-
//
|
|
12236
|
+
// node_modules/ajv/dist/vocabularies/applicator/thenElse.js
|
|
12238
12237
|
var require_thenElse = __commonJS((exports) => {
|
|
12239
12238
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12240
12239
|
var util_1 = require_util();
|
|
@@ -12249,7 +12248,7 @@ var require_thenElse = __commonJS((exports) => {
|
|
|
12249
12248
|
exports.default = def;
|
|
12250
12249
|
});
|
|
12251
12250
|
|
|
12252
|
-
//
|
|
12251
|
+
// node_modules/ajv/dist/vocabularies/applicator/index.js
|
|
12253
12252
|
var require_applicator = __commonJS((exports) => {
|
|
12254
12253
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12255
12254
|
var additionalItems_1 = require_additionalItems();
|
|
@@ -12292,7 +12291,7 @@ var require_applicator = __commonJS((exports) => {
|
|
|
12292
12291
|
exports.default = getApplicator;
|
|
12293
12292
|
});
|
|
12294
12293
|
|
|
12295
|
-
//
|
|
12294
|
+
// node_modules/ajv/dist/vocabularies/format/format.js
|
|
12296
12295
|
var require_format = __commonJS((exports) => {
|
|
12297
12296
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12298
12297
|
var codegen_1 = require_codegen();
|
|
@@ -12379,7 +12378,7 @@ var require_format = __commonJS((exports) => {
|
|
|
12379
12378
|
exports.default = def;
|
|
12380
12379
|
});
|
|
12381
12380
|
|
|
12382
|
-
//
|
|
12381
|
+
// node_modules/ajv/dist/vocabularies/format/index.js
|
|
12383
12382
|
var require_format2 = __commonJS((exports) => {
|
|
12384
12383
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12385
12384
|
var format_1 = require_format();
|
|
@@ -12387,7 +12386,7 @@ var require_format2 = __commonJS((exports) => {
|
|
|
12387
12386
|
exports.default = format;
|
|
12388
12387
|
});
|
|
12389
12388
|
|
|
12390
|
-
//
|
|
12389
|
+
// node_modules/ajv/dist/vocabularies/metadata.js
|
|
12391
12390
|
var require_metadata = __commonJS((exports) => {
|
|
12392
12391
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12393
12392
|
exports.contentVocabulary = exports.metadataVocabulary = undefined;
|
|
@@ -12407,7 +12406,7 @@ var require_metadata = __commonJS((exports) => {
|
|
|
12407
12406
|
];
|
|
12408
12407
|
});
|
|
12409
12408
|
|
|
12410
|
-
//
|
|
12409
|
+
// node_modules/ajv/dist/vocabularies/draft7.js
|
|
12411
12410
|
var require_draft7 = __commonJS((exports) => {
|
|
12412
12411
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12413
12412
|
var core_1 = require_core2();
|
|
@@ -12426,7 +12425,7 @@ var require_draft7 = __commonJS((exports) => {
|
|
|
12426
12425
|
exports.default = draft7Vocabularies;
|
|
12427
12426
|
});
|
|
12428
12427
|
|
|
12429
|
-
//
|
|
12428
|
+
// node_modules/ajv/dist/vocabularies/discriminator/types.js
|
|
12430
12429
|
var require_types = __commonJS((exports) => {
|
|
12431
12430
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12432
12431
|
exports.DiscrError = undefined;
|
|
@@ -12437,7 +12436,7 @@ var require_types = __commonJS((exports) => {
|
|
|
12437
12436
|
})(DiscrError || (exports.DiscrError = DiscrError = {}));
|
|
12438
12437
|
});
|
|
12439
12438
|
|
|
12440
|
-
//
|
|
12439
|
+
// node_modules/ajv/dist/vocabularies/discriminator/index.js
|
|
12441
12440
|
var require_discriminator = __commonJS((exports) => {
|
|
12442
12441
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12443
12442
|
var codegen_1 = require_codegen();
|
|
@@ -12539,7 +12538,7 @@ var require_discriminator = __commonJS((exports) => {
|
|
|
12539
12538
|
exports.default = def;
|
|
12540
12539
|
});
|
|
12541
12540
|
|
|
12542
|
-
//
|
|
12541
|
+
// node_modules/ajv/dist/refs/json-schema-draft-07.json
|
|
12543
12542
|
var require_json_schema_draft_07 = __commonJS((exports, module) => {
|
|
12544
12543
|
module.exports = {
|
|
12545
12544
|
$schema: "http://json-schema.org/draft-07/schema#",
|
|
@@ -12694,7 +12693,7 @@ var require_json_schema_draft_07 = __commonJS((exports, module) => {
|
|
|
12694
12693
|
};
|
|
12695
12694
|
});
|
|
12696
12695
|
|
|
12697
|
-
//
|
|
12696
|
+
// node_modules/ajv/dist/ajv.js
|
|
12698
12697
|
var require_ajv = __commonJS((exports, module) => {
|
|
12699
12698
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12700
12699
|
exports.MissingRefError = exports.ValidationError = exports.CodeGen = exports.Name = exports.nil = exports.stringify = exports.str = exports._ = exports.KeywordCxt = exports.Ajv = undefined;
|
|
@@ -12762,7 +12761,7 @@ var require_ajv = __commonJS((exports, module) => {
|
|
|
12762
12761
|
} });
|
|
12763
12762
|
});
|
|
12764
12763
|
|
|
12765
|
-
//
|
|
12764
|
+
// node_modules/ajv-formats/dist/formats.js
|
|
12766
12765
|
var require_formats = __commonJS((exports) => {
|
|
12767
12766
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12768
12767
|
exports.formatNames = exports.fastFormats = exports.fullFormats = undefined;
|
|
@@ -12939,7 +12938,7 @@ var require_formats = __commonJS((exports) => {
|
|
|
12939
12938
|
}
|
|
12940
12939
|
});
|
|
12941
12940
|
|
|
12942
|
-
//
|
|
12941
|
+
// node_modules/ajv-formats/dist/limit.js
|
|
12943
12942
|
var require_limit = __commonJS((exports) => {
|
|
12944
12943
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12945
12944
|
exports.formatLimitDefinition = undefined;
|
|
@@ -13008,7 +13007,7 @@ var require_limit = __commonJS((exports) => {
|
|
|
13008
13007
|
exports.default = formatLimitPlugin;
|
|
13009
13008
|
});
|
|
13010
13009
|
|
|
13011
|
-
//
|
|
13010
|
+
// node_modules/ajv-formats/dist/index.js
|
|
13012
13011
|
var require_dist2 = __commonJS((exports, module) => {
|
|
13013
13012
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13014
13013
|
var formats_1 = require_formats();
|
|
@@ -13047,7 +13046,7 @@ var require_dist2 = __commonJS((exports, module) => {
|
|
|
13047
13046
|
exports.default = formatsPlugin;
|
|
13048
13047
|
});
|
|
13049
13048
|
|
|
13050
|
-
//
|
|
13049
|
+
// node_modules/commander/esm.mjs
|
|
13051
13050
|
var import__ = __toESM(require_commander(), 1);
|
|
13052
13051
|
var {
|
|
13053
13052
|
program,
|
|
@@ -13065,7 +13064,7 @@ var {
|
|
|
13065
13064
|
// package.json
|
|
13066
13065
|
var package_default = {
|
|
13067
13066
|
name: "postgresai",
|
|
13068
|
-
version: "0.14.0-beta.
|
|
13067
|
+
version: "0.14.0-beta.13",
|
|
13069
13068
|
description: "postgres_ai CLI",
|
|
13070
13069
|
license: "Apache-2.0",
|
|
13071
13070
|
private: false,
|
|
@@ -13221,7 +13220,7 @@ function deleteConfigKeys(keys) {
|
|
|
13221
13220
|
}
|
|
13222
13221
|
}
|
|
13223
13222
|
|
|
13224
|
-
//
|
|
13223
|
+
// node_modules/js-yaml/dist/js-yaml.mjs
|
|
13225
13224
|
/*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT */
|
|
13226
13225
|
function isNothing(subject) {
|
|
13227
13226
|
return typeof subject === "undefined" || subject === null;
|
|
@@ -15874,7 +15873,7 @@ import * as path5 from "path";
|
|
|
15874
15873
|
import * as os3 from "os";
|
|
15875
15874
|
import * as crypto2 from "crypto";
|
|
15876
15875
|
|
|
15877
|
-
//
|
|
15876
|
+
// node_modules/pg/esm/index.mjs
|
|
15878
15877
|
var import_lib = __toESM(require_lib2(), 1);
|
|
15879
15878
|
var Client = import_lib.default.Client;
|
|
15880
15879
|
var Pool = import_lib.default.Pool;
|
|
@@ -15888,7 +15887,7 @@ var Result = import_lib.default.Result;
|
|
|
15888
15887
|
var TypeOverrides = import_lib.default.TypeOverrides;
|
|
15889
15888
|
var defaults = import_lib.default.defaults;
|
|
15890
15889
|
// package.json
|
|
15891
|
-
var version = "0.14.0-beta.
|
|
15890
|
+
var version = "0.14.0-beta.13";
|
|
15892
15891
|
var package_default2 = {
|
|
15893
15892
|
name: "postgresai",
|
|
15894
15893
|
version,
|
|
@@ -16080,13 +16079,24 @@ function resolveBaseUrls(opts, cfg, defaults2 = {}) {
|
|
|
16080
16079
|
|
|
16081
16080
|
// lib/issues.ts
|
|
16082
16081
|
async function fetchIssues(params) {
|
|
16083
|
-
const { apiKey, apiBaseUrl, debug } = params;
|
|
16082
|
+
const { apiKey, apiBaseUrl, orgId, status, limit = 20, offset = 0, debug } = params;
|
|
16084
16083
|
if (!apiKey) {
|
|
16085
16084
|
throw new Error("API key is required");
|
|
16086
16085
|
}
|
|
16087
16086
|
const base = normalizeBaseUrl(apiBaseUrl);
|
|
16088
16087
|
const url = new URL(`${base}/issues`);
|
|
16089
16088
|
url.searchParams.set("select", "id,title,status,created_at");
|
|
16089
|
+
url.searchParams.set("order", "id.desc");
|
|
16090
|
+
url.searchParams.set("limit", String(limit));
|
|
16091
|
+
url.searchParams.set("offset", String(offset));
|
|
16092
|
+
if (typeof orgId === "number") {
|
|
16093
|
+
url.searchParams.set("org_id", `eq.${orgId}`);
|
|
16094
|
+
}
|
|
16095
|
+
if (status === "open") {
|
|
16096
|
+
url.searchParams.set("status", "eq.0");
|
|
16097
|
+
} else if (status === "closed") {
|
|
16098
|
+
url.searchParams.set("status", "eq.1");
|
|
16099
|
+
}
|
|
16090
16100
|
const headers = {
|
|
16091
16101
|
"access-token": apiKey,
|
|
16092
16102
|
Prefer: "return=representation",
|
|
@@ -16171,7 +16181,7 @@ async function fetchIssue(params) {
|
|
|
16171
16181
|
}
|
|
16172
16182
|
const base = normalizeBaseUrl(apiBaseUrl);
|
|
16173
16183
|
const url = new URL(`${base}/issues`);
|
|
16174
|
-
url.searchParams.set("select", "id,title,description,status,created_at,author_display_name");
|
|
16184
|
+
url.searchParams.set("select", "id,title,description,status,created_at,author_display_name,action_items");
|
|
16175
16185
|
url.searchParams.set("id", `eq.${issueId}`);
|
|
16176
16186
|
url.searchParams.set("limit", "1");
|
|
16177
16187
|
const headers = {
|
|
@@ -16199,11 +16209,20 @@ async function fetchIssue(params) {
|
|
|
16199
16209
|
if (response.ok) {
|
|
16200
16210
|
try {
|
|
16201
16211
|
const parsed = JSON.parse(data);
|
|
16202
|
-
|
|
16203
|
-
|
|
16204
|
-
|
|
16205
|
-
return parsed;
|
|
16212
|
+
const rawIssue = Array.isArray(parsed) ? parsed[0] : parsed;
|
|
16213
|
+
if (!rawIssue) {
|
|
16214
|
+
return null;
|
|
16206
16215
|
}
|
|
16216
|
+
const actionItemsSummary = Array.isArray(rawIssue.action_items) ? rawIssue.action_items.map((item) => ({ id: item.id, title: item.title })) : [];
|
|
16217
|
+
return {
|
|
16218
|
+
id: rawIssue.id,
|
|
16219
|
+
title: rawIssue.title,
|
|
16220
|
+
description: rawIssue.description,
|
|
16221
|
+
status: rawIssue.status,
|
|
16222
|
+
created_at: rawIssue.created_at,
|
|
16223
|
+
author_display_name: rawIssue.author_display_name,
|
|
16224
|
+
action_items: actionItemsSummary
|
|
16225
|
+
};
|
|
16207
16226
|
} catch {
|
|
16208
16227
|
throw new Error(`Failed to parse issue response: ${data}`);
|
|
16209
16228
|
}
|
|
@@ -16442,8 +16461,245 @@ async function updateIssueComment(params) {
|
|
|
16442
16461
|
throw new Error(formatHttpError("Failed to update issue comment", response.status, data));
|
|
16443
16462
|
}
|
|
16444
16463
|
}
|
|
16464
|
+
async function fetchActionItem(params) {
|
|
16465
|
+
const { apiKey, apiBaseUrl, actionItemIds, debug } = params;
|
|
16466
|
+
if (!apiKey) {
|
|
16467
|
+
throw new Error("API key is required");
|
|
16468
|
+
}
|
|
16469
|
+
const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
16470
|
+
const rawIds = Array.isArray(actionItemIds) ? actionItemIds : [actionItemIds];
|
|
16471
|
+
const validIds = rawIds.filter((id) => id != null && typeof id === "string").map((id) => id.trim()).filter((id) => id.length > 0 && uuidPattern.test(id));
|
|
16472
|
+
if (validIds.length === 0) {
|
|
16473
|
+
throw new Error("actionItemId is required and must be a valid UUID");
|
|
16474
|
+
}
|
|
16475
|
+
const base = normalizeBaseUrl(apiBaseUrl);
|
|
16476
|
+
const url = new URL(`${base}/issue_action_items`);
|
|
16477
|
+
if (validIds.length === 1) {
|
|
16478
|
+
url.searchParams.set("id", `eq.${validIds[0]}`);
|
|
16479
|
+
} else {
|
|
16480
|
+
url.searchParams.set("id", `in.(${validIds.join(",")})`);
|
|
16481
|
+
}
|
|
16482
|
+
const headers = {
|
|
16483
|
+
"access-token": apiKey,
|
|
16484
|
+
Prefer: "return=representation",
|
|
16485
|
+
"Content-Type": "application/json",
|
|
16486
|
+
Connection: "close"
|
|
16487
|
+
};
|
|
16488
|
+
if (debug) {
|
|
16489
|
+
const debugHeaders = { ...headers, "access-token": maskSecret(apiKey) };
|
|
16490
|
+
console.log(`Debug: Resolved API base URL: ${base}`);
|
|
16491
|
+
console.log(`Debug: GET URL: ${url.toString()}`);
|
|
16492
|
+
console.log(`Debug: Auth scheme: access-token`);
|
|
16493
|
+
console.log(`Debug: Request headers: ${JSON.stringify(debugHeaders)}`);
|
|
16494
|
+
}
|
|
16495
|
+
const response = await fetch(url.toString(), {
|
|
16496
|
+
method: "GET",
|
|
16497
|
+
headers
|
|
16498
|
+
});
|
|
16499
|
+
if (debug) {
|
|
16500
|
+
console.log(`Debug: Response status: ${response.status}`);
|
|
16501
|
+
console.log(`Debug: Response headers: ${JSON.stringify(Object.fromEntries(response.headers.entries()))}`);
|
|
16502
|
+
}
|
|
16503
|
+
const data = await response.text();
|
|
16504
|
+
if (response.ok) {
|
|
16505
|
+
try {
|
|
16506
|
+
const parsed = JSON.parse(data);
|
|
16507
|
+
if (Array.isArray(parsed)) {
|
|
16508
|
+
return parsed;
|
|
16509
|
+
}
|
|
16510
|
+
return parsed ? [parsed] : [];
|
|
16511
|
+
} catch {
|
|
16512
|
+
throw new Error(`Failed to parse action item response: ${data}`);
|
|
16513
|
+
}
|
|
16514
|
+
} else {
|
|
16515
|
+
throw new Error(formatHttpError("Failed to fetch action item", response.status, data));
|
|
16516
|
+
}
|
|
16517
|
+
}
|
|
16518
|
+
async function fetchActionItems(params) {
|
|
16519
|
+
const { apiKey, apiBaseUrl, issueId, debug } = params;
|
|
16520
|
+
if (!apiKey) {
|
|
16521
|
+
throw new Error("API key is required");
|
|
16522
|
+
}
|
|
16523
|
+
if (!issueId) {
|
|
16524
|
+
throw new Error("issueId is required");
|
|
16525
|
+
}
|
|
16526
|
+
const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
16527
|
+
if (!uuidPattern.test(issueId.trim())) {
|
|
16528
|
+
throw new Error("issueId must be a valid UUID");
|
|
16529
|
+
}
|
|
16530
|
+
const base = normalizeBaseUrl(apiBaseUrl);
|
|
16531
|
+
const url = new URL(`${base}/issue_action_items`);
|
|
16532
|
+
url.searchParams.set("issue_id", `eq.${issueId.trim()}`);
|
|
16533
|
+
const headers = {
|
|
16534
|
+
"access-token": apiKey,
|
|
16535
|
+
Prefer: "return=representation",
|
|
16536
|
+
"Content-Type": "application/json",
|
|
16537
|
+
Connection: "close"
|
|
16538
|
+
};
|
|
16539
|
+
if (debug) {
|
|
16540
|
+
const debugHeaders = { ...headers, "access-token": maskSecret(apiKey) };
|
|
16541
|
+
console.log(`Debug: Resolved API base URL: ${base}`);
|
|
16542
|
+
console.log(`Debug: GET URL: ${url.toString()}`);
|
|
16543
|
+
console.log(`Debug: Auth scheme: access-token`);
|
|
16544
|
+
console.log(`Debug: Request headers: ${JSON.stringify(debugHeaders)}`);
|
|
16545
|
+
}
|
|
16546
|
+
const response = await fetch(url.toString(), {
|
|
16547
|
+
method: "GET",
|
|
16548
|
+
headers
|
|
16549
|
+
});
|
|
16550
|
+
if (debug) {
|
|
16551
|
+
console.log(`Debug: Response status: ${response.status}`);
|
|
16552
|
+
console.log(`Debug: Response headers: ${JSON.stringify(Object.fromEntries(response.headers.entries()))}`);
|
|
16553
|
+
}
|
|
16554
|
+
const data = await response.text();
|
|
16555
|
+
if (response.ok) {
|
|
16556
|
+
try {
|
|
16557
|
+
return JSON.parse(data);
|
|
16558
|
+
} catch {
|
|
16559
|
+
throw new Error(`Failed to parse action items response: ${data}`);
|
|
16560
|
+
}
|
|
16561
|
+
} else {
|
|
16562
|
+
throw new Error(formatHttpError("Failed to fetch action items", response.status, data));
|
|
16563
|
+
}
|
|
16564
|
+
}
|
|
16565
|
+
async function createActionItem(params) {
|
|
16566
|
+
const { apiKey, apiBaseUrl, issueId, title, description, sqlAction, configs, debug } = params;
|
|
16567
|
+
if (!apiKey) {
|
|
16568
|
+
throw new Error("API key is required");
|
|
16569
|
+
}
|
|
16570
|
+
if (!issueId) {
|
|
16571
|
+
throw new Error("issueId is required");
|
|
16572
|
+
}
|
|
16573
|
+
const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
16574
|
+
if (!uuidPattern.test(issueId.trim())) {
|
|
16575
|
+
throw new Error("issueId must be a valid UUID");
|
|
16576
|
+
}
|
|
16577
|
+
if (!title) {
|
|
16578
|
+
throw new Error("title is required");
|
|
16579
|
+
}
|
|
16580
|
+
const base = normalizeBaseUrl(apiBaseUrl);
|
|
16581
|
+
const url = new URL(`${base}/rpc/issue_action_item_create`);
|
|
16582
|
+
const bodyObj = {
|
|
16583
|
+
issue_id: issueId,
|
|
16584
|
+
title
|
|
16585
|
+
};
|
|
16586
|
+
if (description !== undefined) {
|
|
16587
|
+
bodyObj.description = description;
|
|
16588
|
+
}
|
|
16589
|
+
if (sqlAction !== undefined) {
|
|
16590
|
+
bodyObj.sql_action = sqlAction;
|
|
16591
|
+
}
|
|
16592
|
+
if (configs !== undefined) {
|
|
16593
|
+
bodyObj.configs = configs;
|
|
16594
|
+
}
|
|
16595
|
+
const body = JSON.stringify(bodyObj);
|
|
16596
|
+
const headers = {
|
|
16597
|
+
"access-token": apiKey,
|
|
16598
|
+
Prefer: "return=representation",
|
|
16599
|
+
"Content-Type": "application/json",
|
|
16600
|
+
Connection: "close"
|
|
16601
|
+
};
|
|
16602
|
+
if (debug) {
|
|
16603
|
+
const debugHeaders = { ...headers, "access-token": maskSecret(apiKey) };
|
|
16604
|
+
console.log(`Debug: Resolved API base URL: ${base}`);
|
|
16605
|
+
console.log(`Debug: POST URL: ${url.toString()}`);
|
|
16606
|
+
console.log(`Debug: Auth scheme: access-token`);
|
|
16607
|
+
console.log(`Debug: Request headers: ${JSON.stringify(debugHeaders)}`);
|
|
16608
|
+
console.log(`Debug: Request body: ${body}`);
|
|
16609
|
+
}
|
|
16610
|
+
const response = await fetch(url.toString(), {
|
|
16611
|
+
method: "POST",
|
|
16612
|
+
headers,
|
|
16613
|
+
body
|
|
16614
|
+
});
|
|
16615
|
+
if (debug) {
|
|
16616
|
+
console.log(`Debug: Response status: ${response.status}`);
|
|
16617
|
+
console.log(`Debug: Response headers: ${JSON.stringify(Object.fromEntries(response.headers.entries()))}`);
|
|
16618
|
+
}
|
|
16619
|
+
const data = await response.text();
|
|
16620
|
+
if (response.ok) {
|
|
16621
|
+
try {
|
|
16622
|
+
return JSON.parse(data);
|
|
16623
|
+
} catch {
|
|
16624
|
+
throw new Error(`Failed to parse create action item response: ${data}`);
|
|
16625
|
+
}
|
|
16626
|
+
} else {
|
|
16627
|
+
throw new Error(formatHttpError("Failed to create action item", response.status, data));
|
|
16628
|
+
}
|
|
16629
|
+
}
|
|
16630
|
+
async function updateActionItem(params) {
|
|
16631
|
+
const { apiKey, apiBaseUrl, actionItemId, title, description, isDone, status, statusReason, sqlAction, configs, debug } = params;
|
|
16632
|
+
if (!apiKey) {
|
|
16633
|
+
throw new Error("API key is required");
|
|
16634
|
+
}
|
|
16635
|
+
if (!actionItemId) {
|
|
16636
|
+
throw new Error("actionItemId is required");
|
|
16637
|
+
}
|
|
16638
|
+
const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
16639
|
+
if (!uuidPattern.test(actionItemId.trim())) {
|
|
16640
|
+
throw new Error("actionItemId must be a valid UUID");
|
|
16641
|
+
}
|
|
16642
|
+
const hasUpdateField = title !== undefined || description !== undefined || isDone !== undefined || status !== undefined || statusReason !== undefined || sqlAction !== undefined || configs !== undefined;
|
|
16643
|
+
if (!hasUpdateField) {
|
|
16644
|
+
throw new Error("At least one field to update is required");
|
|
16645
|
+
}
|
|
16646
|
+
const base = normalizeBaseUrl(apiBaseUrl);
|
|
16647
|
+
const url = new URL(`${base}/rpc/issue_action_item_update`);
|
|
16648
|
+
const bodyObj = {
|
|
16649
|
+
action_item_id: actionItemId
|
|
16650
|
+
};
|
|
16651
|
+
if (title !== undefined) {
|
|
16652
|
+
bodyObj.title = title;
|
|
16653
|
+
}
|
|
16654
|
+
if (description !== undefined) {
|
|
16655
|
+
bodyObj.description = description;
|
|
16656
|
+
}
|
|
16657
|
+
if (isDone !== undefined) {
|
|
16658
|
+
bodyObj.is_done = isDone;
|
|
16659
|
+
}
|
|
16660
|
+
if (status !== undefined) {
|
|
16661
|
+
bodyObj.status = status;
|
|
16662
|
+
}
|
|
16663
|
+
if (statusReason !== undefined) {
|
|
16664
|
+
bodyObj.status_reason = statusReason;
|
|
16665
|
+
}
|
|
16666
|
+
if (sqlAction !== undefined) {
|
|
16667
|
+
bodyObj.sql_action = sqlAction;
|
|
16668
|
+
}
|
|
16669
|
+
if (configs !== undefined) {
|
|
16670
|
+
bodyObj.configs = configs;
|
|
16671
|
+
}
|
|
16672
|
+
const body = JSON.stringify(bodyObj);
|
|
16673
|
+
const headers = {
|
|
16674
|
+
"access-token": apiKey,
|
|
16675
|
+
Prefer: "return=representation",
|
|
16676
|
+
"Content-Type": "application/json",
|
|
16677
|
+
Connection: "close"
|
|
16678
|
+
};
|
|
16679
|
+
if (debug) {
|
|
16680
|
+
const debugHeaders = { ...headers, "access-token": maskSecret(apiKey) };
|
|
16681
|
+
console.log(`Debug: Resolved API base URL: ${base}`);
|
|
16682
|
+
console.log(`Debug: POST URL: ${url.toString()}`);
|
|
16683
|
+
console.log(`Debug: Auth scheme: access-token`);
|
|
16684
|
+
console.log(`Debug: Request headers: ${JSON.stringify(debugHeaders)}`);
|
|
16685
|
+
console.log(`Debug: Request body: ${body}`);
|
|
16686
|
+
}
|
|
16687
|
+
const response = await fetch(url.toString(), {
|
|
16688
|
+
method: "POST",
|
|
16689
|
+
headers,
|
|
16690
|
+
body
|
|
16691
|
+
});
|
|
16692
|
+
if (debug) {
|
|
16693
|
+
console.log(`Debug: Response status: ${response.status}`);
|
|
16694
|
+
console.log(`Debug: Response headers: ${JSON.stringify(Object.fromEntries(response.headers.entries()))}`);
|
|
16695
|
+
}
|
|
16696
|
+
if (!response.ok) {
|
|
16697
|
+
const data = await response.text();
|
|
16698
|
+
throw new Error(formatHttpError("Failed to update action item", response.status, data));
|
|
16699
|
+
}
|
|
16700
|
+
}
|
|
16445
16701
|
|
|
16446
|
-
//
|
|
16702
|
+
// node_modules/zod/v4/core/core.js
|
|
16447
16703
|
var NEVER = Object.freeze({
|
|
16448
16704
|
status: "aborted"
|
|
16449
16705
|
});
|
|
@@ -16519,7 +16775,7 @@ function config(newConfig) {
|
|
|
16519
16775
|
Object.assign(globalConfig, newConfig);
|
|
16520
16776
|
return globalConfig;
|
|
16521
16777
|
}
|
|
16522
|
-
//
|
|
16778
|
+
// node_modules/zod/v4/core/util.js
|
|
16523
16779
|
var exports_util = {};
|
|
16524
16780
|
__export(exports_util, {
|
|
16525
16781
|
unwrapMessage: () => unwrapMessage,
|
|
@@ -17154,7 +17410,7 @@ class Class {
|
|
|
17154
17410
|
constructor(..._args) {}
|
|
17155
17411
|
}
|
|
17156
17412
|
|
|
17157
|
-
//
|
|
17413
|
+
// node_modules/zod/v4/core/errors.js
|
|
17158
17414
|
var initializer = (inst, def) => {
|
|
17159
17415
|
inst.name = "$ZodError";
|
|
17160
17416
|
Object.defineProperty(inst, "_zod", {
|
|
@@ -17220,7 +17476,7 @@ function formatError2(error, mapper = (issue2) => issue2.message) {
|
|
|
17220
17476
|
return fieldErrors;
|
|
17221
17477
|
}
|
|
17222
17478
|
|
|
17223
|
-
//
|
|
17479
|
+
// node_modules/zod/v4/core/parse.js
|
|
17224
17480
|
var _parse = (_Err) => (schema2, value, _ctx, _params) => {
|
|
17225
17481
|
const ctx = _ctx ? Object.assign(_ctx, { async: false }) : { async: false };
|
|
17226
17482
|
const result = schema2._zod.run({ value, issues: [] }, ctx);
|
|
@@ -17297,7 +17553,7 @@ var _safeEncodeAsync = (_Err) => async (schema2, value, _ctx) => {
|
|
|
17297
17553
|
var _safeDecodeAsync = (_Err) => async (schema2, value, _ctx) => {
|
|
17298
17554
|
return _safeParseAsync(_Err)(schema2, value, _ctx);
|
|
17299
17555
|
};
|
|
17300
|
-
//
|
|
17556
|
+
// node_modules/zod/v4/core/regexes.js
|
|
17301
17557
|
var cuid = /^[cC][^\s-]{8,}$/;
|
|
17302
17558
|
var cuid2 = /^[0-9a-z]+$/;
|
|
17303
17559
|
var ulid = /^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/;
|
|
@@ -17354,7 +17610,7 @@ var _null2 = /^null$/i;
|
|
|
17354
17610
|
var lowercase = /^[^A-Z]*$/;
|
|
17355
17611
|
var uppercase = /^[^a-z]*$/;
|
|
17356
17612
|
|
|
17357
|
-
//
|
|
17613
|
+
// node_modules/zod/v4/core/checks.js
|
|
17358
17614
|
var $ZodCheck = /* @__PURE__ */ $constructor("$ZodCheck", (inst, def) => {
|
|
17359
17615
|
var _a;
|
|
17360
17616
|
inst._zod ?? (inst._zod = {});
|
|
@@ -17739,7 +17995,7 @@ var $ZodCheckOverwrite = /* @__PURE__ */ $constructor("$ZodCheckOverwrite", (ins
|
|
|
17739
17995
|
};
|
|
17740
17996
|
});
|
|
17741
17997
|
|
|
17742
|
-
//
|
|
17998
|
+
// node_modules/zod/v4/core/doc.js
|
|
17743
17999
|
class Doc {
|
|
17744
18000
|
constructor(args = []) {
|
|
17745
18001
|
this.content = [];
|
|
@@ -17777,14 +18033,14 @@ class Doc {
|
|
|
17777
18033
|
}
|
|
17778
18034
|
}
|
|
17779
18035
|
|
|
17780
|
-
//
|
|
18036
|
+
// node_modules/zod/v4/core/versions.js
|
|
17781
18037
|
var version2 = {
|
|
17782
18038
|
major: 4,
|
|
17783
18039
|
minor: 2,
|
|
17784
18040
|
patch: 1
|
|
17785
18041
|
};
|
|
17786
18042
|
|
|
17787
|
-
//
|
|
18043
|
+
// node_modules/zod/v4/core/schemas.js
|
|
17788
18044
|
var $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
|
|
17789
18045
|
var _a;
|
|
17790
18046
|
inst ?? (inst = {});
|
|
@@ -19100,7 +19356,7 @@ function handleRefineResult(result, payload, input, inst) {
|
|
|
19100
19356
|
payload.issues.push(issue(_iss));
|
|
19101
19357
|
}
|
|
19102
19358
|
}
|
|
19103
|
-
//
|
|
19359
|
+
// node_modules/zod/v4/locales/en.js
|
|
19104
19360
|
var parsedType = (data) => {
|
|
19105
19361
|
const t = typeof data;
|
|
19106
19362
|
switch (t) {
|
|
@@ -19218,7 +19474,7 @@ function en_default() {
|
|
|
19218
19474
|
localeError: error()
|
|
19219
19475
|
};
|
|
19220
19476
|
}
|
|
19221
|
-
//
|
|
19477
|
+
// node_modules/zod/v4/core/registries.js
|
|
19222
19478
|
var _a;
|
|
19223
19479
|
var $output = Symbol("ZodOutput");
|
|
19224
19480
|
var $input = Symbol("ZodInput");
|
|
@@ -19271,7 +19527,7 @@ function registry() {
|
|
|
19271
19527
|
}
|
|
19272
19528
|
(_a = globalThis).__zod_globalRegistry ?? (_a.__zod_globalRegistry = registry());
|
|
19273
19529
|
var globalRegistry = globalThis.__zod_globalRegistry;
|
|
19274
|
-
//
|
|
19530
|
+
// node_modules/zod/v4/core/api.js
|
|
19275
19531
|
function _string(Class2, params) {
|
|
19276
19532
|
return new Class2({
|
|
19277
19533
|
type: "string",
|
|
@@ -19737,7 +19993,7 @@ function _check(fn, params) {
|
|
|
19737
19993
|
ch._zod.check = fn;
|
|
19738
19994
|
return ch;
|
|
19739
19995
|
}
|
|
19740
|
-
//
|
|
19996
|
+
// node_modules/zod/v4/core/to-json-schema.js
|
|
19741
19997
|
function initializeContext(params) {
|
|
19742
19998
|
let target = params?.target ?? "draft-2020-12";
|
|
19743
19999
|
if (target === "draft-4")
|
|
@@ -20034,7 +20290,7 @@ var createStandardJSONSchemaMethod = (schema2, io) => (params) => {
|
|
|
20034
20290
|
extractDefs(ctx, schema2);
|
|
20035
20291
|
return finalize(ctx, schema2);
|
|
20036
20292
|
};
|
|
20037
|
-
//
|
|
20293
|
+
// node_modules/zod/v4/core/json-schema-processors.js
|
|
20038
20294
|
var formatMap = {
|
|
20039
20295
|
guid: "uuid",
|
|
20040
20296
|
url: "uri",
|
|
@@ -20345,7 +20601,7 @@ var optionalProcessor = (schema2, ctx, _json, params) => {
|
|
|
20345
20601
|
const seen = ctx.seen.get(schema2);
|
|
20346
20602
|
seen.ref = def.innerType;
|
|
20347
20603
|
};
|
|
20348
|
-
//
|
|
20604
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
|
|
20349
20605
|
function isZ4Schema(s) {
|
|
20350
20606
|
const schema2 = s;
|
|
20351
20607
|
return !!schema2._zod;
|
|
@@ -20407,7 +20663,7 @@ function getLiteralValue(schema2) {
|
|
|
20407
20663
|
return directValue;
|
|
20408
20664
|
return;
|
|
20409
20665
|
}
|
|
20410
|
-
//
|
|
20666
|
+
// node_modules/zod/v4/classic/iso.js
|
|
20411
20667
|
var exports_iso = {};
|
|
20412
20668
|
__export(exports_iso, {
|
|
20413
20669
|
time: () => time2,
|
|
@@ -20448,7 +20704,7 @@ function duration2(params) {
|
|
|
20448
20704
|
return _isoDuration(ZodISODuration, params);
|
|
20449
20705
|
}
|
|
20450
20706
|
|
|
20451
|
-
//
|
|
20707
|
+
// node_modules/zod/v4/classic/errors.js
|
|
20452
20708
|
var initializer2 = (inst, issues) => {
|
|
20453
20709
|
$ZodError.init(inst, issues);
|
|
20454
20710
|
inst.name = "ZodError";
|
|
@@ -20483,7 +20739,7 @@ var ZodRealError = $constructor("ZodError", initializer2, {
|
|
|
20483
20739
|
Parent: Error
|
|
20484
20740
|
});
|
|
20485
20741
|
|
|
20486
|
-
//
|
|
20742
|
+
// node_modules/zod/v4/classic/parse.js
|
|
20487
20743
|
var parse3 = /* @__PURE__ */ _parse(ZodRealError);
|
|
20488
20744
|
var parseAsync2 = /* @__PURE__ */ _parseAsync(ZodRealError);
|
|
20489
20745
|
var safeParse3 = /* @__PURE__ */ _safeParse(ZodRealError);
|
|
@@ -20497,7 +20753,7 @@ var safeDecode2 = /* @__PURE__ */ _safeDecode(ZodRealError);
|
|
|
20497
20753
|
var safeEncodeAsync2 = /* @__PURE__ */ _safeEncodeAsync(ZodRealError);
|
|
20498
20754
|
var safeDecodeAsync2 = /* @__PURE__ */ _safeDecodeAsync(ZodRealError);
|
|
20499
20755
|
|
|
20500
|
-
//
|
|
20756
|
+
// node_modules/zod/v4/classic/schemas.js
|
|
20501
20757
|
var ZodType = /* @__PURE__ */ $constructor("ZodType", (inst, def) => {
|
|
20502
20758
|
$ZodType.init(inst, def);
|
|
20503
20759
|
Object.assign(inst["~standard"], {
|
|
@@ -21119,10 +21375,10 @@ function superRefine(fn) {
|
|
|
21119
21375
|
function preprocess(fn, schema2) {
|
|
21120
21376
|
return pipe(transform(fn), schema2);
|
|
21121
21377
|
}
|
|
21122
|
-
//
|
|
21378
|
+
// node_modules/zod/v4/classic/external.js
|
|
21123
21379
|
config(en_default());
|
|
21124
21380
|
|
|
21125
|
-
//
|
|
21381
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
|
|
21126
21382
|
var LATEST_PROTOCOL_VERSION = "2025-11-25";
|
|
21127
21383
|
var SUPPORTED_PROTOCOL_VERSIONS = [LATEST_PROTOCOL_VERSION, "2025-06-18", "2025-03-26", "2024-11-05", "2024-10-07"];
|
|
21128
21384
|
var RELATED_TASK_META_KEY = "io.modelcontextprotocol/related-task";
|
|
@@ -21954,16 +22210,16 @@ class UrlElicitationRequiredError extends McpError {
|
|
|
21954
22210
|
}
|
|
21955
22211
|
}
|
|
21956
22212
|
|
|
21957
|
-
//
|
|
22213
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
|
|
21958
22214
|
function isTerminal(status) {
|
|
21959
22215
|
return status === "completed" || status === "failed" || status === "cancelled";
|
|
21960
22216
|
}
|
|
21961
22217
|
|
|
21962
|
-
//
|
|
22218
|
+
// node_modules/zod-to-json-schema/dist/esm/Options.js
|
|
21963
22219
|
var ignoreOverride = Symbol("Let zodToJsonSchema decide on which parser to use");
|
|
21964
|
-
//
|
|
22220
|
+
// node_modules/zod-to-json-schema/dist/esm/parsers/string.js
|
|
21965
22221
|
var ALPHA_NUMERIC = new Set("ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvxyz0123456789");
|
|
21966
|
-
//
|
|
22222
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js
|
|
21967
22223
|
function getMethodLiteral(schema2) {
|
|
21968
22224
|
const shape = getObjectShape(schema2);
|
|
21969
22225
|
const methodSchema = shape?.method;
|
|
@@ -21984,7 +22240,7 @@ function parseWithCompat(schema2, data) {
|
|
|
21984
22240
|
return result.data;
|
|
21985
22241
|
}
|
|
21986
22242
|
|
|
21987
|
-
//
|
|
22243
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
|
|
21988
22244
|
var DEFAULT_REQUEST_TIMEOUT_MSEC = 60000;
|
|
21989
22245
|
|
|
21990
22246
|
class Protocol {
|
|
@@ -22807,7 +23063,7 @@ function mergeCapabilities(base, additional) {
|
|
|
22807
23063
|
return result;
|
|
22808
23064
|
}
|
|
22809
23065
|
|
|
22810
|
-
//
|
|
23066
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js
|
|
22811
23067
|
var import_ajv = __toESM(require_ajv(), 1);
|
|
22812
23068
|
var import_ajv_formats = __toESM(require_dist2(), 1);
|
|
22813
23069
|
function createDefaultAjvInstance() {
|
|
@@ -22847,7 +23103,7 @@ class AjvJsonSchemaValidator {
|
|
|
22847
23103
|
}
|
|
22848
23104
|
}
|
|
22849
23105
|
|
|
22850
|
-
//
|
|
23106
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
|
|
22851
23107
|
class ExperimentalServerTasks {
|
|
22852
23108
|
constructor(_server) {
|
|
22853
23109
|
this._server = _server;
|
|
@@ -22869,7 +23125,7 @@ class ExperimentalServerTasks {
|
|
|
22869
23125
|
}
|
|
22870
23126
|
}
|
|
22871
23127
|
|
|
22872
|
-
//
|
|
23128
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
|
|
22873
23129
|
function assertToolsCallTaskCapability(requests, method, entityName) {
|
|
22874
23130
|
if (!requests) {
|
|
22875
23131
|
throw new Error(`${entityName} does not support task creation (required for ${method})`);
|
|
@@ -22904,7 +23160,7 @@ function assertClientRequestTaskCapability(requests, method, entityName) {
|
|
|
22904
23160
|
}
|
|
22905
23161
|
}
|
|
22906
23162
|
|
|
22907
|
-
//
|
|
23163
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
|
|
22908
23164
|
class Server extends Protocol {
|
|
22909
23165
|
constructor(_serverInfo, options) {
|
|
22910
23166
|
super(options);
|
|
@@ -23237,10 +23493,10 @@ class Server extends Protocol {
|
|
|
23237
23493
|
}
|
|
23238
23494
|
}
|
|
23239
23495
|
|
|
23240
|
-
//
|
|
23496
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
23241
23497
|
import process3 from "node:process";
|
|
23242
23498
|
|
|
23243
|
-
//
|
|
23499
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
|
|
23244
23500
|
class ReadBuffer {
|
|
23245
23501
|
append(chunk) {
|
|
23246
23502
|
this._buffer = this._buffer ? Buffer.concat([this._buffer, chunk]) : chunk;
|
|
@@ -23270,7 +23526,7 @@ function serializeMessage(message) {
|
|
|
23270
23526
|
`;
|
|
23271
23527
|
}
|
|
23272
23528
|
|
|
23273
|
-
//
|
|
23529
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
23274
23530
|
class StdioServerTransport {
|
|
23275
23531
|
constructor(_stdin = process3.stdin, _stdout = process3.stdout) {
|
|
23276
23532
|
this._stdin = _stdin;
|
|
@@ -23351,7 +23607,16 @@ async function handleToolCall(req, rootOpts, extra) {
|
|
|
23351
23607
|
}
|
|
23352
23608
|
try {
|
|
23353
23609
|
if (toolName === "list_issues") {
|
|
23354
|
-
const
|
|
23610
|
+
const orgId = args.org_id !== undefined ? Number(args.org_id) : cfg.orgId ?? undefined;
|
|
23611
|
+
const statusArg = args.status ? String(args.status) : undefined;
|
|
23612
|
+
let status;
|
|
23613
|
+
if (statusArg === "open")
|
|
23614
|
+
status = "open";
|
|
23615
|
+
else if (statusArg === "closed")
|
|
23616
|
+
status = "closed";
|
|
23617
|
+
const limit = args.limit !== undefined ? Number(args.limit) : undefined;
|
|
23618
|
+
const offset = args.offset !== undefined ? Number(args.offset) : undefined;
|
|
23619
|
+
const issues = await fetchIssues({ apiKey, apiBaseUrl, orgId, status, limit, offset, debug });
|
|
23355
23620
|
return { content: [{ type: "text", text: JSON.stringify(issues, null, 2) }] };
|
|
23356
23621
|
}
|
|
23357
23622
|
if (toolName === "view_issue") {
|
|
@@ -23431,6 +23696,70 @@ async function handleToolCall(req, rootOpts, extra) {
|
|
|
23431
23696
|
const result = await updateIssueComment({ apiKey, apiBaseUrl, commentId, content, debug });
|
|
23432
23697
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
23433
23698
|
}
|
|
23699
|
+
if (toolName === "view_action_item") {
|
|
23700
|
+
let actionItemIds;
|
|
23701
|
+
if (Array.isArray(args.action_item_ids)) {
|
|
23702
|
+
actionItemIds = args.action_item_ids.map((id) => String(id).trim()).filter((id) => id);
|
|
23703
|
+
} else if (args.action_item_id) {
|
|
23704
|
+
actionItemIds = [String(args.action_item_id).trim()];
|
|
23705
|
+
} else {
|
|
23706
|
+
actionItemIds = [];
|
|
23707
|
+
}
|
|
23708
|
+
if (actionItemIds.length === 0) {
|
|
23709
|
+
return { content: [{ type: "text", text: "action_item_id or action_item_ids is required" }], isError: true };
|
|
23710
|
+
}
|
|
23711
|
+
const actionItems = await fetchActionItem({ apiKey, apiBaseUrl, actionItemIds, debug });
|
|
23712
|
+
if (actionItems.length === 0) {
|
|
23713
|
+
return { content: [{ type: "text", text: "Action item(s) not found" }], isError: true };
|
|
23714
|
+
}
|
|
23715
|
+
return { content: [{ type: "text", text: JSON.stringify(actionItems, null, 2) }] };
|
|
23716
|
+
}
|
|
23717
|
+
if (toolName === "list_action_items") {
|
|
23718
|
+
const issueId = String(args.issue_id || "").trim();
|
|
23719
|
+
if (!issueId) {
|
|
23720
|
+
return { content: [{ type: "text", text: "issue_id is required" }], isError: true };
|
|
23721
|
+
}
|
|
23722
|
+
const actionItems = await fetchActionItems({ apiKey, apiBaseUrl, issueId, debug });
|
|
23723
|
+
return { content: [{ type: "text", text: JSON.stringify(actionItems, null, 2) }] };
|
|
23724
|
+
}
|
|
23725
|
+
if (toolName === "create_action_item") {
|
|
23726
|
+
const issueId = String(args.issue_id || "").trim();
|
|
23727
|
+
const rawTitle = String(args.title || "").trim();
|
|
23728
|
+
if (!issueId) {
|
|
23729
|
+
return { content: [{ type: "text", text: "issue_id is required" }], isError: true };
|
|
23730
|
+
}
|
|
23731
|
+
if (!rawTitle) {
|
|
23732
|
+
return { content: [{ type: "text", text: "title is required" }], isError: true };
|
|
23733
|
+
}
|
|
23734
|
+
const title = interpretEscapes(rawTitle);
|
|
23735
|
+
const rawDescription = args.description ? String(args.description) : undefined;
|
|
23736
|
+
const description = rawDescription ? interpretEscapes(rawDescription) : undefined;
|
|
23737
|
+
const sqlAction = args.sql_action !== undefined ? String(args.sql_action) : undefined;
|
|
23738
|
+
const configs = Array.isArray(args.configs) ? args.configs : undefined;
|
|
23739
|
+
const result = await createActionItem({ apiKey, apiBaseUrl, issueId, title, description, sqlAction, configs, debug });
|
|
23740
|
+
return { content: [{ type: "text", text: JSON.stringify({ id: result }, null, 2) }] };
|
|
23741
|
+
}
|
|
23742
|
+
if (toolName === "update_action_item") {
|
|
23743
|
+
const actionItemId = String(args.action_item_id || "").trim();
|
|
23744
|
+
if (!actionItemId) {
|
|
23745
|
+
return { content: [{ type: "text", text: "action_item_id is required" }], isError: true };
|
|
23746
|
+
}
|
|
23747
|
+
const rawTitle = args.title !== undefined ? String(args.title) : undefined;
|
|
23748
|
+
const title = rawTitle !== undefined ? interpretEscapes(rawTitle) : undefined;
|
|
23749
|
+
const rawDescription = args.description !== undefined ? String(args.description) : undefined;
|
|
23750
|
+
const description = rawDescription !== undefined ? interpretEscapes(rawDescription) : undefined;
|
|
23751
|
+
const isDone = args.is_done !== undefined ? Boolean(args.is_done) : undefined;
|
|
23752
|
+
const status = args.status !== undefined ? String(args.status) : undefined;
|
|
23753
|
+
const statusReason = args.status_reason !== undefined ? String(args.status_reason) : undefined;
|
|
23754
|
+
if (title === undefined && description === undefined && isDone === undefined && status === undefined && statusReason === undefined) {
|
|
23755
|
+
return { content: [{ type: "text", text: "At least one field to update is required (title, description, is_done, status, or status_reason)" }], isError: true };
|
|
23756
|
+
}
|
|
23757
|
+
if (status !== undefined && !["waiting_for_approval", "approved", "rejected"].includes(status)) {
|
|
23758
|
+
return { content: [{ type: "text", text: "status must be 'waiting_for_approval', 'approved', or 'rejected'" }], isError: true };
|
|
23759
|
+
}
|
|
23760
|
+
await updateActionItem({ apiKey, apiBaseUrl, actionItemId, title, description, isDone, status, statusReason, debug });
|
|
23761
|
+
return { content: [{ type: "text", text: JSON.stringify({ success: true }, null, 2) }] };
|
|
23762
|
+
}
|
|
23434
23763
|
throw new Error(`Unknown tool: ${toolName}`);
|
|
23435
23764
|
} catch (err) {
|
|
23436
23765
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -23438,7 +23767,11 @@ async function handleToolCall(req, rootOpts, extra) {
|
|
|
23438
23767
|
}
|
|
23439
23768
|
}
|
|
23440
23769
|
async function startMcpServer(rootOpts, extra) {
|
|
23441
|
-
const server = new Server({
|
|
23770
|
+
const server = new Server({
|
|
23771
|
+
name: "postgresai-mcp",
|
|
23772
|
+
version: package_default2.version,
|
|
23773
|
+
title: "PostgresAI MCP Server"
|
|
23774
|
+
}, { capabilities: { tools: {} } });
|
|
23442
23775
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
23443
23776
|
return {
|
|
23444
23777
|
tools: [
|
|
@@ -23448,6 +23781,10 @@ async function startMcpServer(rootOpts, extra) {
|
|
|
23448
23781
|
inputSchema: {
|
|
23449
23782
|
type: "object",
|
|
23450
23783
|
properties: {
|
|
23784
|
+
org_id: { type: "number", description: "Organization ID (optional, falls back to config)" },
|
|
23785
|
+
status: { type: "string", description: "Filter by status: 'open', 'closed', or omit for all" },
|
|
23786
|
+
limit: { type: "number", description: "Max number of issues to return (default: 20)" },
|
|
23787
|
+
offset: { type: "number", description: "Number of issues to skip (default: 0)" },
|
|
23451
23788
|
debug: { type: "boolean", description: "Enable verbose debug logs" }
|
|
23452
23789
|
},
|
|
23453
23790
|
additionalProperties: false
|
|
@@ -23536,47 +23873,130 @@ async function startMcpServer(rootOpts, extra) {
|
|
|
23536
23873
|
required: ["comment_id", "content"],
|
|
23537
23874
|
additionalProperties: false
|
|
23538
23875
|
}
|
|
23539
|
-
}
|
|
23540
|
-
|
|
23541
|
-
|
|
23542
|
-
|
|
23543
|
-
|
|
23544
|
-
|
|
23545
|
-
|
|
23546
|
-
|
|
23547
|
-
|
|
23548
|
-
}
|
|
23549
|
-
|
|
23550
|
-
|
|
23551
|
-
|
|
23552
|
-
|
|
23553
|
-
|
|
23554
|
-
|
|
23555
|
-
|
|
23556
|
-
|
|
23557
|
-
|
|
23558
|
-
|
|
23559
|
-
|
|
23560
|
-
|
|
23561
|
-
|
|
23562
|
-
|
|
23563
|
-
|
|
23564
|
-
|
|
23565
|
-
|
|
23566
|
-
|
|
23567
|
-
|
|
23568
|
-
|
|
23569
|
-
|
|
23570
|
-
|
|
23571
|
-
|
|
23572
|
-
|
|
23573
|
-
|
|
23574
|
-
|
|
23575
|
-
|
|
23576
|
-
|
|
23577
|
-
|
|
23578
|
-
|
|
23579
|
-
|
|
23876
|
+
},
|
|
23877
|
+
{
|
|
23878
|
+
name: "view_action_item",
|
|
23879
|
+
description: "View action item(s) with all details. Supports single ID or multiple IDs.",
|
|
23880
|
+
inputSchema: {
|
|
23881
|
+
type: "object",
|
|
23882
|
+
properties: {
|
|
23883
|
+
action_item_id: { type: "string", description: "Single action item ID (UUID)" },
|
|
23884
|
+
action_item_ids: { type: "array", items: { type: "string" }, description: "Multiple action item IDs (UUIDs)" },
|
|
23885
|
+
debug: { type: "boolean", description: "Enable verbose debug logs" }
|
|
23886
|
+
},
|
|
23887
|
+
additionalProperties: false
|
|
23888
|
+
}
|
|
23889
|
+
},
|
|
23890
|
+
{
|
|
23891
|
+
name: "list_action_items",
|
|
23892
|
+
description: "List action items for an issue",
|
|
23893
|
+
inputSchema: {
|
|
23894
|
+
type: "object",
|
|
23895
|
+
properties: {
|
|
23896
|
+
issue_id: { type: "string", description: "Issue ID (UUID)" },
|
|
23897
|
+
debug: { type: "boolean", description: "Enable verbose debug logs" }
|
|
23898
|
+
},
|
|
23899
|
+
required: ["issue_id"],
|
|
23900
|
+
additionalProperties: false
|
|
23901
|
+
}
|
|
23902
|
+
},
|
|
23903
|
+
{
|
|
23904
|
+
name: "create_action_item",
|
|
23905
|
+
description: "Create a new action item for an issue",
|
|
23906
|
+
inputSchema: {
|
|
23907
|
+
type: "object",
|
|
23908
|
+
properties: {
|
|
23909
|
+
issue_id: { type: "string", description: "Issue ID (UUID)" },
|
|
23910
|
+
title: { type: "string", description: "Action item title" },
|
|
23911
|
+
description: { type: "string", description: "Detailed description" },
|
|
23912
|
+
sql_action: { type: "string", description: "SQL command to execute, e.g. 'DROP INDEX CONCURRENTLY idx_unused;'" },
|
|
23913
|
+
configs: {
|
|
23914
|
+
type: "array",
|
|
23915
|
+
items: {
|
|
23916
|
+
type: "object",
|
|
23917
|
+
properties: {
|
|
23918
|
+
parameter: { type: "string" },
|
|
23919
|
+
value: { type: "string" }
|
|
23920
|
+
},
|
|
23921
|
+
required: ["parameter", "value"]
|
|
23922
|
+
},
|
|
23923
|
+
description: "Configuration parameter changes"
|
|
23924
|
+
},
|
|
23925
|
+
debug: { type: "boolean", description: "Enable verbose debug logs" }
|
|
23926
|
+
},
|
|
23927
|
+
required: ["issue_id", "title"],
|
|
23928
|
+
additionalProperties: false
|
|
23929
|
+
}
|
|
23930
|
+
},
|
|
23931
|
+
{
|
|
23932
|
+
name: "update_action_item",
|
|
23933
|
+
description: "Update an action item: mark as done/not done, approve/reject, or edit title/description",
|
|
23934
|
+
inputSchema: {
|
|
23935
|
+
type: "object",
|
|
23936
|
+
properties: {
|
|
23937
|
+
action_item_id: { type: "string", description: "Action item ID (UUID)" },
|
|
23938
|
+
title: { type: "string", description: "New title" },
|
|
23939
|
+
description: { type: "string", description: "New description" },
|
|
23940
|
+
is_done: { type: "boolean", description: "Mark as done (true) or not done (false)" },
|
|
23941
|
+
status: { type: "string", description: "Approval status: 'waiting_for_approval', 'approved', or 'rejected'" },
|
|
23942
|
+
status_reason: { type: "string", description: "Reason for approval/rejection" },
|
|
23943
|
+
debug: { type: "boolean", description: "Enable verbose debug logs" }
|
|
23944
|
+
},
|
|
23945
|
+
required: ["action_item_id"],
|
|
23946
|
+
additionalProperties: false
|
|
23947
|
+
}
|
|
23948
|
+
}
|
|
23949
|
+
]
|
|
23950
|
+
};
|
|
23951
|
+
});
|
|
23952
|
+
server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
23953
|
+
return handleToolCall(req, rootOpts, extra);
|
|
23954
|
+
});
|
|
23955
|
+
const transport = new StdioServerTransport;
|
|
23956
|
+
await server.connect(transport);
|
|
23957
|
+
}
|
|
23958
|
+
|
|
23959
|
+
// lib/issues.ts
|
|
23960
|
+
async function fetchIssues2(params) {
|
|
23961
|
+
const { apiKey, apiBaseUrl, orgId, status, limit = 20, offset = 0, debug } = params;
|
|
23962
|
+
if (!apiKey) {
|
|
23963
|
+
throw new Error("API key is required");
|
|
23964
|
+
}
|
|
23965
|
+
const base = normalizeBaseUrl(apiBaseUrl);
|
|
23966
|
+
const url = new URL(`${base}/issues`);
|
|
23967
|
+
url.searchParams.set("select", "id,title,status,created_at");
|
|
23968
|
+
url.searchParams.set("order", "id.desc");
|
|
23969
|
+
url.searchParams.set("limit", String(limit));
|
|
23970
|
+
url.searchParams.set("offset", String(offset));
|
|
23971
|
+
if (typeof orgId === "number") {
|
|
23972
|
+
url.searchParams.set("org_id", `eq.${orgId}`);
|
|
23973
|
+
}
|
|
23974
|
+
if (status === "open") {
|
|
23975
|
+
url.searchParams.set("status", "eq.0");
|
|
23976
|
+
} else if (status === "closed") {
|
|
23977
|
+
url.searchParams.set("status", "eq.1");
|
|
23978
|
+
}
|
|
23979
|
+
const headers = {
|
|
23980
|
+
"access-token": apiKey,
|
|
23981
|
+
Prefer: "return=representation",
|
|
23982
|
+
"Content-Type": "application/json",
|
|
23983
|
+
Connection: "close"
|
|
23984
|
+
};
|
|
23985
|
+
if (debug) {
|
|
23986
|
+
const debugHeaders = { ...headers, "access-token": maskSecret(apiKey) };
|
|
23987
|
+
console.log(`Debug: Resolved API base URL: ${base}`);
|
|
23988
|
+
console.log(`Debug: GET URL: ${url.toString()}`);
|
|
23989
|
+
console.log(`Debug: Auth scheme: access-token`);
|
|
23990
|
+
console.log(`Debug: Request headers: ${JSON.stringify(debugHeaders)}`);
|
|
23991
|
+
}
|
|
23992
|
+
const response = await fetch(url.toString(), {
|
|
23993
|
+
method: "GET",
|
|
23994
|
+
headers
|
|
23995
|
+
});
|
|
23996
|
+
if (debug) {
|
|
23997
|
+
console.log(`Debug: Response status: ${response.status}`);
|
|
23998
|
+
console.log(`Debug: Response headers: ${JSON.stringify(Object.fromEntries(response.headers.entries()))}`);
|
|
23999
|
+
}
|
|
23580
24000
|
const data = await response.text();
|
|
23581
24001
|
if (response.ok) {
|
|
23582
24002
|
try {
|
|
@@ -23640,7 +24060,7 @@ async function fetchIssue2(params) {
|
|
|
23640
24060
|
}
|
|
23641
24061
|
const base = normalizeBaseUrl(apiBaseUrl);
|
|
23642
24062
|
const url = new URL(`${base}/issues`);
|
|
23643
|
-
url.searchParams.set("select", "id,title,description,status,created_at,author_display_name");
|
|
24063
|
+
url.searchParams.set("select", "id,title,description,status,created_at,author_display_name,action_items");
|
|
23644
24064
|
url.searchParams.set("id", `eq.${issueId}`);
|
|
23645
24065
|
url.searchParams.set("limit", "1");
|
|
23646
24066
|
const headers = {
|
|
@@ -23668,11 +24088,20 @@ async function fetchIssue2(params) {
|
|
|
23668
24088
|
if (response.ok) {
|
|
23669
24089
|
try {
|
|
23670
24090
|
const parsed = JSON.parse(data);
|
|
23671
|
-
|
|
23672
|
-
|
|
23673
|
-
|
|
23674
|
-
return parsed;
|
|
24091
|
+
const rawIssue = Array.isArray(parsed) ? parsed[0] : parsed;
|
|
24092
|
+
if (!rawIssue) {
|
|
24093
|
+
return null;
|
|
23675
24094
|
}
|
|
24095
|
+
const actionItemsSummary = Array.isArray(rawIssue.action_items) ? rawIssue.action_items.map((item) => ({ id: item.id, title: item.title })) : [];
|
|
24096
|
+
return {
|
|
24097
|
+
id: rawIssue.id,
|
|
24098
|
+
title: rawIssue.title,
|
|
24099
|
+
description: rawIssue.description,
|
|
24100
|
+
status: rawIssue.status,
|
|
24101
|
+
created_at: rawIssue.created_at,
|
|
24102
|
+
author_display_name: rawIssue.author_display_name,
|
|
24103
|
+
action_items: actionItemsSummary
|
|
24104
|
+
};
|
|
23676
24105
|
} catch {
|
|
23677
24106
|
throw new Error(`Failed to parse issue response: ${data}`);
|
|
23678
24107
|
}
|
|
@@ -23911,6 +24340,243 @@ async function updateIssueComment2(params) {
|
|
|
23911
24340
|
throw new Error(formatHttpError("Failed to update issue comment", response.status, data));
|
|
23912
24341
|
}
|
|
23913
24342
|
}
|
|
24343
|
+
async function fetchActionItem2(params) {
|
|
24344
|
+
const { apiKey, apiBaseUrl, actionItemIds, debug } = params;
|
|
24345
|
+
if (!apiKey) {
|
|
24346
|
+
throw new Error("API key is required");
|
|
24347
|
+
}
|
|
24348
|
+
const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
24349
|
+
const rawIds = Array.isArray(actionItemIds) ? actionItemIds : [actionItemIds];
|
|
24350
|
+
const validIds = rawIds.filter((id) => id != null && typeof id === "string").map((id) => id.trim()).filter((id) => id.length > 0 && uuidPattern.test(id));
|
|
24351
|
+
if (validIds.length === 0) {
|
|
24352
|
+
throw new Error("actionItemId is required and must be a valid UUID");
|
|
24353
|
+
}
|
|
24354
|
+
const base = normalizeBaseUrl(apiBaseUrl);
|
|
24355
|
+
const url = new URL(`${base}/issue_action_items`);
|
|
24356
|
+
if (validIds.length === 1) {
|
|
24357
|
+
url.searchParams.set("id", `eq.${validIds[0]}`);
|
|
24358
|
+
} else {
|
|
24359
|
+
url.searchParams.set("id", `in.(${validIds.join(",")})`);
|
|
24360
|
+
}
|
|
24361
|
+
const headers = {
|
|
24362
|
+
"access-token": apiKey,
|
|
24363
|
+
Prefer: "return=representation",
|
|
24364
|
+
"Content-Type": "application/json",
|
|
24365
|
+
Connection: "close"
|
|
24366
|
+
};
|
|
24367
|
+
if (debug) {
|
|
24368
|
+
const debugHeaders = { ...headers, "access-token": maskSecret(apiKey) };
|
|
24369
|
+
console.log(`Debug: Resolved API base URL: ${base}`);
|
|
24370
|
+
console.log(`Debug: GET URL: ${url.toString()}`);
|
|
24371
|
+
console.log(`Debug: Auth scheme: access-token`);
|
|
24372
|
+
console.log(`Debug: Request headers: ${JSON.stringify(debugHeaders)}`);
|
|
24373
|
+
}
|
|
24374
|
+
const response = await fetch(url.toString(), {
|
|
24375
|
+
method: "GET",
|
|
24376
|
+
headers
|
|
24377
|
+
});
|
|
24378
|
+
if (debug) {
|
|
24379
|
+
console.log(`Debug: Response status: ${response.status}`);
|
|
24380
|
+
console.log(`Debug: Response headers: ${JSON.stringify(Object.fromEntries(response.headers.entries()))}`);
|
|
24381
|
+
}
|
|
24382
|
+
const data = await response.text();
|
|
24383
|
+
if (response.ok) {
|
|
24384
|
+
try {
|
|
24385
|
+
const parsed = JSON.parse(data);
|
|
24386
|
+
if (Array.isArray(parsed)) {
|
|
24387
|
+
return parsed;
|
|
24388
|
+
}
|
|
24389
|
+
return parsed ? [parsed] : [];
|
|
24390
|
+
} catch {
|
|
24391
|
+
throw new Error(`Failed to parse action item response: ${data}`);
|
|
24392
|
+
}
|
|
24393
|
+
} else {
|
|
24394
|
+
throw new Error(formatHttpError("Failed to fetch action item", response.status, data));
|
|
24395
|
+
}
|
|
24396
|
+
}
|
|
24397
|
+
async function fetchActionItems2(params) {
|
|
24398
|
+
const { apiKey, apiBaseUrl, issueId, debug } = params;
|
|
24399
|
+
if (!apiKey) {
|
|
24400
|
+
throw new Error("API key is required");
|
|
24401
|
+
}
|
|
24402
|
+
if (!issueId) {
|
|
24403
|
+
throw new Error("issueId is required");
|
|
24404
|
+
}
|
|
24405
|
+
const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
24406
|
+
if (!uuidPattern.test(issueId.trim())) {
|
|
24407
|
+
throw new Error("issueId must be a valid UUID");
|
|
24408
|
+
}
|
|
24409
|
+
const base = normalizeBaseUrl(apiBaseUrl);
|
|
24410
|
+
const url = new URL(`${base}/issue_action_items`);
|
|
24411
|
+
url.searchParams.set("issue_id", `eq.${issueId.trim()}`);
|
|
24412
|
+
const headers = {
|
|
24413
|
+
"access-token": apiKey,
|
|
24414
|
+
Prefer: "return=representation",
|
|
24415
|
+
"Content-Type": "application/json",
|
|
24416
|
+
Connection: "close"
|
|
24417
|
+
};
|
|
24418
|
+
if (debug) {
|
|
24419
|
+
const debugHeaders = { ...headers, "access-token": maskSecret(apiKey) };
|
|
24420
|
+
console.log(`Debug: Resolved API base URL: ${base}`);
|
|
24421
|
+
console.log(`Debug: GET URL: ${url.toString()}`);
|
|
24422
|
+
console.log(`Debug: Auth scheme: access-token`);
|
|
24423
|
+
console.log(`Debug: Request headers: ${JSON.stringify(debugHeaders)}`);
|
|
24424
|
+
}
|
|
24425
|
+
const response = await fetch(url.toString(), {
|
|
24426
|
+
method: "GET",
|
|
24427
|
+
headers
|
|
24428
|
+
});
|
|
24429
|
+
if (debug) {
|
|
24430
|
+
console.log(`Debug: Response status: ${response.status}`);
|
|
24431
|
+
console.log(`Debug: Response headers: ${JSON.stringify(Object.fromEntries(response.headers.entries()))}`);
|
|
24432
|
+
}
|
|
24433
|
+
const data = await response.text();
|
|
24434
|
+
if (response.ok) {
|
|
24435
|
+
try {
|
|
24436
|
+
return JSON.parse(data);
|
|
24437
|
+
} catch {
|
|
24438
|
+
throw new Error(`Failed to parse action items response: ${data}`);
|
|
24439
|
+
}
|
|
24440
|
+
} else {
|
|
24441
|
+
throw new Error(formatHttpError("Failed to fetch action items", response.status, data));
|
|
24442
|
+
}
|
|
24443
|
+
}
|
|
24444
|
+
async function createActionItem2(params) {
|
|
24445
|
+
const { apiKey, apiBaseUrl, issueId, title, description, sqlAction, configs, debug } = params;
|
|
24446
|
+
if (!apiKey) {
|
|
24447
|
+
throw new Error("API key is required");
|
|
24448
|
+
}
|
|
24449
|
+
if (!issueId) {
|
|
24450
|
+
throw new Error("issueId is required");
|
|
24451
|
+
}
|
|
24452
|
+
const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
24453
|
+
if (!uuidPattern.test(issueId.trim())) {
|
|
24454
|
+
throw new Error("issueId must be a valid UUID");
|
|
24455
|
+
}
|
|
24456
|
+
if (!title) {
|
|
24457
|
+
throw new Error("title is required");
|
|
24458
|
+
}
|
|
24459
|
+
const base = normalizeBaseUrl(apiBaseUrl);
|
|
24460
|
+
const url = new URL(`${base}/rpc/issue_action_item_create`);
|
|
24461
|
+
const bodyObj = {
|
|
24462
|
+
issue_id: issueId,
|
|
24463
|
+
title
|
|
24464
|
+
};
|
|
24465
|
+
if (description !== undefined) {
|
|
24466
|
+
bodyObj.description = description;
|
|
24467
|
+
}
|
|
24468
|
+
if (sqlAction !== undefined) {
|
|
24469
|
+
bodyObj.sql_action = sqlAction;
|
|
24470
|
+
}
|
|
24471
|
+
if (configs !== undefined) {
|
|
24472
|
+
bodyObj.configs = configs;
|
|
24473
|
+
}
|
|
24474
|
+
const body = JSON.stringify(bodyObj);
|
|
24475
|
+
const headers = {
|
|
24476
|
+
"access-token": apiKey,
|
|
24477
|
+
Prefer: "return=representation",
|
|
24478
|
+
"Content-Type": "application/json",
|
|
24479
|
+
Connection: "close"
|
|
24480
|
+
};
|
|
24481
|
+
if (debug) {
|
|
24482
|
+
const debugHeaders = { ...headers, "access-token": maskSecret(apiKey) };
|
|
24483
|
+
console.log(`Debug: Resolved API base URL: ${base}`);
|
|
24484
|
+
console.log(`Debug: POST URL: ${url.toString()}`);
|
|
24485
|
+
console.log(`Debug: Auth scheme: access-token`);
|
|
24486
|
+
console.log(`Debug: Request headers: ${JSON.stringify(debugHeaders)}`);
|
|
24487
|
+
console.log(`Debug: Request body: ${body}`);
|
|
24488
|
+
}
|
|
24489
|
+
const response = await fetch(url.toString(), {
|
|
24490
|
+
method: "POST",
|
|
24491
|
+
headers,
|
|
24492
|
+
body
|
|
24493
|
+
});
|
|
24494
|
+
if (debug) {
|
|
24495
|
+
console.log(`Debug: Response status: ${response.status}`);
|
|
24496
|
+
console.log(`Debug: Response headers: ${JSON.stringify(Object.fromEntries(response.headers.entries()))}`);
|
|
24497
|
+
}
|
|
24498
|
+
const data = await response.text();
|
|
24499
|
+
if (response.ok) {
|
|
24500
|
+
try {
|
|
24501
|
+
return JSON.parse(data);
|
|
24502
|
+
} catch {
|
|
24503
|
+
throw new Error(`Failed to parse create action item response: ${data}`);
|
|
24504
|
+
}
|
|
24505
|
+
} else {
|
|
24506
|
+
throw new Error(formatHttpError("Failed to create action item", response.status, data));
|
|
24507
|
+
}
|
|
24508
|
+
}
|
|
24509
|
+
async function updateActionItem2(params) {
|
|
24510
|
+
const { apiKey, apiBaseUrl, actionItemId, title, description, isDone, status, statusReason, sqlAction, configs, debug } = params;
|
|
24511
|
+
if (!apiKey) {
|
|
24512
|
+
throw new Error("API key is required");
|
|
24513
|
+
}
|
|
24514
|
+
if (!actionItemId) {
|
|
24515
|
+
throw new Error("actionItemId is required");
|
|
24516
|
+
}
|
|
24517
|
+
const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
24518
|
+
if (!uuidPattern.test(actionItemId.trim())) {
|
|
24519
|
+
throw new Error("actionItemId must be a valid UUID");
|
|
24520
|
+
}
|
|
24521
|
+
const hasUpdateField = title !== undefined || description !== undefined || isDone !== undefined || status !== undefined || statusReason !== undefined || sqlAction !== undefined || configs !== undefined;
|
|
24522
|
+
if (!hasUpdateField) {
|
|
24523
|
+
throw new Error("At least one field to update is required");
|
|
24524
|
+
}
|
|
24525
|
+
const base = normalizeBaseUrl(apiBaseUrl);
|
|
24526
|
+
const url = new URL(`${base}/rpc/issue_action_item_update`);
|
|
24527
|
+
const bodyObj = {
|
|
24528
|
+
action_item_id: actionItemId
|
|
24529
|
+
};
|
|
24530
|
+
if (title !== undefined) {
|
|
24531
|
+
bodyObj.title = title;
|
|
24532
|
+
}
|
|
24533
|
+
if (description !== undefined) {
|
|
24534
|
+
bodyObj.description = description;
|
|
24535
|
+
}
|
|
24536
|
+
if (isDone !== undefined) {
|
|
24537
|
+
bodyObj.is_done = isDone;
|
|
24538
|
+
}
|
|
24539
|
+
if (status !== undefined) {
|
|
24540
|
+
bodyObj.status = status;
|
|
24541
|
+
}
|
|
24542
|
+
if (statusReason !== undefined) {
|
|
24543
|
+
bodyObj.status_reason = statusReason;
|
|
24544
|
+
}
|
|
24545
|
+
if (sqlAction !== undefined) {
|
|
24546
|
+
bodyObj.sql_action = sqlAction;
|
|
24547
|
+
}
|
|
24548
|
+
if (configs !== undefined) {
|
|
24549
|
+
bodyObj.configs = configs;
|
|
24550
|
+
}
|
|
24551
|
+
const body = JSON.stringify(bodyObj);
|
|
24552
|
+
const headers = {
|
|
24553
|
+
"access-token": apiKey,
|
|
24554
|
+
Prefer: "return=representation",
|
|
24555
|
+
"Content-Type": "application/json",
|
|
24556
|
+
Connection: "close"
|
|
24557
|
+
};
|
|
24558
|
+
if (debug) {
|
|
24559
|
+
const debugHeaders = { ...headers, "access-token": maskSecret(apiKey) };
|
|
24560
|
+
console.log(`Debug: Resolved API base URL: ${base}`);
|
|
24561
|
+
console.log(`Debug: POST URL: ${url.toString()}`);
|
|
24562
|
+
console.log(`Debug: Auth scheme: access-token`);
|
|
24563
|
+
console.log(`Debug: Request headers: ${JSON.stringify(debugHeaders)}`);
|
|
24564
|
+
console.log(`Debug: Request body: ${body}`);
|
|
24565
|
+
}
|
|
24566
|
+
const response = await fetch(url.toString(), {
|
|
24567
|
+
method: "POST",
|
|
24568
|
+
headers,
|
|
24569
|
+
body
|
|
24570
|
+
});
|
|
24571
|
+
if (debug) {
|
|
24572
|
+
console.log(`Debug: Response status: ${response.status}`);
|
|
24573
|
+
console.log(`Debug: Response headers: ${JSON.stringify(Object.fromEntries(response.headers.entries()))}`);
|
|
24574
|
+
}
|
|
24575
|
+
if (!response.ok) {
|
|
24576
|
+
const data = await response.text();
|
|
24577
|
+
throw new Error(formatHttpError("Failed to update action item", response.status, data));
|
|
24578
|
+
}
|
|
24579
|
+
}
|
|
23914
24580
|
|
|
23915
24581
|
// lib/util.ts
|
|
23916
24582
|
function maskSecret2(secret) {
|
|
@@ -23948,6 +24614,15 @@ import { URL as URL2, fileURLToPath } from "url";
|
|
|
23948
24614
|
import * as fs3 from "fs";
|
|
23949
24615
|
import * as path3 from "path";
|
|
23950
24616
|
var DEFAULT_MONITORING_USER = "postgres_ai_mon";
|
|
24617
|
+
var KNOWN_PROVIDERS = ["self-managed", "supabase"];
|
|
24618
|
+
var SKIP_ROLE_CREATION_PROVIDERS = ["supabase"];
|
|
24619
|
+
var SKIP_ALTER_USER_PROVIDERS = ["supabase"];
|
|
24620
|
+
var SKIP_SEARCH_PATH_CHECK_PROVIDERS = ["supabase"];
|
|
24621
|
+
function validateProvider(provider) {
|
|
24622
|
+
if (!provider || KNOWN_PROVIDERS.includes(provider))
|
|
24623
|
+
return null;
|
|
24624
|
+
return `Unknown provider "${provider}". Known providers: ${KNOWN_PROVIDERS.join(", ")}. Treating as self-managed.`;
|
|
24625
|
+
}
|
|
23951
24626
|
function sslModeToConfig(mode) {
|
|
23952
24627
|
if (mode.toLowerCase() === "disable")
|
|
23953
24628
|
return false;
|
|
@@ -24262,6 +24937,7 @@ async function resolveMonitoringPassword(opts) {
|
|
|
24262
24937
|
async function buildInitPlan(params) {
|
|
24263
24938
|
const monitoringUser = params.monitoringUser || DEFAULT_MONITORING_USER;
|
|
24264
24939
|
const database = params.database;
|
|
24940
|
+
const provider = params.provider ?? "self-managed";
|
|
24265
24941
|
const qRole = quoteIdent(monitoringUser);
|
|
24266
24942
|
const qDb = quoteIdent(database);
|
|
24267
24943
|
const qPw = quoteLiteral(params.monitoringPassword);
|
|
@@ -24271,7 +24947,8 @@ async function buildInitPlan(params) {
|
|
|
24271
24947
|
ROLE_IDENT: qRole,
|
|
24272
24948
|
DB_IDENT: qDb
|
|
24273
24949
|
};
|
|
24274
|
-
|
|
24950
|
+
if (!SKIP_ROLE_CREATION_PROVIDERS.includes(provider)) {
|
|
24951
|
+
const roleStmt = `do $$ begin
|
|
24275
24952
|
if not exists (select 1 from pg_catalog.pg_roles where rolname = ${qRoleNameLit}) then
|
|
24276
24953
|
begin
|
|
24277
24954
|
create user ${qRole} with password ${qPw};
|
|
@@ -24281,11 +24958,23 @@ async function buildInitPlan(params) {
|
|
|
24281
24958
|
end if;
|
|
24282
24959
|
alter user ${qRole} with password ${qPw};
|
|
24283
24960
|
end $$;`;
|
|
24284
|
-
|
|
24285
|
-
|
|
24961
|
+
const roleSql = applyTemplate(loadSqlTemplate("01.role.sql"), { ...vars, ROLE_STMT: roleStmt });
|
|
24962
|
+
steps.push({ name: "01.role", sql: roleSql });
|
|
24963
|
+
}
|
|
24964
|
+
let permissionsSql = applyTemplate(loadSqlTemplate("02.permissions.sql"), vars);
|
|
24965
|
+
if (SKIP_ALTER_USER_PROVIDERS.includes(provider)) {
|
|
24966
|
+
permissionsSql = permissionsSql.split(`
|
|
24967
|
+
`).filter((line) => {
|
|
24968
|
+
const trimmed = line.trim();
|
|
24969
|
+
if (trimmed.startsWith("--") || trimmed === "")
|
|
24970
|
+
return true;
|
|
24971
|
+
return !/^\s*alter\s+user\s+/i.test(line);
|
|
24972
|
+
}).join(`
|
|
24973
|
+
`);
|
|
24974
|
+
}
|
|
24286
24975
|
steps.push({
|
|
24287
24976
|
name: "02.permissions",
|
|
24288
|
-
sql:
|
|
24977
|
+
sql: permissionsSql
|
|
24289
24978
|
});
|
|
24290
24979
|
steps.push({
|
|
24291
24980
|
name: "05.helpers",
|
|
@@ -24302,25 +24991,413 @@ end $$;`;
|
|
|
24302
24991
|
optional: true
|
|
24303
24992
|
});
|
|
24304
24993
|
}
|
|
24305
|
-
return { monitoringUser, database, steps };
|
|
24994
|
+
return { monitoringUser, database, steps };
|
|
24995
|
+
}
|
|
24996
|
+
async function applyInitPlan(params) {
|
|
24997
|
+
const applied = [];
|
|
24998
|
+
const skippedOptional = [];
|
|
24999
|
+
const executeStep = async (step) => {
|
|
25000
|
+
await params.client.query("begin;");
|
|
25001
|
+
try {
|
|
25002
|
+
await params.client.query(step.sql, step.params);
|
|
25003
|
+
await params.client.query("commit;");
|
|
25004
|
+
} catch (e) {
|
|
25005
|
+
try {
|
|
25006
|
+
await params.client.query("rollback;");
|
|
25007
|
+
} catch {}
|
|
25008
|
+
throw e;
|
|
25009
|
+
}
|
|
25010
|
+
};
|
|
25011
|
+
for (const step of params.plan.steps.filter((s) => !s.optional)) {
|
|
25012
|
+
try {
|
|
25013
|
+
await executeStep(step);
|
|
25014
|
+
applied.push(step.name);
|
|
25015
|
+
} catch (e) {
|
|
25016
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
25017
|
+
const errAny = e;
|
|
25018
|
+
const wrapped = new Error(`Failed at step "${step.name}": ${msg}`);
|
|
25019
|
+
const pgErrorFields = [
|
|
25020
|
+
"code",
|
|
25021
|
+
"detail",
|
|
25022
|
+
"hint",
|
|
25023
|
+
"position",
|
|
25024
|
+
"internalPosition",
|
|
25025
|
+
"internalQuery",
|
|
25026
|
+
"where",
|
|
25027
|
+
"schema",
|
|
25028
|
+
"table",
|
|
25029
|
+
"column",
|
|
25030
|
+
"dataType",
|
|
25031
|
+
"constraint",
|
|
25032
|
+
"file",
|
|
25033
|
+
"line",
|
|
25034
|
+
"routine"
|
|
25035
|
+
];
|
|
25036
|
+
if (errAny && typeof errAny === "object") {
|
|
25037
|
+
for (const field of pgErrorFields) {
|
|
25038
|
+
if (errAny[field] !== undefined)
|
|
25039
|
+
wrapped[field] = errAny[field];
|
|
25040
|
+
}
|
|
25041
|
+
}
|
|
25042
|
+
if (e instanceof Error && e.stack) {
|
|
25043
|
+
wrapped.stack = e.stack;
|
|
25044
|
+
}
|
|
25045
|
+
throw wrapped;
|
|
25046
|
+
}
|
|
25047
|
+
}
|
|
25048
|
+
for (const step of params.plan.steps.filter((s) => s.optional)) {
|
|
25049
|
+
try {
|
|
25050
|
+
await executeStep(step);
|
|
25051
|
+
applied.push(step.name);
|
|
25052
|
+
} catch {
|
|
25053
|
+
skippedOptional.push(step.name);
|
|
25054
|
+
}
|
|
25055
|
+
}
|
|
25056
|
+
return { applied, skippedOptional };
|
|
25057
|
+
}
|
|
25058
|
+
async function verifyInitSetup(params) {
|
|
25059
|
+
await params.client.query("begin isolation level repeatable read;");
|
|
25060
|
+
try {
|
|
25061
|
+
const missingRequired = [];
|
|
25062
|
+
const missingOptional = [];
|
|
25063
|
+
const role = params.monitoringUser;
|
|
25064
|
+
const db = params.database;
|
|
25065
|
+
const provider = params.provider ?? "self-managed";
|
|
25066
|
+
const roleRes = await params.client.query("select 1 from pg_catalog.pg_roles where rolname = $1", [role]);
|
|
25067
|
+
const roleExists = (roleRes.rowCount ?? 0) > 0;
|
|
25068
|
+
if (!roleExists) {
|
|
25069
|
+
missingRequired.push(`role "${role}" does not exist`);
|
|
25070
|
+
return { ok: false, missingRequired, missingOptional };
|
|
25071
|
+
}
|
|
25072
|
+
const connectRes = await params.client.query("select has_database_privilege($1, $2, 'CONNECT') as ok", [role, db]);
|
|
25073
|
+
if (!connectRes.rows?.[0]?.ok) {
|
|
25074
|
+
missingRequired.push(`CONNECT on database "${db}"`);
|
|
25075
|
+
}
|
|
25076
|
+
const pgMonitorRes = await params.client.query("select pg_has_role($1, 'pg_monitor', 'member') as ok", [role]);
|
|
25077
|
+
if (!pgMonitorRes.rows?.[0]?.ok) {
|
|
25078
|
+
missingRequired.push("membership in role pg_monitor");
|
|
25079
|
+
}
|
|
25080
|
+
const pgIndexRes = await params.client.query("select has_table_privilege($1, 'pg_catalog.pg_index', 'SELECT') as ok", [role]);
|
|
25081
|
+
if (!pgIndexRes.rows?.[0]?.ok) {
|
|
25082
|
+
missingRequired.push("SELECT on pg_catalog.pg_index");
|
|
25083
|
+
}
|
|
25084
|
+
const schemaExistsRes = await params.client.query("select has_schema_privilege($1, 'postgres_ai', 'USAGE') as ok", [role]);
|
|
25085
|
+
if (!schemaExistsRes.rows?.[0]?.ok) {
|
|
25086
|
+
missingRequired.push("USAGE on schema postgres_ai");
|
|
25087
|
+
}
|
|
25088
|
+
const viewExistsRes = await params.client.query("select to_regclass('postgres_ai.pg_statistic') is not null as ok");
|
|
25089
|
+
if (!viewExistsRes.rows?.[0]?.ok) {
|
|
25090
|
+
missingRequired.push("view postgres_ai.pg_statistic exists");
|
|
25091
|
+
} else {
|
|
25092
|
+
const viewPrivRes = await params.client.query("select has_table_privilege($1, 'postgres_ai.pg_statistic', 'SELECT') as ok", [role]);
|
|
25093
|
+
if (!viewPrivRes.rows?.[0]?.ok) {
|
|
25094
|
+
missingRequired.push("SELECT on view postgres_ai.pg_statistic");
|
|
25095
|
+
}
|
|
25096
|
+
}
|
|
25097
|
+
const schemaUsageRes = await params.client.query("select has_schema_privilege($1, 'public', 'USAGE') as ok", [role]);
|
|
25098
|
+
if (!schemaUsageRes.rows?.[0]?.ok) {
|
|
25099
|
+
missingRequired.push("USAGE on schema public");
|
|
25100
|
+
}
|
|
25101
|
+
if (!SKIP_SEARCH_PATH_CHECK_PROVIDERS.includes(provider)) {
|
|
25102
|
+
const rolcfgRes = await params.client.query("select rolconfig from pg_catalog.pg_roles where rolname = $1", [role]);
|
|
25103
|
+
const rolconfig = rolcfgRes.rows?.[0]?.rolconfig;
|
|
25104
|
+
const spLine = Array.isArray(rolconfig) ? rolconfig.find((v) => String(v).startsWith("search_path=")) : undefined;
|
|
25105
|
+
if (typeof spLine !== "string" || !spLine) {
|
|
25106
|
+
missingRequired.push("role search_path is set");
|
|
25107
|
+
} else {
|
|
25108
|
+
const sp = spLine.toLowerCase();
|
|
25109
|
+
if (!sp.includes("postgres_ai") || !sp.includes("public") || !sp.includes("pg_catalog")) {
|
|
25110
|
+
missingRequired.push("role search_path includes postgres_ai, public and pg_catalog");
|
|
25111
|
+
}
|
|
25112
|
+
}
|
|
25113
|
+
}
|
|
25114
|
+
const explainFnRes = await params.client.query("select has_function_privilege($1, 'postgres_ai.explain_generic(text, text, text)', 'EXECUTE') as ok", [role]);
|
|
25115
|
+
if (!explainFnRes.rows?.[0]?.ok) {
|
|
25116
|
+
missingRequired.push("EXECUTE on postgres_ai.explain_generic(text, text, text)");
|
|
25117
|
+
}
|
|
25118
|
+
const tableDescribeFnRes = await params.client.query("select has_function_privilege($1, 'postgres_ai.table_describe(text)', 'EXECUTE') as ok", [role]);
|
|
25119
|
+
if (!tableDescribeFnRes.rows?.[0]?.ok) {
|
|
25120
|
+
missingRequired.push("EXECUTE on postgres_ai.table_describe(text)");
|
|
25121
|
+
}
|
|
25122
|
+
if (params.includeOptionalPermissions) {
|
|
25123
|
+
{
|
|
25124
|
+
const extRes = await params.client.query("select 1 from pg_extension where extname = 'rds_tools'");
|
|
25125
|
+
if ((extRes.rowCount ?? 0) === 0) {
|
|
25126
|
+
missingOptional.push("extension rds_tools");
|
|
25127
|
+
} else {
|
|
25128
|
+
const fnRes = await params.client.query("select has_function_privilege($1, 'rds_tools.pg_ls_multixactdir()', 'EXECUTE') as ok", [role]);
|
|
25129
|
+
if (!fnRes.rows?.[0]?.ok) {
|
|
25130
|
+
missingOptional.push("EXECUTE on rds_tools.pg_ls_multixactdir()");
|
|
25131
|
+
}
|
|
25132
|
+
}
|
|
25133
|
+
}
|
|
25134
|
+
const optionalFns = [
|
|
25135
|
+
"pg_catalog.pg_stat_file(text)",
|
|
25136
|
+
"pg_catalog.pg_stat_file(text, boolean)",
|
|
25137
|
+
"pg_catalog.pg_ls_dir(text)",
|
|
25138
|
+
"pg_catalog.pg_ls_dir(text, boolean, boolean)"
|
|
25139
|
+
];
|
|
25140
|
+
for (const fn of optionalFns) {
|
|
25141
|
+
const fnRes = await params.client.query("select has_function_privilege($1, $2, 'EXECUTE') as ok", [role, fn]);
|
|
25142
|
+
if (!fnRes.rows?.[0]?.ok) {
|
|
25143
|
+
missingOptional.push(`EXECUTE on ${fn}`);
|
|
25144
|
+
}
|
|
25145
|
+
}
|
|
25146
|
+
}
|
|
25147
|
+
return { ok: missingRequired.length === 0, missingRequired, missingOptional };
|
|
25148
|
+
} finally {
|
|
25149
|
+
try {
|
|
25150
|
+
await params.client.query("rollback;");
|
|
25151
|
+
} catch {}
|
|
25152
|
+
}
|
|
25153
|
+
}
|
|
25154
|
+
|
|
25155
|
+
// lib/supabase.ts
|
|
25156
|
+
var SUPABASE_API_BASE = "https://api.supabase.com";
|
|
25157
|
+
function isValidProjectRef(ref) {
|
|
25158
|
+
return /^[a-z0-9]{10,30}$/i.test(ref);
|
|
25159
|
+
}
|
|
25160
|
+
|
|
25161
|
+
class SupabaseClient {
|
|
25162
|
+
config;
|
|
25163
|
+
constructor(config2) {
|
|
25164
|
+
if (!config2.projectRef) {
|
|
25165
|
+
throw new Error("Supabase project reference is required");
|
|
25166
|
+
}
|
|
25167
|
+
if (!config2.accessToken) {
|
|
25168
|
+
throw new Error("Supabase access token is required");
|
|
25169
|
+
}
|
|
25170
|
+
if (!isValidProjectRef(config2.projectRef)) {
|
|
25171
|
+
throw new Error(`Invalid Supabase project reference format: "${config2.projectRef}". Expected 10-30 alphanumeric characters.`);
|
|
25172
|
+
}
|
|
25173
|
+
this.config = config2;
|
|
25174
|
+
}
|
|
25175
|
+
async query(sql, readOnly = false) {
|
|
25176
|
+
const url = `${SUPABASE_API_BASE}/v1/projects/${encodeURIComponent(this.config.projectRef)}/database/query`;
|
|
25177
|
+
const response = await fetch(url, {
|
|
25178
|
+
method: "POST",
|
|
25179
|
+
headers: {
|
|
25180
|
+
"Content-Type": "application/json",
|
|
25181
|
+
Authorization: `Bearer ${this.config.accessToken}`
|
|
25182
|
+
},
|
|
25183
|
+
body: JSON.stringify({
|
|
25184
|
+
query: sql,
|
|
25185
|
+
read_only: readOnly
|
|
25186
|
+
})
|
|
25187
|
+
});
|
|
25188
|
+
const body = await response.text();
|
|
25189
|
+
let data;
|
|
25190
|
+
try {
|
|
25191
|
+
data = JSON.parse(body);
|
|
25192
|
+
} catch {
|
|
25193
|
+
throw this.createPgError({
|
|
25194
|
+
message: `Supabase API returned non-JSON response: ${body.slice(0, 200)}`,
|
|
25195
|
+
httpStatus: response.status
|
|
25196
|
+
});
|
|
25197
|
+
}
|
|
25198
|
+
if (!response.ok) {
|
|
25199
|
+
throw this.parseApiError(data, response.status);
|
|
25200
|
+
}
|
|
25201
|
+
if (data && typeof data === "object" && "error" in data && data.error) {
|
|
25202
|
+
throw this.parseApiError(data, response.status);
|
|
25203
|
+
}
|
|
25204
|
+
const rows = Array.isArray(data) ? data : [];
|
|
25205
|
+
return {
|
|
25206
|
+
rows,
|
|
25207
|
+
rowCount: rows.length
|
|
25208
|
+
};
|
|
25209
|
+
}
|
|
25210
|
+
async testConnection() {
|
|
25211
|
+
const result = await this.query("SELECT current_database() as db, version() as version", true);
|
|
25212
|
+
const row = result.rows[0] ?? {};
|
|
25213
|
+
return {
|
|
25214
|
+
database: String(row.db ?? ""),
|
|
25215
|
+
version: String(row.version ?? "")
|
|
25216
|
+
};
|
|
25217
|
+
}
|
|
25218
|
+
async getCurrentDatabase() {
|
|
25219
|
+
const result = await this.query("SELECT current_database() as db", true);
|
|
25220
|
+
const row = result.rows[0] ?? {};
|
|
25221
|
+
return String(row.db ?? "");
|
|
25222
|
+
}
|
|
25223
|
+
parseApiError(data, httpStatus) {
|
|
25224
|
+
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
25225
|
+
const errObj = "error" in data && data.error ? data.error : data;
|
|
25226
|
+
const pgCode = this.extractPgErrorCode(errObj);
|
|
25227
|
+
const message = this.extractErrorMessage(errObj);
|
|
25228
|
+
const detail = this.extractField(errObj, ["details", "detail"]);
|
|
25229
|
+
const hint = this.extractField(errObj, ["hint"]);
|
|
25230
|
+
return this.createPgError({
|
|
25231
|
+
message,
|
|
25232
|
+
code: pgCode,
|
|
25233
|
+
detail,
|
|
25234
|
+
hint,
|
|
25235
|
+
httpStatus,
|
|
25236
|
+
supabaseErrorCode: typeof errObj === "object" && errObj && "code" in errObj ? String(errObj.code ?? "") : undefined
|
|
25237
|
+
});
|
|
25238
|
+
}
|
|
25239
|
+
return this.createPgError({
|
|
25240
|
+
message: `Supabase API error (HTTP ${httpStatus})`,
|
|
25241
|
+
httpStatus
|
|
25242
|
+
});
|
|
25243
|
+
}
|
|
25244
|
+
extractPgErrorCode(errObj) {
|
|
25245
|
+
if (!errObj || typeof errObj !== "object")
|
|
25246
|
+
return;
|
|
25247
|
+
const obj = errObj;
|
|
25248
|
+
if (typeof obj.code === "string") {
|
|
25249
|
+
const code = obj.code;
|
|
25250
|
+
if (/^\d{5}$/.test(code)) {
|
|
25251
|
+
return code;
|
|
25252
|
+
}
|
|
25253
|
+
return this.mapSupabaseCodeToPg(code);
|
|
25254
|
+
}
|
|
25255
|
+
return;
|
|
25256
|
+
}
|
|
25257
|
+
mapSupabaseCodeToPg(code) {
|
|
25258
|
+
const mapping = {
|
|
25259
|
+
PGRST301: "28000",
|
|
25260
|
+
PGRST302: "28P01",
|
|
25261
|
+
"42501": "42501",
|
|
25262
|
+
PGRST000: "42501",
|
|
25263
|
+
"42601": "42601",
|
|
25264
|
+
"42P01": "42P01",
|
|
25265
|
+
PGRST200: "42P01",
|
|
25266
|
+
"42883": "42883",
|
|
25267
|
+
"08000": "08000",
|
|
25268
|
+
"08003": "08003",
|
|
25269
|
+
"08006": "08006",
|
|
25270
|
+
"42710": "42710"
|
|
25271
|
+
};
|
|
25272
|
+
return mapping[code];
|
|
25273
|
+
}
|
|
25274
|
+
extractErrorMessage(errObj) {
|
|
25275
|
+
if (!errObj || typeof errObj !== "object") {
|
|
25276
|
+
return "Unknown Supabase API error";
|
|
25277
|
+
}
|
|
25278
|
+
const obj = errObj;
|
|
25279
|
+
for (const field of ["message", "error", "msg", "description"]) {
|
|
25280
|
+
if (typeof obj[field] === "string" && obj[field]) {
|
|
25281
|
+
return obj[field];
|
|
25282
|
+
}
|
|
25283
|
+
}
|
|
25284
|
+
if (obj.error && typeof obj.error === "object") {
|
|
25285
|
+
return this.extractErrorMessage(obj.error);
|
|
25286
|
+
}
|
|
25287
|
+
return "Unknown Supabase API error";
|
|
25288
|
+
}
|
|
25289
|
+
extractField(errObj, fieldNames) {
|
|
25290
|
+
if (!errObj || typeof errObj !== "object")
|
|
25291
|
+
return;
|
|
25292
|
+
const obj = errObj;
|
|
25293
|
+
for (const field of fieldNames) {
|
|
25294
|
+
if (typeof obj[field] === "string" && obj[field]) {
|
|
25295
|
+
return obj[field];
|
|
25296
|
+
}
|
|
25297
|
+
}
|
|
25298
|
+
return;
|
|
25299
|
+
}
|
|
25300
|
+
createPgError(opts) {
|
|
25301
|
+
const err = new Error(opts.message);
|
|
25302
|
+
if (opts.code)
|
|
25303
|
+
err.code = opts.code;
|
|
25304
|
+
if (opts.detail)
|
|
25305
|
+
err.detail = opts.detail;
|
|
25306
|
+
if (opts.hint)
|
|
25307
|
+
err.hint = opts.hint;
|
|
25308
|
+
if (opts.httpStatus)
|
|
25309
|
+
err.httpStatus = opts.httpStatus;
|
|
25310
|
+
if (opts.supabaseErrorCode)
|
|
25311
|
+
err.supabaseErrorCode = opts.supabaseErrorCode;
|
|
25312
|
+
return err;
|
|
25313
|
+
}
|
|
25314
|
+
}
|
|
25315
|
+
async function fetchPoolerDatabaseUrl(config2, username) {
|
|
25316
|
+
const url = `${SUPABASE_API_BASE}/v1/projects/${encodeURIComponent(config2.projectRef)}/config/database/pooler`;
|
|
25317
|
+
try {
|
|
25318
|
+
const response = await fetch(url, {
|
|
25319
|
+
method: "GET",
|
|
25320
|
+
headers: {
|
|
25321
|
+
Authorization: `Bearer ${config2.accessToken}`
|
|
25322
|
+
}
|
|
25323
|
+
});
|
|
25324
|
+
if (!response.ok) {
|
|
25325
|
+
return null;
|
|
25326
|
+
}
|
|
25327
|
+
const data = await response.json();
|
|
25328
|
+
if (Array.isArray(data) && data.length > 0) {
|
|
25329
|
+
const pooler = data[0];
|
|
25330
|
+
if (pooler.db_host && pooler.db_port && pooler.db_name) {
|
|
25331
|
+
return `postgresql://${username}@${pooler.db_host}:${pooler.db_port}/${pooler.db_name}`;
|
|
25332
|
+
}
|
|
25333
|
+
if (typeof pooler.connection_string === "string") {
|
|
25334
|
+
try {
|
|
25335
|
+
const connUrl = new URL(pooler.connection_string);
|
|
25336
|
+
const portPart = connUrl.port ? `:${connUrl.port}` : "";
|
|
25337
|
+
return `postgresql://${username}@${connUrl.hostname}${portPart}${connUrl.pathname}`;
|
|
25338
|
+
} catch {
|
|
25339
|
+
return null;
|
|
25340
|
+
}
|
|
25341
|
+
}
|
|
25342
|
+
}
|
|
25343
|
+
return null;
|
|
25344
|
+
} catch {
|
|
25345
|
+
return null;
|
|
25346
|
+
}
|
|
24306
25347
|
}
|
|
24307
|
-
|
|
25348
|
+
function resolveSupabaseConfig(opts) {
|
|
25349
|
+
const accessToken = opts.accessToken?.trim() || process.env.SUPABASE_ACCESS_TOKEN?.trim() || "";
|
|
25350
|
+
const projectRef = opts.projectRef?.trim() || process.env.SUPABASE_PROJECT_REF?.trim() || "";
|
|
25351
|
+
if (!accessToken) {
|
|
25352
|
+
throw new Error(`Supabase access token is required.
|
|
25353
|
+
` + `Provide it via --supabase-access-token or SUPABASE_ACCESS_TOKEN environment variable.
|
|
25354
|
+
` + "Generate a token at: https://supabase.com/dashboard/account/tokens");
|
|
25355
|
+
}
|
|
25356
|
+
if (!projectRef) {
|
|
25357
|
+
throw new Error(`Supabase project reference is required.
|
|
25358
|
+
` + `Provide it via --supabase-project-ref or SUPABASE_PROJECT_REF environment variable.
|
|
25359
|
+
` + "Find your project ref in the Supabase dashboard URL: https://supabase.com/dashboard/project/<ref>");
|
|
25360
|
+
}
|
|
25361
|
+
return { accessToken, projectRef };
|
|
25362
|
+
}
|
|
25363
|
+
function extractProjectRefFromUrl(dbUrl) {
|
|
25364
|
+
try {
|
|
25365
|
+
const url = new URL(dbUrl);
|
|
25366
|
+
const host = url.hostname;
|
|
25367
|
+
const match = host.match(/^(?:db\.)?([^.]+)\.supabase\.co$/i);
|
|
25368
|
+
if (match && match[1]) {
|
|
25369
|
+
return match[1];
|
|
25370
|
+
}
|
|
25371
|
+
if (host.includes("pooler.supabase.com")) {
|
|
25372
|
+
const username = url.username;
|
|
25373
|
+
const userMatch = username.match(/^postgres\.([a-z0-9]+)$/i);
|
|
25374
|
+
if (userMatch && userMatch[1]) {
|
|
25375
|
+
return userMatch[1];
|
|
25376
|
+
}
|
|
25377
|
+
}
|
|
25378
|
+
const poolerMatch = host.match(/^([a-z0-9]+)\.pooler\.supabase\.com$/i);
|
|
25379
|
+
if (poolerMatch && poolerMatch[1] && !poolerMatch[1].startsWith("aws-")) {
|
|
25380
|
+
return poolerMatch[1];
|
|
25381
|
+
}
|
|
25382
|
+
return;
|
|
25383
|
+
} catch {
|
|
25384
|
+
return;
|
|
25385
|
+
}
|
|
25386
|
+
}
|
|
25387
|
+
async function applyInitPlanViaSupabase(params) {
|
|
24308
25388
|
const applied = [];
|
|
24309
25389
|
const skippedOptional = [];
|
|
24310
25390
|
const executeStep = async (step) => {
|
|
24311
|
-
|
|
24312
|
-
|
|
24313
|
-
|
|
24314
|
-
|
|
24315
|
-
} catch (e) {
|
|
24316
|
-
try {
|
|
24317
|
-
await params.client.query("rollback;");
|
|
24318
|
-
} catch {}
|
|
24319
|
-
throw e;
|
|
24320
|
-
}
|
|
25391
|
+
const wrappedSql = `BEGIN;
|
|
25392
|
+
${step.sql}
|
|
25393
|
+
COMMIT;`;
|
|
25394
|
+
await params.client.query(wrappedSql, false);
|
|
24321
25395
|
};
|
|
24322
25396
|
for (const step of params.plan.steps.filter((s) => !s.optional)) {
|
|
24323
25397
|
try {
|
|
25398
|
+
if (params.verbose) {
|
|
25399
|
+
console.log(`Executing step: ${step.name}`);
|
|
25400
|
+
}
|
|
24324
25401
|
await executeStep(step);
|
|
24325
25402
|
applied.push(step.name);
|
|
24326
25403
|
} catch (e) {
|
|
@@ -24342,12 +25419,13 @@ async function applyInitPlan(params) {
|
|
|
24342
25419
|
"constraint",
|
|
24343
25420
|
"file",
|
|
24344
25421
|
"line",
|
|
24345
|
-
"routine"
|
|
25422
|
+
"routine",
|
|
25423
|
+
"httpStatus",
|
|
25424
|
+
"supabaseErrorCode"
|
|
24346
25425
|
];
|
|
24347
|
-
|
|
24348
|
-
|
|
24349
|
-
|
|
24350
|
-
wrapped[field] = errAny[field];
|
|
25426
|
+
for (const field of pgErrorFields) {
|
|
25427
|
+
if (errAny[field] !== undefined) {
|
|
25428
|
+
wrapped[field] = errAny[field];
|
|
24351
25429
|
}
|
|
24352
25430
|
}
|
|
24353
25431
|
if (e instanceof Error && e.stack) {
|
|
@@ -24358,6 +25436,9 @@ async function applyInitPlan(params) {
|
|
|
24358
25436
|
}
|
|
24359
25437
|
for (const step of params.plan.steps.filter((s) => s.optional)) {
|
|
24360
25438
|
try {
|
|
25439
|
+
if (params.verbose) {
|
|
25440
|
+
console.log(`Executing optional step: ${step.name}`);
|
|
25441
|
+
}
|
|
24361
25442
|
await executeStep(step);
|
|
24362
25443
|
applied.push(step.name);
|
|
24363
25444
|
} catch {
|
|
@@ -24366,98 +25447,133 @@ async function applyInitPlan(params) {
|
|
|
24366
25447
|
}
|
|
24367
25448
|
return { applied, skippedOptional };
|
|
24368
25449
|
}
|
|
24369
|
-
async function
|
|
24370
|
-
|
|
24371
|
-
|
|
24372
|
-
|
|
24373
|
-
|
|
24374
|
-
|
|
24375
|
-
|
|
24376
|
-
|
|
24377
|
-
|
|
24378
|
-
|
|
24379
|
-
|
|
24380
|
-
|
|
24381
|
-
}
|
|
24382
|
-
|
|
24383
|
-
|
|
24384
|
-
|
|
24385
|
-
}
|
|
24386
|
-
|
|
24387
|
-
|
|
24388
|
-
|
|
24389
|
-
|
|
24390
|
-
|
|
24391
|
-
|
|
24392
|
-
|
|
24393
|
-
|
|
24394
|
-
|
|
24395
|
-
|
|
25450
|
+
async function verifyInitSetupViaSupabase(params) {
|
|
25451
|
+
const missingRequired = [];
|
|
25452
|
+
const missingOptional = [];
|
|
25453
|
+
const role = params.monitoringUser;
|
|
25454
|
+
const db = params.database;
|
|
25455
|
+
if (!isValidIdentifier(role)) {
|
|
25456
|
+
throw new Error(`Invalid monitoring user name: "${role}". Must be a valid PostgreSQL identifier (letters, digits, underscores, max 63 chars, starting with letter or underscore).`);
|
|
25457
|
+
}
|
|
25458
|
+
const roleRes = await params.client.query(`SELECT 1 FROM pg_catalog.pg_roles WHERE rolname = '${escapeLiteral2(role)}'`, true);
|
|
25459
|
+
const roleExists = roleRes.rowCount > 0;
|
|
25460
|
+
if (!roleExists) {
|
|
25461
|
+
missingRequired.push(`role "${role}" does not exist`);
|
|
25462
|
+
return { ok: false, missingRequired, missingOptional };
|
|
25463
|
+
}
|
|
25464
|
+
const connectRes = await params.client.query(`SELECT has_database_privilege('${escapeLiteral2(role)}', '${escapeLiteral2(db)}', 'CONNECT') as ok`, true);
|
|
25465
|
+
if (!connectRes.rows?.[0]?.ok) {
|
|
25466
|
+
missingRequired.push(`CONNECT on database "${db}"`);
|
|
25467
|
+
}
|
|
25468
|
+
const pgMonitorRes = await params.client.query(`SELECT pg_has_role('${escapeLiteral2(role)}', 'pg_monitor', 'member') as ok`, true);
|
|
25469
|
+
if (!pgMonitorRes.rows?.[0]?.ok) {
|
|
25470
|
+
missingRequired.push("membership in role pg_monitor");
|
|
25471
|
+
}
|
|
25472
|
+
const pgIndexRes = await params.client.query(`SELECT has_table_privilege('${escapeLiteral2(role)}', 'pg_catalog.pg_index', 'SELECT') as ok`, true);
|
|
25473
|
+
if (!pgIndexRes.rows?.[0]?.ok) {
|
|
25474
|
+
missingRequired.push("SELECT on pg_catalog.pg_index");
|
|
25475
|
+
}
|
|
25476
|
+
const schemaExistsRes = await params.client.query("SELECT nspname FROM pg_namespace WHERE nspname = 'postgres_ai'", true);
|
|
25477
|
+
if (schemaExistsRes.rowCount === 0) {
|
|
25478
|
+
missingRequired.push("schema postgres_ai exists");
|
|
25479
|
+
} else {
|
|
25480
|
+
const schemaPrivRes = await params.client.query(`SELECT has_schema_privilege('${escapeLiteral2(role)}', 'postgres_ai', 'USAGE') as ok`, true);
|
|
25481
|
+
if (!schemaPrivRes.rows?.[0]?.ok) {
|
|
24396
25482
|
missingRequired.push("USAGE on schema postgres_ai");
|
|
24397
25483
|
}
|
|
24398
|
-
|
|
24399
|
-
|
|
24400
|
-
|
|
24401
|
-
|
|
24402
|
-
|
|
24403
|
-
|
|
24404
|
-
|
|
24405
|
-
|
|
25484
|
+
}
|
|
25485
|
+
const viewExistsRes = await params.client.query("SELECT to_regclass('postgres_ai.pg_statistic') IS NOT NULL as ok", true);
|
|
25486
|
+
if (!viewExistsRes.rows?.[0]?.ok) {
|
|
25487
|
+
missingRequired.push("view postgres_ai.pg_statistic exists");
|
|
25488
|
+
} else {
|
|
25489
|
+
const viewPrivRes = await params.client.query(`SELECT has_table_privilege('${escapeLiteral2(role)}', 'postgres_ai.pg_statistic', 'SELECT') as ok`, true);
|
|
25490
|
+
if (!viewPrivRes.rows?.[0]?.ok) {
|
|
25491
|
+
missingRequired.push("SELECT on view postgres_ai.pg_statistic");
|
|
24406
25492
|
}
|
|
24407
|
-
|
|
25493
|
+
}
|
|
25494
|
+
const publicSchemaExistsRes = await params.client.query("SELECT nspname FROM pg_namespace WHERE nspname = 'public'", true);
|
|
25495
|
+
if (publicSchemaExistsRes.rowCount === 0) {
|
|
25496
|
+
missingRequired.push("schema public exists");
|
|
25497
|
+
} else {
|
|
25498
|
+
const schemaUsageRes = await params.client.query(`SELECT has_schema_privilege('${escapeLiteral2(role)}', 'public', 'USAGE') as ok`, true);
|
|
24408
25499
|
if (!schemaUsageRes.rows?.[0]?.ok) {
|
|
24409
25500
|
missingRequired.push("USAGE on schema public");
|
|
24410
25501
|
}
|
|
24411
|
-
|
|
24412
|
-
|
|
24413
|
-
|
|
24414
|
-
|
|
24415
|
-
|
|
24416
|
-
|
|
24417
|
-
|
|
24418
|
-
|
|
24419
|
-
|
|
24420
|
-
|
|
25502
|
+
}
|
|
25503
|
+
const rolcfgRes = await params.client.query(`SELECT rolconfig FROM pg_catalog.pg_roles WHERE rolname = '${escapeLiteral2(role)}'`, true);
|
|
25504
|
+
const rolconfig = rolcfgRes.rows?.[0]?.rolconfig;
|
|
25505
|
+
const spLine = Array.isArray(rolconfig) ? rolconfig.find((v) => String(v).startsWith("search_path=")) : undefined;
|
|
25506
|
+
if (typeof spLine !== "string" || !spLine) {
|
|
25507
|
+
missingRequired.push("role search_path is set");
|
|
25508
|
+
} else {
|
|
25509
|
+
const sp = spLine.toLowerCase();
|
|
25510
|
+
if (!sp.includes("postgres_ai") || !sp.includes("public") || !sp.includes("pg_catalog")) {
|
|
25511
|
+
missingRequired.push("role search_path includes postgres_ai, public and pg_catalog");
|
|
24421
25512
|
}
|
|
24422
|
-
|
|
25513
|
+
}
|
|
25514
|
+
const explainFnExistsRes = await params.client.query("SELECT oid FROM pg_proc WHERE proname = 'explain_generic' AND pronamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'postgres_ai')", true);
|
|
25515
|
+
if (explainFnExistsRes.rowCount === 0) {
|
|
25516
|
+
missingRequired.push("function postgres_ai.explain_generic exists");
|
|
25517
|
+
} else {
|
|
25518
|
+
const explainFnRes = await params.client.query(`SELECT has_function_privilege('${escapeLiteral2(role)}', 'postgres_ai.explain_generic(text, text, text)', 'EXECUTE') as ok`, true);
|
|
24423
25519
|
if (!explainFnRes.rows?.[0]?.ok) {
|
|
24424
25520
|
missingRequired.push("EXECUTE on postgres_ai.explain_generic(text, text, text)");
|
|
24425
25521
|
}
|
|
24426
|
-
|
|
25522
|
+
}
|
|
25523
|
+
const tableDescribeFnExistsRes = await params.client.query("SELECT oid FROM pg_proc WHERE proname = 'table_describe' AND pronamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'postgres_ai')", true);
|
|
25524
|
+
if (tableDescribeFnExistsRes.rowCount === 0) {
|
|
25525
|
+
missingRequired.push("function postgres_ai.table_describe exists");
|
|
25526
|
+
} else {
|
|
25527
|
+
const tableDescribeFnRes = await params.client.query(`SELECT has_function_privilege('${escapeLiteral2(role)}', 'postgres_ai.table_describe(text)', 'EXECUTE') as ok`, true);
|
|
24427
25528
|
if (!tableDescribeFnRes.rows?.[0]?.ok) {
|
|
24428
25529
|
missingRequired.push("EXECUTE on postgres_ai.table_describe(text)");
|
|
24429
25530
|
}
|
|
24430
|
-
|
|
24431
|
-
|
|
24432
|
-
|
|
24433
|
-
|
|
24434
|
-
|
|
24435
|
-
|
|
24436
|
-
|
|
24437
|
-
|
|
24438
|
-
|
|
24439
|
-
|
|
25531
|
+
}
|
|
25532
|
+
if (params.includeOptionalPermissions) {
|
|
25533
|
+
const extRes = await params.client.query("SELECT 1 FROM pg_extension WHERE extname = 'rds_tools'", true);
|
|
25534
|
+
if (extRes.rowCount === 0) {
|
|
25535
|
+
missingOptional.push("extension rds_tools");
|
|
25536
|
+
} else {
|
|
25537
|
+
try {
|
|
25538
|
+
const fnRes = await params.client.query(`SELECT has_function_privilege('${escapeLiteral2(role)}', 'rds_tools.pg_ls_multixactdir()', 'EXECUTE') as ok`, true);
|
|
25539
|
+
if (!fnRes.rows?.[0]?.ok) {
|
|
25540
|
+
missingOptional.push("EXECUTE on rds_tools.pg_ls_multixactdir()");
|
|
24440
25541
|
}
|
|
25542
|
+
} catch {
|
|
25543
|
+
missingOptional.push("EXECUTE on rds_tools.pg_ls_multixactdir()");
|
|
24441
25544
|
}
|
|
24442
|
-
|
|
24443
|
-
|
|
24444
|
-
|
|
24445
|
-
|
|
24446
|
-
|
|
24447
|
-
|
|
24448
|
-
|
|
24449
|
-
|
|
25545
|
+
}
|
|
25546
|
+
const optionalFns = [
|
|
25547
|
+
"pg_catalog.pg_stat_file(text)",
|
|
25548
|
+
"pg_catalog.pg_stat_file(text, boolean)",
|
|
25549
|
+
"pg_catalog.pg_ls_dir(text)",
|
|
25550
|
+
"pg_catalog.pg_ls_dir(text, boolean, boolean)"
|
|
25551
|
+
];
|
|
25552
|
+
for (const fn of optionalFns) {
|
|
25553
|
+
try {
|
|
25554
|
+
const fnRes = await params.client.query(`SELECT has_function_privilege('${escapeLiteral2(role)}', '${fn}', 'EXECUTE') as ok`, true);
|
|
24450
25555
|
if (!fnRes.rows?.[0]?.ok) {
|
|
24451
25556
|
missingOptional.push(`EXECUTE on ${fn}`);
|
|
24452
25557
|
}
|
|
25558
|
+
} catch {
|
|
25559
|
+
missingOptional.push(`EXECUTE on ${fn}`);
|
|
24453
25560
|
}
|
|
24454
25561
|
}
|
|
24455
|
-
return { ok: missingRequired.length === 0, missingRequired, missingOptional };
|
|
24456
|
-
} finally {
|
|
24457
|
-
try {
|
|
24458
|
-
await params.client.query("rollback;");
|
|
24459
|
-
} catch {}
|
|
24460
25562
|
}
|
|
25563
|
+
return {
|
|
25564
|
+
ok: missingRequired.length === 0,
|
|
25565
|
+
missingRequired,
|
|
25566
|
+
missingOptional
|
|
25567
|
+
};
|
|
25568
|
+
}
|
|
25569
|
+
function isValidIdentifier(name) {
|
|
25570
|
+
return /^[a-zA-Z_][a-zA-Z0-9_]{0,62}$/.test(name);
|
|
25571
|
+
}
|
|
25572
|
+
function escapeLiteral2(value) {
|
|
25573
|
+
if (value.includes("\x00")) {
|
|
25574
|
+
throw new Error("SQL literal cannot contain null bytes");
|
|
25575
|
+
}
|
|
25576
|
+
return value.replace(/'/g, "''");
|
|
24461
25577
|
}
|
|
24462
25578
|
|
|
24463
25579
|
// lib/pkce.ts
|
|
@@ -24959,17 +26075,17 @@ where
|
|
|
24959
26075
|
statement_timeout_seconds: 300
|
|
24960
26076
|
},
|
|
24961
26077
|
pg_invalid_indexes: {
|
|
24962
|
-
description: "This metric identifies invalid indexes in the database. It provides insights into
|
|
26078
|
+
description: "This metric identifies invalid indexes in the database with decision tree data for remediation. It provides insights into whether to DROP (if duplicate exists), RECREATE (if backs constraint), or flag as UNCERTAIN (if additional RCA is needed to check query plans). Decision tree: 1) Valid duplicate exists -> DROP, 2) Backs PK/UNIQUE constraint -> RECREATE, 3) Table < 10K rows -> RECREATE (small tables rebuild quickly, typically under 1 second), 4) Otherwise -> UNCERTAIN (need query plan analysis to assess impact).",
|
|
24963
26079
|
sqls: {
|
|
24964
26080
|
11: `with fk_indexes as ( /* pgwatch_generated */
|
|
24965
26081
|
select
|
|
24966
|
-
schemaname as
|
|
24967
|
-
|
|
24968
|
-
(
|
|
24969
|
-
(
|
|
24970
|
-
|
|
24971
|
-
|
|
24972
|
-
|
|
26082
|
+
schemaname as schema_name,
|
|
26083
|
+
indexrelid,
|
|
26084
|
+
(indexrelid::regclass)::text as index_name,
|
|
26085
|
+
(relid::regclass)::text as table_name,
|
|
26086
|
+
(confrelid::regclass)::text as fk_table_ref,
|
|
26087
|
+
array_to_string(indclass, ', ') as opclasses
|
|
26088
|
+
from pg_stat_all_indexes
|
|
24973
26089
|
join pg_index using (indexrelid)
|
|
24974
26090
|
left join pg_constraint
|
|
24975
26091
|
on array_to_string(indkey, ',') = array_to_string(conkey, ',')
|
|
@@ -24978,37 +26094,58 @@ where
|
|
|
24978
26094
|
and contype = 'f'
|
|
24979
26095
|
where idx_scan = 0
|
|
24980
26096
|
and indisunique is false
|
|
24981
|
-
and conkey is not null
|
|
24982
|
-
),
|
|
26097
|
+
and conkey is not null
|
|
26098
|
+
),
|
|
26099
|
+
-- Find valid indexes that could be duplicates (same table, same columns)
|
|
26100
|
+
valid_duplicates as (
|
|
26101
|
+
select
|
|
26102
|
+
inv.indexrelid as invalid_indexrelid,
|
|
26103
|
+
val.indexrelid as valid_indexrelid,
|
|
26104
|
+
(val.indexrelid::regclass)::text as valid_index_name,
|
|
26105
|
+
pg_get_indexdef(val.indexrelid) as valid_index_definition
|
|
26106
|
+
from pg_index inv
|
|
26107
|
+
join pg_index val on inv.indrelid = val.indrelid -- same table
|
|
26108
|
+
and inv.indkey = val.indkey -- same columns (in same order)
|
|
26109
|
+
and inv.indexrelid != val.indexrelid -- different index
|
|
26110
|
+
and val.indisvalid = true -- valid index
|
|
26111
|
+
where inv.indisvalid = false
|
|
26112
|
+
),
|
|
26113
|
+
data as (
|
|
24983
26114
|
select
|
|
24984
26115
|
pci.relname as tag_index_name,
|
|
24985
26116
|
pn.nspname as tag_schema_name,
|
|
24986
26117
|
pct.relname as tag_table_name,
|
|
24987
|
-
quote_ident(pn.nspname) as tag_schema_name,
|
|
24988
|
-
quote_ident(pci.relname) as tag_index_name,
|
|
24989
|
-
quote_ident(pct.relname) as tag_table_name,
|
|
24990
26118
|
coalesce(nullif(quote_ident(pn.nspname), 'public') || '.', '') || quote_ident(pct.relname) as tag_relation_name,
|
|
24991
26119
|
pg_get_indexdef(pidx.indexrelid) as index_definition,
|
|
24992
|
-
pg_relation_size(pidx.indexrelid) index_size_bytes,
|
|
26120
|
+
pg_relation_size(pidx.indexrelid) as index_size_bytes,
|
|
26121
|
+
-- Constraint info
|
|
26122
|
+
pidx.indisprimary as is_pk,
|
|
26123
|
+
pidx.indisunique as is_unique,
|
|
26124
|
+
con.conname as constraint_name,
|
|
26125
|
+
-- Table row estimate
|
|
26126
|
+
pct.reltuples::bigint as table_row_estimate,
|
|
26127
|
+
-- Valid duplicate check
|
|
26128
|
+
(vd.valid_indexrelid is not null) as has_valid_duplicate,
|
|
26129
|
+
vd.valid_index_name,
|
|
26130
|
+
vd.valid_index_definition,
|
|
26131
|
+
-- FK support check
|
|
24993
26132
|
((
|
|
24994
26133
|
select count(1)
|
|
24995
26134
|
from fk_indexes fi
|
|
24996
|
-
where
|
|
24997
|
-
fi.
|
|
24998
|
-
and fi.tag_opclasses like (array_to_string(pidx.indclass, ', ') || '%')
|
|
26135
|
+
where fi.fk_table_ref = pct.relname
|
|
26136
|
+
and fi.opclasses like (array_to_string(pidx.indclass, ', ') || '%')
|
|
24999
26137
|
) > 0)::int as supports_fk
|
|
25000
26138
|
from pg_index pidx
|
|
25001
|
-
join pg_class
|
|
25002
|
-
join pg_class
|
|
26139
|
+
join pg_class pci on pci.oid = pidx.indexrelid
|
|
26140
|
+
join pg_class pct on pct.oid = pidx.indrelid
|
|
25003
26141
|
left join pg_namespace pn on pn.oid = pct.relnamespace
|
|
26142
|
+
left join pg_constraint con on con.conindid = pidx.indexrelid
|
|
26143
|
+
left join valid_duplicates vd on vd.invalid_indexrelid = pidx.indexrelid
|
|
25004
26144
|
where pidx.indisvalid = false
|
|
25005
|
-
),
|
|
25006
|
-
|
|
25007
|
-
sum(index_size_bytes) as index_size_bytes_sum
|
|
25008
|
-
from data
|
|
25009
|
-
), num_data as (
|
|
26145
|
+
),
|
|
26146
|
+
num_data as (
|
|
25010
26147
|
select
|
|
25011
|
-
row_number() over () num,
|
|
26148
|
+
row_number() over () as num,
|
|
25012
26149
|
data.*
|
|
25013
26150
|
from data
|
|
25014
26151
|
)
|
|
@@ -25346,7 +26483,7 @@ function transformMetricRow(row) {
|
|
|
25346
26483
|
}
|
|
25347
26484
|
|
|
25348
26485
|
// lib/checkup.ts
|
|
25349
|
-
var __dirname = "/
|
|
26486
|
+
var __dirname = "/builds/postgres-ai/postgres_ai/cli/lib";
|
|
25350
26487
|
var SECONDS_PER_DAY = 86400;
|
|
25351
26488
|
var SECONDS_PER_HOUR = 3600;
|
|
25352
26489
|
var SECONDS_PER_MINUTE = 60;
|
|
@@ -25627,7 +26764,14 @@ async function getInvalidIndexes(client, pgMajorVersion = 16) {
|
|
|
25627
26764
|
index_size_bytes: indexSizeBytes,
|
|
25628
26765
|
index_size_pretty: formatBytes(indexSizeBytes),
|
|
25629
26766
|
index_definition: String(transformed.index_definition || ""),
|
|
25630
|
-
supports_fk: toBool(transformed.supports_fk)
|
|
26767
|
+
supports_fk: toBool(transformed.supports_fk),
|
|
26768
|
+
is_pk: toBool(transformed.is_pk),
|
|
26769
|
+
is_unique: toBool(transformed.is_unique),
|
|
26770
|
+
constraint_name: transformed.constraint_name ? String(transformed.constraint_name) : null,
|
|
26771
|
+
table_row_estimate: parseInt(String(transformed.table_row_estimate || 0), 10),
|
|
26772
|
+
has_valid_duplicate: toBool(transformed.has_valid_duplicate),
|
|
26773
|
+
valid_duplicate_name: transformed.valid_index_name ? String(transformed.valid_index_name) : null,
|
|
26774
|
+
valid_duplicate_definition: transformed.valid_index_definition ? String(transformed.valid_index_definition) : null
|
|
25631
26775
|
};
|
|
25632
26776
|
});
|
|
25633
26777
|
}
|
|
@@ -26716,7 +27860,7 @@ program2.command("set-default-project <project>").description("store default pro
|
|
|
26716
27860
|
writeConfig({ defaultProject: value });
|
|
26717
27861
|
console.log(`Default project saved: ${value}`);
|
|
26718
27862
|
});
|
|
26719
|
-
program2.command("prepare-db [conn]").description("prepare database for monitoring: create monitoring user, required view(s), and grant permissions (idempotent)").option("--db-url <url>", "PostgreSQL connection URL (admin) to run the setup against (deprecated; pass it as positional arg)").option("-h, --host <host>", "PostgreSQL host (psql-like)").option("-p, --port <port>", "PostgreSQL port (psql-like)").option("-U, --username <username>", "PostgreSQL user (psql-like)").option("-d, --dbname <dbname>", "PostgreSQL database name (psql-like)").option("--admin-password <password>", "Admin connection password (otherwise uses PGPASSWORD if set)").option("--monitoring-user <name>", "Monitoring role name to create/update", DEFAULT_MONITORING_USER).option("--password <password>", "Monitoring role password (overrides PGAI_MON_PASSWORD)").option("--skip-optional-permissions", "Skip optional permissions (RDS/self-managed extras)", false).option("--verify", "Verify that monitoring role/permissions are in place (no changes)", false).option("--reset-password", "Reset monitoring role password only (no other changes)", false).option("--print-sql", "Print SQL plan and exit (no changes applied)", false).option("--print-password", "Print generated monitoring password (DANGEROUS in CI logs)", false).addHelpText("after", [
|
|
27863
|
+
program2.command("prepare-db [conn]").description("prepare database for monitoring: create monitoring user, required view(s), and grant permissions (idempotent)").option("--db-url <url>", "PostgreSQL connection URL (admin) to run the setup against (deprecated; pass it as positional arg)").option("-h, --host <host>", "PostgreSQL host (psql-like)").option("-p, --port <port>", "PostgreSQL port (psql-like)").option("-U, --username <username>", "PostgreSQL user (psql-like)").option("-d, --dbname <dbname>", "PostgreSQL database name (psql-like)").option("--admin-password <password>", "Admin connection password (otherwise uses PGPASSWORD if set)").option("--monitoring-user <name>", "Monitoring role name to create/update", DEFAULT_MONITORING_USER).option("--password <password>", "Monitoring role password (overrides PGAI_MON_PASSWORD)").option("--skip-optional-permissions", "Skip optional permissions (RDS/self-managed extras)", false).option("--provider <provider>", "Database provider (e.g., supabase). Affects which steps are executed.").option("--verify", "Verify that monitoring role/permissions are in place (no changes)", false).option("--reset-password", "Reset monitoring role password only (no other changes)", false).option("--print-sql", "Print SQL plan and exit (no changes applied)", false).option("--print-password", "Print generated monitoring password (DANGEROUS in CI logs)", false).option("--supabase", "Use Supabase Management API instead of direct PostgreSQL connection", false).option("--supabase-access-token <token>", "Supabase Management API access token (or SUPABASE_ACCESS_TOKEN env)").option("--supabase-project-ref <ref>", "Supabase project reference (or SUPABASE_PROJECT_REF env)").option("--json", "Output result as JSON (machine-readable)", false).addHelpText("after", [
|
|
26720
27864
|
"",
|
|
26721
27865
|
"Examples:",
|
|
26722
27866
|
" postgresai prepare-db postgresql://admin@host:5432/dbname",
|
|
@@ -26752,21 +27896,60 @@ program2.command("prepare-db [conn]").description("prepare database for monitori
|
|
|
26752
27896
|
" postgresai prepare-db <conn> --reset-password --password '...'",
|
|
26753
27897
|
"",
|
|
26754
27898
|
"Offline SQL plan (no DB connection):",
|
|
26755
|
-
" postgresai prepare-db --print-sql"
|
|
27899
|
+
" postgresai prepare-db --print-sql",
|
|
27900
|
+
"",
|
|
27901
|
+
"Supabase mode (use Management API instead of direct connection):",
|
|
27902
|
+
" postgresai prepare-db --supabase --supabase-project-ref <ref>",
|
|
27903
|
+
" SUPABASE_ACCESS_TOKEN=... postgresai prepare-db --supabase --supabase-project-ref <ref>",
|
|
27904
|
+
"",
|
|
27905
|
+
" Generate a token at: https://supabase.com/dashboard/account/tokens",
|
|
27906
|
+
" Find your project ref in: https://supabase.com/dashboard/project/<ref>",
|
|
27907
|
+
"",
|
|
27908
|
+
"Provider-specific behavior (for direct connections):",
|
|
27909
|
+
" --provider supabase Skip role creation (create user in Supabase dashboard)",
|
|
27910
|
+
" Skip ALTER USER (restricted by Supabase)"
|
|
26756
27911
|
].join(`
|
|
26757
27912
|
`)).action(async (conn, opts, cmd) => {
|
|
26758
|
-
|
|
26759
|
-
|
|
27913
|
+
const jsonOutput = opts.json;
|
|
27914
|
+
const outputJson = (data) => {
|
|
27915
|
+
console.log(JSON.stringify(data, null, 2));
|
|
27916
|
+
};
|
|
27917
|
+
const outputError = (error2) => {
|
|
27918
|
+
if (jsonOutput) {
|
|
27919
|
+
outputJson({
|
|
27920
|
+
success: false,
|
|
27921
|
+
mode: opts.supabase ? "supabase" : "direct",
|
|
27922
|
+
error: error2
|
|
27923
|
+
});
|
|
27924
|
+
} else {
|
|
27925
|
+
console.error(`Error: prepare-db${opts.supabase ? " (Supabase)" : ""}: ${error2.message}`);
|
|
27926
|
+
if (error2.step)
|
|
27927
|
+
console.error(` Step: ${error2.step}`);
|
|
27928
|
+
if (error2.code)
|
|
27929
|
+
console.error(` Code: ${error2.code}`);
|
|
27930
|
+
if (error2.detail)
|
|
27931
|
+
console.error(` Detail: ${error2.detail}`);
|
|
27932
|
+
if (error2.hint)
|
|
27933
|
+
console.error(` Hint: ${error2.hint}`);
|
|
27934
|
+
if (error2.httpStatus)
|
|
27935
|
+
console.error(` HTTP Status: ${error2.httpStatus}`);
|
|
27936
|
+
}
|
|
26760
27937
|
process.exitCode = 1;
|
|
27938
|
+
};
|
|
27939
|
+
if (opts.verify && opts.resetPassword) {
|
|
27940
|
+
outputError({ message: "Provide only one of --verify or --reset-password" });
|
|
26761
27941
|
return;
|
|
26762
27942
|
}
|
|
26763
27943
|
if (opts.verify && opts.printSql) {
|
|
26764
|
-
|
|
26765
|
-
process.exitCode = 1;
|
|
27944
|
+
outputError({ message: "--verify cannot be combined with --print-sql" });
|
|
26766
27945
|
return;
|
|
26767
27946
|
}
|
|
26768
27947
|
const shouldPrintSql = !!opts.printSql;
|
|
26769
27948
|
const redactPasswords = (sql) => redactPasswordsInSql(sql);
|
|
27949
|
+
const providerWarning = validateProvider(opts.provider);
|
|
27950
|
+
if (providerWarning) {
|
|
27951
|
+
console.warn(`\u26A0 ${providerWarning}`);
|
|
27952
|
+
}
|
|
26770
27953
|
if (!conn && !opts.dbUrl && !opts.host && !opts.port && !opts.username && !opts.adminPassword) {
|
|
26771
27954
|
if (shouldPrintSql) {
|
|
26772
27955
|
const database = (opts.dbname ?? process.env.PGDATABASE ?? "postgres").trim();
|
|
@@ -26776,12 +27959,14 @@ program2.command("prepare-db [conn]").description("prepare database for monitori
|
|
|
26776
27959
|
database,
|
|
26777
27960
|
monitoringUser: opts.monitoringUser,
|
|
26778
27961
|
monitoringPassword: monPassword,
|
|
26779
|
-
includeOptionalPermissions: includeOptionalPermissions2
|
|
27962
|
+
includeOptionalPermissions: includeOptionalPermissions2,
|
|
27963
|
+
provider: opts.provider
|
|
26780
27964
|
});
|
|
26781
27965
|
console.log(`
|
|
26782
27966
|
--- SQL plan (offline; not connected) ---`);
|
|
26783
27967
|
console.log(`-- database: ${database}`);
|
|
26784
27968
|
console.log(`-- monitoring user: ${opts.monitoringUser}`);
|
|
27969
|
+
console.log(`-- provider: ${opts.provider ?? "self-managed"}`);
|
|
26785
27970
|
console.log(`-- optional permissions: ${includeOptionalPermissions2 ? "enabled" : "skipped"}`);
|
|
26786
27971
|
for (const step of plan.steps) {
|
|
26787
27972
|
console.log(`
|
|
@@ -26795,6 +27980,281 @@ program2.command("prepare-db [conn]").description("prepare database for monitori
|
|
|
26795
27980
|
return;
|
|
26796
27981
|
}
|
|
26797
27982
|
}
|
|
27983
|
+
if (opts.supabase) {
|
|
27984
|
+
let supabaseConfig;
|
|
27985
|
+
try {
|
|
27986
|
+
let projectRef = opts.supabaseProjectRef;
|
|
27987
|
+
if (!projectRef && conn) {
|
|
27988
|
+
projectRef = extractProjectRefFromUrl(conn);
|
|
27989
|
+
}
|
|
27990
|
+
supabaseConfig = resolveSupabaseConfig({
|
|
27991
|
+
accessToken: opts.supabaseAccessToken,
|
|
27992
|
+
projectRef
|
|
27993
|
+
});
|
|
27994
|
+
} catch (e) {
|
|
27995
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
27996
|
+
outputError({ message: msg });
|
|
27997
|
+
return;
|
|
27998
|
+
}
|
|
27999
|
+
const includeOptionalPermissions2 = !opts.skipOptionalPermissions;
|
|
28000
|
+
if (!jsonOutput) {
|
|
28001
|
+
console.log(`Supabase mode: project ref ${supabaseConfig.projectRef}`);
|
|
28002
|
+
console.log(`Monitoring user: ${opts.monitoringUser}`);
|
|
28003
|
+
console.log(`Optional permissions: ${includeOptionalPermissions2 ? "enabled" : "skipped"}`);
|
|
28004
|
+
}
|
|
28005
|
+
const supabaseClient = new SupabaseClient(supabaseConfig);
|
|
28006
|
+
let databaseUrl = null;
|
|
28007
|
+
if (jsonOutput) {
|
|
28008
|
+
databaseUrl = await fetchPoolerDatabaseUrl(supabaseConfig, opts.monitoringUser);
|
|
28009
|
+
}
|
|
28010
|
+
try {
|
|
28011
|
+
const database = await supabaseClient.getCurrentDatabase();
|
|
28012
|
+
if (!database) {
|
|
28013
|
+
throw new Error("Failed to resolve current database name");
|
|
28014
|
+
}
|
|
28015
|
+
if (!jsonOutput) {
|
|
28016
|
+
console.log(`Database: ${database}`);
|
|
28017
|
+
}
|
|
28018
|
+
if (opts.verify) {
|
|
28019
|
+
const v = await verifyInitSetupViaSupabase({
|
|
28020
|
+
client: supabaseClient,
|
|
28021
|
+
database,
|
|
28022
|
+
monitoringUser: opts.monitoringUser,
|
|
28023
|
+
includeOptionalPermissions: includeOptionalPermissions2
|
|
28024
|
+
});
|
|
28025
|
+
if (v.ok) {
|
|
28026
|
+
if (jsonOutput) {
|
|
28027
|
+
const result = {
|
|
28028
|
+
success: true,
|
|
28029
|
+
mode: "supabase",
|
|
28030
|
+
action: "verify",
|
|
28031
|
+
database,
|
|
28032
|
+
monitoringUser: opts.monitoringUser,
|
|
28033
|
+
verified: true,
|
|
28034
|
+
missingOptional: v.missingOptional
|
|
28035
|
+
};
|
|
28036
|
+
if (databaseUrl) {
|
|
28037
|
+
result.databaseUrl = databaseUrl;
|
|
28038
|
+
}
|
|
28039
|
+
outputJson(result);
|
|
28040
|
+
} else {
|
|
28041
|
+
console.log("\u2713 prepare-db verify: OK");
|
|
28042
|
+
if (v.missingOptional.length > 0) {
|
|
28043
|
+
console.log("\u26A0 Optional items missing:");
|
|
28044
|
+
for (const m of v.missingOptional)
|
|
28045
|
+
console.log(`- ${m}`);
|
|
28046
|
+
}
|
|
28047
|
+
}
|
|
28048
|
+
return;
|
|
28049
|
+
}
|
|
28050
|
+
if (jsonOutput) {
|
|
28051
|
+
const result = {
|
|
28052
|
+
success: false,
|
|
28053
|
+
mode: "supabase",
|
|
28054
|
+
action: "verify",
|
|
28055
|
+
database,
|
|
28056
|
+
monitoringUser: opts.monitoringUser,
|
|
28057
|
+
verified: false,
|
|
28058
|
+
missingRequired: v.missingRequired,
|
|
28059
|
+
missingOptional: v.missingOptional
|
|
28060
|
+
};
|
|
28061
|
+
if (databaseUrl) {
|
|
28062
|
+
result.databaseUrl = databaseUrl;
|
|
28063
|
+
}
|
|
28064
|
+
outputJson(result);
|
|
28065
|
+
} else {
|
|
28066
|
+
console.error("\u2717 prepare-db verify failed: missing required items");
|
|
28067
|
+
for (const m of v.missingRequired)
|
|
28068
|
+
console.error(`- ${m}`);
|
|
28069
|
+
if (v.missingOptional.length > 0) {
|
|
28070
|
+
console.error("Optional items missing:");
|
|
28071
|
+
for (const m of v.missingOptional)
|
|
28072
|
+
console.error(`- ${m}`);
|
|
28073
|
+
}
|
|
28074
|
+
}
|
|
28075
|
+
process.exitCode = 1;
|
|
28076
|
+
return;
|
|
28077
|
+
}
|
|
28078
|
+
let monPassword;
|
|
28079
|
+
let passwordGenerated = false;
|
|
28080
|
+
try {
|
|
28081
|
+
const resolved = await resolveMonitoringPassword({
|
|
28082
|
+
passwordFlag: opts.password,
|
|
28083
|
+
passwordEnv: process.env.PGAI_MON_PASSWORD,
|
|
28084
|
+
monitoringUser: opts.monitoringUser
|
|
28085
|
+
});
|
|
28086
|
+
monPassword = resolved.password;
|
|
28087
|
+
passwordGenerated = resolved.generated;
|
|
28088
|
+
if (resolved.generated) {
|
|
28089
|
+
const canPrint = process.stdout.isTTY || !!opts.printPassword || jsonOutput;
|
|
28090
|
+
if (canPrint) {
|
|
28091
|
+
if (!jsonOutput) {
|
|
28092
|
+
const shellSafe = monPassword.replace(/'/g, "'\\''");
|
|
28093
|
+
console.error("");
|
|
28094
|
+
console.error(`Generated monitoring password for ${opts.monitoringUser} (copy/paste):`);
|
|
28095
|
+
console.error(`PGAI_MON_PASSWORD='${shellSafe}'`);
|
|
28096
|
+
console.error("");
|
|
28097
|
+
console.log("Store it securely (or rerun with --password / PGAI_MON_PASSWORD to set your own).");
|
|
28098
|
+
}
|
|
28099
|
+
} else {
|
|
28100
|
+
console.error([
|
|
28101
|
+
`\u2717 Monitoring password was auto-generated for ${opts.monitoringUser} but not printed in non-interactive mode.`,
|
|
28102
|
+
"",
|
|
28103
|
+
"Provide it explicitly:",
|
|
28104
|
+
" --password <password> or PGAI_MON_PASSWORD=...",
|
|
28105
|
+
"",
|
|
28106
|
+
"Or (NOT recommended) print the generated password:",
|
|
28107
|
+
" --print-password"
|
|
28108
|
+
].join(`
|
|
28109
|
+
`));
|
|
28110
|
+
process.exitCode = 1;
|
|
28111
|
+
return;
|
|
28112
|
+
}
|
|
28113
|
+
}
|
|
28114
|
+
} catch (e) {
|
|
28115
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
28116
|
+
outputError({ message: msg });
|
|
28117
|
+
return;
|
|
28118
|
+
}
|
|
28119
|
+
const plan = await buildInitPlan({
|
|
28120
|
+
database,
|
|
28121
|
+
monitoringUser: opts.monitoringUser,
|
|
28122
|
+
monitoringPassword: monPassword,
|
|
28123
|
+
includeOptionalPermissions: includeOptionalPermissions2
|
|
28124
|
+
});
|
|
28125
|
+
const supabaseApplicableSteps = plan.steps.filter((s) => s.name !== "03.optional_rds" && s.name !== "04.optional_self_managed");
|
|
28126
|
+
const effectivePlan = opts.resetPassword ? { ...plan, steps: supabaseApplicableSteps.filter((s) => s.name === "01.role") } : { ...plan, steps: supabaseApplicableSteps };
|
|
28127
|
+
if (shouldPrintSql) {
|
|
28128
|
+
console.log(`
|
|
28129
|
+
--- SQL plan ---`);
|
|
28130
|
+
for (const step of effectivePlan.steps) {
|
|
28131
|
+
console.log(`
|
|
28132
|
+
-- ${step.name}${step.optional ? " (optional)" : ""}`);
|
|
28133
|
+
console.log(redactPasswords(step.sql));
|
|
28134
|
+
}
|
|
28135
|
+
console.log(`
|
|
28136
|
+
--- end SQL plan ---
|
|
28137
|
+
`);
|
|
28138
|
+
console.log("Note: passwords are redacted in the printed SQL output.");
|
|
28139
|
+
return;
|
|
28140
|
+
}
|
|
28141
|
+
const { applied, skippedOptional } = await applyInitPlanViaSupabase({
|
|
28142
|
+
client: supabaseClient,
|
|
28143
|
+
plan: effectivePlan
|
|
28144
|
+
});
|
|
28145
|
+
if (jsonOutput) {
|
|
28146
|
+
const result = {
|
|
28147
|
+
success: true,
|
|
28148
|
+
mode: "supabase",
|
|
28149
|
+
action: opts.resetPassword ? "reset-password" : "apply",
|
|
28150
|
+
database,
|
|
28151
|
+
monitoringUser: opts.monitoringUser,
|
|
28152
|
+
applied,
|
|
28153
|
+
skippedOptional,
|
|
28154
|
+
warnings: skippedOptional.length > 0 ? ["Some optional steps were skipped (not supported or insufficient privileges)"] : []
|
|
28155
|
+
};
|
|
28156
|
+
if (passwordGenerated) {
|
|
28157
|
+
result.generatedPassword = monPassword;
|
|
28158
|
+
}
|
|
28159
|
+
if (databaseUrl) {
|
|
28160
|
+
result.databaseUrl = databaseUrl;
|
|
28161
|
+
}
|
|
28162
|
+
outputJson(result);
|
|
28163
|
+
} else {
|
|
28164
|
+
console.log(opts.resetPassword ? "\u2713 prepare-db password reset completed" : "\u2713 prepare-db completed");
|
|
28165
|
+
if (skippedOptional.length > 0) {
|
|
28166
|
+
console.log("\u26A0 Some optional steps were skipped (not supported or insufficient privileges):");
|
|
28167
|
+
for (const s of skippedOptional)
|
|
28168
|
+
console.log(`- ${s}`);
|
|
28169
|
+
}
|
|
28170
|
+
if (process.stdout.isTTY) {
|
|
28171
|
+
console.log(`Applied ${applied.length} steps`);
|
|
28172
|
+
}
|
|
28173
|
+
}
|
|
28174
|
+
} catch (error2) {
|
|
28175
|
+
const errAny = error2;
|
|
28176
|
+
let message = "";
|
|
28177
|
+
if (error2 instanceof Error && error2.message) {
|
|
28178
|
+
message = error2.message;
|
|
28179
|
+
} else if (errAny && typeof errAny === "object" && typeof errAny.message === "string" && errAny.message) {
|
|
28180
|
+
message = errAny.message;
|
|
28181
|
+
} else {
|
|
28182
|
+
message = String(error2);
|
|
28183
|
+
}
|
|
28184
|
+
if (!message || message === "[object Object]") {
|
|
28185
|
+
message = "Unknown error";
|
|
28186
|
+
}
|
|
28187
|
+
const stepMatch = typeof message === "string" ? message.match(/Failed at step "([^"]+)":/i) : null;
|
|
28188
|
+
const failedStep = stepMatch?.[1];
|
|
28189
|
+
const errorObj = { message };
|
|
28190
|
+
if (failedStep)
|
|
28191
|
+
errorObj.step = failedStep;
|
|
28192
|
+
if (errAny && typeof errAny === "object") {
|
|
28193
|
+
if (typeof errAny.code === "string" && errAny.code)
|
|
28194
|
+
errorObj.code = errAny.code;
|
|
28195
|
+
if (typeof errAny.detail === "string" && errAny.detail)
|
|
28196
|
+
errorObj.detail = errAny.detail;
|
|
28197
|
+
if (typeof errAny.hint === "string" && errAny.hint)
|
|
28198
|
+
errorObj.hint = errAny.hint;
|
|
28199
|
+
if (typeof errAny.httpStatus === "number")
|
|
28200
|
+
errorObj.httpStatus = errAny.httpStatus;
|
|
28201
|
+
}
|
|
28202
|
+
if (jsonOutput) {
|
|
28203
|
+
outputJson({
|
|
28204
|
+
success: false,
|
|
28205
|
+
mode: "supabase",
|
|
28206
|
+
error: errorObj
|
|
28207
|
+
});
|
|
28208
|
+
process.exitCode = 1;
|
|
28209
|
+
} else {
|
|
28210
|
+
console.error(`Error: prepare-db (Supabase): ${message}`);
|
|
28211
|
+
if (failedStep) {
|
|
28212
|
+
console.error(` Step: ${failedStep}`);
|
|
28213
|
+
}
|
|
28214
|
+
if (errAny && typeof errAny === "object") {
|
|
28215
|
+
if (typeof errAny.code === "string" && errAny.code) {
|
|
28216
|
+
console.error(` Code: ${errAny.code}`);
|
|
28217
|
+
}
|
|
28218
|
+
if (typeof errAny.detail === "string" && errAny.detail) {
|
|
28219
|
+
console.error(` Detail: ${errAny.detail}`);
|
|
28220
|
+
}
|
|
28221
|
+
if (typeof errAny.hint === "string" && errAny.hint) {
|
|
28222
|
+
console.error(` Hint: ${errAny.hint}`);
|
|
28223
|
+
}
|
|
28224
|
+
if (typeof errAny.httpStatus === "number") {
|
|
28225
|
+
console.error(` HTTP Status: ${errAny.httpStatus}`);
|
|
28226
|
+
}
|
|
28227
|
+
}
|
|
28228
|
+
if (errAny && typeof errAny === "object" && typeof errAny.code === "string") {
|
|
28229
|
+
if (errAny.code === "42501") {
|
|
28230
|
+
if (failedStep === "01.role") {
|
|
28231
|
+
console.error(" Context: role creation/update requires CREATEROLE or superuser");
|
|
28232
|
+
} else if (failedStep === "02.permissions") {
|
|
28233
|
+
console.error(" Context: grants/view/search_path require sufficient GRANT/DDL privileges");
|
|
28234
|
+
}
|
|
28235
|
+
console.error(" Fix: ensure your Supabase access token has sufficient permissions");
|
|
28236
|
+
console.error(" Tip: run with --print-sql to review the exact SQL plan");
|
|
28237
|
+
}
|
|
28238
|
+
}
|
|
28239
|
+
if (errAny && typeof errAny === "object" && typeof errAny.httpStatus === "number") {
|
|
28240
|
+
if (errAny.httpStatus === 401) {
|
|
28241
|
+
console.error(" Hint: invalid or expired access token; generate a new one at https://supabase.com/dashboard/account/tokens");
|
|
28242
|
+
}
|
|
28243
|
+
if (errAny.httpStatus === 403) {
|
|
28244
|
+
console.error(" Hint: access denied; check your token permissions and project access");
|
|
28245
|
+
}
|
|
28246
|
+
if (errAny.httpStatus === 404) {
|
|
28247
|
+
console.error(" Hint: project not found; verify the project reference is correct");
|
|
28248
|
+
}
|
|
28249
|
+
if (errAny.httpStatus === 429) {
|
|
28250
|
+
console.error(" Hint: rate limited; wait a moment and try again");
|
|
28251
|
+
}
|
|
28252
|
+
}
|
|
28253
|
+
process.exitCode = 1;
|
|
28254
|
+
}
|
|
28255
|
+
}
|
|
28256
|
+
return;
|
|
28257
|
+
}
|
|
26798
28258
|
let adminConn;
|
|
26799
28259
|
try {
|
|
26800
28260
|
adminConn = resolveAdminConnection({
|
|
@@ -26809,18 +28269,24 @@ program2.command("prepare-db [conn]").description("prepare database for monitori
|
|
|
26809
28269
|
});
|
|
26810
28270
|
} catch (e) {
|
|
26811
28271
|
const msg = e instanceof Error ? e.message : String(e);
|
|
26812
|
-
|
|
26813
|
-
|
|
26814
|
-
|
|
26815
|
-
|
|
28272
|
+
if (jsonOutput) {
|
|
28273
|
+
outputError({ message: msg });
|
|
28274
|
+
} else {
|
|
28275
|
+
console.error(`Error: prepare-db: ${msg}`);
|
|
28276
|
+
if (typeof msg === "string" && msg.startsWith("Connection is required.")) {
|
|
28277
|
+
console.error("");
|
|
28278
|
+
cmd.outputHelp({ error: true });
|
|
28279
|
+
}
|
|
28280
|
+
process.exitCode = 1;
|
|
26816
28281
|
}
|
|
26817
|
-
process.exitCode = 1;
|
|
26818
28282
|
return;
|
|
26819
28283
|
}
|
|
26820
28284
|
const includeOptionalPermissions = !opts.skipOptionalPermissions;
|
|
26821
|
-
|
|
26822
|
-
|
|
26823
|
-
|
|
28285
|
+
if (!jsonOutput) {
|
|
28286
|
+
console.log(`Connecting to: ${adminConn.display}`);
|
|
28287
|
+
console.log(`Monitoring user: ${opts.monitoringUser}`);
|
|
28288
|
+
console.log(`Optional permissions: ${includeOptionalPermissions ? "enabled" : "skipped"}`);
|
|
28289
|
+
}
|
|
26824
28290
|
let client;
|
|
26825
28291
|
try {
|
|
26826
28292
|
const connResult = await connectWithSslFallback(Client, adminConn);
|
|
@@ -26835,29 +28301,57 @@ program2.command("prepare-db [conn]").description("prepare database for monitori
|
|
|
26835
28301
|
client,
|
|
26836
28302
|
database,
|
|
26837
28303
|
monitoringUser: opts.monitoringUser,
|
|
26838
|
-
includeOptionalPermissions
|
|
28304
|
+
includeOptionalPermissions,
|
|
28305
|
+
provider: opts.provider
|
|
26839
28306
|
});
|
|
26840
28307
|
if (v.ok) {
|
|
26841
|
-
|
|
26842
|
-
|
|
26843
|
-
|
|
26844
|
-
|
|
26845
|
-
|
|
28308
|
+
if (jsonOutput) {
|
|
28309
|
+
outputJson({
|
|
28310
|
+
success: true,
|
|
28311
|
+
mode: "direct",
|
|
28312
|
+
action: "verify",
|
|
28313
|
+
database,
|
|
28314
|
+
monitoringUser: opts.monitoringUser,
|
|
28315
|
+
provider: opts.provider,
|
|
28316
|
+
verified: true,
|
|
28317
|
+
missingOptional: v.missingOptional
|
|
28318
|
+
});
|
|
28319
|
+
} else {
|
|
28320
|
+
console.log(`\u2713 prepare-db verify: OK${opts.provider ? ` (provider: ${opts.provider})` : ""}`);
|
|
28321
|
+
if (v.missingOptional.length > 0) {
|
|
28322
|
+
console.log("\u26A0 Optional items missing:");
|
|
28323
|
+
for (const m of v.missingOptional)
|
|
28324
|
+
console.log(`- ${m}`);
|
|
28325
|
+
}
|
|
26846
28326
|
}
|
|
26847
28327
|
return;
|
|
26848
28328
|
}
|
|
26849
|
-
|
|
26850
|
-
|
|
26851
|
-
|
|
26852
|
-
|
|
26853
|
-
|
|
26854
|
-
|
|
28329
|
+
if (jsonOutput) {
|
|
28330
|
+
outputJson({
|
|
28331
|
+
success: false,
|
|
28332
|
+
mode: "direct",
|
|
28333
|
+
action: "verify",
|
|
28334
|
+
database,
|
|
28335
|
+
monitoringUser: opts.monitoringUser,
|
|
28336
|
+
verified: false,
|
|
28337
|
+
missingRequired: v.missingRequired,
|
|
28338
|
+
missingOptional: v.missingOptional
|
|
28339
|
+
});
|
|
28340
|
+
} else {
|
|
28341
|
+
console.error("\u2717 prepare-db verify failed: missing required items");
|
|
28342
|
+
for (const m of v.missingRequired)
|
|
26855
28343
|
console.error(`- ${m}`);
|
|
28344
|
+
if (v.missingOptional.length > 0) {
|
|
28345
|
+
console.error("Optional items missing:");
|
|
28346
|
+
for (const m of v.missingOptional)
|
|
28347
|
+
console.error(`- ${m}`);
|
|
28348
|
+
}
|
|
26856
28349
|
}
|
|
26857
28350
|
process.exitCode = 1;
|
|
26858
28351
|
return;
|
|
26859
28352
|
}
|
|
26860
28353
|
let monPassword;
|
|
28354
|
+
let passwordGenerated = false;
|
|
26861
28355
|
try {
|
|
26862
28356
|
const resolved = await resolveMonitoringPassword({
|
|
26863
28357
|
passwordFlag: opts.password,
|
|
@@ -26865,15 +28359,18 @@ program2.command("prepare-db [conn]").description("prepare database for monitori
|
|
|
26865
28359
|
monitoringUser: opts.monitoringUser
|
|
26866
28360
|
});
|
|
26867
28361
|
monPassword = resolved.password;
|
|
28362
|
+
passwordGenerated = resolved.generated;
|
|
26868
28363
|
if (resolved.generated) {
|
|
26869
|
-
const canPrint = process.stdout.isTTY || !!opts.printPassword;
|
|
28364
|
+
const canPrint = process.stdout.isTTY || !!opts.printPassword || jsonOutput;
|
|
26870
28365
|
if (canPrint) {
|
|
26871
|
-
|
|
26872
|
-
|
|
26873
|
-
|
|
26874
|
-
|
|
26875
|
-
|
|
26876
|
-
|
|
28366
|
+
if (!jsonOutput) {
|
|
28367
|
+
const shellSafe = monPassword.replace(/'/g, "'\\''");
|
|
28368
|
+
console.error("");
|
|
28369
|
+
console.error(`Generated monitoring password for ${opts.monitoringUser} (copy/paste):`);
|
|
28370
|
+
console.error(`PGAI_MON_PASSWORD='${shellSafe}'`);
|
|
28371
|
+
console.error("");
|
|
28372
|
+
console.log("Store it securely (or rerun with --password / PGAI_MON_PASSWORD to set your own).");
|
|
28373
|
+
}
|
|
26877
28374
|
} else {
|
|
26878
28375
|
console.error([
|
|
26879
28376
|
`\u2717 Monitoring password was auto-generated for ${opts.monitoringUser} but not printed in non-interactive mode.`,
|
|
@@ -26891,17 +28388,22 @@ program2.command("prepare-db [conn]").description("prepare database for monitori
|
|
|
26891
28388
|
}
|
|
26892
28389
|
} catch (e) {
|
|
26893
28390
|
const msg = e instanceof Error ? e.message : String(e);
|
|
26894
|
-
|
|
26895
|
-
process.exitCode = 1;
|
|
28391
|
+
outputError({ message: msg });
|
|
26896
28392
|
return;
|
|
26897
28393
|
}
|
|
26898
28394
|
const plan = await buildInitPlan({
|
|
26899
28395
|
database,
|
|
26900
28396
|
monitoringUser: opts.monitoringUser,
|
|
26901
28397
|
monitoringPassword: monPassword,
|
|
26902
|
-
includeOptionalPermissions
|
|
28398
|
+
includeOptionalPermissions,
|
|
28399
|
+
provider: opts.provider
|
|
26903
28400
|
});
|
|
26904
28401
|
const effectivePlan = opts.resetPassword ? { ...plan, steps: plan.steps.filter((s) => s.name === "01.role") } : plan;
|
|
28402
|
+
if (opts.resetPassword && effectivePlan.steps.length === 0) {
|
|
28403
|
+
console.error(`\u2717 --reset-password not supported for provider "${opts.provider}" (role creation is skipped)`);
|
|
28404
|
+
process.exitCode = 1;
|
|
28405
|
+
return;
|
|
28406
|
+
}
|
|
26905
28407
|
if (shouldPrintSql) {
|
|
26906
28408
|
console.log(`
|
|
26907
28409
|
--- SQL plan ---`);
|
|
@@ -26917,14 +28419,31 @@ program2.command("prepare-db [conn]").description("prepare database for monitori
|
|
|
26917
28419
|
return;
|
|
26918
28420
|
}
|
|
26919
28421
|
const { applied, skippedOptional } = await applyInitPlan({ client, plan: effectivePlan });
|
|
26920
|
-
|
|
26921
|
-
|
|
26922
|
-
|
|
26923
|
-
|
|
26924
|
-
|
|
26925
|
-
|
|
26926
|
-
|
|
26927
|
-
|
|
28422
|
+
if (jsonOutput) {
|
|
28423
|
+
const result = {
|
|
28424
|
+
success: true,
|
|
28425
|
+
mode: "direct",
|
|
28426
|
+
action: opts.resetPassword ? "reset-password" : "apply",
|
|
28427
|
+
database,
|
|
28428
|
+
monitoringUser: opts.monitoringUser,
|
|
28429
|
+
applied,
|
|
28430
|
+
skippedOptional,
|
|
28431
|
+
warnings: skippedOptional.length > 0 ? ["Some optional steps were skipped (not supported or insufficient privileges)"] : []
|
|
28432
|
+
};
|
|
28433
|
+
if (passwordGenerated) {
|
|
28434
|
+
result.generatedPassword = monPassword;
|
|
28435
|
+
}
|
|
28436
|
+
outputJson(result);
|
|
28437
|
+
} else {
|
|
28438
|
+
console.log(opts.resetPassword ? "\u2713 prepare-db password reset completed" : "\u2713 prepare-db completed");
|
|
28439
|
+
if (skippedOptional.length > 0) {
|
|
28440
|
+
console.log("\u26A0 Some optional steps were skipped (not supported or insufficient privileges):");
|
|
28441
|
+
for (const s of skippedOptional)
|
|
28442
|
+
console.log(`- ${s}`);
|
|
28443
|
+
}
|
|
28444
|
+
if (process.stdout.isTTY) {
|
|
28445
|
+
console.log(`Applied ${applied.length} steps`);
|
|
28446
|
+
}
|
|
26928
28447
|
}
|
|
26929
28448
|
} catch (error2) {
|
|
26930
28449
|
const errAny = error2;
|
|
@@ -26939,45 +28458,65 @@ program2.command("prepare-db [conn]").description("prepare database for monitori
|
|
|
26939
28458
|
if (!message || message === "[object Object]") {
|
|
26940
28459
|
message = "Unknown error";
|
|
26941
28460
|
}
|
|
26942
|
-
console.error(`Error: prepare-db: ${message}`);
|
|
26943
28461
|
const stepMatch = typeof message === "string" ? message.match(/Failed at step "([^"]+)":/i) : null;
|
|
26944
28462
|
const failedStep = stepMatch?.[1];
|
|
26945
|
-
|
|
26946
|
-
|
|
26947
|
-
|
|
28463
|
+
const errorObj = { message };
|
|
28464
|
+
if (failedStep)
|
|
28465
|
+
errorObj.step = failedStep;
|
|
26948
28466
|
if (errAny && typeof errAny === "object") {
|
|
26949
|
-
if (typeof errAny.code === "string" && errAny.code)
|
|
26950
|
-
|
|
26951
|
-
|
|
26952
|
-
|
|
26953
|
-
|
|
26954
|
-
|
|
26955
|
-
|
|
26956
|
-
|
|
28467
|
+
if (typeof errAny.code === "string" && errAny.code)
|
|
28468
|
+
errorObj.code = errAny.code;
|
|
28469
|
+
if (typeof errAny.detail === "string" && errAny.detail)
|
|
28470
|
+
errorObj.detail = errAny.detail;
|
|
28471
|
+
if (typeof errAny.hint === "string" && errAny.hint)
|
|
28472
|
+
errorObj.hint = errAny.hint;
|
|
28473
|
+
}
|
|
28474
|
+
if (jsonOutput) {
|
|
28475
|
+
outputJson({
|
|
28476
|
+
success: false,
|
|
28477
|
+
mode: "direct",
|
|
28478
|
+
error: errorObj
|
|
28479
|
+
});
|
|
28480
|
+
process.exitCode = 1;
|
|
28481
|
+
} else {
|
|
28482
|
+
console.error(`Error: prepare-db: ${message}`);
|
|
28483
|
+
if (failedStep) {
|
|
28484
|
+
console.error(` Step: ${failedStep}`);
|
|
26957
28485
|
}
|
|
26958
|
-
|
|
26959
|
-
|
|
26960
|
-
|
|
26961
|
-
|
|
26962
|
-
|
|
26963
|
-
|
|
26964
|
-
|
|
28486
|
+
if (errAny && typeof errAny === "object") {
|
|
28487
|
+
if (typeof errAny.code === "string" && errAny.code) {
|
|
28488
|
+
console.error(` Code: ${errAny.code}`);
|
|
28489
|
+
}
|
|
28490
|
+
if (typeof errAny.detail === "string" && errAny.detail) {
|
|
28491
|
+
console.error(` Detail: ${errAny.detail}`);
|
|
28492
|
+
}
|
|
28493
|
+
if (typeof errAny.hint === "string" && errAny.hint) {
|
|
28494
|
+
console.error(` Hint: ${errAny.hint}`);
|
|
26965
28495
|
}
|
|
26966
|
-
console.error(" Fix: connect as a superuser (or a role with CREATEROLE and sufficient GRANT privileges)");
|
|
26967
|
-
console.error(" Fix: on managed Postgres, use the provider's admin/master user");
|
|
26968
|
-
console.error(" Tip: run with --print-sql to review the exact SQL plan");
|
|
26969
|
-
}
|
|
26970
|
-
if (errAny.code === "ECONNREFUSED") {
|
|
26971
|
-
console.error(" Hint: check host/port and ensure Postgres is reachable from this machine");
|
|
26972
|
-
}
|
|
26973
|
-
if (errAny.code === "ENOTFOUND") {
|
|
26974
|
-
console.error(" Hint: DNS resolution failed; double-check the host name");
|
|
26975
28496
|
}
|
|
26976
|
-
if (errAny.code === "
|
|
26977
|
-
|
|
28497
|
+
if (errAny && typeof errAny === "object" && typeof errAny.code === "string") {
|
|
28498
|
+
if (errAny.code === "42501") {
|
|
28499
|
+
if (failedStep === "01.role") {
|
|
28500
|
+
console.error(" Context: role creation/update requires CREATEROLE or superuser");
|
|
28501
|
+
} else if (failedStep === "02.permissions") {
|
|
28502
|
+
console.error(" Context: grants/view/search_path require sufficient GRANT/DDL privileges");
|
|
28503
|
+
}
|
|
28504
|
+
console.error(" Fix: connect as a superuser (or a role with CREATEROLE and sufficient GRANT privileges)");
|
|
28505
|
+
console.error(" Fix: on managed Postgres, use the provider's admin/master user");
|
|
28506
|
+
console.error(" Tip: run with --print-sql to review the exact SQL plan");
|
|
28507
|
+
}
|
|
28508
|
+
if (errAny.code === "ECONNREFUSED") {
|
|
28509
|
+
console.error(" Hint: check host/port and ensure Postgres is reachable from this machine");
|
|
28510
|
+
}
|
|
28511
|
+
if (errAny.code === "ENOTFOUND") {
|
|
28512
|
+
console.error(" Hint: DNS resolution failed; double-check the host name");
|
|
28513
|
+
}
|
|
28514
|
+
if (errAny.code === "ETIMEDOUT") {
|
|
28515
|
+
console.error(" Hint: connection timed out; check network/firewall rules");
|
|
28516
|
+
}
|
|
26978
28517
|
}
|
|
28518
|
+
process.exitCode = 1;
|
|
26979
28519
|
}
|
|
26980
|
-
process.exitCode = 1;
|
|
26981
28520
|
} finally {
|
|
26982
28521
|
if (client) {
|
|
26983
28522
|
try {
|
|
@@ -27214,14 +28753,10 @@ mon.command("local-install").description("install local monitoring stack (genera
|
|
|
27214
28753
|
console.log(`Project directory: ${projectDir}
|
|
27215
28754
|
`);
|
|
27216
28755
|
const envFile = path5.resolve(projectDir, ".env");
|
|
27217
|
-
let existingTag = null;
|
|
27218
28756
|
let existingRegistry = null;
|
|
27219
28757
|
let existingPassword = null;
|
|
27220
28758
|
if (fs5.existsSync(envFile)) {
|
|
27221
28759
|
const existingEnv = fs5.readFileSync(envFile, "utf8");
|
|
27222
|
-
const tagMatch = existingEnv.match(/^PGAI_TAG=(.+)$/m);
|
|
27223
|
-
if (tagMatch)
|
|
27224
|
-
existingTag = tagMatch[1].trim();
|
|
27225
28760
|
const registryMatch = existingEnv.match(/^PGAI_REGISTRY=(.+)$/m);
|
|
27226
28761
|
if (registryMatch)
|
|
27227
28762
|
existingRegistry = registryMatch[1].trim();
|
|
@@ -27229,7 +28764,7 @@ mon.command("local-install").description("install local monitoring stack (genera
|
|
|
27229
28764
|
if (pwdMatch)
|
|
27230
28765
|
existingPassword = pwdMatch[1].trim();
|
|
27231
28766
|
}
|
|
27232
|
-
const imageTag = opts.tag ||
|
|
28767
|
+
const imageTag = opts.tag || package_default.version;
|
|
27233
28768
|
const envLines = [`PGAI_TAG=${imageTag}`];
|
|
27234
28769
|
if (existingRegistry) {
|
|
27235
28770
|
envLines.push(`PGAI_REGISTRY=${existingRegistry}`);
|
|
@@ -27566,6 +29101,9 @@ var MONITORING_CONTAINERS = [
|
|
|
27566
29101
|
"sources-generator",
|
|
27567
29102
|
"postgres-reports"
|
|
27568
29103
|
];
|
|
29104
|
+
var COMPOSE_PROJECT_NAME = "postgres_ai";
|
|
29105
|
+
var DOCKER_NETWORK_NAME = `${COMPOSE_PROJECT_NAME}_default`;
|
|
29106
|
+
var NETWORK_CLEANUP_DELAY_MS = 2000;
|
|
27569
29107
|
async function removeOrphanedContainers() {
|
|
27570
29108
|
for (const container of MONITORING_CONTAINERS) {
|
|
27571
29109
|
try {
|
|
@@ -27574,7 +29112,18 @@ async function removeOrphanedContainers() {
|
|
|
27574
29112
|
}
|
|
27575
29113
|
}
|
|
27576
29114
|
mon.command("stop").description("stop monitoring services").action(async () => {
|
|
27577
|
-
|
|
29115
|
+
let code = await runCompose(["down", "--remove-orphans"]);
|
|
29116
|
+
if (code !== 0) {
|
|
29117
|
+
await removeOrphanedContainers();
|
|
29118
|
+
await new Promise((resolve6) => setTimeout(resolve6, NETWORK_CLEANUP_DELAY_MS));
|
|
29119
|
+
code = await runCompose(["down", "--remove-orphans"]);
|
|
29120
|
+
}
|
|
29121
|
+
if (code !== 0) {
|
|
29122
|
+
try {
|
|
29123
|
+
await execFilePromise("docker", ["network", "rm", DOCKER_NETWORK_NAME]);
|
|
29124
|
+
code = 0;
|
|
29125
|
+
} catch {}
|
|
29126
|
+
}
|
|
27578
29127
|
if (code !== 0)
|
|
27579
29128
|
process.exitCode = code;
|
|
27580
29129
|
});
|
|
@@ -28341,18 +29890,36 @@ function interpretEscapes2(str2) {
|
|
|
28341
29890
|
`).replace(/\\t/g, "\t").replace(/\\r/g, "\r").replace(/\\"/g, '"').replace(/\\'/g, "'").replace(/\x00/g, "\\");
|
|
28342
29891
|
}
|
|
28343
29892
|
var issues = program2.command("issues").description("issues management");
|
|
28344
|
-
issues.command("list").description("list issues").option("--debug", "enable debug output").option("--json", "output raw JSON").action(async (opts) => {
|
|
29893
|
+
issues.command("list").description("list issues").option("--status <status>", "filter by status: open, closed, or all (default: all)").option("--limit <n>", "max number of issues to return (default: 20)", parseInt).option("--offset <n>", "number of issues to skip (default: 0)", parseInt).option("--debug", "enable debug output").option("--json", "output raw JSON").action(async (opts) => {
|
|
29894
|
+
const spinner = createTtySpinner(process.stdout.isTTY ?? false, "Fetching issues...");
|
|
28345
29895
|
try {
|
|
28346
29896
|
const rootOpts = program2.opts();
|
|
28347
29897
|
const cfg = readConfig();
|
|
28348
29898
|
const { apiKey } = getConfig(rootOpts);
|
|
28349
29899
|
if (!apiKey) {
|
|
29900
|
+
spinner.stop();
|
|
28350
29901
|
console.error("API key is required. Run 'pgai auth' first or set --api-key.");
|
|
28351
29902
|
process.exitCode = 1;
|
|
28352
29903
|
return;
|
|
28353
29904
|
}
|
|
29905
|
+
const orgId = cfg.orgId ?? undefined;
|
|
28354
29906
|
const { apiBaseUrl } = resolveBaseUrls2(rootOpts, cfg);
|
|
28355
|
-
|
|
29907
|
+
let statusFilter;
|
|
29908
|
+
if (opts.status === "open") {
|
|
29909
|
+
statusFilter = "open";
|
|
29910
|
+
} else if (opts.status === "closed") {
|
|
29911
|
+
statusFilter = "closed";
|
|
29912
|
+
}
|
|
29913
|
+
const result = await fetchIssues2({
|
|
29914
|
+
apiKey,
|
|
29915
|
+
apiBaseUrl,
|
|
29916
|
+
orgId,
|
|
29917
|
+
status: statusFilter,
|
|
29918
|
+
limit: opts.limit,
|
|
29919
|
+
offset: opts.offset,
|
|
29920
|
+
debug: !!opts.debug
|
|
29921
|
+
});
|
|
29922
|
+
spinner.stop();
|
|
28356
29923
|
const trimmed = Array.isArray(result) ? result.map((r) => ({
|
|
28357
29924
|
id: r.id,
|
|
28358
29925
|
title: r.title,
|
|
@@ -28361,17 +29928,20 @@ issues.command("list").description("list issues").option("--debug", "enable debu
|
|
|
28361
29928
|
})) : result;
|
|
28362
29929
|
printResult(trimmed, opts.json);
|
|
28363
29930
|
} catch (err) {
|
|
29931
|
+
spinner.stop();
|
|
28364
29932
|
const message = err instanceof Error ? err.message : String(err);
|
|
28365
29933
|
console.error(message);
|
|
28366
29934
|
process.exitCode = 1;
|
|
28367
29935
|
}
|
|
28368
29936
|
});
|
|
28369
29937
|
issues.command("view <issueId>").description("view issue details and comments").option("--debug", "enable debug output").option("--json", "output raw JSON").action(async (issueId, opts) => {
|
|
29938
|
+
const spinner = createTtySpinner(process.stdout.isTTY ?? false, "Fetching issue...");
|
|
28370
29939
|
try {
|
|
28371
29940
|
const rootOpts = program2.opts();
|
|
28372
29941
|
const cfg = readConfig();
|
|
28373
29942
|
const { apiKey } = getConfig(rootOpts);
|
|
28374
29943
|
if (!apiKey) {
|
|
29944
|
+
spinner.stop();
|
|
28375
29945
|
console.error("API key is required. Run 'pgai auth' first or set --api-key.");
|
|
28376
29946
|
process.exitCode = 1;
|
|
28377
29947
|
return;
|
|
@@ -28379,32 +29949,38 @@ issues.command("view <issueId>").description("view issue details and comments").
|
|
|
28379
29949
|
const { apiBaseUrl } = resolveBaseUrls2(rootOpts, cfg);
|
|
28380
29950
|
const issue2 = await fetchIssue2({ apiKey, apiBaseUrl, issueId, debug: !!opts.debug });
|
|
28381
29951
|
if (!issue2) {
|
|
29952
|
+
spinner.stop();
|
|
28382
29953
|
console.error("Issue not found");
|
|
28383
29954
|
process.exitCode = 1;
|
|
28384
29955
|
return;
|
|
28385
29956
|
}
|
|
29957
|
+
spinner.update("Fetching comments...");
|
|
28386
29958
|
const comments = await fetchIssueComments2({ apiKey, apiBaseUrl, issueId, debug: !!opts.debug });
|
|
29959
|
+
spinner.stop();
|
|
28387
29960
|
const combined = { issue: issue2, comments };
|
|
28388
29961
|
printResult(combined, opts.json);
|
|
28389
29962
|
} catch (err) {
|
|
29963
|
+
spinner.stop();
|
|
28390
29964
|
const message = err instanceof Error ? err.message : String(err);
|
|
28391
29965
|
console.error(message);
|
|
28392
29966
|
process.exitCode = 1;
|
|
28393
29967
|
}
|
|
28394
29968
|
});
|
|
28395
29969
|
issues.command("post-comment <issueId> <content>").description("post a new comment to an issue").option("--parent <uuid>", "parent comment id").option("--debug", "enable debug output").option("--json", "output raw JSON").action(async (issueId, content, opts) => {
|
|
29970
|
+
if (opts.debug) {
|
|
29971
|
+
console.log(`Debug: Original content: ${JSON.stringify(content)}`);
|
|
29972
|
+
}
|
|
29973
|
+
content = interpretEscapes2(content);
|
|
29974
|
+
if (opts.debug) {
|
|
29975
|
+
console.log(`Debug: Interpreted content: ${JSON.stringify(content)}`);
|
|
29976
|
+
}
|
|
29977
|
+
const spinner = createTtySpinner(process.stdout.isTTY ?? false, "Posting comment...");
|
|
28396
29978
|
try {
|
|
28397
|
-
if (opts.debug) {
|
|
28398
|
-
console.log(`Debug: Original content: ${JSON.stringify(content)}`);
|
|
28399
|
-
}
|
|
28400
|
-
content = interpretEscapes2(content);
|
|
28401
|
-
if (opts.debug) {
|
|
28402
|
-
console.log(`Debug: Interpreted content: ${JSON.stringify(content)}`);
|
|
28403
|
-
}
|
|
28404
29979
|
const rootOpts = program2.opts();
|
|
28405
29980
|
const cfg = readConfig();
|
|
28406
29981
|
const { apiKey } = getConfig(rootOpts);
|
|
28407
29982
|
if (!apiKey) {
|
|
29983
|
+
spinner.stop();
|
|
28408
29984
|
console.error("API key is required. Run 'pgai auth' first or set --api-key.");
|
|
28409
29985
|
process.exitCode = 1;
|
|
28410
29986
|
return;
|
|
@@ -28418,41 +29994,44 @@ issues.command("post-comment <issueId> <content>").description("post a new comme
|
|
|
28418
29994
|
parentCommentId: opts.parent,
|
|
28419
29995
|
debug: !!opts.debug
|
|
28420
29996
|
});
|
|
29997
|
+
spinner.stop();
|
|
28421
29998
|
printResult(result, opts.json);
|
|
28422
29999
|
} catch (err) {
|
|
30000
|
+
spinner.stop();
|
|
28423
30001
|
const message = err instanceof Error ? err.message : String(err);
|
|
28424
30002
|
console.error(message);
|
|
28425
30003
|
process.exitCode = 1;
|
|
28426
30004
|
}
|
|
28427
30005
|
});
|
|
28428
|
-
issues.command("create <title>").description("create a new issue").option("--org-id <id>", "organization id (defaults to config orgId)", (v) => parseInt(v, 10)).option("--project-id <id>", "project id", (v) => parseInt(v, 10)).option("--description <text>", "issue description (
|
|
30006
|
+
issues.command("create <title>").description("create a new issue").option("--org-id <id>", "organization id (defaults to config orgId)", (v) => parseInt(v, 10)).option("--project-id <id>", "project id", (v) => parseInt(v, 10)).option("--description <text>", "issue description (use \\n for newlines)").option("--label <label>", "issue label (repeatable)", (value, previous) => {
|
|
28429
30007
|
previous.push(value);
|
|
28430
30008
|
return previous;
|
|
28431
30009
|
}, []).option("--debug", "enable debug output").option("--json", "output raw JSON").action(async (rawTitle, opts) => {
|
|
30010
|
+
const rootOpts = program2.opts();
|
|
30011
|
+
const cfg = readConfig();
|
|
30012
|
+
const { apiKey } = getConfig(rootOpts);
|
|
30013
|
+
if (!apiKey) {
|
|
30014
|
+
console.error("API key is required. Run 'pgai auth' first or set --api-key.");
|
|
30015
|
+
process.exitCode = 1;
|
|
30016
|
+
return;
|
|
30017
|
+
}
|
|
30018
|
+
const title = interpretEscapes2(String(rawTitle || "").trim());
|
|
30019
|
+
if (!title) {
|
|
30020
|
+
console.error("title is required");
|
|
30021
|
+
process.exitCode = 1;
|
|
30022
|
+
return;
|
|
30023
|
+
}
|
|
30024
|
+
const orgId = typeof opts.orgId === "number" && !Number.isNaN(opts.orgId) ? opts.orgId : cfg.orgId;
|
|
30025
|
+
if (typeof orgId !== "number") {
|
|
30026
|
+
console.error("org_id is required. Either pass --org-id or run 'pgai auth' to store it in config.");
|
|
30027
|
+
process.exitCode = 1;
|
|
30028
|
+
return;
|
|
30029
|
+
}
|
|
30030
|
+
const description = opts.description !== undefined ? interpretEscapes2(String(opts.description)) : undefined;
|
|
30031
|
+
const labels = Array.isArray(opts.label) && opts.label.length > 0 ? opts.label.map(String) : undefined;
|
|
30032
|
+
const projectId = typeof opts.projectId === "number" && !Number.isNaN(opts.projectId) ? opts.projectId : undefined;
|
|
30033
|
+
const spinner = createTtySpinner(process.stdout.isTTY ?? false, "Creating issue...");
|
|
28432
30034
|
try {
|
|
28433
|
-
const rootOpts = program2.opts();
|
|
28434
|
-
const cfg = readConfig();
|
|
28435
|
-
const { apiKey } = getConfig(rootOpts);
|
|
28436
|
-
if (!apiKey) {
|
|
28437
|
-
console.error("API key is required. Run 'pgai auth' first or set --api-key.");
|
|
28438
|
-
process.exitCode = 1;
|
|
28439
|
-
return;
|
|
28440
|
-
}
|
|
28441
|
-
const title = interpretEscapes2(String(rawTitle || "").trim());
|
|
28442
|
-
if (!title) {
|
|
28443
|
-
console.error("title is required");
|
|
28444
|
-
process.exitCode = 1;
|
|
28445
|
-
return;
|
|
28446
|
-
}
|
|
28447
|
-
const orgId = typeof opts.orgId === "number" && !Number.isNaN(opts.orgId) ? opts.orgId : cfg.orgId;
|
|
28448
|
-
if (typeof orgId !== "number") {
|
|
28449
|
-
console.error("org_id is required. Either pass --org-id or run 'pgai auth' to store it in config.");
|
|
28450
|
-
process.exitCode = 1;
|
|
28451
|
-
return;
|
|
28452
|
-
}
|
|
28453
|
-
const description = opts.description !== undefined ? interpretEscapes2(String(opts.description)) : undefined;
|
|
28454
|
-
const labels = Array.isArray(opts.label) && opts.label.length > 0 ? opts.label.map(String) : undefined;
|
|
28455
|
-
const projectId = typeof opts.projectId === "number" && !Number.isNaN(opts.projectId) ? opts.projectId : undefined;
|
|
28456
30035
|
const { apiBaseUrl } = resolveBaseUrls2(rootOpts, cfg);
|
|
28457
30036
|
const result = await createIssue2({
|
|
28458
30037
|
apiKey,
|
|
@@ -28464,57 +30043,60 @@ issues.command("create <title>").description("create a new issue").option("--org
|
|
|
28464
30043
|
labels,
|
|
28465
30044
|
debug: !!opts.debug
|
|
28466
30045
|
});
|
|
30046
|
+
spinner.stop();
|
|
28467
30047
|
printResult(result, opts.json);
|
|
28468
30048
|
} catch (err) {
|
|
30049
|
+
spinner.stop();
|
|
28469
30050
|
const message = err instanceof Error ? err.message : String(err);
|
|
28470
30051
|
console.error(message);
|
|
28471
30052
|
process.exitCode = 1;
|
|
28472
30053
|
}
|
|
28473
30054
|
});
|
|
28474
|
-
issues.command("update <issueId>").description("update an existing issue (title/description/status/labels)").option("--title <text>", "new title (
|
|
30055
|
+
issues.command("update <issueId>").description("update an existing issue (title/description/status/labels)").option("--title <text>", "new title (use \\n for newlines)").option("--description <text>", "new description (use \\n for newlines)").option("--status <value>", "status: open|closed|0|1").option("--label <label>", "set labels (repeatable). If provided, replaces existing labels.", (value, previous) => {
|
|
28475
30056
|
previous.push(value);
|
|
28476
30057
|
return previous;
|
|
28477
30058
|
}, []).option("--clear-labels", "set labels to an empty list").option("--debug", "enable debug output").option("--json", "output raw JSON").action(async (issueId, opts) => {
|
|
28478
|
-
|
|
28479
|
-
|
|
28480
|
-
|
|
28481
|
-
|
|
28482
|
-
|
|
28483
|
-
|
|
28484
|
-
|
|
28485
|
-
|
|
28486
|
-
|
|
28487
|
-
|
|
28488
|
-
|
|
28489
|
-
|
|
28490
|
-
|
|
28491
|
-
|
|
28492
|
-
|
|
28493
|
-
|
|
28494
|
-
|
|
28495
|
-
|
|
28496
|
-
|
|
28497
|
-
|
|
28498
|
-
|
|
28499
|
-
|
|
28500
|
-
console.error("status must be open|closed|0|1");
|
|
28501
|
-
process.exitCode = 1;
|
|
28502
|
-
return;
|
|
28503
|
-
}
|
|
28504
|
-
status = n;
|
|
28505
|
-
}
|
|
28506
|
-
if (status !== 0 && status !== 1) {
|
|
28507
|
-
console.error("status must be 0 (open) or 1 (closed)");
|
|
30059
|
+
const rootOpts = program2.opts();
|
|
30060
|
+
const cfg = readConfig();
|
|
30061
|
+
const { apiKey } = getConfig(rootOpts);
|
|
30062
|
+
if (!apiKey) {
|
|
30063
|
+
console.error("API key is required. Run 'pgai auth' first or set --api-key.");
|
|
30064
|
+
process.exitCode = 1;
|
|
30065
|
+
return;
|
|
30066
|
+
}
|
|
30067
|
+
const { apiBaseUrl } = resolveBaseUrls2(rootOpts, cfg);
|
|
30068
|
+
const title = opts.title !== undefined ? interpretEscapes2(String(opts.title)) : undefined;
|
|
30069
|
+
const description = opts.description !== undefined ? interpretEscapes2(String(opts.description)) : undefined;
|
|
30070
|
+
let status = undefined;
|
|
30071
|
+
if (opts.status !== undefined) {
|
|
30072
|
+
const raw = String(opts.status).trim().toLowerCase();
|
|
30073
|
+
if (raw === "open")
|
|
30074
|
+
status = 0;
|
|
30075
|
+
else if (raw === "closed")
|
|
30076
|
+
status = 1;
|
|
30077
|
+
else {
|
|
30078
|
+
const n = Number(raw);
|
|
30079
|
+
if (!Number.isFinite(n)) {
|
|
30080
|
+
console.error("status must be open|closed|0|1");
|
|
28508
30081
|
process.exitCode = 1;
|
|
28509
30082
|
return;
|
|
28510
30083
|
}
|
|
30084
|
+
status = n;
|
|
28511
30085
|
}
|
|
28512
|
-
|
|
28513
|
-
|
|
28514
|
-
|
|
28515
|
-
|
|
28516
|
-
labels = opts.label.map(String);
|
|
30086
|
+
if (status !== 0 && status !== 1) {
|
|
30087
|
+
console.error("status must be 0 (open) or 1 (closed)");
|
|
30088
|
+
process.exitCode = 1;
|
|
30089
|
+
return;
|
|
28517
30090
|
}
|
|
30091
|
+
}
|
|
30092
|
+
let labels = undefined;
|
|
30093
|
+
if (opts.clearLabels) {
|
|
30094
|
+
labels = [];
|
|
30095
|
+
} else if (Array.isArray(opts.label) && opts.label.length > 0) {
|
|
30096
|
+
labels = opts.label.map(String);
|
|
30097
|
+
}
|
|
30098
|
+
const spinner = createTtySpinner(process.stdout.isTTY ?? false, "Updating issue...");
|
|
30099
|
+
try {
|
|
28518
30100
|
const result = await updateIssue2({
|
|
28519
30101
|
apiKey,
|
|
28520
30102
|
apiBaseUrl,
|
|
@@ -28525,40 +30107,217 @@ issues.command("update <issueId>").description("update an existing issue (title/
|
|
|
28525
30107
|
labels,
|
|
28526
30108
|
debug: !!opts.debug
|
|
28527
30109
|
});
|
|
30110
|
+
spinner.stop();
|
|
28528
30111
|
printResult(result, opts.json);
|
|
28529
30112
|
} catch (err) {
|
|
30113
|
+
spinner.stop();
|
|
28530
30114
|
const message = err instanceof Error ? err.message : String(err);
|
|
28531
30115
|
console.error(message);
|
|
28532
30116
|
process.exitCode = 1;
|
|
28533
30117
|
}
|
|
28534
30118
|
});
|
|
28535
30119
|
issues.command("update-comment <commentId> <content>").description("update an existing issue comment").option("--debug", "enable debug output").option("--json", "output raw JSON").action(async (commentId, content, opts) => {
|
|
30120
|
+
if (opts.debug) {
|
|
30121
|
+
console.log(`Debug: Original content: ${JSON.stringify(content)}`);
|
|
30122
|
+
}
|
|
30123
|
+
content = interpretEscapes2(content);
|
|
30124
|
+
if (opts.debug) {
|
|
30125
|
+
console.log(`Debug: Interpreted content: ${JSON.stringify(content)}`);
|
|
30126
|
+
}
|
|
30127
|
+
const rootOpts = program2.opts();
|
|
30128
|
+
const cfg = readConfig();
|
|
30129
|
+
const { apiKey } = getConfig(rootOpts);
|
|
30130
|
+
if (!apiKey) {
|
|
30131
|
+
console.error("API key is required. Run 'pgai auth' first or set --api-key.");
|
|
30132
|
+
process.exitCode = 1;
|
|
30133
|
+
return;
|
|
30134
|
+
}
|
|
30135
|
+
const spinner = createTtySpinner(process.stdout.isTTY ?? false, "Updating comment...");
|
|
28536
30136
|
try {
|
|
28537
|
-
|
|
28538
|
-
|
|
28539
|
-
|
|
28540
|
-
|
|
28541
|
-
|
|
28542
|
-
|
|
30137
|
+
const { apiBaseUrl } = resolveBaseUrls2(rootOpts, cfg);
|
|
30138
|
+
const result = await updateIssueComment2({
|
|
30139
|
+
apiKey,
|
|
30140
|
+
apiBaseUrl,
|
|
30141
|
+
commentId,
|
|
30142
|
+
content,
|
|
30143
|
+
debug: !!opts.debug
|
|
30144
|
+
});
|
|
30145
|
+
spinner.stop();
|
|
30146
|
+
printResult(result, opts.json);
|
|
30147
|
+
} catch (err) {
|
|
30148
|
+
spinner.stop();
|
|
30149
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
30150
|
+
console.error(message);
|
|
30151
|
+
process.exitCode = 1;
|
|
30152
|
+
}
|
|
30153
|
+
});
|
|
30154
|
+
issues.command("action-items <issueId>").description("list action items for an issue").option("--debug", "enable debug output").option("--json", "output raw JSON").action(async (issueId, opts) => {
|
|
30155
|
+
const spinner = createTtySpinner(process.stdout.isTTY ?? false, "Fetching action items...");
|
|
30156
|
+
try {
|
|
30157
|
+
const rootOpts = program2.opts();
|
|
30158
|
+
const cfg = readConfig();
|
|
30159
|
+
const { apiKey } = getConfig(rootOpts);
|
|
30160
|
+
if (!apiKey) {
|
|
30161
|
+
spinner.stop();
|
|
30162
|
+
console.error("API key is required. Run 'pgai auth' first or set --api-key.");
|
|
30163
|
+
process.exitCode = 1;
|
|
30164
|
+
return;
|
|
28543
30165
|
}
|
|
30166
|
+
const { apiBaseUrl } = resolveBaseUrls2(rootOpts, cfg);
|
|
30167
|
+
const result = await fetchActionItems2({ apiKey, apiBaseUrl, issueId, debug: !!opts.debug });
|
|
30168
|
+
spinner.stop();
|
|
30169
|
+
printResult(result, opts.json);
|
|
30170
|
+
} catch (err) {
|
|
30171
|
+
spinner.stop();
|
|
30172
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
30173
|
+
console.error(message);
|
|
30174
|
+
process.exitCode = 1;
|
|
30175
|
+
}
|
|
30176
|
+
});
|
|
30177
|
+
issues.command("view-action-item <actionItemIds...>").description("view action item(s) with all details (supports multiple IDs)").option("--debug", "enable debug output").option("--json", "output raw JSON").action(async (actionItemIds, opts) => {
|
|
30178
|
+
const spinner = createTtySpinner(process.stdout.isTTY ?? false, "Fetching action item(s)...");
|
|
30179
|
+
try {
|
|
28544
30180
|
const rootOpts = program2.opts();
|
|
28545
30181
|
const cfg = readConfig();
|
|
28546
30182
|
const { apiKey } = getConfig(rootOpts);
|
|
28547
30183
|
if (!apiKey) {
|
|
30184
|
+
spinner.stop();
|
|
28548
30185
|
console.error("API key is required. Run 'pgai auth' first or set --api-key.");
|
|
28549
30186
|
process.exitCode = 1;
|
|
28550
30187
|
return;
|
|
28551
30188
|
}
|
|
28552
30189
|
const { apiBaseUrl } = resolveBaseUrls2(rootOpts, cfg);
|
|
28553
|
-
const result = await
|
|
30190
|
+
const result = await fetchActionItem2({ apiKey, apiBaseUrl, actionItemIds, debug: !!opts.debug });
|
|
30191
|
+
if (result.length === 0) {
|
|
30192
|
+
spinner.stop();
|
|
30193
|
+
console.error("Action item(s) not found");
|
|
30194
|
+
process.exitCode = 1;
|
|
30195
|
+
return;
|
|
30196
|
+
}
|
|
30197
|
+
spinner.stop();
|
|
30198
|
+
printResult(result, opts.json);
|
|
30199
|
+
} catch (err) {
|
|
30200
|
+
spinner.stop();
|
|
30201
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
30202
|
+
console.error(message);
|
|
30203
|
+
process.exitCode = 1;
|
|
30204
|
+
}
|
|
30205
|
+
});
|
|
30206
|
+
issues.command("create-action-item <issueId> <title>").description("create a new action item for an issue").option("--description <text>", "detailed description (use \\n for newlines)").option("--sql-action <sql>", "SQL command to execute").option("--config <json>", 'config change as JSON: {"parameter":"...","value":"..."} (repeatable)', (value, previous) => {
|
|
30207
|
+
try {
|
|
30208
|
+
previous.push(JSON.parse(value));
|
|
30209
|
+
} catch {
|
|
30210
|
+
console.error(`Invalid JSON for --config: ${value}`);
|
|
30211
|
+
process.exit(1);
|
|
30212
|
+
}
|
|
30213
|
+
return previous;
|
|
30214
|
+
}, []).option("--debug", "enable debug output").option("--json", "output raw JSON").action(async (issueId, rawTitle, opts) => {
|
|
30215
|
+
const rootOpts = program2.opts();
|
|
30216
|
+
const cfg = readConfig();
|
|
30217
|
+
const { apiKey } = getConfig(rootOpts);
|
|
30218
|
+
if (!apiKey) {
|
|
30219
|
+
console.error("API key is required. Run 'pgai auth' first or set --api-key.");
|
|
30220
|
+
process.exitCode = 1;
|
|
30221
|
+
return;
|
|
30222
|
+
}
|
|
30223
|
+
const title = interpretEscapes2(String(rawTitle || "").trim());
|
|
30224
|
+
if (!title) {
|
|
30225
|
+
console.error("title is required");
|
|
30226
|
+
process.exitCode = 1;
|
|
30227
|
+
return;
|
|
30228
|
+
}
|
|
30229
|
+
const description = opts.description !== undefined ? interpretEscapes2(String(opts.description)) : undefined;
|
|
30230
|
+
const sqlAction = opts.sqlAction;
|
|
30231
|
+
const configs = Array.isArray(opts.config) && opts.config.length > 0 ? opts.config : undefined;
|
|
30232
|
+
const spinner = createTtySpinner(process.stdout.isTTY ?? false, "Creating action item...");
|
|
30233
|
+
try {
|
|
30234
|
+
const { apiBaseUrl } = resolveBaseUrls2(rootOpts, cfg);
|
|
30235
|
+
const result = await createActionItem2({
|
|
28554
30236
|
apiKey,
|
|
28555
30237
|
apiBaseUrl,
|
|
28556
|
-
|
|
28557
|
-
|
|
30238
|
+
issueId,
|
|
30239
|
+
title,
|
|
30240
|
+
description,
|
|
30241
|
+
sqlAction,
|
|
30242
|
+
configs,
|
|
28558
30243
|
debug: !!opts.debug
|
|
28559
30244
|
});
|
|
28560
|
-
|
|
30245
|
+
spinner.stop();
|
|
30246
|
+
printResult({ id: result }, opts.json);
|
|
30247
|
+
} catch (err) {
|
|
30248
|
+
spinner.stop();
|
|
30249
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
30250
|
+
console.error(message);
|
|
30251
|
+
process.exitCode = 1;
|
|
30252
|
+
}
|
|
30253
|
+
});
|
|
30254
|
+
issues.command("update-action-item <actionItemId>").description("update an action item (title, description, status, sql_action, configs)").option("--title <text>", "new title (use \\n for newlines)").option("--description <text>", "new description (use \\n for newlines)").option("--done", "mark as done").option("--not-done", "mark as not done").option("--status <value>", "status: waiting_for_approval|approved|rejected").option("--status-reason <text>", "reason for status change").option("--sql-action <sql>", "SQL command (use empty string to clear)").option("--config <json>", "config change as JSON (repeatable, replaces all configs)", (value, previous) => {
|
|
30255
|
+
try {
|
|
30256
|
+
previous.push(JSON.parse(value));
|
|
30257
|
+
} catch {
|
|
30258
|
+
console.error(`Invalid JSON for --config: ${value}`);
|
|
30259
|
+
process.exit(1);
|
|
30260
|
+
}
|
|
30261
|
+
return previous;
|
|
30262
|
+
}, []).option("--clear-configs", "clear all config changes").option("--debug", "enable debug output").option("--json", "output raw JSON").action(async (actionItemId, opts) => {
|
|
30263
|
+
const rootOpts = program2.opts();
|
|
30264
|
+
const cfg = readConfig();
|
|
30265
|
+
const { apiKey } = getConfig(rootOpts);
|
|
30266
|
+
if (!apiKey) {
|
|
30267
|
+
console.error("API key is required. Run 'pgai auth' first or set --api-key.");
|
|
30268
|
+
process.exitCode = 1;
|
|
30269
|
+
return;
|
|
30270
|
+
}
|
|
30271
|
+
const title = opts.title !== undefined ? interpretEscapes2(String(opts.title)) : undefined;
|
|
30272
|
+
const description = opts.description !== undefined ? interpretEscapes2(String(opts.description)) : undefined;
|
|
30273
|
+
let isDone = undefined;
|
|
30274
|
+
if (opts.done)
|
|
30275
|
+
isDone = true;
|
|
30276
|
+
else if (opts.notDone)
|
|
30277
|
+
isDone = false;
|
|
30278
|
+
let status = undefined;
|
|
30279
|
+
if (opts.status !== undefined) {
|
|
30280
|
+
const validStatuses = ["waiting_for_approval", "approved", "rejected"];
|
|
30281
|
+
if (!validStatuses.includes(opts.status)) {
|
|
30282
|
+
console.error(`status must be one of: ${validStatuses.join(", ")}`);
|
|
30283
|
+
process.exitCode = 1;
|
|
30284
|
+
return;
|
|
30285
|
+
}
|
|
30286
|
+
status = opts.status;
|
|
30287
|
+
}
|
|
30288
|
+
const statusReason = opts.statusReason;
|
|
30289
|
+
const sqlAction = opts.sqlAction;
|
|
30290
|
+
let configs = undefined;
|
|
30291
|
+
if (opts.clearConfigs) {
|
|
30292
|
+
configs = [];
|
|
30293
|
+
} else if (Array.isArray(opts.config) && opts.config.length > 0) {
|
|
30294
|
+
configs = opts.config;
|
|
30295
|
+
}
|
|
30296
|
+
if (title === undefined && description === undefined && isDone === undefined && status === undefined && statusReason === undefined && sqlAction === undefined && configs === undefined) {
|
|
30297
|
+
console.error("At least one update option is required");
|
|
30298
|
+
process.exitCode = 1;
|
|
30299
|
+
return;
|
|
30300
|
+
}
|
|
30301
|
+
const spinner = createTtySpinner(process.stdout.isTTY ?? false, "Updating action item...");
|
|
30302
|
+
try {
|
|
30303
|
+
const { apiBaseUrl } = resolveBaseUrls2(rootOpts, cfg);
|
|
30304
|
+
await updateActionItem2({
|
|
30305
|
+
apiKey,
|
|
30306
|
+
apiBaseUrl,
|
|
30307
|
+
actionItemId,
|
|
30308
|
+
title,
|
|
30309
|
+
description,
|
|
30310
|
+
isDone,
|
|
30311
|
+
status,
|
|
30312
|
+
statusReason,
|
|
30313
|
+
sqlAction,
|
|
30314
|
+
configs,
|
|
30315
|
+
debug: !!opts.debug
|
|
30316
|
+
});
|
|
30317
|
+
spinner.stop();
|
|
30318
|
+
printResult({ success: true }, opts.json);
|
|
28561
30319
|
} catch (err) {
|
|
30320
|
+
spinner.stop();
|
|
28562
30321
|
const message = err instanceof Error ? err.message : String(err);
|
|
28563
30322
|
console.error(message);
|
|
28564
30323
|
process.exitCode = 1;
|