prool 0.0.25 → 0.1.1

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 (114) hide show
  1. package/{LICENSE → LICENSE.md} +1 -1
  2. package/README.md +46 -163
  3. package/{_lib/instance.d.ts → dist/Instance.d.ts} +28 -25
  4. package/dist/Instance.d.ts.map +1 -0
  5. package/{_lib/instance.js → dist/Instance.js} +9 -4
  6. package/dist/Instance.js.map +1 -0
  7. package/{_lib/pool.d.ts → dist/Pool.d.ts} +15 -13
  8. package/dist/Pool.d.ts.map +1 -0
  9. package/{_lib/pool.js → dist/Pool.js} +3 -3
  10. package/dist/Pool.js.map +1 -0
  11. package/{_lib/server.d.ts → dist/Server.d.ts} +7 -10
  12. package/dist/Server.d.ts.map +1 -0
  13. package/{_lib/server.js → dist/Server.js} +8 -9
  14. package/dist/Server.js.map +1 -0
  15. package/dist/index.d.ts +4 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +4 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/instances/alto.d.ts +452 -0
  20. package/dist/instances/alto.d.ts.map +1 -0
  21. package/{_lib → dist}/instances/alto.js +4 -4
  22. package/dist/instances/alto.js.map +1 -0
  23. package/dist/instances/anvil.d.ts +458 -0
  24. package/dist/instances/anvil.d.ts.map +1 -0
  25. package/{_lib → dist}/instances/anvil.js +4 -4
  26. package/dist/instances/anvil.js.map +1 -0
  27. package/dist/instances/tempo.d.ts +189 -0
  28. package/dist/instances/tempo.d.ts.map +1 -0
  29. package/dist/instances/tempo.js +200 -0
  30. package/dist/instances/tempo.js.map +1 -0
  31. package/{_lib → dist/internal}/utils.d.ts +5 -5
  32. package/dist/internal/utils.d.ts.map +1 -0
  33. package/{_lib → dist/internal}/utils.js +37 -7
  34. package/dist/internal/utils.js.map +1 -0
  35. package/{_lib → dist}/processes/execa.d.ts +11 -10
  36. package/dist/processes/execa.d.ts.map +1 -0
  37. package/{_lib → dist}/processes/execa.js +1 -1
  38. package/dist/processes/execa.js.map +1 -0
  39. package/package.json +17 -16
  40. package/{instance.test.ts → src/Instance.test.ts} +12 -12
  41. package/{instance.ts → src/Instance.ts} +51 -42
  42. package/{pool.test.ts → src/Pool.test.ts} +41 -55
  43. package/{pool.ts → src/Pool.ts} +21 -19
  44. package/{server.test.ts → src/Server.test.ts} +26 -149
  45. package/{server.ts → src/Server.ts} +9 -11
  46. package/src/index.ts +3 -0
  47. package/{instances → src/instances}/alto.test.ts +8 -11
  48. package/src/instances/alto.ts +289 -0
  49. package/{instances → src/instances}/anvil.test.ts +5 -6
  50. package/src/instances/anvil.ts +306 -0
  51. package/{instances/silius.test.ts → src/instances/tempo.test.ts} +20 -44
  52. package/src/instances/tempo.ts +322 -0
  53. package/{utils.test.ts → src/internal/utils.test.ts} +20 -6
  54. package/{utils.ts → src/internal/utils.ts} +47 -17
  55. package/{processes → src/processes}/execa.test.ts +6 -11
  56. package/{processes → src/processes}/execa.ts +19 -15
  57. package/src/processes/index.ts +1 -0
  58. package/CHANGELOG.md +0 -154
  59. package/_lib/exports/index.d.ts +0 -5
  60. package/_lib/exports/index.d.ts.map +0 -1
  61. package/_lib/exports/index.js +0 -5
  62. package/_lib/exports/index.js.map +0 -1
  63. package/_lib/exports/instances.d.ts +0 -7
  64. package/_lib/exports/instances.d.ts.map +0 -1
  65. package/_lib/exports/instances.js +0 -7
  66. package/_lib/exports/instances.js.map +0 -1
  67. package/_lib/exports/processes.d.ts +0 -2
  68. package/_lib/exports/processes.d.ts.map +0 -1
  69. package/_lib/exports/processes.js +0 -2
  70. package/_lib/exports/processes.js.map +0 -1
  71. package/_lib/instance.d.ts.map +0 -1
  72. package/_lib/instance.js.map +0 -1
  73. package/_lib/instances/alto.d.ts +0 -449
  74. package/_lib/instances/alto.d.ts.map +0 -1
  75. package/_lib/instances/alto.js.map +0 -1
  76. package/_lib/instances/anvil.d.ts +0 -455
  77. package/_lib/instances/anvil.d.ts.map +0 -1
  78. package/_lib/instances/anvil.js.map +0 -1
  79. package/_lib/instances/rundler.d.ts +0 -604
  80. package/_lib/instances/rundler.d.ts.map +0 -1
  81. package/_lib/instances/rundler.js +0 -86
  82. package/_lib/instances/rundler.js.map +0 -1
  83. package/_lib/instances/silius.d.ts +0 -224
  84. package/_lib/instances/silius.d.ts.map +0 -1
  85. package/_lib/instances/silius.js +0 -117
  86. package/_lib/instances/silius.js.map +0 -1
  87. package/_lib/instances/stackup.d.ts +0 -86
  88. package/_lib/instances/stackup.d.ts.map +0 -1
  89. package/_lib/instances/stackup.js +0 -89
  90. package/_lib/instances/stackup.js.map +0 -1
  91. package/_lib/pool.d.ts.map +0 -1
  92. package/_lib/pool.js.map +0 -1
  93. package/_lib/processes/execa.d.ts.map +0 -1
  94. package/_lib/processes/execa.js.map +0 -1
  95. package/_lib/server.d.ts.map +0 -1
  96. package/_lib/server.js.map +0 -1
  97. package/_lib/utils.d.ts.map +0 -1
  98. package/_lib/utils.js.map +0 -1
  99. package/exports/index.test.ts +0 -16
  100. package/exports/index.ts +0 -29
  101. package/exports/instances.test.ts +0 -15
  102. package/exports/instances.ts +0 -13
  103. package/exports/processes.test.ts +0 -10
  104. package/exports/processes.ts +0 -8
  105. package/instances/alto.ts +0 -280
  106. package/instances/anvil.ts +0 -304
  107. package/instances/package.json +0 -5
  108. package/instances/rundler.test.ts +0 -111
  109. package/instances/rundler.ts +0 -451
  110. package/instances/silius.ts +0 -347
  111. package/instances/stackup.test.ts +0 -106
  112. package/instances/stackup.ts +0 -162
  113. package/processes/package.json +0 -5
  114. package/tsconfig.build.tsbuildinfo +0 -1
