@nostrify/policies 0.36.5 → 0.36.6

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.
Files changed (132) hide show
  1. package/.turbo/turbo-build.log +28 -5
  2. package/.turbo/turbo-setup.log +22 -0
  3. package/.turbo/turbo-test.log +4 -0
  4. package/AntiDuplicationPolicy.test.ts +54 -41
  5. package/AntiDuplicationPolicy.ts +7 -3
  6. package/AnyPolicy.test.ts +15 -14
  7. package/AnyPolicy.ts +5 -2
  8. package/AuthorPolicy.test.ts +8 -7
  9. package/AuthorPolicy.ts +9 -3
  10. package/CHANGELOG.md +9 -0
  11. package/DomainPolicy.test.ts +130 -77
  12. package/DomainPolicy.ts +3 -3
  13. package/FiltersPolicy.test.ts +14 -7
  14. package/FiltersPolicy.ts +5 -2
  15. package/HashtagPolicy.test.ts +25 -14
  16. package/HashtagPolicy.ts +5 -2
  17. package/HellthreadPolicy.test.ts +10 -9
  18. package/HellthreadPolicy.ts +6 -3
  19. package/InvertPolicy.test.ts +10 -9
  20. package/InvertPolicy.ts +8 -2
  21. package/KeywordPolicy.test.ts +18 -12
  22. package/KeywordPolicy.ts +5 -2
  23. package/NoOpPolicy.test.ts +8 -7
  24. package/NoOpPolicy.ts +1 -1
  25. package/OpenAIPolicy.test.ts +22 -9
  26. package/OpenAIPolicy.ts +5 -2
  27. package/PipePolicy.test.ts +18 -17
  28. package/PipePolicy.ts +5 -2
  29. package/PowPolicy.test.ts +14 -13
  30. package/PowPolicy.ts +6 -3
  31. package/PubkeyBanPolicy.test.ts +15 -8
  32. package/PubkeyBanPolicy.ts +5 -2
  33. package/ReadOnlyPolicy.test.ts +9 -8
  34. package/ReadOnlyPolicy.ts +1 -1
  35. package/RegexPolicy.test.ts +19 -10
  36. package/RegexPolicy.ts +5 -2
  37. package/ReplyBotPolicy.test.ts +43 -27
  38. package/ReplyBotPolicy.ts +6 -3
  39. package/SizePolicy.test.ts +9 -8
  40. package/SizePolicy.ts +6 -2
  41. package/WhitelistPolicy.test.ts +15 -8
  42. package/WhitelistPolicy.ts +6 -2
  43. package/WoTPolicy.test.ts +48 -22
  44. package/WoTPolicy.ts +5 -2
  45. package/dist/AntiDuplicationPolicy.d.ts +2 -2
  46. package/dist/AntiDuplicationPolicy.d.ts.map +1 -1
  47. package/dist/AntiDuplicationPolicy.js +41 -56
  48. package/dist/AnyPolicy.d.ts +1 -1
  49. package/dist/AnyPolicy.d.ts.map +1 -1
  50. package/dist/AnyPolicy.js +17 -16
  51. package/dist/AuthorPolicy.d.ts +1 -1
  52. package/dist/AuthorPolicy.d.ts.map +1 -1
  53. package/dist/AuthorPolicy.js +19 -20
  54. package/dist/DomainPolicy.d.ts +2 -2
  55. package/dist/DomainPolicy.d.ts.map +1 -1
  56. package/dist/DomainPolicy.js +57 -59
  57. package/dist/FiltersPolicy.d.ts +1 -1
  58. package/dist/FiltersPolicy.d.ts.map +1 -1
  59. package/dist/FiltersPolicy.js +15 -24
  60. package/dist/HashtagPolicy.d.ts +1 -1
  61. package/dist/HashtagPolicy.d.ts.map +1 -1
  62. package/dist/HashtagPolicy.js +16 -23
  63. package/dist/HellthreadPolicy.d.ts +1 -1
  64. package/dist/HellthreadPolicy.d.ts.map +1 -1
  65. package/dist/HellthreadPolicy.js +18 -17
  66. package/dist/InvertPolicy.d.ts +1 -1
  67. package/dist/InvertPolicy.d.ts.map +1 -1
  68. package/dist/InvertPolicy.js +18 -18
  69. package/dist/KeywordPolicy.d.ts +1 -1
  70. package/dist/KeywordPolicy.d.ts.map +1 -1
  71. package/dist/KeywordPolicy.js +16 -23
  72. package/dist/NoOpPolicy.d.ts +1 -1
  73. package/dist/NoOpPolicy.d.ts.map +1 -1
  74. package/dist/NoOpPolicy.js +8 -7
  75. package/dist/OpenAIPolicy.d.ts +1 -1
  76. package/dist/OpenAIPolicy.d.ts.map +1 -1
  77. package/dist/OpenAIPolicy.js +35 -55
  78. package/dist/PipePolicy.d.ts +1 -1
  79. package/dist/PipePolicy.d.ts.map +1 -1
  80. package/dist/PipePolicy.js +16 -33
  81. package/dist/PowPolicy.d.ts +1 -1
  82. package/dist/PowPolicy.d.ts.map +1 -1
  83. package/dist/PowPolicy.js +25 -30
  84. package/dist/PubkeyBanPolicy.d.ts +1 -1
  85. package/dist/PubkeyBanPolicy.d.ts.map +1 -1
  86. package/dist/PubkeyBanPolicy.js +16 -22
  87. package/dist/ReadOnlyPolicy.d.ts +1 -1
  88. package/dist/ReadOnlyPolicy.d.ts.map +1 -1
  89. package/dist/ReadOnlyPolicy.js +8 -7
  90. package/dist/RegexPolicy.d.ts +1 -1
  91. package/dist/RegexPolicy.d.ts.map +1 -1
  92. package/dist/RegexPolicy.js +14 -20
  93. package/dist/ReplyBotPolicy.d.ts +1 -1
  94. package/dist/ReplyBotPolicy.d.ts.map +1 -1
  95. package/dist/ReplyBotPolicy.js +39 -38
  96. package/dist/SizePolicy.d.ts +1 -1
  97. package/dist/SizePolicy.d.ts.map +1 -1
  98. package/dist/SizePolicy.js +17 -25
  99. package/dist/WhitelistPolicy.d.ts +1 -1
  100. package/dist/WhitelistPolicy.d.ts.map +1 -1
  101. package/dist/WhitelistPolicy.js +23 -29
  102. package/dist/WoTPolicy.d.ts +2 -2
  103. package/dist/WoTPolicy.d.ts.map +1 -1
  104. package/dist/WoTPolicy.js +34 -33
  105. package/dist/mod.d.ts +20 -20
  106. package/dist/mod.js +42 -21
  107. package/dist/mod.js.map +7 -1
  108. package/dist/tsconfig.tsbuildinfo +1 -1
  109. package/mod.ts +20 -20
  110. package/package.json +8 -6
  111. package/tsconfig.json +3 -1
  112. package/.turbo/daemon/7bb8240f68f7ad88-turbo.log.2025-07-29 +0 -0
  113. package/dist/AntiDuplicationPolicy.js.map +0 -1
  114. package/dist/AnyPolicy.js.map +0 -1
  115. package/dist/AuthorPolicy.js.map +0 -1
  116. package/dist/DomainPolicy.js.map +0 -1
  117. package/dist/FiltersPolicy.js.map +0 -1
  118. package/dist/HashtagPolicy.js.map +0 -1
  119. package/dist/HellthreadPolicy.js.map +0 -1
  120. package/dist/InvertPolicy.js.map +0 -1
  121. package/dist/KeywordPolicy.js.map +0 -1
  122. package/dist/NoOpPolicy.js.map +0 -1
  123. package/dist/OpenAIPolicy.js.map +0 -1
  124. package/dist/PipePolicy.js.map +0 -1
  125. package/dist/PowPolicy.js.map +0 -1
  126. package/dist/PubkeyBanPolicy.js.map +0 -1
  127. package/dist/ReadOnlyPolicy.js.map +0 -1
  128. package/dist/RegexPolicy.js.map +0 -1
  129. package/dist/ReplyBotPolicy.js.map +0 -1
  130. package/dist/SizePolicy.js.map +0 -1
  131. package/dist/WhitelistPolicy.js.map +0 -1
  132. package/dist/WoTPolicy.js.map +0 -1
