@playcraft/adsdk 1.0.12 → 1.0.13

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/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025-present Smoud
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2025-present Smoud
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/defines.d.ts CHANGED
@@ -1,130 +1,130 @@
1
- declare const mraid: {
2
- getVersion: () => string; // MRAID 规范必需:返回 MRAID 版本(如 "3.0")
3
- isReady: () => boolean;
4
- isViewable: () => boolean;
5
- getState: () => string;
6
- addEventListener: (
7
- event: 'viewableChange' | 'sizeChange' | 'ready' | 'audioVolumeChange' | 'stateChange' | 'error' | 'orientationChange' | 'resize',
8
- callback: (...args: any[]) => void
9
- ) => void;
10
- removeEventListener: (
11
- event: 'viewableChange' | 'sizeChange' | 'ready' | 'audioVolumeChange' | 'stateChange' | 'error' | 'orientationChange' | 'resize',
12
- callback: (...args: any[]) => void
13
- ) => void;
14
- getMaxSize: () => { width: number; height: number };
15
- openStoreUrl: () => void;
16
- open: (url: string) => void;
17
- close: () => void; // Unity Ads 必需:关闭广告
18
- getAudioVolume: () => number;
19
- fireTrackingEvent?: (event: string) => void; // Unity Ads 可选:跟踪事件
20
- preloadStore?: () => void;
21
- };
22
-
23
- declare const dapi: {
24
- addEventListener: (
25
- event: 'viewableChange' | 'adResized' | 'ready' | 'audioVolumeChange' | 'error',
26
- callback: (...args: any[]) => void
27
- ) => void;
28
- removeEventListener: (
29
- event: 'viewableChange' | 'adResized' | 'ready' | 'audioVolumeChange' | 'error',
30
- callback: (...args: any[]) => void
31
- ) => void;
32
- getScreenSize: () => { width: number; height: number };
33
- openStoreUrl: () => void;
34
- getAudioVolume: () => number;
35
- isViewable: () => boolean;
36
- isReady: () => boolean;
37
- };
38
-
39
- declare const NUC: {
40
- trigger: {
41
- convert: (destinationUrl: string) => void;
42
- tryAgain: Function;
43
- };
44
- };
45
-
46
- declare const ScPlayableAd: { onCTAClick: () => void };
47
-
48
- // Adikteev 占位符变量
49
- declare const AK_CLICK_DESTINATION_URL: string;
50
- declare const AK_CLICK_PIXEL_URL: string;
51
- declare const FbPlayableAd: { onCTAClick: () => void };
52
- declare const smxTracking: { redirect: () => void };
53
- declare const ExitApi: { exit: () => void };
54
-
55
- declare const AD_NETWORK:
56
- | 'preview'
57
- | 'applovin'
58
- | 'unity'
59
- | 'google'
60
- | 'ironsource'
61
- | 'facebook'
62
- | 'moloco'
63
- | 'mintegral'
64
- | 'vungle'
65
- | 'adcolony'
66
- | 'tapjoy'
67
- | 'snapchat'
68
- | 'tiktok'
69
- | 'appreciate'
70
- | 'chartboost'
71
- | 'pangle'
72
- | 'mytarget'
73
- | 'liftoff'
74
- | 'smadex'
75
- | 'adikteev'
76
- | 'bigabid'
77
- | 'inmobi'
78
- | 'bigoads';
79
-
80
- declare const AD_PROTOCOL: 'mraid' | 'dapi' | 'nucleo' | 'none';
81
- declare const GOOGLE_PLAY_URL: string;
82
- declare const APP_STORE_URL: string;
83
- declare const BUILD_HASH: string;
84
-
85
- interface Window {
86
- PlayableSDK: any;
87
- ADS_MRAID_CONFIG: {
88
- landUrl: string;
89
- };
90
-
91
- // AppLovin Playable Analytics
92
- // 文档: https://support.axon.ai/en/growth/promoting-your-apps/creatives/playable-analytics-integration
93
- ALPlayableAnalytics?: {
94
- trackEvent: (event: string) => void;
95
- };
96
-
97
- // BigoAds SDK
98
- // 文档: https://www.bigoads.com/help/detail?id=143&moduleId=7&currentLan=CN
99
- BGY_MRAID: {
100
- open: () => void; // 打开应用商店/推广地址
101
- gameReady: () => void; // 素材准备完毕时调用
102
- gameEnd: () => void; // 游戏结束时调用
103
- isViewable: () => boolean;
104
- addEventListener: (event: string, callback: (...args: any[]) => void) => void;
105
- removeEventListener: (event: string, callback: (...args: any[]) => void) => void;
106
- };
107
-
108
- // Mintegral functions
109
- gameReady: Function;
110
- gameEnd: Function;
111
- gameRetry: Function;
112
- install: Function;
113
- mintGameStart: Function;
114
- mintGameClose: Function;
115
-
116
- // Tapjoy functions
117
- TJ_API: {
118
- objectiveComplete: Function;
119
- playableFinished: Function;
120
- gameplayFinished: Function;
121
- setPlayableBuild: Function;
122
- setPlayableAPI: Function;
123
- click: Function;
124
- };
125
-
126
- BIGABID_BIDTIMEMACROS?: Record<string, string>
127
- INMOBI_DSPMACROS?: Record<string, string>
128
-
129
- openAppStore: Function;
130
- }
1
+ declare const mraid: {
2
+ getVersion: () => string; // MRAID 规范必需:返回 MRAID 版本(如 "3.0")
3
+ isReady: () => boolean;
4
+ isViewable: () => boolean;
5
+ getState: () => string;
6
+ addEventListener: (
7
+ event: 'viewableChange' | 'sizeChange' | 'ready' | 'audioVolumeChange' | 'stateChange' | 'error' | 'orientationChange' | 'resize',
8
+ callback: (...args: any[]) => void
9
+ ) => void;
10
+ removeEventListener: (
11
+ event: 'viewableChange' | 'sizeChange' | 'ready' | 'audioVolumeChange' | 'stateChange' | 'error' | 'orientationChange' | 'resize',
12
+ callback: (...args: any[]) => void
13
+ ) => void;
14
+ getMaxSize: () => { width: number; height: number };
15
+ openStoreUrl: () => void;
16
+ open: (url: string) => void;
17
+ close: () => void; // Unity Ads 必需:关闭广告
18
+ getAudioVolume: () => number;
19
+ fireTrackingEvent?: (event: string) => void; // Unity Ads 可选:跟踪事件
20
+ preloadStore?: () => void;
21
+ };
22
+
23
+ declare const dapi: {
24
+ addEventListener: (
25
+ event: 'viewableChange' | 'adResized' | 'ready' | 'audioVolumeChange' | 'error',
26
+ callback: (...args: any[]) => void
27
+ ) => void;
28
+ removeEventListener: (
29
+ event: 'viewableChange' | 'adResized' | 'ready' | 'audioVolumeChange' | 'error',
30
+ callback: (...args: any[]) => void
31
+ ) => void;
32
+ getScreenSize: () => { width: number; height: number };
33
+ openStoreUrl: () => void;
34
+ getAudioVolume: () => number;
35
+ isViewable: () => boolean;
36
+ isReady: () => boolean;
37
+ };
38
+
39
+ declare const NUC: {
40
+ trigger: {
41
+ convert: (destinationUrl: string) => void;
42
+ tryAgain: Function;
43
+ };
44
+ };
45
+
46
+ declare const ScPlayableAd: { onCTAClick: () => void };
47
+
48
+ // Adikteev 占位符变量
49
+ declare const AK_CLICK_DESTINATION_URL: string;
50
+ declare const AK_CLICK_PIXEL_URL: string;
51
+ declare const FbPlayableAd: { onCTAClick: () => void };
52
+ declare const smxTracking: { redirect: () => void };
53
+ declare const ExitApi: { exit: () => void };
54
+
55
+ declare const AD_NETWORK:
56
+ | 'preview'
57
+ | 'applovin'
58
+ | 'unity'
59
+ | 'google'
60
+ | 'ironsource'
61
+ | 'facebook'
62
+ | 'moloco'
63
+ | 'mintegral'
64
+ | 'vungle'
65
+ | 'adcolony'
66
+ | 'tapjoy'
67
+ | 'snapchat'
68
+ | 'tiktok'
69
+ | 'appreciate'
70
+ | 'chartboost'
71
+ | 'pangle'
72
+ | 'mytarget'
73
+ | 'liftoff'
74
+ | 'smadex'
75
+ | 'adikteev'
76
+ | 'bigabid'
77
+ | 'inmobi'
78
+ | 'bigoads';
79
+
80
+ declare const AD_PROTOCOL: 'mraid' | 'dapi' | 'nucleo' | 'none';
81
+ declare const GOOGLE_PLAY_URL: string;
82
+ declare const APP_STORE_URL: string;
83
+ declare const BUILD_HASH: string;
84
+
85
+ interface Window {
86
+ PlayableSDK: any;
87
+ ADS_MRAID_CONFIG: {
88
+ landUrl: string;
89
+ };
90
+
91
+ // AppLovin Playable Analytics
92
+ // 文档: https://support.axon.ai/en/growth/promoting-your-apps/creatives/playable-analytics-integration
93
+ ALPlayableAnalytics?: {
94
+ trackEvent: (event: string) => void;
95
+ };
96
+
97
+ // BigoAds SDK
98
+ // 文档: https://www.bigoads.com/help/detail?id=143&moduleId=7&currentLan=CN
99
+ BGY_MRAID: {
100
+ open: () => void; // 打开应用商店/推广地址
101
+ gameReady: () => void; // 素材准备完毕时调用
102
+ gameEnd: () => void; // 游戏结束时调用
103
+ isViewable: () => boolean;
104
+ addEventListener: (event: string, callback: (...args: any[]) => void) => void;
105
+ removeEventListener: (event: string, callback: (...args: any[]) => void) => void;
106
+ };
107
+
108
+ // Mintegral functions
109
+ gameReady: Function;
110
+ gameEnd: Function;
111
+ gameRetry: Function;
112
+ install: Function;
113
+ mintGameStart: Function;
114
+ mintGameClose: Function;
115
+
116
+ // Tapjoy functions
117
+ TJ_API: {
118
+ objectiveComplete: Function;
119
+ playableFinished: Function;
120
+ gameplayFinished: Function;
121
+ setPlayableBuild: Function;
122
+ setPlayableAPI: Function;
123
+ click: Function;
124
+ };
125
+
126
+ BIGABID_BIDTIMEMACROS?: Record<string, string>
127
+ INMOBI_DSPMACROS?: Record<string, string>
128
+
129
+ openAppStore: Function;
130
+ }
package/dist/esm/index.js CHANGED
@@ -693,6 +693,73 @@ function removeWechatGuide() {
693
693
  }
