@safe-hand/safe-env-check 1.0.3 → 1.1.0

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.
@@ -3,7 +3,7 @@ name: Release
3
3
  on:
4
4
  push:
5
5
  tags:
6
- - 'v*.*.*'
6
+ - "v*.*.*"
7
7
 
8
8
  jobs:
9
9
  release:
@@ -14,8 +14,8 @@ jobs:
14
14
  - name: Set up Node.js
15
15
  uses: actions/setup-node@v3
16
16
  with:
17
- node-version: '20'
18
- registry-url: 'https://registry.npmjs.org'
17
+ node-version: "20"
18
+ registry-url: "https://registry.npmjs.org"
19
19
 
20
20
  - name: Install dependencies
21
21
  run: npm install
@@ -30,5 +30,7 @@ jobs:
30
30
 
31
31
  - name: Create GitHub Release
32
32
  uses: ncipollo/release-action@v1
33
+ env:
34
+ GITHUB_TOKEN: ${{secrets.GH_PAT}}
33
35
  with:
34
36
  tag: ${{ github.ref_name }}
package/README.md CHANGED
@@ -4,7 +4,6 @@
4
4
  ![license](https://img.shields.io/npm/l/@safe-hand/safe-env-check)
5
5
  ![downloads](https://img.shields.io/npm/dm/@safe-hand/safe-env-check)
6
6
 
7
-
8
7
  A tiny TypeScript library to validate environment variables using a schema with support for:
9
8
 
10
9
  - ✅ Type validation
@@ -22,7 +21,9 @@ A tiny TypeScript library to validate environment variables using a schema with
22
21
  ```bash
23
22
  npm install @safe-hand/safe-env-check
24
23
  ```
24
+
25
25
  or
26
+
26
27
  ```bash
27
28
  yarn add @safe-hand/safe-env-check
28
29
  ```
@@ -44,6 +45,7 @@ yarn add @safe-hand/safe-env-check
44
45
  ## Basic Usage
45
46
 
46
47
  ### Define a schema
48
+
47
49
  ```ts
48
50
  const schema = {
49
51
  PORT: { type: "number", required: true },
@@ -57,26 +59,29 @@ const schema = {
57
59
  ```
58
60
 
59
61
  ### Validate environment variables
62
+
60
63
  ```ts
61
64
  import { validateEnv } from "@safe-hand/safe-env-check";
62
65
 
63
66
  const env = validateEnv(schema);
64
67
 
65
- console.log(env.PORT); // number
66
- console.log(env.NODE_ENV); // "development" | "production"
68
+ console.log(env.PORT); // number
69
+ console.log(env.NODE_ENV); // "development" | "production"
67
70
  ```
68
71
 
69
72
  ## Schema Options
73
+
70
74
  Each environment variables supports the following options:
71
75
 
72
- | Field | Type | Description | | | |
73
- | ---------- | ---------- | -------------------------------- | --------- | ------- | ------------------- |
74
- | `type` | `"string" or "number" or "boolean" or "enum"` | Expected value type |
75
- | `required` | `boolean` | Whether the variable is required | | | |
76
- | `default` | `any` | Default value if not provided | | | |
77
- | `values` | `string[]` | Required for `enum` type | | | |
76
+ | Field | Type | Description |
77
+ | ---------- | ---------------------------------------------- | -------------------------------- |
78
+ | `type` | `"string" or "number" or "boolean" or "enum"` | Expected value type |
79
+ | `required` | `boolean` | Whether the variable is required |
80
+ | `default` | `any` | Default value if not provided |
81
+ | `values` | `string[]` | Required for `enum` type |
78
82
 
79
83
  ## Example
84
+
80
85
  ```ts
81
86
  DATABASE_URL: { type: "string", required: true },
82
87
  DEBUG: { type: "boolean", default: false },
@@ -84,14 +89,19 @@ MODE: { type: "enum", values: ["dev", "prod"] }
84
89
  ```
85
90
 
86
91
  ## Strict Mode
92
+
87
93
  Disallow environment variables that are not defined in the schema.
94
+
88
95
  ```ts
89
96
  validateEnv(schema, { strict: true });
90
97
  ```
98
+
91
99
  If extra variables are found, validation will fail.
92
100
 
93
101
  ## Custom Error Formatter
102
+
94
103
  You can control how errors are displayed:
104
+
95
105
  ```ts
96
106
  validateEnv(schema, {
97
107
  formatError: (errors) => `Config error:\n${errors.join("\n")}`,
@@ -103,6 +113,7 @@ validateEnv(schema, {
103
113
  By default, the library loads .env automatically using dotenv.
104
114
 
105
115
  Example .env file:
116
+
106
117
  ```bash
107
118
  PORT=3000
108
119
  JWT_SECRET=supersecret
@@ -112,6 +123,7 @@ NODE_ENV=development
112
123
  ## CLI Usage
113
124
 
114
125
  Create a schema file called env.schema.js:
126
+
115
127
  ```ts
116
128
  module.exports = {
117
129
  PORT: { type: "number", required: true },
@@ -120,10 +132,15 @@ module.exports = {
120
132
  ```
121
133
 
122
134
  Run validation:
135
+
123
136
  ```bash
124
137
  npx safe-env-check env.schema.js
138
+ npx safe-env-check env.schema.js
139
+ npx safe-env-check --schema env.schema.js --strict
140
+ npx safe-env-check env.schema.js --env-file .env.production
141
+ npx safe-env-check env.schema.js --format json
125
142
  ```
126
143
 
127
144
  ## License
128
145
 
129
- MIT © Shakhawat Hossain
146
+ MIT © Shakhawat Hossain
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+
2
+ export { }
package/dist/cli.js ADDED
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (let key of __getOwnPropNames(from))
11
+ if (!__hasOwnProp.call(to, key) && key !== except)
12
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
13
+ }
14
+ return to;
15
+ };
16
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
+ // If the importer is in node compatibility mode or this is not an ESM
18
+ // file that has been converted to a CommonJS file using a Babel-
19
+ // compatible transform (i.e. "__esModule" has not been set), then set
20
+ // "default" to the CommonJS "module.exports" for node compatibility.
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
24
+
25
+ // src/cli.ts
26
+ var import_dotenv = __toESM(require("dotenv"));
27
+ var import_path = __toESM(require("path"));
28
+ var import_fs = __toESM(require("fs"));
29
+
30
+ // package.json
31
+ var version = "1.1.0";
32
+
33
+ // src/validateEnv.ts
34
+ var validateEnv = (schema, options = {}) => {
35
+ const errors = [];
36
+ const result = {};
37
+ if (options.strict) {
38
+ const schemaKeys = Object.keys(schema);
39
+ const envKeys = Object.keys(process.env);
40
+ const unknownKeys = envKeys.filter((key) => !schemaKeys.includes(key));
41
+ if (unknownKeys.length)
42
+ errors.push(`Unknown evn variables: ${unknownKeys.join(", ")}`);
43
+ }
44
+ for (const key in schema) {
45
+ const rule = schema[key];
46
+ const rawValue = process.env[key];
47
+ if (!rawValue) {
48
+ if (rule.required && rule.default === void 0) {
49
+ errors.push(`${key} is required`);
50
+ continue;
51
+ }
52
+ result[key] = rule.default;
53
+ continue;
54
+ }
55
+ switch (rule.type) {
56
+ case "string":
57
+ result[key] = rawValue;
58
+ break;
59
+ case "number":
60
+ const num = Number(rawValue);
61
+ if (isNaN(num)) errors.push(`${key} must be a number`);
62
+ else result[key] = num;
63
+ break;
64
+ case "boolean":
65
+ result[key] = rawValue === "true";
66
+ break;
67
+ case "enum":
68
+ if (!rule.values.includes(rawValue)) {
69
+ errors.push(`${key} must be one of: ${rule.values.join(", ")}`);
70
+ } else {
71
+ result[key] = rawValue;
72
+ }
73
+ break;
74
+ }
75
+ }
76
+ if (errors.length) {
77
+ const message = options.formatError ? options.formatError(errors) : defaultErrorFormatter(errors);
78
+ throw new Error(message);
79
+ }
80
+ return result;
81
+ };
82
+ var defaultErrorFormatter = (errors) => {
83
+ return "\u274C Environment validation failed:\n" + errors.map((e) => `- ${e}`).join("\n");
84
+ };
85
+
86
+ // src/cli.ts
87
+ var args = process.argv.slice(2);
88
+ var getArg = (flag) => {
89
+ const index = args.indexOf(flag);
90
+ return index !== -1 ? args[index + 1] : void 0;
91
+ };
92
+ var hasFlag = (flag) => args.includes(flag);
93
+ var getPositionalArgs = (args2) => {
94
+ return args2.filter((arg, index) => {
95
+ if (arg.startsWith("--")) return false;
96
+ const prev = args2[index - 1];
97
+ if (prev === "--schema" || prev === "--env-file" || prev === "--format") {
98
+ return false;
99
+ }
100
+ return true;
101
+ });
102
+ };
103
+ var printHelp = () => {
104
+ console.log(`
105
+ safe-env-check
106
+
107
+ Usage:
108
+ safe-env-check <schema-file> [options]
109
+
110
+ Options:
111
+ --schema <file> Path to schema file
112
+ --strict Enable strict mode
113
+ --env-file <file> Load a custom .env file
114
+ --format json Output errors as JSON
115
+ --quiet Suppress success message
116
+ --version Show version
117
+ --help Show help
118
+
119
+ Examples:
120
+ safe-env-check env.schema.js
121
+ safe-env-check --schema env.schema.js --strict
122
+ safe-env-check env.schema.js --env-file .env.production
123
+ safe-env-check env.schema.js --format json
124
+ safe-env-check --strict env.schema.js
125
+ `);
126
+ };
127
+ if (hasFlag("--help")) {
128
+ printHelp();
129
+ process.exit(0);
130
+ }
131
+ if (hasFlag("--version")) {
132
+ console.log(version);
133
+ process.exit(0);
134
+ }
135
+ var positionalArgs = getPositionalArgs(args);
136
+ var schemaFile = getArg("--schema") || positionalArgs[0];
137
+ if (!schemaFile) {
138
+ console.error("\u274C Schema file is required.\n");
139
+ printHelp();
140
+ process.exit(1);
141
+ }
142
+ var envFile = getArg("--env-file");
143
+ if (envFile) {
144
+ import_dotenv.default.config({ path: envFile });
145
+ }
146
+ var isStrict = hasFlag("--strict");
147
+ var isQuiet = hasFlag("--quiet");
148
+ var format = getArg("--format");
149
+ try {
150
+ const fullPath = import_path.default.resolve(process.cwd(), schemaFile);
151
+ if (!import_fs.default.existsSync(fullPath)) {
152
+ throw new Error(`Schema file not found: ${schemaFile}`);
153
+ }
154
+ const schema = require(fullPath);
155
+ validateEnv(schema, {
156
+ strict: isStrict,
157
+ formatError: (errors) => {
158
+ if (format === "json") {
159
+ return JSON.stringify({ errors }, null, 2);
160
+ }
161
+ return "\u274C Environment validation failed:\n" + errors.map((e) => `- ${e}`).join("\n");
162
+ }
163
+ });
164
+ if (!isQuiet) {
165
+ console.log("\u2705 Environment variables are valid");
166
+ }
167
+ } catch (error) {
168
+ console.error(error);
169
+ process.exit(1);
170
+ }
package/package.json CHANGED
@@ -1,13 +1,18 @@
1
1
  {
2
2
  "name": "@safe-hand/safe-env-check",
3
- "version": "1.0.3",
3
+ "version": "1.1.0",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/shshamim63/safe-env-check.git"
7
+ },
8
+ "homepage": "https://github.com/your-username/your-repo#readme",
4
9
  "main": "dist/index.js",
