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,94 @@
1
+ "use strict";
2
+ // ============================================================================
3
+ // Guarden — Custom Error Classes
4
+ // ============================================================================
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.UnreachableError = exports.EnvConfigError = exports.EnvValidationError = exports.CoercionError = exports.InvariantError = exports.AssertionError = exports.GuardenError = void 0;
7
+ /**
8
+ * Base error class for all Guarden errors.
9
+ * Provides clean stack traces and error identification.
10
+ */
11
+ class GuardenError extends Error {
12
+ code;
13
+ constructor(message, code) {
14
+ super(message);
15
+ this.name = 'GuardenError';
16
+ this.code = code;
17
+ // Fix prototype chain for instanceof checks
18
+ Object.setPrototypeOf(this, new.target.prototype);
19
+ }
20
+ }
21
+ exports.GuardenError = GuardenError;
22
+ /**
23
+ * Thrown when a runtime assertion fails.
24
+ */
25
+ class AssertionError extends GuardenError {
26
+ constructor(message) {
27
+ super(message, 'ERR_ASSERTION');
28
+ this.name = 'AssertionError';
29
+ }
30
+ }
31
+ exports.AssertionError = AssertionError;
32
+ /**
33
+ * Thrown when an invariant is violated.
34
+ * Indicates a bug in the program logic.
35
+ */
36
+ class InvariantError extends GuardenError {
37
+ constructor(message) {
38
+ super(`Invariant violation: ${message}`, 'ERR_INVARIANT');
39
+ this.name = 'InvariantError';
40
+ }
41
+ }
42
+ exports.InvariantError = InvariantError;
43
+ /**
44
+ * Thrown when type coercion fails.
45
+ */
46
+ class CoercionError extends GuardenError {
47
+ originalValue;
48
+ targetType;
49
+ constructor(value, targetType) {
50
+ super(`Cannot coerce ${typeof value} (${String(value)}) to ${targetType}`, 'ERR_COERCION');
51
+ this.name = 'CoercionError';
52
+ this.originalValue = value;
53
+ this.targetType = targetType;
54
+ }
55
+ }
56
+ exports.CoercionError = CoercionError;
57
+ /**
58
+ * Thrown when environment variable validation fails.
59
+ */
60
+ class EnvValidationError extends GuardenError {
61
+ variableName;
62
+ errors;
63
+ constructor(variableName, errors) {
64
+ super(`Environment variable "${variableName}" validation failed:\n - ${errors.join('\n - ')}`, 'ERR_ENV_VALIDATION');
65
+ this.name = 'EnvValidationError';
66
+ this.variableName = variableName;
67
+ this.errors = errors;
68
+ }
69
+ }
70
+ exports.EnvValidationError = EnvValidationError;
71
+ /**
72
+ * Thrown when multiple environment variables fail validation.
73
+ */
74
+ class EnvConfigError extends GuardenError {
75
+ validationErrors;
76
+ constructor(errors) {
77
+ const summary = errors.map((e) => ` ${e.variableName}: ${e.errors.join(', ')}`).join('\n');
78
+ super(`Environment configuration is invalid:\n${summary}`, 'ERR_ENV_CONFIG');
79
+ this.name = 'EnvConfigError';
80
+ this.validationErrors = errors;
81
+ }
82
+ }
83
+ exports.EnvConfigError = EnvConfigError;
84
+ /**
85
+ * Thrown when code reaches a state that should be unreachable.
86
+ */
87
+ class UnreachableError extends GuardenError {
88
+ constructor(value) {
89
+ super(`Unreachable code reached with value: ${JSON.stringify(value)}`, 'ERR_UNREACHABLE');
90
+ this.name = 'UnreachableError';
91
+ }
92
+ }
93
+ exports.UnreachableError = UnreachableError;
94
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/utils/errors.ts"],"names":[],"mappings":";AAAA,+EAA+E;AAC/E,iCAAiC;AACjC,+EAA+E;;;AAE/E;;;GAGG;AACH,MAAa,YAAa,SAAQ,KAAK;IACrB,IAAI,CAAS;IAE7B,YAAY,OAAe,EAAE,IAAY;QACvC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,4CAA4C;QAC5C,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;CACF;AAVD,oCAUC;AAED;;GAEG;AACH,MAAa,cAAe,SAAQ,YAAY;IAC9C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AALD,wCAKC;AAED;;;GAGG;AACH,MAAa,cAAe,SAAQ,YAAY;IAC9C,YAAY,OAAe;QACzB,KAAK,CAAC,wBAAwB,OAAO,EAAE,EAAE,eAAe,CAAC,CAAC;QAC1D,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AALD,wCAKC;AAED;;GAEG;AACH,MAAa,aAAc,SAAQ,YAAY;IAC7B,aAAa,CAAU;IACvB,UAAU,CAAS;IAEnC,YAAY,KAAc,EAAE,UAAkB;QAC5C,KAAK,CACH,iBAAiB,OAAO,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC,QAAQ,UAAU,EAAE,EACnE,cAAc,CACf,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;QAC3B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;CACF;AAbD,sCAaC;AAED;;GAEG;AACH,MAAa,kBAAmB,SAAQ,YAAY;IAClC,YAAY,CAAS;IACrB,MAAM,CAAW;IAEjC,YAAY,YAAoB,EAAE,MAAgB;QAChD,KAAK,CACH,yBAAyB,YAAY,6BAA6B,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,EACzF,oBAAoB,CACrB,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;QACjC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAbD,gDAaC;AAED;;GAEG;AACH,MAAa,cAAe,SAAQ,YAAY;IAC9B,gBAAgB,CAAuB;IAEvD,YAAY,MAA4B;QACtC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC5F,KAAK,CAAC,0CAA0C,OAAO,EAAE,EAAE,gBAAgB,CAAC,CAAC;QAC7E,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,IAAI,CAAC,gBAAgB,GAAG,MAAM,CAAC;IACjC,CAAC;CACF;AATD,wCASC;AAED;;GAEG;AACH,MAAa,gBAAiB,SAAQ,YAAY;IAChD,YAAY,KAAY;QACtB,KAAK,CACH,wCAAwC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,EAC/D,iBAAiB,CAClB,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CACF;AARD,4CAQC"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ // ============================================================================
3
+ // Guarden — Shared TypeScript Utility Types
4
+ // ============================================================================
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/utils/types.ts"],"names":[],"mappings":";AAAA,+EAA+E;AAC/E,4CAA4C;AAC5C,+EAA+E"}
@@ -0,0 +1,75 @@
1
+ // ============================================================================
2
+ // Guarden — Runtime Assertions
3
+ // ============================================================================
4
+ import { AssertionError } from '../utils/errors.js';
5
+ /**
6
+ * Assert that a condition is true. Throws `AssertionError` if false.
7
+ * Narrows the condition to `true` in the subsequent code.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * assert(user !== null, 'User must exist');
12
+ * user.name; // OK — TypeScript knows user is not null
13
+ * ```
14
+ */
15
+ export function assert(condition, message) {
16
+ if (!condition) {
17
+ throw new AssertionError(message ?? 'Assertion failed');
18
+ }
19
+ }
20
+ /**
21
+ * Assert that a value is defined (not undefined).
22
+ * Narrows away `undefined`.
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * const val: string | undefined = getConfig('key');
27
+ * assertDefined(val, 'Config key is required');
28
+ * val.toUpperCase(); // OK
29
+ * ```
30
+ */
31
+ export function assertDefined(value, message) {
32
+ if (value === undefined) {
33
+ throw new AssertionError(message ?? 'Expected value to be defined, but got undefined');
34
+ }
35
+ }
36
+ /**
37
+ * Assert that a value is not null and not undefined.
38
+ * Narrows away `null | undefined`.
39
+ *
40
+ * @example
41
+ * ```ts
42
+ * assertNonNull(result);
43
+ * result.doSomething(); // OK
44
+ * ```
45
+ */
46
+ export function assertNonNull(value, message) {
47
+ if (value === null || value === undefined) {
48
+ throw new AssertionError(message ?? `Expected non-null value, but got ${value === null ? 'null' : 'undefined'}`);
49
+ }
50
+ }
51
+ /**
52
+ * Assert that a value passes a type guard.
53
+ * Narrows to the guarded type.
54
+ *
55
+ * @example
56
+ * ```ts
57
+ * assertType(input, isString, 'Expected string input');
58
+ * input.toUpperCase(); // OK — narrowed to string
59
+ * ```
60
+ */
61
+ export function assertType(value, guard, message) {
62
+ if (!guard(value)) {
63
+ throw new AssertionError(message ?? `Type assertion failed: value ${JSON.stringify(value)} did not pass guard`);
64
+ }
65
+ }
66
+ /**
67
+ * Assert that a value is truthy.
68
+ * Narrows away falsy values (false, 0, '', null, undefined, NaN).
69
+ */
70
+ export function assertTruthy(value, message) {
71
+ if (!value) {
72
+ throw new AssertionError(message ?? `Expected truthy value, but got ${JSON.stringify(value)}`);
73
+ }
74
+ }
75
+ //# sourceMappingURL=assertions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assertions.js","sourceRoot":"","sources":["../../../src/assert/assertions.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,+BAA+B;AAC/B,+EAA+E;AAE/E,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGpD;;;;;;;;;GASG;AACH,MAAM,UAAU,MAAM,CAAC,SAAkB,EAAE,OAAgB;IACzD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,cAAc,CAAC,OAAO,IAAI,kBAAkB,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAC3B,KAAQ,EACR,OAAgB;IAEhB,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,cAAc,CAAC,OAAO,IAAI,iDAAiD,CAAC,CAAC;IACzF,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAC3B,KAAQ,EACR,OAAgB;IAEhB,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,MAAM,IAAI,cAAc,CACtB,OAAO,IAAI,oCAAoC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,EAAE,CACvF,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,UAAU,CACxB,KAAc,EACd,KAAe,EACf,OAAgB;IAEhB,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QAClB,MAAM,IAAI,cAAc,CACtB,OAAO,IAAI,gCAAgC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,qBAAqB,CACtF,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,KAAQ,EACR,OAAgB;IAEhB,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,cAAc,CACtB,OAAO,IAAI,kCAAkC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CACrE,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { assert, assertDefined, assertNonNull, assertType, assertTruthy, } from './assertions.js';
2
+ export { invariant, unreachable } from './invariant.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/assert/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,aAAa,EACb,aAAa,EACb,UAAU,EACV,YAAY,GACb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,39 @@
1
+ // ============================================================================
2
+ // Guarden — Invariants & Unreachable
3
+ // ============================================================================
4
+ import { InvariantError, UnreachableError } from '../utils/errors.js';
5
+ /**
6
+ * Assert an invariant condition. Throws `InvariantError` if violated.
7
+ * Use this for conditions that indicate a bug in your code if broken.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * invariant(items.length > 0, 'items should never be empty at this point');
12
+ * ```
13
+ */
14
+ export function invariant(condition, message) {
15
+ if (!condition) {
16
+ throw new InvariantError(message);
17
+ }
18
+ }
19
+ /**
20
+ * Mark code as unreachable. Useful for exhaustive switch/if checks.
21
+ * Throws `UnreachableError` at runtime if reached.
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * type Direction = 'up' | 'down';
26
+ *
27
+ * function move(dir: Direction) {
28
+ * switch (dir) {
29
+ * case 'up': return goUp();
30
+ * case 'down': return goDown();
31
+ * default: unreachable(dir); // TypeScript error if case missing
32
+ * }
33
+ * }
34
+ * ```
35
+ */
36
+ export function unreachable(value) {
37
+ throw new UnreachableError(value);
38
+ }
39
+ //# sourceMappingURL=invariant.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invariant.js","sourceRoot":"","sources":["../../../src/assert/invariant.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,qCAAqC;AACrC,+EAA+E;AAE/E,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtE;;;;;;;;GAQG;AACH,MAAM,UAAU,SAAS,CAAC,SAAkB,EAAE,OAAe;IAC3D,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,WAAW,CAAC,KAAY;IACtC,MAAM,IAAI,gBAAgB,CAAC,KAAK,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { createEnv, envString, envNumber, envBoolean, envEnum, EnvField, } from './schema.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/env/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,UAAU,EACV,OAAO,EACP,QAAQ,GACT,MAAM,aAAa,CAAC"}
@@ -0,0 +1,304 @@
1
+ // ============================================================================
2
+ // Guarden — Environment Variable Validation
3
+ // ============================================================================
4
+ import { EnvValidationError, EnvConfigError } from '../utils/errors.js';
5
+ // -- Field Builder -----------------------------------------------------------
6
+ /**
7
+ * A builder for defining environment variable validation rules.
8
+ */
9
+ export class EnvField {
10
+ /** @internal */
11
+ _config;
12
+ constructor(config) {
13
+ this._config = config;
14
+ }
15
+ /** Mark the field as required (default). */
16
+ required() {
17
+ return new EnvField({ ...this._config, required: true });
18
+ }
19
+ /** Mark the field as optional with a default value. */
20
+ default(value) {
21
+ return new EnvField({ ...this._config, required: false, defaultValue: value });
22
+ }
23
+ /** Add a custom validation rule. */
24
+ validate(fn) {
25
+ return new EnvField({
26
+ ...this._config,
27
+ validators: [...this._config.validators, fn],
28
+ });
29
+ }
30
+ }
31
+ // -- Field Constructors ------------------------------------------------------
32
+ /**
33
+ * Define a string environment variable.
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * const env = createEnv({
38
+ * DATABASE_URL: envString().url().required(),
39
+ * });
40
+ * ```
41
+ */
42
+ export function envString() {
43
+ return new StringEnvField({
44
+ type: 'string',
45
+ required: true,
46
+ validators: [],
47
+ transformer: (raw) => raw,
48
+ });
49
+ }
50
+ class StringEnvField extends EnvField {
51
+ /** Validate that the string is a valid URL. */
52
+ url() {
53
+ return new StringEnvField({
54
+ ...this._config,
55
+ validators: [
56
+ ...this._config.validators,
57
+ (value) => {
58
+ try {
59
+ new URL(value);
60
+ return null;
61
+ }
62
+ catch {
63
+ return `must be a valid URL`;
64
+ }
65
+ },
66
+ ],
67
+ });
68
+ }
69
+ /** Validate minimum length. */
70
+ minLength(min) {
71
+ return new StringEnvField({
72
+ ...this._config,
73
+ validators: [
74
+ ...this._config.validators,
75
+ (value) => value.length >= min ? null : `must be at least ${min} characters`,
76
+ ],
77
+ });
78
+ }
79
+ /** Validate that the string matches a pattern. */
80
+ matches(pattern) {
81
+ return new StringEnvField({
82
+ ...this._config,
83
+ validators: [
84
+ ...this._config.validators,
85
+ (value) => pattern.test(value) ? null : `must match pattern ${pattern.toString()}`,
86
+ ],
87
+ });
88
+ }
89
+ /** Set a default value. */
90
+ default(value) {
91
+ return new StringEnvField({
92
+ ...this._config,
93
+ required: false,
94
+ defaultValue: value,
95
+ });
96
+ }
97
+ /** Mark as required. */
98
+ required() {
99
+ return new StringEnvField({ ...this._config, required: true });
100
+ }
101
+ }
102
+ /**
103
+ * Define a numeric environment variable.
104
+ * Automatically coerces the string value to a number.
105
+ *
106
+ * @example
107
+ * ```ts
108
+ * const env = createEnv({
109
+ * PORT: envNumber().port().default(3000),
110
+ * });
111
+ * ```
112
+ */
113
+ export function envNumber() {
114
+ return new NumberEnvField({
115
+ type: 'number',
116
+ required: true,
117
+ validators: [],
118
+ transformer: (raw) => {
119
+ const n = Number(raw);
120
+ if (Number.isNaN(n))
121
+ throw new Error(`Cannot parse "${raw}" as number`);
122
+ return n;
123
+ },
124
+ });
125
+ }
126
+ class NumberEnvField extends EnvField {
127
+ /** Validate that the number is a valid port (1-65535). */
128
+ port() {
129
+ return new NumberEnvField({
130
+ ...this._config,
131
+ validators: [
132
+ ...this._config.validators,
133
+ (value) => Number.isInteger(value) && value >= 1 && value <= 65535
134
+ ? null
135
+ : `must be a valid port (1-65535)`,
136
+ ],
137
+ });
138
+ }
139
+ /** Validate minimum value. */
140
+ min(min) {
141
+ return new NumberEnvField({
142
+ ...this._config,
143
+ validators: [
144
+ ...this._config.validators,
145
+ (value) => (value >= min ? null : `must be at least ${min}`),
146
+ ],
147
+ });
148
+ }
149
+ /** Validate maximum value. */
150
+ max(max) {
151
+ return new NumberEnvField({
152
+ ...this._config,
153
+ validators: [
154
+ ...this._config.validators,
155
+ (value) => (value <= max ? null : `must be at most ${max}`),
156
+ ],
157
+ });
158
+ }
159
+ /** Set a default value. */
160
+ default(value) {
161
+ return new NumberEnvField({
162
+ ...this._config,
163
+ required: false,
164
+ defaultValue: value,
165
+ });
166
+ }
167
+ /** Mark as required. */
168
+ required() {
169
+ return new NumberEnvField({ ...this._config, required: true });
170
+ }
171
+ }
172
+ /**
173
+ * Define a boolean environment variable.
174
+ * Recognizes: "true", "1", "yes", "on" as true.
175
+ *
176
+ * @example
177
+ * ```ts
178
+ * const env = createEnv({
179
+ * DEBUG: envBoolean().default(false),
180
+ * });
181
+ * ```
182
+ */
183
+ export function envBoolean() {
184
+ return new BooleanEnvField({
185
+ type: 'boolean',
186
+ required: true,
187
+ validators: [],
188
+ transformer: (raw) => {
189
+ const lower = raw.trim().toLowerCase();
190
+ return ['true', '1', 'yes', 'on'].includes(lower);
191
+ },
192
+ });
193
+ }
194
+ class BooleanEnvField extends EnvField {
195
+ /** Set a default value. */
196
+ default(value) {
197
+ return new BooleanEnvField({
198
+ ...this._config,
199
+ required: false,
200
+ defaultValue: value,
201
+ });
202
+ }
203
+ /** Mark as required. */
204
+ required() {
205
+ return new BooleanEnvField({ ...this._config, required: true });
206
+ }
207
+ }
208
+ /**
209
+ * Define an enum environment variable.
210
+ * Value must be one of the specified options.
211
+ *
212
+ * @example
213
+ * ```ts
214
+ * const env = createEnv({
215
+ * NODE_ENV: envEnum(['development', 'production', 'test'] as const),
216
+ * });
217
+ * // env.NODE_ENV is 'development' | 'production' | 'test'
218
+ * ```
219
+ */
220
+ export function envEnum(values) {
221
+ return new EnvField({
222
+ type: 'enum',
223
+ required: true,
224
+ validators: [
225
+ (value) => values.includes(value)
226
+ ? null
227
+ : `must be one of: ${values.join(', ')}`,
228
+ ],
229
+ transformer: (raw) => raw,
230
+ enumValues: values,
231
+ });
232
+ }
233
+ // -- createEnv ---------------------------------------------------------------
234
+ /**
235
+ * Validate and type-safe environment variables.
236
+ * Throws `EnvConfigError` at startup if validation fails.
237
+ *
238
+ * @example
239
+ * ```ts
240
+ * import { createEnv, envString, envNumber, envBoolean, envEnum } from 'guarden/env';
241
+ *
242
+ * export const env = createEnv({
243
+ * DATABASE_URL: envString().url().required(),
244
+ * PORT: envNumber().port().default(3000),
245
+ * DEBUG: envBoolean().default(false),
246
+ * NODE_ENV: envEnum(['development', 'production', 'test']),
247
+ * });
248
+ *
249
+ * // Fully typed!
250
+ * env.DATABASE_URL // string
251
+ * env.PORT // number
252
+ * env.DEBUG // boolean
253
+ * env.NODE_ENV // 'development' | 'production' | 'test'
254
+ * ```
255
+ */
256
+ export function createEnv(schema, source) {
257
+ const envSource = source ?? (typeof process !== 'undefined' ? process.env : {});
258
+ const result = {};
259
+ const errors = [];
260
+ for (const [key, field] of Object.entries(schema)) {
261
+ const raw = envSource[key];
262
+ const config = field._config;
263
+ // Check if required
264
+ if (raw === undefined || raw === '') {
265
+ if (config.required) {
266
+ errors.push(new EnvValidationError(key, ['is required but not set']));
267
+ continue;
268
+ }
269
+ if (config.defaultValue !== undefined) {
270
+ result[key] = config.defaultValue;
271
+ continue;
272
+ }
273
+ }
274
+ // Transform
275
+ let value;
276
+ try {
277
+ value = config.transformer(raw ?? '');
278
+ }
279
+ catch (e) {
280
+ errors.push(new EnvValidationError(key, [
281
+ `transformation failed: ${e instanceof Error ? e.message : String(e)}`,
282
+ ]));
283
+ continue;
284
+ }
285
+ // Validate
286
+ const fieldErrors = [];
287
+ for (const validator of config.validators) {
288
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
289
+ const error = validator(value);
290
+ if (error)
291
+ fieldErrors.push(error);
292
+ }
293
+ if (fieldErrors.length > 0) {
294
+ errors.push(new EnvValidationError(key, fieldErrors));
295
+ continue;
296
+ }
297
+ result[key] = value;
298
+ }
299
+ if (errors.length > 0) {
300
+ throw new EnvConfigError(errors);
301
+ }
302
+ return result;
303
+ }
304
+ //# 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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"}