distapp 1.0.0 → 1.0.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "distapp",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
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()
@@ -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
- }