@base44-preview/cli 0.1.32-pr.665.1a74073 → 0.1.32-pr.666.eab827b
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 +4 -0
- package/dist/cli/index.js +2521 -650
- package/dist/cli/index.js.map +36 -17
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -31177,7 +31177,7 @@ function cleanDoc(doc) {
|
|
|
31177
31177
|
return mapDoc(doc, (currentDoc) => cleanDocFn(currentDoc));
|
|
31178
31178
|
}
|
|
31179
31179
|
function replaceEndOfLine(doc, replacement = literalline) {
|
|
31180
|
-
return mapDoc(doc, (currentDoc) => typeof currentDoc === "string" ?
|
|
31180
|
+
return mapDoc(doc, (currentDoc) => typeof currentDoc === "string" ? join33(replacement, currentDoc.split(`
|
|
31181
31181
|
`)) : currentDoc);
|
|
31182
31182
|
}
|
|
31183
31183
|
function canBreakFn(doc) {
|
|
@@ -31257,7 +31257,7 @@ function indentIfBreak(contents, options) {
|
|
|
31257
31257
|
negate: options.negate
|
|
31258
31258
|
};
|
|
31259
31259
|
}
|
|
31260
|
-
function
|
|
31260
|
+
function join33(separator, docs) {
|
|
31261
31261
|
assertDoc(separator);
|
|
31262
31262
|
assertDocArray(docs);
|
|
31263
31263
|
const parts = [];
|
|
@@ -31968,7 +31968,7 @@ var init_doc = __esm(() => {
|
|
|
31968
31968
|
MODE_FLAT = Symbol("MODE_FLAT");
|
|
31969
31969
|
DOC_FILL_PRINTED_LENGTH = Symbol("DOC_FILL_PRINTED_LENGTH");
|
|
31970
31970
|
builders = {
|
|
31971
|
-
join:
|
|
31971
|
+
join: join33,
|
|
31972
31972
|
line,
|
|
31973
31973
|
softline,
|
|
31974
31974
|
hardline,
|
|
@@ -37919,9 +37919,9 @@ function zt3(e, t) {
|
|
|
37919
37919
|
return e.map(() => Pc(e, t), "expressions");
|
|
37920
37920
|
}
|
|
37921
37921
|
function tn2(e, t) {
|
|
37922
|
-
return ft3(e, (r) => typeof r == "string" ? t ? W4(0, r, /(\\*)`/gu, "$1$1\\`") :
|
|
37922
|
+
return ft3(e, (r) => typeof r == "string" ? t ? W4(0, r, /(\\*)`/gu, "$1$1\\`") : ms3(r) : r);
|
|
37923
37923
|
}
|
|
37924
|
-
function
|
|
37924
|
+
function ms3(e) {
|
|
37925
37925
|
return W4(0, e, /([\\`]|\$\{)/gu, "\\$1");
|
|
37926
37926
|
}
|
|
37927
37927
|
function kc({ node: e, parent: t }) {
|
|
@@ -38021,7 +38021,7 @@ async function mo(e, t, r, n, s) {
|
|
|
38021
38021
|
for (let S = 0;S < g.length; S++) {
|
|
38022
38022
|
let j = g[S];
|
|
38023
38023
|
if (S % 2 === 0) {
|
|
38024
|
-
j && (j =
|
|
38024
|
+
j && (j = ms3(j), s.__embeddedInHtml && (j = W4(0, j, /<\/(?=script\b)/giu, "<\\/")), h.push(j));
|
|
38025
38025
|
continue;
|
|
38026
38026
|
}
|
|
38027
38027
|
let U = Number(j);
|
|
@@ -39570,9 +39570,9 @@ function tm(e, t, r) {
|
|
|
39570
39570
|
return l(["<", r("name"), r("typeArguments"), " ", ...e.map(r, "attributes"), n.selfClosing ? " />" : ">"]);
|
|
39571
39571
|
let i = n.attributes?.some((u) => V3(u.value) && u.value.value.includes(`
|
|
39572
39572
|
`)), o = t.singleAttributePerLine && n.attributes.length > 1 ? E : A;
|
|
39573
|
-
return l(["<", r("name"), r("typeArguments"), m(e.map(() => [o, r()], "attributes")), ...
|
|
39573
|
+
return l(["<", r("name"), r("typeArguments"), m(e.map(() => [o, r()], "attributes")), ...rm3(n, t, s)], { shouldBreak: i });
|
|
39574
39574
|
}
|
|
39575
|
-
function
|
|
39575
|
+
function rm3(e, t, r) {
|
|
39576
39576
|
return e.selfClosing ? [A, "/>"] : nm(e, t, r) ? [">"] : [f, ">"];
|
|
39577
39577
|
}
|
|
39578
39578
|
function nm(e, t, r) {
|
|
@@ -41615,7 +41615,7 @@ function ds2(e) {
|
|
|
41615
41615
|
function qt2(e) {
|
|
41616
41616
|
return Ut3(e) || e === 95;
|
|
41617
41617
|
}
|
|
41618
|
-
function
|
|
41618
|
+
function ms4(e) {
|
|
41619
41619
|
return qt2(e) || Ee3(e);
|
|
41620
41620
|
}
|
|
41621
41621
|
function xs3(e) {
|
|
@@ -44055,7 +44055,7 @@ var init_acorn = __esm(() => {
|
|
|
44055
44055
|
};
|
|
44056
44056
|
f2.regexp_eatUnicodePropertyValue = function(e) {
|
|
44057
44057
|
var t = 0;
|
|
44058
|
-
for (e.lastStringValue = "";
|
|
44058
|
+
for (e.lastStringValue = "";ms4(t = e.current()); )
|
|
44059
44059
|
e.lastStringValue += q5(t), e.advance();
|
|
44060
44060
|
return e.lastStringValue !== "";
|
|
44061
44061
|
};
|
|
@@ -45348,7 +45348,7 @@ var Ci4, _i4, Ti4, an3 = (t) => {
|
|
|
45348
45348
|
toString() {
|
|
45349
45349
|
return this.start.file.content.substring(this.start.offset, this.end.offset);
|
|
45350
45350
|
}
|
|
45351
|
-
}, qe3, Ce5, Rn2, $n2, Dn2, Yi4 = "(:(where|is)\\()?",
|
|
45351
|
+
}, qe3, Ce5, Rn2, $n2, Dn2, Yi4 = "(:(where|is)\\()?", ms5 = "-shadowcsshost", Qi4 = "-shadowcsscontext", Bt3 = "[^)(]*", Ki4, Zi4, zt4, Yr3, Qr3, er4, Kr2, tr4, Zr2, gs3 = "%COMMENT%", eo3, to3, nr4 = "%COMMA_IN_PLACEHOLDER%", sr4 = "%SEMI_IN_PLACEHOLDER%", ir4 = "%COLON_IN_PLACEHOLDER%", no3, so3, io3, f3, ie3, Bn2, On2, Fn2, M5, Vn2, Un2, Hn3, Wn2, R5, qn3, jn2, rr4, vs4, Te4, Gt4, ro3, oo3, ao3, je4 = class {
|
|
45352
45352
|
strings;
|
|
45353
45353
|
expressions;
|
|
45354
45354
|
i18nPlaceholders;
|
|
@@ -47437,10 +47437,10 @@ var init_angular = __esm(() => {
|
|
|
47437
47437
|
Zi4 = `(?:\\(${Ki4}\\)|${Bt3})+?`;
|
|
47438
47438
|
zt4 = `(?:\\((${Zi4})\\))`;
|
|
47439
47439
|
Yr3 = new RegExp("(:nth-[-\\w]+)" + zt4, "g");
|
|
47440
|
-
Qr3 = new RegExp(
|
|
47440
|
+
Qr3 = new RegExp(ms5 + zt4 + "?([^,{]*)", "gim");
|
|
47441
47441
|
er4 = Qi4 + zt4 + "?([^{]*)";
|
|
47442
47442
|
Kr2 = new RegExp(`${Yi4}(${er4})`, "gim");
|
|
47443
|
-
tr4 =
|
|
47443
|
+
tr4 = ms5 + "-no-combinator";
|
|
47444
47444
|
Zr2 = new RegExp(`${tr4}(?![^(]*\\))`, "g");
|
|
47445
47445
|
eo3 = new RegExp(gs3, "g");
|
|
47446
47446
|
to3 = new RegExp(`(\\s*(?:${gs3}\\s*)*)([^;\\{\\}]+?)(\\s*)((?:{%BLOCK%}?\\s*;?)|(?:\\s*;))`, "g");
|
|
@@ -48644,7 +48644,7 @@ function qr3(a, t) {
|
|
|
48644
48644
|
return true;
|
|
48645
48645
|
let e = ve6(a);
|
|
48646
48646
|
e && (a = a.slice(e.length));
|
|
48647
|
-
let s =
|
|
48647
|
+
let s = ms6(a, 0);
|
|
48648
48648
|
return s !== false && (a = a.slice(0, s)), zr3.test(a);
|
|
48649
48649
|
}
|
|
48650
48650
|
function $r4(a, t, e) {
|
|
@@ -52298,7 +52298,7 @@ var Hs5, Re5 = (a, t) => {
|
|
|
52298
52298
|
return this.parseV8Intrinsic() || super.parseExprAtom(e);
|
|
52299
52299
|
}
|
|
52300
52300
|
}, Kt5, Ht6, hs4, tr5, pt7, ze5, sr5, ir5, qe4, ut4, Ee5, ua2, Wt6, da2, cs4, ma2, ls4, ps4, us4 = (a) => a === `
|
|
52301
|
-
` || a === "\r" || a === "\u2028" || a === "\u2029", fs23, ds4,
|
|
52301
|
+
` || a === "\r" || a === "\u2028" || a === "\u2029", fs23, ds4, ms6, ve6, ee3 = (a, t) => (e, s, ...i) => e | 1 && s == null ? undefined : (t.call(s) ?? s[a]).apply(s, i), ur5, fr5, xs5, mr3, Ps5, te5, xr4, se5, Pr3, gs4, St6, Ts3, wt6, Ct7, bs4, As4, me6 = null, wr4 = 10, Ss3, c4, ws4, Er4, Cs3, Es3, fn4, Ns4, De5, ks4 = "Unexpected parseExpression() input: ", Me5, vr4, Lr4, xe4, Dr4, Mr4, Or4, Fr4, vs5, Br4, Ls5, Rr4, Ur4, Os4, Fs5, H6, Oe5 = "module", Nt6 = "commonjs", Fe5, ie4 = (a) => H6(Kr3(a)), Vr4, js5 = "v8intrinsic", Vs4, _4 = (a, t = Vr4) => ({ ...t, plugins: [...t.plugins, ...a] }), zr3, Hr3, zs5, Wr2, Jr2, Gr3, Xr2, qs5, Yr4, Lt7, vt7, $s4, ea2, ta2, sa2, ia2, ra2;
|
|
52302
52302
|
var init_babel = __esm(() => {
|
|
52303
52303
|
Hs5 = Object.defineProperty;
|
|
52304
52304
|
Ks4 = {};
|
|
@@ -55433,7 +55433,7 @@ var init_babel = __esm(() => {
|
|
|
55433
55433
|
ps4 = or5;
|
|
55434
55434
|
fs23 = hr5;
|
|
55435
55435
|
ds4 = cr4;
|
|
55436
|
-
|
|
55436
|
+
ms6 = lr4;
|
|
55437
55437
|
ve6 = pr5;
|
|
55438
55438
|
ur5 = Array.prototype.findLast ?? function(a) {
|
|
55439
55439
|
for (let t = this.length - 1;t >= 0; t--) {
|
|
@@ -85877,7 +85877,7 @@ function ps5(e) {
|
|
|
85877
85877
|
function fs24(e, t) {
|
|
85878
85878
|
return { open: e.charAt(2) === "~", close: t.charAt(t.length - 3) === "~" };
|
|
85879
85879
|
}
|
|
85880
|
-
function
|
|
85880
|
+
function ms7(e) {
|
|
85881
85881
|
return e.replace(/^\{\{~?!-?-?/, "").replace(/-?-?~?\}\}$/, "");
|
|
85882
85882
|
}
|
|
85883
85883
|
function ds5(e, t, r, s) {
|
|
@@ -87725,7 +87725,7 @@ Expecting ` + Qt.join(", ") + ", got '" + (this.terminals_[L] || L) + "'" : De =
|
|
|
87725
87725
|
};
|
|
87726
87726
|
jr3 = G6;
|
|
87727
87727
|
Ft7 = {};
|
|
87728
|
-
Oe6(Ft7, { SourceLocation: () => Qe6, id: () => ps5, prepareBlock: () => ys5, prepareMustache: () => gs5, preparePartialBlock: () => ks5, preparePath: () => ds5, prepareProgram: () => Ss4, prepareRawBlock: () => bs5, stripComment: () =>
|
|
87728
|
+
Oe6(Ft7, { SourceLocation: () => Qe6, id: () => ps5, prepareBlock: () => ys5, prepareMustache: () => gs5, preparePartialBlock: () => ks5, preparePath: () => ds5, prepareProgram: () => Ss4, prepareRawBlock: () => bs5, stripComment: () => ms7, stripFlags: () => fs24 });
|
|
87729
87729
|
Qr5 = {};
|
|
87730
87730
|
for (ue5 in Ft7)
|
|
87731
87731
|
Object.prototype.hasOwnProperty.call(Ft7, ue5) && (Qr5[ue5] = Ft7[ue5]);
|
|
@@ -89973,7 +89973,7 @@ spurious results.`);
|
|
|
89973
89973
|
var exports_html = {};
|
|
89974
89974
|
__export(exports_html, {
|
|
89975
89975
|
default: () => ws6,
|
|
89976
|
-
languages: () =>
|
|
89976
|
+
languages: () => ms8,
|
|
89977
89977
|
options: () => ds6,
|
|
89978
89978
|
parsers: () => Qr6,
|
|
89979
89979
|
printers: () => Ll2
|
|
@@ -92502,7 +92502,7 @@ ${e}`, wi7, Ja3 = (e) => e?.kind === "angularControlFlowBlock" && (e.name === "c
|
|
|
92502
92502
|
}
|
|
92503
92503
|
return i;
|
|
92504
92504
|
}
|
|
92505
|
-
}, us6, Ur6 = null, $o2 = () => (Ur6 || (Ur6 = new us6), Ur6), zo2, ps6, al2, hs6,
|
|
92505
|
+
}, us6, Ur6 = null, $o2 = () => (Ur6 || (Ur6 = new us6), Ur6), zo2, ps6, al2, hs6, ms8, Wr4, fs25 = "HTML", ol3, ds6, Qr6, gs6, cl2, Zt8, _s6, er7, Ss5, oe7, $r6, zr5, We9 = class We {
|
|
92506
92506
|
constructor(t = {}) {
|
|
92507
92507
|
tn6(this, oe7);
|
|
92508
92508
|
ir7(this, "kind");
|
|
@@ -92597,7 +92597,7 @@ ${e}`, wi7, Ja3 = (e) => e?.kind === "angularControlFlowBlock" && (e.name === "c
|
|
|
92597
92597
|
var init_html = __esm(() => {
|
|
92598
92598
|
Jr4 = Object.defineProperty;
|
|
92599
92599
|
ws6 = {};
|
|
92600
|
-
en6(ws6, { languages: () =>
|
|
92600
|
+
en6(ws6, { languages: () => ms8, options: () => ds6, parsers: () => Qr6, printers: () => Ll2 });
|
|
92601
92601
|
As6 = String.prototype.replaceAll ?? function(e, t) {
|
|
92602
92602
|
return e.global ? this.replace(e, t) : this.split(e).join(t);
|
|
92603
92603
|
};
|
|
@@ -92998,7 +92998,7 @@ If '${e}' is a directive input, make sure the directive is imported by the curre
|
|
|
92998
92998
|
ps6 = Yo2;
|
|
92999
92999
|
al2 = { features: { experimental_frontMatterSupport: { massageAstNode: true, embed: true, print: true } }, preprocess: ps6, print: sl3, insertPragma: bi7, massageAstNode: dn5, embed: fi7, getVisitorKeys: _i6 };
|
|
93000
93000
|
hs6 = al2;
|
|
93001
|
-
|
|
93001
|
+
ms8 = [{ name: "Angular", type: "markup", aceMode: "html", extensions: [".component.html"], tmScope: "text.html.basic", aliases: ["xhtml"], codemirrorMode: "htmlmixed", codemirrorMimeType: "text/html", parsers: ["angular"], vscodeLanguageIds: ["html"], filenames: [], linguistLanguageId: 146 }, { name: "HTML", type: "markup", aceMode: "html", extensions: [".html", ".hta", ".htm", ".html.hl", ".inc", ".xht", ".xhtml"], tmScope: "text.html.basic", aliases: ["xhtml"], codemirrorMode: "htmlmixed", codemirrorMimeType: "text/html", parsers: ["html"], vscodeLanguageIds: ["html"], linguistLanguageId: 146 }, { name: "Lightning Web Components", type: "markup", aceMode: "html", extensions: [], tmScope: "text.html.basic", aliases: ["xhtml"], codemirrorMode: "htmlmixed", codemirrorMimeType: "text/html", parsers: ["lwc"], vscodeLanguageIds: ["html"], filenames: [], linguistLanguageId: 146 }, { name: "MJML", type: "markup", aceMode: "html", extensions: [".mjml"], tmScope: "text.mjml.basic", aliases: ["MJML", "mjml"], codemirrorMode: "htmlmixed", codemirrorMimeType: "text/html", parsers: ["mjml"], filenames: [], vscodeLanguageIds: ["mjml"], linguistLanguageId: 146 }, { name: "Vue", type: "markup", aceMode: "vue", extensions: [".vue"], tmScope: "source.vue", codemirrorMode: "vue", codemirrorMimeType: "text/x-vue", parsers: ["vue"], vscodeLanguageIds: ["vue"], linguistLanguageId: 391 }];
|
|
93002
93002
|
Wr4 = { bracketSpacing: { category: "Common", type: "boolean", default: true, description: "Print spaces between brackets.", oppositeDescription: "Do not print spaces between brackets." }, objectWrap: { category: "Common", type: "choice", default: "preserve", description: "How to wrap object literals.", choices: [{ value: "preserve", description: "Keep as multi-line, if there is a newline between the opening brace and first property." }, { value: "collapse", description: "Fit to a single line when possible." }] }, singleQuote: { category: "Common", type: "boolean", default: false, description: "Use single quotes instead of double quotes." }, proseWrap: { category: "Common", type: "choice", default: "preserve", description: "How to wrap prose.", choices: [{ value: "always", description: "Wrap prose if it exceeds the print width." }, { value: "never", description: "Do not wrap prose." }, { value: "preserve", description: "Wrap prose as-is." }] }, bracketSameLine: { category: "Common", type: "boolean", default: false, description: "Put > of opening tags on the last line instead of on a new line." }, singleAttributePerLine: { category: "Common", type: "boolean", default: false, description: "Enforce single attribute per line in HTML, Vue and JSX." } };
|
|
93003
93003
|
ol3 = { bracketSameLine: Wr4.bracketSameLine, htmlWhitespaceSensitivity: { category: fs25, type: "choice", default: "css", description: "How to handle whitespaces in HTML.", choices: [{ value: "css", description: "Respect the default value of CSS display property." }, { value: "strict", description: "Whitespaces are considered sensitive." }, { value: "ignore", description: "Whitespaces are considered insensitive." }] }, singleAttributePerLine: Wr4.singleAttributePerLine, vueIndentScriptAndStyle: { category: fs25, type: "boolean", default: false, description: "Indent script and style tags in Vue files." } };
|
|
93004
93004
|
ds6 = ol3;
|
|
@@ -94224,7 +94224,7 @@ var El3, Ft10, Cl3, vl3, Al3, bl3, x7 = (e, r) => () => (r || e((r = { exports:
|
|
|
94224
94224
|
for (let i of vl3(r))
|
|
94225
94225
|
!bl3.call(e, i) && i !== t && Ft10(e, i, { get: () => r[i], enumerable: !(n = Cl3(r, i)) || n.enumerable });
|
|
94226
94226
|
return e;
|
|
94227
|
-
}, Re9 = (e, r, t) => (t = e != null ? El3(Al3(e)) : {}, xl3(r || !e || !e.__esModule ? Ft10(t, "default", { value: e, enumerable: true }) : t, e)), Tr6, Qi7, Mt10, uu2, lu2, Du2, Ie9, hu2, Fu2, Eu2, vu2, bu2, xu2, yu2, Se9, Tu2, $e8, Ou2, qu2, Iu2, mr6, Ju2, ea4, na3, ua4, Kt8, sa4, fa3, pa3, Fa4, Ea3, va3, xa3, wa3, Zr6, Qt8, Oa3, Pa3, Le9, rt11, Ua4, za3, ja4, nn7, Ja4, no5, oo5, cn6, po5, se8, ln6, bo3, wo4, Bo3, Oo3, Io4, hn6, Yo3, zo3, jo3, Jo3, rs6, us7, ss7, yn6,
|
|
94227
|
+
}, Re9 = (e, r, t) => (t = e != null ? El3(Al3(e)) : {}, xl3(r || !e || !e.__esModule ? Ft10(t, "default", { value: e, enumerable: true }) : t, e)), Tr6, Qi7, Mt10, uu2, lu2, Du2, Ie9, hu2, Fu2, Eu2, vu2, bu2, xu2, yu2, Se9, Tu2, $e8, Ou2, qu2, Iu2, mr6, Ju2, ea4, na3, ua4, Kt8, sa4, fa3, pa3, Fa4, Ea3, va3, xa3, wa3, Zr6, Qt8, Oa3, Pa3, Le9, rt11, Ua4, za3, ja4, nn7, Ja4, no5, oo5, cn6, po5, se8, ln6, bo3, wo4, Bo3, Oo3, Io4, hn6, Yo3, zo3, jo3, Jo3, rs6, us7, ss7, yn6, ms9, Es6, vs8, ys7, ks7, Bs8, Ps8, Ss6, Ys8, zs8, js8, Hs8, Js8, Zs8, nc2, oc2, cc2, Pn5, Ec2, vc2, bc2, Tc2, qc2, Ic2, Sc2, Rc2, Yc2, zc2, Vc2, el3, gl3, Me9 = (e, r) => (t, n, ...i) => t | 1 && n == null ? undefined : (r.call(n) ?? n[e]).apply(n, i), wl3, U9, kl3, Tl3, R10, $i7, _l3 = () => {}, tr8, V9 = "string", j7 = "array", be9 = "cursor", ee6 = "indent", re6 = "align", De8 = "trim", X10 = "group", J11 = "fill", Q10 = "if-break", pe8 = "indent-if-break", he9 = "line-suffix", de8 = "line-suffix-boundary", $9 = "line", me10 = "label", te9 = "break-parent", Br6, W10, ql2 = (e) => new Intl.ListFormat("en-US", { type: "disjunction" }).format(e), gt10, Be8, $n5, Hn5, ne9, Or6, Jn4, Qn5, Ue7, qr5, Nr6, ar8, M9, Sl3, nr7, Ll3 = "cr", Rl2 = "crlf", Ml2 = "\r", Ul2 = `\r
|
|
94228
94228
|
`, Yl2 = `
|
|
94229
94229
|
`, Gl2, ri8 = () => /[#*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, ti8 = "©®‼⁉™ℹ↔↕↖↗↘↙↩↪⌨⏏⏱⏲⏸⏹⏺▪▫▶◀◻◼☀☁☂☃☄☎☑☘☝☠☢☣☦☪☮☯☸☹☺♀♂♟♠♣♥♦♨♻♾⚒⚔⚕⚖⚗⚙⚛⚜⚠⚧⚰⚱⛈⛏⛑⛓⛩⛱⛷⛸⛹✂✈✉✌✍✏✒✔✖✝✡✳✴❄❇❣❤➡⤴⤵⬅⬆⬇", zl2, Wl2, or8, jl2, $l2, vt11, H10, ue8, bt11, Ir5, oi8, si8, ci8, Jl2, Ql2, li8, xt9, fi8, bi8, ef, rf, Di7, nf, hi8 = (e) => String(e).split(/[/\\]/u).pop(), di8 = (e) => String(e).startsWith("file:"), sf = undefined, wt10, Sr6, kt11, sr8 = 3, _e8, gi8 = "format", Ei8, Ci7, Lr7 = (e) => _e8(e).content.trimStart().match(Ci7)?.index === 0, vi8 = (e) => _e8(e).content.trimStart().match(Ei8)?.index === 0, Ai8 = (e) => {
|
|
94230
94230
|
let { frontMatter: r } = _e8(e), t = `<!-- @${gi8} -->`;
|
|
@@ -95901,7 +95901,7 @@ $$`;
|
|
|
95901
95901
|
return n === -1 || t < n ? t : n;
|
|
95902
95902
|
}
|
|
95903
95903
|
});
|
|
95904
|
-
|
|
95904
|
+
ms9 = x7((i2, ds) => {
|
|
95905
95905
|
var br = se8(), T0 = yn6();
|
|
95906
95906
|
ds.exports = hs;
|
|
95907
95907
|
hs.locator = T0;
|
|
@@ -96210,7 +96210,7 @@ $$`;
|
|
|
96210
96210
|
Y.interruptList = [["atxHeading", { pedantic: false }], ["fencedCode", { pedantic: false }], ["thematicBreak", { pedantic: false }], ["definition", { commonmark: false }]];
|
|
96211
96211
|
Y.interruptBlockquote = [["indentedCode", { commonmark: true }], ["fencedCode", { commonmark: true }], ["atxHeading", { commonmark: true }], ["setextHeading", { commonmark: true }], ["thematicBreak", { commonmark: true }], ["html", { commonmark: true }], ["list", { commonmark: true }], ["definition", { commonmark: false }]];
|
|
96212
96212
|
Y.blockTokenizers = { blankLine: wa3(), indentedCode: Oa3(), fencedCode: Pa3(), blockquote: Ua4(), atxHeading: za3(), thematicBreak: ja4(), list: no5(), setextHeading: oo5(), html: po5(), definition: bo3(), table: wo4(), paragraph: Bo3() };
|
|
96213
|
-
Y.inlineTokenizers = { escape: Io4(), autoLink: Yo3(), url: Jo3(), email: us7(), html: ss7(), link:
|
|
96213
|
+
Y.inlineTokenizers = { escape: Io4(), autoLink: Yo3(), url: Jo3(), email: us7(), html: ss7(), link: ms9(), reference: Es6(), strong: ys7(), emphasis: Ps8(), deletion: Ys8(), code: js8(), break: Js8(), text: Zs8() };
|
|
96214
96214
|
Y.blockMethods = rc(Y.blockTokenizers);
|
|
96215
96215
|
Y.inlineMethods = rc(Y.inlineTokenizers);
|
|
96216
96216
|
Y.tokenizeBlock = Nn("block");
|
|
@@ -111521,7 +111521,7 @@ function N62(e) {
|
|
|
111521
111521
|
function nm2(e, t, a) {
|
|
111522
111522
|
return ie10(t, a, e.typeParameters) || ie10(t, a, e.parameters) || S7(t, e.type);
|
|
111523
111523
|
}
|
|
111524
|
-
function
|
|
111524
|
+
function rm4(e, t, a) {
|
|
111525
111525
|
return ie10(t, a, e.types);
|
|
111526
111526
|
}
|
|
111527
111527
|
function im2(e, t, a) {
|
|
@@ -114489,7 +114489,7 @@ ${Me.join(`
|
|
|
114489
114489
|
return S7(a, t.elementType);
|
|
114490
114490
|
}, 190: function(t, a, _) {
|
|
114491
114491
|
return ie10(a, _, t.elements);
|
|
114492
|
-
}, 193:
|
|
114492
|
+
}, 193: rm4, 194: rm4, 195: function(t, a, _) {
|
|
114493
114493
|
return S7(a, t.checkType) || S7(a, t.extendsType) || S7(a, t.trueType) || S7(a, t.falseType);
|
|
114494
114494
|
}, 196: function(t, a, _) {
|
|
114495
114495
|
return S7(a, t.typeParameter);
|
|
@@ -119123,7 +119123,7 @@ import url22 from "url";
|
|
|
119123
119123
|
function diffLines(oldStr, newStr, options8) {
|
|
119124
119124
|
return lineDiff.diff(oldStr, newStr, options8);
|
|
119125
119125
|
}
|
|
119126
|
-
function
|
|
119126
|
+
function tokenize2(value, options8) {
|
|
119127
119127
|
if (options8.stripTrailingCr) {
|
|
119128
119128
|
value = value.replace(/\r\n/g, `
|
|
119129
119129
|
`);
|
|
@@ -120053,7 +120053,7 @@ function highlight(text) {
|
|
|
120053
120053
|
for (const {
|
|
120054
120054
|
type,
|
|
120055
120055
|
value
|
|
120056
|
-
} of
|
|
120056
|
+
} of tokenize22(text)) {
|
|
120057
120057
|
if (type in defs) {
|
|
120058
120058
|
highlighted += value.split(NEWLINE$1).map((str) => defs[type](str)).join(`
|
|
120059
120059
|
`);
|
|
@@ -124581,7 +124581,7 @@ var require2, __filename2, __dirname3, __create2, __defProp3, __getOwnPropDesc2,
|
|
|
124581
124581
|
return internalize({ "": root }, "", reviver);
|
|
124582
124582
|
}
|
|
124583
124583
|
return root;
|
|
124584
|
-
}, lexState, buffer, doubleQuote, sign, c7, lexStates, parseStates, dist_default, import_picocolors4, import_js_tokens, nonASCIIidentifierStartChars = "ªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙՠ-ֈא-תׯ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࡠ-ࡪࡰ-ࢇࢉ-ࢠ-ࣉऄ-हऽॐक़-ॡॱ-ঀঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱৼਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡૹଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-హఽౘ-ౚౝౠౡಀಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽ-ೞೠೡೱೲഄ-ഌഎ-ഐഒ-ഺഽൎൔ-ൖൟ-ൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄຆ-ຊຌ-ຣລວ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏽᏸ-ᏽᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜑᜟ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡸᢀ-ᢨᢪᢰ-ᣵᤀ-ᤞᥐ-ᥭᥰ-ᥴᦀ-ᦫᦰ-ᧉᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭌᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᲀ-Ა-ᲺᲽ-Ჿᳩ-ᳬᳮ-ᳳᳵᳶᳺᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕ℘-ℝℤΩℨK-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⰀ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞ々-〇〡-〩〱-〵〸-〼ぁ-ゖ゛-ゟァ-ヺー-ヿㄅ-ㄯㄱ-ㆎㆠ-ㆿㇰ-ㇿ㐀-䶿一-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚝꚠ-ꛯꜗ-ꜟꜢ-ꞈꞋ--ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꣽꣾꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꩾ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭩꭰ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ", nonASCIIidentifierChars = "·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-٩ٰۖ-ۜ۟-۪ۤۧۨ-ۭ۰-۹ܑܰ-݊ަ-ް߀-߉߫-߽߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛-࢟࣊-ࣣ࣡-ःऺ-़ा-ॏ॑-ॗॢॣ०-९ঁ-ঃ়া-ৄেৈো-্ৗৢৣ০-৯৾ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑ੦-ੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣ૦-૯ૺ-૿ଁ-ଃ଼ା-ୄେୈୋ-୍୕-ୗୢୣ୦-୯ஂா-ூெ-ைொ-்ௗ௦-௯ఀ-ఄ఼ా-ౄె-ైొ-్ౕౖౢౣ౦-౯ಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣ೦-೯ೳഀ-ഃ഻഼ാ-ൄെ-ൈൊ-്ൗൢൣ൦-൯ඁ-ඃ්ා-ුූෘ-ෟ෦-෯ෲෳัิ-ฺ็-๎๐-๙ັິ-ຼ່-໎໐-໙༘༙༠-༩༹༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှ၀-၉ၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏ-ႝ፝-፟፩-፱ᜒ-᜕ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝០-៩᠋-᠍᠏-᠙ᢩᤠ-ᤫᤰ-᤻᥆-᥏᧐-᧚ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼-᪉᪐-᪙᪰-᪽ᪿ--ᬀ-ᬄ᬴-᭄᭐-᭙᭫-᭳ᮀ-ᮂᮡ-ᮭ᮰-᮹᯦-᯳ᰤ-᰷᱀-᱉᱐-᱙᳐-᳔᳒-᳨᳭᳴᳷-᳹᷀-᷿‿⁀⁔⃐-⃥⃜⃡-⃰⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯・꘠-꘩꙯ꙴ-꙽ꚞꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧ꠬ꢀꢁꢴ-ꣅ꣐-꣙꣠-꣱ꣿ-꤉ꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀꧐-꧙ꧥ꧰-꧹ꨩ-ꨶꩃꩌꩍ꩐-꩙ꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭꯰-꯹ﬞ︀-️︠-︯︳︴﹍-﹏0-9_・", nonASCIIidentifierStart, nonASCIIidentifier, reservedWords, keywords, reservedWordsStrictSet, reservedWordsStrictBindSet, compose = (f, g) => (v) => f(g(v)), defsOn, defsOff, sometimesKeywords, NEWLINE$1, BRACKET,
|
|
124584
|
+
}, lexState, buffer, doubleQuote, sign, c7, lexStates, parseStates, dist_default, import_picocolors4, import_js_tokens, nonASCIIidentifierStartChars = "ªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙՠ-ֈא-תׯ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࡠ-ࡪࡰ-ࢇࢉ-ࢠ-ࣉऄ-हऽॐक़-ॡॱ-ঀঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱৼਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡૹଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-హఽౘ-ౚౝౠౡಀಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽ-ೞೠೡೱೲഄ-ഌഎ-ഐഒ-ഺഽൎൔ-ൖൟ-ൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄຆ-ຊຌ-ຣລວ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏽᏸ-ᏽᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜑᜟ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡸᢀ-ᢨᢪᢰ-ᣵᤀ-ᤞᥐ-ᥭᥰ-ᥴᦀ-ᦫᦰ-ᧉᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭌᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᲀ-Ა-ᲺᲽ-Ჿᳩ-ᳬᳮ-ᳳᳵᳶᳺᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕ℘-ℝℤΩℨK-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⰀ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞ々-〇〡-〩〱-〵〸-〼ぁ-ゖ゛-ゟァ-ヺー-ヿㄅ-ㄯㄱ-ㆎㆠ-ㆿㇰ-ㇿ㐀-䶿一-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚝꚠ-ꛯꜗ-ꜟꜢ-ꞈꞋ--ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꣽꣾꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꩾ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭩꭰ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ", nonASCIIidentifierChars = "·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-٩ٰۖ-ۜ۟-۪ۤۧۨ-ۭ۰-۹ܑܰ-݊ަ-ް߀-߉߫-߽߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛-࢟࣊-ࣣ࣡-ःऺ-़ा-ॏ॑-ॗॢॣ०-९ঁ-ঃ়া-ৄেৈো-্ৗৢৣ০-৯৾ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑ੦-ੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣ૦-૯ૺ-૿ଁ-ଃ଼ା-ୄେୈୋ-୍୕-ୗୢୣ୦-୯ஂா-ூெ-ைொ-்ௗ௦-௯ఀ-ఄ఼ా-ౄె-ైొ-్ౕౖౢౣ౦-౯ಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣ೦-೯ೳഀ-ഃ഻഼ാ-ൄെ-ൈൊ-്ൗൢൣ൦-൯ඁ-ඃ්ා-ුූෘ-ෟ෦-෯ෲෳัิ-ฺ็-๎๐-๙ັິ-ຼ່-໎໐-໙༘༙༠-༩༹༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှ၀-၉ၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏ-ႝ፝-፟፩-፱ᜒ-᜕ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝០-៩᠋-᠍᠏-᠙ᢩᤠ-ᤫᤰ-᤻᥆-᥏᧐-᧚ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼-᪉᪐-᪙᪰-᪽ᪿ--ᬀ-ᬄ᬴-᭄᭐-᭙᭫-᭳ᮀ-ᮂᮡ-ᮭ᮰-᮹᯦-᯳ᰤ-᰷᱀-᱉᱐-᱙᳐-᳔᳒-᳨᳭᳴᳷-᳹᷀-᷿‿⁀⁔⃐-⃥⃜⃡-⃰⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯・꘠-꘩꙯ꙴ-꙽ꚞꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧ꠬ꢀꢁꢴ-ꣅ꣐-꣙꣠-꣱ꣿ-꤉ꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀꧐-꧙ꧥ꧰-꧹ꨩ-ꨶꩃꩌꩍ꩐-꩙ꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭꯰-꯹ﬞ︀-️︠-︯︳︴﹍-﹏0-9_・", nonASCIIidentifierStart, nonASCIIidentifier, reservedWords, keywords, reservedWordsStrictSet, reservedWordsStrictBindSet, compose = (f, g) => (v) => f(g(v)), defsOn, defsOff, sometimesKeywords, NEWLINE$1, BRACKET, tokenize22, NEWLINE, getOffsets = ({
|
|
124585
124585
|
oneBased,
|
|
124586
124586
|
oneBasedLine = oneBased,
|
|
124587
124587
|
oneBasedColumn = oneBased
|
|
@@ -124807,7 +124807,7 @@ var require2, __filename2, __dirname3, __create2, __defProp3, __getOwnPropDesc2,
|
|
|
124807
124807
|
}
|
|
124808
124808
|
}
|
|
124809
124809
|
}, ast_path_default, is_object_default, skipWhitespace, skipSpaces, skipToLineEnd, skipEverythingButNewLine, isNewlineCharacter = (character) => character === `
|
|
124810
|
-
` || character === "\r" || character === "\u2028" || character === "\u2029", skip_newline_default, has_newline_default, is_non_empty_array_default, get_sorted_child_nodes_default, childNodesCache, returnFalse = () => false, isAllEmptyAndNoLineBreak = (text) => !/[\S\n\u2028\u2029]/u.test(text), is_previous_line_empty_default, breakParent2, hardline2, indent2,
|
|
124810
|
+
` || character === "\r" || character === "\u2028" || character === "\u2029", skip_newline_default, has_newline_default, is_non_empty_array_default, get_sorted_child_nodes_default, childNodesCache, returnFalse = () => false, isAllEmptyAndNoLineBreak = (text) => !/[\S\n\u2028\u2029]/u.test(text), is_previous_line_empty_default, breakParent2, hardline2, indent2, join35, line22, lineSuffix2, create_print_pre_check_function_default = () => noop_default2, core_options_evaluate_default, arrayToReversed, toReversed, method_to_reversed_default, import_n_readlines, get_interpreter_default, getFileBasename = (file) => {
|
|
124811
124811
|
try {
|
|
124812
124812
|
return path112.basename(toPath3(file));
|
|
124813
124813
|
} catch {
|
|
@@ -133471,7 +133471,7 @@ globstar while`, file, fr, pattern, pr, swallowee);
|
|
|
133471
133471
|
LineDiff = class extends Diff {
|
|
133472
133472
|
constructor() {
|
|
133473
133473
|
super(...arguments);
|
|
133474
|
-
this.tokenize =
|
|
133474
|
+
this.tokenize = tokenize2;
|
|
133475
133475
|
}
|
|
133476
133476
|
equals(left, right, options8) {
|
|
133477
133477
|
if (options8.ignoreWhitespace) {
|
|
@@ -134348,7 +134348,7 @@ globstar while`, file, fr, pattern, pr, swallowee);
|
|
|
134348
134348
|
return "uncolored";
|
|
134349
134349
|
}
|
|
134350
134350
|
};
|
|
134351
|
-
|
|
134351
|
+
tokenize22 = function* (text) {
|
|
134352
134352
|
for (const token2 of (0, import_js_tokens.default)(text, {
|
|
134353
134353
|
jsx: true
|
|
134354
134354
|
})) {
|
|
@@ -134836,7 +134836,7 @@ ${codeblock}`, options8);
|
|
|
134836
134836
|
breakParent: breakParent2,
|
|
134837
134837
|
hardline: hardline2,
|
|
134838
134838
|
indent: indent2,
|
|
134839
|
-
join:
|
|
134839
|
+
join: join35,
|
|
134840
134840
|
line: line22,
|
|
134841
134841
|
lineSuffix: lineSuffix2
|
|
134842
134842
|
} = builders);
|
|
@@ -228838,7 +228838,7 @@ function normalizeBase44Env() {
|
|
|
228838
228838
|
loadProjectEnvFiles();
|
|
228839
228839
|
|
|
228840
228840
|
// src/cli/index.ts
|
|
228841
|
-
import { dirname as dirname30, join as
|
|
228841
|
+
import { dirname as dirname30, join as join43 } from "node:path";
|
|
228842
228842
|
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
228843
228843
|
|
|
228844
228844
|
// ../../node_modules/@clack/core/dist/index.mjs
|
|
@@ -239451,6 +239451,7 @@ var package_default = {
|
|
|
239451
239451
|
jsonwebtoken: "^9.0.3",
|
|
239452
239452
|
ky: "^1.14.2",
|
|
239453
239453
|
lodash: "^4.17.23",
|
|
239454
|
+
minisearch: "^7.1.2",
|
|
239454
239455
|
ms: "^2.1.3",
|
|
239455
239456
|
multer: "^2.0.0",
|
|
239456
239457
|
nanoid: "^5.1.6",
|
|
@@ -246836,10 +246837,21 @@ var {
|
|
|
246836
246837
|
} = getIpcExport();
|
|
246837
246838
|
|
|
246838
246839
|
// src/core/utils/git.ts
|
|
246840
|
+
import { dirname as dirname13, join as join19 } from "node:path";
|
|
246839
246841
|
var GIT_HASH_PATTERN = /^[a-fA-F0-9]{7,64}$/;
|
|
246840
246842
|
function isGitCommitHash(value) {
|
|
246841
246843
|
return GIT_HASH_PATTERN.test(value);
|
|
246842
246844
|
}
|
|
246845
|
+
async function findGitRoot2(startPath = process.cwd()) {
|
|
246846
|
+
let current = startPath;
|
|
246847
|
+
while (!await pathExists(join19(current, ".git"))) {
|
|
246848
|
+
const parent = dirname13(current);
|
|
246849
|
+
if (parent === current)
|
|
246850
|
+
return;
|
|
246851
|
+
current = parent;
|
|
246852
|
+
}
|
|
246853
|
+
return current;
|
|
246854
|
+
}
|
|
246843
246855
|
|
|
246844
246856
|
// src/core/site/git-hash.ts
|
|
246845
246857
|
async function resolveGitHash(projectRoot, explicit) {
|
|
@@ -246951,20 +246963,19 @@ async function deployAll(projectData, options) {
|
|
|
246951
246963
|
return { connectorResults };
|
|
246952
246964
|
}
|
|
246953
246965
|
// src/core/project/target.ts
|
|
246954
|
-
import { dirname as
|
|
246966
|
+
import { dirname as dirname14, join as join20, resolve as resolve6 } from "node:path";
|
|
246955
246967
|
async function resolveBuildTarget(projectRoot, overrides = {}) {
|
|
246956
246968
|
const project = await readSettingsIfPresent(projectRoot);
|
|
246957
246969
|
const root = project?.root ?? projectRoot ?? process.cwd();
|
|
246958
246970
|
const site = project ? siteOrDefault(project) : DEFAULT_SITE;
|
|
246959
246971
|
return {
|
|
246960
246972
|
root,
|
|
246961
|
-
configDir: project ?
|
|
246973
|
+
configDir: project ? dirname14(project.configPath) : join20(root, PROJECT_SUBDIR),
|
|
246962
246974
|
buildCommand: site.buildCommand,
|
|
246963
246975
|
outputDir: resolve6(root, overrides.outputDir ?? site.outputDirectory ?? DEFAULT_SITE.outputDirectory),
|
|
246964
246976
|
entitiesDir: project?.entitiesDir ?? "entities",
|
|
246965
246977
|
agentsDir: project?.agentsDir ?? "agents",
|
|
246966
|
-
functionsDir: project?.functionsDir ?? "functions"
|
|
246967
|
-
actorsDir: project?.actorsDir ?? "actors"
|
|
246978
|
+
functionsDir: project?.functionsDir ?? "functions"
|
|
246968
246979
|
};
|
|
246969
246980
|
}
|
|
246970
246981
|
async function readSettingsIfPresent(projectRoot) {
|
|
@@ -247587,8 +247598,8 @@ function normalizeDatetime(value) {
|
|
|
247587
247598
|
return `${value}Z`;
|
|
247588
247599
|
}
|
|
247589
247600
|
// src/cli/utils/json.ts
|
|
247590
|
-
function toJsonStdout(result) {
|
|
247591
|
-
return `${JSON.stringify(result, null, 2)}
|
|
247601
|
+
function toJsonStdout(result, options = {}) {
|
|
247602
|
+
return `${JSON.stringify(result, null, options.compact ? undefined : 2)}
|
|
247592
247603
|
`;
|
|
247593
247604
|
}
|
|
247594
247605
|
// src/cli/errors.ts
|
|
@@ -247695,6 +247706,9 @@ function getConnectorsUrl(projectId) {
|
|
|
247695
247706
|
const id = projectId ?? getAppContext().id;
|
|
247696
247707
|
return `${getBase44ApiUrl()}/apps/${id}/editor/workspace/app-connections`;
|
|
247697
247708
|
}
|
|
247709
|
+
function getBaseCodeUrl(appId, branchName) {
|
|
247710
|
+
return `${getBase44ApiUrl()}/apps/${appId}/editor/workspace/code?branch=${encodeURIComponent(branchName)}`;
|
|
247711
|
+
}
|
|
247698
247712
|
// src/cli/utils/yaml.ts
|
|
247699
247713
|
var import_lodash = __toESM(require_lodash8(), 1);
|
|
247700
247714
|
var YAML_INDENT = 2;
|
|
@@ -247821,7 +247835,7 @@ function getActorsCommand() {
|
|
|
247821
247835
|
}
|
|
247822
247836
|
|
|
247823
247837
|
// src/cli/commands/agent-skills/pull.ts
|
|
247824
|
-
import { dirname as
|
|
247838
|
+
import { dirname as dirname15, join as join21 } from "node:path";
|
|
247825
247839
|
// src/core/utils/dependencies.ts
|
|
247826
247840
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
247827
247841
|
function verifyDenoInstalled(context) {
|
|
@@ -247910,7 +247924,7 @@ async function pullAction({
|
|
|
247910
247924
|
runTask
|
|
247911
247925
|
}) {
|
|
247912
247926
|
const { project } = await readProjectConfig();
|
|
247913
|
-
const dir =
|
|
247927
|
+
const dir = join21(dirname15(project.configPath), project.agentSkillsDir);
|
|
247914
247928
|
const remote = await runTask("Fetching agent skills from Base44", () => fetchAgentSkills(), {
|
|
247915
247929
|
successMessage: "Agent skills fetched successfully",
|
|
247916
247930
|
errorMessage: "Failed to fetch agent skills"
|
|
@@ -247966,14 +247980,14 @@ function getAgentSkillsCommand() {
|
|
|
247966
247980
|
}
|
|
247967
247981
|
|
|
247968
247982
|
// src/cli/commands/agents/pull.ts
|
|
247969
|
-
import { dirname as
|
|
247983
|
+
import { dirname as dirname16, join as join22 } from "node:path";
|
|
247970
247984
|
async function pullAgentsAction({
|
|
247971
247985
|
log,
|
|
247972
247986
|
runTask
|
|
247973
247987
|
}) {
|
|
247974
247988
|
const { project } = await readProjectConfig();
|
|
247975
|
-
const configDir =
|
|
247976
|
-
const agentsDir =
|
|
247989
|
+
const configDir = dirname16(project.configPath);
|
|
247990
|
+
const agentsDir = join22(configDir, project.agentsDir);
|
|
247977
247991
|
const remoteAgents = await runTask("Fetching agents from Base44", async () => {
|
|
247978
247992
|
return await fetchAgents();
|
|
247979
247993
|
}, {
|
|
@@ -248042,13 +248056,1873 @@ function getAgentsCommand() {
|
|
|
248042
248056
|
return new Command2("agents").description("Manage project agents").addCommand(getAgentsPushCommand()).addCommand(getAgentsPullCommand());
|
|
248043
248057
|
}
|
|
248044
248058
|
|
|
248059
|
+
// ../../node_modules/minisearch/dist/es/index.js
|
|
248060
|
+
var ENTRIES = "ENTRIES";
|
|
248061
|
+
var KEYS = "KEYS";
|
|
248062
|
+
var VALUES = "VALUES";
|
|
248063
|
+
var LEAF = "";
|
|
248064
|
+
|
|
248065
|
+
class TreeIterator {
|
|
248066
|
+
constructor(set, type) {
|
|
248067
|
+
const node = set._tree;
|
|
248068
|
+
const keys = Array.from(node.keys());
|
|
248069
|
+
this.set = set;
|
|
248070
|
+
this._type = type;
|
|
248071
|
+
this._path = keys.length > 0 ? [{ node, keys }] : [];
|
|
248072
|
+
}
|
|
248073
|
+
next() {
|
|
248074
|
+
const value = this.dive();
|
|
248075
|
+
this.backtrack();
|
|
248076
|
+
return value;
|
|
248077
|
+
}
|
|
248078
|
+
dive() {
|
|
248079
|
+
if (this._path.length === 0) {
|
|
248080
|
+
return { done: true, value: undefined };
|
|
248081
|
+
}
|
|
248082
|
+
const { node, keys } = last$1(this._path);
|
|
248083
|
+
if (last$1(keys) === LEAF) {
|
|
248084
|
+
return { done: false, value: this.result() };
|
|
248085
|
+
}
|
|
248086
|
+
const child = node.get(last$1(keys));
|
|
248087
|
+
this._path.push({ node: child, keys: Array.from(child.keys()) });
|
|
248088
|
+
return this.dive();
|
|
248089
|
+
}
|
|
248090
|
+
backtrack() {
|
|
248091
|
+
if (this._path.length === 0) {
|
|
248092
|
+
return;
|
|
248093
|
+
}
|
|
248094
|
+
const keys = last$1(this._path).keys;
|
|
248095
|
+
keys.pop();
|
|
248096
|
+
if (keys.length > 0) {
|
|
248097
|
+
return;
|
|
248098
|
+
}
|
|
248099
|
+
this._path.pop();
|
|
248100
|
+
this.backtrack();
|
|
248101
|
+
}
|
|
248102
|
+
key() {
|
|
248103
|
+
return this.set._prefix + this._path.map(({ keys }) => last$1(keys)).filter((key) => key !== LEAF).join("");
|
|
248104
|
+
}
|
|
248105
|
+
value() {
|
|
248106
|
+
return last$1(this._path).node.get(LEAF);
|
|
248107
|
+
}
|
|
248108
|
+
result() {
|
|
248109
|
+
switch (this._type) {
|
|
248110
|
+
case VALUES:
|
|
248111
|
+
return this.value();
|
|
248112
|
+
case KEYS:
|
|
248113
|
+
return this.key();
|
|
248114
|
+
default:
|
|
248115
|
+
return [this.key(), this.value()];
|
|
248116
|
+
}
|
|
248117
|
+
}
|
|
248118
|
+
[Symbol.iterator]() {
|
|
248119
|
+
return this;
|
|
248120
|
+
}
|
|
248121
|
+
}
|
|
248122
|
+
var last$1 = (array) => {
|
|
248123
|
+
return array[array.length - 1];
|
|
248124
|
+
};
|
|
248125
|
+
var fuzzySearch = (node, query, maxDistance) => {
|
|
248126
|
+
const results = new Map;
|
|
248127
|
+
if (query === undefined)
|
|
248128
|
+
return results;
|
|
248129
|
+
const n = query.length + 1;
|
|
248130
|
+
const m = n + maxDistance;
|
|
248131
|
+
const matrix = new Uint8Array(m * n).fill(maxDistance + 1);
|
|
248132
|
+
for (let j = 0;j < n; ++j)
|
|
248133
|
+
matrix[j] = j;
|
|
248134
|
+
for (let i = 1;i < m; ++i)
|
|
248135
|
+
matrix[i * n] = i;
|
|
248136
|
+
recurse(node, query, maxDistance, results, matrix, 1, n, "");
|
|
248137
|
+
return results;
|
|
248138
|
+
};
|
|
248139
|
+
var recurse = (node, query, maxDistance, results, matrix, m, n, prefix) => {
|
|
248140
|
+
const offset = m * n;
|
|
248141
|
+
key:
|
|
248142
|
+
for (const key of node.keys()) {
|
|
248143
|
+
if (key === LEAF) {
|
|
248144
|
+
const distance = matrix[offset - 1];
|
|
248145
|
+
if (distance <= maxDistance) {
|
|
248146
|
+
results.set(prefix, [node.get(key), distance]);
|
|
248147
|
+
}
|
|
248148
|
+
} else {
|
|
248149
|
+
let i = m;
|
|
248150
|
+
for (let pos = 0;pos < key.length; ++pos, ++i) {
|
|
248151
|
+
const char = key[pos];
|
|
248152
|
+
const thisRowOffset = n * i;
|
|
248153
|
+
const prevRowOffset = thisRowOffset - n;
|
|
248154
|
+
let minDistance = matrix[thisRowOffset];
|
|
248155
|
+
const jmin = Math.max(0, i - maxDistance - 1);
|
|
248156
|
+
const jmax = Math.min(n - 1, i + maxDistance);
|
|
248157
|
+
for (let j = jmin;j < jmax; ++j) {
|
|
248158
|
+
const different = char !== query[j];
|
|
248159
|
+
const rpl = matrix[prevRowOffset + j] + +different;
|
|
248160
|
+
const del = matrix[prevRowOffset + j + 1] + 1;
|
|
248161
|
+
const ins = matrix[thisRowOffset + j] + 1;
|
|
248162
|
+
const dist = matrix[thisRowOffset + j + 1] = Math.min(rpl, del, ins);
|
|
248163
|
+
if (dist < minDistance)
|
|
248164
|
+
minDistance = dist;
|
|
248165
|
+
}
|
|
248166
|
+
if (minDistance > maxDistance) {
|
|
248167
|
+
continue key;
|
|
248168
|
+
}
|
|
248169
|
+
}
|
|
248170
|
+
recurse(node.get(key), query, maxDistance, results, matrix, i, n, prefix + key);
|
|
248171
|
+
}
|
|
248172
|
+
}
|
|
248173
|
+
};
|
|
248174
|
+
|
|
248175
|
+
class SearchableMap {
|
|
248176
|
+
constructor(tree = new Map, prefix = "") {
|
|
248177
|
+
this._size = undefined;
|
|
248178
|
+
this._tree = tree;
|
|
248179
|
+
this._prefix = prefix;
|
|
248180
|
+
}
|
|
248181
|
+
atPrefix(prefix) {
|
|
248182
|
+
if (!prefix.startsWith(this._prefix)) {
|
|
248183
|
+
throw new Error("Mismatched prefix");
|
|
248184
|
+
}
|
|
248185
|
+
const [node, path] = trackDown(this._tree, prefix.slice(this._prefix.length));
|
|
248186
|
+
if (node === undefined) {
|
|
248187
|
+
const [parentNode, key] = last(path);
|
|
248188
|
+
for (const k of parentNode.keys()) {
|
|
248189
|
+
if (k !== LEAF && k.startsWith(key)) {
|
|
248190
|
+
const node = new Map;
|
|
248191
|
+
node.set(k.slice(key.length), parentNode.get(k));
|
|
248192
|
+
return new SearchableMap(node, prefix);
|
|
248193
|
+
}
|
|
248194
|
+
}
|
|
248195
|
+
}
|
|
248196
|
+
return new SearchableMap(node, prefix);
|
|
248197
|
+
}
|
|
248198
|
+
clear() {
|
|
248199
|
+
this._size = undefined;
|
|
248200
|
+
this._tree.clear();
|
|
248201
|
+
}
|
|
248202
|
+
delete(key) {
|
|
248203
|
+
this._size = undefined;
|
|
248204
|
+
return remove(this._tree, key);
|
|
248205
|
+
}
|
|
248206
|
+
entries() {
|
|
248207
|
+
return new TreeIterator(this, ENTRIES);
|
|
248208
|
+
}
|
|
248209
|
+
forEach(fn) {
|
|
248210
|
+
for (const [key, value] of this) {
|
|
248211
|
+
fn(key, value, this);
|
|
248212
|
+
}
|
|
248213
|
+
}
|
|
248214
|
+
fuzzyGet(key, maxEditDistance) {
|
|
248215
|
+
return fuzzySearch(this._tree, key, maxEditDistance);
|
|
248216
|
+
}
|
|
248217
|
+
get(key) {
|
|
248218
|
+
const node = lookup(this._tree, key);
|
|
248219
|
+
return node !== undefined ? node.get(LEAF) : undefined;
|
|
248220
|
+
}
|
|
248221
|
+
has(key) {
|
|
248222
|
+
const node = lookup(this._tree, key);
|
|
248223
|
+
return node !== undefined && node.has(LEAF);
|
|
248224
|
+
}
|
|
248225
|
+
keys() {
|
|
248226
|
+
return new TreeIterator(this, KEYS);
|
|
248227
|
+
}
|
|
248228
|
+
set(key, value) {
|
|
248229
|
+
if (typeof key !== "string") {
|
|
248230
|
+
throw new Error("key must be a string");
|
|
248231
|
+
}
|
|
248232
|
+
this._size = undefined;
|
|
248233
|
+
const node = createPath(this._tree, key);
|
|
248234
|
+
node.set(LEAF, value);
|
|
248235
|
+
return this;
|
|
248236
|
+
}
|
|
248237
|
+
get size() {
|
|
248238
|
+
if (this._size) {
|
|
248239
|
+
return this._size;
|
|
248240
|
+
}
|
|
248241
|
+
this._size = 0;
|
|
248242
|
+
const iter = this.entries();
|
|
248243
|
+
while (!iter.next().done)
|
|
248244
|
+
this._size += 1;
|
|
248245
|
+
return this._size;
|
|
248246
|
+
}
|
|
248247
|
+
update(key, fn) {
|
|
248248
|
+
if (typeof key !== "string") {
|
|
248249
|
+
throw new Error("key must be a string");
|
|
248250
|
+
}
|
|
248251
|
+
this._size = undefined;
|
|
248252
|
+
const node = createPath(this._tree, key);
|
|
248253
|
+
node.set(LEAF, fn(node.get(LEAF)));
|
|
248254
|
+
return this;
|
|
248255
|
+
}
|
|
248256
|
+
fetch(key, initial) {
|
|
248257
|
+
if (typeof key !== "string") {
|
|
248258
|
+
throw new Error("key must be a string");
|
|
248259
|
+
}
|
|
248260
|
+
this._size = undefined;
|
|
248261
|
+
const node = createPath(this._tree, key);
|
|
248262
|
+
let value = node.get(LEAF);
|
|
248263
|
+
if (value === undefined) {
|
|
248264
|
+
node.set(LEAF, value = initial());
|
|
248265
|
+
}
|
|
248266
|
+
return value;
|
|
248267
|
+
}
|
|
248268
|
+
values() {
|
|
248269
|
+
return new TreeIterator(this, VALUES);
|
|
248270
|
+
}
|
|
248271
|
+
[Symbol.iterator]() {
|
|
248272
|
+
return this.entries();
|
|
248273
|
+
}
|
|
248274
|
+
static from(entries) {
|
|
248275
|
+
const tree = new SearchableMap;
|
|
248276
|
+
for (const [key, value] of entries) {
|
|
248277
|
+
tree.set(key, value);
|
|
248278
|
+
}
|
|
248279
|
+
return tree;
|
|
248280
|
+
}
|
|
248281
|
+
static fromObject(object) {
|
|
248282
|
+
return SearchableMap.from(Object.entries(object));
|
|
248283
|
+
}
|
|
248284
|
+
}
|
|
248285
|
+
var trackDown = (tree, key, path = []) => {
|
|
248286
|
+
if (key.length === 0 || tree == null) {
|
|
248287
|
+
return [tree, path];
|
|
248288
|
+
}
|
|
248289
|
+
for (const k of tree.keys()) {
|
|
248290
|
+
if (k !== LEAF && key.startsWith(k)) {
|
|
248291
|
+
path.push([tree, k]);
|
|
248292
|
+
return trackDown(tree.get(k), key.slice(k.length), path);
|
|
248293
|
+
}
|
|
248294
|
+
}
|
|
248295
|
+
path.push([tree, key]);
|
|
248296
|
+
return trackDown(undefined, "", path);
|
|
248297
|
+
};
|
|
248298
|
+
var lookup = (tree, key) => {
|
|
248299
|
+
if (key.length === 0 || tree == null) {
|
|
248300
|
+
return tree;
|
|
248301
|
+
}
|
|
248302
|
+
for (const k of tree.keys()) {
|
|
248303
|
+
if (k !== LEAF && key.startsWith(k)) {
|
|
248304
|
+
return lookup(tree.get(k), key.slice(k.length));
|
|
248305
|
+
}
|
|
248306
|
+
}
|
|
248307
|
+
};
|
|
248308
|
+
var createPath = (node, key) => {
|
|
248309
|
+
const keyLength = key.length;
|
|
248310
|
+
outer:
|
|
248311
|
+
for (let pos = 0;node && pos < keyLength; ) {
|
|
248312
|
+
for (const k of node.keys()) {
|
|
248313
|
+
if (k !== LEAF && key[pos] === k[0]) {
|
|
248314
|
+
const len = Math.min(keyLength - pos, k.length);
|
|
248315
|
+
let offset = 1;
|
|
248316
|
+
while (offset < len && key[pos + offset] === k[offset])
|
|
248317
|
+
++offset;
|
|
248318
|
+
const child = node.get(k);
|
|
248319
|
+
if (offset === k.length) {
|
|
248320
|
+
node = child;
|
|
248321
|
+
} else {
|
|
248322
|
+
const intermediate = new Map;
|
|
248323
|
+
intermediate.set(k.slice(offset), child);
|
|
248324
|
+
node.set(key.slice(pos, pos + offset), intermediate);
|
|
248325
|
+
node.delete(k);
|
|
248326
|
+
node = intermediate;
|
|
248327
|
+
}
|
|
248328
|
+
pos += offset;
|
|
248329
|
+
continue outer;
|
|
248330
|
+
}
|
|
248331
|
+
}
|
|
248332
|
+
const child = new Map;
|
|
248333
|
+
node.set(key.slice(pos), child);
|
|
248334
|
+
return child;
|
|
248335
|
+
}
|
|
248336
|
+
return node;
|
|
248337
|
+
};
|
|
248338
|
+
var remove = (tree, key) => {
|
|
248339
|
+
const [node, path] = trackDown(tree, key);
|
|
248340
|
+
if (node === undefined) {
|
|
248341
|
+
return;
|
|
248342
|
+
}
|
|
248343
|
+
node.delete(LEAF);
|
|
248344
|
+
if (node.size === 0) {
|
|
248345
|
+
cleanup(path);
|
|
248346
|
+
} else if (node.size === 1) {
|
|
248347
|
+
const [key, value] = node.entries().next().value;
|
|
248348
|
+
merge3(path, key, value);
|
|
248349
|
+
}
|
|
248350
|
+
};
|
|
248351
|
+
var cleanup = (path) => {
|
|
248352
|
+
if (path.length === 0) {
|
|
248353
|
+
return;
|
|
248354
|
+
}
|
|
248355
|
+
const [node, key] = last(path);
|
|
248356
|
+
node.delete(key);
|
|
248357
|
+
if (node.size === 0) {
|
|
248358
|
+
cleanup(path.slice(0, -1));
|
|
248359
|
+
} else if (node.size === 1) {
|
|
248360
|
+
const [key, value] = node.entries().next().value;
|
|
248361
|
+
if (key !== LEAF) {
|
|
248362
|
+
merge3(path.slice(0, -1), key, value);
|
|
248363
|
+
}
|
|
248364
|
+
}
|
|
248365
|
+
};
|
|
248366
|
+
var merge3 = (path, key, value) => {
|
|
248367
|
+
if (path.length === 0) {
|
|
248368
|
+
return;
|
|
248369
|
+
}
|
|
248370
|
+
const [node, nodeKey] = last(path);
|
|
248371
|
+
node.set(nodeKey + key, value);
|
|
248372
|
+
node.delete(nodeKey);
|
|
248373
|
+
};
|
|
248374
|
+
var last = (array) => {
|
|
248375
|
+
return array[array.length - 1];
|
|
248376
|
+
};
|
|
248377
|
+
var OR = "or";
|
|
248378
|
+
var AND = "and";
|
|
248379
|
+
var AND_NOT = "and_not";
|
|
248380
|
+
|
|
248381
|
+
class MiniSearch {
|
|
248382
|
+
constructor(options) {
|
|
248383
|
+
if ((options === null || options === undefined ? undefined : options.fields) == null) {
|
|
248384
|
+
throw new Error('MiniSearch: option "fields" must be provided');
|
|
248385
|
+
}
|
|
248386
|
+
const autoVacuum = options.autoVacuum == null || options.autoVacuum === true ? defaultAutoVacuumOptions : options.autoVacuum;
|
|
248387
|
+
this._options = {
|
|
248388
|
+
...defaultOptions,
|
|
248389
|
+
...options,
|
|
248390
|
+
autoVacuum,
|
|
248391
|
+
searchOptions: { ...defaultSearchOptions, ...options.searchOptions || {} },
|
|
248392
|
+
autoSuggestOptions: { ...defaultAutoSuggestOptions, ...options.autoSuggestOptions || {} }
|
|
248393
|
+
};
|
|
248394
|
+
this._index = new SearchableMap;
|
|
248395
|
+
this._documentCount = 0;
|
|
248396
|
+
this._documentIds = new Map;
|
|
248397
|
+
this._idToShortId = new Map;
|
|
248398
|
+
this._fieldIds = {};
|
|
248399
|
+
this._fieldLength = new Map;
|
|
248400
|
+
this._avgFieldLength = [];
|
|
248401
|
+
this._nextId = 0;
|
|
248402
|
+
this._storedFields = new Map;
|
|
248403
|
+
this._dirtCount = 0;
|
|
248404
|
+
this._currentVacuum = null;
|
|
248405
|
+
this._enqueuedVacuum = null;
|
|
248406
|
+
this._enqueuedVacuumConditions = defaultVacuumConditions;
|
|
248407
|
+
this.addFields(this._options.fields);
|
|
248408
|
+
}
|
|
248409
|
+
add(document2) {
|
|
248410
|
+
const { extractField, tokenize, processTerm, fields, idField } = this._options;
|
|
248411
|
+
const id = extractField(document2, idField);
|
|
248412
|
+
if (id == null) {
|
|
248413
|
+
throw new Error(`MiniSearch: document does not have ID field "${idField}"`);
|
|
248414
|
+
}
|
|
248415
|
+
if (this._idToShortId.has(id)) {
|
|
248416
|
+
throw new Error(`MiniSearch: duplicate ID ${id}`);
|
|
248417
|
+
}
|
|
248418
|
+
const shortDocumentId = this.addDocumentId(id);
|
|
248419
|
+
this.saveStoredFields(shortDocumentId, document2);
|
|
248420
|
+
for (const field of fields) {
|
|
248421
|
+
const fieldValue = extractField(document2, field);
|
|
248422
|
+
if (fieldValue == null)
|
|
248423
|
+
continue;
|
|
248424
|
+
const tokens = tokenize(fieldValue.toString(), field);
|
|
248425
|
+
const fieldId = this._fieldIds[field];
|
|
248426
|
+
const uniqueTerms = new Set(tokens).size;
|
|
248427
|
+
this.addFieldLength(shortDocumentId, fieldId, this._documentCount - 1, uniqueTerms);
|
|
248428
|
+
for (const term of tokens) {
|
|
248429
|
+
const processedTerm = processTerm(term, field);
|
|
248430
|
+
if (Array.isArray(processedTerm)) {
|
|
248431
|
+
for (const t of processedTerm) {
|
|
248432
|
+
this.addTerm(fieldId, shortDocumentId, t);
|
|
248433
|
+
}
|
|
248434
|
+
} else if (processedTerm) {
|
|
248435
|
+
this.addTerm(fieldId, shortDocumentId, processedTerm);
|
|
248436
|
+
}
|
|
248437
|
+
}
|
|
248438
|
+
}
|
|
248439
|
+
}
|
|
248440
|
+
addAll(documents) {
|
|
248441
|
+
for (const document2 of documents)
|
|
248442
|
+
this.add(document2);
|
|
248443
|
+
}
|
|
248444
|
+
addAllAsync(documents, options = {}) {
|
|
248445
|
+
const { chunkSize = 10 } = options;
|
|
248446
|
+
const acc = { chunk: [], promise: Promise.resolve() };
|
|
248447
|
+
const { chunk, promise } = documents.reduce(({ chunk, promise }, document2, i) => {
|
|
248448
|
+
chunk.push(document2);
|
|
248449
|
+
if ((i + 1) % chunkSize === 0) {
|
|
248450
|
+
return {
|
|
248451
|
+
chunk: [],
|
|
248452
|
+
promise: promise.then(() => new Promise((resolve) => setTimeout(resolve, 0))).then(() => this.addAll(chunk))
|
|
248453
|
+
};
|
|
248454
|
+
} else {
|
|
248455
|
+
return { chunk, promise };
|
|
248456
|
+
}
|
|
248457
|
+
}, acc);
|
|
248458
|
+
return promise.then(() => this.addAll(chunk));
|
|
248459
|
+
}
|
|
248460
|
+
remove(document2) {
|
|
248461
|
+
const { tokenize, processTerm, extractField, fields, idField } = this._options;
|
|
248462
|
+
const id = extractField(document2, idField);
|
|
248463
|
+
if (id == null) {
|
|
248464
|
+
throw new Error(`MiniSearch: document does not have ID field "${idField}"`);
|
|
248465
|
+
}
|
|
248466
|
+
const shortId = this._idToShortId.get(id);
|
|
248467
|
+
if (shortId == null) {
|
|
248468
|
+
throw new Error(`MiniSearch: cannot remove document with ID ${id}: it is not in the index`);
|
|
248469
|
+
}
|
|
248470
|
+
for (const field of fields) {
|
|
248471
|
+
const fieldValue = extractField(document2, field);
|
|
248472
|
+
if (fieldValue == null)
|
|
248473
|
+
continue;
|
|
248474
|
+
const tokens = tokenize(fieldValue.toString(), field);
|
|
248475
|
+
const fieldId = this._fieldIds[field];
|
|
248476
|
+
const uniqueTerms = new Set(tokens).size;
|
|
248477
|
+
this.removeFieldLength(shortId, fieldId, this._documentCount, uniqueTerms);
|
|
248478
|
+
for (const term of tokens) {
|
|
248479
|
+
const processedTerm = processTerm(term, field);
|
|
248480
|
+
if (Array.isArray(processedTerm)) {
|
|
248481
|
+
for (const t of processedTerm) {
|
|
248482
|
+
this.removeTerm(fieldId, shortId, t);
|
|
248483
|
+
}
|
|
248484
|
+
} else if (processedTerm) {
|
|
248485
|
+
this.removeTerm(fieldId, shortId, processedTerm);
|
|
248486
|
+
}
|
|
248487
|
+
}
|
|
248488
|
+
}
|
|
248489
|
+
this._storedFields.delete(shortId);
|
|
248490
|
+
this._documentIds.delete(shortId);
|
|
248491
|
+
this._idToShortId.delete(id);
|
|
248492
|
+
this._fieldLength.delete(shortId);
|
|
248493
|
+
this._documentCount -= 1;
|
|
248494
|
+
}
|
|
248495
|
+
removeAll(documents) {
|
|
248496
|
+
if (documents) {
|
|
248497
|
+
for (const document2 of documents)
|
|
248498
|
+
this.remove(document2);
|
|
248499
|
+
} else if (arguments.length > 0) {
|
|
248500
|
+
throw new Error("Expected documents to be present. Omit the argument to remove all documents.");
|
|
248501
|
+
} else {
|
|
248502
|
+
this._index = new SearchableMap;
|
|
248503
|
+
this._documentCount = 0;
|
|
248504
|
+
this._documentIds = new Map;
|
|
248505
|
+
this._idToShortId = new Map;
|
|
248506
|
+
this._fieldLength = new Map;
|
|
248507
|
+
this._avgFieldLength = [];
|
|
248508
|
+
this._storedFields = new Map;
|
|
248509
|
+
this._nextId = 0;
|
|
248510
|
+
}
|
|
248511
|
+
}
|
|
248512
|
+
discard(id) {
|
|
248513
|
+
const shortId = this._idToShortId.get(id);
|
|
248514
|
+
if (shortId == null) {
|
|
248515
|
+
throw new Error(`MiniSearch: cannot discard document with ID ${id}: it is not in the index`);
|
|
248516
|
+
}
|
|
248517
|
+
this._idToShortId.delete(id);
|
|
248518
|
+
this._documentIds.delete(shortId);
|
|
248519
|
+
this._storedFields.delete(shortId);
|
|
248520
|
+
(this._fieldLength.get(shortId) || []).forEach((fieldLength, fieldId) => {
|
|
248521
|
+
this.removeFieldLength(shortId, fieldId, this._documentCount, fieldLength);
|
|
248522
|
+
});
|
|
248523
|
+
this._fieldLength.delete(shortId);
|
|
248524
|
+
this._documentCount -= 1;
|
|
248525
|
+
this._dirtCount += 1;
|
|
248526
|
+
this.maybeAutoVacuum();
|
|
248527
|
+
}
|
|
248528
|
+
maybeAutoVacuum() {
|
|
248529
|
+
if (this._options.autoVacuum === false) {
|
|
248530
|
+
return;
|
|
248531
|
+
}
|
|
248532
|
+
const { minDirtFactor, minDirtCount, batchSize, batchWait } = this._options.autoVacuum;
|
|
248533
|
+
this.conditionalVacuum({ batchSize, batchWait }, { minDirtCount, minDirtFactor });
|
|
248534
|
+
}
|
|
248535
|
+
discardAll(ids) {
|
|
248536
|
+
const autoVacuum = this._options.autoVacuum;
|
|
248537
|
+
try {
|
|
248538
|
+
this._options.autoVacuum = false;
|
|
248539
|
+
for (const id of ids) {
|
|
248540
|
+
this.discard(id);
|
|
248541
|
+
}
|
|
248542
|
+
} finally {
|
|
248543
|
+
this._options.autoVacuum = autoVacuum;
|
|
248544
|
+
}
|
|
248545
|
+
this.maybeAutoVacuum();
|
|
248546
|
+
}
|
|
248547
|
+
replace(updatedDocument) {
|
|
248548
|
+
const { idField, extractField } = this._options;
|
|
248549
|
+
const id = extractField(updatedDocument, idField);
|
|
248550
|
+
this.discard(id);
|
|
248551
|
+
this.add(updatedDocument);
|
|
248552
|
+
}
|
|
248553
|
+
vacuum(options = {}) {
|
|
248554
|
+
return this.conditionalVacuum(options);
|
|
248555
|
+
}
|
|
248556
|
+
conditionalVacuum(options, conditions) {
|
|
248557
|
+
if (this._currentVacuum) {
|
|
248558
|
+
this._enqueuedVacuumConditions = this._enqueuedVacuumConditions && conditions;
|
|
248559
|
+
if (this._enqueuedVacuum != null) {
|
|
248560
|
+
return this._enqueuedVacuum;
|
|
248561
|
+
}
|
|
248562
|
+
this._enqueuedVacuum = this._currentVacuum.then(() => {
|
|
248563
|
+
const conditions = this._enqueuedVacuumConditions;
|
|
248564
|
+
this._enqueuedVacuumConditions = defaultVacuumConditions;
|
|
248565
|
+
return this.performVacuuming(options, conditions);
|
|
248566
|
+
});
|
|
248567
|
+
return this._enqueuedVacuum;
|
|
248568
|
+
}
|
|
248569
|
+
if (this.vacuumConditionsMet(conditions) === false) {
|
|
248570
|
+
return Promise.resolve();
|
|
248571
|
+
}
|
|
248572
|
+
this._currentVacuum = this.performVacuuming(options);
|
|
248573
|
+
return this._currentVacuum;
|
|
248574
|
+
}
|
|
248575
|
+
async performVacuuming(options, conditions) {
|
|
248576
|
+
const initialDirtCount = this._dirtCount;
|
|
248577
|
+
if (this.vacuumConditionsMet(conditions)) {
|
|
248578
|
+
const batchSize = options.batchSize || defaultVacuumOptions.batchSize;
|
|
248579
|
+
const batchWait = options.batchWait || defaultVacuumOptions.batchWait;
|
|
248580
|
+
let i = 1;
|
|
248581
|
+
for (const [term, fieldsData] of this._index) {
|
|
248582
|
+
for (const [fieldId, fieldIndex] of fieldsData) {
|
|
248583
|
+
for (const [shortId] of fieldIndex) {
|
|
248584
|
+
if (this._documentIds.has(shortId)) {
|
|
248585
|
+
continue;
|
|
248586
|
+
}
|
|
248587
|
+
if (fieldIndex.size <= 1) {
|
|
248588
|
+
fieldsData.delete(fieldId);
|
|
248589
|
+
} else {
|
|
248590
|
+
fieldIndex.delete(shortId);
|
|
248591
|
+
}
|
|
248592
|
+
}
|
|
248593
|
+
}
|
|
248594
|
+
if (this._index.get(term).size === 0) {
|
|
248595
|
+
this._index.delete(term);
|
|
248596
|
+
}
|
|
248597
|
+
if (i % batchSize === 0) {
|
|
248598
|
+
await new Promise((resolve) => setTimeout(resolve, batchWait));
|
|
248599
|
+
}
|
|
248600
|
+
i += 1;
|
|
248601
|
+
}
|
|
248602
|
+
this._dirtCount -= initialDirtCount;
|
|
248603
|
+
}
|
|
248604
|
+
await null;
|
|
248605
|
+
this._currentVacuum = this._enqueuedVacuum;
|
|
248606
|
+
this._enqueuedVacuum = null;
|
|
248607
|
+
}
|
|
248608
|
+
vacuumConditionsMet(conditions) {
|
|
248609
|
+
if (conditions == null) {
|
|
248610
|
+
return true;
|
|
248611
|
+
}
|
|
248612
|
+
let { minDirtCount, minDirtFactor } = conditions;
|
|
248613
|
+
minDirtCount = minDirtCount || defaultAutoVacuumOptions.minDirtCount;
|
|
248614
|
+
minDirtFactor = minDirtFactor || defaultAutoVacuumOptions.minDirtFactor;
|
|
248615
|
+
return this.dirtCount >= minDirtCount && this.dirtFactor >= minDirtFactor;
|
|
248616
|
+
}
|
|
248617
|
+
get isVacuuming() {
|
|
248618
|
+
return this._currentVacuum != null;
|
|
248619
|
+
}
|
|
248620
|
+
get dirtCount() {
|
|
248621
|
+
return this._dirtCount;
|
|
248622
|
+
}
|
|
248623
|
+
get dirtFactor() {
|
|
248624
|
+
return this._dirtCount / (1 + this._documentCount + this._dirtCount);
|
|
248625
|
+
}
|
|
248626
|
+
has(id) {
|
|
248627
|
+
return this._idToShortId.has(id);
|
|
248628
|
+
}
|
|
248629
|
+
getStoredFields(id) {
|
|
248630
|
+
const shortId = this._idToShortId.get(id);
|
|
248631
|
+
if (shortId == null) {
|
|
248632
|
+
return;
|
|
248633
|
+
}
|
|
248634
|
+
return this._storedFields.get(shortId);
|
|
248635
|
+
}
|
|
248636
|
+
search(query, searchOptions = {}) {
|
|
248637
|
+
const { searchOptions: globalSearchOptions } = this._options;
|
|
248638
|
+
const searchOptionsWithDefaults = { ...globalSearchOptions, ...searchOptions };
|
|
248639
|
+
const rawResults = this.executeQuery(query, searchOptions);
|
|
248640
|
+
const results = [];
|
|
248641
|
+
for (const [docId, { score, terms, match }] of rawResults) {
|
|
248642
|
+
const quality = terms.length || 1;
|
|
248643
|
+
const result = {
|
|
248644
|
+
id: this._documentIds.get(docId),
|
|
248645
|
+
score: score * quality,
|
|
248646
|
+
terms: Object.keys(match),
|
|
248647
|
+
queryTerms: terms,
|
|
248648
|
+
match
|
|
248649
|
+
};
|
|
248650
|
+
Object.assign(result, this._storedFields.get(docId));
|
|
248651
|
+
if (searchOptionsWithDefaults.filter == null || searchOptionsWithDefaults.filter(result)) {
|
|
248652
|
+
results.push(result);
|
|
248653
|
+
}
|
|
248654
|
+
}
|
|
248655
|
+
if (query === MiniSearch.wildcard && searchOptionsWithDefaults.boostDocument == null) {
|
|
248656
|
+
return results;
|
|
248657
|
+
}
|
|
248658
|
+
results.sort(byScore);
|
|
248659
|
+
return results;
|
|
248660
|
+
}
|
|
248661
|
+
autoSuggest(queryString, options = {}) {
|
|
248662
|
+
options = { ...this._options.autoSuggestOptions, ...options };
|
|
248663
|
+
const suggestions = new Map;
|
|
248664
|
+
for (const { score, terms } of this.search(queryString, options)) {
|
|
248665
|
+
const phrase = terms.join(" ");
|
|
248666
|
+
const suggestion = suggestions.get(phrase);
|
|
248667
|
+
if (suggestion != null) {
|
|
248668
|
+
suggestion.score += score;
|
|
248669
|
+
suggestion.count += 1;
|
|
248670
|
+
} else {
|
|
248671
|
+
suggestions.set(phrase, { score, terms, count: 1 });
|
|
248672
|
+
}
|
|
248673
|
+
}
|
|
248674
|
+
const results = [];
|
|
248675
|
+
for (const [suggestion, { score, terms, count }] of suggestions) {
|
|
248676
|
+
results.push({ suggestion, terms, score: score / count });
|
|
248677
|
+
}
|
|
248678
|
+
results.sort(byScore);
|
|
248679
|
+
return results;
|
|
248680
|
+
}
|
|
248681
|
+
get documentCount() {
|
|
248682
|
+
return this._documentCount;
|
|
248683
|
+
}
|
|
248684
|
+
get termCount() {
|
|
248685
|
+
return this._index.size;
|
|
248686
|
+
}
|
|
248687
|
+
static loadJSON(json, options) {
|
|
248688
|
+
if (options == null) {
|
|
248689
|
+
throw new Error("MiniSearch: loadJSON should be given the same options used when serializing the index");
|
|
248690
|
+
}
|
|
248691
|
+
return this.loadJS(JSON.parse(json), options);
|
|
248692
|
+
}
|
|
248693
|
+
static async loadJSONAsync(json, options) {
|
|
248694
|
+
if (options == null) {
|
|
248695
|
+
throw new Error("MiniSearch: loadJSON should be given the same options used when serializing the index");
|
|
248696
|
+
}
|
|
248697
|
+
return this.loadJSAsync(JSON.parse(json), options);
|
|
248698
|
+
}
|
|
248699
|
+
static getDefault(optionName) {
|
|
248700
|
+
if (defaultOptions.hasOwnProperty(optionName)) {
|
|
248701
|
+
return getOwnProperty(defaultOptions, optionName);
|
|
248702
|
+
} else {
|
|
248703
|
+
throw new Error(`MiniSearch: unknown option "${optionName}"`);
|
|
248704
|
+
}
|
|
248705
|
+
}
|
|
248706
|
+
static loadJS(js, options) {
|
|
248707
|
+
const { index, documentIds, fieldLength, storedFields, serializationVersion } = js;
|
|
248708
|
+
const miniSearch = this.instantiateMiniSearch(js, options);
|
|
248709
|
+
miniSearch._documentIds = objectToNumericMap(documentIds);
|
|
248710
|
+
miniSearch._fieldLength = objectToNumericMap(fieldLength);
|
|
248711
|
+
miniSearch._storedFields = objectToNumericMap(storedFields);
|
|
248712
|
+
for (const [shortId, id] of miniSearch._documentIds) {
|
|
248713
|
+
miniSearch._idToShortId.set(id, shortId);
|
|
248714
|
+
}
|
|
248715
|
+
for (const [term, data] of index) {
|
|
248716
|
+
const dataMap = new Map;
|
|
248717
|
+
for (const fieldId of Object.keys(data)) {
|
|
248718
|
+
let indexEntry = data[fieldId];
|
|
248719
|
+
if (serializationVersion === 1) {
|
|
248720
|
+
indexEntry = indexEntry.ds;
|
|
248721
|
+
}
|
|
248722
|
+
dataMap.set(parseInt(fieldId, 10), objectToNumericMap(indexEntry));
|
|
248723
|
+
}
|
|
248724
|
+
miniSearch._index.set(term, dataMap);
|
|
248725
|
+
}
|
|
248726
|
+
return miniSearch;
|
|
248727
|
+
}
|
|
248728
|
+
static async loadJSAsync(js, options) {
|
|
248729
|
+
const { index, documentIds, fieldLength, storedFields, serializationVersion } = js;
|
|
248730
|
+
const miniSearch = this.instantiateMiniSearch(js, options);
|
|
248731
|
+
miniSearch._documentIds = await objectToNumericMapAsync(documentIds);
|
|
248732
|
+
miniSearch._fieldLength = await objectToNumericMapAsync(fieldLength);
|
|
248733
|
+
miniSearch._storedFields = await objectToNumericMapAsync(storedFields);
|
|
248734
|
+
for (const [shortId, id] of miniSearch._documentIds) {
|
|
248735
|
+
miniSearch._idToShortId.set(id, shortId);
|
|
248736
|
+
}
|
|
248737
|
+
let count = 0;
|
|
248738
|
+
for (const [term, data] of index) {
|
|
248739
|
+
const dataMap = new Map;
|
|
248740
|
+
for (const fieldId of Object.keys(data)) {
|
|
248741
|
+
let indexEntry = data[fieldId];
|
|
248742
|
+
if (serializationVersion === 1) {
|
|
248743
|
+
indexEntry = indexEntry.ds;
|
|
248744
|
+
}
|
|
248745
|
+
dataMap.set(parseInt(fieldId, 10), await objectToNumericMapAsync(indexEntry));
|
|
248746
|
+
}
|
|
248747
|
+
if (++count % 1000 === 0)
|
|
248748
|
+
await wait(0);
|
|
248749
|
+
miniSearch._index.set(term, dataMap);
|
|
248750
|
+
}
|
|
248751
|
+
return miniSearch;
|
|
248752
|
+
}
|
|
248753
|
+
static instantiateMiniSearch(js, options) {
|
|
248754
|
+
const { documentCount, nextId, fieldIds, averageFieldLength, dirtCount, serializationVersion } = js;
|
|
248755
|
+
if (serializationVersion !== 1 && serializationVersion !== 2) {
|
|
248756
|
+
throw new Error("MiniSearch: cannot deserialize an index created with an incompatible version");
|
|
248757
|
+
}
|
|
248758
|
+
const miniSearch = new MiniSearch(options);
|
|
248759
|
+
miniSearch._documentCount = documentCount;
|
|
248760
|
+
miniSearch._nextId = nextId;
|
|
248761
|
+
miniSearch._idToShortId = new Map;
|
|
248762
|
+
miniSearch._fieldIds = fieldIds;
|
|
248763
|
+
miniSearch._avgFieldLength = averageFieldLength;
|
|
248764
|
+
miniSearch._dirtCount = dirtCount || 0;
|
|
248765
|
+
miniSearch._index = new SearchableMap;
|
|
248766
|
+
return miniSearch;
|
|
248767
|
+
}
|
|
248768
|
+
executeQuery(query, searchOptions = {}) {
|
|
248769
|
+
if (query === MiniSearch.wildcard) {
|
|
248770
|
+
return this.executeWildcardQuery(searchOptions);
|
|
248771
|
+
}
|
|
248772
|
+
if (typeof query !== "string") {
|
|
248773
|
+
const options = { ...searchOptions, ...query, queries: undefined };
|
|
248774
|
+
const results = query.queries.map((subquery) => this.executeQuery(subquery, options));
|
|
248775
|
+
return this.combineResults(results, options.combineWith);
|
|
248776
|
+
}
|
|
248777
|
+
const { tokenize, processTerm, searchOptions: globalSearchOptions } = this._options;
|
|
248778
|
+
const options = { tokenize, processTerm, ...globalSearchOptions, ...searchOptions };
|
|
248779
|
+
const { tokenize: searchTokenize, processTerm: searchProcessTerm } = options;
|
|
248780
|
+
const terms = searchTokenize(query).flatMap((term) => searchProcessTerm(term)).filter((term) => !!term);
|
|
248781
|
+
const queries = terms.map(termToQuerySpec(options));
|
|
248782
|
+
const results = queries.map((query) => this.executeQuerySpec(query, options));
|
|
248783
|
+
return this.combineResults(results, options.combineWith);
|
|
248784
|
+
}
|
|
248785
|
+
executeQuerySpec(query, searchOptions) {
|
|
248786
|
+
const options = { ...this._options.searchOptions, ...searchOptions };
|
|
248787
|
+
const boosts = (options.fields || this._options.fields).reduce((boosts, field) => ({ ...boosts, [field]: getOwnProperty(options.boost, field) || 1 }), {});
|
|
248788
|
+
const { boostDocument, weights, maxFuzzy, bm25: bm25params } = options;
|
|
248789
|
+
const { fuzzy: fuzzyWeight, prefix: prefixWeight } = { ...defaultSearchOptions.weights, ...weights };
|
|
248790
|
+
const data = this._index.get(query.term);
|
|
248791
|
+
const results = this.termResults(query.term, query.term, 1, query.termBoost, data, boosts, boostDocument, bm25params);
|
|
248792
|
+
let prefixMatches;
|
|
248793
|
+
let fuzzyMatches;
|
|
248794
|
+
if (query.prefix) {
|
|
248795
|
+
prefixMatches = this._index.atPrefix(query.term);
|
|
248796
|
+
}
|
|
248797
|
+
if (query.fuzzy) {
|
|
248798
|
+
const fuzzy = query.fuzzy === true ? 0.2 : query.fuzzy;
|
|
248799
|
+
const maxDistance = fuzzy < 1 ? Math.min(maxFuzzy, Math.round(query.term.length * fuzzy)) : fuzzy;
|
|
248800
|
+
if (maxDistance)
|
|
248801
|
+
fuzzyMatches = this._index.fuzzyGet(query.term, maxDistance);
|
|
248802
|
+
}
|
|
248803
|
+
if (prefixMatches) {
|
|
248804
|
+
for (const [term, data] of prefixMatches) {
|
|
248805
|
+
const distance = term.length - query.term.length;
|
|
248806
|
+
if (!distance) {
|
|
248807
|
+
continue;
|
|
248808
|
+
}
|
|
248809
|
+
fuzzyMatches === null || fuzzyMatches === undefined || fuzzyMatches.delete(term);
|
|
248810
|
+
const weight = prefixWeight * term.length / (term.length + 0.3 * distance);
|
|
248811
|
+
this.termResults(query.term, term, weight, query.termBoost, data, boosts, boostDocument, bm25params, results);
|
|
248812
|
+
}
|
|
248813
|
+
}
|
|
248814
|
+
if (fuzzyMatches) {
|
|
248815
|
+
for (const term of fuzzyMatches.keys()) {
|
|
248816
|
+
const [data, distance] = fuzzyMatches.get(term);
|
|
248817
|
+
if (!distance) {
|
|
248818
|
+
continue;
|
|
248819
|
+
}
|
|
248820
|
+
const weight = fuzzyWeight * term.length / (term.length + distance);
|
|
248821
|
+
this.termResults(query.term, term, weight, query.termBoost, data, boosts, boostDocument, bm25params, results);
|
|
248822
|
+
}
|
|
248823
|
+
}
|
|
248824
|
+
return results;
|
|
248825
|
+
}
|
|
248826
|
+
executeWildcardQuery(searchOptions) {
|
|
248827
|
+
const results = new Map;
|
|
248828
|
+
const options = { ...this._options.searchOptions, ...searchOptions };
|
|
248829
|
+
for (const [shortId, id] of this._documentIds) {
|
|
248830
|
+
const score = options.boostDocument ? options.boostDocument(id, "", this._storedFields.get(shortId)) : 1;
|
|
248831
|
+
results.set(shortId, {
|
|
248832
|
+
score,
|
|
248833
|
+
terms: [],
|
|
248834
|
+
match: {}
|
|
248835
|
+
});
|
|
248836
|
+
}
|
|
248837
|
+
return results;
|
|
248838
|
+
}
|
|
248839
|
+
combineResults(results, combineWith = OR) {
|
|
248840
|
+
if (results.length === 0) {
|
|
248841
|
+
return new Map;
|
|
248842
|
+
}
|
|
248843
|
+
const operator = combineWith.toLowerCase();
|
|
248844
|
+
const combinator = combinators[operator];
|
|
248845
|
+
if (!combinator) {
|
|
248846
|
+
throw new Error(`Invalid combination operator: ${combineWith}`);
|
|
248847
|
+
}
|
|
248848
|
+
return results.reduce(combinator) || new Map;
|
|
248849
|
+
}
|
|
248850
|
+
toJSON() {
|
|
248851
|
+
const index = [];
|
|
248852
|
+
for (const [term, fieldIndex] of this._index) {
|
|
248853
|
+
const data = {};
|
|
248854
|
+
for (const [fieldId, freqs] of fieldIndex) {
|
|
248855
|
+
data[fieldId] = Object.fromEntries(freqs);
|
|
248856
|
+
}
|
|
248857
|
+
index.push([term, data]);
|
|
248858
|
+
}
|
|
248859
|
+
return {
|
|
248860
|
+
documentCount: this._documentCount,
|
|
248861
|
+
nextId: this._nextId,
|
|
248862
|
+
documentIds: Object.fromEntries(this._documentIds),
|
|
248863
|
+
fieldIds: this._fieldIds,
|
|
248864
|
+
fieldLength: Object.fromEntries(this._fieldLength),
|
|
248865
|
+
averageFieldLength: this._avgFieldLength,
|
|
248866
|
+
storedFields: Object.fromEntries(this._storedFields),
|
|
248867
|
+
dirtCount: this._dirtCount,
|
|
248868
|
+
index,
|
|
248869
|
+
serializationVersion: 2
|
|
248870
|
+
};
|
|
248871
|
+
}
|
|
248872
|
+
termResults(sourceTerm, derivedTerm, termWeight, termBoost, fieldTermData, fieldBoosts, boostDocumentFn, bm25params, results = new Map) {
|
|
248873
|
+
if (fieldTermData == null)
|
|
248874
|
+
return results;
|
|
248875
|
+
for (const field of Object.keys(fieldBoosts)) {
|
|
248876
|
+
const fieldBoost = fieldBoosts[field];
|
|
248877
|
+
const fieldId = this._fieldIds[field];
|
|
248878
|
+
const fieldTermFreqs = fieldTermData.get(fieldId);
|
|
248879
|
+
if (fieldTermFreqs == null)
|
|
248880
|
+
continue;
|
|
248881
|
+
let matchingFields = fieldTermFreqs.size;
|
|
248882
|
+
const avgFieldLength = this._avgFieldLength[fieldId];
|
|
248883
|
+
for (const docId of fieldTermFreqs.keys()) {
|
|
248884
|
+
if (!this._documentIds.has(docId)) {
|
|
248885
|
+
this.removeTerm(fieldId, docId, derivedTerm);
|
|
248886
|
+
matchingFields -= 1;
|
|
248887
|
+
continue;
|
|
248888
|
+
}
|
|
248889
|
+
const docBoost = boostDocumentFn ? boostDocumentFn(this._documentIds.get(docId), derivedTerm, this._storedFields.get(docId)) : 1;
|
|
248890
|
+
if (!docBoost)
|
|
248891
|
+
continue;
|
|
248892
|
+
const termFreq = fieldTermFreqs.get(docId);
|
|
248893
|
+
const fieldLength = this._fieldLength.get(docId)[fieldId];
|
|
248894
|
+
const rawScore = calcBM25Score(termFreq, matchingFields, this._documentCount, fieldLength, avgFieldLength, bm25params);
|
|
248895
|
+
const weightedScore = termWeight * termBoost * fieldBoost * docBoost * rawScore;
|
|
248896
|
+
const result = results.get(docId);
|
|
248897
|
+
if (result) {
|
|
248898
|
+
result.score += weightedScore;
|
|
248899
|
+
assignUniqueTerm(result.terms, sourceTerm);
|
|
248900
|
+
const match = getOwnProperty(result.match, derivedTerm);
|
|
248901
|
+
if (match) {
|
|
248902
|
+
match.push(field);
|
|
248903
|
+
} else {
|
|
248904
|
+
result.match[derivedTerm] = [field];
|
|
248905
|
+
}
|
|
248906
|
+
} else {
|
|
248907
|
+
results.set(docId, {
|
|
248908
|
+
score: weightedScore,
|
|
248909
|
+
terms: [sourceTerm],
|
|
248910
|
+
match: { [derivedTerm]: [field] }
|
|
248911
|
+
});
|
|
248912
|
+
}
|
|
248913
|
+
}
|
|
248914
|
+
}
|
|
248915
|
+
return results;
|
|
248916
|
+
}
|
|
248917
|
+
addTerm(fieldId, documentId, term) {
|
|
248918
|
+
const indexData = this._index.fetch(term, createMap);
|
|
248919
|
+
let fieldIndex = indexData.get(fieldId);
|
|
248920
|
+
if (fieldIndex == null) {
|
|
248921
|
+
fieldIndex = new Map;
|
|
248922
|
+
fieldIndex.set(documentId, 1);
|
|
248923
|
+
indexData.set(fieldId, fieldIndex);
|
|
248924
|
+
} else {
|
|
248925
|
+
const docs = fieldIndex.get(documentId);
|
|
248926
|
+
fieldIndex.set(documentId, (docs || 0) + 1);
|
|
248927
|
+
}
|
|
248928
|
+
}
|
|
248929
|
+
removeTerm(fieldId, documentId, term) {
|
|
248930
|
+
if (!this._index.has(term)) {
|
|
248931
|
+
this.warnDocumentChanged(documentId, fieldId, term);
|
|
248932
|
+
return;
|
|
248933
|
+
}
|
|
248934
|
+
const indexData = this._index.fetch(term, createMap);
|
|
248935
|
+
const fieldIndex = indexData.get(fieldId);
|
|
248936
|
+
if (fieldIndex == null || fieldIndex.get(documentId) == null) {
|
|
248937
|
+
this.warnDocumentChanged(documentId, fieldId, term);
|
|
248938
|
+
} else if (fieldIndex.get(documentId) <= 1) {
|
|
248939
|
+
if (fieldIndex.size <= 1) {
|
|
248940
|
+
indexData.delete(fieldId);
|
|
248941
|
+
} else {
|
|
248942
|
+
fieldIndex.delete(documentId);
|
|
248943
|
+
}
|
|
248944
|
+
} else {
|
|
248945
|
+
fieldIndex.set(documentId, fieldIndex.get(documentId) - 1);
|
|
248946
|
+
}
|
|
248947
|
+
if (this._index.get(term).size === 0) {
|
|
248948
|
+
this._index.delete(term);
|
|
248949
|
+
}
|
|
248950
|
+
}
|
|
248951
|
+
warnDocumentChanged(shortDocumentId, fieldId, term) {
|
|
248952
|
+
for (const fieldName of Object.keys(this._fieldIds)) {
|
|
248953
|
+
if (this._fieldIds[fieldName] === fieldId) {
|
|
248954
|
+
this._options.logger("warn", `MiniSearch: document with ID ${this._documentIds.get(shortDocumentId)} has changed before removal: term "${term}" was not present in field "${fieldName}". Removing a document after it has changed can corrupt the index!`, "version_conflict");
|
|
248955
|
+
return;
|
|
248956
|
+
}
|
|
248957
|
+
}
|
|
248958
|
+
}
|
|
248959
|
+
addDocumentId(documentId) {
|
|
248960
|
+
const shortDocumentId = this._nextId;
|
|
248961
|
+
this._idToShortId.set(documentId, shortDocumentId);
|
|
248962
|
+
this._documentIds.set(shortDocumentId, documentId);
|
|
248963
|
+
this._documentCount += 1;
|
|
248964
|
+
this._nextId += 1;
|
|
248965
|
+
return shortDocumentId;
|
|
248966
|
+
}
|
|
248967
|
+
addFields(fields) {
|
|
248968
|
+
for (let i = 0;i < fields.length; i++) {
|
|
248969
|
+
this._fieldIds[fields[i]] = i;
|
|
248970
|
+
}
|
|
248971
|
+
}
|
|
248972
|
+
addFieldLength(documentId, fieldId, count, length) {
|
|
248973
|
+
let fieldLengths = this._fieldLength.get(documentId);
|
|
248974
|
+
if (fieldLengths == null)
|
|
248975
|
+
this._fieldLength.set(documentId, fieldLengths = []);
|
|
248976
|
+
fieldLengths[fieldId] = length;
|
|
248977
|
+
const averageFieldLength = this._avgFieldLength[fieldId] || 0;
|
|
248978
|
+
const totalFieldLength = averageFieldLength * count + length;
|
|
248979
|
+
this._avgFieldLength[fieldId] = totalFieldLength / (count + 1);
|
|
248980
|
+
}
|
|
248981
|
+
removeFieldLength(documentId, fieldId, count, length) {
|
|
248982
|
+
if (count === 1) {
|
|
248983
|
+
this._avgFieldLength[fieldId] = 0;
|
|
248984
|
+
return;
|
|
248985
|
+
}
|
|
248986
|
+
const totalFieldLength = this._avgFieldLength[fieldId] * count - length;
|
|
248987
|
+
this._avgFieldLength[fieldId] = totalFieldLength / (count - 1);
|
|
248988
|
+
}
|
|
248989
|
+
saveStoredFields(documentId, doc) {
|
|
248990
|
+
const { storeFields, extractField } = this._options;
|
|
248991
|
+
if (storeFields == null || storeFields.length === 0) {
|
|
248992
|
+
return;
|
|
248993
|
+
}
|
|
248994
|
+
let documentFields = this._storedFields.get(documentId);
|
|
248995
|
+
if (documentFields == null)
|
|
248996
|
+
this._storedFields.set(documentId, documentFields = {});
|
|
248997
|
+
for (const fieldName of storeFields) {
|
|
248998
|
+
const fieldValue = extractField(doc, fieldName);
|
|
248999
|
+
if (fieldValue !== undefined)
|
|
249000
|
+
documentFields[fieldName] = fieldValue;
|
|
249001
|
+
}
|
|
249002
|
+
}
|
|
249003
|
+
}
|
|
249004
|
+
MiniSearch.wildcard = Symbol("*");
|
|
249005
|
+
var getOwnProperty = (object, property) => Object.prototype.hasOwnProperty.call(object, property) ? object[property] : undefined;
|
|
249006
|
+
var combinators = {
|
|
249007
|
+
[OR]: (a, b) => {
|
|
249008
|
+
for (const docId of b.keys()) {
|
|
249009
|
+
const existing = a.get(docId);
|
|
249010
|
+
if (existing == null) {
|
|
249011
|
+
a.set(docId, b.get(docId));
|
|
249012
|
+
} else {
|
|
249013
|
+
const { score, terms, match } = b.get(docId);
|
|
249014
|
+
existing.score = existing.score + score;
|
|
249015
|
+
existing.match = Object.assign(existing.match, match);
|
|
249016
|
+
assignUniqueTerms(existing.terms, terms);
|
|
249017
|
+
}
|
|
249018
|
+
}
|
|
249019
|
+
return a;
|
|
249020
|
+
},
|
|
249021
|
+
[AND]: (a, b) => {
|
|
249022
|
+
const combined = new Map;
|
|
249023
|
+
for (const docId of b.keys()) {
|
|
249024
|
+
const existing = a.get(docId);
|
|
249025
|
+
if (existing == null)
|
|
249026
|
+
continue;
|
|
249027
|
+
const { score, terms, match } = b.get(docId);
|
|
249028
|
+
assignUniqueTerms(existing.terms, terms);
|
|
249029
|
+
combined.set(docId, {
|
|
249030
|
+
score: existing.score + score,
|
|
249031
|
+
terms: existing.terms,
|
|
249032
|
+
match: Object.assign(existing.match, match)
|
|
249033
|
+
});
|
|
249034
|
+
}
|
|
249035
|
+
return combined;
|
|
249036
|
+
},
|
|
249037
|
+
[AND_NOT]: (a, b) => {
|
|
249038
|
+
for (const docId of b.keys())
|
|
249039
|
+
a.delete(docId);
|
|
249040
|
+
return a;
|
|
249041
|
+
}
|
|
249042
|
+
};
|
|
249043
|
+
var defaultBM25params = { k: 1.2, b: 0.7, d: 0.5 };
|
|
249044
|
+
var calcBM25Score = (termFreq, matchingCount, totalCount, fieldLength, avgFieldLength, bm25params) => {
|
|
249045
|
+
const { k, b, d } = bm25params;
|
|
249046
|
+
const invDocFreq = Math.log(1 + (totalCount - matchingCount + 0.5) / (matchingCount + 0.5));
|
|
249047
|
+
return invDocFreq * (d + termFreq * (k + 1) / (termFreq + k * (1 - b + b * fieldLength / avgFieldLength)));
|
|
249048
|
+
};
|
|
249049
|
+
var termToQuerySpec = (options) => (term, i, terms) => {
|
|
249050
|
+
const fuzzy = typeof options.fuzzy === "function" ? options.fuzzy(term, i, terms) : options.fuzzy || false;
|
|
249051
|
+
const prefix = typeof options.prefix === "function" ? options.prefix(term, i, terms) : options.prefix === true;
|
|
249052
|
+
const termBoost = typeof options.boostTerm === "function" ? options.boostTerm(term, i, terms) : 1;
|
|
249053
|
+
return { term, fuzzy, prefix, termBoost };
|
|
249054
|
+
};
|
|
249055
|
+
var defaultOptions = {
|
|
249056
|
+
idField: "id",
|
|
249057
|
+
extractField: (document2, fieldName) => document2[fieldName],
|
|
249058
|
+
tokenize: (text) => text.split(SPACE_OR_PUNCTUATION),
|
|
249059
|
+
processTerm: (term) => term.toLowerCase(),
|
|
249060
|
+
fields: undefined,
|
|
249061
|
+
searchOptions: undefined,
|
|
249062
|
+
storeFields: [],
|
|
249063
|
+
logger: (level, message) => {
|
|
249064
|
+
if (typeof (console === null || console === undefined ? undefined : console[level]) === "function")
|
|
249065
|
+
console[level](message);
|
|
249066
|
+
},
|
|
249067
|
+
autoVacuum: true
|
|
249068
|
+
};
|
|
249069
|
+
var defaultSearchOptions = {
|
|
249070
|
+
combineWith: OR,
|
|
249071
|
+
prefix: false,
|
|
249072
|
+
fuzzy: false,
|
|
249073
|
+
maxFuzzy: 6,
|
|
249074
|
+
boost: {},
|
|
249075
|
+
weights: { fuzzy: 0.45, prefix: 0.375 },
|
|
249076
|
+
bm25: defaultBM25params
|
|
249077
|
+
};
|
|
249078
|
+
var defaultAutoSuggestOptions = {
|
|
249079
|
+
combineWith: AND,
|
|
249080
|
+
prefix: (term, i, terms) => i === terms.length - 1
|
|
249081
|
+
};
|
|
249082
|
+
var defaultVacuumOptions = { batchSize: 1000, batchWait: 10 };
|
|
249083
|
+
var defaultVacuumConditions = { minDirtFactor: 0.1, minDirtCount: 20 };
|
|
249084
|
+
var defaultAutoVacuumOptions = { ...defaultVacuumOptions, ...defaultVacuumConditions };
|
|
249085
|
+
var assignUniqueTerm = (target, term) => {
|
|
249086
|
+
if (!target.includes(term))
|
|
249087
|
+
target.push(term);
|
|
249088
|
+
};
|
|
249089
|
+
var assignUniqueTerms = (target, source) => {
|
|
249090
|
+
for (const term of source) {
|
|
249091
|
+
if (!target.includes(term))
|
|
249092
|
+
target.push(term);
|
|
249093
|
+
}
|
|
249094
|
+
};
|
|
249095
|
+
var byScore = ({ score: a }, { score: b }) => b - a;
|
|
249096
|
+
var createMap = () => new Map;
|
|
249097
|
+
var objectToNumericMap = (object) => {
|
|
249098
|
+
const map = new Map;
|
|
249099
|
+
for (const key of Object.keys(object)) {
|
|
249100
|
+
map.set(parseInt(key, 10), object[key]);
|
|
249101
|
+
}
|
|
249102
|
+
return map;
|
|
249103
|
+
};
|
|
249104
|
+
var objectToNumericMapAsync = async (object) => {
|
|
249105
|
+
const map = new Map;
|
|
249106
|
+
let count = 0;
|
|
249107
|
+
for (const key of Object.keys(object)) {
|
|
249108
|
+
map.set(parseInt(key, 10), object[key]);
|
|
249109
|
+
if (++count % 1000 === 0) {
|
|
249110
|
+
await wait(0);
|
|
249111
|
+
}
|
|
249112
|
+
}
|
|
249113
|
+
return map;
|
|
249114
|
+
};
|
|
249115
|
+
var wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
249116
|
+
var SPACE_OR_PUNCTUATION = /[\n\r\p{Z}\p{P}]+/u;
|
|
249117
|
+
|
|
249118
|
+
// src/core/api-spec/search.ts
|
|
249119
|
+
var BOOST = {
|
|
249120
|
+
method: 1,
|
|
249121
|
+
path: 8,
|
|
249122
|
+
summary: 5,
|
|
249123
|
+
description: 2,
|
|
249124
|
+
parameters: 0.5
|
|
249125
|
+
};
|
|
249126
|
+
var MIN_RELATIVE_SCORE = 0.2;
|
|
249127
|
+
var TOKEN_SEPARATOR = /[\n\r\p{Z}\p{P}\p{S}]+/u;
|
|
249128
|
+
var STOPWORDS = new Set("a an and are at be by do does for from how i id in is it its me my of on or our that the this to we what who with you your".split(" "));
|
|
249129
|
+
function tokenize(text) {
|
|
249130
|
+
return text.split(TOKEN_SEPARATOR).filter((word) => word.length >= 2 && !STOPWORDS.has(word.toLowerCase()));
|
|
249131
|
+
}
|
|
249132
|
+
function toOperationSummary(op) {
|
|
249133
|
+
return { endpoint: op.endpoint, summary: op.summary };
|
|
249134
|
+
}
|
|
249135
|
+
function buildSearchIndex(operations) {
|
|
249136
|
+
const index = new MiniSearch({
|
|
249137
|
+
fields: ["method", "path", "summary", "description", "parameters"],
|
|
249138
|
+
tokenize
|
|
249139
|
+
});
|
|
249140
|
+
index.addAll(operations.map((op, id) => ({
|
|
249141
|
+
id,
|
|
249142
|
+
method: op.method,
|
|
249143
|
+
path: op.path.replace(/\{[^}]*\}/g, ""),
|
|
249144
|
+
summary: op.summary,
|
|
249145
|
+
description: op.description,
|
|
249146
|
+
parameters: op.parameterText
|
|
249147
|
+
})));
|
|
249148
|
+
return index;
|
|
249149
|
+
}
|
|
249150
|
+
function summaryMatch(terms, op) {
|
|
249151
|
+
const words = tokenize(op?.summary.toLowerCase() ?? "");
|
|
249152
|
+
const named = (word) => terms.some((term) => word.startsWith(term));
|
|
249153
|
+
return {
|
|
249154
|
+
coverage: terms.filter((term) => words.some((word) => word.startsWith(term))).length / terms.length,
|
|
249155
|
+
precision: words.length ? words.filter(named).length / words.length : 0
|
|
249156
|
+
};
|
|
249157
|
+
}
|
|
249158
|
+
var readsFirst = (op) => op?.method === "GET" ? 0 : 1;
|
|
249159
|
+
function searchOperations(operations, query, options = {}) {
|
|
249160
|
+
const terms = tokenize(query.toLowerCase());
|
|
249161
|
+
if (terms.length === 0) {
|
|
249162
|
+
return [];
|
|
249163
|
+
}
|
|
249164
|
+
const index = buildSearchIndex(operations);
|
|
249165
|
+
const hits = index.search(query, {
|
|
249166
|
+
prefix: (term) => term.length >= 3,
|
|
249167
|
+
fuzzy: (term) => term.length >= 4 ? 0.2 : false,
|
|
249168
|
+
boost: BOOST,
|
|
249169
|
+
filter: options.readOnly ? (hit) => operations[hit.id]?.readOnly === true : undefined
|
|
249170
|
+
}).map((hit) => {
|
|
249171
|
+
const match = summaryMatch(terms, operations[hit.id]);
|
|
249172
|
+
return {
|
|
249173
|
+
...hit,
|
|
249174
|
+
...match,
|
|
249175
|
+
full: match.coverage === 1,
|
|
249176
|
+
score: hit.score * (1 + match.coverage)
|
|
249177
|
+
};
|
|
249178
|
+
}).sort((a, b) => Number(b.full) - Number(a.full) || (a.full ? b.precision - a.precision || readsFirst(operations[a.id]) - readsFirst(operations[b.id]) : 0) || b.score - a.score);
|
|
249179
|
+
const baseline = Math.max(0, ...hits.map((hit) => hit.score)) * MIN_RELATIVE_SCORE;
|
|
249180
|
+
return hits.filter((hit) => hit.full || hit.score >= baseline).slice(0, options.limit ?? 5).flatMap((hit) => {
|
|
249181
|
+
const op = operations[hit.id];
|
|
249182
|
+
return op ? [toOperationSummary(op)] : [];
|
|
249183
|
+
});
|
|
249184
|
+
}
|
|
249185
|
+
|
|
249186
|
+
// src/core/api-spec/catalog.ts
|
|
249187
|
+
var INLINE_AREA_MAX = 2;
|
|
249188
|
+
var AREA_SAMPLE_MAX = 3;
|
|
249189
|
+
var AREA_OPERATIONS_MAX = 200;
|
|
249190
|
+
var byCodePoint = (a, b) => a < b ? -1 : a > b ? 1 : 0;
|
|
249191
|
+
function areaOf(path) {
|
|
249192
|
+
const parts = path.split("/").filter(Boolean);
|
|
249193
|
+
const appIdIndex = parts.indexOf("{app_id}");
|
|
249194
|
+
if (appIdIndex !== -1 && appIdIndex + 1 < parts.length) {
|
|
249195
|
+
return parts[appIdIndex + 1] ?? "other";
|
|
249196
|
+
}
|
|
249197
|
+
if (parts[0] === "api" && parts.length > 1) {
|
|
249198
|
+
return parts[1] ?? "other";
|
|
249199
|
+
}
|
|
249200
|
+
return parts[0] ?? "other";
|
|
249201
|
+
}
|
|
249202
|
+
function groupByArea(operations) {
|
|
249203
|
+
const sorted = [...operations].sort((a, b) => byCodePoint(`${a.method} ${a.path}`, `${b.method} ${b.path}`));
|
|
249204
|
+
const areas = new Map;
|
|
249205
|
+
for (const op of sorted) {
|
|
249206
|
+
const area = areaOf(op.path);
|
|
249207
|
+
areas.set(area, [...areas.get(area) ?? [], op]);
|
|
249208
|
+
}
|
|
249209
|
+
return new Map([...areas].sort(([a], [b]) => byCodePoint(a, b)));
|
|
249210
|
+
}
|
|
249211
|
+
function readsFirst2(ops) {
|
|
249212
|
+
const isRead = (op) => op.method === "GET" ? 0 : 1;
|
|
249213
|
+
return [...ops].sort((a, b) => isRead(a) - isRead(b));
|
|
249214
|
+
}
|
|
249215
|
+
function catalogIndex(operations) {
|
|
249216
|
+
const areas = [...groupByArea(operations)].map(([area, ops]) => ops.length <= INLINE_AREA_MAX ? { area, operations: ops.map(toOperationSummary) } : {
|
|
249217
|
+
area,
|
|
249218
|
+
operationCount: ops.length,
|
|
249219
|
+
sample: readsFirst2(ops).slice(0, AREA_SAMPLE_MAX).map((op) => op.summary)
|
|
249220
|
+
});
|
|
249221
|
+
return { areas, total: operations.length };
|
|
249222
|
+
}
|
|
249223
|
+
function areaListing(area, operations, max = AREA_OPERATIONS_MAX) {
|
|
249224
|
+
return {
|
|
249225
|
+
area,
|
|
249226
|
+
operations: operations.slice(0, max).map(toOperationSummary),
|
|
249227
|
+
total: operations.length,
|
|
249228
|
+
truncated: operations.length > max
|
|
249229
|
+
};
|
|
249230
|
+
}
|
|
249231
|
+
// src/core/api-spec/schema.ts
|
|
249232
|
+
var HTTP_METHODS = [
|
|
249233
|
+
"get",
|
|
249234
|
+
"put",
|
|
249235
|
+
"post",
|
|
249236
|
+
"delete",
|
|
249237
|
+
"patch",
|
|
249238
|
+
"head",
|
|
249239
|
+
"options",
|
|
249240
|
+
"trace"
|
|
249241
|
+
];
|
|
249242
|
+
var ParameterSchema = looseObject({
|
|
249243
|
+
name: string2(),
|
|
249244
|
+
in: string2(),
|
|
249245
|
+
required: boolean2().optional(),
|
|
249246
|
+
description: string2().optional(),
|
|
249247
|
+
schema: unknown().optional(),
|
|
249248
|
+
example: unknown().optional()
|
|
249249
|
+
});
|
|
249250
|
+
var MediaTypesSchema = record(string2(), looseObject({ schema: unknown().optional() }));
|
|
249251
|
+
var MediaContentSchema = looseObject({
|
|
249252
|
+
content: MediaTypesSchema.optional()
|
|
249253
|
+
});
|
|
249254
|
+
var ResponseObjectSchema = looseObject({
|
|
249255
|
+
description: string2().optional(),
|
|
249256
|
+
content: MediaTypesSchema.optional()
|
|
249257
|
+
});
|
|
249258
|
+
var SecurityRequirementSchema = record(string2(), array(string2()));
|
|
249259
|
+
var OperationSchema = looseObject({
|
|
249260
|
+
summary: string2().optional(),
|
|
249261
|
+
description: string2().optional(),
|
|
249262
|
+
operationId: string2().optional(),
|
|
249263
|
+
parameters: array(unknown()).optional(),
|
|
249264
|
+
requestBody: unknown().optional(),
|
|
249265
|
+
responses: record(string2(), unknown()).optional(),
|
|
249266
|
+
security: array(SecurityRequirementSchema).optional()
|
|
249267
|
+
});
|
|
249268
|
+
var OpenApiSpecSchema = looseObject({
|
|
249269
|
+
openapi: string2(),
|
|
249270
|
+
paths: record(string2(), record(string2(), unknown())),
|
|
249271
|
+
components: looseObject({
|
|
249272
|
+
schemas: record(string2(), unknown()).optional()
|
|
249273
|
+
}).optional(),
|
|
249274
|
+
security: array(SecurityRequirementSchema).optional().catch(undefined)
|
|
249275
|
+
});
|
|
249276
|
+
var ParameterListSchema = array(unknown());
|
|
249277
|
+
|
|
249278
|
+
// src/core/api-spec/text.ts
|
|
249279
|
+
var DOCS_CALLOUT = /<(Info|Note|Tip|Check|Warning)>([\s\S]*?)<\/\1>/g;
|
|
249280
|
+
var RELATIVE_LINK = /\[([^\]]+)\]\(\/[^)]*\)/g;
|
|
249281
|
+
function cleanText(text) {
|
|
249282
|
+
return text.replace(DOCS_CALLOUT, (_, kind, body) => kind === "Warning" ? `Warning: ${body}` : body).replace(RELATIVE_LINK, "$1");
|
|
249283
|
+
}
|
|
249284
|
+
|
|
249285
|
+
// src/core/api-spec/operations.ts
|
|
249286
|
+
var PERSONAL_ACCESS_TOKEN_SCHEME = "PersonalAccessTokenAuth";
|
|
249287
|
+
var READ_ONLY_SCOPE = "read_only";
|
|
249288
|
+
function isReadOnly(operation, spec) {
|
|
249289
|
+
const security = operation.security ?? spec.security ?? [];
|
|
249290
|
+
return security.some((requirement) => requirement[PERSONAL_ACCESS_TOKEN_SCHEME]?.includes(READ_ONLY_SCOPE));
|
|
249291
|
+
}
|
|
249292
|
+
function parameterText(operation) {
|
|
249293
|
+
return (operation.parameters ?? []).flatMap((parameter) => {
|
|
249294
|
+
const parsed = ParameterSchema.safeParse(parameter);
|
|
249295
|
+
return parsed.success ? [parsed.data.name, cleanText(parsed.data.description ?? "")] : [];
|
|
249296
|
+
}).join(" ");
|
|
249297
|
+
}
|
|
249298
|
+
var COMPONENT_REF = /^#\/components\/([^/]+)\/([^/]+)$/;
|
|
249299
|
+
function resolveComponentRef(spec, value) {
|
|
249300
|
+
const ref = value !== null && typeof value === "object" ? value.$ref : undefined;
|
|
249301
|
+
const match = typeof ref === "string" ? COMPONENT_REF.exec(ref) : null;
|
|
249302
|
+
if (!match?.[1] || !match[2]) {
|
|
249303
|
+
return value;
|
|
249304
|
+
}
|
|
249305
|
+
const components = spec.components;
|
|
249306
|
+
return components?.[match[1]]?.[match[2]] ?? value;
|
|
249307
|
+
}
|
|
249308
|
+
function mergeParameters(shared, own) {
|
|
249309
|
+
if (!shared?.length) {
|
|
249310
|
+
return own;
|
|
249311
|
+
}
|
|
249312
|
+
const key = (parameter) => {
|
|
249313
|
+
const parsed = ParameterSchema.safeParse(parameter);
|
|
249314
|
+
return parsed.success ? `${parsed.data.in}:${parsed.data.name}` : undefined;
|
|
249315
|
+
};
|
|
249316
|
+
const ownKeys = new Set((own ?? []).map(key));
|
|
249317
|
+
return [
|
|
249318
|
+
...shared.filter((parameter) => !ownKeys.has(key(parameter))),
|
|
249319
|
+
...own ?? []
|
|
249320
|
+
];
|
|
249321
|
+
}
|
|
249322
|
+
function listOperations(spec) {
|
|
249323
|
+
return Object.entries(spec.paths).flatMap(([path, item]) => HTTP_METHODS.flatMap((method) => {
|
|
249324
|
+
const parsed = OperationSchema.safeParse(item[method]);
|
|
249325
|
+
if (!parsed.success) {
|
|
249326
|
+
return [];
|
|
249327
|
+
}
|
|
249328
|
+
const shared = ParameterListSchema.safeParse(item.parameters);
|
|
249329
|
+
const resolve = (list) => list?.map((parameter) => resolveComponentRef(spec, parameter));
|
|
249330
|
+
const operation = {
|
|
249331
|
+
...parsed.data,
|
|
249332
|
+
parameters: mergeParameters(resolve(shared.success ? shared.data : undefined), resolve(parsed.data.parameters))
|
|
249333
|
+
};
|
|
249334
|
+
return [
|
|
249335
|
+
{
|
|
249336
|
+
endpoint: `${method.toUpperCase()} ${path}`,
|
|
249337
|
+
method: method.toUpperCase(),
|
|
249338
|
+
path,
|
|
249339
|
+
summary: operation.summary ?? "",
|
|
249340
|
+
description: cleanText(operation.description ?? ""),
|
|
249341
|
+
parameterText: parameterText(operation),
|
|
249342
|
+
readOnly: isReadOnly(operation, spec),
|
|
249343
|
+
operation
|
|
249344
|
+
}
|
|
249345
|
+
];
|
|
249346
|
+
}));
|
|
249347
|
+
}
|
|
249348
|
+
function pathSegments(path) {
|
|
249349
|
+
const pathname = path.split(/[?#]/, 1)[0] ?? "";
|
|
249350
|
+
return pathname.replace(/^\/+|\/+$/g, "").split("/");
|
|
249351
|
+
}
|
|
249352
|
+
function segmentPattern(segment) {
|
|
249353
|
+
const source = segment.split(/(\{[^}]+\})/).map((part) => part.startsWith("{") ? "[^/]+" : part.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("");
|
|
249354
|
+
return new RegExp(`^${source}$`);
|
|
249355
|
+
}
|
|
249356
|
+
function literalSegments(path) {
|
|
249357
|
+
return pathSegments(path).map((segment) => segment.includes("{") ? "0" : "1").join("");
|
|
249358
|
+
}
|
|
249359
|
+
function matchOperation(operations, method, concretePath) {
|
|
249360
|
+
const upperMethod = method.toUpperCase();
|
|
249361
|
+
const segments = pathSegments(concretePath);
|
|
249362
|
+
const candidates = operations.filter((op) => {
|
|
249363
|
+
if (op.method !== upperMethod) {
|
|
249364
|
+
return false;
|
|
249365
|
+
}
|
|
249366
|
+
const template = pathSegments(op.path);
|
|
249367
|
+
return template.length === segments.length && template.every((part, i) => segmentPattern(part).test(segments[i] ?? ""));
|
|
249368
|
+
});
|
|
249369
|
+
return candidates.sort((a, b) => literalSegments(b.path).localeCompare(literalSegments(a.path)))[0];
|
|
249370
|
+
}
|
|
249371
|
+
|
|
249372
|
+
// src/core/api-spec/contract.ts
|
|
249373
|
+
var SCHEMA_REF_PREFIX = "#/components/schemas/";
|
|
249374
|
+
var MAX_REF_DEPTH = 4;
|
|
249375
|
+
function inlineRefs(node, schemas, seen = new Set, depth = 0) {
|
|
249376
|
+
if (depth > MAX_REF_DEPTH) {
|
|
249377
|
+
return node;
|
|
249378
|
+
}
|
|
249379
|
+
if (Array.isArray(node)) {
|
|
249380
|
+
return node.map((item) => inlineRefs(item, schemas, seen, depth));
|
|
249381
|
+
}
|
|
249382
|
+
if (node === null || typeof node !== "object") {
|
|
249383
|
+
return node;
|
|
249384
|
+
}
|
|
249385
|
+
const { $ref, ...siblings } = node;
|
|
249386
|
+
if (typeof $ref === "string" && $ref.startsWith(SCHEMA_REF_PREFIX)) {
|
|
249387
|
+
const name = $ref.slice(SCHEMA_REF_PREFIX.length);
|
|
249388
|
+
if (seen.has(name) || !(name in schemas)) {
|
|
249389
|
+
return node;
|
|
249390
|
+
}
|
|
249391
|
+
const resolved = inlineRefs(schemas[name], schemas, new Set([...seen, name]), depth + 1);
|
|
249392
|
+
return resolved !== null && typeof resolved === "object" ? { ...resolved, ...siblings } : resolved;
|
|
249393
|
+
}
|
|
249394
|
+
return Object.fromEntries(Object.entries(node).map(([key, value]) => [
|
|
249395
|
+
key,
|
|
249396
|
+
inlineRefs(value, schemas, seen, depth)
|
|
249397
|
+
]));
|
|
249398
|
+
}
|
|
249399
|
+
function bodyOf(value) {
|
|
249400
|
+
const parsed = MediaContentSchema.safeParse(value);
|
|
249401
|
+
const content = parsed.success ? parsed.data.content ?? {} : {};
|
|
249402
|
+
const contentType = "application/json" in content ? "application/json" : Object.keys(content)[0];
|
|
249403
|
+
return contentType ? { contentType, schema: content[contentType]?.schema } : {};
|
|
249404
|
+
}
|
|
249405
|
+
function leftoverRefs(node, schemas, found = new Map) {
|
|
249406
|
+
if (Array.isArray(node)) {
|
|
249407
|
+
for (const item of node) {
|
|
249408
|
+
leftoverRefs(item, schemas, found);
|
|
249409
|
+
}
|
|
249410
|
+
} else if (node !== null && typeof node === "object") {
|
|
249411
|
+
for (const [key, value] of Object.entries(node)) {
|
|
249412
|
+
if (key === "$ref" && typeof value === "string" && value.startsWith(SCHEMA_REF_PREFIX) && !found.has(value)) {
|
|
249413
|
+
const schema = schemas[value.slice(SCHEMA_REF_PREFIX.length)];
|
|
249414
|
+
if (schema !== undefined) {
|
|
249415
|
+
found.set(value, schema);
|
|
249416
|
+
leftoverRefs(schema, schemas, found);
|
|
249417
|
+
}
|
|
249418
|
+
} else {
|
|
249419
|
+
leftoverRefs(value, schemas, found);
|
|
249420
|
+
}
|
|
249421
|
+
}
|
|
249422
|
+
}
|
|
249423
|
+
return found;
|
|
249424
|
+
}
|
|
249425
|
+
var SCHEMA_DATA_KEYS = new Set([
|
|
249426
|
+
"example",
|
|
249427
|
+
"examples",
|
|
249428
|
+
"default",
|
|
249429
|
+
"enum",
|
|
249430
|
+
"const"
|
|
249431
|
+
]);
|
|
249432
|
+
function slimSchema(node, isPropertyMap = false) {
|
|
249433
|
+
if (Array.isArray(node)) {
|
|
249434
|
+
return node.map((item) => slimSchema(item));
|
|
249435
|
+
}
|
|
249436
|
+
if (node === null || typeof node !== "object") {
|
|
249437
|
+
return node;
|
|
249438
|
+
}
|
|
249439
|
+
const entries = Object.entries(node);
|
|
249440
|
+
if (isPropertyMap) {
|
|
249441
|
+
return Object.fromEntries(entries.map(([name, value]) => [name, slimSchema(value)]));
|
|
249442
|
+
}
|
|
249443
|
+
const slim = {};
|
|
249444
|
+
for (const [key, value] of entries) {
|
|
249445
|
+
if (key === "title" && typeof value === "string") {
|
|
249446
|
+
continue;
|
|
249447
|
+
}
|
|
249448
|
+
slim[key] = SCHEMA_DATA_KEYS.has(key) ? value : key === "properties" ? slimSchema(value, true) : key === "description" && typeof value === "string" ? cleanText(value) : slimSchema(value);
|
|
249449
|
+
}
|
|
249450
|
+
const { anyOf, ...rest } = slim;
|
|
249451
|
+
const nullable = Array.isArray(anyOf) && anyOf.length === 2 ? nullableType(anyOf) : undefined;
|
|
249452
|
+
return nullable ? { type: [nullable, "null"], ...rest } : slim;
|
|
249453
|
+
}
|
|
249454
|
+
function nullableType(variants) {
|
|
249455
|
+
const types = variants.map((variant) => variant !== null && typeof variant === "object" && Object.keys(variant).length === 1 && typeof variant.type === "string" ? variant.type : undefined);
|
|
249456
|
+
if (types.includes(undefined) || !types.includes("null")) {
|
|
249457
|
+
return;
|
|
249458
|
+
}
|
|
249459
|
+
return types.find((type) => type !== "null");
|
|
249460
|
+
}
|
|
249461
|
+
function getOperationContract(spec, op) {
|
|
249462
|
+
const schemas = spec.components?.schemas ?? {};
|
|
249463
|
+
const inline = (node) => node === undefined ? null : slimSchema(inlineRefs(node, schemas));
|
|
249464
|
+
const responses = Object.entries(op.operation.responses ?? {}).flatMap(([status, response]) => {
|
|
249465
|
+
const parsed = ResponseObjectSchema.safeParse(resolveComponentRef(spec, response));
|
|
249466
|
+
return parsed.success ? [[status, parsed.data]] : [];
|
|
249467
|
+
});
|
|
249468
|
+
const success = responses.filter(([status]) => status.startsWith("2")).sort(([a], [b]) => a.localeCompare(b)).map(([, response]) => bodyOf(response).schema).find(Boolean);
|
|
249469
|
+
const requestBody = bodyOf(resolveComponentRef(spec, op.operation.requestBody));
|
|
249470
|
+
const contract = {
|
|
249471
|
+
endpoint: op.endpoint,
|
|
249472
|
+
method: op.method,
|
|
249473
|
+
path: op.path,
|
|
249474
|
+
summary: op.summary,
|
|
249475
|
+
description: op.description,
|
|
249476
|
+
parameters: (op.operation.parameters ?? []).flatMap((parameter) => {
|
|
249477
|
+
const parsed = ParameterSchema.safeParse(parameter);
|
|
249478
|
+
if (!parsed.success) {
|
|
249479
|
+
return [parameter];
|
|
249480
|
+
}
|
|
249481
|
+
const { name, in: location2, required, schema, description } = parsed.data;
|
|
249482
|
+
const inSchema = schema !== null && typeof schema === "object" && "description" in schema;
|
|
249483
|
+
return [
|
|
249484
|
+
{
|
|
249485
|
+
name,
|
|
249486
|
+
in: location2,
|
|
249487
|
+
required: required ?? false,
|
|
249488
|
+
schema: inline(schema ?? {}),
|
|
249489
|
+
...description && !inSchema ? { description: cleanText(description) } : {},
|
|
249490
|
+
..."example" in parsed.data ? { example: parsed.data.example } : {}
|
|
249491
|
+
}
|
|
249492
|
+
];
|
|
249493
|
+
}),
|
|
249494
|
+
...requestBody.contentType && requestBody.contentType !== "application/json" ? { requestBodyContentType: requestBody.contentType } : {},
|
|
249495
|
+
requestBodySchema: inline(requestBody.schema),
|
|
249496
|
+
responseSchema: inline(success)
|
|
249497
|
+
};
|
|
249498
|
+
const refs = leftoverRefs(contract, schemas);
|
|
249499
|
+
return {
|
|
249500
|
+
...contract,
|
|
249501
|
+
...refs.size > 0 ? {
|
|
249502
|
+
refs: Object.fromEntries([...refs].map(([ref, schema]) => [ref, slimSchema(schema)]))
|
|
249503
|
+
} : {}
|
|
249504
|
+
};
|
|
249505
|
+
}
|
|
249506
|
+
// src/core/api-spec/grep.ts
|
|
249507
|
+
function grepOperations(spec, operations, pattern, options = {}) {
|
|
249508
|
+
const regex = new RegExp(pattern, options.ignoreCase ? "i" : "");
|
|
249509
|
+
return operations.filter((op) => regex.test(JSON.stringify(getOperationContract(spec, op)))).slice(0, options.limit ?? 20).map(toOperationSummary);
|
|
249510
|
+
}
|
|
249511
|
+
// src/core/api-spec/request.ts
|
|
249512
|
+
var MAX_ERROR_BODY_CHARS = 4000;
|
|
249513
|
+
var QUERY_STRING = /\?\S*/g;
|
|
249514
|
+
async function readBody(response) {
|
|
249515
|
+
try {
|
|
249516
|
+
const text = (await response.clone().text()).trim();
|
|
249517
|
+
return text.length > MAX_ERROR_BODY_CHARS ? `${text.slice(0, MAX_ERROR_BODY_CHARS)}…` : text || undefined;
|
|
249518
|
+
} catch {
|
|
249519
|
+
return;
|
|
249520
|
+
}
|
|
249521
|
+
}
|
|
249522
|
+
function normalizePath(path) {
|
|
249523
|
+
const url = new URL(path.replace(/^\/*/, "/"), "http://placeholder");
|
|
249524
|
+
return `${url.pathname}${url.search}`;
|
|
249525
|
+
}
|
|
249526
|
+
async function sendApiRequest(method, path, body) {
|
|
249527
|
+
try {
|
|
249528
|
+
const response = await base44Client(path.replace(/^\/+/, ""), {
|
|
249529
|
+
method,
|
|
249530
|
+
body,
|
|
249531
|
+
headers: typeof body === "string" ? { "Content-Type": "application/json" } : {},
|
|
249532
|
+
timeout: false,
|
|
249533
|
+
retry: { methods: ["get", "head"] }
|
|
249534
|
+
});
|
|
249535
|
+
return {
|
|
249536
|
+
status: response.status,
|
|
249537
|
+
contentType: response.headers.get("content-type") ?? "",
|
|
249538
|
+
body: new Uint8Array(await response.arrayBuffer())
|
|
249539
|
+
};
|
|
249540
|
+
} catch (error) {
|
|
249541
|
+
const apiError = await ApiError.fromHttpError(error, `calling ${method} ${path}`);
|
|
249542
|
+
const response = error instanceof HTTPError ? error.response : undefined;
|
|
249543
|
+
const raw = response ? await readBody(response) : undefined;
|
|
249544
|
+
const retryAfter = response?.headers.get("retry-after") ?? undefined;
|
|
249545
|
+
throw redactedApiError(apiError, raw, method, path, retryAfter);
|
|
249546
|
+
}
|
|
249547
|
+
}
|
|
249548
|
+
function redactedApiError(apiError, raw, method, path, retryAfter) {
|
|
249549
|
+
const wait = retryAfter ? ` (retry after ${/^\d+$/.test(retryAfter) ? `${retryAfter} s` : retryAfter})` : "";
|
|
249550
|
+
const reason = apiError.statusCode !== undefined ? `HTTP ${apiError.statusCode}${wait}` : (apiError.cause?.message ?? "request failed").replace(QUERY_STRING, "");
|
|
249551
|
+
const message = `Error calling ${method} ${path.split("?", 1)[0]}: ${reason}`;
|
|
249552
|
+
return new ApiError(message, {
|
|
249553
|
+
statusCode: apiError.statusCode,
|
|
249554
|
+
requestUrl: apiError.requestUrl?.split("?", 1)[0],
|
|
249555
|
+
requestMethod: apiError.requestMethod,
|
|
249556
|
+
requestId: apiError.requestId,
|
|
249557
|
+
hints: apiError.hints,
|
|
249558
|
+
details: [
|
|
249559
|
+
...raw ? [`Response body: ${raw}`] : apiError.details ?? [],
|
|
249560
|
+
...apiError.requestId ? [`Request ID: ${apiError.requestId}`] : []
|
|
249561
|
+
]
|
|
249562
|
+
});
|
|
249563
|
+
}
|
|
249564
|
+
// src/core/api-spec/spec.ts
|
|
249565
|
+
import { rename, rm, stat as stat3 } from "node:fs/promises";
|
|
249566
|
+
import { join as join23 } from "node:path";
|
|
249567
|
+
var SPEC_CACHE_TTL_MS = 60 * 60 * 1000;
|
|
249568
|
+
function getSpecCachePath(apiUrl = getBase44ApiUrl()) {
|
|
249569
|
+
const server = new URL(apiUrl).host.replace(/[^a-zA-Z0-9.-]/g, "_");
|
|
249570
|
+
return join23(getBase44GlobalDir(), "cache", server, "openapi.json");
|
|
249571
|
+
}
|
|
249572
|
+
function isSpecCacheFresh(mtimeMs, now = Date.now()) {
|
|
249573
|
+
return now - mtimeMs < SPEC_CACHE_TTL_MS;
|
|
249574
|
+
}
|
|
249575
|
+
function parseSpec(text) {
|
|
249576
|
+
let json;
|
|
249577
|
+
try {
|
|
249578
|
+
json = JSON.parse(text);
|
|
249579
|
+
} catch {
|
|
249580
|
+
throw new ApiError("The API spec from the server is not valid JSON");
|
|
249581
|
+
}
|
|
249582
|
+
const result = OpenApiSpecSchema.safeParse(json);
|
|
249583
|
+
if (!result.success) {
|
|
249584
|
+
throw new SchemaValidationError("Invalid API spec", result.error);
|
|
249585
|
+
}
|
|
249586
|
+
return result.data;
|
|
249587
|
+
}
|
|
249588
|
+
var SPEC_DOWNLOAD_TIMEOUT_MS = 60000;
|
|
249589
|
+
async function readFreshCache(path) {
|
|
249590
|
+
try {
|
|
249591
|
+
const { mtimeMs } = await stat3(path);
|
|
249592
|
+
if (!isSpecCacheFresh(mtimeMs)) {
|
|
249593
|
+
return null;
|
|
249594
|
+
}
|
|
249595
|
+
const text = await readTextFile(path);
|
|
249596
|
+
return { text, spec: parseSpec(text) };
|
|
249597
|
+
} catch {
|
|
249598
|
+
return null;
|
|
249599
|
+
}
|
|
249600
|
+
}
|
|
249601
|
+
async function downloadSpec() {
|
|
249602
|
+
try {
|
|
249603
|
+
const response = await base44Client.get("api/openapi.json", {
|
|
249604
|
+
timeout: SPEC_DOWNLOAD_TIMEOUT_MS
|
|
249605
|
+
});
|
|
249606
|
+
return await response.text();
|
|
249607
|
+
} catch (error) {
|
|
249608
|
+
throw await ApiError.fromHttpError(error, "fetching the API spec");
|
|
249609
|
+
}
|
|
249610
|
+
}
|
|
249611
|
+
async function loadSpec(options = {}) {
|
|
249612
|
+
const path = getSpecCachePath();
|
|
249613
|
+
const cached = options.refresh ? null : await readFreshCache(path);
|
|
249614
|
+
if (cached !== null) {
|
|
249615
|
+
return cached;
|
|
249616
|
+
}
|
|
249617
|
+
const text = await downloadSpec();
|
|
249618
|
+
const spec = parseSpec(text);
|
|
249619
|
+
const partial = `${path}.${process.pid}.tmp`;
|
|
249620
|
+
try {
|
|
249621
|
+
await writeFile(partial, text);
|
|
249622
|
+
await rename(partial, path);
|
|
249623
|
+
} catch {
|
|
249624
|
+
await rm(partial, { force: true }).catch(() => {
|
|
249625
|
+
return;
|
|
249626
|
+
});
|
|
249627
|
+
}
|
|
249628
|
+
return { text, spec };
|
|
249629
|
+
}
|
|
249630
|
+
// src/cli/commands/api/shared.ts
|
|
249631
|
+
import { basename as basename6 } from "node:path";
|
|
249632
|
+
function formatJson(value) {
|
|
249633
|
+
return toJsonStdout(value, { compact: !process.stdout.isTTY });
|
|
249634
|
+
}
|
|
249635
|
+
function parseLimit(value) {
|
|
249636
|
+
if (value === undefined) {
|
|
249637
|
+
return;
|
|
249638
|
+
}
|
|
249639
|
+
const n = Number.parseInt(value, 10);
|
|
249640
|
+
if (!Number.isInteger(n) || n < 1) {
|
|
249641
|
+
throw new InvalidInputError("--limit must be a positive integer.");
|
|
249642
|
+
}
|
|
249643
|
+
return n;
|
|
249644
|
+
}
|
|
249645
|
+
var READ_ONLY_FILTER_HELP = "Only read-only operations";
|
|
249646
|
+
var REFRESH_OPTION_HELP = "Fetch the API spec again instead of using the cached copy (kept 1 hour)";
|
|
249647
|
+
function loadSpecTask({ runTask }, refresh) {
|
|
249648
|
+
return runTask("Loading the API spec", () => loadSpec({ refresh }), {
|
|
249649
|
+
successMessage: "Loaded the API spec"
|
|
249650
|
+
});
|
|
249651
|
+
}
|
|
249652
|
+
function operationsInArea(operations, area) {
|
|
249653
|
+
const areas = groupByArea(operations);
|
|
249654
|
+
const inArea = areas.get(area);
|
|
249655
|
+
if (!inArea) {
|
|
249656
|
+
throw new InvalidInputError(`Unknown API area: ${area}`, {
|
|
249657
|
+
details: [`Areas: ${[...areas.keys()].join(", ")}`],
|
|
249658
|
+
hints: [{ message: "List the areas", command: "base44 api catalog" }]
|
|
249659
|
+
});
|
|
249660
|
+
}
|
|
249661
|
+
return inArea;
|
|
249662
|
+
}
|
|
249663
|
+
async function readRequestBody(flag) {
|
|
249664
|
+
if (flag === "@-") {
|
|
249665
|
+
return readStdin("--body @-", { trim: false });
|
|
249666
|
+
}
|
|
249667
|
+
if (flag?.startsWith("@")) {
|
|
249668
|
+
return readTextFile(flag.slice(1));
|
|
249669
|
+
}
|
|
249670
|
+
return flag;
|
|
249671
|
+
}
|
|
249672
|
+
var FORM_FILE = /^@(.+?)(?:;type=([^;]+))?$/;
|
|
249673
|
+
async function readFormBody(fields) {
|
|
249674
|
+
const form = new FormData;
|
|
249675
|
+
for (const field of fields) {
|
|
249676
|
+
const separator = field.indexOf("=");
|
|
249677
|
+
if (separator < 1) {
|
|
249678
|
+
throw new InvalidInputError(`--form takes name=value or name=@file, got "${field}".`);
|
|
249679
|
+
}
|
|
249680
|
+
const name = field.slice(0, separator);
|
|
249681
|
+
const value = field.slice(separator + 1);
|
|
249682
|
+
const file = FORM_FILE.exec(value);
|
|
249683
|
+
if (file?.[1]) {
|
|
249684
|
+
const type = file[2] ?? "application/octet-stream";
|
|
249685
|
+
const blob = new Blob([await readFile(file[1])], { type });
|
|
249686
|
+
form.append(name, blob, basename6(file[1]));
|
|
249687
|
+
} else {
|
|
249688
|
+
form.append(name, value);
|
|
249689
|
+
}
|
|
249690
|
+
}
|
|
249691
|
+
return form;
|
|
249692
|
+
}
|
|
249693
|
+
function withoutQuery(path) {
|
|
249694
|
+
return path.split("?", 1)[0] ?? "";
|
|
249695
|
+
}
|
|
249696
|
+
function reportedFetchCommand(method, path, options) {
|
|
249697
|
+
return {
|
|
249698
|
+
name: "api fetch",
|
|
249699
|
+
args: [method, withoutQuery(path)],
|
|
249700
|
+
options: {
|
|
249701
|
+
...options,
|
|
249702
|
+
...options.body === undefined ? {} : { body: "[not reported]" },
|
|
249703
|
+
...Array.isArray(options.form) && options.form.length > 0 ? { form: "[not reported]" } : {}
|
|
249704
|
+
}
|
|
249705
|
+
};
|
|
249706
|
+
}
|
|
249707
|
+
|
|
249708
|
+
// src/cli/commands/api/catalog.ts
|
|
249709
|
+
async function catalogAction(ctx, area, options) {
|
|
249710
|
+
const { spec } = await loadSpecTask(ctx, options.refresh);
|
|
249711
|
+
const operations = listOperations(spec);
|
|
249712
|
+
const filterReadOnly = (ops) => options.readOnly ? ops.filter((op) => op.readOnly) : ops;
|
|
249713
|
+
if (!area) {
|
|
249714
|
+
return { stdout: formatJson(catalogIndex(filterReadOnly(operations))) };
|
|
249715
|
+
}
|
|
249716
|
+
const inArea = filterReadOnly(operationsInArea(operations, area));
|
|
249717
|
+
return { stdout: formatJson(areaListing(area, inArea)) };
|
|
249718
|
+
}
|
|
249719
|
+
function getApiCatalogCommand() {
|
|
249720
|
+
return new Base44Command("catalog", {
|
|
249721
|
+
requireAuth: false,
|
|
249722
|
+
requireAppContext: false
|
|
249723
|
+
}).description("List the API's areas, or every operation in one area").argument("[area]", 'An area from the list, e.g. "workflows"').option("--read-only", READ_ONLY_FILTER_HELP).option("--refresh", REFRESH_OPTION_HELP).action(catalogAction);
|
|
249724
|
+
}
|
|
249725
|
+
|
|
249726
|
+
// src/cli/commands/api/fetch.ts
|
|
249727
|
+
async function findOperation(ctx, method, path, { refresh, flag }) {
|
|
249728
|
+
const { spec } = await loadSpecTask(ctx, refresh);
|
|
249729
|
+
const op = matchOperation(listOperations(spec), method, path);
|
|
249730
|
+
if (!op) {
|
|
249731
|
+
throw new InvalidInputError(`No operation in the API spec matches ${method} ${withoutQuery(path)}.`, {
|
|
249732
|
+
hints: [
|
|
249733
|
+
{
|
|
249734
|
+
message: "The cached spec may predate this route; fetch it again",
|
|
249735
|
+
command: `base44 api fetch ${method} ${path} ${flag} --refresh`
|
|
249736
|
+
},
|
|
249737
|
+
{
|
|
249738
|
+
message: "Find the operation and its path template",
|
|
249739
|
+
command: 'base44 api search "<what you want to do>"'
|
|
249740
|
+
}
|
|
249741
|
+
]
|
|
249742
|
+
});
|
|
249743
|
+
}
|
|
249744
|
+
return { spec, op };
|
|
249745
|
+
}
|
|
249746
|
+
var ENCODED_SEPARATOR = /%(2f|5c|2e)/i;
|
|
249747
|
+
async function fillAppId(ctx, path, command) {
|
|
249748
|
+
let filled = path;
|
|
249749
|
+
if (withoutQuery(path).includes("{app_id}")) {
|
|
249750
|
+
const { appId } = command.optsWithGlobals();
|
|
249751
|
+
await ensureAppContext(ctx, { appId });
|
|
249752
|
+
filled = path.replaceAll("{app_id}", requireApp(ctx).id);
|
|
249753
|
+
}
|
|
249754
|
+
const placeholder = withoutQuery(filled).match(/\{[^}/]*\}/);
|
|
249755
|
+
if (placeholder) {
|
|
249756
|
+
throw new InvalidInputError(`Replace ${placeholder[0]} in the path with a real value; only {app_id} is filled in.`);
|
|
249757
|
+
}
|
|
249758
|
+
return filled;
|
|
249759
|
+
}
|
|
249760
|
+
var MULTIPART_HINT = "Send this body with --form name=value, and --form name=@path for files.";
|
|
249761
|
+
var CONTRACT_HELP = "The contract is JSON; cut it down with e.g. | jq '.parameters, .requestBodySchema'";
|
|
249762
|
+
var TEXT_CONTENT_TYPES = [
|
|
249763
|
+
"json",
|
|
249764
|
+
"text/",
|
|
249765
|
+
"xml",
|
|
249766
|
+
"javascript",
|
|
249767
|
+
"x-www-form-urlencoded"
|
|
249768
|
+
];
|
|
249769
|
+
function decodeText(body, contentType) {
|
|
249770
|
+
const type = contentType.toLowerCase();
|
|
249771
|
+
if (type && !TEXT_CONTENT_TYPES.some((hint) => type.includes(hint))) {
|
|
249772
|
+
return;
|
|
249773
|
+
}
|
|
249774
|
+
try {
|
|
249775
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(body);
|
|
249776
|
+
} catch {
|
|
249777
|
+
return;
|
|
249778
|
+
}
|
|
249779
|
+
}
|
|
249780
|
+
async function formatResponse({ status, contentType, body }, output, jsonMode) {
|
|
249781
|
+
if (output) {
|
|
249782
|
+
await writeFile(output, body);
|
|
249783
|
+
return formatJson({ status, contentType, bytes: body.length, output });
|
|
249784
|
+
}
|
|
249785
|
+
if (body.length === 0) {
|
|
249786
|
+
return formatJson({ status });
|
|
249787
|
+
}
|
|
249788
|
+
const text = decodeText(body, contentType);
|
|
249789
|
+
if (text === undefined) {
|
|
249790
|
+
return formatJson({
|
|
249791
|
+
status,
|
|
249792
|
+
contentType,
|
|
249793
|
+
bytes: body.length,
|
|
249794
|
+
note: "Binary body not printed; add --output <file> to save it."
|
|
249795
|
+
});
|
|
249796
|
+
}
|
|
249797
|
+
const asIs = text.endsWith(`
|
|
249798
|
+
`) ? text : `${text}
|
|
249799
|
+
`;
|
|
249800
|
+
try {
|
|
249801
|
+
const parsed = JSON.parse(text);
|
|
249802
|
+
return process.stdout.isTTY ? formatJson(parsed) : asIs;
|
|
249803
|
+
} catch {
|
|
249804
|
+
return jsonMode ? formatJson({ status, contentType, body: text }) : asIs;
|
|
249805
|
+
}
|
|
249806
|
+
}
|
|
249807
|
+
async function fetchAction(ctx, methodArg, path, options, command) {
|
|
249808
|
+
ctx.errorReporter.setContext({
|
|
249809
|
+
command: reportedFetchCommand(methodArg ?? "", path ?? "", { ...options })
|
|
249810
|
+
});
|
|
249811
|
+
if (!methodArg || !path) {
|
|
249812
|
+
if (options.help) {
|
|
249813
|
+
const usage = `${command.helpInformation()}
|
|
249814
|
+
${CONTRACT_HELP}
|
|
249815
|
+
`;
|
|
249816
|
+
return { stdout: ctx.jsonMode ? formatJson({ usage }) : usage };
|
|
249817
|
+
}
|
|
249818
|
+
throw new InvalidInputError("Provide a method and a path, e.g. GET /api/apps.");
|
|
249819
|
+
}
|
|
249820
|
+
const method = methodArg.toUpperCase();
|
|
249821
|
+
if (options.help) {
|
|
249822
|
+
const { spec, op } = await findOperation(ctx, method, normalizePath(path), {
|
|
249823
|
+
refresh: options.refresh,
|
|
249824
|
+
flag: "--help"
|
|
249825
|
+
});
|
|
249826
|
+
const contract = getOperationContract(spec, op);
|
|
249827
|
+
return {
|
|
249828
|
+
stdout: formatJson(contract.requestBodyContentType === "multipart/form-data" ? { ...contract, hint: MULTIPART_HINT } : contract)
|
|
249829
|
+
};
|
|
249830
|
+
}
|
|
249831
|
+
const target = normalizePath(await fillAppId(ctx, path, command));
|
|
249832
|
+
if (options.readOnly) {
|
|
249833
|
+
if (ENCODED_SEPARATOR.test(withoutQuery(target))) {
|
|
249834
|
+
throw new InvalidInputError("Refused under --read-only: the path has an encoded /, \\ or ., so it can't be checked. Nothing was sent.");
|
|
249835
|
+
}
|
|
249836
|
+
const { op } = await findOperation(ctx, method, target, {
|
|
249837
|
+
refresh: options.refresh,
|
|
249838
|
+
flag: "--read-only"
|
|
249839
|
+
});
|
|
249840
|
+
if (!op.readOnly) {
|
|
249841
|
+
throw new InvalidInputError(`Refused under --read-only: ${op.method} ${op.path} is not a read-only operation. Nothing was sent.`);
|
|
249842
|
+
}
|
|
249843
|
+
}
|
|
249844
|
+
if (options.body !== undefined && options.form.length > 0) {
|
|
249845
|
+
throw new InvalidInputError("Use --body or --form, not both.");
|
|
249846
|
+
}
|
|
249847
|
+
await ensureAuth(ctx);
|
|
249848
|
+
const body = options.form.length > 0 ? await readFormBody(options.form) : await readRequestBody(options.body);
|
|
249849
|
+
const response = await ctx.runTask(`Calling ${method} ${target}`, () => sendApiRequest(method, target, body), {
|
|
249850
|
+
successMessage: `Called ${method} ${target}`,
|
|
249851
|
+
errorMessage: "Request failed"
|
|
249852
|
+
});
|
|
249853
|
+
return {
|
|
249854
|
+
stdout: await formatResponse(response, options.output, ctx.jsonMode)
|
|
249855
|
+
};
|
|
249856
|
+
}
|
|
249857
|
+
function getApiFetchCommand() {
|
|
249858
|
+
return new Base44Command("fetch", {
|
|
249859
|
+
requireAuth: false,
|
|
249860
|
+
requireAppContext: false
|
|
249861
|
+
}).description("Call a Base44 API operation; add --help after a path for its contract").helpOption(false).argument("[method]", "HTTP method, e.g. GET or POST").argument("[path]", 'Path with any query string; {app_id} is filled from --app-id or the project, e.g. "/api/apps/{app_id}/workflows/runs?status=failed"').option("--body <json>", "Request body: JSON, @file.json, or @- to read it from stdin").option("--form <field>", "Multipart field: name=value, or name=@file to attach a file (repeatable)", (field, fields) => [...fields, field], []).option("--output <file>", "Save the response body to a file").option("--read-only", "Refuse, before sending, any operation the spec does not mark read-only").option("--refresh", REFRESH_OPTION_HELP).option("-h, --help", "With a method and path, print that operation's contract; otherwise this help").addHelpText("after", `
|
|
249862
|
+
${CONTRACT_HELP}`).action(fetchAction);
|
|
249863
|
+
}
|
|
249864
|
+
|
|
249865
|
+
// src/cli/commands/api/grep.ts
|
|
249866
|
+
function assertValidRegex(pattern) {
|
|
249867
|
+
try {
|
|
249868
|
+
new RegExp(pattern);
|
|
249869
|
+
} catch (error) {
|
|
249870
|
+
throw new InvalidInputError(`Invalid regular expression: ${error instanceof Error ? error.message : pattern}`);
|
|
249871
|
+
}
|
|
249872
|
+
}
|
|
249873
|
+
async function grepAction(ctx, pattern, options) {
|
|
249874
|
+
const limit = parseLimit(options.limit);
|
|
249875
|
+
assertValidRegex(pattern);
|
|
249876
|
+
const { spec } = await loadSpecTask(ctx, options.refresh);
|
|
249877
|
+
let operations = listOperations(spec);
|
|
249878
|
+
if (options.area) {
|
|
249879
|
+
operations = operationsInArea(operations, options.area);
|
|
249880
|
+
}
|
|
249881
|
+
if (options.readOnly) {
|
|
249882
|
+
operations = operations.filter((op) => op.readOnly);
|
|
249883
|
+
}
|
|
249884
|
+
const hits = grepOperations(spec, operations, pattern, {
|
|
249885
|
+
ignoreCase: options.ignoreCase,
|
|
249886
|
+
limit
|
|
249887
|
+
});
|
|
249888
|
+
return { stdout: formatJson(hits) };
|
|
249889
|
+
}
|
|
249890
|
+
function getApiGrepCommand() {
|
|
249891
|
+
return new Base44Command("grep", {
|
|
249892
|
+
requireAuth: false,
|
|
249893
|
+
requireAppContext: false
|
|
249894
|
+
}).description("Search the API spec with a regular expression, for when search misses").argument("<pattern>", `Regular expression over each operation's contract as JSON text (quotes and newlines appear escaped), e.g. "runs.*status"`).option("--area <area>", "Search only one area's operations (see base44 api catalog)").option("-i, --ignore-case", "Case-insensitive match").option("--limit <n>", "Most operations to return (default 20)").option("--read-only", READ_ONLY_FILTER_HELP).option("--refresh", REFRESH_OPTION_HELP).action(grepAction);
|
|
249895
|
+
}
|
|
249896
|
+
|
|
249897
|
+
// src/cli/commands/api/search.ts
|
|
249898
|
+
async function searchAction(ctx, words, options) {
|
|
249899
|
+
const limit = parseLimit(options.limit);
|
|
249900
|
+
const { spec } = await loadSpecTask(ctx, options.refresh);
|
|
249901
|
+
const results = searchOperations(listOperations(spec), words.join(" "), {
|
|
249902
|
+
limit,
|
|
249903
|
+
readOnly: options.readOnly
|
|
249904
|
+
});
|
|
249905
|
+
return { stdout: formatJson(results) };
|
|
249906
|
+
}
|
|
249907
|
+
function getApiSearchCommand() {
|
|
249908
|
+
return new Base44Command("search", {
|
|
249909
|
+
requireAuth: false,
|
|
249910
|
+
requireAppContext: false
|
|
249911
|
+
}).description("Search every Base44 API operation by what it does").argument("<text...>", 'What you are looking for, e.g. "failed workflow runs"').option("--limit <n>", "Most results to return (default 5)").option("--read-only", READ_ONLY_FILTER_HELP).option("--refresh", REFRESH_OPTION_HELP).action(searchAction);
|
|
249912
|
+
}
|
|
249913
|
+
|
|
249914
|
+
// src/cli/commands/api/index.ts
|
|
249915
|
+
function getApiCommand() {
|
|
249916
|
+
return new Command2("api").description("Search and call any public Base44 API operation").addCommand(getApiCatalogCommand()).addCommand(getApiSearchCommand()).addCommand(getApiGrepCommand()).addCommand(getApiFetchCommand());
|
|
249917
|
+
}
|
|
249918
|
+
|
|
248045
249919
|
// src/cli/commands/auth/password-login.ts
|
|
248046
|
-
import { dirname as
|
|
249920
|
+
import { dirname as dirname17, join as join24 } from "node:path";
|
|
248047
249921
|
async function passwordLoginAction({ log, runTask }, action) {
|
|
248048
249922
|
const shouldEnable = action === "enable";
|
|
248049
249923
|
const { project } = await readProjectConfig();
|
|
248050
|
-
const configDir =
|
|
248051
|
-
const authDir =
|
|
249924
|
+
const configDir = dirname17(project.configPath);
|
|
249925
|
+
const authDir = join24(configDir, project.authDir);
|
|
248052
249926
|
const updated = await runTask("Updating local auth config", async () => {
|
|
248053
249927
|
const current = await readAuthConfig(authDir) ?? DEFAULT_AUTH_CONFIG;
|
|
248054
249928
|
const merged = { ...current, enableUsernamePassword: shouldEnable };
|
|
@@ -248068,14 +249942,14 @@ function getPasswordLoginCommand() {
|
|
|
248068
249942
|
}
|
|
248069
249943
|
|
|
248070
249944
|
// src/cli/commands/auth/pull.ts
|
|
248071
|
-
import { dirname as
|
|
249945
|
+
import { dirname as dirname18, join as join25 } from "node:path";
|
|
248072
249946
|
async function pullAuthAction({
|
|
248073
249947
|
log,
|
|
248074
249948
|
runTask
|
|
248075
249949
|
}) {
|
|
248076
249950
|
const { project } = await readProjectConfig();
|
|
248077
|
-
const configDir =
|
|
248078
|
-
const authDir =
|
|
249951
|
+
const configDir = dirname18(project.configPath);
|
|
249952
|
+
const authDir = join25(configDir, project.authDir);
|
|
248079
249953
|
const remoteConfig = await runTask("Fetching auth config from Base44", async () => {
|
|
248080
249954
|
return await pullAuthConfig();
|
|
248081
249955
|
}, {
|
|
@@ -248139,7 +250013,7 @@ function getAuthPushCommand() {
|
|
|
248139
250013
|
}
|
|
248140
250014
|
|
|
248141
250015
|
// src/cli/commands/auth/social-login.ts
|
|
248142
|
-
import { dirname as
|
|
250016
|
+
import { dirname as dirname19, join as join26, resolve as resolve7 } from "node:path";
|
|
248143
250017
|
var PROVIDER_LABELS = {
|
|
248144
250018
|
google: "Google",
|
|
248145
250019
|
microsoft: "Microsoft",
|
|
@@ -248209,8 +250083,8 @@ async function socialLoginAction({ log, isNonInteractive, runTask }, provider, a
|
|
|
248209
250083
|
}
|
|
248210
250084
|
}
|
|
248211
250085
|
const { project } = await readProjectConfig();
|
|
248212
|
-
const configDir =
|
|
248213
|
-
const authDir =
|
|
250086
|
+
const configDir = dirname19(project.configPath);
|
|
250087
|
+
const authDir = join26(configDir, project.authDir);
|
|
248214
250088
|
const { config: updated } = await runTask("Updating local auth config", async () => updateSocialLoginConfig(authDir, provider, shouldEnable, useCustomOAuth && options.clientId ? { clientId: options.clientId } : undefined));
|
|
248215
250089
|
if (clientSecret) {
|
|
248216
250090
|
await runTask("Saving client secret", async () => pushCustomOAuthSecret(provider, clientSecret));
|
|
@@ -248235,7 +250109,7 @@ function getSocialLoginCommand() {
|
|
|
248235
250109
|
}
|
|
248236
250110
|
|
|
248237
250111
|
// src/cli/commands/auth/sso.ts
|
|
248238
|
-
import { dirname as
|
|
250112
|
+
import { dirname as dirname20, join as join27, resolve as resolve8 } from "node:path";
|
|
248239
250113
|
var SSOConfigFileSchema = object({
|
|
248240
250114
|
provider: _enum(Object.values(KNOWN_SSO_PROVIDERS)),
|
|
248241
250115
|
clientId: string2(),
|
|
@@ -248398,8 +250272,8 @@ async function ssoEnableAction({ isNonInteractive, runTask }, options) {
|
|
|
248398
250272
|
throw error;
|
|
248399
250273
|
}
|
|
248400
250274
|
const { project } = await readProjectConfig();
|
|
248401
|
-
const configDir =
|
|
248402
|
-
const authDir =
|
|
250275
|
+
const configDir = dirname20(project.configPath);
|
|
250276
|
+
const authDir = join27(configDir, project.authDir);
|
|
248403
250277
|
await runTask("Updating local auth config", async () => updateSSOConfig(authDir, provider, true));
|
|
248404
250278
|
await runTask("Saving SSO credentials", async () => pushSSOSecrets(secrets));
|
|
248405
250279
|
return {
|
|
@@ -248414,8 +250288,8 @@ async function ssoDisableAction({ log, runTask }, options) {
|
|
|
248414
250288
|
throw new InvalidInputError("Configuration options cannot be used with disable. To disable SSO: base44 auth sso disable");
|
|
248415
250289
|
}
|
|
248416
250290
|
const { project } = await readProjectConfig();
|
|
248417
|
-
const configDir =
|
|
248418
|
-
const authDir =
|
|
250291
|
+
const configDir = dirname20(project.configPath);
|
|
250292
|
+
const authDir = join27(configDir, project.authDir);
|
|
248419
250293
|
const updated = await runTask("Updating local auth config", async () => updateSSOConfig(authDir, null, false));
|
|
248420
250294
|
await runTask("Removing SSO credentials", async () => deleteSSOSecrets());
|
|
248421
250295
|
if (!hasAnyLoginMethod(updated)) {
|
|
@@ -249297,13 +251171,13 @@ function getConnectorsListAvailableCommand() {
|
|
|
249297
251171
|
}
|
|
249298
251172
|
|
|
249299
251173
|
// src/cli/commands/connectors/pull.ts
|
|
249300
|
-
import { dirname as
|
|
251174
|
+
import { dirname as dirname21, join as join28, resolve as resolve9 } from "node:path";
|
|
249301
251175
|
async function resolveConnectorsDir(options) {
|
|
249302
251176
|
if (!getAppContext().projectRoot) {
|
|
249303
251177
|
return resolve9(options.dir ?? "connectors");
|
|
249304
251178
|
}
|
|
249305
251179
|
const { project } = await readProjectConfig();
|
|
249306
|
-
return
|
|
251180
|
+
return join28(dirname21(project.configPath), project.connectorsDir);
|
|
249307
251181
|
}
|
|
249308
251182
|
async function pullConnectorsAction({ log, runTask, jsonMode }, options) {
|
|
249309
251183
|
const connectorsDir = await resolveConnectorsDir(options);
|
|
@@ -249690,11 +251564,11 @@ function getListCommand() {
|
|
|
249690
251564
|
}
|
|
249691
251565
|
|
|
249692
251566
|
// src/cli/commands/functions/pull.ts
|
|
249693
|
-
import { dirname as
|
|
251567
|
+
import { dirname as dirname22, join as join29 } from "node:path";
|
|
249694
251568
|
async function pullFunctionsAction({ log, runTask }, name) {
|
|
249695
251569
|
const { project, functions } = await readProjectConfig();
|
|
249696
|
-
const configDir =
|
|
249697
|
-
const functionsDir =
|
|
251570
|
+
const configDir = dirname22(project.configPath);
|
|
251571
|
+
const functionsDir = join29(configDir, project.functionsDir);
|
|
249698
251572
|
const pluginFunctionNames = new Set(functions.filter((fn) => fn.source.type === "plugin").map((fn) => fn.name));
|
|
249699
251573
|
const remoteFunctions = await runTask("Fetching functions from Base44", async () => {
|
|
249700
251574
|
const { functions } = await listDeployedFunctions();
|
|
@@ -249804,11 +251678,11 @@ function getBuildCommand() {
|
|
|
249804
251678
|
}
|
|
249805
251679
|
|
|
249806
251680
|
// src/cli/commands/project/create.ts
|
|
249807
|
-
import { basename as
|
|
251681
|
+
import { basename as basename7, resolve as resolve11 } from "node:path";
|
|
249808
251682
|
var import_kebabCase = __toESM(require_kebabCase(), 1);
|
|
249809
251683
|
|
|
249810
251684
|
// src/cli/commands/project/scaffold-shared.ts
|
|
249811
|
-
import { join as
|
|
251685
|
+
import { join as join30 } from "node:path";
|
|
249812
251686
|
var DEFAULT_TEMPLATE_ID = "backend-only";
|
|
249813
251687
|
async function getTemplateById(templateId) {
|
|
249814
251688
|
const templates = await listTemplates();
|
|
@@ -249871,7 +251745,7 @@ async function completeProjectSetup({
|
|
|
249871
251745
|
env: { VITE_BASE44_APP_ID: projectId }
|
|
249872
251746
|
})`${buildCommand}`;
|
|
249873
251747
|
updateMessage("Deploying site...");
|
|
249874
|
-
return await deploySite(
|
|
251748
|
+
return await deploySite(join30(resolvedPath, outputDirectory));
|
|
249875
251749
|
}, {
|
|
249876
251750
|
successMessage: theme.colors.base44Orange("Site deployed successfully"),
|
|
249877
251751
|
errorMessage: "Failed to deploy site"
|
|
@@ -249969,8 +251843,8 @@ async function createInteractive(options, ctx) {
|
|
|
249969
251843
|
name: () => {
|
|
249970
251844
|
return options.name ? Promise.resolve(options.name) : Ze({
|
|
249971
251845
|
message: "What is the name of your project?",
|
|
249972
|
-
placeholder:
|
|
249973
|
-
initialValue:
|
|
251846
|
+
placeholder: basename7(process.cwd()),
|
|
251847
|
+
initialValue: basename7(process.cwd()),
|
|
249974
251848
|
validate: (value) => {
|
|
249975
251849
|
if (!value || value.trim().length === 0) {
|
|
249976
251850
|
return "Every project deserves a name";
|
|
@@ -250665,7 +252539,7 @@ function getLogsCommand() {
|
|
|
250665
252539
|
}
|
|
250666
252540
|
|
|
250667
252541
|
// src/cli/commands/project/scaffold.ts
|
|
250668
|
-
import { basename as
|
|
252542
|
+
import { basename as basename8, resolve as resolve12 } from "node:path";
|
|
250669
252543
|
function resolveAppId(options) {
|
|
250670
252544
|
const appId = options.appId;
|
|
250671
252545
|
if (!appId) {
|
|
@@ -250682,7 +252556,7 @@ async function scaffoldAction(ctx, name, options, command) {
|
|
|
250682
252556
|
const { log, runTask } = ctx;
|
|
250683
252557
|
const appId = resolveAppId(command.optsWithGlobals());
|
|
250684
252558
|
const resolvedPath = resolve12("./");
|
|
250685
|
-
const projectName = (name ??
|
|
252559
|
+
const projectName = (name ?? basename8(resolvedPath)).trim();
|
|
250686
252560
|
const template = await getTemplateById("backend-only");
|
|
250687
252561
|
log.info(`Scaffolding project at ${resolvedPath}`);
|
|
250688
252562
|
const { projectId } = await runTask("Setting up your project...", async () => {
|
|
@@ -250793,25 +252667,6 @@ function declaredBundle({
|
|
|
250793
252667
|
}
|
|
250794
252668
|
};
|
|
250795
252669
|
}
|
|
250796
|
-
function declaredActor({
|
|
250797
|
-
name,
|
|
250798
|
-
entry,
|
|
250799
|
-
source,
|
|
250800
|
-
size,
|
|
250801
|
-
digest,
|
|
250802
|
-
staticEgress
|
|
250803
|
-
}) {
|
|
250804
|
-
return {
|
|
250805
|
-
name,
|
|
250806
|
-
entry,
|
|
250807
|
-
source,
|
|
250808
|
-
module: { size, digest },
|
|
250809
|
-
static_egress: staticEgress
|
|
250810
|
-
};
|
|
250811
|
-
}
|
|
250812
|
-
function actorUploadPath(actor) {
|
|
250813
|
-
return `actors/${actor.name}.mjs`;
|
|
250814
|
-
}
|
|
250815
252670
|
function declaredServingConfig(config) {
|
|
250816
252671
|
const stated = {
|
|
250817
252672
|
html_handling: config?.htmlHandling ?? null,
|
|
@@ -250866,7 +252721,6 @@ async function createVersion(artifacts, options = {}) {
|
|
|
250866
252721
|
}
|
|
250867
252722
|
} : {},
|
|
250868
252723
|
backend_bundles: artifacts.backendBundles.map(declaredBundle),
|
|
250869
|
-
actors: artifacts.actors.map(declaredActor),
|
|
250870
252724
|
entities: artifacts.entities,
|
|
250871
252725
|
agents: artifacts.agents,
|
|
250872
252726
|
source_commit: options.sourceCommit
|
|
@@ -250875,8 +252729,7 @@ async function createVersion(artifacts, options = {}) {
|
|
|
250875
252729
|
...artifacts.assets,
|
|
250876
252730
|
...artifacts.siteWorker?.modules ?? []
|
|
250877
252731
|
];
|
|
250878
|
-
const
|
|
250879
|
-
const slotCount = actorsAt + artifacts.actors.length;
|
|
252732
|
+
const slotCount = declaredFiles.length + artifacts.backendBundles.length;
|
|
250880
252733
|
options.progress?.onDeclared?.({ fileCount: slotCount });
|
|
250881
252734
|
if (declared.uploads.length !== slotCount) {
|
|
250882
252735
|
throw new InternalError(`Declared ${slotCount} files but the server signed ${declared.uploads.length} upload URLs.`);
|
|
@@ -250885,18 +252738,12 @@ async function createVersion(artifacts, options = {}) {
|
|
|
250885
252738
|
if (drifted !== -1) {
|
|
250886
252739
|
throw new InternalError(`Upload ${drifted} is signed for ${declared.uploads[drifted].path}, but that slot declared ${declaredFiles[drifted].path}.`);
|
|
250887
252740
|
}
|
|
250888
|
-
const actorDrifted = artifacts.actors.findIndex((actor, index) => declared.uploads[actorsAt + index].path !== actorUploadPath(actor));
|
|
250889
|
-
if (actorDrifted !== -1) {
|
|
250890
|
-
throw new InternalError(`Upload ${actorsAt + actorDrifted} is signed for ${declared.uploads[actorsAt + actorDrifted].path}, but that slot declared the actor ${artifacts.actors[actorDrifted].name}.`);
|
|
250891
|
-
}
|
|
250892
252741
|
let uploadedFiles = 0;
|
|
250893
252742
|
await pMap(declared.uploads, async (upload, index) => {
|
|
250894
252743
|
if (index < declaredFiles.length) {
|
|
250895
252744
|
await putPresigned(upload, declaredFiles[index].absolutePath);
|
|
250896
|
-
} else if (index < actorsAt) {
|
|
250897
|
-
await putPresignedBody(upload, artifacts.backendBundles[index - declaredFiles.length].module);
|
|
250898
252745
|
} else {
|
|
250899
|
-
await putPresignedBody(upload, artifacts.
|
|
252746
|
+
await putPresignedBody(upload, artifacts.backendBundles[index - declaredFiles.length].module);
|
|
250900
252747
|
}
|
|
250901
252748
|
uploadedFiles++;
|
|
250902
252749
|
options.progress?.onUpload?.({
|
|
@@ -250914,10 +252761,11 @@ async function setEnvironmentVersion(environment, versionId, options = {}) {
|
|
|
250914
252761
|
}
|
|
250915
252762
|
// src/core/version/artifacts.ts
|
|
250916
252763
|
import { createHash as createHash3 } from "node:crypto";
|
|
250917
|
-
import { join as
|
|
252764
|
+
import { join as join31, resolve as resolve13 } from "node:path";
|
|
250918
252765
|
|
|
250919
|
-
// src/core/version/
|
|
250920
|
-
import {
|
|
252766
|
+
// src/core/version/functions.ts
|
|
252767
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
252768
|
+
import { relative as relative6 } from "node:path";
|
|
250921
252769
|
|
|
250922
252770
|
// ../functions-compiler/src/assembly.ts
|
|
250923
252771
|
import path17 from "node:path";
|
|
@@ -256400,7 +258248,7 @@ var TELEMETRY_PATCH = [
|
|
|
256400
258248
|
var TELEMETRY_STORE_FIELDS = "reqId: crypto.randomUUID(), respondedAt: null, inflight: new Map(), inflightTotal: 0, hadRejection: false, hadNonOk: false, logBudget: 5";
|
|
256401
258249
|
|
|
256402
258250
|
// ../functions-compiler/src/version.ts
|
|
256403
|
-
var COMPILER_VERSION = "0.1.
|
|
258251
|
+
var COMPILER_VERSION = "0.1.8";
|
|
256404
258252
|
|
|
256405
258253
|
// ../functions-compiler/src/worker-entry.ts
|
|
256406
258254
|
function denoShimSource() {
|
|
@@ -256451,18 +258299,6 @@ function consolePatch(runtimeSecrets) {
|
|
|
256451
258299
|
return runtimeSecrets ? `${CONSOLE_PATCH}
|
|
256452
258300
|
${RUNTIME_SECRETS_RESERVED_PATCH}` : CONSOLE_PATCH;
|
|
256453
258301
|
}
|
|
256454
|
-
async function prepareFunction(entry, files, postResponseTelemetry = false, runtimeSecrets = false) {
|
|
256455
|
-
assertNoReservedFilenames(files);
|
|
256456
|
-
return {
|
|
256457
|
-
entry: ENTRY_FILENAME,
|
|
256458
|
-
files: {
|
|
256459
|
-
...userFiles(files),
|
|
256460
|
-
...workerRuntimeFiles(),
|
|
256461
|
-
...runtimeSecrets ? { [ACTIVATION_FILENAME]: activationShimSource() } : {},
|
|
256462
|
-
[ENTRY_FILENAME]: buildEntrySource(entry, postResponseTelemetry, runtimeSecrets)
|
|
256463
|
-
}
|
|
256464
|
-
};
|
|
256465
|
-
}
|
|
256466
258302
|
var BANNER_FORMAT = 1;
|
|
256467
258303
|
function buildBanner(entries, telemetry, runtimeSecrets) {
|
|
256468
258304
|
return `//!b44:${BANNER_FORMAT} ${JSON.stringify({
|
|
@@ -256506,50 +258342,6 @@ function activationImport(runtimeSecrets) {
|
|
|
256506
258342
|
return runtimeSecrets ? `
|
|
256507
258343
|
import { ensureActivation, takeActivationChallenge, withoutActivationHeaders } from "./${ACTIVATION_FILENAME}";` : "";
|
|
256508
258344
|
}
|
|
256509
|
-
function buildEntrySource(userEntry, telemetry, runtimeSecrets = false) {
|
|
256510
|
-
const userImport = `./${userEntry.replace(/^\.\//, "")}`;
|
|
256511
|
-
const handlerExpr = telemetry ? "_b44AttachTelemetry(await handler(request, info))" : runtimeSecrets ? "await handler(request, info)" : "handler(request, info)";
|
|
256512
|
-
const guard = activationGuard(runtimeSecrets);
|
|
256513
|
-
const returnExpr = guard(handlerExpr);
|
|
256514
|
-
return `// Auto-generated by the base44 bundler. Do not edit.
|
|
256515
|
-
|
|
256516
|
-
import { currentWorkerRuntimeContext as _b44Context, runWithWorkerEnvironment as _b44Run } from ${JSON.stringify(RUNTIME_CONTEXT_SPECIFIER)};
|
|
256517
|
-
import { getRegisteredHandler, installStaticEgressFetch } from "./${SHIM_FILENAME}";${activationImport(runtimeSecrets)}
|
|
256518
|
-
|
|
256519
|
-
${consolePatch(runtimeSecrets)}
|
|
256520
|
-
// Static egress reads workerEnv from the active request store. Install it
|
|
256521
|
-
// before telemetry so telemetry remains the outermost fetch wrapper.
|
|
256522
|
-
installStaticEgressFetch();
|
|
256523
|
-
${telemetry ? TELEMETRY_PATCH : ""}
|
|
256524
|
-
|
|
256525
|
-
let _b44Init = null;
|
|
256526
|
-
export default {
|
|
256527
|
-
async fetch(request, env, ctx) {
|
|
256528
|
-
${runtimeSecrets ? ACTIVATION_TAKE : ""} const _b44Env = (request.headers.get('base44-functions-version') ?? '') === 'prod' ? 'prod' : 'preview';
|
|
256529
|
-
return _b44Run({ env: _b44Env, secrets: ${runtimeSecrets ? "process.env" : "env"}, workerEnv: env, waitUntil: (p) => ctx.waitUntil(p)${telemetry ? `, ${TELEMETRY_STORE_FIELDS}` : ""} }, async () => {
|
|
256530
|
-
${runtimeSecrets ? ACTIVATION_GATE : ""} if (!_b44Init) _b44Init = import(${JSON.stringify(userImport)}).catch(e => { _b44Init = null; throw e; });
|
|
256531
|
-
const _b44Mod = await _b44Init;
|
|
256532
|
-
// Deno.serve capture wins (legacy contract, zero behavior change);
|
|
256533
|
-
// a default-exported handler is the new-contract fallback.
|
|
256534
|
-
const handler = getRegisteredHandler() ?? (typeof _b44Mod?.default === 'function' ? _b44Mod.default : null);
|
|
256535
|
-
if (!handler) {
|
|
256536
|
-
return ${guard(`new Response(
|
|
256537
|
-
"The function must export default a request handler or call Deno.serve()",
|
|
256538
|
-
{ status: 503 },
|
|
256539
|
-
)`)};
|
|
256540
|
-
}
|
|
256541
|
-
// Deno's handler signature is (request, info). Cloudflare doesn't expose a
|
|
256542
|
-
// connection address the same way; pass a best-effort placeholder. Real
|
|
256543
|
-
// client IP is available via the "cf-connecting-ip" request header.
|
|
256544
|
-
const info = {
|
|
256545
|
-
remoteAddr: { transport: "tcp", hostname: "0.0.0.0", port: 0 },
|
|
256546
|
-
};
|
|
256547
|
-
return ${returnExpr};
|
|
256548
|
-
});
|
|
256549
|
-
},
|
|
256550
|
-
};
|
|
256551
|
-
`;
|
|
256552
|
-
}
|
|
256553
258345
|
function buildFunctionModuleSource(functionName, userEntry) {
|
|
256554
258346
|
const userImport = `./${userEntry.replace(/^\.\//, "")}`;
|
|
256555
258347
|
return `// Auto-generated by the base44 bundler. Do not edit.
|
|
@@ -256852,284 +258644,6 @@ function runtimeContextVirtualPlugin() {
|
|
|
256852
258644
|
};
|
|
256853
258645
|
}
|
|
256854
258646
|
|
|
256855
|
-
// ../functions-compiler/src/actor-compat.ts
|
|
256856
|
-
var ACTOR_ENTRY_FILENAME2 = "__base44_actor_entry.mjs";
|
|
256857
|
-
var ACTOR_PRELUDE_FILENAME = "__base44_actor_prelude.mjs";
|
|
256858
|
-
var ACTOR_AUTH_FILENAME = "__base44_actor_auth.mjs";
|
|
256859
|
-
var ACTORS_PREFIX = "base44/actors/";
|
|
256860
|
-
var ENTRY_SUFFIX = "/entry.ts";
|
|
256861
|
-
function actorNameFromEntry(entry) {
|
|
256862
|
-
if (!entry.startsWith(ACTORS_PREFIX) || !entry.endsWith(ENTRY_SUFFIX))
|
|
256863
|
-
return null;
|
|
256864
|
-
const name = entry.slice(ACTORS_PREFIX.length, -ENTRY_SUFFIX.length);
|
|
256865
|
-
return name && !name.includes("/") ? name : null;
|
|
256866
|
-
}
|
|
256867
|
-
function applyActorCompat(entry, files) {
|
|
256868
|
-
const actorName = actorNameFromEntry(entry);
|
|
256869
|
-
if (!actorName || files[entry] === undefined)
|
|
256870
|
-
return null;
|
|
256871
|
-
assertNoReservedFilenames(files);
|
|
256872
|
-
if (ACTOR_PRELUDE_FILENAME in files) {
|
|
256873
|
-
throw new Error(`Reserved filename "${ACTOR_PRELUDE_FILENAME}" in actor bundle — ` + "it is generated by the bundler. Rename the file.");
|
|
256874
|
-
}
|
|
256875
|
-
if (ACTOR_AUTH_FILENAME in files) {
|
|
256876
|
-
throw new Error(`Reserved filename "${ACTOR_AUTH_FILENAME}" in actor bundle — ` + "it is generated by the bundler. Rename the file.");
|
|
256877
|
-
}
|
|
256878
|
-
const handlerName = actorName;
|
|
256879
|
-
const doClassName = handlerName;
|
|
256880
|
-
const prelude = buildPrelude();
|
|
256881
|
-
const entryWrapper = buildEntryWrapper(doClassName, entry);
|
|
256882
|
-
return {
|
|
256883
|
-
entry: ACTOR_ENTRY_FILENAME2,
|
|
256884
|
-
files: {
|
|
256885
|
-
...files,
|
|
256886
|
-
...workerRuntimeFiles(),
|
|
256887
|
-
[ACTOR_AUTH_FILENAME]: buildActorAuth(),
|
|
256888
|
-
[ACTOR_PRELUDE_FILENAME]: prelude,
|
|
256889
|
-
[ACTOR_ENTRY_FILENAME2]: entryWrapper
|
|
256890
|
-
},
|
|
256891
|
-
handlerName,
|
|
256892
|
-
doClassName
|
|
256893
|
-
};
|
|
256894
|
-
}
|
|
256895
|
-
function buildActorAuth() {
|
|
256896
|
-
return `// Auto-generated by the base44 bundler. Do not edit.
|
|
256897
|
-
const TOKEN_HEADER = "X-Base44-Actor-Token";
|
|
256898
|
-
const IDENTITY_HEADER = "X-Base44-Actor-Identity";
|
|
256899
|
-
const CLOCK_SKEW_SECONDS = 30;
|
|
256900
|
-
const TOKEN_TTL_SECONDS = 300;
|
|
256901
|
-
|
|
256902
|
-
const decodeSegment = (segment) => {
|
|
256903
|
-
const normalized = segment.replace(/-/g, "+").replace(/_/g, "/");
|
|
256904
|
-
const padded = normalized + "=".repeat((4 - normalized.length % 4) % 4);
|
|
256905
|
-
const binary = atob(padded);
|
|
256906
|
-
return new Uint8Array([...binary].map((character) => character.charCodeAt(0)));
|
|
256907
|
-
};
|
|
256908
|
-
|
|
256909
|
-
const decodeJsonSegment = (segment) =>
|
|
256910
|
-
JSON.parse(new TextDecoder().decode(decodeSegment(segment)));
|
|
256911
|
-
|
|
256912
|
-
const unauthorized = () => ({
|
|
256913
|
-
ok: false,
|
|
256914
|
-
response: new Response("Unauthorized", { status: 401 }),
|
|
256915
|
-
});
|
|
256916
|
-
|
|
256917
|
-
const validPrincipal = (principal) => {
|
|
256918
|
-
if (principal === null || typeof principal !== "object" || Array.isArray(principal)) return false;
|
|
256919
|
-
if (principal.type === "authenticated") {
|
|
256920
|
-
return typeof principal.userId === "string" && principal.userId.length > 0 && principal.userId.length <= 128;
|
|
256921
|
-
}
|
|
256922
|
-
if (principal.type === "anonymous") {
|
|
256923
|
-
return typeof principal.anonymousId === "string" && principal.anonymousId.length > 0 && principal.anonymousId.length <= 128;
|
|
256924
|
-
}
|
|
256925
|
-
return false;
|
|
256926
|
-
};
|
|
256927
|
-
|
|
256928
|
-
export async function verifyActorConnection(request, env, actorName, room) {
|
|
256929
|
-
const publicKey = env.BASE44_ACTOR_PUBLIC_KEY;
|
|
256930
|
-
const scriptId = env.BASE44_ACTOR_SCRIPT_ID;
|
|
256931
|
-
const token = request.headers.get(TOKEN_HEADER) ?? new URL(request.url).searchParams.get("token");
|
|
256932
|
-
if (
|
|
256933
|
-
typeof publicKey !== "string" || !publicKey ||
|
|
256934
|
-
typeof scriptId !== "string" || !scriptId ||
|
|
256935
|
-
typeof token !== "string" || token.length > 4096
|
|
256936
|
-
) return unauthorized();
|
|
256937
|
-
|
|
256938
|
-
const parts = token.split(".");
|
|
256939
|
-
if (parts.length !== 3) return unauthorized();
|
|
256940
|
-
try {
|
|
256941
|
-
const header = decodeJsonSegment(parts[0]);
|
|
256942
|
-
const claims = decodeJsonSegment(parts[1]);
|
|
256943
|
-
if (header?.alg !== "EdDSA" || (header.typ !== undefined && header.typ !== "JWT")) {
|
|
256944
|
-
return unauthorized();
|
|
256945
|
-
}
|
|
256946
|
-
const key = await crypto.subtle.importKey(
|
|
256947
|
-
"raw",
|
|
256948
|
-
decodeSegment(publicKey),
|
|
256949
|
-
{ name: "Ed25519" },
|
|
256950
|
-
false,
|
|
256951
|
-
["verify"],
|
|
256952
|
-
);
|
|
256953
|
-
const validSignature = await crypto.subtle.verify(
|
|
256954
|
-
{ name: "Ed25519" },
|
|
256955
|
-
key,
|
|
256956
|
-
decodeSegment(parts[2]),
|
|
256957
|
-
new TextEncoder().encode(parts[0] + "." + parts[1]),
|
|
256958
|
-
);
|
|
256959
|
-
if (!validSignature) return unauthorized();
|
|
256960
|
-
|
|
256961
|
-
const now = Math.floor(Date.now() / 1000);
|
|
256962
|
-
const times = [claims.iat, claims.nbf, claims.exp];
|
|
256963
|
-
if (!times.every(Number.isInteger)) return unauthorized();
|
|
256964
|
-
if (
|
|
256965
|
-
claims.iss !== "base44" ||
|
|
256966
|
-
claims.aud !== "base44-actor-connect" ||
|
|
256967
|
-
claims.purpose !== "actor-connect" ||
|
|
256968
|
-
claims.v !== 1 ||
|
|
256969
|
-
typeof claims.jti !== "string" || !claims.jti || claims.jti.length > 64 ||
|
|
256970
|
-
claims.iat > now + CLOCK_SKEW_SECONDS ||
|
|
256971
|
-
claims.nbf > now + CLOCK_SKEW_SECONDS ||
|
|
256972
|
-
claims.exp < now - CLOCK_SKEW_SECONDS ||
|
|
256973
|
-
claims.exp <= claims.iat || claims.exp - claims.iat > TOKEN_TTL_SECONDS ||
|
|
256974
|
-
claims.app_id !== env.BASE44_APP_ID ||
|
|
256975
|
-
claims.actor_name !== actorName ||
|
|
256976
|
-
claims.actor_script_id !== scriptId ||
|
|
256977
|
-
claims.room !== room ||
|
|
256978
|
-
claims.connection_id !== new URL(request.url).searchParams.get("_pk") ||
|
|
256979
|
-
claims.runtime_mode !== (env.BASE44_FUNCTIONS_VERSION === "prod" ? "prod" : "preview") ||
|
|
256980
|
-
!validPrincipal(claims.principal)
|
|
256981
|
-
) return unauthorized();
|
|
256982
|
-
|
|
256983
|
-
return {
|
|
256984
|
-
ok: true,
|
|
256985
|
-
identity: Object.freeze({ ...claims.principal }),
|
|
256986
|
-
runtimeMode: claims.runtime_mode,
|
|
256987
|
-
};
|
|
256988
|
-
} catch {
|
|
256989
|
-
return unauthorized();
|
|
256990
|
-
}
|
|
256991
|
-
}
|
|
256992
|
-
|
|
256993
|
-
export function authorizedActorRequest(request, identity, actorName, room, runtimeMode) {
|
|
256994
|
-
const url = new URL(request.url);
|
|
256995
|
-
url.searchParams.delete("token");
|
|
256996
|
-
url.pathname = "/parties/" + encodeURIComponent(actorName) + "/" + encodeURIComponent(room);
|
|
256997
|
-
const headers = new Headers(request.headers);
|
|
256998
|
-
headers.delete(TOKEN_HEADER);
|
|
256999
|
-
headers.set(IDENTITY_HEADER, JSON.stringify(identity));
|
|
257000
|
-
headers.set("base44-functions-version", runtimeMode === "prod" ? "prod" : "preview");
|
|
257001
|
-
return new Request(new Request(url.toString(), request), { headers });
|
|
257002
|
-
}
|
|
257003
|
-
`;
|
|
257004
|
-
}
|
|
257005
|
-
function buildPrelude() {
|
|
257006
|
-
return `// Auto-generated by the base44 bundler. Do not edit.
|
|
257007
|
-
import { currentWorkerRuntimeContext as _b44Context } from ${JSON.stringify(RUNTIME_CONTEXT_SPECIFIER)};
|
|
257008
|
-
import { installStaticEgressFetch } from "./${SHIM_FILENAME}";
|
|
257009
|
-
|
|
257010
|
-
${CONSOLE_PATCH}
|
|
257011
|
-
installStaticEgressFetch();
|
|
257012
|
-
`;
|
|
257013
|
-
}
|
|
257014
|
-
function buildEntryWrapper(doClassName, userEntry) {
|
|
257015
|
-
const userImport = `./${userEntry.replace(/^\.\//, "")}`;
|
|
257016
|
-
return `// Auto-generated by the base44 bundler. Do not edit.
|
|
257017
|
-
// The prelude is intentionally the first dependency: it installs the fetch
|
|
257018
|
-
// shim before the user module evaluates while this static default import keeps
|
|
257019
|
-
// missing-default actors as bundle-time errors.
|
|
257020
|
-
import "./${ACTOR_PRELUDE_FILENAME}";
|
|
257021
|
-
import Base44UserActor from ${JSON.stringify(userImport)};
|
|
257022
|
-
import { runWithWorkerEnvironment as _b44Run } from ${JSON.stringify(RUNTIME_CONTEXT_SPECIFIER)};
|
|
257023
|
-
import { authorizedActorRequest as _b44AuthorizedActorRequest, verifyActorConnection as _b44VerifyActorConnection } from "./${ACTOR_AUTH_FILENAME}";
|
|
257024
|
-
|
|
257025
|
-
const _b44ActorState = new WeakMap();
|
|
257026
|
-
const _b44RunWithActorEnvironment = (ctx, env, runtimeEnv, callback) => _b44Run({
|
|
257027
|
-
env: runtimeEnv,
|
|
257028
|
-
secrets: env,
|
|
257029
|
-
workerEnv: env,
|
|
257030
|
-
waitUntil: (promise) => ctx.waitUntil(promise),
|
|
257031
|
-
}, callback);
|
|
257032
|
-
const _b44ConstructActor = (ctx, env, newTarget) => _b44RunWithActorEnvironment(
|
|
257033
|
-
ctx,
|
|
257034
|
-
env,
|
|
257035
|
-
"prod",
|
|
257036
|
-
() => {
|
|
257037
|
-
// A derived constructor may return an explicitly constructed instance.
|
|
257038
|
-
// This keeps the user's constructor and class-field initializers inside the
|
|
257039
|
-
// request-scoped Worker environment without changing the exported subclass.
|
|
257040
|
-
const actor = Reflect.construct(Base44UserActor, [ctx, env], newTarget);
|
|
257041
|
-
_b44ActorState.set(actor, { ctx, env, runtimeEnv: null });
|
|
257042
|
-
return actor;
|
|
257043
|
-
},
|
|
257044
|
-
);
|
|
257045
|
-
const _b44RunActor = (actor, request, callback) => {
|
|
257046
|
-
const state = _b44ActorState.get(actor);
|
|
257047
|
-
const runtimeEnv = request
|
|
257048
|
-
? ((request.headers.get("base44-functions-version") ?? "") === "prod" ? "prod" : "preview")
|
|
257049
|
-
: (state.runtimeEnv ?? "prod");
|
|
257050
|
-
state.runtimeEnv = runtimeEnv;
|
|
257051
|
-
return _b44RunWithActorEnvironment(state.ctx, state.env, runtimeEnv, callback);
|
|
257052
|
-
};
|
|
257053
|
-
|
|
257054
|
-
export class ${doClassName} extends Base44UserActor {
|
|
257055
|
-
// Read by the shim's service-token exchange: the assertion's actor_name claim
|
|
257056
|
-
// selects the verification key on the platform side. A static (not .name) so
|
|
257057
|
-
// minification can't change it.
|
|
257058
|
-
static _b44ActorName = ${JSON.stringify(doClassName)};
|
|
257059
|
-
|
|
257060
|
-
constructor(ctx, env) {
|
|
257061
|
-
return _b44ConstructActor(ctx, env, new.target);
|
|
257062
|
-
}
|
|
257063
|
-
|
|
257064
|
-
fetch(request) {
|
|
257065
|
-
return _b44RunActor(this, request, () => super.fetch(request));
|
|
257066
|
-
}
|
|
257067
|
-
|
|
257068
|
-
onConnect(...args) {
|
|
257069
|
-
return _b44RunActor(this, null, () => super.onConnect(...args));
|
|
257070
|
-
}
|
|
257071
|
-
|
|
257072
|
-
onMessage(...args) {
|
|
257073
|
-
return _b44RunActor(this, null, () => super.onMessage(...args));
|
|
257074
|
-
}
|
|
257075
|
-
|
|
257076
|
-
onClose(...args) {
|
|
257077
|
-
return _b44RunActor(this, null, () => super.onClose(...args));
|
|
257078
|
-
}
|
|
257079
|
-
|
|
257080
|
-
onAlarm(...args) {
|
|
257081
|
-
return _b44RunActor(this, null, () => super.onAlarm(...args));
|
|
257082
|
-
}
|
|
257083
|
-
|
|
257084
|
-
onStart(...args) {
|
|
257085
|
-
return _b44RunActor(this, null, () => super.onStart(...args));
|
|
257086
|
-
}
|
|
257087
|
-
|
|
257088
|
-
onError(...args) {
|
|
257089
|
-
return _b44RunActor(this, null, () => super.onError(...args));
|
|
257090
|
-
}
|
|
257091
|
-
}
|
|
257092
|
-
export default {
|
|
257093
|
-
async fetch(request, env, ctx) {
|
|
257094
|
-
const url = new URL(request.url);
|
|
257095
|
-
const parts = url.pathname.split("/");
|
|
257096
|
-
const direct = parts[1] === "rooms" && parts.length === 3;
|
|
257097
|
-
const legacy = parts[1] === "parties" && parts.length === 4;
|
|
257098
|
-
if (direct || legacy) {
|
|
257099
|
-
// Decode the room: the token was verified against the decoded instance id,
|
|
257100
|
-
// so an escaped room must map to the same Durable Object.
|
|
257101
|
-
const namespace = direct ? "${doClassName}" : parts[2];
|
|
257102
|
-
const encodedRoom = direct ? parts[2] : parts[3];
|
|
257103
|
-
let room;
|
|
257104
|
-
try { room = decodeURIComponent(encodedRoom); } catch { return new Response("Invalid room", { status: 400 }); }
|
|
257105
|
-
let actorRequest = request;
|
|
257106
|
-
if (direct || typeof env.BASE44_ACTOR_PUBLIC_KEY === "string") {
|
|
257107
|
-
const verification = await _b44VerifyActorConnection(request, env, "${doClassName}", room);
|
|
257108
|
-
if (!verification.ok) return verification.response;
|
|
257109
|
-
actorRequest = _b44AuthorizedActorRequest(
|
|
257110
|
-
request,
|
|
257111
|
-
verification.identity,
|
|
257112
|
-
"${doClassName}",
|
|
257113
|
-
room,
|
|
257114
|
-
verification.runtimeMode,
|
|
257115
|
-
);
|
|
257116
|
-
}
|
|
257117
|
-
const doNs = env["${doClassName}"];
|
|
257118
|
-
if (doNs && typeof doNs.idFromName === "function") {
|
|
257119
|
-
const stub = doNs.get(doNs.idFromName(room));
|
|
257120
|
-
const req = new Request(actorRequest);
|
|
257121
|
-
req.headers.set("x-partykit-room", room);
|
|
257122
|
-
req.headers.set("x-partykit-namespace", namespace);
|
|
257123
|
-
return stub.fetch(req);
|
|
257124
|
-
}
|
|
257125
|
-
return new Response("DO binding not found", { status: 503 });
|
|
257126
|
-
}
|
|
257127
|
-
return new Response("Not found", { status: 404 });
|
|
257128
|
-
},
|
|
257129
|
-
};
|
|
257130
|
-
`;
|
|
257131
|
-
}
|
|
257132
|
-
|
|
257133
258647
|
// ../../node_modules/zod/v3/helpers/util.js
|
|
257134
258648
|
var util;
|
|
257135
258649
|
(function(util) {
|
|
@@ -260937,7 +262451,7 @@ var nativeEnumType = ZodNativeEnum.create;
|
|
|
260937
262451
|
var promiseType = ZodPromise.create;
|
|
260938
262452
|
var effectsType = ZodEffects.create;
|
|
260939
262453
|
var optionalType = ZodOptional2.create;
|
|
260940
|
-
var
|
|
262454
|
+
var nullableType2 = ZodNullable2.create;
|
|
260941
262455
|
var preprocessType = ZodEffects.createWithPreprocess;
|
|
260942
262456
|
var pipelineType = ZodPipeline.create;
|
|
260943
262457
|
// ../functions-compiler/src/contracts.ts
|
|
@@ -260967,7 +262481,7 @@ var bundleAppRequestSchema = objectType({
|
|
|
260967
262481
|
var ACTIVATION_MODE = "pull";
|
|
260968
262482
|
|
|
260969
262483
|
// ../functions-compiler/src/deno-bundle.ts
|
|
260970
|
-
import { mkdtemp, rm, writeFile as writeFile2 } from "node:fs/promises";
|
|
262484
|
+
import { mkdtemp, rm as rm2, writeFile as writeFile2 } from "node:fs/promises";
|
|
260971
262485
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
260972
262486
|
import path21 from "node:path";
|
|
260973
262487
|
|
|
@@ -261574,7 +263088,7 @@ async function bundleToModule(prepared, nodeModulesDir = "none") {
|
|
|
261574
263088
|
warnings: result.warnings.map((w) => w.text)
|
|
261575
263089
|
};
|
|
261576
263090
|
} finally {
|
|
261577
|
-
await
|
|
263091
|
+
await rm2(dir, { recursive: true, force: true });
|
|
261578
263092
|
}
|
|
261579
263093
|
}
|
|
261580
263094
|
function buildFailureErrors(e, dir) {
|
|
@@ -261634,51 +263148,6 @@ function setSpanTags(tags) {
|
|
|
261634
263148
|
// ../functions-compiler/src/bundler.ts
|
|
261635
263149
|
var NORMALIZED_MAIN_MODULE = "_bundled.mjs";
|
|
261636
263150
|
var MAX_PARALLEL_COMPILES = 4;
|
|
261637
|
-
async function bundle(req) {
|
|
261638
|
-
let actor;
|
|
261639
|
-
try {
|
|
261640
|
-
actor = applyActorCompat(req.entry, req.files);
|
|
261641
|
-
} catch (e) {
|
|
261642
|
-
return denoCompatErrorOrThrow(e);
|
|
261643
|
-
}
|
|
261644
|
-
if (actor) {
|
|
261645
|
-
if (req.runtimeSecrets) {
|
|
261646
|
-
return denoCompatErrorOrThrow(new DenoCompatError("runtimeSecrets is not supported for Actor entries: an Actor reads secrets " + "from its Durable Object env, so it must be deployed in binding mode."));
|
|
261647
|
-
}
|
|
261648
|
-
const outcome = await installAndCompile({
|
|
261649
|
-
entry: actor.entry,
|
|
261650
|
-
files: actor.files
|
|
261651
|
-
});
|
|
261652
|
-
if (outcome.ok) {
|
|
261653
|
-
return {
|
|
261654
|
-
ok: true,
|
|
261655
|
-
module: outcome.module,
|
|
261656
|
-
main_module: NORMALIZED_MAIN_MODULE,
|
|
261657
|
-
warnings: outcome.warnings,
|
|
261658
|
-
handler_name: actor.handlerName,
|
|
261659
|
-
do_class_name: actor.doClassName
|
|
261660
|
-
};
|
|
261661
|
-
}
|
|
261662
|
-
return { ok: false, stage: outcome.stage, errors: outcome.errors };
|
|
261663
|
-
}
|
|
261664
|
-
let prepared;
|
|
261665
|
-
try {
|
|
261666
|
-
prepared = await prepareFunction(req.entry, req.files, req.postResponseTelemetry, req.runtimeSecrets);
|
|
261667
|
-
} catch (e) {
|
|
261668
|
-
return denoCompatErrorOrThrow(e);
|
|
261669
|
-
}
|
|
261670
|
-
const outcome = await installAndCompile(prepared);
|
|
261671
|
-
if (outcome.ok) {
|
|
261672
|
-
return {
|
|
261673
|
-
ok: true,
|
|
261674
|
-
module: outcome.module,
|
|
261675
|
-
main_module: NORMALIZED_MAIN_MODULE,
|
|
261676
|
-
warnings: outcome.warnings,
|
|
261677
|
-
...activationField(req.runtimeSecrets ?? false)
|
|
261678
|
-
};
|
|
261679
|
-
}
|
|
261680
|
-
return { ok: false, stage: outcome.stage, errors: outcome.errors };
|
|
261681
|
-
}
|
|
261682
263151
|
function activationField(runtimeSecrets) {
|
|
261683
263152
|
return runtimeSecrets ? { activation: ACTIVATION_MODE } : {};
|
|
261684
263153
|
}
|
|
@@ -261866,16 +263335,6 @@ async function installAndCompile(prepared) {
|
|
|
261866
263335
|
return { ok: false, stage: "esbuild", errors: result.errors };
|
|
261867
263336
|
});
|
|
261868
263337
|
}
|
|
261869
|
-
function denoCompatErrorOrThrow(e) {
|
|
261870
|
-
if (e instanceof DenoCompatError) {
|
|
261871
|
-
return {
|
|
261872
|
-
ok: false,
|
|
261873
|
-
stage: "deno_compat",
|
|
261874
|
-
errors: [denoCompatErrorItem(e)]
|
|
261875
|
-
};
|
|
261876
|
-
}
|
|
261877
|
-
throw e;
|
|
261878
|
-
}
|
|
261879
263338
|
function denoCompatErrorItem(e) {
|
|
261880
263339
|
return { message: e.message, file: e.file };
|
|
261881
263340
|
}
|
|
@@ -262078,8 +263537,6 @@ async function mapWithConcurrency2(items, limit, fn) {
|
|
|
262078
263537
|
return results;
|
|
262079
263538
|
}
|
|
262080
263539
|
// src/core/version/functions.ts
|
|
262081
|
-
import { createHash as createHash2 } from "node:crypto";
|
|
262082
|
-
import { relative as relative6 } from "node:path";
|
|
262083
263540
|
var SHARD_POLICY = {
|
|
262084
263541
|
shardSize: 100,
|
|
262085
263542
|
globalShardSize: 100,
|
|
@@ -262087,11 +263544,11 @@ var SHARD_POLICY = {
|
|
|
262087
263544
|
gzipCapBytes: 9500000
|
|
262088
263545
|
};
|
|
262089
263546
|
var COMPILE_MODES = { runtimeSecrets: false, postResponseTelemetry: false };
|
|
262090
|
-
async function requireCompilerRuntime(
|
|
263547
|
+
async function requireCompilerRuntime() {
|
|
262091
263548
|
try {
|
|
262092
263549
|
await Promise.all([import("esbuild"), import("@deno/loader")]);
|
|
262093
263550
|
} catch (error) {
|
|
262094
|
-
throw new DependencyNotFoundError(
|
|
263551
|
+
throw new DependencyNotFoundError("Backend functions cannot be compiled by this installation of the CLI.", {
|
|
262095
263552
|
hints: [{ message: "Install the CLI from npm: npm install -g base44" }],
|
|
262096
263553
|
cause: error instanceof Error ? error : undefined
|
|
262097
263554
|
});
|
|
@@ -262148,97 +263605,6 @@ async function compileBackendBundles(root, functionsDir) {
|
|
|
262148
263605
|
});
|
|
262149
263606
|
}
|
|
262150
263607
|
|
|
262151
|
-
// src/core/version/actors.ts
|
|
262152
|
-
var MAX_ACTORS = 50;
|
|
262153
|
-
var COMPILE_CONCURRENCY = 4;
|
|
262154
|
-
var ACTORS_ROOT = "base44/actors";
|
|
262155
|
-
var SHARED_ROOT = "base44/shared";
|
|
262156
|
-
function forwardSlashed(from, to) {
|
|
262157
|
-
return relative7(from, to).split(/[/\\]/).join("/");
|
|
262158
|
-
}
|
|
262159
|
-
async function readSharedFiles2(actorsDir) {
|
|
262160
|
-
const sharedDir = resolve13(actorsDir, "..", "shared");
|
|
262161
|
-
if (!await pathExists(sharedDir)) {
|
|
262162
|
-
return {};
|
|
262163
|
-
}
|
|
262164
|
-
const paths = await globby(BACKEND_FILE_GLOB, {
|
|
262165
|
-
cwd: sharedDir,
|
|
262166
|
-
absolute: true
|
|
262167
|
-
});
|
|
262168
|
-
const files = {};
|
|
262169
|
-
for (const path of paths.sort()) {
|
|
262170
|
-
files[`${SHARED_ROOT}/${forwardSlashed(sharedDir, path)}`] = await readTextFile(path);
|
|
262171
|
-
}
|
|
262172
|
-
return files;
|
|
262173
|
-
}
|
|
262174
|
-
async function compilerInput2(actor, shared) {
|
|
262175
|
-
const actorDir = dirname22(actor.entryPath);
|
|
262176
|
-
const entry = `${ACTORS_ROOT}/${actor.name}/entry.ts`;
|
|
262177
|
-
const source = await readTextFile(actor.entryPath);
|
|
262178
|
-
const candidates = { ...shared };
|
|
262179
|
-
for (const filePath of actor.filePaths) {
|
|
262180
|
-
if (filePath !== actor.entryPath) {
|
|
262181
|
-
candidates[`${ACTORS_ROOT}/${actor.name}/${forwardSlashed(actorDir, filePath)}`] = await readTextFile(filePath);
|
|
262182
|
-
}
|
|
262183
|
-
}
|
|
262184
|
-
candidates[entry] = source;
|
|
262185
|
-
return {
|
|
262186
|
-
entry,
|
|
262187
|
-
files: await collectReachableFiles(entry, candidates),
|
|
262188
|
-
source
|
|
262189
|
-
};
|
|
262190
|
-
}
|
|
262191
|
-
async function compileActors(actorsDir) {
|
|
262192
|
-
const actors = await readAllActors(actorsDir);
|
|
262193
|
-
if (actors.length === 0) {
|
|
262194
|
-
return [];
|
|
262195
|
-
}
|
|
262196
|
-
if (actors.length > MAX_ACTORS) {
|
|
262197
|
-
throw new InvalidInputError(`Too many actors: found ${actors.length}, the limit is ${MAX_ACTORS}.`);
|
|
262198
|
-
}
|
|
262199
|
-
await requireCompilerRuntime("Actors");
|
|
262200
|
-
const shared = await readSharedFiles2(actorsDir);
|
|
262201
|
-
const sorted = [...actors].sort((a, b) => a.name < b.name ? -1 : 1);
|
|
262202
|
-
const compiled = await pMap(sorted, async (actor) => {
|
|
262203
|
-
const input = await compilerInput2(actor, shared);
|
|
262204
|
-
const result = await bundle({ entry: input.entry, files: input.files });
|
|
262205
|
-
return {
|
|
262206
|
-
name: actor.name,
|
|
262207
|
-
entry: input.entry,
|
|
262208
|
-
source: input.source,
|
|
262209
|
-
result
|
|
262210
|
-
};
|
|
262211
|
-
}, { concurrency: COMPILE_CONCURRENCY });
|
|
262212
|
-
const failures = compiled.flatMap(({ name, result }) => result.ok ? [] : [
|
|
262213
|
-
{
|
|
262214
|
-
function: name,
|
|
262215
|
-
message: `Actor "${name}" failed to compile.`,
|
|
262216
|
-
errors: result.errors
|
|
262217
|
-
}
|
|
262218
|
-
]);
|
|
262219
|
-
if (failures.length > 0) {
|
|
262220
|
-
throw new InvalidInputError(`Actors failed to compile (${failures.length} error${failures.length === 1 ? "" : "s"}).`, { details: failures.map(describeFailure) });
|
|
262221
|
-
}
|
|
262222
|
-
return compiled.map(({ name, entry, source, result }) => {
|
|
262223
|
-
const module = new TextEncoder().encode(compiledModule(name, result));
|
|
262224
|
-
return {
|
|
262225
|
-
name,
|
|
262226
|
-
entry,
|
|
262227
|
-
source,
|
|
262228
|
-
module,
|
|
262229
|
-
size: module.byteLength,
|
|
262230
|
-
digest: sha256(module),
|
|
262231
|
-
staticEgress: STATIC_EGRESS_ARTIFACT_MARKER
|
|
262232
|
-
};
|
|
262233
|
-
});
|
|
262234
|
-
}
|
|
262235
|
-
function compiledModule(name, result) {
|
|
262236
|
-
if (!result.ok || result.do_class_name !== name) {
|
|
262237
|
-
throw new InternalError(`Actor "${name}" did not compile as an actor of that name.`);
|
|
262238
|
-
}
|
|
262239
|
-
return result.module;
|
|
262240
|
-
}
|
|
262241
|
-
|
|
262242
263608
|
// src/core/version/publish.ts
|
|
262243
263609
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
262244
263610
|
var DEFAULT_ENVIRONMENT = "production";
|
|
@@ -262291,7 +263657,7 @@ async function collectBuildOutput(outputDir, options = {}) {
|
|
|
262291
263657
|
}
|
|
262292
263658
|
async function describeSiteWorker(built) {
|
|
262293
263659
|
const { config, modules } = built;
|
|
262294
|
-
const entry =
|
|
263660
|
+
const entry = resolve13(config.configDir, config.main);
|
|
262295
263661
|
const main = modules.find((m) => m.absolutePath === entry)?.name;
|
|
262296
263662
|
if (!main) {
|
|
262297
263663
|
throw new InvalidInputError(`The Worker's entry module ${config.main} is not among the ${modules.length} modules collected from ${config.configDir}.`);
|
|
@@ -262322,14 +263688,14 @@ async function readRawResources(dir) {
|
|
|
262322
263688
|
const payloads = {};
|
|
262323
263689
|
for (const relativePath of files.sort()) {
|
|
262324
263690
|
const name = relativePath.replace(/\.jsonc?$/, "");
|
|
262325
|
-
payloads[name] = await readJsonFile(
|
|
263691
|
+
payloads[name] = await readJsonFile(join31(dir, ...relativePath.split("/")));
|
|
262326
263692
|
}
|
|
262327
263693
|
return payloads;
|
|
262328
263694
|
}
|
|
262329
263695
|
async function collectResources(configDir, dirs) {
|
|
262330
263696
|
const [entities, agents] = await Promise.all([
|
|
262331
|
-
readRawResources(
|
|
262332
|
-
readRawResources(
|
|
263697
|
+
readRawResources(join31(configDir, dirs.entitiesDir)),
|
|
263698
|
+
readRawResources(join31(configDir, dirs.agentsDir))
|
|
262333
263699
|
]);
|
|
262334
263700
|
return { entities, agents };
|
|
262335
263701
|
}
|
|
@@ -262341,8 +263707,7 @@ async function collectArtifacts(target) {
|
|
|
262341
263707
|
entryFile: ENTRY2
|
|
262342
263708
|
}),
|
|
262343
263709
|
...siteWorker ? { siteWorker } : {},
|
|
262344
|
-
backendBundles: await tagStep2("build", () => compileBackendBundles(target.root,
|
|
262345
|
-
actors: await tagStep2("build", () => compileActors(join29(target.configDir, target.actorsDir))),
|
|
263710
|
+
backendBundles: await tagStep2("build", () => compileBackendBundles(target.root, join31(target.configDir, target.functionsDir))),
|
|
262346
263711
|
...await collectResources(target.configDir, target)
|
|
262347
263712
|
};
|
|
262348
263713
|
}
|
|
@@ -262559,7 +263924,7 @@ function writeFile3(appId, params) {
|
|
|
262559
263924
|
function editFile(appId, params) {
|
|
262560
263925
|
return callTool(appId, "edit_file", { ...params }, EditFileResponseSchema, `editing file "${params.path}"`);
|
|
262561
263926
|
}
|
|
262562
|
-
function
|
|
263927
|
+
function grep2(appId, params) {
|
|
262563
263928
|
return callTool(appId, "grep", { ...params }, GrepResponseSchema, "searching files");
|
|
262564
263929
|
}
|
|
262565
263930
|
function runCommand(appId, params) {
|
|
@@ -262663,10 +264028,10 @@ Examples:
|
|
|
262663
264028
|
}
|
|
262664
264029
|
|
|
262665
264030
|
// src/cli/commands/sandbox/grep.ts
|
|
262666
|
-
async function
|
|
264031
|
+
async function grepAction2({ runTask, branchId }, pattern, options) {
|
|
262667
264032
|
const { id: appId } = getAppContext();
|
|
262668
264033
|
const maxResults = parsePositiveInt(options.maxResults, "--max-results");
|
|
262669
|
-
const result = await runTask("Searching files", () =>
|
|
264034
|
+
const result = await runTask("Searching files", () => grep2(appId, {
|
|
262670
264035
|
pattern,
|
|
262671
264036
|
path: options.path,
|
|
262672
264037
|
is_regex: options.regex,
|
|
@@ -262678,7 +264043,7 @@ async function grepAction({ runTask, branchId }, pattern, options) {
|
|
|
262678
264043
|
return { outroMessage: "Searched files", stdout: toJsonStdout(result) };
|
|
262679
264044
|
}
|
|
262680
264045
|
function getSandboxGrepCommand() {
|
|
262681
|
-
return new Base44Command("grep", { supportsBranch: true }).description("Search files for a pattern in an app's remote sandbox").argument("<pattern>", "Search pattern").option("--path <path>", "Subtree to search, relative to the app root").option("--no-regex", "Treat the pattern as a literal string, not a regex").option("--case-sensitive", "Case-sensitive match").option("--glob <glob>", 'File glob filter, e.g. "*.tsx"').option("--max-results <n>", "Maximum number of match lines to return").action(
|
|
264046
|
+
return new Base44Command("grep", { supportsBranch: true }).description("Search files for a pattern in an app's remote sandbox").argument("<pattern>", "Search pattern").option("--path <path>", "Subtree to search, relative to the app root").option("--no-regex", "Treat the pattern as a literal string, not a regex").option("--case-sensitive", "Case-sensitive match").option("--glob <glob>", 'File glob filter, e.g. "*.tsx"').option("--max-results <n>", "Maximum number of match lines to return").action(grepAction2);
|
|
262682
264047
|
}
|
|
262683
264048
|
|
|
262684
264049
|
// src/cli/commands/sandbox/list-directory.ts
|
|
@@ -262800,7 +264165,7 @@ function getSecretsListCommand() {
|
|
|
262800
264165
|
}
|
|
262801
264166
|
|
|
262802
264167
|
// src/cli/commands/secrets/set.ts
|
|
262803
|
-
import { resolve as
|
|
264168
|
+
import { resolve as resolve14 } from "node:path";
|
|
262804
264169
|
function parseEntries(entries) {
|
|
262805
264170
|
const secrets = {};
|
|
262806
264171
|
for (const entry of entries) {
|
|
@@ -262831,7 +264196,7 @@ async function setSecretsAction({ log, runTask }, entries, options) {
|
|
|
262831
264196
|
validateInput(entries, options);
|
|
262832
264197
|
let secrets;
|
|
262833
264198
|
if (options.envFile) {
|
|
262834
|
-
secrets = await parseEnvFile(
|
|
264199
|
+
secrets = await parseEnvFile(resolve14(options.envFile));
|
|
262835
264200
|
if (Object.keys(secrets).length === 0) {
|
|
262836
264201
|
throw new InvalidInputError("The env file contains no valid KEY=VALUE entries.");
|
|
262837
264202
|
}
|
|
@@ -262859,8 +264224,512 @@ function getSecretsCommand() {
|
|
|
262859
264224
|
return new Command2("secrets").description("Manage project secrets (environment variables)").addCommand(getSecretsListCommand()).addCommand(getSecretsSetCommand()).addCommand(getSecretsDeleteCommand());
|
|
262860
264225
|
}
|
|
262861
264226
|
|
|
264227
|
+
// src/cli/commands/session/import.ts
|
|
264228
|
+
var import_ms2 = __toESM(require_ms(), 1);
|
|
264229
|
+
|
|
264230
|
+
// src/core/session-import/transcript.ts
|
|
264231
|
+
import { gzipSync } from "node:zlib";
|
|
264232
|
+
var SESSION_SOURCE_LABELS = {
|
|
264233
|
+
claude_code: "Claude Code",
|
|
264234
|
+
codex: "Codex"
|
|
264235
|
+
};
|
|
264236
|
+
var MAX_TURNS = 120;
|
|
264237
|
+
var MAX_CHARS_PER_TURN = 4000;
|
|
264238
|
+
var MAX_TOTAL_CHARS = 1e5;
|
|
264239
|
+
var TRUNCATION_MARK = " … [truncated]";
|
|
264240
|
+
function parseJsonObject(line) {
|
|
264241
|
+
if (line[0] !== "{")
|
|
264242
|
+
return;
|
|
264243
|
+
try {
|
|
264244
|
+
const parsed = JSON.parse(line);
|
|
264245
|
+
return typeof parsed === "object" && parsed !== null ? parsed : undefined;
|
|
264246
|
+
} catch {
|
|
264247
|
+
return;
|
|
264248
|
+
}
|
|
264249
|
+
}
|
|
264250
|
+
function stringField(object, key) {
|
|
264251
|
+
const value = object[key];
|
|
264252
|
+
return typeof value === "string" && value !== "" ? value : undefined;
|
|
264253
|
+
}
|
|
264254
|
+
function objectField(object, key) {
|
|
264255
|
+
const value = object[key];
|
|
264256
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
|
|
264257
|
+
}
|
|
264258
|
+
function contentText(content) {
|
|
264259
|
+
if (typeof content === "string")
|
|
264260
|
+
return content.trim();
|
|
264261
|
+
if (!Array.isArray(content))
|
|
264262
|
+
return "";
|
|
264263
|
+
return content.map((block) => typeof block === "object" && block !== null && typeof block.text === "string" ? block.text : "").filter((text) => text !== "").join(`
|
|
264264
|
+
`).trim();
|
|
264265
|
+
}
|
|
264266
|
+
function conversationTurn(role, content) {
|
|
264267
|
+
const text = contentText(content);
|
|
264268
|
+
return text === "" || text.startsWith("<") || text.startsWith(INTERRUPT_MARKER) ? undefined : { role, text };
|
|
264269
|
+
}
|
|
264270
|
+
var NOT_CONVERSATION_FLAGS = [
|
|
264271
|
+
"isMeta",
|
|
264272
|
+
"isSidechain",
|
|
264273
|
+
"isCompactSummary",
|
|
264274
|
+
"isVisibleInTranscriptOnly",
|
|
264275
|
+
"isApiErrorMessage"
|
|
264276
|
+
];
|
|
264277
|
+
var INTERRUPT_MARKER = "[Request interrupted by user";
|
|
264278
|
+
var SLASH_COMMAND_NAME = /<command-name>([^<]*)<\/command-name>/;
|
|
264279
|
+
var SLASH_COMMAND_ARGS = /<command-args>([^<]*)<\/command-args>/;
|
|
264280
|
+
function slashCommandText(text) {
|
|
264281
|
+
const name = SLASH_COMMAND_NAME.exec(text)?.[1]?.trim();
|
|
264282
|
+
if (!name)
|
|
264283
|
+
return;
|
|
264284
|
+
const args = SLASH_COMMAND_ARGS.exec(text)?.[1]?.trim();
|
|
264285
|
+
return args ? `${name} ${args}` : name;
|
|
264286
|
+
}
|
|
264287
|
+
function claudeTurnFromLine(line) {
|
|
264288
|
+
const type = stringField(line, "type");
|
|
264289
|
+
if (type !== "user" && type !== "assistant")
|
|
264290
|
+
return;
|
|
264291
|
+
if (NOT_CONVERSATION_FLAGS.some((flag) => line[flag] === true)) {
|
|
264292
|
+
return;
|
|
264293
|
+
}
|
|
264294
|
+
const message = objectField(line, "message");
|
|
264295
|
+
if (message?.model === "<synthetic>")
|
|
264296
|
+
return;
|
|
264297
|
+
const content = message?.content;
|
|
264298
|
+
const command = type === "user" ? slashCommandText(contentText(content)) : undefined;
|
|
264299
|
+
return command ? { role: "user", text: command } : conversationTurn(type, content);
|
|
264300
|
+
}
|
|
264301
|
+
var CODEX_INJECTED_USER_ITEM = /^\s*(<(recommended_plugins|environment_context|user_instructions)>|# AGENTS\.md instructions for )/;
|
|
264302
|
+
function codexTurnFromLine(line) {
|
|
264303
|
+
if (stringField(line, "type") !== "response_item")
|
|
264304
|
+
return;
|
|
264305
|
+
const payload = objectField(line, "payload");
|
|
264306
|
+
if (payload === undefined || payload.type !== "message")
|
|
264307
|
+
return;
|
|
264308
|
+
const role = payload.role;
|
|
264309
|
+
if (role !== "user" && role !== "assistant")
|
|
264310
|
+
return;
|
|
264311
|
+
const turn = conversationTurn(role, payload.content);
|
|
264312
|
+
if (turn?.role === "user" && CODEX_INJECTED_USER_ITEM.test(turn.text)) {
|
|
264313
|
+
return;
|
|
264314
|
+
}
|
|
264315
|
+
return turn;
|
|
264316
|
+
}
|
|
264317
|
+
function mergeConsecutiveRoles(turns) {
|
|
264318
|
+
const merged = [];
|
|
264319
|
+
for (const turn of turns) {
|
|
264320
|
+
const last = merged.at(-1);
|
|
264321
|
+
if (last?.role === turn.role) {
|
|
264322
|
+
last.text = `${last.text}
|
|
264323
|
+
|
|
264324
|
+
${turn.text}`;
|
|
264325
|
+
} else {
|
|
264326
|
+
merged.push({ ...turn });
|
|
264327
|
+
}
|
|
264328
|
+
}
|
|
264329
|
+
return merged;
|
|
264330
|
+
}
|
|
264331
|
+
function cut(text, maxChars) {
|
|
264332
|
+
const end = text.charCodeAt(maxChars - 1);
|
|
264333
|
+
return text.slice(0, end >= 55296 && end <= 56319 ? maxChars - 1 : maxChars);
|
|
264334
|
+
}
|
|
264335
|
+
function clip(text, maxChars) {
|
|
264336
|
+
return text.length <= maxChars ? text : cut(text, maxChars - TRUNCATION_MARK.length) + TRUNCATION_MARK;
|
|
264337
|
+
}
|
|
264338
|
+
function prepareTranscript(source) {
|
|
264339
|
+
const merged = mergeConsecutiveRoles(source).map((turn) => ({
|
|
264340
|
+
role: turn.role,
|
|
264341
|
+
text: clip(turn.text, MAX_CHARS_PER_TURN)
|
|
264342
|
+
}));
|
|
264343
|
+
let kept = merged.slice(-MAX_TURNS);
|
|
264344
|
+
let total = kept.reduce((sum, turn) => sum + turn.text.length, 0);
|
|
264345
|
+
while (kept.length > 1 && total > MAX_TOTAL_CHARS) {
|
|
264346
|
+
total -= kept[0]?.text.length ?? 0;
|
|
264347
|
+
kept = kept.slice(1);
|
|
264348
|
+
}
|
|
264349
|
+
const droppedTurns = merged.length - kept.length;
|
|
264350
|
+
const firstUser = kept.findIndex((turn) => turn.role === "user");
|
|
264351
|
+
return {
|
|
264352
|
+
turns: firstUser === -1 ? [] : kept.slice(firstUser),
|
|
264353
|
+
droppedTurns
|
|
264354
|
+
};
|
|
264355
|
+
}
|
|
264356
|
+
function encodeTurns(turns) {
|
|
264357
|
+
return gzipSync(JSON.stringify(turns), { level: 9 }).toString("base64");
|
|
264358
|
+
}
|
|
264359
|
+
|
|
264360
|
+
// src/core/session-import/api.ts
|
|
264361
|
+
var ImportResponseSchema = object({ branch_id: string2().min(1), branch_name: string2().min(1) }).transform((data) => ({
|
|
264362
|
+
branchId: data.branch_id,
|
|
264363
|
+
branchName: data.branch_name
|
|
264364
|
+
}));
|
|
264365
|
+
function withoutTranscript(error) {
|
|
264366
|
+
if (error instanceof HTTPError) {
|
|
264367
|
+
delete error.options.context.__requestBody;
|
|
264368
|
+
}
|
|
264369
|
+
return error;
|
|
264370
|
+
}
|
|
264371
|
+
function withUnavailableHint(error) {
|
|
264372
|
+
if (error.statusCode !== 404)
|
|
264373
|
+
return error;
|
|
264374
|
+
return new ApiError(error.message, {
|
|
264375
|
+
statusCode: error.statusCode,
|
|
264376
|
+
requestUrl: error.requestUrl,
|
|
264377
|
+
requestMethod: error.requestMethod,
|
|
264378
|
+
responseBody: error.responseBody,
|
|
264379
|
+
requestId: error.requestId,
|
|
264380
|
+
details: error.details,
|
|
264381
|
+
hints: [
|
|
264382
|
+
{
|
|
264383
|
+
message: "Session import works on apps imported from a repository, and needs early access on your account. Check the app id."
|
|
264384
|
+
}
|
|
264385
|
+
],
|
|
264386
|
+
cause: error
|
|
264387
|
+
});
|
|
264388
|
+
}
|
|
264389
|
+
async function importSession(params) {
|
|
264390
|
+
let response;
|
|
264391
|
+
try {
|
|
264392
|
+
response = await getAppClient().post("imported/session-imports", {
|
|
264393
|
+
json: {
|
|
264394
|
+
source: params.source,
|
|
264395
|
+
source_session_id: params.sessionId,
|
|
264396
|
+
title: params.title,
|
|
264397
|
+
turns_gzip_base64: encodeTurns(params.turns)
|
|
264398
|
+
},
|
|
264399
|
+
timeout: 60000
|
|
264400
|
+
});
|
|
264401
|
+
} catch (error) {
|
|
264402
|
+
throw withUnavailableHint(await ApiError.fromHttpError(withoutTranscript(error), "importing session"));
|
|
264403
|
+
}
|
|
264404
|
+
const result = ImportResponseSchema.safeParse(await response.json());
|
|
264405
|
+
if (!result.success) {
|
|
264406
|
+
throw new SchemaValidationError("Invalid session import response from server", result.error);
|
|
264407
|
+
}
|
|
264408
|
+
return { ...result.data, created: response.status === 201 };
|
|
264409
|
+
}
|
|
264410
|
+
// src/core/session-import/sessions.ts
|
|
264411
|
+
import { createReadStream as createReadStream3 } from "node:fs";
|
|
264412
|
+
import { readdir as readdir2, realpath, stat as stat4 } from "node:fs/promises";
|
|
264413
|
+
import { homedir as homedir4 } from "node:os";
|
|
264414
|
+
import { join as join32, sep as sep2 } from "node:path";
|
|
264415
|
+
import { createInterface as createInterface2 } from "node:readline";
|
|
264416
|
+
function defaultSessionRoots() {
|
|
264417
|
+
const claudeHome = process.env.CLAUDE_CONFIG_DIR ?? join32(homedir4(), ".claude");
|
|
264418
|
+
return {
|
|
264419
|
+
claudeProjectsDir: join32(claudeHome, "projects"),
|
|
264420
|
+
codexHome: process.env.CODEX_HOME ?? join32(homedir4(), ".codex")
|
|
264421
|
+
};
|
|
264422
|
+
}
|
|
264423
|
+
var CODEX_ROLLOUT_FILE = /^rollout-.*-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/;
|
|
264424
|
+
var MAX_TITLE_CHARS = 80;
|
|
264425
|
+
async function forEachJsonObject(filePath, onObject) {
|
|
264426
|
+
const stream = createReadStream3(filePath, { encoding: "utf8" });
|
|
264427
|
+
const lines = createInterface2({
|
|
264428
|
+
input: stream,
|
|
264429
|
+
crlfDelay: Number.POSITIVE_INFINITY
|
|
264430
|
+
});
|
|
264431
|
+
try {
|
|
264432
|
+
for await (const line of lines) {
|
|
264433
|
+
const object = parseJsonObject(line);
|
|
264434
|
+
if (object && onObject(object) === false)
|
|
264435
|
+
break;
|
|
264436
|
+
}
|
|
264437
|
+
} finally {
|
|
264438
|
+
lines.close();
|
|
264439
|
+
stream.destroy();
|
|
264440
|
+
}
|
|
264441
|
+
}
|
|
264442
|
+
async function listDir(dir) {
|
|
264443
|
+
try {
|
|
264444
|
+
return await readdir2(dir, { withFileTypes: true });
|
|
264445
|
+
} catch {
|
|
264446
|
+
return [];
|
|
264447
|
+
}
|
|
264448
|
+
}
|
|
264449
|
+
async function withMtime(files) {
|
|
264450
|
+
const stamped = await Promise.all(files.map(async (file) => {
|
|
264451
|
+
try {
|
|
264452
|
+
return { ...file, updatedAtMs: (await stat4(file.filePath)).mtimeMs };
|
|
264453
|
+
} catch {
|
|
264454
|
+
return;
|
|
264455
|
+
}
|
|
264456
|
+
}));
|
|
264457
|
+
return stamped.filter((file) => file !== undefined);
|
|
264458
|
+
}
|
|
264459
|
+
function oneLine(text) {
|
|
264460
|
+
const flat = text.replace(/\s+/g, " ").trim();
|
|
264461
|
+
return flat.length <= MAX_TITLE_CHARS ? flat : `${cut(flat, MAX_TITLE_CHARS - 1)}…`;
|
|
264462
|
+
}
|
|
264463
|
+
function claudeAdapter(projectsDir) {
|
|
264464
|
+
return {
|
|
264465
|
+
async files() {
|
|
264466
|
+
const found = [];
|
|
264467
|
+
for (const project of await listDir(projectsDir)) {
|
|
264468
|
+
if (!project.isDirectory())
|
|
264469
|
+
continue;
|
|
264470
|
+
const projectDir = join32(projectsDir, project.name);
|
|
264471
|
+
for (const entry of await listDir(projectDir)) {
|
|
264472
|
+
if (entry.isFile() && entry.name.endsWith(".jsonl")) {
|
|
264473
|
+
found.push({
|
|
264474
|
+
source: "claude_code",
|
|
264475
|
+
id: entry.name.slice(0, -".jsonl".length),
|
|
264476
|
+
filePath: join32(projectDir, entry.name)
|
|
264477
|
+
});
|
|
264478
|
+
}
|
|
264479
|
+
}
|
|
264480
|
+
}
|
|
264481
|
+
return withMtime(found);
|
|
264482
|
+
},
|
|
264483
|
+
async head(filePath) {
|
|
264484
|
+
let cwd;
|
|
264485
|
+
await forEachJsonObject(filePath, (line) => {
|
|
264486
|
+
cwd = stringField(line, "cwd");
|
|
264487
|
+
return cwd === undefined;
|
|
264488
|
+
});
|
|
264489
|
+
return { cwd };
|
|
264490
|
+
},
|
|
264491
|
+
async read(file) {
|
|
264492
|
+
const turns = [];
|
|
264493
|
+
let cwd;
|
|
264494
|
+
let customTitle;
|
|
264495
|
+
let aiTitle;
|
|
264496
|
+
let summary;
|
|
264497
|
+
await forEachJsonObject(file.filePath, (line) => {
|
|
264498
|
+
const type = stringField(line, "type");
|
|
264499
|
+
if (type === "custom-title") {
|
|
264500
|
+
customTitle = stringField(line, "customTitle") ?? customTitle;
|
|
264501
|
+
} else if (type === "ai-title") {
|
|
264502
|
+
aiTitle = stringField(line, "aiTitle") ?? aiTitle;
|
|
264503
|
+
} else if (type === "summary") {
|
|
264504
|
+
summary = stringField(line, "summary") ?? summary;
|
|
264505
|
+
} else {
|
|
264506
|
+
cwd ??= stringField(line, "cwd");
|
|
264507
|
+
const turn = claudeTurnFromLine(line);
|
|
264508
|
+
if (turn)
|
|
264509
|
+
turns.push(turn);
|
|
264510
|
+
}
|
|
264511
|
+
return;
|
|
264512
|
+
});
|
|
264513
|
+
return { cwd, title: customTitle ?? aiTitle ?? summary, turns };
|
|
264514
|
+
}
|
|
264515
|
+
};
|
|
264516
|
+
}
|
|
264517
|
+
function codexAdapter(codexHome) {
|
|
264518
|
+
const sessionsDir = join32(codexHome, "sessions");
|
|
264519
|
+
const titleOf = async (id) => {
|
|
264520
|
+
let title;
|
|
264521
|
+
try {
|
|
264522
|
+
await forEachJsonObject(join32(codexHome, "session_index.jsonl"), (line) => {
|
|
264523
|
+
if (stringField(line, "id") === id) {
|
|
264524
|
+
title = stringField(line, "thread_name") ?? title;
|
|
264525
|
+
}
|
|
264526
|
+
return;
|
|
264527
|
+
});
|
|
264528
|
+
} catch {}
|
|
264529
|
+
return title;
|
|
264530
|
+
};
|
|
264531
|
+
return {
|
|
264532
|
+
async files() {
|
|
264533
|
+
const found = [];
|
|
264534
|
+
for (const year of await listDir(sessionsDir)) {
|
|
264535
|
+
for (const month of await listDir(join32(sessionsDir, year.name))) {
|
|
264536
|
+
const monthDir = join32(sessionsDir, year.name, month.name);
|
|
264537
|
+
for (const day of await listDir(monthDir)) {
|
|
264538
|
+
const dayDir = join32(monthDir, day.name);
|
|
264539
|
+
for (const entry of await listDir(dayDir)) {
|
|
264540
|
+
const id = CODEX_ROLLOUT_FILE.exec(entry.name)?.[1];
|
|
264541
|
+
if (id && entry.isFile()) {
|
|
264542
|
+
found.push({
|
|
264543
|
+
source: "codex",
|
|
264544
|
+
id,
|
|
264545
|
+
filePath: join32(dayDir, entry.name)
|
|
264546
|
+
});
|
|
264547
|
+
}
|
|
264548
|
+
}
|
|
264549
|
+
}
|
|
264550
|
+
}
|
|
264551
|
+
}
|
|
264552
|
+
return withMtime(found);
|
|
264553
|
+
},
|
|
264554
|
+
async head(filePath) {
|
|
264555
|
+
const head = {};
|
|
264556
|
+
await forEachJsonObject(filePath, (line) => {
|
|
264557
|
+
const payload = objectField(line, "payload");
|
|
264558
|
+
if (stringField(line, "type") !== "session_meta" || !payload) {
|
|
264559
|
+
return true;
|
|
264560
|
+
}
|
|
264561
|
+
head.cwd = stringField(payload, "cwd");
|
|
264562
|
+
const source = payload.source;
|
|
264563
|
+
head.skip = typeof source !== "string" || source === "exec";
|
|
264564
|
+
return false;
|
|
264565
|
+
});
|
|
264566
|
+
return head;
|
|
264567
|
+
},
|
|
264568
|
+
async read(file) {
|
|
264569
|
+
const turns = [];
|
|
264570
|
+
let cwd;
|
|
264571
|
+
await forEachJsonObject(file.filePath, (line) => {
|
|
264572
|
+
const payload = objectField(line, "payload");
|
|
264573
|
+
if (stringField(line, "type") === "session_meta" && payload) {
|
|
264574
|
+
cwd ??= stringField(payload, "cwd");
|
|
264575
|
+
}
|
|
264576
|
+
const turn = codexTurnFromLine(line);
|
|
264577
|
+
if (turn)
|
|
264578
|
+
turns.push(turn);
|
|
264579
|
+
return;
|
|
264580
|
+
});
|
|
264581
|
+
return { cwd, title: await titleOf(file.id), turns };
|
|
264582
|
+
}
|
|
264583
|
+
};
|
|
264584
|
+
}
|
|
264585
|
+
function adapters(roots) {
|
|
264586
|
+
return [
|
|
264587
|
+
claudeAdapter(roots.claudeProjectsDir),
|
|
264588
|
+
codexAdapter(roots.codexHome)
|
|
264589
|
+
];
|
|
264590
|
+
}
|
|
264591
|
+
async function describe2(adapter, file) {
|
|
264592
|
+
const content = await adapter.read(file);
|
|
264593
|
+
const firstPrompt = content.turns.find((turn) => turn.role === "user")?.text;
|
|
264594
|
+
const title = oneLine(content.title ?? firstPrompt ?? "");
|
|
264595
|
+
if (content.turns.length === 0 || title === "")
|
|
264596
|
+
return;
|
|
264597
|
+
return {
|
|
264598
|
+
session: {
|
|
264599
|
+
source: file.source,
|
|
264600
|
+
id: file.id,
|
|
264601
|
+
title,
|
|
264602
|
+
cwd: content.cwd,
|
|
264603
|
+
filePath: file.filePath,
|
|
264604
|
+
updatedAtMs: file.updatedAtMs
|
|
264605
|
+
},
|
|
264606
|
+
turns: content.turns
|
|
264607
|
+
};
|
|
264608
|
+
}
|
|
264609
|
+
async function isWithin(cwd, dir) {
|
|
264610
|
+
const roots = new Set([dir, await realpath(dir).catch(() => dir)]);
|
|
264611
|
+
const places = new Set([cwd, await realpath(cwd).catch(() => cwd)]);
|
|
264612
|
+
return [...roots].some((root) => [...places].some((place) => place === root || place.startsWith(root + sep2)));
|
|
264613
|
+
}
|
|
264614
|
+
async function listSessions(roots, { within, limit }) {
|
|
264615
|
+
const found = [];
|
|
264616
|
+
const files = (await Promise.all(adapters(roots).map(async (adapter) => (await adapter.files()).map((file) => ({ adapter, file }))))).flat().sort((a, b) => b.file.updatedAtMs - a.file.updatedAtMs);
|
|
264617
|
+
for (const { adapter, file } of files) {
|
|
264618
|
+
if (found.length >= limit)
|
|
264619
|
+
break;
|
|
264620
|
+
const head = await adapter.head(file.filePath).catch(() => ({ skip: true }));
|
|
264621
|
+
if (head.skip)
|
|
264622
|
+
continue;
|
|
264623
|
+
if (within && (!head.cwd || !await isWithin(head.cwd, within)))
|
|
264624
|
+
continue;
|
|
264625
|
+
const described = await describe2(adapter, file).catch(() => {
|
|
264626
|
+
return;
|
|
264627
|
+
});
|
|
264628
|
+
if (described)
|
|
264629
|
+
found.push(described.session);
|
|
264630
|
+
}
|
|
264631
|
+
return found;
|
|
264632
|
+
}
|
|
264633
|
+
async function readSessionById(roots, id) {
|
|
264634
|
+
for (const adapter of adapters(roots)) {
|
|
264635
|
+
const file = (await adapter.files()).find((candidate) => candidate.id === id);
|
|
264636
|
+
if (!file)
|
|
264637
|
+
continue;
|
|
264638
|
+
try {
|
|
264639
|
+
return await describe2(adapter, file);
|
|
264640
|
+
} catch (error) {
|
|
264641
|
+
throw new FileReadError(`Failed to read session file ${file.filePath}: ${error instanceof Error ? error.message : "Unknown error"}`, { cause: error instanceof Error ? error : undefined });
|
|
264642
|
+
}
|
|
264643
|
+
}
|
|
264644
|
+
return;
|
|
264645
|
+
}
|
|
264646
|
+
// src/cli/commands/session/import.ts
|
|
264647
|
+
var PICKER_LIMIT = 30;
|
|
264648
|
+
async function pickSession(all) {
|
|
264649
|
+
const within = all ? undefined : await findGitRoot2() ?? process.cwd();
|
|
264650
|
+
const sessions = await listSessions(defaultSessionRoots(), {
|
|
264651
|
+
within,
|
|
264652
|
+
limit: PICKER_LIMIT
|
|
264653
|
+
});
|
|
264654
|
+
if (sessions.length === 0) {
|
|
264655
|
+
throw new InvalidInputError(all ? "No Claude Code or Codex sessions found on this machine." : "No Claude Code or Codex sessions found for this repository. Pass --all to list sessions from every directory, or --session <id>.");
|
|
264656
|
+
}
|
|
264657
|
+
const choice = await Je({
|
|
264658
|
+
message: "Which session do you want to continue in Base Code?",
|
|
264659
|
+
options: sessions.map((session) => ({
|
|
264660
|
+
value: session,
|
|
264661
|
+
label: session.title,
|
|
264662
|
+
hint: `${SESSION_SOURCE_LABELS[session.source]}, ${import_ms2.default(Date.now() - session.updatedAtMs)} ago`
|
|
264663
|
+
}))
|
|
264664
|
+
});
|
|
264665
|
+
if (Ct(choice)) {
|
|
264666
|
+
Ne("Operation cancelled.");
|
|
264667
|
+
throw new CLIExitError(0);
|
|
264668
|
+
}
|
|
264669
|
+
return choice.id;
|
|
264670
|
+
}
|
|
264671
|
+
async function importSessionAction(ctx, options) {
|
|
264672
|
+
const { log, runTask, jsonMode } = ctx;
|
|
264673
|
+
const interactive = !ctx.isNonInteractive && !jsonMode;
|
|
264674
|
+
const appId = requireApp(ctx).id;
|
|
264675
|
+
if (!options.session && !interactive) {
|
|
264676
|
+
throw new InvalidInputError("--session <id> is required in non-interactive mode");
|
|
264677
|
+
}
|
|
264678
|
+
const sessionId = options.session ?? await pickSession(options.all);
|
|
264679
|
+
const found = await runTask("Reading session", () => readSessionById(defaultSessionRoots(), sessionId));
|
|
264680
|
+
if (!found) {
|
|
264681
|
+
throw new InvalidInputError(`No Claude Code or Codex session with id "${sessionId}" was found on this machine.`);
|
|
264682
|
+
}
|
|
264683
|
+
const { session } = found;
|
|
264684
|
+
const { turns, droppedTurns } = prepareTranscript(found.turns);
|
|
264685
|
+
if (turns.length === 0) {
|
|
264686
|
+
throw new InvalidInputError("This session has no conversation text to import.");
|
|
264687
|
+
}
|
|
264688
|
+
if (droppedTurns > 0) {
|
|
264689
|
+
log.info(`Sending the latest ${turns.length} messages; ${droppedTurns} older ones exceed the size limit.`);
|
|
264690
|
+
}
|
|
264691
|
+
const confirmed = await confirmPush({
|
|
264692
|
+
isNonInteractive: !interactive,
|
|
264693
|
+
yes: options.yes,
|
|
264694
|
+
log,
|
|
264695
|
+
warning: `This uploads the ${turns.length} messages of "${session.title}" to your Base44 app. Only text goes up; tool calls and their output stay on this machine.`
|
|
264696
|
+
});
|
|
264697
|
+
if (!confirmed) {
|
|
264698
|
+
return { outroMessage: "Import cancelled" };
|
|
264699
|
+
}
|
|
264700
|
+
const imported = await runTask("Importing session", () => importSession({
|
|
264701
|
+
source: session.source,
|
|
264702
|
+
sessionId: session.id,
|
|
264703
|
+
title: session.title,
|
|
264704
|
+
turns
|
|
264705
|
+
}));
|
|
264706
|
+
const url = getBaseCodeUrl(appId, imported.branchName);
|
|
264707
|
+
const result = {
|
|
264708
|
+
branchId: imported.branchId,
|
|
264709
|
+
branchName: imported.branchName,
|
|
264710
|
+
url,
|
|
264711
|
+
created: imported.created,
|
|
264712
|
+
source: session.source,
|
|
264713
|
+
sessionId: session.id,
|
|
264714
|
+
messageCount: turns.length
|
|
264715
|
+
};
|
|
264716
|
+
return {
|
|
264717
|
+
outroMessage: `${imported.created ? "Imported into" : "Already imported into"} branch ${theme.styles.bold(imported.branchName)}
|
|
264718
|
+
${theme.colors.links(url)}`,
|
|
264719
|
+
stdout: jsonMode ? toJsonStdout(result) : undefined
|
|
264720
|
+
};
|
|
264721
|
+
}
|
|
264722
|
+
function getSessionImportCommand() {
|
|
264723
|
+
return new Base44Command("import").description("Continue a local Claude Code or Codex session in a Base Code branch").option("--session <id>", "Session id to import (skips the picker)").option("--all", "List sessions from every directory, not just this repository").option("-y, --yes", "Skip the confirmation prompt").action(importSessionAction);
|
|
264724
|
+
}
|
|
264725
|
+
|
|
264726
|
+
// src/cli/commands/session/index.ts
|
|
264727
|
+
function getSessionCommand() {
|
|
264728
|
+
return new Command2("session").description("Move local coding-agent sessions into Base44 (experimental)").addCommand(getSessionImportCommand());
|
|
264729
|
+
}
|
|
264730
|
+
|
|
262862
264731
|
// src/cli/commands/site/deploy.ts
|
|
262863
|
-
import { resolve as
|
|
264732
|
+
import { resolve as resolve15 } from "node:path";
|
|
262864
264733
|
async function deployAction2(ctx, options) {
|
|
262865
264734
|
const { isNonInteractive } = ctx;
|
|
262866
264735
|
if (isNonInteractive && !options.yes) {
|
|
@@ -262929,7 +264798,7 @@ async function deployTarball({ runTask }, project) {
|
|
|
262929
264798
|
}
|
|
262930
264799
|
function siteOutputDir(project) {
|
|
262931
264800
|
const { outputDirectory = DEFAULT_SITE.outputDirectory } = siteOrDefault(project);
|
|
262932
|
-
return
|
|
264801
|
+
return resolve15(project.root, outputDirectory);
|
|
262933
264802
|
}
|
|
262934
264803
|
function getSiteDeployCommand() {
|
|
262935
264804
|
const command = new Base44Command("deploy").description("Deploy built site files to Base44 hosting").option("-y, --yes", "Skip confirmation prompt").option("--build", "Build the site before deploying (skips the prompt)").option("--no-build", "Deploy without building (skips the prompt)");
|
|
@@ -263273,10 +265142,10 @@ function toPascalCase(name) {
|
|
|
263273
265142
|
return name.split(/[-_\s]+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
|
|
263274
265143
|
}
|
|
263275
265144
|
// src/core/types/update-project.ts
|
|
263276
|
-
import { join as
|
|
265145
|
+
import { join as join36 } from "node:path";
|
|
263277
265146
|
var TYPES_INCLUDE_PATH = `${PROJECT_SUBDIR}/${TYPES_OUTPUT_SUBDIR}/*.d.ts`;
|
|
263278
265147
|
async function updateProjectConfig(projectRoot) {
|
|
263279
|
-
const tsconfigPath =
|
|
265148
|
+
const tsconfigPath = join36(projectRoot, "tsconfig.json");
|
|
263280
265149
|
if (!await pathExists(tsconfigPath)) {
|
|
263281
265150
|
return false;
|
|
263282
265151
|
}
|
|
@@ -263495,7 +265364,7 @@ function rethrowLegacyAppAsExplanation(error) {
|
|
|
263495
265364
|
|
|
263496
265365
|
// src/cli/commands/workflows/limit.ts
|
|
263497
265366
|
var MAX_LIMIT = 200;
|
|
263498
|
-
function
|
|
265367
|
+
function parseLimit2(limit) {
|
|
263499
265368
|
if (limit === undefined)
|
|
263500
265369
|
return;
|
|
263501
265370
|
const parsed = Number.parseInt(limit, 10);
|
|
@@ -263512,7 +265381,7 @@ function formatWorkflowLine(workflow) {
|
|
|
263512
265381
|
return `${workflow.name} [${workflow.status}] runs: ${workflow.totalRuns}, ${lastRun}${failures}`;
|
|
263513
265382
|
}
|
|
263514
265383
|
async function listAction({ log, runTask, jsonMode }, options) {
|
|
263515
|
-
const limit =
|
|
265384
|
+
const limit = parseLimit2(options.limit);
|
|
263516
265385
|
const workflows = await runTask("Fetching workflows from Base44", async () => listWorkflows(limit).catch(rethrowLegacyAppAsExplanation), {
|
|
263517
265386
|
successMessage: "Workflows fetched successfully",
|
|
263518
265387
|
errorMessage: "Failed to fetch workflows"
|
|
@@ -263571,7 +265440,7 @@ async function describeEmptyResult(hasFilters) {
|
|
|
263571
265440
|
return hasFilters ? `No runs match your filters. Workflows in this app: ${names}.` : `No runs yet. Workflows in this app: ${names}.`;
|
|
263572
265441
|
}
|
|
263573
265442
|
async function runsAction(ctx, options) {
|
|
263574
|
-
const limit =
|
|
265443
|
+
const limit = parseLimit2(options.limit);
|
|
263575
265444
|
const runs = await ctx.runTask("Fetching workflow runs from Base44", async () => listWorkflowRuns({
|
|
263576
265445
|
status: options.status,
|
|
263577
265446
|
since: options.since,
|
|
@@ -263757,7 +265626,7 @@ function getWorkspaceCommand() {
|
|
|
263757
265626
|
// src/cli/dev/dev-server/main.ts
|
|
263758
265627
|
var import_cors = __toESM(require_lib4(), 1);
|
|
263759
265628
|
var import_express6 = __toESM(require_express(), 1);
|
|
263760
|
-
import { dirname as dirname28, join as
|
|
265629
|
+
import { dirname as dirname28, join as join41 } from "node:path";
|
|
263761
265630
|
|
|
263762
265631
|
// ../../node_modules/get-port/index.js
|
|
263763
265632
|
import net from "node:net";
|
|
@@ -263887,7 +265756,7 @@ var $tmpName = promisify12(tmp.tmpName);
|
|
|
263887
265756
|
|
|
263888
265757
|
// src/cli/dev/dev-server/function-manager.ts
|
|
263889
265758
|
import { spawn as spawn3 } from "node:child_process";
|
|
263890
|
-
import { dirname as dirname25, join as
|
|
265759
|
+
import { dirname as dirname25, join as join37 } from "node:path";
|
|
263891
265760
|
import { pathToFileURL as pathToFileURL6 } from "node:url";
|
|
263892
265761
|
|
|
263893
265762
|
// src/cli/dev/dev-server/base-function-manager.ts
|
|
@@ -263992,7 +265861,7 @@ class FunctionManager extends BaseFunctionManager {
|
|
|
263992
265861
|
}
|
|
263993
265862
|
spawnFunction(func, port) {
|
|
263994
265863
|
this.logger.log(`Spawning function "${func.name}" on port ${port}`);
|
|
263995
|
-
const importMapPath =
|
|
265864
|
+
const importMapPath = join37(dirname25(this.wrapperPath), "import-map.json");
|
|
263996
265865
|
const process2 = spawn3("deno", ["run", "--allow-all", "--import-map", importMapPath, this.wrapperPath], {
|
|
263997
265866
|
env: {
|
|
263998
265867
|
...globalThis.process.env,
|
|
@@ -264065,8 +265934,8 @@ class FunctionManager extends BaseFunctionManager {
|
|
|
264065
265934
|
// src/cli/dev/dev-server/function-bundler.ts
|
|
264066
265935
|
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
264067
265936
|
import { isBuiltin as isBuiltin3 } from "node:module";
|
|
264068
|
-
import { homedir as
|
|
264069
|
-
import { join as
|
|
265937
|
+
import { homedir as homedir5 } from "node:os";
|
|
265938
|
+
import { join as join38 } from "node:path";
|
|
264070
265939
|
import { pathToFileURL as pathToFileURL7 } from "node:url";
|
|
264071
265940
|
var depsPromise;
|
|
264072
265941
|
function loadDeps() {
|
|
@@ -264187,9 +266056,9 @@ export default {
|
|
|
264187
266056
|
};
|
|
264188
266057
|
`;
|
|
264189
266058
|
function ensureBundlerConfig() {
|
|
264190
|
-
const dir =
|
|
266059
|
+
const dir = join38(homedir5(), ".base44", "function-bundler");
|
|
264191
266060
|
mkdirSync2(dir, { recursive: true });
|
|
264192
|
-
const configPath =
|
|
266061
|
+
const configPath = join38(dir, "deno.json");
|
|
264193
266062
|
writeFileSync2(configPath, `${JSON.stringify({ nodeModulesDir: "auto" }, null, 2)}
|
|
264194
266063
|
`);
|
|
264195
266064
|
return configPath;
|
|
@@ -265721,16 +267590,16 @@ function createCustomIntegrationRoutes(remoteProxy, logger) {
|
|
|
265721
267590
|
|
|
265722
267591
|
// src/cli/dev/dev-server/watcher.ts
|
|
265723
267592
|
import { EventEmitter as EventEmitter4 } from "node:events";
|
|
265724
|
-
import { relative as
|
|
267593
|
+
import { relative as relative10 } from "node:path";
|
|
265725
267594
|
|
|
265726
267595
|
// ../../node_modules/chokidar/index.js
|
|
265727
267596
|
import { EventEmitter as EventEmitter3 } from "node:events";
|
|
265728
267597
|
import { stat as statcb, Stats } from "node:fs";
|
|
265729
|
-
import { readdir as
|
|
267598
|
+
import { readdir as readdir4, stat as stat8 } from "node:fs/promises";
|
|
265730
267599
|
import * as sp3 from "node:path";
|
|
265731
267600
|
|
|
265732
267601
|
// ../../node_modules/readdirp/index.js
|
|
265733
|
-
import { lstat as lstat2, readdir as
|
|
267602
|
+
import { lstat as lstat2, readdir as readdir3, realpath as realpath2, stat as stat6 } from "node:fs/promises";
|
|
265734
267603
|
import { join as pjoin, relative as prelative, resolve as presolve, sep as psep } from "node:path";
|
|
265735
267604
|
import { Readable as Readable6 } from "node:stream";
|
|
265736
267605
|
var EntryTypes = {
|
|
@@ -265739,7 +267608,7 @@ var EntryTypes = {
|
|
|
265739
267608
|
FILE_DIR_TYPE: "files_directories",
|
|
265740
267609
|
EVERYTHING_TYPE: "all"
|
|
265741
267610
|
};
|
|
265742
|
-
var
|
|
267611
|
+
var defaultOptions2 = {
|
|
265743
267612
|
root: ".",
|
|
265744
267613
|
fileFilter: (_entryInfo) => true,
|
|
265745
267614
|
directoryFilter: (_entryInfo) => true,
|
|
@@ -265749,7 +267618,7 @@ var defaultOptions = {
|
|
|
265749
267618
|
alwaysStat: false,
|
|
265750
267619
|
highWaterMark: 4096
|
|
265751
267620
|
};
|
|
265752
|
-
Object.freeze(
|
|
267621
|
+
Object.freeze(defaultOptions2);
|
|
265753
267622
|
var RECURSIVE_ERROR_CODE = "READDIRP_RECURSIVE_ERROR";
|
|
265754
267623
|
var NORMAL_FLOW_ERRORS = new Set(["ENOENT", "EPERM", "EACCES", "ELOOP", RECURSIVE_ERROR_CODE]);
|
|
265755
267624
|
var ALL_TYPES = [
|
|
@@ -265808,17 +267677,17 @@ class ReaddirpStream extends Readable6 {
|
|
|
265808
267677
|
autoDestroy: true,
|
|
265809
267678
|
highWaterMark: options.highWaterMark
|
|
265810
267679
|
});
|
|
265811
|
-
const opts = { ...
|
|
267680
|
+
const opts = { ...defaultOptions2, ...options };
|
|
265812
267681
|
const { root, type } = opts;
|
|
265813
267682
|
this._fileFilter = normalizeFilter(opts.fileFilter);
|
|
265814
267683
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
265815
|
-
const statMethod = opts.lstat ? lstat2 :
|
|
267684
|
+
const statMethod = opts.lstat ? lstat2 : stat6;
|
|
265816
267685
|
if (wantBigintFsStats) {
|
|
265817
267686
|
this._stat = (path) => statMethod(path, { bigint: true });
|
|
265818
267687
|
} else {
|
|
265819
267688
|
this._stat = statMethod;
|
|
265820
267689
|
}
|
|
265821
|
-
this._maxDepth = opts.depth != null && Number.isSafeInteger(opts.depth) ? opts.depth :
|
|
267690
|
+
this._maxDepth = opts.depth != null && Number.isSafeInteger(opts.depth) ? opts.depth : defaultOptions2.depth;
|
|
265822
267691
|
this._wantsDir = type ? DIR_TYPES.has(type) : false;
|
|
265823
267692
|
this._wantsFile = type ? FILE_TYPES2.has(type) : false;
|
|
265824
267693
|
this._wantsEverything = type === EntryTypes.EVERYTHING_TYPE;
|
|
@@ -265883,7 +267752,7 @@ class ReaddirpStream extends Readable6 {
|
|
|
265883
267752
|
async _exploreDir(path, depth) {
|
|
265884
267753
|
let files;
|
|
265885
267754
|
try {
|
|
265886
|
-
files = await
|
|
267755
|
+
files = await readdir3(path, this._rdOptions);
|
|
265887
267756
|
} catch (error) {
|
|
265888
267757
|
this._onError(error);
|
|
265889
267758
|
}
|
|
@@ -265921,7 +267790,7 @@ class ReaddirpStream extends Readable6 {
|
|
|
265921
267790
|
if (stats && stats.isSymbolicLink()) {
|
|
265922
267791
|
const full = entry.fullPath;
|
|
265923
267792
|
try {
|
|
265924
|
-
const entryRealPath = await
|
|
267793
|
+
const entryRealPath = await realpath2(full);
|
|
265925
267794
|
const entryRealPathStats = await lstat2(entryRealPath);
|
|
265926
267795
|
if (entryRealPathStats.isFile()) {
|
|
265927
267796
|
return "file";
|
|
@@ -265965,7 +267834,7 @@ function readdirp(root, options = {}) {
|
|
|
265965
267834
|
|
|
265966
267835
|
// ../../node_modules/chokidar/handler.js
|
|
265967
267836
|
import { watch as fs_watch, unwatchFile, watchFile } from "node:fs";
|
|
265968
|
-
import { realpath as fsrealpath, lstat as lstat3, open as open2, stat as
|
|
267837
|
+
import { realpath as fsrealpath, lstat as lstat3, open as open2, stat as stat7 } from "node:fs/promises";
|
|
265969
267838
|
import { type as osType } from "node:os";
|
|
265970
267839
|
import * as sp2 from "node:path";
|
|
265971
267840
|
var STR_DATA = "data";
|
|
@@ -265991,7 +267860,7 @@ var EVENTS = {
|
|
|
265991
267860
|
};
|
|
265992
267861
|
var EV = EVENTS;
|
|
265993
267862
|
var THROTTLE_MODE_WATCH = "watch";
|
|
265994
|
-
var statMethods = { lstat: lstat3, stat:
|
|
267863
|
+
var statMethods = { lstat: lstat3, stat: stat7 };
|
|
265995
267864
|
var KEY_LISTENERS = "listeners";
|
|
265996
267865
|
var KEY_ERR = "errHandlers";
|
|
265997
267866
|
var KEY_RAW = "rawEmitters";
|
|
@@ -266462,7 +268331,7 @@ class NodeFsHandler {
|
|
|
266462
268331
|
return;
|
|
266463
268332
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
266464
268333
|
try {
|
|
266465
|
-
const newStats = await
|
|
268334
|
+
const newStats = await stat7(file);
|
|
266466
268335
|
if (this.fsw.closed)
|
|
266467
268336
|
return;
|
|
266468
268337
|
const at = newStats.atimeMs;
|
|
@@ -266714,7 +268583,7 @@ function createPattern(matcher) {
|
|
|
266714
268583
|
}
|
|
266715
268584
|
return () => false;
|
|
266716
268585
|
}
|
|
266717
|
-
function
|
|
268586
|
+
function normalizePath2(path) {
|
|
266718
268587
|
if (typeof path !== "string")
|
|
266719
268588
|
throw new Error("string expected");
|
|
266720
268589
|
path = sp3.normalize(path);
|
|
@@ -266728,7 +268597,7 @@ function normalizePath(path) {
|
|
|
266728
268597
|
return path;
|
|
266729
268598
|
}
|
|
266730
268599
|
function matchPatterns(patterns, testString, stats) {
|
|
266731
|
-
const path =
|
|
268600
|
+
const path = normalizePath2(testString);
|
|
266732
268601
|
for (let index = 0;index < patterns.length; index++) {
|
|
266733
268602
|
const pattern = patterns[index];
|
|
266734
268603
|
if (pattern(path, stats)) {
|
|
@@ -266810,7 +268679,7 @@ class DirEntry {
|
|
|
266810
268679
|
return;
|
|
266811
268680
|
const dir = this.path;
|
|
266812
268681
|
try {
|
|
266813
|
-
await
|
|
268682
|
+
await readdir4(dir);
|
|
266814
268683
|
} catch (err) {
|
|
266815
268684
|
if (this._removeWatcher) {
|
|
266816
268685
|
this._removeWatcher(sp3.dirname(dir), sp3.basename(dir));
|
|
@@ -267134,7 +269003,7 @@ class FSWatcher extends EventEmitter3 {
|
|
|
267134
269003
|
const fullPath = opts.cwd ? sp3.join(opts.cwd, path) : path;
|
|
267135
269004
|
let stats;
|
|
267136
269005
|
try {
|
|
267137
|
-
stats = await
|
|
269006
|
+
stats = await stat8(fullPath);
|
|
267138
269007
|
} catch (err) {}
|
|
267139
269008
|
if (!stats || this.closed)
|
|
267140
269009
|
return;
|
|
@@ -267406,7 +269275,7 @@ class WatchBase44 extends EventEmitter4 {
|
|
|
267406
269275
|
ignoreInitial: true
|
|
267407
269276
|
});
|
|
267408
269277
|
watcher.on("all", import_debounce.default(async (_event, path) => {
|
|
267409
|
-
this.emit("change", name,
|
|
269278
|
+
this.emit("change", name, relative10(targetPath, path));
|
|
267410
269279
|
}, WATCH_DEBOUNCE_MS));
|
|
267411
269280
|
watcher.on("error", (err) => {
|
|
267412
269281
|
this.logger.error(`Watch handler failed for ${targetPath}`, err);
|
|
@@ -267518,8 +269387,8 @@ async function createDevServer(options) {
|
|
|
267518
269387
|
broadcastEntityEvent(io, appId, entityName, event);
|
|
267519
269388
|
};
|
|
267520
269389
|
const base44ConfigWatcher = new WatchBase44({
|
|
267521
|
-
functions:
|
|
267522
|
-
entities:
|
|
269390
|
+
functions: join41(dirname28(project.configPath), project.functionsDir),
|
|
269391
|
+
entities: join41(dirname28(project.configPath), project.entitiesDir)
|
|
267523
269392
|
}, devLogger);
|
|
267524
269393
|
base44ConfigWatcher.on("change", async (name) => {
|
|
267525
269394
|
try {
|
|
@@ -267722,7 +269591,7 @@ function readExecEnvTarget(env = process.env) {
|
|
|
267722
269591
|
// src/core/exec/run-script.ts
|
|
267723
269592
|
import { spawn as spawn4 } from "node:child_process";
|
|
267724
269593
|
import { readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
267725
|
-
import { join as
|
|
269594
|
+
import { join as join42 } from "node:path";
|
|
267726
269595
|
var SDK_SPECIFIER = '"npm:@base44/sdk"';
|
|
267727
269596
|
function wrapperSource(sdkVersion) {
|
|
267728
269597
|
const source = readFileSync4(getExecWrapperPath(), "utf-8");
|
|
@@ -267758,7 +269627,7 @@ async function runScript(options) {
|
|
|
267758
269627
|
writeFileSync3(tempWrapper.path, wrapperSource(sdkVersion), "utf-8");
|
|
267759
269628
|
const configDir = await $dir({ unsafeCleanup: true });
|
|
267760
269629
|
cleanupFns.push(configDir.cleanup);
|
|
267761
|
-
const configPath =
|
|
269630
|
+
const configPath = join42(configDir.path, "deno.json");
|
|
267762
269631
|
writeFileSync3(configPath, JSON.stringify(DENO_CONFIG), "utf-8");
|
|
267763
269632
|
try {
|
|
267764
269633
|
const exitCode = await new Promise((resolvePromise) => {
|
|
@@ -267879,7 +269748,7 @@ Examples:
|
|
|
267879
269748
|
}
|
|
267880
269749
|
|
|
267881
269750
|
// src/cli/commands/project/eject.ts
|
|
267882
|
-
import { resolve as
|
|
269751
|
+
import { resolve as resolve19 } from "node:path";
|
|
267883
269752
|
var import_kebabCase2 = __toESM(require_kebabCase(), 1);
|
|
267884
269753
|
async function eject(ctx, options, command) {
|
|
267885
269754
|
const { log, runTask, isNonInteractive } = ctx;
|
|
@@ -267943,7 +269812,7 @@ async function eject(ctx, options, command) {
|
|
|
267943
269812
|
Ne("Operation cancelled.");
|
|
267944
269813
|
throw new CLIExitError(0);
|
|
267945
269814
|
}
|
|
267946
|
-
const resolvedPath =
|
|
269815
|
+
const resolvedPath = resolve19(selectedPath);
|
|
267947
269816
|
await runTask("Downloading your project's code...", async (updateMessage) => {
|
|
267948
269817
|
await createProjectFilesForExistingProject({
|
|
267949
269818
|
projectId,
|
|
@@ -268030,6 +269899,8 @@ function createProgram(context) {
|
|
|
268030
269899
|
program.addCommand(getSecretsCommand());
|
|
268031
269900
|
program.addCommand(getSandboxCommand());
|
|
268032
269901
|
program.addCommand(getBranchesCommand());
|
|
269902
|
+
program.addCommand(getSessionCommand(), { hidden: true });
|
|
269903
|
+
program.addCommand(getApiCommand());
|
|
268033
269904
|
program.addCommand(getAuthCommand());
|
|
268034
269905
|
program.addCommand(getSiteCommand());
|
|
268035
269906
|
if (versionsApiEnabled()) {
|
|
@@ -268048,7 +269919,7 @@ var import_detect_agent = __toESM(require_dist5(), 1);
|
|
|
268048
269919
|
import { release, type } from "node:os";
|
|
268049
269920
|
|
|
268050
269921
|
// ../../node_modules/posthog-node/dist/extensions/error-tracking/modifiers/module.node.mjs
|
|
268051
|
-
import { dirname as dirname29, posix, sep as
|
|
269922
|
+
import { dirname as dirname29, posix, sep as sep3 } from "path";
|
|
268052
269923
|
function createModulerModifier() {
|
|
268053
269924
|
const getModuleFromFileName = createGetModuleFromFilename();
|
|
268054
269925
|
return async (frames) => {
|
|
@@ -268057,7 +269928,7 @@ function createModulerModifier() {
|
|
|
268057
269928
|
return frames;
|
|
268058
269929
|
};
|
|
268059
269930
|
}
|
|
268060
|
-
function createGetModuleFromFilename(basePath = process.argv[1] ? dirname29(process.argv[1]) : process.cwd(), isWindows =
|
|
269931
|
+
function createGetModuleFromFilename(basePath = process.argv[1] ? dirname29(process.argv[1]) : process.cwd(), isWindows = sep3 === "\\") {
|
|
268061
269932
|
const normalizedBase = isWindows ? normalizeWindowsPath2(basePath) : basePath;
|
|
268062
269933
|
return (filename) => {
|
|
268063
269934
|
if (!filename)
|
|
@@ -270092,8 +271963,8 @@ class ReduceableCache {
|
|
|
270092
271963
|
}
|
|
270093
271964
|
}
|
|
270094
271965
|
// ../../node_modules/posthog-node/dist/extensions/error-tracking/modifiers/context-lines.node.mjs
|
|
270095
|
-
import { createReadStream as
|
|
270096
|
-
import { createInterface as
|
|
271966
|
+
import { createReadStream as createReadStream4 } from "node:fs";
|
|
271967
|
+
import { createInterface as createInterface3 } from "node:readline";
|
|
270097
271968
|
var LRU_FILE_CONTENTS_CACHE = new ReduceableCache(25);
|
|
270098
271969
|
var LRU_FILE_CONTENTS_FS_READ_FAILED = new ReduceableCache(20);
|
|
270099
271970
|
var DEFAULT_LINES_OF_CONTEXT = 7;
|
|
@@ -270136,8 +272007,8 @@ async function addSourceContext(frames) {
|
|
|
270136
272007
|
}
|
|
270137
272008
|
function getContextLinesFromFile(path, ranges, output) {
|
|
270138
272009
|
return new Promise((resolve) => {
|
|
270139
|
-
const stream =
|
|
270140
|
-
const lineReaded =
|
|
272010
|
+
const stream = createReadStream4(path);
|
|
272011
|
+
const lineReaded = createInterface3({
|
|
270141
272012
|
input: stream
|
|
270142
272013
|
});
|
|
270143
272014
|
function destroyStreamAndResolve() {
|
|
@@ -272048,7 +273919,7 @@ function addCommandInfoToErrorReporter(program, errorReporter) {
|
|
|
272048
273919
|
// src/cli/index.ts
|
|
272049
273920
|
var __dirname4 = dirname30(fileURLToPath7(import.meta.url));
|
|
272050
273921
|
async function runCLI(options) {
|
|
272051
|
-
ensureNpmAssets(
|
|
273922
|
+
ensureNpmAssets(join43(__dirname4, "../assets"));
|
|
272052
273923
|
const errorReporter = new ErrorReporter;
|
|
272053
273924
|
errorReporter.registerProcessErrorHandlers();
|
|
272054
273925
|
const jsonMode = process.argv.includes("--json");
|
|
@@ -272087,4 +273958,4 @@ export {
|
|
|
272087
273958
|
runCLI
|
|
272088
273959
|
};
|
|
272089
273960
|
|
|
272090
|
-
//# debugId=
|
|
273961
|
+
//# debugId=F036CB7D2B7C691564756E2164756E21
|