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 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/options.ts
10
- import path from "path";
11
- import process from "process";
12
- var DoculaOptions = class {
13
- /**
14
- * Path to the template directory
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 path2 from "path";
97
- import process2 from "process";
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(" build Build the project. By default just npx docula will build the project if it finds a ./site folder");
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(" -s, --site Set the path where site files are located");
121
- console.log(" -o, --outputPath Set the output directory. Default is ./site/dist");
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(" -s, --site Set the path where site files are located");
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
- result = "init";
144
- break;
71
+ return "init";
145
72
  }
146
73
  case "build": {
147
- result = "build";
148
- break;
74
+ return "build";
149
75
  }
150
76
  case "serve": {
151
- result = "serve";
152
- break;
77
+ return "serve";
153
78
  }
154
79
  case "help": {
155
- result = "help";
156
- break;
80
+ return "help";
157
81
  }
158
82
  case "version": {
159
- result = argument;
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 = path2.join(process2.cwd(), 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 = path2.join(process2.cwd(), 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 = path2.join(process2.cwd(), 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 process3 from "process";
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 config2 = {};
245
- if (process3.env.GITHUB_TOKEN) {
246
- config2 = {
163
+ let config = {};
164
+ if (process2.env.GITHUB_TOKEN) {
165
+ config = {
247
166
  headers: {
248
- // eslint-disable-next-line @typescript-eslint/naming-convention
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, config2);
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(`Repository ${this.options.author}/${this.options.repo} not found.`);
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 config2 = {};
272
- if (process3.env.GITHUB_TOKEN) {
273
- config2 = {
191
+ let config = {};
192
+ if (process2.env.GITHUB_TOKEN) {
193
+ config = {
274
194
  headers: {
275
- // eslint-disable-next-line @typescript-eslint/naming-convention
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, config2);
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(`Repository ${this.options.author}/${this.options.repo} not found.`);
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(`${doculaData.sitePath}/docs`, doculaData);
340
- doculaData.sections = this.getSections(`${doculaData.sitePath}/docs`, this.options);
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(this.options, doculaData.hasDocuments);
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(readmeContent, void 0, "markdown");
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}`, { recursive: true });
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(`${data.sitePath}/docs/`, "");
556
- const sectionPath = relativeFilePath.slice(0, Math.max(0, relativeFilePath.lastIndexOf("/")));
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((section) => section.path === documentSection);
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((a, b) => (a.order ?? section.children.length) - (b.order ?? section.children.length));
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((a, b) => (a.order ?? sidebarItems.length) - (b.order ?? sidebarItems.length));
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 = new Array();
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 = new Array();
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((a, b) => (a.order ?? documents.length) - (b.order ?? documents.length));
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 = new Array();
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((a, b) => (a.order ?? sections.length) - (b.order ?? sections.length));
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((sectionOption) => sectionOption.path === section.path);
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(markdownContent, void 0, "markdown"),
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(this._configFileModule.options);
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(`docula initialized. Please update the ${doculaConfigFile} file with your site information. In addition, you can replace the image, favicon, and stype the site with site.css file.`);
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 config2 = {
977
+ const config = {
924
978
  public: outputPath
925
979
  };
926
- this._server = http.createServer(async (request, response) => (
927
- /* c8 ignore next */
928
- handler(request, response, config2)
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.13.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
- "serve-mega": "rimraf ./test/fixtures/mega-page-site/dist && node bin/docula.mjs serve -s ./test/fixtures/mega-page-site",
40
- "test": "xo --fix && vitest run --coverage",
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.10.0",
51
- "cheerio": "^1.1.0",
52
- "ecto": "^4.3.0",
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.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.3",
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": "^16.5.0",
70
+ "dotenv": "^17.2.1",
68
71
  "rimraf": "^6.0.1",
69
72
  "tsup": "^8.5.0",
70
- "tsx": "^4.20.3",
71
- "typescript": "^5.8.3",
73
+ "tsx": "^4.20.4",
74
+ "typescript": "^5.9.2",
72
75
  "vitest": "^3.2.4",
73
- "webpack": "^5.99.9",
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
+ }