@playcraft/devkit 1.0.31-beta.10 → 1.0.31-beta.11
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 +262 -0
- package/cli/bin/playable-scripts.js +53 -6
- package/cli/commands/build.js +241 -32
- package/cli/commands/builds.js +13 -2
- package/cli/commands/dev.js +22 -1
- package/cli/commands/pack.js +320 -40
- package/cli/commands/vite-dev.js +7 -1
- package/core/artifacts/emit.js +98 -1
- package/core/artifacts/fflate.js +31 -1
- package/core/artifacts/zip.js +39 -1
- package/core/batch-build.js +1261 -147
- package/core/constants.js +20 -2
- package/core/cos-uploader.js +289 -23
- package/core/engines/cocos/clean-cache.js +179 -5
- package/core/engines/cocos/clean-cache.test.js +75 -1
- package/core/engines/cocos/cli-build.js +116 -2
- package/core/engines/cocos/cli.js +38 -1
- package/core/engines/cocos/constants.js +21 -1
- package/core/engines/cocos/creator-cli.js +108 -1
- package/core/engines/cocos/dev-server.js +412 -4
- package/core/engines/cocos/fs.js +105 -1
- package/core/engines/cocos/injects/3x/init.js +438 -19
- package/core/engines/cocos/injects/3x/main.js +52 -2
- package/core/engines/cocos/injects/libs/pako.js +2 -1
- package/core/engines/cocos/mcp-refresh.js +76 -2
- package/core/engines/cocos/merge.js +147 -2
- package/core/engines/cocos/pack.js +187 -1
- package/core/engines/cocos/preview-cache.js +48 -2
- package/core/engines/cocos/preview-cache.test.js +32 -1
- package/core/engines/cocos/preview-concat.js +189 -5
- package/core/engines/cocos/preview-concat.test.js +73 -1
- package/core/engines/cocos/preview-json-hook.js +200 -1
- package/core/engines/cocos/preview-json-pack.js +376 -2
- package/core/engines/cocos/preview-json-pack.test.js +226 -2
- package/core/engines/cocos/preview-proxy.js +132 -1
- package/core/engines/cocos/rebundle-preview.js +54 -2
- package/core/engines/cocos/strip-social-share.js +115 -3
- package/core/engines/cocos/theme-assets.js +161 -2
- package/core/engines/cocos/writable-cli.js +248 -2
- package/core/engines/cocos/writable-cli.test.js +112 -1
- package/core/engines/web/index.js +20 -1
- package/core/engines/web/vite.dev.js +322 -17
- package/core/engines/web/webpack.build.js +522 -65
- package/core/engines/web/webpack.common.js +177 -11
- package/core/engines/web/webpack.dev.js +88 -6
- package/core/index.js +101 -7
- package/core/injectors/apply.js +94 -1
- package/core/injectors/check-channel-matrix.js +130 -2
- package/core/injectors/spec.js +217 -9
- package/core/loaders/gltf-loader.js +74 -28
- package/core/options.js +353 -16
- package/core/plugins/AdikteevInjectorPlugin.js +26 -4
- package/core/plugins/BigoAdsInjectorPlugin.js +21 -4
- package/core/plugins/DAPIInjectorPlugin.js +25 -2
- package/core/plugins/DebuggerInjectionPlugin.js +31 -3
- package/core/plugins/ExitAPIInjectorPlugin.js +56 -3
- package/core/plugins/FflateCompressionPlugin.js +231 -40
- package/core/plugins/FontInjectionWebpackPlugin.js +46 -4
- package/core/plugins/LiftoffInjectorPlugin.js +26 -4
- package/core/plugins/MRAIDInjectorPlugin.js +24 -2
- package/core/plugins/MintegralInjectorPlugin.js +25 -2
- package/core/plugins/PangleInjectorPlugin.js +24 -2
- package/core/plugins/PlaycraftOrientationInjectorPlugin.js +29 -3
- package/core/plugins/SnapchatInjectorPlugin.js +26 -4
- package/core/plugins/SocialMediaInjectorPlugin.js +119 -7
- package/core/plugins/TikTokInjectorPlugin.js +24 -2
- package/core/plugins/UnityInjectorPlugin.js +37 -8
- package/core/plugins/ZipPlugin.js +154 -20
- package/core/plugins/socialMediaVitePlugin.js +108 -2
- package/core/utils/buildDefines.js +30 -2
- package/core/utils/buildTemplateString.js +39 -5
- package/core/utils/date.js +16 -1
- package/core/utils/fontRegistry.js +81 -13
- package/core/utils/fontResolver.js +335 -37
- package/core/utils/generateAdikteevHtmlWebpackPluginConfig.js +42 -7
- package/core/utils/generateBigabidHtmlWebpackPluginConfig.js +30 -3
- package/core/utils/generateInMobiHtmlWebpackPluginConfig.js +43 -7
- package/core/utils/getPlaycraftOrientationSuffix.js +9 -2
- package/core/utils/injectSDKPlugins.js +68 -13
- package/core/utils/logOptions.js +46 -5
- package/core/utils/mergeOptions.js +21 -2
- package/core/utils/parseArgvOptions.js +125 -5
- package/core/utils/resolveChannelFold2Zip.js +15 -3
- package/core/utils/validateThemeData.js +227 -26
- package/core/validators/pre-build-checker.js +287 -25
- package/core/validators/tracking-validator.js +441 -40
- package/core/validators/tracking-validator.test.js +84 -2
- package/core/vite.dev.js +1 -1
- package/core/webpack.build.js +1 -1
- package/core/webpack.common.js +1 -1
- package/core/webpack.dev.js +1 -1
- package/package.json +3 -2
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
/**
|
|
2
5
|
* InMobi 追踪宏定义
|
|
3
6
|
* 文档: https://support.inmobi.com/dsp/in/inmobi-dsp-india/creative-specifications-and-guidelines/
|
|
4
7
|
*
|
|
@@ -7,7 +10,8 @@
|
|
|
7
10
|
* 2. 必须包含 INMOBI_DSPMACROS 追踪变量
|
|
8
11
|
* 3. 引用外部 mraid.js(由 InMobi 平台提供)
|
|
9
12
|
* 4. 支持 MRAID 3.0 标准
|
|
10
|
-
*/
|
|
13
|
+
*/
|
|
14
|
+
const InMobiPlaceholders = `<script>
|
|
11
15
|
var INMOBI_DSPMACROS = {
|
|
12
16
|
"Ad_Load_Start": ["$P_AD_LOAD_START"],
|
|
13
17
|
"Ad_Viewable": ["$P_AD_READY"],
|
|
@@ -23,14 +27,46 @@
|
|
|
23
27
|
"Spent_30_Seconds": ["$P_TIMESPENT_30"]
|
|
24
28
|
};
|
|
25
29
|
</script>
|
|
26
|
-
<script src="mraid.js"></script
|
|
30
|
+
<script src="mraid.js"></script>`;
|
|
31
|
+
|
|
32
|
+
/**
|
|
27
33
|
* 生成 InMobi 平台所需的 HTML 配置
|
|
28
34
|
*
|
|
29
35
|
* 策略:
|
|
30
36
|
* 1. 使用标准的 HtmlWebpackPlugin 配置(不是 templateContent)
|
|
31
37
|
* 2. JS 会通过 HtmlInlineScriptPlugin 自动内联到 HTML 中
|
|
32
38
|
* 3. 通过修改 template 文件注入 InMobi 追踪脚本
|
|
33
|
-
*/
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
39
|
+
*/
|
|
40
|
+
exports.generateInMobiHtmlWebpackPluginConfig = function generateInMobiHtmlWebpackPluginConfig(
|
|
41
|
+
originalHtmlContentPath,
|
|
42
|
+
buildOptions
|
|
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
|
+
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
2
|
* 根据当前构建的横竖屏方向版本,计算用于产物文件夹/文件命名的后缀。
|
|
3
3
|
* 命名规则:landscape → '_L',portrait → '_P',both(自适应)→ ''(无后缀)。
|
|
4
4
|
* @param {'both'|'landscape'|'portrait'} [orientation] - 方向版本,默认为 'both'
|
|
5
5
|
* @returns {string} 命名后缀
|
|
6
|
-
*/
|
|
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;
|
|
@@ -1,7 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
2
|
* 根据 AD_NETWORK 和 AD_PROTOCOL 注入对应的渠道 SDK 脚本插件
|
|
3
3
|
* 此函数被 webpack.dev.js 和 webpack.build.js 共用
|
|
4
|
-
*/
|
|
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
|
+
/**
|
|
5
20
|
* 注入渠道 SDK 插件到 webpack 配置中
|
|
6
21
|
* @param {import('webpack').Configuration} webpackConfig - webpack 配置对象
|
|
7
22
|
* @param {Object} options - 配置选项
|
|
@@ -12,14 +27,54 @@
|
|
|
12
27
|
* @param {string} [options.themeName] - 当前主题名
|
|
13
28
|
* @param {object} [options.themeConfig] - builds.config.js 中的 themes 配置
|
|
14
29
|
* @param {object} [options.mergedData] - 预合并的主题数据(可选)
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
webpackConfig.plugins.push(new
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
//
|
|
25
|
-
|
|
30
|
+
*/
|
|
31
|
+
function injectSDKPlugins(webpackConfig, options) {
|
|
32
|
+
const { network: adNetwork, protocol: adProtocol, playcraftOrientationValue, projectRoot, themeName, themeConfig, mergedData } = options;
|
|
33
|
+
|
|
34
|
+
// 协议层注入
|
|
35
|
+
if ('dapi' === adProtocol) {
|
|
36
|
+
webpackConfig.plugins.push(new DAPIInjectorPlugin());
|
|
37
|
+
} else if ('mraid' === adProtocol) {
|
|
38
|
+
// ironsource / remerge:HTML 内必须带 <script src="mraid.js">
|
|
39
|
+
// Unity 使用专门的 UnityInjectorPlugin(在渠道特定注入中处理)
|
|
40
|
+
if (adNetwork === 'ironsource' || adNetwork === 'remerge') {
|
|
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;
|
package/core/utils/logOptions.js
CHANGED
|
@@ -1,6 +1,47 @@
|
|
|
1
|
-
|
|
1
|
+
var prettyjson = require('prettyjson');
|
|
2
|
+
|
|
3
|
+
/**
|
|
2
4
|
* Log provided options into console output
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
*/
|
|
6
|
+
exports.logOptions = function logOptions(options) {
|
|
7
|
+
let logOptions = { mode: process.env.NODE_ENV, ...options };
|
|
8
|
+
let isProduction = false;
|
|
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
|
+
};
|
|
@@ -1,6 +1,25 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
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
|
-
*/
|
|
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 cocos = Object.assign({}, options1.cocos, options2.cocos);
|
|
16
|
+
const options = Object.assign({}, options1, options2);
|
|
17
|
+
|
|
18
|
+
options.defines = defines;
|
|
19
|
+
options.compilation = compilation;
|
|
20
|
+
options.adNetworkNames = adNetworkNames;
|
|
21
|
+
options.build = build;
|
|
22
|
+
options.cocos = cocos;
|
|
23
|
+
|
|
24
|
+
return options;
|
|
25
|
+
};
|
|
@@ -1,8 +1,128 @@
|
|
|
1
|
-
|
|
1
|
+
/** @type {string[]} List of supported advertising networks */
|
|
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
|
+
'remerge',
|
|
27
|
+
'social_media'
|
|
28
|
+
];
|
|
29
|
+
/** @type {AD_PROTOCOL[]} List of supported advertising protocols */
|
|
30
|
+
const allowedAdProtocols = ['none', 'mraid', 'dapi'];
|
|
31
|
+
|
|
32
|
+
/** @type {AD_NETWORK[]} List of advertising partners that support MRAID protocol */
|
|
33
|
+
const mraidPartners = [
|
|
34
|
+
'ironsource',
|
|
35
|
+
'applovin',
|
|
36
|
+
'unity',
|
|
37
|
+
'appreciate',
|
|
38
|
+
'chartboost',
|
|
39
|
+
'mytarget',
|
|
40
|
+
'liftoff',
|
|
41
|
+
'adcolony',
|
|
42
|
+
'adikteev',
|
|
43
|
+
'bigabid',
|
|
44
|
+
'inmobi',
|
|
45
|
+
'remerge'
|
|
46
|
+
];
|
|
47
|
+
|
|
48
|
+
/** @type {LANGUAGE[]} */
|
|
49
|
+
const allowedLanguages = ['auto', 'en', 'es', 'zh', 'hi', 'ar', 'fr', 'de', 'ja', 'pt'];
|
|
50
|
+
|
|
51
|
+
/** @type {('both'|'landscape'|'portrait')[]} playcraftOrientation 允许的横竖屏方向版本取值 */
|
|
52
|
+
const allowedPlaycraftOrientations = ['both', 'landscape', 'portrait'];
|
|
53
|
+
|
|
54
|
+
/** @type {('phaser'|'threejs'|'cocos')[]} */
|
|
55
|
+
const allowedEngines = ['phaser', 'threejs', 'cocos'];
|
|
56
|
+
|
|
57
|
+
const WEB_ENGINES = ['phaser', 'threejs'];
|
|
58
|
+
|
|
59
|
+
function isWebEngine(engine) {
|
|
60
|
+
return !engine || WEB_ENGINES.includes(engine);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
2
64
|
* Parses command line arguments based on provided options configuration
|
|
3
65
|
* @param {import('../index').CLIOptionConfig[]} posiibleOptions - Array of possible options to parse
|
|
4
66
|
* @returns {Record<string, any>} Parsed options object with values from command line arguments
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
67
|
+
*/
|
|
68
|
+
exports.parseArgvOptions = function parseArgvOptions(posiibleOptions) {
|
|
69
|
+
const argvOptions = {};
|
|
70
|
+
// Track which options were explicitly set via CLI args
|
|
71
|
+
const cliExplicitKeys = new Set();
|
|
72
|
+
|
|
73
|
+
for (let possibleOption of posiibleOptions) {
|
|
74
|
+
if (possibleOption.defaultValue !== undefined)
|
|
75
|
+
argvOptions[possibleOption.alias || possibleOption.name] = possibleOption.defaultValue;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
let adNetwork = null;
|
|
79
|
+
|
|
80
|
+
for (let i = 2; i < process.argv.length; i++) {
|
|
81
|
+
let key = process.argv[i];
|
|
82
|
+
let inlineValue = null;
|
|
83
|
+
|
|
84
|
+
// 支持 --key=value 格式
|
|
85
|
+
if (key.includes('=')) {
|
|
86
|
+
const eqIndex = key.indexOf('=');
|
|
87
|
+
inlineValue = key.slice(eqIndex + 1);
|
|
88
|
+
key = key.slice(0, eqIndex);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const allowedOption = posiibleOptions.find((e) => '--' + e.name === key);
|
|
92
|
+
|
|
93
|
+
if (allowedOption) {
|
|
94
|
+
let value = true;
|
|
95
|
+
if (allowedOption.hasValue) {
|
|
96
|
+
// 优先使用内联值(--key=value),否则使用下一个参数
|
|
97
|
+
value = inlineValue !== null ? inlineValue : process.argv[++i];
|
|
98
|
+
if (allowedOption.parser) value = allowedOption.parser(value);
|
|
99
|
+
}
|
|
100
|
+
const optionKey = allowedOption.alias || allowedOption.name;
|
|
101
|
+
argvOptions[optionKey] = value;
|
|
102
|
+
cliExplicitKeys.add(optionKey);
|
|
103
|
+
} else if (!adNetwork) adNetwork = key;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (posiibleOptions.find((e) => e.name === 'network')) {
|
|
107
|
+
if (adNetwork && allowedAdNetworks.includes(adNetwork)) {
|
|
108
|
+
argvOptions['network'] = adNetwork;
|
|
109
|
+
}
|
|
110
|
+
if (posiibleOptions.find((e) => e.name === 'protocol')) {
|
|
111
|
+
if (mraidPartners.includes(argvOptions['network']) && argvOptions['protocol'] === 'none') {
|
|
112
|
+
argvOptions['protocol'] = 'mraid';
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
argvOptions._cliExplicitKeys = cliExplicitKeys;
|
|
118
|
+
return argvOptions;
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
exports.allowedAdNetworks = allowedAdNetworks;
|
|
122
|
+
exports.allowedAdProtocols = allowedAdProtocols;
|
|
123
|
+
exports.mraidPartners = mraidPartners;
|
|
124
|
+
exports.allowedLanguages = allowedLanguages;
|
|
125
|
+
exports.allowedPlaycraftOrientations = allowedPlaycraftOrientations;
|
|
126
|
+
exports.allowedEngines = allowedEngines;
|
|
127
|
+
exports.WEB_ENGINES = WEB_ENGINES;
|
|
128
|
+
exports.isWebEngine = isWebEngine;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
2
|
* 解析 isChannelFold2Zip 相关标志
|
|
3
3
|
*
|
|
4
4
|
* isChannelFold2Zip:所有渠道(排除 preview)输出 dist/渠道名称.zip
|
|
@@ -10,5 +10,17 @@
|
|
|
10
10
|
* @param {string} params.adNetwork - 当前渠道名称
|
|
11
11
|
* @param {boolean} params.isZipOutput - 当前渠道是否本身就走 ZIP 输出流程
|
|
12
12
|
* @returns {{ isChannelFold2Zip: boolean, isZipOutputFinal: boolean }}
|
|
13
|
-
*/
|
|
14
|
-
|
|
13
|
+
*/
|
|
14
|
+
function resolveChannelFold2Zip({ isChannelFold2ZipOption, adNetwork, isZipOutput }) {
|
|
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;
|