@innvoid/getmarket-sdk 0.1.4 → 0.1.6

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 (57) hide show
  1. package/dist/cache/index.js +0 -1
  2. package/dist/chunk-JXOLNJ7J.js +224 -0
  3. package/dist/chunk-JXOLNJ7J.js.map +1 -0
  4. package/dist/chunk-KJ64O2EG.js +19 -0
  5. package/dist/chunk-KJ64O2EG.js.map +1 -0
  6. package/dist/{chunk-GG7EI74E.js → chunk-OSYBK5AN.js} +5 -3
  7. package/dist/chunk-OSYBK5AN.js.map +1 -0
  8. package/dist/chunk-P2U3MT2E.js +39 -0
  9. package/dist/chunk-P2U3MT2E.js.map +1 -0
  10. package/dist/core/index.cjs +4 -2
  11. package/dist/core/index.cjs.map +1 -1
  12. package/dist/core/index.d.cts +1 -2
  13. package/dist/core/index.d.ts +1 -2
  14. package/dist/core/index.js +2 -4
  15. package/dist/express.cjs +19 -0
  16. package/dist/express.cjs.map +1 -0
  17. package/dist/express.d.cts +12 -0
  18. package/dist/express.d.ts +12 -0
  19. package/dist/express.js +1 -0
  20. package/dist/headers/index.cjs +12 -6
  21. package/dist/headers/index.cjs.map +1 -1
  22. package/dist/headers/index.d.cts +3 -18
  23. package/dist/headers/index.d.ts +3 -18
  24. package/dist/headers/index.js +1 -2
  25. package/dist/index.cjs +138 -51
  26. package/dist/index.cjs.map +1 -1
  27. package/dist/index.d.cts +34 -6
  28. package/dist/index.d.ts +34 -6
  29. package/dist/index.js +147 -14
  30. package/dist/index.js.map +1 -1
  31. package/dist/middlewares/index.cjs +133 -35
  32. package/dist/middlewares/index.cjs.map +1 -1
  33. package/dist/middlewares/index.d.cts +43 -14
  34. package/dist/middlewares/index.d.ts +43 -14
  35. package/dist/middlewares/index.js +9 -4
  36. package/dist/parse-C4vk-fmH.d.cts +16 -0
  37. package/dist/parse-C4vk-fmH.d.ts +16 -0
  38. package/dist/types-CRECQuHp.d.cts +54 -0
  39. package/dist/types-CRECQuHp.d.ts +54 -0
  40. package/package.json +6 -1
  41. package/dist/auth/index.cjs +0 -181
  42. package/dist/auth/index.cjs.map +0 -1
  43. package/dist/auth/index.d.cts +0 -3
  44. package/dist/auth/index.d.ts +0 -3
  45. package/dist/auth/index.js +0 -12
  46. package/dist/chunk-65HACONF.js +0 -33
  47. package/dist/chunk-65HACONF.js.map +0 -1
  48. package/dist/chunk-GG7EI74E.js.map +0 -1
  49. package/dist/chunk-PZ5AY32C.js +0 -10
  50. package/dist/chunk-PZ5AY32C.js.map +0 -1
  51. package/dist/chunk-W23UYULS.js +0 -156
  52. package/dist/chunk-W23UYULS.js.map +0 -1
  53. package/dist/chunk-Y2JJLHAY.js +0 -149
  54. package/dist/chunk-Y2JJLHAY.js.map +0 -1
  55. package/dist/index-WbfzvmOt.d.cts +0 -87
  56. package/dist/index-WbfzvmOt.d.ts +0 -87
  57. /package/dist/{auth/index.js.map → express.js.map} +0 -0
@@ -4,7 +4,6 @@ import {
4
4
  getOrSet,
5
5
  getTwoLevelCache
6
6
  } from "../chunk-IYFWQDHD.js";
