@webspatial/builder 0.1.15 → 0.1.17
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 +15 -75
- package/dist/index.js +99 -1
- package/dist/lib/cmds/build.js +116 -1
- package/dist/lib/cmds/check.js +41 -1
- package/dist/lib/cmds/help.js +66 -1
- package/dist/lib/cmds/launch.js +14 -1
- package/dist/lib/cmds/shutdown.js +8 -1
- package/dist/lib/cmds/version.js +11 -1
- package/dist/lib/pwa/config.js +208 -1
- package/dist/lib/pwa/index.js +92 -1
- package/dist/lib/pwa/validate.js +240 -1
- package/dist/lib/resource/file.js +45 -1
- package/dist/lib/resource/imageHelper.js +37 -1
- package/dist/lib/resource/index.js +102 -1
- package/dist/lib/resource/load.js +121 -1
- package/dist/lib/types.d.ts +2 -2
- package/dist/lib/types.js +2 -1
- package/dist/lib/utils/CustomError.js +11 -1
- package/dist/lib/utils/FetchUtils-1.js +25 -1
- package/dist/lib/utils/Log.js +98 -1
- package/dist/lib/utils/fetch.js +56 -1
- package/dist/lib/utils/history.d.ts +1 -0
- package/dist/lib/utils/history.js +116 -1
- package/dist/lib/utils/messages.js +102 -1
- package/dist/lib/utils/utils.js +15 -1
- package/dist/lib/xcode/index.js +35 -1
- package/dist/lib/xcode/manifestSwiftTemplate.js +109 -1
- package/dist/lib/xcode/xcodebuild.js +119 -1
- package/dist/lib/xcode/xcodeproject.js +239 -1
- package/dist/lib/xcode/xcrun.d.ts +1 -1
- package/dist/lib/xcode/xcrun.js +433 -1
- package/package.json +3 -3
|
@@ -1 +1,116 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const path_1 = require("path");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const utils_1 = require("./utils");
|
|
6
|
+
const resource_1 = require("../resource");
|
|
7
|
+
/*
|
|
8
|
+
Histoy is used to record information about successful execution of the run command,
|
|
9
|
+
including cmd, manifest, appInfo, simulator.
|
|
10
|
+
The historical record is used to determine whether the current execution is the same as the historical execution.
|
|
11
|
+
If the current execution is the same as the historical execution, the historical record will be used to avoid repeated execution.
|
|
12
|
+
If the current execution is different from the historical execution, the historical record will be overwritten.
|
|
13
|
+
*/
|
|
14
|
+
class CliHistory {
|
|
15
|
+
/*
|
|
16
|
+
If history file not exist, create it
|
|
17
|
+
If history file exist, read it
|
|
18
|
+
If history file is empty, use default history
|
|
19
|
+
*/
|
|
20
|
+
static init(cmd) {
|
|
21
|
+
let historyFile = (0, path_1.join)(__dirname, '../../run_history.txt');
|
|
22
|
+
let history = this.defaultHistory;
|
|
23
|
+
if (!fs.existsSync(historyFile)) {
|
|
24
|
+
fs.writeFileSync(historyFile, '');
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
try {
|
|
28
|
+
history = JSON.parse(fs.readFileSync(historyFile, 'utf-8'));
|
|
29
|
+
console.log('Historical records found');
|
|
30
|
+
}
|
|
31
|
+
catch (e) {
|
|
32
|
+
utils_1.CliLog.warn('No historical records found');
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
this.history = history;
|
|
36
|
+
this.record.cmd = cmd;
|
|
37
|
+
}
|
|
38
|
+
static getAppInfoRecord() {
|
|
39
|
+
return this.record.appInfo;
|
|
40
|
+
}
|
|
41
|
+
static getSimulatorRecord() {
|
|
42
|
+
return this.record.simulator;
|
|
43
|
+
}
|
|
44
|
+
static getSimulatorHistory() {
|
|
45
|
+
return this.history.simulator;
|
|
46
|
+
}
|
|
47
|
+
static recordManifest(manifest) {
|
|
48
|
+
this.record.manifest = manifest;
|
|
49
|
+
this.record.appInfo.name = manifest.name;
|
|
50
|
+
this.record.appInfo.id = manifest.id;
|
|
51
|
+
}
|
|
52
|
+
static recordSimulator(simulator) {
|
|
53
|
+
this.record.simulator = simulator;
|
|
54
|
+
}
|
|
55
|
+
static checkManifest(manifest) {
|
|
56
|
+
return this.compareObjects(this.history.manifest, manifest);
|
|
57
|
+
}
|
|
58
|
+
// Check whether the test app exists
|
|
59
|
+
static checkTestAppIsExist() {
|
|
60
|
+
const appInfo = this.getAppInfoRecord();
|
|
61
|
+
const appFile = (0, path_1.join)(resource_1.PROJECT_TEST_DIRECTORY, `Build/Products/Debug-xrsimulator/${appInfo.name}.app`);
|
|
62
|
+
return fs.existsSync(appFile);
|
|
63
|
+
}
|
|
64
|
+
// Compare whether two objects are equal
|
|
65
|
+
static compareObjects(obj1, obj2) {
|
|
66
|
+
// 1. Check if the number of properties is the same
|
|
67
|
+
const keys1 = Object.keys(obj1);
|
|
68
|
+
const keys2 = Object.keys(obj2);
|
|
69
|
+
if (keys1.length !== keys2.length) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
// 2. Deep comparison of each attribute
|
|
73
|
+
for (const key of keys1) {
|
|
74
|
+
const value1 = obj1[key];
|
|
75
|
+
const value2 = obj2[key];
|
|
76
|
+
// Dealing with undefined/null situations
|
|
77
|
+
if (value1 === undefined || value2 === undefined) {
|
|
78
|
+
if (value1 !== value2)
|
|
79
|
+
return false;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
// Recursive comparison of nested objects
|
|
83
|
+
if (typeof value1 === 'object' && value1 !== null) {
|
|
84
|
+
if (!this.compareObjects(value1, value2))
|
|
85
|
+
return false;
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
// Basic comparison of primitive types
|
|
89
|
+
if (value1 !== value2) {
|
|
90
|
+
console.log(`Mismatch found at key: ${key}`);
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
static checkCommand(cmd) {
|
|
97
|
+
return this.history.cmd === cmd;
|
|
98
|
+
}
|
|
99
|
+
static write() {
|
|
100
|
+
let historyFile = (0, path_1.join)(__dirname, '../../run_history.txt');
|
|
101
|
+
fs.writeFileSync(historyFile, JSON.stringify(this.record));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
CliHistory.defaultHistory = {
|
|
105
|
+
cmd: '',
|
|
106
|
+
manifest: {},
|
|
107
|
+
appInfo: { name: '', id: '' },
|
|
108
|
+
simulator: '',
|
|
109
|
+
};
|
|
110
|
+
CliHistory.record = {
|
|
111
|
+
cmd: '',
|
|
112
|
+
manifest: {},
|
|
113
|
+
appInfo: { name: '', id: '' },
|
|
114
|
+
simulator: '',
|
|
115
|
+
};
|
|
116
|
+
exports.default = CliHistory;
|
|
@@ -1 +1,102 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.messages = void 0;
|
|
4
|
+
const colors_1 = require("colors");
|
|
5
|
+
exports.messages = {
|
|
6
|
+
promptInstallJdk: `Do you want picoxr-web to install the JDK (recommended)?
|
|
7
|
+
(Enter "No" to use your own JDK 11 installation)`,
|
|
8
|
+
promptJdkPath: 'Path to your existing JDK 11:',
|
|
9
|
+
messageDownloadJdk: 'Downloading JDK 11 to ',
|
|
10
|
+
messageDownloadJdkSrc: 'Downloading the JDK 11 Sources...',
|
|
11
|
+
messageDecompressJdkSrc: 'Decompressing the JDK 11 Sources...',
|
|
12
|
+
messageDownloadJdkBin: 'Downloading the JDK 11 Binaries...',
|
|
13
|
+
messageDecompressJdkBin: 'Decompressing the JDK 11 Binaries...',
|
|
14
|
+
promptInstallSdk: `Do you want picoxr-web to install the Android SDK (recommended)?
|
|
15
|
+
(Enter "No" to use your own Android SDK installation)`,
|
|
16
|
+
promptSdkPath: 'Path to your existing Android SDK:',
|
|
17
|
+
messageDownloadSdk: 'Downloading Android SDK to ',
|
|
18
|
+
errorSdkTerms: 'Downloading Android SDK failed because Terms and Conditions was not signed.',
|
|
19
|
+
promptSdkTerms: `Do you agree to the Android SDK terms and conditions at ${(0, colors_1.underline)('https://developer.android.com/studio/terms.html')}?`,
|
|
20
|
+
messageDownloadAndroidSdk: 'Downloading the Android SDK...',
|
|
21
|
+
messageDecompressAndroidSdk: 'Decompressing the Android SDK...',
|
|
22
|
+
messageInstallingBuildTools: 'Installing Android Build Tools. Please, read and accept the ' +
|
|
23
|
+
'license agreement.',
|
|
24
|
+
messageGeneratingAndroidProject: 'Generating Android Project.',
|
|
25
|
+
// 可安装检测成功输出
|
|
26
|
+
messageCheckSuccess: (url, redirectLocation) => {
|
|
27
|
+
return ` URL ${(0, colors_1.cyan)(url)} ${redirectLocation ? `redirected to ${(0, colors_1.cyan)(redirectLocation)}` : ''} validation successful.Here is the relevant information:`;
|
|
28
|
+
},
|
|
29
|
+
errorMissingManifestParameter: 'Missing required parameter ' +
|
|
30
|
+
`${(0, colors_1.cyan)('--manifest-url')} or ${(0, colors_1.cyan)('--manifest')}`,
|
|
31
|
+
messageInitializingWebManifest: (manifestUrl) => {
|
|
32
|
+
return `Initializing application from Web Manifest:\n\t- ${(0, colors_1.cyan)(manifestUrl)}`;
|
|
33
|
+
},
|
|
34
|
+
messageInitializingLocalManifest: (manifestPath) => {
|
|
35
|
+
return `Initializing application from Local Manifest:\n\t- ${(0, colors_1.cyan)(manifestPath)}`;
|
|
36
|
+
},
|
|
37
|
+
messageInvalidIcon: (iconPath) => {
|
|
38
|
+
return `Invalid icon path: ${(0, colors_1.cyan)(iconPath)}`;
|
|
39
|
+
},
|
|
40
|
+
errorStartUrlNotReachable: (launchUrl) => `URL ${launchUrl} can not be accessible.` +
|
|
41
|
+
'Please check your internet connection or start_url in manifest file.',
|
|
42
|
+
warnFamilyPolicy: (0, colors_1.bold)((0, colors_1.yellow)('WARNING: ')) +
|
|
43
|
+
'Trusted Web Activities are currently incompatible' +
|
|
44
|
+
' with applications\ntargeting children under the age of 13.' +
|
|
45
|
+
' Check out the Play for' +
|
|
46
|
+
' Families\npolicies to learn more.\n' +
|
|
47
|
+
(0, colors_1.cyan)('https://play.google.com/console/about/families/'),
|
|
48
|
+
// 本地manifest,交互式提供icon
|
|
49
|
+
promptIconUrl: 'Icon URL:',
|
|
50
|
+
errorInvalidUrl: (url) => {
|
|
51
|
+
return `Invalid URL: ${url}`;
|
|
52
|
+
},
|
|
53
|
+
errorUrlMustBeImage: (mimeType) => {
|
|
54
|
+
return `URL must resolve to an image/* mime-type, but resolved to ${mimeType}.`;
|
|
55
|
+
},
|
|
56
|
+
promptVersionCode: 'Starting version code for the new app version:',
|
|
57
|
+
promptVersionName: 'Starting version name for the new app version:',
|
|
58
|
+
messageSigningKeyInformation: (0, colors_1.underline)(`\nSigning key information ${(0, colors_1.green)('(5/5)')}`),
|
|
59
|
+
// messageSigningKeyInformationDesc: `
|
|
60
|
+
// Please, enter information about the key store containing the keys that will be used
|
|
61
|
+
// to sign the application. If a key store does not exist on the provided path,
|
|
62
|
+
// picoxr-web will prompt for the creation of a new keystore.
|
|
63
|
+
// \t- ${bold('Key store location:')} The location of the key store in the file
|
|
64
|
+
// \t system.
|
|
65
|
+
// \t- ${bold('Key name:')} The alias used on the key.
|
|
66
|
+
// Read more about Android signing keys at:
|
|
67
|
+
// \t ${cyan('https://developer.android.com/studio/publish/app-signing')}\n`,
|
|
68
|
+
// promptKeyAlias: 'Key name:',
|
|
69
|
+
messageProjectGeneratedSuccess: '\nProject generated successfully.',
|
|
70
|
+
// 创建keystore
|
|
71
|
+
messageSigningKeyCreation: (0, colors_1.underline)('\nSigning key creation'),
|
|
72
|
+
messageSigningKeyNotFound: (path) => {
|
|
73
|
+
return `\nAn existing key store could not be found at "${path}".\n`;
|
|
74
|
+
},
|
|
75
|
+
promptCreateKey: 'Do you want to create one now?',
|
|
76
|
+
promptKeyFullName: 'First and Last names (eg: PICO):',
|
|
77
|
+
promptKeyOrganizationalUnit: 'Organizational Unit (eg: PICO Dept):',
|
|
78
|
+
promptKeyOrganization: 'Organization (eg: Company Name):',
|
|
79
|
+
promptKeyCountry: 'Country (2 letter code):',
|
|
80
|
+
promptKeystorePassword: 'Password for the Key Store:',
|
|
81
|
+
promptKeyPassword: 'Password for the Key:',
|
|
82
|
+
messageBuildingApp: '\nBuilding the Android App...',
|
|
83
|
+
messageEnterPasswords: (keypath, keyalias) => {
|
|
84
|
+
return `Please, enter passwords for the keystore ${(0, colors_1.cyan)(keypath)} and alias \
|
|
85
|
+
${(0, colors_1.cyan)(keyalias)}.\n`;
|
|
86
|
+
},
|
|
87
|
+
// build时,校验输入的keystore和key的密码长度
|
|
88
|
+
errorMinLength: (minLength, actualLength) => {
|
|
89
|
+
return `Minimum length is ${minLength} but input is ${actualLength}.`;
|
|
90
|
+
},
|
|
91
|
+
errorMaxLength: (maxLength, actualLength) => {
|
|
92
|
+
return `Maximum length is ${maxLength} but input is ${actualLength}.`;
|
|
93
|
+
},
|
|
94
|
+
errorInvalidInteger: (integer) => {
|
|
95
|
+
return `Invalid integer provided: ${integer}`;
|
|
96
|
+
},
|
|
97
|
+
messageApkSuccess: (filename) => {
|
|
98
|
+
return `\t- Generated Android APK at ${(0, colors_1.cyan)(filename)}`;
|
|
99
|
+
},
|
|
100
|
+
// 可安装检测url参数缺失
|
|
101
|
+
missingUrlToCheck: 'Missing required parameter ' + `${(0, colors_1.cyan)('--url')}`,
|
|
102
|
+
};
|
package/dist/lib/utils/utils.js
CHANGED
|
@@ -1 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CliLog = void 0;
|
|
4
|
+
exports.parseRouter = parseRouter;
|
|
5
|
+
const Log_1 = require("./Log");
|
|
6
|
+
function parseRouter(url) {
|
|
7
|
+
let urlParts = url.split('/');
|
|
8
|
+
urlParts.pop();
|
|
9
|
+
let pathUrl = urlParts.join();
|
|
10
|
+
while (pathUrl.indexOf(',') >= 0) {
|
|
11
|
+
pathUrl = pathUrl.replace(',', '/');
|
|
12
|
+
}
|
|
13
|
+
return pathUrl;
|
|
14
|
+
}
|
|
15
|
+
exports.CliLog = new Log_1.ConsoleLog('webspatial-builder');
|
package/dist/lib/xcode/index.js
CHANGED
|
@@ -1 +1,35 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.XcodeManager = void 0;
|
|
4
|
+
const resource_1 = require("../resource");
|
|
5
|
+
const xcodeproject_1 = require("./xcodeproject");
|
|
6
|
+
const xcodebuild_1 = require("./xcodebuild");
|
|
7
|
+
const xcrun_1 = require("./xcrun");
|
|
8
|
+
const path_1 = require("path");
|
|
9
|
+
class XcodeManager {
|
|
10
|
+
static async parseProject(option, isDev = false) {
|
|
11
|
+
const projectPath = resource_1.PROJECT_DIRECTORY + '/web-spatial.xcodeproj/project.pbxproj';
|
|
12
|
+
await xcodeproject_1.default.modify(projectPath, option, isDev);
|
|
13
|
+
console.log('write project.pbxproj: ok');
|
|
14
|
+
}
|
|
15
|
+
static async build(exportPath) {
|
|
16
|
+
await xcodebuild_1.default.archive(exportPath);
|
|
17
|
+
}
|
|
18
|
+
static async upload(option, appInfo) {
|
|
19
|
+
if (option['u'] && option['p']) {
|
|
20
|
+
// use username, password
|
|
21
|
+
xcrun_1.default.uploadApp((0, path_1.join)(resource_1.PROJECT_EXPORT_DIRECTORY, `${appInfo.name}.ipa`), option['u'], option['p'], true);
|
|
22
|
+
}
|
|
23
|
+
else if (option['k'] && option['i']) {
|
|
24
|
+
// use apiKey, apiIssuer
|
|
25
|
+
xcrun_1.default.uploadApp((0, path_1.join)(resource_1.PROJECT_EXPORT_DIRECTORY, `${appInfo.name}.ipa`), option['k'], option['i'], false);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
static async runWithSimulator() {
|
|
29
|
+
await xcrun_1.default.runWithSimulator();
|
|
30
|
+
}
|
|
31
|
+
static async runWithHistory() {
|
|
32
|
+
await xcrun_1.default.runWithHistory();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.XcodeManager = XcodeManager;
|
|
@@ -1 +1,109 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.manifestSwiftTemplate = void 0;
|
|
4
|
+
exports.manifestSwiftTemplate = `
|
|
5
|
+
import Foundation
|
|
6
|
+
|
|
7
|
+
var pwaManager = PWAManager()
|
|
8
|
+
|
|
9
|
+
struct PWAManager: Codable {
|
|
10
|
+
var isLocal: Bool = false
|
|
11
|
+
var start_url: String = "START_URL"
|
|
12
|
+
var scope: String = "SCOPE"
|
|
13
|
+
var id: String = "AppID"
|
|
14
|
+
|
|
15
|
+
var name: String = "AppName"
|
|
16
|
+
var short_name: String = "name"
|
|
17
|
+
var description: String = "Description"
|
|
18
|
+
|
|
19
|
+
var display: PWADisplayMode = .minimal
|
|
20
|
+
var display_override: [PWADisplayMode] = []
|
|
21
|
+
var protocol_handlers: [PWAProtocol] = [PWAProtocol(protocolValue: "", url: "")]
|
|
22
|
+
var mainScene: WindowContainerOptions = .init(
|
|
23
|
+
defaultSize: .init(
|
|
24
|
+
width: SceneWidth,
|
|
25
|
+
height: SceneHeight
|
|
26
|
+
),
|
|
27
|
+
resizability: SceneResizability
|
|
28
|
+
)
|
|
29
|
+
var useMainScene: Bool = USE_MAIN_SCENE
|
|
30
|
+
|
|
31
|
+
mutating func _init() {
|
|
32
|
+
let urlType = start_url.split(separator: "://").first
|
|
33
|
+
if !(urlType == "http" || urlType == "https") {
|
|
34
|
+
if scope == "" || scope == "/" {
|
|
35
|
+
scope = "./"
|
|
36
|
+
}
|
|
37
|
+
let startUrl = Bundle.main.url(forResource: start_url, withExtension: "", subdirectory: "")
|
|
38
|
+
start_url = startUrl!.absoluteString
|
|
39
|
+
scope = URL(string: scope, relativeTo: startUrl)!.absoluteString
|
|
40
|
+
isLocal = true
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if display_override.count > 0 {
|
|
44
|
+
display = display_override[0]
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
for i in 0 ... protocol_handlers.count - 1 {
|
|
48
|
+
let item = protocol_handlers[i]
|
|
49
|
+
protocol_handlers[i].updateUrl(scope + item.url)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
func checkInScope(url: String) -> Bool {
|
|
54
|
+
return url.starts(with: scope)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// web+spatial://test
|
|
58
|
+
func checkInDeeplink(url: String) -> String {
|
|
59
|
+
var linkUrl: String = url
|
|
60
|
+
for item in protocol_handlers {
|
|
61
|
+
if linkUrl.starts(with: item.protocolValue) {
|
|
62
|
+
let queryString: String = linkUrl.replacingOccurrences(of: item.protocolValue, with: "").addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
|
|
63
|
+
linkUrl = item.url.replacingOccurrences(of: "%s", with: item.protocolValue + queryString)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
logger.debug(linkUrl)
|
|
67
|
+
return linkUrl
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
func getLocalResourceURL(url: String) -> String {
|
|
71
|
+
let path = String(url.split(separator: "file://").first!.split(separator: "?").first!)
|
|
72
|
+
let newUrl = URL(string: url)
|
|
73
|
+
let fileManager = FileManager.default
|
|
74
|
+
if fileManager.fileExists(atPath: newUrl!.path) {
|
|
75
|
+
return url
|
|
76
|
+
}
|
|
77
|
+
var resource: String = Bundle.main.url(forResource: newUrl?.path, withExtension: "", subdirectory: "")?.absoluteString ?? ""
|
|
78
|
+
if resource == "" {
|
|
79
|
+
resource = Bundle.main.url(forResource: "static-web" + path, withExtension: "", subdirectory: "")?.absoluteString ?? ""
|
|
80
|
+
}
|
|
81
|
+
if resource == "" {
|
|
82
|
+
return url
|
|
83
|
+
}
|
|
84
|
+
if newUrl?.query() != nil {
|
|
85
|
+
resource += "?" + (newUrl?.query())!
|
|
86
|
+
}
|
|
87
|
+
if newUrl?.fragment() != nil {
|
|
88
|
+
resource += "#" + (newUrl?.fragment())!
|
|
89
|
+
}
|
|
90
|
+
return resource
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
enum PWADisplayMode: Codable {
|
|
95
|
+
case minimal
|
|
96
|
+
case standalone
|
|
97
|
+
case fullscreen
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
struct PWAProtocol: Codable {
|
|
101
|
+
var protocolValue: String = ""
|
|
102
|
+
var url: String = ""
|
|
103
|
+
|
|
104
|
+
mutating func updateUrl(_ str: String) {
|
|
105
|
+
url = str
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
`;
|
|
@@ -1 +1,119 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.XcodebuildCMD = void 0;
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const resource_1 = require("../resource");
|
|
7
|
+
const semver_1 = require("semver");
|
|
8
|
+
const file_1 = require("../resource/file");
|
|
9
|
+
const { execSync, exec } = require('child_process');
|
|
10
|
+
class Xcodebuild {
|
|
11
|
+
static async project() {
|
|
12
|
+
try {
|
|
13
|
+
await new Promise((resolve, reject) => {
|
|
14
|
+
const projectFile = resource_1.PROJECT_DIRECTORY + '/web-spatial.xcodeproj';
|
|
15
|
+
const execRes = execSync(new XcodebuildCMD().project(projectFile).list().line);
|
|
16
|
+
console.log(execRes.toString());
|
|
17
|
+
resolve(execRes);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
console.log(error);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
static async list() {
|
|
25
|
+
try {
|
|
26
|
+
await new Promise((resolve, reject) => {
|
|
27
|
+
const projectFile = resource_1.PROJECT_DIRECTORY + '/web-spatial.xcodeproj';
|
|
28
|
+
const execRes = execSync(new XcodebuildCMD().project(projectFile).list().line);
|
|
29
|
+
console.log(execRes.toString());
|
|
30
|
+
resolve(execRes);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
console.log(error);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
static async archive(exportPath) {
|
|
38
|
+
try {
|
|
39
|
+
console.log('start archive');
|
|
40
|
+
if (!fs.existsSync(resource_1.PROJECT_EXPORT_DIRECTORY)) {
|
|
41
|
+
fs.mkdirSync(resource_1.PROJECT_EXPORT_DIRECTORY, { recursive: true });
|
|
42
|
+
}
|
|
43
|
+
return await new Promise((resolve, reject) => {
|
|
44
|
+
const projectFile = resource_1.PROJECT_DIRECTORY + '/web-spatial.xcodeproj';
|
|
45
|
+
// Archive
|
|
46
|
+
const archiveRes = execSync(new XcodebuildCMD()
|
|
47
|
+
.project(projectFile)
|
|
48
|
+
.scheme('web-spatial')
|
|
49
|
+
.archive((0, path_1.join)(resource_1.PROJECT_BUILD_DIRECTORY, './pack'))
|
|
50
|
+
.clean().line);
|
|
51
|
+
let resString = archiveRes.toString();
|
|
52
|
+
if (resString.indexOf('ARCHIVE SUCCEEDED') > 0) {
|
|
53
|
+
console.log('------------------- ARCHIVE SUCCEEDED -------------------');
|
|
54
|
+
console.log('start export');
|
|
55
|
+
// Export
|
|
56
|
+
const outRes = execSync(new XcodebuildCMD()
|
|
57
|
+
.output((0, path_1.join)(resource_1.PROJECT_BUILD_DIRECTORY, 'pack.xcarchive'), resource_1.PROJECT_EXPORT_DIRECTORY, (0, path_1.join)(resource_1.PROJECT_BUILD_DIRECTORY, 'ExportOptions.plist'))
|
|
58
|
+
.allowProvisioningUpdates().line);
|
|
59
|
+
resString = outRes.toString();
|
|
60
|
+
if (resString.indexOf('EXPORT SUCCEEDED') > 0) {
|
|
61
|
+
// copy .ipa file to export path
|
|
62
|
+
const useExportPath = exportPath !== null && exportPath !== void 0 ? exportPath : './build';
|
|
63
|
+
const path = (0, path_1.join)(process.cwd(), useExportPath);
|
|
64
|
+
if (!fs.existsSync(path)) {
|
|
65
|
+
fs.mkdirSync(path, { recursive: true });
|
|
66
|
+
}
|
|
67
|
+
(0, file_1.copyDir)(resource_1.PROJECT_EXPORT_DIRECTORY, path);
|
|
68
|
+
console.log('------------------- EXPORT SUCCEEDED -------------------');
|
|
69
|
+
resolve(true);
|
|
70
|
+
}
|
|
71
|
+
(0, semver_1.clean)(resource_1.PROJECT_BUILD_DIRECTORY);
|
|
72
|
+
}
|
|
73
|
+
resolve(false);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
console.log(error);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
exports.default = Xcodebuild;
|
|
82
|
+
class XcodebuildCMD {
|
|
83
|
+
constructor() {
|
|
84
|
+
this.line = 'xcodebuild';
|
|
85
|
+
}
|
|
86
|
+
project(xcodeproj) {
|
|
87
|
+
this.line += ` -project ${xcodeproj}`;
|
|
88
|
+
return this;
|
|
89
|
+
}
|
|
90
|
+
list() {
|
|
91
|
+
this.line += ' -list';
|
|
92
|
+
return this;
|
|
93
|
+
}
|
|
94
|
+
scheme(schemeName) {
|
|
95
|
+
this.line += ` -scheme ${schemeName}`;
|
|
96
|
+
return this;
|
|
97
|
+
}
|
|
98
|
+
archive(path) {
|
|
99
|
+
this.line += ` -archivePath ${path} archive`;
|
|
100
|
+
return this;
|
|
101
|
+
}
|
|
102
|
+
allowProvisioningUpdates() {
|
|
103
|
+
this.line += ' -allowProvisioningUpdates';
|
|
104
|
+
return this;
|
|
105
|
+
}
|
|
106
|
+
destination(target) {
|
|
107
|
+
this.line += ` -destination '${target}'`;
|
|
108
|
+
return this;
|
|
109
|
+
}
|
|
110
|
+
output(archivePath, outPath, plistPath) {
|
|
111
|
+
this.line += ` -exportArchive -archivePath ${archivePath} -exportPath ${outPath} -exportOptionsPlist ${plistPath}`;
|
|
112
|
+
return this;
|
|
113
|
+
}
|
|
114
|
+
clean() {
|
|
115
|
+
this.line += ' clean';
|
|
116
|
+
return this;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
exports.XcodebuildCMD = XcodebuildCMD;
|