appos 0.2.1-0 → 0.2.2-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/auth-schema-7KeUwlcd.mjs +2 -0
- package/dist/bin/concurrently.mjs +2 -0
- package/dist/bin/event-v2sCJkNd.mjs +2 -0
- package/dist/bin/extract-blob-metadata-TqNd9w-6.mjs +2 -0
- package/dist/bin/generate-image-variant-D8H9FxgD.mjs +2 -0
- package/dist/bin/generate-preview-5jLZLX6I.mjs +2 -0
- package/dist/bin/main.mjs +362 -0
- package/dist/bin/purge-attachment-CMlJMNOk.mjs +2 -0
- package/dist/bin/purge-audit-logs-hd6q6vnR.mjs +2 -0
- package/dist/bin/purge-unattached-blobs-BYv5b9R9.mjs +2 -0
- package/dist/bin/track-db-changes-q0Vl7Htm.mjs +2 -0
- package/dist/bin/vite.mjs +2 -0
- package/dist/bin/vitest.mjs +2 -0
- package/dist/bin/workflow-BagSlsMp.mjs +2 -0
- package/dist/bin/youch-handler-Jj6i1XIT.mjs +2 -0
- package/dist/exports/api/_virtual/rolldown_runtime.mjs +1 -0
- package/dist/exports/api/app-context.d.mts +115 -0
- package/dist/exports/api/app-context.mjs +1 -0
- package/dist/exports/api/auth-schema.d.mts +4248 -0
- package/dist/exports/api/auth-schema.mjs +1 -0
- package/dist/exports/api/auth.d.mts +398 -0
- package/dist/exports/api/auth.mjs +1 -0
- package/dist/exports/api/cache.d.mts +44 -0
- package/dist/exports/api/cache.mjs +1 -0
- package/dist/exports/api/config.d.mts +28 -0
- package/dist/exports/api/config.mjs +1 -0
- package/dist/exports/api/container.d.mts +210 -0
- package/dist/exports/api/container.mjs +1 -0
- package/dist/exports/api/database.d.mts +99 -0
- package/dist/exports/api/database.mjs +1 -0
- package/dist/exports/api/event.d.mts +235 -0
- package/dist/exports/api/event.mjs +1 -0
- package/dist/exports/api/i18n.d.mts +34 -0
- package/dist/exports/api/i18n.mjs +1 -0
- package/dist/exports/api/index.d.mts +21 -0
- package/dist/exports/api/index.mjs +1 -0
- package/dist/exports/api/logger.d.mts +21 -0
- package/dist/exports/api/logger.mjs +1 -0
- package/dist/exports/api/mailer.d.mts +70 -0
- package/dist/exports/api/mailer.mjs +1 -0
- package/dist/exports/api/middleware/request-logger.d.mts +24 -0
- package/dist/exports/api/middleware.d.mts +39 -0
- package/dist/exports/api/middleware.mjs +1 -0
- package/dist/exports/api/node_modules/.bun/change-case@5.4.4/node_modules/change-case/dist/index.mjs +1 -0
- package/dist/exports/api/openapi.d.mts +271 -0
- package/dist/exports/api/openapi.mjs +1 -0
- package/dist/exports/api/orm.d.mts +13 -0
- package/dist/exports/api/orm.mjs +1 -0
- package/dist/exports/api/otel.d.mts +40 -0
- package/dist/exports/api/otel.mjs +1 -0
- package/dist/exports/api/packages/appos/src/constants.mjs +1 -0
- package/dist/exports/api/packages/appos/src/instrumentation.d.mts +7 -0
- package/dist/exports/api/packages/appos/src/instrumentation.mjs +1 -0
- package/dist/exports/api/packages/appos/src/web/auth.mjs +1 -0
- package/dist/exports/api/redis.d.mts +34 -0
- package/dist/exports/api/redis.mjs +1 -0
- package/dist/exports/api/storage-schema.d.mts +707 -0
- package/dist/exports/api/storage-schema.mjs +1 -0
- package/dist/exports/api/storage.d.mts +506 -0
- package/dist/exports/api/storage.mjs +1 -0
- package/dist/exports/api/workflow.d.mts +250 -0
- package/dist/exports/api/workflow.mjs +1 -0
- package/dist/exports/api/workflows/_virtual/rolldown_runtime.mjs +1 -0
- package/dist/exports/api/workflows/auth-schema.mjs +1 -0
- package/dist/exports/api/workflows/auth.d.mts +375 -0
- package/dist/exports/api/workflows/cache.d.mts +44 -0
- package/dist/exports/api/workflows/config.d.mts +18 -0
- package/dist/exports/api/workflows/container.d.mts +167 -0
- package/dist/exports/api/workflows/database.d.mts +46 -0
- package/dist/exports/api/workflows/event.d.mts +68 -0
- package/dist/exports/api/workflows/event.mjs +1 -0
- package/dist/exports/api/workflows/extract-blob-metadata.mjs +1 -0
- package/dist/exports/api/workflows/generate-image-variant.d.mts +99 -0
- package/dist/exports/api/workflows/generate-image-variant.mjs +1 -0
- package/dist/exports/api/workflows/generate-preview.mjs +1 -0
- package/dist/exports/api/workflows/index.d.mts +2 -0
- package/dist/exports/api/workflows/index.mjs +1 -0
- package/dist/exports/api/workflows/logger.d.mts +21 -0
- package/dist/exports/api/workflows/mailer.d.mts +70 -0
- package/dist/exports/api/workflows/orm.d.mts +13 -0
- package/dist/exports/api/workflows/purge-attachment.mjs +1 -0
- package/dist/exports/api/workflows/purge-audit-logs.mjs +1 -0
- package/dist/exports/api/workflows/purge-unattached-blobs.mjs +1 -0
- package/dist/exports/api/workflows/redis.mjs +1 -0
- package/dist/exports/api/workflows/storage-schema.d.mts +699 -0
- package/dist/exports/api/workflows/storage.d.mts +396 -0
- package/dist/exports/api/workflows/track-db-changes.d.mts +72 -0
- package/dist/exports/api/workflows/track-db-changes.mjs +1 -0
- package/dist/exports/api/workflows/workflow.d.mts +24 -0
- package/dist/exports/api/workflows/workflow.mjs +1 -0
- package/dist/exports/cli/_virtual/rolldown_runtime.mjs +1 -0
- package/dist/exports/cli/api/auth-schema.mjs +1 -0
- package/dist/exports/cli/api/auth.d.mts +375 -0
- package/dist/exports/cli/api/cache.d.mts +44 -0
- package/dist/exports/cli/api/config.d.mts +18 -0
- package/dist/exports/cli/api/container.d.mts +167 -0
- package/dist/exports/cli/api/database.d.mts +46 -0
- package/dist/exports/cli/api/event.d.mts +68 -0
- package/dist/exports/cli/api/event.mjs +1 -0
- package/dist/exports/cli/api/logger.d.mts +21 -0
- package/dist/exports/cli/api/mailer.d.mts +70 -0
- package/dist/exports/cli/api/orm.d.mts +13 -0
- package/dist/exports/cli/api/redis.mjs +1 -0
- package/dist/exports/cli/api/storage-schema.d.mts +699 -0
- package/dist/exports/cli/api/storage.d.mts +396 -0
- package/dist/exports/cli/api/workflow.d.mts +2 -0
- package/dist/exports/cli/api/workflow.mjs +1 -0
- package/dist/exports/cli/api/workflows/extract-blob-metadata.mjs +1 -0
- package/dist/exports/cli/api/workflows/generate-image-variant.d.mts +63 -0
- package/dist/exports/cli/api/workflows/generate-image-variant.mjs +1 -0
- package/dist/exports/cli/api/workflows/generate-preview.mjs +1 -0
- package/dist/exports/cli/api/workflows/purge-attachment.mjs +1 -0
- package/dist/exports/cli/api/workflows/purge-audit-logs.mjs +1 -0
- package/dist/exports/cli/api/workflows/purge-unattached-blobs.mjs +1 -0
- package/dist/exports/cli/api/workflows/track-db-changes.mjs +1 -0
- package/dist/exports/cli/command.d.mts +54 -0
- package/dist/exports/cli/command.mjs +1 -0
- package/dist/exports/cli/context.d.mts +170 -0
- package/dist/exports/cli/index.d.mts +3 -0
- package/dist/exports/cli/index.mjs +1 -0
- package/dist/exports/devtools/index.d.ts +3 -0
- package/dist/exports/devtools/index.js +1 -0
- package/dist/exports/instrumentation.d.mts +1 -0
- package/dist/exports/instrumentation.mjs +1 -0
- package/dist/exports/tests/_virtual/rolldown_runtime.mjs +1 -0
- package/dist/exports/tests/api.d.mts +86 -0
- package/dist/exports/tests/api.mjs +1 -0
- package/dist/exports/tests/mock.d.mts +1 -0
- package/dist/exports/tests/mock.mjs +1 -0
- package/dist/exports/tests/node_modules/.bun/change-case@5.4.4/node_modules/change-case/dist/index.mjs +1 -0
- package/dist/exports/tests/node_modules/.bun/rate-limit-redis@4.3.1_f1fa5524233c9c60/node_modules/rate-limit-redis/dist/index.mjs +25 -0
- package/dist/exports/tests/packages/appos/src/api/app-context.d.mts +115 -0
- package/dist/exports/tests/packages/appos/src/api/auth-schema.d.mts +4248 -0
- package/dist/exports/tests/packages/appos/src/api/auth-schema.mjs +1 -0
- package/dist/exports/tests/packages/appos/src/api/auth.d.mts +398 -0
- package/dist/exports/tests/packages/appos/src/api/cache.d.mts +44 -0
- package/dist/exports/tests/packages/appos/src/api/config.d.mts +28 -0
- package/dist/exports/tests/packages/appos/src/api/container.d.mts +210 -0
- package/dist/exports/tests/packages/appos/src/api/database.d.mts +99 -0
- package/dist/exports/tests/packages/appos/src/api/database.mjs +1 -0
- package/dist/exports/tests/packages/appos/src/api/event.d.mts +235 -0
- package/dist/exports/tests/packages/appos/src/api/event.mjs +1 -0
- package/dist/exports/tests/packages/appos/src/api/i18n.d.mts +34 -0
- package/dist/exports/tests/packages/appos/src/api/index.d.mts +27 -0
- package/dist/exports/tests/packages/appos/src/api/logger.d.mts +21 -0
- package/dist/exports/tests/packages/appos/src/api/mailer.d.mts +70 -0
- package/dist/exports/tests/packages/appos/src/api/middleware/error-handler.mjs +1 -0
- package/dist/exports/tests/packages/appos/src/api/middleware/health.mjs +1 -0
- package/dist/exports/tests/packages/appos/src/api/middleware/i18n.mjs +1 -0
- package/dist/exports/tests/packages/appos/src/api/middleware/request-logger.d.mts +24 -0
- package/dist/exports/tests/packages/appos/src/api/middleware/request-logger.mjs +1 -0
- package/dist/exports/tests/packages/appos/src/api/middleware/shutdown.mjs +1 -0
- package/dist/exports/tests/packages/appos/src/api/middleware/timeout.mjs +1 -0
- package/dist/exports/tests/packages/appos/src/api/middleware/youch-handler.mjs +1 -0
- package/dist/exports/tests/packages/appos/src/api/middleware.d.mts +39 -0
- package/dist/exports/tests/packages/appos/src/api/middleware.mjs +1 -0
- package/dist/exports/tests/packages/appos/src/api/openapi.d.mts +271 -0
- package/dist/exports/tests/packages/appos/src/api/orm.d.mts +13 -0
- package/dist/exports/tests/packages/appos/src/api/otel.d.mts +40 -0
- package/dist/exports/tests/packages/appos/src/api/redis.d.mts +34 -0
- package/dist/exports/tests/packages/appos/src/api/redis.mjs +1 -0
- package/dist/exports/tests/packages/appos/src/api/server.mjs +1 -0
- package/dist/exports/tests/packages/appos/src/api/storage-schema.d.mts +707 -0
- package/dist/exports/tests/packages/appos/src/api/storage.d.mts +506 -0
- package/dist/exports/tests/packages/appos/src/api/workflow.d.mts +250 -0
- package/dist/exports/tests/packages/appos/src/api/workflow.mjs +1 -0
- package/dist/exports/tests/packages/appos/src/api/workflows/extract-blob-metadata.mjs +1 -0
- package/dist/exports/tests/packages/appos/src/api/workflows/generate-image-variant.d.mts +99 -0
- package/dist/exports/tests/packages/appos/src/api/workflows/generate-image-variant.mjs +1 -0
- package/dist/exports/tests/packages/appos/src/api/workflows/generate-preview.mjs +1 -0
- package/dist/exports/tests/packages/appos/src/api/workflows/purge-attachment.mjs +1 -0
- package/dist/exports/tests/packages/appos/src/api/workflows/purge-audit-logs.mjs +1 -0
- package/dist/exports/tests/packages/appos/src/api/workflows/purge-unattached-blobs.mjs +1 -0
- package/dist/exports/tests/packages/appos/src/api/workflows/track-db-changes.mjs +1 -0
- package/dist/exports/tests/packages/appos/src/constants.mjs +1 -0
- package/dist/exports/tests/packages/appos/src/instrumentation.d.mts +7 -0
- package/dist/exports/tests/packages/appos/src/instrumentation.mjs +1 -0
- package/dist/exports/tests/react.d.mts +2 -0
- package/dist/exports/tests/react.mjs +1 -0
- package/dist/exports/tests/setup.d.mts +1 -0
- package/dist/exports/tests/setup.mjs +1 -0
- package/dist/exports/vendors/date.js +1 -0
- package/dist/exports/vendors/toolkit.js +1 -0
- package/dist/exports/vendors/zod.d.ts +1 -0
- package/dist/exports/vendors/zod.js +1 -0
- package/dist/exports/vite/index.d.mts +19 -0
- package/dist/exports/vite/index.mjs +1 -0
- package/dist/exports/vitest/config.d.mts +1 -0
- package/dist/exports/vitest/config.mjs +1 -0
- package/dist/exports/vitest/globals.d.mts +1 -0
- package/dist/exports/vitest/globals.mjs +1 -0
- package/dist/exports/vitest/index.d.mts +1 -0
- package/dist/exports/vitest/index.mjs +1 -0
- package/dist/exports/web/api/auth.d.ts +125 -0
- package/dist/exports/web/api/database.d.ts +4 -0
- package/dist/exports/web/api/logger.d.ts +1 -0
- package/dist/exports/web/auth.d.ts +2388 -0
- package/dist/exports/web/auth.js +1 -0
- package/dist/exports/web/i18n.d.ts +42 -0
- package/dist/exports/web/i18n.js +1 -0
- package/dist/exports/web/index.d.ts +6 -0
- package/dist/exports/web/index.js +1 -0
- package/package.json +138 -98
- package/build/bin/main.mjs +0 -2
- package/build/exports/cli/index.d.mts +0 -325
- package/build/exports/cli/index.mjs +0 -1
- package/build/exports/instrumentation/execAsync-DaIUcs6_.mjs +0 -1
- package/build/exports/instrumentation/getMachineId-bsd-bB6ipDhm.mjs +0 -1
- package/build/exports/instrumentation/getMachineId-darwin-D1Bx5aCe.mjs +0 -2
- package/build/exports/instrumentation/getMachineId-linux-D_R9Tla0.mjs +0 -1
- package/build/exports/instrumentation/getMachineId-unsupported-BZKPE_Ev.mjs +0 -1
- package/build/exports/instrumentation/getMachineId-win-CmPvIqHL.mjs +0 -1
- package/build/exports/instrumentation/instrumentation.d.mts +0 -1
- package/build/exports/instrumentation/instrumentation.mjs +0 -80
- package/build/exports/server/index.d.mts +0 -327
- package/build/exports/server/index.mjs +0 -219
- package/build/exports/server/react-gPO8Jsy-.mjs +0 -13
- package/build/exports/server/server.node-D_9RYjm9.mjs +0 -210
- package/build/exports/store/index.d.mts +0 -58
- package/build/exports/store/index.mjs +0 -15
- package/build/exports/support/datetime.js +0 -1
- package/build/exports/support/utils.js +0 -1
- package/build/exports/support/zod.d.ts +0 -2
- package/build/exports/support/zod.js +0 -23
- package/build/exports/test/dist-DAsoCGWk.mjs +0 -348
- package/build/exports/test/index.d.mts +0 -3
- package/build/exports/test/index.mjs +0 -1
- package/build/exports/test/magic-string.es-BWgiB2kd.mjs +0 -14
- package/build/exports/test/setup.d.mts +0 -1
- package/build/exports/test/setup.mjs +0 -329
- /package/{build/exports/support/datetime.d.ts → dist/exports/vendors/date.d.ts} +0 -0
- /package/{build/exports/support/utils.d.ts → dist/exports/vendors/toolkit.d.ts} +0 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
//#region src/api/config.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The config base schema.
|
|
7
|
+
*/
|
|
8
|
+
declare const baseSchema: z.ZodObject<{
|
|
9
|
+
APP_NAME: z.ZodDefault<z.ZodString>;
|
|
10
|
+
APP_DESC: z.ZodDefault<z.ZodString>;
|
|
11
|
+
APP_VERSION: z.ZodDefault<z.ZodString>;
|
|
12
|
+
}, z.core.$strip>;
|
|
13
|
+
/**
|
|
14
|
+
* The configuration type inferred from the merged schema.
|
|
15
|
+
*/
|
|
16
|
+
type Config<T extends z.ZodRawShape = {}> = z.infer<ReturnType<typeof baseSchema.extend<T>>>;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { Config };
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { Logger } from "./logger.mjs";
|
|
2
|
+
import { Database } from "./database.mjs";
|
|
3
|
+
import { Auth } from "./auth.mjs";
|
|
4
|
+
import { Cache } from "./cache.mjs";
|
|
5
|
+
import { Config } from "./config.mjs";
|
|
6
|
+
import { EventBus } from "./event.mjs";
|
|
7
|
+
import { Mailer } from "./mailer.mjs";
|
|
8
|
+
import { Storage } from "./storage.mjs";
|
|
9
|
+
import { CorsOptions } from "cors";
|
|
10
|
+
import { Options } from "express-rate-limit";
|
|
11
|
+
import { HelmetOptions } from "helmet";
|
|
12
|
+
import { i18n } from "i18next";
|
|
13
|
+
|
|
14
|
+
//#region src/api/container.d.ts
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Server configuration for the HTTP server.
|
|
18
|
+
*/
|
|
19
|
+
interface ServerConfig {
|
|
20
|
+
/**
|
|
21
|
+
* The host address the server will bind to.
|
|
22
|
+
*
|
|
23
|
+
* @default "0.0.0.0"
|
|
24
|
+
*/
|
|
25
|
+
host?: string;
|
|
26
|
+
/**
|
|
27
|
+
* The port number the server will listen on.
|
|
28
|
+
*/
|
|
29
|
+
port: number;
|
|
30
|
+
/**
|
|
31
|
+
* Request timeout in milliseconds. Requests exceeding this duration
|
|
32
|
+
* will receive a 408 Request Timeout response.
|
|
33
|
+
*
|
|
34
|
+
* @default 30000
|
|
35
|
+
*/
|
|
36
|
+
timeout?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Maximum request body size for JSON and URL-encoded payloads.
|
|
39
|
+
* Supports bytes.js format strings (e.g., "1mb", "500kb", "10mb").
|
|
40
|
+
*
|
|
41
|
+
* @default "1mb"
|
|
42
|
+
*/
|
|
43
|
+
bodyLimit?: string;
|
|
44
|
+
/**
|
|
45
|
+
* The path for the health check endpoint.
|
|
46
|
+
*
|
|
47
|
+
* @default "/health"
|
|
48
|
+
*/
|
|
49
|
+
healthPath?: string;
|
|
50
|
+
/**
|
|
51
|
+
* CORS configuration. Omit or set to undefined to disable.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* cors: { origin: "https://example.com", credentials: true }
|
|
55
|
+
*/
|
|
56
|
+
cors?: CorsOptions;
|
|
57
|
+
/**
|
|
58
|
+
* Security headers configuration (via helmet). Omit or set to undefined to disable.
|
|
59
|
+
* Recommended for production deployments.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* helmet: { contentSecurityPolicy: false } // Enable with CSP disabled
|
|
63
|
+
* helmet: {} // Enable with all defaults
|
|
64
|
+
*/
|
|
65
|
+
helmet?: HelmetOptions;
|
|
66
|
+
/**
|
|
67
|
+
* Rate limiting configuration. Array of express-rate-limit options.
|
|
68
|
+
* Each config is applied as a separate middleware - use `skip` function for path-specific limits.
|
|
69
|
+
* Redis store is automatically configured if `redisUrl` is provided.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* // Global rate limit
|
|
73
|
+
* rateLimit: [{ windowMs: 60000, limit: 100 }]
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* // Path-specific rate limits
|
|
77
|
+
* rateLimit: [
|
|
78
|
+
* { windowMs: 900000, limit: 5, skip: (req) => !req.path.startsWith("/api/auth") },
|
|
79
|
+
* { windowMs: 60000, limit: 100 }, // Default for all other routes
|
|
80
|
+
* ]
|
|
81
|
+
*/
|
|
82
|
+
rateLimit?: Options[];
|
|
83
|
+
/**
|
|
84
|
+
* Redis URL for rate limiting store (for multi-instance deployments).
|
|
85
|
+
* Server auto-connects and cleans up on shutdown.
|
|
86
|
+
* If omitted, uses in-memory store (not suitable for production clusters).
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* redisUrl: "redis://localhost:6379"
|
|
90
|
+
*/
|
|
91
|
+
redisUrl?: string;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Worker configuration for the DBOS workflow worker.
|
|
95
|
+
*/
|
|
96
|
+
interface WorkerConfig {
|
|
97
|
+
/**
|
|
98
|
+
* The system database URL for DBOS.
|
|
99
|
+
*/
|
|
100
|
+
dbUrl: string;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* The base application container type that holds required services like
|
|
104
|
+
* config, databases, and caches.
|
|
105
|
+
*/
|
|
106
|
+
interface AppContainer<TDb extends Record<"primary", Database> & Record<string, Database> = Record<"primary", Database> & Record<string, Database>> {
|
|
107
|
+
/**
|
|
108
|
+
* The application auth configuration.
|
|
109
|
+
*/
|
|
110
|
+
auth: Auth<TDb>;
|
|
111
|
+
/**
|
|
112
|
+
* A map of caches available in the application.
|
|
113
|
+
*/
|
|
114
|
+
cache: Record<string, Cache>;
|
|
115
|
+
/**
|
|
116
|
+
* The application configuration.
|
|
117
|
+
*/
|
|
118
|
+
config: Config;
|
|
119
|
+
/**
|
|
120
|
+
* A map of databases available in the application.
|
|
121
|
+
*/
|
|
122
|
+
db: TDb;
|
|
123
|
+
/**
|
|
124
|
+
* The i18n instance for internationalization.
|
|
125
|
+
*/
|
|
126
|
+
i18n: i18n;
|
|
127
|
+
/**
|
|
128
|
+
* The logger instance for logging messages.
|
|
129
|
+
*/
|
|
130
|
+
logger: Logger;
|
|
131
|
+
/**
|
|
132
|
+
* The event bus for in-memory and Redis pub/sub messaging.
|
|
133
|
+
*/
|
|
134
|
+
eventBus: EventBus;
|
|
135
|
+
/**
|
|
136
|
+
* The mailer instance for sending emails.
|
|
137
|
+
*/
|
|
138
|
+
mailer: Mailer;
|
|
139
|
+
/**
|
|
140
|
+
* Server configuration for the HTTP server.
|
|
141
|
+
*/
|
|
142
|
+
server: ServerConfig;
|
|
143
|
+
/**
|
|
144
|
+
* A map of storage services available in the application.
|
|
145
|
+
*/
|
|
146
|
+
storage: Record<"primary", Storage> & Record<string, Storage>;
|
|
147
|
+
/**
|
|
148
|
+
* Worker configuration for the DBOS workflow worker.
|
|
149
|
+
*/
|
|
150
|
+
worker: WorkerConfig;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Global namespace for user container augmentation.
|
|
154
|
+
* Users can extend Container interface in their container.ts file.
|
|
155
|
+
*/
|
|
156
|
+
declare global {
|
|
157
|
+
namespace AppOS {
|
|
158
|
+
interface Container {}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* The container type used throughout the application.
|
|
163
|
+
* Merges base AppContainer with user's custom Container augmentations.
|
|
164
|
+
*/
|
|
165
|
+
type Container = AppContainer & AppOS.Container;
|
|
166
|
+
//#endregion
|
|
167
|
+
export { Container };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Logger } from "./logger.mjs";
|
|
2
|
+
import { AnyRelations, EmptyRelations } from "drizzle-orm";
|
|
3
|
+
import "drizzle-orm/pg-core";
|
|
4
|
+
import * as drizzle_orm_node_postgres0 from "drizzle-orm/node-postgres";
|
|
5
|
+
import { Pool, PoolConfig } from "pg";
|
|
6
|
+
|
|
7
|
+
//#region src/api/database.d.ts
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Extract qualified table names from db object.
|
|
11
|
+
*/
|
|
12
|
+
type QualifiedTableNames<TDb> = { [K in keyof TDb]: TDb[K] extends {
|
|
13
|
+
_: {
|
|
14
|
+
fullSchema: infer S;
|
|
15
|
+
};
|
|
16
|
+
} ? `${K & string}.${keyof S & string}` : never }[keyof TDb];
|
|
17
|
+
/**
|
|
18
|
+
* Options for defining the database.
|
|
19
|
+
*/
|
|
20
|
+
interface DefineDatabaseOptions<TSchema extends Record<string, unknown> = Record<string, never>, TRelations extends AnyRelations = EmptyRelations> {
|
|
21
|
+
logger: Logger;
|
|
22
|
+
poolConfig: PoolConfig;
|
|
23
|
+
relations?: TRelations;
|
|
24
|
+
schema?: TSchema;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The database type.
|
|
28
|
+
*/
|
|
29
|
+
type Database = Awaited<ReturnType<typeof defineDatabase>>;
|
|
30
|
+
/**
|
|
31
|
+
* Define the database with the provided options.
|
|
32
|
+
*
|
|
33
|
+
* Algorithm:
|
|
34
|
+
* 1. Create a connection pool with sensible defaults
|
|
35
|
+
* 2. Initialize drizzle ORM with schema and relations
|
|
36
|
+
*
|
|
37
|
+
* @param opts The options for defining the database, including pool configuration, relations, and schema.
|
|
38
|
+
* @template TSchema The schema type for the database.
|
|
39
|
+
* @template TRelations The relations type for the database.
|
|
40
|
+
* @returns The defined database instance.
|
|
41
|
+
*/
|
|
42
|
+
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> & {
|
|
43
|
+
$client: Pool;
|
|
44
|
+
}>;
|
|
45
|
+
//#endregion
|
|
46
|
+
export { Database, QualifiedTableNames };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Logger } from "./logger.mjs";
|
|
2
|
+
import "./container.mjs";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
//#region src/api/event.d.ts
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Options for defining an event bus.
|
|
9
|
+
*/
|
|
10
|
+
interface DefineEventBusOptions {
|
|
11
|
+
/**
|
|
12
|
+
* Redis URL for pub/sub.
|
|
13
|
+
*/
|
|
14
|
+
dbUrl: string;
|
|
15
|
+
/**
|
|
16
|
+
* Logger instance for error reporting.
|
|
17
|
+
*/
|
|
18
|
+
logger: Logger;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The event bus type for container.
|
|
22
|
+
*/
|
|
23
|
+
type EventBus = ReturnType<typeof defineEventBus>;
|
|
24
|
+
/**
|
|
25
|
+
* Defines the event bus for pub/sub messaging.
|
|
26
|
+
* Uses Redis for cross-server communication.
|
|
27
|
+
*
|
|
28
|
+
* Algorithm:
|
|
29
|
+
* 1. Create lazy Redis publisher client
|
|
30
|
+
* 2. Create lazy Redis subscriber client
|
|
31
|
+
* 3. Manage subscriptions via callback registry
|
|
32
|
+
* 4. Provide publish/subscribe/close methods
|
|
33
|
+
*
|
|
34
|
+
* @param opts - Event bus configuration
|
|
35
|
+
* @returns Event bus instance
|
|
36
|
+
*/
|
|
37
|
+
declare function defineEventBus(opts: DefineEventBusOptions): {
|
|
38
|
+
/**
|
|
39
|
+
* Publish a message to a channel.
|
|
40
|
+
* Auto-connects on first call if not already connected.
|
|
41
|
+
*
|
|
42
|
+
* @param channel - Channel name
|
|
43
|
+
* @param message - Message payload (will be JSON stringified)
|
|
44
|
+
*/
|
|
45
|
+
publish(channel: string, message: unknown): Promise<void>;
|
|
46
|
+
/**
|
|
47
|
+
* Subscribe to a channel. Returns unsubscribe function.
|
|
48
|
+
* Uses single connection with callback management.
|
|
49
|
+
*
|
|
50
|
+
* @param channel - Channel name
|
|
51
|
+
* @param callback - Callback for received messages
|
|
52
|
+
* @returns Unsubscribe function
|
|
53
|
+
*/
|
|
54
|
+
subscribe(channel: string, callback: (message: unknown) => void): Promise<() => void>;
|
|
55
|
+
/**
|
|
56
|
+
* Check if a channel has any subscribers.
|
|
57
|
+
*
|
|
58
|
+
* @param channel - Channel name
|
|
59
|
+
* @returns true if channel has subscribers
|
|
60
|
+
*/
|
|
61
|
+
hasSubscribers(channel: string): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Close the Redis connections.
|
|
64
|
+
*/
|
|
65
|
+
close(): Promise<void>;
|
|
66
|
+
};
|
|
67
|
+
//#endregion
|
|
68
|
+
export { EventBus };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"./redis.mjs";import{z as e}from"zod";import{join as t}from"node:path";import"es-toolkit";function n(e){let t=null,n=null;return{inputSchema:e.input,get name(){return n},register(e,r){t=e,n=r},async emit(r){if(!t||!n)throw Error(`Event not registered. Ensure the worker is started before emitting events.`);let i=e.input.parse(r),a={container:t,input:i};await e.run(a),t.eventBus.publish(n,i).catch(e=>{t.logger.error({err:e,event:n},`Redis publish failed`)})},async subscribe(r){if(!t||!n)throw Error(`Event not registered. Ensure the worker is started before subscribing.`);return t.eventBus.subscribe(n,async i=>{let a=e.input.parse(i),o={container:t,input:a};try{await r(o)}catch(e){t.logger.error({err:e,event:n},`Event subscription handler error`)}})}}}const r=n({input:e.object({action:e.enum([`INSERT`,`UPDATE`,`DELETE`]),newData:e.record(e.string(),e.unknown()).nullable(),oldData:e.record(e.string(),e.unknown()).nullable(),organizationId:e.string().nullable(),tableName:e.string(),timestamp:e.string(),userId:e.string().nullable()}),async run(){}});export{r as dbChangesEvent};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{defineWorkflow as e}from"../workflow.mjs";import t from"zod";import{join as n}from"node:path";import{ALL_FORMATS as r,BlobSource as i,Input as a}from"mediabunny";import o from"sharp";const s=e({input:t.object({blobId:t.string()}),async run({container:e,input:{blobId:t},step:s}){let c=await s(`fetch-blob`,async()=>e.storage.primary.getBlob(t));if(!c)throw Error(`Blob ${t} not found`);let l=await s(`download-blob`,async()=>e.storage.primary.downloadBlob(t));if(!l)throw Error(`Failed to download blob ${t}`);let u={};return c.contentType?.startsWith(`image/`)?u=await s(`extract-image-metadata`,async()=>{let e=await o(l).metadata();return{width:e.width,height:e.height,format:e.format,hasAlpha:e.hasAlpha,space:e.space}}):c.contentType?.startsWith(`video/`)||c.contentType?.startsWith(`audio/`)?u=await s(`extract-media-metadata`,async()=>{let e=new Uint8Array(l),t=new a({source:new i(new Blob([e],{type:c.contentType||`video/mp4`})),formats:r}),n=await t.computeDuration(),o=await t.getMetadataTags(),s={},u={},d=!1,f=!1;try{let e=await t.getPrimaryVideoTrack();if(e){d=!0;let t=e.displayWidth&&e.displayHeight?e.displayWidth/e.displayHeight:null;s={width:e.displayWidth,height:e.displayHeight,rotation:e.rotation,angle:e.rotation,displayAspectRatio:t}}}catch{}try{let e=await t.getPrimaryAudioTrack();e&&(f=!0,u={sampleRate:e.sampleRate,channels:e.numberOfChannels})}catch{}return{duration:n,video:d,audio:f,...s,...u,tags:o}}):c.contentType===`application/pdf`&&(u=await s(`extract-pdf-metadata`,async()=>{try{let e=await import(`pdfjs-dist/legacy/build/pdf.mjs`),t=`${n(process.cwd(),`node_modules/pdfjs-dist/standard_fonts`)}/`,r=await e.getDocument({data:new Uint8Array(l),standardFontDataUrl:t}).promise,i=await r.getMetadata(),a=(await r.getPage(1)).getViewport({scale:1}),o=i.info;return{pageCount:r.numPages,width:a.width,height:a.height,title:o?.Title||null,author:o?.Author||null,subject:o?.Subject||null,keywords:o?.Keywords||null,creator:o?.Creator||null,producer:o?.Producer||null,creationDate:o?.CreationDate||null,modificationDate:o?.ModDate||null,pdfVersion:o?.PDFFormatVersion||null}}catch(n){return e.logger.error({error:n,errorMessage:n instanceof Error?n.message:String(n),errorStack:n instanceof Error?n.stack:void 0,errorCode:n?.code,blobId:t},`Failed to extract PDF metadata`),{error:`Failed to extract PDF metadata`,errorMessage:n instanceof Error?n.message:String(n)}}})),await s(`save-metadata`,async()=>{await e.storage.primary.updateBlobMetadata(t,{...u,analyzed:!0})}),e.logger.info({blobId:t,metadata:u},`Metadata extracted`),{...u,analyzed:!0}}});export{s as extractBlobMetadata};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import "../workflow.mjs";
|
|
2
|
+
import "../index.mjs";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
//#region src/api/workflows/generate-image-variant.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Resize options schema for image transformations.
|
|
8
|
+
*/
|
|
9
|
+
declare const resizeSchema: z.ZodObject<{
|
|
10
|
+
width: z.ZodOptional<z.ZodNumber>;
|
|
11
|
+
height: z.ZodOptional<z.ZodNumber>;
|
|
12
|
+
fit: z.ZodOptional<z.ZodEnum<{
|
|
13
|
+
fill: "fill";
|
|
14
|
+
cover: "cover";
|
|
15
|
+
contain: "contain";
|
|
16
|
+
inside: "inside";
|
|
17
|
+
outside: "outside";
|
|
18
|
+
}>>;
|
|
19
|
+
position: z.ZodOptional<z.ZodEnum<{
|
|
20
|
+
left: "left";
|
|
21
|
+
right: "right";
|
|
22
|
+
top: "top";
|
|
23
|
+
"right top": "right top";
|
|
24
|
+
"right bottom": "right bottom";
|
|
25
|
+
bottom: "bottom";
|
|
26
|
+
"left bottom": "left bottom";
|
|
27
|
+
"left top": "left top";
|
|
28
|
+
centre: "centre";
|
|
29
|
+
}>>;
|
|
30
|
+
kernel: z.ZodOptional<z.ZodEnum<{
|
|
31
|
+
nearest: "nearest";
|
|
32
|
+
linear: "linear";
|
|
33
|
+
cubic: "cubic";
|
|
34
|
+
mitchell: "mitchell";
|
|
35
|
+
lanczos2: "lanczos2";
|
|
36
|
+
lanczos3: "lanczos3";
|
|
37
|
+
}>>;
|
|
38
|
+
}, z.core.$strip>;
|
|
39
|
+
/**
|
|
40
|
+
* Image transformations schema.
|
|
41
|
+
* Supports resize, rotate, flip, flop, sharpen, blur, grayscale, format conversion.
|
|
42
|
+
*/
|
|
43
|
+
declare const transformationsSchema: z.ZodObject<{
|
|
44
|
+
resize: z.ZodOptional<z.ZodObject<{
|
|
45
|
+
width: z.ZodOptional<z.ZodNumber>;
|
|
46
|
+
height: z.ZodOptional<z.ZodNumber>;
|
|
47
|
+
fit: z.ZodOptional<z.ZodEnum<{
|
|
48
|
+
fill: "fill";
|
|
49
|
+
cover: "cover";
|
|
50
|
+
contain: "contain";
|
|
51
|
+
inside: "inside";
|
|
52
|
+
outside: "outside";
|
|
53
|
+
}>>;
|
|
54
|
+
position: z.ZodOptional<z.ZodEnum<{
|
|
55
|
+
left: "left";
|
|
56
|
+
right: "right";
|
|
57
|
+
top: "top";
|
|
58
|
+
"right top": "right top";
|
|
59
|
+
"right bottom": "right bottom";
|
|
60
|
+
bottom: "bottom";
|
|
61
|
+
"left bottom": "left bottom";
|
|
62
|
+
"left top": "left top";
|
|
63
|
+
centre: "centre";
|
|
64
|
+
}>>;
|
|
65
|
+
kernel: z.ZodOptional<z.ZodEnum<{
|
|
66
|
+
nearest: "nearest";
|
|
67
|
+
linear: "linear";
|
|
68
|
+
cubic: "cubic";
|
|
69
|
+
mitchell: "mitchell";
|
|
70
|
+
lanczos2: "lanczos2";
|
|
71
|
+
lanczos3: "lanczos3";
|
|
72
|
+
}>>;
|
|
73
|
+
}, z.core.$strip>>;
|
|
74
|
+
rotate: z.ZodOptional<z.ZodNumber>;
|
|
75
|
+
flip: z.ZodOptional<z.ZodBoolean>;
|
|
76
|
+
flop: z.ZodOptional<z.ZodBoolean>;
|
|
77
|
+
sharpen: z.ZodOptional<z.ZodBoolean>;
|
|
78
|
+
blur: z.ZodOptional<z.ZodNumber>;
|
|
79
|
+
grayscale: z.ZodOptional<z.ZodBoolean>;
|
|
80
|
+
format: z.ZodOptional<z.ZodEnum<{
|
|
81
|
+
jpeg: "jpeg";
|
|
82
|
+
png: "png";
|
|
83
|
+
webp: "webp";
|
|
84
|
+
avif: "avif";
|
|
85
|
+
gif: "gif";
|
|
86
|
+
}>>;
|
|
87
|
+
quality: z.ZodOptional<z.ZodNumber>;
|
|
88
|
+
preview: z.ZodOptional<z.ZodLiteral<true>>;
|
|
89
|
+
}, z.core.$strip>;
|
|
90
|
+
/**
|
|
91
|
+
* Types for image transformations.
|
|
92
|
+
*/
|
|
93
|
+
type ImageTransformations = z.infer<typeof transformationsSchema>;
|
|
94
|
+
/**
|
|
95
|
+
* Types for resize options.
|
|
96
|
+
*/
|
|
97
|
+
type ResizeOptions = z.infer<typeof resizeSchema>;
|
|
98
|
+
//#endregion
|
|
99
|
+
export { ImageTransformations, ResizeOptions, resizeSchema, transformationsSchema };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{defineWorkflow as e}from"../workflow.mjs";import{z as t}from"zod";import n from"sharp";const r=t.object({width:t.number().optional(),height:t.number().optional(),fit:t.enum([`cover`,`contain`,`fill`,`inside`,`outside`]).optional(),position:t.enum([`top`,`right top`,`right`,`right bottom`,`bottom`,`left bottom`,`left`,`left top`,`centre`]).optional(),kernel:t.enum([`nearest`,`linear`,`cubic`,`mitchell`,`lanczos2`,`lanczos3`]).optional()}),i=t.object({resize:r.optional(),rotate:t.number().optional(),flip:t.boolean().optional(),flop:t.boolean().optional(),sharpen:t.boolean().optional(),blur:t.number().optional(),grayscale:t.boolean().optional(),format:t.enum([`jpeg`,`png`,`webp`,`avif`,`gif`]).optional(),quality:t.number().min(1).max(100).optional(),preview:t.literal(!0).optional()}),a=e({input:t.object({blobId:t.string(),transformations:i}),async run({container:e,input:{blobId:t,transformations:r},step:i}){if(!await i(`fetch-blob`,async()=>e.storage.primary.getBlob(t)))throw Error(`Blob ${t} not found`);let a=await i(`download-blob`,async()=>e.storage.primary.downloadBlob(t));if(!a)throw Error(`Failed to download blob ${t}`);let o=await i(`apply-transformations`,async()=>{let e=n(a);return r.resize&&(e=e.resize({width:r.resize.width,height:r.resize.height,fit:r.resize.fit,position:r.resize.position,kernel:r.resize.kernel})),r.rotate!==void 0&&(e=e.rotate(r.rotate)),r.flip&&(e=e.flip()),r.flop&&(e=e.flop()),r.sharpen&&(e=e.sharpen()),r.blur!==void 0&&(e=e.blur(r.blur)),r.grayscale&&(e=e.grayscale()),r.format&&(e=e.toFormat(r.format,{quality:r.quality})),e.toBuffer()}),s=await i(`store-variant`,async()=>e.storage.primary.createVariant(t,r,o));return e.logger.info({blobId:t,variantId:s.id},`Image variant generated`),s}});export{a as generateImageVariant,r as resizeSchema,i as transformationsSchema};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{defineWorkflow as e}from"../workflow.mjs";import t from"zod";import{join as n}from"node:path";import r from"sharp";import{spawn as i}from"node:child_process";import{createCanvas as a}from"canvas";const o=e({input:t.object({blobId:t.string(),timeInSeconds:t.number().optional()}),async run({container:e,input:{blobId:t,timeInSeconds:o=1},step:s}){let c=await s(`fetch-blob`,async()=>e.storage.primary.getBlob(t));if(!c)throw Error(`Blob ${t} not found`);let l=await s(`download-blob`,async()=>e.storage.primary.downloadBlob(t));if(!l)throw Error(`Failed to download blob ${t}`);let u=null;if(c.contentType?.startsWith(`video/`))u=await s(`generate-video-preview`,async()=>new Promise((n,a)=>{try{let s=i(`ffmpeg`,[`-i`,`pipe:0`,`-ss`,o.toString(),`-frames:v`,`1`,`-f`,`image2pipe`,`-c:v`,`png`,`pipe:1`]),c=[],u=[];s.stdout.on(`data`,e=>{c.push(e)}),s.stderr.on(`data`,e=>{u.push(e)}),s.on(`close`,async i=>{if(i===0)try{n(await r(Buffer.concat(c)).jpeg({quality:80}).toBuffer())}catch(n){e.logger.error({error:n,blobId:t},`Failed to convert video frame to JPEG`),a(n)}else{let n=Buffer.concat(u).toString(),r=Error(`FFmpeg exited with code ${i}: ${n}`);e.logger.error({error:r,blobId:t,code:i,stderr:n},`Failed to generate video preview`),a(r)}}),s.on(`error`,n=>{e.logger.error({error:n,blobId:t},`Failed to spawn FFmpeg process`),a(n)}),s.stdin.on(`error`,n=>{n.code!==`EPIPE`&&e.logger.error({error:n,blobId:t},`Failed to write to FFmpeg stdin`)}),s.stdin.write(l),s.stdin.end()}catch(n){e.logger.error({error:n,blobId:t},`Failed to generate video preview`),a(n)}}));else if(c.contentType===`application/pdf`)u=await s(`generate-pdf-preview`,async()=>{try{let e=await import(`pdfjs-dist/legacy/build/pdf.mjs`),t=`${n(process.cwd(),`node_modules/pdfjs-dist/standard_fonts`)}/`,i=await(await e.getDocument({data:new Uint8Array(l),standardFontDataUrl:t}).promise).getPage(1),o=i.getViewport({scale:2}),s=a(o.width,o.height),c=s.getContext(`2d`);return await i.render({canvasContext:c,viewport:o,canvas:s}).promise,await r(s.toBuffer(`image/png`)).resize(800,800,{fit:`inside`,withoutEnlargement:!0}).jpeg({quality:85}).toBuffer()}catch(n){throw e.logger.error({error:n,errorMessage:n instanceof Error?n.message:String(n),errorStack:n instanceof Error?n.stack:void 0,errorCode:n?.code,blobId:t},`Failed to generate PDF preview`),n}});else if(c.contentType?.startsWith(`image/`))u=await s(`generate-image-preview`,async()=>await r(l).resize(800,800,{fit:`inside`,withoutEnlargement:!0}).jpeg({quality:85}).toBuffer());else throw Error(`Preview generation not supported for content type: ${c.contentType}`);let d=await s(`store-preview`,async()=>await e.storage.primary.createVariant(t,{preview:!0},u));return e.logger.info({blobId:t,previewId:d.id,contentType:c.contentType},`Preview generated`),d}});export{o as generatePreview};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{trackDbChanges as e}from"./track-db-changes.mjs";export{e as trackDbChanges};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import pino, { LoggerOptions } from "pino";
|
|
2
|
+
|
|
3
|
+
//#region src/api/logger.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Extended logger options with OpenTelemetry support.
|
|
7
|
+
*/
|
|
8
|
+
interface DefineLoggerOptions extends LoggerOptions {}
|
|
9
|
+
/**
|
|
10
|
+
* The logger instance type.
|
|
11
|
+
*/
|
|
12
|
+
type Logger = Awaited<ReturnType<typeof defineLogger>>;
|
|
13
|
+
/**
|
|
14
|
+
* Define the logger instance.
|
|
15
|
+
*
|
|
16
|
+
* @param opts - The options.
|
|
17
|
+
* @returns The logger.
|
|
18
|
+
*/
|
|
19
|
+
declare function defineLogger(opts: DefineLoggerOptions): Promise<pino.Logger<never, boolean>>;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { Logger };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import Mail from "nodemailer/lib/mailer/index.ts";
|
|
2
|
+
import { JSX } from "react";
|
|
3
|
+
|
|
4
|
+
//#region src/api/mailer.d.ts
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The mailer type.
|
|
8
|
+
*/
|
|
9
|
+
type Mailer = ReturnType<typeof defineMailer>;
|
|
10
|
+
/**
|
|
11
|
+
* The mailer payload type with React component.
|
|
12
|
+
*/
|
|
13
|
+
type MailerPayloadReact = Omit<Mail.Options, "from" | "html" | "text"> & {
|
|
14
|
+
/**
|
|
15
|
+
* The email address to send the email from.
|
|
16
|
+
*/
|
|
17
|
+
from?: string;
|
|
18
|
+
/**
|
|
19
|
+
* The React component to render as the email body.
|
|
20
|
+
*/
|
|
21
|
+
react: JSX.Element;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* The mailer payload type with direct HTML and text.
|
|
25
|
+
*/
|
|
26
|
+
type MailerPayloadHtml = Omit<Mail.Options, "from"> & {
|
|
27
|
+
/**
|
|
28
|
+
* The email address to send the email from.
|
|
29
|
+
*/
|
|
30
|
+
from?: string;
|
|
31
|
+
/**
|
|
32
|
+
* The HTML content of the email.
|
|
33
|
+
*/
|
|
34
|
+
html: string;
|
|
35
|
+
/**
|
|
36
|
+
* The plain text content of the email.
|
|
37
|
+
*/
|
|
38
|
+
text: string;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* The mailer payload type - supports either React component or direct HTML+text.
|
|
42
|
+
*/
|
|
43
|
+
type MailerPayload = MailerPayloadReact | MailerPayloadHtml;
|
|
44
|
+
/**
|
|
45
|
+
* Define the options for the mailer.
|
|
46
|
+
*/
|
|
47
|
+
interface DefineMailerOptions {
|
|
48
|
+
/**
|
|
49
|
+
* The default email address to use as the sender.
|
|
50
|
+
*/
|
|
51
|
+
from: string;
|
|
52
|
+
/**
|
|
53
|
+
* The SMTP URL to use for sending emails.
|
|
54
|
+
*/
|
|
55
|
+
smtpUrl: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Define the mailer.
|
|
59
|
+
*
|
|
60
|
+
* @param env - The environment variables.
|
|
61
|
+
* @returns The mailer.
|
|
62
|
+
*/
|
|
63
|
+
declare function defineMailer({
|
|
64
|
+
from,
|
|
65
|
+
smtpUrl
|
|
66
|
+
}: DefineMailerOptions): {
|
|
67
|
+
send(payload: MailerPayload): Promise<void>;
|
|
68
|
+
};
|
|
69
|
+
//#endregion
|
|
70
|
+
export { Mailer };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { __export, __reExport } from "./_virtual/rolldown_runtime.mjs";
|
|
2
|
+
import { index, isPgEnum, isPgMaterializedView, isPgSchema, isPgSequence, isPgView, numeric, parsePgArray, parsePgNestedArray, pgEnum, pgMaterializedView, pgPolicy, pgRole, pgSchema, pgSequence, pgTable as pgTable$1, pgTableCreator, pgView, serial, smallint, smallserial, sparsevec, unique, uniqueIndex, uniqueKeyName, withReplicas } from "drizzle-orm/pg-core";
|
|
3
|
+
export * from "drizzle-orm";
|
|
4
|
+
export * from "drizzle-seed";
|
|
5
|
+
|
|
6
|
+
//#region src/api/orm.d.ts
|
|
7
|
+
declare namespace orm_d_exports {
|
|
8
|
+
export { index, isPgEnum, isPgMaterializedView, isPgSchema, isPgSequence, isPgView, numeric, parsePgArray, parsePgNestedArray, pgEnum, pgMaterializedView, pgPolicy, pgRole, pgSchema, pgSequence, pgTable$1 as pgTable, pgTableCreator, pgView, serial, smallint, smallserial, sparsevec, unique, uniqueIndex, uniqueKeyName, withReplicas };
|
|
9
|
+
}
|
|
10
|
+
import * as import_drizzle_orm from "drizzle-orm";
|
|
11
|
+
import * as import_drizzle_seed from "drizzle-seed";
|
|
12
|
+
//#endregion
|
|
13
|
+
export { import_drizzle_seed as orm_d_exports };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{defineWorkflow as e}from"../workflow.mjs";import t from"zod";const n=e({input:t.object({attachmentIds:t.array(t.string()).min(1)}),async run({container:e,input:{attachmentIds:t},step:n}){let r=await n(`fetch-attachments`,async()=>(await e.storage.primary.getAttachmentsByIds(t)).filter(e=>e.blob!==null).map(e=>({attachmentId:e.id,blobId:e.blob.id})));return await n(`delete-attachments`,async()=>{for(let{attachmentId:t}of r)await e.storage.primary.deleteAttachment(t)}),await n(`delete-blobs`,async()=>{for(let{blobId:t}of r)await e.storage.primary.deleteBlob(t)}),e.logger.info({attachmentIds:t,blobCount:r.length},`Attachments and blobs purged`),{purgedCount:r.length}}});export{n as purgeAttachment};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{defineAuthSchema as e}from"../auth-schema.mjs";import{defineScheduledWorkflow as t}from"../workflow.mjs";import{lt as n}from"drizzle-orm";const r=e();function i(e=`0 0 * * *`){return t({crontab:e,async run({container:e,step:t,scheduledTime:i}){let a=e.auth.auditLog?.retentionDays??90,o=new Date(i);o.setDate(o.getDate()-a);let s=o.toISOString(),c=await t(`delete-old-logs`,async()=>{let{auditLogs:t}=r.tables;return(await e.db.primary.delete(t).where(n(t.createdAt,s)).returning({id:t.id})).length});e.logger.info({deletedCount:c,retentionDays:a,cutoffDate:s},`Audit log purge completed`)}})}export{i as definePurgeAuditLogs};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{defineScheduledWorkflow as e}from"../workflow.mjs";function t(t=`0 0 * * *`){return e({crontab:t,async run({container:e,step:t}){let n=new Date(Date.now()-2880*60*1e3).toISOString(),r=await t(`fetch-unattached-blobs`,async()=>e.storage.primary.getUnattachedBlobs({olderThan:n})),i=await t(`fetch-pending-blobs`,async()=>e.storage.primary.getPendingBlobs(n)),a=[...r,...i],o=0;for(let n of a)await t(`delete-blob`,async()=>{await e.storage.primary.deleteBlob(n.id),o++});e.logger.info({purgedCount:o,unattachedCount:r.length,pendingCount:i.length},`Orphaned blobs purged`)}})}export{t as definePurgeUnattachedBlobs};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"redis";export{};
|