ts-data-forge 11.0.1 → 12.1.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 +2 -2
- package/dist/array/impl/array-utils-length-bounded-array-cast.d.mts +65 -5
- package/dist/array/impl/array-utils-length-bounded-array-cast.d.mts.map +1 -1
- package/dist/array/impl/array-utils-length-bounded-array-cast.mjs +69 -27
- package/dist/array/impl/array-utils-length-bounded-array-cast.mjs.map +1 -1
- package/dist/array/impl/index.mjs +1 -1
- package/dist/number/branded-types/int16.d.mts +12 -7
- package/dist/number/branded-types/int16.d.mts.map +1 -1
- package/dist/number/branded-types/int16.mjs +13 -8
- package/dist/number/branded-types/int16.mjs.map +1 -1
- package/dist/number/branded-types/int32.d.mts +12 -7
- package/dist/number/branded-types/int32.d.mts.map +1 -1
- package/dist/number/branded-types/int32.mjs +13 -8
- package/dist/number/branded-types/int32.mjs.map +1 -1
- package/dist/number/branded-types/negative-finite-number.d.mts +13 -6
- package/dist/number/branded-types/negative-finite-number.d.mts.map +1 -1
- package/dist/number/branded-types/negative-finite-number.mjs +15 -8
- package/dist/number/branded-types/negative-finite-number.mjs.map +1 -1
- package/dist/number/branded-types/negative-int.d.mts +11 -6
- package/dist/number/branded-types/negative-int.d.mts.map +1 -1
- package/dist/number/branded-types/negative-int.mjs +13 -8
- package/dist/number/branded-types/negative-int.mjs.map +1 -1
- package/dist/number/branded-types/negative-safe-int.d.mts +13 -7
- package/dist/number/branded-types/negative-safe-int.d.mts.map +1 -1
- package/dist/number/branded-types/negative-safe-int.mjs +15 -9
- package/dist/number/branded-types/negative-safe-int.mjs.map +1 -1
- package/dist/number/branded-types/non-negative-finite-number.d.mts +11 -6
- package/dist/number/branded-types/non-negative-finite-number.d.mts.map +1 -1
- package/dist/number/branded-types/non-negative-finite-number.mjs +12 -7
- package/dist/number/branded-types/non-negative-finite-number.mjs.map +1 -1
- package/dist/number/branded-types/non-negative-int16.d.mts +13 -7
- package/dist/number/branded-types/non-negative-int16.d.mts.map +1 -1
- package/dist/number/branded-types/non-negative-int16.mjs +14 -8
- package/dist/number/branded-types/non-negative-int16.mjs.map +1 -1
- package/dist/number/branded-types/non-negative-int32.d.mts +13 -7
- package/dist/number/branded-types/non-negative-int32.d.mts.map +1 -1
- package/dist/number/branded-types/non-negative-int32.mjs +14 -8
- package/dist/number/branded-types/non-negative-int32.mjs.map +1 -1
- package/dist/number/branded-types/non-positive-finite-number.d.mts +11 -6
- package/dist/number/branded-types/non-positive-finite-number.d.mts.map +1 -1
- package/dist/number/branded-types/non-positive-finite-number.mjs +12 -7
- package/dist/number/branded-types/non-positive-finite-number.mjs.map +1 -1
- package/dist/number/branded-types/non-positive-int.d.mts +11 -6
- package/dist/number/branded-types/non-positive-int.d.mts.map +1 -1
- package/dist/number/branded-types/non-positive-int.mjs +12 -7
- package/dist/number/branded-types/non-positive-int.mjs.map +1 -1
- package/dist/number/branded-types/non-positive-safe-int.d.mts +14 -7
- package/dist/number/branded-types/non-positive-safe-int.d.mts.map +1 -1
- package/dist/number/branded-types/non-positive-safe-int.mjs +15 -8
- package/dist/number/branded-types/non-positive-safe-int.mjs.map +1 -1
- package/dist/number/branded-types/non-zero-int16.d.mts +13 -7
- package/dist/number/branded-types/non-zero-int16.d.mts.map +1 -1
- package/dist/number/branded-types/non-zero-int16.mjs +14 -8
- package/dist/number/branded-types/non-zero-int16.mjs.map +1 -1
- package/dist/number/branded-types/non-zero-int32.d.mts +13 -7
- package/dist/number/branded-types/non-zero-int32.d.mts.map +1 -1
- package/dist/number/branded-types/non-zero-int32.mjs +14 -8
- package/dist/number/branded-types/non-zero-int32.mjs.map +1 -1
- package/dist/number/branded-types/non-zero-safe-int.d.mts +13 -7
- package/dist/number/branded-types/non-zero-safe-int.d.mts.map +1 -1
- package/dist/number/branded-types/non-zero-safe-int.mjs +14 -8
- package/dist/number/branded-types/non-zero-safe-int.mjs.map +1 -1
- package/dist/number/branded-types/non-zero-uint16.d.mts +13 -7
- package/dist/number/branded-types/non-zero-uint16.d.mts.map +1 -1
- package/dist/number/branded-types/non-zero-uint16.mjs +14 -8
- package/dist/number/branded-types/non-zero-uint16.mjs.map +1 -1
- package/dist/number/branded-types/non-zero-uint32.d.mts +13 -7
- package/dist/number/branded-types/non-zero-uint32.d.mts.map +1 -1
- package/dist/number/branded-types/non-zero-uint32.mjs +14 -8
- package/dist/number/branded-types/non-zero-uint32.mjs.map +1 -1
- package/dist/number/branded-types/positive-finite-number.d.mts +13 -6
- package/dist/number/branded-types/positive-finite-number.d.mts.map +1 -1
- package/dist/number/branded-types/positive-finite-number.mjs +14 -7
- package/dist/number/branded-types/positive-finite-number.mjs.map +1 -1
- package/dist/number/branded-types/positive-int.d.mts +13 -8
- package/dist/number/branded-types/positive-int.d.mts.map +1 -1
- package/dist/number/branded-types/positive-int.mjs +14 -9
- package/dist/number/branded-types/positive-int.mjs.map +1 -1
- package/dist/number/branded-types/positive-int16.d.mts +13 -7
- package/dist/number/branded-types/positive-int16.d.mts.map +1 -1
- package/dist/number/branded-types/positive-int16.mjs +14 -8
- package/dist/number/branded-types/positive-int16.mjs.map +1 -1
- package/dist/number/branded-types/positive-int32.d.mts +13 -7
- package/dist/number/branded-types/positive-int32.d.mts.map +1 -1
- package/dist/number/branded-types/positive-int32.mjs +14 -8
- package/dist/number/branded-types/positive-int32.mjs.map +1 -1
- package/dist/number/branded-types/positive-safe-int.d.mts +16 -10
- package/dist/number/branded-types/positive-safe-int.d.mts.map +1 -1
- package/dist/number/branded-types/positive-safe-int.mjs +17 -11
- package/dist/number/branded-types/positive-safe-int.mjs.map +1 -1
- package/dist/number/branded-types/positive-uint16.d.mts +13 -7
- package/dist/number/branded-types/positive-uint16.d.mts.map +1 -1
- package/dist/number/branded-types/positive-uint16.mjs +14 -8
- package/dist/number/branded-types/positive-uint16.mjs.map +1 -1
- package/dist/number/branded-types/positive-uint32.d.mts +13 -7
- package/dist/number/branded-types/positive-uint32.d.mts.map +1 -1
- package/dist/number/branded-types/positive-uint32.mjs +14 -8
- package/dist/number/branded-types/positive-uint32.mjs.map +1 -1
- package/dist/number/branded-types/safe-int.d.mts +15 -10
- package/dist/number/branded-types/safe-int.d.mts.map +1 -1
- package/dist/number/branded-types/safe-int.mjs +16 -11
- package/dist/number/branded-types/safe-int.mjs.map +1 -1
- package/dist/number/branded-types/safe-uint.d.mts +12 -7
- package/dist/number/branded-types/safe-uint.d.mts.map +1 -1
- package/dist/number/branded-types/safe-uint.mjs +13 -8
- package/dist/number/branded-types/safe-uint.mjs.map +1 -1
- package/dist/number/branded-types/uint.d.mts +14 -10
- package/dist/number/branded-types/uint.d.mts.map +1 -1
- package/dist/number/branded-types/uint.mjs +15 -11
- package/dist/number/branded-types/uint.mjs.map +1 -1
- package/dist/number/branded-types/uint16.d.mts +12 -7
- package/dist/number/branded-types/uint16.d.mts.map +1 -1
- package/dist/number/branded-types/uint16.mjs +13 -8
- package/dist/number/branded-types/uint16.mjs.map +1 -1
- package/dist/number/branded-types/uint32.d.mts +12 -7
- package/dist/number/branded-types/uint32.d.mts.map +1 -1
- package/dist/number/branded-types/uint32.mjs +13 -8
- package/dist/number/branded-types/uint32.mjs.map +1 -1
- package/dist/number/enum/int8.d.mts +12 -7
- package/dist/number/enum/int8.d.mts.map +1 -1
- package/dist/number/enum/int8.mjs +19 -14
- package/dist/number/enum/int8.mjs.map +1 -1
- package/dist/number/enum/uint8.d.mts +12 -7
- package/dist/number/enum/uint8.d.mts.map +1 -1
- package/dist/number/enum/uint8.mjs +19 -14
- package/dist/number/enum/uint8.mjs.map +1 -1
- package/dist/number/refined-number-utils.d.mts +9 -9
- package/dist/number/refined-number-utils.d.mts.map +1 -1
- package/dist/number/refined-number-utils.mjs +7 -7
- package/dist/number/refined-number-utils.mjs.map +1 -1
- package/dist/string/str.d.mts +70 -5
- package/dist/string/str.d.mts.map +1 -1
- package/dist/string/str.mjs +72 -26
- package/dist/string/str.mjs.map +1 -1
- package/package.json +1 -1
- package/src/array/impl/array-utils-length-bounded-array-cast.mts +204 -39
- package/src/array/impl/array-utils-length-bounded-array-cast.test.mts +126 -0
- package/src/number/branded-types/int16.mts +13 -8
- package/src/number/branded-types/int32.mts +13 -8
- package/src/number/branded-types/negative-finite-number.mts +15 -8
- package/src/number/branded-types/negative-finite-number.test.mts +4 -4
- package/src/number/branded-types/negative-int.mts +13 -8
- package/src/number/branded-types/negative-int.test.mts +5 -5
- package/src/number/branded-types/negative-safe-int.mts +15 -9
- package/src/number/branded-types/negative-safe-int.test.mts +4 -4
- package/src/number/branded-types/non-negative-finite-number.mts +12 -7
- package/src/number/branded-types/non-negative-int16.mts +14 -8
- package/src/number/branded-types/non-negative-int32.mts +14 -8
- package/src/number/branded-types/non-positive-finite-number.mts +12 -7
- package/src/number/branded-types/non-positive-finite-number.test.mts +7 -7
- package/src/number/branded-types/non-positive-int.mts +12 -7
- package/src/number/branded-types/non-positive-int.test.mts +7 -7
- package/src/number/branded-types/non-positive-safe-int.mts +15 -8
- package/src/number/branded-types/non-positive-safe-int.test.mts +7 -7
- package/src/number/branded-types/non-zero-int16.mts +14 -8
- package/src/number/branded-types/non-zero-int32.mts +14 -8
- package/src/number/branded-types/non-zero-safe-int.mts +14 -8
- package/src/number/branded-types/non-zero-uint16.mts +14 -8
- package/src/number/branded-types/non-zero-uint32.mts +14 -8
- package/src/number/branded-types/positive-finite-number.mts +14 -7
- package/src/number/branded-types/positive-int.mts +14 -9
- package/src/number/branded-types/positive-int16.mts +14 -8
- package/src/number/branded-types/positive-int32.mts +14 -8
- package/src/number/branded-types/positive-safe-int.mts +17 -11
- package/src/number/branded-types/positive-uint16.mts +14 -8
- package/src/number/branded-types/positive-uint32.mts +14 -8
- package/src/number/branded-types/safe-int.mts +16 -11
- package/src/number/branded-types/safe-uint.mts +13 -8
- package/src/number/branded-types/uint.mts +15 -11
- package/src/number/branded-types/uint16.mts +13 -8
- package/src/number/branded-types/uint32.mts +13 -8
- package/src/number/enum/int8.mts +20 -14
- package/src/number/enum/int8.test.mts +7 -4
- package/src/number/enum/uint8.mts +20 -14
- package/src/number/enum/uint8.test.mts +7 -4
- package/src/number/refined-number-utils.mts +22 -19
- package/src/string/str.mts +201 -39
- package/src/string/str.test.mts +76 -0
package/dist/string/str.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type BoundedLengthString, type FixedLengthString, type MaxLengthString, type MinLengthString, type SupportedLength } from 'ts-type-forge';
|
|
1
|
+
import { type BoundedLengthString, type FixedLengthString, type MaxLengthString, type MinLengthString, type NonEmptyString, type SupportedLength } from 'ts-type-forge';
|
|
2
2
|
/**
|
|
3
3
|
* Namespace providing type guards and runtime-checked casts for the branded
|
|
4
4
|
* length-constrained string types (`MinLengthString`, `MaxLengthString`,
|
|
@@ -162,6 +162,9 @@ export declare namespace Str {
|
|
|
162
162
|
* length is verified at runtime, and the original string type (e.g. literal
|
|
163
163
|
* types) is preserved via intersection.
|
|
164
164
|
*
|
|
165
|
+
* Supports a curried overload: calling it with only `minLength` returns a
|
|
166
|
+
* function that casts a string, which is convenient for `pipe`/`map`.
|
|
167
|
+
*
|
|
165
168
|
* @example
|
|
166
169
|
*
|
|
167
170
|
* ```ts
|
|
@@ -171,6 +174,11 @@ export declare namespace Str {
|
|
|
171
174
|
*
|
|
172
175
|
* assert.isTrue(nonEmpty.length >= 12);
|
|
173
176
|
*
|
|
177
|
+
* // curried version
|
|
178
|
+
* const asPassword = Str.asMinLengthString(12);
|
|
179
|
+
*
|
|
180
|
+
* assert.strictEqual(asPassword('another-secret'), 'another-secret');
|
|
181
|
+
*
|
|
174
182
|
* assert.throws(() => Str.asMinLengthString('short', 12)); // length 5 < 12
|
|
175
183
|
* ```
|
|
176
184
|
*
|
|
@@ -181,7 +189,8 @@ export declare namespace Str {
|
|
|
181
189
|
* @returns `s` typed as `MinLengthString<MinLength> & S`.
|
|
182
190
|
* @throws {TypeError} If `s.length < minLength`.
|
|
183
191
|
*/
|
|
184
|
-
|
|
192
|
+
function asMinLengthString<S extends string, MinLength extends SupportedLength>(s: S, minLength: MinLength): MinLengthString<MinLength> & S;
|
|
193
|
+
function asMinLengthString<MinLength extends SupportedLength>(minLength: MinLength): <S extends string>(s: S) => MinLengthString<MinLength> & S;
|
|
185
194
|
/**
|
|
186
195
|
* Casts a string to `MaxLengthString<MaxLength>` after checking that it has
|
|
187
196
|
* at most `maxLength` characters.
|
|
@@ -190,6 +199,9 @@ export declare namespace Str {
|
|
|
190
199
|
* length is verified at runtime, and the original string type (e.g. literal
|
|
191
200
|
* types) is preserved via intersection.
|
|
192
201
|
*
|
|
202
|
+
* Supports a curried overload: calling it with only `maxLength` returns a
|
|
203
|
+
* function that casts a string, which is convenient for `pipe`/`map`.
|
|
204
|
+
*
|
|
193
205
|
* @example
|
|
194
206
|
*
|
|
195
207
|
* ```ts
|
|
@@ -199,6 +211,11 @@ export declare namespace Str {
|
|
|
199
211
|
*
|
|
200
212
|
* assert.isTrue(relaxed.length <= 32);
|
|
201
213
|
*
|
|
214
|
+
* // curried version
|
|
215
|
+
* const asUserName = Str.asMaxLengthString(32);
|
|
216
|
+
*
|
|
217
|
+
* assert.strictEqual(asUserName('another-user'), 'another-user');
|
|
218
|
+
*
|
|
202
219
|
* assert.throws(() => Str.asMaxLengthString('noshiro', 3)); // length 7 > 3
|
|
203
220
|
* ```
|
|
204
221
|
*
|
|
@@ -209,7 +226,8 @@ export declare namespace Str {
|
|
|
209
226
|
* @returns `s` typed as `MaxLengthString<MaxLength> & S`.
|
|
210
227
|
* @throws {TypeError} If `s.length > maxLength`.
|
|
211
228
|
*/
|
|
212
|
-
|
|
229
|
+
function asMaxLengthString<S extends string, MaxLength extends SupportedLength>(s: S, maxLength: MaxLength): MaxLengthString<MaxLength> & S;
|
|
230
|
+
function asMaxLengthString<MaxLength extends SupportedLength>(maxLength: MaxLength): <S extends string>(s: S) => MaxLengthString<MaxLength> & S;
|
|
213
231
|
/**
|
|
214
232
|
* Casts a string to `BoundedLengthString<MinLength, MaxLength>` after
|
|
215
233
|
* checking that its length is within the inclusive range
|
|
@@ -219,6 +237,10 @@ export declare namespace Str {
|
|
|
219
237
|
* the length is verified at runtime, and the original string type (e.g.
|
|
220
238
|
* literal types) is preserved via intersection.
|
|
221
239
|
*
|
|
240
|
+
* Supports a curried overload: calling it with only `minLength` and
|
|
241
|
+
* `maxLength` returns a function that casts a string, which is convenient for
|
|
242
|
+
* `pipe`/`map`.
|
|
243
|
+
*
|
|
222
244
|
* @example
|
|
223
245
|
*
|
|
224
246
|
* ```ts
|
|
@@ -228,6 +250,11 @@ export declare namespace Str {
|
|
|
228
250
|
*
|
|
229
251
|
* assert.isTrue(relaxed.length >= 8 && relaxed.length <= 16);
|
|
230
252
|
*
|
|
253
|
+
* // curried version
|
|
254
|
+
* const asUserId = Str.asBoundedLengthString(8, 16);
|
|
255
|
+
*
|
|
256
|
+
* assert.strictEqual(asUserId('user-87654321'), 'user-87654321');
|
|
257
|
+
*
|
|
231
258
|
* assert.throws(() => Str.asBoundedLengthString('user', 8, 16)); // length 4 < 8
|
|
232
259
|
* ```
|
|
233
260
|
*
|
|
@@ -240,7 +267,8 @@ export declare namespace Str {
|
|
|
240
267
|
* @returns `s` typed as `BoundedLengthString<MinLength, MaxLength> & S`.
|
|
241
268
|
* @throws {TypeError} If `s.length < minLength` or `s.length > maxLength`.
|
|
242
269
|
*/
|
|
243
|
-
|
|
270
|
+
function asBoundedLengthString<S extends string, MinLength extends SupportedLength, MaxLength extends SupportedLength>(s: S, minLength: MinLength, maxLength: MaxLength): BoundedLengthString<MinLength, MaxLength> & S;
|
|
271
|
+
function asBoundedLengthString<MinLength extends SupportedLength, MaxLength extends SupportedLength>(minLength: MinLength, maxLength: MaxLength): <S extends string>(s: S) => BoundedLengthString<MinLength, MaxLength> & S;
|
|
244
272
|
/**
|
|
245
273
|
* Casts a string to `FixedLengthString<Length>` after checking that it has
|
|
246
274
|
* exactly `length` characters.
|
|
@@ -249,6 +277,9 @@ export declare namespace Str {
|
|
|
249
277
|
* length is verified at runtime, and the original string type (e.g. literal
|
|
250
278
|
* types) is preserved via intersection.
|
|
251
279
|
*
|
|
280
|
+
* Supports a curried overload: calling it with only `length` returns a
|
|
281
|
+
* function that casts a string, which is convenient for `pipe`/`map`.
|
|
282
|
+
*
|
|
252
283
|
* @example
|
|
253
284
|
*
|
|
254
285
|
* ```ts
|
|
@@ -258,6 +289,11 @@ export declare namespace Str {
|
|
|
258
289
|
*
|
|
259
290
|
* assert.isTrue(atMost5.length === 2);
|
|
260
291
|
*
|
|
292
|
+
* // curried version
|
|
293
|
+
* const asCountryCode = Str.asFixedLengthString(2);
|
|
294
|
+
*
|
|
295
|
+
* assert.strictEqual(asCountryCode('US'), 'US');
|
|
296
|
+
*
|
|
261
297
|
* assert.throws(() => Str.asFixedLengthString('JP', 3)); // length 2 !== 3
|
|
262
298
|
* ```
|
|
263
299
|
*
|
|
@@ -268,6 +304,35 @@ export declare namespace Str {
|
|
|
268
304
|
* @returns `s` typed as `FixedLengthString<Length> & S`.
|
|
269
305
|
* @throws {TypeError} If `s.length !== length`.
|
|
270
306
|
*/
|
|
271
|
-
|
|
307
|
+
function asFixedLengthString<S extends string, Length extends SupportedLength>(s: S, length: Length): FixedLengthString<Length> & S;
|
|
308
|
+
function asFixedLengthString<Length extends SupportedLength>(length: Length): <S extends string>(s: S) => FixedLengthString<Length> & S;
|
|
309
|
+
/**
|
|
310
|
+
* Casts a string to `NonEmptyString` after checking that it has at least one
|
|
311
|
+
* character.
|
|
312
|
+
*
|
|
313
|
+
* `NonEmptyString` is an alias of `MinLengthString<1>`, so this is the
|
|
314
|
+
* length-1 specialization of {@link asMinLengthString}. Use this instead of
|
|
315
|
+
* writing `s as unknown as NonEmptyString`: the length is verified at
|
|
316
|
+
* runtime, and the original string type (e.g. literal types) is preserved
|
|
317
|
+
* via intersection.
|
|
318
|
+
*
|
|
319
|
+
* @example
|
|
320
|
+
*
|
|
321
|
+
* ```ts
|
|
322
|
+
* const name = Str.asNonEmptyString('noshiro');
|
|
323
|
+
*
|
|
324
|
+
* const nonEmpty: NonEmptyString = name; // OK
|
|
325
|
+
*
|
|
326
|
+
* assert.isTrue(nonEmpty.length >= 1);
|
|
327
|
+
*
|
|
328
|
+
* assert.throws(() => Str.asNonEmptyString('')); // length 0 < 1
|
|
329
|
+
* ```
|
|
330
|
+
*
|
|
331
|
+
* @template S - The input string type (literal types are preserved).
|
|
332
|
+
* @param s - The string to cast.
|
|
333
|
+
* @returns `s` typed as `NonEmptyString & S`.
|
|
334
|
+
* @throws {TypeError} If `s` is empty.
|
|
335
|
+
*/
|
|
336
|
+
const asNonEmptyString: <S extends string>(s: S) => NonEmptyString & S;
|
|
272
337
|
}
|
|
273
338
|
//# sourceMappingURL=str.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"str.d.mts","sourceRoot":"","sources":["../../src/string/str.mts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,eAAe,EACrB,MAAM,eAAe,CAAC;AAEvB;;;;;;;;GAQG;AACH,yBAAiB,GAAG,CAAC;IACnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACI,MAAM,iBAAiB,GAC5B,CAAC,SAAS,MAAM,EAChB,SAAS,SAAS,eAAe,KAE9B,CAAC,aACO,SAAS,KACnB,CAAC,IAAI,eAAe,CAAC,SAAS,CAAC,GAAG,CAA0B,CAAC;IAEhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACI,MAAM,iBAAiB,GAC5B,CAAC,SAAS,MAAM,EAChB,SAAS,SAAS,eAAe,KAE9B,CAAC,aACO,SAAS,KACnB,CAAC,IAAI,eAAe,CAAC,SAAS,CAAC,GAAG,CAA0B,CAAC;IAEhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAqCG;IACI,MAAM,qBAAqB,GAChC,CAAC,SAAS,MAAM,EAChB,SAAS,SAAS,eAAe,EACjC,SAAS,SAAS,eAAe,KAE9B,CAAC,aACO,SAAS,aACT,SAAS,KACnB,CAAC,IAAI,mBAAmB,CAAC,SAAS,EAAE,SAAS,CAAC,GAAG,CACJ,CAAC;IAEjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAkCG;IACI,MAAM,mBAAmB,GAC9B,CAAC,SAAS,MAAM,EAChB,MAAM,SAAS,eAAe,KAE3B,CAAC,UACI,MAAM,KACb,CAAC,IAAI,iBAAiB,CAAC,MAAM,CAAC,GAAG,CAAwB,CAAC;IAE7D
|
|
1
|
+
{"version":3,"file":"str.d.mts","sourceRoot":"","sources":["../../src/string/str.mts"],"names":[],"mappings":"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"}
|
package/dist/string/str.mjs
CHANGED
|
@@ -4,35 +4,81 @@ var Str;
|
|
|
4
4
|
Str2.isMaxLengthString = (s, maxLength) => s.length <= maxLength;
|
|
5
5
|
Str2.isBoundedLengthString = (s, minLength, maxLength) => s.length >= minLength && s.length <= maxLength;
|
|
6
6
|
Str2.isFixedLengthString = (s, length) => s.length === length;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
function asMinLengthString(...args) {
|
|
8
|
+
switch (args.length) {
|
|
9
|
+
case 2: {
|
|
10
|
+
const [s, minLength] = args;
|
|
11
|
+
if (!(0, Str2.isMinLengthString)(s, minLength)) {
|
|
12
|
+
throw new TypeError(
|
|
13
|
+
`Expected a string of length >= ${minLength}, got a string of length ${s.length}`
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
return s;
|
|
17
|
+
}
|
|
18
|
+
case 1: {
|
|
19
|
+
const [minLength] = args;
|
|
20
|
+
return (s) => asMinLengthString(s, minLength);
|
|
21
|
+
}
|
|
12
22
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
23
|
+
}
|
|
24
|
+
Str2.asMinLengthString = asMinLengthString;
|
|
25
|
+
function asMaxLengthString(...args) {
|
|
26
|
+
switch (args.length) {
|
|
27
|
+
case 2: {
|
|
28
|
+
const [s, maxLength] = args;
|
|
29
|
+
if (!(0, Str2.isMaxLengthString)(s, maxLength)) {
|
|
30
|
+
throw new TypeError(
|
|
31
|
+
`Expected a string of length <= ${maxLength}, got a string of length ${s.length}`
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
return s;
|
|
35
|
+
}
|
|
36
|
+
case 1: {
|
|
37
|
+
const [maxLength] = args;
|
|
38
|
+
return (s) => asMaxLengthString(s, maxLength);
|
|
39
|
+
}
|
|
20
40
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
41
|
+
}
|
|
42
|
+
Str2.asMaxLengthString = asMaxLengthString;
|
|
43
|
+
function asBoundedLengthString(...args) {
|
|
44
|
+
switch (args.length) {
|
|
45
|
+
case 3: {
|
|
46
|
+
const [s, minLength, maxLength] = args;
|
|
47
|
+
if (!(0, Str2.isBoundedLengthString)(s, minLength, maxLength)) {
|
|
48
|
+
throw new TypeError(
|
|
49
|
+
`Expected a string of length in [${minLength}, ${maxLength}], got a string of length ${s.length}`
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
return s;
|
|
53
|
+
}
|
|
54
|
+
case 2: {
|
|
55
|
+
const [minLength, maxLength] = args;
|
|
56
|
+
return (s) => asBoundedLengthString(s, minLength, maxLength);
|
|
57
|
+
}
|
|
28
58
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
59
|
+
}
|
|
60
|
+
Str2.asBoundedLengthString = asBoundedLengthString;
|
|
61
|
+
function asFixedLengthString(...args) {
|
|
62
|
+
switch (args.length) {
|
|
63
|
+
case 2: {
|
|
64
|
+
const [s, length] = args;
|
|
65
|
+
if (!(0, Str2.isFixedLengthString)(s, length)) {
|
|
66
|
+
throw new TypeError(
|
|
67
|
+
`Expected a string of length ${length}, got a string of length ${s.length}`
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
return s;
|
|
71
|
+
}
|
|
72
|
+
case 1: {
|
|
73
|
+
const [length] = args;
|
|
74
|
+
return (s) => asFixedLengthString(s, length);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
Str2.asFixedLengthString = asFixedLengthString;
|
|
79
|
+
Str2.asNonEmptyString = (s) => {
|
|
80
|
+
if (!(0, Str2.isMinLengthString)(s, 1)) {
|
|
81
|
+
throw new TypeError("Expected a non-empty string, got an empty string");
|
|
36
82
|
}
|
|
37
83
|
return s;
|
|
38
84
|
};
|
package/dist/string/str.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"str.mjs","sources":["../../src/string/str.mts"],"sourcesContent":["import {\n type BoundedLengthString,\n type FixedLengthString,\n type MaxLengthString,\n type MinLengthString,\n type SupportedLength,\n} from 'ts-type-forge';\n\n/**\n * Namespace providing type guards and runtime-checked casts for the branded\n * length-constrained string types (`MinLengthString`, `MaxLengthString`,\n * `BoundedLengthString`, `FixedLengthString`).\n *\n * Lengths are measured in UTF-16 code units (the same unit as\n * `String.prototype.length`), so characters outside the Basic Multilingual\n * Plane (e.g. emoji) count as 2.\n */\nexport namespace Str {\n /**\n * Type guard that checks if a string has at least `minLength` characters.\n *\n * **Type Narrowing Behavior:**\n *\n * - Narrows the input to `MinLengthString<MinLength>` while preserving the\n * original string type (e.g. literal types) via intersection.\n * - The result participates in the length-constraint subtyping relation: for\n * example, a value narrowed to `MinLengthString<3>` is assignable to\n * `MinLengthString<1>` (= `NonEmptyString`).\n *\n * @example\n *\n * ```ts\n * const input: string = 'very-secret-password';\n *\n * assert.isTrue(Str.isMinLengthString(input, 12));\n *\n * assert.isFalse(Str.isMinLengthString('short', 12));\n *\n * if (Str.isMinLengthString(input, 12)) {\n * const nonEmpty: NonEmptyString = input; // OK (12 >= 1)\n *\n * assert.isTrue(nonEmpty.length >= 12);\n * }\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template MinLength - The minimum number of characters (inclusive).\n * @param s - The string to check.\n * @param minLength - The minimum number of characters (inclusive).\n * @returns `true` if `s.length >= minLength`, `false` otherwise. When `true`,\n * TypeScript narrows `s` to `MinLengthString<MinLength> & S`.\n */\n export const isMinLengthString = <\n S extends string,\n MinLength extends SupportedLength,\n >(\n s: S,\n minLength: MinLength,\n ): s is MinLengthString<MinLength> & S => s.length >= minLength;\n\n /**\n * Type guard that checks if a string has at most `maxLength` characters.\n *\n * **Type Narrowing Behavior:**\n *\n * - Narrows the input to `MaxLengthString<MaxLength>` while preserving the\n * original string type (e.g. literal types) via intersection.\n * - The result participates in the length-constraint subtyping relation: for\n * example, a value narrowed to `MaxLengthString<16>` is assignable to\n * `MaxLengthString<32>`.\n *\n * @example\n *\n * ```ts\n * const input: string = 'noshiro';\n *\n * assert.isTrue(Str.isMaxLengthString(input, 32));\n *\n * assert.isFalse(Str.isMaxLengthString(input, 3));\n *\n * if (Str.isMaxLengthString(input, 32)) {\n * const relaxed: MaxLengthString<64> = input; // OK (32 <= 64)\n *\n * assert.isTrue(relaxed.length <= 32);\n * }\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template MaxLength - The maximum number of characters (inclusive).\n * @param s - The string to check.\n * @param maxLength - The maximum number of characters (inclusive).\n * @returns `true` if `s.length <= maxLength`, `false` otherwise. When `true`,\n * TypeScript narrows `s` to `MaxLengthString<MaxLength> & S`.\n */\n export const isMaxLengthString = <\n S extends string,\n MaxLength extends SupportedLength,\n >(\n s: S,\n maxLength: MaxLength,\n ): s is MaxLengthString<MaxLength> & S => s.length <= maxLength;\n\n /**\n * Type guard that checks if a string's length is within the inclusive range\n * `[minLength, maxLength]`.\n *\n * **Type Narrowing Behavior:**\n *\n * - Narrows the input to `BoundedLengthString<MinLength, MaxLength>` while\n * preserving the original string type (e.g. literal types) via intersection.\n * - Since `BoundedLengthString` is the intersection of `MinLengthString` and\n * `MaxLengthString`, the narrowed value is assignable to both, and both\n * bounds can be weakened independently.\n *\n * @example\n *\n * ```ts\n * const input: string = 'user-12345678';\n *\n * assert.isTrue(Str.isBoundedLengthString(input, 8, 16));\n *\n * assert.isFalse(Str.isBoundedLengthString('user', 8, 16));\n *\n * if (Str.isBoundedLengthString(input, 8, 16)) {\n * const userId: BoundedLengthString<1, 255> = input; // OK ([8, 16] ⊆ [1, 255])\n *\n * assert.isTrue(userId.length >= 8 && userId.length <= 16);\n * }\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template MinLength - The minimum number of characters (inclusive).\n * @template MaxLength - The maximum number of characters (inclusive).\n * @param s - The string to check.\n * @param minLength - The minimum number of characters (inclusive).\n * @param maxLength - The maximum number of characters (inclusive).\n * @returns `true` if `minLength <= s.length && s.length <= maxLength`, `false`\n * otherwise. When `true`, TypeScript narrows `s` to\n * `BoundedLengthString<MinLength, MaxLength> & S`.\n */\n export const isBoundedLengthString = <\n S extends string,\n MinLength extends SupportedLength,\n MaxLength extends SupportedLength,\n >(\n s: S,\n minLength: MinLength,\n maxLength: MaxLength,\n ): s is BoundedLengthString<MinLength, MaxLength> & S =>\n s.length >= minLength && s.length <= maxLength;\n\n /**\n * Type guard that checks if a string has exactly `length` characters.\n *\n * **Type Narrowing Behavior:**\n *\n * - Narrows the input to `FixedLengthString<Length>` while preserving the\n * original string type (e.g. literal types) via intersection.\n * - Since `FixedLengthString<Length>` is defined as\n * `BoundedLengthString<Length, Length>`, the narrowed value is assignable to\n * any `MinLengthString<N>` with `N <= Length` and any `MaxLengthString<N>`\n * with `N >= Length`.\n *\n * @example\n *\n * ```ts\n * const input: string = 'JP';\n *\n * assert.isTrue(Str.isFixedLengthString(input, 2));\n *\n * assert.isFalse(Str.isFixedLengthString(input, 3));\n *\n * if (Str.isFixedLengthString(input, 2)) {\n * const atMost5: MaxLengthString<5> = input; // OK (2 <= 5)\n *\n * assert.isTrue(atMost5.length === 2);\n * }\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template Length - The exact number of characters.\n * @param s - The string to check.\n * @param length - The exact number of characters.\n * @returns `true` if `s.length === length`, `false` otherwise. When `true`,\n * TypeScript narrows `s` to `FixedLengthString<Length> & S`.\n */\n export const isFixedLengthString = <\n S extends string,\n Length extends SupportedLength,\n >(\n s: S,\n length: Length,\n ): s is FixedLengthString<Length> & S => s.length === length;\n\n /**\n * Casts a string to `MinLengthString<MinLength>` after checking that it has\n * at least `minLength` characters.\n *\n * Use this instead of writing `s as unknown as MinLengthString<N>`: the\n * length is verified at runtime, and the original string type (e.g. literal\n * types) is preserved via intersection.\n *\n * @example\n *\n * ```ts\n * const password = Str.asMinLengthString('very-secret-password', 12);\n *\n * const nonEmpty: NonEmptyString = password; // OK (>= 1)\n *\n * assert.isTrue(nonEmpty.length >= 12);\n *\n * assert.throws(() => Str.asMinLengthString('short', 12)); // length 5 < 12\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template MinLength - The minimum number of characters (inclusive).\n * @param s - The string to cast.\n * @param minLength - The minimum number of characters (inclusive).\n * @returns `s` typed as `MinLengthString<MinLength> & S`.\n * @throws {TypeError} If `s.length < minLength`.\n */\n export const asMinLengthString = <\n S extends string,\n MinLength extends SupportedLength,\n >(\n s: S,\n minLength: MinLength,\n ): MinLengthString<MinLength> & S => {\n if (!isMinLengthString(s, minLength)) {\n throw new TypeError(\n `Expected a string of length >= ${minLength}, got a string of length ${s.length}`,\n );\n }\n\n return s;\n };\n\n /**\n * Casts a string to `MaxLengthString<MaxLength>` after checking that it has\n * at most `maxLength` characters.\n *\n * Use this instead of writing `s as unknown as MaxLengthString<N>`: the\n * length is verified at runtime, and the original string type (e.g. literal\n * types) is preserved via intersection.\n *\n * @example\n *\n * ```ts\n * const userName = Str.asMaxLengthString('noshiro', 32);\n *\n * const relaxed: MaxLengthString<64> = userName; // OK (32 <= 64)\n *\n * assert.isTrue(relaxed.length <= 32);\n *\n * assert.throws(() => Str.asMaxLengthString('noshiro', 3)); // length 7 > 3\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template MaxLength - The maximum number of characters (inclusive).\n * @param s - The string to cast.\n * @param maxLength - The maximum number of characters (inclusive).\n * @returns `s` typed as `MaxLengthString<MaxLength> & S`.\n * @throws {TypeError} If `s.length > maxLength`.\n */\n export const asMaxLengthString = <\n S extends string,\n MaxLength extends SupportedLength,\n >(\n s: S,\n maxLength: MaxLength,\n ): MaxLengthString<MaxLength> & S => {\n if (!isMaxLengthString(s, maxLength)) {\n throw new TypeError(\n `Expected a string of length <= ${maxLength}, got a string of length ${s.length}`,\n );\n }\n\n return s;\n };\n\n /**\n * Casts a string to `BoundedLengthString<MinLength, MaxLength>` after\n * checking that its length is within the inclusive range\n * `[minLength, maxLength]`.\n *\n * Use this instead of writing `s as unknown as BoundedLengthString<M, N>`:\n * the length is verified at runtime, and the original string type (e.g.\n * literal types) is preserved via intersection.\n *\n * @example\n *\n * ```ts\n * const userId = Str.asBoundedLengthString('user-12345678', 8, 16);\n *\n * const relaxed: BoundedLengthString<1, 255> = userId; // OK ([8, 16] ⊆ [1, 255])\n *\n * assert.isTrue(relaxed.length >= 8 && relaxed.length <= 16);\n *\n * assert.throws(() => Str.asBoundedLengthString('user', 8, 16)); // length 4 < 8\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template MinLength - The minimum number of characters (inclusive).\n * @template MaxLength - The maximum number of characters (inclusive).\n * @param s - The string to cast.\n * @param minLength - The minimum number of characters (inclusive).\n * @param maxLength - The maximum number of characters (inclusive).\n * @returns `s` typed as `BoundedLengthString<MinLength, MaxLength> & S`.\n * @throws {TypeError} If `s.length < minLength` or `s.length > maxLength`.\n */\n export const asBoundedLengthString = <\n S extends string,\n MinLength extends SupportedLength,\n MaxLength extends SupportedLength,\n >(\n s: S,\n minLength: MinLength,\n maxLength: MaxLength,\n ): BoundedLengthString<MinLength, MaxLength> & S => {\n if (!isBoundedLengthString(s, minLength, maxLength)) {\n throw new TypeError(\n `Expected a string of length in [${minLength}, ${maxLength}], got a string of length ${s.length}`,\n );\n }\n\n return s;\n };\n\n /**\n * Casts a string to `FixedLengthString<Length>` after checking that it has\n * exactly `length` characters.\n *\n * Use this instead of writing `s as unknown as FixedLengthString<N>`: the\n * length is verified at runtime, and the original string type (e.g. literal\n * types) is preserved via intersection.\n *\n * @example\n *\n * ```ts\n * const countryCode = Str.asFixedLengthString('JP', 2);\n *\n * const atMost5: MaxLengthString<5> = countryCode; // OK (2 <= 5)\n *\n * assert.isTrue(atMost5.length === 2);\n *\n * assert.throws(() => Str.asFixedLengthString('JP', 3)); // length 2 !== 3\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template Length - The exact number of characters.\n * @param s - The string to cast.\n * @param length - The exact number of characters.\n * @returns `s` typed as `FixedLengthString<Length> & S`.\n * @throws {TypeError} If `s.length !== length`.\n */\n export const asFixedLengthString = <\n S extends string,\n Length extends SupportedLength,\n >(\n s: S,\n length: Length,\n ): FixedLengthString<Length> & S => {\n if (!isFixedLengthString(s, length)) {\n throw new TypeError(\n `Expected a string of length ${length}, got a string of length ${s.length}`,\n );\n }\n\n return s;\n };\n}\n"],"names":["Str"],"mappings":"AAiBO,IAAU;AAAA,CAAV,CAAUA,IAAAA,KAAV;AAmCE,EAAMA,KAAA,iBAAA,GAAoB,CAI/B,CAAA,EACA,SAAA,KACwC,EAAE,MAAA,IAAU,SAAA;AAoC/C,EAAMA,KAAA,iBAAA,GAAoB,CAI/B,CAAA,EACA,SAAA,KACwC,EAAE,MAAA,IAAU,SAAA;AAwC/C,EAAMA,IAAAA,CAAA,qBAAA,GAAwB,CAKnC,CAAA,EACA,SAAA,EACA,cAEA,CAAA,CAAE,MAAA,IAAU,SAAA,IAAa,CAAA,CAAE,MAAA,IAAU,SAAA;AAqChC,EAAMA,KAAA,mBAAA,GAAsB,CAIjC,CAAA,EACA,MAAA,KACuC,EAAE,MAAA,KAAW,MAAA;AA6B/C,EAAMA,IAAAA,CAAA,iBAAA,GAAoB,CAI/B,CAAA,EACA,SAAA,KACmC;AACnC,IAAA,IAAI,CAAA,IAACA,IAAAA,CAAA,iBAAA,EAAkB,CAAA,EAAG,SAAS,CAAA,EAAG;AACpC,MAAA,MAAM,IAAI,SAAA;AAAA,QACR,CAAA,+BAAA,EAAkC,SAAS,CAAA,yBAAA,EAA4B,CAAA,CAAE,MAAM,CAAA;AAAA,OACjF;AAAA,IACF;AAEA,IAAA,OAAO,CAAA;AAAA,EACT,CAAA;AA6BO,EAAMA,IAAAA,CAAA,iBAAA,GAAoB,CAI/B,CAAA,EACA,SAAA,KACmC;AACnC,IAAA,IAAI,CAAA,IAACA,IAAAA,CAAA,iBAAA,EAAkB,CAAA,EAAG,SAAS,CAAA,EAAG;AACpC,MAAA,MAAM,IAAI,SAAA;AAAA,QACR,CAAA,+BAAA,EAAkC,SAAS,CAAA,yBAAA,EAA4B,CAAA,CAAE,MAAM,CAAA;AAAA,OACjF;AAAA,IACF;AAEA,IAAA,OAAO,CAAA;AAAA,EACT,CAAA;AAgCO,EAAMA,IAAAA,CAAA,qBAAA,GAAwB,CAKnC,CAAA,EACA,WACA,SAAA,KACkD;AAClD,IAAA,IAAI,KAACA,IAAAA,CAAA,qBAAA,EAAsB,CAAA,EAAG,SAAA,EAAW,SAAS,CAAA,EAAG;AACnD,MAAA,MAAM,IAAI,SAAA;AAAA,QACR,mCAAmC,SAAS,CAAA,EAAA,EAAK,SAAS,CAAA,0BAAA,EAA6B,EAAE,MAAM,CAAA;AAAA,OACjG;AAAA,IACF;AAEA,IAAA,OAAO,CAAA;AAAA,EACT,CAAA;AA6BO,EAAMA,IAAAA,CAAA,mBAAA,GAAsB,CAIjC,CAAA,EACA,MAAA,KACkC;AAClC,IAAA,IAAI,CAAA,IAACA,IAAAA,CAAA,mBAAA,EAAoB,CAAA,EAAG,MAAM,CAAA,EAAG;AACnC,MAAA,MAAM,IAAI,SAAA;AAAA,QACR,CAAA,4BAAA,EAA+B,MAAM,CAAA,yBAAA,EAA4B,CAAA,CAAE,MAAM,CAAA;AAAA,OAC3E;AAAA,IACF;AAEA,IAAA,OAAO,CAAA;AAAA,EACT,CAAA;AAAA,CAAA,EAhWe,GAAA,KAAA,GAAA,GAAA,EAAA,CAAA,CAAA;;;;"}
|
|
1
|
+
{"version":3,"file":"str.mjs","sources":["../../src/string/str.mts"],"sourcesContent":["import {\n type BoundedLengthString,\n type FixedLengthString,\n type MaxLengthString,\n type MinLengthString,\n type NonEmptyString,\n type SupportedLength,\n} from 'ts-type-forge';\n\n/**\n * Namespace providing type guards and runtime-checked casts for the branded\n * length-constrained string types (`MinLengthString`, `MaxLengthString`,\n * `BoundedLengthString`, `FixedLengthString`).\n *\n * Lengths are measured in UTF-16 code units (the same unit as\n * `String.prototype.length`), so characters outside the Basic Multilingual\n * Plane (e.g. emoji) count as 2.\n */\nexport namespace Str {\n /**\n * Type guard that checks if a string has at least `minLength` characters.\n *\n * **Type Narrowing Behavior:**\n *\n * - Narrows the input to `MinLengthString<MinLength>` while preserving the\n * original string type (e.g. literal types) via intersection.\n * - The result participates in the length-constraint subtyping relation: for\n * example, a value narrowed to `MinLengthString<3>` is assignable to\n * `MinLengthString<1>` (= `NonEmptyString`).\n *\n * @example\n *\n * ```ts\n * const input: string = 'very-secret-password';\n *\n * assert.isTrue(Str.isMinLengthString(input, 12));\n *\n * assert.isFalse(Str.isMinLengthString('short', 12));\n *\n * if (Str.isMinLengthString(input, 12)) {\n * const nonEmpty: NonEmptyString = input; // OK (12 >= 1)\n *\n * assert.isTrue(nonEmpty.length >= 12);\n * }\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template MinLength - The minimum number of characters (inclusive).\n * @param s - The string to check.\n * @param minLength - The minimum number of characters (inclusive).\n * @returns `true` if `s.length >= minLength`, `false` otherwise. When `true`,\n * TypeScript narrows `s` to `MinLengthString<MinLength> & S`.\n */\n export const isMinLengthString = <\n S extends string,\n MinLength extends SupportedLength,\n >(\n s: S,\n minLength: MinLength,\n ): s is MinLengthString<MinLength> & S => s.length >= minLength;\n\n /**\n * Type guard that checks if a string has at most `maxLength` characters.\n *\n * **Type Narrowing Behavior:**\n *\n * - Narrows the input to `MaxLengthString<MaxLength>` while preserving the\n * original string type (e.g. literal types) via intersection.\n * - The result participates in the length-constraint subtyping relation: for\n * example, a value narrowed to `MaxLengthString<16>` is assignable to\n * `MaxLengthString<32>`.\n *\n * @example\n *\n * ```ts\n * const input: string = 'noshiro';\n *\n * assert.isTrue(Str.isMaxLengthString(input, 32));\n *\n * assert.isFalse(Str.isMaxLengthString(input, 3));\n *\n * if (Str.isMaxLengthString(input, 32)) {\n * const relaxed: MaxLengthString<64> = input; // OK (32 <= 64)\n *\n * assert.isTrue(relaxed.length <= 32);\n * }\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template MaxLength - The maximum number of characters (inclusive).\n * @param s - The string to check.\n * @param maxLength - The maximum number of characters (inclusive).\n * @returns `true` if `s.length <= maxLength`, `false` otherwise. When `true`,\n * TypeScript narrows `s` to `MaxLengthString<MaxLength> & S`.\n */\n export const isMaxLengthString = <\n S extends string,\n MaxLength extends SupportedLength,\n >(\n s: S,\n maxLength: MaxLength,\n ): s is MaxLengthString<MaxLength> & S => s.length <= maxLength;\n\n /**\n * Type guard that checks if a string's length is within the inclusive range\n * `[minLength, maxLength]`.\n *\n * **Type Narrowing Behavior:**\n *\n * - Narrows the input to `BoundedLengthString<MinLength, MaxLength>` while\n * preserving the original string type (e.g. literal types) via intersection.\n * - Since `BoundedLengthString` is the intersection of `MinLengthString` and\n * `MaxLengthString`, the narrowed value is assignable to both, and both\n * bounds can be weakened independently.\n *\n * @example\n *\n * ```ts\n * const input: string = 'user-12345678';\n *\n * assert.isTrue(Str.isBoundedLengthString(input, 8, 16));\n *\n * assert.isFalse(Str.isBoundedLengthString('user', 8, 16));\n *\n * if (Str.isBoundedLengthString(input, 8, 16)) {\n * const userId: BoundedLengthString<1, 255> = input; // OK ([8, 16] ⊆ [1, 255])\n *\n * assert.isTrue(userId.length >= 8 && userId.length <= 16);\n * }\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template MinLength - The minimum number of characters (inclusive).\n * @template MaxLength - The maximum number of characters (inclusive).\n * @param s - The string to check.\n * @param minLength - The minimum number of characters (inclusive).\n * @param maxLength - The maximum number of characters (inclusive).\n * @returns `true` if `minLength <= s.length && s.length <= maxLength`, `false`\n * otherwise. When `true`, TypeScript narrows `s` to\n * `BoundedLengthString<MinLength, MaxLength> & S`.\n */\n export const isBoundedLengthString = <\n S extends string,\n MinLength extends SupportedLength,\n MaxLength extends SupportedLength,\n >(\n s: S,\n minLength: MinLength,\n maxLength: MaxLength,\n ): s is BoundedLengthString<MinLength, MaxLength> & S =>\n s.length >= minLength && s.length <= maxLength;\n\n /**\n * Type guard that checks if a string has exactly `length` characters.\n *\n * **Type Narrowing Behavior:**\n *\n * - Narrows the input to `FixedLengthString<Length>` while preserving the\n * original string type (e.g. literal types) via intersection.\n * - Since `FixedLengthString<Length>` is defined as\n * `BoundedLengthString<Length, Length>`, the narrowed value is assignable to\n * any `MinLengthString<N>` with `N <= Length` and any `MaxLengthString<N>`\n * with `N >= Length`.\n *\n * @example\n *\n * ```ts\n * const input: string = 'JP';\n *\n * assert.isTrue(Str.isFixedLengthString(input, 2));\n *\n * assert.isFalse(Str.isFixedLengthString(input, 3));\n *\n * if (Str.isFixedLengthString(input, 2)) {\n * const atMost5: MaxLengthString<5> = input; // OK (2 <= 5)\n *\n * assert.isTrue(atMost5.length === 2);\n * }\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template Length - The exact number of characters.\n * @param s - The string to check.\n * @param length - The exact number of characters.\n * @returns `true` if `s.length === length`, `false` otherwise. When `true`,\n * TypeScript narrows `s` to `FixedLengthString<Length> & S`.\n */\n export const isFixedLengthString = <\n S extends string,\n Length extends SupportedLength,\n >(\n s: S,\n length: Length,\n ): s is FixedLengthString<Length> & S => s.length === length;\n\n /**\n * Casts a string to `MinLengthString<MinLength>` after checking that it has\n * at least `minLength` characters.\n *\n * Use this instead of writing `s as unknown as MinLengthString<N>`: the\n * length is verified at runtime, and the original string type (e.g. literal\n * types) is preserved via intersection.\n *\n * Supports a curried overload: calling it with only `minLength` returns a\n * function that casts a string, which is convenient for `pipe`/`map`.\n *\n * @example\n *\n * ```ts\n * const password = Str.asMinLengthString('very-secret-password', 12);\n *\n * const nonEmpty: NonEmptyString = password; // OK (>= 1)\n *\n * assert.isTrue(nonEmpty.length >= 12);\n *\n * // curried version\n * const asPassword = Str.asMinLengthString(12);\n *\n * assert.strictEqual(asPassword('another-secret'), 'another-secret');\n *\n * assert.throws(() => Str.asMinLengthString('short', 12)); // length 5 < 12\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template MinLength - The minimum number of characters (inclusive).\n * @param s - The string to cast.\n * @param minLength - The minimum number of characters (inclusive).\n * @returns `s` typed as `MinLengthString<MinLength> & S`.\n * @throws {TypeError} If `s.length < minLength`.\n */\n export function asMinLengthString<\n S extends string,\n MinLength extends SupportedLength,\n >(s: S, minLength: MinLength): MinLengthString<MinLength> & S;\n\n // Curried version\n export function asMinLengthString<MinLength extends SupportedLength>(\n minLength: MinLength,\n ): <S extends string>(s: S) => MinLengthString<MinLength> & S;\n\n export function asMinLengthString(\n ...args:\n | readonly [s: string, minLength: SupportedLength]\n | readonly [minLength: SupportedLength]\n ): string | ((s: string) => string) {\n switch (args.length) {\n case 2: {\n const [s, minLength] = args;\n\n if (!isMinLengthString(s, minLength)) {\n throw new TypeError(\n `Expected a string of length >= ${minLength}, got a string of length ${s.length}`,\n );\n }\n\n return s;\n }\n\n case 1: {\n const [minLength] = args;\n\n return (s) => asMinLengthString(s, minLength);\n }\n }\n }\n\n /**\n * Casts a string to `MaxLengthString<MaxLength>` after checking that it has\n * at most `maxLength` characters.\n *\n * Use this instead of writing `s as unknown as MaxLengthString<N>`: the\n * length is verified at runtime, and the original string type (e.g. literal\n * types) is preserved via intersection.\n *\n * Supports a curried overload: calling it with only `maxLength` returns a\n * function that casts a string, which is convenient for `pipe`/`map`.\n *\n * @example\n *\n * ```ts\n * const userName = Str.asMaxLengthString('noshiro', 32);\n *\n * const relaxed: MaxLengthString<64> = userName; // OK (32 <= 64)\n *\n * assert.isTrue(relaxed.length <= 32);\n *\n * // curried version\n * const asUserName = Str.asMaxLengthString(32);\n *\n * assert.strictEqual(asUserName('another-user'), 'another-user');\n *\n * assert.throws(() => Str.asMaxLengthString('noshiro', 3)); // length 7 > 3\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template MaxLength - The maximum number of characters (inclusive).\n * @param s - The string to cast.\n * @param maxLength - The maximum number of characters (inclusive).\n * @returns `s` typed as `MaxLengthString<MaxLength> & S`.\n * @throws {TypeError} If `s.length > maxLength`.\n */\n export function asMaxLengthString<\n S extends string,\n MaxLength extends SupportedLength,\n >(s: S, maxLength: MaxLength): MaxLengthString<MaxLength> & S;\n\n // Curried version\n export function asMaxLengthString<MaxLength extends SupportedLength>(\n maxLength: MaxLength,\n ): <S extends string>(s: S) => MaxLengthString<MaxLength> & S;\n\n export function asMaxLengthString(\n ...args:\n | readonly [s: string, maxLength: SupportedLength]\n | readonly [maxLength: SupportedLength]\n ): string | ((s: string) => string) {\n switch (args.length) {\n case 2: {\n const [s, maxLength] = args;\n\n if (!isMaxLengthString(s, maxLength)) {\n throw new TypeError(\n `Expected a string of length <= ${maxLength}, got a string of length ${s.length}`,\n );\n }\n\n return s;\n }\n\n case 1: {\n const [maxLength] = args;\n\n return (s) => asMaxLengthString(s, maxLength);\n }\n }\n }\n\n /**\n * Casts a string to `BoundedLengthString<MinLength, MaxLength>` after\n * checking that its length is within the inclusive range\n * `[minLength, maxLength]`.\n *\n * Use this instead of writing `s as unknown as BoundedLengthString<M, N>`:\n * the length is verified at runtime, and the original string type (e.g.\n * literal types) is preserved via intersection.\n *\n * Supports a curried overload: calling it with only `minLength` and\n * `maxLength` returns a function that casts a string, which is convenient for\n * `pipe`/`map`.\n *\n * @example\n *\n * ```ts\n * const userId = Str.asBoundedLengthString('user-12345678', 8, 16);\n *\n * const relaxed: BoundedLengthString<1, 255> = userId; // OK ([8, 16] ⊆ [1, 255])\n *\n * assert.isTrue(relaxed.length >= 8 && relaxed.length <= 16);\n *\n * // curried version\n * const asUserId = Str.asBoundedLengthString(8, 16);\n *\n * assert.strictEqual(asUserId('user-87654321'), 'user-87654321');\n *\n * assert.throws(() => Str.asBoundedLengthString('user', 8, 16)); // length 4 < 8\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template MinLength - The minimum number of characters (inclusive).\n * @template MaxLength - The maximum number of characters (inclusive).\n * @param s - The string to cast.\n * @param minLength - The minimum number of characters (inclusive).\n * @param maxLength - The maximum number of characters (inclusive).\n * @returns `s` typed as `BoundedLengthString<MinLength, MaxLength> & S`.\n * @throws {TypeError} If `s.length < minLength` or `s.length > maxLength`.\n */\n export function asBoundedLengthString<\n S extends string,\n MinLength extends SupportedLength,\n MaxLength extends SupportedLength,\n >(\n s: S,\n minLength: MinLength,\n maxLength: MaxLength,\n ): BoundedLengthString<MinLength, MaxLength> & S;\n\n // Curried version\n export function asBoundedLengthString<\n MinLength extends SupportedLength,\n MaxLength extends SupportedLength,\n >(\n minLength: MinLength,\n maxLength: MaxLength,\n ): <S extends string>(s: S) => BoundedLengthString<MinLength, MaxLength> & S;\n\n export function asBoundedLengthString(\n ...args:\n | readonly [\n s: string,\n minLength: SupportedLength,\n maxLength: SupportedLength,\n ]\n | readonly [minLength: SupportedLength, maxLength: SupportedLength]\n ): string | ((s: string) => string) {\n switch (args.length) {\n case 3: {\n const [s, minLength, maxLength] = args;\n\n if (!isBoundedLengthString(s, minLength, maxLength)) {\n throw new TypeError(\n `Expected a string of length in [${minLength}, ${maxLength}], got a string of length ${s.length}`,\n );\n }\n\n return s;\n }\n\n case 2: {\n const [minLength, maxLength] = args;\n\n return (s) => asBoundedLengthString(s, minLength, maxLength);\n }\n }\n }\n\n /**\n * Casts a string to `FixedLengthString<Length>` after checking that it has\n * exactly `length` characters.\n *\n * Use this instead of writing `s as unknown as FixedLengthString<N>`: the\n * length is verified at runtime, and the original string type (e.g. literal\n * types) is preserved via intersection.\n *\n * Supports a curried overload: calling it with only `length` returns a\n * function that casts a string, which is convenient for `pipe`/`map`.\n *\n * @example\n *\n * ```ts\n * const countryCode = Str.asFixedLengthString('JP', 2);\n *\n * const atMost5: MaxLengthString<5> = countryCode; // OK (2 <= 5)\n *\n * assert.isTrue(atMost5.length === 2);\n *\n * // curried version\n * const asCountryCode = Str.asFixedLengthString(2);\n *\n * assert.strictEqual(asCountryCode('US'), 'US');\n *\n * assert.throws(() => Str.asFixedLengthString('JP', 3)); // length 2 !== 3\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @template Length - The exact number of characters.\n * @param s - The string to cast.\n * @param length - The exact number of characters.\n * @returns `s` typed as `FixedLengthString<Length> & S`.\n * @throws {TypeError} If `s.length !== length`.\n */\n export function asFixedLengthString<\n S extends string,\n Length extends SupportedLength,\n >(s: S, length: Length): FixedLengthString<Length> & S;\n\n // Curried version\n export function asFixedLengthString<Length extends SupportedLength>(\n length: Length,\n ): <S extends string>(s: S) => FixedLengthString<Length> & S;\n\n export function asFixedLengthString(\n ...args:\n | readonly [s: string, length: SupportedLength]\n | readonly [length: SupportedLength]\n ): string | ((s: string) => string) {\n switch (args.length) {\n case 2: {\n const [s, length] = args;\n\n if (!isFixedLengthString(s, length)) {\n throw new TypeError(\n `Expected a string of length ${length}, got a string of length ${s.length}`,\n );\n }\n\n return s;\n }\n\n case 1: {\n const [length] = args;\n\n return (s) => asFixedLengthString(s, length);\n }\n }\n }\n\n /**\n * Casts a string to `NonEmptyString` after checking that it has at least one\n * character.\n *\n * `NonEmptyString` is an alias of `MinLengthString<1>`, so this is the\n * length-1 specialization of {@link asMinLengthString}. Use this instead of\n * writing `s as unknown as NonEmptyString`: the length is verified at\n * runtime, and the original string type (e.g. literal types) is preserved\n * via intersection.\n *\n * @example\n *\n * ```ts\n * const name = Str.asNonEmptyString('noshiro');\n *\n * const nonEmpty: NonEmptyString = name; // OK\n *\n * assert.isTrue(nonEmpty.length >= 1);\n *\n * assert.throws(() => Str.asNonEmptyString('')); // length 0 < 1\n * ```\n *\n * @template S - The input string type (literal types are preserved).\n * @param s - The string to cast.\n * @returns `s` typed as `NonEmptyString & S`.\n * @throws {TypeError} If `s` is empty.\n */\n export const asNonEmptyString = <S extends string>(\n s: S,\n ): NonEmptyString & S => {\n if (!isMinLengthString(s, 1)) {\n throw new TypeError('Expected a non-empty string, got an empty string');\n }\n\n return s;\n };\n}\n"],"names":["Str"],"mappings":"AAkBO,IAAU;AAAA,CAAV,CAAUA,IAAAA,KAAV;AAmCE,EAAMA,KAAA,iBAAA,GAAoB,CAI/B,CAAA,EACA,SAAA,KACwC,EAAE,MAAA,IAAU,SAAA;AAoC/C,EAAMA,KAAA,iBAAA,GAAoB,CAI/B,CAAA,EACA,SAAA,KACwC,EAAE,MAAA,IAAU,SAAA;AAwC/C,EAAMA,IAAAA,CAAA,qBAAA,GAAwB,CAKnC,CAAA,EACA,SAAA,EACA,cAEA,CAAA,CAAE,MAAA,IAAU,SAAA,IAAa,CAAA,CAAE,MAAA,IAAU,SAAA;AAqChC,EAAMA,KAAA,mBAAA,GAAsB,CAIjC,CAAA,EACA,MAAA,KACuC,EAAE,MAAA,KAAW,MAAA;AA+C/C,EAAA,SAAS,qBACX,IAAA,EAG+B;AAClC,IAAA,QAAQ,KAAK,MAAA;AAAQ,MACnB,KAAK,CAAA,EAAG;AACN,QAAA,MAAM,CAAC,CAAA,EAAG,SAAS,CAAA,GAAI,IAAA;AAEvB,QAAA,IAAI,CAAA,IAACA,IAAAA,CAAA,iBAAA,EAAkB,CAAA,EAAG,SAAS,CAAA,EAAG;AACpC,UAAA,MAAM,IAAI,SAAA;AAAA,YACR,CAAA,+BAAA,EAAkC,SAAS,CAAA,yBAAA,EAA4B,CAAA,CAAE,MAAM,CAAA;AAAA,WACjF;AAAA,QACF;AAEA,QAAA,OAAO,CAAA;AAAA,MACT;AAAA,MAEA,KAAK,CAAA,EAAG;AACN,QAAA,MAAM,CAAC,SAAS,CAAA,GAAI,IAAA;AAEpB,QAAA,OAAO,CAAC,CAAA,KAAM,iBAAA,CAAkB,CAAA,EAAG,SAAS,CAAA;AAAA,MAC9C;AAAA;AACF,EACF;AAxBO,EAAAA,IAAAA,CAAS,iBAAA,GAAA,iBAAA;AAuET,EAAA,SAAS,qBACX,IAAA,EAG+B;AAClC,IAAA,QAAQ,KAAK,MAAA;AAAQ,MACnB,KAAK,CAAA,EAAG;AACN,QAAA,MAAM,CAAC,CAAA,EAAG,SAAS,CAAA,GAAI,IAAA;AAEvB,QAAA,IAAI,CAAA,IAACA,IAAAA,CAAA,iBAAA,EAAkB,CAAA,EAAG,SAAS,CAAA,EAAG;AACpC,UAAA,MAAM,IAAI,SAAA;AAAA,YACR,CAAA,+BAAA,EAAkC,SAAS,CAAA,yBAAA,EAA4B,CAAA,CAAE,MAAM,CAAA;AAAA,WACjF;AAAA,QACF;AAEA,QAAA,OAAO,CAAA;AAAA,MACT;AAAA,MAEA,KAAK,CAAA,EAAG;AACN,QAAA,MAAM,CAAC,SAAS,CAAA,GAAI,IAAA;AAEpB,QAAA,OAAO,CAAC,CAAA,KAAM,iBAAA,CAAkB,CAAA,EAAG,SAAS,CAAA;AAAA,MAC9C;AAAA;AACF,EACF;AAxBO,EAAAA,IAAAA,CAAS,iBAAA,GAAA,iBAAA;AAoFT,EAAA,SAAS,yBACX,IAAA,EAO+B;AAClC,IAAA,QAAQ,KAAK,MAAA;AAAQ,MACnB,KAAK,CAAA,EAAG;AACN,QAAA,MAAM,CAAC,CAAA,EAAG,SAAA,EAAW,SAAS,CAAA,GAAI,IAAA;AAElC,QAAA,IAAI,KAACA,IAAAA,CAAA,qBAAA,EAAsB,CAAA,EAAG,SAAA,EAAW,SAAS,CAAA,EAAG;AACnD,UAAA,MAAM,IAAI,SAAA;AAAA,YACR,mCAAmC,SAAS,CAAA,EAAA,EAAK,SAAS,CAAA,0BAAA,EAA6B,EAAE,MAAM,CAAA;AAAA,WACjG;AAAA,QACF;AAEA,QAAA,OAAO,CAAA;AAAA,MACT;AAAA,MAEA,KAAK,CAAA,EAAG;AACN,QAAA,MAAM,CAAC,SAAA,EAAW,SAAS,CAAA,GAAI,IAAA;AAE/B,QAAA,OAAO,CAAC,CAAA,KAAM,qBAAA,CAAsB,CAAA,EAAG,WAAW,SAAS,CAAA;AAAA,MAC7D;AAAA;AACF,EACF;AA5BO,EAAAA,IAAAA,CAAS,qBAAA,GAAA,qBAAA;AA2ET,EAAA,SAAS,uBACX,IAAA,EAG+B;AAClC,IAAA,QAAQ,KAAK,MAAA;AAAQ,MACnB,KAAK,CAAA,EAAG;AACN,QAAA,MAAM,CAAC,CAAA,EAAG,MAAM,CAAA,GAAI,IAAA;AAEpB,QAAA,IAAI,CAAA,IAACA,IAAAA,CAAA,mBAAA,EAAoB,CAAA,EAAG,MAAM,CAAA,EAAG;AACnC,UAAA,MAAM,IAAI,SAAA;AAAA,YACR,CAAA,4BAAA,EAA+B,MAAM,CAAA,yBAAA,EAA4B,CAAA,CAAE,MAAM,CAAA;AAAA,WAC3E;AAAA,QACF;AAEA,QAAA,OAAO,CAAA;AAAA,MACT;AAAA,MAEA,KAAK,CAAA,EAAG;AACN,QAAA,MAAM,CAAC,MAAM,CAAA,GAAI,IAAA;AAEjB,QAAA,OAAO,CAAC,CAAA,KAAM,mBAAA,CAAoB,CAAA,EAAG,MAAM,CAAA;AAAA,MAC7C;AAAA;AACF,EACF;AAxBO,EAAAA,IAAAA,CAAS,mBAAA,GAAA,mBAAA;AAqDT,EAAMA,IAAAA,CAAA,gBAAA,GAAmB,CAC9B,CAAA,KACuB;AACvB,IAAA,IAAI,CAAA,IAACA,IAAAA,CAAA,iBAAA,EAAkB,CAAA,EAAG,CAAC,CAAA,EAAG;AAC5B,MAAA,MAAM,IAAI,UAAU,kDAAkD,CAAA;AAAA,IACxE;AAEA,IAAA,OAAO,CAAA;AAAA,EACT,CAAA;AAAA,CAAA,EAjgBe,GAAA,KAAA,GAAA,GAAA,EAAA,CAAA,CAAA;;;;"}
|