docula 0.50.0 → 0.90.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docula",
3
- "version": "0.50.0",
3
+ "version": "0.90.0",
4
4
  "description": "Beautiful Website for Your Projects",
5
5
  "type": "module",
6
6
  "main": "./dist/docula.js",
@@ -41,6 +41,7 @@
41
41
  },
42
42
  "dependencies": {
43
43
  "@cacheable/net": "^2.0.5",
44
+ "colorette": "^2.0.20",
44
45
  "ecto": "^4.8.2",
45
46
  "feed": "^5.2.0",
46
47
  "jiti": "^2.6.1",
@@ -50,6 +51,7 @@
50
51
  },
51
52
  "devDependencies": {
52
53
  "@biomejs/biome": "^2.4.2",
54
+ "@playwright/test": "^1.58.2",
53
55
  "@types/express": "^5.0.6",
54
56
  "@types/js-yaml": "^4.0.9",
55
57
  "@types/node": "^25.2.3",
@@ -69,22 +71,18 @@
69
71
  "bin"
70
72
  ],
71
73
  "scripts": {
72
- "clean": "rimraf ./dist ./coverage ./node_modules ./package-lock.json ./yarn.lock ./pnpm-lock.yaml ./site/README.md ./site/dist",
74
+ "clean": "rimraf ./dist ./coverage ./node_modules ./package-lock.json ./yarn.lock ./pnpm-lock.yaml ./site/dist",
73
75
  "build": "pnpm generate-init-file && rimraf ./dist && tsup src/docula.ts --format esm --dts --clean",
74
76
  "lint": "biome check --write --error-on-warnings",
75
77
  "lint:ci": "biome check --error-on-warnings",
76
78
  "test": "pnpm lint && vitest run --coverage",
77
79
  "test:ci": "pnpm lint:ci && vitest run --coverage",
80
+ "test:e2e": "pnpm build && playwright test",
78
81
  "generate-init-file": "tsx scripts/generate-init-file.ts",
79
- "website:build": "rimraf ./site/README.md && node bin/docula.js build -s ./site -o ./site/dist",
80
- "website:serve": "rimraf ./site/README.md && node bin/docula.js serve -s ./site -o ./site/dist",
81
- "website:mega": "pnpm website:build:mega && pnpm website:serve:mega",
82
- "website:build:mega": "rimraf ./test/fixtures/mega-page-site/dist && node bin/docula.js build -s ./test/fixtures/mega-page-site",
83
- "website:serve:mega": "rimraf ./test/fixtures/mega-page-site/dist && node bin/docula.js serve -s ./test/fixtures/mega-page-site",
84
- "website:mega:nohome": "pnpm website:build:mega:nohome && pnpm website:serve:mega:nohome",
85
- "website:build:mega:nohome": "rimraf ./test/fixtures/mega-page-site-no-home-page/dist && node bin/docula.js build -s ./test/fixtures/mega-page-site-no-home-page",
86
- "website:serve:mega:nohome": "rimraf ./test/fixtures/mega-page-site-no-home-page/dist && node bin/docula.js serve -s ./test/fixtures/mega-page-site-no-home-page",
87
- "website:build:changelog": "rimraf ./test/fixtures/changelog-site/dist && node bin/docula.js build -s ./test/fixtures/changelog-site",
88
- "website:serve:changelog": "rimraf ./test/fixtures/changelog-site/dist && node bin/docula.js serve -s ./test/fixtures/changelog-site"
82
+ "website:build": "node bin/docula.js build -s ./site -o ./site/dist",
83
+ "website:serve": "node bin/docula.js serve -s ./site -o ./site/dist -w -p 3333",
84
+ "website:mega": "node bin/docula.js serve -s ./test/fixtures/mega-page-site --watch --clean",
85
+ "website:nohome": "node bin/docula.js serve -s ./test/fixtures/mega-page-site-no-home-page --watch --clean",
86
+ "website:changelog": "node bin/docula.js serve -s ./test/fixtures/changelog-site --watch --clean"
89
87
  }
