applesauce-actions 2.0.0 → 2.3.0

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.
@@ -1,41 +1,41 @@
1
1
  import { BLOSSOM_SERVER_LIST_KIND } from "applesauce-core/helpers/blossom";
2
- import { modifyPublicTags } from "applesauce-factory/operations/event";
2
+ import { modifyPublicTags, modifyTags } from "applesauce-factory/operations/event";
3
3
  import { addBlossomServerTag, removeBlossomServerTag } from "applesauce-factory/operations/tag/blossom";
4
- function getBlossomServersEvent(events, self) {
5
- const event = events.getReplaceable(BLOSSOM_SERVER_LIST_KIND, self);
6
- if (!event)
7
- throw new Error("Can't find Blossom servers event");
8
- return event;
9
- }
10
4
  /** An action that adds a server to the Blossom servers event */
11
5
  export function AddBlossomServer(server) {
12
6
  return async function* ({ events, factory, self }) {
13
- const servers = getBlossomServersEvent(events, self);
7
+ const servers = events.getReplaceable(BLOSSOM_SERVER_LIST_KIND, self);
14
8
  const operation = Array.isArray(server) ? server.map((s) => addBlossomServerTag(s)) : addBlossomServerTag(server);
15
- const draft = await factory.modifyTags(servers, operation);
9
+ // Modify or build new event
10
+ const draft = servers
11
+ ? await factory.modifyTags(servers, operation)
12
+ : await factory.build({ kind: BLOSSOM_SERVER_LIST_KIND }, modifyTags(operation));
16
13
  yield await factory.sign(draft);
17
14
  };
18
15
  }
19
16
  /** An action that removes a server from the Blossom servers event */
20
17
  export function RemoveBlossomServer(server) {
21
18
  return async function* ({ events, factory, self }) {
22
- const servers = getBlossomServersEvent(events, self);
19
+ const servers = events.getReplaceable(BLOSSOM_SERVER_LIST_KIND, self);
23
20
  const operation = Array.isArray(server)
24
21
  ? server.map((s) => removeBlossomServerTag(s))
25
22
  : removeBlossomServerTag(server);
26
- const draft = await factory.modifyTags(servers, operation);
23
+ // Modify or build new event
24
+ const draft = servers
25
+ ? await factory.modifyTags(servers, operation)
26
+ : await factory.build({ kind: BLOSSOM_SERVER_LIST_KIND }, modifyTags(operation));
27
27
  yield await factory.sign(draft);
28
28
  };
29
29
  }
30
30
  /** Makes a specific Blossom server the default server (move it to the top of the list) */
31
31
  export function SetDefaultBlossomServer(server) {
32
32
  return async function* ({ events, factory, self }) {
33
- const servers = getBlossomServersEvent(events, self);
33
+ const servers = events.getReplaceable(BLOSSOM_SERVER_LIST_KIND, self);
34
34
  const prependTag = (tag) => (tags) => [tag, ...tags];
35
- const draft = await factory.modifyTags(servers, [
36
- removeBlossomServerTag(server),
37
- prependTag(["server", String(server)]),
38
- ]);
35
+ const operations = [removeBlossomServerTag(server), prependTag(["server", String(server)])];
36
+ const draft = servers
37
+ ? await factory.modifyTags(servers, operations)
38
+ : await factory.build({ kind: BLOSSOM_SERVER_LIST_KIND }, modifyTags(...operations));
39
39
  yield await factory.sign(draft);
40
40
  };
41
41
  }
@@ -3,17 +3,17 @@ import { Action } from "../action-hub.js";
3
3
  /**
4
4
  * An action that adds a note or article to the bookmark list or a bookmark set
5
5
  * @param event the event to bookmark
6
- * @param identifier the "d" tag of the bookmark set
6
+ * @param identifier the "d" tag of the bookmark set or `undefined` for the default bookmark list
7
7
  * @param hidden set to true to add to hidden bookmarks
8
8
  */
9
- export declare function BookmarkEvent(event: NostrEvent, identifier?: string, hidden?: boolean): Action;
9
+ export declare function BookmarkEvent(event: NostrEvent, identifier?: string | NostrEvent, hidden?: boolean): Action;
10
10
  /**
11
11
  * An action that removes a note or article from the bookmark list or bookmark set
12
12
  * @param event the event to remove from bookmarks
13
- * @param identifier the "d" tag of the bookmark set
13
+ * @param identifier the "d" tag of the bookmark set or `undefined` for the default bookmark list
14
14
  * @param hidden set to true to remove from hidden bookmarks
15
15
  */
16
- export declare function UnbookmarkEvent(event: NostrEvent, identifier: string, hidden?: boolean): Action;
16
+ export declare function UnbookmarkEvent(event: NostrEvent, identifier?: string | NostrEvent, hidden?: boolean): Action;
17
17
  /** An action that creates a new bookmark list for a user */
