@base44-preview/cli 0.1.32-pr.662.e04bb64 → 0.1.32-pr.663.57b7b28
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 +3 -0
- package/dist/cli/index.js +1563 -196
- package/dist/cli/index.js.map +20 -7
- 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" ? join31(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 join31(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: join31,
|
|
31972
31972
|
line,
|
|
31973
31973
|
softline,
|
|
31974
31974
|
hardline,
|
|
@@ -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, join33, 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 {
|
|
@@ -134836,7 +134836,7 @@ ${codeblock}`, options8);
|
|
|
134836
134836
|
breakParent: breakParent2,
|
|
134837
134837
|
hardline: hardline2,
|
|
134838
134838
|
indent: indent2,
|
|
134839
|
-
join:
|
|
134839
|
+
join: join33,
|
|
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 dirname29, join as
|
|
228841
|
+
import { dirname as dirname29, join as join41 } 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",
|
|
@@ -248041,13 +248042,1511 @@ function getAgentsCommand() {
|
|
|
248041
248042
|
return new Command2("agents").description("Manage project agents").addCommand(getAgentsPushCommand()).addCommand(getAgentsPullCommand());
|
|
248042
248043
|
}
|
|
248043
248044
|
|
|
248045
|
+
// src/core/api-spec/body.ts
|
|
248046
|
+
var METHODS_WITHOUT_BODY = new Set(["GET", "HEAD"]);
|
|
248047
|
+
async function resolveRequestBody(method, flag, source) {
|
|
248048
|
+
const takesBody = !METHODS_WITHOUT_BODY.has(method.toUpperCase());
|
|
248049
|
+
if (flag !== undefined && !takesBody) {
|
|
248050
|
+
throw new InvalidInputError(`${method.toUpperCase()} requests cannot have a body.`);
|
|
248051
|
+
}
|
|
248052
|
+
if (flag === "@-") {
|
|
248053
|
+
return source.readStdin();
|
|
248054
|
+
}
|
|
248055
|
+
if (flag?.startsWith("@")) {
|
|
248056
|
+
return readTextFile(flag.slice(1));
|
|
248057
|
+
}
|
|
248058
|
+
if (flag !== undefined) {
|
|
248059
|
+
return flag;
|
|
248060
|
+
}
|
|
248061
|
+
if (!takesBody || source.stdinIsTTY) {
|
|
248062
|
+
return;
|
|
248063
|
+
}
|
|
248064
|
+
const piped = await source.readStdin();
|
|
248065
|
+
return piped.trim() ? piped : undefined;
|
|
248066
|
+
}
|
|
248067
|
+
// ../../node_modules/minisearch/dist/es/index.js
|
|
248068
|
+
var ENTRIES = "ENTRIES";
|
|
248069
|
+
var KEYS = "KEYS";
|
|
248070
|
+
var VALUES = "VALUES";
|
|
248071
|
+
var LEAF = "";
|
|
248072
|
+
|
|
248073
|
+
class TreeIterator {
|
|
248074
|
+
constructor(set, type) {
|
|
248075
|
+
const node = set._tree;
|
|
248076
|
+
const keys = Array.from(node.keys());
|
|
248077
|
+
this.set = set;
|
|
248078
|
+
this._type = type;
|
|
248079
|
+
this._path = keys.length > 0 ? [{ node, keys }] : [];
|
|
248080
|
+
}
|
|
248081
|
+
next() {
|
|
248082
|
+
const value = this.dive();
|
|
248083
|
+
this.backtrack();
|
|
248084
|
+
return value;
|
|
248085
|
+
}
|
|
248086
|
+
dive() {
|
|
248087
|
+
if (this._path.length === 0) {
|
|
248088
|
+
return { done: true, value: undefined };
|
|
248089
|
+
}
|
|
248090
|
+
const { node, keys } = last$1(this._path);
|
|
248091
|
+
if (last$1(keys) === LEAF) {
|
|
248092
|
+
return { done: false, value: this.result() };
|
|
248093
|
+
}
|
|
248094
|
+
const child = node.get(last$1(keys));
|
|
248095
|
+
this._path.push({ node: child, keys: Array.from(child.keys()) });
|
|
248096
|
+
return this.dive();
|
|
248097
|
+
}
|
|
248098
|
+
backtrack() {
|
|
248099
|
+
if (this._path.length === 0) {
|
|
248100
|
+
return;
|
|
248101
|
+
}
|
|
248102
|
+
const keys = last$1(this._path).keys;
|
|
248103
|
+
keys.pop();
|
|
248104
|
+
if (keys.length > 0) {
|
|
248105
|
+
return;
|
|
248106
|
+
}
|
|
248107
|
+
this._path.pop();
|
|
248108
|
+
this.backtrack();
|
|
248109
|
+
}
|
|
248110
|
+
key() {
|
|
248111
|
+
return this.set._prefix + this._path.map(({ keys }) => last$1(keys)).filter((key) => key !== LEAF).join("");
|
|
248112
|
+
}
|
|
248113
|
+
value() {
|
|
248114
|
+
return last$1(this._path).node.get(LEAF);
|
|
248115
|
+
}
|
|
248116
|
+
result() {
|
|
248117
|
+
switch (this._type) {
|
|
248118
|
+
case VALUES:
|
|
248119
|
+
return this.value();
|
|
248120
|
+
case KEYS:
|
|
248121
|
+
return this.key();
|
|
248122
|
+
default:
|
|
248123
|
+
return [this.key(), this.value()];
|
|
248124
|
+
}
|
|
248125
|
+
}
|
|
248126
|
+
[Symbol.iterator]() {
|
|
248127
|
+
return this;
|
|
248128
|
+
}
|
|
248129
|
+
}
|
|
248130
|
+
var last$1 = (array) => {
|
|
248131
|
+
return array[array.length - 1];
|
|
248132
|
+
};
|
|
248133
|
+
var fuzzySearch = (node, query, maxDistance) => {
|
|
248134
|
+
const results = new Map;
|
|
248135
|
+
if (query === undefined)
|
|
248136
|
+
return results;
|
|
248137
|
+
const n = query.length + 1;
|
|
248138
|
+
const m = n + maxDistance;
|
|
248139
|
+
const matrix = new Uint8Array(m * n).fill(maxDistance + 1);
|
|
248140
|
+
for (let j = 0;j < n; ++j)
|
|
248141
|
+
matrix[j] = j;
|
|
248142
|
+
for (let i = 1;i < m; ++i)
|
|
248143
|
+
matrix[i * n] = i;
|
|
248144
|
+
recurse(node, query, maxDistance, results, matrix, 1, n, "");
|
|
248145
|
+
return results;
|
|
248146
|
+
};
|
|
248147
|
+
var recurse = (node, query, maxDistance, results, matrix, m, n, prefix) => {
|
|
248148
|
+
const offset = m * n;
|
|
248149
|
+
key:
|
|
248150
|
+
for (const key of node.keys()) {
|
|
248151
|
+
if (key === LEAF) {
|
|
248152
|
+
const distance = matrix[offset - 1];
|
|
248153
|
+
if (distance <= maxDistance) {
|
|
248154
|
+
results.set(prefix, [node.get(key), distance]);
|
|
248155
|
+
}
|
|
248156
|
+
} else {
|
|
248157
|
+
let i = m;
|
|
248158
|
+
for (let pos = 0;pos < key.length; ++pos, ++i) {
|
|
248159
|
+
const char = key[pos];
|
|
248160
|
+
const thisRowOffset = n * i;
|
|
248161
|
+
const prevRowOffset = thisRowOffset - n;
|
|
248162
|
+
let minDistance = matrix[thisRowOffset];
|
|
248163
|
+
const jmin = Math.max(0, i - maxDistance - 1);
|
|
248164
|
+
const jmax = Math.min(n - 1, i + maxDistance);
|
|
248165
|
+
for (let j = jmin;j < jmax; ++j) {
|
|
248166
|
+
const different = char !== query[j];
|
|
248167
|
+
const rpl = matrix[prevRowOffset + j] + +different;
|
|
248168
|
+
const del = matrix[prevRowOffset + j + 1] + 1;
|
|
248169
|
+
const ins = matrix[thisRowOffset + j] + 1;
|
|
248170
|
+
const dist = matrix[thisRowOffset + j + 1] = Math.min(rpl, del, ins);
|
|
248171
|
+
if (dist < minDistance)
|
|
248172
|
+
minDistance = dist;
|
|
248173
|
+
}
|
|
248174
|
+
if (minDistance > maxDistance) {
|
|
248175
|
+
continue key;
|
|
248176
|
+
}
|
|
248177
|
+
}
|
|
248178
|
+
recurse(node.get(key), query, maxDistance, results, matrix, i, n, prefix + key);
|
|
248179
|
+
}
|
|
248180
|
+
}
|
|
248181
|
+
};
|
|
248182
|
+
|
|
248183
|
+
class SearchableMap {
|
|
248184
|
+
constructor(tree = new Map, prefix = "") {
|
|
248185
|
+
this._size = undefined;
|
|
248186
|
+
this._tree = tree;
|
|
248187
|
+
this._prefix = prefix;
|
|
248188
|
+
}
|
|
248189
|
+
atPrefix(prefix) {
|
|
248190
|
+
if (!prefix.startsWith(this._prefix)) {
|
|
248191
|
+
throw new Error("Mismatched prefix");
|
|
248192
|
+
}
|
|
248193
|
+
const [node, path] = trackDown(this._tree, prefix.slice(this._prefix.length));
|
|
248194
|
+
if (node === undefined) {
|
|
248195
|
+
const [parentNode, key] = last(path);
|
|
248196
|
+
for (const k of parentNode.keys()) {
|
|
248197
|
+
if (k !== LEAF && k.startsWith(key)) {
|
|
248198
|
+
const node = new Map;
|
|
248199
|
+
node.set(k.slice(key.length), parentNode.get(k));
|
|
248200
|
+
return new SearchableMap(node, prefix);
|
|
248201
|
+
}
|
|
248202
|
+
}
|
|
248203
|
+
}
|
|
248204
|
+
return new SearchableMap(node, prefix);
|
|
248205
|
+
}
|
|
248206
|
+
clear() {
|
|
248207
|
+
this._size = undefined;
|
|
248208
|
+
this._tree.clear();
|
|
248209
|
+
}
|
|
248210
|
+
delete(key) {
|
|
248211
|
+
this._size = undefined;
|
|
248212
|
+
return remove(this._tree, key);
|
|
248213
|
+
}
|
|
248214
|
+
entries() {
|
|
248215
|
+
return new TreeIterator(this, ENTRIES);
|
|
248216
|
+
}
|
|
248217
|
+
forEach(fn) {
|
|
248218
|
+
for (const [key, value] of this) {
|
|
248219
|
+
fn(key, value, this);
|
|
248220
|
+
}
|
|
248221
|
+
}
|
|
248222
|
+
fuzzyGet(key, maxEditDistance) {
|
|
248223
|
+
return fuzzySearch(this._tree, key, maxEditDistance);
|
|
248224
|
+
}
|
|
248225
|
+
get(key) {
|
|
248226
|
+
const node = lookup(this._tree, key);
|
|
248227
|
+
return node !== undefined ? node.get(LEAF) : undefined;
|
|
248228
|
+
}
|
|
248229
|
+
has(key) {
|
|
248230
|
+
const node = lookup(this._tree, key);
|
|
248231
|
+
return node !== undefined && node.has(LEAF);
|
|
248232
|
+
}
|
|
248233
|
+
keys() {
|
|
248234
|
+
return new TreeIterator(this, KEYS);
|
|
248235
|
+
}
|
|
248236
|
+
set(key, value) {
|
|
248237
|
+
if (typeof key !== "string") {
|
|
248238
|
+
throw new Error("key must be a string");
|
|
248239
|
+
}
|
|
248240
|
+
this._size = undefined;
|
|
248241
|
+
const node = createPath(this._tree, key);
|
|
248242
|
+
node.set(LEAF, value);
|
|
248243
|
+
return this;
|
|
248244
|
+
}
|
|
248245
|
+
get size() {
|
|
248246
|
+
if (this._size) {
|
|
248247
|
+
return this._size;
|
|
248248
|
+
}
|
|
248249
|
+
this._size = 0;
|
|
248250
|
+
const iter = this.entries();
|
|
248251
|
+
while (!iter.next().done)
|
|
248252
|
+
this._size += 1;
|
|
248253
|
+
return this._size;
|
|
248254
|
+
}
|
|
248255
|
+
update(key, fn) {
|
|
248256
|
+
if (typeof key !== "string") {
|
|
248257
|
+
throw new Error("key must be a string");
|
|
248258
|
+
}
|
|
248259
|
+
this._size = undefined;
|
|
248260
|
+
const node = createPath(this._tree, key);
|
|
248261
|
+
node.set(LEAF, fn(node.get(LEAF)));
|
|
248262
|
+
return this;
|
|
248263
|
+
}
|
|
248264
|
+
fetch(key, initial) {
|
|
248265
|
+
if (typeof key !== "string") {
|
|
248266
|
+
throw new Error("key must be a string");
|
|
248267
|
+
}
|
|
248268
|
+
this._size = undefined;
|
|
248269
|
+
const node = createPath(this._tree, key);
|
|
248270
|
+
let value = node.get(LEAF);
|
|
248271
|
+
if (value === undefined) {
|
|
248272
|
+
node.set(LEAF, value = initial());
|
|
248273
|
+
}
|
|
248274
|
+
return value;
|
|
248275
|
+
}
|
|
248276
|
+
values() {
|
|
248277
|
+
return new TreeIterator(this, VALUES);
|
|
248278
|
+
}
|
|
248279
|
+
[Symbol.iterator]() {
|
|
248280
|
+
return this.entries();
|
|
248281
|
+
}
|
|
248282
|
+
static from(entries) {
|
|
248283
|
+
const tree = new SearchableMap;
|
|
248284
|
+
for (const [key, value] of entries) {
|
|
248285
|
+
tree.set(key, value);
|
|
248286
|
+
}
|
|
248287
|
+
return tree;
|
|
248288
|
+
}
|
|
248289
|
+
static fromObject(object) {
|
|
248290
|
+
return SearchableMap.from(Object.entries(object));
|
|
248291
|
+
}
|
|
248292
|
+
}
|
|
248293
|
+
var trackDown = (tree, key, path = []) => {
|
|
248294
|
+
if (key.length === 0 || tree == null) {
|
|
248295
|
+
return [tree, path];
|
|
248296
|
+
}
|
|
248297
|
+
for (const k of tree.keys()) {
|
|
248298
|
+
if (k !== LEAF && key.startsWith(k)) {
|
|
248299
|
+
path.push([tree, k]);
|
|
248300
|
+
return trackDown(tree.get(k), key.slice(k.length), path);
|
|
248301
|
+
}
|
|
248302
|
+
}
|
|
248303
|
+
path.push([tree, key]);
|
|
248304
|
+
return trackDown(undefined, "", path);
|
|
248305
|
+
};
|
|
248306
|
+
var lookup = (tree, key) => {
|
|
248307
|
+
if (key.length === 0 || tree == null) {
|
|
248308
|
+
return tree;
|
|
248309
|
+
}
|
|
248310
|
+
for (const k of tree.keys()) {
|
|
248311
|
+
if (k !== LEAF && key.startsWith(k)) {
|
|
248312
|
+
return lookup(tree.get(k), key.slice(k.length));
|
|
248313
|
+
}
|
|
248314
|
+
}
|
|
248315
|
+
};
|
|
248316
|
+
var createPath = (node, key) => {
|
|
248317
|
+
const keyLength = key.length;
|
|
248318
|
+
outer:
|
|
248319
|
+
for (let pos = 0;node && pos < keyLength; ) {
|
|
248320
|
+
for (const k of node.keys()) {
|
|
248321
|
+
if (k !== LEAF && key[pos] === k[0]) {
|
|
248322
|
+
const len = Math.min(keyLength - pos, k.length);
|
|
248323
|
+
let offset = 1;
|
|
248324
|
+
while (offset < len && key[pos + offset] === k[offset])
|
|
248325
|
+
++offset;
|
|
248326
|
+
const child = node.get(k);
|
|
248327
|
+
if (offset === k.length) {
|
|
248328
|
+
node = child;
|
|
248329
|
+
} else {
|
|
248330
|
+
const intermediate = new Map;
|
|
248331
|
+
intermediate.set(k.slice(offset), child);
|
|
248332
|
+
node.set(key.slice(pos, pos + offset), intermediate);
|
|
248333
|
+
node.delete(k);
|
|
248334
|
+
node = intermediate;
|
|
248335
|
+
}
|
|
248336
|
+
pos += offset;
|
|
248337
|
+
continue outer;
|
|
248338
|
+
}
|
|
248339
|
+
}
|
|
248340
|
+
const child = new Map;
|
|
248341
|
+
node.set(key.slice(pos), child);
|
|
248342
|
+
return child;
|
|
248343
|
+
}
|
|
248344
|
+
return node;
|
|
248345
|
+
};
|
|
248346
|
+
var remove = (tree, key) => {
|
|
248347
|
+
const [node, path] = trackDown(tree, key);
|
|
248348
|
+
if (node === undefined) {
|
|
248349
|
+
return;
|
|
248350
|
+
}
|
|
248351
|
+
node.delete(LEAF);
|
|
248352
|
+
if (node.size === 0) {
|
|
248353
|
+
cleanup(path);
|
|
248354
|
+
} else if (node.size === 1) {
|
|
248355
|
+
const [key, value] = node.entries().next().value;
|
|
248356
|
+
merge3(path, key, value);
|
|
248357
|
+
}
|
|
248358
|
+
};
|
|
248359
|
+
var cleanup = (path) => {
|
|
248360
|
+
if (path.length === 0) {
|
|
248361
|
+
return;
|
|
248362
|
+
}
|
|
248363
|
+
const [node, key] = last(path);
|
|
248364
|
+
node.delete(key);
|
|
248365
|
+
if (node.size === 0) {
|
|
248366
|
+
cleanup(path.slice(0, -1));
|
|
248367
|
+
} else if (node.size === 1) {
|
|
248368
|
+
const [key, value] = node.entries().next().value;
|
|
248369
|
+
if (key !== LEAF) {
|
|
248370
|
+
merge3(path.slice(0, -1), key, value);
|
|
248371
|
+
}
|
|
248372
|
+
}
|
|
248373
|
+
};
|
|
248374
|
+
var merge3 = (path, key, value) => {
|
|
248375
|
+
if (path.length === 0) {
|
|
248376
|
+
return;
|
|
248377
|
+
}
|
|
248378
|
+
const [node, nodeKey] = last(path);
|
|
248379
|
+
node.set(nodeKey + key, value);
|
|
248380
|
+
node.delete(nodeKey);
|
|
248381
|
+
};
|
|
248382
|
+
var last = (array) => {
|
|
248383
|
+
return array[array.length - 1];
|
|
248384
|
+
};
|
|
248385
|
+
var OR = "or";
|
|
248386
|
+
var AND = "and";
|
|
248387
|
+
var AND_NOT = "and_not";
|
|
248388
|
+
|
|
248389
|
+
class MiniSearch {
|
|
248390
|
+
constructor(options) {
|
|
248391
|
+
if ((options === null || options === undefined ? undefined : options.fields) == null) {
|
|
248392
|
+
throw new Error('MiniSearch: option "fields" must be provided');
|
|
248393
|
+
}
|
|
248394
|
+
const autoVacuum = options.autoVacuum == null || options.autoVacuum === true ? defaultAutoVacuumOptions : options.autoVacuum;
|
|
248395
|
+
this._options = {
|
|
248396
|
+
...defaultOptions,
|
|
248397
|
+
...options,
|
|
248398
|
+
autoVacuum,
|
|
248399
|
+
searchOptions: { ...defaultSearchOptions, ...options.searchOptions || {} },
|
|
248400
|
+
autoSuggestOptions: { ...defaultAutoSuggestOptions, ...options.autoSuggestOptions || {} }
|
|
248401
|
+
};
|
|
248402
|
+
this._index = new SearchableMap;
|
|
248403
|
+
this._documentCount = 0;
|
|
248404
|
+
this._documentIds = new Map;
|
|
248405
|
+
this._idToShortId = new Map;
|
|
248406
|
+
this._fieldIds = {};
|
|
248407
|
+
this._fieldLength = new Map;
|
|
248408
|
+
this._avgFieldLength = [];
|
|
248409
|
+
this._nextId = 0;
|
|
248410
|
+
this._storedFields = new Map;
|
|
248411
|
+
this._dirtCount = 0;
|
|
248412
|
+
this._currentVacuum = null;
|
|
248413
|
+
this._enqueuedVacuum = null;
|
|
248414
|
+
this._enqueuedVacuumConditions = defaultVacuumConditions;
|
|
248415
|
+
this.addFields(this._options.fields);
|
|
248416
|
+
}
|
|
248417
|
+
add(document2) {
|
|
248418
|
+
const { extractField, tokenize, processTerm, fields, idField } = this._options;
|
|
248419
|
+
const id = extractField(document2, idField);
|
|
248420
|
+
if (id == null) {
|
|
248421
|
+
throw new Error(`MiniSearch: document does not have ID field "${idField}"`);
|
|
248422
|
+
}
|
|
248423
|
+
if (this._idToShortId.has(id)) {
|
|
248424
|
+
throw new Error(`MiniSearch: duplicate ID ${id}`);
|
|
248425
|
+
}
|
|
248426
|
+
const shortDocumentId = this.addDocumentId(id);
|
|
248427
|
+
this.saveStoredFields(shortDocumentId, document2);
|
|
248428
|
+
for (const field of fields) {
|
|
248429
|
+
const fieldValue = extractField(document2, field);
|
|
248430
|
+
if (fieldValue == null)
|
|
248431
|
+
continue;
|
|
248432
|
+
const tokens = tokenize(fieldValue.toString(), field);
|
|
248433
|
+
const fieldId = this._fieldIds[field];
|
|
248434
|
+
const uniqueTerms = new Set(tokens).size;
|
|
248435
|
+
this.addFieldLength(shortDocumentId, fieldId, this._documentCount - 1, uniqueTerms);
|
|
248436
|
+
for (const term of tokens) {
|
|
248437
|
+
const processedTerm = processTerm(term, field);
|
|
248438
|
+
if (Array.isArray(processedTerm)) {
|
|
248439
|
+
for (const t of processedTerm) {
|
|
248440
|
+
this.addTerm(fieldId, shortDocumentId, t);
|
|
248441
|
+
}
|
|
248442
|
+
} else if (processedTerm) {
|
|
248443
|
+
this.addTerm(fieldId, shortDocumentId, processedTerm);
|
|
248444
|
+
}
|
|
248445
|
+
}
|
|
248446
|
+
}
|
|
248447
|
+
}
|
|
248448
|
+
addAll(documents) {
|
|
248449
|
+
for (const document2 of documents)
|
|
248450
|
+
this.add(document2);
|
|
248451
|
+
}
|
|
248452
|
+
addAllAsync(documents, options = {}) {
|
|
248453
|
+
const { chunkSize = 10 } = options;
|
|
248454
|
+
const acc = { chunk: [], promise: Promise.resolve() };
|
|
248455
|
+
const { chunk, promise } = documents.reduce(({ chunk, promise }, document2, i) => {
|
|
248456
|
+
chunk.push(document2);
|
|
248457
|
+
if ((i + 1) % chunkSize === 0) {
|
|
248458
|
+
return {
|
|
248459
|
+
chunk: [],
|
|
248460
|
+
promise: promise.then(() => new Promise((resolve) => setTimeout(resolve, 0))).then(() => this.addAll(chunk))
|
|
248461
|
+
};
|
|
248462
|
+
} else {
|
|
248463
|
+
return { chunk, promise };
|
|
248464
|
+
}
|
|
248465
|
+
}, acc);
|
|
248466
|
+
return promise.then(() => this.addAll(chunk));
|
|
248467
|
+
}
|
|
248468
|
+
remove(document2) {
|
|
248469
|
+
const { tokenize, processTerm, extractField, fields, idField } = this._options;
|
|
248470
|
+
const id = extractField(document2, idField);
|
|
248471
|
+
if (id == null) {
|
|
248472
|
+
throw new Error(`MiniSearch: document does not have ID field "${idField}"`);
|
|
248473
|
+
}
|
|
248474
|
+
const shortId = this._idToShortId.get(id);
|
|
248475
|
+
if (shortId == null) {
|
|
248476
|
+
throw new Error(`MiniSearch: cannot remove document with ID ${id}: it is not in the index`);
|
|
248477
|
+
}
|
|
248478
|
+
for (const field of fields) {
|
|
248479
|
+
const fieldValue = extractField(document2, field);
|
|
248480
|
+
if (fieldValue == null)
|
|
248481
|
+
continue;
|
|
248482
|
+
const tokens = tokenize(fieldValue.toString(), field);
|
|
248483
|
+
const fieldId = this._fieldIds[field];
|
|
248484
|
+
const uniqueTerms = new Set(tokens).size;
|
|
248485
|
+
this.removeFieldLength(shortId, fieldId, this._documentCount, uniqueTerms);
|
|
248486
|
+
for (const term of tokens) {
|
|
248487
|
+
const processedTerm = processTerm(term, field);
|
|
248488
|
+
if (Array.isArray(processedTerm)) {
|
|
248489
|
+
for (const t of processedTerm) {
|
|
248490
|
+
this.removeTerm(fieldId, shortId, t);
|
|
248491
|
+
}
|
|
248492
|
+
} else if (processedTerm) {
|
|
248493
|
+
this.removeTerm(fieldId, shortId, processedTerm);
|
|
248494
|
+
}
|
|
248495
|
+
}
|
|
248496
|
+
}
|
|
248497
|
+
this._storedFields.delete(shortId);
|
|
248498
|
+
this._documentIds.delete(shortId);
|
|
248499
|
+
this._idToShortId.delete(id);
|
|
248500
|
+
this._fieldLength.delete(shortId);
|
|
248501
|
+
this._documentCount -= 1;
|
|
248502
|
+
}
|
|
248503
|
+
removeAll(documents) {
|
|
248504
|
+
if (documents) {
|
|
248505
|
+
for (const document2 of documents)
|
|
248506
|
+
this.remove(document2);
|
|
248507
|
+
} else if (arguments.length > 0) {
|
|
248508
|
+
throw new Error("Expected documents to be present. Omit the argument to remove all documents.");
|
|
248509
|
+
} else {
|
|
248510
|
+
this._index = new SearchableMap;
|
|
248511
|
+
this._documentCount = 0;
|
|
248512
|
+
this._documentIds = new Map;
|
|
248513
|
+
this._idToShortId = new Map;
|
|
248514
|
+
this._fieldLength = new Map;
|
|
248515
|
+
this._avgFieldLength = [];
|
|
248516
|
+
this._storedFields = new Map;
|
|
248517
|
+
this._nextId = 0;
|
|
248518
|
+
}
|
|
248519
|
+
}
|
|
248520
|
+
discard(id) {
|
|
248521
|
+
const shortId = this._idToShortId.get(id);
|
|
248522
|
+
if (shortId == null) {
|
|
248523
|
+
throw new Error(`MiniSearch: cannot discard document with ID ${id}: it is not in the index`);
|
|
248524
|
+
}
|
|
248525
|
+
this._idToShortId.delete(id);
|
|
248526
|
+
this._documentIds.delete(shortId);
|
|
248527
|
+
this._storedFields.delete(shortId);
|
|
248528
|
+
(this._fieldLength.get(shortId) || []).forEach((fieldLength, fieldId) => {
|
|
248529
|
+
this.removeFieldLength(shortId, fieldId, this._documentCount, fieldLength);
|
|
248530
|
+
});
|
|
248531
|
+
this._fieldLength.delete(shortId);
|
|
248532
|
+
this._documentCount -= 1;
|
|
248533
|
+
this._dirtCount += 1;
|
|
248534
|
+
this.maybeAutoVacuum();
|
|
248535
|
+
}
|
|
248536
|
+
maybeAutoVacuum() {
|
|
248537
|
+
if (this._options.autoVacuum === false) {
|
|
248538
|
+
return;
|
|
248539
|
+
}
|
|
248540
|
+
const { minDirtFactor, minDirtCount, batchSize, batchWait } = this._options.autoVacuum;
|
|
248541
|
+
this.conditionalVacuum({ batchSize, batchWait }, { minDirtCount, minDirtFactor });
|
|
248542
|
+
}
|
|
248543
|
+
discardAll(ids) {
|
|
248544
|
+
const autoVacuum = this._options.autoVacuum;
|
|
248545
|
+
try {
|
|
248546
|
+
this._options.autoVacuum = false;
|
|
248547
|
+
for (const id of ids) {
|
|
248548
|
+
this.discard(id);
|
|
248549
|
+
}
|
|
248550
|
+
} finally {
|
|
248551
|
+
this._options.autoVacuum = autoVacuum;
|
|
248552
|
+
}
|
|
248553
|
+
this.maybeAutoVacuum();
|
|
248554
|
+
}
|
|
248555
|
+
replace(updatedDocument) {
|
|
248556
|
+
const { idField, extractField } = this._options;
|
|
248557
|
+
const id = extractField(updatedDocument, idField);
|
|
248558
|
+
this.discard(id);
|
|
248559
|
+
this.add(updatedDocument);
|
|
248560
|
+
}
|
|
248561
|
+
vacuum(options = {}) {
|
|
248562
|
+
return this.conditionalVacuum(options);
|
|
248563
|
+
}
|
|
248564
|
+
conditionalVacuum(options, conditions) {
|
|
248565
|
+
if (this._currentVacuum) {
|
|
248566
|
+
this._enqueuedVacuumConditions = this._enqueuedVacuumConditions && conditions;
|
|
248567
|
+
if (this._enqueuedVacuum != null) {
|
|
248568
|
+
return this._enqueuedVacuum;
|
|
248569
|
+
}
|
|
248570
|
+
this._enqueuedVacuum = this._currentVacuum.then(() => {
|
|
248571
|
+
const conditions = this._enqueuedVacuumConditions;
|
|
248572
|
+
this._enqueuedVacuumConditions = defaultVacuumConditions;
|
|
248573
|
+
return this.performVacuuming(options, conditions);
|
|
248574
|
+
});
|
|
248575
|
+
return this._enqueuedVacuum;
|
|
248576
|
+
}
|
|
248577
|
+
if (this.vacuumConditionsMet(conditions) === false) {
|
|
248578
|
+
return Promise.resolve();
|
|
248579
|
+
}
|
|
248580
|
+
this._currentVacuum = this.performVacuuming(options);
|
|
248581
|
+
return this._currentVacuum;
|
|
248582
|
+
}
|
|
248583
|
+
async performVacuuming(options, conditions) {
|
|
248584
|
+
const initialDirtCount = this._dirtCount;
|
|
248585
|
+
if (this.vacuumConditionsMet(conditions)) {
|
|
248586
|
+
const batchSize = options.batchSize || defaultVacuumOptions.batchSize;
|
|
248587
|
+
const batchWait = options.batchWait || defaultVacuumOptions.batchWait;
|
|
248588
|
+
let i = 1;
|
|
248589
|
+
for (const [term, fieldsData] of this._index) {
|
|
248590
|
+
for (const [fieldId, fieldIndex] of fieldsData) {
|
|
248591
|
+
for (const [shortId] of fieldIndex) {
|
|
248592
|
+
if (this._documentIds.has(shortId)) {
|
|
248593
|
+
continue;
|
|
248594
|
+
}
|
|
248595
|
+
if (fieldIndex.size <= 1) {
|
|
248596
|
+
fieldsData.delete(fieldId);
|
|
248597
|
+
} else {
|
|
248598
|
+
fieldIndex.delete(shortId);
|
|
248599
|
+
}
|
|
248600
|
+
}
|
|
248601
|
+
}
|
|
248602
|
+
if (this._index.get(term).size === 0) {
|
|
248603
|
+
this._index.delete(term);
|
|
248604
|
+
}
|
|
248605
|
+
if (i % batchSize === 0) {
|
|
248606
|
+
await new Promise((resolve) => setTimeout(resolve, batchWait));
|
|
248607
|
+
}
|
|
248608
|
+
i += 1;
|
|
248609
|
+
}
|
|
248610
|
+
this._dirtCount -= initialDirtCount;
|
|
248611
|
+
}
|
|
248612
|
+
await null;
|
|
248613
|
+
this._currentVacuum = this._enqueuedVacuum;
|
|
248614
|
+
this._enqueuedVacuum = null;
|
|
248615
|
+
}
|
|
248616
|
+
vacuumConditionsMet(conditions) {
|
|
248617
|
+
if (conditions == null) {
|
|
248618
|
+
return true;
|
|
248619
|
+
}
|
|
248620
|
+
let { minDirtCount, minDirtFactor } = conditions;
|
|
248621
|
+
minDirtCount = minDirtCount || defaultAutoVacuumOptions.minDirtCount;
|
|
248622
|
+
minDirtFactor = minDirtFactor || defaultAutoVacuumOptions.minDirtFactor;
|
|
248623
|
+
return this.dirtCount >= minDirtCount && this.dirtFactor >= minDirtFactor;
|
|
248624
|
+
}
|
|
248625
|
+
get isVacuuming() {
|
|
248626
|
+
return this._currentVacuum != null;
|
|
248627
|
+
}
|
|
248628
|
+
get dirtCount() {
|
|
248629
|
+
return this._dirtCount;
|
|
248630
|
+
}
|
|
248631
|
+
get dirtFactor() {
|
|
248632
|
+
return this._dirtCount / (1 + this._documentCount + this._dirtCount);
|
|
248633
|
+
}
|
|
248634
|
+
has(id) {
|
|
248635
|
+
return this._idToShortId.has(id);
|
|
248636
|
+
}
|
|
248637
|
+
getStoredFields(id) {
|
|
248638
|
+
const shortId = this._idToShortId.get(id);
|
|
248639
|
+
if (shortId == null) {
|
|
248640
|
+
return;
|
|
248641
|
+
}
|
|
248642
|
+
return this._storedFields.get(shortId);
|
|
248643
|
+
}
|
|
248644
|
+
search(query, searchOptions = {}) {
|
|
248645
|
+
const { searchOptions: globalSearchOptions } = this._options;
|
|
248646
|
+
const searchOptionsWithDefaults = { ...globalSearchOptions, ...searchOptions };
|
|
248647
|
+
const rawResults = this.executeQuery(query, searchOptions);
|
|
248648
|
+
const results = [];
|
|
248649
|
+
for (const [docId, { score, terms, match }] of rawResults) {
|
|
248650
|
+
const quality = terms.length || 1;
|
|
248651
|
+
const result = {
|
|
248652
|
+
id: this._documentIds.get(docId),
|
|
248653
|
+
score: score * quality,
|
|
248654
|
+
terms: Object.keys(match),
|
|
248655
|
+
queryTerms: terms,
|
|
248656
|
+
match
|
|
248657
|
+
};
|
|
248658
|
+
Object.assign(result, this._storedFields.get(docId));
|
|
248659
|
+
if (searchOptionsWithDefaults.filter == null || searchOptionsWithDefaults.filter(result)) {
|
|
248660
|
+
results.push(result);
|
|
248661
|
+
}
|
|
248662
|
+
}
|
|
248663
|
+
if (query === MiniSearch.wildcard && searchOptionsWithDefaults.boostDocument == null) {
|
|
248664
|
+
return results;
|
|
248665
|
+
}
|
|
248666
|
+
results.sort(byScore);
|
|
248667
|
+
return results;
|
|
248668
|
+
}
|
|
248669
|
+
autoSuggest(queryString, options = {}) {
|
|
248670
|
+
options = { ...this._options.autoSuggestOptions, ...options };
|
|
248671
|
+
const suggestions = new Map;
|
|
248672
|
+
for (const { score, terms } of this.search(queryString, options)) {
|
|
248673
|
+
const phrase = terms.join(" ");
|
|
248674
|
+
const suggestion = suggestions.get(phrase);
|
|
248675
|
+
if (suggestion != null) {
|
|
248676
|
+
suggestion.score += score;
|
|
248677
|
+
suggestion.count += 1;
|
|
248678
|
+
} else {
|
|
248679
|
+
suggestions.set(phrase, { score, terms, count: 1 });
|
|
248680
|
+
}
|
|
248681
|
+
}
|
|
248682
|
+
const results = [];
|
|
248683
|
+
for (const [suggestion, { score, terms, count }] of suggestions) {
|
|
248684
|
+
results.push({ suggestion, terms, score: score / count });
|
|
248685
|
+
}
|
|
248686
|
+
results.sort(byScore);
|
|
248687
|
+
return results;
|
|
248688
|
+
}
|
|
248689
|
+
get documentCount() {
|
|
248690
|
+
return this._documentCount;
|
|
248691
|
+
}
|
|
248692
|
+
get termCount() {
|
|
248693
|
+
return this._index.size;
|
|
248694
|
+
}
|
|
248695
|
+
static loadJSON(json, options) {
|
|
248696
|
+
if (options == null) {
|
|
248697
|
+
throw new Error("MiniSearch: loadJSON should be given the same options used when serializing the index");
|
|
248698
|
+
}
|
|
248699
|
+
return this.loadJS(JSON.parse(json), options);
|
|
248700
|
+
}
|
|
248701
|
+
static async loadJSONAsync(json, options) {
|
|
248702
|
+
if (options == null) {
|
|
248703
|
+
throw new Error("MiniSearch: loadJSON should be given the same options used when serializing the index");
|
|
248704
|
+
}
|
|
248705
|
+
return this.loadJSAsync(JSON.parse(json), options);
|
|
248706
|
+
}
|
|
248707
|
+
static getDefault(optionName) {
|
|
248708
|
+
if (defaultOptions.hasOwnProperty(optionName)) {
|
|
248709
|
+
return getOwnProperty(defaultOptions, optionName);
|
|
248710
|
+
} else {
|
|
248711
|
+
throw new Error(`MiniSearch: unknown option "${optionName}"`);
|
|
248712
|
+
}
|
|
248713
|
+
}
|
|
248714
|
+
static loadJS(js, options) {
|
|
248715
|
+
const { index, documentIds, fieldLength, storedFields, serializationVersion } = js;
|
|
248716
|
+
const miniSearch = this.instantiateMiniSearch(js, options);
|
|
248717
|
+
miniSearch._documentIds = objectToNumericMap(documentIds);
|
|
248718
|
+
miniSearch._fieldLength = objectToNumericMap(fieldLength);
|
|
248719
|
+
miniSearch._storedFields = objectToNumericMap(storedFields);
|
|
248720
|
+
for (const [shortId, id] of miniSearch._documentIds) {
|
|
248721
|
+
miniSearch._idToShortId.set(id, shortId);
|
|
248722
|
+
}
|
|
248723
|
+
for (const [term, data] of index) {
|
|
248724
|
+
const dataMap = new Map;
|
|
248725
|
+
for (const fieldId of Object.keys(data)) {
|
|
248726
|
+
let indexEntry = data[fieldId];
|
|
248727
|
+
if (serializationVersion === 1) {
|
|
248728
|
+
indexEntry = indexEntry.ds;
|
|
248729
|
+
}
|
|
248730
|
+
dataMap.set(parseInt(fieldId, 10), objectToNumericMap(indexEntry));
|
|
248731
|
+
}
|
|
248732
|
+
miniSearch._index.set(term, dataMap);
|
|
248733
|
+
}
|
|
248734
|
+
return miniSearch;
|
|
248735
|
+
}
|
|
248736
|
+
static async loadJSAsync(js, options) {
|
|
248737
|
+
const { index, documentIds, fieldLength, storedFields, serializationVersion } = js;
|
|
248738
|
+
const miniSearch = this.instantiateMiniSearch(js, options);
|
|
248739
|
+
miniSearch._documentIds = await objectToNumericMapAsync(documentIds);
|
|
248740
|
+
miniSearch._fieldLength = await objectToNumericMapAsync(fieldLength);
|
|
248741
|
+
miniSearch._storedFields = await objectToNumericMapAsync(storedFields);
|
|
248742
|
+
for (const [shortId, id] of miniSearch._documentIds) {
|
|
248743
|
+
miniSearch._idToShortId.set(id, shortId);
|
|
248744
|
+
}
|
|
248745
|
+
let count = 0;
|
|
248746
|
+
for (const [term, data] of index) {
|
|
248747
|
+
const dataMap = new Map;
|
|
248748
|
+
for (const fieldId of Object.keys(data)) {
|
|
248749
|
+
let indexEntry = data[fieldId];
|
|
248750
|
+
if (serializationVersion === 1) {
|
|
248751
|
+
indexEntry = indexEntry.ds;
|
|
248752
|
+
}
|
|
248753
|
+
dataMap.set(parseInt(fieldId, 10), await objectToNumericMapAsync(indexEntry));
|
|
248754
|
+
}
|
|
248755
|
+
if (++count % 1000 === 0)
|
|
248756
|
+
await wait(0);
|
|
248757
|
+
miniSearch._index.set(term, dataMap);
|
|
248758
|
+
}
|
|
248759
|
+
return miniSearch;
|
|
248760
|
+
}
|
|
248761
|
+
static instantiateMiniSearch(js, options) {
|
|
248762
|
+
const { documentCount, nextId, fieldIds, averageFieldLength, dirtCount, serializationVersion } = js;
|
|
248763
|
+
if (serializationVersion !== 1 && serializationVersion !== 2) {
|
|
248764
|
+
throw new Error("MiniSearch: cannot deserialize an index created with an incompatible version");
|
|
248765
|
+
}
|
|
248766
|
+
const miniSearch = new MiniSearch(options);
|
|
248767
|
+
miniSearch._documentCount = documentCount;
|
|
248768
|
+
miniSearch._nextId = nextId;
|
|
248769
|
+
miniSearch._idToShortId = new Map;
|
|
248770
|
+
miniSearch._fieldIds = fieldIds;
|
|
248771
|
+
miniSearch._avgFieldLength = averageFieldLength;
|
|
248772
|
+
miniSearch._dirtCount = dirtCount || 0;
|
|
248773
|
+
miniSearch._index = new SearchableMap;
|
|
248774
|
+
return miniSearch;
|
|
248775
|
+
}
|
|
248776
|
+
executeQuery(query, searchOptions = {}) {
|
|
248777
|
+
if (query === MiniSearch.wildcard) {
|
|
248778
|
+
return this.executeWildcardQuery(searchOptions);
|
|
248779
|
+
}
|
|
248780
|
+
if (typeof query !== "string") {
|
|
248781
|
+
const options = { ...searchOptions, ...query, queries: undefined };
|
|
248782
|
+
const results = query.queries.map((subquery) => this.executeQuery(subquery, options));
|
|
248783
|
+
return this.combineResults(results, options.combineWith);
|
|
248784
|
+
}
|
|
248785
|
+
const { tokenize, processTerm, searchOptions: globalSearchOptions } = this._options;
|
|
248786
|
+
const options = { tokenize, processTerm, ...globalSearchOptions, ...searchOptions };
|
|
248787
|
+
const { tokenize: searchTokenize, processTerm: searchProcessTerm } = options;
|
|
248788
|
+
const terms = searchTokenize(query).flatMap((term) => searchProcessTerm(term)).filter((term) => !!term);
|
|
248789
|
+
const queries = terms.map(termToQuerySpec(options));
|
|
248790
|
+
const results = queries.map((query) => this.executeQuerySpec(query, options));
|
|
248791
|
+
return this.combineResults(results, options.combineWith);
|
|
248792
|
+
}
|
|
248793
|
+
executeQuerySpec(query, searchOptions) {
|
|
248794
|
+
const options = { ...this._options.searchOptions, ...searchOptions };
|
|
248795
|
+
const boosts = (options.fields || this._options.fields).reduce((boosts, field) => ({ ...boosts, [field]: getOwnProperty(options.boost, field) || 1 }), {});
|
|
248796
|
+
const { boostDocument, weights, maxFuzzy, bm25: bm25params } = options;
|
|
248797
|
+
const { fuzzy: fuzzyWeight, prefix: prefixWeight } = { ...defaultSearchOptions.weights, ...weights };
|
|
248798
|
+
const data = this._index.get(query.term);
|
|
248799
|
+
const results = this.termResults(query.term, query.term, 1, query.termBoost, data, boosts, boostDocument, bm25params);
|
|
248800
|
+
let prefixMatches;
|
|
248801
|
+
let fuzzyMatches;
|
|
248802
|
+
if (query.prefix) {
|
|
248803
|
+
prefixMatches = this._index.atPrefix(query.term);
|
|
248804
|
+
}
|
|
248805
|
+
if (query.fuzzy) {
|
|
248806
|
+
const fuzzy = query.fuzzy === true ? 0.2 : query.fuzzy;
|
|
248807
|
+
const maxDistance = fuzzy < 1 ? Math.min(maxFuzzy, Math.round(query.term.length * fuzzy)) : fuzzy;
|
|
248808
|
+
if (maxDistance)
|
|
248809
|
+
fuzzyMatches = this._index.fuzzyGet(query.term, maxDistance);
|
|
248810
|
+
}
|
|
248811
|
+
if (prefixMatches) {
|
|
248812
|
+
for (const [term, data] of prefixMatches) {
|
|
248813
|
+
const distance = term.length - query.term.length;
|
|
248814
|
+
if (!distance) {
|
|
248815
|
+
continue;
|
|
248816
|
+
}
|
|
248817
|
+
fuzzyMatches === null || fuzzyMatches === undefined || fuzzyMatches.delete(term);
|
|
248818
|
+
const weight = prefixWeight * term.length / (term.length + 0.3 * distance);
|
|
248819
|
+
this.termResults(query.term, term, weight, query.termBoost, data, boosts, boostDocument, bm25params, results);
|
|
248820
|
+
}
|
|
248821
|
+
}
|
|
248822
|
+
if (fuzzyMatches) {
|
|
248823
|
+
for (const term of fuzzyMatches.keys()) {
|
|
248824
|
+
const [data, distance] = fuzzyMatches.get(term);
|
|
248825
|
+
if (!distance) {
|
|
248826
|
+
continue;
|
|
248827
|
+
}
|
|
248828
|
+
const weight = fuzzyWeight * term.length / (term.length + distance);
|
|
248829
|
+
this.termResults(query.term, term, weight, query.termBoost, data, boosts, boostDocument, bm25params, results);
|
|
248830
|
+
}
|
|
248831
|
+
}
|
|
248832
|
+
return results;
|
|
248833
|
+
}
|
|
248834
|
+
executeWildcardQuery(searchOptions) {
|
|
248835
|
+
const results = new Map;
|
|
248836
|
+
const options = { ...this._options.searchOptions, ...searchOptions };
|
|
248837
|
+
for (const [shortId, id] of this._documentIds) {
|
|
248838
|
+
const score = options.boostDocument ? options.boostDocument(id, "", this._storedFields.get(shortId)) : 1;
|
|
248839
|
+
results.set(shortId, {
|
|
248840
|
+
score,
|
|
248841
|
+
terms: [],
|
|
248842
|
+
match: {}
|
|
248843
|
+
});
|
|
248844
|
+
}
|
|
248845
|
+
return results;
|
|
248846
|
+
}
|
|
248847
|
+
combineResults(results, combineWith = OR) {
|
|
248848
|
+
if (results.length === 0) {
|
|
248849
|
+
return new Map;
|
|
248850
|
+
}
|
|
248851
|
+
const operator = combineWith.toLowerCase();
|
|
248852
|
+
const combinator = combinators[operator];
|
|
248853
|
+
if (!combinator) {
|
|
248854
|
+
throw new Error(`Invalid combination operator: ${combineWith}`);
|
|
248855
|
+
}
|
|
248856
|
+
return results.reduce(combinator) || new Map;
|
|
248857
|
+
}
|
|
248858
|
+
toJSON() {
|
|
248859
|
+
const index = [];
|
|
248860
|
+
for (const [term, fieldIndex] of this._index) {
|
|
248861
|
+
const data = {};
|
|
248862
|
+
for (const [fieldId, freqs] of fieldIndex) {
|
|
248863
|
+
data[fieldId] = Object.fromEntries(freqs);
|
|
248864
|
+
}
|
|
248865
|
+
index.push([term, data]);
|
|
248866
|
+
}
|
|
248867
|
+
return {
|
|
248868
|
+
documentCount: this._documentCount,
|
|
248869
|
+
nextId: this._nextId,
|
|
248870
|
+
documentIds: Object.fromEntries(this._documentIds),
|
|
248871
|
+
fieldIds: this._fieldIds,
|
|
248872
|
+
fieldLength: Object.fromEntries(this._fieldLength),
|
|
248873
|
+
averageFieldLength: this._avgFieldLength,
|
|
248874
|
+
storedFields: Object.fromEntries(this._storedFields),
|
|
248875
|
+
dirtCount: this._dirtCount,
|
|
248876
|
+
index,
|
|
248877
|
+
serializationVersion: 2
|
|
248878
|
+
};
|
|
248879
|
+
}
|
|
248880
|
+
termResults(sourceTerm, derivedTerm, termWeight, termBoost, fieldTermData, fieldBoosts, boostDocumentFn, bm25params, results = new Map) {
|
|
248881
|
+
if (fieldTermData == null)
|
|
248882
|
+
return results;
|
|
248883
|
+
for (const field of Object.keys(fieldBoosts)) {
|
|
248884
|
+
const fieldBoost = fieldBoosts[field];
|
|
248885
|
+
const fieldId = this._fieldIds[field];
|
|
248886
|
+
const fieldTermFreqs = fieldTermData.get(fieldId);
|
|
248887
|
+
if (fieldTermFreqs == null)
|
|
248888
|
+
continue;
|
|
248889
|
+
let matchingFields = fieldTermFreqs.size;
|
|
248890
|
+
const avgFieldLength = this._avgFieldLength[fieldId];
|
|
248891
|
+
for (const docId of fieldTermFreqs.keys()) {
|
|
248892
|
+
if (!this._documentIds.has(docId)) {
|
|
248893
|
+
this.removeTerm(fieldId, docId, derivedTerm);
|
|
248894
|
+
matchingFields -= 1;
|
|
248895
|
+
continue;
|
|
248896
|
+
}
|
|
248897
|
+
const docBoost = boostDocumentFn ? boostDocumentFn(this._documentIds.get(docId), derivedTerm, this._storedFields.get(docId)) : 1;
|
|
248898
|
+
if (!docBoost)
|
|
248899
|
+
continue;
|
|
248900
|
+
const termFreq = fieldTermFreqs.get(docId);
|
|
248901
|
+
const fieldLength = this._fieldLength.get(docId)[fieldId];
|
|
248902
|
+
const rawScore = calcBM25Score(termFreq, matchingFields, this._documentCount, fieldLength, avgFieldLength, bm25params);
|
|
248903
|
+
const weightedScore = termWeight * termBoost * fieldBoost * docBoost * rawScore;
|
|
248904
|
+
const result = results.get(docId);
|
|
248905
|
+
if (result) {
|
|
248906
|
+
result.score += weightedScore;
|
|
248907
|
+
assignUniqueTerm(result.terms, sourceTerm);
|
|
248908
|
+
const match = getOwnProperty(result.match, derivedTerm);
|
|
248909
|
+
if (match) {
|
|
248910
|
+
match.push(field);
|
|
248911
|
+
} else {
|
|
248912
|
+
result.match[derivedTerm] = [field];
|
|
248913
|
+
}
|
|
248914
|
+
} else {
|
|
248915
|
+
results.set(docId, {
|
|
248916
|
+
score: weightedScore,
|
|
248917
|
+
terms: [sourceTerm],
|
|
248918
|
+
match: { [derivedTerm]: [field] }
|
|
248919
|
+
});
|
|
248920
|
+
}
|
|
248921
|
+
}
|
|
248922
|
+
}
|
|
248923
|
+
return results;
|
|
248924
|
+
}
|
|
248925
|
+
addTerm(fieldId, documentId, term) {
|
|
248926
|
+
const indexData = this._index.fetch(term, createMap);
|
|
248927
|
+
let fieldIndex = indexData.get(fieldId);
|
|
248928
|
+
if (fieldIndex == null) {
|
|
248929
|
+
fieldIndex = new Map;
|
|
248930
|
+
fieldIndex.set(documentId, 1);
|
|
248931
|
+
indexData.set(fieldId, fieldIndex);
|
|
248932
|
+
} else {
|
|
248933
|
+
const docs = fieldIndex.get(documentId);
|
|
248934
|
+
fieldIndex.set(documentId, (docs || 0) + 1);
|
|
248935
|
+
}
|
|
248936
|
+
}
|
|
248937
|
+
removeTerm(fieldId, documentId, term) {
|
|
248938
|
+
if (!this._index.has(term)) {
|
|
248939
|
+
this.warnDocumentChanged(documentId, fieldId, term);
|
|
248940
|
+
return;
|
|
248941
|
+
}
|
|
248942
|
+
const indexData = this._index.fetch(term, createMap);
|
|
248943
|
+
const fieldIndex = indexData.get(fieldId);
|
|
248944
|
+
if (fieldIndex == null || fieldIndex.get(documentId) == null) {
|
|
248945
|
+
this.warnDocumentChanged(documentId, fieldId, term);
|
|
248946
|
+
} else if (fieldIndex.get(documentId) <= 1) {
|
|
248947
|
+
if (fieldIndex.size <= 1) {
|
|
248948
|
+
indexData.delete(fieldId);
|
|
248949
|
+
} else {
|
|
248950
|
+
fieldIndex.delete(documentId);
|
|
248951
|
+
}
|
|
248952
|
+
} else {
|
|
248953
|
+
fieldIndex.set(documentId, fieldIndex.get(documentId) - 1);
|
|
248954
|
+
}
|
|
248955
|
+
if (this._index.get(term).size === 0) {
|
|
248956
|
+
this._index.delete(term);
|
|
248957
|
+
}
|
|
248958
|
+
}
|
|
248959
|
+
warnDocumentChanged(shortDocumentId, fieldId, term) {
|
|
248960
|
+
for (const fieldName of Object.keys(this._fieldIds)) {
|
|
248961
|
+
if (this._fieldIds[fieldName] === fieldId) {
|
|
248962
|
+
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");
|
|
248963
|
+
return;
|
|
248964
|
+
}
|
|
248965
|
+
}
|
|
248966
|
+
}
|
|
248967
|
+
addDocumentId(documentId) {
|
|
248968
|
+
const shortDocumentId = this._nextId;
|
|
248969
|
+
this._idToShortId.set(documentId, shortDocumentId);
|
|
248970
|
+
this._documentIds.set(shortDocumentId, documentId);
|
|
248971
|
+
this._documentCount += 1;
|
|
248972
|
+
this._nextId += 1;
|
|
248973
|
+
return shortDocumentId;
|
|
248974
|
+
}
|
|
248975
|
+
addFields(fields) {
|
|
248976
|
+
for (let i = 0;i < fields.length; i++) {
|
|
248977
|
+
this._fieldIds[fields[i]] = i;
|
|
248978
|
+
}
|
|
248979
|
+
}
|
|
248980
|
+
addFieldLength(documentId, fieldId, count, length) {
|
|
248981
|
+
let fieldLengths = this._fieldLength.get(documentId);
|
|
248982
|
+
if (fieldLengths == null)
|
|
248983
|
+
this._fieldLength.set(documentId, fieldLengths = []);
|
|
248984
|
+
fieldLengths[fieldId] = length;
|
|
248985
|
+
const averageFieldLength = this._avgFieldLength[fieldId] || 0;
|
|
248986
|
+
const totalFieldLength = averageFieldLength * count + length;
|
|
248987
|
+
this._avgFieldLength[fieldId] = totalFieldLength / (count + 1);
|
|
248988
|
+
}
|
|
248989
|
+
removeFieldLength(documentId, fieldId, count, length) {
|
|
248990
|
+
if (count === 1) {
|
|
248991
|
+
this._avgFieldLength[fieldId] = 0;
|
|
248992
|
+
return;
|
|
248993
|
+
}
|
|
248994
|
+
const totalFieldLength = this._avgFieldLength[fieldId] * count - length;
|
|
248995
|
+
this._avgFieldLength[fieldId] = totalFieldLength / (count - 1);
|
|
248996
|
+
}
|
|
248997
|
+
saveStoredFields(documentId, doc) {
|
|
248998
|
+
const { storeFields, extractField } = this._options;
|
|
248999
|
+
if (storeFields == null || storeFields.length === 0) {
|
|
249000
|
+
return;
|
|
249001
|
+
}
|
|
249002
|
+
let documentFields = this._storedFields.get(documentId);
|
|
249003
|
+
if (documentFields == null)
|
|
249004
|
+
this._storedFields.set(documentId, documentFields = {});
|
|
249005
|
+
for (const fieldName of storeFields) {
|
|
249006
|
+
const fieldValue = extractField(doc, fieldName);
|
|
249007
|
+
if (fieldValue !== undefined)
|
|
249008
|
+
documentFields[fieldName] = fieldValue;
|
|
249009
|
+
}
|
|
249010
|
+
}
|
|
249011
|
+
}
|
|
249012
|
+
MiniSearch.wildcard = Symbol("*");
|
|
249013
|
+
var getOwnProperty = (object, property) => Object.prototype.hasOwnProperty.call(object, property) ? object[property] : undefined;
|
|
249014
|
+
var combinators = {
|
|
249015
|
+
[OR]: (a, b) => {
|
|
249016
|
+
for (const docId of b.keys()) {
|
|
249017
|
+
const existing = a.get(docId);
|
|
249018
|
+
if (existing == null) {
|
|
249019
|
+
a.set(docId, b.get(docId));
|
|
249020
|
+
} else {
|
|
249021
|
+
const { score, terms, match } = b.get(docId);
|
|
249022
|
+
existing.score = existing.score + score;
|
|
249023
|
+
existing.match = Object.assign(existing.match, match);
|
|
249024
|
+
assignUniqueTerms(existing.terms, terms);
|
|
249025
|
+
}
|
|
249026
|
+
}
|
|
249027
|
+
return a;
|
|
249028
|
+
},
|
|
249029
|
+
[AND]: (a, b) => {
|
|
249030
|
+
const combined = new Map;
|
|
249031
|
+
for (const docId of b.keys()) {
|
|
249032
|
+
const existing = a.get(docId);
|
|
249033
|
+
if (existing == null)
|
|
249034
|
+
continue;
|
|
249035
|
+
const { score, terms, match } = b.get(docId);
|
|
249036
|
+
assignUniqueTerms(existing.terms, terms);
|
|
249037
|
+
combined.set(docId, {
|
|
249038
|
+
score: existing.score + score,
|
|
249039
|
+
terms: existing.terms,
|
|
249040
|
+
match: Object.assign(existing.match, match)
|
|
249041
|
+
});
|
|
249042
|
+
}
|
|
249043
|
+
return combined;
|
|
249044
|
+
},
|
|
249045
|
+
[AND_NOT]: (a, b) => {
|
|
249046
|
+
for (const docId of b.keys())
|
|
249047
|
+
a.delete(docId);
|
|
249048
|
+
return a;
|
|
249049
|
+
}
|
|
249050
|
+
};
|
|
249051
|
+
var defaultBM25params = { k: 1.2, b: 0.7, d: 0.5 };
|
|
249052
|
+
var calcBM25Score = (termFreq, matchingCount, totalCount, fieldLength, avgFieldLength, bm25params) => {
|
|
249053
|
+
const { k, b, d } = bm25params;
|
|
249054
|
+
const invDocFreq = Math.log(1 + (totalCount - matchingCount + 0.5) / (matchingCount + 0.5));
|
|
249055
|
+
return invDocFreq * (d + termFreq * (k + 1) / (termFreq + k * (1 - b + b * fieldLength / avgFieldLength)));
|
|
249056
|
+
};
|
|
249057
|
+
var termToQuerySpec = (options) => (term, i, terms) => {
|
|
249058
|
+
const fuzzy = typeof options.fuzzy === "function" ? options.fuzzy(term, i, terms) : options.fuzzy || false;
|
|
249059
|
+
const prefix = typeof options.prefix === "function" ? options.prefix(term, i, terms) : options.prefix === true;
|
|
249060
|
+
const termBoost = typeof options.boostTerm === "function" ? options.boostTerm(term, i, terms) : 1;
|
|
249061
|
+
return { term, fuzzy, prefix, termBoost };
|
|
249062
|
+
};
|
|
249063
|
+
var defaultOptions = {
|
|
249064
|
+
idField: "id",
|
|
249065
|
+
extractField: (document2, fieldName) => document2[fieldName],
|
|
249066
|
+
tokenize: (text) => text.split(SPACE_OR_PUNCTUATION),
|
|
249067
|
+
processTerm: (term) => term.toLowerCase(),
|
|
249068
|
+
fields: undefined,
|
|
249069
|
+
searchOptions: undefined,
|
|
249070
|
+
storeFields: [],
|
|
249071
|
+
logger: (level, message) => {
|
|
249072
|
+
if (typeof (console === null || console === undefined ? undefined : console[level]) === "function")
|
|
249073
|
+
console[level](message);
|
|
249074
|
+
},
|
|
249075
|
+
autoVacuum: true
|
|
249076
|
+
};
|
|
249077
|
+
var defaultSearchOptions = {
|
|
249078
|
+
combineWith: OR,
|
|
249079
|
+
prefix: false,
|
|
249080
|
+
fuzzy: false,
|
|
249081
|
+
maxFuzzy: 6,
|
|
249082
|
+
boost: {},
|
|
249083
|
+
weights: { fuzzy: 0.45, prefix: 0.375 },
|
|
249084
|
+
bm25: defaultBM25params
|
|
249085
|
+
};
|
|
249086
|
+
var defaultAutoSuggestOptions = {
|
|
249087
|
+
combineWith: AND,
|
|
249088
|
+
prefix: (term, i, terms) => i === terms.length - 1
|
|
249089
|
+
};
|
|
249090
|
+
var defaultVacuumOptions = { batchSize: 1000, batchWait: 10 };
|
|
249091
|
+
var defaultVacuumConditions = { minDirtFactor: 0.1, minDirtCount: 20 };
|
|
249092
|
+
var defaultAutoVacuumOptions = { ...defaultVacuumOptions, ...defaultVacuumConditions };
|
|
249093
|
+
var assignUniqueTerm = (target, term) => {
|
|
249094
|
+
if (!target.includes(term))
|
|
249095
|
+
target.push(term);
|
|
249096
|
+
};
|
|
249097
|
+
var assignUniqueTerms = (target, source) => {
|
|
249098
|
+
for (const term of source) {
|
|
249099
|
+
if (!target.includes(term))
|
|
249100
|
+
target.push(term);
|
|
249101
|
+
}
|
|
249102
|
+
};
|
|
249103
|
+
var byScore = ({ score: a }, { score: b }) => b - a;
|
|
249104
|
+
var createMap = () => new Map;
|
|
249105
|
+
var objectToNumericMap = (object) => {
|
|
249106
|
+
const map = new Map;
|
|
249107
|
+
for (const key of Object.keys(object)) {
|
|
249108
|
+
map.set(parseInt(key, 10), object[key]);
|
|
249109
|
+
}
|
|
249110
|
+
return map;
|
|
249111
|
+
};
|
|
249112
|
+
var objectToNumericMapAsync = async (object) => {
|
|
249113
|
+
const map = new Map;
|
|
249114
|
+
let count = 0;
|
|
249115
|
+
for (const key of Object.keys(object)) {
|
|
249116
|
+
map.set(parseInt(key, 10), object[key]);
|
|
249117
|
+
if (++count % 1000 === 0) {
|
|
249118
|
+
await wait(0);
|
|
249119
|
+
}
|
|
249120
|
+
}
|
|
249121
|
+
return map;
|
|
249122
|
+
};
|
|
249123
|
+
var wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
249124
|
+
var SPACE_OR_PUNCTUATION = /[\n\r\p{Z}\p{P}]+/u;
|
|
249125
|
+
|
|
249126
|
+
// src/core/api-spec/search.ts
|
|
249127
|
+
var BOOST = { path: 8, summary: 5, description: 2, parameters: 0.5 };
|
|
249128
|
+
var MIN_RELATIVE_SCORE = 0.2;
|
|
249129
|
+
var TOKEN_SEPARATOR = /[\n\r\p{Z}\p{P}\p{S}]+/u;
|
|
249130
|
+
function toOperationSummary(op) {
|
|
249131
|
+
return {
|
|
249132
|
+
method: op.method,
|
|
249133
|
+
path: op.path,
|
|
249134
|
+
summary: op.summary,
|
|
249135
|
+
readOnly: op.readOnly
|
|
249136
|
+
};
|
|
249137
|
+
}
|
|
249138
|
+
function buildSearchIndex(operations) {
|
|
249139
|
+
const index = new MiniSearch({
|
|
249140
|
+
fields: ["path", "summary", "description", "parameters"],
|
|
249141
|
+
tokenize: (text) => text.split(TOKEN_SEPARATOR).filter(Boolean)
|
|
249142
|
+
});
|
|
249143
|
+
index.addAll(operations.map((op, id) => ({
|
|
249144
|
+
id,
|
|
249145
|
+
path: op.path.replace(/\{[^}]*\}/g, ""),
|
|
249146
|
+
summary: op.summary,
|
|
249147
|
+
description: op.description,
|
|
249148
|
+
parameters: op.parameterText
|
|
249149
|
+
})));
|
|
249150
|
+
return index;
|
|
249151
|
+
}
|
|
249152
|
+
function searchOperations(operations, query, options = {}) {
|
|
249153
|
+
const index = buildSearchIndex(operations);
|
|
249154
|
+
const hits = index.search(query, {
|
|
249155
|
+
prefix: true,
|
|
249156
|
+
fuzzy: 0.2,
|
|
249157
|
+
boost: BOOST,
|
|
249158
|
+
filter: options.readOnly ? (hit) => operations[hit.id]?.readOnly === true : undefined
|
|
249159
|
+
});
|
|
249160
|
+
const baseline = (hits[0]?.score ?? 0) * MIN_RELATIVE_SCORE;
|
|
249161
|
+
return hits.filter((hit) => hit.score >= baseline).slice(0, options.limit ?? 5).flatMap((hit) => {
|
|
249162
|
+
const op = operations[hit.id];
|
|
249163
|
+
return op ? [toOperationSummary(op)] : [];
|
|
249164
|
+
});
|
|
249165
|
+
}
|
|
249166
|
+
|
|
249167
|
+
// src/core/api-spec/grep.ts
|
|
249168
|
+
var CONTEXT_CHARS = 40;
|
|
249169
|
+
var MAX_SNIPPETS = 3;
|
|
249170
|
+
var MAX_SNIPPET_CHARS = 200;
|
|
249171
|
+
function snippets(text, pattern) {
|
|
249172
|
+
const found = [];
|
|
249173
|
+
for (const match of text.matchAll(pattern)) {
|
|
249174
|
+
const start = Math.max(0, match.index - CONTEXT_CHARS);
|
|
249175
|
+
const end = match.index + match[0].length + CONTEXT_CHARS;
|
|
249176
|
+
found.push(text.slice(start, Math.min(end, start + MAX_SNIPPET_CHARS)));
|
|
249177
|
+
if (found.length === MAX_SNIPPETS || match[0].length === 0) {
|
|
249178
|
+
break;
|
|
249179
|
+
}
|
|
249180
|
+
}
|
|
249181
|
+
return found;
|
|
249182
|
+
}
|
|
249183
|
+
function grepSpec(spec, operations, pattern, options = {}) {
|
|
249184
|
+
const regex = new RegExp(pattern, options.ignoreCase ? "gi" : "g");
|
|
249185
|
+
const hits = [];
|
|
249186
|
+
for (const op of operations) {
|
|
249187
|
+
const matches = snippets(`${op.method} ${op.path} ${JSON.stringify(op.operation)}`, regex);
|
|
249188
|
+
if (matches.length > 0) {
|
|
249189
|
+
hits.push({ ...toOperationSummary(op), matches });
|
|
249190
|
+
}
|
|
249191
|
+
}
|
|
249192
|
+
for (const [schema, definition] of Object.entries(spec.components?.schemas ?? {})) {
|
|
249193
|
+
const matches = snippets(JSON.stringify(definition), regex);
|
|
249194
|
+
if (matches.length > 0) {
|
|
249195
|
+
hits.push({ schema, matches });
|
|
249196
|
+
}
|
|
249197
|
+
}
|
|
249198
|
+
return hits.slice(0, options.limit ?? 20);
|
|
249199
|
+
}
|
|
249200
|
+
// src/core/api-spec/schema.ts
|
|
249201
|
+
var HTTP_METHODS = [
|
|
249202
|
+
"get",
|
|
249203
|
+
"put",
|
|
249204
|
+
"post",
|
|
249205
|
+
"delete",
|
|
249206
|
+
"patch",
|
|
249207
|
+
"head",
|
|
249208
|
+
"options",
|
|
249209
|
+
"trace"
|
|
249210
|
+
];
|
|
249211
|
+
var ParameterSchema = looseObject({
|
|
249212
|
+
name: string2(),
|
|
249213
|
+
in: string2(),
|
|
249214
|
+
required: boolean2().optional(),
|
|
249215
|
+
description: string2().optional(),
|
|
249216
|
+
schema: unknown().optional()
|
|
249217
|
+
});
|
|
249218
|
+
var SecurityRequirementSchema = record(string2(), array(string2()));
|
|
249219
|
+
var OperationSchema = looseObject({
|
|
249220
|
+
summary: string2().optional(),
|
|
249221
|
+
description: string2().optional(),
|
|
249222
|
+
operationId: string2().optional(),
|
|
249223
|
+
parameters: array(unknown()).optional(),
|
|
249224
|
+
requestBody: unknown().optional(),
|
|
249225
|
+
responses: record(string2(), unknown()).optional(),
|
|
249226
|
+
security: array(SecurityRequirementSchema).optional()
|
|
249227
|
+
});
|
|
249228
|
+
var PathItemSchema = looseObject(Object.fromEntries(HTTP_METHODS.map((method) => [method, OperationSchema.optional()])));
|
|
249229
|
+
var OpenApiSpecSchema = looseObject({
|
|
249230
|
+
openapi: string2(),
|
|
249231
|
+
paths: record(string2(), PathItemSchema),
|
|
249232
|
+
components: looseObject({
|
|
249233
|
+
schemas: record(string2(), unknown()).optional()
|
|
249234
|
+
}).optional(),
|
|
249235
|
+
security: array(SecurityRequirementSchema).optional()
|
|
249236
|
+
});
|
|
249237
|
+
|
|
249238
|
+
// src/core/api-spec/operations.ts
|
|
249239
|
+
var PERSONAL_ACCESS_TOKEN_SCHEME = "PersonalAccessTokenAuth";
|
|
249240
|
+
var READ_ONLY_SCOPE = "read_only";
|
|
249241
|
+
function isReadOnly(operation, spec) {
|
|
249242
|
+
const security = operation.security ?? spec.security ?? [];
|
|
249243
|
+
return security.some((requirement) => requirement[PERSONAL_ACCESS_TOKEN_SCHEME]?.includes(READ_ONLY_SCOPE));
|
|
249244
|
+
}
|
|
249245
|
+
function parameterText(operation) {
|
|
249246
|
+
return (operation.parameters ?? []).flatMap((parameter) => {
|
|
249247
|
+
const parsed = ParameterSchema.safeParse(parameter);
|
|
249248
|
+
return parsed.success ? [parsed.data.name, parsed.data.description ?? ""] : [];
|
|
249249
|
+
}).join(" ");
|
|
249250
|
+
}
|
|
249251
|
+
function listOperations(spec) {
|
|
249252
|
+
return Object.entries(spec.paths).flatMap(([path, item]) => HTTP_METHODS.flatMap((method) => {
|
|
249253
|
+
const operation = item[method];
|
|
249254
|
+
if (!operation) {
|
|
249255
|
+
return [];
|
|
249256
|
+
}
|
|
249257
|
+
return [
|
|
249258
|
+
{
|
|
249259
|
+
method: method.toUpperCase(),
|
|
249260
|
+
path,
|
|
249261
|
+
summary: operation.summary ?? "",
|
|
249262
|
+
description: operation.description ?? "",
|
|
249263
|
+
parameterText: parameterText(operation),
|
|
249264
|
+
readOnly: isReadOnly(operation, spec),
|
|
249265
|
+
operation
|
|
249266
|
+
}
|
|
249267
|
+
];
|
|
249268
|
+
}));
|
|
249269
|
+
}
|
|
249270
|
+
function pathSegments(path) {
|
|
249271
|
+
const pathname = path.split(/[?#]/, 1)[0] ?? "";
|
|
249272
|
+
return pathname.split("/").filter(Boolean);
|
|
249273
|
+
}
|
|
249274
|
+
function segmentPattern(segment) {
|
|
249275
|
+
const source = segment.split(/(\{[^}]+\})/).map((part) => part.startsWith("{") ? "[^/]+" : part.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")).join("");
|
|
249276
|
+
return new RegExp(`^${source}$`);
|
|
249277
|
+
}
|
|
249278
|
+
function specificity(templateSegments) {
|
|
249279
|
+
return templateSegments.map((segment) => segment.includes("{") ? 0 : 1);
|
|
249280
|
+
}
|
|
249281
|
+
function compareSpecificity(a, b) {
|
|
249282
|
+
for (let i = 0;i < a.length; i++) {
|
|
249283
|
+
if (a[i] !== b[i]) {
|
|
249284
|
+
return (b[i] ?? 0) - (a[i] ?? 0);
|
|
249285
|
+
}
|
|
249286
|
+
}
|
|
249287
|
+
return 0;
|
|
249288
|
+
}
|
|
249289
|
+
function matchOperation(operations, method, concretePath) {
|
|
249290
|
+
const upperMethod = method.toUpperCase();
|
|
249291
|
+
const segments = pathSegments(concretePath);
|
|
249292
|
+
const candidates = operations.filter((op) => {
|
|
249293
|
+
if (op.method !== upperMethod) {
|
|
249294
|
+
return false;
|
|
249295
|
+
}
|
|
249296
|
+
const template = pathSegments(op.path);
|
|
249297
|
+
return template.length === segments.length && template.every((part, i) => segmentPattern(part).test(segments[i] ?? ""));
|
|
249298
|
+
});
|
|
249299
|
+
return candidates.sort((a, b) => compareSpecificity(specificity(pathSegments(a.path)), specificity(pathSegments(b.path))))[0];
|
|
249300
|
+
}
|
|
249301
|
+
function collectRefs(value, spec, found) {
|
|
249302
|
+
if (Array.isArray(value)) {
|
|
249303
|
+
for (const item of value) {
|
|
249304
|
+
collectRefs(item, spec, found);
|
|
249305
|
+
}
|
|
249306
|
+
return;
|
|
249307
|
+
}
|
|
249308
|
+
if (value === null || typeof value !== "object") {
|
|
249309
|
+
return;
|
|
249310
|
+
}
|
|
249311
|
+
for (const [key, child] of Object.entries(value)) {
|
|
249312
|
+
if (key === "$ref" && typeof child === "string" && !found.has(child)) {
|
|
249313
|
+
const target = resolvePointer(spec, child);
|
|
249314
|
+
found.set(child, target);
|
|
249315
|
+
collectRefs(target, spec, found);
|
|
249316
|
+
} else {
|
|
249317
|
+
collectRefs(child, spec, found);
|
|
249318
|
+
}
|
|
249319
|
+
}
|
|
249320
|
+
}
|
|
249321
|
+
function resolvePointer(spec, ref) {
|
|
249322
|
+
if (!ref.startsWith("#/")) {
|
|
249323
|
+
return;
|
|
249324
|
+
}
|
|
249325
|
+
return ref.slice(2).split("/").map((part) => part.replace(/~1/g, "/").replace(/~0/g, "~")).reduce((node, part) => node !== null && typeof node === "object" ? node[part] : undefined, spec);
|
|
249326
|
+
}
|
|
249327
|
+
function getOperationContract(spec, op) {
|
|
249328
|
+
const { parameters, requestBody, responses } = op.operation;
|
|
249329
|
+
const refs = new Map;
|
|
249330
|
+
collectRefs({ parameters, requestBody, responses }, spec, refs);
|
|
249331
|
+
return {
|
|
249332
|
+
method: op.method,
|
|
249333
|
+
path: op.path,
|
|
249334
|
+
summary: op.summary,
|
|
249335
|
+
description: op.description,
|
|
249336
|
+
readOnly: op.readOnly,
|
|
249337
|
+
parameters: parameters ?? [],
|
|
249338
|
+
requestBody: requestBody ?? null,
|
|
249339
|
+
responses: responses ?? {},
|
|
249340
|
+
refs: Object.fromEntries(refs)
|
|
249341
|
+
};
|
|
249342
|
+
}
|
|
249343
|
+
// src/core/api-spec/request.ts
|
|
249344
|
+
async function sendApiRequest(method, path, body) {
|
|
249345
|
+
try {
|
|
249346
|
+
const response = await base44Client(path.replace(/^\/+/, ""), {
|
|
249347
|
+
method,
|
|
249348
|
+
body,
|
|
249349
|
+
headers: body === undefined ? {} : { "Content-Type": "application/json" }
|
|
249350
|
+
});
|
|
249351
|
+
return await response.text();
|
|
249352
|
+
} catch (error) {
|
|
249353
|
+
throw await ApiError.fromHttpError(error, `calling ${method} ${path}`);
|
|
249354
|
+
}
|
|
249355
|
+
}
|
|
249356
|
+
// src/core/api-spec/spec.ts
|
|
249357
|
+
import { stat as stat3 } from "node:fs/promises";
|
|
249358
|
+
import { join as join22 } from "node:path";
|
|
249359
|
+
var SPEC_CACHE_TTL_MS = 60 * 60 * 1000;
|
|
249360
|
+
function getSpecCachePath(apiUrl = getBase44ApiUrl()) {
|
|
249361
|
+
const server = new URL(apiUrl).host.replace(/[^a-zA-Z0-9.-]/g, "_");
|
|
249362
|
+
return join22(getBase44GlobalDir(), "cache", server, "openapi.json");
|
|
249363
|
+
}
|
|
249364
|
+
function isSpecCacheFresh(mtimeMs, now = Date.now()) {
|
|
249365
|
+
return now - mtimeMs < SPEC_CACHE_TTL_MS;
|
|
249366
|
+
}
|
|
249367
|
+
function parseSpec(text) {
|
|
249368
|
+
let json;
|
|
249369
|
+
try {
|
|
249370
|
+
json = JSON.parse(text);
|
|
249371
|
+
} catch {
|
|
249372
|
+
throw new ApiError("The API spec from the server is not valid JSON");
|
|
249373
|
+
}
|
|
249374
|
+
const result = OpenApiSpecSchema.safeParse(json);
|
|
249375
|
+
if (!result.success) {
|
|
249376
|
+
throw new SchemaValidationError("Invalid API spec", result.error);
|
|
249377
|
+
}
|
|
249378
|
+
return result.data;
|
|
249379
|
+
}
|
|
249380
|
+
async function readFreshCache(path) {
|
|
249381
|
+
try {
|
|
249382
|
+
const { mtimeMs } = await stat3(path);
|
|
249383
|
+
return isSpecCacheFresh(mtimeMs) ? await readTextFile(path) : null;
|
|
249384
|
+
} catch {
|
|
249385
|
+
return null;
|
|
249386
|
+
}
|
|
249387
|
+
}
|
|
249388
|
+
async function downloadSpec() {
|
|
249389
|
+
try {
|
|
249390
|
+
const response = await base44Client.get("api/openapi.json");
|
|
249391
|
+
return await response.text();
|
|
249392
|
+
} catch (error) {
|
|
249393
|
+
throw await ApiError.fromHttpError(error, "fetching the API spec");
|
|
249394
|
+
}
|
|
249395
|
+
}
|
|
249396
|
+
async function loadSpec(options = {}) {
|
|
249397
|
+
const path = getSpecCachePath();
|
|
249398
|
+
const cached = options.refresh ? null : await readFreshCache(path);
|
|
249399
|
+
if (cached !== null) {
|
|
249400
|
+
return { text: cached, spec: parseSpec(cached) };
|
|
249401
|
+
}
|
|
249402
|
+
const text = await downloadSpec();
|
|
249403
|
+
const spec = parseSpec(text);
|
|
249404
|
+
await writeFile(path, text);
|
|
249405
|
+
return { text, spec };
|
|
249406
|
+
}
|
|
249407
|
+
// src/cli/commands/api/shared.ts
|
|
249408
|
+
function formatJson(value) {
|
|
249409
|
+
return `${JSON.stringify(value, null, process.stdout.isTTY ? 2 : undefined)}
|
|
249410
|
+
`;
|
|
249411
|
+
}
|
|
249412
|
+
function formatResponseBody(text) {
|
|
249413
|
+
if (!text) {
|
|
249414
|
+
return "";
|
|
249415
|
+
}
|
|
249416
|
+
try {
|
|
249417
|
+
return formatJson(JSON.parse(text));
|
|
249418
|
+
} catch {
|
|
249419
|
+
return text.endsWith(`
|
|
249420
|
+
`) ? text : `${text}
|
|
249421
|
+
`;
|
|
249422
|
+
}
|
|
249423
|
+
}
|
|
249424
|
+
function parseLimit(value) {
|
|
249425
|
+
if (value === undefined) {
|
|
249426
|
+
return;
|
|
249427
|
+
}
|
|
249428
|
+
const n = Number.parseInt(value, 10);
|
|
249429
|
+
if (!Number.isInteger(n) || n < 1) {
|
|
249430
|
+
throw new InvalidInputError("--limit must be a positive integer.");
|
|
249431
|
+
}
|
|
249432
|
+
return n;
|
|
249433
|
+
}
|
|
249434
|
+
var REFRESH_OPTION_HELP = "Fetch the API spec again instead of using the cached copy (kept 1 hour)";
|
|
249435
|
+
function loadSpecTask({ runTask }, refresh) {
|
|
249436
|
+
return runTask("Loading the API spec", () => loadSpec({ refresh }), {
|
|
249437
|
+
successMessage: "Loaded the API spec"
|
|
249438
|
+
});
|
|
249439
|
+
}
|
|
249440
|
+
|
|
249441
|
+
// src/cli/commands/api/fetch.ts
|
|
249442
|
+
async function findOperation(ctx, method, path, refresh) {
|
|
249443
|
+
const { spec } = await loadSpecTask(ctx, refresh);
|
|
249444
|
+
const op = matchOperation(listOperations(spec), method, path);
|
|
249445
|
+
if (!op) {
|
|
249446
|
+
throw new InvalidInputError(`No operation in the API spec matches ${method} ${path}.`, {
|
|
249447
|
+
hints: [
|
|
249448
|
+
{
|
|
249449
|
+
message: "Find the operation and its path template",
|
|
249450
|
+
command: 'base44 api search "<what you want to do>"'
|
|
249451
|
+
}
|
|
249452
|
+
]
|
|
249453
|
+
});
|
|
249454
|
+
}
|
|
249455
|
+
return { spec, op };
|
|
249456
|
+
}
|
|
249457
|
+
async function fetchAction(ctx, methodArg, path, options, command) {
|
|
249458
|
+
if (!methodArg || !path) {
|
|
249459
|
+
if (options.help) {
|
|
249460
|
+
return { stdout: command.helpInformation() };
|
|
249461
|
+
}
|
|
249462
|
+
throw new InvalidInputError("Provide a method and a path, e.g. GET /api/apps.");
|
|
249463
|
+
}
|
|
249464
|
+
const method = methodArg.toUpperCase();
|
|
249465
|
+
if (!HTTP_METHODS.some((m) => m.toUpperCase() === method)) {
|
|
249466
|
+
throw new InvalidInputError(`Unknown HTTP method: ${methodArg}`);
|
|
249467
|
+
}
|
|
249468
|
+
if (!path.startsWith("/")) {
|
|
249469
|
+
throw new InvalidInputError(`The path must start with "/", got ${path}.`);
|
|
249470
|
+
}
|
|
249471
|
+
if (options.help) {
|
|
249472
|
+
const { spec, op } = await findOperation(ctx, method, path, options.refresh);
|
|
249473
|
+
return { stdout: formatJson(getOperationContract(spec, op)) };
|
|
249474
|
+
}
|
|
249475
|
+
if (options.readOnly) {
|
|
249476
|
+
const { op } = await findOperation(ctx, method, path, options.refresh);
|
|
249477
|
+
if (!op.readOnly) {
|
|
249478
|
+
throw new InvalidInputError(`Refused under --read-only: ${op.method} ${op.path} is not a read-only operation. Nothing was sent.`);
|
|
249479
|
+
}
|
|
249480
|
+
}
|
|
249481
|
+
const body = await resolveRequestBody(method, options.body, {
|
|
249482
|
+
stdinIsTTY: Boolean(process.stdin.isTTY),
|
|
249483
|
+
readStdin: () => readStdin("--body @-", { trim: false })
|
|
249484
|
+
});
|
|
249485
|
+
await ensureAuth(ctx);
|
|
249486
|
+
const text = await ctx.runTask(`Calling ${method} ${path}`, () => sendApiRequest(method, path, body), { successMessage: `Called ${method} ${path}` });
|
|
249487
|
+
return { stdout: formatResponseBody(text) };
|
|
249488
|
+
}
|
|
249489
|
+
function getApiFetchCommand() {
|
|
249490
|
+
return new Base44Command("fetch", {
|
|
249491
|
+
requireAuth: false,
|
|
249492
|
+
requireAppContext: false
|
|
249493
|
+
}).description("Call a Base44 API operation, like curl; add --help after a path for its contract").helpOption(false).argument("[method]", "HTTP method, e.g. GET or POST").argument("[path]", 'Concrete path with any query string, e.g. "/api/apps/<app-id>/workflows/runs?status=failed"').option("--body <json>", "Request body: JSON, @file.json, or @- for stdin (piped stdin is read too)").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").action(fetchAction);
|
|
249494
|
+
}
|
|
249495
|
+
|
|
249496
|
+
// src/cli/commands/api/grep.ts
|
|
249497
|
+
function assertValidRegex(pattern) {
|
|
249498
|
+
try {
|
|
249499
|
+
new RegExp(pattern);
|
|
249500
|
+
} catch (error) {
|
|
249501
|
+
throw new InvalidInputError(`Invalid regular expression: ${error instanceof Error ? error.message : pattern}`);
|
|
249502
|
+
}
|
|
249503
|
+
}
|
|
249504
|
+
async function grepAction(ctx, pattern, options) {
|
|
249505
|
+
const limit = parseLimit(options.limit);
|
|
249506
|
+
assertValidRegex(pattern);
|
|
249507
|
+
const { spec } = await loadSpecTask(ctx, options.refresh);
|
|
249508
|
+
const hits = grepSpec(spec, listOperations(spec), pattern, {
|
|
249509
|
+
ignoreCase: options.ignoreCase,
|
|
249510
|
+
limit
|
|
249511
|
+
});
|
|
249512
|
+
return { stdout: formatJson(hits) };
|
|
249513
|
+
}
|
|
249514
|
+
function getApiGrepCommand() {
|
|
249515
|
+
return new Base44Command("grep", {
|
|
249516
|
+
requireAuth: false,
|
|
249517
|
+
requireAppContext: false
|
|
249518
|
+
}).description("Search the raw API spec with a regular expression, for when search misses").argument("<pattern>", 'Regular expression, e.g. "runs.*status"').option("-i, --ignore-case", "Case-insensitive match").option("--limit <n>", "Most operations or schemas to return (default 20)").option("--refresh", REFRESH_OPTION_HELP).action(grepAction);
|
|
249519
|
+
}
|
|
249520
|
+
|
|
249521
|
+
// src/cli/commands/api/search.ts
|
|
249522
|
+
async function searchAction(ctx, words, options) {
|
|
249523
|
+
const limit = parseLimit(options.limit);
|
|
249524
|
+
const { spec } = await loadSpecTask(ctx, options.refresh);
|
|
249525
|
+
const results = searchOperations(listOperations(spec), words.join(" "), {
|
|
249526
|
+
limit,
|
|
249527
|
+
readOnly: options.readOnly
|
|
249528
|
+
});
|
|
249529
|
+
return { stdout: formatJson(results) };
|
|
249530
|
+
}
|
|
249531
|
+
function getApiSearchCommand() {
|
|
249532
|
+
return new Base44Command("search", {
|
|
249533
|
+
requireAuth: false,
|
|
249534
|
+
requireAppContext: false
|
|
249535
|
+
}).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", "Return only read-only operations").option("--refresh", REFRESH_OPTION_HELP).action(searchAction);
|
|
249536
|
+
}
|
|
249537
|
+
|
|
249538
|
+
// src/cli/commands/api/index.ts
|
|
249539
|
+
function getApiCommand() {
|
|
249540
|
+
return new Command2("api").description("Search and call any public Base44 API operation").addCommand(getApiSearchCommand()).addCommand(getApiGrepCommand()).addCommand(getApiFetchCommand());
|
|
249541
|
+
}
|
|
249542
|
+
|
|
248044
249543
|
// src/cli/commands/auth/password-login.ts
|
|
248045
|
-
import { dirname as dirname16, join as
|
|
249544
|
+
import { dirname as dirname16, join as join23 } from "node:path";
|
|
248046
249545
|
async function passwordLoginAction({ log, runTask }, action) {
|
|
248047
249546
|
const shouldEnable = action === "enable";
|
|
248048
249547
|
const { project } = await readProjectConfig();
|
|
248049
249548
|
const configDir = dirname16(project.configPath);
|
|
248050
|
-
const authDir =
|
|
249549
|
+
const authDir = join23(configDir, project.authDir);
|
|
248051
249550
|
const updated = await runTask("Updating local auth config", async () => {
|
|
248052
249551
|
const current = await readAuthConfig(authDir) ?? DEFAULT_AUTH_CONFIG;
|
|
248053
249552
|
const merged = { ...current, enableUsernamePassword: shouldEnable };
|
|
@@ -248067,14 +249566,14 @@ function getPasswordLoginCommand() {
|
|
|
248067
249566
|
}
|
|
248068
249567
|
|
|
248069
249568
|
// src/cli/commands/auth/pull.ts
|
|
248070
|
-
import { dirname as dirname17, join as
|
|
249569
|
+
import { dirname as dirname17, join as join24 } from "node:path";
|
|
248071
249570
|
async function pullAuthAction({
|
|
248072
249571
|
log,
|
|
248073
249572
|
runTask
|
|
248074
249573
|
}) {
|
|
248075
249574
|
const { project } = await readProjectConfig();
|
|
248076
249575
|
const configDir = dirname17(project.configPath);
|
|
248077
|
-
const authDir =
|
|
249576
|
+
const authDir = join24(configDir, project.authDir);
|
|
248078
249577
|
const remoteConfig = await runTask("Fetching auth config from Base44", async () => {
|
|
248079
249578
|
return await pullAuthConfig();
|
|
248080
249579
|
}, {
|
|
@@ -248138,7 +249637,7 @@ function getAuthPushCommand() {
|
|
|
248138
249637
|
}
|
|
248139
249638
|
|
|
248140
249639
|
// src/cli/commands/auth/social-login.ts
|
|
248141
|
-
import { dirname as dirname18, join as
|
|
249640
|
+
import { dirname as dirname18, join as join25, resolve as resolve7 } from "node:path";
|
|
248142
249641
|
var PROVIDER_LABELS = {
|
|
248143
249642
|
google: "Google",
|
|
248144
249643
|
microsoft: "Microsoft",
|
|
@@ -248209,7 +249708,7 @@ async function socialLoginAction({ log, isNonInteractive, runTask }, provider, a
|
|
|
248209
249708
|
}
|
|
248210
249709
|
const { project } = await readProjectConfig();
|
|
248211
249710
|
const configDir = dirname18(project.configPath);
|
|
248212
|
-
const authDir =
|
|
249711
|
+
const authDir = join25(configDir, project.authDir);
|
|
248213
249712
|
const { config: updated } = await runTask("Updating local auth config", async () => updateSocialLoginConfig(authDir, provider, shouldEnable, useCustomOAuth && options.clientId ? { clientId: options.clientId } : undefined));
|
|
248214
249713
|
if (clientSecret) {
|
|
248215
249714
|
await runTask("Saving client secret", async () => pushCustomOAuthSecret(provider, clientSecret));
|
|
@@ -248234,7 +249733,7 @@ function getSocialLoginCommand() {
|
|
|
248234
249733
|
}
|
|
248235
249734
|
|
|
248236
249735
|
// src/cli/commands/auth/sso.ts
|
|
248237
|
-
import { dirname as dirname19, join as
|
|
249736
|
+
import { dirname as dirname19, join as join26, resolve as resolve8 } from "node:path";
|
|
248238
249737
|
var SSOConfigFileSchema = object({
|
|
248239
249738
|
provider: _enum(Object.values(KNOWN_SSO_PROVIDERS)),
|
|
248240
249739
|
clientId: string2(),
|
|
@@ -248398,7 +249897,7 @@ async function ssoEnableAction({ isNonInteractive, runTask }, options) {
|
|
|
248398
249897
|
}
|
|
248399
249898
|
const { project } = await readProjectConfig();
|
|
248400
249899
|
const configDir = dirname19(project.configPath);
|
|
248401
|
-
const authDir =
|
|
249900
|
+
const authDir = join26(configDir, project.authDir);
|
|
248402
249901
|
await runTask("Updating local auth config", async () => updateSSOConfig(authDir, provider, true));
|
|
248403
249902
|
await runTask("Saving SSO credentials", async () => pushSSOSecrets(secrets));
|
|
248404
249903
|
return {
|
|
@@ -248414,7 +249913,7 @@ async function ssoDisableAction({ log, runTask }, options) {
|
|
|
248414
249913
|
}
|
|
248415
249914
|
const { project } = await readProjectConfig();
|
|
248416
249915
|
const configDir = dirname19(project.configPath);
|
|
248417
|
-
const authDir =
|
|
249916
|
+
const authDir = join26(configDir, project.authDir);
|
|
248418
249917
|
const updated = await runTask("Updating local auth config", async () => updateSSOConfig(authDir, null, false));
|
|
248419
249918
|
await runTask("Removing SSO credentials", async () => deleteSSOSecrets());
|
|
248420
249919
|
if (!hasAnyLoginMethod(updated)) {
|
|
@@ -249296,13 +250795,13 @@ function getConnectorsListAvailableCommand() {
|
|
|
249296
250795
|
}
|
|
249297
250796
|
|
|
249298
250797
|
// src/cli/commands/connectors/pull.ts
|
|
249299
|
-
import { dirname as dirname20, join as
|
|
250798
|
+
import { dirname as dirname20, join as join27, resolve as resolve9 } from "node:path";
|
|
249300
250799
|
async function resolveConnectorsDir(options) {
|
|
249301
250800
|
if (!getAppContext().projectRoot) {
|
|
249302
250801
|
return resolve9(options.dir ?? "connectors");
|
|
249303
250802
|
}
|
|
249304
250803
|
const { project } = await readProjectConfig();
|
|
249305
|
-
return
|
|
250804
|
+
return join27(dirname20(project.configPath), project.connectorsDir);
|
|
249306
250805
|
}
|
|
249307
250806
|
async function pullConnectorsAction({ log, runTask, jsonMode }, options) {
|
|
249308
250807
|
const connectorsDir = await resolveConnectorsDir(options);
|
|
@@ -249689,11 +251188,11 @@ function getListCommand() {
|
|
|
249689
251188
|
}
|
|
249690
251189
|
|
|
249691
251190
|
// src/cli/commands/functions/pull.ts
|
|
249692
|
-
import { dirname as dirname21, join as
|
|
251191
|
+
import { dirname as dirname21, join as join28 } from "node:path";
|
|
249693
251192
|
async function pullFunctionsAction({ log, runTask }, name) {
|
|
249694
251193
|
const { project, functions } = await readProjectConfig();
|
|
249695
251194
|
const configDir = dirname21(project.configPath);
|
|
249696
|
-
const functionsDir =
|
|
251195
|
+
const functionsDir = join28(configDir, project.functionsDir);
|
|
249697
251196
|
const pluginFunctionNames = new Set(functions.filter((fn) => fn.source.type === "plugin").map((fn) => fn.name));
|
|
249698
251197
|
const remoteFunctions = await runTask("Fetching functions from Base44", async () => {
|
|
249699
251198
|
const { functions } = await listDeployedFunctions();
|
|
@@ -249807,7 +251306,7 @@ import { basename as basename6, resolve as resolve11 } from "node:path";
|
|
|
249807
251306
|
var import_kebabCase = __toESM(require_kebabCase(), 1);
|
|
249808
251307
|
|
|
249809
251308
|
// src/cli/commands/project/scaffold-shared.ts
|
|
249810
|
-
import { join as
|
|
251309
|
+
import { join as join29 } from "node:path";
|
|
249811
251310
|
var DEFAULT_TEMPLATE_ID = "backend-only";
|
|
249812
251311
|
async function getTemplateById(templateId) {
|
|
249813
251312
|
const templates = await listTemplates();
|
|
@@ -249870,7 +251369,7 @@ async function completeProjectSetup({
|
|
|
249870
251369
|
env: { VITE_BASE44_APP_ID: projectId }
|
|
249871
251370
|
})`${buildCommand}`;
|
|
249872
251371
|
updateMessage("Deploying site...");
|
|
249873
|
-
return await deploySite(
|
|
251372
|
+
return await deploySite(join29(resolvedPath, outputDirectory));
|
|
249874
251373
|
}, {
|
|
249875
251374
|
successMessage: theme.colors.base44Orange("Site deployed successfully"),
|
|
249876
251375
|
errorMessage: "Failed to deploy site"
|
|
@@ -250886,7 +252385,7 @@ async function setEnvironmentVersion(environment, versionId, options = {}) {
|
|
|
250886
252385
|
}
|
|
250887
252386
|
// src/core/version/artifacts.ts
|
|
250888
252387
|
import { createHash as createHash3 } from "node:crypto";
|
|
250889
|
-
import { join as
|
|
252388
|
+
import { join as join30, resolve as resolve13 } from "node:path";
|
|
250890
252389
|
|
|
250891
252390
|
// src/core/version/functions.ts
|
|
250892
252391
|
import { createHash as createHash2 } from "node:crypto";
|
|
@@ -253161,10 +254660,6 @@ var STATIC_EGRESS_ENABLED_ENV = "BASE44_STATIC_EGRESS_ENABLED";
|
|
|
253161
254660
|
var STATIC_EGRESS_DIAGNOSTIC_LIMIT = 5;
|
|
253162
254661
|
var staticEgressFetchInstalled = false;
|
|
253163
254662
|
var staticEgressDiagnosticCount = 0;
|
|
253164
|
-
var dedicatedEgressResponses = /* @__PURE__ */ new WeakSet();
|
|
253165
|
-
function isDedicatedEgressResponse(response) {
|
|
253166
|
-
return dedicatedEgressResponses.has(response);
|
|
253167
|
-
}
|
|
253168
254663
|
function inputKind(input) {
|
|
253169
254664
|
if (typeof input === "string") return "string";
|
|
253170
254665
|
return input instanceof URL ? "url" : "request";
|
|
@@ -253266,10 +254761,7 @@ function createRequestScopedStaticEgressFetch(originalFetch, readEnvironment) {
|
|
|
253266
254761
|
return originalFetch(input, init);
|
|
253267
254762
|
}
|
|
253268
254763
|
logStaticEgressDecision("dedicated", input, binding, enableSecret);
|
|
253269
|
-
return binding.fetch(input, init)
|
|
253270
|
-
dedicatedEgressResponses.add(response);
|
|
253271
|
-
return response;
|
|
253272
|
-
});
|
|
254764
|
+
return binding.fetch(input, init);
|
|
253273
254765
|
};
|
|
253274
254766
|
}
|
|
253275
254767
|
function installStaticEgressFetch() {
|
|
@@ -253281,128 +254773,6 @@ function installStaticEgressFetch() {
|
|
|
253281
254773
|
staticEgressFetchInstalled = true;
|
|
253282
254774
|
}
|
|
253283
254775
|
|
|
253284
|
-
// src/edge-errors.ts
|
|
253285
|
-
var EDGE_ERRORS_HEADER = "X-B44-Edge-Errors";
|
|
253286
|
-
var MAX_EDGE_ERRORS = 5;
|
|
253287
|
-
var MAX_INSPECTED_BODY_BYTES = 8192;
|
|
253288
|
-
var BODY_READ_TIMEOUT_MS = 500;
|
|
253289
|
-
var PLAIN_TEXT_EDGE_ERROR = /^error code: (\\d{3,4})\\s*$/;
|
|
253290
|
-
var UNBRANDED_5XX_PAGE = /<center>cloudflare<\\/center>/i;
|
|
253291
|
-
var SAFE_VALUE = /^[\\x20-\\x7e]{1,253}$/;
|
|
253292
|
-
function safe(value) {
|
|
253293
|
-
return typeof value === "string" && SAFE_VALUE.test(value) ? value : void 0;
|
|
253294
|
-
}
|
|
253295
|
-
function parseEdgeErrorBody(body, status) {
|
|
253296
|
-
const plain = PLAIN_TEXT_EDGE_ERROR.exec(body);
|
|
253297
|
-
if (plain) return { code: Number(plain[1]) };
|
|
253298
|
-
if (status >= 500 && UNBRANDED_5XX_PAGE.test(body)) return { code: status };
|
|
253299
|
-
try {
|
|
253300
|
-
const json = JSON.parse(body);
|
|
253301
|
-
if (json === null || typeof json !== "object") return null;
|
|
253302
|
-
const fields = json;
|
|
253303
|
-
if (fields.cloudflare_error !== true || !Number.isInteger(fields.error_code)) return null;
|
|
253304
|
-
return {
|
|
253305
|
-
code: fields.error_code,
|
|
253306
|
-
name: safe(fields.error_name),
|
|
253307
|
-
category: safe(fields.error_category),
|
|
253308
|
-
zone: safe(fields.zone)
|
|
253309
|
-
};
|
|
253310
|
-
} catch {
|
|
253311
|
-
return null;
|
|
253312
|
-
}
|
|
253313
|
-
}
|
|
253314
|
-
async function readBodyPrefix(response) {
|
|
253315
|
-
if (Number(response.headers.get("content-length")) > MAX_INSPECTED_BODY_BYTES) return null;
|
|
253316
|
-
const reader = response.clone().body?.getReader();
|
|
253317
|
-
if (!reader) return "";
|
|
253318
|
-
const timer = setTimeout(() => reader.cancel().catch(() => {
|
|
253319
|
-
}), BODY_READ_TIMEOUT_MS);
|
|
253320
|
-
const decoder = new TextDecoder();
|
|
253321
|
-
let text = "";
|
|
253322
|
-
let size = 0;
|
|
253323
|
-
try {
|
|
253324
|
-
for (; ; ) {
|
|
253325
|
-
const { done, value } = await reader.read();
|
|
253326
|
-
if (done) break;
|
|
253327
|
-
size += value.byteLength;
|
|
253328
|
-
if (size > MAX_INSPECTED_BODY_BYTES) return null;
|
|
253329
|
-
text += decoder.decode(value, { stream: true });
|
|
253330
|
-
}
|
|
253331
|
-
} catch {
|
|
253332
|
-
return null;
|
|
253333
|
-
} finally {
|
|
253334
|
-
clearTimeout(timer);
|
|
253335
|
-
reader.cancel().catch(() => {
|
|
253336
|
-
});
|
|
253337
|
-
}
|
|
253338
|
-
return text + decoder.decode();
|
|
253339
|
-
}
|
|
253340
|
-
async function readEdgeError(response) {
|
|
253341
|
-
if (response.status < 400 || !response.headers.get("cf-ray")) return null;
|
|
253342
|
-
if (response.headers.get("cf-mitigated") === "challenge") {
|
|
253343
|
-
return { code: response.status, name: "challenge" };
|
|
253344
|
-
}
|
|
253345
|
-
const body = await readBodyPrefix(response);
|
|
253346
|
-
return body === null ? null : parseEdgeErrorBody(body, response.status);
|
|
253347
|
-
}
|
|
253348
|
-
function targetOrigin(input) {
|
|
253349
|
-
try {
|
|
253350
|
-
const raw = input instanceof URL ? input.href : typeof input === "string" ? input : input.url;
|
|
253351
|
-
return new URL(raw).origin;
|
|
253352
|
-
} catch {
|
|
253353
|
-
return null;
|
|
253354
|
-
}
|
|
253355
|
-
}
|
|
253356
|
-
async function recordEdgeError(input, response, startedAt) {
|
|
253357
|
-
const store = currentWorkerRuntimeContext();
|
|
253358
|
-
if (!store) return;
|
|
253359
|
-
const body = await readEdgeError(response);
|
|
253360
|
-
const target = targetOrigin(input);
|
|
253361
|
-
if (!body || !target) return;
|
|
253362
|
-
const record = store.edgeErrors ??= { errors: [], dropped: 0 };
|
|
253363
|
-
if (record.errors.length >= MAX_EDGE_ERRORS) {
|
|
253364
|
-
record.dropped += 1;
|
|
253365
|
-
return;
|
|
253366
|
-
}
|
|
253367
|
-
record.errors.push({
|
|
253368
|
-
...body,
|
|
253369
|
-
target,
|
|
253370
|
-
status: response.status,
|
|
253371
|
-
ray: safe(response.headers.get("cf-ray")) ?? "",
|
|
253372
|
-
egress: isDedicatedEgressResponse(response) ? "dedicated" : "shared",
|
|
253373
|
-
elapsed_ms: Date.now() - startedAt
|
|
253374
|
-
});
|
|
253375
|
-
}
|
|
253376
|
-
function createEdgeErrorFetch(innerFetch) {
|
|
253377
|
-
return async (input, init) => {
|
|
253378
|
-
const startedAt = Date.now();
|
|
253379
|
-
const response = await innerFetch(input, init);
|
|
253380
|
-
try {
|
|
253381
|
-
await recordEdgeError(input, response, startedAt);
|
|
253382
|
-
} catch {
|
|
253383
|
-
}
|
|
253384
|
-
return response;
|
|
253385
|
-
};
|
|
253386
|
-
}
|
|
253387
|
-
var edgeErrorFetchInstalled = false;
|
|
253388
|
-
function installEdgeErrorFetch() {
|
|
253389
|
-
if (edgeErrorFetchInstalled) return;
|
|
253390
|
-
globalThis.fetch = createEdgeErrorFetch(globalThis.fetch.bind(globalThis));
|
|
253391
|
-
edgeErrorFetchInstalled = true;
|
|
253392
|
-
}
|
|
253393
|
-
function attachEdgeErrors(response) {
|
|
253394
|
-
const record = currentWorkerRuntimeContext()?.edgeErrors;
|
|
253395
|
-
if (!record || !(response instanceof Response)) return response;
|
|
253396
|
-
if (response.status === 101 || response.webSocket) return response;
|
|
253397
|
-
try {
|
|
253398
|
-
const wrapped = new Response(response.body, response);
|
|
253399
|
-
wrapped.headers.set(EDGE_ERRORS_HEADER, JSON.stringify(record));
|
|
253400
|
-
return wrapped;
|
|
253401
|
-
} catch {
|
|
253402
|
-
return response;
|
|
253403
|
-
}
|
|
253404
|
-
}
|
|
253405
|
-
|
|
253406
254776
|
// src/static-egress-tcp-core.mjs
|
|
253407
254777
|
function normalizeHost(host) {
|
|
253408
254778
|
return host.toLowerCase().replace(/^\\[(.*)\\]$/, "$1").replace(/\\.$/, "");
|
|
@@ -253556,9 +254926,7 @@ function resolveHandler(functionName) {
|
|
|
253556
254926
|
return handler;
|
|
253557
254927
|
}
|
|
253558
254928
|
export {
|
|
253559
|
-
attachEdgeErrors,
|
|
253560
254929
|
getRegisteredHandler,
|
|
253561
|
-
installEdgeErrorFetch,
|
|
253562
254930
|
installStaticEgressFetch,
|
|
253563
254931
|
registerLazy,
|
|
253564
254932
|
resolveHandler
|
|
@@ -256603,22 +257971,20 @@ registerLazy(${JSON.stringify(functionName)}, () => import(${JSON.stringify(user
|
|
|
256603
257971
|
function buildAppEntrySource(functionModules, telemetry, runtimeSecrets = false) {
|
|
256604
257972
|
const moduleImports = functionModules.map((file) => `import "./${file}";`).join(`
|
|
256605
257973
|
`);
|
|
256606
|
-
const handlerExpr = `_b44AttachInvocationLogs(
|
|
257974
|
+
const handlerExpr = `_b44AttachInvocationLogs(${telemetry ? "_b44AttachTelemetry(await handler(request, info))" : "await handler(request, info)"})`;
|
|
256607
257975
|
const guard = activationGuard(runtimeSecrets);
|
|
256608
257976
|
const returnExpr = guard(handlerExpr);
|
|
256609
257977
|
return `// Auto-generated by the base44 bundler. Do not edit.
|
|
256610
257978
|
|
|
256611
257979
|
import { currentWorkerRuntimeContext as _b44Context, runWithWorkerEnvironment as _b44Run } from ${JSON.stringify(RUNTIME_CONTEXT_SPECIFIER)};
|
|
256612
|
-
import {
|
|
257980
|
+
import { installStaticEgressFetch, resolveHandler } from "./${SHIM_FILENAME}";${activationImport(runtimeSecrets)}
|
|
256613
257981
|
${moduleImports}
|
|
256614
257982
|
|
|
256615
257983
|
${consolePatch(runtimeSecrets)}
|
|
256616
257984
|
${INVOCATION_LOGS_PATCH}
|
|
256617
|
-
// Static egress reads workerEnv from the active request store. Install it
|
|
256618
|
-
//
|
|
256619
|
-
// fetch wrapper.
|
|
257985
|
+
// Static egress reads workerEnv from the active request store. Install it
|
|
257986
|
+
// before telemetry so telemetry remains the outermost fetch wrapper.
|
|
256620
257987
|
installStaticEgressFetch();
|
|
256621
|
-
installEdgeErrorFetch();
|
|
256622
257988
|
${telemetry ? TELEMETRY_PATCH : ""}
|
|
256623
257989
|
|
|
256624
257990
|
export default {
|
|
@@ -261771,14 +263137,14 @@ async function readRawResources(dir) {
|
|
|
261771
263137
|
const payloads = {};
|
|
261772
263138
|
for (const relativePath of files.sort()) {
|
|
261773
263139
|
const name = relativePath.replace(/\.jsonc?$/, "");
|
|
261774
|
-
payloads[name] = await readJsonFile(
|
|
263140
|
+
payloads[name] = await readJsonFile(join30(dir, ...relativePath.split("/")));
|
|
261775
263141
|
}
|
|
261776
263142
|
return payloads;
|
|
261777
263143
|
}
|
|
261778
263144
|
async function collectResources(configDir, dirs) {
|
|
261779
263145
|
const [entities, agents] = await Promise.all([
|
|
261780
|
-
readRawResources(
|
|
261781
|
-
readRawResources(
|
|
263146
|
+
readRawResources(join30(configDir, dirs.entitiesDir)),
|
|
263147
|
+
readRawResources(join30(configDir, dirs.agentsDir))
|
|
261782
263148
|
]);
|
|
261783
263149
|
return { entities, agents };
|
|
261784
263150
|
}
|
|
@@ -261790,7 +263156,7 @@ async function collectArtifacts(target) {
|
|
|
261790
263156
|
entryFile: ENTRY2
|
|
261791
263157
|
}),
|
|
261792
263158
|
...siteWorker ? { siteWorker } : {},
|
|
261793
|
-
backendBundles: await tagStep2("build", () => compileBackendBundles(target.root,
|
|
263159
|
+
backendBundles: await tagStep2("build", () => compileBackendBundles(target.root, join30(target.configDir, target.functionsDir))),
|
|
261794
263160
|
...await collectResources(target.configDir, target)
|
|
261795
263161
|
};
|
|
261796
263162
|
}
|
|
@@ -262007,7 +263373,7 @@ function writeFile3(appId, params) {
|
|
|
262007
263373
|
function editFile(appId, params) {
|
|
262008
263374
|
return callTool(appId, "edit_file", { ...params }, EditFileResponseSchema, `editing file "${params.path}"`);
|
|
262009
263375
|
}
|
|
262010
|
-
function
|
|
263376
|
+
function grep2(appId, params) {
|
|
262011
263377
|
return callTool(appId, "grep", { ...params }, GrepResponseSchema, "searching files");
|
|
262012
263378
|
}
|
|
262013
263379
|
function runCommand(appId, params) {
|
|
@@ -262111,10 +263477,10 @@ Examples:
|
|
|
262111
263477
|
}
|
|
262112
263478
|
|
|
262113
263479
|
// src/cli/commands/sandbox/grep.ts
|
|
262114
|
-
async function
|
|
263480
|
+
async function grepAction2({ runTask, branchId }, pattern, options) {
|
|
262115
263481
|
const { id: appId } = getAppContext();
|
|
262116
263482
|
const maxResults = parsePositiveInt(options.maxResults, "--max-results");
|
|
262117
|
-
const result = await runTask("Searching files", () =>
|
|
263483
|
+
const result = await runTask("Searching files", () => grep2(appId, {
|
|
262118
263484
|
pattern,
|
|
262119
263485
|
path: options.path,
|
|
262120
263486
|
is_regex: options.regex,
|
|
@@ -262126,7 +263492,7 @@ async function grepAction({ runTask, branchId }, pattern, options) {
|
|
|
262126
263492
|
return { outroMessage: "Searched files", stdout: toJsonStdout(result) };
|
|
262127
263493
|
}
|
|
262128
263494
|
function getSandboxGrepCommand() {
|
|
262129
|
-
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(
|
|
263495
|
+
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);
|
|
262130
263496
|
}
|
|
262131
263497
|
|
|
262132
263498
|
// src/cli/commands/sandbox/list-directory.ts
|
|
@@ -262721,10 +264087,10 @@ function toPascalCase(name) {
|
|
|
262721
264087
|
return name.split(/[-_\s]+/).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
|
|
262722
264088
|
}
|
|
262723
264089
|
// src/core/types/update-project.ts
|
|
262724
|
-
import { join as
|
|
264090
|
+
import { join as join34 } from "node:path";
|
|
262725
264091
|
var TYPES_INCLUDE_PATH = `${PROJECT_SUBDIR}/${TYPES_OUTPUT_SUBDIR}/*.d.ts`;
|
|
262726
264092
|
async function updateProjectConfig(projectRoot) {
|
|
262727
|
-
const tsconfigPath =
|
|
264093
|
+
const tsconfigPath = join34(projectRoot, "tsconfig.json");
|
|
262728
264094
|
if (!await pathExists(tsconfigPath)) {
|
|
262729
264095
|
return false;
|
|
262730
264096
|
}
|
|
@@ -262943,7 +264309,7 @@ function rethrowLegacyAppAsExplanation(error) {
|
|
|
262943
264309
|
|
|
262944
264310
|
// src/cli/commands/workflows/limit.ts
|
|
262945
264311
|
var MAX_LIMIT = 200;
|
|
262946
|
-
function
|
|
264312
|
+
function parseLimit2(limit) {
|
|
262947
264313
|
if (limit === undefined)
|
|
262948
264314
|
return;
|
|
262949
264315
|
const parsed = Number.parseInt(limit, 10);
|
|
@@ -262960,7 +264326,7 @@ function formatWorkflowLine(workflow) {
|
|
|
262960
264326
|
return `${workflow.name} [${workflow.status}] runs: ${workflow.totalRuns}, ${lastRun}${failures}`;
|
|
262961
264327
|
}
|
|
262962
264328
|
async function listAction({ log, runTask, jsonMode }, options) {
|
|
262963
|
-
const limit =
|
|
264329
|
+
const limit = parseLimit2(options.limit);
|
|
262964
264330
|
const workflows = await runTask("Fetching workflows from Base44", async () => listWorkflows(limit).catch(rethrowLegacyAppAsExplanation), {
|
|
262965
264331
|
successMessage: "Workflows fetched successfully",
|
|
262966
264332
|
errorMessage: "Failed to fetch workflows"
|
|
@@ -263019,7 +264385,7 @@ async function describeEmptyResult(hasFilters) {
|
|
|
263019
264385
|
return hasFilters ? `No runs match your filters. Workflows in this app: ${names}.` : `No runs yet. Workflows in this app: ${names}.`;
|
|
263020
264386
|
}
|
|
263021
264387
|
async function runsAction(ctx, options) {
|
|
263022
|
-
const limit =
|
|
264388
|
+
const limit = parseLimit2(options.limit);
|
|
263023
264389
|
const runs = await ctx.runTask("Fetching workflow runs from Base44", async () => listWorkflowRuns({
|
|
263024
264390
|
status: options.status,
|
|
263025
264391
|
since: options.since,
|
|
@@ -263205,7 +264571,7 @@ function getWorkspaceCommand() {
|
|
|
263205
264571
|
// src/cli/dev/dev-server/main.ts
|
|
263206
264572
|
var import_cors = __toESM(require_lib4(), 1);
|
|
263207
264573
|
var import_express6 = __toESM(require_express(), 1);
|
|
263208
|
-
import { dirname as dirname27, join as
|
|
264574
|
+
import { dirname as dirname27, join as join39 } from "node:path";
|
|
263209
264575
|
|
|
263210
264576
|
// ../../node_modules/get-port/index.js
|
|
263211
264577
|
import net from "node:net";
|
|
@@ -263335,7 +264701,7 @@ var $tmpName = promisify12(tmp.tmpName);
|
|
|
263335
264701
|
|
|
263336
264702
|
// src/cli/dev/dev-server/function-manager.ts
|
|
263337
264703
|
import { spawn as spawn3 } from "node:child_process";
|
|
263338
|
-
import { dirname as dirname24, join as
|
|
264704
|
+
import { dirname as dirname24, join as join35 } from "node:path";
|
|
263339
264705
|
import { pathToFileURL as pathToFileURL6 } from "node:url";
|
|
263340
264706
|
|
|
263341
264707
|
// src/cli/dev/dev-server/base-function-manager.ts
|
|
@@ -263440,7 +264806,7 @@ class FunctionManager extends BaseFunctionManager {
|
|
|
263440
264806
|
}
|
|
263441
264807
|
spawnFunction(func, port) {
|
|
263442
264808
|
this.logger.log(`Spawning function "${func.name}" on port ${port}`);
|
|
263443
|
-
const importMapPath =
|
|
264809
|
+
const importMapPath = join35(dirname24(this.wrapperPath), "import-map.json");
|
|
263444
264810
|
const process2 = spawn3("deno", ["run", "--allow-all", "--import-map", importMapPath, this.wrapperPath], {
|
|
263445
264811
|
env: {
|
|
263446
264812
|
...globalThis.process.env,
|
|
@@ -263514,7 +264880,7 @@ class FunctionManager extends BaseFunctionManager {
|
|
|
263514
264880
|
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync2 } from "node:fs";
|
|
263515
264881
|
import { isBuiltin as isBuiltin3 } from "node:module";
|
|
263516
264882
|
import { homedir as homedir4 } from "node:os";
|
|
263517
|
-
import { join as
|
|
264883
|
+
import { join as join36 } from "node:path";
|
|
263518
264884
|
import { pathToFileURL as pathToFileURL7 } from "node:url";
|
|
263519
264885
|
var depsPromise;
|
|
263520
264886
|
function loadDeps() {
|
|
@@ -263635,9 +265001,9 @@ export default {
|
|
|
263635
265001
|
};
|
|
263636
265002
|
`;
|
|
263637
265003
|
function ensureBundlerConfig() {
|
|
263638
|
-
const dir =
|
|
265004
|
+
const dir = join36(homedir4(), ".base44", "function-bundler");
|
|
263639
265005
|
mkdirSync2(dir, { recursive: true });
|
|
263640
|
-
const configPath =
|
|
265006
|
+
const configPath = join36(dir, "deno.json");
|
|
263641
265007
|
writeFileSync2(configPath, `${JSON.stringify({ nodeModulesDir: "auto" }, null, 2)}
|
|
263642
265008
|
`);
|
|
263643
265009
|
return configPath;
|
|
@@ -265174,11 +266540,11 @@ import { relative as relative10 } from "node:path";
|
|
|
265174
266540
|
// ../../node_modules/chokidar/index.js
|
|
265175
266541
|
import { EventEmitter as EventEmitter3 } from "node:events";
|
|
265176
266542
|
import { stat as statcb, Stats } from "node:fs";
|
|
265177
|
-
import { readdir as readdir3, stat as
|
|
266543
|
+
import { readdir as readdir3, stat as stat7 } from "node:fs/promises";
|
|
265178
266544
|
import * as sp3 from "node:path";
|
|
265179
266545
|
|
|
265180
266546
|
// ../../node_modules/readdirp/index.js
|
|
265181
|
-
import { lstat as lstat2, readdir as readdir2, realpath, stat as
|
|
266547
|
+
import { lstat as lstat2, readdir as readdir2, realpath, stat as stat5 } from "node:fs/promises";
|
|
265182
266548
|
import { join as pjoin, relative as prelative, resolve as presolve, sep as psep } from "node:path";
|
|
265183
266549
|
import { Readable as Readable6 } from "node:stream";
|
|
265184
266550
|
var EntryTypes = {
|
|
@@ -265187,7 +266553,7 @@ var EntryTypes = {
|
|
|
265187
266553
|
FILE_DIR_TYPE: "files_directories",
|
|
265188
266554
|
EVERYTHING_TYPE: "all"
|
|
265189
266555
|
};
|
|
265190
|
-
var
|
|
266556
|
+
var defaultOptions2 = {
|
|
265191
266557
|
root: ".",
|
|
265192
266558
|
fileFilter: (_entryInfo) => true,
|
|
265193
266559
|
directoryFilter: (_entryInfo) => true,
|
|
@@ -265197,7 +266563,7 @@ var defaultOptions = {
|
|
|
265197
266563
|
alwaysStat: false,
|
|
265198
266564
|
highWaterMark: 4096
|
|
265199
266565
|
};
|
|
265200
|
-
Object.freeze(
|
|
266566
|
+
Object.freeze(defaultOptions2);
|
|
265201
266567
|
var RECURSIVE_ERROR_CODE = "READDIRP_RECURSIVE_ERROR";
|
|
265202
266568
|
var NORMAL_FLOW_ERRORS = new Set(["ENOENT", "EPERM", "EACCES", "ELOOP", RECURSIVE_ERROR_CODE]);
|
|
265203
266569
|
var ALL_TYPES = [
|
|
@@ -265256,17 +266622,17 @@ class ReaddirpStream extends Readable6 {
|
|
|
265256
266622
|
autoDestroy: true,
|
|
265257
266623
|
highWaterMark: options.highWaterMark
|
|
265258
266624
|
});
|
|
265259
|
-
const opts = { ...
|
|
266625
|
+
const opts = { ...defaultOptions2, ...options };
|
|
265260
266626
|
const { root, type } = opts;
|
|
265261
266627
|
this._fileFilter = normalizeFilter(opts.fileFilter);
|
|
265262
266628
|
this._directoryFilter = normalizeFilter(opts.directoryFilter);
|
|
265263
|
-
const statMethod = opts.lstat ? lstat2 :
|
|
266629
|
+
const statMethod = opts.lstat ? lstat2 : stat5;
|
|
265264
266630
|
if (wantBigintFsStats) {
|
|
265265
266631
|
this._stat = (path) => statMethod(path, { bigint: true });
|
|
265266
266632
|
} else {
|
|
265267
266633
|
this._stat = statMethod;
|
|
265268
266634
|
}
|
|
265269
|
-
this._maxDepth = opts.depth != null && Number.isSafeInteger(opts.depth) ? opts.depth :
|
|
266635
|
+
this._maxDepth = opts.depth != null && Number.isSafeInteger(opts.depth) ? opts.depth : defaultOptions2.depth;
|
|
265270
266636
|
this._wantsDir = type ? DIR_TYPES.has(type) : false;
|
|
265271
266637
|
this._wantsFile = type ? FILE_TYPES2.has(type) : false;
|
|
265272
266638
|
this._wantsEverything = type === EntryTypes.EVERYTHING_TYPE;
|
|
@@ -265413,7 +266779,7 @@ function readdirp(root, options = {}) {
|
|
|
265413
266779
|
|
|
265414
266780
|
// ../../node_modules/chokidar/handler.js
|
|
265415
266781
|
import { watch as fs_watch, unwatchFile, watchFile } from "node:fs";
|
|
265416
|
-
import { realpath as fsrealpath, lstat as lstat3, open as open2, stat as
|
|
266782
|
+
import { realpath as fsrealpath, lstat as lstat3, open as open2, stat as stat6 } from "node:fs/promises";
|
|
265417
266783
|
import { type as osType } from "node:os";
|
|
265418
266784
|
import * as sp2 from "node:path";
|
|
265419
266785
|
var STR_DATA = "data";
|
|
@@ -265439,7 +266805,7 @@ var EVENTS = {
|
|
|
265439
266805
|
};
|
|
265440
266806
|
var EV = EVENTS;
|
|
265441
266807
|
var THROTTLE_MODE_WATCH = "watch";
|
|
265442
|
-
var statMethods = { lstat: lstat3, stat:
|
|
266808
|
+
var statMethods = { lstat: lstat3, stat: stat6 };
|
|
265443
266809
|
var KEY_LISTENERS = "listeners";
|
|
265444
266810
|
var KEY_ERR = "errHandlers";
|
|
265445
266811
|
var KEY_RAW = "rawEmitters";
|
|
@@ -265910,7 +267276,7 @@ class NodeFsHandler {
|
|
|
265910
267276
|
return;
|
|
265911
267277
|
if (!newStats || newStats.mtimeMs === 0) {
|
|
265912
267278
|
try {
|
|
265913
|
-
const newStats = await
|
|
267279
|
+
const newStats = await stat6(file);
|
|
265914
267280
|
if (this.fsw.closed)
|
|
265915
267281
|
return;
|
|
265916
267282
|
const at = newStats.atimeMs;
|
|
@@ -266582,7 +267948,7 @@ class FSWatcher extends EventEmitter3 {
|
|
|
266582
267948
|
const fullPath = opts.cwd ? sp3.join(opts.cwd, path) : path;
|
|
266583
267949
|
let stats;
|
|
266584
267950
|
try {
|
|
266585
|
-
stats = await
|
|
267951
|
+
stats = await stat7(fullPath);
|
|
266586
267952
|
} catch (err) {}
|
|
266587
267953
|
if (!stats || this.closed)
|
|
266588
267954
|
return;
|
|
@@ -266966,8 +268332,8 @@ async function createDevServer(options) {
|
|
|
266966
268332
|
broadcastEntityEvent(io, appId, entityName, event);
|
|
266967
268333
|
};
|
|
266968
268334
|
const base44ConfigWatcher = new WatchBase44({
|
|
266969
|
-
functions:
|
|
266970
|
-
entities:
|
|
268335
|
+
functions: join39(dirname27(project.configPath), project.functionsDir),
|
|
268336
|
+
entities: join39(dirname27(project.configPath), project.entitiesDir)
|
|
266971
268337
|
}, devLogger);
|
|
266972
268338
|
base44ConfigWatcher.on("change", async (name) => {
|
|
266973
268339
|
try {
|
|
@@ -267170,7 +268536,7 @@ function readExecEnvTarget(env = process.env) {
|
|
|
267170
268536
|
// src/core/exec/run-script.ts
|
|
267171
268537
|
import { spawn as spawn4 } from "node:child_process";
|
|
267172
268538
|
import { readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
267173
|
-
import { join as
|
|
268539
|
+
import { join as join40 } from "node:path";
|
|
267174
268540
|
var SDK_SPECIFIER = '"npm:@base44/sdk"';
|
|
267175
268541
|
function wrapperSource(sdkVersion) {
|
|
267176
268542
|
const source = readFileSync4(getExecWrapperPath(), "utf-8");
|
|
@@ -267206,7 +268572,7 @@ async function runScript(options) {
|
|
|
267206
268572
|
writeFileSync3(tempWrapper.path, wrapperSource(sdkVersion), "utf-8");
|
|
267207
268573
|
const configDir = await $dir({ unsafeCleanup: true });
|
|
267208
268574
|
cleanupFns.push(configDir.cleanup);
|
|
267209
|
-
const configPath =
|
|
268575
|
+
const configPath = join40(configDir.path, "deno.json");
|
|
267210
268576
|
writeFileSync3(configPath, JSON.stringify(DENO_CONFIG), "utf-8");
|
|
267211
268577
|
try {
|
|
267212
268578
|
const exitCode = await new Promise((resolvePromise) => {
|
|
@@ -267478,6 +268844,7 @@ function createProgram(context) {
|
|
|
267478
268844
|
program.addCommand(getSecretsCommand());
|
|
267479
268845
|
program.addCommand(getSandboxCommand());
|
|
267480
268846
|
program.addCommand(getBranchesCommand());
|
|
268847
|
+
program.addCommand(getApiCommand());
|
|
267481
268848
|
program.addCommand(getAuthCommand());
|
|
267482
268849
|
program.addCommand(getSiteCommand());
|
|
267483
268850
|
if (versionsApiEnabled()) {
|
|
@@ -271496,7 +272863,7 @@ function addCommandInfoToErrorReporter(program, errorReporter) {
|
|
|
271496
272863
|
// src/cli/index.ts
|
|
271497
272864
|
var __dirname4 = dirname29(fileURLToPath7(import.meta.url));
|
|
271498
272865
|
async function runCLI(options) {
|
|
271499
|
-
ensureNpmAssets(
|
|
272866
|
+
ensureNpmAssets(join41(__dirname4, "../assets"));
|
|
271500
272867
|
const errorReporter = new ErrorReporter;
|
|
271501
272868
|
errorReporter.registerProcessErrorHandlers();
|
|
271502
272869
|
const jsonMode = process.argv.includes("--json");
|
|
@@ -271535,4 +272902,4 @@ export {
|
|
|
271535
272902
|
runCLI
|
|
271536
272903
|
};
|
|
271537
272904
|
|
|
271538
|
-
//# debugId=
|
|
272905
|
+
//# debugId=FA1E97B3DE15B20C64756E2164756E21
|