694
694
  }
695
695
 
696
+ // src/theme-config.ts
697
+ function extractDefaultsFromSchema(schema) {
698
+ if (!schema || typeof schema !== "object") return void 0;
699
+ if (schema.type === "object" && schema.properties) {
700
+ const result = {};
701
+ for (const [key, propSchema] of Object.entries(schema.properties)) {
702
+ const val = extractDefaultsFromSchema(propSchema);
703
+ if (val !== void 0) {
704
+ result[key] = val;
705
+ }
706
+ }
707
+ return Object.keys(result).length > 0 ? result : void 0;
708
+ }
709
+ if ("default" in schema) {
710
+ return schema.default;
711
+ }
712
+ return void 0;
713
+ }
714
+ function resolveImagePaths(config, assetRecordByPath) {
715
+ if (!assetRecordByPath || !config || typeof config !== "object") return;
716
+ for (const key of Object.keys(config)) {
717
+ const value = config[key];
718
+ if (typeof value === "string") {
719
+ if (assetRecordByPath[value]) {
720
+ config[key] = assetRecordByPath[value];
721
+ }
722
+ } else if (value !== null && typeof value === "object" && !Array.isArray(value)) {
723
+ resolveImagePaths(value, assetRecordByPath);
724
+ }
725
+ }
726
+ }
727
+ var _cachedConfig = null;
728
+ function deepMerge(target, source) {
729
+ for (const key of Object.keys(source)) {
730
+ const srcVal = source[key];
731
+ const tgtVal = target[key];
732
+ if (srcVal !== null && typeof srcVal === "object" && !Array.isArray(srcVal) && tgtVal !== null && typeof tgtVal === "object" && !Array.isArray(tgtVal)) {
733
+ deepMerge(tgtVal, srcVal);
734
+ } else if (srcVal !== void 0) {
735
+ target[key] = srcVal;
736
+ }
737
+ }
738
+ return target;
739
+ }
740
+ function setConfig(configList, config) {
741
+ const { assetRecordByPath } = config;
742
+ const resolvedConfigs = configList.map((item) => {
743
+ var _a;
744
+ if (!item) return {};
745
+ return item.$schema ? (_a = extractDefaultsFromSchema(item)) != null ? _a : {} : item;
746
+ });
747
+ const [first, ...rest] = resolvedConfigs;
748
+ const mergedConfig = JSON.parse(JSON.stringify(first));
749
+ for (const data of rest) {
750
+ deepMerge(mergedConfig, data);
751
+ }
752
+ resolveImagePaths(mergedConfig, assetRecordByPath);
753
+ _cachedConfig = mergedConfig;
754
+ }
755
+ function getConfig() {
756
+ if (!_cachedConfig) {
757
+ console.warn("[PlayableSDK] Theme config not initialized. Call setConfig() first.");
758
+ return {};
759
+ }
760
+ return _cachedConfig;
761
+ }
762
+
696
763
  // src/core.ts