90
88
  }
@@ -3,26 +3,212 @@
3
3
 
4
4
  <head>
5
5
  {{> header }}
6
- <title>API Documentation - {{ siteTitle }}</title>
7
- <meta name="description" content="API Documentation for {{ siteTitle }}" />
8
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@docutopia/react/dist/browser/docutopia.css" />
9
- <style>
10
- body {
11
- margin: 0;
12
- padding: 0;
13
- }
14
- </style>
6
+ <link rel="stylesheet" href="/css/api.css" />
7
+ <title>API Reference - {{ siteTitle }}</title>
8
+ <meta name="description" content="API Reference for {{ siteTitle }}" />
15
9
  </head>
16
10
 
17
11
  <body>
18
- <div id="docs" style="height: 100vh;"></div>
19
-
20
- <script src="https://cdn.jsdelivr.net/npm/@docutopia/react/dist/browser/docutopia.js"></script>
21
- <script>
22
- Docutopia.render('docs', {
23
- specUrl: '{{ specUrl }}',
24
- });
25
- </script>
12
+ {{#if githubPath}}
13
+ <a href="https://github.com/{{ githubPath }}" class="github-corner" aria-label="View source on GitHub"><svg width="80"
14
+ height="80" viewBox="0 0 250 250" style="color:#fff; position: absolute; top: 0; border: 0; right: 0;"
15
+ aria-hidden="true">
16
+ <path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
17
+ <path
18
+ d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
19
+ fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>
20
+ <path
21
+ d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
22
+ fill="currentColor" class="octo-body"></path>
23
+ </svg></a>
24
+ <style>
25
+ .github-corner:hover .octo-arm { animation: octocat-wave 560ms ease-in-out }
26
+ @keyframes octocat-wave { 0%,100% { transform: rotate(0) } 20%,60% { transform: rotate(-25deg) } 40%,80% { transform: rotate(10deg) } }
27
+ @media (max-width:500px) { .github-corner:hover .octo-arm { animation: none } .github-corner .octo-arm { animation: octocat-wave 560ms ease-in-out } }
28
+ </style>
29
+ {{/if}}
30
+
31
+ {{#if apiSpec}}
32
+ <div class="api-mobile-toggle">
33
+ <button id="api-sidebar-toggle">
34
+ <span>API Navigation</span>
35
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m7 15 5 5 5-5"/><path d="m7 9 5-5 5 5"/></svg>
36
+ </button>
37
+ </div>
38
+
39
+ <div class="api-reference">
40
+ <aside class="api-sidebar" id="api-sidebar">
41
+ <input type="text" class="api-search" id="api-search" placeholder="Search endpoints..." />
42
+
43
+ {{#each apiSpec.groups}}
44
+ <div class="api-sidebar__group" data-group="{{this.id}}">
45
+ <button class="api-sidebar__group-toggle">
46
+ <span>{{this.name}}</span>
47
+ <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>
48
+ </button>
49
+ <div class="api-sidebar__group-items">
50
+ {{#each this.operations}}
51
+ <a href="#{{this.id}}" class="api-sidebar__item" data-method="{{this.method}}" data-path="{{this.path}}">
52
+ <span class="method-badge method-badge--{{this.method}}">{{this.methodUpper}}</span>
53
+ <span class="api-sidebar__item-path">{{this.path}}</span>
54
+ </a>
55
+ {{/each}}
56
+ </div>
57
+ </div>
58
+ {{/each}}
59
+ </aside>
60
+
61
+ <main class="api-content">
62
+ <section class="api-info">
63
+ <h1 class="api-info__title">{{apiSpec.info.title}}</h1>
64
+ {{#if apiSpec.info.version}}
65
+ <span class="api-info__version">v{{apiSpec.info.version}}</span>
66
+ {{/if}}
67
+ {{#if apiSpec.info.description}}
68
+ <div class="api-info__description">{{{apiSpec.info.description}}}</div>
69
+ {{/if}}
70
+ {{#if apiSpec.servers}}
71
+ <div class="api-info__servers">
72
+ <div class="api-info__server-label">Server</div>
73
+ {{#each apiSpec.servers}}
74
+ <code class="api-info__server-url">{{this.url}}</code>
75
+ {{/each}}
76
+ </div>
77
+ {{/if}}
78
+ <div class="api-auth">
79
+ <div class="api-auth__label">Authorization</div>
80
+ <div class="api-auth__controls">
81
+ <select class="api-auth__type" id="api-auth-type">
82
+ <option value="none">None</option>
83
+ <option value="apikey">API Key (x-api-key)</option>
84
+ <option value="bearer">Bearer Token</option>
85
+ </select>
86
+ <input type="password" class="api-auth__value api-auth__value--hidden" id="api-auth-value" placeholder="Enter value..." />
87
+ </div>
88
+ </div>
89
+ </section>
90
+
91
+ {{#each apiSpec.groups}}
92
+ <div class="api-group" id="group-{{this.id}}">
93
+ <div class="api-group__header">
94
+ <h2 class="api-group__title">{{this.name}}</h2>
95
+ {{#if this.description}}
96
+ <div class="api-group__description">{{{this.description}}}</div>
97
+ {{/if}}
98
+ </div>
99
+
100
+ {{#each this.operations}}
101
+ <div class="api-operation api-operation--collapsed" id="{{this.id}}">
102
+ <div class="api-operation__header" data-toggle="operation">
103
+ <span class="method-badge method-badge--{{this.method}}">{{this.methodUpper}}</span>
104
+ <span class="api-operation__path">{{this.path}}</span>
105
+ {{#if this.summary}}
106
+ <span class="api-operation__summary">{{this.summary}}</span>
107
+ {{/if}}
108
+ <svg class="api-operation__toggle-icon" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>
109
+ </div>
110
+ <div class="api-operation__body">
111
+ <div class="api-operation__docs">
112
+ {{#if this.description}}
113
+ <div class="api-operation__description">{{{this.description}}}</div>
114
+ {{/if}}
115
+
116
+ {{#if this.parameters.length}}
117
+ <div class="api-section-title">Parameters</div>
118
+ <table class="api-params-table">
119
+ <thead><tr><th>Name</th><th>Type</th><th>In</th><th>Description</th></tr></thead>
120
+ <tbody>
121
+ {{#each this.parameters}}
122
+ <tr>
123
+ <td><span class="api-param-name">{{this.name}}</span>{{#if this.required}}<span class="api-param-required">*</span>{{/if}}</td>
124
+ <td><span class="api-param-type">{{this.type}}</span></td>
125
+ <td><span class="api-param-in">{{this.in}}</span></td>
126
+ <td><span class="api-param-desc">{{this.description}}</span></td>
127
+ </tr>
128
+ {{/each}}
129
+ </tbody>
130
+ </table>
131
+ {{/if}}
132
+
133
+ {{#if this.requestBody}}
134
+ <div class="api-section-title">Request Body <span class="api-param-type">{{this.requestBody.contentType}}</span></div>
135
+ {{#if this.requestBody.schemaProperties.length}}
136
+ <div class="api-schema"><div class="api-schema-props">
137
+ {{#each this.requestBody.schemaProperties}}
138
+ <div class="api-schema-prop">
139
+ <span class="api-schema-prop-name">{{this.name}}{{#if this.required}}<span class="api-param-required">*</span>{{/if}}</span>
140
+ <span class="api-schema-prop-type">{{this.type}}</span>
141
+ <span class="api-schema-prop-desc">{{this.description}}</span>
142
+ </div>
143
+ {{/each}}
144
+ </div></div>
145
+ {{/if}}
146
+ {{#if this.requestBody.example}}
147
+ <div class="api-response__example"><pre><code>{{this.requestBody.example}}</code></pre></div>
148
+ {{/if}}
149
+ {{/if}}
150
+
151
+ {{#if this.responses.length}}
152
+ <div class="api-section-title">Responses</div>
153
+ {{#each this.responses}}
154
+ <div class="api-response">
155
+ <div class="api-response__status">
156
+ <span class="api-status-code api-status-code--{{this.statusClass}}">{{this.statusCode}}</span>
157
+ <span class="api-response__desc">{{this.description}}</span>
158
+ </div>
159
+ {{#if this.schemaProperties.length}}
160
+ <div class="api-schema"><div class="api-schema-props">
161
+ {{#each this.schemaProperties}}
162
+ <div class="api-schema-prop">
163
+ <span class="api-schema-prop-name">{{this.name}}</span>
164
+ <span class="api-schema-prop-type">{{this.type}}</span>
165
+ <span class="api-schema-prop-desc">{{this.description}}</span>
166
+ </div>
167
+ {{/each}}
168
+ </div></div>
169
+ {{/if}}
170
+ {{#if this.example}}
171
+ <div class="api-response__example"><pre><code>{{this.example}}</code></pre></div>
172
+ {{/if}}
173
+ </div>
174
+ {{/each}}
175
+ {{/if}}
176
+
177
+ <div class="api-code-examples">
178
+ <div class="api-code-tabs">
179
+ <button class="api-code-tab api-code-tab--active" data-tab="curl">cURL</button>
180
+ <button class="api-code-tab" data-tab="javascript">JavaScript</button>
181
+ <button class="api-code-tab" data-tab="python">Python</button>
182
+ </div>
183
+ <div class="api-code-panel api-code-panel--active" data-panel="curl">
184
+ <button class="api-copy-btn" data-copy>Copy</button>
185
+ <pre><code>{{this.codeExamples.curl}}</code></pre>
186
+ </div>
187
+ <div class="api-code-panel" data-panel="javascript">
188
+ <button class="api-copy-btn" data-copy>Copy</button>
189
+ <pre><code>{{this.codeExamples.javascript}}</code></pre>
190
+ </div>
191
+ <div class="api-code-panel" data-panel="python">
192
+ <button class="api-copy-btn" data-copy>Copy</button>
193
+ <pre><code>{{this.codeExamples.python}}</code></pre>
194
+ </div>
195
+ </div>
196
+ </div>
197
+
198
+ {{> api-try-it }}
199
+ </div>
200
+ </div>
201
+ {{/each}}
202
+ </div>
203
+ {{/each}}
204
+ </main>
205
+ </div>
206
+ {{/if}}
207
+
208
+ {{> footer}}
209
+ {{> scripts }}
210
+
211
+ <script src="/js/api.js"></script>
26
212
  </body>
27
213
 
28
214
  </html>
@@ -8,6 +8,7 @@
8
8
 
9
9
  <body>
10
10
  {{> singlepage/hero }}
11
+ {{#if githubPath}}
11
12
  <a href="https://github.com/{{ githubPath }}" class="github-corner" aria-label="View source on GitHub"><svg width="80"
12
13
  height="80" viewBox="0 0 250 250" style="color:#fff; position: absolute; top: 0; border: 0; right: 0;"
13
14
  aria-hidden="true">
@@ -52,6 +53,7 @@
52
53
  }
53
54
  }
54
55
  </style>
56
+ {{/if}}
55
57
  <main class="versions-container">
56
58
  <div class="versions-content">
57
59
  <div class="changelog-entry-nav">
@@ -8,6 +8,7 @@
8
8
 
9
9
  <body>
10
10
  {{> singlepage/hero }}
11
+ {{#if githubPath}}
11
12
  <a href="https://github.com/{{ githubPath }}" class="github-corner" aria-label="View source on GitHub"><svg width="80"
12
13
  height="80" viewBox="0 0 250 250" style="color:#fff; position: absolute; top: 0; border: 0; right: 0;"
13
14
  aria-hidden="true">
@@ -52,6 +53,7 @@
52
53
  }
53
54
  }
54
55
  </style>
56
+ {{/if}}
55
57
  <main class="versions-container">
56
58
  <div class="versions-content">
57
59
  <h2 class="home-title">Changelog</h2>