├── .gitignore ├── .vscode └── launch.json ├── LICENSE ├── README-en_US.md ├── README.md ├── docs └── 1.规划.md ├── lerna.json ├── package.json ├── packages ├── fe-cli │ ├── cli.js │ ├── iconfont.css │ ├── lib │ │ ├── checkNodeVersion.js │ │ ├── color.js │ │ ├── download.js │ │ ├── formatPkg.js │ │ ├── getGitInfo.js │ │ └── progressbar.js │ ├── package-lock.json │ ├── package.json │ ├── script │ │ ├── diff.js │ │ ├── hls.js │ │ ├── iconfont.js │ │ ├── ipAddress.js │ │ ├── qrcode.js │ │ └── tinypng.js │ └── yarn.lock ├── ffmpeg │ ├── index.js │ ├── output.m3u8 │ ├── output0.ts │ ├── output1.ts │ ├── output2.ts │ ├── output3.ts │ ├── package.json │ └── yarn.lock ├── iconfont-adapter │ ├── .gitignore │ ├── README.md │ ├── assets │ │ ├── iconType.ts │ │ └── iconfont.css │ ├── font │ │ ├── demo.css │ │ ├── demo_index.html │ │ ├── iconfont.css │ │ ├── iconfont.eot │ │ ├── iconfont.js │ │ ├── iconfont.svg │ │ ├── iconfont.ttf │ │ ├── iconfont.woff │ │ └── iconfont.woff2 │ ├── iconfont.config.js │ ├── index.js │ ├── package.json │ └── yarn.lock ├── index-creater │ ├── .eslintignore │ ├── .eslintrc.js │ ├── .gitignore │ ├── .npmignore │ ├── .vscode │ │ └── launch.json │ ├── README.md │ ├── example │ │ ├── README.md │ │ ├── autoComponents │ │ │ ├── foo-bar-baz │ │ │ │ ├── index.js │ │ │ │ └── qux.js │ │ │ ├── foo │ │ │ │ ├── bar.js │ │ │ │ ├── baz │ │ │ │ │ └── index.js │ │ │ │ └── index.js │ │ │ └── index.js │ │ ├── components │ │ │ ├── button │ │ │ │ └── index.js │ │ │ ├── foo-bar │ │ │ │ └── index.js │ │ │ ├── index.ts │ │ │ └── nest │ │ │ │ ├── child-nest │ │ │ │ ├── grandson-nest │ │ │ │ │ └── index.js │ │ │ │ └── index.js │ │ │ │ └── index.js │ │ ├── index.js │ │ └── otherComponents │ │ │ ├── button │ │ │ └── index.js │ │ │ ├── foo-bar │ │ │ └── index.js │ │ │ ├── index.jsx │ │ │ └── nest │ │ │ ├── child-nest │ │ │ ├── grandson-nest │ │ │ │ └── index.js │ │ │ └── index.js │ │ │ └── index.js │ ├── index.js │ ├── lib │ │ ├── ast.js │ │ ├── fileInfoParse.js │ │ └── getPascal.js │ ├── package.json │ └── yarn.lock └── quick-switch │ ├── .eslintrc.js │ ├── .gitignore │ ├── README.md │ ├── bin │ ├── cli.js │ └── run.js │ ├── img │ ├── qsinit.gif │ └── qsnew.gif │ ├── index.js │ ├── lib │ ├── attempt.js │ ├── get-config.js │ └── rename-files.js │ ├── package.json │ ├── qs.config.js │ └── yarn.lock └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | 9 | # Diagnostic reports (https://nodejs.org/api/report.html) 10 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 11 | 12 | # Runtime data 13 | pids 14 | *.pid 15 | *.seed 16 | *.pid.lock 17 | 18 | # Directory for instrumented libs generated by jscoverage/JSCover 19 | lib-cov 20 | 21 | # Coverage directory used by tools like istanbul 22 | coverage 23 | *.lcov 24 | 25 | # nyc test coverage 26 | .nyc_output 27 | 28 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 29 | .grunt 30 | 31 | # Bower dependency directory (https://bower.io/) 32 | bower_components 33 | 34 | # node-waf configuration 35 | .lock-wscript 36 | 37 | # Compiled binary addons (https://nodejs.org/api/addons.html) 38 | build/Release 39 | 40 | # Dependency directories 41 | node_modules/ 42 | jspm_packages/ 43 | 44 | # TypeScript v1 declaration files 45 | typings/ 46 | 47 | # TypeScript cache 48 | *.tsbuildinfo 49 | 50 | # Optional npm cache directory 51 | .npm 52 | 53 | # Optional eslint cache 54 | .eslintcache 55 | 56 | # Microbundle cache 57 | .rpt2_cache/ 58 | .rts2_cache_cjs/ 59 | .rts2_cache_es/ 60 | .rts2_cache_umd/ 61 | 62 | # Optional REPL history 63 | .node_repl_history 64 | 65 | # Output of 'npm pack' 66 | *.tgz 67 | 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | 71 | # dotenv environment variables file 72 | .env 73 | .env.test 74 | 75 | # parcel-bundler cache (https://parceljs.org/) 76 | .cache 77 | 78 | # Next.js build output 79 | .next 80 | 81 | # Nuxt.js build / generate output 82 | .nuxt 83 | dist 84 | 85 | # Gatsby files 86 | .cache/ 87 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 88 | # https://nextjs.org/blog/next-9-1#public-directory-support 89 | # public 90 | 91 | # vuepress build output 92 | .vuepress/dist 93 | 94 | # Serverless directories 95 | .serverless/ 96 | 97 | # FuseBox cache 98 | .fusebox/ 99 | 100 | # DynamoDB Local files 101 | .dynamodb/ 102 | 103 | # TernJS port file 104 | .tern-port 105 | 106 | test 107 | assets 108 | .DS_Store 109 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Attach", 9 | "port": 9229, 10 | "request": "attach", 11 | "skipFiles": [ 12 | "/**" 13 | ], 14 | "type": "pwa-node" 15 | } 16 | 17 | 18 | ] 19 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 zhuo.li 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README-en_US.md: -------------------------------------------------------------------------------- 1 | # fe-cli 2 | 3 | [![](https://badge.fury.io/js/fe-cli.svg)](http://badge.fury.io/js/fe-cli) 4 | 5 | [简体中文](./README.md) | English(./README-en_US.md) 6 | 7 | [fe-cli](https://github.com/fe-go/fe-cli) 8 | 9 | - [fe-cli](#fe-cli) 10 | - [install](#install) 11 | - [view video immediately](#view-video-immediately) 12 | - [show diff betweeen different files](#show-diff-betweeen-different-files) 13 | - [get local public IP address](#get-local-public-ip-address) 14 | - [transfer URL to qrcode](#transfer-url-to-qrcode) 15 | 16 | ## install 17 | 18 | `$ npm i @fe-go/fe-cli -g` 19 | 20 | ## view video immediately 21 | Based on [HTTP Live Streaming](https://zh.wikipedia.org/wiki/HTTP_Live_Streaming), split the video into mutiple parts through `ffmpeg`, in order to the purpose of opening the video in seconds. 22 | 23 | Prerequisites ffmpeg needs to be installed on this machine and recommend to install by `homebrew` 24 | 25 | - install `homebrew`: `$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"` 26 | - install `ffmpeg`: `$ brew install ffmpeg` 27 | 28 | `fe hls ` 29 | 30 | * `file.mp4` mp4file read to cut 31 | * `outdir` output directory 32 | 33 | exmaple: 34 | 35 | `fe hls test.mp4 ./` 36 | 37 | ## show diff betweeen different files 38 | `$ fe diff ` 39 | 40 | If computer is installed vscode and command code has been added into environment variable, option`--code` can be used to show diff in vscode. 41 | 42 | `fe diff file1 file2 --code` 43 | 44 | example: 45 | 46 | ``` 47 | // example1.js 48 | function example(firstName, lastName) { 49 | console.log(firstName + " " + lastName) 50 | } 51 | 52 | // example2.js 53 | function example(firstName, lastName) { 54 | console.log('He/She is: ') 55 | console.log(firstName + "/" + lastName) 56 | } 57 | ``` 58 | 59 | `$ fe diff example1.js example2.js` 60 | 61 | 结果 62 | ``` 63 | function example(firstName, lastName) { 64 | - console.log(firstName + " " + lastName) 65 | + console.log('He/She is: ') 66 | console.log(firstName + "/" + lastName) 67 | } 68 | 69 | ``` 70 | 71 | ## get local public IP address 72 | `fe IP` 73 | 74 | ## transfer URL to qrcode 75 | 76 | `fe qr -S/--small` 77 | 78 | * `` converted URL 79 | * `-S/--small` optional to get small size qrcode 80 | 81 | example: 82 | 83 | `fe qr www.github.com` get default size 84 | 85 | `fe qr www.github.com -small` / `fe qr www.github.com -S` get small size qrcode -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fe-cli 2 | [![](https://badge.fury.io/js/fe-cli.svg)](http://badge.fury.io/js/fe-cli) 3 | 4 | 一个 cli 工具,集成各种前端开发需要用的功能,持续迭代中!!!,欢迎贡献想法或者功能。 5 | 6 | 简体中文 | [English](./README-en_US.md) 7 | 8 | [目录](#fe-cli) 9 | - [fe-cli](#fe-cli) 10 | - [安装](#安装) 11 | - [视频切片](#视频切片) 12 | - [图片压缩](#图片压缩) 13 | - [展示文件diff](#展示文件diff) 14 | - [iconfont 转化](#iconfont-转化) 15 | - [获取本机IP](#获取本机ip) 16 | - [URL转qrcode](#url转qrcode) 17 | 18 | ## 安装 19 | 20 | `$ npm i @fe-go/fe-cli -g` 21 | 22 | ## 视频切片 23 | 基于 [HTTP Live Streaming](https://zh.wikipedia.org/wiki/HTTP_Live_Streaming) 通过 ffmpeg 将视频分割为多份以达到视频秒开的目的。 24 | 25 | 了解更多看这里[视频秒开操作指南](https://juejin.cn/post/6979223117415579656) 26 | 27 | v1.1.3 版本后基于wasm 实现已经不需要安装 ffmpeg 了! 28 | 29 | ~~前提本机需要安装 ffmpeg (70多M实在难以内置) 推荐通过 homebrew 安装~~ 30 | - ~~安装 homebrew `$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"`~~ 31 | - ~~安装 ffmpeg `$ brew install ffmpeg`~~ 32 | 33 | `fe hls [time]` 34 | 35 | * `file.mp4` 切片的mp4文件 36 | * `outdir` 输出路径 37 | * `time` 切片时间 38 | 39 | 示例: 40 | 41 | `fe hls test.mp4 ./` 42 | 43 | ## 图片压缩 44 | 45 | 压缩 `.png` `.jpg` `.jpeg` 图片,借鉴[super-tinypng](https://github.com/advence-liz/super-tinypng) 调用[tinypng](https://tinify.cn/) 进行图片压缩。 46 | 47 | `$ fe tinypng [dest]` 48 | 49 | - `src` 压缩图片所在目录或者具体文件路径,自动寻找目录中 `.png` `.jpg` `.jpeg` 图片(`src/*.{jpg,png.jpeg}`),但是不进行深层遍历。 50 | - `dest` 图片输出目录,可选参数默认值`.` ,当`dest` 为默认值时为了防止直接覆盖源文件,后缀名前会拼接`.min` 51 | 52 | 示例: 53 | - `$ fe tinypng images outdir` 54 | - `$ fe tinypng images` 55 | - `$ fe tinypng xx.png outdir` 56 | 57 | ## 展示文件diff 58 | 展示两个文件间的diff 59 | 60 | `$ fe diff --code` 61 | 62 | - `code` 当电脑中已经安装了vscode并且code命令已经添加到环境变量中就可以使用vscode显示文件DIFF。 63 | 64 | 65 | 示例: 66 | 67 | ``` 68 | // example1.js 69 | function example(firstName, lastName) { 70 | console.log(firstName + " " + lastName) 71 | } 72 | 73 | // example2.js 74 | function example(firstName, lastName) { 75 | console.log('He/She is: ') 76 | console.log(firstName + "/" + lastName) 77 | } 78 | ``` 79 | 80 | `$ fe diff example1.js example2.js` 81 | 82 | 结果 83 | ``` 84 | function example(firstName, lastName) { 85 | - console.log(firstName + " " + lastName) 86 | + console.log('He/She is: ') 87 | console.log(firstName + "/" + lastName) 88 | } 89 | 90 | ``` 91 | 92 | `$ fe diff file1 file2 --code` 93 | ## iconfont 转化 94 | 95 | `$ fe iconfont [dest] ` 96 | - `src` `iconfont` 源文件目录 97 | - `dest` 输出路径 98 | 99 | 去掉iconfont中冗余的引用资源,将需要引用的`.ttf`资源自动转化为`base64`,简化 iconfont 引入方式。 100 | 101 | 转化前:`@font-face`如下依照浏览器兼容情况我们只要保留`ttf`就ok了。 102 | 103 | ```less 104 | @font-face {font-family: "iconfont"; 105 | src: url('iconfont.eot?t=1557322756059'); /* IE9 */ 106 | src: url('iconfont.eot?t=1557322756059#iefix') format('embedded-opentype'), /* IE6-IE8 */ 107 | url('data:application/x-font-woff2;charset=utf-8;base64,........') format('woff2'), 108 | url('iconfont.woff?t=1557322756059') format('woff'), 109 | url('iconfont.ttf?t=1557322756059') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ 110 | url('iconfont.svg?t=1557322756059#iconfont') format('svg'); /* iOS 4.1- */ 111 | } 112 | 113 | ``` 114 | 115 | 转化后:如下去掉冗余部分,并将`ttf`转为`base64` 116 | 117 | ```less 118 | @font-face { 119 | font-family: "iconfont"; 120 | src: url('data:font/ttf;charset=utf-8;base64,....') format('truetype'); 121 | } 122 | 123 | ``` 124 | ## 获取本机IP 125 | 通过`fe IP`命令可以获取本机IP 126 | 127 | ## URL转qrcode 128 | 129 | `fe qr --small` 130 | 131 | * `` 被转换的URL地址 132 | * `-S/--small` 可选值表示得到小尺寸的二维码 133 | 134 | 示例: 135 | 136 | `fe qr www.github.com` 137 | 138 | `fe qr www.github.com -small` / `fe qr www.github.com -S` 139 | -------------------------------------------------------------------------------- /docs/1.规划.md: -------------------------------------------------------------------------------- 1 | # 规划 2 | 3 | 构建一个 cli 工具集成各种前端开发需要用的功能,类似 https://github.com/zxlie/FeHelper ,但是侧重那些依赖操作系统和文件系统的功能。 4 | 5 | ## 功能点 6 | 7 | - 视频秒开 https://github.com/advence-liz/workspace/blob/master/node/ffmpeg/hls/hls.js 8 | - 获取ip https://github.com/sindresorhus/ipify 9 | - es-check https://github.com/dollarshaveclub/es-check 10 | - 编译 es5 11 | - qrcode 12 | - diff https://www.npmjs.com/package/diff vscode 展示diff code --diff f1.js f2.js 13 | - tree https://www.npmjs.com/package/tree-cli 14 | - 静态服务器 https://www.npmjs.com/package/serve 15 | - mock server 16 | - 图片压缩 17 | - git 下载 18 | - js css html 压缩 19 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "packages/*" 4 | ], 5 | "version": "0.0.0" 6 | } 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "root", 3 | "private": true, 4 | "devDependencies": { 5 | "lerna": "^3.20.2" 6 | }, 7 | "dependencies": { 8 | "colors": "^1.4.0", 9 | "diff": "^5.0.0", 10 | "qrcode-terminal": "^0.12.0" 11 | }, 12 | "version": "0.0.1" 13 | } 14 | -------------------------------------------------------------------------------- /packages/fe-cli/cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const program = require('commander') 4 | const { error } = require('qrcode-terminal') 5 | const updateNotifier = require('update-notifier') 6 | const pkg = require('./package.json') 7 | require('./lib/checkNodeVersion') 8 | 9 | const notifier = updateNotifier({ pkg }) 10 | 11 | if (notifier.update) { 12 | console.log(`Update available: ${notifier.update.latest}`) 13 | } 14 | 15 | program 16 | .version(pkg.version, '-v, --version', 'version') 17 | .option('--code', '使用 vscode 展示 diff') 18 | .option('-S, --small', 'small qrcode size') 19 | // .option('-p, --packages [value]', '新生成monorepo组件') 20 | // .option('--type ', '编译类型 dev,build,prepub,publish,test') 21 | 22 | program 23 | .command('hls [time]') 24 | .description('视频切片') 25 | .action(async (src, outdir, time = 2) => { 26 | console.log(src, outdir) 27 | await require('./script/hls')(src, outdir, time) 28 | }) 29 | 30 | program 31 | .command('diff ') 32 | .description('展示文件 diff') 33 | .option('--code, --diff_mode ', '通过 vscode 展示 DIFF', true) 34 | .action(async (one, other) => { 35 | require('./script/diff')(one, other, program.opts()) 36 | }) 37 | 38 | program 39 | .command('qrcode ') 40 | .alias('qr') 41 | .description('generate qrcode') 42 | .action((url) => { 43 | require('./script/qrcode')(url, program.opts()) 44 | }) 45 | 46 | // get local public IP address 47 | program 48 | .command('IP') 49 | .alias('ip') 50 | .description('get local public IP address') 51 | .action(() => { 52 | console.log(require('./script/ipAddress')()) 53 | }) 54 | 55 | program 56 | .command('iconfont [dest]') 57 | .description( 58 | '去掉iconfont中冗余的引用资源,将需要引用的 .ttf 资源自动转化为 base64,简化 iconfont 引入方式。' 59 | ) 60 | .action((src, dest = '.') => { 61 | require('./script/iconfont')(src, dest, program.opts()) 62 | }) 63 | 64 | program 65 | .command('tinypng [dest]') 66 | .alias('ty') 67 | .description('压缩指定目录下的 .png .jpg .jpeg 文件') 68 | .action((src, dest = '.') => { 69 | require('./script/tinypng')(src, dest, program.opts()) 70 | }) 71 | 72 | program.on('--help', function () { 73 | console.log('') 74 | console.log('Examples:') 75 | console.log(' $ fe diff file1 file2') 76 | console.log(' $ fe diff file1 file2 --code') 77 | console.log(' $ fe hls xxx.mp4 outdir') 78 | console.log(' $ fe qr URL') 79 | console.log(' $ fe qr URL -S/--small') 80 | console.log(' $ fe ty images outdir') 81 | console.log(' $ fe tinypng images outdir') 82 | console.log(' $ fe tinypng images') 83 | console.log(' $ fe tinypng xx.png outdir') 84 | }) 85 | 86 | try { 87 | program.parse(process.argv) 88 | } catch (err) { 89 | // 逻辑执行错误此处也会抛出 90 | console.log(err) 91 | // program.outputHelp() 92 | } 93 | 94 | if (!process.argv.slice(2).length) { 95 | program.outputHelp() 96 | } 97 | -------------------------------------------------------------------------------- /packages/fe-cli/iconfont.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "iconfont"; 3 | src: url('data:font/ttf;charset=utf-8;base64,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') format('truetype'); 4 | } 5 | 6 | 7 | .iconfont { 8 | font-family: "iconfont" !important; 9 | font-size: 16px; 10 | font-style: normal; 11 | -webkit-font-smoothing: antialiased; 12 | -moz-osx-font-smoothing: grayscale; 13 | } 14 | 15 | .icon-jiantou:before { 16 | content: "\e697"; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /packages/fe-cli/lib/checkNodeVersion.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const fs = require('fs') 3 | const semver = require('semver') 4 | const { red } = require('./color') 5 | 6 | function checkNodeVersion() { 7 | const packageJsonPath = path.resolve(process.cwd(), 'package.json') 8 | 9 | if (!fs.existsSync(packageJsonPath)) { 10 | return 11 | } 12 | 13 | const packageJson = require(packageJsonPath) 14 | if (!packageJson.engines || !packageJson.engines.node) { 15 | return 16 | } 17 | 18 | if (!semver.satisfies(process.version, packageJson.engines.node)) { 19 | console.error( 20 | red( 21 | 'You are running Node %s.\n' + 22 | 'cube-cli requires Node %s or higher. \n' + 23 | 'Please update your version of Node.' 24 | ), 25 | process.version, 26 | packageJson.engines.node 27 | ) 28 | process.exit(1) 29 | } 30 | } 31 | checkNodeVersion() 32 | -------------------------------------------------------------------------------- /packages/fe-cli/lib/color.js: -------------------------------------------------------------------------------- 1 | // console.log('\033[42;30m heee') \033[背景色编号;字色编号m 2 | // 字色编号:30黑,31红,32绿,33黄,34蓝,35紫,36深绿,37白色 3 | // 背景编号:40黑,41红,42绿,43黄,44蓝,45紫,46深绿,47白色 4 | // 033 x1B等效而且还不区分大小写 5 | //https://www.jianshu.com/p/cca3e72c3ba7 6 | const ColorMap = { 7 | black: 0, 8 | red: 1, 9 | green: 2, 10 | yellow: 3, 11 | blue: 4, 12 | purple: 5, 13 | darkGreen: 6, 14 | white: 7 15 | } 16 | /** 17 | * 18 | * @param {string} x 文字颜色 19 | * @param {string} y 背景颜色 20 | */ 21 | function color(x = 7, y) { 22 | const fontColor = `3${x}m` 23 | const backgroundColor = y !== undefined ? `4${y};` : '' 24 | return message => { 25 | return '\033' + `[${backgroundColor}${fontColor}${message}` + '\033[0m' 26 | } 27 | } 28 | 29 | const blue = color(ColorMap.blue) 30 | const red = color(ColorMap.red) 31 | const green = color(ColorMap.green) 32 | 33 | // console.log(blue('reerer')) 34 | // console.log(red('reerer')) 35 | // console.log(green('reerer')) 36 | // console.log(color(ColorMap.red, ColorMap.green)('reerer')) 37 | // console.log(green('reerer')) 38 | 39 | module.exports = { 40 | blue, 41 | green, 42 | red, 43 | color 44 | } 45 | -------------------------------------------------------------------------------- /packages/fe-cli/lib/download.js: -------------------------------------------------------------------------------- 1 | const shell = require('shelljs') 2 | const fs = require('fs-extra') 3 | const path = require('path') 4 | const downloadTemplate = function(cwd, target, branch) { 5 | shell.exec('git init', { cwd }) 6 | shell.exec( 7 | 'git remote add -f origin ssh://git@git.xxxx.com/xxx/xxx.git', 8 | { 9 | cwd 10 | } 11 | ) 12 | shell.exec('git config core.sparsecheckout true', { cwd }) 13 | shell.exec(`echo packages/${target}-template >> .git/info/sparse-checkout`, { 14 | cwd 15 | }) 16 | console.log(`git pull origin ${branch}`) 17 | shell.exec(`git pull origin ${branch}`, { cwd }) 18 | } 19 | /** 20 | * 21 | * @param {*} name 22 | * @param {*} target 23 | */ 24 | module.exports = async (name, target, branch) => { 25 | const tempPath = path.resolve('temp') 26 | fs.ensureDirSync(tempPath) 27 | downloadTemplate(tempPath, target, branch) 28 | fs.copySync(tempPath + `/packages/${target}-template`, path.resolve(name)) 29 | fs.removeSync(tempPath) 30 | } 31 | -------------------------------------------------------------------------------- /packages/fe-cli/lib/formatPkg.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs-extra') 2 | const path = require('path') 3 | module.exports = (name, author, config) => { 4 | const monoScope = config && config.monoScope 5 | const pkgPath = monoScope ? path.resolve(`./${monoScope}/${name}/package.json`) : path.resolve(`./${name}/package.json`) 6 | let pkg = require(pkgPath) 7 | pkg.name = `@hfe/block-component-${name}` 8 | pkg.author = author 9 | fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2)) 10 | } 11 | -------------------------------------------------------------------------------- /packages/fe-cli/lib/getGitInfo.js: -------------------------------------------------------------------------------- 1 | const exec = require('child_process').execSync 2 | module.exports = () => { 3 | let name 4 | let email 5 | 6 | try { 7 | name = exec('git config --get user.name') 8 | email = exec('git config --get user.email') 9 | } catch (e) { } 10 | 11 | name = name && JSON.stringify(name.toString().trim()).slice(1, -1) 12 | email = email && email.toString().trim() 13 | return { 14 | name, 15 | email 16 | } 17 | } -------------------------------------------------------------------------------- /packages/fe-cli/lib/progressbar.js: -------------------------------------------------------------------------------- 1 | // 这里用到一个很实用的 npm 模块,用以在同一行打印文本 2 | var slog = require('single-line-log').stdout 3 | 4 | // 封装的 ProgressBar 工具 5 | function ProgressBar(description, total = 100) { 6 | // 两个基本参数(属性) 7 | this.description = description || 'Progress' // 命令行开头的文字信息 8 | this.length = 25 // 进度条的长度(单位:字符),默认设为 25 9 | 10 | // 刷新进度条图案、文字的方法 11 | this.render = function (completed) { 12 | var percent = (completed / total).toFixed(2) // 计算进度(子任务的 完成数 除以 总数) 13 | var cell_num = Math.floor(percent * this.length) // 计算需要多少个 █ 符号来拼凑图案 14 | 15 | // 拼接黑色条 16 | var cell = '' 17 | for (var i = 0; i < cell_num; i++) { 18 | cell += '█' 19 | } 20 | 21 | // 拼接灰色条 22 | var empty = '' 23 | for (var i = 0; i < this.length - cell_num; i++) { 24 | empty += '░' 25 | } 26 | 27 | // 拼接最终文本 28 | var cmdText = 29 | this.description + 30 | ': ' + 31 | (100 * percent).toFixed(2) + 32 | '% ' + 33 | cell + 34 | empty + 35 | ' ' + 36 | completed + 37 | '/' + 38 | total 39 | return cmdText 40 | } 41 | } 42 | 43 | // 模块导出 44 | module.exports = ProgressBar 45 | -------------------------------------------------------------------------------- /packages/fe-cli/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@fe-go/fe-cli", 3 | "version": "1.1.3", 4 | "description": "前端工具集 cli ", 5 | "main": "index.js", 6 | "bin": { 7 | "fe": "cli.js" 8 | }, 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+ssh://git@github.com/advence-liz/fe-cli.git" 15 | }, 16 | "keywords": [ 17 | "fe", 18 | "fed", 19 | "tool", 20 | "cli" 21 | ], 22 | "author": "advence-liz", 23 | "license": "ISC", 24 | "bugs": { 25 | "url": "https://github.com/advence-liz/fe-cli/issues" 26 | }, 27 | "homepage": "https://github.com/advence-liz/fe-cli#readme", 28 | "dependencies": { 29 | "commander": "7.2.0", 30 | "diff": "^5.0.0", 31 | "fs-extra": "^10.0.0", 32 | "lodash": "^4.17.21", 33 | "mime-types": "^2.1.31", 34 | "ora": "^5.4.1", 35 | "qrcode-terminal": "^0.12.0", 36 | "single-line-log": "^1.1.2", 37 | "update-notifier": "^5.1.0", 38 | "@ffmpeg/core": "^0.11.0", 39 | "@ffmpeg/ffmpeg": "^0.11.6" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/fe-cli/script/diff.js: -------------------------------------------------------------------------------- 1 | const { green, blue, red } = require('../lib/color') 2 | const fs = require('fs-extra') 3 | const Diff = require('diff') 4 | const exec = require('child_process').execSync 5 | function diffFile(one, other) { 6 | const f1 = fs.readFileSync(one).toString() 7 | const f2 = fs.readFileSync(other).toString() 8 | const diff = Diff.diffLines(f1, f2) 9 | diff.forEach((part) => { 10 | // green for additions, red for deletions 11 | // grey for common parts 12 | let text = '' 13 | if (part.added) { 14 | text = green(`+ ${part.value}`) 15 | } else if (part.removed) { 16 | text = red(`- ${part.value}`) 17 | } else { 18 | text = ` ${part.value}` 19 | } 20 | process.stdout.write(text) 21 | }) 22 | } 23 | 24 | module.exports = (one, other, opts) => { 25 | try { 26 | exec(`code --diff ${one} ${other}`) 27 | process.exit(0) 28 | } catch (error) { 29 | diffFile(one, other) 30 | } 31 | 32 | // console.log(blue('\n\nfe-cli tips\n')) 33 | // console.log(green('如果已经安装了 vscode 并且 code 命令已经添加到环境变量中可以添加 --code options')) 34 | // console.log(green('$ fe diff file1 file2 --code')) 35 | } 36 | -------------------------------------------------------------------------------- /packages/fe-cli/script/hls.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const fs = require('fs-extra') 3 | const exec = require('child_process').execSync 4 | const { blue, red, green } = require('../lib/color') 5 | const Progressbar = require('../lib/progressbar') 6 | const ora = require('ora') 7 | const { createFFmpeg, fetchFile } = require('@ffmpeg/ffmpeg') 8 | /** 9 | * node 16 10 | */ 11 | const ffmpeg = createFFmpeg({ 12 | log: true 13 | }) 14 | 15 | module.exports = async (src, dist, time=2) => { 16 | fs.ensureDirSync(path.resolve(dist)) 17 | const sourcePath = path.resolve(src) 18 | // 当文件名为中文是 s3 上传会失败,创建临时目录转移视频 19 | const memSourcePath = 'hls' + path.parse(src).ext 20 | // await fs.renameSync(sourcePath, memSourcePath) 21 | // const outputPath = path.resolve(dist, `${path.parse(memSourcePath).name}.m3u8`) 22 | const outputPath = path.resolve(dist) 23 | const spinner = ora('progress').start() 24 | const pb = new Progressbar() 25 | // ffmpeg -i output.mp4 -c:v libx264 -c:a aac -strict -2 -f hls -hls_list_size 0 -hls_time 5 output1.m3u8 26 | await ffmpeg.load() 27 | ffmpeg.FS('writeFile', memSourcePath, await fetchFile(path.resolve(src))) 28 | // await ffmpeg.run('-i,output.mp4,-c:v,libx264,-c:a,aac,-strict,-2,-f,hls,-hls_list_size,0,-hls_time,5,output1.m3u8') 29 | // ffmpeg.setProgress(({ ratio }) => { 30 | // /* 31 | // * ratio is a float number between 0 to 1. 32 | // */ 33 | // spinner.color = 'yellow' 34 | // const percent = ratio 35 | // if (!percent) return 36 | // spinner.text = pb.render(percent) 37 | // }) 38 | const r = await ffmpeg.run( 39 | '-i', 40 | memSourcePath, 41 | '-c:v', 42 | 'libx264', 43 | '-c:a', 44 | 'aac', 45 | '-strict', 46 | '-2', 47 | '-f', 48 | 'hls', 49 | '-hls_list_size', 50 | '0', 51 | '-hls_time', 52 | String(time), 53 | '-force_key_frames', 54 | 'expr:gte(t,n_forced*1)', 55 | 'output.m3u8' // mem target 56 | ) 57 | 58 | await fs.promises.writeFile( 59 | path.join(outputPath, 'hls.m3u8'), 60 | ffmpeg.FS('readFile', 'output.m3u8') 61 | ) 62 | 63 | ffmpeg 64 | .FS('readdir', '/') 65 | .filter((p) => p.endsWith('.ts')) 66 | .forEach(async (p) => { 67 | console.log(p) 68 | await fs.promises.writeFile( 69 | path.join(outputPath, p), 70 | ffmpeg.FS('readFile', p) 71 | ) 72 | // await fs.writeFileSync(outputPath, ffmpeg.FS('readFile', p)) 73 | }) 74 | spinner.succeed(green(`${src} file has been converted succesfully`)) 75 | // ora('uploding').start() 76 | // 恢复视频文件 77 | // await fs.renameSync(memSourcePath, sourcePath) 78 | process.exit(0) 79 | } 80 | -------------------------------------------------------------------------------- /packages/fe-cli/script/iconfont.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | const mime = require('mime-types') 4 | const _ = require('lodash') 5 | 6 | /** 7 | * 8 | * @param {string} filePath 文件路径 9 | */ 10 | function convert2base64(filePath) { 11 | let data = fs.readFileSync(path.resolve(filePath)) 12 | data = Buffer.from(data).toString('base64') 13 | // return 'data:' + mime.lookup(filePath) + ';base64,' + data 14 | 15 | return 'data:' + mime.lookup(filePath) + ';charset=utf-8' + ';base64,' + data 16 | } 17 | 18 | /** 19 | * 将iconfont css 源文件转化为想要的形式 20 | * @param {string} filePath 文件路径 21 | */ 22 | function convertIconfont(config) { 23 | const str = fs.readFileSync(path.join(config.src, 'iconfont.css')).toString() 24 | const matchNames = [] 25 | const arr = str.split(/\n/g) 26 | let destCss = arr.slice(6).join('\n') 27 | 28 | const base64 = convert2base64(path.join(config.src, 'iconfont.ttf')) 29 | 30 | const template = `@font-face { 31 | font-family: "iconfont"; 32 | src: url('${base64}') format('truetype'); 33 | } 34 | 35 | ${destCss}` 36 | 37 | fs.writeFileSync(`${config.dest}/iconfont.css`, template) 38 | } 39 | /** 40 | * 将匹配的class name 转换为 typescript type 41 | * @param {Array} matchNames matchNames 42 | */ 43 | function convertMatchNames(matchNames) { 44 | const matchType = matchNames.join(`' | '`) 45 | 46 | return `export type iconType = '${matchType}' 47 | export const icons = ${JSON.stringify(matchNames)} 48 | ` 49 | } 50 | 51 | module.exports = (src, dest) => { 52 | const config = { 53 | fontSize: 36, 54 | // pattern: 'camelCase', 55 | src, 56 | dest 57 | } 58 | 59 | if (!fs.existsSync(config.dest)) fs.mkdirSync(config.dest) 60 | convertIconfont(config) 61 | } 62 | -------------------------------------------------------------------------------- /packages/fe-cli/script/ipAddress.js: -------------------------------------------------------------------------------- 1 | function getIPAddress() { 2 | let interfaces = require('os').networkInterfaces() 3 | for (var devName in interfaces) { 4 | let iface = interfaces[devName] 5 | for (let i = 0; i < iface.length; i++) { 6 | let alias = iface[i] 7 | if ( 8 | alias.family === 'IPv4' && 9 | alias.address !== '127.0.0.1' && 10 | !alias.internal 11 | ) { 12 | return alias.address 13 | } 14 | } 15 | } 16 | } 17 | 18 | 19 | module.exports = getIPAddress -------------------------------------------------------------------------------- /packages/fe-cli/script/qrcode.js: -------------------------------------------------------------------------------- 1 | const qrcode = require('qrcode-terminal') 2 | 3 | function genQrCode(url, opts, cb) { 4 | let size = false 5 | if (opts) { 6 | size = opts['small'] 7 | } 8 | return qrcode.generate(url, {small: size ? true : false}, cb) 9 | } 10 | module.exports = genQrCode 11 | 12 | -------------------------------------------------------------------------------- /packages/fe-cli/script/tinypng.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 参考: https://github.com/zhanyuzhang/super-tinypng/edit/master/index.js 3 | * */ 4 | 5 | const fs = require('fs') 6 | const path = require('path') 7 | const https = require('https') 8 | const glob = require('glob') 9 | const { blue, green } = require('../lib/color') 10 | const { URL } = require('url') 11 | 12 | const cwd = process.cwd() 13 | const root = cwd 14 | const exts = ['.jpg', '.png', '.jpeg'] 15 | const max = 5200000 // 5MB == 5242848.754299136 16 | 17 | const options = { 18 | method: 'POST', 19 | hostname: 'tinypng.com', 20 | path: '/web/shrink', 21 | headers: { 22 | rejectUnauthorized: false, 23 | 'Postman-Token': Date.now(), 24 | 'Cache-Control': 'no-cache', 25 | 'Content-Type': 'application/x-www-form-urlencoded', 26 | 'User-Agent': 27 | 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36' 28 | } 29 | } 30 | 31 | // 生成随机IP, 赋值给 X-Forwarded-For 32 | function getRandomIP() { 33 | return Array.from(Array(4)) 34 | .map(() => parseInt(Math.random() * 255)) 35 | .join('.') 36 | } 37 | 38 | // 过滤文件格式,返回所有jpg,png图片 39 | function fileFilter(file, dest) { 40 | fs.stat(file, (err, stats) => { 41 | if (err) return console.error(err) 42 | if (stats.size <= max && stats.isFile()) { 43 | // 通过 X-Forwarded-For 头部伪造客户端IP 44 | options.headers['X-Forwarded-For'] = getRandomIP() 45 | fileUpload(file, dest) // console.log('可以压缩:' + file); 46 | } 47 | // if (stats.isDirectory()) fileList(file + '/'); 48 | }) 49 | } 50 | // 异步API,压缩图片 51 | // {"error":"Bad request","message":"Request is invalid"} 52 | // {"input": { "size": 887, "type": "image/png" },"output": { "size": 785, "type": "image/png", "width": 81, "height": 81, "ratio": 0.885, "url": "https://tinypng.com/web/output/7aztz90nq5p9545zch8gjzqg5ubdatd6" }} 53 | function fileUpload(img, dest) { 54 | var req = https.request(options, function (res) { 55 | res.on('data', (buf) => { 56 | let obj = JSON.parse(buf.toString()) 57 | if (obj.error) { 58 | console.log(`[${img}]:压缩失败!报错:${obj.message}`) 59 | } else { 60 | fileUpdate(img, obj, dest) 61 | } 62 | }) 63 | }) 64 | 65 | req.write(fs.readFileSync(img), 'binary') 66 | req.on('error', (e) => { 67 | console.error(e) 68 | }) 69 | req.end() 70 | } 71 | // 该方法被循环调用,请求图片数据 72 | function fileUpdate(imgpath, obj, dest) { 73 | const outputDir = path.resolve(dest) 74 | const { name, ext } = path.parse(imgpath) 75 | const fileName = dest === '.' ? name + '.min' : name 76 | 77 | imgpath = path.resolve(dest, fileName + ext) 78 | 79 | if (!fs.existsSync(outputDir)) { 80 | fs.mkdirSync(outputDir) 81 | } 82 | 83 | let options = new URL(obj.output.url) 84 | let req = https.request(options, (res) => { 85 | let body = '' 86 | res.setEncoding('binary') 87 | res.on('data', function (data) { 88 | body += data 89 | }) 90 | res.on('end', function () { 91 | fs.writeFile(imgpath, body, 'binary', (err) => { 92 | if (err) return console.error(err) 93 | console.log( 94 | blue('原始大小:'), 95 | green(`${(obj.input.size / 1000).toFixed(0)}k`), 96 | blue('压缩大小:'), 97 | green(`${(obj.output.size / 1000).toFixed(0)}k`), 98 | blue('优化比例:'), 99 | green(`- ${((1 - obj.output.ratio) * 100).toFixed(0)}%`), 100 | blue('图片路径:'), 101 | green(imgpath) 102 | ) 103 | }) 104 | }) 105 | }) 106 | req.on('error', (e) => { 107 | console.error(e) 108 | }) 109 | req.end() 110 | } 111 | 112 | module.exports = (src, dest) => { 113 | const stats = fs.statSync(path.join(src)) 114 | const fileList = glob.sync( 115 | stats.isFile() ? src : path.join(src, '*.{png,jpg,jpeg}') 116 | ) 117 | fileList.forEach((file) => { 118 | fileFilter(path.join(file), dest) 119 | }) 120 | } 121 | -------------------------------------------------------------------------------- /packages/fe-cli/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@ffmpeg/core@^0.11.0": 6 | version "0.11.0" 7 | resolved "https://registry.npmmirror.com/@ffmpeg/core/-/core-0.11.0.tgz" 8 | integrity sha512-9Tt/+2PMpkGPXUK8n6He9G8Y+qR6qmCPSCw9iEKZxHHOvJ9BE/r0Fccj+YgDZTlyu6rXxc9x6EqCaFBIt7qzjA== 9 | 10 | "@ffmpeg/ffmpeg@^0.11.6": 11 | version "0.11.6" 12 | resolved "https://registry.npmmirror.com/@ffmpeg/ffmpeg/-/ffmpeg-0.11.6.tgz" 13 | integrity sha512-uN8J8KDjADEavPhNva6tYO9Fj0lWs9z82swF3YXnTxWMBoFLGq3LZ6FLlIldRKEzhOBKnkVfA8UnFJuvGvNxcA== 14 | dependencies: 15 | is-url "^1.2.4" 16 | node-fetch "^2.6.1" 17 | regenerator-runtime "^0.13.7" 18 | resolve-url "^0.2.1" 19 | 20 | "@sindresorhus/is@^0.14.0": 21 | version "0.14.0" 22 | resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz" 23 | integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== 24 | 25 | "@szmarczak/http-timer@^1.1.2": 26 | version "1.1.2" 27 | resolved "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz" 28 | integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== 29 | dependencies: 30 | defer-to-connect "^1.0.1" 31 | 32 | ansi-align@^3.0.0: 33 | version "3.0.0" 34 | resolved "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz" 35 | integrity sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw== 36 | dependencies: 37 | string-width "^3.0.0" 38 | 39 | ansi-regex@^2.0.0: 40 | version "2.1.1" 41 | resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz" 42 | integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= 43 | 44 | ansi-regex@^4.1.0: 45 | version "4.1.0" 46 | resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz" 47 | integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== 48 | 49 | ansi-regex@^5.0.0: 50 | version "5.0.0" 51 | resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz" 52 | integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== 53 | 54 | ansi-styles@^4.0.0, ansi-styles@^4.1.0: 55 | version "4.3.0" 56 | resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" 57 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 58 | dependencies: 59 | color-convert "^2.0.1" 60 | 61 | base64-js@^1.3.1: 62 | version "1.5.1" 63 | resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" 64 | integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== 65 | 66 | bl@^4.1.0: 67 | version "4.1.0" 68 | resolved "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz" 69 | integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== 70 | dependencies: 71 | buffer "^5.5.0" 72 | inherits "^2.0.4" 73 | readable-stream "^3.4.0" 74 | 75 | boxen@^5.0.0: 76 | version "5.0.1" 77 | resolved "https://registry.npmjs.org/boxen/-/boxen-5.0.1.tgz" 78 | integrity sha512-49VBlw+PrWEF51aCmy7QIteYPIFZxSpvqBdP/2itCPPlJ49kj9zg/XPRFrdkne2W+CfwXUls8exMvu1RysZpKA== 79 | dependencies: 80 | ansi-align "^3.0.0" 81 | camelcase "^6.2.0" 82 | chalk "^4.1.0" 83 | cli-boxes "^2.2.1" 84 | string-width "^4.2.0" 85 | type-fest "^0.20.2" 86 | widest-line "^3.1.0" 87 | wrap-ansi "^7.0.0" 88 | 89 | buffer@^5.5.0: 90 | version "5.7.1" 91 | resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" 92 | integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== 93 | dependencies: 94 | base64-js "^1.3.1" 95 | ieee754 "^1.1.13" 96 | 97 | cacheable-request@^6.0.0: 98 | version "6.1.0" 99 | resolved "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz" 100 | integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== 101 | dependencies: 102 | clone-response "^1.0.2" 103 | get-stream "^5.1.0" 104 | http-cache-semantics "^4.0.0" 105 | keyv "^3.0.0" 106 | lowercase-keys "^2.0.0" 107 | normalize-url "^4.1.0" 108 | responselike "^1.0.2" 109 | 110 | camelcase@^6.2.0: 111 | version "6.2.0" 112 | resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz" 113 | integrity sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg== 114 | 115 | chalk@^4.1.0: 116 | version "4.1.1" 117 | resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz" 118 | integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== 119 | dependencies: 120 | ansi-styles "^4.1.0" 121 | supports-color "^7.1.0" 122 | 123 | ci-info@^2.0.0: 124 | version "2.0.0" 125 | resolved "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz" 126 | integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== 127 | 128 | cli-boxes@^2.2.1: 129 | version "2.2.1" 130 | resolved "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz" 131 | integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== 132 | 133 | cli-cursor@^3.1.0: 134 | version "3.1.0" 135 | resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz" 136 | integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== 137 | dependencies: 138 | restore-cursor "^3.1.0" 139 | 140 | cli-spinners@^2.5.0: 141 | version "2.6.0" 142 | resolved "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.0.tgz" 143 | integrity sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q== 144 | 145 | clone-response@^1.0.2: 146 | version "1.0.2" 147 | resolved "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz" 148 | integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= 149 | dependencies: 150 | mimic-response "^1.0.0" 151 | 152 | clone@^1.0.2: 153 | version "1.0.4" 154 | resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz" 155 | integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= 156 | 157 | code-point-at@^1.0.0: 158 | version "1.1.0" 159 | resolved "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz" 160 | integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= 161 | 162 | color-convert@^2.0.1: 163 | version "2.0.1" 164 | resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" 165 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 166 | dependencies: 167 | color-name "~1.1.4" 168 | 169 | color-name@~1.1.4: 170 | version "1.1.4" 171 | resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" 172 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 173 | 174 | commander@7.2.0: 175 | version "7.2.0" 176 | resolved "https://r.npm.sankuai.com/commander/download/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" 177 | integrity sha1-o2y1fQtQHOEI5NIFWaFQo5HZerc= 178 | 179 | configstore@^5.0.1: 180 | version "5.0.1" 181 | resolved "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz" 182 | integrity sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA== 183 | dependencies: 184 | dot-prop "^5.2.0" 185 | graceful-fs "^4.1.2" 186 | make-dir "^3.0.0" 187 | unique-string "^2.0.0" 188 | write-file-atomic "^3.0.0" 189 | xdg-basedir "^4.0.0" 190 | 191 | crypto-random-string@^2.0.0: 192 | version "2.0.0" 193 | resolved "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz" 194 | integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== 195 | 196 | decompress-response@^3.3.0: 197 | version "3.3.0" 198 | resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz" 199 | integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= 200 | dependencies: 201 | mimic-response "^1.0.0" 202 | 203 | deep-extend@^0.6.0: 204 | version "0.6.0" 205 | resolved "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz" 206 | integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== 207 | 208 | defaults@^1.0.3: 209 | version "1.0.3" 210 | resolved "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz" 211 | integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= 212 | dependencies: 213 | clone "^1.0.2" 214 | 215 | defer-to-connect@^1.0.1: 216 | version "1.1.3" 217 | resolved "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz" 218 | integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== 219 | 220 | diff@^5.0.0: 221 | version "5.0.0" 222 | resolved "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz" 223 | integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== 224 | 225 | dot-prop@^5.2.0: 226 | version "5.3.0" 227 | resolved "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz" 228 | integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== 229 | dependencies: 230 | is-obj "^2.0.0" 231 | 232 | duplexer3@^0.1.4: 233 | version "0.1.4" 234 | resolved "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz" 235 | integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= 236 | 237 | emoji-regex@^7.0.1: 238 | version "7.0.3" 239 | resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz" 240 | integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== 241 | 242 | emoji-regex@^8.0.0: 243 | version "8.0.0" 244 | resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" 245 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 246 | 247 | end-of-stream@^1.1.0: 248 | version "1.4.4" 249 | resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" 250 | integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== 251 | dependencies: 252 | once "^1.4.0" 253 | 254 | escape-goat@^2.0.0: 255 | version "2.1.1" 256 | resolved "https://registry.npmjs.org/escape-goat/-/escape-goat-2.1.1.tgz" 257 | integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== 258 | 259 | fs-extra@^10.0.0: 260 | version "10.0.0" 261 | resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz" 262 | integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ== 263 | dependencies: 264 | graceful-fs "^4.2.0" 265 | jsonfile "^6.0.1" 266 | universalify "^2.0.0" 267 | 268 | get-stream@^4.1.0: 269 | version "4.1.0" 270 | resolved "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz" 271 | integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== 272 | dependencies: 273 | pump "^3.0.0" 274 | 275 | get-stream@^5.1.0: 276 | version "5.2.0" 277 | resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" 278 | integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== 279 | dependencies: 280 | pump "^3.0.0" 281 | 282 | global-dirs@^3.0.0: 283 | version "3.0.0" 284 | resolved "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.0.tgz" 285 | integrity sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA== 286 | dependencies: 287 | ini "2.0.0" 288 | 289 | got@^9.6.0: 290 | version "9.6.0" 291 | resolved "https://registry.npmjs.org/got/-/got-9.6.0.tgz" 292 | integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== 293 | dependencies: 294 | "@sindresorhus/is" "^0.14.0" 295 | "@szmarczak/http-timer" "^1.1.2" 296 | cacheable-request "^6.0.0" 297 | decompress-response "^3.3.0" 298 | duplexer3 "^0.1.4" 299 | get-stream "^4.1.0" 300 | lowercase-keys "^1.0.1" 301 | mimic-response "^1.0.1" 302 | p-cancelable "^1.0.0" 303 | to-readable-stream "^1.0.0" 304 | url-parse-lax "^3.0.0" 305 | 306 | graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: 307 | version "4.2.6" 308 | resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz" 309 | integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== 310 | 311 | has-flag@^4.0.0: 312 | version "4.0.0" 313 | resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" 314 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 315 | 316 | has-yarn@^2.1.0: 317 | version "2.1.0" 318 | resolved "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz" 319 | integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw== 320 | 321 | http-cache-semantics@^4.0.0: 322 | version "4.1.0" 323 | resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz" 324 | integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== 325 | 326 | ieee754@^1.1.13: 327 | version "1.2.1" 328 | resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" 329 | integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== 330 | 331 | import-lazy@^2.1.0: 332 | version "2.1.0" 333 | resolved "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz" 334 | integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= 335 | 336 | imurmurhash@^0.1.4: 337 | version "0.1.4" 338 | resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" 339 | integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= 340 | 341 | inherits@^2.0.3, inherits@^2.0.4: 342 | version "2.0.4" 343 | resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" 344 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 345 | 346 | ini@2.0.0: 347 | version "2.0.0" 348 | resolved "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz" 349 | integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== 350 | 351 | ini@~1.3.0: 352 | version "1.3.8" 353 | resolved "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz" 354 | integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== 355 | 356 | is-ci@^2.0.0: 357 | version "2.0.0" 358 | resolved "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz" 359 | integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== 360 | dependencies: 361 | ci-info "^2.0.0" 362 | 363 | is-fullwidth-code-point@^1.0.0: 364 | version "1.0.0" 365 | resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz" 366 | integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= 367 | dependencies: 368 | number-is-nan "^1.0.0" 369 | 370 | is-fullwidth-code-point@^2.0.0: 371 | version "2.0.0" 372 | resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz" 373 | integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= 374 | 375 | is-fullwidth-code-point@^3.0.0: 376 | version "3.0.0" 377 | resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" 378 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 379 | 380 | is-installed-globally@^0.4.0: 381 | version "0.4.0" 382 | resolved "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.4.0.tgz" 383 | integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== 384 | dependencies: 385 | global-dirs "^3.0.0" 386 | is-path-inside "^3.0.2" 387 | 388 | is-interactive@^1.0.0: 389 | version "1.0.0" 390 | resolved "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz" 391 | integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== 392 | 393 | is-npm@^5.0.0: 394 | version "5.0.0" 395 | resolved "https://registry.npmjs.org/is-npm/-/is-npm-5.0.0.tgz" 396 | integrity sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA== 397 | 398 | is-obj@^2.0.0: 399 | version "2.0.0" 400 | resolved "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz" 401 | integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== 402 | 403 | is-path-inside@^3.0.2: 404 | version "3.0.3" 405 | resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" 406 | integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== 407 | 408 | is-typedarray@^1.0.0: 409 | version "1.0.0" 410 | resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" 411 | integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= 412 | 413 | is-unicode-supported@^0.1.0: 414 | version "0.1.0" 415 | resolved "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz" 416 | integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== 417 | 418 | is-url@^1.2.4: 419 | version "1.2.4" 420 | resolved "https://registry.npmmirror.com/is-url/-/is-url-1.2.4.tgz" 421 | integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== 422 | 423 | is-yarn-global@^0.3.0: 424 | version "0.3.0" 425 | resolved "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz" 426 | integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== 427 | 428 | json-buffer@3.0.0: 429 | version "3.0.0" 430 | resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz" 431 | integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= 432 | 433 | jsonfile@^6.0.1: 434 | version "6.1.0" 435 | resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz" 436 | integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== 437 | dependencies: 438 | universalify "^2.0.0" 439 | optionalDependencies: 440 | graceful-fs "^4.1.6" 441 | 442 | keyv@^3.0.0: 443 | version "3.1.0" 444 | resolved "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz" 445 | integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== 446 | dependencies: 447 | json-buffer "3.0.0" 448 | 449 | latest-version@^5.1.0: 450 | version "5.1.0" 451 | resolved "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz" 452 | integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== 453 | dependencies: 454 | package-json "^6.3.0" 455 | 456 | lodash@^4.17.21: 457 | version "4.17.21" 458 | resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" 459 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== 460 | 461 | log-symbols@^4.1.0: 462 | version "4.1.0" 463 | resolved "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz" 464 | integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== 465 | dependencies: 466 | chalk "^4.1.0" 467 | is-unicode-supported "^0.1.0" 468 | 469 | lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: 470 | version "1.0.1" 471 | resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz" 472 | integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== 473 | 474 | lowercase-keys@^2.0.0: 475 | version "2.0.0" 476 | resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz" 477 | integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== 478 | 479 | lru-cache@^6.0.0: 480 | version "6.0.0" 481 | resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" 482 | integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== 483 | dependencies: 484 | yallist "^4.0.0" 485 | 486 | make-dir@^3.0.0: 487 | version "3.1.0" 488 | resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz" 489 | integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== 490 | dependencies: 491 | semver "^6.0.0" 492 | 493 | mime-db@1.48.0: 494 | version "1.48.0" 495 | resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz" 496 | integrity sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ== 497 | 498 | mime-types@^2.1.31: 499 | version "2.1.31" 500 | resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz" 501 | integrity sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg== 502 | dependencies: 503 | mime-db "1.48.0" 504 | 505 | mimic-fn@^2.1.0: 506 | version "2.1.0" 507 | resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" 508 | integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== 509 | 510 | mimic-response@^1.0.0, mimic-response@^1.0.1: 511 | version "1.0.1" 512 | resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz" 513 | integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== 514 | 515 | minimist@^1.2.0: 516 | version "1.2.5" 517 | resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz" 518 | integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== 519 | 520 | node-fetch@^2.6.1: 521 | version "2.6.9" 522 | resolved "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.6.9.tgz" 523 | integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg== 524 | dependencies: 525 | whatwg-url "^5.0.0" 526 | 527 | normalize-url@^4.1.0: 528 | version "4.5.1" 529 | resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz" 530 | integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== 531 | 532 | number-is-nan@^1.0.0: 533 | version "1.0.1" 534 | resolved "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz" 535 | integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= 536 | 537 | once@^1.3.1, once@^1.4.0: 538 | version "1.4.0" 539 | resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" 540 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 541 | dependencies: 542 | wrappy "1" 543 | 544 | onetime@^5.1.0: 545 | version "5.1.2" 546 | resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" 547 | integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== 548 | dependencies: 549 | mimic-fn "^2.1.0" 550 | 551 | ora@^5.4.1: 552 | version "5.4.1" 553 | resolved "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz" 554 | integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== 555 | dependencies: 556 | bl "^4.1.0" 557 | chalk "^4.1.0" 558 | cli-cursor "^3.1.0" 559 | cli-spinners "^2.5.0" 560 | is-interactive "^1.0.0" 561 | is-unicode-supported "^0.1.0" 562 | log-symbols "^4.1.0" 563 | strip-ansi "^6.0.0" 564 | wcwidth "^1.0.1" 565 | 566 | p-cancelable@^1.0.0: 567 | version "1.1.0" 568 | resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz" 569 | integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== 570 | 571 | package-json@^6.3.0: 572 | version "6.5.0" 573 | resolved "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz" 574 | integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ== 575 | dependencies: 576 | got "^9.6.0" 577 | registry-auth-token "^4.0.0" 578 | registry-url "^5.0.0" 579 | semver "^6.2.0" 580 | 581 | prepend-http@^2.0.0: 582 | version "2.0.0" 583 | resolved "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz" 584 | integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= 585 | 586 | pump@^3.0.0: 587 | version "3.0.0" 588 | resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" 589 | integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== 590 | dependencies: 591 | end-of-stream "^1.1.0" 592 | once "^1.3.1" 593 | 594 | pupa@^2.1.1: 595 | version "2.1.1" 596 | resolved "https://registry.npmjs.org/pupa/-/pupa-2.1.1.tgz" 597 | integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A== 598 | dependencies: 599 | escape-goat "^2.0.0" 600 | 601 | qrcode-terminal@^0.12.0: 602 | version "0.12.0" 603 | resolved "https://registry.npmmirror.com/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz" 604 | integrity sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ== 605 | 606 | rc@^1.2.8: 607 | version "1.2.8" 608 | resolved "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz" 609 | integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== 610 | dependencies: 611 | deep-extend "^0.6.0" 612 | ini "~1.3.0" 613 | minimist "^1.2.0" 614 | strip-json-comments "~2.0.1" 615 | 616 | readable-stream@^3.4.0: 617 | version "3.6.0" 618 | resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz" 619 | integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== 620 | dependencies: 621 | inherits "^2.0.3" 622 | string_decoder "^1.1.1" 623 | util-deprecate "^1.0.1" 624 | 625 | regenerator-runtime@^0.13.7: 626 | version "0.13.11" 627 | resolved "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz" 628 | integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== 629 | 630 | registry-auth-token@^4.0.0: 631 | version "4.2.1" 632 | resolved "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz" 633 | integrity sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw== 634 | dependencies: 635 | rc "^1.2.8" 636 | 637 | registry-url@^5.0.0: 638 | version "5.1.0" 639 | resolved "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz" 640 | integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw== 641 | dependencies: 642 | rc "^1.2.8" 643 | 644 | resolve-url@^0.2.1: 645 | version "0.2.1" 646 | resolved "https://registry.npmmirror.com/resolve-url/-/resolve-url-0.2.1.tgz" 647 | integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== 648 | 649 | responselike@^1.0.2: 650 | version "1.0.2" 651 | resolved "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz" 652 | integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= 653 | dependencies: 654 | lowercase-keys "^1.0.0" 655 | 656 | restore-cursor@^3.1.0: 657 | version "3.1.0" 658 | resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz" 659 | integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== 660 | dependencies: 661 | onetime "^5.1.0" 662 | signal-exit "^3.0.2" 663 | 664 | safe-buffer@~5.2.0: 665 | version "5.2.1" 666 | resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" 667 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 668 | 669 | semver-diff@^3.1.1: 670 | version "3.1.1" 671 | resolved "https://registry.npmjs.org/semver-diff/-/semver-diff-3.1.1.tgz" 672 | integrity sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg== 673 | dependencies: 674 | semver "^6.3.0" 675 | 676 | semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: 677 | version "6.3.0" 678 | resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" 679 | integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== 680 | 681 | semver@^7.3.4: 682 | version "7.3.5" 683 | resolved "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz" 684 | integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== 685 | dependencies: 686 | lru-cache "^6.0.0" 687 | 688 | signal-exit@^3.0.2: 689 | version "3.0.3" 690 | resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz" 691 | integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== 692 | 693 | single-line-log@^1.1.2: 694 | version "1.1.2" 695 | resolved "https://registry.npmjs.org/single-line-log/-/single-line-log-1.1.2.tgz" 696 | integrity sha1-wvg/Jzo+GhbtsJlWYdoO1e8DM2Q= 697 | dependencies: 698 | string-width "^1.0.1" 699 | 700 | string-width@^1.0.1: 701 | version "1.0.2" 702 | resolved "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz" 703 | integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= 704 | dependencies: 705 | code-point-at "^1.0.0" 706 | is-fullwidth-code-point "^1.0.0" 707 | strip-ansi "^3.0.0" 708 | 709 | string-width@^3.0.0: 710 | version "3.1.0" 711 | resolved "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz" 712 | integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== 713 | dependencies: 714 | emoji-regex "^7.0.1" 715 | is-fullwidth-code-point "^2.0.0" 716 | strip-ansi "^5.1.0" 717 | 718 | string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0: 719 | version "4.2.2" 720 | resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz" 721 | integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== 722 | dependencies: 723 | emoji-regex "^8.0.0" 724 | is-fullwidth-code-point "^3.0.0" 725 | strip-ansi "^6.0.0" 726 | 727 | string_decoder@^1.1.1: 728 | version "1.3.0" 729 | resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" 730 | integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== 731 | dependencies: 732 | safe-buffer "~5.2.0" 733 | 734 | strip-ansi@^3.0.0: 735 | version "3.0.1" 736 | resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz" 737 | integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= 738 | dependencies: 739 | ansi-regex "^2.0.0" 740 | 741 | strip-ansi@^5.1.0: 742 | version "5.2.0" 743 | resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz" 744 | integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== 745 | dependencies: 746 | ansi-regex "^4.1.0" 747 | 748 | strip-ansi@^6.0.0: 749 | version "6.0.0" 750 | resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz" 751 | integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== 752 | dependencies: 753 | ansi-regex "^5.0.0" 754 | 755 | strip-json-comments@~2.0.1: 756 | version "2.0.1" 757 | resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz" 758 | integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= 759 | 760 | supports-color@^7.1.0: 761 | version "7.2.0" 762 | resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" 763 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 764 | dependencies: 765 | has-flag "^4.0.0" 766 | 767 | to-readable-stream@^1.0.0: 768 | version "1.0.0" 769 | resolved "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz" 770 | integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== 771 | 772 | tr46@~0.0.3: 773 | version "0.0.3" 774 | resolved "https://registry.npmmirror.com/tr46/-/tr46-0.0.3.tgz" 775 | integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== 776 | 777 | type-fest@^0.20.2: 778 | version "0.20.2" 779 | resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" 780 | integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== 781 | 782 | typedarray-to-buffer@^3.1.5: 783 | version "3.1.5" 784 | resolved "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz" 785 | integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== 786 | dependencies: 787 | is-typedarray "^1.0.0" 788 | 789 | unique-string@^2.0.0: 790 | version "2.0.0" 791 | resolved "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz" 792 | integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== 793 | dependencies: 794 | crypto-random-string "^2.0.0" 795 | 796 | universalify@^2.0.0: 797 | version "2.0.0" 798 | resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" 799 | integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== 800 | 801 | update-notifier@^5.1.0: 802 | version "5.1.0" 803 | resolved "https://registry.npmjs.org/update-notifier/-/update-notifier-5.1.0.tgz" 804 | integrity sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw== 805 | dependencies: 806 | boxen "^5.0.0" 807 | chalk "^4.1.0" 808 | configstore "^5.0.1" 809 | has-yarn "^2.1.0" 810 | import-lazy "^2.1.0" 811 | is-ci "^2.0.0" 812 | is-installed-globally "^0.4.0" 813 | is-npm "^5.0.0" 814 | is-yarn-global "^0.3.0" 815 | latest-version "^5.1.0" 816 | pupa "^2.1.1" 817 | semver "^7.3.4" 818 | semver-diff "^3.1.1" 819 | xdg-basedir "^4.0.0" 820 | 821 | url-parse-lax@^3.0.0: 822 | version "3.0.0" 823 | resolved "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz" 824 | integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= 825 | dependencies: 826 | prepend-http "^2.0.0" 827 | 828 | util-deprecate@^1.0.1: 829 | version "1.0.2" 830 | resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" 831 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= 832 | 833 | wcwidth@^1.0.1: 834 | version "1.0.1" 835 | resolved "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz" 836 | integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= 837 | dependencies: 838 | defaults "^1.0.3" 839 | 840 | webidl-conversions@^3.0.0: 841 | version "3.0.1" 842 | resolved "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz" 843 | integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== 844 | 845 | whatwg-url@^5.0.0: 846 | version "5.0.0" 847 | resolved "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-5.0.0.tgz" 848 | integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== 849 | dependencies: 850 | tr46 "~0.0.3" 851 | webidl-conversions "^3.0.0" 852 | 853 | widest-line@^3.1.0: 854 | version "3.1.0" 855 | resolved "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz" 856 | integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== 857 | dependencies: 858 | string-width "^4.0.0" 859 | 860 | wrap-ansi@^7.0.0: 861 | version "7.0.0" 862 | resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" 863 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 864 | dependencies: 865 | ansi-styles "^4.0.0" 866 | string-width "^4.1.0" 867 | strip-ansi "^6.0.0" 868 | 869 | wrappy@1: 870 | version "1.0.2" 871 | resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" 872 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 873 | 874 | write-file-atomic@^3.0.0: 875 | version "3.0.3" 876 | resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz" 877 | integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== 878 | dependencies: 879 | imurmurhash "^0.1.4" 880 | is-typedarray "^1.0.0" 881 | signal-exit "^3.0.2" 882 | typedarray-to-buffer "^3.1.5" 883 | 884 | xdg-basedir@^4.0.0: 885 | version "4.0.0" 886 | resolved "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz" 887 | integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== 888 | 889 | yallist@^4.0.0: 890 | version "4.0.0" 891 | resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" 892 | integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== 893 | -------------------------------------------------------------------------------- /packages/ffmpeg/index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | const { createFFmpeg, fetchFile } = require('@ffmpeg/ffmpeg') 4 | 5 | const ffmpeg = createFFmpeg({ 6 | log: true 7 | }) 8 | 9 | // ffmpeg -i output.mp4 -c:v libx264 -c:a aac -strict -2 -f hls -hls_list_size 0 -hls_time 5 output1.m3u8 10 | 11 | ;(async (src, dist, time) => { 12 | await ffmpeg.load() 13 | ffmpeg.FS('writeFile', 'flame.avi', await fetchFile(path.resolve(src))) 14 | // await ffmpeg.run('-i,output.mp4,-c:v,libx264,-c:a,aac,-strict,-2,-f,hls,-hls_list_size,0,-hls_time,5,output1.m3u8') 15 | ffmpeg.setProgress(({ ratio }) => { 16 | console.log('进度', ratio) 17 | /* 18 | * ratio is a float number between 0 to 1. 19 | */ 20 | }) 21 | const r = await ffmpeg.run( 22 | '-i', 23 | 'flame.avi', 24 | '-c:v', 25 | 'libx264', 26 | '-c:a', 27 | 'aac', 28 | '-strict', 29 | '-2', 30 | '-f', 31 | 'hls', 32 | '-hls_list_size', 33 | '0', 34 | '-hls_time', 35 | String(time), 36 | '-force_key_frames', 37 | 'expr:gte(t,n_forced*1)', 38 | 'output.m3u8' 39 | ) 40 | 41 | console.log(r) 42 | 43 | await fs.promises.writeFile( 44 | 'output.m3u8', 45 | ffmpeg.FS('readFile', 'output.m3u8') 46 | ) 47 | 48 | ffmpeg 49 | .FS('readdir', '/') 50 | .filter((p) => p.endsWith('.ts')) 51 | .forEach(async (p) => { 52 | fs.writeFileSync(p, ffmpeg.FS('readFile', p)) 53 | }) 54 | 55 | process.exit(0) 56 | })() 57 | -------------------------------------------------------------------------------- /packages/ffmpeg/output.m3u8: -------------------------------------------------------------------------------- 1 | #EXTM3U 2 | #EXT-X-VERSION:3 3 | #EXT-X-TARGETDURATION:1 4 | #EXT-X-MEDIA-SEQUENCE:0 5 | #EXTINF:1.000000, 6 | output0.ts 7 | #EXTINF:1.000000, 8 | output1.ts 9 | #EXTINF:1.000000, 10 | output2.ts 11 | #EXTINF:0.142833, 12 | output3.ts 13 | #EXT-X-ENDLIST 14 | -------------------------------------------------------------------------------- /packages/ffmpeg/output0.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fe-go/fe-cli/8c1ae45b60747197acec7e10a184625968a86b1a/packages/ffmpeg/output0.ts -------------------------------------------------------------------------------- /packages/ffmpeg/output1.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fe-go/fe-cli/8c1ae45b60747197acec7e10a184625968a86b1a/packages/ffmpeg/output1.ts -------------------------------------------------------------------------------- /packages/ffmpeg/output2.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fe-go/fe-cli/8c1ae45b60747197acec7e10a184625968a86b1a/packages/ffmpeg/output2.ts -------------------------------------------------------------------------------- /packages/ffmpeg/output3.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fe-go/fe-cli/8c1ae45b60747197acec7e10a184625968a86b1a/packages/ffmpeg/output3.ts -------------------------------------------------------------------------------- /packages/ffmpeg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ffmpeg", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@ffmpeg/core": "^0.11.0", 13 | "@ffmpeg/ffmpeg": "^0.11.6" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/ffmpeg/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@ffmpeg/core@^0.11.0": 6 | version "0.11.0" 7 | resolved "https://registry.npmmirror.com/@ffmpeg/core/-/core-0.11.0.tgz#fc24fe5af587f83cd2575d0e45de455d8eed9ba9" 8 | integrity sha512-9Tt/+2PMpkGPXUK8n6He9G8Y+qR6qmCPSCw9iEKZxHHOvJ9BE/r0Fccj+YgDZTlyu6rXxc9x6EqCaFBIt7qzjA== 9 | 10 | "@ffmpeg/ffmpeg@^0.11.6": 11 | version "0.11.6" 12 | resolved "https://registry.npmmirror.com/@ffmpeg/ffmpeg/-/ffmpeg-0.11.6.tgz#9cbe42dfb5132fca74ae5570ebeee2341f8c6e51" 13 | integrity sha512-uN8J8KDjADEavPhNva6tYO9Fj0lWs9z82swF3YXnTxWMBoFLGq3LZ6FLlIldRKEzhOBKnkVfA8UnFJuvGvNxcA== 14 | dependencies: 15 | is-url "^1.2.4" 16 | node-fetch "^2.6.1" 17 | regenerator-runtime "^0.13.7" 18 | resolve-url "^0.2.1" 19 | 20 | is-url@^1.2.4: 21 | version "1.2.4" 22 | resolved "https://registry.npmmirror.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" 23 | integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== 24 | 25 | node-fetch@^2.6.1: 26 | version "2.6.9" 27 | resolved "https://registry.npmmirror.com/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6" 28 | integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg== 29 | dependencies: 30 | whatwg-url "^5.0.0" 31 | 32 | regenerator-runtime@^0.13.7: 33 | version "0.13.11" 34 | resolved "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" 35 | integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== 36 | 37 | resolve-url@^0.2.1: 38 | version "0.2.1" 39 | resolved "https://registry.npmmirror.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" 40 | integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== 41 | 42 | tr46@~0.0.3: 43 | version "0.0.3" 44 | resolved "https://registry.npmmirror.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" 45 | integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== 46 | 47 | webidl-conversions@^3.0.0: 48 | version "3.0.1" 49 | resolved "https://registry.npmmirror.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" 50 | integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== 51 | 52 | whatwg-url@^5.0.0: 53 | version "5.0.0" 54 | resolved "https://registry.npmmirror.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" 55 | integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== 56 | dependencies: 57 | tr46 "~0.0.3" 58 | webidl-conversions "^3.0.0" 59 | -------------------------------------------------------------------------------- /packages/iconfont-adapter/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /packages/iconfont-adapter/README.md: -------------------------------------------------------------------------------- 1 | # iconfont adapter 2 | 3 | 写了一个小demo自动化将下载iconfont源文件转化为更贴近业务使用的模式,减少手动操作犯错误的机会, 4 | `font`目录为源文件`assets`为转化后的样子 5 | 6 | ## 去掉iconfont中冗余的引用资源并将引用的资源自动转化为base64 7 | 8 | 转化前:`@font-face`如下依照浏览器兼容情况我们只要保留ttf就ok了 9 | 10 | ```less 11 | @font-face {font-family: "iconfont"; 12 | src: url('iconfont.eot?t=1557322756059'); /* IE9 */ 13 | src: url('iconfont.eot?t=1557322756059#iefix') format('embedded-opentype'), /* IE6-IE8 */ 14 | url('data:application/x-font-woff2;charset=utf-8;base64,........') format('woff2'), 15 | url('iconfont.woff?t=1557322756059') format('woff'), 16 | url('iconfont.ttf?t=1557322756059') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ 17 | url('iconfont.svg?t=1557322756059#iconfont') format('svg'); /* iOS 4.1- */ 18 | } 19 | 20 | ``` 21 | 22 | 转化后:如下去掉冗余部分,并将ttf转为base64 23 | 24 | ```less 25 | @font-face { 26 | font-family: "iconfont"; 27 | src: url('data:font/ttf;charset=utf-8;base64,....') format('truetype'); 28 | } 29 | 30 | ``` 31 | 32 | ## 修改iconfont源css文件中的默认字体大小 33 | 34 | ```less 35 | .iconfont { 36 | font-family: "iconfont" !important; 37 | font-size: 36px;//也就是之定义font-size 值 38 | font-style: normal; 39 | -webkit-font-smoothing: antialiased; 40 | -moz-osx-font-smoothing: grayscale; 41 | } 42 | 43 | ``` 44 | 45 | ## 修改iconfont源css 文件中icon class 的命名规则 46 | 47 | 转化前 48 | 49 | ```less 50 | .iconarrow_right:before { 51 | content: "\e666"; 52 | } 53 | 54 | .iconarrow_under:before { 55 | content: "\e667"; 56 | } 57 | 58 | .iconarrow_on:before { 59 | content: "\e668"; 60 | } 61 | ``` 62 | 63 | 转化后: 变成驼峰主要是为了兼容typescript中引入 64 | 65 | ```less 66 | .icon-arrowRight:before { 67 | content: "\e666"; 68 | } 69 | 70 | .icon-arrowUnder:before { 71 | content: "\e667"; 72 | } 73 | 74 | .icon-arrowOn:before { 75 | content: "\e668"; 76 | } 77 | ``` 78 | 79 | ## 输出typescirpt 类型定义 和 icon 类型数据源 80 | 81 | 主要是为了方便之后的代码引入,达到更新iconfont之后不需要修改别的地方的源码 82 | 83 | ```js 84 | export type iconType = 'arrowRight' | 'arrowUnder' | 'arrowOn' | 'closePop' | 'navBack' | 'selectDownRadio' | 'navSearch' | 'selectUp' | 'warning' | 'success' | 'failure' | 'wait' | 'prompt' | 'delete' 85 | export const icons = ["arrowRight","arrowUnder","arrowOn","closePop","navBack","selectDownRadio","navSearch","selectUp","warning","success","failure","wait","prompt","delete"] 86 | ``` 87 | 88 | ## run 89 | 90 | `$ node index.js` 91 | 92 | ## 忽略 93 | 94 | //icon[\w-]*: 95 | 96 | `url('data:;;base64,..............) format('truetype')` 97 | `url('data:application/x-font-woff2;charset=utf-8;base64,.............)` 98 | mimetype charset 填错了目前看都没有影响 format 填错了不行 99 | 100 | mime.contentType('markdown') // 'text/x-markdown; charset=utf-8' 101 | mime.lookup('json') // 'application/json' -------------------------------------------------------------------------------- /packages/iconfont-adapter/assets/iconType.ts: -------------------------------------------------------------------------------- 1 | export type iconType = 'arrowRight' | 'arrowUnder' | 'arrowOn' | 'closePop' | 'navBack' | 'selectDownRadio' | 'navSearch' | 'selectUp' | 'warning' | 'success' | 'failure' | 'wait' | 'prompt' | 'delete' 2 | export const icons = ["arrowRight","arrowUnder","arrowOn","closePop","navBack","selectDownRadio","navSearch","selectUp","warning","success","failure","wait","prompt","delete"] 3 | -------------------------------------------------------------------------------- /packages/iconfont-adapter/assets/iconfont.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: "iconfont"; 3 | src: url('data:font/ttf;charset=utf-8;base64,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') format('truetype'); 4 | } 5 | 6 | .iconfont { 7 | font-family: "iconfont" !important; 8 | font-size: 36px; 9 | font-style: normal; 10 | -webkit-font-smoothing: antialiased; 11 | -moz-osx-font-smoothing: grayscale; 12 | } 13 | 14 | .icon-arrowRight:before { 15 | content: "\e666"; 16 | } 17 | 18 | .icon-arrowUnder:before { 19 | content: "\e667"; 20 | } 21 | 22 | .icon-arrowOn:before { 23 | content: "\e668"; 24 | } 25 | 26 | .icon-closePop:before { 27 | content: "\e669"; 28 | } 29 | 30 | .icon-navBack:before { 31 | content: "\e671"; 32 | } 33 | 34 | .icon-selectDownRadio:before { 35 | content: "\e672"; 36 | } 37 | 38 | .icon-navSearch:before { 39 | content: "\e673"; 40 | } 41 | 42 | .icon-selectUp:before { 43 | content: "\e675"; 44 | } 45 | 46 | .icon-warning:before { 47 | content: "\e674"; 48 | } 49 | 50 | .icon-success:before { 51 | content: "\e676"; 52 | } 53 | 54 | .icon-failure:before { 55 | content: "\e677"; 56 | } 57 | 58 | .icon-wait:before { 59 | content: "\e678"; 60 | } 61 | 62 | .icon-prompt:before { 63 | content: "\e679"; 64 | } 65 | 66 | .icon-delete:before { 67 | content: "\e67a"; 68 | } 69 | 70 | -------------------------------------------------------------------------------- /packages/iconfont-adapter/font/demo.css: -------------------------------------------------------------------------------- 1 | /* Logo 字体 */ 2 | @font-face { 3 | font-family: "iconfont logo"; 4 | src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834'); 5 | src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'), 6 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'), 7 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'), 8 | url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg'); 9 | } 10 | 11 | .logo { 12 | font-family: "iconfont logo"; 13 | font-size: 160px; 14 | font-style: normal; 15 | -webkit-font-smoothing: antialiased; 16 | -moz-osx-font-smoothing: grayscale; 17 | } 18 | 19 | /* tabs */ 20 | .nav-tabs { 21 | position: relative; 22 | } 23 | 24 | .nav-tabs .nav-more { 25 | position: absolute; 26 | right: 0; 27 | bottom: 0; 28 | height: 42px; 29 | line-height: 42px; 30 | color: #666; 31 | } 32 | 33 | #tabs { 34 | border-bottom: 1px solid #eee; 35 | } 36 | 37 | #tabs li { 38 | cursor: pointer; 39 | width: 100px; 40 | height: 40px; 41 | line-height: 40px; 42 | text-align: center; 43 | font-size: 16px; 44 | border-bottom: 2px solid transparent; 45 | position: relative; 46 | z-index: 1; 47 | margin-bottom: -1px; 48 | color: #666; 49 | } 50 | 51 | 52 | #tabs .active { 53 | border-bottom-color: #f00; 54 | color: #222; 55 | } 56 | 57 | .tab-container .content { 58 | display: none; 59 | } 60 | 61 | /* 页面布局 */ 62 | .main { 63 | padding: 30px 100px; 64 | width: 960px; 65 | margin: 0 auto; 66 | } 67 | 68 | .main .logo { 69 | color: #333; 70 | text-align: left; 71 | margin-bottom: 30px; 72 | line-height: 1; 73 | height: 110px; 74 | margin-top: -50px; 75 | overflow: hidden; 76 | *zoom: 1; 77 | } 78 | 79 | .main .logo a { 80 | font-size: 160px; 81 | color: #333; 82 | } 83 | 84 | .helps { 85 | margin-top: 40px; 86 | } 87 | 88 | .helps pre { 89 | padding: 20px; 90 | margin: 10px 0; 91 | border: solid 1px #e7e1cd; 92 | background-color: #fffdef; 93 | overflow: auto; 94 | } 95 | 96 | .icon_lists { 97 | width: 100% !important; 98 | overflow: hidden; 99 | *zoom: 1; 100 | } 101 | 102 | .icon_lists li { 103 | width: 100px; 104 | margin-bottom: 10px; 105 | margin-right: 20px; 106 | text-align: center; 107 | list-style: none !important; 108 | cursor: default; 109 | } 110 | 111 | .icon_lists li .code-name { 112 | line-height: 1.2; 113 | } 114 | 115 | .icon_lists .icon { 116 | display: block; 117 | height: 100px; 118 | line-height: 100px; 119 | font-size: 42px; 120 | margin: 10px auto; 121 | color: #333; 122 | -webkit-transition: font-size 0.25s linear, width 0.25s linear; 123 | -moz-transition: font-size 0.25s linear, width 0.25s linear; 124 | transition: font-size 0.25s linear, width 0.25s linear; 125 | } 126 | 127 | .icon_lists .icon:hover { 128 | font-size: 100px; 129 | } 130 | 131 | .icon_lists .svg-icon { 132 | /* 通过设置 font-size 来改变图标大小 */ 133 | width: 1em; 134 | /* 图标和文字相邻时,垂直对齐 */ 135 | vertical-align: -0.15em; 136 | /* 通过设置 color 来改变 SVG 的颜色/fill */ 137 | fill: currentColor; 138 | /* path 和 stroke 溢出 viewBox 部分在 IE 下会显示 139 | normalize.css 中也包含这行 */ 140 | overflow: hidden; 141 | } 142 | 143 | .icon_lists li .name, 144 | .icon_lists li .code-name { 145 | color: #666; 146 | } 147 | 148 | /* markdown 样式 */ 149 | .markdown { 150 | color: #666; 151 | font-size: 14px; 152 | line-height: 1.8; 153 | } 154 | 155 | .highlight { 156 | line-height: 1.5; 157 | } 158 | 159 | .markdown img { 160 | vertical-align: middle; 161 | max-width: 100%; 162 | } 163 | 164 | .markdown h1 { 165 | color: #404040; 166 | font-weight: 500; 167 | line-height: 40px; 168 | margin-bottom: 24px; 169 | } 170 | 171 | .markdown h2, 172 | .markdown h3, 173 | .markdown h4, 174 | .markdown h5, 175 | .markdown h6 { 176 | color: #404040; 177 | margin: 1.6em 0 0.6em 0; 178 | font-weight: 500; 179 | clear: both; 180 | } 181 | 182 | .markdown h1 { 183 | font-size: 28px; 184 | } 185 | 186 | .markdown h2 { 187 | font-size: 22px; 188 | } 189 | 190 | .markdown h3 { 191 | font-size: 16px; 192 | } 193 | 194 | .markdown h4 { 195 | font-size: 14px; 196 | } 197 | 198 | .markdown h5 { 199 | font-size: 12px; 200 | } 201 | 202 | .markdown h6 { 203 | font-size: 12px; 204 | } 205 | 206 | .markdown hr { 207 | height: 1px; 208 | border: 0; 209 | background: #e9e9e9; 210 | margin: 16px 0; 211 | clear: both; 212 | } 213 | 214 | .markdown p { 215 | margin: 1em 0; 216 | } 217 | 218 | .markdown>p, 219 | .markdown>blockquote, 220 | .markdown>.highlight, 221 | .markdown>ol, 222 | .markdown>ul { 223 | width: 80%; 224 | } 225 | 226 | .markdown ul>li { 227 | list-style: circle; 228 | } 229 | 230 | .markdown>ul li, 231 | .markdown blockquote ul>li { 232 | margin-left: 20px; 233 | padding-left: 4px; 234 | } 235 | 236 | .markdown>ul li p, 237 | .markdown>ol li p { 238 | margin: 0.6em 0; 239 | } 240 | 241 | .markdown ol>li { 242 | list-style: decimal; 243 | } 244 | 245 | .markdown>ol li, 246 | .markdown blockquote ol>li { 247 | margin-left: 20px; 248 | padding-left: 4px; 249 | } 250 | 251 | .markdown code { 252 | margin: 0 3px; 253 | padding: 0 5px; 254 | background: #eee; 255 | border-radius: 3px; 256 | } 257 | 258 | .markdown strong, 259 | .markdown b { 260 | font-weight: 600; 261 | } 262 | 263 | .markdown>table { 264 | border-collapse: collapse; 265 | border-spacing: 0px; 266 | empty-cells: show; 267 | border: 1px solid #e9e9e9; 268 | width: 95%; 269 | margin-bottom: 24px; 270 | } 271 | 272 | .markdown>table th { 273 | white-space: nowrap; 274 | color: #333; 275 | font-weight: 600; 276 | } 277 | 278 | .markdown>table th, 279 | .markdown>table td { 280 | border: 1px solid #e9e9e9; 281 | padding: 8px 16px; 282 | text-align: left; 283 | } 284 | 285 | .markdown>table th { 286 | background: #F7F7F7; 287 | } 288 | 289 | .markdown blockquote { 290 | font-size: 90%; 291 | color: #999; 292 | border-left: 4px solid #e9e9e9; 293 | padding-left: 0.8em; 294 | margin: 1em 0; 295 | } 296 | 297 | .markdown blockquote p { 298 | margin: 0; 299 | } 300 | 301 | .markdown .anchor { 302 | opacity: 0; 303 | transition: opacity 0.3s ease; 304 | margin-left: 8px; 305 | } 306 | 307 | .markdown .waiting { 308 | color: #ccc; 309 | } 310 | 311 | .markdown h1:hover .anchor, 312 | .markdown h2:hover .anchor, 313 | .markdown h3:hover .anchor, 314 | .markdown h4:hover .anchor, 315 | .markdown h5:hover .anchor, 316 | .markdown h6:hover .anchor { 317 | opacity: 1; 318 | display: inline-block; 319 | } 320 | 321 | .markdown>br, 322 | .markdown>p>br { 323 | clear: both; 324 | } 325 | 326 | 327 | .hljs { 328 | display: block; 329 | background: white; 330 | padding: 0.5em; 331 | color: #333333; 332 | overflow-x: auto; 333 | } 334 | 335 | .hljs-comment, 336 | .hljs-meta { 337 | color: #969896; 338 | } 339 | 340 | .hljs-string, 341 | .hljs-variable, 342 | .hljs-template-variable, 343 | .hljs-strong, 344 | .hljs-emphasis, 345 | .hljs-quote { 346 | color: #df5000; 347 | } 348 | 349 | .hljs-keyword, 350 | .hljs-selector-tag, 351 | .hljs-type { 352 | color: #a71d5d; 353 | } 354 | 355 | .hljs-literal, 356 | .hljs-symbol, 357 | .hljs-bullet, 358 | .hljs-attribute { 359 | color: #0086b3; 360 | } 361 | 362 | .hljs-section, 363 | .hljs-name { 364 | color: #63a35c; 365 | } 366 | 367 | .hljs-tag { 368 | color: #333333; 369 | } 370 | 371 | .hljs-title, 372 | .hljs-attr, 373 | .hljs-selector-id, 374 | .hljs-selector-class, 375 | .hljs-selector-attr, 376 | .hljs-selector-pseudo { 377 | color: #795da3; 378 | } 379 | 380 | .hljs-addition { 381 | color: #55a532; 382 | background-color: #eaffea; 383 | } 384 | 385 | .hljs-deletion { 386 | color: #bd2c00; 387 | background-color: #ffecec; 388 | } 389 | 390 | .hljs-link { 391 | text-decoration: underline; 392 | } 393 | 394 | /* 代码高亮 */ 395 | /* PrismJS 1.15.0 396 | https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */ 397 | /** 398 | * prism.js default theme for JavaScript, CSS and HTML 399 | * Based on dabblet (http://dabblet.com) 400 | * @author Lea Verou 401 | */ 402 | code[class*="language-"], 403 | pre[class*="language-"] { 404 | color: black; 405 | background: none; 406 | text-shadow: 0 1px white; 407 | font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; 408 | text-align: left; 409 | white-space: pre; 410 | word-spacing: normal; 411 | word-break: normal; 412 | word-wrap: normal; 413 | line-height: 1.5; 414 | 415 | -moz-tab-size: 4; 416 | -o-tab-size: 4; 417 | tab-size: 4; 418 | 419 | -webkit-hyphens: none; 420 | -moz-hyphens: none; 421 | -ms-hyphens: none; 422 | hyphens: none; 423 | } 424 | 425 | pre[class*="language-"]::-moz-selection, 426 | pre[class*="language-"] ::-moz-selection, 427 | code[class*="language-"]::-moz-selection, 428 | code[class*="language-"] ::-moz-selection { 429 | text-shadow: none; 430 | background: #b3d4fc; 431 | } 432 | 433 | pre[class*="language-"]::selection, 434 | pre[class*="language-"] ::selection, 435 | code[class*="language-"]::selection, 436 | code[class*="language-"] ::selection { 437 | text-shadow: none; 438 | background: #b3d4fc; 439 | } 440 | 441 | @media print { 442 | 443 | code[class*="language-"], 444 | pre[class*="language-"] { 445 | text-shadow: none; 446 | } 447 | } 448 | 449 | /* Code blocks */ 450 | pre[class*="language-"] { 451 | padding: 1em; 452 | margin: .5em 0; 453 | overflow: auto; 454 | } 455 | 456 | :not(pre)>code[class*="language-"], 457 | pre[class*="language-"] { 458 | background: #f5f2f0; 459 | } 460 | 461 | /* Inline code */ 462 | :not(pre)>code[class*="language-"] { 463 | padding: .1em; 464 | border-radius: .3em; 465 | white-space: normal; 466 | } 467 | 468 | .token.comment, 469 | .token.prolog, 470 | .token.doctype, 471 | .token.cdata { 472 | color: slategray; 473 | } 474 | 475 | .token.punctuation { 476 | color: #999; 477 | } 478 | 479 | .namespace { 480 | opacity: .7; 481 | } 482 | 483 | .token.property, 484 | .token.tag, 485 | .token.boolean, 486 | .token.number, 487 | .token.constant, 488 | .token.symbol, 489 | .token.deleted { 490 | color: #905; 491 | } 492 | 493 | .token.selector, 494 | .token.attr-name, 495 | .token.string, 496 | .token.char, 497 | .token.builtin, 498 | .token.inserted { 499 | color: #690; 500 | } 501 | 502 | .token.operator, 503 | .token.entity, 504 | .token.url, 505 | .language-css .token.string, 506 | .style .token.string { 507 | color: #9a6e3a; 508 | background: hsla(0, 0%, 100%, .5); 509 | } 510 | 511 | .token.atrule, 512 | .token.attr-value, 513 | .token.keyword { 514 | color: #07a; 515 | } 516 | 517 | .token.function, 518 | .token.class-name { 519 | color: #DD4A68; 520 | } 521 | 522 | .token.regex, 523 | .token.important, 524 | .token.variable { 525 | color: #e90; 526 | } 527 | 528 | .token.important, 529 | .token.bold { 530 | font-weight: bold; 531 | } 532 | 533 | .token.italic { 534 | font-style: italic; 535 | } 536 | 537 | .token.entity { 538 | cursor: help; 539 | } 540 | -------------------------------------------------------------------------------- /packages/iconfont-adapter/font/demo_index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IconFont Demo 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 |

