apple-notes-mcp 2.9.13 → 2.9.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -1
- package/build/index.js +2058 -495
- package/docs/markdown-templates.md +239 -0
- package/package.json +1 -1
package/build/index.js
CHANGED
|
@@ -417,11 +417,11 @@ var require_codegen = __commonJS({
|
|
|
417
417
|
const rhs = this.rhs === void 0 ? "" : ` = ${this.rhs}`;
|
|
418
418
|
return `${varKind} ${this.name}${rhs};` + _n;
|
|
419
419
|
}
|
|
420
|
-
optimizeNames(names,
|
|
420
|
+
optimizeNames(names, constants8) {
|
|
421
421
|
if (!names[this.name.str])
|
|
422
422
|
return;
|
|
423
423
|
if (this.rhs)
|
|
424
|
-
this.rhs = optimizeExpr(this.rhs, names,
|
|
424
|
+
this.rhs = optimizeExpr(this.rhs, names, constants8);
|
|
425
425
|
return this;
|
|
426
426
|
}
|
|
427
427
|
get names() {
|
|
@@ -438,10 +438,10 @@ var require_codegen = __commonJS({
|
|
|
438
438
|
render({ _n }) {
|
|
439
439
|
return `${this.lhs} = ${this.rhs};` + _n;
|
|
440
440
|
}
|
|
441
|
-
optimizeNames(names,
|
|
441
|
+
optimizeNames(names, constants8) {
|
|
442
442
|
if (this.lhs instanceof code_1.Name && !names[this.lhs.str] && !this.sideEffects)
|
|
443
443
|
return;
|
|
444
|
-
this.rhs = optimizeExpr(this.rhs, names,
|
|
444
|
+
this.rhs = optimizeExpr(this.rhs, names, constants8);
|
|
445
445
|
return this;
|
|
446
446
|
}
|
|
447
447
|
get names() {
|
|
@@ -502,8 +502,8 @@ var require_codegen = __commonJS({
|
|
|
502
502
|
optimizeNodes() {
|
|
503
503
|
return `${this.code}` ? this : void 0;
|
|
504
504
|
}
|
|
505
|
-
optimizeNames(names,
|
|
506
|
-
this.code = optimizeExpr(this.code, names,
|
|
505
|
+
optimizeNames(names, constants8) {
|
|
506
|
+
this.code = optimizeExpr(this.code, names, constants8);
|
|
507
507
|
return this;
|
|
508
508
|
}
|
|
509
509
|
get names() {
|
|
@@ -532,12 +532,12 @@ var require_codegen = __commonJS({
|
|
|
532
532
|
}
|
|
533
533
|
return nodes.length > 0 ? this : void 0;
|
|
534
534
|
}
|
|
535
|
-
optimizeNames(names,
|
|
535
|
+
optimizeNames(names, constants8) {
|
|
536
536
|
const { nodes } = this;
|
|
537
537
|
let i = nodes.length;
|
|
538
538
|
while (i--) {
|
|
539
539
|
const n = nodes[i];
|
|
540
|
-
if (n.optimizeNames(names,
|
|
540
|
+
if (n.optimizeNames(names, constants8))
|
|
541
541
|
continue;
|
|
542
542
|
subtractNames(names, n.names);
|
|
543
543
|
nodes.splice(i, 1);
|
|
@@ -590,12 +590,12 @@ var require_codegen = __commonJS({
|
|
|
590
590
|
return void 0;
|
|
591
591
|
return this;
|
|
592
592
|
}
|
|
593
|
-
optimizeNames(names,
|
|
593
|
+
optimizeNames(names, constants8) {
|
|
594
594
|
var _a;
|
|
595
|
-
this.else = (_a = this.else) === null || _a === void 0 ? void 0 : _a.optimizeNames(names,
|
|
596
|
-
if (!(super.optimizeNames(names,
|
|
595
|
+
this.else = (_a = this.else) === null || _a === void 0 ? void 0 : _a.optimizeNames(names, constants8);
|
|
596
|
+
if (!(super.optimizeNames(names, constants8) || this.else))
|
|
597
597
|
return;
|
|
598
|
-
this.condition = optimizeExpr(this.condition, names,
|
|
598
|
+
this.condition = optimizeExpr(this.condition, names, constants8);
|
|
599
599
|
return this;
|
|
600
600
|
}
|
|
601
601
|
get names() {
|
|
@@ -618,10 +618,10 @@ var require_codegen = __commonJS({
|
|
|
618
618
|
render(opts) {
|
|
619
619
|
return `for(${this.iteration})` + super.render(opts);
|
|
620
620
|
}
|
|
621
|
-
optimizeNames(names,
|
|
622
|
-
if (!super.optimizeNames(names,
|
|
621
|
+
optimizeNames(names, constants8) {
|
|
622
|
+
if (!super.optimizeNames(names, constants8))
|
|
623
623
|
return;
|
|
624
|
-
this.iteration = optimizeExpr(this.iteration, names,
|
|
624
|
+
this.iteration = optimizeExpr(this.iteration, names, constants8);
|
|
625
625
|
return this;
|
|
626
626
|
}
|
|
627
627
|
get names() {
|
|
@@ -657,10 +657,10 @@ var require_codegen = __commonJS({
|
|
|
657
657
|
render(opts) {
|
|
658
658
|
return `for(${this.varKind} ${this.name} ${this.loop} ${this.iterable})` + super.render(opts);
|
|
659
659
|
}
|
|
660
|
-
optimizeNames(names,
|
|
661
|
-
if (!super.optimizeNames(names,
|
|
660
|
+
optimizeNames(names, constants8) {
|
|
661
|
+
if (!super.optimizeNames(names, constants8))
|
|
662
662
|
return;
|
|
663
|
-
this.iterable = optimizeExpr(this.iterable, names,
|
|
663
|
+
this.iterable = optimizeExpr(this.iterable, names, constants8);
|
|
664
664
|
return this;
|
|
665
665
|
}
|
|
666
666
|
get names() {
|
|
@@ -702,11 +702,11 @@ var require_codegen = __commonJS({
|
|
|
702
702
|
(_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNodes();
|
|
703
703
|
return this;
|
|
704
704
|
}
|
|
705
|
-
optimizeNames(names,
|
|
705
|
+
optimizeNames(names, constants8) {
|
|
706
706
|
var _a, _b;
|
|
707
|
-
super.optimizeNames(names,
|
|
708
|
-
(_a = this.catch) === null || _a === void 0 ? void 0 : _a.optimizeNames(names,
|
|
709
|
-
(_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNames(names,
|
|
707
|
+
super.optimizeNames(names, constants8);
|
|
708
|
+
(_a = this.catch) === null || _a === void 0 ? void 0 : _a.optimizeNames(names, constants8);
|
|
709
|
+
(_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNames(names, constants8);
|
|
710
710
|
return this;
|
|
711
711
|
}
|
|
712
712
|
get names() {
|
|
@@ -1007,7 +1007,7 @@ var require_codegen = __commonJS({
|
|
|
1007
1007
|
function addExprNames(names, from) {
|
|
1008
1008
|
return from instanceof code_1._CodeOrName ? addNames(names, from.names) : names;
|
|
1009
1009
|
}
|
|
1010
|
-
function optimizeExpr(expr, names,
|
|
1010
|
+
function optimizeExpr(expr, names, constants8) {
|
|
1011
1011
|
if (expr instanceof code_1.Name)
|
|
1012
1012
|
return replaceName(expr);
|
|
1013
1013
|
if (!canOptimize(expr))
|
|
@@ -1022,14 +1022,14 @@ var require_codegen = __commonJS({
|
|
|
1022
1022
|
return items;
|
|
1023
1023
|
}, []));
|
|
1024
1024
|
function replaceName(n) {
|
|
1025
|
-
const c =
|
|
1025
|
+
const c = constants8[n.str];
|
|
1026
1026
|
if (c === void 0 || names[n.str] !== 1)
|
|
1027
1027
|
return n;
|
|
1028
1028
|
delete names[n.str];
|
|
1029
1029
|
return c;
|
|
1030
1030
|
}
|
|
1031
1031
|
function canOptimize(e) {
|
|
1032
|
-
return e instanceof code_1._Code && e._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 &&
|
|
1032
|
+
return e instanceof code_1._Code && e._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 && constants8[c.str] !== void 0);
|
|
1033
1033
|
}
|
|
1034
1034
|
}
|
|
1035
1035
|
function subtractNames(names, from) {
|
|
@@ -1785,14 +1785,14 @@ var require_code2 = __commonJS({
|
|
|
1785
1785
|
}
|
|
1786
1786
|
exports.callValidateCode = callValidateCode;
|
|
1787
1787
|
var newRegExp = (0, codegen_1._)`new RegExp`;
|
|
1788
|
-
function usePattern({ gen, it: { opts } },
|
|
1788
|
+
function usePattern({ gen, it: { opts } }, pattern2) {
|
|
1789
1789
|
const u = opts.unicodeRegExp ? "u" : "";
|
|
1790
1790
|
const { regExp } = opts.code;
|
|
1791
|
-
const rx = regExp(
|
|
1791
|
+
const rx = regExp(pattern2, u);
|
|
1792
1792
|
return gen.scopeValue("pattern", {
|
|
1793
1793
|
key: rx.toString(),
|
|
1794
1794
|
ref: rx,
|
|
1795
|
-
code: (0, codegen_1._)`${regExp.code === "new RegExp" ? newRegExp : (0, util_2.useFunc)(gen, regExp)}(${
|
|
1795
|
+
code: (0, codegen_1._)`${regExp.code === "new RegExp" ? newRegExp : (0, util_2.useFunc)(gen, regExp)}(${pattern2}, ${u})`
|
|
1796
1796
|
});
|
|
1797
1797
|
}
|
|
1798
1798
|
exports.usePattern = usePattern;
|
|
@@ -2991,7 +2991,7 @@ var require_compile = __commonJS({
|
|
|
2991
2991
|
const schOrFunc = root.refs[ref];
|
|
2992
2992
|
if (schOrFunc)
|
|
2993
2993
|
return schOrFunc;
|
|
2994
|
-
let _sch =
|
|
2994
|
+
let _sch = resolve8.call(this, root, ref);
|
|
2995
2995
|
if (_sch === void 0) {
|
|
2996
2996
|
const schema = (_a = root.localRefs) === null || _a === void 0 ? void 0 : _a[ref];
|
|
2997
2997
|
const { schemaId } = this.opts;
|
|
@@ -3018,7 +3018,7 @@ var require_compile = __commonJS({
|
|
|
3018
3018
|
function sameSchemaEnv(s1, s2) {
|
|
3019
3019
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
3020
3020
|
}
|
|
3021
|
-
function
|
|
3021
|
+
function resolve8(root, ref) {
|
|
3022
3022
|
let sch;
|
|
3023
3023
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
3024
3024
|
ref = sch;
|
|
@@ -3843,7 +3843,7 @@ var require_fast_uri = __commonJS({
|
|
|
3843
3843
|
}
|
|
3844
3844
|
return uri;
|
|
3845
3845
|
}
|
|
3846
|
-
function
|
|
3846
|
+
function resolve8(baseURI, relativeURI, options) {
|
|
3847
3847
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
3848
3848
|
const {
|
|
3849
3849
|
parsed: baseParsed,
|
|
@@ -3876,49 +3876,49 @@ var require_fast_uri = __commonJS({
|
|
|
3876
3876
|
schemelessOptions.skipEscape = true;
|
|
3877
3877
|
return serialize(resolved, schemelessOptions);
|
|
3878
3878
|
}
|
|
3879
|
-
function resolveComponent(base,
|
|
3879
|
+
function resolveComponent(base, relative5, options, skipNormalization) {
|
|
3880
3880
|
const target = {};
|
|
3881
3881
|
if (!skipNormalization) {
|
|
3882
3882
|
base = parse3(serialize(base, options), options);
|
|
3883
|
-
|
|
3883
|
+
relative5 = parse3(serialize(relative5, options), options);
|
|
3884
3884
|
}
|
|
3885
3885
|
options = options || {};
|
|
3886
|
-
if (!options.tolerant &&
|
|
3887
|
-
target.scheme =
|
|
3888
|
-
target.userinfo =
|
|
3889
|
-
target.host =
|
|
3890
|
-
target.port =
|
|
3891
|
-
target.path = removeDotSegments(
|
|
3892
|
-
target.query =
|
|
3886
|
+
if (!options.tolerant && relative5.scheme) {
|
|
3887
|
+
target.scheme = relative5.scheme;
|
|
3888
|
+
target.userinfo = relative5.userinfo;
|
|
3889
|
+
target.host = relative5.host;
|
|
3890
|
+
target.port = relative5.port;
|
|
3891
|
+
target.path = removeDotSegments(relative5.path || "");
|
|
3892
|
+
target.query = relative5.query;
|
|
3893
3893
|
} else {
|
|
3894
|
-
if (
|
|
3895
|
-
target.userinfo =
|
|
3896
|
-
target.host =
|
|
3897
|
-
target.port =
|
|
3898
|
-
target.path = removeDotSegments(
|
|
3899
|
-
target.query =
|
|
3894
|
+
if (relative5.userinfo !== void 0 || relative5.host !== void 0 || relative5.port !== void 0) {
|
|
3895
|
+
target.userinfo = relative5.userinfo;
|
|
3896
|
+
target.host = relative5.host;
|
|
3897
|
+
target.port = relative5.port;
|
|
3898
|
+
target.path = removeDotSegments(relative5.path || "");
|
|
3899
|
+
target.query = relative5.query;
|
|
3900
3900
|
} else {
|
|
3901
|
-
if (!
|
|
3901
|
+
if (!relative5.path) {
|
|
3902
3902
|
target.path = base.path;
|
|
3903
|
-
if (
|
|
3904
|
-
target.query =
|
|
3903
|
+
if (relative5.query !== void 0) {
|
|
3904
|
+
target.query = relative5.query;
|
|
3905
3905
|
} else {
|
|
3906
3906
|
target.query = base.query;
|
|
3907
3907
|
}
|
|
3908
3908
|
} else {
|
|
3909
|
-
if (
|
|
3910
|
-
target.path = removeDotSegments(
|
|
3909
|
+
if (relative5.path[0] === "/") {
|
|
3910
|
+
target.path = removeDotSegments(relative5.path);
|
|
3911
3911
|
} else {
|
|
3912
3912
|
if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) {
|
|
3913
|
-
target.path = "/" +
|
|
3913
|
+
target.path = "/" + relative5.path;
|
|
3914
3914
|
} else if (!base.path) {
|
|
3915
|
-
target.path =
|
|
3915
|
+
target.path = relative5.path;
|
|
3916
3916
|
} else {
|
|
3917
|
-
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) +
|
|
3917
|
+
target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative5.path;
|
|
3918
3918
|
}
|
|
3919
3919
|
target.path = removeDotSegments(target.path);
|
|
3920
3920
|
}
|
|
3921
|
-
target.query =
|
|
3921
|
+
target.query = relative5.query;
|
|
3922
3922
|
}
|
|
3923
3923
|
target.userinfo = base.userinfo;
|
|
3924
3924
|
target.host = base.host;
|
|
@@ -3926,7 +3926,7 @@ var require_fast_uri = __commonJS({
|
|
|
3926
3926
|
}
|
|
3927
3927
|
target.scheme = base.scheme;
|
|
3928
3928
|
}
|
|
3929
|
-
target.fragment =
|
|
3929
|
+
target.fragment = relative5.fragment;
|
|
3930
3930
|
return target;
|
|
3931
3931
|
}
|
|
3932
3932
|
function equal(uriA, uriB, options) {
|
|
@@ -4205,7 +4205,7 @@ var require_fast_uri = __commonJS({
|
|
|
4205
4205
|
var fastUri = {
|
|
4206
4206
|
SCHEMES,
|
|
4207
4207
|
normalize,
|
|
4208
|
-
resolve:
|
|
4208
|
+
resolve: resolve8,
|
|
4209
4209
|
resolveComponent,
|
|
4210
4210
|
equal,
|
|
4211
4211
|
serialize,
|
|
@@ -7422,7 +7422,7 @@ var require_DOMException = __commonJS({
|
|
|
7422
7422
|
"INVALID_NODE_TYPE_ERR (24): the supplied node is invalid or has an invalid ancestor for this operation",
|
|
7423
7423
|
"DATA_CLONE_ERR (25): the object can not be cloned."
|
|
7424
7424
|
];
|
|
7425
|
-
var
|
|
7425
|
+
var constants8 = {
|
|
7426
7426
|
INDEX_SIZE_ERR,
|
|
7427
7427
|
DOMSTRING_SIZE_ERR: 2,
|
|
7428
7428
|
// historical
|
|
@@ -7461,8 +7461,8 @@ var require_DOMException = __commonJS({
|
|
|
7461
7461
|
this.name = names[code];
|
|
7462
7462
|
}
|
|
7463
7463
|
DOMException.prototype.__proto__ = Error.prototype;
|
|
7464
|
-
for (c in
|
|
7465
|
-
v = { value:
|
|
7464
|
+
for (c in constants8) {
|
|
7465
|
+
v = { value: constants8[c] };
|
|
7466
7466
|
Object.defineProperty(DOMException, c, v);
|
|
7467
7467
|
Object.defineProperty(DOMException.prototype, c, v);
|
|
7468
7468
|
}
|
|
@@ -8184,7 +8184,7 @@ var require_Node = __commonJS({
|
|
|
8184
8184
|
}
|
|
8185
8185
|
return sum;
|
|
8186
8186
|
} },
|
|
8187
|
-
_ensureInsertValid: { value: function _ensureInsertValid(node,
|
|
8187
|
+
_ensureInsertValid: { value: function _ensureInsertValid(node, child2, isPreinsert) {
|
|
8188
8188
|
var parent = this, i, kid;
|
|
8189
8189
|
if (!node.nodeType) throw new TypeError("not a node");
|
|
8190
8190
|
switch (parent.nodeType) {
|
|
@@ -8196,8 +8196,8 @@ var require_Node = __commonJS({
|
|
|
8196
8196
|
utils.HierarchyRequestError();
|
|
8197
8197
|
}
|
|
8198
8198
|
if (node.isAncestor(parent)) utils.HierarchyRequestError();
|
|
8199
|
-
if (
|
|
8200
|
-
if (
|
|
8199
|
+
if (child2 !== null || !isPreinsert) {
|
|
8200
|
+
if (child2.parentNode !== parent) utils.NotFoundError();
|
|
8201
8201
|
}
|
|
8202
8202
|
switch (node.nodeType) {
|
|
8203
8203
|
case DOCUMENT_FRAGMENT_NODE:
|
|
@@ -8222,10 +8222,10 @@ var require_Node = __commonJS({
|
|
|
8222
8222
|
case 0:
|
|
8223
8223
|
break;
|
|
8224
8224
|
case 1:
|
|
8225
|
-
if (
|
|
8226
|
-
if (isPreinsert &&
|
|
8225
|
+
if (child2 !== null) {
|
|
8226
|
+
if (isPreinsert && child2.nodeType === DOCUMENT_TYPE_NODE)
|
|
8227
8227
|
utils.HierarchyRequestError();
|
|
8228
|
-
for (kid =
|
|
8228
|
+
for (kid = child2.nextSibling; kid !== null; kid = kid.nextSibling) {
|
|
8229
8229
|
if (kid.nodeType === DOCUMENT_TYPE_NODE)
|
|
8230
8230
|
utils.HierarchyRequestError();
|
|
8231
8231
|
}
|
|
@@ -8235,7 +8235,7 @@ var require_Node = __commonJS({
|
|
|
8235
8235
|
if (i > 0)
|
|
8236
8236
|
utils.HierarchyRequestError();
|
|
8237
8237
|
} else {
|
|
8238
|
-
if (i > 1 || i === 1 &&
|
|
8238
|
+
if (i > 1 || i === 1 && child2.nodeType !== ELEMENT_NODE)
|
|
8239
8239
|
utils.HierarchyRequestError();
|
|
8240
8240
|
}
|
|
8241
8241
|
break;
|
|
@@ -8244,10 +8244,10 @@ var require_Node = __commonJS({
|
|
|
8244
8244
|
}
|
|
8245
8245
|
break;
|
|
8246
8246
|
case ELEMENT_NODE:
|
|
8247
|
-
if (
|
|
8248
|
-
if (isPreinsert &&
|
|
8247
|
+
if (child2 !== null) {
|
|
8248
|
+
if (isPreinsert && child2.nodeType === DOCUMENT_TYPE_NODE)
|
|
8249
8249
|
utils.HierarchyRequestError();
|
|
8250
|
-
for (kid =
|
|
8250
|
+
for (kid = child2.nextSibling; kid !== null; kid = kid.nextSibling) {
|
|
8251
8251
|
if (kid.nodeType === DOCUMENT_TYPE_NODE)
|
|
8252
8252
|
utils.HierarchyRequestError();
|
|
8253
8253
|
}
|
|
@@ -8257,17 +8257,17 @@ var require_Node = __commonJS({
|
|
|
8257
8257
|
if (i > 0)
|
|
8258
8258
|
utils.HierarchyRequestError();
|
|
8259
8259
|
} else {
|
|
8260
|
-
if (i > 1 || i === 1 &&
|
|
8260
|
+
if (i > 1 || i === 1 && child2.nodeType !== ELEMENT_NODE)
|
|
8261
8261
|
utils.HierarchyRequestError();
|
|
8262
8262
|
}
|
|
8263
8263
|
break;
|
|
8264
8264
|
case DOCUMENT_TYPE_NODE:
|
|
8265
|
-
if (
|
|
8265
|
+
if (child2 === null) {
|
|
8266
8266
|
if (parent._countChildrenOfType(ELEMENT_NODE))
|
|
8267
8267
|
utils.HierarchyRequestError();
|
|
8268
8268
|
} else {
|
|
8269
8269
|
for (kid = parent.firstChild; kid !== null; kid = kid.nextSibling) {
|
|
8270
|
-
if (kid ===
|
|
8270
|
+
if (kid === child2) break;
|
|
8271
8271
|
if (kid.nodeType === ELEMENT_NODE)
|
|
8272
8272
|
utils.HierarchyRequestError();
|
|
8273
8273
|
}
|
|
@@ -8277,7 +8277,7 @@ var require_Node = __commonJS({
|
|
|
8277
8277
|
if (i > 0)
|
|
8278
8278
|
utils.HierarchyRequestError();
|
|
8279
8279
|
} else {
|
|
8280
|
-
if (i > 1 || i === 1 &&
|
|
8280
|
+
if (i > 1 || i === 1 && child2.nodeType !== DOCUMENT_TYPE_NODE)
|
|
8281
8281
|
utils.HierarchyRequestError();
|
|
8282
8282
|
}
|
|
8283
8283
|
break;
|
|
@@ -8286,10 +8286,10 @@ var require_Node = __commonJS({
|
|
|
8286
8286
|
if (node.nodeType === DOCUMENT_TYPE_NODE) utils.HierarchyRequestError();
|
|
8287
8287
|
}
|
|
8288
8288
|
} },
|
|
8289
|
-
insertBefore: { value: function insertBefore(node,
|
|
8289
|
+
insertBefore: { value: function insertBefore(node, child2) {
|
|
8290
8290
|
var parent = this;
|
|
8291
|
-
parent._ensureInsertValid(node,
|
|
8292
|
-
var refChild =
|
|
8291
|
+
parent._ensureInsertValid(node, child2, true);
|
|
8292
|
+
var refChild = child2;
|
|
8293
8293
|
if (refChild === node) {
|
|
8294
8294
|
refChild = node.nextSibling;
|
|
8295
8295
|
}
|
|
@@ -8297,28 +8297,28 @@ var require_Node = __commonJS({
|
|
|
8297
8297
|
node._insertOrReplace(parent, refChild, false);
|
|
8298
8298
|
return node;
|
|
8299
8299
|
} },
|
|
8300
|
-
appendChild: { value: function(
|
|
8301
|
-
return this.insertBefore(
|
|
8300
|
+
appendChild: { value: function(child2) {
|
|
8301
|
+
return this.insertBefore(child2, null);
|
|
8302
8302
|
} },
|
|
8303
|
-
_appendChild: { value: function(
|
|
8304
|
-
|
|
8303
|
+
_appendChild: { value: function(child2) {
|
|
8304
|
+
child2._insertOrReplace(this, null, false);
|
|
8305
8305
|
} },
|
|
8306
|
-
removeChild: { value: function removeChild(
|
|
8306
|
+
removeChild: { value: function removeChild(child2) {
|
|
8307
8307
|
var parent = this;
|
|
8308
|
-
if (!
|
|
8309
|
-
if (
|
|
8310
|
-
|
|
8311
|
-
return
|
|
8308
|
+
if (!child2.nodeType) throw new TypeError("not a node");
|
|
8309
|
+
if (child2.parentNode !== parent) utils.NotFoundError();
|
|
8310
|
+
child2.remove();
|
|
8311
|
+
return child2;
|
|
8312
8312
|
} },
|
|
8313
8313
|
// To replace a `child` with `node` within a `parent` (this)
|
|
8314
|
-
replaceChild: { value: function replaceChild(node,
|
|
8314
|
+
replaceChild: { value: function replaceChild(node, child2) {
|
|
8315
8315
|
var parent = this;
|
|
8316
|
-
parent._ensureInsertValid(node,
|
|
8316
|
+
parent._ensureInsertValid(node, child2, false);
|
|
8317
8317
|
if (node.doc !== parent.doc) {
|
|
8318
8318
|
parent.doc.adoptNode(node);
|
|
8319
8319
|
}
|
|
8320
|
-
node._insertOrReplace(parent,
|
|
8321
|
-
return
|
|
8320
|
+
node._insertOrReplace(parent, child2, true);
|
|
8321
|
+
return child2;
|
|
8322
8322
|
} },
|
|
8323
8323
|
// See: http://ejohn.org/blog/comparing-document-position/
|
|
8324
8324
|
contains: { value: function contains(node) {
|
|
@@ -8474,14 +8474,14 @@ var require_Node = __commonJS({
|
|
|
8474
8474
|
// or replace the specified child with this node, firing mutation events as
|
|
8475
8475
|
// necessary
|
|
8476
8476
|
_insertOrReplace: { value: function _insertOrReplace(parent, before, isReplace) {
|
|
8477
|
-
var
|
|
8478
|
-
if (
|
|
8477
|
+
var child2 = this, before_index, i;
|
|
8478
|
+
if (child2.nodeType === DOCUMENT_FRAGMENT_NODE && child2.rooted) {
|
|
8479
8479
|
utils.HierarchyRequestError();
|
|
8480
8480
|
}
|
|
8481
8481
|
if (parent._childNodes) {
|
|
8482
8482
|
before_index = before === null ? parent._childNodes.length : before.index;
|
|
8483
|
-
if (
|
|
8484
|
-
var child_index =
|
|
8483
|
+
if (child2.parentNode === parent) {
|
|
8484
|
+
var child_index = child2.index;
|
|
8485
8485
|
if (child_index < before_index) {
|
|
8486
8486
|
before_index--;
|
|
8487
8487
|
}
|
|
@@ -8495,10 +8495,10 @@ var require_Node = __commonJS({
|
|
|
8495
8495
|
if (n === null) {
|
|
8496
8496
|
n = parent.firstChild;
|
|
8497
8497
|
}
|
|
8498
|
-
var bothRooted =
|
|
8499
|
-
if (
|
|
8498
|
+
var bothRooted = child2.rooted && parent.rooted;
|
|
8499
|
+
if (child2.nodeType === DOCUMENT_FRAGMENT_NODE) {
|
|
8500
8500
|
var spliceArgs = [0, isReplace ? 1 : 0], next;
|
|
8501
|
-
for (var kid =
|
|
8501
|
+
for (var kid = child2.firstChild; kid !== null; kid = next) {
|
|
8502
8502
|
next = kid.nextSibling;
|
|
8503
8503
|
spliceArgs.push(kid);
|
|
8504
8504
|
kid.parentNode = parent;
|
|
@@ -8522,10 +8522,10 @@ var require_Node = __commonJS({
|
|
|
8522
8522
|
parent._firstChild = null;
|
|
8523
8523
|
}
|
|
8524
8524
|
}
|
|
8525
|
-
if (
|
|
8526
|
-
|
|
8525
|
+
if (child2._childNodes) {
|
|
8526
|
+
child2._childNodes.length = 0;
|
|
8527
8527
|
} else {
|
|
8528
|
-
|
|
8528
|
+
child2._firstChild = null;
|
|
8529
8529
|
}
|
|
8530
8530
|
if (parent.rooted) {
|
|
8531
8531
|
parent.modify();
|
|
@@ -8534,40 +8534,40 @@ var require_Node = __commonJS({
|
|
|
8534
8534
|
}
|
|
8535
8535
|
}
|
|
8536
8536
|
} else {
|
|
8537
|
-
if (before ===
|
|
8537
|
+
if (before === child2) {
|
|
8538
8538
|
return;
|
|
8539
8539
|
}
|
|
8540
8540
|
if (bothRooted) {
|
|
8541
|
-
|
|
8542
|
-
} else if (
|
|
8543
|
-
|
|
8541
|
+
child2._remove();
|
|
8542
|
+
} else if (child2.parentNode) {
|
|
8543
|
+
child2.remove();
|
|
8544
8544
|
}
|
|
8545
|
-
|
|
8545
|
+
child2.parentNode = parent;
|
|
8546
8546
|
if (isReplace) {
|
|
8547
|
-
LinkedList.replace(n,
|
|
8547
|
+
LinkedList.replace(n, child2);
|
|
8548
8548
|
if (parent._childNodes) {
|
|
8549
|
-
|
|
8550
|
-
parent._childNodes[before_index] =
|
|
8549
|
+
child2._index = before_index;
|
|
8550
|
+
parent._childNodes[before_index] = child2;
|
|
8551
8551
|
} else if (parent._firstChild === before) {
|
|
8552
|
-
parent._firstChild =
|
|
8552
|
+
parent._firstChild = child2;
|
|
8553
8553
|
}
|
|
8554
8554
|
} else {
|
|
8555
8555
|
if (n !== null) {
|
|
8556
|
-
LinkedList.insertBefore(
|
|
8556
|
+
LinkedList.insertBefore(child2, n);
|
|
8557
8557
|
}
|
|
8558
8558
|
if (parent._childNodes) {
|
|
8559
|
-
|
|
8560
|
-
parent._childNodes.splice(before_index, 0,
|
|
8559
|
+
child2._index = before_index;
|
|
8560
|
+
parent._childNodes.splice(before_index, 0, child2);
|
|
8561
8561
|
} else if (parent._firstChild === before) {
|
|
8562
|
-
parent._firstChild =
|
|
8562
|
+
parent._firstChild = child2;
|
|
8563
8563
|
}
|
|
8564
8564
|
}
|
|
8565
8565
|
if (bothRooted) {
|
|
8566
8566
|
parent.modify();
|
|
8567
|
-
parent.doc.mutateMove(
|
|
8567
|
+
parent.doc.mutateMove(child2);
|
|
8568
8568
|
} else if (parent.rooted) {
|
|
8569
8569
|
parent.modify();
|
|
8570
|
-
parent.doc.mutateInsert(
|
|
8570
|
+
parent.doc.mutateInsert(child2);
|
|
8571
8571
|
}
|
|
8572
8572
|
}
|
|
8573
8573
|
} },
|
|
@@ -8615,24 +8615,24 @@ var require_Node = __commonJS({
|
|
|
8615
8615
|
} },
|
|
8616
8616
|
normalize: { value: function() {
|
|
8617
8617
|
var next;
|
|
8618
|
-
for (var
|
|
8619
|
-
next =
|
|
8620
|
-
if (
|
|
8621
|
-
|
|
8618
|
+
for (var child2 = this.firstChild; child2 !== null; child2 = next) {
|
|
8619
|
+
next = child2.nextSibling;
|
|
8620
|
+
if (child2.normalize) {
|
|
8621
|
+
child2.normalize();
|
|
8622
8622
|
}
|
|
8623
|
-
if (
|
|
8623
|
+
if (child2.nodeType !== Node.TEXT_NODE) {
|
|
8624
8624
|
continue;
|
|
8625
8625
|
}
|
|
8626
|
-
if (
|
|
8627
|
-
this.removeChild(
|
|
8626
|
+
if (child2.nodeValue === "") {
|
|
8627
|
+
this.removeChild(child2);
|
|
8628
8628
|
continue;
|
|
8629
8629
|
}
|
|
8630
|
-
var prevChild =
|
|
8630
|
+
var prevChild = child2.previousSibling;
|
|
8631
8631
|
if (prevChild === null) {
|
|
8632
8632
|
continue;
|
|
8633
8633
|
} else if (prevChild.nodeType === Node.TEXT_NODE) {
|
|
8634
|
-
prevChild.appendData(
|
|
8635
|
-
this.removeChild(
|
|
8634
|
+
prevChild.appendData(child2.nodeValue);
|
|
8635
|
+
this.removeChild(child2);
|
|
8636
8636
|
}
|
|
8637
8637
|
}
|
|
8638
8638
|
} },
|
|
@@ -9247,7 +9247,7 @@ var require_select = __commonJS({
|
|
|
9247
9247
|
while ((el = el.previousSibling) && el.nodeType !== 1) ;
|
|
9248
9248
|
return el;
|
|
9249
9249
|
};
|
|
9250
|
-
var
|
|
9250
|
+
var child2 = function(el) {
|
|
9251
9251
|
if (el = el.firstChild) {
|
|
9252
9252
|
while (el.nodeType !== 1 && (el = el.nextSibling)) ;
|
|
9253
9253
|
}
|
|
@@ -9348,7 +9348,7 @@ var require_select = __commonJS({
|
|
|
9348
9348
|
};
|
|
9349
9349
|
};
|
|
9350
9350
|
var nth = function(param_, test, last) {
|
|
9351
|
-
var param = parseNth(param_), group = param.group, offset = param.offset, find2 = !last ?
|
|
9351
|
+
var param = parseNth(param_), group = param.group, offset = param.offset, find2 = !last ? child2 : lastChild, advance = !last ? next : prev;
|
|
9352
9352
|
return function(el) {
|
|
9353
9353
|
if (!parentIsElement(el)) return;
|
|
9354
9354
|
var rel = find2(el.parentNode), pos = 0;
|
|
@@ -11181,11 +11181,11 @@ var require_Leaf = __commonJS({
|
|
|
11181
11181
|
} },
|
|
11182
11182
|
firstChild: { value: null },
|
|
11183
11183
|
lastChild: { value: null },
|
|
11184
|
-
insertBefore: { value: function(node,
|
|
11184
|
+
insertBefore: { value: function(node, child2) {
|
|
11185
11185
|
if (!node.nodeType) throw new TypeError("not a node");
|
|
11186
11186
|
HierarchyRequestError();
|
|
11187
11187
|
} },
|
|
11188
|
-
replaceChild: { value: function(node,
|
|
11188
|
+
replaceChild: { value: function(node, child2) {
|
|
11189
11189
|
if (!node.nodeType) throw new TypeError("not a node");
|
|
11190
11190
|
HierarchyRequestError();
|
|
11191
11191
|
} },
|
|
@@ -11676,7 +11676,7 @@ var require_TreeWalker = __commonJS({
|
|
|
11676
11676
|
previous: "previousSibling"
|
|
11677
11677
|
};
|
|
11678
11678
|
function traverseChildren(tw, type) {
|
|
11679
|
-
var
|
|
11679
|
+
var child2, node, parent, result, sibling;
|
|
11680
11680
|
node = tw._currentNode[mapChild[type]];
|
|
11681
11681
|
while (node !== null) {
|
|
11682
11682
|
result = tw._internalFilter(node);
|
|
@@ -11685,9 +11685,9 @@ var require_TreeWalker = __commonJS({
|
|
|
11685
11685
|
return node;
|
|
11686
11686
|
}
|
|
11687
11687
|
if (result === NodeFilter.FILTER_SKIP) {
|
|
11688
|
-
|
|
11689
|
-
if (
|
|
11690
|
-
node =
|
|
11688
|
+
child2 = node[mapChild[type]];
|
|
11689
|
+
if (child2 !== null) {
|
|
11690
|
+
node = child2;
|
|
11691
11691
|
continue;
|
|
11692
11692
|
}
|
|
11693
11693
|
}
|
|
@@ -12184,9 +12184,9 @@ var require_URL = __commonJS({
|
|
|
12184
12184
|
},
|
|
12185
12185
|
// See: http://tools.ietf.org/html/rfc3986#section-5.2
|
|
12186
12186
|
// and https://url.spec.whatwg.org/#constructors
|
|
12187
|
-
resolve: function(
|
|
12187
|
+
resolve: function(relative5) {
|
|
12188
12188
|
var base = this;
|
|
12189
|
-
var r = new URL2(
|
|
12189
|
+
var r = new URL2(relative5);
|
|
12190
12190
|
var t = new URL2();
|
|
12191
12191
|
if (r.scheme !== void 0) {
|
|
12192
12192
|
t.scheme = r.scheme;
|
|
@@ -12220,7 +12220,7 @@ var require_URL = __commonJS({
|
|
|
12220
12220
|
if (r.path.charAt(0) === "/") {
|
|
12221
12221
|
t.path = remove_dot_segments(r.path);
|
|
12222
12222
|
} else {
|
|
12223
|
-
t.path =
|
|
12223
|
+
t.path = merge3(base.path, r.path);
|
|
12224
12224
|
t.path = remove_dot_segments(t.path);
|
|
12225
12225
|
}
|
|
12226
12226
|
t.query = r.query;
|
|
@@ -12229,7 +12229,7 @@ var require_URL = __commonJS({
|
|
|
12229
12229
|
}
|
|
12230
12230
|
t.fragment = r.fragment;
|
|
12231
12231
|
return t.toString();
|
|
12232
|
-
function
|
|
12232
|
+
function merge3(basepath, refpath) {
|
|
12233
12233
|
if (base.host !== void 0 && !base.path)
|
|
12234
12234
|
return "/" + refpath;
|
|
12235
12235
|
var lastslash = basepath.lastIndexOf("/");
|
|
@@ -13867,9 +13867,9 @@ var require_htmlelts = __commonJS({
|
|
|
13867
13867
|
get: function() {
|
|
13868
13868
|
var s = "";
|
|
13869
13869
|
for (var i = 0, n = this.childNodes.length; i < n; i++) {
|
|
13870
|
-
var
|
|
13871
|
-
if (
|
|
13872
|
-
s +=
|
|
13870
|
+
var child2 = this.childNodes[i];
|
|
13871
|
+
if (child2.nodeType === Node.TEXT_NODE)
|
|
13872
|
+
s += child2._data;
|
|
13873
13873
|
}
|
|
13874
13874
|
return s;
|
|
13875
13875
|
},
|
|
@@ -14830,20 +14830,20 @@ var require_Document = __commonJS({
|
|
|
14830
14830
|
this.documentElement = kid;
|
|
14831
14831
|
}
|
|
14832
14832
|
} },
|
|
14833
|
-
insertBefore: { value: function insertBefore(
|
|
14834
|
-
Node.prototype.insertBefore.call(this,
|
|
14833
|
+
insertBefore: { value: function insertBefore(child2, refChild) {
|
|
14834
|
+
Node.prototype.insertBefore.call(this, child2, refChild);
|
|
14835
14835
|
this._updateDocTypeElement();
|
|
14836
|
-
return
|
|
14836
|
+
return child2;
|
|
14837
14837
|
} },
|
|
14838
|
-
replaceChild: { value: function replaceChild(node,
|
|
14839
|
-
Node.prototype.replaceChild.call(this, node,
|
|
14838
|
+
replaceChild: { value: function replaceChild(node, child2) {
|
|
14839
|
+
Node.prototype.replaceChild.call(this, node, child2);
|
|
14840
14840
|
this._updateDocTypeElement();
|
|
14841
|
-
return
|
|
14841
|
+
return child2;
|
|
14842
14842
|
} },
|
|
14843
|
-
removeChild: { value: function removeChild(
|
|
14844
|
-
Node.prototype.removeChild.call(this,
|
|
14843
|
+
removeChild: { value: function removeChild(child2) {
|
|
14844
|
+
Node.prototype.removeChild.call(this, child2);
|
|
14845
14845
|
this._updateDocTypeElement();
|
|
14846
|
-
return
|
|
14846
|
+
return child2;
|
|
14847
14847
|
} },
|
|
14848
14848
|
getElementById: { value: function(id2) {
|
|
14849
14849
|
var n = this.byId[id2];
|
|
@@ -18469,7 +18469,7 @@ var require_HTMLParser = __commonJS({
|
|
|
18469
18469
|
}
|
|
18470
18470
|
}
|
|
18471
18471
|
function scanChars(shouldPauseFunc) {
|
|
18472
|
-
var codepoint, s,
|
|
18472
|
+
var codepoint, s, pattern2, eof;
|
|
18473
18473
|
while (nextchar < numchars) {
|
|
18474
18474
|
if (paused > 0 || shouldPauseFunc && shouldPauseFunc()) {
|
|
18475
18475
|
return true;
|
|
@@ -18530,10 +18530,10 @@ var require_HTMLParser = __commonJS({
|
|
|
18530
18530
|
break;
|
|
18531
18531
|
case "string":
|
|
18532
18532
|
codepoint = chars.charCodeAt(nextchar);
|
|
18533
|
-
|
|
18534
|
-
var pos = chars.indexOf(
|
|
18533
|
+
pattern2 = tokenizer.lookahead;
|
|
18534
|
+
var pos = chars.indexOf(pattern2, nextchar);
|
|
18535
18535
|
if (pos !== -1) {
|
|
18536
|
-
s = chars.substring(nextchar, pos +
|
|
18536
|
+
s = chars.substring(nextchar, pos + pattern2.length);
|
|
18537
18537
|
eof = false;
|
|
18538
18538
|
} else {
|
|
18539
18539
|
if (!input_complete) return true;
|
|
@@ -18641,9 +18641,9 @@ var require_HTMLParser = __commonJS({
|
|
|
18641
18641
|
}
|
|
18642
18642
|
ignore_linefeed = false;
|
|
18643
18643
|
}
|
|
18644
|
-
function getMatchingChars(
|
|
18645
|
-
|
|
18646
|
-
var match =
|
|
18644
|
+
function getMatchingChars(pattern2) {
|
|
18645
|
+
pattern2.lastIndex = nextchar - 1;
|
|
18646
|
+
var match = pattern2.exec(chars);
|
|
18647
18647
|
if (match && match.index === nextchar - 1) {
|
|
18648
18648
|
match = match[0];
|
|
18649
18649
|
nextchar += match.length - 1;
|
|
@@ -18656,9 +18656,9 @@ var require_HTMLParser = __commonJS({
|
|
|
18656
18656
|
throw new Error("should never happen");
|
|
18657
18657
|
}
|
|
18658
18658
|
}
|
|
18659
|
-
function emitCharsWhile(
|
|
18660
|
-
|
|
18661
|
-
var match =
|
|
18659
|
+
function emitCharsWhile(pattern2) {
|
|
18660
|
+
pattern2.lastIndex = nextchar - 1;
|
|
18661
|
+
var match = pattern2.exec(chars)[0];
|
|
18662
18662
|
if (!match) return false;
|
|
18663
18663
|
emitCharString(match);
|
|
18664
18664
|
nextchar += match.length - 1;
|
|
@@ -24465,14 +24465,14 @@ var require_turndown_cjs = __commonJS({
|
|
|
24465
24465
|
} else if (node.nodeType === 1) {
|
|
24466
24466
|
replacement = replacementForNode.call(self, node);
|
|
24467
24467
|
}
|
|
24468
|
-
return
|
|
24468
|
+
return join29(output, replacement);
|
|
24469
24469
|
}, "");
|
|
24470
24470
|
}
|
|
24471
24471
|
function postProcess(output) {
|
|
24472
24472
|
var self = this;
|
|
24473
24473
|
this.rules.forEach(function(rule) {
|
|
24474
24474
|
if (typeof rule.append === "function") {
|
|
24475
|
-
output =
|
|
24475
|
+
output = join29(output, rule.append(self.options));
|
|
24476
24476
|
}
|
|
24477
24477
|
});
|
|
24478
24478
|
return output.replace(/^[\t\r\n]+/, "").replace(/[\t\r\n\s]+$/, "");
|
|
@@ -24484,7 +24484,7 @@ var require_turndown_cjs = __commonJS({
|
|
|
24484
24484
|
if (whitespace.leading || whitespace.trailing) content = content.trim();
|
|
24485
24485
|
return whitespace.leading + rule.replacement(content, node, this.options) + whitespace.trailing;
|
|
24486
24486
|
}
|
|
24487
|
-
function
|
|
24487
|
+
function join29(output, replacement) {
|
|
24488
24488
|
var s1 = trimTrailingNewlines(output);
|
|
24489
24489
|
var s2 = trimLeadingNewlines(replacement);
|
|
24490
24490
|
var nls = Math.max(output.length - s1.length, replacement.length - s2.length);
|
|
@@ -29618,12 +29618,12 @@ var $ZodCheckUpperCase = /* @__PURE__ */ $constructor("$ZodCheckUpperCase", (ins
|
|
|
29618
29618
|
var $ZodCheckIncludes = /* @__PURE__ */ $constructor("$ZodCheckIncludes", (inst, def) => {
|
|
29619
29619
|
$ZodCheck.init(inst, def);
|
|
29620
29620
|
const escapedRegex = escapeRegex(def.includes);
|
|
29621
|
-
const
|
|
29622
|
-
def.pattern =
|
|
29621
|
+
const pattern2 = new RegExp(typeof def.position === "number" ? `^.{${def.position}}${escapedRegex}` : escapedRegex);
|
|
29622
|
+
def.pattern = pattern2;
|
|
29623
29623
|
inst._zod.onattach.push((inst2) => {
|
|
29624
29624
|
const bag = inst2._zod.bag;
|
|
29625
29625
|
bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set());
|
|
29626
|
-
bag.patterns.add(
|
|
29626
|
+
bag.patterns.add(pattern2);
|
|
29627
29627
|
});
|
|
29628
29628
|
inst._zod.check = (payload) => {
|
|
29629
29629
|
if (payload.value.includes(def.includes, def.position))
|
|
@@ -29641,12 +29641,12 @@ var $ZodCheckIncludes = /* @__PURE__ */ $constructor("$ZodCheckIncludes", (inst,
|
|
|
29641
29641
|
});
|
|
29642
29642
|
var $ZodCheckStartsWith = /* @__PURE__ */ $constructor("$ZodCheckStartsWith", (inst, def) => {
|
|
29643
29643
|
$ZodCheck.init(inst, def);
|
|
29644
|
-
const
|
|
29645
|
-
def.pattern ?? (def.pattern =
|
|
29644
|
+
const pattern2 = new RegExp(`^${escapeRegex(def.prefix)}.*`);
|
|
29645
|
+
def.pattern ?? (def.pattern = pattern2);
|
|
29646
29646
|
inst._zod.onattach.push((inst2) => {
|
|
29647
29647
|
const bag = inst2._zod.bag;
|
|
29648
29648
|
bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set());
|
|
29649
|
-
bag.patterns.add(
|
|
29649
|
+
bag.patterns.add(pattern2);
|
|
29650
29650
|
});
|
|
29651
29651
|
inst._zod.check = (payload) => {
|
|
29652
29652
|
if (payload.value.startsWith(def.prefix))
|
|
@@ -29664,12 +29664,12 @@ var $ZodCheckStartsWith = /* @__PURE__ */ $constructor("$ZodCheckStartsWith", (i
|
|
|
29664
29664
|
});
|
|
29665
29665
|
var $ZodCheckEndsWith = /* @__PURE__ */ $constructor("$ZodCheckEndsWith", (inst, def) => {
|
|
29666
29666
|
$ZodCheck.init(inst, def);
|
|
29667
|
-
const
|
|
29668
|
-
def.pattern ?? (def.pattern =
|
|
29667
|
+
const pattern2 = new RegExp(`.*${escapeRegex(def.suffix)}$`);
|
|
29668
|
+
def.pattern ?? (def.pattern = pattern2);
|
|
29669
29669
|
inst._zod.onattach.push((inst2) => {
|
|
29670
29670
|
const bag = inst2._zod.bag;
|
|
29671
29671
|
bag.patterns ?? (bag.patterns = /* @__PURE__ */ new Set());
|
|
29672
|
-
bag.patterns.add(
|
|
29672
|
+
bag.patterns.add(pattern2);
|
|
29673
29673
|
});
|
|
29674
29674
|
inst._zod.check = (payload) => {
|
|
29675
29675
|
if (payload.value.endsWith(def.suffix))
|
|
@@ -30351,7 +30351,7 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
|
|
|
30351
30351
|
return (payload, ctx) => fn(shape, payload, ctx);
|
|
30352
30352
|
};
|
|
30353
30353
|
let fastpass;
|
|
30354
|
-
const
|
|
30354
|
+
const isObject3 = isObject;
|
|
30355
30355
|
const jit = !globalConfig.jitless;
|
|
30356
30356
|
const allowsEval2 = allowsEval;
|
|
30357
30357
|
const fastEnabled = jit && allowsEval2.value;
|
|
@@ -30360,7 +30360,7 @@ var $ZodObject = /* @__PURE__ */ $constructor("$ZodObject", (inst, def) => {
|
|
|
30360
30360
|
inst._zod.parse = (payload, ctx) => {
|
|
30361
30361
|
value ?? (value = _normalized.value);
|
|
30362
30362
|
const input = payload.value;
|
|
30363
|
-
if (!
|
|
30363
|
+
if (!isObject3(input)) {
|
|
30364
30364
|
payload.issues.push({
|
|
30365
30365
|
expected: "object",
|
|
30366
30366
|
code: "invalid_type",
|
|
@@ -30777,8 +30777,8 @@ var $ZodOptional = /* @__PURE__ */ $constructor("$ZodOptional", (inst, def) => {
|
|
|
30777
30777
|
return def.innerType._zod.values ? /* @__PURE__ */ new Set([...def.innerType._zod.values, void 0]) : void 0;
|
|
30778
30778
|
});
|
|
30779
30779
|
defineLazy(inst._zod, "pattern", () => {
|
|
30780
|
-
const
|
|
30781
|
-
return
|
|
30780
|
+
const pattern2 = def.innerType._zod.pattern;
|
|
30781
|
+
return pattern2 ? new RegExp(`^(${cleanRegex(pattern2.source)})?$`) : void 0;
|
|
30782
30782
|
});
|
|
30783
30783
|
inst._zod.parse = (payload, ctx) => {
|
|
30784
30784
|
if (def.innerType._zod.optin === "optional") {
|
|
@@ -30795,8 +30795,8 @@ var $ZodNullable = /* @__PURE__ */ $constructor("$ZodNullable", (inst, def) => {
|
|
|
30795
30795
|
defineLazy(inst._zod, "optin", () => def.innerType._zod.optin);
|
|
30796
30796
|
defineLazy(inst._zod, "optout", () => def.innerType._zod.optout);
|
|
30797
30797
|
defineLazy(inst._zod, "pattern", () => {
|
|
30798
|
-
const
|
|
30799
|
-
return
|
|
30798
|
+
const pattern2 = def.innerType._zod.pattern;
|
|
30799
|
+
return pattern2 ? new RegExp(`^(${cleanRegex(pattern2.source)}|null)$`) : void 0;
|
|
30800
30800
|
});
|
|
30801
30801
|
defineLazy(inst._zod, "values", () => {
|
|
30802
30802
|
return def.innerType._zod.values ? /* @__PURE__ */ new Set([...def.innerType._zod.values, null]) : void 0;
|
|
@@ -31483,12 +31483,12 @@ function _length(length, params) {
|
|
|
31483
31483
|
length
|
|
31484
31484
|
});
|
|
31485
31485
|
}
|
|
31486
|
-
function _regex(
|
|
31486
|
+
function _regex(pattern2, params) {
|
|
31487
31487
|
return new $ZodCheckRegex({
|
|
31488
31488
|
check: "string_format",
|
|
31489
31489
|
format: "regex",
|
|
31490
31490
|
...normalizeParams(params),
|
|
31491
|
-
pattern
|
|
31491
|
+
pattern: pattern2
|
|
31492
31492
|
});
|
|
31493
31493
|
}
|
|
31494
31494
|
function _lowercase(params) {
|
|
@@ -31997,11 +31997,11 @@ var JSONSchemaGenerator = class {
|
|
|
31997
31997
|
}
|
|
31998
31998
|
case "template_literal": {
|
|
31999
31999
|
const json2 = _json;
|
|
32000
|
-
const
|
|
32001
|
-
if (!
|
|
32000
|
+
const pattern2 = schema._zod.pattern;
|
|
32001
|
+
if (!pattern2)
|
|
32002
32002
|
throw new Error("Pattern not found in template literal");
|
|
32003
32003
|
json2.type = "string";
|
|
32004
|
-
json2.pattern =
|
|
32004
|
+
json2.pattern = pattern2.source;
|
|
32005
32005
|
break;
|
|
32006
32006
|
}
|
|
32007
32007
|
case "pipe": {
|
|
@@ -35368,13 +35368,13 @@ function stringifyRegExpWithFlags(regex, refs) {
|
|
|
35368
35368
|
// `.` matches newlines
|
|
35369
35369
|
};
|
|
35370
35370
|
const source = flags.i ? regex.source.toLowerCase() : regex.source;
|
|
35371
|
-
let
|
|
35371
|
+
let pattern2 = "";
|
|
35372
35372
|
let isEscaped = false;
|
|
35373
35373
|
let inCharGroup = false;
|
|
35374
35374
|
let inCharRange = false;
|
|
35375
35375
|
for (let i = 0; i < source.length; i++) {
|
|
35376
35376
|
if (isEscaped) {
|
|
35377
|
-
|
|
35377
|
+
pattern2 += source[i];
|
|
35378
35378
|
isEscaped = false;
|
|
35379
35379
|
continue;
|
|
35380
35380
|
}
|
|
@@ -35382,40 +35382,40 @@ function stringifyRegExpWithFlags(regex, refs) {
|
|
|
35382
35382
|
if (inCharGroup) {
|
|
35383
35383
|
if (source[i].match(/[a-z]/)) {
|
|
35384
35384
|
if (inCharRange) {
|
|
35385
|
-
|
|
35386
|
-
|
|
35385
|
+
pattern2 += source[i];
|
|
35386
|
+
pattern2 += `${source[i - 2]}-${source[i]}`.toUpperCase();
|
|
35387
35387
|
inCharRange = false;
|
|
35388
35388
|
} else if (source[i + 1] === "-" && source[i + 2]?.match(/[a-z]/)) {
|
|
35389
|
-
|
|
35389
|
+
pattern2 += source[i];
|
|
35390
35390
|
inCharRange = true;
|
|
35391
35391
|
} else {
|
|
35392
|
-
|
|
35392
|
+
pattern2 += `${source[i]}${source[i].toUpperCase()}`;
|
|
35393
35393
|
}
|
|
35394
35394
|
continue;
|
|
35395
35395
|
}
|
|
35396
35396
|
} else if (source[i].match(/[a-z]/)) {
|
|
35397
|
-
|
|
35397
|
+
pattern2 += `[${source[i]}${source[i].toUpperCase()}]`;
|
|
35398
35398
|
continue;
|
|
35399
35399
|
}
|
|
35400
35400
|
}
|
|
35401
35401
|
if (flags.m) {
|
|
35402
35402
|
if (source[i] === "^") {
|
|
35403
|
-
|
|
35403
|
+
pattern2 += `(^|(?<=[\r
|
|
35404
35404
|
]))`;
|
|
35405
35405
|
continue;
|
|
35406
35406
|
} else if (source[i] === "$") {
|
|
35407
|
-
|
|
35407
|
+
pattern2 += `($|(?=[\r
|
|
35408
35408
|
]))`;
|
|
35409
35409
|
continue;
|
|
35410
35410
|
}
|
|
35411
35411
|
}
|
|
35412
35412
|
if (flags.s && source[i] === ".") {
|
|
35413
|
-
|
|
35413
|
+
pattern2 += inCharGroup ? `${source[i]}\r
|
|
35414
35414
|
` : `[${source[i]}\r
|
|
35415
35415
|
]`;
|
|
35416
35416
|
continue;
|
|
35417
35417
|
}
|
|
35418
|
-
|
|
35418
|
+
pattern2 += source[i];
|
|
35419
35419
|
if (source[i] === "\\") {
|
|
35420
35420
|
isEscaped = true;
|
|
35421
35421
|
} else if (inCharGroup && source[i] === "]") {
|
|
@@ -35425,12 +35425,12 @@ function stringifyRegExpWithFlags(regex, refs) {
|
|
|
35425
35425
|
}
|
|
35426
35426
|
}
|
|
35427
35427
|
try {
|
|
35428
|
-
new RegExp(
|
|
35428
|
+
new RegExp(pattern2);
|
|
35429
35429
|
} catch {
|
|
35430
35430
|
console.warn(`Could not convert regex pattern at ${refs.currentPath.join("/")} to a flag-independent form! Falling back to the flag-ignorant source`);
|
|
35431
35431
|
return regex.source;
|
|
35432
35432
|
}
|
|
35433
|
-
return
|
|
35433
|
+
return pattern2;
|
|
35434
35434
|
}
|
|
35435
35435
|
|
|
35436
35436
|
// node_modules/.pnpm/zod-to-json-schema@3.25.2_zod@3.25.76/node_modules/zod-to-json-schema/dist/esm/parsers/record.js
|
|
@@ -36608,7 +36608,7 @@ var Protocol = class {
|
|
|
36608
36608
|
return;
|
|
36609
36609
|
}
|
|
36610
36610
|
const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
|
|
36611
|
-
await new Promise((
|
|
36611
|
+
await new Promise((resolve8) => setTimeout(resolve8, pollInterval));
|
|
36612
36612
|
options?.signal?.throwIfAborted();
|
|
36613
36613
|
}
|
|
36614
36614
|
} catch (error2) {
|
|
@@ -36625,7 +36625,7 @@ var Protocol = class {
|
|
|
36625
36625
|
*/
|
|
36626
36626
|
request(request, resultSchema, options) {
|
|
36627
36627
|
const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
|
|
36628
|
-
return new Promise((
|
|
36628
|
+
return new Promise((resolve8, reject) => {
|
|
36629
36629
|
const earlyReject = (error2) => {
|
|
36630
36630
|
reject(error2);
|
|
36631
36631
|
};
|
|
@@ -36703,7 +36703,7 @@ var Protocol = class {
|
|
|
36703
36703
|
if (!parseResult.success) {
|
|
36704
36704
|
reject(parseResult.error);
|
|
36705
36705
|
} else {
|
|
36706
|
-
|
|
36706
|
+
resolve8(parseResult.data);
|
|
36707
36707
|
}
|
|
36708
36708
|
} catch (error2) {
|
|
36709
36709
|
reject(error2);
|
|
@@ -36964,12 +36964,12 @@ var Protocol = class {
|
|
|
36964
36964
|
}
|
|
36965
36965
|
} catch {
|
|
36966
36966
|
}
|
|
36967
|
-
return new Promise((
|
|
36967
|
+
return new Promise((resolve8, reject) => {
|
|
36968
36968
|
if (signal.aborted) {
|
|
36969
36969
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
36970
36970
|
return;
|
|
36971
36971
|
}
|
|
36972
|
-
const timeoutId = setTimeout(
|
|
36972
|
+
const timeoutId = setTimeout(resolve8, interval);
|
|
36973
36973
|
signal.addEventListener("abort", () => {
|
|
36974
36974
|
clearTimeout(timeoutId);
|
|
36975
36975
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
@@ -37927,46 +37927,46 @@ var UriTemplate = class _UriTemplate {
|
|
|
37927
37927
|
}
|
|
37928
37928
|
return patterns;
|
|
37929
37929
|
}
|
|
37930
|
-
let
|
|
37930
|
+
let pattern2;
|
|
37931
37931
|
const name = part.name;
|
|
37932
37932
|
switch (part.operator) {
|
|
37933
37933
|
case "":
|
|
37934
|
-
|
|
37934
|
+
pattern2 = part.exploded ? "([^/,]+(?:,[^/,]+)*)" : "([^/,]+)";
|
|
37935
37935
|
break;
|
|
37936
37936
|
case "+":
|
|
37937
37937
|
case "#":
|
|
37938
|
-
|
|
37938
|
+
pattern2 = "(.+)";
|
|
37939
37939
|
break;
|
|
37940
37940
|
case ".":
|
|
37941
|
-
|
|
37941
|
+
pattern2 = "\\.([^/,]+)";
|
|
37942
37942
|
break;
|
|
37943
37943
|
case "/":
|
|
37944
|
-
|
|
37944
|
+
pattern2 = "/" + (part.exploded ? "([^/,]+(?:,[^/,]+)*)" : "([^/,]+)");
|
|
37945
37945
|
break;
|
|
37946
37946
|
default:
|
|
37947
|
-
|
|
37947
|
+
pattern2 = "([^/]+)";
|
|
37948
37948
|
}
|
|
37949
|
-
patterns.push({ pattern, name });
|
|
37949
|
+
patterns.push({ pattern: pattern2, name });
|
|
37950
37950
|
return patterns;
|
|
37951
37951
|
}
|
|
37952
37952
|
match(uri) {
|
|
37953
37953
|
_UriTemplate.validateLength(uri, MAX_TEMPLATE_LENGTH, "URI");
|
|
37954
|
-
let
|
|
37954
|
+
let pattern2 = "^";
|
|
37955
37955
|
const names = [];
|
|
37956
37956
|
for (const part of this.parts) {
|
|
37957
37957
|
if (typeof part === "string") {
|
|
37958
|
-
|
|
37958
|
+
pattern2 += this.escapeRegExp(part);
|
|
37959
37959
|
} else {
|
|
37960
37960
|
const patterns = this.partToRegExp(part);
|
|
37961
37961
|
for (const { pattern: partPattern, name } of patterns) {
|
|
37962
|
-
|
|
37962
|
+
pattern2 += partPattern;
|
|
37963
37963
|
names.push({ name, exploded: part.exploded });
|
|
37964
37964
|
}
|
|
37965
37965
|
}
|
|
37966
37966
|
}
|
|
37967
|
-
|
|
37968
|
-
_UriTemplate.validateLength(
|
|
37969
|
-
const regex = new RegExp(
|
|
37967
|
+
pattern2 += "$";
|
|
37968
|
+
_UriTemplate.validateLength(pattern2, MAX_REGEX_LENGTH, "Generated regex pattern");
|
|
37969
|
+
const regex = new RegExp(pattern2);
|
|
37970
37970
|
const match = uri.match(regex);
|
|
37971
37971
|
if (!match)
|
|
37972
37972
|
return null;
|
|
@@ -38282,7 +38282,7 @@ var McpServer = class {
|
|
|
38282
38282
|
let task = createTaskResult.task;
|
|
38283
38283
|
const pollInterval = task.pollInterval ?? 5e3;
|
|
38284
38284
|
while (task.status !== "completed" && task.status !== "failed" && task.status !== "cancelled") {
|
|
38285
|
-
await new Promise((
|
|
38285
|
+
await new Promise((resolve8) => setTimeout(resolve8, pollInterval));
|
|
38286
38286
|
const updatedTask = await extra.taskStore.getTask(taskId);
|
|
38287
38287
|
if (!updatedTask) {
|
|
38288
38288
|
throw new McpError(ErrorCode.InternalError, `Task ${taskId} not found during polling`);
|
|
@@ -38970,12 +38970,12 @@ var StdioServerTransport = class {
|
|
|
38970
38970
|
this.onclose?.();
|
|
38971
38971
|
}
|
|
38972
38972
|
send(message) {
|
|
38973
|
-
return new Promise((
|
|
38973
|
+
return new Promise((resolve8) => {
|
|
38974
38974
|
const json2 = serializeMessage(message);
|
|
38975
38975
|
if (this._stdout.write(json2)) {
|
|
38976
|
-
|
|
38976
|
+
resolve8();
|
|
38977
38977
|
} else {
|
|
38978
|
-
this._stdout.once("drain",
|
|
38978
|
+
this._stdout.once("drain", resolve8);
|
|
38979
38979
|
}
|
|
38980
38980
|
});
|
|
38981
38981
|
}
|
|
@@ -39077,7 +39077,7 @@ var RETRYABLE_ERROR_PATTERNS = [
|
|
|
39077
39077
|
/changed during listing/i
|
|
39078
39078
|
];
|
|
39079
39079
|
function isRetryableError(errorMessage) {
|
|
39080
|
-
return RETRYABLE_ERROR_PATTERNS.some((
|
|
39080
|
+
return RETRYABLE_ERROR_PATTERNS.some((pattern2) => pattern2.test(errorMessage));
|
|
39081
39081
|
}
|
|
39082
39082
|
function sleep(ms) {
|
|
39083
39083
|
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
@@ -39161,8 +39161,8 @@ function parseErrorMessage(errorOutput) {
|
|
|
39161
39161
|
if (isPermissionDenied(errorOutput)) {
|
|
39162
39162
|
return PERMISSION_DENIED_MESSAGE;
|
|
39163
39163
|
}
|
|
39164
|
-
for (const { pattern, message } of ERROR_MAPPINGS) {
|
|
39165
|
-
const match = coreError.match(
|
|
39164
|
+
for (const { pattern: pattern2, message } of ERROR_MAPPINGS) {
|
|
39165
|
+
const match = coreError.match(pattern2);
|
|
39166
39166
|
if (match) {
|
|
39167
39167
|
let result = message;
|
|
39168
39168
|
for (let i = 1; i < match.length; i++) {
|
|
@@ -41540,10 +41540,10 @@ function previewFileInBundle(bundle, accountDir) {
|
|
|
41540
41540
|
const direct = [];
|
|
41541
41541
|
const nested = [];
|
|
41542
41542
|
for (const entry of boundedEntries(bundle, MAX_BUNDLE_ENTRIES) ?? []) {
|
|
41543
|
-
const
|
|
41544
|
-
if (!
|
|
41545
|
-
if (isRegularFile(
|
|
41546
|
-
else if (isDirectory(
|
|
41543
|
+
const child2 = realInside(join7(bundle, entry), accountDir);
|
|
41544
|
+
if (!child2) continue;
|
|
41545
|
+
if (isRegularFile(child2)) direct.push(child2);
|
|
41546
|
+
else if (isDirectory(child2)) nested.push(child2);
|
|
41547
41547
|
}
|
|
41548
41548
|
nested.sort((a, b) => generationRank(basename(b)) - generationRank(basename(a)));
|
|
41549
41549
|
const pick2 = (files) => files.find((f) => basename(f) === "Preview.png") ?? files.find((f) => PREVIEW_IMAGE_SUFFIXES.has(extname(f).toLowerCase())) ?? null;
|
|
@@ -41648,8 +41648,8 @@ function assembleAttachmentAssets(rows, bodyOrder, containerDir = NOTES_CONTAINE
|
|
|
41648
41648
|
const attachments = [];
|
|
41649
41649
|
for (const root of orderedRoots) {
|
|
41650
41650
|
attachments.push(record2(root, null));
|
|
41651
|
-
for (const
|
|
41652
|
-
attachments.push(record2(
|
|
41651
|
+
for (const child2 of rows.filter((r) => r.parentPk === root.pk && r !== root)) {
|
|
41652
|
+
attachments.push(record2(child2, root));
|
|
41653
41653
|
}
|
|
41654
41654
|
}
|
|
41655
41655
|
return { orderSource, attachments };
|
|
@@ -42644,8 +42644,8 @@ function getNoteLinkFromDB(coreDataId3) {
|
|
|
42644
42644
|
}
|
|
42645
42645
|
}
|
|
42646
42646
|
function extractCoreDataId(output, prefix) {
|
|
42647
|
-
const
|
|
42648
|
-
const match = output.match(
|
|
42647
|
+
const pattern2 = new RegExp(`${prefix} id ([^\\s]+)`);
|
|
42648
|
+
const match = output.match(pattern2);
|
|
42649
42649
|
return match ? match[1] : "";
|
|
42650
42650
|
}
|
|
42651
42651
|
var AppleNotesManager = class {
|
|
@@ -46643,9 +46643,9 @@ var NO_FDA_MESSAGE = `Resolving a Notes UUID or numeric key reads the Notes data
|
|
|
46643
46643
|
function canonicalKey(value) {
|
|
46644
46644
|
return BigInt(value).toString();
|
|
46645
46645
|
}
|
|
46646
|
-
function assertAll(values,
|
|
46646
|
+
function assertAll(values, pattern2, label) {
|
|
46647
46647
|
for (const value of values) {
|
|
46648
|
-
if (!
|
|
46648
|
+
if (!pattern2.test(value)) throw new Error(`Refusing to query with an invalid ${label}`);
|
|
46649
46649
|
}
|
|
46650
46650
|
}
|
|
46651
46651
|
function entityClause(entity3) {
|
|
@@ -46802,10 +46802,10 @@ function withStableIdentifiers(items, entity3, dbPath2 = NOTES_DB_PATH9) {
|
|
|
46802
46802
|
}
|
|
46803
46803
|
var defaultResolver = (values, entity3) => resolveIdentifiers(values, entity3);
|
|
46804
46804
|
var DEFAULT_MAX_ID_LENGTH = 2e3;
|
|
46805
|
-
function acceptAlternateForms(
|
|
46805
|
+
function acceptAlternateForms(pattern2) {
|
|
46806
46806
|
return new RegExp(
|
|
46807
|
-
`${
|
|
46808
|
-
|
|
46807
|
+
`${pattern2.source}|${UUID_PATTERN.source}|${NUMERIC_KEY_PATTERN.source}`,
|
|
46808
|
+
pattern2.flags
|
|
46809
46809
|
);
|
|
46810
46810
|
}
|
|
46811
46811
|
function resolveInSchema(values, entity3, ctx, resolver) {
|
|
@@ -46820,16 +46820,16 @@ function resolveInSchema(values, entity3, ctx, resolver) {
|
|
|
46820
46820
|
return null;
|
|
46821
46821
|
}
|
|
46822
46822
|
}
|
|
46823
|
-
function exactIdInput(entity3,
|
|
46823
|
+
function exactIdInput(entity3, pattern2, message, options = {}) {
|
|
46824
46824
|
const resolver = options.resolver ?? defaultResolver;
|
|
46825
|
-
return external_exports.string().max(options.maxLength ?? DEFAULT_MAX_ID_LENGTH).regex(acceptAlternateForms(
|
|
46825
|
+
return external_exports.string().max(options.maxLength ?? DEFAULT_MAX_ID_LENGTH).regex(acceptAlternateForms(pattern2), message).transform((value, ctx) => {
|
|
46826
46826
|
const map = resolveInSchema([value], entity3, ctx, resolver);
|
|
46827
46827
|
return map ? map.get(value) ?? value : external_exports.NEVER;
|
|
46828
46828
|
});
|
|
46829
46829
|
}
|
|
46830
|
-
function exactIdArrayInput(entity3,
|
|
46830
|
+
function exactIdArrayInput(entity3, pattern2, message, options = {}) {
|
|
46831
46831
|
const resolver = options.resolver ?? defaultResolver;
|
|
46832
|
-
const item = external_exports.string().max(options.maxLength ?? DEFAULT_MAX_ID_LENGTH).regex(acceptAlternateForms(
|
|
46832
|
+
const item = external_exports.string().max(options.maxLength ?? DEFAULT_MAX_ID_LENGTH).regex(acceptAlternateForms(pattern2), message);
|
|
46833
46833
|
const array2 = options.maxItems === void 0 ? external_exports.array(item) : external_exports.array(item).max(options.maxItems);
|
|
46834
46834
|
return array2.transform((values, ctx) => {
|
|
46835
46835
|
const map = resolveInSchema(values, entity3, ctx, resolver);
|
|
@@ -46933,13 +46933,6 @@ function describeSearchScope(searchContent, resultCount) {
|
|
|
46933
46933
|
return "\n\n\u2139\uFE0F Only note titles were searched, so a term that appears in note bodies would not match. Retry with `searchContent: true` to search bodies instead.";
|
|
46934
46934
|
}
|
|
46935
46935
|
|
|
46936
|
-
// src/utils/noteQueryStore.ts
|
|
46937
|
-
import { execFileSync as execFileSync14 } from "child_process";
|
|
46938
|
-
import * as fs8 from "fs";
|
|
46939
|
-
import * as os8 from "os";
|
|
46940
|
-
import * as path8 from "path";
|
|
46941
|
-
import { gunzipSync as gunzipSync8 } from "zlib";
|
|
46942
|
-
|
|
46943
46936
|
// src/utils/noteQuery.ts
|
|
46944
46937
|
var QUERY_LIMITS = {
|
|
46945
46938
|
/** Maximum number of tokens (terms, operators, parentheses). */
|
|
@@ -47043,12 +47036,12 @@ function tokenize(input) {
|
|
|
47043
47036
|
const field = prefix.toLowerCase();
|
|
47044
47037
|
let value = word.slice(colon + 1);
|
|
47045
47038
|
if (FIELDS.has(field)) {
|
|
47046
|
-
let
|
|
47039
|
+
let quoted2 = false;
|
|
47047
47040
|
if (value === "" && input[j] === '"') {
|
|
47048
47041
|
[value, j] = readQuoted(input, j);
|
|
47049
|
-
|
|
47042
|
+
quoted2 = true;
|
|
47050
47043
|
}
|
|
47051
|
-
push({ kind: "term", pos: i, field, value, quoted });
|
|
47044
|
+
push({ kind: "term", pos: i, field, value, quoted: quoted2 });
|
|
47052
47045
|
i = j;
|
|
47053
47046
|
continue;
|
|
47054
47047
|
}
|
|
@@ -47087,11 +47080,11 @@ function parseLocalDate(text2, pos) {
|
|
|
47087
47080
|
return { start: start.getTime(), end: new Date(year, month - 1, day + 1).getTime() };
|
|
47088
47081
|
}
|
|
47089
47082
|
function termNode(token) {
|
|
47090
|
-
const { field, value, quoted, pos } = token;
|
|
47083
|
+
const { field, value, quoted: quoted2, pos } = token;
|
|
47091
47084
|
if (field === void 0) {
|
|
47092
47085
|
if (value === "") throw new NoteQueryError("Empty quoted phrase", pos);
|
|
47093
47086
|
const lower2 = value.toLowerCase();
|
|
47094
|
-
if (!
|
|
47087
|
+
if (!quoted2 && FLAGS.includes(lower2)) {
|
|
47095
47088
|
return { type: "flag", flag: lower2 };
|
|
47096
47089
|
}
|
|
47097
47090
|
return { type: "text", field: "any", value };
|
|
@@ -47210,9 +47203,9 @@ var Parser = class {
|
|
|
47210
47203
|
if (token?.kind === "not") {
|
|
47211
47204
|
this.index++;
|
|
47212
47205
|
this.enter(token.pos);
|
|
47213
|
-
const
|
|
47206
|
+
const child2 = this.parseUnary();
|
|
47214
47207
|
this.depth--;
|
|
47215
|
-
return { type: "not", child };
|
|
47208
|
+
return { type: "not", child: child2 };
|
|
47216
47209
|
}
|
|
47217
47210
|
return this.parsePrimary();
|
|
47218
47211
|
}
|
|
@@ -47333,9 +47326,9 @@ function cheapFirst(children) {
|
|
|
47333
47326
|
function evaluateNoteQuery(node, note) {
|
|
47334
47327
|
switch (node.type) {
|
|
47335
47328
|
case "and":
|
|
47336
|
-
return cheapFirst(node.children).every((
|
|
47329
|
+
return cheapFirst(node.children).every((child2) => evaluateNoteQuery(child2, note));
|
|
47337
47330
|
case "or":
|
|
47338
|
-
return cheapFirst(node.children).some((
|
|
47331
|
+
return cheapFirst(node.children).some((child2) => evaluateNoteQuery(child2, note));
|
|
47339
47332
|
case "not":
|
|
47340
47333
|
return !evaluateNoteQuery(node.child, note);
|
|
47341
47334
|
case "text": {
|
|
@@ -47371,21 +47364,50 @@ function evaluateNoteQuery(node, note) {
|
|
|
47371
47364
|
}
|
|
47372
47365
|
}
|
|
47373
47366
|
}
|
|
47374
|
-
function
|
|
47367
|
+
function positiveTextPredicates(node, negated = false) {
|
|
47375
47368
|
switch (node.type) {
|
|
47376
47369
|
case "and":
|
|
47377
47370
|
case "or":
|
|
47378
|
-
return node.children.flatMap((
|
|
47371
|
+
return node.children.flatMap((child2) => positiveTextPredicates(child2, negated));
|
|
47379
47372
|
case "not":
|
|
47380
|
-
return
|
|
47373
|
+
return positiveTextPredicates(node.child, !negated);
|
|
47381
47374
|
case "text":
|
|
47382
|
-
return negated ? [] : [node.value];
|
|
47375
|
+
return negated ? [] : [{ field: node.field, value: node.value }];
|
|
47383
47376
|
default:
|
|
47384
47377
|
return [];
|
|
47385
47378
|
}
|
|
47386
47379
|
}
|
|
47380
|
+
function positiveTextTerms(node, negated = false) {
|
|
47381
|
+
return positiveTextPredicates(node, negated).map((predicate) => predicate.value);
|
|
47382
|
+
}
|
|
47383
|
+
function matchLocations(predicates, title, text2) {
|
|
47384
|
+
if (predicates.length === 0) return void 0;
|
|
47385
|
+
if (text2 === null && predicates.some((p) => p.field !== "title")) return void 0;
|
|
47386
|
+
const firstBreak = text2 === null ? -1 : text2.indexOf("\n");
|
|
47387
|
+
const titleLower = normalizeForMatch(title);
|
|
47388
|
+
const firstLineLower = text2 === null ? "" : normalizeForMatch(firstBreak === -1 ? text2 : text2.slice(0, firstBreak));
|
|
47389
|
+
const bodyLower = text2 === null || firstBreak === -1 ? "" : normalizeForMatch(text2.slice(firstBreak + 1));
|
|
47390
|
+
let inTitle = false;
|
|
47391
|
+
let inBody = false;
|
|
47392
|
+
for (const predicate of predicates) {
|
|
47393
|
+
const needle = normalizeForMatch(predicate.value);
|
|
47394
|
+
if (predicate.field !== "body" && !inTitle) {
|
|
47395
|
+
inTitle = titleLower.includes(needle) || firstLineLower.includes(needle);
|
|
47396
|
+
}
|
|
47397
|
+
if (predicate.field !== "title" && !inBody) inBody = bodyLower.includes(needle);
|
|
47398
|
+
}
|
|
47399
|
+
const locations = [];
|
|
47400
|
+
if (inTitle) locations.push("title");
|
|
47401
|
+
if (inBody) locations.push("body");
|
|
47402
|
+
return locations;
|
|
47403
|
+
}
|
|
47387
47404
|
|
|
47388
47405
|
// src/utils/noteQueryStore.ts
|
|
47406
|
+
import { execFileSync as execFileSync14 } from "child_process";
|
|
47407
|
+
import * as fs8 from "fs";
|
|
47408
|
+
import * as os8 from "os";
|
|
47409
|
+
import * as path8 from "path";
|
|
47410
|
+
import { gunzipSync as gunzipSync8 } from "zlib";
|
|
47389
47411
|
var NOTES_DB_PATH10 = path8.join(
|
|
47390
47412
|
os8.homedir(),
|
|
47391
47413
|
"Library/Group Containers/group.com.apple.notes/NoteStore.sqlite"
|
|
@@ -47467,6 +47489,15 @@ function decodeNoteBody(data) {
|
|
|
47467
47489
|
objectIds
|
|
47468
47490
|
};
|
|
47469
47491
|
}
|
|
47492
|
+
function decodeBodyHex(hex3) {
|
|
47493
|
+
try {
|
|
47494
|
+
return decodeNoteBody(
|
|
47495
|
+
new Uint8Array(gunzipSync8(Buffer.from(hex3, "hex"), { maxOutputLength: 32 * 1024 * 1024 }))
|
|
47496
|
+
);
|
|
47497
|
+
} catch {
|
|
47498
|
+
return null;
|
|
47499
|
+
}
|
|
47500
|
+
}
|
|
47470
47501
|
function countWords(text2) {
|
|
47471
47502
|
let count = 0;
|
|
47472
47503
|
for (const word of text2.replace(/\ufffc/gu, " ").split(/\s+/u)) {
|
|
@@ -47537,17 +47568,78 @@ function presentColumns2(dbPath2) {
|
|
|
47537
47568
|
}
|
|
47538
47569
|
return cols;
|
|
47539
47570
|
}
|
|
47571
|
+
function readStore(dbPath2, build) {
|
|
47572
|
+
if (!fs8.existsSync(dbPath2)) throw new NoteQueryStoreError(QUERY_FDA_MESSAGE, "no_fda");
|
|
47573
|
+
try {
|
|
47574
|
+
return runSqlite6(dbPath2, build(presentColumns2(dbPath2)));
|
|
47575
|
+
} catch (error2) {
|
|
47576
|
+
if (error2 instanceof NoteQueryStoreError) throw error2;
|
|
47577
|
+
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
47578
|
+
if (message.includes("authorization denied") || message.includes("unable to open database")) {
|
|
47579
|
+
throw new NoteQueryStoreError(QUERY_FDA_MESSAGE, "no_fda");
|
|
47580
|
+
}
|
|
47581
|
+
console.error(`query-notes: database read failed: ${message}`);
|
|
47582
|
+
throw new NoteQueryStoreError("Failed to read the Notes database.", "query_error");
|
|
47583
|
+
}
|
|
47584
|
+
}
|
|
47585
|
+
var NOTE_TEXT_BATCH_MAX = QUERY_RESULTS.MAX;
|
|
47586
|
+
function buildNoteTextsSql(available, pks) {
|
|
47587
|
+
const missing = ["Z_PK", "Z_ENT"].filter((c) => !available.has(c));
|
|
47588
|
+
if (missing.length) {
|
|
47589
|
+
throw new NoteQueryStoreError(
|
|
47590
|
+
`This macOS version's Notes database lacks columns search enrichment needs (${missing.join(", ")}).`,
|
|
47591
|
+
"schema"
|
|
47592
|
+
);
|
|
47593
|
+
}
|
|
47594
|
+
const keys = [...new Set(pks)];
|
|
47595
|
+
if (keys.length > NOTE_TEXT_BATCH_MAX) {
|
|
47596
|
+
throw new NoteQueryStoreError(
|
|
47597
|
+
`At most ${NOTE_TEXT_BATCH_MAX} notes can be read at once.`,
|
|
47598
|
+
"query_error"
|
|
47599
|
+
);
|
|
47600
|
+
}
|
|
47601
|
+
for (const pk of keys) {
|
|
47602
|
+
if (!Number.isSafeInteger(pk) || pk < 1) {
|
|
47603
|
+
throw new NoteQueryStoreError(`Invalid note key ${String(pk)}`, "query_error");
|
|
47604
|
+
}
|
|
47605
|
+
}
|
|
47606
|
+
const locked = available.has("ZISPASSWORDPROTECTED") ? "COALESCE(n.ZISPASSWORDPROTECTED, 0)" : "0";
|
|
47607
|
+
return [
|
|
47608
|
+
"BEGIN;",
|
|
47609
|
+
"SELECT json_object('k', 'meta', 'uuid', (SELECT Z_UUID FROM Z_METADATA LIMIT 1));",
|
|
47610
|
+
`SELECT json_object('k', 'note', 'pk', n.Z_PK, 'locked', ${locked}, 'data', (SELECT hex(d.ZDATA) FROM ZICNOTEDATA d WHERE d.ZNOTE = n.Z_PK ORDER BY d.Z_PK DESC LIMIT 1)) FROM ZICCLOUDSYNCINGOBJECT n WHERE n.Z_ENT = ${entity2("ICNote")} AND n.Z_PK IN (${keys.length ? keys.join(", ") : "NULL"});`,
|
|
47611
|
+
"COMMIT;"
|
|
47612
|
+
].join(" ");
|
|
47613
|
+
}
|
|
47614
|
+
function readNoteTexts(pks, options = {}) {
|
|
47615
|
+
const output = readStore(
|
|
47616
|
+
options.dbPath ?? NOTES_DB_PATH10,
|
|
47617
|
+
(available) => buildNoteTextsSql(available, pks)
|
|
47618
|
+
);
|
|
47619
|
+
let uuid2;
|
|
47620
|
+
const texts = /* @__PURE__ */ new Map();
|
|
47621
|
+
for (const line of output.split("\n")) {
|
|
47622
|
+
if (!line.trim()) continue;
|
|
47623
|
+
const row = JSON.parse(line);
|
|
47624
|
+
if (row.k === "meta") uuid2 = typeof row.uuid === "string" ? row.uuid : void 0;
|
|
47625
|
+
else if (row.k === "note" && typeof row.pk === "number") {
|
|
47626
|
+
const body = row.locked || !row.data ? null : decodeBodyHex(row.data);
|
|
47627
|
+
texts.set(row.pk, body ? body.text : null);
|
|
47628
|
+
}
|
|
47629
|
+
}
|
|
47630
|
+
return { uuid: uuid2, texts };
|
|
47631
|
+
}
|
|
47540
47632
|
var escapeSegment = escapeFolderName;
|
|
47541
47633
|
function resolveFolders(rows) {
|
|
47542
47634
|
const byPk = new Map(rows.map((row) => [row.pk, row]));
|
|
47543
47635
|
const resolved = /* @__PURE__ */ new Map();
|
|
47544
|
-
const
|
|
47636
|
+
const resolve8 = (pk, seen) => {
|
|
47545
47637
|
const cached2 = resolved.get(pk);
|
|
47546
47638
|
if (cached2) return cached2;
|
|
47547
47639
|
const row = byPk.get(pk);
|
|
47548
47640
|
if (!row || seen.has(pk)) return void 0;
|
|
47549
47641
|
seen.add(pk);
|
|
47550
|
-
const parent = row.parent !== null ?
|
|
47642
|
+
const parent = row.parent !== null ? resolve8(row.parent, seen) : void 0;
|
|
47551
47643
|
const name = row.name ?? "";
|
|
47552
47644
|
const path10 = parent ? `${parent.path}/${escapeSegment(name)}` : escapeSegment(name);
|
|
47553
47645
|
const plainPath = parent ? `${parent.plainPath}/${name}` : name;
|
|
@@ -47561,7 +47653,7 @@ function resolveFolders(rows) {
|
|
|
47561
47653
|
resolved.set(pk, info);
|
|
47562
47654
|
return info;
|
|
47563
47655
|
};
|
|
47564
|
-
for (const row of rows)
|
|
47656
|
+
for (const row of rows) resolve8(row.pk, /* @__PURE__ */ new Set());
|
|
47565
47657
|
return resolved;
|
|
47566
47658
|
}
|
|
47567
47659
|
var coreDataMs = (seconds) => seconds === null || !Number.isFinite(seconds) ? void 0 : CORE_DATA_EPOCH_MS2 + seconds * 1e3;
|
|
@@ -47593,23 +47685,10 @@ function runNoteQuery(ast, options = {}) {
|
|
|
47593
47685
|
const withBodies = needsContent(ast);
|
|
47594
47686
|
const withTags = needsTags(ast);
|
|
47595
47687
|
const dbPath2 = options.dbPath ?? NOTES_DB_PATH10;
|
|
47596
|
-
|
|
47597
|
-
|
|
47598
|
-
|
|
47599
|
-
|
|
47600
|
-
output = runSqlite6(
|
|
47601
|
-
dbPath2,
|
|
47602
|
-
buildScanSql(available, { scanLimit, includeDeleted, withBodies, withTags })
|
|
47603
|
-
);
|
|
47604
|
-
} catch (error2) {
|
|
47605
|
-
if (error2 instanceof NoteQueryStoreError) throw error2;
|
|
47606
|
-
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
47607
|
-
if (message.includes("authorization denied") || message.includes("unable to open database")) {
|
|
47608
|
-
throw new NoteQueryStoreError(QUERY_FDA_MESSAGE, "no_fda");
|
|
47609
|
-
}
|
|
47610
|
-
console.error(`query-notes: database read failed: ${message}`);
|
|
47611
|
-
throw new NoteQueryStoreError("Failed to read the Notes database.", "query_error");
|
|
47612
|
-
}
|
|
47688
|
+
const output = readStore(
|
|
47689
|
+
dbPath2,
|
|
47690
|
+
(available) => buildScanSql(available, { scanLimit, includeDeleted, withBodies, withTags })
|
|
47691
|
+
);
|
|
47613
47692
|
let uuid2;
|
|
47614
47693
|
let eligible = 0;
|
|
47615
47694
|
const folderRows = [];
|
|
@@ -47633,6 +47712,8 @@ function runNoteQuery(ast, options = {}) {
|
|
|
47633
47712
|
}
|
|
47634
47713
|
const folders = resolveFolders(folderRows);
|
|
47635
47714
|
const textTerms = positiveTextTerms(ast);
|
|
47715
|
+
const textPredicates = positiveTextPredicates(ast);
|
|
47716
|
+
const pendingWordCounts = [];
|
|
47636
47717
|
const hits = [];
|
|
47637
47718
|
let matched = 0;
|
|
47638
47719
|
let unreadable = 0;
|
|
@@ -47650,15 +47731,7 @@ function runNoteQuery(ast, options = {}) {
|
|
|
47650
47731
|
if (withBodies) unreadable++;
|
|
47651
47732
|
return decoded;
|
|
47652
47733
|
}
|
|
47653
|
-
|
|
47654
|
-
decoded = decodeNoteBody(
|
|
47655
|
-
new Uint8Array(
|
|
47656
|
-
gunzipSync8(Buffer.from(row.data, "hex"), { maxOutputLength: 32 * 1024 * 1024 })
|
|
47657
|
-
)
|
|
47658
|
-
);
|
|
47659
|
-
} catch {
|
|
47660
|
-
decoded = null;
|
|
47661
|
-
}
|
|
47734
|
+
decoded = decodeBodyHex(row.data);
|
|
47662
47735
|
if (!decoded) unreadable++;
|
|
47663
47736
|
return decoded;
|
|
47664
47737
|
};
|
|
@@ -47699,6 +47772,8 @@ function runNoteQuery(ast, options = {}) {
|
|
|
47699
47772
|
matched++;
|
|
47700
47773
|
if (hits.length >= limit) continue;
|
|
47701
47774
|
const body = locked ? null : decode2();
|
|
47775
|
+
const matchedIn = matchLocations(textPredicates, row.title ?? "", body ? body.text : null);
|
|
47776
|
+
if (options.includeWordCount && !withBodies) pendingWordCounts.push(row.pk);
|
|
47702
47777
|
hits.push({
|
|
47703
47778
|
id: `x-coredata://${uuid2}/ICNote/p${row.pk}`,
|
|
47704
47779
|
title: row.title ?? "",
|
|
@@ -47707,7 +47782,16 @@ function runNoteQuery(ast, options = {}) {
|
|
|
47707
47782
|
...note.modified !== void 0 ? { modified: new Date(note.modified).toISOString() } : {},
|
|
47708
47783
|
...note.created !== void 0 ? { created: new Date(note.created).toISOString() } : {},
|
|
47709
47784
|
snippet: locked ? "" : body ? buildSnippet(body.text, textTerms) : (row.snippet ?? "").replace(/\s+/gu, " ").trim(),
|
|
47710
|
-
...locked ? { locked: true } : {}
|
|
47785
|
+
...locked ? { locked: true } : {},
|
|
47786
|
+
...matchedIn ? { matchedIn } : {},
|
|
47787
|
+
...options.includeWordCount && withBodies ? { wordCount: body ? countWords(body.text) : null } : {}
|
|
47788
|
+
});
|
|
47789
|
+
}
|
|
47790
|
+
if (pendingWordCounts.length) {
|
|
47791
|
+
const { texts } = readNoteTexts(pendingWordCounts, { dbPath: dbPath2 });
|
|
47792
|
+
pendingWordCounts.forEach((pk, index) => {
|
|
47793
|
+
const text2 = texts.get(pk);
|
|
47794
|
+
hits[index].wordCount = typeof text2 === "string" ? countWords(text2) : null;
|
|
47711
47795
|
});
|
|
47712
47796
|
}
|
|
47713
47797
|
return {
|
|
@@ -47750,6 +47834,7 @@ function searchContentViaDatabase(options) {
|
|
|
47750
47834
|
const result = runNoteQuery(buildSearchContentQuery(options), {
|
|
47751
47835
|
limit: options.limit,
|
|
47752
47836
|
scanLimit: QUERY_SCAN.MAX,
|
|
47837
|
+
includeWordCount: options.includeWordCount,
|
|
47753
47838
|
dbPath: options.dbPath
|
|
47754
47839
|
});
|
|
47755
47840
|
const notes = result.notes.map((hit) => ({
|
|
@@ -47760,7 +47845,9 @@ function searchContentViaDatabase(options) {
|
|
|
47760
47845
|
created: hit.created ? new Date(hit.created) : /* @__PURE__ */ new Date(0),
|
|
47761
47846
|
modified: hit.modified ? new Date(hit.modified) : /* @__PURE__ */ new Date(0),
|
|
47762
47847
|
...hit.folder !== void 0 ? { folder: hit.folder } : {},
|
|
47763
|
-
...hit.account !== void 0 ? { account: hit.account } : {}
|
|
47848
|
+
...hit.account !== void 0 ? { account: hit.account } : {},
|
|
47849
|
+
...hit.matchedIn ? { matchedIn: hit.matchedIn } : {},
|
|
47850
|
+
...hit.wordCount !== void 0 ? { wordCount: hit.wordCount } : {}
|
|
47764
47851
|
}));
|
|
47765
47852
|
return {
|
|
47766
47853
|
notes,
|
|
@@ -47783,6 +47870,55 @@ function contentSearchFailureHint(message, dbUnavailable) {
|
|
|
47783
47870
|
const remedy = dbUnavailable === "no_fda" ? " Grant Full Disk Access to the Node binary running this server (run the doctor tool for its path) so search-notes can search note bodies through the Notes database instead, which takes well under a second." : "";
|
|
47784
47871
|
return `${message} Body search through AppleScript scans every note body before the result limit applies, so a broad term can exceed the time budget on a large library.${remedy} Otherwise narrow the search with \`folder\` or \`modifiedSince\`, or use a more specific term.`;
|
|
47785
47872
|
}
|
|
47873
|
+
var NOTE_ID = /^x-coredata:\/\/([0-9A-Fa-f-]+)\/ICNote\/p(\d{1,15})$/;
|
|
47874
|
+
function addWordCountsFromDatabase(notes, query2, options = {}) {
|
|
47875
|
+
const keys = /* @__PURE__ */ new Map();
|
|
47876
|
+
for (const note of notes) {
|
|
47877
|
+
const match = NOTE_ID.exec(note.id ?? "");
|
|
47878
|
+
if (match) keys.set(note, { store: match[1].toUpperCase(), pk: Number(match[2]) });
|
|
47879
|
+
}
|
|
47880
|
+
const pks = [...new Set([...keys.values()].map((key) => key.pk))];
|
|
47881
|
+
let store;
|
|
47882
|
+
const texts = /* @__PURE__ */ new Map();
|
|
47883
|
+
try {
|
|
47884
|
+
for (let start = 0; start < pks.length; start += NOTE_TEXT_BATCH_MAX) {
|
|
47885
|
+
const read = readNoteTexts(pks.slice(start, start + NOTE_TEXT_BATCH_MAX), options);
|
|
47886
|
+
store = read.uuid?.toUpperCase();
|
|
47887
|
+
for (const [pk, text2] of read.texts) texts.set(pk, text2);
|
|
47888
|
+
}
|
|
47889
|
+
} catch (error2) {
|
|
47890
|
+
if (error2 instanceof NoteQueryStoreError) return { notes, unavailable: error2.kind };
|
|
47891
|
+
throw error2;
|
|
47892
|
+
}
|
|
47893
|
+
const predicates = [{ field: "any", value: query2 }];
|
|
47894
|
+
return {
|
|
47895
|
+
notes: notes.map((note) => {
|
|
47896
|
+
const key = keys.get(note);
|
|
47897
|
+
const text2 = key && key.store === store ? texts.get(key.pk) : void 0;
|
|
47898
|
+
if (typeof text2 !== "string") return { ...note, wordCount: null };
|
|
47899
|
+
const matchedIn = matchLocations(predicates, note.title, text2);
|
|
47900
|
+
return {
|
|
47901
|
+
...note,
|
|
47902
|
+
...matchedIn?.length ? { matchedIn } : {},
|
|
47903
|
+
wordCount: countWords(text2)
|
|
47904
|
+
};
|
|
47905
|
+
})
|
|
47906
|
+
};
|
|
47907
|
+
}
|
|
47908
|
+
function describeMatchDetails(hit) {
|
|
47909
|
+
const parts = [];
|
|
47910
|
+
if (hit.matchedIn) {
|
|
47911
|
+
parts.push(
|
|
47912
|
+
hit.matchedIn.length ? `matched in ${hit.matchedIn.join(", ")}` : "no text match (metadata)"
|
|
47913
|
+
);
|
|
47914
|
+
}
|
|
47915
|
+
if (hit.wordCount !== void 0) {
|
|
47916
|
+
parts.push(
|
|
47917
|
+
hit.wordCount === null ? "word count unavailable" : `${hit.wordCount} word${hit.wordCount === 1 ? "" : "s"}`
|
|
47918
|
+
);
|
|
47919
|
+
}
|
|
47920
|
+
return parts.map((part) => ` \xB7 ${part}`).join("");
|
|
47921
|
+
}
|
|
47786
47922
|
|
|
47787
47923
|
// src/tools/doctor.ts
|
|
47788
47924
|
import { spawnSync } from "child_process";
|
|
@@ -48232,8 +48368,8 @@ function validateAppendContent(content, format, options = {}) {
|
|
|
48232
48368
|
if (/!\[|<\/?[a-z]|\]\(\s*(?:javascript|data|file):/i.test(checked))
|
|
48233
48369
|
throw new Error("Markdown images, raw HTML and local/executable links are unsupported");
|
|
48234
48370
|
const withoutLinkDestinations = checked.replace(/(\[[^\]\n]+\])\([^()\s]+\)/g, "$1()");
|
|
48235
|
-
for (const [
|
|
48236
|
-
if (
|
|
48371
|
+
for (const [pattern2, name] of UNMODELED_MARKDOWN)
|
|
48372
|
+
if (pattern2.test(name === UNDERSCORES_OUTSIDE_A_WORD ? withoutLinkDestinations : checked))
|
|
48237
48373
|
throw new Error(
|
|
48238
48374
|
`Markdown cannot use ${name}; Notes would change that text, so the result could not be verified`
|
|
48239
48375
|
);
|
|
@@ -49333,7 +49469,7 @@ function selectParagraph(paragraphs, selector) {
|
|
|
49333
49469
|
);
|
|
49334
49470
|
return matches[occurrence - 1];
|
|
49335
49471
|
}
|
|
49336
|
-
var
|
|
49472
|
+
var NOTE_ID2 = /^x-coredata:\/\/[0-9a-f-]+\/ICNote\/p([0-9]{1,15})$/i;
|
|
49337
49473
|
function titleMatchSql(columns) {
|
|
49338
49474
|
return `SELECT json_object('pk', n.Z_PK, 'folder', n.ZFOLDER) FROM ZICCLOUDSYNCINGOBJECT n LEFT JOIN ZICCLOUDSYNCINGOBJECT f ON f.Z_PK = n.ZFOLDER WHERE n.Z_ENT = ${entity("ICNote")} AND n.ZTITLE1 = CAST(@title AS TEXT) AND ${activeNoteSql(columns, "n", "f")} ORDER BY n.Z_PK;`;
|
|
49339
49475
|
}
|
|
@@ -49344,7 +49480,7 @@ function checkNoteSelector(selector) {
|
|
|
49344
49480
|
if (selector.folder !== void 0 && selector.title === void 0)
|
|
49345
49481
|
throw new ParagraphLinkError("invalid-argument", "folder only narrows a title lookup");
|
|
49346
49482
|
if (selector.id === void 0) return void 0;
|
|
49347
|
-
const pk =
|
|
49483
|
+
const pk = NOTE_ID2.exec(selector.id)?.[1];
|
|
49348
49484
|
if (!pk)
|
|
49349
49485
|
throw new ParagraphLinkError(
|
|
49350
49486
|
"invalid-argument",
|
|
@@ -49759,8 +49895,8 @@ function describeBodyReadFailure(title, error2, attachments) {
|
|
|
49759
49895
|
const kind = classifyBodyReadError(error2);
|
|
49760
49896
|
if (kind === "other") return base;
|
|
49761
49897
|
const large = attachments ? largeAttachments(attachments) : [];
|
|
49762
|
-
const
|
|
49763
|
-
const holds = large.length > 0 ? `The note holds ${large.length === 1 ? "a large attachment" : "large attachments"} (${
|
|
49898
|
+
const listed2 = large.map((a) => `${a.name}, ${formatBytes2(a.bytes)}`).join("; ");
|
|
49899
|
+
const holds = large.length > 0 ? `The note holds ${large.length === 1 ? "a large attachment" : "large attachments"} (${listed2}). ` : "";
|
|
49764
49900
|
if (kind === "buffer") {
|
|
49765
49901
|
const cause2 = `${holds}Notes.app returns images inside the note body as base64, so a large image makes the body bigger than this server can read in one call.`;
|
|
49766
49902
|
const remedy2 = "Retrying, or a longer timeoutSeconds, will not help. Remove or shrink the attachment in Notes.app, or delete the note there; delete-note needs a successful read to verify the note first.";
|
|
@@ -50097,8 +50233,8 @@ function insertLink(request, deps) {
|
|
|
50097
50233
|
}
|
|
50098
50234
|
|
|
50099
50235
|
// src/services/notesExport.ts
|
|
50100
|
-
import { mkdirSync as
|
|
50101
|
-
import { basename as basename4, dirname as dirname6, extname as
|
|
50236
|
+
import { mkdirSync as mkdirSync6 } from "node:fs";
|
|
50237
|
+
import { basename as basename4, dirname as dirname6, extname as extname5, join as join22 } from "node:path";
|
|
50102
50238
|
|
|
50103
50239
|
// src/utils/exportAssets.ts
|
|
50104
50240
|
import {
|
|
@@ -50288,8 +50424,8 @@ var AssetLocator = class {
|
|
|
50288
50424
|
/** Preview.png (or another image) at most two levels inside a bundle. */
|
|
50289
50425
|
bundleImage(bundle, account) {
|
|
50290
50426
|
const found = [];
|
|
50291
|
-
for (const
|
|
50292
|
-
const path10 = confine(join19(bundle,
|
|
50427
|
+
for (const child2 of listDirectory(bundle, MAX_BUNDLE_ENTRIES2)) {
|
|
50428
|
+
const path10 = confine(join19(bundle, child2), account);
|
|
50293
50429
|
if (!path10) continue;
|
|
50294
50430
|
if (isFile(path10)) found.push(path10);
|
|
50295
50431
|
else
|
|
@@ -50624,7 +50760,7 @@ function planAttachment(attachment, ctx) {
|
|
|
50624
50760
|
ctx.stats.attachments--;
|
|
50625
50761
|
return {
|
|
50626
50762
|
type: "gallery",
|
|
50627
|
-
items: attachment.children.map((
|
|
50763
|
+
items: attachment.children.map((child2) => planAttachment(child2, ctx))
|
|
50628
50764
|
};
|
|
50629
50765
|
}
|
|
50630
50766
|
case "link": {
|
|
@@ -51196,9 +51332,9 @@ function wrapMarkdown(markdown, width) {
|
|
|
51196
51332
|
}
|
|
51197
51333
|
return out.join("\n");
|
|
51198
51334
|
}
|
|
51199
|
-
function renderNotesMarkdown(notes, ctx, { wrap:
|
|
51335
|
+
function renderNotesMarkdown(notes, ctx, { wrap: wrap3 = 0 } = {}) {
|
|
51200
51336
|
const body = notes.map((note) => renderNoteMarkdown(note, ctx)).join(NOTE_SEPARATOR);
|
|
51201
|
-
return (
|
|
51337
|
+
return (wrap3 ? wrapMarkdown(body, wrap3) : body) + (notes.length ? "\n" : "");
|
|
51202
51338
|
}
|
|
51203
51339
|
|
|
51204
51340
|
// src/utils/noteExportData.ts
|
|
@@ -51372,18 +51508,1290 @@ function readExportNote(id2, { dbPath: dbPath2 = NOTES_DB_PATH11 } = {}) {
|
|
|
51372
51508
|
ordered
|
|
51373
51509
|
};
|
|
51374
51510
|
}
|
|
51511
|
+
var CORE_DATA_EPOCH = 978307200;
|
|
51512
|
+
function coreDataDate(value) {
|
|
51513
|
+
const seconds = typeof value === "number" ? value : typeof value === "string" && value.trim() ? Number(value) : NaN;
|
|
51514
|
+
if (!Number.isFinite(seconds) || Math.abs(seconds) > 1e10) return void 0;
|
|
51515
|
+
return new Date((seconds + CORE_DATA_EPOCH) * 1e3).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
51516
|
+
}
|
|
51517
|
+
function noteMetaQuery(columns) {
|
|
51518
|
+
const first2 = (names) => {
|
|
51519
|
+
const present = names.filter((name) => columns.has(name)).map((name) => `n.${name}`);
|
|
51520
|
+
if (!present.length) return "NULL";
|
|
51521
|
+
return present.length === 1 ? present[0] : `COALESCE(${present.join(", ")})`;
|
|
51522
|
+
};
|
|
51523
|
+
const accountColumns = [...columns].filter((name) => /^ZACCOUNT\d*$/.test(name)).sort((a, b) => Number(b.slice(8) || 0) - Number(a.slice(8) || 0));
|
|
51524
|
+
const folder = columns.has("ZFOLDER") && columns.has("ZTITLE2") ? "(SELECT f.ZTITLE2 FROM ZICCLOUDSYNCINGOBJECT f WHERE f.Z_PK = n.ZFOLDER)" : "NULL";
|
|
51525
|
+
const account = columns.has("ZNAME") && accountColumns.length ? `(SELECT a.ZNAME FROM ZICCLOUDSYNCINGOBJECT a WHERE a.Z_PK = ${first2(accountColumns)})` : "NULL";
|
|
51526
|
+
return `SELECT json_object('uuid', ${first2(["ZIDENTIFIER"])}, 'created', ${first2(["ZCREATIONDATE3", "ZCREATIONDATE1", "ZCREATIONDATE"])}, 'modified', ${first2(["ZMODIFICATIONDATE1", "ZMODIFICATIONDATE"])}, 'folder', ${folder}, 'account', ${account}) FROM ZICCLOUDSYNCINGOBJECT n WHERE n.Z_PK = @pk;`;
|
|
51527
|
+
}
|
|
51528
|
+
function readExportNoteMeta(id2, { dbPath: dbPath2 = NOTES_DB_PATH11 } = {}) {
|
|
51529
|
+
const match = /\/ICNote\/p([0-9]{1,18})$/.exec(id2);
|
|
51530
|
+
if (!match) throw new NoteBlocksError("invalid-id", "Not a note id");
|
|
51531
|
+
const output = sqlite(dbPath2, [
|
|
51532
|
+
"-cmd",
|
|
51533
|
+
".parameter init",
|
|
51534
|
+
"-cmd",
|
|
51535
|
+
`.parameter set @pk ${match[1]}`,
|
|
51536
|
+
noteMetaQuery(objectColumns(dbPath2))
|
|
51537
|
+
]);
|
|
51538
|
+
if (!output) return {};
|
|
51539
|
+
let row;
|
|
51540
|
+
try {
|
|
51541
|
+
row = JSON.parse(output);
|
|
51542
|
+
} catch {
|
|
51543
|
+
throw new NoteBlocksError("query-failed", "Unexpected Notes database response");
|
|
51544
|
+
}
|
|
51545
|
+
const meta = {};
|
|
51546
|
+
const set = (key, value) => {
|
|
51547
|
+
if (value !== void 0) meta[key] = value;
|
|
51548
|
+
};
|
|
51549
|
+
set("uuid", text(row.uuid));
|
|
51550
|
+
set("created", coreDataDate(row.created));
|
|
51551
|
+
set("modified", coreDataDate(row.modified));
|
|
51552
|
+
set("folder", text(row.folder));
|
|
51553
|
+
set("account", text(row.account));
|
|
51554
|
+
return meta;
|
|
51555
|
+
}
|
|
51556
|
+
|
|
51557
|
+
// src/utils/markdownTemplate.ts
|
|
51558
|
+
var TEMPLATE_SCHEMA_VERSION = 1;
|
|
51559
|
+
var MAX_TEMPLATE_BYTES = 256 * 1024;
|
|
51560
|
+
var MAX_META_LENGTH = 512;
|
|
51561
|
+
var MAX_RULE_TEXT = 4096;
|
|
51562
|
+
var MAX_DIRECTORY_LENGTH = 1024;
|
|
51563
|
+
var RULE_IDS = [
|
|
51564
|
+
"document.header",
|
|
51565
|
+
"document.footer",
|
|
51566
|
+
"document.separator",
|
|
51567
|
+
"block.title",
|
|
51568
|
+
"block.heading",
|
|
51569
|
+
"block.subheading",
|
|
51570
|
+
"block.body",
|
|
51571
|
+
"block.bulleted",
|
|
51572
|
+
"block.dashed",
|
|
51573
|
+
"block.numbered",
|
|
51574
|
+
"block.checklist.checked",
|
|
51575
|
+
"block.checklist.unchecked",
|
|
51576
|
+
"block.code",
|
|
51577
|
+
"paragraph.quote",
|
|
51578
|
+
"inline.bold",
|
|
51579
|
+
"inline.italic",
|
|
51580
|
+
"inline.underline",
|
|
51581
|
+
"inline.strikethrough",
|
|
51582
|
+
"inline.superscript",
|
|
51583
|
+
"inline.subscript",
|
|
51584
|
+
"inline.highlight.purple",
|
|
51585
|
+
"inline.highlight.pink",
|
|
51586
|
+
"inline.highlight.orange",
|
|
51587
|
+
"inline.highlight.mint",
|
|
51588
|
+
"inline.highlight.blue",
|
|
51589
|
+
"inline.highlight.other",
|
|
51590
|
+
"inline.color",
|
|
51591
|
+
"inline.link",
|
|
51592
|
+
"attachment.image",
|
|
51593
|
+
"attachment.drawing.classic",
|
|
51594
|
+
"attachment.drawing.paper",
|
|
51595
|
+
"attachment.scan",
|
|
51596
|
+
"attachment.pdf",
|
|
51597
|
+
"attachment.audio",
|
|
51598
|
+
"attachment.video",
|
|
51599
|
+
"attachment.other",
|
|
51600
|
+
"attachment.table",
|
|
51601
|
+
"attachment.divider",
|
|
51602
|
+
"attachment.gallery",
|
|
51603
|
+
"attachment.url",
|
|
51604
|
+
"attachment.url.image",
|
|
51605
|
+
"attachment.map",
|
|
51606
|
+
"attachment.placeholder"
|
|
51607
|
+
];
|
|
51608
|
+
var RULE_MODES = ["wrap", "linePrefix", "pattern", "plain", "omit"];
|
|
51609
|
+
var INLINE_FORMATS = [
|
|
51610
|
+
"subscript",
|
|
51611
|
+
"superscript",
|
|
51612
|
+
"highlight",
|
|
51613
|
+
"underline",
|
|
51614
|
+
"strikethrough",
|
|
51615
|
+
"bold",
|
|
51616
|
+
"italic",
|
|
51617
|
+
"color",
|
|
51618
|
+
"link"
|
|
51619
|
+
];
|
|
51620
|
+
var PLACEHOLDERS = [
|
|
51621
|
+
"content",
|
|
51622
|
+
"title",
|
|
51623
|
+
"id",
|
|
51624
|
+
"uuid",
|
|
51625
|
+
"folder",
|
|
51626
|
+
"account",
|
|
51627
|
+
"created",
|
|
51628
|
+
"modified",
|
|
51629
|
+
"tags",
|
|
51630
|
+
"exportStem",
|
|
51631
|
+
"index",
|
|
51632
|
+
"checked",
|
|
51633
|
+
"url",
|
|
51634
|
+
"path",
|
|
51635
|
+
"alt",
|
|
51636
|
+
"caption",
|
|
51637
|
+
"linkText",
|
|
51638
|
+
"filename",
|
|
51639
|
+
"kind",
|
|
51640
|
+
"uti",
|
|
51641
|
+
"color",
|
|
51642
|
+
"highlight",
|
|
51643
|
+
"fence"
|
|
51644
|
+
];
|
|
51645
|
+
var NOTE_PLACEHOLDERS = [
|
|
51646
|
+
"title",
|
|
51647
|
+
"id",
|
|
51648
|
+
"uuid",
|
|
51649
|
+
"folder",
|
|
51650
|
+
"account",
|
|
51651
|
+
"created",
|
|
51652
|
+
"modified",
|
|
51653
|
+
"exportStem"
|
|
51654
|
+
];
|
|
51655
|
+
var PLACEHOLDER_MODIFIERS = ["raw", "yaml"];
|
|
51656
|
+
var wrap2 = (before, after = "", join29) => ({
|
|
51657
|
+
mode: "wrap",
|
|
51658
|
+
before,
|
|
51659
|
+
after,
|
|
51660
|
+
...join29 ? { join: join29 } : {}
|
|
51661
|
+
});
|
|
51662
|
+
var pattern = (value, join29) => ({
|
|
51663
|
+
mode: "pattern",
|
|
51664
|
+
value,
|
|
51665
|
+
...join29 ? { join: join29 } : {}
|
|
51666
|
+
});
|
|
51667
|
+
var STANDARD = {
|
|
51668
|
+
schemaVersion: 1,
|
|
51669
|
+
name: "standard-markdown",
|
|
51670
|
+
description: "The default export-notes-markdown output",
|
|
51671
|
+
assets: { mode: "copy", pathStyle: "relative", directory: null },
|
|
51672
|
+
inlineOrder: [...INLINE_FORMATS],
|
|
51673
|
+
options: {
|
|
51674
|
+
titleFallback: true,
|
|
51675
|
+
richLinkImages: false,
|
|
51676
|
+
richLinkImageCaption: "none",
|
|
51677
|
+
listIndent: " "
|
|
51678
|
+
},
|
|
51679
|
+
rules: {
|
|
51680
|
+
"document.header": pattern(""),
|
|
51681
|
+
"document.footer": pattern(""),
|
|
51682
|
+
"document.separator": pattern("\n\n---\n\n"),
|
|
51683
|
+
"block.title": wrap2("# ", "", "paragraph"),
|
|
51684
|
+
"block.heading": wrap2("## ", "", "paragraph"),
|
|
51685
|
+
"block.subheading": wrap2("### ", "", "paragraph"),
|
|
51686
|
+
"block.body": { mode: "plain", join: "paragraph" },
|
|
51687
|
+
"block.bulleted": wrap2("- ", "", "line"),
|
|
51688
|
+
"block.dashed": wrap2("- ", "", "line"),
|
|
51689
|
+
"block.numbered": pattern("{{index}}. {{content}}", "line"),
|
|
51690
|
+
"block.checklist.checked": wrap2("- [x] ", "", "line"),
|
|
51691
|
+
"block.checklist.unchecked": wrap2("- [ ] ", "", "line"),
|
|
51692
|
+
"block.code": wrap2("{{fence}}\n", "\n{{fence}}", "paragraph"),
|
|
51693
|
+
"paragraph.quote": { mode: "linePrefix", value: "> " },
|
|
51694
|
+
"inline.bold": wrap2("**", "**"),
|
|
51695
|
+
"inline.italic": wrap2("*", "*"),
|
|
51696
|
+
"inline.underline": wrap2("<u>", "</u>"),
|
|
51697
|
+
"inline.strikethrough": wrap2("~~", "~~"),
|
|
51698
|
+
"inline.superscript": wrap2("<sup>", "</sup>"),
|
|
51699
|
+
"inline.subscript": wrap2("<sub>", "</sub>"),
|
|
51700
|
+
"inline.highlight.purple": wrap2("==", "=="),
|
|
51701
|
+
"inline.highlight.pink": wrap2("==", "=="),
|
|
51702
|
+
"inline.highlight.orange": wrap2("==", "=="),
|
|
51703
|
+
"inline.highlight.mint": wrap2("==", "=="),
|
|
51704
|
+
"inline.highlight.blue": wrap2("==", "=="),
|
|
51705
|
+
"inline.highlight.other": wrap2("==", "=="),
|
|
51706
|
+
"inline.color": { mode: "plain" },
|
|
51707
|
+
"inline.link": pattern("[{{content}}]({{url}})"),
|
|
51708
|
+
"attachment.image": pattern(""),
|
|
51709
|
+
"attachment.drawing.classic": pattern(""),
|
|
51710
|
+
"attachment.drawing.paper": pattern(""),
|
|
51711
|
+
"attachment.scan": pattern("[{{linkText}}]({{path}})"),
|
|
51712
|
+
"attachment.pdf": pattern("[{{linkText}}]({{path}})"),
|
|
51713
|
+
"attachment.audio": pattern("[{{linkText}}]({{path}})"),
|
|
51714
|
+
"attachment.video": pattern("[{{linkText}}]({{path}})"),
|
|
51715
|
+
"attachment.other": pattern("[{{linkText}}]({{path}})"),
|
|
51716
|
+
"attachment.table": { mode: "plain" },
|
|
51717
|
+
"attachment.divider": pattern("---"),
|
|
51718
|
+
"attachment.gallery": { mode: "plain", join: "paragraph" },
|
|
51719
|
+
"attachment.url": pattern("[{{alt}}]({{url}})"),
|
|
51720
|
+
"attachment.url.image": pattern(""),
|
|
51721
|
+
"attachment.map": pattern("[{{alt}}]({{url}})"),
|
|
51722
|
+
"attachment.placeholder": pattern("\\[{{content}}\\]")
|
|
51723
|
+
}
|
|
51724
|
+
};
|
|
51725
|
+
var OBSIDIAN = {
|
|
51726
|
+
schemaVersion: 1,
|
|
51727
|
+
name: "obsidian",
|
|
51728
|
+
description: "Obsidian-style Markdown: YAML front matter (title, dates, folder, tags, id), image-URL link cards as images, attachments copied to <file>.assets",
|
|
51729
|
+
extends: "standard-markdown",
|
|
51730
|
+
assets: { directory: "{{exportStem}}.assets" },
|
|
51731
|
+
options: { richLinkImages: true, richLinkImageCaption: "followingItalicParagraph" },
|
|
51732
|
+
rules: {
|
|
51733
|
+
"document.header": pattern(
|
|
51734
|
+
"---\ntitle: {{title:yaml}}\ncreated: {{created:yaml}}\nmodified: {{modified:yaml}}\nfolder: {{folder:yaml}}\ntags: {{tags:yaml}}\nnote-id: {{uuid:yaml}}\n---\n\n"
|
|
51735
|
+
)
|
|
51736
|
+
}
|
|
51737
|
+
};
|
|
51738
|
+
var BUILTINS = { "standard-markdown": STANDARD, obsidian: OBSIDIAN };
|
|
51739
|
+
var BUILTIN_TEMPLATE_NAMES = Object.keys(BUILTINS);
|
|
51740
|
+
var isBuiltinTemplate = (name) => Object.prototype.hasOwnProperty.call(BUILTINS, name);
|
|
51741
|
+
function builtinTemplate(name) {
|
|
51742
|
+
return JSON.parse(JSON.stringify(BUILTINS[name]));
|
|
51743
|
+
}
|
|
51744
|
+
var TemplateValidationError = class extends Error {
|
|
51745
|
+
constructor(errors) {
|
|
51746
|
+
super(
|
|
51747
|
+
`Invalid template (${errors.length} problem${errors.length === 1 ? "" : "s"}): ` + errors.map((e) => `${e.path}: ${e.message}`).join("; ")
|
|
51748
|
+
);
|
|
51749
|
+
this.errors = errors;
|
|
51750
|
+
this.name = "TemplateValidationError";
|
|
51751
|
+
}
|
|
51752
|
+
errors;
|
|
51753
|
+
code = "invalid-template";
|
|
51754
|
+
};
|
|
51755
|
+
var MAX_QUOTED_TOKEN = 32;
|
|
51756
|
+
function child(path10, key) {
|
|
51757
|
+
if (typeof key === "number") return `${path10}[${key}]`;
|
|
51758
|
+
if (key.length > MAX_QUOTED_TOKEN) key = `${key.slice(0, MAX_QUOTED_TOKEN - 3)}...`;
|
|
51759
|
+
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key) ? `${path10}.${key}` : `${path10}[${JSON.stringify(key)}]`;
|
|
51760
|
+
}
|
|
51761
|
+
var isObject2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
51762
|
+
var describe = (value) => value === null ? "null" : Array.isArray(value) ? "an array" : `a ${typeof value}`;
|
|
51763
|
+
var describeVersion = (value) => typeof value === "number" && Number.isFinite(value) ? String(value) : describe(value);
|
|
51764
|
+
var listed = (values) => values.map((v) => JSON.stringify(v)).join(", ");
|
|
51765
|
+
var quoted = (token) => token.length <= MAX_QUOTED_TOKEN ? token : `${token.slice(0, MAX_QUOTED_TOKEN - 3)}...}}`;
|
|
51766
|
+
var TOKEN = /\{\{([^{}]*)\}\}/g;
|
|
51767
|
+
var TOKEN_BODY = /^\s*([A-Za-z]+)(?::([A-Za-z]+))?\s*$/;
|
|
51768
|
+
var META_PLACEHOLDERS = ["uuid", "folder", "account", "created", "modified"];
|
|
51769
|
+
function usesNoteMeta(template) {
|
|
51770
|
+
const uses = (value) => typeof value === "string" ? placeholderTokens(value).some(({ name }) => META_PLACEHOLDERS.includes(name)) : typeof value === "object" && value !== null && Object.values(value).some(uses);
|
|
51771
|
+
return uses(template.rules) || uses(template.assets) || uses(template.options);
|
|
51772
|
+
}
|
|
51773
|
+
function placeholderTokens(text2) {
|
|
51774
|
+
return [...text2.matchAll(TOKEN)].map((match) => {
|
|
51775
|
+
const body = TOKEN_BODY.exec(match[1]);
|
|
51776
|
+
return {
|
|
51777
|
+
token: match[0],
|
|
51778
|
+
name: body?.[1] ?? match[1],
|
|
51779
|
+
...body?.[2] ? { modifier: body[2] } : {}
|
|
51780
|
+
};
|
|
51781
|
+
});
|
|
51782
|
+
}
|
|
51783
|
+
var Collector = class {
|
|
51784
|
+
errors = [];
|
|
51785
|
+
add(path10, message) {
|
|
51786
|
+
this.errors.push({ path: path10, message });
|
|
51787
|
+
}
|
|
51788
|
+
/** Report unknown keys; returns the known keys present, sorted. */
|
|
51789
|
+
keys(value, path10, allowed) {
|
|
51790
|
+
const present = Object.keys(value).sort();
|
|
51791
|
+
for (const key of present)
|
|
51792
|
+
if (!allowed.includes(key))
|
|
51793
|
+
this.add(child(path10, key), `unknown key; allowed keys are ${listed(allowed)}`);
|
|
51794
|
+
return present.filter((key) => allowed.includes(key));
|
|
51795
|
+
}
|
|
51796
|
+
text(value, path10, { max, allowed = PLACEHOLDERS }) {
|
|
51797
|
+
if (typeof value !== "string") {
|
|
51798
|
+
this.add(path10, `must be a string, not ${describe(value)}`);
|
|
51799
|
+
return false;
|
|
51800
|
+
}
|
|
51801
|
+
if (value.length > max)
|
|
51802
|
+
this.add(path10, `must be at most ${max} characters (is ${value.length})`);
|
|
51803
|
+
for (const { token: raw, name, modifier } of placeholderTokens(value)) {
|
|
51804
|
+
const token = quoted(raw);
|
|
51805
|
+
if (!PLACEHOLDERS.includes(name))
|
|
51806
|
+
this.add(path10, `unknown placeholder ${token}; allowed: ${PLACEHOLDERS.join(", ")}`);
|
|
51807
|
+
else if (!allowed.includes(name))
|
|
51808
|
+
this.add(
|
|
51809
|
+
path10,
|
|
51810
|
+
`placeholder ${token} is not available here; allowed: ${allowed.join(", ")}`
|
|
51811
|
+
);
|
|
51812
|
+
else if (modifier && !PLACEHOLDER_MODIFIERS.includes(modifier))
|
|
51813
|
+
this.add(
|
|
51814
|
+
path10,
|
|
51815
|
+
`unknown modifier in ${token}; allowed modifiers are ${PLACEHOLDER_MODIFIERS.join(", ")}`
|
|
51816
|
+
);
|
|
51817
|
+
}
|
|
51818
|
+
return true;
|
|
51819
|
+
}
|
|
51820
|
+
oneOf(value, path10, allowed) {
|
|
51821
|
+
if (typeof value === "string" && allowed.includes(value)) return true;
|
|
51822
|
+
this.add(
|
|
51823
|
+
path10,
|
|
51824
|
+
typeof value === "string" ? `must be one of ${listed(allowed)}` : `must be one of ${listed(allowed)}, not ${describe(value)}`
|
|
51825
|
+
);
|
|
51826
|
+
return false;
|
|
51827
|
+
}
|
|
51828
|
+
boolean(value, path10) {
|
|
51829
|
+
if (typeof value === "boolean") return true;
|
|
51830
|
+
this.add(path10, `must be true or false, not ${describe(value)}`);
|
|
51831
|
+
return false;
|
|
51832
|
+
}
|
|
51833
|
+
};
|
|
51834
|
+
var RULE_FIELDS = {
|
|
51835
|
+
wrap: ["before", "after"],
|
|
51836
|
+
linePrefix: ["value"],
|
|
51837
|
+
pattern: ["value"],
|
|
51838
|
+
plain: [],
|
|
51839
|
+
omit: []
|
|
51840
|
+
};
|
|
51841
|
+
function validateRule(c, rule, path10) {
|
|
51842
|
+
if (!isObject2(rule)) {
|
|
51843
|
+
c.add(path10, `must be an object, not ${describe(rule)}`);
|
|
51844
|
+
return;
|
|
51845
|
+
}
|
|
51846
|
+
const keys = c.keys(rule, path10, ["mode", "before", "after", "value", "join"]);
|
|
51847
|
+
if (!("mode" in rule)) {
|
|
51848
|
+
c.add(child(path10, "mode"), `is required; one of ${listed(RULE_MODES)}`);
|
|
51849
|
+
return;
|
|
51850
|
+
}
|
|
51851
|
+
if (!c.oneOf(rule.mode, child(path10, "mode"), RULE_MODES)) return;
|
|
51852
|
+
const needed = RULE_FIELDS[rule.mode];
|
|
51853
|
+
for (const field of ["before", "after", "value"]) {
|
|
51854
|
+
const fieldPath = child(path10, field);
|
|
51855
|
+
if (needed.includes(field)) {
|
|
51856
|
+
if (!(field in rule)) c.add(fieldPath, `is required when mode is "${rule.mode}"`);
|
|
51857
|
+
else c.text(rule[field], fieldPath, { max: MAX_RULE_TEXT });
|
|
51858
|
+
} else if (keys.includes(field)) c.add(fieldPath, `is not used when mode is "${rule.mode}"`);
|
|
51859
|
+
}
|
|
51860
|
+
if ("join" in rule) c.oneOf(rule.join, child(path10, "join"), ["line", "paragraph"]);
|
|
51861
|
+
}
|
|
51862
|
+
function validateDirectory(c, value, path10) {
|
|
51863
|
+
if (value === null) return;
|
|
51864
|
+
if (!c.text(value, path10, { max: MAX_DIRECTORY_LENGTH, allowed: NOTE_PLACEHOLDERS })) return;
|
|
51865
|
+
if (!value.trim()) c.add(path10, "must not be empty; use null to copy only with assetsDir");
|
|
51866
|
+
else if (/^[/~]/.test(value)) c.add(path10, "must be relative to the output file's directory");
|
|
51867
|
+
else if (/[\\\0]/.test(value)) c.add(path10, "must not contain a backslash or NUL");
|
|
51868
|
+
else if (value.split("/").some((part) => part.trim() === ".."))
|
|
51869
|
+
c.add(path10, 'must not contain a ".." component');
|
|
51870
|
+
}
|
|
51871
|
+
function validateInlineOrder(c, value, path10) {
|
|
51872
|
+
if (!Array.isArray(value)) {
|
|
51873
|
+
c.add(
|
|
51874
|
+
path10,
|
|
51875
|
+
`must be an array of ${INLINE_FORMATS.length} inline formats, not ${describe(value)}`
|
|
51876
|
+
);
|
|
51877
|
+
return;
|
|
51878
|
+
}
|
|
51879
|
+
const seen = /* @__PURE__ */ new Set();
|
|
51880
|
+
value.forEach((item, i) => {
|
|
51881
|
+
if (!c.oneOf(item, child(path10, i), INLINE_FORMATS)) return;
|
|
51882
|
+
if (seen.has(item)) c.add(child(path10, i), `duplicate format "${item}"`);
|
|
51883
|
+
seen.add(item);
|
|
51884
|
+
});
|
|
51885
|
+
const missing = INLINE_FORMATS.filter((format) => !seen.has(format));
|
|
51886
|
+
if (missing.length) c.add(path10, `must list every inline format; missing ${listed(missing)}`);
|
|
51887
|
+
}
|
|
51888
|
+
function validateOptions(c, value, path10) {
|
|
51889
|
+
if (!isObject2(value)) {
|
|
51890
|
+
c.add(path10, `must be an object, not ${describe(value)}`);
|
|
51891
|
+
return;
|
|
51892
|
+
}
|
|
51893
|
+
for (const key of c.keys(value, path10, [
|
|
51894
|
+
"titleFallback",
|
|
51895
|
+
"richLinkImages",
|
|
51896
|
+
"richLinkImageCaption",
|
|
51897
|
+
"listIndent"
|
|
51898
|
+
])) {
|
|
51899
|
+
const at = child(path10, key);
|
|
51900
|
+
if (key === "richLinkImageCaption")
|
|
51901
|
+
c.oneOf(value[key], at, ["none", "followingItalicParagraph"]);
|
|
51902
|
+
else if (key === "listIndent") {
|
|
51903
|
+
if (typeof value[key] !== "string" || !/^[ \t]{0,16}$/.test(value[key]))
|
|
51904
|
+
c.add(at, "must be a string of at most 16 spaces or tabs");
|
|
51905
|
+
} else c.boolean(value[key], at);
|
|
51906
|
+
}
|
|
51907
|
+
}
|
|
51908
|
+
function templateErrors(input) {
|
|
51909
|
+
const c = new Collector();
|
|
51910
|
+
if (!isObject2(input)) {
|
|
51911
|
+
c.add("$", `a template must be a JSON object, not ${describe(input)}`);
|
|
51912
|
+
return c.errors;
|
|
51913
|
+
}
|
|
51914
|
+
if (input.schemaVersion !== TEMPLATE_SCHEMA_VERSION) {
|
|
51915
|
+
c.add(
|
|
51916
|
+
"$.schemaVersion",
|
|
51917
|
+
"schemaVersion" in input ? `must be ${TEMPLATE_SCHEMA_VERSION}, not ${describeVersion(input.schemaVersion)}` : `is required and must be ${TEMPLATE_SCHEMA_VERSION}`
|
|
51918
|
+
);
|
|
51919
|
+
return c.errors;
|
|
51920
|
+
}
|
|
51921
|
+
const keys = c.keys(input, "$", [
|
|
51922
|
+
"schemaVersion",
|
|
51923
|
+
"name",
|
|
51924
|
+
"description",
|
|
51925
|
+
"extends",
|
|
51926
|
+
"assets",
|
|
51927
|
+
"inlineOrder",
|
|
51928
|
+
"rules",
|
|
51929
|
+
"options"
|
|
51930
|
+
]);
|
|
51931
|
+
for (const key of keys) {
|
|
51932
|
+
const path10 = child("$", key);
|
|
51933
|
+
const value = input[key];
|
|
51934
|
+
switch (key) {
|
|
51935
|
+
case "schemaVersion":
|
|
51936
|
+
break;
|
|
51937
|
+
case "name":
|
|
51938
|
+
case "description":
|
|
51939
|
+
c.text(value, path10, { max: MAX_META_LENGTH, allowed: [] });
|
|
51940
|
+
break;
|
|
51941
|
+
case "extends":
|
|
51942
|
+
c.oneOf(value, path10, BUILTIN_TEMPLATE_NAMES);
|
|
51943
|
+
break;
|
|
51944
|
+
case "assets":
|
|
51945
|
+
if (!isObject2(value)) {
|
|
51946
|
+
c.add(path10, `must be an object, not ${describe(value)}`);
|
|
51947
|
+
break;
|
|
51948
|
+
}
|
|
51949
|
+
for (const field of c.keys(value, path10, ["mode", "pathStyle", "directory"])) {
|
|
51950
|
+
const at = child(path10, field);
|
|
51951
|
+
if (field === "mode") c.oneOf(value.mode, at, ["copy", "reference", "omit"]);
|
|
51952
|
+
else if (field === "pathStyle")
|
|
51953
|
+
c.oneOf(value.pathStyle, at, ["relative", "absolute"]);
|
|
51954
|
+
else validateDirectory(c, value.directory, at);
|
|
51955
|
+
}
|
|
51956
|
+
break;
|
|
51957
|
+
case "inlineOrder":
|
|
51958
|
+
validateInlineOrder(c, value, path10);
|
|
51959
|
+
break;
|
|
51960
|
+
case "rules":
|
|
51961
|
+
if (!isObject2(value)) {
|
|
51962
|
+
c.add(path10, `must be an object keyed by rule id, not ${describe(value)}`);
|
|
51963
|
+
break;
|
|
51964
|
+
}
|
|
51965
|
+
for (const id2 of Object.keys(value).sort()) {
|
|
51966
|
+
if (!RULE_IDS.includes(id2))
|
|
51967
|
+
c.add(child(path10, id2), "unknown rule id; see the template reference for the list");
|
|
51968
|
+
else validateRule(c, value[id2], child(path10, id2));
|
|
51969
|
+
}
|
|
51970
|
+
break;
|
|
51971
|
+
default:
|
|
51972
|
+
validateOptions(c, value, path10);
|
|
51973
|
+
}
|
|
51974
|
+
}
|
|
51975
|
+
return c.errors;
|
|
51976
|
+
}
|
|
51977
|
+
function validateTemplate(input) {
|
|
51978
|
+
const errors = templateErrors(input);
|
|
51979
|
+
if (errors.length) throw new TemplateValidationError(errors);
|
|
51980
|
+
return input;
|
|
51981
|
+
}
|
|
51982
|
+
function jsonErrorLocation(text2, message) {
|
|
51983
|
+
const lineColumn = /\(line (\d+) column (\d+)\)/.exec(message);
|
|
51984
|
+
if (lineColumn) return { line: Number(lineColumn[1]), column: Number(lineColumn[2]) };
|
|
51985
|
+
const position = /at position (\d+)/.exec(message);
|
|
51986
|
+
if (!position) return void 0;
|
|
51987
|
+
const offset = Math.min(Number(position[1]), text2.length);
|
|
51988
|
+
const before = text2.slice(0, offset).split("\n");
|
|
51989
|
+
return { line: before.length, column: before[before.length - 1].length + 1 };
|
|
51990
|
+
}
|
|
51991
|
+
function parseTemplate(text2) {
|
|
51992
|
+
const bytes = Buffer.byteLength(text2, "utf8");
|
|
51993
|
+
if (bytes > MAX_TEMPLATE_BYTES)
|
|
51994
|
+
throw new TemplateValidationError([
|
|
51995
|
+
{ path: "$", message: `template is ${bytes} bytes; the limit is ${MAX_TEMPLATE_BYTES}` }
|
|
51996
|
+
]);
|
|
51997
|
+
let parsed;
|
|
51998
|
+
try {
|
|
51999
|
+
parsed = JSON.parse(text2);
|
|
52000
|
+
} catch (error2) {
|
|
52001
|
+
const at = jsonErrorLocation(text2, error2.message);
|
|
52002
|
+
throw new TemplateValidationError([
|
|
52003
|
+
{
|
|
52004
|
+
path: "$",
|
|
52005
|
+
message: at ? `not valid JSON at line ${at.line}, column ${at.column}` : "not valid JSON"
|
|
52006
|
+
}
|
|
52007
|
+
]);
|
|
52008
|
+
}
|
|
52009
|
+
return validateTemplate(parsed);
|
|
52010
|
+
}
|
|
52011
|
+
function resolveTemplate(template, name) {
|
|
52012
|
+
if (template === STANDARD) return merge2(void 0, STANDARD, name);
|
|
52013
|
+
return merge2(resolveTemplate(BUILTINS[template.extends ?? "standard-markdown"]), template, name);
|
|
52014
|
+
}
|
|
52015
|
+
function merge2(base, template, name) {
|
|
52016
|
+
return {
|
|
52017
|
+
name: name ?? template.name ?? base?.name ?? "template",
|
|
52018
|
+
...template.description !== void 0 ? { description: template.description } : base?.description !== void 0 ? { description: base.description } : {},
|
|
52019
|
+
assets: { ...base?.assets, ...template.assets },
|
|
52020
|
+
inlineOrder: [...template.inlineOrder ?? base.inlineOrder],
|
|
52021
|
+
rules: { ...base?.rules, ...template.rules },
|
|
52022
|
+
options: { ...base?.options, ...template.options }
|
|
52023
|
+
};
|
|
52024
|
+
}
|
|
52025
|
+
var plainValue = (text2) => ({ md: text2, raw: text2 });
|
|
52026
|
+
function fillPlaceholders(text2, values) {
|
|
52027
|
+
return text2.replace(TOKEN, (token, body) => {
|
|
52028
|
+
const parsed = TOKEN_BODY.exec(body);
|
|
52029
|
+
const raw = parsed ? values[parsed[1]] : void 0;
|
|
52030
|
+
const value = typeof raw === "string" ? plainValue(raw) : raw;
|
|
52031
|
+
if (parsed?.[2] === "yaml") {
|
|
52032
|
+
if (!value) return "null";
|
|
52033
|
+
return JSON.stringify(value.list ?? value.raw);
|
|
52034
|
+
}
|
|
52035
|
+
if (!value) return "";
|
|
52036
|
+
return parsed?.[2] === "raw" ? value.raw : value.md;
|
|
52037
|
+
});
|
|
52038
|
+
}
|
|
52039
|
+
function ruleUses(rule, name) {
|
|
52040
|
+
return [rule.before, rule.after, rule.value].some(
|
|
52041
|
+
(text2) => text2 !== void 0 && placeholderTokens(text2).some((token) => token.name === name)
|
|
52042
|
+
);
|
|
52043
|
+
}
|
|
52044
|
+
|
|
52045
|
+
// src/utils/templateRender.ts
|
|
52046
|
+
var FILE_BACKED = /* @__PURE__ */ new Set([
|
|
52047
|
+
"image",
|
|
52048
|
+
"drawing",
|
|
52049
|
+
"paper",
|
|
52050
|
+
"scan",
|
|
52051
|
+
"pdf",
|
|
52052
|
+
"audio",
|
|
52053
|
+
"video",
|
|
52054
|
+
"file",
|
|
52055
|
+
"gallery"
|
|
52056
|
+
]);
|
|
52057
|
+
var KIND_RULES = {
|
|
52058
|
+
image: "attachment.image",
|
|
52059
|
+
drawing: "attachment.drawing.classic",
|
|
52060
|
+
paper: "attachment.drawing.paper",
|
|
52061
|
+
scan: "attachment.scan",
|
|
52062
|
+
pdf: "attachment.pdf",
|
|
52063
|
+
audio: "attachment.audio",
|
|
52064
|
+
video: "attachment.video",
|
|
52065
|
+
file: "attachment.other",
|
|
52066
|
+
table: "attachment.table",
|
|
52067
|
+
divider: "attachment.divider",
|
|
52068
|
+
gallery: "attachment.gallery",
|
|
52069
|
+
link: "attachment.url"
|
|
52070
|
+
};
|
|
52071
|
+
var IMAGE_URL_EXTENSIONS = /\.(?:apng|avif|bmp|gif|heic|heif|ico|jfif|jpe?g|jxl|png|svgz?|tiff?|webp)$/i;
|
|
52072
|
+
function isImageUrl(url) {
|
|
52073
|
+
try {
|
|
52074
|
+
const parsed = new URL(url);
|
|
52075
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return false;
|
|
52076
|
+
let path10 = parsed.pathname;
|
|
52077
|
+
try {
|
|
52078
|
+
path10 = decodeURIComponent(path10);
|
|
52079
|
+
} catch {
|
|
52080
|
+
}
|
|
52081
|
+
return IMAGE_URL_EXTENSIONS.test(path10);
|
|
52082
|
+
} catch {
|
|
52083
|
+
return false;
|
|
52084
|
+
}
|
|
52085
|
+
}
|
|
52086
|
+
function isMapUrl(url) {
|
|
52087
|
+
try {
|
|
52088
|
+
const host = new URL(url).hostname.toLowerCase();
|
|
52089
|
+
return host === "maps.apple.com" || host.endsWith(".maps.apple.com");
|
|
52090
|
+
} catch {
|
|
52091
|
+
return false;
|
|
52092
|
+
}
|
|
52093
|
+
}
|
|
52094
|
+
function attachmentRuleId(attachment, template) {
|
|
52095
|
+
if (attachment.kind === "inline") return void 0;
|
|
52096
|
+
if (attachment.kind === "link") {
|
|
52097
|
+
const url = attachment.url ?? "";
|
|
52098
|
+
if (template.options.richLinkImages && isImageUrl(url)) return "attachment.url.image";
|
|
52099
|
+
if (isMapUrl(url)) return "attachment.map";
|
|
52100
|
+
}
|
|
52101
|
+
return KIND_RULES[attachment.kind] ?? "attachment.other";
|
|
52102
|
+
}
|
|
52103
|
+
function applyRule(rule, content, values) {
|
|
52104
|
+
const fill = (text2 = "") => fillPlaceholders(text2, { ...values, content: plainValue(content) });
|
|
52105
|
+
switch (rule.mode) {
|
|
52106
|
+
case "omit":
|
|
52107
|
+
return void 0;
|
|
52108
|
+
case "plain":
|
|
52109
|
+
return content;
|
|
52110
|
+
case "wrap":
|
|
52111
|
+
return fill(rule.before) + content + fill(rule.after);
|
|
52112
|
+
case "pattern":
|
|
52113
|
+
return fill(rule.value);
|
|
52114
|
+
case "linePrefix": {
|
|
52115
|
+
const prefix = fill(rule.value);
|
|
52116
|
+
return content.split("\n").map((line) => line ? prefix + line : prefix.trimEnd()).join("\n");
|
|
52117
|
+
}
|
|
52118
|
+
}
|
|
52119
|
+
}
|
|
52120
|
+
function applyInline(rule, text2, values) {
|
|
52121
|
+
const match = /^(\s*)([\s\S]*?)(\s*)$/.exec(text2);
|
|
52122
|
+
if (!match[2]) return text2;
|
|
52123
|
+
const out = applyRule(rule, match[2], values);
|
|
52124
|
+
return out === void 0 ? "" : `${match[1]}${out}${match[3]}`;
|
|
52125
|
+
}
|
|
52126
|
+
var HIGHLIGHT_RULES = /* @__PURE__ */ new Set(["purple", "pink", "orange", "mint", "blue"]);
|
|
52127
|
+
function highlightRule(name) {
|
|
52128
|
+
return HIGHLIGHT_RULES.has(name) ? `inline.highlight.${name}` : "inline.highlight.other";
|
|
52129
|
+
}
|
|
52130
|
+
function buildLayers(template) {
|
|
52131
|
+
const { rules } = template;
|
|
52132
|
+
const active = (rule) => rule.mode !== "plain";
|
|
52133
|
+
const flag3 = (format) => {
|
|
52134
|
+
const rule = rules[`inline.${format}`];
|
|
52135
|
+
return {
|
|
52136
|
+
key: (fmt) => fmt[format] && active(rule) ? "on" : void 0,
|
|
52137
|
+
rule: () => rule,
|
|
52138
|
+
values: () => ({})
|
|
52139
|
+
};
|
|
52140
|
+
};
|
|
52141
|
+
const layers = {
|
|
52142
|
+
bold: flag3("bold"),
|
|
52143
|
+
italic: flag3("italic"),
|
|
52144
|
+
underline: flag3("underline"),
|
|
52145
|
+
strikethrough: flag3("strikethrough"),
|
|
52146
|
+
superscript: flag3("superscript"),
|
|
52147
|
+
subscript: flag3("subscript"),
|
|
52148
|
+
highlight: {
|
|
52149
|
+
key: (fmt) => {
|
|
52150
|
+
if (!fmt.highlight) return void 0;
|
|
52151
|
+
const rule = rules[highlightRule(fmt.highlight)];
|
|
52152
|
+
if (!active(rule)) return void 0;
|
|
52153
|
+
return JSON.stringify(rule) + (ruleUses(rule, "highlight") ? fmt.highlight : "");
|
|
52154
|
+
},
|
|
52155
|
+
rule: (fmt) => rules[highlightRule(fmt.highlight)],
|
|
52156
|
+
values: (fmt) => ({ highlight: fmt.highlight })
|
|
52157
|
+
},
|
|
52158
|
+
color: {
|
|
52159
|
+
key: (fmt) => {
|
|
52160
|
+
const rule = rules["inline.color"];
|
|
52161
|
+
if (!fmt.color || !active(rule)) return void 0;
|
|
52162
|
+
return ruleUses(rule, "color") ? fmt.color : "on";
|
|
52163
|
+
},
|
|
52164
|
+
rule: () => rules["inline.color"],
|
|
52165
|
+
values: (fmt) => ({ color: fmt.color })
|
|
52166
|
+
},
|
|
52167
|
+
link: {
|
|
52168
|
+
key: (fmt) => fmt.link,
|
|
52169
|
+
rule: () => rules["inline.link"],
|
|
52170
|
+
values: (fmt) => ({ url: { md: linkDestination(fmt.link), raw: fmt.link } })
|
|
52171
|
+
}
|
|
52172
|
+
};
|
|
52173
|
+
return [...template.inlineOrder].reverse().map((format) => layers[format]);
|
|
52174
|
+
}
|
|
52175
|
+
var LIST_STYLES2 = /* @__PURE__ */ new Set(["bulleted", "dashed", "numbered", "checklist"]);
|
|
52176
|
+
var TemplateRenderer = class {
|
|
52177
|
+
constructor(ctx, options) {
|
|
52178
|
+
this.ctx = ctx;
|
|
52179
|
+
this.options = options;
|
|
52180
|
+
this.layers = buildLayers(options.template);
|
|
52181
|
+
this.rules = options.template.rules;
|
|
52182
|
+
}
|
|
52183
|
+
ctx;
|
|
52184
|
+
options;
|
|
52185
|
+
warnings = [];
|
|
52186
|
+
layers;
|
|
52187
|
+
rules;
|
|
52188
|
+
/** The attachment each plan was made from, for rule and placeholder lookup. */
|
|
52189
|
+
origins = /* @__PURE__ */ new WeakMap();
|
|
52190
|
+
get template() {
|
|
52191
|
+
return this.options.template;
|
|
52192
|
+
}
|
|
52193
|
+
/** Placeholder values describing the note. */
|
|
52194
|
+
noteValues(note) {
|
|
52195
|
+
const meta = this.options.metaFor?.(note) ?? {};
|
|
52196
|
+
const text2 = (value) => value === void 0 ? void 0 : { md: escapeMarkdown(value), raw: value };
|
|
52197
|
+
const tags = noteTags(note);
|
|
52198
|
+
const values = {
|
|
52199
|
+
title: text2(note.title.trim()),
|
|
52200
|
+
id: note.id,
|
|
52201
|
+
uuid: meta.uuid,
|
|
52202
|
+
folder: text2(meta.folder),
|
|
52203
|
+
account: text2(meta.account),
|
|
52204
|
+
created: meta.created,
|
|
52205
|
+
modified: meta.modified,
|
|
52206
|
+
tags: {
|
|
52207
|
+
md: tags.map((tag) => escapeMarkdown(tag)).join(", "),
|
|
52208
|
+
raw: tags.join(", "),
|
|
52209
|
+
list: tags
|
|
52210
|
+
},
|
|
52211
|
+
exportStem: this.options.exportStem ?? "export"
|
|
52212
|
+
};
|
|
52213
|
+
return Object.fromEntries(Object.entries(values).filter(([, v]) => v !== void 0));
|
|
52214
|
+
}
|
|
52215
|
+
warn(code, note, attachmentId) {
|
|
52216
|
+
this.warnings.push({ code, noteId: note.id, ...attachmentId ? { attachmentId } : {} });
|
|
52217
|
+
}
|
|
52218
|
+
/** Plan one attachment, honoring omit rules before any file is placed. */
|
|
52219
|
+
plan(note, id2, attachment, binding) {
|
|
52220
|
+
const omitted = { type: "inline", text: "" };
|
|
52221
|
+
if (!attachment) {
|
|
52222
|
+
this.warn("attachment_not_found", note, id2);
|
|
52223
|
+
return planAttachment(void 0, this.ctx);
|
|
52224
|
+
}
|
|
52225
|
+
const ruleId = attachmentRuleId(attachment, this.template);
|
|
52226
|
+
if (ruleId && this.rules[ruleId].mode === "omit") return omitted;
|
|
52227
|
+
const fileBacked = FILE_BACKED.has(attachment.kind);
|
|
52228
|
+
if (fileBacked && this.template.assets.mode === "omit") return omitted;
|
|
52229
|
+
if (fileBacked && !binding.writer && binding.required)
|
|
52230
|
+
this.warn("assets_dir_required", note, attachment.id);
|
|
52231
|
+
const plan = planAttachment(attachment, {
|
|
52232
|
+
...this.ctx,
|
|
52233
|
+
...binding.writer ? { writer: binding.writer } : { writer: void 0 }
|
|
52234
|
+
});
|
|
52235
|
+
this.inspect(note, plan, attachment);
|
|
52236
|
+
return plan;
|
|
52237
|
+
}
|
|
52238
|
+
/** Record origins and warnings for a plan and any gallery items. */
|
|
52239
|
+
inspect(note, plan, attachment) {
|
|
52240
|
+
this.origins.set(plan, attachment);
|
|
52241
|
+
switch (plan.type) {
|
|
52242
|
+
case "inline":
|
|
52243
|
+
if (!plan.text) this.warn("inline_token_metadata_missing", note, attachment.id);
|
|
52244
|
+
break;
|
|
52245
|
+
case "unavailable":
|
|
52246
|
+
this.warn(
|
|
52247
|
+
plan.reason === "undecodable" ? "table_decode_failed" : plan.reason === "missing" ? "missing_asset" : "asset_copy_failed",
|
|
52248
|
+
note,
|
|
52249
|
+
attachment.id
|
|
52250
|
+
);
|
|
52251
|
+
break;
|
|
52252
|
+
case "gallery":
|
|
52253
|
+
if (!plan.items.length) this.warn("gallery_children_missing", note, attachment.id);
|
|
52254
|
+
plan.items.forEach((item, i) => this.inspect(note, item, attachment.children[i]));
|
|
52255
|
+
break;
|
|
52256
|
+
}
|
|
52257
|
+
}
|
|
52258
|
+
/** Placeholder values for an attachment. */
|
|
52259
|
+
attachmentValues(attachment, base) {
|
|
52260
|
+
if (!attachment) return base;
|
|
52261
|
+
const filename = attachment.mediaFilename ?? attachment.title;
|
|
52262
|
+
return {
|
|
52263
|
+
...base,
|
|
52264
|
+
kind: attachment.kind,
|
|
52265
|
+
uti: attachment.uti,
|
|
52266
|
+
...filename ? { filename: { md: escapeMarkdown(filename), raw: filename } } : {}
|
|
52267
|
+
};
|
|
52268
|
+
}
|
|
52269
|
+
/** Render a plan through its template rule; "" when omitted. */
|
|
52270
|
+
renderPlan(plan, values, caption) {
|
|
52271
|
+
const origin = this.origins.get(plan);
|
|
52272
|
+
const vars = this.attachmentValues(origin, values);
|
|
52273
|
+
const apply2 = (id2, content, extra = {}) => applyRule(this.rules[id2], content, { ...vars, ...extra }) ?? "";
|
|
52274
|
+
switch (plan.type) {
|
|
52275
|
+
case "inline":
|
|
52276
|
+
return plan.link ? applyInline(this.rules["inline.link"], escapeMarkdown(plan.text), {
|
|
52277
|
+
...vars,
|
|
52278
|
+
url: { md: linkDestination(plan.link), raw: plan.link }
|
|
52279
|
+
}) : escapeMarkdown(plan.text);
|
|
52280
|
+
case "divider":
|
|
52281
|
+
return apply2("attachment.divider", "");
|
|
52282
|
+
case "table":
|
|
52283
|
+
return apply2("attachment.table", tableMarkdown(plan.rows));
|
|
52284
|
+
case "placeholder":
|
|
52285
|
+
case "unavailable": {
|
|
52286
|
+
const label = plan.type === "unavailable" ? `${plan.label} unavailable` : plan.label;
|
|
52287
|
+
return apply2(
|
|
52288
|
+
"attachment.placeholder",
|
|
52289
|
+
escapeMarkdown(plan.name ? `${label}: ${plan.name}` : label)
|
|
52290
|
+
);
|
|
52291
|
+
}
|
|
52292
|
+
case "asset": {
|
|
52293
|
+
const alt = escapeMarkdown(plan.name ?? plan.label);
|
|
52294
|
+
const id2 = origin && attachmentRuleId(origin, this.template) || "attachment.other";
|
|
52295
|
+
return apply2(id2, "", {
|
|
52296
|
+
alt: { md: alt, raw: plan.name ?? plan.label },
|
|
52297
|
+
path: { md: linkDestination(plan.url), raw: plan.url },
|
|
52298
|
+
linkText: plan.previewUrl ? `})` : alt
|
|
52299
|
+
});
|
|
52300
|
+
}
|
|
52301
|
+
case "card": {
|
|
52302
|
+
if (!plan.url) return `${escapeMarkdown(plan.title)} (${escapeMarkdown(plan.displayUrl)})`;
|
|
52303
|
+
const id2 = origin && attachmentRuleId(origin, this.template) || "attachment.url";
|
|
52304
|
+
const alt = caption ?? plan.title;
|
|
52305
|
+
return apply2(id2, "", {
|
|
52306
|
+
alt: { md: escapeMarkdown(alt), raw: alt },
|
|
52307
|
+
url: { md: linkDestination(plan.url), raw: plan.url },
|
|
52308
|
+
...caption !== void 0 ? { caption: { md: escapeMarkdown(caption), raw: caption } } : {}
|
|
52309
|
+
});
|
|
52310
|
+
}
|
|
52311
|
+
case "gallery": {
|
|
52312
|
+
const rule = this.rules["attachment.gallery"];
|
|
52313
|
+
const items = plan.items.map((item) => this.renderPlan(item, values)).filter(Boolean);
|
|
52314
|
+
if (!items.length) return "";
|
|
52315
|
+
return apply2("attachment.gallery", items.join(rule.join === "line" ? "\n" : "\n\n"));
|
|
52316
|
+
}
|
|
52317
|
+
}
|
|
52318
|
+
}
|
|
52319
|
+
/** Format text runs through the inline layers. */
|
|
52320
|
+
layered(pieces, values, depth = 0) {
|
|
52321
|
+
if (depth === this.layers.length)
|
|
52322
|
+
return pieces.map((piece) => escapeMarkdown(piece.text.replace(/\n/g, " "))).join("");
|
|
52323
|
+
const layer = this.layers[depth];
|
|
52324
|
+
let out = "";
|
|
52325
|
+
for (let i = 0; i < pieces.length; ) {
|
|
52326
|
+
const key = layer.key(pieces[i].fmt);
|
|
52327
|
+
let j = i;
|
|
52328
|
+
while (j < pieces.length && layer.key(pieces[j].fmt) === key) j++;
|
|
52329
|
+
const inner = this.layered(pieces.slice(i, j), values, depth + 1);
|
|
52330
|
+
const fmt = pieces[i].fmt;
|
|
52331
|
+
out = joinSafe(
|
|
52332
|
+
out,
|
|
52333
|
+
key === void 0 ? inner : applyInline(layer.rule(fmt), inner, { ...values, ...layer.values(fmt) })
|
|
52334
|
+
);
|
|
52335
|
+
i = j;
|
|
52336
|
+
}
|
|
52337
|
+
return out;
|
|
52338
|
+
}
|
|
52339
|
+
inline(pieces, values, caption) {
|
|
52340
|
+
let out = "";
|
|
52341
|
+
for (let i = 0; i < pieces.length; ) {
|
|
52342
|
+
const piece = pieces[i];
|
|
52343
|
+
if (piece.type === "attachment") {
|
|
52344
|
+
out = joinSafe(out, this.renderPlan(piece.plan, values, caption));
|
|
52345
|
+
i++;
|
|
52346
|
+
continue;
|
|
52347
|
+
}
|
|
52348
|
+
let j = i;
|
|
52349
|
+
while (j < pieces.length && pieces[j].type === "text") j++;
|
|
52350
|
+
out = joinSafe(out, this.layered(pieces.slice(i, j), values));
|
|
52351
|
+
i = j;
|
|
52352
|
+
}
|
|
52353
|
+
return out;
|
|
52354
|
+
}
|
|
52355
|
+
/** The caption paragraph after a lone image-URL link card, if the template wants one. */
|
|
52356
|
+
captionFor(note, index) {
|
|
52357
|
+
const { options } = this.template;
|
|
52358
|
+
if (!options.richLinkImages || options.richLinkImageCaption !== "followingItalicParagraph")
|
|
52359
|
+
return void 0;
|
|
52360
|
+
const blocks = note.doc.blocks;
|
|
52361
|
+
const current = blocks[index];
|
|
52362
|
+
if (current.text.trim() !== "\uFFFC" || current.attachments.length !== 1) return void 0;
|
|
52363
|
+
const attachment = note.attachments.get(current.attachments[0].id);
|
|
52364
|
+
if (!attachment || attachmentRuleId(attachment, this.template) !== "attachment.url.image")
|
|
52365
|
+
return void 0;
|
|
52366
|
+
if (this.rules["attachment.url.image"].mode === "omit" || !isSafe(attachment.url))
|
|
52367
|
+
return void 0;
|
|
52368
|
+
const next = blocks[index + 1];
|
|
52369
|
+
if (!next || next.style !== "body" || next.blockQuote || next.indent !== 0 || next.attachments.length || next.text.includes("\uFFFC") || !next.text.trim() || !next.runs.every((run) => !run.text.trim() || run.italic))
|
|
52370
|
+
return void 0;
|
|
52371
|
+
return next.text.trim();
|
|
52372
|
+
}
|
|
52373
|
+
/** Render one note's body. */
|
|
52374
|
+
renderBody(note, values) {
|
|
52375
|
+
const binding = this.options.assetsFor?.(note) ?? {};
|
|
52376
|
+
const plan = (id2) => this.plan(note, id2, note.attachments.get(id2), binding);
|
|
52377
|
+
const titleIndex = titleBlockIndex(note);
|
|
52378
|
+
const lines = [];
|
|
52379
|
+
const counters = [];
|
|
52380
|
+
const skip = /* @__PURE__ */ new Set();
|
|
52381
|
+
let code;
|
|
52382
|
+
const push = (text2, quote, group) => {
|
|
52383
|
+
if (!text2) return;
|
|
52384
|
+
if (quote) {
|
|
52385
|
+
const quoted2 = applyRule(this.rules["paragraph.quote"], text2, values);
|
|
52386
|
+
if (!quoted2) return;
|
|
52387
|
+
text2 = quoted2;
|
|
52388
|
+
}
|
|
52389
|
+
lines.push({ text: text2, quote, ...group ? { group } : {} });
|
|
52390
|
+
};
|
|
52391
|
+
const ruled = (id2, content, extra = {}) => applyRule(this.rules[id2], content, { ...values, ...extra });
|
|
52392
|
+
const groupOf = (id2, list) => this.rules[id2].join === "line" ? list ? "list" : id2 : void 0;
|
|
52393
|
+
const flushCode = () => {
|
|
52394
|
+
if (!code) return;
|
|
52395
|
+
const longest = Math.max(
|
|
52396
|
+
2,
|
|
52397
|
+
...code.lines.map((l) => Math.max(0, ...(l.match(/`+/g) ?? []).map((m) => m.length)))
|
|
52398
|
+
);
|
|
52399
|
+
push(
|
|
52400
|
+
ruled("block.code", code.lines.join("\n"), { fence: "`".repeat(longest + 1) }),
|
|
52401
|
+
code.quote,
|
|
52402
|
+
groupOf("block.code", false)
|
|
52403
|
+
);
|
|
52404
|
+
code = void 0;
|
|
52405
|
+
};
|
|
52406
|
+
if (this.template.options.titleFallback && titleIndex === -1 && note.title.trim())
|
|
52407
|
+
push(
|
|
52408
|
+
ruled("block.title", escapeMarkdown(note.title.trim())),
|
|
52409
|
+
false,
|
|
52410
|
+
groupOf("block.title", false)
|
|
52411
|
+
);
|
|
52412
|
+
for (const block of note.doc.blocks) {
|
|
52413
|
+
if (skip.has(block.index)) continue;
|
|
52414
|
+
if (block.style === "monospaced") {
|
|
52415
|
+
if (code && code.quote !== block.blockQuote) flushCode();
|
|
52416
|
+
code ??= { lines: [], quote: block.blockQuote };
|
|
52417
|
+
code.lines.push(block.text.replace(//g, ""));
|
|
52418
|
+
continue;
|
|
52419
|
+
}
|
|
52420
|
+
flushCode();
|
|
52421
|
+
if (!LIST_STYLES2.has(block.style)) counters.length = 0;
|
|
52422
|
+
if (!block.text.trim()) continue;
|
|
52423
|
+
const caption = this.captionFor(note, block.index);
|
|
52424
|
+
if (caption !== void 0) skip.add(block.index + 1);
|
|
52425
|
+
const pieces = blockPieces(block, plan);
|
|
52426
|
+
let segment = [];
|
|
52427
|
+
const segments = [];
|
|
52428
|
+
for (const piece of pieces) {
|
|
52429
|
+
if (piece.type === "attachment" && isBlockPlan(piece.plan)) {
|
|
52430
|
+
segments.push(segment, piece.plan);
|
|
52431
|
+
segment = [];
|
|
52432
|
+
} else segment.push(piece);
|
|
52433
|
+
}
|
|
52434
|
+
segments.push(segment);
|
|
52435
|
+
let first2 = true;
|
|
52436
|
+
for (const segment2 of segments) {
|
|
52437
|
+
if (!Array.isArray(segment2)) {
|
|
52438
|
+
push(this.renderPlan(segment2, values), block.blockQuote);
|
|
52439
|
+
continue;
|
|
52440
|
+
}
|
|
52441
|
+
const body = this.inline(segment2, values, caption).trim();
|
|
52442
|
+
if (!body) continue;
|
|
52443
|
+
const [text2, group] = this.blockLine(
|
|
52444
|
+
block,
|
|
52445
|
+
body,
|
|
52446
|
+
first2,
|
|
52447
|
+
block.index === titleIndex,
|
|
52448
|
+
counters,
|
|
52449
|
+
values
|
|
52450
|
+
);
|
|
52451
|
+
push(text2, block.blockQuote, group);
|
|
52452
|
+
first2 = false;
|
|
52453
|
+
}
|
|
52454
|
+
}
|
|
52455
|
+
flushCode();
|
|
52456
|
+
for (const attachment of unreferencedAttachments(note)) {
|
|
52457
|
+
this.ctx.stats.unreferenced++;
|
|
52458
|
+
push(this.renderPlan(this.plan(note, attachment.id, attachment, binding), values), false);
|
|
52459
|
+
}
|
|
52460
|
+
return this.join(lines, values);
|
|
52461
|
+
}
|
|
52462
|
+
/** One paragraph through its block rule, with list indent and numbering. */
|
|
52463
|
+
blockLine(block, body, first2, isTitle, counters, values) {
|
|
52464
|
+
const rule = (id2, content, extra = {}, list = false) => [
|
|
52465
|
+
applyRule(this.rules[id2], content, { ...values, ...extra }),
|
|
52466
|
+
this.rules[id2].join === "line" ? list ? "list" : id2 : void 0
|
|
52467
|
+
];
|
|
52468
|
+
if (isTitle || block.style === "title") return rule("block.title", body);
|
|
52469
|
+
if (block.style === "heading") return rule("block.heading", body);
|
|
52470
|
+
if (block.style === "subheading") return rule("block.subheading", body);
|
|
52471
|
+
if (!LIST_STYLES2.has(block.style) || !first2) return rule("block.body", escapeLineStart(body));
|
|
52472
|
+
const item = escapeLineStart(body);
|
|
52473
|
+
const level = Math.min(block.indent, 20);
|
|
52474
|
+
counters.length = Math.min(counters.length, level + 1);
|
|
52475
|
+
while (counters.length <= level) counters.push(0);
|
|
52476
|
+
let result;
|
|
52477
|
+
if (block.style === "numbered")
|
|
52478
|
+
result = rule("block.numbered", item, { index: String(++counters[level]) }, true);
|
|
52479
|
+
else {
|
|
52480
|
+
counters[level] = 0;
|
|
52481
|
+
if (block.style === "checklist") {
|
|
52482
|
+
const done = !!block.checklist?.done;
|
|
52483
|
+
result = rule(
|
|
52484
|
+
done ? "block.checklist.checked" : "block.checklist.unchecked",
|
|
52485
|
+
item,
|
|
52486
|
+
{ checked: String(done) },
|
|
52487
|
+
true
|
|
52488
|
+
);
|
|
52489
|
+
} else
|
|
52490
|
+
result = rule(block.style === "dashed" ? "block.dashed" : "block.bulleted", item, {}, true);
|
|
52491
|
+
}
|
|
52492
|
+
const indent = this.template.options.listIndent.repeat(level);
|
|
52493
|
+
if (result[0] && indent)
|
|
52494
|
+
result[0] = result[0].split("\n").map((line) => line ? indent + line : line).join("\n");
|
|
52495
|
+
return result;
|
|
52496
|
+
}
|
|
52497
|
+
/** Join lines: one newline within a `line`-join group, a blank line elsewhere. */
|
|
52498
|
+
join(lines, values) {
|
|
52499
|
+
const quote = this.rules["paragraph.quote"];
|
|
52500
|
+
const quoteGap = quote.mode === "linePrefix" ? `
|
|
52501
|
+
${fillPlaceholders(quote.value ?? "", values).trimEnd()}
|
|
52502
|
+
` : "\n\n";
|
|
52503
|
+
let out = "";
|
|
52504
|
+
let previous;
|
|
52505
|
+
for (const line of lines) {
|
|
52506
|
+
if (previous) {
|
|
52507
|
+
const tight = previous.group !== void 0 && previous.group === line.group && previous.quote === line.quote;
|
|
52508
|
+
out += tight ? "\n" : previous.quote && line.quote ? quoteGap : "\n\n";
|
|
52509
|
+
}
|
|
52510
|
+
out += line.text;
|
|
52511
|
+
previous = line;
|
|
52512
|
+
}
|
|
52513
|
+
return out;
|
|
52514
|
+
}
|
|
52515
|
+
};
|
|
52516
|
+
var isSafe = (url) => !!url && /^https?:\/\//i.test(url) && !Array.from(url).some((c) => c.charCodeAt(0) < 32);
|
|
52517
|
+
function noteTags(note) {
|
|
52518
|
+
const tags = [];
|
|
52519
|
+
for (const attachment of note.attachments.values()) {
|
|
52520
|
+
if (!attachment.uti.endsWith(".hashtag") || !attachment.altText) continue;
|
|
52521
|
+
const tag = attachment.altText.replace(/^#/, "").trim();
|
|
52522
|
+
if (tag && !tags.includes(tag)) tags.push(tag);
|
|
52523
|
+
}
|
|
52524
|
+
return tags;
|
|
52525
|
+
}
|
|
52526
|
+
function renderNotesWithTemplate(notes, ctx, options) {
|
|
52527
|
+
const renderer = new TemplateRenderer(ctx, options);
|
|
52528
|
+
const rules = options.template.rules;
|
|
52529
|
+
let markdown = "";
|
|
52530
|
+
notes.forEach((note, i) => {
|
|
52531
|
+
const values = renderer.noteValues(note);
|
|
52532
|
+
if (i > 0) markdown += applyRule(rules["document.separator"], "", values) ?? "";
|
|
52533
|
+
const body = renderer.renderBody(note, values);
|
|
52534
|
+
markdown += (applyRule(rules["document.header"], "", values) ?? "") + (options.wrap ? wrapMarkdown(body, options.wrap) : body) + (applyRule(rules["document.footer"], "", values) ?? "");
|
|
52535
|
+
});
|
|
52536
|
+
return { markdown: markdown + (notes.length ? "\n" : ""), warnings: renderer.warnings };
|
|
52537
|
+
}
|
|
52538
|
+
|
|
52539
|
+
// src/utils/templateAssets.ts
|
|
52540
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
52541
|
+
import {
|
|
52542
|
+
closeSync as closeSync5,
|
|
52543
|
+
constants as constants5,
|
|
52544
|
+
fstatSync as fstatSync5,
|
|
52545
|
+
lstatSync as lstatSync4,
|
|
52546
|
+
mkdirSync as mkdirSync5,
|
|
52547
|
+
openSync as openSync5,
|
|
52548
|
+
readSync as readSync4,
|
|
52549
|
+
writeSync as writeSync4
|
|
52550
|
+
} from "node:fs";
|
|
52551
|
+
import { extname as extname4, isAbsolute as isAbsolute3, join as join21, relative as relative4, resolve as resolve4, sep as sep4 } from "node:path";
|
|
52552
|
+
var CHUNK = 1024 * 1024;
|
|
52553
|
+
function openRegular(path10) {
|
|
52554
|
+
const fd = openSync5(path10, constants5.O_RDONLY | constants5.O_NOFOLLOW);
|
|
52555
|
+
if (!fstatSync5(fd).isFile()) {
|
|
52556
|
+
closeSync5(fd);
|
|
52557
|
+
throw new Error("not a regular file");
|
|
52558
|
+
}
|
|
52559
|
+
return fd;
|
|
52560
|
+
}
|
|
52561
|
+
function digest(fd) {
|
|
52562
|
+
const hash = createHash2("sha256");
|
|
52563
|
+
const chunk = Buffer.alloc(CHUNK);
|
|
52564
|
+
let head = Buffer.alloc(0);
|
|
52565
|
+
for (let position = 0; ; ) {
|
|
52566
|
+
const n = readSync4(fd, chunk, 0, chunk.length, position);
|
|
52567
|
+
if (n <= 0) break;
|
|
52568
|
+
if (position === 0) head = Buffer.from(chunk.subarray(0, Math.min(n, 16)));
|
|
52569
|
+
hash.update(chunk.subarray(0, n));
|
|
52570
|
+
position += n;
|
|
52571
|
+
}
|
|
52572
|
+
return { hash: hash.digest("hex"), head };
|
|
52573
|
+
}
|
|
52574
|
+
function urlFor(target, linkBase) {
|
|
52575
|
+
return encodePathUrl(linkBase ? relative4(linkBase, target).split(sep4).join("/") : target);
|
|
52576
|
+
}
|
|
52577
|
+
var HashedSidecarWriter = class {
|
|
52578
|
+
constructor(dir, linkBase) {
|
|
52579
|
+
this.dir = dir;
|
|
52580
|
+
this.linkBase = linkBase;
|
|
52581
|
+
}
|
|
52582
|
+
dir;
|
|
52583
|
+
linkBase;
|
|
52584
|
+
placed = /* @__PURE__ */ new Map();
|
|
52585
|
+
ready = false;
|
|
52586
|
+
/** Absolute paths of files written or reused. */
|
|
52587
|
+
files = [];
|
|
52588
|
+
count = 0;
|
|
52589
|
+
prepare() {
|
|
52590
|
+
if (this.ready) return;
|
|
52591
|
+
assertExportPath(this.dir);
|
|
52592
|
+
mkdirSync5(this.dir, { recursive: true });
|
|
52593
|
+
if (!lstatSync4(this.dir).isDirectory()) throw new Error("assets directory is not a directory");
|
|
52594
|
+
this.ready = true;
|
|
52595
|
+
}
|
|
52596
|
+
place(asset) {
|
|
52597
|
+
const done = this.placed.get(asset.path);
|
|
52598
|
+
if (done) return done;
|
|
52599
|
+
let source;
|
|
52600
|
+
try {
|
|
52601
|
+
source = openRegular(asset.path);
|
|
52602
|
+
} catch {
|
|
52603
|
+
return { error: "unreadable" };
|
|
52604
|
+
}
|
|
52605
|
+
try {
|
|
52606
|
+
const { hash, head } = digest(source);
|
|
52607
|
+
const mime = sniffMime(head, asset.name);
|
|
52608
|
+
this.prepare();
|
|
52609
|
+
const name = safeAssetName(asset.name, mime);
|
|
52610
|
+
const ext = extname4(name);
|
|
52611
|
+
const target = join21(
|
|
52612
|
+
this.dir,
|
|
52613
|
+
`${name.slice(0, name.length - ext.length)}-${hash.slice(0, 8)}${ext}`
|
|
52614
|
+
);
|
|
52615
|
+
let existing;
|
|
52616
|
+
try {
|
|
52617
|
+
existing = openRegular(target);
|
|
52618
|
+
} catch (error2) {
|
|
52619
|
+
const code = error2.code;
|
|
52620
|
+
if (code !== "ENOENT") return { error: "destination-not-regular" };
|
|
52621
|
+
}
|
|
52622
|
+
if (existing !== void 0) {
|
|
52623
|
+
try {
|
|
52624
|
+
if (digest(existing).hash !== hash) return { error: "name-taken" };
|
|
52625
|
+
} finally {
|
|
52626
|
+
closeSync5(existing);
|
|
52627
|
+
}
|
|
52628
|
+
} else this.copy(source, target);
|
|
52629
|
+
this.count++;
|
|
52630
|
+
this.files.push(target);
|
|
52631
|
+
const result = { url: urlFor(target, this.linkBase), mime };
|
|
52632
|
+
this.placed.set(asset.path, result);
|
|
52633
|
+
return result;
|
|
52634
|
+
} catch (error2) {
|
|
52635
|
+
return { error: error2 instanceof Error ? error2.message : String(error2) };
|
|
52636
|
+
} finally {
|
|
52637
|
+
closeSync5(source);
|
|
52638
|
+
}
|
|
52639
|
+
}
|
|
52640
|
+
copy(source, target) {
|
|
52641
|
+
const out = openSync5(
|
|
52642
|
+
target,
|
|
52643
|
+
constants5.O_WRONLY | constants5.O_CREAT | constants5.O_EXCL | constants5.O_NOFOLLOW,
|
|
52644
|
+
420
|
|
52645
|
+
);
|
|
52646
|
+
try {
|
|
52647
|
+
const chunk = Buffer.alloc(CHUNK);
|
|
52648
|
+
for (let position = 0; ; ) {
|
|
52649
|
+
const n = readSync4(source, chunk, 0, chunk.length, position);
|
|
52650
|
+
if (n <= 0) break;
|
|
52651
|
+
let written = 0;
|
|
52652
|
+
while (written < n) written += writeSync4(out, chunk, written, n - written);
|
|
52653
|
+
position += n;
|
|
52654
|
+
}
|
|
52655
|
+
} finally {
|
|
52656
|
+
closeSync5(out);
|
|
52657
|
+
}
|
|
52658
|
+
}
|
|
52659
|
+
};
|
|
52660
|
+
var ReferenceWriter = class {
|
|
52661
|
+
constructor(linkBase) {
|
|
52662
|
+
this.linkBase = linkBase;
|
|
52663
|
+
}
|
|
52664
|
+
linkBase;
|
|
52665
|
+
count = 0;
|
|
52666
|
+
place(asset) {
|
|
52667
|
+
let fd;
|
|
52668
|
+
try {
|
|
52669
|
+
fd = openRegular(asset.path);
|
|
52670
|
+
} catch {
|
|
52671
|
+
return { error: "unreadable" };
|
|
52672
|
+
}
|
|
52673
|
+
try {
|
|
52674
|
+
const head = Buffer.alloc(16);
|
|
52675
|
+
const n = readSync4(fd, head, 0, 16, 0);
|
|
52676
|
+
this.count++;
|
|
52677
|
+
return {
|
|
52678
|
+
url: urlFor(asset.path, this.linkBase),
|
|
52679
|
+
mime: sniffMime(head.subarray(0, n), asset.name)
|
|
52680
|
+
};
|
|
52681
|
+
} finally {
|
|
52682
|
+
closeSync5(fd);
|
|
52683
|
+
}
|
|
52684
|
+
}
|
|
52685
|
+
};
|
|
52686
|
+
function pathComponent(value) {
|
|
52687
|
+
const clean = Array.from(
|
|
52688
|
+
value.normalize("NFC"),
|
|
52689
|
+
(char) => char.charCodeAt(0) < 32 || char === "\x7F" ? "_" : char
|
|
52690
|
+
).join("").replace(/[/\\:]+/g, "_").replace(/^[.\s]+/, "").trim().slice(0, 120);
|
|
52691
|
+
return clean || "untitled";
|
|
52692
|
+
}
|
|
52693
|
+
function templateAssetsDir(directory, outputDir, values) {
|
|
52694
|
+
const safe = {};
|
|
52695
|
+
for (const [key, value] of Object.entries(values)) {
|
|
52696
|
+
const raw = typeof value === "string" ? value : value?.raw;
|
|
52697
|
+
if (raw !== void 0) safe[key] = pathComponent(raw);
|
|
52698
|
+
}
|
|
52699
|
+
const filled = fillPlaceholders(directory, safe);
|
|
52700
|
+
const base = resolve4(outputDir);
|
|
52701
|
+
const dir = resolve4(base, filled);
|
|
52702
|
+
if (isAbsolute3(filled) || filled.split("/").includes("..") || !dir.startsWith(base + sep4))
|
|
52703
|
+
throw new Error(`assets.directory "${directory}" resolves outside the output directory`);
|
|
52704
|
+
return dir;
|
|
52705
|
+
}
|
|
52706
|
+
function readTemplateFile(path10) {
|
|
52707
|
+
const abs = assertExportPath(path10);
|
|
52708
|
+
if (extname4(abs).toLowerCase() !== ".json")
|
|
52709
|
+
throw new Error(`Template file must have a .json extension: ${abs}`);
|
|
52710
|
+
let fd;
|
|
52711
|
+
try {
|
|
52712
|
+
fd = openRegular(abs);
|
|
52713
|
+
} catch (error2) {
|
|
52714
|
+
const code = error2.code;
|
|
52715
|
+
throw new Error(
|
|
52716
|
+
code === "ENOENT" ? `Template file not found: ${abs}` : code === "ELOOP" ? `Refusing to read the symbolic link ${abs}` : `Template file is not a readable regular file: ${abs}`
|
|
52717
|
+
);
|
|
52718
|
+
}
|
|
52719
|
+
try {
|
|
52720
|
+
const size = fstatSync5(fd).size;
|
|
52721
|
+
if (size > MAX_TEMPLATE_BYTES)
|
|
52722
|
+
throw new Error(`Template file is ${size} bytes; the limit is ${MAX_TEMPLATE_BYTES}`);
|
|
52723
|
+
const data = Buffer.alloc(size);
|
|
52724
|
+
let read = 0;
|
|
52725
|
+
while (read < size) {
|
|
52726
|
+
const n = readSync4(fd, data, read, size - read, read);
|
|
52727
|
+
if (n <= 0) break;
|
|
52728
|
+
read += n;
|
|
52729
|
+
}
|
|
52730
|
+
return data.subarray(0, read).toString("utf8");
|
|
52731
|
+
} finally {
|
|
52732
|
+
closeSync5(fd);
|
|
52733
|
+
}
|
|
52734
|
+
}
|
|
51375
52735
|
|
|
51376
52736
|
// src/services/notesExport.ts
|
|
51377
52737
|
var DEFAULT_FOLDER_EXPORT_LIMIT = 100;
|
|
51378
52738
|
var MAX_FOLDER_EXPORT_LIMIT = 1e3;
|
|
51379
52739
|
var NotesExportError = class extends Error {
|
|
51380
|
-
constructor(code, message) {
|
|
52740
|
+
constructor(code, message, details) {
|
|
51381
52741
|
super(message);
|
|
51382
52742
|
this.code = code;
|
|
52743
|
+
this.details = details;
|
|
51383
52744
|
this.name = "NotesExportError";
|
|
51384
52745
|
}
|
|
51385
52746
|
code;
|
|
52747
|
+
details;
|
|
51386
52748
|
};
|
|
52749
|
+
var MAX_EXPORT_WARNINGS = 200;
|
|
52750
|
+
var MAX_LISTED_ASSETS = 1e3;
|
|
52751
|
+
function chooseTemplate(request, deps) {
|
|
52752
|
+
if (request.template !== void 0 && request.templateFile !== void 0)
|
|
52753
|
+
throw new NotesExportError(
|
|
52754
|
+
"invalid-request",
|
|
52755
|
+
"Provide at most one of 'template' or 'templateFile'."
|
|
52756
|
+
);
|
|
52757
|
+
const invalid2 = (error2, where) => new NotesExportError("invalid-template", `${where}: ${error2.message}`, error2.errors);
|
|
52758
|
+
if (request.template !== void 0) {
|
|
52759
|
+
const name2 = request.template;
|
|
52760
|
+
if (isBuiltinTemplate(name2))
|
|
52761
|
+
return {
|
|
52762
|
+
info: { name: name2, source: "builtin" },
|
|
52763
|
+
template: resolveTemplate(builtinTemplate(name2), name2)
|
|
52764
|
+
};
|
|
52765
|
+
let portable2;
|
|
52766
|
+
try {
|
|
52767
|
+
portable2 = deps.findTemplate?.(name2);
|
|
52768
|
+
} catch (error2) {
|
|
52769
|
+
if (error2 instanceof TemplateValidationError)
|
|
52770
|
+
throw invalid2(error2, `Saved template "${name2}"`);
|
|
52771
|
+
throw error2;
|
|
52772
|
+
}
|
|
52773
|
+
if (!portable2) throw new NotesExportError("template-not-found", `No template named "${name2}".`);
|
|
52774
|
+
return { info: { name: name2, source: "saved" }, template: resolveTemplate(portable2, name2) };
|
|
52775
|
+
}
|
|
52776
|
+
if (request.templateFile === void 0) return void 0;
|
|
52777
|
+
let text2;
|
|
52778
|
+
try {
|
|
52779
|
+
text2 = readTemplateFile(request.templateFile);
|
|
52780
|
+
} catch (error2) {
|
|
52781
|
+
throw new NotesExportError(
|
|
52782
|
+
"invalid-path",
|
|
52783
|
+
`templateFile: ${error2 instanceof Error ? error2.message : String(error2)}`
|
|
52784
|
+
);
|
|
52785
|
+
}
|
|
52786
|
+
let portable;
|
|
52787
|
+
try {
|
|
52788
|
+
portable = parseTemplate(text2);
|
|
52789
|
+
} catch (error2) {
|
|
52790
|
+
throw invalid2(error2, "templateFile");
|
|
52791
|
+
}
|
|
52792
|
+
const name = portable.name ?? basename4(request.templateFile, extname5(request.templateFile));
|
|
52793
|
+
return { info: { name, source: "file" }, template: resolveTemplate(portable, name) };
|
|
52794
|
+
}
|
|
51387
52795
|
function validPath(path10, what) {
|
|
51388
52796
|
try {
|
|
51389
52797
|
return assertExportPath(path10);
|
|
@@ -51423,7 +52831,7 @@ function loadNotes(ids, single, read) {
|
|
|
51423
52831
|
return { notes, skipped };
|
|
51424
52832
|
}
|
|
51425
52833
|
function openOutput(output) {
|
|
51426
|
-
|
|
52834
|
+
mkdirSync6(dirname6(output), { recursive: true });
|
|
51427
52835
|
try {
|
|
51428
52836
|
return openCreateOnly(output);
|
|
51429
52837
|
} catch (error2) {
|
|
@@ -51445,8 +52853,16 @@ function exportNotesMarkdown(request, deps) {
|
|
|
51445
52853
|
const assetsDir = request.assetsDir ? validPath(request.assetsDir, "assetsDir") : void 0;
|
|
51446
52854
|
if (output && assetsDir && output === assetsDir)
|
|
51447
52855
|
throw new NotesExportError("invalid-path", "outputPath and assetsDir must differ.");
|
|
52856
|
+
const chosen = chooseTemplate(request, deps);
|
|
52857
|
+
if (chosen && assetsDir && chosen.template.assets.mode !== "copy")
|
|
52858
|
+
throw new NotesExportError(
|
|
52859
|
+
"invalid-request",
|
|
52860
|
+
`assetsDir has no effect: template "${chosen.info.name}" sets assets.mode to "${chosen.template.assets.mode}".`
|
|
52861
|
+
);
|
|
51448
52862
|
const ids = selectNotes(request, deps);
|
|
51449
52863
|
const { notes, skipped } = loadNotes(ids, !!request.id, deps.readNote);
|
|
52864
|
+
if (chosen)
|
|
52865
|
+
return exportWithTemplate(request, deps, chosen, notes, skipped, { output, assetsDir });
|
|
51450
52866
|
const fd = output ? openOutput(output) : void 0;
|
|
51451
52867
|
const writer = assetsDir ? new SidecarWriter(assetsDir, output ? dirname6(output) : void 0) : void 0;
|
|
51452
52868
|
const ctx = {
|
|
@@ -51478,7 +52894,7 @@ function exportNotesMarkdown(request, deps) {
|
|
|
51478
52894
|
return { ...receipt, markdown };
|
|
51479
52895
|
}
|
|
51480
52896
|
function defaultSidecarDir(output) {
|
|
51481
|
-
return
|
|
52897
|
+
return join22(dirname6(output), `${basename4(output, extname5(output))}.assets`);
|
|
51482
52898
|
}
|
|
51483
52899
|
function exportNotesHtml(request, deps) {
|
|
51484
52900
|
if (!request.outputPath)
|
|
@@ -51518,21 +52934,127 @@ function exportNotesHtml(request, deps) {
|
|
|
51518
52934
|
...assetsDir ? { assets: { dir: assetsDir, files: writer.count } } : { embedded: writer.count }
|
|
51519
52935
|
};
|
|
51520
52936
|
}
|
|
52937
|
+
function readMetaSafely(read, id2) {
|
|
52938
|
+
try {
|
|
52939
|
+
return read(id2);
|
|
52940
|
+
} catch {
|
|
52941
|
+
return {};
|
|
52942
|
+
}
|
|
52943
|
+
}
|
|
52944
|
+
function pathValues(note, meta, exportStem) {
|
|
52945
|
+
const values = { title: note.title.trim(), id: note.id, exportStem };
|
|
52946
|
+
for (const [key, value] of Object.entries(meta)) if (value) values[key] = value;
|
|
52947
|
+
return values;
|
|
52948
|
+
}
|
|
52949
|
+
function assetBindings(template, notes, meta, { output, assetsDir, exportStem }) {
|
|
52950
|
+
const linkBase = template.assets.pathStyle === "relative" && output ? dirname6(output) : void 0;
|
|
52951
|
+
const writers = /* @__PURE__ */ new Map();
|
|
52952
|
+
const writerFor = (dir) => {
|
|
52953
|
+
let writer = writers.get(dir);
|
|
52954
|
+
if (!writer) writers.set(dir, writer = new HashedSidecarWriter(dir, linkBase));
|
|
52955
|
+
return writer;
|
|
52956
|
+
};
|
|
52957
|
+
const reference = template.assets.mode === "reference" ? new ReferenceWriter(linkBase) : void 0;
|
|
52958
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
52959
|
+
for (const note of notes) {
|
|
52960
|
+
let binding = {};
|
|
52961
|
+
if (reference) binding = { writer: reference };
|
|
52962
|
+
else if (template.assets.mode === "copy") {
|
|
52963
|
+
if (assetsDir) binding = { writer: writerFor(assetsDir) };
|
|
52964
|
+
else if (template.assets.directory !== null && output) {
|
|
52965
|
+
let dir;
|
|
52966
|
+
try {
|
|
52967
|
+
dir = templateAssetsDir(
|
|
52968
|
+
template.assets.directory,
|
|
52969
|
+
dirname6(output),
|
|
52970
|
+
pathValues(note, meta.get(note) ?? {}, exportStem)
|
|
52971
|
+
);
|
|
52972
|
+
} catch (error2) {
|
|
52973
|
+
throw new NotesExportError("invalid-path", error2.message);
|
|
52974
|
+
}
|
|
52975
|
+
dir = validPath(dir, "assets.directory");
|
|
52976
|
+
if (dir === output)
|
|
52977
|
+
throw new NotesExportError("invalid-path", "assets.directory resolves to outputPath.");
|
|
52978
|
+
binding = { writer: writerFor(dir) };
|
|
52979
|
+
} else if (template.assets.directory !== null) binding = { required: true };
|
|
52980
|
+
}
|
|
52981
|
+
bindings.set(note, binding);
|
|
52982
|
+
}
|
|
52983
|
+
return { bindings, writers };
|
|
52984
|
+
}
|
|
52985
|
+
function exportWithTemplate(request, deps, chosen, notes, skipped, { output, assetsDir }) {
|
|
52986
|
+
const { template } = chosen;
|
|
52987
|
+
const readMeta = deps.readMeta ?? ((id2) => readExportNoteMeta(id2));
|
|
52988
|
+
const needsMeta = usesNoteMeta(template);
|
|
52989
|
+
const meta = new Map(
|
|
52990
|
+
notes.map((note) => [note, needsMeta ? readMetaSafely(readMeta, note.id) : {}])
|
|
52991
|
+
);
|
|
52992
|
+
const exportStem = output ? basename4(output, extname5(output)) : "export";
|
|
52993
|
+
const { bindings, writers } = assetBindings(template, notes, meta, {
|
|
52994
|
+
output,
|
|
52995
|
+
assetsDir,
|
|
52996
|
+
exportStem
|
|
52997
|
+
});
|
|
52998
|
+
const fd = output ? openOutput(output) : void 0;
|
|
52999
|
+
const ctx = { stats: emptyStats(), locator: deps.locator ?? new AssetLocator() };
|
|
53000
|
+
let warnings = [];
|
|
53001
|
+
const markdown = renderInto(fd, () => {
|
|
53002
|
+
const result = renderNotesWithTemplate(notes, ctx, {
|
|
53003
|
+
template,
|
|
53004
|
+
exportStem,
|
|
53005
|
+
wrap: request.wrap ?? 0,
|
|
53006
|
+
assetsFor: (note) => bindings.get(note) ?? {},
|
|
53007
|
+
metaFor: (note) => meta.get(note) ?? {}
|
|
53008
|
+
});
|
|
53009
|
+
warnings = result.warnings;
|
|
53010
|
+
return result.markdown;
|
|
53011
|
+
});
|
|
53012
|
+
const bytes = Buffer.byteLength(markdown);
|
|
53013
|
+
const used = [...writers.values()].filter((writer) => writer.count > 0);
|
|
53014
|
+
const files = used.flatMap((writer) => writer.files);
|
|
53015
|
+
const receipt = {
|
|
53016
|
+
format: "markdown",
|
|
53017
|
+
count: notes.length,
|
|
53018
|
+
bytes,
|
|
53019
|
+
stats: ctx.stats,
|
|
53020
|
+
skipped,
|
|
53021
|
+
template: chosen.info,
|
|
53022
|
+
warnings: warnings.slice(0, MAX_EXPORT_WARNINGS),
|
|
53023
|
+
...warnings.length > MAX_EXPORT_WARNINGS ? { warningsOmitted: warnings.length - MAX_EXPORT_WARNINGS } : {},
|
|
53024
|
+
...used.length ? {
|
|
53025
|
+
assets: {
|
|
53026
|
+
dir: used.length === 1 ? used[0].dir : dirname6(output),
|
|
53027
|
+
files: files.length
|
|
53028
|
+
},
|
|
53029
|
+
assetFiles: files.slice(0, MAX_LISTED_ASSETS)
|
|
53030
|
+
} : {}
|
|
53031
|
+
};
|
|
53032
|
+
if (fd !== void 0) {
|
|
53033
|
+
writeAllAndClose(fd, markdown);
|
|
53034
|
+
return { ...receipt, output };
|
|
53035
|
+
}
|
|
53036
|
+
if (bytes > deps.maxInlineBytes)
|
|
53037
|
+
throw new NotesExportError(
|
|
53038
|
+
"too-large",
|
|
53039
|
+
`The Markdown is ${bytes} bytes, over the ${deps.maxInlineBytes}-byte inline limit. Pass outputPath to write it to a file, or export fewer notes.`
|
|
53040
|
+
);
|
|
53041
|
+
return { ...receipt, markdown };
|
|
53042
|
+
}
|
|
51521
53043
|
|
|
51522
53044
|
// src/tools/directOperations.ts
|
|
51523
|
-
import { createHash as
|
|
53045
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
51524
53046
|
import {
|
|
51525
|
-
closeSync as
|
|
51526
|
-
constants as
|
|
51527
|
-
fstatSync as
|
|
53047
|
+
closeSync as closeSync6,
|
|
53048
|
+
constants as constants6,
|
|
53049
|
+
fstatSync as fstatSync6,
|
|
51528
53050
|
mkdtempSync as mkdtempSync5,
|
|
51529
|
-
openSync as
|
|
53051
|
+
openSync as openSync6,
|
|
51530
53052
|
readFileSync as readFileSync3,
|
|
51531
53053
|
rmSync as rmSync5,
|
|
51532
53054
|
writeFileSync as writeFileSync4
|
|
51533
53055
|
} from "node:fs";
|
|
51534
53056
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
51535
|
-
import { basename as basename5, extname as
|
|
53057
|
+
import { basename as basename5, extname as extname6, isAbsolute as isAbsolute4, join as join23 } from "node:path";
|
|
51536
53058
|
var noteId = exactIdInput(
|
|
51537
53059
|
"ICNote",
|
|
51538
53060
|
/^x-coredata:\/\/[0-9a-f-]+\/ICNote\/p\d+$/i,
|
|
@@ -51576,10 +53098,10 @@ function assertExistingContentPreserved(before, after) {
|
|
|
51576
53098
|
}
|
|
51577
53099
|
}
|
|
51578
53100
|
function localAttachment(path10) {
|
|
51579
|
-
if (!
|
|
51580
|
-
const descriptor =
|
|
53101
|
+
if (!isAbsolute4(path10)) throw new Error("An absolute local file path is required");
|
|
53102
|
+
const descriptor = openSync6(path10, constants6.O_RDONLY | constants6.O_NOFOLLOW);
|
|
51581
53103
|
try {
|
|
51582
|
-
const stat =
|
|
53104
|
+
const stat = fstatSync6(descriptor);
|
|
51583
53105
|
if (!stat.isFile() || stat.size === 0 || stat.size > 64 * 1024 * 1024)
|
|
51584
53106
|
throw new Error("Attachment must be a nonempty regular file of at most 64 MiB");
|
|
51585
53107
|
const bytes = readFileSync3(descriptor);
|
|
@@ -51587,7 +53109,7 @@ function localAttachment(path10) {
|
|
|
51587
53109
|
throw new Error("Attachment changed while it was being read; try again");
|
|
51588
53110
|
return bytes;
|
|
51589
53111
|
} finally {
|
|
51590
|
-
|
|
53112
|
+
closeSync6(descriptor);
|
|
51591
53113
|
}
|
|
51592
53114
|
}
|
|
51593
53115
|
function registerDirectOperations(server2, manager) {
|
|
@@ -51710,15 +53232,15 @@ function attachmentName(path10, filename) {
|
|
|
51710
53232
|
throw new Error(
|
|
51711
53233
|
"filename must be one path component with no slash, colon, backslash, control character, leading dot, or surrounding spaces"
|
|
51712
53234
|
);
|
|
51713
|
-
if (
|
|
53235
|
+
if (extname6(filename).toLowerCase() !== extname6(source).toLowerCase())
|
|
51714
53236
|
throw new Error(
|
|
51715
|
-
`filename must keep the source file's extension (${
|
|
53237
|
+
`filename must keep the source file's extension (${extname6(source) || "none"})`
|
|
51716
53238
|
);
|
|
51717
53239
|
return filename;
|
|
51718
53240
|
}
|
|
51719
53241
|
var UNCERTAIN = "Attachment insertion outcome uncertain; read the exact note before retrying";
|
|
51720
53242
|
var pause = (ms) => Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
51721
|
-
var sha256 = (data) =>
|
|
53243
|
+
var sha256 = (data) => createHash3("sha256").update(data).digest("hex");
|
|
51722
53244
|
function storedAttachmentIds(manager, id2) {
|
|
51723
53245
|
try {
|
|
51724
53246
|
return new Set(
|
|
@@ -51751,13 +53273,13 @@ function storedInsertion(manager, id2, before, bytes, returnedId) {
|
|
|
51751
53273
|
const matches = row.assetPaths.some((path10) => {
|
|
51752
53274
|
let descriptor;
|
|
51753
53275
|
try {
|
|
51754
|
-
descriptor =
|
|
51755
|
-
const stat =
|
|
53276
|
+
descriptor = openSync6(path10, constants6.O_RDONLY | constants6.O_NOFOLLOW);
|
|
53277
|
+
const stat = fstatSync6(descriptor);
|
|
51756
53278
|
return stat.isFile() && stat.size === bytes.length && sha256(readFileSync3(descriptor)) === expected;
|
|
51757
53279
|
} catch {
|
|
51758
53280
|
return false;
|
|
51759
53281
|
} finally {
|
|
51760
|
-
if (descriptor !== void 0)
|
|
53282
|
+
if (descriptor !== void 0) closeSync6(descriptor);
|
|
51761
53283
|
}
|
|
51762
53284
|
});
|
|
51763
53285
|
if (!matches)
|
|
@@ -51774,8 +53296,8 @@ function attachFile(manager, args) {
|
|
|
51774
53296
|
const bytes = localAttachment(path10);
|
|
51775
53297
|
const beforeAttachments = manager.listAttachmentsById(id2);
|
|
51776
53298
|
const beforeStored = storedAttachmentIds(manager, id2);
|
|
51777
|
-
const directory = mkdtempSync5(
|
|
51778
|
-
const temporaryFile =
|
|
53299
|
+
const directory = mkdtempSync5(join23(tmpdir5(), "notes-attachment-add-"));
|
|
53300
|
+
const temporaryFile = join23(directory, name);
|
|
51779
53301
|
try {
|
|
51780
53302
|
writeFileSync4(temporaryFile, bytes, { mode: 384 });
|
|
51781
53303
|
if (readSnapshot(manager, id2).hash !== before.hash) throw new Error("Note revision changed");
|
|
@@ -51842,7 +53364,7 @@ function attachFile(manager, args) {
|
|
|
51842
53364
|
}
|
|
51843
53365
|
|
|
51844
53366
|
// src/tools/folderDelete.ts
|
|
51845
|
-
import { createHash as
|
|
53367
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
51846
53368
|
|
|
51847
53369
|
// src/utils/folderStore.ts
|
|
51848
53370
|
import { execFileSync as execFileSync19 } from "child_process";
|
|
@@ -52029,7 +53551,7 @@ function folderDeleteRevision(app, store) {
|
|
|
52029
53551
|
store.childFolderCount,
|
|
52030
53552
|
store.noteCount
|
|
52031
53553
|
];
|
|
52032
|
-
return `sha256:${
|
|
53554
|
+
return `sha256:${createHash4("sha256").update(JSON.stringify(state)).digest("hex")}`;
|
|
52033
53555
|
}
|
|
52034
53556
|
function checkFolder(manager, args, deps) {
|
|
52035
53557
|
const app = manager.readFolderForDelete(args.id);
|
|
@@ -52165,8 +53687,8 @@ function registerFolderDelete(server2, manager, deps = defaultDeps) {
|
|
|
52165
53687
|
}
|
|
52166
53688
|
|
|
52167
53689
|
// src/utils/svgAnalyzer.ts
|
|
52168
|
-
import { createHash as
|
|
52169
|
-
import { closeSync as
|
|
53690
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
53691
|
+
import { closeSync as closeSync7, constants as constants7, fstatSync as fstatSync7, openSync as openSync7, readSync as readSync5 } from "node:fs";
|
|
52170
53692
|
|
|
52171
53693
|
// src/utils/svgColor.ts
|
|
52172
53694
|
var NAMED = {
|
|
@@ -52840,10 +54362,10 @@ function clipPolyline(points, r) {
|
|
|
52840
54362
|
if (run.length) parts.push(run);
|
|
52841
54363
|
return { parts, clipped: true };
|
|
52842
54364
|
}
|
|
52843
|
-
function dashPolyline(points,
|
|
52844
|
-
const total =
|
|
54365
|
+
function dashPolyline(points, pattern2, offset, charge) {
|
|
54366
|
+
const total = pattern2.reduce((s, v) => s + v, 0);
|
|
52845
54367
|
let index = 0;
|
|
52846
|
-
let remaining =
|
|
54368
|
+
let remaining = pattern2[0];
|
|
52847
54369
|
let on = true;
|
|
52848
54370
|
let shift = (offset % total + total) % total;
|
|
52849
54371
|
while (shift > 0) {
|
|
@@ -52851,8 +54373,8 @@ function dashPolyline(points, pattern, offset, charge) {
|
|
|
52851
54373
|
remaining -= step;
|
|
52852
54374
|
shift -= step;
|
|
52853
54375
|
if (remaining <= 0) {
|
|
52854
|
-
index = (index + 1) %
|
|
52855
|
-
remaining =
|
|
54376
|
+
index = (index + 1) % pattern2.length;
|
|
54377
|
+
remaining = pattern2[index];
|
|
52856
54378
|
on = !on;
|
|
52857
54379
|
}
|
|
52858
54380
|
}
|
|
@@ -52874,8 +54396,8 @@ function dashPolyline(points, pattern, offset, charge) {
|
|
|
52874
54396
|
on = !on;
|
|
52875
54397
|
segLen -= remaining;
|
|
52876
54398
|
a = cut;
|
|
52877
|
-
index = (index + 1) %
|
|
52878
|
-
remaining =
|
|
54399
|
+
index = (index + 1) % pattern2.length;
|
|
54400
|
+
remaining = pattern2[index];
|
|
52879
54401
|
}
|
|
52880
54402
|
remaining -= segLen;
|
|
52881
54403
|
if (on && currentDash) currentDash.push(b);
|
|
@@ -53107,7 +54629,7 @@ function parseXml(source, limits) {
|
|
|
53107
54629
|
if (a.name === "xmlns") scope2.set("", a.value);
|
|
53108
54630
|
else if (a.name.startsWith("xmlns:")) scope2.set(a.name.slice(6), a.value);
|
|
53109
54631
|
}
|
|
53110
|
-
const
|
|
54632
|
+
const resolve8 = (qualified, isAttribute) => {
|
|
53111
54633
|
const colon = qualified.indexOf(":");
|
|
53112
54634
|
if (colon < 0) return { local: qualified, ns: isAttribute ? null : scope2.get("") ?? null };
|
|
53113
54635
|
const prefix = qualified.slice(0, colon);
|
|
@@ -53117,12 +54639,12 @@ function parseXml(source, limits) {
|
|
|
53117
54639
|
if (ns === void 0) fail(`Undeclared namespace prefix "${prefix.slice(0, 40)}"`);
|
|
53118
54640
|
return { local, ns };
|
|
53119
54641
|
};
|
|
53120
|
-
const resolved =
|
|
54642
|
+
const resolved = resolve8(name, false);
|
|
53121
54643
|
const element = {
|
|
53122
54644
|
name,
|
|
53123
54645
|
local: resolved.local,
|
|
53124
54646
|
ns: resolved.ns,
|
|
53125
|
-
attributes: rawAttributes.filter((a) => a.name !== "xmlns" && !a.name.startsWith("xmlns:")).map((a) => ({ name: a.name, value: a.value, ...
|
|
54647
|
+
attributes: rawAttributes.filter((a) => a.name !== "xmlns" && !a.name.startsWith("xmlns:")).map((a) => ({ name: a.name, value: a.value, ...resolve8(a.name, true) })),
|
|
53126
54648
|
children: [],
|
|
53127
54649
|
text: "",
|
|
53128
54650
|
line: tagLine
|
|
@@ -53248,7 +54770,7 @@ function canonicalJson(value) {
|
|
|
53248
54770
|
return JSON.stringify(value);
|
|
53249
54771
|
}
|
|
53250
54772
|
function sha2562(text2) {
|
|
53251
|
-
return
|
|
54773
|
+
return createHash5("sha256").update(text2).digest("hex");
|
|
53252
54774
|
}
|
|
53253
54775
|
var round = (v, digits) => {
|
|
53254
54776
|
const r = Number(v.toFixed(digits));
|
|
@@ -53365,10 +54887,10 @@ function assertInert(el, location) {
|
|
|
53365
54887
|
throw new SvgError("svg_unsafe", "Active content in a style attribute", location);
|
|
53366
54888
|
}
|
|
53367
54889
|
const counts = /* @__PURE__ */ new Map();
|
|
53368
|
-
for (const
|
|
53369
|
-
const n = (counts.get(
|
|
53370
|
-
counts.set(
|
|
53371
|
-
assertInert(
|
|
54890
|
+
for (const child2 of el.children) {
|
|
54891
|
+
const n = (counts.get(child2.local) ?? 0) + 1;
|
|
54892
|
+
counts.set(child2.local, n);
|
|
54893
|
+
assertInert(child2, `${location}/${child2.local}[${n}]`);
|
|
53372
54894
|
}
|
|
53373
54895
|
}
|
|
53374
54896
|
var INITIAL_STYLE = {
|
|
@@ -53620,14 +55142,14 @@ var Analyzer = class {
|
|
|
53620
55142
|
/** Walk an element's children with its own style and transform applied. */
|
|
53621
55143
|
container(el, ctx) {
|
|
53622
55144
|
const counts = /* @__PURE__ */ new Map();
|
|
53623
|
-
for (const
|
|
53624
|
-
const n = (counts.get(
|
|
53625
|
-
counts.set(
|
|
53626
|
-
const id2 = attr(
|
|
53627
|
-
this.element(
|
|
55145
|
+
for (const child2 of el.children) {
|
|
55146
|
+
const n = (counts.get(child2.local) ?? 0) + 1;
|
|
55147
|
+
counts.set(child2.local, n);
|
|
55148
|
+
const id2 = attr(child2, "id");
|
|
55149
|
+
this.element(child2, {
|
|
53628
55150
|
...ctx,
|
|
53629
55151
|
depth: ctx.depth + 1,
|
|
53630
|
-
location: `${ctx.location}/${
|
|
55152
|
+
location: `${ctx.location}/${child2.local}[${n}]${id2 ? `#${id2}` : ""}`
|
|
53631
55153
|
});
|
|
53632
55154
|
}
|
|
53633
55155
|
}
|
|
@@ -54050,9 +55572,9 @@ var Analyzer = class {
|
|
|
54050
55572
|
let pieces = polylines;
|
|
54051
55573
|
if (style.dasharray) {
|
|
54052
55574
|
const k = nonScaling ? 1 : mean;
|
|
54053
|
-
const
|
|
55575
|
+
const pattern2 = style.dasharray.map((v) => v * k);
|
|
54054
55576
|
pieces = polylines.flatMap(
|
|
54055
|
-
(p) => dashPolyline(p,
|
|
55577
|
+
(p) => dashPolyline(p, pattern2, style.dashoffset * k, (n) => this.charge("dashWork", n))
|
|
54056
55578
|
);
|
|
54057
55579
|
}
|
|
54058
55580
|
this.layers++;
|
|
@@ -54135,14 +55657,14 @@ function analyzeSvgBuffer(source) {
|
|
|
54135
55657
|
function readSvgSource(path10) {
|
|
54136
55658
|
let fd;
|
|
54137
55659
|
try {
|
|
54138
|
-
fd =
|
|
55660
|
+
fd = openSync7(path10, constants7.O_RDONLY | constants7.O_NOFOLLOW | constants7.O_NONBLOCK);
|
|
54139
55661
|
} catch (error2) {
|
|
54140
55662
|
if (error2.code === "ELOOP")
|
|
54141
55663
|
throw new SvgError("svg_file_invalid", "The SVG path is a symbolic link");
|
|
54142
55664
|
throw new SvgError("svg_file_invalid", "The SVG file does not exist or cannot be read");
|
|
54143
55665
|
}
|
|
54144
55666
|
try {
|
|
54145
|
-
const info =
|
|
55667
|
+
const info = fstatSync7(fd);
|
|
54146
55668
|
if (!info.isFile())
|
|
54147
55669
|
throw new SvgError("svg_file_invalid", "The SVG path is not a regular file");
|
|
54148
55670
|
if (info.size > SVG_LIMITS.maxSourceBytes)
|
|
@@ -54153,7 +55675,7 @@ function readSvgSource(path10) {
|
|
|
54153
55675
|
const buffer = Buffer.alloc(SVG_LIMITS.maxSourceBytes + 1);
|
|
54154
55676
|
let total = 0;
|
|
54155
55677
|
for (; ; ) {
|
|
54156
|
-
const n =
|
|
55678
|
+
const n = readSync5(fd, buffer, total, buffer.length - total, null);
|
|
54157
55679
|
if (n === 0) break;
|
|
54158
55680
|
total += n;
|
|
54159
55681
|
if (total > SVG_LIMITS.maxSourceBytes)
|
|
@@ -54164,7 +55686,7 @@ function readSvgSource(path10) {
|
|
|
54164
55686
|
}
|
|
54165
55687
|
return buffer.subarray(0, total);
|
|
54166
55688
|
} finally {
|
|
54167
|
-
|
|
55689
|
+
closeSync7(fd);
|
|
54168
55690
|
}
|
|
54169
55691
|
}
|
|
54170
55692
|
function analyzeSvgFile(path10) {
|
|
@@ -54735,7 +56257,7 @@ function registerNativeOperations(server2, manager) {
|
|
|
54735
56257
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
54736
56258
|
import { existsSync as existsSync13 } from "node:fs";
|
|
54737
56259
|
import { release as release2 } from "node:os";
|
|
54738
|
-
import { dirname as dirname7, resolve as
|
|
56260
|
+
import { dirname as dirname7, resolve as resolve5 } from "node:path";
|
|
54739
56261
|
import { fileURLToPath } from "node:url";
|
|
54740
56262
|
var OPTIONAL_BRIDGE_NOTE = "(optional \u2014 needed only for create-note format: markdown, macOS 26+)";
|
|
54741
56263
|
var MARKDOWN_MIN_DARWIN_MAJOR = 25;
|
|
@@ -54758,11 +56280,11 @@ function setupShortcuts(checkOnly, dependencies = {}) {
|
|
|
54758
56280
|
const result = spawnSync2("/usr/bin/open", [path10], { encoding: "utf8" });
|
|
54759
56281
|
return result.status === 0 ? { ok: true } : { ok: false, error: result.stderr || result.error?.message || "open failed" };
|
|
54760
56282
|
});
|
|
54761
|
-
const baseDirectory = dependencies.baseDirectory ||
|
|
56283
|
+
const baseDirectory = dependencies.baseDirectory || resolve5(dirname7(fileURLToPath(import.meta.url)), "../shortcuts");
|
|
54762
56284
|
const osRelease = (dependencies.osRelease || release2)();
|
|
54763
56285
|
const darwinMajor = Number.parseInt(osRelease.split(".")[0], 10);
|
|
54764
56286
|
const items = shortcutFiles.map(({ name, file, optional: optional2 }) => {
|
|
54765
|
-
const path10 =
|
|
56287
|
+
const path10 = resolve5(baseDirectory, file);
|
|
54766
56288
|
let installed = false;
|
|
54767
56289
|
let identifier;
|
|
54768
56290
|
let error2;
|
|
@@ -54822,11 +56344,11 @@ function formatShortcutSetup(report) {
|
|
|
54822
56344
|
|
|
54823
56345
|
// src/services/publicHelper.ts
|
|
54824
56346
|
import { spawn, spawnSync as spawnSync3 } from "node:child_process";
|
|
54825
|
-
import { createHash as
|
|
56347
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
54826
56348
|
import {
|
|
54827
56349
|
chmodSync,
|
|
54828
56350
|
existsSync as existsSync14,
|
|
54829
|
-
mkdirSync as
|
|
56351
|
+
mkdirSync as mkdirSync7,
|
|
54830
56352
|
mkdtempSync as mkdtempSync6,
|
|
54831
56353
|
readFileSync as readFileSync4,
|
|
54832
56354
|
renameSync,
|
|
@@ -54834,7 +56356,7 @@ import {
|
|
|
54834
56356
|
writeFileSync as writeFileSync5
|
|
54835
56357
|
} from "node:fs";
|
|
54836
56358
|
import { homedir as homedir19, release as release3 } from "node:os";
|
|
54837
|
-
import { dirname as dirname8, join as
|
|
56359
|
+
import { dirname as dirname8, join as join25, resolve as resolve6 } from "node:path";
|
|
54838
56360
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
54839
56361
|
var PUBLIC_HELPER_PROTOCOL = 1;
|
|
54840
56362
|
var PUBLIC_HELPER_DIR_ENV = "APPLE_NOTES_MCP_PUBLIC_HELPER_DIR";
|
|
@@ -54862,7 +56384,7 @@ var publicManifestSchema = external_exports.object({
|
|
|
54862
56384
|
function packageRoot(fromDir = dirname8(fileURLToPath2(import.meta.url))) {
|
|
54863
56385
|
let dir = fromDir;
|
|
54864
56386
|
for (; ; ) {
|
|
54865
|
-
const candidate =
|
|
56387
|
+
const candidate = join25(dir, "package.json");
|
|
54866
56388
|
if (existsSync14(candidate)) {
|
|
54867
56389
|
try {
|
|
54868
56390
|
if (JSON.parse(readFileSync4(candidate, "utf8")).name === "apple-notes-mcp")
|
|
@@ -54871,7 +56393,7 @@ function packageRoot(fromDir = dirname8(fileURLToPath2(import.meta.url))) {
|
|
|
54871
56393
|
}
|
|
54872
56394
|
}
|
|
54873
56395
|
const parent = dirname8(dir);
|
|
54874
|
-
if (parent === dir) return
|
|
56396
|
+
if (parent === dir) return resolve6(fromDir, "..");
|
|
54875
56397
|
dir = parent;
|
|
54876
56398
|
}
|
|
54877
56399
|
}
|
|
@@ -54879,7 +56401,7 @@ function defaultPublicHelperDeps(overrides = {}) {
|
|
|
54879
56401
|
return {
|
|
54880
56402
|
env: process.env,
|
|
54881
56403
|
platform: process.platform,
|
|
54882
|
-
sourcePath:
|
|
56404
|
+
sourcePath: join25(packageRoot(), PUBLIC_HELPER_SOURCE),
|
|
54883
56405
|
exists: existsSync14,
|
|
54884
56406
|
readFile: (path10) => readFileSync4(path10),
|
|
54885
56407
|
spawn: spawnSync3,
|
|
@@ -54890,14 +56412,14 @@ function defaultPublicHelperDeps(overrides = {}) {
|
|
|
54890
56412
|
function publicHelperInstallDir(env = process.env) {
|
|
54891
56413
|
const override = env[PUBLIC_HELPER_DIR_ENV]?.trim();
|
|
54892
56414
|
if (override) return override;
|
|
54893
|
-
return
|
|
56415
|
+
return join25(homedir19(), "Library", "Application Support", "apple-notes-mcp", "public-helper");
|
|
54894
56416
|
}
|
|
54895
56417
|
function sha256Hex(data) {
|
|
54896
|
-
return
|
|
56418
|
+
return createHash6("sha256").update(data).digest("hex");
|
|
54897
56419
|
}
|
|
54898
56420
|
function inspectPublicHelper(deps = defaultPublicHelperDeps()) {
|
|
54899
56421
|
const installDir = publicHelperInstallDir(deps.env);
|
|
54900
|
-
const binaryPath =
|
|
56422
|
+
const binaryPath = join25(installDir, PUBLIC_HELPER_BINARY);
|
|
54901
56423
|
const base = { installDir, binaryPath, sourcePath: deps.sourcePath, manifest: null };
|
|
54902
56424
|
const fail = (reason, detail) => ({
|
|
54903
56425
|
...base,
|
|
@@ -54908,7 +56430,7 @@ function inspectPublicHelper(deps = defaultPublicHelperDeps()) {
|
|
|
54908
56430
|
if (deps.platform !== "darwin") return fail("unsupported_platform", "macOS only");
|
|
54909
56431
|
if (!deps.exists(deps.sourcePath))
|
|
54910
56432
|
return fail("helper_not_installed", `Packaged helper source is missing: ${deps.sourcePath}`);
|
|
54911
|
-
const manifestPath =
|
|
56433
|
+
const manifestPath = join25(installDir, PUBLIC_HELPER_MANIFEST);
|
|
54912
56434
|
if (!deps.exists(binaryPath) || !deps.exists(manifestPath))
|
|
54913
56435
|
return fail(
|
|
54914
56436
|
"helper_not_installed",
|
|
@@ -54995,7 +56517,7 @@ async function callPublicHelperAsync(action, fields = {}, deps = defaultPublicHe
|
|
|
54995
56517
|
const aborted2 = () => new PublicHelperError("aborted", "The request was cancelled; the helper was stopped.");
|
|
54996
56518
|
if (signal?.aborted) throw aborted2();
|
|
54997
56519
|
return new Promise((resolvePromise, reject) => {
|
|
54998
|
-
const
|
|
56520
|
+
const child2 = (deps.spawnAsync ?? spawn)(binaryPath, [], {
|
|
54999
56521
|
stdio: ["pipe", "pipe", "ignore"]
|
|
55000
56522
|
});
|
|
55001
56523
|
const chunks = [];
|
|
@@ -55003,7 +56525,7 @@ async function callPublicHelperAsync(action, fields = {}, deps = defaultPublicHe
|
|
|
55003
56525
|
let failure = null;
|
|
55004
56526
|
const stop = (error2) => {
|
|
55005
56527
|
failure ??= error2;
|
|
55006
|
-
|
|
56528
|
+
child2.kill("SIGKILL");
|
|
55007
56529
|
};
|
|
55008
56530
|
const timer = setTimeout(
|
|
55009
56531
|
() => stop(new PublicHelperError("timeout", `The helper did not answer within ${timeout} ms.`)),
|
|
@@ -55015,19 +56537,19 @@ async function callPublicHelperAsync(action, fields = {}, deps = defaultPublicHe
|
|
|
55015
56537
|
clearTimeout(timer);
|
|
55016
56538
|
signal?.removeEventListener("abort", onAbort);
|
|
55017
56539
|
};
|
|
55018
|
-
|
|
56540
|
+
child2.stdout?.on("data", (chunk) => {
|
|
55019
56541
|
size += chunk.length;
|
|
55020
56542
|
if (size > MAX_OUTPUT_BYTES2)
|
|
55021
56543
|
stop(new PublicHelperError("invalid_response", "The helper response is too large."));
|
|
55022
56544
|
else chunks.push(chunk);
|
|
55023
56545
|
});
|
|
55024
|
-
|
|
56546
|
+
child2.on("error", (error2) => {
|
|
55025
56547
|
settle();
|
|
55026
56548
|
reject(
|
|
55027
56549
|
failure ?? new PublicHelperError("helper_unreachable", `Could not run the helper: ${error2.message}`)
|
|
55028
56550
|
);
|
|
55029
56551
|
});
|
|
55030
|
-
|
|
56552
|
+
child2.on("close", (status, exitSignal) => {
|
|
55031
56553
|
settle();
|
|
55032
56554
|
if (failure) return reject(failure);
|
|
55033
56555
|
if (status === null && exitSignal)
|
|
@@ -55040,9 +56562,9 @@ async function callPublicHelperAsync(action, fields = {}, deps = defaultPublicHe
|
|
|
55040
56562
|
reject(error2);
|
|
55041
56563
|
}
|
|
55042
56564
|
});
|
|
55043
|
-
|
|
56565
|
+
child2.stdin?.on("error", () => {
|
|
55044
56566
|
});
|
|
55045
|
-
|
|
56567
|
+
child2.stdin?.end(input);
|
|
55046
56568
|
});
|
|
55047
56569
|
}
|
|
55048
56570
|
function prepareCall(action, fields, deps, options) {
|
|
@@ -55184,12 +56706,12 @@ function buildPublicHelper(checkOnly, deps = defaultPublicHelperBuildDeps()) {
|
|
|
55184
56706
|
const compiler = String(version3.stdout || version3.stderr || "").split("\n").find((line) => line.includes("Swift version"))?.trim() || "swiftc";
|
|
55185
56707
|
steps.push({ step: "find compiler", ok: true, detail: compiler });
|
|
55186
56708
|
const installDir = publicHelperInstallDir(deps.env);
|
|
55187
|
-
|
|
55188
|
-
const staging = mkdtempSync6(
|
|
56709
|
+
mkdirSync7(installDir, { recursive: true, mode: 448 });
|
|
56710
|
+
const staging = mkdtempSync6(join25(installDir, ".staging-"));
|
|
55189
56711
|
try {
|
|
55190
|
-
const stagedBinary =
|
|
55191
|
-
const digestPath =
|
|
55192
|
-
const plistPath =
|
|
56712
|
+
const stagedBinary = join25(staging, PUBLIC_HELPER_BINARY);
|
|
56713
|
+
const digestPath = join25(staging, "source-digest.swift");
|
|
56714
|
+
const plistPath = join25(staging, "Info.plist");
|
|
55193
56715
|
writeFileSync5(digestPath, sourceDigestSwift(sourceSha), { mode: 384 });
|
|
55194
56716
|
writeFileSync5(plistPath, publicHelperInfoPlist(), { mode: 384 });
|
|
55195
56717
|
const compile = deps.spawn(
|
|
@@ -55252,9 +56774,9 @@ function buildPublicHelper(checkOnly, deps = defaultPublicHelperBuildDeps()) {
|
|
|
55252
56774
|
compiler
|
|
55253
56775
|
};
|
|
55254
56776
|
chmodSync(stagedBinary, 448);
|
|
55255
|
-
renameSync(stagedBinary,
|
|
56777
|
+
renameSync(stagedBinary, join25(installDir, PUBLIC_HELPER_BINARY));
|
|
55256
56778
|
writeFileSync5(
|
|
55257
|
-
|
|
56779
|
+
join25(installDir, PUBLIC_HELPER_MANIFEST),
|
|
55258
56780
|
JSON.stringify(manifest, null, 2) + "\n",
|
|
55259
56781
|
{ mode: 384 }
|
|
55260
56782
|
);
|
|
@@ -55499,7 +57021,7 @@ function formatNoteDrawings(result) {
|
|
|
55499
57021
|
|
|
55500
57022
|
// src/utils/noteAudio.ts
|
|
55501
57023
|
import { readdirSync as readdirSync4, statSync as statSync4 } from "node:fs";
|
|
55502
|
-
import { join as
|
|
57024
|
+
import { join as join26 } from "node:path";
|
|
55503
57025
|
var EXTRA_AUDIO_UTIS = [
|
|
55504
57026
|
"public.mp3",
|
|
55505
57027
|
"public.aiff-audio",
|
|
@@ -55524,7 +57046,7 @@ function accountDirsFor(containerDir, accountIdentifier) {
|
|
|
55524
57046
|
if (own) return [own];
|
|
55525
57047
|
let names;
|
|
55526
57048
|
try {
|
|
55527
|
-
names = readdirSync4(
|
|
57049
|
+
names = readdirSync4(join26(containerDir, "Accounts")).sort();
|
|
55528
57050
|
} catch {
|
|
55529
57051
|
return [];
|
|
55530
57052
|
}
|
|
@@ -55536,8 +57058,8 @@ function resolveMediaPath(media, accountIdentifier = null, containerDir = NOTES_
|
|
|
55536
57058
|
if (!id2 || !filename) return null;
|
|
55537
57059
|
const generation = safeComponent(media?.generation);
|
|
55538
57060
|
for (const dir of accountDirsFor(containerDir, accountIdentifier)) {
|
|
55539
|
-
const base =
|
|
55540
|
-
const candidates = generation ? [
|
|
57061
|
+
const base = join26(dir, "Media", id2);
|
|
57062
|
+
const candidates = generation ? [join26(base, generation, filename), join26(base, filename)] : [join26(base, filename)];
|
|
55541
57063
|
for (const candidate of candidates) {
|
|
55542
57064
|
const real = realInside(candidate, dir);
|
|
55543
57065
|
if (real && isFile2(real)) return real;
|
|
@@ -55809,21 +57331,21 @@ import { spawnSync as spawnSync5 } from "node:child_process";
|
|
|
55809
57331
|
import {
|
|
55810
57332
|
chmodSync as chmodSync2,
|
|
55811
57333
|
existsSync as existsSync16,
|
|
55812
|
-
mkdirSync as
|
|
57334
|
+
mkdirSync as mkdirSync8,
|
|
55813
57335
|
mkdtempSync as mkdtempSync7,
|
|
55814
57336
|
renameSync as renameSync2,
|
|
55815
57337
|
rmSync as rmSync7,
|
|
55816
57338
|
writeFileSync as writeFileSync6
|
|
55817
57339
|
} from "node:fs";
|
|
55818
57340
|
import { release as release4 } from "node:os";
|
|
55819
|
-
import { join as
|
|
57341
|
+
import { join as join28 } from "node:path";
|
|
55820
57342
|
|
|
55821
57343
|
// src/services/privateHelper.ts
|
|
55822
57344
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
55823
|
-
import { createHash as
|
|
57345
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
55824
57346
|
import { existsSync as existsSync15, readFileSync as readFileSync5 } from "node:fs";
|
|
55825
57347
|
import { homedir as homedir20 } from "node:os";
|
|
55826
|
-
import { dirname as dirname9, join as
|
|
57348
|
+
import { dirname as dirname9, join as join27, resolve as resolve7 } from "node:path";
|
|
55827
57349
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
55828
57350
|
var PRIVATE_HELPER_PROTOCOL = 1;
|
|
55829
57351
|
var ENABLE_ENV = "APPLE_NOTES_MCP_ENABLE_PRIVATE";
|
|
@@ -55851,7 +57373,7 @@ var manifestSchema = external_exports.object({
|
|
|
55851
57373
|
function packageRoot2(fromDir = dirname9(fileURLToPath3(import.meta.url))) {
|
|
55852
57374
|
let dir = fromDir;
|
|
55853
57375
|
for (; ; ) {
|
|
55854
|
-
const candidate =
|
|
57376
|
+
const candidate = join27(dir, "package.json");
|
|
55855
57377
|
if (existsSync15(candidate)) {
|
|
55856
57378
|
try {
|
|
55857
57379
|
const pkg = JSON.parse(readFileSync5(candidate, "utf8"));
|
|
@@ -55860,7 +57382,7 @@ function packageRoot2(fromDir = dirname9(fileURLToPath3(import.meta.url))) {
|
|
|
55860
57382
|
}
|
|
55861
57383
|
}
|
|
55862
57384
|
const parent = dirname9(dir);
|
|
55863
|
-
if (parent === dir) return
|
|
57385
|
+
if (parent === dir) return resolve7(fromDir, "..");
|
|
55864
57386
|
dir = parent;
|
|
55865
57387
|
}
|
|
55866
57388
|
}
|
|
@@ -55868,7 +57390,7 @@ function defaultDeps2(overrides = {}) {
|
|
|
55868
57390
|
return {
|
|
55869
57391
|
env: process.env,
|
|
55870
57392
|
platform: process.platform,
|
|
55871
|
-
sourcePath:
|
|
57393
|
+
sourcePath: join27(packageRoot2(), HELPER_SOURCE_RELATIVE),
|
|
55872
57394
|
exists: existsSync15,
|
|
55873
57395
|
readFile: (path10) => readFileSync5(path10),
|
|
55874
57396
|
spawn: spawnSync4,
|
|
@@ -55881,14 +57403,14 @@ function privateHelperEnabled(env = process.env) {
|
|
|
55881
57403
|
function helperInstallDir(env = process.env) {
|
|
55882
57404
|
const override = env[HELPER_DIR_ENV]?.trim();
|
|
55883
57405
|
if (override) return override;
|
|
55884
|
-
return
|
|
57406
|
+
return join27(homedir20(), "Library", "Application Support", "apple-notes-mcp", "private-helper");
|
|
55885
57407
|
}
|
|
55886
57408
|
function sha256Hex2(data) {
|
|
55887
|
-
return
|
|
57409
|
+
return createHash7("sha256").update(data).digest("hex");
|
|
55888
57410
|
}
|
|
55889
57411
|
function inspectInstallation(deps = defaultDeps2()) {
|
|
55890
57412
|
const installDir = helperInstallDir(deps.env);
|
|
55891
|
-
const binaryPath =
|
|
57413
|
+
const binaryPath = join27(installDir, HELPER_BINARY_NAME);
|
|
55892
57414
|
const base = {
|
|
55893
57415
|
installDir,
|
|
55894
57416
|
binaryPath,
|
|
@@ -55906,7 +57428,7 @@ function inspectInstallation(deps = defaultDeps2()) {
|
|
|
55906
57428
|
if (!deps.exists(deps.sourcePath))
|
|
55907
57429
|
return fail("helper_not_installed", `Packaged helper source is missing: ${deps.sourcePath}`);
|
|
55908
57430
|
base.expectedSourceSha256 = sha256Hex2(deps.readFile(deps.sourcePath));
|
|
55909
|
-
const manifestPath =
|
|
57431
|
+
const manifestPath = join27(installDir, MANIFEST_NAME);
|
|
55910
57432
|
if (!deps.exists(binaryPath) || !deps.exists(manifestPath))
|
|
55911
57433
|
return fail(
|
|
55912
57434
|
"helper_not_installed",
|
|
@@ -56220,10 +57742,10 @@ function buildPrivateHelper(checkOnly, deps = defaultBuildDeps()) {
|
|
|
56220
57742
|
const compiler = String(clangVersion.stdout || "").split("\n")[0] || "clang";
|
|
56221
57743
|
steps.push({ step: "find compiler", ok: true, detail: compiler });
|
|
56222
57744
|
const installDir = helperInstallDir(deps.env);
|
|
56223
|
-
|
|
56224
|
-
const staging = mkdtempSync7(
|
|
57745
|
+
mkdirSync8(installDir, { recursive: true, mode: 448 });
|
|
57746
|
+
const staging = mkdtempSync7(join28(installDir, ".staging-"));
|
|
56225
57747
|
try {
|
|
56226
|
-
const stagedBinary =
|
|
57748
|
+
const stagedBinary = join28(staging, HELPER_BINARY_NAME);
|
|
56227
57749
|
const compile = deps.spawn(
|
|
56228
57750
|
"/usr/bin/xcrun",
|
|
56229
57751
|
compileArguments(deps.sourcePath, stagedBinary, sourceSha),
|
|
@@ -56300,8 +57822,8 @@ function buildPrivateHelper(checkOnly, deps = defaultBuildDeps()) {
|
|
|
56300
57822
|
compiler
|
|
56301
57823
|
};
|
|
56302
57824
|
chmodSync2(stagedBinary, 448);
|
|
56303
|
-
renameSync2(stagedBinary,
|
|
56304
|
-
writeFileSync6(
|
|
57825
|
+
renameSync2(stagedBinary, join28(installDir, HELPER_BINARY_NAME));
|
|
57826
|
+
writeFileSync6(join28(installDir, MANIFEST_NAME), JSON.stringify(manifest, null, 2) + "\n", {
|
|
56305
57827
|
mode: 384
|
|
56306
57828
|
});
|
|
56307
57829
|
steps.push({ step: "install", ok: true, detail: installDir });
|
|
@@ -56827,7 +58349,7 @@ registerTool(
|
|
|
56827
58349
|
registerTool(
|
|
56828
58350
|
"search-notes",
|
|
56829
58351
|
{
|
|
56830
|
-
description: "Use when: finding notes by a keyword in the title (or body with searchContent=true) and you need their ids.\nReturns: matching notes with title, folder, and id; `source` says whether a body search read the Notes database or fell back to AppleScript.\nDo not use when: you already have a note id (use get-note-content), want every note (use list-notes), or need boolean or metadata filters (use query-notes).\nPrefer this first to obtain ids for subsequent read/update/delete/move calls.\nNote: with Full Disk Access, body search reads the Notes database (fast; the most recent 5000 notes, Recently Deleted excluded); without it, it falls back to AppleScript, which scans every body and can time out on broad terms.",
|
|
58352
|
+
description: "Use when: finding notes by a keyword in the title (or body with searchContent=true) and you need their ids.\nReturns: matching notes with title, folder, and id; `source` says whether a body search read the Notes database or fell back to AppleScript. When the note text came from the database, each result has matchedIn (title, body, or both); includeWordCount adds wordCount.\nDo not use when: you already have a note id (use get-note-content), want every note (use list-notes), or need boolean or metadata filters (use query-notes).\nPrefer this first to obtain ids for subsequent read/update/delete/move calls.\nNote: with Full Disk Access, body search reads the Notes database (fast; the most recent 5000 notes, Recently Deleted excluded); without it, it falls back to AppleScript, which scans every body and can time out on broad terms.",
|
|
56831
58353
|
inputSchema: {
|
|
56832
58354
|
query: external_exports.string().min(1, "Search query is required").max(MAX.QUERY),
|
|
56833
58355
|
searchContent: external_exports.boolean().optional().describe(
|
|
@@ -56840,112 +58362,132 @@ registerTool(
|
|
|
56840
58362
|
),
|
|
56841
58363
|
limit: external_exports.number().int().positive().optional().describe(
|
|
56842
58364
|
"Maximum number of results to return. Defaults to 50 \u2014 a broad query reads several properties per match via AppleScript, so an unbounded search can time out. Pass a higher value to see more; the applied limit is disclosed in the response."
|
|
58365
|
+
),
|
|
58366
|
+
includeWordCount: external_exports.boolean().optional().describe(
|
|
58367
|
+
"Add wordCount to each result (null when locked or unreadable). A database body search already has the text; otherwise the bodies are read in one batched read-only database query (needs Full Disk Access), which also adds matchedIn"
|
|
56843
58368
|
)
|
|
56844
58369
|
},
|
|
56845
58370
|
outputSchema: {
|
|
56846
58371
|
notes: external_exports.array(external_exports.object({}).passthrough()).optional(),
|
|
56847
58372
|
count: external_exports.number().optional(),
|
|
56848
58373
|
source: external_exports.enum(["database", "applescript"]).optional(),
|
|
56849
|
-
scanTruncated: external_exports.boolean().optional()
|
|
58374
|
+
scanTruncated: external_exports.boolean().optional(),
|
|
58375
|
+
wordCountUnavailable: external_exports.string().optional()
|
|
56850
58376
|
}
|
|
56851
58377
|
},
|
|
56852
|
-
withErrorHandling(
|
|
56853
|
-
|
|
56854
|
-
|
|
56855
|
-
|
|
56856
|
-
|
|
56857
|
-
|
|
56858
|
-
|
|
56859
|
-
|
|
58378
|
+
withErrorHandling(
|
|
58379
|
+
({ query: query2, searchContent = false, account, folder, modifiedSince, limit, includeWordCount }) => {
|
|
58380
|
+
const effectiveLimit = resolveSearchLimit(limit);
|
|
58381
|
+
const limitWasDefault = limit === void 0;
|
|
58382
|
+
let source;
|
|
58383
|
+
let dbScan;
|
|
58384
|
+
let dbUnavailable;
|
|
58385
|
+
const runSearch = () => {
|
|
58386
|
+
if (searchContent) {
|
|
58387
|
+
try {
|
|
58388
|
+
const db = searchContentViaDatabase({
|
|
58389
|
+
query: query2,
|
|
58390
|
+
account: notesManager.searchAccountScope(account),
|
|
58391
|
+
folder,
|
|
58392
|
+
modifiedSince,
|
|
58393
|
+
limit: effectiveLimit,
|
|
58394
|
+
includeWordCount
|
|
58395
|
+
});
|
|
58396
|
+
source = "database";
|
|
58397
|
+
dbScan = db.scan;
|
|
58398
|
+
return db.notes;
|
|
58399
|
+
} catch (error2) {
|
|
58400
|
+
if (!(error2 instanceof NoteQueryStoreError)) throw error2;
|
|
58401
|
+
dbUnavailable = error2.kind;
|
|
58402
|
+
}
|
|
58403
|
+
source = "applescript";
|
|
58404
|
+
}
|
|
56860
58405
|
try {
|
|
56861
|
-
|
|
56862
|
-
|
|
56863
|
-
|
|
58406
|
+
return notesManager.searchNotes(
|
|
58407
|
+
query2,
|
|
58408
|
+
searchContent,
|
|
58409
|
+
account,
|
|
56864
58410
|
folder,
|
|
56865
58411
|
modifiedSince,
|
|
56866
|
-
|
|
56867
|
-
|
|
56868
|
-
source = "database";
|
|
56869
|
-
dbScan = db.scan;
|
|
56870
|
-
return db.notes;
|
|
58412
|
+
effectiveLimit
|
|
58413
|
+
);
|
|
56871
58414
|
} catch (error2) {
|
|
56872
|
-
if (!(error2 instanceof
|
|
56873
|
-
|
|
58415
|
+
if (!searchContent || !(error2 instanceof Error)) throw error2;
|
|
58416
|
+
throw new Error(contentSearchFailureHint(error2.message, dbUnavailable));
|
|
56874
58417
|
}
|
|
56875
|
-
|
|
58418
|
+
};
|
|
58419
|
+
const {
|
|
58420
|
+
result: found,
|
|
58421
|
+
syncBefore,
|
|
58422
|
+
syncInterference
|
|
58423
|
+
} = withSyncAwarenessSync("search-notes", runSearch);
|
|
58424
|
+
let notes = found;
|
|
58425
|
+
let wordCountUnavailable;
|
|
58426
|
+
if (includeWordCount && source !== "database" && found.length > 0) {
|
|
58427
|
+
const enriched = addWordCountsFromDatabase(found, query2);
|
|
58428
|
+
notes = enriched.notes;
|
|
58429
|
+
wordCountUnavailable = enriched.unavailable;
|
|
58430
|
+
}
|
|
58431
|
+
const wordCountFields = wordCountUnavailable ? { wordCountUnavailable } : {};
|
|
58432
|
+
const wordCountNote = wordCountUnavailable ? `
|
|
58433
|
+
|
|
58434
|
+
\u2139\uFE0F Word counts were not added: ${wordCountUnavailable === "no_fda" ? "they are read from the Notes database, which needs Full Disk Access (run the doctor tool)" : "the Notes database could not be read"}.` : "";
|
|
58435
|
+
const searchType = searchContent ? source === "database" ? "content via the Notes database" : "content" : "titles";
|
|
58436
|
+
const sourceFields = source ? { source } : {};
|
|
58437
|
+
const scanFields = dbScan ? { scanTruncated: dbScan.scanTruncated } : {};
|
|
58438
|
+
const scanNote = describeContentScan(dbScan);
|
|
58439
|
+
const folderInfo = folder ? ` in folder "${folder}"` : "";
|
|
58440
|
+
const dateInfo = modifiedSince ? ` modified since ${modifiedSince}` : "";
|
|
58441
|
+
const { info: limitInfo, truncationNote } = describeSearchLimit(
|
|
58442
|
+
effectiveLimit,
|
|
58443
|
+
limitWasDefault,
|
|
58444
|
+
notes.length
|
|
58445
|
+
);
|
|
58446
|
+
const syncWarnings = [];
|
|
58447
|
+
if (syncBefore.syncDetected) {
|
|
58448
|
+
syncWarnings.push(`\u26A0\uFE0F iCloud sync was active during search.`);
|
|
56876
58449
|
}
|
|
56877
|
-
|
|
56878
|
-
|
|
56879
|
-
query2,
|
|
56880
|
-
searchContent,
|
|
56881
|
-
account,
|
|
56882
|
-
folder,
|
|
56883
|
-
modifiedSince,
|
|
56884
|
-
effectiveLimit
|
|
56885
|
-
);
|
|
56886
|
-
} catch (error2) {
|
|
56887
|
-
if (!searchContent || !(error2 instanceof Error)) throw error2;
|
|
56888
|
-
throw new Error(contentSearchFailureHint(error2.message, dbUnavailable));
|
|
58450
|
+
if (syncInterference) {
|
|
58451
|
+
syncWarnings.push(`\u26A0\uFE0F Sync activity detected - results may be incomplete.`);
|
|
56889
58452
|
}
|
|
56890
|
-
|
|
56891
|
-
const {
|
|
56892
|
-
result: notes,
|
|
56893
|
-
syncBefore,
|
|
56894
|
-
syncInterference
|
|
56895
|
-
} = withSyncAwarenessSync("search-notes", runSearch);
|
|
56896
|
-
const searchType = searchContent ? source === "database" ? "content via the Notes database" : "content" : "titles";
|
|
56897
|
-
const sourceFields = source ? { source } : {};
|
|
56898
|
-
const scanFields = dbScan ? { scanTruncated: dbScan.scanTruncated } : {};
|
|
56899
|
-
const scanNote = describeContentScan(dbScan);
|
|
56900
|
-
const folderInfo = folder ? ` in folder "${folder}"` : "";
|
|
56901
|
-
const dateInfo = modifiedSince ? ` modified since ${modifiedSince}` : "";
|
|
56902
|
-
const { info: limitInfo, truncationNote } = describeSearchLimit(
|
|
56903
|
-
effectiveLimit,
|
|
56904
|
-
limitWasDefault,
|
|
56905
|
-
notes.length
|
|
56906
|
-
);
|
|
56907
|
-
const syncWarnings = [];
|
|
56908
|
-
if (syncBefore.syncDetected) {
|
|
56909
|
-
syncWarnings.push(`\u26A0\uFE0F iCloud sync was active during search.`);
|
|
56910
|
-
}
|
|
56911
|
-
if (syncInterference) {
|
|
56912
|
-
syncWarnings.push(`\u26A0\uFE0F Sync activity detected - results may be incomplete.`);
|
|
56913
|
-
}
|
|
56914
|
-
const syncNote = syncWarnings.length > 0 ? `
|
|
58453
|
+
const syncNote = syncWarnings.length > 0 ? `
|
|
56915
58454
|
|
|
56916
58455
|
${syncWarnings.join(" ")}` : "";
|
|
56917
|
-
|
|
56918
|
-
|
|
58456
|
+
if (notes.length === 0) {
|
|
58457
|
+
const scopeHint = describeSearchScope(searchContent, notes.length);
|
|
58458
|
+
return successResponse(
|
|
58459
|
+
`No notes found matching "${query2}" in ${searchType}${folderInfo}${dateInfo}${scopeHint}${scanNote}${syncNote}`,
|
|
58460
|
+
{ notes: [], count: 0, ...sourceFields, ...scanFields }
|
|
58461
|
+
);
|
|
58462
|
+
}
|
|
58463
|
+
const noteList = notes.map((n) => {
|
|
58464
|
+
const idSuffix = `${n.id ? ` [id: ${n.id}]` : ""}${describeMatchDetails(n)}`;
|
|
58465
|
+
if (n.folder === "Recently Deleted") {
|
|
58466
|
+
return ` - ${n.title} [DELETED]${idSuffix}`;
|
|
58467
|
+
} else if (n.folder) {
|
|
58468
|
+
return ` - ${n.title} (${n.folder})${idSuffix}`;
|
|
58469
|
+
}
|
|
58470
|
+
return ` - ${n.title}${idSuffix}`;
|
|
58471
|
+
}).join("\n");
|
|
56919
58472
|
return successResponse(
|
|
56920
|
-
`
|
|
56921
|
-
|
|
58473
|
+
`Found ${notes.length} notes (searched ${searchType}${folderInfo}${dateInfo}${limitInfo}):
|
|
58474
|
+
${noteList}${truncationNote}${scanNote}${wordCountNote}${syncNote}`,
|
|
58475
|
+
{
|
|
58476
|
+
notes: withStableIdentifiers(notes, "ICNote"),
|
|
58477
|
+
count: notes.length,
|
|
58478
|
+
...sourceFields,
|
|
58479
|
+
...scanFields,
|
|
58480
|
+
...wordCountFields
|
|
58481
|
+
}
|
|
56922
58482
|
);
|
|
56923
|
-
}
|
|
56924
|
-
|
|
56925
|
-
|
|
56926
|
-
if (n.folder === "Recently Deleted") {
|
|
56927
|
-
return ` - ${n.title} [DELETED]${idSuffix}`;
|
|
56928
|
-
} else if (n.folder) {
|
|
56929
|
-
return ` - ${n.title} (${n.folder})${idSuffix}`;
|
|
56930
|
-
}
|
|
56931
|
-
return ` - ${n.title}${idSuffix}`;
|
|
56932
|
-
}).join("\n");
|
|
56933
|
-
return successResponse(
|
|
56934
|
-
`Found ${notes.length} notes (searched ${searchType}${folderInfo}${dateInfo}${limitInfo}):
|
|
56935
|
-
${noteList}${truncationNote}${scanNote}${syncNote}`,
|
|
56936
|
-
{
|
|
56937
|
-
notes: withStableIdentifiers(notes, "ICNote"),
|
|
56938
|
-
count: notes.length,
|
|
56939
|
-
...sourceFields,
|
|
56940
|
-
...scanFields
|
|
56941
|
-
}
|
|
56942
|
-
);
|
|
56943
|
-
}, "Error searching notes")
|
|
58483
|
+
},
|
|
58484
|
+
"Error searching notes"
|
|
58485
|
+
)
|
|
56944
58486
|
);
|
|
56945
58487
|
registerTool(
|
|
56946
58488
|
"query-notes",
|
|
56947
58489
|
{
|
|
56948
|
-
description: 'Use when: finding notes with a boolean expression over text and metadata \u2014 e.g. `folder:Work has:checklist -checklist:done`, `(title:invoice OR tag:finance) modified:>=2026-07-01`, `pinned words:>250`. Reads the Notes database directly, so it is fast and can match title OR body in one call.\nSyntax: bare words and "quoted phrases" match title or body (case-insensitive substring); fields title:, body:, text:, folder:, account:, tag: (values may be quoted, e.g. folder:"Work Projects"); facets has:link|attachment|checklist|drawing|image|video|audio|pdf|table|scan|tag; checklist:open|done; flags pinned, locked, shared (or is:pinned); words:>250 and created:/modified: with =, >, >=, <, <= and YYYY-MM-DD local dates. AND is implicit; OR, NOT, leading -, and parentheses are supported; operators are case-insensitive and a quoted "and" searches the literal word.\nReturns: matching notes (most recently modified first) with id, title, folder, account, modified date, and
|
|
58490
|
+
description: 'Use when: finding notes with a boolean expression over text and metadata \u2014 e.g. `folder:Work has:checklist -checklist:done`, `(title:invoice OR tag:finance) modified:>=2026-07-01`, `pinned words:>250`. Reads the Notes database directly, so it is fast and can match title OR body in one call.\nSyntax: bare words and "quoted phrases" match title or body (case-insensitive substring); fields title:, body:, text:, folder:, account:, tag: (values may be quoted, e.g. folder:"Work Projects"); facets has:link|attachment|checklist|drawing|image|video|audio|pdf|table|scan|tag; checklist:open|done; flags pinned, locked, shared (or is:pinned); words:>250 and created:/modified: with =, >, >=, <, <= and YYYY-MM-DD local dates. AND is implicit; OR, NOT, leading -, and parentheses are supported; operators are case-insensitive and a quoted "and" searches the literal word.\nReturns: matching notes (most recently modified first) with id, title, folder, account, modified date, snippet, and matchedIn (where the positive text terms occur: title, body, or both; absent when the body is unreadable or the query has no text term), plus scan/match counts; includeWordCount adds wordCount. Ids work with get-note-content and every other id-based tool.\nDo not use when: Full Disk Access is unavailable (use search-notes). Scans the most recent scanLimit notes (default 500); raise it for older notes.\nSafety: read-only; never writes the database. Excludes Recently Deleted and folderless notes unless includeDeleted is true. Locked notes match on title and metadata only; body predicates never match them.',
|
|
56949
58491
|
inputSchema: {
|
|
56950
58492
|
query: external_exports.string().min(1, "A query expression is required").max(MAX.QUERY).describe(
|
|
56951
58493
|
'Boolean query expression, e.g. `folder:"Work Projects" has:checklist -checklist:done`'
|
|
@@ -56958,6 +58500,9 @@ registerTool(
|
|
|
56958
58500
|
),
|
|
56959
58501
|
includeDeleted: external_exports.boolean().optional().describe(
|
|
56960
58502
|
"Also scan notes in Recently Deleted, notes pending deletion, and folderless notes (default false)"
|
|
58503
|
+
),
|
|
58504
|
+
includeWordCount: external_exports.boolean().optional().describe(
|
|
58505
|
+
"Add wordCount to each returned note (the count words: filters on; null when locked or unreadable). Free when the query reads bodies; a metadata-only query reads just the returned notes' bodies in one extra query (default false)"
|
|
56961
58506
|
)
|
|
56962
58507
|
},
|
|
56963
58508
|
outputSchema: {
|
|
@@ -56974,10 +58519,10 @@ registerTool(
|
|
|
56974
58519
|
},
|
|
56975
58520
|
annotations: { readOnlyHint: true }
|
|
56976
58521
|
},
|
|
56977
|
-
withErrorHandling(({ query: query2, limit, scanLimit, includeDeleted }) => {
|
|
58522
|
+
withErrorHandling(({ query: query2, limit, scanLimit, includeDeleted, includeWordCount }) => {
|
|
56978
58523
|
let result;
|
|
56979
58524
|
try {
|
|
56980
|
-
result = queryNotes(query2, { limit, scanLimit, includeDeleted });
|
|
58525
|
+
result = queryNotes(query2, { limit, scanLimit, includeDeleted, includeWordCount });
|
|
56981
58526
|
} catch (error2) {
|
|
56982
58527
|
if (error2 instanceof NoteQueryError || error2 instanceof NoteQueryStoreError) {
|
|
56983
58528
|
return errorResponse(
|
|
@@ -57008,7 +58553,7 @@ ${notes.join("\n")}` : "";
|
|
|
57008
58553
|
const where = [n.account, n.folder].filter(Boolean).join(" / ");
|
|
57009
58554
|
const snippet = n.snippet ? `
|
|
57010
58555
|
${n.snippet}` : "";
|
|
57011
|
-
return ` - ${n.title}${where ? ` (${where})` : ""}${n.locked ? " [locked]" : ""} [id: ${n.id}]${snippet}`;
|
|
58556
|
+
return ` - ${n.title}${where ? ` (${where})` : ""}${n.locked ? " [locked]" : ""} [id: ${n.id}]${describeMatchDetails(n)}${snippet}`;
|
|
57012
58557
|
}).join("\n");
|
|
57013
58558
|
return successResponse(
|
|
57014
58559
|
`Found ${result.matched} matching notes (${scope2}):
|
|
@@ -57875,10 +59420,10 @@ function guardedAppend({
|
|
|
57875
59420
|
return `<div>${escaped || "<br>"}</div>`;
|
|
57876
59421
|
}).join("");
|
|
57877
59422
|
};
|
|
57878
|
-
const separatorToHtml = (
|
|
57879
|
-
if (format === "html") return
|
|
57880
|
-
if (
|
|
57881
|
-
const escaped =
|
|
59423
|
+
const separatorToHtml = (sep5) => {
|
|
59424
|
+
if (format === "html") return sep5;
|
|
59425
|
+
if (sep5 === "\n\n") return "<div><br></div>";
|
|
59426
|
+
const escaped = sep5.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
57882
59427
|
return `<div>${escaped}</div>`;
|
|
57883
59428
|
};
|
|
57884
59429
|
const snapshot = readExactNoteSnapshot(id2);
|
|
@@ -59251,7 +60796,7 @@ var exportStatsSchema = external_exports.object({
|
|
|
59251
60796
|
registerTool(
|
|
59252
60797
|
"export-notes-markdown",
|
|
59253
60798
|
{
|
|
59254
|
-
description: "Use when: exporting one note (by exact id) or a folder's notes as one Markdown document rendered from the decoded note body: headings, bulleted/dashed/numbered lists with indent, checklists with state, block quotes, monospaced blocks, bold/italic/strikethrough/underline/highlight, links, tables, and attachments in body order.\nReturns: the Markdown inline (capped by APPLE_NOTES_MCP_EXPORT_MAX_BYTES), or with outputPath a receipt {format, count, bytes, output}; plus attachment counts and skipped notes (for example password-protected ones).\nDo not use when: you need the legacy HTML-converted Markdown of one note (get-note-markdown) or a restorable backup (export-notes-json). A folder document separates notes with '---' and is a presentation format, not something to import back.\nSafety: read-only against Notes; requires Full Disk Access. outputPath is create-only (an existing file is refused with [output_exists]); assetsDir copies attachment files without replacing existing ones (collisions get -2, -3 suffixes). Without assetsDir, attachments render as labeled placeholders.",
|
|
60799
|
+
description: "Use when: exporting one note (by exact id) or a folder's notes as one Markdown document rendered from the decoded note body: headings, bulleted/dashed/numbered lists with indent, checklists with state, block quotes, monospaced blocks, bold/italic/strikethrough/underline/highlight, links, tables, and attachments in body order.\nReturns: the Markdown inline (capped by APPLE_NOTES_MCP_EXPORT_MAX_BYTES), or with outputPath a receipt {format, count, bytes, output}; plus attachment counts and skipped notes (for example password-protected ones).\nDo not use when: you need the legacy HTML-converted Markdown of one note (get-note-markdown) or a restorable backup (export-notes-json). A folder document separates notes with '---' and is a presentation format, not something to import back.\nSafety: read-only against Notes; requires Full Disk Access. outputPath is create-only (an existing file is refused with [output_exists]); assetsDir copies attachment files without replacing existing ones (collisions get -2, -3 suffixes). Without assetsDir, attachments render as labeled placeholders.\nTemplates: pass template ('standard-markdown' reproduces the default output; 'obsidian' adds YAML front matter and copies attachments beside outputPath) or templateFile (a JSON template) to control how every block, inline style, attachment, per-note header/footer and separator renders. Templated receipts add template, warnings (e.g. missing_asset) and assetFiles; an invalid template is refused with [invalid-template] and every problem's JSON path.",
|
|
59255
60800
|
inputSchema: {
|
|
59256
60801
|
id: noteIdInput.optional(),
|
|
59257
60802
|
folder: external_exports.string().min(1).max(MAX.FOLDER).optional().describe("Folder path to export instead of one note (nested paths use '/')"),
|
|
@@ -59261,7 +60806,13 @@ registerTool(
|
|
|
59261
60806
|
),
|
|
59262
60807
|
outputPath: exportPathInput("File to create for the Markdown"),
|
|
59263
60808
|
assetsDir: exportPathInput("Directory that receives copies of attachment files"),
|
|
59264
|
-
wrap: external_exports.number().int().min(0).max(1e3).optional().describe("Hard-wrap prose at this many columns (0 or omitted: no wrapping)")
|
|
60809
|
+
wrap: external_exports.number().int().min(0).max(1e3).optional().describe("Hard-wrap prose at this many columns (0 or omitted: no wrapping)"),
|
|
60810
|
+
template: external_exports.string().min(1).max(64).optional().describe(
|
|
60811
|
+
`Render through this template: built-in ${BUILTIN_TEMPLATE_NAMES.map((n) => `'${n}'`).join(" or ")}. Exclusive with templateFile`
|
|
60812
|
+
),
|
|
60813
|
+
templateFile: exportPathInput(
|
|
60814
|
+
"JSON template file (.json) to render through (exclusive with template; at most 256 KiB)"
|
|
60815
|
+
)
|
|
59265
60816
|
},
|
|
59266
60817
|
outputSchema: {
|
|
59267
60818
|
format: external_exports.string().optional(),
|
|
@@ -59271,7 +60822,13 @@ registerTool(
|
|
|
59271
60822
|
output: external_exports.string().optional(),
|
|
59272
60823
|
assets: external_exports.object({ dir: external_exports.string(), files: external_exports.number() }).optional(),
|
|
59273
60824
|
stats: exportStatsSchema.optional(),
|
|
59274
|
-
skipped: external_exports.array(external_exports.object({ id: external_exports.string(), code: external_exports.string() })).optional()
|
|
60825
|
+
skipped: external_exports.array(external_exports.object({ id: external_exports.string(), code: external_exports.string() })).optional(),
|
|
60826
|
+
template: external_exports.object({ name: external_exports.string(), source: external_exports.string() }).optional(),
|
|
60827
|
+
warnings: external_exports.array(
|
|
60828
|
+
external_exports.object({ code: external_exports.string(), noteId: external_exports.string(), attachmentId: external_exports.string().optional() })
|
|
60829
|
+
).optional(),
|
|
60830
|
+
warningsOmitted: external_exports.number().optional(),
|
|
60831
|
+
assetFiles: external_exports.array(external_exports.string()).optional()
|
|
59275
60832
|
},
|
|
59276
60833
|
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false }
|
|
59277
60834
|
},
|
|
@@ -59286,9 +60843,15 @@ registerTool(
|
|
|
59286
60843
|
} catch (error2) {
|
|
59287
60844
|
if (!(error2 instanceof NotesExportError || error2 instanceof NoteBlocksError)) throw error2;
|
|
59288
60845
|
const hint = error2.code === "no-full-disk-access" ? ` Grant Full Disk Access to the Node binary running this server (run the doctor tool for its path): ${FULL_DISK_ACCESS_GUIDE_URL}` : "";
|
|
60846
|
+
if (error2 instanceof NotesExportError && error2.details)
|
|
60847
|
+
return errorResponse(
|
|
60848
|
+
`Error exporting Markdown [${error2.code}]: the template is invalid:
|
|
60849
|
+
` + error2.details.map((detail) => `${detail.path}: ${detail.message}`).join("\n")
|
|
60850
|
+
);
|
|
59289
60851
|
return errorResponse(`Error exporting Markdown [${error2.code}]: ${error2.message}${hint}`);
|
|
59290
60852
|
}
|
|
59291
|
-
const
|
|
60853
|
+
const warned = receipt.warnings?.length ? `; ${receipt.warnings.length + (receipt.warningsOmitted ?? 0)} warning(s)` : "";
|
|
60854
|
+
const skipped = (receipt.skipped.length ? `; skipped ${receipt.skipped.length}` : "") + warned;
|
|
59292
60855
|
if (receipt.output)
|
|
59293
60856
|
return successResponse(
|
|
59294
60857
|
`Wrote ${receipt.count} note(s) as Markdown (${receipt.bytes} bytes) to ${receipt.output}` + (receipt.assets ? `; copied ${receipt.assets.files} asset file(s) to ${receipt.assets.dir}` : "") + `${skipped}.`,
|