docula 0.13.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/docula.js +215 -159
- package/package.json +15 -13
- package/template/css/landing.css +36 -0
package/dist/docula.js
CHANGED
|
@@ -1,100 +1,21 @@
|
|
|
1
1
|
// src/docula.ts
|
|
2
|
+
import fs3 from "fs";
|
|
2
3
|
import http from "http";
|
|
3
4
|
import path3 from "path";
|
|
4
5
|
import process4 from "process";
|
|
5
|
-
import fs3 from "fs";
|
|
6
6
|
import handler from "serve-handler";
|
|
7
7
|
import updateNotifier from "update-notifier";
|
|
8
8
|
|
|
9
|
-
// src/
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
*/
|
|
16
|
-
templatePath = path.join(import.meta.url, "../../template").replace("file:", "");
|
|
17
|
-
/**
|
|
18
|
-
* Path to the output directory
|
|
19
|
-
*/
|
|
20
|
-
outputPath = path.join(process.cwd(), "./dist");
|
|
21
|
-
/**
|
|
22
|
-
* Path to the site directory
|
|
23
|
-
*/
|
|
24
|
-
sitePath = path.join(process.cwd(), "./site");
|
|
25
|
-
/**
|
|
26
|
-
* Path to the github repository
|
|
27
|
-
*/
|
|
28
|
-
githubPath = "jaredwray/docula";
|
|
29
|
-
/**
|
|
30
|
-
* Site title
|
|
31
|
-
*/
|
|
32
|
-
siteTitle = "docula";
|
|
33
|
-
/**
|
|
34
|
-
* Site description
|
|
35
|
-
*/
|
|
36
|
-
siteDescription = "Beautiful Website for Your Projects";
|
|
37
|
-
/**
|
|
38
|
-
* Site URL
|
|
39
|
-
*/
|
|
40
|
-
siteUrl = "https://docula.org";
|
|
41
|
-
/**
|
|
42
|
-
* Port to run the server
|
|
43
|
-
*/
|
|
44
|
-
port = 3e3;
|
|
45
|
-
/**
|
|
46
|
-
* Single page website
|
|
47
|
-
*/
|
|
48
|
-
singlePage = true;
|
|
49
|
-
/**
|
|
50
|
-
* Sections
|
|
51
|
-
*/
|
|
52
|
-
sections;
|
|
53
|
-
constructor(options) {
|
|
54
|
-
if (options) {
|
|
55
|
-
this.parseOptions(options);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
parseOptions(options) {
|
|
59
|
-
if (options.templatePath) {
|
|
60
|
-
this.templatePath = options.templatePath;
|
|
61
|
-
this.templatePath = path.join(process.cwd(), this.templatePath);
|
|
62
|
-
}
|
|
63
|
-
if (options.outputPath) {
|
|
64
|
-
this.outputPath = options.outputPath;
|
|
65
|
-
this.githubPath = path.join(process.cwd(), this.outputPath);
|
|
66
|
-
}
|
|
67
|
-
if (options.sitePath) {
|
|
68
|
-
this.sitePath = options.sitePath;
|
|
69
|
-
this.sitePath = path.join(process.cwd(), this.sitePath);
|
|
70
|
-
}
|
|
71
|
-
if (options.githubPath) {
|
|
72
|
-
this.githubPath = options.githubPath;
|
|
73
|
-
}
|
|
74
|
-
if (options.siteTitle) {
|
|
75
|
-
this.siteTitle = options.siteTitle;
|
|
76
|
-
}
|
|
77
|
-
if (options.siteDescription) {
|
|
78
|
-
this.siteDescription = options.siteDescription;
|
|
79
|
-
}
|
|
80
|
-
if (options.siteUrl) {
|
|
81
|
-
this.siteUrl = options.siteUrl;
|
|
82
|
-
}
|
|
83
|
-
if (options.sections) {
|
|
84
|
-
this.sections = options.sections;
|
|
85
|
-
}
|
|
86
|
-
if (options.port) {
|
|
87
|
-
this.port = options.port;
|
|
88
|
-
}
|
|
89
|
-
if (options.singlePage !== void 0 && typeof options.singlePage === "boolean") {
|
|
90
|
-
this.singlePage = options.singlePage;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
};
|
|
9
|
+
// src/builder.ts
|
|
10
|
+
import fs from "fs";
|
|
11
|
+
import * as cheerio from "cheerio";
|
|
12
|
+
import { Ecto } from "ecto";
|
|
13
|
+
import he from "he";
|
|
14
|
+
import { Writr } from "writr";
|
|
94
15
|
|
|
95
16
|
// src/console.ts
|
|
96
|
-
import
|
|
97
|
-
import
|
|
17
|
+
import path from "path";
|
|
18
|
+
import process from "process";
|
|
98
19
|
var DoculaConsole = class {
|
|
99
20
|
log(message) {
|
|
100
21
|
console.log(message);
|
|
@@ -110,21 +31,29 @@ var DoculaConsole = class {
|
|
|
110
31
|
console.log();
|
|
111
32
|
console.log(" Commands:");
|
|
112
33
|
console.log(" init Initialize a new project");
|
|
113
|
-
console.log(
|
|
34
|
+
console.log(
|
|
35
|
+
" build Build the project. By default just npx docula will build the project if it finds a ./site folder"
|
|
36
|
+
);
|
|
114
37
|
console.log(" serve Serve the project as a local website");
|
|
115
38
|
console.log(" help Print this help");
|
|
116
39
|
console.log(" version Print the version");
|
|
117
40
|
console.log();
|
|
118
41
|
console.log(" Arguments Build:");
|
|
119
42
|
console.log(" -w, --watch watch for changes and rebuild");
|
|
120
|
-
console.log(
|
|
121
|
-
|
|
43
|
+
console.log(
|
|
44
|
+
" -s, --site Set the path where site files are located"
|
|
45
|
+
);
|
|
46
|
+
console.log(
|
|
47
|
+
" -o, --outputPath Set the output directory. Default is ./site/dist"
|
|
48
|
+
);
|
|
122
49
|
console.log(" -t, --templatePath Set the custom template to use");
|
|
123
50
|
console.log();
|
|
124
51
|
console.log(" Arguments serve:");
|
|
125
52
|
console.log(" -p, --port Set the port number used with serve");
|
|
126
53
|
console.log(" -w, --watch watch for changes and rebuild");
|
|
127
|
-
console.log(
|
|
54
|
+
console.log(
|
|
55
|
+
" -s, --site Set the path where site files are located"
|
|
56
|
+
);
|
|
128
57
|
}
|
|
129
58
|
parseProcessArgv(argv) {
|
|
130
59
|
const command = this.getCommand(argv);
|
|
@@ -136,32 +65,25 @@ var DoculaConsole = class {
|
|
|
136
65
|
};
|
|
137
66
|
}
|
|
138
67
|
getCommand(argv) {
|
|
139
|
-
let result;
|
|
140
68
|
for (const argument of argv) {
|
|
141
69
|
switch (argument) {
|
|
142
70
|
case "init": {
|
|
143
|
-
|
|
144
|
-
break;
|
|
71
|
+
return "init";
|
|
145
72
|
}
|
|
146
73
|
case "build": {
|
|
147
|
-
|
|
148
|
-
break;
|
|
74
|
+
return "build";
|
|
149
75
|
}
|
|
150
76
|
case "serve": {
|
|
151
|
-
|
|
152
|
-
break;
|
|
77
|
+
return "serve";
|
|
153
78
|
}
|
|
154
79
|
case "help": {
|
|
155
|
-
|
|
156
|
-
break;
|
|
80
|
+
return "help";
|
|
157
81
|
}
|
|
158
82
|
case "version": {
|
|
159
|
-
|
|
160
|
-
break;
|
|
83
|
+
return "version";
|
|
161
84
|
}
|
|
162
85
|
}
|
|
163
86
|
}
|
|
164
|
-
return result;
|
|
165
87
|
}
|
|
166
88
|
getArguments(argv) {
|
|
167
89
|
const arguments_ = {
|
|
@@ -185,7 +107,7 @@ var DoculaConsole = class {
|
|
|
185
107
|
case "-o":
|
|
186
108
|
case "--output": {
|
|
187
109
|
arguments_.output = argv[i + 1];
|
|
188
|
-
arguments_.output =
|
|
110
|
+
arguments_.output = path.join(process.cwd(), arguments_.output);
|
|
189
111
|
break;
|
|
190
112
|
}
|
|
191
113
|
case "-w":
|
|
@@ -196,13 +118,16 @@ var DoculaConsole = class {
|
|
|
196
118
|
case "-s":
|
|
197
119
|
case "--site": {
|
|
198
120
|
arguments_.sitePath = argv[i + 1];
|
|
199
|
-
arguments_.sitePath =
|
|
121
|
+
arguments_.sitePath = path.join(process.cwd(), arguments_.sitePath);
|
|
200
122
|
break;
|
|
201
123
|
}
|
|
202
124
|
case "-t":
|
|
203
125
|
case "--templatePath": {
|
|
204
126
|
arguments_.templatePath = argv[i + 1];
|
|
205
|
-
arguments_.templatePath =
|
|
127
|
+
arguments_.templatePath = path.join(
|
|
128
|
+
process.cwd(),
|
|
129
|
+
arguments_.templatePath
|
|
130
|
+
);
|
|
206
131
|
break;
|
|
207
132
|
}
|
|
208
133
|
}
|
|
@@ -211,15 +136,8 @@ var DoculaConsole = class {
|
|
|
211
136
|
}
|
|
212
137
|
};
|
|
213
138
|
|
|
214
|
-
// src/builder.ts
|
|
215
|
-
import fs from "fs";
|
|
216
|
-
import { Ecto } from "ecto";
|
|
217
|
-
import { Writr } from "writr";
|
|
218
|
-
import he from "he";
|
|
219
|
-
import * as cheerio from "cheerio";
|
|
220
|
-
|
|
221
139
|
// src/github.ts
|
|
222
|
-
import
|
|
140
|
+
import process2 from "process";
|
|
223
141
|
import axios from "axios";
|
|
224
142
|
var Github = class {
|
|
225
143
|
options = {
|
|
@@ -239,21 +157,20 @@ var Github = class {
|
|
|
239
157
|
data.contributors = await this.getContributors();
|
|
240
158
|
return data;
|
|
241
159
|
}
|
|
160
|
+
// biome-ignore lint/suspicious/noExplicitAny: need to fix
|
|
242
161
|
async getReleases() {
|
|
243
162
|
const url = `${this.options.api}/repos/${this.options.author}/${this.options.repo}/releases`;
|
|
244
|
-
let
|
|
245
|
-
if (
|
|
246
|
-
|
|
163
|
+
let config = {};
|
|
164
|
+
if (process2.env.GITHUB_TOKEN) {
|
|
165
|
+
config = {
|
|
247
166
|
headers: {
|
|
248
|
-
|
|
249
|
-
Authorization: `Bearer ${process3.env.GITHUB_TOKEN}`,
|
|
250
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
167
|
+
Authorization: `Bearer ${process2.env.GITHUB_TOKEN}`,
|
|
251
168
|
Accept: "application/vnd.github.v3+json"
|
|
252
169
|
}
|
|
253
170
|
};
|
|
254
171
|
}
|
|
255
172
|
try {
|
|
256
|
-
const result = await axios.get(url,
|
|
173
|
+
const result = await axios.get(url, config);
|
|
257
174
|
if (result && result.data.length > 0) {
|
|
258
175
|
return this.addAnchorLink(result.data);
|
|
259
176
|
}
|
|
@@ -261,33 +178,36 @@ var Github = class {
|
|
|
261
178
|
} catch (error) {
|
|
262
179
|
const typedError = error;
|
|
263
180
|
if (typedError.response?.status === 404) {
|
|
264
|
-
throw new Error(
|
|
181
|
+
throw new Error(
|
|
182
|
+
`Repository ${this.options.author}/${this.options.repo} not found.`
|
|
183
|
+
);
|
|
265
184
|
}
|
|
266
185
|
throw error;
|
|
267
186
|
}
|
|
268
187
|
}
|
|
188
|
+
// biome-ignore lint/suspicious/noExplicitAny: need to fix
|
|
269
189
|
async getContributors() {
|
|
270
190
|
const url = `${this.options.api}/repos/${this.options.author}/${this.options.repo}/contributors`;
|
|
271
|
-
let
|
|
272
|
-
if (
|
|
273
|
-
|
|
191
|
+
let config = {};
|
|
192
|
+
if (process2.env.GITHUB_TOKEN) {
|
|
193
|
+
config = {
|
|
274
194
|
headers: {
|
|
275
|
-
|
|
276
|
-
Authorization: `Bearer ${process3.env.GITHUB_TOKEN}`,
|
|
277
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
195
|
+
Authorization: `Bearer ${process2.env.GITHUB_TOKEN}`,
|
|
278
196
|
Accept: "application/vnd.github.v3+json"
|
|
279
197
|
}
|
|
280
198
|
};
|
|
281
199
|
}
|
|
282
200
|
try {
|
|
283
|
-
const result = await axios.get(url,
|
|
201
|
+
const result = await axios.get(url, config);
|
|
284
202
|
if (result && result.data.length > 0) {
|
|
285
203
|
return result.data;
|
|
286
204
|
}
|
|
287
205
|
} catch (error) {
|
|
288
206
|
const typedError = error;
|
|
289
207
|
if (typedError.response?.status === 404) {
|
|
290
|
-
throw new Error(
|
|
208
|
+
throw new Error(
|
|
209
|
+
`Repository ${this.options.author}/${this.options.repo} not found.`
|
|
210
|
+
);
|
|
291
211
|
}
|
|
292
212
|
throw error;
|
|
293
213
|
}
|
|
@@ -299,6 +219,7 @@ var Github = class {
|
|
|
299
219
|
this.options.author = options.author;
|
|
300
220
|
this.options.repo = options.repo;
|
|
301
221
|
}
|
|
222
|
+
// biome-ignore lint/suspicious/noExplicitAny: need to fix
|
|
302
223
|
addAnchorLink(data) {
|
|
303
224
|
return data.map((release) => {
|
|
304
225
|
const regex = /(?<!]\()(https:\/\/[\w./]+)(?!\))/g;
|
|
@@ -308,11 +229,99 @@ var Github = class {
|
|
|
308
229
|
}
|
|
309
230
|
};
|
|
310
231
|
|
|
232
|
+
// src/options.ts
|
|
233
|
+
import path2 from "path";
|
|
234
|
+
import process3 from "process";
|
|
235
|
+
var DoculaOptions = class {
|
|
236
|
+
/**
|
|
237
|
+
* Path to the template directory
|
|
238
|
+
*/
|
|
239
|
+
templatePath = path2.join(import.meta.url, "../../template").replace("file:", "");
|
|
240
|
+
/**
|
|
241
|
+
* Path to the output directory
|
|
242
|
+
*/
|
|
243
|
+
outputPath = path2.join(process3.cwd(), "./dist");
|
|
244
|
+
/**
|
|
245
|
+
* Path to the site directory
|
|
246
|
+
*/
|
|
247
|
+
sitePath = path2.join(process3.cwd(), "./site");
|
|
248
|
+
/**
|
|
249
|
+
* Path to the github repository
|
|
250
|
+
*/
|
|
251
|
+
githubPath = "jaredwray/docula";
|
|
252
|
+
/**
|
|
253
|
+
* Site title
|
|
254
|
+
*/
|
|
255
|
+
siteTitle = "docula";
|
|
256
|
+
/**
|
|
257
|
+
* Site description
|
|
258
|
+
*/
|
|
259
|
+
siteDescription = "Beautiful Website for Your Projects";
|
|
260
|
+
/**
|
|
261
|
+
* Site URL
|
|
262
|
+
*/
|
|
263
|
+
siteUrl = "https://docula.org";
|
|
264
|
+
/**
|
|
265
|
+
* Port to run the server
|
|
266
|
+
*/
|
|
267
|
+
port = 3e3;
|
|
268
|
+
/**
|
|
269
|
+
* Single page website
|
|
270
|
+
*/
|
|
271
|
+
singlePage = true;
|
|
272
|
+
/**
|
|
273
|
+
* Sections
|
|
274
|
+
*/
|
|
275
|
+
sections;
|
|
276
|
+
constructor(options) {
|
|
277
|
+
if (options) {
|
|
278
|
+
this.parseOptions(options);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
// biome-ignore lint/suspicious/noExplicitAny: need to fix
|
|
282
|
+
parseOptions(options) {
|
|
283
|
+
if (options.templatePath) {
|
|
284
|
+
this.templatePath = options.templatePath;
|
|
285
|
+
this.templatePath = path2.join(process3.cwd(), this.templatePath);
|
|
286
|
+
}
|
|
287
|
+
if (options.outputPath) {
|
|
288
|
+
this.outputPath = options.outputPath;
|
|
289
|
+
this.githubPath = path2.join(process3.cwd(), this.outputPath);
|
|
290
|
+
}
|
|
291
|
+
if (options.sitePath) {
|
|
292
|
+
this.sitePath = options.sitePath;
|
|
293
|
+
this.sitePath = path2.join(process3.cwd(), this.sitePath);
|
|
294
|
+
}
|
|
295
|
+
if (options.githubPath) {
|
|
296
|
+
this.githubPath = options.githubPath;
|
|
297
|
+
}
|
|
298
|
+
if (options.siteTitle) {
|
|
299
|
+
this.siteTitle = options.siteTitle;
|
|
300
|
+
}
|
|
301
|
+
if (options.siteDescription) {
|
|
302
|
+
this.siteDescription = options.siteDescription;
|
|
303
|
+
}
|
|
304
|
+
if (options.siteUrl) {
|
|
305
|
+
this.siteUrl = options.siteUrl;
|
|
306
|
+
}
|
|
307
|
+
if (options.sections) {
|
|
308
|
+
this.sections = options.sections;
|
|
309
|
+
}
|
|
310
|
+
if (options.port) {
|
|
311
|
+
this.port = options.port;
|
|
312
|
+
}
|
|
313
|
+
if (options.singlePage !== void 0 && typeof options.singlePage === "boolean") {
|
|
314
|
+
this.singlePage = options.singlePage;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
|
|
311
319
|
// src/builder.ts
|
|
312
320
|
var DoculaBuilder = class {
|
|
313
321
|
_options = new DoculaOptions();
|
|
314
322
|
_ecto;
|
|
315
323
|
_console = new DoculaConsole();
|
|
324
|
+
// biome-ignore lint/suspicious/noExplicitAny: need to fix
|
|
316
325
|
constructor(options, engineOptions) {
|
|
317
326
|
if (options) {
|
|
318
327
|
this._options = options;
|
|
@@ -336,10 +345,19 @@ var DoculaBuilder = class {
|
|
|
336
345
|
sections: this.options.sections
|
|
337
346
|
};
|
|
338
347
|
doculaData.github = await this.getGithubData(this.options.githubPath);
|
|
339
|
-
doculaData.documents = this.getDocuments(
|
|
340
|
-
|
|
348
|
+
doculaData.documents = this.getDocuments(
|
|
349
|
+
`${doculaData.sitePath}/docs`,
|
|
350
|
+
doculaData
|
|
351
|
+
);
|
|
352
|
+
doculaData.sections = this.getSections(
|
|
353
|
+
`${doculaData.sitePath}/docs`,
|
|
354
|
+
this.options
|
|
355
|
+
);
|
|
341
356
|
doculaData.hasDocuments = doculaData.documents?.length > 0;
|
|
342
|
-
doculaData.templates = await this.getTemplates(
|
|
357
|
+
doculaData.templates = await this.getTemplates(
|
|
358
|
+
this.options,
|
|
359
|
+
doculaData.hasDocuments
|
|
360
|
+
);
|
|
343
361
|
await this.buildIndexPage(doculaData);
|
|
344
362
|
await this.buildReleasePage(doculaData);
|
|
345
363
|
await this.buildSiteMapPage(doculaData);
|
|
@@ -422,10 +440,7 @@ var DoculaBuilder = class {
|
|
|
422
440
|
if (releases) {
|
|
423
441
|
templates.releases = releases;
|
|
424
442
|
}
|
|
425
|
-
const documentPage = hasDocuments ? await this.getTemplateFile(
|
|
426
|
-
options.templatePath,
|
|
427
|
-
"docs"
|
|
428
|
-
) : void 0;
|
|
443
|
+
const documentPage = hasDocuments ? await this.getTemplateFile(options.templatePath, "docs") : void 0;
|
|
429
444
|
if (documentPage) {
|
|
430
445
|
templates.docPage = documentPage;
|
|
431
446
|
}
|
|
@@ -516,7 +531,11 @@ var DoculaBuilder = class {
|
|
|
516
531
|
`${data.sitePath}/README.md`,
|
|
517
532
|
"utf8"
|
|
518
533
|
);
|
|
519
|
-
htmlReadme = await this._ecto.render(
|
|
534
|
+
htmlReadme = await this._ecto.render(
|
|
535
|
+
readmeContent,
|
|
536
|
+
void 0,
|
|
537
|
+
"markdown"
|
|
538
|
+
);
|
|
520
539
|
}
|
|
521
540
|
return htmlReadme;
|
|
522
541
|
}
|
|
@@ -527,7 +546,9 @@ var DoculaBuilder = class {
|
|
|
527
546
|
data.sidebarItems = this.generateSidebarItems(data);
|
|
528
547
|
const promises = data.documents.map(async (document) => {
|
|
529
548
|
const folder = document.urlPath.split("/").slice(0, -1).join("/");
|
|
530
|
-
await fs.promises.mkdir(`${data.outputPath}/${folder}`, {
|
|
549
|
+
await fs.promises.mkdir(`${data.outputPath}/${folder}`, {
|
|
550
|
+
recursive: true
|
|
551
|
+
});
|
|
531
552
|
const slug = `${data.outputPath}${document.urlPath}`;
|
|
532
553
|
let documentContent = await this._ecto.renderFromFile(
|
|
533
554
|
documentsTemplate,
|
|
@@ -552,10 +573,18 @@ var DoculaBuilder = class {
|
|
|
552
573
|
order: document.order
|
|
553
574
|
});
|
|
554
575
|
} else {
|
|
555
|
-
const relativeFilePath = document.documentPath.replace(
|
|
556
|
-
|
|
576
|
+
const relativeFilePath = document.documentPath.replace(
|
|
577
|
+
`${data.sitePath}/docs/`,
|
|
578
|
+
""
|
|
579
|
+
);
|
|
580
|
+
const sectionPath = relativeFilePath.slice(
|
|
581
|
+
0,
|
|
582
|
+
Math.max(0, relativeFilePath.lastIndexOf("/"))
|
|
583
|
+
);
|
|
557
584
|
const documentSection = document.section ?? sectionPath;
|
|
558
|
-
const sectionIndex = sidebarItems.findIndex(
|
|
585
|
+
const sectionIndex = sidebarItems.findIndex(
|
|
586
|
+
(section) => section.path === documentSection
|
|
587
|
+
);
|
|
559
588
|
if (sectionIndex === -1) {
|
|
560
589
|
continue;
|
|
561
590
|
}
|
|
@@ -569,15 +598,23 @@ var DoculaBuilder = class {
|
|
|
569
598
|
}
|
|
570
599
|
sidebarItems = sidebarItems.map((section) => {
|
|
571
600
|
if (section.children) {
|
|
572
|
-
section.children.sort(
|
|
601
|
+
section.children.sort(
|
|
602
|
+
(a, b) => (
|
|
603
|
+
// biome-ignore lint/style/noNonNullAssertion: need to fix
|
|
604
|
+
(a.order ?? section.children.length) - // biome-ignore lint/style/noNonNullAssertion: need to fix
|
|
605
|
+
(b.order ?? section.children.length)
|
|
606
|
+
)
|
|
607
|
+
);
|
|
573
608
|
}
|
|
574
609
|
return section;
|
|
575
610
|
});
|
|
576
|
-
sidebarItems.sort(
|
|
611
|
+
sidebarItems.sort(
|
|
612
|
+
(a, b) => (a.order ?? sidebarItems.length) - (b.order ?? sidebarItems.length)
|
|
613
|
+
);
|
|
577
614
|
return sidebarItems;
|
|
578
615
|
}
|
|
579
616
|
getDocuments(sitePath, doculaData) {
|
|
580
|
-
let documents =
|
|
617
|
+
let documents = [];
|
|
581
618
|
if (fs.existsSync(sitePath)) {
|
|
582
619
|
documents = this.getDocumentInDirectory(sitePath);
|
|
583
620
|
doculaData.sections = this.getSections(sitePath, this.options);
|
|
@@ -590,7 +627,7 @@ var DoculaBuilder = class {
|
|
|
590
627
|
return documents;
|
|
591
628
|
}
|
|
592
629
|
getDocumentInDirectory(sitePath) {
|
|
593
|
-
const documents =
|
|
630
|
+
const documents = [];
|
|
594
631
|
const documentList = fs.readdirSync(sitePath);
|
|
595
632
|
if (documentList.length > 0) {
|
|
596
633
|
for (const document of documentList) {
|
|
@@ -602,11 +639,13 @@ var DoculaBuilder = class {
|
|
|
602
639
|
}
|
|
603
640
|
}
|
|
604
641
|
}
|
|
605
|
-
documents.sort(
|
|
642
|
+
documents.sort(
|
|
643
|
+
(a, b) => (a.order ?? documents.length) - (b.order ?? documents.length)
|
|
644
|
+
);
|
|
606
645
|
return documents;
|
|
607
646
|
}
|
|
608
647
|
getSections(sitePath, doculaOptions) {
|
|
609
|
-
const sections =
|
|
648
|
+
const sections = [];
|
|
610
649
|
if (fs.existsSync(sitePath)) {
|
|
611
650
|
const documentList = fs.readdirSync(sitePath);
|
|
612
651
|
if (documentList.length > 0) {
|
|
@@ -623,13 +662,17 @@ var DoculaBuilder = class {
|
|
|
623
662
|
}
|
|
624
663
|
}
|
|
625
664
|
}
|
|
626
|
-
sections.sort(
|
|
665
|
+
sections.sort(
|
|
666
|
+
(a, b) => (a.order ?? sections.length) - (b.order ?? sections.length)
|
|
667
|
+
);
|
|
627
668
|
}
|
|
628
669
|
return sections;
|
|
629
670
|
}
|
|
630
671
|
mergeSectionWithOptions(section, options) {
|
|
631
672
|
if (options.sections) {
|
|
632
|
-
const sectionOptions = options.sections.find(
|
|
673
|
+
const sectionOptions = options.sections.find(
|
|
674
|
+
(sectionOption) => sectionOption.path === section.path
|
|
675
|
+
);
|
|
633
676
|
if (sectionOptions) {
|
|
634
677
|
section.name = sectionOptions.name;
|
|
635
678
|
section.order = sectionOptions.order;
|
|
@@ -663,7 +706,11 @@ var DoculaBuilder = class {
|
|
|
663
706
|
keywords: matterData.keywords ?? [],
|
|
664
707
|
content: documentContent,
|
|
665
708
|
markdown: markdownContent,
|
|
666
|
-
generatedHtml: this._ecto.renderSync(
|
|
709
|
+
generatedHtml: this._ecto.renderSync(
|
|
710
|
+
markdownContent,
|
|
711
|
+
void 0,
|
|
712
|
+
"markdown"
|
|
713
|
+
),
|
|
667
714
|
tableOfContents: this.getTableOfContents(markdownContent),
|
|
668
715
|
documentPath,
|
|
669
716
|
urlPath,
|
|
@@ -750,6 +797,7 @@ var DoculaHelpers = class {
|
|
|
750
797
|
var Docula = class {
|
|
751
798
|
_options = new DoculaOptions();
|
|
752
799
|
_console = new DoculaConsole();
|
|
800
|
+
// biome-ignore lint/suspicious/noExplicitAny: need to fix
|
|
753
801
|
_configFileModule = {};
|
|
754
802
|
_server;
|
|
755
803
|
/**
|
|
@@ -788,6 +836,7 @@ var Docula = class {
|
|
|
788
836
|
* The config file module. This is the module that is loaded from the docula.config.mjs file
|
|
789
837
|
* @returns {any}
|
|
790
838
|
*/
|
|
839
|
+
// biome-ignore lint/suspicious/noExplicitAny: need to fix
|
|
791
840
|
get configFileModule() {
|
|
792
841
|
return this._configFileModule;
|
|
793
842
|
}
|
|
@@ -816,7 +865,10 @@ var Docula = class {
|
|
|
816
865
|
}
|
|
817
866
|
await this.loadConfigFile(this.options.sitePath);
|
|
818
867
|
if (this._configFileModule.options) {
|
|
819
|
-
this.options.parseOptions(
|
|
868
|
+
this.options.parseOptions(
|
|
869
|
+
// biome-ignore lint/suspicious/noExplicitAny: need to fix
|
|
870
|
+
this._configFileModule.options
|
|
871
|
+
);
|
|
820
872
|
}
|
|
821
873
|
if (this._configFileModule.onPrepare) {
|
|
822
874
|
try {
|
|
@@ -885,7 +937,9 @@ var Docula = class {
|
|
|
885
937
|
fs3.writeFileSync(`${sitePath}/favicon.ico`, faviconBuffer);
|
|
886
938
|
const variablesBuffer = Buffer.from(variablescss, "base64");
|
|
887
939
|
fs3.writeFileSync(`${sitePath}/variables.css`, variablesBuffer);
|
|
888
|
-
this._console.log(
|
|
940
|
+
this._console.log(
|
|
941
|
+
`docula initialized. Please update the ${doculaConfigFile} file with your site information. In addition, you can replace the image, favicon, and style the site with site.css file.`
|
|
942
|
+
);
|
|
889
943
|
}
|
|
890
944
|
/**
|
|
891
945
|
* Get the version of the package
|
|
@@ -920,13 +974,15 @@ var Docula = class {
|
|
|
920
974
|
}
|
|
921
975
|
const { port } = options;
|
|
922
976
|
const { outputPath } = options;
|
|
923
|
-
const
|
|
977
|
+
const config = {
|
|
924
978
|
public: outputPath
|
|
925
979
|
};
|
|
926
|
-
this._server = http.createServer(
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
980
|
+
this._server = http.createServer(
|
|
981
|
+
async (request, response) => (
|
|
982
|
+
/* c8 ignore next */
|
|
983
|
+
handler(request, response, config)
|
|
984
|
+
)
|
|
985
|
+
);
|
|
930
986
|
this._server.listen(port, () => {
|
|
931
987
|
this._console.log(`Docula \u{1F987} at http://localhost:${port}`);
|
|
932
988
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "docula",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "Beautiful Website for Your Projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/docula.js",
|
|
@@ -36,42 +36,44 @@
|
|
|
36
36
|
"scripts": {
|
|
37
37
|
"clean": "rimraf ./dist ./coverage ./node_modules ./package-lock.json ./yarn.lock ./pnpm-lock.yaml ./site/README.md ./site/dist",
|
|
38
38
|
"build": "pnpm generate-init-file && rimraf ./dist && tsup src/docula.ts --format esm --dts --clean",
|
|
39
|
-
"
|
|
40
|
-
"test": "
|
|
39
|
+
"lint": "biome check --write",
|
|
40
|
+
"test": "pnpm lint && vitest run --coverage",
|
|
41
|
+
"test:ci": "biome check && vitest run --coverage",
|
|
41
42
|
"generate-init-file": "tsx scripts/generate-init-file.ts",
|
|
42
43
|
"website:build": "rimraf ./site/README.md && node bin/docula.mjs build -s ./site -o ./site/dist",
|
|
43
44
|
"website:serve": "rimraf ./site/README.md && node bin/docula.mjs serve -s ./site -o ./site/dist",
|
|
45
|
+
"website:serve:mega": "rimraf ./test/fixtures/mega-page-site/dist && node bin/docula.mjs serve -s ./test/fixtures/mega-page-site",
|
|
44
46
|
"prepare": "pnpm build"
|
|
45
47
|
},
|
|
46
48
|
"bin": {
|
|
47
49
|
"docula": "./bin/docula.mjs"
|
|
48
50
|
},
|
|
49
51
|
"dependencies": {
|
|
50
|
-
"axios": "^1.
|
|
51
|
-
"cheerio": "^1.1.
|
|
52
|
-
"ecto": "^4.
|
|
52
|
+
"axios": "^1.11.0",
|
|
53
|
+
"cheerio": "^1.1.2",
|
|
54
|
+
"ecto": "^4.4.0",
|
|
53
55
|
"feed": "^5.1.0",
|
|
54
56
|
"he": "^1.2.0",
|
|
55
57
|
"serve-handler": "^6.1.6",
|
|
56
58
|
"update-notifier": "^7.3.1",
|
|
57
|
-
"writr": "^4.4.
|
|
59
|
+
"writr": "^4.4.6"
|
|
58
60
|
},
|
|
59
61
|
"devDependencies": {
|
|
62
|
+
"@biomejs/biome": "^2.2.0",
|
|
60
63
|
"@types/express": "^5.0.3",
|
|
61
64
|
"@types/he": "^1.2.3",
|
|
62
65
|
"@types/js-yaml": "^4.0.9",
|
|
63
|
-
"@types/node": "^24.0
|
|
66
|
+
"@types/node": "^24.3.0",
|
|
64
67
|
"@types/serve-handler": "^6.1.4",
|
|
65
68
|
"@types/update-notifier": "^6.0.8",
|
|
66
69
|
"@vitest/coverage-v8": "^3.2.4",
|
|
67
|
-
"dotenv": "^
|
|
70
|
+
"dotenv": "^17.2.1",
|
|
68
71
|
"rimraf": "^6.0.1",
|
|
69
72
|
"tsup": "^8.5.0",
|
|
70
|
-
"tsx": "^4.20.
|
|
71
|
-
"typescript": "^5.
|
|
73
|
+
"tsx": "^4.20.4",
|
|
74
|
+
"typescript": "^5.9.2",
|
|
72
75
|
"vitest": "^3.2.4",
|
|
73
|
-
"webpack": "^5.
|
|
74
|
-
"xo": "^1.1.0"
|
|
76
|
+
"webpack": "^5.101.3"
|
|
75
77
|
},
|
|
76
78
|
"xo": {
|
|
77
79
|
"rules": {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/* Landing */
|
|
2
|
+
.home-hero {
|
|
3
|
+
display: flex;
|
|
4
|
+
justify-content: center;
|
|
5
|
+
height: 20vh;
|
|
6
|
+
padding: 3rem 0 2.5rem;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
@media screen and (min-width: 768px) {
|
|
10
|
+
.home-hero {
|
|
11
|
+
height: 40vh;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.hero-container {
|
|
16
|
+
margin: 2rem auto 3rem;
|
|
17
|
+
max-width: 90%;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.home-container {
|
|
21
|
+
margin: 0 auto 3rem;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.home-container h1,
|
|
25
|
+
.hero-container h1 {
|
|
26
|
+
font-weight: 500;
|
|
27
|
+
font-size: 1.5rem;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.home-docs-button {
|
|
31
|
+
padding: 0.75rem 1.5rem;
|
|
32
|
+
border: 2px solid var(--color-secondary-dark);
|
|
33
|
+
border-radius: 0.5rem;
|
|
34
|
+
color: var(--color-secondary-dark);
|
|
35
|
+
font-weight: 600;
|
|
36
|
+
}
|