ansimax 1.2.0 → 1.2.2

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/CHANGELOG.md CHANGED
@@ -3,6 +3,68 @@
3
3
  All notable changes to **ansimax** are documented in this file.
4
4
  This project follows [Semantic Versioning](https://semver.org/).
5
5
 
6
+ ## [1.2.2] — Quality polish
7
+
8
+ Patch release focused on API ergonomics and robustness refinements. No
9
+ breaking changes — every 1.2.x program runs identically.
10
+
11
+ ### Improved
12
+
13
+ - **`animateGradient` controller is now thenable** — you can `await` it
14
+ directly instead of `await ctrl.done`:
15
+
16
+ ```ts
17
+ // Before (v1.2.0)
18
+ const ctrl = animateGradient(text, stops, { infinite: false, cycles: 1 });
19
+ await ctrl.done;
20
+
21
+ // After (v1.2.2) — both still work
22
+ await animateGradient(text, stops, { infinite: false, cycles: 1 });
23
+
24
+ // Also supports .then() / .catch() / .finally()
25
+ animateGradient(text, stops, opts).finally(() => cleanup());
26
+ ```
27
+
28
+ The `.done` property remains for backwards compatibility.
29
+
30
+ - **Stable error codes for programmatic catch.** Errors thrown by the
31
+ theme system now carry a `.code` property with the `ANSIMAX_*` prefix
32
+ for stable programmatic filtering:
33
+
34
+ ```ts
35
+ try {
36
+ themes.use('not-a-real-theme');
37
+ } catch (e) {
38
+ if ((e as { code?: string }).code === 'ANSIMAX_UNKNOWN_THEME') {
39
+ // handle gracefully
40
+ }
41
+ }
42
+ ```
43
+
44
+ New codes: `ANSIMAX_INVALID_THEME`, `ANSIMAX_INVALID_THEME_NAME`,
45
+ `ANSIMAX_UNKNOWN_THEME`. Error messages and types
46
+ (`TypeError` / `RangeError`) are unchanged.
47
+
48
+ - **`animateGradient` is safer in sandboxed environments.** The default
49
+ stdout-write path now checks `process?.stdout?.write` before calling
50
+ it, so the function no longer crashes in workers, Edge runtimes, or
51
+ embedded sandboxes that lack a writable stdout.
52
+
53
+ - **Better JSDoc on the `gradient()` function.** IntelliSense now shows
54
+ parameter descriptions, return semantics, and three runnable
55
+ `@example` blocks (basic, with easing, with phase animation).
56
+
57
+ - **README fix: `Easing Curves` snippet.** The v1.2.0 snippet was missing
58
+ the `stops` variable declaration. Now copy-paste runnable.
59
+
60
+ ### Notes
61
+
62
+ - 1880 + 7 new tests pass.
63
+ - No new dependencies — still zero runtime deps.
64
+ - All API additions are non-breaking and side-effect-free for existing code.
65
+
66
+ ---
67
+
6
68
  ## [1.2.0] — Phase 2 complete: animated, eased & conic gradients
7
69
 
8
70
  Minor release closing the **gradient engine roadmap (Phase 2)** with three
package/README.es.md CHANGED
@@ -7,7 +7,7 @@
7
7
  _Colores • Gradientes • Animaciones • ASCII Art • Pixel Art • Árboles • Componentes • Temas_
8
8
 
9
9
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square)](LICENSE)
10
- [![npm](https://img.shields.io/badge/npm-v1.2.0-cb3837.svg?style=flat-square)](https://www.npmjs.com/package/ansimax)
10
+ [![npm](https://img.shields.io/badge/npm-v1.2.2-cb3837.svg?style=flat-square)](https://www.npmjs.com/package/ansimax)
11
11
  [![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178c6.svg?style=flat-square)](tsconfig.json)
12
12
  [![Coverage](https://img.shields.io/badge/coverage-98%25-brightgreen.svg?style=flat-square)](#testing)
13
13
  [![Tests](https://img.shields.io/badge/tests-1700%2B%20passing-brightgreen.svg?style=flat-square)](#testing)
@@ -216,26 +216,37 @@ const ctrl = animateGradient('Cargando...', ['#ff79c6', '#bd93f9', '#8be9fd'], {
216
216
 
217
217
  await sleep(3000);
218
218
  ctrl.stop();
219
+
220
+ // v1.2.2: await directo (no se necesita .done)
221
+ await animateGradient('¡Listo!', ['#50fa7b', '#bd93f9'], {
222
+ infinite: false, cycles: 2, duration: 800,
223
+ });
219
224
  ```
220
225
 
221
226
  ### Curvas de interpolación (v1.2.0)
222
227
 
228
+ <img src="media/easing_curves.png" alt="Colors and gradients" />
229
+
223
230
  ```ts
224
231
  import { gradient } from 'ansimax';
225
232
 
233
+ const stops = ['#ff79c6', '#bd93f9', '#8be9fd'];
234
+
226
235
  // Cinco easings built-in + soporte para funciones personalizadas
227
- gradient('hola mundo', stops, { easing: 'linear' });
228
- gradient('hola mundo', stops, { easing: 'ease-in' });
229
- gradient('hola mundo', stops, { easing: 'ease-out' });
230
- gradient('hola mundo', stops, { easing: 'ease-in-out' });
231
- gradient('hola mundo', stops, { easing: 'cubic-bezier' });
236
+ console.log(gradient('hola mundo', stops, { easing: 'linear' }));
237
+ console.log(gradient('hola mundo', stops, { easing: 'ease-in' }));
238
+ console.log(gradient('hola mundo', stops, { easing: 'ease-out' }));
239
+ console.log(gradient('hola mundo', stops, { easing: 'ease-in-out' }));
240
+ console.log(gradient('hola mundo', stops, { easing: 'cubic-bezier' }));
232
241
 
233
242
  // O tu propia función de easing (t → t suavizado, ambos en [0,1])
234
- gradient('hola mundo', stops, { easing: (t) => t * t * t });
243
+ console.log(gradient('hola mundo', stops, { easing: (t) => t * t * t }));
235
244
  ```
236
245
 
237
246
  ### Gradientes cónicos (v1.2.0)
238
247
 
248
+ <img src="media/conic_gradients.png" alt="Colors and gradients" />
249
+
239
250
  ```ts
240
251
  import { gradientRect } from 'ansimax';
241
252
 
@@ -324,7 +335,7 @@ console.log(components.table([
324
335
  ['loaders', color.green('● listo'), '100%'],
325
336
  ], { borderStyle: 'rounded' }));
326
337
 
327
- console.log(components.badge('VERSION', 'v1.2.0'));
338
+ console.log(components.badge('VERSION', 'v1.2.2'));
328
339
  console.log(components.badge('BUILD', 'passing'));
329
340
  ```
330
341
 
@@ -726,6 +737,18 @@ ansimax/
726
737
 
727
738
  ## 📝 Changelog
728
739
 
740
+ ### v1.2.2 — Pulido de calidad
741
+
742
+ Release patch enfocado en ergonomía de API y refinamientos de robustez.
743
+
744
+ - ✨ **`animateGradient` ahora es thenable** — `await animateGradient(...)` directo sin `.done`
745
+ - 🎯 **Códigos de error estables** — los errores de tema llevan propiedad `.code` (`ANSIMAX_UNKNOWN_THEME`, etc.) para `catch` programático
746
+ - 🛡️ **Seguridad en sandboxes** — `animateGradient` ya no crashea cuando `process.stdout` no está disponible (workers, edge runtimes)
747
+ - 📖 **Mejor JSDoc** — `gradient()` ahora muestra IntelliSense completo con ejemplos
748
+ - 🐛 **Fix de README** — snippet de Easing Curves ahora es ejecutable copy-paste
749
+
750
+ Drop-in replacement para `1.2.0`.
751
+
729
752
  ### v1.2.0 — Fase 2 completa: gradientes animados, easing y cónicos
730
753
 
731
754
  Release minor que cierra el roadmap del motor de gradientes con tres features potentes:
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  _Colors • Gradients • Animations • ASCII Art • Pixel Art • Trees • Components • Themes_
8
8
 
9
9
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square)](LICENSE)
10
- [![npm](https://img.shields.io/badge/npm-v1.2.0-cb3837.svg?style=flat-square)](https://www.npmjs.com/package/ansimax)
10
+ [![npm](https://img.shields.io/badge/npm-v1.2.2-cb3837.svg?style=flat-square)](https://www.npmjs.com/package/ansimax)
11
11
  [![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178c6.svg?style=flat-square)](tsconfig.json)
12
12
  [![Coverage](https://img.shields.io/badge/coverage-98%25-brightgreen.svg?style=flat-square)](#testing)
13
13
  [![Tests](https://img.shields.io/badge/tests-1700%2B%20passing-brightgreen.svg?style=flat-square)](#testing)
@@ -216,26 +216,37 @@ const ctrl = animateGradient('Loading...', ['#ff79c6', '#bd93f9', '#8be9fd'], {
216
216
 
217
217
  await sleep(3000);
218
218
  ctrl.stop();
219
+
220
+ // v1.2.2: await directly (no .done needed)
221
+ await animateGradient('Done!', ['#50fa7b', '#bd93f9'], {
222
+ infinite: false, cycles: 2, duration: 800,
223
+ });
219
224
  ```
220
225
 
221
226
  ### Easing Curves (v1.2.0)
222
227
 
228
+ <img src="media/easing_curves.png" alt="Colors and gradients" />
229
+
223
230
  ```ts
224
231
  import { gradient } from 'ansimax';
225
232
 
233
+ const stops = ['#ff79c6', '#bd93f9', '#8be9fd'];
234
+
226
235
  // Five built-in easings + custom function support
227
- gradient('hello world', stops, { easing: 'linear' });
228
- gradient('hello world', stops, { easing: 'ease-in' });
229
- gradient('hello world', stops, { easing: 'ease-out' });
230
- gradient('hello world', stops, { easing: 'ease-in-out' });
231
- gradient('hello world', stops, { easing: 'cubic-bezier' });
236
+ console.log(gradient('hello world', stops, { easing: 'linear' }));
237
+ console.log(gradient('hello world', stops, { easing: 'ease-in' }));
238
+ console.log(gradient('hello world', stops, { easing: 'ease-out' }));
239
+ console.log(gradient('hello world', stops, { easing: 'ease-in-out' }));
240
+ console.log(gradient('hello world', stops, { easing: 'cubic-bezier' }));
232
241
 
233
242
  // Or pass your own easing function (t → eased t, both in [0,1])
234
- gradient('hello world', stops, { easing: (t) => t * t * t });
243
+ console.log(gradient('hello world', stops, { easing: (t) => t * t * t }));
235
244
  ```
236
245
 
237
246
  ### Conic Gradients (v1.2.0)
238
247
 
248
+ <img src="media/conic_gradients.png" alt="Colors and gradients" />
249
+
239
250
  ```ts
240
251
  import { gradientRect } from 'ansimax';
241
252
 
@@ -324,7 +335,7 @@ console.log(components.table([
324
335
  ['loaders', color.green('● ready'), '100%'],
325
336
  ], { borderStyle: 'rounded' }));
326
337
 
327
- console.log(components.badge('VERSION', 'v1.2.0'));
338
+ console.log(components.badge('VERSION', 'v1.2.2'));
328
339
  console.log(components.badge('BUILD', 'passing'));
329
340
  ```
330
341
 
@@ -726,6 +737,18 @@ ansimax/
726
737
 
727
738
  ## 📝 Changelog
728
739
 
740
+ ### v1.2.2 — Quality polish
741
+
742
+ Patch release focused on API ergonomics and robustness refinements.
743
+
744
+ - ✨ **`animateGradient` is now thenable** — `await animateGradient(...)` directly without `.done`
745
+ - 🎯 **Stable error codes** — theme errors carry `.code` properties (`ANSIMAX_UNKNOWN_THEME`, etc.) for programmatic catch
746
+ - 🛡️ **Sandbox safety** — `animateGradient` no longer crashes when `process.stdout` is unavailable (workers, edge runtimes)
747
+ - 📖 **Better JSDoc** — `gradient()` now shows full IntelliSense with examples
748
+ - 🐛 **README fix** — Easing Curves snippet now copy-paste runnable
749
+
750
+ Drop-in replacement for `1.2.0`.
751
+
729
752
  ### v1.2.0 — Phase 2 complete: animated, eased & conic gradients
730
753
 
731
754
  Minor release closing the gradient engine roadmap with three powerful features:
package/dist/index.d.mts CHANGED
@@ -565,6 +565,38 @@ interface GradientOptions {
565
565
  */
566
566
  phase?: number;
567
567
  }
568
+ /**
569
+ * Apply a multi-stop color gradient across the visible characters of `text`.
570
+ * ANSI escapes are skipped, and Unicode wide characters / graphemes are
571
+ * counted correctly.
572
+ *
573
+ * @param text - The text to colorize. Non-string inputs are coerced via `String(text)`.
574
+ * @param stops - Array of hex colors (`#rgb` or `#rrggbb`). At least 1 required.
575
+ * Invalid stops are silently dropped; an empty array returns input as-is.
576
+ * @param opts - Optional configuration. See `GradientOptions`.
577
+ *
578
+ * @returns ANSI-colorized string. Returns input unchanged if `NO_COLOR` is set
579
+ * or if no valid stops are provided.
580
+ *
581
+ * @example
582
+ * ```ts
583
+ * gradient('Hello world!', ['#ff0000', '#00ff00', '#0000ff']);
584
+ * // → ANSI-colored "Hello world!" with smooth color transition
585
+ * ```
586
+ *
587
+ * @example with easing curve
588
+ * ```ts
589
+ * gradient('Smooth text', ['#ff79c6', '#8be9fd'], { easing: 'ease-in-out' });
590
+ * ```
591
+ *
592
+ * @example animated phase shift
593
+ * ```ts
594
+ * setInterval(() => {
595
+ * const phase = (Date.now() / 1000) % 1;
596
+ * process.stdout.write('\r' + gradient('flowing', ['#f00', '#00f'], { phase }));
597
+ * }, 33);
598
+ * ```
599
+ */
568
600
  declare const gradient: (text: unknown, stops: string[] | null | undefined, opts?: GradientOptions) => string;
569
601
  declare const rainbow: ColorFn;
570
602
  interface AnimateGradientOptions {
@@ -614,6 +646,15 @@ interface AnimateGradientController {
614
646
  stop: () => void;
615
647
  /** Promise that resolves when animation finishes (stop / abort / cycle limit). */
616
648
  done: Promise<void>;
649
+ /**
650
+ * Thenable hook — lets you `await animateGradient(...)` directly.
651
+ * Equivalent to `await ctrl.done`.
652
+ */
653
+ then: Promise<void>['then'];
654
+ /** Equivalent to `ctrl.done.catch(...)`. */
655
+ catch: Promise<void>['catch'];
656
+ /** Equivalent to `ctrl.done.finally(...)`. */
657
+ finally: Promise<void>['finally'];
617
658
  }
618
659
  declare const animateGradient: (text: string, stops: string[], opts?: AnimateGradientOptions) => AnimateGradientController;
619
660
  declare const PRESET_DEFS: {
package/dist/index.d.ts CHANGED
@@ -565,6 +565,38 @@ interface GradientOptions {
565
565
  */
566
566
  phase?: number;
567
567
  }
568
+ /**
569
+ * Apply a multi-stop color gradient across the visible characters of `text`.
570
+ * ANSI escapes are skipped, and Unicode wide characters / graphemes are
571
+ * counted correctly.
572
+ *
573
+ * @param text - The text to colorize. Non-string inputs are coerced via `String(text)`.
574
+ * @param stops - Array of hex colors (`#rgb` or `#rrggbb`). At least 1 required.
575
+ * Invalid stops are silently dropped; an empty array returns input as-is.
576
+ * @param opts - Optional configuration. See `GradientOptions`.
577
+ *
578
+ * @returns ANSI-colorized string. Returns input unchanged if `NO_COLOR` is set
579
+ * or if no valid stops are provided.
580
+ *
581
+ * @example
582
+ * ```ts
583
+ * gradient('Hello world!', ['#ff0000', '#00ff00', '#0000ff']);
584
+ * // → ANSI-colored "Hello world!" with smooth color transition
585
+ * ```
586
+ *
587
+ * @example with easing curve
588
+ * ```ts
589
+ * gradient('Smooth text', ['#ff79c6', '#8be9fd'], { easing: 'ease-in-out' });
590
+ * ```
591
+ *
592
+ * @example animated phase shift
593
+ * ```ts
594
+ * setInterval(() => {
595
+ * const phase = (Date.now() / 1000) % 1;
596
+ * process.stdout.write('\r' + gradient('flowing', ['#f00', '#00f'], { phase }));
597
+ * }, 33);
598
+ * ```
599
+ */
568
600
  declare const gradient: (text: unknown, stops: string[] | null | undefined, opts?: GradientOptions) => string;
569
601
  declare const rainbow: ColorFn;
570
602
  interface AnimateGradientOptions {
@@ -614,6 +646,15 @@ interface AnimateGradientController {
614
646
  stop: () => void;
615
647
  /** Promise that resolves when animation finishes (stop / abort / cycle limit). */
616
648
  done: Promise<void>;
649
+ /**
650
+ * Thenable hook — lets you `await animateGradient(...)` directly.
651
+ * Equivalent to `await ctrl.done`.
652
+ */
653
+ then: Promise<void>['then'];
654
+ /** Equivalent to `ctrl.done.catch(...)`. */
655
+ catch: Promise<void>['catch'];
656
+ /** Equivalent to `ctrl.done.finally(...)`. */
657
+ finally: Promise<void>['finally'];
617
658
  }
618
659
  declare const animateGradient: (text: string, stops: string[], opts?: AnimateGradientOptions) => AnimateGradientController;
619
660
  declare const PRESET_DEFS: {
package/dist/index.js CHANGED
@@ -1273,7 +1273,13 @@ var animateGradient = (text, stops, opts = {}) => {
1273
1273
  if (signal) {
1274
1274
  if (signal.aborted) {
1275
1275
  stop();
1276
- return { stop, done };
1276
+ return {
1277
+ stop,
1278
+ done,
1279
+ then: done.then.bind(done),
1280
+ catch: done.catch.bind(done),
1281
+ finally: done.finally.bind(done)
1282
+ };
1277
1283
  }
1278
1284
  signal.addEventListener("abort", stop, { once: true });
1279
1285
  }
@@ -1288,7 +1294,9 @@ var animateGradient = (text, stops, opts = {}) => {
1288
1294
  onFrame(frame, phase);
1289
1295
  } else {
1290
1296
  try {
1291
- process.stdout.write("\r" + frame);
1297
+ if (process?.stdout?.write) {
1298
+ process.stdout.write("\r" + frame);
1299
+ }
1292
1300
  } catch {
1293
1301
  }
1294
1302
  }
@@ -1303,7 +1311,14 @@ var animateGradient = (text, stops, opts = {}) => {
1303
1311
  if (!stopped) {
1304
1312
  timer = setInterval(renderFrame, frameInterval2);
1305
1313
  }
1306
- return { stop, done };
1314
+ return {
1315
+ stop,
1316
+ done,
1317
+ // Thenable hooks — bind to done so `await ctrl` works directly
1318
+ then: done.then.bind(done),
1319
+ catch: done.catch.bind(done),
1320
+ finally: done.finally.bind(done)
1321
+ };
1307
1322
  };
1308
1323
  var PRESET_DEFS = {
1309
1324
  sunset: ["#ff6b6b", "#feca57", "#48dbfb"],
@@ -4222,13 +4237,18 @@ var STYLE_NAMES = [
4222
4237
  "muted",
4223
4238
  "text"
4224
4239
  ];
4240
+ var _themeError = (Ctor, code, message) => {
4241
+ const err = new Ctor(message);
4242
+ err.code = code;
4243
+ return err;
4244
+ };
4225
4245
  var validateTheme = (t) => {
4226
4246
  if (typeof t !== "object" || t === null || Array.isArray(t)) {
4227
- throw new TypeError("Theme must be a non-null object.");
4247
+ throw _themeError(TypeError, "ANSIMAX_INVALID_THEME", "Theme must be a non-null object.");
4228
4248
  }
4229
4249
  const obj = t;
4230
4250
  if (typeof obj.name !== "string" || obj.name.length === 0) {
4231
- throw new TypeError('Theme must have a non-empty "name" string.');
4251
+ throw _themeError(TypeError, "ANSIMAX_INVALID_THEME_NAME", 'Theme must have a non-empty "name" string.');
4232
4252
  }
4233
4253
  for (const key of REQUIRED_COLOR_KEYS) {
4234
4254
  const value = obj[key];
@@ -4567,7 +4587,9 @@ var themes = {
4567
4587
  use(name) {
4568
4588
  const t = _globalRegistry.get(name);
4569
4589
  if (!t) {
4570
- throw new RangeError(
4590
+ throw _themeError(
4591
+ RangeError,
4592
+ "ANSIMAX_UNKNOWN_THEME",
4571
4593
  `Theme "${name}" not found. Available themes: ${[..._globalRegistry.keys()].join(", ")}`
4572
4594
  );
4573
4595
  }
package/dist/index.mjs CHANGED
@@ -1100,7 +1100,13 @@ var animateGradient = (text, stops, opts = {}) => {
1100
1100
  if (signal) {
1101
1101
  if (signal.aborted) {
1102
1102
  stop();
1103
- return { stop, done };
1103
+ return {
1104
+ stop,
1105
+ done,
1106
+ then: done.then.bind(done),
1107
+ catch: done.catch.bind(done),
1108
+ finally: done.finally.bind(done)
1109
+ };
1104
1110
  }
1105
1111
  signal.addEventListener("abort", stop, { once: true });
1106
1112
  }
@@ -1115,7 +1121,9 @@ var animateGradient = (text, stops, opts = {}) => {
1115
1121
  onFrame(frame, phase);
1116
1122
  } else {
1117
1123
  try {
1118
- process.stdout.write("\r" + frame);
1124
+ if (process?.stdout?.write) {
1125
+ process.stdout.write("\r" + frame);
1126
+ }
1119
1127
  } catch {
1120
1128
  }
1121
1129
  }
@@ -1130,7 +1138,14 @@ var animateGradient = (text, stops, opts = {}) => {
1130
1138
  if (!stopped) {
1131
1139
  timer = setInterval(renderFrame, frameInterval2);
1132
1140
  }
1133
- return { stop, done };
1141
+ return {
1142
+ stop,
1143
+ done,
1144
+ // Thenable hooks — bind to done so `await ctrl` works directly
1145
+ then: done.then.bind(done),
1146
+ catch: done.catch.bind(done),
1147
+ finally: done.finally.bind(done)
1148
+ };
1134
1149
  };
1135
1150
  var PRESET_DEFS = {
1136
1151
  sunset: ["#ff6b6b", "#feca57", "#48dbfb"],
@@ -4049,13 +4064,18 @@ var STYLE_NAMES = [
4049
4064
  "muted",
4050
4065
  "text"
4051
4066
  ];
4067
+ var _themeError = (Ctor, code, message) => {
4068
+ const err = new Ctor(message);
4069
+ err.code = code;
4070
+ return err;
4071
+ };
4052
4072
  var validateTheme = (t) => {
4053
4073
  if (typeof t !== "object" || t === null || Array.isArray(t)) {
4054
- throw new TypeError("Theme must be a non-null object.");
4074
+ throw _themeError(TypeError, "ANSIMAX_INVALID_THEME", "Theme must be a non-null object.");
4055
4075
  }
4056
4076
  const obj = t;
4057
4077
  if (typeof obj.name !== "string" || obj.name.length === 0) {
4058
- throw new TypeError('Theme must have a non-empty "name" string.');
4078
+ throw _themeError(TypeError, "ANSIMAX_INVALID_THEME_NAME", 'Theme must have a non-empty "name" string.');
4059
4079
  }
4060
4080
  for (const key of REQUIRED_COLOR_KEYS) {
4061
4081
  const value = obj[key];
@@ -4394,7 +4414,9 @@ var themes = {
4394
4414
  use(name) {
4395
4415
  const t = _globalRegistry.get(name);
4396
4416
  if (!t) {
4397
- throw new RangeError(
4417
+ throw _themeError(
4418
+ RangeError,
4419
+ "ANSIMAX_UNKNOWN_THEME",
4398
4420
  `Theme "${name}" not found. Available themes: ${[..._globalRegistry.keys()].join(", ")}`
4399
4421
  );
4400
4422
  }
@@ -118,7 +118,7 @@ async function main() {
118
118
  console.log(components.section('🏷️ Badges & Status', { width: 60 }));
119
119
  console.log();
120
120
  console.log(' ',
121
- components.badge('VERSION', 'v1.2.0'),
121
+ components.badge('VERSION', 'v1.2.2'),
122
122
  components.badge('BUILD', 'passing'),
123
123
  components.badge('LICENSE', 'Apache 2.0'));
124
124
  console.log();
@@ -117,7 +117,7 @@ console.log();
117
117
  console.log(components.section('🏷️ Badges & Status', { width: 60 }));
118
118
  console.log();
119
119
  console.log(' ',
120
- components.badge('VERSION', 'v1.2.0'),
120
+ components.badge('VERSION', 'v1.2.2'),
121
121
  components.badge('BUILD', 'passing'),
122
122
  components.badge('LICENSE', 'Apache 2.0'));
123
123
  console.log();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ansimax",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "Zero-dependency CLI rendering library: colors, gradients, animations, ASCII art, pixel art, components, and themes \u2014 all in TypeScript.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",