@bgord/bun 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/dist/api-key-shield.d.ts +14 -13
  2. package/dist/api-key-shield.d.ts.map +1 -0
  3. package/dist/api-key-shield.js +19 -0
  4. package/dist/api-key-shield.js.map +1 -0
  5. package/dist/api-version.d.ts +6 -5
  6. package/dist/api-version.d.ts.map +1 -0
  7. package/dist/api-version.js +12 -0
  8. package/dist/api-version.js.map +1 -0
  9. package/dist/auth-shield.d.ts +31 -29
  10. package/dist/auth-shield.d.ts.map +1 -0
  11. package/dist/auth-shield.js +83 -0
  12. package/dist/auth-shield.js.map +1 -0
  13. package/dist/build-info-repository.d.ts +5 -3
  14. package/dist/build-info-repository.d.ts.map +1 -0
  15. package/dist/build-info-repository.js +18 -0
  16. package/dist/build-info-repository.js.map +1 -0
  17. package/dist/cache-resolver.d.ts +46 -0
  18. package/dist/cache-resolver.d.ts.map +1 -0
  19. package/dist/cache-resolver.js +44 -0
  20. package/dist/cache-resolver.js.map +1 -0
  21. package/dist/cache-response.d.ts +9 -12
  22. package/dist/cache-response.d.ts.map +1 -0
  23. package/dist/cache-response.js +25 -0
  24. package/dist/cache-response.js.map +1 -0
  25. package/dist/cache-static-files.d.ts +9 -8
  26. package/dist/cache-static-files.d.ts.map +1 -0
  27. package/dist/cache-static-files.js +25 -0
  28. package/dist/cache-static-files.js.map +1 -0
  29. package/dist/context.d.ts +14 -9
  30. package/dist/context.d.ts.map +1 -0
  31. package/dist/context.js +11 -0
  32. package/dist/context.js.map +1 -0
  33. package/dist/correlation-id.d.ts +4 -0
  34. package/dist/correlation-id.d.ts.map +1 -0
  35. package/dist/correlation-id.js +3 -0
  36. package/dist/correlation-id.js.map +1 -0
  37. package/dist/download-file.d.ts +13 -12
  38. package/dist/download-file.d.ts.map +1 -0
  39. package/dist/download-file.js +11 -0
  40. package/dist/download-file.js.map +1 -0
  41. package/dist/etag-extractor.d.ts +11 -15
  42. package/dist/etag-extractor.d.ts.map +1 -0
  43. package/dist/etag-extractor.js +18 -0
  44. package/dist/etag-extractor.js.map +1 -0
  45. package/dist/file-uploader.d.ts +13 -12
  46. package/dist/file-uploader.d.ts.map +1 -0
  47. package/dist/file-uploader.js +35 -0
  48. package/dist/file-uploader.js.map +1 -0
  49. package/dist/graceful-shutdown.d.ts +7 -6
  50. package/dist/graceful-shutdown.d.ts.map +1 -0
  51. package/dist/graceful-shutdown.js +32 -0
  52. package/dist/graceful-shutdown.js.map +1 -0
  53. package/dist/healthcheck.d.ts +22 -20
  54. package/dist/healthcheck.d.ts.map +1 -0
  55. package/dist/healthcheck.js +35 -0
  56. package/dist/healthcheck.js.map +1 -0
  57. package/dist/http-logger.d.ts +7 -7
  58. package/dist/http-logger.d.ts.map +1 -0
  59. package/dist/http-logger.js +89 -0
  60. package/dist/http-logger.js.map +1 -0
  61. package/dist/i18n.d.ts +22 -26
  62. package/dist/i18n.d.ts.map +1 -0
  63. package/dist/i18n.js +35 -0
  64. package/dist/i18n.js.map +1 -0
  65. package/dist/image-processor.d.ts +5 -4
  66. package/dist/image-processor.d.ts.map +1 -0
  67. package/dist/image-processor.js +5 -0
  68. package/dist/image-processor.js.map +1 -0
  69. package/dist/index.d.ts +37 -17
  70. package/dist/index.d.ts.map +1 -0
  71. package/dist/index.js +37 -0
  72. package/dist/index.js.map +1 -0
  73. package/dist/jobs.d.ts +1 -0
  74. package/dist/jobs.d.ts.map +1 -0
  75. package/dist/jobs.js +72 -0
  76. package/dist/jobs.js.map +1 -0
  77. package/dist/logger.d.ts +23 -7
  78. package/dist/logger.d.ts.map +1 -0
  79. package/dist/logger.js +87 -0
  80. package/dist/logger.js.map +1 -0
  81. package/dist/mailer.d.ts +10 -1
  82. package/dist/mailer.d.ts.map +1 -0
  83. package/dist/mailer.js +27 -0
  84. package/dist/mailer.js.map +1 -0
  85. package/dist/memory-consumption.d.ts +3 -2
  86. package/dist/memory-consumption.d.ts.map +1 -0
  87. package/dist/memory-consumption.js +8 -0
  88. package/dist/memory-consumption.js.map +1 -0
  89. package/dist/new-uuid.d.ts +4 -0
  90. package/dist/new-uuid.d.ts.map +1 -0
  91. package/dist/new-uuid.js +6 -0
  92. package/dist/new-uuid.js.map +1 -0
  93. package/dist/node-env.vo.d.ts +9 -0
  94. package/dist/node-env.vo.d.ts.map +1 -0
  95. package/dist/node-env.vo.js +10 -0
  96. package/dist/node-env.vo.js.map +1 -0
  97. package/dist/passwords.d.ts +21 -0
  98. package/dist/passwords.d.ts.map +1 -0
  99. package/dist/passwords.js +42 -0
  100. package/dist/passwords.js.map +1 -0
  101. package/dist/path.d.ts +4 -0
  102. package/dist/path.d.ts.map +1 -0
  103. package/dist/path.js +3 -0
  104. package/dist/path.js.map +1 -0
  105. package/dist/port.d.ts +4 -0
  106. package/dist/port.d.ts.map +1 -0
  107. package/dist/port.js +3 -0
  108. package/dist/port.js.map +1 -0
  109. package/dist/prerequisites/binary.d.ts +4 -3
  110. package/dist/prerequisites/binary.d.ts.map +1 -0
  111. package/dist/prerequisites/binary.js +29 -0
  112. package/dist/prerequisites/binary.js.map +1 -0
  113. package/dist/prerequisites/bun.d.ts +7 -4
  114. package/dist/prerequisites/bun.d.ts.map +1 -0
  115. package/dist/prerequisites/bun.js +18 -0
  116. package/dist/prerequisites/bun.js.map +1 -0
  117. package/dist/prerequisites/index.d.ts +17 -0
  118. package/dist/prerequisites/index.d.ts.map +1 -0
  119. package/dist/prerequisites/index.js +17 -0
  120. package/dist/prerequisites/index.js.map +1 -0
  121. package/dist/prerequisites/jobs.d.ts +4 -2
  122. package/dist/prerequisites/jobs.d.ts.map +1 -0
  123. package/dist/prerequisites/jobs.js +16 -0
  124. package/dist/prerequisites/jobs.js.map +1 -0
  125. package/dist/prerequisites/log-file.d.ts +15 -0
  126. package/dist/prerequisites/log-file.d.ts.map +1 -0
  127. package/dist/prerequisites/log-file.js +22 -0
  128. package/dist/prerequisites/log-file.js.map +1 -0
  129. package/dist/prerequisites/mailer.d.ts +4 -2
  130. package/dist/prerequisites/mailer.d.ts.map +1 -0
  131. package/dist/prerequisites/mailer.js +21 -0
  132. package/dist/prerequisites/mailer.js.map +1 -0
  133. package/dist/prerequisites/memory.d.ts +6 -4
  134. package/dist/prerequisites/memory.d.ts.map +1 -0
  135. package/dist/prerequisites/memory.js +20 -0
  136. package/dist/prerequisites/memory.js.map +1 -0
  137. package/dist/prerequisites/node.d.ts +6 -4
  138. package/dist/prerequisites/node.d.ts.map +1 -0
  139. package/dist/prerequisites/node.js +23 -0
  140. package/dist/prerequisites/node.js.map +1 -0
  141. package/dist/prerequisites/outside-connectivity.d.ts +4 -2
  142. package/dist/prerequisites/outside-connectivity.d.ts.map +1 -0
  143. package/dist/prerequisites/outside-connectivity.js +21 -0
  144. package/dist/prerequisites/outside-connectivity.js.map +1 -0
  145. package/dist/prerequisites/path.d.ts +4 -2
  146. package/dist/prerequisites/path.d.ts.map +1 -0
  147. package/dist/prerequisites/path.js +26 -0
  148. package/dist/prerequisites/path.js.map +1 -0
  149. package/dist/prerequisites/port.d.ts +6 -4
  150. package/dist/prerequisites/port.d.ts.map +1 -0
  151. package/dist/prerequisites/port.js +26 -0
  152. package/dist/prerequisites/port.js.map +1 -0
  153. package/dist/prerequisites/ram.d.ts +6 -4
  154. package/dist/prerequisites/ram.d.ts.map +1 -0
  155. package/dist/prerequisites/ram.js +23 -0
  156. package/dist/prerequisites/ram.js.map +1 -0
  157. package/dist/prerequisites/self.d.ts +4 -2
  158. package/dist/prerequisites/self.d.ts.map +1 -0
  159. package/dist/prerequisites/self.js +15 -0
  160. package/dist/prerequisites/self.js.map +1 -0
  161. package/dist/prerequisites/space.d.ts +6 -4
  162. package/dist/prerequisites/space.d.ts.map +1 -0
  163. package/dist/prerequisites/space.js +26 -0
  164. package/dist/prerequisites/space.js.map +1 -0
  165. package/dist/prerequisites/ssl-certificate-expiry.d.ts +4 -2
  166. package/dist/prerequisites/ssl-certificate-expiry.d.ts.map +1 -0
  167. package/dist/prerequisites/ssl-certificate-expiry.js +24 -0
  168. package/dist/prerequisites/ssl-certificate-expiry.js.map +1 -0
  169. package/dist/prerequisites/timezone-utc.d.ts +6 -4
  170. package/dist/prerequisites/timezone-utc.d.ts.map +1 -0
  171. package/dist/prerequisites/timezone-utc.js +22 -0
  172. package/dist/prerequisites/timezone-utc.js.map +1 -0
  173. package/dist/prerequisites/translations.d.ts +4 -2
  174. package/dist/prerequisites/translations.d.ts.map +1 -0
  175. package/dist/prerequisites/translations.js +59 -0
  176. package/dist/prerequisites/translations.js.map +1 -0
  177. package/dist/prerequisites.d.ts +2 -0
  178. package/dist/prerequisites.d.ts.map +1 -0
  179. package/dist/prerequisites.js +83 -0
  180. package/dist/prerequisites.js.map +1 -0
  181. package/dist/rate-limit-shield.d.ts +9 -8
  182. package/dist/rate-limit-shield.d.ts.map +1 -0
  183. package/dist/rate-limit-shield.js +18 -0
  184. package/dist/rate-limit-shield.js.map +1 -0
  185. package/dist/session-id.d.ts +7 -0
  186. package/dist/session-id.d.ts.map +1 -0
  187. package/dist/session-id.js +10 -0
  188. package/dist/session-id.js.map +1 -0
  189. package/dist/setup.d.ts +9 -7
  190. package/dist/setup.d.ts.map +1 -0
  191. package/dist/setup.js +39 -0
  192. package/dist/setup.js.map +1 -0
  193. package/dist/time-zone-offset.d.ts +15 -14
  194. package/dist/time-zone-offset.d.ts.map +1 -0
  195. package/dist/time-zone-offset.js +22 -0
  196. package/dist/time-zone-offset.js.map +1 -0
  197. package/dist/tsconfig.tsbuildinfo +1 -0
  198. package/dist/uptime.d.ts +4 -4
  199. package/dist/uptime.d.ts.map +1 -0
  200. package/dist/uptime.js +10 -0
  201. package/dist/uptime.js.map +1 -0
  202. package/dist/username.d.ts +11 -0
  203. package/dist/username.d.ts.map +1 -0
  204. package/dist/username.js +13 -0
  205. package/dist/username.js.map +1 -0
  206. package/dist/uuid.d.ts +4 -3
  207. package/dist/uuid.d.ts.map +1 -0
  208. package/dist/uuid.js +4 -0
  209. package/dist/uuid.js.map +1 -0
  210. package/dist/weak-etag-extractor.d.ts +7 -0
  211. package/dist/weak-etag-extractor.d.ts.map +1 -0
  212. package/dist/weak-etag-extractor.js +18 -0
  213. package/dist/weak-etag-extractor.js.map +1 -0
  214. package/package.json +29 -28
  215. package/src/api-key-shield.ts +2 -2
  216. package/src/api-version.ts +3 -2
  217. package/src/auth-shield.ts +14 -23
  218. package/src/build-info-repository.ts +26 -0
  219. package/src/cache-resolver.ts +93 -0
  220. package/src/cache-response.ts +2 -5
  221. package/src/cache-static-files.ts +3 -3
  222. package/src/context.ts +9 -4
  223. package/src/correlation-id.ts +6 -0
  224. package/src/download-file.ts +2 -2
  225. package/src/etag-extractor.ts +5 -20
  226. package/src/file-uploader.ts +4 -4
  227. package/src/graceful-shutdown.ts +3 -3
  228. package/src/healthcheck.ts +30 -20
  229. package/src/http-logger.ts +10 -6
  230. package/src/i18n.ts +13 -47
  231. package/src/index.ts +26 -7
  232. package/src/jobs.ts +91 -0
  233. package/src/logger.ts +156 -0
  234. package/src/mailer.ts +48 -0
  235. package/src/memory-consumption.ts +9 -0
  236. package/src/new-uuid.ts +5 -0
  237. package/src/node-env.vo.ts +9 -0
  238. package/src/passwords.ts +55 -0
  239. package/src/path.ts +4 -0
  240. package/src/port.ts +4 -0
  241. package/src/prerequisites/binary.ts +44 -0
  242. package/src/prerequisites/bun.ts +32 -0
  243. package/src/prerequisites/index.ts +16 -0
  244. package/src/prerequisites/jobs.ts +28 -0
  245. package/src/prerequisites/log-file.ts +35 -0
  246. package/src/prerequisites/mailer.ts +32 -0
  247. package/src/prerequisites/memory.ts +34 -0
  248. package/src/prerequisites/node.ts +36 -0
  249. package/src/prerequisites/outside-connectivity.ts +31 -0
  250. package/src/prerequisites/path.ts +41 -0
  251. package/src/prerequisites/port.ts +44 -0
  252. package/src/prerequisites/ram.ts +35 -0
  253. package/src/prerequisites/self.ts +24 -0
  254. package/src/prerequisites/space.ts +39 -0
  255. package/src/prerequisites/ssl-certificate-expiry.ts +37 -0
  256. package/src/prerequisites/timezone-utc.ts +34 -0
  257. package/src/prerequisites/translations.ts +92 -0
  258. package/src/prerequisites.ts +105 -0
  259. package/src/rate-limit-shield.ts +3 -3
  260. package/src/session-id.ts +13 -0
  261. package/src/setup.ts +13 -5
  262. package/src/time-zone-offset.ts +11 -14
  263. package/src/uptime.ts +16 -0
  264. package/src/username.ts +20 -0
  265. package/src/uuid.ts +6 -0
  266. package/src/weak-etag-extractor.ts +19 -0
  267. package/src/image-processor.ts +0 -5
