-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
338 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"extends": [ | ||
"eslint-config-egg/typescript", | ||
"eslint-config-egg/lib/rules/enforce-node-prefix" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
name: CI | ||
|
||
on: | ||
push: | ||
branches: [ master ] | ||
pull_request: | ||
branches: [ master ] | ||
|
||
jobs: | ||
Job: | ||
name: Node.js | ||
uses: node-modules/github-actions/.github/workflows/node-test.yml@master | ||
with: | ||
os: 'ubuntu-latest, macos-latest, windows-latest' | ||
version: '20, 22' | ||
secrets: | ||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
name: Publish Any Commit | ||
on: [push, pull_request] | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v4 | ||
|
||
- run: corepack enable | ||
- uses: actions/setup-node@v4 | ||
with: | ||
node-version: 20 | ||
|
||
- name: Install dependencies | ||
run: npm install | ||
|
||
- name: Build | ||
run: npm run prepublishOnly --if-present | ||
|
||
- run: npx pkg-pr-new publish |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
name: Release | ||
|
||
on: | ||
push: | ||
branches: [ master ] | ||
|
||
jobs: | ||
release: | ||
name: Node.js | ||
uses: node-modules/github-actions/.github/workflows/node-release.yml@master | ||
secrets: | ||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | ||
GIT_TOKEN: ${{ secrets.GIT_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -128,3 +128,4 @@ dist | |
.yarn/build-state.yml | ||
.yarn/install-state.gz | ||
.pnp.* | ||
.tshy |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,50 @@ | ||
# read-env-value | ||
|
||
[](https://www.npmjs.com/package/read-env-value) | ||
[](https://www.npmjs.com/package/read-env-value) | ||
[](https://github.com/node-modules/read-env-value/blob/master/LICENSE) | ||
[](https://codecov.io/gh/node-modules/read-env-value) | ||
[](https://github.com/node-modules/read-env-value/actions/workflows/ci.yml?query=branch%3Amaster) | ||
|
||
Read env with default value | ||
|
||
## Usage | ||
|
||
```ts | ||
import { env } from 'read-env-value'; | ||
|
||
// read env 'NODE_ENV' with default value 'development' | ||
const value = env('NODE_ENV', 'string', 'development'); | ||
``` | ||
|
||
## API | ||
|
||
### env(key: string, type: 'string' | 'number' | 'boolean', defaultValue?: string | number | boolean) | ||
|
||
#### Parameters | ||
|
||
- `key`: The environment variable key to read. | ||
- `type`: The type of the value to be returned. | ||
- `defaultValue`: The default value to return if the environment variable is not set. | ||
|
||
#### Returns | ||
|
||
- The value of the environment variable. | ||
|
||
#### Example | ||
|
||
```ts | ||
import { env } from 'read-env-value'; | ||
|
||
const value = env('NODE_ENV', 'string', 'development'); | ||
``` | ||
|
||
## License | ||
|
||
[MIT](./LICENSE) | ||
|
||
## Contributors | ||
|
||
[](https://github.com/node-modules/read-env-value/graphs/contributors) | ||
|
||
Made with [contributors-img](https://contrib.rocks). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
{ | ||
"name": "read-env-value", | ||
"version": "1.0.0", | ||
"description": "Read env with default value", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+ssh://[email protected]/node-modules/read-env-value.git" | ||
}, | ||
"keywords": [ | ||
"env", | ||
"environment" | ||
], | ||
"author": "fengmk2", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/node-modules/read-env-value/issues" | ||
}, | ||
"homepage": "https://github.com/node-modules/read-env-value#readme", | ||
"engines": { | ||
"node": ">= 20.0.0" | ||
}, | ||
"devDependencies": { | ||
"@arethetypeswrong/cli": "^0.17.3", | ||
"@eggjs/tsconfig": "1", | ||
"@types/mocha": "10", | ||
"@types/node": "22", | ||
"@vitest/coverage-v8": "^3.0.5", | ||
"eslint": "8", | ||
"eslint-config-egg": "14", | ||
"mm": "^4.0.2", | ||
"tshy": "3", | ||
"tshy-after": "1", | ||
"typescript": "5", | ||
"vitest": "^3.0.5" | ||
}, | ||
"scripts": { | ||
"lint": "eslint --cache src test --ext .ts", | ||
"pretest": "npm run lint -- --fix", | ||
"test": "vitest", | ||
"preci": "npm run lint", | ||
"ci": "vitest run --coverage", | ||
"postci": "npm run prepublishOnly", | ||
"prepublishOnly": "tshy && tshy-after && attw --pack" | ||
}, | ||
"type": "module", | ||
"tshy": { | ||
"exports": { | ||
".": "./src/index.ts", | ||
"./package.json": "./package.json" | ||
} | ||
}, | ||
"exports": { | ||
".": { | ||
"import": { | ||
"types": "./dist/esm/index.d.ts", | ||
"default": "./dist/esm/index.js" | ||
}, | ||
"require": { | ||
"types": "./dist/commonjs/index.d.ts", | ||
"default": "./dist/commonjs/index.js" | ||
} | ||
}, | ||
"./package.json": "./package.json" | ||
}, | ||
"files": [ | ||
"dist", | ||
"src" | ||
], | ||
"types": "./dist/commonjs/index.d.ts", | ||
"main": "./dist/commonjs/index.js", | ||
"module": "./dist/esm/index.js" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
export type ValueType = 'string' | 'boolean' | 'number'; | ||
export type DefaultValue = string | boolean | number | undefined; | ||
|
||
type TypeMap<D> = { | ||
'string': D extends undefined ? string | undefined : string; | ||
'boolean': D extends undefined ? boolean | undefined : boolean; | ||
'number': D extends undefined ? number | undefined : number; | ||
}; | ||
|
||
type EnvReturn<V extends ValueType, D extends DefaultValue> = TypeMap<D>[V]; | ||
|
||
export function env<V extends ValueType, D extends DefaultValue>(key: string, valueType: V, defaultValue?: D): EnvReturn<V, D> { | ||
let value = process.env[key]; | ||
if (typeof value === 'string') { | ||
value = value.trim(); | ||
} | ||
if (!value) { | ||
return defaultValue as EnvReturn<V, D>; | ||
} | ||
|
||
if (valueType === 'string') { | ||
return value as EnvReturn<V, D>; | ||
} | ||
|
||
if (valueType === 'boolean') { | ||
let booleanValue = false; | ||
if (value === 'true' || value === '1') { | ||
booleanValue = true; | ||
} else if (value === 'false' || value === '0') { | ||
booleanValue = false; | ||
} else { | ||
throw new TypeError(`Invalid boolean value: ${value} on process.env.${key}`); | ||
} | ||
return booleanValue as EnvReturn<V, D>; | ||
} | ||
|
||
if (valueType === 'number') { | ||
const numberValue = Number(value); | ||
if (isNaN(numberValue)) { | ||
throw new TypeError(`Invalid number value: ${value} on process.env.${key}`); | ||
} | ||
return numberValue as EnvReturn<V, D>; | ||
} | ||
|
||
throw new TypeError(`Invalid value type: ${valueType}`); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import assert from 'node:assert/strict'; | ||
import { test, beforeEach } from 'vitest'; | ||
import { mock, restore } from 'mm'; | ||
import { env } from '../src/index.js'; | ||
|
||
beforeEach(restore); | ||
|
||
test('should return default value if env is not set', () => { | ||
assert.equal(env('TEST_ENV_STRING', 'string', 'default'), 'default'); | ||
assert.equal(env('TEST_ENV_BOOLEAN', 'boolean', false), false); | ||
assert.equal(env('TEST_ENV_NUMBER', 'number', 0), 0); | ||
}); | ||
|
||
test('should return undefined if env is not set', () => { | ||
assert.equal(env('TEST_ENV_STRING', 'string'), undefined); | ||
assert.equal(env('TEST_ENV_BOOLEAN', 'boolean'), undefined); | ||
assert.equal(env('TEST_ENV_NUMBER', 'number'), undefined); | ||
|
||
assert.equal(env('TEST_ENV_STRING', 'string') ?? null, null); | ||
assert.equal(env('TEST_ENV_NUMBER', 'number') ?? 0, 0); | ||
assert.equal(env('TEST_ENV_BOOLEAN', 'boolean') ?? false, false); | ||
assert.equal(env('TEST_ENV_STRING', 'string') ?? 'default', 'default'); | ||
}); | ||
|
||
test('should return env value if env is set to empty string', () => { | ||
mock(process.env, 'TEST_ENV_STRING', ''); | ||
mock(process.env, 'TEST_ENV_BOOLEAN', ''); | ||
mock(process.env, 'TEST_ENV_NUMBER', ''); | ||
|
||
assert.equal(env('TEST_ENV_STRING', 'string', ''), ''); | ||
assert.equal(env('TEST_ENV_STRING', 'string'), undefined); | ||
assert.equal(env('TEST_ENV_STRING', 'string', 'default string'), 'default string'); | ||
assert.equal(env('TEST_ENV_BOOLEAN', 'boolean', true), true); | ||
assert.equal(env('TEST_ENV_BOOLEAN', 'boolean', false), false); | ||
assert.equal(env('TEST_ENV_NUMBER', 'number', 3306), 3306); | ||
assert.equal(env('TEST_ENV_NUMBER', 'number', 0), 0); | ||
assert.equal(env('TEST_ENV_NUMBER', 'number', -123), -123); | ||
|
||
mock(process.env, 'TEST_ENV_STRING', ' '); | ||
mock(process.env, 'TEST_ENV_BOOLEAN', ' \t '); | ||
mock(process.env, 'TEST_ENV_NUMBER', ' \t\t\t '); | ||
|
||
assert.equal(env('TEST_ENV_STRING', 'string', ''), ''); | ||
assert.equal(env('TEST_ENV_STRING', 'string', 'default string'), 'default string'); | ||
assert.equal(env('TEST_ENV_BOOLEAN', 'boolean', true), true); | ||
assert.equal(env('TEST_ENV_BOOLEAN', 'boolean', false), false); | ||
assert.equal(env('TEST_ENV_NUMBER', 'number', 3306), 3306); | ||
assert.equal(env('TEST_ENV_NUMBER', 'number', 0), 0); | ||
}); | ||
|
||
test('should throw error if env is set to invalid value', () => { | ||
mock(process.env, 'TEST_ENV_BOOLEAN', 'invalid'); | ||
assert.throws(() => env('TEST_ENV_BOOLEAN', 'boolean', false), /Invalid boolean value: invalid on process.env.TEST_ENV_BOOLEAN/); | ||
|
||
mock(process.env, 'TEST_ENV_NUMBER', 'invalid'); | ||
assert.throws(() => env('TEST_ENV_NUMBER', 'number', 0), /Invalid number value: invalid on process.env.TEST_ENV_NUMBER/); | ||
|
||
mock(process.env, 'TEST_ENV_NUMBER', 'abc'); | ||
assert.throws(() => env('TEST_ENV_NUMBER', 'number', 0), /Invalid number value: abc on process.env.TEST_ENV_NUMBER/); | ||
}); | ||
|
||
test('should throw error if value type is invalid', () => { | ||
mock(process.env, 'TEST_ENV_STRING', '123'); | ||
assert.throws(() => (env as any)('TEST_ENV_STRING', 'float', 'default'), /Invalid value type: float/); | ||
}); | ||
|
||
test('should work with string value', () => { | ||
mock(process.env, 'TEST_ENV_STRING', 'http://localhost:3000'); | ||
assert.equal(env('TEST_ENV_STRING', 'string', 'default'), 'http://localhost:3000'); | ||
|
||
mock(process.env, 'TEST_ENV_STRING', ' '); | ||
assert.equal(env('TEST_ENV_STRING', 'string', 'default'), 'default'); | ||
}); | ||
|
||
test('should work with boolean value', () => { | ||
mock(process.env, 'TEST_ENV_BOOLEAN', 'true'); | ||
assert.equal(env('TEST_ENV_BOOLEAN', 'boolean', false), true); | ||
|
||
mock(process.env, 'TEST_ENV_BOOLEAN', 'false'); | ||
assert.equal(env('TEST_ENV_BOOLEAN', 'boolean', true), false); | ||
|
||
mock(process.env, 'TEST_ENV_BOOLEAN', '1'); | ||
assert.equal(env('TEST_ENV_BOOLEAN', 'boolean', false), true); | ||
|
||
mock(process.env, 'TEST_ENV_BOOLEAN', '0'); | ||
assert.equal(env('TEST_ENV_BOOLEAN', 'boolean', true), false); | ||
}); | ||
|
||
test('should work with number value', () => { | ||
mock(process.env, 'TEST_ENV_NUMBER', '123'); | ||
assert.equal(env('TEST_ENV_NUMBER', 'number', 0), 123); | ||
|
||
mock(process.env, 'TEST_ENV_NUMBER', '-123'); | ||
assert.equal(env('TEST_ENV_NUMBER', 'number', 0), -123); | ||
|
||
mock(process.env, 'TEST_ENV_NUMBER', '123.456'); | ||
assert.equal(env('TEST_ENV_NUMBER', 'number', 0), 123.456); | ||
|
||
mock(process.env, 'TEST_ENV_NUMBER', '0'); | ||
assert.equal(env('TEST_ENV_NUMBER', 'number', 10), 0); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"extends": "@eggjs/tsconfig", | ||
"compilerOptions": { | ||
"strict": true, | ||
"noImplicitAny": true, | ||
"target": "ES2022", | ||
"module": "NodeNext", | ||
"moduleResolution": "NodeNext" | ||
} | ||
} |