@@ -0,0 +1,322 @@
1
+ import * as os from 'node:os'
2
+ import * as path from 'node:path'
3
+ import {
4
+ GenericContainer,
5
+ type StartedTestContainer,
6
+ Wait,
7
+ } from 'testcontainers'
8
+ import * as Instance from '../Instance.js'
9
+ import { deepAssign, toArgs } from '../internal/utils.js'
10
+ import { execa } from '../processes/execa.js'
11
+
12
+ export function command(parameters: tempo.Parameters): string[] {
13
+ const { blockMaxTransactions, blockTime, mnemonic, port, ...rest } =
14
+ parameters
15
+
16
+ const datadir = path.join(os.tmpdir(), '.prool', `tempo.${port}`)
17
+ const defaultParameters = {
18
+ authrpc: {
19
+ port: port! + 30,
20
+ },
21
+ datadir,
22
+ dev: [
23
+ true,
24
+ {
25
+ blockTime: blockTime ?? '50ms',
26
+ ...(blockMaxTransactions ? { blockMaxTransactions } : {}),
27
+ ...(mnemonic ? { mnemonic } : {}),
28
+ },
29
+ ],
30
+ engine: {
31
+ disablePrecompileCache: true,
32
+ legacyStateRoot: true,
33
+ },
34
+ faucet: {
35
+ address: [
36
+ '0x20c0000000000000000000000000000000000000',
37
+ '0x20c0000000000000000000000000000000000001',
38
+ '0x20c0000000000000000000000000000000000002',
39
+ '0x20c0000000000000000000000000000000000003',
40
+ ],
41
+ amount: '1000000000000',
42
+ enabled: true,
43
+ privateKey:
44
+ '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80',
45
+ },
46
+ http: {
47
+ addr: '0.0.0.0',
48
+ api: 'all',
49
+ corsdomain: '*',
50
+ port: port!,
51
+ },
52
+ port: port! + 10,
53
+ ws: {
54
+ port: port! + 20,
55
+ },
56
+ }
57
+
58
+ return [
59
+ 'node',
60
+ ...toArgs(deepAssign(defaultParameters, rest), {
61
+ arraySeparator: null,
62
+ }),
63
+ ]
64
+ }
65
+
66
+ /**
67
+ * Defines a Tempo instance.
68
+ *
69
+ * @example
70
+ * ```ts
71
+ * const instance = Instance.tempo({ port: 8545 })
72
+ * await instance.start()
73
+ * // ...
74
+ * await instance.stop()
75
+ * ```
76
+ */
77
+ export const tempo = Instance.define((parameters?: tempo.Parameters) => {
78
+ const { binary = 'tempo', log: log_, ...args } = parameters || {}
79
+
80
+ const log = (() => {
81
+ try {
82
+ return JSON.parse(log_ as string)
83
+ } catch {
84
+ return log_
85
+ }
86
+ })()
87
+ const RUST_LOG = log && typeof log !== 'boolean' ? log : ''
88
+
89
+ const name = 'tempo'
90
+ const process = execa({ name })
91
+
92
+ return {
93
+ _internal: {
94
+ args,
95
+ get process() {
96
+ return process._internal.process
97
+ },
98
+ },
99
+ host: args.host ?? 'localhost',
100
+ name,
101
+ port: args.port ?? 8545,
102
+ async start({ port = args.port }, options) {
103
+ return await process.start(
104
+ ($) =>
105
+ $({
106
+ env: {
107
+ RUST_LOG,
108
+ },
109
+ })`${[binary, ...command({ ...args, port })]}`,
110
+ {
111
+ ...options,
112
+ // Resolve when the process is listening via "RPC HTTP server started" message.
113
+ resolver({ process, reject, resolve }) {
114
+ process.stdout.on('data', (data) => {
115
+ const message = data.toString()
116
+ if (log) console.log(message)
117
+ if (message.includes('RPC HTTP server started')) resolve()
118
+ if (message.includes('shutting down')) reject('shutting down')
119
+ })
120
+ process.stderr.on('data', (data) => {
121
+ const message = data.toString()
122
+ if (log) console.error(message)
123
+ })
124
+ },
125
+ },
126
+ )
127
+ },
128
+ async stop() {
129
+ await process.stop()
130
+ },
131
+ }
132
+ })
133
+
134
+ export declare namespace tempo {
135
+ export type Parameters = {
136
+ /**
137
+ * Path or alias to the Tempo binary.
138
+ */
139
+ binary?: string | undefined
140
+ /**
141
+ * Interval between blocks.
142
+ */
143
+ blockTime?: string | undefined
144
+ /**
145
+ * How many transactions to mine per block
146
+ */
147
+ blockMaxTransactions?: number | undefined
148
+ /**
149
+ * Path to a configuration file.
150
+ */
151
+ config?: string | undefined
152
+ /**
153
+ * The chain this node is running.
154
+ * Possible values are either a built-in chain or the path to a chain specification file.
155
+ *
156
+ * Built-in chains:
157
+ * - testnet
158
+ *
159
+ * @default "testnet"
160
+ */
161
+ chain?: string | undefined
162
+ /**
163
+ * The path to the data dir for all reth files and subdirectories.
164
+ */
165
+ datadir?: string | undefined
166
+ /**
167
+ * Faucet options.
168
+ */
169
+ faucet?:
170
+ | {
171
+ /**
172
+ * Target token addresses for the faucet to be funding with
173
+ */
174
+ addresses?: string[] | undefined
175
+ /**
176
+ * Amount for each faucet funding transaction
177
+ */
178
+ amount?: bigint | undefined
179
+ /**
180
+ * Faucet funding mnemonic
181
+ */
182
+ privateKey?: string | undefined
183
+ }
184
+ | undefined
185
+ /**
186
+ * Rust log level configuration (sets RUST_LOG environment variable).
187
+ * Can be a log level or a custom filter string.
188
+ */
189
+ log?:
190
+ | 'trace'
191
+ | 'debug'
192
+ | 'info'
193
+ | 'warn'
194
+ | 'error'
195
+ | (string & {})
196
+ | boolean
197
+ | undefined
198
+ /**
199
+ * Host the server will listen on.
200
+ */
201
+ host?: string | undefined
202
+ /**
203
+ * Derive dev accounts from a fixed mnemonic instead of random ones.
204
+ * @default "test test test test test test test test test test test junk"
205
+ */
206
+ mnemonic?: string | undefined
207
+ /**
208
+ * Port the server will listen on.
209
+ */
210
+ port?: number | undefined
211
+ } & Record<string, unknown>
212
+ }
213
+
214
+ /**
215
+ * Defines a Tempo instance.
216
+ *
217
+ * @example
218
+ * ```ts
219
+ * const instance = Instance.tempoDocker({ port: 8545 })
220
+ * await instance.start()
221
+ * // ...
222
+ * await instance.stop()
223
+ * ```
224
+ */
225
+ export const tempoDocker = Instance.define(
226
+ (parameters?: tempoDocker.Parameters) => {
227
+ const {
228
+ containerName = `tempo.${crypto.randomUUID()}`,
229
+ image = 'ghcr.io/tempoxyz/tempo:latest',
230
+ log: log_,
231
+ ...args
232
+ } = parameters || {}
233
+
234
+ const log = (() => {
235
+ try {
236
+ return JSON.parse(log_ as string)
237
+ } catch {
238
+ return log_
239
+ }
240
+ })()
241
+ const RUST_LOG = log && typeof log !== 'boolean' ? log : ''
242
+
243
+ const name = 'tempo'
244
+ let container: StartedTestContainer | undefined
245
+
246
+ return {
247
+ _internal: {
248
+ args,
249
+ },
250
+ host: args.host ?? 'localhost',
251
+ name,
252
+ port: args.port ?? 8545,
253
+ async start({ port = args.port }, { emitter }) {
254
+ const promise = Promise.withResolvers<void>()
255
+
256
+ const c = new GenericContainer(image)
257
+ .withPlatform('linux/x86_64')
258
+ .withNetworkMode('host')
259
+ .withExtraHosts([
260
+ { host: 'host.docker.internal', ipAddress: 'host-gateway' },
261
+ { host: 'localhost', ipAddress: 'host-gateway' },
262
+ ])
263
+ .withName(containerName)
264
+ .withEnvironment({ RUST_LOG })
265
+ .withCommand(command({ ...args, port }))
266
+ .withWaitStrategy(Wait.forLogMessage(/RPC HTTP server started/))
267
+ .withLogConsumer((stream) => {
268
+ stream.on('data', (data) => {
269
+ const message = data.toString()
270
+ emitter.emit('message', message)
271
+ emitter.emit('stdout', message)
272
+ if (log) console.log(message)
273
+ if (message.includes('shutting down'))
274
+ promise.reject(new Error(`Failed to start: ${message}`))
275
+ })
276
+ stream.on('error', (error) => {
277
+ if (log) console.error(error.message)
278
+ emitter.emit('message', error.message)
279
+ emitter.emit('stderr', error.message)
280
+ promise.reject(new Error(`Failed to start: ${error.message}`))
281
+ })
282
+ })
283
+ .withStartupTimeout(10_000)
284
+
285
+ c.start()
286
+ .then((c) => {
287
+ container = c
288
+ promise.resolve()
289
+ })
290
+ .catch(promise.reject)
291
+
292
+ return promise.promise
293
+ },
294
+ async stop() {
295
+ if (!container) return
296
+ await container.stop()
297
+ container = undefined
298
+ },
299
+ }
300
+ },
301
+ )
302
+
303
+ export declare namespace tempoDocker {
304
+ export type Parameters = Omit<tempo.Parameters, 'binary'> & {
305
+ /**
306
+ * Name of the container.
307
+ */
308
+ containerName?: string | undefined
309
+ /**
310
+ * Docker image to use.
311
+ */
312
+ image?: string | undefined
313
+ /**
314
+ * Host the server will listen on.
315
+ */
316
+ host?: string | undefined
317
+ /**
318
+ * Port the server will listen on.
319
+ */
320
+ port?: number | undefined
321
+ }
322
+ }
@@ -30,10 +30,12 @@ test.each([
30
30
  [[{ foo: 0 }], ['--foo', '0']],
31
31
  [[{ foo: 1 }], ['--foo', '1']],
32
32
  [[{ foo: 1n }], ['--foo', '1']],
33
+ [[{ foo: 1n }], ['--foo', '1']],
33
34
  [[{ foo: 'bar', baz: 1 }], ['--foo', 'bar', '--baz', '1']],
34
35
  [[{ fooBar: 'test' }], ['--foo-bar', 'test']],
35
36
  [[{ foo: ['bar', 'baz'] }], ['--foo', 'bar,baz']],
36
37
  [[{ foo: { barBaz: 'test' } }], ['--foo.bar-baz', 'test']],
38
+ [[{ foo: [true, { barBaz: 'test' }] }], ['--foo', '--foo.bar-baz', 'test']],
37
39
  [[{ foo: { barBaz: ['test', 'test2'] } }], ['--foo.bar-baz', 'test,test2']],
38
40
  [
39
41
  [{ fooBar: 'test' }, { casing: 'snake' }],
@@ -43,12 +45,24 @@ test.each([
43
45
  [{ foo: { barBaz: 'test' } }, { casing: 'snake' }],
44
46
  ['--foo.bar_baz', 'test'],
45
47
  ],
46
- ] as [Parameters<typeof toArgs>, string[]][])(
47
- 'toArgs(%o) -> %o',
48
- ([input, options], expected) => {
49
- expect(toArgs(input, options)).toEqual(expected)
50
- },
51
- )
48
+ [
49
+ [{ foo: ['bar', 'baz'] }, { arraySeparator: null }],
50
+ ['--foo', 'bar', 'baz'],
51
+ ],
52
+ [
53
+ [{ foo: { bar: ['baz', 'qux'] } }, { arraySeparator: null }],
54
+ ['--foo.bar', 'baz', 'qux'],
55
+ ],
56
+ [
57
+ [{ foo: ['bar', 'baz'] }, { arraySeparator: null }],
58
+ ['--foo', 'bar', 'baz'],
59
+ ],
60
+ ] as [Parameters<typeof toArgs>, string[]][])('toArgs(%o) -> %o', ([
61
+ input,
62
+ options,
63
+ ], expected) => {
64
+ expect(toArgs(input, options)).toEqual(expected)
65
+ })
52
66
 