19 | 29 |
30 |
31 |
    32 | 33 |
  • 34 | 35 |
    arrow_right
    36 |
    &#xe666;
    37 |
  • 38 | 39 |
  • 40 | 41 |
    arrow_under
    42 |
    &#xe667;
    43 |
  • 44 | 45 |
  • 46 | 47 |
    arrow_on
    48 |
    &#xe668;
    49 |
  • 50 | 51 |
  • 52 | 53 |
    close_pop
    54 |
    &#xe669;
    55 |
  • 56 | 57 |
  • 58 | 59 |
    nav_back
    60 |
    &#xe671;
    61 |
  • 62 | 63 |
  • 64 | 65 |
    select_down_radio
    66 |
    &#xe672;
    67 |
  • 68 | 69 |
  • 70 | 71 |
    nav_search
    72 |
    &#xe673;
    73 |
  • 74 | 75 |
  • 76 | 77 |
    select_up
    78 |
    &#xe675;
    79 |
  • 80 | 81 |
  • 82 | 83 |
    warning
    84 |
    &#xe674;
    85 |
  • 86 | 87 |
  • 88 | 89 |
    success
    90 |
    &#xe676;
    91 |
  • 92 | 93 |
  • 94 | 95 |
    failure
    96 |
    &#xe677;
    97 |
  • 98 | 99 |
  • 100 | 101 |
    wait
    102 |
    &#xe678;
    103 |
  • 104 | 105 |
  • 106 | 107 |
    prompt
    108 |
    &#xe679;
    109 |
  • 110 | 111 |
  • 112 | 113 |
    delete
    114 |
    &#xe67a;
    115 |
  • 116 | 117 |
