@xnoxs/flux-lang 3.4.8 → 3.5.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/src/self/pkg.js CHANGED
@@ -1,5 +1,7 @@
1
1
  // ── Flux stdlib ──
2
2
 
3
+ function map(arr, fn) { return arr.map(fn); }
4
+
3
5
  function join(arr, sep) { return arr.join(sep != null ? sep : ','); }
4
6
 
5
7
  function keys(obj) { return Object.keys(obj); }
@@ -19,9 +21,11 @@ const { readPackage, writeConfig, loadConfig } = require("./config");
19
21
  const REGISTRY_URL = "https://registry.npmjs.org";
20
22
  const FLUX_PKG_DIR = "flux_modules";
21
23
  const PKG_FILE = "flux.json";
22
- const C = { reset: "\x1b[0m", bold: "\x1b[1m", dim: "\x1b[2m", red: "\x1b[31m", green: "\x1b[32m", yellow: "\x1b[33m", blue: "\x1b[34m", cyan: "\x1b[36m", gray: "\x1b[90m" };
24
+ const C = { reset: "\u001b[0m", bold: "\u001b[1m", dim: "\u001b[2m", red: "\u001b[31m", green: "\u001b[32m", yellow: "\u001b[33m", blue: "\u001b[34m", cyan: "\u001b[36m", gray: "\u001b[90m" };
25
+ const hasColor = ((process.env.COLORTERM || process.env.FORCE_COLOR) || (process.stdout.isTTY && (process.env.TERM != "dumb")));
26
+ const noColor = (process.env.NO_COLOR || !hasColor);
23
27
  function clr(c, s) {
24
- return ((c + s) + C.reset);
28
+ return (noColor ? s : ((c + s) + C.reset));
25
29
  }
