applesauce-content 0.0.0-concord-20260710175615
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/LICENSE +21 -0
- package/README.md +32 -0
- package/dist/helpers/index.d.ts +1 -0
- package/dist/helpers/index.js +1 -0
- package/dist/helpers/media.d.ts +3 -0
- package/dist/helpers/media.js +15 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/markdown/blossom.d.ts +9 -0
- package/dist/markdown/blossom.js +22 -0
- package/dist/markdown/cashu.d.ts +12 -0
- package/dist/markdown/cashu.js +24 -0
- package/dist/markdown/index.d.ts +2 -0
- package/dist/markdown/index.js +2 -0
- package/dist/markdown/mentions.d.ts +8 -0
- package/dist/markdown/mentions.js +22 -0
- package/dist/nast/eol-metadata.d.ts +3 -0
- package/dist/nast/eol-metadata.js +14 -0
- package/dist/nast/find-and-replace.d.ts +6 -0
- package/dist/nast/find-and-replace.js +95 -0
- package/dist/nast/index.d.ts +4 -0
- package/dist/nast/index.js +4 -0
- package/dist/nast/truncate.d.ts +2 -0
- package/dist/nast/truncate.js +51 -0
- package/dist/nast/types.d.ts +74 -0
- package/dist/nast/types.js +1 -0
- package/dist/text/blossom.d.ts +4 -0
- package/dist/text/blossom.js +23 -0
- package/dist/text/cashu.d.ts +15 -0
- package/dist/text/cashu.js +32 -0
- package/dist/text/content.d.ts +8 -0
- package/dist/text/content.js +53 -0
- package/dist/text/emoji.d.ts +4 -0
- package/dist/text/emoji.js +32 -0
- package/dist/text/gallery.d.ts +8 -0
- package/dist/text/gallery.js +58 -0
- package/dist/text/hashtag.d.ts +4 -0
- package/dist/text/hashtag.js +30 -0
- package/dist/text/imeta.d.ts +11 -0
- package/dist/text/imeta.js +40 -0
- package/dist/text/index.d.ts +9 -0
- package/dist/text/index.js +9 -0
- package/dist/text/lightning.d.ts +15 -0
- package/dist/text/lightning.js +33 -0
- package/dist/text/links.d.ts +4 -0
- package/dist/text/links.js +23 -0
- package/dist/text/mentions.d.ts +4 -0
- package/dist/text/mentions.js +24 -0
- package/dist/text/parser.d.ts +6 -0
- package/dist/text/parser.js +15 -0
- package/package.json +96 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 hzrd149
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# applesauce-content
|
|
2
|
+
|
|
3
|
+
applesauce package for parsing text note content
|
|
4
|
+
|
|
5
|
+
## Example
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { getParsedContent } from "applesauce-content/text";
|
|
9
|
+
|
|
10
|
+
const stringContent = `
|
|
11
|
+
hello nostr!
|
|
12
|
+
nostr:npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6
|
|
13
|
+
`;
|
|
14
|
+
const ats = getParsedContent(stringContent);
|
|
15
|
+
|
|
16
|
+
console.log(ats);
|
|
17
|
+
/*
|
|
18
|
+
{
|
|
19
|
+
type: 'root',
|
|
20
|
+
event: undefined,
|
|
21
|
+
children: [
|
|
22
|
+
{ type: 'text', value: 'hello nostr!' },
|
|
23
|
+
{ type: 'text', value: '\n' },
|
|
24
|
+
{
|
|
25
|
+
type: 'mention',
|
|
26
|
+
decoded: [Object],
|
|
27
|
+
encoded: 'npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6'
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
*/
|
|
32
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./media.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./media.js";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { getSha256FromURL } from "applesauce-common/helpers/file-metadata";
|
|
2
|
+
import { Tokens } from "applesauce-core/helpers/regexp";
|
|
3
|
+
/** Returns all URLs in a content string that contain a sha256 hash */
|
|
4
|
+
export function getMediaAttachmentURLsFromContent(content) {
|
|
5
|
+
return (Array.from(content.matchAll(Tokens.link))
|
|
6
|
+
.map((match) => match[0])
|
|
7
|
+
// filter out invalid URLs
|
|
8
|
+
.filter((str) => URL.canParse(str))
|
|
9
|
+
// convert to URLs
|
|
10
|
+
.map((url) => new URL(url))
|
|
11
|
+
// only keep urls with sha256 hashes in the
|
|
12
|
+
.filter((url) => !!getSha256FromURL(url))
|
|
13
|
+
// convert to media attachments
|
|
14
|
+
.map((url) => ({ url: url.toString(), sha256: getSha256FromURL(url) })));
|
|
15
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ParsedBlossomURI } from "applesauce-common/helpers/blossom";
|
|
2
|
+
import { Link, Nodes } from "mdast";
|
|
3
|
+
import { Transformer } from "unified";
|
|
4
|
+
export interface BlossomMdastLink extends Link {
|
|
5
|
+
type: "link";
|
|
6
|
+
data: ParsedBlossomURI;
|
|
7
|
+
}
|
|
8
|
+
/** Finds and creates BUD-10 `blossom:` URI links in a mdast tree */
|
|
9
|
+
export declare function remarkBlossomURIs(): Transformer<Nodes>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { parseBlossomURI } from "applesauce-common/helpers/blossom";
|
|
2
|
+
import { Tokens } from "applesauce-core/helpers/regexp";
|
|
3
|
+
import { findAndReplace } from "mdast-util-find-and-replace";
|
|
4
|
+
/** Finds and creates BUD-10 `blossom:` URI links in a mdast tree */
|
|
5
|
+
export function remarkBlossomURIs() {
|
|
6
|
+
return (tree) => {
|
|
7
|
+
findAndReplace(tree, [
|
|
8
|
+
Tokens.blossom,
|
|
9
|
+
(raw) => {
|
|
10
|
+
const parsed = parseBlossomURI(raw);
|
|
11
|
+
if (!parsed)
|
|
12
|
+
return false;
|
|
13
|
+
return {
|
|
14
|
+
type: "link",
|
|
15
|
+
data: parsed,
|
|
16
|
+
url: raw,
|
|
17
|
+
children: [{ type: "text", value: raw }],
|
|
18
|
+
};
|
|
19
|
+
},
|
|
20
|
+
]);
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Token } from "@cashu/cashu-ts";
|
|
2
|
+
import { Link, Nodes } from "mdast";
|
|
3
|
+
import { Transformer } from "unified";
|
|
4
|
+
export interface CashuMdastLink extends Link {
|
|
5
|
+
type: "link";
|
|
6
|
+
data: {
|
|
7
|
+
token: Token;
|
|
8
|
+
raw: string;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/** Finds cashu tokens in a mdast tree and replaces them with link nodes carrying the decoded token */
|
|
12
|
+
export declare function remarkCashuTokens(): Transformer<Nodes>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { getDecodedToken } from "@cashu/cashu-ts";
|
|
2
|
+
import { Tokens } from "applesauce-core/helpers/regexp";
|
|
3
|
+
import { findAndReplace } from "mdast-util-find-and-replace";
|
|
4
|
+
/** Finds cashu tokens in a mdast tree and replaces them with link nodes carrying the decoded token */
|
|
5
|
+
export function remarkCashuTokens() {
|
|
6
|
+
return (tree) => {
|
|
7
|
+
findAndReplace(tree, [
|
|
8
|
+
Tokens.cashu,
|
|
9
|
+
(_, $1) => {
|
|
10
|
+
try {
|
|
11
|
+
const token = getDecodedToken($1, []);
|
|
12
|
+
return {
|
|
13
|
+
type: "link",
|
|
14
|
+
data: { token, raw: $1 },
|
|
15
|
+
url: "cashu:" + $1,
|
|
16
|
+
children: [{ type: "text", value: $1 }],
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
catch (error) { }
|
|
20
|
+
return false;
|
|
21
|
+
},
|
|
22
|
+
]);
|
|
23
|
+
};
|
|
24
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { DecodeResult } from "applesauce-core/helpers";
|
|
2
|
+
import { Link, Nodes } from "mdast";
|
|
3
|
+
import { Transformer } from "unified";
|
|
4
|
+
export interface NostrMention extends Link {
|
|
5
|
+
type: "link";
|
|
6
|
+
data: DecodeResult;
|
|
7
|
+
}
|
|
8
|
+
export declare function remarkNostrMentions(): Transformer<Nodes>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { decodePointer } from "applesauce-core/helpers/pointers";
|
|
2
|
+
import { Tokens } from "applesauce-core/helpers/regexp";
|
|
3
|
+
import { findAndReplace } from "mdast-util-find-and-replace";
|
|
4
|
+
export function remarkNostrMentions() {
|
|
5
|
+
return (tree) => {
|
|
6
|
+
findAndReplace(tree, [
|
|
7
|
+
Tokens.nostrLink,
|
|
8
|
+
(_, $1) => {
|
|
9
|
+
try {
|
|
10
|
+
return {
|
|
11
|
+
type: "link",
|
|
12
|
+
data: decodePointer($1),
|
|
13
|
+
children: [],
|
|
14
|
+
url: "nostr:" + $1,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
catch (error) { }
|
|
18
|
+
return false;
|
|
19
|
+
},
|
|
20
|
+
]);
|
|
21
|
+
};
|
|
22
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function eolMetadata() {
|
|
2
|
+
return (tree) => {
|
|
3
|
+
for (let i = 0; i < tree.children.length; i++) {
|
|
4
|
+
const node = tree.children[i];
|
|
5
|
+
const next = tree.children[i + 1];
|
|
6
|
+
if ((node.type === "text" && node.value.endsWith("\n")) ||
|
|
7
|
+
!next ||
|
|
8
|
+
(next.type === "text" && next.value.startsWith("\n"))) {
|
|
9
|
+
node.data = node.data || {};
|
|
10
|
+
node.data.eol = true;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Content, Root } from "./types.js";
|
|
2
|
+
type Replace = (...groups: string[]) => null | undefined | false | string | Content | Content[];
|
|
3
|
+
type FindAndReplaceTuple = [RegExp, Replace];
|
|
4
|
+
type FindAndReplaceList = FindAndReplaceTuple[];
|
|
5
|
+
export declare function findAndReplace(tree: Root, list: FindAndReplaceList): void;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { visitParents } from "unist-util-visit-parents";
|
|
2
|
+
export function findAndReplace(tree, list) {
|
|
3
|
+
const pairs = list;
|
|
4
|
+
let pairIndex = -1;
|
|
5
|
+
const visitor = (node, parents) => {
|
|
6
|
+
let index = -1;
|
|
7
|
+
/** @type {Parents | undefined} */
|
|
8
|
+
let grandparent;
|
|
9
|
+
while (++index < parents.length) {
|
|
10
|
+
const parent = parents[index];
|
|
11
|
+
// const siblings = grandparent ? grandparent.children : undefined;
|
|
12
|
+
grandparent = parent;
|
|
13
|
+
}
|
|
14
|
+
if (grandparent) {
|
|
15
|
+
return handler(node, parents);
|
|
16
|
+
}
|
|
17
|
+
return undefined;
|
|
18
|
+
};
|
|
19
|
+
while (++pairIndex < pairs.length) {
|
|
20
|
+
visitParents(tree, "text", visitor);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Handle a text node which is not in an ignored parent.
|
|
24
|
+
*
|
|
25
|
+
* @param {Text} node
|
|
26
|
+
* Text node.
|
|
27
|
+
* @param {Array<Parents>} parents
|
|
28
|
+
* Parents.
|
|
29
|
+
* @returns {VisitorResult}
|
|
30
|
+
* Result.
|
|
31
|
+
*/
|
|
32
|
+
function handler(node, parents) {
|
|
33
|
+
const parent = parents[parents.length - 1];
|
|
34
|
+
const find = pairs[pairIndex][0];
|
|
35
|
+
const replace = pairs[pairIndex][1];
|
|
36
|
+
let start = 0;
|
|
37
|
+
const siblings = parent.children;
|
|
38
|
+
const index = siblings.indexOf(node);
|
|
39
|
+
let change = false;
|
|
40
|
+
let nodes = [];
|
|
41
|
+
find.lastIndex = 0;
|
|
42
|
+
let match = find.exec(node.value);
|
|
43
|
+
while (match) {
|
|
44
|
+
const position = match.index;
|
|
45
|
+
/** @type {RegExpMatchObject} */
|
|
46
|
+
// const matchObject = {
|
|
47
|
+
// index: match.index,
|
|
48
|
+
// input: match.input,
|
|
49
|
+
// stack: [...parents, node],
|
|
50
|
+
// };
|
|
51
|
+
// let value = replace(...match, matchObject);
|
|
52
|
+
let value = replace(...match);
|
|
53
|
+
if (typeof value === "string") {
|
|
54
|
+
value = value.length > 0 ? { type: "text", value } : undefined;
|
|
55
|
+
}
|
|
56
|
+
// It wasn’t a match after all.
|
|
57
|
+
if (value === false) {
|
|
58
|
+
// False acts as if there was no match.
|
|
59
|
+
// So we need to reset `lastIndex`, which currently being at the end of
|
|
60
|
+
// the current match, to the beginning.
|
|
61
|
+
find.lastIndex = position + 1;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
if (start !== position) {
|
|
65
|
+
nodes.push({
|
|
66
|
+
type: "text",
|
|
67
|
+
value: node.value.slice(start, position),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
if (Array.isArray(value)) {
|
|
71
|
+
nodes.push(...value);
|
|
72
|
+
}
|
|
73
|
+
else if (value) {
|
|
74
|
+
nodes.push(value);
|
|
75
|
+
}
|
|
76
|
+
start = position + match[0].length;
|
|
77
|
+
change = true;
|
|
78
|
+
}
|
|
79
|
+
if (!find.global) {
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
match = find.exec(node.value);
|
|
83
|
+
}
|
|
84
|
+
if (change) {
|
|
85
|
+
if (start < node.value.length) {
|
|
86
|
+
nodes.push({ type: "text", value: node.value.slice(start) });
|
|
87
|
+
}
|
|
88
|
+
parent.children.splice(index, 1, ...nodes);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
nodes = [node];
|
|
92
|
+
}
|
|
93
|
+
return index + nodes.length;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export function truncateContent(tree, maxLength = 256) {
|
|
2
|
+
let length = 0;
|
|
3
|
+
for (let i = 0; i < tree.children.length; i++) {
|
|
4
|
+
const node = tree.children[i];
|
|
5
|
+
switch (node.type) {
|
|
6
|
+
case "hashtag":
|
|
7
|
+
length += 1 + node.hashtag.length;
|
|
8
|
+
break;
|
|
9
|
+
case "mention":
|
|
10
|
+
// guess user names are about 10 long
|
|
11
|
+
length += 10;
|
|
12
|
+
break;
|
|
13
|
+
case "cashu":
|
|
14
|
+
length += node.raw.length;
|
|
15
|
+
break;
|
|
16
|
+
case "blossom":
|
|
17
|
+
length += node.raw.length;
|
|
18
|
+
break;
|
|
19
|
+
case "gallery":
|
|
20
|
+
length += node.links.reduce((t, l) => t + l.length, 0);
|
|
21
|
+
break;
|
|
22
|
+
case "link":
|
|
23
|
+
case "text":
|
|
24
|
+
length += node.value.length;
|
|
25
|
+
break;
|
|
26
|
+
case "emoji":
|
|
27
|
+
length += 1;
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
if (length > maxLength) {
|
|
31
|
+
if (node.type === "text") {
|
|
32
|
+
const children = i > 0 ? tree.children.slice(0, i) : [];
|
|
33
|
+
const chunkLength = node.value.length - (length - maxLength);
|
|
34
|
+
// find the nearest newline
|
|
35
|
+
const newLines = node.value.matchAll(/\n/g);
|
|
36
|
+
for (const match of newLines) {
|
|
37
|
+
if (match.index && match.index > chunkLength) {
|
|
38
|
+
children.push({ type: "text", value: node.value.slice(0, match.index) });
|
|
39
|
+
return { ...tree, children, truncated: true };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// just cut the string
|
|
43
|
+
children.push({ type: "text", value: node.value.slice(0, maxLength - length) });
|
|
44
|
+
return { ...tree, children, truncated: true };
|
|
45
|
+
}
|
|
46
|
+
else
|
|
47
|
+
return { ...tree, children: tree.children.slice(0, i), truncated: true };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return tree;
|
|
51
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { type EventTemplate, type NostrEvent } from "applesauce-core/helpers/event";
|
|
2
|
+
import { type DecodeResult } from "applesauce-core/helpers/pointers";
|
|
3
|
+
import { type Parent, type Node as UnistNode } from "unist";
|
|
4
|
+
export interface CommonData {
|
|
5
|
+
eol?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface Node extends Omit<UnistNode, "data"> {
|
|
8
|
+
data?: CommonData;
|
|
9
|
+
}
|
|
10
|
+
export interface Text extends Node {
|
|
11
|
+
type: "text";
|
|
12
|
+
value: string;
|
|
13
|
+
}
|
|
14
|
+
export interface Link extends Node {
|
|
15
|
+
type: "link";
|
|
16
|
+
value: string;
|
|
17
|
+
href: string;
|
|
18
|
+
}
|
|
19
|
+
export interface Gallery extends Node {
|
|
20
|
+
type: "gallery";
|
|
21
|
+
links: string[];
|
|
22
|
+
}
|
|
23
|
+
export interface Mention extends Node {
|
|
24
|
+
type: "mention";
|
|
25
|
+
decoded: DecodeResult;
|
|
26
|
+
encoded: string;
|
|
27
|
+
}
|
|
28
|
+
export interface Hashtag extends Node {
|
|
29
|
+
type: "hashtag";
|
|
30
|
+
/** The name as it was written in the event */
|
|
31
|
+
name: string;
|
|
32
|
+
/** The lowercase canonical name */
|
|
33
|
+
hashtag: string;
|
|
34
|
+
/** The indexable tag for the hashtag. will be undefined if none was found */
|
|
35
|
+
tag?: ["t", ...string[]];
|
|
36
|
+
}
|
|
37
|
+
export interface Emoji extends Node {
|
|
38
|
+
type: "emoji";
|
|
39
|
+
code: string;
|
|
40
|
+
raw: string;
|
|
41
|
+
url: string;
|
|
42
|
+
tag: ["emoji", ...string[]];
|
|
43
|
+
}
|
|
44
|
+
export interface BlossomURI extends Node {
|
|
45
|
+
type: "blossom";
|
|
46
|
+
/** The original matched text, e.g. `blossom:<hash>.pdf?xs=...` */
|
|
47
|
+
raw: string;
|
|
48
|
+
/** 64 character lowercase hex sha256 hash of the blob */
|
|
49
|
+
sha256: string;
|
|
50
|
+
/** File extension without the leading dot */
|
|
51
|
+
ext: string;
|
|
52
|
+
/** Optional exact blob size in bytes */
|
|
53
|
+
size?: number;
|
|
54
|
+
/** Server hints from repeated `xs` query parameters */
|
|
55
|
+
servers: string[];
|
|
56
|
+
/** Author hex pubkeys from repeated `as` query parameters */
|
|
57
|
+
authors: string[];
|
|
58
|
+
}
|
|
59
|
+
export interface ContentMap {
|
|
60
|
+
text: Text;
|
|
61
|
+
link: Link;
|
|
62
|
+
mention: Mention;
|
|
63
|
+
hashtag: Hashtag;
|
|
64
|
+
emoji: Emoji;
|
|
65
|
+
gallery: Gallery;
|
|
66
|
+
blossom: BlossomURI;
|
|
67
|
+
}
|
|
68
|
+
export type Content = ContentMap[keyof ContentMap];
|
|
69
|
+
export interface Root extends Parent {
|
|
70
|
+
type: "root";
|
|
71
|
+
children: Content[];
|
|
72
|
+
event?: NostrEvent | EventTemplate;
|
|
73
|
+
truncated?: boolean;
|
|
74
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { parseBlossomURI } from "applesauce-common/helpers/blossom";
|
|
2
|
+
import { Tokens } from "applesauce-core/helpers/regexp";
|
|
3
|
+
import { findAndReplace } from "../nast/find-and-replace.js";
|
|
4
|
+
/** Finds and creates BUD-10 blossom URI nodes in the tree */
|
|
5
|
+
export function blossomURIs() {
|
|
6
|
+
return (tree) => {
|
|
7
|
+
findAndReplace(tree, [
|
|
8
|
+
[
|
|
9
|
+
Tokens.blossom,
|
|
10
|
+
(raw) => {
|
|
11
|
+
const parsed = parseBlossomURI(raw);
|
|
12
|
+
if (!parsed)
|
|
13
|
+
return false;
|
|
14
|
+
return {
|
|
15
|
+
type: "blossom",
|
|
16
|
+
raw,
|
|
17
|
+
...parsed,
|
|
18
|
+
};
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
]);
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type Token } from "@cashu/cashu-ts";
|
|
2
|
+
import { Transformer } from "unified";
|
|
3
|
+
import { Node, Root } from "../nast/types.js";
|
|
4
|
+
export interface CashuToken extends Node {
|
|
5
|
+
type: "cashu";
|
|
6
|
+
token: Token;
|
|
7
|
+
raw: string;
|
|
8
|
+
}
|
|
9
|
+
declare module "../nast/types.js" {
|
|
10
|
+
interface ContentMap {
|
|
11
|
+
cashu: CashuToken;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/** Parse cashu tokens from an ATS tree */
|
|
15
|
+
export declare function cashuTokens(): Transformer<Root>;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { getDecodedToken } from "@cashu/cashu-ts";
|
|
2
|
+
import { Tokens } from "applesauce-core/helpers/regexp";
|
|
3
|
+
import { findAndReplace } from "../nast/find-and-replace.js";
|
|
4
|
+
import { textNoteTransformers } from "./content.js";
|
|
5
|
+
/** Parse cashu tokens from an ATS tree */
|
|
6
|
+
export function cashuTokens() {
|
|
7
|
+
return (tree) => {
|
|
8
|
+
findAndReplace(tree, [
|
|
9
|
+
[
|
|
10
|
+
Tokens.cashu,
|
|
11
|
+
(_, $1) => {
|
|
12
|
+
try {
|
|
13
|
+
const token = getDecodedToken($1, []);
|
|
14
|
+
return {
|
|
15
|
+
type: "cashu",
|
|
16
|
+
token,
|
|
17
|
+
raw: $1,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
catch (error) { }
|
|
21
|
+
return false;
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
]);
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
// Register the cashu transformer in the default text-note pipeline as a side
|
|
28
|
+
// effect of importing this module. Consumers opt-in to cashu support by
|
|
29
|
+
// importing `applesauce-content/text/cashu`.
|
|
30
|
+
if (!textNoteTransformers.includes(cashuTokens)) {
|
|
31
|
+
textNoteTransformers.push(cashuTokens);
|
|
32
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Transformer } from "unified";
|
|
2
|
+
import { EventTemplate, NostrEvent } from "applesauce-core/helpers/event";
|
|
3
|
+
import { Root } from "../nast/types.js";
|
|
4
|
+
export declare const TextNoteContentSymbol: unique symbol;
|
|
5
|
+
export declare const textNoteTransformers: (() => Transformer<Root>)[];
|
|
6
|
+
/** Parsed and process a note with custom transformers */
|
|
7
|
+
export declare function getParsedContent(event: NostrEvent | EventTemplate | string, content?: string, transformers?: (() => Transformer<Root>)[], cacheKey?: symbol | null | undefined): Root;
|
|
8
|
+
export declare function removeParsedTextContent(event: NostrEvent | EventTemplate): void;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { unified } from "unified";
|
|
2
|
+
import { getOrComputeCachedValue } from "applesauce-core/helpers/cache";
|
|
3
|
+
import { nostrMentions } from "./mentions.js";
|
|
4
|
+
import { emojis } from "./emoji.js";
|
|
5
|
+
import { createEventContentTree } from "./parser.js";
|
|
6
|
+
import { hashtags } from "./hashtag.js";
|
|
7
|
+
import { galleries } from "./gallery.js";
|
|
8
|
+
import { eolMetadata } from "../nast/eol-metadata.js";
|
|
9
|
+
import { links } from "./links.js";
|
|
10
|
+
import { blossomURIs } from "./blossom.js";
|
|
11
|
+
export const TextNoteContentSymbol = Symbol.for("text-note-content");
|
|
12
|
+
// default kind 1 transformers. Optional transformers (like `cashuTokens` and
|
|
13
|
+
// `lightningInvoices`) opt in by appending to this array when their module is
|
|
14
|
+
// imported — see `applesauce-content/text/cashu` and
|
|
15
|
+
// `applesauce-content/text/lightning`.
|
|
16
|
+
export const textNoteTransformers = [
|
|
17
|
+
blossomURIs,
|
|
18
|
+
links,
|
|
19
|
+
nostrMentions,
|
|
20
|
+
galleries,
|
|
21
|
+
emojis,
|
|
22
|
+
hashtags,
|
|
23
|
+
eolMetadata,
|
|
24
|
+
];
|
|
25
|
+
/** Parsed and process a note with custom transformers */
|
|
26
|
+
export function getParsedContent(event, content, transformers = textNoteTransformers, cacheKey = TextNoteContentSymbol) {
|
|
27
|
+
// process strings
|
|
28
|
+
if (typeof event === "string") {
|
|
29
|
+
const processor = unified();
|
|
30
|
+
for (const transformer of transformers) {
|
|
31
|
+
processor.use(transformer);
|
|
32
|
+
}
|
|
33
|
+
return processor.runSync(createEventContentTree(event, content));
|
|
34
|
+
}
|
|
35
|
+
// no caching
|
|
36
|
+
if (!cacheKey) {
|
|
37
|
+
const processor = unified();
|
|
38
|
+
for (const transformer of transformers) {
|
|
39
|
+
processor.use(transformer);
|
|
40
|
+
}
|
|
41
|
+
return processor.runSync(createEventContentTree(event, content));
|
|
42
|
+
}
|
|
43
|
+
return getOrComputeCachedValue(event, cacheKey, () => {
|
|
44
|
+
const processor = unified();
|
|
45
|
+
for (const transformer of transformers) {
|
|
46
|
+
processor.use(transformer);
|
|
47
|
+
}
|
|
48
|
+
return processor.runSync(createEventContentTree(event, content));
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
export function removeParsedTextContent(event) {
|
|
52
|
+
Reflect.deleteProperty(event, TextNoteContentSymbol);
|
|
53
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { getEmojiTag } from "applesauce-common/helpers/emoji";
|
|
2
|
+
import { Tokens } from "applesauce-core/helpers/regexp";
|
|
3
|
+
import { findAndReplace } from "../nast/find-and-replace.js";
|
|
4
|
+
/** Finds and creates emoji nodes in the tree */
|
|
5
|
+
export function emojis() {
|
|
6
|
+
return (tree) => {
|
|
7
|
+
const event = tree.event;
|
|
8
|
+
if (!event)
|
|
9
|
+
return;
|
|
10
|
+
findAndReplace(tree, [
|
|
11
|
+
[
|
|
12
|
+
Tokens.emoji,
|
|
13
|
+
(full, $1) => {
|
|
14
|
+
try {
|
|
15
|
+
const tag = getEmojiTag(event, $1);
|
|
16
|
+
if (!tag)
|
|
17
|
+
return false;
|
|
18
|
+
return {
|
|
19
|
+
type: "emoji",
|
|
20
|
+
tag,
|
|
21
|
+
raw: full,
|
|
22
|
+
code: tag[1].toLowerCase(),
|
|
23
|
+
url: tag[2],
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
catch (error) { }
|
|
27
|
+
return false;
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
]);
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Transformer } from "unified";
|
|
2
|
+
import { Root } from "../nast/types.js";
|
|
3
|
+
export interface GalleriesOptions {
|
|
4
|
+
/** When true, adjacent `blossom:` image URIs are clustered alongside HTTP image links. Defaults to false. */
|
|
5
|
+
includeBlossom?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/** Group images into galleries in an ATS tree */
|
|
8
|
+
export declare function galleries(types?: string[], options?: GalleriesOptions): Transformer<Root>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { convertToUrl, getURLFilename, IMAGE_EXT } from "applesauce-core/helpers/url";
|
|
2
|
+
/** Group images into galleries in an ATS tree */
|
|
3
|
+
export function galleries(types = IMAGE_EXT, options = {}) {
|
|
4
|
+
const { includeBlossom = false } = options;
|
|
5
|
+
return (tree) => {
|
|
6
|
+
let items = [];
|
|
7
|
+
const getItemHref = (item) => (item.type === "link" ? item.href : item.raw);
|
|
8
|
+
const commit = (index) => {
|
|
9
|
+
// only create a gallery if there are more than a single image
|
|
10
|
+
if (items.length > 1) {
|
|
11
|
+
const start = tree.children.indexOf(items[0]);
|
|
12
|
+
const end = tree.children.indexOf(items[items.length - 1]);
|
|
13
|
+
// replace all nodes with a gallery
|
|
14
|
+
tree.children.splice(start, 1 + end - start, { type: "gallery", links: items.map(getItemHref) });
|
|
15
|
+
items = [];
|
|
16
|
+
// return new cursor
|
|
17
|
+
return end - 1;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
items = [];
|
|
21
|
+
return index;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
for (let i = 0; i < tree.children.length; i++) {
|
|
25
|
+
const node = tree.children[i];
|
|
26
|
+
try {
|
|
27
|
+
if (node.type === "link") {
|
|
28
|
+
const url = convertToUrl(node.href);
|
|
29
|
+
const filename = getURLFilename(url);
|
|
30
|
+
if (filename && types.some((ext) => filename.endsWith(ext))) {
|
|
31
|
+
items.push(node);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
i = commit(i);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
else if (node.type === "blossom" && includeBlossom) {
|
|
38
|
+
if (types.some((ext) => ext === `.${node.ext.toLowerCase()}`)) {
|
|
39
|
+
items.push(node);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
i = commit(i);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
else if (node.type === "text" && items.length > 0) {
|
|
46
|
+
const isEmpty = node.value === "\n" || !node.value.match(/[^\s]/g);
|
|
47
|
+
if (!isEmpty)
|
|
48
|
+
i = commit(i);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
i = commit(i);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Do one finally commit, just in case a link is the last element in the list
|
|
56
|
+
commit(tree.children.length);
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { getHashtagTag } from "applesauce-common/helpers/hashtag";
|
|
2
|
+
import { Tokens } from "applesauce-core/helpers/regexp";
|
|
3
|
+
import { findAndReplace } from "../nast/find-and-replace.js";
|
|
4
|
+
/** Find and create hashtag notes in provided tree */
|
|
5
|
+
export function hashtags() {
|
|
6
|
+
return (tree) => {
|
|
7
|
+
const event = tree.event;
|
|
8
|
+
findAndReplace(tree, [
|
|
9
|
+
[
|
|
10
|
+
Tokens.hashtag,
|
|
11
|
+
(_, $1) => {
|
|
12
|
+
try {
|
|
13
|
+
const tag = event && getHashtagTag(event, $1);
|
|
14
|
+
// Skip if the match if no tag was found in the event
|
|
15
|
+
if (!tag && event)
|
|
16
|
+
return false;
|
|
17
|
+
return {
|
|
18
|
+
type: "hashtag",
|
|
19
|
+
tag,
|
|
20
|
+
name: $1,
|
|
21
|
+
hashtag: tag?.[1].toLowerCase() || $1.toLowerCase(),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
catch (error) { }
|
|
25
|
+
return false;
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
]);
|
|
29
|
+
};
|
|
30
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type FileMetadataFields } from "applesauce-common/helpers/file-metadata";
|
|
2
|
+
import { type Transformer } from "unified";
|
|
3
|
+
import { Root } from "../nast/types.js";
|
|
4
|
+
declare module "../nast/types.js" {
|
|
5
|
+
interface Link {
|
|
6
|
+
/** File metadata from a matching NIP-92 `imeta` tag on the event */
|
|
7
|
+
metadata?: FileMetadataFields;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/** Hydrates link nodes with NIP-92 file metadata from matching `imeta` tags on the event */
|
|
11
|
+
export declare function imetaLinks(): Transformer<Root>;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { getMediaAttachments } from "applesauce-common/helpers/file-metadata";
|
|
2
|
+
import { textNoteTransformers } from "./content.js";
|
|
3
|
+
/** Hydrates link nodes with NIP-92 file metadata from matching `imeta` tags on the event */
|
|
4
|
+
export function imetaLinks() {
|
|
5
|
+
return (tree) => {
|
|
6
|
+
const event = tree.event;
|
|
7
|
+
if (!event || !event.tags || event.tags.length === 0)
|
|
8
|
+
return;
|
|
9
|
+
const attachments = getMediaAttachments(event);
|
|
10
|
+
if (attachments.length === 0)
|
|
11
|
+
return;
|
|
12
|
+
// Build a normalized URL -> metadata map so lookups match `link.href` exactly
|
|
13
|
+
const byUrl = new Map();
|
|
14
|
+
for (const attachment of attachments) {
|
|
15
|
+
if (!attachment.url)
|
|
16
|
+
continue;
|
|
17
|
+
try {
|
|
18
|
+
byUrl.set(new URL(attachment.url).toString(), attachment);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
// ignore invalid URLs
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (byUrl.size === 0)
|
|
25
|
+
return;
|
|
26
|
+
for (const node of tree.children) {
|
|
27
|
+
if (node.type !== "link")
|
|
28
|
+
continue;
|
|
29
|
+
const metadata = byUrl.get(node.href);
|
|
30
|
+
if (metadata)
|
|
31
|
+
node.metadata = metadata;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
// Register the imeta transformer in the default text-note pipeline as a side
|
|
36
|
+
// effect of importing this module. Consumers opt-in to imeta link hydration
|
|
37
|
+
// by importing `applesauce-content/text/imeta`.
|
|
38
|
+
if (!textNoteTransformers.includes(imetaLinks)) {
|
|
39
|
+
textNoteTransformers.push(imetaLinks);
|
|
40
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "./blossom.js";
|
|
2
|
+
export * from "./content.js";
|
|
3
|
+
export * from "./emoji.js";
|
|
4
|
+
export * from "./gallery.js";
|
|
5
|
+
export * from "./hashtag.js";
|
|
6
|
+
export * from "./imeta.js";
|
|
7
|
+
export * from "./links.js";
|
|
8
|
+
export * from "./mentions.js";
|
|
9
|
+
export * from "./parser.js";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "./blossom.js";
|
|
2
|
+
export * from "./content.js";
|
|
3
|
+
export * from "./emoji.js";
|
|
4
|
+
export * from "./gallery.js";
|
|
5
|
+
export * from "./hashtag.js";
|
|
6
|
+
export * from "./imeta.js";
|
|
7
|
+
export * from "./links.js";
|
|
8
|
+
export * from "./mentions.js";
|
|
9
|
+
export * from "./parser.js";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type ParsedInvoice } from "applesauce-common/helpers/bolt11";
|
|
2
|
+
import { type Transformer } from "unified";
|
|
3
|
+
import { Node, Root } from "../nast/types.js";
|
|
4
|
+
export interface LightningInvoice extends Node {
|
|
5
|
+
type: "lightning";
|
|
6
|
+
invoice: string;
|
|
7
|
+
parsed: ParsedInvoice;
|
|
8
|
+
}
|
|
9
|
+
declare module "../nast/types.js" {
|
|
10
|
+
interface ContentMap {
|
|
11
|
+
lightning: LightningInvoice;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/** Finds and creates lightning invoice nodes in the tree */
|
|
15
|
+
export declare function lightningInvoices(): Transformer<Root>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { parseBolt11 } from "applesauce-common/helpers/bolt11";
|
|
2
|
+
import { Tokens } from "applesauce-core/helpers/regexp";
|
|
3
|
+
import { findAndReplace } from "../nast/find-and-replace.js";
|
|
4
|
+
import { textNoteTransformers } from "./content.js";
|
|
5
|
+
/** Finds and creates lightning invoice nodes in the tree */
|
|
6
|
+
export function lightningInvoices() {
|
|
7
|
+
return (tree) => {
|
|
8
|
+
findAndReplace(tree, [
|
|
9
|
+
[
|
|
10
|
+
Tokens.lightning,
|
|
11
|
+
(_, $1) => {
|
|
12
|
+
try {
|
|
13
|
+
const invoice = $1;
|
|
14
|
+
const parsed = parseBolt11(invoice);
|
|
15
|
+
return {
|
|
16
|
+
type: "lightning",
|
|
17
|
+
invoice,
|
|
18
|
+
parsed,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
catch (error) { }
|
|
22
|
+
return false;
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
]);
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
// Register the lightning transformer in the default text-note pipeline as a
|
|
29
|
+
// side effect of importing this module. Consumers opt-in to lightning invoice
|
|
30
|
+
// parsing by importing `applesauce-content/text/lightning`.
|
|
31
|
+
if (!textNoteTransformers.includes(lightningInvoices)) {
|
|
32
|
+
textNoteTransformers.push(lightningInvoices);
|
|
33
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Tokens } from "applesauce-core/helpers";
|
|
2
|
+
import { findAndReplace } from "../nast/find-and-replace.js";
|
|
3
|
+
/** Finds and creates web links in the tree */
|
|
4
|
+
export function links() {
|
|
5
|
+
return (tree) => {
|
|
6
|
+
findAndReplace(tree, [
|
|
7
|
+
[
|
|
8
|
+
Tokens.link,
|
|
9
|
+
(_) => {
|
|
10
|
+
try {
|
|
11
|
+
return {
|
|
12
|
+
type: "link",
|
|
13
|
+
href: new URL(_).toString(),
|
|
14
|
+
value: _,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
catch (error) { }
|
|
18
|
+
return false;
|
|
19
|
+
},
|
|
20
|
+
],
|
|
21
|
+
]);
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { decodePointer } from "applesauce-core/helpers/pointers";
|
|
2
|
+
import { Tokens } from "applesauce-core/helpers/regexp";
|
|
3
|
+
import { findAndReplace } from "../nast/find-and-replace.js";
|
|
4
|
+
/** Finds and creates NIP-19 nostr mentions in the tree */
|
|
5
|
+
export function nostrMentions() {
|
|
6
|
+
return (tree) => {
|
|
7
|
+
findAndReplace(tree, [
|
|
8
|
+
[
|
|
9
|
+
Tokens.nostrLink,
|
|
10
|
+
(_, $1) => {
|
|
11
|
+
try {
|
|
12
|
+
return {
|
|
13
|
+
type: "mention",
|
|
14
|
+
decoded: decodePointer($1),
|
|
15
|
+
encoded: $1,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
catch (error) { }
|
|
19
|
+
return false;
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
]);
|
|
23
|
+
};
|
|
24
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { EventTemplate, NostrEvent } from "applesauce-core/helpers/event";
|
|
2
|
+
import { Root } from "../nast/types.js";
|
|
3
|
+
/** Creates a {@link Root} ATS node for a text note */
|
|
4
|
+
export declare function createEventContentTree(event: NostrEvent | EventTemplate | string, content?: string): Root;
|
|
5
|
+
/** @deprecated use createEventContentTree instead */
|
|
6
|
+
export declare const createTextNoteATS: typeof createEventContentTree;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Creates a {@link Root} ATS node for a text note */
|
|
2
|
+
export function createEventContentTree(event, content) {
|
|
3
|
+
return {
|
|
4
|
+
type: "root",
|
|
5
|
+
event: typeof event !== "string" ? event : undefined,
|
|
6
|
+
children: [
|
|
7
|
+
{
|
|
8
|
+
type: "text",
|
|
9
|
+
value: content || (typeof event === "string" ? event : event.content),
|
|
10
|
+
},
|
|
11
|
+
],
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/** @deprecated use createEventContentTree instead */
|
|
15
|
+
export const createTextNoteATS = createEventContentTree;
|
package/package.json
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "applesauce-content",
|
|
3
|
+
"version": "0.0.0-concord-20260710175615",
|
|
4
|
+
"description": "Unified plugins for processing event content",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"nostr"
|
|
10
|
+
],
|
|
11
|
+
"author": "hzrd149",
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"files": [
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"import": "./dist/index.js",
|
|
19
|
+
"require": "./dist/index.js",
|
|
20
|
+
"types": "./dist/index.d.ts"
|
|
21
|
+
},
|
|
22
|
+
"./helpers": {
|
|
23
|
+
"import": "./dist/helpers/index.js",
|
|
24
|
+
"require": "./dist/helpers/index.js",
|
|
25
|
+
"types": "./dist/helpers/index.d.ts"
|
|
26
|
+
},
|
|
27
|
+
"./helpers/*": {
|
|
28
|
+
"import": "./dist/helpers/*.js",
|
|
29
|
+
"require": "./dist/helpers/*.js",
|
|
30
|
+
"types": "./dist/helpers/*.d.ts"
|
|
31
|
+
},
|
|
32
|
+
"./nast": {
|
|
33
|
+
"import": "./dist/nast/index.js",
|
|
34
|
+
"require": "./dist/nast/index.js",
|
|
35
|
+
"types": "./dist/nast/index.d.ts"
|
|
36
|
+
},
|
|
37
|
+
"./markdown": {
|
|
38
|
+
"import": "./dist/markdown/index.js",
|
|
39
|
+
"require": "./dist/markdown/index.js",
|
|
40
|
+
"types": "./dist/markdown/index.d.ts"
|
|
41
|
+
},
|
|
42
|
+
"./markdown/*": {
|
|
43
|
+
"import": "./dist/markdown/*.js",
|
|
44
|
+
"require": "./dist/markdown/*.js",
|
|
45
|
+
"types": "./dist/markdown/*.d.ts"
|
|
46
|
+
},
|
|
47
|
+
"./text": {
|
|
48
|
+
"import": "./dist/text/index.js",
|
|
49
|
+
"require": "./dist/text/index.js",
|
|
50
|
+
"types": "./dist/text/index.d.ts"
|
|
51
|
+
},
|
|
52
|
+
"./text/*": {
|
|
53
|
+
"import": "./dist/text/*.js",
|
|
54
|
+
"require": "./dist/text/*.js",
|
|
55
|
+
"types": "./dist/text/*.d.ts"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"dependencies": {
|
|
59
|
+
"@types/hast": "^3.0.4",
|
|
60
|
+
"@types/mdast": "^4.0.4",
|
|
61
|
+
"@types/unist": "^3.0.3",
|
|
62
|
+
"applesauce-common": "0.0.0-concord-20260710175615",
|
|
63
|
+
"applesauce-core": "0.0.0-concord-20260710175615",
|
|
64
|
+
"mdast-util-find-and-replace": "^3.0.2",
|
|
65
|
+
"remark": "^15.0.1",
|
|
66
|
+
"remark-parse": "^11.0.0",
|
|
67
|
+
"unified": "^11.0.5",
|
|
68
|
+
"unist-util-visit-parents": "^6.0.1"
|
|
69
|
+
},
|
|
70
|
+
"devDependencies": {
|
|
71
|
+
"@cashu/cashu-ts": "^4.5.1",
|
|
72
|
+
"applesauce-signers": "0.0.0-concord-20260710175615",
|
|
73
|
+
"rimraf": "^6.0.1",
|
|
74
|
+
"typescript": "^5.8.3",
|
|
75
|
+
"vitest": "^4.0.15"
|
|
76
|
+
},
|
|
77
|
+
"peerDependencies": {
|
|
78
|
+
"@cashu/cashu-ts": "^4.5.1"
|
|
79
|
+
},
|
|
80
|
+
"peerDependenciesMeta": {
|
|
81
|
+
"@cashu/cashu-ts": {
|
|
82
|
+
"optional": true
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"funding": {
|
|
86
|
+
"type": "lightning",
|
|
87
|
+
"url": "lightning:nostrudel@geyser.fund"
|
|
88
|
+
},
|
|
89
|
+
"scripts": {
|
|
90
|
+
"prebuild": "rimraf dist",
|
|
91
|
+
"build": "tsc",
|
|
92
|
+
"watch:build": "tsc --watch > /dev/null",
|
|
93
|
+
"test": "vitest run --passWithNoTests",
|
|
94
|
+
"watch:test": "vitest"
|
|
95
|
+
}
|
|
96
|
+
}
|