@heroku/heroku-cli-util 8.0.14 → 9.0.0-beta.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.
- package/LICENSE +15 -3
- package/README.md +44 -241
- package/dist/test-helpers/expect-output.d.ts +2 -0
- package/dist/test-helpers/expect-output.js +16 -0
- package/dist/test-helpers/init.d.ts +1 -0
- package/dist/test-helpers/init.js +18 -0
- package/dist/test-helpers/stub-output.d.ts +2 -0
- package/dist/test-helpers/stub-output.js +33 -0
- package/dist/types/errors/ambiguous.d.ts +15 -0
- package/dist/types/errors/ambiguous.js +14 -0
- package/dist/types/errors/not-found.d.ts +5 -0
- package/dist/types/errors/not-found.js +12 -0
- package/dist/types/pg/data-api.d.ts +17 -0
- package/dist/types/pg/data-api.js +2 -0
- package/dist/types/pg/tunnel.d.ts +22 -0
- package/dist/types/pg/tunnel.js +2 -0
- package/dist/utils/addons/resolve.d.ts +9 -0
- package/dist/utils/addons/resolve.js +39 -0
- package/dist/utils/pg/bastion.d.ts +30 -0
- package/dist/utils/pg/bastion.js +122 -0
- package/dist/utils/pg/config-vars.d.ts +8 -0
- package/dist/utils/pg/config-vars.js +34 -0
- package/dist/utils/pg/databases.d.ts +12 -0
- package/dist/utils/pg/databases.js +137 -0
- package/dist/utils/pg/host.d.ts +1 -0
- package/dist/utils/pg/host.js +7 -0
- package/dist/utils/pg/psql.d.ts +28 -0
- package/dist/utils/pg/psql.js +188 -0
- package/dist/ux/confirm.d.ts +1 -0
- package/dist/ux/confirm.js +7 -0
- package/dist/ux/prompt.d.ts +2 -0
- package/dist/ux/prompt.js +7 -0
- package/dist/ux/styled-header.d.ts +1 -0
- package/dist/ux/styled-header.js +7 -0
- package/dist/ux/styled-json.d.ts +1 -0
- package/dist/ux/styled-json.js +7 -0
- package/dist/ux/styled-object.d.ts +1 -0
- package/dist/ux/styled-object.js +7 -0
- package/dist/ux/table.d.ts +2 -0
- package/dist/ux/table.js +7 -0
- package/dist/ux/wait.d.ts +1 -0
- package/dist/ux/wait.js +7 -0
- package/package.json +54 -55
- package/index.js +0 -40
- package/lib/action.js +0 -54
- package/lib/auth.js +0 -207
- package/lib/command.js +0 -171
- package/lib/console.js +0 -105
- package/lib/date.js +0 -18
- package/lib/errors.js +0 -122
- package/lib/exit.js +0 -42
- package/lib/got.js +0 -153
- package/lib/linewrap.js +0 -783
- package/lib/mutex.js +0 -41
- package/lib/open.js +0 -22
- package/lib/preauth.js +0 -26
- package/lib/process.js +0 -14
- package/lib/prompt.js +0 -150
- package/lib/spinner.js +0 -147
- package/lib/spinners.json +0 -739
- package/lib/styled.js +0 -131
- package/lib/table.js +0 -132
- package/lib/util.js +0 -38
- package/lib/vars.js +0 -29
- package/lib/yubikey.js +0 -14
package/lib/linewrap.js
DELETED
|
@@ -1,783 +0,0 @@
|
|
|
1
|
-
// code is from https://github.com/AnAppAMonth/linewrap
|
|
2
|
-
|
|
3
|
-
// Presets
|
|
4
|
-
var presetMap = {
|
|
5
|
-
'html': {
|
|
6
|
-
skipScheme: 'html',
|
|
7
|
-
lineBreakScheme: 'html',
|
|
8
|
-
whitespace: 'collapse'
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// lineBreak Schemes
|
|
13
|
-
var brPat = /<\s*br(?:[\s/]*|\s[^>]*)>/gi
|
|
14
|
-
var lineBreakSchemeMap = {
|
|
15
|
-
'unix': [/\n/g, '\n'],
|
|
16
|
-
'dos': [/\r\n/g, '\r\n'],
|
|
17
|
-
'mac': [/\r/g, '\r'],
|
|
18
|
-
'html': [brPat, '<br>'],
|
|
19
|
-
'xhtml': [brPat, '<br/>']
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// skip Schemes
|
|
23
|
-
var skipSchemeMap = {
|
|
24
|
-
'ansi-color': /\x1B\[[^m]*m/g,
|
|
25
|
-
'html': /<[^>]*>/g,
|
|
26
|
-
'bbcode': /\[[^]]*\]/g
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
var modeMap = {
|
|
30
|
-
'soft': 1,
|
|
31
|
-
'hard': 1
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
var wsMap = {
|
|
35
|
-
'collapse': 1,
|
|
36
|
-
'default': 1,
|
|
37
|
-
'line': 1,
|
|
38
|
-
'all': 1
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
var rlbMap = {
|
|
42
|
-
'all': 1,
|
|
43
|
-
'multi': 1,
|
|
44
|
-
'none': 1
|
|
45
|
-
}
|
|
46
|
-
var rlbSMPat = /([sm])(\d+)/
|
|
47
|
-
|
|
48
|
-
var escapePat = /[-/\\^$*+?.()|[\]{}]/g
|
|
49
|
-
function escapeRegExp (s) {
|
|
50
|
-
return s.replace(escapePat, '\\$&')
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
var linewrap = module.exports = function (start, stop, params) {
|
|
54
|
-
if (typeof start === 'object') {
|
|
55
|
-
params = start
|
|
56
|
-
start = params.start
|
|
57
|
-
stop = params.stop
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (typeof stop === 'object') {
|
|
61
|
-
params = stop
|
|
62
|
-
start = start || params.start
|
|
63
|
-
stop = undefined
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
if (!stop) {
|
|
67
|
-
stop = start
|
|
68
|
-
start = 0
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
if (!params) { params = {}; }
|
|
72
|
-
// Supported options and default values.
|
|
73
|
-
var preset,
|
|
74
|
-
mode = 'soft',
|
|
75
|
-
whitespace = 'default',
|
|
76
|
-
tabWidth = 4,
|
|
77
|
-
skip, skipScheme, lineBreak, lineBreakScheme,
|
|
78
|
-
respectLineBreaks = 'all',
|
|
79
|
-
respectNum,
|
|
80
|
-
preservedLineIndent,
|
|
81
|
-
wrapLineIndent, wrapLineIndentBase
|
|
82
|
-
|
|
83
|
-
var skipPat
|
|
84
|
-
var lineBreakPat, lineBreakStr
|
|
85
|
-
var multiLineBreakPat
|
|
86
|
-
var preservedLinePrefix = ''
|
|
87
|
-
var wrapLineIndentPat, wrapLineInitPrefix = ''
|
|
88
|
-
var tabRepl
|
|
89
|
-
var item, flags
|
|
90
|
-
var i
|
|
91
|
-
|
|
92
|
-
// First process presets, because these settings can be overwritten later.
|
|
93
|
-
preset = params.preset
|
|
94
|
-
if (preset) {
|
|
95
|
-
if (!(preset instanceof Array)) {
|
|
96
|
-
preset = [preset]
|
|
97
|
-
}
|
|
98
|
-
for (i = 0; i < preset.length; i++) {
|
|
99
|
-
item = presetMap[preset[i]]
|
|
100
|
-
if (item) {
|
|
101
|
-
if (item.mode) {
|
|
102
|
-
mode = item.mode
|
|
103
|
-
}
|
|
104
|
-
if (item.whitespace) {
|
|
105
|
-
whitespace = item.whitespace
|
|
106
|
-
}
|
|
107
|
-
if (item.tabWidth !== undefined) {
|
|
108
|
-
tabWidth = item.tabWidth
|
|
109
|
-
}
|
|
110
|
-
if (item.skip) {
|
|
111
|
-
skip = item.skip
|
|
112
|
-
}
|
|
113
|
-
if (item.skipScheme) {
|
|
114
|
-
skipScheme = item.skipScheme
|
|
115
|
-
}
|
|
116
|
-
if (item.lineBreak) {
|
|
117
|
-
lineBreak = item.lineBreak
|
|
118
|
-
}
|
|
119
|
-
if (item.lineBreakScheme) {
|
|
120
|
-
lineBreakScheme = item.lineBreakScheme
|
|
121
|
-
}
|
|
122
|
-
if (item.respectLineBreaks) {
|
|
123
|
-
respectLineBreaks = item.respectLineBreaks
|
|
124
|
-
}
|
|
125
|
-
if (item.preservedLineIndent !== undefined) {
|
|
126
|
-
preservedLineIndent = item.preservedLineIndent
|
|
127
|
-
}
|
|
128
|
-
if (item.wrapLineIndent !== undefined) {
|
|
129
|
-
wrapLineIndent = item.wrapLineIndent
|
|
130
|
-
}
|
|
131
|
-
if (item.wrapLineIndentBase) {
|
|
132
|
-
wrapLineIndentBase = item.wrapLineIndentBase
|
|
133
|
-
}
|
|
134
|
-
} else {
|
|
135
|
-
throw new TypeError('preset must be one of "' + Object.keys(presetMap).join('", "') + '"')
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (params.mode) {
|
|
141
|
-
if (modeMap[params.mode]) {
|
|
142
|
-
mode = params.mode
|
|
143
|
-
} else {
|
|
144
|
-
throw new TypeError('mode must be one of "' + Object.keys(modeMap).join('", "') + '"')
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
// Available options: 'collapse', 'default', 'line', and 'all'
|
|
148
|
-
if (params.whitespace) {
|
|
149
|
-
if (wsMap[params.whitespace]) {
|
|
150
|
-
whitespace = params.whitespace
|
|
151
|
-
} else {
|
|
152
|
-
throw new TypeError('whitespace must be one of "' + Object.keys(wsMap).join('", "') + '"')
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (params.tabWidth !== undefined) {
|
|
157
|
-
if (parseInt(params.tabWidth, 10) >= 0) {
|
|
158
|
-
tabWidth = parseInt(params.tabWidth, 10)
|
|
159
|
-
} else {
|
|
160
|
-
throw new TypeError('tabWidth must be a non-negative integer')
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
tabRepl = new Array(tabWidth + 1).join(' ')
|
|
164
|
-
|
|
165
|
-
// Available options: 'all', 'multi', 'm\d+', 's\d+', 'none'
|
|
166
|
-
if (params.respectLineBreaks) {
|
|
167
|
-
if (rlbMap[params.respectLineBreaks] || rlbSMPat.test(params.respectLineBreaks)) {
|
|
168
|
-
respectLineBreaks = params.respectLineBreaks
|
|
169
|
-
} else {
|
|
170
|
-
throw new TypeError('respectLineBreaks must be one of "' + Object.keys(rlbMap).join('", "') +
|
|
171
|
-
'", "m<num>", "s<num>"')
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
// After these conversions, now we have 4 options in `respectLineBreaks`:
|
|
175
|
-
// 'all', 'none', 'm' and 's'.
|
|
176
|
-
// `respectNum` is applicable iff `respectLineBreaks` is either 'm' or 's'.
|
|
177
|
-
if (respectLineBreaks === 'multi') {
|
|
178
|
-
respectLineBreaks = 'm'
|
|
179
|
-
respectNum = 2
|
|
180
|
-
} else if (!rlbMap[respectLineBreaks]) {
|
|
181
|
-
var match = rlbSMPat.exec(respectLineBreaks)
|
|
182
|
-
respectLineBreaks = match[1]
|
|
183
|
-
respectNum = parseInt(match[2], 10)
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
if (params.preservedLineIndent !== undefined) {
|
|
187
|
-
if (parseInt(params.preservedLineIndent, 10) >= 0) {
|
|
188
|
-
preservedLineIndent = parseInt(params.preservedLineIndent, 10)
|
|
189
|
-
} else {
|
|
190
|
-
throw new TypeError('preservedLineIndent must be a non-negative integer')
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
if (preservedLineIndent > 0) {
|
|
195
|
-
preservedLinePrefix = new Array(preservedLineIndent + 1).join(' ')
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
if (params.wrapLineIndent !== undefined) {
|
|
199
|
-
if (!isNaN(parseInt(params.wrapLineIndent, 10))) {
|
|
200
|
-
wrapLineIndent = parseInt(params.wrapLineIndent, 10)
|
|
201
|
-
} else {
|
|
202
|
-
throw new TypeError('wrapLineIndent must be an integer')
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
if (params.wrapLineIndentBase) {
|
|
206
|
-
wrapLineIndentBase = params.wrapLineIndentBase
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
if (wrapLineIndentBase) {
|
|
210
|
-
if (wrapLineIndent === undefined) {
|
|
211
|
-
throw new TypeError('wrapLineIndent must be specified when wrapLineIndentBase is specified')
|
|
212
|
-
}
|
|
213
|
-
if (wrapLineIndentBase instanceof RegExp) {
|
|
214
|
-
wrapLineIndentPat = wrapLineIndentBase
|
|
215
|
-
} else if (typeof wrapLineIndentBase === 'string') {
|
|
216
|
-
wrapLineIndentPat = new RegExp(escapeRegExp(wrapLineIndentBase))
|
|
217
|
-
} else {
|
|
218
|
-
throw new TypeError('wrapLineIndentBase must be either a RegExp object or a string')
|
|
219
|
-
}
|
|
220
|
-
} else if (wrapLineIndent > 0) {
|
|
221
|
-
wrapLineInitPrefix = new Array(wrapLineIndent + 1).join(' ')
|
|
222
|
-
} else if (wrapLineIndent < 0) {
|
|
223
|
-
throw new TypeError('wrapLineIndent must be non-negative when a base is not specified')
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// NOTE: For the two RegExps `skipPat` and `lineBreakPat` that can be specified
|
|
227
|
-
// by the user:
|
|
228
|
-
// 1. We require them to be "global", so we have to convert them to global
|
|
229
|
-
// if the user specifies a non-global regex.
|
|
230
|
-
// 2. We cannot call `split()` on them, because they may or may not contain
|
|
231
|
-
// capturing parentheses which affect the output of `split()`.
|
|
232
|
-
|
|
233
|
-
// Precedence: Regex = Str > Scheme
|
|
234
|
-
if (params.skipScheme) {
|
|
235
|
-
if (skipSchemeMap[params.skipScheme]) {
|
|
236
|
-
skipScheme = params.skipScheme
|
|
237
|
-
} else {
|
|
238
|
-
throw new TypeError('skipScheme must be one of "' + Object.keys(skipSchemeMap).join('", "') + '"')
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
if (params.skip) {
|
|
242
|
-
skip = params.skip
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
if (skip) {
|
|
246
|
-
if (skip instanceof RegExp) {
|
|
247
|
-
skipPat = skip
|
|
248
|
-
if (!skipPat.global) {
|
|
249
|
-
flags = 'g'
|
|
250
|
-
if (skipPat.ignoreCase) { flags += 'i'; }
|
|
251
|
-
if (skipPat.multiline) { flags += 'm'; }
|
|
252
|
-
skipPat = new RegExp(skipPat.source, flags)
|
|
253
|
-
}
|
|
254
|
-
} else if (typeof skip === 'string') {
|
|
255
|
-
skipPat = new RegExp(escapeRegExp(skip), 'g')
|
|
256
|
-
} else {
|
|
257
|
-
throw new TypeError('skip must be either a RegExp object or a string')
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
if (!skipPat && skipScheme) {
|
|
261
|
-
skipPat = skipSchemeMap[skipScheme]
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// Precedence:
|
|
265
|
-
// - for lineBreakPat: Regex > Scheme > Str
|
|
266
|
-
// - for lineBreakStr: Str > Scheme > Regex
|
|
267
|
-
if (params.lineBreakScheme) {
|
|
268
|
-
if (lineBreakSchemeMap[params.lineBreakScheme]) {
|
|
269
|
-
lineBreakScheme = params.lineBreakScheme
|
|
270
|
-
} else {
|
|
271
|
-
throw new TypeError('lineBreakScheme must be one of "' + Object.keys(lineBreakSchemeMap).join('", "') + '"')
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
if (params.lineBreak) {
|
|
275
|
-
lineBreak = params.lineBreak
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
if (lineBreakScheme) {
|
|
279
|
-
// Supported schemes: 'unix', 'dos', 'mac', 'html', 'xhtml'
|
|
280
|
-
item = lineBreakSchemeMap[lineBreakScheme]
|
|
281
|
-
if (item) {
|
|
282
|
-
lineBreakPat = item[0]
|
|
283
|
-
lineBreakStr = item[1]
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
if (lineBreak) {
|
|
287
|
-
if (lineBreak instanceof Array) {
|
|
288
|
-
if (lineBreak.length === 1) {
|
|
289
|
-
lineBreak = lineBreak[0]
|
|
290
|
-
} else if (lineBreak.length >= 2) {
|
|
291
|
-
if (lineBreak[0] instanceof RegExp) {
|
|
292
|
-
lineBreakPat = lineBreak[0]
|
|
293
|
-
if (typeof lineBreak[1] === 'string') {
|
|
294
|
-
lineBreakStr = lineBreak[1]
|
|
295
|
-
}
|
|
296
|
-
} else if (lineBreak[1] instanceof RegExp) {
|
|
297
|
-
lineBreakPat = lineBreak[1]
|
|
298
|
-
if (typeof lineBreak[0] === 'string') {
|
|
299
|
-
lineBreakStr = lineBreak[0]
|
|
300
|
-
}
|
|
301
|
-
} else if (typeof lineBreak[0] === 'string' && typeof lineBreak[1] === 'string') {
|
|
302
|
-
lineBreakPat = new RegExp(escapeRegExp(lineBreak[0]), 'g')
|
|
303
|
-
lineBreakStr = lineBreak[1]
|
|
304
|
-
} else {
|
|
305
|
-
lineBreak = lineBreak[0]
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
if (typeof lineBreak === 'string') {
|
|
310
|
-
lineBreakStr = lineBreak
|
|
311
|
-
if (!lineBreakPat) {
|
|
312
|
-
lineBreakPat = new RegExp(escapeRegExp(lineBreak), 'g')
|
|
313
|
-
}
|
|
314
|
-
} else if (lineBreak instanceof RegExp) {
|
|
315
|
-
lineBreakPat = lineBreak
|
|
316
|
-
} else if (!(lineBreak instanceof Array)) {
|
|
317
|
-
throw new TypeError('lineBreak must be a RegExp object, a string, or an array consisted of a RegExp object and a string')
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
// Only assign defaults when `lineBreakPat` is not assigned.
|
|
321
|
-
// So if `params.lineBreak` is a RegExp, we don't have a value in `lineBreakStr`
|
|
322
|
-
// yet. We will try to get the value from the input string, and if failed, we
|
|
323
|
-
// will throw an exception.
|
|
324
|
-
if (!lineBreakPat) {
|
|
325
|
-
lineBreakPat = /\n/g
|
|
326
|
-
lineBreakStr = '\n'
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// Create `multiLineBreakPat` based on `lineBreakPat`, that matches strings
|
|
330
|
-
// consisted of one or more line breaks and zero or more whitespaces.
|
|
331
|
-
// Also convert `lineBreakPat` to global if not already so.
|
|
332
|
-
flags = 'g'
|
|
333
|
-
if (lineBreakPat.ignoreCase) { flags += 'i'; }
|
|
334
|
-
if (lineBreakPat.multiline) { flags += 'm'; }
|
|
335
|
-
multiLineBreakPat = new RegExp('\\s*(?:' + lineBreakPat.source + ')(?:' +
|
|
336
|
-
lineBreakPat.source + '|\\s)*', flags)
|
|
337
|
-
if (!lineBreakPat.global) {
|
|
338
|
-
lineBreakPat = new RegExp(lineBreakPat.source, flags)
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
// Initialize other useful variables.
|
|
342
|
-
var re = mode === 'hard' ? /\b/ : /(\S+\s+)/
|
|
343
|
-
var prefix = new Array(start + 1).join(' ')
|
|
344
|
-
var wsStrip = (whitespace === 'default' || whitespace === 'collapse'),
|
|
345
|
-
wsCollapse = (whitespace === 'collapse'),
|
|
346
|
-
wsLine = (whitespace === 'line'),
|
|
347
|
-
wsAll = (whitespace === 'all')
|
|
348
|
-
var tabPat = /\t/g,
|
|
349
|
-
collapsePat = / +/g,
|
|
350
|
-
pPat = /^\s+/,
|
|
351
|
-
tPat = /\s+$/,
|
|
352
|
-
nonWsPat = /\S/,
|
|
353
|
-
wsPat = /\s/
|
|
354
|
-
var wrapLen = stop - start
|
|
355
|
-
|
|
356
|
-
return function (text) {
|
|
357
|
-
text = text.toString().replace(tabPat, tabRepl)
|
|
358
|
-
|
|
359
|
-
var match
|
|
360
|
-
if (!lineBreakStr) {
|
|
361
|
-
// Try to get lineBreakStr from `text`
|
|
362
|
-
lineBreakPat.lastIndex = 0
|
|
363
|
-
match = lineBreakPat.exec(text)
|
|
364
|
-
if (match) {
|
|
365
|
-
lineBreakStr = match[0]
|
|
366
|
-
} else {
|
|
367
|
-
throw new TypeError('Line break string for the output not specified')
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
// text -> blocks; each bloc -> segments; each segment -> chunks
|
|
372
|
-
var blocks, base = 0
|
|
373
|
-
var mo, arr, b, res
|
|
374
|
-
// Split `text` by line breaks.
|
|
375
|
-
blocks = []
|
|
376
|
-
multiLineBreakPat.lastIndex = 0
|
|
377
|
-
match = multiLineBreakPat.exec(text)
|
|
378
|
-
while(match) {
|
|
379
|
-
blocks.push(text.substring(base, match.index))
|
|
380
|
-
|
|
381
|
-
if (respectLineBreaks !== 'none') {
|
|
382
|
-
arr = []
|
|
383
|
-
b = 0
|
|
384
|
-
lineBreakPat.lastIndex = 0
|
|
385
|
-
mo = lineBreakPat.exec(match[0])
|
|
386
|
-
while(mo) {
|
|
387
|
-
arr.push(match[0].substring(b, mo.index))
|
|
388
|
-
b = mo.index + mo[0].length
|
|
389
|
-
mo = lineBreakPat.exec(match[0])
|
|
390
|
-
}
|
|
391
|
-
arr.push(match[0].substring(b))
|
|
392
|
-
blocks.push({type: 'break', breaks: arr})
|
|
393
|
-
} else {
|
|
394
|
-
// Strip line breaks and insert spaces when necessary.
|
|
395
|
-
if (wsCollapse) {
|
|
396
|
-
res = ' '
|
|
397
|
-
} else {
|
|
398
|
-
res = match[0].replace(lineBreakPat, '')
|
|
399
|
-
}
|
|
400
|
-
blocks.push({type: 'break', remaining: res})
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
base = match.index + match[0].length
|
|
404
|
-
match = multiLineBreakPat.exec(text)
|
|
405
|
-
}
|
|
406
|
-
blocks.push(text.substring(base))
|
|
407
|
-
|
|
408
|
-
var i, j, k
|
|
409
|
-
var segments
|
|
410
|
-
if (skipPat) {
|
|
411
|
-
segments = []
|
|
412
|
-
for (i = 0; i < blocks.length; i++) {
|
|
413
|
-
var bloc = blocks[i]
|
|
414
|
-
if (typeof bloc !== 'string') {
|
|
415
|
-
// This is an object.
|
|
416
|
-
segments.push(bloc)
|
|
417
|
-
} else {
|
|
418
|
-
base = 0
|
|
419
|
-
skipPat.lastIndex = 0
|
|
420
|
-
match = skipPat.exec(bloc)
|
|
421
|
-
while(match) {
|
|
422
|
-
segments.push(bloc.substring(base, match.index))
|
|
423
|
-
segments.push({type: 'skip', value: match[0]})
|
|
424
|
-
base = match.index + match[0].length
|
|
425
|
-
match = skipPat.exec(bloc)
|
|
426
|
-
}
|
|
427
|
-
segments.push(bloc.substring(base))
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
} else {
|
|
431
|
-
segments = blocks
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
var chunks = []
|
|
435
|
-
for (i = 0; i < segments.length; i++) {
|
|
436
|
-
var segment = segments[i]
|
|
437
|
-
if (typeof segment !== 'string') {
|
|
438
|
-
// This is an object.
|
|
439
|
-
chunks.push(segment)
|
|
440
|
-
} else {
|
|
441
|
-
if (wsCollapse) {
|
|
442
|
-
segment = segment.replace(collapsePat, ' ')
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
var parts = segment.split(re),
|
|
446
|
-
acc = []
|
|
447
|
-
|
|
448
|
-
for (j = 0; j < parts.length; j++) {
|
|
449
|
-
var x = parts[j]
|
|
450
|
-
if (mode === 'hard') {
|
|
451
|
-
for (k = 0; k < x.length; k += wrapLen) {
|
|
452
|
-
acc.push(x.slice(k, k + wrapLen))
|
|
453
|
-
}
|
|
454
|
-
} else { acc.push(x); }
|
|
455
|
-
}
|
|
456
|
-
chunks = chunks.concat(acc)
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
var curLine = 0,
|
|
461
|
-
curLineLength = start + preservedLinePrefix.length,
|
|
462
|
-
lines = [ prefix + preservedLinePrefix ],
|
|
463
|
-
// Holds the "real length" (excluding trailing whitespaces) of the
|
|
464
|
-
// current line if it exceeds `stop`, otherwise 0.
|
|
465
|
-
// ONLY USED when `wsAll` is true, in `finishOffCurLine()`.
|
|
466
|
-
bulge = 0,
|
|
467
|
-
// `cleanLine` is true iff we are at the beginning of an output line. By
|
|
468
|
-
// "beginning" we mean it doesn't contain any non-whitespace char yet.
|
|
469
|
-
// But its `curLineLength` can be greater than `start`, or even possibly
|
|
470
|
-
// be greater than `stop`, if `wsStrip` is false.
|
|
471
|
-
//
|
|
472
|
-
// Note that a "clean" line can still contain skip strings, in addition
|
|
473
|
-
// to whitespaces.
|
|
474
|
-
//
|
|
475
|
-
// This variable is used to allow us strip preceding whitespaces when
|
|
476
|
-
// `wsStrip` is true, or `wsLine` is true and `preservedLine` is false.
|
|
477
|
-
cleanLine = true,
|
|
478
|
-
// `preservedLine` is true iff we are in a preserved input line.
|
|
479
|
-
//
|
|
480
|
-
// It's used when `wsLine` is true to (combined with `cleanLine`) decide
|
|
481
|
-
// whether a whitespace is at the beginning of a preserved input line and
|
|
482
|
-
// should not be stripped.
|
|
483
|
-
preservedLine = true,
|
|
484
|
-
// The current indent prefix for wrapped lines.
|
|
485
|
-
wrapLinePrefix = wrapLineInitPrefix,
|
|
486
|
-
remnant
|
|
487
|
-
|
|
488
|
-
// Always returns '' if `beforeHardBreak` is true.
|
|
489
|
-
//
|
|
490
|
-
// Assumption: Each call of this function is always followed by a `lines.push()` call.
|
|
491
|
-
//
|
|
492
|
-
// This function can change the status of `cleanLine`, but we don't modify the value of
|
|
493
|
-
// `cleanLine` in this function. It's fine because `cleanLine` will be set to the correct
|
|
494
|
-
// value after the `lines.push()` call following this function call. We also don't update
|
|
495
|
-
// `curLineLength` when pushing a new line and it's safe for the same reason.
|
|
496
|
-
function finishOffCurLine (beforeHardBreak) {
|
|
497
|
-
var str = lines[curLine],
|
|
498
|
-
idx, ln, rBase
|
|
499
|
-
|
|
500
|
-
if (!wsAll) {
|
|
501
|
-
// Strip all trailing whitespaces past `start`.
|
|
502
|
-
idx = str.length - 1
|
|
503
|
-
while (idx >= start && str[idx] === ' ') { idx--; }
|
|
504
|
-
while (idx >= start && wsPat.test(str[idx])) { idx--; }
|
|
505
|
-
idx++
|
|
506
|
-
|
|
507
|
-
if (idx !== str.length) {
|
|
508
|
-
lines[curLine] = str.substring(0, idx)
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
if (preservedLine && cleanLine && wsLine && curLineLength > stop) {
|
|
512
|
-
// Add the remnants to the next line, just like when `wsAll` is true.
|
|
513
|
-
rBase = str.length - (curLineLength - stop)
|
|
514
|
-
if (rBase < idx) {
|
|
515
|
-
// We didn't reach `stop` when stripping due to a bulge.
|
|
516
|
-
rBase = idx
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
} else {
|
|
520
|
-
// Strip trailing whitespaces exceeding stop.
|
|
521
|
-
if (curLineLength > stop) {
|
|
522
|
-
bulge = bulge || stop
|
|
523
|
-
rBase = str.length - (curLineLength - bulge)
|
|
524
|
-
lines[curLine] = str.substring(0, rBase)
|
|
525
|
-
}
|
|
526
|
-
bulge = 0
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
// Bug: the current implementation of `wrapLineIndent` is buggy: we are not
|
|
530
|
-
// taking the extra space occupied by the additional indentation into account
|
|
531
|
-
// when wrapping the line. For example, in "hard" mode, we should hard-wrap
|
|
532
|
-
// long words at `wrapLen - wrapLinePrefix.length` instead of `wrapLen`
|
|
533
|
-
// and remnants should also be wrapped at `wrapLen - wrapLinePrefix.length`.
|
|
534
|
-
if (preservedLine) {
|
|
535
|
-
// This is a preserved line, and the next output line isn't a
|
|
536
|
-
// preserved line.
|
|
537
|
-
preservedLine = false
|
|
538
|
-
if (wrapLineIndentPat) {
|
|
539
|
-
idx = lines[curLine].substring(start).search(wrapLineIndentPat)
|
|
540
|
-
if (idx >= 0 && idx + wrapLineIndent > 0) {
|
|
541
|
-
wrapLinePrefix = new Array(idx + wrapLineIndent + 1).join(' ')
|
|
542
|
-
} else {
|
|
543
|
-
wrapLinePrefix = ''
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
// Some remnants are left to the next line.
|
|
549
|
-
if (rBase) {
|
|
550
|
-
while (rBase + wrapLen < str.length) {
|
|
551
|
-
if (wsAll) {
|
|
552
|
-
ln = str.substring(rBase, rBase + wrapLen)
|
|
553
|
-
lines.push(prefix + wrapLinePrefix + ln)
|
|
554
|
-
} else {
|
|
555
|
-
lines.push(prefix + wrapLinePrefix)
|
|
556
|
-
}
|
|
557
|
-
rBase += wrapLen
|
|
558
|
-
curLine++
|
|
559
|
-
}
|
|
560
|
-
if (beforeHardBreak) {
|
|
561
|
-
if (wsAll) {
|
|
562
|
-
ln = str.substring(rBase)
|
|
563
|
-
lines.push(prefix + wrapLinePrefix + ln)
|
|
564
|
-
} else {
|
|
565
|
-
lines.push(prefix + wrapLinePrefix)
|
|
566
|
-
}
|
|
567
|
-
curLine++
|
|
568
|
-
} else {
|
|
569
|
-
ln = str.substring(rBase)
|
|
570
|
-
return wrapLinePrefix + ln
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
return ''
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
for (i = 0; i < chunks.length; i++) {
|
|
578
|
-
var chunk = chunks[i]
|
|
579
|
-
|
|
580
|
-
if (chunk === '') { continue; }
|
|
581
|
-
|
|
582
|
-
if (typeof chunk !== 'string') {
|
|
583
|
-
if (chunk.type === 'break') {
|
|
584
|
-
// This is one or more line breaks.
|
|
585
|
-
// Each entry in `breaks` is just zero or more whitespaces.
|
|
586
|
-
if (respectLineBreaks !== 'none') {
|
|
587
|
-
// Note that if `whitespace` is "collapse", we still need
|
|
588
|
-
// to collapse whitespaces in entries of `breaks`.
|
|
589
|
-
var breaks = chunk.breaks
|
|
590
|
-
var num = breaks.length - 1
|
|
591
|
-
|
|
592
|
-
if (respectLineBreaks === 's') {
|
|
593
|
-
// This is the most complex scenario. We have to check
|
|
594
|
-
// the line breaks one by one.
|
|
595
|
-
for (j = 0; j < num; j++) {
|
|
596
|
-
if (breaks[j + 1].length < respectNum) {
|
|
597
|
-
// This line break should be stripped.
|
|
598
|
-
if (wsCollapse) {
|
|
599
|
-
breaks[j + 1] = ' '
|
|
600
|
-
} else {
|
|
601
|
-
breaks[j + 1] = breaks[j] + breaks[j + 1]
|
|
602
|
-
}
|
|
603
|
-
} else {
|
|
604
|
-
// This line break should be preserved.
|
|
605
|
-
// First finish off the current line.
|
|
606
|
-
if (wsAll) {
|
|
607
|
-
lines[curLine] += breaks[j]
|
|
608
|
-
curLineLength += breaks[j].length
|
|
609
|
-
}
|
|
610
|
-
finishOffCurLine(true)
|
|
611
|
-
|
|
612
|
-
lines.push(prefix + preservedLinePrefix)
|
|
613
|
-
curLine++
|
|
614
|
-
curLineLength = start + preservedLinePrefix.length
|
|
615
|
-
|
|
616
|
-
preservedLine = cleanLine = true
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
// We are adding to either the existing line (if no line break
|
|
620
|
-
// is qualified for preservance) or a "new" line.
|
|
621
|
-
if (!cleanLine || wsAll || (wsLine && preservedLine)) {
|
|
622
|
-
if (wsCollapse || (!cleanLine && breaks[num] === '')) {
|
|
623
|
-
breaks[num] = ' '
|
|
624
|
-
}
|
|
625
|
-
lines[curLine] += breaks[num]
|
|
626
|
-
curLineLength += breaks[num].length
|
|
627
|
-
}
|
|
628
|
-
} else if (respectLineBreaks === 'm' && num < respectNum) {
|
|
629
|
-
// These line breaks should be stripped.
|
|
630
|
-
if (!cleanLine || wsAll || (wsLine && preservedLine)) {
|
|
631
|
-
if (wsCollapse) {
|
|
632
|
-
chunk = ' '
|
|
633
|
-
} else {
|
|
634
|
-
chunk = breaks.join('')
|
|
635
|
-
if (!cleanLine && chunk === '') {
|
|
636
|
-
chunk = ' '
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
lines[curLine] += chunk
|
|
640
|
-
curLineLength += chunk.length
|
|
641
|
-
}
|
|
642
|
-
} else { // 'all' || ('m' && num >= respectNum)
|
|
643
|
-
// These line breaks should be preserved.
|
|
644
|
-
if (wsStrip) {
|
|
645
|
-
// Finish off the current line.
|
|
646
|
-
finishOffCurLine(true)
|
|
647
|
-
|
|
648
|
-
for (j = 0; j < num; j++) {
|
|
649
|
-
lines.push(prefix + preservedLinePrefix)
|
|
650
|
-
curLine++
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
curLineLength = start + preservedLinePrefix.length
|
|
654
|
-
preservedLine = cleanLine = true
|
|
655
|
-
} else {
|
|
656
|
-
if (wsAll || (preservedLine && cleanLine)) {
|
|
657
|
-
lines[curLine] += breaks[0]
|
|
658
|
-
curLineLength += breaks[0].length
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
for (j = 0; j < num; j++) {
|
|
662
|
-
// Finish off the current line.
|
|
663
|
-
finishOffCurLine(true)
|
|
664
|
-
|
|
665
|
-
lines.push(prefix + preservedLinePrefix + breaks[j + 1])
|
|
666
|
-
curLine++
|
|
667
|
-
curLineLength = start + preservedLinePrefix.length + breaks[j + 1].length
|
|
668
|
-
|
|
669
|
-
preservedLine = cleanLine = true
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
} else {
|
|
674
|
-
// These line breaks should be stripped.
|
|
675
|
-
if (!cleanLine || wsAll || (wsLine && preservedLine)) {
|
|
676
|
-
chunk = chunk.remaining
|
|
677
|
-
|
|
678
|
-
// Bug: If `wsAll` is true, `cleanLine` is false, and `chunk`
|
|
679
|
-
// is '', we insert a space to replace the line break. This
|
|
680
|
-
// space will be preserved even if we are at the end of an
|
|
681
|
-
// output line, which is wrong behavior. However, I'm not
|
|
682
|
-
// sure it's worth it to fix this edge case.
|
|
683
|
-
if (wsCollapse || (!cleanLine && chunk === '')) {
|
|
684
|
-
chunk = ' '
|
|
685
|
-
}
|
|
686
|
-
lines[curLine] += chunk
|
|
687
|
-
curLineLength += chunk.length
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
} else if (chunk.type === 'skip') {
|
|
691
|
-
// This is a skip string.
|
|
692
|
-
// Assumption: skip strings don't end with whitespaces.
|
|
693
|
-
if (curLineLength > stop) {
|
|
694
|
-
remnant = finishOffCurLine(false)
|
|
695
|
-
|
|
696
|
-
lines.push(prefix + wrapLinePrefix)
|
|
697
|
-
curLine++
|
|
698
|
-
curLineLength = start + wrapLinePrefix.length
|
|
699
|
-
|
|
700
|
-
if (remnant) {
|
|
701
|
-
lines[curLine] += remnant
|
|
702
|
-
curLineLength += remnant.length
|
|
703
|
-
}
|
|
704
|
-
|
|
705
|
-
cleanLine = true
|
|
706
|
-
}
|
|
707
|
-
lines[curLine] += chunk.value
|
|
708
|
-
}
|
|
709
|
-
continue
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
var chunk2
|
|
713
|
-
while (1) {
|
|
714
|
-
chunk2 = undefined
|
|
715
|
-
if (curLineLength + chunk.length > stop &&
|
|
716
|
-
curLineLength + (chunk2 = chunk.replace(tPat, '')).length > stop &&
|
|
717
|
-
chunk2 !== '' &&
|
|
718
|
-
curLineLength > start) {
|
|
719
|
-
// This line is full, add `chunk` to the next line
|
|
720
|
-
remnant = finishOffCurLine(false)
|
|
721
|
-
|
|
722
|
-
lines.push(prefix + wrapLinePrefix)
|
|
723
|
-
curLine++
|
|
724
|
-
curLineLength = start + wrapLinePrefix.length
|
|
725
|
-
|
|
726
|
-
if (remnant) {
|
|
727
|
-
lines[curLine] += remnant
|
|
728
|
-
curLineLength += remnant.length
|
|
729
|
-
cleanLine = true
|
|
730
|
-
continue
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
if (wsStrip || (wsLine && !(preservedLine && cleanLine))) {
|
|
734
|
-
chunk = chunk.replace(pPat, '')
|
|
735
|
-
}
|
|
736
|
-
cleanLine = false
|
|
737
|
-
} else {
|
|
738
|
-
// Add `chunk` to this line
|
|
739
|
-
if (cleanLine) {
|
|
740
|
-
if (wsStrip || (wsLine && !(preservedLine && cleanLine))) {
|
|
741
|
-
chunk = chunk.replace(pPat, '')
|
|
742
|
-
if (chunk !== '') {
|
|
743
|
-
cleanLine = false
|
|
744
|
-
}
|
|
745
|
-
} else {
|
|
746
|
-
if (nonWsPat.test(chunk)) {
|
|
747
|
-
cleanLine = false
|
|
748
|
-
}
|
|
749
|
-
}
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
break
|
|
753
|
-
}
|
|
754
|
-
if (wsAll && chunk2 && curLineLength + chunk2.length > stop) {
|
|
755
|
-
bulge = curLineLength + chunk2.length
|
|
756
|
-
}
|
|
757
|
-
lines[curLine] += chunk
|
|
758
|
-
curLineLength += chunk.length
|
|
759
|
-
}
|
|
760
|
-
// Finally, finish off the last line.
|
|
761
|
-
finishOffCurLine(true)
|
|
762
|
-
return lines.join(lineBreakStr)
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
linewrap.soft = linewrap
|
|
767
|
-
|
|
768
|
-
linewrap.hard = function ( /*start, stop, params*/) {
|
|
769
|
-
var args = [].slice.call(arguments)
|
|
770
|
-
var last = args.length - 1
|
|
771
|
-
if (typeof args[last] === 'object') {
|
|
772
|
-
args[last].mode = 'hard'
|
|
773
|
-
} else {
|
|
774
|
-
args.push({ mode: 'hard' })
|
|
775
|
-
}
|
|
776
|
-
return linewrap.apply(null, args)
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
linewrap.wrap = function (text /*, start, stop, params*/) {
|
|
780
|
-
var args = [].slice.call(arguments)
|
|
781
|
-
args.shift()
|
|
782
|
-
return linewrap.apply(null, args)(text)
|
|
783
|
-
}
|