guarden 1.0.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 (129) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +370 -0
  3. package/dist/cjs/assert/assertions.js +82 -0
  4. package/dist/cjs/assert/assertions.js.map +1 -0
  5. package/dist/cjs/assert/index.js +13 -0
  6. package/dist/cjs/assert/index.js.map +1 -0
  7. package/dist/cjs/assert/invariant.js +43 -0
  8. package/dist/cjs/assert/invariant.js.map +1 -0
  9. package/dist/cjs/env/index.js +11 -0
  10. package/dist/cjs/env/index.js.map +1 -0
  11. package/dist/cjs/env/schema.js +313 -0
  12. package/dist/cjs/env/schema.js.map +1 -0
  13. package/dist/cjs/guards/advanced.js +190 -0
  14. package/dist/cjs/guards/advanced.js.map +1 -0
  15. package/dist/cjs/guards/combinators.js +195 -0
  16. package/dist/cjs/guards/combinators.js.map +1 -0
  17. package/dist/cjs/guards/index.js +68 -0
  18. package/dist/cjs/guards/index.js.map +1 -0
  19. package/dist/cjs/guards/primitives.js +123 -0
  20. package/dist/cjs/guards/primitives.js.map +1 -0
  21. package/dist/cjs/guards/structures.js +113 -0
  22. package/dist/cjs/guards/structures.js.map +1 -0
  23. package/dist/cjs/index.js +135 -0
  24. package/dist/cjs/index.js.map +1 -0
  25. package/dist/cjs/result/async.js +132 -0
  26. package/dist/cjs/result/async.js.map +1 -0
  27. package/dist/cjs/result/index.js +15 -0
  28. package/dist/cjs/result/index.js.map +1 -0
  29. package/dist/cjs/result/option.js +175 -0
  30. package/dist/cjs/result/option.js.map +1 -0
  31. package/dist/cjs/result/result.js +208 -0
  32. package/dist/cjs/result/result.js.map +1 -0
  33. package/dist/cjs/transform/coerce.js +151 -0
  34. package/dist/cjs/transform/coerce.js.map +1 -0
  35. package/dist/cjs/transform/index.js +36 -0
  36. package/dist/cjs/transform/index.js.map +1 -0
  37. package/dist/cjs/transform/pipe.js +18 -0
  38. package/dist/cjs/transform/pipe.js.map +1 -0
  39. package/dist/cjs/transform/sanitize.js +218 -0
  40. package/dist/cjs/transform/sanitize.js.map +1 -0
  41. package/dist/cjs/utils/errors.js +94 -0
  42. package/dist/cjs/utils/errors.js.map +1 -0
  43. package/dist/cjs/utils/types.js +6 -0
  44. package/dist/cjs/utils/types.js.map +1 -0
  45. package/dist/esm/assert/assertions.js +75 -0
  46. package/dist/esm/assert/assertions.js.map +1 -0
  47. package/dist/esm/assert/index.js +3 -0
  48. package/dist/esm/assert/index.js.map +1 -0
  49. package/dist/esm/assert/invariant.js +39 -0
  50. package/dist/esm/assert/invariant.js.map +1 -0
  51. package/dist/esm/env/index.js +2 -0
  52. package/dist/esm/env/index.js.map +1 -0
  53. package/dist/esm/env/schema.js +304 -0
  54. package/dist/esm/env/schema.js.map +1 -0
  55. package/dist/esm/guards/advanced.js +170 -0
  56. package/dist/esm/guards/advanced.js.map +1 -0
  57. package/dist/esm/guards/combinators.js +182 -0
  58. package/dist/esm/guards/combinators.js.map +1 -0
  59. package/dist/esm/guards/index.js +8 -0
  60. package/dist/esm/guards/index.js.map +1 -0
  61. package/dist/esm/guards/primitives.js +108 -0
  62. package/dist/esm/guards/primitives.js.map +1 -0
  63. package/dist/esm/guards/structures.js +97 -0
  64. package/dist/esm/guards/structures.js.map +1 -0
  65. package/dist/esm/index.js +17 -0
  66. package/dist/esm/index.js.map +1 -0
  67. package/dist/esm/result/async.js +127 -0
  68. package/dist/esm/result/async.js.map +1 -0
  69. package/dist/esm/result/index.js +4 -0
  70. package/dist/esm/result/index.js.map +1 -0
  71. package/dist/esm/result/option.js +170 -0
  72. package/dist/esm/result/option.js.map +1 -0
  73. package/dist/esm/result/result.js +203 -0
  74. package/dist/esm/result/result.js.map +1 -0
  75. package/dist/esm/transform/coerce.js +143 -0
  76. package/dist/esm/transform/coerce.js.map +1 -0
  77. package/dist/esm/transform/index.js +4 -0
  78. package/dist/esm/transform/index.js.map +1 -0
  79. package/dist/esm/transform/pipe.js +14 -0
  80. package/dist/esm/transform/pipe.js.map +1 -0
  81. package/dist/esm/transform/sanitize.js +195 -0
  82. package/dist/esm/transform/sanitize.js.map +1 -0
  83. package/dist/esm/utils/errors.js +84 -0
  84. package/dist/esm/utils/errors.js.map +1 -0
  85. package/dist/esm/utils/types.js +5 -0
  86. package/dist/esm/utils/types.js.map +1 -0
  87. package/dist/types/assert/assertions.d.ts +52 -0
  88. package/dist/types/assert/assertions.d.ts.map +1 -0
  89. package/dist/types/assert/index.d.ts +3 -0
  90. package/dist/types/assert/index.d.ts.map +1 -0
  91. package/dist/types/assert/invariant.d.ts +29 -0
  92. package/dist/types/assert/invariant.d.ts.map +1 -0
  93. package/dist/types/env/index.d.ts +2 -0
  94. package/dist/types/env/index.d.ts.map +1 -0
  95. package/dist/types/env/schema.d.ts +131 -0
  96. package/dist/types/env/schema.d.ts.map +1 -0
  97. package/dist/types/guards/advanced.d.ts +101 -0
  98. package/dist/types/guards/advanced.d.ts.map +1 -0
  99. package/dist/types/guards/combinators.d.ts +120 -0
  100. package/dist/types/guards/combinators.d.ts.map +1 -0
  101. package/dist/types/guards/index.d.ts +5 -0
  102. package/dist/types/guards/index.d.ts.map +1 -0
  103. package/dist/types/guards/primitives.d.ts +75 -0
  104. package/dist/types/guards/primitives.d.ts.map +1 -0
  105. package/dist/types/guards/structures.d.ts +58 -0
  106. package/dist/types/guards/structures.d.ts.map +1 -0
  107. package/dist/types/index.d.ts +8 -0
  108. package/dist/types/index.d.ts.map +1 -0
  109. package/dist/types/result/async.d.ts +72 -0
  110. package/dist/types/result/async.d.ts.map +1 -0
  111. package/dist/types/result/index.d.ts +4 -0
  112. package/dist/types/result/index.d.ts.map +1 -0
  113. package/dist/types/result/option.d.ts +106 -0
  114. package/dist/types/result/option.d.ts.map +1 -0
  115. package/dist/types/result/result.d.ts +126 -0
  116. package/dist/types/result/result.d.ts.map +1 -0
  117. package/dist/types/transform/coerce.d.ts +73 -0
  118. package/dist/types/transform/coerce.d.ts.map +1 -0
  119. package/dist/types/transform/index.d.ts +4 -0
  120. package/dist/types/transform/index.d.ts.map +1 -0
  121. package/dist/types/transform/pipe.d.ts +44 -0
  122. package/dist/types/transform/pipe.d.ts.map +1 -0
  123. package/dist/types/transform/sanitize.d.ts +108 -0
  124. package/dist/types/transform/sanitize.d.ts.map +1 -0
  125. package/dist/types/utils/errors.d.ts +51 -0
  126. package/dist/types/utils/errors.d.ts.map +1 -0
  127. package/dist/types/utils/types.d.ts +29 -0
  128. package/dist/types/utils/types.d.ts.map +1 -0
  129. package/package.json +144 -0
