From 6b00bb4d78d327e4e65b9df07ca1115ce28eaf47 Mon Sep 17 00:00:00 2001 From: "Fabio M. Costa" Date: Mon, 9 Jul 2018 21:26:04 -0700 Subject: [PATCH 1/5] Add Flow to react-ape --- packages/react-ape/package.json | 9 +- yarn.lock | 357 ++++++++++++++++++++++++++++++-- 2 files changed, 352 insertions(+), 14 deletions(-) diff --git a/packages/react-ape/package.json b/packages/react-ape/package.json index 0b5562f..37b8111 100644 --- a/packages/react-ape/package.json +++ b/packages/react-ape/package.json @@ -3,6 +3,9 @@ "version": "0.0.6", "description": "React Renderer to build interfaces using canvas/WebGL", "main": "index.js", + "scripts": { + "flow": "flow" + }, "peerDependencies": { "react": "^16.4.1" }, @@ -28,5 +31,9 @@ "bugs": { "url": "https://github.com/raphamorim/react-ape/issues" }, - "homepage": "https://github.com/raphamorim/react-ape#readme" + "homepage": "https://github.com/raphamorim/react-ape#readme", + "devDependencies": { + "flow-bin": "^0.76.0", + "flow-typed": "^2.5.1" + } } diff --git a/yarn.lock b/yarn.lock index 9d7b4d0..8a9742b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16,6 +16,19 @@ esutils "^2.0.2" js-tokens "^3.0.0" +"@octokit/rest@^15.2.6": + version "15.9.4" + resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-15.9.4.tgz#c6cf0f483275d9c798b18419b7c9d417493bb70f" + dependencies: + before-after-hook "^1.1.0" + btoa-lite "^1.0.0" + debug "^3.1.0" + http-proxy-agent "^2.1.0" + https-proxy-agent "^2.2.0" + lodash "^4.17.4" + node-fetch "^2.1.1" + url-template "^2.0.8" + "@types/estree@0.0.39": version "0.0.39" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" @@ -63,7 +76,13 @@ acorn@^5.0.0: version "5.6.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.6.2.tgz#b1da1d7be2ac1b4a327fb9eab851702c5045b4e7" -ajv-keywords@^3.1.0: +agent-base@4, agent-base@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" + dependencies: + es6-promisify "^5.0.0" + +ajv-keywords@^3.0.0, ajv-keywords@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" @@ -76,6 +95,15 @@ ajv@^5.1.0: fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" +ajv@^6.0.1: + version "6.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.2.tgz#678495f9b82f7cca6be248dd92f59bff5e1f4360" + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.1" + ajv@^6.1.0: version "6.5.1" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.1.tgz#88ebc1263c7133937d108b80c5572e64e1d9322d" @@ -982,6 +1010,14 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" +before-after-hook@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-1.1.0.tgz#83165e15a59460d13702cb8febd6a1807896db5a" + +big-integer@^1.6.17: + version "1.6.32" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.32.tgz#5867458b25ecd5bcb36b627c30bb501a13c07e89" + big.js@^3.1.3: version "3.2.0" resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" @@ -990,10 +1026,21 @@ binary-extensions@^1.0.0: version "1.11.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" +binary@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/binary/-/binary-0.3.0.tgz#9f60553bc5ce8c3386f3b553cff47462adecaa79" + dependencies: + buffers "~0.1.1" + chainsaw "~0.1.0" + bluebird@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" +bluebird@~3.4.1: + version "3.4.7" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" + bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: version "4.11.8" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" @@ -1129,14 +1176,26 @@ bser@^2.0.0: dependencies: node-int64 "^0.4.0" +btoa-lite@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337" + buffer-from@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.0.tgz#87fcaa3a298358e0ade6e442cfce840740d1ad04" +buffer-indexof-polyfill@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.1.tgz#a9fb806ce8145d5428510ce72f278bb363a638bf" + buffer-indexof@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" +buffer-shims@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" + buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" @@ -1149,6 +1208,10 @@ buffer@^4.3.0: ieee754 "^1.1.4" isarray "^1.0.0" +buffers@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb" + builtin-modules@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" @@ -1245,6 +1308,12 @@ center-align@^0.1.1: align-text "^0.1.3" lazy-cache "^1.0.3" +chainsaw@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98" + dependencies: + traverse ">=0.3.0 <0.4" + chalk@^1.0.0, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -1255,7 +1324,7 @@ chalk@^1.0.0, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.1: +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" dependencies: @@ -1263,6 +1332,10 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.1: escape-string-regexp "^1.0.5" supports-color "^5.3.0" +charenc@~0.0.1: + version "0.0.2" + resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" + chokidar@^2.0.0, chokidar@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.3.tgz#dcbd4f6cbb2a55b4799ba8a840ac527e5f4b1176" @@ -1366,6 +1439,10 @@ color-name@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689" +colors@^1.1.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.0.tgz#5f20c9fef6945cb1134260aab33bfbdc8295e04e" + combined-stream@1.0.6, combined-stream@~1.0.5: version "1.0.6" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" @@ -1528,6 +1605,10 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" +crypt@~0.0.1: + version "0.0.2" + resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" + crypto-browserify@^3.11.0: version "3.12.0" resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" @@ -1586,7 +1667,7 @@ debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.6, debug@^2.6. dependencies: ms "2.0.0" -debug@^3.1.0: +debug@3.1.0, debug@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" dependencies: @@ -1600,6 +1681,12 @@ decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" +decompress-response@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + dependencies: + mimic-response "^1.0.0" + deep-equal@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" @@ -1729,6 +1816,16 @@ domain-browser@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" +duplexer2@~0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" + dependencies: + readable-stream "^2.0.2" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + duplexify@^3.4.2, duplexify@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.6.0.tgz#592903f5d80b38d037220541264d69a198fb3410" @@ -1850,6 +1947,16 @@ es6-map@^0.1.3: es6-symbol "~3.1.1" event-emitter "~0.3.5" +es6-promise@^4.0.3: + version "4.2.4" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29" + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + dependencies: + es6-promise "^4.0.3" + es6-set@~0.1.5: version "0.1.5" resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" @@ -2218,6 +2325,30 @@ find-up@^2.0.0, find-up@^2.1.0: dependencies: locate-path "^2.0.0" +flow-bin@^0.76.0: + version "0.76.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.76.0.tgz#eb00036991c3abc106743fcbc7ee321f02aa4faa" + +flow-typed@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/flow-typed/-/flow-typed-2.5.1.tgz#0ff565cc94d2af8c557744ba364b6f14726a6b9f" + dependencies: + "@octokit/rest" "^15.2.6" + babel-polyfill "^6.26.0" + colors "^1.1.2" + fs-extra "^5.0.0" + glob "^7.1.2" + got "^7.1.0" + md5 "^2.1.0" + mkdirp "^0.5.1" + rimraf "^2.6.2" + semver "^5.5.0" + table "^4.0.2" + through "^2.3.8" + unzipper "^0.8.11" + which "^1.3.0" + yargs "^4.2.0" + flush-write-stream@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd" @@ -2278,6 +2409,14 @@ from2@^2.1.0: inherits "^2.0.1" readable-stream "^2.0.0" +fs-extra@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-5.0.0.tgz#414d0110cdd06705734d055652c5411260c31abd" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-minipass@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" @@ -2304,6 +2443,15 @@ fsevents@^1.1.2, fsevents@^1.2.3: nan "^2.9.2" node-pre-gyp "^0.10.0" +fstream@~1.0.10: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -2396,7 +2544,26 @@ google-closure-compiler@20180506.0.0: vinyl "^2.0.1" vinyl-sourcemaps-apply "^0.2.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.2: +got@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" + dependencies: + decompress-response "^3.2.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-plain-obj "^1.1.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + p-cancelable "^0.3.0" + p-timeout "^1.1.1" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + url-parse-lax "^1.0.0" + url-to-options "^1.0.1" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -2447,6 +2614,16 @@ has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" +has-symbol-support-x@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + +has-to-string-tag-x@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + dependencies: + has-symbol-support-x "^1.4.1" + has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -2562,6 +2739,13 @@ http-parser-js@>=0.4.0: version "0.4.13" resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.13.tgz#3bd6d6fde6e3172c9334c3b33b6c193d80fe1137" +http-proxy-agent@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" + dependencies: + agent-base "4" + debug "3.1.0" + http-proxy-middleware@~0.17.4: version "0.17.4" resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz#642e8848851d66f09d4f124912846dbaeb41b833" @@ -2591,6 +2775,13 @@ https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" +https-proxy-agent@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0" + dependencies: + agent-base "^4.1.0" + debug "^3.1.0" + iconv-lite@0.4.19: version "0.4.19" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" @@ -2643,7 +2834,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" @@ -2705,7 +2896,7 @@ is-binary-path@^1.0.0: dependencies: binary-extensions "^1.0.0" -is-buffer@^1.1.5: +is-buffer@^1.1.5, is-buffer@~1.1.1: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -2839,6 +3030,10 @@ is-number@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" +is-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" + is-odd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-odd/-/is-odd-2.0.0.tgz#7646624671fd7ea558ccd9a2795182f2958f1b24" @@ -2861,6 +3056,10 @@ is-path-inside@^1.0.0: dependencies: path-is-inside "^1.0.1" +is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -2881,7 +3080,11 @@ is-regex@^1.0.4: dependencies: has "^1.0.1" -is-stream@^1.0.1, is-stream@^1.1.0: +is-retry-allowed@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + +is-stream@^1.0.0, is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -3008,6 +3211,13 @@ istanbul-reports@^1.3.0: dependencies: handlebars "^4.0.3" +isurl@^1.0.0-alpha5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + dependencies: + has-to-string-tag-x "^1.2.0" + is-object "^1.0.1" + jest-changed-files@^21.2.0: version "21.2.0" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-21.2.0.tgz#5dbeecad42f5d88b482334902ce1cba6d9798d29" @@ -3314,6 +3524,12 @@ json5@^0.5.0, json5@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + optionalDependencies: + graceful-fs "^4.1.6" + jsonify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" @@ -3372,6 +3588,10 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +listenercount@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/listenercount/-/listenercount-1.0.1.tgz#84c8a72ab59c4725321480c975e6508342e70937" + load-json-file@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" @@ -3439,6 +3659,10 @@ loud-rejection@^1.0.0: currently-unhandled "^0.4.1" signal-exit "^3.0.0" +lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + lru-cache@^4.0.1, lru-cache@^4.1.1: version "4.1.3" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" @@ -3501,6 +3725,14 @@ md5.js@^1.3.4: hash-base "^3.0.0" inherits "^2.0.1" +md5@^2.1.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" + dependencies: + charenc "~0.0.1" + crypt "~0.0.1" + is-buffer "~1.1.1" + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -3614,6 +3846,10 @@ mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" +mimic-response@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e" + minimalistic-assert@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" @@ -3675,7 +3911,7 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@0.5.x, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: +mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" dependencies: @@ -3759,6 +3995,10 @@ node-fetch@^1.0.1: encoding "^0.1.11" is-stream "^1.0.1" +node-fetch@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.1.2.tgz#ab884e8e7e57e38a944753cec706f788d1768bb5" + node-forge@0.7.5: version "0.7.5" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df" @@ -4031,6 +4271,12 @@ p-map@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" +p-timeout@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" + dependencies: + p-finally "^1.0.0" + p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" @@ -4190,6 +4436,10 @@ prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" @@ -4213,6 +4463,10 @@ process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + process@^0.11.10: version "0.11.10" resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" @@ -4436,6 +4690,18 @@ read-pkg@^2.0.0: string_decoder "~1.1.1" util-deprecate "~1.0.1" +readable-stream@~2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0" + dependencies: + buffer-shims "^1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + readdirp@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" @@ -4596,7 +4862,7 @@ right-align@^0.1.1: dependencies: align-text "^0.1.1" -rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: +rimraf@2, rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" dependencies: @@ -4753,7 +5019,7 @@ selfsigned@^1.9.1: dependencies: node-forge "0.7.5" -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1: +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" @@ -4826,7 +5092,7 @@ set-value@^2.0.0: is-plain-object "^2.0.3" split-string "^3.0.1" -setimmediate@^1.0.4, setimmediate@^1.0.5: +setimmediate@^1.0.4, setimmediate@^1.0.5, setimmediate@~1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" @@ -4867,6 +5133,12 @@ slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" +slice-ansi@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" + dependencies: + is-fullwidth-code-point "^2.0.0" + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -5084,7 +5356,7 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2", string-width@^2.0.0: +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" dependencies: @@ -5097,6 +5369,10 @@ string_decoder@^1.0.0, string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" @@ -5167,6 +5443,17 @@ symbol-tree@^3.2.1: version "3.2.2" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" +table@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/table/-/table-4.0.3.tgz#00b5e2b602f1794b9acaf9ca908a76386a7813bc" + dependencies: + ajv "^6.0.1" + ajv-keywords "^3.0.0" + chalk "^2.1.0" + lodash "^4.17.4" + slice-ansi "1.0.0" + string-width "^2.1.1" + tapable@^0.2.7: version "0.2.8" resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.8.tgz#99372a5c999bf2df160afc0d74bed4f47948cd22" @@ -5204,6 +5491,10 @@ through2@^2.0.0: readable-stream "^2.1.5" xtend "~4.0.1" +through@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + thunky@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.0.2.tgz#a862e018e3fb1ea2ec3fce5d55605cf57f247371" @@ -5212,6 +5503,10 @@ time-stamp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-2.0.0.tgz#95c6a44530e15ba8d6f4a3ecb8c3a3fac46da357" +timed-out@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + timers-browserify@^2.0.4: version "2.0.10" resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" @@ -5275,6 +5570,10 @@ tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" +"traverse@>=0.3.0 <0.4": + version "0.3.9" + resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" + trim-newlines@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" @@ -5387,6 +5686,10 @@ unique-slug@^2.0.0: dependencies: imurmurhash "^0.1.4" +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" @@ -5398,6 +5701,20 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" +unzipper@^0.8.11: + version "0.8.14" + resolved "https://registry.yarnpkg.com/unzipper/-/unzipper-0.8.14.tgz#ade0524cd2fc14d11b8de258be22f9d247d3f79b" + dependencies: + big-integer "^1.6.17" + binary "~0.3.0" + bluebird "~3.4.1" + buffer-indexof-polyfill "~1.0.0" + duplexer2 "~0.1.4" + fstream "~1.0.10" + listenercount "~1.0.1" + readable-stream "~2.1.5" + setimmediate "~1.0.4" + upath@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" @@ -5412,6 +5729,12 @@ urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + dependencies: + prepend-http "^1.0.1" + url-parse@^1.1.8, url-parse@~1.4.0: version "1.4.1" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.1.tgz#4dec9dad3dc8585f862fed461d2e19bbf623df30" @@ -5419,6 +5742,14 @@ url-parse@^1.1.8, url-parse@~1.4.0: querystringify "^2.0.0" requires-port "^1.0.0" +url-template@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21" + +url-to-options@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + url@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" @@ -5767,7 +6098,7 @@ yargs@6.6.0: y18n "^3.2.1" yargs-parser "^4.2.0" -yargs@^4.8.1: +yargs@^4.2.0, yargs@^4.8.1: version "4.8.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0" dependencies: From e31a619fbeb30a487263dc8df09e7eec7a73dec7 Mon Sep 17 00:00:00 2001 From: "Fabio M. Costa" Date: Mon, 9 Jul 2018 21:26:57 -0700 Subject: [PATCH 2/5] addinf flowconfig and flow-typed folders --- packages/react-ape/.flowconfig | 20 + .../react-ape/flow-typed/npm/jest_v21.x.x.js | 630 ++++++++++++++++++ 2 files changed, 650 insertions(+) create mode 100644 packages/react-ape/.flowconfig create mode 100644 packages/react-ape/flow-typed/npm/jest_v21.x.x.js diff --git a/packages/react-ape/.flowconfig b/packages/react-ape/.flowconfig new file mode 100644 index 0000000..61d5ba0 --- /dev/null +++ b/packages/react-ape/.flowconfig @@ -0,0 +1,20 @@ +[ignore] + +[include] + +[libs] + +[lints] +all=warn + +[options] +module.use_strict=true +suppress_type=$FlowIssue +suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe + +[strict] +nonstrict-import +unclear-type +unsafe-getters-setters +untyped-import +untyped-type-import diff --git a/packages/react-ape/flow-typed/npm/jest_v21.x.x.js b/packages/react-ape/flow-typed/npm/jest_v21.x.x.js new file mode 100644 index 0000000..e583351 --- /dev/null +++ b/packages/react-ape/flow-typed/npm/jest_v21.x.x.js @@ -0,0 +1,630 @@ +// flow-typed signature: 483ecb6e4d88147c244d0b4e27951c1e +// flow-typed version: a5bbe16c29/jest_v21.x.x/flow_>=v0.39.x + +type JestMockFn, TReturn> = { + (...args: TArguments): TReturn, + /** + * An object for introspecting mock calls + */ + mock: { + /** + * An array that represents all calls that have been made into this mock + * function. Each call is represented by an array of arguments that were + * passed during the call. + */ + calls: Array, + /** + * An array that contains all the object instances that have been + * instantiated from this mock function. + */ + instances: Array + }, + /** + * Resets all information stored in the mockFn.mock.calls and + * mockFn.mock.instances arrays. Often this is useful when you want to clean + * up a mock's usage data between two assertions. + */ + mockClear(): void, + /** + * Resets all information stored in the mock. This is useful when you want to + * completely restore a mock back to its initial state. + */ + mockReset(): void, + /** + * Removes the mock and restores the initial implementation. This is useful + * when you want to mock functions in certain test cases and restore the + * original implementation in others. Beware that mockFn.mockRestore only + * works when mock was created with jest.spyOn. Thus you have to take care of + * restoration yourself when manually assigning jest.fn(). + */ + mockRestore(): void, + /** + * Accepts a function that should be used as the implementation of the mock. + * The mock itself will still record all calls that go into and instances + * that come from itself -- the only difference is that the implementation + * will also be executed when the mock is called. + */ + mockImplementation( + fn: (...args: TArguments) => TReturn + ): JestMockFn, + /** + * Accepts a function that will be used as an implementation of the mock for + * one call to the mocked function. Can be chained so that multiple function + * calls produce different results. + */ + mockImplementationOnce( + fn: (...args: TArguments) => TReturn + ): JestMockFn, + /** + * Just a simple sugar function for returning `this` + */ + mockReturnThis(): void, + /** + * Deprecated: use jest.fn(() => value) instead + */ + mockReturnValue(value: TReturn): JestMockFn, + /** + * Sugar for only returning a value once inside your mock + */ + mockReturnValueOnce(value: TReturn): JestMockFn +}; + +type JestAsymmetricEqualityType = { + /** + * A custom Jasmine equality tester + */ + asymmetricMatch(value: mixed): boolean +}; + +type JestCallsType = { + allArgs(): mixed, + all(): mixed, + any(): boolean, + count(): number, + first(): mixed, + mostRecent(): mixed, + reset(): void +}; + +type JestClockType = { + install(): void, + mockDate(date: Date): void, + tick(milliseconds?: number): void, + uninstall(): void +}; + +type JestMatcherResult = { + message?: string | (() => string), + pass: boolean +}; + +type JestMatcher = (actual: any, expected: any) => JestMatcherResult; + +type JestPromiseType = { + /** + * Use rejects to unwrap the reason of a rejected promise so any other + * matcher can be chained. If the promise is fulfilled the assertion fails. + */ + rejects: JestExpectType, + /** + * Use resolves to unwrap the value of a fulfilled promise so any other + * matcher can be chained. If the promise is rejected the assertion fails. + */ + resolves: JestExpectType +}; + +/** + * Plugin: jest-enzyme + */ +type EnzymeMatchersType = { + toBeChecked(): void, + toBeDisabled(): void, + toBeEmpty(): void, + toBePresent(): void, + toContainReact(element: React$Element): void, + toHaveClassName(className: string): void, + toHaveHTML(html: string): void, + toHaveProp(propKey: string, propValue?: any): void, + toHaveRef(refName: string): void, + toHaveState(stateKey: string, stateValue?: any): void, + toHaveStyle(styleKey: string, styleValue?: any): void, + toHaveTagName(tagName: string): void, + toHaveText(text: string): void, + toIncludeText(text: string): void, + toHaveValue(value: any): void, + toMatchElement(element: React$Element): void, + toMatchSelector(selector: string): void +}; + +type JestExpectType = { + not: JestExpectType & EnzymeMatchersType, + /** + * If you have a mock function, you can use .lastCalledWith to test what + * arguments it was last called with. + */ + lastCalledWith(...args: Array): void, + /** + * toBe just checks that a value is what you expect. It uses === to check + * strict equality. + */ + toBe(value: any): void, + /** + * Use .toHaveBeenCalled to ensure that a mock function got called. + */ + toBeCalled(): void, + /** + * Use .toBeCalledWith to ensure that a mock function was called with + * specific arguments. + */ + toBeCalledWith(...args: Array): void, + /** + * Using exact equality with floating point numbers is a bad idea. Rounding + * means that intuitive things fail. + */ + toBeCloseTo(num: number, delta: any): void, + /** + * Use .toBeDefined to check that a variable is not undefined. + */ + toBeDefined(): void, + /** + * Use .toBeFalsy when you don't care what a value is, you just want to + * ensure a value is false in a boolean context. + */ + toBeFalsy(): void, + /** + * To compare floating point numbers, you can use toBeGreaterThan. + */ + toBeGreaterThan(number: number): void, + /** + * To compare floating point numbers, you can use toBeGreaterThanOrEqual. + */ + toBeGreaterThanOrEqual(number: number): void, + /** + * To compare floating point numbers, you can use toBeLessThan. + */ + toBeLessThan(number: number): void, + /** + * To compare floating point numbers, you can use toBeLessThanOrEqual. + */ + toBeLessThanOrEqual(number: number): void, + /** + * Use .toBeInstanceOf(Class) to check that an object is an instance of a + * class. + */ + toBeInstanceOf(cls: Class<*>): void, + /** + * .toBeNull() is the same as .toBe(null) but the error messages are a bit + * nicer. + */ + toBeNull(): void, + /** + * Use .toBeTruthy when you don't care what a value is, you just want to + * ensure a value is true in a boolean context. + */ + toBeTruthy(): void, + /** + * Use .toBeUndefined to check that a variable is undefined. + */ + toBeUndefined(): void, + /** + * Use .toContain when you want to check that an item is in a list. For + * testing the items in the list, this uses ===, a strict equality check. + */ + toContain(item: any): void, + /** + * Use .toContainEqual when you want to check that an item is in a list. For + * testing the items in the list, this matcher recursively checks the + * equality of all fields, rather than checking for object identity. + */ + toContainEqual(item: any): void, + /** + * Use .toEqual when you want to check that two objects have the same value. + * This matcher recursively checks the equality of all fields, rather than + * checking for object identity. + */ + toEqual(value: any): void, + /** + * Use .toHaveBeenCalled to ensure that a mock function got called. + */ + toHaveBeenCalled(): void, + /** + * Use .toHaveBeenCalledTimes to ensure that a mock function got called exact + * number of times. + */ + toHaveBeenCalledTimes(number: number): void, + /** + * Use .toHaveBeenCalledWith to ensure that a mock function was called with + * specific arguments. + */ + toHaveBeenCalledWith(...args: Array): void, + /** + * Use .toHaveBeenLastCalledWith to ensure that a mock function was last called + * with specific arguments. + */ + toHaveBeenLastCalledWith(...args: Array): void, + /** + * Check that an object has a .length property and it is set to a certain + * numeric value. + */ + toHaveLength(number: number): void, + /** + * + */ + toHaveProperty(propPath: string, value?: any): void, + /** + * Use .toMatch to check that a string matches a regular expression or string. + */ + toMatch(regexpOrString: RegExp | string): void, + /** + * Use .toMatchObject to check that a javascript object matches a subset of the properties of an object. + */ + toMatchObject(object: Object | Array): void, + /** + * This ensures that a React component matches the most recent snapshot. + */ + toMatchSnapshot(name?: string): void, + /** + * Use .toThrow to test that a function throws when it is called. + * If you want to test that a specific error gets thrown, you can provide an + * argument to toThrow. The argument can be a string for the error message, + * a class for the error, or a regex that should match the error. + * + * Alias: .toThrowError + */ + toThrow(message?: string | Error | Class | RegExp): void, + toThrowError(message?: string | Error | Class | RegExp): void, + /** + * Use .toThrowErrorMatchingSnapshot to test that a function throws a error + * matching the most recent snapshot when it is called. + */ + toThrowErrorMatchingSnapshot(): void +}; + +type JestObjectType = { + /** + * Disables automatic mocking in the module loader. + * + * After this method is called, all `require()`s will return the real + * versions of each module (rather than a mocked version). + */ + disableAutomock(): JestObjectType, + /** + * An un-hoisted version of disableAutomock + */ + autoMockOff(): JestObjectType, + /** + * Enables automatic mocking in the module loader. + */ + enableAutomock(): JestObjectType, + /** + * An un-hoisted version of enableAutomock + */ + autoMockOn(): JestObjectType, + /** + * Clears the mock.calls and mock.instances properties of all mocks. + * Equivalent to calling .mockClear() on every mocked function. + */ + clearAllMocks(): JestObjectType, + /** + * Resets the state of all mocks. Equivalent to calling .mockReset() on every + * mocked function. + */ + resetAllMocks(): JestObjectType, + /** + * Removes any pending timers from the timer system. + */ + clearAllTimers(): void, + /** + * The same as `mock` but not moved to the top of the expectation by + * babel-jest. + */ + doMock(moduleName: string, moduleFactory?: any): JestObjectType, + /** + * The same as `unmock` but not moved to the top of the expectation by + * babel-jest. + */ + dontMock(moduleName: string): JestObjectType, + /** + * Returns a new, unused mock function. Optionally takes a mock + * implementation. + */ + fn, TReturn>( + implementation?: (...args: TArguments) => TReturn + ): JestMockFn, + /** + * Determines if the given function is a mocked function. + */ + isMockFunction(fn: Function): boolean, + /** + * Given the name of a module, use the automatic mocking system to generate a + * mocked version of the module for you. + */ + genMockFromModule(moduleName: string): any, + /** + * Mocks a module with an auto-mocked version when it is being required. + * + * The second argument can be used to specify an explicit module factory that + * is being run instead of using Jest's automocking feature. + * + * The third argument can be used to create virtual mocks -- mocks of modules + * that don't exist anywhere in the system. + */ + mock( + moduleName: string, + moduleFactory?: any, + options?: Object + ): JestObjectType, + /** + * Returns the actual module instead of a mock, bypassing all checks on + * whether the module should receive a mock implementation or not. + */ + requireActual(moduleName: string): any, + /** + * Returns a mock module instead of the actual module, bypassing all checks + * on whether the module should be required normally or not. + */ + requireMock(moduleName: string): any, + /** + * Resets the module registry - the cache of all required modules. This is + * useful to isolate modules where local state might conflict between tests. + */ + resetModules(): JestObjectType, + /** + * Exhausts the micro-task queue (usually interfaced in node via + * process.nextTick). + */ + runAllTicks(): void, + /** + * Exhausts the macro-task queue (i.e., all tasks queued by setTimeout(), + * setInterval(), and setImmediate()). + */ + runAllTimers(): void, + /** + * Exhausts all tasks queued by setImmediate(). + */ + runAllImmediates(): void, + /** + * Executes only the macro task queue (i.e. all tasks queued by setTimeout() + * or setInterval() and setImmediate()). + */ + runTimersToTime(msToRun: number): void, + /** + * Executes only the macro-tasks that are currently pending (i.e., only the + * tasks that have been queued by setTimeout() or setInterval() up to this + * point) + */ + runOnlyPendingTimers(): void, + /** + * Explicitly supplies the mock object that the module system should return + * for the specified module. Note: It is recommended to use jest.mock() + * instead. + */ + setMock(moduleName: string, moduleExports: any): JestObjectType, + /** + * Indicates that the module system should never return a mocked version of + * the specified module from require() (e.g. that it should always return the + * real module). + */ + unmock(moduleName: string): JestObjectType, + /** + * Instructs Jest to use fake versions of the standard timer functions + * (setTimeout, setInterval, clearTimeout, clearInterval, nextTick, + * setImmediate and clearImmediate). + */ + useFakeTimers(): JestObjectType, + /** + * Instructs Jest to use the real versions of the standard timer functions. + */ + useRealTimers(): JestObjectType, + /** + * Creates a mock function similar to jest.fn but also tracks calls to + * object[methodName]. + */ + spyOn(object: Object, methodName: string): JestMockFn, + /** + * Set the default timeout interval for tests and before/after hooks in milliseconds. + * Note: The default timeout interval is 5 seconds if this method is not called. + */ + setTimeout(timeout: number): JestObjectType +}; + +type JestSpyType = { + calls: JestCallsType +}; + +/** Runs this function after every test inside this context */ +declare function afterEach( + fn: (done: () => void) => ?Promise, + timeout?: number +): void; +/** Runs this function before every test inside this context */ +declare function beforeEach( + fn: (done: () => void) => ?Promise, + timeout?: number +): void; +/** Runs this function after all tests have finished inside this context */ +declare function afterAll( + fn: (done: () => void) => ?Promise, + timeout?: number +): void; +/** Runs this function before any tests have started inside this context */ +declare function beforeAll( + fn: (done: () => void) => ?Promise, + timeout?: number +): void; + +/** A context for grouping tests together */ +declare var describe: { + /** + * Creates a block that groups together several related tests in one "test suite" + */ + (name: string, fn: () => void): void, + + /** + * Only run this describe block + */ + only(name: string, fn: () => void): void, + + /** + * Skip running this describe block + */ + skip(name: string, fn: () => void): void +}; + +/** An individual test unit */ +declare var it: { + /** + * An individual test unit + * + * @param {string} Name of Test + * @param {Function} Test + * @param {number} Timeout for the test, in milliseconds. + */ + ( + name: string, + fn?: (done: () => void) => ?Promise, + timeout?: number + ): void, + /** + * Only run this test + * + * @param {string} Name of Test + * @param {Function} Test + * @param {number} Timeout for the test, in milliseconds. + */ + only( + name: string, + fn?: (done: () => void) => ?Promise, + timeout?: number + ): void, + /** + * Skip running this test + * + * @param {string} Name of Test + * @param {Function} Test + * @param {number} Timeout for the test, in milliseconds. + */ + skip( + name: string, + fn?: (done: () => void) => ?Promise, + timeout?: number + ): void, + /** + * Run the test concurrently + * + * @param {string} Name of Test + * @param {Function} Test + * @param {number} Timeout for the test, in milliseconds. + */ + concurrent( + name: string, + fn?: (done: () => void) => ?Promise, + timeout?: number + ): void +}; +declare function fit( + name: string, + fn: (done: () => void) => ?Promise, + timeout?: number +): void; +/** An individual test unit */ +declare var test: typeof it; +/** A disabled group of tests */ +declare var xdescribe: typeof describe; +/** A focused group of tests */ +declare var fdescribe: typeof describe; +/** A disabled individual test */ +declare var xit: typeof it; +/** A disabled individual test */ +declare var xtest: typeof it; + +type JestPrettyFormatColors = { + comment: { close: string, open: string }, + content: { close: string, open: string }, + prop: { close: string, open: string }, + tag: { close: string, open: string }, + value: { close: string, open: string }, +}; + +type JestPrettyFormatIndent = string => string; +type JestPrettyFormatRefs = Array; +type JestPrettyFormatPrint = any => string; +type JestPrettyFormatStringOrNull = string | null; + +type JestPrettyFormatOptions = {| + callToJSON: boolean, + edgeSpacing: string, + escapeRegex: boolean, + highlight: boolean, + indent: number, + maxDepth: number, + min: boolean, + plugins: JestPrettyFormatPlugins, + printFunctionName: boolean, + spacing: string, + theme: {| + comment: string, + content: string, + prop: string, + tag: string, + value: string, + |}, +|}; + +type JestPrettyFormatPlugin = { + print: ( + val: any, + serialize: JestPrettyFormatPrint, + indent: JestPrettyFormatIndent, + opts: JestPrettyFormatOptions, + colors: JestPrettyFormatColors, + ) => string, + test: any => boolean, +}; + +type JestPrettyFormatPlugins = Array; + +/** The expect function is used every time you want to test a value */ +declare var expect: { + /** The object that you want to make assertions against */ + (value: any): JestExpectType & JestPromiseType & EnzymeMatchersType, + /** Add additional Jasmine matchers to Jest's roster */ + extend(matchers: { [name: string]: JestMatcher }): void, + /** Add a module that formats application-specific data structures. */ + addSnapshotSerializer(pluginModule: JestPrettyFormatPlugin): void, + assertions(expectedAssertions: number): void, + hasAssertions(): void, + any(value: mixed): JestAsymmetricEqualityType, + anything(): void, + arrayContaining(value: Array): void, + objectContaining(value: Object): void, + /** Matches any received string that contains the exact expected string. */ + stringContaining(value: string): void, + stringMatching(value: string | RegExp): void +}; + +// TODO handle return type +// http://jasmine.github.io/2.4/introduction.html#section-Spies +declare function spyOn(value: mixed, method: string): Object; + +/** Holds all functions related to manipulating test runner */ +declare var jest: JestObjectType; + +/** + * The global Jasmine object, this is generally not exposed as the public API, + * using features inside here could break in later versions of Jest. + */ +declare var jasmine: { + DEFAULT_TIMEOUT_INTERVAL: number, + any(value: mixed): JestAsymmetricEqualityType, + anything(): void, + arrayContaining(value: Array): void, + clock(): JestClockType, + createSpy(name: string): JestSpyType, + createSpyObj( + baseName: string, + methodNames: Array + ): { [methodName: string]: JestSpyType }, + objectContaining(value: Object): void, + stringMatching(value: string): void +}; From 9d7b0a1ddac9ccf95a9dd505d7cb1b954ff351d4 Mon Sep 17 00:00:00 2001 From: "Fabio M. Costa" Date: Mon, 9 Jul 2018 20:45:42 -0700 Subject: [PATCH 3/5] Add basic focusable utility components. --- .../modules/navigation/FocusPathContext.js | 3 ++ .../react-ape/modules/navigation/withFocus.js | 31 +++++++++++++++++++ .../modules/navigation/withNavigation.js | 24 ++++++++++++++ packages/react-ape/modules/utils.js | 11 +++++++ 4 files changed, 69 insertions(+) create mode 100644 packages/react-ape/modules/navigation/FocusPathContext.js create mode 100644 packages/react-ape/modules/navigation/withFocus.js create mode 100644 packages/react-ape/modules/navigation/withNavigation.js create mode 100644 packages/react-ape/modules/utils.js diff --git a/packages/react-ape/modules/navigation/FocusPathContext.js b/packages/react-ape/modules/navigation/FocusPathContext.js new file mode 100644 index 0000000..0534406 --- /dev/null +++ b/packages/react-ape/modules/navigation/FocusPathContext.js @@ -0,0 +1,3 @@ +import React from 'react'; + +export const FocusPathContext = React.createContext(); diff --git a/packages/react-ape/modules/navigation/withFocus.js b/packages/react-ape/modules/navigation/withFocus.js new file mode 100644 index 0000000..663399f --- /dev/null +++ b/packages/react-ape/modules/navigation/withFocus.js @@ -0,0 +1,31 @@ +import React from 'react'; +import { createHOC } from '../utils'; +import { FocusPathContext } from './FocusPathContext'; + +// focusKey: string +// focused: boolean +function withFocus(WrappedComponent) { + return createHOC( + WrappedComponent, + class extends React.Component { + render() { + const { focusKey } = this.props; + // TODO: I need to listen to a global and observable focusPath that will define + // if this component should be focused or not (the value of focused) + return ( + + {focusPath => ( + + + + )} + + ); + } + } + ); +} diff --git a/packages/react-ape/modules/navigation/withNavigation.js b/packages/react-ape/modules/navigation/withNavigation.js new file mode 100644 index 0000000..41d2691 --- /dev/null +++ b/packages/react-ape/modules/navigation/withNavigation.js @@ -0,0 +1,24 @@ +import React from 'react'; +import { createHOC } from '../utils'; +import { FocusPathContext } from './FocusPathContext'; + +export function withNavigation(WrappedComponent) { + return createHOC( + WrappedComponent, + class extends React.Component { + constructor() { + super(...arguments); + this.state = { + focusedPath: null + }; + } + render() { + return ( + + + + ); + } + } + ); +} diff --git a/packages/react-ape/modules/utils.js b/packages/react-ape/modules/utils.js new file mode 100644 index 0000000..d24aa89 --- /dev/null +++ b/packages/react-ape/modules/utils.js @@ -0,0 +1,11 @@ +function getDisplayName(Comp) { + return Comp.displayName || Comp.name || 'Component'; +} + +export function createHOC(WrappedComponent, HOCDeclaration) { + HOCDeclaration.displayName = `withNavigation(${getDisplayName( + WrappedComponent + )})`; + HOCDeclaration.WrappedComponent = WrappedComponent; + return HOCDeclaration; +} From 5c5db916164a51c5b527c613665628d436c83552 Mon Sep 17 00:00:00 2001 From: "Fabio M. Costa" Date: Mon, 9 Jul 2018 21:38:37 -0700 Subject: [PATCH 4/5] continuing reorg --- .../react-ape/modules/navigation/withFocus.js | 46 +++++++++---------- .../modules/navigation/withNavigation.js | 20 ++++---- packages/react-ape/modules/utils.js | 10 +--- 3 files changed, 36 insertions(+), 40 deletions(-) diff --git a/packages/react-ape/modules/navigation/withFocus.js b/packages/react-ape/modules/navigation/withFocus.js index 663399f..f4e1e20 100644 --- a/packages/react-ape/modules/navigation/withFocus.js +++ b/packages/react-ape/modules/navigation/withFocus.js @@ -1,31 +1,31 @@ import React from 'react'; -import { createHOC } from '../utils'; +import { getDisplayName } from '../utils'; import { FocusPathContext } from './FocusPathContext'; // focusKey: string // focused: boolean function withFocus(WrappedComponent) { - return createHOC( - WrappedComponent, - class extends React.Component { - render() { - const { focusKey } = this.props; - // TODO: I need to listen to a global and observable focusPath that will define - // if this component should be focused or not (the value of focused) - return ( - - {focusPath => ( - - - - )} - - ); - } + return class extends React.Component { + static WrappedComponent = WrappedComponent; + static displayName = `withFocus(${getDisplayName(WrappedComponent)})`; + + render() { + const { focusKey } = this.props; + // TODO: I need to listen to a global and observable focusPath that will define + // if this component should be focused or not (the value of focused) + return ( + + {focusPath => ( + + + + )} + + ); } - ); + }; } diff --git a/packages/react-ape/modules/navigation/withNavigation.js b/packages/react-ape/modules/navigation/withNavigation.js index 41d2691..bc93e4e 100644 --- a/packages/react-ape/modules/navigation/withNavigation.js +++ b/packages/react-ape/modules/navigation/withNavigation.js @@ -1,17 +1,21 @@ import React from 'react'; -import { createHOC } from '../utils'; +import { getDisplayName } from '../utils'; import { FocusPathContext } from './FocusPathContext'; +/** + * + * + */ export function withNavigation(WrappedComponent) { - return createHOC( + return class extends React.Component { + + static WrappedComponent = WrappedComponent; + static displayName = `withNavigation(${getDisplayName( + WrappedComponent + )})`; + WrappedComponent, class extends React.Component { - constructor() { - super(...arguments); - this.state = { - focusedPath: null - }; - } render() { return ( diff --git a/packages/react-ape/modules/utils.js b/packages/react-ape/modules/utils.js index d24aa89..4a8b0f5 100644 --- a/packages/react-ape/modules/utils.js +++ b/packages/react-ape/modules/utils.js @@ -1,11 +1,3 @@ -function getDisplayName(Comp) { +export function getDisplayName(Comp) { return Comp.displayName || Comp.name || 'Component'; } - -export function createHOC(WrappedComponent, HOCDeclaration) { - HOCDeclaration.displayName = `withNavigation(${getDisplayName( - WrappedComponent - )})`; - HOCDeclaration.WrappedComponent = WrappedComponent; - return HOCDeclaration; -} From 6374d4bf64b25dfdc47150ef4608fd70db2bed48 Mon Sep 17 00:00:00 2001 From: "Fabio M. Costa" Date: Tue, 10 Jul 2018 22:48:51 -0700 Subject: [PATCH 5/5] Adding withFocus and withNavigation on the example app and making sure the base behavior is working --- .babelrc | 2 +- package.json | 1 + packages/example-movie-list/.babelrc | 5 - packages/example-movie-list/package.json | 1 + packages/example-movie-list/src/App.js | 99 ++++++++++++------- .../webpack.config.babel.js | 15 ++- packages/react-ape/.flowconfig | 20 ---- .../react-ape/modules/navigation/withFocus.js | 62 ++++++++---- .../modules/navigation/withNavigation.js | 54 ++++++---- packages/react-ape/modules/utils.js | 17 +++- packages/react-ape/package.json | 8 +- packages/react-ape/reactApeEntry.js | 16 +-- .../renderer/reactApeComponentTree.js | 6 +- .../react-ape/renderer/reactApeRenderer.js | 6 -- 14 files changed, 177 insertions(+), 135 deletions(-) delete mode 100644 packages/example-movie-list/.babelrc delete mode 100644 packages/react-ape/.flowconfig diff --git a/.babelrc b/.babelrc index a7d8829..e4e5340 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,3 @@ { - "presets": [ "env", "react", "stage-2" ], + "presets": [ "env", "react", "stage-2", "flow" ], } diff --git a/package.json b/package.json index 2547119..39f7fcb 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "devDependencies": { "babel-jest": "21.0.2", "babel-plugin-external-helpers": "^6.22.0", + "babel-preset-flow": "^6.23.0", "babel-preset-stage-2": "^6.24.1", "chalk": "^2.4.1", "flow-bin": "^0.76.0", diff --git a/packages/example-movie-list/.babelrc b/packages/example-movie-list/.babelrc deleted file mode 100644 index 63c3455..0000000 --- a/packages/example-movie-list/.babelrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "presets":[ - "env", "react" - ] -} diff --git a/packages/example-movie-list/package.json b/packages/example-movie-list/package.json index 4ad0a18..d8f62f0 100644 --- a/packages/example-movie-list/package.json +++ b/packages/example-movie-list/package.json @@ -15,6 +15,7 @@ "babel-loader": "^7.1.2", "babel-polyfill": "^6.26.0", "babel-preset-env": "^1.6.1", + "babel-preset-flow": "^6.23.0", "babel-preset-react": "^6.24.1", "uglifyjs-webpack-plugin": "^1.0.1", "webpack": "^3.8.1", diff --git a/packages/example-movie-list/src/App.js b/packages/example-movie-list/src/App.js index 5e85c43..0dc5800 100644 --- a/packages/example-movie-list/src/App.js +++ b/packages/example-movie-list/src/App.js @@ -1,5 +1,14 @@ import React from 'react'; -import {render, Text, ListView, View, Image, StyleSheet} from 'react-ape'; +import { + render, + Text, + ListView, + View, + Image, + StyleSheet, + withFocus, + withNavigation +} from 'react-ape'; const styles = StyleSheet.create({ heading: { @@ -8,7 +17,7 @@ const styles = StyleSheet.create({ color: 'white', fontFamily: 'Arial', fontWeight: 'bold', - fontSize: 29, + fontSize: 29 }, time: { top: 62, @@ -16,11 +25,11 @@ const styles = StyleSheet.create({ color: 'red', fontFamily: 'Arial', fontWeight: 'bold', - fontSize: 25, + fontSize: 25 }, logo: { top: 10, - left: 30, + left: 30 }, infoAboutRenderer: { top: 590, @@ -28,33 +37,59 @@ const styles = StyleSheet.create({ fontFamily: 'Arial', fontWeight: 'bold', color: 'lightblue', - fontSize: 23, + fontSize: 23 }, list: { top: 100, left: 0, backgroundColor: '#303030', width: 2000, - height: 400, - }, + height: 400 + } }); +class Item extends React.Component { + render() { + const { idx, data } = this.props; + return ( + { + console.log(data); + }} + > + + + {data.name} + + + ); + } +} + +const FocusableItem = withFocus(Item); + class App extends React.Component { constructor() { - super(); + super(...arguments); this.posters = [ - {name: 'Narcos', src: 'posters/narcos.jpg'}, - {name: 'Daredevil', src: 'posters/daredevil.jpg'}, - {name: 'Stranger Things', src: 'posters/stranger-things.jpg'}, - {name: 'Narcos', src: 'posters/narcos.jpg'}, - {name: 'Daredevil', src: 'posters/daredevil.jpg'}, - {name: 'Stranger Things', src: 'posters/stranger-things.jpg'}, - {name: 'Narcos', src: 'posters/narcos.jpg'}, - {name: 'Daredevil', src: 'posters/daredevil.jpg'}, - {name: 'Stranger Things', src: 'posters/stranger-things.jpg'}, + { name: 'Narcos', src: 'posters/narcos.jpg' }, + { name: 'Daredevil', src: 'posters/daredevil.jpg' }, + { name: 'Stranger Things', src: 'posters/stranger-things.jpg' }, + { name: 'Narcos', src: 'posters/narcos.jpg' }, + { name: 'Daredevil', src: 'posters/daredevil.jpg' }, + { name: 'Stranger Things', src: 'posters/stranger-things.jpg' }, + { name: 'Narcos', src: 'posters/narcos.jpg' }, + { name: 'Daredevil', src: 'posters/daredevil.jpg' }, + { name: 'Stranger Things', src: 'posters/stranger-things.jpg' } ]; this.state = { - time: new Date().toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, '$1'), + time: new Date().toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, '$1') }; } @@ -63,29 +98,19 @@ class App extends React.Component { const time = new Date() .toTimeString() .replace(/.*(\d{2}:\d{2}:\d{2}).*/, '$1'); - this.setState({time}); + this.setState({ time }); }, 100); } renderPostersList() { const renderRow = (data, idx) => ( - { - console.log(data); - }}> - - - {data.name} - - + ); - return ( , document.getElementById('root')); +const NavigationApp = withNavigation(App); + +render(, document.getElementById('root')); diff --git a/packages/example-movie-list/webpack.config.babel.js b/packages/example-movie-list/webpack.config.babel.js index d9e00a5..85aa4eb 100644 --- a/packages/example-movie-list/webpack.config.babel.js +++ b/packages/example-movie-list/webpack.config.babel.js @@ -22,10 +22,9 @@ const config = { module: { rules: [ { - test: /\.(js|jsx)$/, + test: /\.jsx?$/, exclude: /node_modules/, - use: ['babel-loader'], - include: sourcePath, + use: { loader: 'babel-loader' } }, ], }, @@ -43,15 +42,13 @@ if (process.env.NODE_ENV === 'production') { warnings: false, }, }, - }) - ); - config.plugins.push( + }), new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify('production'), - }) + }), + new webpack.optimize.ModuleConcatenationPlugin(), + new webpack.HashedModuleIdsPlugin(), ); - config.plugins.push(new webpack.optimize.ModuleConcatenationPlugin()); - config.plugins.push(new webpack.HashedModuleIdsPlugin()); } module.exports = config; diff --git a/packages/react-ape/.flowconfig b/packages/react-ape/.flowconfig deleted file mode 100644 index 61d5ba0..0000000 --- a/packages/react-ape/.flowconfig +++ /dev/null @@ -1,20 +0,0 @@ -[ignore] - -[include] - -[libs] - -[lints] -all=warn - -[options] -module.use_strict=true -suppress_type=$FlowIssue -suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe - -[strict] -nonstrict-import -unclear-type -unsafe-getters-setters -untyped-import -untyped-type-import diff --git a/packages/react-ape/modules/navigation/withFocus.js b/packages/react-ape/modules/navigation/withFocus.js index f4e1e20..ecb3fd5 100644 --- a/packages/react-ape/modules/navigation/withFocus.js +++ b/packages/react-ape/modules/navigation/withFocus.js @@ -1,29 +1,53 @@ -import React from 'react'; -import { getDisplayName } from '../utils'; +/** + * @flow + */ + +import * as React from 'react'; +import { getComponentDisplayName } from '../utils'; import { FocusPathContext } from './FocusPathContext'; -// focusKey: string -// focused: boolean -function withFocus(WrappedComponent) { - return class extends React.Component { +type RequiredProps = { + focusKey: string +}; + +// See why we do `| void` +// https://flow.org/en/docs/react/hoc/#toc-injecting-props-with-a-higher-order-component +type InjectedProps = { + focused: boolean | void +}; + +/** + * Allows the WrappedComponent to be focusable and provides the `focused` + * property to it. + * The resulting component should provide a `focusKey` property. + */ +export function withFocus( + WrappedComponent: React.ComponentType +): React.ComponentType<$Diff> { + return class extends React.Component { static WrappedComponent = WrappedComponent; - static displayName = `withFocus(${getDisplayName(WrappedComponent)})`; + static displayName = `withFocus(${getComponentDisplayName( + WrappedComponent + )})`; - render() { + renderWithFocusPath = focusPath => { + // TODO: I need to listen to a global and observable focusPath that will + // define if this component should be focused or not (the value of focused) const { focusKey } = this.props; - // TODO: I need to listen to a global and observable focusPath that will define - // if this component should be focused or not (the value of focused) + return ( + + + + ); + }; + + render() { return ( - {focusPath => ( - - - - )} + {this.renderWithFocusPath} ); } diff --git a/packages/react-ape/modules/navigation/withNavigation.js b/packages/react-ape/modules/navigation/withNavigation.js index bc93e4e..277cdb1 100644 --- a/packages/react-ape/modules/navigation/withNavigation.js +++ b/packages/react-ape/modules/navigation/withNavigation.js @@ -1,28 +1,46 @@ -import React from 'react'; -import { getDisplayName } from '../utils'; +/** + * @flow + */ + +import * as React from 'react'; +import { getComponentDisplayName, unsafeCreateUniqueId } from '../utils'; import { FocusPathContext } from './FocusPathContext'; +type RequiredProps = {}; + +// See why we do `| void` +// https://flow.org/en/docs/react/hoc/#toc-injecting-props-with-a-higher-order-component +type InjectedProps = { + focusPath: string | void +}; + /** - * - * + * Adds `focusPath` to the context so we can create the `focusPath` + * from the focusable elements inside the WrappedComponent. + * Should be used to wrap the root component of the application. */ -export function withNavigation(WrappedComponent) { - return class extends React.Component { - +export function withNavigation( + WrappedComponent: React.ComponentType +): React.ComponentType<$Diff> { + return class extends React.Component { static WrappedComponent = WrappedComponent; - static displayName = `withNavigation(${getDisplayName( + static displayName = `withNavigation(${getComponentDisplayName( WrappedComponent )})`; - WrappedComponent, - class extends React.Component { - render() { - return ( - - - - ); - } + rootFocusPath: string; + + constructor() { + super(...arguments); + this.rootFocusPath = `root-${unsafeCreateUniqueId()}`; + } + + render() { + return ( + + + + ); } - ); + }; } diff --git a/packages/react-ape/modules/utils.js b/packages/react-ape/modules/utils.js index 4a8b0f5..2720f1e 100644 --- a/packages/react-ape/modules/utils.js +++ b/packages/react-ape/modules/utils.js @@ -1,3 +1,18 @@ -export function getDisplayName(Comp) { +/** + * @flow + */ + +import type { ComponentType } from 'react'; + +export function getComponentDisplayName(Comp: ComponentType): string { return Comp.displayName || Comp.name || 'Component'; } + +/** + * Returns a relatively "guaranteed" unique id. + * It's still not 100% guaranteed, that's why we added the "unsafe" prefix on + * this function. + */ +export function unsafeCreateUniqueId(): string { + return ((Math.random() * 10e18) + Date.now()).toString(36); +} diff --git a/packages/react-ape/package.json b/packages/react-ape/package.json index 37b8111..9e31b28 100644 --- a/packages/react-ape/package.json +++ b/packages/react-ape/package.json @@ -2,7 +2,7 @@ "name": "react-ape", "version": "0.0.6", "description": "React Renderer to build interfaces using canvas/WebGL", - "main": "index.js", + "main": "reactApeEntry.js", "scripts": { "flow": "flow" }, @@ -31,9 +31,5 @@ "bugs": { "url": "https://github.com/raphamorim/react-ape/issues" }, - "homepage": "https://github.com/raphamorim/react-ape#readme", - "devDependencies": { - "flow-bin": "^0.76.0", - "flow-typed": "^2.5.1" - } + "homepage": "https://github.com/raphamorim/react-ape#readme" } diff --git a/packages/react-ape/reactApeEntry.js b/packages/react-ape/reactApeEntry.js index a8205d5..be9b150 100644 --- a/packages/react-ape/reactApeEntry.js +++ b/packages/react-ape/reactApeEntry.js @@ -6,19 +6,13 @@ * */ -import ReactApeRenderer from './renderer/reactApeRenderer'; -import StyleSheetModule from './modules/StyleSheet'; - -import ListViewComponent from './renderer/components/ListView'; -export const ListView = ListViewComponent; +export { View, Image, Text } from './renderer/constants'; +export { default as ListView } from './renderer/components/ListView'; +export { default as StyleSheet } from './modules/StyleSheet'; +export { withFocus, withNavigation } from './modules/navigation'; +import ReactApeRenderer from './renderer/reactApeRenderer'; export const render = ReactApeRenderer.render; // export const unmountComponentAtNode = ReactTVRenderer.unmountComponentAtNode; -export const Image = 'Image'; -export const View = 'View'; -export const Text = 'Text'; - -export const StyleSheet = StyleSheetModule; - export default ReactApeRenderer; diff --git a/packages/react-ape/renderer/reactApeComponentTree.js b/packages/react-ape/renderer/reactApeComponentTree.js index ccd2eac..f540df6 100644 --- a/packages/react-ape/renderer/reactApeComponentTree.js +++ b/packages/react-ape/renderer/reactApeComponentTree.js @@ -6,9 +6,9 @@ * */ -const randomKey = Math.random() - .toString(36) - .slice(2); +import { unsafeCreateUniqueId } from '../modules/utils'; + +const randomKey = unsafeCreateUniqueId(); const internalInstanceKey = '__reactInternalInstance$' + randomKey; const internalEventHandlersKey = '__reactEventHandlers$' + randomKey; diff --git a/packages/react-ape/renderer/reactApeRenderer.js b/packages/react-ape/renderer/reactApeRenderer.js index b3b2911..fb19535 100644 --- a/packages/react-ape/renderer/reactApeRenderer.js +++ b/packages/react-ape/renderer/reactApeRenderer.js @@ -10,12 +10,6 @@ import reconciler from 'react-reconciler'; import reactApeComponent from './reactApeComponent'; import { precacheFiberNode, updateFiberProps } from './reactApeComponentTree'; -export type CanvasComponentContext = { - _renderQueueForUpdate: Array, - type: 'canvas', - ctx: CanvasRenderingContext2D -}; - function scaleDPI(canvas, context, customWidth, customHeight) { const devicePixelRatio = window.devicePixelRatio || 1;