7
- import "../chunk-PZ5AY32C.js";
8
7
  export {
9
8
  TwoLevelCache,
10
9
  closeCache,
@@ -0,0 +1,224 @@
1
+ import {
2
+ HEADER_INTERNAL_API_KEY,
3
+ getRequestContextFromHeaders
4
+ } from "./chunk-P2U3MT2E.js";
5
+
6
+ // src/middlewares/parseHeaders.ts
7
+ function parseHeaders(req, _res, next) {
8
+ req.context = getRequestContextFromHeaders(req.headers);
9
+ next();
10
+ }
11
+
12
+ // src/middlewares/internalAuth.ts
13
+ import fs from "fs";
14
+ import crypto from "crypto";
15
+
16
+ // src/middlewares/respond.ts
17
+ function sendOk(_req, res, data, statusCode = 200) {
18
+ return res.status(statusCode).json({ ok: true, data, requestId: res.locals?.requestId ?? null });
19
+ }
20
+ function sendError(_req, res, statusCode, code, message, details) {
21
+ return res.status(statusCode).json({
22
+ ok: false,
23
+ error: { code, message, ...details !== void 0 ? { details } : {} },
24
+ requestId: res.locals?.requestId ?? null
25
+ });
26
+ }
27
+
28
+ // src/middlewares/internalAuth.ts
29
+ function readSecretFile(path) {
30
+ if (!path) return null;
31
+ try {
32
+ const v = fs.readFileSync(path, "utf8").trim();
33
+ return v.length ? v : null;
34
+ } catch {
35
+ return null;
36
+ }
37
+ }
38
+ function splitKeys(v) {
39
+ if (!v) return [];
40
+ return v.split(",").map((s) => s.trim()).filter(Boolean);
41
+ }
42
+ function getExpectedKeys() {
43
+ const fileKey = readSecretFile(process.env.INTERNAL_API_KEY_FILE);
44
+ const envKey = (process.env.INTERNAL_API_KEY || "").trim();
45
+ const raw = fileKey || envKey;
46
+ return splitKeys(raw);
47
+ }
48
+ function extractToken(req) {
49
+ const apiKey = (req.header(HEADER_INTERNAL_API_KEY) || "").trim();
50
+ return apiKey || null;
51
+ }
52
+ function safeEquals(a, b) {
53
+ const aa = Buffer.from(a);
54
+ const bb = Buffer.from(b);
55
+ if (aa.length !== bb.length) return false;
56
+ return crypto.timingSafeEqual(aa, bb);
57
+ }
58
+ function internalAuth(req, res, next) {
59
+ const token = extractToken(req);
60
+ if (!token) {
61
+ return sendError(req, res, 401, "UNAUTHORIZED", `Missing internal api key (${HEADER_INTERNAL_API_KEY})`);
62
+ }
63
+ const expectedKeys = getExpectedKeys();
64
+ if (expectedKeys.length === 0) {
65
+ return sendError(
66
+ req,
67
+ res,
68
+ 500,
69
+ "MISCONFIGURED_INTERNAL_AUTH",
70
+ "Internal api key not configured (INTERNAL_API_KEY or INTERNAL_API_KEY_FILE)"
71
+ );
72
+ }
73
+ const ok = expectedKeys.some((k) => safeEquals(token, k));
74
+ if (!ok) {
75
+ return sendError(req, res, 403, "FORBIDDEN", "Invalid internal api key");
76
+ }
77
+ return next();
78
+ }
79
+
80
+ // src/middlewares/authorization.ts
81
+ function getAuth(req) {
82
+ return req.auth ?? {};
83
+ }
84
+ function normalizeCode(v) {
85
+ if (!v) return null;
86
+ if (typeof v === "string") return v;
87
+ if (typeof v === "object") return v.code || v.name || null;
88
+ return null;
89
+ }
90
+ function rolesSet(auth) {
91
+ const out = /* @__PURE__ */ new Set();
92
+ for (const r of auth.roles || []) {
93
+ const c = normalizeCode(r);
94
+ if (c) out.add(c);
95
+ }
96
+ return out;
97
+ }
98
+ function permsSet(list) {
99
+ const out = /* @__PURE__ */ new Set();
100
+ for (const p of list || []) {
101
+ const c = normalizeCode(p);
102
+ if (c) out.add(c);
103
+ }
104
+ return out;
105
+ }
106
+ function requireAuthContext() {
107
+ return (req, res, next) => {
108
+ if (!req.auth) {
109
+ return sendError(req, res, 401, "UNAUTHORIZED", "Missing auth context");
110
+ }
111
+ return next();
112
+ };
113
+ }
114
+ function isSysAdmin(auth, sysAdminRole) {
115
+ const have = rolesSet(auth);
116
+ return have.has(sysAdminRole);
117
+ }
118
+ function requirePermissions(perms, options) {
119
+ const sysAdminBypass = options?.sysAdminBypass !== false;
120
+ const sysAdminRole = options?.sysAdminRole || "SYS_ADMIN";
121
+ return (req, res, next) => {
122
+ const auth = getAuth(req);
123
+ if (sysAdminBypass && isSysAdmin(auth, sysAdminRole)) return next();
124
+ const allow = permsSet(auth.permissions);
125
+ const deny = permsSet(auth.denied_permissions);
126
+ for (const p of perms) {
127
+ if (deny.has(p)) {
128
+ return sendError(req, res, 403, "FORBIDDEN", `Denied permission: ${p}`, {
129
+ denied: p
130
+ });
131
+ }
132
+ }
133
+ const missing = perms.filter((p) => !allow.has(p));
134
+ if (missing.length) {
135
+ return sendError(req, res, 403, "FORBIDDEN", "Missing permissions", {
136
+ missing,
137
+ mode: "ALL"
138
+ });
139
+ }
140
+ return next();
141
+ };
142
+ }
143
+ function requireAnyPermission(perms, options) {
144
+ const sysAdminBypass = options?.sysAdminBypass !== false;
145
+ const sysAdminRole = options?.sysAdminRole || "SYS_ADMIN";
146
+ return (req, res, next) => {
147
+ const auth = getAuth(req);
148
+ if (sysAdminBypass && isSysAdmin(auth, sysAdminRole)) return next();
149
+ const allow = permsSet(auth.permissions);
150
+ const deny = permsSet(auth.denied_permissions);
151
+ for (const p of perms) {
152
+ if (deny.has(p)) {
153
+ return sendError(req, res, 403, "FORBIDDEN", `Denied permission: ${p}`, {
154
+ denied: p
155
+ });
156
+ }
157
+ }
158
+ const ok = perms.some((p) => allow.has(p));
159
+ if (!ok) {
160
+ return sendError(req, res, 403, "FORBIDDEN", "Permission denied", {
161
+ required: perms,
162
+ mode: "ANY"
163
+ });
164
+ }
165
+ return next();
166
+ };
167
+ }
168
+ function requireRoles(roles, options) {
169
+ const sysAdminBypass = options?.sysAdminBypass !== false;
170
+ const sysAdminRole = options?.sysAdminRole || "SYS_ADMIN";
171
+ return (req, res, next) => {
172
+ const auth = getAuth(req);
173
+ if (sysAdminBypass && isSysAdmin(auth, sysAdminRole)) return next();
174
+ const have = rolesSet(auth);
175
+ if (!roles.some((r) => have.has(r))) {
176
+ return sendError(req, res, 403, "FORBIDDEN", "Role not allowed", {
177
+ required: roles,
178
+ mode: "ANY"
179
+ });
180
+ }
181
+ return next();
182
+ };
183
+ }
184
+ function requireRolesOrAnyPermission(roles, perms, options) {
185
+ const sysAdminBypass = options?.sysAdminBypass !== false;
186
+ const sysAdminRole = options?.sysAdminRole || "SYS_ADMIN";
187
+ return (req, res, next) => {
188
+ const auth = getAuth(req);
189
+ if (sysAdminBypass && isSysAdmin(auth, sysAdminRole)) return next();
190
+ const haveRoles = rolesSet(auth);
191
+ const allow = permsSet(auth.permissions);
192
+ const deny = permsSet(auth.denied_permissions);
193
+ for (const p of perms) {
194
+ if (deny.has(p)) {
195
+ return sendError(req, res, 403, "FORBIDDEN", `Denied permission: ${p}`, {
196
+ denied: p
197
+ });
198
+ }
199
+ }
200
+ const okRole = roles.some((r) => haveRoles.has(r));
201
+ const okPerm = perms.some((p) => allow.has(p));
202
+ if (!okRole && !okPerm) {
203
+ return sendError(req, res, 403, "FORBIDDEN", "Access denied", {
204
+ roles,
205
+ permissions: perms,
206
+ mode: "ROLES_OR_PERMS_ANY"
207
+ });
208
+ }
209
+ return next();
210
+ };
211
+ }
212
+
213
+ export {
214
+ parseHeaders,
215
+ sendOk,
216
+ sendError,
217
+ internalAuth,
218
+ requireAuthContext,
219
+ requirePermissions,
220
+ requireAnyPermission,
221
+ requireRoles,
222
+ requireRolesOrAnyPermission
223
+ };
224
+ //# sourceMappingURL=chunk-JXOLNJ7J.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/middlewares/parseHeaders.ts","../src/middlewares/internalAuth.ts","../src/middlewares/respond.ts","../src/middlewares/authorization.ts"],"sourcesContent":["// sdk/src/middlewares/parseHeaders.ts\nimport type {Request, Response, NextFunction} from \"express\";\nimport {getRequestContextFromHeaders} from \"../headers\";\n\n/**\n * ✅ NO-LEGACY / ESTÁNDAR:\n * - Lee SOLO x-company y x-branch (UIDs planos)\n * - Setea req.context = { company_uid, branch_uid }\n * - NO toca req.auth (auth lo setea authentication/requireAuth)\n */\nexport default function parseHeaders(req: Request, _res: Response, next: NextFunction) {\n (req as any).context = getRequestContextFromHeaders(req.headers as any);\n next();\n}\n","import type {Request, Response, NextFunction} from \"express\";\nimport fs from \"fs\";\nimport crypto from \"crypto\";\nimport {sendError} from \"./respond\";\nimport {HEADER_INTERNAL_API_KEY} from \"../headers\";\n\nfunction readSecretFile(path?: string): string | null {\n if (!path) return null;\n try {\n const v = fs.readFileSync(path, \"utf8\").trim();\n return v.length ? v : null;\n } catch {\n return null;\n }\n}\n\nfunction splitKeys(v?: string | null): string[] {\n if (!v) return [];\n return v.split(\",\").map((s) => s.trim()).filter(Boolean);\n}\n\nfunction getExpectedKeys(): string[] {\n const fileKey = readSecretFile(process.env.INTERNAL_API_KEY_FILE);\n const envKey = (process.env.INTERNAL_API_KEY || \"\").trim();\n const raw = fileKey || envKey;\n return splitKeys(raw);\n}\n\nfunction extractToken(req: Request): string | null {\n const apiKey = (req.header(HEADER_INTERNAL_API_KEY) || \"\").trim();\n return apiKey || null;\n}\n\nfunction safeEquals(a: string, b: string): boolean {\n const aa = Buffer.from(a);\n const bb = Buffer.from(b);\n if (aa.length !== bb.length) return false;\n return crypto.timingSafeEqual(aa, bb);\n}\n\nexport default function internalAuth(req: Request, res: Response, next: NextFunction) {\n const token = extractToken(req);\n\n if (!token) {\n return sendError(req, res, 401, \"UNAUTHORIZED\", `Missing internal api key (${HEADER_INTERNAL_API_KEY})`);\n }\n\n const expectedKeys = getExpectedKeys();\n if (expectedKeys.length === 0) {\n return sendError(\n req,\n res,\n 500,\n \"MISCONFIGURED_INTERNAL_AUTH\",\n \"Internal api key not configured (INTERNAL_API_KEY or INTERNAL_API_KEY_FILE)\"\n );\n }\n\n const ok = expectedKeys.some((k) => safeEquals(token, k));\n if (!ok) {\n return sendError(req, res, 403, \"FORBIDDEN\", \"Invalid internal api key\");\n }\n\n return next();\n}\n","import type {Request, Response} from \"express\";\n\nexport function sendOk<T>(_req: Request, res: Response, data: T, statusCode = 200) {\n return res.status(statusCode).json({ok: true, data, requestId: res.locals?.requestId ?? null});\n}\n\nexport function sendError(\n _req: Request,\n res: Response,\n statusCode: number,\n code: string,\n message: string,\n details?: any\n) {\n return res.status(statusCode).json({\n ok: false,\n error: {code, message, ...(details !== undefined ? {details} : {})},\n requestId: res.locals?.requestId ?? null,\n });\n}\n","// packages/sdk/src/middlewares/authorization.ts\nimport type {Request, Response, NextFunction} from \"express\";\nimport {sendError} from \"./respond\";\n\ntype AuthRole = string | { code?: string; name?: string };\ntype AuthPermission = string | { code?: string; name?: string };\n\ntype AuthShape = {\n roles?: AuthRole[];\n permissions?: AuthPermission[];\n denied_permissions?: AuthPermission[];\n};\n\nfunction getAuth(req: Request): AuthShape {\n return ((req as any).auth ?? {}) as AuthShape;\n}\n\nfunction normalizeCode(v: any): string | null {\n if (!v) return null;\n if (typeof v === \"string\") return v;\n if (typeof v === \"object\") return v.code || v.name || null;\n return null;\n}\n\nfunction rolesSet(auth: AuthShape): Set<string> {\n const out = new Set<string>();\n for (const r of auth.roles || []) {\n const c = normalizeCode(r);\n if (c) out.add(c);\n }\n return out;\n}\n\nfunction permsSet(list?: AuthPermission[]): Set<string> {\n const out = new Set<string>();\n for (const p of list || []) {\n const c = normalizeCode(p);\n if (c) out.add(c);\n }\n return out;\n}\n\n/**\n * 401 si no existe req.auth (contexto auth).\n * Útil para proteger rutas donde SIEMPRE debe existir auth.\n */\nexport function requireAuthContext() {\n return (req: Request, res: Response, next: NextFunction) => {\n if (!(req as any).auth) {\n return sendError(req, res, 401, \"UNAUTHORIZED\", \"Missing auth context\");\n }\n return next();\n };\n}\n\n/**\n * Helper: SYS_ADMIN bypass (por defecto activo)\n */\nfunction isSysAdmin(auth: AuthShape, sysAdminRole: string) {\n const have = rolesSet(auth);\n return have.has(sysAdminRole);\n}\n\n/**\n * Requiere TODOS los permisos indicados.\n * Regla: denied_permissions siempre gana sobre permissions.\n *\n * options:\n * - sysAdminBypass: default true\n * - sysAdminRole: default \"SYS_ADMIN\"\n */\nexport function requirePermissions(\n perms: string[],\n options?: { sysAdminBypass?: boolean; sysAdminRole?: string }\n) {\n const sysAdminBypass = options?.sysAdminBypass !== false;\n const sysAdminRole = options?.sysAdminRole || \"SYS_ADMIN\";\n\n return (req: Request, res: Response, next: NextFunction) => {\n const auth = getAuth(req);\n\n if (sysAdminBypass && isSysAdmin(auth, sysAdminRole)) return next();\n\n const allow = permsSet(auth.permissions);\n const deny = permsSet(auth.denied_permissions);\n\n // deny gana siempre\n for (const p of perms) {\n if (deny.has(p)) {\n return sendError(req, res, 403, \"FORBIDDEN\", `Denied permission: ${p}`, {\n denied: p,\n });\n }\n }\n\n const missing = perms.filter((p) => !allow.has(p));\n if (missing.length) {\n return sendError(req, res, 403, \"FORBIDDEN\", \"Missing permissions\", {\n missing,\n mode: \"ALL\",\n });\n }\n\n return next();\n };\n}\n\n/**\n * Requiere AL MENOS 1 permiso de la lista (ANY/OR).\n * Regla: denied_permissions siempre gana.\n */\nexport function requireAnyPermission(\n perms: string[],\n options?: { sysAdminBypass?: boolean; sysAdminRole?: string }\n) {\n const sysAdminBypass = options?.sysAdminBypass !== false;\n const sysAdminRole = options?.sysAdminRole || \"SYS_ADMIN\";\n\n return (req: Request, res: Response, next: NextFunction) => {\n const auth = getAuth(req);\n\n if (sysAdminBypass && isSysAdmin(auth, sysAdminRole)) return next();\n\n const allow = permsSet(auth.permissions);\n const deny = permsSet(auth.denied_permissions);\n\n // deny gana siempre (si alguno requerido está denegado explícitamente)\n for (const p of perms) {\n if (deny.has(p)) {\n return sendError(req, res, 403, \"FORBIDDEN\", `Denied permission: ${p}`, {\n denied: p,\n });\n }\n }\n\n const ok = perms.some((p) => allow.has(p));\n if (!ok) {\n return sendError(req, res, 403, \"FORBIDDEN\", \"Permission denied\", {\n required: perms,\n mode: \"ANY\",\n });\n }\n\n return next();\n };\n}\n\n/**\n * Requiere al menos 1 rol (ANY/OR).\n * options:\n * - sysAdminBypass: default true\n * - sysAdminRole: default \"SYS_ADMIN\"\n */\nexport function requireRoles(\n roles: string[],\n options?: { sysAdminBypass?: boolean; sysAdminRole?: string }\n) {\n const sysAdminBypass = options?.sysAdminBypass !== false;\n const sysAdminRole = options?.sysAdminRole || \"SYS_ADMIN\";\n\n return (req: Request, res: Response, next: NextFunction) => {\n const auth = getAuth(req);\n\n // SYS_ADMIN bypass aplica también aquí\n if (sysAdminBypass && isSysAdmin(auth, sysAdminRole)) return next();\n\n const have = rolesSet(auth);\n if (!roles.some((r) => have.has(r))) {\n return sendError(req, res, 403, \"FORBIDDEN\", \"Role not allowed\", {\n required: roles,\n mode: \"ANY\",\n });\n }\n\n return next();\n };\n}\n\n/**\n * Requiere (roles ANY) OR (permissions ANY).\n * deny_permissions siempre gana sobre permissions.\n */\nexport function requireRolesOrAnyPermission(\n roles: string[],\n perms: string[],\n options?: { sysAdminBypass?: boolean; sysAdminRole?: string }\n) {\n const sysAdminBypass = options?.sysAdminBypass !== false;\n const sysAdminRole = options?.sysAdminRole || \"SYS_ADMIN\";\n\n return (req: Request, res: Response, next: NextFunction) => {\n const auth = getAuth(req);\n\n if (sysAdminBypass && isSysAdmin(auth, sysAdminRole)) return next();\n\n const haveRoles = rolesSet(auth);\n const allow = permsSet(auth.permissions);\n const deny = permsSet(auth.denied_permissions);\n\n // deny gana siempre (si cualquiera de los permisos evaluados está denegado explícitamente)\n for (const p of perms) {\n if (deny.has(p)) {\n return sendError(req, res, 403, \"FORBIDDEN\", `Denied permission: ${p}`, {\n denied: p,\n });\n }\n }\n\n const okRole = roles.some((r) => haveRoles.has(r));\n const okPerm = perms.some((p) => allow.has(p));\n\n if (!okRole && !okPerm) {\n return sendError(req, res, 403, \"FORBIDDEN\", \"Access denied\", {\n roles,\n permissions: perms,\n mode: \"ROLES_OR_PERMS_ANY\",\n });\n }\n\n return next();\n };\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,19 @@
1
+ // src/middlewares/requestId.ts
2
+ import { randomUUID, randomBytes } from "crypto";
3
+ var REQUEST_ID_HEADER = "x-request-id";
4
+ var REQUEST_ID_HEADER_ALT = "x-requestid";
5
+ var RESPONSE_REQUEST_ID_HEADER = "X-Request-Id";
6
+ function requestId(req, res, next) {
7
+ const headerId = req.headers[REQUEST_ID_HEADER] || req.headers[REQUEST_ID_HEADER_ALT];
8
+ const id = headerId?.trim() || randomUUID();
9
+ req.requestId = id;
10
+ res.locals.requestId = id;
11
+ res.setHeader(RESPONSE_REQUEST_ID_HEADER, id);
12
+ next();
13
+ }
14
+
15
+ export {
16
+ REQUEST_ID_HEADER,
17
+ requestId
18
+ };
19
+ //# sourceMappingURL=chunk-KJ64O2EG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/middlewares/requestId.ts"],"sourcesContent":["// middlewares/requestId.ts\nimport type {Request, Response, NextFunction} from \"express\";\nimport {randomUUID, randomBytes} from \"crypto\";\n\nexport const REQUEST_ID_HEADER = \"x-request-id\";\nexport const REQUEST_ID_HEADER_ALT = \"x-requestid\";\nexport const RESPONSE_REQUEST_ID_HEADER = \"X-Request-Id\";\n\n// Si quieres IDs más cortos (opcional). Por defecto usamos UUID.\nfunction nanoidLike(len = 21) {\n return randomBytes(16).toString(\"base64url\").slice(0, len);\n}\n\nexport default function requestId(req: Request, res: Response, next: NextFunction) {\n const headerId = (req.headers[REQUEST_ID_HEADER] || req.headers[REQUEST_ID_HEADER_ALT]) as\n | string\n | undefined;\n\n // ✅ estándar único: usa UUID (o cambia a nanoidLike() si prefieres corto)\n const id = headerId?.trim() || randomUUID();\n\n // ✅ estándar único (no legacy)\n (req as any).requestId = id;\n res.locals.requestId = id;\n\n // ✅ respuesta\n res.setHeader(RESPONSE_REQUEST_ID_HEADER, id);\n\n next();\n}\n"],"mappings":";AAEA,SAAQ,YAAY,mBAAkB;AAE/B,IAAM,oBAAoB;AAC1B,IAAM,wBAAwB;AAC9B,IAAM,6BAA6B;AAO3B,SAAR,UAA2B,KAAc,KAAe,MAAoB;AAC/E,QAAM,WAAY,IAAI,QAAQ,iBAAiB,KAAK,IAAI,QAAQ,qBAAqB;AAKrF,QAAM,KAAK,UAAU,KAAK,KAAK,WAAW;AAG1C,EAAC,IAAY,YAAY;AACzB,MAAI,OAAO,YAAY;AAGvB,MAAI,UAAU,4BAA4B,EAAE;AAE5C,OAAK;AACT;","names":[]}
@@ -1,3 +1,7 @@
1
+ import {
2
+ REQUEST_ID_HEADER
3
+ } from "./chunk-KJ64O2EG.js";
4
+
1
5
  // src/core/errors.ts
2
6
  var UpstreamError = class extends Error {
3
7
  code;
@@ -32,7 +36,6 @@ function mapAxiosToUpstreamError(err, svc) {
32
36
 
33
37
  // src/core/http.ts
34
38
  import axios from "axios";
35
- var REQUEST_ID_HEADER = "x-request-id";
36
39
  function withRequestId(headers, requestId) {
37
40
  const h = headers && typeof headers === "object" ? { ...headers } : {};
38
41
  const rid = (requestId || "").trim();
@@ -160,10 +163,9 @@ var InternalHttp = class {
160
163
  export {
161
164
  UpstreamError,
162
165
  mapAxiosToUpstreamError,
163
- REQUEST_ID_HEADER,
164
166
  withRequestId,
165
167
  withRequestIdConfig,
166
168
  createHttpClient,
167
169
  InternalHttp
168
170
  };
169
- //# sourceMappingURL=chunk-GG7EI74E.js.map
171
+ //# sourceMappingURL=chunk-OSYBK5AN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/errors.ts","../src/core/http.ts","../src/core/internalHttp.ts"],"sourcesContent":["export type ClientErrorCode =\n | \"UPSTREAM_TIMEOUT\"\n | \"UPSTREAM_UNAVAILABLE\"\n | \"UPSTREAM_BAD_RESPONSE\"\n | \"UPSTREAM_NOT_FOUND\"\n | \"UPSTREAM_UNAUTHORIZED\"\n | \"UPSTREAM_FORBIDDEN\"\n | \"UPSTREAM_UNKNOWN\";\n\nexport class UpstreamError extends Error {\n public code: ClientErrorCode;\n public status?: number;\n public details?: any;\n\n constructor(message: string, code: ClientErrorCode, status?: number, details?: any) {\n super(message);\n this.name = \"UpstreamError\";\n this.code = code;\n this.status = status;\n this.details = details;\n }\n}\n\nexport function mapAxiosToUpstreamError(err: any, svc: string): UpstreamError {\n const status = err?.response?.status;\n const data = err?.response?.data;\n const isTimeout = err?.code === \"ECONNABORTED\" || String(err?.message || \"\").includes(\"timeout\");\n\n if (isTimeout) {\n return new UpstreamError(`[${svc}] timeout`, \"UPSTREAM_TIMEOUT\", 504, {cause: err?.message});\n }\n if (!err?.response) {\n return new UpstreamError(`[${svc}] unavailable`, \"UPSTREAM_UNAVAILABLE\", 503, {cause: err?.message});\n }\n if (status === 404) return new UpstreamError(`[${svc}] not found`, \"UPSTREAM_NOT_FOUND\", 404, data);\n if (status === 401) return new UpstreamError(`[${svc}] unauthorized`, \"UPSTREAM_UNAUTHORIZED\", 401, data);\n if (status === 403) return new UpstreamError(`[${svc}] forbidden`, \"UPSTREAM_FORBIDDEN\", 403, data);\n if (status >= 400 && status < 600) {\n return new UpstreamError(`[${svc}] bad response`, \"UPSTREAM_BAD_RESPONSE\", status, data);\n }\n return new UpstreamError(`[${svc}] unknown error`, \"UPSTREAM_UNKNOWN\", status, data);\n}\n","// packages/sdk/src/core/http.ts\nimport axios, {AxiosInstance, AxiosRequestConfig} from \"axios\";\nimport {REQUEST_ID_HEADER} from \"../middlewares/requestId\";\n\nexport type HttpClientOpts = {\n baseURL: string;\n timeoutMs?: number;\n};\n\n/**\n * Headers compatibles con múltiples versiones de axios.\n * En axios antiguo, `headers` suele ser `any`, así que mantenemos tolerancia.\n */\nexport type AnyHeaders = NonNullable<AxiosRequestConfig[\"headers\"]> | Record<string, string>;\n\n/**\n * Agrega x-request-id a headers (sin pisar otros headers).\n */\nexport function withRequestId(headers: AnyHeaders | undefined, requestId?: string | null): AnyHeaders {\n const h: Record<string, any> =\n headers && typeof headers === \"object\"\n ? {...(headers as any)}\n : {};\n\n const rid = (requestId || \"\").trim();\n if (rid) h[REQUEST_ID_HEADER] = rid;\n\n return h as AnyHeaders;\n}\n\n/**\n * Helper para construir config de axios con requestId\n * (SIN genéricos para compat con axios typings antiguos).\n */\nexport function withRequestIdConfig(\n config: AxiosRequestConfig = {},\n requestId?: string | null\n): AxiosRequestConfig {\n return {\n ...config,\n headers: withRequestId((config as any).headers, requestId) as any,\n };\n}\n\nexport function createHttpClient(opts: HttpClientOpts): AxiosInstance {\n return axios.create({\n baseURL: opts.baseURL,\n timeout: opts.timeoutMs ?? 4000,\n headers: {\"Content-Type\": \"application/json\"},\n });\n}\n","// clients/internalHttp.ts\n\ntype RetryPolicy = {\n retries: number;\n baseDelayMs: number;\n retryOnStatuses: number[];\n retryOnNetworkErrors: boolean;\n};\n\ntype InternalHttpOptions = {\n baseUrl: string;\n apiKey?: string; // x-internal-api-key\n timeoutMs?: number;\n retry?: Partial<RetryPolicy>;\n};\n\nconst DEFAULT_RETRY: RetryPolicy = {\n retries: 1,\n baseDelayMs: 150,\n retryOnStatuses: [429, 502, 503, 504],\n retryOnNetworkErrors: true,\n};\n\nfunction sleep(ms: number) {\n return new Promise((r) => setTimeout(r, ms));\n}\n\nfunction safeJsonStringify(v: any) {\n try {\n return JSON.stringify(v);\n } catch {\n return String(v);\n }\n}\n\nfunction toHeaders(init?: HeadersInit): Headers {\n return new Headers(init || {});\n}\n\nfunction isJsonContentType(contentType: string | null): boolean {\n if (!contentType) return false;\n const ct = contentType.toLowerCase();\n return ct.includes(\"application/json\") || ct.includes(\"+json\");\n}\n\nfunction isAbortError(e: any): boolean {\n return e?.name === \"AbortError\";\n}\n\nfunction withJitter(ms: number): number {\n // jitter +-20%\n const jitter = ms * 0.2;\n const delta = (Math.random() * 2 - 1) * jitter;\n return Math.max(0, Math.floor(ms + delta));\n}\n\nexport class InternalHttp {\n private readonly baseUrl: string;\n private readonly apiKey: string | undefined;\n private readonly timeoutMs: number;\n private retry: RetryPolicy;\n\n constructor(opts: InternalHttpOptions) {\n this.baseUrl = opts.baseUrl.replace(/\\/+$/, \"\");\n this.apiKey = opts.apiKey;\n\n // ✅ Default más seguro para internas (evita cascadas)\n this.timeoutMs = opts.timeoutMs ?? 4000;\n\n this.retry = {...DEFAULT_RETRY, ...(opts.retry || {})};\n }\n\n async request<T>(\n path: string,\n init: RequestInit & {\n requestId?: string;\n idempotencyKey?: string;\n headers?: HeadersInit;\n } = {}\n ): Promise<T> {\n const url = `${this.baseUrl}${path.startsWith(\"/\") ? \"\" : \"/\"}${path}`;\n\n const baseHeaders = toHeaders(init.headers);\n\n if (!baseHeaders.has(\"Content-Type\")) baseHeaders.set(\"Content-Type\", \"application/json\");\n if (this.apiKey) baseHeaders.set(\"x-internal-api-key\", this.apiKey);\n\n if (init.requestId) baseHeaders.set(\"x-request-id\", init.requestId);\n if (init.idempotencyKey) baseHeaders.set(\"Idempotency-Key\", init.idempotencyKey);\n\n const {headers: _ignored, ...restInit} = init;\n\n const doFetchOnce = async () => {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.timeoutMs);\n\n try {\n const res = await fetch(url, {\n ...restInit,\n headers: baseHeaders,\n signal: controller.signal,\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n const err: any = new Error(\n `HTTP ${res.status} ${res.statusText}${text ? ` - ${text}` : \"\"}`\n );\n err.status = res.status;\n err.body = text;\n throw err;\n }\n\n if (res.status === 204) return undefined as unknown as T;\n\n const contentType = res.headers.get(\"content-type\");\n if (isJsonContentType(contentType)) {\n return (await res.json()) as T;\n }\n\n const text = await res.text().catch(() => \"\");\n return text as unknown as T;\n } finally {\n clearTimeout(timeout);\n }\n };\n\n let attempt = 0;\n\n while (true) {\n try {\n return await doFetchOnce();\n } catch (e: any) {\n attempt++;\n\n const status = e?.status;\n const retryableStatus = !!status && this.retry.retryOnStatuses.includes(status);\n\n const retryableNetwork =\n this.retry.retryOnNetworkErrors &&\n (isAbortError(e) || !status); // sin status suele ser red/dns/timeout\n\n const isRetryable = retryableStatus || retryableNetwork;\n\n if (!isRetryable || attempt > this.retry.retries) {\n console.error(\n `[InternalHttp] request failed: ${url} attempt=${attempt} status=${status ?? \"n/a\"} err=${e?.message\n } body=${safeJsonStringify(e?.body)}`\n );\n throw e;\n }\n\n const backoff = withJitter(this.retry.baseDelayMs * attempt);\n await sleep(backoff);\n }\n }\n }\n}\n"],"mappings":"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","names":["text"]}
@@ -0,0 +1,39 @@
1
+ // src/headers/constants.ts
2
+ var HEADER_REQUEST_ID = "x-request-id";
3
+ var HEADER_COMPANY_UID = "x-company";
4
+ var HEADER_BRANCH_UID = "x-branch";
5
+ var HEADER_EMPLOYEE_UID = "x-employee-uid";
6
+ var HEADER_INTERNAL_API_KEY = "x-internal-api-key";
7
+ var HEADER_AUTHORIZATION = "authorization";
8
+
9
+ // src/headers/parse.ts
10
+ function normalizeHeaderValue(v) {
11
+ if (typeof v !== "string") return null;
12
+ const s = v.trim();
13
+ if (!s) return null;
14
+ if (s.startsWith("{") || s.startsWith("[") || s.includes('"')) return null;
15
+ if (s.length < 6) return null;
16
+ return s;
17
+ }
18
+ function h(headers, key) {
19
+ return headers[key] ?? headers[key.toLowerCase()] ?? headers[key.toUpperCase()];
20
+ }
21
+ function getRequestContextFromHeaders(headers) {
22
+ return {
23
+ requestId: normalizeHeaderValue(h(headers, HEADER_REQUEST_ID)) ?? null,
24
+ company_uid: normalizeHeaderValue(h(headers, HEADER_COMPANY_UID)) ?? null,
25
+ branch_uid: normalizeHeaderValue(h(headers, HEADER_BRANCH_UID)) ?? null,
26
+ employee_uid: normalizeHeaderValue(h(headers, HEADER_EMPLOYEE_UID)) ?? null
27
+ };
28
+ }
29
+
30
+ export {
31
+ HEADER_REQUEST_ID,
32
+ HEADER_COMPANY_UID,
33
+ HEADER_BRANCH_UID,
34
+ HEADER_EMPLOYEE_UID,
35
+ HEADER_INTERNAL_API_KEY,
36
+ HEADER_AUTHORIZATION,
37
+ getRequestContextFromHeaders
38
+ };
39
+ //# sourceMappingURL=chunk-P2U3MT2E.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/headers/constants.ts","../src/headers/parse.ts"],"sourcesContent":["export const HEADER_REQUEST_ID = \"x-request-id\";\n\nexport const HEADER_COMPANY_UID = \"x-company\";\nexport const HEADER_BRANCH_UID = \"x-branch\";\nexport const HEADER_EMPLOYEE_UID = \"x-employee-uid\";\n\nexport const HEADER_INTERNAL_API_KEY = \"x-internal-api-key\";\nexport const HEADER_AUTHORIZATION = \"authorization\";\n","import {\n HEADER_BRANCH_UID,\n HEADER_COMPANY_UID,\n HEADER_EMPLOYEE_UID,\n HEADER_REQUEST_ID,\n} from \"./constants\";\n\nexport type RequestContext = {\n requestId?: string | null;\n company_uid?: string | null;\n branch_uid?: string | null;\n employee_uid?: string | null;\n};\n\nfunction normalizeHeaderValue(v: unknown): string | null {\n if (typeof v !== \"string\") return null;\n const s = v.trim();\n if (!s) return null;\n\n // ✅ NO-LEGACY: bloquea JSON en headers\n if (s.startsWith(\"{\") || s.startsWith(\"[\") || s.includes('\"')) return null;\n\n // Evitar valores demasiado cortos (basura)\n if (s.length < 6) return null;\n\n return s;\n}\n\n/**\n * Lee header aunque venga en mayúsculas/minúsculas (Express suele bajar a lower-case).\n */\nfunction h(headers: Record<string, any>, key: string): unknown {\n return headers[key] ?? headers[key.toLowerCase()] ?? headers[key.toUpperCase()];\n}\n\n/**\n * ✅ NO-LEGACY:\n * - x-company: <UID>\n * - x-branch: <UID>\n * - x-employee-uid: <UID> (opcional; NO reemplaza JWT)\n * - x-request-id: string (opcional)\n */\nexport function getRequestContextFromHeaders(headers: Record<string, any>): RequestContext {\n return {\n requestId: normalizeHeaderValue(h(headers, HEADER_REQUEST_ID)) ?? null,\n company_uid: normalizeHeaderValue(h(headers, HEADER_COMPANY_UID)) ?? null,\n branch_uid: normalizeHeaderValue(h(headers, HEADER_BRANCH_UID)) ?? null,\n employee_uid: normalizeHeaderValue(h(headers, HEADER_EMPLOYEE_UID)) ?? null,\n };\n}\n"],"mappings":";AAAO,IAAM,oBAAoB;AAE1B,IAAM,qBAAqB;AAC3B,IAAM,oBAAoB;AAC1B,IAAM,sBAAsB;AAE5B,IAAM,0BAA0B;AAChC,IAAM,uBAAuB;;;ACOpC,SAAS,qBAAqB,GAA2B;AACrD,MAAI,OAAO,MAAM,SAAU,QAAO;AAClC,QAAM,IAAI,EAAE,KAAK;AACjB,MAAI,CAAC,EAAG,QAAO;AAGf,MAAI,EAAE,WAAW,GAAG,KAAK,EAAE,WAAW,GAAG,KAAK,EAAE,SAAS,GAAG,EAAG,QAAO;AAGtE,MAAI,EAAE,SAAS,EAAG,QAAO;AAEzB,SAAO;AACX;AAKA,SAAS,EAAE,SAA8B,KAAsB;AAC3D,SAAO,QAAQ,GAAG,KAAK,QAAQ,IAAI,YAAY,CAAC,KAAK,QAAQ,IAAI,YAAY,CAAC;AAClF;AASO,SAAS,6BAA6B,SAA8C;AACvF,SAAO;AAAA,IACH,WAAW,qBAAqB,EAAE,SAAS,iBAAiB,CAAC,KAAK;AAAA,IAClE,aAAa,qBAAqB,EAAE,SAAS,kBAAkB,CAAC,KAAK;AAAA,IACrE,YAAY,qBAAqB,EAAE,SAAS,iBAAiB,CAAC,KAAK;AAAA,IACnE,cAAc,qBAAqB,EAAE,SAAS,mBAAmB,CAAC,KAAK;AAAA,EAC3E;AACJ;","names":[]}
@@ -31,7 +31,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var core_exports = {};
32
32
  __export(core_exports, {
33
33
  InternalHttp: () => InternalHttp,
34
- REQUEST_ID_HEADER: () => REQUEST_ID_HEADER,
35
34
  UpstreamError: () => UpstreamError,
36
35
  createHttpClient: () => createHttpClient,
37
36
  mapAxiosToUpstreamError: () => mapAxiosToUpstreamError,
@@ -74,7 +73,11 @@ function mapAxiosToUpstreamError(err, svc) {
74
73
 
75
74
  // src/core/http.ts
76
75
  var import_axios = __toESM(require("axios"), 1);
76
+
77
+ // src/middlewares/requestId.ts
77
78
  var REQUEST_ID_HEADER = "x-request-id";
79
+
80
+ // src/core/http.ts
78
81
  function withRequestId(headers, requestId) {
79
82
  const h = headers && typeof headers === "object" ? { ...headers } : {};
80
83
  const rid = (requestId || "").trim();
@@ -201,7 +204,6 @@ var InternalHttp = class {
201
204
  // Annotate the CommonJS export names for ESM import in node:
202
205
  0 && (module.exports = {
203
206
  InternalHttp,
204
- REQUEST_ID_HEADER,
205
207
  UpstreamError,
206
208
  createHttpClient,
207
209
  mapAxiosToUpstreamError,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/core/index.ts","../../src/core/errors.ts","../../src/core/http.ts","../../src/core/internalHttp.ts"],"sourcesContent":["// sdk/src/core/index.ts\n\nexport * from \"./errors\";\nexport * from \"./http\";\nexport * from \"./internalHttp\";\n","export type ClientErrorCode =\n | \"UPSTREAM_TIMEOUT\"\n | \"UPSTREAM_UNAVAILABLE\"\n | \"UPSTREAM_BAD_RESPONSE\"\n | \"UPSTREAM_NOT_FOUND\"\n | \"UPSTREAM_UNAUTHORIZED\"\n | \"UPSTREAM_FORBIDDEN\"\n | \"UPSTREAM_UNKNOWN\";\n\nexport class UpstreamError extends Error {\n public code: ClientErrorCode;\n public status?: number;\n public details?: any;\n\n constructor(message: string, code: ClientErrorCode, status?: number, details?: any) {\n super(message);\n this.name = \"UpstreamError\";\n this.code = code;\n this.status = status;\n this.details = details;\n }\n}\n\nexport function mapAxiosToUpstreamError(err: any, svc: string): UpstreamError {\n const status = err?.response?.status;\n const data = err?.response?.data;\n const isTimeout = err?.code === \"ECONNABORTED\" || String(err?.message || \"\").includes(\"timeout\");\n\n if (isTimeout) {\n return new UpstreamError(`[${svc}] timeout`, \"UPSTREAM_TIMEOUT\", 504, {cause: err?.message});\n }\n if (!err?.response) {\n return new UpstreamError(`[${svc}] unavailable`, \"UPSTREAM_UNAVAILABLE\", 503, {cause: err?.message});\n }\n if (status === 404) return new UpstreamError(`[${svc}] not found`, \"UPSTREAM_NOT_FOUND\", 404, data);\n if (status === 401) return new UpstreamError(`[${svc}] unauthorized`, \"UPSTREAM_UNAUTHORIZED\", 401, data);\n if (status === 403) return new UpstreamError(`[${svc}] forbidden`, \"UPSTREAM_FORBIDDEN\", 403, data);\n if (status >= 400 && status < 600) {\n return new UpstreamError(`[${svc}] bad response`, \"UPSTREAM_BAD_RESPONSE\", status, data);\n }\n return new UpstreamError(`[${svc}] unknown error`, \"UPSTREAM_UNKNOWN\", status, data);\n}\n","// clients/core/http.ts\nimport axios, {AxiosInstance, AxiosRequestConfig} from \"axios\";\n\nexport const REQUEST_ID_HEADER = \"x-request-id\";\n\nexport type HttpClientOpts = {\n baseURL: string;\n timeoutMs?: number;\n};\n\n/**\n * Headers compatibles con múltiples versiones de axios.\n * En axios antiguo, `headers` suele ser `any`, así que mantenemos tolerancia.\n */\nexport type AnyHeaders = NonNullable<AxiosRequestConfig[\"headers\"]> | Record<string, string>;\n\n/**\n * Agrega x-request-id a headers (sin pisar otros headers).\n */\nexport function withRequestId(headers: AnyHeaders | undefined, requestId?: string | null): AnyHeaders {\n const h: Record<string, any> =\n headers && typeof headers === \"object\"\n ? {...(headers as any)}\n : {};\n\n const rid = (requestId || \"\").trim();\n if (rid) h[REQUEST_ID_HEADER] = rid;\n\n return h as AnyHeaders;\n}\n\n/**\n * Helper para construir config de axios con requestId\n * (SIN genéricos para compat con axios typings antiguos).\n */\nexport function withRequestIdConfig(\n config: AxiosRequestConfig = {},\n requestId?: string | null\n): AxiosRequestConfig {\n return {\n ...config,\n headers: withRequestId((config as any).headers, requestId) as any,\n };\n}\n\nexport function createHttpClient(opts: HttpClientOpts): AxiosInstance {\n return axios.create({\n baseURL: opts.baseURL,\n timeout: opts.timeoutMs ?? 4000,\n headers: {\"Content-Type\": \"application/json\"},\n });\n}\n","// clients/internalHttp.ts\n\ntype RetryPolicy = {\n retries: number;\n baseDelayMs: number;\n retryOnStatuses: number[];\n retryOnNetworkErrors: boolean;\n};\n\ntype InternalHttpOptions = {\n baseUrl: string;\n apiKey?: string; // x-internal-api-key\n timeoutMs?: number;\n retry?: Partial<RetryPolicy>;\n};\n\nconst DEFAULT_RETRY: RetryPolicy = {\n retries: 1,\n baseDelayMs: 150,\n retryOnStatuses: [429, 502, 503, 504],\n retryOnNetworkErrors: true,\n};\n\nfunction sleep(ms: number) {\n return new Promise((r) => setTimeout(r, ms));\n}\n\nfunction safeJsonStringify(v: any) {\n try {\n return JSON.stringify(v);\n } catch {\n return String(v);\n }\n}\n\nfunction toHeaders(init?: HeadersInit): Headers {\n return new Headers(init || {});\n}\n\nfunction isJsonContentType(contentType: string | null): boolean {\n if (!contentType) return false;\n const ct = contentType.toLowerCase();\n return ct.includes(\"application/json\") || ct.includes(\"+json\");\n}\n\nfunction isAbortError(e: any): boolean {\n return e?.name === \"AbortError\";\n}\n\nfunction withJitter(ms: number): number {\n // jitter +-20%\n const jitter = ms * 0.2;\n const delta = (Math.random() * 2 - 1) * jitter;\n return Math.max(0, Math.floor(ms + delta));\n}\n\nexport class InternalHttp {\n private readonly baseUrl: string;\n private readonly apiKey: string | undefined;\n private readonly timeoutMs: number;\n private retry: RetryPolicy;\n\n constructor(opts: InternalHttpOptions) {\n this.baseUrl = opts.baseUrl.replace(/\\/+$/, \"\");\n this.apiKey = opts.apiKey;\n\n // ✅ Default más seguro para internas (evita cascadas)\n this.timeoutMs = opts.timeoutMs ?? 4000;\n\n this.retry = {...DEFAULT_RETRY, ...(opts.retry || {})};\n }\n\n async request<T>(\n path: string,\n init: RequestInit & {\n requestId?: string;\n idempotencyKey?: string;\n headers?: HeadersInit;\n } = {}\n ): Promise<T> {\n const url = `${this.baseUrl}${path.startsWith(\"/\") ? \"\" : \"/\"}${path}`;\n\n const baseHeaders = toHeaders(init.headers);\n\n if (!baseHeaders.has(\"Content-Type\")) baseHeaders.set(\"Content-Type\", \"application/json\");\n if (this.apiKey) baseHeaders.set(\"x-internal-api-key\", this.apiKey);\n\n if (init.requestId) baseHeaders.set(\"x-request-id\", init.requestId);\n if (init.idempotencyKey) baseHeaders.set(\"Idempotency-Key\", init.idempotencyKey);\n\n const {headers: _ignored, ...restInit} = init;\n\n const doFetchOnce = async () => {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.timeoutMs);\n\n try {\n const res = await fetch(url, {\n ...restInit,\n headers: baseHeaders,\n signal: controller.signal,\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n const err: any = new Error(\n `HTTP ${res.status} ${res.statusText}${text ? ` - ${text}` : \"\"}`\n );\n err.status = res.status;\n err.body = text;\n throw err;\n }\n\n if (res.status === 204) return undefined as unknown as T;\n\n const contentType = res.headers.get(\"content-type\");\n if (isJsonContentType(contentType)) {\n return (await res.json()) as T;\n }\n\n const text = await res.text().catch(() => \"\");\n return text as unknown as T;\n } finally {\n clearTimeout(timeout);\n }\n };\n\n let attempt = 0;\n\n while (true) {\n try {\n return await doFetchOnce();\n } catch (e: any) {\n attempt++;\n\n const status = e?.status;\n const retryableStatus = !!status && this.retry.retryOnStatuses.includes(status);\n\n const retryableNetwork =\n this.retry.retryOnNetworkErrors &&\n (isAbortError(e) || !status); // sin status suele ser red/dns/timeout\n\n const isRetryable = retryableStatus || retryableNetwork;\n\n if (!isRetryable || attempt > this.retry.retries) {\n console.error(\n `[InternalHttp] request failed: ${url} attempt=${attempt} status=${status ?? \"n/a\"} err=${e?.message\n } body=${safeJsonStringify(e?.body)}`\n );\n throw e;\n }\n\n const backoff = withJitter(this.retry.baseDelayMs * attempt);\n await sleep(backoff);\n }\n }\n }\n}\n"],"mappings":"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","names":["axios","text"]}
1
+ {"version":3,"sources":["../../src/core/index.ts","../../src/core/errors.ts","../../src/core/http.ts","../../src/middlewares/requestId.ts","../../src/core/internalHttp.ts"],"sourcesContent":["// sdk/src/core/index.ts\n\nexport * from \"./errors\";\nexport * from \"./http\";\nexport * from \"./internalHttp\";\n","export type ClientErrorCode =\n | \"UPSTREAM_TIMEOUT\"\n | \"UPSTREAM_UNAVAILABLE\"\n | \"UPSTREAM_BAD_RESPONSE\"\n | \"UPSTREAM_NOT_FOUND\"\n | \"UPSTREAM_UNAUTHORIZED\"\n | \"UPSTREAM_FORBIDDEN\"\n | \"UPSTREAM_UNKNOWN\";\n\nexport class UpstreamError extends Error {\n public code: ClientErrorCode;\n public status?: number;\n public details?: any;\n\n constructor(message: string, code: ClientErrorCode, status?: number, details?: any) {\n super(message);\n this.name = \"UpstreamError\";\n this.code = code;\n this.status = status;\n this.details = details;\n }\n}\n\nexport function mapAxiosToUpstreamError(err: any, svc: string): UpstreamError {\n const status = err?.response?.status;\n const data = err?.response?.data;\n const isTimeout = err?.code === \"ECONNABORTED\" || String(err?.message || \"\").includes(\"timeout\");\n\n if (isTimeout) {\n return new UpstreamError(`[${svc}] timeout`, \"UPSTREAM_TIMEOUT\", 504, {cause: err?.message});\n }\n if (!err?.response) {\n return new UpstreamError(`[${svc}] unavailable`, \"UPSTREAM_UNAVAILABLE\", 503, {cause: err?.message});\n }\n if (status === 404) return new UpstreamError(`[${svc}] not found`, \"UPSTREAM_NOT_FOUND\", 404, data);\n if (status === 401) return new UpstreamError(`[${svc}] unauthorized`, \"UPSTREAM_UNAUTHORIZED\", 401, data);\n if (status === 403) return new UpstreamError(`[${svc}] forbidden`, \"UPSTREAM_FORBIDDEN\", 403, data);\n if (status >= 400 && status < 600) {\n return new UpstreamError(`[${svc}] bad response`, \"UPSTREAM_BAD_RESPONSE\", status, data);\n }\n return new UpstreamError(`[${svc}] unknown error`, \"UPSTREAM_UNKNOWN\", status, data);\n}\n","// packages/sdk/src/core/http.ts\nimport axios, {AxiosInstance, AxiosRequestConfig} from \"axios\";\nimport {REQUEST_ID_HEADER} from \"../middlewares/requestId\";\n\nexport type HttpClientOpts = {\n baseURL: string;\n timeoutMs?: number;\n};\n\n/**\n * Headers compatibles con múltiples versiones de axios.\n * En axios antiguo, `headers` suele ser `any`, así que mantenemos tolerancia.\n */\nexport type AnyHeaders = NonNullable<AxiosRequestConfig[\"headers\"]> | Record<string, string>;\n\n/**\n * Agrega x-request-id a headers (sin pisar otros headers).\n */\nexport function withRequestId(headers: AnyHeaders | undefined, requestId?: string | null): AnyHeaders {\n const h: Record<string, any> =\n headers && typeof headers === \"object\"\n ? {...(headers as any)}\n : {};\n\n const rid = (requestId || \"\").trim();\n if (rid) h[REQUEST_ID_HEADER] = rid;\n\n return h as AnyHeaders;\n}\n\n/**\n * Helper para construir config de axios con requestId\n * (SIN genéricos para compat con axios typings antiguos).\n */\nexport function withRequestIdConfig(\n config: AxiosRequestConfig = {},\n requestId?: string | null\n): AxiosRequestConfig {\n return {\n ...config,\n headers: withRequestId((config as any).headers, requestId) as any,\n };\n}\n\nexport function createHttpClient(opts: HttpClientOpts): AxiosInstance {\n return axios.create({\n baseURL: opts.baseURL,\n timeout: opts.timeoutMs ?? 4000,\n headers: {\"Content-Type\": \"application/json\"},\n });\n}\n","// middlewares/requestId.ts\nimport type {Request, Response, NextFunction} from \"express\";\nimport {randomUUID, randomBytes} from \"crypto\";\n\nexport const REQUEST_ID_HEADER = \"x-request-id\";\nexport const REQUEST_ID_HEADER_ALT = \"x-requestid\";\nexport const RESPONSE_REQUEST_ID_HEADER = \"X-Request-Id\";\n\n// Si quieres IDs más cortos (opcional). Por defecto usamos UUID.\nfunction nanoidLike(len = 21) {\n return randomBytes(16).toString(\"base64url\").slice(0, len);\n}\n\nexport default function requestId(req: Request, res: Response, next: NextFunction) {\n const headerId = (req.headers[REQUEST_ID_HEADER] || req.headers[REQUEST_ID_HEADER_ALT]) as\n | string\n | undefined;\n\n // ✅ estándar único: usa UUID (o cambia a nanoidLike() si prefieres corto)\n const id = headerId?.trim() || randomUUID();\n\n // ✅ estándar único (no legacy)\n (req as any).requestId = id;\n res.locals.requestId = id;\n\n // ✅ respuesta\n res.setHeader(RESPONSE_REQUEST_ID_HEADER, id);\n\n next();\n}\n","// clients/internalHttp.ts\n\ntype RetryPolicy = {\n retries: number;\n baseDelayMs: number;\n retryOnStatuses: number[];\n retryOnNetworkErrors: boolean;\n};\n\ntype InternalHttpOptions = {\n baseUrl: string;\n apiKey?: string; // x-internal-api-key\n timeoutMs?: number;\n retry?: Partial<RetryPolicy>;\n};\n\nconst DEFAULT_RETRY: RetryPolicy = {\n retries: 1,\n baseDelayMs: 150,\n retryOnStatuses: [429, 502, 503, 504],\n retryOnNetworkErrors: true,\n};\n\nfunction sleep(ms: number) {\n return new Promise((r) => setTimeout(r, ms));\n}\n\nfunction safeJsonStringify(v: any) {\n try {\n return JSON.stringify(v);\n } catch {\n return String(v);\n }\n}\n\nfunction toHeaders(init?: HeadersInit): Headers {\n return new Headers(init || {});\n}\n\nfunction isJsonContentType(contentType: string | null): boolean {\n if (!contentType) return false;\n const ct = contentType.toLowerCase();\n return ct.includes(\"application/json\") || ct.includes(\"+json\");\n}\n\nfunction isAbortError(e: any): boolean {\n return e?.name === \"AbortError\";\n}\n\nfunction withJitter(ms: number): number {\n // jitter +-20%\n const jitter = ms * 0.2;\n const delta = (Math.random() * 2 - 1) * jitter;\n return Math.max(0, Math.floor(ms + delta));\n}\n\nexport class InternalHttp {\n private readonly baseUrl: string;\n private readonly apiKey: string | undefined;\n private readonly timeoutMs: number;\n private retry: RetryPolicy;\n\n constructor(opts: InternalHttpOptions) {\n this.baseUrl = opts.baseUrl.replace(/\\/+$/, \"\");\n this.apiKey = opts.apiKey;\n\n // ✅ Default más seguro para internas (evita cascadas)\n this.timeoutMs = opts.timeoutMs ?? 4000;\n\n this.retry = {...DEFAULT_RETRY, ...(opts.retry || {})};\n }\n\n async request<T>(\n path: string,\n init: RequestInit & {\n requestId?: string;\n idempotencyKey?: string;\n headers?: HeadersInit;\n } = {}\n ): Promise<T> {\n const url = `${this.baseUrl}${path.startsWith(\"/\") ? \"\" : \"/\"}${path}`;\n\n const baseHeaders = toHeaders(init.headers);\n\n if (!baseHeaders.has(\"Content-Type\")) baseHeaders.set(\"Content-Type\", \"application/json\");\n if (this.apiKey) baseHeaders.set(\"x-internal-api-key\", this.apiKey);\n\n if (init.requestId) baseHeaders.set(\"x-request-id\", init.requestId);\n if (init.idempotencyKey) baseHeaders.set(\"Idempotency-Key\", init.idempotencyKey);\n\n const {headers: _ignored, ...restInit} = init;\n\n const doFetchOnce = async () => {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.timeoutMs);\n\n try {\n const res = await fetch(url, {\n ...restInit,\n headers: baseHeaders,\n signal: controller.signal,\n });\n\n if (!res.ok) {\n const text = await res.text().catch(() => \"\");\n const err: any = new Error(\n `HTTP ${res.status} ${res.statusText}${text ? ` - ${text}` : \"\"}`\n );\n err.status = res.status;\n err.body = text;\n throw err;\n }\n\n if (res.status === 204) return undefined as unknown as T;\n\n const contentType = res.headers.get(\"content-type\");\n if (isJsonContentType(contentType)) {\n return (await res.json()) as T;\n }\n\n const text = await res.text().catch(() => \"\");\n return text as unknown as T;\n } finally {\n clearTimeout(timeout);\n }\n };\n\n let attempt = 0;\n\n while (true) {\n try {\n return await doFetchOnce();\n } catch (e: any) {\n attempt++;\n\n const status = e?.status;\n const retryableStatus = !!status && this.retry.retryOnStatuses.includes(status);\n\n const retryableNetwork =\n this.retry.retryOnNetworkErrors &&\n (isAbortError(e) || !status); // sin status suele ser red/dns/timeout\n\n const isRetryable = retryableStatus || retryableNetwork;\n\n if (!isRetryable || attempt > this.retry.retries) {\n console.error(\n `[InternalHttp] request failed: ${url} attempt=${attempt} status=${status ?? \"n/a\"} err=${e?.message\n } body=${safeJsonStringify(e?.body)}`\n );\n throw e;\n }\n\n const backoff = withJitter(this.retry.baseDelayMs * attempt);\n await sleep(backoff);\n }\n }\n }\n}\n"],"mappings":"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","names":["axios","text"]}
@@ -9,7 +9,6 @@ declare class UpstreamError extends Error {
9
9
  }
10
10
  declare function mapAxiosToUpstreamError(err: any, svc: string): UpstreamError;
11
11
 
12
- declare const REQUEST_ID_HEADER = "x-request-id";
13
12
  type HttpClientOpts = {
14
13
  baseURL: string;
15
14
  timeoutMs?: number;
@@ -55,4 +54,4 @@ declare class InternalHttp {
55
54
  }): Promise<T>;
56
55
  }
57
56
 
58
- export { type AnyHeaders, type ClientErrorCode, type HttpClientOpts, InternalHttp, REQUEST_ID_HEADER, UpstreamError, createHttpClient, mapAxiosToUpstreamError, withRequestId, withRequestIdConfig };
57
+ export { type AnyHeaders, type ClientErrorCode, type HttpClientOpts, InternalHttp, UpstreamError, createHttpClient, mapAxiosToUpstreamError, withRequestId, withRequestIdConfig };
@@ -9,7 +9,6 @@ declare class UpstreamError extends Error {
9
9
  }
10
10
  declare function mapAxiosToUpstreamError(err: any, svc: string): UpstreamError;
11
11
 
12
- declare const REQUEST_ID_HEADER = "x-request-id";
13
12
  type HttpClientOpts = {
14
13
  baseURL: string;
15
14
  timeoutMs?: number;
@@ -55,4 +54,4 @@ declare class InternalHttp {
55
54
  }): Promise<T>;
56
55
  }
57
56
 
58
- export { type AnyHeaders, type ClientErrorCode, type HttpClientOpts, InternalHttp, REQUEST_ID_HEADER, UpstreamError, createHttpClient, mapAxiosToUpstreamError, withRequestId, withRequestIdConfig };
57
+ export { type AnyHeaders, type ClientErrorCode, type HttpClientOpts, InternalHttp, UpstreamError, createHttpClient, mapAxiosToUpstreamError, withRequestId, withRequestIdConfig };
@@ -1,16 +1,14 @@
1
1
  import {
2
2
  InternalHttp,
3
- REQUEST_ID_HEADER,
4
3
  UpstreamError,
5
4
  createHttpClient,
6
5
  mapAxiosToUpstreamError,
7
6
  withRequestId,
8
7
  withRequestIdConfig
9
- } from "../chunk-GG7EI74E.js";
10
- import "../chunk-PZ5AY32C.js";
8
+ } from "../chunk-OSYBK5AN.js";
9
+ import "../chunk-KJ64O2EG.js";
11
10
  export {
12
11
  InternalHttp,
13
- REQUEST_ID_HEADER,
14
12
  UpstreamError,
15
13
  createHttpClient,
16
14
  mapAxiosToUpstreamError,
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/express.ts
17
+ var express_exports = {};
18
+ module.exports = __toCommonJS(express_exports);
19
+ //# sourceMappingURL=express.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/express.ts"],"sourcesContent":["// sdk/src/express.d.ts\nimport type {RequestContext} from \"./headers/parse\";\nimport type {AuthContext} from \"./auth/types\";\n\ndeclare global {\n namespace Express {\n interface Request {\n context?: RequestContext;\n auth?: AuthContext;\n }\n }\n}\n\nexport {};\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -0,0 +1,12 @@
1
+ import { R as RequestContext } from './parse-C4vk-fmH.cjs';
2
+ import { A as AuthContext } from './types-CRECQuHp.cjs';
3
+ import 'express';
4
+
5
+ declare global {
6
+ namespace Express {
7
+ interface Request {
8
+ context?: RequestContext;
9
+ auth?: AuthContext;
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,12 @@
1
+ import { R as RequestContext } from './parse-C4vk-fmH.js';
2
+ import { A as AuthContext } from './types-CRECQuHp.js';
3
+ import 'express';
4
+
5
+ declare global {
6
+ namespace Express {
7
+ interface Request {
8
+ context?: RequestContext;
9
+ auth?: AuthContext;
10
+ }
11
+ }
12
+ }
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=express.js.map
@@ -39,17 +39,23 @@ var HEADER_INTERNAL_API_KEY = "x-internal-api-key";
39
39
  var HEADER_AUTHORIZATION = "authorization";
40
40
 
41
41
  // src/headers/parse.ts
42
- function asString(v) {
42
+ function normalizeHeaderValue(v) {
43
43
  if (typeof v !== "string") return null;
44
44
  const s = v.trim();
45
- return s ? s : null;
45
+ if (!s) return null;
46
+ if (s.startsWith("{") || s.startsWith("[") || s.includes('"')) return null;
47
+ if (s.length < 6) return null;
48
+ return s;
49
+ }
50
+ function h(headers, key) {
51
+ return headers[key] ?? headers[key.toLowerCase()] ?? headers[key.toUpperCase()];
46
52
  }
47
53
  function getRequestContextFromHeaders(headers) {
48
54
  return {
49
- requestId: asString(headers[HEADER_REQUEST_ID]) ?? null,
50
- company_uid: asString(headers[HEADER_COMPANY_UID]) ?? null,
51
- branch_uid: asString(headers[HEADER_BRANCH_UID]) ?? null,
52
- employee_uid: asString(headers[HEADER_EMPLOYEE_UID]) ?? null
55
+ requestId: normalizeHeaderValue(h(headers, HEADER_REQUEST_ID)) ?? null,
56
+ company_uid: normalizeHeaderValue(h(headers, HEADER_COMPANY_UID)) ?? null,
57
+ branch_uid: normalizeHeaderValue(h(headers, HEADER_BRANCH_UID)) ?? null,
58
+ employee_uid: normalizeHeaderValue(h(headers, HEADER_EMPLOYEE_UID)) ?? null
53
59
  };
54
60
  }
55
61
  // Annotate the CommonJS export names for ESM import in node: