@learnpack/learnpack 2.1.0 → 2.1.3
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/README.md +11 -11
- package/lib/commands/audit.d.ts +1 -1
- package/lib/commands/audit.js +48 -47
- package/lib/managers/config/defaults.d.ts +1 -0
- package/lib/managers/config/defaults.js +15 -14
- package/lib/managers/config/index.js +4 -10
- package/lib/models/config.d.ts +1 -0
- package/lib/utils/watcher.js +3 -3
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
- package/src/commands/audit.ts +463 -462
- package/src/commands/init.ts +172 -172
- package/src/managers/config/defaults.ts +34 -33
- package/src/managers/config/index.ts +4 -11
- package/src/models/config.ts +1 -0
- package/src/utils/fileQueue.ts +198 -198
- package/src/utils/templates/incremental/.learn/exercises/01-hello-world/README.es.md +24 -24
- package/src/utils/templates/incremental/.learn/exercises/01-hello-world/README.md +24 -24
- package/src/utils/watcher.ts +25 -26
    
        package/README.md
    CHANGED
    
    | @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            # learnpack
         | 
| 2 2 |  | 
| 3 | 
            -
            Create, sell or download and take learning amazing learning packages
         | 
| 3 | 
            +
            Create, sell or download and take learning amazing learning packages.
         | 
