@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.
Files changed (65) hide show
  1. package/LICENSE +15 -3
  2. package/README.md +44 -241
  3. package/dist/test-helpers/expect-output.d.ts +2 -0
  4. package/dist/test-helpers/expect-output.js +16 -0
  5. package/dist/test-helpers/init.d.ts +1 -0
  6. package/dist/test-helpers/init.js +18 -0
  7. package/dist/test-helpers/stub-output.d.ts +2 -0
  8. package/dist/test-helpers/stub-output.js +33 -0
  9. package/dist/types/errors/ambiguous.d.ts +15 -0
  10. package/dist/types/errors/ambiguous.js +14 -0
  11. package/dist/types/errors/not-found.d.ts +5 -0
  12. package/dist/types/errors/not-found.js +12 -0
  13. package/dist/types/pg/data-api.d.ts +17 -0
  14. package/dist/types/pg/data-api.js +2 -0
  15. package/dist/types/pg/tunnel.d.ts +22 -0
  16. package/dist/types/pg/tunnel.js +2 -0
  17. package/dist/utils/addons/resolve.d.ts +9 -0
  18. package/dist/utils/addons/resolve.js +39 -0
  19. package/dist/utils/pg/bastion.d.ts +30 -0
  20. package/dist/utils/pg/bastion.js +122 -0
  21. package/dist/utils/pg/config-vars.d.ts +8 -0
  22. package/dist/utils/pg/config-vars.js +34 -0
  23. package/dist/utils/pg/databases.d.ts +12 -0
  24. package/dist/utils/pg/databases.js +137 -0
  25. package/dist/utils/pg/host.d.ts +1 -0
  26. package/dist/utils/pg/host.js +7 -0
  27. package/dist/utils/pg/psql.d.ts +28 -0
  28. package/dist/utils/pg/psql.js +188 -0
  29. package/dist/ux/confirm.d.ts +1 -0
  30. package/dist/ux/confirm.js +7 -0
  31. package/dist/ux/prompt.d.ts +2 -0
  32. package/dist/ux/prompt.js +7 -0
  33. package/dist/ux/styled-header.d.ts +1 -0
  34. package/dist/ux/styled-header.js +7 -0
  35. package/dist/ux/styled-json.d.ts +1 -0
  36. package/dist/ux/styled-json.js +7 -0
  37. package/dist/ux/styled-object.d.ts +1 -0
  38. package/dist/ux/styled-object.js +7 -0
  39. package/dist/ux/table.d.ts +2 -0
  40. package/dist/ux/table.js +7 -0
  41. package/dist/ux/wait.d.ts +1 -0
  42. package/dist/ux/wait.js +7 -0
  43. package/package.json +54 -55
  44. package/index.js +0 -40
  45. package/lib/action.js +0 -54
  46. package/lib/auth.js +0 -207
  47. package/lib/command.js +0 -171
  48. package/lib/console.js +0 -105
  49. package/lib/date.js +0 -18
  50. package/lib/errors.js +0 -122
  51. package/lib/exit.js +0 -42
  52. package/lib/got.js +0 -153
  53. package/lib/linewrap.js +0 -783
  54. package/lib/mutex.js +0 -41
  55. package/lib/open.js +0 -22
  56. package/lib/preauth.js +0 -26
  57. package/lib/process.js +0 -14
  58. package/lib/prompt.js +0 -150
  59. package/lib/spinner.js +0 -147
  60. package/lib/spinners.json +0 -739
  61. package/lib/styled.js +0 -131
  62. package/lib/table.js +0 -132
  63. package/lib/util.js +0 -38
  64. package/lib/vars.js +0 -29
  65. 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
- }