@codeimplants/version-control 1.0.4 → 1.0.6

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/dist/client.js CHANGED
@@ -2,10 +2,10 @@ export async function fetchRules(config) {
2
2
  const controller = new AbortController();
3
3
  const id = setTimeout(() => controller.abort(), config.timeout || 8000);
4
4
  const body = {
5
- appId: config.appId || "unknown",
6
- platform: config.platform || "web",
7
- currentVersion: config.version || "1.0.0",
8
- environment: "prod" // Default to prod
5
+ appId: config.appId, // Send undefined if missing
6
+ platform: config.platform, // Send undefined if missing
7
+ currentVersion: config.version, // Send undefined if missing
8
+ environment: "prod"
9
9
  };
10
10
  if (config.debug) {
11
11
  console.log("[VC-SDK] Request Body:", body);
@@ -1,5 +1,5 @@
1
1
  import { Platform } from "./types";
2
- export declare function detectPlatform(): Promise<Platform>;
3
- export declare function detectVersion(): Promise<string>;
4
- export declare function detectAppId(): Promise<string>;
2
+ export declare function detectPlatform(): Promise<Platform | undefined>;
3
+ export declare function detectVersion(): Promise<string | undefined>;
4
+ export declare function detectAppId(): Promise<string | undefined>;
5
5
  //# sourceMappingURL=detector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../src/detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,wBAAsB,cAAc,IAAI,OAAO,CAAC,QAAQ,CAAC,CAoBxD;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,CAoBrD;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAoBnD"}
1
+ {"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../src/detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,wBAAsB,cAAc,IAAI,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAoDpE;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA+CjE;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA8C/D"}
package/dist/detector.js CHANGED
@@ -1,29 +1,63 @@
1
1
  export async function detectPlatform() {
2
- var _a, _b;
3
- if (typeof window === "undefined")
4
- return "web";
2
+ var _a, _b, _c;
3
+ if (typeof window === "undefined") {
4
+ // Node environment or similar
5
+ return undefined;
6
+ }
5
7
  const win = window;
6
- // Check for Capacitor
7
- if ((_a = win.Capacitor) === null || _a === void 0 ? void 0 : _a.getPlatform) {
8
- const platform = win.Capacitor.getPlatform();
9
- if (platform === "android" || platform === "ios")
10
- return platform;
8
+ try {
9
+ // 1. Try React Native detection
10
+ if (((_a = win.navigator) === null || _a === void 0 ? void 0 : _a.product) === "ReactNative") {
11
+ // Attempt to dynamically require Platform from react-native
12
+ // This works in Metro bundler environments
13
+ try {
14
+ // @ts-ignore
15
+ const RN = require("react-native");
16
+ if (RN && RN.Platform && (RN.Platform.OS === "android" || RN.Platform.OS === "ios")) {
17
+ return RN.Platform.OS;
18
+ }
19
+ }
20
+ catch (e) {
21
+ // ignore
22
+ }
23
+ // Fallback for RN if require fails but we know it's RN
24
+ // We might return "android" or "ios" if we can infer from userAgent, otherwise return undefined to let backend decide or user override
25
+ const ua = ((_c = (_b = win.navigator) === null || _b === void 0 ? void 0 : _b.userAgent) === null || _c === void 0 ? void 0 : _c.toLowerCase()) || "";
26
+ if (ua.includes("android"))
27
+ return "android";
28
+ if (ua.includes("iphone") || ua.includes("ipad"))
29
+ return "ios";
30
+ return undefined; // Let SDK user provide it explicitly if we can't be sure
31
+ }
32
+ // 2. Try Capacitor detection
33
+ if (win.Capacitor) {
34
+ if (win.Capacitor.isNativePlatform()) {
35
+ const platform = win.Capacitor.getPlatform();
36
+ if (platform === "android" || platform === "ios")
37
+ return platform;
38
+ }
39
+ // Even if not native, Capacitor.getPlatform() might return 'web'
40
+ // We can check if we are truly in a Capacitor shell
41
+ }
42
+ // 3. Browser / Web detection
43
+ const ua = navigator.userAgent.toLowerCase();
44
+ if (ua.includes("android"))
45
+ return "android";
46
+ if (ua.includes("iphone") || ua.includes("ipad") || ua.includes("ipod"))
47
+ return "ios";
48
+ return "web";
11
49
  }
12
- if (((_b = win.navigator) === null || _b === void 0 ? void 0 : _b.product) === "ReactNative") {
13
- return "all";
50
+ catch (e) {
51
+ console.warn("[VC-SDK] Error detecting platform:", e);
52
+ return undefined;
14
53
  }
15
- const ua = navigator.userAgent.toLowerCase();
16
- if (ua.includes("android"))
17
- return "android";
18
- if (ua.includes("iphone") || ua.includes("ipad") || ua.includes("ipod"))
19
- return "ios";
20
- return "web";
21
54
  }
22
55
  export async function detectVersion() {
23
- var _a, _b;
56
+ var _a, _b, _c;
24
57
  const win = window;
25
58
  if (typeof window === "undefined")
26
- return "1.0.0";
59
+ return undefined;
60
+ // 1. Capacitor
27
61
  if ((_b = (_a = win.Capacitor) === null || _a === void 0 ? void 0 : _a.Plugins) === null || _b === void 0 ? void 0 : _b.App) {
28
62
  try {
29
63
  const info = await win.Capacitor.Plugins.App.getInfo();
@@ -34,18 +68,47 @@ export async function detectVersion() {
34
68
  // ignore
35
69
  }
36
70
  }
71
+ // 2. React Native (Expo / DeviceInfo)
72
+ try {
73
+ if (((_c = win.navigator) === null || _c === void 0 ? void 0 : _c.product) === "ReactNative") {
74
+ // Try Expo Constants
75
+ try {
76
+ // @ts-ignore
77
+ const Constants = require("expo-constants").default;
78
+ if (Constants && Constants.manifest && Constants.manifest.version) {
79
+ return Constants.manifest.version;
80
+ }
81
+ if (Constants && Constants.expoConfig && Constants.expoConfig.version) {
82
+ return Constants.expoConfig.version;
83
+ }
84
+ }
85
+ catch (e) { }
86
+ // Try replace-native-device-info
87
+ try {
88
+ // @ts-ignore
89
+ const DeviceInfo = require("react-native-device-info");
90
+ if (DeviceInfo && DeviceInfo.getVersion) {
91
+ return DeviceInfo.getVersion();
92
+ }
93
+ }
94
+ catch (e) { }
95
+ }
96
+ }
97
+ catch (e) { }
98
+ // 3. Globals
37
99
  const versionKeys = ["APP_VERSION", "__VERSION__", "VERSION", "packageVersion"];
38
100
  for (const key of versionKeys) {
39
101
  if (win[key])
40
102
  return win[key];
41
103
  }
42
- return "1.0.0";
104
+ return undefined;
43
105
  }
44
106
  export async function detectAppId() {
45
- var _a, _b;
107
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
46
108
  const win = window;
47
109
  if (typeof window === "undefined")
48
- return "unknown.app";
110
+ return undefined;
111
+ // 1. Capacitor
49
112
  if ((_b = (_a = win.Capacitor) === null || _a === void 0 ? void 0 : _a.Plugins) === null || _b === void 0 ? void 0 : _b.App) {
50
113
  try {
51
114
  const info = await win.Capacitor.Plugins.App.getInfo();
@@ -56,10 +119,41 @@ export async function detectAppId() {
56
119
  // ignore
57
120
  }
58
121
  }
122
+ // 2. React Native (Expo / DeviceInfo)
123
+ try {
124
+ if (((_c = win.navigator) === null || _c === void 0 ? void 0 : _c.product) === "ReactNative") {
125
+ // Try Expo Constants
126
+ try {
127
+ // @ts-ignore
128
+ const Constants = require("expo-constants").default;
129
+ // Expo Go app ID or standalone bundle ID
130
+ if ((_e = (_d = Constants === null || Constants === void 0 ? void 0 : Constants.manifest) === null || _d === void 0 ? void 0 : _d.android) === null || _e === void 0 ? void 0 : _e.package)
131
+ return Constants.manifest.android.package;
132
+ if ((_g = (_f = Constants === null || Constants === void 0 ? void 0 : Constants.manifest) === null || _f === void 0 ? void 0 : _f.ios) === null || _g === void 0 ? void 0 : _g.bundleIdentifier)
133
+ return Constants.manifest.ios.bundleIdentifier;
134
+ if ((_j = (_h = Constants === null || Constants === void 0 ? void 0 : Constants.expoConfig) === null || _h === void 0 ? void 0 : _h.android) === null || _j === void 0 ? void 0 : _j.package)
135
+ return Constants.expoConfig.android.package;
136
+ if ((_l = (_k = Constants === null || Constants === void 0 ? void 0 : Constants.expoConfig) === null || _k === void 0 ? void 0 : _k.ios) === null || _l === void 0 ? void 0 : _l.bundleIdentifier)
137
+ return Constants.expoConfig.ios.bundleIdentifier;
138
+ }
139
+ catch (e) { }
140
+ // Try react-native-device-info
141
+ try {
142
+ // @ts-ignore
143
+ const DeviceInfo = require("react-native-device-info");
144
+ if (DeviceInfo && DeviceInfo.getBundleId) {
145
+ return DeviceInfo.getBundleId();
146
+ }
147
+ }
148
+ catch (e) { }
149
+ }
150
+ }
151
+ catch (e) { }
152
+ // 3. Globals
59
153
  const idKeys = ["APP_ID", "__APP_ID__", "BUNDLE_ID", "PACKAGE_NAME"];
60
154
  for (const key of idKeys) {
61
155
  if (win[key])
62
156
  return win[key];
63
157
  }
64
- return "unknown.app";
158
+ return undefined;
65
159
  }
package/dist/sdk.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { VCConfig, VCDecision } from "./types";
2
2
  export declare class VersionSDK {
3
3
  private config;
4
- static init(config: VCConfig | string, apiKey?: string): VersionSDK;
5
- static check(config: VCConfig | string, apiKey?: string): Promise<VCDecision>;
4
+ static init(config: VCConfig | string, apiKey?: string, debug?: boolean): VersionSDK;
5
+ static check(config: VCConfig | string, apiKey?: string, debug?: boolean): Promise<VCDecision>;
6
6
  checkVersion(): Promise<VCDecision>;
7
7
  }
8
8
  //# sourceMappingURL=sdk.d.ts.map
package/dist/sdk.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../src/sdk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAK/C,qBAAa,UAAU;IACnB,OAAO,CAAC,MAAM,CAAY;IAE1B,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;WAczC,KAAK,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAI7E,YAAY,IAAI,OAAO,CAAC,UAAU,CAAC;CAsD5C"}
1
+ {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../src/sdk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAK/C,qBAAa,UAAU;IACnB,OAAO,CAAC,MAAM,CAAY;IAE1B,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;WAc1D,KAAK,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAI9F,YAAY,IAAI,OAAO,CAAC,UAAU,CAAC;CAsE5C"}
package/dist/sdk.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import { fetchRules } from "./client";
2
2
  import { detectAppId, detectPlatform, detectVersion } from "./detector";
3
3
  export class VersionSDK {
4
- static init(config, apiKey) {
4
+ static init(config, apiKey, debug) {
5
5
  const sdk = new VersionSDK();
6
6
  if (typeof config === "string") {
7
7
  sdk.config = {
8
8
  backendUrl: config,
9
9
  apiKey: apiKey,
10
- debug: false
10
+ debug: debug
11
11
  };
12
12
  }
13
13
  else {
@@ -15,17 +15,28 @@ export class VersionSDK {
15
15
  }
16
16
  return sdk;
17
17
  }
18
- static async check(config, apiKey) {
19
- return VersionSDK.init(config, apiKey).checkVersion();
18
+ static async check(config, apiKey, debug) {
19
+ return VersionSDK.init(config, apiKey, debug).checkVersion();
20
20
  }
21
21
  async checkVersion() {
22
22
  try {
23
- if (!this.config.platform)
24
- this.config.platform = await detectPlatform();
25
- if (!this.config.version)
26
- this.config.version = await detectVersion();
27
- if (!this.config.appId)
28
- this.config.appId = await detectAppId();
23
+ // Auto-detect only if NOT provided, but allow them to remain undefined if detection fails or is not desired.
24
+ // The backend should handle cases where appId or version are missing (e.g. web or simple API key check).
25
+ if (!this.config.platform) {
26
+ const detected = await detectPlatform();
27
+ if (detected !== 'web')
28
+ this.config.platform = detected;
29
+ }
30
+ if (!this.config.version) {
31
+ const detected = await detectVersion();
32
+ if (detected !== '1.0.0')
33
+ this.config.version = detected;
34
+ }
35
+ if (!this.config.appId) {
36
+ const detected = await detectAppId();
37
+ if (detected !== 'unknown.app')
38
+ this.config.appId = detected;
39
+ }
29
40
  if (this.config.debug) {
30
41
  console.log("[VC-SDK] Checking version for:", {
31
42
  appId: this.config.appId,
@@ -33,6 +44,11 @@ export class VersionSDK {
33
44
  version: this.config.version,
34
45
  url: `${this.config.backendUrl}/sdk/version/check`
35
46
  });
47
+ if (this.config.appId === 'unknown.app' || this.config.platform === 'all' || this.config.version === '1.0.0') {
48
+ console.warn("[VC-SDK] ⚠️ WARNING: Using fallback values. Auto-detection might have failed.");
49
+ console.warn("[VC-SDK] If you are using React Native, please initialize the SDK with explicit 'appId', 'platform', and 'version'.");
50
+ console.warn("[VC-SDK] Example: VersionSDK.init({ ..., platform: Platform.OS, appId: 'com.yourapp' })");
51
+ }
36
52
  }
37
53
  const response = await fetchRules(this.config);
38
54
  if (this.config.debug) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codeimplants/version-control",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "A lightweight cross-platform SDK to remotely control app version behavior such as soft update, force update, and maintenance mode using backend-driven rules, without enforcing UI.",
5
5
  "keywords": [
6
6
  "version-control",
package/src/client.ts CHANGED
@@ -5,10 +5,10 @@ export async function fetchRules(config: VCConfig) {
5
5
  const id = setTimeout(() => controller.abort(), config.timeout || 8000);
6
6
 
7
7
  const body = {
8
- appId: config.appId || "unknown",
9
- platform: config.platform || "web",
10
- currentVersion: config.version || "1.0.0",
11
- environment: "prod" // Default to prod
8
+ appId: config.appId, // Send undefined if missing
9
+ platform: config.platform, // Send undefined if missing
10
+ currentVersion: config.version, // Send undefined if missing
11
+ environment: "prod"
12
12
  };
13
13
 
14
14
  if (config.debug) {
package/src/detector.ts CHANGED
@@ -1,32 +1,64 @@
1
1
  import { Platform } from "./types";
2
2
 
3
- export async function detectPlatform(): Promise<Platform> {
4
- if (typeof window === "undefined") return "web";
3
+ export async function detectPlatform(): Promise<Platform | undefined> {
4
+ if (typeof window === "undefined") {
5
+ // Node environment or similar
6
+ return undefined;
7
+ }
5
8
 
6
9
  const win = window as any;
7
10
 
8
- // Check for Capacitor
9
- if (win.Capacitor?.getPlatform) {
10
- const platform = win.Capacitor.getPlatform();
11
- if (platform === "android" || platform === "ios") return platform as Platform;
12
- }
11
+ try {
12
+ // 1. Try React Native detection
13
+ if (win.navigator?.product === "ReactNative") {
14
+ // Attempt to dynamically require Platform from react-native
15
+ // This works in Metro bundler environments
16
+ try {
17
+ // @ts-ignore
18
+ const RN = require("react-native");
19
+ if (RN && RN.Platform && (RN.Platform.OS === "android" || RN.Platform.OS === "ios")) {
20
+ return RN.Platform.OS as Platform;
21
+ }
22
+ } catch (e) {
23
+ // ignore
24
+ }
25
+
26
+ // Fallback for RN if require fails but we know it's RN
27
+ // We might return "android" or "ios" if we can infer from userAgent, otherwise return undefined to let backend decide or user override
28
+ const ua = win.navigator?.userAgent?.toLowerCase() || "";
29
+ if (ua.includes("android")) return "android";
30
+ if (ua.includes("iphone") || ua.includes("ipad")) return "ios";
31
+
32
+ return undefined; // Let SDK user provide it explicitly if we can't be sure
33
+ }
13
34
 
14
- if (win.navigator?.product === "ReactNative") {
15
- return "all";
16
- }
35
+ // 2. Try Capacitor detection
36
+ if (win.Capacitor) {
37
+ if (win.Capacitor.isNativePlatform()) {
38
+ const platform = win.Capacitor.getPlatform();
39
+ if (platform === "android" || platform === "ios") return platform as Platform;
40
+ }
41
+ // Even if not native, Capacitor.getPlatform() might return 'web'
42
+ // We can check if we are truly in a Capacitor shell
43
+ }
17
44
 
18
- const ua = navigator.userAgent.toLowerCase();
19
- if (ua.includes("android")) return "android";
20
- if (ua.includes("iphone") || ua.includes("ipad") || ua.includes("ipod")) return "ios";
45
+ // 3. Browser / Web detection
46
+ const ua = navigator.userAgent.toLowerCase();
47
+ if (ua.includes("android")) return "android";
48
+ if (ua.includes("iphone") || ua.includes("ipad") || ua.includes("ipod")) return "ios";
21
49
 
22
- return "web";
50
+ return "web";
51
+ } catch (e) {
52
+ console.warn("[VC-SDK] Error detecting platform:", e);
53
+ return undefined;
54
+ }
23
55
  }
24
56
 
25
- export async function detectVersion(): Promise<string> {
57
+ export async function detectVersion(): Promise<string | undefined> {
26
58
  const win = window as any;
59
+ if (typeof window === "undefined") return undefined;
27
60
 
28
- if (typeof window === "undefined") return "1.0.0";
29
-
61
+ // 1. Capacitor
30
62
  if (win.Capacitor?.Plugins?.App) {
31
63
  try {
32
64
  const info = await win.Capacitor.Plugins.App.getInfo();
@@ -36,19 +68,46 @@ export async function detectVersion(): Promise<string> {
36
68
  }
37
69
  }
38
70
 
71
+ // 2. React Native (Expo / DeviceInfo)
72
+ try {
73
+ if (win.navigator?.product === "ReactNative") {
74
+ // Try Expo Constants
75
+ try {
76
+ // @ts-ignore
77
+ const Constants = require("expo-constants").default;
78
+ if (Constants && Constants.manifest && Constants.manifest.version) {
79
+ return Constants.manifest.version;
80
+ }
81
+ if (Constants && Constants.expoConfig && Constants.expoConfig.version) {
82
+ return Constants.expoConfig.version;
83
+ }
84
+ } catch (e) { }
85
+
86
+ // Try replace-native-device-info
87
+ try {
88
+ // @ts-ignore
89
+ const DeviceInfo = require("react-native-device-info");
90
+ if (DeviceInfo && DeviceInfo.getVersion) {
91
+ return DeviceInfo.getVersion();
92
+ }
93
+ } catch (e) { }
94
+ }
95
+ } catch (e) { }
96
+
97
+ // 3. Globals
39
98
  const versionKeys = ["APP_VERSION", "__VERSION__", "VERSION", "packageVersion"];
40
99
  for (const key of versionKeys) {
41
100
  if (win[key]) return win[key];
42
101
  }
43
102
 
44
- return "1.0.0";
103
+ return undefined;
45
104
  }
46
105
 
47
- export async function detectAppId(): Promise<string> {
106
+ export async function detectAppId(): Promise<string | undefined> {
48
107
  const win = window as any;
108
+ if (typeof window === "undefined") return undefined;
49
109
 
50
- if (typeof window === "undefined") return "unknown.app";
51
-
110
+ // 1. Capacitor
52
111
  if (win.Capacitor?.Plugins?.App) {
53
112
  try {
54
113
  const info = await win.Capacitor.Plugins.App.getInfo();
@@ -58,10 +117,36 @@ export async function detectAppId(): Promise<string> {
58
117
  }
59
118
  }
60
119
 
120
+ // 2. React Native (Expo / DeviceInfo)
121
+ try {
122
+ if (win.navigator?.product === "ReactNative") {
123
+ // Try Expo Constants
124
+ try {
125
+ // @ts-ignore
126
+ const Constants = require("expo-constants").default;
127
+ // Expo Go app ID or standalone bundle ID
128
+ if (Constants?.manifest?.android?.package) return Constants.manifest.android.package;
129
+ if (Constants?.manifest?.ios?.bundleIdentifier) return Constants.manifest.ios.bundleIdentifier;
130
+ if (Constants?.expoConfig?.android?.package) return Constants.expoConfig.android.package;
131
+ if (Constants?.expoConfig?.ios?.bundleIdentifier) return Constants.expoConfig.ios.bundleIdentifier;
132
+ } catch (e) { }
133
+
134
+ // Try react-native-device-info
135
+ try {
136
+ // @ts-ignore
137
+ const DeviceInfo = require("react-native-device-info");
138
+ if (DeviceInfo && DeviceInfo.getBundleId) {
139
+ return DeviceInfo.getBundleId();
140
+ }
141
+ } catch (e) { }
142
+ }
143
+ } catch (e) { }
144
+
145
+ // 3. Globals
61
146
  const idKeys = ["APP_ID", "__APP_ID__", "BUNDLE_ID", "PACKAGE_NAME"];
62
147
  for (const key of idKeys) {
63
148
  if (win[key]) return win[key];
64
149
  }
65
150
 
66
- return "unknown.app";
151
+ return undefined;
67
152
  }
package/src/sdk.ts CHANGED
@@ -6,13 +6,13 @@ import { detectAppId, detectPlatform, detectVersion } from "./detector";
6
6
  export class VersionSDK {
7
7
  private config!: VCConfig;
8
8
 
9
- static init(config: VCConfig | string, apiKey?: string) {
9
+ static init(config: VCConfig | string, apiKey?: string, debug?: boolean) {
10
10
  const sdk = new VersionSDK();
11
11
  if (typeof config === "string") {
12
12
  sdk.config = {
13
13
  backendUrl: config,
14
14
  apiKey: apiKey,
15
- debug: false
15
+ debug: debug
16
16
  };
17
17
  } else {
18
18
  sdk.config = config;
@@ -20,16 +20,26 @@ export class VersionSDK {
20
20
  return sdk;
21
21
  }
22
22
 
23
- static async check(config: VCConfig | string, apiKey?: string): Promise<VCDecision> {
24
- return VersionSDK.init(config, apiKey).checkVersion();
23
+ static async check(config: VCConfig | string, apiKey?: string, debug?: boolean): Promise<VCDecision> {
24
+ return VersionSDK.init(config, apiKey, debug).checkVersion();
25
25
  }
26
26
 
27
27
  async checkVersion(): Promise<VCDecision> {
28
28
  try {
29
- if (!this.config.platform) this.config.platform = await detectPlatform();
30
- if (!this.config.version) this.config.version = await detectVersion();
31
- if (!this.config.appId) this.config.appId = await detectAppId();
32
-
29
+ // Auto-detect only if NOT provided, but allow them to remain undefined if detection fails or is not desired.
30
+ // The backend should handle cases where appId or version are missing (e.g. web or simple API key check).
31
+ if (!this.config.platform) {
32
+ const detected = await detectPlatform();
33
+ if (detected !== 'web') this.config.platform = detected;
34
+ }
35
+ if (!this.config.version) {
36
+ const detected = await detectVersion();
37
+ if (detected !== '1.0.0') this.config.version = detected;
38
+ }
39
+ if (!this.config.appId) {
40
+ const detected = await detectAppId();
41
+ if (detected !== 'unknown.app') this.config.appId = detected;
42
+ }
33
43
  if (this.config.debug) {
34
44
  console.log("[VC-SDK] Checking version for:", {
35
45
  appId: this.config.appId,
@@ -37,6 +47,12 @@ export class VersionSDK {
37
47
  version: this.config.version,
38
48
  url: `${this.config.backendUrl}/sdk/version/check`
39
49
  });
50
+
51
+ if (this.config.appId === 'unknown.app' || this.config.platform === 'all' || this.config.version === '1.0.0') {
52
+ console.warn("[VC-SDK] ⚠️ WARNING: Using fallback values. Auto-detection might have failed.");
53
+ console.warn("[VC-SDK] If you are using React Native, please initialize the SDK with explicit 'appId', 'platform', and 'version'.");
54
+ console.warn("[VC-SDK] Example: VersionSDK.init({ ..., platform: Platform.OS, appId: 'com.yourapp' })");
55
+ }
40
56
  }
41
57
 
42
58
  const response = await fetchRules(this.config);