@stacksjs/cli 0.64.5 → 0.65.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/README.md +29 -28
- package/dist/actions/index.d.ts +1 -0
- package/dist/actions/install.d.ts +26 -0
- package/dist/app.d.ts +100 -0
- package/dist/cli.d.ts +10 -0
- package/dist/command.d.ts +32 -0
- package/dist/console.d.ts +3 -0
- package/dist/exec.d.ts +40 -0
- package/dist/helpers.d.ts +9 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +9 -9
- package/dist/index.js.map +18 -18
- package/dist/parse.d.ts +15 -0
- package/dist/run.d.ts +63 -0
- package/dist/spinner.d.ts +2 -0
- package/dist/utils.d.ts +5 -0
- package/package.json +15 -20
- package/src/actions/install.ts +8 -5
- package/src/app.ts +64 -60
- package/src/cli.ts +1 -1
- package/src/command.ts +10 -3
- package/src/console.ts +1 -1
- package/src/exec.ts +33 -15
- package/src/helpers.ts +21 -11
- package/src/index.ts +1 -1
- package/src/parse.ts +57 -45
- package/src/run.ts +7 -3
- package/src/spinner.ts +1 -1
- package/src/utils.ts +13 -13
package/src/exec.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
+
import type { CliOptions, ErrorLike, SpawnOptions, Subprocess } from '@stacksjs/types'
|
|
1
2
|
import process from 'node:process'
|
|
2
|
-
import {
|
|
3
|
-
import type { CliOptions, Subprocess } from '@stacksjs/types'
|
|
3
|
+
import { err, handleError, ok, type Result } from '@stacksjs/error-handling'
|
|
4
4
|
import { ExitCode } from '@stacksjs/types'
|
|
5
|
-
import { log } from './'
|
|
5
|
+
import { italic, log } from './'
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Execute a command.
|
|
@@ -25,15 +25,16 @@ import { log } from './'
|
|
|
25
25
|
* ```
|
|
26
26
|
*/
|
|
27
27
|
export async function exec(command: string | string[], options?: CliOptions): Promise<Result<Subprocess, Error>> {
|
|
28
|
-
const cmd = Array.isArray(command) ? command : command.match(/(?:[^\s"]
|
|
28
|
+
const cmd = Array.isArray(command) ? command : command.match(/(?:[^\s"]|"[^"]*")+/g)
|
|
29
29
|
|
|
30
|
-
if (!cmd)
|
|
30
|
+
if (!cmd)
|
|
31
|
+
return err(handleError(`Failed to parse command: ${cmd}`, options))
|
|
31
32
|
|
|
32
33
|
log.debug('exec:', Array.isArray(command) ? command.join(' ') : command)
|
|
33
34
|
log.debug('cmd:', cmd)
|
|
34
35
|
log.debug('exec options:', options)
|
|
35
|
-
const cwd = options?.cwd || process.cwd()
|
|
36
36
|
|
|
37
|
+
const cwd = options?.cwd ?? process.cwd()
|
|
37
38
|
const proc = Bun.spawn(cmd, {
|
|
38
39
|
...options,
|
|
39
40
|
stdout:
|
|
@@ -42,7 +43,12 @@ export async function exec(command: string | string[], options?: CliOptions): Pr
|
|
|
42
43
|
detached: options?.background || false,
|
|
43
44
|
cwd,
|
|
44
45
|
// env: { ...e, ...options?.env },
|
|
45
|
-
onExit(
|
|
46
|
+
onExit(
|
|
47
|
+
subprocess: Subprocess<SpawnOptions.Writable, SpawnOptions.Readable, SpawnOptions.Readable>,
|
|
48
|
+
exitCode: number | null,
|
|
49
|
+
signalCode: number | null,
|
|
50
|
+
error: ErrorLike | undefined,
|
|
51
|
+
) {
|
|
46
52
|
exitHandler('spawn', subprocess, exitCode, signalCode, error)
|
|
47
53
|
},
|
|
48
54
|
})
|
|
@@ -59,9 +65,10 @@ export async function exec(command: string | string[], options?: CliOptions): Pr
|
|
|
59
65
|
}
|
|
60
66
|
|
|
61
67
|
const exited = await proc.exited
|
|
62
|
-
if (exited === ExitCode.Success)
|
|
68
|
+
if (exited === ExitCode.Success)
|
|
69
|
+
return ok(proc)
|
|
63
70
|
|
|
64
|
-
return err(handleError(`Failed to execute command: ${cmd.join(' ')}
|
|
71
|
+
return err(handleError(`Failed to execute command: ${italic(cmd.join(' '))} in ${italic(cwd)}`, options))
|
|
65
72
|
}
|
|
66
73
|
|
|
67
74
|
/**
|
|
@@ -84,7 +91,7 @@ export async function execSync(command: string | string[], options?: CliOptions)
|
|
|
84
91
|
log.debug('Running ExecSync:', command)
|
|
85
92
|
log.debug('ExecSync Options:', options)
|
|
86
93
|
|
|
87
|
-
const cmd = Array.isArray(command) ? command : command.match(/(?:[^\s"]
|
|
94
|
+
const cmd = Array.isArray(command) ? command : command.match(/(?:[^\s"]|"[^"]*")+/g)
|
|
88
95
|
|
|
89
96
|
if (!cmd) {
|
|
90
97
|
log.error(`Failed to parse command: ${cmd}`, options)
|
|
@@ -98,16 +105,26 @@ export async function execSync(command: string | string[], options?: CliOptions)
|
|
|
98
105
|
stderr: options?.stderr ?? 'inherit',
|
|
99
106
|
cwd: options?.cwd ?? process.cwd(),
|
|
100
107
|
// env: { ...Bun.env, ...options?.env },
|
|
101
|
-
onExit(
|
|
108
|
+
onExit(
|
|
109
|
+
subprocess: Subprocess<SpawnOptions.Writable, SpawnOptions.Readable, SpawnOptions.Readable>,
|
|
110
|
+
exitCode: number | null,
|
|
111
|
+
signalCode: number | null,
|
|
112
|
+
error: ErrorLike | undefined,
|
|
113
|
+
) {
|
|
102
114
|
exitHandler('spawnSync', subprocess, exitCode, signalCode, error)
|
|
103
115
|
},
|
|
104
116
|
})
|
|
105
117
|
|
|
106
|
-
return proc.stdout
|
|
118
|
+
return proc.stdout?.toString() ?? ''
|
|
107
119
|
}
|
|
108
120
|
|
|
109
|
-
|
|
110
|
-
|
|
121
|
+
function exitHandler(
|
|
122
|
+
type: 'spawn' | 'spawnSync',
|
|
123
|
+
subprocess: Subprocess,
|
|
124
|
+
exitCode: number | null,
|
|
125
|
+
signalCode: number | null,
|
|
126
|
+
error?: Error,
|
|
127
|
+
) {
|
|
111
128
|
log.debug(`exitHandler: ${type}`)
|
|
112
129
|
log.debug('subprocess', subprocess)
|
|
113
130
|
log.debug('exitCode', exitCode)
|
|
@@ -118,5 +135,6 @@ function exitHandler(type: 'spawn' | 'spawnSync', subprocess, exitCode, signalCo
|
|
|
118
135
|
process.exit(ExitCode.FatalError)
|
|
119
136
|
}
|
|
120
137
|
|
|
121
|
-
if (exitCode !== ExitCode.Success && exitCode)
|
|
138
|
+
if (exitCode !== ExitCode.Success && exitCode)
|
|
139
|
+
process.exit(exitCode)
|
|
122
140
|
}
|
package/src/helpers.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import type { IntroOptions, OutroOptions } from '@stacksjs/types'
|
|
1
2
|
import { handleError } from '@stacksjs/error-handling'
|
|
2
3
|
import { log } from '@stacksjs/logging'
|
|
3
|
-
import type { IntroOptions, OutroOptions } from '@stacksjs/types'
|
|
4
4
|
import { ExitCode } from '@stacksjs/types'
|
|
5
5
|
import { bgCyan, bold, cyan, dim, gray, green, italic } from 'kolorist'
|
|
6
6
|
import { version } from '../package.json'
|
|
@@ -18,7 +18,8 @@ export async function intro(command: string, options?: IntroOptions): Promise<nu
|
|
|
18
18
|
|
|
19
19
|
log.info(`Running ${bgCyan(italic(bold(` ${command} `)))}`)
|
|
20
20
|
|
|
21
|
-
if (options?.showPerformance === false || options?.quiet)
|
|
21
|
+
if (options?.showPerformance === false || options?.quiet)
|
|
22
|
+
return resolve(0)
|
|
22
23
|
|
|
23
24
|
return resolve(performance.now())
|
|
24
25
|
})
|
|
@@ -27,7 +28,7 @@ export async function intro(command: string, options?: IntroOptions): Promise<nu
|
|
|
27
28
|
/**
|
|
28
29
|
* Prints the outro message.
|
|
29
30
|
*/
|
|
30
|
-
export function outro(text: string, options?: OutroOptions, error?: Error | string) {
|
|
31
|
+
export function outro(text: string, options?: OutroOptions, error?: Error | string): Promise<number> {
|
|
31
32
|
const opts = {
|
|
32
33
|
type: 'success',
|
|
33
34
|
useSeconds: true,
|
|
@@ -37,7 +38,8 @@ export function outro(text: string, options?: OutroOptions, error?: Error | stri
|
|
|
37
38
|
opts.message = options?.message || text
|
|
38
39
|
|
|
39
40
|
return new Promise((resolve) => {
|
|
40
|
-
if (error)
|
|
41
|
+
if (error)
|
|
42
|
+
return handleError(error)
|
|
41
43
|
|
|
42
44
|
if (opts?.startTime) {
|
|
43
45
|
let time = performance.now() - opts.startTime
|
|
@@ -47,21 +49,29 @@ export function outro(text: string, options?: OutroOptions, error?: Error | stri
|
|
|
47
49
|
time = Math.round(time * 100) / 100 // https://stackoverflow.com/a/11832950/7811162
|
|
48
50
|
}
|
|
49
51
|
|
|
50
|
-
if (opts.quiet === true)
|
|
52
|
+
if (opts.quiet === true)
|
|
53
|
+
return resolve(ExitCode.Success)
|
|
51
54
|
|
|
52
|
-
if (error)
|
|
53
|
-
|
|
55
|
+
if (error) {
|
|
56
|
+
log.error(`[${time.toFixed(2)}${opts.useSeconds ? 's' : 'ms'}] Failed`)
|
|
57
|
+
}
|
|
58
|
+
else if (opts.type === 'info') {
|
|
54
59
|
log.info(`${dim(gray(`[${time.toFixed(2)}${opts.useSeconds ? 's' : 'ms'}]`))} ${opts.message ?? 'Complete'}`)
|
|
55
|
-
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
56
62
|
log.success(
|
|
57
63
|
`${dim(gray(bold(`[${time.toFixed(2)}${opts.useSeconds ? 's' : 'ms'}]`)))} ${bold(
|
|
58
64
|
green(opts.message ?? 'Complete'),
|
|
59
65
|
)}`,
|
|
60
66
|
)
|
|
61
|
-
|
|
62
|
-
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
if (opts?.type === 'info')
|
|
71
|
+
log.info(text)
|
|
63
72
|
// the following condition triggers in the case of "Cleaned up" messages
|
|
64
|
-
else if (opts?.type === 'success' && opts?.quiet !== true)
|
|
73
|
+
else if (opts?.type === 'success' && opts?.quiet !== true)
|
|
74
|
+
log.success(text)
|
|
65
75
|
}
|
|
66
76
|
|
|
67
77
|
return resolve(ExitCode.Success)
|
package/src/index.ts
CHANGED
|
@@ -2,9 +2,9 @@ export * from './actions'
|
|
|
2
2
|
export * from './cli'
|
|
3
3
|
export * from './command'
|
|
4
4
|
export * from './console'
|
|
5
|
+
export * from './exec'
|
|
5
6
|
export * from './helpers'
|
|
6
7
|
export * from './parse'
|
|
7
|
-
export * from './exec'
|
|
8
8
|
export * from './run'
|
|
9
9
|
export * from './spinner'
|
|
10
10
|
export * from './utils'
|
package/src/parse.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import process from 'node:process'
|
|
2
|
-
import { log } from '@stacksjs/logging'
|
|
3
2
|
|
|
4
3
|
interface ParsedArgv {
|
|
5
4
|
args: string[]
|
|
@@ -9,7 +8,8 @@ interface ParsedArgv {
|
|
|
9
8
|
}
|
|
10
9
|
|
|
11
10
|
function isLongOption(arg?: string): boolean {
|
|
12
|
-
if (!arg)
|
|
11
|
+
if (!arg)
|
|
12
|
+
return false
|
|
13
13
|
|
|
14
14
|
return arg.startsWith('--')
|
|
15
15
|
}
|
|
@@ -19,12 +19,15 @@ function isShortOption(arg: string): boolean {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
function parseValue(value: string): string | boolean | number {
|
|
22
|
-
if (value === 'true')
|
|
22
|
+
if (value === 'true')
|
|
23
|
+
return true
|
|
23
24
|
|
|
24
|
-
if (value === 'false')
|
|
25
|
+
if (value === 'false')
|
|
26
|
+
return false
|
|
25
27
|
|
|
26
28
|
const numberValue = Number.parseFloat(value)
|
|
27
|
-
if (!Number.isNaN(numberValue))
|
|
29
|
+
if (!Number.isNaN(numberValue))
|
|
30
|
+
return numberValue
|
|
28
31
|
|
|
29
32
|
return value.replace(/"/g, '')
|
|
30
33
|
}
|
|
@@ -38,10 +41,12 @@ function parseLongOption(
|
|
|
38
41
|
const [key, value] = arg.slice(2).split('=')
|
|
39
42
|
if (value !== undefined) {
|
|
40
43
|
options[key as string] = parseValue(value)
|
|
41
|
-
}
|
|
44
|
+
}
|
|
45
|
+
else if (index + 1 < argv.length && !argv[index + 1]?.startsWith('-')) {
|
|
42
46
|
options[key as string] = argv[index + 1] as string
|
|
43
47
|
index++
|
|
44
|
-
}
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
45
50
|
options[key as string] = true
|
|
46
51
|
}
|
|
47
52
|
return index
|
|
@@ -56,16 +61,19 @@ function parseShortOption(
|
|
|
56
61
|
const [key, value] = arg.slice(1).split('=')
|
|
57
62
|
|
|
58
63
|
// Check if key is undefined and handle it
|
|
59
|
-
if (key === undefined)
|
|
64
|
+
if (key === undefined)
|
|
65
|
+
return index
|
|
60
66
|
|
|
61
67
|
if (value !== undefined && key !== undefined) {
|
|
62
68
|
for (let j = 0; j < key.length; j++) options[key[j] as string] = parseValue(value)
|
|
63
|
-
}
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
64
71
|
for (let j = 0; j < key.length; j++) {
|
|
65
72
|
if (index + 1 < argv.length && j === key.length - 1 && !argv[index + 1]?.startsWith('-')) {
|
|
66
73
|
options[key[j] as string] = parseValue(argv[index + 1] as string)
|
|
67
74
|
index++
|
|
68
|
-
}
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
69
77
|
options[key[j] as string] = true
|
|
70
78
|
}
|
|
71
79
|
}
|
|
@@ -75,16 +83,20 @@ function parseShortOption(
|
|
|
75
83
|
}
|
|
76
84
|
|
|
77
85
|
export function parseArgv(argv?: string[]): ParsedArgv {
|
|
78
|
-
if (argv === undefined)
|
|
86
|
+
if (argv === undefined)
|
|
87
|
+
argv = process.argv.slice(2)
|
|
79
88
|
|
|
80
89
|
const args: string[] = []
|
|
81
90
|
const options: { [k: string]: string | boolean | number } = {}
|
|
82
91
|
|
|
83
92
|
for (let i = 0; i < argv.length; i++) {
|
|
84
93
|
const arg = argv[i]
|
|
85
|
-
if (!arg)
|
|
86
|
-
|
|
87
|
-
|
|
94
|
+
if (!arg)
|
|
95
|
+
continue
|
|
96
|
+
if (isLongOption(arg))
|
|
97
|
+
i = parseLongOption(arg, argv, i, options)
|
|
98
|
+
else if (isShortOption(arg))
|
|
99
|
+
i = parseShortOption(arg, argv, i, options)
|
|
88
100
|
else args.push(arg)
|
|
89
101
|
}
|
|
90
102
|
|
|
@@ -92,7 +104,8 @@ export function parseArgv(argv?: string[]): ParsedArgv {
|
|
|
92
104
|
}
|
|
93
105
|
|
|
94
106
|
export function parseArgs(argv?: string[]): string[] {
|
|
95
|
-
if (argv === undefined)
|
|
107
|
+
if (argv === undefined)
|
|
108
|
+
argv = process.argv.slice(2)
|
|
96
109
|
|
|
97
110
|
return parseArgv(argv).args
|
|
98
111
|
}
|
|
@@ -106,6 +119,7 @@ interface CliOptions {
|
|
|
106
119
|
|
|
107
120
|
export function parseOptions(options?: CliOptions): CliOptions {
|
|
108
121
|
options = options || {}
|
|
122
|
+
const defaults = { dryRun: false, quiet: false, verbose: false }
|
|
109
123
|
const args = process.argv.slice(2)
|
|
110
124
|
|
|
111
125
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -114,57 +128,55 @@ export function parseOptions(options?: CliOptions): CliOptions {
|
|
|
114
128
|
const key = arg.substring(2) // remove the --
|
|
115
129
|
const camelCaseKey = key.replace(
|
|
116
130
|
/-([a-z])/gi,
|
|
117
|
-
|
|
131
|
+
g => (g[1] ? g[1].toUpperCase() : ''), // convert kebab-case to camelCase
|
|
118
132
|
)
|
|
119
133
|
|
|
120
|
-
if (i + 1 < args.length) {
|
|
121
|
-
// if the next arg exists
|
|
122
|
-
if (args[i + 1] === 'true' || args[i + 1] === 'false') {
|
|
134
|
+
if (i + 1 < args.length && !args?.[i + 1]?.startsWith('--')) {
|
|
135
|
+
// if the next arg exists and is not an option
|
|
136
|
+
if (args?.[i + 1] === 'true' || args?.[i + 1] === 'false') {
|
|
123
137
|
// if the next arg is a boolean
|
|
124
138
|
options[camelCaseKey] = args[i + 1] === 'true' // set the value to the boolean
|
|
125
139
|
i++
|
|
126
|
-
}
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
127
142
|
options[camelCaseKey] = args[i + 1]
|
|
128
143
|
i++
|
|
129
144
|
}
|
|
130
|
-
}
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
131
147
|
options[camelCaseKey] = true
|
|
132
148
|
}
|
|
133
149
|
}
|
|
134
150
|
}
|
|
135
151
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
// convert the string 'true' or 'false' to a boolean
|
|
140
|
-
Object.keys(options).forEach((key) => {
|
|
141
|
-
if (!options) return { dryRun: false, quiet: false, verbose: false }
|
|
142
|
-
|
|
143
|
-
const value = options[key]
|
|
152
|
+
if (Object.keys(options).length === 0)
|
|
153
|
+
// if options has no keys, return an empty object
|
|
154
|
+
return {}
|
|
144
155
|
|
|
145
|
-
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
return options
|
|
156
|
+
return { ...defaults, ...options }
|
|
149
157
|
}
|
|
158
|
+
|
|
150
159
|
// interface BuddyOptions {
|
|
151
160
|
// dryRun?: boolean
|
|
152
161
|
// verbose?: boolean
|
|
153
162
|
// }
|
|
154
|
-
export function buddyOptions(options?: any): string {
|
|
155
|
-
if (
|
|
156
|
-
options =
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
if (options[0] && !options[0].startsWith('-')) options.shift()
|
|
163
|
+
export function buddyOptions(options?: string[] | Record<string, any>): string {
|
|
164
|
+
if (Array.isArray(options)) {
|
|
165
|
+
options = Array.from(new Set(options)) as string[]
|
|
166
|
+
if (Array.isArray(options) && options[0] && !options[0].startsWith('-'))
|
|
167
|
+
options.shift()
|
|
168
|
+
return options.join(' ')
|
|
161
169
|
}
|
|
162
170
|
|
|
163
|
-
if (options
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
171
|
+
if (typeof options === 'object' && options !== null) {
|
|
172
|
+
return Object.entries(options)
|
|
173
|
+
.map(([key, value]) => {
|
|
174
|
+
if (value === true)
|
|
175
|
+
return `--${key}`
|
|
176
|
+
return `--${key} ${value}`
|
|
177
|
+
})
|
|
178
|
+
.join(' ')
|
|
167
179
|
}
|
|
168
180
|
|
|
169
|
-
return
|
|
181
|
+
return buddyOptions(process.argv.slice(2))
|
|
170
182
|
}
|
package/src/run.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import type { Result } from '@stacksjs/error-handling'
|
|
2
|
-
import type { CliOptions, CommandError, Subprocess } from '@stacksjs/types'
|
|
1
|
+
import type { Ok, Result } from '@stacksjs/error-handling'
|
|
2
|
+
import type { CliOptions, CommandError, Readable, Subprocess, Writable } from '@stacksjs/types'
|
|
3
|
+
import process from 'node:process'
|
|
3
4
|
import { ExitCode } from '@stacksjs/types'
|
|
4
5
|
import { log } from './console'
|
|
5
6
|
import { exec, execSync } from './exec'
|
|
@@ -90,7 +91,10 @@ export async function runCommandSync(command: string, options?: CliOptions): Pro
|
|
|
90
91
|
* @param options The options to pass to the command.
|
|
91
92
|
* @returns The result of the command.
|
|
92
93
|
*/
|
|
93
|
-
export async function runCommands(
|
|
94
|
+
export async function runCommands(
|
|
95
|
+
commands: string[],
|
|
96
|
+
options?: CliOptions,
|
|
97
|
+
): Promise<Ok<Subprocess<Writable, Readable, Readable>, Error>[]> {
|
|
94
98
|
const results = []
|
|
95
99
|
|
|
96
100
|
for (const command of commands) {
|
package/src/spinner.ts
CHANGED
package/src/utils.ts
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import { collect } from '@stacksjs/collections'
|
|
2
|
-
|
|
3
|
-
export * as kolorist from 'kolorist'
|
|
1
|
+
import { collect, type Collection } from '@stacksjs/collections'
|
|
4
2
|
|
|
5
3
|
export {
|
|
6
|
-
stripAnsi,
|
|
7
|
-
centerAlign,
|
|
8
|
-
rightAlign,
|
|
9
|
-
leftAlign,
|
|
10
4
|
align,
|
|
11
5
|
box,
|
|
6
|
+
centerAlign,
|
|
7
|
+
colorize,
|
|
12
8
|
colors,
|
|
13
9
|
getColor,
|
|
14
|
-
|
|
10
|
+
leftAlign,
|
|
11
|
+
rightAlign,
|
|
12
|
+
stripAnsi,
|
|
15
13
|
} from 'consola/utils'
|
|
16
14
|
|
|
15
|
+
export * as kolorist from 'kolorist'
|
|
16
|
+
|
|
17
17
|
export {
|
|
18
|
+
ansi256,
|
|
18
19
|
ansi256Bg,
|
|
19
20
|
bgBlack,
|
|
20
21
|
bgBlue,
|
|
@@ -54,16 +55,15 @@ export {
|
|
|
54
55
|
red,
|
|
55
56
|
reset,
|
|
56
57
|
strikethrough,
|
|
58
|
+
stripColors,
|
|
59
|
+
trueColor,
|
|
60
|
+
trueColorBg,
|
|
57
61
|
underline,
|
|
58
62
|
white,
|
|
59
63
|
yellow,
|
|
60
|
-
ansi256,
|
|
61
|
-
trueColor,
|
|
62
|
-
trueColorBg,
|
|
63
|
-
stripColors,
|
|
64
64
|
} from 'kolorist'
|
|
65
65
|
|
|
66
|
-
export const quotes = collect([
|
|
66
|
+
export const quotes: Collection<string> = collect([
|
|
67
67
|
// could be queried from any API or database
|
|
68
68
|
'The best way to get started is to quit talking and begin doing.',
|
|
69
69
|
'The pessimist sees difficulty in every opportunity. The optimist sees opportunity in every difficulty.',
|