@playcraft/devkit 1.0.28 → 1.0.30
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/cli/bin/playable-scripts.js +6 -44
- package/cli/commands/build.js +40 -220
- package/cli/commands/builds.js +2 -13
- package/cli/commands/dev.js +1 -7
- package/cli/commands/pack.js +39 -308
- package/cli/commands/vite-dev.js +1 -7
- package/core/batch-build.js +149 -1255
- package/core/constants.js +2 -16
- package/core/cos-uploader.js +24 -286
- package/core/index.d.ts +4 -1
- package/core/index.js +7 -76
- package/core/loaders/gltf-loader.js +28 -74
- package/core/options.js +15 -326
- package/core/plugins/AdikteevInjectorPlugin.js +4 -26
- package/core/plugins/BigoAdsInjectorPlugin.js +4 -21
- package/core/plugins/DAPIInjectorPlugin.js +2 -25
- package/core/plugins/DebuggerInjectionPlugin.js +3 -31
- package/core/plugins/ExitAPIInjectorPlugin.js +3 -56
- package/core/plugins/FflateCompressionPlugin.js +40 -231
- package/core/plugins/FontInjectionWebpackPlugin.js +4 -46
- package/core/plugins/LiftoffInjectorPlugin.js +4 -26
- package/core/plugins/MRAIDInjectorPlugin.js +2 -24
- package/core/plugins/MintegralInjectorPlugin.js +2 -25
- package/core/plugins/PangleInjectorPlugin.js +2 -24
- package/core/plugins/PlaycraftOrientationInjectorPlugin.js +3 -29
- package/core/plugins/SnapchatInjectorPlugin.js +4 -26
- package/core/plugins/SocialMediaInjectorPlugin.js +7 -119
- package/core/plugins/TikTokInjectorPlugin.js +2 -24
- package/core/plugins/UnityInjectorPlugin.js +8 -37
- package/core/plugins/ZipPlugin.js +20 -138
- package/core/plugins/socialMediaVitePlugin.js +2 -108
- package/core/utils/buildDefines.js +2 -30
- package/core/utils/buildTemplateString.js +5 -39
- package/core/utils/date.js +1 -16
- package/core/utils/fontRegistry.js +13 -81
- package/core/utils/fontResolver.js +37 -335
- package/core/utils/generateAdikteevHtmlWebpackPluginConfig.js +7 -42
- package/core/utils/generateBigabidHtmlWebpackPluginConfig.js +3 -30
- package/core/utils/generateInMobiHtmlWebpackPluginConfig.js +7 -43
- package/core/utils/getPlaycraftOrientationSuffix.js +2 -9
- package/core/utils/injectSDKPlugins.js +13 -68
- package/core/utils/logOptions.js +5 -46
- package/core/utils/mergeOptions.js +2 -19
- package/core/utils/parseArgvOptions.js +5 -111
- package/core/utils/resolveChannelFold2Zip.js +5 -17
- package/core/utils/validateThemeData.js +26 -227
- package/core/validators/pre-build-checker.js +26 -286
- package/core/validators/tracking-validator.js +40 -358
- package/core/vite.dev.js +17 -322
- package/core/webpack.build.js +66 -520
- package/core/webpack.common.js +11 -177
- package/core/webpack.dev.js +6 -88
- package/defines.d.ts +1 -0
- package/package.json +3 -4
- package/README.md +0 -262
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
const fs
|
|
2
|
-
const path = require('path');
|
|
3
|
-
|
|
4
|
-
/**
|
|
1
|
+
"use strict";const fs=require("fs");const path=require("path");/**
|
|
5
2
|
* InMobi 追踪宏定义
|
|
6
3
|
* 文档: https://support.inmobi.com/dsp/in/inmobi-dsp-india/creative-specifications-and-guidelines/
|
|
7
4
|
*
|
|
@@ -10,8 +7,7 @@ const path = require('path');
|
|
|
10
7
|
* 2. 必须包含 INMOBI_DSPMACROS 追踪变量
|
|
11
8
|
* 3. 引用外部 mraid.js(由 InMobi 平台提供)
|
|
12
9
|
* 4. 支持 MRAID 3.0 标准
|
|
13
|
-
*/
|
|
14
|
-
const InMobiPlaceholders = `<script>
|
|
10
|
+
*/const InMobiPlaceholders=`<script>
|
|
15
11
|
var INMOBI_DSPMACROS = {
|
|
16
12
|
"Ad_Load_Start": ["$P_AD_LOAD_START"],
|
|
17
13
|
"Ad_Viewable": ["$P_AD_READY"],
|
|
@@ -27,46 +23,14 @@ const InMobiPlaceholders = `<script>
|
|
|
27
23
|
"Spent_30_Seconds": ["$P_TIMESPENT_30"]
|
|
28
24
|
};
|
|
29
25
|
</script>
|
|
30
|
-
<script src="mraid.js"></script
|
|
31
|
-
|
|
32
|
-
/**
|
|
26
|
+
<script src="mraid.js"></script>`;/**
|
|
33
27
|
* 生成 InMobi 平台所需的 HTML 配置
|
|
34
28
|
*
|
|
35
29
|
* 策略:
|
|
36
30
|
* 1. 使用标准的 HtmlWebpackPlugin 配置(不是 templateContent)
|
|
37
31
|
* 2. JS 会通过 HtmlInlineScriptPlugin 自动内联到 HTML 中
|
|
38
32
|
* 3. 通过修改 template 文件注入 InMobi 追踪脚本
|
|
39
|
-
*/
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
) {
|
|
44
|
-
originalHtmlContentPath = originalHtmlContentPath || 'src/index.html';
|
|
45
|
-
|
|
46
|
-
const placeholder = InMobiPlaceholders
|
|
47
|
-
.replaceAll('{GOOGLE_PLAY_URL}', buildOptions.googlePlayUrl)
|
|
48
|
-
.replaceAll('{APP_STORE_URL}', buildOptions.appStoreUrl);
|
|
49
|
-
|
|
50
|
-
// 读取原始 HTML 模板
|
|
51
|
-
let htmlContent = '';
|
|
52
|
-
try {
|
|
53
|
-
htmlContent = fs.readFileSync(path.resolve(originalHtmlContentPath), 'utf8');
|
|
54
|
-
} catch (e) {
|
|
55
|
-
console.warn('[InMobi] Could not read HTML template:', e.message);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// 在 </head> 之前注入 InMobi 追踪脚本
|
|
59
|
-
htmlContent = htmlContent.replace('</head>', `${placeholder}\n</head>`);
|
|
60
|
-
|
|
61
|
-
return {
|
|
62
|
-
filename: 'index.html',
|
|
63
|
-
inject: 'head', // webpack 会自动注入 JS,然后 HtmlInlineScriptPlugin 内联
|
|
64
|
-
minify: false,
|
|
65
|
-
templateContent: htmlContent,
|
|
66
|
-
meta: {
|
|
67
|
-
charset: 'UTF-8',
|
|
68
|
-
viewport: 'width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no'
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
};
|
|
72
|
-
|
|
33
|
+
*/exports.generateInMobiHtmlWebpackPluginConfig=function generateInMobiHtmlWebpackPluginConfig(originalHtmlContentPath,buildOptions){originalHtmlContentPath=originalHtmlContentPath||"src/index.html";const placeholder=InMobiPlaceholders.replaceAll("{GOOGLE_PLAY_URL}",buildOptions.googlePlayUrl).replaceAll("{APP_STORE_URL}",buildOptions.appStoreUrl);// 读取原始 HTML 模板
|
|
34
|
+
let htmlContent="";try{htmlContent=fs.readFileSync(path.resolve(originalHtmlContentPath),"utf8")}catch(e){console.warn("[InMobi] Could not read HTML template:",e.message)}// 在 </head> 之前注入 InMobi 追踪脚本
|
|
35
|
+
htmlContent=htmlContent.replace("</head>",`${placeholder}\n</head>`);return{filename:"index.html",inject:"head",// webpack 会自动注入 JS,然后 HtmlInlineScriptPlugin 内联
|
|
36
|
+
minify:false,templateContent:htmlContent,meta:{charset:"UTF-8",viewport:"width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no"}}};
|
|
@@ -1,13 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";/**
|
|
2
2
|
* 根据当前构建的横竖屏方向版本,计算用于产物文件夹/文件命名的后缀。
|
|
3
3
|
* 命名规则:landscape → '_L',portrait → '_P',both(自适应)→ ''(无后缀)。
|
|
4
4
|
* @param {'both'|'landscape'|'portrait'} [orientation] - 方向版本,默认为 'both'
|
|
5
5
|
* @returns {string} 命名后缀
|
|
6
|
-
*/
|
|
7
|
-
function getPlaycraftOrientationSuffix(orientation) {
|
|
8
|
-
if (orientation === 'landscape') return '_L';
|
|
9
|
-
if (orientation === 'portrait') return '_P';
|
|
10
|
-
return '';
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
exports.getPlaycraftOrientationSuffix = getPlaycraftOrientationSuffix;
|
|
6
|
+
*/function getPlaycraftOrientationSuffix(orientation){if(orientation==="landscape")return"_L";if(orientation==="portrait")return"_P";return""}exports.getPlaycraftOrientationSuffix=getPlaycraftOrientationSuffix;
|
|
@@ -1,22 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";/**
|
|
2
2
|
* 根据 AD_NETWORK 和 AD_PROTOCOL 注入对应的渠道 SDK 脚本插件
|
|
3
3
|
* 此函数被 webpack.dev.js 和 webpack.build.js 共用
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const { ExitAPIInjectorPlugin } = require('../plugins/ExitAPIInjectorPlugin.js');
|
|
7
|
-
const { DAPIInjectorPlugin } = require('../plugins/DAPIInjectorPlugin.js');
|
|
8
|
-
const { PangleInjectorPlugin } = require('../plugins/PangleInjectorPlugin.js');
|
|
9
|
-
const { TikTokInjectorPlugin } = require('../plugins/TikTokInjectorPlugin.js');
|
|
10
|
-
const { MintegralInjectorPlugin } = require('../plugins/MintegralInjectorPlugin.js');
|
|
11
|
-
const { MRAIDInjectorPlugin } = require('../plugins/MRAIDInjectorPlugin.js');
|
|
12
|
-
const { BigoAdsInjectorPlugin } = require('../plugins/BigoAdsInjectorPlugin.js');
|
|
13
|
-
const { LiftoffInjectorPlugin } = require('../plugins/LiftoffInjectorPlugin.js');
|
|
14
|
-
const { SnapchatInjectorPlugin } = require('../plugins/SnapchatInjectorPlugin.js');
|
|
15
|
-
const { AdikteevInjectorPlugin } = require('../plugins/AdikteevInjectorPlugin.js');
|
|
16
|
-
const { UnityInjectorPlugin } = require('../plugins/UnityInjectorPlugin.js');
|
|
17
|
-
const { SocialMediaInjectorPlugin } = require('../plugins/SocialMediaInjectorPlugin.js');
|
|
18
|
-
|
|
19
|
-
/**
|
|
4
|
+
*/const{ExitAPIInjectorPlugin}=require("../plugins/ExitAPIInjectorPlugin.js");const{DAPIInjectorPlugin}=require("../plugins/DAPIInjectorPlugin.js");const{PangleInjectorPlugin}=require("../plugins/PangleInjectorPlugin.js");const{TikTokInjectorPlugin}=require("../plugins/TikTokInjectorPlugin.js");const{MintegralInjectorPlugin}=require("../plugins/MintegralInjectorPlugin.js");const{MRAIDInjectorPlugin}=require("../plugins/MRAIDInjectorPlugin.js");const{BigoAdsInjectorPlugin}=require("../plugins/BigoAdsInjectorPlugin.js");const{LiftoffInjectorPlugin}=require("../plugins/LiftoffInjectorPlugin.js");const{SnapchatInjectorPlugin}=require("../plugins/SnapchatInjectorPlugin.js");const{AdikteevInjectorPlugin}=require("../plugins/AdikteevInjectorPlugin.js");const{UnityInjectorPlugin}=require("../plugins/UnityInjectorPlugin.js");const{SocialMediaInjectorPlugin}=require("../plugins/SocialMediaInjectorPlugin.js");/**
|
|
20
5
|
* 注入渠道 SDK 插件到 webpack 配置中
|
|
21
6
|
* @param {import('webpack').Configuration} webpackConfig - webpack 配置对象
|
|
22
7
|
* @param {Object} options - 配置选项
|
|
@@ -27,54 +12,14 @@ const { SocialMediaInjectorPlugin } = require('../plugins/SocialMediaInjectorPlu
|
|
|
27
12
|
* @param {string} [options.themeName] - 当前主题名
|
|
28
13
|
* @param {object} [options.themeConfig] - builds.config.js 中的 themes 配置
|
|
29
14
|
* @param {object} [options.mergedData] - 预合并的主题数据(可选)
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
webpackConfig.plugins.push(new MRAIDInjectorPlugin());
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// 渠道特定注入
|
|
46
|
-
if (adNetwork === 'google') {
|
|
47
|
-
webpackConfig.plugins.push(new ExitAPIInjectorPlugin(playcraftOrientationValue));
|
|
48
|
-
} else if (adNetwork === 'unity') {
|
|
49
|
-
// Unity Ads 使用专门的 UnityInjectorPlugin
|
|
50
|
-
webpackConfig.plugins.push(new UnityInjectorPlugin());
|
|
51
|
-
} else if (adNetwork === 'pangle') {
|
|
52
|
-
webpackConfig.plugins.push(new PangleInjectorPlugin());
|
|
53
|
-
} else if (adNetwork === 'tiktok') {
|
|
54
|
-
webpackConfig.plugins.push(new TikTokInjectorPlugin());
|
|
55
|
-
} else if (adNetwork === 'mintegral') {
|
|
56
|
-
webpackConfig.plugins.push(new MintegralInjectorPlugin());
|
|
57
|
-
} else if (adNetwork === 'bigoads') {
|
|
58
|
-
// BigoAds 在 dev 模式下注入模拟配置
|
|
59
|
-
webpackConfig.plugins.push(new BigoAdsInjectorPlugin());
|
|
60
|
-
} else if (adNetwork === 'liftoff') {
|
|
61
|
-
webpackConfig.plugins.push(new LiftoffInjectorPlugin());
|
|
62
|
-
} else if (adNetwork === 'snapchat') {
|
|
63
|
-
// Snapchat 注入 ScPlayableAd SDK
|
|
64
|
-
webpackConfig.plugins.push(new SnapchatInjectorPlugin());
|
|
65
|
-
} else if (adNetwork === 'adikteev') {
|
|
66
|
-
// Adikteev 注入 MRAID mock 和占位符变量
|
|
67
|
-
webpackConfig.plugins.push(new AdikteevInjectorPlugin());
|
|
68
|
-
} else if (adNetwork === 'social_media') {
|
|
69
|
-
// social_media 渠道:注入 OG / Twitter meta 标签,让 Facebook / LinkedIn 爬取时
|
|
70
|
-
// 能拿到正确的标题/描述/预览图。注意 Telegram / Slack / Discord 也读 OG meta
|
|
71
|
-
webpackConfig.plugins.push(new SocialMediaInjectorPlugin({
|
|
72
|
-
projectRoot,
|
|
73
|
-
themeName,
|
|
74
|
-
themeConfig,
|
|
75
|
-
mergedData,
|
|
76
|
-
}));
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
exports.injectSDKPlugins = injectSDKPlugins;
|
|
15
|
+
*/function injectSDKPlugins(webpackConfig,options){const{network:adNetwork,protocol:adProtocol,playcraftOrientationValue,projectRoot,themeName,themeConfig,mergedData}=options;// 协议层注入
|
|
16
|
+
if("dapi"===adProtocol){webpackConfig.plugins.push(new DAPIInjectorPlugin)}else if("mraid"===adProtocol){// ironsource / remerge:HTML 内必须带 <script src="mraid.js">
|
|
17
|
+
// Unity 使用专门的 UnityInjectorPlugin(在渠道特定注入中处理)
|
|
18
|
+
if(adNetwork==="ironsource"||adNetwork==="remerge"){webpackConfig.plugins.push(new MRAIDInjectorPlugin)}}// 渠道特定注入
|
|
19
|
+
if(adNetwork==="google"){webpackConfig.plugins.push(new ExitAPIInjectorPlugin(playcraftOrientationValue))}else if(adNetwork==="unity"){// Unity Ads 使用专门的 UnityInjectorPlugin
|
|
20
|
+
webpackConfig.plugins.push(new UnityInjectorPlugin)}else if(adNetwork==="pangle"){webpackConfig.plugins.push(new PangleInjectorPlugin)}else if(adNetwork==="tiktok"){webpackConfig.plugins.push(new TikTokInjectorPlugin)}else if(adNetwork==="mintegral"){webpackConfig.plugins.push(new MintegralInjectorPlugin)}else if(adNetwork==="bigoads"){// BigoAds 在 dev 模式下注入模拟配置
|
|
21
|
+
webpackConfig.plugins.push(new BigoAdsInjectorPlugin)}else if(adNetwork==="liftoff"){webpackConfig.plugins.push(new LiftoffInjectorPlugin)}else if(adNetwork==="snapchat"){// Snapchat 注入 ScPlayableAd SDK
|
|
22
|
+
webpackConfig.plugins.push(new SnapchatInjectorPlugin)}else if(adNetwork==="adikteev"){// Adikteev 注入 MRAID mock 和占位符变量
|
|
23
|
+
webpackConfig.plugins.push(new AdikteevInjectorPlugin)}else if(adNetwork==="social_media"){// social_media 渠道:注入 OG / Twitter meta 标签,让 Facebook / LinkedIn 爬取时
|
|
24
|
+
// 能拿到正确的标题/描述/预览图。注意 Telegram / Slack / Discord 也读 OG meta
|
|
25
|
+
webpackConfig.plugins.push(new SocialMediaInjectorPlugin({projectRoot,themeName,themeConfig,mergedData}))}}exports.injectSDKPlugins=injectSDKPlugins;
|
package/core/utils/logOptions.js
CHANGED
|
@@ -1,47 +1,6 @@
|
|
|
1
|
-
var prettyjson
|
|
2
|
-
|
|
3
|
-
/**
|
|
1
|
+
"use strict";var prettyjson=require("prettyjson");/**
|
|
4
2
|
* Log provided options into console output
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (process.env.NODE_ENV === 'production') {
|
|
10
|
-
isProduction = true;
|
|
11
|
-
delete logOptions.port;
|
|
12
|
-
delete logOptions.open;
|
|
13
|
-
} else if (process.env.NODE_ENV === 'development') {
|
|
14
|
-
delete logOptions.outDir;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
if (Object.keys(logOptions.compilation).length === 0 || !isProduction) delete logOptions.compilation;
|
|
18
|
-
if (Object.keys(logOptions.adNetworkNames).length === 0 || !isProduction) delete logOptions.adNetworkNames;
|
|
19
|
-
if (Object.keys(logOptions.defines).length === 0) delete logOptions.defines;
|
|
20
|
-
if (logOptions.zip === false || !isProduction) delete logOptions.zip;
|
|
21
|
-
if (logOptions.tsConfig === 'tsconfig.json') delete logOptions.tsConfig;
|
|
22
|
-
if (logOptions.jsConfig === 'jsconfig.json') delete logOptions.jsConfig;
|
|
23
|
-
if (logOptions.buildConfig === 'build.json') delete logOptions.buildConfig;
|
|
24
|
-
if (logOptions.language === 'en') delete logOptions.language;
|
|
25
|
-
// playcraftOrientation/playcraftOrientationChannel 为默认值时不显示,避免日志噪音
|
|
26
|
-
if (Array.isArray(logOptions.playcraftOrientation) && logOptions.playcraftOrientation.length === 1 && logOptions.playcraftOrientation[0] === 'both') {
|
|
27
|
-
delete logOptions.playcraftOrientation;
|
|
28
|
-
}
|
|
29
|
-
if (Array.isArray(logOptions.playcraftOrientationChannel) && logOptions.playcraftOrientationChannel.length === 0) {
|
|
30
|
-
delete logOptions.playcraftOrientationChannel;
|
|
31
|
-
}
|
|
32
|
-
if (!logOptions.playcraftOrientationValue || logOptions.playcraftOrientationValue === 'both') {
|
|
33
|
-
delete logOptions.playcraftOrientationValue;
|
|
34
|
-
}
|
|
35
|
-
// 在 dev 模式下,如果 network 为默认值 preview 则不显示
|
|
36
|
-
if (!isProduction && logOptions.network === 'preview') delete logOptions.network;
|
|
37
|
-
// 在 dev 模式下,如果 protocol 为默认值 none 则不显示
|
|
38
|
-
if (!isProduction && logOptions.protocol === 'none') delete logOptions.protocol;
|
|
39
|
-
delete logOptions.filename;
|
|
40
|
-
delete logOptions.app;
|
|
41
|
-
delete logOptions.name;
|
|
42
|
-
delete logOptions.googlePlayUrl;
|
|
43
|
-
delete logOptions.appStoreUrl;
|
|
44
|
-
if (logOptions.obfuscateLevel === 2) delete logOptions.obfuscateLevel;
|
|
45
|
-
|
|
46
|
-
console.log(prettyjson.render(logOptions, {}, 2));
|
|
47
|
-
};
|
|
3
|
+
*/exports.logOptions=function logOptions(options){let logOptions={mode:process.env.NODE_ENV,...options};let isProduction=false;if(process.env.NODE_ENV==="production"){isProduction=true;delete logOptions.port;delete logOptions.open}else if(process.env.NODE_ENV==="development"){delete logOptions.outDir}if(Object.keys(logOptions.compilation).length===0||!isProduction)delete logOptions.compilation;if(Object.keys(logOptions.adNetworkNames).length===0||!isProduction)delete logOptions.adNetworkNames;if(Object.keys(logOptions.defines).length===0)delete logOptions.defines;if(logOptions.zip===false||!isProduction)delete logOptions.zip;if(logOptions.tsConfig==="tsconfig.json")delete logOptions.tsConfig;if(logOptions.jsConfig==="jsconfig.json")delete logOptions.jsConfig;if(logOptions.buildConfig==="build.json")delete logOptions.buildConfig;if(logOptions.language==="en")delete logOptions.language;// playcraftOrientation/playcraftOrientationChannel 为默认值时不显示,避免日志噪音
|
|
4
|
+
if(Array.isArray(logOptions.playcraftOrientation)&&logOptions.playcraftOrientation.length===1&&logOptions.playcraftOrientation[0]==="both"){delete logOptions.playcraftOrientation}if(Array.isArray(logOptions.playcraftOrientationChannel)&&logOptions.playcraftOrientationChannel.length===0){delete logOptions.playcraftOrientationChannel}if(!logOptions.playcraftOrientationValue||logOptions.playcraftOrientationValue==="both"){delete logOptions.playcraftOrientationValue}// 在 dev 模式下,如果 network 为默认值 preview 则不显示
|
|
5
|
+
if(!isProduction&&logOptions.network==="preview")delete logOptions.network;// 在 dev 模式下,如果 protocol 为默认值 none 则不显示
|
|
6
|
+
if(!isProduction&&logOptions.protocol==="none")delete logOptions.protocol;delete logOptions.filename;delete logOptions.app;delete logOptions.name;delete logOptions.googlePlayUrl;delete logOptions.appStoreUrl;if(logOptions.obfuscateLevel===2)delete logOptions.obfuscateLevel;console.log(prettyjson.render(logOptions,{},2))};
|
|
@@ -1,23 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";/**
|
|
2
2
|
* Merges two option objects with deep merge for 'defines' and 'build' properties
|
|
3
3
|
* @param {import('../index').CLIOptions} options1 - First options object
|
|
4
4
|
* @param {Partial<import('../index').CLIOptions>} [options2] - Second options object
|
|
5
5
|
* @returns {import('../index').CLIOptions} Merged options object with combined defines and build properties
|
|
6
|
-
*/
|
|
7
|
-
exports.mergeOptions = function mergeOptions(options1, options2) {
|
|
8
|
-
if (!options1) return {};
|
|
9
|
-
if (!options2) return options1;
|
|
10
|
-
|
|
11
|
-
const defines = Object.assign({}, options1.defines, options2.defines);
|
|
12
|
-
const build = Object.assign({}, options1.build, options2.build);
|
|
13
|
-
const compilation = Object.assign({}, options1.compilation, options2.compilation);
|
|
14
|
-
const adNetworkNames = Object.assign({}, options1.adNetworkNames, options2.adNetworkNames);
|
|
15
|
-
const options = Object.assign({}, options1, options2);
|
|
16
|
-
|
|
17
|
-
options.defines = defines;
|
|
18
|
-
options.compilation = compilation;
|
|
19
|
-
options.adNetworkNames = adNetworkNames;
|
|
20
|
-
options.build = build;
|
|
21
|
-
|
|
22
|
-
return options;
|
|
23
|
-
};
|
|
6
|
+
*/exports.mergeOptions=function mergeOptions(options1,options2){if(!options1)return{};if(!options2)return options1;const defines=Object.assign({},options1.defines,options2.defines);const build=Object.assign({},options1.build,options2.build);const compilation=Object.assign({},options1.compilation,options2.compilation);const adNetworkNames=Object.assign({},options1.adNetworkNames,options2.adNetworkNames);const options=Object.assign({},options1,options2);options.defines=defines;options.compilation=compilation;options.adNetworkNames=adNetworkNames;options.build=build;return options};
|
|
@@ -1,114 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
const allowedAdNetworks = [
|
|
3
|
-
'preview',
|
|
4
|
-
'applovin',
|
|
5
|
-
'unity',
|
|
6
|
-
'google',
|
|
7
|
-
'ironsource',
|
|
8
|
-
'facebook',
|
|
9
|
-
'moloco',
|
|
10
|
-
'adcolony',
|
|
11
|
-
'mintegral',
|
|
12
|
-
'vungle',
|
|
13
|
-
'tapjoy',
|
|
14
|
-
'snapchat',
|
|
15
|
-
'tiktok',
|
|
16
|
-
'appreciate',
|
|
17
|
-
'chartboost',
|
|
18
|
-
'pangle',
|
|
19
|
-
'mytarget',
|
|
20
|
-
'liftoff',
|
|
21
|
-
'smadex',
|
|
22
|
-
'adikteev',
|
|
23
|
-
'bigabid',
|
|
24
|
-
'inmobi',
|
|
25
|
-
'bigoads',
|
|
26
|
-
'social_media'
|
|
27
|
-
];
|
|
28
|
-
/** @type {AD_PROTOCOL[]} List of supported advertising protocols */
|
|
29
|
-
const allowedAdProtocols = ['none', 'mraid', 'dapi'];
|
|
30
|
-
|
|
31
|
-
/** @type {AD_NETWORK[]} List of advertising partners that support MRAID protocol */
|
|
32
|
-
const mraidPartners = [
|
|
33
|
-
'ironsource',
|
|
34
|
-
'applovin',
|
|
35
|
-
'unity',
|
|
36
|
-
'appreciate',
|
|
37
|
-
'chartboost',
|
|
38
|
-
'mytarget',
|
|
39
|
-
'liftoff',
|
|
40
|
-
'adcolony',
|
|
41
|
-
'adikteev',
|
|
42
|
-
'bigabid',
|
|
43
|
-
'inmobi'
|
|
44
|
-
];
|
|
45
|
-
|
|
46
|
-
/** @type {LANGUAGE[]} */
|
|
47
|
-
const allowedLanguages = ['auto', 'en', 'es', 'zh', 'hi', 'ar', 'fr', 'de', 'ja', 'pt'];
|
|
48
|
-
|
|
49
|
-
/** @type {('both'|'landscape'|'portrait')[]} playcraftOrientation 允许的横竖屏方向版本取值 */
|
|
50
|
-
const allowedPlaycraftOrientations = ['both', 'landscape', 'portrait'];
|
|
51
|
-
|
|
52
|
-
/**
|
|
1
|
+
"use strict";/** @type {string[]} List of supported advertising networks */const allowedAdNetworks=["preview","applovin","unity","google","ironsource","facebook","moloco","adcolony","mintegral","vungle","tapjoy","snapchat","tiktok","appreciate","chartboost","pangle","mytarget","liftoff","smadex","adikteev","bigabid","inmobi","bigoads","remerge","social_media"];/** @type {AD_PROTOCOL[]} List of supported advertising protocols */const allowedAdProtocols=["none","mraid","dapi"];/** @type {AD_NETWORK[]} List of advertising partners that support MRAID protocol */const mraidPartners=["ironsource","applovin","unity","appreciate","chartboost","mytarget","liftoff","adcolony","adikteev","bigabid","inmobi","remerge"];/** @type {LANGUAGE[]} */const allowedLanguages=["auto","en","es","zh","hi","ar","fr","de","ja","pt"];/** @type {('both'|'landscape'|'portrait')[]} playcraftOrientation 允许的横竖屏方向版本取值 */const allowedPlaycraftOrientations=["both","landscape","portrait"];/**
|
|
53
2
|
* Parses command line arguments based on provided options configuration
|
|
54
3
|
* @param {import('../index').CLIOptionConfig[]} posiibleOptions - Array of possible options to parse
|
|
55
4
|
* @returns {Record<string, any>} Parsed options object with values from command line arguments
|
|
56
|
-
*/
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const cliExplicitKeys = new Set();
|
|
61
|
-
|
|
62
|
-
for (let possibleOption of posiibleOptions) {
|
|
63
|
-
if (possibleOption.defaultValue !== undefined)
|
|
64
|
-
argvOptions[possibleOption.alias || possibleOption.name] = possibleOption.defaultValue;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
let adNetwork = null;
|
|
68
|
-
|
|
69
|
-
for (let i = 2; i < process.argv.length; i++) {
|
|
70
|
-
let key = process.argv[i];
|
|
71
|
-
let inlineValue = null;
|
|
72
|
-
|
|
73
|
-
// 支持 --key=value 格式
|
|
74
|
-
if (key.includes('=')) {
|
|
75
|
-
const eqIndex = key.indexOf('=');
|
|
76
|
-
inlineValue = key.slice(eqIndex + 1);
|
|
77
|
-
key = key.slice(0, eqIndex);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const allowedOption = posiibleOptions.find((e) => '--' + e.name === key);
|
|
81
|
-
|
|
82
|
-
if (allowedOption) {
|
|
83
|
-
let value = true;
|
|
84
|
-
if (allowedOption.hasValue) {
|
|
85
|
-
// 优先使用内联值(--key=value),否则使用下一个参数
|
|
86
|
-
value = inlineValue !== null ? inlineValue : process.argv[++i];
|
|
87
|
-
if (allowedOption.parser) value = allowedOption.parser(value);
|
|
88
|
-
}
|
|
89
|
-
const optionKey = allowedOption.alias || allowedOption.name;
|
|
90
|
-
argvOptions[optionKey] = value;
|
|
91
|
-
cliExplicitKeys.add(optionKey);
|
|
92
|
-
} else if (!adNetwork) adNetwork = key;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
if (posiibleOptions.find((e) => e.name === 'network')) {
|
|
96
|
-
if (adNetwork && allowedAdNetworks.includes(adNetwork)) {
|
|
97
|
-
argvOptions['network'] = adNetwork;
|
|
98
|
-
}
|
|
99
|
-
if (posiibleOptions.find((e) => e.name === 'protocol')) {
|
|
100
|
-
if (mraidPartners.includes(argvOptions['network']) && argvOptions['protocol'] === 'none') {
|
|
101
|
-
argvOptions['protocol'] = 'mraid';
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
argvOptions._cliExplicitKeys = cliExplicitKeys;
|
|
107
|
-
return argvOptions;
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
exports.allowedAdNetworks = allowedAdNetworks;
|
|
111
|
-
exports.allowedAdProtocols = allowedAdProtocols;
|
|
112
|
-
exports.mraidPartners = mraidPartners;
|
|
113
|
-
exports.allowedLanguages = allowedLanguages;
|
|
114
|
-
exports.allowedPlaycraftOrientations = allowedPlaycraftOrientations;
|
|
5
|
+
*/exports.parseArgvOptions=function parseArgvOptions(posiibleOptions){const argvOptions={};// Track which options were explicitly set via CLI args
|
|
6
|
+
const cliExplicitKeys=new Set;for(let possibleOption of posiibleOptions){if(possibleOption.defaultValue!==undefined)argvOptions[possibleOption.alias||possibleOption.name]=possibleOption.defaultValue}let adNetwork=null;for(let i=2;i<process.argv.length;i++){let key=process.argv[i];let inlineValue=null;// 支持 --key=value 格式
|
|
7
|
+
if(key.includes("=")){const eqIndex=key.indexOf("=");inlineValue=key.slice(eqIndex+1);key=key.slice(0,eqIndex)}const allowedOption=posiibleOptions.find(e=>"--"+e.name===key);if(allowedOption){let value=true;if(allowedOption.hasValue){// 优先使用内联值(--key=value),否则使用下一个参数
|
|
8
|
+
value=inlineValue!==null?inlineValue:process.argv[++i];if(allowedOption.parser)value=allowedOption.parser(value)}const optionKey=allowedOption.alias||allowedOption.name;argvOptions[optionKey]=value;cliExplicitKeys.add(optionKey)}else if(!adNetwork)adNetwork=key}if(posiibleOptions.find(e=>e.name==="network")){if(adNetwork&&allowedAdNetworks.includes(adNetwork)){argvOptions["network"]=adNetwork}if(posiibleOptions.find(e=>e.name==="protocol")){if(mraidPartners.includes(argvOptions["network"])&&argvOptions["protocol"]==="none"){argvOptions["protocol"]="mraid"}}}argvOptions._cliExplicitKeys=cliExplicitKeys;return argvOptions};exports.allowedAdNetworks=allowedAdNetworks;exports.allowedAdProtocols=allowedAdProtocols;exports.mraidPartners=mraidPartners;exports.allowedLanguages=allowedLanguages;exports.allowedPlaycraftOrientations=allowedPlaycraftOrientations;
|
|
@@ -1,26 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";/**
|
|
2
2
|
* 解析 isChannelFold2Zip 相关标志
|
|
3
3
|
*
|
|
4
4
|
* isChannelFold2Zip:所有渠道(排除 preview)输出 dist/渠道名称.zip
|
|
5
|
-
* - ZIP 渠道(google/tiktok 等):正常 ZIP 流程,输出路径改为 dist/渠道名称.zip
|
|
6
|
-
* - 非 ZIP 渠道(
|
|
5
|
+
* - ZIP 渠道(google/tiktok/facebook 等):正常 ZIP 流程,输出路径改为 dist/渠道名称.zip
|
|
6
|
+
* - 非 ZIP 渠道(moloco 默认 HTML 等):强制将 HTML 打包成 zip,输出 dist/渠道名称.zip
|
|
7
7
|
*
|
|
8
8
|
* @param {object} params
|
|
9
9
|
* @param {boolean} params.isChannelFold2ZipOption - buildOptions.isChannelFold2Zip 的值
|
|
10
10
|
* @param {string} params.adNetwork - 当前渠道名称
|
|
11
11
|
* @param {boolean} params.isZipOutput - 当前渠道是否本身就走 ZIP 输出流程
|
|
12
12
|
* @returns {{ isChannelFold2Zip: boolean, isZipOutputFinal: boolean }}
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
const isChannelFold2Zip = !!(isChannelFold2ZipOption && adNetwork !== 'preview');
|
|
16
|
-
// 非 ZIP 渠道启用 isChannelFold2Zip 时,需要强制走 ZIP 输出流程
|
|
17
|
-
const isZipOutputFinal = isZipOutput || isChannelFold2Zip;
|
|
18
|
-
|
|
19
|
-
if (isChannelFold2Zip) {
|
|
20
|
-
console.log(`✅ isChannelFold2Zip enabled: output will be dist/${adNetwork}.zip`);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return { isChannelFold2Zip, isZipOutputFinal };
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
exports.resolveChannelFold2Zip = resolveChannelFold2Zip;
|
|
13
|
+
*/function resolveChannelFold2Zip({isChannelFold2ZipOption,adNetwork,isZipOutput}){const isChannelFold2Zip=!!(isChannelFold2ZipOption&&adNetwork!=="preview");// 非 ZIP 渠道启用 isChannelFold2Zip 时,需要强制走 ZIP 输出流程
|
|
14
|
+
const isZipOutputFinal=isZipOutput||isChannelFold2Zip;if(isChannelFold2Zip){console.log(`✅ isChannelFold2Zip enabled: output will be dist/${adNetwork}.zip`)}return{isChannelFold2Zip,isZipOutputFinal}}exports.resolveChannelFold2Zip=resolveChannelFold2Zip;
|