@macle-community/simulator-web 0.0.0-stage → 1.0.0
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 +125 -2
- package/bin/macle-web-simulator.js +108 -0
- package/package.json +37 -4
- package/runtime/framework/service/service.js +1 -0
- package/runtime/framework/view/view.js +1 -0
- package/runtime/remoteDebug/adapter.js +1 -0
- package/runtime/remoteDebug/service.html +16 -0
- package/runtime/remoteDebug/sub-packages.js +1 -0
- package/runtime/simulator/config/config.json +40 -0
- package/runtime/simulator/css/common.css +945 -0
- package/runtime/simulator/index.html +95 -0
- package/runtime/simulator/mockApi.json +1 -0
- package/runtime/simulator/native/native.js +1 -0
- package/runtime/simulator/public/default-user-avatar@128w.jpg +0 -0
- package/runtime/simulator/service/app.js +1 -0
- package/runtime/simulator/service/service.html +14 -0
- package/runtime/simulator/service/sync-api.js +1 -0
- package/runtime/simulator/version.json +1 -0
- package/runtime/simulator/view/webview.js +1 -0
- package/src/compiler.js +117 -0
- package/src/mock-backend.js +225 -0
- package/src/project-parser.js +87 -0
- package/src/server.js +334 -0
- package/src/watcher.js +76 -0
- package/web/index.html +234 -0
- package/web/qrcode.js +1145 -0
- package/web/simulator.css +526 -0
- package/web/simulator.js +510 -0
package/src/compiler.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const os = require('os');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Search candidates for official @macle/compiler
|
|
7
|
+
*/
|
|
8
|
+
function findMacleCompiler() {
|
|
9
|
+
const candidates = [
|
|
10
|
+
path.join(__dirname, '../../DevToolkit_26.6.0/DevToolkit_26.6.0-LG0001/Macle_26.6.0-LG0001_Engine_Compiler/node_modules/@macle/compiler'),
|
|
11
|
+
path.join(__dirname, '../../../DevToolkit_26.6.0/DevToolkit_26.6.0-LG0001/Macle_26.6.0-LG0001_Engine_Compiler/node_modules/@macle/compiler'),
|
|
12
|
+
path.join(__dirname, '../../DevToolkit_25.9.0/Macle_25.9.0_DevSuite_IDE/macle-miniprogram-tools-25.9.0-file/extension/node_modules/@macle/compiler'),
|
|
13
|
+
path.join(__dirname, '../node_modules/@macle/compiler')
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
for (const cand of candidates) {
|
|
17
|
+
if (fs.existsSync(cand)) {
|
|
18
|
+
try {
|
|
19
|
+
const compiler = require(cand);
|
|
20
|
+
return { compiler, path: cand };
|
|
21
|
+
} catch (err) {
|
|
22
|
+
console.warn(`[Compiler] Notice: Candidate found at ${cand} but could not be loaded:`, err.message);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Compile or prepare project assets for web simulator
|
|
31
|
+
*/
|
|
32
|
+
async function compileProject(sourceDir, projectName) {
|
|
33
|
+
const compilerInfo = findMacleCompiler();
|
|
34
|
+
const outComposeDir = path.join(os.homedir(), '.macle/target/compose', projectName, 'root/debug/app');
|
|
35
|
+
|
|
36
|
+
// Check if sourceDir is already compiled (e.g. contains app-service.js)
|
|
37
|
+
const isAlreadyCompiled = fs.existsSync(path.join(sourceDir, 'app-service.js')) ||
|
|
38
|
+
fs.existsSync(path.join(sourceDir, 'app-config.json'));
|
|
39
|
+
|
|
40
|
+
fs.mkdirSync(outComposeDir, { recursive: true });
|
|
41
|
+
|
|
42
|
+
if (isAlreadyCompiled) {
|
|
43
|
+
// Copy compiled files directly
|
|
44
|
+
copyDirectory(sourceDir, outComposeDir);
|
|
45
|
+
return {
|
|
46
|
+
success: true,
|
|
47
|
+
mode: 'precompiled',
|
|
48
|
+
outDir: outComposeDir
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Needs compilation via @macle/compiler
|
|
53
|
+
if (!compilerInfo) {
|
|
54
|
+
console.warn('[Compiler] Warning: @macle/compiler not found; copying source files directly.');
|
|
55
|
+
copyDirectory(sourceDir, outComposeDir);
|
|
56
|
+
return {
|
|
57
|
+
success: false,
|
|
58
|
+
mode: 'raw-copy',
|
|
59
|
+
outDir: outComposeDir,
|
|
60
|
+
error: '@macle/compiler not found'
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
try {
|
|
65
|
+
const startTime = Date.now();
|
|
66
|
+
console.log(`[Compiler] Pre-compiling Macle source (${sourceDir})...`);
|
|
67
|
+
await compilerInfo.compiler.compile(sourceDir, outComposeDir, { debug: true, es5: false });
|
|
68
|
+
|
|
69
|
+
// Sync project config if available
|
|
70
|
+
const projConf = path.join(sourceDir, 'project.config.json');
|
|
71
|
+
if (fs.existsSync(projConf)) {
|
|
72
|
+
fs.copyFileSync(projConf, path.join(outComposeDir, 'project.config.json'));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const elapsed = ((Date.now() - startTime) / 1000).toFixed(2);
|
|
76
|
+
console.log(`[Compiler] Pre-compilation successful -> ${outComposeDir} (${elapsed}s)`);
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
success: true,
|
|
80
|
+
mode: 'compiled',
|
|
81
|
+
outDir: outComposeDir,
|
|
82
|
+
compilerPath: compilerInfo.path,
|
|
83
|
+
elapsed
|
|
84
|
+
};
|
|
85
|
+
} catch (err) {
|
|
86
|
+
console.error('[Compiler] Compilation error:', err.message);
|
|
87
|
+
return {
|
|
88
|
+
success: false,
|
|
89
|
+
mode: 'error',
|
|
90
|
+
outDir: outComposeDir,
|
|
91
|
+
error: err.message
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function copyDirectory(src, dest) {
|
|
97
|
+
if (!fs.existsSync(src)) return;
|
|
98
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
99
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
100
|
+
for (const entry of entries) {
|
|
101
|
+
const srcPath = path.join(src, entry.name);
|
|
102
|
+
const destPath = path.join(dest, entry.name);
|
|
103
|
+
if (entry.isDirectory()) {
|
|
104
|
+
if (entry.name !== 'node_modules' && entry.name !== '.git') {
|
|
105
|
+
copyDirectory(srcPath, destPath);
|
|
106
|
+
}
|
|
107
|
+
} else {
|
|
108
|
+
fs.copyFileSync(srcPath, destPath);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
module.exports = {
|
|
114
|
+
findMacleCompiler,
|
|
115
|
+
compileProject,
|
|
116
|
+
copyDirectory
|
|
117
|
+
};
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const http = require('http');
|
|
4
|
+
const https = require('https');
|
|
5
|
+
const crypto = require('crypto');
|
|
6
|
+
const url = require('url');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Native Macle MCSS Simulator Backend
|
|
10
|
+
* Handles /mcss/simulate/* endpoints
|
|
11
|
+
*/
|
|
12
|
+
function createMockBackend(appDir) {
|
|
13
|
+
const storeDir = path.join(appDir, 'store');
|
|
14
|
+
const tmpDir = path.join(appDir, 'tmp');
|
|
15
|
+
fs.mkdirSync(storeDir, { recursive: true });
|
|
16
|
+
fs.mkdirSync(tmpDir, { recursive: true });
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
handleRequestData(req, res, body) {
|
|
20
|
+
try {
|
|
21
|
+
const data = body.data || {};
|
|
22
|
+
const params = data.mockType ? data.inputParams : (typeof data.inputParams === 'string' ? JSON.parse(data.inputParams) : data.inputParams);
|
|
23
|
+
const targetUrl = params.url;
|
|
24
|
+
const method = (params.method || 'GET').toUpperCase();
|
|
25
|
+
const headers = params.header || {};
|
|
26
|
+
const postData = params.data ? (typeof params.data === 'string' ? params.data : JSON.stringify(params.data)) : null;
|
|
27
|
+
|
|
28
|
+
if (!targetUrl) {
|
|
29
|
+
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
30
|
+
return res.end(JSON.stringify({ errMsg: 'requestData:fail missing url' }));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const parsedUrl = new URL(targetUrl);
|
|
34
|
+
const isHttps = parsedUrl.protocol === 'https:';
|
|
35
|
+
const client = isHttps ? https : http;
|
|
36
|
+
|
|
37
|
+
if (postData && !headers['Content-Type']) {
|
|
38
|
+
headers['Content-Type'] = 'application/json';
|
|
39
|
+
}
|
|
40
|
+
if (postData) {
|
|
41
|
+
headers['Content-Length'] = Buffer.byteLength(postData);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const requestOptions = {
|
|
45
|
+
hostname: parsedUrl.hostname,
|
|
46
|
+
port: parsedUrl.port || (isHttps ? 443 : 80),
|
|
47
|
+
path: parsedUrl.pathname + parsedUrl.search,
|
|
48
|
+
method: method,
|
|
49
|
+
headers: headers,
|
|
50
|
+
timeout: params.timeout || 10000
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const proxyReq = client.request(requestOptions, (proxyRes) => {
|
|
54
|
+
let chunks = [];
|
|
55
|
+
proxyRes.on('data', chunk => chunks.push(chunk));
|
|
56
|
+
proxyRes.on('end', () => {
|
|
57
|
+
const buffer = Buffer.concat(chunks);
|
|
58
|
+
const contentType = proxyRes.headers['content-type'] || '';
|
|
59
|
+
let responseData;
|
|
60
|
+
|
|
61
|
+
if (contentType.includes('application/json')) {
|
|
62
|
+
try {
|
|
63
|
+
responseData = JSON.parse(buffer.toString('utf8'));
|
|
64
|
+
} catch (e) {
|
|
65
|
+
responseData = buffer.toString('utf8');
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
responseData = buffer.toString('utf8');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
res.writeHead(proxyRes.statusCode || 200, {
|
|
72
|
+
'Content-Type': 'application/json',
|
|
73
|
+
'Access-Control-Allow-Origin': '*'
|
|
74
|
+
});
|
|
75
|
+
res.end(JSON.stringify(responseData));
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
proxyReq.on('error', (err) => {
|
|
80
|
+
res.writeHead(502, { 'Content-Type': 'application/json' });
|
|
81
|
+
res.end(JSON.stringify({ errMsg: `requestData:fail ${err.message}` }));
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
proxyReq.on('timeout', () => {
|
|
85
|
+
proxyReq.destroy();
|
|
86
|
+
res.writeHead(504, { 'Content-Type': 'application/json' });
|
|
87
|
+
res.end(JSON.stringify({ errMsg: 'requestData:fail timeout' }));
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
if (postData) {
|
|
91
|
+
proxyReq.write(postData);
|
|
92
|
+
}
|
|
93
|
+
proxyReq.end();
|
|
94
|
+
} catch (err) {
|
|
95
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
96
|
+
res.end(JSON.stringify({ errMsg: `requestData:error ${err.message}` }));
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
handleSaveFile(req, res, body) {
|
|
101
|
+
try {
|
|
102
|
+
const data = body.data || {};
|
|
103
|
+
const params = typeof data.inputParams === 'string' ? JSON.parse(data.inputParams) : (data.inputParams || {});
|
|
104
|
+
const tempPath = params.tempFilePath || '';
|
|
105
|
+
const fileName = path.basename(tempPath);
|
|
106
|
+
const sourceFile = path.join(tmpDir, fileName);
|
|
107
|
+
const targetFile = path.join(storeDir, fileName);
|
|
108
|
+
|
|
109
|
+
if (!fileName || !fs.existsSync(sourceFile)) {
|
|
110
|
+
// If file not in tmpDir, create a mock saved file
|
|
111
|
+
const mockContent = 'mock-saved-content';
|
|
112
|
+
fs.writeFileSync(targetFile, mockContent);
|
|
113
|
+
} else {
|
|
114
|
+
fs.copyFileSync(sourceFile, targetFile);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
118
|
+
res.end(JSON.stringify({
|
|
119
|
+
errMsg: 'savedFile:ok',
|
|
120
|
+
savedFilePath: `/store/${fileName}`
|
|
121
|
+
}));
|
|
122
|
+
} catch (err) {
|
|
123
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
124
|
+
res.end(JSON.stringify({ errMsg: `saveFile:fail ${err.message}` }));
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
handleRemoveSaved(req, res, body) {
|
|
129
|
+
try {
|
|
130
|
+
const data = body.data || {};
|
|
131
|
+
const params = typeof data.inputParams === 'string' ? JSON.parse(data.inputParams) : (data.inputParams || {});
|
|
132
|
+
const filePath = params.filePath || '';
|
|
133
|
+
const fileName = path.basename(filePath);
|
|
134
|
+
const targetFile = path.join(storeDir, fileName);
|
|
135
|
+
|
|
136
|
+
if (fs.existsSync(targetFile)) {
|
|
137
|
+
fs.unlinkSync(targetFile);
|
|
138
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
139
|
+
res.end(JSON.stringify({ errMsg: 'removeSavedFile:ok' }));
|
|
140
|
+
} else {
|
|
141
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
142
|
+
res.end(JSON.stringify({ errMsg: 'removeSavedFile:fail file not exist' }));
|
|
143
|
+
}
|
|
144
|
+
} catch (err) {
|
|
145
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
146
|
+
res.end(JSON.stringify({ errMsg: `removeSaved:fail ${err.message}` }));
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
|
|
150
|
+
handleFileInfo(req, res, query) {
|
|
151
|
+
try {
|
|
152
|
+
const dataStr = query.data;
|
|
153
|
+
const params = typeof dataStr === 'string' ? JSON.parse(dataStr) : (dataStr || {});
|
|
154
|
+
const filePath = params.filePath || '';
|
|
155
|
+
const algorithm = (params.digestAlgorithm || 'sha256').toLowerCase();
|
|
156
|
+
const targetFile = path.resolve(appDir, filePath.replace(/^\//, ''));
|
|
157
|
+
|
|
158
|
+
if (fs.existsSync(targetFile)) {
|
|
159
|
+
const content = fs.readFileSync(targetFile);
|
|
160
|
+
const hash = crypto.createHash(algorithm).update(content).digest('hex');
|
|
161
|
+
const stat = fs.statSync(targetFile);
|
|
162
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
163
|
+
res.end(JSON.stringify({
|
|
164
|
+
errMsg: 'getFileInfo:ok',
|
|
165
|
+
digest: hash,
|
|
166
|
+
size: stat.size
|
|
167
|
+
}));
|
|
168
|
+
} else {
|
|
169
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
170
|
+
res.end(JSON.stringify({ errMsg: 'getFileInfo:fail file not exist' }));
|
|
171
|
+
}
|
|
172
|
+
} catch (err) {
|
|
173
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
174
|
+
res.end(JSON.stringify({ errMsg: `getFileInfo:fail ${err.message}` }));
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
|
|
178
|
+
handleSavedFileList(req, res) {
|
|
179
|
+
try {
|
|
180
|
+
const files = fs.readdirSync(storeDir);
|
|
181
|
+
const fileList = files.map(file => {
|
|
182
|
+
const p = path.join(storeDir, file);
|
|
183
|
+
const stat = fs.statSync(p);
|
|
184
|
+
return {
|
|
185
|
+
filePath: `/store/${file}`,
|
|
186
|
+
size: stat.size,
|
|
187
|
+
creatTime: stat.ctimeMs
|
|
188
|
+
};
|
|
189
|
+
});
|
|
190
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
191
|
+
res.end(JSON.stringify({ errMsg: 'getSavedFileList:ok', fileList }));
|
|
192
|
+
} catch (err) {
|
|
193
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
194
|
+
res.end(JSON.stringify({ errMsg: `getSavedFileList:fail ${err.message}` }));
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
|
|
198
|
+
handleSavedFileInfo(req, res, query) {
|
|
199
|
+
try {
|
|
200
|
+
const dataStr = query.data;
|
|
201
|
+
const params = typeof dataStr === 'string' ? JSON.parse(dataStr) : (dataStr || {});
|
|
202
|
+
const fileName = path.basename(params.filePath || '');
|
|
203
|
+
const targetFile = path.join(storeDir, fileName);
|
|
204
|
+
|
|
205
|
+
if (fs.existsSync(targetFile)) {
|
|
206
|
+
const stat = fs.statSync(targetFile);
|
|
207
|
+
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
208
|
+
res.end(JSON.stringify({
|
|
209
|
+
errMsg: 'getSavedFileInfo:ok',
|
|
210
|
+
size: stat.size,
|
|
211
|
+
createTime: stat.ctimeMs
|
|
212
|
+
}));
|
|
213
|
+
} else {
|
|
214
|
+
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
215
|
+
res.end(JSON.stringify({ errMsg: 'getSavedFileInfo:fail file not find' }));
|
|
216
|
+
}
|
|
217
|
+
} catch (err) {
|
|
218
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
219
|
+
res.end(JSON.stringify({ errMsg: `getSavedFileInfo:fail ${err.message}` }));
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
module.exports = { createMockBackend };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Discovers and parses Macle miniprogram project configuration
|
|
6
|
+
*/
|
|
7
|
+
function parseProject(projectDir) {
|
|
8
|
+
const resolvedDir = path.resolve(projectDir);
|
|
9
|
+
let appConfig = null;
|
|
10
|
+
let projectConfig = null;
|
|
11
|
+
let isCompiled = false;
|
|
12
|
+
let appDir = resolvedDir;
|
|
13
|
+
|
|
14
|
+
// Check if projectDir is already a compiled dist folder
|
|
15
|
+
const appServiceCandidates = [
|
|
16
|
+
path.join(resolvedDir, 'app-service.js'),
|
|
17
|
+
path.join(resolvedDir, 'root/debug/app/app-service.js')
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
for (const cand of appServiceCandidates) {
|
|
21
|
+
if (fs.existsSync(cand)) {
|
|
22
|
+
isCompiled = true;
|
|
23
|
+
appDir = path.dirname(cand);
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Look for app-config.json or app.json
|
|
29
|
+
const configCandidates = [
|
|
30
|
+
path.join(appDir, 'app-config.json'),
|
|
31
|
+
path.join(resolvedDir, 'app-config.json'),
|
|
32
|
+
path.join(resolvedDir, 'app.json'),
|
|
33
|
+
path.join(appDir, 'app.json')
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
for (const cand of configCandidates) {
|
|
37
|
+
if (fs.existsSync(cand)) {
|
|
38
|
+
try {
|
|
39
|
+
appConfig = JSON.parse(fs.readFileSync(cand, 'utf8'));
|
|
40
|
+
break;
|
|
41
|
+
} catch (err) {
|
|
42
|
+
console.warn(`[Parser] Warning: Failed to parse ${cand}:`, err.message);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Look for project.config.json
|
|
48
|
+
const projCandidates = [
|
|
49
|
+
path.join(resolvedDir, 'project.config.json'),
|
|
50
|
+
path.join(path.dirname(resolvedDir), 'project.config.json')
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
for (const cand of projCandidates) {
|
|
54
|
+
if (fs.existsSync(cand)) {
|
|
55
|
+
try {
|
|
56
|
+
projectConfig = JSON.parse(fs.readFileSync(cand, 'utf8'));
|
|
57
|
+
break;
|
|
58
|
+
} catch (e) {}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const projectName = (projectConfig && projectConfig.projectname) ||
|
|
63
|
+
path.basename(resolvedDir);
|
|
64
|
+
|
|
65
|
+
const pages = (appConfig && Array.isArray(appConfig.pages)) ? appConfig.pages : ['pages/index/index'];
|
|
66
|
+
const entryPagePath = (appConfig && appConfig.entryPagePath) || pages[0] || 'pages/index/index';
|
|
67
|
+
const windowConfig = (appConfig && appConfig.window) || {
|
|
68
|
+
navigationBarTitleText: projectName,
|
|
69
|
+
navigationBarBackgroundColor: '#000000',
|
|
70
|
+
navigationBarTextStyle: 'white'
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
sourceDir: resolvedDir,
|
|
75
|
+
appDir,
|
|
76
|
+
isCompiled,
|
|
77
|
+
projectName,
|
|
78
|
+
pages,
|
|
79
|
+
entryPagePath,
|
|
80
|
+
window: windowConfig,
|
|
81
|
+
tabBar: (appConfig && appConfig.tabBar) || null,
|
|
82
|
+
appConfig,
|
|
83
|
+
projectConfig
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
module.exports = { parseProject };
|