@kindgi/env-schema 0.0.0-bootstrap.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/values.ts ADDED
@@ -0,0 +1,59 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // Copyright (C) 2026 Kindgi Inc.
3
+
4
+ /**
5
+ * Value checks for variables whose shape the schema can't express.
6
+ * Shared by the server, which reads them at startup, and the CLI, which
7
+ * checks them before it starts anything: both refuse the same values
8
+ * with the same message.
9
+ */
10
+
11
+ /** The Ed25519 private key file that signs public run tokens. */
12
+ export const PUBLIC_TOKEN_KEY_PATH_VAR = 'KINDGI_PUBLIC_TOKEN_SIGNING_KEY_PATH';
13
+
14
+ /** The same key's PEM file, base64: the alternative to the path. */
15
+ export const PUBLIC_TOKEN_KEY_VAR = 'KINDGI_PUBLIC_TOKEN_SIGNING_KEY';
16
+
17
+ /** The license key the server checks at startup outside development mode. */
18
+ export const LICENSE_KEY_VAR = 'KINDGI_LICENSE_KEY';
19
+
20
+ /** The browser origins allowed on the routes a public run token opens. */
21
+ export const CORS_ORIGINS_VAR = 'KINDGI_CORS_ORIGINS';
22
+
23
+ /**
24
+ * Parse `KINDGI_CORS_ORIGINS`: comma-separated exact origins
25
+ * (`https://app.example.com`, `http://localhost:3000`): a scheme, a host
26
+ * and an optional port; no path, no trailing slash, no wildcard. Unset or
27
+ * empty: none. Throws on anything else, so a typo fails at startup rather
28
+ * than as a browser's CORS error.
29
+ */
30
+ export function parseCorsOrigins(raw: string | undefined): readonly string[] {
31
+ if (raw === undefined || raw.trim() === '') return [];
32
+ const origins = raw
33
+ .split(',')
34
+ .map((entry) => entry.trim())
35
+ .filter((entry) => entry !== '');
36
+ const invalid = origins.filter((origin) => !isExactOrigin(origin));
37
+ if (invalid.length > 0) {
38
+ throw new Error(
39
+ `${CORS_ORIGINS_VAR} entries must be exact origins like https://app.example.com ` +
40
+ `(scheme, host, optional port; no path or wildcard). Got: ${invalid.join(', ')}.`,
41
+ );
42
+ }
43
+ return [...new Set(origins)];
44
+ }
45
+
46
+ function isExactOrigin(value: string): boolean {
47
+ let url: URL;
48
+ try {
49
+ url = new URL(value);
50
+ } catch {
51
+ return false;
52
+ }
53
+ // `https://*.example.com` parses (as a literal `*` host): refuse it.
54
+ return (
55
+ (url.protocol === 'https:' || url.protocol === 'http:') &&
56
+ url.origin === value &&
57
+ !value.includes('*')
58
+ );
59
+ }