dpl/scripts/tutorials/build.mjs

45 lines
3.1 KiB
JavaScript

import fs from 'node:fs/promises'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..')
const source = path.join(root, 'content/tutorials')
const output = path.join(root, 'public/tutorials')
let layout = await fs.readFile(path.join(root, 'resources/tutorials/layout.html'), 'utf8')
if (process.argv.includes('--live-reload')) {
layout = layout.replace('</body>', `@if(in_array(request()->getHost(), ['localhost', '127.0.0.1']))
<script src="/tutorials/assets/live-reload.js" defer></script>
@endif
</body>`)
}
const registry = {}
const views = path.join(root, 'resources/views/tutorials')
await fs.mkdir(path.join(output, 'assets'), {recursive: true})
await fs.copyFile(path.join(root, 'resources/tutorials/tutorial.css'), path.join(output, 'assets/tutorial.css'))
if (process.argv.includes('--live-reload')) await fs.copyFile(path.join(root, 'resources/tutorials/live-reload.js'), path.join(output, 'assets/live-reload.js'))
for (const platform of await fs.readdir(source, {withFileTypes: true})) {
if (!platform.isDirectory()) continue
for (const client of await fs.readdir(path.join(source, platform.name), {withFileTypes: true})) {
if (!client.isDirectory()) continue
const folder = path.join(source, platform.name, client.name)
const meta = JSON.parse(await fs.readFile(path.join(folder, 'meta.json'), 'utf8'))
if (meta.platform !== platform.name || meta.client !== client.name || !/^[a-z0-9-]+$/.test(platform.name) || !/^[a-z0-9-]+$/.test(client.name)) throw new Error('Invalid tutorial location')
const prefix = `/tutorials/${platform.name}/${client.name}`
let body = await fs.readFile(path.join(folder, `${meta.language}.html`), 'utf8')
for (const match of body.matchAll(/src="\.\/images\/([^"]+)"/g)) await fs.access(path.join(folder, 'images', match[1]))
body = body.replaceAll('src="./images/', `src="${prefix}/images/`)
const escape = value => value.replaceAll('&','&amp;').replaceAll('<','&lt;').replaceAll('"','&quot;')
const html = layout.replace('{{language}}', escape(meta.language)).replace('{{title}}', escape(meta.title)).replace('{{body}}', body).replaceAll('{{brand}}', '{{ $brand }}')
await fs.mkdir(path.join(output, platform.name), {recursive:true})
await fs.mkdir(path.join(views, platform.name), {recursive:true})
await fs.writeFile(path.join(views, platform.name, `${client.name}.blade.php`), html)
// Remove legacy static HTML so Laravel can inject the current configured name.
await fs.rm(path.join(output, platform.name, `${client.name}.html`), {force:true})
await fs.cp(path.join(folder,'images'), path.join(output,platform.name,client.name,'images'),{recursive:true})
registry[platform.name] = prefix + '.html'
}
}
const generated = path.join(root, 'stellar/src/generated')
await fs.mkdir(generated,{recursive:true})
await fs.writeFile(path.join(generated,'tutorials.ts'), '// Generated by scripts/tutorials/build.mjs\nexport const tutorialPages: Record<string, string> = '+JSON.stringify(registry,null,2)+'\n')
console.log(`Built ${Object.keys(registry).length} independent tutorial page(s).`)