118 |
119 |

Unicode 引用

120 |
121 | 122 |

Unicode 是字体在网页端最原始的应用方式,特点是:

123 |
    124 |
  • 兼容性最好,支持 IE6+,及所有现代浏览器。
  • 125 |
  • 支持按字体的方式去动态调整图标大小,颜色等等。
  • 126 |
  • 但是因为是字体,所以不支持多色。只能使用平台里单色的图标,就算项目里有多色图标也会自动去色。
  • 127 |
128 |
129 |

注意:新版 iconfont 支持多色图标,这些多色图标在 Unicode 模式下将不能使用,如果有需求建议使用symbol 的引用方式

130 |
131 |

Unicode 使用步骤如下:

132 |

第一步:拷贝项目下面生成的 @font-face

133 |
@font-face {
135 |   font-family: 'iconfont';
136 |   src: url('iconfont.eot');
137 |   src: url('iconfont.eot?#iefix') format('embedded-opentype'),
138 |       url('iconfont.woff2') format('woff2'),
139 |       url('iconfont.woff') format('woff'),
140 |       url('iconfont.ttf') format('truetype'),
141 |       url('iconfont.svg#iconfont') format('svg');
142 | }
143 | 
144 |

第二步:定义使用 iconfont 的样式

145 |
.iconfont {
147 |   font-family: "iconfont" !important;
148 |   font-size: 16px;
149 |   font-style: normal;
150 |   -webkit-font-smoothing: antialiased;
151 |   -moz-osx-font-smoothing: grayscale;
152 | }
153 | 
154 |

