applesauce-core 0.0.0-next-20250120191411 → 0.0.0-next-20250123205825
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/package.json +1 -1
- package/dist/event-store/common.d.ts +0 -1
- package/dist/event-store/common.js +0 -2
- package/dist/event-store/database.d.ts +0 -64
- package/dist/event-store/database.js +0 -311
- package/dist/event-store/event-store.d.ts +0 -49
- package/dist/event-store/event-store.js +0 -389
- package/dist/event-store/index.d.ts +0 -2
- package/dist/event-store/index.js +0 -2
- package/dist/helpers/bolt11.d.ts +0 -9
- package/dist/helpers/bolt11.js +0 -15
- package/dist/helpers/cache.d.ts +0 -5
- package/dist/helpers/cache.js +0 -17
- package/dist/helpers/comment.d.ts +0 -47
- package/dist/helpers/comment.js +0 -116
- package/dist/helpers/content.d.ts +0 -3
- package/dist/helpers/content.js +0 -8
- package/dist/helpers/delete.d.ts +0 -3
- package/dist/helpers/delete.js +0 -7
- package/dist/helpers/emoji.d.ts +0 -11
- package/dist/helpers/emoji.js +0 -16
- package/dist/helpers/event.d.ts +0 -48
- package/dist/helpers/event.js +0 -105
- package/dist/helpers/external-id.d.ts +0 -29
- package/dist/helpers/external-id.js +0 -20
- package/dist/helpers/file-metadata.d.ts +0 -53
- package/dist/helpers/file-metadata.js +0 -90
- package/dist/helpers/file-metadata.test.d.ts +0 -1
- package/dist/helpers/file-metadata.test.js +0 -103
- package/dist/helpers/filter.d.ts +0 -10
- package/dist/helpers/filter.js +0 -46
- package/dist/helpers/hashtag.d.ts +0 -2
- package/dist/helpers/hashtag.js +0 -7
- package/dist/helpers/hidden-tags.d.ts +0 -48
- package/dist/helpers/hidden-tags.js +0 -108
- package/dist/helpers/hidden-tags.test.d.ts +0 -1
- package/dist/helpers/hidden-tags.test.js +0 -28
- package/dist/helpers/index.d.ts +0 -26
- package/dist/helpers/index.js +0 -26
- package/dist/helpers/json.d.ts +0 -2
- package/dist/helpers/json.js +0 -9
- package/dist/helpers/lnurl.d.ts +0 -4
- package/dist/helpers/lnurl.js +0 -40
- package/dist/helpers/lru.d.ts +0 -32
- package/dist/helpers/lru.js +0 -148
- package/dist/helpers/mailboxes.d.ts +0 -11
- package/dist/helpers/mailboxes.js +0 -36
- package/dist/helpers/mailboxes.test.d.ts +0 -1
- package/dist/helpers/mailboxes.test.js +0 -81
- package/dist/helpers/media-attachment.d.ts +0 -42
- package/dist/helpers/media-attachment.js +0 -72
- package/dist/helpers/media-attachment.test.d.ts +0 -1
- package/dist/helpers/media-attachment.test.js +0 -59
- package/dist/helpers/media-post.d.ts +0 -4
- package/dist/helpers/media-post.js +0 -6
- package/dist/helpers/picture-post.d.ts +0 -4
- package/dist/helpers/picture-post.js +0 -6
- package/dist/helpers/pipe.d.ts +0 -10
- package/dist/helpers/pipe.js +0 -3
- package/dist/helpers/pointers.d.ts +0 -55
- package/dist/helpers/pointers.js +0 -205
- package/dist/helpers/profile.d.ts +0 -20
- package/dist/helpers/profile.js +0 -31
- package/dist/helpers/relays.d.ts +0 -12
- package/dist/helpers/relays.js +0 -31
- package/dist/helpers/string.d.ts +0 -10
- package/dist/helpers/string.js +0 -15
- package/dist/helpers/tags.d.ts +0 -25
- package/dist/helpers/tags.js +0 -42
- package/dist/helpers/tags.test.d.ts +0 -1
- package/dist/helpers/tags.test.js +0 -16
- package/dist/helpers/threading.d.ts +0 -55
- package/dist/helpers/threading.js +0 -94
- package/dist/helpers/threading.test.d.ts +0 -1
- package/dist/helpers/threading.test.js +0 -41
- package/dist/helpers/time.d.ts +0 -2
- package/dist/helpers/time.js +0 -4
- package/dist/helpers/url.d.ts +0 -14
- package/dist/helpers/url.js +0 -30
- package/dist/helpers/zap.d.ts +0 -39
- package/dist/helpers/zap.js +0 -95
- package/dist/index.d.ts +0 -5
- package/dist/index.js +0 -5
- package/dist/logger.d.ts +0 -2
- package/dist/logger.js +0 -2
- package/dist/observable/get-value.d.ts +0 -3
- package/dist/observable/get-value.js +0 -14
- package/dist/observable/index.d.ts +0 -2
- package/dist/observable/index.js +0 -2
- package/dist/observable/share-latest-value.d.ts +0 -8
- package/dist/observable/share-latest-value.js +0 -21
- package/dist/promise/deferred.d.ts +0 -6
- package/dist/promise/deferred.js +0 -15
- package/dist/promise/index.d.ts +0 -1
- package/dist/promise/index.js +0 -1
- package/dist/queries/comment.d.ts +0 -4
- package/dist/queries/comment.js +0 -14
- package/dist/queries/comments.d.ts +0 -4
- package/dist/queries/comments.js +0 -14
- package/dist/queries/index.d.ts +0 -7
- package/dist/queries/index.js +0 -7
- package/dist/queries/mailboxes.d.ts +0 -6
- package/dist/queries/mailboxes.js +0 -13
- package/dist/queries/profile.d.ts +0 -4
- package/dist/queries/profile.js +0 -12
- package/dist/queries/reactions.d.ts +0 -4
- package/dist/queries/reactions.js +0 -19
- package/dist/queries/simple.d.ts +0 -16
- package/dist/queries/simple.js +0 -38
- package/dist/queries/thread.d.ts +0 -25
- package/dist/queries/thread.js +0 -92
- package/dist/queries/zaps.d.ts +0 -5
- package/dist/queries/zaps.js +0 -21
- package/dist/query-store/index.d.ts +0 -57
- package/dist/query-store/index.js +0 -68
package/dist/helpers/event.d.ts
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { NostrEvent, VerifiedEvent } from "nostr-tools";
|
|
2
|
-
export declare const EventUIDSymbol: unique symbol;
|
|
3
|
-
export declare const EventIndexableTagsSymbol: unique symbol;
|
|
4
|
-
export declare const FromCacheSymbol: unique symbol;
|
|
5
|
-
export declare const ReplaceableIdentifierSymbol: unique symbol;
|
|
6
|
-
declare module "nostr-tools" {
|
|
7
|
-
interface Event {
|
|
8
|
-
[EventUIDSymbol]?: string;
|
|
9
|
-
[EventIndexableTagsSymbol]?: Set<string>;
|
|
10
|
-
[FromCacheSymbol]?: boolean;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Checks if an object is a nostr event
|
|
15
|
-
* NOTE: does not validation the signature on the event
|
|
16
|
-
*/
|
|
17
|
-
export declare function isEvent(event: any): event is NostrEvent;
|
|
18
|
-
/**
|
|
19
|
-
* Returns if a kind is replaceable ( 10000 <= n < 20000 || n == 0 || n == 3 )
|
|
20
|
-
* or parameterized replaceable ( 30000 <= n < 40000 )
|
|
21
|
-
*/
|
|
22
|
-
export declare function isReplaceable(kind: number): boolean;
|
|
23
|
-
/**
|
|
24
|
-
* Returns the events Unique ID
|
|
25
|
-
* For normal or ephemeral events this is ( event.id )
|
|
26
|
-
* For replaceable events this is ( event.kind + ":" + event.pubkey )
|
|
27
|
-
* For parametrized replaceable events this is ( event.kind + ":" + event.pubkey + ":" + event.tags.d.1 )
|
|
28
|
-
*/
|
|
29
|
-
export declare function getEventUID(event: NostrEvent): string;
|
|
30
|
-
export declare function getReplaceableUID(kind: number, pubkey: string, d?: string): string;
|
|
31
|
-
/** Returns a Set of tag names and values that are indexable */
|
|
32
|
-
export declare function getIndexableTags(event: NostrEvent): Set<string>;
|
|
33
|
-
/**
|
|
34
|
-
* Returns the second index ( tag[1] ) of the first tag that matches the name
|
|
35
|
-
* If the event has any hidden tags they will be searched first
|
|
36
|
-
*/
|
|
37
|
-
export declare function getTagValue(event: NostrEvent, name: string): string | undefined;
|
|
38
|
-
/** Sets events verified flag without checking anything */
|
|
39
|
-
export declare function fakeVerifyEvent(event: NostrEvent): event is VerifiedEvent;
|
|
40
|
-
/** Marks an event as being from a cache */
|
|
41
|
-
export declare function markFromCache(event: NostrEvent): void;
|
|
42
|
-
/** Returns if an event was from a cache */
|
|
43
|
-
export declare function isFromCache(event: NostrEvent): boolean;
|
|
44
|
-
/**
|
|
45
|
-
* Returns the replaceable identifier for a replaceable event
|
|
46
|
-
* @throws
|
|
47
|
-
*/
|
|
48
|
-
export declare function getReplaceableIdentifier(event: NostrEvent): string;
|
package/dist/helpers/event.js
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
import { kinds, verifiedSymbol } from "nostr-tools";
|
|
2
|
-
import { INDEXABLE_TAGS } from "../event-store/common.js";
|
|
3
|
-
import { getHiddenTags } from "./hidden-tags.js";
|
|
4
|
-
import { getOrComputeCachedValue } from "./cache.js";
|
|
5
|
-
import { isParameterizedReplaceableKind } from "nostr-tools/kinds";
|
|
6
|
-
export const EventUIDSymbol = Symbol.for("event-uid");
|
|
7
|
-
export const EventIndexableTagsSymbol = Symbol.for("indexable-tags");
|
|
8
|
-
export const FromCacheSymbol = Symbol.for("from-cache");
|
|
9
|
-
export const ReplaceableIdentifierSymbol = Symbol.for("replaceable-identifier");
|
|
10
|
-
/**
|
|
11
|
-
* Checks if an object is a nostr event
|
|
12
|
-
* NOTE: does not validation the signature on the event
|
|
13
|
-
*/
|
|
14
|
-
export function isEvent(event) {
|
|
15
|
-
if (event === undefined || event === null)
|
|
16
|
-
return false;
|
|
17
|
-
return (event.id?.length === 64 &&
|
|
18
|
-
typeof event.sig === "string" &&
|
|
19
|
-
typeof event.pubkey === "string" &&
|
|
20
|
-
event.pubkey.length === 64 &&
|
|
21
|
-
typeof event.content === "string" &&
|
|
22
|
-
Array.isArray(event.tags) &&
|
|
23
|
-
typeof event.created_at === "number" &&
|
|
24
|
-
event.created_at > 0);
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Returns if a kind is replaceable ( 10000 <= n < 20000 || n == 0 || n == 3 )
|
|
28
|
-
* or parameterized replaceable ( 30000 <= n < 40000 )
|
|
29
|
-
*/
|
|
30
|
-
export function isReplaceable(kind) {
|
|
31
|
-
return kinds.isReplaceableKind(kind) || kinds.isParameterizedReplaceableKind(kind);
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Returns the events Unique ID
|
|
35
|
-
* For normal or ephemeral events this is ( event.id )
|
|
36
|
-
* For replaceable events this is ( event.kind + ":" + event.pubkey )
|
|
37
|
-
* For parametrized replaceable events this is ( event.kind + ":" + event.pubkey + ":" + event.tags.d.1 )
|
|
38
|
-
*/
|
|
39
|
-
export function getEventUID(event) {
|
|
40
|
-
let id = event[EventUIDSymbol];
|
|
41
|
-
if (!id) {
|
|
42
|
-
if (isReplaceable(event.kind)) {
|
|
43
|
-
const d = event.tags.find((t) => t[0] === "d")?.[1];
|
|
44
|
-
id = getReplaceableUID(event.kind, event.pubkey, d);
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
id = event.id;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
return id;
|
|
51
|
-
}
|
|
52
|
-
export function getReplaceableUID(kind, pubkey, d) {
|
|
53
|
-
return d ? `${kind}:${pubkey}:${d}` : `${kind}:${pubkey}`;
|
|
54
|
-
}
|
|
55
|
-
/** Returns a Set of tag names and values that are indexable */
|
|
56
|
-
export function getIndexableTags(event) {
|
|
57
|
-
let indexable = event[EventIndexableTagsSymbol];
|
|
58
|
-
if (!indexable) {
|
|
59
|
-
const tags = new Set();
|
|
60
|
-
for (const tag of event.tags) {
|
|
61
|
-
if (tag[0] && INDEXABLE_TAGS.has(tag[0]) && tag[1]) {
|
|
62
|
-
tags.add(tag[0] + ":" + tag[1]);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
indexable = event[EventIndexableTagsSymbol] = tags;
|
|
66
|
-
}
|
|
67
|
-
return indexable;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Returns the second index ( tag[1] ) of the first tag that matches the name
|
|
71
|
-
* If the event has any hidden tags they will be searched first
|
|
72
|
-
*/
|
|
73
|
-
export function getTagValue(event, name) {
|
|
74
|
-
const hidden = getHiddenTags(event);
|
|
75
|
-
const hiddenValue = hidden?.find((t) => t[0] === name)?.[1];
|
|
76
|
-
if (hiddenValue)
|
|
77
|
-
return hiddenValue;
|
|
78
|
-
return event.tags.find((t) => t[0] === name)?.[1];
|
|
79
|
-
}
|
|
80
|
-
/** Sets events verified flag without checking anything */
|
|
81
|
-
export function fakeVerifyEvent(event) {
|
|
82
|
-
return (event[verifiedSymbol] = true);
|
|
83
|
-
}
|
|
84
|
-
/** Marks an event as being from a cache */
|
|
85
|
-
export function markFromCache(event) {
|
|
86
|
-
event[FromCacheSymbol] = true;
|
|
87
|
-
}
|
|
88
|
-
/** Returns if an event was from a cache */
|
|
89
|
-
export function isFromCache(event) {
|
|
90
|
-
return !!event[FromCacheSymbol];
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Returns the replaceable identifier for a replaceable event
|
|
94
|
-
* @throws
|
|
95
|
-
*/
|
|
96
|
-
export function getReplaceableIdentifier(event) {
|
|
97
|
-
if (!isParameterizedReplaceableKind(event.kind))
|
|
98
|
-
throw new Error("Event is not replaceable");
|
|
99
|
-
return getOrComputeCachedValue(event, ReplaceableIdentifierSymbol, () => {
|
|
100
|
-
const d = getTagValue(event, "d");
|
|
101
|
-
if (d === undefined)
|
|
102
|
-
throw new Error("Event missing identifier");
|
|
103
|
-
return d;
|
|
104
|
-
});
|
|
105
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
export type ExternalIdentifiers = {
|
|
2
|
-
"#": `#${string}`;
|
|
3
|
-
geo: `geo:${string}`;
|
|
4
|
-
isbn: `isbn:${string}`;
|
|
5
|
-
"podcast:guid": `podcast:guid:${string}`;
|
|
6
|
-
"podcast:item:guid": `podcast:item:guid:${string}`;
|
|
7
|
-
"podcast:publisher:guid": `podcast:publisher:guid:${string}`;
|
|
8
|
-
isan: `isan:${string}`;
|
|
9
|
-
doi: `doi:${string}`;
|
|
10
|
-
};
|
|
11
|
-
export type ExternalPointer<Prefix extends keyof ExternalIdentifiers> = {
|
|
12
|
-
kind: Prefix;
|
|
13
|
-
identifier: ExternalIdentifiers[Prefix];
|
|
14
|
-
};
|
|
15
|
-
export type ParseResult = {
|
|
16
|
-
[P in keyof ExternalIdentifiers]: ExternalPointer<P>;
|
|
17
|
-
}[keyof ExternalIdentifiers];
|
|
18
|
-
/**
|
|
19
|
-
* Parses a NIP-73 external identifier
|
|
20
|
-
* @throws
|
|
21
|
-
*/
|
|
22
|
-
export declare function parseExternalPointer<Prefix extends keyof ExternalIdentifiers>(identifier: `${Prefix}1${string}`): ExternalPointer<Prefix>;
|
|
23
|
-
export declare function parseExternalPointer(identifier: string): ParseResult;
|
|
24
|
-
/**
|
|
25
|
-
* Gets an ExternalPointer for a "i" tag
|
|
26
|
-
* @throws
|
|
27
|
-
*/
|
|
28
|
-
export declare function getExternalPointerFromTag<Prefix extends keyof ExternalIdentifiers>(tag: string[]): ExternalPointer<Prefix>;
|
|
29
|
-
export declare function getExternalPointerFromTag(tag: string[]): ParseResult;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export function parseExternalPointer(identifier) {
|
|
2
|
-
if (identifier.startsWith("#"))
|
|
3
|
-
return { kind: "#", identifier: identifier };
|
|
4
|
-
if (identifier.startsWith("geo:"))
|
|
5
|
-
return { kind: "geo", identifier: identifier };
|
|
6
|
-
if (identifier.startsWith("podcast:guid:"))
|
|
7
|
-
return { kind: "podcast:guid", identifier: identifier };
|
|
8
|
-
if (identifier.startsWith("podcast:item:guid:"))
|
|
9
|
-
return { kind: "podcast:item:guid", identifier: identifier };
|
|
10
|
-
if (identifier.startsWith("podcast:publisher:guid:"))
|
|
11
|
-
return { kind: "podcast:publisher:guid", identifier: identifier };
|
|
12
|
-
if (identifier.startsWith("isan:"))
|
|
13
|
-
return { kind: "isan", identifier: identifier };
|
|
14
|
-
if (identifier.startsWith("doi:"))
|
|
15
|
-
return { kind: "doi", identifier: identifier };
|
|
16
|
-
throw new Error("Failed to parse external identifier");
|
|
17
|
-
}
|
|
18
|
-
export function getExternalPointerFromTag(tag) {
|
|
19
|
-
return parseExternalPointer(tag[1]);
|
|
20
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import { NostrEvent } from "nostr-tools";
|
|
2
|
-
export type FileMetadata = {
|
|
3
|
-
/** URL of the file */
|
|
4
|
-
url: string;
|
|
5
|
-
/** MIME type */
|
|
6
|
-
type?: string;
|
|
7
|
-
/** sha256 hash of the file */
|
|
8
|
-
sha256?: string;
|
|
9
|
-
/**
|
|
10
|
-
* The original sha256 hash before the file was transformed
|
|
11
|
-
* @deprecated
|
|
12
|
-
*/
|
|
13
|
-
originalSha256?: string;
|
|
14
|
-
/** size of the file in bytes */
|
|
15
|
-
size?: number;
|
|
16
|
-
/** size of file in pixels in the form <width>x<height> */
|
|
17
|
-
dimensions?: string;
|
|
18
|
-
/** magnet */
|
|
19
|
-
magnet?: string;
|
|
20
|
-
/** torrent infohash */
|
|
21
|
-
infohash?: string;
|
|
22
|
-
/** URL to a thumbnail */
|
|
23
|
-
thumbnail?: string;
|
|
24
|
-
/** URL to a preview image with the same dimensions */
|
|
25
|
-
image?: string;
|
|
26
|
-
/** summary */
|
|
27
|
-
summary?: string;
|
|
28
|
-
/** description for accessability */
|
|
29
|
-
alt?: string;
|
|
30
|
-
/** blurhash */
|
|
31
|
-
blurhash?: string;
|
|
32
|
-
/** fallback URLs */
|
|
33
|
-
fallback?: string[];
|
|
34
|
-
};
|
|
35
|
-
export type MediaAttachment = FileMetadata;
|
|
36
|
-
/**
|
|
37
|
-
* Parses file metadata tags into {@link FileMetadata}
|
|
38
|
-
* @throws
|
|
39
|
-
*/
|
|
40
|
-
export declare function parseFileMetadataTags(tags: string[][]): FileMetadata;
|
|
41
|
-
/**
|
|
42
|
-
* Parses a imeta tag into a {@link FileMetadata}
|
|
43
|
-
* @throws
|
|
44
|
-
*/
|
|
45
|
-
export declare function getFileMetadataFromImetaTag(tag: string[]): FileMetadata;
|
|
46
|
-
export declare const MediaAttachmentsSymbol: unique symbol;
|
|
47
|
-
/** Gets all the media attachments on an event */
|
|
48
|
-
export declare function getMediaAttachments(event: NostrEvent): FileMetadata[];
|
|
49
|
-
/**
|
|
50
|
-
* Gets {@link FileMetadata} for a NIP-94 kind 1063 event
|
|
51
|
-
* @throws
|
|
52
|
-
*/
|
|
53
|
-
export declare function getFileMetadata(file: NostrEvent): FileMetadata;
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { getOrComputeCachedValue } from "./cache.js";
|
|
2
|
-
/**
|
|
3
|
-
* Parses file metadata tags into {@link FileMetadata}
|
|
4
|
-
* @throws
|
|
5
|
-
*/
|
|
6
|
-
export function parseFileMetadataTags(tags) {
|
|
7
|
-
const fields = {};
|
|
8
|
-
let fallback = undefined;
|
|
9
|
-
for (const [name, value] of tags) {
|
|
10
|
-
switch (name) {
|
|
11
|
-
case "fallback":
|
|
12
|
-
fallback = fallback ? [...fallback, value] : [value];
|
|
13
|
-
break;
|
|
14
|
-
default:
|
|
15
|
-
fields[name] = value;
|
|
16
|
-
break;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
if (!fields.url)
|
|
20
|
-
throw new Error("Missing required url in file metadata");
|
|
21
|
-
const metadata = { url: fields.url, fallback };
|
|
22
|
-
// parse size
|
|
23
|
-
if (fields.size)
|
|
24
|
-
metadata.size = parseInt(fields.size);
|
|
25
|
-
// copy optional fields
|
|
26
|
-
if (fields.m)
|
|
27
|
-
metadata.type = fields.m;
|
|
28
|
-
if (fields.x)
|
|
29
|
-
metadata.sha256 = fields.x;
|
|
30
|
-
if (fields.ox)
|
|
31
|
-
metadata.originalSha256 = fields.ox;
|
|
32
|
-
if (fields.dim)
|
|
33
|
-
metadata.dimensions = fields.dim;
|
|
34
|
-
if (fields.magnet)
|
|
35
|
-
metadata.magnet = fields.magnet;
|
|
36
|
-
if (fields.i)
|
|
37
|
-
metadata.infohash = fields.i;
|
|
38
|
-
if (fields.thumb)
|
|
39
|
-
metadata.thumbnail = fields.thumb;
|
|
40
|
-
if (fields.image)
|
|
41
|
-
metadata.image = fields.image;
|
|
42
|
-
if (fields.summary)
|
|
43
|
-
metadata.summary = fields.summary;
|
|
44
|
-
if (fields.alt)
|
|
45
|
-
metadata.alt = fields.alt;
|
|
46
|
-
if (fields.blurhash)
|
|
47
|
-
metadata.blurhash = fields.blurhash;
|
|
48
|
-
return metadata;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Parses a imeta tag into a {@link FileMetadata}
|
|
52
|
-
* @throws
|
|
53
|
-
*/
|
|
54
|
-
export function getFileMetadataFromImetaTag(tag) {
|
|
55
|
-
const parts = tag.slice(1);
|
|
56
|
-
const tags = [];
|
|
57
|
-
for (const part of parts) {
|
|
58
|
-
const match = part.match(/^(.+?)\s(.+)$/);
|
|
59
|
-
if (match) {
|
|
60
|
-
const [_, name, value] = match;
|
|
61
|
-
tags.push([name, value]);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
return parseFileMetadataTags(tags);
|
|
65
|
-
}
|
|
66
|
-
export const MediaAttachmentsSymbol = Symbol.for("media-attachments");
|
|
67
|
-
/** Gets all the media attachments on an event */
|
|
68
|
-
export function getMediaAttachments(event) {
|
|
69
|
-
return getOrComputeCachedValue(event, MediaAttachmentsSymbol, () => {
|
|
70
|
-
return event.tags
|
|
71
|
-
.filter((t) => t[0] === "imeta")
|
|
72
|
-
.map((tag) => {
|
|
73
|
-
try {
|
|
74
|
-
return getFileMetadataFromImetaTag(tag);
|
|
75
|
-
}
|
|
76
|
-
catch (error) {
|
|
77
|
-
// ignore invalid attachments
|
|
78
|
-
return undefined;
|
|
79
|
-
}
|
|
80
|
-
})
|
|
81
|
-
.filter((a) => !!a);
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Gets {@link FileMetadata} for a NIP-94 kind 1063 event
|
|
86
|
-
* @throws
|
|
87
|
-
*/
|
|
88
|
-
export function getFileMetadata(file) {
|
|
89
|
-
return parseFileMetadataTags(file.tags);
|
|
90
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "vitest";
|
|
2
|
-
import { getFileMetadataFromImetaTag, parseFileMetadataTags } from "./file-metadata.js";
|
|
3
|
-
describe("file metadata helpers", () => {
|
|
4
|
-
describe("parseFileMetadataTags", () => {
|
|
5
|
-
it("should parse a simple 1060 event", () => {
|
|
6
|
-
const tags = [
|
|
7
|
-
["url", "https://image.nostr.build/30696696e57a2732d4e9f1b15ff4d4d4eaa64b759df6876863f436ff5d736eae.gif"],
|
|
8
|
-
["ox", "30696696e57a2732d4e9f1b15ff4d4d4eaa64b759df6876863f436ff5d736eae"],
|
|
9
|
-
["fallback", "https://media.tenor.com/wpvrkjn192gAAAAC/daenerys-targaryen.gif"],
|
|
10
|
-
["x", "77fcf42b2b720babcdbe686eff67273d8a68862d74a2672db672bc48439a3ea5"],
|
|
11
|
-
["m", "image/gif"],
|
|
12
|
-
["dim", "360x306"],
|
|
13
|
-
["bh", "L38zleNL00~W^kRj0L-p0KM_^kx]"],
|
|
14
|
-
["blurhash", "L38zleNL00~W^kRj0L-p0KM_^kx]"],
|
|
15
|
-
[
|
|
16
|
-
"thumb",
|
|
17
|
-
"https://image.nostr.build/thumb/30696696e57a2732d4e9f1b15ff4d4d4eaa64b759df6876863f436ff5d736eae.gif",
|
|
18
|
-
],
|
|
19
|
-
["t", "gifbuddy"],
|
|
20
|
-
["summary", "Khaleesi call dragons Daenerys Targaryen"],
|
|
21
|
-
["alt", "a woman with blonde hair and a brooch on her shoulder"],
|
|
22
|
-
[
|
|
23
|
-
"thumb",
|
|
24
|
-
"https://media.tenor.com/wpvrkjn192gAAAAx/daenerys-targaryen.webp",
|
|
25
|
-
"5d92423664fc15874b1d26c70a05a541ec09b5c438bf157977a87c8e64b31463",
|
|
26
|
-
],
|
|
27
|
-
[
|
|
28
|
-
"image",
|
|
29
|
-
"https://media.tenor.com/wpvrkjn192gAAAAe/daenerys-targaryen.png",
|
|
30
|
-
"5d92423664fc15874b1d26c70a05a541ec09b5c438bf157977a87c8e64b31463",
|
|
31
|
-
],
|
|
32
|
-
];
|
|
33
|
-
expect(parseFileMetadataTags(tags)).toEqual({
|
|
34
|
-
url: "https://image.nostr.build/30696696e57a2732d4e9f1b15ff4d4d4eaa64b759df6876863f436ff5d736eae.gif",
|
|
35
|
-
type: "image/gif",
|
|
36
|
-
dimensions: "360x306",
|
|
37
|
-
blurhash: "L38zleNL00~W^kRj0L-p0KM_^kx]",
|
|
38
|
-
sha256: "77fcf42b2b720babcdbe686eff67273d8a68862d74a2672db672bc48439a3ea5",
|
|
39
|
-
originalSha256: "30696696e57a2732d4e9f1b15ff4d4d4eaa64b759df6876863f436ff5d736eae",
|
|
40
|
-
thumbnail: "https://media.tenor.com/wpvrkjn192gAAAAx/daenerys-targaryen.webp",
|
|
41
|
-
image: "https://media.tenor.com/wpvrkjn192gAAAAe/daenerys-targaryen.png",
|
|
42
|
-
summary: "Khaleesi call dragons Daenerys Targaryen",
|
|
43
|
-
fallback: ["https://media.tenor.com/wpvrkjn192gAAAAC/daenerys-targaryen.gif"],
|
|
44
|
-
alt: "a woman with blonde hair and a brooch on her shoulder",
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
describe("getFileMetadataFromImetaTag", () => {
|
|
49
|
-
it("should parse simple imeta tag", () => {
|
|
50
|
-
expect(getFileMetadataFromImetaTag([
|
|
51
|
-
"imeta",
|
|
52
|
-
"url https://blossom.primal.net/3f4dbf2797ac4e90b00bcfe2728e5c8367ed909c48230ac454cc325f1993646c.jpg",
|
|
53
|
-
"x 3f4dbf2797ac4e90b00bcfe2728e5c8367ed909c48230ac454cc325f1993646c",
|
|
54
|
-
"dim 1024x1024",
|
|
55
|
-
"m image/jpeg",
|
|
56
|
-
"blurhash ggH{Aws:RPWBRjaeay?^ozV@aeRjaej[$gt7kCofWVofkCrrofxuofa|ozbHx]s:tRofaet7ay",
|
|
57
|
-
])).toEqual({
|
|
58
|
-
url: "https://blossom.primal.net/3f4dbf2797ac4e90b00bcfe2728e5c8367ed909c48230ac454cc325f1993646c.jpg",
|
|
59
|
-
sha256: "3f4dbf2797ac4e90b00bcfe2728e5c8367ed909c48230ac454cc325f1993646c",
|
|
60
|
-
dimensions: "1024x1024",
|
|
61
|
-
type: "image/jpeg",
|
|
62
|
-
blurhash: "ggH{Aws:RPWBRjaeay?^ozV@aeRjaej[$gt7kCofWVofkCrrofxuofa|ozbHx]s:tRofaet7ay",
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
it("should parse thumbnail url", () => {
|
|
66
|
-
expect(getFileMetadataFromImetaTag([
|
|
67
|
-
"imeta",
|
|
68
|
-
"url https://blossom.primal.net/3f4dbf2797ac4e90b00bcfe2728e5c8367ed909c48230ac454cc325f1993646c.jpg",
|
|
69
|
-
"x 3f4dbf2797ac4e90b00bcfe2728e5c8367ed909c48230ac454cc325f1993646c",
|
|
70
|
-
"dim 1024x1024",
|
|
71
|
-
"m image/jpeg",
|
|
72
|
-
"blurhash ggH{Aws:RPWBRjaeay?^ozV@aeRjaej[$gt7kCofWVofkCrrofxuofa|ozbHx]s:tRofaet7ay",
|
|
73
|
-
"thumb https://exmaple.com/thumb.jpg",
|
|
74
|
-
])).toEqual({
|
|
75
|
-
url: "https://blossom.primal.net/3f4dbf2797ac4e90b00bcfe2728e5c8367ed909c48230ac454cc325f1993646c.jpg",
|
|
76
|
-
sha256: "3f4dbf2797ac4e90b00bcfe2728e5c8367ed909c48230ac454cc325f1993646c",
|
|
77
|
-
dimensions: "1024x1024",
|
|
78
|
-
type: "image/jpeg",
|
|
79
|
-
blurhash: "ggH{Aws:RPWBRjaeay?^ozV@aeRjaej[$gt7kCofWVofkCrrofxuofa|ozbHx]s:tRofaet7ay",
|
|
80
|
-
thumbnail: "https://exmaple.com/thumb.jpg",
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
it("should parse multiple fallback urls", () => {
|
|
84
|
-
expect(getFileMetadataFromImetaTag([
|
|
85
|
-
"imeta",
|
|
86
|
-
"url https://blossom.primal.net/3f4dbf2797ac4e90b00bcfe2728e5c8367ed909c48230ac454cc325f1993646c.jpg",
|
|
87
|
-
"x 3f4dbf2797ac4e90b00bcfe2728e5c8367ed909c48230ac454cc325f1993646c",
|
|
88
|
-
"dim 1024x1024",
|
|
89
|
-
"m image/jpeg",
|
|
90
|
-
"blurhash ggH{Aws:RPWBRjaeay?^ozV@aeRjaej[$gt7kCofWVofkCrrofxuofa|ozbHx]s:tRofaet7ay",
|
|
91
|
-
"fallback https://exmaple.com/image2.jpg",
|
|
92
|
-
"fallback https://exmaple.com/image3.jpg",
|
|
93
|
-
])).toEqual({
|
|
94
|
-
url: "https://blossom.primal.net/3f4dbf2797ac4e90b00bcfe2728e5c8367ed909c48230ac454cc325f1993646c.jpg",
|
|
95
|
-
sha256: "3f4dbf2797ac4e90b00bcfe2728e5c8367ed909c48230ac454cc325f1993646c",
|
|
96
|
-
dimensions: "1024x1024",
|
|
97
|
-
type: "image/jpeg",
|
|
98
|
-
blurhash: "ggH{Aws:RPWBRjaeay?^ozV@aeRjaej[$gt7kCofWVofkCrrofxuofa|ozbHx]s:tRofaet7ay",
|
|
99
|
-
fallback: ["https://exmaple.com/image2.jpg", "https://exmaple.com/image3.jpg"],
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
});
|
package/dist/helpers/filter.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { Filter, NostrEvent } from "nostr-tools";
|
|
2
|
-
/**
|
|
3
|
-
* Copied from nostr-tools and modified to use getIndexableTags
|
|
4
|
-
* @see https://github.com/nbd-wtf/nostr-tools/blob/a61cde77eacc9518001f11d7f67f1a50ae05fd80/filter.ts
|
|
5
|
-
*/
|
|
6
|
-
export declare function matchFilter(filter: Filter, event: NostrEvent): boolean;
|
|
7
|
-
/** Copied from nostr-tools */
|
|
8
|
-
export declare function matchFilters(filters: Filter[], event: NostrEvent): boolean;
|
|
9
|
-
/** Check if two filters are equal */
|
|
10
|
-
export declare function isFilterEqual(a: Filter | Filter[], b: Filter | Filter[]): boolean;
|
package/dist/helpers/filter.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { getIndexableTags } from "./event.js";
|
|
2
|
-
import equal from "fast-deep-equal";
|
|
3
|
-
/**
|
|
4
|
-
* Copied from nostr-tools and modified to use getIndexableTags
|
|
5
|
-
* @see https://github.com/nbd-wtf/nostr-tools/blob/a61cde77eacc9518001f11d7f67f1a50ae05fd80/filter.ts
|
|
6
|
-
*/
|
|
7
|
-
export function matchFilter(filter, event) {
|
|
8
|
-
if (filter.ids && filter.ids.indexOf(event.id) === -1) {
|
|
9
|
-
return false;
|
|
10
|
-
}
|
|
11
|
-
if (filter.kinds && filter.kinds.indexOf(event.kind) === -1) {
|
|
12
|
-
return false;
|
|
13
|
-
}
|
|
14
|
-
if (filter.authors && filter.authors.indexOf(event.pubkey) === -1) {
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
17
|
-
for (let f in filter) {
|
|
18
|
-
if (f[0] === "#") {
|
|
19
|
-
let tagName = f.slice(1);
|
|
20
|
-
let values = filter[`#${tagName}`];
|
|
21
|
-
if (values) {
|
|
22
|
-
const tags = getIndexableTags(event);
|
|
23
|
-
if (values.some((v) => tags.has(tagName + ":" + v)) === false)
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
if (filter.since && event.created_at < filter.since)
|
|
29
|
-
return false;
|
|
30
|
-
if (filter.until && event.created_at > filter.until)
|
|
31
|
-
return false;
|
|
32
|
-
return true;
|
|
33
|
-
}
|
|
34
|
-
/** Copied from nostr-tools */
|
|
35
|
-
export function matchFilters(filters, event) {
|
|
36
|
-
for (let i = 0; i < filters.length; i++) {
|
|
37
|
-
if (matchFilter(filters[i], event)) {
|
|
38
|
-
return true;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
/** Check if two filters are equal */
|
|
44
|
-
export function isFilterEqual(a, b) {
|
|
45
|
-
return equal(a, b);
|
|
46
|
-
}
|
package/dist/helpers/hashtag.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { stripInvisibleChar } from "./string.js";
|
|
2
|
-
export function getHashtagTag(event, hashtag) {
|
|
3
|
-
hashtag = stripInvisibleChar(hashtag.replace(/^#/, "").toLocaleLowerCase());
|
|
4
|
-
return event.tags
|
|
5
|
-
.filter((t) => t[0] === "t" && t[1])
|
|
6
|
-
.find((t) => stripInvisibleChar(t[1].toLowerCase()) === hashtag);
|
|
7
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { EventTemplate, NostrEvent, UnsignedEvent } from "nostr-tools";
|
|
2
|
-
import { EventStore } from "applesauce-core";
|
|
3
|
-
export type HiddenTagsSigner = {
|
|
4
|
-
nip04?: {
|
|
5
|
-
encrypt: (pubkey: string, plaintext: string) => Promise<string> | string;
|
|
6
|
-
decrypt: (pubkey: string, ciphertext: string) => Promise<string> | string;
|
|
7
|
-
};
|
|
8
|
-
nip44?: {
|
|
9
|
-
encrypt: (pubkey: string, plaintext: string) => Promise<string> | string;
|
|
10
|
-
decrypt: (pubkey: string, ciphertext: string) => Promise<string> | string;
|
|
11
|
-
};
|
|
12
|
-
};
|
|
13
|
-
export type TagOperation = (tags: string[][]) => string[][];
|
|
14
|
-
export declare const HiddenTagsSymbol: unique symbol;
|
|
15
|
-
/** Various event kinds that can have encrypted tags in their content and which encryption method they use */
|
|
16
|
-
export declare const EventEncryptionMethod: Record<number, "nip04" | "nip44">;
|
|
17
|
-
/** Checks if an event can have hidden tags */
|
|
18
|
-
export declare function canHaveHiddenTags(kind: number): boolean;
|
|
19
|
-
/** Checks if an event has hidden tags */
|
|
20
|
-
export declare function hasHiddenTags(event: NostrEvent | EventTemplate): boolean;
|
|
21
|
-
/** Returns the hidden tags for an event if they are unlocked */
|
|
22
|
-
export declare function getHiddenTags(event: NostrEvent | EventTemplate): string[][] | undefined;
|
|
23
|
-
/** Checks if the hidden tags are locked */
|
|
24
|
-
export declare function isHiddenTagsLocked(event: NostrEvent): boolean;
|
|
25
|
-
/**
|
|
26
|
-
* Decrypts the private list
|
|
27
|
-
* @param event The list event to decrypt
|
|
28
|
-
* @param signer A signer to use to decrypt the tags
|
|
29
|
-
* @param store An optional EventStore to notify about the update
|
|
30
|
-
* @throws
|
|
31
|
-
*/
|
|
32
|
-
export declare function unlockHiddenTags(event: NostrEvent, signer: HiddenTagsSigner, store?: EventStore): Promise<NostrEvent>;
|
|
33
|
-
/**
|
|
34
|
-
* Modifies tags and returns an EventTemplate
|
|
35
|
-
* @param event Event to modify
|
|
36
|
-
* @param operations Operations for hidden and public tags
|
|
37
|
-
* @param signer A signer to use to decrypt the tags
|
|
38
|
-
* @throws
|
|
39
|
-
*/
|
|
40
|
-
export declare function modifyEventTags(event: NostrEvent | UnsignedEvent, operations: {
|
|
41
|
-
public?: TagOperation;
|
|
42
|
-
hidden?: TagOperation;
|
|
43
|
-
}, signer?: HiddenTagsSigner): Promise<EventTemplate>;
|
|
44
|
-
/**
|
|
45
|
-
* Override the hidden tags in an event
|
|
46
|
-
* @throws
|
|
47
|
-
*/
|
|
48
|
-
export declare function overrideHiddenTags(event: NostrEvent, hidden: string[][], signer: HiddenTagsSigner): Promise<EventTemplate>;
|