53
67
  test.each([
54
68
  ['foo', '--foo'],
@@ -30,7 +30,7 @@ export function extractPath(request: string): ExtractPathReturnType {
30
30
  }
31
31
 
32
32
  const ansiColorRegex =
33
- // biome-ignore lint/suspicious/noControlCharactersInRegex: <explanation>
33
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: _
34
34
  /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g
35
35
 
36
36
  /**
@@ -50,23 +50,26 @@ export function stripColors(message: string) {
50
50
  * @returns The command line arguments.
51
51
  */
52
52
  export function toArgs(
53
- obj: {
54
- [key: string]:
55
- | Record<string, any>
56
- | string
57
- | readonly string[]
58
- | boolean
59
- | number
60
- | bigint
61
- | undefined
62
- },
63
- options: { casing: 'kebab' | 'snake' } = { casing: 'kebab' },
64
- ) {
65
- const { casing } = options
53
+ obj: Record<string, unknown>,
54
+ options: {
55
+ arraySeparator?: string | null | undefined
56
+ casing?: 'kebab' | 'snake' | undefined
57
+ } = {},
58
+ ): string[] {
59
+ const { arraySeparator = ',', casing = 'kebab' } = options
66
60
  return Object.entries(obj).flatMap(([key, value]) => {
67
61
  if (value === undefined) return []
68
62
 
69
- if (Array.isArray(value)) return [toFlagCase(key), value.join(',')]
63
+ if (Array.isArray(value)) {
64
+ if (value[0] === true)
65
+ return [toFlagCase(key), ...toArgs({ [key]: value[1] }, options)]
66
+ const arrayValue = (() => {
67
+ if (arraySeparator === null) return value
68
+ return value.join(arraySeparator)
69
+ })()
70
+
71
+ return [toFlagCase(key), arrayValue].flat()
72
+ }
70
73
 
71
74
  if (typeof value === 'object' && value !== null) {
72
75
  return Object.entries(value).flatMap(([subKey, subValue]) => {
@@ -75,7 +78,7 @@ export function toArgs(
75
78
  `${key}.${subKey}`,
76
79
  casing === 'kebab' ? '-' : '_',
77
80
  )
78
- return [flag, Array.isArray(subValue) ? subValue.join(',') : subValue]
81
+ return toArgs({ [flag.slice(2)]: subValue }, options)
79
82
  })
80
83
  }
81
84
 
@@ -84,7 +87,7 @@ export function toArgs(
84
87
  if (value === false) return [flag, 'false']
85
88
  if (value === true) return [flag]
86
89
 
87
- const stringified = value.toString()
90
+ const stringified = value?.toString() ?? ''
88
91
  if (stringified === '') return [flag]
89
92
 
90
93
  return [flag, stringified]
@@ -106,3 +109,30 @@ export function toFlagCase(str: string, separator = '-') {
106
109
  }
107
110
  return `--${keys.join('.')}`
108
111
  }
112
+
113
+ function isPlainObject(value: unknown): value is Record<string, unknown> {
114
+ return Object.prototype.toString.call(value) === '[object Object]'
115
+ }
116
+
117
+ export function deepAssign(
118
+ target: Record<string, unknown>,
119
+ ...sources: Record<string, unknown>[]
120
+ ): Record<string, unknown> {
121
+ for (const source of sources) {
122
+ if (!isPlainObject(source)) continue
123
+
124
+ for (const key of Reflect.ownKeys(source)) {
125
+ const srcVal = source[key as keyof typeof source]
126
+ const tgtVal = target[key as keyof typeof target]
127
+
128
+ // If both are plain objects, merge recursively
129
+ if (isPlainObject(srcVal) && isPlainObject(tgtVal)) {
130
+ deepAssign(tgtVal, srcVal)
131
+ continue
132
+ }
133
+ // Otherwise, assign a deep clone of the source value
134
+ ;(target as any)[key] = structuredClone(srcVal)
135
+ }
136
+ }
137
+ return target
138
+ }
@@ -1,8 +1,9 @@
1
1
  import { EventEmitter } from 'eventemitter3'
2
+ import getPort from 'get-port'
2
3
  import { afterEach, expect, test } from 'vitest'
3
- import { type ExecaProcess, execa } from './execa.js'
4
+ import { execa } from './execa.js'
4
5
 
5
- const processes: ExecaProcess[] = []
6
+ const processes: execa.ReturnType[] = []
6
7
  function createProcess() {
7
8
  const process = execa({ name: 'foo' })
8
9
  processes.push(process)
@@ -82,14 +83,7 @@ test('start (error)', async () => {
82
83
  process.stderr.on('data', reject)
83
84
  },
84
85
  }),
85
- ).rejects.toThrowErrorMatchingInlineSnapshot(`
86
- [Error: Failed to start process "foo": error: unexpected argument '--lol' found
87
-
88
- Usage: anvil [OPTIONS] [COMMAND]
89
-
90
- For more information, try '--help'.
91
- ]
92
- `)
86
+ ).rejects.toThrowError('Failed to start process "foo"')
93
87
  await expect(resolvers.message.promise).resolves.toBeDefined()
94
88
  await expect(resolvers.stderr.promise).resolves.toBeDefined()
95
89
  })
@@ -128,7 +122,8 @@ test('behavior: exit when status is starting', async () => {
128
122
  emitter.on('exit', resolvers.exit.resolve)
129
123
 
130
124
  // Invalid argument
131
- await process.start(($) => $`anvil`, {
125
+ const port = await getPort()
126
+ await process.start(($) => $`anvil --port ${port}`, {
132
127
  emitter,
133
128
  status: 'starting',
134
129
  resolver({ process, resolve }) {
@@ -1,21 +1,20 @@
1
1
  import type { SignalConstants } from 'node:os'
2
- import { type ResultPromise, execa as exec } from 'execa'
3
- import type { InstanceStartOptions_internal } from '../instance.js'
4
- import { stripColors } from '../utils.js'
2
+ import { execa as exec, type ResultPromise } from 'execa'
3
+ import type * as Instance from '../Instance.js'
4
+ import { stripColors } from '../internal/utils.js'
5
5
 
6
6
  export type Process_internal = ResultPromise<{ cleanup: true; reject: false }>
7
7
 
8
- export type ExecaStartOptions = InstanceStartOptions_internal & {
9
- resolver(options: {
10
- process: Process_internal
11
- reject(data: string): Promise<void>
12
- resolve(): void
13
- }): void
14
- }
15
-
16
- export type ExecaParameters = { name: string }
8
+ export type ExecaStartOptions =
9
+ Instance.define.InstanceStartOptions_internal & {
10
+ resolver(options: {
11
+ process: Process_internal
12
+ reject(data: string): Promise<void>
13
+ resolve(): void
14
+ }): void
15
+ }
17
16
 
18
- export type ExecaProcess = {
17
+ export type Process = {
19
18
  _internal: {
20
19
  process: Process_internal
21
20
  }
@@ -26,9 +25,8 @@ export type ExecaProcess = {
26
25
  ): Promise<void>
27
26
  stop(signal?: keyof SignalConstants | number): Promise<void>
28
27
  }
29
- export type ExecaReturnType = ExecaProcess
30
28
 
31
- export function execa(parameters: ExecaParameters): ExecaReturnType {
29
+ export function execa(parameters: execa.Parameters): execa.ReturnType {
32
30
  const { name } = parameters
33
31
 
34
32
  const errorMessages: string[] = []
@@ -112,3 +110,9 @@ export function execa(parameters: ExecaParameters): ExecaReturnType {
112
110
  },
113
111
  }
114
112
  }
113
+
114
+ export declare namespace execa {
115
+ export type Parameters = { name: string }
116
+
117
+ export type ReturnType = Process
118
+ }
@@ -0,0 +1 @@
1
+ export * as execa from './execa.js'