├── .editorconfig ├── .gitignore ├── LICENSE ├── README.md ├── images ├── default-color-icon.png ├── icons.png ├── multi-color-icon.png ├── one-color-icon.png └── symbol-url.png ├── package.json ├── publish.sh ├── pubspec.lock ├── pubspec.yaml ├── scripts ├── config │ ├── normal.json │ └── nullsafety.json └── update-snapshot.sh ├── snapshots ├── icon_font.dart └── null_safety.dart ├── src ├── commands │ ├── createIcon.ts │ ├── createJson.ts │ └── help.ts ├── libs │ ├── generateComponent.ts │ ├── getConfig.ts │ ├── getTemplate.ts │ ├── iconfont.json │ ├── replace.ts │ └── whitespace.ts └── templates │ ├── Icon.dart.template │ └── Icon.null.safety.dart.template ├── tsconfig.json └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [.*] 12 | insert_final_newline = false 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | *.log 3 | .idea/ 4 | build/ 5 | /iconfont.json 6 | .DS_Store 7 | .dart_tool/ 8 | .packages -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 原罪 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.md: -------------------------------------------------------------------------------- 1 | ## flutter-iconfont-cli 2 | 用纯JS把iconfont.cn的图标转换成Flutter Widget,不依赖字体,支持多色彩 3 | 4 | ![](https://github.com/fwh1990/flutter-iconfont-cli/blob/master/images/icons.png?raw=true) 5 | 6 | ## 特性 7 | 8 | 1、纯组件,不依赖字体,体积小 9 |
10 | 2、支持渲染多色彩图标,支持自定义颜色 11 |
12 | 3、自动化生成图标组件 13 | 14 | ## Step 1 15 | 16 | 在项目文件`pubspec.yml`中加入flutter插件 `flutter_svg` 17 | ```yaml 18 | { 19 | ... 20 | 21 | dependencies: 22 | # 版本号请以官方库的为准:https://pub.dev/packages/flutter_svg 23 | flutter_svg: ^0.19.3 24 | ... 25 | } 26 | ``` 27 | 然后执行flutter插件安装操作 28 | ```bash 29 | flutter packages get 30 | ``` 31 | 32 | 接着安装全局插件(基于nodeJs) 33 | ```bash 34 | npm install flutter-iconfont-cli -g 35 | ``` 36 | 37 | # Step 2 38 | 生成配置文件 39 | ```bash 40 | npx iconfont-init 41 | ``` 42 | 此时项目根目录会生成一个`iconfont.json`的文件,内容如下: 43 | ```json 44 | { 45 | "symbol_url": "请参考README.md,复制官网提供的JS链接", 46 | "save_dir": "./lib/iconfont", 47 | "trim_icon_prefix": "icon", 48 | "default_icon_size": 18, 49 | "null_safety": true 50 | } 51 | ``` 52 | ### 配置参数说明: 53 | ### symbol_url 54 | 请直接复制[iconfont](http://iconfont.cn)官网提供的项目链接。请务必看清是`.js`后缀而不是.css后缀。如果你现在还没有创建iconfont的仓库,那么可以填入这个链接去测试:`http://at.alicdn.com/t/font_1373348_ghk94ooopqr.js` 55 | 56 |
57 | 58 | ![](https://github.com/fwh1990/flutter-iconfont-cli/blob/master/images/symbol-url.png?raw=true) 59 | 60 | 61 | ### save_dir 62 | 根据iconfont图标生成的组件存放的位置。每次生成组件之前,该文件夹都会被清空。 63 | 64 | ### trim_icon_prefix 65 | 如果你的图标有通用的前缀,而你在使用的时候又不想重复去写,那么可以通过这种配置这个选项把前缀统一去掉。 66 | 67 | ### default_icon_size 68 | 我们将为每个生成的图标组件加入默认的字体大小,当然,你也可以通过传入props的方式改变这个size值 69 | 70 | ### null_safety 71 | dart 2.12.0 开始支持的空安全特性,开启该参数后,生成的语法会有所变化,所以需要变更sdk以保证语法能被识别。 72 | ```diff 73 | environment: 74 | - sdk: ">=2.7.0 <3.0.0" 75 | + sdk: ">=2.12.0 <3.0.0" 76 | ``` 77 | 78 | # Step 3 79 | 开始生成React标准组件 80 | ```bash 81 | npx iconfont-flutter 82 | ``` 83 | 生成后查看您设置的保存目录中是否含有所有的图标 84 | 85 | ----------- 86 | 87 | 现在,你可以参考[snapshots目录](https://github.com/iconfont-cli/flutter-iconfont-cli/tree/master/snapshots)的快照文件。 88 | 89 | # 使用 90 | 91 | ### 图标尺寸 92 | 根据配置`default_icon_size`,每个图标都会有一个默认的尺寸,你可以随时覆盖。 93 | ```dart 94 | class App extends StatelessWidget { 95 | @override 96 | Widget build(BuildContext context) { 97 | return IconFont(IconNames.alipay, size: 100); 98 | } 99 | } 100 | ``` 101 | ![](https://github.com/fwh1990/flutter-iconfont-cli/blob/master/images/default-color-icon.png?raw=true) 102 | ### 图标单色 103 | 单色图标,如果不指定颜色值,图标将渲染原本的颜色。如果你想设置为其他的颜色,那么设置一个你想要的颜色即可。 104 | 105 | **注意:如果你在props传入的color是字符串而不是数组,那么即使原本是多色彩的图标,也会变成单色图标。** 106 | 107 | ```dart 108 | IconFont(IconNames.alipay, color: 'red'); 109 | ``` 110 | ![](https://github.com/fwh1990/flutter-iconfont-cli/blob/master/images/one-color-icon.png?raw=true) 111 | 112 | ### 图标多色彩 113 | 多色彩的图标,如果不指定颜色值,图标将渲染原本的多色彩。如果你想设置为其他的颜色,那么设置一组你想要的颜色即可 114 | ```dart 115 | IconFont(IconNames.alipay, colors: ['green', 'orange']); 116 | ``` 117 | 颜色组的数量以及排序,需要根据当前图标的信息来确定。您需要进入图标组件中查看并得出结论。 118 | 119 | 120 | ![](https://github.com/fwh1990/flutter-iconfont-cli/blob/master/images/multi-color-icon.png?raw=true) 121 | 122 | # 更新图标 123 | 当您在iconfont.cn中的图标有变更时,只需更改配置`symbol_url`,然后再次执行`Step 3`即可生成最新的图标组件 124 | ```bash 125 | # 修改 symbol_url 配置后执行: 126 | npx iconfont-flutter 127 | ``` 128 | 129 | # 扩展 130 | |平台|库| 131 | |----|---| 132 | |小程序|[mini-program-iconfont-cli](https://github.com/iconfont-cli/mini-program-iconfont-cli)| 133 | |Taro|[taro-iconfont-cli](https://github.com/iconfont-cli/taro-iconfont-cli)| 134 | |React H5|[react-iconfont-cli](https://github.com/iconfont-cli/react-iconfont-cli)| 135 | |React Native|[react-native-iconfont-cli](https://github.com/iconfont-cli/react-native-iconfont-cli)| 136 | |Remax|[remax-iconfont-cli](https://github.com/iconfont-cli/remax-iconfont-cli)| 137 | 138 | -------- 139 | 140 | 欢迎使用,并给我一些反馈和建议,让这个库做的更好 141 | -------------------------------------------------------------------------------- /images/default-color-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iconfont-cli/flutter-iconfont-cli/255b190f3979ea49ebaa37bd670c2c599652d9a6/images/default-color-icon.png -------------------------------------------------------------------------------- /images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iconfont-cli/flutter-iconfont-cli/255b190f3979ea49ebaa37bd670c2c599652d9a6/images/icons.png -------------------------------------------------------------------------------- /images/multi-color-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iconfont-cli/flutter-iconfont-cli/255b190f3979ea49ebaa37bd670c2c599652d9a6/images/multi-color-icon.png -------------------------------------------------------------------------------- /images/one-color-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iconfont-cli/flutter-iconfont-cli/255b190f3979ea49ebaa37bd670c2c599652d9a6/images/one-color-icon.png -------------------------------------------------------------------------------- /images/symbol-url.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iconfont-cli/flutter-iconfont-cli/255b190f3979ea49ebaa37bd670c2c599652d9a6/images/symbol-url.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flutter-iconfont-cli", 3 | "version": "1.2.0", 4 | "main": "index.js", 5 | "keywords": [ 6 | "iconfont", 7 | "flutter", 8 | "flutter-iconfont", 9 | "icon", 10 | "icons", 11 | "iconfont.cn" 12 | ], 13 | "repository": "git@github.com:fwh1990/flutter-iconfont-cli.git", 14 | "author": "范文华 <531362022@qq.com>", 15 | "license": "MIT", 16 | "bin": { 17 | "iconfont": "./commands/help.js", 18 | "iconfont-init": "./commands/createJson.js", 19 | "iconfont-flutter": "./commands/createIcon.js" 20 | }, 21 | "peerDependencies": {}, 22 | "dependencies": { 23 | "colors": "^1.3.3", 24 | "glob": "^7.1.4", 25 | "iconfont-parser": "^1.0.0", 26 | "lodash": "^4.17.15", 27 | "minimist": "^1.2.5", 28 | "mkdirp": "^0.5.1", 29 | "tslib": "^1.10.0" 30 | }, 31 | "devDependencies": { 32 | "@types/glob": "^7.1.1", 33 | "@types/lodash": "^4.14.137", 34 | "@types/minimist": "^1.2.0", 35 | "@types/mkdirp": "^0.5.2", 36 | "@types/node": "^12.7.2", 37 | "@types/react": "^16.9.2", 38 | "@types/xml2js": "^0.4.4", 39 | "ts-node": "^8.3.0", 40 | "typescript": "^3.5.3" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /publish.sh: -------------------------------------------------------------------------------- 1 | set -e 2 | 3 | rm -rf ./build 4 | rm -rf ./src/iconfont 5 | 6 | ./node_modules/.bin/tsc 7 | 8 | mv ./build/src/* ./build 9 | rm -rf ./build/src ./build/snapshots 10 | cp README.md package.json LICENSE ./build 11 | cp -rf src/templates ./build/templates 12 | 13 | old_registry=$(npm config get registry) 14 | npm config set registry https://registry.npmjs.org 15 | set +e 16 | whoami=$(npm whoami 2>/dev/null) 17 | set -e 18 | 19 | if [ -z "$whoami" ] 20 | then 21 | echo "login plz..." 22 | npm login 23 | fi 24 | echo "I am: $(npm whoami)" 25 | 26 | sleep 1 27 | echo "Begin publish..." 28 | npm publish ./build/ --access=public "$@" 29 | 30 | npm config set registry ${old_registry} 31 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 9 | source: hosted 10 | version: "2.5.0" 11 | boolean_selector: 12 | dependency: transitive 13 | description: 14 | name: boolean_selector 15 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 16 | source: hosted 17 | version: "2.1.0" 18 | characters: 19 | dependency: transitive 20 | description: 21 | name: characters 22 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 23 | source: hosted 24 | version: "1.1.0" 25 | charcode: 26 | dependency: transitive 27 | description: 28 | name: charcode 29 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 30 | source: hosted 31 | version: "1.2.0" 32 | clock: 33 | dependency: transitive 34 | description: 35 | name: clock 36 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 37 | source: hosted 38 | version: "1.1.0" 39 | collection: 40 | dependency: transitive 41 | description: 42 | name: collection 43 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 44 | source: hosted 45 | version: "1.15.0" 46 | cupertino_icons: 47 | dependency: "direct main" 48 | description: 49 | name: cupertino_icons 50 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 51 | source: hosted 52 | version: "1.0.2" 53 | fake_async: 54 | dependency: transitive 55 | description: 56 | name: fake_async 57 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 58 | source: hosted 59 | version: "1.2.0" 60 | flutter: 61 | dependency: "direct main" 62 | description: flutter 63 | source: sdk 64 | version: "0.0.0" 65 | flutter_svg: 66 | dependency: "direct main" 67 | description: 68 | name: flutter_svg 69 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 70 | source: hosted 71 | version: "0.21.0-nullsafety.0" 72 | flutter_test: 73 | dependency: "direct dev" 74 | description: flutter 75 | source: sdk 76 | version: "0.0.0" 77 | matcher: 78 | dependency: transitive 79 | description: 80 | name: matcher 81 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 82 | source: hosted 83 | version: "0.12.10" 84 | meta: 85 | dependency: transitive 86 | description: 87 | name: meta 88 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 89 | source: hosted 90 | version: "1.3.0" 91 | path: 92 | dependency: transitive 93 | description: 94 | name: path 95 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 96 | source: hosted 97 | version: "1.8.0" 98 | path_drawing: 99 | dependency: transitive 100 | description: 101 | name: path_drawing 102 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 103 | source: hosted 104 | version: "0.5.0-nullsafety.0" 105 | path_parsing: 106 | dependency: transitive 107 | description: 108 | name: path_parsing 109 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 110 | source: hosted 111 | version: "0.2.0-nullsafety.0" 112 | petitparser: 113 | dependency: transitive 114 | description: 115 | name: petitparser 116 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 117 | source: hosted 118 | version: "4.0.2" 119 | sky_engine: 120 | dependency: transitive 121 | description: flutter 122 | source: sdk 123 | version: "0.0.99" 124 | source_span: 125 | dependency: transitive 126 | description: 127 | name: source_span 128 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 129 | source: hosted 130 | version: "1.8.0" 131 | stack_trace: 132 | dependency: transitive 133 | description: 134 | name: stack_trace 135 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 136 | source: hosted 137 | version: "1.10.0" 138 | stream_channel: 139 | dependency: transitive 140 | description: 141 | name: stream_channel 142 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 143 | source: hosted 144 | version: "2.1.0" 145 | string_scanner: 146 | dependency: transitive 147 | description: 148 | name: string_scanner 149 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 150 | source: hosted 151 | version: "1.1.0" 152 | term_glyph: 153 | dependency: transitive 154 | description: 155 | name: term_glyph 156 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 157 | source: hosted 158 | version: "1.2.0" 159 | test_api: 160 | dependency: transitive 161 | description: 162 | name: test_api 163 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 164 | source: hosted 165 | version: "0.2.19" 166 | typed_data: 167 | dependency: transitive 168 | description: 169 | name: typed_data 170 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 171 | source: hosted 172 | version: "1.3.0" 173 | vector_math: 174 | dependency: transitive 175 | description: 176 | name: vector_math 177 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 178 | source: hosted 179 | version: "2.1.0" 180 | xml: 181 | dependency: transitive 182 | description: 183 | name: xml 184 | url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub" 185 | source: hosted 186 | version: "5.0.2" 187 | sdks: 188 | dart: ">=2.12.0 <3.0.0" 189 | flutter: ">=1.24.0-7.0" 190 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_demo 2 | description: A new Flutter project. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 7 | 8 | # The following defines the version and build number for your application. 9 | # A version number is three numbers separated by dots, like 1.2.43 10 | # followed by an optional build number separated by a +. 11 | # Both the version and the builder number may be overridden in flutter 12 | # build by specifying --build-name and --build-number, respectively. 13 | # In Android, build-name is used as versionName while build-number used as versionCode. 14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 16 | # Read more about iOS versioning at 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 18 | version: 1.0.0+1 19 | 20 | environment: 21 | sdk: ">=2.12.0 <3.0.0" 22 | 23 | dependencies: 24 | flutter: 25 | sdk: flutter 26 | flutter_svg: ^0.21.0-nullsafety.0 27 | 28 | # The following adds the Cupertino Icons font to your application. 29 | # Use with the CupertinoIcons class for iOS style icons. 30 | cupertino_icons: ^1.0.0 31 | 32 | dev_dependencies: 33 | flutter_test: 34 | sdk: flutter 35 | 36 | # For information on the generic Dart part of this file, see the 37 | # following page: https://dart.dev/tools/pub/pubspec 38 | 39 | # The following section is specific to Flutter. 40 | flutter: 41 | 42 | # The following line ensures that the Material Icons font is 43 | # included with your application, so that you can use the icons in 44 | # the material Icons class. 45 | uses-material-design: true 46 | 47 | # To add assets to your application, add an assets section, like this: 48 | # assets: 49 | # - images/a_dot_burr.jpeg 50 | # - images/a_dot_ham.jpeg 51 | 52 | # An image asset can refer to one or more resolution-specific "variants", see 53 | # https://flutter.dev/assets-and-images/#resolution-aware. 54 | 55 | # For details regarding adding assets from package dependencies, see 56 | # https://flutter.dev/assets-and-images/#from-packages 57 | 58 | # To add custom fonts to your application, add a fonts section here, 59 | # in this "flutter" section. Each entry in this list should have a 60 | # "family" key with the font family name, and a "fonts" key with a 61 | # list giving the asset and other descriptors for the font. For 62 | # example: 63 | # fonts: 64 | # - family: Schyler 65 | # fonts: 66 | # - asset: fonts/Schyler-Regular.ttf 67 | # - asset: fonts/Schyler-Italic.ttf 68 | # style: italic 69 | # - family: Trajan Pro 70 | # fonts: 71 | # - asset: fonts/TrajanPro.ttf 72 | # - asset: fonts/TrajanPro_Bold.ttf 73 | # weight: 700 74 | # 75 | # For details regarding fonts from package dependencies, 76 | # see https://flutter.dev/custom-fonts/#from-packages 77 | -------------------------------------------------------------------------------- /scripts/config/normal.json: -------------------------------------------------------------------------------- 1 | { 2 | "symbol_url": "http://at.alicdn.com/t/font_1373348_do9g97fppkg.js", 3 | "save_dir": "./snapshots", 4 | "trim_icon_prefix": "icon", 5 | "default_icon_size": 14 6 | } 7 | -------------------------------------------------------------------------------- /scripts/config/nullsafety.json: -------------------------------------------------------------------------------- 1 | { 2 | "symbol_url": "http://at.alicdn.com/t/font_1373348_do9g97fppkg.js", 3 | "save_dir": "./snapshots-1", 4 | "trim_icon_prefix": "icon", 5 | "default_icon_size": 14, 6 | "null_safety": true 7 | } 8 | -------------------------------------------------------------------------------- /scripts/update-snapshot.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cp -f ./scripts/config/normal.json ./iconfont.json 4 | npx ts-node src/commands/createIcon.ts 5 | 6 | cp -f ./scripts/config/nullsafety.json ./iconfont.json 7 | npx ts-node src/commands/createIcon.ts 8 | mv ./snapshots-1/icon_font.dart ./snapshots/null_safety.dart 9 | rmdir ./snapshots-1 10 | -------------------------------------------------------------------------------- /snapshots/icon_font.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter_svg/svg.dart'; 3 | 4 | enum IconNames { 5 | _123, setup, user, alipay 6 | } 7 | 8 | extension parseString on IconNames { 9 | String serialize() => this.toString().split('.').last; 10 | } 11 | 12 | /// A class includes all icons which you provided from https://iconfont.cn 13 | /// 14 | /// How to use it: 15 | /// ```dart 16 | /// IconFont(IconNames.xxx); 17 | /// IconFont(IconNames.xxx, color: '#f00'); 18 | /// IconFont(IconNames.xxx, colors: ['#f00', 'blue']); 19 | /// IconFont(IconNames.xxx, size: 30, color: '#000'); 20 | /// ``` 21 | /// 22 | /// The name is dynamic to against server interface. 23 | /// Feel free to input string literal. 24 | /// ```dart 25 | /// IconFont('xxx'); 26 | /// ``` 27 | class IconFont extends StatelessWidget { 28 | IconNames name; 29 | final String color; 30 | final List colors; 31 | final double size; 32 | 33 | IconFont(dynamic iconName, { this.size = 14, this.color, this.colors }) { 34 | this.name = getIconNames(iconName); 35 | } 36 | 37 | static IconNames getIconNames(dynamic iconName) { 38 | switch (iconName) { 39 | case '_123': 40 | iconName = IconNames._123; 41 | break; 42 | case 'setup': 43 | iconName = IconNames.setup; 44 | break; 45 | case 'user': 46 | iconName = IconNames.user; 47 | break; 48 | case 'alipay': 49 | iconName = IconNames.alipay; 50 | break; 51 | 52 | } 53 | return iconName; 54 | } 55 | 56 | static String getColor(int arrayIndex, String color, List colors, String defaultColor) { 57 | if (color != null && color.isNotEmpty) { 58 | return color; 59 | } 60 | 61 | if (colors != null && colors.isNotEmpty && colors.length > arrayIndex) { 62 | return colors.elementAt(arrayIndex); 63 | } 64 | 65 | return defaultColor; 66 | } 67 | 68 | @override 69 | Widget build(BuildContext context) { 70 | String svgXml; 71 | 72 | switch (this.name) { 73 | case IconNames._123: 74 | svgXml = ''' 75 | 76 | 80 | 84 | 88 | 92 | 93 | '''; 94 | break; 95 | case IconNames.setup: 96 | svgXml = ''' 97 | 98 | 102 | 106 | 111 | 115 | 119 | 124 | 128 | 133 | 137 | 142 | 143 | '''; 144 | break; 145 | case IconNames.user: 146 | svgXml = ''' 147 | 148 | 152 | 156 | 157 | '''; 158 | break; 159 | case IconNames.alipay: 160 | svgXml = ''' 161 | 162 | 166 | 170 | 171 | '''; 172 | break; 173 | 174 | } 175 | 176 | return SvgPicture.string(svgXml, width: this.size, height: this.size); 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /snapshots/null_safety.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter_svg/svg.dart'; 3 | 4 | enum IconNames { 5 | _123, setup, user, alipay 6 | } 7 | 8 | extension parseString on IconNames { 9 | String serialize() => this.toString().split('.').last; 10 | } 11 | 12 | /// A class includes all icons which you provided from https://iconfont.cn 13 | /// 14 | /// How to use it: 15 | /// ```dart 16 | /// IconFont(IconNames.xxx); 17 | /// IconFont(IconNames.xxx, color: '#f00'); 18 | /// IconFont(IconNames.xxx, colors: ['#f00', 'blue']); 19 | /// IconFont(IconNames.xxx, size: 30, color: '#000'); 20 | /// ``` 21 | /// 22 | /// The name is dynamic to against server interface. 23 | /// Feel free to input string literal. 24 | /// ```dart 25 | /// IconFont('xxx'); 26 | /// ``` 27 | class IconFont extends StatelessWidget { 28 | IconNames? name; 29 | final String? color; 30 | final List? colors; 31 | final double size; 32 | 33 | IconFont(dynamic iconName, { this.size = 14, this.color, this.colors }) { 34 | this.name = getIconNames(iconName); 35 | } 36 | 37 | static IconNames getIconNames(dynamic iconName) { 38 | switch (iconName) { 39 | case '_123': 40 | iconName = IconNames._123; 41 | break; 42 | case 'setup': 43 | iconName = IconNames.setup; 44 | break; 45 | case 'user': 46 | iconName = IconNames.user; 47 | break; 48 | case 'alipay': 49 | iconName = IconNames.alipay; 50 | break; 51 | 52 | } 53 | return iconName; 54 | } 55 | 56 | static String getColor(int arrayIndex, String? color, List? colors, String defaultColor) { 57 | if (color != null && color.isNotEmpty) { 58 | return color; 59 | } 60 | 61 | if (colors != null && colors.isNotEmpty && colors.length > arrayIndex) { 62 | return colors.elementAt(arrayIndex); 63 | } 64 | 65 | return defaultColor; 66 | } 67 | 68 | @override 69 | Widget build(BuildContext context) { 70 | String svgXml; 71 | 72 | switch (this.name!) { 73 | case IconNames._123: 74 | svgXml = ''' 75 | 76 | 80 | 84 | 88 | 92 | 93 | '''; 94 | break; 95 | case IconNames.setup: 96 | svgXml = ''' 97 | 98 | 102 | 106 | 111 | 115 | 119 | 124 | 128 | 133 | 137 | 142 | 143 | '''; 144 | break; 145 | case IconNames.user: 146 | svgXml = ''' 147 | 148 | 152 | 156 | 157 | '''; 158 | break; 159 | case IconNames.alipay: 160 | svgXml = ''' 161 | 162 | 166 | 170 | 171 | '''; 172 | break; 173 | 174 | } 175 | 176 | return SvgPicture.string(svgXml, width: this.size, height: this.size); 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /src/commands/createIcon.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import colors from 'colors'; 4 | import { getConfig } from '../libs/getConfig'; 5 | import { fetchXml } from 'iconfont-parser'; 6 | import { generateComponent } from '../libs/generateComponent'; 7 | 8 | const config = getConfig(); 9 | 10 | fetchXml(config.symbol_url).then((result) => { 11 | generateComponent(result, config); 12 | }).catch((e) => { 13 | console.error(colors.red(e.message || 'Unknown Error')); 14 | process.exit(1); 15 | }); 16 | -------------------------------------------------------------------------------- /src/commands/createJson.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import path from 'path'; 4 | import fs from 'fs'; 5 | import colors from 'colors'; 6 | 7 | const targetFile = path.resolve('iconfont.json'); 8 | 9 | if (fs.existsSync(targetFile)) { 10 | console.error(colors.red('File "iconfont.json" was created before.')); 11 | } else { 12 | fs.copyFileSync(path.join(__dirname, '../libs/iconfont.json'), targetFile); 13 | console.log(colors.green('File "iconfont.json" is created now. We recommend you add it to version control.')); 14 | } 15 | -------------------------------------------------------------------------------- /src/commands/help.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import colors from 'colors'; 4 | 5 | console.log([ 6 | '', 7 | 'Usage:', 8 | '', 9 | ' ' + colors.yellow('npx iconfont-init') + ' : generate config file', 10 | ' ' + colors.yellow('npx iconfont-flutter') + ' : generate icon components', 11 | '', 12 | ].join('\n')); 13 | -------------------------------------------------------------------------------- /src/libs/generateComponent.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import path from 'path'; 3 | import mkdirp from 'mkdirp'; 4 | import glob from 'glob'; 5 | import colors from 'colors'; 6 | import { snakeCase } from 'lodash'; 7 | import { XmlData } from 'iconfont-parser'; 8 | import { Config } from './getConfig'; 9 | import { getTemplate } from './getTemplate'; 10 | import { 11 | replaceCases, 12 | replaceConvertCases, 13 | replaceNames, 14 | replaceSize, 15 | } from './replace'; 16 | import { whitespace } from './whitespace'; 17 | 18 | const ATTRIBUTE_FILL_MAP = ['path']; 19 | 20 | export const generateComponent = (data: XmlData, config: Config) => { 21 | const names: string[] = []; 22 | const saveDir = path.resolve(config.save_dir); 23 | let cases: string = ''; 24 | let stringToEnumCases = ''; 25 | 26 | mkdirp.sync(saveDir); 27 | glob.sync(path.join(saveDir, '*')).forEach((file) => fs.unlinkSync(file)); 28 | 29 | data.svg.symbol.forEach((item) => { 30 | const iconId = item.$.id; 31 | let iconIdAfterTrim = snakeCase(config.trim_icon_prefix 32 | ? iconId.replace(new RegExp(`^${config.trim_icon_prefix}(.+?)$`), '$1') 33 | : iconId); 34 | 35 | // dart enum doesn't support keyword with digit prefix 36 | if (/^\d/.test(iconIdAfterTrim)) { 37 | iconIdAfterTrim = '_' + iconIdAfterTrim; 38 | } 39 | 40 | names.push(iconIdAfterTrim); 41 | 42 | cases += `${whitespace(6)}case IconNames.${iconIdAfterTrim}:\n`; 43 | cases += `${whitespace(8)}svgXml = '''${generateCase(item, 10)}${whitespace(8)}''';\n`; 44 | cases += `${whitespace(8)}break;\n`; 45 | 46 | stringToEnumCases += `${whitespace(6)}case '${iconIdAfterTrim}':\n`; 47 | stringToEnumCases += `${whitespace(8)}iconName = IconNames.${iconIdAfterTrim};\n`; 48 | stringToEnumCases += `${whitespace(8)}break;\n`; 49 | }); 50 | 51 | let iconFile = getTemplate(config.null_safety ? 'Icon.null.safety.dart' : 'Icon.dart'); 52 | 53 | iconFile = replaceSize(iconFile, config.default_icon_size); 54 | iconFile = replaceCases(iconFile, cases); 55 | iconFile = replaceConvertCases(iconFile, stringToEnumCases); 56 | iconFile = replaceNames(iconFile, names); 57 | 58 | fs.writeFileSync(path.join(saveDir, 'icon_font.dart'), iconFile); 59 | 60 | console.log(`\n${colors.green('√')} All icons have putted into dir: ${colors.green(config.save_dir)}\n`); 61 | }; 62 | 63 | const generateCase = (data: XmlData['svg']['symbol'][number], baseIdent: number) => { 64 | let template = `\n${whitespace(baseIdent)}\n`; 65 | 66 | for (const domName of Object.keys(data)) { 67 | if (domName === '$') { 68 | continue; 69 | } 70 | 71 | if (!domName) { 72 | console.error(colors.red(`Unable to transform dom "${domName}"`)); 73 | process.exit(1); 74 | } 75 | 76 | const counter = { 77 | colorIndex: 0, 78 | baseIdent, 79 | }; 80 | 81 | if (data[domName].$) { 82 | template += `${whitespace(baseIdent + 2)}<${domName}${addAttribute(domName, data[domName], counter)}\n${whitespace(baseIdent + 2)}/>\n`; 83 | } else if (Array.isArray(data[domName])) { 84 | data[domName].forEach((sub) => { 85 | template += `${whitespace(baseIdent + 2)}<${domName}${addAttribute(domName, sub, counter)}\n${whitespace(baseIdent + 2)}/>\n`; 86 | }); 87 | } 88 | } 89 | 90 | template += `${whitespace(baseIdent)}\n`; 91 | 92 | return template; 93 | }; 94 | 95 | const addAttribute = (domName: string, sub: XmlData['svg']['symbol'][number]['path'][number], counter: { colorIndex: number, baseIdent: number }) => { 96 | let template = ''; 97 | 98 | if (sub && sub.$) { 99 | if (ATTRIBUTE_FILL_MAP.includes(domName)) { 100 | // Set default color same as in iconfont.cn 101 | // And create placeholder to inject color by user's behavior 102 | sub.$.fill = sub.$.fill || '#333333'; 103 | } 104 | 105 | for (const attributeName of Object.keys(sub.$)) { 106 | if (attributeName === 'fill') { 107 | template += `\n${whitespace(counter.baseIdent + 4)}${attributeName}="''' + getColor(${counter.colorIndex}, color, colors, '${sub.$[attributeName]}') + '''"`; 108 | counter.colorIndex += 1; 109 | } else { 110 | template += `\n${whitespace(counter.baseIdent + 4)}${attributeName}="${sub.$[attributeName]}"`; 111 | } 112 | } 113 | } 114 | 115 | return template; 116 | }; 117 | -------------------------------------------------------------------------------- /src/libs/getConfig.ts: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import fs from 'fs'; 3 | import colors from 'colors'; 4 | import defaultConfig from './iconfont.json'; 5 | 6 | export interface Config { 7 | symbol_url: string; 8 | save_dir: string; 9 | trim_icon_prefix: string; 10 | default_icon_size: number; 11 | null_safety: boolean; 12 | } 13 | 14 | let cacheConfig: Config; 15 | 16 | export const getConfig = () => { 17 | if (cacheConfig) { 18 | return cacheConfig; 19 | } 20 | 21 | const targetFile = path.resolve('iconfont.json'); 22 | 23 | if (!fs.existsSync(targetFile)) { 24 | console.warn(colors.red('File "iconfont.json" doesn\'t exist, did you forget to generate it?')); 25 | process.exit(1); 26 | } 27 | 28 | const config = require(targetFile) as Config; 29 | 30 | if (!config.symbol_url || !/^(https?:)?\/\//.test(config.symbol_url)) { 31 | console.warn(colors.red('You are required to provide symbol_url')); 32 | process.exit(1); 33 | } 34 | 35 | if (config.symbol_url.indexOf('//') === 0) { 36 | config.symbol_url = 'http:' + config.symbol_url; 37 | } 38 | 39 | if (config.null_safety === undefined) { 40 | config.null_safety = false; 41 | } 42 | 43 | config.save_dir = config.save_dir || defaultConfig.save_dir; 44 | config.default_icon_size = config.default_icon_size || defaultConfig.default_icon_size; 45 | 46 | cacheConfig = config; 47 | 48 | return config; 49 | }; 50 | -------------------------------------------------------------------------------- /src/libs/getTemplate.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import path from 'path'; 3 | 4 | export const getTemplate = (fileName: string) => { 5 | return fs.readFileSync(path.join(__dirname, `../templates/${fileName}.template`)).toString(); 6 | }; 7 | -------------------------------------------------------------------------------- /src/libs/iconfont.json: -------------------------------------------------------------------------------- 1 | { 2 | "symbol_url": "请参考README.md,复制官网提供的JS链接", 3 | "save_dir": "./lib/iconfont", 4 | "trim_icon_prefix": "icon", 5 | "default_icon_size": 18, 6 | "null_safety": true 7 | } 8 | -------------------------------------------------------------------------------- /src/libs/replace.ts: -------------------------------------------------------------------------------- 1 | export const replaceSize = (content: string, size: number) => { 2 | return content.replace(/#size#/g, String(size)); 3 | }; 4 | 5 | export const replaceCases = (content: string, cases: string) => { 6 | return content.replace(/#cases#/g, cases); 7 | }; 8 | 9 | export const replaceConvertCases = (content: string, cases: string) => { 10 | return content.replace(/#convertCases#/g, cases); 11 | }; 12 | 13 | export const replaceNames = (content: string, names: string[]) => { 14 | return content.replace(/#names#/g, names.join(', ')); 15 | }; 16 | -------------------------------------------------------------------------------- /src/libs/whitespace.ts: -------------------------------------------------------------------------------- 1 | export const whitespace = (repeat: number) => { 2 | return ' '.repeat(repeat); 3 | }; 4 | -------------------------------------------------------------------------------- /src/templates/Icon.dart.template: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter_svg/svg.dart'; 3 | 4 | enum IconNames { 5 | #names# 6 | } 7 | 8 | extension parseString on IconNames { 9 | String serialize() => this.toString().split('.').last; 10 | } 11 | 12 | /// A class includes all icons which you provided from https://iconfont.cn 13 | /// 14 | /// How to use it: 15 | /// ```dart 16 | /// IconFont(IconNames.xxx); 17 | /// IconFont(IconNames.xxx, color: '#f00'); 18 | /// IconFont(IconNames.xxx, colors: ['#f00', 'blue']); 19 | /// IconFont(IconNames.xxx, size: 30, color: '#000'); 20 | /// ``` 21 | /// 22 | /// The name is dynamic to against server interface. 23 | /// Feel free to input string literal. 24 | /// ```dart 25 | /// IconFont('xxx'); 26 | /// ``` 27 | class IconFont extends StatelessWidget { 28 | IconNames name; 29 | final String color; 30 | final List colors; 31 | final double size; 32 | 33 | IconFont(dynamic iconName, { this.size = #size#, this.color, this.colors }) { 34 | this.name = getIconNames(iconName); 35 | } 36 | 37 | static IconNames getIconNames(dynamic iconName) { 38 | switch (iconName) { 39 | #convertCases# 40 | } 41 | return iconName; 42 | } 43 | 44 | static String getColor(int arrayIndex, String color, List colors, String defaultColor) { 45 | if (color != null && color.isNotEmpty) { 46 | return color; 47 | } 48 | 49 | if (colors != null && colors.isNotEmpty && colors.length > arrayIndex) { 50 | return colors.elementAt(arrayIndex); 51 | } 52 | 53 | return defaultColor; 54 | } 55 | 56 | @override 57 | Widget build(BuildContext context) { 58 | String svgXml; 59 | 60 | switch (this.name) { 61 | #cases# 62 | } 63 | 64 | return SvgPicture.string(svgXml, width: this.size, height: this.size); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/templates/Icon.null.safety.dart.template: -------------------------------------------------------------------------------- 1 | import 'package:flutter/cupertino.dart'; 2 | import 'package:flutter_svg/svg.dart'; 3 | 4 | enum IconNames { 5 | #names# 6 | } 7 | 8 | extension parseString on IconNames { 9 | String serialize() => this.toString().split('.').last; 10 | } 11 | 12 | /// A class includes all icons which you provided from https://iconfont.cn 13 | /// 14 | /// How to use it: 15 | /// ```dart 16 | /// IconFont(IconNames.xxx); 17 | /// IconFont(IconNames.xxx, color: '#f00'); 18 | /// IconFont(IconNames.xxx, colors: ['#f00', 'blue']); 19 | /// IconFont(IconNames.xxx, size: 30, color: '#000'); 20 | /// ``` 21 | /// 22 | /// The name is dynamic to against server interface. 23 | /// Feel free to input string literal. 24 | /// ```dart 25 | /// IconFont('xxx'); 26 | /// ``` 27 | class IconFont extends StatelessWidget { 28 | IconNames? name; 29 | final String? color; 30 | final List? colors; 31 | final double size; 32 | 33 | IconFont(dynamic iconName, { this.size = #size#, this.color, this.colors }) { 34 | this.name = getIconNames(iconName); 35 | } 36 | 37 | static IconNames getIconNames(dynamic iconName) { 38 | switch (iconName) { 39 | #convertCases# 40 | } 41 | return iconName; 42 | } 43 | 44 | static String getColor(int arrayIndex, String? color, List? colors, String defaultColor) { 45 | if (color != null && color.isNotEmpty) { 46 | return color; 47 | } 48 | 49 | if (colors != null && colors.isNotEmpty && colors.length > arrayIndex) { 50 | return colors.elementAt(arrayIndex); 51 | } 52 | 53 | return defaultColor; 54 | } 55 | 56 | @override 57 | Widget build(BuildContext context) { 58 | String svgXml; 59 | 60 | switch (this.name!) { 61 | #cases# 62 | } 63 | 64 | return SvgPicture.string(svgXml, width: this.size, height: this.size); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "lib": ["esnext"], 6 | "allowJs": false, 7 | "declaration": true, 8 | "removeComments": false, 9 | "outDir": "./build", 10 | "rootDir": "./", 11 | "jsx": "react", 12 | "importHelpers": true, 13 | "downlevelIteration": true, 14 | "strict": true, 15 | "noImplicitAny": false, 16 | "strictNullChecks": true, 17 | "strictFunctionTypes": true, 18 | "strictBindCallApply": true, 19 | "strictPropertyInitialization": true, 20 | "noImplicitThis": true, 21 | "alwaysStrict": true, 22 | 23 | "noUnusedLocals": true, 24 | "noUnusedParameters": true, 25 | "noImplicitReturns": true, 26 | "noFallthroughCasesInSwitch": true, 27 | "moduleResolution": "node", 28 | "allowSyntheticDefaultImports": true, 29 | "esModuleInterop": true, 30 | "resolveJsonModule": true 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@types/events@*": 6 | version "3.0.0" 7 | resolved "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" 8 | integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== 9 | 10 | "@types/glob@^7.1.1": 11 | version "7.1.1" 12 | resolved "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" 13 | integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w== 14 | dependencies: 15 | "@types/events" "*" 16 | "@types/minimatch" "*" 17 | "@types/node" "*" 18 | 19 | "@types/lodash@^4.14.137": 20 | version "4.14.137" 21 | resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.137.tgz#8a4804937dc6462274ffcc088df8f14fc1b368e2" 22 | integrity sha512-g4rNK5SRKloO+sUGbuO7aPtwbwzMgjK+bm9BBhLD7jGUiGR7zhwYEhSln/ihgYQBeIJ5j7xjyaYzrWTcu3UotQ== 23 | 24 | "@types/minimatch@*": 25 | version "3.0.3" 26 | resolved "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" 27 | integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== 28 | 29 | "@types/minimist@^1.2.0": 30 | version "1.2.0" 31 | resolved "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz#69a23a3ad29caf0097f06eda59b361ee2f0639f6" 32 | integrity sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY= 33 | 34 | "@types/mkdirp@^0.5.2": 35 | version "0.5.2" 36 | resolved "https://registry.npmjs.org/@types/mkdirp/-/mkdirp-0.5.2.tgz#503aacfe5cc2703d5484326b1b27efa67a339c1f" 37 | integrity sha512-U5icWpv7YnZYGsN4/cmh3WD2onMY0aJIiTE6+51TwJCttdHvtCYmkBNOobHlXwrJRL0nkH9jH4kD+1FAdMN4Tg== 38 | dependencies: 39 | "@types/node" "*" 40 | 41 | "@types/node@*", "@types/node@^12.7.2": 42 | version "12.7.2" 43 | resolved "https://registry.npmjs.org/@types/node/-/node-12.7.2.tgz#c4e63af5e8823ce9cc3f0b34f7b998c2171f0c44" 44 | integrity sha512-dyYO+f6ihZEtNPDcWNR1fkoTDf3zAK3lAABDze3mz6POyIercH0lEUawUFXlG8xaQZmm1yEBON/4TsYv/laDYg== 45 | 46 | "@types/prop-types@*": 47 | version "15.7.1" 48 | resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.1.tgz#f1a11e7babb0c3cad68100be381d1e064c68f1f6" 49 | integrity sha512-CFzn9idOEpHrgdw8JsoTkaDDyRWk1jrzIV8djzcgpq0y9tG4B4lFT+Nxh52DVpDXV+n4+NPNv7M1Dj5uMp6XFg== 50 | 51 | "@types/react@^16.9.2": 52 | version "16.9.2" 53 | resolved "https://registry.npmjs.org/@types/react/-/react-16.9.2.tgz#6d1765431a1ad1877979013906731aae373de268" 54 | integrity sha512-jYP2LWwlh+FTqGd9v7ynUKZzjj98T8x7Yclz479QdRhHfuW9yQ+0jjnD31eXSXutmBpppj5PYNLYLRfnZJvcfg== 55 | dependencies: 56 | "@types/prop-types" "*" 57 | csstype "^2.2.0" 58 | 59 | "@types/xml2js@^0.4.4": 60 | version "0.4.4" 61 | resolved "https://registry.npmjs.org/@types/xml2js/-/xml2js-0.4.4.tgz#2093d94359a201806d997dccefc80153db311c66" 62 | integrity sha512-O6Xgai01b9PB3IGA0lRIp1Ex3JBcxGDhdO0n3NIIpCyDOAjxcIGQFmkvgJpP8anTrthxOUQjBfLdRRi0Zn/TXA== 63 | dependencies: 64 | "@types/node" "*" 65 | 66 | arg@^4.1.0: 67 | version "4.1.1" 68 | resolved "https://registry.npmjs.org/arg/-/arg-4.1.1.tgz#485f8e7c390ce4c5f78257dbea80d4be11feda4c" 69 | integrity sha512-SlmP3fEA88MBv0PypnXZ8ZfJhwmDeIE3SP71j37AiXQBXYosPV0x6uISAaHYSlSVhmHOVkomen0tbGk6Anlebw== 70 | 71 | axios@^0.19.0: 72 | version "0.19.0" 73 | resolved "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8" 74 | integrity sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ== 75 | dependencies: 76 | follow-redirects "1.5.10" 77 | is-buffer "^2.0.2" 78 | 79 | balanced-match@^1.0.0: 80 | version "1.0.0" 81 | resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 82 | integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= 83 | 84 | brace-expansion@^1.1.7: 85 | version "1.1.11" 86 | resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 87 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 88 | dependencies: 89 | balanced-match "^1.0.0" 90 | concat-map "0.0.1" 91 | 92 | buffer-from@^1.0.0: 93 | version "1.1.1" 94 | resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" 95 | integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== 96 | 97 | colors@^1.3.3: 98 | version "1.3.3" 99 | resolved "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz#39e005d546afe01e01f9c4ca8fa50f686a01205d" 100 | integrity sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg== 101 | 102 | colors@^1.4.0: 103 | version "1.4.0" 104 | resolved "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" 105 | integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== 106 | 107 | concat-map@0.0.1: 108 | version "0.0.1" 109 | resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 110 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 111 | 112 | csstype@^2.2.0: 113 | version "2.6.6" 114 | resolved "https://registry.npmjs.org/csstype/-/csstype-2.6.6.tgz#c34f8226a94bbb10c32cc0d714afdf942291fc41" 115 | integrity sha512-RpFbQGUE74iyPgvr46U9t1xoQBM8T4BL8SxrN66Le2xYAPSaDJJKeztV3awugusb3g3G9iL8StmkBBXhcbbXhg== 116 | 117 | debug@=3.1.0: 118 | version "3.1.0" 119 | resolved "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" 120 | integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== 121 | dependencies: 122 | ms "2.0.0" 123 | 124 | diff@^4.0.1: 125 | version "4.0.1" 126 | resolved "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz#0c667cb467ebbb5cea7f14f135cc2dba7780a8ff" 127 | integrity sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q== 128 | 129 | follow-redirects@1.5.10: 130 | version "1.5.10" 131 | resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" 132 | integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== 133 | dependencies: 134 | debug "=3.1.0" 135 | 136 | fs.realpath@^1.0.0: 137 | version "1.0.0" 138 | resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 139 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 140 | 141 | glob@^7.1.4: 142 | version "7.1.4" 143 | resolved "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" 144 | integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== 145 | dependencies: 146 | fs.realpath "^1.0.0" 147 | inflight "^1.0.4" 148 | inherits "2" 149 | minimatch "^3.0.4" 150 | once "^1.3.0" 151 | path-is-absolute "^1.0.0" 152 | 153 | iconfont-parser@^1.0.0: 154 | version "1.0.0" 155 | resolved "https://registry.npmjs.org/iconfont-parser/-/iconfont-parser-1.0.0.tgz#1fa61be02677005a9a014653ef2eeb7503c3538a" 156 | integrity sha512-3RJceYHEjaqYyeDdfSAb1vP1x1Eb7ZtC9Xwetj+axm85sBlJU7HMvdNLVpwm/3g5eghYOdkQK+epUITZGAIqKQ== 157 | dependencies: 158 | axios "^0.19.0" 159 | colors "^1.4.0" 160 | tslib "^1.10.0" 161 | xml2js "^0.4.22" 162 | 163 | inflight@^1.0.4: 164 | version "1.0.6" 165 | resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 166 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 167 | dependencies: 168 | once "^1.3.0" 169 | wrappy "1" 170 | 171 | inherits@2: 172 | version "2.0.4" 173 | resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 174 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 175 | 176 | is-buffer@^2.0.2: 177 | version "2.0.3" 178 | resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725" 179 | integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw== 180 | 181 | lodash@^4.17.15: 182 | version "4.17.15" 183 | resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" 184 | integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== 185 | 186 | make-error@^1.1.1: 187 | version "1.3.5" 188 | resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8" 189 | integrity sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g== 190 | 191 | minimatch@^3.0.4: 192 | version "3.0.4" 193 | resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 194 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 195 | dependencies: 196 | brace-expansion "^1.1.7" 197 | 198 | minimist@0.0.8: 199 | version "0.0.8" 200 | resolved "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 201 | integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= 202 | 203 | minimist@^1.2.5: 204 | version "1.2.5" 205 | resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" 206 | integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== 207 | 208 | mkdirp@^0.5.1: 209 | version "0.5.1" 210 | resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 211 | integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= 212 | dependencies: 213 | minimist "0.0.8" 214 | 215 | ms@2.0.0: 216 | version "2.0.0" 217 | resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 218 | integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= 219 | 220 | once@^1.3.0: 221 | version "1.4.0" 222 | resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 223 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 224 | dependencies: 225 | wrappy "1" 226 | 227 | path-is-absolute@^1.0.0: 228 | version "1.0.1" 229 | resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 230 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 231 | 232 | sax@>=0.6.0: 233 | version "1.2.4" 234 | resolved "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" 235 | integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== 236 | 237 | source-map-support@^0.5.6: 238 | version "0.5.13" 239 | resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" 240 | integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== 241 | dependencies: 242 | buffer-from "^1.0.0" 243 | source-map "^0.6.0" 244 | 245 | source-map@^0.6.0: 246 | version "0.6.1" 247 | resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 248 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 249 | 250 | ts-node@^8.3.0: 251 | version "8.3.0" 252 | resolved "https://registry.npmjs.org/ts-node/-/ts-node-8.3.0.tgz#e4059618411371924a1fb5f3b125915f324efb57" 253 | integrity sha512-dyNS/RqyVTDcmNM4NIBAeDMpsAdaQ+ojdf0GOLqE6nwJOgzEkdRNzJywhDfwnuvB10oa6NLVG1rUJQCpRN7qoQ== 254 | dependencies: 255 | arg "^4.1.0" 256 | diff "^4.0.1" 257 | make-error "^1.1.1" 258 | source-map-support "^0.5.6" 259 | yn "^3.0.0" 260 | 261 | tslib@^1.10.0: 262 | version "1.10.0" 263 | resolved "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" 264 | integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== 265 | 266 | typescript@^3.5.3: 267 | version "3.5.3" 268 | resolved "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz#c830f657f93f1ea846819e929092f5fe5983e977" 269 | integrity sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g== 270 | 271 | wrappy@1: 272 | version "1.0.2" 273 | resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 274 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 275 | 276 | xml2js@^0.4.22: 277 | version "0.4.23" 278 | resolved "https://registry.npmjs.org/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" 279 | integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== 280 | dependencies: 281 | sax ">=0.6.0" 282 | xmlbuilder "~11.0.0" 283 | 284 | xmlbuilder@~11.0.0: 285 | version "11.0.1" 286 | resolved "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" 287 | integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== 288 | 289 | yn@^3.0.0: 290 | version "3.1.1" 291 | resolved "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" 292 | integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== 293 | --------------------------------------------------------------------------------