Skip to content

Commit

Permalink
chore:changes
Browse files Browse the repository at this point in the history
  • Loading branch information
broisnischal committed Oct 8, 2024
1 parent fc1d997 commit 212ebe9
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 127 deletions.
47 changes: 0 additions & 47 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# [envnest](https://www.npmjs.com/package/envnest)

## This package is in underdevelopment and should not be used in production.

`envnest` is a TypeScript library for NestJS that provides type-safe environment variable validation and access using Zod schemas.

## Installation
Expand Down Expand Up @@ -75,50 +73,6 @@ export class AppService {
}
```

## Presets

envnest comes with built-in presets for common environment variables. You can use these presets to quickly set up your environment schema.

### Using a preset

```typescript
import { createEnvConfig, presets } from "envnest";

const envSchema = presets.node().extend({
...presets.databaseUrl,
// Add your custom environment variables here
});

export const envService = createEnvConfig(envSchema);
```

### Available presets

- `presets.node()`: Common Node.js environment variables (NODE_ENV, PORT)
- `presets.databaseUrl()`: Database URL validation
- `presets.jwt()`: JWT secret and expiration time
- `presets.cors()`: CORS configuration

## Custom Presets

You can create custom presets for your specific needs:

```typescript
import { z } from "envnest";

const myCustomPreset = () => z.object({
CUSTOM_API_KEY: z.string().min(1),
CUSTOM_API_URL: z.string().url(),
});

const envSchema = presets.node().extend({
...myCustomPreset().shape,
// Other environment variables
});

export const envService = createEnvConfig(envSchema);
```

## Features

- Type-safe environment variable access
Expand All @@ -133,7 +87,6 @@ export const envService = createEnvConfig(envSchema);
- `createEnvConfig(schema: ZodSchema)`: Creates a configuration service with validation
- `envService.config`: Typed ConfigService instance
- `envService.validateConfig`: Validation function for use with NestJS ConfigModule
- `presets`: Object containing built-in presets

## License

Expand Down
48 changes: 48 additions & 0 deletions Test.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,51 @@ Creates a Zod schema by combining multiple preset schemas.
## License

MIT


<!-- //// -->


## Presets

envnest comes with built-in presets for common environment variables. You can use these presets to quickly set up your environment schema.

### Using a preset

```typescript
import { createEnvConfig, presets } from "envnest";

const envSchema = presets.node().extend({
...presets.databaseUrl,
// Add your custom environment variables here
});

export const envService = createEnvConfig(envSchema);
```

### Available presets

- `presets.node()`: Common Node.js environment variables (NODE_ENV, PORT)
- `presets.databaseUrl()`: Database URL validation
- `presets.jwt()`: JWT secret and expiration time
- `presets.cors()`: CORS configuration

## Custom Presets

You can create custom presets for your specific needs:

```typescript
import { z } from "envnest";

const myCustomPreset = () => z.object({
CUSTOM_API_KEY: z.string().min(1),
CUSTOM_API_URL: z.string().url(),
});

const envSchema = presets.node().extend({
...myCustomPreset().shape,
// Other environment variables
});

