@arkenv/core 1.0.0-alpha.2
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/LICENSE +21 -0
- package/README.md +104 -0
- package/dist/index.cjs +403 -0
- package/dist/index.d.cts +6464 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +6458 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +392 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +83 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Yam Borodetsky <https://yam.codes/>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://github.com/yamcodes/arkenv/blob/main/apps/www/public/assets/icon.svg"><img alt="ArkEnv Logo" src="https://arkenv.js.org/assets/icon.svg" width="160px" align="center"/></a>
|
|
3
|
+
<h1 align="center">ArkEnv</h1>
|
|
4
|
+
<div align="center">
|
|
5
|
+
<p align="center">
|
|
6
|
+
Environment variable validation from editor to runtime<br/> for <a href="https://nextjs.org/">Next.js</a>, <a href="https://nuxt.com/">Nuxt</a>, <a href="https://nodejs.org/">Node.js</a>, <a href="https://vite.dev/">Vite</a>, and <a href="https://bun.com/">Bun</a>
|
|
7
|
+
</p>
|
|
8
|
+
<a href="https://github.com/yamcodes/arkenv/actions/workflows/test.yml?query=branch%3Amain"><img alt="Test Status" src="https://github.com/yamcodes/arkenv/actions/workflows/tests-badge.yml/badge.svg?branch=main"></a>
|
|
9
|
+
<a href="https://bundlephobia.com/package/arkenv"><img alt="npm bundle size" src="https://img.shields.io/bundlephobia/minzip/arkenv"></a>
|
|
10
|
+
<a href="https://arktype.io/docs/ecosystem#arkenv"><img alt="ArkType Ecosystem" src="https://custom-icon-badges.demolab.com/badge/ArkType%20Ecosystem-0d1526?logo=arktype2&logoColor=e9eef9"></a>
|
|
11
|
+
<a href="https://pullfrog.com"><img alt="Pullfrog" src="https://custom-icon-badges.demolab.com/badge/Powered%20by%20Pullfrog-2f4032?logo=pullfrog-white"></a>
|
|
12
|
+
</div>
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
<div align="center">
|
|
16
|
+
<a href="https://arkenv.js.org/docs/arkenv">Docs</a>
|
|
17
|
+
<span> • </span>
|
|
18
|
+
<a href="https://arkenv.js.org/docs/arkenv/faq">FAQ</a>
|
|
19
|
+
<span> • </span>
|
|
20
|
+
<a href="https://stackblitz.com/github/yamcodes/arkenv/tree/main/examples/stackblitz?file=index.ts">Try on StackBlitz</a>
|
|
21
|
+
<br />
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
<br />
|
|
25
|
+
<br />
|
|
26
|
+
|
|
27
|
+
<p align="center">
|
|
28
|
+
<img alt="ArkEnv Demo" src="https://arkenv.js.org/assets/demo.gif" />
|
|
29
|
+
</p>
|
|
30
|
+
|
|
31
|
+
<br />
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
<details open>
|
|
36
|
+
<summary>npm</summary>
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
npx arkenv@latest init
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
</details>
|
|
43
|
+
|
|
44
|
+
<details>
|
|
45
|
+
<summary>pnpm</summary>
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
pnx arkenv@latest init
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
</details>
|
|
52
|
+
|
|
53
|
+
<details>
|
|
54
|
+
<summary>Yarn</summary>
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
yarn dlx arkenv@latest init
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
</details>
|
|
61
|
+
|
|
62
|
+
<details>
|
|
63
|
+
<summary>Bun</summary>
|
|
64
|
+
|
|
65
|
+
```sh
|
|
66
|
+
bunx arkenv@latest init
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
</details>
|
|
70
|
+
|
|
71
|
+
<br />
|
|
72
|
+
|
|
73
|
+
### [Read the docs →](https://arkenv.js.org/docs/ArkEnv/quickstart)
|
|
74
|
+
|
|
75
|
+
<br />
|
|
76
|
+
|
|
77
|
+
## Supporting ArkEnv
|
|
78
|
+
|
|
79
|
+
If you love ArkEnv, you can support the project by **starring it on GitHub**!
|
|
80
|
+
|
|
81
|
+
You are also welcome to [contribute to the project](https://github.com/yamcodes/arkenv/blob/main/docs/CONTRIBUTING.md) and join the wonderful people who have contributed:
|
|
82
|
+
|
|
83
|
+
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
|
84
|
+
<!-- prettier-ignore-start -->
|
|
85
|
+
<!-- markdownlint-disable -->
|
|
86
|
+
<table>
|
|
87
|
+
<tbody>
|
|
88
|
+
<tr>
|
|
89
|
+
<td align="center" valign="top" width="14.28%"><a href="https://yam.codes"><img src="https://avatars.githubusercontent.com/u/2014360?v=4?s=100" width="100px;" alt="Yam C Borodetsky"/><br /><sub><b>Yam C Borodetsky</b></sub></a><br /><a href="https://github.com/yamcodes/arkenv/commits?author=yamcodes" title="Code">💻</a> <a href="#question-yamcodes" title="Answering Questions">💬</a> <a href="#ideas-yamcodes" title="Ideas, Planning, & Feedback">🤔</a> <a href="#design-yamcodes" title="Design">🎨</a> <a href="https://github.com/yamcodes/arkenv/commits?author=yamcodes" title="Documentation">📖</a> <a href="https://github.com/yamcodes/arkenv/issues?q=author%3Ayamcodes" title="Bug reports">🐛</a> <a href="#example-yamcodes" title="Examples">💡</a> <a href="#infra-yamcodes" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="https://github.com/yamcodes/arkenv/commits?author=yamcodes" title="Tests">⚠️</a></td>
|
|
90
|
+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/aruaycodes"><img src="https://avatars.githubusercontent.com/u/57131628?v=4?s=100" width="100px;" alt="Aruay Berdikulova"/><br /><sub><b>Aruay Berdikulova</b></sub></a><br /><a href="https://github.com/yamcodes/arkenv/commits?author=aruaycodes" title="Code">💻</a> <a href="#ideas-aruaycodes" title="Ideas, Planning, & Feedback">🤔</a></td>
|
|
91
|
+
<td align="center" valign="top" width="14.28%"><a href="https://arktype.io"><img src="https://avatars.githubusercontent.com/u/10645823?v=4?s=100" width="100px;" alt="David Blass"/><br /><sub><b>David Blass</b></sub></a><br /><a href="#ideas-ssalbdivad" title="Ideas, Planning, & Feedback">🤔</a> <a href="#mentoring-ssalbdivad" title="Mentoring">🧑🏫</a> <a href="#question-ssalbdivad" title="Answering Questions">💬</a></td>
|
|
92
|
+
<td align="center" valign="top" width="14.28%"><a href="https://github.com/danciudev"><img src="https://avatars.githubusercontent.com/u/44430251?v=4?s=100" width="100px;" alt="Andrei Danciu"/><br /><sub><b>Andrei Danciu</b></sub></a><br /><a href="https://github.com/yamcodes/arkenv/commits?author=danciudev" title="Code">💻</a></td>
|
|
93
|
+
<td align="center" valign="top" width="14.28%"><a href="https://joakim.beng.se"><img src="https://avatars.githubusercontent.com/u/1427383?v=4?s=100" width="100px;" alt="Joakim Carlstein"/><br /><sub><b>Joakim Carlstein</b></sub></a><br /><a href="https://github.com/yamcodes/arkenv/commits?author=joakimbeng" title="Code">💻</a> <a href="https://github.com/yamcodes/arkenv/commits?author=joakimbeng" title="Documentation">📖</a></td>
|
|
94
|
+
<td align="center" valign="top" width="14.28%"><a href="https://fresh-accordion-06a.notion.site/Jiayi-Du-1817075e92978076b95cf9d90fb5eceb"><img src="https://avatars.githubusercontent.com/u/166608075?v=4?s=100" width="100px;" alt="RoomWithOutRoof"/><br /><sub><b>RoomWithOutRoof</b></sub></a><br /><a href="https://github.com/yamcodes/arkenv/commits?author=Jah-yee" title="Documentation">📖</a></td>
|
|
95
|
+
</tr>
|
|
96
|
+
</tbody>
|
|
97
|
+
</table>
|
|
98
|
+
|
|
99
|
+
<!-- markdownlint-restore -->
|
|
100
|
+
<!-- prettier-ignore-end -->
|
|
101
|
+
|
|
102
|
+
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
|
103
|
+
|
|
104
|
+
We [acknowledge](https://github.com/yamcodes/arkenv/blob/main/docs/ACKNOWLEDGEMENTS.md) the various projects and people that inspired ArkEnv.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
|
|
2
|
+
let arktype = require("arktype");
|
|
3
|
+
|
|
4
|
+
//#region ../internal/scope/dist/index.js
|
|
5
|
+
const n$1 = (0, arktype.type)(`0 <= number.integer <= 65535`), r$1 = (0, arktype.type)(`string.ip | 'localhost'`), i$1 = (0, arktype.scope)({
|
|
6
|
+
string: arktype.type.module({
|
|
7
|
+
...arktype.type.keywords.string,
|
|
8
|
+
host: r$1
|
|
9
|
+
}),
|
|
10
|
+
number: arktype.type.module({
|
|
11
|
+
...arktype.type.keywords.number,
|
|
12
|
+
port: n$1
|
|
13
|
+
})
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region ../internal/utils/dist/index.js
|
|
18
|
+
const e = (e) => {
|
|
19
|
+
if (typeof e == `number` || typeof e != `string` || !e.trim()) return e;
|
|
20
|
+
if (e.trim() === `NaN`) return NaN;
|
|
21
|
+
let t = Number(e);
|
|
22
|
+
return Number.isNaN(t) ? e : t;
|
|
23
|
+
}, t = (e) => e === `true` ? !0 : e === `false` ? !1 : e, n = (e) => {
|
|
24
|
+
if (typeof e != `string`) return e;
|
|
25
|
+
let t = e.trim();
|
|
26
|
+
if (t[0] !== `{` && t[0] !== `[`) return e;
|
|
27
|
+
try {
|
|
28
|
+
return JSON.parse(t);
|
|
29
|
+
} catch {
|
|
30
|
+
return e;
|
|
31
|
+
}
|
|
32
|
+
}, r = (e) => {
|
|
33
|
+
if (e instanceof Date || typeof e != `string` || !e.trim()) return e;
|
|
34
|
+
let t = new Date(e);
|
|
35
|
+
return Number.isNaN(t.getTime()) ? e : t;
|
|
36
|
+
}, i = (e) => {
|
|
37
|
+
let t = {};
|
|
38
|
+
for (let n in e) {
|
|
39
|
+
let r = e[n];
|
|
40
|
+
r !== `` && (t[n] = r);
|
|
41
|
+
}
|
|
42
|
+
return t;
|
|
43
|
+
}, a = `*`, o = (e, t = []) => {
|
|
44
|
+
let n = [];
|
|
45
|
+
if (!e || typeof e != `object` || Array.isArray(e)) return n;
|
|
46
|
+
let r = e;
|
|
47
|
+
if (`const` in r) {
|
|
48
|
+
let e = typeof r.const;
|
|
49
|
+
(e === `number` || e === `boolean`) && n.push({
|
|
50
|
+
path: [...t],
|
|
51
|
+
type: `primitive`
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
`enum` in r && Array.isArray(r.enum) && r.enum.some((e) => typeof e == `number` || typeof e == `boolean`) && n.push({
|
|
55
|
+
path: [...t],
|
|
56
|
+
type: `primitive`
|
|
57
|
+
});
|
|
58
|
+
let i = r.type;
|
|
59
|
+
if (i === `number` || i === `integer` || i === `boolean`) n.push({
|
|
60
|
+
path: [...t],
|
|
61
|
+
type: `primitive`
|
|
62
|
+
});
|
|
63
|
+
else if (i === `string` && `format` in r && (r.format === `date-time` || r.format === `date`)) n.push({
|
|
64
|
+
path: [...t],
|
|
65
|
+
type: `date`
|
|
66
|
+
});
|
|
67
|
+
else if (i === `object`) {
|
|
68
|
+
if (r.properties && Object.keys(r.properties).length > 0) {
|
|
69
|
+
n.push({
|
|
70
|
+
path: [...t],
|
|
71
|
+
type: `object`
|
|
72
|
+
});
|
|
73
|
+
for (let e in r.properties) n.push(...o(r.properties[e], [...t, e]));
|
|
74
|
+
}
|
|
75
|
+
} else i === `array` && (n.push({
|
|
76
|
+
path: [...t],
|
|
77
|
+
type: `array`
|
|
78
|
+
}), r.items && (Array.isArray(r.items) ? r.items.forEach((e, r) => {
|
|
79
|
+
n.push(...o(e, [...t, String(r)]));
|
|
80
|
+
}) : n.push(...o(r.items, [...t, `*`]))));
|
|
81
|
+
for (let e of [
|
|
82
|
+
`anyOf`,
|
|
83
|
+
`allOf`,
|
|
84
|
+
`oneOf`
|
|
85
|
+
]) if (r[e] && Array.isArray(r[e])) for (let i of r[e]) n.push(...o(i, t));
|
|
86
|
+
let a = /* @__PURE__ */ new Set();
|
|
87
|
+
return n.filter((e) => {
|
|
88
|
+
let t = e.path.join(`/`) + `:` + e.type;
|
|
89
|
+
return a.has(t) ? !1 : a.add(t);
|
|
90
|
+
});
|
|
91
|
+
}, s = (i, a, o = {}) => {
|
|
92
|
+
let { arrayFormat: s = `comma` } = o, c = (e) => {
|
|
93
|
+
if (s === `json`) try {
|
|
94
|
+
return JSON.parse(e);
|
|
95
|
+
} catch {
|
|
96
|
+
return e;
|
|
97
|
+
}
|
|
98
|
+
return e.trim() ? e.split(`,`).map((e) => e.trim()) : [];
|
|
99
|
+
}, l = (i, a) => {
|
|
100
|
+
if (a === `array` && typeof i == `string`) return c(i);
|
|
101
|
+
if (a === `object` && typeof i == `string`) return n(i);
|
|
102
|
+
if (a === `date` && typeof i == `string`) return r(i);
|
|
103
|
+
if (a === `primitive`) {
|
|
104
|
+
if (Array.isArray(i)) return i.map((n) => {
|
|
105
|
+
if (typeof n != `string`) return n;
|
|
106
|
+
let r = e(n);
|
|
107
|
+
return typeof r == `number` ? r : t(n);
|
|
108
|
+
});
|
|
109
|
+
if (typeof i != `string`) return i;
|
|
110
|
+
let n = e(i);
|
|
111
|
+
return typeof n == `number` ? n : t(i);
|
|
112
|
+
}
|
|
113
|
+
return i;
|
|
114
|
+
};
|
|
115
|
+
if (typeof i != `object` || !i) {
|
|
116
|
+
let e = a.find((e) => e.path.length === 0);
|
|
117
|
+
return e ? l(i, e.type) : i;
|
|
118
|
+
}
|
|
119
|
+
let u = [...a].sort((e, t) => e.path.length - t.path.length), d = (e, t, n) => {
|
|
120
|
+
if (t.length === 0) return n(e);
|
|
121
|
+
let [r, ...i] = t;
|
|
122
|
+
if (r === `*`) {
|
|
123
|
+
if (Array.isArray(e)) {
|
|
124
|
+
let t = !1, r = e.map((e) => {
|
|
125
|
+
let r = d(e, i, n);
|
|
126
|
+
return r !== e && (t = !0), r;
|
|
127
|
+
});
|
|
128
|
+
return t ? r : e;
|
|
129
|
+
}
|
|
130
|
+
return e;
|
|
131
|
+
}
|
|
132
|
+
if (!e || typeof e != `object`) return e;
|
|
133
|
+
if (Array.isArray(e)) {
|
|
134
|
+
let t = Number(r);
|
|
135
|
+
if (!Number.isNaN(t) && t >= 0 && t < e.length) {
|
|
136
|
+
let r = d(e[t], i, n);
|
|
137
|
+
if (r !== e[t]) {
|
|
138
|
+
let n = [...e];
|
|
139
|
+
return n[t] = r, n;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return e;
|
|
143
|
+
}
|
|
144
|
+
if (Object.hasOwn(e, r)) {
|
|
145
|
+
let t = d(e[r], i, n);
|
|
146
|
+
if (t !== e[r]) return {
|
|
147
|
+
...e,
|
|
148
|
+
[r]: t
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
return e;
|
|
152
|
+
}, f = i;
|
|
153
|
+
for (let e of u) e.path.length > 0 && (f = d(f, e.path, (t) => l(t, e.type)));
|
|
154
|
+
return f;
|
|
155
|
+
};
|
|
156
|
+
function c(e, t, n, r) {
|
|
157
|
+
let a = t ? i(e) : e, c = { ...a }, l = [];
|
|
158
|
+
if (r) {
|
|
159
|
+
let e = r();
|
|
160
|
+
l.push(...e.missingKeys || []), e.hasSchema && (c = s(c, o(e.schema), { arrayFormat: n }));
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
processedEnv: a,
|
|
164
|
+
coercedEnv: c,
|
|
165
|
+
missingKeys: l
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
const l = (e, t = 2, { dontDetectNewlines: n = !1 } = {}) => n ? `${` `.repeat(t)}${e}` : e.split(`
|
|
169
|
+
`).map((e) => `${` `.repeat(t)}${e}`).join(`
|
|
170
|
+
`), u = {
|
|
171
|
+
red: `\x1B[31m`,
|
|
172
|
+
yellow: `\x1B[33m`,
|
|
173
|
+
cyan: `\x1B[36m`,
|
|
174
|
+
reset: `\x1B[0m`
|
|
175
|
+
}, d = () => typeof process < `u` && process.versions != null && process.versions.node != null, f = () => !!(!d() || process.env.NO_COLOR !== void 0 || process.env.CI !== void 0 || process.stdout && !process.stdout.isTTY), p = (e, t) => d() && !f() ? `${u[e]}${t}${u.reset}` : t;
|
|
176
|
+
function m(e) {
|
|
177
|
+
return e.map((e) => `${p(`yellow`, e.path)} ${e.message.trimStart()}`).join(`
|
|
178
|
+
`);
|
|
179
|
+
}
|
|
180
|
+
var h = class extends Error {
|
|
181
|
+
constructor(e, t = `Errors found while validating environment variables`) {
|
|
182
|
+
let n = m(e);
|
|
183
|
+
super(`${p(`red`, t)}\n${l(n)}\n`), this.name = `ArkEnvError`, this.issues = e;
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
Object.defineProperty(h, `name`, { value: `ArkEnvError` });
|
|
187
|
+
const y = /secret|(_|^)key(_|$)|token|(_|^)password(_|$)|(_|^)pass(_|$)|(_|^)auth(_|$)|jwt|cert|credential|database_url|db_url/i;
|
|
188
|
+
function b(e) {
|
|
189
|
+
if (e !== void 0) return e;
|
|
190
|
+
if (typeof process > `u`) return !1;
|
|
191
|
+
let t = process.env.ARKENV_DEBUG_SECRETS;
|
|
192
|
+
return t === `true` || t === `1`;
|
|
193
|
+
}
|
|
194
|
+
function x(e) {
|
|
195
|
+
return y.test(e) && !/public/i.test(e);
|
|
196
|
+
}
|
|
197
|
+
function E(e) {
|
|
198
|
+
try {
|
|
199
|
+
return {
|
|
200
|
+
success: !0,
|
|
201
|
+
data: e()
|
|
202
|
+
};
|
|
203
|
+
} catch (e) {
|
|
204
|
+
if (e instanceof h) return {
|
|
205
|
+
success: !1,
|
|
206
|
+
issues: e.issues
|
|
207
|
+
};
|
|
208
|
+
throw e;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
function D(e, t, n, r, i, a) {
|
|
212
|
+
let o = {
|
|
213
|
+
path: e,
|
|
214
|
+
message: t,
|
|
215
|
+
code: n,
|
|
216
|
+
meta: r ?? {}
|
|
217
|
+
};
|
|
218
|
+
return i && (o.expected = i), a !== void 0 && (o.received = a), o;
|
|
219
|
+
}
|
|
220
|
+
function P(e) {
|
|
221
|
+
if (!e || typeof e != `object` && typeof e != `function`) return [];
|
|
222
|
+
if (e.json && typeof e.json == `object` && e.json.domain === `object`) {
|
|
223
|
+
let t = [];
|
|
224
|
+
if (Array.isArray(e.json.required)) for (let n of e.json.required) n && typeof n == `object` && `key` in n && t.push(n.key);
|
|
225
|
+
if (Array.isArray(e.json.optional)) for (let n of e.json.optional) n && typeof n == `object` && `key` in n && t.push(n.key);
|
|
226
|
+
return t;
|
|
227
|
+
}
|
|
228
|
+
let t = e[`~standard`], n = typeof t?.jsonSchema?.input == `function` && t.jsonSchema.input || typeof e.jsonSchema?.input == `function` && e.jsonSchema.input;
|
|
229
|
+
if (n) try {
|
|
230
|
+
let e = n({ target: `draft-07` });
|
|
231
|
+
if (e && typeof e == `object` && e.properties) return Object.keys(e.properties);
|
|
232
|
+
} catch {}
|
|
233
|
+
if (typeof e.toJSONSchema == `function`) try {
|
|
234
|
+
let t = e.toJSONSchema();
|
|
235
|
+
if (t && typeof t == `object` && t.properties) return Object.keys(t.properties);
|
|
236
|
+
} catch {}
|
|
237
|
+
if (typeof e.toStandardJSONSchema?.v1 == `function`) try {
|
|
238
|
+
let t = e.toStandardJSONSchema.v1();
|
|
239
|
+
if (t && typeof t == `object` && t.properties) return Object.keys(t.properties);
|
|
240
|
+
} catch {}
|
|
241
|
+
return Object.keys(e);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
//#endregion
|
|
245
|
+
//#region src/arktype/index.ts
|
|
246
|
+
const ARKTYPE_CODE_MAP = {
|
|
247
|
+
required: "MISSING_VARIABLE",
|
|
248
|
+
pattern: "PATTERN_MISMATCH",
|
|
249
|
+
min: "VALUE_TOO_SMALL",
|
|
250
|
+
minLength: "VALUE_TOO_SMALL",
|
|
251
|
+
max: "VALUE_TOO_LARGE",
|
|
252
|
+
maxLength: "VALUE_TOO_LARGE",
|
|
253
|
+
divisor: "INVALID_TYPE",
|
|
254
|
+
intersection: "INVALID_TYPE",
|
|
255
|
+
union: "INVALID_TYPE",
|
|
256
|
+
unit: "INVALID_TYPE",
|
|
257
|
+
proto: "INVALID_TYPE",
|
|
258
|
+
domain: "INVALID_TYPE",
|
|
259
|
+
exactLength: "INVALID_FORMAT",
|
|
260
|
+
before: "INVALID_FORMAT",
|
|
261
|
+
after: "INVALID_FORMAT",
|
|
262
|
+
predicate: "CUSTOM"
|
|
263
|
+
};
|
|
264
|
+
/**
|
|
265
|
+
* Map an ArkType error code to an ArkEnv issue code.
|
|
266
|
+
*
|
|
267
|
+
* @param engineCode The ArkType engine error code
|
|
268
|
+
* @returns The corresponding ArkEnv issue code
|
|
269
|
+
*/
|
|
270
|
+
function mapArkTypeCode(engineCode) {
|
|
271
|
+
return engineCode in ARKTYPE_CODE_MAP ? ARKTYPE_CODE_MAP[engineCode] : "INVALID_FORMAT";
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Extract numeric bounds from an ArkType error object.
|
|
275
|
+
*
|
|
276
|
+
* @param error The ArkType error object
|
|
277
|
+
* @returns An object containing optional min and max bounds
|
|
278
|
+
*/
|
|
279
|
+
function getArkTypeMeta(error) {
|
|
280
|
+
const min = error.min ?? error.rule;
|
|
281
|
+
const max = error.max;
|
|
282
|
+
return {
|
|
283
|
+
...typeof min === "number" ? { min } : {},
|
|
284
|
+
...typeof max === "number" ? { max } : {}
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Redact and colorize the value inside a "(was ...)" message fragment.
|
|
289
|
+
*
|
|
290
|
+
* @param message The validation error message
|
|
291
|
+
* @param path The environment variable key path
|
|
292
|
+
* @param debugSecrets Whether to display sensitive values in debug mode
|
|
293
|
+
* @returns The modified error message with styled or redacted value
|
|
294
|
+
*/
|
|
295
|
+
function redactMessageWasValue(message, path, debugSecrets) {
|
|
296
|
+
const valueMatch = message.match(/\(was (.*)\)/);
|
|
297
|
+
if (!valueMatch?.[1]) return message;
|
|
298
|
+
const value = valueMatch[1];
|
|
299
|
+
const displayedValue = !b(debugSecrets) && x(path) ? "[REDACTED]" : value;
|
|
300
|
+
if (displayedValue.includes("\x1B[")) return message;
|
|
301
|
+
return message.replace(`(was ${value})`, `(was ${p("cyan", displayedValue)})`);
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Convert ArkType's `ArkErrors` (keyed by path) into a flat `EnvIssue[]`
|
|
305
|
+
* suitable for `ArkEnvError`.
|
|
306
|
+
*
|
|
307
|
+
* @param errors The ArkType errors object to convert
|
|
308
|
+
* @param config Optional ArkEnvConfig to read debugSecrets options
|
|
309
|
+
* @returns An array of flattened validation issues
|
|
310
|
+
*
|
|
311
|
+
* @internal
|
|
312
|
+
*/
|
|
313
|
+
function arkErrorsToIssues(errors, config) {
|
|
314
|
+
return Object.entries(errors.byPath).map(([path, error]) => {
|
|
315
|
+
let message = error.message;
|
|
316
|
+
let trimmed = message.trimStart();
|
|
317
|
+
if (trimmed.length > 0 && ":.-".includes(trimmed[0])) trimmed = trimmed.slice(1).trimStart();
|
|
318
|
+
if (trimmed.toLowerCase().startsWith(path.toLowerCase())) {
|
|
319
|
+
let rest = trimmed.slice(path.length).trimStart();
|
|
320
|
+
if (rest.length > 0 && ":.-".includes(rest[0])) rest = rest.slice(1);
|
|
321
|
+
message = rest.trimStart();
|
|
322
|
+
}
|
|
323
|
+
message = redactMessageWasValue(message, path, config?.debugSecrets);
|
|
324
|
+
const code = mapArkTypeCode(error.code);
|
|
325
|
+
const meta = { ...getArkTypeMeta(error) };
|
|
326
|
+
return D(path, message, code, meta, error.expected, error.code === "required" ? void 0 : error.data);
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Parse and validate environment variables using ArkEnv's schema rules.
|
|
331
|
+
*
|
|
332
|
+
* This applies:
|
|
333
|
+
* - schema validation
|
|
334
|
+
* - optional coercion (strings → numbers, booleans, arrays)
|
|
335
|
+
* - undeclared key handling
|
|
336
|
+
*
|
|
337
|
+
* On success, returns the validated environment object.
|
|
338
|
+
* On failure, throws an {@link ArkEnvError}.
|
|
339
|
+
*
|
|
340
|
+
* This is a low-level utility used internally by ArkEnv.
|
|
341
|
+
* Most users should prefer the default `arkenv()` export.
|
|
342
|
+
*
|
|
343
|
+
* @param def The ArkType schema definition to validate against
|
|
344
|
+
* @param config The configuration object for parsing and coercion
|
|
345
|
+
* @returns The parsed and validated environment variables
|
|
346
|
+
* @throws {@link ArkEnvError} if validation fails
|
|
347
|
+
*
|
|
348
|
+
* @internal
|
|
349
|
+
*/
|
|
350
|
+
function parse(def, config) {
|
|
351
|
+
const { env = process.env, coerce: shouldCoerce = true, onUndeclaredKey = "delete", arrayFormat = "comma", emptyAsUndefined = false } = config;
|
|
352
|
+
const schemaWithKeys = (typeof def === "function" && "assert" in def ? def : i$1.type.raw(def)).onUndeclaredKey(onUndeclaredKey);
|
|
353
|
+
const { coercedEnv } = c(env, emptyAsUndefined, arrayFormat, shouldCoerce ? () => {
|
|
354
|
+
return {
|
|
355
|
+
schema: schemaWithKeys.in.toJsonSchema({ fallback: (ctx) => ctx.base }),
|
|
356
|
+
hasSchema: true
|
|
357
|
+
};
|
|
358
|
+
} : void 0);
|
|
359
|
+
const validatedEnv = schemaWithKeys(coercedEnv);
|
|
360
|
+
if (validatedEnv instanceof arktype.ArkErrors) throw new h(arkErrorsToIssues(validatedEnv, config));
|
|
361
|
+
return validatedEnv;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
//#endregion
|
|
365
|
+
//#region src/arkenv.ts
|
|
366
|
+
function arkenv(def, config = {}) {
|
|
367
|
+
if (config.safe) return E(() => parse(def, config));
|
|
368
|
+
return parse(def, config);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
//#endregion
|
|
372
|
+
//#region src/index.ts
|
|
373
|
+
/**
|
|
374
|
+
* Like ArkType's `type`, but with ArkEnv's extra keywords, such as:
|
|
375
|
+
*
|
|
376
|
+
* - `string.host` – a hostname (e.g. `"localhost"`, `"127.0.0.1"`)
|
|
377
|
+
* - `number.port` – a port number (e.g. `8080`)
|
|
378
|
+
*
|
|
379
|
+
* See ArkType's docs for the full API:
|
|
380
|
+
* https://arktype.io/docs/type-api
|
|
381
|
+
*/
|
|
382
|
+
const type = i$1.type;
|
|
383
|
+
/**
|
|
384
|
+
* ArkEnv's main export, an alias for {@link arkenv}
|
|
385
|
+
*
|
|
386
|
+
* {@link https://arkenv.js.org | ArkEnv} is a typesafe environment variables validator from editor to runtime.
|
|
387
|
+
*/
|
|
388
|
+
var src_default = arkenv;
|
|
389
|
+
|
|
390
|
+
//#endregion
|
|
391
|
+
exports.ArkEnvError = h;
|
|
392
|
+
exports.arkenv = arkenv;
|
|
393
|
+
exports.default = src_default;
|
|
394
|
+
exports.formatIssues = m;
|
|
395
|
+
exports.getSchemaKeys = P;
|
|
396
|
+
exports.type = type;
|
|
397
|
+
|
|
398
|
+
// CJS Interop Shim
|
|
399
|
+
if (module.exports && module.exports.default) {
|
|
400
|
+
Object.assign(module.exports.default, module.exports);
|
|
401
|
+
module.exports = module.exports.default;
|
|
402
|
+
}
|
|
403
|
+
|