@welshman/content 0.0.1

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 ADDED
@@ -0,0 +1,3 @@
1
+ # @welshman/content [![version](https://badgen.net/npm/v/@welshman/content)](https://npmjs.com/package/@welshman/content)
2
+
3
+ Utilities for parsing note content.
@@ -0,0 +1,247 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.truncate = exports.parse = exports.parseNext = exports.parsers = exports.parseLegacyMention = exports.parseTopic = exports.parseProfile = exports.parseNewline = exports.parseLink = exports.parseInvoice = exports.parseEvent = exports.parseCodeInline = exports.parseCodeBlock = exports.parseCashu = exports.parseAddress = exports.ParsedType = void 0;
4
+ const nostr_tools_1 = require("nostr-tools");
5
+ const last = (xs, ...args) => xs[xs.length - 1];
6
+ const fromNostrURI = (s) => s.replace(/^nostr:\/?\/?/, "");
7
+ var ParsedType;
8
+ (function (ParsedType) {
9
+ ParsedType["Address"] = "address";
10
+ ParsedType["Cashu"] = "cashu";
11
+ ParsedType["CodeBlock"] = "code_block";
12
+ ParsedType["CodeInline"] = "code_inline";
13
+ ParsedType["Ellipsis"] = "ellipsis";
14
+ ParsedType["Event"] = "event";
15
+ ParsedType["Invoice"] = "invoice";
16
+ ParsedType["Link"] = "link";
17
+ ParsedType["Newline"] = "newline";
18
+ ParsedType["Profile"] = "profile";
19
+ ParsedType["Text"] = "text";
20
+ ParsedType["Topic"] = "topic";
21
+ })(ParsedType || (exports.ParsedType = ParsedType = {}));
22
+ // Parsers for known formats
23
+ const parseAddress = (raw, context) => {
24
+ const [naddr] = raw.match(/^(web\+)?(nostr:)?\/?\/?naddr1[\d\w]+/i) || [];
25
+ if (naddr) {
26
+ try {
27
+ const { data } = nostr_tools_1.nip19.decode(fromNostrURI(naddr));
28
+ return { type: ParsedType.Address, value: data, raw };
29
+ }
30
+ catch (e) {
31
+ // Pass
32
+ }
33
+ }
34
+ };
35
+ exports.parseAddress = parseAddress;
36
+ const parseCashu = (raw, context) => {
37
+ const [value] = raw.match(/^(cashu)[\d\w=]{50,5000}/i) || [];
38
+ if (value) {
39
+ return { type: ParsedType.Cashu, value, raw };
40
+ }
41
+ };
42
+ exports.parseCashu = parseCashu;
43
+ const parseCodeBlock = (raw, context) => {
44
+ const [code, value] = raw.match(/^```([^]*?)```/i) || [];
45
+ if (code) {
46
+ return { type: ParsedType.CodeBlock, value, raw };
47
+ }
48
+ };
49
+ exports.parseCodeBlock = parseCodeBlock;
50
+ const parseCodeInline = (raw, context) => {
51
+ const [code, value] = raw.match(/^`(.*?)`/i) || [];
52
+ if (code) {
53
+ return { type: ParsedType.CodeInline, value, raw };
54
+ }
55
+ };
56
+ exports.parseCodeInline = parseCodeInline;
57
+ const parseEvent = (raw, context) => {
58
+ const [entity] = raw.match(/^(web\+)?(nostr:)?\/?\/?n(event|ote)1[\d\w]+/i) || [];
59
+ if (entity) {
60
+ try {
61
+ const { type, data } = nostr_tools_1.nip19.decode(fromNostrURI(entity));
62
+ const value = type === "note"
63
+ ? { id: data, relays: [] }
64
+ : data;
65
+ return { type: ParsedType.Event, value, raw };
66
+ }
67
+ catch (e) {
68
+ // Pass
69
+ }
70
+ }
71
+ };
72
+ exports.parseEvent = parseEvent;
73
+ const parseInvoice = (raw, context) => {
74
+ const [value] = raw.match(/^ln(lnbc|lnurl)[\d\w]{50,1000}/i) || [];
75
+ if (value) {
76
+ return { type: ParsedType.Invoice, value, raw };
77
+ }
78
+ };
79
+ exports.parseInvoice = parseInvoice;
80
+ const parseLink = (raw, context) => {
81
+ var _a;
82
+ const [link] = raw.match(/^([a-z\+:]{2,30}:\/\/)?[^<>\(\)\s]+\.[a-z]{2,6}[^\s]*[^<>"'\.!?,:\s\)\(]/gi) || [];
83
+ if (!link) {
84
+ return;
85
+ }
86
+ const prev = last(context.results);
87
+ // Skip url if it's just the end of a filepath
88
+ if ((prev === null || prev === void 0 ? void 0 : prev.type) === ParsedType.Text && prev.value.endsWith("/")) {
89
+ return;
90
+ }
91
+ // Strip hash component
92
+ let [url, hash] = link.split("#");
93
+ // Skip ellipses and very short non-urls
94
+ if (url.match(/\.\./)) {
95
+ return;
96
+ }
97
+ // Make sure there's a protocol
98
+ if (!url.match("^\w+://")) {
99
+ url = "https://" + url;
100
+ }
101
+ const meta = Object.fromEntries(new URLSearchParams(hash).entries());
102
+ for (const tag of context.tags) {
103
+ if (tag[0] === 'imeta' && tag.find(t => t.includes(`url ${raw}`))) {
104
+ Object.assign(meta, Object.fromEntries(tag.slice(1).map((m) => m.split(" "))));
105
+ }
106
+ }
107
+ const isMedia = Boolean(url.match(/\.(jpe?g|png|wav|mp3|mp4|mov|avi|webm|webp|gif|bmp|svg)$/) &&
108
+ ((_a = last(url.replace(/\/$/, "").split("://"))) === null || _a === void 0 ? void 0 : _a.includes("/")));
109
+ const value = { url, hash, meta, isMedia };
110
+ return { type: ParsedType.Link, value, raw };
111
+ };
112
+ exports.parseLink = parseLink;
113
+ const parseNewline = (raw, context) => {
114
+ const [value] = raw.match(/^\n+/) || [];
115
+ if (value) {
116
+ return { type: ParsedType.Newline, raw, value };
117
+ }
118
+ };
119
+ exports.parseNewline = parseNewline;
120
+ const parseProfile = (raw, context) => {
121
+ const [entity] = raw.match(/^(web\+)?(nostr:)?\/?\/?n(profile|pub)1[\d\w]+/i) || [];
122
+ if (entity) {
123
+ try {
124
+ const { type, data } = nostr_tools_1.nip19.decode(fromNostrURI(entity));
125
+ const value = type === "npub"
126
+ ? { pubkey: data, relays: [] }
127
+ : data;
128
+ return { type: ParsedType.Profile, value, raw };
129
+ }
130
+ catch (e) {
131
+ // Pass
132
+ }
133
+ }
134
+ };
135
+ exports.parseProfile = parseProfile;
136
+ const parseTopic = (raw, context) => {
137
+ const [value] = raw.match(/^#[^\s!\"#$%&'()*+,-.\/:;<=>?@[\\\]^_`{|}~]+/i) || [];
138
+ // Skip numeric topics
139
+ if (value && !value.match(/^#\d+$/)) {
140
+ return { type: ParsedType.Topic, raw, value };
141
+ }
142
+ };
143
+ exports.parseTopic = parseTopic;
144
+ // Parse other formats to known types
145
+ const parseLegacyMention = (raw, context) => {
146
+ const mentionMatch = raw.match(/^#\[(\d+)\]/i) || [];
147
+ if (mentionMatch) {
148
+ const [tag, value, url] = context.tags[parseInt(mentionMatch[1])] || [];
149
+ const relays = url ? [url] : [];
150
+ if (tag === "p") {
151
+ return { type: ParsedType.Profile, value: { pubkey: value, relays }, raw };
152
+ }
153
+ if (tag === "e") {
154
+ return { type: ParsedType.Event, value: { id: value, relays }, raw };
155
+ }
156
+ }
157
+ };
158
+ exports.parseLegacyMention = parseLegacyMention;
159
+ exports.parsers = [
160
+ exports.parseNewline,
161
+ exports.parseLegacyMention,
162
+ exports.parseTopic,
163
+ exports.parseCodeBlock,
164
+ exports.parseCodeInline,
165
+ exports.parseAddress,
166
+ exports.parseProfile,
167
+ exports.parseEvent,
168
+ exports.parseCashu,
169
+ exports.parseInvoice,
170
+ exports.parseLink
171
+ ];
172
+ const parseNext = (raw, context) => {
173
+ for (const parser of exports.parsers) {
174
+ const result = parser(raw, context);
175
+ if (result) {
176
+ return result;
177
+ }
178
+ }
179
+ };
180
+ exports.parseNext = parseNext;
181
+ // Main exports
182
+ const parse = ({ content = "", tags = [] }) => {
183
+ var _a;
184
+ const context = { content, tags, results: [] };
185
+ let buffer = "";
186
+ let remaining = content.trim() || ((_a = tags.find(t => t[0] === "alt")) === null || _a === void 0 ? void 0 : _a[1]) || "";
187
+ while (remaining) {
188
+ const parsed = (0, exports.parseNext)(remaining, context);
189
+ if (parsed) {
190
+ if (buffer) {
191
+ context.results.push({ type: ParsedType.Text, value: buffer, raw: buffer });
192
+ buffer = "";
193
+ }
194
+ context.results.push(parsed);
195
+ remaining = remaining.slice(parsed.raw.length);
196
+ }
197
+ else {
198
+ // Instead of going character by character and re-running all the above regular expressions
199
+ // a million times, try to match the next word and add it to the buffer
200
+ const [match] = remaining.match(/^[\w\d]+ ?/i) || remaining[0];
201
+ buffer += match;
202
+ remaining = remaining.slice(match.length);
203
+ }
204
+ }
205
+ if (buffer) {
206
+ context.results.push({ type: ParsedType.Text, value: buffer, raw: buffer });
207
+ }
208
+ return context.results;
209
+ };
210
+ exports.parse = parse;
211
+ const truncate = (content, { minLength = 400, maxLength = 600, mediaLength = 200, entityLength = 30, }) => {
212
+ // Get a list of content sizes so we know where to truncate
213
+ // Non-plaintext things might take up more or less room if rendered
214
+ const sizes = content.map((parsed) => {
215
+ switch (parsed.type) {
216
+ case ParsedType.Link:
217
+ case ParsedType.Cashu:
218
+ case ParsedType.Invoice:
219
+ return mediaLength;
220
+ case ParsedType.Event:
221
+ case ParsedType.Address:
222
+ case ParsedType.Profile:
223
+ return entityLength;
224
+ default:
225
+ return parsed.value.length;
226
+ }
227
+ });
228
+ // If total size fits inside our max, we're done
229
+ if (sizes.reduce((r, x) => r + x, 0) < maxLength) {
230
+ return content;
231
+ }
232
+ let currentSize = 0;
233
+ // Otherwise, truncate more then necessary so that when the user expands the note
234
+ // they have more than just a tiny bit to look at. Truncating a single word is annoying.
235
+ sizes.every((size, i) => {
236
+ currentSize += size;
237
+ // Don't truncate down to nothing
238
+ if (currentSize > minLength && i > 0) {
239
+ content = content.slice(0, i);
240
+ return false;
241
+ }
242
+ return true;
243
+ });
244
+ return content;
245
+ };
246
+ exports.truncate = truncate;
247
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,127 @@
1
+ type AddressPointer = {
2
+ identifier: string;
3
+ pubkey: string;
4
+ kind: number;
5
+ relays?: string[];
6
+ };
7
+ type EventPointer = {
8
+ id: string;
9
+ relays?: string[];
10
+ author?: string;
11
+ kind?: number;
12
+ };
13
+ type ProfilePointer = {
14
+ pubkey: string;
15
+ relays?: string[];
16
+ };
17
+ export type ParseContext = {
18
+ results: Parsed[];
19
+ content: string;
20
+ tags: string[][];
21
+ };
22
+ export declare enum ParsedType {
23
+ Address = "address",
24
+ Cashu = "cashu",
25
+ CodeBlock = "code_block",
26
+ CodeInline = "code_inline",
27
+ Ellipsis = "ellipsis",
28
+ Event = "event",
29
+ Invoice = "invoice",
30
+ Link = "link",
31
+ Newline = "newline",
32
+ Profile = "profile",
33
+ Text = "text",
34
+ Topic = "topic"
35
+ }
36
+ export type ParsedCashu = {
37
+ type: ParsedType.Cashu;
38
+ value: string;
39
+ raw: string;
40
+ };
41
+ export type ParsedCodeBlock = {
42
+ type: ParsedType.CodeBlock;
43
+ value: string;
44
+ raw: string;
45
+ };
46
+ export type ParsedCodeInline = {
47
+ type: ParsedType.CodeInline;
48
+ value: string;
49
+ raw: string;
50
+ };
51
+ export type ParsedEllipsis = {
52
+ type: ParsedType.Ellipsis;
53
+ value: string;
54
+ raw: string;
55
+ };
56
+ export type ParsedInvoice = {
57
+ type: ParsedType.Invoice;
58
+ value: string;
59
+ raw: string;
60
+ };
61
+ export type ParsedLinkValue = {
62
+ url: string;
63
+ hash: string;
64
+ meta: Record<string, string>;
65
+ isMedia: boolean;
66
+ };
67
+ export type ParsedLink = {
68
+ type: ParsedType.Link;
69
+ value: ParsedLinkValue;
70
+ raw: string;
71
+ };
72
+ export type ParsedNewline = {
73
+ type: ParsedType.Newline;
74
+ value: string;
75
+ raw: string;
76
+ };
77
+ export type ParsedText = {
78
+ type: ParsedType.Text;
79
+ value: string;
80
+ raw: string;
81
+ };
82
+ export type ParsedTopic = {
83
+ type: ParsedType.Topic;
84
+ value: string;
85
+ raw: string;
86
+ };
87
+ export type ParsedEvent = {
88
+ type: ParsedType.Event;
89
+ value: EventPointer;
90
+ raw: string;
91
+ };
92
+ export type ParsedProfile = {
93
+ type: ParsedType.Profile;
94
+ value: ProfilePointer;
95
+ raw: string;
96
+ };
97
+ export type ParsedAddress = {
98
+ type: ParsedType.Address;
99
+ value: AddressPointer;
100
+ raw: string;
101
+ };
102
+ export type Parsed = ParsedAddress | ParsedCashu | ParsedCodeBlock | ParsedCodeInline | ParsedEllipsis | ParsedEvent | ParsedInvoice | ParsedLink | ParsedNewline | ParsedProfile | ParsedText | ParsedTopic;
103
+ export declare const parseAddress: (raw: string, context: ParseContext) => ParsedAddress | void;
104
+ export declare const parseCashu: (raw: string, context: ParseContext) => ParsedCashu | void;
105
+ export declare const parseCodeBlock: (raw: string, context: ParseContext) => ParsedCodeBlock | void;
106
+ export declare const parseCodeInline: (raw: string, context: ParseContext) => ParsedCodeInline | void;
107
+ export declare const parseEvent: (raw: string, context: ParseContext) => ParsedEvent | void;
108
+ export declare const parseInvoice: (raw: string, context: ParseContext) => ParsedInvoice | void;
109
+ export declare const parseLink: (raw: string, context: ParseContext) => ParsedLink | void;
110
+ export declare const parseNewline: (raw: string, context: ParseContext) => ParsedNewline | void;
111
+ export declare const parseProfile: (raw: string, context: ParseContext) => ParsedProfile | void;
112
+ export declare const parseTopic: (raw: string, context: ParseContext) => ParsedTopic | void;
113
+ export declare const parseLegacyMention: (raw: string, context: ParseContext) => ParsedProfile | ParsedEvent | void;
114
+ export declare const parsers: (((raw: string, context: ParseContext) => ParsedAddress | void) | ((raw: string, context: ParseContext) => ParsedCashu | void) | ((raw: string, context: ParseContext) => ParsedCodeBlock | void) | ((raw: string, context: ParseContext) => ParsedCodeInline | void) | ((raw: string, context: ParseContext) => ParsedInvoice | void) | ((raw: string, context: ParseContext) => ParsedLink | void) | ((raw: string, context: ParseContext) => ParsedNewline | void) | ((raw: string, context: ParseContext) => ParsedTopic | void) | ((raw: string, context: ParseContext) => ParsedProfile | ParsedEvent | void))[];
115
+ export declare const parseNext: (raw: string, context: ParseContext) => Parsed | void;
116
+ export declare const parse: ({ content, tags }: {
117
+ content?: string | undefined;
118
+ tags?: string[][] | undefined;
119
+ }) => Parsed[];
120
+ type TruncateOpts = {
121
+ minLength: number;
122
+ maxLength: number;
123
+ mediaLength: number;
124
+ entityLength: number;
125
+ };
126
+ export declare const truncate: (content: Parsed[], { minLength, maxLength, mediaLength, entityLength, }: TruncateOpts) => Parsed[];
127
+ export {};
@@ -0,0 +1,230 @@
1
+ import { nip19 } from "nostr-tools";
2
+ const last = (xs, ...args) => xs[xs.length - 1];
3
+ const fromNostrURI = (s) => s.replace(/^nostr:\/?\/?/, "");
4
+ export var ParsedType;
5
+ (function (ParsedType) {
6
+ ParsedType["Address"] = "address";
7
+ ParsedType["Cashu"] = "cashu";
8
+ ParsedType["CodeBlock"] = "code_block";
9
+ ParsedType["CodeInline"] = "code_inline";
10
+ ParsedType["Ellipsis"] = "ellipsis";
11
+ ParsedType["Event"] = "event";
12
+ ParsedType["Invoice"] = "invoice";
13
+ ParsedType["Link"] = "link";
14
+ ParsedType["Newline"] = "newline";
15
+ ParsedType["Profile"] = "profile";
16
+ ParsedType["Text"] = "text";
17
+ ParsedType["Topic"] = "topic";
18
+ })(ParsedType || (ParsedType = {}));
19
+ // Parsers for known formats
20
+ export const parseAddress = (raw, context) => {
21
+ const [naddr] = raw.match(/^(web\+)?(nostr:)?\/?\/?naddr1[\d\w]+/i) || [];
22
+ if (naddr) {
23
+ try {
24
+ const { data } = nip19.decode(fromNostrURI(naddr));
25
+ return { type: ParsedType.Address, value: data, raw };
26
+ }
27
+ catch (e) {
28
+ // Pass
29
+ }
30
+ }
31
+ };
32
+ export const parseCashu = (raw, context) => {
33
+ const [value] = raw.match(/^(cashu)[\d\w=]{50,5000}/i) || [];
34
+ if (value) {
35
+ return { type: ParsedType.Cashu, value, raw };
36
+ }
37
+ };
38
+ export const parseCodeBlock = (raw, context) => {
39
+ const [code, value] = raw.match(/^```([^]*?)```/i) || [];
40
+ if (code) {
41
+ return { type: ParsedType.CodeBlock, value, raw };
42
+ }
43
+ };
44
+ export const parseCodeInline = (raw, context) => {
45
+ const [code, value] = raw.match(/^`(.*?)`/i) || [];
46
+ if (code) {
47
+ return { type: ParsedType.CodeInline, value, raw };
48
+ }
49
+ };
50
+ export const parseEvent = (raw, context) => {
51
+ const [entity] = raw.match(/^(web\+)?(nostr:)?\/?\/?n(event|ote)1[\d\w]+/i) || [];
52
+ if (entity) {
53
+ try {
54
+ const { type, data } = nip19.decode(fromNostrURI(entity));
55
+ const value = type === "note"
56
+ ? { id: data, relays: [] }
57
+ : data;
58
+ return { type: ParsedType.Event, value, raw };
59
+ }
60
+ catch (e) {
61
+ // Pass
62
+ }
63
+ }
64
+ };
65
+ export const parseInvoice = (raw, context) => {
66
+ const [value] = raw.match(/^ln(lnbc|lnurl)[\d\w]{50,1000}/i) || [];
67
+ if (value) {
68
+ return { type: ParsedType.Invoice, value, raw };
69
+ }
70
+ };
71
+ export const parseLink = (raw, context) => {
72
+ var _a;
73
+ const [link] = raw.match(/^([a-z\+:]{2,30}:\/\/)?[^<>\(\)\s]+\.[a-z]{2,6}[^\s]*[^<>"'\.!?,:\s\)\(]/gi) || [];
74
+ if (!link) {
75
+ return;
76
+ }
77
+ const prev = last(context.results);
78
+ // Skip url if it's just the end of a filepath
79
+ if ((prev === null || prev === void 0 ? void 0 : prev.type) === ParsedType.Text && prev.value.endsWith("/")) {
80
+ return;
81
+ }
82
+ // Strip hash component
83
+ let [url, hash] = link.split("#");
84
+ // Skip ellipses and very short non-urls
85
+ if (url.match(/\.\./)) {
86
+ return;
87
+ }
88
+ // Make sure there's a protocol
89
+ if (!url.match("^\w+://")) {
90
+ url = "https://" + url;
91
+ }
92
+ const meta = Object.fromEntries(new URLSearchParams(hash).entries());
93
+ for (const tag of context.tags) {
94
+ if (tag[0] === 'imeta' && tag.find(t => t.includes(`url ${raw}`))) {
95
+ Object.assign(meta, Object.fromEntries(tag.slice(1).map((m) => m.split(" "))));
96
+ }
97
+ }
98
+ const isMedia = Boolean(url.match(/\.(jpe?g|png|wav|mp3|mp4|mov|avi|webm|webp|gif|bmp|svg)$/) &&
99
+ ((_a = last(url.replace(/\/$/, "").split("://"))) === null || _a === void 0 ? void 0 : _a.includes("/")));
100
+ const value = { url, hash, meta, isMedia };
101
+ return { type: ParsedType.Link, value, raw };
102
+ };
103
+ export const parseNewline = (raw, context) => {
104
+ const [value] = raw.match(/^\n+/) || [];
105
+ if (value) {
106
+ return { type: ParsedType.Newline, raw, value };
107
+ }
108
+ };
109
+ export const parseProfile = (raw, context) => {
110
+ const [entity] = raw.match(/^(web\+)?(nostr:)?\/?\/?n(profile|pub)1[\d\w]+/i) || [];
111
+ if (entity) {
112
+ try {
113
+ const { type, data } = nip19.decode(fromNostrURI(entity));
114
+ const value = type === "npub"
115
+ ? { pubkey: data, relays: [] }
116
+ : data;
117
+ return { type: ParsedType.Profile, value, raw };
118
+ }
119
+ catch (e) {
120
+ // Pass
121
+ }
122
+ }
123
+ };
124
+ export const parseTopic = (raw, context) => {
125
+ const [value] = raw.match(/^#[^\s!\"#$%&'()*+,-.\/:;<=>?@[\\\]^_`{|}~]+/i) || [];
126
+ // Skip numeric topics
127
+ if (value && !value.match(/^#\d+$/)) {
128
+ return { type: ParsedType.Topic, raw, value };
129
+ }
130
+ };
131
+ // Parse other formats to known types
132
+ export const parseLegacyMention = (raw, context) => {
133
+ const mentionMatch = raw.match(/^#\[(\d+)\]/i) || [];
134
+ if (mentionMatch) {
135
+ const [tag, value, url] = context.tags[parseInt(mentionMatch[1])] || [];
136
+ const relays = url ? [url] : [];
137
+ if (tag === "p") {
138
+ return { type: ParsedType.Profile, value: { pubkey: value, relays }, raw };
139
+ }
140
+ if (tag === "e") {
141
+ return { type: ParsedType.Event, value: { id: value, relays }, raw };
142
+ }
143
+ }
144
+ };
145
+ export const parsers = [
146
+ parseNewline,
147
+ parseLegacyMention,
148
+ parseTopic,
149
+ parseCodeBlock,
150
+ parseCodeInline,
151
+ parseAddress,
152
+ parseProfile,
153
+ parseEvent,
154
+ parseCashu,
155
+ parseInvoice,
156
+ parseLink
157
+ ];
158
+ export const parseNext = (raw, context) => {
159
+ for (const parser of parsers) {
160
+ const result = parser(raw, context);
161
+ if (result) {
162
+ return result;
163
+ }
164
+ }
165
+ };
166
+ // Main exports
167
+ export const parse = ({ content = "", tags = [] }) => {
168
+ var _a;
169
+ const context = { content, tags, results: [] };
170
+ let buffer = "";
171
+ let remaining = content.trim() || ((_a = tags.find(t => t[0] === "alt")) === null || _a === void 0 ? void 0 : _a[1]) || "";
172
+ while (remaining) {
173
+ const parsed = parseNext(remaining, context);
174
+ if (parsed) {
175
+ if (buffer) {
176
+ context.results.push({ type: ParsedType.Text, value: buffer, raw: buffer });
177
+ buffer = "";
178
+ }
179
+ context.results.push(parsed);
180
+ remaining = remaining.slice(parsed.raw.length);
181
+ }
182
+ else {
183
+ // Instead of going character by character and re-running all the above regular expressions
184
+ // a million times, try to match the next word and add it to the buffer
185
+ const [match] = remaining.match(/^[\w\d]+ ?/i) || remaining[0];
186
+ buffer += match;
187
+ remaining = remaining.slice(match.length);
188
+ }
189
+ }
190
+ if (buffer) {
191
+ context.results.push({ type: ParsedType.Text, value: buffer, raw: buffer });
192
+ }
193
+ return context.results;
194
+ };
195
+ export const truncate = (content, { minLength = 400, maxLength = 600, mediaLength = 200, entityLength = 30, }) => {
196
+ // Get a list of content sizes so we know where to truncate
197
+ // Non-plaintext things might take up more or less room if rendered
198
+ const sizes = content.map((parsed) => {
199
+ switch (parsed.type) {
200
+ case ParsedType.Link:
201
+ case ParsedType.Cashu:
202
+ case ParsedType.Invoice:
203
+ return mediaLength;
204
+ case ParsedType.Event:
205
+ case ParsedType.Address:
206
+ case ParsedType.Profile:
207
+ return entityLength;
208
+ default:
209
+ return parsed.value.length;
210
+ }
211
+ });
212
+ // If total size fits inside our max, we're done
213
+ if (sizes.reduce((r, x) => r + x, 0) < maxLength) {
214
+ return content;
215
+ }
216
+ let currentSize = 0;
217
+ // Otherwise, truncate more then necessary so that when the user expands the note
218
+ // they have more than just a tiny bit to look at. Truncating a single word is annoying.
219
+ sizes.every((size, i) => {
220
+ currentSize += size;
221
+ // Don't truncate down to nothing
222
+ if (currentSize > minLength && i > 0) {
223
+ content = content.slice(0, i);
224
+ return false;
225
+ }
226
+ return true;
227
+ });
228
+ return content;
229
+ };
230
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@welshman/content",
3
+ "version": "0.0.1",
4
+ "author": "hodlbod",
5
+ "license": "MIT",
6
+ "description": "A collection of utilities for parsing nostr note content.",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "type": "module",
11
+ "files": [
12
+ "build"
13
+ ],
14
+ "types": "./build/index.d.ts",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./build/index.d.ts",
18
+ "import": "./build/index.mjs",
19
+ "require": "./build/index.cjs"
20
+ }
21
+ },
22
+ "scripts": {
23
+ "pub": "npm run lint && npm run build && npm publish",
24
+ "build": "gts clean && tsc-multi",
25
+ "lint": "gts lint",
26
+ "fix": "gts fix"
27
+ },
28
+ "devDependencies": {
29
+ "gts": "^5.0.1",
30
+ "tsc-multi": "^1.1.0",
31
+ "typescript": "~5.1.6"
32
+ },
33
+ "dependencies": {
34
+ "nostr-tools": "^2.7.0"
35
+ }
36
+ }