@zudojs/constants 0.1.0 → 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 (105) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +123 -15
  3. package/dist/cache/cacheControl.type.d.ts +16 -7
  4. package/dist/cache/cacheControl.type.js +38 -6
  5. package/dist/common/common.constant.d.ts +80 -11
  6. package/dist/common/common.constant.js +126 -12
  7. package/dist/common/common.lifecycle.d.ts +43 -25
  8. package/dist/common/common.lifecycle.js +41 -27
  9. package/dist/common/common.schema.d.ts +58 -29
  10. package/dist/common/common.schema.js +74 -41
  11. package/dist/common/common.serialization.d.ts +18 -5
  12. package/dist/common/common.serialization.js +23 -8
  13. package/dist/common/index.d.ts +1 -1
  14. package/dist/common/index.js +1 -1
  15. package/dist/environment/environment.constant.d.ts +26 -2
  16. package/dist/environment/environment.constant.js +27 -3
  17. package/dist/environment/environment.type.d.ts +1 -1
  18. package/dist/environment/environment.type.js +3 -2
  19. package/dist/environment/index.d.ts +1 -1
  20. package/dist/http/httpContentType.type.d.ts +18 -4
  21. package/dist/http/httpContentType.type.js +22 -2
  22. package/dist/http/httpHeader.type.d.ts +7 -2
  23. package/dist/http/httpMethod.type.d.ts +3 -3
  24. package/dist/http/httpMethod.type.js +7 -6
  25. package/dist/http/httpStatus.type.d.ts +42 -2
  26. package/dist/http/httpStatus.type.js +36 -0
  27. package/dist/http/index.d.ts +3 -3
  28. package/dist/http/index.js +1 -1
  29. package/dist/internal/immutableSet.d.ts +26 -0
  30. package/dist/internal/immutableSet.js +40 -0
  31. package/dist/runtime/clock.d.ts +22 -2
  32. package/dist/runtime/clock.js +10 -1
  33. package/dist/runtime/index.d.ts +1 -1
  34. package/dist/runtime/random.d.ts +10 -1
  35. package/dist/runtime/random.js +32 -17
  36. package/dist/time/time.constant.d.ts +7 -1
  37. package/dist/time/time.constant.js +11 -5
  38. package/dist/validation/validation.constant.d.ts +12 -5
  39. package/dist/validation/validation.constant.js +16 -8
  40. package/dist/validation/validation.pattern.type.d.ts +37 -8
  41. package/dist/validation/validation.pattern.type.js +44 -15
  42. package/package.json +21 -13
  43. package/dist/.tsbuildinfo +0 -1
  44. package/dist/cache/cacheControl.type.d.ts.map +0 -1
  45. package/dist/cache/cacheControl.type.js.map +0 -1
  46. package/dist/cache/cacheStrategy.type.d.ts.map +0 -1
  47. package/dist/cache/cacheStrategy.type.js.map +0 -1
  48. package/dist/cache/index.d.ts.map +0 -1
  49. package/dist/cache/index.js.map +0 -1
  50. package/dist/common/common.constant.d.ts.map +0 -1
  51. package/dist/common/common.constant.js.map +0 -1
  52. package/dist/common/common.lifecycle.d.ts.map +0 -1
  53. package/dist/common/common.lifecycle.js.map +0 -1
  54. package/dist/common/common.schema.d.ts.map +0 -1
  55. package/dist/common/common.schema.js.map +0 -1
  56. package/dist/common/common.serialization.d.ts.map +0 -1
  57. package/dist/common/common.serialization.js.map +0 -1
  58. package/dist/common/common.type.d.ts.map +0 -1
  59. package/dist/common/common.type.js.map +0 -1
  60. package/dist/common/index.d.ts.map +0 -1
  61. package/dist/common/index.js.map +0 -1
  62. package/dist/constantsErrors/constantsError.base.d.ts.map +0 -1
  63. package/dist/constantsErrors/constantsError.base.js.map +0 -1
  64. package/dist/constantsErrors/index.d.ts.map +0 -1
  65. package/dist/constantsErrors/index.js.map +0 -1
  66. package/dist/environment/environment.constant.d.ts.map +0 -1
  67. package/dist/environment/environment.constant.js.map +0 -1
  68. package/dist/environment/environment.type.d.ts.map +0 -1
  69. package/dist/environment/environment.type.js.map +0 -1
  70. package/dist/environment/index.d.ts.map +0 -1
  71. package/dist/environment/index.js.map +0 -1
  72. package/dist/http/httpContentType.type.d.ts.map +0 -1
  73. package/dist/http/httpContentType.type.js.map +0 -1
  74. package/dist/http/httpHeader.type.d.ts.map +0 -1
  75. package/dist/http/httpHeader.type.js.map +0 -1
  76. package/dist/http/httpMethod.type.d.ts.map +0 -1
  77. package/dist/http/httpMethod.type.js.map +0 -1
  78. package/dist/http/httpStatus.type.d.ts.map +0 -1
  79. package/dist/http/httpStatus.type.js.map +0 -1
  80. package/dist/http/index.d.ts.map +0 -1
  81. package/dist/http/index.js.map +0 -1
  82. package/dist/index.d.ts.map +0 -1
  83. package/dist/index.js.map +0 -1
  84. package/dist/priority/index.d.ts.map +0 -1
  85. package/dist/priority/index.js.map +0 -1
  86. package/dist/priority/priority.type.d.ts.map +0 -1
  87. package/dist/priority/priority.type.js.map +0 -1
  88. package/dist/runtime/clock.d.ts.map +0 -1
  89. package/dist/runtime/clock.js.map +0 -1
  90. package/dist/runtime/index.d.ts.map +0 -1
  91. package/dist/runtime/index.js.map +0 -1
  92. package/dist/runtime/random.d.ts.map +0 -1
  93. package/dist/runtime/random.js.map +0 -1
  94. package/dist/time/index.d.ts.map +0 -1
  95. package/dist/time/index.js.map +0 -1
  96. package/dist/time/time.constant.d.ts.map +0 -1
  97. package/dist/time/time.constant.js.map +0 -1
  98. package/dist/time/time.unit.type.d.ts.map +0 -1
  99. package/dist/time/time.unit.type.js.map +0 -1
  100. package/dist/validation/index.d.ts.map +0 -1
  101. package/dist/validation/index.js.map +0 -1
  102. package/dist/validation/validation.constant.d.ts.map +0 -1
  103. package/dist/validation/validation.constant.js.map +0 -1
  104. package/dist/validation/validation.pattern.type.d.ts.map +0 -1
  105. package/dist/validation/validation.pattern.type.js.map +0 -1
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Zudojs Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -11,24 +11,132 @@ npm install @zudojs/constants
11
11
  ## Quick Start