697
764
  var destinationUrl = "";
698
765
  var isSDKInitialized = false;
@@ -1439,9 +1506,43 @@ var _sdk = class _sdk {
1439
1506
  static isGoogle() {
1440
1507
  return _sdk.getCurChannel() === "google";
1441
1508
  }
1509
+ /**
1510
+ * 设置主题配置,支持传入多份 JSON5 配置。
1511
+ * 每一份配置都可以是 JSON Schema(带 $schema 字段),会自动提取其中的 default 值。
1512
+ * 所有配置按顺序依次深度合并,后面的优先级更高。
1513
+ *
1514
+ * @param configList - 配置数组,每一项可以是:
1515
+ * - JSON Schema(带 $schema 字段):自动提取 default 值后参与合并
1516
+ * - 普通配置对象:直接参与合并
1517
+ * @param config - 额外配置项
1518
+ * - config.assetRecordByPath: 相对路径到已解析 URL 的映射
1519
+ *
1520
+ * @example
1521
+ * sdk.setConfig(
1522
+ * [schemaA, schemaB, themeData],
1523
+ * { assetRecordByPath: imageAssets }
1524
+ * );
1525
+ */
1526
+ static setConfig(configList, config) {
1527
+ setConfig(configList, config);
1528
+ }
1529
+ /**
1530
+ * 获取合并后的主题配置。
1531
+ * 返回 schema 默认值与用户主题数据深度合并后的结果。
1532
+ * 必须先调用 sdk.setConfig() 才能使用此方法。
1533
+ *
1534
+ * @returns 合并后的主题配置对象
1535
+ *
1536
+ * @example
1537
+ * const config = sdk.getConfig();
1538
+ * console.log(config.primaryColor); // '#ff0000'
1539
+ */
1540
+ static getConfig() {
1541
+ return getConfig();
1542
+ }
1442
1543
  };
