env-flag 1.0.0
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 +91 -0
- package/dist/index.d.ts +66 -0
- package/dist/index.js +317 -0
- package/package.json +37 -0
package/README.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# env-flag
|
|
2
|
+
|
|
3
|
+
A lightweight, customizable environment flag indicator for browser applications. Shows DEV/PROD/STAGING/TEST status as a badge in your app. Perfect for distinguishing environments at a glance!
|
|
4
|
+
|
|
5
|
+
## 🚀 Features
|
|
6
|
+
- **Automatic environment detection** (development, production, staging, test)
|
|
7
|
+
- **Customizable colors, text, position, and size**
|
|
8
|
+
- **Accessible** (keyboard, screen reader, ARIA labels)
|
|
9
|
+
- **TypeScript support**
|
|
10
|
+
- **No dependencies**
|
|
11
|
+
|
|
12
|
+
## 📦 Installation
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
npm install env-flag
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
or
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
yarn add env-flag
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## 🛠️ Usage
|
|
25
|
+
|
|
26
|
+
### Basic
|
|
27
|
+
```js
|
|
28
|
+
import EnvFlag from 'env-flag';
|
|
29
|
+
|
|
30
|
+
const flag = new EnvFlag();
|
|
31
|
+
flag.init();
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### With Custom Options
|
|
35
|
+
```js
|
|
36
|
+
import EnvFlag from 'env-flag';
|
|
37
|
+
|
|
38
|
+
const flag = new EnvFlag({
|
|
39
|
+
position: 'top-left',
|
|
40
|
+
size: 'large',
|
|
41
|
+
productionColor: '#27ae60',
|
|
42
|
+
developmentText: 'DEVS',
|
|
43
|
+
debug: true
|
|
44
|
+
});
|
|
45
|
+
flag.init();
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Force Environment (for testing)
|
|
49
|
+
```js
|
|
50
|
+
const flag = new EnvFlag({
|
|
51
|
+
forceEnv: 'staging',
|
|
52
|
+
stagingColor: '#ff9800',
|
|
53
|
+
stagingText: 'STAGING'
|
|
54
|
+
});
|
|
55
|
+
flag.init();
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## ⚙️ Configuration
|
|
59
|
+
|
|
60
|
+
| Option | Type | Default | Description |
|
|
61
|
+
|--------------------|----------|-----------------|----------------------------------------------|
|
|
62
|
+
| productionColor | string | `#e74c3c` | Prod badge color |
|
|
63
|
+
| developmentColor | string | `#3498db` | Dev badge color |
|
|
64
|
+
| stagingColor | string | `#f39c12` | Staging badge color |
|
|
65
|
+
| testColor | string | `#9b59b6` | Test badge color |
|
|
66
|
+
| productionText | string | `PROD` | Prod badge text |
|
|
67
|
+
| developmentText | string | `DEV` | Dev badge text |
|
|
68
|
+
| stagingText | string | `STAGING` | Staging badge text |
|
|
69
|
+
| testText | string | `TEST` | Test badge text |
|
|
70
|
+
| position | string | `bottom-right` | Badge position (`top-right`, `top-left`, `bottom-right`, `bottom-left`) |
|
|
71
|
+
| size | string | `medium` | Badge size (`small`, `medium`, `large`) |
|
|
72
|
+
| autoDetectEnv | boolean | `true` | Try to detect environment automatically |
|
|
73
|
+
| forceEnv | string | | Force environment (`production`, `development`, `staging`, `test`) |
|
|
74
|
+
| enabled | boolean | `true` | Show/hide the flag |
|
|
75
|
+
| debug | boolean | `false` | Enable debug logs |
|
|
76
|
+
|
|
77
|
+
## 🧑💻 Contributing
|
|
78
|
+
|
|
79
|
+
1. Fork the repo
|
|
80
|
+
2. Create your feature branch (`git checkout -b feature/your-feature`)
|
|
81
|
+
3. Commit your changes (`git commit -am 'Add new feature'`)
|
|
82
|
+
4. Push to the branch (`git push origin feature/your-feature`)
|
|
83
|
+
5. Open a Pull Request
|
|
84
|
+
|
|
85
|
+
## 📄 License
|
|
86
|
+
|
|
87
|
+
ISC
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
Made with ❤️ by Koray TUNCER
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment Flag - A lightweight library to display environment indicators
|
|
3
|
+
* @version 1.0.0
|
|
4
|
+
*/
|
|
5
|
+
type Environment = 'development' | 'production' | 'staging' | 'test';
|
|
6
|
+
type Position = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
|
|
7
|
+
type Size = 'small' | 'medium' | 'large';
|
|
8
|
+
interface EnvFlagConfig {
|
|
9
|
+
readonly productionColor?: string;
|
|
10
|
+
readonly developmentColor?: string;
|
|
11
|
+
readonly stagingColor?: string;
|
|
12
|
+
readonly testColor?: string;
|
|
13
|
+
readonly productionText?: string;
|
|
14
|
+
readonly developmentText?: string;
|
|
15
|
+
readonly stagingText?: string;
|
|
16
|
+
readonly testText?: string;
|
|
17
|
+
readonly position?: Position;
|
|
18
|
+
readonly size?: Size;
|
|
19
|
+
readonly autoDetectEnv?: boolean;
|
|
20
|
+
readonly forceEnv?: Environment;
|
|
21
|
+
readonly enabled?: boolean;
|
|
22
|
+
readonly debug?: boolean;
|
|
23
|
+
}
|
|
24
|
+
declare class EnvFlag {
|
|
25
|
+
private static readonly DEFAULT_CONFIG;
|
|
26
|
+
private static readonly ELEMENT_ID;
|
|
27
|
+
private static readonly Z_INDEX;
|
|
28
|
+
private readonly config;
|
|
29
|
+
private flagElement;
|
|
30
|
+
private eventListeners;
|
|
31
|
+
constructor(config?: EnvFlagConfig);
|
|
32
|
+
/**
|
|
33
|
+
* Initialize the environment flag
|
|
34
|
+
*/
|
|
35
|
+
init(): void;
|
|
36
|
+
/**
|
|
37
|
+
* Destroy the environment flag and clean up resources
|
|
38
|
+
*/
|
|
39
|
+
destroy(): void;
|
|
40
|
+
/**
|
|
41
|
+
* Update configuration and recreate flag
|
|
42
|
+
*/
|
|
43
|
+
updateConfig(newConfig: Partial<EnvFlagConfig>): void;
|
|
44
|
+
/**
|
|
45
|
+
* Get current environment
|
|
46
|
+
*/
|
|
47
|
+
getCurrentEnvironment(): Environment;
|
|
48
|
+
private isValidEnvironment;
|
|
49
|
+
private detectEnvironment;
|
|
50
|
+
private createFlag;
|
|
51
|
+
private applyStyles;
|
|
52
|
+
private getEnvironmentStyles;
|
|
53
|
+
private getEnvironmentText;
|
|
54
|
+
private getSizeStyles;
|
|
55
|
+
private getPositionStyles;
|
|
56
|
+
private getPositionCoordinates;
|
|
57
|
+
private attachEventListeners;
|
|
58
|
+
private handleClick;
|
|
59
|
+
private handleMouseEnter;
|
|
60
|
+
private handleMouseLeave;
|
|
61
|
+
private handleKeydown;
|
|
62
|
+
private removeEventListeners;
|
|
63
|
+
private removeFlagElement;
|
|
64
|
+
}
|
|
65
|
+
export default EnvFlag;
|
|
66
|
+
export type { EnvFlagConfig, Environment, Position, Size };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment Flag - A lightweight library to display environment indicators
|
|
3
|
+
* @version 1.0.0
|
|
4
|
+
*/
|
|
5
|
+
class EnvFlag {
|
|
6
|
+
constructor(config = {}) {
|
|
7
|
+
this.flagElement = null;
|
|
8
|
+
this.eventListeners = [];
|
|
9
|
+
this.config = Object.assign(Object.assign({}, EnvFlag.DEFAULT_CONFIG), config);
|
|
10
|
+
if (this.config.debug) {
|
|
11
|
+
console.log('[EnvFlag] Initialized with config:', this.config);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Initialize the environment flag
|
|
16
|
+
*/
|
|
17
|
+
init() {
|
|
18
|
+
try {
|
|
19
|
+
if (!this.isValidEnvironment()) {
|
|
20
|
+
if (this.config.debug) {
|
|
21
|
+
console.warn('[EnvFlag] Invalid environment, skipping initialization');
|
|
22
|
+
}
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (!this.config.enabled) {
|
|
26
|
+
if (this.config.debug) {
|
|
27
|
+
console.log('[EnvFlag] Flag is disabled');
|
|
28
|
+
}
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
this.destroy(); // Clean up any existing flag
|
|
32
|
+
this.createFlag();
|
|
33
|
+
if (this.config.debug) {
|
|
34
|
+
console.log('[EnvFlag] Flag created successfully');
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
console.error('[EnvFlag] Failed to initialize:', error);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Destroy the environment flag and clean up resources
|
|
43
|
+
*/
|
|
44
|
+
destroy() {
|
|
45
|
+
try {
|
|
46
|
+
this.removeEventListeners();
|
|
47
|
+
this.removeFlagElement();
|
|
48
|
+
if (this.config.debug) {
|
|
49
|
+
console.log('[EnvFlag] Flag destroyed and resources cleaned up');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
console.error('[EnvFlag] Error during cleanup:', error);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Update configuration and recreate flag
|
|
58
|
+
*/
|
|
59
|
+
updateConfig(newConfig) {
|
|
60
|
+
Object.assign(this.config, newConfig);
|
|
61
|
+
this.init();
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get current environment
|
|
65
|
+
*/
|
|
66
|
+
getCurrentEnvironment() {
|
|
67
|
+
if (this.config.forceEnv) {
|
|
68
|
+
return this.config.forceEnv;
|
|
69
|
+
}
|
|
70
|
+
if (!this.config.autoDetectEnv) {
|
|
71
|
+
return 'development';
|
|
72
|
+
}
|
|
73
|
+
return this.detectEnvironment();
|
|
74
|
+
}
|
|
75
|
+
isValidEnvironment() {
|
|
76
|
+
if (typeof window === 'undefined') {
|
|
77
|
+
if (this.config.debug) {
|
|
78
|
+
console.warn('[EnvFlag] Window is undefined, likely running in Node.js environment');
|
|
79
|
+
}
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
if (typeof document === 'undefined') {
|
|
83
|
+
if (this.config.debug) {
|
|
84
|
+
console.warn('[EnvFlag] Document is undefined');
|
|
85
|
+
}
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
detectEnvironment() {
|
|
91
|
+
var _a, _b, _c;
|
|
92
|
+
// Check various environment indicators
|
|
93
|
+
const indicators = {
|
|
94
|
+
hostname: ((_a = window.location) === null || _a === void 0 ? void 0 : _a.hostname) || '',
|
|
95
|
+
nodeEnv: ((_c = (_b = globalThis.process) === null || _b === void 0 ? void 0 : _b.env) === null || _c === void 0 ? void 0 : _c.NODE_ENV) || '',
|
|
96
|
+
userAgent: (navigator === null || navigator === void 0 ? void 0 : navigator.userAgent) || ''
|
|
97
|
+
};
|
|
98
|
+
if (this.config.debug) {
|
|
99
|
+
console.log('[EnvFlag] Environment indicators:', indicators);
|
|
100
|
+
}
|
|
101
|
+
// Production indicators
|
|
102
|
+
if (indicators.nodeEnv === 'production' ||
|
|
103
|
+
indicators.hostname.includes('prod') ||
|
|
104
|
+
!indicators.hostname.includes('localhost') &&
|
|
105
|
+
!indicators.hostname.includes('127.0.0.1') &&
|
|
106
|
+
!indicators.hostname.includes('dev') &&
|
|
107
|
+
!indicators.hostname.includes('staging')) {
|
|
108
|
+
return 'production';
|
|
109
|
+
}
|
|
110
|
+
// Staging indicators
|
|
111
|
+
if (indicators.nodeEnv === 'staging' ||
|
|
112
|
+
indicators.hostname.includes('staging') ||
|
|
113
|
+
indicators.hostname.includes('stage')) {
|
|
114
|
+
return 'staging';
|
|
115
|
+
}
|
|
116
|
+
// Test indicators
|
|
117
|
+
if (indicators.nodeEnv === 'test' ||
|
|
118
|
+
indicators.hostname.includes('test')) {
|
|
119
|
+
return 'test';
|
|
120
|
+
}
|
|
121
|
+
// Default to development
|
|
122
|
+
return 'development';
|
|
123
|
+
}
|
|
124
|
+
createFlag() {
|
|
125
|
+
const environment = this.getCurrentEnvironment();
|
|
126
|
+
this.flagElement = document.createElement('div');
|
|
127
|
+
this.flagElement.id = EnvFlag.ELEMENT_ID;
|
|
128
|
+
this.flagElement.setAttribute('data-env', environment);
|
|
129
|
+
this.flagElement.setAttribute('role', 'status');
|
|
130
|
+
this.flagElement.setAttribute('aria-label', `Environment: ${environment}`);
|
|
131
|
+
this.applyStyles(environment);
|
|
132
|
+
this.attachEventListeners();
|
|
133
|
+
// Use requestAnimationFrame for better performance
|
|
134
|
+
requestAnimationFrame(() => {
|
|
135
|
+
if (this.flagElement && document.body) {
|
|
136
|
+
document.body.appendChild(this.flagElement);
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
applyStyles(environment) {
|
|
141
|
+
if (!this.flagElement)
|
|
142
|
+
return;
|
|
143
|
+
const styles = this.getEnvironmentStyles(environment);
|
|
144
|
+
const positionStyles = this.getPositionStyles();
|
|
145
|
+
const sizeStyles = this.getSizeStyles();
|
|
146
|
+
// Apply base styles
|
|
147
|
+
Object.assign(this.flagElement.style, Object.assign(Object.assign({
|
|
148
|
+
// Content
|
|
149
|
+
textContent: this.getEnvironmentText(environment),
|
|
150
|
+
// Colors
|
|
151
|
+
backgroundColor: styles.backgroundColor, color: styles.color,
|
|
152
|
+
// Typography
|
|
153
|
+
fontFamily: '"Segoe UI", system-ui, -apple-system, sans-serif', fontWeight: '600', fontSize: sizeStyles.fontSize, lineHeight: '1', textAlign: 'center',
|
|
154
|
+
// Layout
|
|
155
|
+
position: 'fixed', zIndex: EnvFlag.Z_INDEX, padding: sizeStyles.padding,
|
|
156
|
+
// Visual
|
|
157
|
+
borderRadius: positionStyles.borderRadius, boxShadow: '0 2px 8px rgba(0, 0, 0, 0.15)', backdropFilter: 'blur(8px)', opacity: styles.opacity,
|
|
158
|
+
// Interaction
|
|
159
|
+
cursor: 'pointer', userSelect: 'none', transition: 'all 0.2s ease-in-out' }, this.getPositionCoordinates()), {
|
|
160
|
+
// Accessibility
|
|
161
|
+
outline: 'none' }));
|
|
162
|
+
this.flagElement.textContent = this.getEnvironmentText(environment);
|
|
163
|
+
}
|
|
164
|
+
getEnvironmentStyles(environment) {
|
|
165
|
+
const colorMap = {
|
|
166
|
+
production: this.config.productionColor,
|
|
167
|
+
development: this.config.developmentColor,
|
|
168
|
+
staging: this.config.stagingColor,
|
|
169
|
+
test: this.config.testColor
|
|
170
|
+
};
|
|
171
|
+
return {
|
|
172
|
+
backgroundColor: colorMap[environment],
|
|
173
|
+
color: '#ffffff',
|
|
174
|
+
fontSize: this.getSizeStyles().fontSize,
|
|
175
|
+
padding: this.getSizeStyles().padding,
|
|
176
|
+
borderRadius: this.getPositionStyles().borderRadius,
|
|
177
|
+
opacity: '0.9'
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
getEnvironmentText(environment) {
|
|
181
|
+
const textMap = {
|
|
182
|
+
production: this.config.productionText,
|
|
183
|
+
development: this.config.developmentText,
|
|
184
|
+
staging: this.config.stagingText,
|
|
185
|
+
test: this.config.testText
|
|
186
|
+
};
|
|
187
|
+
return textMap[environment];
|
|
188
|
+
}
|
|
189
|
+
getSizeStyles() {
|
|
190
|
+
const sizeMap = {
|
|
191
|
+
small: { fontSize: '10px', padding: '4px 8px' },
|
|
192
|
+
medium: { fontSize: '12px', padding: '6px 12px' },
|
|
193
|
+
large: { fontSize: '14px', padding: '8px 16px' }
|
|
194
|
+
};
|
|
195
|
+
return sizeMap[this.config.size];
|
|
196
|
+
}
|
|
197
|
+
getPositionStyles() {
|
|
198
|
+
const radiusMap = {
|
|
199
|
+
'top-right': '0 0 0 4px',
|
|
200
|
+
'top-left': '0 0 4px 0',
|
|
201
|
+
'bottom-left': '0 4px 0 0',
|
|
202
|
+
'bottom-right': '4px 0 0 0'
|
|
203
|
+
};
|
|
204
|
+
return { borderRadius: radiusMap[this.config.position] };
|
|
205
|
+
}
|
|
206
|
+
getPositionCoordinates() {
|
|
207
|
+
const coordinateMap = {
|
|
208
|
+
'top-right': { top: '0', right: '0' },
|
|
209
|
+
'top-left': { top: '0', left: '0' },
|
|
210
|
+
'bottom-left': { bottom: '0', left: '0' },
|
|
211
|
+
'bottom-right': { bottom: '0', right: '0' }
|
|
212
|
+
};
|
|
213
|
+
return coordinateMap[this.config.position];
|
|
214
|
+
}
|
|
215
|
+
attachEventListeners() {
|
|
216
|
+
if (!this.flagElement)
|
|
217
|
+
return;
|
|
218
|
+
// Click to remove
|
|
219
|
+
const clickHandler = this.handleClick.bind(this);
|
|
220
|
+
this.flagElement.addEventListener('click', clickHandler);
|
|
221
|
+
this.eventListeners.push({
|
|
222
|
+
element: this.flagElement,
|
|
223
|
+
event: 'click',
|
|
224
|
+
handler: clickHandler
|
|
225
|
+
});
|
|
226
|
+
// Hover effects
|
|
227
|
+
const mouseEnterHandler = this.handleMouseEnter.bind(this);
|
|
228
|
+
const mouseLeaveHandler = this.handleMouseLeave.bind(this);
|
|
229
|
+
this.flagElement.addEventListener('mouseenter', mouseEnterHandler);
|
|
230
|
+
this.flagElement.addEventListener('mouseleave', mouseLeaveHandler);
|
|
231
|
+
this.eventListeners.push({
|
|
232
|
+
element: this.flagElement,
|
|
233
|
+
event: 'mouseenter',
|
|
234
|
+
handler: mouseEnterHandler
|
|
235
|
+
}, {
|
|
236
|
+
element: this.flagElement,
|
|
237
|
+
event: 'mouseleave',
|
|
238
|
+
handler: mouseLeaveHandler
|
|
239
|
+
});
|
|
240
|
+
// Keyboard accessibility
|
|
241
|
+
const keydownHandler = this.handleKeydown.bind(this);
|
|
242
|
+
this.flagElement.addEventListener('keydown', keydownHandler);
|
|
243
|
+
this.flagElement.setAttribute('tabindex', '0');
|
|
244
|
+
this.eventListeners.push({
|
|
245
|
+
element: this.flagElement,
|
|
246
|
+
event: 'keydown',
|
|
247
|
+
handler: keydownHandler
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
handleClick() {
|
|
251
|
+
this.destroy();
|
|
252
|
+
}
|
|
253
|
+
handleMouseEnter() {
|
|
254
|
+
if (this.flagElement) {
|
|
255
|
+
this.flagElement.style.opacity = '1';
|
|
256
|
+
this.flagElement.style.transform = 'scale(1.05)';
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
handleMouseLeave() {
|
|
260
|
+
if (this.flagElement) {
|
|
261
|
+
this.flagElement.style.opacity = '0.9';
|
|
262
|
+
this.flagElement.style.transform = 'scale(1)';
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
handleKeydown(event) {
|
|
266
|
+
const keyboardEvent = event;
|
|
267
|
+
if (keyboardEvent.key === 'Enter' || keyboardEvent.key === ' ') {
|
|
268
|
+
keyboardEvent.preventDefault();
|
|
269
|
+
this.destroy();
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
removeEventListeners() {
|
|
273
|
+
this.eventListeners.forEach(({ element, event, handler }) => {
|
|
274
|
+
element.removeEventListener(event, handler);
|
|
275
|
+
});
|
|
276
|
+
this.eventListeners = [];
|
|
277
|
+
}
|
|
278
|
+
removeFlagElement() {
|
|
279
|
+
var _a;
|
|
280
|
+
if (this.flagElement && ((_a = document.body) === null || _a === void 0 ? void 0 : _a.contains(this.flagElement))) {
|
|
281
|
+
document.body.removeChild(this.flagElement);
|
|
282
|
+
this.flagElement = null;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
EnvFlag.DEFAULT_CONFIG = {
|
|
287
|
+
productionColor: '#e74c3c',
|
|
288
|
+
developmentColor: '#3498db',
|
|
289
|
+
stagingColor: '#f39c12',
|
|
290
|
+
testColor: '#9b59b6',
|
|
291
|
+
productionText: 'PROD',
|
|
292
|
+
developmentText: 'DEV',
|
|
293
|
+
stagingText: 'STAGING',
|
|
294
|
+
testText: 'TEST',
|
|
295
|
+
position: 'bottom-right',
|
|
296
|
+
size: 'medium',
|
|
297
|
+
autoDetectEnv: true,
|
|
298
|
+
enabled: true,
|
|
299
|
+
debug: false
|
|
300
|
+
};
|
|
301
|
+
EnvFlag.ELEMENT_ID = 'env-flag-indicator';
|
|
302
|
+
EnvFlag.Z_INDEX = '999999';
|
|
303
|
+
// Auto-initialization for immediate testing
|
|
304
|
+
if (typeof window !== 'undefined') {
|
|
305
|
+
const autoEnvFlag = new EnvFlag({
|
|
306
|
+
debug: true // Enable debug mode for testing
|
|
307
|
+
});
|
|
308
|
+
// Initialize when DOM is ready
|
|
309
|
+
if (document.readyState === 'loading') {
|
|
310
|
+
document.addEventListener('DOMContentLoaded', () => autoEnvFlag.init());
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
// DOM is already ready
|
|
314
|
+
autoEnvFlag.init();
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
export default EnvFlag;
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "env-flag",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"module": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"start": "tsc && node dist/index.js",
|
|
15
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"env",
|
|
19
|
+
"flag",
|
|
20
|
+
"environment",
|
|
21
|
+
"indicator",
|
|
22
|
+
"typescript",
|
|
23
|
+
"browser",
|
|
24
|
+
"badge"
|
|
25
|
+
],
|
|
26
|
+
"author": "Koray TUNCER <ktuncerr@gmail.com>",
|
|
27
|
+
"license": "ISC",
|
|
28
|
+
"description": "A lightweight, customizable environment flag indicator for browser apps. Shows DEV/PROD/STAGING status as a badge.",
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://github.com/ktuncerr/env-flag.git"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^24.0.11",
|
|
35
|
+
"typescript": "^5.8.3"
|
|
36
|
+
}
|
|
37
|
+
}
|