@spudlabs/guardis 0.4.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.
Files changed (106) hide show
  1. package/README.md +901 -0
  2. package/esm/mod.d.ts +55 -0
  3. package/esm/mod.d.ts.map +1 -0
  4. package/esm/mod.js +43 -0
  5. package/esm/package.json +3 -0
  6. package/esm/specs/standard-schema-spec.v1.d.ts +56 -0
  7. package/esm/specs/standard-schema-spec.v1.d.ts.map +1 -0
  8. package/esm/specs/standard-schema-spec.v1.js +1 -0
  9. package/esm/src/batch.d.ts +23 -0
  10. package/esm/src/batch.d.ts.map +1 -0
  11. package/esm/src/batch.js +23 -0
  12. package/esm/src/brand.d.ts +62 -0
  13. package/esm/src/brand.d.ts.map +1 -0
  14. package/esm/src/brand.js +9 -0
  15. package/esm/src/context.d.ts +19 -0
  16. package/esm/src/context.d.ts.map +1 -0
  17. package/esm/src/context.js +41 -0
  18. package/esm/src/extend.d.ts +23 -0
  19. package/esm/src/extend.d.ts.map +1 -0
  20. package/esm/src/extend.js +9 -0
  21. package/esm/src/guard.d.ts +288 -0
  22. package/esm/src/guard.d.ts.map +1 -0
  23. package/esm/src/guard.js +631 -0
  24. package/esm/src/helpers/http.helpers.d.ts +3 -0
  25. package/esm/src/helpers/http.helpers.d.ts.map +1 -0
  26. package/esm/src/helpers/http.helpers.js +2 -0
  27. package/esm/src/helpers/strings.helpers.d.ts +18 -0
  28. package/esm/src/helpers/strings.helpers.d.ts.map +1 -0
  29. package/esm/src/helpers/strings.helpers.js +47 -0
  30. package/esm/src/introspect.d.ts +36 -0
  31. package/esm/src/introspect.d.ts.map +1 -0
  32. package/esm/src/introspect.js +25 -0
  33. package/esm/src/modules/async.d.ts +27 -0
  34. package/esm/src/modules/async.d.ts.map +1 -0
  35. package/esm/src/modules/async.js +38 -0
  36. package/esm/src/modules/http.branded.d.ts +42 -0
  37. package/esm/src/modules/http.branded.d.ts.map +1 -0
  38. package/esm/src/modules/http.branded.js +24 -0
  39. package/esm/src/modules/http.d.ts +46 -0
  40. package/esm/src/modules/http.d.ts.map +1 -0
  41. package/esm/src/modules/http.js +59 -0
  42. package/esm/src/modules/strings.branded.d.ts +185 -0
  43. package/esm/src/modules/strings.branded.d.ts.map +1 -0
  44. package/esm/src/modules/strings.branded.js +123 -0
  45. package/esm/src/modules/strings.d.ts +109 -0
  46. package/esm/src/modules/strings.d.ts.map +1 -0
  47. package/esm/src/modules/strings.js +147 -0
  48. package/esm/src/types.d.ts +318 -0
  49. package/esm/src/types.d.ts.map +1 -0
  50. package/esm/src/types.js +1 -0
  51. package/esm/src/utilities.d.ts +95 -0
  52. package/esm/src/utilities.d.ts.map +1 -0
  53. package/esm/src/utilities.js +196 -0
  54. package/package.json +40 -0
  55. package/script/mod.d.ts +55 -0
  56. package/script/mod.d.ts.map +1 -0
  57. package/script/mod.js +83 -0
  58. package/script/package.json +3 -0
  59. package/script/specs/standard-schema-spec.v1.d.ts +56 -0
  60. package/script/specs/standard-schema-spec.v1.d.ts.map +1 -0
  61. package/script/specs/standard-schema-spec.v1.js +2 -0
  62. package/script/src/batch.d.ts +23 -0
  63. package/script/src/batch.d.ts.map +1 -0
  64. package/script/src/batch.js +26 -0
  65. package/script/src/brand.d.ts +62 -0
  66. package/script/src/brand.d.ts.map +1 -0
  67. package/script/src/brand.js +12 -0
  68. package/script/src/context.d.ts +19 -0
  69. package/script/src/context.d.ts.map +1 -0
  70. package/script/src/context.js +45 -0
  71. package/script/src/extend.d.ts +23 -0
  72. package/script/src/extend.d.ts.map +1 -0
  73. package/script/src/extend.js +12 -0
  74. package/script/src/guard.d.ts +288 -0
  75. package/script/src/guard.d.ts.map +1 -0
  76. package/script/src/guard.js +640 -0
  77. package/script/src/helpers/http.helpers.d.ts +3 -0
  78. package/script/src/helpers/http.helpers.d.ts.map +1 -0
  79. package/script/src/helpers/http.helpers.js +5 -0
  80. package/script/src/helpers/strings.helpers.d.ts +18 -0
  81. package/script/src/helpers/strings.helpers.d.ts.map +1 -0
  82. package/script/src/helpers/strings.helpers.js +52 -0
  83. package/script/src/introspect.d.ts +36 -0
  84. package/script/src/introspect.d.ts.map +1 -0
  85. package/script/src/introspect.js +31 -0
  86. package/script/src/modules/async.d.ts +27 -0
  87. package/script/src/modules/async.d.ts.map +1 -0
  88. package/script/src/modules/async.js +41 -0
  89. package/script/src/modules/http.branded.d.ts +42 -0
  90. package/script/src/modules/http.branded.d.ts.map +1 -0
  91. package/script/src/modules/http.branded.js +30 -0
  92. package/script/src/modules/http.d.ts +46 -0
  93. package/script/src/modules/http.d.ts.map +1 -0
  94. package/script/src/modules/http.js +62 -0
  95. package/script/src/modules/strings.branded.d.ts +185 -0
  96. package/script/src/modules/strings.branded.d.ts.map +1 -0
  97. package/script/src/modules/strings.branded.js +126 -0
  98. package/script/src/modules/strings.d.ts +109 -0
  99. package/script/src/modules/strings.d.ts.map +1 -0
  100. package/script/src/modules/strings.js +150 -0
  101. package/script/src/types.d.ts +318 -0
  102. package/script/src/types.d.ts.map +1 -0
  103. package/script/src/types.js +2 -0
  104. package/script/src/utilities.d.ts +95 -0
  105. package/script/src/utilities.d.ts.map +1 -0
  106. package/script/src/utilities.js +207 -0
