mirror of
				https://gitcode.com/github-mirrors/react-native-update-cli.git
				synced 2025-11-01 07:13:11 +08:00 
			
		
		
		
	update i18n
This commit is contained in:
		
							
								
								
									
										22
									
								
								src/api.ts
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								src/api.ts
									
									
									
									
									
								
							| @@ -6,19 +6,20 @@ import ProgressBar from 'progress'; | |||||||
| import packageJson from '../package.json'; | import packageJson from '../package.json'; | ||||||
| import tcpp from 'tcp-ping'; | import tcpp from 'tcp-ping'; | ||||||
| import filesizeParser from 'filesize-parser'; | 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 type { Session } from 'types'; | ||||||
| import FormData from 'form-data'; | import FormData from 'form-data'; | ||||||
|  | import { t } from './utils/i18n'; | ||||||
|  |  | ||||||
| const tcpPing = util.promisify(tcpp.ping); | const tcpPing = util.promisify(tcpp.ping); | ||||||
|  |  | ||||||
| let session: Session | undefined; | let session: Session | undefined; | ||||||
| let savedSession: Session | undefined; | let savedSession: Session | undefined; | ||||||
|  |  | ||||||
| const defaultEndpoint = IS_CRESC |  | ||||||
|   ? 'https://api.cresc.dev' |  | ||||||
|   : 'https://update.reactnative.cn/api'; |  | ||||||
|  |  | ||||||
| const host = | const host = | ||||||
|   process.env.PUSHY_REGISTRY || process.env.RNU_API || defaultEndpoint; |   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) { |   if (resp.status !== 200) { | ||||||
|     const message = json?.message || resp.statusText; |     const message = json?.message || resp.statusText; | ||||||
|     if (resp.status === 401) { |     if (resp.status === 401) { | ||||||
|       throw new Error('登录信息已过期,请使用 pushy login 命令重新登录'); |       throw new Error(t('loginExpired')); | ||||||
|     } |     } | ||||||
|     throw new Error(message); |     throw new Error(message); | ||||||
|   } |   } | ||||||
| @@ -133,10 +134,13 @@ export async function uploadFile(fn: string, key?: string) { | |||||||
|  |  | ||||||
|   const fileSize = fs.statSync(fn).size; |   const fileSize = fs.statSync(fn).size; | ||||||
|   if (maxSize && fileSize > filesizeParser(maxSize)) { |   if (maxSize && fileSize > filesizeParser(maxSize)) { | ||||||
|  |     const readableFileSize = `${(fileSize / 1048576).toFixed(1)}m`; | ||||||
|     throw new Error( |     throw new Error( | ||||||
|       `此文件大小 ${(fileSize / 1048576).toFixed( |       t('fileSizeExceeded', { | ||||||
|         1, |         fileSize: readableFileSize, | ||||||
|       )}m , 超出当前额度 ${maxSize} 。您可以考虑升级付费业务以提升此额度。详情请访问: ${pricingPageUrl}`, |         maxSize, | ||||||
|  |         pricingPageUrl, | ||||||
|  |       }), | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -14,4 +14,15 @@ Best practices for lock files: | |||||||
| 3. Pay attention to changes in the lock file during code review. | 3. Pay attention to changes in the lock file during code review. | ||||||
| This can reduce the risk of inconsistent dependencies and supply chain attacks. | 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', | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -13,4 +13,14 @@ export default { | |||||||
| `, | `, | ||||||
|   multipleLocksFound: |   multipleLocksFound: | ||||||
|     '检测到多种不同格式的锁文件({lockFiles}),这可能导致依赖关系不一致而使热更异常。', |     '检测到多种不同格式的锁文件({lockFiles}),这可能导致依赖关系不一致而使热更异常。', | ||||||
|  |   loginExpired: '登录信息已过期,请使用 `pushy login` 命令重新登录', | ||||||
|  |   fileSizeExceeded: | ||||||
|  |     '此文件大小 {{fileSize}} , 超出当前额度 {{maxSize}} 。您可以考虑升级付费业务以提升此额度。详情请访问: {{pricingPageUrl}}', | ||||||
|  |   bundleNotFound: | ||||||
|  |     '找不到 bundle 文件。请确保此 {{packageType}} 为 release 版本,且 bundle 文件名为默认的 `{{entryFile}}`', | ||||||
|  |   buildTimeNotFound: | ||||||
|  |     '无法获取此包的编译时间戳。请更新 `react-native-update` 到最新版本后重新打包上传。', | ||||||
|  |   latestVersionTag: '(最新:{{version}})', | ||||||
|  |   rnuVersionNotFound: | ||||||
|  |     'react-native-update: 无法获取版本号。请在项目目录中运行命令', | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -4,17 +4,19 @@ const AppParser = require('./app'); | |||||||
| const supportFileTypes = ['ipa', 'apk', 'app']; | const supportFileTypes = ['ipa', 'apk', 'app']; | ||||||
| 
 | 
 | ||||||
| class AppInfoParser { | class AppInfoParser { | ||||||
|  |   file: string | File; | ||||||
|  |   parser: any; | ||||||
|   /** |   /** | ||||||
|    * parser for parsing .ipa or .apk file |    * 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) { |     if (!file) { | ||||||
|       throw new Error( |       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(); |     const fileType = splits[splits.length - 1].toLowerCase(); | ||||||
|     if (!supportFileTypes.includes(fileType)) { |     if (!supportFileTypes.includes(fileType)) { | ||||||
|       throw new Error( |       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(); |       const isEnabled = await plugin.detect(); | ||||||
|       if (isEnabled && plugin.bundleParams) { |       if (isEnabled && plugin.bundleParams) { | ||||||
|         Object.assign(params, plugin.bundleParams); |         Object.assign(params, plugin.bundleParams); | ||||||
|         console.log(`检测到 ${plugin.name} 插件,应用相应打包配置`); |         console.log(`detected ${plugin.name} plugin`); | ||||||
|       } |       } | ||||||
|     } catch (err) { |     } 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'; | import path from 'node:path'; | ||||||
|  |  | ||||||
| const scriptName: 'cresc' | 'pushy' = path.basename(process.argv[1]) as | const scriptName = path.basename(process.argv[1]) as 'cresc' | 'pushy'; | ||||||
|   | 'cresc' |  | ||||||
|   | 'pushy'; |  | ||||||
| export const IS_CRESC = scriptName === 'cresc'; | export const IS_CRESC = scriptName === 'cresc'; | ||||||
|  |  | ||||||
| export const credentialFile = IS_CRESC ? '.cresc.token' : '.update'; | 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 | export const pricingPageUrl = IS_CRESC | ||||||
|   ? 'https://cresc.dev/pricing' |   ? 'https://cresc.dev/pricing' | ||||||
|   : 'https://pushy.reactnative.cn/pricing.html'; |   : '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 en from '../locales/en'; | ||||||
| import zh from '../locales/zh'; | import zh from '../locales/zh'; | ||||||
| import { IS_CRESC } from './constants'; | import { IS_CRESC } from './constants'; | ||||||
|  |  | ||||||
| i18next.init({ | i18next.init({ | ||||||
|   lng: IS_CRESC ? 'en' : 'zh', |   lng: IS_CRESC ? 'en' : 'zh', | ||||||
|   // debug: process.env.NODE_ENV !== 'production', |   // debug: process.env.NODE_ENV !== 'production', | ||||||
|  |   // debug: true, | ||||||
|   resources: { |   resources: { | ||||||
|     en, |     en: { | ||||||
|     zh, |       translation: en, | ||||||
|  |     }, | ||||||
|  |     zh: { | ||||||
|  |       translation: zh, | ||||||
|  |     }, | ||||||
|   }, |   }, | ||||||
| }); | }); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,8 +9,9 @@ import latestVersion from '@badisi/latest-version'; | |||||||
| import { checkPlugins } from './check-plugin'; | import { checkPlugins } from './check-plugin'; | ||||||
|  |  | ||||||
| import { read } from 'read'; | import { read } from 'read'; | ||||||
| import { tempDir } from './constants'; | import { IS_CRESC, tempDir } from './constants'; | ||||||
| import { depVersions } from './dep-versions'; | import { depVersions } from './dep-versions'; | ||||||
|  | import { t } from './i18n'; | ||||||
|  |  | ||||||
| export async function question(query: string, password?: boolean) { | export async function question(query: string, password?: boolean) { | ||||||
|   if (NO_INTERACTIVE) { |   if (NO_INTERACTIVE) { | ||||||
| @@ -46,7 +47,10 @@ export async function getApkInfo(fn: string) { | |||||||
|   ); |   ); | ||||||
|   if (!bundleFile) { |   if (!bundleFile) { | ||||||
|     throw new Error( |     throw new Error( | ||||||
|       '找不到bundle文件。请确保此apk为release版本,且bundle文件名为默认的index.android.bundle', |       t('bundleNotFound', { | ||||||
|  |         packageType: 'apk', | ||||||
|  |         entryFile: 'index.android.bundle', | ||||||
|  |       }), | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|   const updateJsonFile = await appInfoParser.parser.getEntry( |   const updateJsonFile = await appInfoParser.parser.getEntry( | ||||||
| @@ -66,21 +70,22 @@ export async function getApkInfo(fn: string) { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   if (buildTime == 0) { |   if (buildTime == 0) { | ||||||
|     throw new Error( |     throw new Error(t('buildTimeNotFound')); | ||||||
|       '无法获取此包的编译时间戳。请更新 react-native-update 到最新版本后重新打包上传。', |  | ||||||
|     ); |  | ||||||
|   } |   } | ||||||
|   return { versionName, buildTime, ...appCredential }; |   return { versionName, buildTime, ...appCredential }; | ||||||
| } | } | ||||||
|  |  | ||||||
| export async function getAppInfo(fn) { | export async function getAppInfo(fn: string) { | ||||||
|   const appInfoParser = new AppInfoParser(fn); |   const appInfoParser = new AppInfoParser(fn); | ||||||
|   const bundleFile = await appInfoParser.parser.getEntryFromHarmonyApp( |   const bundleFile = await appInfoParser.parser.getEntryFromHarmonyApp( | ||||||
|     /rawfile\/bundle.harmony.js/, |     /rawfile\/bundle.harmony.js/, | ||||||
|   ); |   ); | ||||||
|   if (!bundleFile) { |   if (!bundleFile) { | ||||||
|     throw new Error( |     throw new Error( | ||||||
|       '找不到bundle文件。请确保此app为release版本,且bundle文件名为默认的bundle.harmony.js', |       t('bundleNotFound', { | ||||||
|  |         packageType: 'app', | ||||||
|  |         entryFile: 'bundle.harmony.js', | ||||||
|  |       }), | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|   const updateJsonFile = await appInfoParser.parser.getEntryFromHarmonyApp( |   const updateJsonFile = await appInfoParser.parser.getEntryFromHarmonyApp( | ||||||
| @@ -103,9 +108,7 @@ export async function getAppInfo(fn) { | |||||||
|     buildTime = pushy_build_time; |     buildTime = pushy_build_time; | ||||||
|   } |   } | ||||||
|   if (buildTime == 0) { |   if (buildTime == 0) { | ||||||
|     throw new Error( |     throw new Error(t('buildTimeNotFound')); | ||||||
|       '无法获取此包的编译时间戳。请更新 react-native-update 到最新版本后重新打包上传。', |  | ||||||
|     ); |  | ||||||
|   } |   } | ||||||
|   return { versionName, buildTime, ...appCredential }; |   return { versionName, buildTime, ...appCredential }; | ||||||
| } | } | ||||||
| @@ -117,7 +120,10 @@ export async function getIpaInfo(fn: string) { | |||||||
|   ); |   ); | ||||||
|   if (!bundleFile) { |   if (!bundleFile) { | ||||||
|     throw new Error( |     throw new Error( | ||||||
|       '找不到bundle文件。请确保此ipa为release版本,且bundle文件名为默认的main.jsbundle', |       t('bundleNotFound', { | ||||||
|  |         packageType: 'ipa', | ||||||
|  |         entryFile: 'main.jsbundle', | ||||||
|  |       }), | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|   const updateJsonFile = await appInfoParser.parser.getEntry( |   const updateJsonFile = await appInfoParser.parser.getEntry( | ||||||
| @@ -139,9 +145,7 @@ export async function getIpaInfo(fn: string) { | |||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|   if (!buildTimeTxtBuffer) { |   if (!buildTimeTxtBuffer) { | ||||||
|     throw new Error( |     throw new Error(t('buildTimeNotFound')); | ||||||
|       '无法获取此包的编译时间戳。请更新 react-native-update 到最新版本后重新打包上传。', |  | ||||||
|     ); |  | ||||||
|   } |   } | ||||||
|   const buildTime = buildTimeTxtBuffer.toString().replace('\n', ''); |   const buildTime = buildTimeTxtBuffer.toString().replace('\n', ''); | ||||||
|   return { versionName, buildTime, ...appCredential }; |   return { versionName, buildTime, ...appCredential }; | ||||||
| @@ -168,40 +172,51 @@ async function getLatestVersion(pkgNames: string[]) { | |||||||
| } | } | ||||||
|  |  | ||||||
| export async function printVersionCommand() { | export async function printVersionCommand() { | ||||||
|   let [latestPushyCliVersion, latestPushyVersion] = await getLatestVersion([ |   let [latestRnuCliVersion, latestRnuVersion] = await getLatestVersion([ | ||||||
|     'react-native-update-cli', |     'react-native-update-cli', | ||||||
|     'react-native-update', |     'react-native-update', | ||||||
|   ]); |   ]); | ||||||
|   latestPushyCliVersion = latestPushyCliVersion |   latestRnuCliVersion = latestRnuCliVersion | ||||||
|     ? ` (最新:${chalk.green(latestPushyCliVersion)})` |     ? ` ${t('latestVersionTag', { | ||||||
|  |         version: chalk.green(latestRnuCliVersion), | ||||||
|  |       })}` | ||||||
|     : ''; |     : ''; | ||||||
|   console.log( |   console.log( | ||||||
|     `react-native-update-cli: ${pkg.version}${latestPushyCliVersion}`, |     `react-native-update-cli: ${pkg.version}${latestRnuCliVersion}`, | ||||||
|   ); |   ); | ||||||
|   let pushyVersion = ''; |   let rnuVersion = ''; | ||||||
|   pushyVersion = depVersions['react-native-update']; |   rnuVersion = depVersions['react-native-update']; | ||||||
|   latestPushyVersion = latestPushyVersion |   latestRnuVersion = latestRnuVersion | ||||||
|     ? ` (最新:${chalk.green(latestPushyVersion)})` |     ? ` ${t('latestVersionTag', { version: chalk.green(latestRnuVersion) })}` | ||||||
|     : ''; |     : ''; | ||||||
|   console.log(`react-native-update: ${pushyVersion}${latestPushyVersion}`); |   console.log(`react-native-update: ${rnuVersion}${latestRnuVersion}`); | ||||||
|   if (pushyVersion) { |   if (rnuVersion) { | ||||||
|     if (semverSatisfies(pushyVersion, '<8.5.2')) { |     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( |         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(pushyVersion, '9.0.0 - 9.2.1')) { |       } else if (semverSatisfies(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(pushyVersion, '10.0.0 - 10.17.0')) { |       } else if (semverSatisfies(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', | ||||||
|         ); |         ); | ||||||
|       } |       } | ||||||
|  |     } | ||||||
|   } else { |   } else { | ||||||
|     console.log('react-native-update: 无法获取版本号,请在项目目录中运行命令'); |     console.log(t('rnuVersionNotFound')); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -6,6 +6,7 @@ import { choosePackage } from './package'; | |||||||
| import { compare } from 'compare-versions'; | 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 { Platform } from 'types'; | ||||||
|  |  | ||||||
| async function showVersion(appId: string, offset: number) { | async function showVersion(appId: string, offset: number) { | ||||||
|   const { data, count } = await get(`/app/${appId}/version/list`); |   const { data, count } = await get(`/app/${appId}/version/list`); | ||||||
| @@ -61,7 +62,7 @@ async function chooseVersion(appId: string) { | |||||||
|     const cmd = await question( |     const cmd = await question( | ||||||
|       'Enter versionId or page Up/page Down/Begin(U/D/B)', |       'Enter versionId or page Up/page Down/Begin(U/D/B)', | ||||||
|     ); |     ); | ||||||
|     switch (cmd.toLowerCase()) { |     switch (cmd.toUpperCase()) { | ||||||
|       case 'U': |       case 'U': | ||||||
|         offset = Math.max(0, offset - 10); |         offset = Math.max(0, offset - 10); | ||||||
|         break; |         break; | ||||||
| @@ -82,7 +83,12 @@ async function chooseVersion(appId: string) { | |||||||
| } | } | ||||||
|  |  | ||||||
| export const commands = { | 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 fn = args[0]; | ||||||
|     const { name, description, metaInfo } = options; |     const { name, description, metaInfo } = options; | ||||||
|  |  | ||||||
| @@ -136,7 +142,7 @@ export const commands = { | |||||||
|       versionId = null; |       versionId = null; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     let pkgId; |     let pkgId: string | undefined; | ||||||
|     let pkgVersion = options.packageVersion; |     let pkgVersion = options.packageVersion; | ||||||
|     let minPkgVersion = options.minPackageVersion; |     let minPkgVersion = options.minPackageVersion; | ||||||
|     let maxPkgVersion = options.maxPackageVersion; |     let maxPkgVersion = options.maxPackageVersion; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 sunnylqm
					sunnylqm