createFullStackAppFromConfig(build: (config: IConfig) => FullStackStarterOptions,options?: FromConfigOptions): Promise<IKernelApplication>
Creates a full-stack application whose options are derived from configuration.
Plugin options must be decided before the plugins are constructed, which is
before ConfigPlugin has registered anything — so an application that needs
a database URL from the environment cannot get it from
ctx.services.get(CAPABILITIES.CONFIG). This factory closes that ordering
gap: it builds runtime services, loads configuration once, hands the
snapshot to build, and passes that same snapshot into the application, so
the configuration the composition branched on is the configuration handlers
read.
It applies to every option uniformly, which is why no plugin option
carries a urlFromConfig-style config-key field: a per-option shorthand
would need the value at the same impossible moment.
Secrets are a different problem and this does not solve it: they are served
by secrets-plugin under CAPABILITIES.SECRETS, which exists only after
registration, so a plugin needing one resolves it lazily at use time.
Choosing a database and a mail provider from the environment
Choosing a database and a mail provider from the environment
import { createFullStackAppFromConfig } from '@setu-ts/full-stack-starter'; const app = await createFullStackAppFromConfig((config) => ({ database: { adapter: 'prisma', url: config.getOrThrow<string>('DATABASE_URL') }, mail: { provider: 'sendgrid', apiKey: config.getOrThrow<string>('SENDGRID_KEY') }, }), { config: { envFilePath: ['.env.local', '.env'] } }); app.router.get('/health', (ctx) => ctx.response.text('ok')); await app.start({ port: 3000 });
build: (config: IConfig) => FullStackStarterOptions
Derives the starter options from the loaded configuration. Called exactly once, before any plugin is constructed.
options: FromConfigOptions
Loading options and, on Cloudflare Workers, the request's
env bindings. See FromConfigOptions.env — omitting it there
yields an empty configuration.