1443
1544
  /** Current version of the SDK */
1444
- _sdk.version = "1.0.12";
1545
+ _sdk.version = "1.0.13";
1445
1546
  /** Current maximum width of the playable ad container in pixels */
1446
1547
  _sdk.maxWidth = Math.floor(window.innerWidth);
1447
1548
  /** Current maximum height of the playable ad container in pixels */
@@ -695,6 +695,73 @@
695
695
  }
696
696
  }
697
697
 
698
+ // src/theme-config.ts
699
+ function extractDefaultsFromSchema(schema) {
700
+ if (!schema || typeof schema !== "object") return void 0;
701
+ if (schema.type === "object" && schema.properties) {
702
+ const result = {};
703
+ for (const [key, propSchema] of Object.entries(schema.properties)) {
704
+ const val = extractDefaultsFromSchema(propSchema);
705
+ if (val !== void 0) {
706
+ result[key] = val;
707
+ }
708
+ }
709
+ return Object.keys(result).length > 0 ? result : void 0;
710
+ }
711
+ if ("default" in schema) {
712
+ return schema.default;
713
+ }
714
+ return void 0;
715
+ }
716
+ function resolveImagePaths(config, assetRecordByPath) {
717
+ if (!assetRecordByPath || !config || typeof config !== "object") return;
718
+ for (const key of Object.keys(config)) {
719
+ const value = config[key];
720
+ if (typeof value === "string") {
721
+ if (assetRecordByPath[value]) {
722
+ config[key] = assetRecordByPath[value];
723
+ }
724
+ } else if (value !== null && typeof value === "object" && !Array.isArray(value)) {
725
+ resolveImagePaths(value, assetRecordByPath);
726
+ }
727
+ }
728
+ }
729
+ var _cachedConfig = null;
730
+ function deepMerge(target, source) {
731
+ for (const key of Object.keys(source)) {
732
+ const srcVal = source[key];
733
+ const tgtVal = target[key];
734
+ if (srcVal !== null && typeof srcVal === "object" && !Array.isArray(srcVal) && tgtVal !== null && typeof tgtVal === "object" && !Array.isArray(tgtVal)) {
735
+ deepMerge(tgtVal, srcVal);
736
+ } else if (srcVal !== void 0) {
737
+ target[key] = srcVal;
738
+ }
739
+ }
740
+ return target;
741
+ }
742
+ function setConfig(configList, config) {
743
+ const { assetRecordByPath } = config;
744
+ const resolvedConfigs = configList.map((item) => {
745
+ var _a;
746
+ if (!item) return {};
747
+ return item.$schema ? (_a = extractDefaultsFromSchema(item)) != null ? _a : {} : item;
748
+ });
749
+ const [first, ...rest] = resolvedConfigs;
750
+ const mergedConfig = JSON.parse(JSON.stringify(first));
751
+ for (const data of rest) {
752
+ deepMerge(mergedConfig, data);
753
+ }
754
+ resolveImagePaths(mergedConfig, assetRecordByPath);
755
+ _cachedConfig = mergedConfig;
756
+ }
757
+ function getConfig() {
758
+ if (!_cachedConfig) {
759
+ console.warn("[PlayableSDK] Theme config not initialized. Call setConfig() first.");
760
+ return {};
761
+ }
762
+ return _cachedConfig;
763
+ }
764
+
698
765
  // src/core.ts
