@tsed/cli-tasks 7.0.0-beta.13
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/lib/esm/domain/TaskLogger.js +270 -0
- package/lib/esm/fn/taskLogger.js +4 -0
- package/lib/esm/index.js +4 -0
- package/lib/esm/interfaces/Task.js +1 -0
- package/lib/esm/tasks.js +101 -0
- package/lib/tsconfig.esm.tsbuildinfo +1 -0
- package/lib/types/domain/TaskLogger.d.ts +37 -0
- package/lib/types/fn/taskLogger.d.ts +2 -0
- package/lib/types/index.d.ts +4 -0
- package/lib/types/interfaces/Task.d.ts +12 -0
- package/lib/types/tasks.d.ts +12 -0
- package/package.json +53 -0
- package/src/domain/TaskLogger.spec.ts +324 -0
- package/src/domain/TaskLogger.ts +319 -0
- package/src/fn/taskLogger.ts +5 -0
- package/src/index.ts +4 -0
- package/src/interfaces/Task.ts +15 -0
- package/src/tasks.spec.ts +193 -0
- package/src/tasks.ts +131 -0
- package/test.js +68 -0
- package/tsconfig.esm.json +27 -0
- package/vitest.config.mts +20 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import { log, progress, spinner, taskLog } from "@clack/prompts";
|
|
2
|
+
import { contextLogger } from "@tsed/di";
|
|
3
|
+
export class TaskLogger {
|
|
4
|
+
#title;
|
|
5
|
+
#logger;
|
|
6
|
+
#verbose;
|
|
7
|
+
#parent;
|
|
8
|
+
#index;
|
|
9
|
+
constructor(opts) {
|
|
10
|
+
this.#title = opts.title;
|
|
11
|
+
this.type = opts.type;
|
|
12
|
+
this.#parent = opts.parent;
|
|
13
|
+
this.#verbose = opts.verbose;
|
|
14
|
+
this.#logger = this.create({
|
|
15
|
+
...opts,
|
|
16
|
+
verbose: this.#verbose
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
get parent() {
|
|
20
|
+
return this.#parent;
|
|
21
|
+
}
|
|
22
|
+
get isReady() {
|
|
23
|
+
return !!this.#logger;
|
|
24
|
+
}
|
|
25
|
+
get title() {
|
|
26
|
+
return this.#title;
|
|
27
|
+
}
|
|
28
|
+
set title(title) {
|
|
29
|
+
if (title) {
|
|
30
|
+
this.#title = title;
|
|
31
|
+
this.#logger.message?.(title);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
set output(message) {
|
|
35
|
+
if (message) {
|
|
36
|
+
(this.#logger.info || this.#logger.message)?.(message);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
static from(opts) {
|
|
40
|
+
if (opts.parent) {
|
|
41
|
+
switch (opts.parent.type) {
|
|
42
|
+
case "progress":
|
|
43
|
+
return new TaskLogger({
|
|
44
|
+
...opts,
|
|
45
|
+
type: "progress",
|
|
46
|
+
parent: opts.parent
|
|
47
|
+
});
|
|
48
|
+
case "spinner":
|
|
49
|
+
return opts.parent;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (opts.parent) {
|
|
53
|
+
if (opts.parent?.parent) {
|
|
54
|
+
opts.type = opts.type || "group";
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
opts.type = opts.type || "taskLog";
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
opts.type = opts.type || "log";
|
|
61
|
+
return new TaskLogger(opts);
|
|
62
|
+
}
|
|
63
|
+
log(message) {
|
|
64
|
+
this.#logger.message(`${this.title} - ${message}`);
|
|
65
|
+
}
|
|
66
|
+
message(message) {
|
|
67
|
+
this.#logger.message(`${this.title} - ${message}`);
|
|
68
|
+
}
|
|
69
|
+
advance() {
|
|
70
|
+
if (this.isReady && this.type === "progress") {
|
|
71
|
+
if (this.isRaw()) {
|
|
72
|
+
this.info(`${this.title} [${this.#index}/${this.parent.max}]`);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
const it = Math.round((1 / this.parent.max) * 100);
|
|
76
|
+
this.#logger.advance(it, this.title);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return this;
|
|
80
|
+
}
|
|
81
|
+
start() {
|
|
82
|
+
if (this.isReady) {
|
|
83
|
+
const msg = `${this.title}...`;
|
|
84
|
+
switch (this.type) {
|
|
85
|
+
default:
|
|
86
|
+
this.#logger.message(msg);
|
|
87
|
+
break;
|
|
88
|
+
case "log":
|
|
89
|
+
this.#logger.info(msg);
|
|
90
|
+
break;
|
|
91
|
+
case "progress":
|
|
92
|
+
if (this.isChildProgress()) {
|
|
93
|
+
this.advance();
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
this.#logger.start(this.title);
|
|
97
|
+
}
|
|
98
|
+
break;
|
|
99
|
+
case "spinner":
|
|
100
|
+
this.#logger.start(this.title);
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return this;
|
|
105
|
+
}
|
|
106
|
+
done() {
|
|
107
|
+
if (this.isReady) {
|
|
108
|
+
const msg = `${this.title} completed`;
|
|
109
|
+
switch (this.type) {
|
|
110
|
+
default:
|
|
111
|
+
this.#logger.success(msg);
|
|
112
|
+
break;
|
|
113
|
+
case "progress":
|
|
114
|
+
if (!this.isChildProgress()) {
|
|
115
|
+
this.#logger.stop(msg);
|
|
116
|
+
}
|
|
117
|
+
break;
|
|
118
|
+
case "spinner":
|
|
119
|
+
this.#logger.stop(msg);
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return this;
|
|
124
|
+
}
|
|
125
|
+
error(message) {
|
|
126
|
+
if (this.isReady) {
|
|
127
|
+
this.#logger.error(`${this.title} - ${message}`);
|
|
128
|
+
}
|
|
129
|
+
return this;
|
|
130
|
+
}
|
|
131
|
+
info(message) {
|
|
132
|
+
if (this.isReady) {
|
|
133
|
+
switch (this.type) {
|
|
134
|
+
case "log":
|
|
135
|
+
case "taskLog":
|
|
136
|
+
this.#logger.info(`${this.title} - ${message}`);
|
|
137
|
+
break;
|
|
138
|
+
default:
|
|
139
|
+
this.#logger.message(`${this.title} - ${message}`);
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return this;
|
|
144
|
+
}
|
|
145
|
+
warn(message) {
|
|
146
|
+
if (this.isReady) {
|
|
147
|
+
switch (this.type) {
|
|
148
|
+
case "log":
|
|
149
|
+
case "taskLog":
|
|
150
|
+
this.#logger.warn(`${this.title} - ${message}`);
|
|
151
|
+
break;
|
|
152
|
+
default:
|
|
153
|
+
this.#logger.message(`${this.title} - WARN ${message}`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return this;
|
|
157
|
+
}
|
|
158
|
+
skip() {
|
|
159
|
+
if (this.isReady) {
|
|
160
|
+
switch (this.type) {
|
|
161
|
+
default:
|
|
162
|
+
case "log":
|
|
163
|
+
this.#logger.warn(`${this.title} skipped...`);
|
|
164
|
+
break;
|
|
165
|
+
case "group":
|
|
166
|
+
case "taskLog":
|
|
167
|
+
this.#logger.error(`${this.title} skipped...`);
|
|
168
|
+
break;
|
|
169
|
+
case "progress":
|
|
170
|
+
this.advance();
|
|
171
|
+
break;
|
|
172
|
+
case "spinner":
|
|
173
|
+
this.#logger.stop(`${this.title} skipped...`);
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return this;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* @ddeprecated use info or message instead
|
|
181
|
+
* @param message
|
|
182
|
+
*/
|
|
183
|
+
report(message) {
|
|
184
|
+
(this.#logger.info || this.#logger.message)?.(message);
|
|
185
|
+
}
|
|
186
|
+
isChildProgress() {
|
|
187
|
+
return this.parent?.type === "progress" && this.type === "progress";
|
|
188
|
+
}
|
|
189
|
+
create(opts) {
|
|
190
|
+
const { type, title, parent } = opts;
|
|
191
|
+
if (this.isRaw()) {
|
|
192
|
+
const success = (message) => {
|
|
193
|
+
!this.isEnvTest() &&
|
|
194
|
+
contextLogger()?.info({
|
|
195
|
+
state: "SUCCESS",
|
|
196
|
+
title,
|
|
197
|
+
message
|
|
198
|
+
});
|
|
199
|
+
};
|
|
200
|
+
const start = (message) => {
|
|
201
|
+
!this.isEnvTest() &&
|
|
202
|
+
contextLogger()?.info({
|
|
203
|
+
title,
|
|
204
|
+
message
|
|
205
|
+
});
|
|
206
|
+
};
|
|
207
|
+
const defaultLogger = {
|
|
208
|
+
message: (message) => {
|
|
209
|
+
!this.isEnvTest() &&
|
|
210
|
+
contextLogger()?.info({
|
|
211
|
+
state: "MSG",
|
|
212
|
+
title,
|
|
213
|
+
message
|
|
214
|
+
});
|
|
215
|
+
},
|
|
216
|
+
stop: success,
|
|
217
|
+
success,
|
|
218
|
+
info: start,
|
|
219
|
+
start,
|
|
220
|
+
warn: (message) => {
|
|
221
|
+
!this.isEnvTest() &&
|
|
222
|
+
contextLogger()?.warn({
|
|
223
|
+
title,
|
|
224
|
+
message
|
|
225
|
+
});
|
|
226
|
+
},
|
|
227
|
+
error: (message) => {
|
|
228
|
+
!this.isEnvTest() &&
|
|
229
|
+
contextLogger()?.error({
|
|
230
|
+
title,
|
|
231
|
+
message
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
defaultLogger.message("...");
|
|
236
|
+
return defaultLogger;
|
|
237
|
+
}
|
|
238
|
+
switch (type) {
|
|
239
|
+
case "spinner":
|
|
240
|
+
const spin = spinner();
|
|
241
|
+
spin.message(title);
|
|
242
|
+
return spin;
|
|
243
|
+
case "progress":
|
|
244
|
+
if (parent && this.isChildProgress()) {
|
|
245
|
+
return parent.#logger;
|
|
246
|
+
}
|
|
247
|
+
return progress({
|
|
248
|
+
style: "block",
|
|
249
|
+
max: 100
|
|
250
|
+
});
|
|
251
|
+
case "taskLog":
|
|
252
|
+
return taskLog({
|
|
253
|
+
title: this.title
|
|
254
|
+
});
|
|
255
|
+
case "log":
|
|
256
|
+
return log;
|
|
257
|
+
case "group":
|
|
258
|
+
if (!parent || parent.type !== "taskLog") {
|
|
259
|
+
return log;
|
|
260
|
+
}
|
|
261
|
+
return parent.#logger.group(this.title);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
isRaw() {
|
|
265
|
+
return this.#verbose || this.isEnvTest();
|
|
266
|
+
}
|
|
267
|
+
isEnvTest() {
|
|
268
|
+
return process.env.NODE_ENV === "test";
|
|
269
|
+
}
|
|
270
|
+
}
|
package/lib/esm/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { TaskLogger } from "../domain/TaskLogger.js";
|
package/lib/esm/tasks.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { isArray } from "@tsed/core/utils/isArray";
|
|
2
|
+
import { isBoolean } from "@tsed/core/utils/isBoolean";
|
|
3
|
+
import { isFunction } from "@tsed/core/utils/isFunction";
|
|
4
|
+
import { isObservable } from "@tsed/core/utils/isObservable";
|
|
5
|
+
import { isPromise } from "@tsed/core/utils/isPromise";
|
|
6
|
+
import { isString } from "@tsed/core/utils/isString";
|
|
7
|
+
import { context } from "@tsed/di";
|
|
8
|
+
import { TaskLogger } from "./domain/TaskLogger.js";
|
|
9
|
+
export async function tasks(list, ctx, parent) {
|
|
10
|
+
const items = list.filter((task) => isEnabled(task));
|
|
11
|
+
parent && (parent.max = items.length);
|
|
12
|
+
for (let i = 0; i < items.length; i++) {
|
|
13
|
+
const task = items[i];
|
|
14
|
+
const taskLogger = TaskLogger.from({
|
|
15
|
+
index: i,
|
|
16
|
+
title: task.title,
|
|
17
|
+
type: task.type,
|
|
18
|
+
parent,
|
|
19
|
+
verbose: ctx.verbose
|
|
20
|
+
});
|
|
21
|
+
try {
|
|
22
|
+
if (!(await isExecutable(task, ctx))) {
|
|
23
|
+
taskLogger.skip();
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
taskLogger.start();
|
|
27
|
+
context().set("TASK_LOGGER", taskLogger);
|
|
28
|
+
const result = await resolveTaskResult(task.task(ctx, taskLogger), taskLogger);
|
|
29
|
+
context().delete("TASK_LOGGER");
|
|
30
|
+
if (isArray(result)) {
|
|
31
|
+
await tasks(result, ctx, taskLogger);
|
|
32
|
+
}
|
|
33
|
+
taskLogger.done();
|
|
34
|
+
}
|
|
35
|
+
catch (er) {
|
|
36
|
+
taskLogger.error(er);
|
|
37
|
+
throw er;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function resolveTaskResult(result, logger) {
|
|
42
|
+
if (!result) {
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
if (isPromise(result)) {
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
if (isObservable(result)) {
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
let subscription;
|
|
51
|
+
subscription = result.subscribe({
|
|
52
|
+
next(value) {
|
|
53
|
+
if (isString(value)) {
|
|
54
|
+
logger.message(value);
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
complete() {
|
|
58
|
+
subscription?.unsubscribe?.();
|
|
59
|
+
resolve(undefined);
|
|
60
|
+
},
|
|
61
|
+
error(err) {
|
|
62
|
+
subscription?.unsubscribe?.();
|
|
63
|
+
reject(err);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
export async function concat(...args) {
|
|
71
|
+
const tasks = [];
|
|
72
|
+
for (const arg of args) {
|
|
73
|
+
if (isArray(arg)) {
|
|
74
|
+
tasks.push(...arg);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return tasks;
|
|
78
|
+
}
|
|
79
|
+
function isEnabled(item) {
|
|
80
|
+
return isBoolean(item.enabled) ? item.enabled : true;
|
|
81
|
+
}
|
|
82
|
+
async function isExecutable(item, ctx) {
|
|
83
|
+
if (isFunction(item.enabled)) {
|
|
84
|
+
const isEnable = await item.enabled(ctx);
|
|
85
|
+
if (!isEnable) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if ("skip" in item) {
|
|
90
|
+
const isSkipped = isFunction(item.skip) ? await item.skip(ctx) : item.skip;
|
|
91
|
+
if (isSkipped) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* @deprecated use tasks function instead
|
|
99
|
+
*/
|
|
100
|
+
export const createTasksRunner = tasks;
|
|
101
|
+
export const createSubTasks = tasks;
|