18
18
  export declare function CreateBookmarkList(bookmarks?: NostrEvent[]): Action;
19
19
  /** An action that creates a new bookmark set for a user */
@@ -1,45 +1,72 @@
1
1
  import { modifyHiddenTags, modifyPublicTags, setListDescription, setListImage, setListTitle, } from "applesauce-factory/operations/event";
2
2
  import { addEventBookmarkTag, removeEventBookmarkTag } from "applesauce-factory/operations/tag";
3
3
  import { kinds } from "nostr-tools";
4
- function getBookmarkEvent(events, self, identifier) {
5
- return events.getReplaceable(identifier ? kinds.Bookmarksets : kinds.BookmarkList, self, identifier);
6
- }
7
4
  /**
8
5
  * An action that adds a note or article to the bookmark list or a bookmark set
9
6
  * @param event the event to bookmark
10
- * @param identifier the "d" tag of the bookmark set
7
+ * @param identifier the "d" tag of the bookmark set or `undefined` for the default bookmark list
11
8
  * @param hidden set to true to add to hidden bookmarks
12
9
  */
13
10
  export function BookmarkEvent(event, identifier, hidden = false) {
14
11
  return async function* ({ events, factory, self }) {
15
- const bookmarks = getBookmarkEvent(events, self, identifier);
16
- if (!bookmarks)
17
- throw new Error("Cant find bookmarks");
12
+ let draft;
18
13
  const operation = addEventBookmarkTag(event);
19
- const draft = await factory.modifyTags(bookmarks, hidden ? { hidden: operation } : operation);
14
+ if (typeof identifier === "string" || identifier?.kind === kinds.Bookmarksets) {
15
+ const list = typeof identifier === "string" ? events.getReplaceable(kinds.Bookmarksets, self, identifier) : identifier;
16
+ if (list && list.kind !== kinds.Bookmarksets)
17
+ throw new Error("Event is not a bookmark set");
18
+ // Modify or build new event bookmark set
19
+ draft = list
20
+ ? await factory.modifyTags(list, hidden ? { hidden: operation } : operation)
21
+ : await factory.build({ kind: kinds.Bookmarksets }, hidden ? modifyHiddenTags(operation) : modifyPublicTags(operation));
22
+ }
23
+ else if (identifier === undefined || identifier?.kind === kinds.BookmarkList) {
24
+ const list = identifier ? identifier : events.getReplaceable(kinds.BookmarkList, self);
25
+ if (list && list.kind !== kinds.BookmarkList)
26
+ throw new Error("Event is not a bookmark list");
27
+ // Modify or build new event bookmark list
28
+ draft = list
29
+ ? await factory.modifyTags(list, hidden ? { hidden: operation } : operation)
30
+ : await factory.build({ kind: kinds.BookmarkList }, hidden ? modifyHiddenTags(operation) : modifyPublicTags(operation));
31
+ }
32
+ else {
33
+ throw new Error(`Event kind ${identifier.kind} is not a bookmark list or bookmark set`);
34
+ }
20
35
  yield await factory.sign(draft);
21
36
  };
22
37
  }
23
38
  /**
24
39
  * An action that removes a note or article from the bookmark list or bookmark set
25
40
  * @param event the event to remove from bookmarks
26
- * @param identifier the "d" tag of the bookmark set
41
+ * @param identifier the "d" tag of the bookmark set or `undefined` for the default bookmark list
27
42
  * @param hidden set to true to remove from hidden bookmarks
28
43
  */
29
44
  export function UnbookmarkEvent(event, identifier, hidden = false) {
30
45
  return async function* ({ events, factory, self }) {
31
- const bookmarks = getBookmarkEvent(events, self, identifier);
32
- if (!bookmarks)
33
- throw new Error("Cant find bookmarks");
46
+ let list;
34
47
  const operation = removeEventBookmarkTag(event);
35
- const draft = await factory.modifyTags(bookmarks, hidden ? { hidden: operation } : operation);
48
+ if (typeof identifier === "string" || identifier?.kind === kinds.Bookmarksets) {
49
+ list = typeof identifier === "string" ? events.getReplaceable(kinds.Bookmarksets, self, identifier) : identifier;
50
+ }
51
+ else if (identifier === undefined || identifier?.kind === kinds.BookmarkList) {
52
+ list = identifier ? identifier : events.getReplaceable(kinds.BookmarkList, self);
53
+ if (!list)
54
+ return;
55
+ }
56
+ else {
57
+ throw new Error(`Event kind ${identifier.kind} is not a bookmark list or bookmark set`);
58
+ }
59
+ // If no list is found, return
60
+ if (!list)
61
+ return;
62
+ const draft = await factory.modifyTags(list, hidden ? { hidden: operation } : operation);
36
63
  yield await factory.sign(draft);
37
64
  };
38
65
  }
