distapp 1.0.0 → 1.0.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/cli.mjs +15 -6
- package/package.json +4 -1
- package/cli.sh +0 -12
- package/cli.ts +0 -74
- package/extract-aab-to-apk.ts +0 -94
package/cli.mjs
CHANGED
|
@@ -18214,13 +18214,17 @@ function normalizeError(error) {
|
|
|
18214
18214
|
|
|
18215
18215
|
// utils/upload-utils.ts
|
|
18216
18216
|
var myFetchApiKey;
|
|
18217
|
-
|
|
18218
|
-
|
|
18217
|
+
var myFetchApiUrl;
|
|
18218
|
+
function updateMyFetch(apiKey, fetchApiUrl) {
|
|
18219
|
+
myFetchApiKey = apiKey;
|
|
18220
|
+
myFetchApiUrl = fetchApiUrl;
|
|
18219
18221
|
}
|
|
18220
18222
|
var myFetch = $ofetch.create({
|
|
18221
18223
|
retry: false,
|
|
18222
18224
|
onRequest(request) {
|
|
18223
|
-
|
|
18225
|
+
if (myFetchApiUrl) {
|
|
18226
|
+
request.options.baseURL = myFetchApiUrl;
|
|
18227
|
+
}
|
|
18224
18228
|
if (myFetchApiKey) {
|
|
18225
18229
|
request.options.headers.append("API-KEY", myFetchApiKey);
|
|
18226
18230
|
}
|
|
@@ -18584,7 +18588,7 @@ async function getBundleKeystore(keystoreFile) {
|
|
|
18584
18588
|
}
|
|
18585
18589
|
var keystoreUrl = bundleKeystoreResponse.appKeystoreUrl;
|
|
18586
18590
|
if (keystoreUrl.startsWith("/")) {
|
|
18587
|
-
keystoreUrl = `${
|
|
18591
|
+
keystoreUrl = `${myFetchApiUrl}${keystoreUrl}`;
|
|
18588
18592
|
}
|
|
18589
18593
|
await downloadFile(keystoreUrl, keystoreFile);
|
|
18590
18594
|
return bundleKeystoreResponse;
|
|
@@ -18656,6 +18660,11 @@ var args = parseArgs({
|
|
|
18656
18660
|
},
|
|
18657
18661
|
apiKey: {
|
|
18658
18662
|
type: "string"
|
|
18663
|
+
},
|
|
18664
|
+
url: {
|
|
18665
|
+
type: "string",
|
|
18666
|
+
short: "u",
|
|
18667
|
+
default: process.env.DISTAPP_CLI_URL || "https://distapp.lhf.my.id"
|
|
18659
18668
|
}
|
|
18660
18669
|
}
|
|
18661
18670
|
});
|
|
@@ -18669,10 +18678,10 @@ function slugToOrgApp(slug) {
|
|
|
18669
18678
|
}
|
|
18670
18679
|
async function start() {
|
|
18671
18680
|
if (!values.apiKey) {
|
|
18672
|
-
console.error("API Key required");
|
|
18681
|
+
console.error("API Key required. Specify using --apiKey YOUR_API_KEY");
|
|
18673
18682
|
return;
|
|
18674
18683
|
}
|
|
18675
|
-
|
|
18684
|
+
updateMyFetch(values.apiKey, values.url);
|
|
18676
18685
|
if (values.distribute) {
|
|
18677
18686
|
const { orgName, appName } = slugToOrgApp(values.slug);
|
|
18678
18687
|
const filePath = resolve(values.file);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "distapp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Manage and distribute Android or iOS app",
|
|
5
5
|
"main": "cli.mjs",
|
|
6
6
|
"bin": {
|
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
"scripts": {
|
|
10
10
|
"start": "node cli.mjs"
|
|
11
11
|
},
|
|
12
|
+
"files": [
|
|
13
|
+
"cli.mjs"
|
|
14
|
+
],
|
|
12
15
|
"author": "Yunus Efendi",
|
|
13
16
|
"license": "GPL-3.0-only",
|
|
14
17
|
"keywords": [
|
package/cli.sh
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env sh
|
|
2
|
-
if ! [ -x "$(command -v node)" ]; then
|
|
3
|
-
echo 'Error: node is not installed.' >&2
|
|
4
|
-
exit 1
|
|
5
|
-
fi
|
|
6
|
-
|
|
7
|
-
set -e
|
|
8
|
-
|
|
9
|
-
scriptUrl="https://github.com/yunusefendi52/distapp/raw/refs/heads/main/cli/cli.mjs"
|
|
10
|
-
scriptPath="/tmp/distapp-cli.mjs"
|
|
11
|
-
curl -sL -o $scriptPath -H 'Cache-Control: no-cache' "$scriptUrl"
|
|
12
|
-
DISTAPP_CLI_URL="https://distapp.lhf.my.id" node $scriptPath "$@"
|
package/cli.ts
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { uploadArtifact, updateMyFetchApiKey } from '../utils/upload-utils.js'
|
|
4
|
-
import { promises } from "node:fs"
|
|
5
|
-
import { resolve } from "node:path"
|
|
6
|
-
import { parseArgs } from "node:util"
|
|
7
|
-
import { extractAabToApk } from './extract-aab-to-apk.js'
|
|
8
|
-
import { basename, extname } from 'path'
|
|
9
|
-
|
|
10
|
-
const args = parseArgs({
|
|
11
|
-
options: {
|
|
12
|
-
distribute: {
|
|
13
|
-
type: 'boolean',
|
|
14
|
-
},
|
|
15
|
-
slug: {
|
|
16
|
-
type: 'string',
|
|
17
|
-
},
|
|
18
|
-
file: {
|
|
19
|
-
type: 'string',
|
|
20
|
-
},
|
|
21
|
-
releaseNotes: {
|
|
22
|
-
type: 'string',
|
|
23
|
-
},
|
|
24
|
-
apiKey: {
|
|
25
|
-
type: 'string',
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
const { values } = args
|
|
31
|
-
|
|
32
|
-
function slugToOrgApp(slug: string): { orgName: string, appName: string } {
|
|
33
|
-
const slugPath = slug.split('/')
|
|
34
|
-
return {
|
|
35
|
-
orgName: slugPath[0],
|
|
36
|
-
appName: slugPath[1],
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
async function start() {
|
|
41
|
-
if (!values.apiKey) {
|
|
42
|
-
console.error('API Key required')
|
|
43
|
-
return
|
|
44
|
-
}
|
|
45
|
-
updateMyFetchApiKey(values.apiKey)
|
|
46
|
-
if (values.distribute) {
|
|
47
|
-
const { orgName, appName } = slugToOrgApp(values.slug!)
|
|
48
|
-
const filePath = resolve(values.file!)
|
|
49
|
-
const filename = basename(filePath, extname(filePath))
|
|
50
|
-
const file = await promises.readFile(filePath)
|
|
51
|
-
console.log("Distributing", {
|
|
52
|
-
filePath,
|
|
53
|
-
})
|
|
54
|
-
var bundleApkPath: string | undefined = undefined
|
|
55
|
-
var disposeBundle: (() => Promise<void>) | undefined
|
|
56
|
-
try {
|
|
57
|
-
if (filePath.endsWith('.aab')) {
|
|
58
|
-
const aabPath = filePath
|
|
59
|
-
const { bundleApk, dispose } = await extractAabToApk(aabPath)
|
|
60
|
-
bundleApkPath = bundleApk
|
|
61
|
-
disposeBundle = dispose
|
|
62
|
-
}
|
|
63
|
-
const bundleApkFile = bundleApkPath ? await promises.readFile(bundleApkPath) : undefined
|
|
64
|
-
await uploadArtifact(file, filename, orgName, appName, values.releaseNotes ? values.releaseNotes : null, bundleApkFile)
|
|
65
|
-
console.log(`Finished Distributing "${filePath}"` + (bundleApkPath ? ' with generated APK' : ''))
|
|
66
|
-
} finally {
|
|
67
|
-
await disposeBundle?.()
|
|
68
|
-
}
|
|
69
|
-
} else {
|
|
70
|
-
console.error('No valid command')
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
start()
|
package/extract-aab-to-apk.ts
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import util from 'util'
|
|
2
|
-
import { join, basename, extname } from 'path'
|
|
3
|
-
import { promises, existsSync } from 'fs'
|
|
4
|
-
import child_process from 'node:child_process'
|
|
5
|
-
import { uuidv4 } from "uuidv7"
|
|
6
|
-
const exec = util.promisify(child_process.exec)
|
|
7
|
-
import { myFetch } from '../utils/upload-utils.js'
|
|
8
|
-
import type { BundleKeystoreResponse } from '../server/api/artifacts/get-bundle-keystore.get.js'
|
|
9
|
-
import { downloadFile } from '~/server/services/downloadFile.js'
|
|
10
|
-
|
|
11
|
-
function getDateFilename(): string {
|
|
12
|
-
const today = new Date()
|
|
13
|
-
const dd = String(today.getDate()).padStart(2, '0')
|
|
14
|
-
const mm = String(today.getMonth() + 1).padStart(2, '0')
|
|
15
|
-
const yyyy = today.getFullYear()
|
|
16
|
-
|
|
17
|
-
return `${yyyy}_${mm}_${dd}_${today.getHours()}_${today.getMinutes()}`
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
async function getBundleKeystore(keystoreFile: string) {
|
|
21
|
-
const bundleKeystoreResponse: BundleKeystoreResponse | undefined = await myFetch('/api/artifacts/get-bundle-keystore')
|
|
22
|
-
if (!bundleKeystoreResponse) {
|
|
23
|
-
throw 'Error bundleKeystoreResponse'
|
|
24
|
-
}
|
|
25
|
-
var keystoreUrl = bundleKeystoreResponse.appKeystoreUrl
|
|
26
|
-
if (keystoreUrl.startsWith('/')) {
|
|
27
|
-
keystoreUrl = `${process.env.DISTAPP_CLI_URL}${keystoreUrl}`
|
|
28
|
-
}
|
|
29
|
-
await downloadFile(keystoreUrl, keystoreFile)
|
|
30
|
-
return bundleKeystoreResponse
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
async function getBundletoolPath(bundeFilesDir: string): Promise<string> {
|
|
34
|
-
if (process.env.DISTAPP_BUNDLETOOL_PATH) {
|
|
35
|
-
return process.env.DISTAPP_BUNDLETOOL_PATH
|
|
36
|
-
} else {
|
|
37
|
-
const bundletoolJarPath = join(bundeFilesDir, 'bundletool.jar')
|
|
38
|
-
const bundletoolCheck = await exec(`java -jar "${bundletoolJarPath}" version || echo "Error check bundletool version"`)
|
|
39
|
-
if (!bundletoolCheck.stdout.includes('1.17.2')) {
|
|
40
|
-
await downloadFile('https://github.com/google/bundletool/releases/download/1.17.2/bundletool-all-1.17.2.jar', bundletoolJarPath)
|
|
41
|
-
}
|
|
42
|
-
return bundletoolJarPath
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export async function extractAabToApk(aabPath: string, bundleKeystoreFetcher?: (keystoreFile: string) => Promise<BundleKeystoreResponse>) {
|
|
47
|
-
const cwdRoot = process.cwd()
|
|
48
|
-
const bundeFilesDir = join(cwdRoot, '.distapp-data', 'bundle_files')
|
|
49
|
-
await promises.mkdir(bundeFilesDir, {
|
|
50
|
-
recursive: true,
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
const bundletoolJarPath = await getBundletoolPath(bundeFilesDir)
|
|
54
|
-
|
|
55
|
-
const tempBundleDir = join(bundeFilesDir, `${getDateFilename()}_${uuidv4().replaceAll('-', '').slice(0, 12)}`)
|
|
56
|
-
// console.log('extract_aab: ', {
|
|
57
|
-
// tempBundleDir: tempBundleDir,
|
|
58
|
-
// })
|
|
59
|
-
await promises.mkdir(tempBundleDir, {
|
|
60
|
-
recursive: true,
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
const bundleApks = join(tempBundleDir, "bundle.apks")
|
|
64
|
-
const actualApk = join(tempBundleDir, `${basename(aabPath, extname(aabPath))}.apk`)
|
|
65
|
-
const keystoreFile = join(tempBundleDir, `app.jks`)
|
|
66
|
-
|
|
67
|
-
const bundleKeystore = bundleKeystoreFetcher
|
|
68
|
-
? await bundleKeystoreFetcher?.(keystoreFile)
|
|
69
|
-
: await getBundleKeystore(keystoreFile)
|
|
70
|
-
|
|
71
|
-
await exec(`
|
|
72
|
-
java -jar "${bundletoolJarPath}" build-apks --bundle=${aabPath} --output=${bundleApks} --mode=universal \\
|
|
73
|
-
--ks="${keystoreFile}" \\
|
|
74
|
-
--ks-pass=pass:${bundleKeystore.appKeystorePass} \\
|
|
75
|
-
--ks-key-alias=${bundleKeystore.appKeystoreAlias} \\
|
|
76
|
-
--key-pass=pass:${bundleKeystore.appKeystorePass}
|
|
77
|
-
`)
|
|
78
|
-
await exec(`unzip -p "${bundleApks}" universal.apk > ${actualApk}`)
|
|
79
|
-
await promises.rm(bundleApks, {
|
|
80
|
-
force: true,
|
|
81
|
-
})
|
|
82
|
-
// console.log('extract_aab: success', {
|
|
83
|
-
// output: actualApk,
|
|
84
|
-
// })
|
|
85
|
-
return {
|
|
86
|
-
bundleApk: actualApk,
|
|
87
|
-
dispose: async () => {
|
|
88
|
-
await promises.rm(tempBundleDir, {
|
|
89
|
-
force: true,
|
|
90
|
-
recursive: true,
|
|
91
|
-
})
|
|
92
|
-
},
|
|
93
|
-
}
|
|
94
|
-
}
|