699
766
  var destinationUrl = "";
700
767
  var isSDKInitialized = false;
@@ -1441,9 +1508,43 @@
1441
1508
  static isGoogle() {
1442
1509
  return _sdk.getCurChannel() === "google";
1443
1510
  }
1511
+ /**
1512
+ * 设置主题配置,支持传入多份 JSON5 配置。
1513
+ * 每一份配置都可以是 JSON Schema(带 $schema 字段),会自动提取其中的 default 值。
1514
+ * 所有配置按顺序依次深度合并,后面的优先级更高。
1515
+ *
1516
+ * @param configList - 配置数组,每一项可以是:
1517
+ * - JSON Schema(带 $schema 字段):自动提取 default 值后参与合并
1518
+ * - 普通配置对象:直接参与合并
1519
+ * @param config - 额外配置项
1520
+ * - config.assetRecordByPath: 相对路径到已解析 URL 的映射
1521
+ *
1522
+ * @example
1523
+ * sdk.setConfig(
1524
+ * [schemaA, schemaB, themeData],
1525
+ * { assetRecordByPath: imageAssets }
1526
+ * );
1527
+ */
1528
+ static setConfig(configList, config) {
1529
+ setConfig(configList, config);
1530
+ }
1531
+ /**
1532
+ * 获取合并后的主题配置。
1533
+ * 返回 schema 默认值与用户主题数据深度合并后的结果。
1534
+ * 必须先调用 sdk.setConfig() 才能使用此方法。
1535
+ *
1536
+ * @returns 合并后的主题配置对象
1537
+ *
1538
+ * @example
1539
+ * const config = sdk.getConfig();
1540
+ * console.log(config.primaryColor); // '#ff0000'
1541
+ */
1542
+ static getConfig() {
1543
+ return getConfig();
1544
+ }
1444
1545
  };