39
66
  /** An action that creates a new bookmark list for a user */
40
67
  export function CreateBookmarkList(bookmarks) {
41
68
  return async function* ({ events, factory, self }) {
42
- const existing = getBookmarkEvent(events, self);
69
+ const existing = events.getReplaceable(kinds.BookmarkList, self);
43
70
  if (existing)
44
71
  throw new Error("Bookmark list already exists");
45
72
  const draft = await factory.build({ kind: kinds.BookmarkList }, bookmarks ? modifyPublicTags(...bookmarks.map(addEventBookmarkTag)) : undefined);
@@ -48,10 +75,7 @@ export function CreateBookmarkList(bookmarks) {
48
75
  }
49
76
  /** An action that creates a new bookmark set for a user */
50
77
  export function CreateBookmarkSet(title, description, additional) {
51
- return async function* ({ events, factory, self }) {
52
- const existing = getBookmarkEvent(events, self);
53
- if (existing)
54
- throw new Error("Bookmark list already exists");
78
+ return async function* ({ factory }) {
55
79
  const draft = await factory.build({ kind: kinds.BookmarkList }, setListTitle(title), setListDescription(description), additional.image ? setListImage(additional.image) : undefined, additional.public ? modifyPublicTags(...additional.public.map(addEventBookmarkTag)) : undefined, additional.hidden ? modifyHiddenTags(...additional.hidden.map(addEventBookmarkTag)) : undefined);
56
80
  yield await factory.sign(draft);
57
81
  };
@@ -1,7 +1,8 @@
1
+ import { ProfilePointer } from "nostr-tools/nip19";
1
2
  import { Action } from "../action-hub.js";
2
3
  /** An action that adds a pubkey to a users contacts event */
3
4
  export declare function FollowUser(pubkey: string, relay?: string, hidden?: boolean): Action;
4
5
  /** An action that removes a pubkey from a users contacts event */
5
- export declare function UnfollowUser(pubkey: string, hidden?: boolean): Action;
6
+ export declare function UnfollowUser(user: string | ProfilePointer, hidden?: boolean): Action;
6
7
  /** An action that creates a new kind 3 contacts lists, throws if a contact list already exists */
7
- export declare function NewContacts(pubkeys?: string[]): Action;
8
+ export declare function NewContacts(pubkeys?: (string | ProfilePointer)[]): Action;
@@ -1,24 +1,29 @@
1
- import { kinds } from "nostr-tools";
1
+ import { modifyHiddenTags, modifyPublicTags } from "applesauce-factory/operations/event";
2
2
  import { addPubkeyTag, removePubkeyTag } from "applesauce-factory/operations/tag";
3
+ import { kinds } from "nostr-tools";
3
4
  /** An action that adds a pubkey to a users contacts event */
4
5
  export function FollowUser(pubkey, relay, hidden = false) {
5
6
  return async function* ({ events, factory, self }) {
6
- const contacts = events.getReplaceable(kinds.Contacts, self);
7
- if (!contacts)
8
- throw new Error("Missing contacts event");
7
+ let contacts = events.getReplaceable(kinds.Contacts, self);
9
8
  const pointer = { pubkey, relays: relay ? [relay] : undefined };
10
9
  const operation = addPubkeyTag(pointer);
11
- const draft = await factory.modifyTags(contacts, hidden ? { hidden: operation } : operation);
10
+ let draft;
11
+ // No contact list, create one
12
+ if (!contacts)
13
+ draft = await factory.build({ kind: kinds.Contacts }, hidden ? modifyHiddenTags(operation) : modifyPublicTags(operation));
14
+ else
15
+ draft = await factory.modifyTags(contacts, hidden ? { hidden: operation } : operation);
12
16
  yield await factory.sign(draft);
13
17
  };
14
18
  }
15
19
  /** An action that removes a pubkey from a users contacts event */
16
- export function UnfollowUser(pubkey, hidden = false) {
20
+ export function UnfollowUser(user, hidden = false) {
17
21
  return async function* ({ events, factory, self }) {
18
22
  const contacts = events.getReplaceable(kinds.Contacts, self);
23
+ // Unable to find a contacts event, so we can't unfollow
19
24
  if (!contacts)
20
- throw new Error("Missing contacts event");
21
- const operation = removePubkeyTag(pubkey);
25
+ return;
26
+ const operation = removePubkeyTag(user);
22
27
  const draft = await factory.modifyTags(contacts, hidden ? { hidden: operation } : operation);
23
28
  yield await factory.sign(draft);
24
29
  };
@@ -29,7 +34,7 @@ export function NewContacts(pubkeys) {
29
34
  const contacts = events.getReplaceable(kinds.Contacts, self);
30
35
  if (contacts)
31
36
  throw new Error("Contact list already exists");
32
- const draft = await factory.build({ kind: kinds.Contacts, tags: pubkeys?.map((p) => ["p", p]) });
37
+ const draft = await factory.build({ kind: kinds.Contacts }, pubkeys ? modifyPublicTags(...pubkeys.map((p) => addPubkeyTag(p))) : undefined);
33
38
  yield await factory.sign(draft);
34
39
  };
35
40
  }
@@ -18,9 +18,9 @@ export function AddInboxRelay(relay) {
18
18
  if (typeof relay === "string")
19
19
  relay = [relay];
20
20
  const mailboxes = events.getReplaceable(kinds.RelayList, self);
21
- if (!mailboxes)
22
- throw new Error("Missing mailboxes event");
23
- const draft = await factory.modifyTags(mailboxes, ...relay.map(addInboxRelay));
21
+ const draft = mailboxes
22
+ ? await factory.modifyTags(mailboxes, ...relay.map(addInboxRelay))
23
+ : await factory.build({ kind: kinds.RelayList }, modifyPublicTags(...relay.map(addInboxRelay)));
24
24
  const signed = await factory.sign(draft);
25
25
  yield signed;
26
26
  };
@@ -32,7 +32,7 @@ export function RemoveInboxRelay(relay) {
32
32
  relay = [relay];
33
33
  const mailboxes = events.getReplaceable(kinds.RelayList, self);
34
34
  if (!mailboxes)
35
- throw new Error("Missing mailboxes event");
35
+ return;
36
36
  const draft = await factory.modifyTags(mailboxes, ...relay.map(removeInboxRelay));
37
37
  const signed = await factory.sign(draft);
38
38
  yield signed;
@@ -44,9 +44,9 @@ export function AddOutboxRelay(relay) {
44
44
  if (typeof relay === "string")
45
45
  relay = [relay];
46
46
  const mailboxes = events.getReplaceable(kinds.RelayList, self);
47
- if (!mailboxes)
48
- throw new Error("Missing mailboxes event");
49
- const draft = await factory.modifyTags(mailboxes, ...relay.map(addOutboxRelay));
47
+ const draft = mailboxes
48
+ ? await factory.modifyTags(mailboxes, ...relay.map(addOutboxRelay))
49
+ : await factory.build({ kind: kinds.RelayList }, modifyPublicTags(...relay.map(addOutboxRelay)));
50
50
  const signed = await factory.sign(draft);
51
51
  yield signed;
52
52
  };
@@ -58,7 +58,7 @@ export function RemoveOutboxRelay(relay) {
58
58
  relay = [relay];
59
59
  const mailboxes = events.getReplaceable(kinds.RelayList, self);
60
60
  if (!mailboxes)
61
- throw new Error("Missing mailboxes event");
61
+ return;
62
62
  const draft = await factory.modifyTags(mailboxes, ...relay.map(removeOutboxRelay));
63
63
  const signed = await factory.sign(draft);
64
64
  yield signed;
@@ -8,10 +8,11 @@ import { GiftWrapBlueprint, WrappedMessageBlueprint, WrappedMessageReplyBlueprin
8
8
  * @returns Signed gift wrapped messages to send
9
9
  */
10
10
  export function SendWrappedMessage(participants, message, opts) {
11
- return async function* ({ factory }) {
11
+ return async function* ({ factory, self }) {
12
12
  const rumor = await factory.create(WrappedMessageBlueprint, participants, message, opts);
13
- // Get the pubkeys to send this message to (will include the sender)
14
- const pubkeys = getConversationParticipants(rumor);
13
+ // Get the pubkeys to send this message to and ensure the sender is included
14
+ const pubkeys = new Set(getConversationParticipants(rumor));
15
+ pubkeys.add(self);
15
16
  for (const pubkey of pubkeys) {
16
17
  yield await factory.create(GiftWrapBlueprint, pubkey, rumor, opts);
17
18
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "applesauce-actions",
3
- "version": "2.0.0",
3
+ "version": "2.3.0",
4
4
  "description": "A package for performing common nostr actions",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -32,8 +32,8 @@
32
32
  }
33
33
  },
34
34
  "dependencies": {
35
- "applesauce-core": "^2.0.0",
36
- "applesauce-factory": "^2.0.0",
35
+ "applesauce-core": "^2.3.0",
36
+ "applesauce-factory": "^2.3.0",
37
37
  "nostr-tools": "^2.13",
38
38
  "rxjs": "^7.8.1"
39
39
  },