@socketsecurity/lib 1.0.5 → 1.1.1
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 +25 -0
- package/dist/arrays.d.ts +143 -0
- package/dist/arrays.js.map +2 -2
- package/dist/effects/text-shimmer.js +2 -1
- package/dist/effects/text-shimmer.js.map +2 -2
- package/dist/fs.d.ts +595 -23
- package/dist/fs.js.map +2 -2
- package/dist/git.d.ts +488 -41
- package/dist/git.js.map +2 -2
- package/dist/github.d.ts +361 -12
- package/dist/github.js.map +2 -2
- package/dist/http-request.d.ts +463 -4
- package/dist/http-request.js.map +2 -2
- package/dist/json.d.ts +177 -4
- package/dist/json.js.map +2 -2
- package/dist/logger.d.ts +822 -67
- package/dist/logger.js +653 -46
- package/dist/logger.js.map +2 -2
- package/dist/objects.d.ts +386 -10
- package/dist/objects.js.map +2 -2
- package/dist/path.d.ts +270 -6
- package/dist/path.js.map +2 -2
- package/dist/promises.d.ts +432 -27
- package/dist/promises.js.map +2 -2
- package/dist/spawn.d.ts +239 -12
- package/dist/spawn.js.map +2 -2
- package/dist/spinner.d.ts +260 -20
- package/dist/spinner.js +201 -63
- package/dist/spinner.js.map +2 -2
- package/dist/stdio/clear.d.ts +130 -9
- package/dist/stdio/clear.js.map +2 -2
- package/dist/stdio/divider.d.ts +106 -10
- package/dist/stdio/divider.js +10 -0
- package/dist/stdio/divider.js.map +2 -2
- package/dist/stdio/footer.d.ts +70 -3
- package/dist/stdio/footer.js.map +2 -2
- package/dist/stdio/header.d.ts +93 -12
- package/dist/stdio/header.js.map +2 -2
- package/dist/stdio/mask.d.ts +82 -14
- package/dist/stdio/mask.js +25 -4
- package/dist/stdio/mask.js.map +2 -2
- package/dist/stdio/progress.d.ts +112 -15
- package/dist/stdio/progress.js +43 -3
- package/dist/stdio/progress.js.map +2 -2
- package/dist/stdio/prompts.d.ts +95 -5
- package/dist/stdio/prompts.js.map +2 -2
- package/dist/stdio/stderr.d.ts +114 -11
- package/dist/stdio/stderr.js.map +2 -2
- package/dist/stdio/stdout.d.ts +107 -11
- package/dist/stdio/stdout.js.map +2 -2
- package/dist/strings.d.ts +357 -28
- package/dist/strings.js.map +2 -2
- package/dist/validation/json-parser.d.ts +226 -7
- package/dist/validation/json-parser.js.map +2 -2
- package/dist/validation/types.d.ts +114 -8
- package/dist/validation/types.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,31 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.1.1] - 2025-10-23
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- Fixed shimmer text effects not respecting CI environment detection (now disabled in CI to prevent ANSI escape codes in logs)
|
|
13
|
+
|
|
14
|
+
## [1.1.0] - 2025-10-23
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- Added `filterOutput` option to `stdio/mask` for filtering output chunks before display/buffering
|
|
19
|
+
- Added `overrideExitCode` option to `stdio/mask` for customizing exit codes based on captured output
|
|
20
|
+
- Added comprehensive JSDoc documentation across entire library for enhanced VSCode IntelliSense
|
|
21
|
+
- Detailed @param, @returns, @template, @throws tags
|
|
22
|
+
- Practical @example blocks with real-world usage patterns
|
|
23
|
+
- @default tags showing default values
|
|
24
|
+
- Enhanced interface property documentation
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- Improved TypeScript type hints and tooltips throughout library
|
|
29
|
+
- Enhanced documentation for all core utilities (arrays, fs, git, github, http-request, json, logger, objects, path, promises, spawn, spinner, strings)
|
|
30
|
+
- Enhanced documentation for stdio utilities (clear, divider, footer, header, mask, progress, prompts, stderr, stdout)
|
|
31
|
+
- Enhanced documentation for validation utilities (json-parser, types)
|
|
32
|
+
|
|
8
33
|
## [1.0.5] - 2025-10-22
|
|
9
34
|
|
|
10
35
|
### Added
|
package/dist/arrays.d.ts
CHANGED
|
@@ -1,10 +1,63 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Split an array into chunks of a specified size.
|
|
3
|
+
*
|
|
4
|
+
* Divides an array into smaller arrays of the specified chunk size.
|
|
5
|
+
* The last chunk may contain fewer elements if the array length is not
|
|
6
|
+
* evenly divisible by the chunk size.
|
|
7
|
+
*
|
|
8
|
+
* @param arr - The array to split into chunks (can be readonly)
|
|
9
|
+
* @param size - Size of each chunk. Must be greater than 0.
|
|
10
|
+
* @default 2
|
|
11
|
+
* @returns Array of chunks, where each chunk is an array of elements
|
|
12
|
+
* @throws {Error} If chunk size is less than or equal to 0
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* // Split into pairs (default)
|
|
17
|
+
* arrayChunk([1, 2, 3, 4, 5])
|
|
18
|
+
* // Returns: [[1, 2], [3, 4], [5]]
|
|
19
|
+
*
|
|
20
|
+
* // Split into groups of 3
|
|
21
|
+
* arrayChunk(['a', 'b', 'c', 'd', 'e', 'f', 'g'], 3)
|
|
22
|
+
* // Returns: [['a', 'b', 'c'], ['d', 'e', 'f'], ['g']]
|
|
23
|
+
*
|
|
24
|
+
* // Works with readonly arrays
|
|
25
|
+
* const readonlyArr = [1, 2, 3] as const
|
|
26
|
+
* arrayChunk(readonlyArr)
|
|
27
|
+
* // Returns: [[1, 2], [3]]
|
|
28
|
+
* ```
|
|
3
29
|
*/
|
|
4
30
|
/*@__NO_SIDE_EFFECTS__*/
|
|
5
31
|
export declare function arrayChunk<T>(arr: T[] | readonly T[], size?: number | undefined): T[][];
|
|
6
32
|
/**
|
|
7
33
|
* Get unique values from an array.
|
|
34
|
+
*
|
|
35
|
+
* Returns a new array containing only the unique values from the input array.
|
|
36
|
+
* Uses `Set` internally for efficient deduplication. Order of first occurrence
|
|
37
|
+
* is preserved.
|
|
38
|
+
*
|
|
39
|
+
* @param arr - The array to deduplicate (can be readonly)
|
|
40
|
+
* @returns New array with duplicate values removed
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```ts
|
|
44
|
+
* // Remove duplicate numbers
|
|
45
|
+
* arrayUnique([1, 2, 2, 3, 1, 4])
|
|
46
|
+
* // Returns: [1, 2, 3, 4]
|
|
47
|
+
*
|
|
48
|
+
* // Remove duplicate strings
|
|
49
|
+
* arrayUnique(['apple', 'banana', 'apple', 'cherry'])
|
|
50
|
+
* // Returns: ['apple', 'banana', 'cherry']
|
|
51
|
+
*
|
|
52
|
+
* // Works with readonly arrays
|
|
53
|
+
* const readonlyArr = [1, 1, 2] as const
|
|
54
|
+
* arrayUnique(readonlyArr)
|
|
55
|
+
* // Returns: [1, 2]
|
|
56
|
+
*
|
|
57
|
+
* // Empty arrays return empty
|
|
58
|
+
* arrayUnique([])
|
|
59
|
+
* // Returns: []
|
|
60
|
+
* ```
|
|
8
61
|
*/
|
|
9
62
|
/*@__NO_SIDE_EFFECTS__*/
|
|
10
63
|
export declare function arrayUnique<T>(arr: T[] | readonly T[]): T[];
|
|
@@ -15,15 +68,105 @@ export declare function arrayUnique<T>(arr: T[] | readonly T[]): T[];
|
|
|
15
68
|
/**
|
|
16
69
|
* Alias for native Array.isArray.
|
|
17
70
|
* Determines whether the passed value is an array.
|
|
71
|
+
*
|
|
72
|
+
* This is a direct reference to the native `Array.isArray` method,
|
|
73
|
+
* providing a type guard that narrows the type to an array type.
|
|
74
|
+
* Exported for consistency with other array utilities in this module.
|
|
75
|
+
*
|
|
76
|
+
* @param value - The value to check
|
|
77
|
+
* @returns `true` if the value is an array, `false` otherwise
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```ts
|
|
81
|
+
* // Check if value is an array
|
|
82
|
+
* isArray([1, 2, 3])
|
|
83
|
+
* // Returns: true
|
|
84
|
+
*
|
|
85
|
+
* isArray('not an array')
|
|
86
|
+
* // Returns: false
|
|
87
|
+
*
|
|
88
|
+
* isArray(null)
|
|
89
|
+
* // Returns: false
|
|
90
|
+
*
|
|
91
|
+
* // Type guard usage
|
|
92
|
+
* function processValue(value: unknown) {
|
|
93
|
+
* if (isArray(value)) {
|
|
94
|
+
* // TypeScript knows value is an array here
|
|
95
|
+
* console.log(value.length)
|
|
96
|
+
* }
|
|
97
|
+
* }
|
|
98
|
+
* ```
|
|
18
99
|
*/
|
|
19
100
|
export declare const isArray: (arg: any) => arg is any[];
|
|
20
101
|
/**
|
|
21
102
|
* Join array elements with proper "and" conjunction formatting.
|
|
103
|
+
*
|
|
104
|
+
* Formats an array of strings into a grammatically correct list using
|
|
105
|
+
* "and" as the conjunction. Uses `Intl.ListFormat` for proper English
|
|
106
|
+
* formatting with Oxford comma support.
|
|
107
|
+
*
|
|
108
|
+
* @param arr - Array of strings to join (can be readonly)
|
|
109
|
+
* @returns Formatted string with proper "and" conjunction
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```ts
|
|
113
|
+
* // Two items
|
|
114
|
+
* joinAnd(['apples', 'oranges'])
|
|
115
|
+
* // Returns: "apples and oranges"
|
|
116
|
+
*
|
|
117
|
+
* // Three or more items (Oxford comma)
|
|
118
|
+
* joinAnd(['apples', 'oranges', 'bananas'])
|
|
119
|
+
* // Returns: "apples, oranges, and bananas"
|
|
120
|
+
*
|
|
121
|
+
* // Single item
|
|
122
|
+
* joinAnd(['apples'])
|
|
123
|
+
* // Returns: "apples"
|
|
124
|
+
*
|
|
125
|
+
* // Empty array
|
|
126
|
+
* joinAnd([])
|
|
127
|
+
* // Returns: ""
|
|
128
|
+
*
|
|
129
|
+
* // Usage in messages
|
|
130
|
+
* const items = ['React', 'Vue', 'Angular']
|
|
131
|
+
* console.log(`You can choose ${joinAnd(items)}`)
|
|
132
|
+
* // Outputs: "You can choose React, Vue, and Angular"
|
|
133
|
+
* ```
|
|
22
134
|
*/
|
|
23
135
|
/*@__NO_SIDE_EFFECTS__*/
|
|
24
136
|
export declare function joinAnd(arr: string[] | readonly string[]): string;
|
|
25
137
|
/**
|
|
26
138
|
* Join array elements with proper "or" disjunction formatting.
|
|
139
|
+
*
|
|
140
|
+
* Formats an array of strings into a grammatically correct list using
|
|
141
|
+
* "or" as the disjunction. Uses `Intl.ListFormat` for proper English
|
|
142
|
+
* formatting with Oxford comma support.
|
|
143
|
+
*
|
|
144
|
+
* @param arr - Array of strings to join (can be readonly)
|
|
145
|
+
* @returns Formatted string with proper "or" disjunction
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```ts
|
|
149
|
+
* // Two items
|
|
150
|
+
* joinOr(['yes', 'no'])
|
|
151
|
+
* // Returns: "yes or no"
|
|
152
|
+
*
|
|
153
|
+
* // Three or more items (Oxford comma)
|
|
154
|
+
* joinOr(['red', 'green', 'blue'])
|
|
155
|
+
* // Returns: "red, green, or blue"
|
|
156
|
+
*
|
|
157
|
+
* // Single item
|
|
158
|
+
* joinOr(['maybe'])
|
|
159
|
+
* // Returns: "maybe"
|
|
160
|
+
*
|
|
161
|
+
* // Empty array
|
|
162
|
+
* joinOr([])
|
|
163
|
+
* // Returns: ""
|
|
164
|
+
*
|
|
165
|
+
* // Usage in prompts
|
|
166
|
+
* const options = ['npm', 'yarn', 'pnpm']
|
|
167
|
+
* console.log(`Choose a package manager: ${joinOr(options)}`)
|
|
168
|
+
* // Outputs: "Choose a package manager: npm, yarn, or pnpm"
|
|
169
|
+
* ```
|
|
27
170
|
*/
|
|
28
171
|
/*@__NO_SIDE_EFFECTS__*/
|
|
29
172
|
export declare function joinOr(arr: string[] | readonly string[]): string;
|
package/dist/arrays.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/arrays.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Array utility functions for formatting lists and collections.\n * Provides conjunction and disjunction formatters using Intl.ListFormat.\n */\n\nlet _conjunctionFormatter: Intl.ListFormat | undefined\n/**\n * Get a cached Intl.ListFormat instance for conjunction (and) formatting.\n * @private\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getConjunctionFormatter() {\n if (_conjunctionFormatter === undefined) {\n _conjunctionFormatter = new Intl.ListFormat('en', {\n style: 'long',\n // \"and\" lists.\n type: 'conjunction',\n })\n }\n return _conjunctionFormatter\n}\n\nlet _disjunctionFormatter: Intl.ListFormat | undefined\n/**\n * Get a cached Intl.ListFormat instance for disjunction (or) formatting.\n * @private\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getDisjunctionFormatter() {\n if (_disjunctionFormatter === undefined) {\n _disjunctionFormatter = new Intl.ListFormat('en', {\n style: 'long',\n // \"or\" lists.\n type: 'disjunction',\n })\n }\n return _disjunctionFormatter\n}\n\n/**\n * Split an array into chunks of a specified size.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function arrayChunk<T>(\n arr: T[] | readonly T[],\n size?: number | undefined,\n): T[][] {\n const chunkSize = size ?? 2\n if (chunkSize <= 0) {\n throw new Error('Chunk size must be greater than 0')\n }\n const { length } = arr\n const actualChunkSize = Math.min(length, chunkSize)\n const chunks = []\n for (let i = 0; i < length; i += actualChunkSize) {\n chunks.push(arr.slice(i, i + actualChunkSize) as T[])\n }\n return chunks\n}\n\n/**\n * Get unique values from an array.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function arrayUnique<T>(arr: T[] | readonly T[]): T[] {\n return [...new Set(arr)]\n}\n\n// IMPORTANT: Do not use destructuring here - use direct assignment instead.\n// tsgo has a bug that incorrectly transpiles destructured exports, resulting in\n// `exports.SomeName = void 0;` which causes runtime errors.\n// See: https://github.com/SocketDev/socket-packageurl-js/issues/3\n\n/**\n * Alias for native Array.isArray.\n * Determines whether the passed value is an array.\n */\nexport const isArray = Array.isArray\n\n/**\n * Join array elements with proper \"and\" conjunction formatting.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function joinAnd(arr: string[] | readonly string[]): string {\n return getConjunctionFormatter().format(arr)\n}\n\n/**\n * Join array elements with proper \"or\" disjunction formatting.\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function joinOr(arr: string[] | readonly string[]): string {\n return getDisjunctionFormatter().format(arr)\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,IAAI;AAAA;
|
|
4
|
+
"sourcesContent": ["/**\n * @fileoverview Array utility functions for formatting lists and collections.\n * Provides conjunction and disjunction formatters using Intl.ListFormat.\n */\n\nlet _conjunctionFormatter: Intl.ListFormat | undefined\n/**\n * Get a cached Intl.ListFormat instance for conjunction (and) formatting.\n *\n * Creates a singleton formatter for English \"and\" lists using the long style.\n * The formatter is lazily initialized on first use and reused for performance.\n *\n * @returns Cached Intl.ListFormat instance configured for conjunction formatting\n *\n * @example\n * ```ts\n * const formatter = getConjunctionFormatter()\n * formatter.format(['apple', 'banana', 'cherry'])\n * // Returns: \"apple, banana, and cherry\"\n * ```\n *\n * @private\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getConjunctionFormatter() {\n if (_conjunctionFormatter === undefined) {\n _conjunctionFormatter = new Intl.ListFormat('en', {\n style: 'long',\n // \"and\" lists.\n type: 'conjunction',\n })\n }\n return _conjunctionFormatter\n}\n\nlet _disjunctionFormatter: Intl.ListFormat | undefined\n/**\n * Get a cached Intl.ListFormat instance for disjunction (or) formatting.\n *\n * Creates a singleton formatter for English \"or\" lists using the long style.\n * The formatter is lazily initialized on first use and reused for performance.\n *\n * @returns Cached Intl.ListFormat instance configured for disjunction formatting\n *\n * @example\n * ```ts\n * const formatter = getDisjunctionFormatter()\n * formatter.format(['red', 'blue', 'green'])\n * // Returns: \"red, blue, or green\"\n * ```\n *\n * @private\n */\n/*@__NO_SIDE_EFFECTS__*/\nfunction getDisjunctionFormatter() {\n if (_disjunctionFormatter === undefined) {\n _disjunctionFormatter = new Intl.ListFormat('en', {\n style: 'long',\n // \"or\" lists.\n type: 'disjunction',\n })\n }\n return _disjunctionFormatter\n}\n\n/**\n * Split an array into chunks of a specified size.\n *\n * Divides an array into smaller arrays of the specified chunk size.\n * The last chunk may contain fewer elements if the array length is not\n * evenly divisible by the chunk size.\n *\n * @param arr - The array to split into chunks (can be readonly)\n * @param size - Size of each chunk. Must be greater than 0.\n * @default 2\n * @returns Array of chunks, where each chunk is an array of elements\n * @throws {Error} If chunk size is less than or equal to 0\n *\n * @example\n * ```ts\n * // Split into pairs (default)\n * arrayChunk([1, 2, 3, 4, 5])\n * // Returns: [[1, 2], [3, 4], [5]]\n *\n * // Split into groups of 3\n * arrayChunk(['a', 'b', 'c', 'd', 'e', 'f', 'g'], 3)\n * // Returns: [['a', 'b', 'c'], ['d', 'e', 'f'], ['g']]\n *\n * // Works with readonly arrays\n * const readonlyArr = [1, 2, 3] as const\n * arrayChunk(readonlyArr)\n * // Returns: [[1, 2], [3]]\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function arrayChunk<T>(\n arr: T[] | readonly T[],\n size?: number | undefined,\n): T[][] {\n const chunkSize = size ?? 2\n if (chunkSize <= 0) {\n throw new Error('Chunk size must be greater than 0')\n }\n const { length } = arr\n const actualChunkSize = Math.min(length, chunkSize)\n const chunks = []\n for (let i = 0; i < length; i += actualChunkSize) {\n chunks.push(arr.slice(i, i + actualChunkSize) as T[])\n }\n return chunks\n}\n\n/**\n * Get unique values from an array.\n *\n * Returns a new array containing only the unique values from the input array.\n * Uses `Set` internally for efficient deduplication. Order of first occurrence\n * is preserved.\n *\n * @param arr - The array to deduplicate (can be readonly)\n * @returns New array with duplicate values removed\n *\n * @example\n * ```ts\n * // Remove duplicate numbers\n * arrayUnique([1, 2, 2, 3, 1, 4])\n * // Returns: [1, 2, 3, 4]\n *\n * // Remove duplicate strings\n * arrayUnique(['apple', 'banana', 'apple', 'cherry'])\n * // Returns: ['apple', 'banana', 'cherry']\n *\n * // Works with readonly arrays\n * const readonlyArr = [1, 1, 2] as const\n * arrayUnique(readonlyArr)\n * // Returns: [1, 2]\n *\n * // Empty arrays return empty\n * arrayUnique([])\n * // Returns: []\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function arrayUnique<T>(arr: T[] | readonly T[]): T[] {\n return [...new Set(arr)]\n}\n\n// IMPORTANT: Do not use destructuring here - use direct assignment instead.\n// tsgo has a bug that incorrectly transpiles destructured exports, resulting in\n// `exports.SomeName = void 0;` which causes runtime errors.\n// See: https://github.com/SocketDev/socket-packageurl-js/issues/3\n\n/**\n * Alias for native Array.isArray.\n * Determines whether the passed value is an array.\n *\n * This is a direct reference to the native `Array.isArray` method,\n * providing a type guard that narrows the type to an array type.\n * Exported for consistency with other array utilities in this module.\n *\n * @param value - The value to check\n * @returns `true` if the value is an array, `false` otherwise\n *\n * @example\n * ```ts\n * // Check if value is an array\n * isArray([1, 2, 3])\n * // Returns: true\n *\n * isArray('not an array')\n * // Returns: false\n *\n * isArray(null)\n * // Returns: false\n *\n * // Type guard usage\n * function processValue(value: unknown) {\n * if (isArray(value)) {\n * // TypeScript knows value is an array here\n * console.log(value.length)\n * }\n * }\n * ```\n */\nexport const isArray = Array.isArray\n\n/**\n * Join array elements with proper \"and\" conjunction formatting.\n *\n * Formats an array of strings into a grammatically correct list using\n * \"and\" as the conjunction. Uses `Intl.ListFormat` for proper English\n * formatting with Oxford comma support.\n *\n * @param arr - Array of strings to join (can be readonly)\n * @returns Formatted string with proper \"and\" conjunction\n *\n * @example\n * ```ts\n * // Two items\n * joinAnd(['apples', 'oranges'])\n * // Returns: \"apples and oranges\"\n *\n * // Three or more items (Oxford comma)\n * joinAnd(['apples', 'oranges', 'bananas'])\n * // Returns: \"apples, oranges, and bananas\"\n *\n * // Single item\n * joinAnd(['apples'])\n * // Returns: \"apples\"\n *\n * // Empty array\n * joinAnd([])\n * // Returns: \"\"\n *\n * // Usage in messages\n * const items = ['React', 'Vue', 'Angular']\n * console.log(`You can choose ${joinAnd(items)}`)\n * // Outputs: \"You can choose React, Vue, and Angular\"\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function joinAnd(arr: string[] | readonly string[]): string {\n return getConjunctionFormatter().format(arr)\n}\n\n/**\n * Join array elements with proper \"or\" disjunction formatting.\n *\n * Formats an array of strings into a grammatically correct list using\n * \"or\" as the disjunction. Uses `Intl.ListFormat` for proper English\n * formatting with Oxford comma support.\n *\n * @param arr - Array of strings to join (can be readonly)\n * @returns Formatted string with proper \"or\" disjunction\n *\n * @example\n * ```ts\n * // Two items\n * joinOr(['yes', 'no'])\n * // Returns: \"yes or no\"\n *\n * // Three or more items (Oxford comma)\n * joinOr(['red', 'green', 'blue'])\n * // Returns: \"red, green, or blue\"\n *\n * // Single item\n * joinOr(['maybe'])\n * // Returns: \"maybe\"\n *\n * // Empty array\n * joinOr([])\n * // Returns: \"\"\n *\n * // Usage in prompts\n * const options = ['npm', 'yarn', 'pnpm']\n * console.log(`Choose a package manager: ${joinOr(options)}`)\n * // Outputs: \"Choose a package manager: npm, yarn, or pnpm\"\n * ```\n */\n/*@__NO_SIDE_EFFECTS__*/\nexport function joinOr(arr: string[] | readonly string[]): string {\n return getDisjunctionFormatter().format(arr)\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,IAAI;AAAA;AAmBJ,SAAS,0BAA0B;AACjC,MAAI,0BAA0B,QAAW;AACvC,4BAAwB,IAAI,KAAK,WAAW,MAAM;AAAA,MAChD,OAAO;AAAA;AAAA,MAEP,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,IAAI;AAAA;AAmBJ,SAAS,0BAA0B;AACjC,MAAI,0BAA0B,QAAW;AACvC,4BAAwB,IAAI,KAAK,WAAW,MAAM;AAAA,MAChD,OAAO;AAAA;AAAA,MAEP,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAAA;AAgCO,SAAS,WACd,KACA,MACO;AACP,QAAM,YAAY,QAAQ;AAC1B,MAAI,aAAa,GAAG;AAClB,UAAM,IAAI,MAAM,mCAAmC;AAAA,EACrD;AACA,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,kBAAkB,KAAK,IAAI,QAAQ,SAAS;AAClD,QAAM,SAAS,CAAC;AAChB,WAAS,IAAI,GAAG,IAAI,QAAQ,KAAK,iBAAiB;AAChD,WAAO,KAAK,IAAI,MAAM,GAAG,IAAI,eAAe,CAAQ;AAAA,EACtD;AACA,SAAO;AACT;AAAA;AAiCO,SAAS,YAAe,KAA8B;AAC3D,SAAO,CAAC,GAAG,IAAI,IAAI,GAAG,CAAC;AACzB;AAuCO,MAAM,UAAU,MAAM;AAAA;AAqCtB,SAAS,QAAQ,KAA2C;AACjE,UAAO,wCAAwB,GAAE,OAAO,GAAG;AAC7C;AAAA;AAqCO,SAAS,OAAO,KAA2C;AAChE,UAAO,wCAAwB,GAAE,OAAO,GAAG;AAC7C;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -29,6 +29,7 @@ __export(text_shimmer_exports, {
|
|
|
29
29
|
module.exports = __toCommonJS(text_shimmer_exports);
|
|
30
30
|
var import_ansi = require("../ansi");
|
|
31
31
|
var import_arrays = require("../arrays");
|
|
32
|
+
var import_ci = require("#env/ci");
|
|
32
33
|
function detectStyles(text) {
|
|
33
34
|
return {
|
|
34
35
|
__proto__: null,
|
|
@@ -123,7 +124,7 @@ function applyShimmer(text, state, options) {
|
|
|
123
124
|
const color = opts.color ?? [140, 82, 255];
|
|
124
125
|
const styles = opts.styles ?? detectStyles(text);
|
|
125
126
|
const plainText = (0, import_ansi.stripAnsi)(text);
|
|
126
|
-
if (!plainText || direction === DIR_NONE) {
|
|
127
|
+
if (import_ci.CI || !plainText || direction === DIR_NONE) {
|
|
127
128
|
const styleCode = stylesToAnsi(styles);
|
|
128
129
|
const isGradient = (0, import_arrays.isArray)(color[0]);
|
|
129
130
|
return plainText.split("").map((char, i) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/effects/text-shimmer.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @fileoverview Text shimmer animation utilities.\n * Provides animated highlight effects for spinner text with configurable directions:\n * - LTR (left-to-right): Shimmer wave moves from left to right\n * - RTL (right-to-left): Shimmer wave moves from right to left\n * - Bidirectional: Alternates between LTR and RTL each cycle\n * - Random: Picks a random direction each cycle\n * - None: No shimmer animation\n *\n * The shimmer effect creates a bright wave that travels across the text,\n * with characters near the wave appearing nearly white and fading to the\n * base color as they get further from the wave position.\n */\n\nimport { ANSI_RESET, stripAnsi } from '../ansi'\nimport { isArray } from '../arrays'\n\nimport type {\n ShimmerColorGradient,\n ShimmerColorRgb,\n ShimmerDirection,\n ShimmerState,\n} from './types'\n\n// Re-export types for backward compatibility.\nexport type {\n ShimmerColor,\n ShimmerColorGradient,\n ShimmerColorInherit,\n ShimmerColorRgb,\n ShimmerConfig,\n ShimmerDirection,\n ShimmerState,\n} from './types'\n\n/**\n * Detected text formatting styles from ANSI codes.\n */\ntype TextStyles = {\n bold: boolean\n dim: boolean\n italic: boolean\n strikethrough: boolean\n underline: boolean\n}\n\n/**\n * Detect all text formatting styles present in ANSI-coded text.\n * Checks for bold, dim, italic, underline, and strikethrough.\n */\nfunction detectStyles(text: string): TextStyles {\n return {\n __proto__: null,\n // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape sequence detection.\n bold: /\\x1b\\[1m/.test(text),\n // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape sequence detection.\n dim: /\\x1b\\[2m/.test(text),\n // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape sequence detection.\n italic: /\\x1b\\[3m/.test(text),\n // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape sequence detection.\n strikethrough: /\\x1b\\[9m/.test(text),\n // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape sequence detection.\n underline: /\\x1b\\[4m/.test(text),\n } as TextStyles\n}\n\n/**\n * Build ANSI code string from text styles.\n * Returns the concatenated ANSI codes needed to apply the styles.\n */\nfunction stylesToAnsi(styles: TextStyles): string {\n let codes = ''\n if (styles.bold) {\n codes += '\\x1b[1m'\n }\n if (styles.dim) {\n codes += '\\x1b[2m'\n }\n if (styles.italic) {\n codes += '\\x1b[3m'\n }\n if (styles.underline) {\n codes += '\\x1b[4m'\n }\n if (styles.strikethrough) {\n codes += '\\x1b[9m'\n }\n return codes\n}\n\n// Internal options for applyShimmer function.\ntype ShimmerOptions = {\n readonly color?: ShimmerColorRgb | ShimmerColorGradient | undefined\n readonly direction?: ShimmerDirection | undefined\n readonly shimmerWidth?: number | undefined\n readonly styles?: TextStyles | undefined\n}\n\nexport const COLOR_INHERIT = 'inherit'\n\nexport const DIR_LTR = 'ltr'\n\nexport const DIR_NONE = 'none'\n\nexport const DIR_RANDOM = 'random'\n\nexport const DIR_RTL = 'rtl'\n\nexport const MODE_BI = 'bi'\n\n/**\n * Calculate shimmer intensity based on distance from shimmer wave position.\n * Uses a power curve for smooth falloff - characters close to the wave\n * get high intensity (bright white), while distant characters get 0.\n */\nfunction shimmerIntensity(\n distance: number,\n shimmerWidth: number = 2.5,\n): number {\n // Characters beyond shimmer width get no effect.\n if (distance > shimmerWidth) {\n return 0\n }\n // Smooth falloff using power curve.\n const normalized = distance / shimmerWidth\n return (1 - normalized) ** 2.5\n}\n\n/**\n * Blend two RGB colors based on a blend factor (0-1).\n * factor 0 = color1, factor 1 = color2, factor 0.5 = 50/50 blend.\n */\nfunction blendColors(\n color1: readonly [number, number, number],\n color2: readonly [number, number, number],\n factor: number,\n): readonly [number, number, number] {\n const r = Math.round(color1[0] + (color2[0] - color1[0]) * factor)\n const g = Math.round(color1[1] + (color2[1] - color1[1]) * factor)\n const b = Math.round(color1[2] + (color2[2] - color1[2]) * factor)\n return [r, g, b] as const\n}\n\n/**\n * Render character with shimmer effect based on distance from shimmer position.\n * Characters closer to the shimmer position get brighter (nearly white),\n * while characters further away use the base color.\n * Creates a smooth gradient by blending base color with white based on intensity.\n * Supports both single color and per-character color gradients.\n */\nfunction renderChar(\n char: string,\n index: number,\n shimmerPos: number,\n baseColor: readonly [number, number, number] | ShimmerColorGradient,\n styles: TextStyles,\n): string {\n // Calculate how far this character is from the shimmer wave.\n const distance = Math.abs(index - shimmerPos)\n const intensity = shimmerIntensity(distance)\n\n const styleCode = stylesToAnsi(styles)\n\n // Get base color for this character (single or per-character from gradient).\n const charColor: readonly [number, number, number] = isArray(baseColor[0])\n ? ((baseColor as ShimmerColorGradient)[index % baseColor.length] ?? [\n 140, 82, 255,\n ])\n : (baseColor as readonly [number, number, number])\n\n // If no shimmer intensity, use base color as-is.\n if (intensity === 0) {\n const base = `\\x1b[38;2;${charColor[0]};${charColor[1]};${charColor[2]}m`\n return `${styleCode}${base}${char}${ANSI_RESET}`\n }\n\n // Blend base color with white based on intensity to create smooth gradient.\n // Higher intensity = more white, creating the shimmer wave effect.\n const white: readonly [number, number, number] = [255, 255, 255] as const\n const blended = blendColors(charColor, white, intensity)\n\n const color = `\\x1b[38;2;${blended[0]};${blended[1]};${blended[2]}m`\n return `${styleCode}${color}${char}${ANSI_RESET}`\n}\n\n/**\n * Calculate shimmer wave position for current animation step.\n * The shimmer wave moves across the text length, with extra space\n * for the wave to fade in/out at the edges.\n */\nfunction getShimmerPos(\n textLength: number,\n step: number,\n currentDir: 'ltr' | 'rtl',\n shimmerWidth: number = 2.5,\n): number {\n // Total steps for one complete cycle (text length + fade in/out space).\n const totalSteps = textLength + shimmerWidth + 2\n\n // RTL: Shimmer moves from right to left.\n if (currentDir === DIR_RTL) {\n return textLength - (step % totalSteps)\n }\n\n // LTR: Shimmer moves from left to right.\n return step % totalSteps\n}\n\n/**\n * Resolve shimmer direction to a concrete 'ltr' or 'rtl' value.\n * Used for initializing shimmer state and picking random directions.\n */\nfunction pickDirection(direction: ShimmerDirection): 'ltr' | 'rtl' {\n // Random mode: 50/50 chance of LTR or RTL.\n if (direction === DIR_RANDOM) {\n return Math.random() < 0.5 ? DIR_LTR : DIR_RTL\n }\n // RTL mode: Use RTL direction.\n if (direction === DIR_RTL) {\n return DIR_RTL\n }\n // LTR mode (or any other): Default to LTR.\n return DIR_LTR\n}\n\n/**\n * Apply shimmer animation effect to text.\n * This is the main entry point for shimmer animations. It:\n * 1. Strips ANSI codes to get plain text for character positioning\n * 2. Detects any styling (bold, italic, underline, etc.) to preserve\n * 3. Calculates the current shimmer wave position based on animation step\n * 4. Renders each character with appropriate brightness based on distance from wave\n * 5. Updates the animation state for the next frame\n * 6. Handles direction changes for bidirectional and random modes\n */\nexport function applyShimmer(\n text: string,\n state: ShimmerState,\n options?: ShimmerOptions | undefined,\n): string {\n const opts = { __proto__: null, ...options } as ShimmerOptions\n const direction = opts.direction ?? DIR_NONE\n const shimmerWidth = opts.shimmerWidth ?? 2.5\n // Socket purple.\n const color = opts.color ?? ([140, 82, 255] as const)\n\n // Detect text formatting styles from original text.\n const styles = opts.styles ?? detectStyles(text)\n\n // Strip ANSI codes to get plain text.\n const plainText = stripAnsi(text)\n\n // No shimmer effect.\n if (!plainText || direction === DIR_NONE) {\n const styleCode = stylesToAnsi(styles)\n\n // Support gradient colors (array of colors, one per character).\n const isGradient = isArray(color[0])\n\n return plainText\n .split('')\n .map((char, i) => {\n const charColor: readonly [number, number, number] = isGradient\n ? ((color as ShimmerColorGradient)[i % color.length] ?? [\n 140, 82, 255,\n ])\n : (color as readonly [number, number, number])\n const base = `\\x1b[38;2;${charColor[0]};${charColor[1]};${charColor[2]}m`\n return `${styleCode}${base}${char}${ANSI_RESET}`\n })\n .join('')\n }\n\n // Calculate shimmer position.\n const shimmerPos = getShimmerPos(\n plainText.length,\n state.step,\n state.currentDir,\n shimmerWidth,\n )\n\n // Render text with shimmer.\n const result = plainText\n .split('')\n .map((char, i) => renderChar(char, i, shimmerPos, color, styles))\n .join('')\n\n // Advance shimmer position by speed amount each frame.\n // Speed represents steps per frame (e.g., 0.33 = advance 0.33 steps per frame).\n // This creates smooth animation by moving in small increments every frame\n // instead of jumping larger distances every N frames.\n state.step += state.speed\n\n // Handle bidirectional direction changes.\n const totalSteps = plainText.length + shimmerWidth + 2\n if (state.mode === MODE_BI) {\n if (state.step >= totalSteps) {\n state.step = 0\n // Toggle direction every cycle.\n state.currentDir = state.currentDir === DIR_LTR ? DIR_RTL : DIR_LTR\n }\n } else if (state.mode === DIR_RANDOM) {\n // Change direction randomly at end of each cycle.\n if (state.step >= totalSteps) {\n state.step = 0\n state.currentDir = pickDirection(DIR_RANDOM)\n }\n } else {\n // Reset for continuous loops.\n if (state.step >= totalSteps) {\n state.step = 0\n }\n }\n\n return result\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcA,kBAAsC;AACtC,oBAAwB;
|
|
4
|
+
"sourcesContent": ["/**\n * @fileoverview Text shimmer animation utilities.\n * Provides animated highlight effects for spinner text with configurable directions:\n * - LTR (left-to-right): Shimmer wave moves from left to right\n * - RTL (right-to-left): Shimmer wave moves from right to left\n * - Bidirectional: Alternates between LTR and RTL each cycle\n * - Random: Picks a random direction each cycle\n * - None: No shimmer animation\n *\n * The shimmer effect creates a bright wave that travels across the text,\n * with characters near the wave appearing nearly white and fading to the\n * base color as they get further from the wave position.\n */\n\nimport { ANSI_RESET, stripAnsi } from '../ansi'\nimport { isArray } from '../arrays'\nimport { CI } from '#env/ci'\n\nimport type {\n ShimmerColorGradient,\n ShimmerColorRgb,\n ShimmerDirection,\n ShimmerState,\n} from './types'\n\n// Re-export types for backward compatibility.\nexport type {\n ShimmerColor,\n ShimmerColorGradient,\n ShimmerColorInherit,\n ShimmerColorRgb,\n ShimmerConfig,\n ShimmerDirection,\n ShimmerState,\n} from './types'\n\n/**\n * Detected text formatting styles from ANSI codes.\n */\ntype TextStyles = {\n bold: boolean\n dim: boolean\n italic: boolean\n strikethrough: boolean\n underline: boolean\n}\n\n/**\n * Detect all text formatting styles present in ANSI-coded text.\n * Checks for bold, dim, italic, underline, and strikethrough.\n */\nfunction detectStyles(text: string): TextStyles {\n return {\n __proto__: null,\n // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape sequence detection.\n bold: /\\x1b\\[1m/.test(text),\n // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape sequence detection.\n dim: /\\x1b\\[2m/.test(text),\n // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape sequence detection.\n italic: /\\x1b\\[3m/.test(text),\n // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape sequence detection.\n strikethrough: /\\x1b\\[9m/.test(text),\n // biome-ignore lint/suspicious/noControlCharactersInRegex: ANSI escape sequence detection.\n underline: /\\x1b\\[4m/.test(text),\n } as TextStyles\n}\n\n/**\n * Build ANSI code string from text styles.\n * Returns the concatenated ANSI codes needed to apply the styles.\n */\nfunction stylesToAnsi(styles: TextStyles): string {\n let codes = ''\n if (styles.bold) {\n codes += '\\x1b[1m'\n }\n if (styles.dim) {\n codes += '\\x1b[2m'\n }\n if (styles.italic) {\n codes += '\\x1b[3m'\n }\n if (styles.underline) {\n codes += '\\x1b[4m'\n }\n if (styles.strikethrough) {\n codes += '\\x1b[9m'\n }\n return codes\n}\n\n// Internal options for applyShimmer function.\ntype ShimmerOptions = {\n readonly color?: ShimmerColorRgb | ShimmerColorGradient | undefined\n readonly direction?: ShimmerDirection | undefined\n readonly shimmerWidth?: number | undefined\n readonly styles?: TextStyles | undefined\n}\n\nexport const COLOR_INHERIT = 'inherit'\n\nexport const DIR_LTR = 'ltr'\n\nexport const DIR_NONE = 'none'\n\nexport const DIR_RANDOM = 'random'\n\nexport const DIR_RTL = 'rtl'\n\nexport const MODE_BI = 'bi'\n\n/**\n * Calculate shimmer intensity based on distance from shimmer wave position.\n * Uses a power curve for smooth falloff - characters close to the wave\n * get high intensity (bright white), while distant characters get 0.\n */\nfunction shimmerIntensity(\n distance: number,\n shimmerWidth: number = 2.5,\n): number {\n // Characters beyond shimmer width get no effect.\n if (distance > shimmerWidth) {\n return 0\n }\n // Smooth falloff using power curve.\n const normalized = distance / shimmerWidth\n return (1 - normalized) ** 2.5\n}\n\n/**\n * Blend two RGB colors based on a blend factor (0-1).\n * factor 0 = color1, factor 1 = color2, factor 0.5 = 50/50 blend.\n */\nfunction blendColors(\n color1: readonly [number, number, number],\n color2: readonly [number, number, number],\n factor: number,\n): readonly [number, number, number] {\n const r = Math.round(color1[0] + (color2[0] - color1[0]) * factor)\n const g = Math.round(color1[1] + (color2[1] - color1[1]) * factor)\n const b = Math.round(color1[2] + (color2[2] - color1[2]) * factor)\n return [r, g, b] as const\n}\n\n/**\n * Render character with shimmer effect based on distance from shimmer position.\n * Characters closer to the shimmer position get brighter (nearly white),\n * while characters further away use the base color.\n * Creates a smooth gradient by blending base color with white based on intensity.\n * Supports both single color and per-character color gradients.\n */\nfunction renderChar(\n char: string,\n index: number,\n shimmerPos: number,\n baseColor: readonly [number, number, number] | ShimmerColorGradient,\n styles: TextStyles,\n): string {\n // Calculate how far this character is from the shimmer wave.\n const distance = Math.abs(index - shimmerPos)\n const intensity = shimmerIntensity(distance)\n\n const styleCode = stylesToAnsi(styles)\n\n // Get base color for this character (single or per-character from gradient).\n const charColor: readonly [number, number, number] = isArray(baseColor[0])\n ? ((baseColor as ShimmerColorGradient)[index % baseColor.length] ?? [\n 140, 82, 255,\n ])\n : (baseColor as readonly [number, number, number])\n\n // If no shimmer intensity, use base color as-is.\n if (intensity === 0) {\n const base = `\\x1b[38;2;${charColor[0]};${charColor[1]};${charColor[2]}m`\n return `${styleCode}${base}${char}${ANSI_RESET}`\n }\n\n // Blend base color with white based on intensity to create smooth gradient.\n // Higher intensity = more white, creating the shimmer wave effect.\n const white: readonly [number, number, number] = [255, 255, 255] as const\n const blended = blendColors(charColor, white, intensity)\n\n const color = `\\x1b[38;2;${blended[0]};${blended[1]};${blended[2]}m`\n return `${styleCode}${color}${char}${ANSI_RESET}`\n}\n\n/**\n * Calculate shimmer wave position for current animation step.\n * The shimmer wave moves across the text length, with extra space\n * for the wave to fade in/out at the edges.\n */\nfunction getShimmerPos(\n textLength: number,\n step: number,\n currentDir: 'ltr' | 'rtl',\n shimmerWidth: number = 2.5,\n): number {\n // Total steps for one complete cycle (text length + fade in/out space).\n const totalSteps = textLength + shimmerWidth + 2\n\n // RTL: Shimmer moves from right to left.\n if (currentDir === DIR_RTL) {\n return textLength - (step % totalSteps)\n }\n\n // LTR: Shimmer moves from left to right.\n return step % totalSteps\n}\n\n/**\n * Resolve shimmer direction to a concrete 'ltr' or 'rtl' value.\n * Used for initializing shimmer state and picking random directions.\n */\nfunction pickDirection(direction: ShimmerDirection): 'ltr' | 'rtl' {\n // Random mode: 50/50 chance of LTR or RTL.\n if (direction === DIR_RANDOM) {\n return Math.random() < 0.5 ? DIR_LTR : DIR_RTL\n }\n // RTL mode: Use RTL direction.\n if (direction === DIR_RTL) {\n return DIR_RTL\n }\n // LTR mode (or any other): Default to LTR.\n return DIR_LTR\n}\n\n/**\n * Apply shimmer animation effect to text.\n * This is the main entry point for shimmer animations. It:\n * 1. Strips ANSI codes to get plain text for character positioning\n * 2. Detects any styling (bold, italic, underline, etc.) to preserve\n * 3. Calculates the current shimmer wave position based on animation step\n * 4. Renders each character with appropriate brightness based on distance from wave\n * 5. Updates the animation state for the next frame\n * 6. Handles direction changes for bidirectional and random modes\n */\nexport function applyShimmer(\n text: string,\n state: ShimmerState,\n options?: ShimmerOptions | undefined,\n): string {\n const opts = { __proto__: null, ...options } as ShimmerOptions\n const direction = opts.direction ?? DIR_NONE\n const shimmerWidth = opts.shimmerWidth ?? 2.5\n // Socket purple.\n const color = opts.color ?? ([140, 82, 255] as const)\n\n // Detect text formatting styles from original text.\n const styles = opts.styles ?? detectStyles(text)\n\n // Strip ANSI codes to get plain text.\n const plainText = stripAnsi(text)\n\n // No shimmer effect in CI or when direction is 'none'.\n if (CI || !plainText || direction === DIR_NONE) {\n const styleCode = stylesToAnsi(styles)\n\n // Support gradient colors (array of colors, one per character).\n const isGradient = isArray(color[0])\n\n return plainText\n .split('')\n .map((char, i) => {\n const charColor: readonly [number, number, number] = isGradient\n ? ((color as ShimmerColorGradient)[i % color.length] ?? [\n 140, 82, 255,\n ])\n : (color as readonly [number, number, number])\n const base = `\\x1b[38;2;${charColor[0]};${charColor[1]};${charColor[2]}m`\n return `${styleCode}${base}${char}${ANSI_RESET}`\n })\n .join('')\n }\n\n // Calculate shimmer position.\n const shimmerPos = getShimmerPos(\n plainText.length,\n state.step,\n state.currentDir,\n shimmerWidth,\n )\n\n // Render text with shimmer.\n const result = plainText\n .split('')\n .map((char, i) => renderChar(char, i, shimmerPos, color, styles))\n .join('')\n\n // Advance shimmer position by speed amount each frame.\n // Speed represents steps per frame (e.g., 0.33 = advance 0.33 steps per frame).\n // This creates smooth animation by moving in small increments every frame\n // instead of jumping larger distances every N frames.\n state.step += state.speed\n\n // Handle bidirectional direction changes.\n const totalSteps = plainText.length + shimmerWidth + 2\n if (state.mode === MODE_BI) {\n if (state.step >= totalSteps) {\n state.step = 0\n // Toggle direction every cycle.\n state.currentDir = state.currentDir === DIR_LTR ? DIR_RTL : DIR_LTR\n }\n } else if (state.mode === DIR_RANDOM) {\n // Change direction randomly at end of each cycle.\n if (state.step >= totalSteps) {\n state.step = 0\n state.currentDir = pickDirection(DIR_RANDOM)\n }\n } else {\n // Reset for continuous loops.\n if (state.step >= totalSteps) {\n state.step = 0\n }\n }\n\n return result\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|