@codeleap/debug 5.8.9 → 5.8.10
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 +2 -2
- package/package.json.bak +1 -1
- package/src/EnvironmentManager/class.ts +139 -0
- package/src/EnvironmentManager/const.ts +4 -0
- package/src/EnvironmentManager/factor.ts +7 -0
- package/src/EnvironmentManager/index.ts +3 -0
- package/src/EnvironmentManager/tests.spec.ts +330 -0
- package/src/EnvironmentManager/types.ts +17 -0
- package/src/faker.ts +34 -0
- package/src/index.ts +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codeleap/debug",
|
|
3
|
-
"version": "5.8.
|
|
3
|
+
"version": "5.8.10",
|
|
4
4
|
"main": "src/index.ts",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"repository": {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"directory": "packages/debug"
|
|
10
10
|
},
|
|
11
11
|
"devDependencies": {
|
|
12
|
-
"@codeleap/config": "5.8.
|
|
12
|
+
"@codeleap/config": "5.8.10",
|
|
13
13
|
"ts-node-dev": "1.1.8"
|
|
14
14
|
},
|
|
15
15
|
"scripts": {
|
package/package.json.bak
CHANGED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { globalState } from '@codeleap/store'
|
|
2
|
+
import { Keyof, StringRecord, TypeGuards } from '@codeleap/types'
|
|
3
|
+
import { capitalize, deepEqual } from '@codeleap/utils'
|
|
4
|
+
import { useState, useMemo } from 'react'
|
|
5
|
+
import { EnvironmentStore, EnvironmentManagerConfig, Editor } from './types'
|
|
6
|
+
import { EDITORS } from './const'
|
|
7
|
+
|
|
8
|
+
export class EnvironmentManager<T extends StringRecord> {
|
|
9
|
+
private store: ReturnType<typeof globalState<EnvironmentStore<T>>>
|
|
10
|
+
|
|
11
|
+
private initialStoreValue: EnvironmentStore<T>
|
|
12
|
+
|
|
13
|
+
readonly editors = EDITORS
|
|
14
|
+
|
|
15
|
+
get environments() {
|
|
16
|
+
return this.config.environments
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
get defaultConfig() {
|
|
20
|
+
return {
|
|
21
|
+
environment: this.config.defaultEnvironment,
|
|
22
|
+
customUrl: '',
|
|
23
|
+
enabledBy: null,
|
|
24
|
+
} as EnvironmentStore<T>
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
constructor(private config: EnvironmentManagerConfig<T>) {
|
|
28
|
+
this.store = globalState<EnvironmentStore<T>>(
|
|
29
|
+
this.defaultConfig,
|
|
30
|
+
{ persistKey: config?.persistKey ?? 'environment-manager' }
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
this.initialStoreValue = this.store.get()
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
testUrl(url: string) {
|
|
37
|
+
const urlValidator: RegExp = /^https?:\/\/([a-zA-Z0-9.-]+|localhost|(\d{1,3}\.){3}\d{1,3})(?::\d+)?\/$/
|
|
38
|
+
return urlValidator.test(url)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
get env(): EnvironmentStore<T> {
|
|
42
|
+
const value = this.store.get() ?? this.defaultConfig
|
|
43
|
+
|
|
44
|
+
if (value.enabledBy) {
|
|
45
|
+
if (value.environment === this.config.customEnvironment && !this.testUrl(value.customUrl)) {
|
|
46
|
+
value.environment = this.defaultConfig.environment
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return value
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return this.defaultConfig
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
setEnabled(by: Editor | false = false) {
|
|
56
|
+
const disable = by === false || TypeGuards.isNil(by)
|
|
57
|
+
this.store.set({ enabledBy: disable ? null : by })
|
|
58
|
+
return !disable
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
get isEnabled(): boolean {
|
|
62
|
+
return !TypeGuards.isNil(this.isEnabledBy)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
get isEnabledBy(): Editor {
|
|
66
|
+
return this.store.get(s => s?.enabledBy)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
get isEnabledBySystem(): boolean {
|
|
70
|
+
return this.isEnabledBy === EDITORS.SYSTEM
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
get isEnabledByUser(): boolean {
|
|
74
|
+
return this.isEnabledBy === EDITORS.USER
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
get is(): Record<Capitalize<Keyof<T> extends string ? Keyof<T> : string>, boolean> {
|
|
78
|
+
const environment = this.store.get(s => s?.environment ?? this.defaultConfig.environment)
|
|
79
|
+
|
|
80
|
+
return Object.entries(this.environments).reduce((acc, [key, value]) => {
|
|
81
|
+
acc[capitalize(key) as Keyof<T>] = environment === key
|
|
82
|
+
return acc
|
|
83
|
+
}, {} as Record<Keyof<T>, boolean>)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
get serverUrl() {
|
|
87
|
+
const env = this.env
|
|
88
|
+
|
|
89
|
+
if (env.environment === this.config.customEnvironment) {
|
|
90
|
+
if (!this.testUrl(env.customUrl)) {
|
|
91
|
+
return this.environments[this.defaultConfig.environment]
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return env.customUrl
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return this.environments[env.environment] ?? this.environments[this.defaultConfig.environment]
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
setEnvironment(environment: Keyof<T>) {
|
|
101
|
+
if (!this.isEnabled) return
|
|
102
|
+
this.store.set({ environment })
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
isEnvironment(env: Keyof<T>): boolean {
|
|
106
|
+
const current = this.env
|
|
107
|
+
return current.environment === env
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
setCustomUrl(url: string) {
|
|
111
|
+
if (!url.endsWith('/')) {
|
|
112
|
+
url += '/'
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (!this.testUrl(url)) return
|
|
116
|
+
|
|
117
|
+
this.store.set({ customUrl: url })
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
use() {
|
|
121
|
+
const value = this.store.use()
|
|
122
|
+
|
|
123
|
+
const { enabledBy, ...config } = value ?? this.defaultConfig
|
|
124
|
+
|
|
125
|
+
const [customUrl, setCustomUrl] = useState(config?.customUrl)
|
|
126
|
+
|
|
127
|
+
const changed = useMemo(() => !deepEqual(value, this.initialStoreValue), [value])
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
enabled: !!enabledBy,
|
|
131
|
+
enabledByUser: enabledBy === EDITORS.USER,
|
|
132
|
+
enabledBySystem: enabledBy === EDITORS.SYSTEM,
|
|
133
|
+
config,
|
|
134
|
+
changed,
|
|
135
|
+
customUrl,
|
|
136
|
+
setCustomUrl,
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { StringRecord } from '@codeleap/types'
|
|
2
|
+
import { EnvironmentManager } from './class'
|
|
3
|
+
import { EnvironmentManagerConfig } from './types'
|
|
4
|
+
|
|
5
|
+
export function createEnvironmentManager<T extends StringRecord>(config: EnvironmentManagerConfig<T>) {
|
|
6
|
+
return new EnvironmentManager<T>(config)
|
|
7
|
+
}
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import { describe, test, expect, beforeEach } from 'bun:test'
|
|
2
|
+
import { createEnvironmentManager } from './factor'
|
|
3
|
+
import { EnvironmentManager } from './class'
|
|
4
|
+
import { EDITORS } from './const'
|
|
5
|
+
|
|
6
|
+
type TestEnvironments = {
|
|
7
|
+
development: string
|
|
8
|
+
staging: string
|
|
9
|
+
production: string
|
|
10
|
+
custom: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
describe('EnvironmentManager', () => {
|
|
14
|
+
let manager: EnvironmentManager<TestEnvironments>
|
|
15
|
+
|
|
16
|
+
const envs = {
|
|
17
|
+
development: 'http://localhost:3000/',
|
|
18
|
+
staging: 'https://staging.example.com/',
|
|
19
|
+
production: 'https://api.example.com/',
|
|
20
|
+
custom: '',
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const testConfig = {
|
|
24
|
+
environments: envs,
|
|
25
|
+
defaultEnvironment: 'development' as const,
|
|
26
|
+
customEnvironment: 'custom' as const,
|
|
27
|
+
persistKey: 'test-env-manager',
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
beforeEach(() => {
|
|
31
|
+
manager = createEnvironmentManager<TestEnvironments>(testConfig)
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
describe('Initialization', () => {
|
|
35
|
+
test('should create instance with correct config', () => {
|
|
36
|
+
expect(manager).toBeInstanceOf(EnvironmentManager)
|
|
37
|
+
expect(manager.environments).toEqual(testConfig.environments)
|
|
38
|
+
expect(manager.editors).toEqual(EDITORS)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
test('should have correct default config', () => {
|
|
42
|
+
expect(manager.defaultConfig).toEqual({
|
|
43
|
+
environment: 'development',
|
|
44
|
+
customUrl: '',
|
|
45
|
+
enabledBy: null,
|
|
46
|
+
})
|
|
47
|
+
})
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
describe('URL Validation', () => {
|
|
51
|
+
test('should validate correct HTTP URLs', () => {
|
|
52
|
+
expect(manager.testUrl(envs.development)).toBe(true)
|
|
53
|
+
expect(manager.testUrl('http://example.com/')).toBe(true)
|
|
54
|
+
expect(manager.testUrl('http://192.168.1.1:8080/')).toBe(true)
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
test('should validate correct HTTPS URLs', () => {
|
|
58
|
+
expect(manager.testUrl('https://example.com/')).toBe(true)
|
|
59
|
+
expect(manager.testUrl(envs.production)).toBe(true)
|
|
60
|
+
expect(manager.testUrl('https://sub.domain.example.com:443/')).toBe(true)
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
test('should reject invalid URLs', () => {
|
|
64
|
+
expect(manager.testUrl('ftp://example.com/')).toBe(false)
|
|
65
|
+
expect(manager.testUrl('http://example.com')).toBe(false)
|
|
66
|
+
expect(manager.testUrl('example.com/')).toBe(false)
|
|
67
|
+
expect(manager.testUrl('http:/example.com/')).toBe(false)
|
|
68
|
+
expect(manager.testUrl('')).toBe(false)
|
|
69
|
+
})
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
describe('Enable/Disable functionality', () => {
|
|
73
|
+
test('should start disabled by default', () => {
|
|
74
|
+
expect(manager.isEnabled).toBe(false)
|
|
75
|
+
expect(manager.isEnabledBy).toBeNull()
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
test('should enable by user', () => {
|
|
79
|
+
const result = manager.setEnabled(EDITORS.USER)
|
|
80
|
+
expect(result).toBe(true)
|
|
81
|
+
expect(manager.isEnabled).toBe(true)
|
|
82
|
+
expect(manager.isEnabledByUser).toBe(true)
|
|
83
|
+
expect(manager.isEnabledBySystem).toBe(false)
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
test('should enable by system', () => {
|
|
87
|
+
manager.setEnabled(EDITORS.SYSTEM)
|
|
88
|
+
expect(manager.isEnabled).toBe(true)
|
|
89
|
+
expect(manager.isEnabledBySystem).toBe(true)
|
|
90
|
+
expect(manager.isEnabledByUser).toBe(false)
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
test('should disable when setting null', () => {
|
|
94
|
+
manager.setEnabled(EDITORS.USER)
|
|
95
|
+
expect(manager.isEnabled).toBe(true)
|
|
96
|
+
|
|
97
|
+
const result = manager.setEnabled(false)
|
|
98
|
+
expect(result).toBe(false)
|
|
99
|
+
expect(manager.isEnabled).toBe(false)
|
|
100
|
+
})
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
describe('Environment management', () => {
|
|
104
|
+
beforeEach(() => {
|
|
105
|
+
manager.setEnabled(EDITORS.USER)
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
test('should return default environment when disabled', () => {
|
|
109
|
+
manager.setEnabled(false)
|
|
110
|
+
const env = manager.env
|
|
111
|
+
expect(env.environment).toBe('development')
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
test('should set environment when enabled', () => {
|
|
115
|
+
manager.setEnvironment('staging')
|
|
116
|
+
const env = manager.env
|
|
117
|
+
expect(env.environment).toBe('staging')
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
test('should not set environment when disabled', () => {
|
|
121
|
+
manager.setEnabled(false)
|
|
122
|
+
manager.setEnvironment('production')
|
|
123
|
+
expect(manager.isEnvironment('development')).toBe(true)
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
test('should check current environment correctly', () => {
|
|
127
|
+
manager.setEnvironment('production')
|
|
128
|
+
expect(manager.isEnvironment('production')).toBe(true)
|
|
129
|
+
expect(manager.isEnvironment('staging')).toBe(false)
|
|
130
|
+
})
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
describe('Environment checker (is)', () => {
|
|
134
|
+
beforeEach(() => {
|
|
135
|
+
manager.setEnabled(EDITORS.USER)
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
test('should have correct environment flags for development', () => {
|
|
139
|
+
manager.setEnvironment('development')
|
|
140
|
+
expect(manager.is.Development).toBe(true)
|
|
141
|
+
expect(manager.is.Staging).toBe(false)
|
|
142
|
+
expect(manager.is.Production).toBe(false)
|
|
143
|
+
})
|
|
144
|
+
|
|
145
|
+
test('should have correct environment flags for production', () => {
|
|
146
|
+
manager.setEnvironment('production')
|
|
147
|
+
expect(manager.is.Production).toBe(true)
|
|
148
|
+
expect(manager.is.Development).toBe(false)
|
|
149
|
+
expect(manager.is.Staging).toBe(false)
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
test('should have correct environment flags for staging', () => {
|
|
153
|
+
manager.setEnvironment('staging')
|
|
154
|
+
expect(manager.is.Staging).toBe(true)
|
|
155
|
+
expect(manager.is.Development).toBe(false)
|
|
156
|
+
expect(manager.is.Production).toBe(false)
|
|
157
|
+
})
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
describe('Server URL', () => {
|
|
161
|
+
beforeEach(() => {
|
|
162
|
+
manager.setEnabled(EDITORS.USER)
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
test('should return correct URL for each environment', () => {
|
|
166
|
+
manager.setEnvironment('development')
|
|
167
|
+
expect(manager.serverUrl).toBe(envs.development)
|
|
168
|
+
|
|
169
|
+
manager.setEnvironment('staging')
|
|
170
|
+
expect(manager.serverUrl).toBe(envs.staging)
|
|
171
|
+
|
|
172
|
+
manager.setEnvironment('production')
|
|
173
|
+
expect(manager.serverUrl).toBe(envs.production)
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
test('should return default URL when disabled', () => {
|
|
177
|
+
manager.setEnabled(false)
|
|
178
|
+
expect(manager.serverUrl).toBe(envs.development)
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
test('should return custom URL when set and valid', () => {
|
|
182
|
+
manager.setCustomUrl('https://custom.example.com/')
|
|
183
|
+
manager.setEnvironment('custom')
|
|
184
|
+
expect(manager.serverUrl).toBe('https://custom.example.com/')
|
|
185
|
+
})
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
describe('Custom URL', () => {
|
|
189
|
+
beforeEach(() => {
|
|
190
|
+
manager.setEnabled(EDITORS.USER)
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
test('should set valid custom URL', () => {
|
|
194
|
+
manager.setCustomUrl('https://custom.example.com/')
|
|
195
|
+
manager.setEnvironment('custom')
|
|
196
|
+
expect(manager.serverUrl).toBe('https://custom.example.com/')
|
|
197
|
+
})
|
|
198
|
+
|
|
199
|
+
test('should add trailing slash if missing', () => {
|
|
200
|
+
manager.setCustomUrl('https://custom.example.com')
|
|
201
|
+
manager.setEnvironment('custom')
|
|
202
|
+
expect(manager.serverUrl).toBe('https://custom.example.com/')
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
test('should not set invalid custom URL', () => {
|
|
206
|
+
const initialUrl = manager.env.customUrl
|
|
207
|
+
manager.setCustomUrl('invalid-url')
|
|
208
|
+
expect(manager.env.customUrl).toBe(initialUrl)
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
test('should handle localhost custom URLs', () => {
|
|
212
|
+
manager.setCustomUrl('http://localhost:4000/')
|
|
213
|
+
manager.setEnvironment('custom')
|
|
214
|
+
expect(manager.serverUrl).toBe('http://localhost:4000/')
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
test('should handle IP address custom URLs', () => {
|
|
218
|
+
manager.setCustomUrl('http://192.168.1.100:8080/')
|
|
219
|
+
manager.setEnvironment('custom')
|
|
220
|
+
expect(manager.serverUrl).toBe('http://192.168.1.100:8080/')
|
|
221
|
+
})
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
describe('Factory function', () => {
|
|
225
|
+
test('should create manager instance', () => {
|
|
226
|
+
const newManager = createEnvironmentManager<TestEnvironments>(testConfig)
|
|
227
|
+
expect(newManager).toBeInstanceOf(EnvironmentManager)
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
test('should create independent instances', () => {
|
|
231
|
+
const manager1 = createEnvironmentManager<TestEnvironments>({
|
|
232
|
+
...testConfig,
|
|
233
|
+
persistKey: 'manager-1',
|
|
234
|
+
})
|
|
235
|
+
const manager2 = createEnvironmentManager<TestEnvironments>({
|
|
236
|
+
...testConfig,
|
|
237
|
+
persistKey: 'manager-2',
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
manager1.setEnabled(EDITORS.USER)
|
|
241
|
+
manager1.setEnvironment('production')
|
|
242
|
+
|
|
243
|
+
manager2.setEnabled(EDITORS.SYSTEM)
|
|
244
|
+
manager2.setEnvironment('staging')
|
|
245
|
+
|
|
246
|
+
expect(manager1.isEnabledByUser).toBe(true)
|
|
247
|
+
expect(manager2.isEnabledBySystem).toBe(true)
|
|
248
|
+
})
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
describe('EDITORS constant', () => {
|
|
252
|
+
test('should have correct editor values', () => {
|
|
253
|
+
expect(EDITORS.SYSTEM).toBe('system')
|
|
254
|
+
expect(EDITORS.USER).toBe('user')
|
|
255
|
+
})
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
describe('Edge cases', () => {
|
|
259
|
+
test('should handle repeated setEnvironment calls', () => {
|
|
260
|
+
manager.setEnabled(EDITORS.USER)
|
|
261
|
+
manager.setEnvironment('development')
|
|
262
|
+
manager.setEnvironment('staging')
|
|
263
|
+
manager.setEnvironment('production')
|
|
264
|
+
|
|
265
|
+
expect(manager.isEnvironment('production')).toBe(true)
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
test('should handle empty custom URL', () => {
|
|
269
|
+
manager.setEnabled(EDITORS.USER)
|
|
270
|
+
manager.setCustomUrl('')
|
|
271
|
+
expect(manager.testUrl('')).toBe(false)
|
|
272
|
+
})
|
|
273
|
+
|
|
274
|
+
test('should handle switching between enabled states', () => {
|
|
275
|
+
manager.setEnabled(EDITORS.USER)
|
|
276
|
+
expect(manager.isEnabledByUser).toBe(true)
|
|
277
|
+
|
|
278
|
+
manager.setEnabled(EDITORS.SYSTEM)
|
|
279
|
+
expect(manager.isEnabledBySystem).toBe(true)
|
|
280
|
+
expect(manager.isEnabledByUser).toBe(false)
|
|
281
|
+
})
|
|
282
|
+
|
|
283
|
+
test('should handle multiple custom URL changes', () => {
|
|
284
|
+
manager.setEnabled(EDITORS.USER)
|
|
285
|
+
|
|
286
|
+
manager.setCustomUrl('https://custom1.example.com/')
|
|
287
|
+
manager.setEnvironment('custom')
|
|
288
|
+
expect(manager.serverUrl).toBe('https://custom1.example.com/')
|
|
289
|
+
|
|
290
|
+
manager.setCustomUrl('https://custom2.example.com/')
|
|
291
|
+
expect(manager.serverUrl).toBe('https://custom2.example.com/')
|
|
292
|
+
})
|
|
293
|
+
})
|
|
294
|
+
|
|
295
|
+
describe('Integration tests', () => {
|
|
296
|
+
test('should handle full workflow: enable, set env, get URL', () => {
|
|
297
|
+
manager.setEnabled(null)
|
|
298
|
+
expect(manager.isEnabled).toBe(false)
|
|
299
|
+
|
|
300
|
+
manager.setEnabled(EDITORS.USER)
|
|
301
|
+
expect(manager.isEnabled).toBe(true)
|
|
302
|
+
|
|
303
|
+
manager.setEnvironment('production')
|
|
304
|
+
expect(manager.isEnvironment('production')).toBe(true)
|
|
305
|
+
|
|
306
|
+
expect(manager.serverUrl).toBe(envs.production)
|
|
307
|
+
})
|
|
308
|
+
|
|
309
|
+
test('should handle custom URL workflow', () => {
|
|
310
|
+
manager.setEnabled(EDITORS.USER)
|
|
311
|
+
|
|
312
|
+
manager.setCustomUrl('https://my-api.example.com/')
|
|
313
|
+
expect(manager.testUrl('https://my-api.example.com/')).toBe(true)
|
|
314
|
+
|
|
315
|
+
manager.setEnvironment('custom')
|
|
316
|
+
expect(manager.isEnvironment('custom')).toBe(true)
|
|
317
|
+
expect(manager.serverUrl).toBe('https://my-api.example.com/')
|
|
318
|
+
})
|
|
319
|
+
|
|
320
|
+
test('should fallback correctly on invalid custom URL', () => {
|
|
321
|
+
manager.setEnabled(EDITORS.USER)
|
|
322
|
+
|
|
323
|
+
manager.setEnvironment('custom')
|
|
324
|
+
manager.setCustomUrl('https://my-api.example.com/')
|
|
325
|
+
manager.setCustomUrl('not-a-valid-url')
|
|
326
|
+
|
|
327
|
+
expect(manager.serverUrl).toBe('https://my-api.example.com/')
|
|
328
|
+
})
|
|
329
|
+
})
|
|
330
|
+
})
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Keyof, StringRecord, ValueOf } from '@codeleap/types'
|
|
2
|
+
import { EDITORS } from './const'
|
|
3
|
+
|
|
4
|
+
export type Editor = ValueOf<typeof EDITORS> | null
|
|
5
|
+
|
|
6
|
+
export type EnvironmentManagerConfig<T extends StringRecord> = {
|
|
7
|
+
environments: T
|
|
8
|
+
defaultEnvironment: Keyof<T>
|
|
9
|
+
customEnvironment: Keyof<T>
|
|
10
|
+
persistKey?: string
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type EnvironmentStore<T extends StringRecord> = {
|
|
14
|
+
environment: Keyof<T>
|
|
15
|
+
customUrl?: string
|
|
16
|
+
enabledBy: Editor
|
|
17
|
+
}
|
package/src/faker.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const names = [
|
|
2
|
+
'James', 'John', 'Robert', 'Michael', 'William', 'David', 'Richard', 'Joseph', 'Thomas',
|
|
3
|
+
'Charles', 'Christopher', 'Daniel', 'Matthew', 'Anthony', 'Donald', 'Mark', 'Paul', 'Steven',
|
|
4
|
+
'Andrew', 'Kenneth', 'Joshua', 'Kevin', 'Brian', 'George', 'Edward', 'Ronald', 'Timothy',
|
|
5
|
+
'Jason', 'Jeffrey', 'Ryan', 'Gary', 'Jacob'
|
|
6
|
+
]
|
|
7
|
+
|
|
8
|
+
const surnames = [
|
|
9
|
+
'Smith', 'Johnson', 'Williams', 'Brown', 'Jones', 'Garcia', 'Miller', 'Davis',
|
|
10
|
+
'Lopez', 'Wilson', 'Anderson', 'Thomas', 'Taylor', 'Moore',
|
|
11
|
+
'Jackson', 'Martin', 'Lee', 'Perez', 'Thompson', 'White', 'Harris', 'Sanchez', 'Clark',
|
|
12
|
+
'Ramirez', 'Lewis', 'Robinson', 'Walker', 'Young', 'Allen', 'King', 'Wright', 'Scott', 'Torres',
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
const animals = [
|
|
16
|
+
'lion', 'tiger', 'zebra', 'panda', 'koala', 'bear',
|
|
17
|
+
'wolf', 'fox', 'rabbit', 'bat', 'spider', 'frog', 'shark'
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
function getRandom(list: Array<string>) {
|
|
21
|
+
return list[Math.floor(Math.random() * list.length)]
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function number(min: number = 0, max: number = 100) {
|
|
25
|
+
return Math.floor(Math.random() * (max - min + 1)) + min
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const faker = {
|
|
29
|
+
lastName: () => getRandom(surnames),
|
|
30
|
+
firstName: () => getRandom(names),
|
|
31
|
+
animal: () => getRandom(animals),
|
|
32
|
+
number,
|
|
33
|
+
name: () => `${getRandom(names)} ${getRandom(surnames)}`
|
|
34
|
+
}
|
package/src/index.ts
CHANGED