summit-marker 2.0.0 → 3.0.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "summit-marker",
3
- "version": "2.0.0",
3
+ "version": "3.0.2",
4
4
  "description": "Marker a zero-dependency Chalk alternative for Node.js with terminal colors, chaining, RGB, hex colors, gradients, and styled messages.",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -32,7 +32,7 @@
32
32
  "summit"
33
33
  ],
34
34
  "author": "Summit",
35
- "license": "UNLICENSED",
35
+ "license": "EULA",
36
36
  "scripts": {
37
37
  "test": "node test.js"
38
38
  },
@@ -0,0 +1,16 @@
1
+ export const backgrounds = {
2
+ bgBlack: "\x1b[40m",
3
+ bgRed: "\x1b[41m",
4
+ bgGreen: "\x1b[42m",
5
+ bgYellow: "\x1b[43m",
6
+ bgBlue: "\x1b[44m",
7
+ bgPurple: "\x1b[45m",
8
+ bgCyan: "\x1b[46m",
9
+ bgWhite: "\x1b[47m",
10
+
11
+ bgGray: "\x1b[100m"
12
+ };
13
+
14
+ export function bgRgb(r, g, b) {
15
+ return `\x1b[48;2;${r};${g};${b}m`;
16
+ }
package/src/box.js ADDED
@@ -0,0 +1,73 @@
1
+ export default function box(text, options = {}) {
2
+ const {
3
+ padding = 1,
4
+ border = "single"
5
+ } = options;
6
+
7
+ const borders = {
8
+ single: {
9
+ top: "─",
10
+ bottom: "─",
11
+ left: "│",
12
+ right: "│",
13
+ tl: "┌",
14
+ tr: "┐",
15
+ bl: "└",
16
+ br: "┘"
17
+ },
18
+
19
+ double: {
20
+ top: "═",
21
+ bottom: "═",
22
+ left: "║",
23
+ right: "║",
24
+ tl: "╔",
25
+ tr: "╗",
26
+ bl: "╚",
27
+ br: "╝"
28
+ },
29
+
30
+ round: {
31
+ top: "─",
32
+ bottom: "─",
33
+ left: "│",
34
+ right: "│",
35
+ tl: "╭",
36
+ tr: "╮",
37
+ bl: "╰",
38
+ br: "╯"
39
+ }
40
+ };
41
+
42
+ const style = borders[border] || borders.single;
43
+
44
+ const lines = String(text).split("\n");
45
+
46
+ const width =
47
+ Math.max(...lines.map(line => line.length)) +
48
+ padding * 2;
49
+
50
+ const top =
51
+ style.tl +
52
+ style.top.repeat(width) +
53
+ style.tr;
54
+
55
+ const bottom =
56
+ style.bl +
57
+ style.bottom.repeat(width) +
58
+ style.br;
59
+
60
+ const middle = lines.map(line =>
61
+ style.left +
62
+ " ".repeat(padding) +
63
+ line +
64
+ " ".repeat(width - line.length - padding) +
65
+ style.right
66
+ );
67
+
68
+ return [
69
+ top,
70
+ ...middle,
71
+ bottom
72
+ ].join("\n");
73
+ }
package/src/colors.js CHANGED
@@ -6,7 +6,7 @@ export const colors = {
6
6
  purple: "\x1b[35m",
7
7
  cyan: "\x1b[36m",
8
8
  white: "\x1b[37m",
9
- grey: "\x1b[90m",
9
+ gray: "\x1b[90m",
10
10
  black: "\x1b[30m",
11
11
 
12
12
  orange: "\x1b[38;5;208m",
package/src/errors.js ADDED
@@ -0,0 +1,34 @@
1
+ export default function error(options = {}) {
2
+ const {
3
+ title = "Error",
4
+ message = "",
5
+ code = null,
6
+ details = null
7
+ } = options;
8
+
9
+ let output = [];
10
+
11
+ output.push(
12
+ `✖ ${title}`
13
+ );
14
+
15
+ if (message) {
16
+ output.push(
17
+ `\n${message}`
18
+ );
19
+ }
20
+
21
+ if (code) {
22
+ output.push(
23
+ `\nCode: ${code}`
24
+ );
25
+ }
26
+
27
+ if (details) {
28
+ output.push(
29
+ `\nDetails:\n${details}`
30
+ );
31
+ }
32
+
33
+ return output.join("");
34
+ }
@@ -0,0 +1,84 @@
1
+ // src/gradients.js
2
+
3
+ function createGradient(colors) {
4
+ return (text) => {
5
+ let output = "";
6
+
7
+ for (let i = 0; i < text.length; i++) {
8
+ const color = colors[i % colors.length];
9
+
10
+ output += `\x1b[38;5;${color}m${text[i]}`;
11
+ }
12
+
13
+ return `${output}\x1b[0m`;
14
+ };
15
+ }
16
+
17
+ export const gradients = {
18
+ rainbow: createGradient([
19
+ 196,
20
+ 208,
21
+ 226,
22
+ 46,
23
+ 51,
24
+ 21,
25
+ 129
26
+ ]),
27
+
28
+ sunset: createGradient([
29
+ 129,
30
+ 198,
31
+ 208,
32
+ 226
33
+ ]),
34
+
35
+ ocean: createGradient([
36
+ 51,
37
+ 45,
38
+ 39,
39
+ 33
40
+ ]),
41
+
42
+ fire: createGradient([
43
+ 196,
44
+ 202,
45
+ 208,
46
+ 226
47
+ ]),
48
+
49
+ neon: createGradient([
50
+ 201,
51
+ 207,
52
+ 51,
53
+ 87
54
+ ]),
55
+
56
+ candy: createGradient([
57
+ 213,
58
+ 207,
59
+ 201,
60
+ 51
61
+ ]),
62
+
63
+ forest: createGradient([
64
+ 22,
65
+ 28,
66
+ 34,
67
+ 82
68
+ ]),
69
+
70
+ ice: createGradient([
71
+ 231,
72
+ 195,
73
+ 159,
74
+ 45
75
+ ]),
76
+
77
+ space: createGradient([
78
+ 17,
79
+ 54,
80
+ 93,
81
+ 129,
82
+ 57
83
+ ])
84
+ };
package/src/index.js CHANGED
@@ -1,8 +1,26 @@
1
+ import spinner from "./spinner.js";
2
+ import table from "./table.js";
3
+ import logger from "./logger.js";
4
+ import { createThemes } from "./themes.js";
5
+ import { backgrounds, bgRgb } from "./backgrounds.js";
6
+ import { text } from "./text.js";
7
+ import box from "./box.js";
1
8
  import { colors, styles, rgb, hex } from "./colors.js";
2
9
  import { apply } from "./styles.js";
3
- import { messages } from "./messages.js";
10
+ import { messages, symbols } from "./messages.js";
11
+ import { gradients } from "./gradients.js";
12
+ import { rgbGradient } from "./rgbGradient.js";
4
13
 
5
14
  const marker = {};
15
+ marker.logger = logger;
16
+ marker.table = table;
17
+ marker.spinner = spinner;
18
+
19
+ const chainStyles = {
20
+ ...colors,
21
+ ...styles,
22
+ ...backgrounds
23
+ };
6
24
 
7
25
  function createChain(codes = []) {
8
26
  const builder = (text) => {
@@ -13,10 +31,7 @@ function createChain(codes = []) {
13
31
  return apply(codes, text);
14
32
  };
15
33
 
16
- for (const [name, code] of Object.entries({
17
- ...colors,
18
- ...styles
19
- })) {
34
+ for (const [name, code] of Object.entries(chainStyles)) {
20
35
  Object.defineProperty(builder, name, {
21
36
  get() {
22
37
  return createChain([
@@ -30,10 +45,7 @@ function createChain(codes = []) {
30
45
  return builder;
31
46
  }
32
47
 
33
- for (const [name, code] of Object.entries({
34
- ...colors,
35
- ...styles
36
- })) {
48
+ for (const [name, code] of Object.entries(chainStyles)) {
37
49
  Object.defineProperty(marker, name, {
38
50
  get() {
39
51
  return createChain([code]);
@@ -41,14 +53,32 @@ for (const [name, code] of Object.entries({
41
53
  });
42
54
  }
43
55
 
56
+
57
+ // RGB foreground
44
58
  marker.rgb = (r, g, b) => {
45
- return createChain([rgb(r, g, b)]);
59
+ return createChain([
60
+ rgb(r, g, b)
61
+ ]);
46
62
  };
47
63
 
64
+
65
+ // HEX foreground
48
66
  marker.hex = (value) => {
49
- return createChain([hex(value)]);
67
+ return createChain([
68
+ hex(value)
69
+ ]);
70
+ };
71
+
72
+
73
+ // RGB background
74
+ marker.bgRgb = (r, g, b) => {
75
+ return createChain([
76
+ bgRgb(r, g, b)
77
+ ]);
50
78
  };
51
79
 
80
+
81
+ // 256 color gradient
52
82
  marker.gradient = (text) => {
53
83
  if (marker.level === 0) {
54
84
  return text;
@@ -63,14 +93,42 @@ marker.gradient = (text) => {
63
93
  let output = "";
64
94
 
65
95
  for (let i = 0; i < text.length; i++) {
66
- output += `\x1b[38;5;${palette[i % palette.length]}m${text[i]}`;
96
+ output +=
97
+ `\x1b[38;5;${palette[i % palette.length]}m${text[i]}`;
67
98
  }
68
99
 
69
100
  return `${output}\x1b[0m`;
70
101
  };
71
102
 
103
+
104
+ // True RGB gradient
105
+ marker.rgbGradient = rgbGradient;
106
+
107
+
108
+ // Gradient presets
109
+ marker.gradients = gradients;
110
+
111
+
112
+ // Box formatting
113
+ marker.box = box;
114
+
115
+
116
+ // Messages
72
117
  Object.assign(marker, messages);
73
118
 
119
+
120
+ // Symbols
121
+ marker.symbols = symbols;
122
+
123
+
124
+ // Text utilities
125
+ Object.assign(marker, text);
126
+
127
+
128
+ // Themes
129
+ marker.themes = createThemes(marker);
130
+
131
+
74
132
  function getColorLevel() {
75
133
  if (process.env.NO_COLOR) {
76
134
  return 0;
@@ -91,7 +149,10 @@ function getColorLevel() {
91
149
  return 1;
92
150
  }
93
151
 
152
+
94
153
  marker.level = getColorLevel();
154
+
95
155
  marker.supportsColor = marker.level > 0;
96
156
 
157
+
97
158
  export default marker;
package/src/logger.js ADDED
@@ -0,0 +1,65 @@
1
+ import { symbols } from "./messages.js";
2
+
3
+ function timestamp() {
4
+ return new Date().toLocaleTimeString();
5
+ }
6
+
7
+ function format(level, message, symbol) {
8
+ return `${symbol} [${timestamp()}] ${level}: ${message}`;
9
+ }
10
+
11
+ export const logger = {
12
+ info(message) {
13
+ console.log(
14
+ format(
15
+ "INFO",
16
+ message,
17
+ symbols.info || "ℹ"
18
+ )
19
+ );
20
+ },
21
+
22
+ success(message) {
23
+ console.log(
24
+ format(
25
+ "SUCCESS",
26
+ message,
27
+ symbols.success || "✔"
28
+ )
29
+ );
30
+ },
31
+
32
+ warn(message) {
33
+ console.log(
34
+ format(
35
+ "WARN",
36
+ message,
37
+ symbols.warning || "⚠"
38
+ )
39
+ );
40
+ },
41
+
42
+ error(message) {
43
+ console.log(
44
+ format(
45
+ "ERROR",
46
+ message,
47
+ symbols.error || "✖"
48
+ )
49
+ );
50
+ },
51
+
52
+ debug(message) {
53
+ if (process.env.MARKER_DEBUG) {
54
+ console.log(
55
+ format(
56
+ "DEBUG",
57
+ message,
58
+ "🐛"
59
+ )
60
+ );
61
+ }
62
+ }
63
+ };
64
+
65
+ export default logger;
package/src/messages.js CHANGED
@@ -1,20 +1,55 @@
1
1
  import { colors } from "./colors.js";
2
2
  import { apply } from "./styles.js";
3
3
 
4
+ export const symbols = {
5
+ success: "✔",
6
+ error: "✖",
7
+ warning: "⚠",
8
+ info: "ℹ",
9
+
10
+ check: "✓",
11
+ cross: "✗",
12
+
13
+ bullet: "•",
14
+ dot: "·",
15
+
16
+ arrowRight: "→",
17
+ arrowLeft: "←",
18
+ arrowUp: "↑",
19
+ arrowDown: "↓",
20
+
21
+ plus: "+",
22
+ minus: "-",
23
+ star: "*",
24
+
25
+ pointer: ">",
26
+ pipe: "|",
27
+
28
+ loading: "⟳",
29
+
30
+ progress: "#",
31
+ empty: "-",
32
+
33
+ block: "█",
34
+ lightBlock: "░",
35
+ mediumBlock: "▒",
36
+ darkBlock: "▓"
37
+ };
38
+
4
39
  export const messages = {
5
40
  success(text) {
6
- return apply(colors.green, `✔ ${text}`);
41
+ return apply(colors.green, `${symbols.success} ${text}`);
7
42
  },
8
43
 
9
44
  error(text) {
10
- return apply(colors.red, `✖ ${text}`);
45
+ return apply(colors.red, `${symbols.error} ${text}`);
11
46
  },
12
47
 
13
48
  warning(text) {
14
- return apply(colors.yellow, `⚠ ${text}`);
49
+ return apply(colors.yellow, `${symbols.warning} ${text}`);
15
50
  },
16
51
 
17
52
  info(text) {
18
- return apply(colors.blue, `ℹ ${text}`);
53
+ return apply(colors.blue, `${symbols.info} ${text}`);
19
54
  }
20
55
  };
@@ -0,0 +1,67 @@
1
+ export function progress(options = {}) {
2
+ const {
3
+ total = 100,
4
+ label = "Progress",
5
+ width = 20
6
+ } = options;
7
+
8
+ let current = 0;
9
+ let finished = false;
10
+
11
+ function render() {
12
+ if (finished) return;
13
+
14
+ const percent = Math.min(
15
+ Math.floor((current / total) * 100),
16
+ 100
17
+ );
18
+
19
+ const filled = Math.floor(
20
+ (percent / 100) * width
21
+ );
22
+
23
+ const empty = width - filled;
24
+
25
+ const bar =
26
+ "█".repeat(filled) +
27
+ "░".repeat(empty);
28
+
29
+ process.stdout.write(
30
+ `\r${label} ${bar} ${current}/${total} ${percent}%`
31
+ );
32
+ }
33
+
34
+ function update(value) {
35
+ current = Math.min(value, total);
36
+ render();
37
+
38
+ if (current >= total) {
39
+ complete();
40
+ }
41
+ }
42
+
43
+ function increment(amount = 1) {
44
+ update(current + amount);
45
+ }
46
+
47
+ function complete() {
48
+ current = total;
49
+ render();
50
+ process.stdout.write("\n");
51
+ finished = true;
52
+ }
53
+
54
+ function stop() {
55
+ process.stdout.write("\n");
56
+ finished = true;
57
+ }
58
+
59
+ render();
60
+
61
+ return {
62
+ update,
63
+ increment,
64
+ complete,
65
+ stop
66
+ };
67
+ }
@@ -0,0 +1,48 @@
1
+ // src/rgbGradient.js
2
+
3
+ function interpolate(start, end, factor) {
4
+ return Math.round(
5
+ start + (end - start) * factor
6
+ );
7
+ }
8
+
9
+ function rgbCode(r, g, b) {
10
+ return `\x1b[38;2;${r};${g};${b}m`;
11
+ }
12
+
13
+ export function rgbGradient(start, end) {
14
+ return (text) => {
15
+ let output = "";
16
+
17
+ for (let i = 0; i < text.length; i++) {
18
+ const factor =
19
+ text.length <= 1
20
+ ? 0
21
+ : i / (text.length - 1);
22
+
23
+ const r = interpolate(
24
+ start[0],
25
+ end[0],
26
+ factor
27
+ );
28
+
29
+ const g = interpolate(
30
+ start[1],
31
+ end[1],
32
+ factor
33
+ );
34
+
35
+ const b = interpolate(
36
+ start[2],
37
+ end[2],
38
+ factor
39
+ );
40
+
41
+ output +=
42
+ rgbCode(r, g, b) +
43
+ text[i];
44
+ }
45
+
46
+ return `${output}\x1b[0m`;
47
+ };
48
+ }
package/src/spinner.js ADDED
@@ -0,0 +1,83 @@
1
+ const frames = [
2
+ "⠋",
3
+ "⠙",
4
+ "⠹",
5
+ "⠸",
6
+ "⠼",
7
+ "⠴",
8
+ "⠦",
9
+ "⠧",
10
+ "⠇",
11
+ "⠏"
12
+ ];
13
+
14
+ export default function spinner(message = "Loading") {
15
+ let interval = null;
16
+ let index = 0;
17
+ let active = false;
18
+
19
+ function render(frame) {
20
+ process.stdout.write(
21
+ `\r${frame} ${message}`
22
+ );
23
+ }
24
+
25
+ return {
26
+
27
+ start() {
28
+ if (active) return;
29
+
30
+ active = true;
31
+
32
+ interval = setInterval(() => {
33
+ render(frames[index]);
34
+
35
+ index++;
36
+
37
+ if (index >= frames.length) {
38
+ index = 0;
39
+ }
40
+
41
+ }, 80);
42
+ },
43
+
44
+
45
+ stop(finalMessage = message) {
46
+ if (!active) return;
47
+
48
+ clearInterval(interval);
49
+ interval = null;
50
+ active = false;
51
+
52
+ process.stdout.write(
53
+ `\r ${finalMessage}\n`
54
+ );
55
+ },
56
+
57
+
58
+ success(finalMessage = "Done") {
59
+ if (interval) {
60
+ clearInterval(interval);
61
+ }
62
+
63
+ active = false;
64
+
65
+ process.stdout.write(
66
+ `\r✔ ${finalMessage}\n`
67
+ );
68
+ },
69
+
70
+
71
+ error(finalMessage = "Failed") {
72
+ if (interval) {
73
+ clearInterval(interval);
74
+ }
75
+
76
+ active = false;
77
+
78
+ process.stdout.write(
79
+ `\r✖ ${finalMessage}\n`
80
+ );
81
+ }
82
+ };
83
+ }