12
12
 
13
13
  ```typescript
14
- import { EntityId, Timestamp, HttpStatus, ErrorCode } from "@zudojs/constants";
14
+ import type { UserId, Timestamp } from "@zudojs/constants";
15
+ import {
16
+ HttpStatus,
17
+ HttpMethods,
18
+ createUserId,
19
+ createTimestamp,
20
+ resolveEnvironment,
21
+ formatDuration,
22
+ } from "@zudojs/constants";
15
23
 
16
- const id: EntityId = "user_123";
17
- const now: Timestamp = new Date();
18
- const status = HttpStatus.OK;
24
+ const id: UserId = createUserId("user_123");
25
+ const now: Timestamp = createTimestamp(new Date().toISOString());
26
+ const status = HttpStatus.OK; // 200
27
+ const env = resolveEnvironment(); // "development" | "test" | "staging" | "production"
28
+ formatDuration(150_000); // "2m 30s"
19
29
  ```
20
30
 
21
- ## Features
31
+ All constant objects are `Object.freeze`d `as const` maps, and every map has a
32
+ matching literal-union type (`HttpStatusCode`, `HttpMethod`, `Environment`,
33
+ `LifecycleState`, `SchemaIssueCode`, ...). Sets such as `HTTP_METHODS` and
34
+ `SCHEMA_FORBIDDEN_KEYS` are immutable at runtime: `add`/`delete`/`clear` throw.
22
35
 
23
- - Branded ID types (EntityId, UserId, EventId, etc.)
24
- - HTTP status codes and constants
25
- - Error codes and categories
26
- - Serialization tags and limits
27
- - Type-safe literal types
36
+ ## Modules
28
37
 
29
- ## Use Cases
38
+ ### `http`
30
39
 
