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.
- package/README.md +84 -0
- package/SETUP_CHECKLIST.md +114 -0
- package/config/hazo_core_config.ini +14 -0
- package/dist/config/index.d.ts +35 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +117 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/ini_parser.d.ts +10 -0
- package/dist/config/ini_parser.d.ts.map +1 -0
- package/dist/config/ini_parser.js +45 -0
- package/dist/config/ini_parser.js.map +1 -0
- package/dist/constants.d.ts +4 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +4 -0
- package/dist/constants.js.map +1 -0
- package/dist/context/client.d.ts +27 -0
- package/dist/context/client.d.ts.map +1 -0
- package/dist/context/client.js +66 -0
- package/dist/context/client.js.map +1 -0
- package/dist/context/index.d.ts +9 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +8 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/server.d.ts +23 -0
- package/dist/context/server.d.ts.map +1 -0
- package/dist/context/server.js +52 -0
- package/dist/context/server.js.map +1 -0
- package/dist/context/types.d.ts +14 -0
- package/dist/context/types.d.ts.map +1 -0
- package/dist/context/types.js +2 -0
- package/dist/context/types.js.map +1 -0
- package/dist/debug/index.d.ts +20 -0
- package/dist/debug/index.d.ts.map +1 -0
- package/dist/debug/index.js +78 -0
- package/dist/debug/index.js.map +1 -0
- package/dist/errors/auth.d.ts +14 -0
- package/dist/errors/auth.d.ts.map +1 -0
- package/dist/errors/auth.js +19 -0
- package/dist/errors/auth.js.map +1 -0
- package/dist/errors/base.d.ts +89 -0
- package/dist/errors/base.d.ts.map +1 -0
- package/dist/errors/base.js +152 -0
- package/dist/errors/base.js.map +1 -0
- package/dist/errors/config.d.ts +18 -0
- package/dist/errors/config.d.ts.map +1 -0
- package/dist/errors/config.js +14 -0
- package/dist/errors/config.js.map +1 -0
- package/dist/errors/conflict.d.ts +9 -0
- package/dist/errors/conflict.d.ts.map +1 -0
- package/dist/errors/conflict.js +14 -0
- package/dist/errors/conflict.js.map +1 -0
- package/dist/errors/external.d.ts +9 -0
- package/dist/errors/external.d.ts.map +1 -0
- package/dist/errors/external.js +14 -0
- package/dist/errors/external.js.map +1 -0
- package/dist/errors/from_zod.d.ts +33 -0
- package/dist/errors/from_zod.d.ts.map +1 -0
- package/dist/errors/from_zod.js +63 -0
- package/dist/errors/from_zod.js.map +1 -0
- package/dist/errors/index.d.ts +22 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +12 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/errors/internal.d.ts +14 -0
- package/dist/errors/internal.d.ts.map +1 -0
- package/dist/errors/internal.js +14 -0
- package/dist/errors/internal.js.map +1 -0
- package/dist/errors/not_found.d.ts +9 -0
- package/dist/errors/not_found.d.ts.map +1 -0
- package/dist/errors/not_found.js +15 -0
- package/dist/errors/not_found.js.map +1 -0
- package/dist/errors/rate_limit.d.ts +9 -0
- package/dist/errors/rate_limit.d.ts.map +1 -0
- package/dist/errors/rate_limit.js +14 -0
- package/dist/errors/rate_limit.js.map +1 -0
- package/dist/errors/unavailable.d.ts +9 -0
- package/dist/errors/unavailable.d.ts.map +1 -0
- package/dist/errors/unavailable.js +14 -0
- package/dist/errors/unavailable.js.map +1 -0
- package/dist/errors/validation.d.ts +15 -0
- package/dist/errors/validation.d.ts.map +1 -0
- package/dist/errors/validation.js +17 -0
- package/dist/errors/validation.js.map +1 -0
- package/dist/http/fetch_with_request_id.d.ts +14 -0
- package/dist/http/fetch_with_request_id.d.ts.map +1 -0
- package/dist/http/fetch_with_request_id.js +29 -0
- package/dist/http/fetch_with_request_id.js.map +1 -0
- package/dist/http/get_origin_url.d.ts +23 -0
- package/dist/http/get_origin_url.d.ts.map +1 -0
- package/dist/http/get_origin_url.js +61 -0
- package/dist/http/get_origin_url.js.map +1 -0
- package/dist/http/request_id_middleware.d.ts +38 -0
- package/dist/http/request_id_middleware.d.ts.map +1 -0
- package/dist/http/request_id_middleware.js +57 -0
- package/dist/http/request_id_middleware.js.map +1 -0
- package/dist/index.client.d.ts +16 -0
- package/dist/index.client.d.ts.map +1 -0
- package/dist/index.client.js +19 -0
- package/dist/index.client.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/logger/index.d.ts +29 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/logger/index.js +125 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/singleton/index.d.ts +16 -0
- package/dist/singleton/index.d.ts.map +1 -0
- package/dist/singleton/index.js +42 -0
- package/dist/singleton/index.js.map +1 -0
- package/dist/utils/dates.d.ts +45 -0
- package/dist/utils/dates.d.ts.map +1 -0
- package/dist/utils/dates.js +79 -0
- package/dist/utils/dates.js.map +1 -0
- package/dist/utils/env.d.ts +7 -0
- package/dist/utils/env.d.ts.map +1 -0
- package/dist/utils/env.js +9 -0
- package/dist/utils/env.js.map +1 -0
- package/dist/utils/index.d.ts +69 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +174 -0
- package/dist/utils/index.js.map +1 -0
- 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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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
|