writr 1.9.12 → 2.0.1

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.
Files changed (133) hide show
  1. package/README.md +76 -135
  2. package/bin/writr.mjs +8 -0
  3. package/dist/builder.d.ts +33 -0
  4. package/dist/builder.js +181 -0
  5. package/dist/console.d.ts +22 -0
  6. package/dist/console.js +120 -0
  7. package/dist/github.d.ts +22 -0
  8. package/dist/github.js +74 -0
  9. package/dist/helpers/markdown.d.ts +10 -0
  10. package/dist/helpers/markdown.js +24 -0
  11. package/dist/helpers.d.ts +7 -0
  12. package/dist/helpers.js +58 -0
  13. package/dist/options.d.ts +12 -0
  14. package/dist/options.js +47 -0
  15. package/dist/writr.d.ts +23 -0
  16. package/dist/writr.js +153 -0
  17. package/init/favicon.svg +1 -0
  18. package/init/logo.png +0 -0
  19. package/init/variables.css +30 -0
  20. package/init/writr.config.cjs +10 -0
  21. package/package.json +44 -66
  22. package/template/css/highlight/highlight.min.js +1433 -0
  23. package/template/css/highlight/styles/base16/dracula.min.css +7 -0
  24. package/template/css/home.css +307 -0
  25. package/template/css/index.css +919 -0
  26. package/template/includes/footer.hbs +10 -0
  27. package/template/includes/header.hbs +17 -0
  28. package/template/includes/landing/content.hbs +63 -0
  29. package/template/includes/landing/hero.hbs +3 -0
  30. package/template/includes/scripts.hbs +4 -0
  31. package/template/index.hbs +16 -0
  32. package/template/releases.hbs +45 -0
  33. package/bin/writr.js +0 -7
  34. package/dist/cache.d.ts +0 -18
  35. package/dist/cache.js +0 -70
  36. package/dist/cache.js.map +0 -1
  37. package/dist/config.d.ts +0 -29
  38. package/dist/config.js +0 -104
  39. package/dist/config.js.map +0 -1
  40. package/dist/data/dataProviderInterface.d.ts +0 -12
  41. package/dist/data/dataProviderInterface.js +0 -2
  42. package/dist/data/dataProviderInterface.js.map +0 -1
  43. package/dist/data/dataService.d.ts +0 -19
  44. package/dist/data/dataService.js +0 -130
  45. package/dist/data/dataService.js.map +0 -1
  46. package/dist/data/fileDataProvider.d.ts +0 -20
  47. package/dist/data/fileDataProvider.js +0 -132
  48. package/dist/data/fileDataProvider.js.map +0 -1
  49. package/dist/generator.d.ts +0 -8
  50. package/dist/generator.js +0 -54
  51. package/dist/generator.js.map +0 -1
  52. package/dist/index.d.ts +0 -8
  53. package/dist/index.js +0 -80
  54. package/dist/index.js.map +0 -1
  55. package/dist/log.d.ts +0 -6
  56. package/dist/log.js +0 -13
  57. package/dist/log.js.map +0 -1
  58. package/dist/migrate/ghostMigrationProvider.d.ts +0 -9
  59. package/dist/migrate/ghostMigrationProvider.js +0 -65
  60. package/dist/migrate/ghostMigrationProvider.js.map +0 -1
  61. package/dist/migrate/jekyllMigrationProvider.d.ts +0 -4
  62. package/dist/migrate/jekyllMigrationProvider.js +0 -11
  63. package/dist/migrate/jekyllMigrationProvider.js.map +0 -1
  64. package/dist/migrate/mediumMigrationProvider.d.ts +0 -7
  65. package/dist/migrate/mediumMigrationProvider.js +0 -26
  66. package/dist/migrate/mediumMigrationProvider.js.map +0 -1
  67. package/dist/migrate/migrationProviderInterface.d.ts +0 -3
  68. package/dist/migrate/migrationProviderInterface.js +0 -2
  69. package/dist/migrate/migrationProviderInterface.js.map +0 -1
  70. package/dist/migrate/wordpressMigrationProvider.d.ts +0 -12
  71. package/dist/migrate/wordpressMigrationProvider.js +0 -103
  72. package/dist/migrate/wordpressMigrationProvider.js.map +0 -1
  73. package/dist/migrate.d.ts +0 -6
  74. package/dist/migrate.js +0 -34
  75. package/dist/migrate.js.map +0 -1
  76. package/dist/post.d.ts +0 -31
  77. package/dist/post.js +0 -189
  78. package/dist/post.js.map +0 -1
  79. package/dist/render/atomRenderProvider.d.ts +0 -8
  80. package/dist/render/atomRenderProvider.js +0 -51
  81. package/dist/render/atomRenderProvider.js.map +0 -1
  82. package/dist/render/htmRenderlProvider.d.ts +0 -14
  83. package/dist/render/htmRenderlProvider.js +0 -117
  84. package/dist/render/htmRenderlProvider.js.map +0 -1
  85. package/dist/render/imageRenderProvider.d.ts +0 -8
  86. package/dist/render/imageRenderProvider.js +0 -15
  87. package/dist/render/imageRenderProvider.js.map +0 -1
  88. package/dist/render/jsonRenderProvider.d.ts +0 -8
  89. package/dist/render/jsonRenderProvider.js +0 -24
  90. package/dist/render/jsonRenderProvider.js.map +0 -1
  91. package/dist/render/renderProviderInterface.d.ts +0 -5
  92. package/dist/render/renderProviderInterface.js +0 -2
  93. package/dist/render/renderProviderInterface.js.map +0 -1
  94. package/dist/serve.d.ts +0 -16
  95. package/dist/serve.js +0 -29
  96. package/dist/serve.js.map +0 -1
  97. package/dist/storage/fileStorageProvider.d.ts +0 -10
  98. package/dist/storage/fileStorageProvider.js +0 -62
  99. package/dist/storage/fileStorageProvider.js.map +0 -1
  100. package/dist/storage/storageProviderInterface.d.ts +0 -8
  101. package/dist/storage/storageProviderInterface.js +0 -2
  102. package/dist/storage/storageProviderInterface.js.map +0 -1
  103. package/dist/storage/storageService.d.ts +0 -12
  104. package/dist/storage/storageService.js +0 -28
  105. package/dist/storage/storageService.js.map +0 -1
  106. package/dist/tag.d.ts +0 -9
  107. package/dist/tag.js +0 -34
  108. package/dist/tag.js.map +0 -1
  109. package/dist/utils/parser.d.ts +0 -5
  110. package/dist/utils/parser.js +0 -37
  111. package/dist/utils/parser.js.map +0 -1
  112. package/dist/utils/setup.d.ts +0 -8
  113. package/dist/utils/setup.js +0 -75
  114. package/dist/utils/setup.js.map +0 -1
  115. package/init/article-complex.md +0 -40
  116. package/init/article-ejs.md +0 -40
  117. package/init/article-unpublished.md +0 -11
  118. package/init/article1-simple.md +0 -13
  119. package/init/article1.md +0 -11
  120. package/init/article2.md +0 -14
  121. package/init/big-content.md +0 -11
  122. package/init/config.json +0 -9
  123. package/init/images/Introducing Docula 1.png +0 -0
  124. package/init/images/Introducing Docula 2.jpeg +0 -0
  125. package/init/images/Introducing Docula 3.png +0 -0
  126. package/init/images/Introducing Docula 4.png +0 -0
  127. package/init/permalink-test.md +0 -13
  128. package/init/templates/index.hjs +0 -13
  129. package/init/templates/partials/header.hjs +0 -2
  130. package/init/templates/post.hjs +0 -19
  131. package/init/templates/post2.hjs +0 -17
  132. package/init/templates/post3.ejs +0 -7
  133. package/init/templates/tag.hjs +0 -9
