vue-ninja 0.4.0-beta.0 → 0.4.0-beta.1

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 CHANGED
@@ -1,63 +1,2 @@
1
1
  #!/usr/bin/env node
2
- "use strict";
3
- var __importDefault = (this && this.__importDefault) || function (mod) {
4
- return (mod && mod.__esModule) ? mod : { "default": mod };
5
- };
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- var command_line_args_1 = __importDefault(require("command-line-args"));
8
- var rimraf_1 = __importDefault(require("rimraf"));
9
- var vitest_1 = __importDefault(require("./vitest"));
10
- var hash_checker_1 = __importDefault(require("./hash-checker"));
11
- var coverage_1 = __importDefault(require("./coverage"));
12
- var lint_1 = __importDefault(require("./lint"));
13
- var e2e_1 = __importDefault(require("./e2e"));
14
- var submit_results_1 = __importDefault(require("./submit-results"));
15
- var logger_1 = require("./logger");
16
- // parse cli options
17
- var options = (0, command_line_args_1.default)([
18
- { name: 'local', type: Boolean },
19
- { name: 'local-server', type: Boolean },
20
- { name: 'verbose', type: Boolean },
21
- { name: 'skip-check', type: Boolean }
22
- ]);
23
- // clean up the directory
24
- rimraf_1.default.sync('results/*');
25
- var results = {
26
- coverage: {
27
- covered: 100,
28
- total: 100
29
- },
30
- e2e: {
31
- failed: 0,
32
- success: 1
33
- },
34
- tslint: {
35
- errors: 0
36
- }
37
- };
38
- (0, hash_checker_1.default)(options)
39
- .then(function (exercise) { return (results.exercise = exercise); })
40
- .then(function () { return logger_1.logger.debug(options, 'Exercise: ', results.exercise.title); })
41
- .then(function () { return (0, vitest_1.default)(options); })
42
- .then(function (vitestResults) { return (results.vitest = vitestResults); })
43
- .then(function () { return logger_1.logger.debug(options, 'Vitest results: ', JSON.stringify(results.vitest)); })
44
- .then(function () { return (0, coverage_1.default)(options); })
45
- .then(function (coverageResults) { return (results.coverage = coverageResults); })
46
- .then(function () { return logger_1.logger.debug(options, 'Coverage results: ', JSON.stringify(results.coverage)); })
47
- .then(function () { return (0, lint_1.default)(options); })
48
- .then(function (tslintResults) { return (results.tslint = tslintResults); })
49
- .then(function () { return logger_1.logger.debug(options, 'Linter results: ', JSON.stringify(results.tslint)); })
50
- .then(function () { return (0, e2e_1.default)(options); })
51
- .then(function (e2eResults) { return (results.e2e = e2eResults); })
52
- .then(function () { return logger_1.logger.debug(options, 'E2e results: ', JSON.stringify(results.e2e)); })
53
- .then(function () { return (0, submit_results_1.default)(results, options); })
54
- .catch(function (error) {
55
- logger_1.logger.error('Try to fix it and retry!');
56
- if (options.verbose) {
57
- logger_1.logger.error(error);
58
- }
59
- if (options.local) {
60
- logger_1.logger.error('Running locally, we exit');
61
- process.exit(1);
62
- }
63
- });
2
+ "use strict";var W=Object.create;var P=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var z=Object.getOwnPropertyNames;var Y=Object.getPrototypeOf,D=Object.prototype.hasOwnProperty;var G=(e,t,o,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of z(t))!D.call(e,n)&&n!==o&&P(e,n,{get:()=>t[n],enumerable:!(s=_(t,n))||s.enumerable});return e};var g=(e,t,o)=>(o=e!=null?W(Y(e)):{},G(t||!e||!e.__esModule?P(o,"default",{value:e,enumerable:!0}):o,e));var M=g(require("../node_modules/command-line-args/dist/index.js")),V=g(require("../node_modules/rimraf/rimraf.js"));var y=g(require("fs")),k=g(require("crypto")),S=g(require("child_process")),p=g(require("../node_modules/prompt/lib/prompt.js")),w=g(require("util")),R=g(require("../node_modules/glob/glob.js"));var d=g(require("../node_modules/chalk/source/index.js")),r={log:console.log,error:e=>console.log(d.default.red(e)),warn:e=>console.log(d.default.yellow(e)),success:e=>console.log(d.default.green(e)),debug:(e,t,o)=>{e.verbose&&(o?console.log(d.default.gray(t),d.default.gray(o)):console.log(d.default.gray(t)))}};var K=w.default.promisify(S.default.exec),Q=w.default.promisify(y.default.readFile),u=e=>Q(e,"utf8"),h=e=>K(e,{maxBuffer:1024*1e3}),T=e=>new Promise((t,o)=>{p.default.start(),p.default.get(e,(s,n)=>{s?o():t(n)})}),O=e=>new Promise((t,o)=>{(0,R.default)(e,{nodir:!0},(s,n)=>{s?(r.error("Could not find the spec files."),o(s)):t(n)})}),F=e=>{process.exit(e)},A=e=>{let t=y.default.readFileSync(e),o=k.default.createHash("sha256");return o.update(t),o.digest("hex")};var C="results/vitest-results.json";function X(e){if(e.failed===void 0)return 0;let t=100-e.failed*5;return t>=0?t:0}function Z(e){let t=X(e);r.warn("Unit tests score: "+t+"%"),r.warn("Looks like you have "+(e.failed?e.failed:"a few")+" unit test(s) failing."),r.warn("Launch `npm run test:unit` and try to fix them.")}function ee(e){return r.error("Error while running unit tests."),r.error("Maybe your code doesn't compile?"),r.error("Launch `npm run test:unit` to see more."),e()}function re(e,t,o,s){let n=JSON.parse(e);if(!n)return r.error("An error occurred during the unit tests."),r.error("Run `npm run test:unit` to see the problem."),s();let l={failed:n.numFailedTests?n.numFailedTests:n.numFailedTestSuites,success:n.numPassedTests};return l.failed!==0?Z(l):r.success("Unit tests score: 100%"),o(l)}var te=e=>new Promise((t,o)=>(r.log("Starting unit tests..."),h("npm run test:unit:ci").then(()=>u(C),s=>(r.debug(e,"Vitest test failed",s),u(C))).then(s=>re(s,e,t,o),s=>(r.debug(e,"An error occurred while reading vitest results: ",s),ee(o))))),L=te;function se(e,t){return e.find(o=>o.name.indexOf(t)!==-1)}function oe(){return O("./{cypress,src}/**/*.@(cy|spec).ts")}function ne(e){return e.map(t=>({name:t,hash:A(t)}))}function ie(){return oe().then(e=>ne(e))}var ue=e=>new Promise((t,o)=>{r.log("Checking submission..."),u("./exercise.json").then(s=>{let n=JSON.parse(s);return r.success("Pack V"+n.pack+" - Exercise "+n.id+" - "+n.title),e["skip-check"]?t(n):n},s=>(r.error("Looks like you have no exercise.json file."),r.debug(e,"An error occurred while reading exercise.json: ",s),Promise.reject())).then(s=>Promise.all([s,ie()])).then(([s,n])=>{r.debug(e,"Exercise :",JSON.stringify(s)),r.debug(e,"Hashes :",JSON.stringify(n));let i=[],l=[];return s.specs.forEach(a=>{let E=se(n,a.name);E?E.hash!==a.hash&&i.push(a.name):l.push(a.name)}),i.length!==0||l.length!==0?(i.length!==0&&(r.error("It looks like you forgot to update these spec files"),r.error("or that you modified them manually:"),i.forEach(a=>r.error(" - "+a))),l.length!==0&&(r.error("It looks like you forgot to add these spec files:"),l.forEach(a=>r.error(" - "+a))),r.error("Copy the new specs and try again."),Promise.reject()):s},s=>(r.debug(e,"Error while computing the hash of the spec files. ",s),Promise.reject(s))).then(s=>t(s),s=>o(s))}),j=ue;var ce="coverage/coverage-summary.json";function ae(e){let t=100+e.covered-e.total;return t<0?0:t}function le(e,t){let o=e.replace(/\\/g,"/"),s=JSON.parse(o),n={covered:s.total.lines.covered,total:s.total.lines.total},i=ae(n);i!==100?(r.warn("Code coverage score: "+i+"%"),r.warn("Looks like you don't have a perfect code coverage."),r.warn("Maybe you skipped/deleted some unit tests?"),r.warn("Or maybe you added some code to try something, and this is not covered by a unit test?"),r.warn("To have more info open `coverage/index.html`"),r.warn("You should see which file has a problem.")):r.success("Code coverage score: 100%"),t(n)}var me=e=>new Promise((t,o)=>(r.log("Starting code coverage..."),u(ce).then(s=>le(s,t),s=>{r.error("Error while reading the code coverage results. Try to run `npm run test:unit`."),r.debug(e,"Error while reading the code coverage results was: ",s),o()}))),N=me;var b="results/lint-results.json",ge=e=>new Promise((t,o)=>(r.log("Starting code analysis..."),h(`npm run lint -- --no-fix --format=json --output-file=${b}`).then(()=>u(b),()=>u(b)).then(s=>s?JSON.parse(s):Promise.reject(),s=>{r.error("Error while running `npm run lint`."),r.error("Try to run `npm run lint`."),r.debug(e,"Error while running lint was: ",s),o()}).then(s=>{if(!s)return o();let n={errors:0};if(n.errors=s.map(i=>i.errorCount+i.warningCount).reduce((i,l)=>i+l,0),n.errors!==0){let i=Math.max(0,100-n.errors);r.warn("Code quality score: "+i+"%"),r.warn("Looks like you have some issues in your code."),r.warn("Try to run `npm run lint` to see what you can fix.")}else r.success("Code quality score: 100%");t(n)},s=>{r.error("Error while reading lint results."),r.error("Try to run `npm run lint`."),r.debug(e,"Error while reading lint errors was: ",s),o()}))),J=ge;var x="results/cypress-results.json";function de(){r.error("Error while running end-to-end tests."),r.error("Check if your app is running with no error in the browser console,"),r.error("and try to launch the tests using `npm run test:e2e`.")}function he(e){let t=JSON.parse(e),o=t.stats.failures,s=t.stats.passes,n={success:s,failed:o};return o?(r.warn("Looks like you have "+o+" e2e tests failing."),r.warn("Try to launch the tests using `npm run test:e2e`."),r.warn(`E2e tests score: ${Math.round(s*100/(s+o))}%`)):r.success("E2e tests score: 100%"),n}function U(){return h(`npx mochawesome-merge ./results/mochawesome/*.json -o ${x}`)}var fe=e=>new Promise((t,o)=>(r.log("Starting end to end tests..."),h("npm run test:e2e:ci").then(()=>U(),s=>(r.debug(e,"Error while running e2e was: ",s),U())).then(()=>u(x),()=>u(x)).then(s=>he(s)).then(s=>t(s),s=>(r.debug(e,"Error while reading e2e results: ",s),de(),o())))),H=fe;var v=g(require("../node_modules/axios/index.js")),I="https://vue-exercises.ninja-squad.com",$="http://localhost:8080";function pe(e,t){return r.success("Authentication success"),e.token=t,e}function f(e,t,o){return t=t+1,t>3?(r.error("Aborting authentication after 3 failures"),Promise.reject()):T({properties:{email:{required:!0},password:{hidden:!0,required:!0}}}).then(n=>v.default.post(`${e["local-server"]?$:I}/api/authentications`,n)).then(n=>n.status!==201?(r.error("Authentication failed, try again."),r.debug(e,`Authentication request returned with status: ${n.status}`),f(e,t,o)):(r.debug(e,"Authentication succeeded and we can store credentials"),pe(o,n.data.token)),n=>(r.error("Authentication failed, try again."),r.debug(e,"An error occurred during authentication: ",n),f(e,t,o)))}function ye(e,t,o){let s=100-t.vitest.failed*5-t.tslint.errors-(t.coverage.total-t.coverage.covered)-t.e2e.failed;return s<10&&(s=10),o.local?(s!==100&&(r.error("Score is not perfect! "+s+"%"),F(1)),r.success("Exercise score: "+s+"%")):s!==100?r.warn("Score is not perfect yet: "+s+"%"):r.success("Perfect score, congrats! "+s+"%"),{metadata:e,score:s}}function B(e,t){let o={Authorization:`Bearer: ${t.token}`},s=e["local-server"]?$:I,n={score:t.score};return v.default.post(`${s}/api/packs/${t.pack}/exercises/${t.id}/scores`,n,{headers:o}).then(i=>i.status===401?(r.error("Authentication failed. Please enter your credentials again."),f(e,0,t).then(a=>B(e,a),a=>(r.error("Error while authenticating to submit results."),r.debug(e,"Error was: ",a),Promise.reject()))):i.status!==201?(r.error("Error while sending the results."),r.debug(e,JSON.stringify(i.status),JSON.stringify(i.data)),Promise.reject()):(r.log("Score submitted."),Promise.resolve(t)),i=>(r.error("Error while sending the results."),r.error("Maybe check your connection?"),r.debug(e,"Error while sending the result was: ",i),Promise.reject()))}var we=(e,t)=>u("./exercise.json").then(o=>JSON.parse(o),o=>(r.error("Looks like you have no exercise.json file."),r.debug(t,"An error occurred while reading exercise.json: ",o),Promise.reject())).then(o=>ye(o,e,t),o=>(r.error("Looks like you have an incorrect JSON in the exercise.json file."),r.debug(t,"An error occurred while parsing exercise.json: ",o),Promise.reject())).then(({metadata:o,score:s})=>{o.score=s;let n=0;return t.local?o:f(t,n,o)}).then(o=>t.local?o:B(t,o)),q=we;var c=(0,M.default)([{name:"local",type:Boolean},{name:"local-server",type:Boolean},{name:"verbose",type:Boolean},{name:"skip-check",type:Boolean}]);V.default.sync("results/*");var m={coverage:{covered:100,total:100},e2e:{failed:0,success:1},tslint:{errors:0}};j(c).then(e=>m.exercise=e).then(()=>r.debug(c,"Exercise: ",m.exercise.title)).then(()=>L(c)).then(e=>m.vitest=e).then(()=>r.debug(c,"Vitest results: ",JSON.stringify(m.vitest))).then(()=>N(c)).then(e=>m.coverage=e).then(()=>r.debug(c,"Coverage results: ",JSON.stringify(m.coverage))).then(()=>J(c)).then(e=>m.tslint=e).then(()=>r.debug(c,"Linter results: ",JSON.stringify(m.tslint))).then(()=>H(c)).then(e=>m.e2e=e).then(()=>r.debug(c,"E2e results: ",JSON.stringify(m.e2e))).then(()=>q(m,c)).catch(e=>{r.error("Try to fix it and retry!"),c.verbose&&r.error(e),c.local&&(r.error("Running locally, we exit"),process.exit(1))});
package/package.json CHANGED
@@ -1,38 +1,39 @@
1
1
  {
2
2
  "name": "vue-ninja",
3
- "version": "0.4.0-beta.0",
3
+ "version": "0.4.0-beta.1",
4
4
  "description": "CLI for the exercises of \"Become a ninja with Vue\"",
5
5
  "main": "dist/vue-ninja.js",
6
6
  "scripts": {
7
- "build": "tsc",
7
+ "build": "esbuild src/vue-ninja.ts --bundle --outfile=dist/vue-ninja.js --platform=node --minify --external:./node_modules/*",
8
8
  "test": "vitest",
9
- "prepublish": "npm run build",
10
- "lint": "eslint {src,tests}/**/* --ext .ts"
9
+ "lint": "eslint {src,tests}/**/* --ext .ts",
10
+ "type-check": "tsc --noEmit"
11
11
  },
12
12
  "author": "",
13
13
  "license": "ISC",
14
14
  "dependencies": {
15
+ "axios": "0.27.2",
15
16
  "chalk": "4.1.2",
16
17
  "command-line-args": "5.2.1",
17
18
  "glob": "8.0.3",
18
19
  "prompt": "1.3.0",
19
- "request": "2.88.2",
20
20
  "rimraf": "3.0.2"
21
21
  },
22
22
  "devDependencies": {
23
- "@typescript-eslint/eslint-plugin": "5.35.1",
24
- "@typescript-eslint/parser": "5.35.1",
25
23
  "@types/command-line-args": "5.2.0",
26
- "@types/glob": "7.2.0",
24
+ "@types/glob": "8.0.0",
27
25
  "@types/node": "16.11.56",
28
26
  "@types/request": "2.48.8",
29
27
  "@types/rimraf": "3.0.2",
28
+ "@typescript-eslint/eslint-plugin": "5.36.1",
29
+ "@typescript-eslint/parser": "5.36.1",
30
30
  "create-vue": "3.3.2",
31
- "eslint": "8.22.0",
31
+ "esbuild": "0.15.6",
32
+ "eslint": "8.23.0",
32
33
  "eslint-config-prettier": "8.5.0",
33
34
  "eslint-plugin-prettier": "4.2.1",
34
35
  "prettier": "2.7.1",
35
- "typescript": "4.7.4",
36
+ "typescript": "4.8.2",
36
37
  "vitest": "0.22.1"
37
38
  },
38
39
  "bin": {
package/dist/coverage.js DELETED
@@ -1,41 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- var logger_1 = require("./logger");
4
- var utils_1 = require("./utils");
5
- var RESULT_FILE = 'coverage/coverage-summary.json';
6
- function computeScore(coverageResults) {
7
- var score = 100 + coverageResults.covered - coverageResults.total;
8
- return score < 0 ? 0 : score;
9
- }
10
- function handleCoverageResults(data, resolve) {
11
- // temporary workaround for https://github.com/istanbuljs/istanbul-reports/pull/20/files:
12
- // the file paths are not properly encoded in the JSON, and so we transform backslashes to slashes.
13
- // since everything else in the file is just hard-coded keys and numbers, this should work fine.
14
- var dataEncoded = data.replace(/\\/g, '/');
15
- var results = JSON.parse(dataEncoded);
16
- var coverageResults = { covered: results.total.lines.covered, total: results.total.lines.total };
17
- var score = computeScore(coverageResults);
18
- if (score !== 100) {
19
- logger_1.logger.warn('Code coverage score: ' + score + '%');
20
- logger_1.logger.warn("Looks like you don't have a perfect code coverage.");
21
- logger_1.logger.warn('Maybe you skipped/deleted some unit tests?');
22
- logger_1.logger.warn('Or maybe you added some code to try something, and this is not covered by a unit test?');
23
- logger_1.logger.warn('To have more info open `coverage/index.html`');
24
- logger_1.logger.warn('You should see which file has a problem.');
25
- }
26
- else {
27
- logger_1.logger.success('Code coverage score: 100%');
28
- }
29
- resolve(coverageResults);
30
- }
31
- var coverage = function (options) {
32
- return new Promise(function (resolve, reject) {
33
- logger_1.logger.log('Starting code coverage...');
34
- return (0, utils_1.readFile)(RESULT_FILE).then(function (data) { return handleCoverageResults(data, resolve); }, function (error) {
35
- logger_1.logger.error('Error while reading the code coverage results. Try to run `npm run test:unit`.');
36
- logger_1.logger.debug(options, 'Error while reading the code coverage results was: ', error);
37
- reject();
38
- });
39
- });
40
- };
41
- exports.default = coverage;
package/dist/e2e.js DELETED
@@ -1,52 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- var logger_1 = require("./logger");
4
- var utils_1 = require("./utils");
5
- var RESULT_FILE = 'results/cypress-results.json';
6
- function warnUserOnFailure() {
7
- logger_1.logger.error('Error while running end-to-end tests.');
8
- logger_1.logger.error('Check if your app is running with no error in the browser console,');
9
- logger_1.logger.error('and try to launch the tests using `npm run test:e2e`.');
10
- }
11
- function handleCypressResults(data) {
12
- var results = JSON.parse(data);
13
- var failed = results.stats.failures;
14
- var success = results.stats.passes;
15
- var cypressResults = { success: success, failed: failed };
16
- if (failed) {
17
- logger_1.logger.warn('Looks like you have ' + failed + ' e2e tests failing.');
18
- logger_1.logger.warn('Try to launch the tests using `npm run test:e2e`.');
19
- logger_1.logger.warn("E2e tests score: ".concat(Math.round((success * 100) / (success + failed)), "%"));
20
- }
21
- else {
22
- logger_1.logger.success('E2e tests score: 100%');
23
- }
24
- return cypressResults;
25
- }
26
- function mergeReports() {
27
- return (0, utils_1.exec)("npx mochawesome-merge ./results/mochawesome/*.json -o ".concat(RESULT_FILE));
28
- }
29
- var e2e = function (options) {
30
- return new Promise(function (resolve, reject) {
31
- logger_1.logger.log('Starting end to end tests...');
32
- // cypress exit code is 1 if a test fail
33
- // so we'll go into the error handler even if the execution went well
34
- // and we try to read the results in both cases
35
- // mode=production is a hacky way to ensure integration tests pass.
36
- return (0, utils_1.exec)('npm run test:e2e:ci')
37
- .then(
38
- // each spec produces a report, so we need to merge them
39
- function () { return mergeReports(); }, function (error) {
40
- logger_1.logger.debug(options, 'Error while running e2e was: ', error);
41
- return mergeReports();
42
- })
43
- .then(function () { return (0, utils_1.readFile)(RESULT_FILE); }, function () { return (0, utils_1.readFile)(RESULT_FILE); })
44
- .then(function (data) { return handleCypressResults(data); })
45
- .then(function (results) { return resolve(results); }, function (error) {
46
- logger_1.logger.debug(options, 'Error while reading e2e results: ', error);
47
- warnUserOnFailure();
48
- return reject();
49
- });
50
- });
51
- };
52
- exports.default = e2e;
@@ -1,78 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- var utils_1 = require("./utils");
4
- var logger_1 = require("./logger");
5
- function findSpecIfItExists(hashes, spec) {
6
- return hashes.find(function (hash) {
7
- return hash.name.indexOf(spec) !== -1;
8
- });
9
- }
10
- function listSpecs() {
11
- return (0, utils_1.listFiles)('./{cypress,src}/**/*.@(cy|spec).ts');
12
- }
13
- function computeHash(specs) {
14
- return specs.map(function (name) {
15
- return { name: name, hash: (0, utils_1.hashFile)(name) };
16
- });
17
- }
18
- function computeHashesOfSpecs() {
19
- return listSpecs().then(function (specs) { return computeHash(specs); });
20
- }
21
- var hashChecker = function (options) {
22
- return new Promise(function (resolve, reject) {
23
- logger_1.logger.log('Checking submission...');
24
- (0, utils_1.readFile)('./exercise.json')
25
- .then(function (exerciseData) {
26
- var exercise = JSON.parse(exerciseData);
27
- logger_1.logger.success('Pack V' + exercise.pack + ' - Exercise ' + exercise.id + ' - ' + exercise.title);
28
- if (options['skip-check']) {
29
- return resolve(exercise);
30
- }
31
- return exercise;
32
- }, function (error) {
33
- logger_1.logger.error('Looks like you have no exercise.json file.');
34
- logger_1.logger.debug(options, 'An error occurred while reading exercise.json: ', error);
35
- return Promise.reject();
36
- })
37
- // then compute the hash of every spec
38
- .then(function (exercise) { return Promise.all([exercise, computeHashesOfSpecs()]); })
39
- // then decide if the submission is correct or not
40
- .then(function (_a) {
41
- var exercise = _a[0], hashes = _a[1];
42
- logger_1.logger.debug(options, 'Exercise :', JSON.stringify(exercise));
43
- logger_1.logger.debug(options, 'Hashes :', JSON.stringify(hashes));
44
- var specsInError = [];
45
- var specsNotFound = [];
46
- exercise.specs.forEach(function (file) {
47
- var spec = findSpecIfItExists(hashes, file.name);
48
- if (spec) {
49
- if (spec.hash !== file.hash) {
50
- specsInError.push(file.name);
51
- }
52
- }
53
- else {
54
- specsNotFound.push(file.name);
55
- }
56
- });
57
- if (specsInError.length !== 0 || specsNotFound.length !== 0) {
58
- if (specsInError.length !== 0) {
59
- logger_1.logger.error('It looks like you forgot to update these spec files');
60
- logger_1.logger.error('or that you modified them manually:');
61
- specsInError.forEach(function (spec) { return logger_1.logger.error(' - ' + spec); });
62
- }
63
- if (specsNotFound.length !== 0) {
64
- logger_1.logger.error('It looks like you forgot to add these spec files:');
65
- specsNotFound.forEach(function (spec) { return logger_1.logger.error(' - ' + spec); });
66
- }
67
- logger_1.logger.error('Copy the new specs and try again.');
68
- return Promise.reject();
69
- }
70
- return exercise;
71
- }, function (error) {
72
- logger_1.logger.debug(options, 'Error while computing the hash of the spec files. ', error);
73
- return Promise.reject(error);
74
- })
75
- .then(function (exercise) { return resolve(exercise); }, function (error) { return reject(error); });
76
- });
77
- };
78
- exports.default = hashChecker;
package/dist/lint.js DELETED
@@ -1,48 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- var logger_1 = require("./logger");
4
- var utils_1 = require("./utils");
5
- var RESULT_FILE = 'results/lint-results.json';
6
- var lint = function (options) {
7
- return new Promise(function (resolve, reject) {
8
- logger_1.logger.log('Starting code analysis...');
9
- return (0, utils_1.exec)("npm run lint -- --no-fix --format=json --output-file=".concat(RESULT_FILE))
10
- .then(function () { return (0, utils_1.readFile)(RESULT_FILE); },
11
- // eslint will error if there is a warning
12
- function () { return (0, utils_1.readFile)(RESULT_FILE); })
13
- .then(function (data) {
14
- if (data) {
15
- return JSON.parse(data);
16
- }
17
- return Promise.reject();
18
- }, function (error) {
19
- logger_1.logger.error('Error while running `npm run lint`.');
20
- logger_1.logger.error('Try to run `npm run lint`.');
21
- logger_1.logger.debug(options, 'Error while running lint was: ', error);
22
- reject();
23
- })
24
- .then(function (results) {
25
- if (!results) {
26
- return reject();
27
- }
28
- var lintResults = { errors: 0 };
29
- lintResults.errors = results.map(function (file) { return file.errorCount + file.warningCount; }).reduce(function (a, b) { return a + b; }, 0);
30
- if (lintResults.errors !== 0) {
31
- var score = Math.max(0, 100 - lintResults.errors);
32
- logger_1.logger.warn('Code quality score: ' + score + '%');
33
- logger_1.logger.warn('Looks like you have some issues in your code.');
34
- logger_1.logger.warn('Try to run `npm run lint` to see what you can fix.');
35
- }
36
- else {
37
- logger_1.logger.success('Code quality score: 100%');
38
- }
39
- resolve(lintResults);
40
- }, function (error) {
41
- logger_1.logger.error('Error while reading lint results.');
42
- logger_1.logger.error('Try to run `npm run lint`.');
43
- logger_1.logger.debug(options, 'Error while reading lint errors was: ', error);
44
- reject();
45
- });
46
- });
47
- };
48
- exports.default = lint;
package/dist/logger.js DELETED
@@ -1,23 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.logger = void 0;
7
- var chalk_1 = __importDefault(require("chalk"));
8
- exports.logger = {
9
- log: console.log,
10
- error: function (value) { return console.log(chalk_1.default.red(value)); },
11
- warn: function (value) { return console.log(chalk_1.default.yellow(value)); },
12
- success: function (value) { return console.log(chalk_1.default.green(value)); },
13
- debug: function (options, value, arg) {
14
- if (options.verbose) {
15
- if (arg) {
16
- console.log(chalk_1.default.gray(value), chalk_1.default.gray(arg));
17
- }
18
- else {
19
- console.log(chalk_1.default.gray(value));
20
- }
21
- }
22
- }
23
- };
package/dist/models.js DELETED
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,128 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- var logger_1 = require("./logger");
4
- var utils_1 = require("./utils");
5
- var BASE_PATH = 'https://vue-exercises.ninja-squad.com';
6
- var LOCALHOST = 'http://localhost:8080';
7
- function storeCredentials(metadata, token) {
8
- logger_1.logger.success('Authentication success');
9
- metadata.token = token;
10
- return metadata;
11
- }
12
- function login(options, loginAttempts, metadata) {
13
- // eslint-disable-next-line no-param-reassign
14
- loginAttempts = loginAttempts + 1;
15
- if (loginAttempts > 3) {
16
- logger_1.logger.error('Aborting authentication after 3 failures');
17
- return Promise.reject();
18
- }
19
- var schema = {
20
- properties: {
21
- email: {
22
- required: true
23
- },
24
- password: {
25
- hidden: true,
26
- required: true
27
- }
28
- }
29
- };
30
- return (0, utils_1.prompt)(schema)
31
- .then(function (result) { return (0, utils_1.post)("".concat(options['local-server'] ? LOCALHOST : BASE_PATH, "/api/authentications"), result); })
32
- .then(function (_a) {
33
- var response = _a.response, body = _a.body;
34
- if (response.statusCode !== 201) {
35
- logger_1.logger.error('Authentication failed, try again.');
36
- logger_1.logger.debug(options, 'Authentication request returned with status: ', JSON.stringify(response.statusCode));
37
- return login(options, loginAttempts, metadata);
38
- }
39
- logger_1.logger.debug(options, 'Authentication succeeded and we can store credentials');
40
- return storeCredentials(metadata, body.token);
41
- }, function (error) {
42
- logger_1.logger.error('Authentication failed, try again.');
43
- logger_1.logger.debug(options, 'An error occurred during authentication: ', error);
44
- return login(options, loginAttempts, metadata);
45
- });
46
- }
47
- function computeScore(metadata, results, options) {
48
- var score = 100 - results.vitest.failed * 5 - results.tslint.errors - (results.coverage.total - results.coverage.covered) - results.e2e.failed;
49
- if (score < 10) {
50
- score = 10;
51
- }
52
- if (options.local) {
53
- // if we are running locally we want to return a failure
54
- if (score !== 100) {
55
- logger_1.logger.error('Score is not perfect! ' + score + '%');
56
- (0, utils_1.exitProcessWithError)(1);
57
- }
58
- logger_1.logger.success('Exercise score: ' + score + '%');
59
- }
60
- else if (score !== 100) {
61
- logger_1.logger.warn('Score is not perfect yet: ' + score + '%');
62
- }
63
- else {
64
- logger_1.logger.success('Perfect score, congrats! ' + score + '%');
65
- }
66
- return { metadata: metadata, score: score };
67
- }
68
- function postScore(options, metadata) {
69
- var headers = { Authorization: "Bearer: ".concat(metadata.token) };
70
- var path = options['local-server'] ? LOCALHOST : BASE_PATH;
71
- var bodyToSubmit = { score: metadata.score };
72
- return (0, utils_1.post)("".concat(path, "/api/packs/").concat(metadata.pack, "/exercises/").concat(metadata.id, "/scores"), bodyToSubmit, headers).then(function (_a) {
73
- var response = _a.response, body = _a.body;
74
- // if authentication error
75
- if (response.statusCode === 401) {
76
- logger_1.logger.error('Authentication failed. Please enter your credentials again.');
77
- var loginAttempts = 0;
78
- // we try to reconnect 3 times
79
- // then submit or fail
80
- return login(options, loginAttempts, metadata).then(function (updatedMetadata) { return postScore(options, updatedMetadata); }, function (error) {
81
- logger_1.logger.error('Error while authenticating to submit results.');
82
- logger_1.logger.debug(options, 'Error was: ', error);
83
- return Promise.reject();
84
- });
85
- }
86
- else if (response.statusCode !== 201) {
87
- logger_1.logger.error('Error while sending the results.');
88
- logger_1.logger.debug(options, JSON.stringify(response.statusCode), JSON.stringify(body));
89
- return Promise.reject();
90
- }
91
- logger_1.logger.log('Score submitted.');
92
- return Promise.resolve(metadata);
93
- }, function (error) {
94
- logger_1.logger.error('Error while sending the results.');
95
- logger_1.logger.error('Maybe check your connection?');
96
- logger_1.logger.debug(options, 'Error while sending the result was: ', error);
97
- return Promise.reject();
98
- });
99
- }
100
- var submitResults = function (results, options) {
101
- return (0, utils_1.readFile)('./exercise.json')
102
- .then(function (data) { return JSON.parse(data); }, function (error) {
103
- logger_1.logger.error('Looks like you have no exercise.json file.');
104
- logger_1.logger.debug(options, 'An error occurred while reading exercise.json: ', error);
105
- return Promise.reject();
106
- })
107
- .then(function (metadata) { return computeScore(metadata, results, options); }, function (error) {
108
- logger_1.logger.error('Looks like you have an incorrect JSON in the exercise.json file.');
109
- logger_1.logger.debug(options, 'An error occurred while parsing exercise.json: ', error);
110
- return Promise.reject();
111
- })
112
- .then(function (_a) {
113
- var metadata = _a.metadata, score = _a.score;
114
- metadata.score = score;
115
- var loginAttempts = 0;
116
- if (options.local) {
117
- return metadata;
118
- }
119
- return login(options, loginAttempts, metadata);
120
- })
121
- .then(function (metadata) {
122
- if (!options.local) {
123
- return postScore(options, metadata);
124
- }
125
- return metadata;
126
- });
127
- };
128
- exports.default = submitResults;
package/dist/utils.js DELETED
@@ -1,72 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.hashFile = exports.exitProcessWithError = exports.listFiles = exports.post = exports.prompt = exports.exec = exports.readFile = void 0;
7
- var fs_1 = __importDefault(require("fs"));
8
- var crypto_1 = __importDefault(require("crypto"));
9
- var child_process_1 = __importDefault(require("child_process"));
10
- var request_1 = __importDefault(require("request"));
11
- var prompt_1 = __importDefault(require("prompt"));
12
- var util_1 = __importDefault(require("util"));
13
- var glob_1 = __importDefault(require("glob"));
14
- var logger_1 = require("./logger");
15
- var execAsync = util_1.default.promisify(child_process_1.default.exec);
16
- var readFileAsync = util_1.default.promisify(fs_1.default.readFile);
17
- var readFile = function (file) { return readFileAsync(file, 'utf8'); };
18
- exports.readFile = readFile;
19
- var exec = function (cmd) { return execAsync(cmd, { maxBuffer: 1024 * 1000 }); };
20
- exports.exec = exec;
21
- var prompt = function (schema) {
22
- return new Promise(function (resolve, reject) {
23
- prompt_1.default.start();
24
- prompt_1.default.get(schema, function (err, result) {
25
- if (err) {
26
- reject();
27
- }
28
- else {
29
- resolve(result);
30
- }
31
- });
32
- });
33
- };
34
- exports.prompt = prompt;
35
- var post = function (url, json, headers) {
36
- return new Promise(function (resolve, reject) {
37
- request_1.default.post({ url: url, json: json, headers: headers }, function (err, response, body) {
38
- if (err) {
39
- reject(err);
40
- }
41
- else {
42
- resolve({ response: response, body: body });
43
- }
44
- });
45
- });
46
- };
47
- exports.post = post;
48
- var listFiles = function (pattern) {
49
- return new Promise(function (resolve, reject) {
50
- (0, glob_1.default)(pattern, { nodir: true }, function (err, files) {
51
- if (err) {
52
- logger_1.logger.error('Could not find the spec files.');
53
- reject(err);
54
- }
55
- else {
56
- resolve(files);
57
- }
58
- });
59
- });
60
- };
61
- exports.listFiles = listFiles;
62
- var exitProcessWithError = function (code) {
63
- process.exit(code);
64
- };
65
- exports.exitProcessWithError = exitProcessWithError;
66
- var hashFile = function (name) {
67
- var fileBuffer = fs_1.default.readFileSync(name);
68
- var hashSum = crypto_1.default.createHash('sha256');
69
- hashSum.update(fileBuffer);
70
- return hashSum.digest('hex');
71
- };
72
- exports.hashFile = hashFile;
package/dist/vitest.js DELETED
@@ -1,65 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- var utils_1 = require("./utils");
4
- var logger_1 = require("./logger");
5
- var RESULT_FILE = 'results/vitest-results.json';
6
- function computeScore(vitestResults) {
7
- // eslint-disable-next-line no-undefined
8
- if (vitestResults.failed === undefined) {
9
- return 0;
10
- }
11
- var score = 100 - vitestResults.failed * 5;
12
- return score >= 0 ? score : 0;
13
- }
14
- function warnUserThatSomeTestsFailed(vitestResults) {
15
- var score = computeScore(vitestResults);
16
- logger_1.logger.warn('Unit tests score: ' + score + '%');
17
- logger_1.logger.warn('Looks like you have ' + (vitestResults.failed ? vitestResults.failed : 'a few') + ' unit test(s) failing.');
18
- logger_1.logger.warn('Launch `npm run test:unit` and try to fix them.');
19
- }
20
- function warnUserThatVitestFailed(reject) {
21
- logger_1.logger.error('Error while running unit tests.');
22
- logger_1.logger.error("Maybe your code doesn't compile?");
23
- logger_1.logger.error('Launch `npm run test:unit` to see more.');
24
- return reject();
25
- }
26
- function handleVitestResults(data, options, resolve, reject) {
27
- var results = JSON.parse(data);
28
- if (!results) {
29
- logger_1.logger.error('An error occurred during the unit tests.');
30
- logger_1.logger.error('Run `npm run test:unit` to see the problem.');
31
- return reject();
32
- }
33
- var failed = results.numFailedTests ? results.numFailedTests : results.numFailedTestSuites;
34
- var vitestResults = {
35
- failed: failed,
36
- success: results.numPassedTests
37
- };
38
- if (vitestResults.failed !== 0) {
39
- warnUserThatSomeTestsFailed(vitestResults);
40
- }
41
- else {
42
- logger_1.logger.success('Unit tests score: 100%');
43
- }
44
- return resolve(vitestResults);
45
- }
46
- var vitest = function (options) {
47
- return new Promise(function (resolve, reject) {
48
- logger_1.logger.log('Starting unit tests...');
49
- // vitest exit code is 1 if a test fails
50
- // so we'll go into the error handler even if the execution went well
51
- // and we try to read the results in both cases
52
- return ((0, utils_1.exec)("npm run test:unit:ci")
53
- .then(function () { return (0, utils_1.readFile)(RESULT_FILE); }, function (error) {
54
- logger_1.logger.debug(options, 'Vitest test failed', error);
55
- return (0, utils_1.readFile)(RESULT_FILE);
56
- })
57
- // if results, great we handle them
58
- // if not we warn the user
59
- .then(function (data) { return handleVitestResults(data, options, resolve, reject); }, function (error) {
60
- logger_1.logger.debug(options, 'An error occurred while reading vitest results: ', error);
61
- return warnUserThatVitestFailed(reject);
62
- }));
63
- });
64
- };
65
- exports.default = vitest;