@buoy-gg/env 1.7.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/README.md +388 -0
- package/lib/commonjs/env/EnvVariables.js +25 -0
- package/lib/commonjs/env/components/EnvStatsOverview.js +134 -0
- package/lib/commonjs/env/components/EnvVarRow.js +170 -0
- package/lib/commonjs/env/components/EnvVarSection.js +84 -0
- package/lib/commonjs/env/components/EnvVarsModal.js +315 -0
- package/lib/commonjs/env/hooks/useDynamicEnv.js +87 -0
- package/lib/commonjs/env/index.js +16 -0
- package/lib/commonjs/env/types/index.js +27 -0
- package/lib/commonjs/env/types/types.js +1 -0
- package/lib/commonjs/env/types/userTypes.js +1 -0
- package/lib/commonjs/env/utils/envTypeDetector.js +59 -0
- package/lib/commonjs/env/utils/helpers.js +119 -0
- package/lib/commonjs/env/utils/index.js +38 -0
- package/lib/commonjs/env/utils/utils.js +121 -0
- package/lib/commonjs/index.js +54 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/preset.js +90 -0
- package/lib/module/env/EnvVariables.js +11 -0
- package/lib/module/env/components/EnvStatsOverview.js +130 -0
- package/lib/module/env/components/EnvVarRow.js +166 -0
- package/lib/module/env/components/EnvVarSection.js +80 -0
- package/lib/module/env/components/EnvVarsModal.js +311 -0
- package/lib/module/env/hooks/useDynamicEnv.js +83 -0
- package/lib/module/env/index.js +3 -0
- package/lib/module/env/types/index.js +4 -0
- package/lib/module/env/types/types.js +1 -0
- package/lib/module/env/types/userTypes.js +1 -0
- package/lib/module/env/utils/envTypeDetector.js +55 -0
- package/lib/module/env/utils/helpers.js +114 -0
- package/lib/module/env/utils/index.js +5 -0
- package/lib/module/env/utils/utils.js +116 -0
- package/lib/module/index.js +13 -0
- package/lib/module/preset.js +85 -0
- package/lib/typescript/env/EnvVariables.d.ts +8 -0
- package/lib/typescript/env/EnvVariables.d.ts.map +1 -0
- package/lib/typescript/env/components/EnvStatsOverview.d.ts +20 -0
- package/lib/typescript/env/components/EnvStatsOverview.d.ts.map +1 -0
- package/lib/typescript/env/components/EnvVarRow.d.ts +9 -0
- package/lib/typescript/env/components/EnvVarRow.d.ts.map +1 -0
- package/lib/typescript/env/components/EnvVarSection.d.ts +10 -0
- package/lib/typescript/env/components/EnvVarSection.d.ts.map +1 -0
- package/lib/typescript/env/components/EnvVarsModal.d.ts +26 -0
- package/lib/typescript/env/components/EnvVarsModal.d.ts.map +1 -0
- package/lib/typescript/env/hooks/useDynamicEnv.d.ts +39 -0
- package/lib/typescript/env/hooks/useDynamicEnv.d.ts.map +1 -0
- package/lib/typescript/env/index.d.ts +2 -0
- package/lib/typescript/env/index.d.ts.map +1 -0
- package/lib/typescript/env/types/index.d.ts +3 -0
- package/lib/typescript/env/types/index.d.ts.map +1 -0
- package/lib/typescript/env/types/types.d.ts +67 -0
- package/lib/typescript/env/types/types.d.ts.map +1 -0
- package/lib/typescript/env/types/userTypes.d.ts +3 -0
- package/lib/typescript/env/types/userTypes.d.ts.map +1 -0
- package/lib/typescript/env/utils/envTypeDetector.d.ts +10 -0
- package/lib/typescript/env/utils/envTypeDetector.d.ts.map +1 -0
- package/lib/typescript/env/utils/helpers.d.ts +70 -0
- package/lib/typescript/env/utils/helpers.d.ts.map +1 -0
- package/lib/typescript/env/utils/index.d.ts +4 -0
- package/lib/typescript/env/utils/index.d.ts.map +1 -0
- package/lib/typescript/env/utils/utils.d.ts +24 -0
- package/lib/typescript/env/utils/utils.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +5 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/preset.d.ts +86 -0
- package/lib/typescript/preset.d.ts.map +1 -0
- package/package.json +66 -0
package/README.md
ADDED
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
# @buoy/env
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@buoy/env)
|
|
4
|
+
|
|
5
|
+
Environment variables inspector and validator for React Native development tools.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Environment Variable Inspector**: Browse all environment variables in your app
|
|
10
|
+
- **Required Variable Validation**: Define and validate required environment variables
|
|
11
|
+
- **Type Checking**: Validate variable types (string, boolean, number, etc.)
|
|
12
|
+
- **Value Validation**: Check if variables match expected values
|
|
13
|
+
- **Search & Filtering**: Search and filter by variable name, value, or status
|
|
14
|
+
- **Copy Functionality**: Easily copy variable values
|
|
15
|
+
- **Beautiful UI**: Modern, game-themed interface matching other React Buoy tools
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
This package is part of the React Buoy monorepo and is automatically available to other packages and the example app.
|
|
20
|
+
|
|
21
|
+
For external projects:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install @buoy/env
|
|
25
|
+
# or
|
|
26
|
+
pnpm add @buoy/env
|
|
27
|
+
# or
|
|
28
|
+
yarn add @buoy/env
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Quick Start
|
|
32
|
+
|
|
33
|
+
### Simplest Setup - Just 1 Line!
|
|
34
|
+
|
|
35
|
+
**Import the preset and add it to your tools array. Done!**
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { envToolPreset } from '@buoy/env';
|
|
39
|
+
import { FloatingDevTools } from '@buoy/core';
|
|
40
|
+
|
|
41
|
+
const installedApps = [
|
|
42
|
+
envToolPreset, // That's it! One line.
|
|
43
|
+
// ...your other tools
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
function App() {
|
|
47
|
+
return (
|
|
48
|
+
<FloatingDevTools
|
|
49
|
+
apps={installedApps}
|
|
50
|
+
environment="local"
|
|
51
|
+
userRole="admin"
|
|
52
|
+
/>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Done!** The preset automatically:
|
|
58
|
+
- ✅ Inspects all environment variables
|
|
59
|
+
- ✅ Provides search and filtering
|
|
60
|
+
- ✅ Includes copy functionality
|
|
61
|
+
- ✅ No configuration required
|
|
62
|
+
|
|
63
|
+
### Custom Configuration
|
|
64
|
+
|
|
65
|
+
If you need to validate specific environment variables:
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import { createEnvTool, createEnvVarConfig, envVar } from '@buoy/env';
|
|
69
|
+
|
|
70
|
+
// Define required environment variables
|
|
71
|
+
const requiredEnvVars = createEnvVarConfig([
|
|
72
|
+
envVar("EXPO_PUBLIC_API_URL").exists(),
|
|
73
|
+
envVar("EXPO_PUBLIC_DEBUG_MODE").withType("boolean").build(),
|
|
74
|
+
envVar("EXPO_PUBLIC_ENVIRONMENT").withValue("development").build(),
|
|
75
|
+
]);
|
|
76
|
+
|
|
77
|
+
// Create custom tool with validation
|
|
78
|
+
const myEnvTool = createEnvTool({
|
|
79
|
+
requiredEnvVars,
|
|
80
|
+
colorPreset: "cyan",
|
|
81
|
+
enableSharedModalDimensions: true,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
const installedApps = [
|
|
85
|
+
myEnvTool,
|
|
86
|
+
// ...other tools
|
|
87
|
+
];
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Alternative: Manual Setup
|
|
91
|
+
|
|
92
|
+
If you're not using FloatingDevTools or want more control:
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
import { EnvVarsModal, createEnvVarConfig, envVar } from '@buoy/env';
|
|
96
|
+
|
|
97
|
+
const requiredEnvVars = createEnvVarConfig([
|
|
98
|
+
envVar("EXPO_PUBLIC_API_URL").exists(),
|
|
99
|
+
envVar("EXPO_PUBLIC_DEBUG_MODE").withType("boolean").build(),
|
|
100
|
+
]);
|
|
101
|
+
|
|
102
|
+
function App() {
|
|
103
|
+
const [showEnv, setShowEnv] = useState(false);
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<>
|
|
107
|
+
<Button onPress={() => setShowEnv(true)}>
|
|
108
|
+
Open Environment Inspector
|
|
109
|
+
</Button>
|
|
110
|
+
|
|
111
|
+
<EnvVarsModal
|
|
112
|
+
visible={showEnv}
|
|
113
|
+
onClose={() => setShowEnv(false)}
|
|
114
|
+
requiredEnvVars={requiredEnvVars}
|
|
115
|
+
/>
|
|
116
|
+
</>
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## API Reference
|
|
122
|
+
|
|
123
|
+
### Presets
|
|
124
|
+
|
|
125
|
+
#### `envToolPreset`
|
|
126
|
+
|
|
127
|
+
Pre-configured environment variables tool ready to use with FloatingDevTools.
|
|
128
|
+
|
|
129
|
+
**Example:**
|
|
130
|
+
```typescript
|
|
131
|
+
import { envToolPreset } from '@buoy/env';
|
|
132
|
+
|
|
133
|
+
const installedApps = [envToolPreset];
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
#### `createEnvTool(options?)`
|
|
137
|
+
|
|
138
|
+
Create a custom environment variables tool configuration.
|
|
139
|
+
|
|
140
|
+
**Options:**
|
|
141
|
+
```typescript
|
|
142
|
+
{
|
|
143
|
+
/** Tool name (default: "ENV") */
|
|
144
|
+
name?: string;
|
|
145
|
+
/** Tool description */
|
|
146
|
+
description?: string;
|
|
147
|
+
/** Icon color preset (default: "green") */
|
|
148
|
+
colorPreset?: "orange" | "cyan" | "purple" | "pink" | "yellow" | "green";
|
|
149
|
+
/** Custom tool ID (default: "env") */
|
|
150
|
+
id?: string;
|
|
151
|
+
/** Array of required environment variables to validate */
|
|
152
|
+
requiredEnvVars?: RequiredEnvVar[];
|
|
153
|
+
/** Enable shared modal dimensions */
|
|
154
|
+
enableSharedModalDimensions?: boolean;
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**Example:**
|
|
159
|
+
```typescript
|
|
160
|
+
import { createEnvTool, createEnvVarConfig, envVar } from '@buoy/env';
|
|
161
|
+
|
|
162
|
+
const requiredEnvVars = createEnvVarConfig([
|
|
163
|
+
envVar("API_URL").exists(),
|
|
164
|
+
envVar("DEBUG").withType("boolean").build(),
|
|
165
|
+
]);
|
|
166
|
+
|
|
167
|
+
const myEnvTool = createEnvTool({
|
|
168
|
+
name: "ENVIRONMENT",
|
|
169
|
+
requiredEnvVars,
|
|
170
|
+
colorPreset: "purple",
|
|
171
|
+
enableSharedModalDimensions: true,
|
|
172
|
+
});
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Components
|
|
176
|
+
|
|
177
|
+
#### `EnvVarsModal`
|
|
178
|
+
|
|
179
|
+
Main modal component for inspecting environment variables.
|
|
180
|
+
|
|
181
|
+
**Props:**
|
|
182
|
+
```typescript
|
|
183
|
+
interface EnvVarsModalProps {
|
|
184
|
+
/** Whether the modal is visible */
|
|
185
|
+
visible: boolean;
|
|
186
|
+
/** Callback when modal is closed */
|
|
187
|
+
onClose: () => void;
|
|
188
|
+
/** List of required environment variables to validate */
|
|
189
|
+
requiredEnvVars: RequiredEnvVar[];
|
|
190
|
+
/** Optional back button handler */
|
|
191
|
+
onBack?: () => void;
|
|
192
|
+
/** Whether to use shared modal dimensions */
|
|
193
|
+
enableSharedModalDimensions?: boolean;
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
**Example:**
|
|
198
|
+
```typescript
|
|
199
|
+
<EnvVarsModal
|
|
200
|
+
visible={isVisible}
|
|
201
|
+
onClose={handleClose}
|
|
202
|
+
requiredEnvVars={requiredEnvVars}
|
|
203
|
+
/>
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Utilities
|
|
207
|
+
|
|
208
|
+
#### `createEnvVarConfig(validators)`
|
|
209
|
+
|
|
210
|
+
Create an array of required environment variables with validation rules.
|
|
211
|
+
|
|
212
|
+
**Signature:**
|
|
213
|
+
```typescript
|
|
214
|
+
function createEnvVarConfig(
|
|
215
|
+
validators: EnvVarValidator[]
|
|
216
|
+
): RequiredEnvVar[]
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
**Example:**
|
|
220
|
+
```typescript
|
|
221
|
+
import { createEnvVarConfig, envVar } from '@buoy/env';
|
|
222
|
+
|
|
223
|
+
const config = createEnvVarConfig([
|
|
224
|
+
envVar("API_URL").exists(),
|
|
225
|
+
envVar("DEBUG").withType("boolean").build(),
|
|
226
|
+
envVar("ENVIRONMENT").withValue("production").build(),
|
|
227
|
+
]);
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
#### `envVar(key)`
|
|
231
|
+
|
|
232
|
+
Create a fluent validator for an environment variable.
|
|
233
|
+
|
|
234
|
+
**Signature:**
|
|
235
|
+
```typescript
|
|
236
|
+
function envVar(key: string): EnvVarValidator
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
**Methods:**
|
|
240
|
+
- `.exists()` - Validate that the variable exists
|
|
241
|
+
- `.withType(type)` - Validate the variable type (string, boolean, number, etc.)
|
|
242
|
+
- `.withValue(value)` - Validate the variable matches a specific value
|
|
243
|
+
- `.build()` - Finalize the validator
|
|
244
|
+
|
|
245
|
+
**Example:**
|
|
246
|
+
```typescript
|
|
247
|
+
import { envVar } from '@buoy/env';
|
|
248
|
+
|
|
249
|
+
// Variable must exist
|
|
250
|
+
envVar("API_URL").exists();
|
|
251
|
+
|
|
252
|
+
// Variable must be a boolean
|
|
253
|
+
envVar("DEBUG_MODE").withType("boolean").build();
|
|
254
|
+
|
|
255
|
+
// Variable must match specific value
|
|
256
|
+
envVar("ENVIRONMENT").withValue("staging").build();
|
|
257
|
+
|
|
258
|
+
// Combined validation
|
|
259
|
+
envVar("PORT")
|
|
260
|
+
.withType("number")
|
|
261
|
+
.withValue("3000")
|
|
262
|
+
.build();
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Types
|
|
266
|
+
|
|
267
|
+
#### `RequiredEnvVar`
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
interface RequiredEnvVar {
|
|
271
|
+
/** Environment variable key */
|
|
272
|
+
key: string;
|
|
273
|
+
/** Optional description */
|
|
274
|
+
description?: string;
|
|
275
|
+
/** Expected type */
|
|
276
|
+
expectedType?: "string" | "boolean" | "number" | "json";
|
|
277
|
+
/** Expected value */
|
|
278
|
+
expectedValue?: string;
|
|
279
|
+
/** Whether the variable must exist */
|
|
280
|
+
required?: boolean;
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
#### `Environment`
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
type Environment =
|
|
288
|
+
| "local"
|
|
289
|
+
| "development"
|
|
290
|
+
| "staging"
|
|
291
|
+
| "production"
|
|
292
|
+
| string;
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
#### `UserRole`
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
type UserRole = "admin" | "internal" | "user";
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## Use Cases
|
|
302
|
+
|
|
303
|
+
### API Configuration Validation
|
|
304
|
+
|
|
305
|
+
```typescript
|
|
306
|
+
import { createEnvTool, createEnvVarConfig, envVar } from '@buoy/env';
|
|
307
|
+
|
|
308
|
+
const requiredEnvVars = createEnvVarConfig([
|
|
309
|
+
envVar("EXPO_PUBLIC_API_URL").exists(),
|
|
310
|
+
envVar("EXPO_PUBLIC_API_KEY").exists(),
|
|
311
|
+
envVar("EXPO_PUBLIC_API_TIMEOUT").withType("number").build(),
|
|
312
|
+
]);
|
|
313
|
+
|
|
314
|
+
const envTool = createEnvTool({ requiredEnvVars });
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
### Environment-Specific Validation
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
import { createEnvVarConfig, envVar } from '@buoy/env';
|
|
321
|
+
|
|
322
|
+
const requiredEnvVars = createEnvVarConfig([
|
|
323
|
+
envVar("EXPO_PUBLIC_ENVIRONMENT")
|
|
324
|
+
.withValue("development")
|
|
325
|
+
.build(),
|
|
326
|
+
envVar("EXPO_PUBLIC_DEBUG_MODE")
|
|
327
|
+
.withType("boolean")
|
|
328
|
+
.build(),
|
|
329
|
+
envVar("EXPO_PUBLIC_ENABLE_LOGGING")
|
|
330
|
+
.withType("boolean")
|
|
331
|
+
.build(),
|
|
332
|
+
]);
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### Feature Flag Configuration
|
|
336
|
+
|
|
337
|
+
```typescript
|
|
338
|
+
import { createEnvVarConfig, envVar } from '@buoy/env';
|
|
339
|
+
|
|
340
|
+
const requiredEnvVars = createEnvVarConfig([
|
|
341
|
+
envVar("EXPO_PUBLIC_FEATURE_NEW_UI")
|
|
342
|
+
.withType("boolean")
|
|
343
|
+
.build(),
|
|
344
|
+
envVar("EXPO_PUBLIC_FEATURE_ANALYTICS")
|
|
345
|
+
.withType("boolean")
|
|
346
|
+
.build(),
|
|
347
|
+
envVar("EXPO_PUBLIC_FEATURE_BETA")
|
|
348
|
+
.withType("boolean")
|
|
349
|
+
.build(),
|
|
350
|
+
]);
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
## Dependencies
|
|
354
|
+
|
|
355
|
+
- `@buoy/shared-ui` - Common UI components and utilities
|
|
356
|
+
- React and React Native (peer dependencies)
|
|
357
|
+
|
|
358
|
+
## Development
|
|
359
|
+
|
|
360
|
+
### Building
|
|
361
|
+
|
|
362
|
+
```bash
|
|
363
|
+
pnpm build
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
### Type Checking
|
|
367
|
+
|
|
368
|
+
```bash
|
|
369
|
+
pnpm typecheck
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### Clean Build
|
|
373
|
+
|
|
374
|
+
```bash
|
|
375
|
+
pnpm clean
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
## License
|
|
379
|
+
|
|
380
|
+
MIT
|
|
381
|
+
|
|
382
|
+
## Contributing
|
|
383
|
+
|
|
384
|
+
See the main repository [CONTRIBUTING.md](../../CONTRIBUTING.md) for contribution guidelines.
|
|
385
|
+
|
|
386
|
+
## Support
|
|
387
|
+
|
|
388
|
+
For issues and feature requests, please visit the [GitHub repository](https://github.com/LovesWorking/react-native-buoy/issues).
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "EnvVarsModal", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _EnvVarsModal.EnvVarsModal;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "createEnvVarConfig", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _helpers.createEnvVarConfig;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "envVar", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _helpers.envVar;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
var _helpers = require("./utils/helpers");
|
|
25
|
+
var _EnvVarsModal = require("./components/EnvVarsModal");
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.EnvStatsOverview = EnvStatsOverview;
|
|
7
|
+
var _reactNative = require("react-native");
|
|
8
|
+
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
9
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
10
|
+
function EnvStatsOverview({
|
|
11
|
+
stats,
|
|
12
|
+
healthPercentage,
|
|
13
|
+
healthStatus,
|
|
14
|
+
healthColor,
|
|
15
|
+
activeFilter = "all",
|
|
16
|
+
onFilterChange
|
|
17
|
+
}) {
|
|
18
|
+
const issuesCount = stats.wrongValueCount + stats.wrongTypeCount;
|
|
19
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
20
|
+
style: styles.container,
|
|
21
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CompactRow, {
|
|
22
|
+
statusDotColor: healthColor,
|
|
23
|
+
statusLabel: "System",
|
|
24
|
+
statusSublabel: healthStatus.toLowerCase(),
|
|
25
|
+
primaryText: "Environment Configuration",
|
|
26
|
+
secondaryText: `${healthPercentage}% healthy`,
|
|
27
|
+
customBadge: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
28
|
+
style: [styles.percentBadge, {
|
|
29
|
+
borderColor: healthColor + "40",
|
|
30
|
+
backgroundColor: healthColor + "10"
|
|
31
|
+
}],
|
|
32
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
33
|
+
style: [styles.percentText, {
|
|
34
|
+
color: healthColor
|
|
35
|
+
}],
|
|
36
|
+
children: [healthPercentage, "%"]
|
|
37
|
+
})
|
|
38
|
+
})
|
|
39
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
40
|
+
style: styles.statsGrid,
|
|
41
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
42
|
+
style: [styles.statCard, activeFilter === "all" && styles.statCardActive],
|
|
43
|
+
onPress: () => onFilterChange?.("all"),
|
|
44
|
+
activeOpacity: 0.8,
|
|
45
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
46
|
+
style: [styles.statValue, activeFilter === "all" && styles.statValueActive],
|
|
47
|
+
children: stats.requiredCount + stats.optionalCount
|
|
48
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
49
|
+
style: [styles.statLabel, activeFilter === "all" && styles.statLabelActive],
|
|
50
|
+
children: "ALL"
|
|
51
|
+
})]
|
|
52
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
53
|
+
style: [styles.statCard, activeFilter === "missing" && styles.statCardActive],
|
|
54
|
+
onPress: () => onFilterChange?.("missing"),
|
|
55
|
+
activeOpacity: 0.8,
|
|
56
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
57
|
+
style: [styles.statValue, activeFilter === "missing" && styles.statValueActive],
|
|
58
|
+
children: stats.missingCount
|
|
59
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
60
|
+
style: [styles.statLabel, activeFilter === "missing" && styles.statLabelActive],
|
|
61
|
+
children: "MISSING"
|
|
62
|
+
})]
|
|
63
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
64
|
+
style: [styles.statCard, activeFilter === "issues" && styles.statCardActive],
|
|
65
|
+
onPress: () => onFilterChange?.("issues"),
|
|
66
|
+
activeOpacity: 0.8,
|
|
67
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
68
|
+
style: [styles.statValue, activeFilter === "issues" && styles.statValueActive],
|
|
69
|
+
children: issuesCount
|
|
70
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
71
|
+
style: [styles.statLabel, activeFilter === "issues" && styles.statLabelActive],
|
|
72
|
+
children: "ISSUES"
|
|
73
|
+
})]
|
|
74
|
+
})]
|
|
75
|
+
})]
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
const styles = _reactNative.StyleSheet.create({
|
|
79
|
+
container: {
|
|
80
|
+
gap: 8
|
|
81
|
+
},
|
|
82
|
+
statsGrid: {
|
|
83
|
+
flexDirection: "row",
|
|
84
|
+
gap: 8,
|
|
85
|
+
paddingHorizontal: 4
|
|
86
|
+
},
|
|
87
|
+
statCard: {
|
|
88
|
+
flex: 1,
|
|
89
|
+
backgroundColor: _sharedUi.buoyColors.card,
|
|
90
|
+
borderRadius: 10,
|
|
91
|
+
borderWidth: 1,
|
|
92
|
+
borderColor: _sharedUi.buoyColors.border,
|
|
93
|
+
padding: 12,
|
|
94
|
+
alignItems: "center",
|
|
95
|
+
justifyContent: "center",
|
|
96
|
+
minHeight: 64
|
|
97
|
+
},
|
|
98
|
+
statCardActive: {
|
|
99
|
+
borderColor: _sharedUi.buoyColors.primary,
|
|
100
|
+
backgroundColor: _sharedUi.buoyColors.primary + "10"
|
|
101
|
+
},
|
|
102
|
+
statValue: {
|
|
103
|
+
fontSize: 22,
|
|
104
|
+
fontWeight: "700",
|
|
105
|
+
fontFamily: "monospace",
|
|
106
|
+
lineHeight: 26,
|
|
107
|
+
color: _sharedUi.buoyColors.text
|
|
108
|
+
},
|
|
109
|
+
statValueActive: {
|
|
110
|
+
color: _sharedUi.buoyColors.primary
|
|
111
|
+
},
|
|
112
|
+
statLabel: {
|
|
113
|
+
fontSize: 9,
|
|
114
|
+
color: _sharedUi.buoyColors.textMuted,
|
|
115
|
+
marginTop: 4,
|
|
116
|
+
textTransform: "uppercase",
|
|
117
|
+
letterSpacing: 0.5,
|
|
118
|
+
fontWeight: "600"
|
|
119
|
+
},
|
|
120
|
+
statLabelActive: {
|
|
121
|
+
color: _sharedUi.buoyColors.primary
|
|
122
|
+
},
|
|
123
|
+
percentBadge: {
|
|
124
|
+
paddingHorizontal: 8,
|
|
125
|
+
paddingVertical: 4,
|
|
126
|
+
borderRadius: 6,
|
|
127
|
+
borderWidth: 1
|
|
128
|
+
},
|
|
129
|
+
percentText: {
|
|
130
|
+
fontSize: 14,
|
|
131
|
+
fontWeight: "700",
|
|
132
|
+
fontFamily: "monospace"
|
|
133
|
+
}
|
|
134
|
+
});
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.EnvVarRow = EnvVarRow;
|
|
7
|
+
var _reactNative = require("react-native");
|
|
8
|
+
var _sharedUi = require("@buoy-gg/shared-ui");
|
|
9
|
+
var _envTypeDetector = require("../utils/envTypeDetector");
|
|
10
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
11
|
+
const getStatusConfig = (status, expectedType) => {
|
|
12
|
+
switch (status) {
|
|
13
|
+
case "required_present":
|
|
14
|
+
return {
|
|
15
|
+
label: "Valid",
|
|
16
|
+
color: _sharedUi.buoyColors.success,
|
|
17
|
+
sublabel: "Required"
|
|
18
|
+
};
|
|
19
|
+
case "required_missing":
|
|
20
|
+
return {
|
|
21
|
+
label: "Missing",
|
|
22
|
+
color: _sharedUi.buoyColors.error,
|
|
23
|
+
sublabel: "Required"
|
|
24
|
+
};
|
|
25
|
+
case "required_wrong_value":
|
|
26
|
+
return {
|
|
27
|
+
label: "Wrong",
|
|
28
|
+
color: _sharedUi.buoyColors.warning,
|
|
29
|
+
sublabel: "Invalid value"
|
|
30
|
+
};
|
|
31
|
+
case "required_wrong_type":
|
|
32
|
+
return {
|
|
33
|
+
label: "Type Error",
|
|
34
|
+
color: _sharedUi.buoyColors.info,
|
|
35
|
+
sublabel: "Wrong type"
|
|
36
|
+
};
|
|
37
|
+
case "optional_present":
|
|
38
|
+
return {
|
|
39
|
+
label: "Set",
|
|
40
|
+
color: _sharedUi.buoyColors.textSecondary,
|
|
41
|
+
sublabel: "Optional"
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
const formatEnvKey = key => {
|
|
46
|
+
// Format key similar to React Query: "section > subsection"
|
|
47
|
+
return key.split("_").join(" › ");
|
|
48
|
+
};
|
|
49
|
+
const formatValue = value => {
|
|
50
|
+
if (value === undefined || value === null) {
|
|
51
|
+
return "undefined";
|
|
52
|
+
}
|
|
53
|
+
const str = typeof value === "string" ? value : String(value);
|
|
54
|
+
return str;
|
|
55
|
+
};
|
|
56
|
+
function EnvVarRow({
|
|
57
|
+
envVar,
|
|
58
|
+
isExpanded,
|
|
59
|
+
onPress
|
|
60
|
+
}) {
|
|
61
|
+
const config = getStatusConfig(envVar.status, envVar.expectedType);
|
|
62
|
+
const hasValue = envVar.value !== undefined && envVar.value !== null;
|
|
63
|
+
|
|
64
|
+
// Format primary text like React Query does: "section › subsection"
|
|
65
|
+
// For env vars, we'll show the key formatted nicely
|
|
66
|
+
const keyParts = envVar.key.split("_");
|
|
67
|
+
const primaryText = keyParts.map(part => part.toLowerCase()).join(" › ");
|
|
68
|
+
|
|
69
|
+
// Create expanded content for value and expected value
|
|
70
|
+
const expandedContent = /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
71
|
+
style: styles.expandedContainer,
|
|
72
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
73
|
+
style: styles.expandedRow,
|
|
74
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
75
|
+
style: styles.expandedLabel,
|
|
76
|
+
children: "Value:"
|
|
77
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
78
|
+
style: styles.expandedValue,
|
|
79
|
+
numberOfLines: 3,
|
|
80
|
+
children: formatValue(envVar.value) || "undefined"
|
|
81
|
+
})]
|
|
82
|
+
}), envVar.status === "required_wrong_type" && envVar.expectedType && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
83
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
84
|
+
style: styles.expandedRow,
|
|
85
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
86
|
+
style: styles.expandedLabel,
|
|
87
|
+
children: "Type:"
|
|
88
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.TypeBadge, {
|
|
89
|
+
type: (0, _envTypeDetector.getEnvVarType)(envVar.value)
|
|
90
|
+
})]
|
|
91
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
92
|
+
style: styles.expandedRow,
|
|
93
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
94
|
+
style: styles.expandedLabel,
|
|
95
|
+
children: "Expected:"
|
|
96
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.TypeBadge, {
|
|
97
|
+
type: envVar.expectedType
|
|
98
|
+
})]
|
|
99
|
+
})]
|
|
100
|
+
}), envVar.status === "required_wrong_value" && envVar.expectedValue && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
101
|
+
style: styles.expandedRow,
|
|
102
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
103
|
+
style: styles.expandedLabel,
|
|
104
|
+
children: "Expected:"
|
|
105
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
106
|
+
style: styles.expandedExpected,
|
|
107
|
+
children: String(envVar.expectedValue)
|
|
108
|
+
})]
|
|
109
|
+
}), envVar.description && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
110
|
+
style: styles.expandedRow,
|
|
111
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
112
|
+
style: styles.expandedLabel,
|
|
113
|
+
children: "Info:"
|
|
114
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
115
|
+
style: styles.expandedDescription,
|
|
116
|
+
children: envVar.description
|
|
117
|
+
})]
|
|
118
|
+
})]
|
|
119
|
+
});
|
|
120
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.CompactRow, {
|
|
121
|
+
statusDotColor: config.color,
|
|
122
|
+
statusLabel: config.label,
|
|
123
|
+
statusSublabel: config.sublabel,
|
|
124
|
+
primaryText: primaryText,
|
|
125
|
+
secondaryText: undefined // Don't show value inline anymore
|
|
126
|
+
,
|
|
127
|
+
expandedContent: expandedContent,
|
|
128
|
+
isExpanded: isExpanded,
|
|
129
|
+
expandedGlowColor: config.color,
|
|
130
|
+
customBadge: envVar.expectedType ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_sharedUi.TypeBadge, {
|
|
131
|
+
type: envVar.expectedType
|
|
132
|
+
}) : undefined,
|
|
133
|
+
showChevron: true,
|
|
134
|
+
onPress: onPress ? () => onPress(envVar) : undefined
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
const styles = _reactNative.StyleSheet.create({
|
|
138
|
+
expandedContainer: {
|
|
139
|
+
gap: 6
|
|
140
|
+
},
|
|
141
|
+
expandedRow: {
|
|
142
|
+
flexDirection: "row",
|
|
143
|
+
alignItems: "center",
|
|
144
|
+
gap: 8
|
|
145
|
+
},
|
|
146
|
+
expandedLabel: {
|
|
147
|
+
fontSize: 10,
|
|
148
|
+
color: _sharedUi.buoyColors.textMuted,
|
|
149
|
+
fontWeight: "600",
|
|
150
|
+
minWidth: 60,
|
|
151
|
+
fontFamily: "monospace"
|
|
152
|
+
},
|
|
153
|
+
expandedValue: {
|
|
154
|
+
fontSize: 11,
|
|
155
|
+
color: _sharedUi.buoyColors.textSecondary,
|
|
156
|
+
fontFamily: "monospace",
|
|
157
|
+
flex: 1
|
|
158
|
+
},
|
|
159
|
+
expandedExpected: {
|
|
160
|
+
fontSize: 11,
|
|
161
|
+
color: _sharedUi.buoyColors.warning,
|
|
162
|
+
fontFamily: "monospace",
|
|
163
|
+
flex: 1
|
|
164
|
+
},
|
|
165
|
+
expandedDescription: {
|
|
166
|
+
fontSize: 11,
|
|
167
|
+
color: _sharedUi.buoyColors.textSecondary,
|
|
168
|
+
flex: 1
|
|
169
|
+
}
|
|
170
|
+
});
|