appos 0.3.5-0 → 0.3.6-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/main.mjs +2 -2
- package/dist/exports/api/adapter-C2mMJKvG.mjs +1504 -0
- package/dist/exports/api/{auth-schema.mjs → auth-schema-CON4yFFY.mjs} +2 -3
- package/dist/exports/api/bun-sqlite-dialect-CPpPZa23.mjs +155 -0
- package/dist/exports/{cli/_virtual/rolldown_runtime.mjs → api/chunk-CyXqrcp_.mjs} +14 -1
- package/dist/exports/api/conditions-DjBAWfiK.mjs +116 -0
- package/dist/exports/api/dialect-CUUD24Ge.mjs +72 -0
- package/dist/exports/api/env-CwT3zhez.mjs +1 -0
- package/dist/exports/api/esm-_hkVMulx.mjs +15816 -0
- package/dist/exports/api/event-BHFSE6hY.mjs +20983 -0
- package/dist/exports/api/extract-blob-metadata-BMgUEPcW.mjs +4 -0
- package/dist/exports/api/extract-blob-metadata-_9RUEwoU.mjs +9818 -0
- package/dist/exports/api/generate-image-variant-DOIzj1wJ.mjs +4 -0
- package/dist/exports/api/generate-image-variant-DxOPoGAk.mjs +118 -0
- package/dist/exports/api/generate-preview-CvTFuq58.mjs +160 -0
- package/dist/exports/api/generate-preview-Dk3coswZ.mjs +4 -0
- package/dist/exports/api/index.d.mts +7347 -20
- package/dist/exports/api/index.mjs +146856 -18
- package/dist/exports/api/kysely-adapter-CmP2TbkS.mjs +296 -0
- package/dist/exports/api/memory-adapter-BzhRhLFK.mjs +212 -0
- package/dist/exports/api/node-sqlite-dialect-Bl5suBxl.mjs +155 -0
- package/dist/exports/api/orm-CMqufD21.mjs +153690 -0
- package/dist/exports/api/orm-DXqYuKvB.d.mts +11 -0
- package/dist/exports/api/orm.d.mts +2 -11
- package/dist/exports/api/orm.mjs +4 -42
- package/dist/exports/api/pdf-YxB2Hm1p.mjs +25822 -0
- package/dist/exports/api/purge-attachment-Cf6KH2Jv.mjs +34 -0
- package/dist/exports/api/purge-attachment-DIuil7ps.mjs +4 -0
- package/dist/exports/{cli/api/workflows/purge-audit-logs.mjs → api/purge-audit-logs-z6j_Pu47.mjs} +3 -3
- package/dist/exports/{cli/api/workflows/purge-unattached-blobs.mjs → api/purge-unattached-blobs-B0TfY5Hk.mjs} +1 -1
- package/dist/exports/api/react-BYhV5bYt.mjs +1131 -0
- package/dist/exports/api/server.node-DyVrQ6cz.mjs +19298 -0
- package/dist/exports/api/table-6bTIEqON.mjs +2636 -0
- package/dist/exports/api/{workflows/track-db-changes.mjs → track-db-changes-BysaV6nN.mjs} +14 -14
- package/dist/exports/api/{workflow.mjs → workflow-BuSWHcX-.mjs} +121 -10
- package/dist/exports/api/workflows/auth-schema-BFve3hgZ.mjs +2813 -0
- package/dist/exports/api/{_virtual/rolldown_runtime.mjs → workflows/chunk-B36mNPO4.mjs} +5 -1
- package/dist/exports/api/workflows/extract-blob-metadata-BcWKvY2K.mjs +9818 -0
- package/dist/exports/api/workflows/{generate-image-variant.mjs → generate-image-variant-BAFvL_zV.mjs} +20 -20
- package/dist/exports/{cli/api/workflows/generate-preview.mjs → api/workflows/generate-preview-BjlIVYYp.mjs} +6 -6
- package/dist/exports/api/workflows/index.d.mts +2011 -1
- package/dist/exports/api/workflows/index.mjs +2 -1
- package/dist/exports/api/workflows/pdf-DUB8zyIc.mjs +25822 -0
- package/dist/exports/{cli/api/workflows/purge-attachment.mjs → api/workflows/purge-attachment-k_sdxTPY.mjs} +3 -3
- package/dist/exports/api/workflows/{purge-audit-logs.mjs → purge-audit-logs-zCyWj4Mw.mjs} +12 -3
- package/dist/exports/api/workflows/{purge-unattached-blobs.mjs → purge-unattached-blobs-CdsuFAeW.mjs} +1 -1
- package/dist/exports/api/workflows/track-db-changes-CiKaI9gT.mjs +20943 -0
- package/dist/exports/api/workflows/track-db-changes-DEWQYryO.mjs +4 -0
- package/dist/exports/{cli/api/workflow.mjs → api/workflows/workflow-BjM2xCa6.mjs} +23 -3
- package/dist/exports/api/workflows/zod-Br0enFWK.mjs +12333 -0
- package/dist/exports/api/zod-CdrJdBtV.mjs +12571 -0
- package/dist/exports/cli/auth-schema-CNuOqPi-.mjs +2813 -0
- package/dist/exports/{api/workflows/_virtual/rolldown_runtime.mjs → cli/chunk-B36mNPO4.mjs} +5 -1
- package/dist/exports/cli/extract-blob-metadata-CV1Ke90d.mjs +9818 -0
- package/dist/exports/cli/{api/workflows/generate-image-variant.mjs → generate-image-variant-CM1BrVvZ.mjs} +20 -20
- package/dist/exports/{api/workflows/generate-preview.mjs → cli/generate-preview-DdHQ3ukz.mjs} +6 -6
- package/dist/exports/cli/index.d.mts +2142 -2
- package/dist/exports/cli/index.mjs +41 -1
- package/dist/exports/cli/pdf-CLUPEIdT.mjs +25822 -0
- package/dist/exports/{api/workflows/purge-attachment.mjs → cli/purge-attachment-Dc_J74dG.mjs} +3 -3
- package/dist/exports/cli/purge-audit-logs-DFhWh-Bx.mjs +56 -0
- package/dist/exports/cli/purge-unattached-blobs-C1MRlM_2.mjs +46 -0
- package/dist/exports/cli/track-db-changes-CfneOF2_.mjs +20943 -0
- package/dist/exports/{api/workflows/api/workflow.mjs → cli/workflow-DSbbXBMt.mjs} +23 -3
- package/dist/exports/cli/zod-7q0_Mtnn.mjs +12333 -0
- package/dist/exports/devtools/BaseTanStackRouterDevtoolsPanel-BBz1qLry-DUwdvyLv.js +2090 -0
- package/dist/exports/devtools/EIDV623S-B7f6114d.js +2497 -0
- package/dist/exports/devtools/FloatingTanStackRouterDevtools-DymJEvfG-BHuQHiRR.js +237 -0
- package/dist/exports/devtools/MIMHJGAX-Cb3wf11F.js +10903 -0
- package/dist/exports/devtools/Q7LWSL4U-BoEO3rNq.js +37 -0
- package/dist/exports/devtools/VLTTJS3N-CIyRc84e.js +44 -0
- package/dist/exports/devtools/index.js +1724 -3
- package/dist/exports/devtools/utils-YRTCpRgb.js +1670 -0
- package/dist/exports/tests/api.d.mts +7354 -5
- package/dist/exports/tests/api.mjs +79 -1
- package/dist/exports/tests/auth-schema-DUCJw-_2.mjs +1 -0
- package/dist/exports/tests/chunk-Cii4FAhs.mjs +1 -0
- package/dist/exports/tests/conditions-B0ffVJ5E.mjs +1 -0
- package/dist/exports/tests/constants-DHjjg05J.mjs +1 -0
- package/dist/exports/tests/dist-D6vgKv3t.mjs +7 -0
- package/dist/exports/tests/dist-EfrRkq5c.mjs +296 -0
- package/dist/exports/tests/extract-blob-metadata-Dv343Vcn.mjs +169 -0
- package/dist/exports/tests/generate-image-variant-cQc8q0kh.mjs +1 -0
- package/dist/exports/tests/generate-preview-HaTMd2hS.mjs +1 -0
- package/dist/exports/tests/magic-string.es-D6VRmdiF.mjs +14 -0
- package/dist/exports/tests/mock-BvkO5nlm.mjs +1 -0
- package/dist/exports/tests/mock.mjs +1 -1
- package/dist/exports/tests/pdf-BDsS3vjF.mjs +13 -0
- package/dist/exports/tests/purge-attachment-D4uOzHRi.mjs +1 -0
- package/dist/exports/tests/purge-audit-logs-DiPcc09d.mjs +1 -0
- package/dist/exports/tests/purge-unattached-blobs-CqW6tlIC.mjs +1 -0
- package/dist/exports/tests/react.mjs +6 -1
- package/dist/exports/tests/setup.d.mts +1 -1
- package/dist/exports/tests/setup.mjs +34 -1
- package/dist/exports/tests/table-CbU04119.mjs +1 -0
- package/dist/exports/tests/track-db-changes-Bd4W-P1q.mjs +1 -0
- package/dist/exports/tests/vi.2VT5v0um-Cme1b0Dl.mjs +348 -0
- package/dist/exports/tests/{api/workflow.mjs → workflow-DwZxTqdH.mjs} +1 -1
- package/dist/exports/tests/zod-DcpxsMPz.mjs +23 -0
- package/dist/exports/vendors/date.js +13236 -1
- package/dist/exports/vendors/toolkit.js +2206 -1
- package/dist/exports/vendors/zod.js +12344 -1
- package/dist/exports/vite/api-DGRU_RdM.mjs +27 -0
- package/dist/exports/vite/build-CxJAu2Bn.mjs +1 -0
- package/dist/exports/vite/build2-BMK0OFVt.mjs +16 -0
- package/dist/exports/vite/chunk-CxnlK1Zi.mjs +1 -0
- package/dist/exports/vite/chunk-PtveFMYu.mjs +1 -0
- package/dist/exports/vite/dist-Bxp8DqWh.mjs +114 -0
- package/dist/exports/vite/dist-CX51FKbX.mjs +1 -0
- package/dist/exports/vite/dist-DcyNr-KR.mjs +1 -0
- package/dist/exports/vite/dist-j3-Khlzt.mjs +1 -0
- package/dist/exports/vite/experimental-index-3KsfmUbz.mjs +1 -0
- package/dist/exports/vite/false-BNJbUKYT.mjs +1 -0
- package/dist/exports/vite/false-BvrPEDU6.mjs +1 -0
- package/dist/exports/vite/index.d.mts +1 -1
- package/dist/exports/vite/index.mjs +26 -1
- package/dist/exports/vite/internal-C5cVwRiK.mjs +1 -0
- package/dist/exports/vite/jiti-BjSPrFvg.mjs +9 -0
- package/dist/exports/vite/lexer-DQCqS3nf-C6xCDOEQ.mjs +3 -0
- package/dist/exports/vite/lib-CMv7Sfwa.mjs +1 -0
- package/dist/exports/vite/lib-D9TnS-7w.mjs +1 -0
- package/dist/exports/vite/lib-DuBRr9dH.mjs +382 -0
- package/dist/exports/vite/node-DI8AnY_i.mjs +437 -0
- package/dist/exports/vite/postcss-BtmDpj-c.mjs +32 -0
- package/dist/exports/vite/postcss-import-Bk_ZCd6c.mjs +5 -0
- package/dist/exports/vite/rolldown-build-CNW2eye_-CJNfyXdF.mjs +13 -0
- package/dist/exports/vitest/api-CPv6lnxG.mjs +27 -0
- package/dist/exports/vitest/build2-28i3OiJ3.mjs +16 -0
- package/dist/exports/vitest/chunk-_e2jlDPK.mjs +1 -0
- package/dist/exports/vitest/chunk-jwDkFoXW.mjs +1 -0
- package/dist/exports/vitest/config.mjs +77 -1
- package/dist/exports/vitest/dist-L-OpshPJ.mjs +114 -0
- package/dist/exports/vitest/index.mjs +348 -1
- package/dist/exports/vitest/jiti-eNGOyHIo.mjs +9 -0
- package/dist/exports/vitest/lexer-DQCqS3nf-TWLyIqlY.mjs +3 -0
- package/dist/exports/vitest/lib-C3G64csm.mjs +1 -0
- package/dist/exports/vitest/magic-string.es-CxM5Ubyl.mjs +14 -0
- package/dist/exports/vitest/module-runner-DsF4L04D.mjs +1 -0
- package/dist/exports/vitest/postcss-BxLp_Too.mjs +32 -0
- package/dist/exports/vitest/postcss-import-5pKj3f5q.mjs +5 -0
- package/dist/exports/web/browser-ponyfill-DxTJMXNq.js +443 -0
- package/dist/exports/web/chunk-DksrlJLg.js +49 -0
- package/dist/exports/web/index.d.ts +2546 -2
- package/dist/exports/web/index.js +9295 -6
- package/dist/exports/web/plugin-DqTFWG7p.js +250 -0
- package/package.json +1 -1
- package/dist/exports/api/app-context.d.mts +0 -115
- package/dist/exports/api/app-context.mjs +0 -24
- package/dist/exports/api/auth-schema.d.mts +0 -4248
- package/dist/exports/api/auth.d.mts +0 -402
- package/dist/exports/api/auth.mjs +0 -188
- package/dist/exports/api/cache.d.mts +0 -44
- package/dist/exports/api/cache.mjs +0 -28
- package/dist/exports/api/config.d.mts +0 -28
- package/dist/exports/api/config.mjs +0 -72
- package/dist/exports/api/constants.mjs +0 -92
- package/dist/exports/api/container.d.mts +0 -210
- package/dist/exports/api/container.mjs +0 -49
- package/dist/exports/api/database.d.mts +0 -101
- package/dist/exports/api/database.mjs +0 -219
- package/dist/exports/api/event.d.mts +0 -235
- package/dist/exports/api/event.mjs +0 -236
- package/dist/exports/api/i18n.d.mts +0 -34
- package/dist/exports/api/i18n.mjs +0 -45
- package/dist/exports/api/instrumentation.d.mts +0 -7
- package/dist/exports/api/instrumentation.mjs +0 -40
- package/dist/exports/api/logger.d.mts +0 -21
- package/dist/exports/api/logger.mjs +0 -26
- package/dist/exports/api/mailer.d.mts +0 -70
- package/dist/exports/api/mailer.mjs +0 -37
- package/dist/exports/api/middleware/request-logger.d.mts +0 -24
- package/dist/exports/api/middleware.d.mts +0 -39
- package/dist/exports/api/middleware.mjs +0 -73
- package/dist/exports/api/openapi.d.mts +0 -271
- package/dist/exports/api/openapi.mjs +0 -507
- package/dist/exports/api/otel.d.mts +0 -40
- package/dist/exports/api/otel.mjs +0 -56
- package/dist/exports/api/redis.d.mts +0 -34
- package/dist/exports/api/redis.mjs +0 -41
- package/dist/exports/api/storage-schema.d.mts +0 -707
- package/dist/exports/api/storage-schema.mjs +0 -72
- package/dist/exports/api/storage.d.mts +0 -506
- package/dist/exports/api/storage.mjs +0 -833
- package/dist/exports/api/web/auth.mjs +0 -17
- package/dist/exports/api/workflow.d.mts +0 -250
- package/dist/exports/api/workflows/api/auth-schema.mjs +0 -373
- package/dist/exports/api/workflows/api/auth.d.mts +0 -379
- package/dist/exports/api/workflows/api/cache.d.mts +0 -44
- package/dist/exports/api/workflows/api/config.d.mts +0 -18
- package/dist/exports/api/workflows/api/container.d.mts +0 -167
- package/dist/exports/api/workflows/api/database.d.mts +0 -47
- package/dist/exports/api/workflows/api/event.d.mts +0 -68
- package/dist/exports/api/workflows/api/event.mjs +0 -126
- package/dist/exports/api/workflows/api/logger.d.mts +0 -21
- package/dist/exports/api/workflows/api/mailer.d.mts +0 -70
- package/dist/exports/api/workflows/api/orm.d.mts +0 -13
- package/dist/exports/api/workflows/api/redis.mjs +0 -3
- package/dist/exports/api/workflows/api/storage-schema.d.mts +0 -699
- package/dist/exports/api/workflows/api/storage.d.mts +0 -396
- package/dist/exports/api/workflows/api/workflow.d.mts +0 -24
- package/dist/exports/api/workflows/constants.mjs +0 -23
- package/dist/exports/api/workflows/extract-blob-metadata.mjs +0 -132
- package/dist/exports/api/workflows/generate-image-variant.d.mts +0 -63
- package/dist/exports/api/workflows/track-db-changes.d.mts +0 -72
- package/dist/exports/cli/api/auth-schema.mjs +0 -373
- package/dist/exports/cli/api/auth.d.mts +0 -379
- package/dist/exports/cli/api/cache.d.mts +0 -44
- package/dist/exports/cli/api/config.d.mts +0 -18
- package/dist/exports/cli/api/container.d.mts +0 -167
- package/dist/exports/cli/api/database.d.mts +0 -47
- package/dist/exports/cli/api/event.d.mts +0 -68
- package/dist/exports/cli/api/event.mjs +0 -126
- package/dist/exports/cli/api/logger.d.mts +0 -21
- package/dist/exports/cli/api/mailer.d.mts +0 -70
- package/dist/exports/cli/api/orm.d.mts +0 -13
- package/dist/exports/cli/api/redis.mjs +0 -3
- package/dist/exports/cli/api/storage-schema.d.mts +0 -699
- package/dist/exports/cli/api/storage.d.mts +0 -396
- package/dist/exports/cli/api/workflow.d.mts +0 -2
- package/dist/exports/cli/api/workflows/extract-blob-metadata.mjs +0 -132
- package/dist/exports/cli/api/workflows/generate-image-variant.d.mts +0 -63
- package/dist/exports/cli/api/workflows/track-db-changes.mjs +0 -110
- package/dist/exports/cli/command.d.mts +0 -56
- package/dist/exports/cli/command.mjs +0 -43
- package/dist/exports/cli/constants.mjs +0 -23
- package/dist/exports/cli/context.d.mts +0 -170
- package/dist/exports/tests/_virtual/rolldown_runtime.mjs +0 -1
- package/dist/exports/tests/api/app-context.d.mts +0 -115
- package/dist/exports/tests/api/app-context.mjs +0 -1
- package/dist/exports/tests/api/auth-schema.d.mts +0 -4248
- package/dist/exports/tests/api/auth-schema.mjs +0 -1
- package/dist/exports/tests/api/auth.d.mts +0 -402
- package/dist/exports/tests/api/cache.d.mts +0 -44
- package/dist/exports/tests/api/config.d.mts +0 -28
- package/dist/exports/tests/api/container.d.mts +0 -210
- package/dist/exports/tests/api/database.d.mts +0 -101
- package/dist/exports/tests/api/database.mjs +0 -1
- package/dist/exports/tests/api/event.d.mts +0 -235
- package/dist/exports/tests/api/event.mjs +0 -1
- package/dist/exports/tests/api/i18n.d.mts +0 -34
- package/dist/exports/tests/api/index.d.mts +0 -26
- package/dist/exports/tests/api/logger.d.mts +0 -21
- package/dist/exports/tests/api/mailer.d.mts +0 -70
- package/dist/exports/tests/api/middleware/error-handler.mjs +0 -1
- package/dist/exports/tests/api/middleware/health.mjs +0 -1
- package/dist/exports/tests/api/middleware/i18n.mjs +0 -1
- package/dist/exports/tests/api/middleware/request-logger.d.mts +0 -24
- package/dist/exports/tests/api/middleware/request-logger.mjs +0 -1
- package/dist/exports/tests/api/middleware/shutdown.mjs +0 -1
- package/dist/exports/tests/api/middleware/timeout.mjs +0 -1
- package/dist/exports/tests/api/middleware.d.mts +0 -39
- package/dist/exports/tests/api/middleware.mjs +0 -1
- package/dist/exports/tests/api/openapi.d.mts +0 -271
- package/dist/exports/tests/api/openapi.mjs +0 -1
- package/dist/exports/tests/api/orm.d.mts +0 -13
- package/dist/exports/tests/api/otel.d.mts +0 -40
- package/dist/exports/tests/api/redis.d.mts +0 -34
- package/dist/exports/tests/api/redis.mjs +0 -1
- package/dist/exports/tests/api/server.mjs +0 -1
- package/dist/exports/tests/api/storage-schema.d.mts +0 -707
- package/dist/exports/tests/api/storage.d.mts +0 -506
- package/dist/exports/tests/api/workflow.d.mts +0 -250
- package/dist/exports/tests/api/workflows/extract-blob-metadata.mjs +0 -1
- package/dist/exports/tests/api/workflows/generate-image-variant.d.mts +0 -63
- package/dist/exports/tests/api/workflows/generate-image-variant.mjs +0 -1
- package/dist/exports/tests/api/workflows/generate-preview.mjs +0 -1
- package/dist/exports/tests/api/workflows/purge-attachment.mjs +0 -1
- package/dist/exports/tests/api/workflows/purge-audit-logs.mjs +0 -1
- package/dist/exports/tests/api/workflows/purge-unattached-blobs.mjs +0 -1
- package/dist/exports/tests/api/workflows/track-db-changes.mjs +0 -1
- package/dist/exports/tests/constants.mjs +0 -1
- package/dist/exports/tests/instrumentation.d.mts +0 -7
- package/dist/exports/tests/instrumentation.mjs +0 -1
- package/dist/exports/web/api/auth.d.ts +0 -125
- package/dist/exports/web/api/database.d.ts +0 -4
- package/dist/exports/web/api/logger.d.ts +0 -1
- package/dist/exports/web/auth.d.ts +0 -2388
- package/dist/exports/web/auth.js +0 -75
- package/dist/exports/web/i18n.d.ts +0 -42
- package/dist/exports/web/i18n.js +0 -45
- /package/dist/exports/tests/{api/middleware/youch-handler.mjs → youch-handler-Ch5yf6im.mjs} +0 -0
|
@@ -1,2 +1,2012 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as __export, r as __reExport } from "./chunk-B36mNPO4.mjs";
|
|
2
|
+
import { CorsOptions } from "cors";
|
|
3
|
+
import { Options } from "express-rate-limit";
|
|
4
|
+
import { HelmetOptions } from "helmet";
|
|
5
|
+
import { i18n } from "i18next";
|
|
6
|
+
import { betterAuth } from "better-auth";
|
|
7
|
+
import { Role, createAccessControl } from "better-auth/plugins/access";
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
import * as drizzle_orm2 from "drizzle-orm";
|
|
10
|
+
import { AnyRelations, EmptyRelations, ExtractTablesWithRelations } from "drizzle-orm";
|
|
11
|
+
import * as drizzle_orm_node_postgres0 from "drizzle-orm/node-postgres";
|
|
12
|
+
import { NodePgDatabase } from "drizzle-orm/node-postgres";
|
|
13
|
+
import * as pg0 from "pg";
|
|
14
|
+
import pg, { Pool } from "pg";
|
|
15
|
+
import * as drizzle_orm_pg_core0 from "drizzle-orm/pg-core";
|
|
16
|
+
import { index, isPgEnum, isPgMaterializedView, isPgSchema, isPgSequence, isPgView, numeric, parsePgArray, parsePgNestedArray, pgEnum, pgMaterializedView, pgPolicy, pgRole, pgSchema, pgSequence, pgTable, pgTableCreator, pgView, serial, smallint, smallserial, sparsevec, unique, uniqueIndex, uniqueKeyName, withReplicas } from "drizzle-orm/pg-core";
|
|
17
|
+
import pino, { LoggerOptions } from "pino";
|
|
18
|
+
import * as _keyv_redis0 from "@keyv/redis";
|
|
19
|
+
import { KeyvRedisOptions } from "@keyv/redis";
|
|
20
|
+
import Mail from "nodemailer/lib/mailer/index.ts";
|
|
21
|
+
import { JSX } from "react";
|
|
22
|
+
import { DriveManager } from "flydrive";
|
|
23
|
+
import { FSDriverOptions } from "flydrive/drivers/fs/types";
|
|
24
|
+
import { S3DriverOptions } from "flydrive/drivers/s3/types";
|
|
25
|
+
import * as _dbos_inc_dbos_sdk0 from "@dbos-inc/dbos-sdk";
|
|
26
|
+
|
|
27
|
+
//#region src/api/logger.d.ts
|
|
28
|
+
/**
|
|
29
|
+
* Extended logger options with OpenTelemetry support.
|
|
30
|
+
*/
|
|
31
|
+
interface DefineLoggerOptions extends LoggerOptions {}
|
|
32
|
+
/**
|
|
33
|
+
* The logger instance type.
|
|
34
|
+
*/
|
|
35
|
+
type Logger = Awaited<ReturnType<typeof defineLogger>>;
|
|
36
|
+
/**
|
|
37
|
+
* Define the logger instance.
|
|
38
|
+
*
|
|
39
|
+
* @param opts - The options.
|
|
40
|
+
* @returns The logger.
|
|
41
|
+
*/
|
|
42
|
+
declare function defineLogger(opts: DefineLoggerOptions): Promise<pino.Logger<never, boolean>>;
|
|
43
|
+
//#endregion
|
|
44
|
+
//#region src/api/database.d.ts
|
|
45
|
+
type PoolConfig = pg.PoolConfig;
|
|
46
|
+
/**
|
|
47
|
+
* Extract qualified table names from db object.
|
|
48
|
+
*/
|
|
49
|
+
type QualifiedTableNames<TDb> = { [K in keyof TDb]: TDb[K] extends {
|
|
50
|
+
_: {
|
|
51
|
+
fullSchema: infer S;
|
|
52
|
+
};
|
|
53
|
+
} ? `${K & string}.${keyof S & string}` : never }[keyof TDb];
|
|
54
|
+
/**
|
|
55
|
+
* Options for defining the database.
|
|
56
|
+
*/
|
|
57
|
+
interface DefineDatabaseOptions<TSchema extends Record<string, unknown> = Record<string, never>, TRelations extends AnyRelations = EmptyRelations> {
|
|
58
|
+
logger: Logger;
|
|
59
|
+
poolConfig: PoolConfig;
|
|
60
|
+
relations?: TRelations;
|
|
61
|
+
schema?: TSchema;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* The database type.
|
|
65
|
+
*/
|
|
66
|
+
type Database = Awaited<ReturnType<typeof defineDatabase>>;
|
|
67
|
+
/**
|
|
68
|
+
* Define the database with the provided options.
|
|
69
|
+
*
|
|
70
|
+
* Algorithm:
|
|
71
|
+
* 1. Create a connection pool with sensible defaults
|
|
72
|
+
* 2. Initialize drizzle ORM with schema and relations
|
|
73
|
+
*
|
|
74
|
+
* @param opts The options for defining the database, including pool configuration, relations, and schema.
|
|
75
|
+
* @template TSchema The schema type for the database.
|
|
76
|
+
* @template TRelations The relations type for the database.
|
|
77
|
+
* @returns The defined database instance.
|
|
78
|
+
*/
|
|
79
|
+
declare function defineDatabase<TSchema extends Record<string, unknown> = Record<string, never>, TRelations extends AnyRelations = EmptyRelations>(opts: DefineDatabaseOptions<TSchema, TRelations>): Promise<drizzle_orm_node_postgres0.NodePgDatabase<TSchema, TRelations> & {
|
|
80
|
+
$client: pg0.Pool;
|
|
81
|
+
}>;
|
|
82
|
+
//#endregion
|
|
83
|
+
//#region src/api/auth.d.ts
|
|
84
|
+
/**
|
|
85
|
+
* Type for access controller created via createAccessControl().
|
|
86
|
+
* Used for RBAC on both server and client.
|
|
87
|
+
*/
|
|
88
|
+
type AccessController = ReturnType<typeof createAccessControl>;
|
|
89
|
+
/**
|
|
90
|
+
* Type for roles created via ac.newRole().
|
|
91
|
+
* Uses Role type from better-auth for compatibility.
|
|
92
|
+
*/
|
|
93
|
+
type AccessControlRoles = Record<string, Role>;
|
|
94
|
+
/**
|
|
95
|
+
* Type-safe audit log options for defineAuth().
|
|
96
|
+
* Generic over db object to provide autocomplete for excludeTables.
|
|
97
|
+
*
|
|
98
|
+
* @template TDb - Database record type for table name inference
|
|
99
|
+
*/
|
|
100
|
+
type AuditLogOptions<TDb> = {
|
|
101
|
+
/**
|
|
102
|
+
* Tables to exclude from audit logging.
|
|
103
|
+
*/
|
|
104
|
+
excludeTables?: QualifiedTableNames<TDb>[];
|
|
105
|
+
/**
|
|
106
|
+
* Cron expression for purge schedule.
|
|
107
|
+
*
|
|
108
|
+
* @default "0 0 * * *"
|
|
109
|
+
*/
|
|
110
|
+
purgeCron?: string;
|
|
111
|
+
/**
|
|
112
|
+
* Retention period in days. Audit logs older than this are auto-deleted.
|
|
113
|
+
* @default 90
|
|
114
|
+
*/
|
|
115
|
+
retentionDays?: number;
|
|
116
|
+
};
|
|
117
|
+
/**
|
|
118
|
+
* Neutral auth configuration - shared between server and client.
|
|
119
|
+
* Contains ONLY fields that affect both sides (UI + server features).
|
|
120
|
+
*
|
|
121
|
+
* PRESENCE-BASED CONFIG: If a key exists, it's enabled. No redundant `enabled` fields.
|
|
122
|
+
* Server-only fields (appName, session) are passed via DefineAuthOptions.
|
|
123
|
+
*/
|
|
124
|
+
interface AuthConfig {
|
|
125
|
+
/**
|
|
126
|
+
* Base URL where auth server is hosted.
|
|
127
|
+
*
|
|
128
|
+
* @default "" (same origin - client uses relative URLs)
|
|
129
|
+
* @example "http://localhost:8000" for cross-origin
|
|
130
|
+
*/
|
|
131
|
+
baseURL?: string;
|
|
132
|
+
/**
|
|
133
|
+
* Base path for auth routes.
|
|
134
|
+
*
|
|
135
|
+
* @default "/auth"
|
|
136
|
+
*/
|
|
137
|
+
basePath?: string;
|
|
138
|
+
/** Authentication methods - if defined, it's enabled */
|
|
139
|
+
methods?: {
|
|
140
|
+
/** Email/password auth. If defined, enabled. */
|
|
141
|
+
emailPassword?: {
|
|
142
|
+
requireEmailVerification?: boolean;
|
|
143
|
+
minPasswordLength?: number;
|
|
144
|
+
maxPasswordLength?: number;
|
|
145
|
+
};
|
|
146
|
+
/** Magic link auth. If defined, enabled. */
|
|
147
|
+
magicLink?: {
|
|
148
|
+
expiresIn?: number;
|
|
149
|
+
};
|
|
150
|
+
/** Passkey auth. If defined (even as empty object), enabled. */
|
|
151
|
+
passkey?: Record<string, never>;
|
|
152
|
+
/** Phone OTP auth. If defined, enabled. */
|
|
153
|
+
phoneOtp?: {
|
|
154
|
+
otpLength?: number;
|
|
155
|
+
expiresIn?: number;
|
|
156
|
+
};
|
|
157
|
+
/** Email OTP auth. If defined, enabled. */
|
|
158
|
+
emailOtp?: {
|
|
159
|
+
otpLength?: number;
|
|
160
|
+
expiresIn?: number;
|
|
161
|
+
};
|
|
162
|
+
};
|
|
163
|
+
/** OAuth providers - true = enabled, undefined/false = disabled */
|
|
164
|
+
oauth?: {
|
|
165
|
+
google?: boolean;
|
|
166
|
+
github?: boolean;
|
|
167
|
+
apple?: boolean;
|
|
168
|
+
facebook?: boolean;
|
|
169
|
+
};
|
|
170
|
+
/** Plugins - if defined, it's enabled */
|
|
171
|
+
plugins?: {
|
|
172
|
+
/** Admin plugin. If defined, enabled. Includes RBAC for both server and client. */
|
|
173
|
+
admin?: {
|
|
174
|
+
defaultRole?: string;
|
|
175
|
+
adminRoles?: string[];
|
|
176
|
+
/** Access controller created via createAccessControl() - shared between server and client */
|
|
177
|
+
ac: AccessController;
|
|
178
|
+
/** Role definitions created via ac.newRole() - shared between server and client */
|
|
179
|
+
roles: AccessControlRoles;
|
|
180
|
+
};
|
|
181
|
+
/** API key plugin. If defined, enabled. */
|
|
182
|
+
apiKey?: {
|
|
183
|
+
defaultPrefix?: string;
|
|
184
|
+
defaultKeyLength?: number;
|
|
185
|
+
rateLimit?: {
|
|
186
|
+
maxRequests?: number;
|
|
187
|
+
timeWindow?: number;
|
|
188
|
+
};
|
|
189
|
+
};
|
|
190
|
+
/** Two-factor plugin. If defined, enabled. Sub-features also presence-based. */
|
|
191
|
+
twoFactor?: {
|
|
192
|
+
issuer?: string;
|
|
193
|
+
totp?: {
|
|
194
|
+
digits?: 6 | 8;
|
|
195
|
+
period?: number;
|
|
196
|
+
};
|
|
197
|
+
otp?: boolean;
|
|
198
|
+
backupCodes?: {
|
|
199
|
+
amount?: number;
|
|
200
|
+
length?: number;
|
|
201
|
+
};
|
|
202
|
+
};
|
|
203
|
+
/** Multi-session plugin. If defined, enabled. */
|
|
204
|
+
multiSession?: {
|
|
205
|
+
maximumSessions?: number;
|
|
206
|
+
};
|
|
207
|
+
/** Username plugin. If defined, enabled. */
|
|
208
|
+
username?: {
|
|
209
|
+
minUsernameLength?: number;
|
|
210
|
+
maxUsernameLength?: number;
|
|
211
|
+
};
|
|
212
|
+
/** Anonymous auth plugin. If defined, enabled. */
|
|
213
|
+
anonymous?: {
|
|
214
|
+
emailDomainName?: string;
|
|
215
|
+
};
|
|
216
|
+
/** SSO plugin. If defined, enabled. Import from @better-auth/sso */
|
|
217
|
+
sso?: {
|
|
218
|
+
providersLimit?: number;
|
|
219
|
+
trustEmailVerified?: boolean;
|
|
220
|
+
domainVerification?: boolean;
|
|
221
|
+
};
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
/** Base hook types for reference */
|
|
225
|
+
type EmailHook = (params: {
|
|
226
|
+
email: string;
|
|
227
|
+
url: string;
|
|
228
|
+
token: string;
|
|
229
|
+
}) => Promise<void>;
|
|
230
|
+
type OtpHook = (params: {
|
|
231
|
+
email: string;
|
|
232
|
+
otp: string;
|
|
233
|
+
}) => Promise<void>;
|
|
234
|
+
type PhoneOtpHook = (params: {
|
|
235
|
+
phoneNumber: string;
|
|
236
|
+
otp: string;
|
|
237
|
+
}) => Promise<void>;
|
|
238
|
+
/**
|
|
239
|
+
* Conditionally required hooks based on config.
|
|
240
|
+
* Uses PRESENCE-BASED detection - if key exists, hook is REQUIRED.
|
|
241
|
+
*/
|
|
242
|
+
type RequiredHooks<T extends AuthConfig> = (T["methods"] extends {
|
|
243
|
+
emailPassword: {
|
|
244
|
+
requireEmailVerification: true;
|
|
245
|
+
};
|
|
246
|
+
} ? {
|
|
247
|
+
sendVerificationEmail: EmailHook;
|
|
248
|
+
} : {
|
|
249
|
+
sendVerificationEmail?: EmailHook;
|
|
250
|
+
}) & (T["methods"] extends {
|
|
251
|
+
emailPassword: object;
|
|
252
|
+
} ? {
|
|
253
|
+
sendResetPasswordEmail: EmailHook;
|
|
254
|
+
} : {
|
|
255
|
+
sendResetPasswordEmail?: EmailHook;
|
|
256
|
+
}) & (T["methods"] extends {
|
|
257
|
+
magicLink: object;
|
|
258
|
+
} ? {
|
|
259
|
+
sendMagicLink: EmailHook;
|
|
260
|
+
} : {
|
|
261
|
+
sendMagicLink?: EmailHook;
|
|
262
|
+
}) & (T["methods"] extends {
|
|
263
|
+
emailOtp: object;
|
|
264
|
+
} ? {
|
|
265
|
+
sendEmailOTP: OtpHook;
|
|
266
|
+
} : {
|
|
267
|
+
sendEmailOTP?: OtpHook;
|
|
268
|
+
}) & (T["methods"] extends {
|
|
269
|
+
phoneOtp: object;
|
|
270
|
+
} ? {
|
|
271
|
+
sendPhoneOTP: PhoneOtpHook;
|
|
272
|
+
} : {
|
|
273
|
+
sendPhoneOTP?: PhoneOtpHook;
|
|
274
|
+
}) & (T["plugins"] extends {
|
|
275
|
+
twoFactor: {
|
|
276
|
+
otp: true;
|
|
277
|
+
};
|
|
278
|
+
} ? {
|
|
279
|
+
send2FAOTP: OtpHook;
|
|
280
|
+
} : {
|
|
281
|
+
send2FAOTP?: OtpHook;
|
|
282
|
+
});
|
|
283
|
+
/**
|
|
284
|
+
* Conditionally required OAuth credentials based on config.
|
|
285
|
+
* If an OAuth provider is enabled in config, its credentials are REQUIRED.
|
|
286
|
+
*/
|
|
287
|
+
type RequiredOAuth<T extends AuthConfig> = (T["oauth"] extends {
|
|
288
|
+
google: true;
|
|
289
|
+
} ? {
|
|
290
|
+
google: {
|
|
291
|
+
clientId: string;
|
|
292
|
+
clientSecret: string;
|
|
293
|
+
};
|
|
294
|
+
} : {
|
|
295
|
+
google?: {
|
|
296
|
+
clientId: string;
|
|
297
|
+
clientSecret: string;
|
|
298
|
+
};
|
|
299
|
+
}) & (T["oauth"] extends {
|
|
300
|
+
github: true;
|
|
301
|
+
} ? {
|
|
302
|
+
github: {
|
|
303
|
+
clientId: string;
|
|
304
|
+
clientSecret: string;
|
|
305
|
+
};
|
|
306
|
+
} : {
|
|
307
|
+
github?: {
|
|
308
|
+
clientId: string;
|
|
309
|
+
clientSecret: string;
|
|
310
|
+
};
|
|
311
|
+
}) & (T["oauth"] extends {
|
|
312
|
+
apple: true;
|
|
313
|
+
} ? {
|
|
314
|
+
apple: {
|
|
315
|
+
clientId: string;
|
|
316
|
+
clientSecret: string;
|
|
317
|
+
};
|
|
318
|
+
} : {
|
|
319
|
+
apple?: {
|
|
320
|
+
clientId: string;
|
|
321
|
+
clientSecret: string;
|
|
322
|
+
};
|
|
323
|
+
}) & (T["oauth"] extends {
|
|
324
|
+
facebook: true;
|
|
325
|
+
} ? {
|
|
326
|
+
facebook: {
|
|
327
|
+
clientId: string;
|
|
328
|
+
clientSecret: string;
|
|
329
|
+
};
|
|
330
|
+
} : {
|
|
331
|
+
facebook?: {
|
|
332
|
+
clientId: string;
|
|
333
|
+
clientSecret: string;
|
|
334
|
+
};
|
|
335
|
+
});
|
|
336
|
+
/** Check if any OAuth provider is enabled */
|
|
337
|
+
type HasOAuthEnabled<T extends AuthConfig> = T["oauth"] extends {
|
|
338
|
+
google: true;
|
|
339
|
+
} | {
|
|
340
|
+
github: true;
|
|
341
|
+
} | {
|
|
342
|
+
apple: true;
|
|
343
|
+
} | {
|
|
344
|
+
facebook: true;
|
|
345
|
+
} ? true : false;
|
|
346
|
+
/** Check if passkey is enabled */
|
|
347
|
+
type HasPasskeyEnabled<T extends AuthConfig> = T["methods"] extends {
|
|
348
|
+
passkey: object;
|
|
349
|
+
} ? true : false;
|
|
350
|
+
/**
|
|
351
|
+
* Server-only session configuration.
|
|
352
|
+
*/
|
|
353
|
+
interface AuthSessionConfig {
|
|
354
|
+
/**
|
|
355
|
+
* Session duration in seconds.
|
|
356
|
+
*
|
|
357
|
+
* @default 604800 (7 days)
|
|
358
|
+
*/
|
|
359
|
+
expiresIn?: number;
|
|
360
|
+
/**
|
|
361
|
+
* How often to update session in seconds.
|
|
362
|
+
*
|
|
363
|
+
* @default 86400 (1 day)
|
|
364
|
+
*/
|
|
365
|
+
updateAge?: number;
|
|
366
|
+
/**
|
|
367
|
+
* Session freshness in seconds for sensitive ops.
|
|
368
|
+
*
|
|
369
|
+
* @default 86400 (1 day)
|
|
370
|
+
*/
|
|
371
|
+
freshAge?: number;
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* Server-only passkey configuration (required if passkey is enabled).
|
|
375
|
+
*/
|
|
376
|
+
interface AuthPasskeyConfig {
|
|
377
|
+
/**
|
|
378
|
+
* Relying Party ID - domain for passkey (e.g., "example.com" or "localhost").
|
|
379
|
+
*/
|
|
380
|
+
rpID: string;
|
|
381
|
+
/**
|
|
382
|
+
* Origin URL for passkey verification (e.g., "http://localhost:8000").
|
|
383
|
+
*/
|
|
384
|
+
origin: string;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Fully type-safe options for defineAuth().
|
|
388
|
+
*
|
|
389
|
+
* Server-only fields:
|
|
390
|
+
* - `appName` - Application name for passkey rpName, TOTP issuer, emails
|
|
391
|
+
* - `auditLog` - Audit logging configuration
|
|
392
|
+
* - `session` - Session duration and freshness settings
|
|
393
|
+
*
|
|
394
|
+
* Conditional requirements:
|
|
395
|
+
* - If config has `oauth.google: true`, then `oauth.google` credentials are REQUIRED
|
|
396
|
+
* - If config has `methods.magicLink` defined, then `hooks.sendMagicLink` is REQUIRED
|
|
397
|
+
*
|
|
398
|
+
* @template T - Auth config type
|
|
399
|
+
* @template TDb - Database record type for type-safe excludeTables
|
|
400
|
+
*/
|
|
401
|
+
type DefineAuthOptions<T extends AuthConfig, TDb = unknown> = {
|
|
402
|
+
/**
|
|
403
|
+
* The application name.
|
|
404
|
+
*/
|
|
405
|
+
appName: string;
|
|
406
|
+
/**
|
|
407
|
+
* Audit logging configuration (server-only). Use qualified table names: "dbName.tableName".
|
|
408
|
+
*/
|
|
409
|
+
auditLog?: AuditLogOptions<TDb>;
|
|
410
|
+
/**
|
|
411
|
+
* The neutral auth configuration.
|
|
412
|
+
*/
|
|
413
|
+
config: T;
|
|
414
|
+
/**
|
|
415
|
+
* Full db object (container.db) for type inference.
|
|
416
|
+
*/
|
|
417
|
+
db: TDb;
|
|
418
|
+
/**
|
|
419
|
+
* Primary database for Better Auth storage.
|
|
420
|
+
*/
|
|
421
|
+
database: Database;
|
|
422
|
+
/**
|
|
423
|
+
* Hooks for email sending and OTP delivery.
|
|
424
|
+
*/
|
|
425
|
+
hooks: RequiredHooks<T>;
|
|
426
|
+
/**
|
|
427
|
+
* Secret key for signing tokens and cookies.
|
|
428
|
+
*/
|
|
429
|
+
secret: string;
|
|
430
|
+
/**
|
|
431
|
+
* Session configuration.
|
|
432
|
+
*/
|
|
433
|
+
session?: AuthSessionConfig;
|
|
434
|
+
} & (HasOAuthEnabled<T> extends true ? {
|
|
435
|
+
oauth: RequiredOAuth<T>;
|
|
436
|
+
} : {
|
|
437
|
+
oauth?: RequiredOAuth<T>;
|
|
438
|
+
}) & (HasPasskeyEnabled<T> extends true ? {
|
|
439
|
+
passkey: AuthPasskeyConfig;
|
|
440
|
+
} : {
|
|
441
|
+
passkey?: AuthPasskeyConfig;
|
|
442
|
+
});
|
|
443
|
+
/**
|
|
444
|
+
* Defines Better Auth instance from neutral config + server dependencies.
|
|
445
|
+
*/
|
|
446
|
+
declare function defineAuth<T extends AuthConfig, TDb extends Record<"primary", Database> & Record<string, Database> = Record<"primary", Database> & Record<string, Database>>(opts: DefineAuthOptions<T, TDb>): ReturnType<typeof betterAuth> & {
|
|
447
|
+
auditLog?: AuditLogOptions<TDb>;
|
|
448
|
+
shouldAudit(tableName: QualifiedTableNames<TDb>): boolean;
|
|
449
|
+
};
|
|
450
|
+
/**
|
|
451
|
+
* The auth instance type.
|
|
452
|
+
*/
|
|
453
|
+
type Auth<TDb extends Record<"primary", Database> & Record<string, Database> = Record<"primary", Database> & Record<string, Database>> = ReturnType<typeof defineAuth<AuthConfig, TDb>>;
|
|
454
|
+
//#endregion
|
|
455
|
+
//#region src/api/cache.d.ts
|
|
456
|
+
/**
|
|
457
|
+
* The cache instance type.
|
|
458
|
+
*/
|
|
459
|
+
type Cache = ReturnType<typeof defineCache>;
|
|
460
|
+
/**
|
|
461
|
+
* Options for defining the cache.
|
|
462
|
+
*/
|
|
463
|
+
type DefineCacheOptions = {
|
|
464
|
+
/**
|
|
465
|
+
* Redis URL(s). Single or comma-separated for cluster.
|
|
466
|
+
*/
|
|
467
|
+
url: string;
|
|
468
|
+
/**
|
|
469
|
+
* The logger instance.
|
|
470
|
+
*/
|
|
471
|
+
logger: Logger;
|
|
472
|
+
/**
|
|
473
|
+
* The Keyv Redis options.
|
|
474
|
+
*/
|
|
475
|
+
options?: KeyvRedisOptions;
|
|
476
|
+
};
|
|
477
|
+
/**
|
|
478
|
+
* Define the cache instance using shared Redis client.
|
|
479
|
+
* Connection is lazy - only connects when first cache operation is performed.
|
|
480
|
+
*
|
|
481
|
+
* Algorithm:
|
|
482
|
+
* 1. Create Redis client using defineRedisClient() (lazy connection)
|
|
483
|
+
* 2. Pass client to createKeyv() - connection happens on first use
|
|
484
|
+
*
|
|
485
|
+
* @param opts - The options for defining the cache.
|
|
486
|
+
* @returns The cache instance.
|
|
487
|
+
*/
|
|
488
|
+
declare function defineCache({
|
|
489
|
+
url,
|
|
490
|
+
logger,
|
|
491
|
+
options
|
|
492
|
+
}: DefineCacheOptions): _keyv_redis0.Keyv<any>;
|
|
493
|
+
//#endregion
|
|
494
|
+
//#region src/api/config.d.ts
|
|
495
|
+
/**
|
|
496
|
+
* The config base schema.
|
|
497
|
+
*/
|
|
498
|
+
declare const baseSchema: z.ZodObject<{
|
|
499
|
+
APP_NAME: z.ZodDefault<z.ZodString>;
|
|
500
|
+
APP_DESC: z.ZodDefault<z.ZodString>;
|
|
501
|
+
APP_VERSION: z.ZodDefault<z.ZodString>;
|
|
502
|
+
}, z.core.$strip>;
|
|
503
|
+
/**
|
|
504
|
+
* The configuration type inferred from the merged schema.
|
|
505
|
+
*/
|
|
506
|
+
type Config<T extends z.ZodRawShape = {}> = z.infer<ReturnType<typeof baseSchema.extend<T>>>;
|
|
507
|
+
//#endregion
|
|
508
|
+
//#region src/api/event.d.ts
|
|
509
|
+
/**
|
|
510
|
+
* Options for defining an event bus.
|
|
511
|
+
*/
|
|
512
|
+
interface DefineEventBusOptions {
|
|
513
|
+
/**
|
|
514
|
+
* Redis URL for pub/sub.
|
|
515
|
+
*/
|
|
516
|
+
dbUrl: string;
|
|
517
|
+
/**
|
|
518
|
+
* Logger instance for error reporting.
|
|
519
|
+
*/
|
|
520
|
+
logger: Logger;
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* The event bus type for container.
|
|
524
|
+
*/
|
|
525
|
+
type EventBus = ReturnType<typeof defineEventBus>;
|
|
526
|
+
/**
|
|
527
|
+
* Defines the event bus for pub/sub messaging.
|
|
528
|
+
* Uses Redis for cross-server communication.
|
|
529
|
+
*
|
|
530
|
+
* Algorithm:
|
|
531
|
+
* 1. Create lazy Redis publisher client
|
|
532
|
+
* 2. Create lazy Redis subscriber client
|
|
533
|
+
* 3. Manage subscriptions via callback registry
|
|
534
|
+
* 4. Provide publish/subscribe/close methods
|
|
535
|
+
*
|
|
536
|
+
* @param opts - Event bus configuration
|
|
537
|
+
* @returns Event bus instance
|
|
538
|
+
*/
|
|
539
|
+
declare function defineEventBus(opts: DefineEventBusOptions): {
|
|
540
|
+
/**
|
|
541
|
+
* Publish a message to a channel.
|
|
542
|
+
* Auto-connects on first call if not already connected.
|
|
543
|
+
*
|
|
544
|
+
* @param channel - Channel name
|
|
545
|
+
* @param message - Message payload (will be JSON stringified)
|
|
546
|
+
*/
|
|
547
|
+
publish(channel: string, message: unknown): Promise<void>;
|
|
548
|
+
/**
|
|
549
|
+
* Subscribe to a channel. Returns unsubscribe function.
|
|
550
|
+
* Uses single connection with callback management.
|
|
551
|
+
*
|
|
552
|
+
* @param channel - Channel name
|
|
553
|
+
* @param callback - Callback for received messages
|
|
554
|
+
* @returns Unsubscribe function
|
|
555
|
+
*/
|
|
556
|
+
subscribe(channel: string, callback: (message: unknown) => void): Promise<() => void>;
|
|
557
|
+
/**
|
|
558
|
+
* Check if a channel has any subscribers.
|
|
559
|
+
*
|
|
560
|
+
* @param channel - Channel name
|
|
561
|
+
* @returns true if channel has subscribers
|
|
562
|
+
*/
|
|
563
|
+
hasSubscribers(channel: string): boolean;
|
|
564
|
+
/**
|
|
565
|
+
* Close the Redis connections.
|
|
566
|
+
*/
|
|
567
|
+
close(): Promise<void>;
|
|
568
|
+
};
|
|
569
|
+
//#endregion
|
|
570
|
+
//#region src/api/mailer.d.ts
|
|
571
|
+
/**
|
|
572
|
+
* The mailer type.
|
|
573
|
+
*/
|
|
574
|
+
type Mailer = ReturnType<typeof defineMailer>;
|
|
575
|
+
/**
|
|
576
|
+
* The mailer payload type with React component.
|
|
577
|
+
*/
|
|
578
|
+
type MailerPayloadReact = Omit<Mail.Options, "from" | "html" | "text"> & {
|
|
579
|
+
/**
|
|
580
|
+
* The email address to send the email from.
|
|
581
|
+
*/
|
|
582
|
+
from?: string;
|
|
583
|
+
/**
|
|
584
|
+
* The React component to render as the email body.
|
|
585
|
+
*/
|
|
586
|
+
react: JSX.Element;
|
|
587
|
+
};
|
|
588
|
+
/**
|
|
589
|
+
* The mailer payload type with direct HTML and text.
|
|
590
|
+
*/
|
|
591
|
+
type MailerPayloadHtml = Omit<Mail.Options, "from"> & {
|
|
592
|
+
/**
|
|
593
|
+
* The email address to send the email from.
|
|
594
|
+
*/
|
|
595
|
+
from?: string;
|
|
596
|
+
/**
|
|
597
|
+
* The HTML content of the email.
|
|
598
|
+
*/
|
|
599
|
+
html: string;
|
|
600
|
+
/**
|
|
601
|
+
* The plain text content of the email.
|
|
602
|
+
*/
|
|
603
|
+
text: string;
|
|
604
|
+
};
|
|
605
|
+
/**
|
|
606
|
+
* The mailer payload type - supports either React component or direct HTML+text.
|
|
607
|
+
*/
|
|
608
|
+
type MailerPayload = MailerPayloadReact | MailerPayloadHtml;
|
|
609
|
+
/**
|
|
610
|
+
* Define the options for the mailer.
|
|
611
|
+
*/
|
|
612
|
+
interface DefineMailerOptions {
|
|
613
|
+
/**
|
|
614
|
+
* The default email address to use as the sender.
|
|
615
|
+
*/
|
|
616
|
+
from: string;
|
|
617
|
+
/**
|
|
618
|
+
* The SMTP URL to use for sending emails.
|
|
619
|
+
*/
|
|
620
|
+
smtpUrl: string;
|
|
621
|
+
}
|
|
622
|
+
/**
|
|
623
|
+
* Define the mailer.
|
|
624
|
+
*
|
|
625
|
+
* @param env - The environment variables.
|
|
626
|
+
* @returns The mailer.
|
|
627
|
+
*/
|
|
628
|
+
declare function defineMailer({
|
|
629
|
+
from,
|
|
630
|
+
smtpUrl
|
|
631
|
+
}: DefineMailerOptions): {
|
|
632
|
+
send(payload: MailerPayload): Promise<void>;
|
|
633
|
+
};
|
|
634
|
+
declare namespace orm_d_exports {
|
|
635
|
+
export { index, isPgEnum, isPgMaterializedView, isPgSchema, isPgSequence, isPgView, numeric, parsePgArray, parsePgNestedArray, pgEnum, pgMaterializedView, pgPolicy, pgRole, pgSchema, pgSequence, pgTable, pgTableCreator, pgView, serial, smallint, smallserial, sparsevec, unique, uniqueIndex, uniqueKeyName, withReplicas };
|
|
636
|
+
}
|
|
637
|
+
import * as import_drizzle_orm from "drizzle-orm";
|
|
638
|
+
import * as import_drizzle_seed from "drizzle-seed";
|
|
639
|
+
//#endregion
|
|
640
|
+
//#region src/api/storage-schema.d.ts
|
|
641
|
+
/**
|
|
642
|
+
* Defines the storage schema for file attachments and blob management.
|
|
643
|
+
*
|
|
644
|
+
* @returns An object containing the schema and relations for the storage tables.
|
|
645
|
+
*/
|
|
646
|
+
declare function defineStorageSchema(): {
|
|
647
|
+
tables: {
|
|
648
|
+
storageBlobs: drizzle_orm_pg_core0.PgTableWithColumns<{
|
|
649
|
+
name: "storage_blobs";
|
|
650
|
+
schema: undefined;
|
|
651
|
+
columns: {
|
|
652
|
+
id: drizzle_orm_pg_core0.PgColumn<{
|
|
653
|
+
name: string;
|
|
654
|
+
tableName: "storage_blobs";
|
|
655
|
+
dataType: "string";
|
|
656
|
+
data: string;
|
|
657
|
+
driverParam: string;
|
|
658
|
+
notNull: true;
|
|
659
|
+
hasDefault: true;
|
|
660
|
+
isPrimaryKey: true;
|
|
661
|
+
isAutoincrement: false;
|
|
662
|
+
hasRuntimeDefault: false;
|
|
663
|
+
enumValues: [string, ...string[]];
|
|
664
|
+
baseColumn: never;
|
|
665
|
+
identity: undefined;
|
|
666
|
+
generated: undefined;
|
|
667
|
+
}, {}>;
|
|
668
|
+
key: drizzle_orm_pg_core0.PgColumn<{
|
|
669
|
+
name: string;
|
|
670
|
+
tableName: "storage_blobs";
|
|
671
|
+
dataType: "string";
|
|
672
|
+
data: string;
|
|
673
|
+
driverParam: string;
|
|
674
|
+
notNull: true;
|
|
675
|
+
hasDefault: false;
|
|
676
|
+
isPrimaryKey: false;
|
|
677
|
+
isAutoincrement: false;
|
|
678
|
+
hasRuntimeDefault: false;
|
|
679
|
+
enumValues: [string, ...string[]];
|
|
680
|
+
baseColumn: never;
|
|
681
|
+
identity: undefined;
|
|
682
|
+
generated: undefined;
|
|
683
|
+
}, {}>;
|
|
684
|
+
filename: drizzle_orm_pg_core0.PgColumn<{
|
|
685
|
+
name: string;
|
|
686
|
+
tableName: "storage_blobs";
|
|
687
|
+
dataType: "string";
|
|
688
|
+
data: string;
|
|
689
|
+
driverParam: string;
|
|
690
|
+
notNull: true;
|
|
691
|
+
hasDefault: false;
|
|
692
|
+
isPrimaryKey: false;
|
|
693
|
+
isAutoincrement: false;
|
|
694
|
+
hasRuntimeDefault: false;
|
|
695
|
+
enumValues: [string, ...string[]];
|
|
696
|
+
baseColumn: never;
|
|
697
|
+
identity: undefined;
|
|
698
|
+
generated: undefined;
|
|
699
|
+
}, {}>;
|
|
700
|
+
contentType: drizzle_orm_pg_core0.PgColumn<{
|
|
701
|
+
name: string;
|
|
702
|
+
tableName: "storage_blobs";
|
|
703
|
+
dataType: "string";
|
|
704
|
+
data: string;
|
|
705
|
+
driverParam: string;
|
|
706
|
+
notNull: false;
|
|
707
|
+
hasDefault: false;
|
|
708
|
+
isPrimaryKey: false;
|
|
709
|
+
isAutoincrement: false;
|
|
710
|
+
hasRuntimeDefault: false;
|
|
711
|
+
enumValues: [string, ...string[]];
|
|
712
|
+
baseColumn: never;
|
|
713
|
+
identity: undefined;
|
|
714
|
+
generated: undefined;
|
|
715
|
+
}, {}>;
|
|
716
|
+
metadata: drizzle_orm_pg_core0.PgColumn<{
|
|
717
|
+
name: string;
|
|
718
|
+
tableName: "storage_blobs";
|
|
719
|
+
dataType: "object json";
|
|
720
|
+
data: unknown;
|
|
721
|
+
driverParam: unknown;
|
|
722
|
+
notNull: false;
|
|
723
|
+
hasDefault: false;
|
|
724
|
+
isPrimaryKey: false;
|
|
725
|
+
isAutoincrement: false;
|
|
726
|
+
hasRuntimeDefault: false;
|
|
727
|
+
enumValues: undefined;
|
|
728
|
+
baseColumn: never;
|
|
729
|
+
identity: undefined;
|
|
730
|
+
generated: undefined;
|
|
731
|
+
}, {}>;
|
|
732
|
+
serviceName: drizzle_orm_pg_core0.PgColumn<{
|
|
733
|
+
name: string;
|
|
734
|
+
tableName: "storage_blobs";
|
|
735
|
+
dataType: "string";
|
|
736
|
+
data: string;
|
|
737
|
+
driverParam: string;
|
|
738
|
+
notNull: true;
|
|
739
|
+
hasDefault: true;
|
|
740
|
+
isPrimaryKey: false;
|
|
741
|
+
isAutoincrement: false;
|
|
742
|
+
hasRuntimeDefault: false;
|
|
743
|
+
enumValues: [string, ...string[]];
|
|
744
|
+
baseColumn: never;
|
|
745
|
+
identity: undefined;
|
|
746
|
+
generated: undefined;
|
|
747
|
+
}, {}>;
|
|
748
|
+
byteSize: drizzle_orm_pg_core0.PgColumn<{
|
|
749
|
+
name: string;
|
|
750
|
+
tableName: "storage_blobs";
|
|
751
|
+
dataType: "number int53";
|
|
752
|
+
data: number;
|
|
753
|
+
driverParam: string | number;
|
|
754
|
+
notNull: true;
|
|
755
|
+
hasDefault: false;
|
|
756
|
+
isPrimaryKey: false;
|
|
757
|
+
isAutoincrement: false;
|
|
758
|
+
hasRuntimeDefault: false;
|
|
759
|
+
enumValues: undefined;
|
|
760
|
+
baseColumn: never;
|
|
761
|
+
identity: undefined;
|
|
762
|
+
generated: undefined;
|
|
763
|
+
}, {}>;
|
|
764
|
+
checksum: drizzle_orm_pg_core0.PgColumn<{
|
|
765
|
+
name: string;
|
|
766
|
+
tableName: "storage_blobs";
|
|
767
|
+
dataType: "string";
|
|
768
|
+
data: string;
|
|
769
|
+
driverParam: string;
|
|
770
|
+
notNull: false;
|
|
771
|
+
hasDefault: false;
|
|
772
|
+
isPrimaryKey: false;
|
|
773
|
+
isAutoincrement: false;
|
|
774
|
+
hasRuntimeDefault: false;
|
|
775
|
+
enumValues: [string, ...string[]];
|
|
776
|
+
baseColumn: never;
|
|
777
|
+
identity: undefined;
|
|
778
|
+
generated: undefined;
|
|
779
|
+
}, {}>;
|
|
780
|
+
createdAt: drizzle_orm_pg_core0.PgColumn<{
|
|
781
|
+
name: string;
|
|
782
|
+
tableName: "storage_blobs";
|
|
783
|
+
dataType: "string timestamp";
|
|
784
|
+
data: string;
|
|
785
|
+
driverParam: string;
|
|
786
|
+
notNull: true;
|
|
787
|
+
hasDefault: true;
|
|
788
|
+
isPrimaryKey: false;
|
|
789
|
+
isAutoincrement: false;
|
|
790
|
+
hasRuntimeDefault: false;
|
|
791
|
+
enumValues: undefined;
|
|
792
|
+
baseColumn: never;
|
|
793
|
+
identity: undefined;
|
|
794
|
+
generated: undefined;
|
|
795
|
+
}, {}>;
|
|
796
|
+
};
|
|
797
|
+
dialect: "pg";
|
|
798
|
+
}>;
|
|
799
|
+
storageAttachments: drizzle_orm_pg_core0.PgTableWithColumns<{
|
|
800
|
+
name: "storage_attachments";
|
|
801
|
+
schema: undefined;
|
|
802
|
+
columns: {
|
|
803
|
+
id: drizzle_orm_pg_core0.PgColumn<{
|
|
804
|
+
name: string;
|
|
805
|
+
tableName: "storage_attachments";
|
|
806
|
+
dataType: "string";
|
|
807
|
+
data: string;
|
|
808
|
+
driverParam: string;
|
|
809
|
+
notNull: true;
|
|
810
|
+
hasDefault: true;
|
|
811
|
+
isPrimaryKey: true;
|
|
812
|
+
isAutoincrement: false;
|
|
813
|
+
hasRuntimeDefault: false;
|
|
814
|
+
enumValues: [string, ...string[]];
|
|
815
|
+
baseColumn: never;
|
|
816
|
+
identity: undefined;
|
|
817
|
+
generated: undefined;
|
|
818
|
+
}, {}>;
|
|
819
|
+
name: drizzle_orm_pg_core0.PgColumn<{
|
|
820
|
+
name: string;
|
|
821
|
+
tableName: "storage_attachments";
|
|
822
|
+
dataType: "string";
|
|
823
|
+
data: string;
|
|
824
|
+
driverParam: string;
|
|
825
|
+
notNull: true;
|
|
826
|
+
hasDefault: false;
|
|
827
|
+
isPrimaryKey: false;
|
|
828
|
+
isAutoincrement: false;
|
|
829
|
+
hasRuntimeDefault: false;
|
|
830
|
+
enumValues: [string, ...string[]];
|
|
831
|
+
baseColumn: never;
|
|
832
|
+
identity: undefined;
|
|
833
|
+
generated: undefined;
|
|
834
|
+
}, {}>;
|
|
835
|
+
recordType: drizzle_orm_pg_core0.PgColumn<{
|
|
836
|
+
name: string;
|
|
837
|
+
tableName: "storage_attachments";
|
|
838
|
+
dataType: "string";
|
|
839
|
+
data: string;
|
|
840
|
+
driverParam: string;
|
|
841
|
+
notNull: true;
|
|
842
|
+
hasDefault: false;
|
|
843
|
+
isPrimaryKey: false;
|
|
844
|
+
isAutoincrement: false;
|
|
845
|
+
hasRuntimeDefault: false;
|
|
846
|
+
enumValues: [string, ...string[]];
|
|
847
|
+
baseColumn: never;
|
|
848
|
+
identity: undefined;
|
|
849
|
+
generated: undefined;
|
|
850
|
+
}, {}>;
|
|
851
|
+
recordId: drizzle_orm_pg_core0.PgColumn<{
|
|
852
|
+
name: string;
|
|
853
|
+
tableName: "storage_attachments";
|
|
854
|
+
dataType: "string";
|
|
855
|
+
data: string;
|
|
856
|
+
driverParam: string;
|
|
857
|
+
notNull: true;
|
|
858
|
+
hasDefault: false;
|
|
859
|
+
isPrimaryKey: false;
|
|
860
|
+
isAutoincrement: false;
|
|
861
|
+
hasRuntimeDefault: false;
|
|
862
|
+
enumValues: [string, ...string[]];
|
|
863
|
+
baseColumn: never;
|
|
864
|
+
identity: undefined;
|
|
865
|
+
generated: undefined;
|
|
866
|
+
}, {}>;
|
|
867
|
+
blobId: drizzle_orm_pg_core0.PgColumn<{
|
|
868
|
+
name: string;
|
|
869
|
+
tableName: "storage_attachments";
|
|
870
|
+
dataType: "string";
|
|
871
|
+
data: string;
|
|
872
|
+
driverParam: string;
|
|
873
|
+
notNull: true;
|
|
874
|
+
hasDefault: false;
|
|
875
|
+
isPrimaryKey: false;
|
|
876
|
+
isAutoincrement: false;
|
|
877
|
+
hasRuntimeDefault: false;
|
|
878
|
+
enumValues: [string, ...string[]];
|
|
879
|
+
baseColumn: never;
|
|
880
|
+
identity: undefined;
|
|
881
|
+
generated: undefined;
|
|
882
|
+
}, {}>;
|
|
883
|
+
createdAt: drizzle_orm_pg_core0.PgColumn<{
|
|
884
|
+
name: string;
|
|
885
|
+
tableName: "storage_attachments";
|
|
886
|
+
dataType: "string timestamp";
|
|
887
|
+
data: string;
|
|
888
|
+
driverParam: string;
|
|
889
|
+
notNull: true;
|
|
890
|
+
hasDefault: true;
|
|
891
|
+
isPrimaryKey: false;
|
|
892
|
+
isAutoincrement: false;
|
|
893
|
+
hasRuntimeDefault: false;
|
|
894
|
+
enumValues: undefined;
|
|
895
|
+
baseColumn: never;
|
|
896
|
+
identity: undefined;
|
|
897
|
+
generated: undefined;
|
|
898
|
+
}, {}>;
|
|
899
|
+
};
|
|
900
|
+
dialect: "pg";
|
|
901
|
+
}>;
|
|
902
|
+
storageVariantRecords: drizzle_orm_pg_core0.PgTableWithColumns<{
|
|
903
|
+
name: "storage_variant_records";
|
|
904
|
+
schema: undefined;
|
|
905
|
+
columns: {
|
|
906
|
+
id: drizzle_orm_pg_core0.PgColumn<{
|
|
907
|
+
name: string;
|
|
908
|
+
tableName: "storage_variant_records";
|
|
909
|
+
dataType: "string";
|
|
910
|
+
data: string;
|
|
911
|
+
driverParam: string;
|
|
912
|
+
notNull: true;
|
|
913
|
+
hasDefault: true;
|
|
914
|
+
isPrimaryKey: true;
|
|
915
|
+
isAutoincrement: false;
|
|
916
|
+
hasRuntimeDefault: false;
|
|
917
|
+
enumValues: [string, ...string[]];
|
|
918
|
+
baseColumn: never;
|
|
919
|
+
identity: undefined;
|
|
920
|
+
generated: undefined;
|
|
921
|
+
}, {}>;
|
|
922
|
+
blobId: drizzle_orm_pg_core0.PgColumn<{
|
|
923
|
+
name: string;
|
|
924
|
+
tableName: "storage_variant_records";
|
|
925
|
+
dataType: "string";
|
|
926
|
+
data: string;
|
|
927
|
+
driverParam: string;
|
|
928
|
+
notNull: true;
|
|
929
|
+
hasDefault: false;
|
|
930
|
+
isPrimaryKey: false;
|
|
931
|
+
isAutoincrement: false;
|
|
932
|
+
hasRuntimeDefault: false;
|
|
933
|
+
enumValues: [string, ...string[]];
|
|
934
|
+
baseColumn: never;
|
|
935
|
+
identity: undefined;
|
|
936
|
+
generated: undefined;
|
|
937
|
+
}, {}>;
|
|
938
|
+
variationDigest: drizzle_orm_pg_core0.PgColumn<{
|
|
939
|
+
name: string;
|
|
940
|
+
tableName: "storage_variant_records";
|
|
941
|
+
dataType: "string";
|
|
942
|
+
data: string;
|
|
943
|
+
driverParam: string;
|
|
944
|
+
notNull: true;
|
|
945
|
+
hasDefault: false;
|
|
946
|
+
isPrimaryKey: false;
|
|
947
|
+
isAutoincrement: false;
|
|
948
|
+
hasRuntimeDefault: false;
|
|
949
|
+
enumValues: [string, ...string[]];
|
|
950
|
+
baseColumn: never;
|
|
951
|
+
identity: undefined;
|
|
952
|
+
generated: undefined;
|
|
953
|
+
}, {}>;
|
|
954
|
+
createdAt: drizzle_orm_pg_core0.PgColumn<{
|
|
955
|
+
name: string;
|
|
956
|
+
tableName: "storage_variant_records";
|
|
957
|
+
dataType: "string timestamp";
|
|
958
|
+
data: string;
|
|
959
|
+
driverParam: string;
|
|
960
|
+
notNull: true;
|
|
961
|
+
hasDefault: true;
|
|
962
|
+
isPrimaryKey: false;
|
|
963
|
+
isAutoincrement: false;
|
|
964
|
+
hasRuntimeDefault: false;
|
|
965
|
+
enumValues: undefined;
|
|
966
|
+
baseColumn: never;
|
|
967
|
+
identity: undefined;
|
|
968
|
+
generated: undefined;
|
|
969
|
+
}, {}>;
|
|
970
|
+
};
|
|
971
|
+
dialect: "pg";
|
|
972
|
+
}>;
|
|
973
|
+
};
|
|
974
|
+
relations: (r: orm_d_exports.RelationsBuilder<{
|
|
975
|
+
storageBlobs: drizzle_orm_pg_core0.PgTableWithColumns<{
|
|
976
|
+
name: "storage_blobs";
|
|
977
|
+
schema: undefined;
|
|
978
|
+
columns: {
|
|
979
|
+
id: drizzle_orm_pg_core0.PgColumn<{
|
|
980
|
+
name: string;
|
|
981
|
+
tableName: "storage_blobs";
|
|
982
|
+
dataType: "string";
|
|
983
|
+
data: string;
|
|
984
|
+
driverParam: string;
|
|
985
|
+
notNull: true;
|
|
986
|
+
hasDefault: true;
|
|
987
|
+
isPrimaryKey: true;
|
|
988
|
+
isAutoincrement: false;
|
|
989
|
+
hasRuntimeDefault: false;
|
|
990
|
+
enumValues: [string, ...string[]];
|
|
991
|
+
baseColumn: never;
|
|
992
|
+
identity: undefined;
|
|
993
|
+
generated: undefined;
|
|
994
|
+
}, {}>;
|
|
995
|
+
key: drizzle_orm_pg_core0.PgColumn<{
|
|
996
|
+
name: string;
|
|
997
|
+
tableName: "storage_blobs";
|
|
998
|
+
dataType: "string";
|
|
999
|
+
data: string;
|
|
1000
|
+
driverParam: string;
|
|
1001
|
+
notNull: true;
|
|
1002
|
+
hasDefault: false;
|
|
1003
|
+
isPrimaryKey: false;
|
|
1004
|
+
isAutoincrement: false;
|
|
1005
|
+
hasRuntimeDefault: false;
|
|
1006
|
+
enumValues: [string, ...string[]];
|
|
1007
|
+
baseColumn: never;
|
|
1008
|
+
identity: undefined;
|
|
1009
|
+
generated: undefined;
|
|
1010
|
+
}, {}>;
|
|
1011
|
+
filename: drizzle_orm_pg_core0.PgColumn<{
|
|
1012
|
+
name: string;
|
|
1013
|
+
tableName: "storage_blobs";
|
|
1014
|
+
dataType: "string";
|
|
1015
|
+
data: string;
|
|
1016
|
+
driverParam: string;
|
|
1017
|
+
notNull: true;
|
|
1018
|
+
hasDefault: false;
|
|
1019
|
+
isPrimaryKey: false;
|
|
1020
|
+
isAutoincrement: false;
|
|
1021
|
+
hasRuntimeDefault: false;
|
|
1022
|
+
enumValues: [string, ...string[]];
|
|
1023
|
+
baseColumn: never;
|
|
1024
|
+
identity: undefined;
|
|
1025
|
+
generated: undefined;
|
|
1026
|
+
}, {}>;
|
|
1027
|
+
contentType: drizzle_orm_pg_core0.PgColumn<{
|
|
1028
|
+
name: string;
|
|
1029
|
+
tableName: "storage_blobs";
|
|
1030
|
+
dataType: "string";
|
|
1031
|
+
data: string;
|
|
1032
|
+
driverParam: string;
|
|
1033
|
+
notNull: false;
|
|
1034
|
+
hasDefault: false;
|
|
1035
|
+
isPrimaryKey: false;
|
|
1036
|
+
isAutoincrement: false;
|
|
1037
|
+
hasRuntimeDefault: false;
|
|
1038
|
+
enumValues: [string, ...string[]];
|
|
1039
|
+
baseColumn: never;
|
|
1040
|
+
identity: undefined;
|
|
1041
|
+
generated: undefined;
|
|
1042
|
+
}, {}>;
|
|
1043
|
+
metadata: drizzle_orm_pg_core0.PgColumn<{
|
|
1044
|
+
name: string;
|
|
1045
|
+
tableName: "storage_blobs";
|
|
1046
|
+
dataType: "object json";
|
|
1047
|
+
data: unknown;
|
|
1048
|
+
driverParam: unknown;
|
|
1049
|
+
notNull: false;
|
|
1050
|
+
hasDefault: false;
|
|
1051
|
+
isPrimaryKey: false;
|
|
1052
|
+
isAutoincrement: false;
|
|
1053
|
+
hasRuntimeDefault: false;
|
|
1054
|
+
enumValues: undefined;
|
|
1055
|
+
baseColumn: never;
|
|
1056
|
+
identity: undefined;
|
|
1057
|
+
generated: undefined;
|
|
1058
|
+
}, {}>;
|
|
1059
|
+
serviceName: drizzle_orm_pg_core0.PgColumn<{
|
|
1060
|
+
name: string;
|
|
1061
|
+
tableName: "storage_blobs";
|
|
1062
|
+
dataType: "string";
|
|
1063
|
+
data: string;
|
|
1064
|
+
driverParam: string;
|
|
1065
|
+
notNull: true;
|
|
1066
|
+
hasDefault: true;
|
|
1067
|
+
isPrimaryKey: false;
|
|
1068
|
+
isAutoincrement: false;
|
|
1069
|
+
hasRuntimeDefault: false;
|
|
1070
|
+
enumValues: [string, ...string[]];
|
|
1071
|
+
baseColumn: never;
|
|
1072
|
+
identity: undefined;
|
|
1073
|
+
generated: undefined;
|
|
1074
|
+
}, {}>;
|
|
1075
|
+
byteSize: drizzle_orm_pg_core0.PgColumn<{
|
|
1076
|
+
name: string;
|
|
1077
|
+
tableName: "storage_blobs";
|
|
1078
|
+
dataType: "number int53";
|
|
1079
|
+
data: number;
|
|
1080
|
+
driverParam: string | number;
|
|
1081
|
+
notNull: true;
|
|
1082
|
+
hasDefault: false;
|
|
1083
|
+
isPrimaryKey: false;
|
|
1084
|
+
isAutoincrement: false;
|
|
1085
|
+
hasRuntimeDefault: false;
|
|
1086
|
+
enumValues: undefined;
|
|
1087
|
+
baseColumn: never;
|
|
1088
|
+
identity: undefined;
|
|
1089
|
+
generated: undefined;
|
|
1090
|
+
}, {}>;
|
|
1091
|
+
checksum: drizzle_orm_pg_core0.PgColumn<{
|
|
1092
|
+
name: string;
|
|
1093
|
+
tableName: "storage_blobs";
|
|
1094
|
+
dataType: "string";
|
|
1095
|
+
data: string;
|
|
1096
|
+
driverParam: string;
|
|
1097
|
+
notNull: false;
|
|
1098
|
+
hasDefault: false;
|
|
1099
|
+
isPrimaryKey: false;
|
|
1100
|
+
isAutoincrement: false;
|
|
1101
|
+
hasRuntimeDefault: false;
|
|
1102
|
+
enumValues: [string, ...string[]];
|
|
1103
|
+
baseColumn: never;
|
|
1104
|
+
identity: undefined;
|
|
1105
|
+
generated: undefined;
|
|
1106
|
+
}, {}>;
|
|
1107
|
+
createdAt: drizzle_orm_pg_core0.PgColumn<{
|
|
1108
|
+
name: string;
|
|
1109
|
+
tableName: "storage_blobs";
|
|
1110
|
+
dataType: "string timestamp";
|
|
1111
|
+
data: string;
|
|
1112
|
+
driverParam: string;
|
|
1113
|
+
notNull: true;
|
|
1114
|
+
hasDefault: true;
|
|
1115
|
+
isPrimaryKey: false;
|
|
1116
|
+
isAutoincrement: false;
|
|
1117
|
+
hasRuntimeDefault: false;
|
|
1118
|
+
enumValues: undefined;
|
|
1119
|
+
baseColumn: never;
|
|
1120
|
+
identity: undefined;
|
|
1121
|
+
generated: undefined;
|
|
1122
|
+
}, {}>;
|
|
1123
|
+
};
|
|
1124
|
+
dialect: "pg";
|
|
1125
|
+
}>;
|
|
1126
|
+
storageAttachments: drizzle_orm_pg_core0.PgTableWithColumns<{
|
|
1127
|
+
name: "storage_attachments";
|
|
1128
|
+
schema: undefined;
|
|
1129
|
+
columns: {
|
|
1130
|
+
id: drizzle_orm_pg_core0.PgColumn<{
|
|
1131
|
+
name: string;
|
|
1132
|
+
tableName: "storage_attachments";
|
|
1133
|
+
dataType: "string";
|
|
1134
|
+
data: string;
|
|
1135
|
+
driverParam: string;
|
|
1136
|
+
notNull: true;
|
|
1137
|
+
hasDefault: true;
|
|
1138
|
+
isPrimaryKey: true;
|
|
1139
|
+
isAutoincrement: false;
|
|
1140
|
+
hasRuntimeDefault: false;
|
|
1141
|
+
enumValues: [string, ...string[]];
|
|
1142
|
+
baseColumn: never;
|
|
1143
|
+
identity: undefined;
|
|
1144
|
+
generated: undefined;
|
|
1145
|
+
}, {}>;
|
|
1146
|
+
name: drizzle_orm_pg_core0.PgColumn<{
|
|
1147
|
+
name: string;
|
|
1148
|
+
tableName: "storage_attachments";
|
|
1149
|
+
dataType: "string";
|
|
1150
|
+
data: string;
|
|
1151
|
+
driverParam: string;
|
|
1152
|
+
notNull: true;
|
|
1153
|
+
hasDefault: false;
|
|
1154
|
+
isPrimaryKey: false;
|
|
1155
|
+
isAutoincrement: false;
|
|
1156
|
+
hasRuntimeDefault: false;
|
|
1157
|
+
enumValues: [string, ...string[]];
|
|
1158
|
+
baseColumn: never;
|
|
1159
|
+
identity: undefined;
|
|
1160
|
+
generated: undefined;
|
|
1161
|
+
}, {}>;
|
|
1162
|
+
recordType: drizzle_orm_pg_core0.PgColumn<{
|
|
1163
|
+
name: string;
|
|
1164
|
+
tableName: "storage_attachments";
|
|
1165
|
+
dataType: "string";
|
|
1166
|
+
data: string;
|
|
1167
|
+
driverParam: string;
|
|
1168
|
+
notNull: true;
|
|
1169
|
+
hasDefault: false;
|
|
1170
|
+
isPrimaryKey: false;
|
|
1171
|
+
isAutoincrement: false;
|
|
1172
|
+
hasRuntimeDefault: false;
|
|
1173
|
+
enumValues: [string, ...string[]];
|
|
1174
|
+
baseColumn: never;
|
|
1175
|
+
identity: undefined;
|
|
1176
|
+
generated: undefined;
|
|
1177
|
+
}, {}>;
|
|
1178
|
+
recordId: drizzle_orm_pg_core0.PgColumn<{
|
|
1179
|
+
name: string;
|
|
1180
|
+
tableName: "storage_attachments";
|
|
1181
|
+
dataType: "string";
|
|
1182
|
+
data: string;
|
|
1183
|
+
driverParam: string;
|
|
1184
|
+
notNull: true;
|
|
1185
|
+
hasDefault: false;
|
|
1186
|
+
isPrimaryKey: false;
|
|
1187
|
+
isAutoincrement: false;
|
|
1188
|
+
hasRuntimeDefault: false;
|
|
1189
|
+
enumValues: [string, ...string[]];
|
|
1190
|
+
baseColumn: never;
|
|
1191
|
+
identity: undefined;
|
|
1192
|
+
generated: undefined;
|
|
1193
|
+
}, {}>;
|
|
1194
|
+
blobId: drizzle_orm_pg_core0.PgColumn<{
|
|
1195
|
+
name: string;
|
|
1196
|
+
tableName: "storage_attachments";
|
|
1197
|
+
dataType: "string";
|
|
1198
|
+
data: string;
|
|
1199
|
+
driverParam: string;
|
|
1200
|
+
notNull: true;
|
|
1201
|
+
hasDefault: false;
|
|
1202
|
+
isPrimaryKey: false;
|
|
1203
|
+
isAutoincrement: false;
|
|
1204
|
+
hasRuntimeDefault: false;
|
|
1205
|
+
enumValues: [string, ...string[]];
|
|
1206
|
+
baseColumn: never;
|
|
1207
|
+
identity: undefined;
|
|
1208
|
+
generated: undefined;
|
|
1209
|
+
}, {}>;
|
|
1210
|
+
createdAt: drizzle_orm_pg_core0.PgColumn<{
|
|
1211
|
+
name: string;
|
|
1212
|
+
tableName: "storage_attachments";
|
|
1213
|
+
dataType: "string timestamp";
|
|
1214
|
+
data: string;
|
|
1215
|
+
driverParam: string;
|
|
1216
|
+
notNull: true;
|
|
1217
|
+
hasDefault: true;
|
|
1218
|
+
isPrimaryKey: false;
|
|
1219
|
+
isAutoincrement: false;
|
|
1220
|
+
hasRuntimeDefault: false;
|
|
1221
|
+
enumValues: undefined;
|
|
1222
|
+
baseColumn: never;
|
|
1223
|
+
identity: undefined;
|
|
1224
|
+
generated: undefined;
|
|
1225
|
+
}, {}>;
|
|
1226
|
+
};
|
|
1227
|
+
dialect: "pg";
|
|
1228
|
+
}>;
|
|
1229
|
+
storageVariantRecords: drizzle_orm_pg_core0.PgTableWithColumns<{
|
|
1230
|
+
name: "storage_variant_records";
|
|
1231
|
+
schema: undefined;
|
|
1232
|
+
columns: {
|
|
1233
|
+
id: drizzle_orm_pg_core0.PgColumn<{
|
|
1234
|
+
name: string;
|
|
1235
|
+
tableName: "storage_variant_records";
|
|
1236
|
+
dataType: "string";
|
|
1237
|
+
data: string;
|
|
1238
|
+
driverParam: string;
|
|
1239
|
+
notNull: true;
|
|
1240
|
+
hasDefault: true;
|
|
1241
|
+
isPrimaryKey: true;
|
|
1242
|
+
isAutoincrement: false;
|
|
1243
|
+
hasRuntimeDefault: false;
|
|
1244
|
+
enumValues: [string, ...string[]];
|
|
1245
|
+
baseColumn: never;
|
|
1246
|
+
identity: undefined;
|
|
1247
|
+
generated: undefined;
|
|
1248
|
+
}, {}>;
|
|
1249
|
+
blobId: drizzle_orm_pg_core0.PgColumn<{
|
|
1250
|
+
name: string;
|
|
1251
|
+
tableName: "storage_variant_records";
|
|
1252
|
+
dataType: "string";
|
|
1253
|
+
data: string;
|
|
1254
|
+
driverParam: string;
|
|
1255
|
+
notNull: true;
|
|
1256
|
+
hasDefault: false;
|
|
1257
|
+
isPrimaryKey: false;
|
|
1258
|
+
isAutoincrement: false;
|
|
1259
|
+
hasRuntimeDefault: false;
|
|
1260
|
+
enumValues: [string, ...string[]];
|
|
1261
|
+
baseColumn: never;
|
|
1262
|
+
identity: undefined;
|
|
1263
|
+
generated: undefined;
|
|
1264
|
+
}, {}>;
|
|
1265
|
+
variationDigest: drizzle_orm_pg_core0.PgColumn<{
|
|
1266
|
+
name: string;
|
|
1267
|
+
tableName: "storage_variant_records";
|
|
1268
|
+
dataType: "string";
|
|
1269
|
+
data: string;
|
|
1270
|
+
driverParam: string;
|
|
1271
|
+
notNull: true;
|
|
1272
|
+
hasDefault: false;
|
|
1273
|
+
isPrimaryKey: false;
|
|
1274
|
+
isAutoincrement: false;
|
|
1275
|
+
hasRuntimeDefault: false;
|
|
1276
|
+
enumValues: [string, ...string[]];
|
|
1277
|
+
baseColumn: never;
|
|
1278
|
+
identity: undefined;
|
|
1279
|
+
generated: undefined;
|
|
1280
|
+
}, {}>;
|
|
1281
|
+
createdAt: drizzle_orm_pg_core0.PgColumn<{
|
|
1282
|
+
name: string;
|
|
1283
|
+
tableName: "storage_variant_records";
|
|
1284
|
+
dataType: "string timestamp";
|
|
1285
|
+
data: string;
|
|
1286
|
+
driverParam: string;
|
|
1287
|
+
notNull: true;
|
|
1288
|
+
hasDefault: true;
|
|
1289
|
+
isPrimaryKey: false;
|
|
1290
|
+
isAutoincrement: false;
|
|
1291
|
+
hasRuntimeDefault: false;
|
|
1292
|
+
enumValues: undefined;
|
|
1293
|
+
baseColumn: never;
|
|
1294
|
+
identity: undefined;
|
|
1295
|
+
generated: undefined;
|
|
1296
|
+
}, {}>;
|
|
1297
|
+
};
|
|
1298
|
+
dialect: "pg";
|
|
1299
|
+
}>;
|
|
1300
|
+
}>) => {
|
|
1301
|
+
storageBlobs: {
|
|
1302
|
+
attachments: drizzle_orm2.Many<"storageAttachments">;
|
|
1303
|
+
variantRecords: drizzle_orm2.Many<"storageVariantRecords">;
|
|
1304
|
+
};
|
|
1305
|
+
storageAttachments: {
|
|
1306
|
+
blob: drizzle_orm2.One<"storageBlobs", true>;
|
|
1307
|
+
};
|
|
1308
|
+
storageVariantRecords: {
|
|
1309
|
+
blob: drizzle_orm2.One<"storageBlobs", true>;
|
|
1310
|
+
};
|
|
1311
|
+
};
|
|
1312
|
+
};
|
|
1313
|
+
/**
|
|
1314
|
+
* Create a schema instance for type inference and exports.
|
|
1315
|
+
*/
|
|
1316
|
+
type StorageSchema = ReturnType<typeof defineStorageSchema>;
|
|
1317
|
+
/**
|
|
1318
|
+
* Type for storage tables.
|
|
1319
|
+
*/
|
|
1320
|
+
type StorageTables = StorageSchema["tables"];
|
|
1321
|
+
/**
|
|
1322
|
+
* Type for storage relations.
|
|
1323
|
+
*/
|
|
1324
|
+
type StorageRelations = ReturnType<StorageSchema["relations"]>;
|
|
1325
|
+
type StorageBlob = StorageTables["storageBlobs"]["$inferSelect"];
|
|
1326
|
+
/**
|
|
1327
|
+
* Type for the storage relations config (result of defineRelations).
|
|
1328
|
+
* Computed at type-level without runtime call.
|
|
1329
|
+
*/
|
|
1330
|
+
type StorageRelationsConfig = ExtractTablesWithRelations<StorageRelations, StorageTables>;
|
|
1331
|
+
//#endregion
|
|
1332
|
+
//#region src/api/workflow.d.ts
|
|
1333
|
+
/**
|
|
1334
|
+
* Handle to a running or completed workflow.
|
|
1335
|
+
*/
|
|
1336
|
+
interface WorkflowHandle<TOutput> {
|
|
1337
|
+
/**
|
|
1338
|
+
* Get the current status of the workflow.
|
|
1339
|
+
*/
|
|
1340
|
+
getStatus(): Promise<unknown>;
|
|
1341
|
+
/**
|
|
1342
|
+
* Wait for the workflow to complete and return its result.
|
|
1343
|
+
*/
|
|
1344
|
+
getResult(): Promise<TOutput>;
|
|
1345
|
+
/**
|
|
1346
|
+
* The unique ID of this workflow execution.
|
|
1347
|
+
*/
|
|
1348
|
+
workflowId: string;
|
|
1349
|
+
}
|
|
1350
|
+
//#endregion
|
|
1351
|
+
//#region src/api/workflows/generate-image-variant.d.ts
|
|
1352
|
+
/**
|
|
1353
|
+
* Image transformations schema.
|
|
1354
|
+
* Supports resize, rotate, flip, flop, sharpen, blur, grayscale, format conversion.
|
|
1355
|
+
*/
|
|
1356
|
+
declare const transformationsSchema: z.ZodObject<{
|
|
1357
|
+
resize: z.ZodOptional<z.ZodObject<{
|
|
1358
|
+
width: z.ZodOptional<z.ZodNumber>;
|
|
1359
|
+
height: z.ZodOptional<z.ZodNumber>;
|
|
1360
|
+
fit: z.ZodOptional<z.ZodEnum<{
|
|
1361
|
+
fill: "fill";
|
|
1362
|
+
cover: "cover";
|
|
1363
|
+
contain: "contain";
|
|
1364
|
+
inside: "inside";
|
|
1365
|
+
outside: "outside";
|
|
1366
|
+
}>>;
|
|
1367
|
+
position: z.ZodOptional<z.ZodEnum<{
|
|
1368
|
+
left: "left";
|
|
1369
|
+
right: "right";
|
|
1370
|
+
top: "top";
|
|
1371
|
+
"right top": "right top";
|
|
1372
|
+
"right bottom": "right bottom";
|
|
1373
|
+
bottom: "bottom";
|
|
1374
|
+
"left bottom": "left bottom";
|
|
1375
|
+
"left top": "left top";
|
|
1376
|
+
centre: "centre";
|
|
1377
|
+
}>>;
|
|
1378
|
+
kernel: z.ZodOptional<z.ZodEnum<{
|
|
1379
|
+
nearest: "nearest";
|
|
1380
|
+
linear: "linear";
|
|
1381
|
+
cubic: "cubic";
|
|
1382
|
+
mitchell: "mitchell";
|
|
1383
|
+
lanczos2: "lanczos2";
|
|
1384
|
+
lanczos3: "lanczos3";
|
|
1385
|
+
}>>;
|
|
1386
|
+
}, z.core.$strip>>;
|
|
1387
|
+
rotate: z.ZodOptional<z.ZodNumber>;
|
|
1388
|
+
flip: z.ZodOptional<z.ZodBoolean>;
|
|
1389
|
+
flop: z.ZodOptional<z.ZodBoolean>;
|
|
1390
|
+
sharpen: z.ZodOptional<z.ZodBoolean>;
|
|
1391
|
+
blur: z.ZodOptional<z.ZodNumber>;
|
|
1392
|
+
grayscale: z.ZodOptional<z.ZodBoolean>;
|
|
1393
|
+
format: z.ZodOptional<z.ZodEnum<{
|
|
1394
|
+
jpeg: "jpeg";
|
|
1395
|
+
png: "png";
|
|
1396
|
+
webp: "webp";
|
|
1397
|
+
avif: "avif";
|
|
1398
|
+
gif: "gif";
|
|
1399
|
+
}>>;
|
|
1400
|
+
quality: z.ZodOptional<z.ZodNumber>;
|
|
1401
|
+
preview: z.ZodOptional<z.ZodLiteral<true>>;
|
|
1402
|
+
}, z.core.$strip>;
|
|
1403
|
+
/**
|
|
1404
|
+
* Types for image transformations.
|
|
1405
|
+
*/
|
|
1406
|
+
type ImageTransformations = z.infer<typeof transformationsSchema>;
|
|
1407
|
+
//#endregion
|
|
1408
|
+
//#region src/api/storage.d.ts
|
|
1409
|
+
/**
|
|
1410
|
+
* Database type with storage schema and relations.
|
|
1411
|
+
*/
|
|
1412
|
+
type DatabaseWithStorage = NodePgDatabase<StorageTables, StorageRelationsConfig> & {
|
|
1413
|
+
$client: Pool;
|
|
1414
|
+
};
|
|
1415
|
+
/**
|
|
1416
|
+
* Type of the storage service instance.
|
|
1417
|
+
*/
|
|
1418
|
+
type Storage<TDisks extends Record<string, FSDriverOptions | S3DriverOptions> = Record<string, FSDriverOptions | S3DriverOptions>, TTableNames extends string = string, TAttachments extends Partial<Record<TTableNames, readonly string[]>> = Record<never, never>> = StorageService<Extract<keyof TDisks, string>, TTableNames, TAttachments>;
|
|
1419
|
+
/**
|
|
1420
|
+
* Helper type to extract attachment name for a specific table.
|
|
1421
|
+
*/
|
|
1422
|
+
type AttachmentName<TAttachments extends Partial<Record<string, readonly string[]>>, TTable extends string> = TTable extends keyof TAttachments ? TAttachments[TTable] extends readonly (infer N)[] ? N : string : string;
|
|
1423
|
+
/**
|
|
1424
|
+
* Storage service for blob operations.
|
|
1425
|
+
*
|
|
1426
|
+
* This service uses a dual-drive architecture when configured:
|
|
1427
|
+
* - `drive`: For actual file operations (upload, delete, read) using internal endpoints
|
|
1428
|
+
* - `signedUrlDrive`: For generating browser-accessible signed URLs with public endpoints
|
|
1429
|
+
*
|
|
1430
|
+
* This allows containers to use fast internal network for operations while
|
|
1431
|
+
* generating URLs that work in end-user browsers.
|
|
1432
|
+
*
|
|
1433
|
+
* @template TDiskNames - Union of disk names (e.g., "private" | "public")
|
|
1434
|
+
* @template TTableNames - Union of table names for type-safe attachment methods
|
|
1435
|
+
* @template TAttachments - Mapping of table names to valid attachment names
|
|
1436
|
+
*/
|
|
1437
|
+
declare class StorageService<TDiskNames extends string = string, TTableNames extends string = string, TAttachments extends Partial<Record<TTableNames, readonly string[]>> = Record<never, never>> {
|
|
1438
|
+
/**
|
|
1439
|
+
* The drive manager for file operations.
|
|
1440
|
+
*/
|
|
1441
|
+
readonly drive: DriveManager<any>;
|
|
1442
|
+
/**
|
|
1443
|
+
* The database instance with storage schema and relations.
|
|
1444
|
+
*/
|
|
1445
|
+
readonly db: DatabaseWithStorage;
|
|
1446
|
+
/**
|
|
1447
|
+
* The default disk name.
|
|
1448
|
+
*/
|
|
1449
|
+
readonly defaultDisk: TDiskNames;
|
|
1450
|
+
/**
|
|
1451
|
+
* Cron expression for unattached blob purge schedule.
|
|
1452
|
+
*
|
|
1453
|
+
* @default "0 0 * * *"
|
|
1454
|
+
*/
|
|
1455
|
+
readonly purgeCron?: string;
|
|
1456
|
+
/**
|
|
1457
|
+
* Secret key for signing blob IDs.
|
|
1458
|
+
*/
|
|
1459
|
+
readonly secret?: string;
|
|
1460
|
+
/**
|
|
1461
|
+
* Drive manager for generating signed URLs (public endpoint).
|
|
1462
|
+
*/
|
|
1463
|
+
readonly signedUrlDrive: DriveManager<any>;
|
|
1464
|
+
constructor(drive: DriveManager<any>, db: DatabaseWithStorage, defaultDisk: TDiskNames, signedUrlDrive: DriveManager<any>, purgeCron?: string, secret?: string);
|
|
1465
|
+
/**
|
|
1466
|
+
* Create a blob record and upload file.
|
|
1467
|
+
*/
|
|
1468
|
+
createBlob(file: Buffer | Uint8Array, options: {
|
|
1469
|
+
filename: string;
|
|
1470
|
+
contentType?: string;
|
|
1471
|
+
metadata?: Record<string, any>;
|
|
1472
|
+
serviceName?: TDiskNames;
|
|
1473
|
+
prefix?: string;
|
|
1474
|
+
}): Promise<StorageBlob>;
|
|
1475
|
+
/**
|
|
1476
|
+
* Get blob by ID.
|
|
1477
|
+
*/
|
|
1478
|
+
getBlob(id: string): Promise<StorageBlob | null>;
|
|
1479
|
+
/**
|
|
1480
|
+
* Download blob content.
|
|
1481
|
+
*/
|
|
1482
|
+
downloadBlob(id: string): Promise<Buffer | null>;
|
|
1483
|
+
/**
|
|
1484
|
+
* Delete blob and its content.
|
|
1485
|
+
*/
|
|
1486
|
+
deleteBlob(id: string): Promise<boolean>;
|
|
1487
|
+
/**
|
|
1488
|
+
* Get signed URL for blob. If blob is on public service, returns permanent
|
|
1489
|
+
* URL instead.
|
|
1490
|
+
*/
|
|
1491
|
+
getSignedUrl(id: string, options?: {
|
|
1492
|
+
expiresIn?: number;
|
|
1493
|
+
disposition?: "inline" | "attachment";
|
|
1494
|
+
filename?: string;
|
|
1495
|
+
}): Promise<string | null>;
|
|
1496
|
+
/**
|
|
1497
|
+
* Get permanent public URL (no expiration).
|
|
1498
|
+
* Works for blobs on public storage service.
|
|
1499
|
+
*/
|
|
1500
|
+
getPublicUrl(id: string): Promise<string | null>;
|
|
1501
|
+
/**
|
|
1502
|
+
* Create attachment between a record and blob.
|
|
1503
|
+
*
|
|
1504
|
+
* @param recordType - The table name (e.g., 'users')
|
|
1505
|
+
* @param recordId - The record ID
|
|
1506
|
+
* @param blobId - The blob ID to attach
|
|
1507
|
+
* @param name - The attachment name (e.g., 'avatar')
|
|
1508
|
+
* @param replaceExisting - If true, replaces existing attachment with same name (for one-to-one)
|
|
1509
|
+
*/
|
|
1510
|
+
createAttachment(recordType: string, recordId: string, blobId: string, name: string, replaceExisting?: boolean): Promise<{
|
|
1511
|
+
id: string;
|
|
1512
|
+
createdAt: string;
|
|
1513
|
+
name: string;
|
|
1514
|
+
recordType: string;
|
|
1515
|
+
recordId: string;
|
|
1516
|
+
blobId: string;
|
|
1517
|
+
}>;
|
|
1518
|
+
/**
|
|
1519
|
+
* Get attachments for a record with their associated blobs.
|
|
1520
|
+
*/
|
|
1521
|
+
getAttachments(recordType: string, recordId: string, name?: string): Promise<{
|
|
1522
|
+
id: string;
|
|
1523
|
+
createdAt: string;
|
|
1524
|
+
name: string;
|
|
1525
|
+
recordType: string;
|
|
1526
|
+
recordId: string;
|
|
1527
|
+
blobId: string;
|
|
1528
|
+
blob: {
|
|
1529
|
+
metadata: unknown;
|
|
1530
|
+
id: string;
|
|
1531
|
+
key: string;
|
|
1532
|
+
filename: string;
|
|
1533
|
+
contentType: string | null;
|
|
1534
|
+
serviceName: string;
|
|
1535
|
+
byteSize: number;
|
|
1536
|
+
checksum: string | null;
|
|
1537
|
+
createdAt: string;
|
|
1538
|
+
} | null;
|
|
1539
|
+
}[]>;
|
|
1540
|
+
/**
|
|
1541
|
+
* Get attachments by their IDs with associated blobs.
|
|
1542
|
+
*
|
|
1543
|
+
* @param attachmentIds - Array of attachment IDs to fetch.
|
|
1544
|
+
*/
|
|
1545
|
+
getAttachmentsByIds(attachmentIds: string[]): Promise<{
|
|
1546
|
+
id: string;
|
|
1547
|
+
createdAt: string;
|
|
1548
|
+
name: string;
|
|
1549
|
+
recordType: string;
|
|
1550
|
+
recordId: string;
|
|
1551
|
+
blobId: string;
|
|
1552
|
+
blob: {
|
|
1553
|
+
metadata: unknown;
|
|
1554
|
+
id: string;
|
|
1555
|
+
key: string;
|
|
1556
|
+
filename: string;
|
|
1557
|
+
contentType: string | null;
|
|
1558
|
+
serviceName: string;
|
|
1559
|
+
byteSize: number;
|
|
1560
|
+
checksum: string | null;
|
|
1561
|
+
createdAt: string;
|
|
1562
|
+
} | null;
|
|
1563
|
+
}[]>;
|
|
1564
|
+
/**
|
|
1565
|
+
* Delete a single attachment by ID.
|
|
1566
|
+
*/
|
|
1567
|
+
deleteAttachment(attachmentId: string): Promise<boolean>;
|
|
1568
|
+
/**
|
|
1569
|
+
* Delete attachments for a record (without deleting the blobs).
|
|
1570
|
+
*/
|
|
1571
|
+
deleteAttachments(recordType: string, recordId: string, name?: string): Promise<number>;
|
|
1572
|
+
/**
|
|
1573
|
+
* Get direct upload credentials (for S3). Also creates a pending blob record
|
|
1574
|
+
* that will be finalized after upload.
|
|
1575
|
+
*/
|
|
1576
|
+
getDirectUploadUrl(options: {
|
|
1577
|
+
contentType?: string;
|
|
1578
|
+
expiresIn?: number;
|
|
1579
|
+
filename: string;
|
|
1580
|
+
metadata?: Record<string, any>;
|
|
1581
|
+
serviceName?: TDiskNames;
|
|
1582
|
+
}): Promise<{
|
|
1583
|
+
blobId: string;
|
|
1584
|
+
headers?: Record<string, string>;
|
|
1585
|
+
key: string;
|
|
1586
|
+
url: string;
|
|
1587
|
+
} | null>;
|
|
1588
|
+
/**
|
|
1589
|
+
* Finalize a direct upload by updating blob metadata. Call this after the
|
|
1590
|
+
* client has uploaded to S3.
|
|
1591
|
+
*/
|
|
1592
|
+
finalizeDirectUpload(blobId: string, actualSize: number): Promise<void>;
|
|
1593
|
+
/**
|
|
1594
|
+
* Update blob metadata (for automatic extraction).
|
|
1595
|
+
*/
|
|
1596
|
+
updateBlobMetadata(blobId: string, metadata: Record<string, any>): Promise<void>;
|
|
1597
|
+
/**
|
|
1598
|
+
* Get existing variant or return null.
|
|
1599
|
+
*/
|
|
1600
|
+
getVariant(blobId: string, transformations: ImageTransformations): Promise<StorageBlob | null>;
|
|
1601
|
+
/**
|
|
1602
|
+
* Create variant blob and record.
|
|
1603
|
+
*/
|
|
1604
|
+
createVariant(blobId: string, transformations: ImageTransformations, variantBuffer: Buffer): Promise<StorageBlob>;
|
|
1605
|
+
/**
|
|
1606
|
+
* Get blobs that have no attachments (orphaned). Useful for cleanup jobs.
|
|
1607
|
+
*/
|
|
1608
|
+
getUnattachedBlobs(options?: {
|
|
1609
|
+
olderThan?: string;
|
|
1610
|
+
limit?: number;
|
|
1611
|
+
}): Promise<StorageBlob[]>;
|
|
1612
|
+
/**
|
|
1613
|
+
* Get pending blobs that were never finalized (stuck direct uploads).
|
|
1614
|
+
*/
|
|
1615
|
+
getPendingBlobs(olderThan?: string): Promise<StorageBlob[]>;
|
|
1616
|
+
/**
|
|
1617
|
+
* Purge unattached blobs.
|
|
1618
|
+
*/
|
|
1619
|
+
purgeUnattached(olderThan?: string): Promise<number>;
|
|
1620
|
+
/**
|
|
1621
|
+
* Create a signed, tamper-proof reference to a blob.
|
|
1622
|
+
* Use findSigned() to resolve back to blob.
|
|
1623
|
+
*
|
|
1624
|
+
* Algorithm:
|
|
1625
|
+
* 1. Create payload with blobId and expiration timestamp
|
|
1626
|
+
* 2. JSON stringify and base64url encode the payload
|
|
1627
|
+
* 3. Create HMAC-SHA256 signature of the encoded payload
|
|
1628
|
+
* 4. Return payload.signature format
|
|
1629
|
+
*/
|
|
1630
|
+
signedId(blobId: string, expiresIn?: number): string;
|
|
1631
|
+
/**
|
|
1632
|
+
* Find blob by signed ID. Returns null if invalid or expired.
|
|
1633
|
+
* Uses constant-time comparison to prevent timing attacks.
|
|
1634
|
+
*
|
|
1635
|
+
* Algorithm:
|
|
1636
|
+
* 1. Split signed ID into payload and signature
|
|
1637
|
+
* 2. Decode and recompute expected signature
|
|
1638
|
+
* 3. Use timingSafeEqual for constant-time comparison
|
|
1639
|
+
* 4. Check expiration timestamp
|
|
1640
|
+
* 5. Return blob if valid, null otherwise
|
|
1641
|
+
*/
|
|
1642
|
+
findSigned(signedId: string): Promise<StorageBlob | null>;
|
|
1643
|
+
/**
|
|
1644
|
+
* Get a single attachment handle (one-to-one relationship).
|
|
1645
|
+
* Similar to Rails' `has_one_attached :avatar`.
|
|
1646
|
+
*
|
|
1647
|
+
* Algorithm:
|
|
1648
|
+
* Returns an object with methods to manage a single attachment:
|
|
1649
|
+
* - attach(): Replace existing attachment with new blob
|
|
1650
|
+
* - get(): Get attached blob or null
|
|
1651
|
+
* - url(): Get signed URL
|
|
1652
|
+
* - variant(): Get/generate image variant
|
|
1653
|
+
* - purge(): Delete attachment and blob
|
|
1654
|
+
*
|
|
1655
|
+
* @template TTable - The table name (must be in TTableNames)
|
|
1656
|
+
*/
|
|
1657
|
+
one<TTable extends TTableNames>(recordType: TTable, recordId: string, name: AttachmentName<TAttachments, TTable>): {
|
|
1658
|
+
/**
|
|
1659
|
+
* Attach a blob to this record (replaces existing).
|
|
1660
|
+
* Auto-triggers extractBlobMetadata workflow.
|
|
1661
|
+
*/
|
|
1662
|
+
attach(blobId: string): Promise<{
|
|
1663
|
+
id: string;
|
|
1664
|
+
createdAt: string;
|
|
1665
|
+
name: string;
|
|
1666
|
+
recordType: string;
|
|
1667
|
+
recordId: string;
|
|
1668
|
+
blobId: string;
|
|
1669
|
+
}>;
|
|
1670
|
+
/** Get the attached blob or null. */
|
|
1671
|
+
get(): Promise<StorageBlob | null>;
|
|
1672
|
+
/** Check if a blob is attached. */
|
|
1673
|
+
attached(): Promise<boolean>;
|
|
1674
|
+
/** Get signed URL or null. */
|
|
1675
|
+
url(options?: {
|
|
1676
|
+
expiresIn?: number;
|
|
1677
|
+
disposition?: "inline" | "attachment";
|
|
1678
|
+
}): Promise<string | null>;
|
|
1679
|
+
/** Get permanent public URL or null. */
|
|
1680
|
+
publicUrl(): Promise<string | null>;
|
|
1681
|
+
/** Get blob metadata or null. */
|
|
1682
|
+
metadata(): Promise<Record<string, unknown> | null>;
|
|
1683
|
+
/** Check if metadata has been extracted. */
|
|
1684
|
+
analyzed(): Promise<boolean>;
|
|
1685
|
+
/** Check if blob supports preview/variant generation. */
|
|
1686
|
+
representable(): Promise<boolean>;
|
|
1687
|
+
/**
|
|
1688
|
+
* Get variant URL. Auto-enqueues generation if not ready.
|
|
1689
|
+
* Returns URL if variant exists, null if generating.
|
|
1690
|
+
*/
|
|
1691
|
+
variant(transformations: ImageTransformations, expiresIn?: number): Promise<string | null>;
|
|
1692
|
+
/**
|
|
1693
|
+
* Get preview URL. Auto-enqueues generation if not ready.
|
|
1694
|
+
* Returns URL if preview exists, null if generating.
|
|
1695
|
+
*/
|
|
1696
|
+
preview(expiresIn?: number, timeInSeconds?: number): Promise<string | null>;
|
|
1697
|
+
/** Detach blob from record (keeps blob for reuse). */
|
|
1698
|
+
detach(): Promise<boolean>;
|
|
1699
|
+
/** Delete attachment AND blob immediately. */
|
|
1700
|
+
purge(): Promise<boolean>;
|
|
1701
|
+
/** Enqueue attachment and blob deletion in background. */
|
|
1702
|
+
purgeLater(): Promise<boolean>;
|
|
1703
|
+
/** Download blob content as Buffer. */
|
|
1704
|
+
download(): Promise<Buffer | null>;
|
|
1705
|
+
/** Download to temp file, run callback, auto-cleanup. */
|
|
1706
|
+
open<T>(callback: (filePath: string) => Promise<T> | T): Promise<T | null>;
|
|
1707
|
+
/**
|
|
1708
|
+
* Smart representation - variant for images, preview for videos/PDFs.
|
|
1709
|
+
* Auto-enqueues generation if not ready.
|
|
1710
|
+
*/
|
|
1711
|
+
representation(transformations: ImageTransformations, expiresIn?: number): Promise<string | null>;
|
|
1712
|
+
/** Get blob's byte size. */
|
|
1713
|
+
byteSize(): Promise<number | null>;
|
|
1714
|
+
/** Get blob's content type. */
|
|
1715
|
+
contentType(): Promise<string | null>;
|
|
1716
|
+
/** Get blob's filename. */
|
|
1717
|
+
filename(): Promise<string | null>;
|
|
1718
|
+
/** Get signed, tamper-proof ID for the blob. */
|
|
1719
|
+
signedId(expiresIn?: number): Promise<string | null>;
|
|
1720
|
+
};
|
|
1721
|
+
/**
|
|
1722
|
+
* Get a multiple attachment handle (one-to-many relationship).
|
|
1723
|
+
* Similar to Rails' `has_many_attached :images`.
|
|
1724
|
+
*
|
|
1725
|
+
* Algorithm:
|
|
1726
|
+
* Returns an object with methods to manage multiple attachments:
|
|
1727
|
+
* - attach(): Add blobs (doesn't replace existing)
|
|
1728
|
+
* - list(): Get all attached blobs
|
|
1729
|
+
* - urls(): Get signed URLs for all
|
|
1730
|
+
* - variants(): Get/generate variants for all
|
|
1731
|
+
* - purge(): Delete all or specific attachment
|
|
1732
|
+
*
|
|
1733
|
+
* @template TTable - The table name (must be in TTableNames)
|
|
1734
|
+
*/
|
|
1735
|
+
many<TTable extends TTableNames>(recordType: TTable, recordId: string, name: AttachmentName<TAttachments, TTable>): {
|
|
1736
|
+
/**
|
|
1737
|
+
* Attach one or more blobs (adds to existing, doesn't replace).
|
|
1738
|
+
* Auto-triggers extractBlobMetadata for each blob.
|
|
1739
|
+
*/
|
|
1740
|
+
attach(blobIds: string | string[]): Promise<{
|
|
1741
|
+
id: string;
|
|
1742
|
+
createdAt: string;
|
|
1743
|
+
name: string;
|
|
1744
|
+
recordType: string;
|
|
1745
|
+
recordId: string;
|
|
1746
|
+
blobId: string;
|
|
1747
|
+
}[]>;
|
|
1748
|
+
/** Get all attached blobs. */
|
|
1749
|
+
list(): Promise<StorageBlob[]>;
|
|
1750
|
+
/** Count attached blobs. */
|
|
1751
|
+
count(): Promise<number>;
|
|
1752
|
+
/** Get signed URLs for all blobs. */
|
|
1753
|
+
urls(options?: {
|
|
1754
|
+
expiresIn?: number;
|
|
1755
|
+
}): Promise<string[]>;
|
|
1756
|
+
/** Get public URLs for all blobs. */
|
|
1757
|
+
publicUrls(): Promise<(string | null)[]>;
|
|
1758
|
+
/** Get metadata for all blobs. */
|
|
1759
|
+
metadata(): Promise<(Record<string, unknown> | null)[]>;
|
|
1760
|
+
/** Check which blobs have been analyzed. */
|
|
1761
|
+
analyzed(): Promise<boolean[]>;
|
|
1762
|
+
/** Check which blobs support preview/variants. */
|
|
1763
|
+
representable(): Promise<boolean[]>;
|
|
1764
|
+
/** Get variant URLs for all blobs. Auto-enqueues if not ready. */
|
|
1765
|
+
variants(transformations: ImageTransformations, expiresIn?: number): Promise<(string | null)[]>;
|
|
1766
|
+
/** Get preview URLs for all blobs. Auto-enqueues if not ready. */
|
|
1767
|
+
previews(expiresIn?: number, timeInSeconds?: number): Promise<(string | null)[]>;
|
|
1768
|
+
/** Detach specific blob or all blobs (keeps blobs for reuse). */
|
|
1769
|
+
detach(blobId?: string): Promise<number>;
|
|
1770
|
+
/** Delete specific or all attachments AND blobs immediately. */
|
|
1771
|
+
purge(blobId?: string): Promise<number>;
|
|
1772
|
+
/** Enqueue specific or all attachments for background deletion. */
|
|
1773
|
+
purgeLater(blobId?: string): Promise<number>;
|
|
1774
|
+
/** Download all blobs as Buffers. */
|
|
1775
|
+
download(): Promise<Buffer[]>;
|
|
1776
|
+
/** Download each blob to temp file, run callback for each. */
|
|
1777
|
+
open<T>(callback: (filePath: string, blob: StorageBlob) => Promise<T> | T): Promise<T[]>;
|
|
1778
|
+
/**
|
|
1779
|
+
* Smart representations - variant for images, preview for videos/PDFs.
|
|
1780
|
+
* Auto-enqueues generation if not ready.
|
|
1781
|
+
*/
|
|
1782
|
+
representations(transformations: ImageTransformations, expiresIn?: number): Promise<(string | null)[]>;
|
|
1783
|
+
/** Get byte sizes for all blobs. */
|
|
1784
|
+
byteSizes(): Promise<number[]>;
|
|
1785
|
+
/** Get content types for all blobs. */
|
|
1786
|
+
contentTypes(): Promise<(string | null)[]>;
|
|
1787
|
+
/** Get filenames for all blobs. */
|
|
1788
|
+
filenames(): Promise<string[]>;
|
|
1789
|
+
/** Get signed IDs for all blobs. */
|
|
1790
|
+
signedIds(expiresIn?: number): Promise<string[]>;
|
|
1791
|
+
};
|
|
1792
|
+
}
|
|
1793
|
+
//#endregion
|
|
1794
|
+
//#region src/api/container.d.ts
|
|
1795
|
+
/**
|
|
1796
|
+
* Server configuration for the HTTP server.
|
|
1797
|
+
*/
|
|
1798
|
+
interface ServerConfig {
|
|
1799
|
+
/**
|
|
1800
|
+
* The host address the server will bind to.
|
|
1801
|
+
*
|
|
1802
|
+
* @default "0.0.0.0"
|
|
1803
|
+
*/
|
|
1804
|
+
host?: string;
|
|
1805
|
+
/**
|
|
1806
|
+
* The port number the server will listen on.
|
|
1807
|
+
*/
|
|
1808
|
+
port: number;
|
|
1809
|
+
/**
|
|
1810
|
+
* Request timeout in milliseconds. Requests exceeding this duration
|
|
1811
|
+
* will receive a 408 Request Timeout response.
|
|
1812
|
+
*
|
|
1813
|
+
* @default 30000
|
|
1814
|
+
*/
|
|
1815
|
+
timeout?: number;
|
|
1816
|
+
/**
|
|
1817
|
+
* Maximum request body size for JSON and URL-encoded payloads.
|
|
1818
|
+
* Supports bytes.js format strings (e.g., "1mb", "500kb", "10mb").
|
|
1819
|
+
*
|
|
1820
|
+
* @default "1mb"
|
|
1821
|
+
*/
|
|
1822
|
+
bodyLimit?: string;
|
|
1823
|
+
/**
|
|
1824
|
+
* The path for the health check endpoint.
|
|
1825
|
+
*
|
|
1826
|
+
* @default "/health"
|
|
1827
|
+
*/
|
|
1828
|
+
healthPath?: string;
|
|
1829
|
+
/**
|
|
1830
|
+
* CORS configuration. Omit or set to undefined to disable.
|
|
1831
|
+
*
|
|
1832
|
+
* @example
|
|
1833
|
+
* cors: { origin: "https://example.com", credentials: true }
|
|
1834
|
+
*/
|
|
1835
|
+
cors?: CorsOptions;
|
|
1836
|
+
/**
|
|
1837
|
+
* Security headers configuration (via helmet). Omit or set to undefined to disable.
|
|
1838
|
+
* Recommended for production deployments.
|
|
1839
|
+
*
|
|
1840
|
+
* @example
|
|
1841
|
+
* helmet: { contentSecurityPolicy: false } // Enable with CSP disabled
|
|
1842
|
+
* helmet: {} // Enable with all defaults
|
|
1843
|
+
*/
|
|
1844
|
+
helmet?: HelmetOptions;
|
|
1845
|
+
/**
|
|
1846
|
+
* Rate limiting configuration. Array of express-rate-limit options.
|
|
1847
|
+
* Each config is applied as a separate middleware - use `skip` function for path-specific limits.
|
|
1848
|
+
* Redis store is automatically configured if `redisUrl` is provided.
|
|
1849
|
+
*
|
|
1850
|
+
* @example
|
|
1851
|
+
* // Global rate limit
|
|
1852
|
+
* rateLimit: [{ windowMs: 60000, limit: 100 }]
|
|
1853
|
+
*
|
|
1854
|
+
* @example
|
|
1855
|
+
* // Path-specific rate limits
|
|
1856
|
+
* rateLimit: [
|
|
1857
|
+
* { windowMs: 900000, limit: 5, skip: (req) => !req.path.startsWith("/api/auth") },
|
|
1858
|
+
* { windowMs: 60000, limit: 100 }, // Default for all other routes
|
|
1859
|
+
* ]
|
|
1860
|
+
*/
|
|
1861
|
+
rateLimit?: Options[];
|
|
1862
|
+
/**
|
|
1863
|
+
* Redis URL for rate limiting store (for multi-instance deployments).
|
|
1864
|
+
* Server auto-connects and cleans up on shutdown.
|
|
1865
|
+
* If omitted, uses in-memory store (not suitable for production clusters).
|
|
1866
|
+
*
|
|
1867
|
+
* @example
|
|
1868
|
+
* redisUrl: "redis://localhost:6379"
|
|
1869
|
+
*/
|
|
1870
|
+
redisUrl?: string;
|
|
1871
|
+
}
|
|
1872
|
+
/**
|
|
1873
|
+
* Worker configuration for the DBOS workflow worker.
|
|
1874
|
+
*/
|
|
1875
|
+
interface WorkerConfig {
|
|
1876
|
+
/**
|
|
1877
|
+
* The system database URL for DBOS.
|
|
1878
|
+
*/
|
|
1879
|
+
dbUrl: string;
|
|
1880
|
+
}
|
|
1881
|
+
/**
|
|
1882
|
+
* The base application container type that holds required services like
|
|
1883
|
+
* config, databases, and caches.
|
|
1884
|
+
*/
|
|
1885
|
+
interface AppContainer<TDb extends Record<"primary", Database> & Record<string, Database> = Record<"primary", Database> & Record<string, Database>> {
|
|
1886
|
+
/**
|
|
1887
|
+
* The application auth configuration.
|
|
1888
|
+
*/
|
|
1889
|
+
auth: Auth<TDb>;
|
|
1890
|
+
/**
|
|
1891
|
+
* A map of caches available in the application.
|
|
1892
|
+
*/
|
|
1893
|
+
cache: Record<string, Cache>;
|
|
1894
|
+
/**
|
|
1895
|
+
* The application configuration.
|
|
1896
|
+
*/
|
|
1897
|
+
config: Config;
|
|
1898
|
+
/**
|
|
1899
|
+
* A map of databases available in the application.
|
|
1900
|
+
*/
|
|
1901
|
+
db: TDb;
|
|
1902
|
+
/**
|
|
1903
|
+
* The i18n instance for internationalization.
|
|
1904
|
+
*/
|
|
1905
|
+
i18n: i18n;
|
|
1906
|
+
/**
|
|
1907
|
+
* The logger instance for logging messages.
|
|
1908
|
+
*/
|
|
1909
|
+
logger: Logger;
|
|
1910
|
+
/**
|
|
1911
|
+
* The event bus for in-memory and Redis pub/sub messaging.
|
|
1912
|
+
*/
|
|
1913
|
+
eventBus: EventBus;
|
|
1914
|
+
/**
|
|
1915
|
+
* The mailer instance for sending emails.
|
|
1916
|
+
*/
|
|
1917
|
+
mailer: Mailer;
|
|
1918
|
+
/**
|
|
1919
|
+
* Server configuration for the HTTP server.
|
|
1920
|
+
*/
|
|
1921
|
+
server: ServerConfig;
|
|
1922
|
+
/**
|
|
1923
|
+
* A map of storage services available in the application.
|
|
1924
|
+
*/
|
|
1925
|
+
storage: Record<"primary", Storage> & Record<string, Storage>;
|
|
1926
|
+
/**
|
|
1927
|
+
* Worker configuration for the DBOS workflow worker.
|
|
1928
|
+
*/
|
|
1929
|
+
worker: WorkerConfig;
|
|
1930
|
+
}
|
|
1931
|
+
/**
|
|
1932
|
+
* Global namespace for user container augmentation.
|
|
1933
|
+
* Users can extend Container interface in their container.ts file.
|
|
1934
|
+
*/
|
|
1935
|
+
declare global {
|
|
1936
|
+
namespace AppOS {
|
|
1937
|
+
interface Container {}
|
|
1938
|
+
}
|
|
1939
|
+
}
|
|
1940
|
+
/**
|
|
1941
|
+
* The container type used throughout the application.
|
|
1942
|
+
* Merges base AppContainer with user's custom Container augmentations.
|
|
1943
|
+
*/
|
|
1944
|
+
type Container = AppContainer & AppOS.Container;
|
|
1945
|
+
//#endregion
|
|
1946
|
+
//#region src/api/workflows/track-db-changes.d.ts
|
|
1947
|
+
/**
|
|
1948
|
+
* Input schema for trackDbChanges workflow.
|
|
1949
|
+
* Accepts dbChanges() output directly from .returning() clause.
|
|
1950
|
+
*/
|
|
1951
|
+
declare const trackDbChangesInputSchema: z.ZodObject<{
|
|
1952
|
+
changes: z.ZodArray<z.ZodObject<{
|
|
1953
|
+
_table: z.ZodString;
|
|
1954
|
+
old: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
1955
|
+
new: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
1956
|
+
}, z.core.$strip>>;
|
|
1957
|
+
dbName: z.ZodString;
|
|
1958
|
+
organizationId: z.ZodNullable<z.ZodString>;
|
|
1959
|
+
requestId: z.ZodString;
|
|
1960
|
+
sessionId: z.ZodNullable<z.ZodString>;
|
|
1961
|
+
userId: z.ZodNullable<z.ZodString>;
|
|
1962
|
+
}, z.core.$strip>;
|
|
1963
|
+
type TrackDbChangesInput = z.infer<typeof trackDbChangesInputSchema>;
|
|
1964
|
+
/**
|
|
1965
|
+
* Built-in workflow for processing database changes.
|
|
1966
|
+
* Handles audit logging and pub/sub notifications with type-safe table filtering.
|
|
1967
|
+
*
|
|
1968
|
+
* Algorithm:
|
|
1969
|
+
* 1. For each change in input, infer the action (INSERT/UPDATE/DELETE)
|
|
1970
|
+
* 2. If table is not excluded from audit logging:
|
|
1971
|
+
* - Insert into audit_logs table with full context
|
|
1972
|
+
* 3. Emit to dbChangesEvent (publishes via Redis if subscribed handlers exist)
|
|
1973
|
+
*
|
|
1974
|
+
* Filtering is configured via:
|
|
1975
|
+
* - `container.auth.shouldAudit()` - Check if table should be audited
|
|
1976
|
+
*
|
|
1977
|
+
* @returns Object with counts: processed (total changes), audited (logged to audit_logs), published (emitted to event)
|
|
1978
|
+
*/
|
|
1979
|
+
declare const trackDbChanges: {
|
|
1980
|
+
inputSchema: z.ZodObject<{
|
|
1981
|
+
changes: z.ZodArray<z.ZodObject<{
|
|
1982
|
+
_table: z.ZodString;
|
|
1983
|
+
old: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
1984
|
+
new: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
1985
|
+
}, z.core.$strip>>;
|
|
1986
|
+
dbName: z.ZodString;
|
|
1987
|
+
organizationId: z.ZodNullable<z.ZodString>;
|
|
1988
|
+
requestId: z.ZodString;
|
|
1989
|
+
sessionId: z.ZodNullable<z.ZodString>;
|
|
1990
|
+
userId: z.ZodNullable<z.ZodString>;
|
|
1991
|
+
}, z.core.$strip>;
|
|
1992
|
+
readonly name: string | null;
|
|
1993
|
+
register(c: Container, name: string, dbos: typeof _dbos_inc_dbos_sdk0.DBOS): void;
|
|
1994
|
+
start(input: {
|
|
1995
|
+
changes: {
|
|
1996
|
+
_table: string;
|
|
1997
|
+
old: Record<string, unknown> | null;
|
|
1998
|
+
new: Record<string, unknown> | null;
|
|
1999
|
+
}[];
|
|
2000
|
+
dbName: string;
|
|
2001
|
+
organizationId: string | null;
|
|
2002
|
+
requestId: string;
|
|
2003
|
+
sessionId: string | null;
|
|
2004
|
+
userId: string | null;
|
|
2005
|
+
}): Promise<WorkflowHandle<{
|
|
2006
|
+
processed: number;
|
|
2007
|
+
audited: number;
|
|
2008
|
+
published: number;
|
|
2009
|
+
}>>;
|
|
2010
|
+
};
|
|
2011
|
+
//#endregion
|
|
2
2012
|
export { TrackDbChangesInput, trackDbChanges };
|