@procamp/cli 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ #! /usr/bin/env node
2
+ import { Command } from 'commander';
3
+ export declare const program: Command;
@@ -0,0 +1,51 @@
1
+ #! /usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.program = void 0;
5
+ const commander_1 = require("commander");
6
+ const generate_1 = require("../command/generate");
7
+ const init_1 = require("../command/init");
8
+ const login_1 = require("../command/login");
9
+ const new_1 = require("../command/new");
10
+ const pack_1 = require("../command/pack");
11
+ const publish_1 = require("../command/publish");
12
+ const validate_1 = require("../command/validate");
13
+ const error_1 = require("../utils/error");
14
+ const { version, name, description } = require('../../package.json');
15
+ exports.program = new commander_1.Command();
16
+ exports.program.name(name).version(version).description(description);
17
+ exports.program
18
+ .command('init')
19
+ .description('Initialise project configuration ')
20
+ .option('-d, --directory <directory>', 'Directory to initialise project', process.cwd())
21
+ .action(init_1.initCourse);
22
+ exports.program
23
+ .command('new <projectName>')
24
+ .description('Generate course project')
25
+ .action(new_1.createCourse);
26
+ exports.program
27
+ .command('pack')
28
+ .description('Compress files')
29
+ .option('-d, --directory <directory>', 'Directory to compress', process.cwd())
30
+ .action(pack_1.zipCourse);
31
+ exports.program
32
+ .command('publish')
33
+ .description('Publish file to service')
34
+ .action(publish_1.publishCourse);
35
+ exports.program
36
+ .command('validate')
37
+ .description('Validate course folder structure')
38
+ .action(validate_1.validate);
39
+ exports.program
40
+ .command('generate course')
41
+ .alias('g')
42
+ .description('Generating Course with blueprint.yml')
43
+ .action(generate_1.generateCourse);
44
+ exports.program.command('login').description('Login to procamp').action(login_1.login);
45
+ exports.program.on('command:*', ([command]) => {
46
+ (0, error_1.error)(`Erreur : commande "${command}" inconnue`);
47
+ exports.program.help();
48
+ process.exit(1);
49
+ });
50
+ exports.program.parse(process.argv);
51
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/bin/index.ts"],"names":[],"mappings":";;;;AAEA,yCAAoC;AACpC,kDAAqD;AACrD,0CAA6C;AAC7C,4CAAyC;AACzC,wCAA8C;AAC9C,0CAA4C;AAC5C,gDAAmD;AACnD,kDAA+C;AAC/C,0CAAuC;AACvC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAExD,QAAA,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AACrC,eAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;AAE7D,eAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,mCAAmC,CAAC;KAChD,MAAM,CACL,6BAA6B,EAC7B,iCAAiC,EACjC,OAAO,CAAC,GAAG,EAAE,CACd;KACA,MAAM,CAAC,iBAAU,CAAC,CAAC;AAEtB,eAAO;KACJ,OAAO,CAAC,mBAAmB,CAAC;KAC5B,WAAW,CAAC,yBAAyB,CAAC;KACtC,MAAM,CAAC,kBAAY,CAAC,CAAC;AAExB,eAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,gBAAgB,CAAC;KAC7B,MAAM,CAAC,6BAA6B,EAAE,uBAAuB,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;KAC7E,MAAM,CAAC,gBAAS,CAAC,CAAC;AAErB,eAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,yBAAyB,CAAC;KACtC,MAAM,CAAC,uBAAa,CAAC,CAAC;AAEzB,eAAO;KACJ,OAAO,CAAC,UAAU,CAAC;KACnB,WAAW,CAAC,kCAAkC,CAAC;KAC/C,MAAM,CAAC,mBAAQ,CAAC,CAAC;AAGpB,eAAO;KACJ,OAAO,CAAC,iBAAiB,CAAC;KAC1B,KAAK,CAAC,GAAG,CAAC;KACV,WAAW,CAAC,sCAAsC,CAAC;KACnD,MAAM,CAAC,yBAAc,CAAC,CAAC;AAE1B,eAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,MAAM,CAAC,aAAK,CAAC,CAAC;AACvE,eAAO,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE;IACpC,IAAA,aAAK,EAAC,sBAAsB,OAAO,YAAY,CAAC,CAAC;IACjD,eAAO,CAAC,IAAI,EAAE,CAAC;IACf,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AACH,eAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC","sourcesContent":["#! /usr/bin/env node\n\nimport { Command } from 'commander';\nimport { generateCourse } from '../command/generate';\nimport { initCourse } from '../command/init';\nimport { login } from '../command/login';\nimport { createCourse } from '../command/new';\nimport { zipCourse } from '../command/pack';\nimport { publishCourse } from '../command/publish';\nimport { validate } from '../command/validate';\nimport { error } from '../utils/error';\nconst { version, name, description } = require('../../package.json');\n\nexport const program = new Command();\nprogram.name(name).version(version).description(description);\n\nprogram\n .command('init')\n .description('Initialise project configuration ')\n .option(\n '-d, --directory <directory>',\n 'Directory to initialise project',\n process.cwd()\n )\n .action(initCourse);\n\nprogram\n .command('new <projectName>')\n .description('Generate course project')\n .action(createCourse);\n\nprogram\n .command('pack')\n .description('Compress files')\n .option('-d, --directory <directory>', 'Directory to compress', process.cwd())\n .action(zipCourse);\n\nprogram\n .command('publish')\n .description('Publish file to service')\n .action(publishCourse);\n\nprogram\n .command('validate')\n .description('Validate course folder structure')\n .action(validate);\n\n// Commande pour générer un chapitre\nprogram\n .command('generate course')\n .alias('g')\n .description('Generating Course with blueprint.yml')\n .action(generateCourse);\n\nprogram.command('login').description('Login to procamp').action(login);\nprogram.on('command:*', ([command]) => {\n error(`Erreur : commande \"${command}\" inconnue`);\n program.help();\n process.exit(1);\n});\nprogram.parse(process.argv);\n"]}
@@ -0,0 +1 @@
1
+ export declare function generateCourse(): Promise<void>;
@@ -0,0 +1,202 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.generateCourse = void 0;
13
+ const fs = require("fs-extra");
14
+ const inquirer_1 = require("inquirer");
15
+ const yaml = require("js-yaml");
16
+ const path = require("path");
17
+ const error_1 = require("../utils/error");
18
+ const getUserId_1 = require("../utils/getUserId");
19
+ const deleteFolder = (srcDir, arrayObject) => __awaiter(void 0, void 0, void 0, function* () {
20
+ if (fs.existsSync(srcDir)) {
21
+ const entries = fs.readdirSync(srcDir, { withFileTypes: true });
22
+ const directories = entries
23
+ .filter((dirent) => dirent.isDirectory())
24
+ .map((dirent) => dirent.name);
25
+ const names = arrayObject.map((obj) => obj.title);
26
+ let deleteFolder = [];
27
+ for (let directory of directories) {
28
+ const dir = directory
29
+ .toString()
30
+ .slice(directory.toString().indexOf('-') + 1)
31
+ .replaceAll('-', ' ');
32
+ if (!names.includes(dir)) {
33
+ deleteFolder.push(directory);
34
+ }
35
+ }
36
+ if (deleteFolder.length !== 0) {
37
+ const { confirm } = yield inquirer_1.default.prompt({
38
+ type: 'confirm',
39
+ message: `We found folders not listed in the structure of your course: \n ${deleteFolder} \n Do you want to delete them ?`,
40
+ name: 'confirm',
41
+ default: 'y'
42
+ });
43
+ if (confirm) {
44
+ deleteFolder.forEach((directory) => {
45
+ fs.rmSync(path.join(srcDir, directory), {
46
+ recursive: true,
47
+ force: true
48
+ });
49
+ });
50
+ console.log('Unlisted folders deleted');
51
+ }
52
+ else {
53
+ console.log('Deletion aborted.');
54
+ return;
55
+ }
56
+ }
57
+ }
58
+ });
59
+ const updateCourse = (srcDir, fileDir, object, i) => __awaiter(void 0, void 0, void 0, function* () {
60
+ if (fs.existsSync(srcDir)) {
61
+ const entries = fs.readdirSync(srcDir, { withFileTypes: true });
62
+ if (entries.length === 0)
63
+ fs.ensureDirSync(fileDir);
64
+ else {
65
+ const directories = entries
66
+ .filter((dirent) => dirent.isDirectory())
67
+ .map((dirent) => dirent.name);
68
+ const file = directories.find((file) => {
69
+ return (file
70
+ .toString()
71
+ .slice(file.toString().indexOf('-') + 1)
72
+ .localeCompare(object.title.toString().replaceAll(' ', '-')) === 0);
73
+ });
74
+ if (file) {
75
+ const filePath = path.join(srcDir, file);
76
+ if (Number(file.toString().slice(0, file.toString().indexOf('-'))) !==
77
+ i + 1) {
78
+ yield fs.move(filePath, fileDir, { overwrite: true });
79
+ }
80
+ }
81
+ else {
82
+ fs.ensureDirSync(fileDir);
83
+ }
84
+ }
85
+ }
86
+ else
87
+ yield fs.mkdir(fileDir);
88
+ });
89
+ function generateCourse() {
90
+ return __awaiter(this, void 0, void 0, function* () {
91
+ const configFile = path.join(process.cwd(), 'blueprint.yaml');
92
+ if (fs.existsSync(configFile)) {
93
+ const { name } = yield inquirer_1.default.prompt({
94
+ type: 'input',
95
+ name: 'name',
96
+ message: 'What is the name of the folder?',
97
+ default: 'course'
98
+ });
99
+ const baseDir = name;
100
+ const fileContents = fs.readFileSync(configFile, 'utf8');
101
+ const courses = yaml.load(fileContents);
102
+ const courseData = Object.assign({}, courses);
103
+ try {
104
+ let configContent = (0, getUserId_1.getUserId)();
105
+ fs.ensureDir(baseDir, () => __awaiter(this, void 0, void 0, function* () {
106
+ if (fs.existsSync(baseDir)) {
107
+ const courseInfo = courseData.course;
108
+ const meta = {
109
+ title: baseDir,
110
+ author: courseInfo.author,
111
+ description: courseInfo.description,
112
+ version: courseInfo.version,
113
+ courseId: courseInfo.courseId,
114
+ userId: configContent['sub']
115
+ };
116
+ try {
117
+ yield fs.writeJson(`${baseDir}/meta.json`, meta, {
118
+ spaces: 2
119
+ });
120
+ yield fs.writeFile(`${baseDir}/README.md`, '');
121
+ }
122
+ catch (e) {
123
+ throw e;
124
+ }
125
+ }
126
+ }));
127
+ if ('chapters' in courseData) {
128
+ const chapters = courseData.chapters;
129
+ yield deleteFolder(baseDir, chapters);
130
+ for (let i = 0; i < chapters.length; i++) {
131
+ const chapter = chapters[i];
132
+ const chapterDir = `${baseDir}/${(i + 1)
133
+ .toString()
134
+ .padStart(2, '0')}-${chapter.title.replace(/[:\s]+/g, '-')}`;
135
+ yield updateCourse(baseDir, chapterDir, chapter, i);
136
+ const chapterMeta = {
137
+ title: chapter.title,
138
+ order: i + 1
139
+ };
140
+ yield fs.writeJson(`${chapterDir}/meta.json`, chapterMeta, {
141
+ spaces: 2
142
+ });
143
+ if ('lessons' in chapter) {
144
+ const lessons = chapter.lessons;
145
+ yield deleteFolder(chapterDir, lessons);
146
+ for (let j = 0; j < lessons.length; j++) {
147
+ const lesson = lessons[j];
148
+ const lessonDir = `${chapterDir}/${(j + 1)
149
+ .toString()
150
+ .padStart(2, '0')}-${lesson.title.replace(/[:\s]+/g, '-')}`;
151
+ yield updateCourse(chapterDir, lessonDir, lesson, j);
152
+ const lessonMeta = {
153
+ title: lesson.title,
154
+ objectives: lesson.objectives,
155
+ order: j + 1
156
+ };
157
+ yield fs.writeJson(`${lessonDir}/meta.json`, lessonMeta, {
158
+ spaces: 2
159
+ });
160
+ if ('assessments' in lesson) {
161
+ const assessments = lesson.assessments;
162
+ yield deleteFolder(lessonDir, assessments);
163
+ for (let k = 0; k < assessments.length; k++) {
164
+ const assessment = assessments[k];
165
+ const assessmentDir = `${lessonDir}/${(k + 1)
166
+ .toString()
167
+ .padStart(2, '0')}-${assessment.title.replace(/[:\s]+/g, '-')}`;
168
+ yield updateCourse(lessonDir, assessmentDir, assessment, k);
169
+ yield fs.writeFile(`${assessmentDir}/README.md`, '');
170
+ yield fs.ensureDir(`${assessmentDir}/app-a`);
171
+ if (assessment.solution === true)
172
+ yield fs.ensureDir(`${assessmentDir}/app-b`);
173
+ }
174
+ }
175
+ else {
176
+ const assessmentDir = `${lessonDir}/${(1)
177
+ .toString()
178
+ .padStart(2, '0')}-${lesson.title.replace(/[:\s]+/g, '-')}`;
179
+ fs.ensureDirSync(assessmentDir);
180
+ yield fs.writeFile(`${assessmentDir}/README.md`, '');
181
+ yield fs.ensureDir(`${assessmentDir}/app-a/src/lib`);
182
+ }
183
+ }
184
+ }
185
+ else
186
+ return (0, error_1.error)(`I can't find lessons in the chapter ${i + 1}`);
187
+ }
188
+ }
189
+ else
190
+ return (0, error_1.error)("You haven't chapters in your blueprint.yaml");
191
+ console.log('Folder structure created');
192
+ }
193
+ catch (err) {
194
+ (0, error_1.error)('Error creating folder structure: ' + err);
195
+ }
196
+ }
197
+ else
198
+ return (0, error_1.error)('We need the blueprint.yaml file to create a course');
199
+ });
200
+ }
201
+ exports.generateCourse = generateCourse;
202
+ //# sourceMappingURL=generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/command/generate.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'fs-extra';\nimport inquirer from 'inquirer';\nimport * as yaml from 'js-yaml';\nimport * as path from 'path';\nimport { course, courseInfo } from '../interfaces/course';\nimport { error } from '../utils/error';\nimport { getUserId } from '../utils/getUserId';\n\nconst deleteFolder = async (srcDir, arrayObject) => {\n if (fs.existsSync(srcDir)) {\n const entries = fs.readdirSync(srcDir, { withFileTypes: true });\n const directories = entries\n .filter((dirent) => dirent.isDirectory())\n .map((dirent) => dirent.name);\n const names = arrayObject.map((obj) => obj.title);\n let deleteFolder: string[] = [];\n for (let directory of directories) {\n const dir = directory\n .toString()\n .slice(directory.toString().indexOf('-') + 1)\n .replaceAll('-', ' ');\n if (!names.includes(dir)) {\n deleteFolder.push(directory);\n }\n }\n if (deleteFolder.length !== 0) {\n const { confirm } = await inquirer.prompt({\n type: 'confirm',\n message: `We found folders not listed in the structure of your course: \\n ${deleteFolder} \\n Do you want to delete them ?`,\n name: 'confirm',\n default: 'y'\n });\n\n if (confirm) {\n deleteFolder.forEach((directory) => {\n fs.rmSync(path.join(srcDir, directory), {\n recursive: true,\n force: true\n });\n });\n console.log('Unlisted folders deleted');\n } else {\n console.log('Deletion aborted.');\n return;\n }\n }\n }\n};\n\nconst updateCourse = async (srcDir, fileDir, object, i) => {\n if (fs.existsSync(srcDir)) {\n const entries = fs.readdirSync(srcDir, { withFileTypes: true });\n if (entries.length === 0) fs.ensureDirSync(fileDir);\n else {\n const directories = entries\n .filter((dirent) => dirent.isDirectory())\n .map((dirent) => dirent.name);\n const file = directories.find((file) => {\n return (\n file\n .toString()\n .slice(file.toString().indexOf('-') + 1)\n .localeCompare(object.title.toString().replaceAll(' ', '-')) === 0\n );\n });\n\n if (file) {\n const filePath = path.join(srcDir, file);\n if (\n Number(file.toString().slice(0, file.toString().indexOf('-'))) !==\n i + 1\n ) {\n await fs.move(filePath, fileDir, { overwrite: true });\n }\n } else {\n fs.ensureDirSync(fileDir);\n }\n }\n } else await fs.mkdir(fileDir);\n};\n\nexport async function generateCourse() {\n const configFile = path.join(process.cwd(), 'blueprint.yaml');\n if (fs.existsSync(configFile)) {\n const { name } = await inquirer.prompt({\n type: 'input',\n name: 'name',\n message: 'What is the name of the folder?',\n default: 'course'\n });\n const baseDir = name;\n const fileContents = fs.readFileSync(configFile, 'utf8');\n const courses: any = yaml.load(fileContents);\n const courseData: course = { ...courses };\n\n try {\n let configContent = getUserId();\n\n fs.ensureDir(baseDir, async () => {\n if (fs.existsSync(baseDir)) {\n const courseInfo = courseData.course;\n const meta: courseInfo = {\n title: baseDir,\n author: courseInfo.author,\n description: courseInfo.description,\n version: courseInfo.version,\n courseId: courseInfo.courseId,\n userId: configContent['sub']\n };\n\n try {\n await fs.writeJson(`${baseDir}/meta.json`, meta, {\n spaces: 2\n });\n await fs.writeFile(`${baseDir}/README.md`, '');\n } catch (e) {\n throw e;\n }\n }\n });\n\n if ('chapters' in courseData) {\n const chapters = courseData.chapters;\n await deleteFolder(baseDir, chapters);\n for (let i = 0; i < chapters.length; i++) {\n const chapter = chapters[i];\n const chapterDir = `${baseDir}/${(i + 1)\n .toString()\n .padStart(2, '0')}-${chapter.title.replace(/[:\\s]+/g, '-')}`;\n await updateCourse(baseDir, chapterDir, chapter, i);\n\n // Create meta.json for chapter\n const chapterMeta = {\n title: chapter.title,\n order: i + 1\n };\n\n await fs.writeJson(`${chapterDir}/meta.json`, chapterMeta, {\n spaces: 2\n });\n\n if ('lessons' in chapter) {\n const lessons = chapter.lessons;\n await deleteFolder(chapterDir, lessons);\n for (let j = 0; j < lessons.length; j++) {\n const lesson = lessons[j];\n const lessonDir = `${chapterDir}/${(j + 1)\n .toString()\n .padStart(2, '0')}-${lesson.title.replace(/[:\\s]+/g, '-')}`;\n await updateCourse(chapterDir, lessonDir, lesson, j);\n\n // Create meta.json for lesson\n const lessonMeta = {\n title: lesson.title,\n objectives: lesson.objectives,\n order: j + 1\n };\n await fs.writeJson(`${lessonDir}/meta.json`, lessonMeta, {\n spaces: 2\n });\n\n if ('assessments' in lesson) {\n const assessments = lesson.assessments;\n await deleteFolder(lessonDir, assessments);\n for (let k = 0; k < assessments.length; k++) {\n const assessment = assessments[k];\n const assessmentDir = `${lessonDir}/${(k + 1)\n .toString()\n .padStart(2, '0')}-${assessment.title.replace(\n /[:\\s]+/g,\n '-'\n )}`;\n await updateCourse(lessonDir, assessmentDir, assessment, k);\n\n // Create meta.json for assessment\n // const assessmentMeta = {\n // title: assessment.title,\n // description: assessment.description,\n // language: assessment.language,\n // solution: assessment.solution,\n // order: k + 1,\n // };\n //await fsExtra.writeJson(`${assessmentDir}/meta.json`, assessmentMeta, {spaces: 2});\n await fs.writeFile(`${assessmentDir}/README.md`, '');\n\n // Create app-a and app-b folders inside assessment folder\n await fs.ensureDir(`${assessmentDir}/app-a`);\n\n if (assessment.solution === true)\n await fs.ensureDir(`${assessmentDir}/app-b`);\n }\n } else {\n const assessmentDir = `${lessonDir}/${(1)\n .toString()\n .padStart(2, '0')}-${lesson.title.replace(/[:\\s]+/g, '-')}`;\n fs.ensureDirSync(assessmentDir);\n // await fsExtra.writeJson(`${assessmentDir}/meta.json`, \"\");\n await fs.writeFile(`${assessmentDir}/README.md`, '');\n // Create app-a folders inside assessment folder\n await fs.ensureDir(`${assessmentDir}/app-a/src/lib`);\n }\n }\n } else return error(`I can't find lessons in the chapter ${i + 1}`);\n }\n } else return error(\"You haven't chapters in your blueprint.yaml\");\n\n console.log('Folder structure created');\n } catch (err) {\n error('Error creating folder structure: ' + err);\n }\n } else return error('We need the blueprint.yaml file to create a course');\n}\n"]}
@@ -0,0 +1 @@
1
+ export declare function initCourse(opt: any): void;
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.initCourse = void 0;
4
+ const fs = require("fs-extra");
5
+ const inquirer_1 = require("inquirer");
6
+ const path = require("path");
7
+ const error_1 = require("../utils/error");
8
+ const getUserId_1 = require("../utils/getUserId");
9
+ function initCourse(opt) {
10
+ const directory = opt.directory;
11
+ const questions = [
12
+ {
13
+ type: 'input',
14
+ name: 'title',
15
+ message: 'What is the title of the Folder?',
16
+ default: path.basename(directory)
17
+ },
18
+ {
19
+ type: 'input',
20
+ name: 'author',
21
+ message: 'Author ?',
22
+ default: ''
23
+ },
24
+ {
25
+ type: 'input',
26
+ name: 'description',
27
+ message: 'What is the course description ?',
28
+ default: ''
29
+ },
30
+ {
31
+ type: 'input',
32
+ name: 'courseId',
33
+ message: 'What is the course id?',
34
+ default: ''
35
+ }
36
+ ];
37
+ let configContent = (0, getUserId_1.getUserId)();
38
+ inquirer_1.default.prompt(questions).then((answers) => {
39
+ if (!answers.courseId || answers.courseId.length === 0)
40
+ return (0, error_1.error)('Course id must be not null');
41
+ const meta = {
42
+ title: answers.title,
43
+ author: answers.author,
44
+ description: answers.description,
45
+ courseId: answers.courseId,
46
+ userId: configContent['sub']
47
+ };
48
+ const filename = 'meta.json';
49
+ const filepath = path.join(directory, filename);
50
+ fs.writeFile(filepath, JSON.stringify(meta), (err) => {
51
+ if (err)
52
+ throw err;
53
+ console.log(`Le fichier ${filename} a été créé avec succès dans le répertoire ${directory} !`);
54
+ });
55
+ });
56
+ }
57
+ exports.initCourse = initCourse;
58
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/command/init.ts"],"names":[],"mappings":";;;AAAA,+BAA+B;AAC/B,uCAAgC;AAChC,6BAA6B;AAC7B,0CAAuC;AACvC,kDAA+C;AAE/C,SAAgB,UAAU,CAAC,GAAG;IAC5B,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;IAChC,MAAM,SAAS,GAAG;QAChB;YACE,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,kCAAkC;YAC3C,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;SAClC;QACD;YACE,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,UAAU;YACnB,OAAO,EAAE,EAAE;SACZ;QACD;YACE,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE,kCAAkC;YAC3C,OAAO,EAAE,EAAE;SACZ;QACD;YACE,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,UAAU;YAChB,OAAO,EAAE,wBAAwB;YACjC,OAAO,EAAE,EAAE;SACZ;KACF,CAAC;IACF,IAAI,aAAa,GAAG,IAAA,qBAAS,GAAE,CAAC;IAChC,kBAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;QAC1C,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;YACpD,OAAO,IAAA,aAAK,EAAC,4BAA4B,CAAC,CAAC;QAE7C,MAAM,IAAI,GAAG;YACX,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC;SAC7B,CAAC;QACF,MAAM,QAAQ,GAAG,WAAW,CAAC;QAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAEhD,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE;YACnD,IAAI,GAAG;gBAAE,MAAM,GAAG,CAAC;YACnB,OAAO,CAAC,GAAG,CACT,cAAc,QAAQ,8CAA8C,SAAS,IAAI,CAClF,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAlDD,gCAkDC","sourcesContent":["import * as fs from 'fs-extra';\nimport inquirer from 'inquirer';\nimport * as path from 'path';\nimport { error } from '../utils/error';\nimport { getUserId } from '../utils/getUserId';\n\nexport function initCourse(opt) {\n const directory = opt.directory;\n const questions = [\n {\n type: 'input',\n name: 'title',\n message: 'What is the title of the Folder?',\n default: path.basename(directory)\n },\n {\n type: 'input',\n name: 'author',\n message: 'Author ?',\n default: ''\n },\n {\n type: 'input',\n name: 'description',\n message: 'What is the course description ?',\n default: ''\n },\n {\n type: 'input',\n name: 'courseId',\n message: 'What is the course id?',\n default: ''\n }\n ];\n let configContent = getUserId();\n inquirer.prompt(questions).then((answers) => {\n if (!answers.courseId || answers.courseId.length === 0)\n return error('Course id must be not null');\n\n const meta = {\n title: answers.title,\n author: answers.author,\n description: answers.description,\n courseId: answers.courseId,\n userId: configContent['sub']\n };\n const filename = 'meta.json';\n const filepath = path.join(directory, filename);\n\n fs.writeFile(filepath, JSON.stringify(meta), (err) => {\n if (err) throw err;\n console.log(\n `Le fichier ${filename} a été créé avec succès dans le répertoire ${directory} !`\n );\n });\n });\n}\n"]}
@@ -0,0 +1 @@
1
+ export declare function login(): Promise<void>;
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.login = void 0;
13
+ const axios_1 = require("axios");
14
+ const fs = require("fs-extra");
15
+ const inquirer_1 = require("inquirer");
16
+ const jwt_decode_1 = require("jwt-decode");
17
+ const os = require("node:os");
18
+ const path = require("path");
19
+ const error_1 = require("../utils/error");
20
+ function login() {
21
+ return __awaiter(this, void 0, void 0, function* () {
22
+ const questions = [
23
+ {
24
+ type: 'input',
25
+ name: 'email',
26
+ message: 'Email:',
27
+ validate: function (input) {
28
+ const emailRegex = /^\S+@\S+\.\S+$/;
29
+ if (input.toString().length === 0)
30
+ return 'Email not be null';
31
+ if (emailRegex.test(input)) {
32
+ return true;
33
+ }
34
+ return 'Please enter a valid email address.';
35
+ }
36
+ },
37
+ {
38
+ type: 'password',
39
+ name: 'password',
40
+ message: 'Password:',
41
+ mask: '*',
42
+ validate: (password) => {
43
+ if (!password || password.length === 0)
44
+ return (0, error_1.error)('Password must be not null');
45
+ return true;
46
+ }
47
+ }
48
+ ];
49
+ const configPath = path.join(os.homedir(), '.procamp-config.json');
50
+ let configContent;
51
+ if (!fs.existsSync(configPath)) {
52
+ try {
53
+ fs.writeJSONSync(configPath, {
54
+ grant_type: 'password',
55
+ client_id: 'procamp-cli',
56
+ client_secret: 'ntVrw42swn4eD5nrIePMPg3R8kQFND6x'
57
+ }, { spaces: 2 });
58
+ }
59
+ catch (e) {
60
+ throw e;
61
+ }
62
+ }
63
+ try {
64
+ configContent = yield fs.readJSON(configPath);
65
+ }
66
+ catch (e) {
67
+ throw e;
68
+ }
69
+ inquirer_1.default.prompt(questions).then((answers) => {
70
+ const clientData = {
71
+ grant_type: configContent.grant_type,
72
+ client_id: configContent.client_id,
73
+ client_secret: configContent.client_secret
74
+ };
75
+ const data = Object.assign({ username: answers.email, password: answers.password }, clientData);
76
+ let bodyContent = '';
77
+ const entries = Object.entries(data);
78
+ for (let i = 0; i < entries.length; i++) {
79
+ const [name, value] = entries[i];
80
+ bodyContent += `${name}=${value}`;
81
+ if (i !== entries.length - 1) {
82
+ bodyContent += '&';
83
+ }
84
+ }
85
+ let headersList = {
86
+ Accept: '*/*',
87
+ 'Content-Type': 'application/x-www-form-urlencoded'
88
+ };
89
+ axios_1.default
90
+ .post('https://auth.procamp.dev/realms/procamp/protocol/openid-connect/token', bodyContent, {
91
+ headers: headersList
92
+ })
93
+ .then((res) => {
94
+ let decoded;
95
+ if ('access_token' in res.data)
96
+ decoded = (0, jwt_decode_1.default)(res.data.access_token);
97
+ fs.writeJSON(configPath, Object.assign(Object.assign({}, clientData), decoded), { spaces: 2 }, (err) => {
98
+ if (err) {
99
+ console.error('Error writing config file:', err);
100
+ }
101
+ });
102
+ console.log('You are \x1b[32m%s\x1b[0m', 'connected');
103
+ return;
104
+ })
105
+ .catch((e) => {
106
+ if ('response' in e)
107
+ if ('data' in e.response)
108
+ if ('error_description' in e.response.data)
109
+ (0, error_1.error)(`${e.response.data.error_description}`);
110
+ return;
111
+ });
112
+ });
113
+ });
114
+ }
115
+ exports.login = login;
116
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/command/login.ts"],"names":[],"mappings":"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","sourcesContent":["import axios from 'axios';\nimport * as fs from 'fs-extra';\nimport inquirer from 'inquirer';\nimport jwt_decode from 'jwt-decode';\nimport * as os from 'node:os';\nimport * as path from 'path';\nimport { error } from '../utils/error';\n\nexport async function login() {\n const questions = [\n {\n type: 'input',\n name: 'email',\n message: 'Email:',\n validate: function (input) {\n // Basic email format validation using a regular expression\n const emailRegex = /^\\S+@\\S+\\.\\S+$/;\n if (input.toString().length === 0) return 'Email not be null';\n\n if (emailRegex.test(input)) {\n return true;\n }\n\n return 'Please enter a valid email address.';\n }\n },\n {\n type: 'password',\n name: 'password',\n message: 'Password:',\n mask: '*',\n validate: (password) => {\n if (!password || password.length === 0)\n return error('Password must be not null');\n return true;\n }\n }\n ];\n\n const configPath = path.join(os.homedir(), '.procamp-config.json');\n let configContent;\n if (!fs.existsSync(configPath)) {\n try {\n fs.writeJSONSync(\n configPath,\n {\n grant_type: 'password',\n client_id: 'procamp-cli',\n client_secret: 'ntVrw42swn4eD5nrIePMPg3R8kQFND6x'\n },\n { spaces: 2 }\n );\n } catch (e) {\n throw e;\n }\n }\n try {\n configContent = await fs.readJSON(configPath);\n } catch (e) {\n throw e;\n }\n inquirer.prompt(questions).then((answers) => {\n const clientData = {\n grant_type: configContent.grant_type,\n client_id: configContent.client_id,\n client_secret: configContent.client_secret\n };\n const data = {\n username: answers.email,\n password: answers.password,\n ...clientData\n };\n let bodyContent = '';\n const entries = Object.entries(data);\n for (let i = 0; i < entries.length; i++) {\n const [name, value] = entries[i];\n bodyContent += `${name}=${value}`;\n if (i !== entries.length - 1) {\n bodyContent += '&';\n }\n }\n let headersList = {\n Accept: '*/*',\n 'Content-Type': 'application/x-www-form-urlencoded'\n };\n axios\n .post(\n 'https://auth.procamp.dev/realms/procamp/protocol/openid-connect/token',\n bodyContent,\n {\n headers: headersList\n }\n )\n .then((res) => {\n let decoded: object;\n\n if ('access_token' in res.data)\n decoded = jwt_decode(res.data.access_token);\n\n fs.writeJSON(\n configPath,\n {\n ...clientData,\n ...decoded\n },\n { spaces: 2 },\n (err) => {\n if (err) {\n console.error('Error writing config file:', err);\n }\n }\n );\n console.log('You are \\x1b[32m%s\\x1b[0m', 'connected');\n return;\n })\n .catch((e) => {\n if ('response' in e)\n if ('data' in e.response)\n if ('error_description' in e.response.data)\n error(`${e.response.data.error_description}`);\n\n return;\n });\n });\n}\n"]}
@@ -0,0 +1 @@
1
+ export declare function createCourse(projectName: any): Promise<void>;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.createCourse = void 0;
13
+ const fs = require("fs-extra");
14
+ const inquirer_1 = require("inquirer");
15
+ const path = require("path");
16
+ const init_1 = require("./init");
17
+ function createCourse(projectName) {
18
+ return __awaiter(this, void 0, void 0, function* () {
19
+ const { confirm } = yield inquirer_1.default.prompt({
20
+ type: 'confirm',
21
+ message: `Are you sure you want to generate a new project named ${projectName} ?`,
22
+ name: 'confirm',
23
+ default: 'y'
24
+ });
25
+ if (!confirm) {
26
+ console.log('Aborted.');
27
+ return;
28
+ }
29
+ fs.mkdirSync(projectName, { recursive: true });
30
+ console.log(`${projectName} course project generated!`);
31
+ const pathfolder = path.join(process.cwd(), projectName);
32
+ if (fs.existsSync(pathfolder)) {
33
+ (0, init_1.initCourse)({
34
+ directory: pathfolder
35
+ });
36
+ return;
37
+ }
38
+ });
39
+ }
40
+ exports.createCourse = createCourse;
41
+ //# sourceMappingURL=new.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"new.js","sourceRoot":"","sources":["../../src/command/new.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,+BAA+B;AAC/B,uCAAgC;AAChC,6BAA6B;AAC7B,iCAAoC;AAEpC,SAAsB,YAAY,CAAC,WAAW;;QAC5C,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,kBAAQ,CAAC,MAAM,CAAC;YACxC,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,yDAAyD,WAAW,IAAI;YACjF,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,GAAG;SACb,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,EAAE;YACZ,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YACxB,OAAO;SACR;QACD,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,GAAG,WAAW,4BAA4B,CAAC,CAAC;QACxD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;QACzD,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE;YAC7B,IAAA,iBAAU,EAAC;gBACT,SAAS,EAAE,UAAU;aACtB,CAAC,CAAC;YACH,OAAO;SACR;IACH,CAAC;CAAA;AArBD,oCAqBC","sourcesContent":["import * as fs from 'fs-extra';\nimport inquirer from 'inquirer';\nimport * as path from 'path';\nimport { initCourse } from './init';\n\nexport async function createCourse(projectName) {\n const { confirm } = await inquirer.prompt({\n type: 'confirm',\n message: `Are you sure you want to generate a new project named ${projectName} ?`,\n name: 'confirm',\n default: 'y'\n });\n\n if (!confirm) {\n console.log('Aborted.');\n return;\n }\n fs.mkdirSync(projectName, { recursive: true });\n console.log(`${projectName} course project generated!`);\n const pathfolder = path.join(process.cwd(), projectName);\n if (fs.existsSync(pathfolder)) {\n initCourse({\n directory: pathfolder\n });\n return;\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ export declare function zipCourse(options: any): void;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.zipCourse = void 0;
4
+ const AdmZip = require("adm-zip");
5
+ const fs = require("fs-extra");
6
+ const path = require("path");
7
+ const error_1 = require("../utils/error");
8
+ function zipCourse(options) {
9
+ console.log(`Compressing ${options.directory}...`);
10
+ const output = '.output.zip';
11
+ const zip = new AdmZip();
12
+ const sourceDirectory = path.resolve(options.directory);
13
+ if (fs.existsSync(sourceDirectory)) {
14
+ const filesToIgnore = ['_MACOSX', 'node_modules'];
15
+ zip.addLocalFolder(sourceDirectory, '', function (filename) {
16
+ for (const files of filesToIgnore) {
17
+ if (filename.startsWith(files)) {
18
+ return false;
19
+ }
20
+ }
21
+ return !filename.startsWith('.');
22
+ });
23
+ const outputFilePath = path.join(sourceDirectory, output);
24
+ zip.writeZip(outputFilePath);
25
+ console.log(`${sourceDirectory} compressed to ${output} in directory ${sourceDirectory}`);
26
+ }
27
+ else {
28
+ (0, error_1.error)(`${options.directory} does not exist`);
29
+ }
30
+ }
31
+ exports.zipCourse = zipCourse;
32
+ //# sourceMappingURL=pack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pack.js","sourceRoot":"","sources":["../../src/command/pack.ts"],"names":[],"mappings":";;;AAAA,kCAAkC;AAClC,+BAA+B;AAC/B,6BAA6B;AAC7B,0CAAuC;AAEvC,SAAgB,SAAS,CAAC,OAAO;IAC/B,OAAO,CAAC,GAAG,CAAC,eAAe,OAAO,CAAC,SAAS,KAAK,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,aAAa,CAAC;IAC7B,MAAM,GAAG,GAAG,IAAI,MAAM,EAAE,CAAC;IACzB,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACxD,IAAI,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE;QAClC,MAAM,aAAa,GAAG,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;QAClD,GAAG,CAAC,cAAc,CAAC,eAAe,EAAE,EAAE,EAAE,UAAU,QAAQ;YACxD,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE;gBACjC,IAAI,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE;oBAC9B,OAAO,KAAK,CAAC;iBACd;aACF;YACD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QACH,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;QAC1D,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;QAC7B,OAAO,CAAC,GAAG,CACT,GAAG,eAAe,kBAAkB,MAAM,iBAAiB,eAAe,EAAE,CAC7E,CAAC;KACH;SAAM;QACL,IAAA,aAAK,EAAC,GAAG,OAAO,CAAC,SAAS,iBAAiB,CAAC,CAAC;KAC9C;AACH,CAAC;AAvBD,8BAuBC","sourcesContent":["import * as AdmZip from 'adm-zip';\nimport * as fs from 'fs-extra';\nimport * as path from 'path';\nimport { error } from '../utils/error';\n\nexport function zipCourse(options) {\n console.log(`Compressing ${options.directory}...`);\n const output = '.output.zip';\n const zip = new AdmZip();\n const sourceDirectory = path.resolve(options.directory);\n if (fs.existsSync(sourceDirectory)) {\n const filesToIgnore = ['_MACOSX', 'node_modules'];\n zip.addLocalFolder(sourceDirectory, '', function (filename) {\n for (const files of filesToIgnore) {\n if (filename.startsWith(files)) {\n return false;\n }\n }\n return !filename.startsWith('.');\n });\n const outputFilePath = path.join(sourceDirectory, output);\n zip.writeZip(outputFilePath);\n console.log(\n `${sourceDirectory} compressed to ${output} in directory ${sourceDirectory}`\n );\n } else {\n error(`${options.directory} does not exist`);\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ export declare function publishCourse(): Promise<void>;
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.publishCourse = void 0;
13
+ const course_validator_1 = require("@procamp/course-validator");
14
+ const axios_1 = require("axios");
15
+ const FormData = require("form-data");
16
+ const fs = require("fs-extra");
17
+ const os = require("os");
18
+ const path = require("path");
19
+ const error_1 = require("../utils/error");
20
+ const pack_1 = require("./pack");
21
+ function publishCourse() {
22
+ return __awaiter(this, void 0, void 0, function* () {
23
+ const directory = process.cwd();
24
+ const filenameConf = path.join(directory, 'meta.json');
25
+ if (fs.existsSync(filenameConf)) {
26
+ const data = yield fs.readFile(filenameConf, { encoding: 'utf-8' });
27
+ const meta = JSON.parse(data);
28
+ if (meta.courseId && meta.courseId.length !== 0) {
29
+ const courseId = meta.courseId;
30
+ const filePathZip = path.join(directory, '.output.zip');
31
+ const configPath = path.join(os.homedir(), '.procamp-config.json');
32
+ let configContent;
33
+ if (fs.existsSync(configPath)) {
34
+ try {
35
+ configContent = yield fs.readJSON(configPath);
36
+ }
37
+ catch (e) {
38
+ throw e;
39
+ }
40
+ if (!('userID' in meta) || meta.userID.length !== 0) {
41
+ if ('sub' in configContent)
42
+ yield fs.writeJson(filenameConf, Object.assign(Object.assign({}, meta), { userId: configContent['sub'] }), { spaces: 2 });
43
+ }
44
+ }
45
+ else
46
+ return (0, error_1.error)("I don't find config file.Please log in ");
47
+ yield (0, course_validator_1.validateCourse)(directory);
48
+ const postZipfile = () => {
49
+ if (fs.existsSync(filePathZip)) {
50
+ const fileStream = fs.createReadStream(filePathZip);
51
+ const form = new FormData();
52
+ form.append('file', fileStream);
53
+ axios_1.default
54
+ .post(`https://course-manager.procamp.dev/api/courses/${courseId}`, form, {
55
+ headers: {
56
+ 'x-api-key': configContent['api-key']
57
+ }
58
+ })
59
+ .then((response) => {
60
+ console.log(response.data);
61
+ })
62
+ .catch((err) => {
63
+ if ('response' in err)
64
+ if ('data' in err.response) {
65
+ const data = err.response.data;
66
+ if ('statusCode' in data && 'message' in data)
67
+ (0, error_1.error)('Error publishing folder: ' +
68
+ data.message +
69
+ '. Error ' +
70
+ data.statusCode);
71
+ }
72
+ });
73
+ }
74
+ };
75
+ if (!fs.existsSync(filePathZip)) {
76
+ (0, pack_1.zipCourse)({
77
+ directory: directory
78
+ });
79
+ postZipfile();
80
+ return;
81
+ }
82
+ return postZipfile();
83
+ }
84
+ else {
85
+ return (0, error_1.error)("Course Id key don't exist or null in meta.json.\n" +
86
+ 'Please complete course id');
87
+ }
88
+ }
89
+ else {
90
+ return (0, error_1.error)('meta.json file does not exist');
91
+ }
92
+ });
93
+ }
94
+ exports.publishCourse = publishCourse;
95
+ //# sourceMappingURL=publish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/command/publish.ts"],"names":[],"mappings":"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","sourcesContent":["import { validateCourse } from '@procamp/course-validator';\nimport axios from 'axios';\nimport * as FormData from 'form-data';\nimport * as fs from 'fs-extra';\nimport * as os from 'os';\nimport * as path from 'path';\nimport { error } from '../utils/error';\nimport { zipCourse } from './pack';\n\nexport async function publishCourse() {\n const directory = process.cwd();\n const filenameConf = path.join(directory, 'meta.json');\n\n if (fs.existsSync(filenameConf)) {\n const data = await fs.readFile(filenameConf, { encoding: 'utf-8' });\n const meta = JSON.parse(data);\n if (meta.courseId && meta.courseId.length !== 0) {\n const courseId: string = meta.courseId;\n const filePathZip = path.join(directory, '.output.zip');\n const configPath = path.join(os.homedir(), '.procamp-config.json');\n let configContent: any;\n if (fs.existsSync(configPath)) {\n try {\n configContent = await fs.readJSON(configPath);\n } catch (e) {\n throw e;\n }\n if (!('userID' in meta) || meta.userID.length !== 0) {\n if ('sub' in configContent)\n await fs.writeJson(\n filenameConf,\n { ...meta, userId: configContent['sub'] },\n { spaces: 2 }\n );\n }\n } else return error(\"I don't find config file.Please log in \");\n\n await validateCourse(directory);\n const postZipfile = () => {\n if (fs.existsSync(filePathZip)) {\n const fileStream = fs.createReadStream(filePathZip);\n const form = new FormData();\n form.append('file', fileStream);\n axios\n .post(\n `https://course-manager.procamp.dev/api/courses/${courseId}`,\n form,\n {\n headers: {\n 'x-api-key': configContent['api-key']\n }\n }\n )\n .then((response) => {\n console.log(response.data);\n })\n .catch((err) => {\n if ('response' in err)\n if ('data' in err.response) {\n const data = err.response.data;\n if ('statusCode' in data && 'message' in data)\n error(\n 'Error publishing folder: ' +\n data.message +\n '. Error ' +\n data.statusCode\n );\n }\n });\n }\n };\n\n if (!fs.existsSync(filePathZip)) {\n zipCourse({\n directory: directory\n });\n postZipfile();\n return;\n }\n\n return postZipfile();\n } else {\n return error(\n \"Course Id key don't exist or null in meta.json.\\n\" +\n 'Please complete course id'\n );\n }\n } else {\n return error('meta.json file does not exist');\n }\n}\n"]}
@@ -0,0 +1 @@
1
+ export declare function validate(): void;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validate = void 0;
4
+ const course_validator_1 = require("@procamp/course-validator");
5
+ function validate() {
6
+ (0, course_validator_1.validateCourse)(process.cwd());
7
+ }
8
+ exports.validate = validate;
9
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/command/validate.ts"],"names":[],"mappings":";;;AAAA,gEAA2D;AAE3D,SAAgB,QAAQ;IACtB,IAAA,iCAAc,EAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AAChC,CAAC;AAFD,4BAEC","sourcesContent":["import { validateCourse } from '@procamp/course-validator';\n\nexport function validate() {\n validateCourse(process.cwd());\n}\n"]}
File without changes
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"","sourcesContent":[""]}
@@ -0,0 +1,27 @@
1
+ export interface assessments {
2
+ title: string;
3
+ description: string;
4
+ language: string;
5
+ solution: boolean;
6
+ }
7
+ export interface lessons {
8
+ title: string;
9
+ objectives: string[];
10
+ assessments?: assessments[];
11
+ }
12
+ export interface chapters {
13
+ title: string;
14
+ lessons: lessons[];
15
+ }
16
+ export interface courseInfo {
17
+ title: string;
18
+ author: string;
19
+ description: string;
20
+ version: string;
21
+ courseId: string;
22
+ userId?: string;
23
+ }
24
+ export interface course {
25
+ course: courseInfo;
26
+ chapters: chapters[];
27
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=course.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"course.js","sourceRoot":"","sources":["../../src/interfaces/course.ts"],"names":[],"mappings":"","sourcesContent":["export interface assessments {\n title: string;\n description: string;\n language: string;\n solution: boolean;\n}\nexport interface lessons {\n title: string;\n objectives: string[];\n assessments?: assessments[];\n}\nexport interface chapters {\n title: string;\n lessons: lessons[];\n}\n\nexport interface courseInfo {\n title: string;\n author: string;\n description: string;\n version: string;\n courseId: string;\n userId?: string;\n}\nexport interface course {\n course: courseInfo;\n chapters: chapters[];\n}\n"]}
@@ -0,0 +1 @@
1
+ export declare function error(err: string): void;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.error = void 0;
4
+ function error(err) {
5
+ console.error('cmp \x1b[31m%s\x1b[0m', 'ERR!', err);
6
+ }
7
+ exports.error = error;
8
+ //# sourceMappingURL=error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/utils/error.ts"],"names":[],"mappings":";;;AAAA,SAAgB,KAAK,CAAC,GAAW;IAC/B,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;AACtD,CAAC;AAFD,sBAEC","sourcesContent":["export function error(err: string) {\n console.error('cmp \\x1b[31m%s\\x1b[0m', 'ERR!', err);\n}\n"]}
@@ -0,0 +1 @@
1
+ export declare function getUserId(): any;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getUserId = void 0;
4
+ const fs = require("fs-extra");
5
+ const os = require("os");
6
+ const path = require("path");
7
+ function getUserId() {
8
+ const configPath = path.join(os.homedir(), '.procamp-config.json');
9
+ if (fs.existsSync(configPath)) {
10
+ return fs.readJSONSync(configPath);
11
+ }
12
+ return;
13
+ }
14
+ exports.getUserId = getUserId;
15
+ //# sourceMappingURL=getUserId.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getUserId.js","sourceRoot":"","sources":["../../src/utils/getUserId.ts"],"names":[],"mappings":";;;AAAA,+BAA+B;AAC/B,yBAAyB;AACzB,6BAA6B;AAE7B,SAAgB,SAAS;IACvB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,sBAAsB,CAAC,CAAC;IACnE,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE;QAC7B,OAAO,EAAE,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;KACpC;IACD,OAAO;AACT,CAAC;AAND,8BAMC","sourcesContent":["import * as fs from 'fs-extra';\nimport * as os from 'os';\nimport * as path from 'path';\n\nexport function getUserId() {\n const configPath = path.join(os.homedir(), '.procamp-config.json');\n if (fs.existsSync(configPath)) {\n return fs.readJSONSync(configPath);\n }\n return;\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@procamp/cli",
3
+ "version": "0.0.1",
4
+ "description": "Procamp CLI",
5
+ "main": "dist/index.js",
6
+ "files": [
7
+ "dist/"
8
+ ],
9
+ "bin": {
10
+ "camp": "dist/bin/index.js"
11
+ },
12
+ "scripts": {
13
+ "link:dev": "npm link --local",
14
+ "prepare": "husky install",
15
+ "build": "npm run clean && tsc",
16
+ "build:dev": "tsc -w",
17
+ "clean": "rimraf dist",
18
+ "release:patch": "npm run test && npm run build && npm version patch",
19
+ "postversion": "git push && git push --tags && npm publish",
20
+ "format": "prettier --write \"**/*.{js,ts,json}\"",
21
+ "test": "npm run clean && jest"
22
+ },
23
+ "keywords": [
24
+ "typescript",
25
+ "tsc"
26
+ ],
27
+ "author": "Afrointelligence",
28
+ "license": "ISC",
29
+ "devDependencies": {
30
+ "@types/adm-zip": "^0.5.0",
31
+ "@types/fs-extra": "^11.0.1",
32
+ "@types/inquirer": "^9.0.3",
33
+ "@types/js-yaml": "^4.0.5",
34
+ "@types/node": "^18.16.4",
35
+ "@types/rimraf": "^4.0.5",
36
+ "husky": "^8.0.3",
37
+ "jwt-decode": "^3.1.2",
38
+ "prettier": "^2.8.8",
39
+ "rimraf": "^5.0.0",
40
+ "typescript": "^5.0.4"
41
+ },
42
+ "dependencies": {
43
+ "@procamp/course-validator": "^1.0.2",
44
+ "@types/jest": "^29.5.1",
45
+ "adm-zip": "^0.5.10",
46
+ "axios": "^1.4.0",
47
+ "commander": "^10.0.1",
48
+ "ejs": "^3.1.9",
49
+ "form-data": "^4.0.0",
50
+ "fs-extra": "^11.1.1",
51
+ "glob-promise": "^6.0.2",
52
+ "globby": "^11.1.0",
53
+ "inquirer": "^8.2.5",
54
+ "js-yaml": "^4.1.0",
55
+ "path": "^0.12.7",
56
+ "ts-jest": "^29.1.0"
57
+ }
58
+ }
package/readme.md ADDED
@@ -0,0 +1,32 @@
1
+ # Getting started with Cmp cli
2
+
3
+ This project was bootstrapped with [Cmp CLI](https://github.com/facebook/create-react-app)
4
+
5
+ ### ENV
6
+
7
+ Copy content from .example.env to .env
8
+ ## Available Scripts
9
+
10
+ You can create the course directory with:
11
+ ### `cmp new`
12
+
13
+ In the course directory, you can run:
14
+
15
+ ### `cmp init`
16
+
17
+ This command allows you to create a meta.json file that
18
+ contains race configurations such as the title, id .
19
+
20
+ ### `cmp pack`
21
+
22
+ Archive the course, by default it archives
23
+ the current folder. The -d or --directory option
24
+ adds the path of the archived folder
25
+
26
+ ### `cmp publish`
27
+ Publishes the course on the course manager platform. It uses the id in the meta.json
28
+ file for publishing the course
29
+
30
+ ### `cmp g course`
31
+ Create course with blueprint.yaml
32
+