Skip to content

Commit 50e0f25

Browse files
authored
feat(config): load config by detecting environment from NODE_ENV (#171)
* feat(config): load configuration based on NODE_ENV environment variable * docs(config): add loadConfigFromNodeEnv() example * refactor: move loadConfigFromNodeEnv() to Chains.loadFromNodeEnv() * docs: update README examples * refactor: import with a "package name" config
1 parent 533ded9 commit 50e0f25

File tree

4 files changed

+90
-42
lines changed

4 files changed

+90
-42
lines changed

packages/config/README.md

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,20 @@ npm install --save @streamr/config
1313
## Examples
1414
Import DATA token production Ethereum address as a variable in a Typescript project:
1515
```typescript
16-
import { Chains } from "index"
16+
import * as config from "config"
1717

18-
const config: Chains = Chains.load("production")
19-
const contractAddress: string = config.ethereum.contracts["DATA-token"]
20-
const chainId: number = config.ethereum.id
21-
const rpcHttpUrl: string = config.ethereum.rpcHttpUrl
22-
const rpcWsUrl: string = config.ethereum.rpcWsUrl
18+
const chains: config.Chains = config.Chains.load("production")
19+
const contractAddress: string = chains.ethereum.contracts["DATA-token"]
20+
const chainId: number = chains.ethereum.id
21+
const httpRpcEndpoints: RPCEndpoint[] = chains.ethereum.getRPCEndpointsByProtocol(RPCProtocol.HTTP)
22+
const wsRpcEndpoints: RPCEndpoint[] = chains.ethereum.getRPCEndpointsByProtocol(RPCProtocol.WEBSOCKET)
23+
```
24+
25+
You can also load configuration based on `$NODE_ENV` environment variable:
26+
```typescript
27+
import * as config from "config"
28+
29+
const chains: Chains = config.Chains.loadFromNodeEnv()
2330
```
2431

2532
Other languages can read the [JSON file](./src/networks.json) directly.

packages/config/src/index.ts renamed to packages/config/src/config.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,17 @@ export class Chains implements ChainsJSON {
8181
const chains: Chains = ChainsFactory.create(chainsJson)
8282
return chains
8383
}
84+
public static loadFromNodeEnv(): Chains {
85+
const nodeEnv = process.env.NODE_ENV
86+
if (nodeEnv === undefined) {
87+
throw new Error("NODE_ENV environment variable is not set")
88+
}
89+
if (nodeEnv !== "production" && nodeEnv !== "development") {
90+
throw new Error("NODE_ENV environment variable value must be either 'production' or 'development'")
91+
}
92+
const env: Environment = nodeEnv
93+
return Chains.load(env)
94+
}
8495
}
8596

8697
class ChainsFactory {
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { describe, it } from "mocha"
2+
import { assert } from "chai"
3+
import * as config from "../src/config"
4+
5+
describe("Load configuration from JSON file", () => {
6+
it("ethereum chain id is 1", () => {
7+
const chains: config.Chains = config.Chains.load("production")
8+
const chainId: number = chains.ethereum.id
9+
const expected = 1
10+
assert.equal(chainId, expected, `Expecting ethereum prod chain id to equal ${expected}, got '${chainId}'`)
11+
})
12+
it("development chain id is 8995", () => {
13+
const chains: config.Chains = config.Chains.load("development")
14+
const chainId: number = chains.ethereum.id
15+
const expected = 8995
16+
assert.equal(chainId, expected, `Expecting ethereum dev chain id to equal ${expected}, got '${chainId}'`)
17+
})
18+
it("reads DATA token dev address from JSON", () => {
19+
const chains: config.Chains = config.Chains.load("development")
20+
const address = chains.ethereum.contracts["DATA-token"]
21+
const expected = "0xbAA81A0179015bE47Ad439566374F2Bae098686F"
22+
assert.equal(address, expected, `Expecting ethereum DATA token to equal ${expected}, got '${address}'`)
23+
})
24+
it("reads prod Polygon RPC URL", () => {
25+
const chains: config.Chains = config.Chains.load("production")
26+
const rpcHttpUrl = chains.polygon.rpcEndpoints[0].url
27+
const expected = "https://polygon-rpc.com"
28+
assert.equal(rpcHttpUrl, expected, `Expecting prod polygon RPC URL to equal ${expected}, got '${rpcHttpUrl}'`)
29+
})
30+
it("finds RPC endpoints by protocol", () => {
31+
const chains: config.Chains = config.Chains.load("production")
32+
const endpoints = chains.binance.getRPCEndpointsByProtocol(config.RPCProtocol.HTTP)
33+
assert.equal(endpoints.length, 1)
34+
assert.equal(endpoints[0].url, "https://bsc-dataseed.binance.org")
35+
})
36+
})
37+
describe("Load configuration based on NODE_ENV environment variable", () => {
38+
it("ethereum chain id is 1", () => {
39+
process.env.NODE_ENV = "production"
40+
const chains: config.Chains = config.Chains.loadFromNodeEnv()
41+
const chainId: number = chains.ethereum.id
42+
const expected = 1
43+
assert.equal(chainId, expected, `Expecting ethereum prod chain id to equal ${expected}, got '${chainId}'`)
44+
})
45+
it("development chain id is 8995", () => {
46+
process.env.NODE_ENV = "development"
47+
const chains: config.Chains = config.Chains.loadFromNodeEnv()
48+
const chainId: number = chains.ethereum.id
49+
const expected = 8995
50+
assert.equal(chainId, expected, `Expecting ethereum dev chain id to equal ${expected}, got '${chainId}'`)
51+
})
52+
it("errors when NODE_ENV is not set", () => {
53+
delete process.env.NODE_ENV
54+
assert.throws(() => {
55+
/* eslint-disable @typescript-eslint/no-unused-vars */
56+
const chains: config.Chains = config.Chains.loadFromNodeEnv()
57+
}, /NODE_ENV environment variable is not set/)
58+
})
59+
it("errors when NODE_ENV is something else than 'production' or 'development'", () => {
60+
process.env.NODE_ENV = "dev"
61+
assert.throws(() => {
62+
/* eslint-disable @typescript-eslint/no-unused-vars */
63+
const chains: config.Chains = config.Chains.loadFromNodeEnv()
64+
}, /NODE_ENV environment variable value must be either 'production' or 'development'/)
65+
})
66+
})

packages/config/test/index.test.ts

Lines changed: 0 additions & 36 deletions
This file was deleted.

0 commit comments

Comments
 (0)