vue-ninja 0.5.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/vue-ninja.js +1 -1
- package/package.json +22 -22
package/dist/vue-ninja.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import e from"command-line-args";import{rimrafSync as r}from"rimraf";import t from"fs";import
|
|
2
|
+
import e from"command-line-args";import{rimrafSync as r}from"rimraf";import t from"fs";import o from"crypto";import s from"child_process";import n from"prompt";import i from"util";import{glob as a}from"glob";import c from"chalk";import u from"axios";const l=i.promisify(s.exec),h=i.promisify(t.readFile),d=e=>h(e,"utf8"),g=e=>l(e,{maxBuffer:1024e3}),m=e=>new Promise(((r,t)=>{n.start(),n.get(e,((e,o)=>{e?t():r(o)}))})),f=e=>a(e,{nodir:!0,posix:!0}),p=e=>{const r=t.readFileSync(e),s=o.createHash("sha256");return s.update(r),s.digest("hex")},y={log:console.log,error:e=>console.log(c.red(e)),warn:e=>console.log(c.yellow(e)),success:e=>console.log(c.green(e)),debug:(e,r,t)=>{e.verbose&&(t?console.log(c.gray(r),c.gray(t)):console.log(c.gray(r)))}},w="results/vitest-results.json";function v(e,r,t){const o=JSON.parse(e);if(!o)return y.error("An error occurred during the unit tests."),y.error("Run `npm run test:unit` to see the problem."),t();const s={failed:o.numFailedTests?o.numFailedTests:o.numFailedTestSuites,success:o.numPassedTests};return 0!==s.failed?function(e){const r=function(e){if(void 0===e.failed)return 0;const r=100-5*e.failed;return r>=0?r:0}(e);y.warn("Unit tests score: "+r+"%"),y.warn("Looks like you have "+(e.failed?e.failed:"a few")+" unit test(s) failing."),y.warn("Launch `npm run test:unit` and try to fix them.")}(s):y.success("Unit tests score: 100%"),r(s)}const b=e=>new Promise(((r,t)=>(y.log("Starting unit tests..."),g("npm run test:unit:ci").then((()=>d(w)),(r=>(y.debug(e,"Vitest test failed",r),d(w)))).then((e=>v(e,r,t)),(r=>(y.debug(e,"An error occurred while reading vitest results: ",r),function(e){return y.error("Error while running unit tests."),y.error("Maybe your code doesn't compile?"),y.error("Launch `npm run test:unit` to see more."),e()}(t)))))));function k(){return f("./{cypress,src}/**/*.@(cy|spec).ts").then((e=>function(e){return e.map((e=>({name:e,hash:p(e)})))}(e)))}const x=e=>new Promise(((r,t)=>(y.log("Starting code coverage..."),d("coverage/coverage-summary.json").then((e=>function(e,r){const t=e.replace(/\\/g,"/"),o=JSON.parse(t),s={covered:o.total.lines.covered,total:o.total.lines.total},n=function(e){const r=100+e.covered-e.total;return r<0?0:r}(s);100!==n?(y.warn("Code coverage score: "+n+"%"),y.warn("Looks like you don't have a perfect code coverage."),y.warn("Maybe you skipped/deleted some unit tests?"),y.warn("Or maybe you added some code to try something, and this is not covered by a unit test?"),y.warn("To have more info open `coverage/index.html`"),y.warn("You should see which file has a problem.")):y.success("Code coverage score: 100%"),r(s)}(e,r)),(r=>{y.error("Error while reading the code coverage results. Try to run `npm run test:unit`."),y.debug(e,"Error while reading the code coverage results was: ",r),t()}))))),E="results/lint-results.json",j="results/cypress-results.json";function S(){return g(`npx mochawesome-merge ./results/mochawesome/*.json -o ${j}`)}const P=e=>new Promise(((r,t)=>(y.log("Starting end to end tests..."),g("npm run test:e2e:ci").then((()=>S()),(r=>(y.debug(e,"Error while running e2e was: ",r),S()))).then((()=>d(j)),(()=>d(j))).then((e=>function(e){const r=JSON.parse(e),t=r.stats.failures,o=r.stats.passes,s={success:o,failed:t};return t?(y.warn("Looks like you have "+t+" e2e tests failing."),y.warn("Try to launch the tests using `npm run test:e2e`."),y.warn(`E2e tests score: ${Math.round(100*o/(o+t))}%`)):y.success("E2e tests score: 100%"),s}(e))).then((e=>r(e)),(r=>(y.debug(e,"Error while reading e2e results: ",r),y.error("Error while running end-to-end tests."),y.error("Check if your app is running with no error in the browser console,"),y.error("and try to launch the tests using `npm run test:e2e`."),t())))))),O="https://vue-exercises.ninja-squad.com",J="http://localhost:8080";function N(e,r,t){if((r+=1)>3)return y.error("Aborting authentication after 3 failures"),Promise.reject();return m({properties:{email:{required:!0},password:{hidden:!0,required:!0}}}).then((r=>u.post(`${e["local-server"]?J:O}/api/authentications`,r))).then((o=>201!==o.status?(y.error("Authentication failed, try again."),y.debug(e,`Authentication request returned with status: ${o.status}`),N(e,r,t)):(y.debug(e,"Authentication succeeded and we can store credentials"),function(e,r){return y.success("Authentication success"),e.token=r,e}(t,o.data.token))),(o=>(y.error("Authentication failed, try again."),y.debug(e,"An error occurred during authentication: ",o),N(e,r,t))))}function A(e,r,t){let o=100-5*r.vitest.failed-r.tslint.errors-(r.coverage.total-r.coverage.covered)-r.e2e.failed;var s;return o<10&&(o=10),t.local?(100!==o&&(y.error("Score is not perfect! "+o+"%"),s=1,process.exit(s)),y.success("Exercise score: "+o+"%")):100!==o?y.warn("Score is not perfect yet: "+o+"%"):y.success("Perfect score, congrats! "+o+"%"),{metadata:e,score:o}}function T(e,r){const t={Authorization:`Bearer: ${r.token}`},o=e["local-server"]?J:O,s={score:r.score};return u.post(`${o}/api/packs/${r.pack}/exercises/${r.id}/scores`,s,{headers:t}).then((t=>{if(401===t.status){y.error("Authentication failed. Please enter your credentials again.");return N(e,0,r).then((r=>T(e,r)),(r=>(y.error("Error while authenticating to submit results."),y.debug(e,"Error was: ",r),Promise.reject())))}return 201!==t.status?(y.error("Error while sending the results."),y.debug(e,JSON.stringify(t.status),JSON.stringify(t.data)),Promise.reject()):(y.log("Score submitted."),Promise.resolve(r))}),(r=>(y.error("Error while sending the results."),y.error("Maybe check your connection?"),y.debug(e,"Error while sending the result was: ",r),Promise.reject())))}const C=(e,r)=>d("./exercise.json").then((e=>JSON.parse(e)),(e=>(y.error("Looks like you have no exercise.json file."),y.debug(r,"An error occurred while reading exercise.json: ",e),Promise.reject()))).then((t=>A(t,e,r)),(e=>(y.error("Looks like you have an incorrect JSON in the exercise.json file."),y.debug(r,"An error occurred while parsing exercise.json: ",e),Promise.reject()))).then((({metadata:e,score:t})=>{e.score=t;return r.local?e:N(r,0,e)})).then((e=>r.local?e:T(r,e))),L=e([{name:"local",type:Boolean},{name:"local-server",type:Boolean},{name:"verbose",type:Boolean},{name:"skip-check",type:Boolean}]);r("results");const $={coverage:{covered:100,total:100},e2e:{failed:0,success:1},tslint:{errors:0}};(e=>new Promise(((r,t)=>{y.log("Checking submission..."),d("./exercise.json").then((t=>{const o=JSON.parse(t);return y.success("Pack V"+o.pack+" - Exercise "+o.id+" - "+o.title),e["skip-check"]?r(o):o}),(r=>(y.error("Looks like you have no exercise.json file."),y.debug(e,"An error occurred while reading exercise.json: ",r),Promise.reject()))).then((e=>Promise.all([e,k()]))).then((([r,t])=>{y.debug(e,"Exercise :",JSON.stringify(r)),y.debug(e,"Hashes :",JSON.stringify(t));const o=[],s=[];return r.specs.forEach((e=>{const r=function(e,r){return e.find((e=>-1!==e.name.indexOf(r)))}(t,e.name);r?r.hash!==e.hash&&o.push(e.name):s.push(e.name)})),0!==o.length||0!==s.length?(0!==o.length&&(y.error("It looks like you forgot to update these spec files"),y.error("or that you modified them manually:"),o.forEach((e=>y.error(" - "+e)))),0!==s.length&&(y.error("It looks like you forgot to add these spec files:"),s.forEach((e=>y.error(" - "+e)))),y.error("Copy the new specs and try again."),Promise.reject()):r}),(r=>(y.debug(e,"Error while computing the hash of the spec files. ",r),Promise.reject(r)))).then((e=>r(e)),(e=>t(e)))})))(L).then((e=>$.exercise=e)).then((()=>y.debug(L,"Exercise: ",$.exercise.title))).then((()=>b(L))).then((e=>$.vitest=e)).then((()=>y.debug(L,"Vitest results: ",JSON.stringify($.vitest)))).then((()=>x(L))).then((e=>$.coverage=e)).then((()=>y.debug(L,"Coverage results: ",JSON.stringify($.coverage)))).then((()=>(e=>new Promise(((r,t)=>(y.log("Starting code analysis..."),g(`npm run lint -- --no-fix --format=json --output-file=${E}`).then((()=>d(E)),(()=>d(E))).then((e=>e?JSON.parse(e):Promise.reject()),(r=>{y.error("Error while running `npm run lint`."),y.error("Try to run `npm run lint`."),y.debug(e,"Error while running lint was: ",r),t()})).then((e=>{if(!e)return t();const o={errors:0};if(o.errors=e.map((e=>e.errorCount+e.warningCount)).reduce(((e,r)=>e+r),0),0!==o.errors){const e=Math.max(0,100-o.errors);y.warn("Code quality score: "+e+"%"),y.warn("Looks like you have some issues in your code."),y.warn("Try to run `npm run lint` to see what you can fix.")}else y.success("Code quality score: 100%");r(o)}),(r=>{y.error("Error while reading lint results."),y.error("Try to run `npm run lint`."),y.debug(e,"Error while reading lint errors was: ",r),t()}))))))(L))).then((e=>$.tslint=e)).then((()=>y.debug(L,"Linter results: ",JSON.stringify($.tslint)))).then((()=>P(L))).then((e=>$.e2e=e)).then((()=>y.debug(L,"E2e results: ",JSON.stringify($.e2e)))).then((()=>C($,L))).catch((e=>{y.error("Try to fix it and retry!"),L.verbose&&y.error(e),L.local&&(y.error("Running locally, we exit"),process.exit(1))}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vue-ninja",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "CLI for the exercises of \"Become a ninja with Vue\"",
|
|
5
5
|
"main": "dist/vue-ninja.js",
|
|
6
6
|
"exports": null,
|
|
@@ -8,31 +8,31 @@
|
|
|
8
8
|
"author": "",
|
|
9
9
|
"license": "ISC",
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"axios": "1.
|
|
12
|
-
"chalk": "5.
|
|
11
|
+
"axios": "1.6.3",
|
|
12
|
+
"chalk": "5.3.0",
|
|
13
13
|
"command-line-args": "5.2.1",
|
|
14
|
-
"glob": "10.
|
|
14
|
+
"glob": "10.3.10",
|
|
15
15
|
"prompt": "1.3.0",
|
|
16
|
-
"rimraf": "5.0.
|
|
16
|
+
"rimraf": "5.0.5"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
|
-
"@rollup/plugin-terser": "0.4.
|
|
20
|
-
"@rollup/plugin-typescript": "11.1.
|
|
21
|
-
"@types/command-line-args": "5.2.
|
|
22
|
-
"@types/
|
|
23
|
-
"@types/
|
|
24
|
-
"@
|
|
25
|
-
"@typescript-eslint/
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"eslint": "
|
|
29
|
-
"eslint-
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"vitest": "
|
|
19
|
+
"@rollup/plugin-terser": "0.4.4",
|
|
20
|
+
"@rollup/plugin-typescript": "11.1.5",
|
|
21
|
+
"@types/command-line-args": "5.2.3",
|
|
22
|
+
"@types/node": "20.10.5",
|
|
23
|
+
"@types/prompt": "1.1.8",
|
|
24
|
+
"@typescript-eslint/eslint-plugin": "6.16.0",
|
|
25
|
+
"@typescript-eslint/parser": "6.16.0",
|
|
26
|
+
"create-vue": "3.9.1",
|
|
27
|
+
"eslint": "8.56.0",
|
|
28
|
+
"eslint-config-prettier": "9.1.0",
|
|
29
|
+
"eslint-plugin-prettier": "5.1.2",
|
|
30
|
+
"prettier": "3.1.1",
|
|
31
|
+
"rollup": "4.9.1",
|
|
32
|
+
"tslib": "2.6.2",
|
|
33
|
+
"typescript": "5.3.3",
|
|
34
|
+
"vite": "5.0.10",
|
|
35
|
+
"vitest": "1.1.0"
|
|
36
36
|
},
|
|
37
37
|
"bin": {
|
|
38
38
|
"vue-ninja": "dist/vue-ninja.js"
|