diff --git a/README.md b/README.md index 83a8f83..37e8573 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,6 @@ It's super easy to install and use. - 🤩 [Editor.js](https://editorjs.io/) ecosystem powered - 📂 Docs nesting — create any structure you need -- 💎 Static rendering - 📱 Nice look on Desktop and Mobile - 🔥 Beautiful page URLs. Human-readable and SEO-friendly. - 🦅 [Hawk](https://hawk.so/?from=docs-demo) is hunting. Errors tracking integrated diff --git a/package.json b/package.json index 4e6ae91..c9ff0c8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "codex.docs", "license": "Apache-2.0", - "version": "2.2.3", + "version": "v2.0.0-rc.4", "type": "module", "bin": { "codex.docs": "dist/backend/app.js" diff --git a/src/backend/build-static.ts b/src/backend/build-static.ts index ca0894a..d0691e0 100644 --- a/src/backend/build-static.ts +++ b/src/backend/build-static.ts @@ -13,7 +13,6 @@ import fse from 'fs-extra'; import appConfig from './utils/appConfig.js'; import Aliases from './controllers/aliases.js'; import Pages from './controllers/pages.js'; -import { downloadFavicon } from './utils/downloadFavicon.js'; /** * Build static pages from database @@ -46,42 +45,14 @@ export default async function buildStatic(): Promise { }); } - if (config.overwrite) { - console.log('Removing old static files'); - await fse.remove(distPath); - } + console.log('Removing old static files'); + await fse.remove(distPath); console.log('Building static files'); const pagesOrder = await PagesOrder.getAll(); const allPages = await Page.getAll(); - try { - console.log('Create dist folder'); - await mkdirp(distPath); - } catch (e) { - console.log('Error while creating dist folder', e); - - return; - } - - console.log('Copy public directory'); - const publicDir = path.resolve(dirname, '../../public'); - - console.log(`Copy from ${publicDir} to ${distPath}`); - - try { - await fse.copy(publicDir, distPath); - console.log('Public directory copied'); - } catch (e) { - console.log('Error while copying public directory'); - console.error(e); - } - - const favicon = appConfig.favicon ? await downloadFavicon(appConfig.favicon, distPath, '') : { - destination: '/favicon.png', - type: 'image/png', - }; - + await mkdirp(distPath); /** * Renders single page @@ -91,11 +62,6 @@ export default async function buildStatic(): Promise { */ async function renderPage(page: Page, isIndex?: boolean): Promise { console.log(`Rendering page ${page.uri}`); - const pageUri = page.uri; - - if (!pageUri) { - throw new Error('Page uri is not defined'); - } const pageParent = await page.getParent(); const pageId = page._id; @@ -106,30 +72,16 @@ export default async function buildStatic(): Promise { const previousPage = await PagesFlatArray.getPageBefore(pageId); const nextPage = await PagesFlatArray.getPageAfter(pageId); const menu = createMenuTree(parentIdOfRootPages, allPages, pagesOrder, 2); - const result = await renderTemplate('./views/pages/page.twig', { page, pageParent, previousPage, nextPage, menu, - favicon, config: appConfig.frontend, }); - let filename: string; - - if (isIndex) { - filename = 'index.html'; - } else if (config?.pagesInsideFolders) { // create folder for each page if pagesInsideFolders is true - const pagePath = path.resolve(distPath, pageUri); - - await mkdirp(pagePath); - - filename = path.resolve(pagePath, 'index.html'); - } else { - filename = `${page.uri}.html`; - } + const filename = (isIndex || page.uri === '') ? 'index.html' : `${page.uri}.html`; await fs.writeFile(path.resolve(distPath, filename), result); console.log(`Page ${page.uri} rendered`); @@ -159,16 +111,15 @@ export default async function buildStatic(): Promise { await renderPage(page); } - // Check if index page is enabled - if (config.indexPage.enabled) { - await renderIndexPage(config.indexPage.uri); - } + await renderIndexPage(config.indexPageUri); console.log('Static files built'); + console.log('Copy public directory'); + await fse.copy(path.resolve(dirname, '../../public'), distPath); + if (appConfig.uploads.driver === 'local') { console.log('Copy uploads directory'); await fse.copy(path.resolve(cwd, appConfig.uploads.local.path), path.resolve(distPath, 'uploads')); - console.log('Uploads directory copied'); } } diff --git a/src/backend/utils/appConfig.ts b/src/backend/utils/appConfig.ts index 34a5e61..c824d49 100644 --- a/src/backend/utils/appConfig.ts +++ b/src/backend/utils/appConfig.ts @@ -90,14 +90,7 @@ const FrontendConfig = z.object({ */ const StaticBuildConfig = z.object({ outputDir: z.string(), // Output directory for static build - overwrite: z.boolean().optional() // Overwrite output directory - .default(true), - pagesInsideFolders: z.boolean().optional() // Create separate folder for each page - .default(true), - indexPage: z.object({ - enabled: z.boolean(), // Is index page enabled - uri: z.string(), // Index page uri - }), + indexPageUri: z.string(), // URI for index page to render }); export type StaticBuildConfig = z.infer; diff --git a/src/backend/utils/downloadFavicon.ts b/src/backend/utils/downloadFavicon.ts index ed10cdb..73aa2c0 100644 --- a/src/backend/utils/downloadFavicon.ts +++ b/src/backend/utils/downloadFavicon.ts @@ -1,5 +1,5 @@ import path from 'path'; -import fs from 'fs/promises'; +import fs from 'fs'; import fetch, { RequestInit } from 'node-fetch'; /** @@ -32,10 +32,9 @@ function checkIsUrl(str: string): boolean { * * @param destination - url or path of favicon * @param faviconFolder - folder to save favicon - * @param subRoute - subroute from which the favicon will be served * @returns { Promise } - Promise with data about favicon */ -export async function downloadFavicon(destination: string, faviconFolder: string, subRoute = '/favicon'): Promise { +export async function downloadFavicon(destination: string, faviconFolder: string): Promise { // Check of destination is empty if (!destination) { throw Error('Favicon destination is empty'); @@ -49,10 +48,8 @@ export async function downloadFavicon(destination: string, faviconFolder: string // Check if string is url if (!checkIsUrl(destination)) { - await fs.copyFile(destination, path.join(faviconFolder, filename)); - return { - destination: `${subRoute}/${filename}`, + destination: `/${filename}`, type: `image/${format}`, } as FaviconData; } @@ -75,10 +72,14 @@ export async function downloadFavicon(destination: string, faviconFolder: string const filePath = path.join(faviconFolder, `favicon.${format}`); // Save file - await fs.writeFile(filePath, fileData); + await fs.writeFile(filePath, fileData, (err) => { + if (err) { + console.log(err); + } + }); return { - destination: `${subRoute}/favicon.${format}`, + destination: `/favicon/favicon.${format}`, type: `image/${format}`, } as FaviconData; } diff --git a/src/backend/views/pages/blocks/code.twig b/src/backend/views/pages/blocks/code.twig index 9ed997e..2402cb5 100644 --- a/src/backend/views/pages/blocks/code.twig +++ b/src/backend/views/pages/blocks/code.twig @@ -3,7 +3,7 @@
{{ code | escape }}
{% - include '../../components/copy-button.twig' with { + include 'components/copy-button.twig' with { ariaLabel: 'Copy Code to Clipboard', class: 'block-code__copy-button', textToCopy: code | escape, diff --git a/src/backend/views/pages/blocks/header.twig b/src/backend/views/pages/blocks/header.twig index d854dd9..e2e0403 100644 --- a/src/backend/views/pages/blocks/header.twig +++ b/src/backend/views/pages/blocks/header.twig @@ -1,6 +1,6 @@ {% - include '../../components/copy-button.twig' with { + include 'components/copy-button.twig' with { ariaLabel: 'Copy Link to the ' ~ text, class: 'block-header__copy-button', textToCopy: '#' ~ text | urlify, diff --git a/src/frontend/styles/components/header.pcss b/src/frontend/styles/components/header.pcss index 3c62720..0b43e9e 100644 --- a/src/frontend/styles/components/header.pcss +++ b/src/frontend/styles/components/header.pcss @@ -40,10 +40,7 @@ html { @media (--not-mobile) { padding: 4px 10px; - - &:hover { - @apply --squircle; - } + @apply --squircle; } &:hover { diff --git a/src/frontend/styles/components/sidebar.pcss b/src/frontend/styles/components/sidebar.pcss index 04f6f83..7ce04ca 100644 --- a/src/frontend/styles/components/sidebar.pcss +++ b/src/frontend/styles/components/sidebar.pcss @@ -182,16 +182,13 @@ transition-property: background-color; transition-duration: 0.1s; + @apply --squircle; + &--selected { border-radius: 8px; /* border using box-shadow which doesn't increase the height */ box-shadow: 0 0 0 2px rgba(147, 166, 233, 0.5) inset; } - - &--active, - &:hover { - @apply --squircle; - } } &__section-title > span, diff --git a/src/frontend/styles/components/table-of-content.pcss b/src/frontend/styles/components/table-of-content.pcss index a3f5674..ab3c921 100644 --- a/src/frontend/styles/components/table-of-content.pcss +++ b/src/frontend/styles/components/table-of-content.pcss @@ -31,10 +31,7 @@ gap: 2px; &-item { - &:hover, - &--active { - @apply --squircle; - } + @apply --squircle; &:hover { background-color: var(--color-link-hover);