@@ -1,11 +1,12 @@
1
- import { genEvent, MockRelay } from '@nostrify/nostrify/test';
2
- import { NostrMetadata } from '@nostrify/types';
3
- import { assertEquals } from '@std/assert';
4
- import { generateSecretKey, getPublicKey } from 'nostr-tools';
1
+ import { test } from "node:test";
2
+ import { genEvent, MockRelay } from "@nostrify/nostrify/test";
3
+ import type { NostrMetadata } from "@nostrify/types";
4
+ import { deepStrictEqual } from "node:assert";
5
+ import { generateSecretKey, getPublicKey } from "nostr-tools";
5
6
 
6
- import { DomainPolicy } from './DomainPolicy.ts';
7
+ import { DomainPolicy } from "./DomainPolicy.ts";
7
8
 
8
- Deno.test('DomainPolicy allows events from authors with a valid nip05', async () => {
9
+ await test("DomainPolicy allows events from authors with a valid nip05", async () => {
9
10
  const sk = generateSecretKey();
10
11
  const pubkey = getPublicKey(sk);
11
12
 
@@ -13,62 +14,73 @@ Deno.test('DomainPolicy allows events from authors with a valid nip05', async ()
13
14
  const policy = new DomainPolicy(store, {
14
15
  // deno-lint-ignore require-await
15
16
  async lookup(nip05: string) {
16
- if (nip05 === 'alex@gleasonator.dev') {
17
+ if (nip05 === "alex@gleasonator.dev") {
17
18
  return { pubkey };
18
19
  } else {
19
- throw new Error('not found');
20
+ throw new Error("not found");
20
21
  }
21
22
  },
22
23
  });
23
24
 
24
- const metadata: NostrMetadata = { nip05: 'alex@gleasonator.dev' };
25
- await store.event(genEvent({ kind: 0, content: JSON.stringify(metadata) }, sk));
26
- const event = genEvent({ kind: 1, content: 'hello world' }, sk);
25
+ const metadata: NostrMetadata = { nip05: "alex@gleasonator.dev" };
26
+ await store.event(
27
+ genEvent({ kind: 0, content: JSON.stringify(metadata) }, sk),
28
+ );
29
+ const event = genEvent({ kind: 1, content: "hello world" }, sk);
27
30
 
28
31
  const result = await policy.call(event);
29
32
 
30
- assertEquals(result, ['OK', event.id, true, '']);
33
+ deepStrictEqual(result, ["OK", event.id, true, ""]);
31
34
  });
32
35
 
33
- Deno.test('DomainPolicy rejects events from authors without a kind 0', async () => {
36
+ await test("DomainPolicy rejects events from authors without a kind 0", async () => {
34
37
  const store = new MockRelay();
35
38
  const policy = new DomainPolicy(store);
36
- const event = genEvent({ kind: 1, content: 'hello world' });
39
+ const event = genEvent({ kind: 1, content: "hello world" });
37
40
 
38
41
  const result = await policy.call(event);
39
42
 
40
- assertEquals(result, ['OK', event.id, false, 'blocked: author is missing a kind 0 event']);
43
+ deepStrictEqual(result, [
44
+ "OK",
45
+ event.id,
46
+ false,
47
+ "blocked: author is missing a kind 0 event",
48
+ ]);
41
49
  });
42
50
 
43
- Deno.test('DomainPolicy rejects events from authors with a missing nip05', async () => {
51
+ await test("DomainPolicy rejects events from authors with a missing nip05", async () => {
44
52
  const store = new MockRelay();
45
53
  const policy = new DomainPolicy(store);
46
54
 
47
55
  const sk = generateSecretKey();
48
56
  const metadata: NostrMetadata = {};
49
- await store.event(genEvent({ kind: 0, content: JSON.stringify(metadata) }, sk));
50
- const event = genEvent({ kind: 1, content: 'hello world' }, sk);
57
+ await store.event(
58
+ genEvent({ kind: 0, content: JSON.stringify(metadata) }, sk),
59
+ );
60
+ const event = genEvent({ kind: 1, content: "hello world" }, sk);
51
61
 
52
62
  const result = await policy.call(event);
53
63
 
54
- assertEquals(result, ['OK', event.id, false, 'blocked: missing nip05']);
64
+ deepStrictEqual(result, ["OK", event.id, false, "blocked: missing nip05"]);
55
65
  });
56
66
 
57
- Deno.test('DomainPolicy rejects events from authors with a malformed nip05', async () => {
67
+ await test("DomainPolicy rejects events from authors with a malformed nip05", async () => {
58
68
  const store = new MockRelay();
59
69
  const policy = new DomainPolicy(store);
60
70
 
61
71
  const sk = generateSecretKey();
62
- const metadata: NostrMetadata = { nip05: 'asdf' };
63
- await store.event(genEvent({ kind: 0, content: JSON.stringify(metadata) }, sk));
64
- const event = genEvent({ kind: 1, content: 'hello world' }, sk);
72
+ const metadata: NostrMetadata = { nip05: "asdf" };
73
+ await store.event(
74
+ genEvent({ kind: 0, content: JSON.stringify(metadata) }, sk),
75
+ );
76
+ const event = genEvent({ kind: 1, content: "hello world" }, sk);
65
77
 
66
78
  const result = await policy.call(event);
67
79
 
68
- assertEquals(result, ['OK', event.id, false, 'blocked: missing nip05']);
80
+ deepStrictEqual(result, ["OK", event.id, false, "blocked: missing nip05"]);
69
81
  });
70
82
 
71
- Deno.test('DomainPolicy rejects events from authors with an invalid nip05', async () => {
83
+ await test("DomainPolicy rejects events from authors with an invalid nip05", async () => {
72
84
  const store = new MockRelay();
73
85
 
74
86
  const policy = new DomainPolicy(store, {
@@ -79,17 +91,24 @@ Deno.test('DomainPolicy rejects events from authors with an invalid nip05', asyn
79
91
  },
80
92
  });
81
93
 
82
- const metadata: NostrMetadata = { nip05: 'alex@gleasonator.dev' };
94
+ const metadata: NostrMetadata = { nip05: "alex@gleasonator.dev" };
83
95
  const sk = generateSecretKey();
84
- await store.event(genEvent({ kind: 0, content: JSON.stringify(metadata) }, sk));
85
- const event = genEvent({ kind: 1, content: 'hello world' }, sk);
96
+ await store.event(
97
+ genEvent({ kind: 0, content: JSON.stringify(metadata) }, sk),
98
+ );
99
+ const event = genEvent({ kind: 1, content: "hello world" }, sk);
86
100
 
87
101
  const result = await policy.call(event);
88
102
 
89
- assertEquals(result, ['OK', event.id, false, 'blocked: mismatched nip05 pubkey']);
103
+ deepStrictEqual(result, [
104
+ "OK",
105
+ event.id,
106
+ false,
107
+ "blocked: mismatched nip05 pubkey",
108
+ ]);
90
109
  });
91
110
 
92
- Deno.test('DomainPolicy rejects events from authors with a blacklisted nip05 domain', async () => {
111
+ await test("DomainPolicy rejects events from authors with a blacklisted nip05 domain", async () => {
93
112
  const sk = generateSecretKey();
94
113
  const pubkey = getPublicKey(sk);
95
114
 
@@ -97,25 +116,32 @@ Deno.test('DomainPolicy rejects events from authors with a blacklisted nip05 dom
97
116
  const policy = new DomainPolicy(store, {
98
117
  // deno-lint-ignore require-await
99
118
  async lookup(nip05: string) {
100
- if (nip05 === 'bot@replyguy.dev') {
119
+ if (nip05 === "bot@replyguy.dev") {
101
120
  return { pubkey };
102
121
  } else {
103
- throw new Error('not found');
122
+ throw new Error("not found");
104
123
  }
105
124
  },
106
- blacklist: ['replyguy.dev'],
125
+ blacklist: ["replyguy.dev"],
107
126
  });
108
127
 
109
- const metadata: NostrMetadata = { nip05: 'bot@replyguy.dev' };
110
- await store.event(genEvent({ kind: 0, content: JSON.stringify(metadata) }, sk));
111
- const event = genEvent({ kind: 1, content: 'hello world' }, sk);
128
+ const metadata: NostrMetadata = { nip05: "bot@replyguy.dev" };
129
+ await store.event(
130
+ genEvent({ kind: 0, content: JSON.stringify(metadata) }, sk),
131
+ );
132
+ const event = genEvent({ kind: 1, content: "hello world" }, sk);
112
133
 
113
134
  const result = await policy.call(event);
114
135
 
115
- assertEquals(result, ['OK', event.id, false, 'blocked: blacklisted nip05 domain']);
136
+ deepStrictEqual(result, [
137
+ "OK",
138
+ event.id,
139
+ false,
140
+ "blocked: blacklisted nip05 domain",
141
+ ]);
116
142
  });
117
143
 
118
- Deno.test("DomainPolicy rejects events from authors who aren't on a whitelisted domain", async () => {
144
+ await test("DomainPolicy rejects events from authors who aren't on a whitelisted domain", async () => {
119
145
  const sk = generateSecretKey();
120
146
  const pubkey = getPublicKey(sk);
121
147
 
@@ -123,25 +149,32 @@ Deno.test("DomainPolicy rejects events from authors who aren't on a whitelisted
123
149
  const policy = new DomainPolicy(store, {
124
150
  // deno-lint-ignore require-await
125
151
  async lookup(nip05: string) {
126
- if (nip05 === 'bot@replyguy.dev') {
152
+ if (nip05 === "bot@replyguy.dev") {
127
153
  return { pubkey };
128
154
  } else {
129
- throw new Error('not found');
155
+ throw new Error("not found");
130
156
  }
131
157
  },
132
- whitelist: ['gleasonator.dev'],
158
+ whitelist: ["gleasonator.dev"],
133
159
  });
134
160
 
135
- const metadata: NostrMetadata = { nip05: 'bot@replyguy.dev' };
136
- await store.event(genEvent({ kind: 0, content: JSON.stringify(metadata) }, sk));
137
- const event = genEvent({ kind: 1, content: 'hello world' }, sk);
161
+ const metadata: NostrMetadata = { nip05: "bot@replyguy.dev" };
162
+ await store.event(
163
+ genEvent({ kind: 0, content: JSON.stringify(metadata) }, sk),
164
+ );
165
+ const event = genEvent({ kind: 1, content: "hello world" }, sk);
138
166
 
139
167
  const result = await policy.call(event);
140
168
 
141
- assertEquals(result, ['OK', event.id, false, 'blocked: nip05 domain not in whitelist']);
169
+ deepStrictEqual(result, [
170
+ "OK",
171
+ event.id,
172
+ false,
173
+ "blocked: nip05 domain not in whitelist",
174
+ ]);
142
175
  });
143
176
 
144
- Deno.test('DomainPolicy allows events from authors who are on a whitelisted domain', async () => {
177
+ await test("DomainPolicy allows events from authors who are on a whitelisted domain", async () => {
145
178
  const sk = generateSecretKey();
146
179
  const pubkey = getPublicKey(sk);
147
180
 
@@ -149,25 +182,27 @@ Deno.test('DomainPolicy allows events from authors who are on a whitelisted doma
149
182
  const policy = new DomainPolicy(store, {
150
183
  // deno-lint-ignore require-await
151
184
  async lookup(nip05: string) {
152
- if (nip05 === 'alex@gleasonator.dev') {
185
+ if (nip05 === "alex@gleasonator.dev") {
153
186
  return { pubkey };
154
187
  } else {
155
- throw new Error('not found');
188
+ throw new Error("not found");
156
189
  }
157
190
  },
158
- whitelist: ['gleasonator.dev'],
191
+ whitelist: ["gleasonator.dev"],
159
192
  });
160
193
 
161
- const metadata: NostrMetadata = { nip05: 'alex@gleasonator.dev' };
162
- await store.event(genEvent({ kind: 0, content: JSON.stringify(metadata) }, sk));
163
- const event = genEvent({ kind: 1, content: 'hello world' }, sk);
194
+ const metadata: NostrMetadata = { nip05: "alex@gleasonator.dev" };
195
+ await store.event(
196
+ genEvent({ kind: 0, content: JSON.stringify(metadata) }, sk),
197
+ );
198
+ const event = genEvent({ kind: 1, content: "hello world" }, sk);
164
199
 
165
200
  const result = await policy.call(event);
166
201
 
167
- assertEquals(result, ['OK', event.id, true, '']);
202
+ deepStrictEqual(result, ["OK", event.id, true, ""]);
168
203
  });
169
204
 
170
- Deno.test('DomainPolicy rejects events from authors with a subdomain of a blacklisted domain', async () => {
205
+ await test("DomainPolicy rejects events from authors with a subdomain of a blacklisted domain", async () => {
171
206
  const sk = generateSecretKey();
172
207
  const pubkey = getPublicKey(sk);
173
208
 
@@ -175,25 +210,32 @@ Deno.test('DomainPolicy rejects events from authors with a subdomain of a blackl
175
210
  const policy = new DomainPolicy(store, {
176
211
  // deno-lint-ignore require-await
177
212
  async lookup(nip05: string) {
178
- if (nip05 === 'bot@spam.replyguy.dev') {
213
+ if (nip05 === "bot@spam.replyguy.dev") {
179
214
  return { pubkey };
180
215
  } else {
181
- throw new Error('not found');
216
+ throw new Error("not found");
182
217
  }
183
218
  },
184
- blacklist: ['replyguy.dev'],
219
+ blacklist: ["replyguy.dev"],
185
220
  });
186
221
 
187
- const metadata: NostrMetadata = { nip05: 'bot@spam.replyguy.dev' };
188
- await store.event(genEvent({ kind: 0, content: JSON.stringify(metadata) }, sk));
189
- const event = genEvent({ kind: 1, content: 'hello world' }, sk);
222
+ const metadata: NostrMetadata = { nip05: "bot@spam.replyguy.dev" };
223
+ await store.event(
224
+ genEvent({ kind: 0, content: JSON.stringify(metadata) }, sk),
225
+ );
226
+ const event = genEvent({ kind: 1, content: "hello world" }, sk);
190
227
 
191
228
  const result = await policy.call(event);
192
229
 
193
- assertEquals(result, ['OK', event.id, false, 'blocked: blacklisted nip05 domain']);
230
+ deepStrictEqual(result, [
231
+ "OK",
232
+ event.id,
233
+ false,
234
+ "blocked: blacklisted nip05 domain",
235
+ ]);
194
236
  });
195
237
 
196
- Deno.test('DomainPolicy rejects events from authors with a deeply nested subdomain of a blacklisted domain', async () => {
238
+ await test("DomainPolicy rejects events from authors with a deeply nested subdomain of a blacklisted domain", async () => {
197
239
  const sk = generateSecretKey();
198
240
  const pubkey = getPublicKey(sk);
199
241
 
@@ -201,25 +243,34 @@ Deno.test('DomainPolicy rejects events from authors with a deeply nested subdoma
201
243
  const policy = new DomainPolicy(store, {
202
244
  // deno-lint-ignore require-await
203
245
  async lookup(nip05: string) {
204
- if (nip05 === 'user@deep.nested.spam.replyguy.dev') {
246
+ if (nip05 === "user@deep.nested.spam.replyguy.dev") {
205
247
  return { pubkey };
206
248
  } else {
207
- throw new Error('not found');
249
+ throw new Error("not found");
208
250
  }
209
251
  },
210
- blacklist: ['replyguy.dev'],
252
+ blacklist: ["replyguy.dev"],
211
253
  });
212
254
 
213
- const metadata: NostrMetadata = { nip05: 'user@deep.nested.spam.replyguy.dev' };
214
- await store.event(genEvent({ kind: 0, content: JSON.stringify(metadata) }, sk));
215
- const event = genEvent({ kind: 1, content: 'hello world' }, sk);
255
+ const metadata: NostrMetadata = {
256
+ nip05: "user@deep.nested.spam.replyguy.dev",
257
+ };
258
+ await store.event(
259
+ genEvent({ kind: 0, content: JSON.stringify(metadata) }, sk),
260
+ );
261
+ const event = genEvent({ kind: 1, content: "hello world" }, sk);
216
262
 
217
263
  const result = await policy.call(event);
218
264
 
219
- assertEquals(result, ['OK', event.id, false, 'blocked: blacklisted nip05 domain']);
265
+ deepStrictEqual(result, [
266
+ "OK",
267
+ event.id,
268
+ false,
269
+ "blocked: blacklisted nip05 domain",
270
+ ]);
220
271
  });
221
272
 
222
- Deno.test('DomainPolicy allows events from authors with similar but not subdomain of blacklisted domain', async () => {
273
+ await test("DomainPolicy allows events from authors with similar but not subdomain of blacklisted domain", async () => {
223
274
  const sk = generateSecretKey();
224
275
  const pubkey = getPublicKey(sk);
225
276
 
@@ -227,20 +278,22 @@ Deno.test('DomainPolicy allows events from authors with similar but not subdomai
227
278
  const policy = new DomainPolicy(store, {
228
279
  // deno-lint-ignore require-await
229
280
  async lookup(nip05: string) {
230
- if (nip05 === 'user@notreplyguy.dev') {
281
+ if (nip05 === "user@notreplyguy.dev") {
231
282
  return { pubkey };
232
283
  } else {
233
- throw new Error('not found');
284
+ throw new Error("not found");
234
285
  }
235
286
  },
236
- blacklist: ['replyguy.dev'],
287
+ blacklist: ["replyguy.dev"],
237
288
  });
238
289
 
239
- const metadata: NostrMetadata = { nip05: 'user@notreplyguy.dev' };
240
- await store.event(genEvent({ kind: 0, content: JSON.stringify(metadata) }, sk));
241
- const event = genEvent({ kind: 1, content: 'hello world' }, sk);
290
+ const metadata: NostrMetadata = { nip05: "user@notreplyguy.dev" };
291
+ await store.event(
292
+ genEvent({ kind: 0, content: JSON.stringify(metadata) }, sk),
293
+ );
294
+ const event = genEvent({ kind: 1, content: "hello world" }, sk);
242
295
 
243
296
  const result = await policy.call(event);
244
297
 
245
- assertEquals(result, ['OK', event.id, true, '']);
298
+ deepStrictEqual(result, ["OK", event.id, true, ""]);
246
299
  });
package/DomainPolicy.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { NIP05, NSchema as n } from '@nostrify/nostrify';
2
- import { NPolicy, NProfilePointer, NStore } from '@nostrify/types';
2
+ import type { NostrEvent, NPolicy, NProfilePointer, NStore } from '@nostrify/types';
3
3
 
4
- import { AuthorPolicy } from './AuthorPolicy.js';
4
+ import { AuthorPolicy } from './AuthorPolicy.ts';
5
5
 
6
6
  /** Options for `DomainPolicy`. */
7
7
  interface DomainPolicyOpts {
@@ -17,7 +17,7 @@ interface DomainPolicyOpts {
17
17
  export class DomainPolicy extends AuthorPolicy implements NPolicy {
18
18
  constructor(store: NStore, opts: DomainPolicyOpts = {}) {
19
19
  super(store, {
20
- async call(event, signal) {
20
+ async call(event: NostrEvent, signal: AbortSignal) {
21
21
  const { blacklist = [], whitelist, lookup = DomainPolicy.lookup } = opts;
22
22
 
23
23
  const metadata = n.json().pipe(n.metadata()).safeParse(event.content);
@@ -1,14 +1,21 @@
1
- import { assertEquals } from '@std/assert';
2
- import { finalizeEvent, generateSecretKey } from 'nostr-tools';
1
+ import { test } from "node:test";
2
+ import { deepStrictEqual } from "node:assert";
3
+ import { finalizeEvent, generateSecretKey } from "nostr-tools";
3
4
 
4
- import { FiltersPolicy } from './FiltersPolicy.ts';
5
+ import { FiltersPolicy } from "./FiltersPolicy.ts";
5
6
 
6
- Deno.test('FiltersPolicy', async () => {
7
+ await test("FiltersPolicy", async () => {
7
8
  const event = finalizeEvent(
8
- { kind: 1, content: '', tags: [], created_at: 0 },
9
+ { kind: 1, content: "", tags: [], created_at: 0 },
9
10
  generateSecretKey(),
10
11
  );
11
12
 
12
- assertEquals((await new FiltersPolicy([{ kinds: [1] }]).call(event))[2], true);
13
- assertEquals((await new FiltersPolicy([{ kinds: [1], authors: [] }]).call(event))[2], false);
13
+ deepStrictEqual(
14
+ (await new FiltersPolicy([{ kinds: [1] }]).call(event))[2],
15
+ true,
16
+ );
17
+ deepStrictEqual(
18
+ (await new FiltersPolicy([{ kinds: [1], authors: [] }]).call(event))[2],
19
+ false,
20
+ );
14
21
  });
package/FiltersPolicy.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { matchFilters } from 'nostr-tools';
2
2
 
3
- import { NostrEvent, NostrFilter, NostrRelayOK, NPolicy } from '@nostrify/types';
3
+ import type { NostrEvent, NostrFilter, NostrRelayOK, NPolicy } from '@nostrify/types';
4
4
 
5
5
  /**
6
6
  * Reject events which don't match the filters.
@@ -14,7 +14,10 @@ import { NostrEvent, NostrFilter, NostrRelayOK, NPolicy } from '@nostrify/types'
14
14
  * ```
15
15
  */
16
16
  export class FiltersPolicy implements NPolicy {
17
- constructor(private filters: NostrFilter[]) {}
17
+ private filters: NostrFilter[];
18
+ constructor(filters: NostrFilter[]) {
19
+ this.filters = filters;
20
+ }
18
21
 
19
22
  // deno-lint-ignore require-await
20
23
  async call(event: NostrEvent): Promise<NostrRelayOK> {
@@ -1,34 +1,45 @@
1
- import { assertEquals } from '@std/assert';
2
- import { finalizeEvent, generateSecretKey } from 'nostr-tools';
1
+ import { test } from "node:test";
2
+ import { deepStrictEqual } from "node:assert";
3
+ import { finalizeEvent, generateSecretKey } from "nostr-tools";
3
4
 
4
- import { HashtagPolicy } from './HashtagPolicy.ts';
5
+ import { HashtagPolicy } from "./HashtagPolicy.ts";
5
6
 
6
- Deno.test('HashtagPolicy', async () => {
7
- const hashtags = ['nsfw'];
7
+ await test("HashtagPolicy", async () => {
8
+ const hashtags = ["nsfw"];
8
9
 
9
10
  const event1 = finalizeEvent(
10
- { kind: 1, content: '', tags: [], created_at: 0 },
11
+ { kind: 1, content: "", tags: [], created_at: 0 },
11
12
  generateSecretKey(),
12
13
  );
13
14
 
14
15
  const event2 = finalizeEvent(
15
- { kind: 1, content: '', tags: [['t', 'nsfw'], ['t', 'other']], created_at: 0 },
16
+ {
17
+ kind: 1,
18
+ content: "",
19
+ tags: [["t", "nsfw"], ["t", "other"]],
20
+ created_at: 0,
21
+ },
16
22
  generateSecretKey(),
17
23
  );
18
24
 
19
25
  const event3 = finalizeEvent(
20
- { kind: 1, content: 'nsfw', tags: [], created_at: 0 },
26
+ { kind: 1, content: "nsfw", tags: [], created_at: 0 },
21
27
  generateSecretKey(),
22
28
  );
23
29
 
24
30
  const event4 = finalizeEvent(
25
- { kind: 1, content: '', tags: [['p', 'nsfw'], ['t', 'other']], created_at: 0 },
31
+ {
32
+ kind: 1,
33
+ content: "",
34
+ tags: [["p", "nsfw"], ["t", "other"]],
35
+ created_at: 0,
36
+ },
26
37
  generateSecretKey(),
27
38
  );
28
39
 
29
- assertEquals((await new HashtagPolicy(hashtags).call(event1))[2], true);
30
- assertEquals((await new HashtagPolicy(hashtags).call(event2))[2], false);
31
- assertEquals((await new HashtagPolicy([]).call(event2))[2], true);
32
- assertEquals((await new HashtagPolicy(hashtags).call(event3))[2], true);
33
- assertEquals((await new HashtagPolicy(hashtags).call(event4))[2], true);
40
+ deepStrictEqual((await new HashtagPolicy(hashtags).call(event1))[2], true);
41
+ deepStrictEqual((await new HashtagPolicy(hashtags).call(event2))[2], false);
42
+ deepStrictEqual((await new HashtagPolicy([]).call(event2))[2], true);
43
+ deepStrictEqual((await new HashtagPolicy(hashtags).call(event3))[2], true);
44
+ deepStrictEqual((await new HashtagPolicy(hashtags).call(event4))[2], true);
34
45
  });
package/HashtagPolicy.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { NostrEvent, NostrRelayOK, NPolicy } from '@nostrify/types';
1
+ import type { NostrEvent, NostrRelayOK, NPolicy } from '@nostrify/types';
2
2
 
3
3
  /**
4
4
  * Reject events containing any of the banned hashtags.
@@ -10,7 +10,10 @@ import { NostrEvent, NostrRelayOK, NPolicy } from '@nostrify/types';
10
10
  * ```
11
11
  */
12
12
  export class HashtagPolicy implements NPolicy {
13
- constructor(private hashtags: string[]) {}
13
+ private hashtags: string[];
14
+ constructor(hashtags: string[]) {
15
+ this.hashtags = hashtags;
16
+ }
14
17
 
15
18
  // deno-lint-ignore require-await
16
19
  async call({ id, tags }: NostrEvent): Promise<NostrRelayOK> {
@@ -1,23 +1,24 @@
1
- import { assertEquals } from '@std/assert';
2
- import { finalizeEvent, generateSecretKey } from 'nostr-tools';
1
+ import { test } from "node:test";
2
+ import { deepStrictEqual } from "node:assert";
3
+ import { finalizeEvent, generateSecretKey } from "nostr-tools";
3
4
 
4
- import { HellthreadPolicy } from './HellthreadPolicy.ts';
5
+ import { HellthreadPolicy } from "./HellthreadPolicy.ts";
5
6
 
6
- Deno.test('HellthreadPolicy', async () => {
7
+ await test("HellthreadPolicy", async () => {
7
8
  const policy = new HellthreadPolicy({ limit: 1 });
8
9
 
9
10
  const okEvent = finalizeEvent(
10
- { kind: 1, content: '', tags: [], created_at: 0 },
11
+ { kind: 1, content: "", tags: [], created_at: 0 },
11
12
  generateSecretKey(),
12
13
  );
13
14
 
14
15
  const badEvent = finalizeEvent({
15
16
  kind: 1,
16
- content: '',
17
- tags: [['p'], ['p'], ['p']],
17
+ content: "",
18
+ tags: [["p"], ["p"], ["p"]],
18
19
  created_at: 0,
19
20
  }, generateSecretKey());
20
21
 
21
- assertEquals((await policy.call(okEvent))[2], true);
22
- assertEquals((await policy.call(badEvent))[2], false);
22
+ deepStrictEqual((await policy.call(okEvent))[2], true);
23
+ deepStrictEqual((await policy.call(badEvent))[2], false);
23
24
  });
@@ -1,4 +1,4 @@
1
- import { NostrEvent, NostrRelayOK, NPolicy } from '@nostrify/types';
1
+ import type { NostrEvent, NostrRelayOK, NPolicy } from '@nostrify/types';
2
2
 
3
3
  /** Policy options for `HellthreadPolicy`. */
4
4
  interface HellthreadPolicyOpts {
@@ -8,14 +8,17 @@ interface HellthreadPolicyOpts {
8
8
 
9
9
  /** Basic policy to demonstrate how policies work. Accepts all events. */
10
10
  export class HellthreadPolicy implements NPolicy {
11
- constructor(private opts: HellthreadPolicyOpts = {}) {}
11
+ private opts: HellthreadPolicyOpts;
12
+ constructor(opts: HellthreadPolicyOpts = {}) {
13
+ this.opts = opts;
14
+ }
12
15
 
13
16
  // deno-lint-ignore require-await
14
17
  async call({ id, kind, tags }: NostrEvent): Promise<NostrRelayOK> {
15
18
  const { limit = 100 } = this.opts;
16
19
 
17
20
  if (kind === 1) {
18
- const p = tags.filter((tag) => tag[0] === 'p');
21
+ const p = tags.filter((tag: string[]) => tag[0] === 'p');
19
22
 
20
23
  if (p.length > limit) {
21
24
  return ['OK', id, false, `blocked: rejected due to ${p.length} "p" tags (${limit} is the limit).`];
@@ -1,19 +1,20 @@
1
- import { assertEquals } from '@std/assert';
2
- import { finalizeEvent, generateSecretKey } from 'nostr-tools';
1
+ import { test } from "node:test";
2
+ import { deepStrictEqual } from "node:assert";
3
+ import { finalizeEvent, generateSecretKey } from "nostr-tools";
3
4
 
4
- import { InvertPolicy } from './InvertPolicy.ts';
5
- import { NoOpPolicy } from './NoOpPolicy.ts';
5
+ import { InvertPolicy } from "./InvertPolicy.ts";
6
+ import { NoOpPolicy } from "./NoOpPolicy.ts";
6
7
 
7
- Deno.test('InvertPolicy', async () => {
8
- const policy = new InvertPolicy(new NoOpPolicy(), 'blocked: inverted');
8
+ await test("InvertPolicy", async () => {
9
+ const policy = new InvertPolicy(new NoOpPolicy(), "blocked: inverted");
9
10
 
10
11
  const event = finalizeEvent(
11
- { kind: 1, content: '', tags: [], created_at: 0 },
12
+ { kind: 1, content: "", tags: [], created_at: 0 },
12
13
  generateSecretKey(),
13
14
  );
14
15
 
15
16
  const [_, _eventId, ok, reason] = await policy.call(event);
16
17
 
17
- assertEquals(ok, false);
18
- assertEquals(reason, 'blocked: inverted');
18
+ deepStrictEqual(ok, false);
19
+ deepStrictEqual(reason, "blocked: inverted");
19
20
  });
package/InvertPolicy.ts CHANGED
@@ -1,8 +1,14 @@
1
- import { NostrEvent, NostrRelayOK, NPolicy } from '@nostrify/types';
1
+ import type { NostrEvent, NostrRelayOK, NPolicy } from '@nostrify/types';
2
2
 
3
3
  /** Rejects if the policy passes, passes if the policy rejects. */
4
4
  export class InvertPolicy implements NPolicy {
5
- constructor(private policy: NPolicy, private reason: string) {}
5
+ private policy: NPolicy;
6
+ private reason: string;
7
+
8
+ constructor(policy: NPolicy, reason: string) {
9
+ this.policy = policy;
10
+ this.reason = reason;
11
+ }
6
12
 
7
13
  async call(event: NostrEvent): Promise<NostrRelayOK> {
8
14
  const result = await this.policy.call(event);