5
10
  "types": "dist/index.d.ts",
6
11
  "bin": {
7
12
  "safe-env-check": "dist/cli.js"
8
13
  },
9
14
  "scripts": {
10
- "build": "tsup src/index.ts --dts",
15
+ "build": "tsup src/index.ts src/cli.ts --dts",
11
16
  "dev": "ts-node src/index.ts",
12
17
  "test": "jest",
13
18
  "lint": "tsc --noEmit"
package/src/cli.ts CHANGED
@@ -1,20 +1,143 @@
1
+ import dotenv from "dotenv";
1
2
  import path from "path";
3
+ import fs from "fs";
4
+ import { version } from "../package.json";
2
5
  import { validateEnv } from "./validateEnv";
3
6
 
4
- const schemaPath = process.argv[2];
7
+ const args = process.argv.slice(2);
5
8
 
6
- if (!schemaPath) {
7
- console.error("Usage: safe-env-check <schema-file>");
9
+ /**
10
+ * Get value of a flag: --schema file, --env-file file, --format json
11
+ */
12
+ const getArg = (flag: string): string | undefined => {
13
+ const index = args.indexOf(flag);
14
+ return index !== -1 ? args[index + 1] : undefined;
15
+ };
16
+
17
+ /**
18
+ * Check if flag exists
19
+ */
20
+ const hasFlag = (flag: string) => args.includes(flag);
21
+
22
+ /**
23
+ * Extract positional (non-flag) arguments safely
24
+ */
25
+ const getPositionalArgs = (args: string[]) => {
26
+ return args.filter((arg, index) => {
27
+ // remove flags
28
+ if (arg.startsWith("--")) return false;
29
+
30
+ // remove values of flags
31
+ const prev = args[index - 1];
32
+ if (prev === "--schema" || prev === "--env-file" || prev === "--format") {
33
+ return false;
34
+ }
35
+
36
+ return true;
37
+ });
38
+ };
39
+
40
+ const printHelp = () => {
41
+ console.log(`
42
+ safe-env-check
43
+
44
+ Usage:
45
+ safe-env-check <schema-file> [options]
46
+
47
+ Options:
48
+ --schema <file> Path to schema file
49
+ --strict Enable strict mode
50
+ --env-file <file> Load a custom .env file
51
+ --format json Output errors as JSON
52
+ --quiet Suppress success message
53
+ --version Show version
54
+ --help Show help
55
+
56
+ Examples:
57
+ safe-env-check env.schema.js
58
+ safe-env-check --schema env.schema.js --strict
59
+ safe-env-check env.schema.js --env-file .env.production
60
+ safe-env-check env.schema.js --format json
61
+ safe-env-check --strict env.schema.js
62
+ `);
63
+ };
64
+
65
+ /* =======================
66
+ Early exit flags
67
+ ======================= */
68
+
69
+ if (hasFlag("--help")) {
70
+ printHelp();
71
+ process.exit(0);
72
+ }
73
+
74
+ if (hasFlag("--version")) {
75
+ console.log(version);
76
+ process.exit(0);
77
+ }
78
+
79
+ /* =======================
80
+ Resolve schema file
81
+ ======================= */
82
+
83
+ const positionalArgs = getPositionalArgs(args);
84
+ const schemaFile = getArg("--schema") || positionalArgs[0];
85
+
86
+ if (!schemaFile) {
87
+ console.error("❌ Schema file is required.\n");
88
+ printHelp();
8
89
  process.exit(1);
9
90
  }
10
91
 
92
+ /* =======================
93
+ Load env file if provided
94
+ ======================= */
95
+
96
+ const envFile = getArg("--env-file");
97
+
98
+ if (envFile) {
99
+ dotenv.config({ path: envFile });
100
+ }
101
+
102
+ /* =======================
103
+ Flags
104
+ ======================= */
105
+
106
+ const isStrict = hasFlag("--strict");
107
+ const isQuiet = hasFlag("--quiet");
108
+ const format = getArg("--format");
109
+
110
+ /* =======================
111
+ Main logic
112
+ ======================= */
113
+
11
114
  try {
12
- const fullPath = path.resolve(process.cwd(), schemaPath);
115
+ const fullPath = path.resolve(process.cwd(), schemaFile);
116
+
117
+ if (!fs.existsSync(fullPath)) {
118
+ throw new Error(`Schema file not found: ${schemaFile}`);
119
+ }
120
+
13
121
  const schema = require(fullPath);
14
122
 
15
- validateEnv(schema);
16
- console.log("✅ Environment variables are valid");
17
- } catch (error: any) {
18
- console.error(error.message);
123
+ validateEnv(schema, {
124
+ strict: isStrict,
125
+ formatError: (errors) => {
126
+ if (format === "json") {
127
+ return JSON.stringify({ errors }, null, 2);
128
+ }
129
+
130
+ return (
131
+ "❌ Environment validation failed:\n" +
132
+ errors.map((e) => `- ${e}`).join("\n")
133
+ );
134
+ },
135
+ });
136
+
137
+ if (!isQuiet) {
138
+ console.log("✅ Environment variables are valid");
139
+ }
140
+ } catch (error) {
141
+ console.error(error);
19
142
  process.exit(1);
20
143
  }
@@ -0,0 +1,200 @@
1
+ import path from "path";
2
+
3
+ /**
4
+ * Mock validateEnv
5
+ */
6
+ const mockValidateEnv = jest.fn();
7
+
8
+ jest.mock("../src/validateEnv", () => ({
9
+ validateEnv: mockValidateEnv,
10
+ }));
11
+
12
+ /**
13
+ * Mock fs
14
+ */
15
+ jest.mock("fs", () => ({
16
+ existsSync: jest.fn(),
17
+ }));
18
+
19
+ /**
20
+ * Mock dotenv
21
+ */
22
+ jest.mock("dotenv", () => ({
23
+ config: jest.fn(),
24
+ }));
25
+
26
+ /**
27
+ * Mock package.json version
28
+ */
29
+ jest.mock("../package.json", () => ({
30
+ version: "1.0.0",
31
+ }));
32
+
33
+ describe("CLI", () => {
34
+ const originalArgv = process.argv;
35
+ const originalEnv = process.env;
36
+
37
+ let exitSpy: jest.SpyInstance;
38
+ let logSpy: jest.SpyInstance;
39
+ let errorSpy: jest.SpyInstance;
40
+
41
+ beforeEach(() => {
42
+ jest.resetModules();
43
+
44
+ process.argv = ["node", "cli.ts"];
45
+ process.env = { ...originalEnv };
46
+
47
+ exitSpy = jest.spyOn(process, "exit").mockImplementation((() => {
48
+ throw new Error("process.exit");
49
+ }) as never);
50
+
51
+ logSpy = jest.spyOn(console, "log").mockImplementation(() => {});
52
+ errorSpy = jest.spyOn(console, "error").mockImplementation(() => {});
53
+ });
54
+
55
+ afterEach(() => {
56
+ process.argv = originalArgv;
57
+ process.env = originalEnv;
58
+ jest.restoreAllMocks();
59
+ });
60
+
61
+ test("prints help when --help is passed", () => {
62
+ process.argv = ["node", "cli.ts", "--help"];
63
+
64
+ expect(() => require("../src/cli")).toThrow("process.exit");
65
+
66
+ expect(exitSpy).toHaveBeenCalledWith(0);
67
+ expect(logSpy).toHaveBeenCalled();
68
+ });
69
+
70
+ test("prints version when --version is passed", () => {
71
+ process.argv = ["node", "cli.ts", "--version"];
72
+
73
+ expect(() => require("../src/cli")).toThrow("process.exit");
74
+
75
+ expect(logSpy).toHaveBeenCalledWith("1.0.0");
76
+ expect(exitSpy).toHaveBeenCalledWith(0);
77
+ });
78
+
79
+ test("fails when schema file is missing", () => {
80
+ process.argv = ["node", "cli.ts"];
81
+
82
+ expect(() => require("../src/cli")).toThrow("process.exit");
83
+
84
+ expect(errorSpy).toHaveBeenCalledWith("❌ Schema file is required.\n");
85
+ expect(exitSpy).toHaveBeenCalledWith(1);
86
+ });
87
+
88
+ test("fails if schema file does not exist", () => {
89
+ const fs = require("fs");
90
+ fs.existsSync.mockReturnValue(false);
91
+
92
+ process.argv = ["node", "cli.ts", "env.schema.js"];
93
+
94
+ expect(() => require("../src/cli")).toThrow("process.exit");
95
+ expect(exitSpy).toHaveBeenCalledWith(1);
96
+ });
97
+
98
+ test("loads custom env file when --env-file is provided", () => {
99
+ const fs = require("fs");
100
+ const dotenv = require("dotenv");
101
+
102
+ fs.existsSync.mockReturnValue(true);
103
+
104
+ const schemaPath = path.resolve(process.cwd(), "env.schema.js");
105
+
106
+ jest.doMock(schemaPath, () => ({}), { virtual: true });
107
+
108
+ process.argv = [
109
+ "node",
110
+ "cli.ts",
111
+ "env.schema.js",
112
+ "--env-file",
113
+ ".env.production",
114
+ ];
115
+
116
+ mockValidateEnv.mockImplementation(() => ({}));
117
+
118
+ require("../src/cli");
119
+
120
+ expect(dotenv.config).toHaveBeenCalledWith({
121
+ path: ".env.production",
122
+ });
123
+ });
124
+
125
+ test("calls validateEnv with correct options", () => {
126
+ const fs = require("fs");
127
+ fs.existsSync.mockReturnValue(true);
128
+
129
+ const schemaPath = path.resolve(process.cwd(), "env.schema.js");
130
+
131
+ jest.doMock(
132
+ schemaPath,
133
+ () => ({
134
+ PORT: { type: "number", required: true },
135
+ }),
136
+ { virtual: true },
137
+ );
138
+
139
+ process.argv = [
140
+ "node",
141
+ "cli.ts",
142
+ "env.schema.js",
143
+ "--strict",
144
+ "--format",
145
+ "json",
146
+ ];
147
+
148
+ mockValidateEnv.mockImplementation(() => ({}));
149
+
150
+ require("../src/cli");
151
+
152
+ expect(mockValidateEnv).toHaveBeenCalledWith(
153
+ expect.any(Object),
154
+ expect.objectContaining({
155
+ strict: true,
156
+ formatError: expect.any(Function),
157
+ }),
158
+ );
159
+
160
+ expect(logSpy).toHaveBeenCalledWith("✅ Environment variables are valid");
161
+ });
162
+
163
+ test("suppresses success message with --quiet", () => {
164
+ const fs = require("fs");
165
+ fs.existsSync.mockReturnValue(true);
166
+
167
+ const schemaPath = path.resolve(process.cwd(), "env.schema.js");
168
+
169
+ jest.doMock(schemaPath, () => ({}), { virtual: true });
170
+
171
+ process.argv = ["node", "cli.ts", "env.schema.js", "--quiet"];
172
+
173
+ mockValidateEnv.mockImplementation(() => ({}));
174
+
175
+ require("../src/cli");
176
+
177
+ expect(logSpy).not.toHaveBeenCalledWith(
178
+ "✅ Environment variables are valid",
179
+ );
180
+ });
181
+
182
+ test("prints formatted error when validateEnv throws", () => {
183
+ const fs = require("fs");
184
+ fs.existsSync.mockReturnValue(true);
185
+
186
+ const schemaPath = path.resolve(process.cwd(), "env.schema.js");
187
+
188
+ jest.doMock(schemaPath, () => ({}), { virtual: true });
189
+
190
+ process.argv = ["node", "cli.ts", "env.schema.js", "--format", "json"];
191
+
192
+ mockValidateEnv.mockImplementation(() => {
193
+ throw new Error(JSON.stringify({ errors: ["PORT is required"] }));
194
+ });
195
+
196
+ expect(() => require("../src/cli")).toThrow("process.exit");
197
+
198
+ expect(exitSpy).toHaveBeenCalledWith(1);
199
+ });
200
+ });
package/tsconfig.json CHANGED
@@ -7,6 +7,7 @@
7
7
  "rootDir": "src",
8
8
  "strict": true,
9
9
  "moduleResolution": "node",
10
+ "resolveJsonModule": true,
10
11
  "esModuleInterop": true,
11
12
  "skipLibCheck": true
12
13
  },