effect
effect copied to clipboard
Config provider Deno support
What is the problem this feature would solve?
Deno has a different api for accessing the environment variables.
There is no process.env.
https://github.com/Effect-TS/effect/blob/ee7abb75d91d7c1c673935db254af0d4a6eb591d/src/internal/configProvider.ts#L106
What is the feature you are proposing to solve the problem?
Support Deno out of box for config provider. I'm willing to contribute.
What alternatives have you considered?
Using the ConfigProvider.fromMap and manually passing the Deno env is an option, but
- you have to set env variables one by one
- or grant access the whole env reading in Deno.
How would supporting Deno look like?
Haven't tried, but something like this should work:
diff --git a/src/internal/configProvider.ts b/src/internal/configProvider.ts
index 44af3ae58..6de804e54 100644
--- a/src/internal/configProvider.ts
+++ b/src/internal/configProvider.ts
@@ -95,6 +95,37 @@ export const fromFlat = (flat: ConfigProvider.ConfigProvider.Flat): ConfigProvid
flattened: flat
})
+interface Environment {
+ getVariable(name: string): string | undefined;
+ getAllVariables(): { [key: string]: string | undefined; }
+}
+
+interface DenoRuntime {
+ Deno: {
+ env: {
+ get(key: string): string | undefined;
+ toObject(): { [index: string]: string; };
+ }
+ }
+}
+
+const isDenoRuntime = (runtime: {}): runtime is DenoRuntime => 'Deno' in runtime
+
+const getEnvironment = (): Environment => {
+ const runtime = globalThis;
+ if (isDenoRuntime(runtime)) {
+ return {
+ getVariable: (name) => runtime.Deno.env.get(name),
+ getAllVariables: () => runtime.Deno.env.toObject(),
+ }
+ }
+
+ return {
+ getVariable: (name) => process.env[name],
+ getAllVariables: () => process.env,
+ }
+}
+
/** @internal */
export const fromEnv = (
config: Partial<ConfigProvider.ConfigProvider.FromEnvConfig> = {}
@@ -103,17 +134,14 @@ export const fromEnv = (
const makePathString = (path: ReadonlyArray<string>): string => pipe(path, RA.join(pathDelim))
const unmakePathString = (pathString: string): ReadonlyArray<string> => pathString.split(pathDelim)
- const getEnv = () =>
- typeof process !== "undefined" && "env" in process && typeof process.env === "object" ? process.env : {}
-
const load = <A>(
path: ReadonlyArray<string>,
primitive: Config.Config.Primitive<A>,
split = true
): Effect.Effect<never, ConfigError.ConfigError, ReadonlyArray<A>> => {
const pathString = makePathString(path)
- const current = getEnv()
- const valueOpt = pathString in current ? Option.some(current[pathString]!) : Option.none()
+ const current = getEnvironment()
+ const valueOpt = Option.fromNullable(current.getVariable(pathString)) // this is doing a different thing, but otherwise you have to grant access to all env in Deno
return pipe(
valueOpt,
core.mapError(() => configError.MissingData(path, `Expected ${pathString} to exist in the process context`)),
@@ -125,8 +153,8 @@ export const fromEnv = (
path: ReadonlyArray<string>
): Effect.Effect<never, ConfigError.ConfigError, HashSet.HashSet<string>> =>
core.sync(() => {
- const current = getEnv()
- const keys = Object.keys(current)
+ const current = getEnvironment()
+ const keys = Object.keys(current.getAllVariables())
const keyPaths = Array.from(keys).map((value) => unmakePathString(value.toUpperCase()))
const filteredKeyPaths = keyPaths.filter((keyPath) => {
for (let i = 0; i < path.length; i++) {
If you want to open a PR I'd be happy to review & merge
I'm glad you are open to support Deno. I'll submit a PR then, just have to figure out some things. For example how to test the project with Deno.
cc @fubhy who's proposing a multi-runtime test matrix
I can add a PR for the test matrix later today.