1445
1546
  /** Current version of the SDK */
1446
- _sdk.version = "1.0.12";
1547
+ _sdk.version = "1.0.13";
1447
1548
  /** Current maximum width of the playable ad container in pixels */
1448
1549
  _sdk.maxWidth = Math.floor(window.innerWidth);
1449
1550
  /** Current maximum height of the playable ad container in pixels */
package/dist/index.d.mts CHANGED
@@ -260,6 +260,36 @@ declare class sdk {
260
260
  * 判断是否是 Google
261
261
  */
262
262
  static isGoogle(): boolean;
263
+ /**
264
+ * 设置主题配置,支持传入多份 JSON5 配置。
265
+ * 每一份配置都可以是 JSON Schema(带 $schema 字段),会自动提取其中的 default 值。
266
+ * 所有配置按顺序依次深度合并,后面的优先级更高。
267
+ *
268
+ * @param configList - 配置数组,每一项可以是:
269
+ * - JSON Schema(带 $schema 字段):自动提取 default 值后参与合并
270
+ * - 普通配置对象:直接参与合并
271
+ * @param config - 额外配置项
272
+ * - config.assetRecordByPath: 相对路径到已解析 URL 的映射
273
+ *
274
+ * @example
275
+ * sdk.setConfig(
276
+ * [schemaA, schemaB, themeData],
277
+ * { assetRecordByPath: imageAssets }
278
+ * );
279
+ */
280
+ static setConfig(configList: any[], config: any): void;
281
+ /**
282
+ * 获取合并后的主题配置。
283
+ * 返回 schema 默认值与用户主题数据深度合并后的结果。
284
+ * 必须先调用 sdk.setConfig() 才能使用此方法。
285
+ *
286
+ * @returns 合并后的主题配置对象
287
+ *
288
+ * @example
289
+ * const config = sdk.getConfig();
290
+ * console.log(config.primaryColor); // '#ff0000'
291
+ */
292
+ static getConfig(): Record<string, any>;
263
293
  }
264
294
 
265
295
  /**
package/dist/index.d.ts CHANGED
@@ -260,6 +260,36 @@ declare class sdk {
260
260
  * 判断是否是 Google
261
261
  */
262
262
  static isGoogle(): boolean;
263
+ /**
264
+ * 设置主题配置,支持传入多份 JSON5 配置。
265
+ * 每一份配置都可以是 JSON Schema(带 $schema 字段),会自动提取其中的 default 值。
266
+ * 所有配置按顺序依次深度合并,后面的优先级更高。
267
+ *
268
+ * @param configList - 配置数组,每一项可以是:
269
+ * - JSON Schema(带 $schema 字段):自动提取 default 值后参与合并
270
+ * - 普通配置对象:直接参与合并
271
+ * @param config - 额外配置项
272
+ * - config.assetRecordByPath: 相对路径到已解析 URL 的映射
273
+ *
274
+ * @example
275
+ * sdk.setConfig(
276
+ * [schemaA, schemaB, themeData],
277
+ * { assetRecordByPath: imageAssets }
278
+ * );
279
+ */
280
+ static setConfig(configList: any[], config: any): void;
281
+ /**
282
+ * 获取合并后的主题配置。
283
+ * 返回 schema 默认值与用户主题数据深度合并后的结果。
284
+ * 必须先调用 sdk.setConfig() 才能使用此方法。
285
+ *
286
+ * @returns 合并后的主题配置对象
287
+ *
288
+ * @example
289
+ * const config = sdk.getConfig();
290
+ * console.log(config.primaryColor); // '#ff0000'
291
+ */
292
+ static getConfig(): Record<string, any>;
263
293
  }
264
294
 
