Skip to content

Commit f869609

Browse files
committed
chore(release): v1.1.0 optimizations
1 parent dcb2bc7 commit f869609

33 files changed

+1912
-11302
lines changed

.github/workflows/lint.yml

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,72 @@
1-
name: Lint
2-
1+
name: Quality Assurance
32
on:
43
workflow_call:
54
push:
5+
pull_request:
66

77
jobs:
8-
lint:
8+
typecheck:
9+
name: typecheck
910
runs-on: ubuntu-latest
11+
1012
steps:
11-
- name: Checkout code
13+
- name: Checkout Repository
1214
uses: actions/checkout@v4
15+
with:
16+
fetch-depth: 0
1317

14-
- name: Cache node modules
18+
- name: Setup Node.js
19+
uses: actions/setup-node@v4
20+
with:
21+
node-version: 22
22+
23+
- name: Setup Bun
24+
uses: oven-sh/setup-bun@v2
25+
26+
- name: Cache Bun Dependencies
1527
uses: actions/cache@v4
1628
with:
17-
path: ~/.npm
18-
key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }}
29+
path: ~/.bun/install/cache
30+
key: ${{ runner.os }}-bun-${{ hashFiles('bun.lock') }}
1931
restore-keys: |
20-
${{ runner.os }}-node-
32+
${{ runner.os }}-bun-
33+
34+
- name: Install Dependencies
35+
run: bun install --frozen-lockfile
36+
37+
- name: Run Type Checker
38+
run: |
39+
bun run typecheck
2140
22-
- name: Set up Node.js
41+
lint:
42+
name: lint
43+
runs-on: ubuntu-latest
44+
45+
steps:
46+
- name: Checkout Repository
47+
uses: actions/checkout@v4
48+
with:
49+
fetch-depth: 0
50+
51+
- name: Setup Node.js
2352
uses: actions/setup-node@v4
2453
with:
2554
node-version: 22
2655

27-
- name: Install dependencies
28-
run: npm ci
56+
- name: Setup Bun
57+
uses: oven-sh/setup-bun@v2
2958

30-
- name: Run Prettier check
31-
run: npm run check
59+
- name: Cache Bun Dependencies
60+
uses: actions/cache@v4
61+
with:
62+
path: ~/.bun/install/cache
63+
key: ${{ runner.os }}-bun-${{ hashFiles('bun.lock') }}
64+
restore-keys: |
65+
${{ runner.os }}-bun-
3266
33-
- name: Run ESLint
34-
run: npm run lint:check
67+
- name: Install Dependencies
68+
run: bun install --frozen-lockfile
3569

36-
- name: Run TypeScript check
37-
run: npm run check-types
70+
- name: Run Linter
71+
run: |
72+
bun run lint

.github/workflows/publish.yml

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,22 @@ jobs:
2828
node-version: 22
2929
registry-url: https://registry.npmjs.org/
3030

31-
- name: Install dependencies
32-
run: npm ci
31+
- name: Setup Bun
32+
uses: oven-sh/setup-bun@v2
33+
34+
- name: Cache Bun Dependencies
35+
uses: actions/cache@v4
36+
with:
37+
path: ~/.bun/install/cache
38+
key: ${{ runner.os }}-bun-${{ hashFiles('bun.lock') }}
39+
restore-keys: |
40+
${{ runner.os }}-bun-
41+
42+
- name: Install Dependencies
43+
run: bun install --frozen-lockfile
3344

3445
- name: Publish to npm
35-
run: npm run release
46+
run: bun run release
3647
env:
3748
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
3849
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

.github/workflows/test.yml

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,39 @@
11
name: Tests
2-
32
on:
43
workflow_call:
54
push:
5+
pull_request:
66

77
jobs:
88
test:
9+
name: test
910
runs-on: ubuntu-latest
11+
1012
steps:
11-
- name: Checkout code
13+
- name: Checkout Repository
1214
uses: actions/checkout@v4
13-
14-
- name: Cache node modules
15-
uses: actions/cache@v4
1615
with:
17-
path: ~/.npm
18-
key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }}
19-
restore-keys: |
20-
${{ runner.os }}-node-
16+
fetch-depth: 0
2117

