| 102 | |
| 103 | /** @internal */ |
| 104 | export const fromEnv = ( |
| 105 | options?: Partial<ConfigProvider.ConfigProvider.FromEnvConfig> |
| 106 | ): ConfigProvider.ConfigProvider => { |
| 107 | const { pathDelim, seqDelim } = Object.assign({}, { pathDelim: "_", seqDelim: "," }, options) |
| 108 | const makePathString = (path: ReadonlyArray<string>): string => pipe(path, Arr.join(pathDelim)) |
| 109 | const unmakePathString = (pathString: string): ReadonlyArray<string> => pathString.split(pathDelim) |
| 110 | |
| 111 | const getEnv = () => |
| 112 | typeof process !== "undefined" && "env" in process && typeof process.env === "object" ? process.env : {} |
| 113 | |
| 114 | const load = <A>( |
| 115 | path: ReadonlyArray<string>, |
| 116 | primitive: Config.Config.Primitive<A>, |
| 117 | split = true |
| 118 | ): Effect.Effect<Array<A>, ConfigError.ConfigError> => { |
| 119 | const pathString = makePathString(path) |
| 120 | const current = getEnv() |
| 121 | const valueOpt = pathString in current ? Option.some(current[pathString]!) : Option.none() |
| 122 | return pipe( |
| 123 | valueOpt, |
| 124 | core.mapError(() => configError.MissingData(path, `Expected ${pathString} to exist in the process context`)), |
| 125 | core.flatMap((value) => parsePrimitive(value, path, primitive, seqDelim, split)) |
| 126 | ) |
| 127 | } |
| 128 | |
| 129 | const enumerateChildren = ( |
| 130 | path: ReadonlyArray<string> |
| 131 | ): Effect.Effect<HashSet.HashSet<string>, ConfigError.ConfigError> => |
| 132 | core.sync(() => { |
| 133 | const current = getEnv() |
| 134 | const keys = Object.keys(current) |
| 135 | const keyPaths = keys.map((value) => unmakePathString(value.toUpperCase())) |
| 136 | const filteredKeyPaths = keyPaths.filter((keyPath) => { |
| 137 | for (let i = 0; i < path.length; i++) { |
| 138 | const pathComponent = pipe(path, Arr.unsafeGet(i)) |
| 139 | const currentElement = keyPath[i] |
| 140 | if (currentElement === undefined || pathComponent !== currentElement) { |
| 141 | return false |
| 142 | } |
| 143 | } |
| 144 | return true |
| 145 | }).flatMap((keyPath) => keyPath.slice(path.length, path.length + 1)) |
| 146 | return HashSet.fromIterable(filteredKeyPaths) |
| 147 | }) |
| 148 | |
| 149 | return fromFlat(makeFlat({ load, enumerateChildren, patch: pathPatch.empty })) |
| 150 | } |
| 151 | |
| 152 | /** @internal */ |
| 153 | export const fromMap = ( |