mirror of
https://gitcode.com/github-mirrors/react-native-update-cli.git
synced 2025-09-17 18:06:10 +08:00
Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3f1b43e38e | ||
![]() |
328b1f5447 |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-native-update-cli",
|
||||
"version": "1.42.1",
|
||||
"version": "1.42.2",
|
||||
"description": "Command tools for javaScript updater with `pushy` service for react native apps.",
|
||||
"main": "index.js",
|
||||
"bin": {
|
||||
|
22
src/api.ts
22
src/api.ts
@@ -6,19 +6,20 @@ import ProgressBar from 'progress';
|
||||
import packageJson from '../package.json';
|
||||
import tcpp from 'tcp-ping';
|
||||
import filesizeParser from 'filesize-parser';
|
||||
import { pricingPageUrl, credentialFile, IS_CRESC } from './utils/constants';
|
||||
import {
|
||||
pricingPageUrl,
|
||||
credentialFile,
|
||||
defaultEndpoint,
|
||||
} from './utils/constants';
|
||||
import type { Session } from 'types';
|
||||
import FormData from 'form-data';
|
||||
import { t } from './utils/i18n';
|
||||
|
||||
const tcpPing = util.promisify(tcpp.ping);
|
||||
|
||||
let session: Session | undefined;
|
||||
let savedSession: Session | undefined;
|
||||
|
||||
const defaultEndpoint = IS_CRESC
|
||||
? 'https://api.cresc.dev'
|
||||
: 'https://update.reactnative.cn/api';
|
||||
|
||||
const host =
|
||||
process.env.PUSHY_REGISTRY || process.env.RNU_API || defaultEndpoint;
|
||||
|
||||
@@ -73,7 +74,7 @@ async function query(url: string, options: fetch.RequestInit) {
|
||||
if (resp.status !== 200) {
|
||||
const message = json?.message || resp.statusText;
|
||||
if (resp.status === 401) {
|
||||
throw new Error('登录信息已过期,请使用 pushy login 命令重新登录');
|
||||
throw new Error(t('loginExpired'));
|
||||
}
|
||||
throw new Error(message);
|
||||
}
|
||||
@@ -133,10 +134,13 @@ export async function uploadFile(fn: string, key?: string) {
|
||||
|
||||
const fileSize = fs.statSync(fn).size;
|
||||
if (maxSize && fileSize > filesizeParser(maxSize)) {
|
||||
const readableFileSize = `${(fileSize / 1048576).toFixed(1)}m`;
|
||||
throw new Error(
|
||||
`此文件大小 ${(fileSize / 1048576).toFixed(
|
||||
1,
|
||||
)}m , 超出当前额度 ${maxSize} 。您可以考虑升级付费业务以提升此额度。详情请访问: ${pricingPageUrl}`,
|
||||
t('fileSizeExceeded', {
|
||||
fileSize: readableFileSize,
|
||||
maxSize,
|
||||
pricingPageUrl,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
|
52
src/app.ts
52
src/app.ts
@@ -4,16 +4,14 @@ import Table from 'tty-table';
|
||||
|
||||
import { post, get, doDelete } from './api';
|
||||
import type { Platform } from './types';
|
||||
import { t } from './utils/i18n';
|
||||
|
||||
const validPlatforms = ['ios', 'android', 'harmony'];
|
||||
|
||||
const validPlatforms = {
|
||||
ios: 1,
|
||||
android: 1,
|
||||
harmony: 1,
|
||||
};
|
||||
|
||||
export function checkPlatform(platform: Platform) {
|
||||
if (!validPlatforms[platform]) {
|
||||
throw new Error(`无法识别的平台 '${platform}'`);
|
||||
if (!validPlatforms.includes(platform)) {
|
||||
throw new Error(t('unsupportedPlatform', { platform }));
|
||||
}
|
||||
return platform;
|
||||
}
|
||||
@@ -22,27 +20,23 @@ export function getSelectedApp(platform: Platform) {
|
||||
checkPlatform(platform);
|
||||
|
||||
if (!fs.existsSync('update.json')) {
|
||||
throw new Error(
|
||||
`App not selected. run 'pushy selectApp --platform ${platform}' first!`,
|
||||
);
|
||||
throw new Error(t('appNotSelected', { platform }));
|
||||
}
|
||||
const updateInfo = JSON.parse(fs.readFileSync('update.json', 'utf8'));
|
||||
if (!updateInfo[platform]) {
|
||||
throw new Error(
|
||||
`App not selected. run 'pushy selectApp --platform ${platform}' first!`,
|
||||
);
|
||||
throw new Error(t('appNotSelected', { platform }));
|
||||
}
|
||||
return updateInfo[platform];
|
||||
}
|
||||
|
||||
export async function listApp(platform: Platform) {
|
||||
export async function listApp(platform: Platform | '' = '') {
|
||||
const { data } = await get('/app/list');
|
||||
const list = platform ? data.filter((v) => v.platform === platform) : data;
|
||||
|
||||
const header = [
|
||||
{ value: '应用 id' },
|
||||
{ value: '应用名称' },
|
||||
{ value: '平台' },
|
||||
{ value: t('appId') },
|
||||
{ value: t('appName') },
|
||||
{ value: t('platform') },
|
||||
];
|
||||
const rows = [];
|
||||
for (const app of list) {
|
||||
@@ -51,11 +45,7 @@ export async function listApp(platform: Platform) {
|
||||
|
||||
console.log(Table(header, rows).render());
|
||||
|
||||
if (platform) {
|
||||
console.log(`\共 ${list.length} ${platform} 个应用`);
|
||||
} else {
|
||||
console.log(`\共 ${list.length} 个应用`);
|
||||
}
|
||||
console.log(`\n${t('totalApps', { count: list.length, platform })}`);
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -63,7 +53,7 @@ export async function chooseApp(platform: Platform) {
|
||||
const list = await listApp(platform);
|
||||
|
||||
while (true) {
|
||||
const id = await question('输入应用 id:');
|
||||
const id = await question(t('enterAppIdQuestion'));
|
||||
const app = list.find((v) => v.id === Number(id));
|
||||
if (app) {
|
||||
return app;
|
||||
@@ -77,13 +67,13 @@ export const commands = {
|
||||
}: {
|
||||
options: { name: string; downloadUrl: string; platform: Platform };
|
||||
}) {
|
||||
const name = options.name || (await question('应用名称:'));
|
||||
const name = options.name || (await question(t('appNameQuestion')));
|
||||
const { downloadUrl } = options;
|
||||
const platform = checkPlatform(
|
||||
options.platform || (await question('平台(ios/android/harmony):')),
|
||||
options.platform || (await question(t('platformQuestion'))),
|
||||
);
|
||||
const { id } = await post('/app/create', { name, platform, downloadUrl });
|
||||
console.log(`已成功创建应用(id: ${id})`);
|
||||
console.log(t('createAppSuccess', { id }));
|
||||
await this.selectApp({
|
||||
args: [id],
|
||||
options: { platform },
|
||||
@@ -93,10 +83,10 @@ export const commands = {
|
||||
const { platform } = options;
|
||||
const id = args[0] || chooseApp(platform);
|
||||
if (!id) {
|
||||
console.log('已取消');
|
||||
console.log(t('cancelled'));
|
||||
}
|
||||
await doDelete(`/app/${id}`);
|
||||
console.log('操作成功');
|
||||
console.log(t('operationSuccess'));
|
||||
},
|
||||
apps: async ({ options }: { options: { platform: Platform } }) => {
|
||||
const { platform } = options;
|
||||
@@ -104,7 +94,7 @@ export const commands = {
|
||||
},
|
||||
selectApp: async ({ args, options }: { args: string[]; options: { platform: Platform } }) => {
|
||||
const platform = checkPlatform(
|
||||
options.platform || (await question('平台(ios/android/harmony):')),
|
||||
options.platform || (await question(t('platformQuestion'))),
|
||||
);
|
||||
const id = args[0]
|
||||
? Number.parseInt(args[0])
|
||||
@@ -115,9 +105,7 @@ export const commands = {
|
||||
try {
|
||||
updateInfo = JSON.parse(fs.readFileSync('update.json', 'utf8'));
|
||||
} catch (e) {
|
||||
console.error(
|
||||
'Failed to parse file `update.json`. Try to remove it manually.',
|
||||
);
|
||||
console.error(t('failedToParseUpdateJson'));
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
@@ -14,4 +14,29 @@ Best practices for lock files:
|
||||
3. Pay attention to changes in the lock file during code review.
|
||||
This can reduce the risk of inconsistent dependencies and supply chain attacks.
|
||||
`,
|
||||
loginExpired:
|
||||
'Login information has expired. Please use `cresc login` command to re-login',
|
||||
fileSizeExceeded:
|
||||
'This file size is {{fileSize}} , exceeding the current quota {{maxSize}} . You may consider upgrading to a higher plan to increase this quota. Details can be found at: {{pricingPageUrl}}',
|
||||
bundleNotFound:
|
||||
'Bundle file not found. Please ensure that this {{packageType}} is a release version and the bundle file name is the default `{{entryFile}}`',
|
||||
buildTimeNotFound:
|
||||
'Cannot get the build timestamp of this package. Please update `react-native-update` to the latest version and re-package and upload.',
|
||||
latestVersionTag: '(latest: {{version}})',
|
||||
rnuVersionNotFound:
|
||||
'react-native-update: Cannot get the version number. Please run the command in the project directory',
|
||||
unsupportedPlatform: 'Unsupported platform `{{platform}}`',
|
||||
appId: 'App ID',
|
||||
appName: 'App Name',
|
||||
platform: 'Platform',
|
||||
totalApps: 'Total {{count}} apps',
|
||||
appNotSelected:
|
||||
'App not selected. run `cresc selectApp --platform {{platform}}` first!',
|
||||
enterAppIdQuestion: 'Enter AppId:',
|
||||
appNameQuestion: 'App Name:',
|
||||
platformQuestion: 'Platform(ios/android/harmony):',
|
||||
createAppSuccess: 'App created successfully (id: {{id}})',
|
||||
cancelled: 'Cancelled',
|
||||
operationSuccess: 'Operation successful',
|
||||
failedToParseUpdateJson: 'Failed to parse file `update.json`. Try to remove it manually.',
|
||||
};
|
||||
|
@@ -13,4 +13,28 @@ export default {
|
||||
`,
|
||||
multipleLocksFound:
|
||||
'检测到多种不同格式的锁文件({lockFiles}),这可能导致依赖关系不一致而使热更异常。',
|
||||
loginExpired: '登录信息已过期,请使用 `pushy login` 命令重新登录',
|
||||
fileSizeExceeded:
|
||||
'此文件大小 {{fileSize}} , 超出当前额度 {{maxSize}} 。您可以考虑升级付费业务以提升此额度。详情请访问: {{pricingPageUrl}}',
|
||||
bundleNotFound:
|
||||
'找不到 bundle 文件。请确保此 {{packageType}} 为 release 版本,且 bundle 文件名为默认的 `{{entryFile}}`',
|
||||
buildTimeNotFound:
|
||||
'无法获取此包的编译时间戳。请更新 `react-native-update` 到最新版本后重新打包上传。',
|
||||
latestVersionTag: '(最新:{{version}})',
|
||||
rnuVersionNotFound:
|
||||
'react-native-update: 无法获取版本号。请在项目目录中运行命令',
|
||||
unsupportedPlatform: '无法识别的平台 `{{platform}}`',
|
||||
appId: '应用 id',
|
||||
appName: '应用名称',
|
||||
platform: '平台',
|
||||
totalApps: '共 {{count}} 个{{platform}}应用',
|
||||
appNotSelected:
|
||||
'尚未选择应用。请先运行 `pushy selectApp --platform {{platform}}` 来选择应用',
|
||||
enterAppIdQuestion: '输入应用 id:',
|
||||
appNameQuestion: '应用名称:',
|
||||
platformQuestion: '平台(ios/android/harmony):',
|
||||
createAppSuccess: '已成功创建应用(id: {{id}})',
|
||||
cancelled: '已取消',
|
||||
operationSuccess: '操作成功',
|
||||
failedToParseUpdateJson: '无法解析文件 `update.json`。请手动删除它。',
|
||||
};
|
||||
|
@@ -4,17 +4,19 @@ const AppParser = require('./app');
|
||||
const supportFileTypes = ['ipa', 'apk', 'app'];
|
||||
|
||||
class AppInfoParser {
|
||||
file: string | File;
|
||||
parser: any;
|
||||
/**
|
||||
* parser for parsing .ipa or .apk file
|
||||
* @param {String | File | Blob} file // file's path in Node, instance of File or Blob in Browser
|
||||
* @param {String | File} file // file's path in Node, instance of File in Browser
|
||||
*/
|
||||
constructor(file) {
|
||||
constructor(file: string | File) {
|
||||
if (!file) {
|
||||
throw new Error(
|
||||
"Param miss: file(file's path in Node, instance of File or Blob in browser).",
|
||||
"Param miss: file(file's path in Node, instance of File in browser).",
|
||||
);
|
||||
}
|
||||
const splits = (file.name || file).split('.');
|
||||
const splits = (typeof file === 'string' ? file : file.name).split('.');
|
||||
const fileType = splits[splits.length - 1].toLowerCase();
|
||||
if (!supportFileTypes.includes(fileType)) {
|
||||
throw new Error(
|
||||
@@ -40,4 +42,4 @@ class AppInfoParser {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = AppInfoParser;
|
||||
export default AppInfoParser;
|
@@ -17,10 +17,10 @@ export async function checkPlugins(): Promise<BundleParams> {
|
||||
const isEnabled = await plugin.detect();
|
||||
if (isEnabled && plugin.bundleParams) {
|
||||
Object.assign(params, plugin.bundleParams);
|
||||
console.log(`检测到 ${plugin.name} 插件,应用相应打包配置`);
|
||||
console.log(`detected ${plugin.name} plugin`);
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn(`检测 ${plugin.name} 插件时出错:`, err);
|
||||
console.warn(`error while detecting ${plugin.name} plugin:`, err);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,8 +1,6 @@
|
||||
import path from 'node:path';
|
||||
|
||||
const scriptName: 'cresc' | 'pushy' = path.basename(process.argv[1]) as
|
||||
| 'cresc'
|
||||
| 'pushy';
|
||||
const scriptName = path.basename(process.argv[1]) as 'cresc' | 'pushy';
|
||||
export const IS_CRESC = scriptName === 'cresc';
|
||||
|
||||
export const credentialFile = IS_CRESC ? '.cresc.token' : '.update';
|
||||
@@ -11,3 +9,7 @@ export const tempDir = IS_CRESC ? '.cresc.temp' : '.pushy';
|
||||
export const pricingPageUrl = IS_CRESC
|
||||
? 'https://cresc.dev/pricing'
|
||||
: 'https://pushy.reactnative.cn/pricing.html';
|
||||
|
||||
export const defaultEndpoint = IS_CRESC
|
||||
? 'https://api.cresc.dev'
|
||||
: 'https://update.reactnative.cn/api';
|
||||
|
@@ -2,12 +2,18 @@ import i18next from 'i18next';
|
||||
import en from '../locales/en';
|
||||
import zh from '../locales/zh';
|
||||
import { IS_CRESC } from './constants';
|
||||
|
||||
i18next.init({
|
||||
lng: IS_CRESC ? 'en' : 'zh',
|
||||
// debug: process.env.NODE_ENV !== 'production',
|
||||
// debug: true,
|
||||
resources: {
|
||||
en,
|
||||
zh,
|
||||
en: {
|
||||
translation: en,
|
||||
},
|
||||
zh: {
|
||||
translation: zh,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
@@ -9,8 +9,9 @@ import latestVersion from '@badisi/latest-version';
|
||||
import { checkPlugins } from './check-plugin';
|
||||
|
||||
import { read } from 'read';
|
||||
import { tempDir } from './constants';
|
||||
import { IS_CRESC, tempDir } from './constants';
|
||||
import { depVersions } from './dep-versions';
|
||||
import { t } from './i18n';
|
||||
|
||||
export async function question(query: string, password?: boolean) {
|
||||
if (NO_INTERACTIVE) {
|
||||
@@ -46,7 +47,10 @@ export async function getApkInfo(fn: string) {
|
||||
);
|
||||
if (!bundleFile) {
|
||||
throw new Error(
|
||||
'找不到bundle文件。请确保此apk为release版本,且bundle文件名为默认的index.android.bundle',
|
||||
t('bundleNotFound', {
|
||||
packageType: 'apk',
|
||||
entryFile: 'index.android.bundle',
|
||||
}),
|
||||
);
|
||||
}
|
||||
const updateJsonFile = await appInfoParser.parser.getEntry(
|
||||
@@ -66,21 +70,22 @@ export async function getApkInfo(fn: string) {
|
||||
}
|
||||
}
|
||||
if (buildTime == 0) {
|
||||
throw new Error(
|
||||
'无法获取此包的编译时间戳。请更新 react-native-update 到最新版本后重新打包上传。',
|
||||
);
|
||||
throw new Error(t('buildTimeNotFound'));
|
||||
}
|
||||
return { versionName, buildTime, ...appCredential };
|
||||
}
|
||||
|
||||
export async function getAppInfo(fn) {
|
||||
export async function getAppInfo(fn: string) {
|
||||
const appInfoParser = new AppInfoParser(fn);
|
||||
const bundleFile = await appInfoParser.parser.getEntryFromHarmonyApp(
|
||||
/rawfile\/bundle.harmony.js/,
|
||||
);
|
||||
if (!bundleFile) {
|
||||
throw new Error(
|
||||
'找不到bundle文件。请确保此app为release版本,且bundle文件名为默认的bundle.harmony.js',
|
||||
t('bundleNotFound', {
|
||||
packageType: 'app',
|
||||
entryFile: 'bundle.harmony.js',
|
||||
}),
|
||||
);
|
||||
}
|
||||
const updateJsonFile = await appInfoParser.parser.getEntryFromHarmonyApp(
|
||||
@@ -103,9 +108,7 @@ export async function getAppInfo(fn) {
|
||||
buildTime = pushy_build_time;
|
||||
}
|
||||
if (buildTime == 0) {
|
||||
throw new Error(
|
||||
'无法获取此包的编译时间戳。请更新 react-native-update 到最新版本后重新打包上传。',
|
||||
);
|
||||
throw new Error(t('buildTimeNotFound'));
|
||||
}
|
||||
return { versionName, buildTime, ...appCredential };
|
||||
}
|
||||
@@ -117,7 +120,10 @@ export async function getIpaInfo(fn: string) {
|
||||
);
|
||||
if (!bundleFile) {
|
||||
throw new Error(
|
||||
'找不到bundle文件。请确保此ipa为release版本,且bundle文件名为默认的main.jsbundle',
|
||||
t('bundleNotFound', {
|
||||
packageType: 'ipa',
|
||||
entryFile: 'main.jsbundle',
|
||||
}),
|
||||
);
|
||||
}
|
||||
const updateJsonFile = await appInfoParser.parser.getEntry(
|
||||
@@ -139,9 +145,7 @@ export async function getIpaInfo(fn: string) {
|
||||
);
|
||||
}
|
||||
if (!buildTimeTxtBuffer) {
|
||||
throw new Error(
|
||||
'无法获取此包的编译时间戳。请更新 react-native-update 到最新版本后重新打包上传。',
|
||||
);
|
||||
throw new Error(t('buildTimeNotFound'));
|
||||
}
|
||||
const buildTime = buildTimeTxtBuffer.toString().replace('\n', '');
|
||||
return { versionName, buildTime, ...appCredential };
|
||||
@@ -168,40 +172,51 @@ async function getLatestVersion(pkgNames: string[]) {
|
||||
}
|
||||
|
||||
export async function printVersionCommand() {
|
||||
let [latestPushyCliVersion, latestPushyVersion] = await getLatestVersion([
|
||||
let [latestRnuCliVersion, latestRnuVersion] = await getLatestVersion([
|
||||
'react-native-update-cli',
|
||||
'react-native-update',
|
||||
]);
|
||||
latestPushyCliVersion = latestPushyCliVersion
|
||||
? ` (最新:${chalk.green(latestPushyCliVersion)})`
|
||||
latestRnuCliVersion = latestRnuCliVersion
|
||||
? ` ${t('latestVersionTag', {
|
||||
version: chalk.green(latestRnuCliVersion),
|
||||
})}`
|
||||
: '';
|
||||
console.log(
|
||||
`react-native-update-cli: ${pkg.version}${latestPushyCliVersion}`,
|
||||
`react-native-update-cli: ${pkg.version}${latestRnuCliVersion}`,
|
||||
);
|
||||
let pushyVersion = '';
|
||||
pushyVersion = depVersions['react-native-update'];
|
||||
latestPushyVersion = latestPushyVersion
|
||||
? ` (最新:${chalk.green(latestPushyVersion)})`
|
||||
let rnuVersion = '';
|
||||
rnuVersion = depVersions['react-native-update'];
|
||||
latestRnuVersion = latestRnuVersion
|
||||
? ` ${t('latestVersionTag', { version: chalk.green(latestRnuVersion) })}`
|
||||
: '';
|
||||
console.log(`react-native-update: ${pushyVersion}${latestPushyVersion}`);
|
||||
if (pushyVersion) {
|
||||
if (semverSatisfies(pushyVersion, '<8.5.2')) {
|
||||
console.log(`react-native-update: ${rnuVersion}${latestRnuVersion}`);
|
||||
if (rnuVersion) {
|
||||
if (IS_CRESC) {
|
||||
if (semverSatisfies(rnuVersion, '<10.27.0')) {
|
||||
console.error(
|
||||
'Unsupported version, please update to the latest version: npm i react-native-update@latest',
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
} else {
|
||||
if (semverSatisfies(rnuVersion, '<8.5.2')) {
|
||||
console.warn(
|
||||
`当前版本已不再支持,请至少升级到 v8 的最新小版本后重新打包(代码无需改动): npm i react-native-update@8 .
|
||||
如有使用安装 apk 的功能,请注意添加所需权限 https://pushy.reactnative.cn/docs/api#async-function-downloadandinstallapkurl`,
|
||||
);
|
||||
} else if (semverSatisfies(pushyVersion, '9.0.0 - 9.2.1')) {
|
||||
} else if (semverSatisfies(rnuVersion, '9.0.0 - 9.2.1')) {
|
||||
console.warn(
|
||||
`当前版本已不再支持,请至少升级到 v9 的最新小版本后重新打包(代码无需改动,可直接热更): npm i react-native-update@9 .
|
||||
如有使用安装 apk 的功能,请注意添加所需权限 https://pushy.reactnative.cn/docs/api#async-function-downloadandinstallapkurl`,
|
||||
);
|
||||
} else if (semverSatisfies(pushyVersion, '10.0.0 - 10.17.0')) {
|
||||
} else if (semverSatisfies(rnuVersion, '10.0.0 - 10.17.0')) {
|
||||
console.warn(
|
||||
'当前版本已不再支持,请升级到 v10 的最新小版本(代码无需改动,可直接热更): npm i react-native-update@10',
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log('react-native-update: 无法获取版本号,请在项目目录中运行命令');
|
||||
console.log(t('rnuVersionNotFound'));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -6,6 +6,7 @@ import { choosePackage } from './package';
|
||||
import { compare } from 'compare-versions';
|
||||
import { depVersions } from './utils/dep-versions';
|
||||
import { getCommitInfo } from './utils/git';
|
||||
import { Platform } from 'types';
|
||||
|
||||
async function showVersion(appId: string, offset: number) {
|
||||
const { data, count } = await get(`/app/${appId}/version/list`);
|
||||
@@ -61,7 +62,7 @@ async function chooseVersion(appId: string) {
|
||||
const cmd = await question(
|
||||
'Enter versionId or page Up/page Down/Begin(U/D/B)',
|
||||
);
|
||||
switch (cmd.toLowerCase()) {
|
||||
switch (cmd.toUpperCase()) {
|
||||
case 'U':
|
||||
offset = Math.max(0, offset - 10);
|
||||
break;
|
||||
@@ -82,7 +83,12 @@ async function chooseVersion(appId: string) {
|
||||
}
|
||||
|
||||
export const commands = {
|
||||
publish: async function ({ args, options }) {
|
||||
publish: async function ({ args, options }: { args: string[]; options: {
|
||||
name: string;
|
||||
description?: string;
|
||||
metaInfo?: string;
|
||||
platform?: Platform;
|
||||
} }) {
|
||||
const fn = args[0];
|
||||
const { name, description, metaInfo } = options;
|
||||
|
||||
@@ -136,7 +142,7 @@ export const commands = {
|
||||
versionId = null;
|
||||
}
|
||||
|
||||
let pkgId;
|
||||
let pkgId: string | undefined;
|
||||
let pkgVersion = options.packageVersion;
|
||||
let minPkgVersion = options.minPackageVersion;
|
||||
let maxPkgVersion = options.maxPackageVersion;
|
||||
|
Reference in New Issue
Block a user