package/package.json CHANGED
@@ -1,45 +1,46 @@
1
1
  {
2
- "version": "0.4.0",
3
- "license": "MIT",
4
2
  "name": "@bgord/bun",
3
+ "version": "0.6.0",
4
+ "license": "MIT",
5
5
  "type": "module",
6
6
  "author": "Bartosz Gordon",
7
- "source": "src/index.ts",
7
+ "main": "./dist/index.js",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
8
10
  "exports": {
9
- "require": "./dist/bgord-bun.cjs",
10
- "default": "./dist/bgord-bun.modern.js"
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
11
13
  },
12
- "main": "./dist/bgord-bun.cjs",
13
- "module": "./dist/bgord-bun.module.js",
14
- "unpkg": "./dist/bgord-bun.umd.js",
15
- "typings": "./dist/index.d.ts",
14
+ "files": ["dist", "src"],
16
15
  "scripts": {
17
- "build": "microbundle",
16
+ "build": "tsc --build",
18
17
  "preinstall": "bunx only-allow bun"
19
18
  },
20
- "files": ["dist", "src"],
21
19
  "devDependencies": {
22
20
  "@biomejs/biome": "1.9.4",
23
- "@commitlint/cli": "19.6.0",
24
- "@commitlint/config-conventional": "19.6.0",
25
- "@types/bun": "1.1.13",
26
- "@types/lodash": "4.17.13",
27
- "cspell": "8.16.0",
28
- "knip": "5.37.2",
29
- "lefthook": "1.8.4",
30
- "microbundle": "0.15.1",
21
+ "@commitlint/cli": "19.8.1",
22
+ "@commitlint/config-conventional": "19.8.1",
23
+ "@types/bun": "1.2.15",
24
+ "@types/lodash": "4.17.17",
25
+ "@types/nodemailer": "6.4.17",
26
+ "cspell": "9.0.2",
27
+ "knip": "5.60.2",
28
+ "lefthook": "1.11.13",
31
29
  "only-allow": "1.2.1",
32
- "shellcheck": "3.0.0",
33
- "supertest": "7.0.0",
34
- "typescript": "5.6.3"
30
+ "shellcheck": "3.1.0",
31
+ "typescript": "5.8.3"
35
32
  },
36
33
  "dependencies": {
37
- "@bgord/node": "0.84.0",
38
- "hono": "4.6.9",
34
+ "@bgord/tools": "0.6.0",
35
+ "check-disk-space": "3.4.0",
36
+ "croner": "9.0.0",
37
+ "hono": "4.7.11",
39
38
  "lodash": "4.17.21",
40
- "sharp": "0.33.5"
41
- },
42
- "resolutions": {
43
- "typescript": "4.7.4"
39
+ "lucia": "3.2.2",
40
+ "node-cache": "5.1.2",
41
+ "nodemailer": "7.0.3",
42
+ "sharp": "0.34.2",
43
+ "ssl-checker": "2.0.10",
44
+ "winston": "3.17.0"
44
45
  }
45
46
  }