265
295
  /**
package/dist/index.js CHANGED
@@ -724,6 +724,73 @@ function removeWechatGuide() {
724
724
  }
725
725
  }
726
726
 
727
+ // src/theme-config.ts
728
+ function extractDefaultsFromSchema(schema) {
729
+ if (!schema || typeof schema !== "object") return void 0;
730
+ if (schema.type === "object" && schema.properties) {
731
+ const result = {};
732
+ for (const [key, propSchema] of Object.entries(schema.properties)) {
733
+ const val = extractDefaultsFromSchema(propSchema);
734
+ if (val !== void 0) {
735
+ result[key] = val;
736
+ }
737
+ }
738
+ return Object.keys(result).length > 0 ? result : void 0;
739
+ }
740
+ if ("default" in schema) {
741
+ return schema.default;
742
+ }
743
+ return void 0;
744
+ }
745
+ function resolveImagePaths(config, assetRecordByPath) {
746
+ if (!assetRecordByPath || !config || typeof config !== "object") return;
747
+ for (const key of Object.keys(config)) {
748
+ const value = config[key];
749
+ if (typeof value === "string") {
750
+ if (assetRecordByPath[value]) {
751
+ config[key] = assetRecordByPath[value];
752
+ }
753
+ } else if (value !== null && typeof value === "object" && !Array.isArray(value)) {
754
+ resolveImagePaths(value, assetRecordByPath);
755
+ }
756
+ }
757
+ }
758
+ var _cachedConfig = null;
759
+ function deepMerge(target, source) {
760
+ for (const key of Object.keys(source)) {
761
+ const srcVal = source[key];
762
+ const tgtVal = target[key];
763
+ if (srcVal !== null && typeof srcVal === "object" && !Array.isArray(srcVal) && tgtVal !== null && typeof tgtVal === "object" && !Array.isArray(tgtVal)) {
764
+ deepMerge(tgtVal, srcVal);
765
+ } else if (srcVal !== void 0) {
766
+ target[key] = srcVal;
767
+ }
768
+ }
769
+ return target;
770
+ }
771
+ function setConfig(configList, config) {
772
+ const { assetRecordByPath } = config;
773
+ const resolvedConfigs = configList.map((item) => {
774
+ var _a;
775
+ if (!item) return {};
776
+ return item.$schema ? (_a = extractDefaultsFromSchema(item)) != null ? _a : {} : item;
777
+ });
778
+ const [first, ...rest] = resolvedConfigs;
779
+ const mergedConfig = JSON.parse(JSON.stringify(first));
780
+ for (const data of rest) {
781
+ deepMerge(mergedConfig, data);
782
+ }
783
+ resolveImagePaths(mergedConfig, assetRecordByPath);
784
+ _cachedConfig = mergedConfig;
785
+ }
786
+ function getConfig() {
787
+ if (!_cachedConfig) {
788
+ console.warn("[PlayableSDK] Theme config not initialized. Call setConfig() first.");
789
+ return {};
790
+ }
791
+ return _cachedConfig;
792
+ }
793
+
727
794
  // src/core.ts
728
795
  var destinationUrl = "";
729
796
  var isSDKInitialized = false;
@@ -1470,9 +1537,43 @@ var _sdk = class _sdk {
1470
1537
  static isGoogle() {
1471
1538
  return _sdk.getCurChannel() === "google";
1472
1539
  }
1540
+ /**
1541
+ * 设置主题配置,支持传入多份 JSON5 配置。
1542
+ * 每一份配置都可以是 JSON Schema(带 $schema 字段),会自动提取其中的 default 值。
1543
+ * 所有配置按顺序依次深度合并,后面的优先级更高。
1544
+ *
1545
+ * @param configList - 配置数组,每一项可以是:
1546
+ * - JSON Schema(带 $schema 字段):自动提取 default 值后参与合并
1547
+ * - 普通配置对象:直接参与合并
1548
+ * @param config - 额外配置项
1549
+ * - config.assetRecordByPath: 相对路径到已解析 URL 的映射
1550
+ *
1551
+ * @example
1552
+ * sdk.setConfig(
1553
+ * [schemaA, schemaB, themeData],
1554
+ * { assetRecordByPath: imageAssets }
1555
+ * );
1556
+ */
1557
+ static setConfig(configList, config) {
1558
+ setConfig(configList, config);
1559
+ }
1560
+ /**
1561
+ * 获取合并后的主题配置。
1562
+ * 返回 schema 默认值与用户主题数据深度合并后的结果。
1563
+ * 必须先调用 sdk.setConfig() 才能使用此方法。
1564
+ *
1565
+ * @returns 合并后的主题配置对象
1566
+ *
1567
+ * @example
1568
+ * const config = sdk.getConfig();
1569
+ * console.log(config.primaryColor); // '#ff0000'
1570
+ */
1571
+ static getConfig() {
1572
+ return getConfig();
1573
+ }
1473
1574
  };
