libp2r2p 0.10.7 → 0.10.9
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/nip27/helpers/user-reference.js +8 -8
- package/nip27/index.js +2 -2
- package/package.json +1 -1
- package/url/app-url.js +52 -3
|
@@ -24,8 +24,8 @@ function stripReferencePrefix (value) {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
// Decodes a user reference without performing any network lookup.
|
|
27
|
-
// Returns `{
|
|
28
|
-
// `{
|
|
27
|
+
// Returns `{ type: 'pubkey', pubkey, relays, raw }` for npub/nprofile/hex or
|
|
28
|
+
// `{ type: 'nip05', local, domain, raw }` for NIP-05 (standard or extended),
|
|
29
29
|
// where `raw` is always the most compact canonical spelling.
|
|
30
30
|
export function decodeUserReference (value) {
|
|
31
31
|
if (typeof value !== 'string') return null
|
|
@@ -34,13 +34,13 @@ export function decodeUserReference (value) {
|
|
|
34
34
|
|
|
35
35
|
if (HEX_PUBKEY.test(text)) {
|
|
36
36
|
const raw = text.toLowerCase()
|
|
37
|
-
return {
|
|
37
|
+
return { type: 'pubkey', pubkey: raw, relays: [], raw }
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
if (text.toLowerCase().startsWith('npub1')) {
|
|
41
41
|
try {
|
|
42
42
|
const raw = text.toLowerCase()
|
|
43
|
-
return {
|
|
43
|
+
return { type: 'pubkey', pubkey: npubDecode(raw), relays: [], raw }
|
|
44
44
|
} catch {
|
|
45
45
|
return null
|
|
46
46
|
}
|
|
@@ -50,7 +50,7 @@ export function decodeUserReference (value) {
|
|
|
50
50
|
try {
|
|
51
51
|
const raw = text.toLowerCase()
|
|
52
52
|
const { pubkey, relays } = nprofileDecode(raw)
|
|
53
|
-
return {
|
|
53
|
+
return { type: 'pubkey', pubkey, relays, raw }
|
|
54
54
|
} catch {
|
|
55
55
|
return null
|
|
56
56
|
}
|
|
@@ -59,7 +59,7 @@ export function decodeUserReference (value) {
|
|
|
59
59
|
const nip05 = decodeNip05Identifier(text)
|
|
60
60
|
if (!nip05) return null
|
|
61
61
|
const raw = compactNip05Raw(nip05.local, nip05.domain)
|
|
62
|
-
return {
|
|
62
|
+
return { type: 'nip05', ...nip05, raw }
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
// Returns the canonical compact spelling for a user reference, either as a
|
|
@@ -68,12 +68,12 @@ export function encodeUserReference (value) {
|
|
|
68
68
|
const ref = typeof value === 'string'
|
|
69
69
|
? decodeUserReference(value)
|
|
70
70
|
: value && typeof value === 'object' &&
|
|
71
|
-
(value.
|
|
71
|
+
(value.type === 'pubkey' || value.type === 'nip05')
|
|
72
72
|
? value
|
|
73
73
|
: null
|
|
74
74
|
if (!ref) {
|
|
75
75
|
throw new ValidationError('INVALID_USER_REFERENCE', { message: 'Invalid user reference' })
|
|
76
76
|
}
|
|
77
|
-
if (ref.
|
|
77
|
+
if (ref.type === 'pubkey') return ref.raw ?? ref.pubkey
|
|
78
78
|
return ref.raw ?? compactNip05Raw(ref.local, ref.domain)
|
|
79
79
|
}
|
package/nip27/index.js
CHANGED
|
@@ -119,7 +119,7 @@ export function decodeReference (value) {
|
|
|
119
119
|
|
|
120
120
|
const account = decodeUserReference(text)
|
|
121
121
|
if (account) {
|
|
122
|
-
return account.
|
|
122
|
+
return account.type === 'pubkey'
|
|
123
123
|
? {
|
|
124
124
|
type: 'pubkey',
|
|
125
125
|
original,
|
|
@@ -350,7 +350,7 @@ export function extractMedia (content, { bareNip05 = false, getMimeType } = {})
|
|
|
350
350
|
export async function resolveUserReference (value, options = {}) {
|
|
351
351
|
const account = decodeUserReference(value)
|
|
352
352
|
if (!account) return null
|
|
353
|
-
if (account.
|
|
353
|
+
if (account.type === 'pubkey') {
|
|
354
354
|
return { pubkey: account.pubkey, relays: account.relays, label: account.raw }
|
|
355
355
|
}
|
|
356
356
|
|
package/package.json
CHANGED
package/url/app-url.js
CHANGED
|
@@ -9,11 +9,25 @@ import {
|
|
|
9
9
|
} from '../nip27/helpers/user-reference.js'
|
|
10
10
|
import {
|
|
11
11
|
NAPP_ENTITY_REGEX,
|
|
12
|
-
appDecode
|
|
12
|
+
appDecode,
|
|
13
|
+
appEncode,
|
|
14
|
+
naddrDecode
|
|
13
15
|
} from '../nip19/index.js'
|
|
16
|
+
import {
|
|
17
|
+
DRAFT_SITE_MANIFEST,
|
|
18
|
+
MAIN_SITE_MANIFEST,
|
|
19
|
+
NEXT_SITE_MANIFEST
|
|
20
|
+
} from '../kind/index.js'
|
|
14
21
|
|
|
15
22
|
export const APP_URL_MIN_ENTITY_BODY_LENGTH = 48
|
|
16
23
|
|
|
24
|
+
const SITE_MANIFEST_KINDS = new Set([
|
|
25
|
+
MAIN_SITE_MANIFEST,
|
|
26
|
+
NEXT_SITE_MANIFEST,
|
|
27
|
+
DRAFT_SITE_MANIFEST
|
|
28
|
+
])
|
|
29
|
+
const NADDR_PREFIX = 'naddr1'
|
|
30
|
+
|
|
17
31
|
const APP_NAME_MAX_LENGTH = 260
|
|
18
32
|
const CHANNEL_BY_PREFIX = { '+': 'main', '++': 'next', '+++': 'draft' }
|
|
19
33
|
const PREFIX_BY_CHANNEL = { main: '+', next: '++', draft: '+++' }
|
|
@@ -38,6 +52,38 @@ function isValidAppName (appName) {
|
|
|
38
52
|
!CONTROL_CHARS.test(appName)
|
|
39
53
|
}
|
|
40
54
|
|
|
55
|
+
// `naddr` already carries the event kind, so it does not need the `+`/`++`/
|
|
56
|
+
// `+++` channel prefix (a leading prefix is still tolerated). Only site
|
|
57
|
+
// manifests are app URLs; the result is canonicalized to the `appEncode`
|
|
58
|
+
// entity so downstream code keeps working unchanged.
|
|
59
|
+
function tryDecodeNaddr (value) {
|
|
60
|
+
if (typeof value !== 'string' || !value) return null
|
|
61
|
+
const body = value.replace(/^\+{1,3}/, '')
|
|
62
|
+
if (!body.startsWith(NADDR_PREFIX)) return null
|
|
63
|
+
|
|
64
|
+
let decoded
|
|
65
|
+
try {
|
|
66
|
+
decoded = naddrDecode(body)
|
|
67
|
+
} catch {
|
|
68
|
+
return null
|
|
69
|
+
}
|
|
70
|
+
if (!SITE_MANIFEST_KINDS.has(decoded.kind)) return null
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
return {
|
|
74
|
+
type: 'entity',
|
|
75
|
+
entity: appEncode({
|
|
76
|
+
dTag: decoded.identifier,
|
|
77
|
+
pubkey: decoded.pubkey,
|
|
78
|
+
kind: decoded.kind,
|
|
79
|
+
relays: decoded.relays
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
} catch {
|
|
83
|
+
return null
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
41
87
|
// Decodes a raw (still percent-encoded) first path segment such as
|
|
42
88
|
// `+apps` or `+caf%C3%A9@bob@example.com` or `+3swFhu...`.
|
|
43
89
|
// Returns:
|
|
@@ -47,6 +93,9 @@ function isValidAppName (appName) {
|
|
|
47
93
|
// - `null` when the segment is not a valid app URL.
|
|
48
94
|
export function decodeAppUrl (segment) {
|
|
49
95
|
if (typeof segment !== 'string' || !segment) return null
|
|
96
|
+
const decodedNaddr = tryDecodeNaddr(segment)
|
|
97
|
+
if (decodedNaddr) return decodedNaddr
|
|
98
|
+
|
|
50
99
|
const prefixMatch = segment.match(/^\+{1,3}/)
|
|
51
100
|
if (!prefixMatch) return null
|
|
52
101
|
const prefix = prefixMatch[0]
|
|
@@ -77,7 +126,7 @@ export function decodeAppUrl (segment) {
|
|
|
77
126
|
const domain = safeDecode(parts[parts.length - 1])
|
|
78
127
|
const nip05 = nip05FromLocalDomain(local, domain)
|
|
79
128
|
if (nip05) {
|
|
80
|
-
user = {
|
|
129
|
+
user = { type: 'nip05', ...nip05, raw: compactNip05Raw(local, domain) }
|
|
81
130
|
appName = parts.slice(0, -2).map(safeDecode).join('@')
|
|
82
131
|
} else {
|
|
83
132
|
appName = safeDecode(remainder)
|
|
@@ -114,7 +163,7 @@ export function encodeAppUrl ({ appName, channel = 'main', user }) {
|
|
|
114
163
|
|
|
115
164
|
let encodedAppName = encodeURIComponent(appName)
|
|
116
165
|
let userText
|
|
117
|
-
if (userRef.
|
|
166
|
+
if (userRef.type === 'nip05') {
|
|
118
167
|
// Keep `@` raw inside the app name so the verbose NIP-05 form stays
|
|
119
168
|
// readable (`+my@app@bob@example.com`).
|
|
120
169
|
encodedAppName = encodedAppName.replace(/%40/g, '@')
|