@liascript/exporter 3.0.0--1.0.3 → 3.0.1--1.0.3
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/assets/capacitor/{index.bfe7363b.js → index.a7f021f7.js} +1 -1
- package/dist/assets/capacitor/index.html +1 -1
- package/dist/assets/capacitor/{jszip.min.f6eda75b.js → jszip.min.43389eb1.js} +1 -1
- package/dist/assets/capacitor/{trystero-ipfs.min.b27a61d7.js → trystero-ipfs.min.f25fe3e7.js} +1 -1
- package/dist/assets/indexeddb/{index.599a57d6.js → index.4aceca2f.js} +1 -1
- package/dist/assets/indexeddb/index.html +1 -1
- package/dist/assets/indexeddb/{jszip.min.63142cc8.js → jszip.min.4fbcc13f.js} +1 -1
- package/dist/assets/scorm2004/{index.7a5820ab.js → index.33bec53a.js} +1 -1
- package/dist/assets/scorm2004/index.html +1 -1
- package/dist/assets/scorm2004/{jszip.min.63142cc8.js → jszip.min.4fbcc13f.js} +1 -1
- package/dist/assets/xapi/{index.018a032a.js → index.f2e89e49.js} +1 -1
- package/dist/assets/xapi/index.html +1 -1
- package/dist/assets/xapi/{jszip.min.eaecf580.js → jszip.min.19c66d77.js} +1 -1
- package/dist/index.js +47 -47
- package/dist/server/presets.json +94 -0
- package/dist/server/presets.yaml +120 -0
- package/dist/server/public/app.js +1 -0
- package/dist/server/public/assets/android.svg +38 -0
- package/dist/server/public/assets/cmi.svg +154 -0
- package/dist/server/public/assets/docx.svg +20 -0
- package/dist/server/public/assets/edX.svg +75 -0
- package/dist/server/public/assets/edx.svg +75 -0
- package/dist/server/public/assets/epub.svg +18 -0
- package/dist/server/public/assets/icon.svg +82 -0
- package/dist/server/public/assets/ilias.png +0 -0
- package/dist/server/public/assets/json.svg +4 -0
- package/dist/server/public/assets/learnworlds.png +0 -0
- package/dist/server/public/assets/moodle.svg +190 -0
- package/dist/server/public/assets/opal.png +0 -0
- package/dist/server/public/assets/openolat.png +0 -0
- package/dist/server/public/assets/pdf.svg +4 -0
- package/dist/server/public/assets/rdf.svg +4 -0
- package/dist/server/public/assets/scorm.png +0 -0
- package/dist/server/public/assets/web.png +0 -0
- package/dist/server/public/assets/xapi.png +0 -0
- package/dist/server/public/i18n.js +1 -0
- package/dist/server/public/index.html +1587 -0
- package/dist/server/public/locales/de.json +247 -0
- package/dist/server/public/locales/en.json +247 -0
- package/dist/server/public/status.html +251 -0
- package/dist/server/public/styles.css +712 -0
- package/package.json +5 -1
- package/.parcelrc +0 -3
- package/DESKTOP_APP_README.md +0 -58
- package/DOCKERHUB_DESCRIPTION.md +0 -52
- package/Dockerfile +0 -129
- package/PLAYSTORE_GUIDE.md +0 -172
- package/action.yml +0 -157
- package/custom.css +0 -10
- package/electron-builder.json +0 -149
- package/src/cli.ts +0 -69
- package/src/colorize.ts +0 -115
- package/src/export/android.ts +0 -419
- package/src/export/docx.ts +0 -1025
- package/src/export/epub.ts +0 -1306
- package/src/export/h5p.ts +0 -390
- package/src/export/helper.ts +0 -360
- package/src/export/ims.ts +0 -191
- package/src/export/pdf.ts +0 -406
- package/src/export/presets.ts +0 -220
- package/src/export/project.ts +0 -829
- package/src/export/rdf.ts +0 -551
- package/src/export/scorm12.ts +0 -167
- package/src/export/scorm2004.ts +0 -140
- package/src/export/web.ts +0 -306
- package/src/export/xapi.ts +0 -424
- package/src/exporter.ts +0 -296
- package/src/index.ts +0 -96
- package/src/parser.ts +0 -373
- package/src/presets.yaml +0 -219
- package/src/types.ts +0 -82
- package/tsconfig.json +0 -24
package/src/export/android.ts
DELETED
|
@@ -1,419 +0,0 @@
|
|
|
1
|
-
import * as helper from './helper'
|
|
2
|
-
|
|
3
|
-
import * as COLOR from '../colorize'
|
|
4
|
-
const path = require('path')
|
|
5
|
-
const fs = require('fs-extra')
|
|
6
|
-
const { exec } = require('child_process')
|
|
7
|
-
|
|
8
|
-
export function help() {
|
|
9
|
-
console.log('')
|
|
10
|
-
console.log(COLOR.heading('Android settings:'), '\n')
|
|
11
|
-
|
|
12
|
-
COLOR.info(
|
|
13
|
-
'Android export generates a native Android application (.apk) from your LiaScript course using Capacitor. This requires the Android SDK to be installed on your system.\n',
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
console.log('\nLearn more:')
|
|
17
|
-
console.log('- Capacitor: https://capacitorjs.com/')
|
|
18
|
-
console.log('- Android SDK: https://developer.android.com/studio')
|
|
19
|
-
console.log('')
|
|
20
|
-
|
|
21
|
-
COLOR.command(
|
|
22
|
-
null,
|
|
23
|
-
'--android-sdk',
|
|
24
|
-
' Specify sdk.dir which is required for building.',
|
|
25
|
-
)
|
|
26
|
-
COLOR.command(
|
|
27
|
-
null,
|
|
28
|
-
'--android-appName',
|
|
29
|
-
' Name of the App (Main-title is used as default).',
|
|
30
|
-
)
|
|
31
|
-
COLOR.command(
|
|
32
|
-
null,
|
|
33
|
-
'--android-appId',
|
|
34
|
-
' Required to identify your App reverse url such as io.github.liascript',
|
|
35
|
-
)
|
|
36
|
-
COLOR.command(
|
|
37
|
-
null,
|
|
38
|
-
'--android-icon',
|
|
39
|
-
' Optional icon with 1024x1024 px',
|
|
40
|
-
)
|
|
41
|
-
COLOR.command(
|
|
42
|
-
null,
|
|
43
|
-
'--android-iconBackgroundColor',
|
|
44
|
-
' Optional background color for the icon',
|
|
45
|
-
)
|
|
46
|
-
COLOR.command(
|
|
47
|
-
null,
|
|
48
|
-
'--android-iconBackgroundColorDark',
|
|
49
|
-
' Optional background color for the icon in dark mode',
|
|
50
|
-
)
|
|
51
|
-
COLOR.command(
|
|
52
|
-
null,
|
|
53
|
-
'--android-release',
|
|
54
|
-
' Create release APK build (requires signing setup)',
|
|
55
|
-
)
|
|
56
|
-
COLOR.command(
|
|
57
|
-
null,
|
|
58
|
-
'--android-bundle',
|
|
59
|
-
' Create release AAB bundle for Play Store (requires signing setup)',
|
|
60
|
-
)
|
|
61
|
-
COLOR.command(
|
|
62
|
-
null,
|
|
63
|
-
'--android-keystore',
|
|
64
|
-
' Path to keystore file for signing',
|
|
65
|
-
)
|
|
66
|
-
COLOR.command(
|
|
67
|
-
null,
|
|
68
|
-
'--android-keystorePassword',
|
|
69
|
-
' Keystore password (or use KEYSTORE_PASSWORD env var)',
|
|
70
|
-
)
|
|
71
|
-
COLOR.command(
|
|
72
|
-
null,
|
|
73
|
-
'--android-keyAlias',
|
|
74
|
-
' Key alias (default: release, or use KEY_ALIAS env var)',
|
|
75
|
-
)
|
|
76
|
-
COLOR.command(
|
|
77
|
-
null,
|
|
78
|
-
'--android-keyPassword',
|
|
79
|
-
' Key password (or use KEY_PASSWORD env var)',
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
COLOR.command(
|
|
83
|
-
null,
|
|
84
|
-
'--android-preview',
|
|
85
|
-
' Open course in Android-Studio',
|
|
86
|
-
)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export interface AndroidExportArguments {
|
|
90
|
-
input: string
|
|
91
|
-
readme: string
|
|
92
|
-
output: string
|
|
93
|
-
format: string
|
|
94
|
-
path: string
|
|
95
|
-
key?: string
|
|
96
|
-
'android-sdk'?: string
|
|
97
|
-
'android-appId'?: string
|
|
98
|
-
'android-appName'?: string
|
|
99
|
-
'android-icon'?: string
|
|
100
|
-
'android-iconBackgroundColor'?: string
|
|
101
|
-
'android-iconBackgroundColorDark'?: string
|
|
102
|
-
'android-preview'?: boolean
|
|
103
|
-
'android-release'?: boolean
|
|
104
|
-
'android-bundle'?: boolean
|
|
105
|
-
'android-keystore'?: string
|
|
106
|
-
'android-keystorePassword'?: string
|
|
107
|
-
'android-keyAlias'?: string
|
|
108
|
-
'android-keyPassword'?: string
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export const format = 'android'
|
|
112
|
-
|
|
113
|
-
export async function exporter(argument: AndroidExportArguments, json: any) {
|
|
114
|
-
// make temp folder
|
|
115
|
-
let tmp = await helper.tmpDir()
|
|
116
|
-
const dirname = helper.dirname()
|
|
117
|
-
|
|
118
|
-
// copy assets to temp/dist
|
|
119
|
-
await fs.copy(
|
|
120
|
-
path.join(dirname, './assets/capacitor'),
|
|
121
|
-
path.join(tmp, './www'),
|
|
122
|
-
)
|
|
123
|
-
|
|
124
|
-
await fs.copy(path.join(dirname, './assets/common'), path.join(tmp, './www'))
|
|
125
|
-
|
|
126
|
-
// copy logo and splash
|
|
127
|
-
await fs.copy(path.join(dirname, './resources'), path.join(tmp, './assets'))
|
|
128
|
-
|
|
129
|
-
if (argument['android-preview']) {
|
|
130
|
-
// create a link, this way, the app can be updated interactively
|
|
131
|
-
await fs.symlink(
|
|
132
|
-
path.resolve(argument.path),
|
|
133
|
-
path.join(tmp, './www/res'),
|
|
134
|
-
'dir',
|
|
135
|
-
)
|
|
136
|
-
} else {
|
|
137
|
-
// copy base path or readme-directory into temp
|
|
138
|
-
await fs.copy(path.resolve(argument.path), path.join(tmp, './www/res'), {
|
|
139
|
-
filter: helper.filterHidden(argument.path),
|
|
140
|
-
})
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
let capacitorCachePath = path.join(dirname, './capacitor-cache')
|
|
144
|
-
if (fs.existsSync(capacitorCachePath)) {
|
|
145
|
-
console.log('Using cached Capacitor dependencies for Android export')
|
|
146
|
-
await fs.copy(capacitorCachePath, tmp)
|
|
147
|
-
} else {
|
|
148
|
-
capacitorCachePath = null
|
|
149
|
-
|
|
150
|
-
await helper.writeFile(
|
|
151
|
-
path.join(tmp, 'package.json'),
|
|
152
|
-
`{
|
|
153
|
-
"scripts": {
|
|
154
|
-
"build": "npx cap sync android"
|
|
155
|
-
},
|
|
156
|
-
"dependencies": {
|
|
157
|
-
"@capacitor/cli": "^8.0.0",
|
|
158
|
-
"@capacitor-community/text-to-speech": "git+https://github.com/capacitor-community/text-to-speech.git#v8.0.0",
|
|
159
|
-
"@capacitor/android": "^8.0.0",
|
|
160
|
-
"@capacitor/assets": "^3.0.5",
|
|
161
|
-
"@capacitor/core": "^8.0.0"
|
|
162
|
-
},
|
|
163
|
-
"engines": {
|
|
164
|
-
"node": ">= 12"
|
|
165
|
-
}
|
|
166
|
-
}`,
|
|
167
|
-
)
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
await helper.writeFile(
|
|
171
|
-
path.join(tmp, 'capacitor.config.ts'),
|
|
172
|
-
`import { CapacitorConfig } from '@capacitor/cli'
|
|
173
|
-
|
|
174
|
-
const config: CapacitorConfig = {
|
|
175
|
-
appId: "${argument['android-appId']}",
|
|
176
|
-
appName: "${argument['android-appName'] || json.lia.str_title}",
|
|
177
|
-
webDir: 'www',
|
|
178
|
-
server: { androidScheme: 'http' },
|
|
179
|
-
plugins: {
|
|
180
|
-
SystemBars: {
|
|
181
|
-
insetsHandling: 'css',
|
|
182
|
-
style: 'light',
|
|
183
|
-
overlaysWebView: true,
|
|
184
|
-
backgroundColor: '#00000000',
|
|
185
|
-
},
|
|
186
|
-
},
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
export default config`,
|
|
190
|
-
)
|
|
191
|
-
|
|
192
|
-
let index = fs.readFileSync(path.join(tmp, 'www/index.html'), 'utf8')
|
|
193
|
-
|
|
194
|
-
index = helper.inject(
|
|
195
|
-
`<script> if (!window.LIA) { window.LIA = {} } window.LIA.defaultCourseURL = "./res/${path.basename(
|
|
196
|
-
argument.readme,
|
|
197
|
-
)}"</script>`,
|
|
198
|
-
index,
|
|
199
|
-
'<body>',
|
|
200
|
-
)
|
|
201
|
-
|
|
202
|
-
try {
|
|
203
|
-
await helper.writeFile(path.join(tmp, 'www/index.html'), index)
|
|
204
|
-
} catch (e) {
|
|
205
|
-
console.warn(e)
|
|
206
|
-
return
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
execute(
|
|
210
|
-
[
|
|
211
|
-
capacitorCachePath
|
|
212
|
-
? 'echo "Using cached Capacitor dependencies"'
|
|
213
|
-
: 'npm i',
|
|
214
|
-
'npx cap add android',
|
|
215
|
-
'npx cap sync',
|
|
216
|
-
`npx @capacitor/assets generate --iconBackgroundColor '${argument['android-iconBackgroundColor'] || '#bbbbbb'}' --iconBackgroundColorDark '${argument['android-iconBackgroundColorDark'] || '#555555'}'`,
|
|
217
|
-
],
|
|
218
|
-
tmp,
|
|
219
|
-
async function () {
|
|
220
|
-
await sdk(tmp, argument['android-sdk'])
|
|
221
|
-
|
|
222
|
-
if (argument['android-preview']) {
|
|
223
|
-
execute(
|
|
224
|
-
['npx cap open android'],
|
|
225
|
-
tmp,
|
|
226
|
-
|
|
227
|
-
() => {
|
|
228
|
-
console.log('ready')
|
|
229
|
-
},
|
|
230
|
-
)
|
|
231
|
-
} else if (argument['android-bundle']) {
|
|
232
|
-
// Build signed AAB for Play Store
|
|
233
|
-
await configureSigning(tmp, argument)
|
|
234
|
-
execute(
|
|
235
|
-
['./gradlew bundleRelease --stacktrace'],
|
|
236
|
-
path.join(tmp, 'android'),
|
|
237
|
-
function () {
|
|
238
|
-
const bundlePath = path.join(
|
|
239
|
-
tmp,
|
|
240
|
-
'android/app/build/outputs/bundle/release/app-release.aab',
|
|
241
|
-
)
|
|
242
|
-
|
|
243
|
-
if (fs.existsSync(bundlePath)) {
|
|
244
|
-
console.warn('✅ AAB bundle created successfully')
|
|
245
|
-
fs.copySync(bundlePath, argument.output + '.aab')
|
|
246
|
-
console.log(`✅ Signed AAB: ${argument.output}.aab`)
|
|
247
|
-
} else {
|
|
248
|
-
console.error('❌ AAB file not found. Build may have failed.')
|
|
249
|
-
process.exit(1)
|
|
250
|
-
}
|
|
251
|
-
},
|
|
252
|
-
)
|
|
253
|
-
} else if (argument['android-release']) {
|
|
254
|
-
// Build signed release APK
|
|
255
|
-
await configureSigning(tmp, argument)
|
|
256
|
-
execute(
|
|
257
|
-
['./gradlew assembleRelease --stacktrace'],
|
|
258
|
-
path.join(tmp, 'android'),
|
|
259
|
-
function () {
|
|
260
|
-
console.warn('✅ APK created successfully')
|
|
261
|
-
fs.copySync(
|
|
262
|
-
path.join(
|
|
263
|
-
tmp,
|
|
264
|
-
'android/app/build/outputs/apk/release/app-release.apk',
|
|
265
|
-
),
|
|
266
|
-
argument.output + '.apk',
|
|
267
|
-
)
|
|
268
|
-
},
|
|
269
|
-
)
|
|
270
|
-
} else {
|
|
271
|
-
// Build debug APK
|
|
272
|
-
execute(
|
|
273
|
-
['./gradlew assembleDebug --stacktrace'],
|
|
274
|
-
path.join(tmp, 'android'),
|
|
275
|
-
function () {
|
|
276
|
-
console.warn('✅ Debug APK created')
|
|
277
|
-
fs.copySync(
|
|
278
|
-
path.join(
|
|
279
|
-
tmp,
|
|
280
|
-
'android/app/build/outputs/apk/debug/app-debug.apk',
|
|
281
|
-
),
|
|
282
|
-
argument.output + '.apk',
|
|
283
|
-
)
|
|
284
|
-
},
|
|
285
|
-
)
|
|
286
|
-
}
|
|
287
|
-
},
|
|
288
|
-
)
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
async function sdk(tmpPath: string, uri?: string) {
|
|
292
|
-
const androidPath = path.join(tmpPath, 'android')
|
|
293
|
-
|
|
294
|
-
// Always create gradle.properties with Java home
|
|
295
|
-
try {
|
|
296
|
-
const javaHome =
|
|
297
|
-
process.env.JAVA_HOME || '/usr/lib/jvm/java-21-openjdk-amd64'
|
|
298
|
-
await helper.writeFile(
|
|
299
|
-
path.join(androidPath, 'gradle.properties'),
|
|
300
|
-
`# Project-wide Gradle settings.
|
|
301
|
-
org.gradle.java.home=${javaHome}
|
|
302
|
-
org.gradle.jvmargs=-Xmx1536m
|
|
303
|
-
android.useAndroidX=true`,
|
|
304
|
-
)
|
|
305
|
-
} catch (e) {
|
|
306
|
-
console.warn('Warning: Could not write gradle.properties:', e)
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
// Create local.properties if SDK path is provided
|
|
310
|
-
if (uri) {
|
|
311
|
-
try {
|
|
312
|
-
await helper.writeFile(
|
|
313
|
-
path.join(androidPath, 'local.properties'),
|
|
314
|
-
`sdk.dir=${uri}`,
|
|
315
|
-
)
|
|
316
|
-
} catch (e) {
|
|
317
|
-
console.warn('Warning: Could not write local.properties:', e)
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
async function configureSigning(
|
|
323
|
-
tmpPath: string,
|
|
324
|
-
argument: AndroidExportArguments,
|
|
325
|
-
) {
|
|
326
|
-
const androidPath = path.join(tmpPath, 'android')
|
|
327
|
-
const buildGradlePath = path.join(androidPath, 'app/build.gradle')
|
|
328
|
-
|
|
329
|
-
// Get signing configuration from arguments or environment variables
|
|
330
|
-
const keystoreFile =
|
|
331
|
-
argument['android-keystore'] || process.env.KEYSTORE_FILE
|
|
332
|
-
const keystorePassword =
|
|
333
|
-
argument['android-keystorePassword'] || process.env.KEYSTORE_PASSWORD
|
|
334
|
-
const keyAlias = argument['android-keyAlias'] || process.env.KEY_ALIAS || 'release'
|
|
335
|
-
const keyPassword =
|
|
336
|
-
argument['android-keyPassword'] || process.env.KEY_PASSWORD || keystorePassword
|
|
337
|
-
|
|
338
|
-
if (!keystoreFile) {
|
|
339
|
-
console.error('ERROR: Keystore file not specified!')
|
|
340
|
-
console.error('Use --android-keystore or set KEYSTORE_FILE environment variable')
|
|
341
|
-
throw new Error('Keystore file required for signed builds')
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
if (!fs.existsSync(keystoreFile)) {
|
|
345
|
-
console.error(`ERROR: Keystore file not found: ${keystoreFile}`)
|
|
346
|
-
throw new Error('Keystore file does not exist')
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
if (!keystorePassword || !keyPassword) {
|
|
350
|
-
console.error('ERROR: Keystore passwords not provided!')
|
|
351
|
-
console.error('Use --android-keystorePassword and --android-keyPassword')
|
|
352
|
-
console.error('Or set KEYSTORE_PASSWORD and KEY_PASSWORD environment variables')
|
|
353
|
-
throw new Error('Keystore passwords required for signed builds')
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
console.log(`Configuring signing with keystore: ${keystoreFile}`)
|
|
357
|
-
|
|
358
|
-
// Read the existing build.gradle
|
|
359
|
-
let buildGradle = fs.readFileSync(buildGradlePath, 'utf8')
|
|
360
|
-
|
|
361
|
-
// Add signing configuration to build.gradle
|
|
362
|
-
const signingConfig = `
|
|
363
|
-
signingConfigs {
|
|
364
|
-
release {
|
|
365
|
-
storeFile file("${keystoreFile}")
|
|
366
|
-
storePassword "${keystorePassword}"
|
|
367
|
-
keyAlias "${keyAlias}"
|
|
368
|
-
keyPassword "${keyPassword}"
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
`
|
|
372
|
-
|
|
373
|
-
// Insert signing config after android {
|
|
374
|
-
buildGradle = buildGradle.replace(
|
|
375
|
-
/android\s*\{/,
|
|
376
|
-
`android {
|
|
377
|
-
${signingConfig}`,
|
|
378
|
-
)
|
|
379
|
-
|
|
380
|
-
// Add signingConfig to release buildType
|
|
381
|
-
buildGradle = buildGradle.replace(
|
|
382
|
-
/buildTypes\s*\{[\s\S]*?release\s*\{/,
|
|
383
|
-
(match: string) => {
|
|
384
|
-
return match + '\n signingConfig signingConfigs.release'
|
|
385
|
-
},
|
|
386
|
-
)
|
|
387
|
-
|
|
388
|
-
await helper.writeFile(buildGradlePath, buildGradle)
|
|
389
|
-
console.log('Signing configuration added to build.gradle')
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
function execute(cmds: string[], cwd: string, callback: () => void) {
|
|
393
|
-
const cmd = cmds.shift()
|
|
394
|
-
|
|
395
|
-
if (cmd) {
|
|
396
|
-
console.log('exec:', cmd)
|
|
397
|
-
|
|
398
|
-
exec(
|
|
399
|
-
cmd,
|
|
400
|
-
{ cwd: cwd },
|
|
401
|
-
async (error: Error | null, stdout: string, stderr: string) => {
|
|
402
|
-
if (error) {
|
|
403
|
-
console.error(`❌ Command failed: ${error.message}`)
|
|
404
|
-
return
|
|
405
|
-
}
|
|
406
|
-
if (stderr && !cmd.includes('gradlew')) {
|
|
407
|
-
console.warn(`stderr: ${stderr}`)
|
|
408
|
-
}
|
|
409
|
-
if (stdout && !cmd.includes('gradlew')) {
|
|
410
|
-
console.log(`stdout: ${stdout}`)
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
execute(cmds, cwd, callback)
|
|
414
|
-
},
|
|
415
|
-
)
|
|
416
|
-
} else {
|
|
417
|
-
callback()
|
|
418
|
-
}
|
|
419
|
-
}
|