@stacksjs/env 0.74.68 → 0.74.70
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/dist/index.d.ts +1 -0
- package/dist/index.js +1 -1
- package/dist/integrations.d.ts +95 -0
- package/dist/integrations.js +1 -0
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./runtime";export*from"./deployment";export*from"./types";export*from"./crypto";export*from"./parser";export*from"./plugin";export*from"./cli";export*from"./plaintext";export*from"./tenants";export*from"./utils";
|
|
1
|
+
export*from"./runtime";export*from"./deployment";export*from"./integrations";export*from"./types";export*from"./crypto";export*from"./parser";export*from"./plugin";export*from"./cli";export*from"./plaintext";export*from"./tenants";export*from"./utils";
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fold the spellings that mean the same deployment onto one name, so an
|
|
3
|
+
* allowlist of `['prod']` admits `APP_ENV=production` and the reverse.
|
|
4
|
+
*
|
|
5
|
+
* Only these three aliases, and only exact matches. `local`, `development` and
|
|
6
|
+
* `test` are deliberately **not** folded together: they are three different
|
|
7
|
+
* places with three different reasons to be excluded, and a framework that
|
|
8
|
+
* quietly treated them as one would make "allow my machine" also mean "allow
|
|
9
|
+
* CI". `@stacksjs/env`'s own loader normalizes the same three aliases when it
|
|
10
|
+
* picks an `.env` file to read.
|
|
11
|
+
*/
|
|
12
|
+
export declare function normalizeEnvironmentName(value: string | undefined | null): string | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* The environment an integration should gate on, or `undefined` when nothing
|
|
15
|
+
* declared one.
|
|
16
|
+
*
|
|
17
|
+
* Read at call time rather than at import: `APP_ENV` is routinely set after the
|
|
18
|
+
* module graph loads - a test harness pinning it, a CLI resolving `--env` - and
|
|
19
|
+
* a const would freeze whatever happened to be set first (stacksjs/stacks#2581).
|
|
20
|
+
*
|
|
21
|
+
* Unlike `appEnv()`, which answers `local` so callers always have a string, this
|
|
22
|
+
* answers `undefined`. The difference matters here: an unset or unreadable
|
|
23
|
+
* `APP_ENV` must not be *guessed* into a label that an allowlist might admit.
|
|
24
|
+
*/
|
|
25
|
+
export declare function integrationEnvironment(): string | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* Decide whether an integration may initialize in this process.
|
|
28
|
+
*
|
|
29
|
+
* Same answer in a web or API server, the dashboard, a worker and a CLI
|
|
30
|
+
* command, because all of them read the same `APP_ENV`.
|
|
31
|
+
*
|
|
32
|
+
* @param options the integration's own configuration
|
|
33
|
+
* @param defaultEnvironments the allowlist to use when the app did not set one
|
|
34
|
+
*/
|
|
35
|
+
export declare function integrationGate(options: EnvironmentGatedIntegration | undefined | null, defaultEnvironments?: readonly string[]): IntegrationGate;
|
|
36
|
+
/**
|
|
37
|
+
* One environment gate, shared by every integration that talks to a remote
|
|
38
|
+
* service (stacksjs/stacks#2792).
|
|
39
|
+
*
|
|
40
|
+
* The problem it solves is not labelling. An adapter that attaches
|
|
41
|
+
* unconditionally and tags its events `development` still transmits them, so a
|
|
42
|
+
* laptop and a CI run report into the same project as production and a local
|
|
43
|
+
* startup failure reads as a live incident. The label describes the event; it
|
|
44
|
+
* does not stop it leaving.
|
|
45
|
+
*
|
|
46
|
+
* So the gate is evaluated *before* an adapter initializes. A gate that answers
|
|
47
|
+
* `false` means no upload client, no remote capture hook, no injected tracking
|
|
48
|
+
* script, no flush timer and no request - not "send it marked local". Ordinary
|
|
49
|
+
* console and file logging are unaffected: they are not this gate's business.
|
|
50
|
+
*
|
|
51
|
+
* The configuration surface is deliberately one option:
|
|
52
|
+
*
|
|
53
|
+
* ```ts
|
|
54
|
+
* bughq: {
|
|
55
|
+
* key: env.BUGHQ_KEY,
|
|
56
|
+
* environments: ['production', 'staging'],
|
|
57
|
+
* }
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* There is no sibling `environment` field and no `enabledIn`. An application
|
|
61
|
+
* never repeats `env.APP_ENV` in each integration: the effective value is
|
|
62
|
+
* resolved here once, used to check the allowlist, and handed back on
|
|
63
|
+
* {@link IntegrationGate.environment} so the adapter can attach it as event
|
|
64
|
+
* metadata without asking.
|
|
65
|
+
*
|
|
66
|
+
* **`APP_ENV` is a configuration label, not proof of deployment identity.** A
|
|
67
|
+
* command launched locally with `APP_ENV=production` passes a production
|
|
68
|
+
* allowlist, because nothing here can tell the difference. Treat the allowlist
|
|
69
|
+
* as "which labels may transmit", not as an authorization boundary.
|
|
70
|
+
*/
|
|
71
|
+
/**
|
|
72
|
+
* The default allowlist for a remote-telemetry integration.
|
|
73
|
+
*
|
|
74
|
+
* Deployed environments report; a developer's machine, CI and test runs do not,
|
|
75
|
+
* until someone adds their label. New integrations should adopt this rather than
|
|
76
|
+
* inventing a policy, and an existing installation's behaviour should not be
|
|
77
|
+
* changed silently by picking it up.
|
|
78
|
+
*/
|
|
79
|
+
export declare const REMOTE_TELEMETRY_ENVIRONMENTS: readonly string[];
|
|
80
|
+
/** The environment-gating surface an integration's own options extend. */
|
|
81
|
+
export declare interface EnvironmentGatedIntegration {
|
|
82
|
+
enabled?: boolean
|
|
83
|
+
environments?: readonly string[]
|
|
84
|
+
}
|
|
85
|
+
export declare interface IntegrationGate {
|
|
86
|
+
enabled: boolean
|
|
87
|
+
environment: string | undefined
|
|
88
|
+
reason: IntegrationGateReason
|
|
89
|
+
}
|
|
90
|
+
/** Why the gate answered as it did. Worth logging; worth asserting in tests. */
|
|
91
|
+
export type IntegrationGateReason = | 'disabled-explicitly'
|
|
92
|
+
| 'empty-allowlist'
|
|
93
|
+
| 'environment-unknown'
|
|
94
|
+
| 'environment-excluded'
|
|
95
|
+
| 'environment-allowed';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const REMOTE_TELEMETRY_ENVIRONMENTS=["production","staging"];export function normalizeEnvironmentName(value){if(typeof value!=="string")return;const normalized=value.trim().toLowerCase();if(!/^[a-z0-9_-]+$/.test(normalized))return;if(normalized==="prod")return"production";if(normalized==="stage")return"staging";if(normalized==="dev")return"development";return normalized}export function integrationEnvironment(){return normalizeEnvironmentName(process.env.APP_ENV)??normalizeEnvironmentName("development")}export function integrationGate(options,defaultEnvironments=REMOTE_TELEMETRY_ENVIRONMENTS){const environment=integrationEnvironment();if(options?.enabled===!1)return{enabled:!1,environment,reason:"disabled-explicitly"};const allowlist=options?.environments??defaultEnvironments;if(allowlist.length===0)return{enabled:!1,environment,reason:"empty-allowlist"};if(environment===void 0)return{enabled:!1,environment,reason:"environment-unknown"};const permitted=new Set;for(const entry of allowlist){const name=normalizeEnvironmentName(entry);if(name!==void 0)permitted.add(name)}return permitted.has(environment)?{enabled:!0,environment,reason:"environment-allowed"}:{enabled:!1,environment,reason:"environment-excluded"}}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/env",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.74.
|
|
5
|
+
"version": "0.74.70",
|
|
6
6
|
"description": "Stacks env helper methods.",
|
|
7
7
|
"author": "Chris Breuer",
|
|
8
8
|
"contributors": [
|
|
@@ -56,10 +56,10 @@
|
|
|
56
56
|
"prepublishOnly": "bun run build"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@stacksjs/path": "0.74.
|
|
59
|
+
"@stacksjs/path": "0.74.70"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"better-dx": "^0.2.24",
|
|
63
|
-
"@stacksjs/validation": "0.74.
|
|
63
|
+
"@stacksjs/validation": "0.74.70"
|
|
64
64
|
}
|
|
65
65
|
}
|