31
- - Type-safe identifiers
32
- - HTTP constants
33
- - Error code management
34
- - Shared enumerations
40
+ - `HttpMethods`, `HTTP_METHODS`, `SAFE_HTTP_METHODS`, `IDEMPOTENT_HTTP_METHODS`
41
+ - `HttpStatus` plus range helpers (`isSuccessStatus`, `isClientError`, ...)
42
+ - `HttpHeader` common header names
43
+ - `ContentTypes`, `Charset` (MIME charset labels), `buildContentType()`
44
+
45
+ ### `environment`
46
+
47
+ - `Environments`, `ENVIRONMENTS`, `isValidEnvironment()`
48
+ - `resolveEnvironment(env?, options?)`, `isProduction()`, `isDevelopment()`, `isTest()`
49
+
50
+ `resolveEnvironment` reads `NODE_ENV` (case-insensitively, accepting the
51
+ aliases `dev`/`prod`). An unrecognized value falls back to `"development"` but
52
+ logs a `console.warn` once per distinct value, so a typo such as
53
+ `NODE_ENV=prodution` is never silent. Use `{ strict: true }` to throw an
54
+ `InvalidConstantError` instead, or `{ silent: true }` to suppress the warning.
55
+
56
+ ```typescript
57
+ import { resolveEnvironment, isProduction } from "@zudojs/constants";
58
+
59
+ resolveEnvironment({ NODE_ENV: "PROD" }); // "production"
60
+ resolveEnvironment({ NODE_ENV: "prodution" }); // "development" + one-time warning
61
+ resolveEnvironment({ NODE_ENV: "prodution" }, { strict: true }); // throws InvalidConstantError
62
+ isProduction(); // reads process.env
63
+ ```
64
+
65
+ ### `time`
66
+
67
+ - `TimeMs` durations (SECOND ... YEAR), `DefaultTimeout`, `DefaultRetry`
68
+ - `TimeUnits` / `TimeUnit`, `toMilliseconds(value, unit)`, `formatDuration(ms)`
69
+
70
+ ```typescript
71
+ import { TimeMs, toMilliseconds, formatDuration } from "@zudojs/constants";
72
+
73
+ const ttl = 5 * TimeMs.MINUTE; // 300_000
74
+ toMilliseconds(2, "hours"); // 7_200_000
75
+ formatDuration(90_000); // "1m 30s"
76
+ formatDuration(4_500_000); // "1h 15m"
77
+ ```
78
+
79
+ ### `common`
80
+
81
+ - Branded types (`UserId`, `EventId`, `Timestamp`, `Url`, `EmailAddress`, ...)
82
+ with `createX` factories — the validating ones (`createTimestamp`,
83
+ `createUrl`, `createEmailAddress`, `createHexString`, `createBase64String`,
84
+ `createJsonString`) throw `InvalidConstantError` on bad input
85
+ - `Limits`, `Defaults`, `Sentinel` and sentinels `NONE`, `UNINITIALIZED`, `EMPTY`
86
+ - Lifecycle state machine: `LifecycleState`, `LifecyclePhase`, `LIFECYCLE_VALID_TRANSITIONS`, timeouts/retries
87
+ - Schema constants: `SchemaIssueCode`, `SCHEMA_FORBIDDEN_KEYS` (immutable at runtime), `SCHEMA_STRING_FORMATS`
88
+ - Serialization constants: `SerializationFormat`, `SerializationContentType`, `SerializationLimits`, `SerializationTags`
89
+
90
+ ### `validation`
91
+
92
+ - `ValidationPattern` — the single source of truth for regexes (EMAIL, UUID,
93
+ UUID_V4, IPV4, IPV6, ISO_DATE_TIME, URL, SEMVER, PHONE, FILE_NAME, ...).
94
+ `SCHEMA_STRING_FORMATS` re-exports these rather than redefining them.
95
+ - `ValidationLength`, `ValidationRange`
96
+
97
+ ```typescript
98
+ import { ValidationPattern, ValidationLength } from "@zudojs/constants";
99
+
100
+ ValidationPattern.SEMVER.test("1.0.0-alpha-1"); // true (semver.org grammar)
101
+ ValidationPattern.IPV6.test("::ffff:192.0.2.1"); // true
102
+ ValidationPattern.FILE_NAME.test(".."); // false (path traversal)
103
+ ValidationLength.EMAIL; // 254
104
+ ```
105
+
106
+ ### `cache`
107
+
108
+ - `CacheStrategies`, `CacheDuration`, `buildCacheControl()`
109
+
110
+ ### `priority`
111
+
112
+ - `Priorities`, `PriorityWeight`, `comparePriority()`
113
+
114
+ ### `runtime`
115
+
116
+ - Injectable `Clock` / `Random` interfaces with `systemClock` / `systemRandom`
117
+ (fully `node:crypto`-backed, safe for tokens and salts) and deterministic
118
+ `createMockClock()` / `createMockRandom(seed)` for tests
119
+ - `MockClock` adds `advance(ms)` and `set(timestampOrDate)`
120
+
121
+ ```typescript
122
+ import {
123
+ createMockClock,
124
+ createMockRandom,
125
+ systemRandom,
126
+ } from "@zudojs/constants";
127
+
128
+ const clock = createMockClock(0);
129
+ clock.advance(1_000);
130
+ clock.set(new Date("2024-01-01T00:00:00Z"));
131
+ clock.now(); // 1704067200000
132
+
133
+ const rng = createMockRandom(42); // same seed => same sequence
134
+ rng.randomInt(1, 6);
135
+
136
+ systemRandom.randomString(32); // CSPRNG-backed
137
+ ```
138
+
139
+ ### Errors
140
+
141
+ - `InvalidConstantError`, `ConstantContextError` (built on `@zudojs/errors`;
142
+ error codes themselves live in `@zudojs/errors`)
@@ -5,21 +5,24 @@
5
5
  */
