git ssb

16+

cel / patchfoo



Tree: 01ea88684375793b3e009d8cefb9722384e2c88b

Files: 01ea88684375793b3e009d8cefb9722384e2c88b / lib / util.js

6879 bytesRaw
1var pull = require('pull-stream')
2var cat = require('pull-cat')
3var h = require('hyperscript')
4var b64url = require('base64-url')
5var u = exports
6
7u.ssbRefRegex = /((?:@|%|&|ssb:\/\/%)[A-Za-z0-9\/+]{43}=\.[\w\d]+)/g
8u.ssbRefRegexOnly = /^(?:@|%|&|ssb:\/\/%)[A-Za-z0-9\/+]{43}=\.[\w\d]+$/
9u.ssbRefEncRegex = /((?:ssb:\/\/)?(?:[@%&]|%26|%40|%25)(?:[A-Za-z0-9\/+]|%2[fF]|%2[bB]){43}(?:=|%3[dD])\.[\w\d]+)/g
10
11u.isRef = function (str) {
12 if (!str) return false
13 u.ssbRefRegexOnly.lastIndex = 0
14 return u.ssbRefRegexOnly.test(str)
15}
16
17u.readNext = function (fn) {
18 var next
19 return function (end, cb) {
20 if (next) return next(end, cb)
21 fn(function (err, _next) {
22 if (err) return cb(err)
23 next = _next
24 next(null, cb)
25 })
26 }
27}
28
29u.pullReverse = function () {
30 return function (read) {
31 return u.readNext(function (cb) {
32 pull(read, pull.collect(function (err, items) {
33 cb(err, items && pull.values(items.reverse()))
34 }))
35 })
36 }
37}
38
39u.toHTML = function (el) {
40 if (!el) return ''
41 if (typeof el === 'string' || Array.isArray(el)) {
42 return h('div', el).innerHTML
43 }
44 var html = el.outerHTML || String(el)
45 if (el.nodeName === 'html') html = '<!doctype html>' + html + '\n'
46 return html
47}
48
49u.hyperwrap = function (fn) {
50 var token = '__HYPERWRAP_' + Math.random() + '__'
51 return function (read) {
52 return u.readNext(function (cb) {
53 fn(token, function (err, el) {
54 if (err) return cb(err)
55 var parts = u.toHTML(el).split(token)
56 switch (parts.length) {
57 case 0: return cb(null, pull.empty())
58 case 1: return cb(null, pull.once(parts[0]))
59 case 2: return cb(null,
60 cat([pull.once(parts[0]), read, pull.once(parts[1])]))
61 default: return cb(new Error('duplicate wrap'))
62 }
63 })
64 })
65 }
66}
67
68u.ifString = function (str) {
69 if (typeof str === 'string') return str
70}
71
72u.ifNumber = function (num) {
73 if (!isNaN(num)) return num
74}
75
76u.toLink = function (link) {
77 return typeof link === 'string' ? {link: link} : link || null
78}
79
80u.linkDest = function (link) {
81 return link && (u.ifString(link) || u.ifString(link.link))
82}
83
84u.toArray = function (x) {
85 return x == null ? [] : Array.isArray(x) ? x : [x]
86}
87
88u.fromArray = function (arr) {
89 return Array.isArray(arr) && arr.length === 1 ? arr[0] : arr
90}
91
92u.toLinkArray = function (x) {
93 return u.toArray(x).map(u.toLink).filter(u.linkDest)
94}
95
96u.renderError = function(err) {
97 return h('div.error',
98 h('h3', err.name),
99 h('pre', err.stack))
100}
101
102u.pullLength = function (cb) {
103 var len = 0
104 return pull.through(function (data) {
105 len += data.length
106 }, function (err) {
107 cb(err, len)
108 })
109}
110
111u.tryDecodeJSON = function (json) {
112 try {
113 return JSON.parse(json)
114 } catch(e) {
115 return null
116 }
117}
118
119u.extractRefs = function (str) {
120 var ids = []
121 String(str).replace(u.ssbRefRegex, function (id) {
122 ids.push(id)
123 })
124 return ids
125}
126
127u.extractFeedIds = function (str) {
128 return u.extractRefs(str).filter(function (ref) {
129 return ref[0] === '@'
130 })
131}
132
133u.extractBlobIds = function (str) {
134 return u.extractRefs(str).filter(function (ref) {
135 return ref[0] === '&'
136 })
137}
138
139u.isMsgReadable = function (msg) {
140 var c = msg && msg.value && msg.value.content
141 return typeof c === 'object' && c !== null
142}
143
144u.isMsgEncrypted = function (msg) {
145 var value = msg && msg.value
146 return value && (value.private || typeof value.content === 'string')
147}
148
149u.pullConcat = function (cb) {
150 return pull.collect(function (err, bufs) {
151 if (err) return cb(err)
152 cb(null, Buffer.concat(bufs))
153 })
154}
155
156u.customError = function (name) {
157 return function (message) {
158 var error = new Error(message)
159 error.name = name
160 error.stack = error.stack.replace(/^ at .*\n/m, '')
161 return error
162 }
163}
164
165u.escapeHTML = function (html) {
166 if (!html) return ''
167 return html.toString('utf8')
168 .replace(/&/g, '&amp;')
169 .replace(/"/g, '&quot;')
170 .replace(/</g, '&lt;')
171 .replace(/>/g, '&gt;')
172 .replace(/\n/g, '&#x0a;')
173}
174
175u.unescapeHTML = function (text) {
176 if (typeof text !== 'string') return text
177 return text.replace(/&amp;/g, '&')
178 .replace(/&quot;/g, '"')
179 .replace(/&#39;/g, '\'')
180 .replace(/&gt;/g, '>')
181 .replace(/&lt;/g, '<')
182}
183
184u.pullSlice = function (start, end) {
185 if (end == null) end = Infinity
186 var offset = 0
187 return function (read) {
188 return function (abort, cb) {
189 if (abort) read(abort, cb)
190 else if (offset >= end) read(true, function (err) {
191 cb(err || true)
192 })
193 else if (offset < start) read(null, function next(err, data) {
194 if (err) return cb(err)
195 offset += data.length
196 if (offset <= start) read(null, next)
197 else if (offset < end) cb(null,
198 data.slice(data.length - (offset - start)))
199 else cb(null, data.slice(data.length - (offset - start),
200 data.length - (offset - end)))
201 })
202 else read(null, function (err, data) {
203 if (err) return cb(err)
204 offset += data.length
205 if (offset <= end) cb(null, data)
206 else cb(null, data.slice(0, data.length - (offset - end)))
207 })
208 }
209 }
210}
211
212u.mergeOpts = function (a, b) {
213 var obj = {}, k
214 for (k in a) {
215 obj[k] = a[k]
216 }
217 for (k in b) {
218 if (b[k] != null) obj[k] = b[k]
219 else delete obj[k]
220 }
221 return obj
222}
223
224u.escapeId = function (id) {
225 return b64url.escape(id)
226}
227
228u.unescapeId = function (str) {
229 var m = /^(.)(.*)(\..*)$/.exec(str)
230 if (!m) return b64url.unescape(str)
231 return m[1] + b64url.unescape(m[2]) + m[3]
232}
233
234u.rows = function (str) {
235 return String(str).split(/[^\n]{150}|\n/).length
236}
237
238u.token = function () {
239 return '__' + Math.random().toString(36).substr(2) + '__'
240}
241
242u.unwrapP = function(html) {
243 return String(html).replace(/^<p>(.*)<\/p>\s*$/, function ($0, $1) {
244 return $1
245 })
246}
247
248u.estimateMessageSize = function (content) {
249 var draftMsg = {
250 key: '%0000000000000000000000000000000000000000000=.sha256',
251 value: {
252 previous: '%0000000000000000000000000000000000000000000=.sha256',
253 author: '@0000000000000000000000000000000000000000000=.ed25519',
254 sequence: 10000,
255 timestamp: 1000000000000,
256 hash: 'sha256',
257 content: content,
258 signature: '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000==.sig.ed25519'
259 }
260 }
261
262 return JSON.stringify(draftMsg, null, 2).length
263}
264
265u.truncate = function (str, len) {
266 str = String(str)
267 return str.length > len ? str.substr(0, len) + '...' : str
268}
269
270u.extractHostPort = function (id, addr) {
271 var i = addr.lastIndexOf(':' + id)
272 if (i > -1 && addr.length === i + id.length + 1) {
273 return addr.substr(0, i)
274 }
275 var m = /^(?:net|onion):([^~;]*(?::[0-9]*)?)~shs:([0-9a-zA-Z/=+]{44})$/.exec(addr)
276 if (m && id === '@' + m[2] + '.ed25519') {
277 return m[1]
278 }
279 return addr
280}
281

Built with git-ssb-web