第三步:挑选相应图标并获取字体编码,应用于页面

155 |
156 | <span class="iconfont">&#x33;</span>
158 | 
159 |
160 |

"iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。

161 |
162 |
163 |
164 |
165 |
    166 | 167 |
  • 168 | 169 |
    170 | arrow_right 171 |
    172 |
    .iconarrow_right 173 |
    174 |
  • 175 | 176 |
  • 177 | 178 |
    179 | arrow_under 180 |
    181 |
    .iconarrow_under 182 |
    183 |
  • 184 | 185 |
  • 186 | 187 |
    188 | arrow_on 189 |
    190 |
    .iconarrow_on 191 |
    192 |
  • 193 | 194 |
  • 195 | 196 |
    197 | close_pop 198 |
    199 |
    .iconclose_pop 200 |
    201 |
  • 202 | 203 |
  • 204 | 205 |
    206 | nav_back 207 |
    208 |
    .iconnav_back 209 |
    210 |
  • 211 | 212 |
  • 213 | 214 |
    215 | select_down_radio 216 |
    217 |
    .iconselect_down_radio 218 |
    219 |
  • 220 | 221 |
  • 222 | 223 |
    224 | nav_search 225 |
    226 |
    .iconnav_search 227 |
    228 |
  • 229 | 230 |
  • 231 | 232 |
    233 | select_up 234 |
    235 |
    .iconselect_up 236 |
    237 |
  • 238 | 239 |
  • 240 | 241 |
    242 | warning 243 |
    244 |
    .iconwarning 245 |
    246 |
  • 247 | 248 |
  • 249 | 250 |
    251 | success 252 |
    253 |
    .iconsuccess 254 |
    255 |
  • 256 | 257 |
  • 258 | 259 |
    260 | failure 261 |
    262 |
    .iconfailure 263 |
    264 |
  • 265 | 266 |
  • 267 | 268 |
    269 | wait 270 |
    271 |
    .iconwait 272 |
    273 |
  • 274 | 275 |
  • 276 | 277 |
    278 | prompt 279 |
    280 |
    .iconprompt 281 |
    282 |
  • 283 | 284 |
  • 285 | 286 |
    287 | delete 288 |
    289 |
    .icondelete 290 |
    291 |
  • 292 | 293 |
