@schafevormfenster/rest-commons 0.1.1

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 (264) hide show
  1. package/CONTRIBUTING.md +1190 -0
  2. package/README.md +275 -0
  3. package/bin/setup.js +10 -0
  4. package/dist/api-schemas/error.schema.d.ts +20 -0
  5. package/dist/api-schemas/error.schema.d.ts.map +1 -0
  6. package/dist/api-schemas/error.schema.js +17 -0
  7. package/dist/api-schemas/health.schema.d.ts +497 -0
  8. package/dist/api-schemas/health.schema.d.ts.map +1 -0
  9. package/dist/api-schemas/health.schema.js +33 -0
  10. package/dist/api-schemas/okay.schema.d.ts +13 -0
  11. package/dist/api-schemas/okay.schema.d.ts.map +1 -0
  12. package/dist/api-schemas/okay.schema.js +5 -0
  13. package/dist/api-schemas/paginated-results.schema.d.ts +59 -0
  14. package/dist/api-schemas/paginated-results.schema.d.ts.map +1 -0
  15. package/dist/api-schemas/paginated-results.schema.js +10 -0
  16. package/dist/api-schemas/partial-results.schema.d.ts +30 -0
  17. package/dist/api-schemas/partial-results.schema.d.ts.map +1 -0
  18. package/dist/api-schemas/partial-results.schema.js +10 -0
  19. package/dist/api-schemas/result.schema.d.ts +17 -0
  20. package/dist/api-schemas/result.schema.d.ts.map +1 -0
  21. package/dist/api-schemas/result.schema.js +5 -0
  22. package/dist/api-schemas/results.schema.d.ts +21 -0
  23. package/dist/api-schemas/results.schema.d.ts.map +1 -0
  24. package/dist/api-schemas/results.schema.js +5 -0
  25. package/dist/helpers/correlation/get-correlation-id.d.ts +7 -0
  26. package/dist/helpers/correlation/get-correlation-id.d.ts.map +1 -0
  27. package/dist/helpers/correlation/get-correlation-id.js +16 -0
  28. package/dist/helpers/correlation/get-header.d.ts +7 -0
  29. package/dist/helpers/correlation/get-header.d.ts.map +1 -0
  30. package/dist/helpers/correlation/get-header.js +11 -0
  31. package/dist/helpers/detect-mime-type.d.ts +11 -0
  32. package/dist/helpers/detect-mime-type.d.ts.map +1 -0
  33. package/dist/helpers/detect-mime-type.js +40 -0
  34. package/dist/helpers/detect-suspicious-patterns.d.ts +8 -0
  35. package/dist/helpers/detect-suspicious-patterns.d.ts.map +1 -0
  36. package/dist/helpers/detect-suspicious-patterns.js +55 -0
  37. package/dist/helpers/eventify-constants.types.d.ts +32 -0
  38. package/dist/helpers/eventify-constants.types.d.ts.map +1 -0
  39. package/dist/helpers/eventify-constants.types.js +40 -0
  40. package/dist/helpers/hash-binary.d.ts +21 -0
  41. package/dist/helpers/hash-binary.d.ts.map +1 -0
  42. package/dist/helpers/hash-binary.js +28 -0
  43. package/dist/helpers/mime-types/detect-image-mime-type.d.ts +5 -0
  44. package/dist/helpers/mime-types/detect-image-mime-type.d.ts.map +1 -0
  45. package/dist/helpers/mime-types/detect-image-mime-type.js +41 -0
  46. package/dist/helpers/mime-types/detect-ole-mime-type.d.ts +6 -0
  47. package/dist/helpers/mime-types/detect-ole-mime-type.d.ts.map +1 -0
  48. package/dist/helpers/mime-types/detect-ole-mime-type.js +34 -0
  49. package/dist/helpers/mime-types/detect-pdf-mime-type.d.ts +5 -0
  50. package/dist/helpers/mime-types/detect-pdf-mime-type.d.ts.map +1 -0
  51. package/dist/helpers/mime-types/detect-pdf-mime-type.js +13 -0
  52. package/dist/helpers/mime-types/detect-zip-mime-type.d.ts +6 -0
  53. package/dist/helpers/mime-types/detect-zip-mime-type.d.ts.map +1 -0
  54. package/dist/helpers/mime-types/detect-zip-mime-type.js +23 -0
  55. package/dist/helpers/parameter-validation.d.ts +6 -0
  56. package/dist/helpers/parameter-validation.d.ts.map +1 -0
  57. package/dist/helpers/parameter-validation.js +19 -0
  58. package/dist/helpers/parameter-validation.types.d.ts +16 -0
  59. package/dist/helpers/parameter-validation.types.d.ts.map +1 -0
  60. package/dist/helpers/parameter-validation.types.js +38 -0
  61. package/dist/helpers/response-headers/build-api-unauthorized-headers.d.ts +6 -0
  62. package/dist/helpers/response-headers/build-api-unauthorized-headers.d.ts.map +1 -0
  63. package/dist/helpers/response-headers/build-api-unauthorized-headers.js +23 -0
  64. package/dist/helpers/response-headers/environment.types.d.ts +2 -0
  65. package/dist/helpers/response-headers/environment.types.d.ts.map +1 -0
  66. package/dist/helpers/response-headers/environment.types.js +1 -0
  67. package/dist/helpers/response-headers/resolve-environment.d.ts +8 -0
  68. package/dist/helpers/response-headers/resolve-environment.d.ts.map +1 -0
  69. package/dist/helpers/response-headers/resolve-environment.js +18 -0
  70. package/dist/helpers/slugify.d.ts +15 -0
  71. package/dist/helpers/slugify.d.ts.map +1 -0
  72. package/dist/helpers/slugify.js +32 -0
  73. package/dist/index.d.ts +36 -0
  74. package/dist/index.d.ts.map +1 -0
  75. package/dist/index.js +41 -0
  76. package/dist/normalization/normalize-list.d.ts +11 -0
  77. package/dist/normalization/normalize-list.d.ts.map +1 -0
  78. package/dist/normalization/normalize-list.js +19 -0
  79. package/dist/normalization/normalize-location.d.ts +16 -0
  80. package/dist/normalization/normalize-location.d.ts.map +1 -0
  81. package/dist/normalization/normalize-location.js +26 -0
  82. package/dist/primitives/coordinate-precision.d.ts +10 -0
  83. package/dist/primitives/coordinate-precision.d.ts.map +1 -0
  84. package/dist/primitives/coordinate-precision.js +27 -0
  85. package/dist/primitives/geo-point.schema.d.ts +8 -0
  86. package/dist/primitives/geo-point.schema.d.ts.map +1 -0
  87. package/dist/primitives/geo-point.schema.js +10 -0
  88. package/dist/primitives/geoname-id.schema.d.ts +8 -0
  89. package/dist/primitives/geoname-id.schema.d.ts.map +1 -0
  90. package/dist/primitives/geoname-id.schema.js +9 -0
  91. package/dist/primitives/international-zip.schema.d.ts +76 -0
  92. package/dist/primitives/international-zip.schema.d.ts.map +1 -0
  93. package/dist/primitives/international-zip.schema.js +81 -0
  94. package/dist/primitives/latitude.schema.d.ts +9 -0
  95. package/dist/primitives/latitude.schema.d.ts.map +1 -0
  96. package/dist/primitives/latitude.schema.js +13 -0
  97. package/dist/primitives/location.schema.d.ts +8 -0
  98. package/dist/primitives/location.schema.d.ts.map +1 -0
  99. package/dist/primitives/location.schema.js +15 -0
  100. package/dist/primitives/longitude.schema.d.ts +9 -0
  101. package/dist/primitives/longitude.schema.d.ts.map +1 -0
  102. package/dist/primitives/longitude.schema.js +13 -0
  103. package/dist/primitives/numeric-id.schema.d.ts +8 -0
  104. package/dist/primitives/numeric-id.schema.d.ts.map +1 -0
  105. package/dist/primitives/numeric-id.schema.js +10 -0
  106. package/dist/primitives/slug.schema.d.ts +17 -0
  107. package/dist/primitives/slug.schema.d.ts.map +1 -0
  108. package/dist/primitives/slug.schema.js +30 -0
  109. package/dist/primitives/uuid.schema.d.ts +8 -0
  110. package/dist/primitives/uuid.schema.d.ts.map +1 -0
  111. package/dist/primitives/uuid.schema.js +9 -0
  112. package/dist/primitives/wikidata-id.schema.d.ts +9 -0
  113. package/dist/primitives/wikidata-id.schema.d.ts.map +1 -0
  114. package/dist/primitives/wikidata-id.schema.js +10 -0
  115. package/dist/time/boundary-enforcement.d.ts +11 -0
  116. package/dist/time/boundary-enforcement.d.ts.map +1 -0
  117. package/dist/time/boundary-enforcement.js +43 -0
  118. package/dist/time/bounded-time.schema.d.ts +31 -0
  119. package/dist/time/bounded-time.schema.d.ts.map +1 -0
  120. package/dist/time/bounded-time.schema.js +77 -0
  121. package/dist/time/flexible-time-parser.d.ts +12 -0
  122. package/dist/time/flexible-time-parser.d.ts.map +1 -0
  123. package/dist/time/flexible-time-parser.js +94 -0
  124. package/dist/time/flexible-time.schema.d.ts +31 -0
  125. package/dist/time/flexible-time.schema.d.ts.map +1 -0
  126. package/dist/time/flexible-time.schema.js +31 -0
  127. package/dist/time/get-week-end.d.ts +10 -0
  128. package/dist/time/get-week-end.d.ts.map +1 -0
  129. package/dist/time/get-week-end.js +25 -0
  130. package/dist/time/get-week-start.d.ts +10 -0
  131. package/dist/time/get-week-start.d.ts.map +1 -0
  132. package/dist/time/get-week-start.js +25 -0
  133. package/dist/time/is-relative-time.d.ts +8 -0
  134. package/dist/time/is-relative-time.d.ts.map +1 -0
  135. package/dist/time/is-relative-time.js +9 -0
  136. package/dist/time/iso8601.schema.d.ts +14 -0
  137. package/dist/time/iso8601.schema.d.ts.map +1 -0
  138. package/dist/time/iso8601.schema.js +17 -0
  139. package/dist/time/iso8601.types.d.ts +6 -0
  140. package/dist/time/iso8601.types.d.ts.map +1 -0
  141. package/dist/time/iso8601.types.js +11 -0
  142. package/dist/time/parse-relative-time.d.ts +9 -0
  143. package/dist/time/parse-relative-time.d.ts.map +1 -0
  144. package/dist/time/parse-relative-time.js +36 -0
  145. package/dist/time/relative-time.schema.d.ts +23 -0
  146. package/dist/time/relative-time.schema.d.ts.map +1 -0
  147. package/dist/time/relative-time.schema.js +25 -0
  148. package/dist/time/since-parameter.schema.d.ts +8 -0
  149. package/dist/time/since-parameter.schema.d.ts.map +1 -0
  150. package/dist/time/since-parameter.schema.js +56 -0
  151. package/dist/time/time-helpers.d.ts +19 -0
  152. package/dist/time/time-helpers.d.ts.map +1 -0
  153. package/dist/time/time-helpers.js +56 -0
  154. package/dist/time/time-schemas.d.ts +20 -0
  155. package/dist/time/time-schemas.d.ts.map +1 -0
  156. package/dist/time/time-schemas.js +25 -0
  157. package/dist/time/timezone.types.d.ts +17 -0
  158. package/dist/time/timezone.types.d.ts.map +1 -0
  159. package/dist/time/timezone.types.js +15 -0
  160. package/dist/validation/zod-error-handler.d.ts +3 -0
  161. package/dist/validation/zod-error-handler.d.ts.map +1 -0
  162. package/dist/validation/zod-error-handler.js +189 -0
  163. package/dist/validation/zod-utils.d.ts +9 -0
  164. package/dist/validation/zod-utils.d.ts.map +1 -0
  165. package/dist/validation/zod-utils.js +23 -0
  166. package/eslint.config.mjs +16 -0
  167. package/package.json +44 -0
  168. package/src/api-schemas/error.schema.test.ts +27 -0
  169. package/src/api-schemas/error.schema.ts +23 -0
  170. package/src/api-schemas/health.schema.test.ts +104 -0
  171. package/src/api-schemas/health.schema.ts +63 -0
  172. package/src/api-schemas/okay.schema.test.ts +15 -0
  173. package/src/api-schemas/okay.schema.ts +8 -0
  174. package/src/api-schemas/paginated-results.schema.ts +17 -0
  175. package/src/api-schemas/partial-results.schema.ts +13 -0
  176. package/src/api-schemas/result.schema.test.ts +19 -0
  177. package/src/api-schemas/result.schema.ts +9 -0
  178. package/src/api-schemas/results.schema.test.ts +15 -0
  179. package/src/api-schemas/results.schema.ts +9 -0
  180. package/src/helpers/correlation/get-correlation-id.test.ts +126 -0
  181. package/src/helpers/correlation/get-correlation-id.ts +22 -0
  182. package/src/helpers/correlation/get-header.test.ts +179 -0
  183. package/src/helpers/correlation/get-header.ts +21 -0
  184. package/src/helpers/detect-mime-type.test.ts +100 -0
  185. package/src/helpers/detect-mime-type.ts +46 -0
  186. package/src/helpers/detect-suspicious-patterns.test.ts +45 -0
  187. package/src/helpers/detect-suspicious-patterns.ts +57 -0
  188. package/src/helpers/eventify-constants.test.ts +52 -0
  189. package/src/helpers/eventify-constants.types.test.ts +52 -0
  190. package/src/helpers/eventify-constants.types.ts +51 -0
  191. package/src/helpers/hash-binary.test.ts +60 -0
  192. package/src/helpers/hash-binary.ts +30 -0
  193. package/src/helpers/mime-types/detect-image-mime-type.test.ts +73 -0
  194. package/src/helpers/mime-types/detect-image-mime-type.ts +50 -0
  195. package/src/helpers/mime-types/detect-ole-mime-type.test.ts +86 -0
  196. package/src/helpers/mime-types/detect-ole-mime-type.ts +44 -0
  197. package/src/helpers/mime-types/detect-pdf-mime-type.test.ts +39 -0
  198. package/src/helpers/mime-types/detect-pdf-mime-type.ts +15 -0
  199. package/src/helpers/mime-types/detect-zip-mime-type.test.ts +88 -0
  200. package/src/helpers/mime-types/detect-zip-mime-type.ts +28 -0
  201. package/src/helpers/parameter-validation.test.ts +35 -0
  202. package/src/helpers/parameter-validation.ts +32 -0
  203. package/src/helpers/process-eventify-request.ts +146 -0
  204. package/src/helpers/response-headers/build-api-unauthorized-headers.ts +30 -0
  205. package/src/helpers/response-headers/environment.types.ts +1 -0
  206. package/src/helpers/response-headers/resolve-environment.ts +17 -0
  207. package/src/helpers/slugify.test.ts +77 -0
  208. package/src/helpers/slugify.ts +34 -0
  209. package/src/index.ts +46 -0
  210. package/src/normalization/normalize-list.test.ts +43 -0
  211. package/src/normalization/normalize-list.ts +21 -0
  212. package/src/normalization/normalize-location.test.ts +91 -0
  213. package/src/normalization/normalize-location.ts +29 -0
  214. package/src/primitives/coordinate-precision.test.ts +46 -0
  215. package/src/primitives/coordinate-precision.ts +30 -0
  216. package/src/primitives/geo-point.schema.test.ts +70 -0
  217. package/src/primitives/geo-point.schema.ts +14 -0
  218. package/src/primitives/geoname-id.schema.test.ts +60 -0
  219. package/src/primitives/geoname-id.schema.ts +12 -0
  220. package/src/primitives/international-zip.schema.test.ts +212 -0
  221. package/src/primitives/international-zip.schema.ts +103 -0
  222. package/src/primitives/latitude.schema.test.ts +77 -0
  223. package/src/primitives/latitude.schema.ts +20 -0
  224. package/src/primitives/location.schema.test.ts +21 -0
  225. package/src/primitives/location.schema.ts +22 -0
  226. package/src/primitives/longitude.schema.test.ts +77 -0
  227. package/src/primitives/longitude.schema.ts +20 -0
  228. package/src/primitives/numeric-id.schema.test.ts +32 -0
  229. package/src/primitives/numeric-id.schema.ts +13 -0
  230. package/src/primitives/slug.schema.test.ts +101 -0
  231. package/src/primitives/slug.schema.ts +41 -0
  232. package/src/primitives/uuid.schema.test.ts +45 -0
  233. package/src/primitives/uuid.schema.ts +12 -0
  234. package/src/primitives/wikidata-id.schema.test.ts +51 -0
  235. package/src/primitives/wikidata-id.schema.ts +16 -0
  236. package/src/time/README.md +220 -0
  237. package/src/time/boundary-enforcement.test.ts +130 -0
  238. package/src/time/boundary-enforcement.ts +59 -0
  239. package/src/time/bounded-time.schema.test.ts +294 -0
  240. package/src/time/bounded-time.schema.ts +111 -0
  241. package/src/time/flexible-time-parser.test.ts +586 -0
  242. package/src/time/flexible-time-parser.ts +122 -0
  243. package/src/time/flexible-time.schema.test.ts +243 -0
  244. package/src/time/flexible-time.schema.ts +43 -0
  245. package/src/time/is-relative-time.test.ts +23 -0
  246. package/src/time/is-relative-time.ts +9 -0
  247. package/src/time/iso8601.schema.ts +29 -0
  248. package/src/time/iso8601.types.test.ts +112 -0
  249. package/src/time/iso8601.types.ts +21 -0
  250. package/src/time/parse-relative-time.test.ts +49 -0
  251. package/src/time/parse-relative-time.ts +50 -0
  252. package/src/time/relative-time.schema.test.ts +23 -0
  253. package/src/time/relative-time.schema.ts +38 -0
  254. package/src/time/since-parameter.schema.test.ts +59 -0
  255. package/src/time/since-parameter.schema.ts +69 -0
  256. package/src/time/time-helpers.test.ts +263 -0
  257. package/src/time/time-helpers.ts +78 -0
  258. package/src/time/time-schemas.test.ts +181 -0
  259. package/src/time/time-schemas.ts +42 -0
  260. package/src/time/time.schema.test.ts +237 -0
  261. package/src/time/timezone-independence.test.ts +188 -0
  262. package/src/time/timezone.types.test.ts +55 -0
  263. package/src/time/timezone.types.ts +22 -0
  264. package/tsconfig.json +26 -0
