@gesslar/toolkit 3.9.0 → 3.12.3
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 +3 -3
- package/src/browser/lib/Data.js +89 -5
- package/src/browser/lib/TypeSpec.js +3 -1
- package/src/lib/CappedDirectoryObject.js +71 -470
- package/src/lib/DirectoryObject.js +94 -146
- package/src/lib/FS.js +221 -70
- package/src/lib/FileObject.js +78 -81
- package/src/lib/TempDirectoryObject.js +92 -141
- package/src/lib/Valid.js +1 -1
- package/src/types/browser/lib/Data.d.ts +46 -2
- package/src/types/browser/lib/Data.d.ts.map +1 -1
- package/src/types/browser/lib/TypeSpec.d.ts.map +1 -1
- package/src/types/lib/CappedDirectoryObject.d.ts +30 -55
- package/src/types/lib/CappedDirectoryObject.d.ts.map +1 -1
- package/src/types/lib/DirectoryObject.d.ts +13 -54
- package/src/types/lib/DirectoryObject.d.ts.map +1 -1
- package/src/types/lib/FS.d.ts +115 -15
- package/src/types/lib/FS.d.ts.map +1 -1
- package/src/types/lib/FileObject.d.ts +6 -3
- package/src/types/lib/FileObject.d.ts.map +1 -1
- package/src/types/lib/TempDirectoryObject.d.ts +15 -62
- package/src/types/lib/TempDirectoryObject.d.ts.map +1 -1
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"name": "gesslar",
|
|
6
6
|
"url": "https://gesslar.dev"
|
|
7
7
|
},
|
|
8
|
-
"version": "3.
|
|
8
|
+
"version": "3.12.3",
|
|
9
9
|
"license": "Unlicense",
|
|
10
10
|
"homepage": "https://github.com/gesslar/toolkit#readme",
|
|
11
11
|
"repository": {
|
|
@@ -53,12 +53,11 @@
|
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@gesslar/colours": "^0.7.1",
|
|
55
55
|
"ajv": "^8.17.1",
|
|
56
|
-
"globby": "^16.1.0",
|
|
57
56
|
"json5": "^2.2.3",
|
|
58
57
|
"yaml": "^2.8.2"
|
|
59
58
|
},
|
|
60
59
|
"devDependencies": {
|
|
61
|
-
"@gesslar/uglier": "^0.
|
|
60
|
+
"@gesslar/uglier": "^0.6.0",
|
|
62
61
|
"eslint": "^9.39.2",
|
|
63
62
|
"happy-dom": "^20.0.11",
|
|
64
63
|
"typescript": "^5.9.3"
|
|
@@ -70,6 +69,7 @@
|
|
|
70
69
|
"submit": "pnpm publish --access public --//registry.npmjs.org/:_authToken=\"${NPM_ACCESS_TOKEN}\"",
|
|
71
70
|
"update": "pnpm up --latest --recursive",
|
|
72
71
|
"test": "node --test tests/**/*.test.js",
|
|
72
|
+
"test:coverage": "node --experimental-config-file=node.config.json --experimental-test-coverage --test-timeout=3000 --test tests/**/*.test.js",
|
|
73
73
|
"test:node": "node --test tests/node/*.test.js",
|
|
74
74
|
"test:browser": "node --test tests/browser/*.test.js",
|
|
75
75
|
"pr": "gt submit -p --ai",
|
package/src/browser/lib/Data.js
CHANGED
|
@@ -75,7 +75,7 @@ export default class Data {
|
|
|
75
75
|
*
|
|
76
76
|
* @type {Array<string>}
|
|
77
77
|
*/
|
|
78
|
-
static emptyableTypes = Object.freeze(["String", "Array", "Object"])
|
|
78
|
+
static emptyableTypes = Object.freeze(["String", "Array", "Object", "Map", "Set"])
|
|
79
79
|
|
|
80
80
|
/**
|
|
81
81
|
* Appends a string to another string if it does not already end with it.
|
|
@@ -84,8 +84,10 @@ export default class Data {
|
|
|
84
84
|
* @param {string} append - The string to append
|
|
85
85
|
* @returns {string} The appended string
|
|
86
86
|
*/
|
|
87
|
-
static
|
|
88
|
-
return string.endsWith(append)
|
|
87
|
+
static append(string, append) {
|
|
88
|
+
return string.endsWith(append)
|
|
89
|
+
? string :
|
|
90
|
+
`${string}${append}`
|
|
89
91
|
}
|
|
90
92
|
|
|
91
93
|
/**
|
|
@@ -95,8 +97,87 @@ export default class Data {
|
|
|
95
97
|
* @param {string} prepend - The string to prepend
|
|
96
98
|
* @returns {string} The prepended string
|
|
97
99
|
*/
|
|
98
|
-
static
|
|
99
|
-
return string.startsWith(prepend)
|
|
100
|
+
static prepend(string, prepend) {
|
|
101
|
+
return string.startsWith(prepend)
|
|
102
|
+
? string
|
|
103
|
+
: `${prepend}${string}`
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Remove a suffix from the end of a string if present.
|
|
108
|
+
*
|
|
109
|
+
* @param {string} string - The string to process
|
|
110
|
+
* @param {string} toChop - The suffix to remove from the end
|
|
111
|
+
* @param {boolean} [caseInsensitive=false] - Whether to perform case-insensitive matching
|
|
112
|
+
* @returns {string} The string with suffix removed, or original if suffix not found
|
|
113
|
+
* @example
|
|
114
|
+
* Data.chopRight("hello.txt", ".txt") // "hello"
|
|
115
|
+
* Data.chopRight("Hello", "o") // "Hell"
|
|
116
|
+
* Data.chopRight("HELLO", "lo", true) // "HEL"
|
|
117
|
+
*/
|
|
118
|
+
static chopRight(string, toChop, caseInsensitive=false) {
|
|
119
|
+
const escaped = toChop.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
|
|
120
|
+
const regex = new RegExp(`${escaped}$`, caseInsensitive === true ? "i" : "")
|
|
121
|
+
|
|
122
|
+
return string.replace(regex, "")
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Remove a prefix from the beginning of a string if present.
|
|
127
|
+
*
|
|
128
|
+
* @param {string} string - The string to process
|
|
129
|
+
* @param {string} toChop - The prefix to remove from the beginning
|
|
130
|
+
* @param {boolean} [caseInsensitive=false] - Whether to perform case-insensitive matching
|
|
131
|
+
* @returns {string} The string with prefix removed, or original if prefix not found
|
|
132
|
+
* @example
|
|
133
|
+
* Data.chopLeft("hello.txt", "hello") // ".txt"
|
|
134
|
+
* Data.chopLeft("Hello", "H") // "ello"
|
|
135
|
+
* Data.chopLeft("HELLO", "he", true) // "LLO"
|
|
136
|
+
*/
|
|
137
|
+
static chopLeft(string, toChop, caseInsensitive=false) {
|
|
138
|
+
const escaped = toChop.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
|
|
139
|
+
const regex = new RegExp(`^${escaped}`, caseInsensitive === true ? "i" : "")
|
|
140
|
+
|
|
141
|
+
return string.replace(regex, "")
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Chop a string after the first occurence of another string.
|
|
146
|
+
*
|
|
147
|
+
* @param {string} string - The string to search
|
|
148
|
+
* @param {string} needle - The bit to chop after
|
|
149
|
+
* @param {boolean} caseInsensitive - Whether to search insensitive to case
|
|
150
|
+
* @returns {string} The remaining string
|
|
151
|
+
*/
|
|
152
|
+
static chopAfter(string, needle, caseInsensitive=false) {
|
|
153
|
+
const escaped = needle.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
|
|
154
|
+
const regex = new RegExp(`${escaped}`, caseInsensitive === true ? "i" : "")
|
|
155
|
+
const index = string.search(regex)
|
|
156
|
+
|
|
157
|
+
if(index === -1)
|
|
158
|
+
return string
|
|
159
|
+
|
|
160
|
+
return string.slice(0, index)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Chop a string before the first occurrence of another string.
|
|
165
|
+
*
|
|
166
|
+
* @param {string} string - The string to search
|
|
167
|
+
* @param {string} needle - The bit to chop before
|
|
168
|
+
* @param {boolean} caseInsensitive - Whether to search insensitive to case
|
|
169
|
+
* @returns {string} The remaining string
|
|
170
|
+
*/
|
|
171
|
+
static chopBefore(string, needle, caseInsensitive=false) {
|
|
172
|
+
const escaped = needle.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
|
|
173
|
+
const regex = new RegExp(`${escaped}`, caseInsensitive === true ? "i" : "")
|
|
174
|
+
const length = needle.length
|
|
175
|
+
const index = string.search(regex)
|
|
176
|
+
|
|
177
|
+
if(index === -1)
|
|
178
|
+
return string
|
|
179
|
+
|
|
180
|
+
return string.slice(index + length)
|
|
100
181
|
}
|
|
101
182
|
|
|
102
183
|
/**
|
|
@@ -236,6 +317,9 @@ export default class Data {
|
|
|
236
317
|
return Object.keys(value).length === 0
|
|
237
318
|
case "String":
|
|
238
319
|
return value.trim().length === 0
|
|
320
|
+
case "Map":
|
|
321
|
+
case "Set":
|
|
322
|
+
return value.size === 0
|
|
239
323
|
default:
|
|
240
324
|
return false
|
|
241
325
|
}
|
|
@@ -144,7 +144,6 @@ export default class TypeSpec {
|
|
|
144
144
|
|
|
145
145
|
match(value, options) {
|
|
146
146
|
const allowEmpty = options?.allowEmpty ?? true
|
|
147
|
-
const empty = Data.isEmpty(value)
|
|
148
147
|
|
|
149
148
|
// If we have a list of types, because the string was validly parsed, we
|
|
150
149
|
// need to ensure that all of the types that were parsed are valid types in
|
|
@@ -161,6 +160,9 @@ export default class TypeSpec {
|
|
|
161
160
|
// types in an array, if it is an array and an array is allowed.
|
|
162
161
|
const matchingTypeSpec = this.filter(spec => {
|
|
163
162
|
const {typeName: allowedType, array: allowedArray} = spec
|
|
163
|
+
const empty =
|
|
164
|
+
Data.emptyableTypes.includes(allowedType) &&
|
|
165
|
+
Data.isEmpty(value)
|
|
164
166
|
|
|
165
167
|
// Handle non-array values
|
|
166
168
|
if(!isArray && !allowedArray) {
|