6
6
  import { type CacheStrategy } from "./cacheStrategy.type.js";
7
7
  /**
8
- * Default cache durations in seconds for different resource types.
8
+ * Default cache durations in **seconds** (the unit `Cache-Control` uses) for
9
+ * different resource types.
10
+ *
11
+ * Derived from {@link TimeMs} (milliseconds) so the two never drift apart.
9
12
  */
10
13
  export declare const CacheDuration: Readonly<{
11
14
  /** No caching */
12
15
  readonly NONE: 0;
13
16
  /** Very short cache (10 seconds) — API data */
14
- readonly SHORT: 10;
17
+ readonly SHORT: number;
15
18
  /** Medium cache (5 minutes) — semi-dynamic content */
16
- readonly MEDIUM: 300;
19
+ readonly MEDIUM: number;
17
20
  /** Long cache (1 hour) — static content */
18
- readonly LONG: 3600;
21
+ readonly LONG: number;
19
22
  /** Very long cache (1 day) — immutable assets */
20
- readonly VERY_LONG: 86400;
23
+ readonly VERY_LONG: number;
21
24
  /** One week — versioned assets */
22
- readonly WEEK: 604800;
25
+ readonly WEEK: number;
23
26
  }>;
24
27
  /**
25
28
  * Options for building a Cache-Control header value.
@@ -31,14 +34,20 @@ export interface CacheControlOptions {
31
34
  readonly maxAge?: number;
32
35
  /** Stale-while-revalidate duration in seconds */
33
36
  readonly staleWhileRevalidate?: number;
34
- /** Whether to include the s-maxage directive */
37
+ /** Shared (proxy) cache max age in seconds — emits the s-maxage directive */
35
38
  readonly sharedMaxAge?: number;
36
39
  }
37
40
  /**
38
41
  * Build a Cache-Control header value from options.
39
42
  *
43
+ * When the strategy is `no-store`, all duration directives (`max-age`,
44
+ * `stale-while-revalidate`, `s-maxage`) are ignored — combining them with
45
+ * `no-store` is invalid per RFC 9111.
46
+ *
40
47
  * @param options - Cache control options
41
48
  * @returns Cache-Control header string
49
+ * @throws {InvalidConstantError} if any provided duration is not a
50
+ * non-negative finite integer
42
51
  */
43
52
  export declare function buildCacheControl(options: CacheControlOptions): string;
44
53
  //# sourceMappingURL=cacheControl.type.d.ts.map
@@ -4,32 +4,64 @@
4
4
  * @module cache/cacheControl
5
5
  */
6
6
  import {} from "./cacheStrategy.type.js";
7
+ import { InvalidConstantError } from "../constantsErrors/constantsError.base.js";
7
8
  import { TimeMs } from "../time/time.constant.js";
