@bgord/bun 1.21.11 → 1.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/alert-channel-composite.adapter.d.ts.map +1 -1
- package/dist/alert-channel-composite.adapter.js +1 -0
- package/dist/alert-channel-composite.adapter.js.map +1 -1
- package/dist/api-version.middleware.d.ts +1 -0
- package/dist/api-version.middleware.d.ts.map +1 -1
- package/dist/api-version.middleware.js +3 -1
- package/dist/api-version.middleware.js.map +1 -1
- package/dist/cache-codec-identity.strategy.d.ts +7 -0
- package/dist/cache-codec-identity.strategy.d.ts.map +1 -0
- package/dist/cache-codec-identity.strategy.js +9 -0
- package/dist/cache-codec-identity.strategy.js.map +1 -0
- package/dist/cache-codec-sitemap-entries.strategy.d.ts +11 -0
- package/dist/cache-codec-sitemap-entries.strategy.d.ts.map +1 -0
- package/dist/cache-codec-sitemap-entries.strategy.js +13 -0
- package/dist/cache-codec-sitemap-entries.strategy.js.map +1 -0
- package/dist/cache-codec.strategy.d.ts +6 -0
- package/dist/cache-codec.strategy.d.ts.map +1 -0
- package/dist/cache-codec.strategy.js +2 -0
- package/dist/cache-codec.strategy.js.map +1 -0
- package/dist/cache-repository-node-cache.adapter.d.ts +3 -2
- package/dist/cache-repository-node-cache.adapter.d.ts.map +1 -1
- package/dist/cache-repository-node-cache.adapter.js +6 -4
- package/dist/cache-repository-node-cache.adapter.js.map +1 -1
- package/dist/cache-repository-noop.adapter.d.ts +3 -2
- package/dist/cache-repository-noop.adapter.d.ts.map +1 -1
- package/dist/cache-repository-noop.adapter.js.map +1 -1
- package/dist/cache-repository-redis.adapter.d.ts +3 -2
- package/dist/cache-repository-redis.adapter.d.ts.map +1 -1
- package/dist/cache-repository-redis.adapter.js +8 -5
- package/dist/cache-repository-redis.adapter.js.map +1 -1
- package/dist/cache-repository.port.d.ts +3 -2
- package/dist/cache-repository.port.d.ts.map +1 -1
- package/dist/cache-resolver-noop.strategy.d.ts +8 -0
- package/dist/cache-resolver-noop.strategy.d.ts.map +1 -0
- package/dist/cache-resolver-noop.strategy.js +7 -0
- package/dist/cache-resolver-noop.strategy.js.map +1 -0
- package/dist/cache-resolver-read-through.strategy.d.ts +15 -0
- package/dist/cache-resolver-read-through.strategy.d.ts.map +1 -0
- package/dist/cache-resolver-read-through.strategy.js +21 -0
- package/dist/cache-resolver-read-through.strategy.js.map +1 -0
- package/dist/cache-resolver.strategy.d.ts +2 -9
- package/dist/cache-resolver.strategy.d.ts.map +1 -1
- package/dist/cache-resolver.strategy.js +1 -5
- package/dist/cache-resolver.strategy.js.map +1 -1
- package/dist/cache-value.vo.d.ts +6 -0
- package/dist/cache-value.vo.d.ts.map +1 -0
- package/dist/cache-value.vo.js +2 -0
- package/dist/cache-value.vo.js.map +1 -0
- package/dist/correlation-id.vo.d.ts.map +1 -1
- package/dist/correlation-id.vo.js +1 -0
- package/dist/correlation-id.vo.js.map +1 -1
- package/dist/cron-scheduler-with-logger.adapter.d.ts +3 -0
- package/dist/cron-scheduler-with-logger.adapter.d.ts.map +1 -1
- package/dist/cron-scheduler-with-logger.adapter.js +29 -7
- package/dist/cron-scheduler-with-logger.adapter.js.map +1 -1
- package/dist/cron-task-handler-with-logger.strategy.js +1 -1
- package/dist/cron-task-handler-with-logger.strategy.js.map +1 -1
- package/dist/crypto-key-provider-with-memo.adapter.d.ts +12 -0
- package/dist/crypto-key-provider-with-memo.adapter.d.ts.map +1 -0
- package/dist/crypto-key-provider-with-memo.adapter.js +17 -0
- package/dist/crypto-key-provider-with-memo.adapter.js.map +1 -0
- package/dist/environment-loader-process-safe.adapter.d.ts +3 -1
- package/dist/environment-loader-process-safe.adapter.d.ts.map +1 -1
- package/dist/environment-loader-process-safe.adapter.js +4 -2
- package/dist/environment-loader-process-safe.adapter.js.map +1 -1
- package/dist/event-store-with-logger.adapter.d.ts +3 -0
- package/dist/event-store-with-logger.adapter.d.ts.map +1 -1
- package/dist/event-store-with-logger.adapter.js +88 -27
- package/dist/event-store-with-logger.adapter.js.map +1 -1
- package/dist/event-stream.vo.d.ts.map +1 -1
- package/dist/event-stream.vo.js +3 -1
- package/dist/event-stream.vo.js.map +1 -1
- package/dist/file-draft-tar-gz.service.d.ts +8 -0
- package/dist/file-draft-tar-gz.service.d.ts.map +1 -0
- package/dist/file-draft-tar-gz.service.js +19 -0
- package/dist/file-draft-tar-gz.service.js.map +1 -0
- package/dist/file-reader-json-with-cache.adapter.d.ts +1 -0
- package/dist/file-reader-json-with-cache.adapter.d.ts.map +1 -1
- package/dist/file-reader-json-with-cache.adapter.js +3 -1
- package/dist/file-reader-json-with-cache.adapter.js.map +1 -1
- package/dist/file-reader-text-with-cache.adapter.d.ts +1 -0
- package/dist/file-reader-text-with-cache.adapter.d.ts.map +1 -1
- package/dist/file-reader-text-with-cache.adapter.js +3 -1
- package/dist/file-reader-text-with-cache.adapter.js.map +1 -1
- package/dist/healthcheck-hono.handler.js +2 -2
- package/dist/healthcheck-hono.handler.js.map +1 -1
- package/dist/healthcheck.handler.d.ts +1 -0
- package/dist/healthcheck.handler.d.ts.map +1 -1
- package/dist/healthcheck.handler.js +1 -0
- package/dist/healthcheck.handler.js.map +1 -1
- package/dist/http-logger-hono.middleware.d.ts.map +1 -1
- package/dist/http-logger-hono.middleware.js +0 -3
- package/dist/http-logger-hono.middleware.js.map +1 -1
- package/dist/http-logger.middleware.d.ts +0 -1
- package/dist/http-logger.middleware.d.ts.map +1 -1
- package/dist/http-logger.middleware.js +0 -1
- package/dist/http-logger.middleware.js.map +1 -1
- package/dist/idempotency-store-cache.adapter.d.ts +13 -0
- package/dist/idempotency-store-cache.adapter.d.ts.map +1 -0
- package/dist/idempotency-store-cache.adapter.js +14 -0
- package/dist/idempotency-store-cache.adapter.js.map +1 -0
- package/dist/idempotency-store-noop.adapter.d.ts +6 -0
- package/dist/idempotency-store-noop.adapter.d.ts.map +1 -0
- package/dist/idempotency-store-noop.adapter.js +6 -0
- package/dist/idempotency-store-noop.adapter.js.map +1 -0
- package/dist/idempotency-store-with-logger.adapter.d.ts +17 -0
- package/dist/idempotency-store-with-logger.adapter.d.ts.map +1 -0
- package/dist/idempotency-store-with-logger.adapter.js +48 -0
- package/dist/idempotency-store-with-logger.adapter.js.map +1 -0
- package/dist/idempotency-store.port.d.ts +5 -0
- package/dist/idempotency-store.port.d.ts.map +1 -0
- package/dist/idempotency-store.port.js +2 -0
- package/dist/idempotency-store.port.js.map +1 -0
- package/dist/image-generator-web-view.adapter.js +8 -72
- package/dist/image-generator-web-view.adapter.js.map +1 -1
- package/dist/index.d.ts +19 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +19 -6
- package/dist/index.js.map +1 -1
- package/dist/job-queue-with-logger.adapter.d.ts +2 -0
- package/dist/job-queue-with-logger.adapter.d.ts.map +1 -1
- package/dist/job-queue-with-logger.adapter.js +133 -36
- package/dist/job-queue-with-logger.adapter.js.map +1 -1
- package/dist/logger.port.d.ts +0 -1
- package/dist/logger.port.d.ts.map +1 -1
- package/dist/mailer-content-html.vo.js +1 -1
- package/dist/mailer-content-html.vo.js.map +1 -1
- package/dist/message-bus-with-logger.adapter.d.ts +2 -0
- package/dist/message-bus-with-logger.adapter.d.ts.map +1 -1
- package/dist/message-bus-with-logger.adapter.js +28 -8
- package/dist/message-bus-with-logger.adapter.js.map +1 -1
- package/dist/modules/preferences/invariants/user-language-has-changed.d.ts +0 -1
- package/dist/modules/preferences/invariants/user-language-has-changed.d.ts.map +1 -1
- package/dist/modules/preferences/invariants/user-language-has-changed.js +0 -4
- package/dist/modules/preferences/invariants/user-language-has-changed.js.map +1 -1
- package/dist/modules/system/invariants/feature-flag-enabled.d.ts +0 -1
- package/dist/modules/system/invariants/feature-flag-enabled.d.ts.map +1 -1
- package/dist/modules/system/invariants/feature-flag-enabled.js +0 -4
- package/dist/modules/system/invariants/feature-flag-enabled.js.map +1 -1
- package/dist/prerequisite-verifier-sqlite.adapter.js +1 -1
- package/dist/prerequisite-verifier-sqlite.adapter.js.map +1 -1
- package/dist/prerequisite-verifier-with-cache.adapter.d.ts +2 -0
- package/dist/prerequisite-verifier-with-cache.adapter.d.ts.map +1 -1
- package/dist/prerequisite-verifier-with-cache.adapter.js +8 -5
- package/dist/prerequisite-verifier-with-cache.adapter.js.map +1 -1
- package/dist/rate-limiter.service.d.ts +22 -0
- package/dist/rate-limiter.service.d.ts.map +1 -0
- package/dist/rate-limiter.service.js +31 -0
- package/dist/rate-limiter.service.js.map +1 -0
- package/dist/reactive-config-with-cache.adapter.d.ts +3 -1
- package/dist/reactive-config-with-cache.adapter.d.ts.map +1 -1
- package/dist/reactive-config-with-cache.adapter.js +3 -1
- package/dist/reactive-config-with-cache.adapter.js.map +1 -1
- package/dist/request-context-hono.adapter.d.ts.map +1 -1
- package/dist/request-context-hono.adapter.js +4 -1
- package/dist/request-context-hono.adapter.js.map +1 -1
- package/dist/secure-key-generator-crypto.adapter.js +1 -1
- package/dist/secure-key-generator-crypto.adapter.js.map +1 -1
- package/dist/security-rule-violation-threshold.strategy.d.ts.map +1 -1
- package/dist/security-rule-violation-threshold.strategy.js +5 -3
- package/dist/security-rule-violation-threshold.strategy.js.map +1 -1
- package/dist/shield-rate-limit-hono.strategy.d.ts +2 -2
- package/dist/shield-rate-limit-hono.strategy.d.ts.map +1 -1
- package/dist/shield-rate-limit.strategy.d.ts +2 -2
- package/dist/shield-rate-limit.strategy.d.ts.map +1 -1
- package/dist/shield-rate-limit.strategy.js +8 -2
- package/dist/shield-rate-limit.strategy.js.map +1 -1
- package/dist/shield-webhook-hono.strategy.d.ts +2 -2
- package/dist/shield-webhook-hono.strategy.d.ts.map +1 -1
- package/dist/shield-webhook-hono.strategy.js +7 -3
- package/dist/shield-webhook-hono.strategy.js.map +1 -1
- package/dist/shield-webhook.strategy.d.ts +23 -3
- package/dist/shield-webhook.strategy.d.ts.map +1 -1
- package/dist/shield-webhook.strategy.js +18 -4
- package/dist/shield-webhook.strategy.js.map +1 -1
- package/dist/sitemap-entries-provider-with-cache.adapter.d.ts +2 -0
- package/dist/sitemap-entries-provider-with-cache.adapter.d.ts.map +1 -1
- package/dist/sitemap-entries-provider-with-cache.adapter.js +8 -5
- package/dist/sitemap-entries-provider-with-cache.adapter.js.map +1 -1
- package/dist/sitemap-entry.vo.d.ts +11 -10
- package/dist/sitemap-entry.vo.d.ts.map +1 -1
- package/dist/sitemap-entry.vo.js +19 -0
- package/dist/sitemap-entry.vo.js.map +1 -1
- package/dist/smtp-port.vo.d.ts.map +1 -1
- package/dist/smtp-port.vo.js +1 -0
- package/dist/smtp-port.vo.js.map +1 -1
- package/dist/sse-registry-with-logger.adapter.d.ts +2 -0
- package/dist/sse-registry-with-logger.adapter.d.ts.map +1 -1
- package/dist/sse-registry-with-logger.adapter.js +80 -22
- package/dist/sse-registry-with-logger.adapter.js.map +1 -1
- package/dist/translations-provider-with-cache.adapter.d.ts +21 -0
- package/dist/translations-provider-with-cache.adapter.d.ts.map +1 -0
- package/dist/translations-provider-with-cache.adapter.js +22 -0
- package/dist/translations-provider-with-cache.adapter.js.map +1 -0
- package/dist/uuid.vo.js +1 -0
- package/dist/uuid.vo.js.map +1 -1
- package/dist/webhook-id-extractor-header.strategy.d.ts +9 -0
- package/dist/webhook-id-extractor-header.strategy.d.ts.map +1 -0
- package/dist/webhook-id-extractor-header.strategy.js +13 -0
- package/dist/webhook-id-extractor-header.strategy.js.map +1 -0
- package/dist/webhook-id-extractor-json-field.strategy.d.ts +9 -0
- package/dist/webhook-id-extractor-json-field.strategy.d.ts.map +1 -0
- package/dist/webhook-id-extractor-json-field.strategy.js +14 -0
- package/dist/webhook-id-extractor-json-field.strategy.js.map +1 -0
- package/dist/webhook-id-extractor.strategy.d.ts +6 -0
- package/dist/webhook-id-extractor.strategy.d.ts.map +1 -0
- package/dist/webhook-id-extractor.strategy.js +2 -0
- package/dist/webhook-id-extractor.strategy.js.map +1 -0
- package/dist/webhook-id.vo.d.ts +9 -0
- package/dist/webhook-id.vo.d.ts.map +1 -0
- package/dist/webhook-id.vo.js +10 -0
- package/dist/webhook-id.vo.js.map +1 -0
- package/dist/{webhook-signature-extractor-header-exact.strategy.d.ts → webhook-signature-extractor-header.strategy.d.ts} +2 -2
- package/dist/webhook-signature-extractor-header.strategy.d.ts.map +1 -0
- package/dist/{webhook-signature-extractor-header-exact.strategy.js → webhook-signature-extractor-header.strategy.js} +2 -2
- package/dist/webhook-signature-extractor-header.strategy.js.map +1 -0
- package/package.json +12 -18
- package/readme.md +19 -6
- package/src/alert-channel-composite.adapter.ts +1 -0
- package/src/api-version.middleware.ts +6 -2
- package/src/cache-codec-identity.strategy.ts +12 -0
- package/src/cache-codec-sitemap-entries.strategy.ts +17 -0
- package/src/cache-codec.strategy.ts +6 -0
- package/src/cache-repository-node-cache.adapter.ts +9 -5
- package/src/cache-repository-noop.adapter.ts +3 -2
- package/src/cache-repository-redis.adapter.ts +10 -7
- package/src/cache-repository.port.ts +3 -2
- package/src/cache-resolver-noop.strategy.ts +11 -0
- package/src/cache-resolver-read-through.strategy.ts +27 -0
- package/src/cache-resolver.strategy.ts +2 -11
- package/src/cache-value.vo.ts +9 -0
- package/src/correlation-id.vo.ts +1 -0
- package/src/cron-scheduler-with-logger.adapter.ts +35 -9
- package/src/cron-task-handler-with-logger.strategy.ts +1 -1
- package/src/crypto-key-provider-with-memo.adapter.ts +21 -0
- package/src/environment-loader-process-safe.adapter.ts +12 -4
- package/src/event-store-with-logger.adapter.ts +97 -27
- package/src/event-stream.vo.ts +1 -0
- package/src/file-draft-tar-gz.service.ts +23 -0
- package/src/file-reader-json-with-cache.adapter.ts +7 -2
- package/src/file-reader-text-with-cache.adapter.ts +8 -1
- package/src/healthcheck-hono.handler.ts +2 -2
- package/src/healthcheck.handler.ts +2 -0
- package/src/http-logger-hono.middleware.ts +0 -3
- package/src/http-logger.middleware.ts +0 -2
- package/src/idempotency-store-cache.adapter.ts +19 -0
- package/src/idempotency-store-noop.adapter.ts +8 -0
- package/src/idempotency-store-with-logger.adapter.ts +59 -0
- package/src/idempotency-store.port.ts +5 -0
- package/src/index.ts +19 -6
- package/src/job-queue-with-logger.adapter.ts +156 -43
- package/src/logger.port.ts +0 -1
- package/src/message-bus-with-logger.adapter.ts +37 -10
- package/src/modules/preferences/invariants/user-language-has-changed.ts +1 -6
- package/src/modules/system/invariants/feature-flag-enabled.ts +1 -6
- package/src/prerequisite-verifier-sqlite.adapter.ts +1 -1
- package/src/prerequisite-verifier-with-cache.adapter.ts +13 -7
- package/src/rate-limiter.service.ts +45 -0
- package/src/reactive-config-with-cache.adapter.ts +8 -2
- package/src/request-context-hono.adapter.ts +5 -1
- package/src/security-rule-violation-threshold.strategy.ts +5 -6
- package/src/shield-rate-limit-hono.strategy.ts +2 -2
- package/src/shield-rate-limit.strategy.ts +14 -7
- package/src/shield-webhook-hono.strategy.ts +11 -3
- package/src/shield-webhook.strategy.ts +41 -6
- package/src/sitemap-entries-provider-with-cache.adapter.ts +13 -7
- package/src/sitemap-entry.vo.ts +23 -11
- package/src/smtp-port.vo.ts +1 -0
- package/src/sse-registry-with-logger.adapter.ts +94 -25
- package/src/translations-provider-with-cache.adapter.ts +38 -0
- package/src/uuid.vo.ts +1 -1
- package/src/webhook-id-extractor-header.strategy.ts +14 -0
- package/src/webhook-id-extractor-json-field.strategy.ts +16 -0
- package/src/webhook-id-extractor.strategy.ts +6 -0
- package/src/webhook-id.vo.ts +17 -0
- package/src/{webhook-signature-extractor-header-exact.strategy.ts → webhook-signature-extractor-header.strategy.ts} +1 -1
- package/dist/cache-resolver-simple.strategy.d.ts +0 -18
- package/dist/cache-resolver-simple.strategy.d.ts.map +0 -1
- package/dist/cache-resolver-simple.strategy.js +0 -23
- package/dist/cache-resolver-simple.strategy.js.map +0 -1
- package/dist/cache-response-hono.middleware.d.ts +0 -9
- package/dist/cache-response-hono.middleware.d.ts.map +0 -1
- package/dist/cache-response-hono.middleware.js +0 -34
- package/dist/cache-response-hono.middleware.js.map +0 -1
- package/dist/cache-response.middleware.d.ts +0 -28
- package/dist/cache-response.middleware.d.ts.map +0 -1
- package/dist/cache-response.middleware.js +0 -20
- package/dist/cache-response.middleware.js.map +0 -1
- package/dist/crypto-key-provider-with-cache.adapter.d.ts +0 -19
- package/dist/crypto-key-provider-with-cache.adapter.d.ts.map +0 -1
- package/dist/crypto-key-provider-with-cache.adapter.js +0 -19
- package/dist/crypto-key-provider-with-cache.adapter.js.map +0 -1
- package/dist/file-draft-zip.service.d.ts +0 -14
- package/dist/file-draft-zip.service.d.ts.map +0 -1
- package/dist/file-draft-zip.service.js +0 -41
- package/dist/file-draft-zip.service.js.map +0 -1
- package/dist/webhook-signature-extractor-header-exact.strategy.d.ts.map +0 -1
- package/dist/webhook-signature-extractor-header-exact.strategy.js.map +0 -1
- package/src/cache-resolver-simple.strategy.ts +0 -33
- package/src/cache-response-hono.middleware.ts +0 -53
- package/src/cache-response.middleware.ts +0 -47
- package/src/crypto-key-provider-with-cache.adapter.ts +0 -30
- package/src/file-draft-zip.service.ts +0 -56
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CacheCodecSitemapEntriesStrategy } from "./cache-codec-sitemap-entries.strategy";
|
|
1
2
|
import type { CacheResolverStrategy } from "./cache-resolver.strategy";
|
|
2
3
|
import type { HashContentStrategy } from "./hash-content.strategy";
|
|
3
4
|
import type { SitemapEntriesProvider } from "./sitemap-entries-provider.port";
|
|
@@ -9,24 +10,29 @@ type Config = { id: string; inner: SitemapEntriesProvider };
|
|
|
9
10
|
type Dependencies = { CacheResolver: CacheResolverStrategy; HashContent: HashContentStrategy };
|
|
10
11
|
|
|
11
12
|
export class SitemapEntriesProviderWithCacheAdapter implements SitemapEntriesProvider {
|
|
13
|
+
private readonly codec = new CacheCodecSitemapEntriesStrategy();
|
|
14
|
+
private readonly resolver: SubjectApplicationResolver;
|
|
15
|
+
|
|
12
16
|
constructor(
|
|
13
17
|
private readonly config: Config,
|
|
14
18
|
private readonly deps: Dependencies,
|
|
15
|
-
) {
|
|
16
|
-
|
|
17
|
-
async produce(): Promise<ReadonlyArray<SitemapEntry>> {
|
|
18
|
-
const resolver = new SubjectApplicationResolver(
|
|
19
|
+
) {
|
|
20
|
+
this.resolver = new SubjectApplicationResolver(
|
|
19
21
|
[
|
|
20
22
|
new SubjectSegmentFixedStrategy("sitemap_entries_provider"),
|
|
21
23
|
new SubjectSegmentFixedStrategy(this.config.id),
|
|
22
24
|
],
|
|
23
25
|
this.deps,
|
|
24
26
|
);
|
|
27
|
+
}
|
|
25
28
|
|
|
26
|
-
|
|
29
|
+
async produce(): Promise<ReadonlyArray<SitemapEntry>> {
|
|
30
|
+
const subject = await this.resolver.resolve();
|
|
27
31
|
|
|
28
|
-
return this.deps.CacheResolver.resolve<ReadonlyArray<SitemapEntry>>(
|
|
29
|
-
|
|
32
|
+
return this.deps.CacheResolver.resolve<ReadonlyArray<SitemapEntry>>(
|
|
33
|
+
subject.hex,
|
|
34
|
+
async () => this.config.inner.produce(),
|
|
35
|
+
this.codec,
|
|
30
36
|
);
|
|
31
37
|
}
|
|
32
38
|
}
|
package/src/sitemap-entry.vo.ts
CHANGED
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
// cspell:ignore apos
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
2
|
+
import * as tools from "@bgord/tools";
|
|
3
|
+
import * as v from "valibot";
|
|
4
|
+
import { SitemapChangefreqEnum } from "./sitemap-changefreq.vo";
|
|
5
|
+
import { SitemapPriority } from "./sitemap-priority.vo";
|
|
6
|
+
import { SitemapUrl } from "./sitemap-url.vo";
|
|
7
|
+
import { StandardSchemaValidator } from "./standard-schema-validator.service";
|
|
8
|
+
|
|
9
|
+
export const SitemapEntrySchema = v.object({
|
|
10
|
+
loc: SitemapUrl,
|
|
11
|
+
lastmod: v.optional(tools.DayIsoId),
|
|
12
|
+
changefreq: v.optional(v.enum(SitemapChangefreqEnum)),
|
|
13
|
+
priority: v.optional(SitemapPriority),
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export type SitemapEntryType = v.InferOutput<typeof SitemapEntrySchema>;
|
|
13
17
|
|
|
14
18
|
export class SitemapEntry {
|
|
15
19
|
constructor(private readonly entry: SitemapEntryType) {}
|
|
@@ -23,6 +27,14 @@ export class SitemapEntry {
|
|
|
23
27
|
.replace(/'/g, "'");
|
|
24
28
|
}
|
|
25
29
|
|
|
30
|
+
static fromJSON(raw: unknown): SitemapEntry {
|
|
31
|
+
return new SitemapEntry(StandardSchemaValidator.validate(SitemapEntrySchema, raw));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
toJSON(): SitemapEntryType {
|
|
35
|
+
return { ...this.entry };
|
|
36
|
+
}
|
|
37
|
+
|
|
26
38
|
toXml(): string {
|
|
27
39
|
const loc = `<loc>${this.escapeXml(this.entry.loc)}</loc>`;
|
|
28
40
|
const lastmod = this.entry.lastmod ? `<lastmod>${this.entry.lastmod}</lastmod>` : "";
|
package/src/smtp-port.vo.ts
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
+
import type { ClockPort } from "./clock.port";
|
|
1
2
|
import { CorrelationStorage } from "./correlation-storage.service";
|
|
2
3
|
import type { HashValueType } from "./hash-value.vo";
|
|
3
4
|
import type { LoggerPort } from "./logger.port";
|
|
4
5
|
import type { Message } from "./message.types";
|
|
5
6
|
import type { SseRegistryPort, SseSenderType } from "./sse-registry.port";
|
|
7
|
+
import { Stopwatch } from "./stopwatch.service";
|
|
6
8
|
|
|
7
|
-
type Dependencies<Messages extends Message> = {
|
|
9
|
+
type Dependencies<Messages extends Message> = {
|
|
10
|
+
inner: SseRegistryPort<Messages>;
|
|
11
|
+
Logger: LoggerPort;
|
|
12
|
+
Clock: ClockPort;
|
|
13
|
+
};
|
|
8
14
|
|
|
9
15
|
export class SseRegistryWithLoggerAdapter<Messages extends Message> implements SseRegistryPort<Messages> {
|
|
10
16
|
private readonly base = { component: "infra", operation: "sse_registry" };
|
|
@@ -12,38 +18,101 @@ export class SseRegistryWithLoggerAdapter<Messages extends Message> implements S
|
|
|
12
18
|
constructor(private readonly deps: Dependencies<Messages>) {}
|
|
13
19
|
|
|
14
20
|
register(identity: HashValueType, sender: SseSenderType<Messages>): boolean {
|
|
15
|
-
const
|
|
21
|
+
const duration = new Stopwatch(this.deps);
|
|
16
22
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
try {
|
|
24
|
+
this.deps.Logger.info({
|
|
25
|
+
message: "SSE registry register attempt",
|
|
26
|
+
correlationId: CorrelationStorage.get(),
|
|
27
|
+
metadata: { identity },
|
|
28
|
+
...this.base,
|
|
29
|
+
});
|
|
23
30
|
|
|
24
|
-
|
|
31
|
+
const registered = this.deps.inner.register(identity, sender);
|
|
32
|
+
|
|
33
|
+
this.deps.Logger.info({
|
|
34
|
+
message: "SSE registry register success",
|
|
35
|
+
correlationId: CorrelationStorage.get(),
|
|
36
|
+
metadata: { identity, registered, duration: duration.stop() },
|
|
37
|
+
...this.base,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
return registered;
|
|
41
|
+
} catch (error) {
|
|
42
|
+
this.deps.Logger.error({
|
|
43
|
+
message: "SSE registry register error",
|
|
44
|
+
correlationId: CorrelationStorage.get(),
|
|
45
|
+
error,
|
|
46
|
+
metadata: { identity, duration: duration.stop() },
|
|
47
|
+
...this.base,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
25
52
|
}
|
|
26
53
|
|
|
27
54
|
unregister(identity: HashValueType, sender: SseSenderType<Messages>): void {
|
|
28
|
-
this.deps
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
55
|
+
const duration = new Stopwatch(this.deps);
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
this.deps.Logger.info({
|
|
59
|
+
message: "SSE registry unregister attempt",
|
|
60
|
+
correlationId: CorrelationStorage.get(),
|
|
61
|
+
metadata: { identity },
|
|
62
|
+
...this.base,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
this.deps.inner.unregister(identity, sender);
|
|
66
|
+
|
|
67
|
+
this.deps.Logger.info({
|
|
68
|
+
message: "SSE registry unregister success",
|
|
69
|
+
correlationId: CorrelationStorage.get(),
|
|
70
|
+
metadata: { identity, duration: duration.stop() },
|
|
71
|
+
...this.base,
|
|
72
|
+
});
|
|
73
|
+
} catch (error) {
|
|
74
|
+
this.deps.Logger.error({
|
|
75
|
+
message: "SSE registry unregister error",
|
|
76
|
+
correlationId: CorrelationStorage.get(),
|
|
77
|
+
error,
|
|
78
|
+
metadata: { identity, duration: duration.stop() },
|
|
79
|
+
...this.base,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
36
84
|
}
|
|
37
85
|
|
|
38
86
|
async emit<M extends Messages>(identity: HashValueType, message: M): Promise<void> {
|
|
39
|
-
this.deps
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
87
|
+
const duration = new Stopwatch(this.deps);
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
this.deps.Logger.info({
|
|
91
|
+
message: "SSE registry emit attempt",
|
|
92
|
+
correlationId: CorrelationStorage.get(),
|
|
93
|
+
metadata: { identity, message },
|
|
94
|
+
...this.base,
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
await this.deps.inner.emit(identity, message);
|
|
98
|
+
|
|
99
|
+
this.deps.Logger.info({
|
|
100
|
+
message: "SSE registry emit success",
|
|
101
|
+
correlationId: CorrelationStorage.get(),
|
|
102
|
+
metadata: { identity, message, duration: duration.stop() },
|
|
103
|
+
...this.base,
|
|
104
|
+
});
|
|
105
|
+
} catch (error) {
|
|
106
|
+
this.deps.Logger.error({
|
|
107
|
+
message: "SSE registry emit error",
|
|
108
|
+
correlationId: CorrelationStorage.get(),
|
|
109
|
+
error,
|
|
110
|
+
metadata: { identity, message, duration: duration.stop() },
|
|
111
|
+
...this.base,
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
throw error;
|
|
115
|
+
}
|
|
47
116
|
}
|
|
48
117
|
|
|
49
118
|
count(identity: HashValueType): number {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type * as tools from "@bgord/tools";
|
|
2
|
+
import { CacheCodecIdentityStrategy } from "./cache-codec-identity.strategy";
|
|
3
|
+
import type { CacheResolverStrategy } from "./cache-resolver.strategy";
|
|
4
|
+
import type { HashContentStrategy } from "./hash-content.strategy";
|
|
5
|
+
import { SubjectApplicationResolver } from "./subject-application-resolver.vo";
|
|
6
|
+
import { SubjectSegmentFixedStrategy } from "./subject-segment-fixed.strategy";
|
|
7
|
+
import type { TranslationsProviderPort, TranslationsType } from "./translations-provider.port";
|
|
8
|
+
|
|
9
|
+
type Config = { id: string; inner: TranslationsProviderPort };
|
|
10
|
+
type Dependencies = { CacheResolver: CacheResolverStrategy; HashContent: HashContentStrategy };
|
|
11
|
+
|
|
12
|
+
export class TranslationsProviderWithCacheAdapter implements TranslationsProviderPort {
|
|
13
|
+
private readonly codec = new CacheCodecIdentityStrategy<TranslationsType>();
|
|
14
|
+
|
|
15
|
+
constructor(
|
|
16
|
+
private readonly config: Config,
|
|
17
|
+
private readonly deps: Dependencies,
|
|
18
|
+
) {}
|
|
19
|
+
|
|
20
|
+
async getTranslationsFor(language: tools.LanguageType): Promise<TranslationsType> {
|
|
21
|
+
const resolver = new SubjectApplicationResolver(
|
|
22
|
+
[
|
|
23
|
+
new SubjectSegmentFixedStrategy("translations_provider"),
|
|
24
|
+
new SubjectSegmentFixedStrategy(this.config.id),
|
|
25
|
+
new SubjectSegmentFixedStrategy(language),
|
|
26
|
+
],
|
|
27
|
+
this.deps,
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
const subject = await resolver.resolve();
|
|
31
|
+
|
|
32
|
+
return this.deps.CacheResolver.resolve<TranslationsType>(
|
|
33
|
+
subject.hex,
|
|
34
|
+
async () => this.config.inner.getTranslationsFor(language),
|
|
35
|
+
this.codec,
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
}
|
package/src/uuid.vo.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as v from "valibot";
|
|
2
2
|
|
|
3
3
|
export const UUIDError = { Type: "uuid.type" } as const;
|
|
4
|
-
|
|
4
|
+
// Stryker disable next-line StringLiteral
|
|
5
5
|
export const UUID = v.pipe(v.string(UUIDError.Type), v.uuid(UUIDError.Type), v.brand("UUID"));
|
|
6
6
|
|
|
7
7
|
export type UUIDType = v.InferOutput<typeof UUID>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
import type { HasRequestHeader } from "./request-context.port";
|
|
3
|
+
import { WebhookId, type WebhookIdType } from "./webhook-id.vo";
|
|
4
|
+
import type { WebhookIdExtractorStrategy } from "./webhook-id-extractor.strategy";
|
|
5
|
+
|
|
6
|
+
export class WebhookIdExtractorHeaderStrategy implements WebhookIdExtractorStrategy {
|
|
7
|
+
constructor(private readonly header: string) {}
|
|
8
|
+
|
|
9
|
+
async extract(context: HasRequestHeader): Promise<WebhookIdType | null> {
|
|
10
|
+
const id = v.safeParse(WebhookId, context.request.header(this.header));
|
|
11
|
+
|
|
12
|
+
return id.success ? id.output : null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
import type { HasRequestJson } from "./request-context.port";
|
|
3
|
+
import { WebhookId, type WebhookIdType } from "./webhook-id.vo";
|
|
4
|
+
import type { WebhookIdExtractorStrategy } from "./webhook-id-extractor.strategy";
|
|
5
|
+
|
|
6
|
+
export class WebhookIdExtractorJsonFieldStrategy implements WebhookIdExtractorStrategy {
|
|
7
|
+
constructor(private readonly field: string) {}
|
|
8
|
+
|
|
9
|
+
async extract(context: HasRequestJson): Promise<WebhookIdType | null> {
|
|
10
|
+
const body = await context.request.json();
|
|
11
|
+
|
|
12
|
+
const id = v.safeParse(WebhookId, body[this.field]);
|
|
13
|
+
|
|
14
|
+
return id.success ? id.output : null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { HasRequestHeader, HasRequestJson } from "./request-context.port";
|
|
2
|
+
import type { WebhookIdType } from "./webhook-id.vo";
|
|
3
|
+
|
|
4
|
+
export interface WebhookIdExtractorStrategy {
|
|
5
|
+
extract(context: HasRequestHeader & HasRequestJson): Promise<WebhookIdType | null>;
|
|
6
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
|
|
3
|
+
export const WebhookIdError = {
|
|
4
|
+
Type: "webhook.id.type",
|
|
5
|
+
Empty: "webhook.id.empty",
|
|
6
|
+
TooLong: "webhook.id.too.long",
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const WebhookId = v.pipe(
|
|
10
|
+
v.string(WebhookIdError.Type),
|
|
11
|
+
v.minLength(1, WebhookIdError.Empty),
|
|
12
|
+
v.maxLength(128, WebhookIdError.TooLong),
|
|
13
|
+
// Stryker disable next-line StringLiteral
|
|
14
|
+
v.brand("WebhookId"),
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
export type WebhookIdType = v.InferOutput<typeof WebhookId>;
|
|
@@ -3,7 +3,7 @@ import type { HasRequestHeader } from "./request-context.port";
|
|
|
3
3
|
import { WebhookSignature, type WebhookSignatureType } from "./webhook-signature.vo";
|
|
4
4
|
import type { WebhookSignatureExtractorStrategy } from "./webhook-signature-extractor.strategy";
|
|
5
5
|
|
|
6
|
-
export class
|
|
6
|
+
export class WebhookSignatureExtractorHeaderStrategy implements WebhookSignatureExtractorStrategy {
|
|
7
7
|
constructor(private readonly header: string) {}
|
|
8
8
|
|
|
9
9
|
extract(context: HasRequestHeader): WebhookSignatureType | null {
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { CacheRepositoryPort } from "./cache-repository.port";
|
|
2
|
-
import { type CacheResolverStrategy, CacheSourceEnum } from "./cache-resolver.strategy";
|
|
3
|
-
import type { Hash } from "./hash.vo";
|
|
4
|
-
type Dependencies = {
|
|
5
|
-
CacheRepository: CacheRepositoryPort;
|
|
6
|
-
};
|
|
7
|
-
export declare class CacheResolverSimpleStrategy implements CacheResolverStrategy {
|
|
8
|
-
private readonly deps;
|
|
9
|
-
constructor(deps: Dependencies);
|
|
10
|
-
resolve<T>(subject: Hash, producer: () => Promise<T>): Promise<T>;
|
|
11
|
-
resolveWithContext<T>(subject: Hash, producer: () => Promise<T>): Promise<{
|
|
12
|
-
value: T;
|
|
13
|
-
source: CacheSourceEnum;
|
|
14
|
-
}>;
|
|
15
|
-
flush(): Promise<void>;
|
|
16
|
-
}
|
|
17
|
-
export {};
|
|
18
|
-
//# sourceMappingURL=cache-resolver-simple.strategy.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cache-resolver-simple.strategy.d.ts","sourceRoot":"","sources":["../src/cache-resolver-simple.strategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,KAAK,qBAAqB,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACxF,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEtC,KAAK,YAAY,GAAG;IAAE,eAAe,EAAE,mBAAmB,CAAA;CAAE,CAAC;AAE7D,qBAAa,2BAA4B,YAAW,qBAAqB;IAC3D,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,YAAY,EAAI;IAE7C,OAAO,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAItE;IAEK,kBAAkB,CAAC,CAAC,EACxB,OAAO,EAAE,IAAI,EACb,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACzB,OAAO,CAAC;QAAE,KAAK,EAAE,CAAC,CAAC;QAAC,MAAM,EAAE,eAAe,CAAA;KAAE,CAAC,CAShD;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAE3B;CACF"}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { CacheSourceEnum } from "./cache-resolver.strategy";
|
|
2
|
-
export class CacheResolverSimpleStrategy {
|
|
3
|
-
deps;
|
|
4
|
-
constructor(deps) {
|
|
5
|
-
this.deps = deps;
|
|
6
|
-
}
|
|
7
|
-
async resolve(subject, producer) {
|
|
8
|
-
const result = await this.resolveWithContext(subject, producer);
|
|
9
|
-
return result.value;
|
|
10
|
-
}
|
|
11
|
-
async resolveWithContext(subject, producer) {
|
|
12
|
-
const cached = await this.deps.CacheRepository.get(subject);
|
|
13
|
-
if (cached !== null)
|
|
14
|
-
return { value: cached, source: CacheSourceEnum.hit };
|
|
15
|
-
const value = await producer();
|
|
16
|
-
await this.deps.CacheRepository.set(subject, value);
|
|
17
|
-
return { value, source: CacheSourceEnum.miss };
|
|
18
|
-
}
|
|
19
|
-
async flush() {
|
|
20
|
-
await this.deps.CacheRepository.flush();
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
//# sourceMappingURL=cache-resolver-simple.strategy.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cache-resolver-simple.strategy.js","sourceRoot":"","sources":["../src/cache-resolver-simple.strategy.ts"],"names":[],"mappings":"AACA,OAAO,EAA8B,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAKxF,MAAM,OAAO,2BAA2B;IACT,IAAI;IAAjC,YAA6B,IAAkB;oBAAlB,IAAI;IAAiB,CAAC;IAEnD,KAAK,CAAC,OAAO,CAAI,OAAa,EAAE,QAA0B;QACxD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAEhE,OAAO,MAAM,CAAC,KAAK,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,kBAAkB,CACtB,OAAa,EACb,QAA0B;QAE1B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAI,OAAO,CAAC,CAAC;QAE/D,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,CAAC,GAAG,EAAE,CAAC;QAE3E,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;QAC/B,MAAM,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAEpD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC,IAAI,EAAE,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;IAC1C,CAAC;CACF"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { type CacheResponseMiddlewareConfig, type CacheResponseMiddlewareDependencies } from "./cache-response.middleware";
|
|
2
|
-
import type { MiddlewareHonoPort } from "./middleware-hono.port";
|
|
3
|
-
export declare class CacheResponseHonoMiddleware implements MiddlewareHonoPort {
|
|
4
|
-
private readonly middleware;
|
|
5
|
-
constructor(config: CacheResponseMiddlewareConfig, deps: CacheResponseMiddlewareDependencies);
|
|
6
|
-
handle(): import("hono").MiddlewareHandler<any, string, {}, Response>;
|
|
7
|
-
clear(): import("hono").MiddlewareHandler<any, string, {}, Response>;
|
|
8
|
-
}
|
|
9
|
-
//# sourceMappingURL=cache-response-hono.middleware.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cache-response-hono.middleware.d.ts","sourceRoot":"","sources":["../src/cache-response-hono.middleware.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,6BAA6B,EAClC,KAAK,mCAAmC,EACzC,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAGjE,qBAAa,2BAA4B,YAAW,kBAAkB;IACpE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA0B;IAErD,YAAY,MAAM,EAAE,6BAA6B,EAAE,IAAI,EAAE,mCAAmC,EAE3F;IAED,MAAM,gEA0BL;IAED,KAAK,gEAMJ;CACF"}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { createMiddleware } from "hono/factory";
|
|
2
|
-
import { CacheResponseMiddleware, } from "./cache-response.middleware";
|
|
3
|
-
import { RequestContextHonoAdapter } from "./request-context-hono.adapter";
|
|
4
|
-
export class CacheResponseHonoMiddleware {
|
|
5
|
-
middleware;
|
|
6
|
-
constructor(config, deps) {
|
|
7
|
-
this.middleware = new CacheResponseMiddleware(config, deps);
|
|
8
|
-
}
|
|
9
|
-
handle() {
|
|
10
|
-
return createMiddleware(async (c, next) => {
|
|
11
|
-
const context = new RequestContextHonoAdapter(c);
|
|
12
|
-
const result = await this.middleware.evaluate(context, async () => {
|
|
13
|
-
await next();
|
|
14
|
-
const response = c.res.clone();
|
|
15
|
-
return {
|
|
16
|
-
body: await response.text(),
|
|
17
|
-
headers: response.headers.toJSON(),
|
|
18
|
-
status: response.status,
|
|
19
|
-
};
|
|
20
|
-
});
|
|
21
|
-
if (!result)
|
|
22
|
-
return next();
|
|
23
|
-
c.header(CacheResponseMiddleware.CACHE_HIT_HEADER, result.source);
|
|
24
|
-
return c.newResponse(result.response.body, result.response.status, result.response.headers);
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
clear() {
|
|
28
|
-
return createMiddleware(async (_c, next) => {
|
|
29
|
-
await this.middleware.clear();
|
|
30
|
-
return next();
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=cache-response-hono.middleware.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cache-response-hono.middleware.js","sourceRoot":"","sources":["../src/cache-response-hono.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,EACL,uBAAuB,GAGxB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAE3E,MAAM,OAAO,2BAA2B;IACrB,UAAU,CAA0B;IAErD,YAAY,MAAqC,EAAE,IAAyC;QAC1F,IAAI,CAAC,UAAU,GAAG,IAAI,uBAAuB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC9D,CAAC;IAED,MAAM;QACJ,OAAO,gBAAgB,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;YACxC,MAAM,OAAO,GAAG,IAAI,yBAAyB,CAAC,CAAC,CAAC,CAAC;YAEjD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;gBAChE,MAAM,IAAI,EAAE,CAAC;gBAEb,MAAM,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;gBAE/B,OAAO;oBACL,IAAI,EAAE,MAAM,QAAQ,CAAC,IAAI,EAAE;oBAC3B,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE;oBAClC,MAAM,EAAE,QAAQ,CAAC,MAA8B;iBAChD,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM;gBAAE,OAAO,IAAI,EAAE,CAAC;YAE3B,CAAC,CAAC,MAAM,CAAC,uBAAuB,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YAElE,OAAO,CAAC,CAAC,WAAW,CAClB,MAAM,CAAC,QAAQ,CAAC,IAAI,EACpB,MAAM,CAAC,QAAQ,CAAC,MAA8B,EAC9C,MAAM,CAAC,QAAQ,CAAC,OAAO,CACxB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK;QACH,OAAO,gBAAgB,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE;YACzC,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;YAE9B,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { CacheResolverStrategy, CacheSourceEnum } from "./cache-resolver.strategy";
|
|
2
|
-
import type { RequestContext } from "./request-context.port";
|
|
3
|
-
import type { SubjectRequestResolver } from "./subject-request-resolver.vo";
|
|
4
|
-
export type CacheResponseMiddlewareDependencies = {
|
|
5
|
-
CacheResolver: CacheResolverStrategy;
|
|
6
|
-
};
|
|
7
|
-
export type CacheResponseMiddlewareConfig = {
|
|
8
|
-
enabled: boolean;
|
|
9
|
-
resolver: SubjectRequestResolver;
|
|
10
|
-
};
|
|
11
|
-
export type CachedResponse<T = string> = {
|
|
12
|
-
body: T;
|
|
13
|
-
headers: Record<string, string>;
|
|
14
|
-
status: number;
|
|
15
|
-
};
|
|
16
|
-
export type CacheResponseResult<T = string> = {
|
|
17
|
-
response: CachedResponse<T>;
|
|
18
|
-
source: CacheSourceEnum;
|
|
19
|
-
};
|
|
20
|
-
export declare class CacheResponseMiddleware {
|
|
21
|
-
private readonly config;
|
|
22
|
-
private readonly deps;
|
|
23
|
-
static readonly CACHE_HIT_HEADER = "Cache-Hit";
|
|
24
|
-
constructor(config: CacheResponseMiddlewareConfig, deps: CacheResponseMiddlewareDependencies);
|
|
25
|
-
evaluate<T = string>(context: RequestContext, generateResponse: () => Promise<CachedResponse<T>>): Promise<CacheResponseResult<T> | null>;
|
|
26
|
-
clear(): Promise<void>;
|
|
27
|
-
}
|
|
28
|
-
//# sourceMappingURL=cache-response.middleware.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cache-response.middleware.d.ts","sourceRoot":"","sources":["../src/cache-response.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACxF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAE5E,MAAM,MAAM,mCAAmC,GAAG;IAAE,aAAa,EAAE,qBAAqB,CAAA;CAAE,CAAC;AAE3F,MAAM,MAAM,6BAA6B,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,sBAAsB,CAAA;CAAE,CAAC;AAEnG,MAAM,MAAM,cAAc,CAAC,CAAC,GAAG,MAAM,IAAI;IACvC,IAAI,EAAE,CAAC,CAAC;IACR,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,mBAAmB,CAAC,CAAC,GAAG,MAAM,IAAI;IAC5C,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IAC5B,MAAM,EAAE,eAAe,CAAC;CACzB,CAAC;AAEF,qBAAa,uBAAuB;IAIhC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAJvB,MAAM,CAAC,QAAQ,CAAC,gBAAgB,eAAe;IAE/C,YACmB,MAAM,EAAE,6BAA6B,EACrC,IAAI,EAAE,mCAAmC,EACxD;IAEE,QAAQ,CAAC,CAAC,GAAG,MAAM,EACvB,OAAO,EAAE,cAAc,EACvB,gBAAgB,EAAE,MAAM,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GACjD,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAWxC;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAE3B;CACF"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
export class CacheResponseMiddleware {
|
|
2
|
-
config;
|
|
3
|
-
deps;
|
|
4
|
-
static CACHE_HIT_HEADER = "Cache-Hit";
|
|
5
|
-
constructor(config, deps) {
|
|
6
|
-
this.config = config;
|
|
7
|
-
this.deps = deps;
|
|
8
|
-
}
|
|
9
|
-
async evaluate(context, generateResponse) {
|
|
10
|
-
if (!this.config.enabled)
|
|
11
|
-
return null;
|
|
12
|
-
const subject = await this.config.resolver.resolve(context);
|
|
13
|
-
const result = await this.deps.CacheResolver.resolveWithContext(subject.hex, generateResponse);
|
|
14
|
-
return { response: result.value, source: result.source };
|
|
15
|
-
}
|
|
16
|
-
async clear() {
|
|
17
|
-
await this.deps.CacheResolver.flush();
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
//# sourceMappingURL=cache-response.middleware.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cache-response.middleware.js","sourceRoot":"","sources":["../src/cache-response.middleware.ts"],"names":[],"mappings":"AAmBA,MAAM,OAAO,uBAAuB;IAIf,MAAM;IACN,IAAI;IAJvB,MAAM,CAAU,gBAAgB,GAAG,WAAW,CAAC;IAE/C,YACmB,MAAqC,EACrC,IAAyC;sBADzC,MAAM;oBACN,IAAI;IACpB,CAAC;IAEJ,KAAK,CAAC,QAAQ,CACZ,OAAuB,EACvB,gBAAkD;QAElD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAEtC,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAE5D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,kBAAkB,CAC7D,OAAO,CAAC,GAAG,EACX,gBAAgB,CACjB,CAAC;QAEF,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;IAC3D,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;IACxC,CAAC;CACF"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { CacheResolverStrategy } from "./cache-resolver.strategy";
|
|
2
|
-
import type { CryptoKeyProviderPort } from "./crypto-key-provider.port";
|
|
3
|
-
import type { HashContentStrategy } from "./hash-content.strategy";
|
|
4
|
-
type Dependencies = {
|
|
5
|
-
CacheResolver: CacheResolverStrategy;
|
|
6
|
-
HashContent: HashContentStrategy;
|
|
7
|
-
};
|
|
8
|
-
type Config = {
|
|
9
|
-
id: string;
|
|
10
|
-
inner: CryptoKeyProviderPort;
|
|
11
|
-
};
|
|
12
|
-
export declare class CryptoKeyProviderWithCacheAdapter implements CryptoKeyProviderPort {
|
|
13
|
-
private readonly config;
|
|
14
|
-
private readonly deps;
|
|
15
|
-
constructor(config: Config, deps: Dependencies);
|
|
16
|
-
get(): Promise<CryptoKey>;
|
|
17
|
-
}
|
|
18
|
-
export {};
|
|
19
|
-
//# sourceMappingURL=crypto-key-provider-with-cache.adapter.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"crypto-key-provider-with-cache.adapter.d.ts","sourceRoot":"","sources":["../src/crypto-key-provider-with-cache.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAInE,KAAK,YAAY,GAAG;IAAE,aAAa,EAAE,qBAAqB,CAAC;IAAC,WAAW,EAAE,mBAAmB,CAAA;CAAE,CAAC;AAE/F,KAAK,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,qBAAqB,CAAA;CAAE,CAAC;AAE3D,qBAAa,iCAAkC,YAAW,qBAAqB;IAE3E,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFvB,YACmB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,YAAY,EACjC;IAEE,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC,CAY9B;CACF"}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { SubjectApplicationResolver } from "./subject-application-resolver.vo";
|
|
2
|
-
import { SubjectSegmentFixedStrategy } from "./subject-segment-fixed.strategy";
|
|
3
|
-
export class CryptoKeyProviderWithCacheAdapter {
|
|
4
|
-
config;
|
|
5
|
-
deps;
|
|
6
|
-
constructor(config, deps) {
|
|
7
|
-
this.config = config;
|
|
8
|
-
this.deps = deps;
|
|
9
|
-
}
|
|
10
|
-
async get() {
|
|
11
|
-
const resolver = new SubjectApplicationResolver([
|
|
12
|
-
new SubjectSegmentFixedStrategy("crypto_key_provider"),
|
|
13
|
-
new SubjectSegmentFixedStrategy(this.config.id),
|
|
14
|
-
], this.deps);
|
|
15
|
-
const subject = await resolver.resolve();
|
|
16
|
-
return this.deps.CacheResolver.resolve(subject.hex, () => this.config.inner.get());
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
//# sourceMappingURL=crypto-key-provider-with-cache.adapter.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"crypto-key-provider-with-cache.adapter.js","sourceRoot":"","sources":["../src/crypto-key-provider-with-cache.adapter.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAC/E,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAM/E,MAAM,OAAO,iCAAiC;IAEzB,MAAM;IACN,IAAI;IAFvB,YACmB,MAAc,EACd,IAAkB;sBADlB,MAAM;oBACN,IAAI;IACpB,CAAC;IAEJ,KAAK,CAAC,GAAG;QACP,MAAM,QAAQ,GAAG,IAAI,0BAA0B,CAC7C;YACE,IAAI,2BAA2B,CAAC,qBAAqB,CAAC;YACtD,IAAI,2BAA2B,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;SAChD,EACD,IAAI,CAAC,IAAI,CACV,CAAC;QAEF,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC;QAEzC,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAY,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;IAChG,CAAC;CACF"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import * as tools from "@bgord/tools";
|
|
2
|
-
import { FileDraft } from "./file-draft.service";
|
|
3
|
-
export declare const FileDraftZipError: {
|
|
4
|
-
MissingDependency: string;
|
|
5
|
-
};
|
|
6
|
-
export declare class FileDraftZip extends FileDraft {
|
|
7
|
-
private readonly parts;
|
|
8
|
-
private readonly yazl;
|
|
9
|
-
private static readonly importer;
|
|
10
|
-
private constructor();
|
|
11
|
-
static build(basename: tools.BasenameType, parts: ReadonlyArray<FileDraft>): Promise<FileDraftZip>;
|
|
12
|
-
create(): Promise<BodyInit>;
|
|
13
|
-
}
|
|
14
|
-
//# sourceMappingURL=file-draft-zip.service.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"file-draft-zip.service.d.ts","sourceRoot":"","sources":["../src/file-draft-zip.service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AAGtC,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,eAAO,MAAM,iBAAiB;IAC5B,iBAAiB;CAClB,CAAC;AAIF,qBAAa,YAAa,SAAQ,SAAS;IAQvC,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,IAAI;IARvB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAG9B;IAEF,OAAO,eAMN;IAED,OAAa,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,YAAY,EAAE,KAAK,EAAE,aAAa,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,CAGvG;IAEK,MAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,CAsBhC;CACF"}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
// cspell:ignore Yazl
|
|
2
|
-
import { Readable } from "node:stream";
|
|
3
|
-
import * as tools from "@bgord/tools";
|
|
4
|
-
import * as v from "valibot";
|
|
5
|
-
import { DynamicImport } from "./dynamic-import.service";
|
|
6
|
-
import { FileDraft } from "./file-draft.service";
|
|
7
|
-
export const FileDraftZipError = {
|
|
8
|
-
MissingDependency: "file.draft.zip.error.missing.dependency",
|
|
9
|
-
};
|
|
10
|
-
export class FileDraftZip extends FileDraft {
|
|
11
|
-
parts;
|
|
12
|
-
yazl;
|
|
13
|
-
static importer = DynamicImport.for("yazl", FileDraftZipError.MissingDependency);
|
|
14
|
-
constructor(basename, parts, yazl) {
|
|
15
|
-
super(basename, v.parse(tools.Extension, "zip"), tools.Mimes.zip.mime);
|
|
16
|
-
this.parts = parts;
|
|
17
|
-
this.yazl = yazl;
|
|
18
|
-
}
|
|
19
|
-
static async build(basename, parts) {
|
|
20
|
-
const library = await FileDraftZip.importer.resolve();
|
|
21
|
-
return new FileDraftZip(basename, parts, library);
|
|
22
|
-
}
|
|
23
|
-
async create() {
|
|
24
|
-
const zip = new this.yazl.ZipFile();
|
|
25
|
-
const chunks = [];
|
|
26
|
-
zip.outputStream.on("data", (buffer) => chunks.push(buffer));
|
|
27
|
-
const output = new Promise((resolve, reject) => {
|
|
28
|
-
zip.outputStream.on("end", () => resolve(Uint8Array.from(Buffer.concat(chunks))));
|
|
29
|
-
// Stryker disable all
|
|
30
|
-
zip.outputStream.on("error", reject);
|
|
31
|
-
// Stryker restore all
|
|
32
|
-
});
|
|
33
|
-
for (const part of this.parts) {
|
|
34
|
-
const bytes = await new Response(await part.create()).bytes();
|
|
35
|
-
zip.addReadStream(Readable.from([bytes]), part.filename.get());
|
|
36
|
-
}
|
|
37
|
-
zip.end();
|
|
38
|
-
return output;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
//# sourceMappingURL=file-draft-zip.service.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"file-draft-zip.service.js","sourceRoot":"","sources":["../src/file-draft-zip.service.ts"],"names":[],"mappings":"AAAA,qBAAqB;AACrB,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,iBAAiB,EAAE,yCAAyC;CAC7D,CAAC;AAIF,MAAM,OAAO,YAAa,SAAQ,SAAS;IAQtB,KAAK;IACL,IAAI;IARf,MAAM,CAAU,QAAQ,GAAG,aAAa,CAAC,GAAG,CAClD,MAAM,EACN,iBAAiB,CAAC,iBAAiB,CACpC,CAAC;IAEF,YACE,QAA4B,EACX,KAA+B,EAC/B,IAAiB;QAElC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;qBAHtD,KAAK;oBACL,IAAI;IAGvB,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,QAA4B,EAAE,KAA+B;QAC9E,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;QACtD,OAAO,IAAI,YAAY,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,MAAM;QACV,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACpC,MAAM,MAAM,GAAkB,EAAE,CAAC;QAEjC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,MAAc,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QAErE,MAAM,MAAM,GAAG,IAAI,OAAO,CAAW,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACvD,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAClF,sBAAsB;YACtB,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACrC,sBAAsB;QACxB,CAAC,CAAC,CAAC;QAEH,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,MAAM,IAAI,QAAQ,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;YAE9D,GAAG,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC;QACjE,CAAC;QAED,GAAG,CAAC,GAAG,EAAE,CAAC;QAEV,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
|