@@ -0,0 +1,313 @@
1
+ "use strict";
2
+ // ============================================================================
3
+ // Guarden — Environment Variable Validation
4
+ // ============================================================================
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.EnvField = void 0;
7
+ exports.envString = envString;
8
+ exports.envNumber = envNumber;
9
+ exports.envBoolean = envBoolean;
10
+ exports.envEnum = envEnum;
11
+ exports.createEnv = createEnv;
12
+ const errors_js_1 = require("../utils/errors.js");
13
+ // -- Field Builder -----------------------------------------------------------
14
+ /**
15
+ * A builder for defining environment variable validation rules.
16
+ */
17
+ class EnvField {
18
+ /** @internal */
19
+ _config;
20
+ constructor(config) {
21
+ this._config = config;
22
+ }
23
+ /** Mark the field as required (default). */
24
+ required() {
25
+ return new EnvField({ ...this._config, required: true });
26
+ }
27
+ /** Mark the field as optional with a default value. */
28
+ default(value) {
29
+ return new EnvField({ ...this._config, required: false, defaultValue: value });
30
+ }
31
+ /** Add a custom validation rule. */
32
+ validate(fn) {
33
+ return new EnvField({
34
+ ...this._config,
35
+ validators: [...this._config.validators, fn],
36
+ });
37
+ }
38
+ }
39
+ exports.EnvField = EnvField;
40
+ // -- Field Constructors ------------------------------------------------------
41
+ /**
42
+ * Define a string environment variable.
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * const env = createEnv({
47
+ * DATABASE_URL: envString().url().required(),
48
+ * });
49
+ * ```
50
+ */
51
+ function envString() {
52
+ return new StringEnvField({
53
+ type: 'string',
54
+ required: true,
55
+ validators: [],
56
+ transformer: (raw) => raw,
57
+ });
58
+ }
59
+ class StringEnvField extends EnvField {
60
+ /** Validate that the string is a valid URL. */
61
+ url() {
62
+ return new StringEnvField({
63
+ ...this._config,
64
+ validators: [
65
+ ...this._config.validators,
66
+ (value) => {
67
+ try {
68
+ new URL(value);
69
+ return null;
70
+ }
71
+ catch {
72
+ return `must be a valid URL`;
73
+ }
74
+ },
75
+ ],
76
+ });
77
+ }
78
+ /** Validate minimum length. */
79
+ minLength(min) {
80
+ return new StringEnvField({
81
+ ...this._config,
82
+ validators: [
83
+ ...this._config.validators,
84
+ (value) => value.length >= min ? null : `must be at least ${min} characters`,
85
+ ],
86
+ });
87
+ }
88
+ /** Validate that the string matches a pattern. */
89
+ matches(pattern) {
90
+ return new StringEnvField({
91
+ ...this._config,
92
+ validators: [
93
+ ...this._config.validators,
94
+ (value) => pattern.test(value) ? null : `must match pattern ${pattern.toString()}`,
95
+ ],
96
+ });
97
+ }
98
+ /** Set a default value. */
99
+ default(value) {
100
+ return new StringEnvField({
101
+ ...this._config,
102
+ required: false,
103
+ defaultValue: value,
104
+ });
105
+ }
106
+ /** Mark as required. */
107
+ required() {
108
+ return new StringEnvField({ ...this._config, required: true });
109
+ }
110
+ }
111
+ /**
112
+ * Define a numeric environment variable.
113
+ * Automatically coerces the string value to a number.
114
+ *
115
+ * @example
116
+ * ```ts
117
+ * const env = createEnv({
118
+ * PORT: envNumber().port().default(3000),
119
+ * });
120
+ * ```
121
+ */
122
+ function envNumber() {
123
+ return new NumberEnvField({
124
+ type: 'number',
125
+ required: true,
126
+ validators: [],
127
+ transformer: (raw) => {
128
+ const n = Number(raw);
129
+ if (Number.isNaN(n))
130
+ throw new Error(`Cannot parse "${raw}" as number`);
131
+ return n;
132
+ },
133
+ });
134
+ }
135
+ class NumberEnvField extends EnvField {
136
+ /** Validate that the number is a valid port (1-65535). */
137
+ port() {
138
+ return new NumberEnvField({
139
+ ...this._config,
140
+ validators: [
141
+ ...this._config.validators,
142
+ (value) => Number.isInteger(value) && value >= 1 && value <= 65535
143
+ ? null
144
+ : `must be a valid port (1-65535)`,
145
+ ],
146
+ });
147
+ }
148
+ /** Validate minimum value. */
149
+ min(min) {
150
+ return new NumberEnvField({
151
+ ...this._config,
152
+ validators: [
153
+ ...this._config.validators,
154
+ (value) => (value >= min ? null : `must be at least ${min}`),
155
+ ],
156
+ });
157
+ }
158
+ /** Validate maximum value. */
159
+ max(max) {
160
+ return new NumberEnvField({
161
+ ...this._config,
162
+ validators: [
163
+ ...this._config.validators,
164
+ (value) => (value <= max ? null : `must be at most ${max}`),
165
+ ],
166
+ });
167
+ }
168
+ /** Set a default value. */
169
+ default(value) {
170
+ return new NumberEnvField({
171
+ ...this._config,
172
+ required: false,
173
+ defaultValue: value,
174
+ });
175
+ }
176
+ /** Mark as required. */
177
+ required() {
178
+ return new NumberEnvField({ ...this._config, required: true });
179
+ }
180
+ }
181
+ /**
182
+ * Define a boolean environment variable.
183
+ * Recognizes: "true", "1", "yes", "on" as true.
184
+ *
185
+ * @example
186
+ * ```ts
187
+ * const env = createEnv({
188
+ * DEBUG: envBoolean().default(false),
189
+ * });
190
+ * ```
191
+ */
192
+ function envBoolean() {
193
+ return new BooleanEnvField({
194
+ type: 'boolean',
195
+ required: true,
196
+ validators: [],
197
+ transformer: (raw) => {
198
+ const lower = raw.trim().toLowerCase();
199
+ return ['true', '1', 'yes', 'on'].includes(lower);
200
+ },
201
+ });
202
+ }
203
+ class BooleanEnvField extends EnvField {
204
+ /** Set a default value. */
205
+ default(value) {
206
+ return new BooleanEnvField({
207
+ ...this._config,
208
+ required: false,
209
+ defaultValue: value,
210
+ });
211
+ }
212
+ /** Mark as required. */
213
+ required() {
214
+ return new BooleanEnvField({ ...this._config, required: true });
215
+ }
216
+ }
217
+ /**
218
+ * Define an enum environment variable.
219
+ * Value must be one of the specified options.
220
+ *
221
+ * @example
222
+ * ```ts
223
+ * const env = createEnv({
224
+ * NODE_ENV: envEnum(['development', 'production', 'test'] as const),
225
+ * });
226
+ * // env.NODE_ENV is 'development' | 'production' | 'test'
227
+ * ```
228
+ */
229
+ function envEnum(values) {
230
+ return new EnvField({
231
+ type: 'enum',
232
+ required: true,
233
+ validators: [
234
+ (value) => values.includes(value)
235
+ ? null
236
+ : `must be one of: ${values.join(', ')}`,
237
+ ],
238
+ transformer: (raw) => raw,
239
+ enumValues: values,
240
+ });
241
+ }
242
+ // -- createEnv ---------------------------------------------------------------
243
+ /**
244
+ * Validate and type-safe environment variables.
245
+ * Throws `EnvConfigError` at startup if validation fails.
246
+ *
247
+ * @example
248
+ * ```ts
249
+ * import { createEnv, envString, envNumber, envBoolean, envEnum } from 'guarden/env';
250
+ *
251
+ * export const env = createEnv({
252
+ * DATABASE_URL: envString().url().required(),
253
+ * PORT: envNumber().port().default(3000),
254
+ * DEBUG: envBoolean().default(false),
255
+ * NODE_ENV: envEnum(['development', 'production', 'test']),
256
+ * });
257
+ *
258
+ * // Fully typed!
259
+ * env.DATABASE_URL // string
260
+ * env.PORT // number
261
+ * env.DEBUG // boolean
262
+ * env.NODE_ENV // 'development' | 'production' | 'test'
263
+ * ```
264
+ */
265
+ function createEnv(schema, source) {
266
+ const envSource = source ?? (typeof process !== 'undefined' ? process.env : {});
267
+ const result = {};
268
+ const errors = [];
269
+ for (const [key, field] of Object.entries(schema)) {
270
+ const raw = envSource[key];
271
+ const config = field._config;
272
+ // Check if required
273
+ if (raw === undefined || raw === '') {
274
+ if (config.required) {
275
+ errors.push(new errors_js_1.EnvValidationError(key, ['is required but not set']));
276
+ continue;
277
+ }
278
+ if (config.defaultValue !== undefined) {
279
+ result[key] = config.defaultValue;
280
+ continue;
281
+ }
282
+ }
283
+ // Transform
284
+ let value;
285
+ try {
286
+ value = config.transformer(raw ?? '');
287
+ }
288
+ catch (e) {
289
+ errors.push(new errors_js_1.EnvValidationError(key, [
290
+ `transformation failed: ${e instanceof Error ? e.message : String(e)}`,
291
+ ]));
292
+ continue;
293
+ }
294
+ // Validate
295
+ const fieldErrors = [];
296
+ for (const validator of config.validators) {
297
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
298
+ const error = validator(value);
299
+ if (error)
300
+ fieldErrors.push(error);
301
+ }
302
+ if (fieldErrors.length > 0) {
303
+ errors.push(new errors_js_1.EnvValidationError(key, fieldErrors));
304
+ continue;
305
+ }
306
+ result[key] = value;
307
+ }
308
+ if (errors.length > 0) {
309
+ throw new errors_js_1.EnvConfigError(errors);
310
+ }
311
+ return result;
312
+ }
313
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/env/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,190 @@
1
+ "use strict";
2
+ // ============================================================================
3
+ // Guarden — Advanced Type Guards
4
+ // ============================================================================
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.isNonEmptyString = isNonEmptyString;
7
+ exports.isEmail = isEmail;
8
+ exports.isURL = isURL;
9
+ exports.isUUID = isUUID;
10
+ exports.isISO8601 = isISO8601;
11
+ exports.isJSONString = isJSONString;
12
+ exports.isHexColor = isHexColor;
13
+ exports.isPositiveNumber = isPositiveNumber;
14
+ exports.isNegativeNumber = isNegativeNumber;
15
+ exports.isInteger = isInteger;
16
+ exports.isSafeInteger = isSafeInteger;
17
+ exports.isNonEmptyArray = isNonEmptyArray;
18
+ exports.isInRange = isInRange;
19
+ exports.isOneOf = isOneOf;
20
+ exports.isMatch = isMatch;
21
+ exports.isMinLength = isMinLength;
22
+ exports.isMaxLength = isMaxLength;
23
+ exports.isInstanceOf = isInstanceOf;
24
+ // -- String guards ----------------------------------------------------------
25
+ /**
26
+ * Check if a value is a non-empty string.
27
+ */
28
+ function isNonEmptyString(value) {
29
+ return typeof value === 'string' && value.length > 0;
30
+ }
31
+ /**
32
+ * Check if a value is a string matching an email pattern.
33
+ */
34
+ function isEmail(value) {
35
+ if (typeof value !== 'string')
36
+ return false;
37
+ // RFC 5322 simplified pattern
38
+ return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
39
+ }
40
+ /**
41
+ * Check if a value is a valid URL string.
42
+ */
43
+ function isURL(value) {
44
+ if (typeof value !== 'string')
45
+ return false;
46
+ try {
47
+ new URL(value);
48
+ return true;
49
+ }
50
+ catch {
51
+ return false;
52
+ }
53
+ }
54
+ /**
55
+ * Check if a value is a valid UUID (v1-v5).
56
+ */
57
+ function isUUID(value) {
58
+ if (typeof value !== 'string')
59
+ return false;
60
+ return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value);
61
+ }
62
+ /**
63
+ * Check if a value is a valid ISO 8601 date string.
64
+ */
65
+ function isISO8601(value) {
66
+ if (typeof value !== 'string')
67
+ return false;
68
+ const date = new Date(value);
69
+ return !Number.isNaN(date.getTime()) && /^\d{4}-\d{2}-\d{2}/.test(value);
70
+ }
71
+ /**
72
+ * Check if a value is a valid JSON string.
73
+ */
74
+ function isJSONString(value) {
75
+ if (typeof value !== 'string')
76
+ return false;
77
+ try {
78
+ JSON.parse(value);
79
+ return true;
80
+ }
81
+ catch {
82
+ return false;
83
+ }
84
+ }
85
+ /**
86
+ * Check if a value is a string matching a hex color (#fff or #ffffff).
87
+ */
88
+ function isHexColor(value) {
89
+ if (typeof value !== 'string')
90
+ return false;
91
+ return /^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(value);
92
+ }
93
+ // -- Number guards ----------------------------------------------------------
94
+ /**
95
+ * Check if a value is a positive number (> 0).
96
+ */
97
+ function isPositiveNumber(value) {
98
+ return typeof value === 'number' && !Number.isNaN(value) && value > 0;
99
+ }
100
+ /**
101
+ * Check if a value is a negative number (< 0).
102
+ */
103
+ function isNegativeNumber(value) {
104
+ return typeof value === 'number' && !Number.isNaN(value) && value < 0;
105
+ }
106
+ /**
107
+ * Check if a value is an integer.
108
+ */
109
+ function isInteger(value) {
110
+ return typeof value === 'number' && Number.isInteger(value);
111
+ }
112
+ /**
113
+ * Check if a value is a safe integer (within Number.MAX_SAFE_INTEGER bounds).
114
+ */
115
+ function isSafeInteger(value) {
116
+ return typeof value === 'number' && Number.isSafeInteger(value);
117
+ }
118
+ // -- Array guards -----------------------------------------------------------
119
+ /**
120
+ * Check if a value is a non-empty array.
121
+ */
122
+ function isNonEmptyArray(value) {
123
+ return Array.isArray(value) && value.length > 0;
124
+ }
125
+ // -- Factory guards ---------------------------------------------------------
126
+ /**
127
+ * Create a guard that checks if a number is within a range [min, max].
128
+ *
129
+ * @example
130
+ * ```ts
131
+ * const isPercent = isInRange(0, 100);
132
+ * isPercent(50) // true
133
+ * isPercent(150) // false
134
+ * ```
135
+ */
136
+ function isInRange(min, max) {
137
+ return (value) => typeof value === 'number' && !Number.isNaN(value) && value >= min && value <= max;
138
+ }
139
+ /**
140
+ * Create a guard that checks if a value is one of the specified values.
141
+ *
142
+ * @example
143
+ * ```ts
144
+ * const isDirection = isOneOf(['up', 'down', 'left', 'right'] as const);
145
+ * if (isDirection(input)) {
146
+ * // input is 'up' | 'down' | 'left' | 'right'
147
+ * }
148
+ * ```
149
+ */
150
+ function isOneOf(values) {
151
+ const valueSet = new Set(values);
152
+ return (value) => valueSet.has(value);
153
+ }
154
+ /**
155
+ * Create a guard that checks if a string matches a pattern.
156
+ *
157
+ * @example
158
+ * ```ts
159
+ * const isSlug = isMatch(/^[a-z0-9-]+$/);
160
+ * isSlug("hello-world") // true
161
+ * isSlug("Hello World") // false
162
+ * ```
163
+ */
164
+ function isMatch(pattern) {
165
+ return (value) => typeof value === 'string' && pattern.test(value);
166
+ }
167
+ /**
168
+ * Create a guard that checks if a string has a minimum length.
169
+ */
170
+ function isMinLength(min) {
171
+ return (value) => typeof value === 'string' && value.length >= min;
172
+ }
173
+ /**
174
+ * Create a guard that checks if a string has a maximum length.
175
+ */
176
+ function isMaxLength(max) {
177
+ return (value) => typeof value === 'string' && value.length <= max;
178
+ }
179
+ /**
180
+ * Check if a value is an instance of a given class.
181
+ *
182
+ * @example
183
+ * ```ts
184
+ * const isMyError = isInstanceOf(TypeError);
185
+ * ```
186
+ */
187
+ function isInstanceOf(constructor) {
188
+ return (value) => value instanceof constructor;
189
+ }
190
+ //# sourceMappingURL=advanced.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advanced.js","sourceRoot":"","sources":["../../../src/guards/advanced.ts"],"names":[],"mappings":"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"}