@volley/vwr-loader 1.0.6 → 1.2.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 +7 -8
- package/dist/__mocks__/@datadog/browser-logs.d.ts +58 -0
- package/dist/__mocks__/@datadog/browser-logs.d.ts.map +1 -0
- package/dist/__mocks__/@datadog/browser-logs.js +34 -0
- package/dist/__mocks__/@datadog/browser-logs.js.map +1 -0
- package/dist/__mocks__/@datadog/browser-rum.d.ts +25 -0
- package/dist/__mocks__/@datadog/browser-rum.d.ts.map +1 -0
- package/dist/__mocks__/@datadog/browser-rum.js +25 -0
- package/dist/__mocks__/@datadog/browser-rum.js.map +1 -0
- package/dist/amplitudeFlagFetcher.d.ts +8 -3
- package/dist/amplitudeFlagFetcher.d.ts.map +1 -1
- package/dist/amplitudeFlagFetcher.js +14 -12
- package/dist/amplitudeFlagFetcher.js.map +1 -1
- package/dist/assets/profiler-BRmTNL9s.js +2 -0
- package/dist/assets/profiler-BRmTNL9s.js.map +1 -0
- package/dist/assets/startRecording-CuFdVhxx.js +3 -0
- package/dist/assets/startRecording-CuFdVhxx.js.map +1 -0
- package/dist/cli.js +47 -34
- package/dist/cli.js.map +1 -1
- package/dist/datadog.d.ts +19 -0
- package/dist/datadog.d.ts.map +1 -0
- package/dist/datadog.js +39 -0
- package/dist/datadog.js.map +1 -0
- package/dist/envDefaults.d.ts.map +1 -1
- package/dist/envDefaults.js +27 -12
- package/dist/envDefaults.js.map +1 -1
- package/dist/errors/InitializationError.d.ts +74 -0
- package/dist/errors/InitializationError.d.ts.map +1 -0
- package/dist/errors/InitializationError.js +77 -0
- package/dist/errors/InitializationError.js.map +1 -0
- package/dist/errors/ensureError.d.ts +2 -0
- package/dist/errors/ensureError.d.ts.map +1 -0
- package/dist/errors/ensureError.js +7 -0
- package/dist/errors/ensureError.js.map +1 -0
- package/dist/errors/index.d.ts +12 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +10 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/getDeviceId.d.ts +1 -32
- package/dist/getDeviceId.d.ts.map +1 -1
- package/dist/getDeviceId.js +18 -16
- package/dist/getDeviceId.js.map +1 -1
- package/dist/getEnvironment.d.ts +3 -4
- package/dist/getEnvironment.d.ts.map +1 -1
- package/dist/getEnvironment.js +11 -6
- package/dist/getEnvironment.js.map +1 -1
- package/dist/getShellVersion.d.ts +2 -20
- package/dist/getShellVersion.d.ts.map +1 -1
- package/dist/getShellVersion.js +41 -8
- package/dist/getShellVersion.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/loadVwr.d.ts +4 -4
- package/dist/loadVwr.d.ts.map +1 -1
- package/dist/loadVwr.js +151 -37
- package/dist/loadVwr.js.map +1 -1
- package/dist/logger.d.ts +11 -6
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +107 -4
- package/dist/logger.js.map +1 -1
- package/dist/main.js +9 -1
- package/dist/main.js.map +1 -1
- package/dist/test-setup.d.ts +2 -0
- package/dist/test-setup.d.ts.map +1 -0
- package/dist/test-setup.js +5 -0
- package/dist/test-setup.js.map +1 -0
- package/dist/types.d.ts +87 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/vwrConfig.d.ts +14 -2
- package/dist/vwrConfig.d.ts.map +1 -1
- package/dist/vwrConfig.js +74 -29
- package/dist/vwrConfig.js.map +1 -1
- package/package.json +59 -53
- package/src/__mocks__/@datadog/browser-logs.ts +35 -0
- package/src/__mocks__/@datadog/browser-rum.ts +27 -0
- package/src/amplitudeFlagFetcher.test.ts +28 -34
- package/src/amplitudeFlagFetcher.ts +22 -14
- package/src/datadog.ts +55 -0
- package/src/envDefaults.ts +32 -13
- package/src/errors/InitializationError.ts +105 -0
- package/src/errors/ensureError.ts +6 -0
- package/src/errors/index.ts +16 -0
- package/src/getDeviceId.test.ts +29 -23
- package/src/getDeviceId.ts +25 -72
- package/src/getEnvironment.test.ts +68 -108
- package/src/getEnvironment.ts +12 -8
- package/src/getShellVersion.test.ts +134 -9
- package/src/getShellVersion.ts +44 -26
- package/src/index.ts +0 -1
- package/src/loadVwr.test.ts +394 -0
- package/src/loadVwr.ts +243 -58
- package/src/logger.ts +118 -11
- package/src/main.test.ts +157 -0
- package/src/main.ts +79 -11
- package/src/test-setup.ts +5 -0
- package/src/types.ts +88 -0
- package/src/vite-env.d.ts +2 -0
- package/src/vwrConfig.test.ts +104 -34
- package/src/vwrConfig.ts +115 -37
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"
|
|
2
2
|
|
|
3
3
|
import { type Environment, getEnvironment } from "./getEnvironment"
|
|
4
|
+
import { logger } from "./logger"
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
vi.mock("./logger", () => ({
|
|
7
|
+
logger: {
|
|
7
8
|
info: vi.fn(),
|
|
8
9
|
warn: vi.fn(),
|
|
9
10
|
error: vi.fn(),
|
|
10
|
-
|
|
11
|
+
debug: vi.fn(),
|
|
12
|
+
child: vi.fn(),
|
|
13
|
+
},
|
|
14
|
+
}))
|
|
11
15
|
|
|
16
|
+
describe("getEnvironment", () => {
|
|
12
17
|
beforeEach(() => {
|
|
13
18
|
vi.clearAllMocks()
|
|
14
|
-
mockLogger.info.mockClear()
|
|
15
|
-
mockLogger.warn.mockClear()
|
|
16
|
-
mockLogger.error.mockClear()
|
|
17
19
|
// Clean up window properties
|
|
18
20
|
delete (window as any).Capacitor
|
|
19
21
|
})
|
|
@@ -42,15 +44,11 @@ describe("getEnvironment", () => {
|
|
|
42
44
|
configurable: true,
|
|
43
45
|
})
|
|
44
46
|
|
|
45
|
-
const result = await getEnvironment(
|
|
46
|
-
"FIRE_TV",
|
|
47
|
-
undefined,
|
|
48
|
-
mockLogger
|
|
49
|
-
)
|
|
47
|
+
const result = await getEnvironment("FIRE_TV", undefined)
|
|
50
48
|
|
|
51
49
|
expect(result.environment).toBe("dev")
|
|
52
50
|
expect(result.source).toBe("native")
|
|
53
|
-
expect(
|
|
51
|
+
expect(logger.info).toHaveBeenCalledWith(
|
|
54
52
|
expect.stringContaining(
|
|
55
53
|
'Environment: "dev" (source: native BuildConfig.ENVIRONMENT="development")'
|
|
56
54
|
)
|
|
@@ -74,11 +72,7 @@ describe("getEnvironment", () => {
|
|
|
74
72
|
configurable: true,
|
|
75
73
|
})
|
|
76
74
|
|
|
77
|
-
const result = await getEnvironment(
|
|
78
|
-
"FIRE_TV",
|
|
79
|
-
undefined,
|
|
80
|
-
mockLogger
|
|
81
|
-
)
|
|
75
|
+
const result = await getEnvironment("FIRE_TV", undefined)
|
|
82
76
|
|
|
83
77
|
expect(result.environment).toBe("prod")
|
|
84
78
|
expect(result.source).toBe("native")
|
|
@@ -101,11 +95,30 @@ describe("getEnvironment", () => {
|
|
|
101
95
|
configurable: true,
|
|
102
96
|
})
|
|
103
97
|
|
|
104
|
-
const result = await getEnvironment(
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
98
|
+
const result = await getEnvironment("FIRE_TV", undefined)
|
|
99
|
+
|
|
100
|
+
expect(result.environment).toBe("staging")
|
|
101
|
+
expect(result.source).toBe("native")
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
it("should map legacy 'qa' to 'staging'", async () => {
|
|
105
|
+
Object.defineProperty(window, "Capacitor", {
|
|
106
|
+
value: {
|
|
107
|
+
Plugins: {
|
|
108
|
+
DeviceInfo: {
|
|
109
|
+
getNativeShellAppEnvironment: vi
|
|
110
|
+
.fn()
|
|
111
|
+
.mockResolvedValue({
|
|
112
|
+
environment: "qa",
|
|
113
|
+
}),
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
writable: true,
|
|
118
|
+
configurable: true,
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
const result = await getEnvironment("FIRE_TV", undefined)
|
|
109
122
|
|
|
110
123
|
expect(result.environment).toBe("staging")
|
|
111
124
|
expect(result.source).toBe("native")
|
|
@@ -128,11 +141,7 @@ describe("getEnvironment", () => {
|
|
|
128
141
|
configurable: true,
|
|
129
142
|
})
|
|
130
143
|
|
|
131
|
-
const result = await getEnvironment(
|
|
132
|
-
"FIRE_TV",
|
|
133
|
-
undefined,
|
|
134
|
-
mockLogger
|
|
135
|
-
)
|
|
144
|
+
const result = await getEnvironment("FIRE_TV", undefined)
|
|
136
145
|
|
|
137
146
|
expect(result.environment).toBe("dev")
|
|
138
147
|
expect(result.source).toBe("native")
|
|
@@ -155,11 +164,7 @@ describe("getEnvironment", () => {
|
|
|
155
164
|
configurable: true,
|
|
156
165
|
})
|
|
157
166
|
|
|
158
|
-
const result = await getEnvironment(
|
|
159
|
-
"FIRE_TV",
|
|
160
|
-
undefined,
|
|
161
|
-
mockLogger
|
|
162
|
-
)
|
|
167
|
+
const result = await getEnvironment("FIRE_TV", undefined)
|
|
163
168
|
|
|
164
169
|
expect(result.environment).toBe("dev")
|
|
165
170
|
expect(result.source).toBe("native")
|
|
@@ -167,15 +172,11 @@ describe("getEnvironment", () => {
|
|
|
167
172
|
|
|
168
173
|
it("should fallback to build-time when native plugin unavailable", async () => {
|
|
169
174
|
// No Capacitor plugin available
|
|
170
|
-
const result = await getEnvironment(
|
|
171
|
-
"FIRE_TV",
|
|
172
|
-
"staging",
|
|
173
|
-
mockLogger
|
|
174
|
-
)
|
|
175
|
+
const result = await getEnvironment("FIRE_TV", "staging")
|
|
175
176
|
|
|
176
177
|
expect(result.environment).toBe("staging")
|
|
177
178
|
expect(result.source).toBe("build-time")
|
|
178
|
-
expect(
|
|
179
|
+
expect(logger.warn).toHaveBeenCalledWith(
|
|
179
180
|
expect.stringContaining(
|
|
180
181
|
"Failed to read environment from native, falling back to build-time"
|
|
181
182
|
)
|
|
@@ -199,12 +200,12 @@ describe("getEnvironment", () => {
|
|
|
199
200
|
configurable: true,
|
|
200
201
|
})
|
|
201
202
|
|
|
202
|
-
const result = await getEnvironment("FIRE_TV", "prod"
|
|
203
|
+
const result = await getEnvironment("FIRE_TV", "prod")
|
|
203
204
|
|
|
204
205
|
expect(result.environment).toBe("prod")
|
|
205
206
|
expect(result.source).toBe("build-time")
|
|
206
|
-
expect(
|
|
207
|
-
expect(
|
|
207
|
+
expect(logger.error).toHaveBeenCalled()
|
|
208
|
+
expect(logger.warn).toHaveBeenCalledWith(
|
|
208
209
|
expect.stringContaining("falling back to build-time")
|
|
209
210
|
)
|
|
210
211
|
})
|
|
@@ -226,11 +227,11 @@ describe("getEnvironment", () => {
|
|
|
226
227
|
configurable: true,
|
|
227
228
|
})
|
|
228
229
|
|
|
229
|
-
const result = await getEnvironment("FIRE_TV", "dev"
|
|
230
|
+
const result = await getEnvironment("FIRE_TV", "dev")
|
|
230
231
|
|
|
231
232
|
expect(result.environment).toBe("dev")
|
|
232
233
|
expect(result.source).toBe("build-time")
|
|
233
|
-
expect(
|
|
234
|
+
expect(logger.error).toHaveBeenCalledWith(
|
|
234
235
|
expect.stringContaining(
|
|
235
236
|
"DeviceInfo.getNativeShellAppEnvironment returned empty"
|
|
236
237
|
)
|
|
@@ -239,15 +240,11 @@ describe("getEnvironment", () => {
|
|
|
239
240
|
|
|
240
241
|
it("should fallback to default when both native and build-time fail", async () => {
|
|
241
242
|
// No Capacitor plugin, no build-time env
|
|
242
|
-
const result = await getEnvironment(
|
|
243
|
-
"FIRE_TV",
|
|
244
|
-
undefined,
|
|
245
|
-
mockLogger
|
|
246
|
-
)
|
|
243
|
+
const result = await getEnvironment("FIRE_TV", undefined)
|
|
247
244
|
|
|
248
245
|
expect(result.environment).toBe("dev")
|
|
249
246
|
expect(result.source).toBe("default")
|
|
250
|
-
expect(
|
|
247
|
+
expect(logger.warn).toHaveBeenCalledWith(
|
|
251
248
|
expect.stringContaining(
|
|
252
249
|
'Environment: "dev" (source: default fallback'
|
|
253
250
|
)
|
|
@@ -271,16 +268,8 @@ describe("getEnvironment", () => {
|
|
|
271
268
|
configurable: true,
|
|
272
269
|
})
|
|
273
270
|
|
|
274
|
-
const result1 = await getEnvironment(
|
|
275
|
-
|
|
276
|
-
undefined,
|
|
277
|
-
mockLogger
|
|
278
|
-
)
|
|
279
|
-
const result2 = await getEnvironment(
|
|
280
|
-
"FIRE_TV",
|
|
281
|
-
undefined,
|
|
282
|
-
mockLogger
|
|
283
|
-
)
|
|
271
|
+
const result1 = await getEnvironment("fire_tv", undefined)
|
|
272
|
+
const result2 = await getEnvironment("FIRE_TV", undefined)
|
|
284
273
|
|
|
285
274
|
expect(result1.environment).toBe("prod")
|
|
286
275
|
expect(result2.environment).toBe("prod")
|
|
@@ -293,15 +282,11 @@ describe("getEnvironment", () => {
|
|
|
293
282
|
platforms.forEach((platform) => {
|
|
294
283
|
describe(`${platform}`, () => {
|
|
295
284
|
it("should use build-time environment when provided", async () => {
|
|
296
|
-
const result = await getEnvironment(
|
|
297
|
-
platform,
|
|
298
|
-
"staging",
|
|
299
|
-
mockLogger
|
|
300
|
-
)
|
|
285
|
+
const result = await getEnvironment(platform, "staging")
|
|
301
286
|
|
|
302
287
|
expect(result.environment).toBe("staging")
|
|
303
288
|
expect(result.source).toBe("build-time")
|
|
304
|
-
expect(
|
|
289
|
+
expect(logger.info).toHaveBeenCalledWith(
|
|
305
290
|
expect.stringContaining(
|
|
306
291
|
'Environment: "staging" (source: build-time CLI injection)'
|
|
307
292
|
)
|
|
@@ -309,48 +294,32 @@ describe("getEnvironment", () => {
|
|
|
309
294
|
})
|
|
310
295
|
|
|
311
296
|
it("should use build-time 'prod' environment", async () => {
|
|
312
|
-
const result = await getEnvironment(
|
|
313
|
-
platform,
|
|
314
|
-
"prod",
|
|
315
|
-
mockLogger
|
|
316
|
-
)
|
|
297
|
+
const result = await getEnvironment(platform, "prod")
|
|
317
298
|
|
|
318
299
|
expect(result.environment).toBe("prod")
|
|
319
300
|
expect(result.source).toBe("build-time")
|
|
320
301
|
})
|
|
321
302
|
|
|
322
303
|
it("should use build-time 'dev' environment", async () => {
|
|
323
|
-
const result = await getEnvironment(
|
|
324
|
-
platform,
|
|
325
|
-
"dev",
|
|
326
|
-
mockLogger
|
|
327
|
-
)
|
|
304
|
+
const result = await getEnvironment(platform, "dev")
|
|
328
305
|
|
|
329
306
|
expect(result.environment).toBe("dev")
|
|
330
307
|
expect(result.source).toBe("build-time")
|
|
331
308
|
})
|
|
332
309
|
|
|
333
310
|
it("should use build-time 'local' environment", async () => {
|
|
334
|
-
const result = await getEnvironment(
|
|
335
|
-
platform,
|
|
336
|
-
"local",
|
|
337
|
-
mockLogger
|
|
338
|
-
)
|
|
311
|
+
const result = await getEnvironment(platform, "local")
|
|
339
312
|
|
|
340
313
|
expect(result.environment).toBe("local")
|
|
341
314
|
expect(result.source).toBe("build-time")
|
|
342
315
|
})
|
|
343
316
|
|
|
344
317
|
it("should fallback to default when build-time not provided", async () => {
|
|
345
|
-
const result = await getEnvironment(
|
|
346
|
-
platform,
|
|
347
|
-
undefined,
|
|
348
|
-
mockLogger
|
|
349
|
-
)
|
|
318
|
+
const result = await getEnvironment(platform, undefined)
|
|
350
319
|
|
|
351
320
|
expect(result.environment).toBe("dev")
|
|
352
321
|
expect(result.source).toBe("default")
|
|
353
|
-
expect(
|
|
322
|
+
expect(logger.warn).toHaveBeenCalledWith(
|
|
354
323
|
expect.stringContaining(
|
|
355
324
|
'Environment: "dev" (source: default fallback'
|
|
356
325
|
)
|
|
@@ -358,11 +327,7 @@ describe("getEnvironment", () => {
|
|
|
358
327
|
})
|
|
359
328
|
|
|
360
329
|
it("should fallback to default when build-time is invalid", async () => {
|
|
361
|
-
const result = await getEnvironment(
|
|
362
|
-
platform,
|
|
363
|
-
"invalid-env",
|
|
364
|
-
mockLogger
|
|
365
|
-
)
|
|
330
|
+
const result = await getEnvironment(platform, "invalid-env")
|
|
366
331
|
|
|
367
332
|
expect(result.environment).toBe("dev")
|
|
368
333
|
expect(result.source).toBe("default")
|
|
@@ -373,16 +338,10 @@ describe("getEnvironment", () => {
|
|
|
373
338
|
|
|
374
339
|
describe("Environment Validation", () => {
|
|
375
340
|
it("should accept valid environments", async () => {
|
|
376
|
-
const validEnvs: Environment[] = [
|
|
377
|
-
"local",
|
|
378
|
-
"dev",
|
|
379
|
-
"qa",
|
|
380
|
-
"staging",
|
|
381
|
-
"prod",
|
|
382
|
-
]
|
|
341
|
+
const validEnvs: Environment[] = ["local", "dev", "staging", "prod"]
|
|
383
342
|
|
|
384
343
|
for (const env of validEnvs) {
|
|
385
|
-
const result = await getEnvironment("WEB", env
|
|
344
|
+
const result = await getEnvironment("WEB", env)
|
|
386
345
|
expect(result.environment).toBe(env)
|
|
387
346
|
expect(result.source).toBe("build-time")
|
|
388
347
|
}
|
|
@@ -392,13 +351,14 @@ describe("getEnvironment", () => {
|
|
|
392
351
|
const invalidEnvs = [
|
|
393
352
|
"development",
|
|
394
353
|
"production",
|
|
354
|
+
"qa",
|
|
395
355
|
"test",
|
|
396
356
|
"",
|
|
397
357
|
"random",
|
|
398
358
|
]
|
|
399
359
|
|
|
400
360
|
for (const env of invalidEnvs) {
|
|
401
|
-
const result = await getEnvironment("WEB", env
|
|
361
|
+
const result = await getEnvironment("WEB", env)
|
|
402
362
|
expect(result.environment).toBe("dev")
|
|
403
363
|
expect(result.source).toBe("default")
|
|
404
364
|
}
|
|
@@ -423,33 +383,33 @@ describe("getEnvironment", () => {
|
|
|
423
383
|
configurable: true,
|
|
424
384
|
})
|
|
425
385
|
|
|
426
|
-
await getEnvironment("FIRE_TV", undefined
|
|
386
|
+
await getEnvironment("FIRE_TV", undefined)
|
|
427
387
|
|
|
428
|
-
expect(
|
|
388
|
+
expect(logger.info).toHaveBeenCalledWith(
|
|
429
389
|
'[Shell] Environment: "prod" (source: native BuildConfig.ENVIRONMENT="production")'
|
|
430
390
|
)
|
|
431
391
|
})
|
|
432
392
|
|
|
433
393
|
it("should log build-time environment source", async () => {
|
|
434
|
-
await getEnvironment("SAMSUNG_TV", "staging"
|
|
394
|
+
await getEnvironment("SAMSUNG_TV", "staging")
|
|
435
395
|
|
|
436
|
-
expect(
|
|
396
|
+
expect(logger.info).toHaveBeenCalledWith(
|
|
437
397
|
'[Shell] Environment: "staging" (source: build-time CLI injection)'
|
|
438
398
|
)
|
|
439
399
|
})
|
|
440
400
|
|
|
441
401
|
it("should warn when falling back to default", async () => {
|
|
442
|
-
await getEnvironment("LG_TV", undefined
|
|
402
|
+
await getEnvironment("LG_TV", undefined)
|
|
443
403
|
|
|
444
|
-
expect(
|
|
404
|
+
expect(logger.warn).toHaveBeenCalledWith(
|
|
445
405
|
'[Shell] Environment: "dev" (source: default fallback - no native or build-time env found)'
|
|
446
406
|
)
|
|
447
407
|
})
|
|
448
408
|
|
|
449
409
|
it("should warn when native fails and falls back", async () => {
|
|
450
|
-
await getEnvironment("FIRE_TV", "prod"
|
|
410
|
+
await getEnvironment("FIRE_TV", "prod")
|
|
451
411
|
|
|
452
|
-
expect(
|
|
412
|
+
expect(logger.warn).toHaveBeenCalledWith(
|
|
453
413
|
"[Shell] Failed to read environment from native, falling back to build-time"
|
|
454
414
|
)
|
|
455
415
|
})
|
package/src/getEnvironment.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { logger } from "./logger"
|
|
2
2
|
|
|
3
|
-
export type Environment = "local" | "dev" | "
|
|
3
|
+
export type Environment = "local" | "dev" | "staging" | "prod"
|
|
4
4
|
export type EnvironmentSource = "native" | "build-time" | "default"
|
|
5
5
|
|
|
6
6
|
export interface EnvironmentResult {
|
|
@@ -19,21 +19,20 @@ export interface EnvironmentResult {
|
|
|
19
19
|
* This ensures production APKs cannot accidentally run dev VWR,
|
|
20
20
|
* since the native Android build variant determines the environment.
|
|
21
21
|
*
|
|
22
|
-
* @param platform - Platform identifier ('FIRE_TV', 'SAMSUNG_TV', 'LG_TV', '
|
|
22
|
+
* @param platform - Platform identifier ('FIRE_TV', 'SAMSUNG_TV', 'LG_TV', 'ANDROID_MOBILE', 'IOS_MOBILE', 'WEB')
|
|
23
23
|
* @param buildTimeEnv - Optional build-time injected environment (from CLI)
|
|
24
24
|
* @param logger - Optional logger for reporting
|
|
25
25
|
* @returns Environment result with source information for logging
|
|
26
26
|
*/
|
|
27
27
|
export async function getEnvironment(
|
|
28
28
|
platform: string,
|
|
29
|
-
buildTimeEnv: string | undefined
|
|
30
|
-
logger: Logger = defaultLogger
|
|
29
|
+
buildTimeEnv: string | undefined
|
|
31
30
|
): Promise<EnvironmentResult> {
|
|
32
31
|
const normalizedPlatform = platform.toUpperCase()
|
|
33
32
|
|
|
34
33
|
// For Fire TV, try to read from native first (safest - prevents env mismatch)
|
|
35
34
|
if (normalizedPlatform === "FIRE_TV") {
|
|
36
|
-
const nativeEnv = await getFireTVEnvironment(
|
|
35
|
+
const nativeEnv = await getFireTVEnvironment()
|
|
37
36
|
if (nativeEnv) {
|
|
38
37
|
const mapped = mapNativeEnvironment(nativeEnv)
|
|
39
38
|
logger.info(
|
|
@@ -72,7 +71,7 @@ export async function getEnvironment(
|
|
|
72
71
|
/**
|
|
73
72
|
* Read environment from Fire TV native shell via Capacitor plugin.
|
|
74
73
|
*/
|
|
75
|
-
async function getFireTVEnvironment(
|
|
74
|
+
async function getFireTVEnvironment(): Promise<string | null> {
|
|
76
75
|
try {
|
|
77
76
|
if (
|
|
78
77
|
!window.Capacitor?.Plugins?.DeviceInfo?.getNativeShellAppEnvironment
|
|
@@ -113,12 +112,17 @@ async function getFireTVEnvironment(logger: Logger): Promise<string | null> {
|
|
|
113
112
|
* - "dev"
|
|
114
113
|
* - "staging"
|
|
115
114
|
* - "prod"
|
|
115
|
+
*
|
|
116
|
+
* Note: Legacy "qa" values are mapped to "staging".
|
|
116
117
|
*/
|
|
117
118
|
function mapNativeEnvironment(nativeEnv: string): Environment {
|
|
118
119
|
const normalized = nativeEnv.toLowerCase()
|
|
119
120
|
switch (normalized) {
|
|
120
121
|
case "development":
|
|
121
122
|
return "dev"
|
|
123
|
+
case "qa":
|
|
124
|
+
// Legacy: map qa to staging
|
|
125
|
+
return "staging"
|
|
122
126
|
case "staging":
|
|
123
127
|
return "staging"
|
|
124
128
|
case "production":
|
|
@@ -133,7 +137,7 @@ function mapNativeEnvironment(nativeEnv: string): Environment {
|
|
|
133
137
|
}
|
|
134
138
|
|
|
135
139
|
function isValidEnvironment(env: string): boolean {
|
|
136
|
-
return ["local", "dev", "
|
|
140
|
+
return ["local", "dev", "staging", "prod"].includes(env)
|
|
137
141
|
}
|
|
138
142
|
|
|
139
143
|
// Note: Window.Capacitor type is declared in getDeviceId.ts
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"
|
|
2
2
|
|
|
3
3
|
import { getShellVersion } from "./getShellVersion"
|
|
4
|
+
import { logger } from "./logger"
|
|
5
|
+
|
|
6
|
+
vi.mock("./logger", () => ({
|
|
7
|
+
logger: {
|
|
8
|
+
info: vi.fn(),
|
|
9
|
+
warn: vi.fn(),
|
|
10
|
+
error: vi.fn(),
|
|
11
|
+
debug: vi.fn(),
|
|
12
|
+
child: vi.fn(),
|
|
13
|
+
},
|
|
14
|
+
}))
|
|
4
15
|
|
|
5
16
|
describe("getShellVersion", () => {
|
|
6
17
|
const originalLocation = window.location
|
|
@@ -220,11 +231,130 @@ describe("getShellVersion", () => {
|
|
|
220
231
|
})
|
|
221
232
|
})
|
|
222
233
|
|
|
223
|
-
describe("Mobile", () => {
|
|
224
|
-
|
|
225
|
-
|
|
234
|
+
describe("Mobile (iOS)", () => {
|
|
235
|
+
afterEach(() => {
|
|
236
|
+
delete (window as any).iosAppContext
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
it("returns version from iosAppContext.appVersion", async () => {
|
|
240
|
+
;(window as any).iosAppContext = {
|
|
241
|
+
appVersion: "2.1.0",
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const version = await getShellVersion("IOS_MOBILE")
|
|
245
|
+
|
|
246
|
+
expect(version).toBe("2.1.0")
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
it("returns unknown when iosAppContext is not available", async () => {
|
|
250
|
+
const consoleWarnSpy = vi
|
|
251
|
+
.spyOn(console, "warn")
|
|
252
|
+
.mockImplementation(() => {})
|
|
253
|
+
|
|
254
|
+
const version = await getShellVersion("IOS_MOBILE")
|
|
226
255
|
|
|
227
256
|
expect(version).toBe("unknown")
|
|
257
|
+
|
|
258
|
+
consoleWarnSpy.mockRestore()
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
it("returns unknown when appVersion is empty", async () => {
|
|
262
|
+
const consoleWarnSpy = vi
|
|
263
|
+
.spyOn(console, "warn")
|
|
264
|
+
.mockImplementation(() => {})
|
|
265
|
+
|
|
266
|
+
;(window as any).iosAppContext = {
|
|
267
|
+
appVersion: " ",
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
const version = await getShellVersion("IOS_MOBILE")
|
|
271
|
+
|
|
272
|
+
expect(version).toBe("unknown")
|
|
273
|
+
|
|
274
|
+
consoleWarnSpy.mockRestore()
|
|
275
|
+
})
|
|
276
|
+
|
|
277
|
+
it("is case insensitive", async () => {
|
|
278
|
+
;(window as any).iosAppContext = {
|
|
279
|
+
appVersion: "2.2.0",
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
const version = await getShellVersion("ios_mobile")
|
|
283
|
+
|
|
284
|
+
expect(version).toBe("2.2.0")
|
|
285
|
+
})
|
|
286
|
+
})
|
|
287
|
+
|
|
288
|
+
describe("Mobile (Android)", () => {
|
|
289
|
+
afterEach(() => {
|
|
290
|
+
delete (window as any).androidAppContext
|
|
291
|
+
})
|
|
292
|
+
|
|
293
|
+
it("returns version from androidAppContext.appVersion", async () => {
|
|
294
|
+
;(window as any).androidAppContext = {
|
|
295
|
+
appVersion: "3.1.0",
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const version = await getShellVersion("ANDROID_MOBILE")
|
|
299
|
+
|
|
300
|
+
expect(version).toBe("3.1.0")
|
|
301
|
+
})
|
|
302
|
+
|
|
303
|
+
it("returns unknown when androidAppContext is not available", async () => {
|
|
304
|
+
const consoleWarnSpy = vi
|
|
305
|
+
.spyOn(console, "warn")
|
|
306
|
+
.mockImplementation(() => {})
|
|
307
|
+
|
|
308
|
+
const version = await getShellVersion("ANDROID_MOBILE")
|
|
309
|
+
|
|
310
|
+
expect(version).toBe("unknown")
|
|
311
|
+
|
|
312
|
+
consoleWarnSpy.mockRestore()
|
|
313
|
+
})
|
|
314
|
+
|
|
315
|
+
it("returns unknown when appVersion is empty", async () => {
|
|
316
|
+
const consoleWarnSpy = vi
|
|
317
|
+
.spyOn(console, "warn")
|
|
318
|
+
.mockImplementation(() => {})
|
|
319
|
+
|
|
320
|
+
;(window as any).androidAppContext = {
|
|
321
|
+
appVersion: "",
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const version = await getShellVersion("ANDROID_MOBILE")
|
|
325
|
+
|
|
326
|
+
expect(version).toBe("unknown")
|
|
327
|
+
|
|
328
|
+
consoleWarnSpy.mockRestore()
|
|
329
|
+
})
|
|
330
|
+
|
|
331
|
+
it("is case insensitive", async () => {
|
|
332
|
+
;(window as any).androidAppContext = {
|
|
333
|
+
appVersion: "3.2.0",
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
const version = await getShellVersion("android_mobile")
|
|
337
|
+
|
|
338
|
+
expect(version).toBe("3.2.0")
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
it("prefers iOS context when both are available", async () => {
|
|
342
|
+
;(window as any).iosAppContext = {
|
|
343
|
+
appVersion: "1.0.0-ios",
|
|
344
|
+
}
|
|
345
|
+
;(window as any).androidAppContext = {
|
|
346
|
+
appVersion: "1.0.0-android",
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// When calling with IOS_MOBILE, should get iOS version
|
|
350
|
+
const iosVersion = await getShellVersion("IOS_MOBILE")
|
|
351
|
+
expect(iosVersion).toBe("1.0.0-ios")
|
|
352
|
+
|
|
353
|
+
// When calling with ANDROID_MOBILE, should still check iOS first (matching SDK behavior)
|
|
354
|
+
const androidVersion = await getShellVersion("ANDROID_MOBILE")
|
|
355
|
+
expect(androidVersion).toBe("1.0.0-ios")
|
|
356
|
+
|
|
357
|
+
delete (window as any).iosAppContext
|
|
228
358
|
})
|
|
229
359
|
})
|
|
230
360
|
|
|
@@ -250,10 +380,6 @@ describe("getShellVersion", () => {
|
|
|
250
380
|
|
|
251
381
|
describe("Error Handling", () => {
|
|
252
382
|
it("returns unknown and logs warning on error", async () => {
|
|
253
|
-
const consoleWarnSpy = vi
|
|
254
|
-
.spyOn(console, "warn")
|
|
255
|
-
.mockImplementation(() => {})
|
|
256
|
-
|
|
257
383
|
// Force an error by making tizen.application.getAppInfo throw
|
|
258
384
|
;(window as any).tizen = {
|
|
259
385
|
application: {
|
|
@@ -266,12 +392,11 @@ describe("getShellVersion", () => {
|
|
|
266
392
|
const version = await getShellVersion("SAMSUNG_TV")
|
|
267
393
|
|
|
268
394
|
expect(version).toBe("unknown")
|
|
269
|
-
expect(
|
|
395
|
+
expect(logger.warn).toHaveBeenCalledWith(
|
|
270
396
|
"[Shell] Failed to get shell version:",
|
|
271
397
|
{ error: expect.any(Error) }
|
|
272
398
|
)
|
|
273
399
|
|
|
274
|
-
consoleWarnSpy.mockRestore()
|
|
275
400
|
delete (window as any).tizen
|
|
276
401
|
})
|
|
277
402
|
})
|