@db3.ai/app 0.1.0-beta.1 → 0.1.0-beta.4
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/README.md +68 -9
- package/agent-instructions.md +76 -0
- package/dist/ai/AIErrors.d.ts +7 -1
- package/dist/ai/AIErrors.js +8 -1
- package/dist/ai/AIFailover.d.ts +10 -0
- package/dist/ai/AIFailover.js +3 -2
- package/dist/ai/AIProviderAdmission.d.ts +101 -0
- package/dist/ai/AIProviderAdmission.js +336 -0
- package/dist/ai/AIRateLimiter.d.ts +11 -2
- package/dist/ai/AIRateLimiter.js +125 -10
- package/dist/ai/AIRequestTrackingError.d.ts +22 -0
- package/dist/ai/AIRequestTrackingError.js +33 -0
- package/dist/ai/Agent.d.ts +7 -7
- package/dist/ai/Agent.js +84 -56
- package/dist/ai/Ai.d.ts +11 -3
- package/dist/ai/Ai.js +94 -44
- package/dist/ai/OpenAIProviderError.js +1 -1
- package/dist/ai/ProviderSseObserver.d.ts +19 -0
- package/dist/ai/ProviderSseObserver.js +98 -0
- package/dist/ai/aiServiceTier.d.ts +5 -0
- package/dist/ai/aiServiceTier.js +14 -0
- package/dist/ai/chunkEmbeddingText.d.ts +14 -0
- package/dist/ai/chunkEmbeddingText.js +147 -0
- package/dist/ai/contracts/AI.d.ts +16 -0
- package/dist/ai/contracts/AIRequestErrorDiagnostics.d.ts +12 -0
- package/dist/ai/contracts/AIRequestErrorDiagnostics.js +1 -0
- package/dist/ai/contracts/AIServiceTier.d.ts +2 -0
- package/dist/ai/contracts/AIServiceTier.js +1 -0
- package/dist/ai/contracts/Agent.d.ts +3 -0
- package/dist/ai/contracts/EmbeddingTextChunk.d.ts +25 -0
- package/dist/ai/contracts/EmbeddingTextChunk.js +1 -0
- package/dist/ai/contracts/Pricing.d.ts +7 -1
- package/dist/ai/contracts/Providers.d.ts +2 -0
- package/dist/ai/contracts/index.d.ts +2 -0
- package/dist/ai/contracts/index.js +1 -0
- package/dist/ai/index.d.ts +8 -2
- package/dist/ai/index.js +5 -2
- package/dist/ai/{Models.d.ts → modelPricing.d.ts} +2 -2
- package/dist/ai/{Models.js → modelPricing.js} +38 -4
- package/dist/apps/AppInstallation.d.ts +21 -0
- package/dist/apps/AppInstallation.js +16 -0
- package/dist/apps/AppRouteError.d.ts +6 -0
- package/dist/apps/AppRouteError.js +10 -0
- package/dist/apps/AppService.d.ts +24 -0
- package/dist/apps/AppService.js +21 -0
- package/dist/apps/Apps.d.ts +59 -0
- package/dist/apps/Apps.js +566 -0
- package/dist/apps/appsPlugin.d.ts +3 -0
- package/dist/apps/appsPlugin.js +36 -0
- package/dist/apps/commands/disableApp.d.ts +2 -0
- package/dist/apps/commands/disableApp.js +5 -0
- package/dist/apps/commands/enableApp.d.ts +2 -0
- package/dist/apps/commands/enableApp.js +5 -0
- package/dist/apps/commands/index.d.ts +10 -0
- package/dist/apps/commands/index.js +27 -0
- package/dist/apps/commands/installApp.d.ts +2 -0
- package/dist/apps/commands/installApp.js +5 -0
- package/dist/apps/commands/listApps.d.ts +2 -0
- package/dist/apps/commands/listApps.js +5 -0
- package/dist/apps/commands/makeAppMigration.d.ts +2 -0
- package/dist/apps/commands/makeAppMigration.js +9 -0
- package/dist/apps/commands/rollbackApp.d.ts +2 -0
- package/dist/apps/commands/rollbackApp.js +5 -0
- package/dist/apps/commands/uninstallApp.d.ts +2 -0
- package/dist/apps/commands/uninstallApp.js +5 -0
- package/dist/apps/contracts/AppAction.d.ts +2 -0
- package/dist/apps/contracts/AppAction.js +1 -0
- package/dist/apps/contracts/AppDefinition.d.ts +45 -0
- package/dist/apps/contracts/AppDefinition.js +1 -0
- package/dist/apps/contracts/AppDescription.d.ts +32 -0
- package/dist/apps/contracts/AppDescription.js +1 -0
- package/dist/apps/contracts/AppManifest.d.ts +30 -0
- package/dist/apps/contracts/AppManifest.js +1 -0
- package/dist/apps/contracts/AppNavigation.d.ts +9 -0
- package/dist/apps/contracts/AppNavigation.js +1 -0
- package/dist/apps/contracts/AppNavigationBadge.d.ts +6 -0
- package/dist/apps/contracts/AppNavigationBadge.js +1 -0
- package/dist/apps/contracts/AppNavigationContext.d.ts +8 -0
- package/dist/apps/contracts/AppNavigationContext.js +1 -0
- package/dist/apps/contracts/AppNavigationResult.d.ts +12 -0
- package/dist/apps/contracts/AppNavigationResult.js +1 -0
- package/dist/apps/contracts/AppRoute.d.ts +19 -0
- package/dist/apps/contracts/AppRoute.js +1 -0
- package/dist/apps/contracts/DiscoveredApp.d.ts +10 -0
- package/dist/apps/contracts/DiscoveredApp.js +1 -0
- package/dist/apps/contracts/InstalledApps.d.ts +3 -0
- package/dist/apps/contracts/InstalledApps.js +1 -0
- package/dist/apps/contracts/index.d.ts +11 -0
- package/dist/apps/contracts/index.js +1 -0
- package/dist/apps/defineApp.d.ts +7 -0
- package/dist/apps/defineApp.js +8 -0
- package/dist/apps/discoverApps.d.ts +3 -0
- package/dist/apps/discoverApps.js +62 -0
- package/dist/apps/fastify.d.ts +1 -0
- package/dist/apps/fastify.js +1 -0
- package/dist/apps/index.d.ts +7 -0
- package/dist/apps/index.js +7 -0
- package/dist/apps/normalizeAppNavigation.d.ts +3 -0
- package/dist/apps/normalizeAppNavigation.js +30 -0
- package/dist/apps/registerAppRoutes.d.ts +6 -0
- package/dist/apps/registerAppRoutes.js +52 -0
- package/dist/apps/validateAppDefinitions.d.ts +3 -0
- package/dist/apps/validateAppDefinitions.js +65 -0
- package/dist/apps/vite.d.ts +1 -0
- package/dist/apps/vite.js +1 -0
- package/dist/apps/writeAppTypes.d.ts +2 -0
- package/dist/apps/writeAppTypes.js +13 -0
- package/dist/auth/Auth.d.ts +18 -0
- package/dist/auth/Auth.js +89 -13
- package/dist/auth/PasswordLoginAttempt.d.ts +50 -0
- package/dist/auth/PasswordLoginAttempt.js +60 -0
- package/dist/auth/PasswordSuspendedError.d.ts +10 -0
- package/dist/auth/PasswordSuspendedError.js +13 -0
- package/dist/auth/contracts/PasswordAuthProviderOptions.d.ts +26 -0
- package/dist/auth/contracts/PasswordAuthProviderOptions.js +1 -0
- package/dist/auth/contracts/PasswordSuspension.d.ts +7 -0
- package/dist/auth/contracts/PasswordSuspension.js +1 -0
- package/dist/auth/contracts/PasswordSuspensionOptions.d.ts +10 -0
- package/dist/auth/contracts/PasswordSuspensionOptions.js +1 -0
- package/dist/auth/contracts/index.d.ts +3 -0
- package/dist/auth/contracts/index.js +3 -0
- package/dist/auth/index.d.ts +2 -0
- package/dist/auth/index.js +2 -0
- package/dist/auth/providers/PasswordAuthProvider.d.ts +19 -23
- package/dist/auth/providers/PasswordAuthProvider.js +96 -8
- package/dist/auth/providers/resolveAuthProviders.js +1 -0
- package/dist/cli/Cli.d.ts +2 -0
- package/dist/cli/Cli.js +8 -0
- package/dist/cli/commands/repl.js +2 -1
- package/dist/cli/contracts/CliCommand.d.ts +2 -0
- package/dist/cli/contracts/CliCommandInfo.d.ts +12 -0
- package/dist/cli/contracts/CliCommandInfo.js +1 -0
- package/dist/cli/contracts/index.d.ts +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +1 -0
- package/dist/cli/listDb3Commands.d.ts +8 -0
- package/dist/cli/listDb3Commands.js +10 -0
- package/dist/cli/runDb3.d.ts +3 -6
- package/dist/cli/runDb3.js +5 -59
- package/dist/cli/withDb3Cli.d.ts +4 -0
- package/dist/cli/withDb3Cli.js +60 -0
- package/dist/db/ActiveQueryBuilder.d.ts +8 -0
- package/dist/db/ActiveQueryBuilder.js +11 -0
- package/dist/db/ActiveRecord.d.ts +6 -0
- package/dist/db/ActiveRecord.js +8 -0
- package/dist/db/connection.js +14 -2
- package/dist/db/fields/TimestampField.d.ts +1 -1
- package/dist/db/fields/TimestampField.js +7 -12
- package/dist/db/migrations/DatabaseMigrationManager.d.ts +3 -1
- package/dist/db/migrations/DatabaseMigrationManager.js +9 -3
- package/dist/db/migrations/contracts/DatabaseMigration.d.ts +7 -0
- package/dist/db/migrations/index.d.ts +1 -1
- package/dist/db/migrations/index.js +1 -1
- package/dist/db/migrations/{KnexMigrationRenderer.d.ts → renderKnexMigration.d.ts} +4 -3
- package/dist/db/migrations/{KnexMigrationRenderer.js → renderKnexMigration.js} +7 -6
- package/dist/flows/FlowCompiler.js +1 -1
- package/dist/flows/Flows.js +1 -1
- package/dist/flows/index.d.ts +1 -1
- package/dist/flows/index.js +1 -1
- package/dist/health/Health.d.ts +41 -0
- package/dist/health/Health.js +153 -0
- package/dist/health/contracts/Health.d.ts +36 -0
- package/dist/health/contracts/Health.js +1 -0
- package/dist/health/contracts/HealthHttp.d.ts +15 -0
- package/dist/health/contracts/HealthHttp.js +1 -0
- package/dist/health/contracts/index.d.ts +2 -0
- package/dist/health/contracts/index.js +1 -0
- package/dist/health/databaseHealthCheck.d.ts +15 -0
- package/dist/health/databaseHealthCheck.js +18 -0
- package/dist/health/fastify.d.ts +13 -0
- package/dist/health/fastify.js +44 -0
- package/dist/health/index.d.ts +3 -0
- package/dist/health/index.js +2 -0
- package/dist/in-app/InApp.d.ts +33 -0
- package/dist/in-app/InApp.js +191 -0
- package/dist/in-app/InAppError.d.ts +6 -0
- package/dist/in-app/InAppError.js +10 -0
- package/dist/in-app/InAppRecord.d.ts +36 -0
- package/dist/in-app/InAppRecord.js +24 -0
- package/dist/in-app/contracts/InAppInbox.d.ts +45 -0
- package/dist/in-app/contracts/InAppInbox.js +1 -0
- package/dist/in-app/contracts/InAppMessage.d.ts +22 -0
- package/dist/in-app/contracts/InAppMessage.js +1 -0
- package/dist/in-app/contracts/InAppScope.d.ts +17 -0
- package/dist/in-app/contracts/InAppScope.js +1 -0
- package/dist/in-app/contracts/index.d.ts +3 -0
- package/dist/in-app/contracts/index.js +3 -0
- package/dist/in-app/index.d.ts +4 -0
- package/dist/in-app/index.js +4 -0
- package/dist/in-app/validation.d.ts +21 -0
- package/dist/in-app/validation.js +50 -0
- package/dist/index.d.ts +2 -14
- package/dist/index.js +2 -5
- package/dist/logging/DevelopmentConsole.d.ts +42 -0
- package/dist/logging/DevelopmentConsole.js +162 -0
- package/dist/logging/Log.d.ts +3 -1
- package/dist/logging/Log.js +5 -2
- package/dist/logging/PrettyLogFormatter.d.ts +16 -0
- package/dist/logging/PrettyLogFormatter.js +151 -0
- package/dist/logging/acquireDevelopmentConsole.d.ts +6 -0
- package/dist/logging/acquireDevelopmentConsole.js +21 -0
- package/dist/logging/contracts/DevelopmentConsoleOptions.d.ts +16 -0
- package/dist/logging/contracts/DevelopmentConsoleOptions.js +1 -0
- package/dist/logging/contracts/EmailLogOptions.d.ts +8 -0
- package/dist/logging/contracts/EmailLogOptions.js +1 -0
- package/dist/logging/contracts/HttpExchangeMonitorOptions.d.ts +12 -0
- package/dist/logging/contracts/HttpExchangeMonitorOptions.js +1 -0
- package/dist/logging/contracts/LogTransportOptions.d.ts +19 -0
- package/dist/logging/contracts/LogTransportOptions.js +1 -0
- package/dist/logging/contracts/LoggingOptions.d.ts +12 -1
- package/dist/logging/contracts/index.d.ts +4 -0
- package/dist/logging/contracts/index.js +4 -0
- package/dist/logging/drivers/PinoLoggerDriver.d.ts +3 -1
- package/dist/logging/drivers/PinoLoggerDriver.js +75 -16
- package/dist/logging/formatLogEmail.d.ts +4 -0
- package/dist/logging/formatLogEmail.js +21 -0
- package/dist/logging/highlightQueueMessage.d.ts +11 -0
- package/dist/logging/highlightQueueMessage.js +36 -0
- package/dist/logging/httpBodyCapture.d.ts +24 -0
- package/dist/logging/httpBodyCapture.js +321 -0
- package/dist/logging/index.d.ts +2 -0
- package/dist/logging/index.js +2 -0
- package/dist/logging/redactLogEmail.d.ts +2 -0
- package/dist/logging/redactLogEmail.js +12 -0
- package/dist/logging/registerHttpExchangeMonitor.d.ts +10 -0
- package/dist/logging/registerHttpExchangeMonitor.js +43 -0
- package/dist/logging/transports/EmailLogTransport.d.ts +18 -0
- package/dist/logging/transports/EmailLogTransport.js +47 -0
- package/dist/mail/Mail.d.ts +2 -0
- package/dist/mail/Mail.js +3 -0
- package/dist/mail/MailDeliveryError.d.ts +9 -0
- package/dist/mail/MailDeliveryError.js +16 -0
- package/dist/mail/index.d.ts +1 -0
- package/dist/mail/index.js +1 -0
- package/dist/mail/transports/MailgunTransport.js +2 -0
- package/dist/mail/transports/ResendTransport.d.ts +3 -2
- package/dist/mail/transports/ResendTransport.js +22 -14
- package/dist/media/MediaManager.d.ts +4 -2
- package/dist/media/MediaManager.js +40 -8
- package/dist/network/BlockedUrlError.d.ts +16 -0
- package/dist/network/BlockedUrlError.js +19 -0
- package/dist/network/assertPublicUrl.d.ts +22 -0
- package/dist/network/assertPublicUrl.js +67 -0
- package/dist/network/contracts/GuardedFetch.d.ts +35 -0
- package/dist/network/contracts/GuardedFetch.js +1 -0
- package/dist/network/contracts/PublicUrlOptions.d.ts +17 -0
- package/dist/network/contracts/PublicUrlOptions.js +1 -0
- package/dist/network/contracts/index.d.ts +2 -0
- package/dist/network/contracts/index.js +2 -0
- package/dist/network/guardedFetch.d.ts +29 -0
- package/dist/network/guardedFetch.js +133 -0
- package/dist/network/index.d.ts +6 -0
- package/dist/network/index.js +6 -0
- package/dist/network/playwright/GuardedBrowserProxy.d.ts +32 -0
- package/dist/network/playwright/GuardedBrowserProxy.js +172 -0
- package/dist/network/playwright/contracts/GuardedBrowserContextOptions.d.ts +37 -0
- package/dist/network/playwright/contracts/GuardedBrowserContextOptions.js +1 -0
- package/dist/network/playwright/contracts/index.d.ts +1 -0
- package/dist/network/playwright/contracts/index.js +1 -0
- package/dist/network/playwright/index.d.ts +2 -0
- package/dist/network/playwright/index.js +2 -0
- package/dist/network/playwright/newGuardedBrowserContext.d.ts +21 -0
- package/dist/network/playwright/newGuardedBrowserContext.js +86 -0
- package/dist/network/privateNetworkAddresses.d.ts +44 -0
- package/dist/network/privateNetworkAddresses.js +157 -0
- package/dist/network/publicAddressLookup.d.ts +26 -0
- package/dist/network/publicAddressLookup.js +42 -0
- package/dist/notifications/Notifications.d.ts +27 -0
- package/dist/notifications/Notifications.js +99 -0
- package/dist/notifications/contracts/Notification.d.ts +56 -0
- package/dist/notifications/contracts/Notification.js +1 -0
- package/dist/notifications/contracts/NotificationDelivery.d.ts +11 -0
- package/dist/notifications/contracts/NotificationDelivery.js +1 -0
- package/dist/notifications/contracts/index.d.ts +2 -0
- package/dist/notifications/contracts/index.js +2 -0
- package/dist/notifications/index.d.ts +2 -0
- package/dist/notifications/index.js +2 -0
- package/dist/queue/JobRunAttempt.d.ts +16 -0
- package/dist/queue/JobRunAttempt.js +17 -0
- package/dist/queue/JobRunEvent.d.ts +15 -0
- package/dist/queue/JobRunEvent.js +16 -0
- package/dist/queue/JobRunStoppedError.d.ts +6 -0
- package/dist/queue/JobRunStoppedError.js +10 -0
- package/dist/queue/Queue.d.ts +19 -4
- package/dist/queue/Queue.js +122 -9
- package/dist/queue/QueueTerminalError.d.ts +9 -0
- package/dist/queue/QueueTerminalError.js +12 -0
- package/dist/queue/QueueWorker.d.ts +12 -5
- package/dist/queue/QueueWorker.js +94 -9
- package/dist/queue/QueueWorkerReporter.d.ts +17 -0
- package/dist/queue/QueueWorkerReporter.js +71 -0
- package/dist/queue/QueueableJob.d.ts +2 -2
- package/dist/queue/RunnableJob.d.ts +78 -0
- package/dist/queue/RunnableJob.js +284 -0
- package/dist/queue/console.d.ts +8 -0
- package/dist/queue/console.js +53 -19
- package/dist/queue/contracts/QueueDriver.d.ts +8 -0
- package/dist/queue/contracts/QueueJobRunner.d.ts +4 -0
- package/dist/queue/contracts/QueueJobRunner.js +1 -0
- package/dist/queue/contracts/QueuePayload.d.ts +1 -1
- package/dist/queue/contracts/QueueSelection.d.ts +11 -0
- package/dist/queue/contracts/QueueSelection.js +1 -0
- package/dist/queue/contracts/QueueService.d.ts +18 -4
- package/dist/queue/contracts/QueueWorkerLifecycle.d.ts +2 -2
- package/dist/queue/contracts/QueueWorkerSnapshot.d.ts +14 -0
- package/dist/queue/contracts/QueueWorkerSnapshot.js +1 -0
- package/dist/queue/contracts/QueueableJob.d.ts +7 -3
- package/dist/queue/contracts/QueueableJobContract.d.ts +12 -0
- package/dist/queue/contracts/QueueableJobContract.js +1 -0
- package/dist/queue/contracts/index.d.ts +4 -0
- package/dist/queue/contracts/index.js +2 -0
- package/dist/queue/drivers/DatabaseQueueDriver.d.ts +4 -0
- package/dist/queue/drivers/DatabaseQueueDriver.js +27 -3
- package/dist/queue/drivers/RedisQueueDriver.d.ts +7 -0
- package/dist/queue/drivers/RedisQueueDriver.js +37 -0
- package/dist/queue/index.d.ts +5 -0
- package/dist/queue/index.js +5 -0
- package/dist/queue/jobEnvelopeHasPrefix.d.ts +3 -0
- package/dist/queue/jobEnvelopeHasPrefix.js +4 -0
- package/dist/scheduler/ScheduledEvent.d.ts +8 -4
- package/dist/scheduler/ScheduledEvent.js +17 -3
- package/dist/scheduler/ScheduledJob.d.ts +1 -1
- package/dist/scheduler/Scheduler.d.ts +5 -0
- package/dist/scheduler/Scheduler.js +92 -28
- package/dist/scheduler/SchedulerCheckpointRecord.d.ts +16 -0
- package/dist/scheduler/SchedulerCheckpointRecord.js +53 -0
- package/dist/scheduler/SchedulerWorker.d.ts +3 -5
- package/dist/scheduler/SchedulerWorker.js +58 -14
- package/dist/scheduler/console.js +3 -1
- package/dist/scheduler/contracts/Schedule.d.ts +19 -0
- package/dist/scheduler/contracts/Schedule.js +1 -0
- package/dist/scheduler/contracts/Scheduler.d.ts +18 -6
- package/dist/scheduler/contracts/SchedulerCheckpoint.d.ts +23 -0
- package/dist/scheduler/contracts/SchedulerCheckpoint.js +1 -0
- package/dist/scheduler/contracts/SchedulerConsole.d.ts +5 -0
- package/dist/scheduler/contracts/SchedulerWorker.d.ts +6 -1
- package/dist/scheduler/contracts/index.d.ts +2 -0
- package/dist/scheduler/contracts/index.js +2 -0
- package/dist/scheduler/index.d.ts +1 -0
- package/dist/scheduler/index.js +1 -0
- package/dist/server/App.d.ts +36 -4
- package/dist/server/App.js +57 -7
- package/dist/server/contracts/HttpErrorHandlerOptions.d.ts +29 -0
- package/dist/server/contracts/HttpErrorHandlerOptions.js +1 -0
- package/dist/server/contracts/index.d.ts +1 -0
- package/dist/server/contracts/index.js +1 -0
- package/dist/server/index.d.ts +4 -0
- package/dist/server/index.js +4 -0
- package/dist/server/publicServerErrorMessage.d.ts +11 -0
- package/dist/server/publicServerErrorMessage.js +16 -0
- package/dist/server/registerBrowserJsonFormatting.d.ts +16 -0
- package/dist/server/registerBrowserJsonFormatting.js +100 -0
- package/dist/server/registerHttpErrorHandler.d.ts +20 -0
- package/dist/server/registerHttpErrorHandler.js +93 -0
- package/dist/ssr/vite/contracts/ViteSsrOptions.d.ts +2 -0
- package/dist/ssr/vite/fastifyViteSsr.js +4 -3
- package/dist/storage/drivers/FlystorageDisk.js +2 -2
- package/dist/storage/index.d.ts +2 -2
- package/dist/storage/index.js +2 -2
- package/dist/websocket/WebSocketChannels.d.ts +18 -0
- package/dist/websocket/WebSocketChannels.js +129 -0
- package/dist/websocket/WebSocketConnection.d.ts +25 -0
- package/dist/websocket/WebSocketConnection.js +244 -0
- package/dist/websocket/WebSockets.d.ts +41 -0
- package/dist/websocket/WebSockets.js +194 -0
- package/dist/websocket/client/WebSocketClient.d.ts +21 -0
- package/dist/websocket/client/WebSocketClient.js +230 -0
- package/dist/websocket/client/index.d.ts +3 -0
- package/dist/websocket/client/index.js +1 -0
- package/dist/websocket/contracts/WebSocketChannel.d.ts +20 -0
- package/dist/websocket/contracts/WebSocketChannel.js +1 -0
- package/dist/websocket/contracts/WebSocketClient.d.ts +45 -0
- package/dist/websocket/contracts/WebSocketClient.js +1 -0
- package/dist/websocket/contracts/WebSocketEndpoint.d.ts +43 -0
- package/dist/websocket/contracts/WebSocketEndpoint.js +1 -0
- package/dist/websocket/contracts/WebSocketOptions.d.ts +48 -0
- package/dist/websocket/contracts/WebSocketOptions.js +1 -0
- package/dist/websocket/contracts/WebSocketPresence.d.ts +6 -0
- package/dist/websocket/contracts/WebSocketPresence.js +1 -0
- package/dist/websocket/contracts/WebSocketServiceOptions.d.ts +12 -0
- package/dist/websocket/contracts/WebSocketServiceOptions.js +1 -0
- package/dist/websocket/contracts/index.d.ts +6 -0
- package/dist/websocket/contracts/index.js +1 -0
- package/dist/websocket/defineChannel.d.ts +8 -0
- package/dist/websocket/defineChannel.js +13 -0
- package/dist/websocket/defineWebSocket.d.ts +14 -0
- package/dist/websocket/defineWebSocket.js +4 -0
- package/dist/websocket/fastify.d.ts +11 -0
- package/dist/websocket/fastify.js +38 -0
- package/dist/websocket/index.d.ts +5 -0
- package/dist/websocket/index.js +4 -0
- package/package.json +108 -7
- package/src/ai/AIErrors.ts +10 -0
- package/src/ai/AIFailover.ts +3 -2
- package/src/ai/AIProviderAdmission.ts +329 -0
- package/src/ai/AIRateLimiter.ts +134 -10
- package/src/ai/AIRequestTrackingError.ts +37 -0
- package/src/ai/Agent.ts +85 -71
- package/src/ai/Ai.ts +104 -48
- package/src/ai/OpenAIProviderError.ts +1 -1
- package/src/ai/ProviderSseObserver.ts +89 -0
- package/src/ai/README.md +216 -11
- package/src/ai/aiServiceTier.ts +14 -0
- package/src/ai/chunkEmbeddingText.ts +137 -0
- package/src/ai/contracts/AI.ts +17 -0
- package/src/ai/contracts/AIRequestErrorDiagnostics.ts +12 -0
- package/src/ai/contracts/AIServiceTier.ts +2 -0
- package/src/ai/contracts/Agent.ts +3 -0
- package/src/ai/contracts/EmbeddingTextChunk.ts +26 -0
- package/src/ai/contracts/Pricing.ts +7 -1
- package/src/ai/contracts/Providers.ts +2 -0
- package/src/ai/contracts/index.ts +2 -0
- package/src/ai/examples/prepareDocumentEmbeddings.ts +20 -0
- package/src/ai/index.ts +9 -2
- package/src/ai/{Models.ts → modelPricing.ts} +37 -4
- package/src/apps/AppInstallation.ts +25 -0
- package/src/apps/AppRouteError.ts +8 -0
- package/src/apps/AppService.ts +30 -0
- package/src/apps/Apps.ts +508 -0
- package/src/apps/README.md +354 -0
- package/src/apps/appsPlugin.ts +34 -0
- package/src/apps/commands/disableApp.ts +6 -0
- package/src/apps/commands/enableApp.ts +6 -0
- package/src/apps/commands/index.ts +29 -0
- package/src/apps/commands/installApp.ts +6 -0
- package/src/apps/commands/listApps.ts +6 -0
- package/src/apps/commands/makeAppMigration.ts +9 -0
- package/src/apps/commands/rollbackApp.ts +6 -0
- package/src/apps/commands/uninstallApp.ts +6 -0
- package/src/apps/contracts/AppAction.ts +2 -0
- package/src/apps/contracts/AppDefinition.ts +49 -0
- package/src/apps/contracts/AppDescription.ts +27 -0
- package/src/apps/contracts/AppManifest.ts +32 -0
- package/src/apps/contracts/AppNavigation.ts +10 -0
- package/src/apps/contracts/AppNavigationBadge.ts +6 -0
- package/src/apps/contracts/AppNavigationContext.ts +6 -0
- package/src/apps/contracts/AppNavigationResult.ts +9 -0
- package/src/apps/contracts/AppRoute.ts +18 -0
- package/src/apps/contracts/DiscoveredApp.ts +11 -0
- package/src/apps/contracts/InstalledApps.ts +2 -0
- package/src/apps/contracts/index.ts +11 -0
- package/src/apps/defineApp.ts +10 -0
- package/src/apps/discoverApps.ts +56 -0
- package/src/apps/fastify.ts +1 -0
- package/src/apps/index.ts +7 -0
- package/src/apps/normalizeAppNavigation.ts +29 -0
- package/src/apps/registerAppRoutes.ts +48 -0
- package/src/apps/validateAppDefinitions.ts +52 -0
- package/src/apps/vite.ts +1 -0
- package/src/apps/writeAppTypes.ts +14 -0
- package/src/auth/Auth.ts +89 -23
- package/src/auth/PasswordLoginAttempt.ts +72 -0
- package/src/auth/PasswordSuspendedError.ts +13 -0
- package/src/auth/README.md +94 -4
- package/src/auth/contracts/PasswordAuthProviderOptions.ts +30 -0
- package/src/auth/contracts/PasswordSuspension.ts +7 -0
- package/src/auth/contracts/PasswordSuspensionOptions.ts +10 -0
- package/src/auth/contracts/index.ts +3 -0
- package/src/auth/examples/runPasswordAuth.ts +6 -6
- package/src/auth/index.ts +2 -0
- package/src/auth/providers/PasswordAuthProvider.ts +96 -30
- package/src/auth/providers/resolveAuthProviders.ts +1 -0
- package/src/cli/Cli.ts +9 -0
- package/src/cli/README.md +19 -0
- package/src/cli/commands/repl.ts +2 -1
- package/src/cli/contracts/CliCommand.ts +2 -0
- package/src/cli/contracts/CliCommandInfo.ts +13 -0
- package/src/cli/contracts/index.ts +1 -0
- package/src/cli/index.ts +1 -0
- package/src/cli/listDb3Commands.ts +12 -0
- package/src/cli/runDb3.ts +5 -51
- package/src/cli/withDb3Cli.ts +55 -0
- package/src/db/ActiveQueryBuilder.ts +12 -0
- package/src/db/ActiveRecord.ts +9 -0
- package/src/db/README.md +45 -1
- package/src/db/connection.ts +12 -1
- package/src/db/examples/FieldNote.ts +7 -13
- package/src/db/examples/KnowledgeNote.ts +7 -13
- package/src/db/examples/runNoteMigrations.ts +11 -11
- package/src/db/fields/TimestampField.ts +8 -17
- package/src/db/migrations/DatabaseMigrationManager.ts +12 -4
- package/src/db/migrations/contracts/DatabaseMigration.ts +9 -0
- package/src/db/migrations/index.ts +1 -1
- package/src/db/migrations/{KnexMigrationRenderer.ts → renderKnexMigration.ts} +8 -14
- package/src/flows/FlowCompiler.ts +1 -1
- package/src/flows/Flows.ts +1 -1
- package/src/flows/index.ts +1 -1
- package/src/health/Health.ts +163 -0
- package/src/health/README.md +46 -0
- package/src/health/contracts/Health.ts +47 -0
- package/src/health/contracts/HealthHttp.ts +19 -0
- package/src/health/contracts/index.ts +2 -0
- package/src/health/databaseHealthCheck.ts +21 -0
- package/src/health/fastify.ts +49 -0
- package/src/health/index.ts +3 -0
- package/src/in-app/InApp.ts +173 -0
- package/src/in-app/InAppError.ts +8 -0
- package/src/in-app/InAppRecord.ts +41 -0
- package/src/in-app/README.md +193 -0
- package/src/in-app/contracts/InAppInbox.ts +51 -0
- package/src/in-app/contracts/InAppMessage.ts +19 -0
- package/src/in-app/contracts/InAppScope.ts +12 -0
- package/src/in-app/contracts/index.ts +3 -0
- package/src/in-app/examples/sendReportReady.ts +14 -0
- package/src/in-app/index.ts +4 -0
- package/src/in-app/validation.ts +49 -0
- package/src/index.ts +2 -22
- package/src/logging/DevelopmentConsole.ts +154 -0
- package/src/logging/Log.ts +5 -2
- package/src/logging/PrettyLogFormatter.ts +165 -0
- package/src/logging/README.md +52 -109
- package/src/logging/acquireDevelopmentConsole.ts +19 -0
- package/src/logging/contracts/DevelopmentConsoleOptions.ts +13 -0
- package/src/logging/contracts/EmailLogOptions.ts +9 -0
- package/src/logging/contracts/HttpExchangeMonitorOptions.ts +13 -0
- package/src/logging/contracts/LogTransportOptions.ts +10 -0
- package/src/logging/contracts/LoggingOptions.ts +12 -1
- package/src/logging/contracts/index.ts +4 -0
- package/src/logging/development/README.md +88 -0
- package/src/logging/drivers/PinoLoggerDriver.ts +72 -20
- package/src/logging/examples/runDevelopmentLogs.ts +36 -0
- package/src/logging/formatLogEmail.ts +24 -0
- package/src/logging/highlightQueueMessage.ts +38 -0
- package/src/logging/httpBodyCapture.ts +393 -0
- package/src/logging/index.ts +2 -0
- package/src/logging/redactLogEmail.ts +12 -0
- package/src/logging/registerHttpExchangeMonitor.ts +45 -0
- package/src/logging/transports/EmailLogTransport.ts +46 -0
- package/src/mail/Mail.ts +5 -0
- package/src/mail/MailDeliveryError.ts +8 -0
- package/src/mail/README.md +11 -1
- package/src/mail/index.ts +1 -0
- package/src/mail/transports/MailgunTransport.ts +2 -0
- package/src/mail/transports/ResendTransport.ts +24 -22
- package/src/media/MediaManager.ts +31 -10
- package/src/media/README.md +4 -0
- package/src/media/examples/runPrivateFiles.ts +2 -2
- package/src/network/BlockedUrlError.ts +19 -0
- package/src/network/README.md +133 -0
- package/src/network/assertPublicUrl.ts +77 -0
- package/src/network/contracts/GuardedFetch.ts +40 -0
- package/src/network/contracts/PublicUrlOptions.ts +17 -0
- package/src/network/contracts/index.ts +2 -0
- package/src/network/examples/runGuardedFetch.ts +35 -0
- package/src/network/guardedFetch.ts +150 -0
- package/src/network/index.ts +6 -0
- package/src/network/playwright/GuardedBrowserProxy.ts +172 -0
- package/src/network/playwright/contracts/GuardedBrowserContextOptions.ts +43 -0
- package/src/network/playwright/contracts/index.ts +1 -0
- package/src/network/playwright/index.ts +2 -0
- package/src/network/playwright/newGuardedBrowserContext.ts +74 -0
- package/src/network/privateNetworkAddresses.ts +166 -0
- package/src/network/publicAddressLookup.ts +49 -0
- package/src/notifications/Notifications.ts +105 -0
- package/src/notifications/README.md +59 -0
- package/src/notifications/contracts/Notification.ts +65 -0
- package/src/notifications/contracts/NotificationDelivery.ts +11 -0
- package/src/notifications/contracts/index.ts +2 -0
- package/src/notifications/examples/ReportReadyNotification.ts +31 -0
- package/src/notifications/index.ts +2 -0
- package/src/queue/JobRunAttempt.ts +17 -0
- package/src/queue/JobRunEvent.ts +16 -0
- package/src/queue/JobRunStoppedError.ts +8 -0
- package/src/queue/Queue.ts +112 -11
- package/src/queue/QueueTerminalError.ts +12 -0
- package/src/queue/QueueWorker.ts +86 -7
- package/src/queue/QueueWorkerReporter.ts +59 -0
- package/src/queue/QueueableJob.ts +2 -2
- package/src/queue/README.md +142 -1
- package/src/queue/RunnableJob.ts +272 -0
- package/src/queue/console.ts +54 -21
- package/src/queue/contracts/QueueDriver.ts +9 -0
- package/src/queue/contracts/QueueJobRunner.ts +4 -0
- package/src/queue/contracts/QueuePayload.ts +1 -1
- package/src/queue/contracts/QueueSelection.ts +11 -0
- package/src/queue/contracts/QueueService.ts +19 -4
- package/src/queue/contracts/QueueWorkerLifecycle.ts +2 -2
- package/src/queue/contracts/QueueWorkerSnapshot.ts +15 -0
- package/src/queue/contracts/QueueableJob.ts +7 -3
- package/src/queue/contracts/QueueableJobContract.ts +13 -0
- package/src/queue/contracts/index.ts +6 -0
- package/src/queue/drivers/DatabaseQueueDriver.ts +25 -3
- package/src/queue/drivers/RedisQueueDriver.ts +36 -0
- package/src/queue/examples/runQueueSelection.ts +34 -0
- package/src/queue/index.ts +7 -0
- package/src/queue/jobEnvelopeHasPrefix.ts +6 -0
- package/src/scheduler/README.md +50 -9
- package/src/scheduler/ScheduledEvent.ts +20 -5
- package/src/scheduler/ScheduledJob.ts +1 -1
- package/src/scheduler/Scheduler.ts +73 -27
- package/src/scheduler/SchedulerCheckpointRecord.ts +51 -0
- package/src/scheduler/SchedulerWorker.ts +54 -19
- package/src/scheduler/console.ts +3 -1
- package/src/scheduler/contracts/Schedule.ts +22 -0
- package/src/scheduler/contracts/Scheduler.ts +21 -6
- package/src/scheduler/contracts/SchedulerCheckpoint.ts +23 -0
- package/src/scheduler/contracts/SchedulerConsole.ts +5 -0
- package/src/scheduler/contracts/SchedulerWorker.ts +6 -1
- package/src/scheduler/contracts/index.ts +2 -0
- package/src/scheduler/examples/runSchedulerWindow.ts +54 -0
- package/src/scheduler/index.ts +1 -0
- package/src/server/App.ts +73 -10
- package/src/server/README.md +95 -2
- package/src/server/contracts/HttpErrorHandlerOptions.ts +29 -0
- package/src/server/contracts/index.ts +1 -0
- package/src/server/examples/createFirstServer.ts +5 -3
- package/src/server/index.ts +4 -0
- package/src/server/publicServerErrorMessage.ts +17 -0
- package/src/server/registerBrowserJsonFormatting.ts +94 -0
- package/src/server/registerHttpErrorHandler.ts +96 -0
- package/src/ssr/README.md +6 -0
- package/src/ssr/vite/contracts/ViteSsrOptions.ts +2 -0
- package/src/ssr/vite/fastifyViteSsr.ts +4 -3
- package/src/storage/drivers/FlystorageDisk.ts +2 -2
- package/src/storage/index.ts +2 -2
- package/src/websocket/README.md +458 -0
- package/src/websocket/WebSocketChannels.ts +99 -0
- package/src/websocket/WebSocketConnection.ts +162 -0
- package/src/websocket/WebSockets.ts +157 -0
- package/src/websocket/client/WebSocketClient.ts +188 -0
- package/src/websocket/client/index.ts +3 -0
- package/src/websocket/contracts/WebSocketChannel.ts +23 -0
- package/src/websocket/contracts/WebSocketClient.ts +48 -0
- package/src/websocket/contracts/WebSocketEndpoint.ts +46 -0
- package/src/websocket/contracts/WebSocketOptions.ts +50 -0
- package/src/websocket/contracts/WebSocketPresence.ts +6 -0
- package/src/websocket/contracts/WebSocketServiceOptions.ts +12 -0
- package/src/websocket/contracts/index.ts +6 -0
- package/src/websocket/defineChannel.ts +14 -0
- package/src/websocket/defineWebSocket.ts +15 -0
- package/src/websocket/examples/board/LiveBoard.ts +97 -0
- package/src/websocket/examples/board/SummarizeBoardJob.ts +52 -0
- package/src/websocket/examples/board/boardSnapshot.ts +16 -0
- package/src/websocket/examples/board/createBoardClient.ts +43 -0
- package/src/websocket/examples/board/createBoardStore.ts +58 -0
- package/src/websocket/examples/board/registerBoardRoutes.ts +31 -0
- package/src/websocket/examples/createChannelSync.ts +66 -0
- package/src/websocket/examples/deploymentEndpoint.ts +13 -0
- package/src/websocket/examples/deploymentSnapshot.ts +36 -0
- package/src/websocket/examples/resourceChannels.ts +18 -0
- package/src/websocket/examples/userEndpoint.ts +27 -0
- package/src/websocket/fastify.ts +39 -0
- package/src/websocket/index.ts +5 -0
- package/templates/AGENTS.md +33 -2
- /package/dist/flows/{FlowValueValidator.d.ts → flowValueValidator.d.ts} +0 -0
- /package/dist/flows/{FlowValueValidator.js → flowValueValidator.js} +0 -0
- /package/dist/storage/{mime.d.ts → mimeTypeFromPath.d.ts} +0 -0
- /package/dist/storage/{mime.js → mimeTypeFromPath.js} +0 -0
- /package/dist/storage/{contents.d.ts → storageContentsToBuffer.d.ts} +0 -0
- /package/dist/storage/{contents.js → storageContentsToBuffer.js} +0 -0
- /package/src/flows/{FlowValueValidator.ts → flowValueValidator.ts} +0 -0
- /package/src/storage/{mime.ts → mimeTypeFromPath.ts} +0 -0
- /package/src/storage/{contents.ts → storageContentsToBuffer.ts} +0 -0
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
# Apps: add a folder, then install
|
|
2
|
+
|
|
3
|
+
Put a cohesive feature in `apps/{id}/` inside the host application. DB3 discovers
|
|
4
|
+
its root `manifest.json` without importing its code. Install it from the Starter's
|
|
5
|
+
Apps screen or the CLI. There are no per-app host imports, model lists, navigation
|
|
6
|
+
registrations or CSS source directives to edit.
|
|
7
|
+
|
|
8
|
+
Start locally and extract the folder into an independent npm package when it
|
|
9
|
+
needs reuse or independent releases. General-purpose libraries still belong in
|
|
10
|
+
`packages/`. A feature app shares the host's runtime, database and authentication.
|
|
11
|
+
|
|
12
|
+
The documentation generator and packed Create test share the Hello fragments in
|
|
13
|
+
`examples/helloGuideSamples.ts`, allowing an independent public checkout to verify
|
|
14
|
+
the exact copyable tutorial code.
|
|
15
|
+
|
|
16
|
+
## Local structure
|
|
17
|
+
|
|
18
|
+
The runnable Social example is `apps/starter/apps/social` in this repository:
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
apps/social/
|
|
22
|
+
manifest.json
|
|
23
|
+
App.ts
|
|
24
|
+
database/
|
|
25
|
+
migrations/20260926000100_social_opportunities.mjs
|
|
26
|
+
schema.snapshot.json
|
|
27
|
+
server/
|
|
28
|
+
models/SocialOpportunity.ts
|
|
29
|
+
routes.ts
|
|
30
|
+
client/
|
|
31
|
+
index.ts
|
|
32
|
+
SocialApp.vue
|
|
33
|
+
shared/ # optional browser-safe contracts
|
|
34
|
+
package.json # optional until packaging
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The folder name is the official identifier: `social`. The root manifest describes
|
|
38
|
+
public metadata, icon, default navigation and dependencies. It need not repeat the id;
|
|
39
|
+
if present, `id` must agree with the folder name.
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"name": "Social",
|
|
44
|
+
"version": "0.1.0",
|
|
45
|
+
"icon": "◎",
|
|
46
|
+
"description": "Study discussions and save opportunities to contribute.",
|
|
47
|
+
"apiVersion": 1,
|
|
48
|
+
"navigation": [
|
|
49
|
+
{ "id": "opportunities", "label": "Opportunities", "path": "" },
|
|
50
|
+
{ "id": "about", "label": "About", "path": "about" }
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`App.ts` default-exports the public service. It can expose subservices as the app
|
|
56
|
+
grows. Extend `AppService`, not the host's framework `App`:
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
import { AppService } from '@db3.ai/app/apps';
|
|
60
|
+
import { SocialOpportunity } from './server/models/SocialOpportunity.js';
|
|
61
|
+
import { socialRoutes } from './server/routes.js';
|
|
62
|
+
|
|
63
|
+
/** Public Social service; the framework supplies the existing host. */
|
|
64
|
+
export default class App extends AppService {
|
|
65
|
+
static override models = [SocialOpportunity];
|
|
66
|
+
static override routes = socialRoutes;
|
|
67
|
+
|
|
68
|
+
/** Returns discussions owned by an already authenticated caller. */
|
|
69
|
+
async list(ownerId: string) {
|
|
70
|
+
return (await SocialOpportunity.where('owner', ownerId).all()).map(record => record.toJSON());
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Static navigation can stay in JSON so a visual tool can inspect an uninstalled app
|
|
76
|
+
without executing its server code. Apps that need live counts, permission-aware
|
|
77
|
+
links or status information provide `navigation(context)` on their root service.
|
|
78
|
+
`client/index.ts` default-exports its browser component.
|
|
79
|
+
Its host supplies an app-relative `path` prop; Social handles its own About view.
|
|
80
|
+
Backend-only apps may omit `client/`. Do not put secrets in the manifest.
|
|
81
|
+
|
|
82
|
+
## Contributions from enabled apps
|
|
83
|
+
|
|
84
|
+
The registry owns the loop; each app owns the data it contributes. Navigation is
|
|
85
|
+
the first typed contribution. The manifest remains public, inspectable metadata;
|
|
86
|
+
`apps.describe()` never invokes viewer-specific providers.
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
import type { AppNavigation, AppNavigationContext } from '@db3.ai/app/apps';
|
|
90
|
+
|
|
91
|
+
// Inside the root App class:
|
|
92
|
+
/** Returns links and counts scoped to the already authenticated viewer. */
|
|
93
|
+
override async navigation(context: AppNavigationContext): Promise<AppNavigation> {
|
|
94
|
+
const count = await SocialOpportunity.where({ owner: context.actor.id, status: 'saved' }).count();
|
|
95
|
+
const badge = { count, label: `${count} saved opportunities` };
|
|
96
|
+
return {
|
|
97
|
+
badge,
|
|
98
|
+
description: count ? 'Ready to review' : 'All caught up',
|
|
99
|
+
items: [
|
|
100
|
+
{ id: 'opportunities', label: 'Opportunities', path: '', badge },
|
|
101
|
+
{ id: 'about', label: 'About Social', path: 'about' },
|
|
102
|
+
],
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The host authenticates the request, then calls:
|
|
108
|
+
|
|
109
|
+
```ts
|
|
110
|
+
const navigation = await host.apps.navigation({ actor: { id: verifiedUser.id } });
|
|
111
|
+
// { apps: [{ appId, name, icon, items, badge?, description? }], unavailable: [] }
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Only booted, enabled apps participate. Providers receive a frozen request context
|
|
115
|
+
and the host database scope. An optional `organisationId` must already be authorized
|
|
116
|
+
by the host; apps still enforce their own permissions. Never accept the actor from
|
|
117
|
+
query parameters or cache a viewer's data on the shared service instance.
|
|
118
|
+
|
|
119
|
+
- No override, or `undefined`: use manifest navigation, defaulting to no sublinks.
|
|
120
|
+
- An object: replace the manifest links with the current contribution.
|
|
121
|
+
- `null`: hide this app's navigation for this viewer.
|
|
122
|
+
- A failure or invalid result: omit only that app, include its id in `unavailable`,
|
|
123
|
+
and log the server error. Do not fall back to links that a permission-aware
|
|
124
|
+
provider may have intended to hide. No error details enter the browser payload.
|
|
125
|
+
|
|
126
|
+
Items have a stable `id`, text `label`, and safe app-relative `path`. Optional
|
|
127
|
+
`description` text and `{ count, label }` badges work on both apps and sublinks.
|
|
128
|
+
Counts are non-negative integers and badge labels provide accessible context.
|
|
129
|
+
The framework copies only declared display fields. App identity, name and icon
|
|
130
|
+
come from the registry. Navigation visibility does not authorize API access.
|
|
131
|
+
|
|
132
|
+
Starter exposes this through authenticated `GET /api/app-navigation` with
|
|
133
|
+
`Cache-Control: no-store`. Its generic menu renders the response, refreshes after
|
|
134
|
+
installation actions, when the window regains focus, and when an app component
|
|
135
|
+
emits `navigation-changed`. It also offers manual refresh. Social emits that event
|
|
136
|
+
after saves and status changes, so the badge updates without remounting the app.
|
|
137
|
+
There is no background polling or push transport in this initial contract.
|
|
138
|
+
|
|
139
|
+
Navigation requests participate in lifecycle draining automatically. Providers run
|
|
140
|
+
concurrently and the registry waits for them all; providers should use bounded
|
|
141
|
+
database/network operations. Programmatic `defineApp` compositions can supply
|
|
142
|
+
`navigation(context, service)` with the same return contract. Further contribution
|
|
143
|
+
types can follow this pattern when there is a concrete consumer.
|
|
144
|
+
|
|
145
|
+
## Use the Starter
|
|
146
|
+
|
|
147
|
+
Use Node 24 and MariaDB. Configure its `.env` using the Starter guide. Set
|
|
148
|
+
`APP_ADMIN_EMAIL` to the account allowed to manage apps, then:
|
|
149
|
+
|
|
150
|
+
```sh
|
|
151
|
+
npm run db:migrate
|
|
152
|
+
npm run dev
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Sign in with that account, open **Apps**, and click **Install** on Social. Its
|
|
156
|
+
migrations run, the service starts, and its navigation becomes available. Save a
|
|
157
|
+
discussion, mark it answered and reload. Social is a private bookmark/review
|
|
158
|
+
example; it does not search social platforms or post replies.
|
|
159
|
+
|
|
160
|
+
Alternatively, with runtimes stopped:
|
|
161
|
+
|
|
162
|
+
```sh
|
|
163
|
+
npm run db3 -- apps:list
|
|
164
|
+
npm run db3 -- apps:install social
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Adding another folder makes it discoverable on the next catalog read. Vite's
|
|
168
|
+
development plugin refreshes browser entries when manifests are added or removed.
|
|
169
|
+
Production browser bundles still need rebuilding when code is added or removed.
|
|
170
|
+
Changing an existing app's code/version requires restarting its server processes;
|
|
171
|
+
this implementation does not replace loaded JavaScript modules in place.
|
|
172
|
+
|
|
173
|
+
## One-time host integration
|
|
174
|
+
|
|
175
|
+
Starter already includes this wiring. A custom host sets its root directory,
|
|
176
|
+
boots apps before serving requests, mounts the authenticated adapter and exposes
|
|
177
|
+
the catalog. Omitting `apps` enables discovery; `apps: {}` opts out. An explicit
|
|
178
|
+
`defineApp` map remains available for tests and unusual compositions.
|
|
179
|
+
|
|
180
|
+
```ts
|
|
181
|
+
const host = new App({ directory: new URL('../', import.meta.url) });
|
|
182
|
+
await host.apps.boot();
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
For Vite frontends, add `appsPlugin()` from `@db3.ai/app/apps/vite` once. Import
|
|
186
|
+
client entries from `virtual:db3/apps`. The plugin generates lazy imports and
|
|
187
|
+
Tailwind sources for local and npm apps; server entries never enter that graph.
|
|
188
|
+
The Starter ships the virtual-module declaration and `AppWorkspace.vue`, which
|
|
189
|
+
renders the catalog, icons, sublinks and administrator actions. Other frontends
|
|
190
|
+
can render the same contracts using their own router.
|
|
191
|
+
|
|
192
|
+
`writeAppTypes(hostDirectory)` generates `.db3/apps.d.ts` without executing app
|
|
193
|
+
code. Include it in the host TypeScript configuration. Starter runs it before
|
|
194
|
+
type checking; Vite also runs it during development/build. Generated declarations
|
|
195
|
+
make direct access optional and typed:
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
import { app } from '@db3.ai/app/server';
|
|
199
|
+
|
|
200
|
+
const social = app().social;
|
|
201
|
+
if (social) await social.list(verifiedUserId);
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
`host.apps.get('social')` also supports runtime discovery. Framework service names,
|
|
205
|
+
registry names, prototype names and `db3`/`db3_` are reserved. Collisions fail before
|
|
206
|
+
app code loads. Identifiers start with a lowercase letter and contain at most 40
|
|
207
|
+
lowercase letters, digits or underscores.
|
|
208
|
+
|
|
209
|
+
A manifest can declare `requires: { crm: 1 }` and `optional: { social: 1 }`. Values
|
|
210
|
+
are exact public API generations, matching `apiVersion` (default 1). Required apps
|
|
211
|
+
must be enabled first. Missing optional apps are allowed; installed incompatible
|
|
212
|
+
contracts and cycles are rejected. Consume another app's public service, not its
|
|
213
|
+
internal models. Startup runs in dependency order.
|
|
214
|
+
|
|
215
|
+
## Lifecycle and administration
|
|
216
|
+
|
|
217
|
+
The base service provides these overridable asynchronous hooks:
|
|
218
|
+
|
|
219
|
+
- `install()` runs after migrations on install/upgrade. Make it retry-safe.
|
|
220
|
+
- `start(context)` starts resources. Use `context.defer(cleanup)` immediately
|
|
221
|
+
after acquiring each resource. Cleanup runs in reverse order, including when
|
|
222
|
+
startup fails. Constructors and module imports should not start resources.
|
|
223
|
+
- `uninstall()` handles durable deregistration and preflight checks. Throw if
|
|
224
|
+
outstanding jobs or schedules would be stranded. The framework does not infer
|
|
225
|
+
job cancellation from a deleted directory.
|
|
226
|
+
|
|
227
|
+
`host.apps.manage(action, id)` supports install, enable, disable and uninstall
|
|
228
|
+
inside an explicitly authorized **single-process** host. It rejects new app HTTP
|
|
229
|
+
requests while waiting for existing app requests, closes owned resources, applies
|
|
230
|
+
the action and boots the remaining apps. The Starter exposes it only to the
|
|
231
|
+
configured administrator, with session authentication and Origin protection.
|
|
232
|
+
Development enables the single-process policy; production additionally requires
|
|
233
|
+
`APPS_MANAGE_ONLINE=true`. Do not enable it when separate workers or replicas use
|
|
234
|
+
these app services. Calls outside the route adapter must use `apps.run()` to
|
|
235
|
+
participate in draining, and background resources must register cleanup.
|
|
236
|
+
|
|
237
|
+
For multiple processes, stop all affected web/worker runtimes and use the CLI.
|
|
238
|
+
The database advisory lock serializes installers; it cannot stop other processes.
|
|
239
|
+
Boot never applies migrations. `App.close()` releases app resources before shared
|
|
240
|
+
framework services. Installation is host-wide, not per tenant.
|
|
241
|
+
|
|
242
|
+
## App-owned migrations and down migrations
|
|
243
|
+
|
|
244
|
+
Feature models stay out of the host's model list and schema snapshot. Tables must
|
|
245
|
+
start with `{id}_`, such as `social_opportunities`. Each app owns `database/`, its
|
|
246
|
+
snapshot and immutable `.mjs` migrations beside `App.ts` (beside `dist/App.js` when
|
|
247
|
+
packaged). The framework keeps installation metadata in `db3_apps` and a separate
|
|
248
|
+
ledger such as `db3_app_social_migrations`. MariaDB is currently supported.
|
|
249
|
+
|
|
250
|
+
Generate changes locally, before publishing:
|
|
251
|
+
|
|
252
|
+
```sh
|
|
253
|
+
npm run db3 -- apps:make-migration social add_topic
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Review and commit the migration and snapshot. The app author owns both `up()` and
|
|
257
|
+
`down()`. Generated `down()` defaults to an explicit refusal because an automatic
|
|
258
|
+
reverse can destroy data. Author and test a reversal **before first installing**
|
|
259
|
+
that migration if rollback is supported. The Social initial migration retains
|
|
260
|
+
that deliberate refusal. Do not rewrite an already applied migration to add one.
|
|
261
|
+
|
|
262
|
+
For a migration with an authored reversal, stop consumers and run:
|
|
263
|
+
|
|
264
|
+
```sh
|
|
265
|
+
npm run db3 -- apps:disable social
|
|
266
|
+
npm run db3 -- apps:rollback social
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
Rollback runs the latest migration's `down()` once, not every historical migration.
|
|
270
|
+
It can delete data and is deliberately absent from the web controls. The app is
|
|
271
|
+
left unavailable until `apps:install` reapplies its current migrations. Uninstall
|
|
272
|
+
never calls `down()` automatically and retains tables, records and history.
|
|
273
|
+
|
|
274
|
+
Increase the stable `x.y.z` manifest/package version for releases and use install
|
|
275
|
+
for upgrades. Installation fingerprints migration bytes and refuses changed or
|
|
276
|
+
missing history and version downgrades. A failed migration, install hook or schema
|
|
277
|
+
check leaves a failed installation; repair and retry. MariaDB DDL is not atomic.
|
|
278
|
+
Use `await host.apps.load(id)` before `host.apps.migrations(id)` for inspection or
|
|
279
|
+
source tooling outside the supplied commands. Never generate inside node_modules.
|
|
280
|
+
|
|
281
|
+
## Extract the same app to npm
|
|
282
|
+
|
|
283
|
+
Social includes an independent build and private package named `@db3.ai/social`.
|
|
284
|
+
The name is an example, not a claim of publication. From the host root:
|
|
285
|
+
|
|
286
|
+
```sh
|
|
287
|
+
npm pack ./apps/social --pack-destination /tmp
|
|
288
|
+
mv apps/social /tmp/social-source
|
|
289
|
+
npm install /tmp/db3.ai-social-0.1.0.tgz
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
Choose an unused extraction destination. Stop running consumers before switching
|
|
293
|
+
sources; restart/rebuild afterward. Do not keep both copies in discovery. No host
|
|
294
|
+
source edits are needed. Install from the Apps screen or `apps:install social`.
|
|
295
|
+
An identical local/package version reuses the existing migration history.
|
|
296
|
+
|
|
297
|
+
The npm package exports `package.json`, ships a root `manifest.json`, uses a
|
|
298
|
+
framework peer dependency and declares:
|
|
299
|
+
|
|
300
|
+
```json
|
|
301
|
+
{
|
|
302
|
+
"name": "@your-scope/social",
|
|
303
|
+
"db3": {
|
|
304
|
+
"app": true,
|
|
305
|
+
"entry": "./dist/App.js",
|
|
306
|
+
"client": "./dist/client/index.js"
|
|
307
|
+
},
|
|
308
|
+
"exports": {
|
|
309
|
+
".": { "types": "./dist/App.d.ts", "import": "./dist/App.js" },
|
|
310
|
+
"./package.json": "./package.json"
|
|
311
|
+
},
|
|
312
|
+
"files": ["manifest.json", "dist"]
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
The final npm name segment (`social`) is its identifier. Discovery reads only
|
|
317
|
+
marked **direct** dependencies/optionalDependencies; it does not execute or scan
|
|
318
|
+
all transitive packages. Export the root service for generated types. Include
|
|
319
|
+
compiled browser code and copy migrations unchanged into `dist/database/`.
|
|
320
|
+
Social's build shows this complete pattern. Outside the monorepo, install its
|
|
321
|
+
declared development dependencies before building. `shared/` stays optional.
|
|
322
|
+
|
|
323
|
+
To remove an app, click **Uninstall · keep data**, then delete its local folder
|
|
324
|
+
or run `npm uninstall @db3.ai/social`. In multi-process hosts use
|
|
325
|
+
`apps:uninstall social` while all consumers are stopped and code is still present.
|
|
326
|
+
Rebuild the browser and restart servers after code removal. There are no host
|
|
327
|
+
imports to clean up. Required dependants must be removed first. If enabled code
|
|
328
|
+
was deleted prematurely, restore it to run its uninstall hook. Reinstalling a
|
|
329
|
+
compatible copy recovers retained data. Npm lifecycle scripts never migrate SQL.
|
|
330
|
+
|
|
331
|
+
## Verification and boundaries
|
|
332
|
+
|
|
333
|
+
Keep a feature app's behaviour tests with its own code and import the smallest
|
|
334
|
+
feature entry that exercises the contract. Add those test paths to the host's
|
|
335
|
+
Vitest configuration so a focused `npm test -- <test path>` runs them without
|
|
336
|
+
selecting every other feature. Use real framework services and install only the
|
|
337
|
+
models required by that fixture. Reserve complete host bootstrap and all-app
|
|
338
|
+
schemas for tests that verify composition, discovery or cross-app workflows.
|
|
339
|
+
This keeps adding an unrelated app from expanding each existing test's import
|
|
340
|
+
graph and schema setup. Full host and package checks remain the release boundary.
|
|
341
|
+
|
|
342
|
+
`npm run framework:apps:test` builds actual tarballs, installs them into a clean
|
|
343
|
+
temporary consumer, generates service types, compiles TypeScript, builds discovered
|
|
344
|
+
browser entries, migrates a disposable database, runs real npm uninstall and
|
|
345
|
+
reinstall, and checks that records survived. Starter tests cover authenticated
|
|
346
|
+
routes and administrator actions; framework tests cover discovery, dependencies,
|
|
347
|
+
cleanup, in-flight draining, schema failures, history integrity and authored down
|
|
348
|
+
migrations.
|
|
349
|
+
|
|
350
|
+
Apps are trusted code in the host process, not a security sandbox. The manifest
|
|
351
|
+
supports visual exploration; visual definition editing, automatic social-platform
|
|
352
|
+
discovery, tenant installations and live replacement of existing code are future
|
|
353
|
+
work. Host authentication and authorization remain mandatory regardless of menu
|
|
354
|
+
visibility.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Plugin } from 'vite';
|
|
2
|
+
import { discoverApps } from './discoverApps';
|
|
3
|
+
import { writeAppTypes } from './writeAppTypes';
|
|
4
|
+
|
|
5
|
+
/** Supplies discovered browser entries, Tailwind sources and app service types without per-app host imports. */
|
|
6
|
+
export function appsPlugin(): Plugin {
|
|
7
|
+
let root: string;
|
|
8
|
+
return {
|
|
9
|
+
name: 'db3-apps', enforce: 'pre',
|
|
10
|
+
/** Generates declarations using Vite's resolved application root. */
|
|
11
|
+
async configResolved(config) { root = config.root; await writeAppTypes(root); },
|
|
12
|
+
/** Resolves the browser-only virtual registry. */
|
|
13
|
+
resolveId(id) { if (id === 'virtual:db3/apps') return '\0virtual:db3/apps'; },
|
|
14
|
+
/** Emits lazy browser imports; server entries never enter the client graph. */
|
|
15
|
+
load(id) {
|
|
16
|
+
if (id !== '\0virtual:db3/apps') return;
|
|
17
|
+
return `export default [${discoverApps(root).filter(app => app.client).map(app => `{ id: ${JSON.stringify(app.manifest.id)}, load: () => import(${JSON.stringify(app.client!.replaceAll('\\', '/'))}) }`).join(',')}];`;
|
|
18
|
+
},
|
|
19
|
+
/** Includes app-owned utility classes, including those shipped inside npm packages. */
|
|
20
|
+
transform(code, id) {
|
|
21
|
+
if (!id.endsWith('.css') || !code.includes('tailwindcss')) return;
|
|
22
|
+
const sources = discoverApps(root).filter(app => app.client).map(app => `@source ${JSON.stringify(app.directory.replaceAll('\\', '/'))};`);
|
|
23
|
+
return `${code}\n${sources.join('\n')}`;
|
|
24
|
+
},
|
|
25
|
+
/** Rebuilds the registry when folders or package installation metadata change in development. */
|
|
26
|
+
configureServer(server) {
|
|
27
|
+
server.watcher.add([`${root}/apps`, `${root}/package.json`]);
|
|
28
|
+
/** Restarts Vite only for discovery inputs; normal source changes retain regular HMR. */
|
|
29
|
+
const refresh = (path: string) => { if (path.endsWith('/manifest.json') || path === `${root}/package.json`) void server.restart(); };
|
|
30
|
+
server.watcher.on('add', refresh).on('unlink', refresh).on('change', refresh);
|
|
31
|
+
server.httpServer?.once('close', () => { server.watcher.off('add', refresh).off('unlink', refresh).off('change', refresh); });
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { defineCommand } from '../../cli';
|
|
2
|
+
import { listApps } from './listApps';
|
|
3
|
+
import { installApp } from './installApp';
|
|
4
|
+
import { enableApp } from './enableApp';
|
|
5
|
+
import { disableApp } from './disableApp';
|
|
6
|
+
import { uninstallApp } from './uninstallApp';
|
|
7
|
+
import { rollbackApp } from './rollbackApp';
|
|
8
|
+
import { makeAppMigration } from './makeAppMigration';
|
|
9
|
+
|
|
10
|
+
export { listApps, installApp, enableApp, disableApp, uninstallApp, makeAppMigration, rollbackApp };
|
|
11
|
+
|
|
12
|
+
/** CLI adapters for the same app-management operations used by programmatic and visual clients. */
|
|
13
|
+
export const appsCommands = [
|
|
14
|
+
defineCommand({ name: 'apps:list', description: 'Inspect app definitions and installation state.', handle: listApps }),
|
|
15
|
+
defineCommand({
|
|
16
|
+
name: 'apps:make-migration', description: 'Generate a local app migration without changing the database.',
|
|
17
|
+
parameters: [{ name: 'id', required: true }, { name: 'name', required: false }],
|
|
18
|
+
/** Delegates development source generation to the app-owned migration manager. */
|
|
19
|
+
handle: parameters => makeAppMigration(parameters.id!, parameters.name),
|
|
20
|
+
}),
|
|
21
|
+
...[
|
|
22
|
+
['install', installApp], ['enable', enableApp], ['disable', disableApp], ['uninstall', uninstallApp], ['rollback', rollbackApp],
|
|
23
|
+
].map(([action, operation]) => defineCommand({
|
|
24
|
+
name: `apps:${action}`, description: `${action} a registered app in a stopped maintenance process.`,
|
|
25
|
+
parameters: [{ name: 'id', required: true }],
|
|
26
|
+
/** Maps CLI input to the normal service action. */
|
|
27
|
+
handle: parameters => (operation as typeof installApp)(parameters.id!),
|
|
28
|
+
})),
|
|
29
|
+
];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { app } from '../../server';
|
|
2
|
+
|
|
3
|
+
/** Generates a frozen app-owned migration and snapshot in development, without applying DDL. */
|
|
4
|
+
export async function makeAppMigration(id: string, name?: string) {
|
|
5
|
+
await app().apps.load(id);
|
|
6
|
+
const manager = app().apps.migrations(id);
|
|
7
|
+
if (!manager) throw new Error(`App "${id}" has no database definition.`);
|
|
8
|
+
return manager.makeMigration({ name });
|
|
9
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { App } from '../../server/App';
|
|
2
|
+
import type { ActiveRecordClass } from '../../db';
|
|
3
|
+
import type { AppManifest } from './AppManifest';
|
|
4
|
+
import type { AppRoute } from './AppRoute';
|
|
5
|
+
import type { QueueableJobClass } from '../../queue';
|
|
6
|
+
import type { Schedule } from '../../scheduler';
|
|
7
|
+
import type { AppNavigation } from './AppNavigation';
|
|
8
|
+
import type { AppNavigationContext } from './AppNavigationContext';
|
|
9
|
+
|
|
10
|
+
/** Explicit contributions of one local or npm-distributed app. Importing it has no runtime effects. */
|
|
11
|
+
export interface AppDefinition<TService = unknown> {
|
|
12
|
+
manifest: AppManifest;
|
|
13
|
+
/** Creates one public service in the host runtime; never create a second framework App. */
|
|
14
|
+
create(host: App): TService;
|
|
15
|
+
/** App-owned models and immutable migration assets, resolved relative to the defining module. */
|
|
16
|
+
database?: {
|
|
17
|
+
models: readonly ActiveRecordClass[];
|
|
18
|
+
/** Directory containing migrations/ and schema.snapshot.json, in source or a published package. */
|
|
19
|
+
directory: URL;
|
|
20
|
+
};
|
|
21
|
+
/** Retry-safe app-owned setup after migrations have succeeded. */
|
|
22
|
+
afterInstall?(host: App): void | Promise<void>;
|
|
23
|
+
routes?: readonly AppRoute<TService>[];
|
|
24
|
+
/** Serializable job classes with explicit names beneath this app's id, such as social.review. */
|
|
25
|
+
jobs?: readonly QueueableJobClass[];
|
|
26
|
+
/** Synchronously declares recurring work for the enabled app during each process boot. */
|
|
27
|
+
schedule?(schedule: Schedule, service: TService): void;
|
|
28
|
+
/** Computes viewer-specific navigation. Undefined uses manifest links; null hides the app. */
|
|
29
|
+
navigation?(context: AppNavigationContext, service: TService): AppNavigation | null | undefined | Promise<AppNavigation | null | undefined>;
|
|
30
|
+
/** Starts resources after dependency services exist. Use defer immediately for failure-safe cleanup. */
|
|
31
|
+
start?(context: AppStartContext<TService>): void | Promise<void>;
|
|
32
|
+
/** Checks app-specific outstanding work before uninstall; throwing leaves the installation intact. */
|
|
33
|
+
beforeUninstall?(host: App): void | Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Resource ownership during startup. Cleanup runs in reverse registration order, including on failure. */
|
|
37
|
+
export interface AppStartContext<TService> {
|
|
38
|
+
host: App;
|
|
39
|
+
service: TService;
|
|
40
|
+
defer(cleanup: () => void | Promise<void>): void;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Explicit host composition, keyed by the matching manifest identifier. */
|
|
44
|
+
export type AppDefinitions = Readonly<Record<string, AppDefinition<any>>>;
|
|
45
|
+
|
|
46
|
+
/** Optional public service types inferred from the host's actual composition. */
|
|
47
|
+
export type AppServices<TDefinitions extends AppDefinitions> = {
|
|
48
|
+
readonly [K in keyof TDefinitions]: TDefinitions[K] extends AppDefinition<infer TService> ? TService | undefined : never;
|
|
49
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { AppManifest } from './AppManifest';
|
|
2
|
+
import type { ScheduledTaskDefinition } from '../../scheduler';
|
|
3
|
+
|
|
4
|
+
/** Durable installation state. Enabled installations become available only after a successful boot. */
|
|
5
|
+
export type AppInstallationState = 'enabled' | 'disabled' | 'uninstalled' | 'failed';
|
|
6
|
+
|
|
7
|
+
/** Inspectable app structure without constructors, secrets or filesystem paths. */
|
|
8
|
+
export interface AppDescription {
|
|
9
|
+
manifest: AppManifest;
|
|
10
|
+
registered: boolean;
|
|
11
|
+
state: AppInstallationState | 'available';
|
|
12
|
+
ready: boolean;
|
|
13
|
+
installedVersion: string | null;
|
|
14
|
+
models: { name: string; table: string }[];
|
|
15
|
+
routes: { method: string; path: string }[];
|
|
16
|
+
/** Stable durable job names owned by this app. */
|
|
17
|
+
jobs: string[];
|
|
18
|
+
/** Runtime declarations collected during boot; empty before the first boot. */
|
|
19
|
+
schedules: ScheduledTaskDefinition[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Browser renderer contract. The host supplies its own component type and routing implementation. */
|
|
23
|
+
export interface AppClientDefinition<TComponent> {
|
|
24
|
+
id: string;
|
|
25
|
+
/** Statically discoverable lazy import, allowing bundlers to keep server code out of browser assets. */
|
|
26
|
+
load(): Promise<{ default: TComponent }>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { AppNavigationBadge } from './AppNavigationBadge';
|
|
2
|
+
|
|
3
|
+
/** Browser-safe description of an app, shared by runtime, navigation and visual tools. */
|
|
4
|
+
export interface AppManifest {
|
|
5
|
+
/** Stable lowercase identifier; also owns the database and route namespaces. */
|
|
6
|
+
id: string;
|
|
7
|
+
name: string;
|
|
8
|
+
/** Stable semantic release version, for example 1.2.0. */
|
|
9
|
+
version: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
/** Plain text glyph or emoji. Render as text, never as HTML. */
|
|
12
|
+
icon?: string;
|
|
13
|
+
/** Public service contract generation, independent of package release version. */
|
|
14
|
+
apiVersion?: number;
|
|
15
|
+
/** Required app identifiers mapped to their exact public API generation. */
|
|
16
|
+
requires?: Readonly<Record<string, number>>;
|
|
17
|
+
/** Optional integrations; absent apps are allowed, incompatible installed apps are not. */
|
|
18
|
+
optional?: Readonly<Record<string, number>>;
|
|
19
|
+
/** Default destinations beneath /apps/{id}; a runtime navigation provider may replace these per viewer. */
|
|
20
|
+
navigation?: readonly AppMenuItem[];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** One app-owned navigation item; nesting is deliberately limited to one level. */
|
|
24
|
+
export interface AppMenuItem {
|
|
25
|
+
id: string;
|
|
26
|
+
label: string;
|
|
27
|
+
/** Empty string opens the app's main view; otherwise a simple relative path. */
|
|
28
|
+
path: string;
|
|
29
|
+
badge?: AppNavigationBadge;
|
|
30
|
+
/** Optional plain-text information about this destination. */
|
|
31
|
+
description?: string;
|
|
32
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AppMenuItem } from './AppManifest';
|
|
2
|
+
import type { AppNavigationBadge } from './AppNavigationBadge';
|
|
3
|
+
|
|
4
|
+
/** One app's current navigation contribution. Return null from the provider to hide the app for this viewer. */
|
|
5
|
+
export interface AppNavigation {
|
|
6
|
+
items: readonly AppMenuItem[];
|
|
7
|
+
badge?: AppNavigationBadge;
|
|
8
|
+
/** Short, plain-text information beneath the app's name. */
|
|
9
|
+
description?: string;
|
|
10
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Request-scoped identity supplied by the host after authentication and scope authorization. Never store it on an app singleton. */
|
|
2
|
+
export interface AppNavigationContext {
|
|
3
|
+
readonly actor: { readonly id: string };
|
|
4
|
+
/** Optional organisation already authorized by the host; apps must still enforce their own data permissions. */
|
|
5
|
+
readonly organisationId?: string;
|
|
6
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AppNavigation } from './AppNavigation';
|
|
2
|
+
|
|
3
|
+
/** Browser-safe contributions for one viewer. Results are request-scoped and must not be cached across users. */
|
|
4
|
+
export interface AppNavigationResult {
|
|
5
|
+
/** Registry-owned identity and public metadata attached to each successful contribution. */
|
|
6
|
+
apps: Array<AppNavigation & { appId: string; name: string; icon?: string }>;
|
|
7
|
+
/** Apps whose providers failed or returned invalid data. Their links are omitted without exposing error details. */
|
|
8
|
+
unavailable: string[];
|
|
9
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Transport-neutral authenticated request passed to an app-owned route. */
|
|
2
|
+
export interface AppRouteContext<TService> {
|
|
3
|
+
service: TService;
|
|
4
|
+
/** Identity established by the host adapter; never taken from a request body. */
|
|
5
|
+
actor: { id: string };
|
|
6
|
+
body: unknown;
|
|
7
|
+
params: Readonly<Record<string, string>>;
|
|
8
|
+
query: Readonly<Record<string, unknown>>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** One route mounted beneath /api/apps/{appId}; authorization remains mandatory in the adapter. */
|
|
12
|
+
export interface AppRoute<TService = unknown> {
|
|
13
|
+
method: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';
|
|
14
|
+
path: string;
|
|
15
|
+
/** HTTP success status; defaults to 200. */
|
|
16
|
+
status?: number;
|
|
17
|
+
handle(context: AppRouteContext<TService>): unknown | Promise<unknown>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AppManifest } from './AppManifest';
|
|
2
|
+
|
|
3
|
+
/** Metadata-only discovery result; reading it does not import the app's server or browser code. */
|
|
4
|
+
export interface DiscoveredApp {
|
|
5
|
+
manifest: AppManifest;
|
|
6
|
+
directory: string;
|
|
7
|
+
entry: string;
|
|
8
|
+
client?: string;
|
|
9
|
+
/** Direct npm dependency, absent for an in-project apps/{id} directory. */
|
|
10
|
+
packageName?: string;
|
|
11
|
+
}
|