env-flag 1.0.0 → 1.0.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/package.json CHANGED
@@ -1,37 +1,38 @@
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
- }
1
+ {
2
+ "name": "env-flag",
3
+ "version": "1.0.2",
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/koraytuncer/env-flag.git"
32
+ },
33
+ "homepage": "https://github.com/koraytuncer/env-flag",
34
+ "devDependencies": {
35
+ "@types/node": "^24.0.11",
36
+ "typescript": "^5.8.3"
37
+ }
38
+ }
package/dist/index.d.ts DELETED
@@ -1,66 +0,0 @@
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 DELETED
@@ -1,317 +0,0 @@
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;