22-
- name: Set up Node.js
18+
- name: Setup Node.js
2319
uses: actions/setup-node@v4
2420
with:
2521
node-version: 22
2622

27-
- name: Install dependencies
28-
run: npm ci
23+
- name: Setup Bun
24+
uses: oven-sh/setup-bun@v2
25+
26+
- name: Cache Bun Dependencies
27+
uses: actions/cache@v4
28+
with:
29+
path: ~/.bun/install/cache
30+
key: ${{ runner.os }}-bun-${{ hashFiles('bun.lock') }}
31+
restore-keys: |
32+
${{ runner.os }}-bun-
33+
34+
- name: Install Dependencies
35+
run: bun install --frozen-lockfile
2936

30-
- name: Run tests
31-
run: npm run test
37+
- name: Run Tests
38+
run: |
39+
bun run test

.husky/pre-commit

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
npm run check-types && npm run check && npm run lint:check && npm run test
1+
bun run typecheck && bun run lint && bun run test

.prettierignore

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

.prettierrc

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

CHANGELOG.md

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,15 @@
11
# @devscast/config
22

3-
## 1.0.3
4-
5-
### Patch Changes
6-
7-
- support typed prefix in environment variables
3+
## 1.1.0
84

9-
## 1.0.2
5+
- enhance: ConfigValidationError now includes detailed validation issues
6+
- fix: correct typing in defineConfig function
7+
- drop support of ts config files
8+
- drop support of csj config files
109

11-
### Patch Changes
10+
## 1.0.3
1211

12+
- support typed prefix in environment variables
1313
- minify production dist
14-
15-
## 1.0.1
16-
17-
### Patch Changes
18-
1914
- remove command expensions tests
20-
21-
## 1.0.0
22-
23-
### Major Changes
24-
2515
- Initial Release

README.md

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111

1212
`@devscast/config` provides a batteries-included configuration loader for Node.js projects. It lets you:
1313

