diff --git a/package-lock.json b/package-lock.json index 38e8e71..76303ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "uilicious-cli", - "version": "5.1.2", + "version": "5.1.4", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -24,6 +24,189 @@ "color-convert": "1.9.3" } }, + "archiver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-5.3.0.tgz", + "integrity": "sha512-iUw+oDwK0fgNpvveEsdQ0Ase6IIKztBJU2U0E9MzszMfmVVUyv1QJhS2ITW9ZCqx8dktAxVAjWWkKehuZE8OPg==", + "requires": { + "archiver-utils": "2.1.0", + "async": "3.2.3", + "buffer-crc32": "0.2.13", + "readable-stream": "3.6.0", + "readdir-glob": "1.1.1", + "tar-stream": "2.2.0", + "zip-stream": "4.1.0" + } + }, + "archiver-promise": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archiver-promise/-/archiver-promise-1.0.0.tgz", + "integrity": "sha1-p8TlLmB/2XbFSjAlBFQXM2g09lI=", + "requires": { + "archiver": "1.3.0" + }, + "dependencies": { + "archiver": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/archiver/-/archiver-1.3.0.tgz", + "integrity": "sha1-TyGU1tj5nfP1MeaIHxTxXVX6ryI=", + "requires": { + "archiver-utils": "1.3.0", + "async": "2.6.3", + "buffer-crc32": "0.2.13", + "glob": "7.1.3", + "lodash": "4.17.21", + "readable-stream": "2.3.7", + "tar-stream": "1.6.2", + "walkdir": "0.0.11", + "zip-stream": "1.2.0" + } + }, + "archiver-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz", + "integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=", + "requires": { + "glob": "7.1.3", + "graceful-fs": "4.2.8", + "lazystream": "1.0.1", + "lodash": "4.17.21", + "normalize-path": "2.1.1", + "readable-stream": "2.3.7" + } + }, + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "requires": { + "lodash": "4.17.21" + } + }, + "bl": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz", + "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==", + "requires": { + "readable-stream": "2.3.7", + "safe-buffer": "5.1.2" + } + }, + "compress-commons": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.2.tgz", + "integrity": "sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8=", + "requires": { + "buffer-crc32": "0.2.13", + "crc32-stream": "2.0.0", + "normalize-path": "2.1.1", + "readable-stream": "2.3.7" + } + }, + "crc32-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz", + "integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=", + "requires": { + "crc": "3.8.0", + "readable-stream": "2.3.7" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "requires": { + "remove-trailing-separator": "1.1.0" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "1.0.3", + "inherits": "2.0.4", + "isarray": "1.0.0", + "process-nextick-args": "2.0.1", + "safe-buffer": "5.1.2", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + }, + "tar-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", + "requires": { + "bl": "1.2.3", + "buffer-alloc": "1.2.0", + "end-of-stream": "1.4.4", + "fs-constants": "1.0.0", + "readable-stream": "2.3.7", + "to-buffer": "1.1.1", + "xtend": "4.0.2" + } + }, + "zip-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz", + "integrity": "sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=", + "requires": { + "archiver-utils": "1.3.0", + "compress-commons": "1.2.2", + "lodash": "4.17.21", + "readable-stream": "2.3.7" + } + } + } + }, + "archiver-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz", + "integrity": "sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==", + "requires": { + "glob": "7.2.0", + "graceful-fs": "4.2.8", + "lazystream": "1.0.1", + "lodash.defaults": "4.2.0", + "lodash.difference": "4.5.0", + "lodash.flatten": "4.4.0", + "lodash.isplainobject": "4.0.6", + "lodash.union": "4.6.0", + "normalize-path": "3.0.0", + "readable-stream": "2.3.7" + }, + "dependencies": { + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.4", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "1.0.3", + "inherits": "2.0.4", + "isarray": "1.0.0", + "process-nextick-args": "2.0.1", + "safe-buffer": "5.1.2", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + } + } + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -39,6 +222,11 @@ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, + "async": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", + "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==" + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -55,14 +243,27 @@ "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "requires": { + "buffer": "5.7.1", + "inherits": "2.0.4", + "readable-stream": "3.6.0" + } }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "1.0.2", "concat-map": "0.0.1" @@ -74,6 +275,39 @@ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", "dev": true }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "1.5.1", + "ieee754": "1.2.1" + } + }, + "buffer-alloc": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", + "requires": { + "buffer-alloc-unsafe": "1.1.0", + "buffer-fill": "1.0.0" + } + }, + "buffer-alloc-unsafe": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==" + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + }, + "buffer-fill": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=" + }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -200,11 +434,52 @@ "delayed-stream": "1.0.0" } }, + "compress-commons": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz", + "integrity": "sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ==", + "requires": { + "buffer-crc32": "0.2.13", + "crc32-stream": "4.0.2", + "normalize-path": "3.0.0", + "readable-stream": "3.6.0" + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, + "crc": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", + "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", + "requires": { + "buffer": "5.7.1" + } + }, + "crc-32": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.1.tgz", + "integrity": "sha512-Dn/xm/1vFFgs3nfrpEVScHoIslO9NZRITWGz/1E/St6u4xw99vfZzVkW0OSnzx2h9egej9xwMCEut6sqwokM/w==", + "requires": { + "exit-on-epipe": "1.0.1", + "printj": "1.3.1" + } + }, + "crc32-stream": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz", + "integrity": "sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w==", + "requires": { + "crc-32": "1.2.1", + "readable-stream": "3.6.0" + } }, "debug": { "version": "3.2.6", @@ -256,6 +531,14 @@ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "1.4.0" + } + }, "es-abstract": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", @@ -320,6 +603,11 @@ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, + "exit-on-epipe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", + "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==" + }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", @@ -353,6 +641,11 @@ "mime-types": "2.1.32" } }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, "fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -366,8 +659,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "function-bind": { "version": "1.1.1", @@ -412,7 +704,6 @@ "version": "7.1.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, "requires": { "fs.realpath": "1.0.0", "inflight": "1.0.6", @@ -479,11 +770,15 @@ "resolved": "https://registry.npmjs.org/hjson/-/hjson-3.2.2.tgz", "integrity": "sha512-MkUeB0cTIlppeSsndgESkfFD21T2nXPRaBStLtf3cAYA2bVEFdXlodZB0TukwZiobPD1Ksax5DK4RTZeaXCI3Q==" }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "requires": { "once": "1.4.0", "wrappy": "1.0.2" @@ -492,8 +787,7 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "internal-slot": { "version": "1.0.3", @@ -615,6 +909,11 @@ "call-bind": "1.0.2" } }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -644,6 +943,30 @@ "graceful-fs": "4.2.8" } }, + "lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "requires": { + "readable-stream": "2.3.7" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "1.0.3", + "inherits": "2.0.4", + "isarray": "1.0.0", + "process-nextick-args": "2.0.1", + "safe-buffer": "5.1.2", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + } + } + }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", @@ -657,8 +980,32 @@ "lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "lodash.defaults": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", + "integrity": "sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw=" + }, + "lodash.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=" + }, + "lodash.flatten": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", + "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + }, + "lodash.union": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz", + "integrity": "sha1-SLtQiECfFvGCFmZkHETdGqrjzYg=" }, "log-symbols": { "version": "2.2.0", @@ -686,7 +1033,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, "requires": { "brace-expansion": "1.1.11" } @@ -924,7 +1270,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1.0.2" } @@ -962,8 +1307,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "pathval": { "version": "1.1.1", @@ -971,11 +1315,44 @@ "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true }, + "printj": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/printj/-/printj-1.3.1.tgz", + "integrity": "sha512-GA3TdL8szPK4AQ2YnOe/b+Y1jUFwmmGMMK/qbY7VcE3Z7FU8JstbKiKRzO6CIiAKPhTO8m01NoQ0V5f3jc4OGg==" + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" + }, "promise-queue": { "version": "2.2.5", "resolved": "https://registry.npmjs.org/promise-queue/-/promise-queue-2.2.5.tgz", "integrity": "sha1-L29ffA9tCBCelnZZx5uIqe1ek7Q=" }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "requires": { + "inherits": "2.0.4", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" + } + }, + "readdir-glob": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.1.tgz", + "integrity": "sha512-91/k1EzZwDx6HbERR+zucygRFfiPl2zkIYZtv3Jjr6Mn7SkKcVct8aVO+sSRiGMc6fLf72du3d92/uY63YPdEA==", + "requires": { + "minimatch": "3.0.4" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -988,6 +1365,11 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -1052,6 +1434,14 @@ "define-properties": "1.1.3" } }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "5.1.2" + } + }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", @@ -1080,6 +1470,23 @@ "resolved": "https://registry.npmjs.org/sywac/-/sywac-1.3.0.tgz", "integrity": "sha512-LDt2stNTp4bVPMgd70Jj9PWrSa4batl+bv+Ea5NLNGT7ufc4oQPtRfQ73wbddNV6RilaPqnEt6y1Wkm5FVTNEg==" }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "requires": { + "bl": "4.1.0", + "end-of-stream": "1.4.4", + "fs-constants": "1.0.0", + "inherits": "2.0.4", + "readable-stream": "3.6.0" + } + }, + "to-buffer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", + "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==" + }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", @@ -1103,12 +1510,22 @@ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" + }, "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", "dev": true }, + "walkdir": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.0.11.tgz", + "integrity": "sha1-oW0CXrkxvQO1LzCMrtD0D86+lTI=" + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -1188,8 +1605,12 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "y18n": { "version": "4.0.3", @@ -1263,6 +1684,16 @@ "lodash": "4.17.21", "yargs": "13.3.2" } + }, + "zip-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz", + "integrity": "sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A==", + "requires": { + "archiver-utils": "2.1.0", + "compress-commons": "4.1.1", + "readable-stream": "3.6.0" + } } } } diff --git a/package.json b/package.json index f3ace03..a91f8e0 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "uilicious-cli", - "version": "5.1.4", + "version": "5.1.6", "description": "Uilicious CLI toolchain", "main": "uilicious-cli.js", "keywords": [ @@ -39,6 +39,8 @@ "uuid": "=3.3.2" }, "dependencies": { + "archiver": "^5.3.0", + "archiver-promise": "^1.0.0", "axios": "=0.21.4", "buffer-from": "=1.1.1", "chalk": "=2.4.2", diff --git a/src/api/ApiServerConnector.js b/src/api/ApiServerConnector.js index a88ffb7..06558df 100755 --- a/src/api/ApiServerConnector.js +++ b/src/api/ApiServerConnector.js @@ -130,16 +130,20 @@ function transformRequestData(data) { if (typeof data === "undefined" || null) { data = new FormData() } - // coerce into form data - let formData = new FormData() + + // Prepare the form data (max size 100MB) + let formData = new FormData( { maxDataSize: (100 * 1000 * 1000) }) if (data instanceof FormData) { + // coerce into form data formData = data } else if (typeof data === "object") { Object.keys(data).forEach((prop) => { let value = data[prop] try { - if(value != null && isStream(value)){ + if(value == null || value == undefined) { + // does nothing + } else if(isStream(value)){ formData.append(prop, value) } else if(value instanceof Buffer) { formData.append(prop, value) @@ -150,10 +154,10 @@ function transformRequestData(data) { } else if( typeof value === "string" ) { formData.append(prop, value) } else { - LoggerWithLevels.warn("WARNING - Skipping unknown data type in form data property name: "+ prop+ " type "+ typeof value) + OutputHandler.debug("WARNING - Skipping unknown data type in form data property name: "+ prop+ " type "+ typeof value) } } catch(e) { - LoggerWithLevels.warn("WARNING - Skipping parameter due to conversion error: "+ prop+ ", type="+ typeof value+", err="+e) + OutputHandler.debug("WARNING - Skipping parameter due to conversion error: "+ prop+ ", type="+ typeof value+", err="+e) } }) } diff --git a/src/api/SpaceAndProjectApi.js b/src/api/SpaceAndProjectApi.js index 9855122..986f2df 100755 --- a/src/api/SpaceAndProjectApi.js +++ b/src/api/SpaceAndProjectApi.js @@ -10,6 +10,7 @@ // //--------------------------------------------------------------------------------------- +const fs = require("fs") const api = require("./ApiServerConnector"); const retryForResult = require("./retryForResult"); const OutputHandler = require("../OutputHandler") @@ -280,8 +281,9 @@ class SpaceAndProjectApi { * * @param {String} projectID to run test from * @param {Object} testParams containing the parameters listed above + * @param {String} srcCodeZip_filePath to append as byte stream, if provided */ - async startProjectTest(projectID, scriptPath, testParams = {}) { + async startProjectTest(projectID, scriptPath, testParams = {}, srcCodeZip_filePath = null) { // Normalize the args let browser = testParams.browser || "chrome"; let width = testParams.width || 1280; @@ -312,7 +314,10 @@ class SpaceAndProjectApi { // Lets start the test ! return await retryForResult( () => { - return api.POST(`/project/testrun/start`, reqObj) + if( srcCodeZip_filePath ) { + return api.POST(`/project/testrun/start`, Object.assign({ "srcCodeZip" : fs.createReadStream(srcCodeZip_filePath) }, reqObj), true ); + } + return api.POST(`/project/testrun/start`, reqObj); } ); } diff --git a/src/cli-command/project/run.js b/src/cli-command/project/run.js index f5b531a..e9196a3 100644 --- a/src/cli-command/project/run.js +++ b/src/cli-command/project/run.js @@ -7,10 +7,12 @@ const sleep = require('sleep-promise') const Hjson = require('hjson'); const fse = require("fs-extra") +const path = require("path") const OutputHandler = require("../../OutputHandler") const FormatShift = require("../../util/FormatShift") const SpaceAndProjectApi = require("../../api/SpaceAndProjectApi") +const FileUtil = require("../../util/FileUtil"); //--------------------------------------------------- // @@ -38,7 +40,7 @@ let outputTableWidth = [4, 7, 6, -1]; let cliOutputIndex = 1; /** - * Given the step object, format it for output into LoggerWithLevels + * Given the step object, format it for output into OutputHandler * * @param {Object} step object to format * @return {Object} normalized step object, for final JSON output @@ -113,6 +115,18 @@ class TestRunnerSession { */ async S01_initialSetup(argv, context) { + // Lets quickly prepare the zip file concurrently + //--------------------------------------------------------------- + + let testCodeDir = argv.testCodeDir || argv["test-dir"]; + if( testCodeDir ) { + this.testCodeDir = testCodeDir; + + // This intentionally do not await, until later (to optimize zip times) + this.testCodeDir_zipPromise = FileUtil.prepareSrcCodeZipFile( testCodeDir ); + this.testCodeDir_zipFile = null + } + // Get the basic values //--------------------------------------------------------------- @@ -239,6 +253,12 @@ class TestRunnerSession { `> Data Set: ${this.dataSet}` ) } + // Log the test dir if present + if( this.testCodeDir != null ) { + OutputHandler.standardGreen( + `> Test Dir: ${this.testCodeDir}` + ) + } OutputHandler.standardGreen(">") } @@ -250,6 +270,17 @@ class TestRunnerSession { * Validate the current script pathing - throws error on error */ async validateScriptPath() { + // Check against the local files + if( this.testCodeDir != null ) { + let check = await fse.pathExists( path.resolve(this.testCodeDir, this.normalizedScriptPath) ); + if( !check ) { + OutputHandler.fatalError(`Invalid Script Path (does not exist?) : ${this.normalizedScriptPath}`); + process.exit(15); + } + return true; + } + + // Check against the API let fileList = await SpaceAndProjectApi.getProjectFileList(this.projectObj._oid); if( fileList.indexOf( this.normalizedScriptPath ) < 0 ) { OutputHandler.fatalError(`Invalid Script Path (does not exist?) : ${this.normalizedScriptPath}`); @@ -278,7 +309,7 @@ class TestRunnerSession { // Safety net, due to the possibility of file renaming race condition: validate script path // also terminate quickly tests, with invalid filepaths - await this.validateScriptPath() + await this.validateScriptPath(); // Skip, as concurrency is not sufficent (existing test runs) if( concurrency.avaliable <= 0 ) { @@ -304,7 +335,8 @@ class TestRunnerSession { dataSetID: this.dataSetID, data: this.dataObject, secretData: this.secretObject - } + }, + this.testCodeDir_zipFile ); // Lets get the testRunID if valid @@ -506,6 +538,15 @@ class TestRunnerSession { // Successful test start let successfulTestStarts = 0; + // Prepare testScript ZIP (if being used) + if( this.testCodeDir ) { + OutputHandler.standardGreen(`> Preparing test script files for upload ... `); + await this.validateScriptPath(); + this.testCodeDir_zipFile = await this.testCodeDir_zipPromise; + OutputHandler.standardGreen(`> Preparing test script files for upload ... Ready `); + OutputHandler.standardGreen(`> `); + } + // ------------------------------ // Lets start the core loop !!! // ------------------------------ @@ -622,7 +663,9 @@ class TestRunnerSession { // Inject the various URL links if( !this.assumeOnPremise ) { // Into the result message - resultMsg.push(`> See full results at : ${this.webstudioURL}/project/${this.projectID}/editor/${this.uriEncodedScriptPath}?testRunId=${this.testID}`) + if( this.testCodeDir == null ) { + resultMsg.push(`> See full results at : ${this.webstudioURL}/project/${this.projectID}/editor/${this.uriEncodedScriptPath}?testRunId=${this.testID}`) + } resultMsg.push(`> See result snippet at : ${this.privateSnippetURL}${this.testID}`) resultMsg.push(">") @@ -634,7 +677,9 @@ class TestRunnerSession { // This is the on-premise version !!! // Into the result message - resultMsg.push(`> See full results at : ${this.webstudioURL}/project/${this.projectID}/editor/${this.uriEncodedScriptPath}?testRunId=${this.testID}`) + if( this.testCodeDir == null ) { + resultMsg.push(`> See full results at : ${this.webstudioURL}/project/${this.projectID}/editor/${this.uriEncodedScriptPath}?testRunId=${this.testID}`) + } resultMsg.push(">") // Or json @@ -738,6 +783,10 @@ module.exports = { cmd.file("--secretFile ", { description: "Dataset to use, passed as a JSON file" }); + + cmd.file("--testCodeDir ", { + description: "Directory to upload and use for code files, this is used instead of the existing files on uilicious platform" + }); cmd.number("--startTimeout ", { description: "[default: 15] Max number of minutes to wait, if concurrency is fully used" @@ -968,8 +1017,6 @@ module.exports = { let scriptPath = argv["script-path"] if( scriptPath == null || scriptPath == "" ) { OutputHandler.cliArgumentError( `Test runs require a valid script-path: ${scriptPath}` ) - // LoggerWithLevels.error(`ERROR - Test runs require a valid script-path: ${scriptPath}`); - // process.exit(12) } }); }, diff --git a/src/util/FileUtil.js b/src/util/FileUtil.js index 4a9bf2b..eda0f97 100644 --- a/src/util/FileUtil.js +++ b/src/util/FileUtil.js @@ -9,10 +9,20 @@ const path = require("path") const fs = require("fs") const fse = require("fs-extra") +const crypto = require("crypto") +const process = require("process") +const archiver = require("archiver-promise") + // Normalize file path with linux formatting const normalizeLinuxPath = require("normalize-path") const bufferFrom = require('buffer-from') +// get temp directory +const tempDir = require("os").tmpdir(); // /tmp + +// additional dependencies +const OutputHandler = require("../OutputHandler") + //--------------------------------------------------- // // Class Definition @@ -57,7 +67,7 @@ class FileUtil { good(true); }); } catch(e) { - // LoggerWithLevels.error(e) + // OutputHandler.debug(e) bad(e); } }); @@ -174,34 +184,92 @@ class FileUtil { return resList; } - // /** - // * Validate a given path is a directory, or die - // * Use this to validate parameters given - // * - // * @return {Promise} true, only if all checks passes - // */ - // async validateLocalDirectory_orDie(path, pathType = "path") { - // LoggerWithLevels.trace(`Validating for writable directory : ${path}`) - - // try { - // let checks = await fs.pathExists(path) - // if( !checks ) { - // LoggerWithLevels.exitError(`${pathType} does not exists : ${path}`); - // return false; - // } + /** + * Validate a given path is a directory, or die + * Use this to validate parameters given + * + * @return {Promise} true, only if all checks passes + */ + async validateLocalDirectory_orDie(path, pathType = "path") { + OutputHandler.debug(`Validating for directory : ${path}`) + + try { + let checks = await fse.pathExists(path) + if( !checks ) { + OutputHandler.fatalError(`${pathType} does not exists : ${path}`); + return false; + } - // // Checks for a valid directory, else throw an error - // await fs.ensureDir(path) - // } catch(e) { - // LoggerWithLevels.error(`ERROR - Invalid directory ${pathType} : ${path}`); - // LoggerWithLevels.error(e); - // LoggerWithLevels.exitError(`Invalid directory ${pathType} : ${path}`); - // return false; - // } - - // // All passes, yay - // return true; - // } + // Checks for a valid directory, else throw an error + await fse.ensureDir(path) + } catch(e) { + OutputHandler.fatalError(`Invalid directory ${pathType} : ${path}`, e); + return false; + } + + // All passes, yay + return true; + } + + /** + * Given the project dir path, prepare a zip file, for uploading + * @param {Path} srcCodeDir + */ + async prepareSrcCodeZipFile( srcCodeDir ) { + // Lets normalize the provided srcCodeDir, and validate it + srcCodeDir = path.resolve( srcCodeDir ); + await this.validateLocalDirectory_orDie( srcCodeDir ); + + // The zip file ID to use (randomly generated) + const zipID = crypto.randomBytes(16).toString("hex"); + + // Prepare tmp dir + await fse.ensureDir( path.resolve(tempDir, "uilicious-cli/zip/") ); + + // Zip file path we will use + const zipFilePath = path.resolve(tempDir, "uilicious-cli/zip/"+zipID+".zip"); + const archive = archiver(zipFilePath, { + zlib: { level: 3 } // Sets the compression level. + }); + + // Lets register the on exit cleanup / removal of tmp zip file + process.on('exit', () => { + fse.removeSync( zipFilePath ); + }); + + // // Pipe the archiver + // const zipOutput = fs.createWriteStream( zipFilePath ); + // archive.pipe(zipOutput); + + // Lets generate the file list + const fileList = await this.generateFileList( srcCodeDir ); + + // the current total file sizes + let totalFileSizes = 0; + + // Lets prepare the zip file, and compute the total size + for( const filePath of fileList ) { + const fullFilePath = path.resolve( srcCodeDir, filePath ); + archive.file(fullFilePath, { name: filePath }); + + // Get the file stat, assume a minimum of 5kb + // (work around some known limitations in FS) + const fileStat = await fs.promises.stat( fullFilePath ); + totalFileSizes += Math.min(fileStat.size, 5 * 1000); + } + + // Check if the total file sizes is >= 100MB + if( totalFileSizes >= (100 * 1000 * 1000) ) { + OutputHandler.fatalError(`Test code directory is larger then 100MB - aborting`); + return; + } + + // Lets finalize and await + await archive.finalize(); + + // Return the zip file path + return zipFilePath; + } } diff --git a/src/version.js b/src/version.js index 7bd2d41..1fbb114 100755 --- a/src/version.js +++ b/src/version.js @@ -1 +1 @@ -module.exports = "5.1.4" \ No newline at end of file +module.exports = "5.1.6" \ No newline at end of file