@cerefox/memory 1.10.1 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/cerefox.js +998 -220
- package/dist/frontend/assets/{index-i67RH1VY.js → index-P1F2Ldl9.js} +25 -25
- package/dist/frontend/assets/{index-i67RH1VY.js.map → index-P1F2Ldl9.js.map} +1 -1
- package/dist/frontend/index.html +1 -1
- package/dist/server-assets/_shared/ef-meta/index.ts +3 -3
- package/dist/server-assets/_shared/mcp-tools/access-paths.ts +51 -0
- package/dist/server-assets/_shared/mcp-tools/types.ts +13 -14
- package/docs/guides/access-paths.md +1 -0
- package/docs/guides/configuration.md +29 -3
- package/package.json +1 -1
package/dist/bin/cerefox.js
CHANGED
|
@@ -7440,7 +7440,7 @@ var exports_meta = {};
|
|
|
7440
7440
|
__export(exports_meta, {
|
|
7441
7441
|
PKG_VERSION: () => PKG_VERSION
|
|
7442
7442
|
});
|
|
7443
|
-
var PKG_VERSION = "1.
|
|
7443
|
+
var PKG_VERSION = "1.12.0";
|
|
7444
7444
|
var init_meta = () => {};
|
|
7445
7445
|
|
|
7446
7446
|
// ../../_shared/config/paths.ts
|
|
@@ -7468,12 +7468,12 @@ function resolveConfigDir(opts = {}) {
|
|
|
7468
7468
|
}
|
|
7469
7469
|
const here = opts.cwd ?? processCwd();
|
|
7470
7470
|
const cwdEnv = join(here, ".env");
|
|
7471
|
-
if (existsSync(cwdEnv) &&
|
|
7471
|
+
if (existsSync(cwdEnv) && envFileHasCerefoxKey(cwdEnv)) {
|
|
7472
7472
|
return resolvePath(here);
|
|
7473
7473
|
}
|
|
7474
7474
|
return userState;
|
|
7475
7475
|
}
|
|
7476
|
-
function
|
|
7476
|
+
function envFileHasCerefoxKey(envPath) {
|
|
7477
7477
|
try {
|
|
7478
7478
|
const contents = readFileSync(envPath, "utf8");
|
|
7479
7479
|
return /^\s*CEREFOX_[A-Z0-9_]+\s*=/m.test(contents);
|
|
@@ -7494,7 +7494,7 @@ function isDevMode(opts = {}) {
|
|
|
7494
7494
|
return false;
|
|
7495
7495
|
const here = opts.cwd ?? processCwd();
|
|
7496
7496
|
const cwdEnv = join(here, ".env");
|
|
7497
|
-
return existsSync(cwdEnv) &&
|
|
7497
|
+
return existsSync(cwdEnv) && envFileHasCerefoxKey(cwdEnv);
|
|
7498
7498
|
}
|
|
7499
7499
|
var USER_STATE_DIR_NAME = ".cerefox";
|
|
7500
7500
|
var init_paths = () => {};
|
|
@@ -7520,11 +7520,11 @@ function parseDotenv(content) {
|
|
|
7520
7520
|
return result;
|
|
7521
7521
|
}
|
|
7522
7522
|
function loadEnv(opts = {}) {
|
|
7523
|
-
|
|
7523
|
+
const envPath = resolveEnvFile(opts);
|
|
7524
|
+
if (_loadedPath === envPath) {
|
|
7524
7525
|
return { path: "(already loaded)", vars: 0 };
|
|
7525
7526
|
}
|
|
7526
|
-
|
|
7527
|
-
const envPath = resolveEnvFile(opts);
|
|
7527
|
+
_loadedPath = envPath;
|
|
7528
7528
|
let content;
|
|
7529
7529
|
try {
|
|
7530
7530
|
content = readFileSync2(envPath, "utf8");
|
|
@@ -7555,7 +7555,7 @@ function loadSettings(opts = {}) {
|
|
|
7555
7555
|
fireworksApiKey: env2.CEREFOX_FIREWORKS_API_KEY ?? ""
|
|
7556
7556
|
};
|
|
7557
7557
|
}
|
|
7558
|
-
var KV_LINE,
|
|
7558
|
+
var KV_LINE, _loadedPath = null;
|
|
7559
7559
|
var init_env = __esm(() => {
|
|
7560
7560
|
init_paths();
|
|
7561
7561
|
KV_LINE = /^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*?)\s*$/;
|
|
@@ -7565,6 +7565,7 @@ var init_env = __esm(() => {
|
|
|
7565
7565
|
var exports_config = {};
|
|
7566
7566
|
__export(exports_config, {
|
|
7567
7567
|
USER_STATE_DIR_NAME: () => USER_STATE_DIR_NAME,
|
|
7568
|
+
envFileHasCerefoxKey: () => envFileHasCerefoxKey,
|
|
7568
7569
|
isDevMode: () => isDevMode,
|
|
7569
7570
|
loadEnv: () => loadEnv,
|
|
7570
7571
|
loadSettings: () => loadSettings,
|
|
@@ -26002,7 +26003,7 @@ var init_bundled_docs = __esm(() => {
|
|
|
26002
26003
|
});
|
|
26003
26004
|
|
|
26004
26005
|
// ../../_shared/ef-meta/index.ts
|
|
26005
|
-
var EF_VERSION = "1.
|
|
26006
|
+
var EF_VERSION = "1.12.0", CEREFOX_VERSION = "1.12.0", EF_LAST_CHANGED = "1.11.0";
|
|
26006
26007
|
var init_ef_meta = () => {};
|
|
26007
26008
|
|
|
26008
26009
|
// ../../_shared/compatibility/index.ts
|
|
@@ -43253,7 +43254,7 @@ var require_nodes = __commonJS(function(exports) {
|
|
|
43253
43254
|
}
|
|
43254
43255
|
});
|
|
43255
43256
|
|
|
43256
|
-
// ../../node_modules/.bun/@xmldom+xmldom@0.8.
|
|
43257
|
+
// ../../node_modules/.bun/@xmldom+xmldom@0.8.15/node_modules/@xmldom/xmldom/lib/conventions.js
|
|
43257
43258
|
var require_conventions = __commonJS(function(exports) {
|
|
43258
43259
|
function find(list, predicate, ac) {
|
|
43259
43260
|
if (ac === undefined) {
|
|
@@ -43307,18 +43308,25 @@ var require_conventions = __commonJS(function(exports) {
|
|
|
43307
43308
|
XML: "http://www.w3.org/XML/1998/namespace",
|
|
43308
43309
|
XMLNS: "http://www.w3.org/2000/xmlns/"
|
|
43309
43310
|
});
|
|
43311
|
+
var nameStartChar = /[A-Z_a-z\xC0-\xD6\xD8-\xF6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD]/;
|
|
43312
|
+
var nameChar = new RegExp("[\\-\\.0-9" + nameStartChar.source.slice(1, -1) + "\\u00B7\\u0300-\\u036F\\u203F-\\u2040]");
|
|
43313
|
+
var tagNamePattern = new RegExp("^" + nameStartChar.source + nameChar.source + "*(?::" + nameStartChar.source + nameChar.source + "*)?$");
|
|
43310
43314
|
exports.assign = assign;
|
|
43311
43315
|
exports.find = find;
|
|
43312
43316
|
exports.freeze = freeze;
|
|
43313
43317
|
exports.MIME_TYPE = MIME_TYPE;
|
|
43314
43318
|
exports.NAMESPACE = NAMESPACE;
|
|
43319
|
+
exports.nameStartChar = nameStartChar;
|
|
43320
|
+
exports.nameChar = nameChar;
|
|
43321
|
+
exports.tagNamePattern = tagNamePattern;
|
|
43315
43322
|
});
|
|
43316
43323
|
|
|
43317
|
-
// ../../node_modules/.bun/@xmldom+xmldom@0.8.
|
|
43324
|
+
// ../../node_modules/.bun/@xmldom+xmldom@0.8.15/node_modules/@xmldom/xmldom/lib/dom.js
|
|
43318
43325
|
var require_dom = __commonJS(function(exports) {
|
|
43319
43326
|
var conventions = require_conventions();
|
|
43320
43327
|
var find = conventions.find;
|
|
43321
43328
|
var NAMESPACE = conventions.NAMESPACE;
|
|
43329
|
+
var tagNamePattern = conventions.tagNamePattern;
|
|
43322
43330
|
function notEmptyString(input) {
|
|
43323
43331
|
return input !== "";
|
|
43324
43332
|
}
|
|
@@ -43459,7 +43467,9 @@ var require_dom = __commonJS(function(exports) {
|
|
|
43459
43467
|
return this[i] || null;
|
|
43460
43468
|
};
|
|
43461
43469
|
_extends(LiveNodeList, NodeList);
|
|
43462
|
-
function NamedNodeMap() {
|
|
43470
|
+
function NamedNodeMap() {
|
|
43471
|
+
this._nameIndex = Object.create(null);
|
|
43472
|
+
}
|
|
43463
43473
|
function _findNodeIndex(list, node) {
|
|
43464
43474
|
var i = list.length;
|
|
43465
43475
|
while (i--) {
|
|
@@ -43468,12 +43478,22 @@ var require_dom = __commonJS(function(exports) {
|
|
|
43468
43478
|
}
|
|
43469
43479
|
}
|
|
43470
43480
|
}
|
|
43481
|
+
function _nnmIndexAdd(list, attr) {
|
|
43482
|
+
list._nameIndex[attr.nodeName] = attr;
|
|
43483
|
+
}
|
|
43484
|
+
function _nnmIndexRemove(list, attr) {
|
|
43485
|
+
if (list._nameIndex[attr.nodeName] === attr) {
|
|
43486
|
+
delete list._nameIndex[attr.nodeName];
|
|
43487
|
+
}
|
|
43488
|
+
}
|
|
43471
43489
|
function _addNamedNode(el, list, newAttr, oldAttr) {
|
|
43472
43490
|
if (oldAttr) {
|
|
43473
43491
|
list[_findNodeIndex(list, oldAttr)] = newAttr;
|
|
43492
|
+
_nnmIndexRemove(list, oldAttr);
|
|
43474
43493
|
} else {
|
|
43475
43494
|
list[list.length++] = newAttr;
|
|
43476
43495
|
}
|
|
43496
|
+
_nnmIndexAdd(list, newAttr);
|
|
43477
43497
|
if (el) {
|
|
43478
43498
|
newAttr.ownerElement = el;
|
|
43479
43499
|
var doc = el.ownerDocument;
|
|
@@ -43491,6 +43511,7 @@ var require_dom = __commonJS(function(exports) {
|
|
|
43491
43511
|
list[i] = list[++i];
|
|
43492
43512
|
}
|
|
43493
43513
|
list.length = lastIndex;
|
|
43514
|
+
_nnmIndexRemove(list, attr);
|
|
43494
43515
|
if (el) {
|
|
43495
43516
|
var doc = el.ownerDocument;
|
|
43496
43517
|
if (doc) {
|
|
@@ -43519,7 +43540,7 @@ var require_dom = __commonJS(function(exports) {
|
|
|
43519
43540
|
if (el && el != this._ownerElement) {
|
|
43520
43541
|
throw new DOMException(INUSE_ATTRIBUTE_ERR);
|
|
43521
43542
|
}
|
|
43522
|
-
var oldAttr = this.
|
|
43543
|
+
var oldAttr = this._nameIndex[attr.nodeName];
|
|
43523
43544
|
_addNamedNode(this._ownerElement, this, attr, oldAttr);
|
|
43524
43545
|
return oldAttr;
|
|
43525
43546
|
},
|
|
@@ -43623,8 +43644,29 @@ var require_dom = __commonJS(function(exports) {
|
|
|
43623
43644
|
while (child) {
|
|
43624
43645
|
var next = child.nextSibling;
|
|
43625
43646
|
if (next !== null && next.nodeType === TEXT_NODE && child.nodeType === TEXT_NODE) {
|
|
43626
|
-
|
|
43627
|
-
|
|
43647
|
+
var tail = [];
|
|
43648
|
+
var sibling = next;
|
|
43649
|
+
while (sibling !== null && sibling.nodeType === TEXT_NODE) {
|
|
43650
|
+
tail.push(sibling.data);
|
|
43651
|
+
sibling = sibling.nextSibling;
|
|
43652
|
+
}
|
|
43653
|
+
var removed = child.nextSibling;
|
|
43654
|
+
while (removed !== sibling) {
|
|
43655
|
+
var following = removed.nextSibling;
|
|
43656
|
+
removed.parentNode = null;
|
|
43657
|
+
removed.previousSibling = null;
|
|
43658
|
+
removed.nextSibling = null;
|
|
43659
|
+
removed = following;
|
|
43660
|
+
}
|
|
43661
|
+
child.nextSibling = sibling;
|
|
43662
|
+
if (sibling !== null) {
|
|
43663
|
+
sibling.previousSibling = child;
|
|
43664
|
+
} else {
|
|
43665
|
+
node.lastChild = child;
|
|
43666
|
+
}
|
|
43667
|
+
child.appendData(tail.join(""));
|
|
43668
|
+
_onUpdateChild(node.ownerDocument, node);
|
|
43669
|
+
child = sibling;
|
|
43628
43670
|
} else {
|
|
43629
43671
|
child = next;
|
|
43630
43672
|
}
|
|
@@ -44082,6 +44124,9 @@ var require_dom = __commonJS(function(exports) {
|
|
|
44082
44124
|
return node;
|
|
44083
44125
|
},
|
|
44084
44126
|
createEntityReference: function(name) {
|
|
44127
|
+
if (!tagNamePattern.test(name)) {
|
|
44128
|
+
throw new DOMException(INVALID_CHARACTER_ERR, 'not a valid xml name "' + name + '"');
|
|
44129
|
+
}
|
|
44085
44130
|
var node = new EntityReference;
|
|
44086
44131
|
node.ownerDocument = this;
|
|
44087
44132
|
node.nodeName = name;
|
|
@@ -44329,7 +44374,10 @@ var require_dom = __commonJS(function(exports) {
|
|
|
44329
44374
|
}
|
|
44330
44375
|
return true;
|
|
44331
44376
|
}
|
|
44332
|
-
function addSerializedAttribute(buf, qualifiedName, value) {
|
|
44377
|
+
function addSerializedAttribute(buf, qualifiedName, value, requireWellFormed) {
|
|
44378
|
+
if (requireWellFormed && !tagNamePattern.test(qualifiedName)) {
|
|
44379
|
+
throw new DOMException(INVALID_STATE_ERR, 'The attribute name "' + qualifiedName + '" is not a valid XML QName');
|
|
44380
|
+
}
|
|
44333
44381
|
buf.push(" ", qualifiedName, '="', value.replace(/[<>&"\t\n\r]/g, _xmlEncoder), '"');
|
|
44334
44382
|
}
|
|
44335
44383
|
function serializeToString(node, buf, isHTML, nodeFilter, visibleNamespaces, requireWellFormed) {
|
|
@@ -44387,6 +44435,9 @@ var require_dom = __commonJS(function(exports) {
|
|
|
44387
44435
|
}
|
|
44388
44436
|
}
|
|
44389
44437
|
}
|
|
44438
|
+
if (requireWellFormed && !tagNamePattern.test(prefixedNodeName)) {
|
|
44439
|
+
throw new DOMException(INVALID_STATE_ERR, 'The element name "' + prefixedNodeName + '" is not a valid XML QName');
|
|
44440
|
+
}
|
|
44390
44441
|
buf.push("<", prefixedNodeName);
|
|
44391
44442
|
var childNs = ns.slice();
|
|
44392
44443
|
for (var i = 0;i < len; i++) {
|
|
@@ -44402,7 +44453,7 @@ var require_dom = __commonJS(function(exports) {
|
|
|
44402
44453
|
if (needNamespaceDefine(attr, html, childNs)) {
|
|
44403
44454
|
var attrPrefix = attr.prefix || "";
|
|
44404
44455
|
var uri = attr.namespaceURI;
|
|
44405
|
-
addSerializedAttribute(buf, attrPrefix ? "xmlns:" + attrPrefix : "xmlns", uri);
|
|
44456
|
+
addSerializedAttribute(buf, attrPrefix ? "xmlns:" + attrPrefix : "xmlns", uri, requireWellFormed);
|
|
44406
44457
|
childNs.push({ prefix: attrPrefix, namespace: uri });
|
|
44407
44458
|
}
|
|
44408
44459
|
var filteredAttr = nodeFilter ? nodeFilter(attr) : attr;
|
|
@@ -44410,14 +44461,14 @@ var require_dom = __commonJS(function(exports) {
|
|
|
44410
44461
|
if (typeof filteredAttr === "string") {
|
|
44411
44462
|
buf.push(filteredAttr);
|
|
44412
44463
|
} else {
|
|
44413
|
-
addSerializedAttribute(buf, filteredAttr.name, filteredAttr.value);
|
|
44464
|
+
addSerializedAttribute(buf, filteredAttr.name, filteredAttr.value, requireWellFormed);
|
|
44414
44465
|
}
|
|
44415
44466
|
}
|
|
44416
44467
|
}
|
|
44417
44468
|
if (nodeName === prefixedNodeName && needNamespaceDefine(n, html, childNs)) {
|
|
44418
44469
|
var nodePrefix = n.prefix || "";
|
|
44419
44470
|
var uri = n.namespaceURI;
|
|
44420
|
-
addSerializedAttribute(buf, nodePrefix ? "xmlns:" + nodePrefix : "xmlns", uri);
|
|
44471
|
+
addSerializedAttribute(buf, nodePrefix ? "xmlns:" + nodePrefix : "xmlns", uri, requireWellFormed);
|
|
44421
44472
|
childNs.push({ prefix: nodePrefix, namespace: uri });
|
|
44422
44473
|
}
|
|
44423
44474
|
var child = n.firstChild;
|
|
@@ -44444,7 +44495,7 @@ var require_dom = __commonJS(function(exports) {
|
|
|
44444
44495
|
case DOCUMENT_FRAGMENT_NODE:
|
|
44445
44496
|
return { ns: ns.slice(), isHTML: html, tag: null };
|
|
44446
44497
|
case ATTRIBUTE_NODE:
|
|
44447
|
-
addSerializedAttribute(buf, n.name, n.value);
|
|
44498
|
+
addSerializedAttribute(buf, n.name, n.value, requireWellFormed);
|
|
44448
44499
|
return null;
|
|
44449
44500
|
case TEXT_NODE:
|
|
44450
44501
|
buf.push(n.data.replace(/[<&>]/g, _xmlEncoder));
|
|
@@ -44463,6 +44514,9 @@ var require_dom = __commonJS(function(exports) {
|
|
|
44463
44514
|
return null;
|
|
44464
44515
|
case DOCUMENT_TYPE_NODE:
|
|
44465
44516
|
if (requireWellFormed) {
|
|
44517
|
+
if (!tagNamePattern.test(n.name)) {
|
|
44518
|
+
throw new DOMException(INVALID_STATE_ERR, 'The doctype name "' + n.name + '" is not a valid XML Name');
|
|
44519
|
+
}
|
|
44466
44520
|
if (n.publicId && !/^("[\x20\r\na-zA-Z0-9\-()+,.\/:=?;!*#@$_%']*"|'[\x20\r\na-zA-Z0-9\-()+,.\/:=?;!*#@$_%'"]*')$/.test(n.publicId)) {
|
|
44467
44521
|
throw new DOMException(INVALID_STATE_ERR, "DocumentType publicId is not a valid PubidLiteral");
|
|
44468
44522
|
}
|
|
@@ -44493,12 +44547,20 @@ var require_dom = __commonJS(function(exports) {
|
|
|
44493
44547
|
}
|
|
44494
44548
|
return null;
|
|
44495
44549
|
case PROCESSING_INSTRUCTION_NODE:
|
|
44496
|
-
if (requireWellFormed
|
|
44497
|
-
|
|
44550
|
+
if (requireWellFormed) {
|
|
44551
|
+
if (!tagNamePattern.test(n.target) || n.target.indexOf(":") !== -1 || n.target.toLowerCase() === "xml") {
|
|
44552
|
+
throw new DOMException(INVALID_STATE_ERR, 'The processing instruction target "' + n.target + '" is not a valid XML NCName or is reserved');
|
|
44553
|
+
}
|
|
44554
|
+
if (n.data.indexOf("?>") !== -1) {
|
|
44555
|
+
throw new DOMException(INVALID_STATE_ERR, 'The ProcessingInstruction data contains "?>"');
|
|
44556
|
+
}
|
|
44498
44557
|
}
|
|
44499
44558
|
buf.push("<?", n.target, " ", n.data, "?>");
|
|
44500
44559
|
return null;
|
|
44501
44560
|
case ENTITY_REFERENCE_NODE:
|
|
44561
|
+
if (requireWellFormed && !tagNamePattern.test(n.nodeName)) {
|
|
44562
|
+
throw new DOMException(INVALID_STATE_ERR, 'The entity reference name "' + n.nodeName + '" is not a valid XML Name');
|
|
44563
|
+
}
|
|
44502
44564
|
buf.push("&", n.nodeName, ";");
|
|
44503
44565
|
return null;
|
|
44504
44566
|
default:
|
|
@@ -44637,7 +44699,7 @@ var require_dom = __commonJS(function(exports) {
|
|
|
44637
44699
|
exports.XMLSerializer = XMLSerializer;
|
|
44638
44700
|
});
|
|
44639
44701
|
|
|
44640
|
-
// ../../node_modules/.bun/@xmldom+xmldom@0.8.
|
|
44702
|
+
// ../../node_modules/.bun/@xmldom+xmldom@0.8.15/node_modules/@xmldom/xmldom/lib/entities.js
|
|
44641
44703
|
var require_entities = __commonJS(function(exports) {
|
|
44642
44704
|
var freeze = require_conventions().freeze;
|
|
44643
44705
|
exports.XML_ENTITIES = freeze({
|
|
@@ -46778,12 +46840,10 @@ var require_entities = __commonJS(function(exports) {
|
|
|
46778
46840
|
exports.entityMap = exports.HTML_ENTITIES;
|
|
46779
46841
|
});
|
|
46780
46842
|
|
|
46781
|
-
// ../../node_modules/.bun/@xmldom+xmldom@0.8.
|
|
46843
|
+
// ../../node_modules/.bun/@xmldom+xmldom@0.8.15/node_modules/@xmldom/xmldom/lib/sax.js
|
|
46782
46844
|
var require_sax = __commonJS(function(exports) {
|
|
46783
46845
|
var NAMESPACE = require_conventions().NAMESPACE;
|
|
46784
|
-
var
|
|
46785
|
-
var nameChar = new RegExp("[\\-\\.0-9" + nameStartChar.source.slice(1, -1) + "\\u00B7\\u0300-\\u036F\\u203F-\\u2040]");
|
|
46786
|
-
var tagNamePattern = new RegExp("^" + nameStartChar.source + nameChar.source + "*(?::" + nameStartChar.source + nameChar.source + "*)?$");
|
|
46846
|
+
var tagNamePattern = require_conventions().tagNamePattern;
|
|
46787
46847
|
var S_TAG = 0;
|
|
46788
46848
|
var S_ATTR = 1;
|
|
46789
46849
|
var S_ATTR_SPACE = 2;
|
|
@@ -46872,7 +46932,7 @@ var require_sax = __commonJS(function(exports) {
|
|
|
46872
46932
|
switch (source.charAt(tagStart + 1)) {
|
|
46873
46933
|
case "/":
|
|
46874
46934
|
var end = source.indexOf(">", tagStart + 3);
|
|
46875
|
-
var tagName = source.substring(tagStart + 2, end).replace(
|
|
46935
|
+
var tagName = source.substring(tagStart + 2, end).replace(/^([\s\S]*?[^ \t\n\r])?[ \t\n\r]*$/, "$1");
|
|
46876
46936
|
var config = parseStack.pop();
|
|
46877
46937
|
if (end < 0) {
|
|
46878
46938
|
tagName = source.substring(tagStart + 2).replace(/[\s<].*/, "");
|
|
@@ -46882,6 +46942,8 @@ var require_sax = __commonJS(function(exports) {
|
|
|
46882
46942
|
tagName = tagName.replace(/[\s<].*/, "");
|
|
46883
46943
|
errorHandler.error("end tag name: " + tagName + " maybe not complete");
|
|
46884
46944
|
end = tagStart + 1 + tagName.length;
|
|
46945
|
+
} else if (/[ \t\n\r]/.test(tagName) && tagNamePattern.test(tagName.split(/[ \t\n\r]/)[0])) {
|
|
46946
|
+
errorHandler.error('end tag name is followed by whitespace and trailing content: "' + tagName + '"');
|
|
46885
46947
|
}
|
|
46886
46948
|
var localNSMap = config.localNSMap;
|
|
46887
46949
|
var endMatch = config.tagName == tagName;
|
|
@@ -46978,6 +47040,9 @@ var require_sax = __commonJS(function(exports) {
|
|
|
46978
47040
|
var s = S_TAG;
|
|
46979
47041
|
while (true) {
|
|
46980
47042
|
var c2 = source.charAt(p);
|
|
47043
|
+
if (s === S_TAG && c2 === "<") {
|
|
47044
|
+
throw new Error("unexpected < in tag name: " + source.slice(start, p));
|
|
47045
|
+
}
|
|
46981
47046
|
switch (c2) {
|
|
46982
47047
|
case "=":
|
|
46983
47048
|
if (s === S_ATTR) {
|
|
@@ -47145,7 +47210,7 @@ var require_sax = __commonJS(function(exports) {
|
|
|
47145
47210
|
if (nsPrefix !== false) {
|
|
47146
47211
|
if (localNSMap == null) {
|
|
47147
47212
|
localNSMap = {};
|
|
47148
|
-
|
|
47213
|
+
currentNSMap = Object.create(currentNSMap);
|
|
47149
47214
|
}
|
|
47150
47215
|
currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
|
|
47151
47216
|
a.uri = NAMESPACE.XMLNS;
|
|
@@ -47334,7 +47399,7 @@ var require_sax = __commonJS(function(exports) {
|
|
|
47334
47399
|
exports.ParseError = ParseError;
|
|
47335
47400
|
});
|
|
47336
47401
|
|
|
47337
|
-
// ../../node_modules/.bun/@xmldom+xmldom@0.8.
|
|
47402
|
+
// ../../node_modules/.bun/@xmldom+xmldom@0.8.15/node_modules/@xmldom/xmldom/lib/dom-parser.js
|
|
47338
47403
|
var require_dom_parser = __commonJS(function(exports) {
|
|
47339
47404
|
var conventions = require_conventions();
|
|
47340
47405
|
var dom = require_dom();
|
|
@@ -47537,7 +47602,7 @@ var require_dom_parser = __commonJS(function(exports) {
|
|
|
47537
47602
|
exports.DOMParser = DOMParser;
|
|
47538
47603
|
});
|
|
47539
47604
|
|
|
47540
|
-
// ../../node_modules/.bun/@xmldom+xmldom@0.8.
|
|
47605
|
+
// ../../node_modules/.bun/@xmldom+xmldom@0.8.15/node_modules/@xmldom/xmldom/lib/index.js
|
|
47541
47606
|
var require_lib5 = __commonJS(function(exports) {
|
|
47542
47607
|
var dom = require_dom();
|
|
47543
47608
|
exports.DOMImplementation = dom.DOMImplementation;
|
|
@@ -55096,9 +55161,13 @@ var init_audit_log = __esm(() => {
|
|
|
55096
55161
|
};
|
|
55097
55162
|
});
|
|
55098
55163
|
|
|
55164
|
+
// ../../_shared/mcp-tools/access-paths.ts
|
|
55165
|
+
var init_access_paths = () => {};
|
|
55166
|
+
|
|
55099
55167
|
// ../../_shared/mcp-tools/types.ts
|
|
55100
55168
|
var McpInvalidParams;
|
|
55101
55169
|
var init_types3 = __esm(() => {
|
|
55170
|
+
init_access_paths();
|
|
55102
55171
|
McpInvalidParams = class McpInvalidParams extends Error {
|
|
55103
55172
|
constructor(message) {
|
|
55104
55173
|
super(message);
|
|
@@ -66863,13 +66932,32 @@ var require_data = __commonJS(function(exports, module) {
|
|
|
66863
66932
|
};
|
|
66864
66933
|
});
|
|
66865
66934
|
|
|
66866
|
-
// ../../node_modules/.bun/fast-uri@3.1.
|
|
66935
|
+
// ../../node_modules/.bun/fast-uri@3.1.7/node_modules/fast-uri/lib/utils.js
|
|
66867
66936
|
var require_utils2 = __commonJS(function(exports, module) {
|
|
66868
66937
|
var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
|
|
66869
66938
|
var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
|
|
66939
|
+
var isPort = RegExp.prototype.test.bind(/^\d*$/u);
|
|
66870
66940
|
var isHexPair = RegExp.prototype.test.bind(/^[\da-f]{2}$/iu);
|
|
66871
66941
|
var isUnreserved = RegExp.prototype.test.bind(/^[\da-z\-._~]$/iu);
|
|
66872
|
-
var isPathCharacter = RegExp.prototype.test.bind(/^[
|
|
66942
|
+
var isPathCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/]$/u);
|
|
66943
|
+
var isQueryFragmentCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:@/?]$/u);
|
|
66944
|
+
var isUserinfoCharacter = RegExp.prototype.test.bind(/^[A-Za-z0-9\-._~!$&'()*+,;=:]$/u);
|
|
66945
|
+
var BYTE_HEX = new Array(256);
|
|
66946
|
+
{
|
|
66947
|
+
const HEX_DIGITS = "0123456789ABCDEF";
|
|
66948
|
+
for (let i = 0;i < 256; i++) {
|
|
66949
|
+
BYTE_HEX[i] = "%" + HEX_DIGITS[i >> 4] + HEX_DIGITS[i & 15];
|
|
66950
|
+
}
|
|
66951
|
+
}
|
|
66952
|
+
function percentEncodeNonAscii(cp) {
|
|
66953
|
+
if (cp < 2048) {
|
|
66954
|
+
return BYTE_HEX[192 | cp >> 6] + BYTE_HEX[128 | cp & 63];
|
|
66955
|
+
}
|
|
66956
|
+
if (cp < 65536) {
|
|
66957
|
+
return BYTE_HEX[224 | cp >> 12] + BYTE_HEX[128 | cp >> 6 & 63] + BYTE_HEX[128 | cp & 63];
|
|
66958
|
+
}
|
|
66959
|
+
return BYTE_HEX[240 | cp >> 18] + BYTE_HEX[128 | cp >> 12 & 63] + BYTE_HEX[128 | cp >> 6 & 63] + BYTE_HEX[128 | cp & 63];
|
|
66960
|
+
}
|
|
66873
66961
|
function stringArrayToHexStripped(input) {
|
|
66874
66962
|
let acc = "";
|
|
66875
66963
|
let code = 0;
|
|
@@ -66894,91 +66982,122 @@ var require_utils2 = __commonJS(function(exports, module) {
|
|
|
66894
66982
|
}
|
|
66895
66983
|
return acc;
|
|
66896
66984
|
}
|
|
66985
|
+
var isHextet = RegExp.prototype.test.bind(/^[\dA-Fa-f]{1,4}$/);
|
|
66986
|
+
var isIPvFuture = RegExp.prototype.test.bind(/^[vV][\dA-Fa-f]+\.[A-Za-z\d\-._~!$&'()*+,;=:]+$/);
|
|
66987
|
+
var isZoneCharacter = RegExp.prototype.test.bind(/^[A-Za-z\d\-._~]$/);
|
|
66897
66988
|
var nonSimpleDomain = RegExp.prototype.test.bind(/[^!"$&'()*+,\-.;=_`a-z{}~]/u);
|
|
66898
|
-
function
|
|
66899
|
-
|
|
66900
|
-
|
|
66901
|
-
|
|
66902
|
-
|
|
66903
|
-
|
|
66904
|
-
|
|
66905
|
-
|
|
66906
|
-
|
|
66907
|
-
} else {
|
|
66908
|
-
output.error = true;
|
|
66909
|
-
return false;
|
|
66989
|
+
function isZoneIdentifier(zone) {
|
|
66990
|
+
if (zone.length === 0)
|
|
66991
|
+
return false;
|
|
66992
|
+
for (let i = 0;i < zone.length; i++) {
|
|
66993
|
+
if (isZoneCharacter(zone[i]))
|
|
66994
|
+
continue;
|
|
66995
|
+
if (zone[i] === "%" && i + 2 < zone.length && isHexPair(zone.slice(i + 1, i + 3))) {
|
|
66996
|
+
i += 2;
|
|
66997
|
+
continue;
|
|
66910
66998
|
}
|
|
66911
|
-
|
|
66999
|
+
return false;
|
|
66912
67000
|
}
|
|
66913
67001
|
return true;
|
|
66914
67002
|
}
|
|
66915
|
-
function
|
|
66916
|
-
let
|
|
66917
|
-
|
|
66918
|
-
|
|
66919
|
-
|
|
66920
|
-
let
|
|
66921
|
-
|
|
66922
|
-
|
|
66923
|
-
|
|
66924
|
-
|
|
66925
|
-
|
|
66926
|
-
|
|
66927
|
-
|
|
66928
|
-
if (cursor === ":") {
|
|
66929
|
-
if (endipv6Encountered === true) {
|
|
66930
|
-
endIpv6 = true;
|
|
66931
|
-
}
|
|
66932
|
-
if (!consume(buffer2, address, output)) {
|
|
66933
|
-
break;
|
|
66934
|
-
}
|
|
66935
|
-
if (++tokenCount > 7) {
|
|
66936
|
-
output.error = true;
|
|
66937
|
-
break;
|
|
67003
|
+
function compressIPv6ZeroRun(hextets) {
|
|
67004
|
+
let bestStart = -1;
|
|
67005
|
+
let bestLength = 0;
|
|
67006
|
+
let runStart = -1;
|
|
67007
|
+
let runLength = 0;
|
|
67008
|
+
for (let i = 0;i < hextets.length; i++) {
|
|
67009
|
+
if (hextets[i] === "0") {
|
|
67010
|
+
if (runStart === -1)
|
|
67011
|
+
runStart = i;
|
|
67012
|
+
runLength++;
|
|
67013
|
+
if (runLength > bestLength) {
|
|
67014
|
+
bestLength = runLength;
|
|
67015
|
+
bestStart = runStart;
|
|
66938
67016
|
}
|
|
66939
|
-
if (i > 0 && input[i - 1] === ":") {
|
|
66940
|
-
endipv6Encountered = true;
|
|
66941
|
-
}
|
|
66942
|
-
address.push(":");
|
|
66943
|
-
continue;
|
|
66944
|
-
} else if (cursor === "%") {
|
|
66945
|
-
if (!consume(buffer2, address, output)) {
|
|
66946
|
-
break;
|
|
66947
|
-
}
|
|
66948
|
-
consume = consumeIsZone;
|
|
66949
67017
|
} else {
|
|
66950
|
-
|
|
66951
|
-
|
|
67018
|
+
runStart = -1;
|
|
67019
|
+
runLength = 0;
|
|
66952
67020
|
}
|
|
66953
67021
|
}
|
|
66954
|
-
if (
|
|
66955
|
-
|
|
66956
|
-
|
|
66957
|
-
|
|
66958
|
-
|
|
66959
|
-
|
|
66960
|
-
|
|
67022
|
+
if (bestLength < 2)
|
|
67023
|
+
return hextets.join(":");
|
|
67024
|
+
const head2 = hextets.slice(0, bestStart).join(":");
|
|
67025
|
+
const tail = hextets.slice(bestStart + bestLength).join(":");
|
|
67026
|
+
return head2 + "::" + tail;
|
|
67027
|
+
}
|
|
67028
|
+
function normalizeIPv6Address(input) {
|
|
67029
|
+
const compression = input.indexOf("::");
|
|
67030
|
+
if (compression !== -1 && input.indexOf("::", compression + 1) !== -1)
|
|
67031
|
+
return;
|
|
67032
|
+
const left = compression === -1 ? input.split(":") : input.slice(0, compression).split(":");
|
|
67033
|
+
const right = compression === -1 ? [] : input.slice(compression + 2).split(":");
|
|
67034
|
+
if (compression !== -1) {
|
|
67035
|
+
if (left.length === 1 && left[0] === "")
|
|
67036
|
+
left.length = 0;
|
|
67037
|
+
if (right.length === 1 && right[0] === "")
|
|
67038
|
+
right.length = 0;
|
|
67039
|
+
}
|
|
67040
|
+
const parts = left.concat(right);
|
|
67041
|
+
let hextetCount = 0;
|
|
67042
|
+
for (let i = 0;i < parts.length; i++) {
|
|
67043
|
+
const part = parts[i];
|
|
67044
|
+
if (part === "")
|
|
67045
|
+
return;
|
|
67046
|
+
if (part.indexOf(".") !== -1) {
|
|
67047
|
+
if (i !== parts.length - 1 || compression !== -1 && right.length === 0 || !isIPv4(part))
|
|
67048
|
+
return;
|
|
67049
|
+
hextetCount += 2;
|
|
67050
|
+
continue;
|
|
66961
67051
|
}
|
|
67052
|
+
if (!isHextet(part))
|
|
67053
|
+
return;
|
|
67054
|
+
parts[i] = parseInt(part, 16).toString(16);
|
|
67055
|
+
hextetCount++;
|
|
66962
67056
|
}
|
|
66963
|
-
|
|
66964
|
-
|
|
67057
|
+
if (compression === -1) {
|
|
67058
|
+
if (hextetCount !== 8)
|
|
67059
|
+
return;
|
|
67060
|
+
return compressIPv6ZeroRun(parts);
|
|
67061
|
+
}
|
|
67062
|
+
if (hextetCount >= 8)
|
|
67063
|
+
return;
|
|
67064
|
+
const expanded = parts.slice(0, left.length);
|
|
67065
|
+
for (let i = hextetCount;i < 8; i++)
|
|
67066
|
+
expanded.push("0");
|
|
67067
|
+
for (let i = left.length;i < parts.length; i++)
|
|
67068
|
+
expanded.push(parts[i]);
|
|
67069
|
+
return compressIPv6ZeroRun(expanded);
|
|
66965
67070
|
}
|
|
66966
67071
|
function normalizeIPv6(host) {
|
|
66967
|
-
|
|
66968
|
-
|
|
66969
|
-
|
|
66970
|
-
|
|
66971
|
-
|
|
66972
|
-
|
|
66973
|
-
|
|
66974
|
-
|
|
66975
|
-
|
|
66976
|
-
|
|
66977
|
-
}
|
|
66978
|
-
|
|
66979
|
-
|
|
66980
|
-
|
|
66981
|
-
|
|
67072
|
+
const bracketed = host[0] === "[" && host[host.length - 1] === "]";
|
|
67073
|
+
const hasBracket = host[0] === "[" || host[host.length - 1] === "]";
|
|
67074
|
+
if (hasBracket && !bracketed)
|
|
67075
|
+
return { host, isIPV6: false, error: true };
|
|
67076
|
+
let input = bracketed ? host.slice(1, -1) : host;
|
|
67077
|
+
if (bracketed && isIPvFuture(input)) {
|
|
67078
|
+
input = input.toLowerCase();
|
|
67079
|
+
return { host: `[${input}]`, escapedHost: input, isIPV6: false, isIPVFuture: true };
|
|
67080
|
+
}
|
|
67081
|
+
if (findToken(input, ":") < 2) {
|
|
67082
|
+
return { host, isIPV6: false, error: bracketed };
|
|
67083
|
+
}
|
|
67084
|
+
let zoneIdentifier = "";
|
|
67085
|
+
const zoneSeparator = input.indexOf("%");
|
|
67086
|
+
if (zoneSeparator !== -1) {
|
|
67087
|
+
const separatorLength = input.slice(zoneSeparator, zoneSeparator + 3).toLowerCase() === "%25" ? 3 : 1;
|
|
67088
|
+
zoneIdentifier = input.slice(zoneSeparator + separatorLength);
|
|
67089
|
+
if (!isZoneIdentifier(zoneIdentifier))
|
|
67090
|
+
return { host, isIPV6: false, error: true };
|
|
67091
|
+
input = input.slice(0, zoneSeparator);
|
|
67092
|
+
}
|
|
67093
|
+
const address = normalizeIPv6Address(input);
|
|
67094
|
+
if (address === undefined)
|
|
67095
|
+
return { host, isIPV6: false, error: true };
|
|
67096
|
+
return {
|
|
67097
|
+
host: address + (zoneIdentifier ? "%" + zoneIdentifier : ""),
|
|
67098
|
+
escapedHost: address + (zoneIdentifier ? "%25" + zoneIdentifier : ""),
|
|
67099
|
+
isIPV6: true
|
|
67100
|
+
};
|
|
66982
67101
|
}
|
|
66983
67102
|
function findToken(str, token) {
|
|
66984
67103
|
let ind = 0;
|
|
@@ -67098,7 +67217,8 @@ var require_utils2 = __commonJS(function(exports, module) {
|
|
|
67098
67217
|
function normalizePathEncoding(input) {
|
|
67099
67218
|
let output = "";
|
|
67100
67219
|
for (let i = 0;i < input.length; i++) {
|
|
67101
|
-
|
|
67220
|
+
const ch = input[i];
|
|
67221
|
+
if (ch === "%" && i + 2 < input.length) {
|
|
67102
67222
|
const hex = input.slice(i + 1, i + 3);
|
|
67103
67223
|
if (isHexPair(hex)) {
|
|
67104
67224
|
const normalizedHex = hex.toUpperCase();
|
|
@@ -67112,10 +67232,152 @@ var require_utils2 = __commonJS(function(exports, module) {
|
|
|
67112
67232
|
continue;
|
|
67113
67233
|
}
|
|
67114
67234
|
}
|
|
67115
|
-
if (isPathCharacter(
|
|
67116
|
-
output +=
|
|
67235
|
+
if (isPathCharacter(ch)) {
|
|
67236
|
+
output += ch;
|
|
67237
|
+
} else {
|
|
67238
|
+
const code = input.charCodeAt(i);
|
|
67239
|
+
if (code < 128) {
|
|
67240
|
+
output += isEscapeSafe(code) ? ch : BYTE_HEX[code];
|
|
67241
|
+
} else if (code < 55296 || code > 57343) {
|
|
67242
|
+
output += percentEncodeNonAscii(code);
|
|
67243
|
+
} else if (code <= 56319 && i + 1 < input.length) {
|
|
67244
|
+
const low = input.charCodeAt(i + 1);
|
|
67245
|
+
if (low >= 56320 && low <= 57343) {
|
|
67246
|
+
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
|
|
67247
|
+
i++;
|
|
67248
|
+
} else {
|
|
67249
|
+
output += percentEncodeNonAscii(65533);
|
|
67250
|
+
}
|
|
67251
|
+
} else {
|
|
67252
|
+
output += percentEncodeNonAscii(65533);
|
|
67253
|
+
}
|
|
67254
|
+
}
|
|
67255
|
+
}
|
|
67256
|
+
return output;
|
|
67257
|
+
}
|
|
67258
|
+
function serializePathEncoding(input, pathNoScheme = false) {
|
|
67259
|
+
let output = "";
|
|
67260
|
+
let firstSegment = pathNoScheme && input[0] !== "/";
|
|
67261
|
+
for (let i = 0;i < input.length; i++) {
|
|
67262
|
+
const ch = input[i];
|
|
67263
|
+
if (ch === "%" && i + 2 < input.length) {
|
|
67264
|
+
const hex = input.slice(i + 1, i + 3);
|
|
67265
|
+
if (isHexPair(hex)) {
|
|
67266
|
+
output += "%" + hex.toUpperCase();
|
|
67267
|
+
i += 2;
|
|
67268
|
+
continue;
|
|
67269
|
+
}
|
|
67270
|
+
}
|
|
67271
|
+
if (ch === "/") {
|
|
67272
|
+
firstSegment = false;
|
|
67273
|
+
}
|
|
67274
|
+
if (isPathCharacter(ch) && (ch !== ":" || !firstSegment)) {
|
|
67275
|
+
output += ch;
|
|
67276
|
+
} else {
|
|
67277
|
+
const code = input.charCodeAt(i);
|
|
67278
|
+
if (code < 128) {
|
|
67279
|
+
output += BYTE_HEX[code];
|
|
67280
|
+
} else if (code < 55296 || code > 57343) {
|
|
67281
|
+
output += percentEncodeNonAscii(code);
|
|
67282
|
+
} else if (code <= 56319 && i + 1 < input.length) {
|
|
67283
|
+
const low = input.charCodeAt(i + 1);
|
|
67284
|
+
if (low >= 56320 && low <= 57343) {
|
|
67285
|
+
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
|
|
67286
|
+
i++;
|
|
67287
|
+
} else {
|
|
67288
|
+
output += percentEncodeNonAscii(65533);
|
|
67289
|
+
}
|
|
67290
|
+
} else {
|
|
67291
|
+
output += percentEncodeNonAscii(65533);
|
|
67292
|
+
}
|
|
67293
|
+
}
|
|
67294
|
+
}
|
|
67295
|
+
return output;
|
|
67296
|
+
}
|
|
67297
|
+
function encodeComponent(input, isAllowed) {
|
|
67298
|
+
let output = "";
|
|
67299
|
+
for (let i = 0;i < input.length; i++) {
|
|
67300
|
+
const ch = input[i];
|
|
67301
|
+
if (ch === "%" && i + 2 < input.length) {
|
|
67302
|
+
const hex = input.slice(i + 1, i + 3);
|
|
67303
|
+
if (isHexPair(hex)) {
|
|
67304
|
+
output += "%" + hex.toUpperCase();
|
|
67305
|
+
i += 2;
|
|
67306
|
+
continue;
|
|
67307
|
+
}
|
|
67308
|
+
}
|
|
67309
|
+
if (isAllowed(ch)) {
|
|
67310
|
+
output += ch;
|
|
67311
|
+
} else {
|
|
67312
|
+
const code = input.charCodeAt(i);
|
|
67313
|
+
if (code < 128) {
|
|
67314
|
+
output += BYTE_HEX[code];
|
|
67315
|
+
} else if (code < 55296 || code > 57343) {
|
|
67316
|
+
output += percentEncodeNonAscii(code);
|
|
67317
|
+
} else if (code <= 56319 && i + 1 < input.length) {
|
|
67318
|
+
const low = input.charCodeAt(i + 1);
|
|
67319
|
+
if (low >= 56320 && low <= 57343) {
|
|
67320
|
+
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
|
|
67321
|
+
i++;
|
|
67322
|
+
} else {
|
|
67323
|
+
output += percentEncodeNonAscii(65533);
|
|
67324
|
+
}
|
|
67325
|
+
} else {
|
|
67326
|
+
output += percentEncodeNonAscii(65533);
|
|
67327
|
+
}
|
|
67328
|
+
}
|
|
67329
|
+
}
|
|
67330
|
+
return output;
|
|
67331
|
+
}
|
|
67332
|
+
function encodeUserinfo(input) {
|
|
67333
|
+
return encodeComponent(input, isUserinfoCharacter);
|
|
67334
|
+
}
|
|
67335
|
+
function encodeQuery(input) {
|
|
67336
|
+
return encodeComponent(input, isQueryFragmentCharacter);
|
|
67337
|
+
}
|
|
67338
|
+
function encodeFragment(input) {
|
|
67339
|
+
return encodeComponent(input, isQueryFragmentCharacter);
|
|
67340
|
+
}
|
|
67341
|
+
function isEscapeSafe(cp) {
|
|
67342
|
+
return cp >= 48 && cp <= 57 || cp >= 65 && cp <= 90 || cp >= 97 && cp <= 122 || cp === 42 || cp === 43 || cp === 45 || cp === 46 || cp === 47 || cp === 64 || cp === 95;
|
|
67343
|
+
}
|
|
67344
|
+
function normalizeQueryFragmentEncoding(input) {
|
|
67345
|
+
let output = "";
|
|
67346
|
+
for (let i = 0;i < input.length; i++) {
|
|
67347
|
+
const ch = input[i];
|
|
67348
|
+
if (ch === "%" && i + 2 < input.length) {
|
|
67349
|
+
const hex = input.slice(i + 1, i + 3);
|
|
67350
|
+
if (isHexPair(hex)) {
|
|
67351
|
+
const normalizedHex = hex.toUpperCase();
|
|
67352
|
+
const decoded = String.fromCharCode(parseInt(normalizedHex, 16));
|
|
67353
|
+
if (isUnreserved(decoded)) {
|
|
67354
|
+
output += decoded;
|
|
67355
|
+
} else {
|
|
67356
|
+
output += "%" + normalizedHex;
|
|
67357
|
+
}
|
|
67358
|
+
i += 2;
|
|
67359
|
+
continue;
|
|
67360
|
+
}
|
|
67361
|
+
}
|
|
67362
|
+
if (isQueryFragmentCharacter(ch)) {
|
|
67363
|
+
output += ch;
|
|
67117
67364
|
} else {
|
|
67118
|
-
|
|
67365
|
+
const code = input.charCodeAt(i);
|
|
67366
|
+
if (code < 128) {
|
|
67367
|
+
output += isEscapeSafe(code) ? ch : BYTE_HEX[code];
|
|
67368
|
+
} else if (code < 55296 || code > 57343) {
|
|
67369
|
+
output += percentEncodeNonAscii(code);
|
|
67370
|
+
} else if (code <= 56319 && i + 1 < input.length) {
|
|
67371
|
+
const low = input.charCodeAt(i + 1);
|
|
67372
|
+
if (low >= 56320 && low <= 57343) {
|
|
67373
|
+
output += percentEncodeNonAscii(65536 + (code - 55296 << 10) + (low - 56320));
|
|
67374
|
+
i++;
|
|
67375
|
+
} else {
|
|
67376
|
+
output += percentEncodeNonAscii(65533);
|
|
67377
|
+
}
|
|
67378
|
+
} else {
|
|
67379
|
+
output += percentEncodeNonAscii(65533);
|
|
67380
|
+
}
|
|
67119
67381
|
}
|
|
67120
67382
|
}
|
|
67121
67383
|
return output;
|
|
@@ -67138,14 +67400,18 @@ var require_utils2 = __commonJS(function(exports, module) {
|
|
|
67138
67400
|
function recomposeAuthority(component) {
|
|
67139
67401
|
const uriTokens = [];
|
|
67140
67402
|
if (component.userinfo !== undefined) {
|
|
67141
|
-
uriTokens.push(component.userinfo);
|
|
67403
|
+
uriTokens.push(encodeUserinfo(component.userinfo));
|
|
67142
67404
|
uriTokens.push("@");
|
|
67143
67405
|
}
|
|
67144
67406
|
if (component.host !== undefined) {
|
|
67145
|
-
let host =
|
|
67407
|
+
let host = component.host;
|
|
67146
67408
|
if (!isIPv4(host)) {
|
|
67147
|
-
|
|
67148
|
-
if (ipV6res.isIPV6
|
|
67409
|
+
let ipV6res = normalizeIPv6(host);
|
|
67410
|
+
if (ipV6res.isIPV6 !== true && ipV6res.isIPVFuture !== true) {
|
|
67411
|
+
host = normalizePercentEncoding(host, true);
|
|
67412
|
+
ipV6res = normalizeIPv6(host);
|
|
67413
|
+
}
|
|
67414
|
+
if (ipV6res.isIPV6 === true || ipV6res.isIPVFuture === true) {
|
|
67149
67415
|
host = `[${ipV6res.escapedHost}]`;
|
|
67150
67416
|
} else {
|
|
67151
67417
|
host = reescapeHostDelimiters(host, false);
|
|
@@ -67154,8 +67420,12 @@ var require_utils2 = __commonJS(function(exports, module) {
|
|
|
67154
67420
|
uriTokens.push(host);
|
|
67155
67421
|
}
|
|
67156
67422
|
if (typeof component.port === "number" || typeof component.port === "string") {
|
|
67423
|
+
const port = String(component.port);
|
|
67424
|
+
if (!isPort(port)) {
|
|
67425
|
+
throw new TypeError("URI port is malformed.");
|
|
67426
|
+
}
|
|
67157
67427
|
uriTokens.push(":");
|
|
67158
|
-
uriTokens.push(
|
|
67428
|
+
uriTokens.push(port);
|
|
67159
67429
|
}
|
|
67160
67430
|
return uriTokens.length ? uriTokens.join("") : undefined;
|
|
67161
67431
|
}
|
|
@@ -67165,6 +67435,11 @@ var require_utils2 = __commonJS(function(exports, module) {
|
|
|
67165
67435
|
reescapeHostDelimiters,
|
|
67166
67436
|
normalizePercentEncoding,
|
|
67167
67437
|
normalizePathEncoding,
|
|
67438
|
+
serializePathEncoding,
|
|
67439
|
+
normalizeQueryFragmentEncoding,
|
|
67440
|
+
encodeUserinfo,
|
|
67441
|
+
encodeQuery,
|
|
67442
|
+
encodeFragment,
|
|
67168
67443
|
escapePreservingEscapes,
|
|
67169
67444
|
removeDotSegments,
|
|
67170
67445
|
isIPv4,
|
|
@@ -67174,10 +67449,10 @@ var require_utils2 = __commonJS(function(exports, module) {
|
|
|
67174
67449
|
};
|
|
67175
67450
|
});
|
|
67176
67451
|
|
|
67177
|
-
// ../../node_modules/.bun/fast-uri@3.1.
|
|
67452
|
+
// ../../node_modules/.bun/fast-uri@3.1.7/node_modules/fast-uri/lib/schemes.js
|
|
67178
67453
|
var require_schemes = __commonJS(function(exports, module) {
|
|
67179
67454
|
var { isUUID } = require_utils2();
|
|
67180
|
-
var URN_REG =
|
|
67455
|
+
var URN_REG = /^([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-./:;=@]|%[\da-f]{2})+)$/iu;
|
|
67181
67456
|
var supportedSchemeNames = [
|
|
67182
67457
|
"http",
|
|
67183
67458
|
"https",
|
|
@@ -67232,9 +67507,10 @@ var require_schemes = __commonJS(function(exports, module) {
|
|
|
67232
67507
|
wsComponent.secure = undefined;
|
|
67233
67508
|
}
|
|
67234
67509
|
if (wsComponent.resourceName) {
|
|
67235
|
-
const
|
|
67510
|
+
const queryIndex = wsComponent.resourceName.indexOf("?");
|
|
67511
|
+
const path = queryIndex === -1 ? wsComponent.resourceName : wsComponent.resourceName.slice(0, queryIndex);
|
|
67236
67512
|
wsComponent.path = path && path !== "/" ? path : undefined;
|
|
67237
|
-
wsComponent.query =
|
|
67513
|
+
wsComponent.query = queryIndex === -1 ? undefined : wsComponent.resourceName.slice(queryIndex + 1);
|
|
67238
67514
|
wsComponent.resourceName = undefined;
|
|
67239
67515
|
}
|
|
67240
67516
|
wsComponent.fragment = undefined;
|
|
@@ -67246,7 +67522,7 @@ var require_schemes = __commonJS(function(exports, module) {
|
|
|
67246
67522
|
return urnComponent;
|
|
67247
67523
|
}
|
|
67248
67524
|
const matches = urnComponent.path.match(URN_REG);
|
|
67249
|
-
if (matches) {
|
|
67525
|
+
if (matches && matches[0] === urnComponent.path) {
|
|
67250
67526
|
const scheme = options.scheme || urnComponent.scheme || "urn";
|
|
67251
67527
|
urnComponent.nid = matches[1].toLowerCase();
|
|
67252
67528
|
urnComponent.nss = matches[2];
|
|
@@ -67348,10 +67624,19 @@ var require_schemes = __commonJS(function(exports, module) {
|
|
|
67348
67624
|
};
|
|
67349
67625
|
});
|
|
67350
67626
|
|
|
67351
|
-
// ../../node_modules/.bun/fast-uri@3.1.
|
|
67627
|
+
// ../../node_modules/.bun/fast-uri@3.1.7/node_modules/fast-uri/index.js
|
|
67352
67628
|
var require_fast_uri = __commonJS(function(exports, module) {
|
|
67353
|
-
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding,
|
|
67629
|
+
var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils2();
|
|
67354
67630
|
var { SCHEMES, getSchemeHandler } = require_schemes();
|
|
67631
|
+
var VALID_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/u;
|
|
67632
|
+
var MALFORMED_SCHEME_ERROR = "URI scheme is malformed.";
|
|
67633
|
+
function decodeValidScheme(scheme) {
|
|
67634
|
+
const decodedScheme = unescape(String(scheme));
|
|
67635
|
+
if (!VALID_SCHEME.test(decodedScheme)) {
|
|
67636
|
+
throw new TypeError(MALFORMED_SCHEME_ERROR);
|
|
67637
|
+
}
|
|
67638
|
+
return decodedScheme;
|
|
67639
|
+
}
|
|
67355
67640
|
function normalize(uri, options) {
|
|
67356
67641
|
if (typeof uri === "string") {
|
|
67357
67642
|
uri = normalizeString(uri, options);
|
|
@@ -67362,12 +67647,34 @@ var require_fast_uri = __commonJS(function(exports, module) {
|
|
|
67362
67647
|
}
|
|
67363
67648
|
function resolve4(baseURI, relativeURI, options) {
|
|
67364
67649
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
67365
|
-
const {
|
|
67366
|
-
|
|
67367
|
-
|
|
67650
|
+
const {
|
|
67651
|
+
parsed: baseParsed,
|
|
67652
|
+
malformedAuthorityOrPort: baseMalformed,
|
|
67653
|
+
malformedPercentEncoding: baseMalformedPercentEncoding,
|
|
67654
|
+
malformedSchemeSpecific: baseMalformedSchemeSpecific,
|
|
67655
|
+
malformedHost: baseMalformedHost,
|
|
67656
|
+
malformedScheme: baseMalformedScheme
|
|
67657
|
+
} = parseWithStatus(baseURI, schemelessOptions);
|
|
67658
|
+
const {
|
|
67659
|
+
parsed: relativeParsed,
|
|
67660
|
+
malformedAuthorityOrPort: relativeMalformed,
|
|
67661
|
+
malformedPercentEncoding: relativeMalformedPercentEncoding,
|
|
67662
|
+
malformedSchemeSpecific: relativeMalformedSchemeSpecific,
|
|
67663
|
+
malformedHost: relativeMalformedHost,
|
|
67664
|
+
malformedScheme: relativeMalformedScheme
|
|
67665
|
+
} = parseWithStatus(relativeURI, schemelessOptions);
|
|
67666
|
+
if (baseMalformed || relativeMalformed || baseMalformedPercentEncoding || relativeMalformedPercentEncoding || baseMalformedSchemeSpecific || relativeMalformedSchemeSpecific || baseMalformedHost || relativeMalformedHost || baseMalformedScheme || relativeMalformedScheme) {
|
|
67368
67667
|
throw new Error(baseParsed.error || relativeParsed.error || "URI is malformed.");
|
|
67369
67668
|
}
|
|
67370
67669
|
const resolved = resolveComponent(baseParsed, relativeParsed, schemelessOptions, true);
|
|
67670
|
+
const resolvedSchemeHandler = getSchemeHandler(options && options.scheme || resolved.scheme);
|
|
67671
|
+
const resolvedHost = resolved.host;
|
|
67672
|
+
const resolvedHostIsIP = resolvedHost !== undefined && resolvedHost !== "" && (isIPv4(resolvedHost) || normalizeIPv6(resolvedHost).isIPV6);
|
|
67673
|
+
canonicalizeHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP);
|
|
67674
|
+
const encodedASCIIHost = resolvedHost && resolvedHost.indexOf("%") !== -1 && !/\P{ASCII}/u.test(resolvedHost);
|
|
67675
|
+
if (resolved.error && !encodedASCIIHost) {
|
|
67676
|
+
throw new Error(resolved.error);
|
|
67677
|
+
}
|
|
67371
67678
|
schemelessOptions.skipEscape = true;
|
|
67372
67679
|
return serialize(resolved, schemelessOptions);
|
|
67373
67680
|
}
|
|
@@ -67427,7 +67734,7 @@ var require_fast_uri = __commonJS(function(exports, module) {
|
|
|
67427
67734
|
function equal(uriA, uriB, options) {
|
|
67428
67735
|
const normalizedA = normalizeComparableURI(uriA, options);
|
|
67429
67736
|
const normalizedB = normalizeComparableURI(uriB, options);
|
|
67430
|
-
return normalizedA !== undefined && normalizedB !== undefined && normalizedA
|
|
67737
|
+
return normalizedA !== undefined && normalizedB !== undefined && normalizedA === normalizedB;
|
|
67431
67738
|
}
|
|
67432
67739
|
function serialize(cmpts, opts) {
|
|
67433
67740
|
const component = {
|
|
@@ -67448,20 +67755,23 @@ var require_fast_uri = __commonJS(function(exports, module) {
|
|
|
67448
67755
|
};
|
|
67449
67756
|
const options = Object.assign({}, opts);
|
|
67450
67757
|
const uriTokens = [];
|
|
67758
|
+
if (component.scheme) {
|
|
67759
|
+
component.scheme = decodeValidScheme(component.scheme);
|
|
67760
|
+
}
|
|
67451
67761
|
const schemeHandler = getSchemeHandler(options.scheme || component.scheme);
|
|
67452
67762
|
if (schemeHandler && schemeHandler.serialize)
|
|
67453
67763
|
schemeHandler.serialize(component, options);
|
|
67764
|
+
const hasAuthority = component.userinfo !== undefined || component.host !== undefined || component.port !== undefined;
|
|
67765
|
+
const pathNoScheme = !options.skipEscape && component.scheme === undefined && !hasAuthority;
|
|
67454
67766
|
if (component.path !== undefined) {
|
|
67455
67767
|
if (!options.skipEscape) {
|
|
67456
|
-
component.path =
|
|
67457
|
-
if (component.scheme !== undefined) {
|
|
67458
|
-
component.path = component.path.split("%3A").join(":");
|
|
67459
|
-
}
|
|
67768
|
+
component.path = serializePathEncoding(component.path, pathNoScheme);
|
|
67460
67769
|
} else {
|
|
67461
67770
|
component.path = normalizePercentEncoding(component.path);
|
|
67462
67771
|
}
|
|
67463
67772
|
}
|
|
67464
67773
|
if (options.reference !== "suffix" && component.scheme) {
|
|
67774
|
+
component.scheme = decodeValidScheme(component.scheme);
|
|
67465
67775
|
uriTokens.push(component.scheme, ":");
|
|
67466
67776
|
}
|
|
67467
67777
|
const authority = recomposeAuthority(component);
|
|
@@ -67479,16 +67789,19 @@ var require_fast_uri = __commonJS(function(exports, module) {
|
|
|
67479
67789
|
if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) {
|
|
67480
67790
|
s = removeDotSegments(s);
|
|
67481
67791
|
}
|
|
67792
|
+
if (pathNoScheme) {
|
|
67793
|
+
s = serializePathEncoding(s, true);
|
|
67794
|
+
}
|
|
67482
67795
|
if (authority === undefined && s[0] === "/" && s[1] === "/") {
|
|
67483
67796
|
s = "/%2F" + s.slice(2);
|
|
67484
67797
|
}
|
|
67485
67798
|
uriTokens.push(s);
|
|
67486
67799
|
}
|
|
67487
67800
|
if (component.query !== undefined) {
|
|
67488
|
-
uriTokens.push("?", component.query);
|
|
67801
|
+
uriTokens.push("?", encodeQuery(component.query));
|
|
67489
67802
|
}
|
|
67490
67803
|
if (component.fragment !== undefined) {
|
|
67491
|
-
uriTokens.push("#", component.fragment);
|
|
67804
|
+
uriTokens.push("#", encodeFragment(component.fragment));
|
|
67492
67805
|
}
|
|
67493
67806
|
return uriTokens.join("");
|
|
67494
67807
|
}
|
|
@@ -67504,6 +67817,36 @@ var require_fast_uri = __commonJS(function(exports, module) {
|
|
|
67504
67817
|
}
|
|
67505
67818
|
return;
|
|
67506
67819
|
}
|
|
67820
|
+
function hasMalformedPercentEncoding(component) {
|
|
67821
|
+
if (component === undefined)
|
|
67822
|
+
return false;
|
|
67823
|
+
let percent = component.indexOf("%");
|
|
67824
|
+
while (percent !== -1) {
|
|
67825
|
+
if (percent + 2 >= component.length || !/^[\da-f]{2}$/iu.test(component.slice(percent + 1, percent + 3))) {
|
|
67826
|
+
return true;
|
|
67827
|
+
}
|
|
67828
|
+
percent = component.indexOf("%", percent + 3);
|
|
67829
|
+
}
|
|
67830
|
+
return false;
|
|
67831
|
+
}
|
|
67832
|
+
function isIPLiteral(host) {
|
|
67833
|
+
return host[0] === "[" && host[host.length - 1] === "]";
|
|
67834
|
+
}
|
|
67835
|
+
function hasMalformedComponentPercentEncoding(matches) {
|
|
67836
|
+
const host = matches[4];
|
|
67837
|
+
return hasMalformedPercentEncoding(matches[3]) || host !== undefined && !isIPLiteral(host) && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
|
|
67838
|
+
}
|
|
67839
|
+
function canonicalizeHost(parsed, options, schemeHandler, isIP) {
|
|
67840
|
+
if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && !isIPLiteral(parsed.host) && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
|
|
67841
|
+
try {
|
|
67842
|
+
parsed.host = new URL("http://" + parsed.host).hostname;
|
|
67843
|
+
} catch (e) {
|
|
67844
|
+
parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
|
|
67845
|
+
return true;
|
|
67846
|
+
}
|
|
67847
|
+
}
|
|
67848
|
+
return false;
|
|
67849
|
+
}
|
|
67507
67850
|
function parseWithStatus(uri, opts) {
|
|
67508
67851
|
const options = Object.assign({}, opts);
|
|
67509
67852
|
const parsed = {
|
|
@@ -67516,6 +67859,11 @@ var require_fast_uri = __commonJS(function(exports, module) {
|
|
|
67516
67859
|
fragment: undefined
|
|
67517
67860
|
};
|
|
67518
67861
|
let malformedAuthorityOrPort = false;
|
|
67862
|
+
let malformedPercentEncoding = false;
|
|
67863
|
+
let malformedSchemeSpecific = false;
|
|
67864
|
+
let malformedHost = false;
|
|
67865
|
+
let malformedIPLiteral = false;
|
|
67866
|
+
let malformedScheme = false;
|
|
67519
67867
|
let isIP = false;
|
|
67520
67868
|
if (options.reference === "suffix") {
|
|
67521
67869
|
if (options.scheme) {
|
|
@@ -67552,6 +67900,19 @@ var require_fast_uri = __commonJS(function(exports, module) {
|
|
|
67552
67900
|
parsed.path = matches[6] || "";
|
|
67553
67901
|
parsed.query = matches[7];
|
|
67554
67902
|
parsed.fragment = matches[8];
|
|
67903
|
+
if (parsed.scheme !== undefined) {
|
|
67904
|
+
const decodedScheme = unescape(parsed.scheme);
|
|
67905
|
+
if (VALID_SCHEME.test(decodedScheme)) {
|
|
67906
|
+
parsed.scheme = decodedScheme.toLowerCase();
|
|
67907
|
+
} else {
|
|
67908
|
+
parsed.error = parsed.error || MALFORMED_SCHEME_ERROR;
|
|
67909
|
+
malformedScheme = true;
|
|
67910
|
+
}
|
|
67911
|
+
}
|
|
67912
|
+
malformedPercentEncoding = hasMalformedComponentPercentEncoding(matches);
|
|
67913
|
+
if (malformedPercentEncoding) {
|
|
67914
|
+
parsed.error = parsed.error || "URI contains malformed percent-encoding.";
|
|
67915
|
+
}
|
|
67555
67916
|
if (isNaN(parsed.port)) {
|
|
67556
67917
|
parsed.port = matches[5];
|
|
67557
67918
|
}
|
|
@@ -67563,9 +67924,16 @@ var require_fast_uri = __commonJS(function(exports, module) {
|
|
|
67563
67924
|
if (parsed.host) {
|
|
67564
67925
|
const ipv4result = isIPv4(parsed.host);
|
|
67565
67926
|
if (ipv4result === false) {
|
|
67927
|
+
const bracketedIPLiteral = isIPLiteral(parsed.host);
|
|
67928
|
+
const hasIPLiteralBracket = parsed.host.indexOf("[") !== -1 || parsed.host.indexOf("]") !== -1;
|
|
67566
67929
|
const ipv6result = normalizeIPv6(parsed.host);
|
|
67567
|
-
|
|
67568
|
-
|
|
67930
|
+
isIP = ipv6result.isIPV6 || ipv6result.isIPVFuture === true;
|
|
67931
|
+
malformedIPLiteral = hasIPLiteralBracket && (!bracketedIPLiteral || ipv6result.error === true);
|
|
67932
|
+
parsed.host = isIP ? ipv6result.host : ipv6result.host.toLowerCase();
|
|
67933
|
+
if (malformedIPLiteral) {
|
|
67934
|
+
parsed.error = parsed.error || "URI host is malformed.";
|
|
67935
|
+
malformedAuthorityOrPort = true;
|
|
67936
|
+
}
|
|
67569
67937
|
} else {
|
|
67570
67938
|
isIP = true;
|
|
67571
67939
|
}
|
|
@@ -67583,42 +67951,36 @@ var require_fast_uri = __commonJS(function(exports, module) {
|
|
|
67583
67951
|
parsed.error = parsed.error || "URI is not a " + options.reference + " reference.";
|
|
67584
67952
|
}
|
|
67585
67953
|
const schemeHandler = getSchemeHandler(options.scheme || parsed.scheme);
|
|
67586
|
-
if (!
|
|
67587
|
-
|
|
67588
|
-
try {
|
|
67589
|
-
parsed.host = new URL("http://" + parsed.host).hostname;
|
|
67590
|
-
} catch (e) {
|
|
67591
|
-
parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
|
|
67592
|
-
}
|
|
67593
|
-
}
|
|
67954
|
+
if (!malformedIPLiteral) {
|
|
67955
|
+
malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP);
|
|
67594
67956
|
}
|
|
67595
67957
|
if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
|
|
67596
67958
|
if (uri.indexOf("%") !== -1) {
|
|
67597
|
-
if (parsed.
|
|
67598
|
-
parsed.
|
|
67599
|
-
|
|
67600
|
-
if (parsed.host !== undefined) {
|
|
67601
|
-
parsed.host = reescapeHostDelimiters(unescape(parsed.host), isIP);
|
|
67959
|
+
if (parsed.host !== undefined && !malformedIPLiteral) {
|
|
67960
|
+
const host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
|
|
67961
|
+
parsed.host = reescapeHostDelimiters(host, isIP);
|
|
67602
67962
|
}
|
|
67603
67963
|
}
|
|
67604
67964
|
if (parsed.path) {
|
|
67605
67965
|
parsed.path = normalizePathEncoding(parsed.path);
|
|
67606
67966
|
}
|
|
67967
|
+
if (parsed.query) {
|
|
67968
|
+
parsed.query = normalizeQueryFragmentEncoding(parsed.query);
|
|
67969
|
+
}
|
|
67607
67970
|
if (parsed.fragment) {
|
|
67608
|
-
|
|
67609
|
-
parsed.fragment = encodeURI(decodeURIComponent(parsed.fragment));
|
|
67610
|
-
} catch {
|
|
67611
|
-
parsed.error = parsed.error || "URI malformed";
|
|
67612
|
-
}
|
|
67971
|
+
parsed.fragment = normalizeQueryFragmentEncoding(parsed.fragment);
|
|
67613
67972
|
}
|
|
67614
67973
|
}
|
|
67615
67974
|
if (schemeHandler && schemeHandler.parse) {
|
|
67616
67975
|
schemeHandler.parse(parsed, options);
|
|
67976
|
+
if (schemeHandler === SCHEMES.urn && parsed.nid === undefined) {
|
|
67977
|
+
malformedSchemeSpecific = true;
|
|
67978
|
+
}
|
|
67617
67979
|
}
|
|
67618
67980
|
} else {
|
|
67619
67981
|
parsed.error = parsed.error || "URI can not be parsed.";
|
|
67620
67982
|
}
|
|
67621
|
-
return { parsed, malformedAuthorityOrPort };
|
|
67983
|
+
return { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme };
|
|
67622
67984
|
}
|
|
67623
67985
|
function parse8(uri, opts) {
|
|
67624
67986
|
return parseWithStatus(uri, opts).parsed;
|
|
@@ -67627,20 +67989,28 @@ var require_fast_uri = __commonJS(function(exports, module) {
|
|
|
67627
67989
|
return normalizeStringWithStatus(uri, opts).normalized;
|
|
67628
67990
|
}
|
|
67629
67991
|
function normalizeStringWithStatus(uri, opts) {
|
|
67630
|
-
const { parsed, malformedAuthorityOrPort } = parseWithStatus(uri, opts);
|
|
67992
|
+
const { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = parseWithStatus(uri, opts);
|
|
67631
67993
|
return {
|
|
67632
|
-
normalized: malformedAuthorityOrPort ? uri : serialize(parsed, opts),
|
|
67633
|
-
malformedAuthorityOrPort
|
|
67994
|
+
normalized: malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? uri : serialize(parsed, opts),
|
|
67995
|
+
malformedAuthorityOrPort,
|
|
67996
|
+
malformedPercentEncoding,
|
|
67997
|
+
malformedSchemeSpecific,
|
|
67998
|
+
malformedHost,
|
|
67999
|
+
malformedScheme
|
|
67634
68000
|
};
|
|
67635
68001
|
}
|
|
67636
68002
|
function normalizeComparableURI(uri, opts) {
|
|
67637
|
-
if (typeof uri
|
|
67638
|
-
|
|
67639
|
-
return malformedAuthorityOrPort ? undefined : normalized;
|
|
68003
|
+
if (typeof uri !== "string" && typeof uri !== "object") {
|
|
68004
|
+
return;
|
|
67640
68005
|
}
|
|
67641
|
-
|
|
67642
|
-
|
|
68006
|
+
let value;
|
|
68007
|
+
try {
|
|
68008
|
+
value = typeof uri === "string" ? uri : serialize(uri, opts);
|
|
68009
|
+
} catch {
|
|
68010
|
+
return;
|
|
67643
68011
|
}
|
|
68012
|
+
const { normalized, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme } = normalizeStringWithStatus(value, opts);
|
|
68013
|
+
return malformedAuthorityOrPort || malformedPercentEncoding || malformedSchemeSpecific || malformedHost || malformedScheme ? undefined : normalized;
|
|
67644
68014
|
}
|
|
67645
68015
|
var fastUri = {
|
|
67646
68016
|
SCHEMES,
|
|
@@ -73587,6 +73957,7 @@ Proceed with deployment to Supabase?`, true);
|
|
|
73587
73957
|
▶ Deploying ${efNames.length} Edge Function(s)…`));
|
|
73588
73958
|
let efOk = 0;
|
|
73589
73959
|
const efFailed = [];
|
|
73960
|
+
const efOutput = [];
|
|
73590
73961
|
for (const ef of efNames) {
|
|
73591
73962
|
info(` deploying ${ef}…`);
|
|
73592
73963
|
const workdir = assets.functionsDir.replace(/\/functions$/, "").replace(/\/supabase$/, "");
|
|
@@ -73599,19 +73970,40 @@ Proceed with deployment to Supabase?`, true);
|
|
|
73599
73970
|
}
|
|
73600
73971
|
const r = spawnSync2("npx", args, {
|
|
73601
73972
|
encoding: "utf8",
|
|
73602
|
-
stdio: "inherit",
|
|
73973
|
+
stdio: ["inherit", "pipe", "pipe"],
|
|
73603
73974
|
cwd: workdir,
|
|
73604
73975
|
timeout: 120000
|
|
73605
73976
|
});
|
|
73977
|
+
if (r.stdout)
|
|
73978
|
+
process.stdout.write(r.stdout);
|
|
73979
|
+
if (r.stderr)
|
|
73980
|
+
process.stderr.write(r.stderr);
|
|
73606
73981
|
if (r.status === 0)
|
|
73607
73982
|
efOk++;
|
|
73608
|
-
else
|
|
73983
|
+
else {
|
|
73609
73984
|
efFailed.push(ef);
|
|
73985
|
+
efOutput.push(`${r.stdout ?? ""}
|
|
73986
|
+
${r.stderr ?? ""}`);
|
|
73987
|
+
}
|
|
73610
73988
|
}
|
|
73611
73989
|
if (efFailed.length > 0) {
|
|
73612
73990
|
eprintln(c.red(`
|
|
73613
73991
|
✗ ${efFailed.length} Edge Function(s) failed: ${efFailed.join(", ")}`));
|
|
73614
|
-
|
|
73992
|
+
if (upstreamRegistryRace(efOutput.join(`
|
|
73993
|
+
`))) {
|
|
73994
|
+
eprintln("");
|
|
73995
|
+
eprintln(c.yellow(" This looks like an UPSTREAM package-registry race, not a problem"));
|
|
73996
|
+
eprintln(c.yellow(" with your Cerefox install:"));
|
|
73997
|
+
eprintln(c.dim(" The Edge Functions import `jsr:@supabase/supabase-js@2`. When Supabase"));
|
|
73998
|
+
eprintln(c.dim(" publishes a new version, JSR and npm do not land at the same instant;"));
|
|
73999
|
+
eprintln(c.dim(" a deploy in that gap resolves a JSR package whose npm dependency is not"));
|
|
74000
|
+
eprintln(c.dim(" published yet, and bundling fails."));
|
|
74001
|
+
eprintln(c.dim(" Your deployed functions were NOT changed — the previous version is"));
|
|
74002
|
+
eprintln(c.dim(" still serving, so nothing is down."));
|
|
74003
|
+
eprintln(c.cyan(" → Wait a few minutes, then re-run: cerefox server deploy --functions-only"));
|
|
74004
|
+
} else {
|
|
74005
|
+
eprintln(c.dim(" Re-run `cerefox server deploy --functions-only` after fixing the cause."));
|
|
74006
|
+
}
|
|
73615
74007
|
process.exit(1);
|
|
73616
74008
|
}
|
|
73617
74009
|
println(c.green(` ✓ Deployed ${efOk} Edge Function(s).`));
|
|
@@ -73639,6 +74031,9 @@ Proceed with deployment to Supabase?`, true);
|
|
|
73639
74031
|
println(c.dim("Verify with: cerefox doctor"));
|
|
73640
74032
|
println(c.dim("Refresh the bundled guides: cerefox guides ingest"));
|
|
73641
74033
|
}
|
|
74034
|
+
function upstreamRegistryRace(output) {
|
|
74035
|
+
return /Failed to bundle the function/i.test(output) && /Could not find npm package/i.test(output);
|
|
74036
|
+
}
|
|
73642
74037
|
function registerDeployServer(program2) {
|
|
73643
74038
|
program2.command("deploy-server").description("Deploy/update the Cerefox server side (schema + RPCs + Edge Functions) on Supabase.").option("--dry-run", "Print the plan + pre-flight without deploying.").option("--schema-only", "Deploy/update only the schema + RPCs (skip Edge Functions).").option("--functions-only", "Deploy only the Edge Functions (skip the schema/RPCs).").option("--project-ref <ref>", "Supabase project ref for Edge Function deploys (default: derived from CEREFOX_SUPABASE_URL).").option("--yes", "Non-interactive (skip the deployment confirmation).").action(action10);
|
|
73644
74039
|
}
|
|
@@ -77982,21 +78377,22 @@ function checkMcpConfigs() {
|
|
|
77982
78377
|
detail: found.join(", ")
|
|
77983
78378
|
};
|
|
77984
78379
|
}
|
|
77985
|
-
function checkLegacyShadowEnv() {
|
|
77986
|
-
const
|
|
77987
|
-
const
|
|
77988
|
-
|
|
77989
|
-
if (!existsSync10(homeEnv) || !existsSync10(cwdEnv))
|
|
78380
|
+
function checkLegacyShadowEnv(opts = {}) {
|
|
78381
|
+
const activeEnv = resolveEnvFile(opts);
|
|
78382
|
+
const cwdEnv = join9(opts.cwd ?? process.cwd(), ".env");
|
|
78383
|
+
if (!existsSync10(activeEnv) || !existsSync10(cwdEnv))
|
|
77990
78384
|
return null;
|
|
77991
78385
|
try {
|
|
77992
|
-
if (realpathSync(
|
|
78386
|
+
if (realpathSync(activeEnv) === realpathSync(cwdEnv))
|
|
77993
78387
|
return null;
|
|
77994
78388
|
} catch {}
|
|
78389
|
+
if (!envFileHasCerefoxKey(cwdEnv))
|
|
78390
|
+
return null;
|
|
77995
78391
|
return {
|
|
77996
78392
|
name: "legacy env",
|
|
77997
78393
|
status: "skipped",
|
|
77998
|
-
detail: `${cwdEnv} (shadowed by
|
|
77999
|
-
hint:
|
|
78394
|
+
detail: `${cwdEnv} (shadowed by ${activeEnv})`,
|
|
78395
|
+
hint: `Shadowed by ${activeEnv} and no longer read by anything (Python was removed at v1.0.0). Safe to delete.`
|
|
78000
78396
|
};
|
|
78001
78397
|
}
|
|
78002
78398
|
async function checkPostgres() {
|
|
@@ -80929,11 +81325,10 @@ function registerStatus(program2) {
|
|
|
80929
81325
|
program2.command("status").description("Quick sanity check (fast subset of `cerefox doctor`).").option("--json", "Emit machine-readable JSON.").action(action34);
|
|
80930
81326
|
}
|
|
80931
81327
|
|
|
80932
|
-
// src/cli/commands/
|
|
81328
|
+
// src/cli/commands/api-key.ts
|
|
80933
81329
|
init_cli_core();
|
|
80934
81330
|
init_config();
|
|
80935
81331
|
import { randomBytes } from "node:crypto";
|
|
80936
|
-
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
80937
81332
|
|
|
80938
81333
|
// src/cli/util/env-file.ts
|
|
80939
81334
|
import { copyFileSync as copyFileSync3, existsSync as existsSync14, readFileSync as readFileSync15, writeFileSync as writeFileSync5 } from "node:fs";
|
|
@@ -80998,14 +81393,214 @@ function envGitignoreWarning(path) {
|
|
|
80998
81393
|
}
|
|
80999
81394
|
}
|
|
81000
81395
|
|
|
81396
|
+
// ../../node_modules/.bun/@hono+node-server@2.0.12+19b9adbcbc3b652f/node_modules/@hono/node-server/dist/conninfo.mjs
|
|
81397
|
+
var getConnInfo = (c2) => {
|
|
81398
|
+
const bindings = c2.env.server ? c2.env.server : c2.env;
|
|
81399
|
+
const address = bindings.incoming.socket.remoteAddress;
|
|
81400
|
+
const port = bindings.incoming.socket.remotePort;
|
|
81401
|
+
const family = bindings.incoming.socket.remoteFamily;
|
|
81402
|
+
return { remote: {
|
|
81403
|
+
address,
|
|
81404
|
+
port,
|
|
81405
|
+
addressType: family === "IPv4" ? "IPv4" : family === "IPv6" ? "IPv6" : undefined
|
|
81406
|
+
} };
|
|
81407
|
+
};
|
|
81408
|
+
|
|
81409
|
+
// ../../_shared/mcp-auth/index.ts
|
|
81410
|
+
function constantTimeEqual(a, b2) {
|
|
81411
|
+
const ab = new TextEncoder().encode(a);
|
|
81412
|
+
const bb = new TextEncoder().encode(b2);
|
|
81413
|
+
const len = Math.max(ab.length, bb.length);
|
|
81414
|
+
let diff = ab.length ^ bb.length;
|
|
81415
|
+
for (let i = 0;i < len; i++) {
|
|
81416
|
+
diff |= (ab[i] ?? 0) ^ (bb[i] ?? 0);
|
|
81417
|
+
}
|
|
81418
|
+
return diff === 0;
|
|
81419
|
+
}
|
|
81420
|
+
|
|
81421
|
+
// ../../_shared/ef-auth/index.ts
|
|
81422
|
+
function parseAccessTokens(raw) {
|
|
81423
|
+
if (!raw)
|
|
81424
|
+
return [];
|
|
81425
|
+
return raw.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
|
|
81426
|
+
}
|
|
81427
|
+
var BEARER_PREFIX = "Bearer ";
|
|
81428
|
+
function checkAccessToken(authorizationHeader, config2) {
|
|
81429
|
+
if (!authorizationHeader || !authorizationHeader.startsWith(BEARER_PREFIX)) {
|
|
81430
|
+
return { ok: false, reason: "no_token" };
|
|
81431
|
+
}
|
|
81432
|
+
const token = authorizationHeader.slice(BEARER_PREFIX.length).trim();
|
|
81433
|
+
if (!token)
|
|
81434
|
+
return { ok: false, reason: "no_token" };
|
|
81435
|
+
if (config2.tokens.length === 0) {
|
|
81436
|
+
return {
|
|
81437
|
+
ok: false,
|
|
81438
|
+
reason: "no_tokens_configured",
|
|
81439
|
+
detail: "CEREFOX_ACCESS_TOKENS is unset/empty; refusing to accept-all"
|
|
81440
|
+
};
|
|
81441
|
+
}
|
|
81442
|
+
let matched = false;
|
|
81443
|
+
for (const accepted of config2.tokens) {
|
|
81444
|
+
if (constantTimeEqual(token, accepted))
|
|
81445
|
+
matched = true;
|
|
81446
|
+
}
|
|
81447
|
+
return matched ? { ok: true } : { ok: false, reason: "bad_token" };
|
|
81448
|
+
}
|
|
81449
|
+
|
|
81450
|
+
// src/web/auth.ts
|
|
81451
|
+
var API_KEY_PREFIX = "cfx_lak_";
|
|
81452
|
+
var LOOPBACK_ADDRESSES = new Set([
|
|
81453
|
+
"127.0.0.1",
|
|
81454
|
+
"::1",
|
|
81455
|
+
"::ffff:127.0.0.1"
|
|
81456
|
+
]);
|
|
81457
|
+
function isLoopbackAddress(address) {
|
|
81458
|
+
if (!address)
|
|
81459
|
+
return false;
|
|
81460
|
+
return LOOPBACK_ADDRESSES.has(address.trim().toLowerCase());
|
|
81461
|
+
}
|
|
81462
|
+
function decideAuth(input) {
|
|
81463
|
+
const keys = input.configuredKeys.trim();
|
|
81464
|
+
if (!keys)
|
|
81465
|
+
return { allow: true, reason: "disabled" };
|
|
81466
|
+
const local = isLoopbackAddress(input.remoteAddress);
|
|
81467
|
+
if (local && !input.requireKeyEverywhere) {
|
|
81468
|
+
return { allow: true, reason: "loopback" };
|
|
81469
|
+
}
|
|
81470
|
+
const result = checkAccessToken(input.authorization, {
|
|
81471
|
+
tokens: parseAccessTokens(keys)
|
|
81472
|
+
});
|
|
81473
|
+
if (result.ok)
|
|
81474
|
+
return { allow: true, reason: "valid_key" };
|
|
81475
|
+
if (result.reason === "no_token") {
|
|
81476
|
+
return {
|
|
81477
|
+
allow: false,
|
|
81478
|
+
reason: "no_key",
|
|
81479
|
+
message: local ? "This server requires an API key on every request (CEREFOX_API_REQUIRE_KEY is set). " + "Send it as `Authorization: Bearer <key>`." : "This request did not come from the local machine, so it needs the server's API key " + "as `Authorization: Bearer <key>`. Print it with `cerefox api-key show` " + "(or `cerefox-local api-key` for a container install)."
|
|
81480
|
+
};
|
|
81481
|
+
}
|
|
81482
|
+
return {
|
|
81483
|
+
allow: false,
|
|
81484
|
+
reason: "bad_key",
|
|
81485
|
+
message: "The API key presented is not valid for this server."
|
|
81486
|
+
};
|
|
81487
|
+
}
|
|
81488
|
+
function apiAuth() {
|
|
81489
|
+
return async (c2, next) => {
|
|
81490
|
+
const decision = decideAuth({
|
|
81491
|
+
remoteAddress: remoteAddressOf(c2),
|
|
81492
|
+
authorization: c2.req.header("Authorization") ?? null,
|
|
81493
|
+
configuredKeys: process.env.CEREFOX_API_KEY ?? "",
|
|
81494
|
+
requireKeyEverywhere: (process.env.CEREFOX_API_REQUIRE_KEY ?? "") === "1"
|
|
81495
|
+
});
|
|
81496
|
+
if (decision.allow)
|
|
81497
|
+
return next();
|
|
81498
|
+
return c2.json({ detail: decision.message }, 401, {
|
|
81499
|
+
"WWW-Authenticate": 'Bearer realm="cerefox"'
|
|
81500
|
+
});
|
|
81501
|
+
};
|
|
81502
|
+
}
|
|
81503
|
+
function remoteAddressOf(c2) {
|
|
81504
|
+
try {
|
|
81505
|
+
return getConnInfo(c2).remote.address;
|
|
81506
|
+
} catch {
|
|
81507
|
+
return;
|
|
81508
|
+
}
|
|
81509
|
+
}
|
|
81510
|
+
|
|
81511
|
+
// src/cli/commands/api-key.ts
|
|
81512
|
+
var ENV_NAME = "CEREFOX_API_KEY";
|
|
81513
|
+
function mint() {
|
|
81514
|
+
return API_KEY_PREFIX + randomBytes(32).toString("base64url");
|
|
81515
|
+
}
|
|
81516
|
+
function mask(key) {
|
|
81517
|
+
const body = key.startsWith(API_KEY_PREFIX) ? key.slice(API_KEY_PREFIX.length) : key;
|
|
81518
|
+
if (body.length <= 8)
|
|
81519
|
+
return `${API_KEY_PREFIX}****`;
|
|
81520
|
+
return `${API_KEY_PREFIX}${body.slice(0, 4)}…${body.slice(-4)}`;
|
|
81521
|
+
}
|
|
81522
|
+
function containerHint() {
|
|
81523
|
+
eprintln(c.dim(` Running Cerefox Local (Docker)? This is not the command you want — the
|
|
81524
|
+
` + " container mints its own key at boot. Read it with: cerefox-local api-key"));
|
|
81525
|
+
}
|
|
81526
|
+
function writeKey(key, opts, verb) {
|
|
81527
|
+
const envPath = resolveEnvFile();
|
|
81528
|
+
if (opts.dryRun) {
|
|
81529
|
+
println(c.dim(`DRY-RUN: would ${verb} ${ENV_NAME} in ${envPath}`));
|
|
81530
|
+
return;
|
|
81531
|
+
}
|
|
81532
|
+
const result = upsertEnvVar(envPath, ENV_NAME, key, {
|
|
81533
|
+
noBackup: !opts.backup,
|
|
81534
|
+
comment: "Local API key for /api/v1 + /rest/v1 (cerefox api-key). Never sent to Supabase."
|
|
81535
|
+
});
|
|
81536
|
+
println(` ${result.action} ${c.bold(ENV_NAME)} in ${envPath}`);
|
|
81537
|
+
if (result.backupPath)
|
|
81538
|
+
println(c.dim(` backup: ${result.backupPath}`));
|
|
81539
|
+
println("");
|
|
81540
|
+
println(c.bold(" Your API key (shown once, in full):"));
|
|
81541
|
+
println(` ${c.green(key)}`);
|
|
81542
|
+
println("");
|
|
81543
|
+
println(c.dim(` A caller that is NOT on this machine sends it as:
|
|
81544
|
+
` + ` Authorization: Bearer <key>
|
|
81545
|
+
` + " Callers on this machine (the web UI, local agents) need nothing."));
|
|
81546
|
+
envGitignoreWarning(envPath);
|
|
81547
|
+
}
|
|
81548
|
+
function generateAction(opts) {
|
|
81549
|
+
const envPath = resolveEnvFile();
|
|
81550
|
+
const existing = readEnvVar(envPath, ENV_NAME);
|
|
81551
|
+
if (existing) {
|
|
81552
|
+
throw userError(`${ENV_NAME} is already set in ${envPath} (${mask(existing)}).`, "Use `cerefox api-key show` to see it, or `cerefox api-key rotate` to replace it. " + "Refusing to overwrite silently: any client already configured with the old key " + "would start getting 401s with no indication why.");
|
|
81553
|
+
}
|
|
81554
|
+
println(c.bold("Minting a local API key"));
|
|
81555
|
+
writeKey(mint(), opts, "write");
|
|
81556
|
+
containerHint();
|
|
81557
|
+
}
|
|
81558
|
+
function rotateAction(opts) {
|
|
81559
|
+
const envPath = resolveEnvFile();
|
|
81560
|
+
const existing = readEnvVar(envPath, ENV_NAME);
|
|
81561
|
+
if (!existing) {
|
|
81562
|
+
throw userError(`No ${ENV_NAME} in ${envPath} — nothing to rotate.`, "Run `cerefox api-key generate` first.");
|
|
81563
|
+
}
|
|
81564
|
+
println(c.bold("Rotating the local API key"));
|
|
81565
|
+
println(c.dim(` replacing ${mask(existing)}`));
|
|
81566
|
+
writeKey(mint(), opts, "replace");
|
|
81567
|
+
println(c.yellow(` The previous key stops working as soon as the server restarts.
|
|
81568
|
+
` + " Update every remote client, then: cerefox web restart"));
|
|
81569
|
+
}
|
|
81570
|
+
function showAction2() {
|
|
81571
|
+
const envPath = resolveEnvFile();
|
|
81572
|
+
const key = readEnvVar(envPath, ENV_NAME);
|
|
81573
|
+
println(c.bold("Local API key"));
|
|
81574
|
+
if (!key) {
|
|
81575
|
+
println(c.dim(` none set in ${envPath}`));
|
|
81576
|
+
println(c.dim(` The server is not gated: callers from any interface it is bound to can
|
|
81577
|
+
` + ` reach it without a credential. That is fine while it binds 127.0.0.1.
|
|
81578
|
+
` + " Mint one with: cerefox api-key generate"));
|
|
81579
|
+
containerHint();
|
|
81580
|
+
return;
|
|
81581
|
+
}
|
|
81582
|
+
println(` ${c.green(key)} ${c.dim(`(${ENV_NAME} in ${envPath})`)}`);
|
|
81583
|
+
println(c.dim(" Remote callers send: Authorization: Bearer <key>"));
|
|
81584
|
+
}
|
|
81585
|
+
function registerApiKey(program2) {
|
|
81586
|
+
const group = program2.command("api-key").description("Manage the local API key for /api/v1 (loopback callers need none).");
|
|
81587
|
+
group.command("generate").description("Mint a local API key and write it to .env. Refuses if one exists.").option("--no-backup", "Skip the .pre-cerefox.bak backup of an existing .env.").option("--dry-run", "Print the plan without minting or writing anything.").action(generateAction);
|
|
81588
|
+
group.command("rotate").description("Replace the existing key. Remote clients must be updated.").option("--no-backup", "Skip the .pre-cerefox.bak backup of an existing .env.").option("--dry-run", "Print the plan without minting or writing anything.").action(rotateAction);
|
|
81589
|
+
group.command("show").description("Print the local API key, in full, for pasting into a client.").action(showAction2);
|
|
81590
|
+
}
|
|
81591
|
+
|
|
81001
81592
|
// src/cli/commands/token.ts
|
|
81593
|
+
init_cli_core();
|
|
81594
|
+
init_config();
|
|
81595
|
+
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
81596
|
+
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
81002
81597
|
var SECRET_NAME = "CEREFOX_ACCESS_TOKENS";
|
|
81003
81598
|
var LOCAL_NAME = "CEREFOX_ACCESS_TOKEN";
|
|
81004
81599
|
var PREFIX = "cfx_pat_";
|
|
81005
81600
|
function mintToken() {
|
|
81006
|
-
return PREFIX +
|
|
81601
|
+
return PREFIX + randomBytes2(32).toString("base64url");
|
|
81007
81602
|
}
|
|
81008
|
-
function
|
|
81603
|
+
function mask2(token) {
|
|
81009
81604
|
return token.length <= 16 ? "…" : `${token.slice(0, PREFIX.length + 4)}…${token.slice(-4)}`;
|
|
81010
81605
|
}
|
|
81011
81606
|
function parseProjectRef2(supabaseUrl) {
|
|
@@ -81023,7 +81618,7 @@ function setSecret(setValue, projectRef, dryRun) {
|
|
|
81023
81618
|
if (projectRef)
|
|
81024
81619
|
args.push("--project-ref", projectRef);
|
|
81025
81620
|
if (dryRun) {
|
|
81026
|
-
const shown = setValue.split(",").map(
|
|
81621
|
+
const shown = setValue.split(",").map(mask2).join(",");
|
|
81027
81622
|
println(c.dim(` (dry-run) npx supabase secrets set ${SECRET_NAME}=${shown}` + (projectRef ? ` --project-ref ${projectRef}` : "")));
|
|
81028
81623
|
return;
|
|
81029
81624
|
}
|
|
@@ -81063,7 +81658,7 @@ function printTokenOnce(token) {
|
|
|
81063
81658
|
println(c.dim(" If the GPT Actions schema changed this release, re-paste it too"));
|
|
81064
81659
|
println(c.dim(" (see docs/guides/connect-agents.md). Lose the token → `cerefox token rotate`."));
|
|
81065
81660
|
}
|
|
81066
|
-
function
|
|
81661
|
+
function generateAction2(opts) {
|
|
81067
81662
|
const projectRef = opts.projectRef ?? parseProjectRef2(loadSettings().supabaseUrl);
|
|
81068
81663
|
const token = mintToken();
|
|
81069
81664
|
println(c.bold("Generating a Cerefox access token…"));
|
|
@@ -81072,7 +81667,7 @@ function generateAction(opts) {
|
|
|
81072
81667
|
if (!opts.dryRun)
|
|
81073
81668
|
printTokenOnce(token);
|
|
81074
81669
|
}
|
|
81075
|
-
function
|
|
81670
|
+
function rotateAction2(opts) {
|
|
81076
81671
|
const projectRef = opts.projectRef ?? parseProjectRef2(loadSettings().supabaseUrl);
|
|
81077
81672
|
const envPath = resolveEnvFile();
|
|
81078
81673
|
const current = readEnvVar(envPath, LOCAL_NAME);
|
|
@@ -81102,14 +81697,14 @@ function listAction2() {
|
|
|
81102
81697
|
const envPath = resolveEnvFile();
|
|
81103
81698
|
const local = readEnvVar(envPath, LOCAL_NAME);
|
|
81104
81699
|
println(c.bold("Cerefox access token"));
|
|
81105
|
-
println(local ? ` local (${LOCAL_NAME} in ${envPath}): ${c.green(
|
|
81700
|
+
println(local ? ` local (${LOCAL_NAME} in ${envPath}): ${c.green(mask2(local))}` : c.dim(` no ${LOCAL_NAME} in ${envPath} — run \`cerefox token generate\``));
|
|
81106
81701
|
println(c.dim(` The server-side accepted set (${SECRET_NAME}) is write-only; list names/digests
|
|
81107
81702
|
` + " with: npx supabase secrets list"));
|
|
81108
81703
|
}
|
|
81109
81704
|
function registerToken(program2) {
|
|
81110
81705
|
const token = program2.command("token").description("Manage the Cerefox Edge Function access token(s).");
|
|
81111
|
-
token.command("generate").description("Mint a token, set the Supabase secret, and write it to .env.").option("--project-ref <ref>", "Supabase project ref (default: derived from CEREFOX_SUPABASE_URL).").option("--no-env", "Do not write CEREFOX_ACCESS_TOKEN to .env.").option("--no-backup", "Skip the .pre-cerefox.bak backup of an existing .env.").option("--dry-run", "Print the plan without minting or writing anything.").action(
|
|
81112
|
-
token.command("rotate").description("Mint a new token accepted alongside the old (zero-downtime); --finalize drops the old.").option("--finalize", "Stop accepting the previous token (run after clients migrate).").option("--project-ref <ref>", "Supabase project ref (default: derived from CEREFOX_SUPABASE_URL).").option("--no-env", "Do not write CEREFOX_ACCESS_TOKEN to .env.").option("--no-backup", "Skip the .pre-cerefox.bak backup of an existing .env.").option("--dry-run", "Print the plan without minting or writing anything.").action(
|
|
81706
|
+
token.command("generate").description("Mint a token, set the Supabase secret, and write it to .env.").option("--project-ref <ref>", "Supabase project ref (default: derived from CEREFOX_SUPABASE_URL).").option("--no-env", "Do not write CEREFOX_ACCESS_TOKEN to .env.").option("--no-backup", "Skip the .pre-cerefox.bak backup of an existing .env.").option("--dry-run", "Print the plan without minting or writing anything.").action(generateAction2);
|
|
81707
|
+
token.command("rotate").description("Mint a new token accepted alongside the old (zero-downtime); --finalize drops the old.").option("--finalize", "Stop accepting the previous token (run after clients migrate).").option("--project-ref <ref>", "Supabase project ref (default: derived from CEREFOX_SUPABASE_URL).").option("--no-env", "Do not write CEREFOX_ACCESS_TOKEN to .env.").option("--no-backup", "Skip the .pre-cerefox.bak backup of an existing .env.").option("--dry-run", "Print the plan without minting or writing anything.").action(rotateAction2);
|
|
81113
81708
|
token.command("list").description("Show the local token (masked) and where the server-side set lives.").action(listAction2);
|
|
81114
81709
|
}
|
|
81115
81710
|
|
|
@@ -84457,7 +85052,7 @@ var CONFIG_CATALOG = [
|
|
|
84457
85052
|
},
|
|
84458
85053
|
{
|
|
84459
85054
|
key: "require_requestor_identity",
|
|
84460
|
-
description: "Require a requestor/author on MCP
|
|
85055
|
+
description: "Require a requestor/author. Enforced on the Edge Functions (incl. remote MCP) ONLY — not local MCP, /api/v1 or the CLI.",
|
|
84461
85056
|
kind: "boolean",
|
|
84462
85057
|
defaultValue: "false",
|
|
84463
85058
|
group: "Governance",
|
|
@@ -84569,6 +85164,78 @@ function validateConfigValue(key, value) {
|
|
|
84569
85164
|
|
|
84570
85165
|
// src/web/routes/config.ts
|
|
84571
85166
|
init_config();
|
|
85167
|
+
|
|
85168
|
+
// src/web/identity.ts
|
|
85169
|
+
var DEFAULT_WEB_AUTHOR = "web-ui";
|
|
85170
|
+
var DEFAULT_WEB_AUTHOR_TYPE = "user";
|
|
85171
|
+
var WEB_UI_IDENTITY = {
|
|
85172
|
+
author: DEFAULT_WEB_AUTHOR,
|
|
85173
|
+
authorType: DEFAULT_WEB_AUTHOR_TYPE,
|
|
85174
|
+
requestor: DEFAULT_WEB_AUTHOR,
|
|
85175
|
+
accessPath: "webapp",
|
|
85176
|
+
named: false
|
|
85177
|
+
};
|
|
85178
|
+
var HEADER = {
|
|
85179
|
+
author: "x-cerefox-author",
|
|
85180
|
+
authorType: "x-cerefox-author-type",
|
|
85181
|
+
requestor: "x-cerefox-requestor"
|
|
85182
|
+
};
|
|
85183
|
+
function readField(c2, headerName, body, bodyKey) {
|
|
85184
|
+
const header = c2.req.header(headerName);
|
|
85185
|
+
if (header !== undefined) {
|
|
85186
|
+
if (header.trim() === "") {
|
|
85187
|
+
return { ok: false, detail: `${headerName} must not be blank.` };
|
|
85188
|
+
}
|
|
85189
|
+
return { ok: true, value: header.trim() };
|
|
85190
|
+
}
|
|
85191
|
+
if (body && bodyKey in body) {
|
|
85192
|
+
const raw2 = body[bodyKey];
|
|
85193
|
+
if (raw2 === null || raw2 === undefined)
|
|
85194
|
+
return { ok: true, value: undefined };
|
|
85195
|
+
if (typeof raw2 !== "string") {
|
|
85196
|
+
return { ok: false, detail: `${bodyKey} must be a string.` };
|
|
85197
|
+
}
|
|
85198
|
+
if (raw2.trim() === "") {
|
|
85199
|
+
return { ok: false, detail: `${bodyKey} must not be blank.` };
|
|
85200
|
+
}
|
|
85201
|
+
return { ok: true, value: raw2.trim() };
|
|
85202
|
+
}
|
|
85203
|
+
return { ok: true, value: undefined };
|
|
85204
|
+
}
|
|
85205
|
+
function resolveCallerIdentity(c2, body) {
|
|
85206
|
+
const author = readField(c2, HEADER.author, body, "author");
|
|
85207
|
+
if (!author.ok)
|
|
85208
|
+
return author;
|
|
85209
|
+
const requestor = readField(c2, HEADER.requestor, body, "requestor");
|
|
85210
|
+
if (!requestor.ok)
|
|
85211
|
+
return requestor;
|
|
85212
|
+
const authorType = readField(c2, HEADER.authorType, body, "author_type");
|
|
85213
|
+
if (!authorType.ok)
|
|
85214
|
+
return authorType;
|
|
85215
|
+
if (authorType.value !== undefined && authorType.value !== "user" && authorType.value !== "agent") {
|
|
85216
|
+
return {
|
|
85217
|
+
ok: false,
|
|
85218
|
+
detail: `author_type must be "user" or "agent" (got ${JSON.stringify(authorType.value)}).`
|
|
85219
|
+
};
|
|
85220
|
+
}
|
|
85221
|
+
const named = author.value !== undefined || requestor.value !== undefined || authorType.value !== undefined;
|
|
85222
|
+
if (!named)
|
|
85223
|
+
return { ok: true, identity: WEB_UI_IDENTITY };
|
|
85224
|
+
const resolvedAuthor = author.value ?? requestor.value ?? DEFAULT_WEB_AUTHOR;
|
|
85225
|
+
const resolvedRequestor = requestor.value ?? author.value ?? DEFAULT_WEB_AUTHOR;
|
|
85226
|
+
return {
|
|
85227
|
+
ok: true,
|
|
85228
|
+
identity: {
|
|
85229
|
+
author: resolvedAuthor,
|
|
85230
|
+
authorType: authorType.value ?? DEFAULT_WEB_AUTHOR_TYPE,
|
|
85231
|
+
requestor: resolvedRequestor,
|
|
85232
|
+
accessPath: "api",
|
|
85233
|
+
named: true
|
|
85234
|
+
}
|
|
85235
|
+
};
|
|
85236
|
+
}
|
|
85237
|
+
|
|
85238
|
+
// src/web/routes/config.ts
|
|
84572
85239
|
init__utils();
|
|
84573
85240
|
function unwrapScalarRpc(data) {
|
|
84574
85241
|
if (typeof data === "string")
|
|
@@ -84640,11 +85307,14 @@ function registerConfigRoutes(app, ctx) {
|
|
|
84640
85307
|
const invalid = validateConfigValue(key, value);
|
|
84641
85308
|
if (invalid)
|
|
84642
85309
|
return c2.json({ detail: invalid }, 400);
|
|
85310
|
+
const who = resolveCallerIdentity(c2, body);
|
|
85311
|
+
if (!who.ok)
|
|
85312
|
+
return c2.json({ detail: who.detail }, 400);
|
|
84643
85313
|
const { error: error3 } = await ctx.supabase.rpc("cerefox_set_config", {
|
|
84644
85314
|
p_key: key,
|
|
84645
85315
|
p_value: value,
|
|
84646
|
-
p_author:
|
|
84647
|
-
p_author_type:
|
|
85316
|
+
p_author: who.identity.author,
|
|
85317
|
+
p_author_type: who.identity.authorType
|
|
84648
85318
|
});
|
|
84649
85319
|
if (error3) {
|
|
84650
85320
|
const remediation = storeWriteRemediation(error3.message ?? "", "cerefox_set_config");
|
|
@@ -84662,8 +85332,8 @@ init__utils();
|
|
|
84662
85332
|
function logWebUsage(ctx, params) {
|
|
84663
85333
|
Promise.resolve(ctx.supabase.rpc("cerefox_log_usage", {
|
|
84664
85334
|
p_operation: params.operation,
|
|
84665
|
-
p_access_path: "webapp",
|
|
84666
|
-
p_requestor: params.requestor ??
|
|
85335
|
+
p_access_path: params.access_path ?? "webapp",
|
|
85336
|
+
p_requestor: params.requestor ?? DEFAULT_WEB_AUTHOR,
|
|
84667
85337
|
p_document_id: params.document_id ?? null,
|
|
84668
85338
|
p_project_id: params.project_id ?? null,
|
|
84669
85339
|
p_query_text: params.query_text ?? null,
|
|
@@ -84989,7 +85659,16 @@ function registerDiscoveryRoutes(app, ctx) {
|
|
|
84989
85659
|
results = results.filter((r) => statusMap.get(r.document_id) === reviewStatus);
|
|
84990
85660
|
}
|
|
84991
85661
|
}
|
|
84992
|
-
|
|
85662
|
+
const who = resolveCallerIdentity(c2);
|
|
85663
|
+
if (!who.ok)
|
|
85664
|
+
return c2.json({ detail: who.detail }, 400);
|
|
85665
|
+
logWebUsage(ctx, {
|
|
85666
|
+
operation: "search",
|
|
85667
|
+
query_text: q,
|
|
85668
|
+
result_count: results.length,
|
|
85669
|
+
requestor: who.identity.requestor,
|
|
85670
|
+
access_path: who.identity.accessPath
|
|
85671
|
+
});
|
|
84993
85672
|
return c2.json({
|
|
84994
85673
|
results,
|
|
84995
85674
|
query: q,
|
|
@@ -85314,7 +85993,15 @@ function registerDocumentReadRoutes(app, ctx) {
|
|
|
85314
85993
|
const meta = await getDocumentRow(ctx, documentId);
|
|
85315
85994
|
const projectIds = await listDocumentProjectIds(ctx, documentId);
|
|
85316
85995
|
const versions3 = await listDocumentVersions(ctx, documentId);
|
|
85317
|
-
|
|
85996
|
+
const who = resolveCallerIdentity(c2);
|
|
85997
|
+
if (!who.ok)
|
|
85998
|
+
return c2.json({ detail: who.detail }, 400);
|
|
85999
|
+
logWebUsage(ctx, {
|
|
86000
|
+
operation: "get-document",
|
|
86001
|
+
document_id: documentId,
|
|
86002
|
+
requestor: who.identity.requestor,
|
|
86003
|
+
access_path: who.identity.accessPath
|
|
86004
|
+
});
|
|
85318
86005
|
return c2.json({
|
|
85319
86006
|
document_id: documentId,
|
|
85320
86007
|
full_content: doc2.full_content ?? "",
|
|
@@ -85451,6 +86138,9 @@ function registerDocumentWriteRoutes(app, ctx) {
|
|
|
85451
86138
|
} catch {
|
|
85452
86139
|
return c2.json({ success: false, error: "Invalid JSON body" }, 400);
|
|
85453
86140
|
}
|
|
86141
|
+
const who = resolveCallerIdentity(c2, body);
|
|
86142
|
+
if (!who.ok)
|
|
86143
|
+
return c2.json({ detail: who.detail }, 400);
|
|
85454
86144
|
const title = String(body.title ?? "").trim();
|
|
85455
86145
|
const content = String(body.content ?? "");
|
|
85456
86146
|
const projectIds = Array.isArray(body.project_ids) ? body.project_ids : [];
|
|
@@ -85491,8 +86181,8 @@ function registerDocumentWriteRoutes(app, ctx) {
|
|
|
85491
86181
|
source: "manual",
|
|
85492
86182
|
projectIds: Array.isArray(body.project_ids) ? body.project_ids : undefined,
|
|
85493
86183
|
metadata: body.metadata != null ? metadata : undefined,
|
|
85494
|
-
author:
|
|
85495
|
-
authorType:
|
|
86184
|
+
author: who.identity.author,
|
|
86185
|
+
authorType: who.identity.authorType,
|
|
85496
86186
|
expectedContentHash: typeof body.expected_content_hash === "string" ? body.expected_content_hash : null
|
|
85497
86187
|
});
|
|
85498
86188
|
return c2.json({ success: true, reindexed: result.reindexed });
|
|
@@ -85537,9 +86227,9 @@ function registerDocumentWriteRoutes(app, ctx) {
|
|
|
85537
86227
|
title: body.title !== undefined && title !== doc2.title ? title : undefined,
|
|
85538
86228
|
metadata: body.metadata != null ? metadata : undefined,
|
|
85539
86229
|
projectIds: Array.isArray(body.project_ids) ? projectIds : undefined,
|
|
85540
|
-
author:
|
|
85541
|
-
authorType:
|
|
85542
|
-
accessPath:
|
|
86230
|
+
author: who.identity.author,
|
|
86231
|
+
authorType: who.identity.authorType,
|
|
86232
|
+
accessPath: who.identity.accessPath
|
|
85543
86233
|
});
|
|
85544
86234
|
return c2.json({ success: true, reindexed: false, ...facets });
|
|
85545
86235
|
} catch (err) {
|
|
@@ -85556,10 +86246,20 @@ function registerDocumentWriteRoutes(app, ctx) {
|
|
|
85556
86246
|
});
|
|
85557
86247
|
app.delete("/api/v1/documents/:document_id", async (c2) => {
|
|
85558
86248
|
const documentId = c2.req.param("document_id");
|
|
86249
|
+
const who = resolveCallerIdentity(c2);
|
|
86250
|
+
if (!who.ok)
|
|
86251
|
+
return c2.json({ detail: who.detail }, 400);
|
|
86252
|
+
const expectedHash = (c2.req.header("x-cerefox-expected-content-hash") ?? c2.req.query("expected_content_hash") ?? "").trim();
|
|
86253
|
+
if (who.identity.named && expectedHash === "") {
|
|
86254
|
+
return c2.json({
|
|
86255
|
+
detail: "CEREFOX_TOKEN_REQUIRED: an identified caller must send the content_hash it read, " + "as the X-Cerefox-Expected-Content-Hash header or an expected_content_hash query " + "parameter. A delete must follow a read."
|
|
86256
|
+
}, 400);
|
|
86257
|
+
}
|
|
85559
86258
|
const { data, error: error3 } = await ctx.supabase.rpc("cerefox_delete_document", {
|
|
85560
86259
|
p_document_id: documentId,
|
|
85561
|
-
p_author:
|
|
85562
|
-
p_author_type:
|
|
86260
|
+
p_author: who.identity.author,
|
|
86261
|
+
p_author_type: who.identity.authorType,
|
|
86262
|
+
p_expected_content_hash: expectedHash === "" ? null : expectedHash
|
|
85563
86263
|
});
|
|
85564
86264
|
if (error3) {
|
|
85565
86265
|
if (isDocumentNotFoundError(error3)) {
|
|
@@ -85572,10 +86272,13 @@ function registerDocumentWriteRoutes(app, ctx) {
|
|
|
85572
86272
|
});
|
|
85573
86273
|
app.post("/api/v1/documents/:document_id/restore", async (c2) => {
|
|
85574
86274
|
const documentId = c2.req.param("document_id");
|
|
86275
|
+
const who = resolveCallerIdentity(c2);
|
|
86276
|
+
if (!who.ok)
|
|
86277
|
+
return c2.json({ detail: who.detail }, 400);
|
|
85575
86278
|
const { data, error: error3 } = await ctx.supabase.rpc("cerefox_restore_document", {
|
|
85576
86279
|
p_document_id: documentId,
|
|
85577
|
-
p_author:
|
|
85578
|
-
p_author_type:
|
|
86280
|
+
p_author: who.identity.author,
|
|
86281
|
+
p_author_type: who.identity.authorType
|
|
85579
86282
|
});
|
|
85580
86283
|
if (error3) {
|
|
85581
86284
|
if (isDocumentNotFoundError(error3)) {
|
|
@@ -85588,10 +86291,13 @@ function registerDocumentWriteRoutes(app, ctx) {
|
|
|
85588
86291
|
});
|
|
85589
86292
|
app.delete("/api/v1/documents/:document_id/purge", async (c2) => {
|
|
85590
86293
|
const documentId = c2.req.param("document_id");
|
|
86294
|
+
const who = resolveCallerIdentity(c2);
|
|
86295
|
+
if (!who.ok)
|
|
86296
|
+
return c2.json({ detail: who.detail }, 400);
|
|
85591
86297
|
const { error: error3 } = await ctx.supabase.rpc("cerefox_purge_document", {
|
|
85592
86298
|
p_document_id: documentId,
|
|
85593
|
-
p_author:
|
|
85594
|
-
p_author_type:
|
|
86299
|
+
p_author: who.identity.author,
|
|
86300
|
+
p_author_type: who.identity.authorType
|
|
85595
86301
|
});
|
|
85596
86302
|
if (error3)
|
|
85597
86303
|
return c2.json({ detail: error3.message }, 500);
|
|
@@ -85605,6 +86311,9 @@ function registerDocumentWriteRoutes(app, ctx) {
|
|
|
85605
86311
|
} catch {
|
|
85606
86312
|
return c2.json({ detail: "Invalid JSON body" }, 400);
|
|
85607
86313
|
}
|
|
86314
|
+
const who = resolveCallerIdentity(c2, body);
|
|
86315
|
+
if (!who.ok)
|
|
86316
|
+
return c2.json({ detail: who.detail }, 400);
|
|
85608
86317
|
const status = body.status;
|
|
85609
86318
|
if (status !== "approved" && status !== "pending_review") {
|
|
85610
86319
|
return c2.json({ detail: `Invalid status: ${JSON.stringify(status)}` }, 400);
|
|
@@ -85619,7 +86328,8 @@ function registerDocumentWriteRoutes(app, ctx) {
|
|
|
85619
86328
|
return c2.json({ detail: error3.message }, 500);
|
|
85620
86329
|
await createAuditEntry(ctx, {
|
|
85621
86330
|
operation: "status-change",
|
|
85622
|
-
author:
|
|
86331
|
+
author: who.identity.author,
|
|
86332
|
+
authorType: who.identity.authorType,
|
|
85623
86333
|
documentId,
|
|
85624
86334
|
description: `Review status changed from '${oldStatus}' to '${status}'`
|
|
85625
86335
|
});
|
|
@@ -85634,6 +86344,9 @@ function registerDocumentWriteRoutes(app, ctx) {
|
|
|
85634
86344
|
} catch {
|
|
85635
86345
|
return c2.json({ detail: "Invalid JSON body" }, 400);
|
|
85636
86346
|
}
|
|
86347
|
+
const who = resolveCallerIdentity(c2, body);
|
|
86348
|
+
if (!who.ok)
|
|
86349
|
+
return c2.json({ detail: who.detail }, 400);
|
|
85637
86350
|
const archived = Boolean(body.archived);
|
|
85638
86351
|
const { data, error: error3 } = await ctx.supabase.from("cerefox_document_versions").update({ archived }).eq("id", versionId).select("document_id, version_number").maybeSingle();
|
|
85639
86352
|
if (error3)
|
|
@@ -85642,7 +86355,8 @@ function registerDocumentWriteRoutes(app, ctx) {
|
|
|
85642
86355
|
const op = archived ? "archive" : "unarchive";
|
|
85643
86356
|
await createAuditEntry(ctx, {
|
|
85644
86357
|
operation: op,
|
|
85645
|
-
author:
|
|
86358
|
+
author: who.identity.author,
|
|
86359
|
+
authorType: who.identity.authorType,
|
|
85646
86360
|
documentId: ver?.document_id ?? documentId,
|
|
85647
86361
|
versionId,
|
|
85648
86362
|
description: `Version ${ver?.version_number ?? "?"} ${op}d`
|
|
@@ -85652,7 +86366,22 @@ function registerDocumentWriteRoutes(app, ctx) {
|
|
|
85652
86366
|
}
|
|
85653
86367
|
// src/web/routes/ingest.ts
|
|
85654
86368
|
function notReady(error3) {
|
|
85655
|
-
return { success: false, error: error3 };
|
|
86369
|
+
return { success: false, error: error3, detail: error3 };
|
|
86370
|
+
}
|
|
86371
|
+
function ingestFailure(err) {
|
|
86372
|
+
if (err instanceof ConcurrencyConflictError) {
|
|
86373
|
+
return [
|
|
86374
|
+
{
|
|
86375
|
+
...notReady(err.message),
|
|
86376
|
+
...err.currentHash ? { current_hash: err.currentHash } : {}
|
|
86377
|
+
},
|
|
86378
|
+
409
|
|
86379
|
+
];
|
|
86380
|
+
}
|
|
86381
|
+
if (err instanceof ConcurrencyTokenRequiredError) {
|
|
86382
|
+
return [notReady(err.message), 400];
|
|
86383
|
+
}
|
|
86384
|
+
return [notReady(err instanceof Error ? err.message : String(err)), 500];
|
|
85656
86385
|
}
|
|
85657
86386
|
function registerIngestRoutes(app, ctx) {
|
|
85658
86387
|
app.post("/api/v1/ingest", async (c2) => {
|
|
@@ -85671,6 +86400,9 @@ function registerIngestRoutes(app, ctx) {
|
|
|
85671
86400
|
return c2.json(notReady("Title is required."), 200);
|
|
85672
86401
|
if (!content.trim())
|
|
85673
86402
|
return c2.json(notReady("Content cannot be empty."), 200);
|
|
86403
|
+
const who = resolveCallerIdentity(c2, body);
|
|
86404
|
+
if (!who.ok)
|
|
86405
|
+
return c2.json({ detail: who.detail }, 400);
|
|
85674
86406
|
try {
|
|
85675
86407
|
const pipeline2 = new IngestionPipeline({
|
|
85676
86408
|
supabase: ctx.supabase,
|
|
@@ -85684,8 +86416,8 @@ function registerIngestRoutes(app, ctx) {
|
|
|
85684
86416
|
metadata: body.metadata ?? null,
|
|
85685
86417
|
updateExisting: Boolean(body.update_existing),
|
|
85686
86418
|
documentId: body.document_id ?? null,
|
|
85687
|
-
author:
|
|
85688
|
-
authorType:
|
|
86419
|
+
author: who.identity.author,
|
|
86420
|
+
authorType: who.identity.authorType
|
|
85689
86421
|
});
|
|
85690
86422
|
const skipped = result.action === "skipped";
|
|
85691
86423
|
const resp = {
|
|
@@ -85697,10 +86429,16 @@ function registerIngestRoutes(app, ctx) {
|
|
|
85697
86429
|
};
|
|
85698
86430
|
if (result.note)
|
|
85699
86431
|
resp.note = result.note;
|
|
85700
|
-
logWebUsage(ctx, {
|
|
86432
|
+
logWebUsage(ctx, {
|
|
86433
|
+
operation: "ingest",
|
|
86434
|
+
document_id: result.documentId,
|
|
86435
|
+
requestor: who.identity.requestor,
|
|
86436
|
+
access_path: who.identity.accessPath
|
|
86437
|
+
});
|
|
85701
86438
|
return c2.json(resp, 200);
|
|
85702
86439
|
} catch (err) {
|
|
85703
|
-
|
|
86440
|
+
const [body2, status] = ingestFailure(err);
|
|
86441
|
+
return c2.json(body2, status);
|
|
85704
86442
|
}
|
|
85705
86443
|
});
|
|
85706
86444
|
app.post("/api/v1/ingest/file", async (c2) => {
|
|
@@ -85736,6 +86474,9 @@ function registerIngestRoutes(app, ctx) {
|
|
|
85736
86474
|
metadata = null;
|
|
85737
86475
|
}
|
|
85738
86476
|
}
|
|
86477
|
+
const who = resolveCallerIdentity(c2, form);
|
|
86478
|
+
if (!who.ok)
|
|
86479
|
+
return c2.json({ detail: who.detail }, 400);
|
|
85739
86480
|
try {
|
|
85740
86481
|
const pipeline2 = new IngestionPipeline({
|
|
85741
86482
|
supabase: ctx.supabase,
|
|
@@ -85749,11 +86490,16 @@ function registerIngestRoutes(app, ctx) {
|
|
|
85749
86490
|
projectIds,
|
|
85750
86491
|
metadata,
|
|
85751
86492
|
updateExisting,
|
|
85752
|
-
author:
|
|
85753
|
-
authorType:
|
|
86493
|
+
author: who.identity.author,
|
|
86494
|
+
authorType: who.identity.authorType
|
|
85754
86495
|
});
|
|
85755
86496
|
const skipped = result.action === "skipped";
|
|
85756
|
-
logWebUsage(ctx, {
|
|
86497
|
+
logWebUsage(ctx, {
|
|
86498
|
+
operation: "ingest",
|
|
86499
|
+
document_id: result.documentId,
|
|
86500
|
+
requestor: who.identity.requestor,
|
|
86501
|
+
access_path: who.identity.accessPath
|
|
86502
|
+
});
|
|
85757
86503
|
return c2.json({
|
|
85758
86504
|
success: !skipped,
|
|
85759
86505
|
document_id: result.documentId,
|
|
@@ -85763,7 +86509,8 @@ function registerIngestRoutes(app, ctx) {
|
|
|
85763
86509
|
...result.note ? { note: result.note } : {}
|
|
85764
86510
|
}, 200);
|
|
85765
86511
|
} catch (err) {
|
|
85766
|
-
|
|
86512
|
+
const [body, status] = ingestFailure(err);
|
|
86513
|
+
return c2.json(body, status);
|
|
85767
86514
|
}
|
|
85768
86515
|
});
|
|
85769
86516
|
app.post("/api/v1/documents/:document_id/upload", async (c2) => {
|
|
@@ -85790,6 +86537,9 @@ function registerIngestRoutes(app, ctx) {
|
|
|
85790
86537
|
if (!existing)
|
|
85791
86538
|
return c2.json(notReady("Document not found"), 404);
|
|
85792
86539
|
const title = existing.title || file.name || "Untitled";
|
|
86540
|
+
const who = resolveCallerIdentity(c2, form);
|
|
86541
|
+
if (!who.ok)
|
|
86542
|
+
return c2.json({ detail: who.detail }, 400);
|
|
85793
86543
|
try {
|
|
85794
86544
|
const pipeline2 = new IngestionPipeline({
|
|
85795
86545
|
supabase: ctx.supabase,
|
|
@@ -85800,10 +86550,17 @@ function registerIngestRoutes(app, ctx) {
|
|
|
85800
86550
|
text,
|
|
85801
86551
|
title,
|
|
85802
86552
|
source: "file",
|
|
85803
|
-
author:
|
|
85804
|
-
authorType:
|
|
86553
|
+
author: who.identity.author,
|
|
86554
|
+
authorType: who.identity.authorType,
|
|
86555
|
+
expectedContentHash: typeof form.expected_content_hash === "string" && form.expected_content_hash.trim() !== "" ? form.expected_content_hash.trim() : null,
|
|
86556
|
+
lastWriteWins: String(form.last_write_wins ?? "") === "true"
|
|
86557
|
+
});
|
|
86558
|
+
logWebUsage(ctx, {
|
|
86559
|
+
operation: "ingest",
|
|
86560
|
+
document_id: result.documentId,
|
|
86561
|
+
requestor: who.identity.requestor,
|
|
86562
|
+
access_path: who.identity.accessPath
|
|
85805
86563
|
});
|
|
85806
|
-
logWebUsage(ctx, { operation: "ingest", document_id: result.documentId });
|
|
85807
86564
|
return c2.json({
|
|
85808
86565
|
success: true,
|
|
85809
86566
|
document_id: result.documentId,
|
|
@@ -85811,7 +86568,8 @@ function registerIngestRoutes(app, ctx) {
|
|
|
85811
86568
|
updated: result.reindexed
|
|
85812
86569
|
}, 200);
|
|
85813
86570
|
} catch (err) {
|
|
85814
|
-
|
|
86571
|
+
const [body, status] = ingestFailure(err);
|
|
86572
|
+
return c2.json(body, status);
|
|
85815
86573
|
}
|
|
85816
86574
|
});
|
|
85817
86575
|
}
|
|
@@ -86154,11 +86912,14 @@ function registerProjectsRoutes(app, ctx) {
|
|
|
86154
86912
|
if (!name)
|
|
86155
86913
|
return c2.json({ detail: "Project name is required" }, 400);
|
|
86156
86914
|
const description = String(body.description ?? "").trim();
|
|
86915
|
+
const who = resolveCallerIdentity(c2, body);
|
|
86916
|
+
if (!who.ok)
|
|
86917
|
+
return c2.json({ detail: who.detail }, 400);
|
|
86157
86918
|
const { data, error: error3 } = await ctx.supabase.rpc("cerefox_create_project", {
|
|
86158
86919
|
p_name: name,
|
|
86159
86920
|
p_description: description,
|
|
86160
|
-
p_author:
|
|
86161
|
-
p_author_type:
|
|
86921
|
+
p_author: who.identity.author,
|
|
86922
|
+
p_author_type: who.identity.authorType
|
|
86162
86923
|
});
|
|
86163
86924
|
if (error3) {
|
|
86164
86925
|
const msg = error3.message ?? "";
|
|
@@ -86194,12 +86955,15 @@ function registerProjectsRoutes(app, ctx) {
|
|
|
86194
86955
|
if (Object.keys(update).length === 0) {
|
|
86195
86956
|
return c2.json({ detail: "Nothing to update — pass name and/or description" }, 400);
|
|
86196
86957
|
}
|
|
86958
|
+
const who = resolveCallerIdentity(c2, body);
|
|
86959
|
+
if (!who.ok)
|
|
86960
|
+
return c2.json({ detail: who.detail }, 400);
|
|
86197
86961
|
const { data, error: error3 } = await ctx.supabase.rpc("cerefox_update_project", {
|
|
86198
86962
|
p_project_id: projectId,
|
|
86199
86963
|
p_name: update.name ?? null,
|
|
86200
86964
|
p_description: update.description ?? null,
|
|
86201
|
-
p_author:
|
|
86202
|
-
p_author_type:
|
|
86965
|
+
p_author: who.identity.author,
|
|
86966
|
+
p_author_type: who.identity.authorType
|
|
86203
86967
|
});
|
|
86204
86968
|
if (error3) {
|
|
86205
86969
|
const msg = error3.message ?? "";
|
|
@@ -86217,10 +86981,13 @@ function registerProjectsRoutes(app, ctx) {
|
|
|
86217
86981
|
});
|
|
86218
86982
|
app.delete("/api/v1/projects/:project_id", async (c2) => {
|
|
86219
86983
|
const projectId = c2.req.param("project_id");
|
|
86984
|
+
const who = resolveCallerIdentity(c2);
|
|
86985
|
+
if (!who.ok)
|
|
86986
|
+
return c2.json({ detail: who.detail }, 400);
|
|
86220
86987
|
const { data, error: error3 } = await ctx.supabase.rpc("cerefox_delete_project", {
|
|
86221
86988
|
p_project_id: projectId,
|
|
86222
|
-
p_author:
|
|
86223
|
-
p_author_type:
|
|
86989
|
+
p_author: who.identity.author,
|
|
86990
|
+
p_author_type: who.identity.authorType
|
|
86224
86991
|
});
|
|
86225
86992
|
if (error3)
|
|
86226
86993
|
return c2.json({ detail: error3.message }, 500);
|
|
@@ -86313,6 +87080,8 @@ function buildApp(ctx = buildWebContext()) {
|
|
|
86313
87080
|
if (true) {
|
|
86314
87081
|
app.use(logger((message, ...rest) => console.log(`${localTimestamp()} ${message}`, ...rest)));
|
|
86315
87082
|
}
|
|
87083
|
+
app.use("/api/v1/*", apiAuth());
|
|
87084
|
+
app.use("/rest/v1/*", apiAuth());
|
|
86316
87085
|
registerMetaRoutes(app, ctx);
|
|
86317
87086
|
registerPreferencesRoutes(app);
|
|
86318
87087
|
if (ctx) {
|
|
@@ -86395,6 +87164,14 @@ async function buildWebServer(options = {}) {
|
|
|
86395
87164
|
const host = options.host ?? "127.0.0.1";
|
|
86396
87165
|
const port = options.port ?? 8000;
|
|
86397
87166
|
await assertServerCompatible();
|
|
87167
|
+
if (!isLoopbackAddress(host) && !(process.env.CEREFOX_API_KEY ?? "").trim()) {
|
|
87168
|
+
console.warn(`
|
|
87169
|
+
⚠ Binding ${host} with NO API key configured.
|
|
87170
|
+
` + ` Every read, write, delete and purge on this server is reachable by
|
|
87171
|
+
` + ` anything that can connect to port ${port}, with no credential.
|
|
87172
|
+
` + ` Mint one: cerefox api-key generate
|
|
87173
|
+
`);
|
|
87174
|
+
}
|
|
86398
87175
|
const app = buildApp();
|
|
86399
87176
|
const server = serve({ fetch: app.fetch, hostname: host, port });
|
|
86400
87177
|
return {
|
|
@@ -86769,6 +87546,7 @@ Learn more:
|
|
|
86769
87546
|
registerWeb(program2);
|
|
86770
87547
|
registerCompletion(program2);
|
|
86771
87548
|
registerToken(program2);
|
|
87549
|
+
registerApiKey(program2);
|
|
86772
87550
|
const document2 = program2.command("document").description("Documents: get, list, edit, delete, restore, ingest, ingest-dir, version.");
|
|
86773
87551
|
moveInto(document2, registerGetDoc, "get");
|
|
86774
87552
|
moveInto(document2, registerListDocs, "list");
|