{"_id":"@db3.ai/app","name":"@db3.ai/app","dist-tags":{"next":"0.1.0-beta.1","latest":"0.1.0-beta.1"},"versions":{"0.1.0-beta.1":{"name":"@db3.ai/app","version":"0.1.0-beta.1","description":"A typed backend application framework with service-owned runtime modules and behavioural contracts.","license":"MIT","type":"module","homepage":"https://db3.ai/","keywords":["db3","typescript","backend","framework","active-record","queue","ssr"],"engines":{"node":">=20"},"bin":{"db3-agents":"bin/db3-agents.mjs","db3":"bin/db3.mjs"},"exports":{"./ai":{"types":"./dist/ai/index.d.ts","import":"./dist/ai/index.js","default":"./dist/ai/index.js"},".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./agent-instructions":"./agent-instructions.md","./auth":{"types":"./dist/auth/index.d.ts","import":"./dist/auth/index.js","default":"./dist/auth/index.js"},"./auth/password-hash":{"types":"./dist/auth/passwordHash.d.ts","import":"./dist/auth/passwordHash.js","default":"./dist/auth/passwordHash.js"},"./cache":{"types":"./dist/cache/index.d.ts","import":"./dist/cache/index.js","default":"./dist/cache/index.js"},"./cli":{"types":"./dist/cli/index.d.ts","import":"./dist/cli/index.js","default":"./dist/cli/index.js"},"./db":{"types":"./dist/db/index.d.ts","import":"./dist/db/index.js","default":"./dist/db/index.js"},"./db/commands":{"types":"./dist/db/commands/index.d.ts","import":"./dist/db/commands/index.js","default":"./dist/db/commands/index.js"},"./db/ActiveProjection":{"types":"./dist/db/ActiveProjection.d.ts","import":"./dist/db/ActiveProjection.js","default":"./dist/db/ActiveProjection.js"},"./db/ActiveRecord":{"types":"./dist/db/ActiveRecord.d.ts","import":"./dist/db/ActiveRecord.js","default":"./dist/db/ActiveRecord.js"},"./db/ActiveQueryBuilder":{"types":"./dist/db/ActiveQueryBuilder.d.ts","import":"./dist/db/ActiveQueryBuilder.js","default":"./dist/db/ActiveQueryBuilder.js"},"./db/Database":{"types":"./dist/db/Database.d.ts","import":"./dist/db/Database.js","default":"./dist/db/Database.js"},"./db/FieldType":{"types":"./dist/db/FieldType.d.ts","import":"./dist/db/FieldType.js","default":"./dist/db/FieldType.js"},"./db/connection":{"types":"./dist/db/connection.d.ts","import":"./dist/db/connection.js","default":"./dist/db/connection.js"},"./db/dialects":{"types":"./dist/db/dialects/index.d.ts","import":"./dist/db/dialects/index.js","default":"./dist/db/dialects/index.js"},"./db/fields":{"types":"./dist/db/fields/index.d.ts","import":"./dist/db/fields/index.js","default":"./dist/db/fields/index.js"},"./db/fields/*":{"types":"./dist/db/fields/*.d.ts","import":"./dist/db/fields/*.js","default":"./dist/db/fields/*.js"},"./db/migrations":{"types":"./dist/db/migrations/index.d.ts","import":"./dist/db/migrations/index.js","default":"./dist/db/migrations/index.js"},"./db/queryMonitor":{"types":"./dist/db/queryMonitor.d.ts","import":"./dist/db/queryMonitor.js","default":"./dist/db/queryMonitor.js"},"./db/test/db":{"types":"./dist/db/test/db.d.ts","import":"./dist/db/test/db.js","default":"./dist/db/test/db.js"},"./config":{"types":"./dist/config/index.d.ts","import":"./dist/config/index.js","default":"./dist/config/index.js"},"./events":{"types":"./dist/events/index.d.ts","import":"./dist/events/index.js","default":"./dist/events/index.js"},"./flows":{"types":"./dist/flows/index.d.ts","import":"./dist/flows/index.js","default":"./dist/flows/index.js"},"./flows/blocks":{"types":"./dist/flows/blocks/index.d.ts","import":"./dist/flows/blocks/index.js","default":"./dist/flows/blocks/index.js"},"./url":{"types":"./dist/url/index.d.ts","import":"./dist/url/index.js","default":"./dist/url/index.js"},"./mail":{"types":"./dist/mail/index.d.ts","import":"./dist/mail/index.js","default":"./dist/mail/index.js"},"./logging":{"types":"./dist/logging/index.d.ts","import":"./dist/logging/index.js","default":"./dist/logging/index.js"},"./media":{"types":"./dist/media/index.d.ts","import":"./dist/media/index.js","default":"./dist/media/index.js"},"./media/image":{"types":"./dist/media/image/index.d.ts","import":"./dist/media/image/index.js","default":"./dist/media/image/index.js"},"./queue":{"types":"./dist/queue/index.d.ts","import":"./dist/queue/index.js","default":"./dist/queue/index.js"},"./queue/commands":{"types":"./dist/queue/commands/index.d.ts","import":"./dist/queue/commands/index.js","default":"./dist/queue/commands/index.js"},"./scheduler":{"types":"./dist/scheduler/index.d.ts","import":"./dist/scheduler/index.js","default":"./dist/scheduler/index.js"},"./security":{"types":"./dist/security/index.d.ts","import":"./dist/security/index.js","default":"./dist/security/index.js"},"./serialization":{"types":"./dist/serialization/index.d.ts","import":"./dist/serialization/index.js","default":"./dist/serialization/index.js"},"./server":{"types":"./dist/server/index.d.ts","import":"./dist/server/index.js","default":"./dist/server/index.js"},"./ssr":{"types":"./dist/ssr/index.d.ts","import":"./dist/ssr/index.js","default":"./dist/ssr/index.js"},"./ssr/fastify":{"types":"./dist/ssr/fastify/index.d.ts","import":"./dist/ssr/fastify/index.js","default":"./dist/ssr/fastify/index.js"},"./ssr/vite":{"types":"./dist/ssr/vite/index.d.ts","import":"./dist/ssr/vite/index.js","default":"./dist/ssr/vite/index.js"},"./storage":{"types":"./dist/storage/index.d.ts","import":"./dist/storage/index.js","default":"./dist/storage/index.js"},"./validation":{"types":"./dist/validation/index.d.ts","import":"./dist/validation/index.js","default":"./dist/validation/index.js"}},"dependencies":{"tsx":"^4.22.4","openai":"^6.44.0","@aws-sdk/client-s3":"^3.1077.0","@flystorage/aws-s3":"^1.2.0","@flystorage/file-storage":"^1.2.2","@flystorage/local-fs":"^1.2.0","@keyv/redis":"^5.1.6","@db3.ai/pure":"0.1.0-beta.1","@redis/client":"^6.1.0","cache-manager":"^7.2.9","cacheable":"^2.5.0","dotenv":"^17.4.2","knex":"^3.2.10","mysql2":"^3.22.5","pino":"^10.3.1","pino-abstract-transport":"^3.0.0","sharp":"^0.35.4","thread-stream":"^4.0.0","zod":"^4.4.3","@openai/agents":"0.12.1"},"peerDependencies":{"@fastify/middie":"^9.3.3","@fastify/static":"^10.1.3","fastify":"^5.11.3","vite":"^8.2.1"},"peerDependenciesMeta":{"@fastify/middie":{"optional":true},"@fastify/static":{"optional":true},"fastify":{"optional":true},"vite":{"optional":true}},"main":"./dist/index.js","types":"./dist/index.d.ts","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/","provenance":true},"repository":{"type":"git","url":"git+https://github.com/db3ai/framework.git","directory":"packages/app"},"_id":"@db3.ai/app@0.1.0-beta.1","bugs":{"url":"https://github.com/db3ai/framework/issues"},"_nodeVersion":"24.15.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-hdCDQP6YqErouTPUMgXaUEg0p7dn980Yn1fpxYBFdOZl/lPHwkpDFI96YQuIZqVjhMqu2XptZqeFp1URmbXImQ==","shasum":"a93687bee4560fc751b2fd549df0aa608d7f05eb","tarball":"https://registry.npmjs.org/@db3.ai/app/-/app-0.1.0-beta.1.tgz","fileCount":1024,"unpackedSize":3456671,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCv+xtuk2HLpkzP7KJNzKk8QPWSsOJ7niYm2MHdiXMq1wIhALnMsJuqR1WJua2e8RiKINTS9AGRKrxVHEK9y9uP7Y90"}]},"_npmUser":{"name":"steven.a.obrien","email":"steven.a.obrien@gmail.com"},"directories":{},"maintainers":[{"name":"steven.a.obrien","email":"steven.a.obrien@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/app_0.1.0-beta.1_1789223603847_0.5394744250948194"},"_hasShrinkwrap":false}},"time":{"created":"2026-09-12T14:33:23.656Z","0.1.0-beta.1":"2026-09-12T14:33:24.014Z","modified":"2026-09-12T14:33:24.264Z"},"maintainers":[{"name":"steven.a.obrien","email":"steven.a.obrien@gmail.com"}],"description":"A typed backend application framework with service-owned runtime modules and behavioural contracts.","homepage":"https://db3.ai/","keywords":["db3","typescript","backend","framework","active-record","queue","ssr"],"repository":{"type":"git","url":"git+https://github.com/db3ai/framework.git","directory":"packages/app"},"bugs":{"url":"https://github.com/db3ai/framework/issues"},"license":"MIT","readme":"# @db3.ai/app\n\nShared backend framework package for DB3 applications.\n\nThe framework is intended to support both code-first and visual application\ndevelopment. Framework operations should expose reusable contracts so CLI,\nGUI, programmatic, and collaborative AI clients can share the same behavior\nrather than creating parallel implementations. Source-repository contributors\ncan read the product direction in `docs/framework-goals.md`; that repository-only\ndocument is not part of the installed runtime package.\n\nThis package owns reusable runtime services and data-layer mechanics:\n\n- `config`: explicit config repositories and environment parsing helpers.\n- `cli`: shared `db3` commands, interactive app REPL, service registration, help and app lifecycle.\n- `cache`: named cache stores and driver-backed value lifecycles.\n- `events`: synchronous and asynchronous in-process event dispatch.\n- `logging`: structured application logging and development-tool delivery.\n- `server`: `App`, service discovery, request context, and database wiring.\n- `db`: ActiveRecord, FieldType, projections, schema installation, and SQL error helpers.\n- `validation`: request-data validation for routes, services, and jobs.\n- `auth`: user identity, configurable auth providers, auth tokens, password reset tokens, and password hashing.\n- `ai`: agents with function calls, streaming, durable conversations, provider request tracking, images, embeddings, structured output and failover.\n- `queue`: database-backed dispatch, handlers, job classes, retry/failure records, and workers.\n- `serialization`: registered root-constructor serialization from ordinary JSON state, with ActiveRecord identity references as the only special nested value.\n- `scheduler`: code-owned daily schedules, durable occurrence claims, queue correlation, and a dedicated worker.\n- `flows`: code-backed graph definitions, queue orchestration, durable block observability, nested flows, and replay.\n- `mail`: file, Mailgun, and Resend mail transports.\n- `storage`: named local and S3-compatible disks, streams, transfers and scoped file operations.\n- `media`: scoped media libraries, managed file ULIDs, and browser-visible folder trees.\n- `security`: central key configuration and versioned authenticated encryption for application secrets.\n- `ssr`: optional render contracts, document assembly, safe hydration state, and Fastify adaptation for public HTML.\n- `url`: canonical base-URL configuration and standard URL resolution, without a named-route registry.\n\nKeep app-specific behavior in `apps/*`. Move code here only when it is reusable framework behavior.\n\n## Installation\n\nAfter the first public release, install the framework runtime with:\n\n```sh\nnpm install @db3.ai/app\n```\n\nInstall optional Fastify or Vite peer packages only when using their matching\nSSR adapters.\n\n## Publishing status\n\nThe framework is MIT licensed; private applications sharing the development\nrepository are excluded by the licence scope. Public framework source belongs\nin `github.com/db3ai/framework`. The published packages are `@db3.ai/app`,\n`@db3.ai/pure` and `@db3.ai/create`. Maintainers can publish a verified beta from\nthe repository root with `npm run framework:publish -- --version 0.1.0-beta.1`;\nadd `--dry-run` to inspect it without publishing. npm handles packaging, login\nand upload. See `docs/framework-release.md` for release checks and the manual\nbootstrap and trusted-publishing workflows.\n\nThe [installation guide](https://db3.ai/docs/installation) distinguishes the\nunpublished preview tarballs from the future npm install command. The\n[first app](https://db3.ai/docs/create-app) uses the shipped\n`src/server/examples` files to run and test an independent Fastify application.\nAuth, Storage, Media and Scheduler also ship their service-owned examples.\n\n## Consumer package artifacts\n\nFrom the repository root, stage both compiled packages and run the clean\nconsumer install gate with:\n\n```sh\nnpm run framework:package\nnpm run framework:package:test\n```\n\nThe first command writes publish-shaped packages to\n`dist/framework-packages/pure` and `dist/framework-packages/app`. The second\npacks both directories, installs the tarballs in a temporary project, imports\nevery public runtime subpath, type-checks representative declarations, verifies\ninstalled Markdown links, and exercises the `db3-agents` scaffold.\n\nThe workspace manifests intentionally keep their source exports for monorepo\ndevelopment; only the staged manifests target compiled JavaScript and\ndeclarations. Workspace manifests, runtime imports, examples, documentation,\nand consumer artifacts all use the same `@db3.ai/*` package names.\nThe ordinary staged manifest omits the private monorepo repository identity.\nRelease-mode staging requires the exact dedicated public framework repository\nand rejects ambiguous or non-GitHub URLs. Candidate preparation also requires\nboth checked-in versions and App's exact Pure dependency to match the requested\ntag; it does not rewrite versions. Always prepare Pure before App because App\ndepends on the matching Pure version. These commands do not publish either\npackage.\n\nnpm provenance requires a public repository whose package `repository.url`\nmatches the GitHub source exactly. Once that repository is established, publish\nfrom its trusted GitHub Actions workflow so npm can attach provenance without a\nlong-lived publish token.\n\nThe eventual public workflow must supply its exact canonical source URL through\neither the option or environment variable below:\n\n```sh\nnpm run framework:package -- --repository-url git+https://github.com/OWNER/REPOSITORY.git\nDB3_FRAMEWORK_REPOSITORY_URL=git+https://github.com/OWNER/REPOSITORY.git npm run framework:package\n```\n\nOnly canonical public GitHub URLs are accepted. In this explicit release mode,\nthe staged manifests include package-directory repository metadata and enable\n`publishConfig.provenance`; neither command publishes a package.\n\n## Testing\n\nFramework tests live with the service they exercise under\n`src/{service}/tests`. Run the complete package suite before considering a\nframework change finished:\n\n```sh\nnpm run check --workspace packages/app\nnpm test --workspace packages/app\n```\n\nRun one service while developing a focused change by passing its directory\nname to the service runner:\n\n```sh\nnpm run test:service --workspace packages/app -- queue\n```\n\nThe service runner fails when the service does not have a test directory, so a\nmisspelled or stale service name cannot produce an accidental green result.\nCoverage uses the same complete suite and enforces package-wide regression\nfloors of 75% statements, 65% branches, 80% functions, and 77% lines:\n\n```sh\nnpm run test:coverage --workspace packages/app\n```\n\nThe test scripts optionally load connection credentials from the package-owned\n`packages/app/.env.test` file, then force `NODE_ENV=test`,\n`DB_DATABASE=db3_app_test`, and `DB_TEST_DATABASE_PREFIX=db3_app_test`.\nStart from the committed example when local credentials are needed:\n\n```sh\ncp packages/app/.env.test.example packages/app/.env.test\n```\n\nFramework integration suites create and remove unique disposable databases\nunder that test-only namespace. They do not read application configuration or connect\nto an application's named database. A `DATABASE_URL` supplied by CI must itself\ntarget `db3_app_test` (or a disposable database with that prefix). The configured\ndatabase server must be reachable for the complete suite and service suites that\nown database integration tests.\n\nRedis Queue integration tests use `QUEUE_REDIS_URL` or the separate\n`QUEUE_REDIS_HOST` and `QUEUE_REDIS_PORT` settings. They skip during an ordinary\nlocal run when Redis is unavailable. A release gate must prove the Redis driver\nagainst a real server and fail instead of skipping it:\n\n```sh\nnpm run test:release --workspace packages/app\n```\n\nThe release command runs the source and example type checks followed by the\ncomplete coverage suite. It sets `TEST_REDIS_REQUIRED=1`, so an unreachable\nRedis server is a failure rather than a conditional skip.\n\nTests should exercise public typed contracts and observable behaviour with real\nframework components. Mock only external provider boundaries, and cover failure,\nretry, cleanup, and lifecycle behaviour when those outcomes are part of the\nservice contract. Public API changes also require a consumer type check through\nthe exported package subpath; importing a private source file is not sufficient.\nWhen a service supports multiple drivers, apply the same behavioural contract to\neach supported driver where practical, and require its external infrastructure\nin the release gate instead of accepting a skipped suite as proof.\n\nThe richer guide at [db3.ai](https://db3.ai/) includes dedicated sections for\nMail, Queue, creating jobs, and queue workers.\n\nSee [src/cli/README.md](./src/cli/README.md) for the shared `db3` executable and\nservice command registration. Generated apps configure it in `server/cli.config.ts`;\ndatabase commands are owned by DB and job generation is owned by Queue.\n\nSee [src/flows/README.md](./src/flows/README.md) for flow definitions, block contracts, file providers, durable run models, nested execution, and replay.\n\nSee [src/scheduler/README.md](./src/scheduler/README.md) for scheduled jobs,\ninline calls, durable deduplication, occurrence history, and process commands.\n\nSee [src/serialization/README.md](./src/serialization/README.md) for\n`app().serializer`, registry configuration, supported values, and ActiveRecord\nreference semantics.\n\nSee [src/security/README.md](./src/security/README.md) for `app().security`,\napplication-key configuration, authenticated encryption, and encrypted JSON\nmodel fields.\n\nSee [src/ssr/README.md](./src/ssr/README.md) for the optional server-rendering\nboundary, document markers, request isolation, and Fastify adapter.\n\n## Auth Providers\n\n`packages/app/src/auth` treats the user row as the account and `auth_providers`\nrows as the ways that account can authenticate. Provider-specific code lives in\n`packages/app/src/auth/providers`: the built-in `password` provider stores\npassword credentials in `auth_providers`, while the Google provider verifies\nGoogle ID tokens and stores only safe profile claims.\n\nApps configure supported providers through the app config repository at\n`auth.providers`:\n\n```ts\nimport {\n\tGOOGLE_AUTH_PROVIDER,\n\tPASSWORD_AUTH_PROVIDER,\n} from '@db3.ai/app/auth';\n\nconst app = new App({\n\tconfig: {\n\t\tauth: {\n\t\t\tproviders: {\n\t\t\t\t[PASSWORD_AUTH_PROVIDER]: {\n\t\t\t\t\tdriver: PASSWORD_AUTH_PROVIDER,\n\t\t\t\t},\n\t\t\t\t[GOOGLE_AUTH_PROVIDER]: {\n\t\t\t\t\tdriver: GOOGLE_AUTH_PROVIDER,\n\t\t\t\t\tclientIds: ['google-client-id.apps.googleusercontent.com'],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t},\n});\n```\n\nTests and advanced apps may also pass concrete provider driver instances through\n`AppOptions.auth.providers`.\n\nProvider rows can be listed, linked, and unlinked through the auth service. The\nframework refuses to unlink the final provider for a user so every account keeps\nat least one usable login method.\n\nSee [src/auth/README.md](./src/auth/README.md) for the account/provider mental\nmodel, route and session examples, provider management, custom drivers, security\nresponsibilities, and complete password and Google setup instructions.\n","readmeFilename":"README.md","_rev":"1-68d5b298633a0f6ad96ef9cf1dae448f"}