diff options
-rw-r--r-- | src/write/build-modes/static-build.js | 148 | ||||
-rw-r--r-- | src/write/write-files.js | 161 |
2 files changed, 140 insertions, 169 deletions
diff --git a/src/write/build-modes/static-build.js b/src/write/build-modes/static-build.js index eafb53d6..b3700c43 100644 --- a/src/write/build-modes/static-build.js +++ b/src/write/build-modes/static-build.js @@ -1,3 +1,5 @@ +import * as path from 'path'; + import {bindUtilities} from '../bind-utilities.js'; import {validateWrites} from '../validate-writes.js'; @@ -8,12 +10,6 @@ import { generateRedirectHTML, } from '../page-template.js'; -import { - writePage, - writeSharedFilesAndPages, - writeSymlinks, -} from '../write-files.js'; - import {serializeThings} from '../../data/serialize.js'; import * as pageSpecs from '../../page/index.js'; @@ -120,12 +116,15 @@ export async function go({ urls, }); - await writeSharedFilesAndPages({ + await writeFavicon({ mediaPath, outputPath, - urls, + }); + await writeSharedFilesAndPages({ language: defaultLanguage, + outputPath, + urls, wikiData, wikiDataJSON: generateGlobalWikiDataJSON({ serializeThings, @@ -421,3 +420,136 @@ async function wrapLanguages(fn, { await fn(language, i, entries); } } + +import { + copyFile, + mkdir, + stat, + symlink, + writeFile, + unlink, +} from 'fs/promises'; + +async function writePage({ + html, + oEmbedJSON = '', + paths, +}) { + await mkdir(paths.output.directory, {recursive: true}); + + await Promise.all([ + writeFile(paths.output.documentHTML, html), + + oEmbedJSON && + writeFile(paths.output.oEmbedJSON, oEmbedJSON), + ].filter(Boolean)); +} + +function writeSymlinks({ + srcRootPath, + mediaPath, + outputPath, + urls, +}) { + return progressPromiseAll('Writing site symlinks.', [ + link(path.join(srcRootPath, 'util'), 'shared.utilityRoot'), + link(path.join(srcRootPath, 'static'), 'shared.staticRoot'), + link(mediaPath, 'media.root'), + ]); + + async function link(directory, urlKey) { + const pathname = urls.from('shared.root').toDevice(urlKey); + const file = path.join(outputPath, pathname); + + try { + await unlink(file); + } catch (error) { + if (error.code !== 'ENOENT') { + throw error; + } + } + + try { + await symlink(path.resolve(directory), file); + } catch (error) { + if (error.code === 'EPERM') { + await symlink(path.resolve(directory), file, 'junction'); + } + } + } +} + +async function writeFavicon({ + mediaPath, + outputPath, +}) { + const faviconFile = 'favicon.ico'; + + try { + await stat(path.join(mediaPath, faviconFile)); + } catch (error) { + return; + } + + try { + await copyFile( + path.join(mediaPath, faviconFile), + path.join(outputPath, faviconFile)); + } catch (error) { + logWarn`Failed to copy favicon! ${error.message}`; + return; + } + + logInfo`Copied favicon to site root.`; +} + +async function writeSharedFilesAndPages({ + language, + outputPath, + urls, + wikiData, + wikiDataJSON, +}) { + const {groupData, wikiInfo} = wikiData; + + return progressPromiseAll(`Writing files & pages shared across languages.`, [ + groupData?.some((group) => group.directory === 'fandom') && + redirect( + 'Fandom - Gallery', + 'albums/fandom', + 'localized.groupGallery', + 'fandom' + ), + + groupData?.some((group) => group.directory === 'official') && + redirect( + 'Official - Gallery', + 'albums/official', + 'localized.groupGallery', + 'official' + ), + + wikiInfo.enableListings && + redirect( + 'Album Commentary', + 'list/all-commentary', + 'localized.commentaryIndex', + '' + ), + + wikiDataJSON && + writeFile( + path.join(outputPath, 'data.json'), + wikiDataJSON), + ].filter(Boolean)); + + async function redirect(title, from, urlKey, directory) { + const target = path.relative( + from, + urls.from('shared.root').to(urlKey, directory) + ); + const content = generateRedirectHTML(title, target, {language}); + await mkdir(path.join(outputPath, from), {recursive: true}); + await writeFile(path.join(outputPath, from, 'index.html'), content); + } +} diff --git a/src/write/write-files.js b/src/write/write-files.js deleted file mode 100644 index 8b6ac3af..00000000 --- a/src/write/write-files.js +++ /dev/null @@ -1,161 +0,0 @@ -import * as path from 'path'; - -import {generateRedirectHTML} from './page-template.js'; - -import { - logInfo, - logWarn, - progressPromiseAll, -} from '../util/cli.js'; - -// Code that's common 8etween the 8uild code (i.e. upd8.js) and gener8ted -// site code should 8e put here. Which, uh, ~~only really means this one -// file~~ is now a variety of useful utilities! -// -// Rather than hard code it, anything in this directory can 8e shared across -// 8oth ends of the code8ase. -// (This gets symlinked into the --data-path directory.) -const UTILITY_DIRECTORY = 'util'; - -// Code that's used only in the static site! CSS, cilent JS, etc. -// (This gets symlinked into the --data-path directory.) -const STATIC_DIRECTORY = 'static'; - -import { - copyFile, - mkdir, - stat, - symlink, - writeFile, - unlink, -} from 'fs/promises'; - -export async function writePage({ - html, - oEmbedJSON = '', - paths, -}) { - await mkdir(paths.output.directory, {recursive: true}); - - await Promise.all([ - writeFile(paths.output.documentHTML, html), - - oEmbedJSON && - writeFile(paths.output.oEmbedJSON, oEmbedJSON), - ].filter(Boolean)); -} - -export function writeSymlinks({ - srcRootPath, - mediaPath, - outputPath, - urls, -}) { - return progressPromiseAll('Writing site symlinks.', [ - link(path.join(srcRootPath, UTILITY_DIRECTORY), 'shared.utilityRoot'), - link(path.join(srcRootPath, STATIC_DIRECTORY), 'shared.staticRoot'), - link(mediaPath, 'media.root'), - ]); - - async function link(directory, urlKey) { - const pathname = urls.from('shared.root').toDevice(urlKey); - const file = path.join(outputPath, pathname); - - try { - await unlink(file); - } catch (error) { - if (error.code !== 'ENOENT') { - throw error; - } - } - - try { - await symlink(path.resolve(directory), file); - } catch (error) { - if (error.code === 'EPERM') { - await symlink(path.resolve(directory), file, 'junction'); - } - } - } -} - -export async function writeFavicon({ - mediaPath, - outputPath, -}) { - const faviconFile = 'favicon.ico'; - - try { - await stat(path.join(mediaPath, faviconFile)); - } catch (error) { - return; - } - - try { - await copyFile( - path.join(mediaPath, faviconFile), - path.join(outputPath, faviconFile)); - } catch (error) { - logWarn`Failed to copy favicon! ${error.message}`; - return; - } - - logInfo`Copied favicon to site root.`; -} - -export async function writeSharedFilesAndPages({ - language, - mediaPath, - outputPath, - urls, - wikiData, - wikiDataJSON, -}) { - const {groupData, wikiInfo} = wikiData; - - await writeFavicon({ - mediaPath, - outputPath, - }); - - return progressPromiseAll(`Writing files & pages shared across languages.`, [ - groupData?.some((group) => group.directory === 'fandom') && - redirect( - 'Fandom - Gallery', - 'albums/fandom', - 'localized.groupGallery', - 'fandom' - ), - - groupData?.some((group) => group.directory === 'official') && - redirect( - 'Official - Gallery', - 'albums/official', - 'localized.groupGallery', - 'official' - ), - - wikiInfo.enableListings && - redirect( - 'Album Commentary', - 'list/all-commentary', - 'localized.commentaryIndex', - '' - ), - - wikiDataJSON && - writeFile( - path.join(outputPath, 'data.json'), - wikiDataJSON), - ].filter(Boolean)); - - async function redirect(title, from, urlKey, directory) { - const target = path.relative( - from, - urls.from('shared.root').to(urlKey, directory) - ); - const content = generateRedirectHTML(title, target, {language}); - await mkdir(path.join(outputPath, from), {recursive: true}); - await writeFile(path.join(outputPath, from, 'index.html'), content); - } -} |