arkenv 0.7.1 → 0.7.3

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 CHANGED
@@ -14,6 +14,10 @@
14
14
  </p>
15
15
  <h3 align="center">Proud member of the <a href="https://arktype.io/docs/ecosystem#arkenv">ArkType ecosystem</a></h3>
16
16
 
17
+ <p align="center">
18
+ <img alt="ArkEnv Demo" src="https://arkenv.js.org/assets/demo.gif" />
19
+ </p>
20
+
17
21
  <br/>
18
22
  <br/>
19
23
  <br/>
@@ -23,12 +27,13 @@
23
27
  <br/>
24
28
  <br/>
25
29
 
26
- ## Introduction
30
+ ## Introduction
27
31
 
32
+ > [!TIP]
33
+ > 📖 **Reading this on GitHub?** Check out [this page in our docs](https://arkenv.js.org/docs) to hover over code blocks and get type hints!
28
34
 
29
35
  ArkEnv is an environment variable parser powered by [ArkType](https://arktype.io/), TypeScript's 1:1 validator. ArkEnv lets you use familiar TypeScript-like syntax to create a ready to use, typesafe environment variable object:
30
36
 
31
-
32
37
  ```ts twoslash
33
38
  import arkenv from 'arkenv';
34
39
 
@@ -38,12 +43,10 @@ const env = arkenv({
38
43
  NODE_ENV: "'development' | 'production' | 'test'",
39
44
  });
40
45
 
41
-
42
- // Automatically validate and parse process.env
43
- // TypeScript knows the ✨exact✨ types!
44
- console.log(env.HOST); // (property) HOST: string
45
- console.log(env.PORT); // (property) PORT: number
46
- console.log(env.NODE_ENV); // (property) NODE_ENV: "development" | "production" | "test"
46
+ // Hover to see ✨exact✨ types
47
+ const host = env.HOST;
48
+ const port = env.PORT;
49
+ const nodeEnv = env.NODE_ENV;
47
50
  ```
48
51
 
49
52
  With ArkEnv, your environment variables are **guaranteed to match your schema**. If any variable is incorrect or missing, the app won't start and a clear error will be thrown:
@@ -61,7 +64,9 @@ ArkEnvError: Errors found while validating environment variables
61
64
  - Tiny: <1kB gzipped
62
65
  - Build-time and runtime validation
63
66
  - Single import, zero config for most projects
67
+ - Validated, defaultable, typesafe environment variables
64
68
  - Powered by ArkType, TypeScript's 1:1 validator
69
+ - Optimized from editor to runtime
65
70
 
66
71
  ## Installation
67
72
 
@@ -99,16 +104,13 @@ bun add arkenv arktype
99
104
 
100
105
  :rocket: **Let's get started!** Read the [2-minute setup guide](https://arkenv.js.org/docs/quickstart) or [start with an example](https://arkenv.js.org/docs/examples).
101
106
 
102
-
103
107
  > [!TIP]
104
- > Improve your DX with syntax highlighting in [VS Code & Cursor](/docs/integrations/vscode) or [JetBrains IDEs](/docs/integrations/jetbrains).
105
- >
106
- > ![ArkType syntax highlighting in VS Code](https://raw.githubusercontent.com/yamcodes/arkenv/main/assets/dx.png)
108
+ > Improve your DX with *syntax highlighting* in [VS Code & Cursor](https://arkenv.js.org/docs/integrations/vscode) or [JetBrains IDEs](https://arkenv.js.org/docs/integrations/jetbrains).
107
109
 
108
110
  ## Requirements
109
111
 
110
112
  - TypeScript >= 5.1 and [anything else required by ArkType](https://arktype.io/docs/intro/setup#installation)
111
- - [Node.js 22 LTS](https://github.com/yamcodes/arkenv/tree/main/examples/basic), [Bun 1.2](https://github.com/yamcodes/arkenv/tree/main/examples/with-bun), and [Vite 7](https://github.com/yamcodes/arkenv/tree/main/examples/with-vite-react-ts) are tested. Older versions may work but aren't officially supported
113
+ - Tested on [Node.js 22 LTS](https://github.com/yamcodes/arkenv/tree/main/examples/basic), [Bun 1.2](https://github.com/yamcodes/arkenv/tree/main/examples/with-bun), and [Vite from **2.9.18** to **7.x**](https://github.com/yamcodes/arkenv/tree/main/examples/with-vite-react-ts). Older versions may work but are not officially supported
112
114
 
113
115
  ## Plugins
114
116
 
package/dist/index.cjs CHANGED
@@ -1,113 +1,137 @@
1
- "use strict";
1
+ Object.defineProperty(exports, '__esModule', { value: true });
2
+ //#region rolldown:runtime
3
+ var __create = Object.create;
2
4
  var __defProp = Object.defineProperty;
3
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
5
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
9
  var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
17
18
  };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
23
- ArkEnvError: () => ArkEnvError,
24
- createEnv: () => createEnv,
25
- default: () => index_default,
26
- type: () => type4
27
- });
28
- module.exports = __toCommonJS(index_exports);
29
-
30
- // src/create-env.ts
31
- var import_arktype3 = require("arktype");
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
32
23
 
33
- // src/errors.ts
34
- var import_node_util = require("util");
24
+ //#endregion
25
+ let arktype = require("arktype");
26
+ arktype = __toESM(arktype);
27
+ let node_util = require("node:util");
28
+ node_util = __toESM(node_util);
35
29
 
36
- // src/utils.ts
37
- var indent = (str, amt = 2, { dontDetectNewlines = false } = {}) => {
38
- const detectNewlines = !dontDetectNewlines;
39
- if (detectNewlines) {
40
- return str.split("\n").map((line) => `${" ".repeat(amt)}${line}`).join("\n");
41
- }
42
- return `${" ".repeat(amt)}${str}`;
30
+ //#region src/utils.ts
31
+ /**
32
+ * Indent a string by a given amount
33
+ * @param str - The string to indent
34
+ * @param amt - The amount to indent by, defaults to 2
35
+ * @param options - {@link IndentOptions}
36
+ * @returns The indented string
37
+ */
38
+ const indent = (str, amt = 2, { dontDetectNewlines = false } = {}) => {
39
+ if (!dontDetectNewlines) return str.split("\n").map((line) => `${" ".repeat(amt)}${line}`).join("\n");
40
+ return `${" ".repeat(amt)}${str}`;
43
41
  };
44
42
 
45
- // src/errors.ts
46
- var formatErrors = (errors) => Object.entries(errors.byPath).map(([path, error]) => {
47
- const messageWithoutPath = error.message.startsWith(path) ? error.message.slice(path.length) : error.message;
48
- const valueMatch = messageWithoutPath.match(/\(was "([^"]+)"\)/);
49
- const formattedMessage = valueMatch ? messageWithoutPath.replace(
50
- `(was "${valueMatch[1]}")`,
51
- `(was ${(0, import_node_util.styleText)("cyan", `"${valueMatch[1]}"`)})`
52
- ) : messageWithoutPath;
53
- return `${(0, import_node_util.styleText)("yellow", path)}${formattedMessage}`;
43
+ //#endregion
44
+ //#region src/errors.ts
45
+ /**
46
+ * Format the errors returned by ArkType to be more readable
47
+ * @param errors - The errors returned by ArkType
48
+ * @returns A string of the formatted errors
49
+ */
50
+ const formatErrors = (errors) => Object.entries(errors.byPath).map(([path, error]) => {
51
+ const messageWithoutPath = error.message.startsWith(path) ? error.message.slice(path.length) : error.message;
52
+ const valueMatch = messageWithoutPath.match(/\(was "([^"]+)"\)/);
53
+ const formattedMessage = valueMatch ? messageWithoutPath.replace(`(was "${valueMatch[1]}")`, `(was ${(0, node_util.styleText)("cyan", `"${valueMatch[1]}"`)})`) : messageWithoutPath;
54
+ return `${(0, node_util.styleText)("yellow", path)}${formattedMessage}`;
54
55
  }).join("\n");
55
56
  var ArkEnvError = class extends Error {
56
- constructor(errors, message = "Errors found while validating environment variables") {
57
- super(`${(0, import_node_util.styleText)("red", message)}
58
- ${indent(formatErrors(errors))}
59
- `);
60
- this.name = "ArkEnvError";
61
- }
57
+ constructor(errors, message = "Errors found while validating environment variables") {
58
+ super(`${(0, node_util.styleText)("red", message)}\n${indent(formatErrors(errors))}\n`);
59
+ this.name = "ArkEnvError";
60
+ }
62
61
  };
63
62
 
64
- // src/scope.ts
65
- var import_arktype2 = require("arktype");
66
-
67
- // src/types.ts
68
- var import_arktype = require("arktype");
69
- var port = (0, import_arktype.type)("string", "=>", (data, ctx) => {
70
- const asNumber = Number.parseInt(data, 10);
71
- const isInteger = Number.isInteger(asNumber);
72
- const isBetween = 0 <= asNumber && asNumber <= 65535;
73
- if (!isInteger || !isBetween) {
74
- ctx.mustBe("an integer between 0 and 65535");
75
- }
76
- return asNumber;
63
+ //#endregion
64
+ //#region src/types.ts
65
+ /**
66
+ * A `string` that can be parsed into a number between 0 and 65535
67
+ */
68
+ const port = (0, arktype.type)("string", "=>", (data, ctx) => {
69
+ const asNumber = Number.parseInt(data, 10);
70
+ if (!Number.isInteger(asNumber) || !(0 <= asNumber && asNumber <= 65535)) ctx.mustBe("an integer between 0 and 65535");
71
+ return asNumber;
77
72
  });
78
- var host = (0, import_arktype.type)("string.ip | 'localhost'");
73
+ /**
74
+ * An IP address or `"localhost"`
75
+ */
76
+ const host = (0, arktype.type)("string.ip | 'localhost'");
77
+ /**
78
+ * A boolean that accepts string values and converts them to boolean
79
+ * Accepts "true" or "false" strings and converts them to actual boolean values
80
+ */
81
+ const boolean = (0, arktype.type)("'true' | 'false' | true | false", "=>", (str) => str === "true" || str === true);
79
82
 
80
- // src/scope.ts
81
- var $ = (0, import_arktype2.scope)({
82
- string: import_arktype2.type.module({
83
- ...import_arktype2.type.keywords.string,
84
- host
85
- }),
86
- number: import_arktype2.type.module({
87
- ...import_arktype2.type.keywords.number,
88
- port
89
- })
83
+ //#endregion
84
+ //#region src/scope.ts
85
+ /**
86
+ * The root scope for the ArkEnv library, containing extensions to the ArkType scopes with ArkEnv-specific types like `string.host` and `number.port`.
87
+ */
88
+ const $ = (0, arktype.scope)({
89
+ string: arktype.type.module({
90
+ ...arktype.type.keywords.string,
91
+ host
92
+ }),
93
+ number: arktype.type.module({
94
+ ...arktype.type.keywords.number,
95
+ port
96
+ }),
97
+ boolean
90
98
  });
91
99
 
92
- // src/create-env.ts
100
+ //#endregion
101
+ //#region src/create-env.ts
102
+ /**
103
+ * TODO: If possible, find a better type than "const T extends Record<string, unknown>",
104
+ * and be as close as possible to the type accepted by ArkType's `type`.
105
+ */
106
+ /**
107
+ * Create an environment variables object from a schema and an environment
108
+ * @param def - The environment variable schema
109
+ * @param env - The environment variables to validate, defaults to `process.env`
110
+ * @returns The validated environment variable schema
111
+ * @throws An {@link ArkEnvError | error} if the environment variables are invalid.
112
+ */
93
113
  function createEnv(def, env = process.env) {
94
- const schema = $.type.raw(def);
95
- const validatedEnv = schema(env);
96
- if (validatedEnv instanceof import_arktype3.type.errors) {
97
- throw new ArkEnvError(validatedEnv);
98
- }
99
- return validatedEnv;
114
+ const validatedEnv = $.type.raw(def)(env);
115
+ if (validatedEnv instanceof arktype.type.errors) throw new ArkEnvError(validatedEnv);
116
+ return validatedEnv;
100
117
  }
101
118
 
102
- // src/type.ts
103
- var type4 = $.type;
119
+ //#endregion
120
+ //#region src/type.ts
121
+ const type = $.type;
104
122
 
105
- // src/index.ts
106
- var arkenv = createEnv;
107
- var index_default = arkenv;
108
- // Annotate the CommonJS export names for ESM import in node:
109
- 0 && (module.exports = {
110
- ArkEnvError,
111
- createEnv,
112
- type
113
- });
123
+ //#endregion
124
+ //#region src/index.ts
125
+ /**
126
+ * `arkenv`'s main export, an alias for {@link createEnv}
127
+ *
128
+ * {@link https://arkenv.js.org | ArkEnv} is a typesafe environment variables parser powered by {@link https://arktype.io | ArkType}, TypeScript's 1:1 validator.
129
+ */
130
+ const arkenv = createEnv;
131
+ var src_default = arkenv;
132
+
133
+ //#endregion
134
+ exports.ArkEnvError = ArkEnvError;
135
+ exports.createEnv = createEnv;
136
+ exports.default = src_default;
137
+ exports.type = type;
package/dist/index.d.cts CHANGED
@@ -1,86 +1,93 @@
1
- import * as arktype from 'arktype';
2
- import { type as type$1, distill, ArkErrors } from 'arktype';
3
- import * as arktype_internal_attributes_ts from 'arktype/internal/attributes.ts';
4
- import * as arktype_internal_keywords_string_ts from 'arktype/internal/keywords/string.ts';
5
- import * as arktype_internal_type_ts from 'arktype/internal/type.ts';
1
+ import * as arktype16 from "arktype";
2
+ import { ArkErrors, distill, type as type$1 } from "arktype";
3
+ import * as arktype_internal_keywords_string_ts10 from "arktype/internal/keywords/string.ts";
4
+ import * as arktype_internal_attributes_ts5 from "arktype/internal/attributes.ts";
5
+ import * as arktype_internal_type_ts0 from "arktype/internal/type.ts";
6
6
 
7
+ //#region src/scope.d.ts
7
8
  /**
8
9
  * The root scope for the ArkEnv library, containing extensions to the ArkType scopes with ArkEnv-specific types like `string.host` and `number.port`.
9
10
  */
10
- declare const $: arktype.Scope<{
11
- string: arktype.Submodule<{
12
- root: string;
13
- " arkInferred": string;
14
- trim: arktype.Submodule<arktype_internal_keywords_string_ts.trim.$ & {
15
- " arkInferred": (In: string) => arktype_internal_attributes_ts.To<string>;
16
- }>;
17
- normalize: arktype.Submodule<arktype_internal_keywords_string_ts.normalize.$ & {
18
- " arkInferred": (In: string) => arktype_internal_attributes_ts.To<string>;
19
- }>;
20
- alpha: string;
21
- alphanumeric: string;
22
- hex: string;
23
- base64: arktype.Submodule<{
24
- root: string;
25
- url: string;
26
- } & {
27
- " arkInferred": string;
28
- }>;
29
- capitalize: arktype.Submodule<arktype_internal_keywords_string_ts.capitalize.$ & {
30
- " arkInferred": (In: string) => arktype_internal_attributes_ts.To<string>;
31
- }>;
32
- creditCard: string;
33
- date: arktype.Submodule<arktype_internal_keywords_string_ts.stringDate.$ & {
34
- " arkInferred": string;
35
- }>;
36
- digits: string;
37
- email: string;
38
- integer: arktype.Submodule<arktype_internal_keywords_string_ts.stringInteger.$ & {
39
- " arkInferred": string;
40
- }>;
41
- ip: arktype.Submodule<arktype_internal_keywords_string_ts.ip.$ & {
42
- " arkInferred": string;
43
- }>;
44
- json: arktype.Submodule<arktype_internal_keywords_string_ts.stringJson.$ & {
45
- " arkInferred": string;
46
- }>;
47
- lower: arktype.Submodule<arktype_internal_keywords_string_ts.lower.$ & {
48
- " arkInferred": (In: string) => arktype_internal_attributes_ts.To<string>;
49
- }>;
50
- numeric: arktype.Submodule<arktype_internal_keywords_string_ts.stringNumeric.$ & {
51
- " arkInferred": string;
52
- }>;
53
- regex: string;
54
- semver: string;
55
- upper: arktype.Submodule<{
56
- root: (In: string) => arktype_internal_attributes_ts.To<string>;
57
- preformatted: string;
58
- } & {
59
- " arkInferred": (In: string) => arktype_internal_attributes_ts.To<string>;
60
- }>;
61
- url: arktype.Submodule<arktype_internal_keywords_string_ts.url.$ & {
62
- " arkInferred": string;
63
- }>;
64
- uuid: arktype.Submodule<arktype_internal_keywords_string_ts.uuid.$ & {
65
- " arkInferred": string;
66
- }>;
67
- host: string;
68
- }>;
69
- number: arktype.Submodule<{
70
- NaN: number;
71
- Infinity: number;
72
- root: number;
73
- " arkInferred": number;
74
- integer: number;
75
- epoch: number;
76
- safe: number;
77
- NegativeInfinity: number;
78
- port: (In: string) => arktype.Out<number>;
11
+ declare const $: arktype16.Scope<{
12
+ string: arktype16.Submodule<{
13
+ trim: arktype16.Submodule<arktype_internal_keywords_string_ts10.trim.$ & {
14
+ " arkInferred": (In: string) => arktype_internal_attributes_ts5.To<string>;
79
15
  }>;
16
+ normalize: arktype16.Submodule<arktype_internal_keywords_string_ts10.normalize.$ & {
17
+ " arkInferred": (In: string) => arktype_internal_attributes_ts5.To<string>;
18
+ }>;
19
+ root: string;
20
+ alpha: string;
21
+ alphanumeric: string;
22
+ hex: string;
23
+ base64: arktype16.Submodule<{
24
+ root: string;
25
+ url: string;
26
+ } & {
27
+ " arkInferred": string;
28
+ }>;
29
+ capitalize: arktype16.Submodule<arktype_internal_keywords_string_ts10.capitalize.$ & {
30
+ " arkInferred": (In: string) => arktype_internal_attributes_ts5.To<string>;
31
+ }>;
32
+ creditCard: string;
33
+ date: arktype16.Submodule<arktype_internal_keywords_string_ts10.stringDate.$ & {
34
+ " arkInferred": string;
35
+ }>;
36
+ digits: string;
37
+ email: string;
38
+ integer: arktype16.Submodule<arktype_internal_keywords_string_ts10.stringInteger.$ & {
39
+ " arkInferred": string;
40
+ }>;
41
+ ip: arktype16.Submodule<arktype_internal_keywords_string_ts10.ip.$ & {
42
+ " arkInferred": string;
43
+ }>;
44
+ json: arktype16.Submodule<arktype_internal_keywords_string_ts10.stringJson.$ & {
45
+ " arkInferred": string;
46
+ }>;
47
+ lower: arktype16.Submodule<arktype_internal_keywords_string_ts10.lower.$ & {
48
+ " arkInferred": (In: string) => arktype_internal_attributes_ts5.To<string>;
49
+ }>;
50
+ numeric: arktype16.Submodule<arktype_internal_keywords_string_ts10.stringNumeric.$ & {
51
+ " arkInferred": string;
52
+ }>;
53
+ regex: string;
54
+ semver: string;
55
+ upper: arktype16.Submodule<{
56
+ root: (In: string) => arktype_internal_attributes_ts5.To<string>;
57
+ preformatted: string;
58
+ } & {
59
+ " arkInferred": (In: string) => arktype_internal_attributes_ts5.To<string>;
60
+ }>;
61
+ url: arktype16.Submodule<arktype_internal_keywords_string_ts10.url.$ & {
62
+ " arkInferred": string;
63
+ }>;
64
+ uuid: arktype16.Submodule<arktype_internal_keywords_string_ts10.uuid.$ & {
65
+ " arkInferred": string;
66
+ }>;
67
+ " arkInferred": string;
68
+ host: string;
69
+ }>;
70
+ number: arktype16.Submodule<{
71
+ NaN: number;
72
+ Infinity: number;
73
+ root: number;
74
+ integer: number;
75
+ " arkInferred": number;
76
+ epoch: number;
77
+ safe: number;
78
+ NegativeInfinity: number;
79
+ port: (In: string) => arktype16.Out<number>;
80
+ }>;
81
+ boolean: (In: boolean | "false" | "true") => arktype16.Out<boolean>;
80
82
  }>;
81
-
83
+ //#endregion
84
+ //#region src/create-env.d.ts
82
85
  type RuntimeEnvironment = Record<string, string | undefined>;
83
86
  type EnvSchema<def> = type$1.validate<def, (typeof $)["t"]>;
87
+ /**
88
+ * TODO: If possible, find a better type than "const T extends Record<string, unknown>",
89
+ * and be as close as possible to the type accepted by ArkType's `type`.
90
+ */
84
91
  /**
85
92
  * Create an environment variables object from a schema and an environment
86
93
  * @param def - The environment variable schema
@@ -88,89 +95,93 @@ type EnvSchema<def> = type$1.validate<def, (typeof $)["t"]>;
88
95
  * @returns The validated environment variable schema
89
96
  * @throws An {@link ArkEnvError | error} if the environment variables are invalid.
90
97
  */
91
- declare function createEnv<const T extends Record<string, string | undefined>>(def: EnvSchema<T>, env?: RuntimeEnvironment): distill.Out<type$1.infer<T, (typeof $)["t"]>>;
92
-
93
- declare const type: arktype_internal_type_ts.TypeParser<{
94
- string: arktype.Submodule<{
95
- root: string;
96
- " arkInferred": string;
97
- trim: arktype.Submodule<arktype_internal_keywords_string_ts.trim.$ & {
98
- " arkInferred": (In: string) => arktype_internal_attributes_ts.To<string>;
99
- }>;
100
- normalize: arktype.Submodule<arktype_internal_keywords_string_ts.normalize.$ & {
101
- " arkInferred": (In: string) => arktype_internal_attributes_ts.To<string>;
102
- }>;
103
- alpha: string;
104
- alphanumeric: string;
105
- hex: string;
106
- base64: arktype.Submodule<{
107
- root: string;
108
- url: string;
109
- } & {
110
- " arkInferred": string;
111
- }>;
112
- capitalize: arktype.Submodule<arktype_internal_keywords_string_ts.capitalize.$ & {
113
- " arkInferred": (In: string) => arktype_internal_attributes_ts.To<string>;
114
- }>;
115
- creditCard: string;
116
- date: arktype.Submodule<arktype_internal_keywords_string_ts.stringDate.$ & {
117
- " arkInferred": string;
118
- }>;
119
- digits: string;
120
- email: string;
121
- integer: arktype.Submodule<arktype_internal_keywords_string_ts.stringInteger.$ & {
122
- " arkInferred": string;
123
- }>;
124
- ip: arktype.Submodule<arktype_internal_keywords_string_ts.ip.$ & {
125
- " arkInferred": string;
126
- }>;
127
- json: arktype.Submodule<arktype_internal_keywords_string_ts.stringJson.$ & {
128
- " arkInferred": string;
129
- }>;
130
- lower: arktype.Submodule<arktype_internal_keywords_string_ts.lower.$ & {
131
- " arkInferred": (In: string) => arktype_internal_attributes_ts.To<string>;
132
- }>;
133
- numeric: arktype.Submodule<arktype_internal_keywords_string_ts.stringNumeric.$ & {
134
- " arkInferred": string;
135
- }>;
136
- regex: string;
137
- semver: string;
138
- upper: arktype.Submodule<{
139
- root: (In: string) => arktype_internal_attributes_ts.To<string>;
140
- preformatted: string;
141
- } & {
142
- " arkInferred": (In: string) => arktype_internal_attributes_ts.To<string>;
143
- }>;
144
- url: arktype.Submodule<arktype_internal_keywords_string_ts.url.$ & {
145
- " arkInferred": string;
146
- }>;
147
- uuid: arktype.Submodule<arktype_internal_keywords_string_ts.uuid.$ & {
148
- " arkInferred": string;
149
- }>;
150
- host: string;
151
- }>;
152
- number: arktype.Submodule<{
153
- NaN: number;
154
- Infinity: number;
155
- root: number;
156
- " arkInferred": number;
157
- integer: number;
158
- epoch: number;
159
- safe: number;
160
- NegativeInfinity: number;
161
- port: (In: string) => arktype.Out<number>;
98
+ declare function createEnv<const T extends Record<string, unknown>>(def: EnvSchema<T>, env?: RuntimeEnvironment): distill.Out<type$1.infer<T, (typeof $)["t"]>>;
99
+ //#endregion
100
+ //#region src/type.d.ts
101
+ declare const type: arktype_internal_type_ts0.TypeParser<{
102
+ string: arktype16.Submodule<{
103
+ trim: arktype16.Submodule<arktype_internal_keywords_string_ts10.trim.$ & {
104
+ " arkInferred": (In: string) => arktype_internal_attributes_ts5.To<string>;
162
105
  }>;
106
+ normalize: arktype16.Submodule<arktype_internal_keywords_string_ts10.normalize.$ & {
107
+ " arkInferred": (In: string) => arktype_internal_attributes_ts5.To<string>;
108
+ }>;
109
+ root: string;
110
+ alpha: string;
111
+ alphanumeric: string;
112
+ hex: string;
113
+ base64: arktype16.Submodule<{
114
+ root: string;
115
+ url: string;
116
+ } & {
117
+ " arkInferred": string;
118
+ }>;
119
+ capitalize: arktype16.Submodule<arktype_internal_keywords_string_ts10.capitalize.$ & {
120
+ " arkInferred": (In: string) => arktype_internal_attributes_ts5.To<string>;
121
+ }>;
122
+ creditCard: string;
123
+ date: arktype16.Submodule<arktype_internal_keywords_string_ts10.stringDate.$ & {
124
+ " arkInferred": string;
125
+ }>;
126
+ digits: string;
127
+ email: string;
128
+ integer: arktype16.Submodule<arktype_internal_keywords_string_ts10.stringInteger.$ & {
129
+ " arkInferred": string;
130
+ }>;
131
+ ip: arktype16.Submodule<arktype_internal_keywords_string_ts10.ip.$ & {
132
+ " arkInferred": string;
133
+ }>;
134
+ json: arktype16.Submodule<arktype_internal_keywords_string_ts10.stringJson.$ & {
135
+ " arkInferred": string;
136
+ }>;
137
+ lower: arktype16.Submodule<arktype_internal_keywords_string_ts10.lower.$ & {
138
+ " arkInferred": (In: string) => arktype_internal_attributes_ts5.To<string>;
139
+ }>;
140
+ numeric: arktype16.Submodule<arktype_internal_keywords_string_ts10.stringNumeric.$ & {
141
+ " arkInferred": string;
142
+ }>;
143
+ regex: string;
144
+ semver: string;
145
+ upper: arktype16.Submodule<{
146
+ root: (In: string) => arktype_internal_attributes_ts5.To<string>;
147
+ preformatted: string;
148
+ } & {
149
+ " arkInferred": (In: string) => arktype_internal_attributes_ts5.To<string>;
150
+ }>;
151
+ url: arktype16.Submodule<arktype_internal_keywords_string_ts10.url.$ & {
152
+ " arkInferred": string;
153
+ }>;
154
+ uuid: arktype16.Submodule<arktype_internal_keywords_string_ts10.uuid.$ & {
155
+ " arkInferred": string;
156
+ }>;
157
+ " arkInferred": string;
158
+ host: string;
159
+ }>;
160
+ number: arktype16.Submodule<{
161
+ NaN: number;
162
+ Infinity: number;
163
+ root: number;
164
+ integer: number;
165
+ " arkInferred": number;
166
+ epoch: number;
167
+ safe: number;
168
+ NegativeInfinity: number;
169
+ port: (In: string) => arktype16.Out<number>;
170
+ }>;
171
+ boolean: (In: boolean | "false" | "true") => arktype16.Out<boolean>;
163
172
  }>;
164
-
173
+ //#endregion
174
+ //#region src/errors.d.ts
165
175
  declare class ArkEnvError extends Error {
166
- constructor(errors: ArkErrors, message?: string);
176
+ constructor(errors: ArkErrors, message?: string);
167
177
  }
168
-
178
+ //#endregion
179
+ //#region src/index.d.ts
169
180
  /**
170
181
  * `arkenv`'s main export, an alias for {@link createEnv}
171
182
  *
172
183
  * {@link https://arkenv.js.org | ArkEnv} is a typesafe environment variables parser powered by {@link https://arktype.io | ArkType}, TypeScript's 1:1 validator.
173
184
  */
174
185
  declare const arkenv: typeof createEnv;
175
-
176
- export { ArkEnvError, type EnvSchema, createEnv, arkenv as default, type };
186
+ //#endregion
187
+ export { ArkEnvError, type EnvSchema, createEnv, arkenv as default, type };
package/dist/index.d.ts CHANGED
@@ -1,86 +1,93 @@
1
- import * as arktype from 'arktype';
2
- import { type as type$1, distill, ArkErrors } from 'arktype';
3
- import * as arktype_internal_attributes_ts from 'arktype/internal/attributes.ts';
4
- import * as arktype_internal_keywords_string_ts from 'arktype/internal/keywords/string.ts';
5
- import * as arktype_internal_type_ts from 'arktype/internal/type.ts';
1
+ import * as arktype16 from "arktype";
2
+ import { ArkErrors, distill, type as type$1 } from "arktype";
3
+ import * as arktype_internal_keywords_string_ts10 from "arktype/internal/keywords/string.ts";
4
+ import * as arktype_internal_attributes_ts5 from "arktype/internal/attributes.ts";
5
+ import * as arktype_internal_type_ts0 from "arktype/internal/type.ts";
6
6
 
7
+ //#region src/scope.d.ts
7
8
  /**
8
9
  * The root scope for the ArkEnv library, containing extensions to the ArkType scopes with ArkEnv-specific types like `string.host` and `number.port`.
9
10
  */
10
- declare const $: arktype.Scope<{
11
- string: arktype.Submodule<{
12
- root: string;
13
- " arkInferred": string;
14
- trim: arktype.Submodule<arktype_internal_keywords_string_ts.trim.$ & {
15
- " arkInferred": (In: string) => arktype_internal_attributes_ts.To<string>;
16
- }>;
17
- normalize: arktype.Submodule<arktype_internal_keywords_string_ts.normalize.$ & {
18
- " arkInferred": (In: string) => arktype_internal_attributes_ts.To<string>;
19
- }>;
20
- alpha: string;
21
- alphanumeric: string;
22
- hex: string;
23
- base64: arktype.Submodule<{
24
- root: string;
25
- url: string;
26
- } & {
27
- " arkInferred": string;
28
- }>;
29
- capitalize: arktype.Submodule<arktype_internal_keywords_string_ts.capitalize.$ & {
30
- " arkInferred": (In: string) => arktype_internal_attributes_ts.To<string>;
31
- }>;
32
- creditCard: string;
33
- date: arktype.Submodule<arktype_internal_keywords_string_ts.stringDate.$ & {
34
- " arkInferred": string;
35
- }>;
36
- digits: string;
37
- email: string;
38
- integer: arktype.Submodule<arktype_internal_keywords_string_ts.stringInteger.$ & {
39
- " arkInferred": string;
40
- }>;
41
- ip: arktype.Submodule<arktype_internal_keywords_string_ts.ip.$ & {
42
- " arkInferred": string;
43
- }>;
44
- json: arktype.Submodule<arktype_internal_keywords_string_ts.stringJson.$ & {
45
- " arkInferred": string;
46
- }>;
47
- lower: arktype.Submodule<arktype_internal_keywords_string_ts.lower.$ & {
48
- " arkInferred": (In: string) => arktype_internal_attributes_ts.To<string>;
49
- }>;
50
- numeric: arktype.Submodule<arktype_internal_keywords_string_ts.stringNumeric.$ & {
51
- " arkInferred": string;
52
- }>;
53
- regex: string;
54
- semver: string;
55
- upper: arktype.Submodule<{
56
- root: (In: string) => arktype_internal_attributes_ts.To<string>;
57
- preformatted: string;
58
- } & {
59
- " arkInferred": (In: string) => arktype_internal_attributes_ts.To<string>;
60
- }>;
61
- url: arktype.Submodule<arktype_internal_keywords_string_ts.url.$ & {
62
- " arkInferred": string;
63
- }>;
64
- uuid: arktype.Submodule<arktype_internal_keywords_string_ts.uuid.$ & {
65
- " arkInferred": string;
66
- }>;
67
- host: string;
68
- }>;
69
- number: arktype.Submodule<{
70
- NaN: number;
71
- Infinity: number;
72
- root: number;
73
- " arkInferred": number;
74
- integer: number;
75
- epoch: number;
76
- safe: number;
77
- NegativeInfinity: number;
78
- port: (In: string) => arktype.Out<number>;
11
+ declare const $: arktype16.Scope<{
12
+ string: arktype16.Submodule<{
13
+ trim: arktype16.Submodule<arktype_internal_keywords_string_ts10.trim.$ & {
14
+ " arkInferred": (In: string) => arktype_internal_attributes_ts5.To<string>;
79
15
  }>;
16
+ normalize: arktype16.Submodule<arktype_internal_keywords_string_ts10.normalize.$ & {
17
+ " arkInferred": (In: string) => arktype_internal_attributes_ts5.To<string>;
18
+ }>;
19
+ root: string;
20
+ alpha: string;
21
+ alphanumeric: string;
22
+ hex: string;
23
+ base64: arktype16.Submodule<{
24
+ root: string;
25
+ url: string;
26
+ } & {
27
+ " arkInferred": string;
28
+ }>;
29
+ capitalize: arktype16.Submodule<arktype_internal_keywords_string_ts10.capitalize.$ & {
30
+ " arkInferred": (In: string) => arktype_internal_attributes_ts5.To<string>;
31
+ }>;
32
+ creditCard: string;
33
+ date: arktype16.Submodule<arktype_internal_keywords_string_ts10.stringDate.$ & {
34
+ " arkInferred": string;
35
+ }>;
36
+ digits: string;
37
+ email: string;
38
+ integer: arktype16.Submodule<arktype_internal_keywords_string_ts10.stringInteger.$ & {
39
+ " arkInferred": string;
40
+ }>;
41
+ ip: arktype16.Submodule<arktype_internal_keywords_string_ts10.ip.$ & {
42
+ " arkInferred": string;
43
+ }>;
44
+ json: arktype16.Submodule<arktype_internal_keywords_string_ts10.stringJson.$ & {
45
+ " arkInferred": string;
46
+ }>;
47
+ lower: arktype16.Submodule<arktype_internal_keywords_string_ts10.lower.$ & {
48
+ " arkInferred": (In: string) => arktype_internal_attributes_ts5.To<string>;
49
+ }>;
50
+ numeric: arktype16.Submodule<arktype_internal_keywords_string_ts10.stringNumeric.$ & {
51
+ " arkInferred": string;
52
+ }>;
53
+ regex: string;
54
+ semver: string;
55
+ upper: arktype16.Submodule<{
56
+ root: (In: string) => arktype_internal_attributes_ts5.To<string>;
57
+ preformatted: string;
58
+ } & {
59
+ " arkInferred": (In: string) => arktype_internal_attributes_ts5.To<string>;
60
+ }>;
61
+ url: arktype16.Submodule<arktype_internal_keywords_string_ts10.url.$ & {
62
+ " arkInferred": string;
63
+ }>;
64
+ uuid: arktype16.Submodule<arktype_internal_keywords_string_ts10.uuid.$ & {
65
+ " arkInferred": string;
66
+ }>;
67
+ " arkInferred": string;
68
+ host: string;
69
+ }>;
70
+ number: arktype16.Submodule<{
71
+ NaN: number;
72
+ Infinity: number;
73
+ root: number;
74
+ integer: number;
75
+ " arkInferred": number;
76
+ epoch: number;
77
+ safe: number;
78
+ NegativeInfinity: number;
79
+ port: (In: string) => arktype16.Out<number>;
80
+ }>;
81
+ boolean: (In: boolean | "false" | "true") => arktype16.Out<boolean>;
80
82
  }>;
81
-
83
+ //#endregion
84
+ //#region src/create-env.d.ts
82
85
  type RuntimeEnvironment = Record<string, string | undefined>;
83
86
  type EnvSchema<def> = type$1.validate<def, (typeof $)["t"]>;
87
+ /**
88
+ * TODO: If possible, find a better type than "const T extends Record<string, unknown>",
89
+ * and be as close as possible to the type accepted by ArkType's `type`.
90
+ */
84
91
  /**
85
92
  * Create an environment variables object from a schema and an environment
86
93
  * @param def - The environment variable schema
@@ -88,89 +95,93 @@ type EnvSchema<def> = type$1.validate<def, (typeof $)["t"]>;
88
95
  * @returns The validated environment variable schema
89
96
  * @throws An {@link ArkEnvError | error} if the environment variables are invalid.
90
97
  */
91
- declare function createEnv<const T extends Record<string, string | undefined>>(def: EnvSchema<T>, env?: RuntimeEnvironment): distill.Out<type$1.infer<T, (typeof $)["t"]>>;
92
-
93
- declare const type: arktype_internal_type_ts.TypeParser<{
94
- string: arktype.Submodule<{
95
- root: string;
96
- " arkInferred": string;
97
- trim: arktype.Submodule<arktype_internal_keywords_string_ts.trim.$ & {
98
- " arkInferred": (In: string) => arktype_internal_attributes_ts.To<string>;
99
- }>;
100
- normalize: arktype.Submodule<arktype_internal_keywords_string_ts.normalize.$ & {
101
- " arkInferred": (In: string) => arktype_internal_attributes_ts.To<string>;
102
- }>;
103
- alpha: string;
104
- alphanumeric: string;
105
- hex: string;
106
- base64: arktype.Submodule<{
107
- root: string;
108
- url: string;
109
- } & {
110
- " arkInferred": string;
111
- }>;
112
- capitalize: arktype.Submodule<arktype_internal_keywords_string_ts.capitalize.$ & {
113
- " arkInferred": (In: string) => arktype_internal_attributes_ts.To<string>;
114
- }>;
115
- creditCard: string;
116
- date: arktype.Submodule<arktype_internal_keywords_string_ts.stringDate.$ & {
117
- " arkInferred": string;
118
- }>;
119
- digits: string;
120
- email: string;
121
- integer: arktype.Submodule<arktype_internal_keywords_string_ts.stringInteger.$ & {
122
- " arkInferred": string;
123
- }>;
124
- ip: arktype.Submodule<arktype_internal_keywords_string_ts.ip.$ & {
125
- " arkInferred": string;
126
- }>;
127
- json: arktype.Submodule<arktype_internal_keywords_string_ts.stringJson.$ & {
128
- " arkInferred": string;
129
- }>;
130
- lower: arktype.Submodule<arktype_internal_keywords_string_ts.lower.$ & {
131
- " arkInferred": (In: string) => arktype_internal_attributes_ts.To<string>;
132
- }>;
133
- numeric: arktype.Submodule<arktype_internal_keywords_string_ts.stringNumeric.$ & {
134
- " arkInferred": string;
135
- }>;
136
- regex: string;
137
- semver: string;
138
- upper: arktype.Submodule<{
139
- root: (In: string) => arktype_internal_attributes_ts.To<string>;
140
- preformatted: string;
141
- } & {
142
- " arkInferred": (In: string) => arktype_internal_attributes_ts.To<string>;
143
- }>;
144
- url: arktype.Submodule<arktype_internal_keywords_string_ts.url.$ & {
145
- " arkInferred": string;
146
- }>;
147
- uuid: arktype.Submodule<arktype_internal_keywords_string_ts.uuid.$ & {
148
- " arkInferred": string;
149
- }>;
150
- host: string;
151
- }>;
152
- number: arktype.Submodule<{
153
- NaN: number;
154
- Infinity: number;
155
- root: number;
156
- " arkInferred": number;
157
- integer: number;
158
- epoch: number;
159
- safe: number;
160
- NegativeInfinity: number;
161
- port: (In: string) => arktype.Out<number>;
98
+ declare function createEnv<const T extends Record<string, unknown>>(def: EnvSchema<T>, env?: RuntimeEnvironment): distill.Out<type$1.infer<T, (typeof $)["t"]>>;
99
+ //#endregion
100
+ //#region src/type.d.ts
101
+ declare const type: arktype_internal_type_ts0.TypeParser<{
102
+ string: arktype16.Submodule<{
103
+ trim: arktype16.Submodule<arktype_internal_keywords_string_ts10.trim.$ & {
104
+ " arkInferred": (In: string) => arktype_internal_attributes_ts5.To<string>;
162
105
  }>;
106
+ normalize: arktype16.Submodule<arktype_internal_keywords_string_ts10.normalize.$ & {
107
+ " arkInferred": (In: string) => arktype_internal_attributes_ts5.To<string>;
108
+ }>;
109
+ root: string;
110
+ alpha: string;
111
+ alphanumeric: string;
112
+ hex: string;
113
+ base64: arktype16.Submodule<{
114
+ root: string;
115
+ url: string;
116
+ } & {
117
+ " arkInferred": string;
118
+ }>;
119
+ capitalize: arktype16.Submodule<arktype_internal_keywords_string_ts10.capitalize.$ & {
120
+ " arkInferred": (In: string) => arktype_internal_attributes_ts5.To<string>;
121
+ }>;
122
+ creditCard: string;
123
+ date: arktype16.Submodule<arktype_internal_keywords_string_ts10.stringDate.$ & {
124
+ " arkInferred": string;
125
+ }>;
126
+ digits: string;
127
+ email: string;
128
+ integer: arktype16.Submodule<arktype_internal_keywords_string_ts10.stringInteger.$ & {
129
+ " arkInferred": string;
130
+ }>;
131
+ ip: arktype16.Submodule<arktype_internal_keywords_string_ts10.ip.$ & {
132
+ " arkInferred": string;
133
+ }>;
134
+ json: arktype16.Submodule<arktype_internal_keywords_string_ts10.stringJson.$ & {
135
+ " arkInferred": string;
136
+ }>;
137
+ lower: arktype16.Submodule<arktype_internal_keywords_string_ts10.lower.$ & {
138
+ " arkInferred": (In: string) => arktype_internal_attributes_ts5.To<string>;
139
+ }>;
140
+ numeric: arktype16.Submodule<arktype_internal_keywords_string_ts10.stringNumeric.$ & {
141
+ " arkInferred": string;
142
+ }>;
143
+ regex: string;
144
+ semver: string;
145
+ upper: arktype16.Submodule<{
146
+ root: (In: string) => arktype_internal_attributes_ts5.To<string>;
147
+ preformatted: string;
148
+ } & {
149
+ " arkInferred": (In: string) => arktype_internal_attributes_ts5.To<string>;
150
+ }>;
151
+ url: arktype16.Submodule<arktype_internal_keywords_string_ts10.url.$ & {
152
+ " arkInferred": string;
153
+ }>;
154
+ uuid: arktype16.Submodule<arktype_internal_keywords_string_ts10.uuid.$ & {
155
+ " arkInferred": string;
156
+ }>;
157
+ " arkInferred": string;
158
+ host: string;
159
+ }>;
160
+ number: arktype16.Submodule<{
161
+ NaN: number;
162
+ Infinity: number;
163
+ root: number;
164
+ integer: number;
165
+ " arkInferred": number;
166
+ epoch: number;
167
+ safe: number;
168
+ NegativeInfinity: number;
169
+ port: (In: string) => arktype16.Out<number>;
170
+ }>;
171
+ boolean: (In: boolean | "false" | "true") => arktype16.Out<boolean>;
163
172
  }>;
164
-
173
+ //#endregion
174
+ //#region src/errors.d.ts
165
175
  declare class ArkEnvError extends Error {
166
- constructor(errors: ArkErrors, message?: string);
176
+ constructor(errors: ArkErrors, message?: string);
167
177
  }
168
-
178
+ //#endregion
179
+ //#region src/index.d.ts
169
180
  /**
170
181
  * `arkenv`'s main export, an alias for {@link createEnv}
171
182
  *
172
183
  * {@link https://arkenv.js.org | ArkEnv} is a typesafe environment variables parser powered by {@link https://arktype.io | ArkType}, TypeScript's 1:1 validator.
173
184
  */
174
185
  declare const arkenv: typeof createEnv;
175
-
176
- export { ArkEnvError, type EnvSchema, createEnv, arkenv as default, type };
186
+ //#endregion
187
+ export { ArkEnvError, type EnvSchema, createEnv, arkenv as default, type };
package/dist/index.js CHANGED
@@ -1,84 +1,108 @@
1
- // src/create-env.ts
2
- import { type as type3 } from "arktype";
1
+ import { scope, type as type$1 } from "arktype";
2
+ import { styleText } from "node:util";
3
3
 
4
- // src/errors.ts
5
- import { styleText } from "util";
6
-
7
- // src/utils.ts
8
- var indent = (str, amt = 2, { dontDetectNewlines = false } = {}) => {
9
- const detectNewlines = !dontDetectNewlines;
10
- if (detectNewlines) {
11
- return str.split("\n").map((line) => `${" ".repeat(amt)}${line}`).join("\n");
12
- }
13
- return `${" ".repeat(amt)}${str}`;
4
+ //#region src/utils.ts
5
+ /**
6
+ * Indent a string by a given amount
7
+ * @param str - The string to indent
8
+ * @param amt - The amount to indent by, defaults to 2
9
+ * @param options - {@link IndentOptions}
10
+ * @returns The indented string
11
+ */
12
+ const indent = (str, amt = 2, { dontDetectNewlines = false } = {}) => {
13
+ if (!dontDetectNewlines) return str.split("\n").map((line) => `${" ".repeat(amt)}${line}`).join("\n");
14
+ return `${" ".repeat(amt)}${str}`;
14
15
  };
15
16
 
16
- // src/errors.ts
17
- var formatErrors = (errors) => Object.entries(errors.byPath).map(([path, error]) => {
18
- const messageWithoutPath = error.message.startsWith(path) ? error.message.slice(path.length) : error.message;
19
- const valueMatch = messageWithoutPath.match(/\(was "([^"]+)"\)/);
20
- const formattedMessage = valueMatch ? messageWithoutPath.replace(
21
- `(was "${valueMatch[1]}")`,
22
- `(was ${styleText("cyan", `"${valueMatch[1]}"`)})`
23
- ) : messageWithoutPath;
24
- return `${styleText("yellow", path)}${formattedMessage}`;
17
+ //#endregion
18
+ //#region src/errors.ts
19
+ /**
20
+ * Format the errors returned by ArkType to be more readable
21
+ * @param errors - The errors returned by ArkType
22
+ * @returns A string of the formatted errors
23
+ */
24
+ const formatErrors = (errors) => Object.entries(errors.byPath).map(([path, error]) => {
25
+ const messageWithoutPath = error.message.startsWith(path) ? error.message.slice(path.length) : error.message;
26
+ const valueMatch = messageWithoutPath.match(/\(was "([^"]+)"\)/);
27
+ const formattedMessage = valueMatch ? messageWithoutPath.replace(`(was "${valueMatch[1]}")`, `(was ${styleText("cyan", `"${valueMatch[1]}"`)})`) : messageWithoutPath;
28
+ return `${styleText("yellow", path)}${formattedMessage}`;
25
29
  }).join("\n");
26
30
  var ArkEnvError = class extends Error {
27
- constructor(errors, message = "Errors found while validating environment variables") {
28
- super(`${styleText("red", message)}
29
- ${indent(formatErrors(errors))}
30
- `);
31
- this.name = "ArkEnvError";
32
- }
31
+ constructor(errors, message = "Errors found while validating environment variables") {
32
+ super(`${styleText("red", message)}\n${indent(formatErrors(errors))}\n`);
33
+ this.name = "ArkEnvError";
34
+ }
33
35
  };
34
36
 
35
- // src/scope.ts
36
- import { scope, type as type2 } from "arktype";
37
-
38
- // src/types.ts
39
- import { type } from "arktype";
40
- var port = type("string", "=>", (data, ctx) => {
41
- const asNumber = Number.parseInt(data, 10);
42
- const isInteger = Number.isInteger(asNumber);
43
- const isBetween = 0 <= asNumber && asNumber <= 65535;
44
- if (!isInteger || !isBetween) {
45
- ctx.mustBe("an integer between 0 and 65535");
46
- }
47
- return asNumber;
37
+ //#endregion
38
+ //#region src/types.ts
39
+ /**
40
+ * A `string` that can be parsed into a number between 0 and 65535
41
+ */
42
+ const port = type$1("string", "=>", (data, ctx) => {
43
+ const asNumber = Number.parseInt(data, 10);
44
+ if (!Number.isInteger(asNumber) || !(0 <= asNumber && asNumber <= 65535)) ctx.mustBe("an integer between 0 and 65535");
45
+ return asNumber;
48
46
  });
49
- var host = type("string.ip | 'localhost'");
47
+ /**
48
+ * An IP address or `"localhost"`
49
+ */
50
+ const host = type$1("string.ip | 'localhost'");
51
+ /**
52
+ * A boolean that accepts string values and converts them to boolean
53
+ * Accepts "true" or "false" strings and converts them to actual boolean values
54
+ */
55
+ const boolean = type$1("'true' | 'false' | true | false", "=>", (str) => str === "true" || str === true);
50
56
 
51
- // src/scope.ts
52
- var $ = scope({
53
- string: type2.module({
54
- ...type2.keywords.string,
55
- host
56
- }),
57
- number: type2.module({
58
- ...type2.keywords.number,
59
- port
60
- })
57
+ //#endregion
58
+ //#region src/scope.ts
59
+ /**
60
+ * The root scope for the ArkEnv library, containing extensions to the ArkType scopes with ArkEnv-specific types like `string.host` and `number.port`.
61
+ */
62
+ const $ = scope({
63
+ string: type$1.module({
64
+ ...type$1.keywords.string,
65
+ host
66
+ }),
67
+ number: type$1.module({
68
+ ...type$1.keywords.number,
69
+ port
70
+ }),
71
+ boolean
61
72
  });
62
73
 
63
- // src/create-env.ts
74
+ //#endregion
75
+ //#region src/create-env.ts
76
+ /**
77
+ * TODO: If possible, find a better type than "const T extends Record<string, unknown>",
78
+ * and be as close as possible to the type accepted by ArkType's `type`.
79
+ */
80
+ /**
81
+ * Create an environment variables object from a schema and an environment
82
+ * @param def - The environment variable schema
83
+ * @param env - The environment variables to validate, defaults to `process.env`
84
+ * @returns The validated environment variable schema
85
+ * @throws An {@link ArkEnvError | error} if the environment variables are invalid.
86
+ */
64
87
  function createEnv(def, env = process.env) {
65
- const schema = $.type.raw(def);
66
- const validatedEnv = schema(env);
67
- if (validatedEnv instanceof type3.errors) {
68
- throw new ArkEnvError(validatedEnv);
69
- }
70
- return validatedEnv;
88
+ const validatedEnv = $.type.raw(def)(env);
89
+ if (validatedEnv instanceof type$1.errors) throw new ArkEnvError(validatedEnv);
90
+ return validatedEnv;
71
91
  }
72
92
 
73
- // src/type.ts
74
- var type4 = $.type;
93
+ //#endregion
94
+ //#region src/type.ts
95
+ const type = $.type;
75
96
 
76
- // src/index.ts
77
- var arkenv = createEnv;
78
- var index_default = arkenv;
79
- export {
80
- ArkEnvError,
81
- createEnv,
82
- index_default as default,
83
- type4 as type
84
- };
97
+ //#endregion
98
+ //#region src/index.ts
99
+ /**
100
+ * `arkenv`'s main export, an alias for {@link createEnv}
101
+ *
102
+ * {@link https://arkenv.js.org | ArkEnv} is a typesafe environment variables parser powered by {@link https://arktype.io | ArkType}, TypeScript's 1:1 validator.
103
+ */
104
+ const arkenv = createEnv;
105
+ var src_default = arkenv;
106
+
107
+ //#endregion
108
+ export { ArkEnvError, createEnv, src_default as default, type };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "arkenv",
3
3
  "type": "module",
4
- "version": "0.7.1",
4
+ "version": "0.7.3",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",
@@ -32,19 +32,20 @@
32
32
  "author": "Yam Borodetsky <yam@yam.codes>",
33
33
  "devDependencies": {
34
34
  "@ark/schema": "^0.49.0",
35
- "@types/node": "24.3.1",
36
- "tsup": "^8.5.0",
37
- "typescript": "^5.9.2"
35
+ "@types/node": "24.6.2",
36
+ "tsdown": "^0.15.6",
37
+ "typescript": "^5.9.3",
38
+ "vitest": "^3.2.4"
38
39
  },
39
40
  "peerDependencies": {
40
41
  "arktype": "^2.1.22"
41
42
  },
42
43
  "scripts": {
43
- "build": "rimraf dist && tsup",
44
+ "build": "tsdown",
44
45
  "test:once": "pnpm test",
45
46
  "typecheck": "tsc --noEmit",
46
47
  "clean": "rimraf dist node_modules",
47
- "test": "pnpm -w test --project arkenv",
48
+ "test": "vitest",
48
49
  "fix": "pnpm -w run fix"
49
50
  }
50
51
  }