struere 0.9.3 → 0.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/struere.js +589 -43
- package/dist/cli/commands/entities.d.ts.map +1 -1
- package/dist/cli/commands/integration.d.ts +3 -0
- package/dist/cli/commands/integration.d.ts.map +1 -0
- package/dist/cli/commands/sync.d.ts.map +1 -1
- package/dist/cli/index.js +504 -19
- package/dist/cli/utils/convex.d.ts +2 -0
- package/dist/cli/utils/convex.d.ts.map +1 -1
- package/dist/cli/utils/credentials.d.ts +1 -0
- package/dist/cli/utils/credentials.d.ts.map +1 -1
- package/dist/cli/utils/entities.d.ts +4 -0
- package/dist/cli/utils/entities.d.ts.map +1 -1
- package/dist/cli/utils/extractor.d.ts.map +1 -1
- package/dist/cli/utils/integrations.d.ts +27 -0
- package/dist/cli/utils/integrations.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/bin/struere.js
CHANGED
|
@@ -17389,10 +17389,10 @@ var source_default = chalk;
|
|
|
17389
17389
|
// ../../node_modules/.bun/ora@8.2.0/node_modules/ora/index.js
|
|
17390
17390
|
import process9 from "process";
|
|
17391
17391
|
|
|
17392
|
-
// ../../node_modules/.bun/
|
|
17392
|
+
// ../../node_modules/.bun/ora@8.2.0/node_modules/ora/node_modules/cli-cursor/index.js
|
|
17393
17393
|
import process5 from "process";
|
|
17394
17394
|
|
|
17395
|
-
// ../../node_modules/.bun/
|
|
17395
|
+
// ../../node_modules/.bun/ora@8.2.0/node_modules/ora/node_modules/cli-cursor/node_modules/restore-cursor/index.js
|
|
17396
17396
|
import process4 from "process";
|
|
17397
17397
|
|
|
17398
17398
|
// ../../node_modules/.bun/mimic-function@5.0.1/node_modules/mimic-function/index.js
|
|
@@ -17441,7 +17441,7 @@ function mimicFunction(to, from, { ignoreNonConfigurable = false } = {}) {
|
|
|
17441
17441
|
return to;
|
|
17442
17442
|
}
|
|
17443
17443
|
|
|
17444
|
-
// ../../node_modules/.bun/
|
|
17444
|
+
// ../../node_modules/.bun/ora@8.2.0/node_modules/ora/node_modules/cli-cursor/node_modules/restore-cursor/node_modules/onetime/index.js
|
|
17445
17445
|
var calledFunctions = new WeakMap;
|
|
17446
17446
|
var onetime = (function_, options = {}) => {
|
|
17447
17447
|
if (typeof function_ !== "function") {
|
|
@@ -17680,7 +17680,7 @@ var {
|
|
|
17680
17680
|
unload
|
|
17681
17681
|
} = signalExitWrap(processOk(process3) ? new SignalExit(process3) : new SignalExitFallback);
|
|
17682
17682
|
|
|
17683
|
-
// ../../node_modules/.bun/
|
|
17683
|
+
// ../../node_modules/.bun/ora@8.2.0/node_modules/ora/node_modules/cli-cursor/node_modules/restore-cursor/index.js
|
|
17684
17684
|
var terminal = process4.stderr.isTTY ? process4.stderr : process4.stdout.isTTY ? process4.stdout : undefined;
|
|
17685
17685
|
var restoreCursor = terminal ? onetime_default(() => {
|
|
17686
17686
|
onExit(() => {
|
|
@@ -17689,7 +17689,7 @@ var restoreCursor = terminal ? onetime_default(() => {
|
|
|
17689
17689
|
}) : () => {};
|
|
17690
17690
|
var restore_cursor_default = restoreCursor;
|
|
17691
17691
|
|
|
17692
|
-
// ../../node_modules/.bun/
|
|
17692
|
+
// ../../node_modules/.bun/ora@8.2.0/node_modules/ora/node_modules/cli-cursor/index.js
|
|
17693
17693
|
var isHidden = false;
|
|
17694
17694
|
var cliCursor = {};
|
|
17695
17695
|
cliCursor.show = (writableStream = process5.stderr) => {
|
|
@@ -17722,7 +17722,7 @@ var cli_cursor_default = cliCursor;
|
|
|
17722
17722
|
// ../../node_modules/.bun/ora@8.2.0/node_modules/ora/index.js
|
|
17723
17723
|
var import_cli_spinners = __toESM(require_cli_spinners(), 1);
|
|
17724
17724
|
|
|
17725
|
-
// ../../node_modules/.bun/
|
|
17725
|
+
// ../../node_modules/.bun/ora@8.2.0/node_modules/ora/node_modules/log-symbols/node_modules/is-unicode-supported/index.js
|
|
17726
17726
|
import process6 from "process";
|
|
17727
17727
|
function isUnicodeSupported() {
|
|
17728
17728
|
if (process6.platform !== "win32") {
|
|
@@ -17731,7 +17731,7 @@ function isUnicodeSupported() {
|
|
|
17731
17731
|
return Boolean(process6.env.CI) || Boolean(process6.env.WT_SESSION) || Boolean(process6.env.TERMINUS_SUBLIME) || process6.env.ConEmuTask === "{cmd::Cmder}" || process6.env.TERM_PROGRAM === "Terminus-Sublime" || process6.env.TERM_PROGRAM === "vscode" || process6.env.TERM === "xterm-256color" || process6.env.TERM === "alacritty" || process6.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
17732
17732
|
}
|
|
17733
17733
|
|
|
17734
|
-
// ../../node_modules/.bun/
|
|
17734
|
+
// ../../node_modules/.bun/ora@8.2.0/node_modules/ora/node_modules/log-symbols/index.js
|
|
17735
17735
|
var main = {
|
|
17736
17736
|
info: source_default.blue("\u2139"),
|
|
17737
17737
|
success: source_default.green("\u2714"),
|
|
@@ -17747,16 +17747,17 @@ var fallback = {
|
|
|
17747
17747
|
var logSymbols = isUnicodeSupported() ? main : fallback;
|
|
17748
17748
|
var log_symbols_default = logSymbols;
|
|
17749
17749
|
|
|
17750
|
-
// ../../node_modules/.bun/
|
|
17750
|
+
// ../../node_modules/.bun/ora@8.2.0/node_modules/ora/node_modules/strip-ansi/node_modules/ansi-regex/index.js
|
|
17751
17751
|
function ansiRegex({ onlyFirst = false } = {}) {
|
|
17752
17752
|
const ST = "(?:\\u0007|\\u001B\\u005C|\\u009C)";
|
|
17753
|
-
const
|
|
17754
|
-
|
|
17755
|
-
|
|
17753
|
+
const pattern = [
|
|
17754
|
+
`[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?${ST})`,
|
|
17755
|
+
"(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"
|
|
17756
|
+
].join("|");
|
|
17756
17757
|
return new RegExp(pattern, onlyFirst ? undefined : "g");
|
|
17757
17758
|
}
|
|
17758
17759
|
|
|
17759
|
-
// ../../node_modules/.bun/
|
|
17760
|
+
// ../../node_modules/.bun/ora@8.2.0/node_modules/ora/node_modules/strip-ansi/index.js
|
|
17760
17761
|
var regex = ansiRegex();
|
|
17761
17762
|
function stripAnsi(string) {
|
|
17762
17763
|
if (typeof string !== "string") {
|
|
@@ -17765,18 +17766,83 @@ function stripAnsi(string) {
|
|
|
17765
17766
|
return string.replace(regex, "");
|
|
17766
17767
|
}
|
|
17767
17768
|
|
|
17768
|
-
// ../../node_modules/.bun/get-east-asian-width@1.
|
|
17769
|
-
|
|
17770
|
-
|
|
17771
|
-
|
|
17772
|
-
|
|
17773
|
-
|
|
17774
|
-
|
|
17775
|
-
|
|
17776
|
-
|
|
17769
|
+
// ../../node_modules/.bun/get-east-asian-width@1.5.0/node_modules/get-east-asian-width/lookup-data.js
|
|
17770
|
+
var ambiguousRanges = [161, 161, 164, 164, 167, 168, 170, 170, 173, 174, 176, 180, 182, 186, 188, 191, 198, 198, 208, 208, 215, 216, 222, 225, 230, 230, 232, 234, 236, 237, 240, 240, 242, 243, 247, 250, 252, 252, 254, 254, 257, 257, 273, 273, 275, 275, 283, 283, 294, 295, 299, 299, 305, 307, 312, 312, 319, 322, 324, 324, 328, 331, 333, 333, 338, 339, 358, 359, 363, 363, 462, 462, 464, 464, 466, 466, 468, 468, 470, 470, 472, 472, 474, 474, 476, 476, 593, 593, 609, 609, 708, 708, 711, 711, 713, 715, 717, 717, 720, 720, 728, 731, 733, 733, 735, 735, 768, 879, 913, 929, 931, 937, 945, 961, 963, 969, 1025, 1025, 1040, 1103, 1105, 1105, 8208, 8208, 8211, 8214, 8216, 8217, 8220, 8221, 8224, 8226, 8228, 8231, 8240, 8240, 8242, 8243, 8245, 8245, 8251, 8251, 8254, 8254, 8308, 8308, 8319, 8319, 8321, 8324, 8364, 8364, 8451, 8451, 8453, 8453, 8457, 8457, 8467, 8467, 8470, 8470, 8481, 8482, 8486, 8486, 8491, 8491, 8531, 8532, 8539, 8542, 8544, 8555, 8560, 8569, 8585, 8585, 8592, 8601, 8632, 8633, 8658, 8658, 8660, 8660, 8679, 8679, 8704, 8704, 8706, 8707, 8711, 8712, 8715, 8715, 8719, 8719, 8721, 8721, 8725, 8725, 8730, 8730, 8733, 8736, 8739, 8739, 8741, 8741, 8743, 8748, 8750, 8750, 8756, 8759, 8764, 8765, 8776, 8776, 8780, 8780, 8786, 8786, 8800, 8801, 8804, 8807, 8810, 8811, 8814, 8815, 8834, 8835, 8838, 8839, 8853, 8853, 8857, 8857, 8869, 8869, 8895, 8895, 8978, 8978, 9312, 9449, 9451, 9547, 9552, 9587, 9600, 9615, 9618, 9621, 9632, 9633, 9635, 9641, 9650, 9651, 9654, 9655, 9660, 9661, 9664, 9665, 9670, 9672, 9675, 9675, 9678, 9681, 9698, 9701, 9711, 9711, 9733, 9734, 9737, 9737, 9742, 9743, 9756, 9756, 9758, 9758, 9792, 9792, 9794, 9794, 9824, 9825, 9827, 9829, 9831, 9834, 9836, 9837, 9839, 9839, 9886, 9887, 9919, 9919, 9926, 9933, 9935, 9939, 9941, 9953, 9955, 9955, 9960, 9961, 9963, 9969, 9972, 9972, 9974, 9977, 9979, 9980, 9982, 9983, 10045, 10045, 10102, 10111, 11094, 11097, 12872, 12879, 57344, 63743, 65024, 65039, 65533, 65533, 127232, 127242, 127248, 127277, 127280, 127337, 127344, 127373, 127375, 127376, 127387, 127404, 917760, 917999, 983040, 1048573, 1048576, 1114109];
|
|
17771
|
+
var fullwidthRanges = [12288, 12288, 65281, 65376, 65504, 65510];
|
|
17772
|
+
var halfwidthRanges = [8361, 8361, 65377, 65470, 65474, 65479, 65482, 65487, 65490, 65495, 65498, 65500, 65512, 65518];
|
|
17773
|
+
var narrowRanges = [32, 126, 162, 163, 165, 166, 172, 172, 175, 175, 10214, 10221, 10629, 10630];
|
|
17774
|
+
var wideRanges = [4352, 4447, 8986, 8987, 9001, 9002, 9193, 9196, 9200, 9200, 9203, 9203, 9725, 9726, 9748, 9749, 9776, 9783, 9800, 9811, 9855, 9855, 9866, 9871, 9875, 9875, 9889, 9889, 9898, 9899, 9917, 9918, 9924, 9925, 9934, 9934, 9940, 9940, 9962, 9962, 9970, 9971, 9973, 9973, 9978, 9978, 9981, 9981, 9989, 9989, 9994, 9995, 10024, 10024, 10060, 10060, 10062, 10062, 10067, 10069, 10071, 10071, 10133, 10135, 10160, 10160, 10175, 10175, 11035, 11036, 11088, 11088, 11093, 11093, 11904, 11929, 11931, 12019, 12032, 12245, 12272, 12287, 12289, 12350, 12353, 12438, 12441, 12543, 12549, 12591, 12593, 12686, 12688, 12773, 12783, 12830, 12832, 12871, 12880, 42124, 42128, 42182, 43360, 43388, 44032, 55203, 63744, 64255, 65040, 65049, 65072, 65106, 65108, 65126, 65128, 65131, 94176, 94180, 94192, 94198, 94208, 101589, 101631, 101662, 101760, 101874, 110576, 110579, 110581, 110587, 110589, 110590, 110592, 110882, 110898, 110898, 110928, 110930, 110933, 110933, 110948, 110951, 110960, 111355, 119552, 119638, 119648, 119670, 126980, 126980, 127183, 127183, 127374, 127374, 127377, 127386, 127488, 127490, 127504, 127547, 127552, 127560, 127568, 127569, 127584, 127589, 127744, 127776, 127789, 127797, 127799, 127868, 127870, 127891, 127904, 127946, 127951, 127955, 127968, 127984, 127988, 127988, 127992, 128062, 128064, 128064, 128066, 128252, 128255, 128317, 128331, 128334, 128336, 128359, 128378, 128378, 128405, 128406, 128420, 128420, 128507, 128591, 128640, 128709, 128716, 128716, 128720, 128722, 128725, 128728, 128732, 128735, 128747, 128748, 128756, 128764, 128992, 129003, 129008, 129008, 129292, 129338, 129340, 129349, 129351, 129535, 129648, 129660, 129664, 129674, 129678, 129734, 129736, 129736, 129741, 129756, 129759, 129770, 129775, 129784, 131072, 196605, 196608, 262141];
|
|
17775
|
+
|
|
17776
|
+
// ../../node_modules/.bun/get-east-asian-width@1.5.0/node_modules/get-east-asian-width/utilities.js
|
|
17777
|
+
var isInRange = (ranges, codePoint) => {
|
|
17778
|
+
let low = 0;
|
|
17779
|
+
let high = Math.floor(ranges.length / 2) - 1;
|
|
17780
|
+
while (low <= high) {
|
|
17781
|
+
const mid = Math.floor((low + high) / 2);
|
|
17782
|
+
const i = mid * 2;
|
|
17783
|
+
if (codePoint < ranges[i]) {
|
|
17784
|
+
high = mid - 1;
|
|
17785
|
+
} else if (codePoint > ranges[i + 1]) {
|
|
17786
|
+
low = mid + 1;
|
|
17787
|
+
} else {
|
|
17788
|
+
return true;
|
|
17789
|
+
}
|
|
17790
|
+
}
|
|
17791
|
+
return false;
|
|
17792
|
+
};
|
|
17793
|
+
|
|
17794
|
+
// ../../node_modules/.bun/get-east-asian-width@1.5.0/node_modules/get-east-asian-width/lookup.js
|
|
17795
|
+
var minimumAmbiguousCodePoint = ambiguousRanges[0];
|
|
17796
|
+
var maximumAmbiguousCodePoint = ambiguousRanges.at(-1);
|
|
17797
|
+
var minimumFullWidthCodePoint = fullwidthRanges[0];
|
|
17798
|
+
var maximumFullWidthCodePoint = fullwidthRanges.at(-1);
|
|
17799
|
+
var minimumHalfWidthCodePoint = halfwidthRanges[0];
|
|
17800
|
+
var maximumHalfWidthCodePoint = halfwidthRanges.at(-1);
|
|
17801
|
+
var minimumNarrowCodePoint = narrowRanges[0];
|
|
17802
|
+
var maximumNarrowCodePoint = narrowRanges.at(-1);
|
|
17803
|
+
var minimumWideCodePoint = wideRanges[0];
|
|
17804
|
+
var maximumWideCodePoint = wideRanges.at(-1);
|
|
17805
|
+
var commonCjkCodePoint = 19968;
|
|
17806
|
+
var [wideFastPathStart, wideFastPathEnd] = findWideFastPathRange(wideRanges);
|
|
17807
|
+
function findWideFastPathRange(ranges) {
|
|
17808
|
+
let fastPathStart = ranges[0];
|
|
17809
|
+
let fastPathEnd = ranges[1];
|
|
17810
|
+
for (let index = 0;index < ranges.length; index += 2) {
|
|
17811
|
+
const start = ranges[index];
|
|
17812
|
+
const end = ranges[index + 1];
|
|
17813
|
+
if (commonCjkCodePoint >= start && commonCjkCodePoint <= end) {
|
|
17814
|
+
return [start, end];
|
|
17815
|
+
}
|
|
17816
|
+
if (end - start > fastPathEnd - fastPathStart) {
|
|
17817
|
+
fastPathStart = start;
|
|
17818
|
+
fastPathEnd = end;
|
|
17819
|
+
}
|
|
17820
|
+
}
|
|
17821
|
+
return [fastPathStart, fastPathEnd];
|
|
17777
17822
|
}
|
|
17823
|
+
var isAmbiguous = (codePoint) => {
|
|
17824
|
+
if (codePoint < minimumAmbiguousCodePoint || codePoint > maximumAmbiguousCodePoint) {
|
|
17825
|
+
return false;
|
|
17826
|
+
}
|
|
17827
|
+
return isInRange(ambiguousRanges, codePoint);
|
|
17828
|
+
};
|
|
17829
|
+
var isFullWidth = (codePoint) => {
|
|
17830
|
+
if (codePoint < minimumFullWidthCodePoint || codePoint > maximumFullWidthCodePoint) {
|
|
17831
|
+
return false;
|
|
17832
|
+
}
|
|
17833
|
+
return isInRange(fullwidthRanges, codePoint);
|
|
17834
|
+
};
|
|
17835
|
+
var isWide = (codePoint) => {
|
|
17836
|
+
if (codePoint >= wideFastPathStart && codePoint <= wideFastPathEnd) {
|
|
17837
|
+
return true;
|
|
17838
|
+
}
|
|
17839
|
+
if (codePoint < minimumWideCodePoint || codePoint > maximumWideCodePoint) {
|
|
17840
|
+
return false;
|
|
17841
|
+
}
|
|
17842
|
+
return isInRange(wideRanges, codePoint);
|
|
17843
|
+
};
|
|
17778
17844
|
|
|
17779
|
-
// ../../node_modules/.bun/get-east-asian-width@1.
|
|
17845
|
+
// ../../node_modules/.bun/get-east-asian-width@1.5.0/node_modules/get-east-asian-width/index.js
|
|
17780
17846
|
function validate(codePoint) {
|
|
17781
17847
|
if (!Number.isSafeInteger(codePoint)) {
|
|
17782
17848
|
throw new TypeError(`Expected a code point, got \`${typeof codePoint}\`.`);
|
|
@@ -17790,12 +17856,12 @@ function eastAsianWidth(codePoint, { ambiguousAsWide = false } = {}) {
|
|
|
17790
17856
|
return 1;
|
|
17791
17857
|
}
|
|
17792
17858
|
|
|
17793
|
-
// ../../node_modules/.bun/
|
|
17859
|
+
// ../../node_modules/.bun/ora@8.2.0/node_modules/ora/node_modules/string-width/node_modules/emoji-regex/index.mjs
|
|
17794
17860
|
var emoji_regex_default = () => {
|
|
17795
17861
|
return /[#*0-9]\uFE0F?\u20E3|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26AA\u26B0\u26B1\u26BD\u26BE\u26C4\u26C8\u26CF\u26D1\u26E9\u26F0-\u26F5\u26F7\u26F8\u26FA\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B55\u3030\u303D\u3297\u3299]\uFE0F?|[\u261D\u270C\u270D](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\u270A\u270B](?:\uD83C[\uDFFB-\uDFFF])?|[\u23E9-\u23EC\u23F0\u23F3\u25FD\u2693\u26A1\u26AB\u26C5\u26CE\u26D4\u26EA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2795-\u2797\u27B0\u27BF\u2B50]|\u26D3\uFE0F?(?:\u200D\uD83D\uDCA5)?|\u26F9(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\u2764\uFE0F?(?:\u200D(?:\uD83D\uDD25|\uD83E\uDE79))?|\uD83C(?:[\uDC04\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]\uFE0F?|[\uDF85\uDFC2\uDFC7](?:\uD83C[\uDFFB-\uDFFF])?|[\uDFC4\uDFCA](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDFCB\uDFCC](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF43\uDF45-\uDF4A\uDF4C-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uDDE6\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF]|\uDDE7\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF]|\uDDE8\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF7\uDDFA-\uDDFF]|\uDDE9\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF]|\uDDEA\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA]|\uDDEB\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7]|\uDDEC\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE]|\uDDED\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA]|\uDDEE\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9]|\uDDEF\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5]|\uDDF0\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF]|\uDDF1\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE]|\uDDF2\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF]|\uDDF3\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF]|\uDDF4\uD83C\uDDF2|\uDDF5\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE]|\uDDF6\uD83C\uDDE6|\uDDF7\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC]|\uDDF8\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF]|\uDDF9\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF]|\uDDFA\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF]|\uDDFB\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA]|\uDDFC\uD83C[\uDDEB\uDDF8]|\uDDFD\uD83C\uDDF0|\uDDFE\uD83C[\uDDEA\uDDF9]|\uDDFF\uD83C[\uDDE6\uDDF2\uDDFC]|\uDF44(?:\u200D\uD83D\uDFEB)?|\uDF4B(?:\u200D\uD83D\uDFE9)?|\uDFC3(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDFF3\uFE0F?(?:\u200D(?:\u26A7\uFE0F?|\uD83C\uDF08))?|\uDFF4(?:\u200D\u2620\uFE0F?|\uDB40\uDC67\uDB40\uDC62\uDB40(?:\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDC73\uDB40\uDC63\uDB40\uDC74|\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F)?)|\uD83D(?:[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3]\uFE0F?|[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC](?:\uD83C[\uDFFB-\uDFFF])?|[\uDC6E-\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4\uDEB5](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD74\uDD90](?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?|[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC25\uDC27-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE41\uDE43\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED8\uDEDC-\uDEDF\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB\uDFF0]|\uDC08(?:\u200D\u2B1B)?|\uDC15(?:\u200D\uD83E\uDDBA)?|\uDC26(?:\u200D(?:\u2B1B|\uD83D\uDD25))?|\uDC3B(?:\u200D\u2744\uFE0F?)?|\uDC41\uFE0F?(?:\u200D\uD83D\uDDE8\uFE0F?)?|\uDC68(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDC68\uDC69]\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?)|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFC-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFD-\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFD\uDFFF]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?\uDC68\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDD1D\uDEEF]\u200D\uD83D\uDC68\uD83C[\uDFFB-\uDFFE]|[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3])))?))?|\uDC69(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:\uDC8B\u200D\uD83D)?[\uDC68\uDC69]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?|\uDC69\u200D\uD83D(?:\uDC66(?:\u200D\uD83D\uDC66)?|\uDC67(?:\u200D\uD83D[\uDC66\uDC67])?))|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFC-\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFD-\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFD\uDFFF]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D\uD83D(?:[\uDC68\uDC69]|\uDC8B\u200D\uD83D[\uDC68\uDC69])\uD83C[\uDFFB-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3]|\uDD1D\u200D\uD83D[\uDC68\uDC69]\uD83C[\uDFFB-\uDFFE]|\uDEEF\u200D\uD83D\uDC69\uD83C[\uDFFB-\uDFFE])))?))?|\uDD75(?:\uD83C[\uDFFB-\uDFFF]|\uFE0F)?(?:\u200D[\u2640\u2642]\uFE0F?)?|\uDE2E(?:\u200D\uD83D\uDCA8)?|\uDE35(?:\u200D\uD83D\uDCAB)?|\uDE36(?:\u200D\uD83C\uDF2B\uFE0F?)?|\uDE42(?:\u200D[\u2194\u2195]\uFE0F?)?|\uDEB6(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?)|\uD83E(?:[\uDD0C\uDD0F\uDD18-\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5\uDEC3-\uDEC5\uDEF0\uDEF2-\uDEF8](?:\uD83C[\uDFFB-\uDFFF])?|[\uDD26\uDD35\uDD37-\uDD39\uDD3C-\uDD3E\uDDB8\uDDB9\uDDCD\uDDCF\uDDD4\uDDD6-\uDDDD](?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDDDE\uDDDF](?:\u200D[\u2640\u2642]\uFE0F?)?|[\uDD0D\uDD0E\uDD10-\uDD17\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCC\uDDD0\uDDE0-\uDDFF\uDE70-\uDE7C\uDE80-\uDE8A\uDE8E-\uDEC2\uDEC6\uDEC8\uDECD-\uDEDC\uDEDF-\uDEEA\uDEEF]|\uDDCE(?:\uD83C[\uDFFB-\uDFFF])?(?:\u200D(?:[\u2640\u2642]\uFE0F?(?:\u200D\u27A1\uFE0F?)?|\u27A1\uFE0F?))?|\uDDD1(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1|\uDDD1\u200D\uD83E\uDDD2(?:\u200D\uD83E\uDDD2)?|\uDDD2(?:\u200D\uD83E\uDDD2)?))|\uD83C(?:\uDFFB(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFC-\uDFFF])))?|\uDFFC(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFD-\uDFFF])))?|\uDFFD(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])))?|\uDFFE(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFD\uDFFF])))?|\uDFFF(?:\u200D(?:[\u2695\u2696\u2708]\uFE0F?|\u2764\uFE0F?\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE]|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D(?:[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uDC30\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE])|\uD83E(?:[\uDDAF\uDDBC\uDDBD](?:\u200D\u27A1\uFE0F?)?|[\uDDB0-\uDDB3\uDE70]|\uDD1D\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFF]|\uDEEF\u200D\uD83E\uDDD1\uD83C[\uDFFB-\uDFFE])))?))?|\uDEF1(?:\uD83C(?:\uDFFB(?:\u200D\uD83E\uDEF2\uD83C[\uDFFC-\uDFFF])?|\uDFFC(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFD-\uDFFF])?|\uDFFD(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])?|\uDFFE(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFD\uDFFF])?|\uDFFF(?:\u200D\uD83E\uDEF2\uD83C[\uDFFB-\uDFFE])?))?)/g;
|
|
17796
17862
|
};
|
|
17797
17863
|
|
|
17798
|
-
// ../../node_modules/.bun/
|
|
17864
|
+
// ../../node_modules/.bun/ora@8.2.0/node_modules/ora/node_modules/string-width/index.js
|
|
17799
17865
|
var segmenter = new Intl.Segmenter;
|
|
17800
17866
|
var defaultIgnorableCodePointRegex = /^\p{Default_Ignorable_Code_Point}$/u;
|
|
17801
17867
|
function stringWidth(string, options = {}) {
|
|
@@ -19402,6 +19468,30 @@ var CONVEX_URL = process.env.STRUERE_CONVEX_URL || "https://rapid-wildebeest-172
|
|
|
19402
19468
|
function getSiteUrl() {
|
|
19403
19469
|
return CONVEX_URL.replace(".cloud", ".site");
|
|
19404
19470
|
}
|
|
19471
|
+
async function refreshToken() {
|
|
19472
|
+
const credentials = loadCredentials();
|
|
19473
|
+
if (!credentials?.sessionId)
|
|
19474
|
+
return null;
|
|
19475
|
+
const siteUrl = getSiteUrl();
|
|
19476
|
+
try {
|
|
19477
|
+
const response = await fetch(`${siteUrl}/v1/auth/refresh`, {
|
|
19478
|
+
method: "POST",
|
|
19479
|
+
headers: { "Content-Type": "application/json" },
|
|
19480
|
+
body: JSON.stringify({ sessionId: credentials.sessionId }),
|
|
19481
|
+
signal: AbortSignal.timeout(1e4)
|
|
19482
|
+
});
|
|
19483
|
+
if (!response.ok)
|
|
19484
|
+
return null;
|
|
19485
|
+
const data = await response.json();
|
|
19486
|
+
if (!data.token)
|
|
19487
|
+
return null;
|
|
19488
|
+
credentials.token = data.token;
|
|
19489
|
+
saveCredentials(credentials);
|
|
19490
|
+
return data.token;
|
|
19491
|
+
} catch {
|
|
19492
|
+
return null;
|
|
19493
|
+
}
|
|
19494
|
+
}
|
|
19405
19495
|
async function listMyOrganizations(token) {
|
|
19406
19496
|
const response = await fetch(`${CONVEX_URL}/api/query`, {
|
|
19407
19497
|
method: "POST",
|
|
@@ -19517,7 +19607,11 @@ async function syncOrganization(payload) {
|
|
|
19517
19607
|
if (apiKey && !credentials?.token) {
|
|
19518
19608
|
return syncViaHttp(apiKey, payload);
|
|
19519
19609
|
}
|
|
19520
|
-
|
|
19610
|
+
if (credentials?.sessionId) {
|
|
19611
|
+
await refreshToken();
|
|
19612
|
+
}
|
|
19613
|
+
const freshCredentials = loadCredentials();
|
|
19614
|
+
const token = apiKey || freshCredentials?.token;
|
|
19521
19615
|
if (!token) {
|
|
19522
19616
|
return { success: false, error: "Not authenticated" };
|
|
19523
19617
|
}
|
|
@@ -19584,7 +19678,11 @@ async function getSyncState(organizationId, environment) {
|
|
|
19584
19678
|
return { error: `Network error: ${err instanceof Error ? err.message : String(err)}` };
|
|
19585
19679
|
}
|
|
19586
19680
|
}
|
|
19587
|
-
|
|
19681
|
+
if (credentials?.sessionId) {
|
|
19682
|
+
await refreshToken();
|
|
19683
|
+
}
|
|
19684
|
+
const freshCredentials = loadCredentials();
|
|
19685
|
+
const token = apiKey || freshCredentials?.token;
|
|
19588
19686
|
if (!token) {
|
|
19589
19687
|
return { error: "Not authenticated" };
|
|
19590
19688
|
}
|
|
@@ -19636,7 +19734,11 @@ async function getPullState(organizationId, environment = "development") {
|
|
|
19636
19734
|
return { error: `Network error: ${err instanceof Error ? err.message : String(err)}` };
|
|
19637
19735
|
}
|
|
19638
19736
|
}
|
|
19639
|
-
|
|
19737
|
+
if (credentials?.sessionId) {
|
|
19738
|
+
await refreshToken();
|
|
19739
|
+
}
|
|
19740
|
+
const freshCredentials = loadCredentials();
|
|
19741
|
+
const token = apiKey || freshCredentials?.token;
|
|
19640
19742
|
if (!token) {
|
|
19641
19743
|
return { error: "Not authenticated" };
|
|
19642
19744
|
}
|
|
@@ -19693,6 +19795,7 @@ async function browserLogin(spinner) {
|
|
|
19693
19795
|
if (result) {
|
|
19694
19796
|
printNextSteps();
|
|
19695
19797
|
}
|
|
19798
|
+
process.exit(0);
|
|
19696
19799
|
}
|
|
19697
19800
|
async function browserLoginInternal(spinner) {
|
|
19698
19801
|
spinner.start("Starting authentication server");
|
|
@@ -19743,7 +19846,7 @@ async function browserLoginInternal(spinner) {
|
|
|
19743
19846
|
}
|
|
19744
19847
|
spinner.start("Waiting for authentication");
|
|
19745
19848
|
try {
|
|
19746
|
-
const { token } = await authPromise;
|
|
19849
|
+
const { token, sessionId } = await authPromise;
|
|
19747
19850
|
spinner.text = "Fetching user info";
|
|
19748
19851
|
const { userInfo, error } = await getUserInfo(token);
|
|
19749
19852
|
if (error || !userInfo) {
|
|
@@ -19752,6 +19855,7 @@ async function browserLoginInternal(spinner) {
|
|
|
19752
19855
|
const { user, organizations } = userInfo;
|
|
19753
19856
|
const credentials = {
|
|
19754
19857
|
token,
|
|
19858
|
+
sessionId,
|
|
19755
19859
|
user: {
|
|
19756
19860
|
id: user.id,
|
|
19757
19861
|
email: user.email,
|
|
@@ -21458,7 +21562,8 @@ var BUILTIN_TOOLS = [
|
|
|
21458
21562
|
"airtable.getRecord",
|
|
21459
21563
|
"airtable.createRecords",
|
|
21460
21564
|
"airtable.updateRecords",
|
|
21461
|
-
"airtable.deleteRecords"
|
|
21565
|
+
"airtable.deleteRecords",
|
|
21566
|
+
"email.send"
|
|
21462
21567
|
];
|
|
21463
21568
|
function extractSyncPayload(resources) {
|
|
21464
21569
|
const customToolsMap = new Map;
|
|
@@ -21628,7 +21733,8 @@ function getBuiltinToolDescription(name) {
|
|
|
21628
21733
|
"airtable.getRecord": "Get a single record from an Airtable table by ID",
|
|
21629
21734
|
"airtable.createRecords": "Create up to 10 records in an Airtable table",
|
|
21630
21735
|
"airtable.updateRecords": "Update up to 10 records in an Airtable table",
|
|
21631
|
-
"airtable.deleteRecords": "Delete up to 10 records from an Airtable table"
|
|
21736
|
+
"airtable.deleteRecords": "Delete up to 10 records from an Airtable table",
|
|
21737
|
+
"email.send": "Send an email via Resend"
|
|
21632
21738
|
};
|
|
21633
21739
|
return descriptions[name] || name;
|
|
21634
21740
|
}
|
|
@@ -21925,6 +22031,17 @@ function getBuiltinToolParameters(name) {
|
|
|
21925
22031
|
recordIds: { type: "array", items: { type: "string" }, description: "Array of record IDs to delete (max 10)" }
|
|
21926
22032
|
},
|
|
21927
22033
|
required: ["baseId", "tableIdOrName", "recordIds"]
|
|
22034
|
+
},
|
|
22035
|
+
"email.send": {
|
|
22036
|
+
type: "object",
|
|
22037
|
+
properties: {
|
|
22038
|
+
to: { type: "string", description: "Recipient email address" },
|
|
22039
|
+
subject: { type: "string", description: "Email subject line" },
|
|
22040
|
+
html: { type: "string", description: "HTML body content" },
|
|
22041
|
+
text: { type: "string", description: "Plain text body content" },
|
|
22042
|
+
replyTo: { type: "string", description: "Reply-to email address" }
|
|
22043
|
+
},
|
|
22044
|
+
required: ["to", "subject"]
|
|
21928
22045
|
}
|
|
21929
22046
|
};
|
|
21930
22047
|
return schemas[name] || { type: "object", properties: {} };
|
|
@@ -22213,13 +22330,32 @@ var syncCommand = new Command("sync").description("Sync resources to Convex and
|
|
|
22213
22330
|
}));
|
|
22214
22331
|
}
|
|
22215
22332
|
} catch (error) {
|
|
22216
|
-
if (jsonMode) {
|
|
22217
|
-
|
|
22333
|
+
if (isAuthError(error) && interactive && !jsonMode) {
|
|
22334
|
+
output.fail("Session expired - re-authenticating...");
|
|
22335
|
+
clearCredentials();
|
|
22336
|
+
const newCredentials = await performLogin();
|
|
22337
|
+
if (!newCredentials) {
|
|
22338
|
+
output.error("Authentication failed");
|
|
22339
|
+
process.exit(1);
|
|
22340
|
+
}
|
|
22341
|
+
output.start("Syncing to Convex");
|
|
22342
|
+
try {
|
|
22343
|
+
const result = await syncToEnvironment(cwd, project.organization.id, environment);
|
|
22344
|
+
output.succeed(`Synced to ${environment}`);
|
|
22345
|
+
} catch (retryError) {
|
|
22346
|
+
output.fail("Sync failed");
|
|
22347
|
+
output.error(retryError instanceof Error ? retryError.message : String(retryError));
|
|
22348
|
+
process.exit(1);
|
|
22349
|
+
}
|
|
22218
22350
|
} else {
|
|
22219
|
-
|
|
22220
|
-
|
|
22351
|
+
if (jsonMode) {
|
|
22352
|
+
console.log(JSON.stringify({ success: false, error: error instanceof Error ? error.message : String(error) }));
|
|
22353
|
+
} else {
|
|
22354
|
+
output.fail("Sync failed");
|
|
22355
|
+
output.error(error instanceof Error ? error.message : String(error));
|
|
22356
|
+
}
|
|
22357
|
+
process.exit(1);
|
|
22221
22358
|
}
|
|
22222
|
-
process.exit(1);
|
|
22223
22359
|
}
|
|
22224
22360
|
});
|
|
22225
22361
|
|
|
@@ -22661,7 +22797,7 @@ var deployCommand = new Command("deploy").description("Deploy all resources to p
|
|
|
22661
22797
|
}
|
|
22662
22798
|
console.log();
|
|
22663
22799
|
console.log(source_default.gray("Test your agents:"));
|
|
22664
|
-
console.log(source_default.gray(" $"), source_default.cyan(`curl -X POST
|
|
22800
|
+
console.log(source_default.gray(" $"), source_default.cyan(`curl -X POST ${getSiteUrl()}/v1/agents/<agent-slug>/chat -H "Authorization: Bearer YOUR_API_KEY" -d '{"message": "Hello"}'`));
|
|
22665
22801
|
console.log();
|
|
22666
22802
|
}
|
|
22667
22803
|
} catch (error) {
|
|
@@ -23718,6 +23854,14 @@ async function queryEntities(slug, env2, opts) {
|
|
|
23718
23854
|
...opts?.limit && { limit: opts.limit }
|
|
23719
23855
|
});
|
|
23720
23856
|
}
|
|
23857
|
+
async function resolveEntityId(partialId, env2) {
|
|
23858
|
+
const result = await convexQuery("entities:resolvePartialId", { partialId, environment: env2 });
|
|
23859
|
+
if (result.error)
|
|
23860
|
+
return { error: result.error };
|
|
23861
|
+
if (!result.data)
|
|
23862
|
+
return { error: `No entity found matching ID "${partialId}"` };
|
|
23863
|
+
return { data: result.data };
|
|
23864
|
+
}
|
|
23721
23865
|
async function queryEntity(id, env2) {
|
|
23722
23866
|
return convexQuery("entities:getWithType", { id, environment: env2 });
|
|
23723
23867
|
}
|
|
@@ -23915,11 +24059,19 @@ entitiesCommand.command("list <type>").description("List entities of a type").op
|
|
|
23915
24059
|
renderTable(columns, entities.map(flattenEntityForTable));
|
|
23916
24060
|
console.log();
|
|
23917
24061
|
});
|
|
23918
|
-
entitiesCommand.command("get <id>").description("Get entity details").option("--env <environment>", "Environment (development|production)", "development").option("--json", "Output raw JSON").action(async (
|
|
24062
|
+
entitiesCommand.command("get <id>").description("Get entity details").option("--env <environment>", "Environment (development|production)", "development").option("--json", "Output raw JSON").action(async (rawId, opts) => {
|
|
23919
24063
|
await ensureAuth();
|
|
23920
24064
|
const spinner = ora();
|
|
23921
24065
|
const env2 = opts.env;
|
|
23922
|
-
spinner.start("
|
|
24066
|
+
spinner.start("Resolving entity ID");
|
|
24067
|
+
const resolved = await resolveEntityId(rawId, env2);
|
|
24068
|
+
if (resolved.error || !resolved.data) {
|
|
24069
|
+
spinner.fail("Entity not found");
|
|
24070
|
+
console.log(source_default.red("Error:"), resolved.error || `No entity matched "${rawId}"`);
|
|
24071
|
+
process.exit(1);
|
|
24072
|
+
}
|
|
24073
|
+
const id = resolved.data;
|
|
24074
|
+
spinner.text = "Fetching entity";
|
|
23923
24075
|
const { data, error } = await queryEntity(id, env2);
|
|
23924
24076
|
if (error || !data) {
|
|
23925
24077
|
spinner.fail("Failed to fetch entity");
|
|
@@ -24027,7 +24179,7 @@ entitiesCommand.command("create <type>").description("Create a new entity").opti
|
|
|
24027
24179
|
console.log();
|
|
24028
24180
|
}
|
|
24029
24181
|
});
|
|
24030
|
-
entitiesCommand.command("update <id>").description("Update an entity").option("--env <environment>", "Environment (development|production)", "development").option("--data <json>", "Update data as JSON").option("--status <status>", "New status").option("--json", "Output raw JSON").action(async (
|
|
24182
|
+
entitiesCommand.command("update <id>").description("Update an entity").option("--env <environment>", "Environment (development|production)", "development").option("--data <json>", "Update data as JSON").option("--status <status>", "New status").option("--json", "Output raw JSON").action(async (rawId, opts) => {
|
|
24031
24183
|
await ensureAuth();
|
|
24032
24184
|
const spinner = ora();
|
|
24033
24185
|
const env2 = opts.env;
|
|
@@ -24044,7 +24196,15 @@ entitiesCommand.command("update <id>").description("Update an entity").option("-
|
|
|
24044
24196
|
process.exit(1);
|
|
24045
24197
|
}
|
|
24046
24198
|
}
|
|
24047
|
-
spinner.start("
|
|
24199
|
+
spinner.start("Resolving entity ID");
|
|
24200
|
+
const resolved = await resolveEntityId(rawId, env2);
|
|
24201
|
+
if (resolved.error || !resolved.data) {
|
|
24202
|
+
spinner.fail("Entity not found");
|
|
24203
|
+
console.log(source_default.red("Error:"), resolved.error || `No entity matched "${rawId}"`);
|
|
24204
|
+
process.exit(1);
|
|
24205
|
+
}
|
|
24206
|
+
const id = resolved.data;
|
|
24207
|
+
spinner.text = "Updating entity";
|
|
24048
24208
|
const { data: result, error } = await updateEntity(id, data, env2, opts.status);
|
|
24049
24209
|
if (error) {
|
|
24050
24210
|
spinner.fail("Failed to update entity");
|
|
@@ -24060,13 +24220,26 @@ entitiesCommand.command("update <id>").description("Update an entity").option("-
|
|
|
24060
24220
|
console.log();
|
|
24061
24221
|
}
|
|
24062
24222
|
});
|
|
24063
|
-
entitiesCommand.command("delete <id>").description("Delete an entity").option("--env <environment>", "Environment (development|production)", "development").option("--yes", "Skip confirmation").option("--json", "Output raw JSON").action(async (
|
|
24223
|
+
entitiesCommand.command("delete <id>").description("Delete an entity").option("--env <environment>", "Environment (development|production)", "development").option("--yes", "Skip confirmation").option("--json", "Output raw JSON").action(async (rawId, opts) => {
|
|
24064
24224
|
await ensureAuth();
|
|
24065
24225
|
const spinner = ora();
|
|
24066
24226
|
const env2 = opts.env;
|
|
24067
24227
|
const jsonMode = !!opts.json;
|
|
24068
24228
|
if (!jsonMode)
|
|
24069
|
-
spinner.start("
|
|
24229
|
+
spinner.start("Resolving entity ID");
|
|
24230
|
+
const resolved = await resolveEntityId(rawId, env2);
|
|
24231
|
+
if (resolved.error || !resolved.data) {
|
|
24232
|
+
if (jsonMode) {
|
|
24233
|
+
console.log(JSON.stringify({ success: false, error: resolved.error || `No entity matched "${rawId}"` }));
|
|
24234
|
+
} else {
|
|
24235
|
+
spinner.fail("Entity not found");
|
|
24236
|
+
console.log(source_default.red("Error:"), resolved.error || `No entity matched "${rawId}"`);
|
|
24237
|
+
}
|
|
24238
|
+
process.exit(1);
|
|
24239
|
+
}
|
|
24240
|
+
const id = resolved.data;
|
|
24241
|
+
if (!jsonMode)
|
|
24242
|
+
spinner.text = "Fetching entity";
|
|
24070
24243
|
const { data, error: fetchError } = await queryEntity(id, env2);
|
|
24071
24244
|
if (fetchError || !data) {
|
|
24072
24245
|
if (jsonMode) {
|
|
@@ -25010,10 +25183,382 @@ templatesCommand.command("status <name>").description("Check template approval s
|
|
|
25010
25183
|
console.log();
|
|
25011
25184
|
}
|
|
25012
25185
|
});
|
|
25186
|
+
|
|
25187
|
+
// src/cli/utils/integrations.ts
|
|
25188
|
+
var CONVEX_URL5 = process.env.STRUERE_CONVEX_URL || "https://rapid-wildebeest-172.convex.cloud";
|
|
25189
|
+
function getToken4() {
|
|
25190
|
+
const credentials = loadCredentials();
|
|
25191
|
+
const apiKey = getApiKey();
|
|
25192
|
+
return apiKey || credentials?.token || null;
|
|
25193
|
+
}
|
|
25194
|
+
async function convexQuery4(path, args) {
|
|
25195
|
+
const token = getToken4();
|
|
25196
|
+
if (!token)
|
|
25197
|
+
return { error: "Not authenticated" };
|
|
25198
|
+
const response = await fetch(`${CONVEX_URL5}/api/query`, {
|
|
25199
|
+
method: "POST",
|
|
25200
|
+
headers: {
|
|
25201
|
+
"Content-Type": "application/json",
|
|
25202
|
+
Authorization: `Bearer ${token}`
|
|
25203
|
+
},
|
|
25204
|
+
body: JSON.stringify({ path, args })
|
|
25205
|
+
});
|
|
25206
|
+
const text = await response.text();
|
|
25207
|
+
let json;
|
|
25208
|
+
try {
|
|
25209
|
+
json = JSON.parse(text);
|
|
25210
|
+
} catch {
|
|
25211
|
+
return { error: text || `HTTP ${response.status}` };
|
|
25212
|
+
}
|
|
25213
|
+
if (!response.ok) {
|
|
25214
|
+
const msg = json.errorData?.message || json.message || json.errorMessage || text;
|
|
25215
|
+
return { error: String(msg) };
|
|
25216
|
+
}
|
|
25217
|
+
if (json.status === "success")
|
|
25218
|
+
return { data: json.value };
|
|
25219
|
+
if (json.status === "error")
|
|
25220
|
+
return { error: String(json.errorMessage || "Unknown error") };
|
|
25221
|
+
return { error: `Unexpected response: ${text}` };
|
|
25222
|
+
}
|
|
25223
|
+
async function convexMutation3(path, args) {
|
|
25224
|
+
const token = getToken4();
|
|
25225
|
+
if (!token)
|
|
25226
|
+
return { error: "Not authenticated" };
|
|
25227
|
+
const response = await fetch(`${CONVEX_URL5}/api/mutation`, {
|
|
25228
|
+
method: "POST",
|
|
25229
|
+
headers: {
|
|
25230
|
+
"Content-Type": "application/json",
|
|
25231
|
+
Authorization: `Bearer ${token}`
|
|
25232
|
+
},
|
|
25233
|
+
body: JSON.stringify({ path, args })
|
|
25234
|
+
});
|
|
25235
|
+
const text = await response.text();
|
|
25236
|
+
let json;
|
|
25237
|
+
try {
|
|
25238
|
+
json = JSON.parse(text);
|
|
25239
|
+
} catch {
|
|
25240
|
+
return { error: text || `HTTP ${response.status}` };
|
|
25241
|
+
}
|
|
25242
|
+
if (!response.ok) {
|
|
25243
|
+
const msg = json.errorData?.message || json.message || json.errorMessage || text;
|
|
25244
|
+
return { error: String(msg) };
|
|
25245
|
+
}
|
|
25246
|
+
if (json.status === "success")
|
|
25247
|
+
return { data: json.value };
|
|
25248
|
+
if (json.status === "error")
|
|
25249
|
+
return { error: String(json.errorMessage || "Unknown error") };
|
|
25250
|
+
return { error: `Unexpected response: ${text}` };
|
|
25251
|
+
}
|
|
25252
|
+
async function convexAction2(path, args) {
|
|
25253
|
+
const token = getToken4();
|
|
25254
|
+
if (!token)
|
|
25255
|
+
return { error: "Not authenticated" };
|
|
25256
|
+
const response = await fetch(`${CONVEX_URL5}/api/action`, {
|
|
25257
|
+
method: "POST",
|
|
25258
|
+
headers: {
|
|
25259
|
+
"Content-Type": "application/json",
|
|
25260
|
+
Authorization: `Bearer ${token}`
|
|
25261
|
+
},
|
|
25262
|
+
body: JSON.stringify({ path, args })
|
|
25263
|
+
});
|
|
25264
|
+
const text = await response.text();
|
|
25265
|
+
let json;
|
|
25266
|
+
try {
|
|
25267
|
+
json = JSON.parse(text);
|
|
25268
|
+
} catch {
|
|
25269
|
+
return { error: text || `HTTP ${response.status}` };
|
|
25270
|
+
}
|
|
25271
|
+
if (!response.ok) {
|
|
25272
|
+
const msg = json.errorData?.message || json.message || json.errorMessage || text;
|
|
25273
|
+
return { error: String(msg) };
|
|
25274
|
+
}
|
|
25275
|
+
if (json.status === "success")
|
|
25276
|
+
return { data: json.value };
|
|
25277
|
+
if (json.status === "error")
|
|
25278
|
+
return { error: String(json.errorMessage || "Unknown error") };
|
|
25279
|
+
return { error: `Unexpected response: ${text}` };
|
|
25280
|
+
}
|
|
25281
|
+
async function getIntegrationConfig(provider, env2) {
|
|
25282
|
+
return convexQuery4("integrations:getConfig", { provider, environment: env2 });
|
|
25283
|
+
}
|
|
25284
|
+
async function updateIntegrationConfig(provider, env2, config) {
|
|
25285
|
+
return convexMutation3("integrations:updateConfig", { provider, environment: env2, config });
|
|
25286
|
+
}
|
|
25287
|
+
async function testIntegrationConnection(provider, env2) {
|
|
25288
|
+
return convexAction2("integrations:testConnection", { provider, environment: env2 });
|
|
25289
|
+
}
|
|
25290
|
+
async function deleteIntegrationConfig(provider, env2) {
|
|
25291
|
+
return convexMutation3("integrations:deleteConfig", { provider, environment: env2 });
|
|
25292
|
+
}
|
|
25293
|
+
async function listIntegrationConfigs(env2) {
|
|
25294
|
+
return convexQuery4("integrations:listConfigs", { environment: env2 });
|
|
25295
|
+
}
|
|
25296
|
+
async function setIntegrationStatus(provider, env2, status) {
|
|
25297
|
+
return convexMutation3("integrations:setConfigStatus", { provider, environment: env2, status });
|
|
25298
|
+
}
|
|
25299
|
+
|
|
25300
|
+
// src/cli/commands/integration.ts
|
|
25301
|
+
var VALID_PROVIDERS = ["airtable", "resend"];
|
|
25302
|
+
async function ensureAuth3() {
|
|
25303
|
+
const cwd = process.cwd();
|
|
25304
|
+
const nonInteractive = !isInteractive2();
|
|
25305
|
+
if (!hasProject(cwd)) {
|
|
25306
|
+
if (nonInteractive) {
|
|
25307
|
+
console.error(source_default.red("No struere.json found. Run struere init first."));
|
|
25308
|
+
process.exit(1);
|
|
25309
|
+
}
|
|
25310
|
+
console.log(source_default.yellow("No struere.json found - initializing project..."));
|
|
25311
|
+
console.log();
|
|
25312
|
+
const success = await runInit(cwd);
|
|
25313
|
+
if (!success) {
|
|
25314
|
+
process.exit(1);
|
|
25315
|
+
}
|
|
25316
|
+
console.log();
|
|
25317
|
+
}
|
|
25318
|
+
let credentials = loadCredentials();
|
|
25319
|
+
const apiKey = getApiKey();
|
|
25320
|
+
if (!credentials && !apiKey) {
|
|
25321
|
+
if (nonInteractive) {
|
|
25322
|
+
console.error(source_default.red("Not authenticated. Set STRUERE_API_KEY or run struere login."));
|
|
25323
|
+
process.exit(1);
|
|
25324
|
+
}
|
|
25325
|
+
console.log(source_default.yellow("Not logged in - authenticating..."));
|
|
25326
|
+
console.log();
|
|
25327
|
+
credentials = await performLogin();
|
|
25328
|
+
if (!credentials) {
|
|
25329
|
+
console.log(source_default.red("Authentication failed"));
|
|
25330
|
+
process.exit(1);
|
|
25331
|
+
}
|
|
25332
|
+
console.log();
|
|
25333
|
+
}
|
|
25334
|
+
return true;
|
|
25335
|
+
}
|
|
25336
|
+
function statusColor3(status) {
|
|
25337
|
+
switch (status) {
|
|
25338
|
+
case "active":
|
|
25339
|
+
return source_default.green(status);
|
|
25340
|
+
case "inactive":
|
|
25341
|
+
return source_default.yellow(status);
|
|
25342
|
+
case "error":
|
|
25343
|
+
return source_default.red(status);
|
|
25344
|
+
default:
|
|
25345
|
+
return source_default.gray(status);
|
|
25346
|
+
}
|
|
25347
|
+
}
|
|
25348
|
+
function getProviderHelp(provider) {
|
|
25349
|
+
switch (provider) {
|
|
25350
|
+
case "airtable":
|
|
25351
|
+
return `Usage: struere integration airtable --token <pat> [--base-id <id>] [--test]`;
|
|
25352
|
+
case "resend":
|
|
25353
|
+
return `Usage: struere integration resend --from-email <email> [--from-name <name>] [--reply-to <email>]`;
|
|
25354
|
+
default:
|
|
25355
|
+
return "";
|
|
25356
|
+
}
|
|
25357
|
+
}
|
|
25358
|
+
function buildConfigFromOpts(provider, opts) {
|
|
25359
|
+
if (provider === "airtable") {
|
|
25360
|
+
const config = {};
|
|
25361
|
+
if (opts.token)
|
|
25362
|
+
config.personalAccessToken = opts.token;
|
|
25363
|
+
if (opts.baseId)
|
|
25364
|
+
config.defaultBaseId = opts.baseId;
|
|
25365
|
+
if (Object.keys(config).length === 0)
|
|
25366
|
+
return null;
|
|
25367
|
+
return config;
|
|
25368
|
+
}
|
|
25369
|
+
if (provider === "resend") {
|
|
25370
|
+
const config = {};
|
|
25371
|
+
if (opts.fromEmail)
|
|
25372
|
+
config.fromEmail = opts.fromEmail;
|
|
25373
|
+
if (opts.fromName)
|
|
25374
|
+
config.fromName = opts.fromName;
|
|
25375
|
+
if (opts.replyTo)
|
|
25376
|
+
config.replyTo = opts.replyTo;
|
|
25377
|
+
if (Object.keys(config).length === 0)
|
|
25378
|
+
return null;
|
|
25379
|
+
return config;
|
|
25380
|
+
}
|
|
25381
|
+
return null;
|
|
25382
|
+
}
|
|
25383
|
+
var integrationCommand = new Command("integration").description("Manage integrations").argument("[provider]", "Integration provider (airtable, resend)").option("--env <environment>", "Environment (development|production)", "development").option("--token <pat>", "Personal access token (airtable)").option("--base-id <id>", "Default base ID (airtable)").option("--from-email <email>", "From email address (resend)").option("--from-name <name>", "From display name (resend)").option("--reply-to <email>", "Reply-to address (resend)").option("--test", "Test the connection after saving").option("--remove", "Remove integration config").option("--enable", "Enable integration").option("--disable", "Disable integration").option("--status", "Show current config status").option("--yes", "Skip confirmation prompts").option("--json", "Output raw JSON").action(async (provider, opts) => {
|
|
25384
|
+
await ensureAuth3();
|
|
25385
|
+
const env2 = opts.env;
|
|
25386
|
+
const out = createOutput();
|
|
25387
|
+
if (!provider || provider === "list") {
|
|
25388
|
+
out.start("Fetching integrations");
|
|
25389
|
+
const { data, error } = await listIntegrationConfigs(env2);
|
|
25390
|
+
if (error) {
|
|
25391
|
+
out.fail("Failed to fetch integrations");
|
|
25392
|
+
out.error(error);
|
|
25393
|
+
process.exit(1);
|
|
25394
|
+
}
|
|
25395
|
+
const configs = data ?? [];
|
|
25396
|
+
out.succeed(`Found ${configs.length} integration${configs.length !== 1 ? "s" : ""}`);
|
|
25397
|
+
if (opts.json) {
|
|
25398
|
+
console.log(JSON.stringify(configs, null, 2));
|
|
25399
|
+
return;
|
|
25400
|
+
}
|
|
25401
|
+
console.log();
|
|
25402
|
+
if (configs.length === 0) {
|
|
25403
|
+
console.log(source_default.gray(" No integrations configured"));
|
|
25404
|
+
console.log();
|
|
25405
|
+
console.log(` ${source_default.gray("Available:")} ${VALID_PROVIDERS.join(", ")}`);
|
|
25406
|
+
console.log(` ${source_default.gray("Example:")} struere integration airtable --token <pat>`);
|
|
25407
|
+
console.log();
|
|
25408
|
+
return;
|
|
25409
|
+
}
|
|
25410
|
+
renderTable([
|
|
25411
|
+
{ key: "provider", label: "Provider", width: 16 },
|
|
25412
|
+
{ key: "status", label: "Status", width: 12 },
|
|
25413
|
+
{ key: "lastVerified", label: "Last Verified", width: 22 }
|
|
25414
|
+
], configs.map((c) => ({
|
|
25415
|
+
provider: c.provider,
|
|
25416
|
+
status: statusColor3(String(c.status ?? "")),
|
|
25417
|
+
lastVerified: c.lastVerifiedAt ? new Date(c.lastVerifiedAt).toLocaleString() : source_default.gray("never")
|
|
25418
|
+
})));
|
|
25419
|
+
console.log();
|
|
25420
|
+
return;
|
|
25421
|
+
}
|
|
25422
|
+
if (!VALID_PROVIDERS.includes(provider)) {
|
|
25423
|
+
out.fail(`Unknown provider: ${provider}`);
|
|
25424
|
+
console.log(` ${source_default.gray("Available:")} ${VALID_PROVIDERS.join(", ")}`);
|
|
25425
|
+
process.exit(1);
|
|
25426
|
+
}
|
|
25427
|
+
if (opts.remove) {
|
|
25428
|
+
if (!opts.yes && isInteractive2()) {
|
|
25429
|
+
const confirmed = await esm_default2({
|
|
25430
|
+
message: `Remove ${provider} integration config? This cannot be undone.`,
|
|
25431
|
+
default: false
|
|
25432
|
+
});
|
|
25433
|
+
if (!confirmed) {
|
|
25434
|
+
console.log(source_default.gray("Cancelled"));
|
|
25435
|
+
return;
|
|
25436
|
+
}
|
|
25437
|
+
}
|
|
25438
|
+
out.start(`Removing ${provider} config`);
|
|
25439
|
+
const { data, error } = await deleteIntegrationConfig(provider, env2);
|
|
25440
|
+
if (error) {
|
|
25441
|
+
out.fail(`Failed to remove ${provider} config`);
|
|
25442
|
+
out.error(error);
|
|
25443
|
+
process.exit(1);
|
|
25444
|
+
}
|
|
25445
|
+
const result = data;
|
|
25446
|
+
if (result?.success) {
|
|
25447
|
+
out.succeed(`${provider} config removed`);
|
|
25448
|
+
} else {
|
|
25449
|
+
out.fail(`No ${provider} config found`);
|
|
25450
|
+
}
|
|
25451
|
+
console.log();
|
|
25452
|
+
return;
|
|
25453
|
+
}
|
|
25454
|
+
if (opts.enable || opts.disable) {
|
|
25455
|
+
const newStatus = opts.enable ? "active" : "inactive";
|
|
25456
|
+
out.start(`Setting ${provider} to ${newStatus}`);
|
|
25457
|
+
const { data, error } = await setIntegrationStatus(provider, env2, newStatus);
|
|
25458
|
+
if (error) {
|
|
25459
|
+
out.fail(`Failed to update ${provider} status`);
|
|
25460
|
+
out.error(error);
|
|
25461
|
+
process.exit(1);
|
|
25462
|
+
}
|
|
25463
|
+
const result = data;
|
|
25464
|
+
if (result?.success) {
|
|
25465
|
+
out.succeed(`${provider} set to ${statusColor3(newStatus)}`);
|
|
25466
|
+
} else {
|
|
25467
|
+
out.fail(`No ${provider} config found`);
|
|
25468
|
+
}
|
|
25469
|
+
console.log();
|
|
25470
|
+
return;
|
|
25471
|
+
}
|
|
25472
|
+
const config = buildConfigFromOpts(provider, opts);
|
|
25473
|
+
if (config) {
|
|
25474
|
+
out.start(`Saving ${provider} config`);
|
|
25475
|
+
const { error } = await updateIntegrationConfig(provider, env2, config);
|
|
25476
|
+
if (error) {
|
|
25477
|
+
out.fail(`Failed to save ${provider} config`);
|
|
25478
|
+
out.error(error);
|
|
25479
|
+
process.exit(1);
|
|
25480
|
+
}
|
|
25481
|
+
out.succeed(`${provider} config saved`);
|
|
25482
|
+
if (opts.test) {
|
|
25483
|
+
out.start(`Testing ${provider} connection`);
|
|
25484
|
+
const { data: testData, error: testError } = await testIntegrationConnection(provider, env2);
|
|
25485
|
+
if (testError) {
|
|
25486
|
+
out.fail(`Connection test failed`);
|
|
25487
|
+
out.error(testError);
|
|
25488
|
+
process.exit(1);
|
|
25489
|
+
}
|
|
25490
|
+
const testResult = testData;
|
|
25491
|
+
if (testResult.success) {
|
|
25492
|
+
out.succeed(testResult.message);
|
|
25493
|
+
} else {
|
|
25494
|
+
out.fail(testResult.message);
|
|
25495
|
+
process.exit(1);
|
|
25496
|
+
}
|
|
25497
|
+
}
|
|
25498
|
+
console.log();
|
|
25499
|
+
return;
|
|
25500
|
+
}
|
|
25501
|
+
if (opts.test) {
|
|
25502
|
+
out.start(`Testing ${provider} connection`);
|
|
25503
|
+
const { data: testData, error: testError } = await testIntegrationConnection(provider, env2);
|
|
25504
|
+
if (testError) {
|
|
25505
|
+
out.fail(`Connection test failed`);
|
|
25506
|
+
out.error(testError);
|
|
25507
|
+
process.exit(1);
|
|
25508
|
+
}
|
|
25509
|
+
const testResult = testData;
|
|
25510
|
+
if (testResult.success) {
|
|
25511
|
+
out.succeed(testResult.message);
|
|
25512
|
+
} else {
|
|
25513
|
+
out.fail(testResult.message);
|
|
25514
|
+
process.exit(1);
|
|
25515
|
+
}
|
|
25516
|
+
console.log();
|
|
25517
|
+
return;
|
|
25518
|
+
}
|
|
25519
|
+
out.start(`Fetching ${provider} config`);
|
|
25520
|
+
const { data: configData, error: configError } = await getIntegrationConfig(provider, env2);
|
|
25521
|
+
if (configError) {
|
|
25522
|
+
out.fail(`Failed to fetch ${provider} config`);
|
|
25523
|
+
out.error(configError);
|
|
25524
|
+
process.exit(1);
|
|
25525
|
+
}
|
|
25526
|
+
if (!configData) {
|
|
25527
|
+
out.fail(`No ${provider} config found`);
|
|
25528
|
+
console.log();
|
|
25529
|
+
console.log(` ${source_default.gray(getProviderHelp(provider))}`);
|
|
25530
|
+
console.log();
|
|
25531
|
+
return;
|
|
25532
|
+
}
|
|
25533
|
+
out.succeed(`${provider} config loaded`);
|
|
25534
|
+
if (opts.json) {
|
|
25535
|
+
console.log(JSON.stringify(configData, null, 2));
|
|
25536
|
+
return;
|
|
25537
|
+
}
|
|
25538
|
+
const cfg = configData;
|
|
25539
|
+
const cfgData = cfg.config;
|
|
25540
|
+
console.log();
|
|
25541
|
+
console.log(source_default.bold(` ${provider}`));
|
|
25542
|
+
console.log(source_default.gray(" " + "\u2500".repeat(48)));
|
|
25543
|
+
console.log(` ${source_default.gray("Status:")} ${statusColor3(String(cfg.status ?? ""))}`);
|
|
25544
|
+
console.log(` ${source_default.gray("Environment:")} ${cfg.environment}`);
|
|
25545
|
+
console.log(` ${source_default.gray("Last Verified:")} ${cfg.lastVerifiedAt ? new Date(cfg.lastVerifiedAt).toLocaleString() : source_default.gray("never")}`);
|
|
25546
|
+
console.log(` ${source_default.gray("Updated:")} ${new Date(cfg.updatedAt).toLocaleString()}`);
|
|
25547
|
+
if (cfgData && Object.keys(cfgData).length > 0) {
|
|
25548
|
+
console.log();
|
|
25549
|
+
console.log(source_default.bold(" Config"));
|
|
25550
|
+
console.log(source_default.gray(" " + "\u2500".repeat(48)));
|
|
25551
|
+
const maxKeyLen = Math.max(...Object.keys(cfgData).map((k) => k.length));
|
|
25552
|
+
for (const [key, value] of Object.entries(cfgData)) {
|
|
25553
|
+
console.log(` ${source_default.gray(key.padEnd(maxKeyLen))} ${String(value ?? "")}`);
|
|
25554
|
+
}
|
|
25555
|
+
}
|
|
25556
|
+
console.log();
|
|
25557
|
+
});
|
|
25013
25558
|
// package.json
|
|
25014
25559
|
var package_default = {
|
|
25015
25560
|
name: "struere",
|
|
25016
|
-
version: "0.9.
|
|
25561
|
+
version: "0.9.5",
|
|
25017
25562
|
description: "Build, test, and deploy AI agents",
|
|
25018
25563
|
keywords: [
|
|
25019
25564
|
"ai",
|
|
@@ -25127,4 +25672,5 @@ program.addCommand(entitiesCommand);
|
|
|
25127
25672
|
program.addCommand(docsCommand);
|
|
25128
25673
|
program.addCommand(evalCommand);
|
|
25129
25674
|
program.addCommand(templatesCommand);
|
|
25675
|
+
program.addCommand(integrationCommand);
|
|
25130
25676
|
program.parse();
|