Derives the starter options from the loaded configuration. Called exactly once, before any plugin is constructed.
Optionaloptions: FromConfigOptions
Loading options and, on Cloudflare Workers, the request's
env bindings. See FromConfigOptions.env — omitting it there
yields an empty configuration.
The configured, un-started application
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 });
Creates a full-stack application whose options are derived from configuration.
Plugin options must be decided before the plugins are constructed, which is before
ConfigPluginhas registered anything — so an application that needs a database URL from the environment cannot get it fromctx.services.get(CAPABILITIES.CONFIG). This factory closes that ordering gap: it builds runtime services, loads configuration once, hands the snapshot tobuild, 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-pluginunderCAPABILITIES.SECRETS, which exists only after registration, so a plugin needing one resolves it lazily at use time.