14-
- Load configuration from JSON, YAML, INI, or native TypeScript modules
14+
- Load configuration from JSON, YAML, INI, or inline objects defined in code
1515
- Reference environment variables in text files with the `%env(FOO)%` syntax
1616
- Bootstrap environment values from `.env` files (including `.env.local`, `.env.<env>`, `.env.<env>.local`)
1717
- Validate the resulting configuration with a [Zod v4](https://zod.dev) schema before your app starts
18-
- Consume the same `env()` helper inside TypeScript configuration files for typed access to `process.env`
18+
- Use the typed `env()` helper throughout your app for safe access to `process.env`
1919

2020
## Installation
2121

@@ -36,7 +36,7 @@ npm install @devscast/config zod
3636
```ts
3737
import path from "node:path";
3838
import { z } from "zod/mini";
39-
import { loadConfig } from "@devscast/config";
39+
import { defineConfig } from "@devscast/config";
4040
4141
const schema = z.object({
4242
database: z.object({
@@ -48,7 +48,7 @@ const schema = z.object({
4848
featureFlags: z.array(z.string()).default([]),
4949
});
5050
51-
const { config, env } = loadConfig({
51+
const { config, env } = defineConfig({
5252
schema,
5353
cwd: process.cwd(),
5454
env: { path: path.join(process.cwd(), ".env") },
@@ -68,9 +68,9 @@ console.log(config.database.host);
6868
6969
```ts
7070
import path from "node:path";
71-
import { loadConfig } from "@devscast/config";
71+
import { defineConfig } from "@devscast/config";
7272
73-
const { config, env } = loadConfig({
73+
const { config, env } = defineConfig({
7474
schema,
7575
env: true,
7676
sources: [
@@ -88,9 +88,9 @@ const { config, env } = loadConfig({
8888
#### Typed environment accessor for reusable helpers
8989
9090
```ts
91-
import { loadConfig } from "@devscast/config";
91+
import { defineConfig } from "@devscast/config";
9292
93-
const { config, env } = loadConfig({
93+
const { config, env } = defineConfig({
9494
schema,
9595
env: {
9696
path: ".env",
@@ -127,51 +127,62 @@ const config = schema.parse({
127127
});
128128
```
129129
130-
- `createEnvAccessor` gives you the same typed helper without invoking `loadConfig`, ideal for lightweight scripts.
130+
- `createEnvAccessor` gives you the same typed helper without invoking `defineConfig`, ideal for lightweight scripts.
131131
- You can still validate the derived values with Zod (or any other validator) before using them.
132132
133-
#### Executable TypeScript configuration modules
133+
#### Inline configuration objects (no compiled files)
134134
135135
```ts
136-
// config/services.ts
137-
import type { EnvAccessor } from "@devscast/config";
136+
import { z } from "zod/mini";
137+
import { defineConfig } from "@devscast/config";
138138
139-
export default ({ env }: { env: EnvAccessor<string> }) => ({
140-
redis: {
141-
host: env("REDIS_HOST"),
142-
port: Number(env("REDIS_PORT", { default: "6379" })),
143-
},
139+
const schema = z.object({
140+
database: z.object({
141+
host: z.string(),
142+
port: z.number(),
143+
}),
144+
featureFlags: z.preprocess(
145+
value => {
146+
if (typeof value === "string") {
147+
return value
148+
.split(",")
149+
.map(flag => flag.trim())
150+
.filter(Boolean);
151+
}
152+
return value;
153+
},
154+
z.array(z.string())
155+
),
144156
});
145157
146-
// loader
147-
import path from "node:path";
148-
import { loadConfig } from "@devscast/config";
149-
150-
const { config } = loadConfig({
158+
const { config } = defineConfig({
151159
schema,
152-
sources: [
153-
{ path: path.join("config", "services.ts"), format: "ts" },
154-
],
160+
env: { path: ".env" },
161+
sources: {
162+
database: { host: "%env(DB_HOST)%", port: "%env(number:DB_PORT)%" },
163+
featureFlags: "%env(FEATURE_FLAGS)%",
164+
},
155165
});
166+
167+
console.log(config.database);
156168
```
157169
158-
- TS sources run inside a sandbox with the same `env` helper, so you can compute complex structures at load time.
159-
- Returning a function lets you access the accessor argument explicitly; you can also export plain objects if no logic is needed.
170+
- Inline objects remove the need for TypeScript config files while still allowing env interpolation.
171+
- Typed placeholders resolve after `.env` files load; use Zod preprocessors for shapes like comma-delimited lists.
160172
161173
### Referencing environment variables
162174
163175
- **Text-based configs** (JSON, YAML, INI): use `%env(DB_HOST)%`
164176
- **Typed placeholders**: `%env(number:PORT)%`, `%env(boolean:FEATURE)%`, `%env(string:NAME)%`
165177
- When the entire value is a single placeholder, typed forms produce native values (number/boolean).
166178
- When used inside larger strings (e.g. `"http://%env(API_HOST)%/v1"`), placeholders are interpolated as text.
167-
- **TypeScript configs**: call `env("DB_HOST")`; the helper is available globally when the module is evaluated
168-
- For tighter autocomplete you can build a project-local accessor via `createEnvAccessor(["DB_HOST", "DB_PORT"] as const)`
179+
- **Inline objects**: placeholders work the same way; combine them with Zod preprocessors for complex shapes (arrays, URLs, etc.).
169180
170181
The `env()` helper throws when the variable is missing. Provide a default with `env("PORT", { default: "3000" })` or switch to `env.optional("PORT")`.
171182
172183
### Dotenv loading
173184
174-
`loadConfig` automatically understands `.env` files when the `env` option is provided. The resolver honours the following precedence, mirroring Symfony's Dotenv component:
185+
`defineConfig` automatically understands `.env` files when the `env` option is provided. The resolver honours the following precedence, mirroring Symfony's Dotenv component:
175186
176187
1. `.env` (or `.env.dist` when `.env` is missing)
177188
2. `.env.local` (skipped when `NODE_ENV === "test"`)

0 commit comments

Comments
 (0)