export const envService = createEnvConfig(envSchema);
```
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
"typesafe-env"
],
"description": "Typesafe environment variables for NestJS using zod.",
"homepage": "https://github.com/nischal-dahal/envnest",
"homepage": "https://github.com/broisnischal/nestenv",
"repository": {
"type": "git",
"url": "https://github.com/nischal-dahal/envnest"
"url": "https://github.com/broisnischal/nestenv"
},
"sponsor": {
"url": "https://nischal.pro"
Expand Down
110 changes: 56 additions & 54 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,61 +25,63 @@ function convertToNumber(value: unknown): number | unknown {
const zodNumberFromString = z.preprocess(convertToNumber, z.number());

export function createNestEnvValidator<T extends z.ZodType>(
schema: T,
options: {
logErrors?: boolean;
throwOnError?: boolean;
useDefaults?: boolean;
} = {},
schema: T,
options: {
logErrors?: boolean;
throwOnError?: boolean;
useDefaults?: boolean;
} = {}
): () => z.infer<T> {
return () => {
const parseOptions: z.ParseParams = {
path: [],
errorMap: (issue, ctx) => {
return {
message: `Invalid value for environment variable ${issue.path.join(".")}`,
};
},
async: false,
};
if (options.useDefaults !== false) {
parseOptions.path = [];
}

// Preprocess the schema to handle number conversions
const preprocessedSchema = z.preprocess((obj) => {
if (typeof obj === "object" && obj !== null) {
return Object.fromEntries(
Object.entries(obj).map(([key, value]) => {
// @ts-ignore
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
const fieldSchema = (schema as any).shape?.[key];
if (fieldSchema instanceof z.ZodNumber) {
return [key, convertToNumber(value)];
}
return [key, value];
}),
);
}
return obj;
}, schema);

const result = preprocessedSchema.safeParse(process.env, parseOptions);

if (!result.success) {
if (options.logErrors !== false) {
console.error(
"❌ Invalid environment variables:",
result.error.format(),
);
}
if (options.throwOnError !== false) {
throw new Error("Invalid environment variables");
}
}

return result.success ? result.data : process.env;
};
return () => {
const parseOptions: z.ParseParams = {
path: [],
errorMap: (issue, ctx) => {
return {
message: `Invalid value for environment variable ${issue.path.join(
"."
)}`,
};
},
async: false,
};
if (options.useDefaults !== false) {
parseOptions.path = [];
}

// Preprocess the schema to handle number conversions
const preprocessedSchema = z.preprocess((obj) => {
if (typeof obj === "object" && obj !== null) {
return Object.fromEntries(
Object.entries(obj).map(([key, value]) => {
// @ts-ignore
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
const fieldSchema = (schema as any).shape?.[key];
if (fieldSchema instanceof z.ZodNumber) {
return [key, convertToNumber(value)];
}
return [key, value];
})
);
}
return obj;
}, schema);

const result = preprocessedSchema.safeParse(process.env, parseOptions);

if (!result.success) {
if (options.logErrors !== false) {
console.error(
"❌ Invalid environment variables:",
result.error.format()
);
}
if (options.throwOnError !== false) {
throw new Error("Invalid environment variables");
}
}

return result.success ? result.data : process.env;
};
}

export function createTypedConfigService<T extends z.ZodType>(schema: T) {
Expand Down
48 changes: 24 additions & 24 deletions src/presets.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
import { z } from "zod";
// import { z } from "zod";

export const commonEnvs = {
NODE_ENV: z
.enum(["development", "production", "test"])
.default("development"),
PORT: z.coerce.number().positive(),
LOG_LEVEL: z.enum(["error", "warn", "info", "debug"]).default("info"),
};
// export const commonEnvs = {
// NODE_ENV: z
// .enum(["development", "production", "test"])
// .default("development"),
// PORT: z.coerce.number().positive(),
// LOG_LEVEL: z.enum(["error", "warn", "info", "debug"]).default("info"),
// };

export const databaseEnvs = {
DATABASE_URL: z.string().url(),
DATABASE_SSL: z.coerce.boolean().default(false),
};
// export const databaseEnvs = {
// DATABASE_URL: z.string().url(),
// DATABASE_SSL: z.coerce.boolean().default(false),
// };

export const awsEnvs = {
AWS_ACCESS_KEY_ID: z.string().min(1),
AWS_SECRET_ACCESS_KEY: z.string().min(1),
AWS_REGION: z.string().min(1),
};
// export const awsEnvs = {
// AWS_ACCESS_KEY_ID: z.string().min(1),
// AWS_SECRET_ACCESS_KEY: z.string().min(1),
// AWS_REGION: z.string().min(1),
// };

export const authEnvs = {
JWT_SECRET: z.string().min(32),
JWT_EXPIRATION: z.string().regex(/^\d+[smhd]$/),
};
// export const authEnvs = {
// JWT_SECRET: z.string().min(32),
// JWT_EXPIRATION: z.string().regex(/^\d+[smhd]$/),
// };

export function createPresetSchema(...presets: z.ZodRawShape[]) {
return z.object(Object.assign({}, ...presets));
}
// export function createPresetSchema(...presets: z.ZodRawShape[]) {
// return z.object(Object.assign({}, ...presets));
// }

0 comments on commit 212ebe9

Please sign in to comment.