@moonwave99/goffre 0.1.5 → 0.1.6
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/chunk-DQk6qfdC.mjs +18 -0
- package/dist/generator.d.mts +73 -0
- package/dist/generator.mjs +36553 -0
- package/dist/index.d.mts +141 -0
- package/dist/index.mjs +280 -0
- package/package.json +5 -4
- package/dist/index.d.ts +0 -188
- package/dist/index.js +0 -5191
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { MarkedExtension, RendererObject } from "marked";
|
|
2
|
+
import { HelperOptions } from "handlebars";
|
|
3
|
+
|
|
4
|
+
//#region lib/goffre.d.ts
|
|
5
|
+
type Page = {
|
|
6
|
+
slug: string;
|
|
7
|
+
link?: string;
|
|
8
|
+
template?: string;
|
|
9
|
+
layout?: string | null;
|
|
10
|
+
content?: string;
|
|
11
|
+
extname?: string;
|
|
12
|
+
};
|
|
13
|
+
declare function getSlug(slug: string, params: Record<string, unknown>): string;
|
|
14
|
+
type GetTemplateParams = {
|
|
15
|
+
page: Page;
|
|
16
|
+
templates: string[];
|
|
17
|
+
defaultTemplate?: string;
|
|
18
|
+
};
|
|
19
|
+
declare function getTemplate({
|
|
20
|
+
page,
|
|
21
|
+
templates,
|
|
22
|
+
defaultTemplate
|
|
23
|
+
}: GetTemplateParams): string;
|
|
24
|
+
type LoadParams = {
|
|
25
|
+
dataPath?: string;
|
|
26
|
+
};
|
|
27
|
+
declare function load({
|
|
28
|
+
dataPath
|
|
29
|
+
}?: LoadParams): Promise<{
|
|
30
|
+
json: {};
|
|
31
|
+
pages: {
|
|
32
|
+
excerpt: string;
|
|
33
|
+
slug: string;
|
|
34
|
+
description: any;
|
|
35
|
+
content: string;
|
|
36
|
+
}[];
|
|
37
|
+
}>;
|
|
38
|
+
declare function loadJSON(cwd: string): Promise<{}>;
|
|
39
|
+
declare function loadMarkdown(cwd: string): Promise<{
|
|
40
|
+
excerpt: string;
|
|
41
|
+
slug: string;
|
|
42
|
+
description: any;
|
|
43
|
+
content: string;
|
|
44
|
+
}[]>;
|
|
45
|
+
type GetSorterParams = {
|
|
46
|
+
sortBy: string;
|
|
47
|
+
order: "asc" | "desc";
|
|
48
|
+
};
|
|
49
|
+
declare function getSorter<T extends Record<string, unknown>>({
|
|
50
|
+
sortBy,
|
|
51
|
+
order
|
|
52
|
+
}: GetSorterParams): (a: T, b: T) => number;
|
|
53
|
+
type RenderParams = {
|
|
54
|
+
pages: Page[];
|
|
55
|
+
viewsPath?: string;
|
|
56
|
+
buildPath?: string;
|
|
57
|
+
blockSeparator?: string;
|
|
58
|
+
domain?: string;
|
|
59
|
+
uglyUrls?: boolean;
|
|
60
|
+
logLevel?: "silent" | "verbose" | "normal";
|
|
61
|
+
locals: Record<string, unknown>;
|
|
62
|
+
sitemap?: {
|
|
63
|
+
generate?: boolean;
|
|
64
|
+
template?: string;
|
|
65
|
+
};
|
|
66
|
+
env?: Record<string, unknown>;
|
|
67
|
+
handlebars?: {
|
|
68
|
+
extname?: string;
|
|
69
|
+
helpers?: Record<string, unknown>;
|
|
70
|
+
};
|
|
71
|
+
markdown?: {
|
|
72
|
+
middleware?: (MarkedExtension | (() => MarkedExtension))[];
|
|
73
|
+
renderer?: RendererObject;
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
declare function render({
|
|
77
|
+
pages,
|
|
78
|
+
viewsPath,
|
|
79
|
+
buildPath,
|
|
80
|
+
blockSeparator,
|
|
81
|
+
domain,
|
|
82
|
+
uglyUrls,
|
|
83
|
+
logLevel,
|
|
84
|
+
locals,
|
|
85
|
+
markdown,
|
|
86
|
+
handlebars,
|
|
87
|
+
sitemap,
|
|
88
|
+
env
|
|
89
|
+
}: RenderParams): Promise<unknown[]>;
|
|
90
|
+
type PaginateParams<T extends Page> = {
|
|
91
|
+
collection: T[];
|
|
92
|
+
size?: number;
|
|
93
|
+
sortBy?: keyof T;
|
|
94
|
+
order?: "asc" | "desc";
|
|
95
|
+
};
|
|
96
|
+
type PaginatedResult<T extends Page> = {
|
|
97
|
+
pagination: {
|
|
98
|
+
page: number;
|
|
99
|
+
prev: number | null;
|
|
100
|
+
next: number | null;
|
|
101
|
+
total: number;
|
|
102
|
+
};
|
|
103
|
+
items: T[];
|
|
104
|
+
};
|
|
105
|
+
declare function paginate<T extends Page>({
|
|
106
|
+
collection,
|
|
107
|
+
size,
|
|
108
|
+
sortBy,
|
|
109
|
+
order
|
|
110
|
+
}: PaginateParams<T>): PaginatedResult<T>[];
|
|
111
|
+
declare namespace helpers_d_exports {
|
|
112
|
+
export { getAsset, getExcerpt, getLink, getNavClass, getParamLink, getSitemapLink, list, markdown$1 as markdown, nextItem, prevItem };
|
|
113
|
+
}
|
|
114
|
+
type Context = {
|
|
115
|
+
data: {
|
|
116
|
+
root: {
|
|
117
|
+
options?: {
|
|
118
|
+
domain?: string;
|
|
119
|
+
env?: {
|
|
120
|
+
mode?: string;
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
type HelperContext = Context & Omit<HelperOptions, "fn" | "inverse">;
|
|
127
|
+
type BlockContext = Context & HelperOptions;
|
|
128
|
+
declare const markdown$1: (text: string) => string | Promise<string>;
|
|
129
|
+
declare function getExcerpt(content: string): Promise<string>;
|
|
130
|
+
declare const getParamLink: (url: string, options: HelperContext) => string;
|
|
131
|
+
declare const getAsset: (asset: string, context: Omit<HelperContext, "hash">) => string;
|
|
132
|
+
declare const getSitemapLink: (page: Page, context: HelperContext) => string;
|
|
133
|
+
declare const getLink: (page: Page, context: HelperContext) => string;
|
|
134
|
+
declare const getNavClass: ({
|
|
135
|
+
slug
|
|
136
|
+
}: Page, currentPage: Page) => string;
|
|
137
|
+
declare const list: (context: Page[], options: BlockContext) => string;
|
|
138
|
+
declare const nextItem: (context: Page, options: Pick<BlockContext, "hash" | "fn">) => string | undefined;
|
|
139
|
+
declare const prevItem: (context: Page, options: Pick<BlockContext, "hash" | "fn">) => string | undefined;
|
|
140
|
+
//#endregion
|
|
141
|
+
export { Page, getSlug, getSorter, getTemplate, helpers_d_exports as helpers, load, loadJSON, loadMarkdown, paginate, render };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import { t as __exportAll } from "./chunk-DQk6qfdC.mjs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { globby } from "globby";
|
|
4
|
+
import { marked } from "marked";
|
|
5
|
+
import matter from "gray-matter";
|
|
6
|
+
import { createRequire } from "module";
|
|
7
|
+
import fs from "fs-extra";
|
|
8
|
+
import express from "express";
|
|
9
|
+
import { engine } from "express-handlebars";
|
|
10
|
+
import chalk from "chalk";
|
|
11
|
+
import slugify from "slugify";
|
|
12
|
+
import { stripHtml } from "string-strip-html";
|
|
13
|
+
|
|
14
|
+
//#region lib/helpers.ts
|
|
15
|
+
var helpers_exports = /* @__PURE__ */ __exportAll({
|
|
16
|
+
getAsset: () => getAsset,
|
|
17
|
+
getExcerpt: () => getExcerpt,
|
|
18
|
+
getLink: () => getLink,
|
|
19
|
+
getNavClass: () => getNavClass,
|
|
20
|
+
getParamLink: () => getParamLink,
|
|
21
|
+
getSitemapLink: () => getSitemapLink,
|
|
22
|
+
list: () => list,
|
|
23
|
+
markdown: () => markdown,
|
|
24
|
+
nextItem: () => nextItem,
|
|
25
|
+
prevItem: () => prevItem
|
|
26
|
+
});
|
|
27
|
+
const markdown = (text) => marked(text);
|
|
28
|
+
async function getExcerpt(content) {
|
|
29
|
+
const firstParagraph = content.split("\n").filter(Boolean).at(0);
|
|
30
|
+
if (!firstParagraph) return "";
|
|
31
|
+
return stripHtml(await marked(firstParagraph)).result;
|
|
32
|
+
}
|
|
33
|
+
const getParamLink = (url, options) => {
|
|
34
|
+
return getAsset(getSlug(url, options.hash), options);
|
|
35
|
+
};
|
|
36
|
+
const getAsset = (asset, context) => {
|
|
37
|
+
const { options, env } = context.data.root;
|
|
38
|
+
return env.mode === "prod" && options.domain ? `${options.domain}${asset.startsWith("/") ? "" : "/"}${asset}` : asset;
|
|
39
|
+
};
|
|
40
|
+
const getSitemapLink = (page, context) => {
|
|
41
|
+
const { options } = context.data.root;
|
|
42
|
+
return `${options.domain}${getLink(page, context)}`;
|
|
43
|
+
};
|
|
44
|
+
const getLink = (page, context) => {
|
|
45
|
+
const base = page.link || `${page.slug.startsWith("/") ? "" : "/"}${page.slug}`;
|
|
46
|
+
const { uglyUrls } = context.data.root.options;
|
|
47
|
+
if (uglyUrls) return getAsset(`${base === "/" ? "/index" : base}.html`, context);
|
|
48
|
+
return getAsset(base.replace(/^\/index/, "/"), context);
|
|
49
|
+
};
|
|
50
|
+
const getNavClass = ({ slug }, currentPage) => {
|
|
51
|
+
const cleanSlug = slug && slug[0] === "/" ? slug.slice(1) : slug;
|
|
52
|
+
return currentPage.slug.startsWith(cleanSlug) ? `${cleanSlug} current` : cleanSlug;
|
|
53
|
+
};
|
|
54
|
+
const list = (context, options) => {
|
|
55
|
+
const offset = parseInt(options.hash.offset, 10) || 0;
|
|
56
|
+
const limit = parseInt(options.hash.limit, 10) || 100;
|
|
57
|
+
const sortBy = options.hash.sortBy || "slug";
|
|
58
|
+
const order = options.hash.order || "asc";
|
|
59
|
+
let output = "";
|
|
60
|
+
let i;
|
|
61
|
+
const data = context.toSorted(getSorter({
|
|
62
|
+
sortBy,
|
|
63
|
+
order
|
|
64
|
+
}));
|
|
65
|
+
if (offset < 0) i = -offset < data.length ? data.length - -offset : 0;
|
|
66
|
+
else i = offset < data.length ? offset : 0;
|
|
67
|
+
const j = limit + i < data.length ? limit + i : data.length;
|
|
68
|
+
for (; i < j; i++) output += options.fn(data[i]);
|
|
69
|
+
return output;
|
|
70
|
+
};
|
|
71
|
+
const nextItem = (context, options) => {
|
|
72
|
+
const { list } = options.hash;
|
|
73
|
+
const next = list[list.findIndex((x) => x.slug === context.slug) + 1];
|
|
74
|
+
if (!next) return;
|
|
75
|
+
return options.fn(next);
|
|
76
|
+
};
|
|
77
|
+
const prevItem = (context, options) => {
|
|
78
|
+
const { list } = options.hash;
|
|
79
|
+
const prev = list[list.findIndex((x) => x.slug === context.slug) - 1];
|
|
80
|
+
if (!prev) return;
|
|
81
|
+
return options.fn(prev);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
//#endregion
|
|
85
|
+
//#region lib/goffre.ts
|
|
86
|
+
const require = createRequire(import.meta.url);
|
|
87
|
+
const { readFile, outputFile } = fs;
|
|
88
|
+
const DEFAULT_DATA_PATH = path.join(process.cwd(), "data");
|
|
89
|
+
const DEFAULT_VIEWS_PATH = path.join(process.cwd(), "src", "views");
|
|
90
|
+
const DEFAULT_BUILD_PATH = path.join(process.cwd(), "dist");
|
|
91
|
+
const MAX_SLUG_LOG_LENGTH = 40;
|
|
92
|
+
const DEFAULT_BLOCK_SEPARATOR = "<!-- block -->";
|
|
93
|
+
const thisYear = (/* @__PURE__ */ new Date()).getFullYear();
|
|
94
|
+
function log(...args) {
|
|
95
|
+
console.log.apply(null, ["[goffre]", ...args].map((x) => chalk.cyan(x)));
|
|
96
|
+
}
|
|
97
|
+
function getEnv() {
|
|
98
|
+
return { mode: process.env.MODE || "dev" };
|
|
99
|
+
}
|
|
100
|
+
function stringify(token) {
|
|
101
|
+
if (token instanceof Date) return token.toISOString().split("T")[0];
|
|
102
|
+
return `${token}`;
|
|
103
|
+
}
|
|
104
|
+
function getSlug(slug, params) {
|
|
105
|
+
return slug.split("/").reduce((memo, x) => {
|
|
106
|
+
if (!x.startsWith(":")) return [...memo, x];
|
|
107
|
+
const param = x.slice(1);
|
|
108
|
+
const value = params[param];
|
|
109
|
+
if (!value) throw new Error(`No value found for parameter: ${param}`);
|
|
110
|
+
return [...memo, slugify(stringify(value), {
|
|
111
|
+
lower: true,
|
|
112
|
+
strict: true
|
|
113
|
+
})];
|
|
114
|
+
}, []).join("/");
|
|
115
|
+
}
|
|
116
|
+
function getTemplate({ page, templates = [], defaultTemplate = "_default" }) {
|
|
117
|
+
if (templates.find((x) => x === `${page.template}.handlebars`)) return page.template;
|
|
118
|
+
if (templates.find((x) => x.startsWith(page.slug))) return page.slug;
|
|
119
|
+
return defaultTemplate;
|
|
120
|
+
}
|
|
121
|
+
function renderPage({ app, templates, buildPath, maxSlugLogLength, blockSeparator, sitemapLink, ...page }) {
|
|
122
|
+
return new Promise((resolve, reject) => {
|
|
123
|
+
const template = getTemplate({
|
|
124
|
+
page,
|
|
125
|
+
templates
|
|
126
|
+
});
|
|
127
|
+
switch (app.locals.options.logLevel) {
|
|
128
|
+
case "silent": break;
|
|
129
|
+
case "verbose":
|
|
130
|
+
log(`Generating ${chalk.yellow(page.slug.padEnd(maxSlugLogLength || MAX_SLUG_LOG_LENGTH, " "))} with template ${chalk.green(template)}...`);
|
|
131
|
+
break;
|
|
132
|
+
default: log(`Generating ${chalk.yellow(page.slug)}...`);
|
|
133
|
+
}
|
|
134
|
+
app.render(template, {
|
|
135
|
+
...page,
|
|
136
|
+
sitemapLink,
|
|
137
|
+
thisYear,
|
|
138
|
+
layout: typeof page.layout === "undefined" ? "main" : page.layout,
|
|
139
|
+
content: page.content ? marked.parse(page.content) : null,
|
|
140
|
+
blocks: getPageBlocks(page.content, blockSeparator || DEFAULT_BLOCK_SEPARATOR)
|
|
141
|
+
}, async (error, html) => {
|
|
142
|
+
if (error) {
|
|
143
|
+
reject(error);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const outputFileName = `${page.slug}${page.extname || ".html"}`;
|
|
147
|
+
await outputFile(path.join(buildPath, outputFileName), html);
|
|
148
|
+
resolve({
|
|
149
|
+
...page,
|
|
150
|
+
outputFileName
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
function getPageBlocks(content = "", separator) {
|
|
156
|
+
if (!content.includes(separator)) return [];
|
|
157
|
+
return content.split(separator).map((x) => marked.parse(x)).filter(Boolean);
|
|
158
|
+
}
|
|
159
|
+
async function load({ dataPath } = {}) {
|
|
160
|
+
return {
|
|
161
|
+
json: await loadJSON(dataPath || DEFAULT_DATA_PATH),
|
|
162
|
+
pages: await loadMarkdown(dataPath || DEFAULT_DATA_PATH)
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
async function loadJSON(cwd) {
|
|
166
|
+
return (await globby("**/*.json", { cwd })).reduce((memo, x) => ({
|
|
167
|
+
...memo,
|
|
168
|
+
[path.basename(x, ".json")]: require(path.join(cwd, x))
|
|
169
|
+
}), {});
|
|
170
|
+
}
|
|
171
|
+
async function loadMarkdown(cwd) {
|
|
172
|
+
const files = await globby("**/*.md", { cwd });
|
|
173
|
+
return Promise.all(files.map(async (fileName) => {
|
|
174
|
+
const parsed = matter(await readFile(path.join(cwd, fileName), "utf-8"));
|
|
175
|
+
const outputFileName = fileName.replace(".md", "");
|
|
176
|
+
const slug = !parsed.data.slug ? outputFileName : getSlug(parsed.data.slug, parsed.data);
|
|
177
|
+
return {
|
|
178
|
+
...parsed.data,
|
|
179
|
+
excerpt: await getExcerpt(parsed.content),
|
|
180
|
+
slug,
|
|
181
|
+
description: parsed.data.description || parsed.excerpt,
|
|
182
|
+
content: parsed.content
|
|
183
|
+
};
|
|
184
|
+
}));
|
|
185
|
+
}
|
|
186
|
+
function getSorter({ sortBy, order }) {
|
|
187
|
+
return (a, b) => {
|
|
188
|
+
let output;
|
|
189
|
+
const valA = a[sortBy];
|
|
190
|
+
const valB = b[sortBy];
|
|
191
|
+
if (valA instanceof Date && valB instanceof Date) output = Number(new Date(valA)) - Number(new Date(valB));
|
|
192
|
+
else output = Number(valA) - Number(valB);
|
|
193
|
+
return order === "desc" ? -output : output;
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
async function render({ pages, viewsPath = DEFAULT_VIEWS_PATH, buildPath = DEFAULT_BUILD_PATH, blockSeparator = DEFAULT_BLOCK_SEPARATOR, domain, uglyUrls = false, logLevel = "normal", locals = {}, markdown = {}, handlebars = {}, sitemap = {}, env = {} }) {
|
|
197
|
+
const extname = handlebars.extname || ".handlebars";
|
|
198
|
+
const app = express();
|
|
199
|
+
app.engine(extname, engine({
|
|
200
|
+
...handlebars,
|
|
201
|
+
helpers: {
|
|
202
|
+
...helpers_exports,
|
|
203
|
+
...handlebars.helpers
|
|
204
|
+
}
|
|
205
|
+
}));
|
|
206
|
+
app.set("view engine", "handlebars");
|
|
207
|
+
app.set("layoutsDir", path.join(viewsPath, "layouts"));
|
|
208
|
+
app.set("views", viewsPath);
|
|
209
|
+
const templates = await globby(`**/*${extname}`, { cwd: viewsPath });
|
|
210
|
+
app.locals = {
|
|
211
|
+
...app.locals,
|
|
212
|
+
...locals,
|
|
213
|
+
options: {
|
|
214
|
+
domain,
|
|
215
|
+
uglyUrls,
|
|
216
|
+
logLevel
|
|
217
|
+
},
|
|
218
|
+
env: {
|
|
219
|
+
...getEnv(),
|
|
220
|
+
...env
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
if (markdown.middleware) markdown.middleware.forEach((x) => marked.use(typeof x === "function" ? x() : x));
|
|
224
|
+
marked.use(markdown);
|
|
225
|
+
switch (logLevel) {
|
|
226
|
+
case "silent": break;
|
|
227
|
+
default: log(`Start generation...`);
|
|
228
|
+
}
|
|
229
|
+
const results = await Promise.all(pages.map((x) => renderPage({
|
|
230
|
+
...x,
|
|
231
|
+
buildPath,
|
|
232
|
+
app,
|
|
233
|
+
templates,
|
|
234
|
+
sitemapLink: sitemap.generate ? `${domain}/sitemap.xml` : "",
|
|
235
|
+
blockSeparator,
|
|
236
|
+
maxSlugLogLength: Math.min(Math.max.call(null, ...pages.map((x) => x.slug.length)), MAX_SLUG_LOG_LENGTH)
|
|
237
|
+
})));
|
|
238
|
+
switch (logLevel) {
|
|
239
|
+
case "silent": break;
|
|
240
|
+
default: log(`Generated ${results.length} pages`);
|
|
241
|
+
}
|
|
242
|
+
if (sitemap.generate) renderPage({
|
|
243
|
+
slug: "sitemap",
|
|
244
|
+
template: sitemap.template || "sitemap",
|
|
245
|
+
extname: ".xml",
|
|
246
|
+
layout: null,
|
|
247
|
+
pages: results,
|
|
248
|
+
buildPath,
|
|
249
|
+
app,
|
|
250
|
+
templates
|
|
251
|
+
});
|
|
252
|
+
return results;
|
|
253
|
+
}
|
|
254
|
+
function paginate({ collection, size = 10, sortBy = "slug", order = "asc" }) {
|
|
255
|
+
const total = Math.ceil(collection.length / size);
|
|
256
|
+
return collection.toSorted(getSorter({
|
|
257
|
+
sortBy,
|
|
258
|
+
order
|
|
259
|
+
})).reduce((memo, x, index) => {
|
|
260
|
+
if (index % size === 0) {
|
|
261
|
+
const page = Math.floor(index / size) + 1;
|
|
262
|
+
return [...memo, {
|
|
263
|
+
pagination: {
|
|
264
|
+
page,
|
|
265
|
+
prev: page > 1 ? page - 1 : null,
|
|
266
|
+
next: page < total ? page + 1 : null,
|
|
267
|
+
total
|
|
268
|
+
},
|
|
269
|
+
items: [x]
|
|
270
|
+
}];
|
|
271
|
+
}
|
|
272
|
+
return [...memo.slice(0, -1), {
|
|
273
|
+
...memo[memo.length - 1],
|
|
274
|
+
items: [...memo[memo.length - 1].items, x]
|
|
275
|
+
}];
|
|
276
|
+
}, []);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
//#endregion
|
|
280
|
+
export { getSlug, getSorter, getTemplate, helpers_exports as helpers, load, loadJSON, loadMarkdown, paginate, render };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moonwave99/goffre",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Mini static site generator",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Diego Caponera",
|
|
@@ -47,6 +47,7 @@
|
|
|
47
47
|
"fs-extra": "^10.0.0",
|
|
48
48
|
"globby": "^12.0.2",
|
|
49
49
|
"gray-matter": "^4.0.3",
|
|
50
|
+
"handlebars": "^4.7.8",
|
|
50
51
|
"marked": "^17.0.3",
|
|
51
52
|
"slugify": "^1.6.2",
|
|
52
53
|
"string-strip-html": "^13.5.3"
|
|
@@ -72,13 +73,13 @@
|
|
|
72
73
|
"js-yaml": "^4.1.1",
|
|
73
74
|
"rimraf": "^6.1.3",
|
|
74
75
|
"sinon": "^21.0.1",
|
|
76
|
+
"tsdown": "^0.20.3",
|
|
75
77
|
"tsimp": "^2.0.12",
|
|
76
|
-
"tsup": "^8.5.1",
|
|
77
78
|
"typescript": "^5.9.3"
|
|
78
79
|
},
|
|
79
80
|
"scripts": {
|
|
80
|
-
"build": "
|
|
81
|
-
"dev": "
|
|
81
|
+
"build": "tsdown",
|
|
82
|
+
"dev": "tsdown --watch",
|
|
82
83
|
"test": "ava **/*.test.ts",
|
|
83
84
|
"lint": "pnpm eslint ./lib --ext .js,.jsx,.ts,.tsx"
|
|
84
85
|
}
|
package/dist/index.d.ts
DELETED
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
import { MarkedExtension, RendererObject } from 'marked';
|
|
2
|
-
import { HelperOptions } from 'handlebars';
|
|
3
|
-
|
|
4
|
-
type Page = {
|
|
5
|
-
slug: string;
|
|
6
|
-
link?: string;
|
|
7
|
-
template?: string;
|
|
8
|
-
layout?: string | null;
|
|
9
|
-
content?: string;
|
|
10
|
-
extname?: string;
|
|
11
|
-
};
|
|
12
|
-
declare function getSlug(slug: string, params: Record<string, unknown>): string;
|
|
13
|
-
type GetTemplateParams = {
|
|
14
|
-
page: Page;
|
|
15
|
-
templates: string[];
|
|
16
|
-
defaultTemplate?: string;
|
|
17
|
-
};
|
|
18
|
-
declare function getTemplate({ page, templates, defaultTemplate, }: GetTemplateParams): string;
|
|
19
|
-
type LoadParams = {
|
|
20
|
-
dataPath?: string;
|
|
21
|
-
};
|
|
22
|
-
declare function load({ dataPath }?: LoadParams): Promise<{
|
|
23
|
-
json: {};
|
|
24
|
-
pages: {
|
|
25
|
-
excerpt: string;
|
|
26
|
-
slug: string;
|
|
27
|
-
description: any;
|
|
28
|
-
content: string;
|
|
29
|
-
}[];
|
|
30
|
-
}>;
|
|
31
|
-
declare function loadJSON(cwd: string): Promise<{}>;
|
|
32
|
-
declare function loadMarkdown(cwd: string): Promise<{
|
|
33
|
-
excerpt: string;
|
|
34
|
-
slug: string;
|
|
35
|
-
description: any;
|
|
36
|
-
content: string;
|
|
37
|
-
}[]>;
|
|
38
|
-
type GetSorterParams = {
|
|
39
|
-
sortBy: string;
|
|
40
|
-
order: "asc" | "desc";
|
|
41
|
-
};
|
|
42
|
-
declare function getSorter<T extends Record<string, unknown>>({ sortBy, order, }: GetSorterParams): (a: T, b: T) => number;
|
|
43
|
-
type RenderParams = {
|
|
44
|
-
pages: Page[];
|
|
45
|
-
viewsPath?: string;
|
|
46
|
-
buildPath?: string;
|
|
47
|
-
blockSeparator?: string;
|
|
48
|
-
domain?: string;
|
|
49
|
-
uglyUrls?: boolean;
|
|
50
|
-
logLevel?: "silent" | "verbose" | "normal";
|
|
51
|
-
locals: Record<string, unknown>;
|
|
52
|
-
sitemap?: {
|
|
53
|
-
generate?: boolean;
|
|
54
|
-
template?: string;
|
|
55
|
-
};
|
|
56
|
-
env?: Record<string, unknown>;
|
|
57
|
-
handlebars?: {
|
|
58
|
-
extname?: string;
|
|
59
|
-
helpers?: Record<string, unknown>;
|
|
60
|
-
};
|
|
61
|
-
markdown?: {
|
|
62
|
-
middleware?: (MarkedExtension | (() => MarkedExtension))[];
|
|
63
|
-
renderer?: RendererObject;
|
|
64
|
-
};
|
|
65
|
-
};
|
|
66
|
-
declare function render({ pages, viewsPath, buildPath, blockSeparator, domain, uglyUrls, logLevel, locals, markdown, handlebars, sitemap, env, }: RenderParams): Promise<unknown[]>;
|
|
67
|
-
type PaginateParams<T extends Page> = {
|
|
68
|
-
collection: T[];
|
|
69
|
-
size?: number;
|
|
70
|
-
sortBy?: keyof T;
|
|
71
|
-
order?: "asc" | "desc";
|
|
72
|
-
};
|
|
73
|
-
type PaginatedResult<T extends Page> = {
|
|
74
|
-
pagination: {
|
|
75
|
-
page: number;
|
|
76
|
-
prev: number | null;
|
|
77
|
-
next: number | null;
|
|
78
|
-
total: number;
|
|
79
|
-
};
|
|
80
|
-
items: T[];
|
|
81
|
-
};
|
|
82
|
-
declare function paginate<T extends Page>({ collection, size, sortBy, order, }: PaginateParams<T>): PaginatedResult<T>[];
|
|
83
|
-
|
|
84
|
-
type Context = {
|
|
85
|
-
data: {
|
|
86
|
-
root: {
|
|
87
|
-
options?: {
|
|
88
|
-
domain?: string;
|
|
89
|
-
env?: {
|
|
90
|
-
mode?: string;
|
|
91
|
-
};
|
|
92
|
-
};
|
|
93
|
-
};
|
|
94
|
-
};
|
|
95
|
-
};
|
|
96
|
-
type HelperContext = Context & Omit<HelperOptions, "fn" | "inverse">;
|
|
97
|
-
type BlockContext = Context & HelperOptions;
|
|
98
|
-
declare const markdown: (text: string) => string | Promise<string>;
|
|
99
|
-
declare function getExcerpt(content: string): Promise<string>;
|
|
100
|
-
declare const getParamLink: (url: string, options: HelperContext) => string;
|
|
101
|
-
declare const getAsset: (asset: string, context: Omit<HelperContext, "hash">) => string;
|
|
102
|
-
declare const getSitemapLink: (page: Page, context: HelperContext) => string;
|
|
103
|
-
declare const getLink: (page: Page, context: HelperContext) => string;
|
|
104
|
-
declare const getNavClass: ({ slug }: Page, currentPage: Page) => string;
|
|
105
|
-
declare const list: (context: Page[], options: BlockContext) => string;
|
|
106
|
-
declare const nextItem: (context: Page, options: Pick<BlockContext, "hash" | "fn">) => string | undefined;
|
|
107
|
-
declare const prevItem: (context: Page, options: Pick<BlockContext, "hash" | "fn">) => string | undefined;
|
|
108
|
-
|
|
109
|
-
declare const helpers_getAsset: typeof getAsset;
|
|
110
|
-
declare const helpers_getExcerpt: typeof getExcerpt;
|
|
111
|
-
declare const helpers_getLink: typeof getLink;
|
|
112
|
-
declare const helpers_getNavClass: typeof getNavClass;
|
|
113
|
-
declare const helpers_getParamLink: typeof getParamLink;
|
|
114
|
-
declare const helpers_getSitemapLink: typeof getSitemapLink;
|
|
115
|
-
declare const helpers_list: typeof list;
|
|
116
|
-
declare const helpers_markdown: typeof markdown;
|
|
117
|
-
declare const helpers_nextItem: typeof nextItem;
|
|
118
|
-
declare const helpers_prevItem: typeof prevItem;
|
|
119
|
-
declare namespace helpers {
|
|
120
|
-
export { helpers_getAsset as getAsset, helpers_getExcerpt as getExcerpt, helpers_getLink as getLink, helpers_getNavClass as getNavClass, helpers_getParamLink as getParamLink, helpers_getSitemapLink as getSitemapLink, helpers_list as list, helpers_markdown as markdown, helpers_nextItem as nextItem, helpers_prevItem as prevItem };
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
declare function getRandomProjectNames(length: number): string[];
|
|
124
|
-
type WriteOutputParams = {
|
|
125
|
-
basePath: string;
|
|
126
|
-
fileName: string;
|
|
127
|
-
output: string;
|
|
128
|
-
};
|
|
129
|
-
declare function writeOutput({ basePath, fileName, output, }: WriteOutputParams): Promise<void>;
|
|
130
|
-
declare function toMarkdownFile({ content, ...frontMatter }: {
|
|
131
|
-
content: string;
|
|
132
|
-
frontMatter: Record<string, unknown>;
|
|
133
|
-
}): string;
|
|
134
|
-
type GeneratePostParams = {
|
|
135
|
-
index: number;
|
|
136
|
-
template?: string;
|
|
137
|
-
slug?: string;
|
|
138
|
-
withBlocks?: boolean;
|
|
139
|
-
};
|
|
140
|
-
declare function generatePost({ index, template, slug, withBlocks, }: GeneratePostParams): {
|
|
141
|
-
title: string;
|
|
142
|
-
template: string;
|
|
143
|
-
created_at: Date;
|
|
144
|
-
slug: string;
|
|
145
|
-
cover: {
|
|
146
|
-
url: string;
|
|
147
|
-
caption: string;
|
|
148
|
-
attribution: {
|
|
149
|
-
text: string;
|
|
150
|
-
link: string;
|
|
151
|
-
};
|
|
152
|
-
};
|
|
153
|
-
fileName: string;
|
|
154
|
-
content: string;
|
|
155
|
-
};
|
|
156
|
-
declare function generateProject({ name, index, }: {
|
|
157
|
-
name: string;
|
|
158
|
-
index: number;
|
|
159
|
-
}): {
|
|
160
|
-
title: string;
|
|
161
|
-
slug: string;
|
|
162
|
-
template: string;
|
|
163
|
-
work_date: Date;
|
|
164
|
-
homepage: string;
|
|
165
|
-
demo: string;
|
|
166
|
-
technologies: string[];
|
|
167
|
-
cover: {
|
|
168
|
-
url: string;
|
|
169
|
-
caption: string;
|
|
170
|
-
attribution: {
|
|
171
|
-
text: string;
|
|
172
|
-
link: string;
|
|
173
|
-
};
|
|
174
|
-
};
|
|
175
|
-
fileName: string;
|
|
176
|
-
content: string;
|
|
177
|
-
};
|
|
178
|
-
|
|
179
|
-
declare const generator_generatePost: typeof generatePost;
|
|
180
|
-
declare const generator_generateProject: typeof generateProject;
|
|
181
|
-
declare const generator_getRandomProjectNames: typeof getRandomProjectNames;
|
|
182
|
-
declare const generator_toMarkdownFile: typeof toMarkdownFile;
|
|
183
|
-
declare const generator_writeOutput: typeof writeOutput;
|
|
184
|
-
declare namespace generator {
|
|
185
|
-
export { generator_generatePost as generatePost, generator_generateProject as generateProject, generator_getRandomProjectNames as getRandomProjectNames, generator_toMarkdownFile as toMarkdownFile, generator_writeOutput as writeOutput };
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
export { type Page, generator, getSlug, getSorter, getTemplate, helpers, load, loadJSON, loadMarkdown, paginate, render };
|