package/README.md CHANGED
@@ -1,183 +1,124 @@
1
- ![Writr](logo.png)
1
+ ![Writr](site/logo.svg)
2
2
 
3
3
  ---
4
4
 
5
- ### CLI Tool for Markdown
5
+ ## Beautiful Website for Your Projects
6
6
  [![Build](https://github.com/jaredwray/writr/actions/workflows/tests.yml/badge.svg)](https://github.com/jaredwray/writr/actions/workflows/tests.yml)
7
7
  [![GitHub license](https://img.shields.io/github/license/jaredwray/writr)](https://github.com/jaredwray/writr/blob/master/LICENSE)
8
8
  [![codecov](https://codecov.io/gh/jaredwray/writr/branch/master/graph/badge.svg?token=1YdMesM07X)](https://codecov.io/gh/jaredwray/writr)
9
9
  [![npm](https://img.shields.io/npm/dm/writr)](https://npmjs.com/package/writr)
10
10
 
11
11
  ---
12
+ ## Table of Contents
13
+ - [Features](#features)
14
+ - [Getting Started](#getting-started)
15
+ - [Using Your own Template](#using-your-own-template)
16
+ - [Building Multiple Pages](#building-multiple-pages)
17
+ - [Helper Functions for Markdown](#helper-functions-for-markdown)
18
+ - [Code of Conduct and Contributing](#code-of-conduct-and-contributing)
19
+ - [What Happened to it Generating a Blog](#what-happened-to-it-generating-a-blog)
20
+ - [License - MIT](#license)
21
+
22
+ ## Features
23
+ * No configuration requrired. Just setup the folder structure with a logo, favicon, and css file.
24
+ * Builds a static website that can be hosted anywhere.
25
+ * For more complex projects easily add a `writr.config.js` or `writr.config.ts` file to customize the build process. With PRE and POST methods.
26
+ * Support for single page with readme or multiple markdown pages in a docs folder.
27
+ * Will generate a sitemap.xml and robots.txt for your site.
28
+ * Uses Github release notes to generate a changelog / releases page.
29
+ * Uses Github to show contributors and link to their profiles.
30
+ * Simple search is provided by default out of the box.
12
31
 
13
32
  ## Getting Started
14
33
 
15
34
  ## 1. Install Writr
16
35
 
17
- > npm install -g writr
36
+ > npx writr init
18
37
 
19
- ## 2. Setup your directory (look at /blog_example for how to do this)
20
-
21
- > writr init
38
+ This will create a folder called site with the following structure:
22
39
 
23
40
  ```
24
- blog/*.md //markdown files in the folder root
25
- blog/images //images for the blog
26
- blog/config.json //config file (optional)
27
- blog/templates //template directory for your index, post, and tag
41
+ site
42
+ ├───site.css
43
+ ├───logo.png
44
+ ├───favicon.ico
45
+ ├───README.md
46
+ ├───writr.config.js
28
47
  ```
48
+ Note: for typescript do 'writr init --typescript'
29
49
 
30
- ## 3. Create your first post
31
-
32
- > writr new
33
-
34
- This will allow you to answer a couple questions to setup your first blog post.
35
-
36
- ## 4. Run Writr on it with defaults. This will output everything to ./blog_output
37
-
38
- > writr
39
-
40
- ## 5. You can serve your blog with a simple webserver
50
+ ## 2. Add your content
41
51
 
42
- > writr serve
52
+ Simply replace the logo, favicon, and css file with your own. The readme is your root project readme and you just need to at build time move it over to the site folder. If you have it at the root of the project and this is a folder inside just delete the README.md file in the site folder and writr will copy it over for you automatically.
43
53
 
44
- ## 4. Integrate your blog with Express
45
-
46
- Then in express map your `blog_output` via static files:
47
-
48
- ```javascript
49
- app.use("/blog/*/images", express.static(path.join(__dirname, "blog_output/images")))
50
- app.use("/blog/images", express.static(path.join(__dirname, "blog_output/images")))
51
- app.use("/blog", express.static(path.join(__dirname, "blog_output")))
52
- ```
53
-
54
- ---
54
+ ## 3. Build your site
55
55
 
56
- ## CLI
56
+ > npx writr
57
57
 
58
- * -h, --help: Output usage information
59
- * -p, --path: Path of where the blog, and config are located
60
- * -o, --output: Path of where to output the generated blog
61
- * -r, --render: What do you want rendered such as html or json (example --render html,json)
62
- * -c, --config: Configuration file location if different than 'path'
63
- * init: Initialize a new blog
64
- * new: Create a new blog post
65
- * serve: Serve the blog. You can also specify a port with --port and --watch for hot reloading
58
+ This will build your site and place it in the `dist` folder. You can then host it anywhere you like.
66
59
 
67
- ## Templates
60
+ ## Using Your own Template
68
61
 
69
- There are three templates that are part of every instance of Writr. By default it goes in the `/blog/templates` directory. Here are the files and are in `Handlebars` format:
70
- * index.hjs: This is the main template that lists all of the latest blogs or what you want to add.
71
- * post.hjs: The post itself and usually supporting items around that such as what is next to look at and tags.
72
- * tag.hjs: Showing articles by tag filtering.
62
+ If you want to use your own template you can do so by adding a `writr.config.ts` file to the root of your project. This file will be used to configure the build process.
73
63
 
74
- ## Template Partials
64
+ or at the command line:
75
65
 
76
- You can use template partials such as a header or footer by creating a folder in templates called `partials`. In there create a standard handlebars template file such as `header.hjs`. To reference it go to any of the main template files and include it like `{{> header}}`:
66
+ > npx writr --template path/to/template
77
67
 
78
- ```html
79
- <h1>Post</h1>
68
+ ## Building Multiple Pages
80
69
 
81
- {{> header}}
70
+ If you want to build multiple pages you can easily do that by adding in a `docs` folder to the root of the site folder. Inside of that folder you can add as many pages as you like. Each page will be a markdown file and it will generate a table of contents for you. Here is an example of what it looks like:
82
71
 
83
- <p>{{post.title}}</p>
84
- <p>{{post.author}}</p>
85
- <p>{{{post.body}}}</p>
86
-
87
- <p>{{post.matter.featured_image}}</p>
88
-
89
- <p>{{previousPost.id}}</p>
90
- <p>{{nextPost.id}}</p>
91
- ...
72
+ ```
73
+ site
74
+ ├───site.css
75
+ ├───logo.png
76
+ ├───favicon.ico
77
+ ├───writr.config.ts
78
+ ├───docs
79
+ │ ├───getting-started.md
80
+ │ ├───contributing.md
81
+ │ ├───license.md
82
+ │ ├───code-of-conduct.md
92
83
  ```
93
84
 
94
- ## Different Templates / Layouts
95
-
96
- You can also set a post to use a different layout by setting the `layout` value in the `front-matter` like so:
85
+ The `readme.md` file will be the root page and the rest will be added to the table of contents. If you want to control the title or order of the pages you can do so by setting the `title` and `order` properties in the front matter of the markdown file. Here is an example:
97
86
 
98
- ```yaml
87
+ ```md
99
88
  ---
100
- title: 'Docula: Persistent Links and Styles!'
101
- tags:
102
- - Github
103
- - Open Source
104
- - Docula
105
- date: 2017-03-07
106
- layout: post2
107
- featured_image: Docula_%20Persistent%20Links%20and%20Styles%201.jpeg
89
+ title: Getting Started
90
+ order: 2
108
91
  ---
109
92
  ```
110
93
 
111
- ## Permalinks
112
-
113
- In your posts `front-matter` you can specify the format of the url to be generated. By default is the `:title` (also known as the `none` style) that is formatted correctly.
94
+ ## Helper Functions for Markdown
114
95
 
115
- ### Variables
96
+ Writr comes with some helper functions that you can use in your markdown files.
97
+ * `writrHelpers.getFrontMatter(fileName)` - Gets the front matter of a markdown file.
98
+ * `writrHelpers.setFrontMatter(fileName, frontMatter)` - Sets the front matter of a markdown file.
99
+ * `writrHelpers.createDoc(source, destination, frontMatter?, contentFn[]?)` - Creates a markdown file with the specified front matter and content. The contentFn is a function that is executed on the original content of the file. This is useful if you want to remove content from the original file.
116
100
 
117
- | Variable | Description |
118
- | --- | ----------- |
119
- | year | Year from the post’s filename with four digits. |
120
- | short_year | Year from the post’s filename without the century. (00..99) |
121
- | month | Month from the post’s filename. (01..12) |
122
- | i_month | Month without leading zeros |
123
- | short_month | Three-letter month abbreviation, e.g. "Dec". |
124
- | long_month | Full month name, e.g. “January”. |
125
- | day | Day of the month from the post’s filename. (01..31) |
126
- | i_day | Day of the month without leading zeros from the post’s filename. |
127
- | y_day | Day of the year (01...365) |
128
- | short_day | Three-letter weekday abbreviation, e.g. “Sun”. |
129
- | long_day | Weekday name, e.g. “Sunday”. |
130
- | week | Week number of the current year, starting with the first week having a majority of its days in January. (01..53) |
131
- | hour | Hour of the day, 24-hour clock, zero-padded from the post’s date front matter. (00..23) |
132
- | minute | Minute of the hour from the post’s date front matter. (00..59) |
133
- | second | Second of the minute from the post’s date front matter. (00..59) |
134
- | title | Title from the document’s front matter. |
101
+ ### Remove html content
135
102
 
103
+ In some cases your markdown file will have html content in it such as the logo of your project or a badge. You can use the `wrtirHelpers.removeHtmlContent()` helper function to remove that content from the page. Here is an example:
136
104
 
137
- ### Default Styles
105
+ ### Get and Set the Front Matter of a Markdown File
138
106
 
139
- You can simply put in the style on permalink setting in the individual post `front-matter` or globally in `config.json`
107
+ You can use the `writrHelpers.getFrontMatter()` and `writrHelpers.setFrontMatter()` helper functions to get and set the front matter of a markdown file. Here is an example:
140
108
 
141
- | Style | Template |
142
- | --- | ----------- |
143
- | default | /:title/ |
144
- | date | /:year/:month/:day/:title/ |
145
- | ordinal | /:year/:y_day/:title/ |
109
+ ```js
110
+ const frontMatter = writrHelpers.getFrontMatter('../readme.md');
111
+ frontMatter.title = 'My Title';
112
+ writrHelpers.setFrontMatter('../readme.md', frontMatter);
113
+ ```
146
114
 
115
+ ## Code of Conduct and Contributing
116
+ [Code of Conduct](CODE_OF_CONDUCT.md) and [Contributing](CONTRIBUTING.md) guidelines.
147
117
 
148
- #### Set Layout it in the Post
118
+ ## What Happened to it Generating a Blog
149
119
 
150
- ```yaml
151
- ---
152
- title: 'Docula: Persistent Links and Styles!'
153
- tags:
154
- - Github
155
- - Open Source
156
- - Docula
157
- permalink: date
158
- date: 2017-03-07
159
- layout: post2
160
- featured_image: Docula_%20Persistent%20Links%20and%20Styles%201.jpeg
161
- ---
162
- ```
120
+ The original version of writr was a blog generator. Since there are plenty of blog generators out there we made the decision to make it a static site generator for open source projects. This is something that we constantly need and we hope you find it useful as well.
163
121
 
164
- The url will be: `/2017/03/07/docula-persistent-links-and-styles`
165
-
166
- #### Set Layout Globally
167
-
168
- To set it globally you can set it in the `config.json` by setting the `permaLink` variable like so:
169
- ```javascript
170
- {
171
- "output" : "./blog_output",
172
- "render": [ "html" , "json", "atom", "images"],
173
- "path": "./blog_example",
174
- "title": "Example Blog",
175
- "url": "https://writr.io/blog",
176
- "authorName": "Jared Wray",
177
- "authorEmail": "me@jaredwray.com",
178
- "permalink": ":year/:month/:title"
179
- }
180
- ```
122
+ ## License
181
123
 
182
- ## Markdown
183
- To learn more about Markdown go here: https://markdownguide.org
124
+ MIT © [Jared Wray](https://jaredwray.com)
package/bin/writr.mjs ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ts-node
2
+
3
+ import * as process from 'node:process';
4
+ import Writr from '../dist/writr.js';
5
+
6
+ const writr = new Writr();
7
+
8
+ await writr.execute(process);
@@ -0,0 +1,33 @@
1
+ import { WritrOptions } from './options.js';
2
+ import { type GithubData } from './github.js';
3
+ export type WritrData = {
4
+ siteUrl: string;
5
+ siteTitle: string;
6
+ siteDescription: string;
7
+ sitePath: string;
8
+ templatePath: string;
9
+ outputPath: string;
10
+ github?: GithubData;
11
+ templates?: WritrTemplates;
12
+ };
13
+ export type WritrTemplates = {
14
+ index: string;
15
+ releases: string;
16
+ };
17
+ export declare class WritrBuilder {
18
+ private readonly _options;
19
+ private readonly _ecto;
20
+ private readonly _console;
21
+ constructor(options?: WritrOptions, engineOptions?: any);
22
+ get options(): WritrOptions;
23
+ build(): Promise<void>;
24
+ validateOptions(options: WritrOptions): void;
25
+ getGithubData(githubPath: string): Promise<GithubData>;
26
+ getTemplates(options: WritrOptions): Promise<WritrTemplates>;
27
+ getTemplateFile(path: string, name: string): Promise<string | undefined>;
28
+ buildRobotsPage(options: WritrOptions): Promise<void>;
29
+ buildSiteMapPage(data: WritrData): Promise<void>;
30
+ buildIndexPage(data: WritrData): Promise<void>;
31
+ buildReleasePage(data: WritrData): Promise<void>;
32
+ buildReadmeSection(data: WritrData): Promise<string>;
33
+ }
@@ -0,0 +1,181 @@
1
+ import { Ecto } from 'ecto';
2
+ import fs from 'fs-extra';
3
+ import { WritrOptions } from './options.js';
4
+ import { WritrConsole } from './console.js';
5
+ import { Github } from './github.js';
6
+ export class WritrBuilder {
7
+ _options = new WritrOptions();
8
+ _ecto;
9
+ _console = new WritrConsole();
10
+ constructor(options, engineOptions) {
11
+ if (options) {
12
+ this._options = options;
13
+ }
14
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
15
+ this._ecto = new Ecto(engineOptions);
16
+ }
17
+ get options() {
18
+ return this._options;
19
+ }
20
+ async build() {
21
+ const startTime = Date.now();
22
+ // Validate the options
23
+ this.validateOptions(this.options);
24
+ // Set the site options
25
+ const writrData = {
26
+ siteUrl: this.options.siteUrl,
27
+ siteTitle: this.options.siteTitle,
28
+ siteDescription: this.options.siteDescription,
29
+ sitePath: this.options.sitePath,
30
+ templatePath: this.options.templatePath,
31
+ outputPath: this.options.outputPath,
32
+ };
33
+ // Get data from github
34
+ const githubData = await this.getGithubData(this.options.githubPath);
35
+ // Get data of the site
36
+ writrData.github = githubData;
37
+ // Get the templates to use
38
+ writrData.templates = await this.getTemplates(this.options);
39
+ // Build the home page (index.html)
40
+ await this.buildIndexPage(writrData);
41
+ // Build the releases page (/releases/index.html)
42
+ await this.buildReleasePage(writrData);
43
+ // Build the sitemap (/sitemap.xml)
44
+ await this.buildSiteMapPage(writrData);
45
+ // Build the robots.txt (/robots.txt)
46
+ await this.buildRobotsPage(this.options);
47
+ const siteRelativePath = this.options.sitePath;
48
+ // Copy over favicon
49
+ if (await fs.pathExists(`${siteRelativePath}/favicon.ico`)) {
50
+ await fs.copy(`${siteRelativePath}/favicon.ico`, `${this.options.outputPath}/favicon.ico`);
51
+ }
52
+ // Copy over logo
53
+ if (await fs.pathExists(`${siteRelativePath}/logo.svg`)) {
54
+ await fs.copy(`${siteRelativePath}/logo.svg`, `${this.options.outputPath}/logo.svg`);
55
+ }
56
+ // Copy over css
57
+ if (await fs.pathExists(`${this.options.templatePath}/css`)) {
58
+ await fs.copy(`${this.options.templatePath}/css`, `${this.options.outputPath}/css`);
59
+ }
60
+ // Copy over variables
61
+ if (await fs.pathExists(`${siteRelativePath}/variables.css`)) {
62
+ await fs.copy(`${siteRelativePath}/variables.css`, `${this.options.outputPath}/css/variables.css`);
63
+ }
64
+ const endTime = Date.now();
65
+ const executionTime = endTime - startTime;
66
+ this._console.log(`Build completed in ${executionTime}ms`);
67
+ }
68
+ validateOptions(options) {
69
+ if (options.githubPath.length < 3) {
70
+ throw new Error('No github options provided');
71
+ }
72
+ if (options.siteDescription.length < 3) {
73
+ throw new Error('No site description options provided');
74
+ }
75
+ if (!options.siteTitle) {
76
+ throw new Error('No site title options provided');
77
+ }
78
+ if (!options.siteUrl) {
79
+ throw new Error('No site url options provided');
80
+ }
81
+ }
82
+ async getGithubData(githubPath) {
83
+ const paths = githubPath.split('/');
84
+ const options = {
85
+ author: paths[0],
86
+ repo: paths[1],
87
+ };
88
+ const github = new Github(options);
89
+ return github.getData();
90
+ }
91
+ async getTemplates(options) {
92
+ const templates = {
93
+ index: '',
94
+ releases: '',
95
+ };
96
+ if (await fs.pathExists(options.templatePath)) {
97
+ const index = await this.getTemplateFile(options.templatePath, 'index');
98
+ if (index) {
99
+ templates.index = index;
100
+ }
101
+ const releases = await this.getTemplateFile(options.templatePath, 'releases');
102
+ if (releases) {
103
+ templates.releases = releases;
104
+ }
105
+ }
106
+ else {
107
+ throw new Error('No template path found');
108
+ }
109
+ return templates;
110
+ }
111
+ async getTemplateFile(path, name) {
112
+ let result;
113
+ const files = await fs.readdir(path);
114
+ for (const file of files) {
115
+ const fileName = file.split('.');
116
+ if (fileName[0].toString().toLowerCase() === name.toLowerCase()) {
117
+ result = file.toString();
118
+ break;
119
+ }
120
+ }
121
+ return result;
122
+ }
123
+ async buildRobotsPage(options) {
124
+ const { sitePath } = options;
125
+ const { outputPath } = options;
126
+ const robotsPath = `${outputPath}/robots.txt`;
127
+ await fs.ensureDir(outputPath);
128
+ await ((await fs.pathExists(`${sitePath}/robots.txt`))
129
+ ? fs.copy(`${sitePath}/robots.txt`, robotsPath)
130
+ : fs.writeFile(robotsPath, 'User-agent: *\nDisallow:'));
131
+ }
132
+ async buildSiteMapPage(data) {
133
+ const sitemapPath = `${data.outputPath}/sitemap.xml`;
134
+ const urls = [{ url: data.siteUrl }, { url: `${data.siteUrl}/releases` }];
135
+ let xml = '<?xml version="1.0" encoding="UTF-8"?>';
136
+ xml += '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
137
+ for (const { url } of urls) {
138
+ xml += '<url>';
139
+ xml += `<loc>${url}</loc>`;
140
+ xml += '</url>';
141
+ }
142
+ xml += '</urlset>';
143
+ await fs.ensureDir(data.outputPath);
144
+ await fs.writeFile(sitemapPath, xml, 'utf8');
145
+ }
146
+ async buildIndexPage(data) {
147
+ if (data.templates) {
148
+ const indexPath = `${data.outputPath}/index.html`;
149
+ await fs.ensureDir(data.outputPath);
150
+ const indexTemplate = `${data.templatePath}/${data.templates.index}`;
151
+ const htmlReadme = await this.buildReadmeSection(data);
152
+ const indexContent = await this._ecto.renderFromFile(indexTemplate, { ...data, content: htmlReadme }, data.templatePath);
153
+ await fs.writeFile(indexPath, indexContent, 'utf8');
154
+ }
155
+ else {
156
+ throw new Error('No templates found');
157
+ }
158
+ }
159
+ async buildReleasePage(data) {
160
+ if (data.github && data.templates) {
161
+ const releasesPath = `${data.outputPath}/releases/index.html`;
162
+ const releaseOutputPath = `${data.outputPath}/releases`;
163
+ await fs.ensureDir(releaseOutputPath);
164
+ const releasesTemplate = `${data.templatePath}/${data.templates.releases}`;
165
+ const releasesContent = await this._ecto.renderFromFile(releasesTemplate, data, data.templatePath);
166
+ await fs.writeFile(releasesPath, releasesContent, 'utf8');
167
+ }
168
+ else {
169
+ throw new Error('No github data found');
170
+ }
171
+ }
172
+ async buildReadmeSection(data) {
173
+ let htmlReadme = '';
174
+ if (fs.existsSync(`${data.sitePath}/README.md`)) {
175
+ const readmeContent = fs.readFileSync(`${data.sitePath}/README.md`, 'utf8');
176
+ htmlReadme = await this._ecto.markdown.render(readmeContent);
177
+ }
178
+ return htmlReadme;
179
+ }
180
+ }
181
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9idWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxJQUFJLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFDMUIsT0FBTyxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQzFCLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFDMUMsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLGNBQWMsQ0FBQztBQUMxQyxPQUFPLEVBQUMsTUFBTSxFQUFzQyxNQUFNLGFBQWEsQ0FBQztBQWtCeEUsTUFBTSxPQUFPLFlBQVk7SUFDUCxRQUFRLEdBQWlCLElBQUksWUFBWSxFQUFFLENBQUM7SUFDNUMsS0FBSyxDQUFPO0lBQ1osUUFBUSxHQUFpQixJQUFJLFlBQVksRUFBRSxDQUFDO0lBRTdELFlBQVksT0FBc0IsRUFBRSxhQUFtQjtRQUN0RCxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQ2IsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUM7UUFDekIsQ0FBQztRQUVELGlFQUFpRTtRQUNqRSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFRCxJQUFXLE9BQU87UUFDakIsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ3RCLENBQUM7SUFFTSxLQUFLLENBQUMsS0FBSztRQUNqQixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFFN0IsdUJBQXVCO1FBQ3ZCLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ25DLHVCQUF1QjtRQUN2QixNQUFNLFNBQVMsR0FBYztZQUM1QixPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPO1lBQzdCLFNBQVMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVM7WUFDakMsZUFB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LENBQ2pCLENBQUM7WUFDRixNQUFNLEVBQUUsQ0FBQyxTQUFTLENBQUMsWUFBWSxFQUFFLGVBQWUsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUMzRCxDQUFDO2FBQU0sQ0FBQztZQUNQLE1BQU0sSUFBSSxLQUFLLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUN6QyxDQUFDO0lBQ0YsQ0FBQztJQUVNLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxJQUFlO1FBQzlDLElBQUksVUFBVSxHQUFHLEVBQUUsQ0FBQztRQUNwQixJQUFJLEVBQUUsQ0FBQyxVQUFVLENBQUMsR0FBRyxJQUFJLENBQUMsUUFBUSxZQUFZLENBQUMsRUFBRSxDQUFDO1lBQ2pELE1BQU0sYUFBYSxHQUFHLEVBQUUsQ0FBQyxZQUFZLENBQ3BDLEdBQUcsSUFBSSxDQUFDLFFBQVEsWUFBWSxFQUM1QixNQUFNLENBQ04sQ0FBQztZQUNGLFVBQVUsR0FBRyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUM5RCxDQUFDO1FBRUQsT0FBTyxVQUFVLENBQUM7SUFDbkIsQ0FBQztDQUNEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtFY3RvfSBmcm9tICdlY3RvJztcbmltcG9ydCBmcyBmcm9tICdmcy1leHRyYSc7XG5pbXBvcnQge1dyaXRyT3B0aW9uc30gZnJvbSAnLi9vcHRpb25zLmpzJztcbmltcG9ydCB7V3JpdHJDb25zb2xlfSBmcm9tICcuL2NvbnNvbGUuanMnO1xuaW1wb3J0IHtHaXRodWIsIHR5cGUgR2l0aHViRGF0YSwgdHlwZSBHaXRodWJPcHRpb25zfSBmcm9tICcuL2dpdGh1Yi5qcyc7XG5cbmV4cG9ydCB0eXBlIFdyaXRyRGF0YSA9IHtcblx0c2l0ZVVybDogc3RyaW5nO1xuXHRzaXRlVGl0bGU6IHN0cmluZztcblx0c2l0ZURlc2NyaXB0aW9uOiBzdHJpbmc7XG5cdHNpdGVQYXRoOiBzdHJpbmc7XG5cdHRlbXBsYXRlUGF0aDogc3RyaW5nO1xuXHRvdXRwdXRQYXRoOiBzdHJpbmc7XG5cdGdpdGh1Yj86IEdpdGh1YkRhdGE7XG5cdHRlbXBsYXRlcz86IFdyaXRyVGVtcGxhdGVzO1xufTtcblxuZXhwb3J0IHR5cGUgV3JpdHJUZW1wbGF0ZXMgPSB7XG5cdGluZGV4OiBzdHJpbmc7XG5cdHJlbGVhc2VzOiBzdHJpbmc7XG59O1xuXG5leHBvcnQgY2xhc3MgV3JpdHJCdWlsZGVyIHtcblx0cHJpdmF0ZSByZWFkb25seSBfb3B0aW9uczogV3JpdHJPcHRpb25zID0gbmV3IFdyaXRyT3B0aW9ucygpO1xuXHRwcml2YXRlIHJlYWRvbmx5IF9lY3RvOiBFY3RvO1xuXHRwcml2YXRlIHJlYWRvbmx5IF9jb25zb2xlOiBXcml0ckNvbnNvbGUgPSBuZXcgV3JpdHJDb25zb2xlKCk7XG5cblx0Y29uc3RydWN0b3Iob3B0aW9ucz86IFdyaXRyT3B0aW9ucywgZW5naW5lT3B0aW9ucz86IGFueSkge1xuXHRcdGlmIChvcHRpb25zKSB7XG5cdFx0XHR0aGlzLl9vcHRpb25zID0gb3B0aW9ucztcblx0XHR9XG5cblx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1hcmd1bWVudFxuXHRcdHRoaXMuX2VjdG8gPSBuZXcgRWN0byhlbmdpbmVPcHRpb25zKTtcblx0fVxuXG5cdHB1YmxpYyBnZXQgb3B0aW9ucygpOiBXcml0ck9wdGlvbnMge1xuXHRcdHJldHVybiB0aGlzLl9vcHRpb25zO1xuXHR9XG5cblx0cHVibGljIGFzeW5jIGJ1aWxkKCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGNvbnN0IHN0YXJ0VGltZSA9IERhdGUubm93KCk7XG5cblx0XHQvLyBWYWxpZGF0ZSB0aGUgb3B0aW9uc1xuXHRcdHRoaXMudmFsaWRhdGVPcHRpb25zKHRoaXMub3B0aW9ucyk7XG5cdFx0Ly8gU2V0IHRoZSBzaXRlIG9wdGlvbnNcblx0XHRjb25zdCB3cml0ckRhdGE6IFdyaXRyRGF0YSA9IHtcblx0XHRcdHNpdGVVcmw6IHRoaXMub3B0aW9ucy5zaXRlVXJsLFxuXHRcdFx0c2l0ZVRpdGxlOiB0aGlzLm9wdGlvbnMuc2l0ZVRpdGxlLFxuXHRcdFx0c2l0ZURlc2NyaXB0aW9uOiB0aGlzLm9wdGlvbnMuc2l0ZURlc2NyaXB0aW9uLFxuXHRcdFx0c2l0ZVBhdGg6IHRoaXMub3B0aW9ucy5zaXRlUGF0aCxcblx0XHRcdHRlbXBsYXRlUGF0aDogdGhpcy5vcHRpb25zLnRlbXBsYXRlUGF0aCxcblx0XHRcdG91dHB1dFBhdGg6IHRoaXMub3B0aW9ucy5vdXRwdXRQYXRoLFxuXHRcdH07XG5cdFx0Ly8gR2V0IGRhdGEgZnJvbSBnaXRodWJcblx0XHRjb25zdCBnaXRodWJEYXRhID0gYXdhaXQgdGhpcy5nZXRHaXRodWJEYXRhKHRoaXMub3B0aW9ucy5naXRodWJQYXRoKTtcblx0XHQvLyBHZXQgZGF0YSBvZiB0aGUgc2l0ZVxuXHRcdHdyaXRyRGF0YS5naXRodWIgPSBnaXRodWJEYXRhO1xuXHRcdC8vIEdldCB0aGUgdGVtcGxhdGVzIHRvIHVzZVxuXHRcdHdyaXRyRGF0YS50ZW1wbGF0ZXMgPSBhd2FpdCB0aGlzLmdldFRlbXBsYXRlcyh0aGlzLm9wdGlvbnMpO1xuXG5cdFx0Ly8gQnVpbGQgdGhlIGhvbWUgcGFnZSAoaW5kZXguaHRtbClcblx0XHRhd2FpdCB0aGlzLmJ1aWxkSW5kZXhQYWdlKHdyaXRyRGF0YSk7XG5cblx0XHQvLyBCdWlsZCB0aGUgcmVsZWFzZXMgcGFnZSAoL3JlbGVhc2VzL2luZGV4Lmh0bWwpXG5cdFx0YXdhaXQgdGhpcy5idWlsZFJlbGVhc2VQYWdlKHdyaXRyRGF0YSk7XG5cblx0XHQvLyBCdWlsZCB0aGUgc2l0ZW1hcCAoL3NpdGVtYXAueG1sKVxuXHRcdGF3YWl0IHRoaXMuYnVpbGRTaXRlTWFwUGFnZSh3cml0ckRhdGEpO1xuXG5cdFx0Ly8gQnVpbGQgdGhlIHJvYm90cy50eHQgKC9yb2JvdHMudHh0KVxuXHRcdGF3YWl0IHRoaXMuYnVpbGRSb2JvdHNQYWdlKHRoaXMub3B0aW9ucyk7XG5cblx0XHRjb25zdCBzaXRlUmVsYXRpdmVQYXRoID0gdGhpcy5vcHRpb25zLnNpdGVQYXRoO1xuXG5cdFx0Ly8gQ29weSBvdmVyIGZhdmljb25cblx0XHRpZiAoYXdhaXQgZnMucGF0aEV4aXN0cyhgJHtzaXRlUmVsYXRpdmVQYXRofS9mYXZpY29uLmljb2ApKSB7XG5cdFx0XHRhd2FpdCBmcy5jb3B5KFxuXHRcdFx0XHRgJHtzaXRlUmVsYXRpdmVQYXRofS9mYXZpY29uLmljb2AsXG5cdFx0XHRcdGAke3RoaXMub3B0aW9ucy5vdXRwdXRQYXRofS9mYXZpY29uLmljb2AsXG5cdFx0XHQpO1xuXHRcdH1cblxuXHRcdC8vIENvcHkgb3ZlciBsb2dvXG5cdFx0aWYgKGF3YWl0IGZzLnBhdGhFeGlzdHMoYCR7c2l0ZVJlbGF0aXZlUGF0aH0vbG9nby5zdmdgKSkge1xuXHRcdFx0YXdhaXQgZnMuY29weShcblx0XHRcdFx0YCR7c2l0ZVJlbGF0aXZlUGF0aH0vbG9nby5zdmdgLFxuXHRcdFx0XHRgJHt0aGlzLm9wdGlvbnMub3V0cHV0UGF0aH0vbG9nby5zdmdgLFxuXHRcdFx0KTtcblx0XHR9XG5cblx0XHQvLyBDb3B5IG92ZXIgY3NzXG5cdFx0aWYgKGF3YWl0IGZzLnBhdGhFeGlzdHMoYCR7dGhpcy5vcHRpb25zLnRlbXBsYXRlUGF0aH0vY3NzYCkpIHtcblx0XHRcdGF3YWl0IGZzLmNvcHkoXG5cdFx0XHRcdGAke3RoaXMub3B0aW9ucy50ZW1wbGF0ZVBhdGh9L2Nzc2AsXG5cdFx0XHRcdGAke3RoaXMub3B0aW9ucy5vdXRwdXRQYXRofS9jc3NgLFxuXHRcdFx0KTtcblx0XHR9XG5cblx0XHQvLyBDb3B5IG92ZXIgdmFyaWFibGVzXG5cdFx0aWYgKGF3YWl0IGZzLnBhdGhFeGlzdHMoYCR7c2l0ZVJlbGF0aXZlUGF0aH0vdmFyaWFibGVzLmNzc2ApKSB7XG5cdFx0XHRhd2FpdCBmcy5jb3B5KFxuXHRcdFx0XHRgJHtzaXRlUmVsYXRpdmVQYXRofS92YXJpYWJsZXMuY3NzYCxcblx0XHRcdFx0YCR7dGhpcy5vcHRpb25zLm91dHB1dFBhdGh9L2Nzcy92YXJpYWJsZXMuY3NzYCxcblx0XHRcdCk7XG5cdFx0fVxuXG5cdFx0Y29uc3QgZW5kVGltZSA9IERhdGUubm93KCk7XG5cblx0XHRjb25zdCBleGVjdXRpb25UaW1lID0gZW5kVGltZSAtIHN0YXJ0VGltZTtcblxuXHRcdHRoaXMuX2NvbnNvbGUubG9nKGBCdWlsZCBjb21wbGV0ZWQgaW4gJHtleGVjdXRpb25UaW1lfW1zYCk7XG5cdH1cblxuXHRwdWJsaWMgdmFsaWRhdGVPcHRpb25zKG9wdGlvbnM6IFdyaXRyT3B0aW9ucyk6IHZvaWQge1xuXHRcdGlmIChvcHRpb25zLmdpdGh1YlBhdGgubGVuZ3RoIDwgMykge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdObyBnaXRodWIgb3B0aW9ucyBwcm92aWRlZCcpO1xuXHRcdH1cblxuXHRcdGlmIChvcHRpb25zLnNpdGVEZXNjcmlwdGlvbi5sZW5ndGggPCAzKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ05vIHNpdGUgZGVzY3JpcHRpb24gb3B0aW9ucyBwcm92aWRlZCcpO1xuXHRcdH1cblxuXHRcdGlmICghb3B0aW9ucy5zaXRlVGl0bGUpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcignTm8gc2l0ZSB0aXRsZSBvcHRpb25zIHByb3ZpZGVkJyk7XG5cdFx0fVxuXG5cdFx0aWYgKCFvcHRpb25zLnNpdGVVcmwpIHtcblx0XHRcdHRocm93IG5ldyBFcnJvcignTm8gc2l0ZSB1cmwgb3B0aW9ucyBwcm92aWRlZCcpO1xuXHRcdH1cblx0fVxuXG5cdHB1YmxpYyBhc3luYyBnZXRHaXRodWJEYXRhKGdpdGh1YlBhdGg6IHN0cmluZyk6IFByb21pc2U8R2l0aHViRGF0YT4ge1xuXHRcdGNvbnN0IHBhdGhzID0gZ2l0aHViUGF0aC5zcGxpdCgnLycpO1xuXHRcdGNvbnN0IG9wdGlvbnM6IEdpdGh1Yk9wdGlvbnMgPSB7XG5cdFx0XHRhdXRob3I6IHBhdGhzWzBdLFxuXHRcdFx0cmVwbzogcGF0aHNbMV0sXG5cdFx0fTtcblx0XHRjb25zdCBnaXRodWIgPSBuZXcgR2l0aHViKG9wdGlvbnMpO1xuXHRcdHJldHVybiBnaXRodWIuZ2V0RGF0YSgpO1xuXHR9XG5cblx0cHVibGljIGFzeW5jIGdldFRlbXBsYXRlcyhvcHRpb25zOiBXcml0ck9wdGlvbnMpOiBQcm9taXNlPFdyaXRyVGVtcGxhdGVzPiB7XG5cdFx0Y29uc3QgdGVtcGxhdGVzOiBXcml0clRlbXBsYXRlcyA9IHtcblx0XHRcdGluZGV4OiAnJyxcblx0XHRcdHJlbGVhc2VzOiAnJyxcblx0XHR9O1xuXG5cdFx0aWYgKGF3YWl0IGZzLnBhdGhFeGlzdHMob3B0aW9ucy50ZW1wbGF0ZVBhdGgpKSB7XG5cdFx0XHRjb25zdCBpbmRleCA9IGF3YWl0IHRoaXMuZ2V0VGVtcGxhdGVGaWxlKG9wdGlvbnMudGVtcGxhdGVQYXRoLCAnaW5kZXgnKTtcblx0XHRcdGlmIChpbmRleCkge1xuXHRcdFx0XHR0ZW1wbGF0ZXMuaW5kZXggPSBpbmRleDtcblx0XHRcdH1cblxuXHRcdFx0Y29uc3QgcmVsZWFzZXMgPSBhd2FpdCB0aGlzLmdldFRlbXBsYXRlRmlsZShcblx0XHRcdFx0b3B0aW9ucy50ZW1wbGF0ZVBhdGgsXG5cdFx0XHRcdCdyZWxlYXNlcycsXG5cdFx0XHQpO1xuXHRcdFx0aWYgKHJlbGVhc2VzKSB7XG5cdFx0XHRcdHRlbXBsYXRlcy5yZWxlYXNlcyA9IHJlbGVhc2VzO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoJ05vIHRlbXBsYXRlIHBhdGggZm91bmQnKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGVtcGxhdGVzO1xuXHR9XG5cblx0cHVibGljIGFzeW5jIGdldFRlbXBsYXRlRmlsZShcblx0XHRwYXRoOiBzdHJpbmcsXG5cdFx0bmFtZTogc3RyaW5nLFxuXHQpOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuXHRcdGxldCByZXN1bHQ7XG5cdFx0Y29uc3QgZmlsZXMgPSBhd2FpdCBmcy5yZWFkZGlyKHBhdGgpO1xuXHRcdGZvciAoY29uc3QgZmlsZSBvZiBmaWxlcykge1xuXHRcdFx0Y29uc3QgZmlsZU5hbWUgPSBmaWxlLnNwbGl0KCcuJyk7XG5cdFx0XHRpZiAoZmlsZU5hbWVbMF0udG9TdHJpbmcoKS50b0xvd2VyQ2FzZSgpID09PSBuYW1lLnRvTG93ZXJDYXNlKCkpIHtcblx0XHRcdFx0cmVzdWx0ID0gZmlsZS50b1N0cmluZygpO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG5cblx0cHVibGljIGFzeW5jIGJ1aWxkUm9ib3RzUGFnZShvcHRpb25zOiBXcml0ck9wdGlvbnMpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRjb25zdCB7c2l0ZVBhdGh9ID0gb3B0aW9ucztcblx0XHRjb25zdCB7b3V0cHV0UGF0aH0gPSBvcHRpb25zO1xuXHRcdGNvbnN0IHJvYm90c1BhdGggPSBgJHtvdXRwdXRQYXRofS9yb2JvdHMudHh0YDtcblxuXHRcdGF3YWl0IGZzLmVuc3VyZURpcihvdXRwdXRQYXRoKTtcblxuXHRcdGF3YWl0ICgoYXdhaXQgZnMucGF0aEV4aXN0cyhgJHtzaXRlUGF0aH0vcm9ib3RzLnR4dGApKVxuXHRcdFx0PyBmcy5jb3B5KGAke3NpdGVQYXRofS9yb2JvdHMudHh0YCwgcm9ib3RzUGF0aClcblx0XHRcdDogZnMud3JpdGVGaWxlKHJvYm90c1BhdGgsICdVc2VyLWFnZW50OiAqXFxuRGlzYWxsb3c6JykpO1xuXHR9XG5cblx0cHVibGljIGFzeW5jIGJ1aWxkU2l0ZU1hcFBhZ2UoZGF0YTogV3JpdHJEYXRhKTogUHJvbWlzZTx2b2lkPiB7XG5cdFx0Y29uc3Qgc2l0ZW1hcFBhdGggPSBgJHtkYXRhLm91dHB1dFBhdGh9L3NpdGVtYXAueG1sYDtcblx0XHRjb25zdCB1cmxzID0gW3t1cmw6IGRhdGEuc2l0ZVVybH0sIHt1cmw6IGAke2RhdGEuc2l0ZVVybH0vcmVsZWFzZXNgfV07XG5cblx0XHRsZXQgeG1sID0gJzw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIlVURi04XCI/Pic7XG5cdFx0eG1sICs9ICc8dXJsc2V0IHhtbG5zPVwiaHR0cDovL3d3dy5zaXRlbWFwcy5vcmcvc2NoZW1hcy9zaXRlbWFwLzAuOVwiPic7XG5cblx0XHRmb3IgKGNvbnN0IHt1cmx9IG9mIHVybHMpIHtcblx0XHRcdHhtbCArPSAnPHVybD4nO1xuXHRcdFx0eG1sICs9IGA8bG9jPiR7dXJsfTwvbG9jPmA7XG5cdFx0XHR4bWwgKz0gJzwvdXJsPic7XG5cdFx0fVxuXG5cdFx0eG1sICs9ICc8L3VybHNldD4nO1xuXG5cdFx0YXdhaXQgZnMuZW5zdXJlRGlyKGRhdGEub3V0cHV0UGF0aCk7XG5cblx0XHRhd2FpdCBmcy53cml0ZUZpbGUoc2l0ZW1hcFBhdGgsIHhtbCwgJ3V0ZjgnKTtcblx0fVxuXG5cdHB1YmxpYyBhc3luYyBidWlsZEluZGV4UGFnZShkYXRhOiBXcml0ckRhdGEpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRpZiAoZGF0YS50ZW1wbGF0ZXMpIHtcblx0XHRcdGNvbnN0IGluZGV4UGF0aCA9IGAke2RhdGEub3V0cHV0UGF0aH0vaW5kZXguaHRtbGA7XG5cblx0XHRcdGF3YWl0IGZzLmVuc3VyZURpcihkYXRhLm91dHB1dFBhdGgpO1xuXG5cdFx0XHRjb25zdCBpbmRleFRlbXBsYXRlID0gYCR7ZGF0YS50ZW1wbGF0ZVBhdGh9LyR7ZGF0YS50ZW1wbGF0ZXMuaW5kZXh9YDtcblxuXHRcdFx0Y29uc3QgaHRtbFJlYWRtZSA9IGF3YWl0IHRoaXMuYnVpbGRSZWFkbWVTZWN0aW9uKGRhdGEpO1xuXG5cdFx0XHRjb25zdCBpbmRleENvbnRlbnQgPSBhd2FpdCB0aGlzLl9lY3RvLnJlbmRlckZyb21GaWxlKFxuXHRcdFx0XHRpbmRleFRlbXBsYXRlLFxuXHRcdFx0XHR7Li4uZGF0YSwgY29udGVudDogaHRtbFJlYWRtZX0sXG5cdFx0XHRcdGRhdGEudGVtcGxhdGVQYXRoLFxuXHRcdFx0KTtcblx0XHRcdGF3YWl0IGZzLndyaXRlRmlsZShpbmRleFBhdGgsIGluZGV4Q29udGVudCwgJ3V0ZjgnKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdObyB0ZW1wbGF0ZXMgZm91bmQnKTtcblx0XHR9XG5cdH1cblxuXHRwdWJsaWMgYXN5bmMgYnVpbGRSZWxlYXNlUGFnZShkYXRhOiBXcml0ckRhdGEpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRpZiAoZGF0YS5naXRodWIgJiYgZGF0YS50ZW1wbGF0ZXMpIHtcblx0XHRcdGNvbnN0IHJlbGVhc2VzUGF0aCA9IGAke2RhdGEub3V0cHV0UGF0aH0vcmVsZWFzZXMvaW5kZXguaHRtbGA7XG5cdFx0XHRjb25zdCByZWxlYXNlT3V0cHV0UGF0aCA9IGAke2RhdGEub3V0cHV0UGF0aH0vcmVsZWFzZXNgO1xuXG5cdFx0XHRhd2FpdCBmcy5lbnN1cmVEaXIocmVsZWFzZU91dHB1dFBhdGgpO1xuXG5cdFx0XHRjb25zdCByZWxlYXNlc1RlbXBsYXRlID0gYCR7ZGF0YS50ZW1wbGF0ZVBhdGh9LyR7ZGF0YS50ZW1wbGF0ZXMucmVsZWFzZXN9YDtcblx0XHRcdGNvbnN0IHJlbGVhc2VzQ29udGVudCA9IGF3YWl0IHRoaXMuX2VjdG8ucmVuZGVyRnJvbUZpbGUoXG5cdFx0XHRcdHJlbGVhc2VzVGVtcGxhdGUsXG5cdFx0XHRcdGRhdGEsXG5cdFx0XHRcdGRhdGEudGVtcGxhdGVQYXRoLFxuXHRcdFx0KTtcblx0XHRcdGF3YWl0IGZzLndyaXRlRmlsZShyZWxlYXNlc1BhdGgsIHJlbGVhc2VzQ29udGVudCwgJ3V0ZjgnKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdObyBnaXRodWIgZGF0YSBmb3VuZCcpO1xuXHRcdH1cblx0fVxuXG5cdHB1YmxpYyBhc3luYyBidWlsZFJlYWRtZVNlY3Rpb24oZGF0YTogV3JpdHJEYXRhKTogUHJvbWlzZTxzdHJpbmc+IHtcblx0XHRsZXQgaHRtbFJlYWRtZSA9ICcnO1xuXHRcdGlmIChmcy5leGlzdHNTeW5jKGAke2RhdGEuc2l0ZVBhdGh9L1JFQURNRS5tZGApKSB7XG5cdFx0XHRjb25zdCByZWFkbWVDb250ZW50ID0gZnMucmVhZEZpbGVTeW5jKFxuXHRcdFx0XHRgJHtkYXRhLnNpdGVQYXRofS9SRUFETUUubWRgLFxuXHRcdFx0XHQndXRmOCcsXG5cdFx0XHQpO1xuXHRcdFx0aHRtbFJlYWRtZSA9IGF3YWl0IHRoaXMuX2VjdG8ubWFya2Rvd24ucmVuZGVyKHJlYWRtZUNvbnRlbnQpO1xuXHRcdH1cblxuXHRcdHJldHVybiBodG1sUmVhZG1lO1xuXHR9XG59XG4iXX0=
@@ -0,0 +1,22 @@
1
+ export declare class WritrConsole {
2
+ log(message: string): void;
3
+ error(message: string): void;
4
+ warn(message: string): void;
5
+ printHelp(): void;
6
+ parseProcessArgv(argv: string[]): WritrConsoleProcess;
7
+ getCommand(argv: string[]): string | undefined;
8
+ getArguments(argv: string[]): WritrConsoleArguments;
9
+ }
10
+ type WritrConsoleProcess = {
11
+ argv: string[];
12
+ command: string | undefined;
13
+ args: WritrConsoleArguments;
14
+ };
15
+ type WritrConsoleArguments = {
16
+ sitePath: string | undefined;
17
+ templatePath: string | undefined;
18
+ output: string | undefined;
19
+ watch: boolean;
20
+ port: number;
21
+ };
22
+ export {};