@zokugun/artifact 0.7.0 → 0.8.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 CHANGED
@@ -68,6 +68,26 @@ Artifacts published to npm must be prefixed with `artifact-`.
68
68
  Command Reference
69
69
  -----------------
70
70
 
71
+ ### Usage
72
+
73
+ ```
74
+ Usage: artifact [options] [command]
75
+
76
+ Boilerplate your project & keep your configurations up to date
77
+
78
+ Options:
79
+ -v, --version output the version number
80
+ -h, --help display help for command
81
+
82
+ Commands:
83
+ add [options] <artifacts...> add an artifact to the current project
84
+ list|ls list the installed artifacts in the project
85
+ outdated|od check for outdated artifacts
86
+ remove|rm [options] [artifacts...] remove an artifact from the current project
87
+ update|up [options] update the current project using the installed artifacts
88
+ help [command] display help for command
89
+ ```
90
+
71
91
  ### `artifact add`
72
92
 
73
93
  Registers and applies one or more artifacts in the current project.
@@ -78,12 +98,12 @@ Registers and applies one or more artifacts in the current project.
78
98
 
79
99
  `<artifact>` can be `name` or `name:variant`.
80
100
 
81
- ### `artifact list` / `artifact l`
101
+ ### `artifact list` / `artifact ls`
82
102
 
83
103
  Shows the artifacts currently tracked in `.artifactrc*`, including versions and, when available, requested variants.
84
104
 
85
105
  - Syntax: `artifact list`
86
- - Alias: `artifact l`
106
+ - Alias: `artifact ls`
87
107
  - Output: prints each artifact as `name@version:variant`.
88
108
 
89
109
  ### `artifact update` / `artifact up`
package/lib/cli.js CHANGED
@@ -28,23 +28,28 @@ program
28
28
  .argument('<artifacts...>')
29
29
  .action(index_js_1.add);
30
30
  program
31
- .command('update')
32
- .description('update the current project using the installed artifacts')
33
- .option('-d, --dry-run', 'fake update')
34
- .option('--verbose', 'output more details')
35
- .alias('up')
36
- .action(index_js_1.update);
31
+ .command('list')
32
+ .description('list the installed artifacts in the project')
33
+ .alias('ls')
34
+ .action(index_js_1.list);
35
+ program
36
+ .command('outdated')
37
+ .description('check for outdated artifacts')
38
+ .alias('od')
39
+ .action(index_js_1.outdated);
37
40
  program
38
41
  .command('remove')
39
42
  .description('remove an artifact from the current project')
40
43
  .option('-d, --dry-run', 'fake uninstall')
41
44
  .option('--verbose', 'output more details')
42
- .argument('<artifacts...>')
45
+ .argument('[artifacts...]')
43
46
  .alias('rm')
44
47
  .action(index_js_1.remove);
45
48
  program
46
- .command('list')
47
- .description('list the installed artifacts in the project')
48
- .alias('l')
49
- .action(index_js_1.list);
49
+ .command('update')
50
+ .description('update the current project using the installed artifacts')
51
+ .option('-d, --dry-run', 'fake update')
52
+ .option('--verbose', 'output more details')
53
+ .alias('up')
54
+ .action(index_js_1.update);
50
55
  program.parse();
@@ -4,11 +4,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.add = add;
7
- const process_1 = __importDefault(require("process"));
7
+ const node_process_1 = __importDefault(require("node:process"));
8
8
  const cli_utils_1 = require("@zokugun/cli-utils");
9
+ const async_1 = require("@zokugun/xtry/async");
9
10
  const pacote_1 = __importDefault(require("pacote"));
10
11
  const tempy_1 = __importDefault(require("tempy"));
11
12
  const index_js_1 = require("../configs/index.js");
13
+ const read_listing_config_js_1 = require("../configs/package/read-listing-config.js");
12
14
  const index_js_2 = require("../steps/index.js");
13
15
  const resolve_request_js_1 = require("../utils/resolve-request.js");
