@goodscript/core 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -0
- package/dist/array-ext-gs.d.ts +62 -0
- package/dist/array-ext-gs.d.ts.map +1 -0
- package/dist/array-ext-gs.js +162 -0
- package/dist/array-ext-gs.js.map +1 -0
- package/dist/array-tools-gs.d.ts +62 -0
- package/dist/array-tools-gs.d.ts.map +1 -0
- package/dist/array-tools-gs.js +162 -0
- package/dist/array-tools-gs.js.map +1 -0
- package/dist/index-gs.d.ts +17 -0
- package/dist/index-gs.d.ts.map +1 -0
- package/dist/index-gs.js +17 -0
- package/dist/index-gs.js.map +1 -0
- package/dist/map-ext-gs.d.ts +46 -0
- package/dist/map-ext-gs.d.ts.map +1 -0
- package/dist/map-ext-gs.js +88 -0
- package/dist/map-ext-gs.js.map +1 -0
- package/dist/map-tools-gs.d.ts +46 -0
- package/dist/map-tools-gs.d.ts.map +1 -0
- package/dist/map-tools-gs.js +88 -0
- package/dist/map-tools-gs.js.map +1 -0
- package/dist/set-ext-gs.d.ts +50 -0
- package/dist/set-ext-gs.d.ts.map +1 -0
- package/dist/set-ext-gs.js +119 -0
- package/dist/set-ext-gs.js.map +1 -0
- package/dist/set-tools-gs.d.ts +50 -0
- package/dist/set-tools-gs.d.ts.map +1 -0
- package/dist/set-tools-gs.js +119 -0
- package/dist/set-tools-gs.js.map +1 -0
- package/dist/string-ext-gs.d.ts +78 -0
- package/dist/string-ext-gs.d.ts.map +1 -0
- package/dist/string-ext-gs.js +145 -0
- package/dist/string-ext-gs.js.map +1 -0
- package/dist/string-tools-gs.d.ts +78 -0
- package/dist/string-tools-gs.d.ts.map +1 -0
- package/dist/string-tools-gs.js +145 -0
- package/dist/string-tools-gs.js.map +1 -0
- package/package.json +45 -0
- package/src/array-tools-gs.ts +172 -0
- package/src/index-gs.ts +17 -0
- package/src/map-tools-gs.ts +96 -0
- package/src/set-tools-gs.ts +128 -0
- package/src/string-tools-gs.ts +166 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Map utilities with dual error handling pattern.
|
|
3
|
+
*/
|
|
4
|
+
export class MapTools {
|
|
5
|
+
/**
|
|
6
|
+
* Get value from map, or return default if key doesn't exist.
|
|
7
|
+
*/
|
|
8
|
+
static getOrDefault<K, V>(map: Map<K, V>, key: K, defaultValue: V): V {
|
|
9
|
+
const value = map.get(key);
|
|
10
|
+
return value !== undefined ? value : defaultValue;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Get value from map. Returns null if key doesn't exist.
|
|
15
|
+
*/
|
|
16
|
+
static tryGet<K, V>(map: Map<K, V>, key: K): V | null {
|
|
17
|
+
const value = map.get(key);
|
|
18
|
+
return value !== undefined ? value : null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Get value from map. Throws if key doesn't exist.
|
|
23
|
+
*/
|
|
24
|
+
static get<K, V>(map: Map<K, V>, key: K): V {
|
|
25
|
+
const value = MapTools.tryGet(map, key);
|
|
26
|
+
if (value === null) {
|
|
27
|
+
throw new Error(`Key not found in map: ${String(key)}`);
|
|
28
|
+
}
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Get all keys as array.
|
|
34
|
+
*/
|
|
35
|
+
static keys<K, V>(map: Map<K, V>): Array<K> {
|
|
36
|
+
return Array.from(map.keys());
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Get all values as array.
|
|
41
|
+
*/
|
|
42
|
+
static values<K, V>(map: Map<K, V>): Array<V> {
|
|
43
|
+
return Array.from(map.values());
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Get all entries as array of tuples.
|
|
48
|
+
*/
|
|
49
|
+
static entries<K, V>(map: Map<K, V>): Array<[K, V]> {
|
|
50
|
+
return Array.from(map.entries());
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Create new map from array of tuples.
|
|
55
|
+
*/
|
|
56
|
+
static fromEntries<K, V>(entries: Array<[K, V]>): Map<K, V> {
|
|
57
|
+
return new Map(entries);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Map over map values, returning new map with same keys.
|
|
62
|
+
*/
|
|
63
|
+
static mapValues<K, V, U>(map: Map<K, V>, fn: (value: V, key: K) => U): Map<K, U> {
|
|
64
|
+
const result = new Map<K, U>();
|
|
65
|
+
for (const [key, value] of map.entries()) {
|
|
66
|
+
result.set(key, fn(value, key));
|
|
67
|
+
}
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Filter map entries by predicate.
|
|
73
|
+
*/
|
|
74
|
+
static filter<K, V>(map: Map<K, V>, predicate: (value: V, key: K) => boolean): Map<K, V> {
|
|
75
|
+
const result = new Map<K, V>();
|
|
76
|
+
for (const [key, value] of map.entries()) {
|
|
77
|
+
if (predicate(value, key)) {
|
|
78
|
+
result.set(key, value);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return result;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Merge multiple maps. Later maps override earlier ones.
|
|
86
|
+
*/
|
|
87
|
+
static merge<K, V>(...maps: Array<Map<K, V>>): Map<K, V> {
|
|
88
|
+
const result = new Map<K, V>();
|
|
89
|
+
for (const map of maps) {
|
|
90
|
+
for (const [key, value] of map.entries()) {
|
|
91
|
+
result.set(key, value);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Set utilities for set operations.
|
|
3
|
+
*/
|
|
4
|
+
export class SetTools {
|
|
5
|
+
/**
|
|
6
|
+
* Union of two sets (all elements from both sets).
|
|
7
|
+
*/
|
|
8
|
+
static union<T>(a: Set<T>, b: Set<T>): Set<T> {
|
|
9
|
+
const result = new Set<T>(a);
|
|
10
|
+
for (const item of b) {
|
|
11
|
+
result.add(item);
|
|
12
|
+
}
|
|
13
|
+
return result;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Intersection of two sets (elements in both sets).
|
|
18
|
+
*/
|
|
19
|
+
static intersection<T>(a: Set<T>, b: Set<T>): Set<T> {
|
|
20
|
+
const result = new Set<T>();
|
|
21
|
+
for (const item of a) {
|
|
22
|
+
if (b.has(item)) {
|
|
23
|
+
result.add(item);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Difference of two sets (elements in first set but not second).
|
|
31
|
+
*/
|
|
32
|
+
static difference<T>(a: Set<T>, b: Set<T>): Set<T> {
|
|
33
|
+
const result = new Set<T>();
|
|
34
|
+
for (const item of a) {
|
|
35
|
+
if (!b.has(item)) {
|
|
36
|
+
result.add(item);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Symmetric difference (elements in either set but not both).
|
|
44
|
+
*/
|
|
45
|
+
static symmetricDifference<T>(a: Set<T>, b: Set<T>): Set<T> {
|
|
46
|
+
const result = new Set<T>();
|
|
47
|
+
for (const item of a) {
|
|
48
|
+
if (!b.has(item)) {
|
|
49
|
+
result.add(item);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
for (const item of b) {
|
|
53
|
+
if (!a.has(item)) {
|
|
54
|
+
result.add(item);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Check if first set is subset of second.
|
|
62
|
+
*/
|
|
63
|
+
static isSubset<T>(a: Set<T>, b: Set<T>): boolean {
|
|
64
|
+
for (const item of a) {
|
|
65
|
+
if (!b.has(item)) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Check if first set is superset of second.
|
|
74
|
+
*/
|
|
75
|
+
static isSuperset<T>(a: Set<T>, b: Set<T>): boolean {
|
|
76
|
+
return SetTools.isSubset(b, a);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Check if sets are disjoint (no common elements).
|
|
81
|
+
*/
|
|
82
|
+
static isDisjoint<T>(a: Set<T>, b: Set<T>): boolean {
|
|
83
|
+
for (const item of a) {
|
|
84
|
+
if (b.has(item)) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Convert set to array.
|
|
93
|
+
*/
|
|
94
|
+
static toArray<T>(set: Set<T>): Array<T> {
|
|
95
|
+
return Array.from(set);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Create set from array.
|
|
100
|
+
*/
|
|
101
|
+
static fromArray<T>(arr: Array<T>): Set<T> {
|
|
102
|
+
return new Set(arr);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Filter set by predicate.
|
|
107
|
+
*/
|
|
108
|
+
static filter<T>(set: Set<T>, predicate: (item: T) => boolean): Set<T> {
|
|
109
|
+
const result = new Set<T>();
|
|
110
|
+
for (const item of set) {
|
|
111
|
+
if (predicate(item)) {
|
|
112
|
+
result.add(item);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Map over set values.
|
|
120
|
+
*/
|
|
121
|
+
static map<T, U>(set: Set<T>, fn: (item: T) => U): Set<U> {
|
|
122
|
+
const result = new Set<U>();
|
|
123
|
+
for (const item of set) {
|
|
124
|
+
result.add(fn(item));
|
|
125
|
+
}
|
|
126
|
+
return result;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* String parsing utilities with dual error handling pattern.
|
|
3
|
+
*/
|
|
4
|
+
export class StringTools {
|
|
5
|
+
/**
|
|
6
|
+
* Parse integer from string. Throws on invalid input.
|
|
7
|
+
*/
|
|
8
|
+
static parseInt(s: string): number {
|
|
9
|
+
const result = StringTools.tryParseInt(s);
|
|
10
|
+
if (result === null) {
|
|
11
|
+
throw new Error(`Invalid integer: "${s}"`);
|
|
12
|
+
}
|
|
13
|
+
return result;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Parse integer from string. Returns null on invalid input.
|
|
18
|
+
*/
|
|
19
|
+
static tryParseInt(s: string): number | null {
|
|
20
|
+
const trimmed = s.trim();
|
|
21
|
+
if (trimmed === '') {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const parsed = Number.parseInt(trimmed, 10);
|
|
26
|
+
if (Number.isNaN(parsed)) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Ensure the entire string was consumed (no trailing garbage)
|
|
31
|
+
if (!/^-?\d+$/.test(trimmed)) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return parsed;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Parse float from string. Throws on invalid input.
|
|
40
|
+
*/
|
|
41
|
+
static parseFloat(s: string): number {
|
|
42
|
+
const result = StringTools.tryParseFloat(s);
|
|
43
|
+
if (result === null) {
|
|
44
|
+
throw new Error(`Invalid number: "${s}"`);
|
|
45
|
+
}
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Parse float from string. Returns null on invalid input.
|
|
51
|
+
*/
|
|
52
|
+
static tryParseFloat(s: string): number | null {
|
|
53
|
+
const trimmed = s.trim();
|
|
54
|
+
if (trimmed === '') {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const parsed = Number.parseFloat(trimmed);
|
|
59
|
+
if (Number.isNaN(parsed)) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return parsed;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Check if string contains substring.
|
|
68
|
+
*/
|
|
69
|
+
static contains(s: string, substring: string): boolean {
|
|
70
|
+
return s.includes(substring);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Check if string starts with prefix.
|
|
75
|
+
*/
|
|
76
|
+
static startsWith(s: string, prefix: string): boolean {
|
|
77
|
+
return s.startsWith(prefix);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Check if string ends with suffix.
|
|
82
|
+
*/
|
|
83
|
+
static endsWith(s: string, suffix: string): boolean {
|
|
84
|
+
return s.endsWith(suffix);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Repeat string n times.
|
|
89
|
+
*/
|
|
90
|
+
static repeat(s: string, count: number): string {
|
|
91
|
+
if (count < 0) {
|
|
92
|
+
throw new Error(`Repeat count must be non-negative: ${count}`);
|
|
93
|
+
}
|
|
94
|
+
return s.repeat(count);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Reverse string.
|
|
99
|
+
*/
|
|
100
|
+
static reverse(s: string): string {
|
|
101
|
+
return s.split('').reverse().join('');
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Pad string to length on left with fillString.
|
|
106
|
+
*/
|
|
107
|
+
static padLeft(s: string, length: number, fillString: string = ' '): string {
|
|
108
|
+
return s.padStart(length, fillString);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Pad string to length on right with fillString.
|
|
113
|
+
*/
|
|
114
|
+
static padRight(s: string, length: number, fillString: string = ' '): string {
|
|
115
|
+
return s.padEnd(length, fillString);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Split string by separator.
|
|
120
|
+
*/
|
|
121
|
+
static split(s: string, separator: string): Array<string> {
|
|
122
|
+
return s.split(separator);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Join array of strings with separator.
|
|
127
|
+
*/
|
|
128
|
+
static join(parts: Array<string>, separator: string = ''): string {
|
|
129
|
+
return parts.join(separator);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Convert string to uppercase.
|
|
134
|
+
*/
|
|
135
|
+
static toUpperCase(s: string): string {
|
|
136
|
+
return s.toUpperCase();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Convert string to lowercase.
|
|
141
|
+
*/
|
|
142
|
+
static toLowerCase(s: string): string {
|
|
143
|
+
return s.toLowerCase();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Trim whitespace from both ends.
|
|
148
|
+
*/
|
|
149
|
+
static trim(s: string): string {
|
|
150
|
+
return s.trim();
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Trim whitespace from left end.
|
|
155
|
+
*/
|
|
156
|
+
static trimLeft(s: string): string {
|
|
157
|
+
return s.trimStart();
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Trim whitespace from right end.
|
|
162
|
+
*/
|
|
163
|
+
static trimRight(s: string): string {
|
|
164
|
+
return s.trimEnd();
|
|
165
|
+
}
|
|
166
|
+
}
|