├── .flowconfig
├── .gitignore
├── LICENSE
├── PATENTS
├── README.md
├── bin.js
├── index.js
├── package.json
└── yarn.lock
/.flowconfig:
--------------------------------------------------------------------------------
1 | [ignore]
2 |
3 | [include]
4 |
5 | [libs]
6 |
7 | [options]
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | *.log
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD License
2 |
3 | For flow-inspect software
4 |
5 | Copyright (c) 2014-2016, Facebook, Inc. All rights reserved.
6 |
7 | Redistribution and use in source and binary forms, with or without modification,
8 | are permitted provided that the following conditions are met:
9 |
10 | * Redistributions of source code must retain the above copyright notice, this
11 | list of conditions and the following disclaimer.
12 |
13 | * Redistributions in binary form must reproduce the above copyright notice,
14 | this list of conditions and the following disclaimer in the documentation
15 | and/or other materials provided with the distribution.
16 |
17 | * Neither the name Facebook nor the names of its contributors may be used to
18 | endorse or promote products derived from this software without specific
19 | prior written permission.
20 |
21 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
22 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
25 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
28 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 |
--------------------------------------------------------------------------------
/PATENTS:
--------------------------------------------------------------------------------
1 | Additional Grant of Patent Rights Version 2
2 |
3 | "Software" means the flow-inspect software distributed by Facebook, Inc.
4 |
5 | Facebook, Inc. (“Facebook”) hereby grants to each recipient of the Software (“you”) a perpetual, worldwide, royalty-free, non-exclusive, irrevocable (subject to the termination provision below) license under any Necessary Claims, to make, have made, use, sell, offer to sell, import, and otherwise transfer the Software. For avoidance of doubt, no license is granted under Facebook’s rights in any patent claims that are infringed by (i) modifications to the Software made by you or any third party or (ii) the Software in combination with any software or other technology.
6 |
7 | The license granted hereunder will terminate, automatically and without notice, if you (or any of your subsidiaries, corporate affiliates or agents) initiate directly or indirectly, or take a direct financial interest in, any Patent Assertion: (i) against Facebook or any of its subsidiaries or corporate affiliates, (ii) against any party if such Patent Assertion arises in whole or in part from any software, technology, product or service of Facebook or any of its subsidiaries or corporate affiliates, or (iii) against any party relating to the Software. Notwithstanding the foregoing, if Facebook or any of its subsidiaries or corporate affiliates files a lawsuit alleging patent infringement against you in the first instance, and you respond by filing a patent infringement counterclaim in that lawsuit against that party that is unrelated to the Software, the license granted hereunder will not terminate under section (i) of this paragraph due to such counterclaim.
8 |
9 | A “Necessary Claim” is a claim of a patent owned by Facebook that is necessarily infringed by the Software standing alone.
10 |
11 | A “Patent Assertion” is any lawsuit or other action alleging direct, indirect, or contributory infringement or inducement to infringe any patent, including a cross-claim or counterclaim.
12 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # flow-inspect
2 |
3 | Inspect the internal types of Flow in an easy to read format.
4 |
5 | ```js
6 | yarn global add flow-bin flow-inspect
7 | ```
8 |
9 | ```js
10 | flow dump-types --raw test.js | flow-inspect
11 | ```
12 |
13 | ### Example
14 |
15 |
16 |
--------------------------------------------------------------------------------
/bin.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | 'use strict';
3 |
4 | const inspect = require('./');
5 |
6 | let stdin = '';
7 |
8 | process.stdin
9 | .setEncoding('utf8')
10 | .on('readable', () => {
11 | var chunk = process.stdin.read();
12 | if (chunk !== null) stdin += chunk;
13 | })
14 | .on('end', () => {
15 | const types = JSON.parse(stdin);
16 | const stdout = inspect(types)
17 | process.stdout.write(stdout + '\n');
18 | });
19 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | // @flow
2 |
3 | 'use strict';
4 |
5 | const chalk = require('chalk');
6 |
7 | const INDENT = chalk.gray(' ');
8 |
9 | let hasKind = value => value && (!!value.kind || !!value.name);
10 | let hasArrayOfKinds = value => Array.isArray(value) && value.every(hasKind);
11 |
12 | function maybePrint(key, value, indent) {
13 | if (key === 'kind' || key === 'name' || key === 'reason') return false;
14 | if (typeof value !== 'object' || value == null) return chalk.blue(value);
15 | if (hasKind(value) ) return printValue(value, indent);
16 | if (hasArrayOfKinds(value) ) return printList(value, indent);
17 | return printObject(value, indent);
18 | }
19 |
20 | function printValue(value, indent) {
21 | return printType(value, indent + INDENT);
22 | }
23 |
24 | function maybePrintKeyValue(key, value, indent) {
25 | const printedKey = chalk.yellow(key) + chalk.gray(':') + ' ';
26 | const printedValue = maybePrint(key, value, indent);
27 |
28 | if (printedValue) {
29 | return `\n${indent}${printedKey}${printedValue}`
30 | } else {
31 | return false;
32 | }
33 | }
34 |
35 | function printList(list, indent) {
36 | let body = '';
37 | let innerIndent = indent + INDENT;
38 |
39 | if (list.length) {
40 | body += '\n';
41 | for (let item of list) {
42 | body += innerIndent + printValue(item, innerIndent) + '\n';
43 | }
44 | body += indent;
45 | }
46 |
47 | return chalk.gray('[') + body + chalk.gray(']')
48 | }
49 |
50 | function printObject(val, indent) {
51 | let body = '';
52 | let keys = Object.keys(val);
53 | let innerIndent = indent + INDENT;
54 |
55 | if (keys.length) {
56 | for (let key of keys) {
57 | const printedKeyValue = maybePrintKeyValue(key, val[key], innerIndent);
58 | if (printedKeyValue) body += printedKeyValue;
59 | }
60 | body += '\n' + indent;
61 | }
62 |
63 | return chalk.gray('{') + body + chalk.gray('}');
64 | }
65 |
66 | function printPos({line, column}) {
67 | return `${line},${column}`;
68 | }
69 |
70 | function printReason(reason) {
71 | const {start, end} = reason.pos;
72 | const printedPos = chalk.italic(`${printPos(start)} - ${printPos(end)}`);
73 | return chalk.gray(`(${reason.desc}) @ ${printedPos}`);
74 | }
75 |
76 | function printType(type, indent) {
77 | const {kind, name, reason} = type;
78 | const keys = Object.keys(type);
79 |
80 | let printedKind = chalk.green(kind || chalk.italic(name));
81 | if (reason) printedKind += ' ' + printReason(reason);
82 |
83 | let printedKeys = '';
84 |
85 | keys.forEach(key => {
86 | const printedKeyValue = maybePrintKeyValue(key, type[key], indent);
87 | if (printedKeyValue) printedKeys += printedKeyValue;
88 | });
89 |
90 | return printedKind + printedKeys;
91 | }
92 |
93 | module.exports = function inspect(types /* : Object */) /* : string */ {
94 | return types.map(type => {
95 | const raw = JSON.parse(type.raw_type);
96 | return printType(raw, INDENT);
97 | }).join('\n')
98 | };
99 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "flow-inspect",
3 | "description": "Inspect the internal types of Flow in an easy to read format",
4 | "version": "1.0.1",
5 | "main": "index.js",
6 | "bin": "bin.js",
7 | "author": "James Kyle ",
8 | "license": "BSD-3-Clause",
9 | "dependencies": {
10 | "chalk": "^1.1.3"
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | ansi-regex@^2.0.0:
6 | version "2.0.0"
7 | resolved ansi-regex-2.0.0.tgz#c5061b6e0ef8a81775e50f5d66151bf6bf371107
8 |
9 | ansi-styles@^2.2.1:
10 | version "2.2.1"
11 | resolved ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe
12 |
13 | array-find-index@^1.0.1:
14 | version "1.0.2"
15 | resolved array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1
16 |
17 | builtin-modules@^1.0.0:
18 | version "1.1.1"
19 | resolved builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f
20 |
21 | camelcase-keys@^2.0.0:
22 | version "2.1.0"
23 | resolved camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7
24 | dependencies:
25 | camelcase "^2.0.0"
26 | map-obj "^1.0.0"
27 |
28 | camelcase@^2.0.0:
29 | version "2.1.1"
30 | resolved camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f
31 |
32 | chalk@^1.1.3:
33 | version "1.1.3"
34 | resolved chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98
35 | dependencies:
36 | ansi-styles "^2.2.1"
37 | escape-string-regexp "^1.0.2"
38 | has-ansi "^2.0.0"
39 | strip-ansi "^3.0.0"
40 | supports-color "^2.0.0"
41 |
42 | currently-unhandled@^0.4.1:
43 | version "0.4.1"
44 | resolved currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea
45 | dependencies:
46 | array-find-index "^1.0.1"
47 |
48 | decamelize@^1.1.2:
49 | version "1.2.0"
50 | resolved decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290
51 |
52 | error-ex@^1.2.0:
53 | version "1.3.0"
54 | resolved error-ex-1.3.0.tgz#e67b43f3e82c96ea3a584ffee0b9fc3325d802d9
55 | dependencies:
56 | is-arrayish "^0.2.1"
57 |
58 | escape-string-regexp@^1.0.2:
59 | version "1.0.5"
60 | resolved escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4
61 |
62 | find-up@^1.0.0:
63 | version "1.1.2"
64 | resolved find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f
65 | dependencies:
66 | path-exists "^2.0.0"
67 | pinkie-promise "^2.0.0"
68 |
69 | get-stdin@^4.0.1:
70 | version "4.0.1"
71 | resolved get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe
72 |
73 | graceful-fs@^4.1.2:
74 | version "4.1.11"
75 | resolved graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658
76 |
77 | has-ansi@^2.0.0:
78 | version "2.0.0"
79 | resolved has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91
80 | dependencies:
81 | ansi-regex "^2.0.0"
82 |
83 | hosted-git-info@^2.1.4:
84 | version "2.1.5"
85 | resolved hosted-git-info-2.1.5.tgz#0ba81d90da2e25ab34a332e6ec77936e1598118b
86 |
87 | indent-string@^2.1.0:
88 | version "2.1.0"
89 | resolved indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80
90 | dependencies:
91 | repeating "^2.0.0"
92 |
93 | is-arrayish@^0.2.1:
94 | version "0.2.1"
95 | resolved is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d
96 |
97 | is-builtin-module@^1.0.0:
98 | version "1.0.0"
99 | resolved is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe
100 | dependencies:
101 | builtin-modules "^1.0.0"
102 |
103 | is-finite@^1.0.0:
104 | version "1.0.2"
105 | resolved is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa
106 | dependencies:
107 | number-is-nan "^1.0.0"
108 |
109 | is-utf8@^0.2.0:
110 | version "0.2.1"
111 | resolved is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72
112 |
113 | load-json-file@^1.0.0:
114 | version "1.1.0"
115 | resolved load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0
116 | dependencies:
117 | graceful-fs "^4.1.2"
118 | parse-json "^2.2.0"
119 | pify "^2.0.0"
120 | pinkie-promise "^2.0.0"
121 | strip-bom "^2.0.0"
122 |
123 | loud-rejection@^1.0.0:
124 | version "1.6.0"
125 | resolved loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f
126 | dependencies:
127 | currently-unhandled "^0.4.1"
128 | signal-exit "^3.0.0"
129 |
130 | map-obj@^1.0.0, map-obj@^1.0.1:
131 | version "1.0.1"
132 | resolved map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d
133 |
134 | meow@^3.7.0:
135 | version "3.7.0"
136 | resolved meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb
137 | dependencies:
138 | camelcase-keys "^2.0.0"
139 | decamelize "^1.1.2"
140 | loud-rejection "^1.0.0"
141 | map-obj "^1.0.1"
142 | minimist "^1.1.3"
143 | normalize-package-data "^2.3.4"
144 | object-assign "^4.0.1"
145 | read-pkg-up "^1.0.1"
146 | redent "^1.0.0"
147 | trim-newlines "^1.0.0"
148 |
149 | minimist@^1.1.3:
150 | version "1.2.0"
151 | resolved minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284
152 |
153 | normalize-package-data@^2.3.2, normalize-package-data@^2.3.4:
154 | version "2.3.5"
155 | resolved normalize-package-data-2.3.5.tgz#8d924f142960e1777e7ffe170543631cc7cb02df
156 | dependencies:
157 | hosted-git-info "^2.1.4"
158 | is-builtin-module "^1.0.0"
159 | semver "2 || 3 || 4 || 5"
160 | validate-npm-package-license "^3.0.1"
161 |
162 | number-is-nan@^1.0.0:
163 | version "1.0.1"
164 | resolved number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d
165 |
166 | object-assign@^4.0.1:
167 | version "4.1.0"
168 | resolved object-assign-4.1.0.tgz#7a3b3d0e98063d43f4c03f2e8ae6cd51a86883a0
169 |
170 | parse-json@^2.2.0:
171 | version "2.2.0"
172 | resolved parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9
173 | dependencies:
174 | error-ex "^1.2.0"
175 |
176 | path-exists@^2.0.0:
177 | version "2.1.0"
178 | resolved path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b
179 | dependencies:
180 | pinkie-promise "^2.0.0"
181 |
182 | path-type@^1.0.0:
183 | version "1.1.0"
184 | resolved path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441
185 | dependencies:
186 | graceful-fs "^4.1.2"
187 | pify "^2.0.0"
188 | pinkie-promise "^2.0.0"
189 |
190 | pify@^2.0.0:
191 | version "2.3.0"
192 | resolved pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c
193 |
194 | pinkie-promise@^2.0.0:
195 | version "2.0.1"
196 | resolved pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa
197 | dependencies:
198 | pinkie "^2.0.0"
199 |
200 | pinkie@^2.0.0:
201 | version "2.0.4"
202 | resolved pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870
203 |
204 | read-pkg-up@^1.0.1:
205 | version "1.0.1"
206 | resolved read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02
207 | dependencies:
208 | find-up "^1.0.0"
209 | read-pkg "^1.0.0"
210 |
211 | read-pkg@^1.0.0:
212 | version "1.1.0"
213 | resolved read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28
214 | dependencies:
215 | load-json-file "^1.0.0"
216 | normalize-package-data "^2.3.2"
217 | path-type "^1.0.0"
218 |
219 | redent@^1.0.0:
220 | version "1.0.0"
221 | resolved redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde
222 | dependencies:
223 | indent-string "^2.1.0"
224 | strip-indent "^1.0.1"
225 |
226 | repeating@^2.0.0:
227 | version "2.0.1"
228 | resolved repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda
229 | dependencies:
230 | is-finite "^1.0.0"
231 |
232 | "semver@2 || 3 || 4 || 5":
233 | version "5.3.0"
234 | resolved semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f
235 |
236 | signal-exit@^3.0.0:
237 | version "3.0.2"
238 | resolved signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d
239 |
240 | spdx-correct@~1.0.0:
241 | version "1.0.2"
242 | resolved spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40
243 | dependencies:
244 | spdx-license-ids "^1.0.2"
245 |
246 | spdx-expression-parse@~1.0.0:
247 | version "1.0.4"
248 | resolved spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c
249 |
250 | spdx-license-ids@^1.0.2:
251 | version "1.2.2"
252 | resolved spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57
253 |
254 | strip-ansi@^3.0.0:
255 | version "3.0.1"
256 | resolved strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf
257 | dependencies:
258 | ansi-regex "^2.0.0"
259 |
260 | strip-bom@^2.0.0:
261 | version "2.0.0"
262 | resolved strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e
263 | dependencies:
264 | is-utf8 "^0.2.0"
265 |
266 | strip-indent@^1.0.1:
267 | version "1.0.1"
268 | resolved strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2
269 | dependencies:
270 | get-stdin "^4.0.1"
271 |
272 | supports-color@^2.0.0:
273 | version "2.0.0"
274 | resolved supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7
275 |
276 | trim-newlines@^1.0.0:
277 | version "1.0.0"
278 | resolved trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613
279 |
280 | validate-npm-package-license@^3.0.1:
281 | version "3.0.1"
282 | resolved validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc
283 | dependencies:
284 | spdx-correct "~1.0.0"
285 | spdx-expression-parse "~1.0.0"
286 |
--------------------------------------------------------------------------------