1474
1575
  /** Current version of the SDK */
1475
- _sdk.version = "1.0.12";
1576
+ _sdk.version = "1.0.13";
1476
1577
  /** Current maximum width of the playable ad container in pixels */
1477
1578
  _sdk.maxWidth = Math.floor(window.innerWidth);
1478
1579
  /** Current maximum height of the playable ad container in pixels */
package/package.json CHANGED
@@ -1,52 +1,52 @@
1
- {
2
- "name": "@playcraft/adsdk",
3
- "version": "1.0.12",
4
- "description": "统一的 Playable SDK,支持 MRAID、Google、Facebook、Vungle、BigoAds 等多广告渠道",
5
- "main": "dist/index.js",
6
- "module": "dist/esm/index.js",
7
- "types": "dist/index.d.ts",
8
- "repository": {
9
- "type": "git"
10
- },
11
- "files": [
12
- "dist",
13
- "LICENSE",
14
- "defines.d.ts"
15
- ],
16
- "scripts": {
17
- "build": "npx tsup",
18
- "test": "jest",
19
- "deploy": "npm run build && node scripts/publish.js"
20
- },
21
- "author": "Tencent ADS Team",
22
- "license": "MIT",
23
- "devDependencies": {
24
- "@types/jest": "^29.5.14",
25
- "jest": "^29.7.0",
26
- "jest-environment-jsdom": "^29.7.0",
27
- "ts-jest": "^29.2.5",
28
- "tsup": "^8.4.0",
29
- "typescript": "^5.7.2"
30
- },
31
- "keywords": [
32
- "playable",
33
- "sdk",
34
- "playable-sdk",
35
- "PlayableSDK",
36
- "playable-ads",
37
- "html5",
38
- "tencent",
39
- "bigoads",
40
- "mraid",
41
- "google-ads",
42
- "facebook-playable",
43
- "unity-ads",
44
- "vungle",
45
- "ironsource",
46
- "javascript-sdk",
47
- "typescript-sdk"
48
- ],
49
- "publishConfig": {
50
- "registry": "https://mirrors.tencent.com/npm/"
51
- }
52
- }
1
+ {
2
+ "name": "@playcraft/adsdk",
3
+ "version": "1.0.13",
4
+ "description": "统一的 Playable SDK,支持 MRAID、Google、Facebook、Vungle、BigoAds 等多广告渠道",
5
+ "main": "dist/index.js",
6
+ "module": "dist/esm/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "repository": {
9
+ "type": "git"
10
+ },
11
+ "files": [
12
+ "dist",
13
+ "LICENSE",
14
+ "defines.d.ts"
15
+ ],
16
+ "scripts": {
17
+ "build": "npx tsup",
18
+ "test": "jest",
19
+ "deploy": "npm run build && node scripts/publish.js"
20
+ },
21
+ "author": "Tencent ADS Team",
22
+ "license": "MIT",
23
+ "devDependencies": {
24
+ "@types/jest": "^29.5.14",
25
+ "jest": "^29.7.0",
26
+ "jest-environment-jsdom": "^29.7.0",
27
+ "ts-jest": "^29.2.5",
28
+ "tsup": "^8.4.0",
29
+ "typescript": "^5.7.2"
30
+ },
31
+ "keywords": [
32
+ "playable",
33
+ "sdk",
34
+ "playable-sdk",
35
+ "PlayableSDK",
36
+ "playable-ads",
37
+ "html5",
38
+ "tencent",
39
+ "bigoads",
40
+ "mraid",
41
+ "google-ads",
42
+ "facebook-playable",
43
+ "unity-ads",
44
+ "vungle",
45
+ "ironsource",
46
+ "javascript-sdk",
47
+ "typescript-sdk"
48
+ ],
49
+ "publishConfig": {
50
+ "registry": "https://mirrors.tencent.com/npm/"
51
+ }
52
+ }