@plugjs/plug 0.0.14 → 0.0.16
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/dist/async.cjs +20 -19
- package/dist/async.cjs.map +1 -1
- package/dist/async.d.ts +9 -9
- package/dist/async.mjs +18 -17
- package/dist/async.mjs.map +1 -1
- package/dist/build.cjs +113 -110
- package/dist/build.cjs.map +2 -2
- package/dist/build.d.ts +14 -56
- package/dist/build.mjs +114 -111
- package/dist/build.mjs.map +2 -2
- package/dist/files.cjs +2 -16
- package/dist/files.cjs.map +1 -1
- package/dist/files.d.ts +3 -10
- package/dist/files.mjs +3 -17
- package/dist/files.mjs.map +1 -1
- package/dist/fork.cjs +28 -40
- package/dist/fork.cjs.map +1 -1
- package/dist/fork.d.ts +6 -27
- package/dist/fork.mjs +29 -40
- package/dist/fork.mjs.map +1 -1
- package/dist/helpers.cjs +27 -61
- package/dist/helpers.cjs.map +2 -2
- package/dist/helpers.d.ts +29 -31
- package/dist/helpers.mjs +27 -62
- package/dist/helpers.mjs.map +2 -2
- package/dist/index.cjs +15 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +9 -13
- package/dist/index.mjs +7 -2
- package/dist/index.mjs.map +1 -1
- package/dist/log/colors.cjs +3 -1
- package/dist/log/colors.cjs.map +1 -1
- package/dist/log/colors.d.ts +2 -2
- package/dist/log/colors.mjs +3 -1
- package/dist/log/colors.mjs.map +1 -1
- package/dist/log/emit.d.ts +1 -1
- package/dist/log/logger.cjs +4 -0
- package/dist/log/logger.cjs.map +1 -1
- package/dist/log/logger.d.ts +4 -1
- package/dist/log/logger.mjs +4 -0
- package/dist/log/logger.mjs.map +1 -1
- package/dist/log/options.d.ts +1 -1
- package/dist/log/report.cjs +2 -11
- package/dist/log/report.cjs.map +1 -1
- package/dist/log/report.d.ts +36 -4
- package/dist/log/report.mjs +1 -10
- package/dist/log/report.mjs.map +1 -1
- package/dist/log.cjs +1 -1
- package/dist/log.cjs.map +1 -1
- package/dist/log.d.ts +6 -6
- package/dist/log.mjs +2 -2
- package/dist/log.mjs.map +1 -1
- package/dist/pipe.cjs +69 -26
- package/dist/pipe.cjs.map +1 -1
- package/dist/pipe.d.ts +178 -119
- package/dist/pipe.mjs +71 -24
- package/dist/pipe.mjs.map +1 -1
- package/dist/plugs/copy.cjs +15 -25
- package/dist/plugs/copy.cjs.map +2 -2
- package/dist/plugs/copy.d.ts +14 -13
- package/dist/plugs/copy.mjs +15 -17
- package/dist/plugs/copy.mjs.map +2 -2
- package/dist/plugs/coverage/analysis.d.ts +2 -2
- package/dist/plugs/coverage/report.cjs +1 -1
- package/dist/plugs/coverage/report.cjs.map +1 -1
- package/dist/plugs/coverage/report.d.ts +3 -3
- package/dist/plugs/coverage/report.mjs +1 -1
- package/dist/plugs/coverage/report.mjs.map +1 -1
- package/dist/plugs/coverage.cjs +20 -26
- package/dist/plugs/coverage.cjs.map +1 -1
- package/dist/plugs/coverage.d.ts +33 -30
- package/dist/plugs/coverage.mjs +21 -19
- package/dist/plugs/coverage.mjs.map +1 -1
- package/dist/plugs/debug.cjs +12 -36
- package/dist/plugs/debug.cjs.map +1 -1
- package/dist/plugs/debug.d.ts +4 -11
- package/dist/plugs/debug.mjs +30 -21
- package/dist/plugs/debug.mjs.map +1 -1
- package/dist/plugs/esbuild/fix-extensions.mjs +1 -1
- package/dist/plugs/esbuild/fix-extensions.mjs.map +1 -1
- package/dist/plugs/esbuild.cjs +14 -25
- package/dist/plugs/esbuild.cjs.map +1 -1
- package/dist/plugs/esbuild.d.ts +11 -16
- package/dist/plugs/esbuild.mjs +14 -17
- package/dist/plugs/esbuild.mjs.map +1 -1
- package/dist/plugs/eslint/runner.cjs +5 -6
- package/dist/plugs/eslint/runner.cjs.map +1 -1
- package/dist/plugs/eslint/runner.d.ts +6 -20
- package/dist/plugs/eslint/runner.mjs +6 -7
- package/dist/plugs/eslint/runner.mjs.map +1 -1
- package/dist/{task.cjs → plugs/eslint.cjs} +7 -24
- package/dist/plugs/eslint.cjs.map +6 -0
- package/dist/plugs/eslint.d.ts +34 -0
- package/dist/plugs/eslint.mjs +5 -0
- package/dist/plugs/eslint.mjs.map +6 -0
- package/dist/plugs/exec.cjs +20 -24
- package/dist/plugs/exec.cjs.map +1 -1
- package/dist/plugs/exec.d.ts +53 -53
- package/dist/plugs/exec.mjs +20 -23
- package/dist/plugs/exec.mjs.map +1 -1
- package/dist/plugs/filter.cjs +9 -19
- package/dist/plugs/filter.cjs.map +1 -1
- package/dist/plugs/filter.d.ts +21 -15
- package/dist/plugs/filter.mjs +10 -12
- package/dist/plugs/filter.mjs.map +1 -1
- package/dist/plugs/mocha/reporter.cjs +12 -6
- package/dist/plugs/mocha/reporter.cjs.map +1 -1
- package/dist/plugs/mocha/reporter.d.ts +0 -2
- package/dist/plugs/mocha/reporter.mjs +11 -4
- package/dist/plugs/mocha/reporter.mjs.map +1 -1
- package/dist/plugs/mocha/runner.cjs +4 -5
- package/dist/plugs/mocha/runner.cjs.map +1 -1
- package/dist/plugs/mocha/runner.d.ts +5 -31
- package/dist/plugs/mocha/runner.mjs +5 -6
- package/dist/plugs/mocha/runner.mjs.map +1 -1
- package/dist/plugs/mocha.cjs +22 -0
- package/dist/plugs/mocha.cjs.map +6 -0
- package/dist/plugs/mocha.d.ts +35 -0
- package/dist/plugs/mocha.mjs +5 -0
- package/dist/plugs/mocha.mjs.map +6 -0
- package/dist/plugs/rmf.cjs +4 -32
- package/dist/plugs/rmf.cjs.map +1 -1
- package/dist/plugs/rmf.d.ts +8 -12
- package/dist/plugs/rmf.mjs +25 -20
- package/dist/plugs/rmf.mjs.map +1 -1
- package/dist/plugs/tsc/compiler.d.ts +1 -1
- package/dist/plugs/tsc/options.d.ts +1 -1
- package/dist/plugs/tsc/report.d.ts +2 -2
- package/dist/plugs/tsc/runner.cjs +12 -11
- package/dist/plugs/tsc/runner.cjs.map +1 -1
- package/dist/plugs/tsc/runner.d.ts +4 -9
- package/dist/plugs/tsc/runner.mjs +12 -11
- package/dist/plugs/tsc/runner.mjs.map +1 -1
- package/dist/plugs/tsc.cjs +7 -0
- package/dist/plugs/tsc.cjs.map +6 -0
- package/dist/plugs/tsc.d.ts +36 -0
- package/dist/plugs/tsc.mjs +15 -0
- package/dist/plugs/tsc.mjs.map +6 -0
- package/dist/plugs.cjs +3 -5
- package/dist/plugs.cjs.map +1 -1
- package/dist/plugs.d.ts +10 -17
- package/dist/plugs.mjs +3 -5
- package/dist/plugs.mjs.map +1 -1
- package/dist/types.cjs +19 -0
- package/dist/types.cjs.map +6 -0
- package/dist/types.d.ts +71 -0
- package/dist/types.mjs +1 -0
- package/dist/types.mjs.map +6 -0
- package/dist/utils/caller.cjs +8 -11
- package/dist/utils/caller.cjs.map +2 -2
- package/dist/utils/caller.d.ts +2 -7
- package/dist/utils/caller.mjs +8 -11
- package/dist/utils/caller.mjs.map +2 -2
- package/dist/utils/options.cjs +4 -6
- package/dist/utils/options.cjs.map +1 -1
- package/dist/utils/options.d.ts +16 -15
- package/dist/utils/options.mjs +4 -6
- package/dist/utils/options.mjs.map +1 -1
- package/dist/utils/walk.d.ts +2 -2
- package/extra/cli.mjs +31 -20
- package/extra/ts-loader.mjs +6 -5
- package/package.json +8 -9
- package/src/async.ts +27 -19
- package/src/files.ts +6 -30
- package/src/fork.ts +35 -76
- package/src/helpers.ts +66 -99
- package/src/index.ts +10 -15
- package/src/log/colors.ts +4 -3
- package/src/log/emit.ts +4 -4
- package/src/log/logger.ts +12 -4
- package/src/log/options.ts +1 -1
- package/src/log/report.ts +8 -22
- package/src/log/spinner.ts +3 -3
- package/src/log.ts +9 -9
- package/src/paths.ts +1 -1
- package/src/pipe.ts +255 -170
- package/src/plugs/copy.ts +40 -31
- package/src/plugs/coverage/analysis.ts +4 -4
- package/src/plugs/coverage/report.ts +6 -5
- package/src/plugs/coverage.ts +64 -53
- package/src/plugs/debug.ts +28 -26
- package/src/plugs/esbuild/fix-extensions.ts +2 -2
- package/src/plugs/esbuild.ts +42 -46
- package/src/plugs/eslint/runner.ts +16 -31
- package/src/plugs/eslint.ts +42 -0
- package/src/plugs/exec.ts +93 -82
- package/src/plugs/filter.ts +42 -27
- package/src/plugs/mocha/reporter.ts +10 -5
- package/src/plugs/mocha/runner.ts +12 -38
- package/src/plugs/mocha.ts +41 -0
- package/src/plugs/rmf.ts +21 -25
- package/src/plugs/tsc/compiler.ts +1 -1
- package/src/plugs/tsc/options.ts +2 -2
- package/src/plugs/tsc/report.ts +2 -2
- package/src/plugs/tsc/runner.ts +24 -30
- package/src/plugs/tsc.ts +45 -0
- package/src/plugs.ts +10 -25
- package/src/types.ts +116 -0
- package/src/utils/caller.ts +11 -22
- package/src/utils/options.ts +49 -17
- package/src/utils/walk.ts +4 -4
- package/dist/run.cjs +0 -90
- package/dist/run.cjs.map +0 -6
- package/dist/run.d.ts +0 -89
- package/dist/run.mjs +0 -65
- package/dist/run.mjs.map +0 -6
- package/dist/task.cjs.map +0 -6
- package/dist/task.d.ts +0 -15
- package/dist/task.mjs +0 -14
- package/dist/task.mjs.map +0 -6
- package/src/run.ts +0 -159
- package/src/task.ts +0 -26
package/src/pipe.ts
CHANGED
|
@@ -1,195 +1,244 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
AbsolutePath,
|
|
3
|
+
commonPath,
|
|
4
|
+
getAbsoluteParent,
|
|
5
|
+
getCurrentWorkingDirectory,
|
|
6
|
+
resolveAbsolutePath,
|
|
7
|
+
} from './paths'
|
|
8
|
+
|
|
9
|
+
import { sep } from 'path'
|
|
10
|
+
import { assert } from './assert'
|
|
11
|
+
import { requireContext } from './async'
|
|
12
|
+
import { Files } from './files'
|
|
13
|
+
import { ForkingPlug } from './fork'
|
|
14
|
+
import { getLogger, Logger } from './log'
|
|
15
|
+
|
|
16
|
+
/* ========================================================================== *
|
|
17
|
+
* PLUGS *
|
|
18
|
+
* ========================================================================== */
|
|
19
|
+
|
|
20
|
+
/** A convenience type indicating what can be returned by a {@link Plug}. */
|
|
21
|
+
export type PlugResult = Files | undefined | void
|
|
4
22
|
|
|
5
23
|
/**
|
|
6
|
-
* The {@link Plug} interface describes
|
|
24
|
+
* The {@link Plug} interface describes _build plugin_.
|
|
25
|
+
*
|
|
26
|
+
* A {@link Plug} receives a {@link Files} instance in its input (for example
|
|
27
|
+
* a list of _source `.ts` files_) and optionally produces a possibly different
|
|
28
|
+
* list (for example the _compiled `.js` files_).
|
|
7
29
|
*/
|
|
8
|
-
export interface Plug<T extends
|
|
9
|
-
pipe(files: Files,
|
|
30
|
+
export interface Plug<T extends PlugResult> {
|
|
31
|
+
pipe(files: Files, context: Context): T | Promise<T>
|
|
10
32
|
}
|
|
11
33
|
|
|
12
|
-
/**
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
34
|
+
/** A type identifying a {@link Plug} as a `function` */
|
|
35
|
+
export type PlugFunction<T extends PlugResult> = Plug<T>['pipe']
|
|
36
|
+
|
|
37
|
+
/* ========================================================================== *
|
|
38
|
+
* PLUG CONTEXT *
|
|
39
|
+
* ========================================================================== */
|
|
16
40
|
|
|
17
41
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
42
|
+
* The {@link Context} class defines the context in which a {@link Plug}
|
|
43
|
+
* is invoked.
|
|
20
44
|
*/
|
|
21
|
-
export
|
|
22
|
-
|
|
45
|
+
export class Context {
|
|
46
|
+
/** The directory of the file where the task was defined (convenience). */
|
|
47
|
+
public readonly buildDir: AbsolutePath
|
|
48
|
+
/** The {@link Logger} associated with this instance. */
|
|
49
|
+
public readonly log: Logger
|
|
50
|
+
|
|
51
|
+
constructor(
|
|
52
|
+
/** The absolute file name where the task was defined. */
|
|
53
|
+
public readonly buildFile: AbsolutePath,
|
|
54
|
+
/** The _name_ of the task associated with this {@link Context}. */
|
|
55
|
+
public readonly taskName: string,
|
|
56
|
+
) {
|
|
57
|
+
this.buildDir = getAbsoluteParent(buildFile)
|
|
58
|
+
this.log = getLogger(taskName)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Resolve a (set of) path(s) in this {@link Context}.
|
|
63
|
+
*
|
|
64
|
+
* If the path (or first component thereof) starts with `@...`, then the
|
|
65
|
+
* resolved path will be relative to the directory containing the build file
|
|
66
|
+
* where the current task was defined, otherwise it will be relative to the
|
|
67
|
+
* current working directory.
|
|
68
|
+
*/
|
|
69
|
+
resolve(path: string, ...paths: string[]): AbsolutePath {
|
|
70
|
+
// Paths starting with "@" are relative to the build file directory
|
|
71
|
+
if (path && path.startsWith('@')) {
|
|
72
|
+
// We can have paths like "@/../foo/bar" or "@../foo/bar"... both are ok
|
|
73
|
+
const components = path.substring(1).split(sep).filter((s) => !!s)
|
|
74
|
+
return resolveAbsolutePath(this.buildDir, ...components, ...paths)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// No path? Resolve to the CWD!
|
|
78
|
+
if (! path) return getCurrentWorkingDirectory()
|
|
79
|
+
|
|
80
|
+
// For all the rest, normal resolution!
|
|
81
|
+
return resolveAbsolutePath(getCurrentWorkingDirectory(), path, ...paths)
|
|
82
|
+
}
|
|
23
83
|
}
|
|
24
84
|
|
|
85
|
+
/* ========================================================================== *
|
|
86
|
+
* PIPES *
|
|
87
|
+
* ========================================================================== */
|
|
88
|
+
|
|
25
89
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
90
|
+
* A class that will be extended by {@link Pipe} where {@link install} will
|
|
91
|
+
* add prototype properties from installed {@link Plug}s
|
|
28
92
|
*/
|
|
29
|
-
|
|
30
|
-
abstract plug(plug: Plug<
|
|
31
|
-
abstract plug(plug: Plug<undefined> | PlugFunction<undefined>): Promise<undefined>
|
|
93
|
+
abstract class PipeProto {
|
|
94
|
+
abstract plug(plug: Plug<PlugResult>): Pipe | Promise<undefined>
|
|
32
95
|
}
|
|
33
96
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
97
|
+
/**
|
|
98
|
+
* The {@link Pipe} class defines processing pipeline where multiple
|
|
99
|
+
* {@link Plug}s can transform lists of {@link Files}.
|
|
100
|
+
*/
|
|
101
|
+
export class Pipe extends PipeProto {
|
|
102
|
+
constructor(
|
|
103
|
+
private readonly _context: Context,
|
|
104
|
+
private readonly _run: () => Promise<Files>,
|
|
105
|
+
) {
|
|
41
106
|
super()
|
|
42
|
-
this.#promise = Promise.resolve(start)
|
|
43
|
-
this.#run = run
|
|
44
107
|
}
|
|
45
108
|
|
|
46
|
-
plug
|
|
109
|
+
plug(plug: Plug<Files>): Pipe
|
|
110
|
+
plug(plug: PlugFunction<Files>): Pipe
|
|
111
|
+
plug(plug: Plug<void | undefined>): Promise<undefined>
|
|
112
|
+
plug(plug: PlugFunction<void | undefined>): Promise<undefined>
|
|
113
|
+
plug(arg: Plug<PlugResult> | PlugFunction<PlugResult>): Pipe | Promise<undefined> {
|
|
47
114
|
const plug = typeof arg === 'function' ? { pipe: arg } : arg
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
115
|
+
|
|
116
|
+
const parent = this
|
|
117
|
+
const context = this._context
|
|
118
|
+
return new Pipe(context, async (): Promise<Files> => {
|
|
119
|
+
const previous = await parent.run()
|
|
120
|
+
const current = await plug.pipe(previous, context)
|
|
121
|
+
assert(current, 'Unable to extend pipe')
|
|
122
|
+
return current
|
|
51
123
|
})
|
|
52
|
-
return new PipeImpl(promise, this.#run)
|
|
53
124
|
}
|
|
54
125
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
onrejected?: ((reason: any) => T2 | PromiseLike<T2>) | null | undefined,
|
|
58
|
-
): Promise<T1 | T2> {
|
|
59
|
-
return this.#promise.then(onfulfilled, onrejected)
|
|
126
|
+
run(): Promise<Files> {
|
|
127
|
+
return this._run()
|
|
60
128
|
}
|
|
61
129
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
130
|
+
/**
|
|
131
|
+
* Merge the results of several {@link Pipe}s into a single one.
|
|
132
|
+
*
|
|
133
|
+
* Merging is performed _in parallel_. When serial execution is to be desired,
|
|
134
|
+
* we can merge the awaited _result_ of the {@link Pipe}.
|
|
135
|
+
*
|
|
136
|
+
* For example:
|
|
137
|
+
*
|
|
138
|
+
* ```
|
|
139
|
+
* const pipe: Pipe = merge([
|
|
140
|
+
* // other tasks return `Pipe & Promise<Files>` so we can
|
|
141
|
+
* // direcrly await their result without invoking `run()`
|
|
142
|
+
* await this.anotherTask1(),
|
|
143
|
+
* await this.anotherTask2(),
|
|
144
|
+
* ])
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
static merge(pipes: (Pipe | Files | Promise<Files>)[]): Pipe {
|
|
148
|
+
const context = requireContext()
|
|
149
|
+
return new Pipe(context, async (): Promise<Files> => {
|
|
150
|
+
if (pipes.length === 0) return Files.builder(getCurrentWorkingDirectory()).build()
|
|
67
151
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
return this.#promise.finally(onfinally)
|
|
72
|
-
}
|
|
152
|
+
const [ first, ...other ] = await Promise.all(pipes.map((pipe) => {
|
|
153
|
+
return 'run' in pipe ? pipe.run() : pipe
|
|
154
|
+
}))
|
|
73
155
|
|
|
74
|
-
|
|
156
|
+
const firstDir = first.directory
|
|
157
|
+
const otherDirs = other.map((f) => f.directory)
|
|
158
|
+
|
|
159
|
+
const directory = commonPath(firstDir, ...otherDirs)
|
|
160
|
+
|
|
161
|
+
return Files.builder(directory).merge(first, ...other).build()
|
|
162
|
+
})
|
|
163
|
+
}
|
|
75
164
|
}
|
|
76
165
|
|
|
77
166
|
/* ========================================================================== *
|
|
78
|
-
* PLUG INSTALLATION (
|
|
167
|
+
* PLUG INSTALLATION (NEW) *
|
|
79
168
|
* ========================================================================== */
|
|
80
169
|
|
|
81
170
|
/** The names which can be installed as direct plugs. */
|
|
82
|
-
export type PlugName = string & Exclude<keyof Pipe, 'plug' |
|
|
83
|
-
|
|
84
|
-
/** A convenience type identifying a {@link Plug} constructor. */
|
|
85
|
-
export type PlugConstructor = new (...args: any) => Plug<Files | undefined>
|
|
86
|
-
|
|
87
|
-
/** Convert the resulting type of a {@link Plug} for use in a {@link Pipe} */
|
|
88
|
-
type PlugReturnForPipe<T> =
|
|
89
|
-
T extends Plug<infer R> ?
|
|
90
|
-
R extends Files ?
|
|
91
|
-
Promise<Files> & Pipe :
|
|
92
|
-
R extends undefined ?
|
|
93
|
-
Promise<undefined> :
|
|
94
|
-
never :
|
|
95
|
-
never
|
|
171
|
+
export type PlugName = string & Exclude<keyof Pipe, 'plug' | 'run'>
|
|
96
172
|
|
|
97
|
-
/**
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
T extends {
|
|
151
|
-
new (...args: infer A0): infer R0
|
|
152
|
-
new (...args: infer A1): infer R1
|
|
153
|
-
} ? [
|
|
154
|
-
R0 extends Plug<Files | undefined> ? (...args: A0) => PlugReturnForPipe<R0> : Function,
|
|
155
|
-
R1 extends Plug<Files | undefined> ? (...args: A1) => PlugReturnForPipe<R1> : Function,
|
|
156
|
-
] :
|
|
157
|
-
T extends {
|
|
158
|
-
new (...args: infer A0): infer R0
|
|
159
|
-
} ? [
|
|
160
|
-
R0 extends Plug<Files | undefined> ? (...args: A0) => PlugReturnForPipe<R0> : Function,
|
|
161
|
-
] :
|
|
162
|
-
never
|
|
173
|
+
/** The parameters of the plug extension with the given name */
|
|
174
|
+
export type PipeParameters<Name extends PlugName> = PipeOverloads<Name>['args']
|
|
175
|
+
|
|
176
|
+
/** Extract arguments and return types from function overloads. */
|
|
177
|
+
type PipeOverloads<Name extends PlugName> =
|
|
178
|
+
Pipe[Name] extends {
|
|
179
|
+
(...args: infer A0): infer R0
|
|
180
|
+
(...args: infer A1): infer R1
|
|
181
|
+
(...args: infer A2): infer R2
|
|
182
|
+
(...args: infer A3): infer R3
|
|
183
|
+
(...args: infer A4): infer R4
|
|
184
|
+
} ?
|
|
185
|
+
| (R0 extends (Pipe | Promise<undefined>) ? { args: A0, ret: R0 } : never)
|
|
186
|
+
| (R1 extends (Pipe | Promise<undefined>) ? { args: A1, ret: R1 } : never)
|
|
187
|
+
| (R2 extends (Pipe | Promise<undefined>) ? { args: A2, ret: R2 } : never)
|
|
188
|
+
| (R3 extends (Pipe | Promise<undefined>) ? { args: A3, ret: R3 } : never)
|
|
189
|
+
| (R4 extends (Pipe | Promise<undefined>) ? { args: A4, ret: R4 } : never)
|
|
190
|
+
:
|
|
191
|
+
Pipe[Name] extends {
|
|
192
|
+
(...args: infer A0): infer R0
|
|
193
|
+
(...args: infer A1): infer R1
|
|
194
|
+
(...args: infer A2): infer R2
|
|
195
|
+
(...args: infer A3): infer R3
|
|
196
|
+
} ?
|
|
197
|
+
| (R0 extends (Pipe | Promise<undefined>) ? { args: A0, ret: R0 } : never)
|
|
198
|
+
| (R1 extends (Pipe | Promise<undefined>) ? { args: A1, ret: R1 } : never)
|
|
199
|
+
| (R2 extends (Pipe | Promise<undefined>) ? { args: A2, ret: R2 } : never)
|
|
200
|
+
| (R3 extends (Pipe | Promise<undefined>) ? { args: A3, ret: R3 } : never)
|
|
201
|
+
:
|
|
202
|
+
Pipe[Name] extends {
|
|
203
|
+
(...args: infer A0): infer R0
|
|
204
|
+
(...args: infer A1): infer R1
|
|
205
|
+
(...args: infer A2): infer R2
|
|
206
|
+
} ?
|
|
207
|
+
| (R0 extends (Pipe | Promise<undefined>) ? { args: A0, ret: R0 } : never)
|
|
208
|
+
| (R1 extends (Pipe | Promise<undefined>) ? { args: A1, ret: R1 } : never)
|
|
209
|
+
| (R2 extends (Pipe | Promise<undefined>) ? { args: A2, ret: R2 } : never)
|
|
210
|
+
:
|
|
211
|
+
Pipe[Name] extends {
|
|
212
|
+
(...args: infer A0): infer R0
|
|
213
|
+
(...args: infer A1): infer R1
|
|
214
|
+
} ?
|
|
215
|
+
| (R0 extends (Pipe | Promise<undefined>) ? { args: A0, ret: R0 } : never)
|
|
216
|
+
| (R1 extends (Pipe | Promise<undefined>) ? { args: A1, ret: R1 } : never)
|
|
217
|
+
:
|
|
218
|
+
Pipe[Name] extends {
|
|
219
|
+
(...args: infer A0): infer R0
|
|
220
|
+
} ?
|
|
221
|
+
| (R0 extends (Pipe | Promise<undefined>) ? { args: A0, ret: R0 } : never)
|
|
222
|
+
: never
|
|
223
|
+
|
|
224
|
+
/** The parameters of the plug extension with the given name */
|
|
225
|
+
type PipeResult<Name extends PlugName> = PipeOverloads<Name>['ret']
|
|
163
226
|
|
|
164
227
|
/**
|
|
165
|
-
* A
|
|
166
|
-
*
|
|
167
|
-
* See also {@link install}.
|
|
168
|
-
*
|
|
169
|
-
* ```
|
|
170
|
-
* export class Write implements Plug {
|
|
171
|
-
* // ... the plug implementation lives here
|
|
172
|
-
* }
|
|
173
|
-
*
|
|
174
|
-
* install('write', Write)
|
|
175
|
-
*
|
|
176
|
-
* declare module '../pipe' {
|
|
177
|
-
* export interface Pipe {
|
|
178
|
-
* write: PipeExtension<typeof Write>
|
|
179
|
-
* }
|
|
180
|
-
* }
|
|
181
|
-
* ```
|
|
228
|
+
* A type defining the correct constructor for a {@link Plug}, inferring
|
|
229
|
+
* argument types and instance type from the definitions in {@link Pipe}.
|
|
182
230
|
*/
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
231
|
+
type PlugConstructor<Name extends PlugName> =
|
|
232
|
+
PipeResult<Name> extends Pipe ?
|
|
233
|
+
new (...args: PipeParameters<Name>) => Plug<Files> :
|
|
234
|
+
PipeResult<Name> extends Promise<undefined> ?
|
|
235
|
+
new (...args: PipeParameters<Name>) => Plug<void | undefined> :
|
|
236
|
+
PipeResult<Name> extends (Pipe | Promise<undefined>) ?
|
|
237
|
+
new (...args: PipeParameters<Name>) => Plug<Files | void | undefined> :
|
|
238
|
+
never
|
|
189
239
|
|
|
190
240
|
/**
|
|
191
|
-
* Install a {@link Plug} into our {@link Pipe} prototype
|
|
192
|
-
* creator function for the {@link Plug} itself.
|
|
241
|
+
* Install a {@link Plug} into our {@link Pipe} prototype.
|
|
193
242
|
*
|
|
194
243
|
* This allows our shorthand syntax for well-defined plugs such as:
|
|
195
244
|
*
|
|
@@ -202,30 +251,66 @@ export type PipeExtension<T extends PlugConstructor, A = PlugConstructorOverload
|
|
|
202
251
|
* Use this alongside interface merging like:
|
|
203
252
|
*
|
|
204
253
|
* ```
|
|
205
|
-
*
|
|
206
|
-
* // ... the plug implementation lives here
|
|
207
|
-
* }
|
|
208
|
-
*
|
|
209
|
-
* install('write', Write)
|
|
210
|
-
*
|
|
211
|
-
* declare module '../pipe' {
|
|
254
|
+
* declare module '@plugjs/plug/pipe' {
|
|
212
255
|
* export interface Pipe {
|
|
213
|
-
* write:
|
|
256
|
+
* write(): Pipe
|
|
214
257
|
* }
|
|
215
258
|
* }
|
|
259
|
+
*
|
|
260
|
+
* install('write', class Write implements Plug {
|
|
261
|
+
* constructorg(...args: PipeParams<'write'>) {
|
|
262
|
+
* // here `args` is automatically inferred by whatever was declared above
|
|
263
|
+
* }
|
|
264
|
+
*
|
|
265
|
+
* // ... the plug implementation lives here
|
|
266
|
+
* })
|
|
216
267
|
* ```
|
|
217
268
|
*/
|
|
218
|
-
export function install<
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
269
|
+
export function install<
|
|
270
|
+
Name extends PlugName,
|
|
271
|
+
Ctor extends PlugConstructor<Name>,
|
|
272
|
+
>(name: Name, ctor: Ctor): void {
|
|
273
|
+
/* The function plugging the newly constructed plug in a pipe */
|
|
274
|
+
function plug(this: PipeProto, ...args: PipeParameters<Name>): Pipe | Promise<undefined> {
|
|
222
275
|
// eslint-disable-next-line new-cap
|
|
223
|
-
return this.plug(new ctor(...args)
|
|
276
|
+
return this.plug(new ctor(...args))
|
|
224
277
|
}
|
|
225
278
|
|
|
226
279
|
/* Setup name so that stack traces look better */
|
|
227
|
-
Object.defineProperty(
|
|
280
|
+
Object.defineProperty(plug, 'name', { value: name })
|
|
228
281
|
|
|
229
282
|
/* Inject the create function in the Pipe's prototype */
|
|
230
|
-
Object.defineProperty(
|
|
283
|
+
Object.defineProperty(PipeProto.prototype, name, { value: plug })
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Install a _forking_ {@link Plug} in the {@link Pipe}, in other words
|
|
288
|
+
* execute the plug in a separate process.
|
|
289
|
+
*
|
|
290
|
+
* As a contract, if the _last non-null_ parameter of the constructor is an
|
|
291
|
+
* object and contains the key `coverageDir`, the process will be forked with
|
|
292
|
+
* the approptiately resolved `NODE_V8_COVERAGE` environment variable.
|
|
293
|
+
*
|
|
294
|
+
* Also, forking plugs require some special attention:
|
|
295
|
+
*
|
|
296
|
+
* * plug functions are not supported, only classes implementing the
|
|
297
|
+
* {@link Plug} interface can be used with this.
|
|
298
|
+
*
|
|
299
|
+
* * the class itself _MUST_ be exported as the _default_ export for the
|
|
300
|
+
* `scriptFile` specified below. This is to simplify interoperability between
|
|
301
|
+
* CommonJS and ESM modules as we use dynamic `import(...)` statements.
|
|
302
|
+
*/
|
|
303
|
+
export function installForking<Name extends PlugName>(
|
|
304
|
+
plugName: Name,
|
|
305
|
+
scriptFile: AbsolutePath,
|
|
306
|
+
): void {
|
|
307
|
+
/** Extend out our ForkingPlug below */
|
|
308
|
+
const ctor = class extends ForkingPlug {
|
|
309
|
+
constructor(...args: any[]) {
|
|
310
|
+
super(scriptFile, args)
|
|
311
|
+
}
|
|
312
|
+
} as unknown as PlugConstructor<Name>
|
|
313
|
+
|
|
314
|
+
/** Install the plug in */
|
|
315
|
+
install(plugName, ctor)
|
|
231
316
|
}
|
package/src/plugs/copy.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import { assert } from '../assert
|
|
2
|
-
import { Files } from '../files
|
|
3
|
-
import { $p } from '../log
|
|
4
|
-
import { assertAbsolutePath, getAbsoluteParent, resolveAbsolutePath } from '../paths
|
|
5
|
-
import { install, Plug } from '../pipe
|
|
6
|
-
import {
|
|
7
|
-
import { chmod, copyFile, fsConstants, mkdir } from '../utils/asyncfs.js'
|
|
1
|
+
import { assert } from '../assert'
|
|
2
|
+
import { Files } from '../files'
|
|
3
|
+
import { $p } from '../log'
|
|
4
|
+
import { assertAbsolutePath, getAbsoluteParent, resolveAbsolutePath } from '../paths'
|
|
5
|
+
import { install, PipeParameters, Plug, Context } from '../pipe'
|
|
6
|
+
import { chmod, copyFile, fsConstants, mkdir } from '../utils/asyncfs'
|
|
8
7
|
|
|
9
8
|
/** Options for copying files */
|
|
10
9
|
export interface CopyOptions {
|
|
@@ -18,15 +17,37 @@ export interface CopyOptions {
|
|
|
18
17
|
rename?: (relative: string) => string
|
|
19
18
|
}
|
|
20
19
|
|
|
20
|
+
declare module '../pipe' {
|
|
21
|
+
export interface Pipe {
|
|
22
|
+
/**
|
|
23
|
+
* Copy the curent {@link Files} to a different directory
|
|
24
|
+
*
|
|
25
|
+
* @param directory The target directory where files will be copied to
|
|
26
|
+
*/
|
|
27
|
+
copy(directory: string): Pipe
|
|
28
|
+
/**
|
|
29
|
+
* Copy the curent {@link Files} to a different directory
|
|
30
|
+
*
|
|
31
|
+
* @param directory The target directory where files will be copied to
|
|
32
|
+
* @param options Extra {@link CopyOptions | options} for the copy operation
|
|
33
|
+
*/
|
|
34
|
+
copy(directory: string, options: CopyOptions): Pipe
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/* ========================================================================== *
|
|
39
|
+
* INSTALLATION / IMPLEMENTATION *
|
|
40
|
+
* ========================================================================== */
|
|
41
|
+
|
|
21
42
|
/** Copy the curent {@link Files} to a different directory */
|
|
22
|
-
|
|
23
|
-
constructor(
|
|
43
|
+
install('copy', class Copy implements Plug<Files> {
|
|
44
|
+
constructor(...args: PipeParameters<'copy'>)
|
|
24
45
|
constructor(
|
|
25
46
|
private readonly _directory: string,
|
|
26
47
|
private readonly _options: CopyOptions = {},
|
|
27
48
|
) {}
|
|
28
49
|
|
|
29
|
-
async pipe(files: Files,
|
|
50
|
+
async pipe(files: Files, context: Context): Promise<Files> {
|
|
30
51
|
/* Destructure our options with some defaults and compute write flags */
|
|
31
52
|
const { mode, dirMode, overwrite, rename = (s): string => s } = this._options
|
|
32
53
|
const flags = overwrite ? fsConstants.COPYFILE_EXCL : 0
|
|
@@ -34,7 +55,8 @@ export class Copy implements Plug<Files> {
|
|
|
34
55
|
const fmode = parseMode(mode)
|
|
35
56
|
|
|
36
57
|
/* Our files builder for all written files */
|
|
37
|
-
const
|
|
58
|
+
const directory = context.resolve(this._directory)
|
|
59
|
+
const builder = Files.builder(directory)
|
|
38
60
|
|
|
39
61
|
/* Iterate through all the mappings of the source files */
|
|
40
62
|
for (const [ relative, absolute ] of files.pathMappings()) {
|
|
@@ -44,7 +66,7 @@ export class Copy implements Plug<Files> {
|
|
|
44
66
|
|
|
45
67
|
/* We never copy a file onto itself, but not fail either */
|
|
46
68
|
if (target === absolute) {
|
|
47
|
-
|
|
69
|
+
context.log.warn('Cowardly refusing to copy same file', $p(absolute))
|
|
48
70
|
continue
|
|
49
71
|
}
|
|
50
72
|
|
|
@@ -56,44 +78,31 @@ export class Copy implements Plug<Files> {
|
|
|
56
78
|
if (firstParent && (dmode !== undefined)) {
|
|
57
79
|
assertAbsolutePath(firstParent)
|
|
58
80
|
for (let dir = directory; ; dir = getAbsoluteParent(dir)) {
|
|
59
|
-
|
|
81
|
+
context.log.trace(`Setting mode ${stringifyMode(dmode)} for directory`, $p(dir))
|
|
60
82
|
await chmod(dir, dmode)
|
|
61
83
|
if (dir === firstParent) break
|
|
62
84
|
}
|
|
63
85
|
}
|
|
64
86
|
|
|
65
87
|
/* Actually _copy_ the file */
|
|
66
|
-
|
|
88
|
+
context.log.trace(`Copying "${$p(absolute)}" to "${$p(target)}"`)
|
|
67
89
|
await copyFile(absolute, target, flags)
|
|
68
90
|
|
|
69
91
|
/* Set the mode, if we need to */
|
|
70
92
|
if (fmode !== undefined) {
|
|
71
|
-
|
|
93
|
+
context.log.trace(`Setting mode ${stringifyMode(fmode)} for file`, $p(target))
|
|
72
94
|
await chmod(target, fmode)
|
|
73
95
|
}
|
|
74
96
|
|
|
75
97
|
/* Record this file */
|
|
76
|
-
builder.
|
|
98
|
+
builder.add(target)
|
|
77
99
|
}
|
|
78
100
|
|
|
79
101
|
const result = builder.build()
|
|
80
|
-
|
|
102
|
+
context.log.info('Copied', result.length, 'files to', $p(builder.directory))
|
|
81
103
|
return result
|
|
82
104
|
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/* ========================================================================== *
|
|
86
|
-
* INSTALLATION *
|
|
87
|
-
* ========================================================================== */
|
|
88
|
-
|
|
89
|
-
install('copy', Copy)
|
|
90
|
-
|
|
91
|
-
declare module '../pipe.js' {
|
|
92
|
-
export interface Pipe {
|
|
93
|
-
/** Copy the curent {@link Files} to a different directory */
|
|
94
|
-
copy: PipeExtension<typeof Copy>
|
|
95
|
-
}
|
|
96
|
-
}
|
|
105
|
+
})
|
|
97
106
|
|
|
98
107
|
/* ========================================================================== *
|
|
99
108
|
* INTERNALS *
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { fileURLToPath, pathToFileURL } from 'node:url'
|
|
2
2
|
import { RawSourceMap, SourceMapConsumer } from 'source-map'
|
|
3
|
-
import { assert } from '../../assert
|
|
4
|
-
import { $gry, $p, Logger } from '../../log
|
|
5
|
-
import { AbsolutePath } from '../../paths
|
|
6
|
-
import { readFile } from '../../utils/asyncfs
|
|
3
|
+
import { assert } from '../../assert'
|
|
4
|
+
import { $gry, $p, Logger } from '../../log'
|
|
5
|
+
import { AbsolutePath } from '../../paths'
|
|
6
|
+
import { readFile } from '../../utils/asyncfs'
|
|
7
7
|
|
|
8
8
|
/* ========================================================================== *
|
|
9
9
|
* V8 COVERAGE TYPES *
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
|
|
2
|
-
import { parse } from '@babel/parser'
|
|
3
2
|
import {
|
|
4
3
|
Comment, isDeclaration,
|
|
5
4
|
isExportDeclaration,
|
|
@@ -13,11 +12,13 @@ import {
|
|
|
13
12
|
Node,
|
|
14
13
|
VISITOR_KEYS
|
|
15
14
|
} from '@babel/types'
|
|
15
|
+
|
|
16
|
+
import { parse } from '@babel/parser'
|
|
16
17
|
import { pathToFileURL } from 'node:url'
|
|
17
|
-
import { $p, Logger } from '../../log
|
|
18
|
-
import { AbsolutePath } from '../../paths
|
|
19
|
-
import { readFile } from '../../utils/asyncfs
|
|
20
|
-
import { CoverageAnalyser } from './analysis
|
|
18
|
+
import { $p, Logger } from '../../log'
|
|
19
|
+
import { AbsolutePath } from '../../paths'
|
|
20
|
+
import { readFile } from '../../utils/asyncfs'
|
|
21
|
+
import { CoverageAnalyser } from './analysis'
|
|
21
22
|
|
|
22
23
|
/* ========================================================================== *
|
|
23
24
|
* EXPORTED CONSTANTS AND TYPES *
|