- Introduced a Makefile for streamlined commands related to building, running, and managing presentations. - Created package.json to define project metadata, dependencies, and scripts for development and testing. - Added .gitignore entries to exclude build artifacts and temporary files from version control. - Included playwright.config.mjs for end-to-end testing setup with Playwright. - Added README.md for project documentation, outlining setup instructions and development guidelines.
106 lines
3.5 KiB
JavaScript
106 lines
3.5 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* create | delete | clone | rename — cohérence slides + portail (sync).
|
|
*/
|
|
import fs from 'node:fs'
|
|
import path from 'node:path'
|
|
import { fileURLToPath } from 'node:url'
|
|
import { execFileSync } from 'node:child_process'
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
const root = path.resolve(__dirname, '..')
|
|
|
|
function sync() {
|
|
execFileSync(process.execPath, [path.join(root, 'tools', 'sync-portal.mjs')], {
|
|
stdio: 'inherit',
|
|
cwd: root,
|
|
env: process.env,
|
|
})
|
|
}
|
|
|
|
function assertSlug(s, label = 'slug') {
|
|
if (!s || typeof s !== 'string') throw new Error(`${label} manquant`)
|
|
if (!/^[a-z0-9-]+$/.test(s)) throw new Error(`${label} invalide (a-z 0-9 -): ${s}`)
|
|
if (s.length < 2) throw new Error(`${label} trop court`)
|
|
if (s === 'portal') throw new Error('slug réservé')
|
|
}
|
|
|
|
const cmd = process.argv[2]
|
|
const a = process.argv[3]
|
|
const b = process.argv[4]
|
|
|
|
try {
|
|
if (cmd === 'create') {
|
|
assertSlug(a)
|
|
const dir = path.join(root, 'slides', a)
|
|
if (fs.existsSync(dir)) throw new Error(`existe déjà: slides/${a}/`)
|
|
fs.mkdirSync(dir, { recursive: true })
|
|
fs.writeFileSync(
|
|
path.join(dir, 'meta.json'),
|
|
JSON.stringify(
|
|
{
|
|
title: 'Nouvelle présentation',
|
|
description: '',
|
|
order: 99,
|
|
tags: [],
|
|
},
|
|
null,
|
|
2,
|
|
),
|
|
'utf8',
|
|
)
|
|
fs.writeFileSync(
|
|
path.join(dir, 'slides.md'),
|
|
['---', 'title: Nouvelle présentation', '---', '', '# Bienvenue', ''].join('\n'),
|
|
'utf8',
|
|
)
|
|
sync()
|
|
console.log(`[create] slides/${a}/ — lancez make run ou make build`)
|
|
} else if (cmd === 'delete') {
|
|
assertSlug(a)
|
|
fs.rmSync(path.join(root, 'slides', a), { recursive: true, force: true })
|
|
fs.rmSync(path.join(root, `dist-${a}`), { recursive: true, force: true })
|
|
sync()
|
|
console.log(`[delete] ${a} retiré`)
|
|
} else if (cmd === 'clone') {
|
|
assertSlug(a, 'source')
|
|
assertSlug(b, 'dest')
|
|
const src = path.join(root, 'slides', a)
|
|
const dst = path.join(root, 'slides', b)
|
|
if (!fs.existsSync(src)) throw new Error(`source absente: slides/${a}/`)
|
|
if (fs.existsSync(dst)) throw new Error(`dest existe: slides/${b}/`)
|
|
fs.cpSync(src, dst, { recursive: true })
|
|
const metaPath = path.join(dst, 'meta.json')
|
|
const meta = JSON.parse(fs.readFileSync(metaPath, 'utf8'))
|
|
meta.title = `${meta.title || a} (copie)`
|
|
fs.writeFileSync(metaPath, JSON.stringify(meta, null, 2), 'utf8')
|
|
sync()
|
|
console.log(`[clone] ${a} → ${b} — build: node tools/build-deck.mjs ${b}`)
|
|
} else if (cmd === 'rename') {
|
|
assertSlug(a, 'ancien')
|
|
assertSlug(b, 'nouveau')
|
|
const src = path.join(root, 'slides', a)
|
|
const dst = path.join(root, 'slides', b)
|
|
if (!fs.existsSync(src)) throw new Error(`slides/${a}/ absent`)
|
|
if (fs.existsSync(dst)) throw new Error(`slides/${b}/ existe déjà`)
|
|
fs.renameSync(src, dst)
|
|
const metaPath = path.join(dst, 'meta.json')
|
|
const meta = JSON.parse(fs.readFileSync(metaPath, 'utf8'))
|
|
delete meta.slug
|
|
fs.writeFileSync(metaPath, JSON.stringify(meta, null, 2), 'utf8')
|
|
const oldDist = path.join(root, `dist-${a}`)
|
|
const newDist = path.join(root, `dist-${b}`)
|
|
if (fs.existsSync(oldDist)) {
|
|
fs.renameSync(oldDist, newDist)
|
|
}
|
|
sync()
|
|
console.log(`[rename] ${a} → ${b}`)
|
|
} else {
|
|
console.error('usage: node tools/presentation-cli.mjs <create|delete|clone|rename> [args]')
|
|
process.exit(1)
|
|
}
|
|
} catch (e) {
|
|
console.error(String(e.message || e))
|
|
process.exit(1)
|
|
}
|