hazo_core 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 (124) hide show
  1. package/README.md +84 -0
  2. package/SETUP_CHECKLIST.md +114 -0
  3. package/config/hazo_core_config.ini +14 -0
  4. package/dist/config/index.d.ts +35 -0
  5. package/dist/config/index.d.ts.map +1 -0
  6. package/dist/config/index.js +117 -0
  7. package/dist/config/index.js.map +1 -0
  8. package/dist/config/ini_parser.d.ts +10 -0
  9. package/dist/config/ini_parser.d.ts.map +1 -0
  10. package/dist/config/ini_parser.js +45 -0
  11. package/dist/config/ini_parser.js.map +1 -0
  12. package/dist/constants.d.ts +4 -0
  13. package/dist/constants.d.ts.map +1 -0
  14. package/dist/constants.js +4 -0
  15. package/dist/constants.js.map +1 -0
  16. package/dist/context/client.d.ts +27 -0
  17. package/dist/context/client.d.ts.map +1 -0
  18. package/dist/context/client.js +66 -0
  19. package/dist/context/client.js.map +1 -0
  20. package/dist/context/index.d.ts +9 -0
  21. package/dist/context/index.d.ts.map +1 -0
  22. package/dist/context/index.js +8 -0
  23. package/dist/context/index.js.map +1 -0
  24. package/dist/context/server.d.ts +23 -0
  25. package/dist/context/server.d.ts.map +1 -0
  26. package/dist/context/server.js +52 -0
  27. package/dist/context/server.js.map +1 -0
  28. package/dist/context/types.d.ts +14 -0
  29. package/dist/context/types.d.ts.map +1 -0
  30. package/dist/context/types.js +2 -0
  31. package/dist/context/types.js.map +1 -0
  32. package/dist/debug/index.d.ts +20 -0
  33. package/dist/debug/index.d.ts.map +1 -0
  34. package/dist/debug/index.js +78 -0
  35. package/dist/debug/index.js.map +1 -0
  36. package/dist/errors/auth.d.ts +14 -0
  37. package/dist/errors/auth.d.ts.map +1 -0
  38. package/dist/errors/auth.js +19 -0
  39. package/dist/errors/auth.js.map +1 -0
  40. package/dist/errors/base.d.ts +89 -0
  41. package/dist/errors/base.d.ts.map +1 -0
  42. package/dist/errors/base.js +152 -0
  43. package/dist/errors/base.js.map +1 -0
  44. package/dist/errors/config.d.ts +18 -0
  45. package/dist/errors/config.d.ts.map +1 -0
  46. package/dist/errors/config.js +14 -0
  47. package/dist/errors/config.js.map +1 -0
  48. package/dist/errors/conflict.d.ts +9 -0
  49. package/dist/errors/conflict.d.ts.map +1 -0
  50. package/dist/errors/conflict.js +14 -0
  51. package/dist/errors/conflict.js.map +1 -0
  52. package/dist/errors/external.d.ts +9 -0
  53. package/dist/errors/external.d.ts.map +1 -0
  54. package/dist/errors/external.js +14 -0
  55. package/dist/errors/external.js.map +1 -0
  56. package/dist/errors/from_zod.d.ts +33 -0
  57. package/dist/errors/from_zod.d.ts.map +1 -0
  58. package/dist/errors/from_zod.js +63 -0
  59. package/dist/errors/from_zod.js.map +1 -0
  60. package/dist/errors/index.d.ts +22 -0
  61. package/dist/errors/index.d.ts.map +1 -0
  62. package/dist/errors/index.js +12 -0
  63. package/dist/errors/index.js.map +1 -0
  64. package/dist/errors/internal.d.ts +14 -0
  65. package/dist/errors/internal.d.ts.map +1 -0
  66. package/dist/errors/internal.js +14 -0
  67. package/dist/errors/internal.js.map +1 -0
  68. package/dist/errors/not_found.d.ts +9 -0
  69. package/dist/errors/not_found.d.ts.map +1 -0
  70. package/dist/errors/not_found.js +15 -0
  71. package/dist/errors/not_found.js.map +1 -0
  72. package/dist/errors/rate_limit.d.ts +9 -0
  73. package/dist/errors/rate_limit.d.ts.map +1 -0
  74. package/dist/errors/rate_limit.js +14 -0
  75. package/dist/errors/rate_limit.js.map +1 -0
  76. package/dist/errors/unavailable.d.ts +9 -0
  77. package/dist/errors/unavailable.d.ts.map +1 -0
  78. package/dist/errors/unavailable.js +14 -0
  79. package/dist/errors/unavailable.js.map +1 -0
  80. package/dist/errors/validation.d.ts +15 -0
  81. package/dist/errors/validation.d.ts.map +1 -0
  82. package/dist/errors/validation.js +17 -0
  83. package/dist/errors/validation.js.map +1 -0
  84. package/dist/http/fetch_with_request_id.d.ts +14 -0
  85. package/dist/http/fetch_with_request_id.d.ts.map +1 -0
  86. package/dist/http/fetch_with_request_id.js +29 -0
  87. package/dist/http/fetch_with_request_id.js.map +1 -0
  88. package/dist/http/get_origin_url.d.ts +23 -0
  89. package/dist/http/get_origin_url.d.ts.map +1 -0
  90. package/dist/http/get_origin_url.js +61 -0
  91. package/dist/http/get_origin_url.js.map +1 -0
  92. package/dist/http/request_id_middleware.d.ts +38 -0
  93. package/dist/http/request_id_middleware.d.ts.map +1 -0
  94. package/dist/http/request_id_middleware.js +57 -0
  95. package/dist/http/request_id_middleware.js.map +1 -0
  96. package/dist/index.client.d.ts +16 -0
  97. package/dist/index.client.d.ts.map +1 -0
  98. package/dist/index.client.js +19 -0
  99. package/dist/index.client.js.map +1 -0
  100. package/dist/index.d.ts +23 -0
  101. package/dist/index.d.ts.map +1 -0
  102. package/dist/index.js +27 -0
  103. package/dist/index.js.map +1 -0
  104. package/dist/logger/index.d.ts +29 -0
  105. package/dist/logger/index.d.ts.map +1 -0
  106. package/dist/logger/index.js +125 -0
  107. package/dist/logger/index.js.map +1 -0
  108. package/dist/singleton/index.d.ts +16 -0
  109. package/dist/singleton/index.d.ts.map +1 -0
  110. package/dist/singleton/index.js +42 -0
  111. package/dist/singleton/index.js.map +1 -0
  112. package/dist/utils/dates.d.ts +45 -0
  113. package/dist/utils/dates.d.ts.map +1 -0
  114. package/dist/utils/dates.js +79 -0
  115. package/dist/utils/dates.js.map +1 -0
  116. package/dist/utils/env.d.ts +7 -0
  117. package/dist/utils/env.d.ts.map +1 -0
  118. package/dist/utils/env.js +9 -0
  119. package/dist/utils/env.js.map +1 -0
  120. package/dist/utils/index.d.ts +69 -0
  121. package/dist/utils/index.d.ts.map +1 -0
  122. package/dist/utils/index.js +174 -0
  123. package/dist/utils/index.js.map +1 -0
  124. package/package.json +82 -0
