basecampjs 0.0.1 → 0.0.2

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 (2) hide show
  1. package/index.js +28 -9
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -102,10 +102,19 @@ function createLiquidEnv(layoutsDir, pagesDir, srcDir) {
102
102
  });
103
103
  }
104
104
 
105
- function pageContext(frontmatter, html, config, relPath, data) {
105
+ function toUrlPath(outRel) {
106
+ const normalized = outRel.replace(/\\/g, "/");
107
+ if (normalized.endsWith("index.html")) {
108
+ const trimmed = normalized.slice(0, -"index.html".length);
109
+ return trimmed ? `/${trimmed}` : "/";
110
+ }
111
+ return `/${normalized}`;
112
+ }
113
+
114
+ function pageContext(frontmatter, html, config, relPath, data, url = "/") {
106
115
  return {
107
116
  site: { name: config.siteName, config },
108
- page: { ...frontmatter, content: html, source: relPath },
117
+ page: { ...frontmatter, content: html, source: relPath, url },
109
118
  frontmatter,
110
119
  content: html,
111
120
  data,
@@ -145,13 +154,14 @@ async function renderPage(filePath, { pagesDir, layoutsDir, outDir, env, liquidE
145
154
  const ext = extname(filePath).toLowerCase();
146
155
  const outRel = rel.replace(/\.liquid(\.html)?$/i, ".html").replace(ext, ".html");
147
156
  const outPath = join(outDir, outRel);
157
+ const url = toUrlPath(outRel);
148
158
  await ensureDir(dirname(outPath));
149
159
 
150
160
  if (ext === ".md") {
151
161
  const raw = await readFile(filePath, "utf8");
152
162
  const parsed = matter(raw);
153
163
  const html = md.render(parsed.content);
154
- const ctx = pageContext(parsed.data, html, config, rel, data);
164
+ const ctx = pageContext(parsed.data, html, config, rel, data, url);
155
165
  const rendered = await renderWithLayout(parsed.data.layout, html, ctx, env, liquidEnv);
156
166
  await writeFile(outPath, rendered, "utf8");
157
167
  return;
@@ -160,7 +170,7 @@ async function renderPage(filePath, { pagesDir, layoutsDir, outDir, env, liquidE
160
170
  if (ext === ".njk") {
161
171
  const raw = await readFile(filePath, "utf8");
162
172
  const parsed = matter(raw);
163
- const ctx = pageContext(parsed.data, parsed.content, config, rel, data);
173
+ const ctx = pageContext(parsed.data, parsed.content, config, rel, data, url);
164
174
  const templateName = rel.replace(/\\/g, "/");
165
175
  let pageHtml = env.renderString(parsed.content, ctx, { path: templateName });
166
176
  if (shouldRenderMarkdown(parsed.data, config, false)) {
@@ -174,7 +184,7 @@ async function renderPage(filePath, { pagesDir, layoutsDir, outDir, env, liquidE
174
184
  if (ext === ".liquid" || filePath.toLowerCase().endsWith(".liquid.html")) {
175
185
  const raw = await readFile(filePath, "utf8");
176
186
  const parsed = matter(raw);
177
- const ctx = pageContext(parsed.data, parsed.content, config, rel, data);
187
+ const ctx = pageContext(parsed.data, parsed.content, config, rel, data, url);
178
188
  let pageHtml = await liquidEnv.parseAndRender(parsed.content, ctx);
179
189
  if (shouldRenderMarkdown(parsed.data, config, false)) {
180
190
  pageHtml = md.render(pageHtml);
@@ -187,7 +197,7 @@ async function renderPage(filePath, { pagesDir, layoutsDir, outDir, env, liquidE
187
197
  if (ext === ".html") {
188
198
  const raw = await readFile(filePath, "utf8");
189
199
  const parsed = matter(raw);
190
- const ctx = pageContext(parsed.data, parsed.content, config, rel, data);
200
+ const ctx = pageContext(parsed.data, parsed.content, config, rel, data, url);
191
201
  let pageHtml = parsed.content;
192
202
  if (shouldRenderMarkdown(parsed.data, config, false)) {
193
203
  pageHtml = md.render(pageHtml);
@@ -244,7 +254,11 @@ function serve(outDir, port = 4173) {
244
254
  const server = createServer(async (req, res) => {
245
255
  const urlPath = decodeURI((req.url || "/").split("?")[0]);
246
256
  const safePath = urlPath.replace(/\.\.+/g, "");
247
- let filePath = join(outDir, safePath);
257
+ const requestPath = safePath.replace(/^\/+/, "") || "index.html";
258
+ let filePath = join(outDir, requestPath);
259
+ const notFoundPath = join(outDir, "404.html");
260
+ const indexPath = join(outDir, "index.html");
261
+ let isNotFoundResponse = false;
248
262
  let stats;
249
263
 
250
264
  try {
@@ -254,13 +268,18 @@ function serve(outDir, port = 4173) {
254
268
  stats = await stat(filePath);
255
269
  }
256
270
  } catch {
257
- filePath = join(outDir, "index.html");
271
+ if (existsSync(notFoundPath)) {
272
+ filePath = notFoundPath;
273
+ isNotFoundResponse = true;
274
+ } else {
275
+ filePath = indexPath;
276
+ }
258
277
  }
259
278
 
260
279
  try {
261
280
  const data = await readFile(filePath);
262
281
  const type = mime[extname(filePath).toLowerCase()] || "text/plain";
263
- res.writeHead(200, { "Content-Type": type });
282
+ res.writeHead(isNotFoundResponse ? 404 : 200, { "Content-Type": type });
264
283
  res.end(data);
265
284
  } catch {
266
285
  res.writeHead(404, { "Content-Type": "text/plain" });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "basecampjs",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "type": "module",
5
5
  "description": "BasecampJS engine for Campsite static site generator.",
6
6
  "bin": {