Files: 8fd6613c73b3cc03e594c3a4ad89e3303cfd5131 / lib / util.js
5505 bytesRaw
1 | var pull = require('pull-stream') |
2 | var cat = require('pull-cat') |
3 | var h = require('hyperscript') |
4 | var b64url = require('base64-url') |
5 | var u = exports |
6 | |
7 | u.ssbRefRegex = /((?:@|%|&|ssb:\/\/%)[A-Za-z0-9\/+]{43}=\.[\w\d]+)/g |
8 | u.ssbRefRegexOnly = /^(?:@|%|&|ssb:\/\/%)[A-Za-z0-9\/+]{43}=\.[\w\d]+$/ |
9 | u.ssbRefEncRegex = /((?:ssb:\/\/)?(?:[@%&]|%26|%40|%25)(?:[A-Za-z0-9\/+]|%2[fF]|%2[bB]){43}(?:=|%3[dD])\.[\w\d]+)/g |
10 | |
11 | u.isRef = function (str) { |
12 | if (!str) return false |
13 | u.ssbRefRegexOnly.lastIndex = 0 |
14 | return u.ssbRefRegexOnly.test(str) |
15 | } |
16 | |
17 | u.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 | |
29 | u.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 | |
39 | u.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 | |
49 | u.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 | |
68 | u.ifString = function (str) { |
69 | if (typeof str === 'string') return str |
70 | } |
71 | |
72 | u.ifNumber = function (num) { |
73 | if (!isNaN(num)) return num |
74 | } |
75 | |
76 | u.toLink = function (link) { |
77 | return typeof link === 'string' ? {link: link} : link || null |
78 | } |
79 | |
80 | u.linkDest = function (link) { |
81 | return link && (u.ifString(link) || u.ifString(link.link)) |
82 | } |
83 | |
84 | u.toArray = function (x) { |
85 | return x == null ? [] : Array.isArray(x) ? x : [x] |
86 | } |
87 | |
88 | u.fromArray = function (arr) { |
89 | return Array.isArray(arr) && arr.length === 1 ? arr[0] : arr |
90 | } |
91 | |
92 | u.toLinkArray = function (x) { |
93 | return u.toArray(x).map(u.toLink).filter(u.linkDest) |
94 | } |
95 | |
96 | u.renderError = function(err) { |
97 | return h('div.error', |
98 | h('h3', err.name), |
99 | h('pre', err.stack)) |
100 | } |
101 | |
102 | u.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 | |
111 | u.tryDecodeJSON = function (json) { |
112 | try { |
113 | return JSON.parse(json) |
114 | } catch(e) { |
115 | return null |
116 | } |
117 | } |
118 | |
119 | u.extractRefs = function (str) { |
120 | var ids = [] |
121 | String(str).replace(u.ssbRefRegex, function (id) { |
122 | ids.push(id) |
123 | }) |
124 | return ids |
125 | } |
126 | |
127 | u.extractFeedIds = function (str) { |
128 | return u.extractRefs(str).filter(function (ref) { |
129 | return ref[0] === '@' |
130 | }) |
131 | } |
132 | |
133 | u.extractBlobIds = function (str) { |
134 | return u.extractRefs(str).filter(function (ref) { |
135 | return ref[0] === '&' |
136 | }) |
137 | } |
138 | |
139 | u.isMsgReadable = function (msg) { |
140 | var c = msg && msg.value && msg.value.content |
141 | return typeof c === 'object' && c !== null |
142 | } |
143 | |
144 | u.isMsgEncrypted = function (msg) { |
145 | var c = msg && msg.value.content |
146 | return typeof c === 'string' |
147 | } |
148 | |
149 | u.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 | |
156 | u.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 | |
165 | u.escapeHTML = function (html) { |
166 | if (!html) return '' |
167 | return html.toString('utf8') |
168 | .replace(/</g, '<') |
169 | .replace(/>/g, '>') |
170 | } |
171 | |
172 | u.pullSlice = function (start, end) { |
173 | if (end == null) end = Infinity |
174 | var offset = 0 |
175 | return function (read) { |
176 | return function (abort, cb) { |
177 | if (abort) read(abort, cb) |
178 | else if (offset >= end) read(true, function (err) { |
179 | cb(err || true) |
180 | }) |
181 | else if (offset < start) read(null, function next(err, data) { |
182 | if (err) return cb(err) |
183 | offset += data.length |
184 | if (offset <= start) read(null, next) |
185 | else if (offset < end) cb(null, |
186 | data.slice(data.length - (offset - start))) |
187 | else cb(null, data.slice(data.length - (offset - start), |
188 | data.length - (offset - end))) |
189 | }) |
190 | else read(null, function (err, data) { |
191 | if (err) return cb(err) |
192 | offset += data.length |
193 | if (offset <= end) cb(null, data) |
194 | else cb(null, data.slice(0, data.length - (offset - end))) |
195 | }) |
196 | } |
197 | } |
198 | } |
199 | |
200 | u.mergeOpts = function (a, b) { |
201 | var obj = {}, k |
202 | for (k in a) { |
203 | obj[k] = a[k] |
204 | } |
205 | for (k in b) { |
206 | if (b[k] != null) obj[k] = b[k] |
207 | else delete obj[k] |
208 | } |
209 | return obj |
210 | } |
211 | |
212 | u.escapeId = function (id) { |
213 | return b64url.escape(id) |
214 | } |
215 | |
216 | u.unescapeId = function (str) { |
217 | var m = /^(.)(.*)(\..*)$/.exec(str) |
218 | if (!m) return b64url.unescape(str) |
219 | return m[1] + b64url.unescape(m[2]) + m[3] |
220 | } |
221 | |
222 | u.rows = function (str) { |
223 | return String(str).split(/[^\n]{150}|\n/).length |
224 | } |
225 | |
226 | u.token = function () { |
227 | return '__' + Math.random().toString(36).substr(2) + '__' |
228 | } |
229 | |
230 | u.unwrapP = function(html) { |
231 | return String(html).replace(/^<p>(.*)<\/p>\s*$/, function ($0, $1) { |
232 | return $1 |
233 | }) |
234 | } |
235 | |
236 |
Built with git-ssb-web