@bgord/bun 1.19.13 → 1.19.14

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 (245) hide show
  1. package/dist/ab-hono-noop.middleware.d.ts +2 -3
  2. package/dist/ab-hono-noop.middleware.d.ts.map +1 -1
  3. package/dist/ab-hono-noop.middleware.js +4 -9
  4. package/dist/ab-hono-noop.middleware.js.map +1 -1
  5. package/dist/ab-variant-name.vo.d.ts +9 -0
  6. package/dist/ab-variant-name.vo.d.ts.map +1 -0
  7. package/dist/ab-variant-name.vo.js +10 -0
  8. package/dist/ab-variant-name.vo.js.map +1 -0
  9. package/dist/ab-variant.vo.d.ts +2 -1
  10. package/dist/ab-variant.vo.d.ts.map +1 -1
  11. package/dist/ab-variant.vo.js.map +1 -1
  12. package/dist/basic-auth-password.vo.d.ts +2 -1
  13. package/dist/basic-auth-password.vo.d.ts.map +1 -1
  14. package/dist/basic-auth-password.vo.js +2 -1
  15. package/dist/basic-auth-password.vo.js.map +1 -1
  16. package/dist/basic-auth-username.vo.d.ts +2 -1
  17. package/dist/basic-auth-username.vo.d.ts.map +1 -1
  18. package/dist/basic-auth-username.vo.js +2 -1
  19. package/dist/basic-auth-username.vo.js.map +1 -1
  20. package/dist/cache-repository-redis.adapter.d.ts +1 -2
  21. package/dist/cache-repository-redis.adapter.d.ts.map +1 -1
  22. package/dist/cache-repository-redis.adapter.js.map +1 -1
  23. package/dist/certificate-inspector-noop.adapter.d.ts +2 -1
  24. package/dist/certificate-inspector-noop.adapter.d.ts.map +1 -1
  25. package/dist/certificate-inspector-noop.adapter.js.map +1 -1
  26. package/dist/certificate-inspector-tls.adapter.d.ts +2 -1
  27. package/dist/certificate-inspector-tls.adapter.d.ts.map +1 -1
  28. package/dist/certificate-inspector-tls.adapter.js.map +1 -1
  29. package/dist/certificate-inspector.port.d.ts +2 -1
  30. package/dist/certificate-inspector.port.d.ts.map +1 -1
  31. package/dist/csv-stringifier.adapter.d.ts.map +1 -1
  32. package/dist/csv-stringifier.adapter.js +1 -0
  33. package/dist/csv-stringifier.adapter.js.map +1 -1
  34. package/dist/environment-loader-encrypted.adapter.d.ts +1 -1
  35. package/dist/environment-loader-encrypted.adapter.d.ts.map +1 -1
  36. package/dist/environment-loader-encrypted.adapter.js +5 -7
  37. package/dist/environment-loader-encrypted.adapter.js.map +1 -1
  38. package/dist/environment-loader-noop.adapter.d.ts +1 -1
  39. package/dist/environment-loader-noop.adapter.d.ts.map +1 -1
  40. package/dist/environment-loader-noop.adapter.js +5 -7
  41. package/dist/environment-loader-noop.adapter.js.map +1 -1
  42. package/dist/environment-loader-process-safe.adapter.d.ts +1 -1
  43. package/dist/environment-loader-process-safe.adapter.d.ts.map +1 -1
  44. package/dist/environment-loader-process-safe.adapter.js +2 -9
  45. package/dist/environment-loader-process-safe.adapter.js.map +1 -1
  46. package/dist/environment-loader-process.adapter.d.ts +1 -1
  47. package/dist/environment-loader-process.adapter.d.ts.map +1 -1
  48. package/dist/environment-loader-process.adapter.js +5 -7
  49. package/dist/environment-loader-process.adapter.js.map +1 -1
  50. package/dist/environment-loader.port.d.ts +0 -3
  51. package/dist/environment-loader.port.d.ts.map +1 -1
  52. package/dist/environment-loader.port.js +1 -1
  53. package/dist/environment-loader.port.js.map +1 -1
  54. package/dist/event-upcaster-chain.adapter.d.ts.map +1 -1
  55. package/dist/event-upcaster-chain.adapter.js +5 -0
  56. package/dist/event-upcaster-chain.adapter.js.map +1 -1
  57. package/dist/event-validator-registry.adapter.d.ts +1 -1
  58. package/dist/event-validator-registry.adapter.d.ts.map +1 -1
  59. package/dist/event-validator-registry.adapter.js +2 -7
  60. package/dist/event-validator-registry.adapter.js.map +1 -1
  61. package/dist/event-validator-registry.port.d.ts +0 -3
  62. package/dist/event-validator-registry.port.d.ts.map +1 -1
  63. package/dist/event-validator-registry.port.js +1 -1
  64. package/dist/event-validator-registry.port.js.map +1 -1
  65. package/dist/file-uploader-hono.middleware.d.ts.map +1 -1
  66. package/dist/file-uploader-hono.middleware.js +4 -13
  67. package/dist/file-uploader-hono.middleware.js.map +1 -1
  68. package/dist/file-uploader.middleware.d.ts.map +1 -1
  69. package/dist/file-uploader.middleware.js +1 -0
  70. package/dist/file-uploader.middleware.js.map +1 -1
  71. package/dist/graceful-shutdown.service.d.ts +8 -4
  72. package/dist/graceful-shutdown.service.d.ts.map +1 -1
  73. package/dist/graceful-shutdown.service.js +27 -26
  74. package/dist/graceful-shutdown.service.js.map +1 -1
  75. package/dist/hostname.vo.d.ts +8 -0
  76. package/dist/hostname.vo.d.ts.map +1 -0
  77. package/dist/hostname.vo.js +9 -0
  78. package/dist/hostname.vo.js.map +1 -0
  79. package/dist/http-logger.middleware.js +1 -1
  80. package/dist/http-logger.middleware.js.map +1 -1
  81. package/dist/image-blur.adapter.d.ts +2 -0
  82. package/dist/image-blur.adapter.d.ts.map +1 -1
  83. package/dist/image-blur.adapter.js +1 -1
  84. package/dist/image-blur.adapter.js.map +1 -1
  85. package/dist/image-compressor.adapter.d.ts +2 -0
  86. package/dist/image-compressor.adapter.d.ts.map +1 -1
  87. package/dist/image-compressor.adapter.js +1 -1
  88. package/dist/image-compressor.adapter.js.map +1 -1
  89. package/dist/image-exif-clear.adapter.d.ts +2 -0
  90. package/dist/image-exif-clear.adapter.d.ts.map +1 -1
  91. package/dist/image-exif-clear.adapter.js +1 -1
  92. package/dist/image-exif-clear.adapter.js.map +1 -1
  93. package/dist/image-formatter.adapter.d.ts +2 -0
  94. package/dist/image-formatter.adapter.d.ts.map +1 -1
  95. package/dist/image-formatter.adapter.js +1 -1
  96. package/dist/image-formatter.adapter.js.map +1 -1
  97. package/dist/image-generator-web-view.adapter.d.ts.map +1 -1
  98. package/dist/image-generator-web-view.adapter.js +1 -0
  99. package/dist/image-generator-web-view.adapter.js.map +1 -1
  100. package/dist/image-grayscale.adapter.d.ts +2 -0
  101. package/dist/image-grayscale.adapter.d.ts.map +1 -1
  102. package/dist/image-grayscale.adapter.js +1 -1
  103. package/dist/image-grayscale.adapter.js.map +1 -1
  104. package/dist/image-processor.adapter.d.ts +2 -0
  105. package/dist/image-processor.adapter.d.ts.map +1 -1
  106. package/dist/image-processor.adapter.js +1 -1
  107. package/dist/image-processor.adapter.js.map +1 -1
  108. package/dist/image-resizer.adapter.d.ts +2 -0
  109. package/dist/image-resizer.adapter.d.ts.map +1 -1
  110. package/dist/image-resizer.adapter.js +1 -1
  111. package/dist/image-resizer.adapter.js.map +1 -1
  112. package/dist/image.types.d.ts +1 -1
  113. package/dist/image.types.d.ts.map +1 -1
  114. package/dist/index.d.ts +2 -0
  115. package/dist/index.d.ts.map +1 -1
  116. package/dist/index.js +2 -0
  117. package/dist/index.js.map +1 -1
  118. package/dist/job-registry.adapter.d.ts +1 -1
  119. package/dist/job-registry.adapter.d.ts.map +1 -1
  120. package/dist/job-registry.adapter.js +2 -7
  121. package/dist/job-registry.adapter.js.map +1 -1
  122. package/dist/job-registry.port.d.ts +0 -3
  123. package/dist/job-registry.port.d.ts.map +1 -1
  124. package/dist/job-registry.port.js +1 -1
  125. package/dist/job-registry.port.js.map +1 -1
  126. package/dist/prerequisite-verifier-binary.adapter.js +1 -1
  127. package/dist/prerequisite-verifier-binary.adapter.js.map +1 -1
  128. package/dist/prerequisite-verifier-dns.adapter.d.ts +2 -1
  129. package/dist/prerequisite-verifier-dns.adapter.d.ts.map +1 -1
  130. package/dist/prerequisite-verifier-dns.adapter.js.map +1 -1
  131. package/dist/prerequisite-verifier-ssl-certificate-expiry.adapter.d.ts +2 -1
  132. package/dist/prerequisite-verifier-ssl-certificate-expiry.adapter.d.ts.map +1 -1
  133. package/dist/prerequisite-verifier-ssl-certificate-expiry.adapter.js.map +1 -1
  134. package/dist/prerequisite-verifier-translations.adapter.js +5 -5
  135. package/dist/prerequisite-verifier-translations.adapter.js.map +1 -1
  136. package/dist/reactive-config-file-json.adapter.d.ts +1 -1
  137. package/dist/reactive-config-file-json.adapter.d.ts.map +1 -1
  138. package/dist/reactive-config-file-json.adapter.js +2 -7
  139. package/dist/reactive-config-file-json.adapter.js.map +1 -1
  140. package/dist/reactive-config-noop.adapter.d.ts +1 -1
  141. package/dist/reactive-config-noop.adapter.d.ts.map +1 -1
  142. package/dist/reactive-config-noop.adapter.js +2 -7
  143. package/dist/reactive-config-noop.adapter.js.map +1 -1
  144. package/dist/reactive-config-with-fallback.adapter.d.ts +1 -1
  145. package/dist/reactive-config-with-fallback.adapter.d.ts.map +1 -1
  146. package/dist/reactive-config-with-fallback.adapter.js +2 -7
  147. package/dist/reactive-config-with-fallback.adapter.js.map +1 -1
  148. package/dist/reactive-config.port.d.ts +0 -3
  149. package/dist/reactive-config.port.d.ts.map +1 -1
  150. package/dist/reactive-config.port.js +1 -1
  151. package/dist/reactive-config.port.js.map +1 -1
  152. package/dist/remote-file-storage-disk.adapter.d.ts +2 -0
  153. package/dist/remote-file-storage-disk.adapter.d.ts.map +1 -1
  154. package/dist/remote-file-storage-disk.adapter.js +1 -1
  155. package/dist/remote-file-storage-disk.adapter.js.map +1 -1
  156. package/dist/shield-api-key.strategy.d.ts.map +1 -1
  157. package/dist/shield-api-key.strategy.js +6 -1
  158. package/dist/shield-api-key.strategy.js.map +1 -1
  159. package/dist/shield-basic-auth.strategy.d.ts.map +1 -1
  160. package/dist/shield-basic-auth.strategy.js +3 -2
  161. package/dist/shield-basic-auth.strategy.js.map +1 -1
  162. package/dist/shield-recaptcha.strategy.js +1 -1
  163. package/dist/shield-recaptcha.strategy.js.map +1 -1
  164. package/dist/sitemap-entry.vo.d.ts +1 -0
  165. package/dist/sitemap-entry.vo.d.ts.map +1 -1
  166. package/dist/sitemap-entry.vo.js +9 -1
  167. package/dist/sitemap-entry.vo.js.map +1 -1
  168. package/dist/standard-schema-validator.service.d.ts +5 -0
  169. package/dist/standard-schema-validator.service.d.ts.map +1 -0
  170. package/dist/standard-schema-validator.service.js +14 -0
  171. package/dist/standard-schema-validator.service.js.map +1 -0
  172. package/dist/subject-application-resolver.vo.d.ts +0 -1
  173. package/dist/subject-application-resolver.vo.d.ts.map +1 -1
  174. package/dist/subject-application-resolver.vo.js +2 -3
  175. package/dist/subject-application-resolver.vo.js.map +1 -1
  176. package/dist/subject-request-resolver.vo.d.ts +0 -1
  177. package/dist/subject-request-resolver.vo.d.ts.map +1 -1
  178. package/dist/subject-request-resolver.vo.js +2 -3
  179. package/dist/subject-request-resolver.vo.js.map +1 -1
  180. package/dist/temporary-file-absolute.adapter.d.ts +2 -0
  181. package/dist/temporary-file-absolute.adapter.d.ts.map +1 -1
  182. package/dist/temporary-file-absolute.adapter.js +1 -1
  183. package/dist/temporary-file-absolute.adapter.js.map +1 -1
  184. package/dist/timing.middleware.d.ts.map +1 -1
  185. package/dist/timing.middleware.js +1 -2
  186. package/dist/timing.middleware.js.map +1 -1
  187. package/dist/woodchopper-sampling-every-nth.strategy.d.ts.map +1 -1
  188. package/dist/woodchopper-sampling-every-nth.strategy.js +1 -3
  189. package/dist/woodchopper-sampling-every-nth.strategy.js.map +1 -1
  190. package/package.json +7 -7
  191. package/readme.md +3 -0
  192. package/src/ab-hono-noop.middleware.ts +2 -13
  193. package/src/ab-variant-name.vo.ts +17 -0
  194. package/src/ab-variant.vo.ts +2 -1
  195. package/src/basic-auth-password.vo.ts +5 -0
  196. package/src/basic-auth-username.vo.ts +5 -0
  197. package/src/cache-repository-redis.adapter.ts +1 -2
  198. package/src/certificate-inspector-noop.adapter.ts +2 -1
  199. package/src/certificate-inspector-tls.adapter.ts +2 -1
  200. package/src/certificate-inspector.port.ts +2 -1
  201. package/src/csv-stringifier.adapter.ts +1 -0
  202. package/src/environment-loader-encrypted.adapter.ts +9 -9
  203. package/src/environment-loader-noop.adapter.ts +9 -9
  204. package/src/environment-loader-process-safe.adapter.ts +8 -11
  205. package/src/environment-loader-process.adapter.ts +9 -9
  206. package/src/environment-loader.port.ts +0 -2
  207. package/src/event-upcaster-chain.adapter.ts +5 -0
  208. package/src/event-validator-registry.adapter.ts +3 -9
  209. package/src/event-validator-registry.port.ts +0 -2
  210. package/src/file-uploader-hono.middleware.ts +3 -17
  211. package/src/file-uploader.middleware.ts +1 -0
  212. package/src/graceful-shutdown.service.ts +27 -28
  213. package/src/hostname.vo.ts +15 -0
  214. package/src/http-logger.middleware.ts +1 -1
  215. package/src/image-blur.adapter.ts +9 -2
  216. package/src/image-compressor.adapter.ts +9 -2
  217. package/src/image-exif-clear.adapter.ts +9 -2
  218. package/src/image-formatter.adapter.ts +5 -1
  219. package/src/image-generator-web-view.adapter.ts +1 -0
  220. package/src/image-grayscale.adapter.ts +9 -2
  221. package/src/image-processor.adapter.ts +5 -1
  222. package/src/image-resizer.adapter.ts +9 -2
  223. package/src/image.types.ts +1 -1
  224. package/src/index.ts +2 -0
  225. package/src/job-registry.adapter.ts +3 -6
  226. package/src/job-registry.port.ts +0 -2
  227. package/src/prerequisite-verifier-binary.adapter.ts +1 -1
  228. package/src/prerequisite-verifier-dns.adapter.ts +2 -1
  229. package/src/prerequisite-verifier-ssl-certificate-expiry.adapter.ts +2 -1
  230. package/src/prerequisite-verifier-translations.adapter.ts +4 -4
  231. package/src/reactive-config-file-json.adapter.ts +3 -9
  232. package/src/reactive-config-noop.adapter.ts +3 -9
  233. package/src/reactive-config-with-fallback.adapter.ts +3 -9
  234. package/src/reactive-config.port.ts +0 -2
  235. package/src/remote-file-storage-disk.adapter.ts +5 -1
  236. package/src/shield-api-key.strategy.ts +7 -1
  237. package/src/shield-basic-auth.strategy.ts +4 -2
  238. package/src/shield-recaptcha.strategy.ts +1 -1
  239. package/src/sitemap-entry.vo.ts +11 -4
  240. package/src/standard-schema-validator.service.ts +15 -0
  241. package/src/subject-application-resolver.vo.ts +2 -6
  242. package/src/subject-request-resolver.vo.ts +2 -6
  243. package/src/temporary-file-absolute.adapter.ts +6 -1
  244. package/src/timing.middleware.ts +1 -3
  245. package/src/woodchopper-sampling-every-nth.strategy.ts +1 -2
