1- import type Config from "#config/Config " ;
1+ import type EnvSchema from "#app/EnvSchema " ;
22import type ServerView from "#client/ServerView" ;
3+ import type Config from "#config/Config" ;
4+ import E from "#errors" ;
35import type ServeApp from "#serve/App" ;
46import dict from "@rcompat/dict" ;
7+ import env from "@rcompat/env" ;
8+ import type { ObjectType } from "pema" ;
9+ import ParseError from "pema/ParseError" ;
510
611const s_attach = Symbol ( "attach" ) ;
712const s_config = Symbol ( "config" ) ;
813
914export { s_attach , s_config } ;
1015
11- export default class AppFacade {
16+ type Env < P extends EnvSchema > = { [ K in keyof P ] : P [ K ] [ "infer" ] } ;
17+
18+ export default class AppFacade < T extends EnvSchema = EnvSchema > {
1219 #config: Config ;
1320 #app?: ServeApp ;
21+ #env?: Env < T > ;
1422
1523 constructor ( config : Config ) {
1624 this . #config = config ;
1725 }
1826
1927 [ s_attach ] ( app : ServeApp ) {
2028 this . #app = app ;
29+
30+ const schema = this . #config. env . schema as ObjectType < T > | undefined ;
31+ if ( schema !== undefined ) {
32+ try {
33+ this . #env = schema . coerce ( env . toJSON ( ) ) as Env < T > ;
34+ } catch ( error ) {
35+ if ( ParseError . is ( error ) ) throw E . env_invalid_schema ( error ) ;
36+ throw error ;
37+ }
38+ }
2139 }
2240
2341 get [ s_config ] ( ) {
@@ -28,6 +46,15 @@ export default class AppFacade {
2846 return dict . get ( this . #config, path ) ;
2947 }
3048
49+ env < K extends keyof T > ( key : K ) : T [ K ] [ "infer" ] ;
50+ env ( key : string ) : unknown {
51+ if ( this . #env !== undefined ) {
52+ if ( ! ( key in this . #env) ) throw E . env_missing_key ( key ) ;
53+ return this . #env[ key as keyof T ] ;
54+ }
55+ return env . get ( key ) ;
56+ }
57+
3158 get #with( ) {
3259 if ( ! this . #app) throw new Error ( "ServeApp not bound yet (used too early)" ) ;
3360 return this . #app;
0 commit comments