@learnpack/learnpack 5.0.14 → 5.0.16
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 +19 -11
- package/lib/commands/init.d.ts +1 -0
- package/lib/commands/init.js +122 -102
- package/lib/utils/BaseCommand.d.ts +3 -0
- package/lib/utils/BaseCommand.js +7 -0
- package/lib/utils/api.d.ts +3 -0
- package/lib/utils/api.js +25 -0
- package/lib/utils/checkNotInstalled.js +7 -1
- package/oclif.manifest.json +1 -1
- package/package.json +152 -152
- package/src/commands/init.ts +144 -106
- package/src/utils/BaseCommand.ts +56 -48
- package/src/utils/api.ts +42 -0
- package/src/utils/checkNotInstalled.ts +8 -1
- package/src/utils/incrementVersion.js +65 -0
package/package.json
CHANGED
@@ -1,152 +1,152 @@
|
|
1
|
-
{
|
2
|
-
"name": "@learnpack/learnpack",
|
3
|
-
"description": "Seamlessly build, sell and/or take interactive & auto-graded tutorials, start learning now or build a new tutorial to your audience.",
|
4
|
-
"version": "5.0.
|
5
|
-
"author": "Alejandro Sanchez @alesanchezr",
|
6
|
-
"contributors": [
|
7
|
-
{
|
8
|
-
"name": "Alejandro Sanchez",
|
9
|
-
"url": "https://www.x.com/alesanchezr"
|
10
|
-
},
|
11
|
-
{
|
12
|
-
"name": "Charly Chacón",
|
13
|
-
"email": "charlyjchaconc@gmail.com",
|
14
|
-
"url": "https://www.linkedin.com/in/charlytoc/"
|
15
|
-
}
|
16
|
-
],
|
17
|
-
"bin": {
|
18
|
-
"learnpack": "bin/run"
|
19
|
-
},
|
20
|
-
"bugs": {
|
21
|
-
"url": "https://github.com/learnpack/learnpack-cli/issues"
|
22
|
-
},
|
23
|
-
"dependencies": {
|
24
|
-
"@oclif/command": "^1.6.1",
|
25
|
-
"@oclif/config": "^1.15.1",
|
26
|
-
"@oclif/plugin-help": "^3.1.0",
|
27
|
-
"@oclif/plugin-plugins": "^1.8.0",
|
28
|
-
"@oclif/plugin-warn-if-update-available": "^1.7.0",
|
29
|
-
"@types/archiver": "^6.0.2",
|
30
|
-
"archiver": "^7.0.1",
|
31
|
-
"axios": "^1.7.7",
|
32
|
-
"body-parser": "^1.19.0",
|
33
|
-
"chalk": "^4.1.0",
|
34
|
-
"chokidar": "^3.4.0",
|
35
|
-
"cli-ux": "^5.4.6",
|
36
|
-
"debounce": "^1.2.0",
|
37
|
-
"dotenv": "^8.2.0",
|
38
|
-
"enquirer": "^2.3.6",
|
39
|
-
"eslint-plugin-unicorn": "^38.0.1",
|
40
|
-
"espree": "^9.3.2",
|
41
|
-
"eta": "^1.2.0",
|
42
|
-
"express": "^4.17.1",
|
43
|
-
"front-matter": "^4.0.2",
|
44
|
-
"moment": "^2.27.0",
|
45
|
-
"node-emoji": "^1.10.0",
|
46
|
-
"node-fetch": "^2.7.0",
|
47
|
-
"node-persist": "^3.1.0",
|
48
|
-
"prompts": "^2.3.2",
|
49
|
-
"shelljs": "^0.8.4",
|
50
|
-
"socket.io": "^4.4.1",
|
51
|
-
"targz": "^1.0.1",
|
52
|
-
"tslib": "^1",
|
53
|
-
"validator": "^13.1.1",
|
54
|
-
"xxhashjs": "^0.2.2"
|
55
|
-
},
|
56
|
-
"devDependencies": {
|
57
|
-
"@oclif/dev-cli": "^1.22.2",
|
58
|
-
"@oclif/test": "^1.2.6",
|
59
|
-
"@types/chai": "^4",
|
60
|
-
"@types/debounce": "^1.2.1",
|
61
|
-
"@types/express": "^4.17.13",
|
62
|
-
"@types/fs-extra": "^8.1.0",
|
63
|
-
"@types/mocha": "^5",
|
64
|
-
"@types/mock-fs": "^4.13.1",
|
65
|
-
"@types/node": "^10.17.60",
|
66
|
-
"@types/node-persist": "^3.1.2",
|
67
|
-
"@types/prompts": "^2.0.14",
|
68
|
-
"@types/shelljs": "^0.8.9",
|
69
|
-
"@types/socket.io": "^3.0.2",
|
70
|
-
"@types/targz": "^1.0.1",
|
71
|
-
"@types/validator": "^13.7.0",
|
72
|
-
"@types/xxhashjs": "^0.2.2",
|
73
|
-
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
74
|
-
"@typescript-eslint/parser": "^5.4.0",
|
75
|
-
"chai": "^4.2.0",
|
76
|
-
"chai-http": "^4.3.0",
|
77
|
-
"eslint": "^8.12.0",
|
78
|
-
"eslint-config-oclif": "^4.0",
|
79
|
-
"eslint-config-oclif-typescript": "^1.0.2",
|
80
|
-
"fs-extra": "^10.0.1",
|
81
|
-
"globby": "^10.0.2",
|
82
|
-
"husky": ">=6",
|
83
|
-
"lint-staged": ">=10",
|
84
|
-
"mocha": "^5.2.0",
|
85
|
-
"mock-fs": "^5.1.2",
|
86
|
-
"nock": "^13.2.2",
|
87
|
-
"nyc": "^14.1.1",
|
88
|
-
"pre-commit": "^1.2.2",
|
89
|
-
"prettier": "^2.4.1",
|
90
|
-
"ts-node": "^8",
|
91
|
-
"typescript": "^5.6.2"
|
92
|
-
},
|
93
|
-
"engines": {
|
94
|
-
"node": ">=14.0.0"
|
95
|
-
},
|
96
|
-
"files": [
|
97
|
-
"/bin",
|
98
|
-
"/npm-shrinkwrap.json",
|
99
|
-
"/oclif.manifest.json",
|
100
|
-
"/src",
|
101
|
-
"/lib"
|
102
|
-
],
|
103
|
-
"homepage": "https://github.com/learnpack/learnpack-cli",
|
104
|
-
"keywords": [
|
105
|
-
"oclif"
|
106
|
-
],
|
107
|
-
"license": "UNLICENSED",
|
108
|
-
"main": "lib/index.js",
|
109
|
-
"types": "lib/index.d.ts",
|
110
|
-
"oclif": {
|
111
|
-
"commands": "./lib/commands",
|
112
|
-
"bin": "learnpack",
|
113
|
-
"plugins": [
|
114
|
-
"@oclif/plugin-help",
|
115
|
-
"@oclif/plugin-plugins",
|
116
|
-
"@oclif/plugin-warn-if-update-available"
|
117
|
-
],
|
118
|
-
"permanent_plugins": [
|
119
|
-
"@oclif/plugin-help",
|
120
|
-
"@oclif/plugin-plugins",
|
121
|
-
"@oclif/plugin-warn-if-update-available"
|
122
|
-
]
|
123
|
-
},
|
124
|
-
"repository": {
|
125
|
-
"type": "git",
|
126
|
-
"url": "git+https://github.com/learnpack/learnpack-cli.git"
|
127
|
-
},
|
128
|
-
"pre-commit": {
|
129
|
-
"silent": true,
|
130
|
-
"run": [
|
131
|
-
"pre"
|
132
|
-
]
|
133
|
-
},
|
134
|
-
"scripts": {
|
135
|
-
"tsc": "tsc -b",
|
136
|
-
"postpack": "rm -f oclif.manifest.json && eslint . --ext .ts --config .eslintrc",
|
137
|
-
"prepack": "rm -rf lib && tsc -b && oclif-dev manifest && oclif-dev readme",
|
138
|
-
"pre": "node ./test/precommit/index.ts",
|
139
|
-
"test": "NODE_ENV=test nyc --extension .ts mocha --forbid-only \"test/**/*.test.ts\"",
|
140
|
-
"version": "oclif-dev readme && git add README.md",
|
141
|
-
"prepare": "husky install"
|
142
|
-
},
|
143
|
-
"lint-staged": {
|
144
|
-
"*.{js,ts}": [
|
145
|
-
"eslint --cache --fix"
|
146
|
-
],
|
147
|
-
"*.{js,css,md,ts}": "prettier --write"
|
148
|
-
},
|
149
|
-
"directories": {
|
150
|
-
"test": "test"
|
151
|
-
}
|
152
|
-
}
|
1
|
+
{
|
2
|
+
"name": "@learnpack/learnpack",
|
3
|
+
"description": "Seamlessly build, sell and/or take interactive & auto-graded tutorials, start learning now or build a new tutorial to your audience.",
|
4
|
+
"version": "5.0.16",
|
5
|
+
"author": "Alejandro Sanchez @alesanchezr",
|
6
|
+
"contributors": [
|
7
|
+
{
|
8
|
+
"name": "Alejandro Sanchez",
|
9
|
+
"url": "https://www.x.com/alesanchezr"
|
10
|
+
},
|
11
|
+
{
|
12
|
+
"name": "Charly Chacón",
|
13
|
+
"email": "charlyjchaconc@gmail.com",
|
14
|
+
"url": "https://www.linkedin.com/in/charlytoc/"
|
15
|
+
}
|
16
|
+
],
|
17
|
+
"bin": {
|
18
|
+
"learnpack": "bin/run"
|
19
|
+
},
|
20
|
+
"bugs": {
|
21
|
+
"url": "https://github.com/learnpack/learnpack-cli/issues"
|
22
|
+
},
|
23
|
+
"dependencies": {
|
24
|
+
"@oclif/command": "^1.6.1",
|
25
|
+
"@oclif/config": "^1.15.1",
|
26
|
+
"@oclif/plugin-help": "^3.1.0",
|
27
|
+
"@oclif/plugin-plugins": "^1.8.0",
|
28
|
+
"@oclif/plugin-warn-if-update-available": "^1.7.0",
|
29
|
+
"@types/archiver": "^6.0.2",
|
30
|
+
"archiver": "^7.0.1",
|
31
|
+
"axios": "^1.7.7",
|
32
|
+
"body-parser": "^1.19.0",
|
33
|
+
"chalk": "^4.1.0",
|
34
|
+
"chokidar": "^3.4.0",
|
35
|
+
"cli-ux": "^5.4.6",
|
36
|
+
"debounce": "^1.2.0",
|
37
|
+
"dotenv": "^8.2.0",
|
38
|
+
"enquirer": "^2.3.6",
|
39
|
+
"eslint-plugin-unicorn": "^38.0.1",
|
40
|
+
"espree": "^9.3.2",
|
41
|
+
"eta": "^1.2.0",
|
42
|
+
"express": "^4.17.1",
|
43
|
+
"front-matter": "^4.0.2",
|
44
|
+
"moment": "^2.27.0",
|
45
|
+
"node-emoji": "^1.10.0",
|
46
|
+
"node-fetch": "^2.7.0",
|
47
|
+
"node-persist": "^3.1.0",
|
48
|
+
"prompts": "^2.3.2",
|
49
|
+
"shelljs": "^0.8.4",
|
50
|
+
"socket.io": "^4.4.1",
|
51
|
+
"targz": "^1.0.1",
|
52
|
+
"tslib": "^1",
|
53
|
+
"validator": "^13.1.1",
|
54
|
+
"xxhashjs": "^0.2.2"
|
55
|
+
},
|
56
|
+
"devDependencies": {
|
57
|
+
"@oclif/dev-cli": "^1.22.2",
|
58
|
+
"@oclif/test": "^1.2.6",
|
59
|
+
"@types/chai": "^4",
|
60
|
+
"@types/debounce": "^1.2.1",
|
61
|
+
"@types/express": "^4.17.13",
|
62
|
+
"@types/fs-extra": "^8.1.0",
|
63
|
+
"@types/mocha": "^5",
|
64
|
+
"@types/mock-fs": "^4.13.1",
|
65
|
+
"@types/node": "^10.17.60",
|
66
|
+
"@types/node-persist": "^3.1.2",
|
67
|
+
"@types/prompts": "^2.0.14",
|
68
|
+
"@types/shelljs": "^0.8.9",
|
69
|
+
"@types/socket.io": "^3.0.2",
|
70
|
+
"@types/targz": "^1.0.1",
|
71
|
+
"@types/validator": "^13.7.0",
|
72
|
+
"@types/xxhashjs": "^0.2.2",
|
73
|
+
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
74
|
+
"@typescript-eslint/parser": "^5.4.0",
|
75
|
+
"chai": "^4.2.0",
|
76
|
+
"chai-http": "^4.3.0",
|
77
|
+
"eslint": "^8.12.0",
|
78
|
+
"eslint-config-oclif": "^4.0",
|
79
|
+
"eslint-config-oclif-typescript": "^1.0.2",
|
80
|
+
"fs-extra": "^10.0.1",
|
81
|
+
"globby": "^10.0.2",
|
82
|
+
"husky": ">=6",
|
83
|
+
"lint-staged": ">=10",
|
84
|
+
"mocha": "^5.2.0",
|
85
|
+
"mock-fs": "^5.1.2",
|
86
|
+
"nock": "^13.2.2",
|
87
|
+
"nyc": "^14.1.1",
|
88
|
+
"pre-commit": "^1.2.2",
|
89
|
+
"prettier": "^2.4.1",
|
90
|
+
"ts-node": "^8",
|
91
|
+
"typescript": "^5.6.2"
|
92
|
+
},
|
93
|
+
"engines": {
|
94
|
+
"node": ">=14.0.0"
|
95
|
+
},
|
96
|
+
"files": [
|
97
|
+
"/bin",
|
98
|
+
"/npm-shrinkwrap.json",
|
99
|
+
"/oclif.manifest.json",
|
100
|
+
"/src",
|
101
|
+
"/lib"
|
102
|
+
],
|
103
|
+
"homepage": "https://github.com/learnpack/learnpack-cli",
|
104
|
+
"keywords": [
|
105
|
+
"oclif"
|
106
|
+
],
|
107
|
+
"license": "UNLICENSED",
|
108
|
+
"main": "lib/index.js",
|
109
|
+
"types": "lib/index.d.ts",
|
110
|
+
"oclif": {
|
111
|
+
"commands": "./lib/commands",
|
112
|
+
"bin": "learnpack",
|
113
|
+
"plugins": [
|
114
|
+
"@oclif/plugin-help",
|
115
|
+
"@oclif/plugin-plugins",
|
116
|
+
"@oclif/plugin-warn-if-update-available"
|
117
|
+
],
|
118
|
+
"permanent_plugins": [
|
119
|
+
"@oclif/plugin-help",
|
120
|
+
"@oclif/plugin-plugins",
|
121
|
+
"@oclif/plugin-warn-if-update-available"
|
122
|
+
]
|
123
|
+
},
|
124
|
+
"repository": {
|
125
|
+
"type": "git",
|
126
|
+
"url": "git+https://github.com/learnpack/learnpack-cli.git"
|
127
|
+
},
|
128
|
+
"pre-commit": {
|
129
|
+
"silent": true,
|
130
|
+
"run": [
|
131
|
+
"pre"
|
132
|
+
]
|
133
|
+
},
|
134
|
+
"scripts": {
|
135
|
+
"tsc": "tsc -b",
|
136
|
+
"postpack": "rm -f oclif.manifest.json && eslint . --ext .ts --config .eslintrc",
|
137
|
+
"prepack": "rm -rf lib && tsc -b && oclif-dev manifest && oclif-dev readme",
|
138
|
+
"pre": "node ./test/precommit/index.ts",
|
139
|
+
"test": "NODE_ENV=test nyc --extension .ts mocha --forbid-only \"test/**/*.test.ts\"",
|
140
|
+
"version": "oclif-dev readme && git add README.md",
|
141
|
+
"prepare": "husky install"
|
142
|
+
},
|
143
|
+
"lint-staged": {
|
144
|
+
"*.{js,ts}": [
|
145
|
+
"eslint --cache --fix"
|
146
|
+
],
|
147
|
+
"*.{js,css,md,ts}": "prettier --write"
|
148
|
+
},
|
149
|
+
"directories": {
|
150
|
+
"test": "test"
|
151
|
+
}
|
152
|
+
}
|
package/src/commands/init.ts
CHANGED
@@ -19,7 +19,7 @@ import {
|
|
19
19
|
downloadImage,
|
20
20
|
generateCourseIntroduction,
|
21
21
|
} from "../utils/rigoActions"
|
22
|
-
|
22
|
+
import { getConsumables } from "../utils/api"
|
23
23
|
const slugify = (text: string) => {
|
24
24
|
return text
|
25
25
|
.toString()
|
@@ -53,6 +53,25 @@ function getFilenameFromUrl(url: string) {
|
|
53
53
|
return path.basename(url)
|
54
54
|
}
|
55
55
|
|
56
|
+
const makePackageInfo = (choices: any) => {
|
57
|
+
const packageInfo = {
|
58
|
+
grading: choices.grading,
|
59
|
+
difficulty: choices.difficulty,
|
60
|
+
duration: parseInt(choices.duration),
|
61
|
+
description: {
|
62
|
+
us: choices.description,
|
63
|
+
},
|
64
|
+
title: {
|
65
|
+
us: choices.title,
|
66
|
+
},
|
67
|
+
slug: choices.title
|
68
|
+
.toLowerCase()
|
69
|
+
.replace(/ /g, "-")
|
70
|
+
.replace(/[^\w-]+/g, ""),
|
71
|
+
}
|
72
|
+
return packageInfo
|
73
|
+
}
|
74
|
+
|
56
75
|
async function createPreviewReadme(
|
57
76
|
tutorialDir: string,
|
58
77
|
packageInfo: PackageInfo,
|
@@ -81,7 +100,9 @@ type PackageInfo = {
|
|
81
100
|
}
|
82
101
|
|
83
102
|
const handleAILogic = async (tutorialDir: string, packageInfo: PackageInfo) => {
|
84
|
-
Console.info(
|
103
|
+
Console.info(
|
104
|
+
"Almost there! First you need to login with 4Geeks.com to use AI Generation tool for creators. You can create a new account here: https://4geeks.com/creators"
|
105
|
+
)
|
85
106
|
|
86
107
|
fs.removeSync(path.join(tutorialDir, "exercises", "01-hello-world"))
|
87
108
|
|
@@ -115,12 +136,23 @@ const handleAILogic = async (tutorialDir: string, packageInfo: PackageInfo) => {
|
|
115
136
|
|
116
137
|
const rigoToken = sessionPayload.rigobot.key
|
117
138
|
|
139
|
+
const consumables = await getConsumables(sessionPayload.token)
|
140
|
+
|
141
|
+
if (consumables.ai_tutorial_generation === 0) {
|
142
|
+
Console.error(
|
143
|
+
"It seems you cannot generate tutorials with AI. Make sure you creator subscription is up to date here: https://4geeks.com/profile/subscriptions?token=" +
|
144
|
+
sessionPayload.token +
|
145
|
+
". If you believe there is an issue you can always contact support@4geeks.com"
|
146
|
+
)
|
147
|
+
process.exit(1)
|
148
|
+
}
|
149
|
+
|
118
150
|
const isCreator = await hasCreatorPermission(rigoToken)
|
119
151
|
if (!isCreator) {
|
120
152
|
Console.error(
|
121
153
|
"👀 Oops! You need to be a creator to use our specialized AI. Please contact support"
|
122
154
|
)
|
123
|
-
|
155
|
+
process.exit(1)
|
124
156
|
}
|
125
157
|
|
126
158
|
Console.success("🎉 Let's begin this learning journey!")
|
@@ -236,6 +268,91 @@ const handleAILogic = async (tutorialDir: string, packageInfo: PackageInfo) => {
|
|
236
268
|
return true
|
237
269
|
}
|
238
270
|
|
271
|
+
const getChoices = async (empty: boolean) => {
|
272
|
+
const defaultChoices = {
|
273
|
+
title: "My Interactive Tutorial",
|
274
|
+
description: "",
|
275
|
+
difficulty: "beginner",
|
276
|
+
duration: 1,
|
277
|
+
useAI: "no",
|
278
|
+
grading: "isolated",
|
279
|
+
}
|
280
|
+
|
281
|
+
if (empty) {
|
282
|
+
return defaultChoices
|
283
|
+
}
|
284
|
+
|
285
|
+
const choices = await prompts([
|
286
|
+
{
|
287
|
+
type: "select",
|
288
|
+
name: "grading",
|
289
|
+
message: "Is the auto-grading going to be isolated or incremental?",
|
290
|
+
choices: [
|
291
|
+
{
|
292
|
+
title: "Incremental: Build on top of each other like a tutorial",
|
293
|
+
value: "incremental",
|
294
|
+
},
|
295
|
+
{ title: "Isolated: Small separated exercises", value: "isolated" },
|
296
|
+
{
|
297
|
+
title: "No grading: No feedback or testing whatsoever",
|
298
|
+
value: null,
|
299
|
+
},
|
300
|
+
],
|
301
|
+
},
|
302
|
+
{
|
303
|
+
type: "text",
|
304
|
+
name: "title",
|
305
|
+
initial: "My Interactive Tutorial",
|
306
|
+
message: "Title for your tutorial? Press enter to leave as it is",
|
307
|
+
},
|
308
|
+
{
|
309
|
+
type: "text",
|
310
|
+
name: "description",
|
311
|
+
initial: "",
|
312
|
+
message: "Description for your tutorial? Press enter to leave blank",
|
313
|
+
},
|
314
|
+
{
|
315
|
+
type: "select",
|
316
|
+
name: "difficulty",
|
317
|
+
message: "How difficulty will be to complete the tutorial?",
|
318
|
+
choices: [
|
319
|
+
{ title: "Begginer (no previous experience)", value: "beginner" },
|
320
|
+
{ title: "Easy (just a bit of experience required)", value: "easy" },
|
321
|
+
{
|
322
|
+
title: "Intermediate (you need experience)",
|
323
|
+
value: "intermediate",
|
324
|
+
},
|
325
|
+
{ title: "Hard (master the topic)", value: "hard" },
|
326
|
+
],
|
327
|
+
},
|
328
|
+
{
|
329
|
+
type: "text",
|
330
|
+
name: "duration",
|
331
|
+
initial: "1",
|
332
|
+
message: "How many hours avg it takes to complete (number)?",
|
333
|
+
validate: (value: string) => {
|
334
|
+
const n = Math.floor(Number(value))
|
335
|
+
return n !== Number.POSITIVE_INFINITY && String(n) === value && n >= 0
|
336
|
+
},
|
337
|
+
},
|
338
|
+
{
|
339
|
+
type: "select",
|
340
|
+
name: "useAI",
|
341
|
+
message:
|
342
|
+
"Want a little bit of AI magic to help you? Our AI can craft the tutorial for you",
|
343
|
+
choices: [
|
344
|
+
{
|
345
|
+
title: "Yes, please help me",
|
346
|
+
value: "yes",
|
347
|
+
},
|
348
|
+
{ title: "No, thanks, I prefer to do it manually", value: "no" },
|
349
|
+
],
|
350
|
+
},
|
351
|
+
])
|
352
|
+
|
353
|
+
return choices
|
354
|
+
}
|
355
|
+
|
239
356
|
class InitComand extends BaseCommand {
|
240
357
|
static description =
|
241
358
|
"Create a new learning package: Book, Tutorial or Exercise"
|
@@ -250,89 +367,9 @@ class InitComand extends BaseCommand {
|
|
250
367
|
|
251
368
|
await alreadyInitialized()
|
252
369
|
|
253
|
-
const choices = await
|
254
|
-
|
255
|
-
|
256
|
-
name: "grading",
|
257
|
-
message: "Is the auto-grading going to be isolated or incremental?",
|
258
|
-
choices: [
|
259
|
-
{
|
260
|
-
title: "Incremental: Build on top of each other like a tutorial",
|
261
|
-
value: "incremental",
|
262
|
-
},
|
263
|
-
{ title: "Isolated: Small separated exercises", value: "isolated" },
|
264
|
-
{
|
265
|
-
title: "No grading: No feedback or testing whatsoever",
|
266
|
-
value: null,
|
267
|
-
},
|
268
|
-
],
|
269
|
-
},
|
270
|
-
{
|
271
|
-
type: "text",
|
272
|
-
name: "title",
|
273
|
-
initial: "My Interactive Tutorial",
|
274
|
-
message: "Title for your tutorial? Press enter to leave as it is",
|
275
|
-
},
|
276
|
-
{
|
277
|
-
type: "text",
|
278
|
-
name: "description",
|
279
|
-
initial: "",
|
280
|
-
message: "Description for your tutorial? Press enter to leave blank",
|
281
|
-
},
|
282
|
-
{
|
283
|
-
type: "select",
|
284
|
-
name: "difficulty",
|
285
|
-
message: "How difficulty will be to complete the tutorial?",
|
286
|
-
choices: [
|
287
|
-
{ title: "Begginer (no previous experience)", value: "beginner" },
|
288
|
-
{ title: "Easy (just a bit of experience required)", value: "easy" },
|
289
|
-
{
|
290
|
-
title: "Intermediate (you need experience)",
|
291
|
-
value: "intermediate",
|
292
|
-
},
|
293
|
-
{ title: "Hard (master the topic)", value: "hard" },
|
294
|
-
],
|
295
|
-
},
|
296
|
-
{
|
297
|
-
type: "text",
|
298
|
-
name: "duration",
|
299
|
-
initial: "1",
|
300
|
-
message: "How many hours avg it takes to complete (number)?",
|
301
|
-
validate: (value: string) => {
|
302
|
-
const n = Math.floor(Number(value))
|
303
|
-
return n !== Number.POSITIVE_INFINITY && String(n) === value && n >= 0
|
304
|
-
},
|
305
|
-
},
|
306
|
-
{
|
307
|
-
type: "select",
|
308
|
-
name: "useAI",
|
309
|
-
message:
|
310
|
-
"Want a little bit of AI magic to help you? Our AI can craft the tutorial for you",
|
311
|
-
choices: [
|
312
|
-
{
|
313
|
-
title: "Yes, please help me",
|
314
|
-
value: "yes",
|
315
|
-
},
|
316
|
-
{ title: "No, thanks, I prefer to do it manually", value: "no" },
|
317
|
-
],
|
318
|
-
},
|
319
|
-
])
|
320
|
-
|
321
|
-
const packageInfo = {
|
322
|
-
grading: choices.grading,
|
323
|
-
difficulty: choices.difficulty,
|
324
|
-
duration: parseInt(choices.duration),
|
325
|
-
description: {
|
326
|
-
us: choices.description,
|
327
|
-
},
|
328
|
-
title: {
|
329
|
-
us: choices.title,
|
330
|
-
},
|
331
|
-
slug: choices.title
|
332
|
-
.toLowerCase()
|
333
|
-
.replace(/ /g, "-")
|
334
|
-
.replace(/[^\w-]+/g, ""),
|
335
|
-
}
|
370
|
+
const choices = await getChoices(flags.yes)
|
371
|
+
|
372
|
+
const packageInfo = makePackageInfo(choices)
|
336
373
|
|
337
374
|
const tutorialDir = `./${packageInfo.slug}`
|
338
375
|
fs.ensureDirSync(tutorialDir)
|
@@ -354,26 +391,26 @@ class InitComand extends BaseCommand {
|
|
354
391
|
// Creating README files
|
355
392
|
for (const language of languages) {
|
356
393
|
const readmeFilename = `README${language !== "en" ? `.${language}` : ""}`
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
394
|
+
const readmeTemplatePath = path.resolve(
|
395
|
+
templatesDir,
|
396
|
+
`${readmeFilename}.ejs`
|
397
|
+
)
|
398
|
+
|
399
|
+
const readmeObject = {
|
400
|
+
title: packageInfo.title.us,
|
401
|
+
description: packageInfo.description.us,
|
402
|
+
grading: packageInfo.grading,
|
403
|
+
difficulty: packageInfo.difficulty,
|
404
|
+
duration: packageInfo.duration,
|
405
|
+
}
|
406
|
+
const readmeContent = eta.render(
|
407
|
+
fs.readFileSync(readmeTemplatePath, "utf-8"),
|
408
|
+
readmeObject
|
409
|
+
)
|
410
|
+
fs.writeFileSync(
|
411
|
+
path.join(tutorialDir, `${readmeFilename}.md`),
|
412
|
+
readmeContent
|
413
|
+
)
|
377
414
|
if (fs.existsSync(path.join(tutorialDir, `${readmeFilename}.ejs`)))
|
378
415
|
fs.removeSync(path.join(tutorialDir, `${readmeFilename}.ejs`))
|
379
416
|
}
|
@@ -398,6 +435,7 @@ class InitComand extends BaseCommand {
|
|
398
435
|
Console.help(
|
399
436
|
`Start the exercises by running the following command on your terminal: $ learnpack start`
|
400
437
|
)
|
438
|
+
process.exit(0)
|
401
439
|
}
|
402
440
|
}
|
403
441
|
|