apple-notes-mcp 2.9.14 → 2.9.16
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 +98 -0
- package/build/index.js +2219 -383
- package/docs/markdown-templates.md +248 -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, constants9) {
|
|
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, constants9);
|
|
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, constants9) {
|
|
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, constants9);
|
|
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, constants9) {
|
|
506
|
+
this.code = optimizeExpr(this.code, names, constants9);
|
|
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, constants9) {
|
|
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, constants9))
|
|
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, constants9) {
|
|
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, constants9);
|
|
596
|
+
if (!(super.optimizeNames(names, constants9) || this.else))
|
|
597
597
|
return;
|
|
598
|
-
this.condition = optimizeExpr(this.condition, names,
|
|
598
|
+
this.condition = optimizeExpr(this.condition, names, constants9);
|
|
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, constants9) {
|
|
622
|
+
if (!super.optimizeNames(names, constants9))
|
|
623
623
|
return;
|
|
624
|
-
this.iteration = optimizeExpr(this.iteration, names,
|
|
624
|
+
this.iteration = optimizeExpr(this.iteration, names, constants9);
|
|
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, constants9) {
|
|
661
|
+
if (!super.optimizeNames(names, constants9))
|
|
662
662
|
return;
|
|
663
|
-
this.iterable = optimizeExpr(this.iterable, names,
|
|
663
|
+
this.iterable = optimizeExpr(this.iterable, names, constants9);
|
|
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, constants9) {
|
|
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, constants9);
|
|
708
|
+
(_a = this.catch) === null || _a === void 0 ? void 0 : _a.optimizeNames(names, constants9);
|
|
709
|
+
(_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNames(names, constants9);
|
|
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, constants9) {
|
|
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 = constants9[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 && constants9[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 = resolve9.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 resolve9(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 resolve9(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: resolve9,
|
|
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 constants9 = {
|
|
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 constants9) {
|
|
7465
|
+
v = { value: constants9[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 join30(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 = join30(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 join30(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((resolve9) => setTimeout(resolve9, 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((resolve9, 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
|
+
resolve9(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((resolve9, 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(resolve9, 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((resolve9) => setTimeout(resolve9, 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((resolve9) => {
|
|
38974
38974
|
const json2 = serializeMessage(message);
|
|
38975
38975
|
if (this._stdout.write(json2)) {
|
|
38976
|
-
|
|
38976
|
+
resolve9();
|
|
38977
38977
|
} else {
|
|
38978
|
-
this._stdout.once("drain",
|
|
38978
|
+
this._stdout.once("drain", resolve9);
|
|
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);
|
|
@@ -47036,12 +47036,12 @@ function tokenize(input) {
|
|
|
47036
47036
|
const field = prefix.toLowerCase();
|
|
47037
47037
|
let value = word.slice(colon + 1);
|
|
47038
47038
|
if (FIELDS.has(field)) {
|
|
47039
|
-
let
|
|
47039
|
+
let quoted2 = false;
|
|
47040
47040
|
if (value === "" && input[j] === '"') {
|
|
47041
47041
|
[value, j] = readQuoted(input, j);
|
|
47042
|
-
|
|
47042
|
+
quoted2 = true;
|
|
47043
47043
|
}
|
|
47044
|
-
push({ kind: "term", pos: i, field, value, quoted });
|
|
47044
|
+
push({ kind: "term", pos: i, field, value, quoted: quoted2 });
|
|
47045
47045
|
i = j;
|
|
47046
47046
|
continue;
|
|
47047
47047
|
}
|
|
@@ -47080,11 +47080,11 @@ function parseLocalDate(text2, pos) {
|
|
|
47080
47080
|
return { start: start.getTime(), end: new Date(year, month - 1, day + 1).getTime() };
|
|
47081
47081
|
}
|
|
47082
47082
|
function termNode(token) {
|
|
47083
|
-
const { field, value, quoted, pos } = token;
|
|
47083
|
+
const { field, value, quoted: quoted2, pos } = token;
|
|
47084
47084
|
if (field === void 0) {
|
|
47085
47085
|
if (value === "") throw new NoteQueryError("Empty quoted phrase", pos);
|
|
47086
47086
|
const lower2 = value.toLowerCase();
|
|
47087
|
-
if (!
|
|
47087
|
+
if (!quoted2 && FLAGS.includes(lower2)) {
|
|
47088
47088
|
return { type: "flag", flag: lower2 };
|
|
47089
47089
|
}
|
|
47090
47090
|
return { type: "text", field: "any", value };
|
|
@@ -47203,9 +47203,9 @@ var Parser = class {
|
|
|
47203
47203
|
if (token?.kind === "not") {
|
|
47204
47204
|
this.index++;
|
|
47205
47205
|
this.enter(token.pos);
|
|
47206
|
-
const
|
|
47206
|
+
const child2 = this.parseUnary();
|
|
47207
47207
|
this.depth--;
|
|
47208
|
-
return { type: "not", child };
|
|
47208
|
+
return { type: "not", child: child2 };
|
|
47209
47209
|
}
|
|
47210
47210
|
return this.parsePrimary();
|
|
47211
47211
|
}
|
|
@@ -47326,9 +47326,9 @@ function cheapFirst(children) {
|
|
|
47326
47326
|
function evaluateNoteQuery(node, note) {
|
|
47327
47327
|
switch (node.type) {
|
|
47328
47328
|
case "and":
|
|
47329
|
-
return cheapFirst(node.children).every((
|
|
47329
|
+
return cheapFirst(node.children).every((child2) => evaluateNoteQuery(child2, note));
|
|
47330
47330
|
case "or":
|
|
47331
|
-
return cheapFirst(node.children).some((
|
|
47331
|
+
return cheapFirst(node.children).some((child2) => evaluateNoteQuery(child2, note));
|
|
47332
47332
|
case "not":
|
|
47333
47333
|
return !evaluateNoteQuery(node.child, note);
|
|
47334
47334
|
case "text": {
|
|
@@ -47368,7 +47368,7 @@ function positiveTextPredicates(node, negated = false) {
|
|
|
47368
47368
|
switch (node.type) {
|
|
47369
47369
|
case "and":
|
|
47370
47370
|
case "or":
|
|
47371
|
-
return node.children.flatMap((
|
|
47371
|
+
return node.children.flatMap((child2) => positiveTextPredicates(child2, negated));
|
|
47372
47372
|
case "not":
|
|
47373
47373
|
return positiveTextPredicates(node.child, !negated);
|
|
47374
47374
|
case "text":
|
|
@@ -47633,13 +47633,13 @@ var escapeSegment = escapeFolderName;
|
|
|
47633
47633
|
function resolveFolders(rows) {
|
|
47634
47634
|
const byPk = new Map(rows.map((row) => [row.pk, row]));
|
|
47635
47635
|
const resolved = /* @__PURE__ */ new Map();
|
|
47636
|
-
const
|
|
47636
|
+
const resolve9 = (pk, seen) => {
|
|
47637
47637
|
const cached2 = resolved.get(pk);
|
|
47638
47638
|
if (cached2) return cached2;
|
|
47639
47639
|
const row = byPk.get(pk);
|
|
47640
47640
|
if (!row || seen.has(pk)) return void 0;
|
|
47641
47641
|
seen.add(pk);
|
|
47642
|
-
const parent = row.parent !== null ?
|
|
47642
|
+
const parent = row.parent !== null ? resolve9(row.parent, seen) : void 0;
|
|
47643
47643
|
const name = row.name ?? "";
|
|
47644
47644
|
const path10 = parent ? `${parent.path}/${escapeSegment(name)}` : escapeSegment(name);
|
|
47645
47645
|
const plainPath = parent ? `${parent.plainPath}/${name}` : name;
|
|
@@ -47653,7 +47653,7 @@ function resolveFolders(rows) {
|
|
|
47653
47653
|
resolved.set(pk, info);
|
|
47654
47654
|
return info;
|
|
47655
47655
|
};
|
|
47656
|
-
for (const row of rows)
|
|
47656
|
+
for (const row of rows) resolve9(row.pk, /* @__PURE__ */ new Set());
|
|
47657
47657
|
return resolved;
|
|
47658
47658
|
}
|
|
47659
47659
|
var coreDataMs = (seconds) => seconds === null || !Number.isFinite(seconds) ? void 0 : CORE_DATA_EPOCH_MS2 + seconds * 1e3;
|
|
@@ -48368,8 +48368,8 @@ function validateAppendContent(content, format, options = {}) {
|
|
|
48368
48368
|
if (/!\[|<\/?[a-z]|\]\(\s*(?:javascript|data|file):/i.test(checked))
|
|
48369
48369
|
throw new Error("Markdown images, raw HTML and local/executable links are unsupported");
|
|
48370
48370
|
const withoutLinkDestinations = checked.replace(/(\[[^\]\n]+\])\([^()\s]+\)/g, "$1()");
|
|
48371
|
-
for (const [
|
|
48372
|
-
if (
|
|
48371
|
+
for (const [pattern2, name] of UNMODELED_MARKDOWN)
|
|
48372
|
+
if (pattern2.test(name === UNDERSCORES_OUTSIDE_A_WORD ? withoutLinkDestinations : checked))
|
|
48373
48373
|
throw new Error(
|
|
48374
48374
|
`Markdown cannot use ${name}; Notes would change that text, so the result could not be verified`
|
|
48375
48375
|
);
|
|
@@ -48860,6 +48860,19 @@ var FEATURES = [
|
|
|
48860
48860
|
tools: [],
|
|
48861
48861
|
minimumMacOSVersion: null,
|
|
48862
48862
|
requirements: [{ kind: "native_write_helper" }]
|
|
48863
|
+
},
|
|
48864
|
+
{
|
|
48865
|
+
name: "markdownTemplateLibrary",
|
|
48866
|
+
description: "Validate, save, list, show and delete Markdown export templates (local JSON files; exporting with one still needs Full Disk Access)",
|
|
48867
|
+
tools: [
|
|
48868
|
+
"list-markdown-templates",
|
|
48869
|
+
"show-markdown-template",
|
|
48870
|
+
"validate-markdown-template",
|
|
48871
|
+
"save-markdown-template",
|
|
48872
|
+
"delete-markdown-template"
|
|
48873
|
+
],
|
|
48874
|
+
minimumMacOSVersion: null,
|
|
48875
|
+
requirements: []
|
|
48863
48876
|
}
|
|
48864
48877
|
];
|
|
48865
48878
|
function requirementLabel(requirement) {
|
|
@@ -49895,8 +49908,8 @@ function describeBodyReadFailure(title, error2, attachments) {
|
|
|
49895
49908
|
const kind = classifyBodyReadError(error2);
|
|
49896
49909
|
if (kind === "other") return base;
|
|
49897
49910
|
const large = attachments ? largeAttachments(attachments) : [];
|
|
49898
|
-
const
|
|
49899
|
-
const holds = large.length > 0 ? `The note holds ${large.length === 1 ? "a large attachment" : "large attachments"} (${
|
|
49911
|
+
const listed2 = large.map((a) => `${a.name}, ${formatBytes2(a.bytes)}`).join("; ");
|
|
49912
|
+
const holds = large.length > 0 ? `The note holds ${large.length === 1 ? "a large attachment" : "large attachments"} (${listed2}). ` : "";
|
|
49900
49913
|
if (kind === "buffer") {
|
|
49901
49914
|
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.`;
|
|
49902
49915
|
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.";
|
|
@@ -50233,8 +50246,8 @@ function insertLink(request, deps) {
|
|
|
50233
50246
|
}
|
|
50234
50247
|
|
|
50235
50248
|
// src/services/notesExport.ts
|
|
50236
|
-
import { mkdirSync as
|
|
50237
|
-
import { basename as basename4, dirname as dirname6, extname as
|
|
50249
|
+
import { mkdirSync as mkdirSync6 } from "node:fs";
|
|
50250
|
+
import { basename as basename4, dirname as dirname6, extname as extname5, join as join22 } from "node:path";
|
|
50238
50251
|
|
|
50239
50252
|
// src/utils/exportAssets.ts
|
|
50240
50253
|
import {
|
|
@@ -50424,8 +50437,8 @@ var AssetLocator = class {
|
|
|
50424
50437
|
/** Preview.png (or another image) at most two levels inside a bundle. */
|
|
50425
50438
|
bundleImage(bundle, account) {
|
|
50426
50439
|
const found = [];
|
|
50427
|
-
for (const
|
|
50428
|
-
const path10 = confine(join19(bundle,
|
|
50440
|
+
for (const child2 of listDirectory(bundle, MAX_BUNDLE_ENTRIES2)) {
|
|
50441
|
+
const path10 = confine(join19(bundle, child2), account);
|
|
50429
50442
|
if (!path10) continue;
|
|
50430
50443
|
if (isFile(path10)) found.push(path10);
|
|
50431
50444
|
else
|
|
@@ -50760,7 +50773,7 @@ function planAttachment(attachment, ctx) {
|
|
|
50760
50773
|
ctx.stats.attachments--;
|
|
50761
50774
|
return {
|
|
50762
50775
|
type: "gallery",
|
|
50763
|
-
items: attachment.children.map((
|
|
50776
|
+
items: attachment.children.map((child2) => planAttachment(child2, ctx))
|
|
50764
50777
|
};
|
|
50765
50778
|
}
|
|
50766
50779
|
case "link": {
|
|
@@ -51332,9 +51345,9 @@ function wrapMarkdown(markdown, width) {
|
|
|
51332
51345
|
}
|
|
51333
51346
|
return out.join("\n");
|
|
51334
51347
|
}
|
|
51335
|
-
function renderNotesMarkdown(notes, ctx, { wrap:
|
|
51348
|
+
function renderNotesMarkdown(notes, ctx, { wrap: wrap3 = 0 } = {}) {
|
|
51336
51349
|
const body = notes.map((note) => renderNoteMarkdown(note, ctx)).join(NOTE_SEPARATOR);
|
|
51337
|
-
return (
|
|
51350
|
+
return (wrap3 ? wrapMarkdown(body, wrap3) : body) + (notes.length ? "\n" : "");
|
|
51338
51351
|
}
|
|
51339
51352
|
|
|
51340
51353
|
// src/utils/noteExportData.ts
|
|
@@ -51508,18 +51521,1290 @@ function readExportNote(id2, { dbPath: dbPath2 = NOTES_DB_PATH11 } = {}) {
|
|
|
51508
51521
|
ordered
|
|
51509
51522
|
};
|
|
51510
51523
|
}
|
|
51524
|
+
var CORE_DATA_EPOCH = 978307200;
|
|
51525
|
+
function coreDataDate(value) {
|
|
51526
|
+
const seconds = typeof value === "number" ? value : typeof value === "string" && value.trim() ? Number(value) : NaN;
|
|
51527
|
+
if (!Number.isFinite(seconds) || Math.abs(seconds) > 1e10) return void 0;
|
|
51528
|
+
return new Date((seconds + CORE_DATA_EPOCH) * 1e3).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
51529
|
+
}
|
|
51530
|
+
function noteMetaQuery(columns) {
|
|
51531
|
+
const first2 = (names) => {
|
|
51532
|
+
const present = names.filter((name) => columns.has(name)).map((name) => `n.${name}`);
|
|
51533
|
+
if (!present.length) return "NULL";
|
|
51534
|
+
return present.length === 1 ? present[0] : `COALESCE(${present.join(", ")})`;
|
|
51535
|
+
};
|
|
51536
|
+
const accountColumns = [...columns].filter((name) => /^ZACCOUNT\d*$/.test(name)).sort((a, b) => Number(b.slice(8) || 0) - Number(a.slice(8) || 0));
|
|
51537
|
+
const folder = columns.has("ZFOLDER") && columns.has("ZTITLE2") ? "(SELECT f.ZTITLE2 FROM ZICCLOUDSYNCINGOBJECT f WHERE f.Z_PK = n.ZFOLDER)" : "NULL";
|
|
51538
|
+
const account = columns.has("ZNAME") && accountColumns.length ? `(SELECT a.ZNAME FROM ZICCLOUDSYNCINGOBJECT a WHERE a.Z_PK = ${first2(accountColumns)})` : "NULL";
|
|
51539
|
+
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;`;
|
|
51540
|
+
}
|
|
51541
|
+
function readExportNoteMeta(id2, { dbPath: dbPath2 = NOTES_DB_PATH11 } = {}) {
|
|
51542
|
+
const match = /\/ICNote\/p([0-9]{1,18})$/.exec(id2);
|
|
51543
|
+
if (!match) throw new NoteBlocksError("invalid-id", "Not a note id");
|
|
51544
|
+
const output = sqlite(dbPath2, [
|
|
51545
|
+
"-cmd",
|
|
51546
|
+
".parameter init",
|
|
51547
|
+
"-cmd",
|
|
51548
|
+
`.parameter set @pk ${match[1]}`,
|
|
51549
|
+
noteMetaQuery(objectColumns(dbPath2))
|
|
51550
|
+
]);
|
|
51551
|
+
if (!output) return {};
|
|
51552
|
+
let row;
|
|
51553
|
+
try {
|
|
51554
|
+
row = JSON.parse(output);
|
|
51555
|
+
} catch {
|
|
51556
|
+
throw new NoteBlocksError("query-failed", "Unexpected Notes database response");
|
|
51557
|
+
}
|
|
51558
|
+
const meta = {};
|
|
51559
|
+
const set = (key, value) => {
|
|
51560
|
+
if (value !== void 0) meta[key] = value;
|
|
51561
|
+
};
|
|
51562
|
+
set("uuid", text(row.uuid));
|
|
51563
|
+
set("created", coreDataDate(row.created));
|
|
51564
|
+
set("modified", coreDataDate(row.modified));
|
|
51565
|
+
set("folder", text(row.folder));
|
|
51566
|
+
set("account", text(row.account));
|
|
51567
|
+
return meta;
|
|
51568
|
+
}
|
|
51569
|
+
|
|
51570
|
+
// src/utils/markdownTemplate.ts
|
|
51571
|
+
var TEMPLATE_SCHEMA_VERSION = 1;
|
|
51572
|
+
var MAX_TEMPLATE_BYTES = 256 * 1024;
|
|
51573
|
+
var MAX_META_LENGTH = 512;
|
|
51574
|
+
var MAX_RULE_TEXT = 4096;
|
|
51575
|
+
var MAX_DIRECTORY_LENGTH = 1024;
|
|
51576
|
+
var RULE_IDS = [
|
|
51577
|
+
"document.header",
|
|
51578
|
+
"document.footer",
|
|
51579
|
+
"document.separator",
|
|
51580
|
+
"block.title",
|
|
51581
|
+
"block.heading",
|
|
51582
|
+
"block.subheading",
|
|
51583
|
+
"block.body",
|
|
51584
|
+
"block.bulleted",
|
|
51585
|
+
"block.dashed",
|
|
51586
|
+
"block.numbered",
|
|
51587
|
+
"block.checklist.checked",
|
|
51588
|
+
"block.checklist.unchecked",
|
|
51589
|
+
"block.code",
|
|
51590
|
+
"paragraph.quote",
|
|
51591
|
+
"inline.bold",
|
|
51592
|
+
"inline.italic",
|
|
51593
|
+
"inline.underline",
|
|
51594
|
+
"inline.strikethrough",
|
|
51595
|
+
"inline.superscript",
|
|
51596
|
+
"inline.subscript",
|
|
51597
|
+
"inline.highlight.purple",
|
|
51598
|
+
"inline.highlight.pink",
|
|
51599
|
+
"inline.highlight.orange",
|
|
51600
|
+
"inline.highlight.mint",
|
|
51601
|
+
"inline.highlight.blue",
|
|
51602
|
+
"inline.highlight.other",
|
|
51603
|
+
"inline.color",
|
|
51604
|
+
"inline.link",
|
|
51605
|
+
"attachment.image",
|
|
51606
|
+
"attachment.drawing.classic",
|
|
51607
|
+
"attachment.drawing.paper",
|
|
51608
|
+
"attachment.scan",
|
|
51609
|
+
"attachment.pdf",
|
|
51610
|
+
"attachment.audio",
|
|
51611
|
+
"attachment.video",
|
|
51612
|
+
"attachment.other",
|
|
51613
|
+
"attachment.table",
|
|
51614
|
+
"attachment.divider",
|
|
51615
|
+
"attachment.gallery",
|
|
51616
|
+
"attachment.url",
|
|
51617
|
+
"attachment.url.image",
|
|
51618
|
+
"attachment.map",
|
|
51619
|
+
"attachment.placeholder"
|
|
51620
|
+
];
|
|
51621
|
+
var RULE_MODES = ["wrap", "linePrefix", "pattern", "plain", "omit"];
|
|
51622
|
+
var INLINE_FORMATS = [
|
|
51623
|
+
"subscript",
|
|
51624
|
+
"superscript",
|
|
51625
|
+
"highlight",
|
|
51626
|
+
"underline",
|
|
51627
|
+
"strikethrough",
|
|
51628
|
+
"bold",
|
|
51629
|
+
"italic",
|
|
51630
|
+
"color",
|
|
51631
|
+
"link"
|
|
51632
|
+
];
|
|
51633
|
+
var PLACEHOLDERS = [
|
|
51634
|
+
"content",
|
|
51635
|
+
"title",
|
|
51636
|
+
"id",
|
|
51637
|
+
"uuid",
|
|
51638
|
+
"folder",
|
|
51639
|
+
"account",
|
|
51640
|
+
"created",
|
|
51641
|
+
"modified",
|
|
51642
|
+
"tags",
|
|
51643
|
+
"exportStem",
|
|
51644
|
+
"index",
|
|
51645
|
+
"checked",
|
|
51646
|
+
"url",
|
|
51647
|
+
"path",
|
|
51648
|
+
"alt",
|
|
51649
|
+
"caption",
|
|
51650
|
+
"linkText",
|
|
51651
|
+
"filename",
|
|
51652
|
+
"kind",
|
|
51653
|
+
"uti",
|
|
51654
|
+
"color",
|
|
51655
|
+
"highlight",
|
|
51656
|
+
"fence"
|
|
51657
|
+
];
|
|
51658
|
+
var NOTE_PLACEHOLDERS = [
|
|
51659
|
+
"title",
|
|
51660
|
+
"id",
|
|
51661
|
+
"uuid",
|
|
51662
|
+
"folder",
|
|
51663
|
+
"account",
|
|
51664
|
+
"created",
|
|
51665
|
+
"modified",
|
|
51666
|
+
"exportStem"
|
|
51667
|
+
];
|
|
51668
|
+
var PLACEHOLDER_MODIFIERS = ["raw", "yaml"];
|
|
51669
|
+
var wrap2 = (before, after = "", join30) => ({
|
|
51670
|
+
mode: "wrap",
|
|
51671
|
+
before,
|
|
51672
|
+
after,
|
|
51673
|
+
...join30 ? { join: join30 } : {}
|
|
51674
|
+
});
|
|
51675
|
+
var pattern = (value, join30) => ({
|
|
51676
|
+
mode: "pattern",
|
|
51677
|
+
value,
|
|
51678
|
+
...join30 ? { join: join30 } : {}
|
|
51679
|
+
});
|
|
51680
|
+
var STANDARD = {
|
|
51681
|
+
schemaVersion: 1,
|
|
51682
|
+
name: "standard-markdown",
|
|
51683
|
+
description: "The default export-notes-markdown output",
|
|
51684
|
+
assets: { mode: "copy", pathStyle: "relative", directory: null },
|
|
51685
|
+
inlineOrder: [...INLINE_FORMATS],
|
|
51686
|
+
options: {
|
|
51687
|
+
titleFallback: true,
|
|
51688
|
+
richLinkImages: false,
|
|
51689
|
+
richLinkImageCaption: "none",
|
|
51690
|
+
listIndent: " "
|
|
51691
|
+
},
|
|
51692
|
+
rules: {
|
|
51693
|
+
"document.header": pattern(""),
|
|
51694
|
+
"document.footer": pattern(""),
|
|
51695
|
+
"document.separator": pattern("\n\n---\n\n"),
|
|
51696
|
+
"block.title": wrap2("# ", "", "paragraph"),
|
|
51697
|
+
"block.heading": wrap2("## ", "", "paragraph"),
|
|
51698
|
+
"block.subheading": wrap2("### ", "", "paragraph"),
|
|
51699
|
+
"block.body": { mode: "plain", join: "paragraph" },
|
|
51700
|
+
"block.bulleted": wrap2("- ", "", "line"),
|
|
51701
|
+
"block.dashed": wrap2("- ", "", "line"),
|
|
51702
|
+
"block.numbered": pattern("{{index}}. {{content}}", "line"),
|
|
51703
|
+
"block.checklist.checked": wrap2("- [x] ", "", "line"),
|
|
51704
|
+
"block.checklist.unchecked": wrap2("- [ ] ", "", "line"),
|
|
51705
|
+
"block.code": wrap2("{{fence}}\n", "\n{{fence}}", "paragraph"),
|
|
51706
|
+
"paragraph.quote": { mode: "linePrefix", value: "> " },
|
|
51707
|
+
"inline.bold": wrap2("**", "**"),
|
|
51708
|
+
"inline.italic": wrap2("*", "*"),
|
|
51709
|
+
"inline.underline": wrap2("<u>", "</u>"),
|
|
51710
|
+
"inline.strikethrough": wrap2("~~", "~~"),
|
|
51711
|
+
"inline.superscript": wrap2("<sup>", "</sup>"),
|
|
51712
|
+
"inline.subscript": wrap2("<sub>", "</sub>"),
|
|
51713
|
+
"inline.highlight.purple": wrap2("==", "=="),
|
|
51714
|
+
"inline.highlight.pink": wrap2("==", "=="),
|
|
51715
|
+
"inline.highlight.orange": wrap2("==", "=="),
|
|
51716
|
+
"inline.highlight.mint": wrap2("==", "=="),
|
|
51717
|
+
"inline.highlight.blue": wrap2("==", "=="),
|
|
51718
|
+
"inline.highlight.other": wrap2("==", "=="),
|
|
51719
|
+
"inline.color": { mode: "plain" },
|
|
51720
|
+
"inline.link": pattern("[{{content}}]({{url}})"),
|
|
51721
|
+
"attachment.image": pattern(""),
|
|
51722
|
+
"attachment.drawing.classic": pattern(""),
|
|
51723
|
+
"attachment.drawing.paper": pattern(""),
|
|
51724
|
+
"attachment.scan": pattern("[{{linkText}}]({{path}})"),
|
|
51725
|
+
"attachment.pdf": pattern("[{{linkText}}]({{path}})"),
|
|
51726
|
+
"attachment.audio": pattern("[{{linkText}}]({{path}})"),
|
|
51727
|
+
"attachment.video": pattern("[{{linkText}}]({{path}})"),
|
|
51728
|
+
"attachment.other": pattern("[{{linkText}}]({{path}})"),
|
|
51729
|
+
"attachment.table": { mode: "plain" },
|
|
51730
|
+
"attachment.divider": pattern("---"),
|
|
51731
|
+
"attachment.gallery": { mode: "plain", join: "paragraph" },
|
|
51732
|
+
"attachment.url": pattern("[{{alt}}]({{url}})"),
|
|
51733
|
+
"attachment.url.image": pattern(""),
|
|
51734
|
+
"attachment.map": pattern("[{{alt}}]({{url}})"),
|
|
51735
|
+
"attachment.placeholder": pattern("\\[{{content}}\\]")
|
|
51736
|
+
}
|
|
51737
|
+
};
|
|
51738
|
+
var OBSIDIAN = {
|
|
51739
|
+
schemaVersion: 1,
|
|
51740
|
+
name: "obsidian",
|
|
51741
|
+
description: "Obsidian-style Markdown: YAML front matter (title, dates, folder, tags, id), image-URL link cards as images, attachments copied to <file>.assets",
|
|
51742
|
+
extends: "standard-markdown",
|
|
51743
|
+
assets: { directory: "{{exportStem}}.assets" },
|
|
51744
|
+
options: { richLinkImages: true, richLinkImageCaption: "followingItalicParagraph" },
|
|
51745
|
+
rules: {
|
|
51746
|
+
"document.header": pattern(
|
|
51747
|
+
"---\ntitle: {{title:yaml}}\ncreated: {{created:yaml}}\nmodified: {{modified:yaml}}\nfolder: {{folder:yaml}}\ntags: {{tags:yaml}}\nnote-id: {{uuid:yaml}}\n---\n\n"
|
|
51748
|
+
)
|
|
51749
|
+
}
|
|
51750
|
+
};
|
|
51751
|
+
var BUILTINS = { "standard-markdown": STANDARD, obsidian: OBSIDIAN };
|
|
51752
|
+
var BUILTIN_TEMPLATE_NAMES = Object.keys(BUILTINS);
|
|
51753
|
+
var isBuiltinTemplate = (name) => Object.prototype.hasOwnProperty.call(BUILTINS, name);
|
|
51754
|
+
function builtinTemplate(name) {
|
|
51755
|
+
return JSON.parse(JSON.stringify(BUILTINS[name]));
|
|
51756
|
+
}
|
|
51757
|
+
var TemplateValidationError = class extends Error {
|
|
51758
|
+
constructor(errors) {
|
|
51759
|
+
super(
|
|
51760
|
+
`Invalid template (${errors.length} problem${errors.length === 1 ? "" : "s"}): ` + errors.map((e) => `${e.path}: ${e.message}`).join("; ")
|
|
51761
|
+
);
|
|
51762
|
+
this.errors = errors;
|
|
51763
|
+
this.name = "TemplateValidationError";
|
|
51764
|
+
}
|
|
51765
|
+
errors;
|
|
51766
|
+
code = "invalid-template";
|
|
51767
|
+
};
|
|
51768
|
+
var MAX_QUOTED_TOKEN = 32;
|
|
51769
|
+
function child(path10, key) {
|
|
51770
|
+
if (typeof key === "number") return `${path10}[${key}]`;
|
|
51771
|
+
if (key.length > MAX_QUOTED_TOKEN) key = `${key.slice(0, MAX_QUOTED_TOKEN - 3)}...`;
|
|
51772
|
+
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key) ? `${path10}.${key}` : `${path10}[${JSON.stringify(key)}]`;
|
|
51773
|
+
}
|
|
51774
|
+
var isObject2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
51775
|
+
var describe = (value) => value === null ? "null" : Array.isArray(value) ? "an array" : `a ${typeof value}`;
|
|
51776
|
+
var describeVersion = (value) => typeof value === "number" && Number.isFinite(value) ? String(value) : describe(value);
|
|
51777
|
+
var listed = (values) => values.map((v) => JSON.stringify(v)).join(", ");
|
|
51778
|
+
var quoted = (token) => token.length <= MAX_QUOTED_TOKEN ? token : `${token.slice(0, MAX_QUOTED_TOKEN - 3)}...}}`;
|
|
51779
|
+
var TOKEN = /\{\{([^{}]*)\}\}/g;
|
|
51780
|
+
var TOKEN_BODY = /^\s*([A-Za-z]+)(?::([A-Za-z]+))?\s*$/;
|
|
51781
|
+
var META_PLACEHOLDERS = ["uuid", "folder", "account", "created", "modified"];
|
|
51782
|
+
function usesNoteMeta(template) {
|
|
51783
|
+
const uses = (value) => typeof value === "string" ? placeholderTokens(value).some(({ name }) => META_PLACEHOLDERS.includes(name)) : typeof value === "object" && value !== null && Object.values(value).some(uses);
|
|
51784
|
+
return uses(template.rules) || uses(template.assets) || uses(template.options);
|
|
51785
|
+
}
|
|
51786
|
+
function placeholderTokens(text2) {
|
|
51787
|
+
return [...text2.matchAll(TOKEN)].map((match) => {
|
|
51788
|
+
const body = TOKEN_BODY.exec(match[1]);
|
|
51789
|
+
return {
|
|
51790
|
+
token: match[0],
|
|
51791
|
+
name: body?.[1] ?? match[1],
|
|
51792
|
+
...body?.[2] ? { modifier: body[2] } : {}
|
|
51793
|
+
};
|
|
51794
|
+
});
|
|
51795
|
+
}
|
|
51796
|
+
var Collector = class {
|
|
51797
|
+
errors = [];
|
|
51798
|
+
add(path10, message) {
|
|
51799
|
+
this.errors.push({ path: path10, message });
|
|
51800
|
+
}
|
|
51801
|
+
/** Report unknown keys; returns the known keys present, sorted. */
|
|
51802
|
+
keys(value, path10, allowed) {
|
|
51803
|
+
const present = Object.keys(value).sort();
|
|
51804
|
+
for (const key of present)
|
|
51805
|
+
if (!allowed.includes(key))
|
|
51806
|
+
this.add(child(path10, key), `unknown key; allowed keys are ${listed(allowed)}`);
|
|
51807
|
+
return present.filter((key) => allowed.includes(key));
|
|
51808
|
+
}
|
|
51809
|
+
text(value, path10, { max, allowed = PLACEHOLDERS }) {
|
|
51810
|
+
if (typeof value !== "string") {
|
|
51811
|
+
this.add(path10, `must be a string, not ${describe(value)}`);
|
|
51812
|
+
return false;
|
|
51813
|
+
}
|
|
51814
|
+
if (value.length > max)
|
|
51815
|
+
this.add(path10, `must be at most ${max} characters (is ${value.length})`);
|
|
51816
|
+
for (const { token: raw, name, modifier } of placeholderTokens(value)) {
|
|
51817
|
+
const token = quoted(raw);
|
|
51818
|
+
if (!PLACEHOLDERS.includes(name))
|
|
51819
|
+
this.add(path10, `unknown placeholder ${token}; allowed: ${PLACEHOLDERS.join(", ")}`);
|
|
51820
|
+
else if (!allowed.includes(name))
|
|
51821
|
+
this.add(
|
|
51822
|
+
path10,
|
|
51823
|
+
`placeholder ${token} is not available here; allowed: ${allowed.join(", ")}`
|
|
51824
|
+
);
|
|
51825
|
+
else if (modifier && !PLACEHOLDER_MODIFIERS.includes(modifier))
|
|
51826
|
+
this.add(
|
|
51827
|
+
path10,
|
|
51828
|
+
`unknown modifier in ${token}; allowed modifiers are ${PLACEHOLDER_MODIFIERS.join(", ")}`
|
|
51829
|
+
);
|
|
51830
|
+
}
|
|
51831
|
+
return true;
|
|
51832
|
+
}
|
|
51833
|
+
oneOf(value, path10, allowed) {
|
|
51834
|
+
if (typeof value === "string" && allowed.includes(value)) return true;
|
|
51835
|
+
this.add(
|
|
51836
|
+
path10,
|
|
51837
|
+
typeof value === "string" ? `must be one of ${listed(allowed)}` : `must be one of ${listed(allowed)}, not ${describe(value)}`
|
|
51838
|
+
);
|
|
51839
|
+
return false;
|
|
51840
|
+
}
|
|
51841
|
+
boolean(value, path10) {
|
|
51842
|
+
if (typeof value === "boolean") return true;
|
|
51843
|
+
this.add(path10, `must be true or false, not ${describe(value)}`);
|
|
51844
|
+
return false;
|
|
51845
|
+
}
|
|
51846
|
+
};
|
|
51847
|
+
var RULE_FIELDS = {
|
|
51848
|
+
wrap: ["before", "after"],
|
|
51849
|
+
linePrefix: ["value"],
|
|
51850
|
+
pattern: ["value"],
|
|
51851
|
+
plain: [],
|
|
51852
|
+
omit: []
|
|
51853
|
+
};
|
|
51854
|
+
function validateRule(c, rule, path10) {
|
|
51855
|
+
if (!isObject2(rule)) {
|
|
51856
|
+
c.add(path10, `must be an object, not ${describe(rule)}`);
|
|
51857
|
+
return;
|
|
51858
|
+
}
|
|
51859
|
+
const keys = c.keys(rule, path10, ["mode", "before", "after", "value", "join"]);
|
|
51860
|
+
if (!("mode" in rule)) {
|
|
51861
|
+
c.add(child(path10, "mode"), `is required; one of ${listed(RULE_MODES)}`);
|
|
51862
|
+
return;
|
|
51863
|
+
}
|
|
51864
|
+
if (!c.oneOf(rule.mode, child(path10, "mode"), RULE_MODES)) return;
|
|
51865
|
+
const needed = RULE_FIELDS[rule.mode];
|
|
51866
|
+
for (const field of ["before", "after", "value"]) {
|
|
51867
|
+
const fieldPath = child(path10, field);
|
|
51868
|
+
if (needed.includes(field)) {
|
|
51869
|
+
if (!(field in rule)) c.add(fieldPath, `is required when mode is "${rule.mode}"`);
|
|
51870
|
+
else c.text(rule[field], fieldPath, { max: MAX_RULE_TEXT });
|
|
51871
|
+
} else if (keys.includes(field)) c.add(fieldPath, `is not used when mode is "${rule.mode}"`);
|
|
51872
|
+
}
|
|
51873
|
+
if ("join" in rule) c.oneOf(rule.join, child(path10, "join"), ["line", "paragraph"]);
|
|
51874
|
+
}
|
|
51875
|
+
function validateDirectory(c, value, path10) {
|
|
51876
|
+
if (value === null) return;
|
|
51877
|
+
if (!c.text(value, path10, { max: MAX_DIRECTORY_LENGTH, allowed: NOTE_PLACEHOLDERS })) return;
|
|
51878
|
+
if (!value.trim()) c.add(path10, "must not be empty; use null to copy only with assetsDir");
|
|
51879
|
+
else if (/^[/~]/.test(value)) c.add(path10, "must be relative to the output file's directory");
|
|
51880
|
+
else if (/[\\\0]/.test(value)) c.add(path10, "must not contain a backslash or NUL");
|
|
51881
|
+
else if (value.split("/").some((part) => part.trim() === ".."))
|
|
51882
|
+
c.add(path10, 'must not contain a ".." component');
|
|
51883
|
+
}
|
|
51884
|
+
function validateInlineOrder(c, value, path10) {
|
|
51885
|
+
if (!Array.isArray(value)) {
|
|
51886
|
+
c.add(
|
|
51887
|
+
path10,
|
|
51888
|
+
`must be an array of ${INLINE_FORMATS.length} inline formats, not ${describe(value)}`
|
|
51889
|
+
);
|
|
51890
|
+
return;
|
|
51891
|
+
}
|
|
51892
|
+
const seen = /* @__PURE__ */ new Set();
|
|
51893
|
+
value.forEach((item, i) => {
|
|
51894
|
+
if (!c.oneOf(item, child(path10, i), INLINE_FORMATS)) return;
|
|
51895
|
+
if (seen.has(item)) c.add(child(path10, i), `duplicate format "${item}"`);
|
|
51896
|
+
seen.add(item);
|
|
51897
|
+
});
|
|
51898
|
+
const missing = INLINE_FORMATS.filter((format) => !seen.has(format));
|
|
51899
|
+
if (missing.length) c.add(path10, `must list every inline format; missing ${listed(missing)}`);
|
|
51900
|
+
}
|
|
51901
|
+
function validateOptions(c, value, path10) {
|
|
51902
|
+
if (!isObject2(value)) {
|
|
51903
|
+
c.add(path10, `must be an object, not ${describe(value)}`);
|
|
51904
|
+
return;
|
|
51905
|
+
}
|
|
51906
|
+
for (const key of c.keys(value, path10, [
|
|
51907
|
+
"titleFallback",
|
|
51908
|
+
"richLinkImages",
|
|
51909
|
+
"richLinkImageCaption",
|
|
51910
|
+
"listIndent"
|
|
51911
|
+
])) {
|
|
51912
|
+
const at = child(path10, key);
|
|
51913
|
+
if (key === "richLinkImageCaption")
|
|
51914
|
+
c.oneOf(value[key], at, ["none", "followingItalicParagraph"]);
|
|
51915
|
+
else if (key === "listIndent") {
|
|
51916
|
+
if (typeof value[key] !== "string" || !/^[ \t]{0,16}$/.test(value[key]))
|
|
51917
|
+
c.add(at, "must be a string of at most 16 spaces or tabs");
|
|
51918
|
+
} else c.boolean(value[key], at);
|
|
51919
|
+
}
|
|
51920
|
+
}
|
|
51921
|
+
function templateErrors(input) {
|
|
51922
|
+
const c = new Collector();
|
|
51923
|
+
if (!isObject2(input)) {
|
|
51924
|
+
c.add("$", `a template must be a JSON object, not ${describe(input)}`);
|
|
51925
|
+
return c.errors;
|
|
51926
|
+
}
|
|
51927
|
+
if (input.schemaVersion !== TEMPLATE_SCHEMA_VERSION) {
|
|
51928
|
+
c.add(
|
|
51929
|
+
"$.schemaVersion",
|
|
51930
|
+
"schemaVersion" in input ? `must be ${TEMPLATE_SCHEMA_VERSION}, not ${describeVersion(input.schemaVersion)}` : `is required and must be ${TEMPLATE_SCHEMA_VERSION}`
|
|
51931
|
+
);
|
|
51932
|
+
return c.errors;
|
|
51933
|
+
}
|
|
51934
|
+
const keys = c.keys(input, "$", [
|
|
51935
|
+
"schemaVersion",
|
|
51936
|
+
"name",
|
|
51937
|
+
"description",
|
|
51938
|
+
"extends",
|
|
51939
|
+
"assets",
|
|
51940
|
+
"inlineOrder",
|
|
51941
|
+
"rules",
|
|
51942
|
+
"options"
|
|
51943
|
+
]);
|
|
51944
|
+
for (const key of keys) {
|
|
51945
|
+
const path10 = child("$", key);
|
|
51946
|
+
const value = input[key];
|
|
51947
|
+
switch (key) {
|
|
51948
|
+
case "schemaVersion":
|
|
51949
|
+
break;
|
|
51950
|
+
case "name":
|
|
51951
|
+
case "description":
|
|
51952
|
+
c.text(value, path10, { max: MAX_META_LENGTH, allowed: [] });
|
|
51953
|
+
break;
|
|
51954
|
+
case "extends":
|
|
51955
|
+
c.oneOf(value, path10, BUILTIN_TEMPLATE_NAMES);
|
|
51956
|
+
break;
|
|
51957
|
+
case "assets":
|
|
51958
|
+
if (!isObject2(value)) {
|
|
51959
|
+
c.add(path10, `must be an object, not ${describe(value)}`);
|
|
51960
|
+
break;
|
|
51961
|
+
}
|
|
51962
|
+
for (const field of c.keys(value, path10, ["mode", "pathStyle", "directory"])) {
|
|
51963
|
+
const at = child(path10, field);
|
|
51964
|
+
if (field === "mode") c.oneOf(value.mode, at, ["copy", "reference", "omit"]);
|
|
51965
|
+
else if (field === "pathStyle")
|
|
51966
|
+
c.oneOf(value.pathStyle, at, ["relative", "absolute"]);
|
|
51967
|
+
else validateDirectory(c, value.directory, at);
|
|
51968
|
+
}
|
|
51969
|
+
break;
|
|
51970
|
+
case "inlineOrder":
|
|
51971
|
+
validateInlineOrder(c, value, path10);
|
|
51972
|
+
break;
|
|
51973
|
+
case "rules":
|
|
51974
|
+
if (!isObject2(value)) {
|
|
51975
|
+
c.add(path10, `must be an object keyed by rule id, not ${describe(value)}`);
|
|
51976
|
+
break;
|
|
51977
|
+
}
|
|
51978
|
+
for (const id2 of Object.keys(value).sort()) {
|
|
51979
|
+
if (!RULE_IDS.includes(id2))
|
|
51980
|
+
c.add(child(path10, id2), "unknown rule id; see the template reference for the list");
|
|
51981
|
+
else validateRule(c, value[id2], child(path10, id2));
|
|
51982
|
+
}
|
|
51983
|
+
break;
|
|
51984
|
+
default:
|
|
51985
|
+
validateOptions(c, value, path10);
|
|
51986
|
+
}
|
|
51987
|
+
}
|
|
51988
|
+
return c.errors;
|
|
51989
|
+
}
|
|
51990
|
+
function validateTemplate(input) {
|
|
51991
|
+
const errors = templateErrors(input);
|
|
51992
|
+
if (errors.length) throw new TemplateValidationError(errors);
|
|
51993
|
+
return input;
|
|
51994
|
+
}
|
|
51995
|
+
function jsonErrorLocation(text2, message) {
|
|
51996
|
+
const lineColumn = /\(line (\d+) column (\d+)\)/.exec(message);
|
|
51997
|
+
if (lineColumn) return { line: Number(lineColumn[1]), column: Number(lineColumn[2]) };
|
|
51998
|
+
const position = /at position (\d+)/.exec(message);
|
|
51999
|
+
if (!position) return void 0;
|
|
52000
|
+
const offset = Math.min(Number(position[1]), text2.length);
|
|
52001
|
+
const before = text2.slice(0, offset).split("\n");
|
|
52002
|
+
return { line: before.length, column: before[before.length - 1].length + 1 };
|
|
52003
|
+
}
|
|
52004
|
+
function parseTemplate(text2) {
|
|
52005
|
+
const bytes = Buffer.byteLength(text2, "utf8");
|
|
52006
|
+
if (bytes > MAX_TEMPLATE_BYTES)
|
|
52007
|
+
throw new TemplateValidationError([
|
|
52008
|
+
{ path: "$", message: `template is ${bytes} bytes; the limit is ${MAX_TEMPLATE_BYTES}` }
|
|
52009
|
+
]);
|
|
52010
|
+
let parsed;
|
|
52011
|
+
try {
|
|
52012
|
+
parsed = JSON.parse(text2);
|
|
52013
|
+
} catch (error2) {
|
|
52014
|
+
const at = jsonErrorLocation(text2, error2.message);
|
|
52015
|
+
throw new TemplateValidationError([
|
|
52016
|
+
{
|
|
52017
|
+
path: "$",
|
|
52018
|
+
message: at ? `not valid JSON at line ${at.line}, column ${at.column}` : "not valid JSON"
|
|
52019
|
+
}
|
|
52020
|
+
]);
|
|
52021
|
+
}
|
|
52022
|
+
return validateTemplate(parsed);
|
|
52023
|
+
}
|
|
52024
|
+
function resolveTemplate(template, name) {
|
|
52025
|
+
if (template === STANDARD) return merge2(void 0, STANDARD, name);
|
|
52026
|
+
return merge2(resolveTemplate(BUILTINS[template.extends ?? "standard-markdown"]), template, name);
|
|
52027
|
+
}
|
|
52028
|
+
function merge2(base, template, name) {
|
|
52029
|
+
return {
|
|
52030
|
+
name: name ?? template.name ?? base?.name ?? "template",
|
|
52031
|
+
...template.description !== void 0 ? { description: template.description } : base?.description !== void 0 ? { description: base.description } : {},
|
|
52032
|
+
assets: { ...base?.assets, ...template.assets },
|
|
52033
|
+
inlineOrder: [...template.inlineOrder ?? base.inlineOrder],
|
|
52034
|
+
rules: { ...base?.rules, ...template.rules },
|
|
52035
|
+
options: { ...base?.options, ...template.options }
|
|
52036
|
+
};
|
|
52037
|
+
}
|
|
52038
|
+
var plainValue = (text2) => ({ md: text2, raw: text2 });
|
|
52039
|
+
function fillPlaceholders(text2, values) {
|
|
52040
|
+
return text2.replace(TOKEN, (token, body) => {
|
|
52041
|
+
const parsed = TOKEN_BODY.exec(body);
|
|
52042
|
+
const raw = parsed ? values[parsed[1]] : void 0;
|
|
52043
|
+
const value = typeof raw === "string" ? plainValue(raw) : raw;
|
|
52044
|
+
if (parsed?.[2] === "yaml") {
|
|
52045
|
+
if (!value) return "null";
|
|
52046
|
+
return JSON.stringify(value.list ?? value.raw);
|
|
52047
|
+
}
|
|
52048
|
+
if (!value) return "";
|
|
52049
|
+
return parsed?.[2] === "raw" ? value.raw : value.md;
|
|
52050
|
+
});
|
|
52051
|
+
}
|
|
52052
|
+
function ruleUses(rule, name) {
|
|
52053
|
+
return [rule.before, rule.after, rule.value].some(
|
|
52054
|
+
(text2) => text2 !== void 0 && placeholderTokens(text2).some((token) => token.name === name)
|
|
52055
|
+
);
|
|
52056
|
+
}
|
|
52057
|
+
|
|
52058
|
+
// src/utils/templateRender.ts
|
|
52059
|
+
var FILE_BACKED = /* @__PURE__ */ new Set([
|
|
52060
|
+
"image",
|
|
52061
|
+
"drawing",
|
|
52062
|
+
"paper",
|
|
52063
|
+
"scan",
|
|
52064
|
+
"pdf",
|
|
52065
|
+
"audio",
|
|
52066
|
+
"video",
|
|
52067
|
+
"file",
|
|
52068
|
+
"gallery"
|
|
52069
|
+
]);
|
|
52070
|
+
var KIND_RULES = {
|
|
52071
|
+
image: "attachment.image",
|
|
52072
|
+
drawing: "attachment.drawing.classic",
|
|
52073
|
+
paper: "attachment.drawing.paper",
|
|
52074
|
+
scan: "attachment.scan",
|
|
52075
|
+
pdf: "attachment.pdf",
|
|
52076
|
+
audio: "attachment.audio",
|
|
52077
|
+
video: "attachment.video",
|
|
52078
|
+
file: "attachment.other",
|
|
52079
|
+
table: "attachment.table",
|
|
52080
|
+
divider: "attachment.divider",
|
|
52081
|
+
gallery: "attachment.gallery",
|
|
52082
|
+
link: "attachment.url"
|
|
52083
|
+
};
|
|
52084
|
+
var IMAGE_URL_EXTENSIONS = /\.(?:apng|avif|bmp|gif|heic|heif|ico|jfif|jpe?g|jxl|png|svgz?|tiff?|webp)$/i;
|
|
52085
|
+
function isImageUrl(url) {
|
|
52086
|
+
try {
|
|
52087
|
+
const parsed = new URL(url);
|
|
52088
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return false;
|
|
52089
|
+
let path10 = parsed.pathname;
|
|
52090
|
+
try {
|
|
52091
|
+
path10 = decodeURIComponent(path10);
|
|
52092
|
+
} catch {
|
|
52093
|
+
}
|
|
52094
|
+
return IMAGE_URL_EXTENSIONS.test(path10);
|
|
52095
|
+
} catch {
|
|
52096
|
+
return false;
|
|
52097
|
+
}
|
|
52098
|
+
}
|
|
52099
|
+
function isMapUrl(url) {
|
|
52100
|
+
try {
|
|
52101
|
+
const host = new URL(url).hostname.toLowerCase();
|
|
52102
|
+
return host === "maps.apple.com" || host.endsWith(".maps.apple.com");
|
|
52103
|
+
} catch {
|
|
52104
|
+
return false;
|
|
52105
|
+
}
|
|
52106
|
+
}
|
|
52107
|
+
function attachmentRuleId(attachment, template) {
|
|
52108
|
+
if (attachment.kind === "inline") return void 0;
|
|
52109
|
+
if (attachment.kind === "link") {
|
|
52110
|
+
const url = attachment.url ?? "";
|
|
52111
|
+
if (template.options.richLinkImages && isImageUrl(url)) return "attachment.url.image";
|
|
52112
|
+
if (isMapUrl(url)) return "attachment.map";
|
|
52113
|
+
}
|
|
52114
|
+
return KIND_RULES[attachment.kind] ?? "attachment.other";
|
|
52115
|
+
}
|
|
52116
|
+
function applyRule(rule, content, values) {
|
|
52117
|
+
const fill = (text2 = "") => fillPlaceholders(text2, { ...values, content: plainValue(content) });
|
|
52118
|
+
switch (rule.mode) {
|
|
52119
|
+
case "omit":
|
|
52120
|
+
return void 0;
|
|
52121
|
+
case "plain":
|
|
52122
|
+
return content;
|
|
52123
|
+
case "wrap":
|
|
52124
|
+
return fill(rule.before) + content + fill(rule.after);
|
|
52125
|
+
case "pattern":
|
|
52126
|
+
return fill(rule.value);
|
|
52127
|
+
case "linePrefix": {
|
|
52128
|
+
const prefix = fill(rule.value);
|
|
52129
|
+
return content.split("\n").map((line) => line ? prefix + line : prefix.trimEnd()).join("\n");
|
|
52130
|
+
}
|
|
52131
|
+
}
|
|
52132
|
+
}
|
|
52133
|
+
function applyInline(rule, text2, values) {
|
|
52134
|
+
const match = /^(\s*)([\s\S]*?)(\s*)$/.exec(text2);
|
|
52135
|
+
if (!match[2]) return text2;
|
|
52136
|
+
const out = applyRule(rule, match[2], values);
|
|
52137
|
+
return out === void 0 ? "" : `${match[1]}${out}${match[3]}`;
|
|
52138
|
+
}
|
|
52139
|
+
var HIGHLIGHT_RULES = /* @__PURE__ */ new Set(["purple", "pink", "orange", "mint", "blue"]);
|
|
52140
|
+
function highlightRule(name) {
|
|
52141
|
+
return HIGHLIGHT_RULES.has(name) ? `inline.highlight.${name}` : "inline.highlight.other";
|
|
52142
|
+
}
|
|
52143
|
+
function buildLayers(template) {
|
|
52144
|
+
const { rules } = template;
|
|
52145
|
+
const active = (rule) => rule.mode !== "plain";
|
|
52146
|
+
const flag3 = (format) => {
|
|
52147
|
+
const rule = rules[`inline.${format}`];
|
|
52148
|
+
return {
|
|
52149
|
+
key: (fmt) => fmt[format] && active(rule) ? "on" : void 0,
|
|
52150
|
+
rule: () => rule,
|
|
52151
|
+
values: () => ({})
|
|
52152
|
+
};
|
|
52153
|
+
};
|
|
52154
|
+
const layers = {
|
|
52155
|
+
bold: flag3("bold"),
|
|
52156
|
+
italic: flag3("italic"),
|
|
52157
|
+
underline: flag3("underline"),
|
|
52158
|
+
strikethrough: flag3("strikethrough"),
|
|
52159
|
+
superscript: flag3("superscript"),
|
|
52160
|
+
subscript: flag3("subscript"),
|
|
52161
|
+
highlight: {
|
|
52162
|
+
key: (fmt) => {
|
|
52163
|
+
if (!fmt.highlight) return void 0;
|
|
52164
|
+
const rule = rules[highlightRule(fmt.highlight)];
|
|
52165
|
+
if (!active(rule)) return void 0;
|
|
52166
|
+
return JSON.stringify(rule) + (ruleUses(rule, "highlight") ? fmt.highlight : "");
|
|
52167
|
+
},
|
|
52168
|
+
rule: (fmt) => rules[highlightRule(fmt.highlight)],
|
|
52169
|
+
values: (fmt) => ({ highlight: fmt.highlight })
|
|
52170
|
+
},
|
|
52171
|
+
color: {
|
|
52172
|
+
key: (fmt) => {
|
|
52173
|
+
const rule = rules["inline.color"];
|
|
52174
|
+
if (!fmt.color || !active(rule)) return void 0;
|
|
52175
|
+
return ruleUses(rule, "color") ? fmt.color : "on";
|
|
52176
|
+
},
|
|
52177
|
+
rule: () => rules["inline.color"],
|
|
52178
|
+
values: (fmt) => ({ color: fmt.color })
|
|
52179
|
+
},
|
|
52180
|
+
link: {
|
|
52181
|
+
key: (fmt) => fmt.link,
|
|
52182
|
+
rule: () => rules["inline.link"],
|
|
52183
|
+
values: (fmt) => ({ url: { md: linkDestination(fmt.link), raw: fmt.link } })
|
|
52184
|
+
}
|
|
52185
|
+
};
|
|
52186
|
+
return [...template.inlineOrder].reverse().map((format) => layers[format]);
|
|
52187
|
+
}
|
|
52188
|
+
var LIST_STYLES2 = /* @__PURE__ */ new Set(["bulleted", "dashed", "numbered", "checklist"]);
|
|
52189
|
+
var TemplateRenderer = class {
|
|
52190
|
+
constructor(ctx, options) {
|
|
52191
|
+
this.ctx = ctx;
|
|
52192
|
+
this.options = options;
|
|
52193
|
+
this.layers = buildLayers(options.template);
|
|
52194
|
+
this.rules = options.template.rules;
|
|
52195
|
+
}
|
|
52196
|
+
ctx;
|
|
52197
|
+
options;
|
|
52198
|
+
warnings = [];
|
|
52199
|
+
layers;
|
|
52200
|
+
rules;
|
|
52201
|
+
/** The attachment each plan was made from, for rule and placeholder lookup. */
|
|
52202
|
+
origins = /* @__PURE__ */ new WeakMap();
|
|
52203
|
+
get template() {
|
|
52204
|
+
return this.options.template;
|
|
52205
|
+
}
|
|
52206
|
+
/** Placeholder values describing the note. */
|
|
52207
|
+
noteValues(note) {
|
|
52208
|
+
const meta = this.options.metaFor?.(note) ?? {};
|
|
52209
|
+
const text2 = (value) => value === void 0 ? void 0 : { md: escapeMarkdown(value), raw: value };
|
|
52210
|
+
const tags = noteTags(note);
|
|
52211
|
+
const values = {
|
|
52212
|
+
title: text2(note.title.trim()),
|
|
52213
|
+
id: note.id,
|
|
52214
|
+
uuid: meta.uuid,
|
|
52215
|
+
folder: text2(meta.folder),
|
|
52216
|
+
account: text2(meta.account),
|
|
52217
|
+
created: meta.created,
|
|
52218
|
+
modified: meta.modified,
|
|
52219
|
+
tags: {
|
|
52220
|
+
md: tags.map((tag) => escapeMarkdown(tag)).join(", "),
|
|
52221
|
+
raw: tags.join(", "),
|
|
52222
|
+
list: tags
|
|
52223
|
+
},
|
|
52224
|
+
exportStem: this.options.exportStem ?? "export"
|
|
52225
|
+
};
|
|
52226
|
+
return Object.fromEntries(Object.entries(values).filter(([, v]) => v !== void 0));
|
|
52227
|
+
}
|
|
52228
|
+
warn(code, note, attachmentId) {
|
|
52229
|
+
this.warnings.push({ code, noteId: note.id, ...attachmentId ? { attachmentId } : {} });
|
|
52230
|
+
}
|
|
52231
|
+
/** Plan one attachment, honoring omit rules before any file is placed. */
|
|
52232
|
+
plan(note, id2, attachment, binding) {
|
|
52233
|
+
const omitted = { type: "inline", text: "" };
|
|
52234
|
+
if (!attachment) {
|
|
52235
|
+
this.warn("attachment_not_found", note, id2);
|
|
52236
|
+
return planAttachment(void 0, this.ctx);
|
|
52237
|
+
}
|
|
52238
|
+
const ruleId = attachmentRuleId(attachment, this.template);
|
|
52239
|
+
if (ruleId && this.rules[ruleId].mode === "omit") return omitted;
|
|
52240
|
+
const fileBacked = FILE_BACKED.has(attachment.kind);
|
|
52241
|
+
if (fileBacked && this.template.assets.mode === "omit") return omitted;
|
|
52242
|
+
if (fileBacked && !binding.writer && binding.required)
|
|
52243
|
+
this.warn("assets_dir_required", note, attachment.id);
|
|
52244
|
+
const plan = planAttachment(attachment, {
|
|
52245
|
+
...this.ctx,
|
|
52246
|
+
...binding.writer ? { writer: binding.writer } : { writer: void 0 }
|
|
52247
|
+
});
|
|
52248
|
+
this.inspect(note, plan, attachment);
|
|
52249
|
+
return plan;
|
|
52250
|
+
}
|
|
52251
|
+
/** Record origins and warnings for a plan and any gallery items. */
|
|
52252
|
+
inspect(note, plan, attachment) {
|
|
52253
|
+
this.origins.set(plan, attachment);
|
|
52254
|
+
switch (plan.type) {
|
|
52255
|
+
case "inline":
|
|
52256
|
+
if (!plan.text) this.warn("inline_token_metadata_missing", note, attachment.id);
|
|
52257
|
+
break;
|
|
52258
|
+
case "unavailable":
|
|
52259
|
+
this.warn(
|
|
52260
|
+
plan.reason === "undecodable" ? "table_decode_failed" : plan.reason === "missing" ? "missing_asset" : "asset_copy_failed",
|
|
52261
|
+
note,
|
|
52262
|
+
attachment.id
|
|
52263
|
+
);
|
|
52264
|
+
break;
|
|
52265
|
+
case "gallery":
|
|
52266
|
+
if (!plan.items.length) this.warn("gallery_children_missing", note, attachment.id);
|
|
52267
|
+
plan.items.forEach((item, i) => this.inspect(note, item, attachment.children[i]));
|
|
52268
|
+
break;
|
|
52269
|
+
}
|
|
52270
|
+
}
|
|
52271
|
+
/** Placeholder values for an attachment. */
|
|
52272
|
+
attachmentValues(attachment, base) {
|
|
52273
|
+
if (!attachment) return base;
|
|
52274
|
+
const filename = attachment.mediaFilename ?? attachment.title;
|
|
52275
|
+
return {
|
|
52276
|
+
...base,
|
|
52277
|
+
kind: attachment.kind,
|
|
52278
|
+
uti: attachment.uti,
|
|
52279
|
+
...filename ? { filename: { md: escapeMarkdown(filename), raw: filename } } : {}
|
|
52280
|
+
};
|
|
52281
|
+
}
|
|
52282
|
+
/** Render a plan through its template rule; "" when omitted. */
|
|
52283
|
+
renderPlan(plan, values, caption) {
|
|
52284
|
+
const origin = this.origins.get(plan);
|
|
52285
|
+
const vars = this.attachmentValues(origin, values);
|
|
52286
|
+
const apply2 = (id2, content, extra = {}) => applyRule(this.rules[id2], content, { ...vars, ...extra }) ?? "";
|
|
52287
|
+
switch (plan.type) {
|
|
52288
|
+
case "inline":
|
|
52289
|
+
return plan.link ? applyInline(this.rules["inline.link"], escapeMarkdown(plan.text), {
|
|
52290
|
+
...vars,
|
|
52291
|
+
url: { md: linkDestination(plan.link), raw: plan.link }
|
|
52292
|
+
}) : escapeMarkdown(plan.text);
|
|
52293
|
+
case "divider":
|
|
52294
|
+
return apply2("attachment.divider", "");
|
|
52295
|
+
case "table":
|
|
52296
|
+
return apply2("attachment.table", tableMarkdown(plan.rows));
|
|
52297
|
+
case "placeholder":
|
|
52298
|
+
case "unavailable": {
|
|
52299
|
+
const label = plan.type === "unavailable" ? `${plan.label} unavailable` : plan.label;
|
|
52300
|
+
return apply2(
|
|
52301
|
+
"attachment.placeholder",
|
|
52302
|
+
escapeMarkdown(plan.name ? `${label}: ${plan.name}` : label)
|
|
52303
|
+
);
|
|
52304
|
+
}
|
|
52305
|
+
case "asset": {
|
|
52306
|
+
const alt = escapeMarkdown(plan.name ?? plan.label);
|
|
52307
|
+
const id2 = origin && attachmentRuleId(origin, this.template) || "attachment.other";
|
|
52308
|
+
return apply2(id2, "", {
|
|
52309
|
+
alt: { md: alt, raw: plan.name ?? plan.label },
|
|
52310
|
+
path: { md: linkDestination(plan.url), raw: plan.url },
|
|
52311
|
+
linkText: plan.previewUrl ? `})` : alt
|
|
52312
|
+
});
|
|
52313
|
+
}
|
|
52314
|
+
case "card": {
|
|
52315
|
+
if (!plan.url) return `${escapeMarkdown(plan.title)} (${escapeMarkdown(plan.displayUrl)})`;
|
|
52316
|
+
const id2 = origin && attachmentRuleId(origin, this.template) || "attachment.url";
|
|
52317
|
+
const alt = caption ?? plan.title;
|
|
52318
|
+
return apply2(id2, "", {
|
|
52319
|
+
alt: { md: escapeMarkdown(alt), raw: alt },
|
|
52320
|
+
url: { md: linkDestination(plan.url), raw: plan.url },
|
|
52321
|
+
...caption !== void 0 ? { caption: { md: escapeMarkdown(caption), raw: caption } } : {}
|
|
52322
|
+
});
|
|
52323
|
+
}
|
|
52324
|
+
case "gallery": {
|
|
52325
|
+
const rule = this.rules["attachment.gallery"];
|
|
52326
|
+
const items = plan.items.map((item) => this.renderPlan(item, values)).filter(Boolean);
|
|
52327
|
+
if (!items.length) return "";
|
|
52328
|
+
return apply2("attachment.gallery", items.join(rule.join === "line" ? "\n" : "\n\n"));
|
|
52329
|
+
}
|
|
52330
|
+
}
|
|
52331
|
+
}
|
|
52332
|
+
/** Format text runs through the inline layers. */
|
|
52333
|
+
layered(pieces, values, depth = 0) {
|
|
52334
|
+
if (depth === this.layers.length)
|
|
52335
|
+
return pieces.map((piece) => escapeMarkdown(piece.text.replace(/\n/g, " "))).join("");
|
|
52336
|
+
const layer = this.layers[depth];
|
|
52337
|
+
let out = "";
|
|
52338
|
+
for (let i = 0; i < pieces.length; ) {
|
|
52339
|
+
const key = layer.key(pieces[i].fmt);
|
|
52340
|
+
let j = i;
|
|
52341
|
+
while (j < pieces.length && layer.key(pieces[j].fmt) === key) j++;
|
|
52342
|
+
const inner = this.layered(pieces.slice(i, j), values, depth + 1);
|
|
52343
|
+
const fmt = pieces[i].fmt;
|
|
52344
|
+
out = joinSafe(
|
|
52345
|
+
out,
|
|
52346
|
+
key === void 0 ? inner : applyInline(layer.rule(fmt), inner, { ...values, ...layer.values(fmt) })
|
|
52347
|
+
);
|
|
52348
|
+
i = j;
|
|
52349
|
+
}
|
|
52350
|
+
return out;
|
|
52351
|
+
}
|
|
52352
|
+
inline(pieces, values, caption) {
|
|
52353
|
+
let out = "";
|
|
52354
|
+
for (let i = 0; i < pieces.length; ) {
|
|
52355
|
+
const piece = pieces[i];
|
|
52356
|
+
if (piece.type === "attachment") {
|
|
52357
|
+
out = joinSafe(out, this.renderPlan(piece.plan, values, caption));
|
|
52358
|
+
i++;
|
|
52359
|
+
continue;
|
|
52360
|
+
}
|
|
52361
|
+
let j = i;
|
|
52362
|
+
while (j < pieces.length && pieces[j].type === "text") j++;
|
|
52363
|
+
out = joinSafe(out, this.layered(pieces.slice(i, j), values));
|
|
52364
|
+
i = j;
|
|
52365
|
+
}
|
|
52366
|
+
return out;
|
|
52367
|
+
}
|
|
52368
|
+
/** The caption paragraph after a lone image-URL link card, if the template wants one. */
|
|
52369
|
+
captionFor(note, index) {
|
|
52370
|
+
const { options } = this.template;
|
|
52371
|
+
if (!options.richLinkImages || options.richLinkImageCaption !== "followingItalicParagraph")
|
|
52372
|
+
return void 0;
|
|
52373
|
+
const blocks = note.doc.blocks;
|
|
52374
|
+
const current = blocks[index];
|
|
52375
|
+
if (current.text.trim() !== "\uFFFC" || current.attachments.length !== 1) return void 0;
|
|
52376
|
+
const attachment = note.attachments.get(current.attachments[0].id);
|
|
52377
|
+
if (!attachment || attachmentRuleId(attachment, this.template) !== "attachment.url.image")
|
|
52378
|
+
return void 0;
|
|
52379
|
+
if (this.rules["attachment.url.image"].mode === "omit" || !isSafe(attachment.url))
|
|
52380
|
+
return void 0;
|
|
52381
|
+
const next = blocks[index + 1];
|
|
52382
|
+
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))
|
|
52383
|
+
return void 0;
|
|
52384
|
+
return next.text.trim();
|
|
52385
|
+
}
|
|
52386
|
+
/** Render one note's body. */
|
|
52387
|
+
renderBody(note, values) {
|
|
52388
|
+
const binding = this.options.assetsFor?.(note) ?? {};
|
|
52389
|
+
const plan = (id2) => this.plan(note, id2, note.attachments.get(id2), binding);
|
|
52390
|
+
const titleIndex = titleBlockIndex(note);
|
|
52391
|
+
const lines = [];
|
|
52392
|
+
const counters = [];
|
|
52393
|
+
const skip = /* @__PURE__ */ new Set();
|
|
52394
|
+
let code;
|
|
52395
|
+
const push = (text2, quote, group) => {
|
|
52396
|
+
if (!text2) return;
|
|
52397
|
+
if (quote) {
|
|
52398
|
+
const quoted2 = applyRule(this.rules["paragraph.quote"], text2, values);
|
|
52399
|
+
if (!quoted2) return;
|
|
52400
|
+
text2 = quoted2;
|
|
52401
|
+
}
|
|
52402
|
+
lines.push({ text: text2, quote, ...group ? { group } : {} });
|
|
52403
|
+
};
|
|
52404
|
+
const ruled = (id2, content, extra = {}) => applyRule(this.rules[id2], content, { ...values, ...extra });
|
|
52405
|
+
const groupOf = (id2, list) => this.rules[id2].join === "line" ? list ? "list" : id2 : void 0;
|
|
52406
|
+
const flushCode = () => {
|
|
52407
|
+
if (!code) return;
|
|
52408
|
+
const longest = Math.max(
|
|
52409
|
+
2,
|
|
52410
|
+
...code.lines.map((l) => Math.max(0, ...(l.match(/`+/g) ?? []).map((m) => m.length)))
|
|
52411
|
+
);
|
|
52412
|
+
push(
|
|
52413
|
+
ruled("block.code", code.lines.join("\n"), { fence: "`".repeat(longest + 1) }),
|
|
52414
|
+
code.quote,
|
|
52415
|
+
groupOf("block.code", false)
|
|
52416
|
+
);
|
|
52417
|
+
code = void 0;
|
|
52418
|
+
};
|
|
52419
|
+
if (this.template.options.titleFallback && titleIndex === -1 && note.title.trim())
|
|
52420
|
+
push(
|
|
52421
|
+
ruled("block.title", escapeMarkdown(note.title.trim())),
|
|
52422
|
+
false,
|
|
52423
|
+
groupOf("block.title", false)
|
|
52424
|
+
);
|
|
52425
|
+
for (const block of note.doc.blocks) {
|
|
52426
|
+
if (skip.has(block.index)) continue;
|
|
52427
|
+
if (block.style === "monospaced") {
|
|
52428
|
+
if (code && code.quote !== block.blockQuote) flushCode();
|
|
52429
|
+
code ??= { lines: [], quote: block.blockQuote };
|
|
52430
|
+
code.lines.push(block.text.replace(//g, ""));
|
|
52431
|
+
continue;
|
|
52432
|
+
}
|
|
52433
|
+
flushCode();
|
|
52434
|
+
if (!LIST_STYLES2.has(block.style)) counters.length = 0;
|
|
52435
|
+
if (!block.text.trim()) continue;
|
|
52436
|
+
const caption = this.captionFor(note, block.index);
|
|
52437
|
+
if (caption !== void 0) skip.add(block.index + 1);
|
|
52438
|
+
const pieces = blockPieces(block, plan);
|
|
52439
|
+
let segment = [];
|
|
52440
|
+
const segments = [];
|
|
52441
|
+
for (const piece of pieces) {
|
|
52442
|
+
if (piece.type === "attachment" && isBlockPlan(piece.plan)) {
|
|
52443
|
+
segments.push(segment, piece.plan);
|
|
52444
|
+
segment = [];
|
|
52445
|
+
} else segment.push(piece);
|
|
52446
|
+
}
|
|
52447
|
+
segments.push(segment);
|
|
52448
|
+
let first2 = true;
|
|
52449
|
+
for (const segment2 of segments) {
|
|
52450
|
+
if (!Array.isArray(segment2)) {
|
|
52451
|
+
push(this.renderPlan(segment2, values), block.blockQuote);
|
|
52452
|
+
continue;
|
|
52453
|
+
}
|
|
52454
|
+
const body = this.inline(segment2, values, caption).trim();
|
|
52455
|
+
if (!body) continue;
|
|
52456
|
+
const [text2, group] = this.blockLine(
|
|
52457
|
+
block,
|
|
52458
|
+
body,
|
|
52459
|
+
first2,
|
|
52460
|
+
block.index === titleIndex,
|
|
52461
|
+
counters,
|
|
52462
|
+
values
|
|
52463
|
+
);
|
|
52464
|
+
push(text2, block.blockQuote, group);
|
|
52465
|
+
first2 = false;
|
|
52466
|
+
}
|
|
52467
|
+
}
|
|
52468
|
+
flushCode();
|
|
52469
|
+
for (const attachment of unreferencedAttachments(note)) {
|
|
52470
|
+
this.ctx.stats.unreferenced++;
|
|
52471
|
+
push(this.renderPlan(this.plan(note, attachment.id, attachment, binding), values), false);
|
|
52472
|
+
}
|
|
52473
|
+
return this.join(lines, values);
|
|
52474
|
+
}
|
|
52475
|
+
/** One paragraph through its block rule, with list indent and numbering. */
|
|
52476
|
+
blockLine(block, body, first2, isTitle, counters, values) {
|
|
52477
|
+
const rule = (id2, content, extra = {}, list = false) => [
|
|
52478
|
+
applyRule(this.rules[id2], content, { ...values, ...extra }),
|
|
52479
|
+
this.rules[id2].join === "line" ? list ? "list" : id2 : void 0
|
|
52480
|
+
];
|
|
52481
|
+
if (isTitle || block.style === "title") return rule("block.title", body);
|
|
52482
|
+
if (block.style === "heading") return rule("block.heading", body);
|
|
52483
|
+
if (block.style === "subheading") return rule("block.subheading", body);
|
|
52484
|
+
if (!LIST_STYLES2.has(block.style) || !first2) return rule("block.body", escapeLineStart(body));
|
|
52485
|
+
const item = escapeLineStart(body);
|
|
52486
|
+
const level = Math.min(block.indent, 20);
|
|
52487
|
+
counters.length = Math.min(counters.length, level + 1);
|
|
52488
|
+
while (counters.length <= level) counters.push(0);
|
|
52489
|
+
let result;
|
|
52490
|
+
if (block.style === "numbered")
|
|
52491
|
+
result = rule("block.numbered", item, { index: String(++counters[level]) }, true);
|
|
52492
|
+
else {
|
|
52493
|
+
counters[level] = 0;
|
|
52494
|
+
if (block.style === "checklist") {
|
|
52495
|
+
const done = !!block.checklist?.done;
|
|
52496
|
+
result = rule(
|
|
52497
|
+
done ? "block.checklist.checked" : "block.checklist.unchecked",
|
|
52498
|
+
item,
|
|
52499
|
+
{ checked: String(done) },
|
|
52500
|
+
true
|
|
52501
|
+
);
|
|
52502
|
+
} else
|
|
52503
|
+
result = rule(block.style === "dashed" ? "block.dashed" : "block.bulleted", item, {}, true);
|
|
52504
|
+
}
|
|
52505
|
+
const indent = this.template.options.listIndent.repeat(level);
|
|
52506
|
+
if (result[0] && indent)
|
|
52507
|
+
result[0] = result[0].split("\n").map((line) => line ? indent + line : line).join("\n");
|
|
52508
|
+
return result;
|
|
52509
|
+
}
|
|
52510
|
+
/** Join lines: one newline within a `line`-join group, a blank line elsewhere. */
|
|
52511
|
+
join(lines, values) {
|
|
52512
|
+
const quote = this.rules["paragraph.quote"];
|
|
52513
|
+
const quoteGap = quote.mode === "linePrefix" ? `
|
|
52514
|
+
${fillPlaceholders(quote.value ?? "", values).trimEnd()}
|
|
52515
|
+
` : "\n\n";
|
|
52516
|
+
let out = "";
|
|
52517
|
+
let previous;
|
|
52518
|
+
for (const line of lines) {
|
|
52519
|
+
if (previous) {
|
|
52520
|
+
const tight = previous.group !== void 0 && previous.group === line.group && previous.quote === line.quote;
|
|
52521
|
+
out += tight ? "\n" : previous.quote && line.quote ? quoteGap : "\n\n";
|
|
52522
|
+
}
|
|
52523
|
+
out += line.text;
|
|
52524
|
+
previous = line;
|
|
52525
|
+
}
|
|
52526
|
+
return out;
|
|
52527
|
+
}
|
|
52528
|
+
};
|
|
52529
|
+
var isSafe = (url) => !!url && /^https?:\/\//i.test(url) && !Array.from(url).some((c) => c.charCodeAt(0) < 32);
|
|
52530
|
+
function noteTags(note) {
|
|
52531
|
+
const tags = [];
|
|
52532
|
+
for (const attachment of note.attachments.values()) {
|
|
52533
|
+
if (!attachment.uti.endsWith(".hashtag") || !attachment.altText) continue;
|
|
52534
|
+
const tag = attachment.altText.replace(/^#/, "").trim();
|
|
52535
|
+
if (tag && !tags.includes(tag)) tags.push(tag);
|
|
52536
|
+
}
|
|
52537
|
+
return tags;
|
|
52538
|
+
}
|
|
52539
|
+
function renderNotesWithTemplate(notes, ctx, options) {
|
|
52540
|
+
const renderer = new TemplateRenderer(ctx, options);
|
|
52541
|
+
const rules = options.template.rules;
|
|
52542
|
+
let markdown = "";
|
|
52543
|
+
notes.forEach((note, i) => {
|
|
52544
|
+
const values = renderer.noteValues(note);
|
|
52545
|
+
if (i > 0) markdown += applyRule(rules["document.separator"], "", values) ?? "";
|
|
52546
|
+
const body = renderer.renderBody(note, values);
|
|
52547
|
+
markdown += (applyRule(rules["document.header"], "", values) ?? "") + (options.wrap ? wrapMarkdown(body, options.wrap) : body) + (applyRule(rules["document.footer"], "", values) ?? "");
|
|
52548
|
+
});
|
|
52549
|
+
return { markdown: markdown + (notes.length ? "\n" : ""), warnings: renderer.warnings };
|
|
52550
|
+
}
|
|
52551
|
+
|
|
52552
|
+
// src/utils/templateAssets.ts
|
|
52553
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
52554
|
+
import {
|
|
52555
|
+
closeSync as closeSync5,
|
|
52556
|
+
constants as constants5,
|
|
52557
|
+
fstatSync as fstatSync5,
|
|
52558
|
+
lstatSync as lstatSync4,
|
|
52559
|
+
mkdirSync as mkdirSync5,
|
|
52560
|
+
openSync as openSync5,
|
|
52561
|
+
readSync as readSync4,
|
|
52562
|
+
writeSync as writeSync4
|
|
52563
|
+
} from "node:fs";
|
|
52564
|
+
import { extname as extname4, isAbsolute as isAbsolute3, join as join21, relative as relative4, resolve as resolve4, sep as sep4 } from "node:path";
|
|
52565
|
+
var CHUNK = 1024 * 1024;
|
|
52566
|
+
function openRegular(path10) {
|
|
52567
|
+
const fd = openSync5(path10, constants5.O_RDONLY | constants5.O_NOFOLLOW);
|
|
52568
|
+
if (!fstatSync5(fd).isFile()) {
|
|
52569
|
+
closeSync5(fd);
|
|
52570
|
+
throw new Error("not a regular file");
|
|
52571
|
+
}
|
|
52572
|
+
return fd;
|
|
52573
|
+
}
|
|
52574
|
+
function digest(fd) {
|
|
52575
|
+
const hash = createHash2("sha256");
|
|
52576
|
+
const chunk = Buffer.alloc(CHUNK);
|
|
52577
|
+
let head = Buffer.alloc(0);
|
|
52578
|
+
for (let position = 0; ; ) {
|
|
52579
|
+
const n = readSync4(fd, chunk, 0, chunk.length, position);
|
|
52580
|
+
if (n <= 0) break;
|
|
52581
|
+
if (position === 0) head = Buffer.from(chunk.subarray(0, Math.min(n, 16)));
|
|
52582
|
+
hash.update(chunk.subarray(0, n));
|
|
52583
|
+
position += n;
|
|
52584
|
+
}
|
|
52585
|
+
return { hash: hash.digest("hex"), head };
|
|
52586
|
+
}
|
|
52587
|
+
function urlFor(target, linkBase) {
|
|
52588
|
+
return encodePathUrl(linkBase ? relative4(linkBase, target).split(sep4).join("/") : target);
|
|
52589
|
+
}
|
|
52590
|
+
var HashedSidecarWriter = class {
|
|
52591
|
+
constructor(dir, linkBase) {
|
|
52592
|
+
this.dir = dir;
|
|
52593
|
+
this.linkBase = linkBase;
|
|
52594
|
+
}
|
|
52595
|
+
dir;
|
|
52596
|
+
linkBase;
|
|
52597
|
+
placed = /* @__PURE__ */ new Map();
|
|
52598
|
+
ready = false;
|
|
52599
|
+
/** Absolute paths of files written or reused. */
|
|
52600
|
+
files = [];
|
|
52601
|
+
count = 0;
|
|
52602
|
+
prepare() {
|
|
52603
|
+
if (this.ready) return;
|
|
52604
|
+
assertExportPath(this.dir);
|
|
52605
|
+
mkdirSync5(this.dir, { recursive: true });
|
|
52606
|
+
if (!lstatSync4(this.dir).isDirectory()) throw new Error("assets directory is not a directory");
|
|
52607
|
+
this.ready = true;
|
|
52608
|
+
}
|
|
52609
|
+
place(asset) {
|
|
52610
|
+
const done = this.placed.get(asset.path);
|
|
52611
|
+
if (done) return done;
|
|
52612
|
+
let source;
|
|
52613
|
+
try {
|
|
52614
|
+
source = openRegular(asset.path);
|
|
52615
|
+
} catch {
|
|
52616
|
+
return { error: "unreadable" };
|
|
52617
|
+
}
|
|
52618
|
+
try {
|
|
52619
|
+
const { hash, head } = digest(source);
|
|
52620
|
+
const mime = sniffMime(head, asset.name);
|
|
52621
|
+
this.prepare();
|
|
52622
|
+
const name = safeAssetName(asset.name, mime);
|
|
52623
|
+
const ext = extname4(name);
|
|
52624
|
+
const target = join21(
|
|
52625
|
+
this.dir,
|
|
52626
|
+
`${name.slice(0, name.length - ext.length)}-${hash.slice(0, 8)}${ext}`
|
|
52627
|
+
);
|
|
52628
|
+
let existing;
|
|
52629
|
+
try {
|
|
52630
|
+
existing = openRegular(target);
|
|
52631
|
+
} catch (error2) {
|
|
52632
|
+
const code = error2.code;
|
|
52633
|
+
if (code !== "ENOENT") return { error: "destination-not-regular" };
|
|
52634
|
+
}
|
|
52635
|
+
if (existing !== void 0) {
|
|
52636
|
+
try {
|
|
52637
|
+
if (digest(existing).hash !== hash) return { error: "name-taken" };
|
|
52638
|
+
} finally {
|
|
52639
|
+
closeSync5(existing);
|
|
52640
|
+
}
|
|
52641
|
+
} else this.copy(source, target);
|
|
52642
|
+
this.count++;
|
|
52643
|
+
this.files.push(target);
|
|
52644
|
+
const result = { url: urlFor(target, this.linkBase), mime };
|
|
52645
|
+
this.placed.set(asset.path, result);
|
|
52646
|
+
return result;
|
|
52647
|
+
} catch (error2) {
|
|
52648
|
+
return { error: error2 instanceof Error ? error2.message : String(error2) };
|
|
52649
|
+
} finally {
|
|
52650
|
+
closeSync5(source);
|
|
52651
|
+
}
|
|
52652
|
+
}
|
|
52653
|
+
copy(source, target) {
|
|
52654
|
+
const out = openSync5(
|
|
52655
|
+
target,
|
|
52656
|
+
constants5.O_WRONLY | constants5.O_CREAT | constants5.O_EXCL | constants5.O_NOFOLLOW,
|
|
52657
|
+
420
|
|
52658
|
+
);
|
|
52659
|
+
try {
|
|
52660
|
+
const chunk = Buffer.alloc(CHUNK);
|
|
52661
|
+
for (let position = 0; ; ) {
|
|
52662
|
+
const n = readSync4(source, chunk, 0, chunk.length, position);
|
|
52663
|
+
if (n <= 0) break;
|
|
52664
|
+
let written = 0;
|
|
52665
|
+
while (written < n) written += writeSync4(out, chunk, written, n - written);
|
|
52666
|
+
position += n;
|
|
52667
|
+
}
|
|
52668
|
+
} finally {
|
|
52669
|
+
closeSync5(out);
|
|
52670
|
+
}
|
|
52671
|
+
}
|
|
52672
|
+
};
|
|
52673
|
+
var ReferenceWriter = class {
|
|
52674
|
+
constructor(linkBase) {
|
|
52675
|
+
this.linkBase = linkBase;
|
|
52676
|
+
}
|
|
52677
|
+
linkBase;
|
|
52678
|
+
count = 0;
|
|
52679
|
+
place(asset) {
|
|
52680
|
+
let fd;
|
|
52681
|
+
try {
|
|
52682
|
+
fd = openRegular(asset.path);
|
|
52683
|
+
} catch {
|
|
52684
|
+
return { error: "unreadable" };
|
|
52685
|
+
}
|
|
52686
|
+
try {
|
|
52687
|
+
const head = Buffer.alloc(16);
|
|
52688
|
+
const n = readSync4(fd, head, 0, 16, 0);
|
|
52689
|
+
this.count++;
|
|
52690
|
+
return {
|
|
52691
|
+
url: urlFor(asset.path, this.linkBase),
|
|
52692
|
+
mime: sniffMime(head.subarray(0, n), asset.name)
|
|
52693
|
+
};
|
|
52694
|
+
} finally {
|
|
52695
|
+
closeSync5(fd);
|
|
52696
|
+
}
|
|
52697
|
+
}
|
|
52698
|
+
};
|
|
52699
|
+
function pathComponent(value) {
|
|
52700
|
+
const clean = Array.from(
|
|
52701
|
+
value.normalize("NFC"),
|
|
52702
|
+
(char) => char.charCodeAt(0) < 32 || char === "\x7F" ? "_" : char
|
|
52703
|
+
).join("").replace(/[/\\:]+/g, "_").replace(/^[.\s]+/, "").trim().slice(0, 120);
|
|
52704
|
+
return clean || "untitled";
|
|
52705
|
+
}
|
|
52706
|
+
function templateAssetsDir(directory, outputDir, values) {
|
|
52707
|
+
const safe = {};
|
|
52708
|
+
for (const [key, value] of Object.entries(values)) {
|
|
52709
|
+
const raw = typeof value === "string" ? value : value?.raw;
|
|
52710
|
+
if (raw !== void 0) safe[key] = pathComponent(raw);
|
|
52711
|
+
}
|
|
52712
|
+
const filled = fillPlaceholders(directory, safe);
|
|
52713
|
+
const base = resolve4(outputDir);
|
|
52714
|
+
const dir = resolve4(base, filled);
|
|
52715
|
+
if (isAbsolute3(filled) || filled.split("/").includes("..") || !dir.startsWith(base + sep4))
|
|
52716
|
+
throw new Error(`assets.directory "${directory}" resolves outside the output directory`);
|
|
52717
|
+
return dir;
|
|
52718
|
+
}
|
|
52719
|
+
function readTemplateFile(path10) {
|
|
52720
|
+
const abs = assertExportPath(path10);
|
|
52721
|
+
if (extname4(abs).toLowerCase() !== ".json")
|
|
52722
|
+
throw new Error(`Template file must have a .json extension: ${abs}`);
|
|
52723
|
+
let fd;
|
|
52724
|
+
try {
|
|
52725
|
+
fd = openRegular(abs);
|
|
52726
|
+
} catch (error2) {
|
|
52727
|
+
const code = error2.code;
|
|
52728
|
+
throw new Error(
|
|
52729
|
+
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}`
|
|
52730
|
+
);
|
|
52731
|
+
}
|
|
52732
|
+
try {
|
|
52733
|
+
const size = fstatSync5(fd).size;
|
|
52734
|
+
if (size > MAX_TEMPLATE_BYTES)
|
|
52735
|
+
throw new Error(`Template file is ${size} bytes; the limit is ${MAX_TEMPLATE_BYTES}`);
|
|
52736
|
+
const data = Buffer.alloc(size);
|
|
52737
|
+
let read = 0;
|
|
52738
|
+
while (read < size) {
|
|
52739
|
+
const n = readSync4(fd, data, read, size - read, read);
|
|
52740
|
+
if (n <= 0) break;
|
|
52741
|
+
read += n;
|
|
52742
|
+
}
|
|
52743
|
+
return data.subarray(0, read).toString("utf8");
|
|
52744
|
+
} finally {
|
|
52745
|
+
closeSync5(fd);
|
|
52746
|
+
}
|
|
52747
|
+
}
|
|
51511
52748
|
|
|
51512
52749
|
// src/services/notesExport.ts
|
|
51513
52750
|
var DEFAULT_FOLDER_EXPORT_LIMIT = 100;
|
|
51514
52751
|
var MAX_FOLDER_EXPORT_LIMIT = 1e3;
|
|
51515
52752
|
var NotesExportError = class extends Error {
|
|
51516
|
-
constructor(code, message) {
|
|
52753
|
+
constructor(code, message, details) {
|
|
51517
52754
|
super(message);
|
|
51518
52755
|
this.code = code;
|
|
52756
|
+
this.details = details;
|
|
51519
52757
|
this.name = "NotesExportError";
|
|
51520
52758
|
}
|
|
51521
52759
|
code;
|
|
52760
|
+
details;
|
|
51522
52761
|
};
|
|
52762
|
+
var MAX_EXPORT_WARNINGS = 200;
|
|
52763
|
+
var MAX_LISTED_ASSETS = 1e3;
|
|
52764
|
+
function chooseTemplate(request, deps) {
|
|
52765
|
+
if (request.template !== void 0 && request.templateFile !== void 0)
|
|
52766
|
+
throw new NotesExportError(
|
|
52767
|
+
"invalid-request",
|
|
52768
|
+
"Provide at most one of 'template' or 'templateFile'."
|
|
52769
|
+
);
|
|
52770
|
+
const invalid2 = (error2, where) => new NotesExportError("invalid-template", `${where}: ${error2.message}`, error2.errors);
|
|
52771
|
+
if (request.template !== void 0) {
|
|
52772
|
+
const name2 = request.template;
|
|
52773
|
+
if (isBuiltinTemplate(name2))
|
|
52774
|
+
return {
|
|
52775
|
+
info: { name: name2, source: "builtin" },
|
|
52776
|
+
template: resolveTemplate(builtinTemplate(name2), name2)
|
|
52777
|
+
};
|
|
52778
|
+
let portable2;
|
|
52779
|
+
try {
|
|
52780
|
+
portable2 = deps.findTemplate?.(name2);
|
|
52781
|
+
} catch (error2) {
|
|
52782
|
+
if (error2 instanceof TemplateValidationError)
|
|
52783
|
+
throw invalid2(error2, `Saved template "${name2}"`);
|
|
52784
|
+
throw error2;
|
|
52785
|
+
}
|
|
52786
|
+
if (!portable2) throw new NotesExportError("template-not-found", `No template named "${name2}".`);
|
|
52787
|
+
return { info: { name: name2, source: "saved" }, template: resolveTemplate(portable2, name2) };
|
|
52788
|
+
}
|
|
52789
|
+
if (request.templateFile === void 0) return void 0;
|
|
52790
|
+
let text2;
|
|
52791
|
+
try {
|
|
52792
|
+
text2 = readTemplateFile(request.templateFile);
|
|
52793
|
+
} catch (error2) {
|
|
52794
|
+
throw new NotesExportError(
|
|
52795
|
+
"invalid-path",
|
|
52796
|
+
`templateFile: ${error2 instanceof Error ? error2.message : String(error2)}`
|
|
52797
|
+
);
|
|
52798
|
+
}
|
|
52799
|
+
let portable;
|
|
52800
|
+
try {
|
|
52801
|
+
portable = parseTemplate(text2);
|
|
52802
|
+
} catch (error2) {
|
|
52803
|
+
throw invalid2(error2, "templateFile");
|
|
52804
|
+
}
|
|
52805
|
+
const name = portable.name ?? basename4(request.templateFile, extname5(request.templateFile));
|
|
52806
|
+
return { info: { name, source: "file" }, template: resolveTemplate(portable, name) };
|
|
52807
|
+
}
|
|
51523
52808
|
function validPath(path10, what) {
|
|
51524
52809
|
try {
|
|
51525
52810
|
return assertExportPath(path10);
|
|
@@ -51559,7 +52844,7 @@ function loadNotes(ids, single, read) {
|
|
|
51559
52844
|
return { notes, skipped };
|
|
51560
52845
|
}
|
|
51561
52846
|
function openOutput(output) {
|
|
51562
|
-
|
|
52847
|
+
mkdirSync6(dirname6(output), { recursive: true });
|
|
51563
52848
|
try {
|
|
51564
52849
|
return openCreateOnly(output);
|
|
51565
52850
|
} catch (error2) {
|
|
@@ -51581,8 +52866,16 @@ function exportNotesMarkdown(request, deps) {
|
|
|
51581
52866
|
const assetsDir = request.assetsDir ? validPath(request.assetsDir, "assetsDir") : void 0;
|
|
51582
52867
|
if (output && assetsDir && output === assetsDir)
|
|
51583
52868
|
throw new NotesExportError("invalid-path", "outputPath and assetsDir must differ.");
|
|
52869
|
+
const chosen = chooseTemplate(request, deps);
|
|
52870
|
+
if (chosen && assetsDir && chosen.template.assets.mode !== "copy")
|
|
52871
|
+
throw new NotesExportError(
|
|
52872
|
+
"invalid-request",
|
|
52873
|
+
`assetsDir has no effect: template "${chosen.info.name}" sets assets.mode to "${chosen.template.assets.mode}".`
|
|
52874
|
+
);
|
|
51584
52875
|
const ids = selectNotes(request, deps);
|
|
51585
52876
|
const { notes, skipped } = loadNotes(ids, !!request.id, deps.readNote);
|
|
52877
|
+
if (chosen)
|
|
52878
|
+
return exportWithTemplate(request, deps, chosen, notes, skipped, { output, assetsDir });
|
|
51586
52879
|
const fd = output ? openOutput(output) : void 0;
|
|
51587
52880
|
const writer = assetsDir ? new SidecarWriter(assetsDir, output ? dirname6(output) : void 0) : void 0;
|
|
51588
52881
|
const ctx = {
|
|
@@ -51614,7 +52907,7 @@ function exportNotesMarkdown(request, deps) {
|
|
|
51614
52907
|
return { ...receipt, markdown };
|
|
51615
52908
|
}
|
|
51616
52909
|
function defaultSidecarDir(output) {
|
|
51617
|
-
return
|
|
52910
|
+
return join22(dirname6(output), `${basename4(output, extname5(output))}.assets`);
|
|
51618
52911
|
}
|
|
51619
52912
|
function exportNotesHtml(request, deps) {
|
|
51620
52913
|
if (!request.outputPath)
|
|
@@ -51654,21 +52947,127 @@ function exportNotesHtml(request, deps) {
|
|
|
51654
52947
|
...assetsDir ? { assets: { dir: assetsDir, files: writer.count } } : { embedded: writer.count }
|
|
51655
52948
|
};
|
|
51656
52949
|
}
|
|
52950
|
+
function readMetaSafely(read, id2) {
|
|
52951
|
+
try {
|
|
52952
|
+
return read(id2);
|
|
52953
|
+
} catch {
|
|
52954
|
+
return {};
|
|
52955
|
+
}
|
|
52956
|
+
}
|
|
52957
|
+
function pathValues(note, meta, exportStem) {
|
|
52958
|
+
const values = { title: note.title.trim(), id: note.id, exportStem };
|
|
52959
|
+
for (const [key, value] of Object.entries(meta)) if (value) values[key] = value;
|
|
52960
|
+
return values;
|
|
52961
|
+
}
|
|
52962
|
+
function assetBindings(template, notes, meta, { output, assetsDir, exportStem }) {
|
|
52963
|
+
const linkBase = template.assets.pathStyle === "relative" && output ? dirname6(output) : void 0;
|
|
52964
|
+
const writers = /* @__PURE__ */ new Map();
|
|
52965
|
+
const writerFor = (dir) => {
|
|
52966
|
+
let writer = writers.get(dir);
|
|
52967
|
+
if (!writer) writers.set(dir, writer = new HashedSidecarWriter(dir, linkBase));
|
|
52968
|
+
return writer;
|
|
52969
|
+
};
|
|
52970
|
+
const reference = template.assets.mode === "reference" ? new ReferenceWriter(linkBase) : void 0;
|
|
52971
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
52972
|
+
for (const note of notes) {
|
|
52973
|
+
let binding = {};
|
|
52974
|
+
if (reference) binding = { writer: reference };
|
|
52975
|
+
else if (template.assets.mode === "copy") {
|
|
52976
|
+
if (assetsDir) binding = { writer: writerFor(assetsDir) };
|
|
52977
|
+
else if (template.assets.directory !== null && output) {
|
|
52978
|
+
let dir;
|
|
52979
|
+
try {
|
|
52980
|
+
dir = templateAssetsDir(
|
|
52981
|
+
template.assets.directory,
|
|
52982
|
+
dirname6(output),
|
|
52983
|
+
pathValues(note, meta.get(note) ?? {}, exportStem)
|
|
52984
|
+
);
|
|
52985
|
+
} catch (error2) {
|
|
52986
|
+
throw new NotesExportError("invalid-path", error2.message);
|
|
52987
|
+
}
|
|
52988
|
+
dir = validPath(dir, "assets.directory");
|
|
52989
|
+
if (dir === output)
|
|
52990
|
+
throw new NotesExportError("invalid-path", "assets.directory resolves to outputPath.");
|
|
52991
|
+
binding = { writer: writerFor(dir) };
|
|
52992
|
+
} else if (template.assets.directory !== null) binding = { required: true };
|
|
52993
|
+
}
|
|
52994
|
+
bindings.set(note, binding);
|
|
52995
|
+
}
|
|
52996
|
+
return { bindings, writers };
|
|
52997
|
+
}
|
|
52998
|
+
function exportWithTemplate(request, deps, chosen, notes, skipped, { output, assetsDir }) {
|
|
52999
|
+
const { template } = chosen;
|
|
53000
|
+
const readMeta = deps.readMeta ?? ((id2) => readExportNoteMeta(id2));
|
|
53001
|
+
const needsMeta = usesNoteMeta(template);
|
|
53002
|
+
const meta = new Map(
|
|
53003
|
+
notes.map((note) => [note, needsMeta ? readMetaSafely(readMeta, note.id) : {}])
|
|
53004
|
+
);
|
|
53005
|
+
const exportStem = output ? basename4(output, extname5(output)) : "export";
|
|
53006
|
+
const { bindings, writers } = assetBindings(template, notes, meta, {
|
|
53007
|
+
output,
|
|
53008
|
+
assetsDir,
|
|
53009
|
+
exportStem
|
|
53010
|
+
});
|
|
53011
|
+
const fd = output ? openOutput(output) : void 0;
|
|
53012
|
+
const ctx = { stats: emptyStats(), locator: deps.locator ?? new AssetLocator() };
|
|
53013
|
+
let warnings = [];
|
|
53014
|
+
const markdown = renderInto(fd, () => {
|
|
53015
|
+
const result = renderNotesWithTemplate(notes, ctx, {
|
|
53016
|
+
template,
|
|
53017
|
+
exportStem,
|
|
53018
|
+
wrap: request.wrap ?? 0,
|
|
53019
|
+
assetsFor: (note) => bindings.get(note) ?? {},
|
|
53020
|
+
metaFor: (note) => meta.get(note) ?? {}
|
|
53021
|
+
});
|
|
53022
|
+
warnings = result.warnings;
|
|
53023
|
+
return result.markdown;
|
|
53024
|
+
});
|
|
53025
|
+
const bytes = Buffer.byteLength(markdown);
|
|
53026
|
+
const used = [...writers.values()].filter((writer) => writer.count > 0);
|
|
53027
|
+
const files = used.flatMap((writer) => writer.files);
|
|
53028
|
+
const receipt = {
|
|
53029
|
+
format: "markdown",
|
|
53030
|
+
count: notes.length,
|
|
53031
|
+
bytes,
|
|
53032
|
+
stats: ctx.stats,
|
|
53033
|
+
skipped,
|
|
53034
|
+
template: chosen.info,
|
|
53035
|
+
warnings: warnings.slice(0, MAX_EXPORT_WARNINGS),
|
|
53036
|
+
...warnings.length > MAX_EXPORT_WARNINGS ? { warningsOmitted: warnings.length - MAX_EXPORT_WARNINGS } : {},
|
|
53037
|
+
...used.length ? {
|
|
53038
|
+
assets: {
|
|
53039
|
+
dir: used.length === 1 ? used[0].dir : dirname6(output),
|
|
53040
|
+
files: files.length
|
|
53041
|
+
},
|
|
53042
|
+
assetFiles: files.slice(0, MAX_LISTED_ASSETS)
|
|
53043
|
+
} : {}
|
|
53044
|
+
};
|
|
53045
|
+
if (fd !== void 0) {
|
|
53046
|
+
writeAllAndClose(fd, markdown);
|
|
53047
|
+
return { ...receipt, output };
|
|
53048
|
+
}
|
|
53049
|
+
if (bytes > deps.maxInlineBytes)
|
|
53050
|
+
throw new NotesExportError(
|
|
53051
|
+
"too-large",
|
|
53052
|
+
`The Markdown is ${bytes} bytes, over the ${deps.maxInlineBytes}-byte inline limit. Pass outputPath to write it to a file, or export fewer notes.`
|
|
53053
|
+
);
|
|
53054
|
+
return { ...receipt, markdown };
|
|
53055
|
+
}
|
|
51657
53056
|
|
|
51658
53057
|
// src/tools/directOperations.ts
|
|
51659
|
-
import { createHash as
|
|
53058
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
51660
53059
|
import {
|
|
51661
|
-
closeSync as
|
|
51662
|
-
constants as
|
|
51663
|
-
fstatSync as
|
|
53060
|
+
closeSync as closeSync6,
|
|
53061
|
+
constants as constants6,
|
|
53062
|
+
fstatSync as fstatSync6,
|
|
51664
53063
|
mkdtempSync as mkdtempSync5,
|
|
51665
|
-
openSync as
|
|
53064
|
+
openSync as openSync6,
|
|
51666
53065
|
readFileSync as readFileSync3,
|
|
51667
53066
|
rmSync as rmSync5,
|
|
51668
53067
|
writeFileSync as writeFileSync4
|
|
51669
53068
|
} from "node:fs";
|
|
51670
53069
|
import { tmpdir as tmpdir5 } from "node:os";
|
|
51671
|
-
import { basename as basename5, extname as
|
|
53070
|
+
import { basename as basename5, extname as extname6, isAbsolute as isAbsolute4, join as join23 } from "node:path";
|
|
51672
53071
|
var noteId = exactIdInput(
|
|
51673
53072
|
"ICNote",
|
|
51674
53073
|
/^x-coredata:\/\/[0-9a-f-]+\/ICNote\/p\d+$/i,
|
|
@@ -51712,10 +53111,10 @@ function assertExistingContentPreserved(before, after) {
|
|
|
51712
53111
|
}
|
|
51713
53112
|
}
|
|
51714
53113
|
function localAttachment(path10) {
|
|
51715
|
-
if (!
|
|
51716
|
-
const descriptor =
|
|
53114
|
+
if (!isAbsolute4(path10)) throw new Error("An absolute local file path is required");
|
|
53115
|
+
const descriptor = openSync6(path10, constants6.O_RDONLY | constants6.O_NOFOLLOW);
|
|
51717
53116
|
try {
|
|
51718
|
-
const stat =
|
|
53117
|
+
const stat = fstatSync6(descriptor);
|
|
51719
53118
|
if (!stat.isFile() || stat.size === 0 || stat.size > 64 * 1024 * 1024)
|
|
51720
53119
|
throw new Error("Attachment must be a nonempty regular file of at most 64 MiB");
|
|
51721
53120
|
const bytes = readFileSync3(descriptor);
|
|
@@ -51723,7 +53122,7 @@ function localAttachment(path10) {
|
|
|
51723
53122
|
throw new Error("Attachment changed while it was being read; try again");
|
|
51724
53123
|
return bytes;
|
|
51725
53124
|
} finally {
|
|
51726
|
-
|
|
53125
|
+
closeSync6(descriptor);
|
|
51727
53126
|
}
|
|
51728
53127
|
}
|
|
51729
53128
|
function registerDirectOperations(server2, manager) {
|
|
@@ -51846,15 +53245,15 @@ function attachmentName(path10, filename) {
|
|
|
51846
53245
|
throw new Error(
|
|
51847
53246
|
"filename must be one path component with no slash, colon, backslash, control character, leading dot, or surrounding spaces"
|
|
51848
53247
|
);
|
|
51849
|
-
if (
|
|
53248
|
+
if (extname6(filename).toLowerCase() !== extname6(source).toLowerCase())
|
|
51850
53249
|
throw new Error(
|
|
51851
|
-
`filename must keep the source file's extension (${
|
|
53250
|
+
`filename must keep the source file's extension (${extname6(source) || "none"})`
|
|
51852
53251
|
);
|
|
51853
53252
|
return filename;
|
|
51854
53253
|
}
|
|
51855
53254
|
var UNCERTAIN = "Attachment insertion outcome uncertain; read the exact note before retrying";
|
|
51856
53255
|
var pause = (ms) => Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
51857
|
-
var sha256 = (data) =>
|
|
53256
|
+
var sha256 = (data) => createHash3("sha256").update(data).digest("hex");
|
|
51858
53257
|
function storedAttachmentIds(manager, id2) {
|
|
51859
53258
|
try {
|
|
51860
53259
|
return new Set(
|
|
@@ -51887,13 +53286,13 @@ function storedInsertion(manager, id2, before, bytes, returnedId) {
|
|
|
51887
53286
|
const matches = row.assetPaths.some((path10) => {
|
|
51888
53287
|
let descriptor;
|
|
51889
53288
|
try {
|
|
51890
|
-
descriptor =
|
|
51891
|
-
const stat =
|
|
53289
|
+
descriptor = openSync6(path10, constants6.O_RDONLY | constants6.O_NOFOLLOW);
|
|
53290
|
+
const stat = fstatSync6(descriptor);
|
|
51892
53291
|
return stat.isFile() && stat.size === bytes.length && sha256(readFileSync3(descriptor)) === expected;
|
|
51893
53292
|
} catch {
|
|
51894
53293
|
return false;
|
|
51895
53294
|
} finally {
|
|
51896
|
-
if (descriptor !== void 0)
|
|
53295
|
+
if (descriptor !== void 0) closeSync6(descriptor);
|
|
51897
53296
|
}
|
|
51898
53297
|
});
|
|
51899
53298
|
if (!matches)
|
|
@@ -51910,8 +53309,8 @@ function attachFile(manager, args) {
|
|
|
51910
53309
|
const bytes = localAttachment(path10);
|
|
51911
53310
|
const beforeAttachments = manager.listAttachmentsById(id2);
|
|
51912
53311
|
const beforeStored = storedAttachmentIds(manager, id2);
|
|
51913
|
-
const directory = mkdtempSync5(
|
|
51914
|
-
const temporaryFile =
|
|
53312
|
+
const directory = mkdtempSync5(join23(tmpdir5(), "notes-attachment-add-"));
|
|
53313
|
+
const temporaryFile = join23(directory, name);
|
|
51915
53314
|
try {
|
|
51916
53315
|
writeFileSync4(temporaryFile, bytes, { mode: 384 });
|
|
51917
53316
|
if (readSnapshot(manager, id2).hash !== before.hash) throw new Error("Note revision changed");
|
|
@@ -51978,7 +53377,7 @@ function attachFile(manager, args) {
|
|
|
51978
53377
|
}
|
|
51979
53378
|
|
|
51980
53379
|
// src/tools/folderDelete.ts
|
|
51981
|
-
import { createHash as
|
|
53380
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
51982
53381
|
|
|
51983
53382
|
// src/utils/folderStore.ts
|
|
51984
53383
|
import { execFileSync as execFileSync19 } from "child_process";
|
|
@@ -52165,7 +53564,7 @@ function folderDeleteRevision(app, store) {
|
|
|
52165
53564
|
store.childFolderCount,
|
|
52166
53565
|
store.noteCount
|
|
52167
53566
|
];
|
|
52168
|
-
return `sha256:${
|
|
53567
|
+
return `sha256:${createHash4("sha256").update(JSON.stringify(state)).digest("hex")}`;
|
|
52169
53568
|
}
|
|
52170
53569
|
function checkFolder(manager, args, deps) {
|
|
52171
53570
|
const app = manager.readFolderForDelete(args.id);
|
|
@@ -52300,9 +53699,426 @@ function registerFolderDelete(server2, manager, deps = defaultDeps) {
|
|
|
52300
53699
|
);
|
|
52301
53700
|
}
|
|
52302
53701
|
|
|
53702
|
+
// src/services/templateStore.ts
|
|
53703
|
+
import { randomBytes } from "node:crypto";
|
|
53704
|
+
import {
|
|
53705
|
+
closeSync as closeSync7,
|
|
53706
|
+
constants as constants7,
|
|
53707
|
+
fstatSync as fstatSync7,
|
|
53708
|
+
linkSync,
|
|
53709
|
+
lstatSync as lstatSync5,
|
|
53710
|
+
mkdirSync as mkdirSync7,
|
|
53711
|
+
openSync as openSync7,
|
|
53712
|
+
readdirSync as readdirSync4,
|
|
53713
|
+
readSync as readSync5,
|
|
53714
|
+
renameSync,
|
|
53715
|
+
unlinkSync as unlinkSync3,
|
|
53716
|
+
writeSync as writeSync5
|
|
53717
|
+
} from "node:fs";
|
|
53718
|
+
import { homedir as homedir19 } from "node:os";
|
|
53719
|
+
import { isAbsolute as isAbsolute5, join as join25, resolve as resolve5 } from "node:path";
|
|
53720
|
+
var TEMPLATE_SLUG = /^[a-z0-9][a-z0-9_-]{0,63}$/;
|
|
53721
|
+
var TemplateStoreError = class extends Error {
|
|
53722
|
+
constructor(code, message) {
|
|
53723
|
+
super(message);
|
|
53724
|
+
this.code = code;
|
|
53725
|
+
this.name = "TemplateStoreError";
|
|
53726
|
+
}
|
|
53727
|
+
code;
|
|
53728
|
+
};
|
|
53729
|
+
function templateDir(env = process.env) {
|
|
53730
|
+
const override = env.APPLE_NOTES_MCP_TEMPLATE_DIR?.trim();
|
|
53731
|
+
if (override) {
|
|
53732
|
+
if (!isAbsolute5(override))
|
|
53733
|
+
throw new TemplateStoreError(
|
|
53734
|
+
"unsafe-path",
|
|
53735
|
+
"APPLE_NOTES_MCP_TEMPLATE_DIR must be an absolute path."
|
|
53736
|
+
);
|
|
53737
|
+
return resolve5(override);
|
|
53738
|
+
}
|
|
53739
|
+
return join25(homedir19(), "Library/Application Support/apple-notes-mcp/templates");
|
|
53740
|
+
}
|
|
53741
|
+
function checkName(name, action) {
|
|
53742
|
+
if (isBuiltinTemplate(name) && action !== "read")
|
|
53743
|
+
throw new TemplateStoreError(
|
|
53744
|
+
"reserved-name",
|
|
53745
|
+
`"${name}" is a built-in template and cannot be ${action === "save" ? "saved over" : "deleted"}.`
|
|
53746
|
+
);
|
|
53747
|
+
if (!TEMPLATE_SLUG.test(name))
|
|
53748
|
+
throw new TemplateStoreError(
|
|
53749
|
+
"invalid-name",
|
|
53750
|
+
`Template names are 1-64 characters of a-z, 0-9, "-" and "_", starting with a letter or digit; got "${name}".`
|
|
53751
|
+
);
|
|
53752
|
+
}
|
|
53753
|
+
var TemplateStore = class {
|
|
53754
|
+
constructor(dir = templateDir()) {
|
|
53755
|
+
this.dir = dir;
|
|
53756
|
+
}
|
|
53757
|
+
dir;
|
|
53758
|
+
/** The library root, which must be a real directory (not a symlink) when it exists. */
|
|
53759
|
+
root(create) {
|
|
53760
|
+
let stat;
|
|
53761
|
+
try {
|
|
53762
|
+
stat = lstatSync5(this.dir);
|
|
53763
|
+
} catch {
|
|
53764
|
+
if (!create) return void 0;
|
|
53765
|
+
mkdirSync7(this.dir, { recursive: true, mode: 448 });
|
|
53766
|
+
stat = lstatSync5(this.dir);
|
|
53767
|
+
}
|
|
53768
|
+
if (!stat.isDirectory())
|
|
53769
|
+
throw new TemplateStoreError(
|
|
53770
|
+
"unsafe-path",
|
|
53771
|
+
`The template library ${this.dir} is not a directory (symlinks are refused).`
|
|
53772
|
+
);
|
|
53773
|
+
return this.dir;
|
|
53774
|
+
}
|
|
53775
|
+
file(name) {
|
|
53776
|
+
return join25(this.dir, `${name}.json`);
|
|
53777
|
+
}
|
|
53778
|
+
/** Read a saved template's text, refusing symlinks and non-regular files. */
|
|
53779
|
+
readText(path10) {
|
|
53780
|
+
let fd;
|
|
53781
|
+
try {
|
|
53782
|
+
fd = openSync7(path10, constants7.O_RDONLY | constants7.O_NOFOLLOW);
|
|
53783
|
+
} catch (error2) {
|
|
53784
|
+
if (error2.code === "ENOENT") return void 0;
|
|
53785
|
+
throw new TemplateStoreError("unsafe-path", `Refusing to read ${path10}: not a regular file.`);
|
|
53786
|
+
}
|
|
53787
|
+
try {
|
|
53788
|
+
const stat = fstatSync7(fd);
|
|
53789
|
+
if (!stat.isFile())
|
|
53790
|
+
throw new TemplateStoreError(
|
|
53791
|
+
"unsafe-path",
|
|
53792
|
+
`Refusing to read ${path10}: not a regular file.`
|
|
53793
|
+
);
|
|
53794
|
+
if (stat.size > MAX_TEMPLATE_BYTES)
|
|
53795
|
+
throw new TemplateValidationError([
|
|
53796
|
+
{
|
|
53797
|
+
path: "$",
|
|
53798
|
+
message: `template is ${stat.size} bytes; the limit is ${MAX_TEMPLATE_BYTES}`
|
|
53799
|
+
}
|
|
53800
|
+
]);
|
|
53801
|
+
const data = Buffer.alloc(stat.size);
|
|
53802
|
+
let read = 0;
|
|
53803
|
+
while (read < stat.size) {
|
|
53804
|
+
const n = readSync5(fd, data, read, stat.size - read, read);
|
|
53805
|
+
if (n <= 0) break;
|
|
53806
|
+
read += n;
|
|
53807
|
+
}
|
|
53808
|
+
return { text: data.subarray(0, read).toString("utf8"), bytes: read, mtime: stat.mtime };
|
|
53809
|
+
} finally {
|
|
53810
|
+
closeSync7(fd);
|
|
53811
|
+
}
|
|
53812
|
+
}
|
|
53813
|
+
/** Saved templates in name order; `skipped` counts entries that are not usable. */
|
|
53814
|
+
list() {
|
|
53815
|
+
const templates = [];
|
|
53816
|
+
let skipped = 0;
|
|
53817
|
+
if (!this.root(false)) return { templates, skipped, dir: this.dir };
|
|
53818
|
+
for (const entry of readdirSync4(this.dir).sort()) {
|
|
53819
|
+
if (!entry.endsWith(".json") || entry.startsWith(".")) continue;
|
|
53820
|
+
const name = entry.slice(0, -5);
|
|
53821
|
+
if (!TEMPLATE_SLUG.test(name) || isBuiltinTemplate(name)) {
|
|
53822
|
+
skipped++;
|
|
53823
|
+
continue;
|
|
53824
|
+
}
|
|
53825
|
+
try {
|
|
53826
|
+
const read = this.readText(this.file(name));
|
|
53827
|
+
if (!read) continue;
|
|
53828
|
+
const template = parseTemplate(read.text);
|
|
53829
|
+
templates.push({
|
|
53830
|
+
name,
|
|
53831
|
+
...template.name && template.name !== name ? { displayName: template.name } : {},
|
|
53832
|
+
...template.description ? { description: template.description } : {},
|
|
53833
|
+
...template.extends ? { extends: template.extends } : {},
|
|
53834
|
+
bytes: read.bytes,
|
|
53835
|
+
modified: read.mtime.toISOString()
|
|
53836
|
+
});
|
|
53837
|
+
} catch {
|
|
53838
|
+
skipped++;
|
|
53839
|
+
}
|
|
53840
|
+
}
|
|
53841
|
+
return { templates, skipped, dir: this.dir };
|
|
53842
|
+
}
|
|
53843
|
+
/**
|
|
53844
|
+
* A saved template in its portable (as stored) form, or undefined when
|
|
53845
|
+
* there is none. Throws {@link TemplateValidationError} for a corrupt file.
|
|
53846
|
+
*/
|
|
53847
|
+
find(name) {
|
|
53848
|
+
checkName(name, "read");
|
|
53849
|
+
if (!this.root(false)) return void 0;
|
|
53850
|
+
const read = this.readText(this.file(name));
|
|
53851
|
+
return read ? parseTemplate(read.text) : void 0;
|
|
53852
|
+
}
|
|
53853
|
+
/** Like {@link find}, but a missing template is an error. */
|
|
53854
|
+
get(name) {
|
|
53855
|
+
const template = this.find(name);
|
|
53856
|
+
if (!template)
|
|
53857
|
+
throw new TemplateStoreError(
|
|
53858
|
+
"template-not-found",
|
|
53859
|
+
`No saved template named "${name}". Built-in templates: ${BUILTIN_TEMPLATE_NAMES.join(", ")}.`
|
|
53860
|
+
);
|
|
53861
|
+
return template;
|
|
53862
|
+
}
|
|
53863
|
+
/**
|
|
53864
|
+
* Validate and save a template under `name`. Create-only unless `force`.
|
|
53865
|
+
* Returns the file path and whether an existing template was replaced.
|
|
53866
|
+
*/
|
|
53867
|
+
save(name, text2, { force = false } = {}) {
|
|
53868
|
+
checkName(name, "save");
|
|
53869
|
+
const template = parseTemplate(text2);
|
|
53870
|
+
const body = JSON.stringify(template, null, 2) + "\n";
|
|
53871
|
+
this.root(true);
|
|
53872
|
+
const path10 = this.file(name);
|
|
53873
|
+
let exists = false;
|
|
53874
|
+
try {
|
|
53875
|
+
const stat = lstatSync5(path10);
|
|
53876
|
+
if (!stat.isFile())
|
|
53877
|
+
throw new TemplateStoreError(
|
|
53878
|
+
"unsafe-path",
|
|
53879
|
+
`Refusing to replace ${path10}: it is not a regular file.`
|
|
53880
|
+
);
|
|
53881
|
+
exists = true;
|
|
53882
|
+
} catch (error2) {
|
|
53883
|
+
if (error2 instanceof TemplateStoreError) throw error2;
|
|
53884
|
+
}
|
|
53885
|
+
if (exists && !force)
|
|
53886
|
+
throw new TemplateStoreError(
|
|
53887
|
+
"template-exists",
|
|
53888
|
+
`A template named "${name}" already exists. Pass force: true to replace it.`
|
|
53889
|
+
);
|
|
53890
|
+
const temp = join25(this.dir, `.${name}.${randomBytes(6).toString("hex")}.tmp`);
|
|
53891
|
+
const fd = openSync7(
|
|
53892
|
+
temp,
|
|
53893
|
+
constants7.O_WRONLY | constants7.O_CREAT | constants7.O_EXCL | constants7.O_NOFOLLOW,
|
|
53894
|
+
384
|
|
53895
|
+
);
|
|
53896
|
+
try {
|
|
53897
|
+
const data = Buffer.from(body, "utf8");
|
|
53898
|
+
let written = 0;
|
|
53899
|
+
while (written < data.length) written += writeSync5(fd, data, written);
|
|
53900
|
+
} finally {
|
|
53901
|
+
closeSync7(fd);
|
|
53902
|
+
}
|
|
53903
|
+
try {
|
|
53904
|
+
if (force) renameSync(temp, path10);
|
|
53905
|
+
else {
|
|
53906
|
+
try {
|
|
53907
|
+
linkSync(temp, path10);
|
|
53908
|
+
} catch (error2) {
|
|
53909
|
+
if (error2.code === "EEXIST")
|
|
53910
|
+
throw new TemplateStoreError(
|
|
53911
|
+
"template-exists",
|
|
53912
|
+
`A template named "${name}" already exists. Pass force: true to replace it.`
|
|
53913
|
+
);
|
|
53914
|
+
throw error2;
|
|
53915
|
+
}
|
|
53916
|
+
}
|
|
53917
|
+
} finally {
|
|
53918
|
+
try {
|
|
53919
|
+
unlinkSync3(temp);
|
|
53920
|
+
} catch {
|
|
53921
|
+
}
|
|
53922
|
+
}
|
|
53923
|
+
return { path: path10, replaced: exists, bytes: Buffer.byteLength(body), template };
|
|
53924
|
+
}
|
|
53925
|
+
/** Delete a saved template. Built-ins cannot be deleted. */
|
|
53926
|
+
delete(name) {
|
|
53927
|
+
checkName(name, "delete");
|
|
53928
|
+
const path10 = this.file(name);
|
|
53929
|
+
let stat;
|
|
53930
|
+
try {
|
|
53931
|
+
if (!this.root(false)) throw new Error("absent");
|
|
53932
|
+
stat = lstatSync5(path10);
|
|
53933
|
+
} catch (error2) {
|
|
53934
|
+
if (error2 instanceof TemplateStoreError) throw error2;
|
|
53935
|
+
throw new TemplateStoreError("template-not-found", `No saved template named "${name}".`);
|
|
53936
|
+
}
|
|
53937
|
+
if (!stat.isFile())
|
|
53938
|
+
throw new TemplateStoreError(
|
|
53939
|
+
"unsafe-path",
|
|
53940
|
+
`Refusing to delete ${path10}: not a regular file.`
|
|
53941
|
+
);
|
|
53942
|
+
unlinkSync3(path10);
|
|
53943
|
+
return { path: path10 };
|
|
53944
|
+
}
|
|
53945
|
+
};
|
|
53946
|
+
|
|
53947
|
+
// src/tools/markdownTemplates.ts
|
|
53948
|
+
var ok = (text2, structured) => ({
|
|
53949
|
+
content: [{ type: "text", text: text2 }],
|
|
53950
|
+
structuredContent: structured
|
|
53951
|
+
});
|
|
53952
|
+
function failure(action, error2) {
|
|
53953
|
+
if (error2 instanceof TemplateValidationError)
|
|
53954
|
+
return errorResult(
|
|
53955
|
+
`Error ${action} [invalid-template]: the template is invalid:
|
|
53956
|
+
` + error2.errors.map((e) => `${e.path}: ${e.message}`).join("\n"),
|
|
53957
|
+
error2
|
|
53958
|
+
);
|
|
53959
|
+
if (error2 instanceof TemplateStoreError)
|
|
53960
|
+
return errorResult(`Error ${action} [${error2.code}]: ${error2.message}`, error2);
|
|
53961
|
+
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
53962
|
+
return errorResult(`Error ${action}: ${message}`, error2);
|
|
53963
|
+
}
|
|
53964
|
+
var nameInput = external_exports.string().min(1).max(64).describe("Template name: a built-in (standard-markdown, obsidian) or a saved template's name");
|
|
53965
|
+
var templateInput = external_exports.union([external_exports.record(external_exports.unknown()), external_exports.string().max(MAX_TEMPLATE_BYTES)]).optional().describe("The template itself, as a JSON object or JSON text (schemaVersion 1)");
|
|
53966
|
+
var templateFileInput = external_exports.string().min(1).max(4096).optional().describe(
|
|
53967
|
+
"Absolute path of a JSON template file ending in .json (home, a temp dir, or /Volumes; symlinks refused; at most 256 KiB)"
|
|
53968
|
+
);
|
|
53969
|
+
function sourceText(args) {
|
|
53970
|
+
if (args.template === void 0 === (args.templateFile === void 0))
|
|
53971
|
+
throw new Error("Provide exactly one of 'template' or 'templateFile'.");
|
|
53972
|
+
if (args.templateFile !== void 0) return readTemplateFile(args.templateFile);
|
|
53973
|
+
return typeof args.template === "string" ? args.template : JSON.stringify(args.template);
|
|
53974
|
+
}
|
|
53975
|
+
function registerMarkdownTemplates(server2, store = () => new TemplateStore()) {
|
|
53976
|
+
const loose = external_exports.object({}).passthrough();
|
|
53977
|
+
server2.registerTool(
|
|
53978
|
+
"list-markdown-templates",
|
|
53979
|
+
{
|
|
53980
|
+
description: "Use when: choosing a Markdown export template, or checking which saved templates exist.\nReturns: the built-in templates, the saved templates (name, display name, description, size, modified date), the library directory, and how many unusable files were skipped.\nDo not use when: you need a template's rules (show-markdown-template).\nSafety: read-only; never opens Notes.",
|
|
53981
|
+
inputSchema: {},
|
|
53982
|
+
outputSchema: loose,
|
|
53983
|
+
annotations: { readOnlyHint: true }
|
|
53984
|
+
},
|
|
53985
|
+
(async () => {
|
|
53986
|
+
try {
|
|
53987
|
+
const listing = store().list();
|
|
53988
|
+
const builtins = BUILTIN_TEMPLATE_NAMES.map((name) => ({
|
|
53989
|
+
name,
|
|
53990
|
+
description: builtinTemplate(name).description ?? ""
|
|
53991
|
+
}));
|
|
53992
|
+
return ok(
|
|
53993
|
+
`${builtins.length} built-in and ${listing.templates.length} saved template(s)` + (listing.skipped ? `; skipped ${listing.skipped} unusable file(s)` : "") + ".",
|
|
53994
|
+
{ builtins, ...listing }
|
|
53995
|
+
);
|
|
53996
|
+
} catch (error2) {
|
|
53997
|
+
return failure("listing templates", error2);
|
|
53998
|
+
}
|
|
53999
|
+
})
|
|
54000
|
+
);
|
|
54001
|
+
const showInput = {
|
|
54002
|
+
name: nameInput,
|
|
54003
|
+
expanded: external_exports.boolean().optional().describe("Also return the fully expanded template (every rule filled from its base)")
|
|
54004
|
+
};
|
|
54005
|
+
server2.registerTool(
|
|
54006
|
+
"show-markdown-template",
|
|
54007
|
+
{
|
|
54008
|
+
description: "Use when: reading a built-in or saved template, to copy it as the start of a new one or to see what an export will do.\nReturns: the template in its portable form (as saved, overrides only), its source, and with expanded: true every rule filled in.\nDo not use when: listing names (list-markdown-templates).\nSafety: read-only.",
|
|
54009
|
+
inputSchema: showInput,
|
|
54010
|
+
outputSchema: loose,
|
|
54011
|
+
annotations: { readOnlyHint: true }
|
|
54012
|
+
},
|
|
54013
|
+
(async ({ name, expanded }) => {
|
|
54014
|
+
try {
|
|
54015
|
+
const builtin = isBuiltinTemplate(name);
|
|
54016
|
+
const template = builtin ? builtinTemplate(name) : store().get(name);
|
|
54017
|
+
const structured = {
|
|
54018
|
+
name,
|
|
54019
|
+
source: builtin ? "builtin" : "saved",
|
|
54020
|
+
template,
|
|
54021
|
+
...expanded ? { expanded: resolveTemplate(template, name) } : {}
|
|
54022
|
+
};
|
|
54023
|
+
return ok(JSON.stringify(template, null, 2), structured);
|
|
54024
|
+
} catch (error2) {
|
|
54025
|
+
return failure("showing template", error2);
|
|
54026
|
+
}
|
|
54027
|
+
})
|
|
54028
|
+
);
|
|
54029
|
+
const validateInput = {
|
|
54030
|
+
name: nameInput.optional(),
|
|
54031
|
+
template: templateInput,
|
|
54032
|
+
templateFile: templateFileInput
|
|
54033
|
+
};
|
|
54034
|
+
server2.registerTool(
|
|
54035
|
+
"validate-markdown-template",
|
|
54036
|
+
{
|
|
54037
|
+
description: 'Use when: checking a template before saving it or exporting with it.\nReturns: valid true, or valid false with every problem as {path, message}, where path is a JSON path such as $.rules["inline.bold"].after.\nDo not use when: you want to store it (save-markdown-template validates too).\nSafety: read-only. Pass exactly one of name (a saved or built-in template), template (JSON object or text) or templateFile.',
|
|
54038
|
+
inputSchema: validateInput,
|
|
54039
|
+
outputSchema: loose,
|
|
54040
|
+
annotations: { readOnlyHint: true }
|
|
54041
|
+
},
|
|
54042
|
+
(async (args) => {
|
|
54043
|
+
try {
|
|
54044
|
+
const given = [args.name, args.template, args.templateFile].filter(
|
|
54045
|
+
(value) => value !== void 0
|
|
54046
|
+
).length;
|
|
54047
|
+
if (given !== 1)
|
|
54048
|
+
throw new Error("Provide exactly one of 'name', 'template' or 'templateFile'.");
|
|
54049
|
+
try {
|
|
54050
|
+
if (args.name !== void 0) {
|
|
54051
|
+
if (!isBuiltinTemplate(args.name)) store().get(args.name);
|
|
54052
|
+
} else parseTemplate(sourceText(args));
|
|
54053
|
+
} catch (error2) {
|
|
54054
|
+
if (!(error2 instanceof TemplateValidationError)) throw error2;
|
|
54055
|
+
return ok(
|
|
54056
|
+
`Invalid template (${error2.errors.length} problem(s)):
|
|
54057
|
+
` + error2.errors.map((e) => `${e.path}: ${e.message}`).join("\n"),
|
|
54058
|
+
{ valid: false, errors: error2.errors }
|
|
54059
|
+
);
|
|
54060
|
+
}
|
|
54061
|
+
return ok("The template is valid.", { valid: true, errors: [] });
|
|
54062
|
+
} catch (error2) {
|
|
54063
|
+
return failure("validating template", error2);
|
|
54064
|
+
}
|
|
54065
|
+
})
|
|
54066
|
+
);
|
|
54067
|
+
const saveInput = {
|
|
54068
|
+
name: external_exports.string().min(1).max(64).describe(
|
|
54069
|
+
'Name to save under: lowercase a-z, 0-9, "-" and "_", starting with a letter or digit'
|
|
54070
|
+
),
|
|
54071
|
+
template: templateInput,
|
|
54072
|
+
templateFile: templateFileInput,
|
|
54073
|
+
force: external_exports.boolean().optional().describe("Replace an existing saved template of this name (default false: create-only)")
|
|
54074
|
+
};
|
|
54075
|
+
server2.registerTool(
|
|
54076
|
+
"save-markdown-template",
|
|
54077
|
+
{
|
|
54078
|
+
description: "Use when: storing a template so export-notes-markdown can use it by name.\nReturns: name, path, bytes and whether an existing template was replaced.\nDo not use when: exporting once (pass templateFile to export-notes-markdown instead).\nSafety: writes one file in the template library only (APPLE_NOTES_MCP_TEMPLATE_DIR, default ~/Library/Application Support/apple-notes-mcp/templates, mode 0600). Validates first; an invalid template is refused with every JSON path. Create-only: an existing name is refused with [template-exists] unless force is true. Built-in names are reserved.",
|
|
54079
|
+
inputSchema: saveInput,
|
|
54080
|
+
outputSchema: loose,
|
|
54081
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false }
|
|
54082
|
+
},
|
|
54083
|
+
(async (args) => {
|
|
54084
|
+
try {
|
|
54085
|
+
const saved = store().save(args.name, sourceText(args), { force: args.force });
|
|
54086
|
+
return ok(
|
|
54087
|
+
`${saved.replaced ? "Replaced" : "Saved"} template "${args.name}" (${saved.bytes} bytes) at ${saved.path}.`,
|
|
54088
|
+
{ name: args.name, path: saved.path, bytes: saved.bytes, replaced: saved.replaced }
|
|
54089
|
+
);
|
|
54090
|
+
} catch (error2) {
|
|
54091
|
+
return failure("saving template", error2);
|
|
54092
|
+
}
|
|
54093
|
+
})
|
|
54094
|
+
);
|
|
54095
|
+
const deleteInput = { name: external_exports.string().min(1).max(64).describe("Saved template to delete") };
|
|
54096
|
+
server2.registerTool(
|
|
54097
|
+
"delete-markdown-template",
|
|
54098
|
+
{
|
|
54099
|
+
description: "Use when: removing a saved Markdown template the user no longer wants.\nReturns: the name and the path of the removed file.\nDo not use when: the template is built in (standard-markdown, obsidian cannot be deleted).\nSafety: permanently removes one file from the template library; never touches Notes.",
|
|
54100
|
+
inputSchema: deleteInput,
|
|
54101
|
+
outputSchema: loose,
|
|
54102
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false }
|
|
54103
|
+
},
|
|
54104
|
+
(async ({ name }) => {
|
|
54105
|
+
try {
|
|
54106
|
+
const removed = store().delete(name);
|
|
54107
|
+
return ok(`Deleted template "${name}" (${removed.path}).`, {
|
|
54108
|
+
name,
|
|
54109
|
+
path: removed.path,
|
|
54110
|
+
deleted: true
|
|
54111
|
+
});
|
|
54112
|
+
} catch (error2) {
|
|
54113
|
+
return failure("deleting template", error2);
|
|
54114
|
+
}
|
|
54115
|
+
})
|
|
54116
|
+
);
|
|
54117
|
+
}
|
|
54118
|
+
|
|
52303
54119
|
// src/utils/svgAnalyzer.ts
|
|
52304
|
-
import { createHash as
|
|
52305
|
-
import { closeSync as
|
|
54120
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
54121
|
+
import { closeSync as closeSync8, constants as constants8, fstatSync as fstatSync8, openSync as openSync8, readSync as readSync6 } from "node:fs";
|
|
52306
54122
|
|
|
52307
54123
|
// src/utils/svgColor.ts
|
|
52308
54124
|
var NAMED = {
|
|
@@ -52976,10 +54792,10 @@ function clipPolyline(points, r) {
|
|
|
52976
54792
|
if (run.length) parts.push(run);
|
|
52977
54793
|
return { parts, clipped: true };
|
|
52978
54794
|
}
|
|
52979
|
-
function dashPolyline(points,
|
|
52980
|
-
const total =
|
|
54795
|
+
function dashPolyline(points, pattern2, offset, charge) {
|
|
54796
|
+
const total = pattern2.reduce((s, v) => s + v, 0);
|
|
52981
54797
|
let index = 0;
|
|
52982
|
-
let remaining =
|
|
54798
|
+
let remaining = pattern2[0];
|
|
52983
54799
|
let on = true;
|
|
52984
54800
|
let shift = (offset % total + total) % total;
|
|
52985
54801
|
while (shift > 0) {
|
|
@@ -52987,8 +54803,8 @@ function dashPolyline(points, pattern, offset, charge) {
|
|
|
52987
54803
|
remaining -= step;
|
|
52988
54804
|
shift -= step;
|
|
52989
54805
|
if (remaining <= 0) {
|
|
52990
|
-
index = (index + 1) %
|
|
52991
|
-
remaining =
|
|
54806
|
+
index = (index + 1) % pattern2.length;
|
|
54807
|
+
remaining = pattern2[index];
|
|
52992
54808
|
on = !on;
|
|
52993
54809
|
}
|
|
52994
54810
|
}
|
|
@@ -53010,8 +54826,8 @@ function dashPolyline(points, pattern, offset, charge) {
|
|
|
53010
54826
|
on = !on;
|
|
53011
54827
|
segLen -= remaining;
|
|
53012
54828
|
a = cut;
|
|
53013
|
-
index = (index + 1) %
|
|
53014
|
-
remaining =
|
|
54829
|
+
index = (index + 1) % pattern2.length;
|
|
54830
|
+
remaining = pattern2[index];
|
|
53015
54831
|
}
|
|
53016
54832
|
remaining -= segLen;
|
|
53017
54833
|
if (on && currentDash) currentDash.push(b);
|
|
@@ -53243,7 +55059,7 @@ function parseXml(source, limits) {
|
|
|
53243
55059
|
if (a.name === "xmlns") scope2.set("", a.value);
|
|
53244
55060
|
else if (a.name.startsWith("xmlns:")) scope2.set(a.name.slice(6), a.value);
|
|
53245
55061
|
}
|
|
53246
|
-
const
|
|
55062
|
+
const resolve9 = (qualified, isAttribute) => {
|
|
53247
55063
|
const colon = qualified.indexOf(":");
|
|
53248
55064
|
if (colon < 0) return { local: qualified, ns: isAttribute ? null : scope2.get("") ?? null };
|
|
53249
55065
|
const prefix = qualified.slice(0, colon);
|
|
@@ -53253,12 +55069,12 @@ function parseXml(source, limits) {
|
|
|
53253
55069
|
if (ns === void 0) fail(`Undeclared namespace prefix "${prefix.slice(0, 40)}"`);
|
|
53254
55070
|
return { local, ns };
|
|
53255
55071
|
};
|
|
53256
|
-
const resolved =
|
|
55072
|
+
const resolved = resolve9(name, false);
|
|
53257
55073
|
const element = {
|
|
53258
55074
|
name,
|
|
53259
55075
|
local: resolved.local,
|
|
53260
55076
|
ns: resolved.ns,
|
|
53261
|
-
attributes: rawAttributes.filter((a) => a.name !== "xmlns" && !a.name.startsWith("xmlns:")).map((a) => ({ name: a.name, value: a.value, ...
|
|
55077
|
+
attributes: rawAttributes.filter((a) => a.name !== "xmlns" && !a.name.startsWith("xmlns:")).map((a) => ({ name: a.name, value: a.value, ...resolve9(a.name, true) })),
|
|
53262
55078
|
children: [],
|
|
53263
55079
|
text: "",
|
|
53264
55080
|
line: tagLine
|
|
@@ -53384,7 +55200,7 @@ function canonicalJson(value) {
|
|
|
53384
55200
|
return JSON.stringify(value);
|
|
53385
55201
|
}
|
|
53386
55202
|
function sha2562(text2) {
|
|
53387
|
-
return
|
|
55203
|
+
return createHash5("sha256").update(text2).digest("hex");
|
|
53388
55204
|
}
|
|
53389
55205
|
var round = (v, digits) => {
|
|
53390
55206
|
const r = Number(v.toFixed(digits));
|
|
@@ -53501,10 +55317,10 @@ function assertInert(el, location) {
|
|
|
53501
55317
|
throw new SvgError("svg_unsafe", "Active content in a style attribute", location);
|
|
53502
55318
|
}
|
|
53503
55319
|
const counts = /* @__PURE__ */ new Map();
|
|
53504
|
-
for (const
|
|
53505
|
-
const n = (counts.get(
|
|
53506
|
-
counts.set(
|
|
53507
|
-
assertInert(
|
|
55320
|
+
for (const child2 of el.children) {
|
|
55321
|
+
const n = (counts.get(child2.local) ?? 0) + 1;
|
|
55322
|
+
counts.set(child2.local, n);
|
|
55323
|
+
assertInert(child2, `${location}/${child2.local}[${n}]`);
|
|
53508
55324
|
}
|
|
53509
55325
|
}
|
|
53510
55326
|
var INITIAL_STYLE = {
|
|
@@ -53756,14 +55572,14 @@ var Analyzer = class {
|
|
|
53756
55572
|
/** Walk an element's children with its own style and transform applied. */
|
|
53757
55573
|
container(el, ctx) {
|
|
53758
55574
|
const counts = /* @__PURE__ */ new Map();
|
|
53759
|
-
for (const
|
|
53760
|
-
const n = (counts.get(
|
|
53761
|
-
counts.set(
|
|
53762
|
-
const id2 = attr(
|
|
53763
|
-
this.element(
|
|
55575
|
+
for (const child2 of el.children) {
|
|
55576
|
+
const n = (counts.get(child2.local) ?? 0) + 1;
|
|
55577
|
+
counts.set(child2.local, n);
|
|
55578
|
+
const id2 = attr(child2, "id");
|
|
55579
|
+
this.element(child2, {
|
|
53764
55580
|
...ctx,
|
|
53765
55581
|
depth: ctx.depth + 1,
|
|
53766
|
-
location: `${ctx.location}/${
|
|
55582
|
+
location: `${ctx.location}/${child2.local}[${n}]${id2 ? `#${id2}` : ""}`
|
|
53767
55583
|
});
|
|
53768
55584
|
}
|
|
53769
55585
|
}
|
|
@@ -54186,9 +56002,9 @@ var Analyzer = class {
|
|
|
54186
56002
|
let pieces = polylines;
|
|
54187
56003
|
if (style.dasharray) {
|
|
54188
56004
|
const k = nonScaling ? 1 : mean;
|
|
54189
|
-
const
|
|
56005
|
+
const pattern2 = style.dasharray.map((v) => v * k);
|
|
54190
56006
|
pieces = polylines.flatMap(
|
|
54191
|
-
(p) => dashPolyline(p,
|
|
56007
|
+
(p) => dashPolyline(p, pattern2, style.dashoffset * k, (n) => this.charge("dashWork", n))
|
|
54192
56008
|
);
|
|
54193
56009
|
}
|
|
54194
56010
|
this.layers++;
|
|
@@ -54271,14 +56087,14 @@ function analyzeSvgBuffer(source) {
|
|
|
54271
56087
|
function readSvgSource(path10) {
|
|
54272
56088
|
let fd;
|
|
54273
56089
|
try {
|
|
54274
|
-
fd =
|
|
56090
|
+
fd = openSync8(path10, constants8.O_RDONLY | constants8.O_NOFOLLOW | constants8.O_NONBLOCK);
|
|
54275
56091
|
} catch (error2) {
|
|
54276
56092
|
if (error2.code === "ELOOP")
|
|
54277
56093
|
throw new SvgError("svg_file_invalid", "The SVG path is a symbolic link");
|
|
54278
56094
|
throw new SvgError("svg_file_invalid", "The SVG file does not exist or cannot be read");
|
|
54279
56095
|
}
|
|
54280
56096
|
try {
|
|
54281
|
-
const info =
|
|
56097
|
+
const info = fstatSync8(fd);
|
|
54282
56098
|
if (!info.isFile())
|
|
54283
56099
|
throw new SvgError("svg_file_invalid", "The SVG path is not a regular file");
|
|
54284
56100
|
if (info.size > SVG_LIMITS.maxSourceBytes)
|
|
@@ -54289,7 +56105,7 @@ function readSvgSource(path10) {
|
|
|
54289
56105
|
const buffer = Buffer.alloc(SVG_LIMITS.maxSourceBytes + 1);
|
|
54290
56106
|
let total = 0;
|
|
54291
56107
|
for (; ; ) {
|
|
54292
|
-
const n =
|
|
56108
|
+
const n = readSync6(fd, buffer, total, buffer.length - total, null);
|
|
54293
56109
|
if (n === 0) break;
|
|
54294
56110
|
total += n;
|
|
54295
56111
|
if (total > SVG_LIMITS.maxSourceBytes)
|
|
@@ -54300,7 +56116,7 @@ function readSvgSource(path10) {
|
|
|
54300
56116
|
}
|
|
54301
56117
|
return buffer.subarray(0, total);
|
|
54302
56118
|
} finally {
|
|
54303
|
-
|
|
56119
|
+
closeSync8(fd);
|
|
54304
56120
|
}
|
|
54305
56121
|
}
|
|
54306
56122
|
function analyzeSvgFile(path10) {
|
|
@@ -54871,7 +56687,7 @@ function registerNativeOperations(server2, manager) {
|
|
|
54871
56687
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
54872
56688
|
import { existsSync as existsSync13 } from "node:fs";
|
|
54873
56689
|
import { release as release2 } from "node:os";
|
|
54874
|
-
import { dirname as dirname7, resolve as
|
|
56690
|
+
import { dirname as dirname7, resolve as resolve6 } from "node:path";
|
|
54875
56691
|
import { fileURLToPath } from "node:url";
|
|
54876
56692
|
var OPTIONAL_BRIDGE_NOTE = "(optional \u2014 needed only for create-note format: markdown, macOS 26+)";
|
|
54877
56693
|
var MARKDOWN_MIN_DARWIN_MAJOR = 25;
|
|
@@ -54894,11 +56710,11 @@ function setupShortcuts(checkOnly, dependencies = {}) {
|
|
|
54894
56710
|
const result = spawnSync2("/usr/bin/open", [path10], { encoding: "utf8" });
|
|
54895
56711
|
return result.status === 0 ? { ok: true } : { ok: false, error: result.stderr || result.error?.message || "open failed" };
|
|
54896
56712
|
});
|
|
54897
|
-
const baseDirectory = dependencies.baseDirectory ||
|
|
56713
|
+
const baseDirectory = dependencies.baseDirectory || resolve6(dirname7(fileURLToPath(import.meta.url)), "../shortcuts");
|
|
54898
56714
|
const osRelease = (dependencies.osRelease || release2)();
|
|
54899
56715
|
const darwinMajor = Number.parseInt(osRelease.split(".")[0], 10);
|
|
54900
56716
|
const items = shortcutFiles.map(({ name, file, optional: optional2 }) => {
|
|
54901
|
-
const path10 =
|
|
56717
|
+
const path10 = resolve6(baseDirectory, file);
|
|
54902
56718
|
let installed = false;
|
|
54903
56719
|
let identifier;
|
|
54904
56720
|
let error2;
|
|
@@ -54958,19 +56774,19 @@ function formatShortcutSetup(report) {
|
|
|
54958
56774
|
|
|
54959
56775
|
// src/services/publicHelper.ts
|
|
54960
56776
|
import { spawn, spawnSync as spawnSync3 } from "node:child_process";
|
|
54961
|
-
import { createHash as
|
|
56777
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
54962
56778
|
import {
|
|
54963
56779
|
chmodSync,
|
|
54964
56780
|
existsSync as existsSync14,
|
|
54965
|
-
mkdirSync as
|
|
56781
|
+
mkdirSync as mkdirSync8,
|
|
54966
56782
|
mkdtempSync as mkdtempSync6,
|
|
54967
56783
|
readFileSync as readFileSync4,
|
|
54968
|
-
renameSync,
|
|
56784
|
+
renameSync as renameSync2,
|
|
54969
56785
|
rmSync as rmSync6,
|
|
54970
56786
|
writeFileSync as writeFileSync5
|
|
54971
56787
|
} from "node:fs";
|
|
54972
|
-
import { homedir as
|
|
54973
|
-
import { dirname as dirname8, join as
|
|
56788
|
+
import { homedir as homedir20, release as release3 } from "node:os";
|
|
56789
|
+
import { dirname as dirname8, join as join26, resolve as resolve7 } from "node:path";
|
|
54974
56790
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
54975
56791
|
var PUBLIC_HELPER_PROTOCOL = 1;
|
|
54976
56792
|
var PUBLIC_HELPER_DIR_ENV = "APPLE_NOTES_MCP_PUBLIC_HELPER_DIR";
|
|
@@ -54998,7 +56814,7 @@ var publicManifestSchema = external_exports.object({
|
|
|
54998
56814
|
function packageRoot(fromDir = dirname8(fileURLToPath2(import.meta.url))) {
|
|
54999
56815
|
let dir = fromDir;
|
|
55000
56816
|
for (; ; ) {
|
|
55001
|
-
const candidate =
|
|
56817
|
+
const candidate = join26(dir, "package.json");
|
|
55002
56818
|
if (existsSync14(candidate)) {
|
|
55003
56819
|
try {
|
|
55004
56820
|
if (JSON.parse(readFileSync4(candidate, "utf8")).name === "apple-notes-mcp")
|
|
@@ -55007,7 +56823,7 @@ function packageRoot(fromDir = dirname8(fileURLToPath2(import.meta.url))) {
|
|
|
55007
56823
|
}
|
|
55008
56824
|
}
|
|
55009
56825
|
const parent = dirname8(dir);
|
|
55010
|
-
if (parent === dir) return
|
|
56826
|
+
if (parent === dir) return resolve7(fromDir, "..");
|
|
55011
56827
|
dir = parent;
|
|
55012
56828
|
}
|
|
55013
56829
|
}
|
|
@@ -55015,7 +56831,7 @@ function defaultPublicHelperDeps(overrides = {}) {
|
|
|
55015
56831
|
return {
|
|
55016
56832
|
env: process.env,
|
|
55017
56833
|
platform: process.platform,
|
|
55018
|
-
sourcePath:
|
|
56834
|
+
sourcePath: join26(packageRoot(), PUBLIC_HELPER_SOURCE),
|
|
55019
56835
|
exists: existsSync14,
|
|
55020
56836
|
readFile: (path10) => readFileSync4(path10),
|
|
55021
56837
|
spawn: spawnSync3,
|
|
@@ -55026,14 +56842,14 @@ function defaultPublicHelperDeps(overrides = {}) {
|
|
|
55026
56842
|
function publicHelperInstallDir(env = process.env) {
|
|
55027
56843
|
const override = env[PUBLIC_HELPER_DIR_ENV]?.trim();
|
|
55028
56844
|
if (override) return override;
|
|
55029
|
-
return
|
|
56845
|
+
return join26(homedir20(), "Library", "Application Support", "apple-notes-mcp", "public-helper");
|
|
55030
56846
|
}
|
|
55031
56847
|
function sha256Hex(data) {
|
|
55032
|
-
return
|
|
56848
|
+
return createHash6("sha256").update(data).digest("hex");
|
|
55033
56849
|
}
|
|
55034
56850
|
function inspectPublicHelper(deps = defaultPublicHelperDeps()) {
|
|
55035
56851
|
const installDir = publicHelperInstallDir(deps.env);
|
|
55036
|
-
const binaryPath =
|
|
56852
|
+
const binaryPath = join26(installDir, PUBLIC_HELPER_BINARY);
|
|
55037
56853
|
const base = { installDir, binaryPath, sourcePath: deps.sourcePath, manifest: null };
|
|
55038
56854
|
const fail = (reason, detail) => ({
|
|
55039
56855
|
...base,
|
|
@@ -55044,7 +56860,7 @@ function inspectPublicHelper(deps = defaultPublicHelperDeps()) {
|
|
|
55044
56860
|
if (deps.platform !== "darwin") return fail("unsupported_platform", "macOS only");
|
|
55045
56861
|
if (!deps.exists(deps.sourcePath))
|
|
55046
56862
|
return fail("helper_not_installed", `Packaged helper source is missing: ${deps.sourcePath}`);
|
|
55047
|
-
const manifestPath =
|
|
56863
|
+
const manifestPath = join26(installDir, PUBLIC_HELPER_MANIFEST);
|
|
55048
56864
|
if (!deps.exists(binaryPath) || !deps.exists(manifestPath))
|
|
55049
56865
|
return fail(
|
|
55050
56866
|
"helper_not_installed",
|
|
@@ -55131,15 +56947,15 @@ async function callPublicHelperAsync(action, fields = {}, deps = defaultPublicHe
|
|
|
55131
56947
|
const aborted2 = () => new PublicHelperError("aborted", "The request was cancelled; the helper was stopped.");
|
|
55132
56948
|
if (signal?.aborted) throw aborted2();
|
|
55133
56949
|
return new Promise((resolvePromise, reject) => {
|
|
55134
|
-
const
|
|
56950
|
+
const child2 = (deps.spawnAsync ?? spawn)(binaryPath, [], {
|
|
55135
56951
|
stdio: ["pipe", "pipe", "ignore"]
|
|
55136
56952
|
});
|
|
55137
56953
|
const chunks = [];
|
|
55138
56954
|
let size = 0;
|
|
55139
|
-
let
|
|
56955
|
+
let failure2 = null;
|
|
55140
56956
|
const stop = (error2) => {
|
|
55141
|
-
|
|
55142
|
-
|
|
56957
|
+
failure2 ??= error2;
|
|
56958
|
+
child2.kill("SIGKILL");
|
|
55143
56959
|
};
|
|
55144
56960
|
const timer = setTimeout(
|
|
55145
56961
|
() => stop(new PublicHelperError("timeout", `The helper did not answer within ${timeout} ms.`)),
|
|
@@ -55151,21 +56967,21 @@ async function callPublicHelperAsync(action, fields = {}, deps = defaultPublicHe
|
|
|
55151
56967
|
clearTimeout(timer);
|
|
55152
56968
|
signal?.removeEventListener("abort", onAbort);
|
|
55153
56969
|
};
|
|
55154
|
-
|
|
56970
|
+
child2.stdout?.on("data", (chunk) => {
|
|
55155
56971
|
size += chunk.length;
|
|
55156
56972
|
if (size > MAX_OUTPUT_BYTES2)
|
|
55157
56973
|
stop(new PublicHelperError("invalid_response", "The helper response is too large."));
|
|
55158
56974
|
else chunks.push(chunk);
|
|
55159
56975
|
});
|
|
55160
|
-
|
|
56976
|
+
child2.on("error", (error2) => {
|
|
55161
56977
|
settle();
|
|
55162
56978
|
reject(
|
|
55163
|
-
|
|
56979
|
+
failure2 ?? new PublicHelperError("helper_unreachable", `Could not run the helper: ${error2.message}`)
|
|
55164
56980
|
);
|
|
55165
56981
|
});
|
|
55166
|
-
|
|
56982
|
+
child2.on("close", (status, exitSignal) => {
|
|
55167
56983
|
settle();
|
|
55168
|
-
if (
|
|
56984
|
+
if (failure2) return reject(failure2);
|
|
55169
56985
|
if (status === null && exitSignal)
|
|
55170
56986
|
return reject(
|
|
55171
56987
|
new PublicHelperError("helper_crashed", `The helper stopped on signal ${exitSignal}.`)
|
|
@@ -55176,9 +56992,9 @@ async function callPublicHelperAsync(action, fields = {}, deps = defaultPublicHe
|
|
|
55176
56992
|
reject(error2);
|
|
55177
56993
|
}
|
|
55178
56994
|
});
|
|
55179
|
-
|
|
56995
|
+
child2.stdin?.on("error", () => {
|
|
55180
56996
|
});
|
|
55181
|
-
|
|
56997
|
+
child2.stdin?.end(input);
|
|
55182
56998
|
});
|
|
55183
56999
|
}
|
|
55184
57000
|
function prepareCall(action, fields, deps, options) {
|
|
@@ -55283,8 +57099,8 @@ function publicHelperCompileArguments(sourcePath, digestPath, plistPath, outputP
|
|
|
55283
57099
|
}
|
|
55284
57100
|
function buildPublicHelper(checkOnly, deps = defaultPublicHelperBuildDeps()) {
|
|
55285
57101
|
const steps = [];
|
|
55286
|
-
const done = (
|
|
55287
|
-
ok,
|
|
57102
|
+
const done = (ok2) => ({
|
|
57103
|
+
ok: ok2,
|
|
55288
57104
|
checkOnly,
|
|
55289
57105
|
steps,
|
|
55290
57106
|
installation: inspectPublicHelper(deps)
|
|
@@ -55320,12 +57136,12 @@ function buildPublicHelper(checkOnly, deps = defaultPublicHelperBuildDeps()) {
|
|
|
55320
57136
|
const compiler = String(version3.stdout || version3.stderr || "").split("\n").find((line) => line.includes("Swift version"))?.trim() || "swiftc";
|
|
55321
57137
|
steps.push({ step: "find compiler", ok: true, detail: compiler });
|
|
55322
57138
|
const installDir = publicHelperInstallDir(deps.env);
|
|
55323
|
-
|
|
55324
|
-
const staging = mkdtempSync6(
|
|
57139
|
+
mkdirSync8(installDir, { recursive: true, mode: 448 });
|
|
57140
|
+
const staging = mkdtempSync6(join26(installDir, ".staging-"));
|
|
55325
57141
|
try {
|
|
55326
|
-
const stagedBinary =
|
|
55327
|
-
const digestPath =
|
|
55328
|
-
const plistPath =
|
|
57142
|
+
const stagedBinary = join26(staging, PUBLIC_HELPER_BINARY);
|
|
57143
|
+
const digestPath = join26(staging, "source-digest.swift");
|
|
57144
|
+
const plistPath = join26(staging, "Info.plist");
|
|
55329
57145
|
writeFileSync5(digestPath, sourceDigestSwift(sourceSha), { mode: 384 });
|
|
55330
57146
|
writeFileSync5(plistPath, publicHelperInfoPlist(), { mode: 384 });
|
|
55331
57147
|
const compile = deps.spawn(
|
|
@@ -55388,9 +57204,9 @@ function buildPublicHelper(checkOnly, deps = defaultPublicHelperBuildDeps()) {
|
|
|
55388
57204
|
compiler
|
|
55389
57205
|
};
|
|
55390
57206
|
chmodSync(stagedBinary, 448);
|
|
55391
|
-
|
|
57207
|
+
renameSync2(stagedBinary, join26(installDir, PUBLIC_HELPER_BINARY));
|
|
55392
57208
|
writeFileSync5(
|
|
55393
|
-
|
|
57209
|
+
join26(installDir, PUBLIC_HELPER_MANIFEST),
|
|
55394
57210
|
JSON.stringify(manifest, null, 2) + "\n",
|
|
55395
57211
|
{ mode: 384 }
|
|
55396
57212
|
);
|
|
@@ -55613,11 +57429,11 @@ function getNoteDrawings(noteId3, options = {}) {
|
|
|
55613
57429
|
if (!install.ready)
|
|
55614
57430
|
throw new PublicHelperError(install.reason ?? "helper_not_installed", install.detail ?? "");
|
|
55615
57431
|
const drawings = rows.map((row) => decodeRow(row, format, includePoints, deps));
|
|
55616
|
-
const
|
|
57432
|
+
const ok2 = drawings.filter((d) => d.status === "ok").length;
|
|
55617
57433
|
return {
|
|
55618
57434
|
id: noteId3,
|
|
55619
57435
|
drawingCount: drawings.length,
|
|
55620
|
-
status:
|
|
57436
|
+
status: ok2 === drawings.length ? "ok" : ok2 ? "partial" : "error",
|
|
55621
57437
|
drawings
|
|
55622
57438
|
};
|
|
55623
57439
|
}
|
|
@@ -55634,8 +57450,8 @@ function formatNoteDrawings(result) {
|
|
|
55634
57450
|
}
|
|
55635
57451
|
|
|
55636
57452
|
// src/utils/noteAudio.ts
|
|
55637
|
-
import { readdirSync as
|
|
55638
|
-
import { join as
|
|
57453
|
+
import { readdirSync as readdirSync5, statSync as statSync4 } from "node:fs";
|
|
57454
|
+
import { join as join27 } from "node:path";
|
|
55639
57455
|
var EXTRA_AUDIO_UTIS = [
|
|
55640
57456
|
"public.mp3",
|
|
55641
57457
|
"public.aiff-audio",
|
|
@@ -55660,7 +57476,7 @@ function accountDirsFor(containerDir, accountIdentifier) {
|
|
|
55660
57476
|
if (own) return [own];
|
|
55661
57477
|
let names;
|
|
55662
57478
|
try {
|
|
55663
|
-
names =
|
|
57479
|
+
names = readdirSync5(join27(containerDir, "Accounts")).sort();
|
|
55664
57480
|
} catch {
|
|
55665
57481
|
return [];
|
|
55666
57482
|
}
|
|
@@ -55672,8 +57488,8 @@ function resolveMediaPath(media, accountIdentifier = null, containerDir = NOTES_
|
|
|
55672
57488
|
if (!id2 || !filename) return null;
|
|
55673
57489
|
const generation = safeComponent(media?.generation);
|
|
55674
57490
|
for (const dir of accountDirsFor(containerDir, accountIdentifier)) {
|
|
55675
|
-
const base =
|
|
55676
|
-
const candidates = generation ? [
|
|
57491
|
+
const base = join27(dir, "Media", id2);
|
|
57492
|
+
const candidates = generation ? [join27(base, generation, filename), join27(base, filename)] : [join27(base, filename)];
|
|
55677
57493
|
for (const candidate of candidates) {
|
|
55678
57494
|
const real = realInside(candidate, dir);
|
|
55679
57495
|
if (real && isFile2(real)) return real;
|
|
@@ -55945,21 +57761,21 @@ import { spawnSync as spawnSync5 } from "node:child_process";
|
|
|
55945
57761
|
import {
|
|
55946
57762
|
chmodSync as chmodSync2,
|
|
55947
57763
|
existsSync as existsSync16,
|
|
55948
|
-
mkdirSync as
|
|
57764
|
+
mkdirSync as mkdirSync9,
|
|
55949
57765
|
mkdtempSync as mkdtempSync7,
|
|
55950
|
-
renameSync as
|
|
57766
|
+
renameSync as renameSync3,
|
|
55951
57767
|
rmSync as rmSync7,
|
|
55952
57768
|
writeFileSync as writeFileSync6
|
|
55953
57769
|
} from "node:fs";
|
|
55954
57770
|
import { release as release4 } from "node:os";
|
|
55955
|
-
import { join as
|
|
57771
|
+
import { join as join29 } from "node:path";
|
|
55956
57772
|
|
|
55957
57773
|
// src/services/privateHelper.ts
|
|
55958
57774
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
55959
|
-
import { createHash as
|
|
57775
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
55960
57776
|
import { existsSync as existsSync15, readFileSync as readFileSync5 } from "node:fs";
|
|
55961
|
-
import { homedir as
|
|
55962
|
-
import { dirname as dirname9, join as
|
|
57777
|
+
import { homedir as homedir21 } from "node:os";
|
|
57778
|
+
import { dirname as dirname9, join as join28, resolve as resolve8 } from "node:path";
|
|
55963
57779
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
55964
57780
|
var PRIVATE_HELPER_PROTOCOL = 1;
|
|
55965
57781
|
var ENABLE_ENV = "APPLE_NOTES_MCP_ENABLE_PRIVATE";
|
|
@@ -55987,7 +57803,7 @@ var manifestSchema = external_exports.object({
|
|
|
55987
57803
|
function packageRoot2(fromDir = dirname9(fileURLToPath3(import.meta.url))) {
|
|
55988
57804
|
let dir = fromDir;
|
|
55989
57805
|
for (; ; ) {
|
|
55990
|
-
const candidate =
|
|
57806
|
+
const candidate = join28(dir, "package.json");
|
|
55991
57807
|
if (existsSync15(candidate)) {
|
|
55992
57808
|
try {
|
|
55993
57809
|
const pkg = JSON.parse(readFileSync5(candidate, "utf8"));
|
|
@@ -55996,7 +57812,7 @@ function packageRoot2(fromDir = dirname9(fileURLToPath3(import.meta.url))) {
|
|
|
55996
57812
|
}
|
|
55997
57813
|
}
|
|
55998
57814
|
const parent = dirname9(dir);
|
|
55999
|
-
if (parent === dir) return
|
|
57815
|
+
if (parent === dir) return resolve8(fromDir, "..");
|
|
56000
57816
|
dir = parent;
|
|
56001
57817
|
}
|
|
56002
57818
|
}
|
|
@@ -56004,7 +57820,7 @@ function defaultDeps2(overrides = {}) {
|
|
|
56004
57820
|
return {
|
|
56005
57821
|
env: process.env,
|
|
56006
57822
|
platform: process.platform,
|
|
56007
|
-
sourcePath:
|
|
57823
|
+
sourcePath: join28(packageRoot2(), HELPER_SOURCE_RELATIVE),
|
|
56008
57824
|
exists: existsSync15,
|
|
56009
57825
|
readFile: (path10) => readFileSync5(path10),
|
|
56010
57826
|
spawn: spawnSync4,
|
|
@@ -56017,14 +57833,14 @@ function privateHelperEnabled(env = process.env) {
|
|
|
56017
57833
|
function helperInstallDir(env = process.env) {
|
|
56018
57834
|
const override = env[HELPER_DIR_ENV]?.trim();
|
|
56019
57835
|
if (override) return override;
|
|
56020
|
-
return
|
|
57836
|
+
return join28(homedir21(), "Library", "Application Support", "apple-notes-mcp", "private-helper");
|
|
56021
57837
|
}
|
|
56022
57838
|
function sha256Hex2(data) {
|
|
56023
|
-
return
|
|
57839
|
+
return createHash7("sha256").update(data).digest("hex");
|
|
56024
57840
|
}
|
|
56025
57841
|
function inspectInstallation(deps = defaultDeps2()) {
|
|
56026
57842
|
const installDir = helperInstallDir(deps.env);
|
|
56027
|
-
const binaryPath =
|
|
57843
|
+
const binaryPath = join28(installDir, HELPER_BINARY_NAME);
|
|
56028
57844
|
const base = {
|
|
56029
57845
|
installDir,
|
|
56030
57846
|
binaryPath,
|
|
@@ -56042,7 +57858,7 @@ function inspectInstallation(deps = defaultDeps2()) {
|
|
|
56042
57858
|
if (!deps.exists(deps.sourcePath))
|
|
56043
57859
|
return fail("helper_not_installed", `Packaged helper source is missing: ${deps.sourcePath}`);
|
|
56044
57860
|
base.expectedSourceSha256 = sha256Hex2(deps.readFile(deps.sourcePath));
|
|
56045
|
-
const manifestPath =
|
|
57861
|
+
const manifestPath = join28(installDir, MANIFEST_NAME);
|
|
56046
57862
|
if (!deps.exists(binaryPath) || !deps.exists(manifestPath))
|
|
56047
57863
|
return fail(
|
|
56048
57864
|
"helper_not_installed",
|
|
@@ -56313,8 +58129,8 @@ function compileArguments(sourcePath, outputPath, sourceSha) {
|
|
|
56313
58129
|
}
|
|
56314
58130
|
function buildPrivateHelper(checkOnly, deps = defaultBuildDeps()) {
|
|
56315
58131
|
const steps = [];
|
|
56316
|
-
const done = (
|
|
56317
|
-
ok,
|
|
58132
|
+
const done = (ok2) => ({
|
|
58133
|
+
ok: ok2,
|
|
56318
58134
|
checkOnly,
|
|
56319
58135
|
steps,
|
|
56320
58136
|
installation: inspectInstallation(deps)
|
|
@@ -56356,10 +58172,10 @@ function buildPrivateHelper(checkOnly, deps = defaultBuildDeps()) {
|
|
|
56356
58172
|
const compiler = String(clangVersion.stdout || "").split("\n")[0] || "clang";
|
|
56357
58173
|
steps.push({ step: "find compiler", ok: true, detail: compiler });
|
|
56358
58174
|
const installDir = helperInstallDir(deps.env);
|
|
56359
|
-
|
|
56360
|
-
const staging = mkdtempSync7(
|
|
58175
|
+
mkdirSync9(installDir, { recursive: true, mode: 448 });
|
|
58176
|
+
const staging = mkdtempSync7(join29(installDir, ".staging-"));
|
|
56361
58177
|
try {
|
|
56362
|
-
const stagedBinary =
|
|
58178
|
+
const stagedBinary = join29(staging, HELPER_BINARY_NAME);
|
|
56363
58179
|
const compile = deps.spawn(
|
|
56364
58180
|
"/usr/bin/xcrun",
|
|
56365
58181
|
compileArguments(deps.sourcePath, stagedBinary, sourceSha),
|
|
@@ -56436,8 +58252,8 @@ function buildPrivateHelper(checkOnly, deps = defaultBuildDeps()) {
|
|
|
56436
58252
|
compiler
|
|
56437
58253
|
};
|
|
56438
58254
|
chmodSync2(stagedBinary, 448);
|
|
56439
|
-
|
|
56440
|
-
writeFileSync6(
|
|
58255
|
+
renameSync3(stagedBinary, join29(installDir, HELPER_BINARY_NAME));
|
|
58256
|
+
writeFileSync6(join29(installDir, MANIFEST_NAME), JSON.stringify(manifest, null, 2) + "\n", {
|
|
56441
58257
|
mode: 384
|
|
56442
58258
|
});
|
|
56443
58259
|
steps.push({ step: "install", ok: true, detail: installDir });
|
|
@@ -56605,6 +58421,7 @@ var server = new McpServer({
|
|
|
56605
58421
|
var notesManager = new AppleNotesManager();
|
|
56606
58422
|
registerDirectOperations(server, notesManager);
|
|
56607
58423
|
registerFolderDelete(server, notesManager);
|
|
58424
|
+
registerMarkdownTemplates(server);
|
|
56608
58425
|
registerSvgAnalysis(server);
|
|
56609
58426
|
registerNativeTagsBridge(server, notesManager);
|
|
56610
58427
|
registerNativeOperations(server, notesManager);
|
|
@@ -58034,10 +59851,10 @@ function guardedAppend({
|
|
|
58034
59851
|
return `<div>${escaped || "<br>"}</div>`;
|
|
58035
59852
|
}).join("");
|
|
58036
59853
|
};
|
|
58037
|
-
const separatorToHtml = (
|
|
58038
|
-
if (format === "html") return
|
|
58039
|
-
if (
|
|
58040
|
-
const escaped =
|
|
59854
|
+
const separatorToHtml = (sep5) => {
|
|
59855
|
+
if (format === "html") return sep5;
|
|
59856
|
+
if (sep5 === "\n\n") return "<div><br></div>";
|
|
59857
|
+
const escaped = sep5.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
58041
59858
|
return `<div>${escaped}</div>`;
|
|
58042
59859
|
};
|
|
58043
59860
|
const snapshot = readExactNoteSnapshot(id2);
|
|
@@ -59410,7 +61227,7 @@ var exportStatsSchema = external_exports.object({
|
|
|
59410
61227
|
registerTool(
|
|
59411
61228
|
"export-notes-markdown",
|
|
59412
61229
|
{
|
|
59413
|
-
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.",
|
|
61230
|
+
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.",
|
|
59414
61231
|
inputSchema: {
|
|
59415
61232
|
id: noteIdInput.optional(),
|
|
59416
61233
|
folder: external_exports.string().min(1).max(MAX.FOLDER).optional().describe("Folder path to export instead of one note (nested paths use '/')"),
|
|
@@ -59420,7 +61237,13 @@ registerTool(
|
|
|
59420
61237
|
),
|
|
59421
61238
|
outputPath: exportPathInput("File to create for the Markdown"),
|
|
59422
61239
|
assetsDir: exportPathInput("Directory that receives copies of attachment files"),
|
|
59423
|
-
wrap: external_exports.number().int().min(0).max(1e3).optional().describe("Hard-wrap prose at this many columns (0 or omitted: no wrapping)")
|
|
61240
|
+
wrap: external_exports.number().int().min(0).max(1e3).optional().describe("Hard-wrap prose at this many columns (0 or omitted: no wrapping)"),
|
|
61241
|
+
template: external_exports.string().min(1).max(64).optional().describe(
|
|
61242
|
+
`Render through this template: built-in ${BUILTIN_TEMPLATE_NAMES.map((n) => `'${n}'`).join(" or ")}, or a saved template's name (list-markdown-templates). Exclusive with templateFile`
|
|
61243
|
+
),
|
|
61244
|
+
templateFile: exportPathInput(
|
|
61245
|
+
"JSON template file (.json) to render through (exclusive with template; at most 256 KiB)"
|
|
61246
|
+
)
|
|
59424
61247
|
},
|
|
59425
61248
|
outputSchema: {
|
|
59426
61249
|
format: external_exports.string().optional(),
|
|
@@ -59430,7 +61253,13 @@ registerTool(
|
|
|
59430
61253
|
output: external_exports.string().optional(),
|
|
59431
61254
|
assets: external_exports.object({ dir: external_exports.string(), files: external_exports.number() }).optional(),
|
|
59432
61255
|
stats: exportStatsSchema.optional(),
|
|
59433
|
-
skipped: external_exports.array(external_exports.object({ id: external_exports.string(), code: external_exports.string() })).optional()
|
|
61256
|
+
skipped: external_exports.array(external_exports.object({ id: external_exports.string(), code: external_exports.string() })).optional(),
|
|
61257
|
+
template: external_exports.object({ name: external_exports.string(), source: external_exports.string() }).optional(),
|
|
61258
|
+
warnings: external_exports.array(
|
|
61259
|
+
external_exports.object({ code: external_exports.string(), noteId: external_exports.string(), attachmentId: external_exports.string().optional() })
|
|
61260
|
+
).optional(),
|
|
61261
|
+
warningsOmitted: external_exports.number().optional(),
|
|
61262
|
+
assetFiles: external_exports.array(external_exports.string()).optional()
|
|
59434
61263
|
},
|
|
59435
61264
|
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false }
|
|
59436
61265
|
},
|
|
@@ -59439,15 +61268,22 @@ registerTool(
|
|
|
59439
61268
|
try {
|
|
59440
61269
|
receipt = exportNotesMarkdown(request, {
|
|
59441
61270
|
listNoteRefs: (account, folder, since, limit) => notesManager.listNoteRefs(account, folder, since, limit),
|
|
61271
|
+
findTemplate: (name) => TEMPLATE_SLUG.test(name) ? new TemplateStore().find(name) : void 0,
|
|
59442
61272
|
// The document travels twice (text and structuredContent).
|
|
59443
61273
|
maxInlineBytes: Math.floor(exportMaxResponseBytes() / 2) - 64 * 1024
|
|
59444
61274
|
});
|
|
59445
61275
|
} catch (error2) {
|
|
59446
61276
|
if (!(error2 instanceof NotesExportError || error2 instanceof NoteBlocksError)) throw error2;
|
|
59447
61277
|
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}` : "";
|
|
61278
|
+
if (error2 instanceof NotesExportError && error2.details)
|
|
61279
|
+
return errorResponse(
|
|
61280
|
+
`Error exporting Markdown [${error2.code}]: the template is invalid:
|
|
61281
|
+
` + error2.details.map((detail) => `${detail.path}: ${detail.message}`).join("\n")
|
|
61282
|
+
);
|
|
59448
61283
|
return errorResponse(`Error exporting Markdown [${error2.code}]: ${error2.message}${hint}`);
|
|
59449
61284
|
}
|
|
59450
|
-
const
|
|
61285
|
+
const warned = receipt.warnings?.length ? `; ${receipt.warnings.length + (receipt.warningsOmitted ?? 0)} warning(s)` : "";
|
|
61286
|
+
const skipped = (receipt.skipped.length ? `; skipped ${receipt.skipped.length}` : "") + warned;
|
|
59451
61287
|
if (receipt.output)
|
|
59452
61288
|
return successResponse(
|
|
59453
61289
|
`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}.`,
|