mirror of
https://gitcode.com/github-mirrors/react-native-update-cli.git
synced 2025-09-18 02:16:11 +08:00
Compare commits
13 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
6db237fc8c | ||
![]() |
bd7d78e7ac | ||
![]() |
91a602979d | ||
![]() |
2cfe451db5 | ||
![]() |
c7d0aadbf2 | ||
![]() |
2e37d6f1c7 | ||
![]() |
6e7d5de82e | ||
![]() |
3266f09644 | ||
![]() |
848f528625 | ||
![]() |
18d772b1bc | ||
![]() |
bf0cea66b9 | ||
![]() |
8c31ee5762 | ||
![]() |
002e8662d6 |
12
bun.lock
12
bun.lock
@@ -25,7 +25,7 @@
|
|||||||
"properties": "^1.2.1",
|
"properties": "^1.2.1",
|
||||||
"read": "^4.1.0",
|
"read": "^4.1.0",
|
||||||
"registry-auth-token": "^5.1.0",
|
"registry-auth-token": "^5.1.0",
|
||||||
"semver": "^7.7.1",
|
"semver": "^7.7.2",
|
||||||
"tcp-ping": "^0.1.1",
|
"tcp-ping": "^0.1.1",
|
||||||
"tty-table": "4.2",
|
"tty-table": "4.2",
|
||||||
"yauzl": "^3.2.0",
|
"yauzl": "^3.2.0",
|
||||||
@@ -33,11 +33,11 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "^1.9.4",
|
"@biomejs/biome": "^1.9.4",
|
||||||
"@swc/cli": "0.7.3",
|
"@swc/cli": "0.7.7",
|
||||||
"@swc/core": "^1.11.24",
|
"@swc/core": "^1.11.24",
|
||||||
"@types/filesize-parser": "^1.5.3",
|
"@types/filesize-parser": "^1.5.3",
|
||||||
"@types/fs-extra": "^11.0.4",
|
"@types/fs-extra": "^11.0.4",
|
||||||
"@types/node": "^22.14.1",
|
"@types/node": "^22.15.18",
|
||||||
"@types/node-fetch": "^2.6.12",
|
"@types/node-fetch": "^2.6.12",
|
||||||
"@types/progress": "^2.0.7",
|
"@types/progress": "^2.0.7",
|
||||||
"@types/semver": "^7.7.0",
|
"@types/semver": "^7.7.0",
|
||||||
@@ -125,7 +125,7 @@
|
|||||||
|
|
||||||
"@sindresorhus/is": ["@sindresorhus/is@5.6.0", "", {}, "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g=="],
|
"@sindresorhus/is": ["@sindresorhus/is@5.6.0", "", {}, "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g=="],
|
||||||
|
|
||||||
"@swc/cli": ["@swc/cli@0.7.3", "", { "dependencies": { "@swc/counter": "^0.1.3", "@xhmikosr/bin-wrapper": "^13.0.5", "commander": "^8.3.0", "fast-glob": "^3.2.5", "minimatch": "^9.0.3", "piscina": "^4.3.1", "semver": "^7.3.8", "slash": "3.0.0", "source-map": "^0.7.3" }, "peerDependencies": { "@swc/core": "^1.2.66", "chokidar": "^4.0.1" }, "optionalPeers": ["chokidar"], "bin": { "swc": "bin/swc.js", "swcx": "bin/swcx.js", "spack": "bin/spack.js" } }, "sha512-rnVXNnlURjdOuPaBIwZ3TmBA44BF/eP0j154LanlgPEYfau74ige7cpKlKkZr1IBqMOG99lAnYNxQipDWA3hdg=="],
|
"@swc/cli": ["@swc/cli@0.7.7", "", { "dependencies": { "@swc/counter": "^0.1.3", "@xhmikosr/bin-wrapper": "^13.0.5", "commander": "^8.3.0", "fast-glob": "^3.2.5", "minimatch": "^9.0.3", "piscina": "^4.3.1", "semver": "^7.3.8", "slash": "3.0.0", "source-map": "^0.7.3" }, "peerDependencies": { "@swc/core": "^1.2.66", "chokidar": "^4.0.1" }, "optionalPeers": ["chokidar"], "bin": { "swc": "bin/swc.js", "swcx": "bin/swcx.js", "spack": "bin/spack.js" } }, "sha512-j4yYm9bx3pxWofaJKX1BFwj/3ngUDynN4UIQ2Xd2h0h/7Gt7zkReBTpDN7g5S13mgAYxacaTHTOUsz18097E8w=="],
|
||||||
|
|
||||||
"@swc/core": ["@swc/core@1.11.24", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.21" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.11.24", "@swc/core-darwin-x64": "1.11.24", "@swc/core-linux-arm-gnueabihf": "1.11.24", "@swc/core-linux-arm64-gnu": "1.11.24", "@swc/core-linux-arm64-musl": "1.11.24", "@swc/core-linux-x64-gnu": "1.11.24", "@swc/core-linux-x64-musl": "1.11.24", "@swc/core-win32-arm64-msvc": "1.11.24", "@swc/core-win32-ia32-msvc": "1.11.24", "@swc/core-win32-x64-msvc": "1.11.24" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" }, "optionalPeers": ["@swc/helpers"] }, "sha512-MaQEIpfcEMzx3VWWopbofKJvaraqmL6HbLlw2bFZ7qYqYw3rkhM0cQVEgyzbHtTWwCwPMFZSC2DUbhlZgrMfLg=="],
|
"@swc/core": ["@swc/core@1.11.24", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.21" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.11.24", "@swc/core-darwin-x64": "1.11.24", "@swc/core-linux-arm-gnueabihf": "1.11.24", "@swc/core-linux-arm64-gnu": "1.11.24", "@swc/core-linux-arm64-musl": "1.11.24", "@swc/core-linux-x64-gnu": "1.11.24", "@swc/core-linux-x64-musl": "1.11.24", "@swc/core-win32-arm64-msvc": "1.11.24", "@swc/core-win32-ia32-msvc": "1.11.24", "@swc/core-win32-x64-msvc": "1.11.24" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" }, "optionalPeers": ["@swc/helpers"] }, "sha512-MaQEIpfcEMzx3VWWopbofKJvaraqmL6HbLlw2bFZ7qYqYw3rkhM0cQVEgyzbHtTWwCwPMFZSC2DUbhlZgrMfLg=="],
|
||||||
|
|
||||||
@@ -165,7 +165,7 @@
|
|||||||
|
|
||||||
"@types/jsonfile": ["@types/jsonfile@6.1.4", "", { "dependencies": { "@types/node": "*" } }, "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ=="],
|
"@types/jsonfile": ["@types/jsonfile@6.1.4", "", { "dependencies": { "@types/node": "*" } }, "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ=="],
|
||||||
|
|
||||||
"@types/node": ["@types/node@22.14.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw=="],
|
"@types/node": ["@types/node@22.15.18", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-v1DKRfUdyW+jJhZNEI1PYy29S2YRxMV5AOO/x/SjKmW0acCIOqmbj6Haf9eHAhsPmrhlHSxEhv/1WszcLWV4cg=="],
|
||||||
|
|
||||||
"@types/node-fetch": ["@types/node-fetch@2.6.12", "", { "dependencies": { "@types/node": "*", "form-data": "^4.0.0" } }, "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA=="],
|
"@types/node-fetch": ["@types/node-fetch@2.6.12", "", { "dependencies": { "@types/node": "*", "form-data": "^4.0.0" } }, "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA=="],
|
||||||
|
|
||||||
@@ -625,7 +625,7 @@
|
|||||||
|
|
||||||
"seek-bzip": ["seek-bzip@2.0.0", "", { "dependencies": { "commander": "^6.0.0" }, "bin": { "seek-bunzip": "bin/seek-bunzip", "seek-table": "bin/seek-bzip-table" } }, "sha512-SMguiTnYrhpLdk3PwfzHeotrcwi8bNV4iemL9tx9poR/yeaMYwB9VzR1w7b57DuWpuqR8n6oZboi0hj3AxZxQg=="],
|
"seek-bzip": ["seek-bzip@2.0.0", "", { "dependencies": { "commander": "^6.0.0" }, "bin": { "seek-bunzip": "bin/seek-bunzip", "seek-table": "bin/seek-bzip-table" } }, "sha512-SMguiTnYrhpLdk3PwfzHeotrcwi8bNV4iemL9tx9poR/yeaMYwB9VzR1w7b57DuWpuqR8n6oZboi0hj3AxZxQg=="],
|
||||||
|
|
||||||
"semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="],
|
"semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="],
|
||||||
|
|
||||||
"semver-regex": ["semver-regex@4.0.5", "", {}, "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw=="],
|
"semver-regex": ["semver-regex@4.0.5", "", {}, "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw=="],
|
||||||
|
|
||||||
|
48
cli.json
48
cli.json
@@ -57,6 +57,27 @@
|
|||||||
},
|
},
|
||||||
"metaInfo": {
|
"metaInfo": {
|
||||||
"hasValue": true
|
"hasValue": true
|
||||||
|
},
|
||||||
|
"packageId": {
|
||||||
|
"hasValue": true
|
||||||
|
},
|
||||||
|
"packageVersion": {
|
||||||
|
"hasValue": true
|
||||||
|
},
|
||||||
|
"minPackageVersion": {
|
||||||
|
"hasValue": true
|
||||||
|
},
|
||||||
|
"maxPackageVersion": {
|
||||||
|
"hasValue": true
|
||||||
|
},
|
||||||
|
"packageVersionRange": {
|
||||||
|
"hasValue": true
|
||||||
|
},
|
||||||
|
"rollout": {
|
||||||
|
"hasValue": true
|
||||||
|
},
|
||||||
|
"dryRun": {
|
||||||
|
"default": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -87,8 +108,14 @@
|
|||||||
"maxPackageVersion": {
|
"maxPackageVersion": {
|
||||||
"hasValue": true
|
"hasValue": true
|
||||||
},
|
},
|
||||||
|
"packageVersionRange": {
|
||||||
|
"hasValue": true
|
||||||
|
},
|
||||||
"rollout": {
|
"rollout": {
|
||||||
"hasValue": true
|
"hasValue": true
|
||||||
|
},
|
||||||
|
"dryRun": {
|
||||||
|
"default": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -169,6 +196,27 @@
|
|||||||
"metaInfo": {
|
"metaInfo": {
|
||||||
"hasValue": true,
|
"hasValue": true,
|
||||||
"description": "Meta information for publishing"
|
"description": "Meta information for publishing"
|
||||||
|
},
|
||||||
|
"packageId": {
|
||||||
|
"hasValue": true
|
||||||
|
},
|
||||||
|
"packageVersion": {
|
||||||
|
"hasValue": true
|
||||||
|
},
|
||||||
|
"minPackageVersion": {
|
||||||
|
"hasValue": true
|
||||||
|
},
|
||||||
|
"maxPackageVersion": {
|
||||||
|
"hasValue": true
|
||||||
|
},
|
||||||
|
"packageVersionRange": {
|
||||||
|
"hasValue": true
|
||||||
|
},
|
||||||
|
"rollout": {
|
||||||
|
"hasValue": true
|
||||||
|
},
|
||||||
|
"dryRun": {
|
||||||
|
"default": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-native-update-cli",
|
"name": "react-native-update-cli",
|
||||||
"version": "1.44.6",
|
"version": "1.46.2",
|
||||||
"description": "command line tool for react-native-update (remote updates for react native)",
|
"description": "command line tool for react-native-update (remote updates for react native)",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
"properties": "^1.2.1",
|
"properties": "^1.2.1",
|
||||||
"read": "^4.1.0",
|
"read": "^4.1.0",
|
||||||
"registry-auth-token": "^5.1.0",
|
"registry-auth-token": "^5.1.0",
|
||||||
"semver": "^7.7.1",
|
"semver": "^7.7.2",
|
||||||
"tcp-ping": "^0.1.1",
|
"tcp-ping": "^0.1.1",
|
||||||
"tty-table": "4.2",
|
"tty-table": "4.2",
|
||||||
"yauzl": "^3.2.0",
|
"yauzl": "^3.2.0",
|
||||||
@@ -68,11 +68,11 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "^1.9.4",
|
"@biomejs/biome": "^1.9.4",
|
||||||
"@swc/cli": "0.7.3",
|
"@swc/cli": "0.7.7",
|
||||||
"@swc/core": "^1.11.24",
|
"@swc/core": "^1.11.24",
|
||||||
"@types/filesize-parser": "^1.5.3",
|
"@types/filesize-parser": "^1.5.3",
|
||||||
"@types/fs-extra": "^11.0.4",
|
"@types/fs-extra": "^11.0.4",
|
||||||
"@types/node": "^22.14.1",
|
"@types/node": "^22.15.18",
|
||||||
"@types/node-fetch": "^2.6.12",
|
"@types/node-fetch": "^2.6.12",
|
||||||
"@types/progress": "^2.0.7",
|
"@types/progress": "^2.0.7",
|
||||||
"@types/semver": "^7.7.0",
|
"@types/semver": "^7.7.0",
|
||||||
|
@@ -11,7 +11,7 @@ import {
|
|||||||
credentialFile,
|
credentialFile,
|
||||||
defaultEndpoint,
|
defaultEndpoint,
|
||||||
} from './utils/constants';
|
} from './utils/constants';
|
||||||
import type { Session } from 'types';
|
import type { Session, Package } from 'types';
|
||||||
import FormData from 'form-data';
|
import FormData from 'form-data';
|
||||||
import { t } from './utils/i18n';
|
import { t } from './utils/i18n';
|
||||||
|
|
||||||
@@ -177,3 +177,8 @@ export async function uploadFile(fn: string, key?: string) {
|
|||||||
// const body = await response.json();
|
// const body = await response.json();
|
||||||
return { hash: key || formData.key };
|
return { hash: key || formData.key };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getAllPackages = async (appId: string) => {
|
||||||
|
const { data } = await get(`/app/${appId}/package/list?limit=1000`);
|
||||||
|
return data as Package[] | undefined | null;
|
||||||
|
};
|
||||||
|
20
src/app.ts
20
src/app.ts
@@ -8,7 +8,13 @@ import { t } from './utils/i18n';
|
|||||||
|
|
||||||
const validPlatforms = ['ios', 'android', 'harmony'];
|
const validPlatforms = ['ios', 'android', 'harmony'];
|
||||||
|
|
||||||
export function checkPlatform(platform: Platform) {
|
export async function getPlatform(platform?: string) {
|
||||||
|
return assertPlatform(
|
||||||
|
platform || (await question(t('platformQuestion'))),
|
||||||
|
) as Platform;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function assertPlatform(platform: string) {
|
||||||
if (!validPlatforms.includes(platform)) {
|
if (!validPlatforms.includes(platform)) {
|
||||||
throw new Error(t('unsupportedPlatform', { platform }));
|
throw new Error(t('unsupportedPlatform', { platform }));
|
||||||
}
|
}
|
||||||
@@ -16,7 +22,7 @@ export function checkPlatform(platform: Platform) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getSelectedApp(platform: Platform) {
|
export function getSelectedApp(platform: Platform) {
|
||||||
checkPlatform(platform);
|
assertPlatform(platform);
|
||||||
|
|
||||||
if (!fs.existsSync('update.json')) {
|
if (!fs.existsSync('update.json')) {
|
||||||
throw new Error(t('appNotSelected', { platform }));
|
throw new Error(t('appNotSelected', { platform }));
|
||||||
@@ -60,7 +66,7 @@ export async function chooseApp(platform: Platform) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const commands = {
|
export const appCommands = {
|
||||||
createApp: async function ({
|
createApp: async function ({
|
||||||
options,
|
options,
|
||||||
}: {
|
}: {
|
||||||
@@ -68,9 +74,7 @@ export const commands = {
|
|||||||
}) {
|
}) {
|
||||||
const name = options.name || (await question(t('appNameQuestion')));
|
const name = options.name || (await question(t('appNameQuestion')));
|
||||||
const { downloadUrl } = options;
|
const { downloadUrl } = options;
|
||||||
const platform = checkPlatform(
|
const platform = await getPlatform(options.platform);
|
||||||
options.platform || (await question(t('platformQuestion'))),
|
|
||||||
);
|
|
||||||
const { id } = await post('/app/create', { name, platform, downloadUrl });
|
const { id } = await post('/app/create', { name, platform, downloadUrl });
|
||||||
console.log(t('createAppSuccess', { id }));
|
console.log(t('createAppSuccess', { id }));
|
||||||
await this.selectApp({
|
await this.selectApp({
|
||||||
@@ -104,9 +108,7 @@ export const commands = {
|
|||||||
args: string[];
|
args: string[];
|
||||||
options: { platform: Platform };
|
options: { platform: Platform };
|
||||||
}) => {
|
}) => {
|
||||||
const platform = checkPlatform(
|
const platform = await getPlatform(options.platform);
|
||||||
options.platform || (await question(t('platformQuestion'))),
|
|
||||||
);
|
|
||||||
const id = args[0]
|
const id = args[0]
|
||||||
? Number.parseInt(args[0])
|
? Number.parseInt(args[0])
|
||||||
: (await chooseApp(platform)).id;
|
: (await chooseApp(platform)).id;
|
||||||
|
@@ -8,9 +8,9 @@ import {
|
|||||||
type ZipFile as YauzlZipFile,
|
type ZipFile as YauzlZipFile,
|
||||||
} from 'yauzl';
|
} from 'yauzl';
|
||||||
import { question, checkPlugins } from './utils';
|
import { question, checkPlugins } from './utils';
|
||||||
import { checkPlatform } from './app';
|
import { getPlatform } from './app';
|
||||||
import { spawn, spawnSync } from 'child_process';
|
import { spawn, spawnSync } from 'child_process';
|
||||||
import semverSatisfies from 'semver/functions/satisfies';
|
import { satisfies } from 'compare-versions';
|
||||||
const g2js = require('gradle-to-js/lib/parser');
|
const g2js = require('gradle-to-js/lib/parser');
|
||||||
import os from 'os';
|
import os from 'os';
|
||||||
const properties = require('properties');
|
const properties = require('properties');
|
||||||
@@ -19,7 +19,7 @@ import { t } from './utils/i18n';
|
|||||||
import { tempDir } from './utils/constants';
|
import { tempDir } from './utils/constants';
|
||||||
import { checkLockFiles } from './utils/check-lockfile';
|
import { checkLockFiles } from './utils/check-lockfile';
|
||||||
import { addGitIgnore } from './utils/add-gitignore';
|
import { addGitIgnore } from './utils/add-gitignore';
|
||||||
import { commands as versionCommands } from './versions';
|
import { versionCommands } from './versions';
|
||||||
|
|
||||||
type Diff = (oldSource?: Buffer, newSource?: Buffer) => Buffer;
|
type Diff = (oldSource?: Buffer, newSource?: Buffer) => Buffer;
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ async function runReactNativeBundleCommand({
|
|||||||
.toString(),
|
.toString(),
|
||||||
).version;
|
).version;
|
||||||
// expo cli 0.10.17 (expo 49) 开始支持 bundle:embed
|
// expo cli 0.10.17 (expo 49) 开始支持 bundle:embed
|
||||||
if (semverSatisfies(expoCliVersion, '>= 0.10.17')) {
|
if (satisfies(expoCliVersion, '>= 0.10.17')) {
|
||||||
usingExpo = true;
|
usingExpo = true;
|
||||||
} else {
|
} else {
|
||||||
cliPath = undefined;
|
cliPath = undefined;
|
||||||
@@ -149,6 +149,14 @@ async function runReactNativeBundleCommand({
|
|||||||
const bundleParams = await checkPlugins();
|
const bundleParams = await checkPlugins();
|
||||||
const isSentry = bundleParams.sentry;
|
const isSentry = bundleParams.sentry;
|
||||||
|
|
||||||
|
if (isSentry) {
|
||||||
|
if (platform === 'ios') {
|
||||||
|
process.env.SENTRY_PROPERTIES = 'ios/sentry.properties';
|
||||||
|
} else if (platform === 'android') {
|
||||||
|
process.env.SENTRY_PROPERTIES = 'android/sentry.properties';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let bundleCommand = 'bundle';
|
let bundleCommand = 'bundle';
|
||||||
if (usingExpo) {
|
if (usingExpo) {
|
||||||
bundleCommand = 'export:embed';
|
bundleCommand = 'export:embed';
|
||||||
@@ -280,9 +288,22 @@ async function copyHarmonyBundle(outputFolder: string) {
|
|||||||
}
|
}
|
||||||
await fs.remove(path.join(harmonyRawPath, 'update.json'));
|
await fs.remove(path.join(harmonyRawPath, 'update.json'));
|
||||||
await fs.copy('update.json', path.join(harmonyRawPath, 'update.json'));
|
await fs.copy('update.json', path.join(harmonyRawPath, 'update.json'));
|
||||||
|
|
||||||
await fs.ensureDir(outputFolder);
|
await fs.ensureDir(outputFolder);
|
||||||
await fs.copy(harmonyRawPath, outputFolder);
|
|
||||||
|
const files = await fs.readdir(harmonyRawPath);
|
||||||
|
for (const file of files) {
|
||||||
|
if (file !== 'update.json' && file !== 'meta.json') {
|
||||||
|
const sourcePath = path.join(harmonyRawPath, file);
|
||||||
|
const destPath = path.join(outputFolder, file);
|
||||||
|
const stat = await fs.stat(sourcePath);
|
||||||
|
|
||||||
|
if (stat.isFile()) {
|
||||||
|
await fs.copy(sourcePath, destPath);
|
||||||
|
} else if (stat.isDirectory()) {
|
||||||
|
await fs.copy(sourcePath, destPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error(t('copyHarmonyBundleError', { error }));
|
console.error(t('copyHarmonyBundleError', { error }));
|
||||||
throw new Error(t('copyFileFailed', { error: error.message }));
|
throw new Error(t('copyFileFailed', { error: error.message }));
|
||||||
@@ -900,11 +921,9 @@ function diffArgsCheck(args: string[], options: any, diffFn: string) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const commands = {
|
export const bundleCommands = {
|
||||||
bundle: async ({ options }) => {
|
bundle: async ({ options }) => {
|
||||||
const platform = checkPlatform(
|
const platform = await getPlatform(options.platform);
|
||||||
options.platform || (await question(t('platformPrompt'))),
|
|
||||||
);
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
bundleName,
|
bundleName,
|
||||||
@@ -920,6 +939,13 @@ export const commands = {
|
|||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
metaInfo,
|
metaInfo,
|
||||||
|
packageId,
|
||||||
|
packageVersion,
|
||||||
|
minPackageVersion,
|
||||||
|
maxPackageVersion,
|
||||||
|
packageVersionRange,
|
||||||
|
rollout,
|
||||||
|
dryRun,
|
||||||
} = translateOptions({
|
} = translateOptions({
|
||||||
...options,
|
...options,
|
||||||
tempDir,
|
tempDir,
|
||||||
@@ -968,6 +994,13 @@ export const commands = {
|
|||||||
name,
|
name,
|
||||||
description,
|
description,
|
||||||
metaInfo,
|
metaInfo,
|
||||||
|
packageId,
|
||||||
|
packageVersion,
|
||||||
|
minPackageVersion,
|
||||||
|
maxPackageVersion,
|
||||||
|
packageVersionRange,
|
||||||
|
rollout,
|
||||||
|
dryRun: Boolean(dryRun),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
15
src/index.ts
15
src/index.ts
@@ -3,6 +3,11 @@
|
|||||||
import { loadSession } from './api';
|
import { loadSession } from './api';
|
||||||
import { printVersionCommand } from './utils';
|
import { printVersionCommand } from './utils';
|
||||||
import { t } from './utils/i18n';
|
import { t } from './utils/i18n';
|
||||||
|
import { bundleCommands } from './bundle';
|
||||||
|
import { versionCommands } from './versions';
|
||||||
|
import { userCommands } from './user';
|
||||||
|
import { appCommands } from './app';
|
||||||
|
import { packageCommands } from './package';
|
||||||
|
|
||||||
function printUsage() {
|
function printUsage() {
|
||||||
// const commandName = args[0];
|
// const commandName = args[0];
|
||||||
@@ -15,11 +20,11 @@ function printUsage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const commands = {
|
const commands = {
|
||||||
...require('./user').commands,
|
...userCommands,
|
||||||
...require('./bundle').commands,
|
...bundleCommands,
|
||||||
...require('./app').commands,
|
...appCommands,
|
||||||
...require('./package').commands,
|
...packageCommands,
|
||||||
...require('./versions').commands,
|
...versionCommands,
|
||||||
help: printUsage,
|
help: printUsage,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -73,9 +73,11 @@ This can reduce the risk of inconsistent dependencies and supply chain attacks.
|
|||||||
'Multiple lock files detected ({{- lockFiles}}), which may cause inconsistent dependencies and hot-updating issues.',
|
'Multiple lock files detected ({{- lockFiles}}), which may cause inconsistent dependencies and hot-updating issues.',
|
||||||
nativePackageId: 'Native Package ID',
|
nativePackageId: 'Native Package ID',
|
||||||
nativeVersion: 'Native Version',
|
nativeVersion: 'Native Version',
|
||||||
nativeVersionNotFound: 'No native version found >= {{version}}',
|
nativeVersionNotFoundGte: 'No native version found >= {{version}}',
|
||||||
nativeVersionNotFoundLess: 'No native version found <= {{version}}',
|
nativeVersionNotFoundLte: 'No native version found <= {{version}}',
|
||||||
nativeVersionNotFoundMatch: 'No matching native version found: {{version}}',
|
nativeVersionNotFoundMatch: 'No matching native version found: {{version}}',
|
||||||
|
nativePackageIdNotFound: 'No native package id found: {{id}}',
|
||||||
|
noPackagesFound: 'No packages found. (appId: {{appId}})',
|
||||||
offset: 'Offset {{offset}}',
|
offset: 'Offset {{offset}}',
|
||||||
operationComplete: 'Operation complete, bound to {{count}} native versions',
|
operationComplete: 'Operation complete, bound to {{count}} native versions',
|
||||||
operationSuccess: 'Operation successful',
|
operationSuccess: 'Operation successful',
|
||||||
@@ -99,7 +101,7 @@ This can reduce the risk of inconsistent dependencies and supply chain attacks.
|
|||||||
rnuVersionNotFound:
|
rnuVersionNotFound:
|
||||||
'react-native-update: Cannot get the version number. Please run the command in the project directory',
|
'react-native-update: Cannot get the version number. Please run the command in the project directory',
|
||||||
rolloutConfigSet:
|
rolloutConfigSet:
|
||||||
'Set {{rollout}}% rollout for version {{version}} on native version(s) {{versions}}',
|
'Set {{rollout}}% rollout for OTA update {{version}} on native version(s) {{versions}}',
|
||||||
rolloutRangeError: 'rollout must be an integer between 1-100',
|
rolloutRangeError: 'rollout must be an integer between 1-100',
|
||||||
runningHermesc: 'Running hermesc: {{- command}} {{- args}}',
|
runningHermesc: 'Running hermesc: {{- command}} {{- args}}',
|
||||||
sentryCliNotFound:
|
sentryCliNotFound:
|
||||||
@@ -120,6 +122,12 @@ This can reduce the risk of inconsistent dependencies and supply chain attacks.
|
|||||||
usageUploadApp: 'Usage: cresc uploadApp <app file>',
|
usageUploadApp: 'Usage: cresc uploadApp <app file>',
|
||||||
usageUploadIpa: 'Usage: cresc uploadIpa <ipa file>',
|
usageUploadIpa: 'Usage: cresc uploadIpa <ipa file>',
|
||||||
versionBind:
|
versionBind:
|
||||||
'Bound version {{version}} to native version {{nativeVersion}} (id: {{id}})',
|
'Bound hot update {{version}} to native version {{nativeVersion}} (id: {{id}})',
|
||||||
welcomeMessage: 'Welcome to Cresc hot update service, {{name}}.',
|
welcomeMessage: 'Welcome to Cresc hot update service, {{name}}.',
|
||||||
|
versionNameQuestion: 'Enter OTA update name:',
|
||||||
|
versionDescriptionQuestion: 'Enter OTA update description:',
|
||||||
|
versionMetaInfoQuestion: 'Enter custom meta info:',
|
||||||
|
updateNativePackageQuestion: 'Bind to native package now?(Y/N)',
|
||||||
|
unnamed: '(Unnamed)',
|
||||||
|
dryRun: 'Below is the dry-run result, no actual operation will be performed:',
|
||||||
};
|
};
|
||||||
|
@@ -69,9 +69,11 @@ export default {
|
|||||||
'检测到多种不同格式的锁文件({{- lockFiles}}),这可能导致依赖关系不一致而使热更异常。',
|
'检测到多种不同格式的锁文件({{- lockFiles}}),这可能导致依赖关系不一致而使热更异常。',
|
||||||
nativePackageId: '原生包 Id',
|
nativePackageId: '原生包 Id',
|
||||||
nativeVersion: '原生版本',
|
nativeVersion: '原生版本',
|
||||||
nativeVersionNotFound: '未查询到 >= {{version}} 的原生版本',
|
nativeVersionNotFoundGte: '未查询到 >= {{version}} 的原生版本',
|
||||||
nativeVersionNotFoundLess: '未查询到 <= {{version}} 的原生版本',
|
nativeVersionNotFoundLte: '未查询到 <= {{version}} 的原生版本',
|
||||||
nativeVersionNotFoundMatch: '未查询到匹配原生版本:{{version}}',
|
nativeVersionNotFoundMatch: '未查询到匹配原生版本:{{version}}',
|
||||||
|
nativePackageIdNotFound: '未查询到原生包 id: {{id}}',
|
||||||
|
noPackagesFound: '未查询到任何原生包(appId: {{appId}})',
|
||||||
offset: '偏移量 {{offset}}',
|
offset: '偏移量 {{offset}}',
|
||||||
operationComplete: '操作完成,共已绑定 {{count}} 个原生版本',
|
operationComplete: '操作完成,共已绑定 {{count}} 个原生版本',
|
||||||
operationSuccess: '操作成功',
|
operationSuccess: '操作成功',
|
||||||
@@ -94,7 +96,7 @@ export default {
|
|||||||
rnuVersionNotFound:
|
rnuVersionNotFound:
|
||||||
'react-native-update: 无法获取版本号。请在项目目录中运行命令',
|
'react-native-update: 无法获取版本号。请在项目目录中运行命令',
|
||||||
rolloutConfigSet:
|
rolloutConfigSet:
|
||||||
'已在原生版本 {{versions}} 上设置灰度发布 {{rollout}}% 热更版本 {{version}}',
|
'已在原生版本 {{versions}} 上设置灰度发布 {{rollout}}% 热更包 {{version}}',
|
||||||
rolloutRangeError: 'rollout 必须是 1-100 的整数',
|
rolloutRangeError: 'rollout 必须是 1-100 的整数',
|
||||||
runningHermesc: '运行 hermesc:{{- command}} {{- args}}',
|
runningHermesc: '运行 hermesc:{{- command}} {{- args}}',
|
||||||
sentryCliNotFound: '无法找到 Sentry CLI 工具,请确保已正确安装 @sentry/cli',
|
sentryCliNotFound: '无法找到 Sentry CLI 工具,请确保已正确安装 @sentry/cli',
|
||||||
@@ -113,6 +115,12 @@ export default {
|
|||||||
usageUploadApp: '使用方法: pushy uploadApp app后缀文件',
|
usageUploadApp: '使用方法: pushy uploadApp app后缀文件',
|
||||||
usageUploadIpa: '使用方法: pushy uploadIpa ipa后缀文件',
|
usageUploadIpa: '使用方法: pushy uploadIpa ipa后缀文件',
|
||||||
versionBind:
|
versionBind:
|
||||||
'已将热更版本 {{version}} 绑定到原生版本 {{nativeVersion}} (id: {{id}})',
|
'已将热更包 {{version}} 绑定到原生版本 {{nativeVersion}} (id: {{id}})',
|
||||||
welcomeMessage: '欢迎使用 pushy 热更新服务,{{name}}。',
|
welcomeMessage: '欢迎使用 pushy 热更新服务,{{name}}。',
|
||||||
|
versionNameQuestion: '输入版本名称:',
|
||||||
|
versionDescriptionQuestion: '输入版本描述:',
|
||||||
|
versionMetaInfoQuestion: '输入自定义的 meta info:',
|
||||||
|
updateNativePackageQuestion: '是否现在将此热更应用到原生包上?(Y/N)',
|
||||||
|
unnamed: '(未命名)',
|
||||||
|
dryRun: '以下是 dry-run 模拟运行结果,不会实际执行任何操作:',
|
||||||
};
|
};
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
import { get, post, uploadFile } from './api';
|
import { get, getAllPackages, post, uploadFile } from './api';
|
||||||
import { question, saveToLocal } from './utils';
|
import { question, saveToLocal } from './utils';
|
||||||
import { t } from './utils/i18n';
|
import { t } from './utils/i18n';
|
||||||
|
|
||||||
import { checkPlatform, getSelectedApp } from './app';
|
import { getPlatform, getSelectedApp } from './app';
|
||||||
|
|
||||||
import { getApkInfo, getIpaInfo, getAppInfo } from './utils';
|
import { getApkInfo, getIpaInfo, getAppInfo } from './utils';
|
||||||
import Table from 'tty-table';
|
import Table from 'tty-table';
|
||||||
@@ -11,14 +11,14 @@ import { getCommitInfo } from './utils/git';
|
|||||||
import type { Platform } from 'types';
|
import type { Platform } from 'types';
|
||||||
|
|
||||||
export async function listPackage(appId: string) {
|
export async function listPackage(appId: string) {
|
||||||
const { data } = await get(`/app/${appId}/package/list?limit=1000`);
|
const allPkgs = await getAllPackages(appId);
|
||||||
|
|
||||||
const header = [
|
const header = [
|
||||||
{ value: t('nativePackageId') },
|
{ value: t('nativePackageId') },
|
||||||
{ value: t('nativeVersion') },
|
{ value: t('nativeVersion') },
|
||||||
];
|
];
|
||||||
const rows = [];
|
const rows = [];
|
||||||
for (const pkg of data) {
|
for (const pkg of allPkgs) {
|
||||||
const { version } = pkg;
|
const { version } = pkg;
|
||||||
let versionInfo = '';
|
let versionInfo = '';
|
||||||
if (version) {
|
if (version) {
|
||||||
@@ -36,8 +36,8 @@ export async function listPackage(appId: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
console.log(Table(header, rows).render());
|
console.log(Table(header, rows).render());
|
||||||
console.log(t('totalPackages', { count: data.length }));
|
console.log(t('totalPackages', { count: allPkgs.length }));
|
||||||
return data;
|
return allPkgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function choosePackage(appId: string) {
|
export async function choosePackage(appId: string) {
|
||||||
@@ -52,7 +52,7 @@ export async function choosePackage(appId: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const commands = {
|
export const packageCommands = {
|
||||||
uploadIpa: async ({ args }: { args: string[] }) => {
|
uploadIpa: async ({ args }: { args: string[] }) => {
|
||||||
const fn = args[0];
|
const fn = args[0];
|
||||||
if (!fn || !fn.endsWith('.ipa')) {
|
if (!fn || !fn.endsWith('.ipa')) {
|
||||||
@@ -174,9 +174,7 @@ export const commands = {
|
|||||||
console.log(await getApkInfo(fn));
|
console.log(await getApkInfo(fn));
|
||||||
},
|
},
|
||||||
packages: async ({ options }: { options: { platform: Platform } }) => {
|
packages: async ({ options }: { options: { platform: Platform } }) => {
|
||||||
const platform = checkPlatform(
|
const platform = await getPlatform(options.platform);
|
||||||
options.platform || (await question(t('platformPrompt'))),
|
|
||||||
);
|
|
||||||
const { appId } = await getSelectedApp(platform);
|
const { appId } = await getSelectedApp(platform);
|
||||||
await listPackage(appId);
|
await listPackage(appId);
|
||||||
},
|
},
|
||||||
|
12
src/types.ts
12
src/types.ts
@@ -8,3 +8,15 @@ export interface Session {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type Platform = 'ios' | 'android' | 'harmony';
|
export type Platform = 'ios' | 'android' | 'harmony';
|
||||||
|
|
||||||
|
export interface Package {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Version {
|
||||||
|
id: string;
|
||||||
|
hash: string;
|
||||||
|
name: string;
|
||||||
|
packages?: Package[];
|
||||||
|
}
|
||||||
|
@@ -7,7 +7,7 @@ function md5(str: string) {
|
|||||||
return crypto.createHash('md5').update(str).digest('hex');
|
return crypto.createHash('md5').update(str).digest('hex');
|
||||||
}
|
}
|
||||||
|
|
||||||
export const commands = {
|
export const userCommands = {
|
||||||
login: async ({ args }: { args: string[] }) => {
|
login: async ({ args }: { args: string[] }) => {
|
||||||
const email = args[0] || (await question('email:'));
|
const email = args[0] || (await question('email:'));
|
||||||
const pwd = args[1] || (await question('password:', true));
|
const pwd = args[1] || (await question('password:', true));
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
const Unzip = require('isomorphic-unzip');
|
const Unzip = require('isomorphic-unzip');
|
||||||
const { isBrowser, decodeNullUnicode } = require('./utils');
|
const { isBrowser, decodeNullUnicode } = require('./utils');
|
||||||
import { enumZipEntries, readEntire } from '../../bundle';
|
import { enumZipEntries, readEntry } from '../../bundle';
|
||||||
|
|
||||||
class Zip {
|
class Zip {
|
||||||
constructor(file) {
|
constructor(file) {
|
||||||
@@ -53,7 +53,7 @@ class Zip {
|
|||||||
let originSource;
|
let originSource;
|
||||||
await enumZipEntries(this.file, (entry, zipFile) => {
|
await enumZipEntries(this.file, (entry, zipFile) => {
|
||||||
if (regex.test(entry.fileName)) {
|
if (regex.test(entry.fileName)) {
|
||||||
return readEntire(entry, zipFile).then((v) => (originSource = v));
|
return readEntry(entry, zipFile).then((v) => (originSource = v));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return originSource;
|
return originSource;
|
||||||
|
@@ -3,7 +3,7 @@ import os from 'os';
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import pkg from '../../package.json';
|
import pkg from '../../package.json';
|
||||||
import AppInfoParser from './app-info-parser';
|
import AppInfoParser from './app-info-parser';
|
||||||
import semverSatisfies from 'semver/functions/satisfies';
|
import { satisfies } from 'compare-versions';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import latestVersion from '../utils/latest-version';
|
import latestVersion from '../utils/latest-version';
|
||||||
import { checkPlugins } from './check-plugin';
|
import { checkPlugins } from './check-plugin';
|
||||||
@@ -189,24 +189,24 @@ export async function printVersionCommand() {
|
|||||||
: '';
|
: '';
|
||||||
console.log(`react-native-update: ${rnuVersion}${latestRnuVersion}`);
|
console.log(`react-native-update: ${rnuVersion}${latestRnuVersion}`);
|
||||||
if (IS_CRESC) {
|
if (IS_CRESC) {
|
||||||
if (semverSatisfies(rnuVersion, '<10.27.0')) {
|
if (satisfies(rnuVersion, '<10.27.0')) {
|
||||||
console.error(
|
console.error(
|
||||||
'Unsupported version, please update to the latest version: npm i react-native-update@latest',
|
'Unsupported version, please update to the latest version: npm i react-native-update@latest',
|
||||||
);
|
);
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (semverSatisfies(rnuVersion, '<8.5.2')) {
|
if (satisfies(rnuVersion, '<8.5.2')) {
|
||||||
console.warn(
|
console.warn(
|
||||||
`当前版本已不再支持,请至少升级到 v8 的最新小版本后重新打包(代码无需改动): npm i react-native-update@8 .
|
`当前版本已不再支持,请至少升级到 v8 的最新小版本后重新打包(代码无需改动): npm i react-native-update@8 .
|
||||||
如有使用安装 apk 的功能,请注意添加所需权限 https://pushy.reactnative.cn/docs/api#async-function-downloadandinstallapkurl`,
|
如有使用安装 apk 的功能,请注意添加所需权限 https://pushy.reactnative.cn/docs/api#async-function-downloadandinstallapkurl`,
|
||||||
);
|
);
|
||||||
} else if (semverSatisfies(rnuVersion, '9.0.0 - 9.2.1')) {
|
} else if (satisfies(rnuVersion, '9.0.0 - 9.2.1')) {
|
||||||
console.warn(
|
console.warn(
|
||||||
`当前版本已不再支持,请至少升级到 v9 的最新小版本后重新打包(代码无需改动,可直接热更): npm i react-native-update@9 .
|
`当前版本已不再支持,请至少升级到 v9 的最新小版本后重新打包(代码无需改动,可直接热更): npm i react-native-update@9 .
|
||||||
如有使用安装 apk 的功能,请注意添加所需权限 https://pushy.reactnative.cn/docs/api#async-function-downloadandinstallapkurl`,
|
如有使用安装 apk 的功能,请注意添加所需权限 https://pushy.reactnative.cn/docs/api#async-function-downloadandinstallapkurl`,
|
||||||
);
|
);
|
||||||
} else if (semverSatisfies(rnuVersion, '10.0.0 - 10.17.0')) {
|
} else if (satisfies(rnuVersion, '10.0.0 - 10.17.0')) {
|
||||||
console.warn(
|
console.warn(
|
||||||
'当前版本已不再支持,请升级到 v10 的最新小版本(代码无需改动,可直接热更): npm i react-native-update@10',
|
'当前版本已不再支持,请升级到 v10 的最新小版本(代码无需改动,可直接热更): npm i react-native-update@10',
|
||||||
);
|
);
|
||||||
|
336
src/versions.ts
336
src/versions.ts
@@ -1,27 +1,17 @@
|
|||||||
import { get, post, put, uploadFile } from './api';
|
import { get, getAllPackages, post, put, uploadFile } from './api';
|
||||||
import { question, saveToLocal } from './utils';
|
import { question, saveToLocal } from './utils';
|
||||||
import { t } from './utils/i18n';
|
import { t } from './utils/i18n';
|
||||||
|
|
||||||
import { checkPlatform, getSelectedApp } from './app';
|
import { getPlatform, getSelectedApp } from './app';
|
||||||
import { choosePackage } from './package';
|
import { choosePackage } from './package';
|
||||||
import { compare } from 'compare-versions';
|
|
||||||
import { depVersions } from './utils/dep-versions';
|
import { depVersions } from './utils/dep-versions';
|
||||||
import { getCommitInfo } from './utils/git';
|
import { getCommitInfo } from './utils/git';
|
||||||
import type { Platform } from 'types';
|
import type { Package, Platform, Version } from 'types';
|
||||||
|
import { satisfies } from 'compare-versions';
|
||||||
|
import chalk from 'chalk';
|
||||||
|
|
||||||
interface Package {
|
interface VersionCommandOptions {
|
||||||
id: string;
|
appId?: string;
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Version {
|
|
||||||
id: string;
|
|
||||||
hash: string;
|
|
||||||
name: string;
|
|
||||||
packages?: Package[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CommandOptions {
|
|
||||||
name?: string;
|
name?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
metaInfo?: string;
|
metaInfo?: string;
|
||||||
@@ -31,7 +21,9 @@ interface CommandOptions {
|
|||||||
packageVersion?: string;
|
packageVersion?: string;
|
||||||
minPackageVersion?: string;
|
minPackageVersion?: string;
|
||||||
maxPackageVersion?: string;
|
maxPackageVersion?: string;
|
||||||
|
packageVersionRange?: string;
|
||||||
rollout?: string;
|
rollout?: string;
|
||||||
|
dryRun?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function showVersion(appId: string, offset: number) {
|
async function showVersion(appId: string, offset: number) {
|
||||||
@@ -113,13 +105,65 @@ async function chooseVersion(appId: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const commands = {
|
export const bindVersionToPackages = async ({
|
||||||
|
appId,
|
||||||
|
versionId,
|
||||||
|
pkgs,
|
||||||
|
rollout,
|
||||||
|
dryRun,
|
||||||
|
}: {
|
||||||
|
appId: string;
|
||||||
|
versionId: string;
|
||||||
|
pkgs: Package[];
|
||||||
|
rollout?: number;
|
||||||
|
dryRun?: boolean;
|
||||||
|
}) => {
|
||||||
|
if (dryRun) {
|
||||||
|
console.log(chalk.yellow(t('dryRun')));
|
||||||
|
}
|
||||||
|
if (rollout !== undefined) {
|
||||||
|
const rolloutConfig: Record<string, number> = {};
|
||||||
|
for (const pkg of pkgs) {
|
||||||
|
rolloutConfig[pkg.name] = rollout;
|
||||||
|
}
|
||||||
|
if (!dryRun) {
|
||||||
|
await put(`/app/${appId}/version/${versionId}`, {
|
||||||
|
config: {
|
||||||
|
rollout: rolloutConfig,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
console.log(
|
||||||
|
`${t('rolloutConfigSet', {
|
||||||
|
versions: pkgs.map((pkg: Package) => pkg.name).join(', '),
|
||||||
|
rollout: rollout,
|
||||||
|
})}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
for (const pkg of pkgs) {
|
||||||
|
if (!dryRun) {
|
||||||
|
await put(`/app/${appId}/package/${pkg.id}`, {
|
||||||
|
versionId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
console.log(
|
||||||
|
`${t('versionBind', {
|
||||||
|
version: versionId,
|
||||||
|
nativeVersion: pkg.name,
|
||||||
|
id: pkg.id,
|
||||||
|
})}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
console.log(t('operationComplete', { count: pkgs.length }));
|
||||||
|
};
|
||||||
|
|
||||||
|
export const versionCommands = {
|
||||||
publish: async function ({
|
publish: async function ({
|
||||||
args,
|
args,
|
||||||
options,
|
options,
|
||||||
}: {
|
}: {
|
||||||
args: string[];
|
args: string[];
|
||||||
options: CommandOptions;
|
options: VersionCommandOptions;
|
||||||
}) {
|
}) {
|
||||||
const fn = args[0];
|
const fn = args[0];
|
||||||
const { name, description, metaInfo } = options;
|
const { name, description, metaInfo } = options;
|
||||||
@@ -128,21 +172,19 @@ export const commands = {
|
|||||||
throw new Error(t('publishUsage'));
|
throw new Error(t('publishUsage'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const platform = checkPlatform(
|
const platform = await getPlatform(options.platform);
|
||||||
options.platform ||
|
|
||||||
((await question('平台(ios/android/harmony):')) as Platform),
|
|
||||||
);
|
|
||||||
const { appId } = await getSelectedApp(platform);
|
const { appId } = await getSelectedApp(platform);
|
||||||
|
|
||||||
const { hash } = await uploadFile(fn);
|
const { hash } = await uploadFile(fn);
|
||||||
|
|
||||||
const versionName =
|
const versionName =
|
||||||
name || (await question('输入版本名称: ')) || '(未命名)';
|
name || (await question(t('versionNameQuestion'))) || t('unnamed');
|
||||||
const { id } = await post(`/app/${appId}/version/create`, {
|
const { id } = await post(`/app/${appId}/version/create`, {
|
||||||
name: versionName,
|
name: versionName,
|
||||||
hash,
|
hash,
|
||||||
description: description || (await question('输入版本描述:')),
|
description:
|
||||||
metaInfo: metaInfo || (await question('输入自定义的 meta info:')),
|
description || (await question(t('versionDescriptionQuestion'))),
|
||||||
|
metaInfo: metaInfo || (await question(t('versionMetaInfoQuestion'))),
|
||||||
deps: depVersions,
|
deps: depVersions,
|
||||||
commit: await getCommitInfo(),
|
commit: await getCommitInfo(),
|
||||||
});
|
});
|
||||||
@@ -150,41 +192,62 @@ export const commands = {
|
|||||||
saveToLocal(fn, `${appId}/ppk/${id}.ppk`);
|
saveToLocal(fn, `${appId}/ppk/${id}.ppk`);
|
||||||
console.log(t('packageUploadSuccess', { id }));
|
console.log(t('packageUploadSuccess', { id }));
|
||||||
|
|
||||||
const v = await question('是否现在将此热更应用到原生包上?(Y/N)');
|
const {
|
||||||
if (v.toLowerCase() === 'y') {
|
packageId,
|
||||||
await this.update({ args: [], options: { versionId: id, platform } });
|
packageVersion,
|
||||||
|
packageVersionRange,
|
||||||
|
minPackageVersion,
|
||||||
|
maxPackageVersion,
|
||||||
|
rollout,
|
||||||
|
dryRun,
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
if (
|
||||||
|
packageId ||
|
||||||
|
packageVersion ||
|
||||||
|
packageVersionRange ||
|
||||||
|
minPackageVersion ||
|
||||||
|
maxPackageVersion
|
||||||
|
) {
|
||||||
|
await this.update({
|
||||||
|
options: {
|
||||||
|
versionId: id,
|
||||||
|
platform,
|
||||||
|
packageId,
|
||||||
|
packageVersion,
|
||||||
|
packageVersionRange,
|
||||||
|
minPackageVersion,
|
||||||
|
maxPackageVersion,
|
||||||
|
rollout,
|
||||||
|
dryRun,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const q = await question(t('updateNativePackageQuestion'));
|
||||||
|
if (q.toLowerCase() === 'y') {
|
||||||
|
await this.update({ options: { versionId: id, platform } });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return versionName;
|
return versionName;
|
||||||
},
|
},
|
||||||
versions: async ({ options }: { options: CommandOptions }) => {
|
versions: async ({ options }: { options: VersionCommandOptions }) => {
|
||||||
const platform = checkPlatform(
|
const platform = await getPlatform(options.platform);
|
||||||
options.platform ||
|
|
||||||
((await question('平台(ios/android/harmony):')) as Platform),
|
|
||||||
);
|
|
||||||
const { appId } = await getSelectedApp(platform);
|
const { appId } = await getSelectedApp(platform);
|
||||||
await listVersions(appId);
|
await listVersions(appId);
|
||||||
},
|
},
|
||||||
update: async ({
|
update: async ({ options }: { options: VersionCommandOptions }) => {
|
||||||
args,
|
const platform = await getPlatform(options.platform);
|
||||||
options,
|
const appId = options.appId || (await getSelectedApp(platform)).appId;
|
||||||
}: {
|
|
||||||
args: string[];
|
|
||||||
options: CommandOptions;
|
|
||||||
}) => {
|
|
||||||
const platform = checkPlatform(
|
|
||||||
options.platform ||
|
|
||||||
((await question('平台(ios/android/harmony):')) as Platform),
|
|
||||||
);
|
|
||||||
const { appId } = await getSelectedApp(platform);
|
|
||||||
let versionId = options.versionId || (await chooseVersion(appId)).id;
|
let versionId = options.versionId || (await chooseVersion(appId)).id;
|
||||||
if (versionId === 'null') {
|
if (versionId === 'null') {
|
||||||
versionId = undefined;
|
versionId = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
let pkgId: string | undefined;
|
let pkgId = options.packageId;
|
||||||
let pkgVersion = options.packageVersion;
|
let pkgVersion = options.packageVersion;
|
||||||
let minPkgVersion = options.minPackageVersion;
|
let minPkgVersion = options.minPackageVersion;
|
||||||
let maxPkgVersion = options.maxPackageVersion;
|
let maxPkgVersion = options.maxPackageVersion;
|
||||||
|
let packageVersionRange = options.packageVersionRange;
|
||||||
let rollout: number | undefined = undefined;
|
let rollout: number | undefined = undefined;
|
||||||
|
|
||||||
if (options.rollout !== undefined) {
|
if (options.rollout !== undefined) {
|
||||||
@@ -198,159 +261,86 @@ export const commands = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (minPkgVersion) {
|
const allPkgs = await getAllPackages(appId);
|
||||||
minPkgVersion = String(minPkgVersion).trim();
|
|
||||||
const { data } = await get(`/app/${appId}/package/list?limit=1000`);
|
if (!allPkgs) {
|
||||||
const pkgs = data.filter((pkg: Package) =>
|
throw new Error(t('noPackagesFound', { appId }));
|
||||||
compare(pkg.name, minPkgVersion!, '>='),
|
|
||||||
);
|
|
||||||
if (pkgs.length === 0) {
|
|
||||||
throw new Error(t('nativeVersionNotFound', { version: minPkgVersion }));
|
|
||||||
}
|
|
||||||
if (rollout !== undefined) {
|
|
||||||
const rolloutConfig: Record<string, number> = {};
|
|
||||||
for (const pkg of pkgs) {
|
|
||||||
rolloutConfig[pkg.name] = rollout;
|
|
||||||
}
|
|
||||||
await put(`/app/${appId}/version/${versionId}`, {
|
|
||||||
config: {
|
|
||||||
rollout: rolloutConfig,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
console.log(
|
|
||||||
`${t('rolloutConfigSet', {
|
|
||||||
versions: pkgs.map((pkg: Package) => pkg.name).join(', '),
|
|
||||||
rollout: rollout,
|
|
||||||
})}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
for (const pkg of pkgs) {
|
|
||||||
await put(`/app/${appId}/package/${pkg.id}`, {
|
|
||||||
versionId,
|
|
||||||
});
|
|
||||||
console.log(
|
|
||||||
`${t('versionBind', {
|
|
||||||
version: versionId,
|
|
||||||
nativeVersion: pkg.name,
|
|
||||||
id: pkg.id,
|
|
||||||
})}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
console.log(t('operationComplete', { count: pkgs.length }));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (maxPkgVersion) {
|
|
||||||
maxPkgVersion = String(maxPkgVersion).trim();
|
|
||||||
const { data } = await get(`/app/${appId}/package/list?limit=1000`);
|
|
||||||
const pkgs = data.filter((pkg: Package) =>
|
|
||||||
compare(pkg.name, maxPkgVersion!, '<='),
|
|
||||||
);
|
|
||||||
if (pkgs.length === 0) {
|
|
||||||
throw new Error(
|
|
||||||
t('nativeVersionNotFoundLess', { version: maxPkgVersion }),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (rollout !== undefined) {
|
|
||||||
const rolloutConfig: Record<string, number> = {};
|
|
||||||
for (const pkg of pkgs) {
|
|
||||||
rolloutConfig[pkg.name] = rollout;
|
|
||||||
}
|
|
||||||
await put(`/app/${appId}/version/${versionId}`, {
|
|
||||||
config: {
|
|
||||||
rollout: rolloutConfig,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
console.log(
|
|
||||||
`${t('rolloutConfigSet', {
|
|
||||||
versions: pkgs.map((pkg: Package) => pkg.name).join(', '),
|
|
||||||
rollout: rollout,
|
|
||||||
})}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
for (const pkg of pkgs) {
|
|
||||||
await put(`/app/${appId}/package/${pkg.id}`, {
|
|
||||||
versionId,
|
|
||||||
});
|
|
||||||
console.log(
|
|
||||||
`${t('versionBind', {
|
|
||||||
version: versionId,
|
|
||||||
nativeVersion: pkg.name,
|
|
||||||
id: pkg.id,
|
|
||||||
})}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
console.log(t('operationComplete', { count: pkgs.length }));
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const { data } = await get(`/app/${appId}/package/list?limit=1000`);
|
let pkgsToBind: Package[] = [];
|
||||||
if (pkgVersion) {
|
|
||||||
|
if (minPkgVersion) {
|
||||||
|
minPkgVersion = String(minPkgVersion).trim();
|
||||||
|
pkgsToBind = allPkgs.filter((pkg: Package) =>
|
||||||
|
satisfies(pkg.name, `>=${minPkgVersion}`),
|
||||||
|
);
|
||||||
|
if (pkgsToBind.length === 0) {
|
||||||
|
throw new Error(
|
||||||
|
t('nativeVersionNotFoundGte', { version: minPkgVersion }),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (maxPkgVersion) {
|
||||||
|
maxPkgVersion = String(maxPkgVersion).trim();
|
||||||
|
pkgsToBind = allPkgs.filter((pkg: Package) =>
|
||||||
|
satisfies(pkg.name, `<=${maxPkgVersion}`),
|
||||||
|
);
|
||||||
|
if (pkgsToBind.length === 0) {
|
||||||
|
throw new Error(
|
||||||
|
t('nativeVersionNotFoundLte', { version: maxPkgVersion }),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else if (pkgVersion) {
|
||||||
pkgVersion = pkgVersion.trim();
|
pkgVersion = pkgVersion.trim();
|
||||||
const pkg = data.find((pkg: Package) => pkg.name === pkgVersion);
|
const pkg = allPkgs.find((pkg: Package) => pkg.name === pkgVersion);
|
||||||
if (pkg) {
|
if (pkg) {
|
||||||
pkgId = pkg.id;
|
pkgsToBind = [pkg];
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
t('nativeVersionNotFoundMatch', { version: pkgVersion }),
|
t('nativeVersionNotFoundMatch', { version: pkgVersion }),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
} else if (packageVersionRange) {
|
||||||
|
packageVersionRange = packageVersionRange.trim();
|
||||||
|
pkgsToBind = allPkgs.filter((pkg: Package) =>
|
||||||
|
satisfies(pkg.name, packageVersionRange!),
|
||||||
|
);
|
||||||
|
if (pkgsToBind.length === 0) {
|
||||||
|
throw new Error(
|
||||||
|
t('nativeVersionNotFoundMatch', { version: packageVersionRange }),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
if (!pkgId) {
|
if (!pkgId) {
|
||||||
pkgId = options.packageId || (await choosePackage(appId)).id;
|
pkgId = (await choosePackage(appId)).id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pkgId) {
|
if (!pkgId) {
|
||||||
throw new Error(t('packageIdRequired'));
|
throw new Error(t('packageIdRequired'));
|
||||||
}
|
}
|
||||||
|
const pkg = allPkgs.find(
|
||||||
if (!pkgVersion) {
|
(pkg: Package) => String(pkg.id) === String(pkgId),
|
||||||
const pkg = data.find((pkg: Package) => String(pkg.id) === String(pkgId));
|
);
|
||||||
if (pkg) {
|
if (pkg) {
|
||||||
pkgVersion = pkg.name;
|
pkgsToBind = [pkg];
|
||||||
|
} else {
|
||||||
|
throw new Error(t('nativePackageIdNotFound', { id: pkgId }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rollout !== undefined && pkgVersion) {
|
await bindVersionToPackages({
|
||||||
await put(`/app/${appId}/version/${versionId}`, {
|
appId,
|
||||||
config: {
|
|
||||||
rollout: {
|
|
||||||
[pkgVersion]: rollout,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
console.log(
|
|
||||||
`${t('rolloutConfigSet', {
|
|
||||||
versions: pkgVersion,
|
|
||||||
rollout: rollout,
|
|
||||||
})}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (versionId !== undefined) {
|
|
||||||
await put(`/app/${appId}/package/${pkgId}`, {
|
|
||||||
versionId,
|
versionId,
|
||||||
|
pkgs: pkgsToBind,
|
||||||
|
rollout,
|
||||||
|
dryRun: options.dryRun,
|
||||||
});
|
});
|
||||||
console.log(
|
|
||||||
`${t('versionBind', {
|
|
||||||
version: versionId,
|
|
||||||
nativeVersion: pkgVersion,
|
|
||||||
id: pkgId,
|
|
||||||
})}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
console.log(t('operationSuccess'));
|
|
||||||
},
|
},
|
||||||
updateVersionInfo: async ({
|
updateVersionInfo: async ({
|
||||||
args,
|
|
||||||
options,
|
options,
|
||||||
}: {
|
}: {
|
||||||
args: string[];
|
options: VersionCommandOptions;
|
||||||
options: CommandOptions;
|
|
||||||
}) => {
|
}) => {
|
||||||
const platform = checkPlatform(
|
const platform = await getPlatform(options.platform);
|
||||||
options.platform ||
|
|
||||||
((await question('平台(ios/android/harmony):')) as Platform),
|
|
||||||
);
|
|
||||||
const { appId } = await getSelectedApp(platform);
|
const { appId } = await getSelectedApp(platform);
|
||||||
const versionId = options.versionId || (await chooseVersion(appId)).id;
|
const versionId = options.versionId || (await chooseVersion(appId)).id;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user