@volley/vwr-loader 1.0.5 → 1.1.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 +21 -0
- package/dist/amplitudeFlagFetcher.d.ts +4 -2
- package/dist/amplitudeFlagFetcher.d.ts.map +1 -1
- package/dist/amplitudeFlagFetcher.js +26 -19
- package/dist/amplitudeFlagFetcher.js.map +1 -1
- package/dist/cli.js +213 -0
- package/dist/cli.js.map +1 -0
- package/dist/envDefaults.d.ts +3 -0
- package/dist/envDefaults.d.ts.map +1 -1
- package/dist/envDefaults.js +16 -4
- package/dist/envDefaults.js.map +1 -1
- package/dist/getDeviceId.d.ts +2 -40
- package/dist/getDeviceId.d.ts.map +1 -1
- package/dist/getDeviceId.js +31 -18
- package/dist/getDeviceId.js.map +1 -1
- package/dist/getEnvironment.d.ts +1 -1
- package/dist/getEnvironment.d.ts.map +1 -1
- package/dist/getEnvironment.js +15 -7
- package/dist/getEnvironment.js.map +1 -1
- package/dist/getShellVersion.d.ts +2 -19
- package/dist/getShellVersion.d.ts.map +1 -1
- package/dist/getShellVersion.js +41 -6
- package/dist/getShellVersion.js.map +1 -1
- package/dist/index.html +1 -1
- package/dist/loadVwr.d.ts.map +1 -1
- package/dist/loadVwr.js +8 -6
- package/dist/loadVwr.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- 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 +2 -0
- package/dist/vwrConfig.d.ts.map +1 -1
- package/dist/vwrConfig.js +148 -119
- package/dist/vwrConfig.js.map +1 -1
- package/package.json +16 -5
- package/src/amplitudeFlagFetcher.test.ts +36 -59
- package/src/amplitudeFlagFetcher.ts +31 -22
- package/src/envDefaults.ts +23 -4
- package/src/getDeviceId.test.ts +89 -27
- package/src/getDeviceId.ts +35 -58
- package/src/getEnvironment.test.ts +479 -0
- package/src/getEnvironment.ts +16 -8
- package/src/getShellVersion.test.ts +123 -4
- package/src/getShellVersion.ts +46 -21
- package/src/loadVwr.ts +13 -6
- package/src/main.ts +3 -1
- package/src/types.ts +88 -0
- package/src/vite-env.d.ts +3 -0
- package/src/vwrConfig.test.ts +2 -2
- package/src/vwrConfig.ts +202 -199
- package/eslint.config.mjs +0 -23
- package/scripts/build.js +0 -2
- package/scripts/build.ts +0 -207
- package/tsconfig.eslint.json +0 -16
- package/tsconfig.json +0 -17
- package/vite.config.ts +0 -24
- package/vitest.config.ts +0 -8
package/dist/vwrConfig.js
CHANGED
|
@@ -18,131 +18,154 @@ const buildUrl = (path, base) => {
|
|
|
18
18
|
const normalizedBase = base.endsWith("/") ? base : `${base}/`;
|
|
19
19
|
return new URL(path, normalizedBase);
|
|
20
20
|
};
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
const tryGetEnvironmentConfig = async (configUrl, configFile, environment, timeout, logger) => {
|
|
78
|
-
try {
|
|
79
|
-
const url = buildUrl(`environments/${environment}/${configFile}`, configUrl);
|
|
80
|
-
logger.info(`[VWR Config] Trying environment: ${url}`);
|
|
81
|
-
return tryGetVWRConfig(url, timeout);
|
|
21
|
+
class VWRConfigFetcher {
|
|
22
|
+
constructor(request, logger) {
|
|
23
|
+
var _a;
|
|
24
|
+
this.defaults = getDefaultConfig(request.environment);
|
|
25
|
+
this.timeout = (_a = request.timeout) !== null && _a !== void 0 ? _a : DEFAULT_CONFIG_TIMEOUT;
|
|
26
|
+
this.logger = logger;
|
|
27
|
+
this.configUrl = request.configUrl;
|
|
28
|
+
this.configFile = request.configFile;
|
|
29
|
+
this.platform = request.platform;
|
|
30
|
+
this.deviceId = request.deviceId;
|
|
31
|
+
this.environment = request.environment;
|
|
32
|
+
this.shellVersion = request.shellVersion;
|
|
33
|
+
}
|
|
34
|
+
async fetch() {
|
|
35
|
+
this.logger.info("[VWR Config] Fetching config with priority: local → device → shellVersion → environment → defaults");
|
|
36
|
+
// Fetch all configs in parallel for performance
|
|
37
|
+
const [localConfig, deviceConfig, shellVersionConfig, environmentConfig,] = await Promise.all([
|
|
38
|
+
this.tryGetLocalConfig(),
|
|
39
|
+
this.tryGetDeviceConfig(),
|
|
40
|
+
this.tryGetShellVersionConfig(),
|
|
41
|
+
this.tryGetEnvironmentConfig(),
|
|
42
|
+
]);
|
|
43
|
+
// Return first successful config in priority order
|
|
44
|
+
if (localConfig !== null) {
|
|
45
|
+
this.logger.info("[VWR Config] ✓ Using config from: local", localConfig);
|
|
46
|
+
return localConfig;
|
|
47
|
+
}
|
|
48
|
+
if (deviceConfig !== null) {
|
|
49
|
+
this.logger.info("[VWR Config] ✓ Using config from: device", deviceConfig);
|
|
50
|
+
return deviceConfig;
|
|
51
|
+
}
|
|
52
|
+
if (shellVersionConfig !== null) {
|
|
53
|
+
this.logger.info("[VWR Config] ✓ Using config from: shellVersion", shellVersionConfig);
|
|
54
|
+
return shellVersionConfig;
|
|
55
|
+
}
|
|
56
|
+
if (environmentConfig !== null) {
|
|
57
|
+
this.logger.info("[VWR Config] ✓ Using config from: environment", environmentConfig);
|
|
58
|
+
return environmentConfig;
|
|
59
|
+
}
|
|
60
|
+
// All fetches failed, use defaults
|
|
61
|
+
this.logger.warn("[VWR Config] All config fetches failed, using built-in defaults");
|
|
62
|
+
return this.defaults;
|
|
63
|
+
}
|
|
64
|
+
async tryGetLocalConfig() {
|
|
65
|
+
var _a, _b;
|
|
66
|
+
try {
|
|
67
|
+
const url = buildUrl(this.configFile, (_b = (_a = ENV_DEFAULTS["local"]) === null || _a === void 0 ? void 0 : _a.configUrl) !== null && _b !== void 0 ? _b : "");
|
|
68
|
+
this.logger.info(`[VWR Config] Trying local: ${url}`);
|
|
69
|
+
return this.tryFetchConfig(url);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
this.logger.error(`[VWR Config] URL construction failed for local config: ${error}`);
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
82
75
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
76
|
+
async tryGetDeviceConfig() {
|
|
77
|
+
try {
|
|
78
|
+
const url = buildUrl(`device/${this.platform}/${this.deviceId}/${this.configFile}`, this.configUrl);
|
|
79
|
+
this.logger.info(`[VWR Config] Trying device: ${url}`);
|
|
80
|
+
return this.tryFetchConfig(url);
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
this.logger.error(`[VWR Config] URL construction failed for device config: ${error}`);
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
86
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
87
|
+
async tryGetEnvironmentConfig() {
|
|
88
|
+
try {
|
|
89
|
+
const url = buildUrl(`environments/${this.environment}/${this.configFile}`, this.configUrl);
|
|
90
|
+
this.logger.info(`[VWR Config] Trying environment: ${url}`);
|
|
91
|
+
return this.tryFetchConfig(url);
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
this.logger.error(`[VWR Config] URL construction failed for environment config: ${error}`);
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
93
97
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
98
|
+
async tryGetShellVersionConfig() {
|
|
99
|
+
try {
|
|
100
|
+
const url = buildUrl(`shellVersion/${this.environment}/${this.platform}/${this.shellVersion}/${this.configFile}`, this.configUrl);
|
|
101
|
+
this.logger.info(`[VWR Config] Trying shellVersion: ${url}`);
|
|
102
|
+
return this.tryFetchConfig(url);
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
this.logger.error(`[VWR Config] URL construction failed for shellVersion config: ${error}`);
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
97
108
|
}
|
|
98
|
-
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
109
|
+
async tryFetchConfig(url) {
|
|
110
|
+
const controller = new AbortController();
|
|
111
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
112
|
+
try {
|
|
113
|
+
const response = await fetch(new Request(url, {
|
|
114
|
+
headers: { "Content-Type": "application/json" },
|
|
115
|
+
signal: controller.signal,
|
|
116
|
+
}));
|
|
117
|
+
if (!response.ok) {
|
|
118
|
+
clearTimeout(timeoutId);
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
const config = await response.json();
|
|
122
|
+
clearTimeout(timeoutId);
|
|
123
|
+
return this.parseConfig(config);
|
|
124
|
+
}
|
|
125
|
+
catch (_a) {
|
|
110
126
|
clearTimeout(timeoutId);
|
|
111
127
|
return null;
|
|
112
128
|
}
|
|
113
|
-
let config = await response.json();
|
|
114
|
-
config = parseConfig(config);
|
|
115
|
-
clearTimeout(timeoutId);
|
|
116
|
-
return config;
|
|
117
|
-
}
|
|
118
|
-
catch (_a) {
|
|
119
|
-
clearTimeout(timeoutId);
|
|
120
|
-
return null;
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
const parseConfig = (config) => {
|
|
124
|
-
const defaultConfig = getDefaultConfig();
|
|
125
|
-
if (!Array.isArray(config.trustedDomains) ||
|
|
126
|
-
config.trustedDomains.length === 0) {
|
|
127
|
-
config.trustedDomains = defaultConfig.trustedDomains;
|
|
128
129
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
config.
|
|
130
|
+
parseConfig(config) {
|
|
131
|
+
const result = {
|
|
132
|
+
hubUrl: config.hubUrl || this.defaults.hubUrl,
|
|
133
|
+
vwrUrl: config.vwrUrl || this.defaults.vwrUrl,
|
|
134
|
+
launchUrl: config.launchUrl,
|
|
135
|
+
platformApiUrl: config.platformApiUrl || this.defaults.platformApiUrl,
|
|
136
|
+
platformAuthApiUrl: config.platformAuthApiUrl || this.defaults.platformAuthApiUrl,
|
|
137
|
+
trustedDomains: Array.isArray(config.trustedDomains) &&
|
|
138
|
+
config.trustedDomains.length > 0
|
|
139
|
+
? [...config.trustedDomains]
|
|
140
|
+
: [...this.defaults.trustedDomains],
|
|
141
|
+
};
|
|
142
|
+
// Ensure vwrUrl origin is in trustedDomains
|
|
143
|
+
const vwrUrlOrigin = new URL(result.vwrUrl).origin;
|
|
144
|
+
if (!result.trustedDomains.includes(vwrUrlOrigin)) {
|
|
145
|
+
result.trustedDomains.push(vwrUrlOrigin);
|
|
133
146
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
config.trustedDomains.push(defaultConfig.hubUrl);
|
|
147
|
+
// Ensure hubUrl origin is in trustedDomains
|
|
148
|
+
const hubUrlOrigin = new URL(result.hubUrl).origin;
|
|
149
|
+
if (!result.trustedDomains.includes(hubUrlOrigin)) {
|
|
150
|
+
result.trustedDomains.push(hubUrlOrigin);
|
|
139
151
|
}
|
|
152
|
+
// launchUrl is optional - only add to trustedDomains if explicitly set
|
|
153
|
+
if (result.launchUrl) {
|
|
154
|
+
try {
|
|
155
|
+
const launchUrlOrigin = new URL(result.launchUrl).origin;
|
|
156
|
+
if (!result.trustedDomains.includes(launchUrlOrigin)) {
|
|
157
|
+
result.trustedDomains.push(launchUrlOrigin);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch (_a) {
|
|
161
|
+
// Invalid launchUrl - skip adding to trustedDomains
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
return result;
|
|
140
165
|
}
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
145
|
-
return config;
|
|
166
|
+
}
|
|
167
|
+
export const getVWRConfig = async (request, logger = defaultLogger) => {
|
|
168
|
+
return new VWRConfigFetcher(request, logger).fetch();
|
|
146
169
|
};
|
|
147
170
|
export const validateConfig = (config) => {
|
|
148
171
|
if (!config.vwrUrl)
|
|
@@ -156,17 +179,23 @@ export const validateConfig = (config) => {
|
|
|
156
179
|
return false;
|
|
157
180
|
return true;
|
|
158
181
|
};
|
|
159
|
-
const getDefaultConfig = () => {
|
|
160
|
-
|
|
161
|
-
const defaults = ENV_DEFAULTS[
|
|
182
|
+
const getDefaultConfig = (environment) => {
|
|
183
|
+
var _a;
|
|
184
|
+
const defaults = ENV_DEFAULTS[environment];
|
|
162
185
|
if (!defaults) {
|
|
163
|
-
throw new Error(`[VWR Config] Unknown environment: ${
|
|
186
|
+
throw new Error(`[VWR Config] Unknown environment: ${environment}. Valid: local, dev, staging, prod`);
|
|
164
187
|
}
|
|
165
188
|
return {
|
|
166
189
|
hubUrl: defaults.hubUrl,
|
|
167
190
|
vwrUrl: defaults.vwrUrl,
|
|
168
191
|
launchUrl: undefined,
|
|
169
|
-
|
|
192
|
+
platformApiUrl: defaults.platformApiUrl,
|
|
193
|
+
platformAuthApiUrl: defaults.platformAuthApiUrl,
|
|
194
|
+
trustedDomains: [
|
|
195
|
+
new URL(defaults.hubUrl).origin,
|
|
196
|
+
new URL(defaults.vwrUrl).origin,
|
|
197
|
+
...((_a = defaults.trustedOrigins) !== null && _a !== void 0 ? _a : []),
|
|
198
|
+
],
|
|
170
199
|
};
|
|
171
200
|
};
|
|
172
201
|
//# sourceMappingURL=vwrConfig.js.map
|
package/dist/vwrConfig.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vwrConfig.js","sourceRoot":"","sources":["../src/vwrConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAe,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"vwrConfig.js","sourceRoot":"","sources":["../src/vwrConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAe,MAAM,UAAU,CAAA;AAqBrD,MAAM,sBAAsB,GAAG,IAAI,CAAA;AAEnC;;;;;;;;;;;;GAYG;AACH,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAE,IAAY,EAAO,EAAE;IACjD,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,CAAA;IAC7D,OAAO,IAAI,GAAG,CAAC,IAAI,EAAE,cAAc,CAAC,CAAA;AACxC,CAAC,CAAA;AAED,MAAM,gBAAgB;IAWlB,YAAY,OAAyB,EAAE,MAAc;;QACjD,IAAI,CAAC,QAAQ,GAAG,gBAAgB,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;QACrD,IAAI,CAAC,OAAO,GAAG,MAAA,OAAO,CAAC,OAAO,mCAAI,sBAAsB,CAAA;QACxD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAA;QAClC,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAA;QACpC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;QAChC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;QAChC,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAA;QACtC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAA;IAC5C,CAAC;IAED,KAAK,CAAC,KAAK;QACP,IAAI,CAAC,MAAM,CAAC,IAAI,CACZ,oGAAoG,CACvG,CAAA;QAED,gDAAgD;QAChD,MAAM,CACF,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,EACpB,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAClB,IAAI,CAAC,iBAAiB,EAAE;YACxB,IAAI,CAAC,kBAAkB,EAAE;YACzB,IAAI,CAAC,wBAAwB,EAAE;YAC/B,IAAI,CAAC,uBAAuB,EAAE;SACjC,CAAC,CAAA;QAEF,mDAAmD;QACnD,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC,MAAM,CAAC,IAAI,CACZ,yCAAyC,EACzC,WAAW,CACd,CAAA;YACD,OAAO,WAAW,CAAA;QACtB,CAAC;QACD,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC,MAAM,CAAC,IAAI,CACZ,0CAA0C,EAC1C,YAAY,CACf,CAAA;YACD,OAAO,YAAY,CAAA;QACvB,CAAC;QACD,IAAI,kBAAkB,KAAK,IAAI,EAAE,CAAC;YAC9B,IAAI,CAAC,MAAM,CAAC,IAAI,CACZ,gDAAgD,EAChD,kBAAkB,CACrB,CAAA;YACD,OAAO,kBAAkB,CAAA;QAC7B,CAAC;QACD,IAAI,iBAAiB,KAAK,IAAI,EAAE,CAAC;YAC7B,IAAI,CAAC,MAAM,CAAC,IAAI,CACZ,+CAA+C,EAC/C,iBAAiB,CACpB,CAAA;YACD,OAAO,iBAAiB,CAAA;QAC5B,CAAC;QAED,mCAAmC;QACnC,IAAI,CAAC,MAAM,CAAC,IAAI,CACZ,iEAAiE,CACpE,CAAA;QACD,OAAO,IAAI,CAAC,QAAQ,CAAA;IACxB,CAAC;IAEO,KAAK,CAAC,iBAAiB;;QAC3B,IAAI,CAAC;YACD,MAAM,GAAG,GAAG,QAAQ,CAChB,IAAI,CAAC,UAAU,EACf,MAAA,MAAA,YAAY,CAAC,OAAO,CAAC,0CAAE,SAAS,mCAAI,EAAE,CACzC,CAAA;YACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,8BAA8B,GAAG,EAAE,CAAC,CAAA;YACrD,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAA;QACnC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CACb,0DAA0D,KAAK,EAAE,CACpE,CAAA;YACD,OAAO,IAAI,CAAA;QACf,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,kBAAkB;QAC5B,IAAI,CAAC;YACD,MAAM,GAAG,GAAG,QAAQ,CAChB,UAAU,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,UAAU,EAAE,EAC7D,IAAI,CAAC,SAAS,CACjB,CAAA;YACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,+BAA+B,GAAG,EAAE,CAAC,CAAA;YACtD,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAA;QACnC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CACb,2DAA2D,KAAK,EAAE,CACrE,CAAA;YACD,OAAO,IAAI,CAAA;QACf,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,uBAAuB;QACjC,IAAI,CAAC;YACD,MAAM,GAAG,GAAG,QAAQ,CAChB,gBAAgB,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,UAAU,EAAE,EACrD,IAAI,CAAC,SAAS,CACjB,CAAA;YACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,oCAAoC,GAAG,EAAE,CAAC,CAAA;YAC3D,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAA;QACnC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CACb,gEAAgE,KAAK,EAAE,CAC1E,CAAA;YACD,OAAO,IAAI,CAAA;QACf,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,wBAAwB;QAClC,IAAI,CAAC;YACD,MAAM,GAAG,GAAG,QAAQ,CAChB,gBAAgB,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,UAAU,EAAE,EAC3F,IAAI,CAAC,SAAS,CACjB,CAAA;YACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qCAAqC,GAAG,EAAE,CAAC,CAAA;YAC5D,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAA;QACnC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CACb,iEAAiE,KAAK,EAAE,CAC3E,CAAA;YACD,OAAO,IAAI,CAAA;QACf,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,GAAQ;QACjC,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;QACxC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;QAEpE,IAAI,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,KAAK,CACxB,IAAI,OAAO,CAAC,GAAG,EAAE;gBACb,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,MAAM,EAAE,UAAU,CAAC,MAAM;aAC5B,CAAC,CACL,CAAA;YAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACf,YAAY,CAAC,SAAS,CAAC,CAAA;gBACvB,OAAO,IAAI,CAAA;YACf,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;YACpC,YAAY,CAAC,SAAS,CAAC,CAAA;YACvB,OAAO,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;QACnC,CAAC;QAAC,WAAM,CAAC;YACL,YAAY,CAAC,SAAS,CAAC,CAAA;YACvB,OAAO,IAAI,CAAA;QACf,CAAC;IACL,CAAC;IAEO,WAAW,CAAC,MAA0B;QAC1C,MAAM,MAAM,GAAc;YACtB,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM;YAC7C,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM;YAC7C,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,cAAc,EACV,MAAM,CAAC,cAAc,IAAI,IAAI,CAAC,QAAQ,CAAC,cAAc;YACzD,kBAAkB,EACd,MAAM,CAAC,kBAAkB,IAAI,IAAI,CAAC,QAAQ,CAAC,kBAAkB;YACjE,cAAc,EACV,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC;gBACpC,MAAM,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC;gBAC5B,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,cAAc,CAAC;gBAC5B,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC;SAC9C,CAAA;QAED,4CAA4C;QAC5C,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAA;QAClD,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YAChD,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QAC5C,CAAC;QAED,4CAA4C;QAC5C,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAA;QAClD,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;YAChD,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QAC5C,CAAC;QAED,uEAAuE;QACvE,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YACnB,IAAI,CAAC;gBACD,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAA;gBACxD,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;oBACnD,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;gBAC/C,CAAC;YACL,CAAC;YAAC,WAAM,CAAC;gBACL,oDAAoD;YACxD,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAA;IACjB,CAAC;CACJ;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,EAC7B,OAAyB,EACzB,SAAiB,aAAa,EACZ,EAAE;IACpB,OAAO,IAAI,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,KAAK,EAAE,CAAA;AACxD,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,MAAiB,EAAW,EAAE;IACzD,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,OAAO,KAAK,CAAA;IAEhC,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,OAAO,KAAK,CAAA;IAEhC,yCAAyC;IAEzC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC;QAAE,OAAO,KAAK,CAAA;SAClD,IAAI,MAAM,CAAC,cAAc,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IAEzD,OAAO,IAAI,CAAA;AACf,CAAC,CAAA;AAED,MAAM,gBAAgB,GAAG,CAAC,WAAmB,EAAa,EAAE;;IACxD,MAAM,QAAQ,GAAG,YAAY,CAAC,WAAW,CAAC,CAAA;IAE1C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACX,qCAAqC,WAAW,oCAAoC,CACvF,CAAA;IACL,CAAC;IAED,OAAO;QACH,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,MAAM,EAAE,QAAQ,CAAC,MAAM;QACvB,SAAS,EAAE,SAAS;QACpB,cAAc,EAAE,QAAQ,CAAC,cAAc;QACvC,kBAAkB,EAAE,QAAQ,CAAC,kBAAkB;QAC/C,cAAc,EAAE;YACZ,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM;YAC/B,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM;YAC/B,GAAG,CAAC,MAAA,QAAQ,CAAC,cAAc,mCAAI,EAAE,CAAC;SACrC;KACJ,CAAA;AACL,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volley/vwr-loader",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Vite-based VWR loader for all Volley platforms",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -13,31 +13,42 @@
|
|
|
13
13
|
"./envDefaults": "./dist/envDefaults.js"
|
|
14
14
|
},
|
|
15
15
|
"bin": {
|
|
16
|
-
"build-loader": "
|
|
16
|
+
"build-loader": "dist/cli.js"
|
|
17
17
|
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist",
|
|
20
|
+
"src"
|
|
21
|
+
],
|
|
18
22
|
"scripts": {
|
|
19
|
-
"build": "tsc && vite build",
|
|
23
|
+
"build": "tsc && vite build && vite build -c vite.cli.config.ts && chmod +x dist/cli.js",
|
|
24
|
+
"build:cli": "vite build -c vite.cli.config.ts",
|
|
20
25
|
"build:loader": "vite build",
|
|
21
26
|
"typecheck": "tsc --noEmit",
|
|
22
27
|
"test": "vitest run",
|
|
23
28
|
"test:watch": "vitest",
|
|
24
29
|
"format": "eslint . --fix",
|
|
25
|
-
"lint": "eslint ."
|
|
30
|
+
"lint": "eslint .",
|
|
31
|
+
"semantic-release": "semantic-release"
|
|
26
32
|
},
|
|
27
33
|
"dependencies": {
|
|
28
34
|
"commander": "^12.0.0",
|
|
29
35
|
"dotenv": "^16.0.0",
|
|
30
36
|
"fs-extra": "^11.0.0",
|
|
31
|
-
"tsx": "^4.7.0",
|
|
32
37
|
"vite": "^5.0.0"
|
|
33
38
|
},
|
|
34
39
|
"devDependencies": {
|
|
40
|
+
"tsx": "^4.7.0",
|
|
35
41
|
"@platform/eslint-config": "workspace:*",
|
|
42
|
+
"@semantic-release/git": "^10.0.1",
|
|
43
|
+
"@semantic-release/npm": "^12.0.1",
|
|
36
44
|
"@types/fs-extra": "^11.0.0",
|
|
37
45
|
"@types/node": "^20.0.0",
|
|
46
|
+
"@volley/vwr": "workspace:*",
|
|
38
47
|
"eslint": "^9.25.1",
|
|
39
48
|
"jsdom": "^24.1.3",
|
|
40
49
|
"prettier": "~3.0.3",
|
|
50
|
+
"semantic-release": "^24.2.3",
|
|
51
|
+
"semantic-release-monorepo": "^8.0.2",
|
|
41
52
|
"typescript": "^5.0.0",
|
|
42
53
|
"vitest": "^1.0.0"
|
|
43
54
|
}
|
|
@@ -1,26 +1,16 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"
|
|
2
2
|
|
|
3
3
|
import { fetchAmplitudeFlags } from "./amplitudeFlagFetcher"
|
|
4
|
-
import * as getShellVersionModule from "./getShellVersion"
|
|
5
4
|
|
|
6
5
|
describe("fetchAmplitudeFlags", () => {
|
|
7
6
|
const mockFetch = vi.fn()
|
|
8
|
-
const originalLocation = window.location
|
|
9
7
|
|
|
10
8
|
beforeEach(() => {
|
|
11
9
|
global.fetch = mockFetch
|
|
12
10
|
vi.clearAllMocks()
|
|
13
|
-
|
|
14
|
-
// Mock window.location for getShellVersion
|
|
15
|
-
delete (window as any).location
|
|
16
|
-
window.location = {
|
|
17
|
-
...originalLocation,
|
|
18
|
-
href: "http://localhost:3000/?version=1.0.0",
|
|
19
|
-
} as Location
|
|
20
11
|
})
|
|
21
12
|
|
|
22
13
|
afterEach(() => {
|
|
23
|
-
window.location = originalLocation
|
|
24
14
|
vi.restoreAllMocks()
|
|
25
15
|
})
|
|
26
16
|
|
|
@@ -36,9 +26,12 @@ describe("fetchAmplitudeFlags", () => {
|
|
|
36
26
|
}),
|
|
37
27
|
})
|
|
38
28
|
|
|
39
|
-
const result = await fetchAmplitudeFlags(
|
|
40
|
-
|
|
41
|
-
|
|
29
|
+
const result = await fetchAmplitudeFlags(
|
|
30
|
+
"device-123",
|
|
31
|
+
"SAMSUNG_TV",
|
|
32
|
+
{ apiKey: "test-key" },
|
|
33
|
+
"1.0.0"
|
|
34
|
+
)
|
|
42
35
|
|
|
43
36
|
expect(result).toEqual({
|
|
44
37
|
"vwr-enabled": true,
|
|
@@ -98,45 +91,17 @@ describe("fetchAmplitudeFlags", () => {
|
|
|
98
91
|
})
|
|
99
92
|
})
|
|
100
93
|
|
|
101
|
-
it("auto-fetches shell version when not provided", async () => {
|
|
102
|
-
const getShellVersionSpy = vi.spyOn(
|
|
103
|
-
getShellVersionModule,
|
|
104
|
-
"getShellVersion"
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
mockFetch.mockResolvedValueOnce({
|
|
108
|
-
ok: true,
|
|
109
|
-
json: async () => ({
|
|
110
|
-
"vwr-enabled": {
|
|
111
|
-
payload: {
|
|
112
|
-
"vwr-enabled": false,
|
|
113
|
-
},
|
|
114
|
-
},
|
|
115
|
-
}),
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
await fetchAmplitudeFlags("device-456", "LG_TV", {
|
|
119
|
-
apiKey: "test-key",
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
expect(getShellVersionSpy).toHaveBeenCalledWith("LG_TV")
|
|
123
|
-
|
|
124
|
-
const callArgs = mockFetch.mock.calls[0]
|
|
125
|
-
const url = new URL(callArgs[0])
|
|
126
|
-
const context = JSON.parse(url.searchParams.get("context") || "{}")
|
|
127
|
-
|
|
128
|
-
expect(context.user_properties).toHaveProperty("nativeShellAppVersion")
|
|
129
|
-
})
|
|
130
|
-
|
|
131
94
|
it("returns safe defaults on timeout", async () => {
|
|
132
95
|
mockFetch.mockImplementationOnce(
|
|
133
96
|
() => new Promise((resolve) => setTimeout(resolve, 3000))
|
|
134
97
|
)
|
|
135
98
|
|
|
136
|
-
const result = await fetchAmplitudeFlags(
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
99
|
+
const result = await fetchAmplitudeFlags(
|
|
100
|
+
"device-123",
|
|
101
|
+
"FIRE_TV",
|
|
102
|
+
{ apiKey: "test-key", timeout: 100 },
|
|
103
|
+
"1.0.0"
|
|
104
|
+
)
|
|
140
105
|
|
|
141
106
|
expect(result).toEqual({
|
|
142
107
|
"vwr-enabled": false,
|
|
@@ -149,9 +114,12 @@ describe("fetchAmplitudeFlags", () => {
|
|
|
149
114
|
status: 500,
|
|
150
115
|
})
|
|
151
116
|
|
|
152
|
-
const result = await fetchAmplitudeFlags(
|
|
153
|
-
|
|
154
|
-
|
|
117
|
+
const result = await fetchAmplitudeFlags(
|
|
118
|
+
"device-123",
|
|
119
|
+
"MOBILE",
|
|
120
|
+
{ apiKey: "test-key" },
|
|
121
|
+
"1.0.0"
|
|
122
|
+
)
|
|
155
123
|
|
|
156
124
|
expect(result).toEqual({
|
|
157
125
|
"vwr-enabled": false,
|
|
@@ -161,9 +129,12 @@ describe("fetchAmplitudeFlags", () => {
|
|
|
161
129
|
it("returns safe defaults on network error", async () => {
|
|
162
130
|
mockFetch.mockRejectedValueOnce(new Error("Network error"))
|
|
163
131
|
|
|
164
|
-
const result = await fetchAmplitudeFlags(
|
|
165
|
-
|
|
166
|
-
|
|
132
|
+
const result = await fetchAmplitudeFlags(
|
|
133
|
+
"device-123",
|
|
134
|
+
"MOBILE",
|
|
135
|
+
{ apiKey: "test-key" },
|
|
136
|
+
"1.0.0"
|
|
137
|
+
)
|
|
167
138
|
|
|
168
139
|
expect(result).toEqual({
|
|
169
140
|
"vwr-enabled": false,
|
|
@@ -176,9 +147,12 @@ describe("fetchAmplitudeFlags", () => {
|
|
|
176
147
|
json: async () => ({}),
|
|
177
148
|
})
|
|
178
149
|
|
|
179
|
-
const result = await fetchAmplitudeFlags(
|
|
180
|
-
|
|
181
|
-
|
|
150
|
+
const result = await fetchAmplitudeFlags(
|
|
151
|
+
"device-123",
|
|
152
|
+
"LG_TV",
|
|
153
|
+
{ apiKey: "test-key" },
|
|
154
|
+
"1.0.0"
|
|
155
|
+
)
|
|
182
156
|
|
|
183
157
|
expect(result).toEqual({
|
|
184
158
|
"vwr-enabled": false,
|
|
@@ -193,9 +167,12 @@ describe("fetchAmplitudeFlags", () => {
|
|
|
193
167
|
}),
|
|
194
168
|
})
|
|
195
169
|
|
|
196
|
-
const result = await fetchAmplitudeFlags(
|
|
197
|
-
|
|
198
|
-
|
|
170
|
+
const result = await fetchAmplitudeFlags(
|
|
171
|
+
"device-123",
|
|
172
|
+
"LG_TV",
|
|
173
|
+
{ apiKey: "test-key" },
|
|
174
|
+
"1.0.0"
|
|
175
|
+
)
|
|
199
176
|
|
|
200
177
|
expect(result).toEqual({
|
|
201
178
|
"vwr-enabled": false,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { defaultLogger, type Logger } from "./logger"
|
|
2
2
|
|
|
3
3
|
export interface AmplitudeConfig {
|
|
4
4
|
apiKey: string
|
|
@@ -20,14 +20,16 @@ export interface FlagResult {
|
|
|
20
20
|
* @param deviceId - Unique device identifier
|
|
21
21
|
* @param platform - Platform name (samsung, lg, firetv, ios, android)
|
|
22
22
|
* @param config - Amplitude configuration
|
|
23
|
-
* @param shellVersion -
|
|
23
|
+
* @param shellVersion - Shell version for flag targeting
|
|
24
|
+
* @param logger - Optional logger, defaults to console
|
|
24
25
|
* @returns Flag values with safe defaults on error
|
|
25
26
|
*/
|
|
26
27
|
export async function fetchAmplitudeFlags(
|
|
27
28
|
deviceId: string,
|
|
28
29
|
platform: string,
|
|
29
30
|
config: AmplitudeConfig,
|
|
30
|
-
shellVersion
|
|
31
|
+
shellVersion: string,
|
|
32
|
+
logger: Logger = defaultLogger
|
|
31
33
|
): Promise<FlagResult> {
|
|
32
34
|
const {
|
|
33
35
|
apiKey,
|
|
@@ -35,28 +37,26 @@ export async function fetchAmplitudeFlags(
|
|
|
35
37
|
timeout = 2000,
|
|
36
38
|
} = config
|
|
37
39
|
|
|
40
|
+
// Build context with user_properties
|
|
41
|
+
const context = {
|
|
42
|
+
user_properties: {
|
|
43
|
+
platformEnum: platform,
|
|
44
|
+
nativeShellAppVersion: shellVersion,
|
|
45
|
+
},
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Build query parameters
|
|
49
|
+
const params = new URLSearchParams({
|
|
50
|
+
user_id: deviceId,
|
|
51
|
+
flag_keys: "vwr-enabled",
|
|
52
|
+
context: JSON.stringify(context),
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
// Start timeout immediately before the fetch call for accurate timing
|
|
38
56
|
const controller = new AbortController()
|
|
39
57
|
const timeoutId = setTimeout(() => controller.abort(), timeout)
|
|
40
58
|
|
|
41
59
|
try {
|
|
42
|
-
// Get shell version if not provided
|
|
43
|
-
const version = shellVersion ?? (await getShellVersion(platform))
|
|
44
|
-
|
|
45
|
-
// Build context with user_properties
|
|
46
|
-
const context = {
|
|
47
|
-
user_properties: {
|
|
48
|
-
platformEnum: platform,
|
|
49
|
-
nativeShellAppVersion: version,
|
|
50
|
-
},
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
// Build query parameters
|
|
54
|
-
const params = new URLSearchParams({
|
|
55
|
-
user_id: deviceId,
|
|
56
|
-
flag_keys: "vwr-enabled",
|
|
57
|
-
context: JSON.stringify(context),
|
|
58
|
-
})
|
|
59
|
-
|
|
60
60
|
const response = await fetch(`${apiUrl}?${params}`, {
|
|
61
61
|
method: "GET",
|
|
62
62
|
headers: {
|
|
@@ -78,7 +78,16 @@ export async function fetchAmplitudeFlags(
|
|
|
78
78
|
data["vwr-enabled"]?.payload?.["vwr-enabled"] ?? false,
|
|
79
79
|
}
|
|
80
80
|
} catch (error) {
|
|
81
|
-
|
|
81
|
+
clearTimeout(timeoutId)
|
|
82
|
+
|
|
83
|
+
// Provide clear warning message for abort vs other errors
|
|
84
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
85
|
+
logger.warn(
|
|
86
|
+
`[Shell] Amplitude flag fetch aborted because it took longer than ${timeout}ms`
|
|
87
|
+
)
|
|
88
|
+
} else {
|
|
89
|
+
logger.warn("[Shell] Amplitude flag fetch failed:", { error })
|
|
90
|
+
}
|
|
82
91
|
|
|
83
92
|
// Return safe defaults - runs legacy path
|
|
84
93
|
return {
|