9
+ /** Milliseconds per second, for deriving second-based durations from {@link TimeMs}. */
10
+ const MS_PER_SECOND = TimeMs.SECOND;
8
11
  /**
9
- * Default cache durations in seconds for different resource types.
12
+ * Default cache durations in **seconds** (the unit `Cache-Control` uses) for
13
+ * different resource types.
14
+ *
15
+ * Derived from {@link TimeMs} (milliseconds) so the two never drift apart.
10
16
  */
11
17
  export const CacheDuration = Object.freeze({
12
18
  /** No caching */
13
19
  NONE: 0,
14
20
  /** Very short cache (10 seconds) — API data */
15
- SHORT: 10,
21
+ SHORT: (10 * TimeMs.SECOND) / MS_PER_SECOND,
16
22
  /** Medium cache (5 minutes) — semi-dynamic content */
17
- MEDIUM: 300,
23
+ MEDIUM: (5 * TimeMs.MINUTE) / MS_PER_SECOND,
18
24
  /** Long cache (1 hour) — static content */
19
- LONG: 3_600,
25
+ LONG: TimeMs.HOUR / MS_PER_SECOND,
20
26
  /** Very long cache (1 day) — immutable assets */
21
- VERY_LONG: 86_400,
27
+ VERY_LONG: TimeMs.DAY / MS_PER_SECOND,
22
28
  /** One week — versioned assets */
23
- WEEK: 604_800,
29
+ WEEK: TimeMs.WEEK / MS_PER_SECOND,
24
30
  });
31
+ /**
32
+ * Assert that a cache duration is a non-negative finite integer.
33
+ */
34
+ function assertCacheSeconds(name, value) {
35
+ if (!Number.isInteger(value) || value < 0) {
36
+ throw new InvalidConstantError(`buildCacheControl: ${name} must be a non-negative finite integer, got ${String(value)}`);
37
+ }
38
+ }
25
39
  /**
26
40
  * Build a Cache-Control header value from options.
27
41
  *
42
+ * When the strategy is `no-store`, all duration directives (`max-age`,
43
+ * `stale-while-revalidate`, `s-maxage`) are ignored — combining them with
44
+ * `no-store` is invalid per RFC 9111.
45
+ *
28
46
  * @param options - Cache control options
29
47
  * @returns Cache-Control header string
48
+ * @throws {InvalidConstantError} if any provided duration is not a
49
+ * non-negative finite integer
30
50
  */