@@ -0,0 +1,63 @@
1
+ import { HazoValidationError } from './validation.js';
2
+ import { HazoConfigError } from './config.js';
3
+ /**
4
+ * Maps a ZodError's issues array to the ValidationIssue shape.
5
+ */
6
+ function mapZodIssues(zodError) {
7
+ return zodError.issues.map((issue) => ({
8
+ path: issue.path,
9
+ message: issue.message,
10
+ }));
11
+ }
12
+ /**
13
+ * Create a HazoValidationError from a ZodError.
14
+ * Typically used for request body / query param validation failures.
15
+ *
16
+ * @example
17
+ * const result = mySchema.safeParse(input);
18
+ * if (!result.success) {
19
+ * throw fromZodValidation(result.error, { pkg: 'hazo_auth', code: 'HAZO_AUTH_INVALID_INPUT' });
20
+ * }
21
+ */
22
+ export function fromZodValidation(zodError, opts) {
23
+ const issues = mapZodIssues(zodError);
24
+ const message = issues.length === 1
25
+ ? issues[0].message
26
+ : `${issues.length} validation error(s): ${issues.map((i) => i.message).join('; ')}`;
27
+ return new HazoValidationError({
28
+ code: opts.code,
29
+ pkg: opts.pkg,
30
+ message,
31
+ httpStatus: opts.httpStatus,
32
+ issues,
33
+ context: {
34
+ zodIssues: zodError.issues,
35
+ },
36
+ });
37
+ }
38
+ /**
39
+ * Create a HazoConfigError from a ZodError.
40
+ * Typically used when a package's INI config fails its Zod schema validation.
41
+ *
42
+ * @example
43
+ * const result = configSchema.safeParse(rawConfig);
44
+ * if (!result.success) {
45
+ * throw fromZodConfig(result.error, { pkg: 'hazo_auth', code: 'HAZO_AUTH_CONFIG_INVALID' });
46
+ * }
47
+ */
48
+ export function fromZodConfig(zodError, opts) {
49
+ const issues = mapZodIssues(zodError);
50
+ const message = issues.length === 1
51
+ ? `Config error: ${issues[0].message}`
52
+ : `Config has ${issues.length} error(s): ${issues.map((i) => `[${i.path.join('.')}] ${i.message}`).join('; ')}`;
53
+ return new HazoConfigError({
54
+ code: opts.code,
55
+ pkg: opts.pkg,
56
+ message,
57
+ context: {
58
+ configIssues: issues,
59
+ zodIssues: zodError.issues,
60
+ },
61
+ });
62
+ }
63
+ //# sourceMappingURL=from_zod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"from_zod.js","sourceRoot":"","sources":["../../src/errors/from_zod.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAwB,MAAM,iBAAiB,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C;;GAEG;AACH,SAAS,YAAY,CAAC,QAAkB;IACtC,OAAO,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACrC,IAAI,EAAE,KAAK,CAAC,IAA2B;QACvC,OAAO,EAAE,KAAK,CAAC,OAAO;KACvB,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAC/B,QAAkB,EAClB,IAAwD;IAExD,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,OAAO,GACX,MAAM,CAAC,MAAM,KAAK,CAAC;QACjB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAE,CAAC,OAAO;QACpB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,yBAAyB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAEzF,OAAO,IAAI,mBAAmB,CAAC;QAC7B,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,OAAO;QACP,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,MAAM;QACN,OAAO,EAAE;YACP,SAAS,EAAE,QAAQ,CAAC,MAAM;SAC3B;KACF,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAC3B,QAAkB,EAClB,IAAmC;IAEnC,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,OAAO,GACX,MAAM,CAAC,MAAM,KAAK,CAAC;QACjB,CAAC,CAAC,iBAAiB,MAAM,CAAC,CAAC,CAAE,CAAC,OAAO,EAAE;QACvC,CAAC,CAAC,cAAc,MAAM,CAAC,MAAM,cAAc,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAEpH,OAAO,IAAI,eAAe,CAAC;QACzB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,OAAO;QACP,OAAO,EAAE;YACP,YAAY,EAAE,MAAM;YACpB,SAAS,EAAE,QAAQ,CAAC,MAAM;SAC3B;KACF,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,22 @@
1
+ export { HazoError } from './base.js';
2
+ export type { HazoErrorOptions } from './base.js';
3
+ export { HazoValidationError } from './validation.js';
4
+ export type { HazoValidationErrorOptions, ValidationIssue } from './validation.js';
5
+ export { HazoAuthError } from './auth.js';
6
+ export type { HazoAuthErrorOptions } from './auth.js';
7
+ export { HazoNotFoundError } from './not_found.js';
8
+ export type { HazoNotFoundErrorOptions } from './not_found.js';
9
+ export { HazoConflictError } from './conflict.js';
10
+ export type { HazoConflictErrorOptions } from './conflict.js';
11
+ export { HazoRateLimitError } from './rate_limit.js';
12
+ export type { HazoRateLimitErrorOptions } from './rate_limit.js';
13
+ export { HazoUnavailableError } from './unavailable.js';
14
+ export type { HazoUnavailableErrorOptions } from './unavailable.js';
15
+ export { HazoExternalError } from './external.js';
16
+ export type { HazoExternalErrorOptions } from './external.js';
17
+ export { HazoConfigError } from './config.js';
18
+ export type { HazoConfigErrorOptions } from './config.js';
19
+ export { HazoInternalError } from './internal.js';
20
+ export type { HazoInternalErrorOptions } from './internal.js';
21
+ export { fromZodValidation, fromZodConfig } from './from_zod.js';
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,YAAY,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAElD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,YAAY,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEnF,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,YAAY,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAEtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,YAAY,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAE/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,YAAY,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAE9D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,YAAY,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAEjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,YAAY,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AAEpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,YAAY,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAE9D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,YAAY,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAE9D,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,12 @@
1
+ export { HazoError } from './base.js';
2
+ export { HazoValidationError } from './validation.js';
3
+ export { HazoAuthError } from './auth.js';
4
+ export { HazoNotFoundError } from './not_found.js';
5
+ export { HazoConflictError } from './conflict.js';
6
+ export { HazoRateLimitError } from './rate_limit.js';
7
+ export { HazoUnavailableError } from './unavailable.js';
8
+ export { HazoExternalError } from './external.js';
9
+ export { HazoConfigError } from './config.js';
10
+ export { HazoInternalError } from './internal.js';
11
+ export { fromZodValidation, fromZodConfig } from './from_zod.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAGtD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAGnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGlD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAGrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAGxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGlD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGlD,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { HazoError, type HazoErrorOptions } from './base.js';
2
+ /**
3
+ * HazoInternalError — programmer error / invariant violation.
4
+ * Not retryable. Distinct from HazoExternalError ("their bug") or HazoUnavailableError
5
+ * (temporary condition) — this is "our bug".
6
+ */
7
+ export type HazoInternalErrorOptions = Omit<HazoErrorOptions, 'httpStatus' | 'retryable'> & {
8
+ httpStatus?: number;
9
+ };
10
+ export declare class HazoInternalError extends HazoError {
11
+ constructor(opts: HazoInternalErrorOptions);
12
+ toUserMessage(): string;
13
+ }
14
+ //# sourceMappingURL=internal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../src/errors/internal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7D;;;;GAIG;AACH,MAAM,MAAM,wBAAwB,GAAG,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,WAAW,CAAC,GAAG;IAC1F,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,qBAAa,iBAAkB,SAAQ,SAAS;gBAClC,IAAI,EAAE,wBAAwB;IAQ1C,aAAa,IAAI,MAAM;CAGxB"}
@@ -0,0 +1,14 @@
1
+ import { HazoError } from './base.js';
2
+ export class HazoInternalError extends HazoError {
3
+ constructor(opts) {
4
+ super({
5
+ httpStatus: 500,
6
+ retryable: false,
7
+ ...opts,
8
+ });
9
+ }
10
+ toUserMessage() {
11
+ return 'An unexpected error occurred. Please try again.';
12
+ }
13
+ }
14
+ //# sourceMappingURL=internal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal.js","sourceRoot":"","sources":["../../src/errors/internal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAyB,MAAM,WAAW,CAAC;AAW7D,MAAM,OAAO,iBAAkB,SAAQ,SAAS;IAC9C,YAAY,IAA8B;QACxC,KAAK,CAAC;YACJ,UAAU,EAAE,GAAG;YACf,SAAS,EAAE,KAAK;YAChB,GAAG,IAAI;SACR,CAAC,CAAC;IACL,CAAC;IAED,aAAa;QACX,OAAO,iDAAiD,CAAC;IAC3D,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ import { HazoError, type HazoErrorOptions } from './base.js';
2
+ export type HazoNotFoundErrorOptions = Omit<HazoErrorOptions, 'httpStatus' | 'retryable'> & {
3
+ httpStatus?: number;
4
+ };
5
+ export declare class HazoNotFoundError extends HazoError {
6
+ constructor(opts: HazoNotFoundErrorOptions);
7
+ toUserMessage(): string;
8
+ }
9
+ //# sourceMappingURL=not_found.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"not_found.d.ts","sourceRoot":"","sources":["../../src/errors/not_found.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7D,MAAM,MAAM,wBAAwB,GAAG,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,WAAW,CAAC,GAAG;IAC1F,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,qBAAa,iBAAkB,SAAQ,SAAS;gBAClC,IAAI,EAAE,wBAAwB;IAQ1C,aAAa,IAAI,MAAM;CAIxB"}
@@ -0,0 +1,15 @@
1
+ import { HazoError } from './base.js';
2
+ export class HazoNotFoundError extends HazoError {
3
+ constructor(opts) {
4
+ super({
5
+ httpStatus: 404,
6
+ retryable: false,
7
+ ...opts,
8
+ });
9
+ }
10
+ toUserMessage() {
11
+ const resource = this.context?.['resource'];
12
+ return resource ? `${String(resource)} not found.` : 'Resource not found.';
13
+ }
14
+ }
15
+ //# sourceMappingURL=not_found.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"not_found.js","sourceRoot":"","sources":["../../src/errors/not_found.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAyB,MAAM,WAAW,CAAC;AAM7D,MAAM,OAAO,iBAAkB,SAAQ,SAAS;IAC9C,YAAY,IAA8B;QACxC,KAAK,CAAC;YACJ,UAAU,EAAE,GAAG;YACf,SAAS,EAAE,KAAK;YAChB,GAAG,IAAI;SACR,CAAC,CAAC;IACL,CAAC;IAED,aAAa;QACX,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC,CAAC;QAC5C,OAAO,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,qBAAqB,CAAC;IAC7E,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ import { HazoError, type HazoErrorOptions } from './base.js';
2
+ export type HazoRateLimitErrorOptions = Omit<HazoErrorOptions, 'httpStatus' | 'retryable'> & {
3
+ httpStatus?: number;
4
+ };
5
+ export declare class HazoRateLimitError extends HazoError {
6
+ constructor(opts: HazoRateLimitErrorOptions);
7
+ toUserMessage(): string;
8
+ }
9
+ //# sourceMappingURL=rate_limit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate_limit.d.ts","sourceRoot":"","sources":["../../src/errors/rate_limit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7D,MAAM,MAAM,yBAAyB,GAAG,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,WAAW,CAAC,GAAG;IAC3F,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,qBAAa,kBAAmB,SAAQ,SAAS;gBACnC,IAAI,EAAE,yBAAyB;IAQ3C,aAAa,IAAI,MAAM;CAGxB"}
@@ -0,0 +1,14 @@
1
+ import { HazoError } from './base.js';
2
+ export class HazoRateLimitError extends HazoError {
3
+ constructor(opts) {
4
+ super({
5
+ httpStatus: 429,
6
+ retryable: true,
7
+ ...opts,
8
+ });
9
+ }
10
+ toUserMessage() {
11
+ return 'Too many requests. Please wait a moment before trying again.';
12
+ }
13
+ }
14
+ //# sourceMappingURL=rate_limit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate_limit.js","sourceRoot":"","sources":["../../src/errors/rate_limit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAyB,MAAM,WAAW,CAAC;AAM7D,MAAM,OAAO,kBAAmB,SAAQ,SAAS;IAC/C,YAAY,IAA+B;QACzC,KAAK,CAAC;YACJ,UAAU,EAAE,GAAG;YACf,SAAS,EAAE,IAAI;YACf,GAAG,IAAI;SACR,CAAC,CAAC;IACL,CAAC;IAED,aAAa;QACX,OAAO,8DAA8D,CAAC;IACxE,CAAC;CACF"}
@@ -0,0 +1,9 @@
1
+ import { HazoError, type HazoErrorOptions } from './base.js';
2
+ export type HazoUnavailableErrorOptions = Omit<HazoErrorOptions, 'httpStatus' | 'retryable'> & {
3
+ httpStatus?: number;
4
+ };
5
+ export declare class HazoUnavailableError extends HazoError {
6
+ constructor(opts: HazoUnavailableErrorOptions);
7
+ toUserMessage(): string;
8
+ }
9
+ //# sourceMappingURL=unavailable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unavailable.d.ts","sourceRoot":"","sources":["../../src/errors/unavailable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7D,MAAM,MAAM,2BAA2B,GAAG,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,WAAW,CAAC,GAAG;IAC7F,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,qBAAa,oBAAqB,SAAQ,SAAS;gBACrC,IAAI,EAAE,2BAA2B;IAQ7C,aAAa,IAAI,MAAM;CAGxB"}
@@ -0,0 +1,14 @@
1
+ import { HazoError } from './base.js';
2
+ export class HazoUnavailableError extends HazoError {
3
+ constructor(opts) {
4
+ super({
5
+ httpStatus: 503,
6
+ retryable: true,
7
+ ...opts,
8
+ });
9
+ }
10
+ toUserMessage() {
11
+ return 'Service temporarily unavailable. Please try again in a moment.';
12
+ }
13
+ }
14
+ //# sourceMappingURL=unavailable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unavailable.js","sourceRoot":"","sources":["../../src/errors/unavailable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAyB,MAAM,WAAW,CAAC;AAM7D,MAAM,OAAO,oBAAqB,SAAQ,SAAS;IACjD,YAAY,IAAiC;QAC3C,KAAK,CAAC;YACJ,UAAU,EAAE,GAAG;YACf,SAAS,EAAE,IAAI;YACf,GAAG,IAAI;SACR,CAAC,CAAC;IACL,CAAC;IAED,aAAa;QACX,OAAO,gEAAgE,CAAC;IAC1E,CAAC;CACF"}
@@ -0,0 +1,15 @@
1
+ import { HazoError, type HazoErrorOptions } from './base.js';
2
+ export interface ValidationIssue {
3
+ path: (string | number)[];
4
+ message: string;
5
+ }
6
+ export interface HazoValidationErrorOptions extends Omit<HazoErrorOptions, 'httpStatus' | 'retryable'> {
7
+ httpStatus?: number;
8
+ issues?: ValidationIssue[];
9
+ }
10
+ export declare class HazoValidationError extends HazoError {
11
+ readonly issues: ValidationIssue[];
12
+ constructor(opts: HazoValidationErrorOptions);
13
+ toUserMessage(): string;
14
+ }
15
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/errors/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7D,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,0BAA2B,SAAQ,IAAI,CAAC,gBAAgB,EAAE,YAAY,GAAG,WAAW,CAAC;IACpG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;CAC5B;AAED,qBAAa,mBAAoB,SAAQ,SAAS;IAChD,QAAQ,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC;gBAEvB,IAAI,EAAE,0BAA0B;IAS5C,aAAa,IAAI,MAAM;CAIxB"}
@@ -0,0 +1,17 @@
1
+ import { HazoError } from './base.js';
2
+ export class HazoValidationError extends HazoError {
3
+ issues;
4
+ constructor(opts) {
5
+ super({
6
+ httpStatus: 400,
7
+ retryable: false,
8
+ ...opts,
9
+ });
10
+ this.issues = opts.issues ?? [];
11
+ }
12
+ toUserMessage() {
13
+ // Validation messages are written for users — safe to return directly.
14
+ return this.message;
15
+ }
16
+ }
17
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/errors/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAyB,MAAM,WAAW,CAAC;AAY7D,MAAM,OAAO,mBAAoB,SAAQ,SAAS;IACvC,MAAM,CAAoB;IAEnC,YAAY,IAAgC;QAC1C,KAAK,CAAC;YACJ,UAAU,EAAE,GAAG;YACf,SAAS,EAAE,KAAK;YAChB,GAAG,IAAI;SACR,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;IAClC,CAAC;IAED,aAAa;QACX,uEAAuE;QACvE,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;CACF"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Drop-in replacement for fetch that injects X-Request-Id from the current
3
+ * AsyncLocalStorage context into the outbound request.
4
+ *
5
+ * If no correlationId is active, behaves identically to native fetch.
6
+ *
7
+ * Per architecture.md §7 (Outbound propagation).
8
+ *
9
+ * @example
10
+ * // Inside a withContext() scope, the correlation ID propagates automatically:
11
+ * const response = await fetchWithRequestId('https://api.example.com/data');
12
+ */
13
+ export declare function fetchWithRequestId(input: RequestInfo | URL, init?: RequestInit): Promise<Response>;
14
+ //# sourceMappingURL=fetch_with_request_id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch_with_request_id.d.ts","sourceRoot":"","sources":["../../src/http/fetch_with_request_id.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,WAAW,GAAG,GAAG,EACxB,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,QAAQ,CAAC,CAgBnB"}
@@ -0,0 +1,29 @@
1
+ import { getCorrelationId } from '../context/server.js';
2
+ import { REQUEST_ID_HEADER } from '../constants.js';
3
+ /**
4
+ * Drop-in replacement for fetch that injects X-Request-Id from the current
5
+ * AsyncLocalStorage context into the outbound request.
6
+ *
7
+ * If no correlationId is active, behaves identically to native fetch.
8
+ *
9
+ * Per architecture.md §7 (Outbound propagation).
10
+ *
11
+ * @example
12
+ * // Inside a withContext() scope, the correlation ID propagates automatically:
13
+ * const response = await fetchWithRequestId('https://api.example.com/data');
14
+ */
15
+ export function fetchWithRequestId(input, init) {
16
+ const correlationId = getCorrelationId();
17
+ if (!correlationId) {
18
+ // No active context — pass through unchanged
19
+ return fetch(input, init);
20
+ }
21
+ // Merge the correlation ID header without mutating the caller's init
22
+ const headers = new Headers(init?.headers);
23
+ // Only set if not already present (caller's explicit header takes precedence)
24
+ if (!headers.has(REQUEST_ID_HEADER)) {
25
+ headers.set(REQUEST_ID_HEADER, correlationId);
26
+ }
27
+ return fetch(input, { ...init, headers });
28
+ }
29
+ //# sourceMappingURL=fetch_with_request_id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch_with_request_id.js","sourceRoot":"","sources":["../../src/http/fetch_with_request_id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAwB,EACxB,IAAkB;IAElB,MAAM,aAAa,GAAG,gBAAgB,EAAE,CAAC;IAEzC,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,6CAA6C;QAC7C,OAAO,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,qEAAqE;IACrE,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3C,8EAA8E;IAC9E,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAC;IAChD,CAAC;IAED,OAAO,KAAK,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Gets the public-facing origin URL for redirect construction.
3
+ *
4
+ * Behind reverse proxies (Cloudflare, nginx, etc.), `request.url` contains the
5
+ * internal address (e.g. `http://localhost:3000`), not the public domain.
6
+ * This function returns the correct origin from environment variables.
7
+ *
8
+ * Priority: NEXTAUTH_URL > APP_DOMAIN_NAME > NEXT_PUBLIC_APP_URL > APP_URL > request.url
9
+ *
10
+ * @param request_url - The request.url to use as fallback
11
+ * @returns The origin URL (e.g. "https://gotimer.org")
12
+ */
13
+ export declare function get_origin_url(request_url: string): string;
14
+ /**
15
+ * Creates a URL using the public-facing origin instead of request.url.
16
+ * Drop-in replacement for `new URL(path, request.url)` in route handlers.
17
+ *
18
+ * @param path - The path or relative URL (e.g. "/hazo_auth/login")
19
+ * @param request_url - The request.url (used as fallback only)
20
+ * @returns A URL object with the correct public origin
21
+ */
22
+ export declare function create_redirect_url(path: string, request_url: string): URL;
23
+ //# sourceMappingURL=get_origin_url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get_origin_url.d.ts","sourceRoot":"","sources":["../../src/http/get_origin_url.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA8B1D;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,GAAG,CAG1E"}
@@ -0,0 +1,61 @@
1
+ // file_description: Resolves the public-facing origin URL for constructing redirects.
2
+ // When running behind a reverse proxy (Cloudflare, nginx), request.url resolves to
3
+ // the internal address (e.g. http://localhost:3000). This utility returns the correct
4
+ // public origin using environment variables.
5
+ //
6
+ // Canonical location: hazo_core/http (moved here from hazo_auth in hazo_core v1).
7
+ // hazo_auth re-exports these from this module for backward compatibility.
8
+ /**
9
+ * Gets the public-facing origin URL for redirect construction.
10
+ *
11
+ * Behind reverse proxies (Cloudflare, nginx, etc.), `request.url` contains the
12
+ * internal address (e.g. `http://localhost:3000`), not the public domain.
13
+ * This function returns the correct origin from environment variables.
14
+ *
15
+ * Priority: NEXTAUTH_URL > APP_DOMAIN_NAME > NEXT_PUBLIC_APP_URL > APP_URL > request.url
16
+ *
17
+ * @param request_url - The request.url to use as fallback
18
+ * @returns The origin URL (e.g. "https://gotimer.org")
19
+ */
20
+ export function get_origin_url(request_url) {
21
+ // NEXTAUTH_URL is the standard for NextAuth.js apps
22
+ const nextauth_url = process.env['NEXTAUTH_URL'];
23
+ if (nextauth_url) {
24
+ return nextauth_url.replace(/\/$/, '');
25
+ }
26
+ // APP_DOMAIN_NAME (with protocol handling)
27
+ const app_domain = process.env['APP_DOMAIN_NAME'];
28
+ if (app_domain) {
29
+ const domain = app_domain.trim();
30
+ if (domain.startsWith('http://') || domain.startsWith('https://')) {
31
+ return domain.replace(/\/$/, '');
32
+ }
33
+ return `https://${domain}`;
34
+ }
35
+ // Other common env vars
36
+ const env_url = process.env['NEXT_PUBLIC_APP_URL'] || process.env['APP_URL'];
37
+ if (env_url) {
38
+ return env_url.replace(/\/$/, '');
39
+ }
40
+ // Fallback to request.url (works in development without a proxy)
41
+ try {
42
+ const url = new URL(request_url);
43
+ return url.origin;
44
+ }
45
+ catch {
46
+ return request_url;
47
+ }
48
+ }
49
+ /**
50
+ * Creates a URL using the public-facing origin instead of request.url.
51
+ * Drop-in replacement for `new URL(path, request.url)` in route handlers.
52
+ *
53
+ * @param path - The path or relative URL (e.g. "/hazo_auth/login")
54
+ * @param request_url - The request.url (used as fallback only)
55
+ * @returns A URL object with the correct public origin
56
+ */
57
+ export function create_redirect_url(path, request_url) {
58
+ const origin = get_origin_url(request_url);
59
+ return new URL(path, origin);
60
+ }
61
+ //# sourceMappingURL=get_origin_url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get_origin_url.js","sourceRoot":"","sources":["../../src/http/get_origin_url.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,mFAAmF;AACnF,sFAAsF;AACtF,6CAA6C;AAC7C,EAAE;AACF,kFAAkF;AAClF,0EAA0E;AAE1E;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,cAAc,CAAC,WAAmB;IAChD,oDAAoD;IACpD,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACjD,IAAI,YAAY,EAAE,CAAC;QACjB,OAAO,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,2CAA2C;IAC3C,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAClD,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC;QACjC,IAAI,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAClE,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACnC,CAAC;QACD,OAAO,WAAW,MAAM,EAAE,CAAC;IAC7B,CAAC;IAED,wBAAwB;IACxB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC7E,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACpC,CAAC;IAED,iEAAiE;IACjE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;QACjC,OAAO,GAAG,CAAC,MAAM,CAAC;IACpB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,WAAW,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,WAAmB;IACnE,MAAM,MAAM,GAAG,cAAc,CAAC,WAAW,CAAC,CAAC;IAC3C,OAAO,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,38 @@
1
+ type Req = {
2
+ headers: Record<string, string | string[] | undefined>;
3
+ };
4
+ type Res = {
5
+ setHeader: (name: string, value: string) => void;
6
+ };
7
+ type Next = () => void;
8
+ /**
9
+ * Express-style middleware. Reads X-Request-Id from the incoming request,
10
+ * generates a new ID if absent, optionally echoes it on the response header,
11
+ * and runs the rest of the pipeline inside withContext({ correlationId }).
12
+ *
13
+ * Options:
14
+ * generate — override the ID generator (default: generateRequestId / UUID v7)
15
+ * echoOnResponse — whether to echo the ID as a response header (default: true)
16
+ */
17
+ export declare function createRequestIdMiddleware(opts?: {
18
+ generate?: () => string;
19
+ echoOnResponse?: boolean;
20
+ }): (req: Req, res: Res, next: Next) => void;
21
+ /**
22
+ * Next.js App Router route-handler wrapper.
23
+ *
24
+ * Reads the x-request-id header from the standard Request object (first
25
+ * argument to the route handler), wraps the handler in
26
+ * withContext({ correlationId }), and returns the result.
27
+ *
28
+ * Does NOT import from 'next' — uses the standard DOM Request type.
29
+ *
30
+ * @example
31
+ * export const GET = withRequestIdRouteHandler(async (req) => {
32
+ * // getCorrelationId() is available anywhere downstream
33
+ * return Response.json({ ok: true });
34
+ * });
35
+ */
36
+ export declare function withRequestIdRouteHandler<H extends (...args: unknown[]) => unknown>(handler: H): H;
37
+ export {};
38
+ //# sourceMappingURL=request_id_middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request_id_middleware.d.ts","sourceRoot":"","sources":["../../src/http/request_id_middleware.ts"],"names":[],"mappings":"AAQA,KAAK,GAAG,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAA;CAAE,CAAC;AACtE,KAAK,GAAG,GAAG;IAAE,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,CAAC;AAChE,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;AAEvB;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,CAAC,EAAE;IAC/C,QAAQ,CAAC,EAAE,MAAM,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,CAe3C;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,CAgBlG"}
@@ -0,0 +1,57 @@
1
+ import { withContext } from '../context/server.js';
2
+ import { REQUEST_ID_HEADER } from '../constants.js';
3
+ import { generateRequestId } from '../utils/index.js';
4
+ /**
5
+ * Express-style middleware. Reads X-Request-Id from the incoming request,
6
+ * generates a new ID if absent, optionally echoes it on the response header,
7
+ * and runs the rest of the pipeline inside withContext({ correlationId }).
8
+ *
9
+ * Options:
10
+ * generate — override the ID generator (default: generateRequestId / UUID v7)
11
+ * echoOnResponse — whether to echo the ID as a response header (default: true)
12
+ */
13
+ export function createRequestIdMiddleware(opts) {
14
+ const generate = opts?.generate ?? generateRequestId;
15
+ const echoOnResponse = opts?.echoOnResponse ?? true;
16
+ return (req, res, next) => {
17
+ const incoming = req.headers[REQUEST_ID_HEADER];
18
+ const correlationId = (Array.isArray(incoming) ? incoming[0] : incoming) ?? generate();
19
+ if (echoOnResponse) {
20
+ res.setHeader(REQUEST_ID_HEADER, correlationId);
21
+ }
22
+ withContext({ correlationId }, next);
23
+ };
24
+ }
25
+ // ---------------------------------------------------------------------------
26
+ // Next.js App Router wrapper
27
+ // ---------------------------------------------------------------------------
28
+ /**
29
+ * Next.js App Router route-handler wrapper.
30
+ *
31
+ * Reads the x-request-id header from the standard Request object (first
32
+ * argument to the route handler), wraps the handler in
33
+ * withContext({ correlationId }), and returns the result.
34
+ *
35
+ * Does NOT import from 'next' — uses the standard DOM Request type.
36
+ *
37
+ * @example
38
+ * export const GET = withRequestIdRouteHandler(async (req) => {
39
+ * // getCorrelationId() is available anywhere downstream
40
+ * return Response.json({ ok: true });
41
+ * });
42
+ */
43
+ export function withRequestIdRouteHandler(handler) {
44
+ return ((...args) => {
45
+ // The first argument for Next.js route handlers is the Request object
46
+ const req = args[0];
47
+ let correlationId;
48
+ if (req instanceof Request) {
49
+ correlationId = req.headers.get(REQUEST_ID_HEADER) ?? undefined;
50
+ }
51
+ if (!correlationId) {
52
+ correlationId = generateRequestId();
53
+ }
54
+ return withContext({ correlationId }, () => handler(...args));
55
+ });
56
+ }
57
+ //# sourceMappingURL=request_id_middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request_id_middleware.js","sourceRoot":"","sources":["../../src/http/request_id_middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAUtD;;;;;;;;GAQG;AACH,MAAM,UAAU,yBAAyB,CAAC,IAGzC;IACC,MAAM,QAAQ,GAAG,IAAI,EAAE,QAAQ,IAAI,iBAAiB,CAAC;IACrD,MAAM,cAAc,GAAG,IAAI,EAAE,cAAc,IAAI,IAAI,CAAC;IAEpD,OAAO,CAAC,GAAQ,EAAE,GAAQ,EAAE,IAAU,EAAQ,EAAE;QAC9C,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAChD,MAAM,aAAa,GACjB,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,QAAQ,EAAE,CAAC;QAEnE,IAAI,cAAc,EAAE,CAAC;YACnB,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAC;QAClD,CAAC;QAED,WAAW,CAAC,EAAE,aAAa,EAAE,EAAE,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,6BAA6B;AAC7B,8EAA8E;AAE9E;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,yBAAyB,CAA4C,OAAU;IAC7F,OAAO,CAAC,CAAC,GAAG,IAAe,EAAE,EAAE;QAC7B,sEAAsE;QACtE,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,aAAiC,CAAC;QAEtC,IAAI,GAAG,YAAY,OAAO,EAAE,CAAC;YAC3B,aAAa,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,SAAS,CAAC;QAClE,CAAC;QAED,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,aAAa,GAAG,iBAAiB,EAAE,CAAC;QACtC,CAAC;QAED,OAAO,WAAW,CAAC,EAAE,aAAa,EAAE,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAChE,CAAC,CAAM,CAAC;AACV,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * hazo_core — browser-safe entry point
3
+ *
4
+ * This file must never import node:* modules. It provides the subset of hazo_core
5
+ * that is safe to bundle for browsers.
6
+ *
7
+ * CI enforces the no-node-imports boundary via scripts/audit_client_boundary.js.
8
+ */
9
+ export { REQUEST_ID_HEADER, HAZO_ERROR_SYMBOL, HAZO_SINGLETONS_KEY } from './constants.js';
10
+ export { registerSingleton, getSingleton } from './singleton/index.js';
11
+ export { HazoError, HazoValidationError, HazoAuthError, HazoNotFoundError, HazoConflictError, HazoConfigError, HazoExternalError, HazoRateLimitError, HazoUnavailableError, HazoInternalError, fromZodValidation, fromZodConfig, } from './errors/index.js';
12
+ export type { HazoErrorOptions, HazoValidationErrorOptions, ValidationIssue, HazoAuthErrorOptions, HazoNotFoundErrorOptions, HazoConflictErrorOptions, HazoConfigErrorOptions, HazoExternalErrorOptions, HazoRateLimitErrorOptions, HazoUnavailableErrorOptions, HazoInternalErrorOptions, } from './errors/index.js';
13
+ export { setBrowserCorrelationId, getContext, getCorrelationId, withContext, } from './context/client.js';
14
+ export type { HazoContext } from './context/types.js';
15
+ export { generateRequestId, safeJsonParse, formatBytes, formatDateShort, formatDateLong, formatDateSlash, formatCurrency, formatNumber, formatBoolean, getInitials, } from './utils/index.js';
16
+ //# sourceMappingURL=index.client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.client.d.ts","sourceRoot":"","sources":["../src/index.client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG3F,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGvE,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,GACd,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,gBAAgB,EAChB,0BAA0B,EAC1B,eAAe,EACf,oBAAoB,EACpB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,wBAAwB,EACxB,yBAAyB,EACzB,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,uBAAuB,EACvB,UAAU,EACV,gBAAgB,EAChB,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtD,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,eAAe,EACf,cAAc,EACd,eAAe,EACf,cAAc,EACd,YAAY,EACZ,aAAa,EACb,WAAW,GACZ,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * hazo_core — browser-safe entry point
3
+ *
4
+ * This file must never import node:* modules. It provides the subset of hazo_core
5
+ * that is safe to bundle for browsers.
6
+ *
7
+ * CI enforces the no-node-imports boundary via scripts/audit_client_boundary.js.
8
+ */
9
+ // Constants (no Node deps)
10
+ export { REQUEST_ID_HEADER, HAZO_ERROR_SYMBOL, HAZO_SINGLETONS_KEY } from './constants.js';
11
+ // Singleton registry (no Node deps — uses globalThis)
12
+ export { registerSingleton, getSingleton } from './singleton/index.js';
13
+ // Errors (no Node deps — uses globalThis for correlationId)
14
+ export { HazoError, HazoValidationError, HazoAuthError, HazoNotFoundError, HazoConflictError, HazoConfigError, HazoExternalError, HazoRateLimitError, HazoUnavailableError, HazoInternalError, fromZodValidation, fromZodConfig, } from './errors/index.js';
15
+ // Context (browser — mutable ref, NOT AsyncLocalStorage)
16
+ export { setBrowserCorrelationId, getContext, getCorrelationId, withContext, } from './context/client.js';
17
+ // Safe utils (no Node deps)
18
+ export { generateRequestId, safeJsonParse, formatBytes, formatDateShort, formatDateLong, formatDateSlash, formatCurrency, formatNumber, formatBoolean, getInitials, } from './utils/index.js';
19
+ //# sourceMappingURL=index.client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.client.js","sourceRoot":"","sources":["../src/index.client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,2BAA2B;AAC3B,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE3F,sDAAsD;AACtD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEvE,4DAA4D;AAC5D,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,GACd,MAAM,mBAAmB,CAAC;AAe3B,yDAAyD;AACzD,OAAO,EACL,uBAAuB,EACvB,UAAU,EACV,gBAAgB,EAChB,WAAW,GACZ,MAAM,qBAAqB,CAAC;AAG7B,4BAA4B;AAC5B,OAAO,EACL,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,eAAe,EACf,cAAc,EACd,eAAe,EACf,cAAc,EACd,YAAY,EACZ,aAAa,EACb,WAAW,GACZ,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * hazo_core — server entry point (Node.js)
3
+ *
4
+ * Exports all public API surface. See architecture.md §5 for the public API spec.
5
+ * Browser-safe consumers should use 'hazo_core/client' instead.
6
+ */
7
+ export { REQUEST_ID_HEADER, HAZO_ERROR_SYMBOL, HAZO_SINGLETONS_KEY } from './constants.js';
8
+ export { registerSingleton, getSingleton } from './singleton/index.js';
9
+ export { getCurrentEnv, generateRequestId, optional_import, safeJsonParse, sleep, formatBytes, formatDateShort, formatDateLong, formatDateSlash, formatCurrency, formatNumber, formatBoolean, getInitials, format_date, format_date_range, DEFAULT_DATE_FORMAT, } from './utils/index.js';
10
+ export type { DateFormat } from './utils/index.js';
11
+ export { HazoError, HazoValidationError, HazoAuthError, HazoNotFoundError, HazoConflictError, HazoConfigError, HazoExternalError, HazoRateLimitError, HazoUnavailableError, HazoInternalError, fromZodValidation, fromZodConfig, } from './errors/index.js';
12
+ export type { HazoErrorOptions, HazoValidationErrorOptions, ValidationIssue, HazoAuthErrorOptions, HazoNotFoundErrorOptions, HazoConflictErrorOptions, HazoConfigErrorOptions, HazoExternalErrorOptions, HazoRateLimitErrorOptions, HazoUnavailableErrorOptions, HazoInternalErrorOptions, } from './errors/index.js';
13
+ export { withContext, getContext, getCorrelationId, } from './context/index.js';
14
+ export type { HazoContext } from './context/index.js';
15
+ export { loadConfig, defineConfig, reloadConfig } from './config/index.js';
16
+ export { createLogger } from './logger/index.js';
17
+ export type { HazoCoreLogger } from './logger/index.js';
18
+ export { createDebug } from './debug/index.js';
19
+ export type { HazoCoreDebug } from './debug/index.js';
20
+ export { createRequestIdMiddleware, withRequestIdRouteHandler, } from './http/request_id_middleware.js';
21
+ export { fetchWithRequestId } from './http/fetch_with_request_id.js';
22
+ export { get_origin_url, create_redirect_url } from './http/get_origin_url.js';
23
+ //# sourceMappingURL=index.d.ts.map