@@ -1,9 +1,9 @@
1
- import {
2
- type EnvironmentLoaderConfig,
3
- EnvironmentLoaderError,
4
- type EnvironmentLoaderPort,
5
- type EnvironmentResultType,
1
+ import type {
2
+ EnvironmentLoaderConfig,
3
+ EnvironmentLoaderPort,
4
+ EnvironmentResultType,
6
5
  } from "./environment-loader.port";
6
+ import { StandardSchemaValidator } from "./standard-schema-validator.service";
7
7
 
8
8
  export class EnvironmentLoaderNoopAdapter<T extends object> implements EnvironmentLoaderPort<T> {
9
9
  constructor(
@@ -12,9 +12,9 @@ export class EnvironmentLoaderNoopAdapter<T extends object> implements Environme
12
12
  ) {}
13
13
 
14
14
  async load(): Promise<Readonly<EnvironmentResultType<T>>> {
15
- const result = this.config.EnvironmentSchema["~standard"].validate(this.deterministic);
16
- if (result instanceof Promise) throw new Error(EnvironmentLoaderError.NoAsyncSchema);
17
- if (result.issues) throw new Error(result.issues[0]?.message);
18
- return Object.freeze({ ...result.value, type: this.config.type });
15
+ return Object.freeze({
16
+ ...StandardSchemaValidator.validate(this.config.EnvironmentSchema, this.deterministic),
17
+ type: this.config.type,
18
+ });
19
19
  }
20
20
  }
@@ -1,11 +1,11 @@
1
1
  import type { CacheResolverStrategy } from "./cache-resolver.strategy";
2
- import {
3
- type EnvironmentLoaderConfig,
4
- EnvironmentLoaderError,
5
- type EnvironmentLoaderPort,
6
- type EnvironmentResultType,
2
+ import type {
3
+ EnvironmentLoaderConfig,
4
+ EnvironmentLoaderPort,
5
+ EnvironmentResultType,
7
6
  } from "./environment-loader.port";
8
7
  import type { HashContentStrategy } from "./hash-content.strategy";
8
+ import { StandardSchemaValidator } from "./standard-schema-validator.service";
9
9
  import { SubjectApplicationResolver } from "./subject-application-resolver.vo";
10
10
  import { SubjectSegmentFixedStrategy } from "./subject-segment-fixed.strategy";
11
11
 
@@ -22,12 +22,9 @@ export class EnvironmentLoaderProcessSafeAdapter<T extends object> implements En
22
22
  const resolver = new SubjectApplicationResolver([new SubjectSegmentFixedStrategy("env")], this.deps);
23
23
  const subject = await resolver.resolve();
24
24
 
25
- const parsed = await this.deps.CacheResolver.resolve(subject.hex, async () => {
26
- const result = this.config.EnvironmentSchema["~standard"].validate(this.env);
27
- if (result instanceof Promise) throw new Error(EnvironmentLoaderError.NoAsyncSchema);
28
- if (result.issues) throw new Error(result.issues[0]?.message);
29
- return result.value;
30
- });
25
+ const parsed = await this.deps.CacheResolver.resolve(subject.hex, async () =>
26
+ StandardSchemaValidator.validate(this.config.EnvironmentSchema, this.env),
27
+ );
31
28
 
32
29
  for (const key of Object.keys(parsed)) delete process.env[key];
33
30
 
@@ -1,9 +1,9 @@
1
- import {
2
- type EnvironmentLoaderConfig,
3
- EnvironmentLoaderError,
4
- type EnvironmentLoaderPort,
5
- type EnvironmentResultType,
1
+ import type {
2
+ EnvironmentLoaderConfig,
3
+ EnvironmentLoaderPort,
4
+ EnvironmentResultType,
6
5
  } from "./environment-loader.port";
6
+ import { StandardSchemaValidator } from "./standard-schema-validator.service";
7
7
 
8
8
  export class EnvironmentLoaderProcessAdapter<T extends object> implements EnvironmentLoaderPort<T> {
9
9
  constructor(
@@ -12,9 +12,9 @@ export class EnvironmentLoaderProcessAdapter<T extends object> implements Enviro
12
12
  ) {}
13
13
 
14
14
  async load(): Promise<Readonly<EnvironmentResultType<T>>> {
15
- const result = this.config.EnvironmentSchema["~standard"].validate(this.env);
16
- if (result instanceof Promise) throw new Error(EnvironmentLoaderError.NoAsyncSchema);
17
- if (result.issues) throw new Error(result.issues[0]?.message);
18
- return Object.freeze({ ...result.value, type: this.config.type });
15
+ return Object.freeze({
16
+ ...StandardSchemaValidator.validate(this.config.EnvironmentSchema, this.env),
17
+ type: this.config.type,
18
+ });
19
19
  }
20
20
  }
@@ -1,8 +1,6 @@
1
1
  import type { StandardSchemaV1 } from "@standard-schema/spec";
2
2
  import type { NodeEnvironmentEnum } from "../src/node-env.vo";
3
3
 
4
- export const EnvironmentLoaderError = { NoAsyncSchema: "environment.loader.no.async.schema" };
5
-
6
4
  export type EnvironmentLoaderConfig<T extends object> = {
7
5
  type: NodeEnvironmentEnum;
8
6
  EnvironmentSchema: StandardSchemaV1<unknown, T>;
@@ -6,6 +6,7 @@ import type { EventUpcasterStep } from "./event-upcaster-step.vo";
6
6
  const EventUpcasterChainAdapterError = {
7
7
  DuplicateStep: "event.upcaster.chain.duplicate.step",
8
8
  GapInChain: "event.upcaster.chain.gap",
9
+ StartOffset: "event.upcaster.chain.start.offset",
9
10
  };
10
11
 
11
12
  type EventUpcasterChainConfig = Record<GenericEvent["name"], ReadonlyArray<EventUpcasterStep<any, any>>>;
@@ -21,6 +22,10 @@ export class EventUpcasterChainAdapter implements EventUpcasterPort {
21
22
  ]),
22
23
  );
23
24
 
25
+ for (const [_, chain] of Object.entries(this.upcasters)) {
26
+ if (chain[0]?.config.fromVersion !== 1) throw new Error(EventUpcasterChainAdapterError.StartOffset);
27
+ }
28
+
24
29
  for (const chain of Object.values(this.upcasters)) {
25
30
  const versions = chain.map((step) => step.config.fromVersion);
26
31
 
@@ -1,9 +1,7 @@
1
1
  import type { StandardSchemaV1 } from "@standard-schema/spec";
2
2
  import type { GenericEvent } from "./event.types";
3
- import {
4
- EventValidatorRegistryError,
5
- type EventValidatorRegistryPort,
6
- } from "./event-validator-registry.port";
3
+ import type { EventValidatorRegistryPort } from "./event-validator-registry.port";
4
+ import { StandardSchemaValidator } from "./standard-schema-validator.service";
7
5
 
8
6
  export type GenericEventSchemaRegistry<Event> = Readonly<
9
7
  Record<GenericEvent["name"], StandardSchemaV1<unknown, Event>>
@@ -34,10 +32,6 @@ export class EventValidatorRegistryAdapter<Event> implements EventValidatorRegis
34
32
  const schema = this.map.get(name);
35
33
  if (!schema) throw new Error(EventValidatorRegistryAdapterError.UnknownEvent);
36
34
 
37
- const result = schema["~standard"].validate(raw);
38
-
39
- if (result instanceof Promise) throw new Error(EventValidatorRegistryError.NoAsyncSchema);
40
- if (result.issues) throw new Error(result.issues[0]?.message);
41
- return result.value;
35
+ return StandardSchemaValidator.validate(schema, raw);
42
36
  }
43
37
  }
@@ -1,7 +1,5 @@
1
1
  import type { GenericEvent } from "./event.types";
2
2
 
3
- export const EventValidatorRegistryError = { NoAsyncSchema: "event.validator.registry.no.async.schema" };
4
-
5
3
  export interface EventValidatorRegistryPort<Event> {
6
4
  readonly names: ReadonlyArray<GenericEvent["name"]>;
7
5
 
@@ -1,10 +1,6 @@
1
1
  import { createMiddleware } from "hono/factory";
2
2
  import { HTTPException } from "hono/http-exception";
3
- import {
4
- type FileUploaderConfig,
5
- FileUploaderError,
6
- FileUploaderMiddleware,
7
- } from "./file-uploader.middleware";
3
+ import { type FileUploaderConfig, FileUploaderMiddleware } from "./file-uploader.middleware";
8
4
  import type { MiddlewareHonoPort } from "./middleware-hono.port";
9
5
 
10
6
  export class FileUploaderHonoMiddleware implements MiddlewareHonoPort {
@@ -21,18 +17,8 @@ export class FileUploaderHonoMiddleware implements MiddlewareHonoPort {
21
17
 
22
18
  const result = this.middleware.validate(file instanceof File ? file : null);
23
19
 
24
- if (result.valid) return next();
25
-
26
- switch (result.error) {
27
- case FileUploaderError.MissingFile:
28
- throw new HTTPException(400, { message: FileUploaderError.MissingFile });
29
- case FileUploaderError.EmptyFile:
30
- throw new HTTPException(400, { message: FileUploaderError.EmptyFile });
31
- case FileUploaderError.SizeLimit:
32
- throw new HTTPException(400, { message: FileUploaderError.SizeLimit });
33
- case FileUploaderError.InvalidMime:
34
- throw new HTTPException(400, { message: FileUploaderError.InvalidMime });
35
- }
20
+ if (result.valid === false) throw new HTTPException(400, { message: result.error });
21
+ return next();
36
22
  });
37
23
  }
38
24
  }