26
30
  function ok(msg) {
27
31
  console.log((clr(C.green, "✓ ") + msg));
@@ -32,6 +36,28 @@ function err(msg) {
32
36
  function info(msg) {
33
37
  console.log((clr(C.cyan, " ") + msg));
34
38
  }
39
+ function createSpinner(msg) {
40
+ if (noColor) {
41
+ process.stdout.write(((" " + msg) + " ...\n"));
42
+ function _stop(ok_, done) {
43
+ process.stdout.write(((((" " + (ok_ ? "✓" : "✗")) + " ") + done) + "\n"));
44
+ }
45
+ return { stop: _stop };
46
+ }
47
+ const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
48
+ let fi = 0;
49
+ function tick() {
50
+ process.stdout.write((((("\r " + clr(C.cyan, frames[(fi % frames.length)])) + " ") + msg) + " "));
51
+ fi = (fi + 1);
52
+ }
53
+ const timer = setInterval(tick, 80);
54
+ function stop(ok_, done) {
55
+ clearInterval(timer);
56
+ const icon = (ok_ ? clr(C.green, "✓") : clr(C.red, "✗"));
57
+ process.stdout.write((((("\r " + icon) + " ") + done) + " \n"));
58
+ }
59
+ return { stop };
60
+ }
35
61
  async function fetchJson(url) {
36
62
  const mod = (url.startsWith("https") ? Https : Http);
37
63
  function doRequest(resolve, reject) {
@@ -81,15 +107,17 @@ async function cmdAdd(specs, opts) {
81
107
  const isDev = (opts?.dev ?? false);
82
108
  const cwd = process.cwd();
83
109
  const pkg = ensureFluxJson(cwd);
110
+ let addedCount = 0;
111
+ console.log();
84
112
  for (const spec of specs) {
85
113
  const { name, version } = parsePackageSpec(spec);
86
- console.log((((clr(C.cyan, "\n Adding ") + clr(C.bold, name)) + clr(C.gray, ("@" + version))) + " ..."));
114
+ const spinner = createSpinner((clr(C.bold, name) + clr(C.gray, ("@" + version))));
87
115
  try {
88
116
  const info_ = await fetchJson(((REGISTRY_URL + "/") + name));
89
117
  const resolvedVersion = ((version == "latest") ? (info_["dist-tags"]?.latest ?? "1.0.0") : version);
90
118
  const versionInfo = info_.versions?.[resolvedVersion];
91
119
  if (!versionInfo) {
92
- err(((("Version " + resolvedVersion) + " not found for ") + name));
120
+ spinner.stop(false, ((clr(C.bold, name) + clr(C.gray, ("@" + resolvedVersion))) + " — version not found"));
93
121
  continue;
94
122
  }
95
123
  const depKey = (isDev ? "devDependencies" : "dependencies");
@@ -98,17 +126,19 @@ async function cmdAdd(specs, opts) {
98
126
  }
99
127
  pkg[depKey][name] = ("^" + resolvedVersion);
100
128
  saveFluxJson(pkg, cwd);
101
- const desc = (versionInfo.description ? clr(C.gray, (" — " + versionInfo.description)) : "");
102
- ok(((name + clr(C.green, ("@" + resolvedVersion))) + desc));
103
- info(("Added to " + (isDev ? "devDependencies" : "dependencies")));
129
+ const shortDesc = (versionInfo.description ? clr(C.gray, (" — " + versionInfo.description.slice(0, 55))) : "");
130
+ spinner.stop(true, ((clr(C.bold, name) + clr(C.green, ("@" + resolvedVersion))) + shortDesc));
131
+ addedCount = (addedCount + 1);
104
132
  }
105
133
  catch (e) {
106
- err(((("Failed to fetch " + name) + ": ") + e.message));
134
+ spinner.stop(false, ((clr(C.bold, name) + " ") + e.message));
107
135
  }
108
136
  }
109
137
  console.log();
110
- console.log(((clr(C.gray, " Run ") + clr(C.yellow, "flux install")) + clr(C.gray, " to install packages")));
111
- console.log();
138
+ if ((addedCount > 0)) {
139
+ console.log((((" " + clr(C.gray, "Run ")) + clr(C.yellow, "flux install")) + clr(C.gray, " to install packages")));
140
+ console.log();
141
+ }
112
142
  }
113
143
  module.exports.cmdAdd = cmdAdd;
114
144
  function cmdRemove(names, opts) {
@@ -142,53 +172,57 @@ async function cmdInstall(opts) {
142
172
  const { execSync } = require("child_process");
143
173
  const cwd = process.cwd();
144
174
  const pkg = ensureFluxJson(cwd);
145
- const deps = (pkg.dependencies ?? {});
146
- const devDeps = (pkg.devDependencies ?? {});
175
+ const fluxModDir = Path.join(cwd, "flux_modules");
176
+ const deps = (pkg.dependencies ?? { });
177
+ const devDeps = (pkg.devDependencies ?? { });
147
178
  const all = { ...deps, ...devDeps };
148
179
  const names = Object.keys(all);
149
180
  if ((names.length == 0)) {
181
+ console.log();
150
182
  info("No dependencies found in flux.json");
183
+ console.log();
151
184
  return;
152
185
  }
153
- console.log(((clr(C.cyan, "\n Installing ") + names.length) + " package(s) into flux_modules/...\n"));
186
+ console.log();
187
+ console.log(((" " + clr(C.bold, (pkg.name ?? "project"))) + clr(C.gray, ((" — " + names.length) + " package(s)"))));
188
+ console.log();
154
189
  for (const name of names) {
155
190
  const spec = all[name];
156
- console.log(((clr(C.gray, " ○ ") + name) + clr(C.gray, ("@" + spec))));
191
+ const isDev_ = Object.prototype.hasOwnProperty.call(devDeps, name);
192
+ const tag = (isDev_ ? clr(C.gray, " dev") : "");
193
+ console.log((((((" " + clr(C.gray, "○")) + " ") + clr((isDev_ ? C.blue : C.green), name)) + clr(C.gray, ("@" + spec))) + tag));
157
194
  }
158
195
  console.log();
159
-
160
- // Ensure flux_modules/ exists with a minimal package.json
161
- const fluxModDir = Path.join(cwd, "flux_modules");
162
- if (!Fs.existsSync(fluxModDir)) Fs.mkdirSync(fluxModDir, { recursive: true });
196
+ if (!Fs.existsSync(fluxModDir)) {
197
+ Fs.mkdirSync(fluxModDir, { recursive: true });
198
+ }
163
199
  const fluxPkgFile = Path.join(fluxModDir, "package.json");
164
200
  if (!Fs.existsSync(fluxPkgFile)) {
165
- const fluxPkg = { name: (pkg.name || "flux-project") + "-flux-modules", version: "1.0.0", private: true };
166
- Fs.writeFileSync(fluxPkgFile, JSON.stringify(fluxPkg, null, 2) + "\n", "utf8");
201
+ const fluxPkg = { name: (pkg.name + "-flux-modules"), version: "1.0.0", private: true };
202
+ Fs.writeFileSync(fluxPkgFile, (JSON.stringify(fluxPkg, null, 2) + "\n"), "utf8");
167
203
  }
168
-
169
204
  const prodNames = Object.keys(deps);
170
- const devNames = Object.keys(devDeps);
171
-
205
+ const devNames = Object.keys(devDeps);
206
+ const spinner = createSpinner("Installing packages into flux_modules/");
172
207
  try {
173
- if (prodNames.length > 0) {
174
- const prodPkgs = prodNames.map(n => n + "@" + (deps[n] ?? "latest")).join(" ");
175
- const installCmd = "npm install --prefix " + fluxModDir + " " + prodPkgs;
176
- info("Running: " + installCmd);
177
- execSync(installCmd, { cwd: cwd, stdio: "inherit" });
208
+ if ((prodNames.length > 0)) {
209
+ const prodPkgs = prodNames.map((n) => ((n + "@") + (deps[n] ?? "latest"))).join(" ");
210
+ const installCmd = ((("npm install --prefix " + fluxModDir) + " ") + prodPkgs);
211
+ execSync(installCmd, { cwd, stdio: "pipe" });
178
212
  }
179
- if (devNames.length > 0) {
180
- const devPkgs = devNames.map(n => n + "@" + (devDeps[n] ?? "latest")).join(" ");
181
- const devCmd = "npm install --prefix " + fluxModDir + " --save-dev " + devPkgs;
182
- info("Running: " + devCmd);
183
- execSync(devCmd, { cwd: cwd, stdio: "inherit" });
213
+ if ((devNames.length > 0)) {
214
+ const devPkgs = devNames.map((n) => ((n + "@") + (devDeps[n] ?? "latest"))).join(" ");
215
+ const devCmd = ((("npm install --prefix " + fluxModDir) + " --save-dev ") + devPkgs);
216
+ execSync(devCmd, { cwd, stdio: "pipe" });
184
217
  }
218
+ spinner.stop(true, ((names.length + " package(s) installed into ") + clr(C.gray, "flux_modules/")));
185
219
  console.log();
186
- ok(names.length + " package(s) installed into flux_modules/node_modules/");
187
- info("Packages resolve automatically when using: flux run, flux bundle");
188
- } catch (e) {
220
+ console.log(((((" " + clr(C.gray, "Packages resolve automatically when using: ")) + clr(C.yellow, "flux run")) + clr(C.gray, ", ")) + clr(C.yellow, "flux bundle")));
221
+ }
222
+ catch (e) {
223
+ spinner.stop(false, ("Install failed: " + e.message));
189
224
  console.log();
190
- err("Install failed: " + e.message);
191
- info("Try manually: npm install --prefix ./flux_modules <package>");
225
+ console.log(((" " + clr(C.gray, "Try: ")) + clr(C.yellow, "npm install --prefix ./flux_modules <package>")));
192
226
  }
193
227
  console.log();
194
228
  }
@@ -226,65 +260,156 @@ function cmdList(opts) {
226
260
  }
227
261
  module.exports.cmdList = cmdList;
228
262
  async function cmdSearch(query, opts) {
229
- console.log(((clr(C.cyan, "\n Searching for ") + clr(C.bold, (("\"" + query) + "\""))) + " ...\n"));
263
+ console.log();
264
+ const spinner = createSpinner(("Searching for " + clr(C.bold, (("\"" + query) + "\""))));
230
265
  try {
231
- const url = (((REGISTRY_URL + "/-/v1/search?text=") + encodeURIComponent((query + " keywords:flux"))) + "&size=10");
266
+ const url = (((REGISTRY_URL + "/-/v1/search?text=") + encodeURIComponent(query)) + "&size=10");
232
267
  const results = await fetchJson(url);
233
268
  const objects = (results.objects ?? []);
234
269
  if ((objects.length == 0)) {
235
- info(("No packages found for: " + query));
270
+ spinner.stop(false, ("No packages found for: " + query));
236
271
  console.log();
237
272
  return;
238
273
  }
274
+ spinner.stop(true, ((("Found " + objects.length) + " result(s) for ") + clr(C.bold, (("\"" + query) + "\""))));
275
+ console.log();
239
276
  for (const obj of objects) {
240
277
  const p = obj.package;
241
278
  console.log(((" " + clr(C.bold, p.name)) + clr(C.gray, (" v" + p.version))));
242
279
  if (p.description) {
243
280
  console.log((" " + clr(C.gray, p.description)));
244
281
  }
245
- console.log((" " + clr(C.blue, (p.links?.npm ?? ""))));
282
+ if (p.links?.npm) {
283
+ console.log((" " + clr(C.blue, p.links.npm)));
284
+ }
246
285
  console.log();
247
286
  }
248
287
  }
249
288
  catch (e) {
250
- err(("Search failed: " + e.message));
289
+ spinner.stop(false, ("Search failed: " + e.message));
290
+ console.log();
251
291
  }
252
292
  }
253
293
  module.exports.cmdSearch = cmdSearch;
254
294
  async function cmdInfo(name, opts) {
255
- console.log(((clr(C.cyan, "\n Fetching info for ") + clr(C.bold, name)) + " ...\n"));
295
+ console.log();
296
+ const spinner = createSpinner(("Fetching info for " + clr(C.bold, name)));
256
297
  try {
257
298
  const info_ = await fetchJson(((REGISTRY_URL + "/") + name));
258
299
  const latest = (info_["dist-tags"]?.latest ?? "unknown");
259
300
  const ver = (info_.versions?.[latest] ?? { });
260
- console.log((clr(C.bold, (" " + name)) + clr(C.gray, (" v" + latest))));
301
+ spinner.stop(true, (clr(C.bold, name) + clr(C.green, ("@" + latest))));
302
+ console.log();
261
303
  if (ver.description) {
262
- console.log((" " + ver.description));
304
+ console.log((" " + clr(C.gray, ver.description)));
263
305
  }
264
306
  console.log();
265
- console.log((clr(C.gray, " license: ") + (ver.license ?? "unknown")));
266
- console.log((clr(C.gray, " author: ") + ((ver.author?.name ?? ver.author) ?? "unknown")));
307
+ console.log((((" " + clr(C.gray, "license:")) + " ") + (ver.license ?? "unknown")));
308
+ console.log((((" " + clr(C.gray, "author: ")) + " ") + ((ver.author?.name ?? ver.author) ?? "unknown")));
267
309
  const homepage = (ver.homepage ?? info_.homepage);
268
310
  if (homepage) {
269
- console.log((clr(C.gray, " home: ") + clr(C.blue, homepage)));
311
+ console.log((((" " + clr(C.gray, "home: ")) + " ") + clr(C.blue, homepage)));
270
312
  }
271
313
  const repo = (ver.repository?.url ?? info_.repository?.url);
272
314
  if (repo) {
273
- console.log((clr(C.gray, " repo: ") + clr(C.blue, repo.replace("git+", "").replace(".git", ""))));
315
+ console.log((((" " + clr(C.gray, "repo: ")) + " ") + clr(C.blue, repo.replace("git+", "").replace(".git", ""))));
274
316
  }
275
317
  const keywords = (ver.keywords ?? []);
276
318
  if ((keywords.length > 0)) {
277
- console.log((clr(C.gray, " tags: ") + keywords.slice(0, 8).join(", ")));
319
+ console.log((((" " + clr(C.gray, "tags: ")) + " ") + keywords.slice(0, 8).join(", ")));
278
320
  }
279
321
  console.log();
280
- console.log((clr(C.gray, " Install: ") + clr(C.yellow, ("flux add " + name))));
322
+ console.log(((" " + clr(C.gray, "Install: ")) + clr(C.yellow, ("flux add " + name))));
281
323
  console.log();
282
324
  }
283
325
  catch (e) {
284
- err(((("Could not fetch info for " + name) + ": ") + e.message));
326
+ spinner.stop(false, ((("Could not fetch info for " + name) + ": ") + e.message));
327
+ console.log();
285
328
  }
286
329
  }
287
330
  module.exports.cmdInfo = cmdInfo;
331
+ async function cmdUpgrade(opts) {
332
+ const isCheck = (opts?.check ?? false);
333
+ const cwd = process.cwd();
334
+ const pkg = ensureFluxJson(cwd);
335
+ const deps = (pkg.dependencies ?? { });
336
+ const devDeps = (pkg.devDependencies ?? { });
337
+ const allKeys = [...Object.keys(deps), ...Object.keys(devDeps)];
338
+ if ((allKeys.length == 0)) {
339
+ console.log();
340
+ info("No dependencies to upgrade");
341
+ console.log();
342
+ return;
343
+ }
344
+ console.log();
345
+ let updated = 0;
346
+ for (const name of Object.keys(deps)) {
347
+ const spinner = createSpinner(clr(C.green, name));
348
+ try {
349
+ const info_ = await fetchJson(((REGISTRY_URL + "/") + name));
350
+ const latest = (info_["dist-tags"]?.latest ?? null);
351
+ if (!latest) {
352
+ spinner.stop(false, (clr(C.green, name) + " — could not resolve latest version"));
353
+ continue;
354
+ }
355
+ const current = deps[name].replace("^", "").replace("~", "");
356
+ if ((latest == current)) {
357
+ spinner.stop(true, (clr(C.green, name) + clr(C.gray, (("@" + current) + " — up to date"))));
358
+ }
359
+ else {
360
+ spinner.stop(true, (((clr(C.green, name) + clr(C.gray, ("@" + current))) + " → ") + clr(C.yellow, latest)));
361
+ if (!isCheck) {
362
+ pkg.dependencies[name] = ("^" + latest);
363
+ updated = (updated + 1);
364
+ }
365
+ }
366
+ }
367
+ catch (e) {
368
+ spinner.stop(false, ((clr(C.green, name) + " — ") + e.message));
369
+ }
370
+ }
371
+ for (const name of Object.keys(devDeps)) {
372
+ const spinner = createSpinner((clr(C.blue, name) + clr(C.gray, " (dev)")));
373
+ try {
374
+ const info_ = await fetchJson(((REGISTRY_URL + "/") + name));
375
+ const latest = (info_["dist-tags"]?.latest ?? null);
376
+ if (!latest) {
377
+ spinner.stop(false, (clr(C.blue, name) + " — could not resolve latest version"));
378
+ continue;
379
+ }
380
+ const current = devDeps[name].replace("^", "").replace("~", "");
381
+ if ((latest == current)) {
382
+ spinner.stop(true, (clr(C.blue, name) + clr(C.gray, (("@" + current) + " — up to date"))));
383
+ }
384
+ else {
385
+ spinner.stop(true, ((((clr(C.blue, name) + clr(C.gray, ("@" + current))) + " → ") + clr(C.yellow, latest)) + clr(C.gray, " (dev)")));
386
+ if (!isCheck) {
387
+ pkg.devDependencies[name] = ("^" + latest);
388
+ updated = (updated + 1);
389
+ }
390
+ }
391
+ }
392
+ catch (e) {
393
+ spinner.stop(false, ((clr(C.blue, name) + " — ") + e.message));
394
+ }
395
+ }
396
+ console.log();
397
+ if (isCheck) {
398
+ ok((("Check complete — run " + clr(C.yellow, "flux upgrade")) + " to apply upgrades"));
399
+ }
400
+ else {
401
+ if ((updated > 0)) {
402
+ saveFluxJson(pkg, cwd);
403
+ ok((updated + " package(s) updated in flux.json"));
404
+ console.log((((" " + clr(C.gray, "Run ")) + clr(C.yellow, "flux install")) + clr(C.gray, " to install upgraded packages")));
405
+ }
406
+ else {
407
+ ok("All packages are already up to date");
408
+ }
409
+ }
410
+ console.log();
411
+ }
412
+ module.exports.cmdUpgrade = cmdUpgrade;
288
413
  function cmdPublish(opts) {
289
414
  const cwd = process.cwd();
290
415
  const pkg = readPackage(cwd);
@@ -311,79 +436,4 @@ function cmdPublish(opts) {
311
436
  info("Run: flux publish --registry <url> for a custom registry");
312
437
  console.log();
313
438
  }
314
- module.exports.cmdPublish = cmdPublish;
315
-
316
- // ── flux upgrade [--check] ─────────────────────────────────────────────────
317
- // Checks all dependencies in flux.json for newer versions and updates them.
318
- // --check : dry-run, only show what would change without writing
319
- async function cmdUpgrade(opts) {
320
- const check = (opts && opts.check) || false;
321
- const cwd = process.cwd();
322
- const pkg = readPackage(cwd);
323
- if (!pkg) { err('No flux.json found. Run: flux init'); return; }
324
-
325
- const allDeps = Object.assign({}, pkg.dependencies || {}, pkg.devDependencies || {});
326
- const names = Object.keys(allDeps);
327
- if (names.length === 0) { info('No dependencies in flux.json'); return; }
328
-
329
- console.log();
330
- console.log(clr(C.cyan, ' Checking ' + names.length + ' package(s) for updates...\n'));
331
-
332
- let updated = 0;
333
- let upToDate = 0;
334
- let failed = 0;
335
-
336
- for (const name of names) {
337
- const current = allDeps[name].replace(/^[\^~>=<\s]+/, '');
338
- try {
339
- const data = await fetchJson(REGISTRY_URL + '/' + name);
340
- const latest = data['dist-tags'] && data['dist-tags'].latest;
341
- if (!latest) { err(name + ' — could not resolve latest'); failed++; continue; }
342
-
343
- const isDev = !!(pkg.devDependencies && pkg.devDependencies[name]);
344
- const tag = isDev ? clr(C.blue, ' (dev)') : '';
345
-
346
- if (current === latest) {
347
- console.log(' ' + clr(C.gray, '✓') + ' ' + clr(C.bold, name) + clr(C.gray, '@' + current + ' — up to date') + tag);
348
- upToDate++;
349
- } else {
350
- console.log(' ' + clr(C.yellow, '↑') + ' ' + clr(C.bold, name) + clr(C.gray, '@' + current) + ' → ' + clr(C.green, latest) + tag);
351
- if (!check) {
352
- if (isDev) {
353
- if (!pkg.devDependencies) pkg.devDependencies = {};
354
- pkg.devDependencies[name] = '^' + latest;
355
- } else {
356
- if (!pkg.dependencies) pkg.dependencies = {};
357
- pkg.dependencies[name] = '^' + latest;
358
- }
359
- }
360
- updated++;
361
- }
362
- } catch (e) {
363
- err(name + ' — ' + e.message);
364
- failed++;
365
- }
366
- }
367
-
368
- console.log();
369
- if (check) {
370
- console.log(clr(C.cyan, ' Check mode: no changes written.'));
371
- if (updated > 0) {
372
- console.log(clr(C.yellow, ' ' + updated + ' update(s) available. Run: flux upgrade'));
373
- } else {
374
- console.log(clr(C.green, ' All packages are up to date.'));
375
- }
376
- } else {
377
- if (updated > 0) {
378
- const pkgPath = Path.join(cwd, 'flux.json');
379
- Fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + '\n', 'utf8');
380
- ok(updated + ' package(s) updated in flux.json');
381
- info('Run: flux install to apply changes');
382
- } else {
383
- console.log(clr(C.green, ' ✓ All packages are already up to date.'));
384
- }
385
- if (failed > 0) info(failed + ' package(s) could not be checked');
386
- }
387
- console.log();
388
- }
389
- module.exports.cmdUpgrade = cmdUpgrade;
439
+ module.exports.cmdPublish = cmdPublish;
@@ -21,7 +21,7 @@ function repeat(s, n) { return String(s).repeat(n); }
21
21
  const Fs = require("fs");
22
22
  const Path = require("path");
23
23
  const Os = require("os");
24
- const C = { reset: "\x1b[0m", bold: "\x1b[1m", red: "\x1b[31m", green: "\x1b[32m", yellow: "\x1b[33m", cyan: "\x1b[36m", gray: "\x1b[90m", dim: "\x1b[2m" };
24
+ const C = { reset: "\\u001b[0m", bold: "\\u001b[1m", red: "\\u001b[31m", green: "\\u001b[32m", yellow: "\\u001b[33m", cyan: "\\u001b[36m", gray: "\\u001b[90m", dim: "\\u001b[2m" };
25
25
  function clr(c, s) {
26
26
  return (process.env.NO_COLOR ? s : ((c + s) + C.reset));
27
27
  }