@playcraft/devkit 1.0.31-beta.11 → 1.0.31-beta.14
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 -53
- package/cli/commands/build.js +32 -241
- package/cli/commands/builds.js +2 -13
- package/cli/commands/dev.js +1 -22
- package/cli/commands/pack.js +40 -320
- package/cli/commands/vite-dev.js +1 -7
- package/core/artifacts/emit-fonts.test.js +1 -0
- package/core/artifacts/emit.js +4 -98
- package/core/artifacts/fflate.js +1 -31
- package/core/artifacts/zip.js +1 -39
- package/core/batch-build.js +147 -1261
- package/core/constants.js +2 -20
- package/core/cos-uploader.js +23 -289
- package/core/engines/cocos/adapter-vfs-path.test.js +1 -0
- package/core/engines/cocos/clean-cache.js +5 -179
- package/core/engines/cocos/clean-cache.test.js +1 -75
- package/core/engines/cocos/cli-build.js +2 -116
- package/core/engines/cocos/cli.js +11 -38
- package/core/engines/cocos/constants.js +1 -21
- package/core/engines/cocos/creator-cli.js +1 -108
- package/core/engines/cocos/dev-server.js +4 -412
- package/core/engines/cocos/fs.js +1 -105
- package/core/engines/cocos/injects/3x/init.js +19 -438
- package/core/engines/cocos/injects/3x/main.js +2 -52
- package/core/engines/cocos/injects/libs/pako.js +1 -2
- package/core/engines/cocos/mcp-refresh.js +2 -76
- package/core/engines/cocos/merge-inline.test.js +1 -0
- package/core/engines/cocos/merge.js +9 -148
- package/core/engines/cocos/omit-playable-weight.js +10 -0
- package/core/engines/cocos/omit-playable-weight.test.js +2 -0
- package/core/engines/cocos/pack.js +1 -187
- package/core/engines/cocos/preview-cache.js +2 -48
- package/core/engines/cocos/preview-cache.test.js +1 -32
- package/core/engines/cocos/preview-concat.js +6 -189
- package/core/engines/cocos/preview-concat.test.js +1 -73
- package/core/engines/cocos/preview-json-hook.js +1 -200
- package/core/engines/cocos/preview-json-pack.js +3 -376
- package/core/engines/cocos/preview-json-pack.test.js +2 -226
- package/core/engines/cocos/preview-proxy.js +1 -132
- package/core/engines/cocos/rebundle-preview.js +2 -54
- package/core/engines/cocos/strip-social-share.js +3 -115
- package/core/engines/cocos/theme-assets.js +2 -161
- package/core/engines/cocos/theme-levels.js +1 -0
- package/core/engines/cocos/writable-cli.js +2 -248
- package/core/engines/cocos/writable-cli.test.js +1 -112
- package/core/engines/web/index.js +1 -20
- package/core/engines/web/vite.dev.js +17 -322
- package/core/engines/web/webpack.build.js +37 -522
- package/core/engines/web/webpack.common.js +11 -177
- package/core/engines/web/webpack.dev.js +6 -88
- package/core/index.js +7 -101
- package/core/injectors/apply.js +1 -94
- package/core/injectors/check-channel-matrix.js +2 -130
- package/core/injectors/spec.js +10 -217
- package/core/loaders/gltf-loader.js +28 -74
- package/core/options.js +16 -353
- 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 +160 -307
- package/core/plugins/FflateCompressionPlugin.test.js +13 -0
- 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 -154
- 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 +8 -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 -21
- package/core/utils/obfuscateLevels.js +14 -0
- package/core/utils/obfuscateLevels.test.js +10 -0
- package/core/utils/parseArgvOptions.js +5 -125
- package/core/utils/resolveChannelFold2Zip.js +3 -15
- package/core/utils/validateThemeData.js +26 -227
- package/core/validators/pre-build-checker.js +25 -287
- package/core/validators/tracking-validator.js +40 -441
- package/core/validators/tracking-validator.test.js +2 -84
- 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 +2 -3
- package/README.md +0 -262
|
@@ -1,110 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/**
|
|
1
|
+
"use strict";/**
|
|
4
2
|
* Vite dev 模式:social_media 渠道的 OG / Twitter meta 注入。
|
|
5
3
|
* 与 SocialMediaInjectorPlugin.js 输出完全一致,仅 hook 形态不同。
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const path = require('path');
|
|
9
|
-
const fs = require('fs');
|
|
10
|
-
const JSON5 = require('json5');
|
|
11
|
-
|
|
12
|
-
/** 把 shareMeta 渲染成 <meta> 标签字符串(与 webpack plugin 完全一致) */
|
|
13
|
-
function buildMetaTags(meta) {
|
|
14
|
-
if (!meta) return [];
|
|
15
|
-
const esc = (s) => String(s)
|
|
16
|
-
.replace(/&/g, '&')
|
|
17
|
-
.replace(/"/g, '"')
|
|
18
|
-
.replace(/</g, '<')
|
|
19
|
-
.replace(/>/g, '>');
|
|
20
|
-
|
|
21
|
-
const tags = [];
|
|
22
|
-
const { title, description, imageUrl, pageUrl, siteName } = meta;
|
|
23
|
-
const t = (title || '').trim();
|
|
24
|
-
const d = (description || '').trim();
|
|
25
|
-
const i = (imageUrl || '').trim();
|
|
26
|
-
const u = (pageUrl || '').trim();
|
|
27
|
-
const s = (siteName || '').trim();
|
|
28
|
-
|
|
29
|
-
if (t) tags.push({ tag: 'meta', injectTo: 'head', attrs: { property: 'og:title', content: t } });
|
|
30
|
-
if (d) tags.push({ tag: 'meta', injectTo: 'head', attrs: { property: 'og:description', content: d } });
|
|
31
|
-
if (i) tags.push({ tag: 'meta', injectTo: 'head', attrs: { property: 'og:image', content: i } });
|
|
32
|
-
if (u) tags.push({ tag: 'meta', injectTo: 'head', attrs: { property: 'og:url', content: u } });
|
|
33
|
-
if (s) tags.push({ tag: 'meta', injectTo: 'head', attrs: { property: 'og:site_name', content: s } });
|
|
34
|
-
tags.push({ tag: 'meta', injectTo: 'head', attrs: { property: 'og:type', content: 'website' } });
|
|
35
|
-
|
|
36
|
-
tags.push({ tag: 'meta', injectTo: 'head', attrs: { name: 'twitter:card', content: 'summary_large_image' } });
|
|
37
|
-
if (t) tags.push({ tag: 'meta', injectTo: 'head', attrs: { name: 'twitter:title', content: t } });
|
|
38
|
-
if (d) tags.push({ tag: 'meta', injectTo: 'head', attrs: { name: 'twitter:description', content: d } });
|
|
39
|
-
if (i) tags.push({ tag: 'meta', injectTo: 'head', attrs: { name: 'twitter:image', content: i } });
|
|
40
|
-
return tags;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/** 检测主题名(与 fontFamilyPlugin 逻辑保持一致) */
|
|
44
|
-
function detectTheme() {
|
|
45
|
-
const root = process.cwd();
|
|
46
|
-
const buildsConfigPath = path.join(root, 'builds.config.js');
|
|
47
|
-
let config = { sourceDir: 'src/theme', entryFile: 'src/theme/index.ts' };
|
|
48
|
-
if (fs.existsSync(buildsConfigPath)) {
|
|
49
|
-
try {
|
|
50
|
-
delete require.cache[require.resolve(buildsConfigPath)];
|
|
51
|
-
const bc = require(buildsConfigPath);
|
|
52
|
-
if (bc.themes) config = { ...config, ...bc.themes };
|
|
53
|
-
} catch (_) { /* ignore */ }
|
|
54
|
-
}
|
|
55
|
-
let name = null;
|
|
56
|
-
const entryPath = path.join(root, config.entryFile);
|
|
57
|
-
if (fs.existsSync(entryPath)) {
|
|
58
|
-
const content = fs.readFileSync(entryPath, 'utf8');
|
|
59
|
-
const m = content.match(/from\s+['"]\.\/([^'"]+)['"]/);
|
|
60
|
-
if (m) name = m[1];
|
|
61
|
-
}
|
|
62
|
-
return { themeName: name, themeConfig: config };
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/** 读取 shareMeta,缓存以避免 transformIndexHtml 多次触发时反复读盘 */
|
|
66
|
-
let _cache = { key: null, value: null };
|
|
67
|
-
|
|
68
|
-
function loadShareMeta() {
|
|
69
|
-
const { themeName, themeConfig } = detectTheme();
|
|
70
|
-
if (!themeName) return null;
|
|
71
|
-
const root = process.cwd();
|
|
72
|
-
const dataPath = path.join(
|
|
73
|
-
root,
|
|
74
|
-
themeConfig.sourceDir || 'src/theme',
|
|
75
|
-
themeName,
|
|
76
|
-
'theme.data.json5'
|
|
77
|
-
);
|
|
78
|
-
if (!fs.existsSync(dataPath)) return null;
|
|
79
|
-
const stat = fs.statSync(dataPath);
|
|
80
|
-
const key = `${dataPath}::${stat.mtimeMs}`;
|
|
81
|
-
if (_cache.key === key) return _cache.value;
|
|
82
|
-
try {
|
|
83
|
-
const raw = fs.readFileSync(dataPath, 'utf8');
|
|
84
|
-
const parsed = JSON5.parse(raw);
|
|
85
|
-
const value = parsed && parsed.gamePlay && parsed.gamePlay.shareMeta
|
|
86
|
-
? parsed.gamePlay.shareMeta
|
|
87
|
-
: null;
|
|
88
|
-
_cache = { key, value };
|
|
89
|
-
return value;
|
|
90
|
-
} catch (e) {
|
|
91
|
-
console.warn('[socialMediaVitePlugin] Failed to read theme.data.json5:', e.message);
|
|
92
|
-
return null;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function socialMediaVitePlugin() {
|
|
97
|
-
return {
|
|
98
|
-
name: 'vite-plugin-social-media',
|
|
99
|
-
apply: 'serve',
|
|
100
|
-
transformIndexHtml: {
|
|
101
|
-
order: 'pre',
|
|
102
|
-
handler() {
|
|
103
|
-
const meta = loadShareMeta();
|
|
104
|
-
return buildMetaTags(meta);
|
|
105
|
-
},
|
|
106
|
-
},
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
module.exports = { socialMediaVitePlugin, buildMetaTags };
|
|
4
|
+
*/const path=require("path");const fs=require("fs");const JSON5=require("json5");/** 把 shareMeta 渲染成 <meta> 标签字符串(与 webpack plugin 完全一致) */function buildMetaTags(meta){if(!meta)return[];const esc=s=>String(s).replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">");const tags=[];const{title,description,imageUrl,pageUrl,siteName}=meta;const t=(title||"").trim();const d=(description||"").trim();const i=(imageUrl||"").trim();const u=(pageUrl||"").trim();const s=(siteName||"").trim();if(t)tags.push({tag:"meta",injectTo:"head",attrs:{property:"og:title",content:t}});if(d)tags.push({tag:"meta",injectTo:"head",attrs:{property:"og:description",content:d}});if(i)tags.push({tag:"meta",injectTo:"head",attrs:{property:"og:image",content:i}});if(u)tags.push({tag:"meta",injectTo:"head",attrs:{property:"og:url",content:u}});if(s)tags.push({tag:"meta",injectTo:"head",attrs:{property:"og:site_name",content:s}});tags.push({tag:"meta",injectTo:"head",attrs:{property:"og:type",content:"website"}});tags.push({tag:"meta",injectTo:"head",attrs:{name:"twitter:card",content:"summary_large_image"}});if(t)tags.push({tag:"meta",injectTo:"head",attrs:{name:"twitter:title",content:t}});if(d)tags.push({tag:"meta",injectTo:"head",attrs:{name:"twitter:description",content:d}});if(i)tags.push({tag:"meta",injectTo:"head",attrs:{name:"twitter:image",content:i}});return tags}/** 检测主题名(与 fontFamilyPlugin 逻辑保持一致) */function detectTheme(){const root=process.cwd();const buildsConfigPath=path.join(root,"builds.config.js");let config={sourceDir:"src/theme",entryFile:"src/theme/index.ts"};if(fs.existsSync(buildsConfigPath)){try{delete require.cache[require.resolve(buildsConfigPath)];const bc=require(buildsConfigPath);if(bc.themes)config={...config,...bc.themes}}catch(_){/* ignore */}}let name=null;const entryPath=path.join(root,config.entryFile);if(fs.existsSync(entryPath)){const content=fs.readFileSync(entryPath,"utf8");const m=content.match(/from\s+['"]\.\/([^'"]+)['"]/);if(m)name=m[1]}return{themeName:name,themeConfig:config}}/** 读取 shareMeta,缓存以避免 transformIndexHtml 多次触发时反复读盘 */let _cache={key:null,value:null};function loadShareMeta(){const{themeName,themeConfig}=detectTheme();if(!themeName)return null;const root=process.cwd();const dataPath=path.join(root,themeConfig.sourceDir||"src/theme",themeName,"theme.data.json5");if(!fs.existsSync(dataPath))return null;const stat=fs.statSync(dataPath);const key=`${dataPath}::${stat.mtimeMs}`;if(_cache.key===key)return _cache.value;try{const raw=fs.readFileSync(dataPath,"utf8");const parsed=JSON5.parse(raw);const value=parsed&&parsed.gamePlay&&parsed.gamePlay.shareMeta?parsed.gamePlay.shareMeta:null;_cache={key,value};return value}catch(e){console.warn("[socialMediaVitePlugin] Failed to read theme.data.json5:",e.message);return null}}function socialMediaVitePlugin(){return{name:"vite-plugin-social-media",apply:"serve",transformIndexHtml:{order:"pre",handler(){const meta=loadShareMeta();return buildMetaTags(meta)}}}}module.exports={socialMediaVitePlugin,buildMetaTags};
|
|
@@ -1,32 +1,4 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
/**
|
|
1
|
+
"use strict";const{options}=require("../options");/**
|
|
4
2
|
* Build's default defines list for dev & prod builds
|
|
5
3
|
* @param {import('../index').CLIOptions} [customOptions] - 合并后的当前构建选项(用于读取会随单次构建变化的字段,如 playcraftOrientationValue);未提供时回退到全局 options
|
|
6
|
-
*/
|
|
7
|
-
exports.buildDefines = function buildDefines(customOptions) {
|
|
8
|
-
const opts = customOptions || options;
|
|
9
|
-
const defines = {
|
|
10
|
-
__DEV__: JSON.stringify(opts['dev'] === undefined ? false : opts['dev']),
|
|
11
|
-
GOOGLE_PLAY_URL: JSON.stringify(opts.googlePlayUrl),
|
|
12
|
-
APP_STORE_URL: JSON.stringify(opts.appStoreUrl),
|
|
13
|
-
AD_NETWORK: JSON.stringify(opts['network']),
|
|
14
|
-
AD_PROTOCOL: JSON.stringify(opts['protocol']),
|
|
15
|
-
APP: JSON.stringify(opts.app),
|
|
16
|
-
NAME: JSON.stringify(opts.name),
|
|
17
|
-
VERSION: JSON.stringify(opts.version),
|
|
18
|
-
BUILD_HASH: JSON.stringify((+new Date()).toString(36)),
|
|
19
|
-
LANGUAGE: JSON.stringify(opts.language),
|
|
20
|
-
PLAYCRAFT_ORIENTATION: JSON.stringify(opts.playcraftOrientationValue || 'both')
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
/** @type {AD_NETWORK} */
|
|
24
|
-
let adNetworkDefine = opts['network'];
|
|
25
|
-
|
|
26
|
-
if (adNetworkDefine === 'pangle') adNetworkDefine = 'tiktok';
|
|
27
|
-
if (adNetworkDefine === 'mytarget' || adNetworkDefine === 'moloco') adNetworkDefine = 'facebook';
|
|
28
|
-
|
|
29
|
-
defines['AD_NETWORK'] = JSON.stringify(adNetworkDefine);
|
|
30
|
-
|
|
31
|
-
return defines;
|
|
32
|
-
};
|
|
4
|
+
*/exports.buildDefines=function buildDefines(customOptions){const opts=customOptions||options;const defines={__DEV__:JSON.stringify(opts["dev"]===undefined?false:opts["dev"]),GOOGLE_PLAY_URL:JSON.stringify(opts.googlePlayUrl),APP_STORE_URL:JSON.stringify(opts.appStoreUrl),AD_NETWORK:JSON.stringify(opts["network"]),AD_PROTOCOL:JSON.stringify(opts["protocol"]),APP:JSON.stringify(opts.app),NAME:JSON.stringify(opts.name),VERSION:JSON.stringify(opts.version),BUILD_HASH:JSON.stringify((+new Date).toString(36)),LANGUAGE:JSON.stringify(opts.language),PLAYCRAFT_ORIENTATION:JSON.stringify(opts.playcraftOrientationValue||"both")};/** @type {AD_NETWORK} */let adNetworkDefine=opts["network"];if(adNetworkDefine==="pangle")adNetworkDefine="tiktok";if(adNetworkDefine==="mytarget"||adNetworkDefine==="moloco")adNetworkDefine="facebook";defines["AD_NETWORK"]=JSON.stringify(adNetworkDefine);return defines};
|
|
@@ -1,40 +1,6 @@
|
|
|
1
|
-
const
|
|
2
|
-
const { getCurrentDateFormatted } = require('./date');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
|
|
5
|
-
/** @type {Record<string, string>} Mapping of ad network identifiers to their display names in filenames */
|
|
6
|
-
const adNetworkFileNameMap = {
|
|
7
|
-
preview: 'Preview',
|
|
8
|
-
bigoads: 'bigo'
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
/**
|
|
1
|
+
"use strict";const{options}=require("../options");const{getCurrentDateFormatted}=require("./date");const path=require("path");/** @type {Record<string, string>} Mapping of ad network identifiers to their display names in filenames */const adNetworkFileNameMap={preview:"Preview",bigoads:"bigo"};/**
|
|
12
2
|
* Build's result string from template. Used for outDir or filename
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
/** @type {AD_NETWORK} */
|
|
18
|
-
const adNetwork = customOptions['network'];
|
|
19
|
-
|
|
20
|
-
/** @type {AD_PROTOCOL} */
|
|
21
|
-
// const adProtocol = customOptions['protocol'];
|
|
22
|
-
|
|
23
|
-
let networkName = customOptions.adNetworkNames[adNetwork] || adNetworkFileNameMap[adNetwork] || adNetwork;
|
|
24
|
-
// if (adProtocol === 'dapi') networkName += '_DAPI';
|
|
25
|
-
|
|
26
|
-
// 如果是绝对路径,直接返回,不做模板替换
|
|
27
|
-
if (path.isAbsolute(template)) {
|
|
28
|
-
return template;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
template = template.replaceAll('{app}', customOptions.app);
|
|
32
|
-
template = template.replaceAll('{name}', customOptions.name);
|
|
33
|
-
template = template.replaceAll('{version}', customOptions.version);
|
|
34
|
-
template = template.replaceAll('{date}', getCurrentDateFormatted());
|
|
35
|
-
template = template.replaceAll('{language}', customOptions.language);
|
|
36
|
-
template = template.replaceAll('{network}', networkName.toLowerCase());
|
|
37
|
-
template = template.replaceAll('{hash}', '[fullhash:6]');
|
|
38
|
-
|
|
39
|
-
return template;
|
|
40
|
-
};
|
|
3
|
+
*/exports.buildTemplateString=function buildTemplateString(template,customOptions){customOptions=customOptions||options;/** @type {AD_NETWORK} */const adNetwork=customOptions["network"];/** @type {AD_PROTOCOL} */// const adProtocol = customOptions['protocol'];
|
|
4
|
+
let networkName=customOptions.adNetworkNames[adNetwork]||adNetworkFileNameMap[adNetwork]||adNetwork;// if (adProtocol === 'dapi') networkName += '_DAPI';
|
|
5
|
+
// 如果是绝对路径,直接返回,不做模板替换
|
|
6
|
+
if(path.isAbsolute(template)){return template}template=template.replaceAll("{app}",customOptions.app);template=template.replaceAll("{name}",customOptions.name);template=template.replaceAll("{version}",customOptions.version);template=template.replaceAll("{date}",getCurrentDateFormatted());template=template.replaceAll("{language}",customOptions.language);template=template.replaceAll("{network}",networkName.toLowerCase());template=template.replaceAll("{hash}","[fullhash:6]");return template};
|
package/core/utils/date.js
CHANGED
|
@@ -1,16 +1 @@
|
|
|
1
|
-
exports.getCurrentDateFormatted
|
|
2
|
-
const date = new Date();
|
|
3
|
-
const year = date.getFullYear();
|
|
4
|
-
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
5
|
-
const day = date.getDate().toString().padStart(2, '0');
|
|
6
|
-
|
|
7
|
-
if (includeTime) {
|
|
8
|
-
const hour = date.getHours().toString().padStart(2, '0');
|
|
9
|
-
const minute = date.getMinutes().toString().padStart(2, '0');
|
|
10
|
-
const second = date.getSeconds().toString().padStart(2, '0');
|
|
11
|
-
|
|
12
|
-
return `${year}${month}${day}-${hour}${minute}${second}`;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
return `${year}${month}${day}`;
|
|
16
|
-
};
|
|
1
|
+
"use strict";exports.getCurrentDateFormatted=function getCurrentDateFormatted(includeTime){const date=new Date;const year=date.getFullYear();const month=(date.getMonth()+1).toString().padStart(2,"0");const day=date.getDate().toString().padStart(2,"0");if(includeTime){const hour=date.getHours().toString().padStart(2,"0");const minute=date.getMinutes().toString().padStart(2,"0");const second=date.getSeconds().toString().padStart(2,"0");return`${year}${month}${day}-${hour}${minute}${second}`}return`${year}${month}${day}`};
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/**
|
|
1
|
+
"use strict";/**
|
|
4
2
|
* 平台预置字体字典。
|
|
5
3
|
*
|
|
6
4
|
* 所有字体文件内置于 playable-scripts/core/resources/fonts/ 目录下。
|
|
@@ -11,87 +9,21 @@
|
|
|
11
9
|
* - builtin=false: 需要从本地字体文件读取并 base64 内联到产物中
|
|
12
10
|
*
|
|
13
11
|
* key 命名规范:与 theme.schema.json5 中 fontFamily 的 enum 值一一对应。
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
// ===== 系统自带字体(无需注入) =====
|
|
23
|
-
system: {
|
|
24
|
-
builtin: true,
|
|
25
|
-
fallback: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
|
|
26
|
-
},
|
|
27
|
-
Arial: {
|
|
28
|
-
builtin: true,
|
|
29
|
-
fallback: 'Arial, Helvetica, sans-serif',
|
|
30
|
-
},
|
|
31
|
-
monaco: {
|
|
32
|
-
builtin: true,
|
|
33
|
-
fallback: 'Monaco, "Courier New", monospace',
|
|
34
|
-
},
|
|
35
|
-
|
|
36
|
-
// ===== 平台内置字体(base64 内联注入) =====
|
|
37
|
-
// key 必须与 theme.schema.json5 fontFamily.enum 值完全一致
|
|
38
|
-
|
|
39
|
-
// Google Fonts 字体:单文件 woff2
|
|
40
|
-
Poppins: {
|
|
41
|
-
builtin: false,
|
|
42
|
-
fontFileName: 'poppins-regular.woff2',
|
|
43
|
-
cssFamily: 'Poppins, sans-serif',
|
|
44
|
-
},
|
|
45
|
-
'Noto Sans SC': {
|
|
46
|
-
builtin: false,
|
|
47
|
-
fontFileName: 'noto-sans-sc-regular.woff2',
|
|
48
|
-
cssFamily: '"Noto Sans SC", sans-serif',
|
|
49
|
-
},
|
|
50
|
-
|
|
51
|
-
// 本地 ttf 种子字体(单文件 woff2,由 download-fonts.js 用 pyftsubset 生成)
|
|
52
|
-
'Pangmen Zhengdao': {
|
|
53
|
-
builtin: false,
|
|
54
|
-
fontFileName: 'pangmen-regular.woff2', // 由 pangmen-biaoti.ttf subset 生成
|
|
55
|
-
cssFamily: '"Pangmen Zhengdao", sans-serif',
|
|
56
|
-
},
|
|
57
|
-
|
|
58
|
-
// ZeoSeven 字体:unicode-range 子集(build 时按需筛选)
|
|
59
|
-
'Maoken Zhuyuan Ti': {
|
|
60
|
-
builtin: false,
|
|
61
|
-
subsetsDir: 'maoken',
|
|
62
|
-
fontFileName: 'maoken-regular.woff2',
|
|
63
|
-
cssFamily: '"Maoken Zhuyuan Ti", sans-serif',
|
|
64
|
-
},
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
/**
|
|
12
|
+
*/const path=require("path");/** 字体资源目录(随 npm 包发布) */const FONTS_DIR=path.join(__dirname,"..","resources","fonts");const FONT_REGISTRY={// ===== 系统自带字体(无需注入) =====
|
|
13
|
+
system:{builtin:true,fallback:"system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif"},Arial:{builtin:true,fallback:"Arial, Helvetica, sans-serif"},monaco:{builtin:true,fallback:"Monaco, \"Courier New\", monospace"},// ===== 平台内置字体(base64 内联注入) =====
|
|
14
|
+
// key 必须与 theme.schema.json5 fontFamily.enum 值完全一致
|
|
15
|
+
// Google Fonts 字体:单文件 woff2
|
|
16
|
+
Poppins:{builtin:false,fontFileName:"poppins-regular.woff2",cssFamily:"Poppins, sans-serif"},"Noto Sans SC":{builtin:false,fontFileName:"noto-sans-sc-regular.woff2",cssFamily:"\"Noto Sans SC\", sans-serif"},// 本地 ttf 种子字体(单文件 woff2,由 download-fonts.js 用 pyftsubset 生成)
|
|
17
|
+
"Pangmen Zhengdao":{builtin:false,fontFileName:"pangmen-regular.woff2",// 由 pangmen-biaoti.ttf subset 生成
|
|
18
|
+
cssFamily:"\"Pangmen Zhengdao\", sans-serif"},// ZeoSeven 字体:unicode-range 子集(build 时按需筛选)
|
|
19
|
+
"Maoken Zhuyuan Ti":{builtin:false,subsetsDir:"maoken",fontFileName:"maoken-regular.woff2",cssFamily:"\"Maoken Zhuyuan Ti\", sans-serif"}};/**
|
|
68
20
|
* @returns {string[]} 所有已注册的字体 key 列表
|
|
69
|
-
*/
|
|
70
|
-
function getRegisteredFontKeys() {
|
|
71
|
-
return Object.keys(FONT_REGISTRY);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
21
|
+
*/function getRegisteredFontKeys(){return Object.keys(FONT_REGISTRY)}/**
|
|
75
22
|
* @param {string} key - 字体 key
|
|
76
23
|
* @returns {boolean} 是否为系统自带字体
|
|
77
|
-
*/
|
|
78
|
-
function isBuiltin(key) {
|
|
79
|
-
return !!(FONT_REGISTRY[key] && FONT_REGISTRY[key].builtin);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
24
|
+
*/function isBuiltin(key){return!!(FONT_REGISTRY[key]&&FONT_REGISTRY[key].builtin)}/**
|
|
83
25
|
* @param {string} key - 字体 key
|
|
84
26
|
* @returns {object|null} 字体配置对象,未注册返回 null
|
|
85
|
-
*/
|
|
86
|
-
function getFontEntry(key) {
|
|
87
|
-
return FONT_REGISTRY[key] || null;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
27
|
+
*/function getFontEntry(key){return FONT_REGISTRY[key]||null}/**
|
|
91
28
|
* @returns {string} 字体资源目录绝对路径
|
|
92
|
-
*/
|
|
93
|
-
function getFontsDir() {
|
|
94
|
-
return FONTS_DIR;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
module.exports = { FONT_REGISTRY, getRegisteredFontKeys, isBuiltin, getFontEntry, getFontsDir };
|
|
29
|
+
*/function getFontsDir(){return FONTS_DIR}module.exports={FONT_REGISTRY,getRegisteredFontKeys,isBuiltin,getFontEntry,getFontsDir};
|