env-dictionary 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +150 -96
- package/index.ts +1 -0
- package/lib/dictionary.ts +92 -26
- package/lib/t.ts +8 -1
- package/lib/types.ts +1 -1
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# env-dictionary
|
|
2
2
|
|
|
3
3
|
A TypeScript library for type-safe environment variable handling with runtime validation.
|
|
4
4
|
|
|
@@ -21,37 +21,13 @@ bun install
|
|
|
21
21
|
|
|
22
22
|
## Quick Start
|
|
23
23
|
|
|
24
|
-
### Using Dictionary (
|
|
24
|
+
### Using Dictionary (Create a typed env)
|
|
25
25
|
|
|
26
26
|
```typescript
|
|
27
|
-
import { Dictionary } from '
|
|
28
|
-
import { t } from '
|
|
27
|
+
import { Dictionary } from 'env-dictionary';
|
|
28
|
+
import { t } from 'env-dictionary';
|
|
29
29
|
|
|
30
|
-
const
|
|
31
|
-
env: {
|
|
32
|
-
API_KEY: 'secret',
|
|
33
|
-
PORT: 3000,
|
|
34
|
-
DEBUG: true,
|
|
35
|
-
},
|
|
36
|
-
schema: {
|
|
37
|
-
API_KEY: t.string(),
|
|
38
|
-
PORT: t.number(),
|
|
39
|
-
DEBUG: t.boolean(),
|
|
40
|
-
},
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
console.log(config.values.API_KEY); // 'secret'
|
|
44
|
-
console.log(config.values.PORT); // 3000
|
|
45
|
-
console.log(config.values.DEBUG); // true
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
### Using DictionaryEnv (Descriptor-based)
|
|
49
|
-
|
|
50
|
-
```typescript
|
|
51
|
-
import { DictionaryEnv } from './lib/dictionary';
|
|
52
|
-
import { t } from './lib/t';
|
|
53
|
-
|
|
54
|
-
const env = new DictionaryEnv([
|
|
30
|
+
const env = new Dictionary([
|
|
55
31
|
{ API_KEY: 'secret', type: t.string() },
|
|
56
32
|
{ PORT: 3000, type: t.number() },
|
|
57
33
|
{ DEBUG: true, type: t.boolean() },
|
|
@@ -62,6 +38,35 @@ console.log(env.env.PORT); // 3000
|
|
|
62
38
|
console.log(env.env.DEBUG); // true
|
|
63
39
|
```
|
|
64
40
|
|
|
41
|
+
### Using DictionaryEnv (Type pre-existing envs)
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { DictionaryEnv } from 'env-dictionary';
|
|
45
|
+
|
|
46
|
+
const typedEnv = new DictionaryEnv({ env: process.env })
|
|
47
|
+
|
|
48
|
+
console.log(typedEnv.env.PORT) // 8080
|
|
49
|
+
console.log(typedEnv.type.PORT) // Number
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
You can also provide a descriptor-based schema:
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { DictionaryEnv } from 'env-dictionary';
|
|
56
|
+
import { t } from 'env-dictionary';
|
|
57
|
+
|
|
58
|
+
const typedEnv = new DictionaryEnv(
|
|
59
|
+
{ env: process.env },
|
|
60
|
+
{ schema: [
|
|
61
|
+
{ var: 'PORT', type: t.number() },
|
|
62
|
+
{ var: 'API_KEY', type: t.string() },
|
|
63
|
+
]}
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
console.log(typedEnv.env.PORT) // 8080
|
|
67
|
+
console.log(typedEnv.type.PORT) // Number
|
|
68
|
+
```
|
|
69
|
+
|
|
65
70
|
## API Reference
|
|
66
71
|
|
|
67
72
|
### t
|
|
@@ -81,106 +86,135 @@ The `t` object provides type validators for schema definitions.
|
|
|
81
86
|
|
|
82
87
|
### Dictionary
|
|
83
88
|
|
|
84
|
-
A class that
|
|
89
|
+
A class that creates a typed environment object from an array of descriptors.
|
|
85
90
|
|
|
86
91
|
#### Constructor
|
|
87
92
|
|
|
88
93
|
```typescript
|
|
89
|
-
new Dictionary<
|
|
94
|
+
new Dictionary<TSchema>(schema: TSchema)
|
|
90
95
|
```
|
|
91
96
|
|
|
92
97
|
**Parameters:**
|
|
93
98
|
|
|
94
|
-
- `
|
|
95
|
-
- `options.schema?: Record<string, SchemaType>` - Optional schema for validation
|
|
99
|
+
- `schema: TSchema[]` - Array of descriptors defining environment variables
|
|
96
100
|
|
|
97
101
|
**Properties:**
|
|
98
102
|
|
|
99
|
-
- `
|
|
103
|
+
- `env: TEnv` - The typed environment object
|
|
100
104
|
|
|
101
105
|
#### Example
|
|
102
106
|
|
|
103
107
|
```typescript
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
},
|
|
112
|
-
schema: {
|
|
113
|
-
API_KEY: t.string(),
|
|
114
|
-
PORT: t.number(),
|
|
115
|
-
DEBUG: t.boolean(),
|
|
116
|
-
CONFIG: t.object(),
|
|
117
|
-
ITEMS: t.array(),
|
|
118
|
-
},
|
|
119
|
-
});
|
|
108
|
+
const env = new Dictionary([
|
|
109
|
+
{ API_KEY: 'secret', type: t.string() },
|
|
110
|
+
{ PORT: 3000, type: t.number() },
|
|
111
|
+
{ DEBUG: true, type: t.boolean() },
|
|
112
|
+
{ CONFIG: { url: 'https://api.example.com' }, type: t.object() },
|
|
113
|
+
{ ITEMS: [1, 2, 3], type: t.array() },
|
|
114
|
+
]);
|
|
120
115
|
```
|
|
121
116
|
|
|
117
|
+
#### Descriptor Format
|
|
118
|
+
|
|
119
|
+
Each descriptor must have:
|
|
120
|
+
- A variable name (key)
|
|
121
|
+
- A value
|
|
122
|
+
- A `type` property with the validator
|
|
123
|
+
|
|
122
124
|
#### Behavior
|
|
123
125
|
|
|
124
|
-
-
|
|
125
|
-
-
|
|
126
|
-
- Throws an error if a
|
|
127
|
-
-
|
|
126
|
+
- Throws an error if a descriptor is missing a variable name
|
|
127
|
+
- Throws an error if a descriptor is missing a type
|
|
128
|
+
- Throws an error if a value fails validation for its type
|
|
129
|
+
- Types are automatically inferred from the descriptors
|
|
128
130
|
|
|
129
131
|
### DictionaryEnv
|
|
130
132
|
|
|
131
|
-
A class that
|
|
133
|
+
A class that validates environment variables against a schema.
|
|
132
134
|
|
|
133
135
|
#### Constructor
|
|
134
136
|
|
|
135
137
|
```typescript
|
|
136
|
-
new DictionaryEnv<
|
|
138
|
+
new DictionaryEnv<T>(options: DictionaryOptions, descriptorOptions?: { schema: Array<{ var: string; type: SchemaType }> })
|
|
137
139
|
```
|
|
138
140
|
|
|
139
141
|
**Parameters:**
|
|
140
142
|
|
|
141
|
-
- `
|
|
143
|
+
- `options.env: Record<string, unknown>` - The environment variables to validate
|
|
144
|
+
- `options.schema?: Record<string, SchemaType>` - Optional schema for validation (key-based)
|
|
145
|
+
- `descriptorOptions?: { schema: Array<{ var: string; type: SchemaType }> }` - Optional descriptor-based schema
|
|
142
146
|
|
|
143
147
|
**Properties:**
|
|
144
148
|
|
|
145
|
-
- `env:
|
|
149
|
+
- `env: T` - The validated and typed environment variables
|
|
150
|
+
- `type: { [K in keyof T]: TypeConstructor }` - Type constructors for each variable
|
|
146
151
|
|
|
147
|
-
####
|
|
152
|
+
#### Examples
|
|
153
|
+
|
|
154
|
+
**Key-based schema:**
|
|
148
155
|
|
|
149
156
|
```typescript
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
]
|
|
157
|
+
const typedEnv = new DictionaryEnv({
|
|
158
|
+
env: {
|
|
159
|
+
API_KEY: 'secret',
|
|
160
|
+
PORT: 3000,
|
|
161
|
+
DEBUG: true,
|
|
162
|
+
CONFIG: { url: 'https://api.example.com' },
|
|
163
|
+
ITEMS: [1, 2, 3],
|
|
164
|
+
},
|
|
165
|
+
schema: {
|
|
166
|
+
API_KEY: t.string(),
|
|
167
|
+
PORT: t.number(),
|
|
168
|
+
DEBUG: t.boolean(),
|
|
169
|
+
CONFIG: t.object(),
|
|
170
|
+
ITEMS: t.array(),
|
|
171
|
+
},
|
|
172
|
+
});
|
|
157
173
|
```
|
|
158
174
|
|
|
159
|
-
|
|
175
|
+
**Descriptor-based schema:**
|
|
160
176
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
177
|
+
```typescript
|
|
178
|
+
const typedEnv = new DictionaryEnv(
|
|
179
|
+
{ env: process.env },
|
|
180
|
+
{ schema: [
|
|
181
|
+
{ var: 'PORT', type: t.number() },
|
|
182
|
+
{ var: 'API_KEY', type: t.string() },
|
|
183
|
+
]}
|
|
184
|
+
);
|
|
185
|
+
```
|
|
165
186
|
|
|
166
187
|
#### Behavior
|
|
167
188
|
|
|
168
|
-
-
|
|
169
|
-
-
|
|
170
|
-
- Throws an error if a
|
|
171
|
-
-
|
|
189
|
+
- If no schema is provided, all environment variables are included as-is with inferred types
|
|
190
|
+
- If a schema is provided (key-based or descriptor-based), only keys defined in the schema are included
|
|
191
|
+
- Throws an error if a variable fails validation
|
|
192
|
+
- Values are automatically typed based on the schema
|
|
172
193
|
|
|
173
194
|
## Usage Patterns
|
|
174
195
|
|
|
175
196
|
### Environment Variables
|
|
176
197
|
|
|
177
|
-
|
|
198
|
+
Use `Dictionary` to create a new typed environment:
|
|
178
199
|
|
|
179
200
|
```typescript
|
|
180
|
-
import { Dictionary } from '
|
|
181
|
-
import { t } from '
|
|
201
|
+
import { Dictionary } from 'env-dictionary';
|
|
202
|
+
import { t } from 'env-dictionary';
|
|
203
|
+
|
|
204
|
+
const env = new Dictionary([
|
|
205
|
+
{ DATABASE_URL: 'postgresql://localhost', type: t.string() },
|
|
206
|
+
{ PORT: 5432, type: t.number() },
|
|
207
|
+
{ NODE_ENV: 'development', type: t.string() },
|
|
208
|
+
]);
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Use `DictionaryEnv` to type a pre-existing environment (key-based schema):
|
|
182
212
|
|
|
183
|
-
|
|
213
|
+
```typescript
|
|
214
|
+
import { DictionaryEnv } from 'env-dictionary';
|
|
215
|
+
import { t } from 'env-dictionary';
|
|
216
|
+
|
|
217
|
+
const typedEnv = new DictionaryEnv({
|
|
184
218
|
env: process.env,
|
|
185
219
|
schema: {
|
|
186
220
|
DATABASE_URL: t.string(),
|
|
@@ -190,6 +224,22 @@ const env = new Dictionary({
|
|
|
190
224
|
});
|
|
191
225
|
```
|
|
192
226
|
|
|
227
|
+
Use `DictionaryEnv` with descriptor-based schema:
|
|
228
|
+
|
|
229
|
+
```typescript
|
|
230
|
+
import { DictionaryEnv } from 'env-dictionary';
|
|
231
|
+
import { t } from 'env-dictionary';
|
|
232
|
+
|
|
233
|
+
const typedEnv = new DictionaryEnv(
|
|
234
|
+
{ env: process.env },
|
|
235
|
+
{ schema: [
|
|
236
|
+
{ var: 'DATABASE_URL', type: t.string() },
|
|
237
|
+
{ var: 'PORT', type: t.number() },
|
|
238
|
+
{ var: 'NODE_ENV', type: t.string() },
|
|
239
|
+
]}
|
|
240
|
+
);
|
|
241
|
+
```
|
|
242
|
+
|
|
193
243
|
### Configuration Object
|
|
194
244
|
|
|
195
245
|
Can be used with any configuration object:
|
|
@@ -206,7 +256,7 @@ const config = {
|
|
|
206
256
|
},
|
|
207
257
|
};
|
|
208
258
|
|
|
209
|
-
const typedConfig = new
|
|
259
|
+
const typedConfig = new DictionaryEnv({
|
|
210
260
|
env: config,
|
|
211
261
|
schema: {
|
|
212
262
|
server: t.object(),
|
|
@@ -220,7 +270,7 @@ const typedConfig = new Dictionary({
|
|
|
220
270
|
For complex nested objects, use the `object` type:
|
|
221
271
|
|
|
222
272
|
```typescript
|
|
223
|
-
const dbConfig = new
|
|
273
|
+
const dbConfig = new DictionaryEnv({
|
|
224
274
|
env: {
|
|
225
275
|
database: {
|
|
226
276
|
host: 'localhost',
|
|
@@ -239,11 +289,23 @@ const dbConfig = new Dictionary({
|
|
|
239
289
|
Both `Dictionary` and `DictionaryEnv` throw errors when validation fails:
|
|
240
290
|
|
|
241
291
|
```typescript
|
|
242
|
-
import { Dictionary } from '
|
|
243
|
-
import { t } from '
|
|
292
|
+
import { Dictionary } from 'env-dictionary';
|
|
293
|
+
import { t } from 'env-dictionary';
|
|
294
|
+
|
|
295
|
+
try {
|
|
296
|
+
const env = new Dictionary([
|
|
297
|
+
{ PORT: '3000', type: t.number() }, // Should be a number
|
|
298
|
+
]);
|
|
299
|
+
} catch (error) {
|
|
300
|
+
console.error(error.message);
|
|
301
|
+
// 'ENV value "PORT" is not valid for the provided type'
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
import { DictionaryEnv } from 'env-dictionary';
|
|
305
|
+
import { t } from 'env-dictionary';
|
|
244
306
|
|
|
245
307
|
try {
|
|
246
|
-
const
|
|
308
|
+
const typedEnv = new DictionaryEnv({
|
|
247
309
|
env: {
|
|
248
310
|
PORT: '3000', // Should be a number
|
|
249
311
|
},
|
|
@@ -255,17 +317,6 @@ try {
|
|
|
255
317
|
console.error(error.message);
|
|
256
318
|
// 'Invalid environment variable "PORT".'
|
|
257
319
|
}
|
|
258
|
-
|
|
259
|
-
import { DictionaryEnv } from './lib/dictionary';
|
|
260
|
-
|
|
261
|
-
try {
|
|
262
|
-
const env = new DictionaryEnv([
|
|
263
|
-
{ PORT: '3000', type: t.number() }, // Should be a number
|
|
264
|
-
]);
|
|
265
|
-
} catch (error) {
|
|
266
|
-
console.error(error.message);
|
|
267
|
-
// 'ENV value "PORT" is not valid for the provided type'
|
|
268
|
-
}
|
|
269
320
|
```
|
|
270
321
|
|
|
271
322
|
## Type Safety
|
|
@@ -273,7 +324,10 @@ try {
|
|
|
273
324
|
Both classes provide full TypeScript type inference:
|
|
274
325
|
|
|
275
326
|
```typescript
|
|
276
|
-
|
|
327
|
+
import { Dictionary } from 'env-dictionary';
|
|
328
|
+
import { t } from 'env-dictionary';
|
|
329
|
+
|
|
330
|
+
const env = new Dictionary([
|
|
277
331
|
{ API_KEY: 'secret', type: t.string() },
|
|
278
332
|
{ PORT: 3000, type: t.number() },
|
|
279
333
|
{ DEBUG: true, type: t.boolean() },
|
package/index.ts
CHANGED
package/lib/dictionary.ts
CHANGED
|
@@ -1,31 +1,11 @@
|
|
|
1
1
|
/** biome-ignore-all lint/suspicious/noExplicitAny: . */
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
DictionaryEnvDescriptor,
|
|
4
|
+
DictionaryOptions,
|
|
5
|
+
SchemaType,
|
|
6
|
+
} from "./types";
|
|
3
7
|
|
|
4
|
-
export class Dictionary<
|
|
5
|
-
public readonly values: T;
|
|
6
|
-
constructor(options: DictionaryOptions) {
|
|
7
|
-
const { env, schema } = options;
|
|
8
|
-
|
|
9
|
-
let typedEnv: any = {};
|
|
10
|
-
if (schema) {
|
|
11
|
-
for (const key in schema) {
|
|
12
|
-
const s = schema[key];
|
|
13
|
-
const value = env[key];
|
|
14
|
-
if (s?.validate(value)) {
|
|
15
|
-
typedEnv[key] = value;
|
|
16
|
-
} else if (s) {
|
|
17
|
-
throw new Error(`Invalid environment variable "${key}".`);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
} else {
|
|
21
|
-
typedEnv = env;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
this.values = typedEnv;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export class DictionaryEnv<
|
|
8
|
+
export class Dictionary<
|
|
29
9
|
TSchema extends DictionaryEnvDescriptor<string, any>[],
|
|
30
10
|
> {
|
|
31
11
|
public readonly env: {
|
|
@@ -57,3 +37,89 @@ export class DictionaryEnv<
|
|
|
57
37
|
this.env = result;
|
|
58
38
|
}
|
|
59
39
|
}
|
|
40
|
+
|
|
41
|
+
export class DictionaryEnv<
|
|
42
|
+
T extends Record<string, any> = Record<string, any>,
|
|
43
|
+
> {
|
|
44
|
+
public readonly env: T;
|
|
45
|
+
public readonly type: {
|
|
46
|
+
[K in keyof T]: T[K] extends string
|
|
47
|
+
? typeof String
|
|
48
|
+
: T[K] extends number
|
|
49
|
+
? typeof Number
|
|
50
|
+
: T[K] extends boolean
|
|
51
|
+
? typeof Boolean
|
|
52
|
+
: T[K] extends object
|
|
53
|
+
? typeof Object
|
|
54
|
+
: typeof Array;
|
|
55
|
+
};
|
|
56
|
+
constructor(
|
|
57
|
+
options: DictionaryOptions,
|
|
58
|
+
descriptorOptions?: { schema: Array<{ var: string; type: SchemaType }> },
|
|
59
|
+
) {
|
|
60
|
+
const { env, schema } = options;
|
|
61
|
+
|
|
62
|
+
const typeMap: any = {
|
|
63
|
+
string: String,
|
|
64
|
+
number: Number,
|
|
65
|
+
boolean: Boolean,
|
|
66
|
+
object: Object,
|
|
67
|
+
array: Array,
|
|
68
|
+
any: Object,
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
let typedEnv: any = {};
|
|
72
|
+
let resultTypeMap: any = {};
|
|
73
|
+
|
|
74
|
+
if (descriptorOptions?.schema) {
|
|
75
|
+
const { schema: descriptors } = descriptorOptions;
|
|
76
|
+
for (const desc of descriptors) {
|
|
77
|
+
const key = desc.var;
|
|
78
|
+
const s = desc.type;
|
|
79
|
+
const value = env[key];
|
|
80
|
+
if (s?.validate(value)) {
|
|
81
|
+
// Convert string numbers to actual numbers
|
|
82
|
+
if (s.type === "number" && typeof value === "string") {
|
|
83
|
+
typedEnv[key] = Number(value);
|
|
84
|
+
} else {
|
|
85
|
+
typedEnv[key] = value;
|
|
86
|
+
}
|
|
87
|
+
resultTypeMap[key] = typeMap[s.type];
|
|
88
|
+
} else if (s) {
|
|
89
|
+
throw new Error(`Invalid environment variable "${key}".`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
} else if (schema) {
|
|
93
|
+
for (const key in schema) {
|
|
94
|
+
const s = schema[key];
|
|
95
|
+
const value = env[key];
|
|
96
|
+
if (s?.validate(value)) {
|
|
97
|
+
// Convert string numbers to actual numbers
|
|
98
|
+
if (s.type === "number" && typeof value === "string") {
|
|
99
|
+
typedEnv[key] = Number(value);
|
|
100
|
+
} else {
|
|
101
|
+
typedEnv[key] = value;
|
|
102
|
+
}
|
|
103
|
+
resultTypeMap[key] = typeMap[s.type];
|
|
104
|
+
} else if (s) {
|
|
105
|
+
throw new Error(`Invalid environment variable "${key}".`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
} else {
|
|
109
|
+
typedEnv = env;
|
|
110
|
+
for (const key in env) {
|
|
111
|
+
const value = env[key];
|
|
112
|
+
if (typeof value === "string") resultTypeMap[key] = String;
|
|
113
|
+
else if (typeof value === "number") resultTypeMap[key] = Number;
|
|
114
|
+
else if (typeof value === "boolean") resultTypeMap[key] = Boolean;
|
|
115
|
+
else if (Array.isArray(value)) resultTypeMap[key] = Array;
|
|
116
|
+
else if (typeof value === "object" && value !== null)
|
|
117
|
+
resultTypeMap[key] = Object;
|
|
118
|
+
else resultTypeMap[key] = typeof value;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
this.env = typedEnv;
|
|
123
|
+
this.type = resultTypeMap;
|
|
124
|
+
}
|
|
125
|
+
}
|
package/lib/t.ts
CHANGED
|
@@ -13,7 +13,14 @@ const stringSchema: Schema<string, "string"> = {
|
|
|
13
13
|
|
|
14
14
|
const numberSchema: Schema<number, "number"> = {
|
|
15
15
|
type: "number",
|
|
16
|
-
validate: (input): input is number =>
|
|
16
|
+
validate: (input): input is number => {
|
|
17
|
+
if (typeof input === "number") return true;
|
|
18
|
+
if (typeof input === "string") {
|
|
19
|
+
const parsed = Number(input);
|
|
20
|
+
return !isNaN(parsed) && isFinite(parsed) && input.trim() !== "";
|
|
21
|
+
}
|
|
22
|
+
return false;
|
|
23
|
+
},
|
|
17
24
|
};
|
|
18
25
|
|
|
19
26
|
const booleanSchema: Schema<boolean, "boolean"> = {
|
package/lib/types.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "env-dictionary",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"module": "dist/index.js",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "bun build index.ts --outdir dist --target node",
|
|
8
|
+
"typecheck": "tsc --noEmit"
|
|
9
|
+
},
|
|
6
10
|
"devDependencies": {
|
|
7
11
|
"@types/bun": "latest"
|
|
8
12
|
},
|