@@ -0,0 +1,640 @@
1
+ "use strict";
2
+ /**
3
+ * guard.ts
4
+ * @module
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.isTuple = exports.isNull = exports.isNil = exports.isIterable = exports.isEmpty = exports.isDate = exports.isJsonValue = exports.isJsonArray = exports.isArray = exports.isJsonObject = exports.isPropertyKey = exports.isObject = exports.isJsonPrimitive = exports.isUndefined = exports.isFunction = exports.isNumeric = exports.isBinary = exports.isSymbol = exports.isNumber = exports.isString = exports.isBoolean = void 0;
8
+ exports.createTypeGuard = createTypeGuard;
9
+ exports.entryToGuard = entryToGuard;
10
+ const context_js_1 = require("./context.js");
11
+ const introspect_js_1 = require("./introspect.js");
12
+ const utilities_js_1 = require("./utilities.js");
13
+ /**
14
+ * Creates a helpers object for use in type guard parsers.
15
+ * When ctx is provided, has/hasOptional pass context for path tracking.
16
+ * When ctx is undefined, they use raw functions (for boolean type guard calls).
17
+ */
18
+ function createHelpers(ctx) {
19
+ return {
20
+ has: (t, k, guard, errorMessage) => (0, utilities_js_1.hasProperty)(t, k, guard, ctx?.pushPath(k), ctx ? errorMessage : undefined),
21
+ hasNot: (t, k, errorMessage) => (0, utilities_js_1.doesNotHaveProperty)(t, k, ctx?.pushPath(k), ctx ? errorMessage : undefined),
22
+ hasOptional: (t, k, guard, errorMessage) => (0, utilities_js_1.hasOptionalProperty)(t, k, guard, ctx?.pushPath(k), ctx ? errorMessage : undefined),
23
+ tupleHas: utilities_js_1.tupleHas,
24
+ includes: utilities_js_1.includes,
25
+ keyOf: (k, t, errorMessage) => (0, utilities_js_1.keyOf)(k, t, ctx, ctx ? errorMessage : undefined),
26
+ fail: (message) => {
27
+ if (ctx)
28
+ ctx.addIssue(message);
29
+ return null;
30
+ },
31
+ _ctx: ctx,
32
+ };
33
+ }
34
+ /** Default helpers for boolean type guard calls (no validation context) */
35
+ const defaultHelpers = createHelpers();
36
+ /**
37
+ * Checks if a value is a TypeGuardShape object (plain object, not a function).
38
+ * Uses raw checks instead of isObject/isFunction to avoid temporal dead zone
39
+ * issues — this function is called during createTypeGuard's implementation,
40
+ * which runs before isObject and isFunction are initialized.
41
+ */
42
+ function isTypeGuardShape(value) {
43
+ return typeof value === "object" && value !== null && !Array.isArray(value) &&
44
+ typeof value !== "function";
45
+ }
46
+ function isRecord(value) {
47
+ return typeof value === "object" && value !== null && !Array.isArray(value);
48
+ }
49
+ /** Adds issues from a guard result to the context if not already tracked. */
50
+ function propagateIssues(issues, key, ctx) {
51
+ for (const issue of issues) {
52
+ const alreadyTracked = ctx.issues.some((i) => i.message === issue.message &&
53
+ JSON.stringify(i.path) === JSON.stringify(issue.path));
54
+ if (!alreadyTracked) {
55
+ ctx.issues.push({ message: issue.message, path: issue.path ?? [key] });
56
+ }
57
+ }
58
+ }
59
+ /**
60
+ * Validates a single shape field against its guard.
61
+ * When ctx is provided, issues are pushed to the shared context.
62
+ * When ctx is absent, issues are collected into localIssues.
63
+ */
64
+ function validateField(obj, key, guard, ctx, localIssues, result) {
65
+ const childCtx = ctx?.pushPath(key);
66
+ // Nested shape — recurse
67
+ if (isTypeGuardShape(guard)) {
68
+ const r = validateShape(obj[key], guard, childCtx);
69
+ if ("value" in r) {
70
+ result[key] = r.value;
71
+ }
72
+ else if (!childCtx) {
73
+ localIssues.push(...r.issues);
74
+ }
75
+ return;
76
+ }
77
+ if (typeof guard !== "function")
78
+ return;
79
+ // Context-aware guard (TypeGuard with _.context)
80
+ if ((0, introspect_js_1.hasContext)(guard)) {
81
+ const guardCtx = childCtx ?? (0, context_js_1.createContext)([key]);
82
+ const r = guard._.context(obj[key], guardCtx);
83
+ if ("value" in r) {
84
+ result[key] = r.value;
85
+ }
86
+ else if (childCtx) {
87
+ propagateIssues(r.issues, key, ctx);
88
+ }
89
+ else {
90
+ localIssues.push(...r.issues);
91
+ }
92
+ return;
93
+ }
94
+ // Plain boolean guard
95
+ if (guard(obj[key])) {
96
+ result[key] = obj[key];
97
+ return;
98
+ }
99
+ const message = `Validation failed for property "${String(key)}"`;
100
+ if (childCtx) {
101
+ childCtx.addIssue(message);
102
+ }
103
+ else {
104
+ localIssues.push({ message, path: [key] });
105
+ }
106
+ }
107
+ /**
108
+ * Recursively validates a value against a TypeGuardShape.
109
+ * When ctx is provided, issues are pushed to the shared context for path tracking.
110
+ * When ctx is absent, issues are collected locally and returned.
111
+ */
112
+ function validateShape(value, shape, ctx) {
113
+ if (!isRecord(value)) {
114
+ const message = "Expected an object";
115
+ if (!ctx)
116
+ return { issues: [{ message }] };
117
+ ctx.addIssue(message);
118
+ return { issues: ctx.issues };
119
+ }
120
+ const result = {};
121
+ const localIssues = [];
122
+ for (const key of Object.keys(shape)) {
123
+ validateField(value, key, shape[key], ctx, localIssues, result);
124
+ }
125
+ const issues = ctx ? ctx.issues : localIssues;
126
+ return issues.length > 0 ? { issues } : { value: result };
127
+ }
128
+ /**
129
+ * Creates a type guard that strictly checks the type, throwing
130
+ * a TypeError if it fails. Uses strict context for detailed error messages
131
+ * with path information on nested validations.
132
+ * @param parser The parser function to use for validation
133
+ * @param name Optional name of the type guard for error messages
134
+ * @returns A strict type guard that throws on failure
135
+ */
136
+ const createStrictTypeGuard = (parser, name) => {
137
+ return (value, errorMsg) => {
138
+ const ctx = (0, context_js_1.createStrictContext)();
139
+ const helpers = createHelpers(ctx);
140
+ const result = parser(value, helpers);
141
+ if (result === null) {
142
+ throw new TypeError(errorMsg ?? (0, utilities_js_1.formatErrorMessage)(value, name));
143
+ }
144
+ return true;
145
+ };
146
+ };
147
+ /**
148
+ * Creates a callback to construct a union type guard from two existing type guards.
149
+ *
150
+ * @template T1 - The type checked by the first type guard.
151
+ * @template T2 - The type checked by the second type guard.
152
+ *
153
+ * @param guard - A type guard function that checks if a value is of type `T1`.
154
+ * @returns A function that takes a second type guard `guardTwo` and returns a new
155
+ * type guard that checks if a value is of type `T1 | T2`.
156
+ *
157
+ * @example
158
+ * ```typescript
159
+ * const isString = (value: unknown): value is string => typeof value === 'string';
160
+ * const isNumber = (value: unknown): value is number => typeof value === 'number';
161
+ *
162
+ * const isStringOrNumber = createOrTypeGuard(isString)(isNumber);
163
+ *
164
+ * console.log(isStringOrNumber("hello")); // true
165
+ * console.log(isStringOrNumber(42)); // true
166
+ * console.log(isStringOrNumber(false)); // false
167
+ * ```
168
+ */
169
+ const createOrTypeGuard = (guard) => (guardTwo) => {
170
+ // Create a union of the names of the two guards for better error messages, if available.
171
+ const name = (0, introspect_js_1.hasName)(guard) && (0, introspect_js_1.hasName)(guardTwo)
172
+ ? `${guard._.name} | ${guardTwo._.name}`
173
+ : undefined;
174
+ const parser = (v) => {
175
+ if (guard(v) || guardTwo(v))
176
+ return v === null ? true : v;
177
+ return null;
178
+ };
179
+ return name ? createTypeGuard(name, parser) : createTypeGuard(parser);
180
+ };
181
+ /**
182
+ * Creates a notEmpty variant of a type guard that rejects empty values
183
+ * (null, undefined, empty string, empty array, empty object).
184
+ */
185
+ const createNotEmptyTypeGuard = (guard) => {
186
+ const notEmpty = (value) => !isEmpty(value) && guard(value);
187
+ const name = (0, introspect_js_1.hasName)(guard) ? `non-empty ${guard._.name}` : undefined;
188
+ const notEmptyParser = (value) => notEmpty(value) && guard(value) ? value : null;
189
+ const context = (value, ctx) => {
190
+ if (notEmpty(value))
191
+ return { value };
192
+ const message = (0, utilities_js_1.formatErrorMessage)(value, name);
193
+ const path = ctx?.path.length ? [...ctx.path] : undefined;
194
+ return { issues: [path ? { message, path } : { message }] };
195
+ };
196
+ notEmpty._ = {
197
+ name,
198
+ parser: notEmptyParser,
199
+ context,
200
+ };
201
+ notEmpty.strict = createStrictTypeGuard(notEmptyParser, name);
202
+ notEmpty.assert = notEmpty.strict;
203
+ notEmpty.validate = (value) => context(value, (0, context_js_1.createContext)());
204
+ const notEmptyOptional = (value) => guard(value) ? notEmpty(value) : (0, exports.isUndefined)(value);
205
+ const optionalName = name ? `${name} | undefined` : undefined;
206
+ const optionalParser = (v) => notEmptyOptional(v) ? v : null;
207
+ notEmptyOptional.strict = createStrictTypeGuard(optionalParser, optionalName);
208
+ notEmptyOptional.assert = notEmptyOptional.strict;
209
+ notEmptyOptional.validate = (value) => {
210
+ if ((0, exports.isUndefined)(value))
211
+ return { value: value };
212
+ return context(value, (0, context_js_1.createContext)());
213
+ };
214
+ notEmptyOptional.or = createOrTypeGuard(notEmptyOptional);
215
+ notEmpty.optional = notEmptyOptional;
216
+ notEmpty.or = createOrTypeGuard(notEmpty);
217
+ return notEmpty;
218
+ };
219
+ function createTypeGuard(...args) {
220
+ const parserOrShape = args.length === 1 ? args[0] : args[1];
221
+ const name = args.length === 2 ? args[0] : undefined;
222
+ // Convert shape to parser, then continue with normal guard creation
223
+ const parser = isTypeGuardShape(parserOrShape)
224
+ ? (val, helpers) => {
225
+ const ctx = helpers._ctx;
226
+ const result = validateShape(val, parserOrShape, ctx);
227
+ return "value" in result ? result.value : null;
228
+ }
229
+ : parserOrShape;
230
+ /**
231
+ * Internal validation method that accepts a context for path tracking.
232
+ * This is used by nested validations to propagate paths.
233
+ */
234
+ const context = (value, ctx) => {
235
+ const issuesBefore = ctx?.issues.length ?? 0;
236
+ const helpers = createHelpers(ctx);
237
+ const result = parser(value, helpers);
238
+ // If parser returned null and no child issues were added, add this guard's error
239
+ if (result === null && ctx?.issues.length === issuesBefore) {
240
+ ctx.addIssue((0, utilities_js_1.formatErrorMessage)(value, name));
241
+ }
242
+ // Return accumulated issues if any
243
+ if (ctx && ctx.issues.length > 0) {
244
+ return { issues: ctx.issues };
245
+ }
246
+ if (result !== null) {
247
+ // Special case: isNull parser returns `true` when value is null
248
+ return { value: result === true && value === null ? value : result };
249
+ }
250
+ return { issues: [{ message: (0, utilities_js_1.formatErrorMessage)(value, name) }] };
251
+ };
252
+ const callback = (value) => parser(value, defaultHelpers) !== null;
253
+ callback._ = { name, parser, context };
254
+ /**
255
+ * Creates a new type guard that checks if the value is of type T1 or T2.
256
+ * This is useful for creating unions of types.
257
+ * @param {Function} guard A type guard for T2
258
+ * @returns {Function} A new type guard that checks if the value is of type T1 or T2
259
+ */
260
+ callback.or = createOrTypeGuard(callback);
261
+ function extend(...args) {
262
+ const parserOrShape = args.length === 1 ? args[0] : args[1];
263
+ const extendName = args.length === 2 ? args[0] : undefined;
264
+ // Build a combined parser that first checks the base guard, then the extension
265
+ let combinedParser;
266
+ if (isTypeGuardShape(parserOrShape)) {
267
+ const shapeGuard = createTypeGuard(parserOrShape);
268
+ combinedParser = (v) => callback(v) && shapeGuard(v) ? v : null;
269
+ }
270
+ else {
271
+ combinedParser = (v, h) => callback(v) ? parserOrShape(v, h) : null;
272
+ }
273
+ if (extendName) {
274
+ return createTypeGuard(extendName, combinedParser);
275
+ }
276
+ return createTypeGuard(combinedParser);
277
+ }
278
+ callback.extend = extend;
279
+ /**
280
+ * Returns false if the value fails the "empty" type guard
281
+ * or if it fails the parser.
282
+ * @param {unknown} value
283
+ * @returns
284
+ */
285
+ callback.notEmpty = createNotEmptyTypeGuard(callback);
286
+ /**
287
+ * Returns true if the value is undefined or passes the parser.
288
+ * @param {unknown} value
289
+ * @returns
290
+ */
291
+ const optional = (value) => (0, exports.isUndefined)(value) || callback(value);
292
+ optional.strict = createStrictTypeGuard((v, h) => (0, exports.isUndefined)(v) ? v : parser(v, h), name ? `${name} | undefined` : undefined);
293
+ optional.assert = optional.strict;
294
+ optional.validate = (value) => (0, exports.isUndefined)(value) ? { value } : context(value, (0, context_js_1.createContext)());
295
+ optional.or = createOrTypeGuard(optional);
296
+ optional.notEmpty = callback.notEmpty.optional;
297
+ callback.optional = optional;
298
+ /**
299
+ * Throws a TypeError if the type guard fails. Optionally you may define an
300
+ * error message to be included.
301
+ * @param {unknown} value
302
+ * @param {string?} errorMsg Optional
303
+ * @returns
304
+ */
305
+ callback.strict = createStrictTypeGuard(parser, name);
306
+ callback.assert = callback.strict;
307
+ // StandardSchemaV1 compatibility - uses context-aware validation for path tracking
308
+ callback.validate = (value) => context(value, (0, context_js_1.createContext)());
309
+ callback["~standard"] = {
310
+ version: 1,
311
+ vendor: "guardis",
312
+ validate: callback.validate,
313
+ };
314
+ // Attach the type to the function for easy access
315
+ return ((t) => t)(callback);
316
+ }
317
+ function isParser(entry) {
318
+ return typeof entry === "function";
319
+ }
320
+ function isNamedParser(entry) {
321
+ return typeof entry === "object" && "parse" in entry && typeof entry.parse === "function";
322
+ }
323
+ /**
324
+ * Converts a ParserEntry (parser function, named parser object, or shape) into a TypeGuard.
325
+ * Shared by `batch` and `extend` to avoid duplicating entry detection logic.
326
+ */
327
+ function entryToGuard(entry) {
328
+ if (isParser(entry))
329
+ return createTypeGuard(entry);
330
+ if (isNamedParser(entry))
331
+ return createTypeGuard(entry.name, entry.parse);
332
+ return createTypeGuard(entry);
333
+ }
334
+ /**
335
+ * Returns true if input satisfies type boolean.
336
+ * @param {unknown} t
337
+ * @return {boolean}
338
+ */
339
+ exports.isBoolean = createTypeGuard("boolean", (t) => typeof t === "boolean" ? t : null);
340
+ /**
341
+ * Returns true if input satisfies type string.
342
+ * @param {unknown} t
343
+ * @return {boolean}
344
+ */
345
+ exports.isString = createTypeGuard("string", (t) => typeof t === "string" ? t : null);
346
+ /**
347
+ * Returns true if input satisfies type number. Returns false if `NaN` is passed.
348
+ *
349
+ * While `NaN` is technically a number in JavaScript, it is not a valid value for many applications
350
+ * and will fail if used with common numeric operations.
351
+ *
352
+ * @param {unknown} t
353
+ * @return {boolean}
354
+ */
355
+ exports.isNumber = createTypeGuard("number", (t) => typeof t === "number" && !Number.isNaN(t) ? t : null);
356
+ /**
357
+ * Returns true if input satisfies type symbol.
358
+ * @param {unknown} t
359
+ * @return {boolean}
360
+ */
361
+ exports.isSymbol = createTypeGuard("symbol", (t) => typeof t === "symbol" ? t : null);
362
+ /**
363
+ * Returns true if input satisfies type binary.
364
+ * @param {unknown} t
365
+ * @return {boolean}
366
+ */
367
+ exports.isBinary = createTypeGuard("binary", (t) => t === 1 || t === 0 ? t : null);
368
+ /**
369
+ * Returns true if input satisfies type numeric.
370
+ * @param {unknown} t
371
+ * @return {boolean}
372
+ */
373
+ exports.isNumeric = createTypeGuard("numeric", (t) => {
374
+ if ((0, exports.isNumber)(t))
375
+ return t;
376
+ if (!/^-?\d*\.?\d+$/.test(t))
377
+ return null;
378
+ const _t = parseInt(t) || parseFloat(t);
379
+ return (!isNaN(_t) && (0, exports.isNumber)(_t)) ? t : null;
380
+ });
381
+ /**
382
+ * Returns true if input satisfies type Function.
383
+ * @param {unknown} t
384
+ * @return {boolean}
385
+ */
386
+ exports.isFunction = createTypeGuard("function", (t) => typeof t === "function" ? t : null);
387
+ /**
388
+ * Returns true if input satisfies type undefined.
389
+ * @param {unknown} t
390
+ * @return {boolean}
391
+ */
392
+ exports.isUndefined = createTypeGuard("undefined", (t) => t === undefined ? t : null);
393
+ /**
394
+ * Returns true if input satisfies type null.
395
+ * @param {unknown} t
396
+ * @return {boolean}
397
+ */
398
+ const isNull = createTypeGuard("null", (t) => (t === null ? true : null));
399
+ exports.isNull = isNull;
400
+ /**
401
+ * Returns true if input is a JSON-able primitive date type
402
+ * @param {unknown} t
403
+ * @return {boolean}
404
+ */
405
+ exports.isJsonPrimitive = (0, utilities_js_1.unionOf)(exports.isBoolean, exports.isString, exports.isNumber, isNull);
406
+ /**
407
+ * Returns true if input satisfies type object. _BEWARE_ object
408
+ * can apply to many different types, including arrays. This
409
+ * is not as type safe as you might think.
410
+ * @param {unknown} t
411
+ * @return {boolean}
412
+ */
413
+ exports.isObject = createTypeGuard("object", (t) => t && typeof t === "object" && !Array.isArray(t) ? t : null);
414
+ /** Returns true if input satisfies type PropertyKey.
415
+ * @param {unknown} t
416
+ * @return {boolean}
417
+ */
418
+ exports.isPropertyKey = (0, utilities_js_1.unionOf)(exports.isString, exports.isNumber, exports.isSymbol);
419
+ /**
420
+ * Returns true if input satisfies type object. _BEWARE_ object
421
+ * can apply to many different types, including arrays. This
422
+ * is not as type safe as you might think.
423
+ * @param {unknown} t
424
+ * @return {boolean}
425
+ */
426
+ exports.isJsonObject = createTypeGuard("JsonObject", (t) => {
427
+ if (t && typeof t === "object" &&
428
+ Object.getPrototypeOf(t) === Object.prototype) {
429
+ for (const v of Object.values(t)) {
430
+ if (!(0, exports.isJsonValue)(v))
431
+ return null;
432
+ }
433
+ return t;
434
+ }
435
+ return null;
436
+ });
437
+ /** Precursor to full isArray guard */
438
+ const _isArray = createTypeGuard("array", (t) => Array.isArray(t) ? t : null);
439
+ /**
440
+ * Returns true if input satisfies type array.
441
+ * @param {unknown} t
442
+ * @return {boolean}
443
+ */
444
+ exports.isArray = Object.assign(_isArray, {
445
+ of: (guard) => {
446
+ const guardName = (0, introspect_js_1.hasName)(guard) ? guard._.name : undefined;
447
+ let name = "array";
448
+ if (guardName) {
449
+ name = guardName?.includes(" | ") ? `(${guardName})[]` : `${guardName}[]`;
450
+ }
451
+ return createTypeGuard(name, (v, helpers) => {
452
+ if (!(0, exports.isArray)(v))
453
+ return null;
454
+ const ctx = helpers._ctx;
455
+ // If we have a context, use index-aware validation
456
+ if (ctx && (0, introspect_js_1.hasContext)(guard)) {
457
+ for (let i = 0; i < v.length; i++) {
458
+ const childCtx = ctx.pushPath(i);
459
+ const result = guard._.context(v[i], childCtx);
460
+ if (result.issues)
461
+ return null; // issues already added to parent ctx
462
+ }
463
+ return v;
464
+ }
465
+ // Otherwise, use simple boolean check
466
+ return v.every((item) => guard(item)) ? v : null;
467
+ });
468
+ },
469
+ });
470
+ /**
471
+ * Returns true if input satisfies type array.
472
+ * @param {unknown} t
473
+ * @return {boolean}
474
+ */
475
+ exports.isJsonArray = createTypeGuard("JsonArray", (t) => Array.isArray(t) ? t : null);
476
+ /**
477
+ * Checks if a given value is a valid JSON value.
478
+ *
479
+ * This type guard leverages helper functions to determine if the provided value is a valid JSON
480
+ * primitive, JSON array, or JSON object. If the value satisfies any of these conditions, it is
481
+ * considered a valid JSON value.
482
+ *
483
+ * @param t - The value to be checked.
484
+ * @returns The value itself if it is a valid JSON value; otherwise, returns null.
485
+ *
486
+ * @remarks
487
+ * - For primitive types, arrays, and objects, the guard confirms conformance with the JSON value standards.
488
+ *
489
+ * @example
490
+ * const value: unknown = getValue();
491
+ * const jsonValue = isJsonValue(value);
492
+ * if (jsonValue !== null) {
493
+ * // Work with the confirmed JSON value.
494
+ * }
495
+ */
496
+ exports.isJsonValue = (0, utilities_js_1.unionOf)(exports.isJsonPrimitive, exports.isJsonArray, exports.isJsonObject);
497
+ /**
498
+ * A type guard function that checks if a value is a Date object.
499
+ *
500
+ * @param t - The value to check
501
+ * @returns The original Date object if the value is a Date, otherwise null
502
+ *
503
+ * @example
504
+ * ```typescript
505
+ * const maybeDate: unknown = new Date();
506
+ *
507
+ * if (isDate(maybeDate)) {
508
+ * // maybeDate is now typed as Date
509
+ * console.log(maybeDate.toISOString());
510
+ * }
511
+ * ```
512
+ */
513
+ exports.isDate = createTypeGuard("Date", (t) => t instanceof Date ? t : null);
514
+ /**
515
+ * Returns true if input satisfies type null or undefined.
516
+ * @param {unknown} t
517
+ * @return {boolean}
518
+ */
519
+ const isNil = isNull.or(exports.isUndefined);
520
+ exports.isNil = isNil;
521
+ const isEmptyRecord = createTypeGuard("{}", (t) => {
522
+ if (t && typeof t === "object" && Object.getPrototypeOf(t) === Object.prototype &&
523
+ Object.keys(t).length === 0) {
524
+ return t;
525
+ }
526
+ return null;
527
+ });
528
+ const isEmptyArray = createTypeGuard("[]", (t) => Array.isArray(t) && t.length === 0 ? t : null);
529
+ const isEmptyString = createTypeGuard('""', (t) => typeof t === "string" ? t === "" ? t : t?.trim?.() === "" ? t : null : null);
530
+ /**
531
+ * Returns true if input is undefined, null, empty string, object with length
532
+ * of 0 or object without enumerable keys.
533
+ *
534
+ * Strings are trimmed when evaluated.
535
+ * @param {unknown} t
536
+ * @return {boolean}
537
+ */
538
+ const isEmpty = isNull
539
+ .or(exports.isUndefined)
540
+ .or(isEmptyString)
541
+ .or(isEmptyArray)
542
+ .or(isEmptyRecord);
543
+ exports.isEmpty = isEmpty;
544
+ /**
545
+ * Returns true if the value is iterable (has Symbol.iterator). Does not
546
+ * check the type contained within the iterable.
547
+ * @param t
548
+ * @returns
549
+ */
550
+ const isIterable = createTypeGuard("Iterable", (t) => {
551
+ if (typeof t === "object" &&
552
+ !isNil(t) &&
553
+ Symbol.iterator in t &&
554
+ (0, exports.isFunction)(t[Symbol.iterator])) {
555
+ return t;
556
+ }
557
+ return null;
558
+ });
559
+ exports.isIterable = isIterable;
560
+ /**
561
+ * Type guard that checks if a value is a tuple (array) of a specific length.
562
+ *
563
+ * A tuple is an array with a fixed number of elements. This function validates
564
+ * that the input is an array and has exactly the specified length.
565
+ *
566
+ * @typeParam N - The expected length of the tuple
567
+ * @param t - The value to check
568
+ * @param length - The expected length of the tuple
569
+ * @returns Type predicate indicating if the value is a tuple of length N
570
+ *
571
+ * @example
572
+ * ```typescript
573
+ * const value: unknown = [1, 2, 3];
574
+ *
575
+ * if (isTuple(value, 3)) {
576
+ * // value is now typed as [unknown, unknown, unknown]
577
+ * console.log(value.length); // 3
578
+ * }
579
+ *
580
+ * // Check for empty tuple
581
+ * if (isTuple([], 0)) {
582
+ * console.log("Empty tuple");
583
+ * }
584
+ * ```
585
+ */
586
+ const isTuple = (t, length) => {
587
+ return Array.isArray(t) && t.length === length;
588
+ };
589
+ exports.isTuple = isTuple;
590
+ /**
591
+ * Strict version of isTuple that throws a TypeError if the value is not a tuple of the specified length.
592
+ * @typeParam N - The expected length of the tuple
593
+ * @param t - The value to check
594
+ * @param length - The expected length of the tuple
595
+ * @param errorMsg - Optional custom error message
596
+ * @returns true if the value is a tuple of the specified length
597
+ * @throws {TypeError} If the value is not a tuple of the specified length
598
+ */
599
+ isTuple.strict = (t, length, errorMsg) => {
600
+ if (!isTuple(t, length)) {
601
+ throw TypeError(errorMsg ?? `Type guard failed. Value is not a tuple of length ${length}.`);
602
+ }
603
+ return true;
604
+ };
605
+ /**
606
+ * Assertion function that throws an error if the value is not a tuple of the specified length.
607
+ * TypeScript will narrow the type to TupleOfLength<N> after this assertion.
608
+ * @typeParam N - The expected length of the tuple
609
+ * @param t - The value to check
610
+ * @param length - The expected length of the tuple
611
+ * @param errorMsg - Optional custom error message
612
+ * @throws {TypeError} If the value is not a tuple of the specified length
613
+ */
614
+ isTuple.assert = isTuple.strict;
615
+ /**
616
+ * Creates a union type guard that checks if a value is a tuple of specified length OR matches another type.
617
+ * @param length - The expected length of the tuple
618
+ * @param guard - The type guard to combine with isTuple
619
+ * @returns A new type guard for TupleOfLength<N> | T2
620
+ */
621
+ isTuple.or = (length, guard) => {
622
+ return createTypeGuard((v) => isTuple(v, length) ? v : guard._.parser(v, defaultHelpers));
623
+ };
624
+ // Define the optional methods for isTuple
625
+ const isTupleOptional = (t, length) => (0, exports.isUndefined)(t) || isTuple(t, length);
626
+ isTupleOptional.strict = (t, length, errorMsg) => {
627
+ if (!isTupleOptional(t, length)) {
628
+ throw TypeError(errorMsg ?? `Type guard failed. Value is not a tuple of length ${length} or undefined.`);
629
+ }
630
+ return true;
631
+ };
632
+ isTupleOptional.assert = isTupleOptional.strict;
633
+ /**
634
+ * Optional variant of isTuple that accepts undefined or a tuple of the specified length.
635
+ * @typeParam N - The expected length of the tuple
636
+ * @param t - The value to check
637
+ * @param length - The expected length of the tuple
638
+ * @returns true if the value is undefined or a tuple of the specified length, otherwise false
639
+ */
640
+ isTuple.optional = isTupleOptional;
@@ -0,0 +1,3 @@
1
+ export declare const IPV4_REGEX: RegExp;
2
+ export declare const IPV6_REGEX: RegExp;
3
+ //# sourceMappingURL=http.helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.helpers.d.ts","sourceRoot":"","sources":["../../../src/src/helpers/http.helpers.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,QAAiD,CAAC;AACzE,eAAO,MAAM,UAAU,QAC6F,CAAC"}
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IPV6_REGEX = exports.IPV4_REGEX = void 0;
4
+ exports.IPV4_REGEX = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
5
+ exports.IPV6_REGEX = /^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$|^([0-9a-fA-F]{1,4}:)*::([0-9a-fA-F]{1,4}:)*[0-9a-fA-F]{1,4}$|^::1$|^::$/;
@@ -0,0 +1,18 @@
1
+ export declare function splitToWords(input: string): [] | RegExpMatchArray;
2
+ export declare function capitalizeWord(word: string): string;
3
+ /**
4
+ * Converts a string into PascalCase.
5
+ *
6
+ * @example Usage
7
+ * ```ts
8
+ * import { toPascalCase } from "@std/text/to-pascal-case";
9
+ * import { assertEquals } from "@std/assert";
10
+ *
11
+ * assertEquals(toPascalCase("deno is awesome"), "DenoIsAwesome");
12
+ * ```
13
+ *
14
+ * @param input The string that is going to be converted into PascalCase
15
+ * @returns The string as PascalCase
16
+ */
17
+ export declare function toPascalCase(input: string): string;
18
+ //# sourceMappingURL=strings.helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strings.helpers.d.ts","sourceRoot":"","sources":["../../../src/src/helpers/strings.helpers.ts"],"names":[],"mappings":"AAiCA,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,yBAEzC;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGlD"}