-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
131 lines (116 loc) · 3.79 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import fsExtra from "fs-extra";
import { exec } from "node:child_process";
import { readFile, writeFile, rmdir, mkdir } from "node:fs/promises";
import path from "node:path";
const TEMPLATE_DIR = "template";
const TUTORIALS_DIR = "tutorials";
const TUTORIALS_URL =
"https://raw.githubusercontent.com/solidjs/solid-docs-legacy/main/langs/en/tutorials";
function buildStackblitzMarkdown(tutorial) {
const file = tutorial.solution.files
.map((file) => `src/${file.nameWithExt}`)
.reverse()
.join(",");
return `[](https://stackblitz.com/github/edivados/solid-tutorials/tree/main/tutorials/${tutorial.internalName}?file=${file})`;
}
async function createTemplate(dir) {
if (await fsExtra.exists(dir)) {
await fsExtra.emptyDir(dir);
await rmdir(dir);
}
await new Promise((res, rej) => {
exec(`npm create vite@latest ${dir} -- --template solid`, (err) =>
err ? rej(err) : res()
);
});
await fsExtra.emptyDir(path.join(dir, "src"));
const publicDir = path.join(dir, "public");
await fsExtra.emptyDir(publicDir);
await fsExtra.rmdir(publicDir);
const indexHtmlPath = path.join(dir, "index.html");
await readFile(indexHtmlPath).then((content) =>
writeFile(
indexHtmlPath,
content
.toString()
.replace('id="root"', 'id="app"')
.replace("index.jsx", "main.jsx")
)
);
}
async function fetchTutorials(url) {
const tutorials = await fetch(`${url}/directory.json`).then((res) =>
res.json()
);
return Promise.all(
tutorials.map(async (tutorial) => {
const [solution, lesson] = await Promise.all([
fetch(`${url}/${tutorial.internalName}/solved.json`).then((res) =>
res.json()
),
fetch(`${url}/${tutorial.internalName}/lesson.md`).then((res) =>
res.text()
),
]);
tutorial.solution = solution;
tutorial.solution.files = tutorial.solution.files.map((file) => {
file.nameWithExt = `${file.name}.${file.type || "jsx"}`;
return file;
});
tutorial.lesson = lesson;
return tutorial;
})
);
}
async function createTutorial(tutorial, tutorialsDir, templateDir) {
const dir = path.join(tutorialsDir, tutorial.internalName);
await fsExtra.copy(templateDir, dir);
return Promise.all([
...tutorial.solution.files.map((file) =>
writeFile(path.join(dir, "src", file.nameWithExt), file.content)
),
readFile(path.join(dir, "package.json")).then((content) => {
const json = JSON.parse(content);
json["name"] = tutorial.internalName;
if (tutorial.internalName === "stores_immutable") {
json["dependencies"]["redux"] = "^4.2.1";
}
return writeFile(
path.join(dir, "package.json"),
JSON.stringify(json, null, 2)
);
}),
readFile(path.join(dir, "README.md")).then((content) =>
writeFile(
path.join(dir, "README.md"),
`${buildStackblitzMarkdown(tutorial)}\n\n## Lesson\n\n${
tutorial.lesson
}\n\n${content}`
)
),
]);
}
async function createTutorials(tutorials, tutorialsDir, templateDir) {
if (!(await fsExtra.exists(tutorialsDir))) await mkdir(tutorialsDir);
else await fsExtra.emptyDir(tutorialsDir);
return Promise.all(
tutorials.map((tutorial) =>
createTutorial(tutorial, tutorialsDir, templateDir)
)
);
}
await createTemplate(TEMPLATE_DIR);
const tutorials = await fetchTutorials(TUTORIALS_URL);
await createTutorials(tutorials, TUTORIALS_DIR, TEMPLATE_DIR);
await readFile("README.md").then((content) =>
writeFile(
"README.md",
tutorials.reduce(
(content, tutorial) =>
`${content}### ${tutorial.lessonName}\n${buildStackblitzMarkdown(
tutorial
)}\n`,
""
)
)
);