@@ -0,0 +1,5 @@
1
+ import { z } from "zod";
2
+ import { OkaySchema } from "./okay.schema";
3
+ export const ResultSchema = OkaySchema.extend({
4
+ timestamp: z.string().transform((value) => new Date(value).toISOString()),
5
+ });
@@ -0,0 +1,21 @@
1
+ import { z } from "zod";
2
+ export declare const ResultsSchema: z.ZodObject<{
3
+ status: z.ZodNumber;
4
+ message: z.ZodOptional<z.ZodString>;
5
+ } & {
6
+ timestamp: z.ZodEffects<z.ZodString, string, string>;
7
+ } & {
8
+ results: z.ZodNumber;
9
+ }, "strict", z.ZodTypeAny, {
10
+ status: number;
11
+ timestamp: string;
12
+ results: number;
13
+ message?: string | undefined;
14
+ }, {
15
+ status: number;
16
+ timestamp: string;
17
+ results: number;
18
+ message?: string | undefined;
19
+ }>;
20
+ export type Results = z.infer<typeof ResultsSchema>;
21
+ //# sourceMappingURL=results.schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"results.schema.d.ts","sourceRoot":"","sources":["../../src/api-schemas/results.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;EAExB,CAAC;AAEH,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { z } from "zod";
2
+ import { ResultSchema } from "./result.schema";
3
+ export const ResultsSchema = ResultSchema.extend({
4
+ results: z.number(),
5
+ });
@@ -0,0 +1,7 @@
1
+ export declare function getCorrelationId(request: {
2
+ headers?: Headers | {
3
+ get?: (name: string) => string | null;
4
+ [key: string]: unknown;
5
+ };
6
+ }): string;
7
+ //# sourceMappingURL=get-correlation-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-correlation-id.d.ts","sourceRoot":"","sources":["../../../src/helpers/correlation/get-correlation-id.ts"],"names":[],"mappings":"AAEA,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IACxC,OAAO,CAAC,EACJ,OAAO,GACP;QAAE,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;CACvE,GAAG,MAAM,CAeT"}
@@ -0,0 +1,16 @@
1
+ import { getHeader } from "./get-header";
2
+ export function getCorrelationId(request) {
3
+ const existingId = getHeader(request, "x-correlation-id");
4
+ if (existingId && typeof existingId === "string" && existingId.length > 0) {
5
+ return existingId;
6
+ }
7
+ // Use crypto for secure random ID generation
8
+ const bytes = new Uint8Array(8);
9
+ crypto.getRandomValues(bytes);
10
+ let randomPart = "";
11
+ for (const byte of bytes) {
12
+ randomPart += byte.toString(16).padStart(2, "0");
13
+ }
14
+ const timestamp = Date.now().toString(16);
15
+ return `${timestamp}-${randomPart}`;
16
+ }
@@ -0,0 +1,7 @@
1
+ export declare function getHeader(request: {
2
+ headers?: Headers | {
3
+ get?: (name: string) => string | null;
4
+ [key: string]: unknown;
5
+ };
6
+ }, name: string): string | undefined;
7
+ //# sourceMappingURL=get-header.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-header.d.ts","sourceRoot":"","sources":["../../../src/helpers/correlation/get-header.ts"],"names":[],"mappings":"AAAA,wBAAgB,SAAS,CACvB,OAAO,EAAE;IACP,OAAO,CAAC,EACJ,OAAO,GACP;QAAE,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;QAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC;CACvE,EACD,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,SAAS,CAapB"}
@@ -0,0 +1,11 @@
1
+ export function getHeader(request, name) {
2
+ const headers = request?.headers;
3
+ if (!headers)
4
+ return undefined;
5
+ if (typeof headers.get === "function") {
6
+ const v = headers.get(name);
7
+ return v === null ? undefined : v;
8
+ }
9
+ const key = Object.keys(headers).find((k) => k.toLowerCase() === name.toLowerCase());
10
+ return key ? String(headers[key]) : undefined;
11
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Detect MIME type from file magic bytes (file signature)
3
+ *
4
+ * This function performs magic byte detection to determine the actual
5
+ * file type regardless of file extension or Content-Type header.
6
+ *
7
+ * @param buffer - File content as Buffer
8
+ * @returns Detected MIME type or undefined if unknown
9
+ */
10
+ export declare function detectMimeType(buffer: Buffer): string | undefined;
11
+ //# sourceMappingURL=detect-mime-type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect-mime-type.d.ts","sourceRoot":"","sources":["../../src/helpers/detect-mime-type.ts"],"names":[],"mappings":"AAKA;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CA+BjE"}
@@ -0,0 +1,40 @@
1
+ import { detectImageMimeType } from "./mime-types/detect-image-mime-type";
2
+ import { detectOleMimeType } from "./mime-types/detect-ole-mime-type";
3
+ import { detectPdfMimeType } from "./mime-types/detect-pdf-mime-type";
4
+ import { detectZipMimeType } from "./mime-types/detect-zip-mime-type";
5
+ /**
6
+ * Detect MIME type from file magic bytes (file signature)
7
+ *
8
+ * This function performs magic byte detection to determine the actual
9
+ * file type regardless of file extension or Content-Type header.
10
+ *
11
+ * @param buffer - File content as Buffer
12
+ * @returns Detected MIME type or undefined if unknown
13
+ */
14
+ export function detectMimeType(buffer) {
15
+ if (!buffer || buffer.length < 4) {
16
+ return undefined;
17
+ }
18
+ // Check for image formats
19
+ const imageType = detectImageMimeType(buffer);
20
+ if (imageType) {
21
+ return imageType;
22
+ }
23
+ // Check for document formats
24
+ // PDF
25
+ const pdfType = detectPdfMimeType(buffer);
26
+ if (pdfType) {
27
+ return pdfType;
28
+ }
29
+ // ZIP-based formats (DOCX, PPTX)
30
+ const zipType = detectZipMimeType(buffer);
31
+ if (zipType) {
32
+ return zipType;
33
+ }
34
+ // MS Office OLE2 formats (DOC, PPT)
35
+ const oleType = detectOleMimeType(buffer);
36
+ if (oleType) {
37
+ return oleType;
38
+ }
39
+ return undefined;
40
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Detect suspicious patterns from a request body without logging or exposing the content.
3
+ * Returns a list of pattern identifiers suitable for security logging.
4
+ *
5
+ * This helper is intentionally conservative and only flags common patterns.
6
+ */
7
+ export declare function detectSuspiciousPatternsFromBody(body: unknown): string[];
8
+ //# sourceMappingURL=detect-suspicious-patterns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect-suspicious-patterns.d.ts","sourceRoot":"","sources":["../../src/helpers/detect-suspicious-patterns.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,EAAE,CAkDxE"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Detect suspicious patterns from a request body without logging or exposing the content.
3
+ * Returns a list of pattern identifiers suitable for security logging.
4
+ *
5
+ * This helper is intentionally conservative and only flags common patterns.
6
+ */
7
+ export function detectSuspiciousPatternsFromBody(body) {
8
+ const patterns = [];
9
+ const checkString = (s) => {
10
+ const lower = s.toLowerCase();
11
+ // XSS/HTML injection indicators
12
+ if (lower.includes("<script"))
13
+ patterns.push("html.script_tag");
14
+ // Basic SQLi strings
15
+ if (lower.includes("union select"))
16
+ patterns.push("sql.union_select");
17
+ if (lower.includes("drop table"))
18
+ patterns.push("sql.drop_table");
19
+ // Prompt injection style phrases
20
+ if (lower.includes("ignore previous") ||
21
+ lower.includes("disregard previous")) {
22
+ patterns.push("prompt.injection.language");
23
+ }
24
+ // Embedded external URLs (often used in attacks/phishing)
25
+ if (lower.includes("http://") || lower.includes("https://")) {
26
+ patterns.push("url.embedded");
27
+ }
28
+ };
29
+ if (typeof body === "string") {
30
+ checkString(body);
31
+ }
32
+ else if (body && typeof body === "object") {
33
+ const walk = (object, depth = 0) => {
34
+ if (depth > 2)
35
+ return; // limit traversal depth
36
+ for (const v of Object.values(object)) {
37
+ if (typeof v === "string") {
38
+ checkString(v);
39
+ }
40
+ else if (Array.isArray(v)) {
41
+ for (const x of v.slice(0, 10)) {
42
+ if (typeof x === "string") {
43
+ checkString(x);
44
+ }
45
+ }
46
+ }
47
+ else if (v && typeof v === "object") {
48
+ walk(v, depth + 1);
49
+ }
50
+ }
51
+ };
52
+ walk(body);
53
+ }
54
+ return [...new Set(patterns)];
55
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Constants for file handling in API endpoints
3
+ * Defines file size limits
4
+ */
5
+ /**
6
+ * Maximum file size in bytes (10 MB)
7
+ */
8
+ export declare const DEFAULT_MAX_FILE_SIZE: number;
9
+ /**
10
+ * Allowed image MIME types for image eventification
11
+ */
12
+ export declare const IMAGE_MIME_TYPES: readonly ["image/jpeg", "image/png", "image/gif", "image/webp"];
13
+ /**
14
+ * PDF MIME type for PDF image extraction
15
+ */
16
+ export declare const PDF_MIME_TYPES: readonly ["application/pdf"];
17
+ /**
18
+ * Combined MIME types for image endpoint (images + PDF)
19
+ * PDF files are converted to images before processing
20
+ */
21
+ export declare const IMAGE_ENDPOINT_MIME_TYPES: readonly ["image/jpeg", "image/png", "image/gif", "image/webp", "application/pdf"];
22
+ /**
23
+ * Allowed document MIME types for document eventification
24
+ * Supports PDF, DOC, DOCX, PPT, PPTX
25
+ */
26
+ export declare const DOCUMENT_MIME_TYPES: readonly ["application/pdf", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", "application/vnd.ms-powerpoint", "application/vnd.openxmlformats-officedocument.presentationml.presentation"];
27
+ export type ImageMimeType = (typeof IMAGE_MIME_TYPES)[number];
28
+ export type PdfMimeType = (typeof PDF_MIME_TYPES)[number];
29
+ export type ImageEndpointMimeType = (typeof IMAGE_ENDPOINT_MIME_TYPES)[number];
30
+ export type DocumentMimeType = (typeof DOCUMENT_MIME_TYPES)[number];
31
+ export type AllowedMimeType = ImageMimeType | DocumentMimeType | PdfMimeType;
32
+ //# sourceMappingURL=eventify-constants.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eventify-constants.types.d.ts","sourceRoot":"","sources":["../../src/helpers/eventify-constants.types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,eAAO,MAAM,qBAAqB,QAAmB,CAAC;AAEtD;;GAEG;AACH,eAAO,MAAM,gBAAgB,iEAKnB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,cAAc,8BAA+B,CAAC;AAE3D;;;GAGG;AACH,eAAO,MAAM,yBAAyB,oFAG5B,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,mBAAmB,6OAMtB,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAC9D,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAC1D,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC;AAC/E,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AACpE,MAAM,MAAM,eAAe,GAAG,aAAa,GAAG,gBAAgB,GAAG,WAAW,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Constants for file handling in API endpoints
3
+ * Defines file size limits
4
+ */
5
+ /**
6
+ * Maximum file size in bytes (10 MB)
7
+ */
8
+ export const DEFAULT_MAX_FILE_SIZE = 10 * 1024 * 1024; // 10 MB
9
+ /**
10
+ * Allowed image MIME types for image eventification
11
+ */
12
+ export const IMAGE_MIME_TYPES = [
13
+ 'image/jpeg',
14
+ 'image/png',
15
+ 'image/gif',
16
+ 'image/webp',
17
+ ];
18
+ /**
19
+ * PDF MIME type for PDF image extraction
20
+ */
21
+ export const PDF_MIME_TYPES = ['application/pdf'];
22
+ /**
23
+ * Combined MIME types for image endpoint (images + PDF)
24
+ * PDF files are converted to images before processing
25
+ */
26
+ export const IMAGE_ENDPOINT_MIME_TYPES = [
27
+ ...IMAGE_MIME_TYPES,
28
+ ...PDF_MIME_TYPES,
29
+ ];
30
+ /**
31
+ * Allowed document MIME types for document eventification
32
+ * Supports PDF, DOC, DOCX, PPT, PPTX
33
+ */
34
+ export const DOCUMENT_MIME_TYPES = [
35
+ 'application/pdf',
36
+ 'application/msword', // DOC
37
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // DOCX
38
+ 'application/vnd.ms-powerpoint', // PPT
39
+ 'application/vnd.openxmlformats-officedocument.presentationml.presentation', // PPTX
40
+ ];
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Computes a deterministic SHA-256 hash from binary data
3
+ *
4
+ * Algorithm: SHA-256 (non-reversible cryptographic hash)
5
+ * Output: Hex-encoded string (64 characters)
6
+ *
7
+ * The same binary input will always produce the same hash output,
8
+ * making it suitable for content-based deduplication and caching.
9
+ *
10
+ * @param data Binary data as Buffer or Uint8Array
11
+ * @returns Hex-encoded SHA-256 hash string (64 characters)
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const fileBytes = Buffer.from('example file content');
16
+ * const hash = hashBinary(fileBytes);
17
+ * // hash = "50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c"
18
+ * ```
19
+ */
20
+ export declare function hashBinary(data: Buffer | Uint8Array): string;
21
+ //# sourceMappingURL=hash-binary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash-binary.d.ts","sourceRoot":"","sources":["../../src/helpers/hash-binary.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAQ5D"}
@@ -0,0 +1,28 @@
1
+ import { createHash } from 'node:crypto';
2
+ /**
3
+ * Computes a deterministic SHA-256 hash from binary data
4
+ *
5
+ * Algorithm: SHA-256 (non-reversible cryptographic hash)
6
+ * Output: Hex-encoded string (64 characters)
7
+ *
8
+ * The same binary input will always produce the same hash output,
9
+ * making it suitable for content-based deduplication and caching.
10
+ *
11
+ * @param data Binary data as Buffer or Uint8Array
12
+ * @returns Hex-encoded SHA-256 hash string (64 characters)
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * const fileBytes = Buffer.from('example file content');
17
+ * const hash = hashBinary(fileBytes);
18
+ * // hash = "50d858e0985ecc7f60418aaf0cc5ab587f42c2570a884095a9e8ccacd0f6545c"
19
+ * ```
20
+ */
21
+ export function hashBinary(data) {
22
+ // Convert Uint8Array to Buffer if needed
23
+ const buffer = Buffer.isBuffer(data) ? data : Buffer.from(data);
24
+ // Compute SHA-256 hash and encode as hex
25
+ const hash = createHash('sha256');
26
+ hash.update(buffer);
27
+ return hash.digest('hex');
28
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Detect image MIME types from magic bytes
3
+ */
4
+ export declare function detectImageMimeType(buffer: Buffer): string | undefined;
5
+ //# sourceMappingURL=detect-image-mime-type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect-image-mime-type.d.ts","sourceRoot":"","sources":["../../../src/helpers/mime-types/detect-image-mime-type.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CA8CtE"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Detect image MIME types from magic bytes
3
+ */
4
+ export function detectImageMimeType(buffer) {
5
+ if (buffer.length < 4) {
6
+ return undefined;
7
+ }
8
+ // JPEG: FF D8 FF E0
9
+ if (buffer[0] === 0xFF && buffer[1] === 0xD8 && buffer[2] === 0xFF && buffer[3] === 0xE0) {
10
+ return "image/jpeg";
11
+ }
12
+ // PNG: 89 50 4E 47 0D 0A 1A 0A
13
+ if (buffer.length >= 8 &&
14
+ buffer[0] === 0x89 &&
15
+ buffer[1] === 0x50 &&
16
+ buffer[2] === 0x4E &&
17
+ buffer[3] === 0x47 &&
18
+ buffer[4] === 0x0D &&
19
+ buffer[5] === 0x0A &&
20
+ buffer[6] === 0x1A &&
21
+ buffer[7] === 0x0A) {
22
+ return "image/png";
23
+ }
24
+ // GIF: 47 49 46 (GIF87a or GIF89a)
25
+ if (buffer[0] === 0x47 && buffer[1] === 0x49 && buffer[2] === 0x46) {
26
+ return "image/gif";
27
+ }
28
+ // WebP: RIFF....WEBP (52 49 46 46 ... 57 45 42 50)
29
+ if (buffer.length >= 12 &&
30
+ buffer[0] === 0x52 &&
31
+ buffer[1] === 0x49 &&
32
+ buffer[2] === 0x46 &&
33
+ buffer[3] === 0x46 &&
34
+ buffer[8] === 0x57 &&
35
+ buffer[9] === 0x45 &&
36
+ buffer[10] === 0x42 &&
37
+ buffer[11] === 0x50) {
38
+ return "image/webp";
39
+ }
40
+ return undefined;
41
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Detect OLE2 (legacy Office) formats from magic bytes
3
+ * Detects DOC, PPT, and XLS files which use OLE2 container format
4
+ */
5
+ export declare function detectOleMimeType(buffer: Buffer): string | undefined;
6
+ //# sourceMappingURL=detect-ole-mime-type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect-ole-mime-type.d.ts","sourceRoot":"","sources":["../../../src/helpers/mime-types/detect-ole-mime-type.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAuCpE"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Detect OLE2 (legacy Office) formats from magic bytes
3
+ * Detects DOC, PPT, and XLS files which use OLE2 container format
4
+ */
5
+ export function detectOleMimeType(buffer) {
6
+ if (buffer.length < 8) {
7
+ return undefined;
8
+ }
9
+ // OLE2 signature: D0 CF 11 E0 A1 B1 1A E1
10
+ if (!(buffer[0] === 0xD0 &&
11
+ buffer[1] === 0xCF &&
12
+ buffer[2] === 0x11 &&
13
+ buffer[3] === 0xE0 &&
14
+ buffer[4] === 0xA1 &&
15
+ buffer[5] === 0xB1 &&
16
+ buffer[6] === 0x1A &&
17
+ buffer[7] === 0xE1)) {
18
+ return undefined;
19
+ }
20
+ // If it's OLE2, try to detect Office type by looking for content indicators
21
+ // Look for "PowerPoint Document" or "Word.Document" in buffer
22
+ const bufferString = buffer.toString("utf8", 0, Math.min(buffer.length, 1024));
23
+ if (bufferString.includes("PowerPoint Document")) {
24
+ return "application/vnd.ms-powerpoint";
25
+ }
26
+ if (bufferString.includes("Word.Document") || bufferString.includes("Microsoft Word")) {
27
+ return "application/msword";
28
+ }
29
+ if (bufferString.includes("Workbook") || bufferString.includes("Excel")) {
30
+ return "application/vnd.ms-excel";
31
+ }
32
+ // Default OLE2 MIME type is Word document
33
+ return "application/msword";
34
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Detect PDF MIME type from magic bytes
3
+ */
4
+ export declare function detectPdfMimeType(buffer: Buffer): string | undefined;
5
+ //# sourceMappingURL=detect-pdf-mime-type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect-pdf-mime-type.d.ts","sourceRoot":"","sources":["../../../src/helpers/mime-types/detect-pdf-mime-type.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAWpE"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Detect PDF MIME type from magic bytes
3
+ */
4
+ export function detectPdfMimeType(buffer) {
5
+ if (buffer.length < 4) {
6
+ return undefined;
7
+ }
8
+ // PDF: 25 50 44 46 (%PDF)
9
+ if (buffer[0] === 0x25 && buffer[1] === 0x50 && buffer[2] === 0x44 && buffer[3] === 0x46) {
10
+ return "application/pdf";
11
+ }
12
+ return undefined;
13
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Detect ZIP-based Office formats from magic bytes
3
+ * Detects DOCX, PPTX by checking ZIP signature followed by Office content
4
+ */
5
+ export declare function detectZipMimeType(buffer: Buffer): string | undefined;
6
+ //# sourceMappingURL=detect-zip-mime-type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect-zip-mime-type.d.ts","sourceRoot":"","sources":["../../../src/helpers/mime-types/detect-zip-mime-type.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAuBpE"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Detect ZIP-based Office formats from magic bytes
3
+ * Detects DOCX, PPTX by checking ZIP signature followed by Office content
4
+ */
5
+ export function detectZipMimeType(buffer) {
6
+ if (buffer.length < 4) {
7
+ return undefined;
8
+ }
9
+ // ZIP signature: 50 4B 03 04
10
+ if (!(buffer[0] === 0x50 && buffer[1] === 0x4B && buffer[2] === 0x03 && buffer[3] === 0x04)) {
11
+ return undefined;
12
+ }
13
+ // If it's a ZIP, check for Office format indicators
14
+ // Look for word/ or ppt/ in the buffer to distinguish Office formats
15
+ const bufferString = buffer.toString("utf8", 30, Math.min(buffer.length, 8192)).toLowerCase();
16
+ if (bufferString.includes("word/")) {
17
+ return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
18
+ }
19
+ if (bufferString.includes("ppt/")) {
20
+ return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
21
+ }
22
+ return undefined;
23
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Validates that a string parameter does not contain suspicious patterns
3
+ * that could indicate injection attacks or other security threats.
4
+ */
5
+ export declare function validateNoSuspiciousPatterns(value: string, parameterName: string): string;
6
+ //# sourceMappingURL=parameter-validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parameter-validation.d.ts","sourceRoot":"","sources":["../../src/helpers/parameter-validation.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,GACpB,MAAM,CAkBR"}
@@ -0,0 +1,19 @@
1
+ import { getLogger } from "@schafevormfenster/logging";
2
+ import { detectSuspiciousPatternsFromBody } from "./detect-suspicious-patterns";
3
+ const log = getLogger("rest.helpers.parameter-validation");
4
+ /**
5
+ * Validates that a string parameter does not contain suspicious patterns
6
+ * that could indicate injection attacks or other security threats.
7
+ */
8
+ export function validateNoSuspiciousPatterns(value, parameterName) {
9
+ const suspiciousPatterns = detectSuspiciousPatternsFromBody(value);
10
+ if (suspiciousPatterns.length > 0) {
11
+ log.error({
12
+ parameterName,
13
+ suspiciousPatterns,
14
+ error: `Parameter '${parameterName}' contains suspicious patterns`,
15
+ }, `Parameter '${parameterName}' contains suspicious patterns: ${suspiciousPatterns.join(", ")}`);
16
+ throw new Error(`Parameter '${parameterName}' contains suspicious patterns: ${suspiciousPatterns.join(", ")}`);
17
+ }
18
+ return value;
19
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Zod schema for validating location parameter in findbyaddress endpoint.
3
+ * Checks for minimum length and suspicious patterns.
4
+ */
5
+ export declare const LocationParameterSchema: any;
6
+ /**
7
+ * Zod schema for validating slug parameter in community slug endpoint.
8
+ * Checks for length between 2-150 characters and suspicious patterns.
9
+ */
10
+ export declare const SlugParameterSchema: any;
11
+ /**
12
+ * Zod schema for validating ID parameter in community ID endpoint.
13
+ * Checks that ID contains only numbers and is between 3-20 characters long.
14
+ */
15
+ export declare const NumericIdParameterSchema: any;
16
+ //# sourceMappingURL=parameter-validation.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parameter-validation.types.d.ts","sourceRoot":"","sources":["../../src/helpers/parameter-validation.types.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,eAAO,MAAM,uBAAuB,KAWjC,CAAC;AAEJ;;;GAGG;AACH,eAAO,MAAM,mBAAmB,KAY7B,CAAC;AAEJ;;;GAGG;AACH,eAAO,MAAM,wBAAwB,KAIuB,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { z } from "zod";
2
+ import { validateNoSuspiciousPatterns } from "./parameter-validation";
3
+ /**
4
+ * Zod schema for validating location parameter in findbyaddress endpoint.
5
+ * Checks for minimum length and suspicious patterns.
6
+ */
7
+ export const LocationParameterSchema = z
8
+ .string()
9
+ .min(2, "Location must be at least 2 characters long")
10
+ .refine((value) => {
11
+ validateNoSuspiciousPatterns(value, "location");
12
+ return true;
13
+ }, {
14
+ message: "Location parameter contains suspicious patterns that are not allowed",
15
+ });
16
+ /**
17
+ * Zod schema for validating slug parameter in community slug endpoint.
18
+ * Checks for length between 2-150 characters and suspicious patterns.
19
+ */
20
+ export const SlugParameterSchema = z
21
+ .string()
22
+ .min(2, "Slug must be at least 2 characters long")
23
+ .max(150, "Slug must not exceed 150 characters")
24
+ .refine((value) => {
25
+ validateNoSuspiciousPatterns(value, "slug");
26
+ return true;
27
+ }, {
28
+ message: "Slug parameter contains suspicious patterns that are not allowed",
29
+ });
30
+ /**
31
+ * Zod schema for validating ID parameter in community ID endpoint.
32
+ * Checks that ID contains only numbers and is between 3-20 characters long.
33
+ */
34
+ export const NumericIdParameterSchema = z
35
+ .string()
36
+ .min(3, "ID must be at least 3 characters long")
37
+ .max(20, "ID must not exceed 20 characters")
38
+ .regex(/^\d+$/, "ID must contain only numeric characters");
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Build a consistent set of headers for unauthorized API responses, including
3
+ * security headers and correlation id propagation.
4
+ */
5
+ export declare function buildApiUnauthorizedHeaders(correlationId: string): Record<string, string>;
6
+ //# sourceMappingURL=build-api-unauthorized-headers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-api-unauthorized-headers.d.ts","sourceRoot":"","sources":["../../../src/helpers/response-headers/build-api-unauthorized-headers.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,MAAM,GACpB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAmBxB"}
@@ -0,0 +1,23 @@
1
+ import { getApiSecurityHeaders } from "@schafevormfenster/security";
2
+ import { resolveEnvironment } from "./resolve-environment";
3
+ /**
4
+ * Build a consistent set of headers for unauthorized API responses, including
5
+ * security headers and correlation id propagation.
6
+ */
7
+ export function buildApiUnauthorizedHeaders(correlationId) {
8
+ const environment = resolveEnvironment();
9
+ const securityHeaders = getApiSecurityHeaders({
10
+ environment,
11
+ enforceHTTPS: environment !== "development",
12
+ allowEmbedding: false,
13
+ });
14
+ const result = {
15
+ "content-type": "application/json",
16
+ "Cache-Control": "no-store",
17
+ "x-correlation-id": correlationId,
18
+ };
19
+ for (const h of securityHeaders) {
20
+ result[h.key] = h.value;
21
+ }
22
+ return result;
23
+ }