@@ -33,20 +33,28 @@ export type EnvaseAwsConfigSchemaType = {
3333/**
3434 * Type for the computed credentials resolver function.
3535 */
36- export type EnvaseAwsConfigComputedType = {
37- credentials : ( raw : {
38- accessKeyId ?: string
39- secretAccessKey ?: string
40- } ) => AwsCredentialIdentity | Provider < AwsCredentialIdentity >
36+ export type EnvaseAwsConfigComputedType < TRaw = { accessKeyId ?: string ; secretAccessKey ?: string } > =
37+ {
38+ credentials : ( raw : TRaw ) => AwsCredentialIdentity | Provider < AwsCredentialIdentity >
39+ }
40+
41+ /**
42+ * Options for `getEnvaseAwsConfig()`.
43+ */
44+ export type EnvaseAwsConfigOptions < TPath extends string | undefined = undefined > = {
45+ /** The key under which AWS schema is nested in your config. Omit for flat spread at root level. */
46+ path ?: TPath
4147}
4248
4349/**
4450 * Return type of `getEnvaseAwsConfig()`.
4551 * Contains schema and computed fragments to spread into `createConfig()`.
4652 */
47- export type EnvaseAwsConfigFragments = {
53+ export type EnvaseAwsConfigFragments < TPath extends string | undefined = undefined > = {
4854 schema : EnvaseAwsConfigSchemaType
49- computed : EnvaseAwsConfigComputedType
55+ computed : TPath extends string
56+ ? EnvaseAwsConfigComputedType < Record < TPath , { accessKeyId ?: string ; secretAccessKey ?: string } > >
57+ : EnvaseAwsConfigComputedType
5058}
5159
5260/**
@@ -96,19 +104,32 @@ const envaseAwsConfigSchema: EnvaseAwsConfigSchemaType = {
96104}
97105
98106/**
99- * Computed values configuration for AWS config.
107+ * Creates computed values configuration for AWS config.
100108 * Derives `credentials` from the parsed `accessKeyId` and `secretAccessKey`.
101109 */
102- const envaseAwsConfigComputed : EnvaseAwsConfigComputedType = {
103- credentials : ( raw : {
110+ function createAwsComputed < TPath extends string | undefined > (
111+ path ?: TPath ,
112+ ) : EnvaseAwsConfigFragments < TPath > [ 'computed' ] {
113+ const resolveCredentials = ( awsRaw : {
104114 accessKeyId ?: string
105115 secretAccessKey ?: string
106116 } ) : AwsCredentialIdentity | Provider < AwsCredentialIdentity > => {
107- if ( raw . accessKeyId && raw . secretAccessKey ) {
108- return { accessKeyId : raw . accessKeyId , secretAccessKey : raw . secretAccessKey }
117+ if ( awsRaw . accessKeyId && awsRaw . secretAccessKey ) {
118+ return { accessKeyId : awsRaw . accessKeyId , secretAccessKey : awsRaw . secretAccessKey }
109119 }
110120 return createCredentialChain ( fromTokenFile ( ) , fromInstanceMetadata ( ) , fromEnv ( ) , fromIni ( ) )
111- } ,
121+ }
122+
123+ if ( path ) {
124+ return {
125+ // biome-ignore lint/suspicious/noExplicitAny: raw config shape depends on consumer's schema
126+ credentials : ( raw : any ) => resolveCredentials ( raw [ path ] ) ,
127+ } as EnvaseAwsConfigFragments < TPath > [ 'computed' ]
128+ }
129+
130+ return {
131+ credentials : resolveCredentials ,
132+ } as EnvaseAwsConfigFragments < TPath > [ 'computed' ]
112133}
113134
114135/**
@@ -118,13 +139,17 @@ const envaseAwsConfigComputed: EnvaseAwsConfigComputedType = {
118139 * your application's configuration. This allows composing AWS config with other
119140 * application-specific configuration.
120141 *
142+ * Use the `path` option when nesting AWS config under a key (e.g., `aws`),
143+ * so that computed resolvers access `fullParsedConfig.aws` instead of `fullParsedConfig`.
144+ *
121145 * @example
122146 * ```typescript
123147 * import { createConfig, envvar } from 'envase'
124148 * import { z } from 'zod'
125149 * import { getEnvaseAwsConfig } from '@lokalise/aws-config'
126150 *
127- * const awsConfig = getEnvaseAwsConfig()
151+ * // Nested under 'aws' key (recommended):
152+ * const awsConfig = getEnvaseAwsConfig({ path: 'aws' })
128153 *
129154 * const config = createConfig(process.env, {
130155 * schema: {
@@ -137,6 +162,8 @@ const envaseAwsConfigComputed: EnvaseAwsConfigComputedType = {
137162 * })
138163 *
139164 * // Or spread directly at root level:
165+ * const awsConfig = getEnvaseAwsConfig()
166+ *
140167 * const config = createConfig(process.env, {
141168 * schema: {
142169 * ...awsConfig.schema,
@@ -148,11 +175,14 @@ const envaseAwsConfigComputed: EnvaseAwsConfigComputedType = {
148175 * })
149176 * ```
150177 *
178+ * @param options - Optional configuration. Use `path` to specify the nesting key.
151179 * @returns Schema and computed fragments for AWS configuration
152180 */
153- export const getEnvaseAwsConfig = ( ) : EnvaseAwsConfigFragments => {
181+ export function getEnvaseAwsConfig < TPath extends string | undefined = undefined > (
182+ options ?: EnvaseAwsConfigOptions < TPath > ,
183+ ) : EnvaseAwsConfigFragments < TPath > {
154184 return {
155185 schema : envaseAwsConfigSchema ,
156- computed : envaseAwsConfigComputed ,
186+ computed : createAwsComputed ( options ?. path ) ,
157187 }
158188}
0 commit comments