@@ -1,8 +1,8 @@
1
- import * as bg from "@bgord/node";
1
+ import * as tools from "@bgord/tools";
2
2
  import { createMiddleware } from "hono/factory";
3
3
  import { HTTPException } from "hono/http-exception";
4
4
 
5
- type ApiKeyShieldConfigType = { API_KEY: bg.Schema.ApiKeyType };
5
+ type ApiKeyShieldConfigType = { API_KEY: tools.ApiKeyType };
6
6
 
7
7
  export const AccessDeniedApiKeyError = new HTTPException(403, {
8
8
  message: "access_denied_api_key",
@@ -1,13 +1,14 @@
1
- import * as bg from "@bgord/node";
2
1
  import { createMiddleware } from "hono/factory";
3
2
 
3
+ import { BuildInfoRepository } from "./build-info-repository";
4
+
4
5
  export class ApiVersion {
5
6
  static HEADER_NAME = "api-version";
6
7
 
7
8
  static DEFAULT_API_VERSION = "unknown";
8
9
 
9
10
  static attach = createMiddleware(async (c, next) => {
10
- const build = await bg.BuildInfoRepository.extract();
11
+ const build = await BuildInfoRepository.extract();
11
12
 
12
13
  c.res.headers.set(ApiVersion.HEADER_NAME, build.BUILD_VERSION ?? ApiVersion.DEFAULT_API_VERSION);
13
14
 
@@ -1,47 +1,38 @@
1
- import * as bgn from "@bgord/node";
2
1
  import hono from "hono";
3
2
  import { createMiddleware } from "hono/factory";
4
3
  import { HTTPException } from "hono/http-exception";
5
4
  import { Lucia } from "lucia";
6
5
 
7
- class SessionId {
8
- private value: string | null;
9
-
10
- constructor(cookie: string | undefined, lucia: Lucia) {
11
- this.value = lucia.readSessionCookie(cookie ?? "");
12
- }
13
-
14
- get(): SessionId["value"] {
15
- return this.value;
16
- }
17
- }
6
+ import { HashedPassword, Password, PasswordType } from "./passwords";
7
+ import { SessionId } from "./session-id";
8
+ import { IdType, Username } from "./username";
18
9
 
19
10
  type AuthShieldConfigType<T> = {
20
- Username: typeof bgn.Username;
21
- Password: typeof bgn.Password;
22
- HashedPassword: typeof bgn.HashedPassword;
11
+ Username: typeof Username;
12
+ Password: typeof Password;
13
+ HashedPassword: typeof HashedPassword;
23
14
  lucia: Lucia;
24
- findUniqueUserOrThrow: (username: bgn.Username) => Promise<T>;
15
+ findUniqueUserOrThrow: (username: Username) => Promise<T>;
25
16
  };
26
17
 
27
18
  export const AccessDeniedAuthShieldError = new HTTPException(403, {
28
19
  message: "access_denied_auth_shield",
29
20
  });
30
21
 
31
- export class AuthShield<T extends { password: bgn.PasswordType; id: bgn.IdType }> {
22
+ export class AuthShield<T extends { password: PasswordType; id: IdType }> {
32
23
  private readonly config: AuthShieldConfigType<T>;
33
24
 
34
25
  constructor(
35
26
  overrides: Omit<AuthShieldConfigType<T>, "Username" | "Password" | "HashedPassword"> & {
36
- Username?: typeof bgn.Username;
37
- Password?: typeof bgn.Password;
38
- HashedPassword?: typeof bgn.HashedPassword;
27
+ Username?: typeof Username;
28
+ Password?: typeof Password;
29
+ HashedPassword?: typeof HashedPassword;
39
30
  },
40
31
  ) {
41
32
  const config = {
42
- Username: overrides.Username ?? bgn.Username,
43
- Password: overrides.Password ?? bgn.Password,
44
- HashedPassword: overrides.HashedPassword ?? bgn.HashedPassword,
33
+ Username: overrides.Username ?? Username,
34
+ Password: overrides.Password ?? Password,
35
+ HashedPassword: overrides.HashedPassword ?? HashedPassword,
45
36
  lucia: overrides.lucia,
46
37
  findUniqueUserOrThrow: overrides.findUniqueUserOrThrow,
47
38
  };
@@ -0,0 +1,26 @@
1
+ import * as tools from "@bgord/tools";
2
+
3
+ export type BuildInfoType = {
4
+ BUILD_DATE: tools.TimestampType;
5
+ BUILD_VERSION?: tools.BuildVersionType;
6
+ };
7
+
8
+ export class BuildInfoRepository {
9
+ static async extract(): Promise<BuildInfoType> {
10
+ const BUILD_DATE = Date.now();
11
+
12
+ try {
13
+ const packageJson = await BuildInfoRepository.getPackageJson();
14
+
15
+ const BUILD_VERSION = tools.BuildVersion.parse(packageJson.version);
16
+
17
+ return { BUILD_DATE, BUILD_VERSION };
18
+ } catch (error) {
19
+ return { BUILD_DATE };
20
+ }
21
+ }
22
+
23
+ static async getPackageJson() {
24
+ return Bun.file("package.json").json();
25
+ }
26
+ }
@@ -0,0 +1,93 @@
1
+ import { Context } from "hono";
2
+ import NodeCache, { Key } from "node-cache";
3
+
4
+ export enum CacheHitEnum {
5
+ hit = "hit",
6
+ miss = "miss",
7
+ }
8
+
9
+ export enum CacheResolverStrategy {
10
+ simple = "simple",
11
+ with_metadata = "with_metadata",
12
+ request_headers = "request_headers",
13
+ }
14
+
15
+ type Resolver<T> = () => Promise<T>;
16
+
17
+ type BaseOptions<T> = { key: Key; resolver: Resolver<T> };
18
+
19
+ type CacheResolverSimpleResult<T> = { data: T };
20
+
21
+ type CacheResolverWithMetadataResult<T> = {
22
+ data: T;
23
+ meta: { hit: CacheHitEnum };
24
+ };
25
+
26
+ type CacheResolverRequestHeadersResult<T> = {
27
+ data: T;
28
+ header: {
29
+ name: "cache-hit";
30
+ value: CacheHitEnum;
31
+ };
32
+ respond: (c: Context) => Promise<void>;
33
+ };
34
+
35
+ export class CacheResolver {
36
+ static async resolve<T>(
37
+ cache: NodeCache,
38
+ options: BaseOptions<T> & { strategy?: CacheResolverStrategy.simple },
39
+ ): Promise<CacheResolverSimpleResult<T>>;
40
+
41
+ static async resolve<T>(
42
+ cache: NodeCache,
43
+ options: BaseOptions<T> & { strategy: CacheResolverStrategy.with_metadata },
44
+ ): Promise<CacheResolverWithMetadataResult<T>>;
45
+
46
+ static async resolve<T>(
47
+ cache: NodeCache,
48
+ options: BaseOptions<T> & {
49
+ strategy: CacheResolverStrategy.request_headers;
50
+ },
51
+ ): Promise<CacheResolverRequestHeadersResult<T>>;
52
+
53
+ static async resolve<T>(
54
+ cache: NodeCache,
55
+ options: BaseOptions<T> & { strategy?: CacheResolverStrategy },
56
+ ): Promise<any> {
57
+ const strategy = options.strategy ?? CacheResolverStrategy.simple;
58
+
59
+ const cached = cache.get<T>(options.key);
60
+
61
+ const hit = cached !== undefined;
62
+
63
+ const data = hit ? cached : await options.resolver();
64
+
65
+ if (!hit) cache.set(options.key, data);
66
+
67
+ switch (strategy) {
68
+ case CacheResolverStrategy.with_metadata:
69
+ return {
70
+ data,
71
+ meta: { hit: hit ? CacheHitEnum.hit : CacheHitEnum.miss },
72
+ };
73
+
74
+ case CacheResolverStrategy.request_headers:
75
+ return {
76
+ data,
77
+ respond: (c: Context) => {
78
+ c.header("cache-hit", hit ? CacheHitEnum.hit : CacheHitEnum.miss);
79
+
80
+ // @ts-expect-error
81
+ return c.json(data);
82
+ },
83
+ header: {
84
+ name: "cache-hit",
85
+ value: hit ? CacheHitEnum.hit : CacheHitEnum.miss,
86
+ },
87
+ };
88
+
89
+ default:
90
+ return { data };
91
+ }
92
+ }
93
+ }
@@ -2,10 +2,7 @@ import { createMiddleware } from "hono/factory";
2
2
  import _ from "lodash";
3
3
  import NodeCache from "node-cache";
4
4
 
5
- export enum CacheHitEnum {
6
- hit = "hit",
7
- miss = "miss",
8
- }
5
+ import { CacheHitEnum } from "./cache-resolver";
9
6
 
10
7
  export class CacheResponse {
11
8
  static readonly CACHE_HIT_HEADER = "Cache-Hit";
@@ -18,7 +15,7 @@ export class CacheResponse {
18
15
  if (this.cache.has(url)) {
19
16
  c.res.headers.set(CacheResponse.CACHE_HIT_HEADER, CacheHitEnum.hit);
20
17
 
21
- // @ts-ignore
18
+ // @ts-expect-error
22
19
  return c.json(this.cache.get(url));
23
20
  }
24
21
 
@@ -1,4 +1,4 @@
1
- import * as bg from "@bgord/node";
1
+ import * as tools from "@bgord/tools";
2
2
  import { createMiddleware } from "hono/factory";
3
3
 
4
4
  export enum CacheStaticFilesStrategy {
@@ -14,10 +14,10 @@ export class CacheStaticFiles {
14
14
  c.res.headers.set("cache-control", "private, no-cache, no-store, must-revalidate");
15
15
  }
16
16
  if (strategy === CacheStaticFilesStrategy.always) {
17
- c.res.headers.set("cache-control", `public, max-age=${bg.Time.Days(365).seconds}, immutable`);
17
+ c.res.headers.set("cache-control", `public, max-age=${tools.Time.Days(365).seconds}, immutable`);
18
18
  }
19
19
  if (strategy === CacheStaticFilesStrategy.five_minutes) {
20
- c.res.headers.set("cache-control", `public, max-age=${bg.Time.Minutes(5).seconds}`);
20
+ c.res.headers.set("cache-control", `public, max-age=${tools.Time.Minutes(5).seconds}`);
21
21
  }
22
22
  return next();
23
23
  });
package/src/context.ts CHANGED
@@ -1,17 +1,22 @@
1
- import * as bg from "@bgord/node";
2
1
  import { createMiddleware } from "hono/factory";
3
2
 
3
+ import { CorrelationIdType } from "./correlation-id";
4
4
  import { TimeZoneOffsetVariables } from "./time-zone-offset";
5
5
 
6
+ export type ContextType = {
7
+ requestId: CorrelationIdType;
8
+ timeZoneOffset: TimeZoneOffsetVariables["timeZoneOffset"];
9
+ };
10
+
6
11
  export type ContextVariables = {
7
- context: bg.ContextType;
8
- requestId: string;
12
+ context: ContextType;
13
+ requestId: CorrelationIdType;
9
14
  } & TimeZoneOffsetVariables;
10
15
 
11
16
  export class Context {
12
17
  static attach = createMiddleware(async (c, next) => {
13
18
  c.set("context", {
14
- requestId: c.get("requestId") as bg.Schema.CorrelationIdType,
19
+ requestId: c.get("requestId") as CorrelationIdType,
15
20
  timeZoneOffset: c.get("timeZoneOffset"),
16
21
  });
17
22
 
@@ -0,0 +1,6 @@
1
+ import { z } from "zod/v4";
2
+
3
+ import { UUID } from "./uuid";
4
+
5
+ export const CorrelationId = UUID;
6
+ export type CorrelationIdType = z.infer<typeof CorrelationId>;
@@ -1,7 +1,7 @@
1
1
  import type { PathLike } from "node:fs";
2
- import * as bgn from "@bgord/node";
2
+ import * as tools from "@bgord/tools";
3
3
 
4
- export type DownloadFileConfigType = { filename: PathLike; mime: bgn.Mime };
4
+ type DownloadFileConfigType = { filename: PathLike; mime: tools.Mime };
5
5
 
6
6
  export class DownloadFile {
7
7
  static attach(config: DownloadFileConfigType) {
@@ -1,18 +1,18 @@
1
- import * as bg from "@bgord/node";
1
+ import * as tools from "@bgord/tools";
2
2
  import { createMiddleware } from "hono/factory";
3
3
 
4
4
  export type EtagVariables = {
5
- ETag: bg.ETag | null;
6
- WeakETag: bg.WeakETag | null;
5
+ ETag: tools.ETag | null;
6
+ WeakETag: tools.WeakETag | null;
7
7
  };
8
8
 
9
9
  export class ETagExtractor {
10
10
  static attach = createMiddleware<{ Variables: EtagVariables }>(async (c, next) => {
11
11
  try {
12
- const header = String(c.req.header(bg.ETag.IF_MATCH_HEADER_NAME));
12
+ const header = String(c.req.header(tools.ETag.IF_MATCH_HEADER_NAME));
13
13
 
14
14
  if (!header || header === "undefined") c.set("ETag", null);
15
- else c.set("ETag", bg.ETag.fromHeader(header));
15
+ else c.set("ETag", tools.ETag.fromHeader(header));
16
16
  } catch (error) {
17
17
  c.set("ETag", null);
18
18
  }
@@ -20,18 +20,3 @@ export class ETagExtractor {
20
20
  await next();
21
21
  });
22
22
  }
23
-
24
- export class WeakETagExtractor {
25
- static attach = createMiddleware<{ Variables: EtagVariables }>(async (c, next) => {
26
- try {
27
- const header = String(c.req.header(bg.WeakETag.IF_MATCH_HEADER_NAME));
28
-
29
- if (!header || header === "undefined") c.set("WeakETag", null);
30
- else c.set("WeakETag", bg.WeakETag.fromHeader(header));
31
- } catch (error) {
32
- c.set("WeakETag", null);
33
- }
34
-
35
- await next();
36
- });
37
- }
@@ -1,4 +1,4 @@
1
- import * as bgn from "@bgord/node";
1
+ import * as tools from "@bgord/tools";
2
2
  import { bodyLimit } from "hono/body-limit";
3
3
  import { createMiddleware } from "hono/factory";
4
4
  import { HTTPException } from "hono/http-exception";
@@ -13,7 +13,7 @@ export const FileTooBigError = new HTTPException(400, {
13
13
 
14
14
  type FileUploaderConfigType = {
15
15
  mimeTypes: string[];
16
- maxFilesSize: bgn.SizeValueType;
16
+ maxFilesSize: tools.SizeValueType;
17
17
  };
18
18
 
19
19
  export class FileUploader {
@@ -35,9 +35,9 @@ export class FileUploader {
35
35
  throw InvalidFileMimeTypeError;
36
36
  }
37
37
 
38
- const contentType = new bgn.Mime(file.type);
38
+ const contentType = new tools.Mime(file.type);
39
39
  const accepted = config.mimeTypes.some((acceptedMimeType) =>
40
- new bgn.Mime(acceptedMimeType).isSatisfiedBy(contentType),
40
+ new tools.Mime(acceptedMimeType).isSatisfiedBy(contentType),
41
41
  );
42
42
 
43
43
  if (!accepted) throw InvalidFileMimeTypeError;
@@ -1,16 +1,16 @@
1
- import * as bg from "@bgord/node";
1
+ import * as tools from "@bgord/tools";
2
2
 
3
3
  type ServerType = ReturnType<typeof Bun.serve>;
4
4
 
5
5
  export class GracefulShutdown {
6
- private static async shutdown(server: ServerType, callback: () => any = bg.noop) {
6
+ private static async shutdown(server: ServerType, callback: () => any = tools.noop) {
7
7
  server.stop();
8
8
  await callback();
9
9
  // biome-ignore lint: lint/suspicious/noConsoleLog
10
10
  console.log("HTTP server closed");
11
11
  }
12
12
 
13
- static applyTo(server: ServerType, callback: () => any = bg.noop) {
13
+ static applyTo(server: ServerType, callback: () => any = tools.noop) {
14
14
  process.on("SIGTERM", async () => {
15
15
  // biome-ignore lint: lint/suspicious/noConsoleLog
16
16
  console.log("SIGTERM signal received: closing HTTP server");
@@ -1,28 +1,38 @@
1
- import * as bg from "@bgord/node";
1
+ import * as tools from "@bgord/tools";
2
2
  import { createFactory } from "hono/factory";
3
3
 
4
+ import { BuildInfoRepository } from "./build-info-repository";
5
+ import { MemoryConsumption } from "./memory-consumption";
6
+ import {
7
+ AbstractPrerequisite,
8
+ BasePrerequisiteConfig,
9
+ PrerequisiteLabelType,
10
+ PrerequisiteStatusEnum,
11
+ } from "./prerequisites";
12
+ import { Uptime, UptimeResultType } from "./uptime";
13
+
4
14
  const handler = createFactory();
5
15
 
6
16
  type HealthcheckResultType = {
7
- ok: bg.PrerequisiteStatusEnum;
8
- version: bg.Schema.BuildVersionType;
17
+ ok: PrerequisiteStatusEnum;
18
+ version: tools.BuildVersionType;
9
19
  details: {
10
- label: bg.PrerequisiteLabelType;
11
- status: bg.PrerequisiteStatusEnum;
20
+ label: PrerequisiteLabelType;
21
+ status: PrerequisiteStatusEnum;
12
22
  }[];
13
- uptime: bg.UptimeResultType;
23
+ uptime: UptimeResultType;
14
24
  memory: {
15
- bytes: bg.Size["bytes"];
16
- formatted: ReturnType<bg.Size["format"]>;
25
+ bytes: tools.Size["bytes"];
26
+ formatted: ReturnType<tools.Size["format"]>;
17
27
  };
18
- } & bg.StopwatchResultType;
28
+ } & tools.StopwatchResultType;
19
29
 
20
30
  export class Healthcheck {
21
- static build = (prerequisites: bg.AbstractPrerequisite<bg.BasePrerequisiteConfig>[]) =>
31
+ static build = (prerequisites: AbstractPrerequisite<BasePrerequisiteConfig>[]) =>
22
32
  handler.createHandlers(async (c) => {
23
- const stopwatch = new bg.Stopwatch();
33
+ const stopwatch = new tools.Stopwatch();
24
34
 
25
- const build = await bg.BuildInfoRepository.extract();
35
+ const build = await BuildInfoRepository.extract();
26
36
 
27
37
  const details: HealthcheckResultType["details"][number][] = [];
28
38
 
@@ -31,20 +41,20 @@ export class Healthcheck {
31
41
  details.push({ label: prerequisite.label, status });
32
42
  }
33
43
 
34
- const ok = details.every((result) => result.status !== bg.PrerequisiteStatusEnum.failure)
35
- ? bg.PrerequisiteStatusEnum.success
36
- : bg.PrerequisiteStatusEnum.failure;
44
+ const ok = details.every((result) => result.status !== PrerequisiteStatusEnum.failure)
45
+ ? PrerequisiteStatusEnum.success
46
+ : PrerequisiteStatusEnum.failure;
37
47
 
38
- const code = ok === bg.PrerequisiteStatusEnum.success ? 200 : 424;
48
+ const code = ok === PrerequisiteStatusEnum.success ? 200 : 424;
39
49
 
40
50
  const result: HealthcheckResultType = {
41
51
  ok,
42
52
  details,
43
- version: build.BUILD_VERSION ?? bg.Schema.BuildVersion.parse("unknown"),
44
- uptime: bg.Uptime.get(),
53
+ version: build.BUILD_VERSION ?? tools.BuildVersion.parse("unknown"),
54
+ uptime: Uptime.get(),
45
55
  memory: {
46
- bytes: bg.MemoryConsumption.get().toBytes(),
47
- formatted: bg.MemoryConsumption.get().format(bg.SizeUnit.MB),
56
+ bytes: MemoryConsumption.get().toBytes(),
57
+ formatted: MemoryConsumption.get().format(tools.SizeUnit.MB),
48
58
  },
49
59
  ...stopwatch.stop(),
50
60
  };
@@ -1,8 +1,12 @@
1
- import * as bg from "@bgord/node";
2
1
  import { getConnInfo } from "hono/bun";
3
2
  import { createMiddleware } from "hono/factory";
4
3
  import _ from "lodash";
5
4
 
5
+ import { CacheHitEnum } from "./cache-resolver";
6
+ import { CacheResponse } from "./cache-response";
7
+ import { CorrelationIdType } from "./correlation-id";
8
+ import { Logger } from "./logger";
9
+
6
10
  export class HttpLogger {
7
11
  private static simplify(response: unknown) {
8
12
  const result = JSON.stringify(response, (_key, value) =>
@@ -34,9 +38,9 @@ export class HttpLogger {
34
38
  "if-none-match",
35
39
  ];
36
40
 
37
- static build = (logger: bg.Logger) =>
41
+ static build = (logger: Logger) =>
38
42
  createMiddleware(async (c, next) => {
39
- const correlationId = c.get("requestId") as bg.Schema.CorrelationIdType;
43
+ const correlationId = c.get("requestId") as CorrelationIdType;
40
44
  const info = getConnInfo(c);
41
45
  const url = c.req.url;
42
46
  const method = c.req.method;
@@ -54,7 +58,7 @@ export class HttpLogger {
54
58
 
55
59
  const httpRequestBeforeMetadata = {
56
60
  params: c.req.param(),
57
- headers: _.omit(c.req.raw.clone().headers.toJSON(), HttpLogger.uninformativeHeaders),
61
+ headers: _.omit(Object.fromEntries(c.req.raw.clone().headers), HttpLogger.uninformativeHeaders),
58
62
  body,
59
63
  query: c.req.queries(),
60
64
  };
@@ -71,9 +75,9 @@ export class HttpLogger {
71
75
 
72
76
  await next();
73
77
 
74
- const cacheHitHeader = c.res.clone().headers.get(bg.CacheResponse.CACHE_HIT_HEADER);
78
+ const cacheHitHeader = c.res.clone().headers.get(CacheResponse.CACHE_HIT_HEADER);
75
79
 
76
- const cacheHit = cacheHitHeader === bg.CacheHitEnum.hit ? bg.CacheHitEnum.hit : undefined;
80
+ const cacheHit = cacheHitHeader === CacheHitEnum.hit ? CacheHitEnum.hit : undefined;
77
81
 
78
82
  let response: any;
79
83
  try {