| 4 4 |  | 
| 5 5 | 
             
            [](https://oclif.io)
         | 
| 6 6 | 
             
            [](https://npmjs.org/package/learnpack)
         | 
| @@ -21,7 +21,7 @@ $ npm install -g @learnpack/learnpack | |
| 21 21 | 
             
            $ learnpack COMMAND
         | 
| 22 22 | 
             
            running command...
         | 
| 23 23 | 
             
            $ learnpack (-v|--version|version)
         | 
| 24 | 
            -
            @learnpack/learnpack/2.1. | 
| 24 | 
            +
            @learnpack/learnpack/2.1.3 win32-x64 node-v16.14.0
         | 
| 25 25 | 
             
            $ learnpack --help [COMMAND]
         | 
| 26 26 | 
             
            USAGE
         | 
| 27 27 | 
             
              $ learnpack COMMAND
         | 
| @@ -74,7 +74,7 @@ DESCRIPTION | |
| 74 74 | 
             
                   12. If there is a file within the exercises folder but not inside of any particular exercise's folder. (Warning)
         | 
| 75 75 | 
             
            ```
         | 
| 76 76 |  | 
| 77 | 
            -
            _See code: [src\commands\audit.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1. | 
| 77 | 
            +
            _See code: [src\commands\audit.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.3/src\commands\audit.ts)_
         | 
| 78 78 |  | 
| 79 79 | 
             
            ## `learnpack clean`
         | 
| 80 80 |  | 
| @@ -89,7 +89,7 @@ DESCRIPTION | |
| 89 89 | 
             
                 Extra documentation goes here
         | 
| 90 90 | 
             
            ```
         | 
| 91 91 |  | 
| 92 | 
            -
            _See code: [src\commands\clean.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1. | 
| 92 | 
            +
            _See code: [src\commands\clean.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.3/src\commands\clean.ts)_
         | 
| 93 93 |  | 
| 94 94 | 
             
            ## `learnpack download [PACKAGE]`
         | 
| 95 95 |  | 
| @@ -107,7 +107,7 @@ DESCRIPTION | |
| 107 107 | 
             
              Extra documentation goes here
         | 
| 108 108 | 
             
            ```
         | 
| 109 109 |  | 
| 110 | 
            -
            _See code: [src\commands\download.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1. | 
| 110 | 
            +
            _See code: [src\commands\download.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.3/src\commands\download.ts)_
         | 
| 111 111 |  | 
| 112 112 | 
             
            ## `learnpack help [COMMAND]`
         | 
| 113 113 |  | 
| @@ -138,7 +138,7 @@ OPTIONS | |
| 138 138 | 
             
              -h, --grading  show CLI help
         | 
| 139 139 | 
             
            ```
         | 
| 140 140 |  | 
| 141 | 
            -
            _See code: [src\commands\init.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1. | 
| 141 | 
            +
            _See code: [src\commands\init.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.3/src\commands\init.ts)_
         | 
| 142 142 |  | 
| 143 143 | 
             
            ## `learnpack login [PACKAGE]`
         | 
| 144 144 |  | 
| @@ -156,7 +156,7 @@ DESCRIPTION | |
| 156 156 | 
             
                 Extra documentation goes here
         | 
| 157 157 | 
             
            ```
         | 
| 158 158 |  | 
| 159 | 
            -
            _See code: [src\commands\login.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1. | 
| 159 | 
            +
            _See code: [src\commands\login.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.3/src\commands\login.ts)_
         | 
| 160 160 |  | 
| 161 161 | 
             
            ## `learnpack logout [PACKAGE]`
         | 
| 162 162 |  | 
| @@ -174,7 +174,7 @@ DESCRIPTION | |
| 174 174 | 
             
                 Extra documentation goes here
         | 
| 175 175 | 
             
            ```
         | 
| 176 176 |  | 
| 177 | 
            -
            _See code: [src\commands\logout.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1. | 
| 177 | 
            +
            _See code: [src\commands\logout.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.3/src\commands\logout.ts)_
         | 
| 178 178 |  | 
| 179 179 | 
             
            ## `learnpack plugins`
         | 
| 180 180 |  | 
| @@ -309,7 +309,7 @@ DESCRIPTION | |
| 309 309 | 
             
                 Extra documentation goes here
         | 
| 310 310 | 
             
            ```
         | 
| 311 311 |  | 
| 312 | 
            -
            _See code: [src\commands\publish.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1. | 
| 312 | 
            +
            _See code: [src\commands\publish.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.3/src\commands\publish.ts)_
         | 
| 313 313 |  | 
| 314 314 | 
             
            ## `learnpack start`
         | 
| 315 315 |  | 
| @@ -330,7 +330,7 @@ OPTIONS | |
| 330 330 | 
             
              -w, --watch                         Watch for file changes
         | 
| 331 331 | 
             
            ```
         | 
| 332 332 |  | 
| 333 | 
            -
            _See code: [src\commands\start.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1. | 
| 333 | 
            +
            _See code: [src\commands\start.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.3/src\commands\start.ts)_
         | 
| 334 334 |  | 
| 335 335 | 
             
            ## `learnpack test [EXERCISESLUG]`
         | 
| 336 336 |  | 
| @@ -344,5 +344,5 @@ ARGUMENTS | |
| 344 344 | 
             
              EXERCISESLUG  The name of the exercise to test
         | 
| 345 345 | 
             
            ```
         | 
| 346 346 |  | 
| 347 | 
            -
            _See code: [src\commands\test.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1. | 
| 347 | 
            +
            _See code: [src\commands\test.ts](https://github.com/learnpack/learnpack-cli/blob/v2.1.3/src\commands\test.ts)_
         | 
| 348 348 | 
             
            <!-- commandsstop -->
         | 
    
        package/lib/commands/audit.d.ts
    CHANGED
    
    
    
        package/lib/commands/audit.js
    CHANGED
    
    | @@ -17,7 +17,7 @@ class AuditCommand extends SessionCommand_1.default { | |
| 17 17 | 
             
                }
         | 
| 18 18 | 
             
                async run() {
         | 
| 19 19 | 
             
                    var _a, _b, _c, _d, _e, _f, _g;
         | 
| 20 | 
            -
                    console_1.default.log( | 
| 20 | 
            +
                    console_1.default.log("Running command audit...");
         | 
| 21 21 | 
             
                    // Get configuration object.
         | 
| 22 22 | 
             
                    let config = (_a = this.configManager) === null || _a === void 0 ? void 0 : _a.get();
         | 
| 23 23 | 
             
                    if (config) {
         | 
| @@ -46,7 +46,7 @@ class AuditCommand extends SessionCommand_1.default { | |
| 46 46 | 
             
                        const exercisesPath = config.config.exercisesPath;
         | 
| 47 47 | 
             
                        fs.readdir(exercisesPath, (err, files) => {
         | 
| 48 48 | 
             
                            if (err) {
         | 
| 49 | 
            -
                                return console.log( | 
| 49 | 
            +
                                return console.log("Unable to scan directory: " + err);
         | 
| 50 50 | 
             
                            }
         | 
| 51 51 | 
             
                            // listing all files using forEach
         | 
| 52 52 | 
             
                            for (const file of files) {
         | 
| @@ -55,7 +55,7 @@ class AuditCommand extends SessionCommand_1.default { | |
| 55 55 | 
             
                                if (fs.statSync(filePath).isFile())
         | 
| 56 56 | 
             
                                    warnings.push({
         | 
| 57 57 | 
             
                                        exercise: file,
         | 
| 58 | 
            -
                                        msg:  | 
| 58 | 
            +
                                        msg: "This file is not inside any exercise folder.",
         | 
| 59 59 | 
             
                                    });
         | 
| 60 60 | 
             
                            }
         | 
| 61 61 | 
             
                        });
         | 
| @@ -74,12 +74,12 @@ class AuditCommand extends SessionCommand_1.default { | |
| 74 74 | 
             
                            const frontmatter = fm(content);
         | 
| 75 75 | 
             
                            for (const attribute in frontmatter.attributes) {
         | 
| 76 76 | 
             
                                if (Object.prototype.hasOwnProperty.call(frontmatter.attributes, attribute) &&
         | 
| 77 | 
            -
                                    (attribute ===  | 
| 77 | 
            +
                                    (attribute === "intro" || attribute === "tutorial")) {
         | 
| 78 78 | 
             
                                    counter.links.total++;
         | 
| 79 79 | 
             
                                    try {
         | 
| 80 80 | 
             
                                        // eslint-disable-next-line
         | 
| 81 81 | 
             
                                        let res = await fetch(frontmatter.attributes[attribute], {
         | 
| 82 | 
            -
                                            method:  | 
| 82 | 
            +
                                            method: "HEAD",
         | 
| 83 83 | 
             
                                        });
         | 
| 84 84 | 
             
                                        if (!res.ok) {
         | 
| 85 85 | 
             
                                            counter.links.error++;
         | 
| @@ -99,20 +99,20 @@ class AuditCommand extends SessionCommand_1.default { | |
| 99 99 | 
             
                                }
         | 
| 100 100 | 
             
                            }
         | 
| 101 101 | 
             
                            // Check url's of each README file.
         | 
| 102 | 
            -
                            const findings = audit_1.default.findInFile([ | 
| 102 | 
            +
                            const findings = audit_1.default.findInFile(["relativeImages", "externalImages", "markdownLinks"], content);
         | 
| 103 103 | 
             
                            for (const finding in findings) {
         | 
| 104 104 | 
             
                                if (Object.prototype.hasOwnProperty.call(findings, finding)) {
         | 
| 105 105 | 
             
                                    const obj = findings[finding];
         | 
| 106 106 | 
             
                                    // Valdites all the relative path images.
         | 
| 107 | 
            -
                                    if (finding ===  | 
| 107 | 
            +
                                    if (finding === "relativeImages" && Object.keys(obj).length > 0) {
         | 
| 108 108 | 
             
                                        for (const img in obj) {
         | 
| 109 109 | 
             
                                            if (Object.prototype.hasOwnProperty.call(obj, img)) {
         | 
| 110 110 | 
             
                                                // Validates if the image is in the assets folder.
         | 
| 111 111 | 
             
                                                counter.images.total++;
         | 
| 112 112 | 
             
                                                const relativePath = path
         | 
| 113 | 
            -
                                                    .relative(exercise.path.replace(/\\/gm,  | 
| 114 | 
            -
                                                    .replace(/\\/gm,  | 
| 115 | 
            -
                                                if (relativePath !== obj[img].absUrl.split( | 
| 113 | 
            +
                                                    .relative(exercise.path.replace(/\\/gm, "/"), `${(_a = config.config) === null || _a === void 0 ? void 0 : _a.dirPath}/assets/${obj[img].relUrl}`)
         | 
| 114 | 
            +
                                                    .replace(/\\/gm, "/");
         | 
| 115 | 
            +
                                                if (relativePath !== obj[img].absUrl.split("?").shift()) {
         | 
| 116 116 | 
             
                                                    counter.images.error++;
         | 
| 117 117 | 
             
                                                    errors.push({
         | 
| 118 118 | 
             
                                                        exercise: exercise.title,
         | 
| @@ -129,18 +129,18 @@ class AuditCommand extends SessionCommand_1.default { | |
| 129 129 | 
             
                                            }
         | 
| 130 130 | 
             
                                        }
         | 
| 131 131 | 
             
                                    }
         | 
| 132 | 
            -
                                    else if (finding ===  | 
| 132 | 
            +
                                    else if (finding === "externalImages" &&
         | 
| 133 133 | 
             
                                        Object.keys(obj).length > 0) {
         | 
| 134 134 | 
             
                                        // Valdites all the aboslute path images.
         | 
| 135 135 | 
             
                                        for (const img in obj) {
         | 
| 136 136 | 
             
                                            if (Object.prototype.hasOwnProperty.call(obj, img)) {
         | 
| 137 137 | 
             
                                                counter.images.total++;
         | 
| 138 138 | 
             
                                                if (fs.existsSync(`${(_c = config.config) === null || _c === void 0 ? void 0 : _c.dirPath}/assets${obj[img].mdUrl
         | 
| 139 | 
            -
                                                    .split( | 
| 139 | 
            +
                                                    .split("?")
         | 
| 140 140 | 
             
                                                    .shift()}`)) {
         | 
| 141 141 | 
             
                                                    const relativePath = path
         | 
| 142 | 
            -
                                                        .relative(exercise.path.replace(/\\/gm,  | 
| 143 | 
            -
                                                        .replace(/\\/gm,  | 
| 142 | 
            +
                                                        .relative(exercise.path.replace(/\\/gm, "/"), `${(_d = config.config) === null || _d === void 0 ? void 0 : _d.dirPath}/assets/${obj[img].mdUrl}`)
         | 
| 143 | 
            +
                                                        .replace(/\\/gm, "/");
         | 
| 144 144 | 
             
                                                    warnings.push({
         | 
| 145 145 | 
             
                                                        exercise: exercise.title,
         | 
| 146 146 | 
             
                                                        msg: `On this exercise you have an image with an absolute path "${obj[img].absUrl}". We recommend you to replace it by the relative path: "${relativePath}".`,
         | 
| @@ -167,7 +167,7 @@ class AuditCommand extends SessionCommand_1.default { | |
| 167 167 | 
             
                                            }
         | 
| 168 168 | 
             
                                        }
         | 
| 169 169 | 
             
                                    }
         | 
| 170 | 
            -
                                    else if (finding ===  | 
| 170 | 
            +
                                    else if (finding === "markdownLinks" &&
         | 
| 171 171 | 
             
                                        Object.keys(obj).length > 0) {
         | 
| 172 172 | 
             
                                        for (const link in obj) {
         | 
| 173 173 | 
             
                                            if (Object.prototype.hasOwnProperty.call(obj, link)) {
         | 
| @@ -175,6 +175,7 @@ class AuditCommand extends SessionCommand_1.default { | |
| 175 175 | 
             
                                                try {
         | 
| 176 176 | 
             
                                                    // eslint-disable-next-line
         | 
| 177 177 | 
             
                                                    let res = await fetch(obj[link].mdUrl, { method: "HEAD" });
         | 
| 178 | 
            +
                                                    console_1.default.log("Response links:", obj[link].mdUrl, res);
         | 
| 178 179 | 
             
                                                    if (res.status > 399 && res.status < 500) {
         | 
| 179 180 | 
             
                                                        counter.links.error++;
         | 
| 180 181 | 
             
                                                        errors.push({
         | 
| @@ -205,38 +206,38 @@ class AuditCommand extends SessionCommand_1.default { | |
| 205 206 | 
             
                            }
         | 
| 206 207 | 
             
                            return false;
         | 
| 207 208 | 
             
                        };
         | 
| 208 | 
            -
                        console_1.default.debug( | 
| 209 | 
            -
                        console_1.default.info( | 
| 209 | 
            +
                        console_1.default.debug("config", config);
         | 
| 210 | 
            +
                        console_1.default.info(" Checking if the config file is fine...");
         | 
| 210 211 | 
             
                        // These two lines check if the 'slug' property is inside the configuration object.
         | 
| 211 | 
            -
                        console_1.default.debug( | 
| 212 | 
            +
                        console_1.default.debug("Checking if the slug property is inside the configuration object...");
         | 
| 212 213 | 
             
                        if (!((_d = config.config) === null || _d === void 0 ? void 0 : _d.slug))
         | 
| 213 214 | 
             
                            errors.push({
         | 
| 214 215 | 
             
                                exercise: undefined,
         | 
| 215 | 
            -
                                msg:  | 
| 216 | 
            +
                                msg: "The slug property is not in the configuration object",
         | 
| 216 217 | 
             
                            });
         | 
| 217 218 | 
             
                        // These two lines check if the 'repository' property is inside the configuration object.
         | 
| 218 | 
            -
                        console_1.default.debug( | 
| 219 | 
            +
                        console_1.default.debug("Checking if the repository property is inside the configuration object...");
         | 
| 219 220 | 
             
                        if (!((_e = config.config) === null || _e === void 0 ? void 0 : _e.repository))
         | 
| 220 221 | 
             
                            errors.push({
         | 
| 221 222 | 
             
                                exercise: undefined,
         | 
| 222 | 
            -
                                msg:  | 
| 223 | 
            +
                                msg: "The repository property is not in the configuration object",
         | 
| 223 224 | 
             
                            });
         | 
| 224 225 | 
             
                        else
         | 
| 225 226 | 
             
                            audit_1.default.isUrl((_f = config.config) === null || _f === void 0 ? void 0 : _f.repository, errors, counter);
         | 
| 226 227 | 
             
                        // These two lines check if the 'description' property is inside the configuration object.
         | 
| 227 | 
            -
                        console_1.default.debug( | 
| 228 | 
            +
                        console_1.default.debug("Checking if the description property is inside the configuration object...");
         | 
| 228 229 | 
             
                        if (!((_g = config.config) === null || _g === void 0 ? void 0 : _g.description))
         | 
| 229 230 | 
             
                            errors.push({
         | 
| 230 231 | 
             
                                exercise: undefined,
         | 
| 231 | 
            -
                                msg:  | 
| 232 | 
            +
                                msg: "The description property is not in the configuration object",
         | 
| 232 233 | 
             
                            });
         | 
| 233 234 | 
             
                        if (errors.length === 0)
         | 
| 234 | 
            -
                            console_1.default.log( | 
| 235 | 
            +
                            console_1.default.log("The config file is ok");
         | 
| 235 236 | 
             
                        // Validates if images and links are working at every README file.
         | 
| 236 237 | 
             
                        const exercises = config.exercises;
         | 
| 237 238 | 
             
                        const readmeFiles = [];
         | 
| 238 239 | 
             
                        if (exercises && exercises.length > 0) {
         | 
| 239 | 
            -
                            console_1.default.info( | 
| 240 | 
            +
                            console_1.default.info(" Checking if the images are working...");
         | 
| 240 241 | 
             
                            for (const index in exercises) {
         | 
| 241 242 | 
             
                                if (Object.prototype.hasOwnProperty.call(exercises, index)) {
         | 
| 242 243 | 
             
                                    const exercise = exercises[index];
         | 
| @@ -251,10 +252,10 @@ class AuditCommand extends SessionCommand_1.default { | |
| 251 252 | 
             
                                            exercise: exercise.title,
         | 
| 252 253 | 
             
                                            msg: `The exercise ${exercise.title} doesn't have a README.md file.`,
         | 
| 253 254 | 
             
                                        });
         | 
| 254 | 
            -
                                    if (exercise.language ===  | 
| 255 | 
            -
                                        exercise.language ===  | 
| 255 | 
            +
                                    if (exercise.language === "python3" ||
         | 
| 256 | 
            +
                                        exercise.language === "python") {
         | 
| 256 257 | 
             
                                        for (const f of exercise.files.map(f => f)) {
         | 
| 257 | 
            -
                                            if (f.path.includes( | 
| 258 | 
            +
                                            if (f.path.includes("test.py") || f.path.includes("tests.py")) {
         | 
| 258 259 | 
             
                                                const content = fs.readFileSync(f.path).toString();
         | 
| 259 260 | 
             
                                                const isEmpty = audit_1.default.checkForEmptySpaces(content);
         | 
| 260 261 | 
             
                                                if (isEmpty || !content)
         | 
| @@ -267,7 +268,7 @@ class AuditCommand extends SessionCommand_1.default { | |
| 267 268 | 
             
                                    }
         | 
| 268 269 | 
             
                                    else {
         | 
| 269 270 | 
             
                                        for (const f of exercise.files.map(f => f)) {
         | 
| 270 | 
            -
                                            if (f.path.includes( | 
| 271 | 
            +
                                            if (f.path.includes("test.js") || f.path.includes("tests.js")) {
         | 
| 271 272 | 
             
                                                const content = fs.readFileSync(f.path).toString();
         | 
| 272 273 | 
             
                                                const isEmpty = audit_1.default.checkForEmptySpaces(content);
         | 
| 273 274 | 
             
                                                if (isEmpty || !content)
         | 
| @@ -308,7 +309,7 @@ class AuditCommand extends SessionCommand_1.default { | |
| 308 309 | 
             
                        else
         | 
| 309 310 | 
             
                            errors.push({
         | 
| 310 311 | 
             
                                exercise: undefined,
         | 
| 311 | 
            -
                                msg:  | 
| 312 | 
            +
                                msg: "The exercises array is empty.",
         | 
| 312 313 | 
             
                            });
         | 
| 313 314 | 
             
                        console_1.default.log(`${counter.images.total - counter.images.error} images ok from ${counter.images.total}`);
         | 
| 314 315 | 
             
                        console_1.default.info(" Checking if important files are missing... (README's, translations, gitignore...)");
         | 
| @@ -324,7 +325,7 @@ class AuditCommand extends SessionCommand_1.default { | |
| 324 325 | 
             
                                files.push(` ${item.exercise}`);
         | 
| 325 326 | 
             
                        }
         | 
| 326 327 | 
             
                        if (files.length > 0) {
         | 
| 327 | 
            -
                            const filesString = files.join( | 
| 328 | 
            +
                            const filesString = files.join(",");
         | 
| 328 329 | 
             
                            warnings.push({
         | 
| 329 330 | 
             
                                exercise: undefined,
         | 
| 330 331 | 
             
                                msg: files.length === 1 ?
         | 
| @@ -333,7 +334,7 @@ class AuditCommand extends SessionCommand_1.default { | |
| 333 334 | 
             
                            });
         | 
| 334 335 | 
             
                        }
         | 
| 335 336 | 
             
                        // Checks if the .gitignore file exists.
         | 
| 336 | 
            -
                        if (!fs.existsSync( | 
| 337 | 
            +
                        if (!fs.existsSync(".gitignore"))
         | 
| 337 338 | 
             
                            warnings.push({
         | 
| 338 339 | 
             
                                exercise: undefined,
         | 
| 339 340 | 
             
                                msg: ".gitignore file doesn't exist",
         | 
| @@ -347,21 +348,21 @@ class AuditCommand extends SessionCommand_1.default { | |
| 347 348 | 
             
                    }
         | 
| 348 349 | 
             
                }
         | 
| 349 350 | 
             
            }
         | 
| 350 | 
            -
            AuditCommand.description = `learnpack audit is the command in charge of creating an auditory of the repository
         | 
| 351 | 
            -
            ...
         | 
| 352 | 
            -
            learnpack audit checks for the following information in a repository:
         | 
| 353 | 
            -
                1. The configuration object has slug, repository and description. (Error)
         | 
| 354 | 
            -
                2. The command learnpack clean has been run. (Error)
         | 
| 355 | 
            -
                3. If a markdown or test file doesn't have any content. (Error)
         | 
| 356 | 
            -
                4. The links are accessing to valid servers. (Error)
         | 
| 357 | 
            -
                5. The relative images are working (If they have the shortest path to the image or if the images exists in the assets). (Error)
         | 
| 358 | 
            -
                6. The external images are working (If they are pointing to a valid server). (Error)
         | 
| 359 | 
            -
                7. The exercises directory names are valid. (Error)
         | 
| 360 | 
            -
                8. If an exercise doesn't have a README file. (Error)
         | 
| 361 | 
            -
                9. The exercises array (Of the config file) has content. (Error)
         | 
| 362 | 
            -
                10. The exercses have the same translations. (Warning)
         | 
| 363 | 
            -
                11. The .gitignore file exists. (Warning)
         | 
| 364 | 
            -
                12. If there is a file within the exercises folder but not inside of any particular exercise's folder. (Warning)
         | 
| 351 | 
            +
            AuditCommand.description = `learnpack audit is the command in charge of creating an auditory of the repository
         | 
| 352 | 
            +
            ...
         | 
| 353 | 
            +
            learnpack audit checks for the following information in a repository:
         | 
| 354 | 
            +
                1. The configuration object has slug, repository and description. (Error)
         | 
| 355 | 
            +
                2. The command learnpack clean has been run. (Error)
         | 
| 356 | 
            +
                3. If a markdown or test file doesn't have any content. (Error)
         | 
| 357 | 
            +
                4. The links are accessing to valid servers. (Error)
         | 
| 358 | 
            +
                5. The relative images are working (If they have the shortest path to the image or if the images exists in the assets). (Error)
         | 
| 359 | 
            +
                6. The external images are working (If they are pointing to a valid server). (Error)
         | 
| 360 | 
            +
                7. The exercises directory names are valid. (Error)
         | 
| 361 | 
            +
                8. If an exercise doesn't have a README file. (Error)
         | 
| 362 | 
            +
                9. The exercises array (Of the config file) has content. (Error)
         | 
| 363 | 
            +
                10. The exercses have the same translations. (Warning)
         | 
| 364 | 
            +
                11. The .gitignore file exists. (Warning)
         | 
| 365 | 
            +
                12. If there is a file within the exercises folder but not inside of any particular exercise's folder. (Warning)
         | 
| 365 366 | 
             
            `;
         | 
| 366 367 | 
             
            AuditCommand.flags = {
         | 
| 367 368 | 
             
            // name: flags.string({char: 'n', description: 'name to print'}),
         | 
| @@ -8,28 +8,29 @@ exports.default = { | |
| 8 8 | 
             
                        agent: null,
         | 
| 9 9 | 
             
                        version: null,
         | 
| 10 10 | 
             
                    },
         | 
| 11 | 
            -
                    dirPath:  | 
| 12 | 
            -
                    configPath:  | 
| 13 | 
            -
                    outputPath:  | 
| 14 | 
            -
                    publicPath:  | 
| 11 | 
            +
                    dirPath: "./.learn",
         | 
| 12 | 
            +
                    configPath: "./learn.json",
         | 
| 13 | 
            +
                    outputPath: "./.learn/dist",
         | 
| 14 | 
            +
                    publicPath: "/preview",
         | 
| 15 15 | 
             
                    publicUrl: null,
         | 
| 16 | 
            -
                    language:  | 
| 17 | 
            -
                     | 
| 18 | 
            -
                     | 
| 16 | 
            +
                    language: "auto",
         | 
| 17 | 
            +
                    autoPlay: true,
         | 
| 18 | 
            +
                    grading: "isolated",
         | 
| 19 | 
            +
                    exercisesPath: "./",
         | 
| 19 20 | 
             
                    webpackTemplate: null,
         | 
| 20 21 | 
             
                    disableGrading: false,
         | 
| 21 22 | 
             
                    disabledActions: [],
         | 
| 22 23 | 
             
                    actions: [],
         | 
| 23 24 | 
             
                    entries: {
         | 
| 24 | 
            -
                        html:  | 
| 25 | 
            -
                        vanillajs:  | 
| 26 | 
            -
                        react:  | 
| 27 | 
            -
                        node:  | 
| 28 | 
            -
                        python3:  | 
| 29 | 
            -
                        java:  | 
| 25 | 
            +
                        html: "index.html",
         | 
| 26 | 
            +
                        vanillajs: "index.js",
         | 
| 27 | 
            +
                        react: "app.jsx",
         | 
| 28 | 
            +
                        node: "app.js",
         | 
| 29 | 
            +
                        python3: "app.py",
         | 
| 30 | 
            +
                        java: "app.java",
         | 
| 30 31 | 
             
                    },
         | 
| 31 32 | 
             
                },
         | 
| 32 | 
            -
                address:  | 
| 33 | 
            +
                address: "http://localhost",
         | 
| 33 34 | 
             
                currentExercise: null,
         | 
| 34 35 | 
             
                exercises: [],
         | 
| 35 36 | 
             
            };
         | 
| @@ -16,12 +16,7 @@ const fetch = require("node-fetch"); | |
| 16 16 | 
             
            const chalk = require("chalk");
         | 
| 17 17 | 
             
            /* exercise folder name standard */
         | 
| 18 18 | 
             
            const getConfigPath = () => {
         | 
| 19 | 
            -
                const possibleFileNames = [
         | 
| 20 | 
            -
                    "learn.json",
         | 
| 21 | 
            -
                    ".learn/learn.json",
         | 
| 22 | 
            -
                    "bc.json",
         | 
| 23 | 
            -
                    ".breathecode/bc.json",
         | 
| 24 | 
            -
                ];
         | 
| 19 | 
            +
                const possibleFileNames = ["learn.json", ".learn/learn.json"];
         | 
| 25 20 | 
             
                const config = possibleFileNames.find(file => fs.existsSync(file)) || null;
         | 
| 26 21 | 
             
                if (config && fs.existsSync(".breathecode"))
         | 
| 27 22 | 
             
                    return { config, base: ".breathecode" };
         | 
| @@ -91,7 +86,6 @@ exports.default = async ({ grading, mode, disableGrading, version, }) => { | |
| 91 86 | 
             
                        [] }));
         | 
| 92 87 | 
             
                // auto detect agent (if possible)
         | 
| 93 88 | 
             
                if (shell.which("gp") && configObj && configObj.config) {
         | 
| 94 | 
            -
                    configObj.config.editor.agent = "gitpod";
         | 
| 95 89 | 
             
                    configObj.address = getGitpodAddress();
         | 
| 96 90 | 
             
                    configObj.config.publicUrl = `https://${configObj.config.port}-${(_b = configObj.address) === null || _b === void 0 ? void 0 : _b.slice(8)}`;
         | 
| 97 91 | 
             
                }
         | 
| @@ -101,8 +95,8 @@ exports.default = async ({ grading, mode, disableGrading, version, }) => { | |
| 101 95 | 
             
                if (configObj.config && !configObj.config.publicUrl)
         | 
| 102 96 | 
             
                    configObj.config.publicUrl = `${configObj.address}:${configObj.config.port}`;
         | 
| 103 97 | 
             
                // Assign default editor mode if not set already
         | 
| 104 | 
            -
                if (configObj.config && mode | 
| 105 | 
            -
                    configObj.config.editor.mode = mode | 
| 98 | 
            +
                if (configObj.config && !mode) {
         | 
| 99 | 
            +
                    configObj.config.editor.mode = mode;
         | 
| 106 100 | 
             
                }
         | 
| 107 101 | 
             
                if (configObj.config && !configObj.config.editor.mode)
         | 
| 108 102 | 
             
                    configObj.config.editor.mode =
         | 
| @@ -113,7 +107,7 @@ exports.default = async ({ grading, mode, disableGrading, version, }) => { | |
| 113 107 | 
             
                    console_1.default.debug("Config version not found, downloading default.");
         | 
| 114 108 | 
             
                    const resp = await fetch("https://raw.githubusercontent.com/learnpack/coding-ide/learnpack/package.json");
         | 
| 115 109 | 
             
                    const packageJSON = await resp.json();
         | 
| 116 | 
            -
                    configObj.config.editor.version = packageJSON.version || "1.0. | 
| 110 | 
            +
                    configObj.config.editor.version = packageJSON.version || "1.0.73";
         | 
| 117 111 | 
             
                }
         | 
| 118 112 | 
             
                if (configObj.config) {
         | 
| 119 113 | 
             
                    configObj.config.dirPath = "./" + confPath.base;
         | 
    
        package/lib/models/config.d.ts
    CHANGED
    
    
    
        package/lib/utils/watcher.js
    CHANGED
    
    | @@ -1,13 +1,13 @@ | |
| 1 1 | 
             
            "use strict";
         | 
| 2 2 | 
             
            Object.defineProperty(exports, "__esModule", { value: true });
         | 
| 3 3 | 
             
            const chokidar = require("chokidar");
         | 
| 4 | 
            +
            const console_1 = require("./console");
         | 
| 4 5 | 
             
            const debounce = require("debounce");
         | 
| 5 6 | 
             
            exports.default = (path, reloadSocket) => new Promise((resolve /* , reject */) => {
         | 
| 7 | 
            +
                console_1.default.debug("PATH:", path);
         | 
| 6 8 | 
             
                const watcher = chokidar.watch(path, {
         | 
| 7 9 | 
             
                    // TODO: This watcher is not ready yet
         | 
| 8 | 
            -
                     | 
| 9 | 
            -
                    //   return new RegExp(_path)
         | 
| 10 | 
            -
                    // },
         | 
| 10 | 
            +
                    ignored: /^(?=.*(\.\w+)$)(?!.*\.md$).*$/gm,
         | 
| 11 11 | 
             
                    ignoreInitial: true,
         | 
| 12 12 | 
             
                });
         | 
| 13 13 | 
             
                const onChange = (eventname, _filename) => {
         | 
    
        package/oclif.manifest.json
    CHANGED
    
    | @@ -1 +1 @@ | |
| 1 | 
            -
            {"version":"2.1. | 
| 1 | 
            +
            {"version":"2.1.3","commands":{"audit":{"id":"audit","description":"learnpack audit is the command in charge of creating an auditory of the repository\n...\nlearnpack audit checks for the following information in a repository:\n    1. The configuration object has slug, repository and description. (Error)\n    2. The command learnpack clean has been run. (Error)\n    3. If a markdown or test file doesn't have any content. (Error)\n    4. The links are accessing to valid servers. (Error)\n    5. The relative images are working (If they have the shortest path to the image or if the images exists in the assets). (Error)\n    6. The external images are working (If they are pointing to a valid server). (Error)\n    7. The exercises directory names are valid. (Error)\n    8. If an exercise doesn't have a README file. (Error)\n    9. The exercises array (Of the config file) has content. (Error)\n    10. The exercses have the same translations. (Warning)\n    11. The .gitignore file exists. (Warning)\n    12. If there is a file within the exercises folder but not inside of any particular exercise's folder. (Warning)\n","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[]},"clean":{"id":"clean","description":"Clean the configuration object\n  ...\n  Extra documentation goes here\n  ","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[]},"download":{"id":"download","description":"Describe the command here\n...\nExtra documentation goes here\n","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"package","description":"The unique string that identifies this package on learnpack","required":false,"hidden":false}]},"init":{"id":"init","description":"Create a new learning package: Book, Tutorial or Exercise","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"grading":{"name":"grading","type":"boolean","char":"h","description":"show CLI help","allowNo":false}},"args":[]},"login":{"id":"login","description":"Describe the command here\n  ...\n  Extra documentation goes here\n  ","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"package","description":"The unique string that identifies this package on learnpack","required":false,"hidden":false}]},"logout":{"id":"logout","description":"Describe the command here\n  ...\n  Extra documentation goes here\n  ","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"package","description":"The unique string that identifies this package on learnpack","required":false,"hidden":false}]},"publish":{"id":"publish","description":"Describe the command here\n  ...\n  Extra documentation goes here\n  ","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"package","description":"The unique string that identifies this package on learnpack","required":false,"hidden":false}]},"start":{"id":"start","description":"Runs a small server with all the exercise instructions","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{"port":{"name":"port","type":"option","char":"p","description":"server port"},"host":{"name":"host","type":"option","char":"h","description":"server host"},"disableGrading":{"name":"disableGrading","type":"boolean","char":"D","description":"disble grading functionality","allowNo":false},"watch":{"name":"watch","type":"boolean","char":"w","description":"Watch for file changes","allowNo":false},"editor":{"name":"editor","type":"option","char":"e","description":"[standalone, gitpod]","options":["standalone","gitpod"]},"version":{"name":"version","type":"option","char":"v","description":"E.g: 1.0.1"},"grading":{"name":"grading","type":"option","char":"g","description":"[isolated, incremental]","options":["isolated","incremental"]},"debug":{"name":"debug","type":"boolean","char":"d","description":"debugger mode for more verbage","allowNo":false}},"args":[]},"test":{"id":"test","description":"Test exercises","pluginName":"@learnpack/learnpack","pluginType":"core","aliases":[],"flags":{},"args":[{"name":"exerciseSlug","description":"The name of the exercise to test","required":false,"hidden":false}]}}}
         | 
    
        package/package.json
    CHANGED