31
51
  export function buildCacheControl(options) {
52
+ if (options.maxAge !== undefined) {
53
+ assertCacheSeconds("maxAge", options.maxAge);
54
+ }
55
+ if (options.staleWhileRevalidate !== undefined) {
56
+ assertCacheSeconds("staleWhileRevalidate", options.staleWhileRevalidate);
57
+ }
58
+ if (options.sharedMaxAge !== undefined) {
59
+ assertCacheSeconds("sharedMaxAge", options.sharedMaxAge);
60
+ }
32
61
  const parts = [options.strategy];
62
+ if (options.strategy === "no-store") {
63
+ return parts.join(", ");
64
+ }
33
65
  if (options.maxAge !== undefined) {
34
66
  parts.push(`max-age=${options.maxAge}`);
35
67
  }
@@ -1,9 +1,10 @@
1
1
  /**
2
- * Common default values, limits, and sentinel constants.
2
+ * Common default values, limits, sentinel constants, and branded-type
3
+ * factories.
3
4
  *
4
5
  * @module common/common
5
6
  */
6
- import { type UserId, type EventId, type RequestId, type CorrelationId, type Timestamp } from "./common.type.js";
7
+ import { type UserId, type EventId, type RequestId, type CorrelationId, type SessionId, type TenantId, type MessageId, type MessageCausationId, type TokenId, type Timestamp, type Url, type EmailAddress, type HexString, type Base64String, type JsonString } from "./common.type.js";
7
8
  /** Sentinel value indicating absence of a value. */
8
9
  export declare const NONE: "NONE";
9
10
  /** Sentinel value indicating an uninitialized state. */
@@ -24,10 +25,24 @@ export declare const Limits: Readonly<{
24
25
  readonly MAX_PAGE_SIZE: 100;
25
26
  /** Default page size for paginated queries */
26
27
  readonly DEFAULT_PAGE_SIZE: 20;
27
- /** Maximum depth for nested structures */
28
+ /**
29
+ * Maximum depth for general nested data structures (e.g. user-supplied
30
+ * config objects).
31
+ *
32
+ * Intentionally distinct from `SCHEMA_DEFAULT_MAX_DEPTH` (100 — recursion
33
+ * guard for schema validation) and `SerializationLimits.MAX_DEPTH` (128 —
34
+ * recursion guard for the serializer): those bound internal traversal,
35
+ * this bounds acceptable user data shape.
36
+ */
28
37
  readonly MAX_NESTING_DEPTH: 10;
29
- /** Maximum number of retry attempts */
30
- readonly MAX_RETRY_ATTEMPTS: 5;
38
+ /**
39
+ * Maximum number of retry attempts a caller may configure (upper bound).
40
+ *
41
+ * This is the single source of truth for the retry cap —
42
+ * `ValidationRange.MAX_RETRIES` derives from it. The out-of-the-box default
43
+ * is the (smaller) `DefaultRetry.MAX_ATTEMPTS`.
44
+ */
45
+ readonly MAX_RETRY_ATTEMPTS: 10;
31
46
  /** Maximum number of concurrent operations */
32
47
  readonly MAX_CONCURRENCY: 10;
33
48
  /** Maximum buffer size (64 KB) */
@@ -39,12 +54,15 @@ export declare const Limits: Readonly<{
39
54
  * Default configuration values for common options.
40
55
  */
41
56
  export declare const Defaults: Readonly<{
42
- /** Default character encoding */
57
+ /** Default character encoding (canonical: {@link Charset.UTF_8}) */
43
58
  readonly ENCODING: "utf-8";
44
- /** Default MIME type */
59
+ /** Default MIME type (canonical: {@link ContentTypes.JSON}) */
45
60
  readonly CONTENT_TYPE: "application/json";
46
- /** Default date format (ISO 8601) */
47
- readonly DATE_FORMAT: "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
61
+ /**
62
+ * Default date format (ISO 8601 with timezone offset; `XXX` renders `Z`
63
+ * for UTC or `±hh:mm` otherwise).
64
+ */
65
+ readonly DATE_FORMAT: "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
48
66
  /** Default time zone */
49
67
  readonly TIMEZONE: "UTC";
50
68
  /** Default locale */
@@ -64,8 +82,6 @@ export declare const Defaults: Readonly<{
64
82
  export declare const Sentinel: Readonly<{
65
83
  /** Value indicating null/absence in serialized form */
66
84
  readonly NULL: null;
67
- /** Value indicating undefined in serialized form */
68
- readonly UNDEFINED: undefined;
69
85
  /** Marker for deleted soft-delete records */
70
86
  readonly DELETED: "__DELETED__";
71
87
  /** Marker for placeholder data */
@@ -89,8 +105,61 @@ export declare function createRequestId(id: string): RequestId;
89
105
  * Create a branded CorrelationId from a raw string.
90
106
  */
91
107
  export declare function createCorrelationId(id: string): CorrelationId;
108
+ /**
109
+ * Create a branded SessionId from a raw string.
110
+ */
111
+ export declare function createSessionId(id: string): SessionId;
112
+ /**
113
+ * Create a branded TenantId from a raw string.
114
+ */
115
+ export declare function createTenantId(id: string): TenantId;
116
+ /**
117
+ * Create a branded MessageId from a raw string.
118
+ */
119
+ export declare function createMessageId(id: string): MessageId;
120
+ /**
121
+ * Create a branded MessageCausationId from a raw string.
122
+ */
123
+ export declare function createMessageCausationId(id: string): MessageCausationId;
124
+ /**
125
+ * Create a branded TokenId from a raw string.
126
+ */
127
+ export declare function createTokenId(id: string): TokenId;
92
128
  /**
93
129
  * Create a branded Timestamp from an ISO 8601 string.
130
+ *
131
+ * @throws {InvalidConstantError} if the input is not a valid ISO 8601
132
+ * date-time string (e.g. `2024-01-01T00:00:00.000Z`).
94
133
  */
95
134
  export declare function createTimestamp(iso: string): Timestamp;
135
+ /**
136
+ * Create a branded Url from a raw string.
137
+ *
138
+ * @throws {InvalidConstantError} if the input is not a parseable URL.
139
+ */
140
+ export declare function createUrl(url: string): Url;
141
+ /**
142
+ * Create a branded EmailAddress from a raw string.
143
+ *
144
+ * @throws {InvalidConstantError} if the input is not a valid email address.
145
+ */
146
+ export declare function createEmailAddress(email: string): EmailAddress;
147
+ /**
148
+ * Create a branded HexString from a raw string.
149
+ *
150
+ * @throws {InvalidConstantError} if the input is not even-length hexadecimal.
151
+ */
152
+ export declare function createHexString(hex: string): HexString;
153
+ /**
154
+ * Create a branded Base64String from a raw string.
155
+ *
156
+ * @throws {InvalidConstantError} if the input is not valid base64.
157
+ */
158
+ export declare function createBase64String(base64: string): Base64String;
159
+ /**
160
+ * Create a branded JsonString from a raw string.
161
+ *
162
+ * @throws {InvalidConstantError} if the input is not parseable JSON.
163
+ */
164
+ export declare function createJsonString(json: string): JsonString;
96
165
  //# sourceMappingURL=common.constant.d.ts.map
@@ -1,9 +1,13 @@
1
1
  /**
2
- * Common default values, limits, and sentinel constants.
2
+ * Common default values, limits, sentinel constants, and branded-type
3
+ * factories.
3
4
  *
4
5
  * @module common/common
5
6
  */
6
7
  import {} from "./common.type.js";
8
+ import { ContentTypes, Charset } from "../http/httpContentType.type.js";
9
+ import { ValidationPattern } from "../validation/validation.pattern.type.js";
10
+ import { InvalidConstantError } from "../constantsErrors/constantsError.base.js";
7
11
  /** Sentinel value indicating absence of a value. */
8
12
  export const NONE = "NONE";
9
13
  /** Sentinel value indicating an uninitialized state. */
@@ -24,10 +28,24 @@ export const Limits = Object.freeze({
24
28
  MAX_PAGE_SIZE: 100,
25
29
  /** Default page size for paginated queries */
26
30
  DEFAULT_PAGE_SIZE: 20,
27
- /** Maximum depth for nested structures */
31
+ /**
32
+ * Maximum depth for general nested data structures (e.g. user-supplied
33
+ * config objects).
34
+ *
35
+ * Intentionally distinct from `SCHEMA_DEFAULT_MAX_DEPTH` (100 — recursion
36
+ * guard for schema validation) and `SerializationLimits.MAX_DEPTH` (128 —
37
+ * recursion guard for the serializer): those bound internal traversal,
38
+ * this bounds acceptable user data shape.
39
+ */
28
40
  MAX_NESTING_DEPTH: 10,
29
- /** Maximum number of retry attempts */
30
- MAX_RETRY_ATTEMPTS: 5,
41
+ /**
42
+ * Maximum number of retry attempts a caller may configure (upper bound).
43
+ *
44
+ * This is the single source of truth for the retry cap —
45
+ * `ValidationRange.MAX_RETRIES` derives from it. The out-of-the-box default
46
+ * is the (smaller) `DefaultRetry.MAX_ATTEMPTS`.
47
+ */
48
+ MAX_RETRY_ATTEMPTS: 10,
31
49
  /** Maximum number of concurrent operations */
32
50
  MAX_CONCURRENCY: 10,
33
51
  /** Maximum buffer size (64 KB) */
@@ -39,12 +57,15 @@ export const Limits = Object.freeze({
39
57
  * Default configuration values for common options.
40
58
  */
41
59
  export const Defaults = Object.freeze({
42
- /** Default character encoding */
43
- ENCODING: "utf-8",
44
- /** Default MIME type */
45
- CONTENT_TYPE: "application/json",
46
- /** Default date format (ISO 8601) */
47
- DATE_FORMAT: "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
60
+ /** Default character encoding (canonical: {@link Charset.UTF_8}) */
61
+ ENCODING: Charset.UTF_8,
62
+ /** Default MIME type (canonical: {@link ContentTypes.JSON}) */
63
+ CONTENT_TYPE: ContentTypes.JSON,
64
+ /**
65
+ * Default date format (ISO 8601 with timezone offset; `XXX` renders `Z`
66
+ * for UTC or `±hh:mm` otherwise).
67
+ */
68
+ DATE_FORMAT: "yyyy-MM-dd'T'HH:mm:ss.SSSXXX",
48
69
  /** Default time zone */
49
70
  TIMEZONE: "UTC",
50
71
  /** Default locale */
@@ -64,8 +85,6 @@ export const Defaults = Object.freeze({
64
85
  export const Sentinel = Object.freeze({
65
86
  /** Value indicating null/absence in serialized form */
66
87
  NULL: null,
67
- /** Value indicating undefined in serialized form */
68
- UNDEFINED: undefined,
69
88
  /** Marker for deleted soft-delete records */
70
89
  DELETED: "__DELETED__",
71
90
  /** Marker for placeholder data */
@@ -97,10 +116,105 @@ export function createRequestId(id) {
97
116
  export function createCorrelationId(id) {
98
117
  return id;
99
118
  }
119
+ /**
120
+ * Create a branded SessionId from a raw string.
121
+ */
122
+ export function createSessionId(id) {
123
+ return id;
124
+ }
125
+ /**
126
+ * Create a branded TenantId from a raw string.
127
+ */
128
+ export function createTenantId(id) {
129
+ return id;
130
+ }
131
+ /**
132
+ * Create a branded MessageId from a raw string.
133
+ */
134
+ export function createMessageId(id) {
135
+ return id;
136
+ }
137
+ /**
138
+ * Create a branded MessageCausationId from a raw string.
139
+ */
140
+ export function createMessageCausationId(id) {
141
+ return id;
142
+ }
143
+ /**
144
+ * Create a branded TokenId from a raw string.
145
+ */
146
+ export function createTokenId(id) {
147
+ return id;
148
+ }
100
149
  /**
101
150
  * Create a branded Timestamp from an ISO 8601 string.
151
+ *
152
+ * @throws {InvalidConstantError} if the input is not a valid ISO 8601
153
+ * date-time string (e.g. `2024-01-01T00:00:00.000Z`).
102
154
  */
103
155
  export function createTimestamp(iso) {
156
+ if (!ValidationPattern.ISO_DATE_TIME.test(iso) ||
157
+ Number.isNaN(Date.parse(iso))) {
158
+ throw new InvalidConstantError(`Invalid ISO 8601 timestamp: ${JSON.stringify(iso)}`);
159
+ }
104
160
  return iso;
105
161
  }
162
+ /**
163
+ * Create a branded Url from a raw string.
164
+ *
165
+ * @throws {InvalidConstantError} if the input is not a parseable URL.
166
+ */
167
+ export function createUrl(url) {
168
+ if (!URL.canParse(url)) {
169
+ throw new InvalidConstantError(`Invalid URL: ${JSON.stringify(url)}`);
170
+ }
171
+ return url;
172
+ }
173
+ /**
174
+ * Create a branded EmailAddress from a raw string.
175
+ *
176
+ * @throws {InvalidConstantError} if the input is not a valid email address.
177
+ */
178
+ export function createEmailAddress(email) {
179
+ if (email.length > 254 || !ValidationPattern.EMAIL.test(email)) {
180
+ throw new InvalidConstantError(`Invalid email address: ${JSON.stringify(email)}`);
181
+ }
182
+ return email;
183
+ }
184
+ /**
185
+ * Create a branded HexString from a raw string.
186
+ *
187
+ * @throws {InvalidConstantError} if the input is not even-length hexadecimal.
188
+ */
189
+ export function createHexString(hex) {
190
+ if (hex.length % 2 !== 0 || !/^[0-9a-fA-F]*$/.test(hex)) {
191
+ throw new InvalidConstantError(`Invalid hex string: ${JSON.stringify(hex)}`);
192
+ }
193
+ return hex;
194
+ }
195
+ /**
196
+ * Create a branded Base64String from a raw string.
197
+ *
198
+ * @throws {InvalidConstantError} if the input is not valid base64.
199
+ */
200
+ export function createBase64String(base64) {
201
+ if (!/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(base64)) {
202
+ throw new InvalidConstantError(`Invalid base64 string: ${JSON.stringify(base64)}`);
203
+ }
204
+ return base64;
205
+ }
206
+ /**
207
+ * Create a branded JsonString from a raw string.
208
+ *
209
+ * @throws {InvalidConstantError} if the input is not parseable JSON.
210
+ */
211
+ export function createJsonString(json) {
212
+ try {
213
+ JSON.parse(json);
214
+ }
215
+ catch {
216
+ throw new InvalidConstantError(`Invalid JSON string: ${JSON.stringify(json)}`);
217
+ }
218
+ return json;
219
+ }
106
220
  //# sourceMappingURL=common.constant.js.map