14
16
  const { mainFlow } = (0, index_js_2.composeSteps)([
@@ -35,7 +37,7 @@ const { mainFlow } = (0, index_js_2.composeSteps)([
35
37
  ]);
36
38
  async function add(specs, inputOptions) {
37
39
  cli_utils_1.logger.beginTimer();
38
- const targetPath = process_1.default.cwd();
40
+ const targetPath = node_process_1.default.cwd();
39
41
  const options = {
40
42
  dryRun: inputOptions?.dryRun ?? false,
41
43
  force: inputOptions?.force ?? false,
@@ -53,6 +55,47 @@ async function add(specs, inputOptions) {
53
55
  cli_utils_1.logger.fatal(configResult.error);
54
56
  }
55
57
  const { config, configStats } = configResult.value;
58
+ if (specs.length === 1 && /^@\w+$/.test(specs[0])) {
59
+ const request = `${specs.shift()}/artifact-listing`;
60
+ const spinner = cli_utils_1.logger.createSpinner(`${cli_utils_1.c.cyan.bold(request)}`);
61
+ const dir = tempy_1.default.directory();
62
+ const pkgResult = await (0, async_1.xtry)(pacote_1.default.extract(request, dir));
63
+ if (pkgResult.fails) {
64
+ cli_utils_1.logger.fatal(`The artifact '${request}' couldn't be found.`);
65
+ }
66
+ spinner.succeed();
67
+ cli_utils_1.logger.stopProgress();
68
+ const listing = await (0, read_listing_config_js_1.readListingConfig)(dir);
69
+ if (listing.fails) {
70
+ cli_utils_1.logger.fatal(listing.error);
71
+ }
72
+ const { value } = await (0, async_1.xtry)(cli_utils_1.enquirer.prompt({
73
+ type: 'multiselect',
74
+ name: 'specs',
75
+ message: 'Pick the artifacts to add',
76
+ // @ts-expect-error TS2353
77
+ limit: 7,
78
+ choices: listing.value.map(({ name, description }) => ({ name, message: `${name}${cli_utils_1.c.grey(`: ${description}`)}` })),
79
+ }));
80
+ const marked = value?.specs;
81
+ if (!marked || marked.length === 0) {
82
+ cli_utils_1.logger.warn('No artifacts marked for addition');
83
+ }
84
+ else {
85
+ const { value } = await (0, async_1.xtry)(cli_utils_1.enquirer.prompt([
86
+ (0, cli_utils_1.confirm)({
87
+ name: 'addition',
88
+ message: `Adds the following artifacts: ${marked.map((name) => cli_utils_1.c.green(name)).join(',')}`,
89
+ }),
90
+ ]));
91
+ if (value?.addition) {
92
+ specs.push(...marked);
93
+ }
94
+ else {
95
+ cli_utils_1.logger.warn('Artifacts addition has been rejected');
96
+ }
97
+ }
98
+ }
56
99
  for (const spec of specs) {
57
100
  const requestResult = (0, resolve_request_js_1.resolveRequest)(spec);
58
101
  if (requestResult.fails) {
@@ -1,4 +1,5 @@
1
1
  export { add } from './add.js';
2
2
  export { list } from './list.js';
3
+ export { outdated } from './outdated.js';
3
4
  export { remove } from './remove.js';
4
5
  export { update } from './update.js';
@@ -1,10 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.update = exports.remove = exports.list = exports.add = void 0;
3
+ exports.update = exports.remove = exports.outdated = exports.list = exports.add = void 0;
4
4
  var add_js_1 = require("./add.js");
5
5
  Object.defineProperty(exports, "add", { enumerable: true, get: function () { return add_js_1.add; } });
6
6
  var list_js_1 = require("./list.js");
7
7
  Object.defineProperty(exports, "list", { enumerable: true, get: function () { return list_js_1.list; } });
8
+ var outdated_js_1 = require("./outdated.js");
9
+ Object.defineProperty(exports, "outdated", { enumerable: true, get: function () { return outdated_js_1.outdated; } });
8
10
  var remove_js_1 = require("./remove.js");
9
11
  Object.defineProperty(exports, "remove", { enumerable: true, get: function () { return remove_js_1.remove; } });
10
12
  var update_js_1 = require("./update.js");
@@ -4,12 +4,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.list = list;
7
+ const node_path_1 = __importDefault(require("node:path"));
7
8
  const process_1 = __importDefault(require("process"));
8
9
  const cli_utils_1 = require("@zokugun/cli-utils");
9
- const lodash_es_1 = require("lodash-es");
10
+ const async_1 = __importDefault(require("@zokugun/fs-extra-plus/async"));
11
+ const xtry_1 = require("@zokugun/xtry");
10
12
  const index_js_1 = require("../configs/index.js");
13
+ const format_table_js_1 = require("../utils/format-table.js");
11
14
  function formatVariant(artifact) {
12
- const variant = Array.isArray(artifact.requires) ? (0, lodash_es_1.last)(artifact.requires) ?? '' : '';
15
+ const variant = Array.isArray(artifact.requires) ? artifact.requires.at(-1) ?? '' : '';
13
16
  if (variant.length > 0) {
14
17
  return `:${variant}`;
15
18
  }
@@ -18,22 +21,37 @@ function formatVariant(artifact) {
18
21
  }
19
22
  }
20
23
  async function list() {
21
- const targetPath = process_1.default.env.INIT_CWD;
24
+ const targetPath = process_1.default.cwd();
22
25
  const configResult = await (0, index_js_1.readInstallConfig)(targetPath);
23
26
  if (configResult.fails) {
24
27
  cli_utils_1.logger.fatal(configResult.error);
25
28
  }
29
+ const packageResult = await async_1.default.readJSON(node_path_1.default.resolve(targetPath, './package.json'));
30
+ if (packageResult.fails) {
31
+ cli_utils_1.logger.fatal((0, xtry_1.stringifyError)(packageResult.error));
32
+ }
33
+ const { name } = packageResult.value;
26
34
  const { config, configStats } = configResult.value;
27
35
  const artifacts = Object.entries(config.artifacts);
36
+ cli_utils_1.logger.newLine();
28
37
  if (artifacts.length === 0) {
29
38
  cli_utils_1.logger.info('No artifacts have been installed.');
30
39
  }
31
40
  else {
32
- cli_utils_1.logger.info(`List of installed artifacts (${configStats.name}):\n`);
41
+ cli_utils_1.logger.print(`${name} ${cli_utils_1.c.grey(configStats.name)}`);
42
+ cli_utils_1.logger.newLine();
43
+ const table = [];
33
44
  for (const [name, artifact] of artifacts) {
34
- const version = artifact.version ? `@${artifact.version}` : '';
35
- cli_utils_1.logger.info(`- ${name}${version}${formatVariant(artifact)}`);
45
+ const line = [
46
+ ' ',
47
+ name,
48
+ ' ',
49
+ artifact.version ? `${cli_utils_1.c.green(artifact.version)}${cli_utils_1.c.gray(formatVariant(artifact))}` : '',
50
+ ];
51
+ table.push(line);
36
52
  }
53
+ const lines = (0, format_table_js_1.formatTable)(table, 'LLLL');
54
+ cli_utils_1.logger.print(lines.join('\n'));
37
55
  }
38
56
  cli_utils_1.logger.newLine();
39
57
  }
@@ -0,0 +1 @@
1
+ export declare function outdated(): Promise<void>;
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.outdated = outdated;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const process_1 = __importDefault(require("process"));
9
+ const cli_utils_1 = require("@zokugun/cli-utils");
10
+ const async_1 = __importDefault(require("@zokugun/fs-extra-plus/async"));
11
+ const xtry_1 = require("@zokugun/xtry");
12
+ const cli_progress_1 = require("cli-progress");
13
+ const pacote_1 = __importDefault(require("pacote"));
14
+ const semver_1 = require("semver");
15
+ const index_js_1 = require("../configs/index.js");
16
+ const format_table_js_1 = require("../utils/format-table.js");
17
+ const time_difference_js_1 = require("../utils/time-difference.js");
18
+ async function outdated() {
19
+ const targetPath = process_1.default.cwd();
20
+ const configResult = await (0, index_js_1.readInstallConfig)(targetPath);
21
+ if (configResult.fails) {
22
+ cli_utils_1.logger.fatal(configResult.error);
23
+ }
24
+ const packageResult = await async_1.default.readJSON(node_path_1.default.resolve(targetPath, './package.json'));
25
+ if (packageResult.fails) {
26
+ cli_utils_1.logger.fatal((0, xtry_1.stringifyError)(packageResult.error));
27
+ }
28
+ const { name } = packageResult.value;
29
+ const { config, configStats } = configResult.value;
30
+ const artifacts = Object.entries(config.artifacts);
31
+ cli_utils_1.logger.newLine();
32
+ if (artifacts.length === 0) {
33
+ cli_utils_1.logger.info('No artifacts have been installed.');
34
+ }
35
+ else {
36
+ cli_utils_1.logger.print(`${name} ${cli_utils_1.c.grey(configStats.name)}`);
37
+ const bar = new cli_progress_1.SingleBar({
38
+ clearOnComplete: true,
39
+ hideCursor: true,
40
+ format: `{bar} {value}/{total} ${cli_utils_1.c.gray('{name}')}`,
41
+ linewrap: false,
42
+ barsize: 40,
43
+ }, cli_progress_1.Presets.shades_classic);
44
+ bar.start(artifacts.length, 0);
45
+ const table = [];
46
+ for (const [index, [name, artifact]] of artifacts.entries()) {
47
+ const current = await pacote_1.default.manifest(`${name}@${artifact.version}`, {
48
+ fullMetadata: true,
49
+ });
50
+ const latest = await pacote_1.default.manifest(name, {
51
+ fullMetadata: true,
52
+ });
53
+ const newer = (0, semver_1.gt)(latest.version, artifact.version);
54
+ const line = [
55
+ ' ',
56
+ newer ? name : cli_utils_1.c.grey(name),
57
+ ' ',
58
+ (0, time_difference_js_1.timeDifference)(current._time),
59
+ artifact.version ? cli_utils_1.c.grey(artifact.version) : '',
60
+ cli_utils_1.c.dim.grey('→'),
61
+ newer ? latest.version : cli_utils_1.c.grey.strikethrough(latest.version),
62
+ newer ? (0, time_difference_js_1.timeDifference)(latest._time) : '',
63
+ ];
64
+ table.push(line);
65
+ bar.update(index, { name });
66
+ }
67
+ bar.stop();
68
+ cli_utils_1.logger.newLine();
69
+ const lines = (0, format_table_js_1.formatTable)(table, 'LLLLRRRL');
70
+ cli_utils_1.logger.print(lines.join('\n'));
71
+ }
72
+ cli_utils_1.logger.newLine();
73
+ }
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.remove = remove;
7
7
  const process_1 = __importDefault(require("process"));
8
8
  const cli_utils_1 = require("@zokugun/cli-utils");
9
+ const async_1 = require("@zokugun/xtry/async");
9
10
  const pacote_1 = __importDefault(require("pacote"));
10
11
  const tempy_1 = __importDefault(require("tempy"));
11
12
  const index_js_1 = require("../configs/index.js");
@@ -43,6 +44,32 @@ async function remove(specs, inputOptions) {
43
44
  cli_utils_1.logger.fatal(configResult.error);
44
45
  }
45
46
  const { config, configStats } = configResult.value;
47
+ if (specs.length === 0) {
48
+ const { value } = await (0, async_1.xtry)(cli_utils_1.enquirer.prompt({
49
+ type: 'multiselect',
50
+ name: 'specs',
51
+ message: 'Pick the artifacts to remove',
52
+ choices: Object.keys(config.artifacts).map((name) => ({ name })),
53
+ }));
54
+ const marked = value?.specs;
55
+ if (!marked || marked.length === 0) {
56
+ cli_utils_1.logger.warn('No artifacts marked for removal');
57
+ }
58
+ else {
59
+ const { value } = await (0, async_1.xtry)(cli_utils_1.enquirer.prompt([
60
+ (0, cli_utils_1.confirm)({
61
+ name: 'remove',
62
+ message: `Remove the following artifacts: ${marked.map((name) => cli_utils_1.c.green(name)).join(',')}`,
63
+ }),
64
+ ]));
65
+ if (value?.remove) {
66
+ specs.push(...marked);
67
+ }
68
+ else {
69
+ cli_utils_1.logger.warn('Artifacts removal has been rejected');
70
+ }
71
+ }
72
+ }
46
73
  for (const spec of specs) {
47
74
  const requestResult = (0, resolve_request_js_1.resolveRequest)(spec);
48
75
  if (requestResult.fails) {
@@ -0,0 +1,7 @@
1
+ import { type AsyncDResult } from '@zokugun/xtry';
2
+ export type Listing = ListingEntry[];
3
+ export type ListingEntry = {
4
+ name: string;
5
+ description: string;
6
+ };
7
+ export declare function readListingConfig(targetPath: string): AsyncDResult<Listing>;
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.readListingConfig = readListingConfig;
7
+ const path_1 = __importDefault(require("path"));
8
+ const async_1 = __importDefault(require("@zokugun/fs-extra-plus/async"));
9
+ const is_it_type_1 = require("@zokugun/is-it-type");
10
+ const xtry_1 = require("@zokugun/xtry");
11
+ const yaml_1 = __importDefault(require("yaml"));
12
+ const CONFIG_LOCATIONS = [
13
+ {
14
+ name: 'artifact-listing.yml',
15
+ type: 'yaml',
16
+ },
17
+ {
18
+ name: 'artifact-listing.yaml',
19
+ type: 'yaml',
20
+ },
21
+ {
22
+ name: 'artifact-listing.json',
23
+ type: 'json',
24
+ },
25
+ ];
26
+ async function readListingConfig(targetPath) {
27
+ let content;
28
+ let name;
29
+ let type;
30
+ for (const place of CONFIG_LOCATIONS) {
31
+ const result = await async_1.default.readFile(path_1.default.join(targetPath, place.name), 'utf8');
32
+ if (!result.fails) {
33
+ content = result.value;
34
+ ({ name, type } = place);
35
+ }
36
+ }
37
+ if (!content) {
38
+ return normalizeConfig(content, name);
39
+ }
40
+ if (type === 'json') {
41
+ return normalizeConfig(JSON.parse(content), name);
42
+ }
43
+ else if (type === 'yaml') {
44
+ return normalizeConfig(yaml_1.default.parse(content), name);
45
+ }
46
+ else {
47
+ try {
48
+ return normalizeConfig(JSON.parse(content), name);
49
+ }
50
+ catch {
51
+ return normalizeConfig(yaml_1.default.parse(content), name);
52
+ }
53
+ }
54
+ }
55
+ function normalizeConfig(data, source) {
56
+ if (!(0, is_it_type_1.isArray)(data)) {
57
+ return (0, xtry_1.err)(`Listing file ${source} must export an array.`);
58
+ }
59
+ for (const entry of data) {
60
+ if (!(0, is_it_type_1.isRecord)(entry)) {
61
+ return (0, xtry_1.err)('Listing entry must be an object.');
62
+ }
63
+ if (!(0, is_it_type_1.isString)(entry.name)) {
64
+ return (0, xtry_1.err)('Listing entry/name must be a string.');
65
+ }
66
+ if (!(0, is_it_type_1.isString)(entry.description)) {
67
+ return (0, xtry_1.err)('Listing entry/description must be a string.');
68
+ }
69
+ }
70
+ return (0, xtry_1.ok)(data);
71
+ } // }}}
@@ -0,0 +1 @@
1
+ export declare function formatTable(rows: string[][], align: string, spaces?: string): string[];
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatTable = formatTable;
4
+ const node_util_1 = require("node:util");
5
+ function formatTable(rows, align, spaces = ' ') {
6
+ const maxLength = [];
7
+ for (const row of rows) {
8
+ for (const [index, cell] of row.entries()) {
9
+ const length = getVisualLength(cell);
10
+ if (!maxLength[index] || maxLength[index] < length) {
11
+ maxLength[index] = length;
12
+ }
13
+ }
14
+ }
15
+ const lines = [];
16
+ for (const row of rows) {
17
+ const cells = [];
18
+ for (const [index, cell] of row.entries()) {
19
+ const pad = align[index] === 'R' ? visualPadStart : visualPadEnd;
20
+ cells.push(pad(cell, maxLength[index]));
21
+ }
22
+ lines.push(cells.join(spaces));
23
+ }
24
+ return lines;
25
+ }
26
+ function getVisualLength(cell) {
27
+ if (cell === '') {
28
+ return 0;
29
+ }
30
+ cell = (0, node_util_1.stripVTControlCharacters)(cell);
31
+ let width = 0;
32
+ for (let i = 0; i < cell.length; i++) {
33
+ const code = cell.codePointAt(i);
34
+ if (!code) {
35
+ continue;
36
+ }
37
+ // Ignore control characters
38
+ if (code <= 0x1F || (code >= 0x7F && code <= 0x9F)) {
39
+ continue;
40
+ }
41
+ // Ignore combining characters
42
+ if (code >= 0x3_00 && code <= 0x3_6F) {
43
+ continue;
44
+ }
45
+ // Surrogates
46
+ if (code > 0xFF_FF) {
47
+ i++;
48
+ }
49
+ width += 1;
50
+ }
51
+ return width;
52
+ }
53
+ function visualPadStart(text, pad, char = ' ') {
54
+ return text.padStart(pad - getVisualLength(text) + text.length, char);
55
+ }
56
+ function visualPadEnd(text, pad, char = ' ') {
57
+ return text.padEnd(pad - getVisualLength(text) + text.length, char);
58
+ }
@@ -0,0 +1 @@
1
+ export declare function timeDifference(from: number | string, to?: number): string;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.timeDifference = timeDifference;
4
+ const cli_utils_1 = require("@zokugun/cli-utils");
5
+ const is_it_type_1 = require("@zokugun/is-it-type");
6
+ const msPerMinute = 60 * 1000;
7
+ const msPerHour = msPerMinute * 60;
8
+ const msPerDay = msPerHour * 24;
9
+ const msPerMonth = msPerDay * 30;
10
+ const msPerYear = msPerDay * 365;
11
+ function timeDifference(from, to = Date.now()) {
12
+ if ((0, is_it_type_1.isString)(from)) {
13
+ from = (new Date(from)).getTime();
14
+ }
15
+ const elapsed = to - from;
16
+ if (elapsed < msPerDay) {
17
+ return cli_utils_1.c.gray('⩽1d');
18
+ }
19
+ else if (elapsed < msPerMonth) {
20
+ return cli_utils_1.c.green(`~${Math.round(elapsed / msPerDay)}d`);
21
+ }
22
+ else if (elapsed < msPerYear) {
23
+ return cli_utils_1.c.yellow(`~${Math.round(elapsed / msPerMonth)}mo`);
24
+ }
25
+ else {
26
+ return cli_utils_1.c.red(`~${(elapsed / msPerYear).toFixed(1)}y`);
27
+ }
28
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@zokugun/artifact",
3
3
  "description": "Boilerplate your project & keep your configurations up to date",
4
- "version": "0.7.0",
4
+ "version": "0.8.0",
5
5
  "author": {
6
6
  "name": "Baptiste Augrain",
7
7
  "email": "daiyam@zokugun.org"
@@ -37,7 +37,7 @@
37
37
  "release": "release-it",
38
38
  "test": "tsc -p test && mocha",
39
39
  "test:dev": "mocha",
40
- "test:watch": "tsc-watch -p src -p test --onSuccess 'mocha -g=\"vars.exp.pipe.gitname.dotprop\"'",
40
+ "test:watch": "tsc-watch -p src -p test --onSuccess 'mocha -g=\"\"'",
41
41
  "update:artifacts": "artifact update",
42
42
  "update:ci": "PINACT_MIN_AGE=7 pinact run",
43
43
  "update:deps": "taze",
@@ -46,11 +46,13 @@
46
46
  "watch:test": "tsc-watch -p test"
47
47
  },
48
48
  "dependencies": {
49
+ "@types/cli-progress": "^3.11.6",
49
50
  "@zokugun/cli-utils": "0.3.1",
50
51
  "@zokugun/configdotts-merge": "0.2.1",
51
52
  "@zokugun/fs-extra-plus": "0.3.7",
52
53
  "@zokugun/is-it-type": "0.8.1",
53
54
  "@zokugun/xtry": "0.11.4",
55
+ "cli-progress": "^3.12.0",
54
56
  "dayjs": "1.11.20",
55
57
  "editorconfig": "0.15.3",
56
58
  "git-url-parse": "16.1.0",