@@ -24,6 +24,7 @@ export class FileUploaderMiddleware {
24
24
 
25
25
  if (size.isGreaterThan(this.config.maxSize)) return { valid: false, error: FileUploaderError.SizeLimit };
26
26
 
27
+ // TODO: MIME spoofing possible by reading client-supplied file.type
27
28
  const mime = tools.Mime.fromString(file.type);
28
29
 
29
30
  if (!this.config.MimeRegistry.hasMime(mime)) {
@@ -1,9 +1,10 @@
1
1
  import * as tools from "@bgord/tools";
2
2
  import type { LoggerPort } from "./logger.port";
3
3
 
4
- type ServerType = ReturnType<typeof Bun.serve>;
4
+ export type ServerType = ReturnType<typeof Bun.serve>;
5
5
 
6
6
  type Dependencies = { Logger: LoggerPort };
7
+ type Config = { cleanup: () => Promise<void> | void; exit?: (code: number) => never };
7
8
 
8
9
  export class GracefulShutdown {
9
10
  private readonly base = { operation: "shutdown", component: "infra" } as const;
@@ -11,10 +12,10 @@ export class GracefulShutdown {
11
12
 
12
13
  constructor(
13
14
  private readonly deps: Dependencies,
14
- private readonly exitFn: (code: number) => never = (code: number) => process.exit(code),
15
+ private readonly config: Config = { cleanup: tools.noop, exit: process.exit },
15
16
  ) {}
16
17
 
17
- private shutdown(server: ServerType, cleanup: () => any, exitCode: number) {
18
+ private async shutdown(server: ServerType, exitCode: number) {
18
19
  // Stryker disable all
19
20
  if (this.isShuttingDown) return;
20
21
  this.isShuttingDown = true;
@@ -26,32 +27,30 @@ export class GracefulShutdown {
26
27
  this.deps.Logger.error({ message: "Server stop failed", error, ...this.base });
27
28
  }
28
29
 
29
- Promise.resolve()
30
- .then(() => cleanup())
31
- .then(() => this.deps.Logger.info({ message: "HTTP server closed", ...this.base }))
32
- .catch((error) => this.deps.Logger.error({ message: "Cleanup hook failed", error, ...this.base }))
33
- .finally(() => this.exitFn(exitCode));
30
+ try {
31
+ await this.config.cleanup();
32
+ this.deps.Logger.info({ message: "HTTP server closed", ...this.base });
33
+ } catch (error) {
34
+ this.deps.Logger.error({ message: "Cleanup hook failed", error, ...this.base });
35
+ } finally {
36
+ this.config.exit?.(exitCode);
37
+ }
34
38
  }
35
39
 
36
- applyTo(server: ServerType, cleanup: () => any = tools.noop) {
37
- process.once("SIGTERM", () => {
38
- this.deps.Logger.info({ message: "SIGTERM received", ...this.base });
39
- this.shutdown(server, cleanup, 0);
40
- });
41
-
42
- process.once("SIGINT", () => {
43
- this.deps.Logger.info({ message: "SIGINT received", ...this.base });
44
- this.shutdown(server, cleanup, 0);
45
- });
46
-
47
- process.once("unhandledRejection", (error) => {
48
- this.deps.Logger.error({ message: "UnhandledRejection received", error, ...this.base });
49
- this.shutdown(server, cleanup, 1);
50
- });
51
-
52
- process.once("uncaughtException", (error) => {
53
- this.deps.Logger.error({ message: "UncaughtException received", error, ...this.base });
54
- this.shutdown(server, cleanup, 1);
55
- });
40
+ applyTo(server: ServerType) {
41
+ const graceful = (signal: string) => () => {
42
+ this.deps.Logger.info({ message: `${signal} received`, ...this.base });
43
+ this.shutdown(server, 0);
44
+ };
45
+
46
+ const fatal = (event: string) => (error: unknown) => {
47
+ this.deps.Logger.error({ message: `${event} received`, error, ...this.base });
48
+ this.shutdown(server, 1);
49
+ };
50
+
51
+ process.once("SIGTERM", graceful("SIGTERM"));
52
+ process.once("SIGINT", graceful("SIGINT"));
53
+ process.once("unhandledRejection", fatal("UnhandledRejection"));
54
+ process.once("uncaughtException", fatal("UncaughtException"));
56
55
  }
57
56
  }
@@ -0,0 +1,15 @@
1
+ import * as v from "valibot";
2
+
3
+ export const HostnameError = {
4
+ Type: "hostname.type",
5
+ Invalid: "hostname.invalid",
6
+ };
7
+
8
+ export const Hostname = v.pipe(
9
+ v.string(HostnameError.Type),
10
+ v.domain(HostnameError.Invalid),
11
+ // Stryker disable next-line StringLiteral
12
+ v.brand("Hostname"),
13
+ );
14
+
15
+ export type HostnameType = v.InferOutput<typeof Hostname>;
@@ -44,7 +44,7 @@ export class HttpLoggerMiddleware {
44
44
  ) {}
45
45
 
46
46
  shouldSkip(context: HasRequestPath & HasRequestHeader): boolean {
47
- if (context.request.header("accept") === "text/event-stream") return true;
47
+ if (context.request.header("accept")?.toLowerCase().startsWith("text/event-stream")) return true;
48
48
 
49
49
  return (
50
50
  this.config?.skip?.some((rule) => {
@@ -3,8 +3,13 @@ import type { FileRenamerPort } from "./file-renamer.port";
3
3
  import type { FileWriterPort } from "./file-writer.port";
4
4
  import type { ImageSupportedType } from "./image.types";
5
5
  import type { ImageBlurPort, ImageBlurStrategy } from "./image-blur.port";
6
+ import type { NonceProviderPort } from "./nonce-provider.port";
6
7
 
7
- type Dependencies = { FileRenamer: FileRenamerPort; FileWriter: FileWriterPort };
8
+ type Dependencies = {
9
+ FileRenamer: FileRenamerPort;
10
+ FileWriter: FileWriterPort;
11
+ NonceProvider: NonceProviderPort;
12
+ };
8
13
 
9
14
  export class ImageBlurAdapter implements ImageBlurPort {
10
15
  constructor(private readonly deps: Dependencies) {}
@@ -13,7 +18,9 @@ export class ImageBlurAdapter implements ImageBlurPort {
13
18
  const final = recipe.strategy === "output_path" ? recipe.output : recipe.input;
14
19
 
15
20
  const filename = final.getFilename();
16
- const temporary = final.withFilename(filename.withSuffix("-blurred"));
21
+ const temporary = final.withFilename(
22
+ filename.withSuffix(`-blurred-${this.deps.NonceProvider.generate()}`),
23
+ );
17
24
 
18
25
  const extension = final.getFilename().getExtension();
19
26
  const format = (extension === "jpg" ? "jpeg" : extension) as ImageSupportedType;
@@ -3,8 +3,13 @@ import type { FileRenamerPort } from "./file-renamer.port";
3
3
  import type { FileWriterPort } from "./file-writer.port";
4
4
  import type { ImageSupportedType } from "./image.types";
5
5
  import type { ImageCompressorPort, ImageCompressorStrategy } from "./image-compressor.port";
6
+ import type { NonceProviderPort } from "./nonce-provider.port";
6
7
 
7
- type Dependencies = { FileRenamer: FileRenamerPort; FileWriter: FileWriterPort };
8
+ type Dependencies = {
9
+ FileRenamer: FileRenamerPort;
10
+ FileWriter: FileWriterPort;
11
+ NonceProvider: NonceProviderPort;
12
+ };
8
13
 
9
14
  export class ImageCompressorAdapter implements ImageCompressorPort {
10
15
  private static readonly DEFAULT_QUALITY = 85;
@@ -16,7 +21,9 @@ export class ImageCompressorAdapter implements ImageCompressorPort {
16
21
 
17
22
  const final = recipe.strategy === "output_path" ? recipe.output : recipe.input;
18
23
  const filename = final.getFilename();
19
- const temporary = final.withFilename(filename.withSuffix("-compressed"));
24
+ const temporary = final.withFilename(
25
+ filename.withSuffix(`-compressed-${this.deps.NonceProvider.generate()}`),
26
+ );
20
27
 
21
28
  const extension = final.getFilename().getExtension();
22
29
  const format = (extension === "jpg" ? "jpeg" : extension) as ImageSupportedType;
@@ -4,15 +4,22 @@ import type { FileRenamerPort } from "./file-renamer.port";
4
4
  import type { FileWriterPort } from "./file-writer.port";
5
5
  import type { ImageSupportedType } from "./image.types";
6
6
  import type { ImageExifClearPort, ImageExifClearStrategy } from "./image-exif-clear.port";
7
+ import type { NonceProviderPort } from "./nonce-provider.port";
7
8
 
8
- type Dependencies = { FileRenamer: FileRenamerPort; FileWriter: FileWriterPort };
9
+ type Dependencies = {
10
+ FileRenamer: FileRenamerPort;
11
+ FileWriter: FileWriterPort;
12
+ NonceProvider: NonceProviderPort;
13
+ };
9
14
 
10
15
  export class ImageExifClearAdapter implements ImageExifClearPort {
11
16
  constructor(private readonly deps: Dependencies) {}
12
17
 
13
18
  async clear(recipe: ImageExifClearStrategy): Promise<tools.FilePathRelative | tools.FilePathAbsolute> {
14
19
  const final = recipe.strategy === "output_path" ? recipe.output : recipe.input;
15
- const temporary = final.withFilename(final.getFilename().withSuffix("-exif-cleared"));
20
+ const temporary = final.withFilename(
21
+ final.getFilename().withSuffix(`-exif-cleared-${this.deps.NonceProvider.generate()}`),
22
+ );
16
23
 
17
24
  const extension = final.getFilename().getExtension();
18
25
  const format = (extension === "jpg" ? "jpeg" : extension) as ImageSupportedType;
@@ -4,11 +4,13 @@ import type { FileRenamerPort } from "./file-renamer.port";
4
4
  import type { FileWriterPort } from "./file-writer.port";
5
5
  import type { ImageSupportedType } from "./image.types";
6
6
  import type { ImageFormatterPort, ImageFormatterStrategy } from "./image-formatter.port";
7
+ import type { NonceProviderPort } from "./nonce-provider.port";
7
8
 
8
9
  type Dependencies = {
9
10
  FileCleaner: FileCleanerPort;
10
11
  FileRenamer: FileRenamerPort;
11
12
  FileWriter: FileWriterPort;
13
+ NonceProvider: NonceProviderPort;
12
14
  };
13
15
 
14
16
  export class ImageFormatterAdapter implements ImageFormatterPort {
@@ -20,7 +22,9 @@ export class ImageFormatterAdapter implements ImageFormatterPort {
20
22
  ? recipe.output
21
23
  : recipe.input.withFilename(recipe.input.getFilename().withExtension(recipe.to));
22
24
 
23
- const temporary = final.withFilename(final.getFilename().withSuffix("-formatted"));
25
+ const temporary = final.withFilename(
26
+ final.getFilename().withSuffix(`-formatted-${this.deps.NonceProvider.generate()}`),
27
+ );
24
28
 
25
29
  const extension = final.getFilename().getExtension();
26
30
  const format = (extension === "jpg" ? "jpeg" : extension) as ImageSupportedType;
@@ -8,6 +8,7 @@ export class ImageGeneratorWebViewAdapter implements ImageGeneratorPort {
8
8
  async generate(config: ImageGeneratorConfig): Promise<Uint8Array<ArrayBuffer>> {
9
9
  await using view = new Bun.WebView(config);
10
10
 
11
+ // TODO: Potential XSS risk
11
12
  await view.navigate(`data:text/html;charset=utf-8,${encodeURIComponent(config.template)}`);
12
13
 
13
14
  const image = await view.screenshot({
@@ -4,8 +4,13 @@ import type { FileRenamerPort } from "./file-renamer.port";
4
4
  import type { FileWriterPort } from "./file-writer.port";
5
5
  import type { ImageSupportedType } from "./image.types";
6
6
  import type { ImageGrayscalePort, ImageGrayscaleStrategy } from "./image-grayscale.port";
7
+ import type { NonceProviderPort } from "./nonce-provider.port";
7
8
 
8
- type Dependencies = { FileRenamer: FileRenamerPort; FileWriter: FileWriterPort };
9
+ type Dependencies = {
10
+ FileRenamer: FileRenamerPort;
11
+ FileWriter: FileWriterPort;
12
+ NonceProvider: NonceProviderPort;
13
+ };
9
14
 
10
15
  export class ImageGrayscaleAdapter implements ImageGrayscalePort {
11
16
  constructor(private readonly deps: Dependencies) {}
@@ -14,7 +19,9 @@ export class ImageGrayscaleAdapter implements ImageGrayscalePort {
14
19
  const final = recipe.strategy === "output_path" ? recipe.output : recipe.input;
15
20
 
16
21
  const filename = final.getFilename();
17
- const temporary = final.withFilename(filename.withSuffix("-grayscale"));
22
+ const temporary = final.withFilename(
23
+ filename.withSuffix(`-grayscale-${this.deps.NonceProvider.generate()}`),
24
+ );
18
25
 
19
26
  const extension = final.getFilename().getExtension();
20
27
  const format = (extension === "jpg" ? "jpeg" : extension) as ImageSupportedType;
@@ -4,11 +4,13 @@ import type { FileRenamerPort } from "./file-renamer.port";
4
4
  import type { FileWriterPort } from "./file-writer.port";
5
5
  import type { ImageSupportedType } from "./image.types";
6
6
  import type { ImageProcessorPort, ImageProcessorStrategy } from "./image-processor.port";
7
+ import type { NonceProviderPort } from "./nonce-provider.port";
7
8
 
8
9
  type Dependencies = {
9
10
  FileCleaner: FileCleanerPort;
10
11
  FileRenamer: FileRenamerPort;
11
12
  FileWriter: FileWriterPort;
13
+ NonceProvider: NonceProviderPort;
12
14
  };
13
15
 
14
16
  export class ImageProcessorAdapter implements ImageProcessorPort {
@@ -22,7 +24,9 @@ export class ImageProcessorAdapter implements ImageProcessorPort {
22
24
  ? recipe.output
23
25
  : recipe.input.withFilename(recipe.input.getFilename().withExtension(recipe.to));
24
26
 
25
- const temporary = final.withFilename(final.getFilename().withSuffix("-processed"));
27
+ const temporary = final.withFilename(
28
+ final.getFilename().withSuffix(`-processed-${this.deps.NonceProvider.generate()}`),
29
+ );
26
30
  const extension = final.getFilename().getExtension();
27
31
  const format = (extension === "jpg" ? "jpeg" : extension) as ImageSupportedType;
28
32
  const quality = recipe.quality ?? ImageProcessorAdapter.DEFAULT_QUALITY;
@@ -4,8 +4,13 @@ import type { FileRenamerPort } from "./file-renamer.port";
4
4
  import type { FileWriterPort } from "./file-writer.port";
5
5
  import type { ImageSupportedType } from "./image.types";
6
6
  import type { ImageResizerPort, ImageResizerStrategy } from "./image-resizer.port";
7
+ import type { NonceProviderPort } from "./nonce-provider.port";
7
8
 
8
- type Dependencies = { FileWriter: FileWriterPort; FileRenamer: FileRenamerPort };
9
+ type Dependencies = {
10
+ FileWriter: FileWriterPort;
11
+ FileRenamer: FileRenamerPort;
12
+ NonceProvider: NonceProviderPort;
13
+ };
9
14
 
10
15
  export class ImageResizerAdapter implements ImageResizerPort {
11
16
  constructor(private readonly deps: Dependencies) {}
@@ -13,7 +18,9 @@ export class ImageResizerAdapter implements ImageResizerPort {
13
18
  async resize(recipe: ImageResizerStrategy): Promise<tools.FilePathRelative | tools.FilePathAbsolute> {
14
19
  const final = recipe.strategy === "output_path" ? recipe.output : recipe.input;
15
20
  const filename = final.getFilename();
16
- const temporary = final.withFilename(filename.withSuffix("-resized"));
21
+ const temporary = final.withFilename(
22
+ filename.withSuffix(`-resized-${this.deps.NonceProvider.generate()}`),
23
+ );
17
24
 
18
25
  const extension = final.getFilename().getExtension();
19
26
  const format = (extension === "jpg" ? "jpeg" : extension) as ImageSupportedType;
@@ -1 +1 @@
1
- export type ImageSupportedType = Exclude<Bun.Image.Format, "bmp" | "tiff" | "gif">;
1
+ export type ImageSupportedType = "jpeg" | "png" | "webp";
package/src/index.ts CHANGED
@@ -10,6 +10,7 @@ export * from "./ab-assignment-query.strategy";
10
10
  export * from "./ab-hono.middleware";
11
11
  export * from "./ab-hono-noop.middleware";
12
12
  export * from "./ab-variant.vo";
13
+ export * from "./ab-variant-name.vo";
13
14
  export * from "./ab-variant-selector.service";
14
15
  export * from "./ab-variant-weight.vo";
15
16
  export * from "./ab-variants.vo";
@@ -201,6 +202,7 @@ export * from "./hcaptcha-secret-key.vo";
201
202
  export * from "./hcaptcha-site-key.vo";
202
203
  export * from "./healthcheck.handler";
203
204
  export * from "./healthcheck-hono.handler";
205
+ export * from "./hostname.vo";
204
206
  export * from "./http-logger.middleware";
205
207
  export * from "./http-logger-hono.middleware";
206
208
  export * from "./id-provider.port";
@@ -1,7 +1,8 @@
1
1
  import type { StandardSchemaV1 } from "@standard-schema/spec";
2
2
  import type { GenericJob } from "./job.types";
3
- import { type JobHandler, JobRegistryError, type JobRegistryPort } from "./job-registry.port";
3
+ import type { JobHandler, JobRegistryPort } from "./job-registry.port";
4
4
  import type { JobRetryPolicyStrategy } from "./job-retry-policy.strategy";
5
+ import { StandardSchemaValidator } from "./standard-schema-validator.service";
5
6
 
6
7
  export type JobRegistryEntry<Specific extends GenericJob> = {
7
8
  schema: StandardSchemaV1<unknown, Specific>;
@@ -38,11 +39,7 @@ export class JobRegistryAdapter<Job extends GenericJob> implements JobRegistryPo
38
39
  const entry = this.map.get(name);
39
40
  if (!entry) throw new Error(JobRegistryAdapterError.UnknownJob);
40
41
 
41
- const result = entry.schema["~standard"].validate(raw);
42
-
43
- if (result instanceof Promise) throw new Error(JobRegistryError.NoAsyncSchema);
44
- if (result.issues) throw new Error(result.issues[0]?.message);
45
- return result.value;
42
+ return StandardSchemaValidator.validate(entry.schema, raw);
46
43
  }
47
44
 
48
45
  getRetryPolicy(name: GenericJob["name"]): JobRetryPolicyStrategy {
@@ -1,8 +1,6 @@
1
1
  import type { GenericJob } from "./job.types";
2
2
  import type { JobRetryPolicyStrategy } from "./job-retry-policy.strategy";
3
3
 
4
- export const JobRegistryError = { NoAsyncSchema: "job.registry.no.async.schema" };
5
-
6
4
  export type JobHandler<Job extends GenericJob> = (job: Job) => Promise<void>;
7
5
 
8
6
  export interface JobRegistryPort<Job extends GenericJob> {
@@ -15,7 +15,7 @@ export class PrerequisiteVerifierBinaryAdapter implements PrerequisiteVerifierPo
15
15
  const result = Bun.which(this.config.binary);
16
16
 
17
17
  if (result) return PrerequisiteVerification.success;
18
- return PrerequisiteVerification.failure();
18
+ return PrerequisiteVerification.failure("Binary not present");
19
19
  } catch (error) {
20
20
  return PrerequisiteVerification.failure(error);
21
21
  }
@@ -1,11 +1,12 @@
1
1
  import dns from "node:dns/promises";
2
+ import type { HostnameType } from "./hostname.vo";
2
3
  import {
3
4
  PrerequisiteVerification,
4
5
  type PrerequisiteVerificationResult,
5
6
  type PrerequisiteVerifierPort,
6
7
  } from "./prerequisite-verifier.port";
7
8
 
8
- type Config = { hostname: string };
9
+ type Config = { hostname: HostnameType };
9
10
 
10
11
  export class PrerequisiteVerifierDnsAdapter implements PrerequisiteVerifierPort {
11
12
  constructor(private readonly config: Config) {}
@@ -1,5 +1,6 @@
1
1
  import type * as tools from "@bgord/tools";
2
2
  import type { CertificateInspectorPort } from "./certificate-inspector.port";
3
+ import type { HostnameType } from "./hostname.vo";
3
4
  import {
4
5
  PrerequisiteVerification,
5
6
  type PrerequisiteVerificationResult,
@@ -8,7 +9,7 @@ import {
8
9
 
9
10
  type Dependencies = { CertificateInspector: CertificateInspectorPort };
10
11
 
11
- type Config = { hostname: string; minimum: tools.Duration };
12
+ type Config = { hostname: HostnameType; minimum: tools.Duration };
12
13
 
13
14
  export class PrerequisiteVerifierSSLCertificateExpiryAdapter implements PrerequisiteVerifierPort {
14
15
  constructor(
@@ -41,14 +41,14 @@ export class PrerequisiteVerifierTranslationsAdapter<T extends tools.LanguageTyp
41
41
 
42
42
  for (const language in dictionary) {
43
43
  // Stryker disable all
44
- const phrases = dictionary[language] ?? [];
44
+ const translations = dictionary[language] ?? [];
45
45
  // Stryker restore all
46
46
 
47
- for (const phrase of phrases) {
47
+ for (const key of translations) {
48
48
  for (const supportedLanguage of languages) {
49
- const phraseExists = new Set(dictionary[supportedLanguage]).has(phrase);
49
+ const exists = new Set(dictionary[supportedLanguage]).has(key);
50
50
 
51
- if (!phraseExists) problems.push({ key: phrase, existsIn: language, missingIn: supportedLanguage });
51
+ if (!exists) problems.push({ key, existsIn: language, missingIn: supportedLanguage });
52
52
  }
53
53
  }
54
54
  }
@@ -1,10 +1,7 @@
1
1
  import type * as tools from "@bgord/tools";
2
2
  import type { FileReaderJsonPort } from "./file-reader-json.port";
3
- import {
4
- ReactiveConfigError,
5
- type ReactiveConfigPort,
6
- type ReactiveConfigSchema,
7
- } from "./reactive-config.port";
3
+ import type { ReactiveConfigPort, ReactiveConfigSchema } from "./reactive-config.port";
4
+ import { StandardSchemaValidator } from "./standard-schema-validator.service";
8
5
 
9
6
  type Dependencies = { FileReaderJson: FileReaderJsonPort };
10
7
 
@@ -18,9 +15,6 @@ export class ReactiveConfigFileJsonAdapter<T extends object> implements Reactive
18
15
  async get(): Promise<Readonly<T>> {
19
16
  const raw = await this.deps.FileReaderJson.read(this.path);
20
17
 
21
- const result = this.schema["~standard"].validate(raw);
22
- if (result instanceof Promise) throw new Error(ReactiveConfigError.NoAsyncSchema);
23
- if (result.issues) throw new Error(result.issues[0]?.message);
24
- return Object.freeze(result.value);
18
+ return Object.freeze(StandardSchemaValidator.validate(this.schema, raw));
25
19
  }
26
20
  }