294 |
295 |

font-class 引用

296 |
297 | 298 |

font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。

299 |

与 Unicode 使用方式相比,具有如下特点:

300 |
    301 |
  • 兼容性良好,支持 IE8+,及所有现代浏览器。
  • 302 |
  • 相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。
  • 303 |
  • 因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。
  • 304 |
  • 不过因为本质上还是使用的字体,所以多色图标还是不支持的。
  • 305 |
306 |

使用步骤如下:

307 |

第一步:引入项目下面生成的 fontclass 代码:

308 |
<link rel="stylesheet" href="./iconfont.css">
309 | 
310 |

第二步:挑选相应图标并获取类名,应用于页面:

311 |
<span class="iconfont iconxxx"></span>
312 | 
313 |
314 |

" 315 | iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。

316 |
317 |
318 |
319 |
320 |
    321 | 322 |
  • 323 | 326 |
    arrow_right
    327 |
    #iconarrow_right
    328 |
  • 329 | 330 |
  • 331 | 334 |
    arrow_under
    335 |
    #iconarrow_under
    336 |
  • 337 | 338 |
  • 339 | 342 |
    arrow_on
    343 |
    #iconarrow_on
    344 |
  • 345 | 346 |
  • 347 | 350 |
    close_pop
    351 |
    #iconclose_pop
    352 |
  • 353 | 354 |
  • 355 | 358 |
    nav_back
    359 |
    #iconnav_back
    360 |
  • 361 | 362 |
  • 363 | 366 |
    select_down_radio
    367 |
    #iconselect_down_radio
    368 |
  • 369 | 370 |
  • 371 | 374 |
    nav_search
    375 |
    #iconnav_search
    376 |
  • 377 | 378 |
  • 379 | 382 |
    select_up
    383 |
    #iconselect_up
    384 |
  • 385 | 386 |
  • 387 | 390 |
    warning
    391 |
    #iconwarning
    392 |
  • 393 | 394 |
  • 395 | 398 |
    success
    399 |
    #iconsuccess
    400 |
  • 401 | 402 |
  • 403 | 406 |
    failure
    407 |
    #iconfailure
    408 |
  • 409 | 410 |
  • 411 | 414 |
    wait
    415 |
    #iconwait
    416 |
  • 417 | 418 |
  • 419 | 422 |
    prompt
    423 |
    #iconprompt
    424 |
  • 425 | 426 |
  • 427 | 430 |
    delete
    431 |
    #icondelete
    432 |
  • 433 | 434 |
