zcw-shared 1.38.2 → 1.40.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants/hybridConstants.d.ts +37 -0
- package/dist/constants/hybridConstants.js +38 -0
- package/dist/constants/hybridConstants.js.map +1 -0
- package/dist/functions/hybrid/createBridgeMessage.d.ts +25 -0
- package/dist/functions/hybrid/createBridgeMessage.js +33 -0
- package/dist/functions/hybrid/createBridgeMessage.js.map +1 -0
- package/dist/functions/hybrid/detectBridgeEnvironment.d.ts +11 -0
- package/dist/functions/hybrid/detectBridgeEnvironment.js +26 -0
- package/dist/functions/hybrid/detectBridgeEnvironment.js.map +1 -0
- package/dist/functions/hybrid/generateBridgeMessageId.d.ts +10 -0
- package/dist/functions/hybrid/generateBridgeMessageId.js +11 -0
- package/dist/functions/hybrid/generateBridgeMessageId.js.map +1 -0
- package/dist/functions/hybrid/postBridgeMessage.d.ts +16 -0
- package/dist/functions/hybrid/postBridgeMessage.js +68 -0
- package/dist/functions/hybrid/postBridgeMessage.js.map +1 -0
- package/dist/functions/hybrid/validateBridgeMessage.d.ts +5 -0
- package/dist/functions/hybrid/validateBridgeMessage.js +55 -0
- package/dist/functions/hybrid/validateBridgeMessage.js.map +1 -0
- package/dist/functions/ios/integrateThirdPartyModule.js +1 -44
- package/dist/functions/ios/integrateThirdPartyModule.js.map +1 -1
- package/dist/functions/ios/modifyInfoPlistKeyValue.d.ts +2 -0
- package/dist/functions/ios/modifyInfoPlistKeyValue.js +45 -0
- package/dist/functions/ios/modifyInfoPlistKeyValue.js.map +1 -0
- package/dist/functions/ios/safelyModifyProjectPbxproj.d.ts +16 -0
- package/dist/functions/ios/safelyModifyProjectPbxproj.js +87 -0
- package/dist/functions/ios/safelyModifyProjectPbxproj.js.map +1 -0
- package/dist/functions/uniapp/app-plus/buildAndroidApp.d.ts +1 -0
- package/dist/functions/uniapp/app-plus/buildAndroidApp.js +190 -111
- package/dist/functions/uniapp/app-plus/buildAndroidApp.js.map +1 -1
- package/dist/functions/uniapp/app-plus/buildAndroidPlugin.d.ts +3 -0
- package/dist/functions/uniapp/app-plus/buildAndroidPlugin.js +501 -0
- package/dist/functions/uniapp/app-plus/buildAndroidPlugin.js.map +1 -0
- package/dist/functions/uniapp/app-plus/buildIOSApp.d.ts +2 -2
- package/dist/functions/uniapp/app-plus/buildIOSApp.js +94 -521
- package/dist/functions/uniapp/app-plus/buildIOSApp.js.map +1 -1
- package/dist/functions/uniapp/app-plus/buildIOSPlugin.d.ts +3 -0
- package/dist/functions/uniapp/app-plus/buildIOSPlugin.js +383 -0
- package/dist/functions/uniapp/app-plus/buildIOSPlugin.js.map +1 -0
- package/dist/hybrid/constants.d.ts +37 -0
- package/dist/hybrid/constants.js +38 -0
- package/dist/hybrid/constants.js.map +1 -0
- package/dist/hybrid/createBridgeMessage.d.ts +17 -0
- package/dist/hybrid/createBridgeMessage.js +81 -0
- package/dist/hybrid/createBridgeMessage.js.map +1 -0
- package/dist/hybrid/types.d.ts +88 -0
- package/dist/hybrid/types.js +2 -0
- package/dist/hybrid/types.js.map +1 -0
- package/dist/vue-hooks/browser/useBridgeMessage.d.ts +34 -0
- package/dist/vue-hooks/browser/useBridgeMessage.js +87 -0
- package/dist/vue-hooks/browser/useBridgeMessage.js.map +1 -0
- package/dist/vue-hooks/browser/useWechatJSSDK.d.ts +2 -0
- package/dist/vue-hooks/browser/useWechatJSSDK.js +16 -1
- package/dist/vue-hooks/browser/useWechatJSSDK.js.map +1 -1
- package/package.json +13 -3
- package/references/hybrid.d.ts +83 -0
- package/types/hybrid.d.ts +119 -0
- package/types/uniapp-android-build.d.ts +25 -0
|
@@ -1,138 +1,13 @@
|
|
|
1
1
|
import { parseManifest } from '../parseManifest';
|
|
2
2
|
import { build } from '../build';
|
|
3
|
-
import { modifyManifest } from '../../android/modifyManifest';
|
|
4
3
|
import { integrateWechatShareIOS } from '../../ios/integrateWechatShare';
|
|
5
4
|
import { integrateWechatOauthIOS } from '../../ios/integrateWechatOauth';
|
|
6
5
|
import { integrateQQShareIOS } from '../../ios/integrateQQShare';
|
|
7
6
|
import { integrateSinaShareIOS } from '../../ios/integrateSinaShare';
|
|
8
7
|
import { integrateNativePluginIOS } from '../../ios/integrateNativePlugin';
|
|
9
8
|
import { configureLaunchScreen } from '../../ios/configureLaunchScreen';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if (!dictElement)
|
|
13
|
-
return false;
|
|
14
|
-
const childNodes = Array.from(dictElement.childNodes || []).filter((node) => node.nodeType === 1);
|
|
15
|
-
let found = false;
|
|
16
|
-
for (let i = 0; i < childNodes.length; i++) {
|
|
17
|
-
const node = childNodes[i];
|
|
18
|
-
if (node.nodeName === 'key' && node.textContent === keyName) {
|
|
19
|
-
if (i + 1 < childNodes.length) {
|
|
20
|
-
const valueNode = childNodes[i + 1];
|
|
21
|
-
if (valueType === 'string' && valueNode.nodeName === 'string') {
|
|
22
|
-
valueNode.textContent = value;
|
|
23
|
-
found = true;
|
|
24
|
-
}
|
|
25
|
-
else if (valueType === 'true' && (valueNode.nodeName === 'true' || valueNode.nodeName === 'false')) {
|
|
26
|
-
const trueElement = xmlDoc.createElement('true');
|
|
27
|
-
const parentNode = valueNode.parentNode;
|
|
28
|
-
if (parentNode && 'replaceChild' in parentNode) {
|
|
29
|
-
parentNode.replaceChild(trueElement, valueNode);
|
|
30
|
-
}
|
|
31
|
-
found = true;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
break;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
if (!found) {
|
|
38
|
-
const keyElement = xmlDoc.createElement('key');
|
|
39
|
-
keyElement.textContent = keyName;
|
|
40
|
-
let valueElement;
|
|
41
|
-
if (valueType === 'string') {
|
|
42
|
-
valueElement = xmlDoc.createElement('string');
|
|
43
|
-
valueElement.textContent = value;
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
valueElement = xmlDoc.createElement('true');
|
|
47
|
-
}
|
|
48
|
-
dictElement.appendChild(keyElement);
|
|
49
|
-
dictElement.appendChild(valueElement);
|
|
50
|
-
found = true;
|
|
51
|
-
}
|
|
52
|
-
return found;
|
|
53
|
-
}
|
|
54
|
-
function safelyModifyProjectPbxproj(projectPbxprojPath, options, deps) {
|
|
55
|
-
try {
|
|
56
|
-
if (!deps.existsSync(projectPbxprojPath)) {
|
|
57
|
-
return { success: false, error: `project.pbxproj 文件不存在: ${projectPbxprojPath}` };
|
|
58
|
-
}
|
|
59
|
-
let content = deps.readFileSync(projectPbxprojPath, 'utf8');
|
|
60
|
-
let modified = false;
|
|
61
|
-
if (options.bundleId) {
|
|
62
|
-
const bundleIdRegex = /PRODUCT_BUNDLE_IDENTIFIER\s*=\s*[^;]+;/g;
|
|
63
|
-
if (bundleIdRegex.test(content)) {
|
|
64
|
-
content = content.replace(bundleIdRegex, `PRODUCT_BUNDLE_IDENTIFIER = ${options.bundleId};`);
|
|
65
|
-
modified = true;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
if (options.version) {
|
|
69
|
-
const marketingVersionRegex = /MARKETING_VERSION\s*=\s*[^;]+;/g;
|
|
70
|
-
if (marketingVersionRegex.test(content)) {
|
|
71
|
-
content = content.replace(marketingVersionRegex, `MARKETING_VERSION = ${options.version};`);
|
|
72
|
-
modified = true;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
if (options.buildNumber) {
|
|
76
|
-
const currentProjectVersionRegex = /CURRENT_PROJECT_VERSION\s*=\s*[^;]+;/g;
|
|
77
|
-
if (currentProjectVersionRegex.test(content)) {
|
|
78
|
-
content = content.replace(currentProjectVersionRegex, `CURRENT_PROJECT_VERSION = ${options.buildNumber};`);
|
|
79
|
-
modified = true;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
if (options.teamId) {
|
|
83
|
-
const devTeamRegex = /DEVELOPMENT_TEAM\s*=\s*[^;]+;/g;
|
|
84
|
-
if (devTeamRegex.test(content)) {
|
|
85
|
-
content = content.replace(devTeamRegex, `DEVELOPMENT_TEAM = ${options.teamId};`);
|
|
86
|
-
modified = true;
|
|
87
|
-
}
|
|
88
|
-
const devTeamSdkRegex = /"DEVELOPMENT_TEAM\[sdk=iphoneos\*\]"\s*=\s*[^;]+;/g;
|
|
89
|
-
if (devTeamSdkRegex.test(content)) {
|
|
90
|
-
content = content.replace(devTeamSdkRegex, `"DEVELOPMENT_TEAM[sdk=iphoneos*]" = ${options.teamId};`);
|
|
91
|
-
modified = true;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
if (options.codeSignIdentity) {
|
|
95
|
-
const identity = options.codeSignIdentity;
|
|
96
|
-
const codeSignIdentityRegex = /CODE_SIGN_IDENTITY\s*=\s*"[^"]*";/g;
|
|
97
|
-
if (codeSignIdentityRegex.test(content)) {
|
|
98
|
-
content = content.replace(codeSignIdentityRegex, `CODE_SIGN_IDENTITY = "${identity}";`);
|
|
99
|
-
modified = true;
|
|
100
|
-
}
|
|
101
|
-
const codeSignIdentitySdkRegex = /"CODE_SIGN_IDENTITY\[sdk=iphoneos\*\]"\s*=\s*"[^"]*";/g;
|
|
102
|
-
if (codeSignIdentitySdkRegex.test(content)) {
|
|
103
|
-
content = content.replace(codeSignIdentitySdkRegex, `"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "${identity}";`);
|
|
104
|
-
modified = true;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
if (options.clearProvisioningProfile !== false) {
|
|
108
|
-
const provProfileRegex = /PROVISIONING_PROFILE\s*=\s*"[^"]*";/g;
|
|
109
|
-
if (provProfileRegex.test(content)) {
|
|
110
|
-
content = content.replace(provProfileRegex, `PROVISIONING_PROFILE = "";`);
|
|
111
|
-
modified = true;
|
|
112
|
-
}
|
|
113
|
-
const provProfileSpecifierRegex = /PROVISIONING_PROFILE_SPECIFIER\s*=\s*"[^"]*";/g;
|
|
114
|
-
if (provProfileSpecifierRegex.test(content)) {
|
|
115
|
-
content = content.replace(provProfileSpecifierRegex, `PROVISIONING_PROFILE_SPECIFIER = "";`);
|
|
116
|
-
modified = true;
|
|
117
|
-
}
|
|
118
|
-
const provProfileSpecifierSdkRegex = /"PROVISIONING_PROFILE_SPECIFIER\[sdk=iphoneos\*\]"\s*=\s*"[^"]*";/g;
|
|
119
|
-
if (provProfileSpecifierSdkRegex.test(content)) {
|
|
120
|
-
content = content.replace(provProfileSpecifierSdkRegex, `"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "";`);
|
|
121
|
-
modified = true;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
if (modified) {
|
|
125
|
-
deps.writeFileSync(projectPbxprojPath, content, 'utf8');
|
|
126
|
-
}
|
|
127
|
-
return { success: true };
|
|
128
|
-
}
|
|
129
|
-
catch (error) {
|
|
130
|
-
return {
|
|
131
|
-
success: false,
|
|
132
|
-
error: `修改 project.pbxproj 失败: ${error instanceof Error ? error.message : String(error)}`
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
}
|
|
9
|
+
import { modifyInfoPlistKeyValue } from '../../ios/modifyInfoPlistKeyValue';
|
|
10
|
+
import { safelyModifyProjectPbxproj } from '../../ios/safelyModifyProjectPbxproj';
|
|
136
11
|
export async function buildIOSApp(options, deps) {
|
|
137
12
|
const logs = [];
|
|
138
13
|
if (!options.uniappProjectPath) {
|
|
@@ -242,7 +117,7 @@ export async function buildIOSApp(options, deps) {
|
|
|
242
117
|
}
|
|
243
118
|
}
|
|
244
119
|
if (options.buildCustomBase) {
|
|
245
|
-
modifyInfoPlistKeyValue(xmlDoc, 'UIFileSharingEnabled',
|
|
120
|
+
modifyInfoPlistKeyValue(xmlDoc, 'UIFileSharingEnabled', true, 'true');
|
|
246
121
|
}
|
|
247
122
|
const serializer = new deps.xmlSerializer();
|
|
248
123
|
const newXmlContent = serializer.serializeToString(xmlDoc);
|
|
@@ -292,33 +167,38 @@ export async function buildIOSApp(options, deps) {
|
|
|
292
167
|
logs.push('步骤 4: 配置自定义基座(control.xml)');
|
|
293
168
|
const controlXmlPath = deps.join(options.projectPath, projectName, 'control.xml');
|
|
294
169
|
if (deps.existsSync(controlXmlPath)) {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
170
|
+
try {
|
|
171
|
+
const xmlContent = deps.readFileSync(controlXmlPath, 'utf8');
|
|
172
|
+
const parser = new deps.xmlParser();
|
|
173
|
+
const xmlDoc = parser.parseFromString(xmlContent, 'text/xml');
|
|
174
|
+
const hbuilderElements = xmlDoc.getElementsByTagName('HBuilder');
|
|
175
|
+
if (hbuilderElements.length > 0) {
|
|
176
|
+
const hbuilderElement = hbuilderElements[0];
|
|
177
|
+
let hasChanges = false;
|
|
178
|
+
if (hbuilderElement.getAttribute('debug') !== 'true') {
|
|
179
|
+
hbuilderElement.setAttribute('debug', 'true');
|
|
180
|
+
hasChanges = true;
|
|
181
|
+
}
|
|
182
|
+
if (hbuilderElement.getAttribute('syncDebug') !== 'true') {
|
|
183
|
+
hbuilderElement.setAttribute('syncDebug', 'true');
|
|
184
|
+
hasChanges = true;
|
|
185
|
+
}
|
|
186
|
+
if (hasChanges) {
|
|
187
|
+
const serializer = new deps.xmlSerializer();
|
|
188
|
+
const newXmlContent = serializer.serializeToString(xmlDoc);
|
|
189
|
+
deps.writeFileSync(controlXmlPath, newXmlContent, 'utf8');
|
|
190
|
+
logs.push('control.xml 自定义基座配置完成:debug="true" syncDebug="true"');
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
logs.push('control.xml 自定义基座配置已存在,无需修改');
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
logs.push('警告:未找到 HBuilder 根节点,无法添加自定义基座配置');
|
|
307
198
|
}
|
|
308
|
-
];
|
|
309
|
-
const controlResult = await modifyManifest(controlXmlPath, controlModifications, {
|
|
310
|
-
existsSync: deps.existsSync,
|
|
311
|
-
readFileSync: deps.readFileSync,
|
|
312
|
-
writeFileSync: deps.writeFileSync,
|
|
313
|
-
xmlParser: deps.xmlParser,
|
|
314
|
-
xmlSerializer: deps.xmlSerializer,
|
|
315
|
-
xpath: deps.xpath
|
|
316
|
-
});
|
|
317
|
-
if (controlResult.success) {
|
|
318
|
-
logs.push('control.xml 自定义基座配置完成:debug="true" syncDebug="true"');
|
|
319
199
|
}
|
|
320
|
-
|
|
321
|
-
logs.push(`配置 control.xml 失败: ${
|
|
200
|
+
catch (error) {
|
|
201
|
+
logs.push(`配置 control.xml 失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
322
202
|
}
|
|
323
203
|
}
|
|
324
204
|
}
|
|
@@ -373,38 +253,70 @@ export async function buildIOSApp(options, deps) {
|
|
|
373
253
|
}
|
|
374
254
|
const controlXmlPath = deps.join(options.projectPath, projectName, 'control.xml');
|
|
375
255
|
if (deps.existsSync(controlXmlPath)) {
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
{
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
256
|
+
try {
|
|
257
|
+
const xmlContent = deps.readFileSync(controlXmlPath, 'utf8');
|
|
258
|
+
const parser = new deps.xmlParser();
|
|
259
|
+
const xmlDoc = parser.parseFromString(xmlContent, 'text/xml');
|
|
260
|
+
const appsElements = xmlDoc.getElementsByTagName('apps');
|
|
261
|
+
if (appsElements.length > 0) {
|
|
262
|
+
const appsElement = appsElements[0];
|
|
263
|
+
const existingAppElements = appsElement.getElementsByTagName('app');
|
|
264
|
+
let appExists = false;
|
|
265
|
+
let hasChanges = false;
|
|
266
|
+
for (let i = 0; i < existingAppElements.length; i++) {
|
|
267
|
+
const appElement = existingAppElements[i];
|
|
268
|
+
if (appElement.getAttribute('appid') === manifest.appid) {
|
|
269
|
+
appExists = true;
|
|
270
|
+
if (appElement.getAttribute('appver') !== '') {
|
|
271
|
+
appElement.setAttribute('appver', '');
|
|
272
|
+
hasChanges = true;
|
|
273
|
+
}
|
|
274
|
+
if (options.appkey && appElement.getAttribute('appkey') !== options.appkey) {
|
|
275
|
+
appElement.setAttribute('appkey', options.appkey);
|
|
276
|
+
hasChanges = true;
|
|
277
|
+
logs.push(`更新 appkey: ${options.appkey}`);
|
|
278
|
+
}
|
|
279
|
+
if (hasChanges) {
|
|
280
|
+
logs.push(`更新现有 app 元素,appid: ${manifest.appid}`);
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
logs.push(`app 元素已存在且配置正确,appid: ${manifest.appid}`);
|
|
284
|
+
}
|
|
285
|
+
break;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
if (!appExists) {
|
|
289
|
+
while (existingAppElements.length > 0) {
|
|
290
|
+
appsElement.removeChild(existingAppElements[0]);
|
|
291
|
+
}
|
|
292
|
+
logs.push('已删除所有现有的 app 元素');
|
|
293
|
+
const newAppElement = xmlDoc.createElement('app');
|
|
294
|
+
newAppElement.setAttribute('appid', manifest.appid);
|
|
295
|
+
newAppElement.setAttribute('appver', '');
|
|
296
|
+
if (options.appkey) {
|
|
297
|
+
newAppElement.setAttribute('appkey', options.appkey);
|
|
298
|
+
logs.push(`设置 appkey: ${options.appkey}`);
|
|
299
|
+
}
|
|
300
|
+
appsElement.appendChild(newAppElement);
|
|
301
|
+
logs.push(`添加新的 app 元素,appid: ${manifest.appid}`);
|
|
302
|
+
hasChanges = true;
|
|
303
|
+
}
|
|
304
|
+
if (hasChanges || !appExists) {
|
|
305
|
+
const serializer = new deps.xmlSerializer();
|
|
306
|
+
const newXmlContent = serializer.serializeToString(xmlDoc);
|
|
307
|
+
deps.writeFileSync(controlXmlPath, newXmlContent, 'utf8');
|
|
308
|
+
logs.push(`control.xml appid 配置完成,appid: ${manifest.appid}`);
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
logs.push(`control.xml appid 配置已存在,无需修改`);
|
|
389
312
|
}
|
|
390
313
|
}
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
existsSync: deps.existsSync,
|
|
394
|
-
readFileSync: deps.readFileSync,
|
|
395
|
-
writeFileSync: deps.writeFileSync,
|
|
396
|
-
xmlParser: deps.xmlParser,
|
|
397
|
-
xmlSerializer: deps.xmlSerializer,
|
|
398
|
-
xpath: deps.xpath
|
|
399
|
-
});
|
|
400
|
-
if (controlResult.success) {
|
|
401
|
-
logs.push(`control.xml appid 配置完成,appid: ${manifest.appid}`);
|
|
402
|
-
if (options.appkey) {
|
|
403
|
-
logs.push(`设置 appkey: ${options.appkey}`);
|
|
314
|
+
else {
|
|
315
|
+
logs.push('control.xml 中未找到 apps 元素');
|
|
404
316
|
}
|
|
405
317
|
}
|
|
406
|
-
|
|
407
|
-
logs.push(`配置 control.xml appid 失败: ${
|
|
318
|
+
catch (error) {
|
|
319
|
+
logs.push(`配置 control.xml appid 失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
408
320
|
}
|
|
409
321
|
}
|
|
410
322
|
const bundleId = options.bundleId || 'io.dcloud.HBuilder';
|
|
@@ -868,344 +780,5 @@ export async function buildIOSApp(options, deps) {
|
|
|
868
780
|
};
|
|
869
781
|
}
|
|
870
782
|
}
|
|
871
|
-
export
|
|
872
|
-
const logs = [];
|
|
873
|
-
if (!options.uniappProjectPath) {
|
|
874
|
-
return {
|
|
875
|
-
success: false,
|
|
876
|
-
error: 'uniappProjectPath 是必需的',
|
|
877
|
-
logs
|
|
878
|
-
};
|
|
879
|
-
}
|
|
880
|
-
if (!options.projectPath) {
|
|
881
|
-
return {
|
|
882
|
-
success: false,
|
|
883
|
-
error: 'projectPath 是必需的',
|
|
884
|
-
logs
|
|
885
|
-
};
|
|
886
|
-
}
|
|
887
|
-
try {
|
|
888
|
-
logs.push('步骤 1: 解析 manifest.json 配置');
|
|
889
|
-
const parseResult = parseManifest(options.uniappProjectPath, {
|
|
890
|
-
existsSync: deps.existsSync,
|
|
891
|
-
readFileSync: deps.readFileSync,
|
|
892
|
-
join: deps.join,
|
|
893
|
-
parse: deps.parse
|
|
894
|
-
});
|
|
895
|
-
if (!parseResult.success) {
|
|
896
|
-
return {
|
|
897
|
-
success: false,
|
|
898
|
-
error: parseResult.error,
|
|
899
|
-
logs
|
|
900
|
-
};
|
|
901
|
-
}
|
|
902
|
-
const manifest = parseResult.manifest;
|
|
903
|
-
const version = manifest.versionName || '1.0.0';
|
|
904
|
-
const buildNumber = manifest.versionCode || '1';
|
|
905
|
-
const projectFiles = deps.readdirSync(options.projectPath).filter(file => file.endsWith('.xcodeproj'));
|
|
906
|
-
if (projectFiles.length === 0) {
|
|
907
|
-
return {
|
|
908
|
-
success: false,
|
|
909
|
-
error: `在 ${options.projectPath} 中未找到 Xcode 项目文件(.xcodeproj)`,
|
|
910
|
-
logs
|
|
911
|
-
};
|
|
912
|
-
}
|
|
913
|
-
const projectFile = projectFiles[0];
|
|
914
|
-
const projectName = options.sourceDirectoryName || projectFile.replace(/\.xcodeproj$/, '');
|
|
915
|
-
logs.push(`找到 Xcode 项目: ${projectFile}`);
|
|
916
|
-
if (options.sourceDirectoryName) {
|
|
917
|
-
logs.push(`使用指定的源码目录: ${projectName}`);
|
|
918
|
-
}
|
|
919
|
-
logs.push('步骤 1: 同步 project.pbxproj 版本配置');
|
|
920
|
-
const projectPbxprojPath = deps.join(options.projectPath, projectFile, 'project.pbxproj');
|
|
921
|
-
const pbxprojResult = safelyModifyProjectPbxproj(projectPbxprojPath, {
|
|
922
|
-
bundleId: options.bundleId,
|
|
923
|
-
version,
|
|
924
|
-
buildNumber,
|
|
925
|
-
teamId: options.signing?.teamId,
|
|
926
|
-
codeSignIdentity: 'Apple Development'
|
|
927
|
-
}, {
|
|
928
|
-
existsSync: deps.existsSync,
|
|
929
|
-
readFileSync: deps.readFileSync,
|
|
930
|
-
writeFileSync: deps.writeFileSync
|
|
931
|
-
});
|
|
932
|
-
if (pbxprojResult.success) {
|
|
933
|
-
logs.push('project.pbxproj 版本配置同步完成');
|
|
934
|
-
}
|
|
935
|
-
else {
|
|
936
|
-
logs.push(`project.pbxproj 版本配置同步失败: ${pbxprojResult.error}`);
|
|
937
|
-
}
|
|
938
|
-
logs.push('步骤 2: 修改 Info.plist 配置');
|
|
939
|
-
const infoPlistPath = deps.join(options.projectPath, projectName, `${projectName}-Info.plist`);
|
|
940
|
-
if (deps.existsSync(infoPlistPath)) {
|
|
941
|
-
try {
|
|
942
|
-
const xmlContent = deps.readFileSync(infoPlistPath, 'utf8');
|
|
943
|
-
const parser = new deps.xmlParser();
|
|
944
|
-
const xmlDoc = parser.parseFromString(xmlContent, 'text/xml');
|
|
945
|
-
if (options.appkey) {
|
|
946
|
-
modifyInfoPlistKeyValue(xmlDoc, 'dcloud_appkey', options.appkey, 'string');
|
|
947
|
-
}
|
|
948
|
-
if (options.bundleId) {
|
|
949
|
-
modifyInfoPlistKeyValue(xmlDoc, 'CFBundleIdentifier', options.bundleId, 'string');
|
|
950
|
-
}
|
|
951
|
-
if (version) {
|
|
952
|
-
modifyInfoPlistKeyValue(xmlDoc, 'CFBundleShortVersionString', version, 'string');
|
|
953
|
-
}
|
|
954
|
-
if (buildNumber) {
|
|
955
|
-
modifyInfoPlistKeyValue(xmlDoc, 'CFBundleVersion', buildNumber, 'string');
|
|
956
|
-
}
|
|
957
|
-
if (manifest.name) {
|
|
958
|
-
modifyInfoPlistKeyValue(xmlDoc, 'CFBundleDisplayName', manifest.name, 'string');
|
|
959
|
-
}
|
|
960
|
-
modifyInfoPlistKeyValue(xmlDoc, 'UIFileSharingEnabled', '', 'true');
|
|
961
|
-
logs.push('已启用 Application supports iTunes file sharing(插件开发必需)');
|
|
962
|
-
const serializer = new deps.xmlSerializer();
|
|
963
|
-
const newXmlContent = serializer.serializeToString(xmlDoc);
|
|
964
|
-
deps.writeFileSync(infoPlistPath, newXmlContent, 'utf8');
|
|
965
|
-
logs.push('Info.plist 配置完成');
|
|
966
|
-
}
|
|
967
|
-
catch (error) {
|
|
968
|
-
logs.push(`配置 Info.plist 失败: ${error instanceof Error ? error.message : String(error)}`);
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
logs.push('步骤 3: 配置自定义基座(control.xml)');
|
|
972
|
-
const controlXmlPath = deps.join(options.projectPath, projectName, 'control.xml');
|
|
973
|
-
if (deps.existsSync(controlXmlPath)) {
|
|
974
|
-
const controlModifications = [
|
|
975
|
-
{
|
|
976
|
-
xpath: "//HBuilder",
|
|
977
|
-
action: 'setAttribute',
|
|
978
|
-
attributeName: 'debug',
|
|
979
|
-
value: 'true'
|
|
980
|
-
},
|
|
981
|
-
{
|
|
982
|
-
xpath: "//HBuilder",
|
|
983
|
-
action: 'setAttribute',
|
|
984
|
-
attributeName: 'syncDebug',
|
|
985
|
-
value: 'true'
|
|
986
|
-
}
|
|
987
|
-
];
|
|
988
|
-
const controlResult = await modifyManifest(controlXmlPath, controlModifications, {
|
|
989
|
-
existsSync: deps.existsSync,
|
|
990
|
-
readFileSync: deps.readFileSync,
|
|
991
|
-
writeFileSync: deps.writeFileSync,
|
|
992
|
-
xmlParser: deps.xmlParser,
|
|
993
|
-
xmlSerializer: deps.xmlSerializer,
|
|
994
|
-
xpath: deps.xpath
|
|
995
|
-
});
|
|
996
|
-
if (controlResult.success) {
|
|
997
|
-
logs.push('control.xml 自定义基座配置完成:debug="true" syncDebug="true"');
|
|
998
|
-
}
|
|
999
|
-
else {
|
|
1000
|
-
logs.push(`配置 control.xml 失败: ${controlResult.error}`);
|
|
1001
|
-
}
|
|
1002
|
-
}
|
|
1003
|
-
logs.push('步骤 4: 编译 UniApp 项目并复制到 apps 目录');
|
|
1004
|
-
let sourcePath;
|
|
1005
|
-
if (options.uniappBuildOutputPath) {
|
|
1006
|
-
logs.push('使用提供的 UniApp 编译结果路径');
|
|
1007
|
-
sourcePath = options.uniappBuildOutputPath;
|
|
1008
|
-
if (!deps.existsSync(sourcePath)) {
|
|
1009
|
-
return {
|
|
1010
|
-
success: false,
|
|
1011
|
-
error: `提供的编译结果路径不存在: ${sourcePath}`,
|
|
1012
|
-
logs
|
|
1013
|
-
};
|
|
1014
|
-
}
|
|
1015
|
-
logs.push(`使用编译结果路径: ${sourcePath}`);
|
|
1016
|
-
}
|
|
1017
|
-
else {
|
|
1018
|
-
logs.push('构建 UniApp 项目');
|
|
1019
|
-
const buildDeps = {
|
|
1020
|
-
exec: deps.exec,
|
|
1021
|
-
join: deps.join,
|
|
1022
|
-
existsSync: deps.existsSync,
|
|
1023
|
-
setTimeout: deps.setTimeout
|
|
1024
|
-
};
|
|
1025
|
-
const uniBuildResult = await build(options.uniappProjectPath, 'app-plus', buildDeps);
|
|
1026
|
-
if (!uniBuildResult.success) {
|
|
1027
|
-
return {
|
|
1028
|
-
success: false,
|
|
1029
|
-
error: `构建失败: ${uniBuildResult.error}`,
|
|
1030
|
-
logs: [...logs, ...uniBuildResult.logs]
|
|
1031
|
-
};
|
|
1032
|
-
}
|
|
1033
|
-
logs.push(...uniBuildResult.logs);
|
|
1034
|
-
sourcePath = deps.join(options.uniappProjectPath, 'dist', 'build', 'app');
|
|
1035
|
-
}
|
|
1036
|
-
const targetPath = deps.join(options.projectPath, projectName, 'Pandora', 'apps', manifest.appid, 'www');
|
|
1037
|
-
try {
|
|
1038
|
-
const targetDir = deps.dirname(targetPath);
|
|
1039
|
-
if (!deps.existsSync(targetDir)) {
|
|
1040
|
-
deps.mkdirSync(targetDir, { recursive: true });
|
|
1041
|
-
}
|
|
1042
|
-
await deps.cp(sourcePath, targetPath, { recursive: true, force: true });
|
|
1043
|
-
logs.push('应用资源复制完成');
|
|
1044
|
-
}
|
|
1045
|
-
catch (error) {
|
|
1046
|
-
return {
|
|
1047
|
-
success: false,
|
|
1048
|
-
error: `复制应用资源失败: ${error instanceof Error ? error.message : String(error)}`,
|
|
1049
|
-
logs
|
|
1050
|
-
};
|
|
1051
|
-
}
|
|
1052
|
-
if (deps.existsSync(controlXmlPath)) {
|
|
1053
|
-
const controlModifications = [
|
|
1054
|
-
{
|
|
1055
|
-
xpath: "//apps/app",
|
|
1056
|
-
action: 'removeElement'
|
|
1057
|
-
},
|
|
1058
|
-
{
|
|
1059
|
-
xpath: "//apps",
|
|
1060
|
-
action: 'addElement',
|
|
1061
|
-
elementName: 'app',
|
|
1062
|
-
attributes: {
|
|
1063
|
-
appid: manifest.appid,
|
|
1064
|
-
appver: '',
|
|
1065
|
-
...(options.appkey ? { appkey: options.appkey } : {})
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
|
-
];
|
|
1069
|
-
const controlResult = await modifyManifest(controlXmlPath, controlModifications, {
|
|
1070
|
-
existsSync: deps.existsSync,
|
|
1071
|
-
readFileSync: deps.readFileSync,
|
|
1072
|
-
writeFileSync: deps.writeFileSync,
|
|
1073
|
-
xmlParser: deps.xmlParser,
|
|
1074
|
-
xmlSerializer: deps.xmlSerializer,
|
|
1075
|
-
xpath: deps.xpath
|
|
1076
|
-
});
|
|
1077
|
-
if (controlResult.success) {
|
|
1078
|
-
logs.push(`control.xml appid 配置完成,appid: ${manifest.appid}`);
|
|
1079
|
-
if (options.appkey) {
|
|
1080
|
-
logs.push(`设置 appkey: ${options.appkey}`);
|
|
1081
|
-
}
|
|
1082
|
-
}
|
|
1083
|
-
else {
|
|
1084
|
-
logs.push(`配置 control.xml appid 失败: ${controlResult.error}`);
|
|
1085
|
-
}
|
|
1086
|
-
}
|
|
1087
|
-
if (options.nativePlugins && options.nativePlugins.length > 0) {
|
|
1088
|
-
logs.push('步骤 5: 集成 UniApp 原生插件');
|
|
1089
|
-
for (const pluginConfig of options.nativePlugins) {
|
|
1090
|
-
const pluginResult = await integrateNativePluginIOS(options.projectPath, projectName, pluginConfig.pluginPath, {
|
|
1091
|
-
existsSync: deps.existsSync,
|
|
1092
|
-
readFileSync: deps.readFileSync,
|
|
1093
|
-
writeFileSync: deps.writeFileSync,
|
|
1094
|
-
copyFileSync: deps.copyFileSync,
|
|
1095
|
-
statSync: deps.statSync,
|
|
1096
|
-
mkdirSync: deps.mkdirSync,
|
|
1097
|
-
readdirSync: deps.readdirSync,
|
|
1098
|
-
cp: deps.cp,
|
|
1099
|
-
join: deps.join,
|
|
1100
|
-
dirname: deps.dirname,
|
|
1101
|
-
basename: deps.basename,
|
|
1102
|
-
exec: deps.exec,
|
|
1103
|
-
parse: deps.parse,
|
|
1104
|
-
xmlParser: deps.xmlParser,
|
|
1105
|
-
xmlSerializer: deps.xmlSerializer
|
|
1106
|
-
}, pluginConfig.parameters);
|
|
1107
|
-
if (pluginResult.success) {
|
|
1108
|
-
logs.push(`原生插件集成完成: ${pluginConfig.pluginPath}`);
|
|
1109
|
-
logs.push(...pluginResult.logs);
|
|
1110
|
-
}
|
|
1111
|
-
else {
|
|
1112
|
-
logs.push(`原生插件集成失败: ${pluginResult.error}`);
|
|
1113
|
-
logs.push(...pluginResult.logs);
|
|
1114
|
-
}
|
|
1115
|
-
}
|
|
1116
|
-
}
|
|
1117
|
-
logs.push('步骤 6: 编译 iOS 插件项目');
|
|
1118
|
-
const configuration = options.configuration || 'Debug';
|
|
1119
|
-
const scheme = options.scheme || projectName;
|
|
1120
|
-
logs.push(`提示: 签名配置必须在 Xcode 中手动设置`);
|
|
1121
|
-
logs.push(`提示: 请打开项目 ${projectFile},在 Signing & Capabilities 中配置 Team`);
|
|
1122
|
-
if (options.signing?.teamId) {
|
|
1123
|
-
logs.push(`提示: 开发团队 ID 应该是: ${options.signing.teamId}`);
|
|
1124
|
-
}
|
|
1125
|
-
const buildBasePath = deps.join(options.outputPath || options.projectPath, 'build');
|
|
1126
|
-
const archivePath = deps.join(buildBasePath, `${projectName}.xcarchive`);
|
|
1127
|
-
if (options.clean) {
|
|
1128
|
-
logs.push('清理构建目录');
|
|
1129
|
-
const cleanCommand = `cd "${options.projectPath}" && xcodebuild -project "${projectFile}" -scheme "${scheme}" -destination "generic/platform=iOS" clean`;
|
|
1130
|
-
await new Promise((resolve) => {
|
|
1131
|
-
deps.exec(cleanCommand, (error, stdout, stderr) => {
|
|
1132
|
-
if (error) {
|
|
1133
|
-
logs.push(`清理警告: ${error.message}`);
|
|
1134
|
-
}
|
|
1135
|
-
if (stdout)
|
|
1136
|
-
logs.push(`清理输出: ${stdout}`);
|
|
1137
|
-
resolve();
|
|
1138
|
-
});
|
|
1139
|
-
});
|
|
1140
|
-
}
|
|
1141
|
-
const buildCommand = `cd "${options.projectPath}" && xcodebuild -project "${projectFile}" -scheme "${scheme}" -configuration "${configuration}" -destination "generic/platform=iOS" -allowProvisioningUpdates -archivePath "${archivePath}" archive`;
|
|
1142
|
-
logs.push(`执行构建命令: ${buildCommand}`);
|
|
1143
|
-
const buildResult = await new Promise((resolve) => {
|
|
1144
|
-
const child = deps.exec(buildCommand, (error, stdout, stderr) => {
|
|
1145
|
-
const allOutput = stdout + (stderr ? '\n' + stderr : '');
|
|
1146
|
-
if (error) {
|
|
1147
|
-
logs.push(`构建错误: ${error.message}`);
|
|
1148
|
-
if (stdout)
|
|
1149
|
-
logs.push(`标准输出:\n${stdout}`);
|
|
1150
|
-
if (stderr)
|
|
1151
|
-
logs.push(`错误输出:\n${stderr}`);
|
|
1152
|
-
const errorDetails = allOutput.includes('error:')
|
|
1153
|
-
? allOutput.split('error:').slice(1).join('error:').split('\n').slice(0, 5).join('\n')
|
|
1154
|
-
: (stderr || stdout || error.message);
|
|
1155
|
-
resolve({
|
|
1156
|
-
success: false,
|
|
1157
|
-
error: error.message,
|
|
1158
|
-
details: errorDetails
|
|
1159
|
-
});
|
|
1160
|
-
return;
|
|
1161
|
-
}
|
|
1162
|
-
if (stdout)
|
|
1163
|
-
logs.push(`构建输出:\n${stdout}`);
|
|
1164
|
-
if (stderr)
|
|
1165
|
-
logs.push(`警告信息:\n${stderr}`);
|
|
1166
|
-
resolve({ success: true });
|
|
1167
|
-
});
|
|
1168
|
-
deps.setTimeout(() => {
|
|
1169
|
-
child.kill();
|
|
1170
|
-
resolve({ success: false, error: '构建超时' });
|
|
1171
|
-
}, 600000);
|
|
1172
|
-
});
|
|
1173
|
-
if (!buildResult.success) {
|
|
1174
|
-
const errorMessage = buildResult.details
|
|
1175
|
-
? `编译失败: ${buildResult.error}\n详细信息:\n${buildResult.details}`
|
|
1176
|
-
: `编译失败: ${buildResult.error}`;
|
|
1177
|
-
return {
|
|
1178
|
-
success: false,
|
|
1179
|
-
error: errorMessage,
|
|
1180
|
-
logs
|
|
1181
|
-
};
|
|
1182
|
-
}
|
|
1183
|
-
if (!deps.existsSync(archivePath)) {
|
|
1184
|
-
const errorMessage = `Archive 文件不存在: ${archivePath}`;
|
|
1185
|
-
logs.push(errorMessage);
|
|
1186
|
-
return {
|
|
1187
|
-
success: false,
|
|
1188
|
-
error: errorMessage,
|
|
1189
|
-
logs
|
|
1190
|
-
};
|
|
1191
|
-
}
|
|
1192
|
-
logs.push('iOS 插件项目编译完成');
|
|
1193
|
-
logs.push(`Archive 文件: ${archivePath}`);
|
|
1194
|
-
logs.push('\n💡 提示: 插件开发构建已完成,可以在 Xcode 中运行项目进行调试');
|
|
1195
|
-
logs.push('💡 如需导出 IPA,请使用 buildIOSApp 函数并设置完整的签名配置');
|
|
1196
|
-
return {
|
|
1197
|
-
success: true,
|
|
1198
|
-
outputPath: archivePath,
|
|
1199
|
-
logs
|
|
1200
|
-
};
|
|
1201
|
-
}
|
|
1202
|
-
catch (error) {
|
|
1203
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
1204
|
-
return {
|
|
1205
|
-
success: false,
|
|
1206
|
-
error: `构建过程中发生异常: ${errorMessage}`,
|
|
1207
|
-
logs
|
|
1208
|
-
};
|
|
1209
|
-
}
|
|
1210
|
-
}
|
|
783
|
+
export { buildIOSPlugin } from './buildIOSPlugin';
|
|
1211
784
|
//# sourceMappingURL=buildIOSApp.js.map
|