docula 1.12.0 → 1.13.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.d.ts +20 -5
- package/dist/docula.js +109 -30
- package/package.json +1 -1
- package/templates/modern/css/styles.css +31 -2
- package/templates/modern/includes/header-bar.hbs +0 -1
package/dist/docula.d.ts
CHANGED
|
@@ -153,6 +153,10 @@ type DoculaChangelogEntry = {
|
|
|
153
153
|
previewImage?: string;
|
|
154
154
|
urlPath: string;
|
|
155
155
|
lastModified: string;
|
|
156
|
+
description?: string;
|
|
157
|
+
keywords?: string[];
|
|
158
|
+
ogTitle?: string;
|
|
159
|
+
ogDescription?: string;
|
|
156
160
|
};
|
|
157
161
|
type DoculaData = {
|
|
158
162
|
siteUrl: string;
|
|
@@ -175,6 +179,13 @@ type DoculaData = {
|
|
|
175
179
|
openApiSpecs?: DoculaOpenApiSpecEntry[];
|
|
176
180
|
changelogEntries?: DoculaChangelogEntry[];
|
|
177
181
|
hasReadme?: boolean;
|
|
182
|
+
readmeContent?: string;
|
|
183
|
+
readmeMetadata?: {
|
|
184
|
+
description?: string;
|
|
185
|
+
keywords?: string[];
|
|
186
|
+
ogTitle?: string;
|
|
187
|
+
ogDescription?: string;
|
|
188
|
+
};
|
|
178
189
|
themeMode?: string;
|
|
179
190
|
cookieAuth?: {
|
|
180
191
|
loginUrl: string;
|
|
@@ -271,7 +282,7 @@ type DoculaCacheOptions = {
|
|
|
271
282
|
type DoculaAIOptions = {
|
|
272
283
|
provider: string;
|
|
273
284
|
model?: string;
|
|
274
|
-
apiKey
|
|
285
|
+
apiKey?: string;
|
|
275
286
|
};
|
|
276
287
|
declare class DoculaOptions {
|
|
277
288
|
/**
|
|
@@ -345,9 +356,10 @@ declare class DoculaOptions {
|
|
|
345
356
|
*/
|
|
346
357
|
autoUpdateIgnores: boolean;
|
|
347
358
|
/**
|
|
348
|
-
* When true, automatically
|
|
349
|
-
*
|
|
350
|
-
*
|
|
359
|
+
* When true, automatically renders the project root README.md as the home
|
|
360
|
+
* page if no README exists in the site directory. The README is read in
|
|
361
|
+
* place and never copied into the site directory. The package.json name
|
|
362
|
+
* field is used to prepend a title heading when the README lacks one.
|
|
351
363
|
*/
|
|
352
364
|
autoReadme: boolean;
|
|
353
365
|
/**
|
|
@@ -441,7 +453,10 @@ declare class DoculaBuilder {
|
|
|
441
453
|
get options(): DoculaOptions;
|
|
442
454
|
build(): Promise<void>;
|
|
443
455
|
validateOptions(options: DoculaOptions): void;
|
|
444
|
-
autoReadme(): Promise<
|
|
456
|
+
autoReadme(): Promise<{
|
|
457
|
+
sourcePath: string;
|
|
458
|
+
content: string;
|
|
459
|
+
} | undefined>;
|
|
445
460
|
getGithubData(githubPath: string): Promise<GithubData>;
|
|
446
461
|
getTemplates(templatePath: string, hasDocuments: boolean, hasChangelog?: boolean): Promise<DoculaTemplates>;
|
|
447
462
|
getTemplateFile(path: string, name: string): Promise<string | undefined>;
|
package/dist/docula.js
CHANGED
|
@@ -12,7 +12,7 @@ import { blue, bold, cyan, dim, gray, green, magenta, red, white, yellow } from
|
|
|
12
12
|
import { CacheableNet } from "@cacheable/net";
|
|
13
13
|
import os from "node:os";
|
|
14
14
|
//#region package.json
|
|
15
|
-
var version = "1.
|
|
15
|
+
var version = "1.13.0";
|
|
16
16
|
var package_default = {
|
|
17
17
|
name: "docula",
|
|
18
18
|
version,
|
|
@@ -161,13 +161,13 @@ function saveAIMetadataCache(sitePath, cache) {
|
|
|
161
161
|
* Check if a document needs AI enrichment for OG/meta fields.
|
|
162
162
|
*/
|
|
163
163
|
function needsDocumentEnrichment(doc) {
|
|
164
|
-
return !doc.description || doc.keywords.length === 0 || !doc.
|
|
164
|
+
return !doc.description || doc.keywords.length === 0 || !doc.ogDescription;
|
|
165
165
|
}
|
|
166
166
|
/**
|
|
167
167
|
* Check if a changelog entry needs AI enrichment.
|
|
168
168
|
*/
|
|
169
169
|
function needsChangelogEnrichment(entry) {
|
|
170
|
-
return !entry.
|
|
170
|
+
return !entry.preview || !entry.description || !entry.keywords?.length || !entry.ogDescription;
|
|
171
171
|
}
|
|
172
172
|
/**
|
|
173
173
|
* Enrich documents with AI-generated metadata for OG/meta tags.
|
|
@@ -183,9 +183,13 @@ async function enrichDocuments(documents, model, hash, console, cache) {
|
|
|
183
183
|
const bodyHash = hash.toHashSync(doc.content);
|
|
184
184
|
const cached = cache[bodyHash];
|
|
185
185
|
if (cached) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
186
|
+
const applied = applyMetadataToDocument(doc, cached);
|
|
187
|
+
if (!needsDocumentEnrichment(applied)) {
|
|
188
|
+
enriched[i] = applied;
|
|
189
|
+
logDocumentMetadata(console, doc.title || doc.documentPath, cached, true);
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
delete cache[bodyHash];
|
|
189
193
|
}
|
|
190
194
|
if (doc.content.trim().length < 10) continue;
|
|
191
195
|
const metadata = await new Writr$1(doc.content, {
|
|
@@ -210,14 +214,19 @@ async function enrichChangelogEntries(entries, model, hash, console, cache) {
|
|
|
210
214
|
const enriched = [...entries];
|
|
211
215
|
for (let i = 0; i < enriched.length; i++) {
|
|
212
216
|
const entry = enriched[i];
|
|
217
|
+
/* v8 ignore next -- @preserve */
|
|
213
218
|
if (!needsChangelogEnrichment(entry)) continue;
|
|
214
219
|
try {
|
|
215
220
|
const bodyHash = hash.toHashSync(entry.content);
|
|
216
221
|
const cached = cache[bodyHash];
|
|
217
222
|
if (cached) {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
223
|
+
const applied = applyMetadataToChangelog(entry, cached);
|
|
224
|
+
if (!needsChangelogEnrichment(applied)) {
|
|
225
|
+
enriched[i] = applied;
|
|
226
|
+
logChangelogMetadata(console, entry.title || entry.slug, cached, true);
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
delete cache[bodyHash];
|
|
221
230
|
}
|
|
222
231
|
if (entry.content.trim().length < 10) continue;
|
|
223
232
|
const metadata = await new Writr$1(entry.content, {
|
|
@@ -235,6 +244,45 @@ async function enrichChangelogEntries(entries, model, hash, console, cache) {
|
|
|
235
244
|
return enriched;
|
|
236
245
|
}
|
|
237
246
|
/**
|
|
247
|
+
* Enrich the site README with AI-generated metadata for OG/meta tags.
|
|
248
|
+
* Accepts the README content directly (from doculaData.readmeContent or
|
|
249
|
+
* by reading sitePath/README.md). Returns mapped metadata or undefined
|
|
250
|
+
* if content is missing, too small, or enrichment fails.
|
|
251
|
+
*/
|
|
252
|
+
async function enrichReadme(content, model, hash, console, cache) {
|
|
253
|
+
if (!content) return;
|
|
254
|
+
try {
|
|
255
|
+
if (content.trim().length < 10) return;
|
|
256
|
+
const bodyHash = hash.toHashSync(content);
|
|
257
|
+
const cached = cache[bodyHash];
|
|
258
|
+
if (cached) {
|
|
259
|
+
logDocumentMetadata(console, "README", cached, true);
|
|
260
|
+
return {
|
|
261
|
+
description: cached.description,
|
|
262
|
+
keywords: cached.keywords,
|
|
263
|
+
ogTitle: cached.title,
|
|
264
|
+
ogDescription: cached.description
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
const metadata = await new Writr$1(content, {
|
|
268
|
+
...writrOptions$6,
|
|
269
|
+
ai: { model }
|
|
270
|
+
}).ai?.getMetadata();
|
|
271
|
+
if (!metadata) return;
|
|
272
|
+
cache[bodyHash] = metadata;
|
|
273
|
+
logDocumentMetadata(console, "README", metadata, false);
|
|
274
|
+
return {
|
|
275
|
+
description: metadata.description,
|
|
276
|
+
keywords: metadata.keywords,
|
|
277
|
+
ogTitle: metadata.title,
|
|
278
|
+
ogDescription: metadata.description
|
|
279
|
+
};
|
|
280
|
+
} catch (error) {
|
|
281
|
+
console.warn(`AI enrichment failed for README: ${error.message}`);
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
238
286
|
* Log AI-generated metadata for a document.
|
|
239
287
|
*/
|
|
240
288
|
function truncate(value, max = 60) {
|
|
@@ -248,7 +296,6 @@ function logDocumentMetadata(console, name, metadata, fromCache) {
|
|
|
248
296
|
console.info(`AI enriched: ${name}`);
|
|
249
297
|
if (metadata.description) console.log(white(` description: ${truncate(metadata.description)}`));
|
|
250
298
|
if (metadata.keywords?.length) console.log(white(` keywords: ${truncate(metadata.keywords.join(", "))}`));
|
|
251
|
-
if (metadata.title) console.log(white(` ogTitle: ${truncate(metadata.title)}`));
|
|
252
299
|
}
|
|
253
300
|
/**
|
|
254
301
|
* Log AI-generated metadata for a changelog entry.
|
|
@@ -259,8 +306,9 @@ function logChangelogMetadata(console, name, metadata, fromCache) {
|
|
|
259
306
|
return;
|
|
260
307
|
}
|
|
261
308
|
console.info(`AI enriched changelog: ${name}`);
|
|
262
|
-
if (metadata.title) console.log(white(` title: ${truncate(metadata.title)}`));
|
|
263
309
|
if (metadata.preview || metadata.summary) console.log(white(` preview: ${truncate(metadata.preview || metadata.summary || "")}`));
|
|
310
|
+
if (metadata.description) console.log(white(` description: ${truncate(metadata.description)}`));
|
|
311
|
+
if (metadata.keywords?.length) console.log(white(` keywords: ${truncate(metadata.keywords.join(", "))}`));
|
|
264
312
|
}
|
|
265
313
|
/**
|
|
266
314
|
* Apply AI-generated metadata to a document, filling only missing fields.
|
|
@@ -270,7 +318,7 @@ function applyMetadataToDocument(doc, metadata) {
|
|
|
270
318
|
...doc,
|
|
271
319
|
description: doc.description || metadata.description || "",
|
|
272
320
|
keywords: doc.keywords.length > 0 ? doc.keywords : metadata.keywords ?? [],
|
|
273
|
-
ogTitle: doc.ogTitle ??
|
|
321
|
+
ogTitle: doc.ogTitle ?? (doc.title || void 0),
|
|
274
322
|
ogDescription: doc.ogDescription ?? metadata.description
|
|
275
323
|
};
|
|
276
324
|
}
|
|
@@ -280,8 +328,11 @@ function applyMetadataToDocument(doc, metadata) {
|
|
|
280
328
|
function applyMetadataToChangelog(entry, metadata) {
|
|
281
329
|
return {
|
|
282
330
|
...entry,
|
|
283
|
-
|
|
284
|
-
|
|
331
|
+
preview: entry.preview || metadata.preview || metadata.summary || "",
|
|
332
|
+
description: entry.description || metadata.description || void 0,
|
|
333
|
+
keywords: entry.keywords?.length ? entry.keywords : metadata.keywords ?? [],
|
|
334
|
+
ogTitle: entry.ogTitle ?? (entry.title || void 0),
|
|
335
|
+
ogDescription: entry.ogDescription ?? metadata.description
|
|
285
336
|
};
|
|
286
337
|
}
|
|
287
338
|
//#endregion
|
|
@@ -745,7 +796,7 @@ function resolveJsonLd(pageType, data, pageUrl, pageData) {
|
|
|
745
796
|
"@context": "https://schema.org",
|
|
746
797
|
"@type": "BlogPosting",
|
|
747
798
|
headline: pageData.title,
|
|
748
|
-
description: pageData?.
|
|
799
|
+
description: pageData?.description ?? pageData?.preview ?? "",
|
|
749
800
|
url,
|
|
750
801
|
publisher: {
|
|
751
802
|
"@type": "Organization",
|
|
@@ -754,6 +805,7 @@ function resolveJsonLd(pageType, data, pageUrl, pageData) {
|
|
|
754
805
|
};
|
|
755
806
|
if (pageData?.date) schema.datePublished = pageData.date;
|
|
756
807
|
if (pageData?.previewImage) schema.image = pageData.previewImage;
|
|
808
|
+
if (pageData?.keywords) schema.keywords = pageData.keywords;
|
|
757
809
|
break;
|
|
758
810
|
}
|
|
759
811
|
/* v8 ignore next 3 -- @preserve */
|
|
@@ -1089,7 +1141,7 @@ function recordsEqual(a, b) {
|
|
|
1089
1141
|
for (const key of keysA) if (a[key] !== b[key]) return false;
|
|
1090
1142
|
return true;
|
|
1091
1143
|
}
|
|
1092
|
-
function hasAssetsChanged(hash, sitePath, previousAssets) {
|
|
1144
|
+
function hasAssetsChanged(hash, sitePath, previousAssets, autoReadme) {
|
|
1093
1145
|
for (const file of [
|
|
1094
1146
|
"favicon.ico",
|
|
1095
1147
|
"logo.svg",
|
|
@@ -1104,6 +1156,14 @@ function hasAssetsChanged(hash, sitePath, previousAssets) {
|
|
|
1104
1156
|
if (previousAssets[file] !== fileHash) return true;
|
|
1105
1157
|
} else if (previousAssets[file]) return true;
|
|
1106
1158
|
}
|
|
1159
|
+
const siteReadmeExists = fs.existsSync(path.join(sitePath, "README.md"));
|
|
1160
|
+
if (autoReadme === true && !siteReadmeExists || previousAssets.__autoReadme !== void 0) {
|
|
1161
|
+
const rootReadmePath = path.join(process.cwd(), "README.md");
|
|
1162
|
+
if (fs.existsSync(rootReadmePath)) {
|
|
1163
|
+
const currentRootHash = hashFile(hash, rootReadmePath);
|
|
1164
|
+
if (previousAssets.__autoReadme !== currentRootHash) return true;
|
|
1165
|
+
} else if (previousAssets.__autoReadme !== void 0) return true;
|
|
1166
|
+
}
|
|
1107
1167
|
const publicPath = path.join(sitePath, "public");
|
|
1108
1168
|
if (fs.existsSync(publicPath)) {
|
|
1109
1169
|
const publicHashes = hashSourceFiles(hash, publicPath);
|
|
@@ -1254,6 +1314,10 @@ function parseChangelogEntry(filePath, options) {
|
|
|
1254
1314
|
});
|
|
1255
1315
|
const previewImage = matterData.previewImage;
|
|
1256
1316
|
const draft = matterData.draft === true;
|
|
1317
|
+
const description = matterData.description || void 0;
|
|
1318
|
+
const keywords = Array.isArray(matterData.keywords) ? matterData.keywords : void 0;
|
|
1319
|
+
const ogTitle = matterData.ogTitle || void 0;
|
|
1320
|
+
const ogDescription = matterData.ogDescription || void 0;
|
|
1257
1321
|
return {
|
|
1258
1322
|
title: matterData.title ?? fileName,
|
|
1259
1323
|
date: dateString,
|
|
@@ -1267,7 +1331,11 @@ function parseChangelogEntry(filePath, options) {
|
|
|
1267
1331
|
draft,
|
|
1268
1332
|
previewImage,
|
|
1269
1333
|
urlPath: `${buildUrlPath(options.baseUrl, options.changelogPath, slug)}/index.html`,
|
|
1270
|
-
lastModified: fs.statSync(filePath).mtime.toISOString().split("T")[0]
|
|
1334
|
+
lastModified: fs.statSync(filePath).mtime.toISOString().split("T")[0],
|
|
1335
|
+
description,
|
|
1336
|
+
keywords,
|
|
1337
|
+
ogTitle,
|
|
1338
|
+
ogDescription
|
|
1271
1339
|
};
|
|
1272
1340
|
}
|
|
1273
1341
|
function generateChangelogPreview(markdown, maxLength = 500, mdx = false) {
|
|
@@ -2427,9 +2495,10 @@ var DoculaOptions = class {
|
|
|
2427
2495
|
*/
|
|
2428
2496
|
autoUpdateIgnores = true;
|
|
2429
2497
|
/**
|
|
2430
|
-
* When true, automatically
|
|
2431
|
-
*
|
|
2432
|
-
*
|
|
2498
|
+
* When true, automatically renders the project root README.md as the home
|
|
2499
|
+
* page if no README exists in the site directory. The README is read in
|
|
2500
|
+
* place and never copied into the site directory. The package.json name
|
|
2501
|
+
* field is used to prepend a title heading when the README lacks one.
|
|
2433
2502
|
*/
|
|
2434
2503
|
autoReadme = true;
|
|
2435
2504
|
/**
|
|
@@ -2697,14 +2766,16 @@ var DoculaBuilder = class {
|
|
|
2697
2766
|
const currentChangelogHashes = hashSourceFiles(this._hash, `${this.options.sitePath}/changelog`);
|
|
2698
2767
|
const currentAssetHashes = {};
|
|
2699
2768
|
if (validManifest && fs.existsSync(this.options.output) && validManifest.templateHash === currentTemplateHash && recordsEqual(validManifest.docs, currentDocHashes) && recordsEqual(validManifest.changelog, currentChangelogHashes)) {
|
|
2700
|
-
if (!hasAssetsChanged(this._hash, this.options.sitePath, validManifest.assets)) {
|
|
2769
|
+
if (!hasAssetsChanged(this._hash, this.options.sitePath, validManifest.assets, this.options.autoReadme)) {
|
|
2701
2770
|
this._console.success("No changes detected, skipping build");
|
|
2702
2771
|
return;
|
|
2703
2772
|
}
|
|
2704
2773
|
}
|
|
2705
2774
|
const cachedDocs = validManifest ? loadCachedDocuments(this.options.sitePath) : /* @__PURE__ */ new Map();
|
|
2706
2775
|
const cachedChangelog = validManifest ? loadCachedChangelog(this.options.sitePath) : /* @__PURE__ */ new Map();
|
|
2707
|
-
await this.
|
|
2776
|
+
await fs.promises.mkdir(this.options.sitePath, { recursive: true });
|
|
2777
|
+
const autoReadmeResult = await this.autoReadme();
|
|
2778
|
+
const siteReadmeExists = !autoReadmeResult && fs.existsSync(path.join(this.options.sitePath, "README.md"));
|
|
2708
2779
|
const doculaData = {
|
|
2709
2780
|
siteUrl: this.options.siteUrl,
|
|
2710
2781
|
siteTitle: this.options.siteTitle,
|
|
@@ -2714,7 +2785,8 @@ var DoculaBuilder = class {
|
|
|
2714
2785
|
output: this.options.output,
|
|
2715
2786
|
githubPath: this.options.githubPath,
|
|
2716
2787
|
sections: this.options.sections,
|
|
2717
|
-
hasReadme:
|
|
2788
|
+
hasReadme: siteReadmeExists || autoReadmeResult !== void 0,
|
|
2789
|
+
readmeContent: autoReadmeResult?.content,
|
|
2718
2790
|
themeMode: this.options.themeMode,
|
|
2719
2791
|
cookieAuth: this.options.cookieAuth,
|
|
2720
2792
|
headerLinks: this.options.headerLinks,
|
|
@@ -2732,8 +2804,8 @@ var DoculaBuilder = class {
|
|
|
2732
2804
|
editPageUrl: this.options.editPageUrl,
|
|
2733
2805
|
openGraph: this.options.openGraph
|
|
2734
2806
|
};
|
|
2735
|
-
|
|
2736
|
-
if (
|
|
2807
|
+
if (siteReadmeExists) currentAssetHashes["README.md"] = hashFile(this._hash, path.join(this.options.sitePath, "README.md"));
|
|
2808
|
+
else if (autoReadmeResult) currentAssetHashes.__autoReadme = hashFile(this._hash, autoReadmeResult.sourcePath);
|
|
2737
2809
|
if (Array.isArray(this.options.openApiUrl)) doculaData.openApiSpecs = this.options.openApiUrl.map((spec) => ({
|
|
2738
2810
|
name: spec.name,
|
|
2739
2811
|
url: isRemoteUrl(spec.url) ? spec.url : buildUrlPath(this.options.apiPath, spec.url),
|
|
@@ -2797,7 +2869,7 @@ var DoculaBuilder = class {
|
|
|
2797
2869
|
});
|
|
2798
2870
|
doculaData.changelogEntries = allChangelogEntries;
|
|
2799
2871
|
doculaData.hasChangelog = allChangelogEntries.length > 0 && hasChangelogTemplate;
|
|
2800
|
-
/* v8 ignore next
|
|
2872
|
+
/* v8 ignore next 40 -- @preserve */
|
|
2801
2873
|
if (this._options.ai) {
|
|
2802
2874
|
const aiModel = await createAIModel(this._options.ai);
|
|
2803
2875
|
if (aiModel) {
|
|
@@ -2805,6 +2877,7 @@ var DoculaBuilder = class {
|
|
|
2805
2877
|
const aiCache = loadAIMetadataCache(this._options.sitePath);
|
|
2806
2878
|
doculaData.documents = await enrichDocuments(doculaData.documents, aiModel, this._hash, this._console, aiCache);
|
|
2807
2879
|
doculaData.changelogEntries = await enrichChangelogEntries(doculaData.changelogEntries, aiModel, this._hash, this._console, aiCache);
|
|
2880
|
+
if (doculaData.hasReadme && !doculaData.hasDocuments) doculaData.readmeMetadata = await enrichReadme(doculaData.readmeContent ?? (siteReadmeExists ? fs.readFileSync(`${this._options.sitePath}/README.md`, "utf8") : void 0), aiModel, this._hash, this._console, aiCache);
|
|
2808
2881
|
saveAIMetadataCache(this._options.sitePath, aiCache);
|
|
2809
2882
|
}
|
|
2810
2883
|
}
|
|
@@ -2941,8 +3014,10 @@ var DoculaBuilder = class {
|
|
|
2941
3014
|
if (packageJson.name && typeof packageJson.name === "string") readmeContent = `# ${packageJson.name}\n\n${readmeContent}`;
|
|
2942
3015
|
} catch {}
|
|
2943
3016
|
}
|
|
2944
|
-
|
|
2945
|
-
|
|
3017
|
+
return {
|
|
3018
|
+
sourcePath: cwdReadmePath,
|
|
3019
|
+
content: readmeContent
|
|
3020
|
+
};
|
|
2946
3021
|
}
|
|
2947
3022
|
async getGithubData(githubPath) {
|
|
2948
3023
|
const paths = githubPath.split("/");
|
|
@@ -3016,11 +3091,14 @@ var DoculaBuilder = class {
|
|
|
3016
3091
|
let content;
|
|
3017
3092
|
if (!data.hasDocuments) content = await this.buildReadmeSection(data);
|
|
3018
3093
|
const announcement = await this.buildAnnouncementSection(data);
|
|
3094
|
+
const readmeMeta = data.readmeMetadata;
|
|
3019
3095
|
const indexContent = await this._ecto.renderFromFile(indexTemplate, {
|
|
3020
3096
|
...data,
|
|
3021
3097
|
content,
|
|
3022
3098
|
announcement,
|
|
3023
|
-
|
|
3099
|
+
description: readmeMeta?.description ?? data.siteDescription,
|
|
3100
|
+
keywords: readmeMeta?.keywords,
|
|
3101
|
+
...this.resolveOpenGraphData(data, "/", readmeMeta),
|
|
3024
3102
|
jsonLd: this.resolveJsonLd("home", data, "/")
|
|
3025
3103
|
}, data.templatePath);
|
|
3026
3104
|
await fs.promises.writeFile(indexPath, indexContent, "utf8");
|
|
@@ -3051,7 +3129,8 @@ var DoculaBuilder = class {
|
|
|
3051
3129
|
}
|
|
3052
3130
|
async buildReadmeSection(data) {
|
|
3053
3131
|
let htmlReadme = "";
|
|
3054
|
-
if (
|
|
3132
|
+
if (data.readmeContent !== void 0) htmlReadme = await new Writr$1(data.readmeContent.replace(/^\s*#\s+[^\r\n]*[\r\n]*/, ""), writrOptions).render();
|
|
3133
|
+
else if (fs.existsSync(`${data.sitePath}/README.md`)) htmlReadme = await new Writr$1(fs.readFileSync(`${data.sitePath}/README.md`, "utf8"), writrOptions).render();
|
|
3055
3134
|
return htmlReadme;
|
|
3056
3135
|
}
|
|
3057
3136
|
async buildAnnouncementSection(data) {
|
package/package.json
CHANGED
|
@@ -68,12 +68,11 @@ body {
|
|
|
68
68
|
gap: 12px;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
.logo-link { display: flex; align-items: center
|
|
71
|
+
.logo-link { display: flex !important; align-items: center !important; text-decoration: none !important; color: var(--fg) !important; font-size: 18px !important; font-weight: 600 !important; }
|
|
72
72
|
.logo__img {
|
|
73
73
|
height: 75px;
|
|
74
74
|
width: auto;
|
|
75
75
|
}
|
|
76
|
-
.logo__text { font-size: 18px; font-weight: 600; }
|
|
77
76
|
|
|
78
77
|
.theme-button {
|
|
79
78
|
border: 1px solid transparent;
|
|
@@ -773,6 +772,36 @@ pre:hover .copy-code-btn { opacity: 1; }
|
|
|
773
772
|
color: #92400e;
|
|
774
773
|
}
|
|
775
774
|
|
|
775
|
+
.changelog-tag-added {
|
|
776
|
+
background-color: rgba(140, 220, 0, 0.15);
|
|
777
|
+
color: #4a7a00;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
.changelog-tag-improved {
|
|
781
|
+
background-color: rgba(59, 130, 246, 0.15);
|
|
782
|
+
color: #1d4ed8;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
.changelog-tag-fixed {
|
|
786
|
+
background-color: rgba(245, 158, 11, 0.15);
|
|
787
|
+
color: #b45309;
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
.changelog-tag-removed {
|
|
791
|
+
background-color: rgba(239, 68, 68, 0.15);
|
|
792
|
+
color: #b91c1c;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
.changelog-tag-deprecated {
|
|
796
|
+
background-color: rgba(156, 163, 175, 0.15);
|
|
797
|
+
color: #4b5563;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
.changelog-tag-security {
|
|
801
|
+
background-color: rgba(168, 85, 247, 0.15);
|
|
802
|
+
color: #6d28d9;
|
|
803
|
+
}
|
|
804
|
+
|
|
776
805
|
.changelog-entry-title::after {
|
|
777
806
|
content: "";
|
|
778
807
|
position: absolute;
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
</button>
|
|
7
7
|
<a href="{{#if homeUrl}}{{homeUrl}}{{else}}{{baseUrl}}/{{/if}}" class="logo-link">
|
|
8
8
|
<img alt="{{siteTitle}}" class="logo__img" src="{{baseUrl}}/logo.svg">
|
|
9
|
-
<span class="logo__text">{{siteTitle}}</span>
|
|
10
9
|
</a>
|
|
11
10
|
<nav class="header-bottom__nav">
|
|
12
11
|
{{#if hasDocuments}}
|