435 |
436 |

Symbol 引用

437 |
438 | 439 |

这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇文章 440 | 这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:

441 |
    442 |
  • 支持多色图标了,不再受单色限制。
  • 443 |
  • 通过一些技巧,支持像字体那样,通过 font-size, color 来调整样式。
  • 444 |
  • 兼容性较差,支持 IE9+,及现代浏览器。
  • 445 |
  • 浏览器渲染 SVG 的性能一般,还不如 png。
  • 446 |
447 |

使用步骤如下:

448 |

第一步:引入项目下面生成的 symbol 代码:

449 |
<script src="./iconfont.js"></script>
450 | 
451 |

第二步:加入通用 CSS 代码(引入一次就行):

452 |
<style>
453 | .icon {
454 |   width: 1em;
455 |   height: 1em;
456 |   vertical-align: -0.15em;
457 |   fill: currentColor;
458 |   overflow: hidden;
459 | }
460 | </style>
461 | 
462 |

第三步:挑选相应图标并获取类名,应用于页面:

463 |
<svg class="icon" aria-hidden="true">
464 |   <use xlink:href="#icon-xxx"></use>
465 | </svg>
466 | 
467 |
468 |
469 | 470 |
471 |
472 | 491 | 492 | 493 | -------------------------------------------------------------------------------- /packages/iconfont-adapter/font/iconfont.css: -------------------------------------------------------------------------------- 1 | @font-face {font-family: "iconfont"; 2 | src: url('iconfont.eot?t=1557322756059'); /* IE9 */ 3 | src: url('iconfont.eot?t=1557322756059#iefix') format('embedded-opentype'), /* IE6-IE8 */ 4 | url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'), 5 | url('iconfont.woff?t=1557322756059') format('woff'), 6 | url('iconfont.ttf?t=1557322756059') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */ 7 | url('iconfont.svg?t=1557322756059#iconfont') format('svg'); /* iOS 4.1- */ 8 | } 9 | 10 | .iconfont { 11 | font-family: "iconfont" !important; 12 | font-size: 16px; 13 | font-style: normal; 14 | -webkit-font-smoothing: antialiased; 15 | -moz-osx-font-smoothing: grayscale; 16 | } 17 | 18 | .iconarrow_right:before { 19 | content: "\e666"; 20 | } 21 | 22 | .iconarrow_under:before { 23 | content: "\e667"; 24 | } 25 | 26 | .iconarrow_on:before { 27 | content: "\e668"; 28 | } 29 | 30 | .iconclose_pop:before { 31 | content: "\e669"; 32 | } 33 | 34 | .iconnav_back:before { 35 | content: "\e671"; 36 | } 37 | 38 | .iconselect_down_radio:before { 39 | content: "\e672"; 40 | } 41 | 42 | .iconnav_search:before { 43 | content: "\e673"; 44 | } 45 | 46 | .iconselect_up:before { 47 | content: "\e675"; 48 | } 49 | 50 | .iconwarning:before { 51 | content: "\e674"; 52 | } 53 | 54 | .iconsuccess:before { 55 | content: "\e676"; 56 | } 57 | 58 | .iconfailure:before { 59 | content: "\e677"; 60 | } 61 | 62 | .iconwait:before { 63 | content: "\e678"; 64 | } 65 | 66 | .iconprompt:before { 67 | content: "\e679"; 68 | } 69 | 70 | .icondelete:before { 71 | content: "\e67a"; 72 | } 73 | 74 | -------------------------------------------------------------------------------- /packages/iconfont-adapter/font/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fe-go/fe-cli/8c1ae45b60747197acec7e10a184625968a86b1a/packages/iconfont-adapter/font/iconfont.eot -------------------------------------------------------------------------------- /packages/iconfont-adapter/font/iconfont.js: -------------------------------------------------------------------------------- 1 | !function(l){var t,o='',e=(t=document.getElementsByTagName("script"))[t.length-1].getAttribute("data-injectcss");if(e&&!l.__iconfont__svg__cssinject__){l.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(t){console&&console.log(t)}}!function(t){if(document.addEventListener)if(~["complete","loaded","interactive"].indexOf(document.readyState))setTimeout(t,0);else{var e=function(){document.removeEventListener("DOMContentLoaded",e,!1),t()};document.addEventListener("DOMContentLoaded",e,!1)}else document.attachEvent&&(o=t,a=l.document,i=!1,n=function(){i||(i=!0,o())},(c=function(){try{a.documentElement.doScroll("left")}catch(t){return void setTimeout(c,50)}n()})(),a.onreadystatechange=function(){"complete"==a.readyState&&(a.onreadystatechange=null,n())});var o,a,i,n,c}(function(){var t,e;(t=document.createElement("div")).innerHTML=o,o=null,(e=t.getElementsByTagName("svg")[0])&&(e.setAttribute("aria-hidden","true"),e.style.position="absolute",e.style.width=0,e.style.height=0,e.style.overflow="hidden",function(t,e){e.firstChild?function(t,e){e.parentNode.insertBefore(t,e)}(t,e.firstChild):e.appendChild(t)}(e,document.body))})}(window); -------------------------------------------------------------------------------- /packages/iconfont-adapter/font/iconfont.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | Created by iconfont 9 | 10 | 11 | 12 | 13 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /packages/iconfont-adapter/font/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fe-go/fe-cli/8c1ae45b60747197acec7e10a184625968a86b1a/packages/iconfont-adapter/font/iconfont.ttf -------------------------------------------------------------------------------- /packages/iconfont-adapter/font/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fe-go/fe-cli/8c1ae45b60747197acec7e10a184625968a86b1a/packages/iconfont-adapter/font/iconfont.woff -------------------------------------------------------------------------------- /packages/iconfont-adapter/font/iconfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fe-go/fe-cli/8c1ae45b60747197acec7e10a184625968a86b1a/packages/iconfont-adapter/font/iconfont.woff2 -------------------------------------------------------------------------------- /packages/iconfont-adapter/iconfont.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | fontSize: 36, 3 | pattern: 'camelCase', 4 | src: 'font', 5 | dest: 'assets' 6 | } 7 | -------------------------------------------------------------------------------- /packages/iconfont-adapter/index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | const mime = require('mime-types') 4 | const _ = require('lodash') 5 | const config = require('./iconfont.config') 6 | /** 7 | * 8 | * @param {string} filePath 文件路径 9 | */ 10 | function convert2base64 (filePath) { 11 | let data = fs.readFileSync(path.resolve(filePath)) 12 | data = Buffer.from(data).toString('base64') 13 | // return 'data:' + mime.lookup(filePath) + ';base64,' + data 14 | 15 | return 'data:' + mime.lookup(filePath) + ';charset=utf-8' + ';base64,' + data 16 | } 17 | 18 | /** 19 | * 将iconfont css 源文件转化为想要的形式 20 | * @param {string} filePath 文件路径 21 | */ 22 | function convertIconfont (filePath) { 23 | const str = fs.readFileSync(path.resolve(filePath)).toString() 24 | const matchNames = [] 25 | const arr = str.split(/\n/g) 26 | let destCss = arr 27 | .slice(9) 28 | .join('\n') 29 | .replace(/font-size: (\d)+px;/, `font-size: ${config.fontSize}px;`) 30 | destCss = destCss.replace(/icon([\w-]*):/g, (match, $1) => { 31 | let className = _[config.pattern]($1) 32 | matchNames.push(className) 33 | return `icon-${className}:` 34 | }) 35 | 36 | const base64 = convert2base64(path.join(config.src, 'iconfont.ttf')) 37 | 38 | const template = `@font-face { 39 | font-family: "iconfont"; 40 | src: url('${base64}') format('truetype'); 41 | } 42 | 43 | ${destCss}` 44 | 45 | fs.writeFileSync(`${config.dest}/iconfont.css`, template) 46 | fs.writeFileSync( 47 | path.join(config.dest, 'iconType.ts'), 48 | convertMatchNames(matchNames) 49 | ) 50 | } 51 | /** 52 | * 将匹配的class name 转换为 typescript type 53 | * @param {Array} matchNames matchNames 54 | */ 55 | function convertMatchNames (matchNames) { 56 | const matchType = matchNames.join(`' | '`) 57 | 58 | return `export type iconType = '${matchType}' 59 | export const icons = ${JSON.stringify(matchNames)} 60 | ` 61 | } 62 | 63 | function main () { 64 | if (!fs.existsSync(config.dest)) fs.mkdirSync(config.dest) 65 | convertIconfont(path.join(config.src, 'iconfont.css')) 66 | } 67 | main() 68 | -------------------------------------------------------------------------------- /packages/iconfont-adapter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "base64", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "lodash": "^4.17.11", 13 | "mime-types": "^2.1.24" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/iconfont-adapter/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | lodash@^4.17.11: 6 | version "4.17.11" 7 | resolved "https://registry.npm.taobao.org/lodash/download/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" 8 | integrity sha1-s56mIp72B+zYniyN8SU2iRysm40= 9 | 10 | mime-db@1.40.0: 11 | version "1.40.0" 12 | resolved "https://registry.npm.taobao.org/mime-db/download/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" 13 | integrity sha1-plBX6ZjbCQ9zKmj2wnbTh9QSbDI= 14 | 15 | mime-types@^2.1.24: 16 | version "2.1.24" 17 | resolved "https://registry.npm.taobao.org/mime-types/download/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" 18 | integrity sha1-tvjQs+lR77d97eyhlM/20W9nb4E= 19 | dependencies: 20 | mime-db "1.40.0" 21 | -------------------------------------------------------------------------------- /packages/index-creater/.eslintignore: -------------------------------------------------------------------------------- 1 | example/**/*.* -------------------------------------------------------------------------------- /packages/index-creater/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | commonjs: true, 5 | es6: true 6 | }, 7 | extends: 'eslint:recommended', 8 | parserOptions: { 9 | ecmaVersion: 2018, 10 | sourceType: 'module' 11 | }, 12 | rules: { 13 | indent: ['error', 4], 14 | 'linebreak-style': ['error', 'unix'], 15 | quotes: ['error', 'single'], 16 | semi: ['error', 'never'], 17 | 'no-console': 1 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/index-creater/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /packages/index-creater/.npmignore: -------------------------------------------------------------------------------- 1 | example -------------------------------------------------------------------------------- /packages/index-creater/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | 8 | { 9 | "type": "node", 10 | "request": "attach", 11 | "name": "Attach", 12 | "port": 9229 13 | }, 14 | { 15 | "type": "node", 16 | "request": "launch", 17 | "cwd": "${workspaceFolder}/example", 18 | "name": "Launch Program", 19 | "program": "${workspaceFolder}/example/index.js" 20 | } 21 | ] 22 | } -------------------------------------------------------------------------------- /packages/index-creater/README.md: -------------------------------------------------------------------------------- 1 | # index-creater 2 | 3 | --- 4 | 5 | 根据指定的形式自动生成目录的索引 6 | 7 | ## index-creater 的目的 8 | 9 | 假设有目录结构如下,自动生成 componets 的索引文件 index.js 10 | 11 | ```bash 12 | - componets 13 | + button 14 | - index.js 15 | + foo-bar 16 | - index.js 17 | + nest 18 | + child-nest 19 | - index.js 20 | + grandson-nest 21 | - index.js 22 | ``` 23 | 24 | 自动生成 components/index.js 25 | 26 | ```js 27 | export { default as Button, IButtonProps } from "./button"; 28 | export { default as FooBar, IFooBarProps } from "./foo-bar"; 29 | export { default as Nest, INestProps } from "./nest"; 30 | export { default as ChildNest, IChildNestProps } from "./nest/child-nest"; 31 | export { default as GrandsonNest, IGrandsonNestProps } from "./nest/child-nest/grandson-nest"; 32 | ``` 33 | 34 | ## 安装 35 | 36 | ```bash 37 | $ npm install index-render 38 | ``` 39 | 40 | ## code example 41 | 42 | ```js 43 | const indexCreater = require("../index"); 44 | 45 | indexCreater([ 46 | { 47 | root: 'components', // 绝对路径或者现对路径,如果是相对路径会通过path.resolve转为绝对路径 48 | match: '**/!(*.*)', // 此处参数为glob类型 49 | separator: /(-|_)/g, 50 | exportPattern: 'export { default as [name] , I[name]Props } from \'[path]\'', 51 | ignore: 'button', // glob pattern 或者 glob pattern Array 52 | suffix: '.ts', 53 | callback(template, items) { 54 | return template + '\n// test' 55 | } 56 | }, 57 | { 58 | root: 'otherComponents', 59 | match: '**/!(*.*)', // 此处参数为glob类型 60 | separator: /(-|_)/g, 61 | exportPattern: 'export { default as [name] } from \'[path]\'', 62 | suffix: '.jsx' 63 | }, 64 | // exportPattern 没有填将自动解析 glob 匹配文件的 export 65 | { 66 | root: 'autoComponents', 67 | match: '*/index.*', 68 | separator: /(-|_)/g, 69 | suffix: '.js' 70 | } 71 | ]) 72 | 73 | 74 | ``` 75 | ## 自动解析文件export 功能 76 | 77 | `exportPattern` 如果没配置自动解析 `glob` 匹配文件的 `export` 78 | 79 | ### 假设匹配的文件内容如下 80 | 81 | ```js 82 | export default class foo {} 83 | export const fooVar = 0 84 | ``` 85 | ### 那么生成的`index.js`将自动解析出`export` 86 | 87 | ```js 88 | export { default as Foo, fooVar } from './foo/index.js' 89 | ``` 90 | 详见`example/autoComponents/` 91 | 92 | 目前不支持解析`export * from "mod"`的玩法 93 | 94 | **感谢**[iZhen](https://github.com/iZhen)添加的自动解析文件`export`功能 95 | 96 | ## API 97 | 98 | - `@prop` {String} root 要生成索引的根目录,绝对路径或者现对路径,如果是相对路径会通过path.resolve转为绝对路径 99 | - `@prop` {String} match 子模块的匹配规则 glob pattern 100 | - `@prop` {Regex} separator 子模块目录(文件)命名分割符默认为 /(-|_)/g 101 | - `@prop` {String} exportPattern 子模块导出模板,如果不填`index-creater`将尝试自动解析`glob`匹配的文件`export` 102 | - `@prop` {String} suffix 生成index文件的后缀默认为 '.js' 103 | - `@prop` {String|Array} ignore glob pattern or glob pattern array 104 | - `@prop` {(template,items)=>String} callback 自定义回调函数,template 为引进生成的文件模板,items 匹配的文件信息,返回值为新的模板 105 | 106 | 107 | -------------------------------------------------------------------------------- /packages/index-creater/example/README.md: -------------------------------------------------------------------------------- 1 | # auto-index demo 2 | 3 | --- 4 | 5 | ```bash 6 | $ node index.js 7 | ``` 8 | -------------------------------------------------------------------------------- /packages/index-creater/example/autoComponents/foo-bar-baz/index.js: -------------------------------------------------------------------------------- 1 | import { qux1 } from './qux' 2 | export default function fun() {} 3 | export { qux1 } 4 | -------------------------------------------------------------------------------- /packages/index-creater/example/autoComponents/foo-bar-baz/qux.js: -------------------------------------------------------------------------------- 1 | const value = 0 2 | export class quxCls {} 3 | export function quxFunc() {} 4 | export const quxVar1 = 0, quxVar2 = 0 5 | export { value as qux1, qux2 } 6 | -------------------------------------------------------------------------------- /packages/index-creater/example/autoComponents/foo/bar.js: -------------------------------------------------------------------------------- 1 | export default function bar() {} 2 | export let barVar = 0 3 | -------------------------------------------------------------------------------- /packages/index-creater/example/autoComponents/foo/baz/index.js: -------------------------------------------------------------------------------- 1 | export default 1 2 | export var bazVar = 0 3 | -------------------------------------------------------------------------------- /packages/index-creater/example/autoComponents/foo/index.js: -------------------------------------------------------------------------------- 1 | export default class foo {} 2 | export const fooVar = 0 3 | -------------------------------------------------------------------------------- /packages/index-creater/example/autoComponents/index.js: -------------------------------------------------------------------------------- 1 | export { default as FooBarBaz, qux1 } from './foo-bar-baz/index.js' 2 | export { default as Foo, fooVar } from './foo/index.js' 3 | -------------------------------------------------------------------------------- /packages/index-creater/example/components/button/index.js: -------------------------------------------------------------------------------- 1 | export default class Button {} 2 | export const IButtonProps = {} 3 | -------------------------------------------------------------------------------- /packages/index-creater/example/components/foo-bar/index.js: -------------------------------------------------------------------------------- 1 | // 占位 2 | -------------------------------------------------------------------------------- /packages/index-creater/example/components/index.ts: -------------------------------------------------------------------------------- 1 | export { default as FooBar , IFooBarProps } from '.foo-bar' 2 | export { default as Nest , INestProps } from '.nest' 3 | export { default as ChildNest , IChildNestProps } from './nestchild-nest' 4 | export { default as GrandsonNest , IGrandsonNestProps } from './nest/child-nestgrandson-nest' 5 | // test 6 | -------------------------------------------------------------------------------- /packages/index-creater/example/components/nest/child-nest/grandson-nest/index.js: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------- /packages/index-creater/example/components/nest/child-nest/index.js: -------------------------------------------------------------------------------- 1 | // 占位 -------------------------------------------------------------------------------- /packages/index-creater/example/components/nest/index.js: -------------------------------------------------------------------------------- 1 | export default class Switch {} 2 | export const ISwitchProps = {} 3 | -------------------------------------------------------------------------------- /packages/index-creater/example/index.js: -------------------------------------------------------------------------------- 1 | const indexCreater = require('../index') 2 | 3 | indexCreater([ 4 | { 5 | root: 'components', // 绝对路径或者现对路径,如果是相对路径会通过path.resolve转为绝对路径 6 | match: '**/!(*.*)', // 此处参数为glob类型 7 | separator: /(-|_)/g, 8 | exportPattern: 9 | "export { default as [name] , I[name]Props } from '[path]'", 10 | ignore: 'button', // glob pattern 或者 glob pattern Array 11 | suffix: '.ts', 12 | callback(template, items) { 13 | return template + '\n// test' 14 | } 15 | }, 16 | { 17 | root: 'otherComponents', 18 | match: '**/!(*.*)', // 此处参数为glob类型 19 | separator: /(-|_)/g, 20 | exportPattern: "export { default as [name] } from '[path]'", 21 | suffix: '.jsx' 22 | }, 23 | { 24 | root: 'autoComponents', 25 | match: '*/index.*', 26 | separator: /(-|_)/g, 27 | suffix: '.js' 28 | } 29 | ]) 30 | -------------------------------------------------------------------------------- /packages/index-creater/example/otherComponents/button/index.js: -------------------------------------------------------------------------------- 1 | export default class Button {} 2 | export const IButtonProps = {} 3 | -------------------------------------------------------------------------------- /packages/index-creater/example/otherComponents/foo-bar/index.js: -------------------------------------------------------------------------------- 1 | // 占位 -------------------------------------------------------------------------------- /packages/index-creater/example/otherComponents/index.jsx: -------------------------------------------------------------------------------- 1 | export { default as Button } from '.button' 2 | export { default as FooBar } from '.foo-bar' 3 | export { default as Nest } from '.nest' 4 | export { default as ChildNest } from './nestchild-nest' 5 | export { default as GrandsonNest } from './nest/child-nestgrandson-nest' 6 | -------------------------------------------------------------------------------- /packages/index-creater/example/otherComponents/nest/child-nest/grandson-nest/index.js: -------------------------------------------------------------------------------- 1 | // -------------------------------------------------------------------------------- /packages/index-creater/example/otherComponents/nest/child-nest/index.js: -------------------------------------------------------------------------------- 1 | // 占位 -------------------------------------------------------------------------------- /packages/index-creater/example/otherComponents/nest/index.js: -------------------------------------------------------------------------------- 1 | export default class Switch {} 2 | export const ISwitchProps = {} 3 | -------------------------------------------------------------------------------- /packages/index-creater/index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | const chalk = require('chalk') 4 | const { 5 | fileInfoParse, 6 | fileInfoParseAutoExport 7 | } = require('./lib/fileInfoParse') 8 | 9 | /** 10 | * @param {Object|Array} config 11 | * @prop {String} match 子模块的匹配规则 glob pattern 12 | * @prop {Regex} separator 子模块目录(文件)命名分割符默认为 /(-|_)/g 13 | * @prop {String} exportPattern 子模块导出模板 14 | * @prop {String} suffix 生成index文件的后缀默认为 '.js' 15 | * @prop {String|Array} ignore glob pattern or glob pattern array 16 | * @prop {(template,items)=>String} callback 自定义回调函数,template 为引进生成的文件模板,items 匹配的文件信息,返回值为新的模板 17 | */ 18 | function createIndex(options = {}) { 19 | const { 20 | match, 21 | root, 22 | separator = /(-|_)/g, 23 | exportPattern, 24 | suffix = 'js', 25 | ignore = false, 26 | callback = () => {}, 27 | output 28 | } = options 29 | const rootPath = path.resolve(root) 30 | const outPath = output 31 | ? path.join(rootPath, output) 32 | : path.join(rootPath, `index.${suffix.replace(/\./g, '')}`) 33 | let ignorePattern = [] 34 | let items = [] 35 | if (ignore) { 36 | const globs = ignore.constructor === Array ? ignore : [ignore] 37 | ignorePattern = globs.map((x) => path.resolve(rootPath, x)) 38 | } 39 | 40 | items = exportPattern 41 | ? fileInfoParse({ 42 | rootPath, 43 | match, 44 | ignorePattern, 45 | separator, 46 | exportPattern 47 | }) 48 | : fileInfoParseAutoExport({ rootPath, match, ignorePattern, separator }) 49 | 50 | const template = items 51 | .map(({ exportTemplate }) => exportTemplate) 52 | .join('\n') 53 | const result = callback(template, items) || template 54 | 55 | fs.writeFileSync(outPath, `${result}\n`) 56 | console.log( 57 | chalk.green( 58 | `${path.join( 59 | rootPath, 60 | `index.${suffix.replace(/\./g, '')}` 61 | )} update succeed!` 62 | ) 63 | ) 64 | } 65 | 66 | /** 67 | * @param {Object|Array} config 68 | * @prop {String} match 子模块的匹配规则 glob pattern 69 | * @prop {Regex} separator 子模块目录(文件)命名分割符默认为 /(-|_)/g 70 | * @prop {String} exportPattern 子模块导出模板 71 | * @prop {String} suffix 生成index文件的后缀默认为 '.js' 72 | * @prop {String|Array} ignore glob pattern or glob pattern array 73 | * @prop {(template,items)=>String} callback 自定义回调函数,template 为引进生成的文件模板,items 匹配的文件信息,返回值为新的模板 74 | */ 75 | module.exports = (config) => { 76 | let configs = [config] 77 | if (config.constructor === Array) { 78 | configs = config 79 | } 80 | configs.forEach((config) => { 81 | createIndex(config) 82 | }) 83 | } 84 | -------------------------------------------------------------------------------- /packages/index-creater/lib/ast.js: -------------------------------------------------------------------------------- 1 | function filterExport(ast) { 2 | const ctx = { 3 | default: null, 4 | name: [], 5 | declaration: [], 6 | specifiers: [] 7 | } 8 | if (!ast && ast.sourceType !== 'module') return ctx 9 | 10 | ast.body.forEach(node => { 11 | // https://github.com/babel/babylon/blob/master/ast/spec.md#exports 12 | switch (node.type) { 13 | case 'ExportNamedDeclaration': { 14 | if (node.declaration) { 15 | if ( 16 | node.declaration.id && 17 | node.declaration.id.type === 'Identifier' 18 | ) { 19 | // type: ClassDeclaration / FunctionDeclaration 20 | ctx.name.push(node.declaration.id.name) 21 | ctx.declaration.push(node.declaration) 22 | } else if ( 23 | node.declaration.declarations && 24 | node.declaration.declarations.length 25 | ) { 26 | // type: VariableDeclaration 27 | node.declaration.declarations.forEach(declarator => { 28 | if ( 29 | declarator.id && 30 | declarator.id.type === 'Identifier' 31 | ) { 32 | ctx.name.push(declarator.id.name) 33 | ctx.declaration.push(declarator) 34 | } 35 | }) 36 | } 37 | } else if (node.specifiers && node.specifiers.length) { 38 | node.specifiers.forEach(specifier => { 39 | if ( 40 | specifier.exported && 41 | specifier.exported.type === 'Identifier' 42 | ) { 43 | ctx.name.push(specifier.exported.name) 44 | ctx.specifiers.push(specifier) 45 | } 46 | }) 47 | } 48 | break 49 | } 50 | case 'ExportDefaultDeclaration': { 51 | ctx.default = node.declaration 52 | break 53 | } 54 | case 'ExportAllDeclaration': { 55 | // TODO: e.g., export * from "mod"; 56 | break 57 | } 58 | default: 59 | break 60 | } 61 | }) 62 | 63 | return ctx 64 | } 65 | 66 | module.exports = { 67 | filterExport 68 | } 69 | -------------------------------------------------------------------------------- /packages/index-creater/lib/fileInfoParse.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | const { red } = require('chalk') 4 | const esprima = require('esprima') 5 | const ast = require('./ast') 6 | const glob = require('glob') 7 | const getPascal = require('./getPascal') 8 | 9 | /** 10 | * 解析匹配的文件,并返回整合后的信息 11 | */ 12 | function fileInfoParse({ 13 | rootPath, 14 | match, 15 | ignorePattern, 16 | separator, 17 | exportPattern 18 | }) { 19 | let items = [] 20 | const dirs = glob.sync(path.resolve(rootPath, match), { 21 | ignore: ignorePattern 22 | }) 23 | 24 | items = dirs.map((filePath) => { 25 | const name = getPascal(path.parse(filePath).name, separator) 26 | const relativePath = `./${path.relative(rootPath, filePath)}` 27 | const parsePath = path.parse(relativePath) 28 | const basePath = parsePath.dir + parsePath.name 29 | 30 | const exportTemplate = exportPattern 31 | .replace(/\[name\]/g, name) 32 | .replace(/\[path\]/g, basePath) 33 | 34 | return { exportTemplate, name, relativePath, filePath } 35 | }) 36 | return items 37 | } 38 | 39 | /** 40 | * 解析匹配的文件,并自动解析文件的export,返回整合活的文件信息 41 | * @param {*} param0 42 | */ 43 | function fileInfoParseAutoExport({ 44 | rootPath, 45 | match, 46 | ignorePattern, 47 | separator 48 | }) { 49 | const files = glob.sync(path.resolve(rootPath, match), { 50 | ignore: ignorePattern 51 | }) 52 | const items = [] 53 | files.forEach((filePath) => { 54 | const pathOpt = path.parse(filePath) 55 | const code = fs.readFileSync(filePath, { encoding: 'utf8' }) 56 | 57 | try { 58 | const tree = esprima.parseModule(code) 59 | const ctx = ast.filterExport(tree) 60 | const relativePath = `./${path.relative(rootPath, filePath)}` 61 | const name = getPascal( 62 | pathOpt.name !== 'index' 63 | ? pathOpt.name 64 | : path.basename(pathOpt.dir), 65 | separator 66 | ) 67 | 68 | let list = [] 69 | if (ctx.default) list.push(`default as ${name}`) 70 | list = list.concat(ctx.name) 71 | 72 | const exportTemplate = list.length 73 | ? `export { ${list.join(', ')} } from '${relativePath}'` 74 | : '' 75 | items.push({ exportTemplate, name, relativePath, filePath }) 76 | } catch (ex) { 77 | console.log(red(ex)) 78 | } 79 | }) 80 | return items 81 | } 82 | module.exports = { fileInfoParse, fileInfoParseAutoExport } 83 | -------------------------------------------------------------------------------- /packages/index-creater/lib/getPascal.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 将传入的字符串的首字母转为大写 3 | */ 4 | function capitalize([first, ...rest]) { 5 | return first.toUpperCase() + rest.join('') 6 | } 7 | /** 8 | * 9 | * @param {String} x 传入字符串 10 | * @param {RegExp} separator 分割符号 11 | * @example 12 | * getPascal('action-sheet',/(-|_)/g) 13 | * => 'ActionSheet' 14 | * @example 15 | * getPascal('action',/(-|_)/g) 16 | * => 'Action' 17 | */ 18 | function getPascal(x, separator) { 19 | const arr = x.split(separator) 20 | let str = capitalize(x) 21 | if (arr.length > 1) { 22 | str = arr.reduce((a, b) => capitalize(a) + capitalize(b)) 23 | } 24 | // str.replace(separator, "") 是为了处理当 25 | return str.replace(separator, '') 26 | } 27 | module.exports = getPascal 28 | -------------------------------------------------------------------------------- /packages/index-creater/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "index-creater", 3 | "version": "1.0.8", 4 | "description": "Automatic index generation", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "dev": "cd example && node --inspect-brk index.js" 9 | }, 10 | "author": "advence-liz", 11 | "license": "ISC", 12 | "dependencies": { 13 | "chalk": "^2.4.1", 14 | "esprima": "^4.0.1", 15 | "glob": "^7.1.3" 16 | }, 17 | "directories": { 18 | "example": "example" 19 | }, 20 | "devDependencies": {}, 21 | "repository": { 22 | "type": "git", 23 | "url": "git+https://github.com/advence-liz/auto-index.git" 24 | }, 25 | "keywords": [ 26 | "node", 27 | "index" 28 | ], 29 | "bugs": { 30 | "url": "https://github.com/advence-liz/auto-index/issues" 31 | }, 32 | "homepage": "https://github.com/advence-liz/auto-index#readme" 33 | } 34 | -------------------------------------------------------------------------------- /packages/index-creater/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | ansi-styles@^3.2.1: 6 | version "3.2.1" 7 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 8 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 9 | dependencies: 10 | color-convert "^1.9.0" 11 | 12 | balanced-match@^1.0.0: 13 | version "1.0.0" 14 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 15 | integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= 16 | 17 | brace-expansion@^1.1.7: 18 | version "1.1.11" 19 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 20 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 21 | dependencies: 22 | balanced-match "^1.0.0" 23 | concat-map "0.0.1" 24 | 25 | chalk@^2.4.1: 26 | version "2.4.1" 27 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" 28 | integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== 29 | dependencies: 30 | ansi-styles "^3.2.1" 31 | escape-string-regexp "^1.0.5" 32 | supports-color "^5.3.0" 33 | 34 | color-convert@^1.9.0: 35 | version "1.9.3" 36 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 37 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 38 | dependencies: 39 | color-name "1.1.3" 40 | 41 | color-name@1.1.3: 42 | version "1.1.3" 43 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 44 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= 45 | 46 | concat-map@0.0.1: 47 | version "0.0.1" 48 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 49 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 50 | 51 | escape-string-regexp@^1.0.5: 52 | version "1.0.5" 53 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 54 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 55 | 56 | esprima@^4.0.1: 57 | version "4.0.1" 58 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" 59 | integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== 60 | 61 | fs.realpath@^1.0.0: 62 | version "1.0.0" 63 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 64 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 65 | 66 | glob@^7.1.3: 67 | version "7.1.3" 68 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" 69 | integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== 70 | dependencies: 71 | fs.realpath "^1.0.0" 72 | inflight "^1.0.4" 73 | inherits "2" 74 | minimatch "^3.0.4" 75 | once "^1.3.0" 76 | path-is-absolute "^1.0.0" 77 | 78 | has-flag@^3.0.0: 79 | version "3.0.0" 80 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 81 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= 82 | 83 | inflight@^1.0.4: 84 | version "1.0.6" 85 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 86 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 87 | dependencies: 88 | once "^1.3.0" 89 | wrappy "1" 90 | 91 | inherits@2: 92 | version "2.0.3" 93 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 94 | integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= 95 | 96 | minimatch@^3.0.4: 97 | version "3.0.4" 98 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 99 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 100 | dependencies: 101 | brace-expansion "^1.1.7" 102 | 103 | once@^1.3.0: 104 | version "1.4.0" 105 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 106 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 107 | dependencies: 108 | wrappy "1" 109 | 110 | path-is-absolute@^1.0.0: 111 | version "1.0.1" 112 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 113 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 114 | 115 | supports-color@^5.3.0: 116 | version "5.5.0" 117 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 118 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 119 | dependencies: 120 | has-flag "^3.0.0" 121 | 122 | wrappy@1: 123 | version "1.0.2" 124 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 125 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 126 | -------------------------------------------------------------------------------- /packages/quick-switch/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: 'standard' 3 | } 4 | -------------------------------------------------------------------------------- /packages/quick-switch/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | src 3 | 4 | package-lock.json 5 | .qsrc.json 6 | test -------------------------------------------------------------------------------- /packages/quick-switch/README.md: -------------------------------------------------------------------------------- 1 | # qs 2 | 3 | 一个`NODE命令行工具`方便快速的根据已有模板快速生成新的模块,以命令行形式替代复制粘贴重命名,并且记录当前的模块,方便整合到 webpack,gulp 脚本中灵活的启动每模块 4 | 5 | - [github](https://github.com/advence-liz/quick-switch) 6 | - [npm](https://www.npmjs.com/package/quickly-switch) 7 | 8 | ```bash 9 | 比如有如下目录结构,每个组件的处除了父目录的名字其他的文件结构都是一样的,这样就可以根据 qs 命令快速的创建新的组件 10 | $ qs --new=nav // 根据_demo 生成 nav 11 | --- 12 | - componets 13 | + _demo 14 | - xxx 15 | - index.js 16 | 17 | 18 | + nav 19 | - xxx 20 | - index.js 21 | --- 22 | ``` 23 | 24 | ## install 25 | 26 | ```bash 27 | $ npm install quickly-switch -g 28 | ``` 29 | 30 | ## 起步 `qs --init` 31 | 32 | `--init` 主要是初始化 qs 的默认配置目前有两个个配置,生成的配置默认存在当前目录的 `.qsrc.json`文件中 33 | 34 | - `root` 模板的根目录默认值为`.` (等同上文中的`components`) 35 | - `defaultDemo` 默认模板默认值为 `_demo`结合`root`参数可以得其实际路径为`/components/_demo`(等同上文中`_demo` 36 | 37 | ```bash 38 | $ qs --new=nav 39 | 会以_demo 为模板生成nav 并且将文件名字全部改为nav 40 | _demo 41 | _demo.xx 42 | _demo.xxx 43 | _demo.XXXX 44 | 45 | nav 46 | nav.xx 47 | nav.xxx 48 | nav.XXXX 49 | ``` 50 | 51 | ![](img/qsinit.gif) 52 | 53 | ## `.qsrc.json` 54 | 55 | `.qsrc.json`文件由`qs --init`生成存储在`qs`命令的运行目录,文件中有三个属性 `root`为`qs`寻找和新建模块的根目录,`defaultDemo`默认的模板模块,`modeule`当前模块 56 | 57 | ```js 58 | {"root":"src/components","defaultDemo":"_demo","module":"_demo"} 59 | ``` 60 | 61 | ```js 62 | // qs 命令会记录当前切换到那个模块下,那记录这个有什么用呢,举个例子 63 | // 比如我们一个工程有多个模块,每个模块单独打包,这样就可以通过读取`.qsrc.json`获取当前模块动态打包 64 | 65 | const { module: currentModule, root } = fs.readJsonSync('.qsrc.json') 66 | module.exports = { 67 | entry: path.resolve(root, currentModule), 68 | mode: 'development', 69 | context: __dirname, 70 | output: { 71 | filename: 'bundle.js', 72 | path: path.resolve(__dirname, 'build') 73 | }, 74 | ``` 75 | 76 | ## 命令介绍 77 | 78 | 命令的实现依赖[yargs](https://github.com/yargs/yargs) 79 | 80 | - `qs -h` 自行查看命令描述 81 | - `qs` 直接键入`qs` 等同于 `qs -l`列出当项目的模块列表 82 | - `qs --new=` 根据默认模板创建新的模块 83 | - `qs --switch=` 将当前模块切换到对应名称的模块下,如果模块不存在则以当前模块为模板创建新的模块 84 | 85 | ### `qs -h`的输出 86 | 87 | ``` 88 | pc git:(master) ✗ qs -h 89 | Usage: qs [options] 90 | 91 | 选项: 92 | --version 显示版本号 [布尔] 93 | --new, -n qs --new= 跟默认模板创建新的模块 [字符串] 94 | --switch, -s qs --switch= 将当前模块切换为,如果 95 | 不存在则以当前模块为模板创建新模块 [字符串] 96 | --delete, -d delete [字符串] 97 | --root, -r root [字符串] 98 | --reset, --rs reset Root [布尔] 99 | --list, -l 列出所有模块 [布尔] 100 | --rename, -R qs -s= --rename 101 | 将新生产模块所有文件的名字改为跟模板目录相同,为了微信小程序那种形式 102 | [布尔] 103 | --init 主要是初始化 qs 104 | 的默认配置目前有三个配置,生成的配置默认存在当前目录的 105 | `.qsrc`文件中 106 | -h, --help 显示帮助信息 107 | ``` 108 | 109 | ![](img/qsnew.gif) 110 | 111 | ## debug 112 | 113 | 将环境变量`DEBUG`设置为`qs` 当 debug 模式下会输出 qs 的配置和命令行参数信息,下面的信息具有时效性更新代表的时候输出就不一定这样喽 114 | 115 | ```js 116 | alg git:(master) export DEBUG=qs 117 | ➜ alg git:(master) qs 118 | qs isInit, rootDir false /xxx/workspace/alg +0ms 119 | qs options +0ms 120 | qs { defaultDemo: '_demo', 121 | qs qsrcPath: 'xxxxxxxx/alg/.qsrc.json', 122 | qs moduleStorePath: 'xxxxxxxx/alg/.qsrc.json', 123 | qs rootDir: 'xxxxxxxx/alg', 124 | qs currentModule: '_demo', 125 | qs _: [], 126 | qs '$0': 'qs', 127 | qs root: '/Users/qudian/liz/workspace/alg' } +1ms 128 | ❤️ For more info use help: qs -h 129 | _demo 130 | ``` 131 | 132 | ## TODO 133 | 134 | - [ ] root 动态设置 root 135 | - [ ] sourcename 自定义源 136 | -------------------------------------------------------------------------------- /packages/quick-switch/bin/cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const yargs = require('yargs') 4 | const run = require('./run') 5 | 6 | const args = yargs 7 | .usage('Usage: $0 [options]') 8 | .options({ 9 | new: { 10 | alias: 'n', 11 | describe: 'qs --new= 跟默认模板创建新的模块', 12 | type: 'string', 13 | conflicts: ['switch', 'delete'] 14 | }, 15 | switch: { 16 | alias: 's', 17 | describe: 18 | 'qs --switch= 将当前模块切换为,如果 不存在则以当前模块为模板创建新模块', 19 | type: 'string', 20 | conflicts: ['new', 'delete'] 21 | }, 22 | delete: { 23 | alias: 'd', 24 | describe: 'delete', 25 | type: 'string', 26 | conflicts: ['new', 'switch'] 27 | }, 28 | root: { 29 | alias: 'r', 30 | describe: 'root', 31 | type: 'string', 32 | conflicts: ['init'] 33 | }, 34 | list: { 35 | alias: 'l', 36 | describe: '列出所有模块', 37 | type: 'boolean' 38 | }, 39 | init: { 40 | describe: 41 | '主要是初始化 qs 的默认配置目前有三个配置,生成的配置默认存在当前目录的 `.qsrc`文件中' 42 | } 43 | }) 44 | .help() 45 | .alias(['h', 'help'], 'help').argv 46 | 47 | run(args) 48 | -------------------------------------------------------------------------------- /packages/quick-switch/bin/run.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const path = require('path') 3 | const fs = require('fs-extra') 4 | const { red, blue, green } = require('chalk') 5 | const inquirer = require('inquirer') 6 | const { createNewModule } = require('quickly-template/lib/createTemplate') 7 | const getConfig = require('../lib/get-config') 8 | const attempt = require('../lib/attempt') 9 | const debug = require('debug')('qs') 10 | const { ConfigOutputPath } = require('../qs.config') 11 | 12 | function main (options) { 13 | debug('options') 14 | debug(options) 15 | if (options.switch) { 16 | const { currentModule } = options 17 | switchModule(currentModule, options.switch, options) 18 | } else if (options.new) { 19 | const { defaultDemo } = options 20 | switchModule(defaultDemo, options.new, options) 21 | } else if (options.delete) { 22 | deleteModule(options.delete, options) 23 | } else if (options.list) { 24 | attempt(printModule, options) 25 | } else if (options.init) { 26 | init() 27 | } else { 28 | // const { root } = options 29 | // console.info(green('root:'), blue(root)) 30 | console.info(green('❤️ For more info use help:'), blue('qs -h')) 31 | attempt(printModule, options) 32 | } 33 | } 34 | 35 | function init () { 36 | const questions = [ 37 | { 38 | type: 'input', 39 | name: 'root', 40 | message: "What's your root", 41 | default: function () { 42 | return '.' 43 | } 44 | }, 45 | { 46 | type: 'input', 47 | name: 'defaultDemo', 48 | message: "What's your defaultDemo", 49 | default: function () { 50 | return '_demo' 51 | } 52 | } 53 | // { 54 | // type: 'confirm', 55 | // name: 'rename', 56 | // message: 'Create new module will reanme files,Is this OK?(default No)', 57 | // default: false 58 | // } 59 | ] 60 | 61 | inquirer.prompt(questions).then(answers => { 62 | // const { moduleStorePath, defaultDemo } = answers 63 | 64 | console.info(blue(JSON.stringify(answers, null, ' '))) 65 | 66 | fs.outputJSONSync(ConfigOutputPath, answers) 67 | }) 68 | } 69 | 70 | function printModule (options) { 71 | const { currentModule, root } = options 72 | const allModules = fs.readdirSync(root) 73 | 74 | allModules.forEach(item => { 75 | let isFilter = /(\.|node_modules)/g.test(item) 76 | if (item === currentModule) { 77 | !isFilter && console.info(green(item)) 78 | } else { 79 | !isFilter && console.info(item) 80 | } 81 | }) 82 | } 83 | function switchModule (currentModule, nextModule, options) { 84 | const { root, new: isNew } = options 85 | const allModules = fs.readdirSync(root) 86 | if (currentModule === nextModule) { 87 | console.info( 88 | red('The target module cannot be equal to the current module!') 89 | ) 90 | return 91 | } 92 | // 如果next模块存在直接重写.qsrc.json,如果调用的是new 提示然后退出 93 | if (allModules.indexOf(nextModule) > -1) { 94 | isNew 95 | ? console.log(red(`${nextModule} alread exist `)) 96 | : rewriteModule(nextModule, options) 97 | 98 | return 99 | } 100 | // 如果是切换判断一下是否创建新模块 101 | if (nextModule) { 102 | if (isNew) { 103 | createModule(currentModule, nextModule, options) 104 | rewriteModule(nextModule, options) 105 | return 106 | } 107 | inquirer 108 | .prompt({ 109 | type: 'confirm', 110 | name: 'createNew', 111 | message: blue( 112 | `The current module ${green( 113 | nextModule 114 | )} does not exist whether to create a new module (default no)` 115 | ), 116 | default: false 117 | }) 118 | .then(answers => { 119 | const { createNew } = answers 120 | if (createNew) { 121 | createModule(currentModule, nextModule, options) 122 | rewriteModule(nextModule, options) 123 | } 124 | }) 125 | } 126 | } 127 | function rewriteModule (nextModule, options) { 128 | const { moduleStorePath } = options 129 | const config = fs.readJsonSync(moduleStorePath) 130 | fs.outputJsonSync(moduleStorePath, { ...config, ...{ module: nextModule } }) 131 | console.info( 132 | green(`Successfully written ${nextModule} to ${moduleStorePath}`) 133 | ) 134 | } 135 | function createModule (sourceModule, targetModule, options = {}) { 136 | const { root } = options 137 | if (!fs.pathExistsSync(path.join(root, sourceModule))) { 138 | console.info(red(`${sourceModule} directory not found`)) 139 | process.exit(0) 140 | } 141 | if (sourceModule === targetModule) { 142 | console.info( 143 | red('The target module cannot be equal to the current module!') 144 | ) 145 | return 146 | } 147 | 148 | const globPattern = path.join(root, sourceModule, '**', '*.*') 149 | const target = root 150 | const renderOptions = { name: targetModule } 151 | const name = targetModule 152 | const argv = options 153 | createNewModule({ globPattern, target, argv, renderOptions, name }) 154 | console.info(green(`create ${targetModule} from ${sourceModule}`)) 155 | } 156 | function deleteModule (targetModule, options) { 157 | const { root, defaultDemo, currentModule } = options 158 | if (targetModule === defaultDemo) { 159 | console.info(red('The demo directory should not be removed!')) 160 | return 161 | } 162 | fs.removeSync(path.join(root, targetModule)) 163 | 164 | console.info(green(`${targetModule} successfully deleted`)) 165 | if (targetModule === currentModule) { 166 | console.info( 167 | blue('currentModule is deleted so change currentModule to default') 168 | ) 169 | rewriteModule(defaultDemo) 170 | } 171 | } 172 | 173 | module.exports = args => { 174 | const options = getConfig(args) 175 | main(options) 176 | } 177 | -------------------------------------------------------------------------------- /packages/quick-switch/img/qsinit.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fe-go/fe-cli/8c1ae45b60747197acec7e10a184625968a86b1a/packages/quick-switch/img/qsinit.gif -------------------------------------------------------------------------------- /packages/quick-switch/img/qsnew.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fe-go/fe-cli/8c1ae45b60747197acec7e10a184625968a86b1a/packages/quick-switch/img/qsnew.gif -------------------------------------------------------------------------------- /packages/quick-switch/index.js: -------------------------------------------------------------------------------- 1 | const getConfig = require('./lib/get-config') 2 | 3 | module.exports = { getConfig } 4 | -------------------------------------------------------------------------------- /packages/quick-switch/lib/attempt.js: -------------------------------------------------------------------------------- 1 | const debug = require('debug')('qs') 2 | function attempt (func, ...args) { 3 | try { 4 | return func.apply(undefined, args) 5 | } catch (e) { 6 | debug(e) 7 | // return false 8 | } 9 | } 10 | 11 | module.exports = attempt 12 | -------------------------------------------------------------------------------- /packages/quick-switch/lib/get-config.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs-extra') 2 | const path = require('path') 3 | const { red, blue, green, yellow } = require('chalk') 4 | const args = require('yargs').argv 5 | const findup = require('findup-sync') 6 | const { ConfigOutputPath, ModuleStorePath } = require('../qs.config') 7 | const debug = require('debug')('qs') 8 | 9 | /** 10 | * 将命令行参数和默认的配置参数结合 命令行优先级 > 根目录配置 11 | * @param {planObject} options 传入的命令行参数 12 | * @returns {planObject} options 返回组合后的参数 13 | * @example 14 | * getConfig({root:'demo'}) 15 | */ 16 | function getConfig (options = {}) { 17 | /** 18 | * @var {planObject} config qs --init 命令生成的配置 19 | * @var {string} currentModule 当前选中模块 20 | * @var {string} qsrcPath qs --init 生成的 .qsrc.json 的 absolute path 21 | * @var {string} rootDir .qsrc.json 所在目录一般也就是项目根目录 22 | */ 23 | 24 | const isInit = !!args.init 25 | // init 模式直接返回 26 | if (isInit) return options 27 | try { 28 | const rootDir = path.parse(findup(ConfigOutputPath)).dir 29 | let config, currentModule, qsrcPath 30 | debug(green('isInit, rootDir'), isInit, rootDir) 31 | if ((qsrcPath = findup(ConfigOutputPath))) { 32 | config = fs.readJsonSync(qsrcPath) 33 | let { defaultDemo, root: configRoot } = config 34 | let { root: cmdRoot } = options 35 | let relativeRoot = cmdRoot || configRoot 36 | // moduleStorePath 动态根据工作目录或者命令输入确定 37 | let moduleStorePath = path.join( 38 | rootDir, 39 | // relativeRoot, 40 | ModuleStorePath // '.qsrc.json' 41 | ) 42 | 43 | fs.ensureFileSync(moduleStorePath) 44 | currentModule = getCurrentModule( 45 | moduleStorePath, 46 | defaultDemo, 47 | path.join(rootDir, relativeRoot) 48 | ) 49 | 50 | fs.outputJsonSync(moduleStorePath, { 51 | ...fs.readJsonSync(moduleStorePath), 52 | ...{ module: currentModule } 53 | }) 54 | 55 | return { 56 | defaultDemo, 57 | qsrcPath, 58 | moduleStorePath, 59 | rootDir, 60 | currentModule, 61 | ...options, 62 | root: path.join(rootDir, relativeRoot) // 绝对路径之后的 switch new print 都依赖root 值 63 | } 64 | } 65 | } catch (error) { 66 | console.info(red(`Can't found ${ConfigOutputPath}`)) 67 | console.info(blue('Please use: qs --init')) 68 | process.exit(0) 69 | } 70 | } 71 | function getCurrentModule (moduleStorePath, defaultDemo, currentRoot) { 72 | let currentModule 73 | try { 74 | currentModule = fs.readJsonSync(moduleStorePath).module 75 | if (!fs.existsSync(path.join(currentRoot, currentModule))) { 76 | console.info( 77 | yellow(`warning ${path.join(currentRoot, currentModule)} not exist!`) 78 | ) 79 | } 80 | } catch (error) { 81 | // console.info(red(`can't found currentModule`)) 82 | // console.info(blue('use: qs --init qs --switch ')) 83 | } 84 | 85 | return currentModule || defaultDemo 86 | } 87 | module.exports = getConfig 88 | -------------------------------------------------------------------------------- /packages/quick-switch/lib/rename-files.js: -------------------------------------------------------------------------------- 1 | const glob = require('glob') 2 | const path = require('path') 3 | const fs = require('fs-extra') 4 | function renameFiles (dir, target) { 5 | let files = glob.sync(path.join(dir, '**', '*.*')) 6 | files.forEach(filePath => { 7 | let name = path.parse(filePath).base // 带上文件后缀防止目录名和文件名字一样 8 | let ext = path.parse(filePath).ext 9 | let targetPath = filePath.replace(name, `${target}${ext}`) 10 | fs.renameSync(filePath, targetPath) 11 | }) 12 | } 13 | module.exports = renameFiles 14 | -------------------------------------------------------------------------------- /packages/quick-switch/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "quickly-switch", 3 | "version": "2.0.2", 4 | "description": "a tool for quick (switch)start ", 5 | "main": "index.js", 6 | "bin": { 7 | "qs": "bin/cli.js" 8 | }, 9 | "scripts": { 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "keywords": [ 13 | "node", 14 | "tool", 15 | "quick" 16 | ], 17 | "author": "advence-liz", 18 | "license": "ISC", 19 | "repository": "git@github.com:advence-liz/quick-switch/.git", 20 | "dependencies": { 21 | "chalk": "^2.4.1", 22 | "debug": "^3.1.0", 23 | "findup-sync": "^2.0.0", 24 | "fs-extra": "^7.0.0", 25 | "glob": "^7.1.2", 26 | "inquirer": "^6.1.0", 27 | "quickly-template": "^1.1.3", 28 | "yargs": "^12.0.1" 29 | }, 30 | "devDependencies": { 31 | "eslint": "^5.14.1", 32 | "eslint-config-standard": "^11.0.0", 33 | "eslint-plugin-import": "^2.14.0", 34 | "eslint-plugin-node": "^7.0.1", 35 | "eslint-plugin-promise": "^3.8.0", 36 | "eslint-plugin-standard": "^3.1.0" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/quick-switch/qs.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ConfigOutputPath: '.qsrc.json', 3 | ModuleStorePath: '.qsrc.json' 4 | } 5 | --------------------------------------------------------------------------------