Skip to content

Commit

Permalink
Create script to create new theme based on Carbon
Browse files Browse the repository at this point in the history
  • Loading branch information
Pierstoval committed Sep 15, 2024
1 parent 79e5cab commit 68d5ada
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 0 deletions.
100 changes: 100 additions & 0 deletions bin/create_theme.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import chalk from 'chalk';

import prompts from 'prompts';
import { spawn } from 'node:child_process';
import fs from 'node:fs/promises';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const projectDir = path.resolve(__dirname + '/../');
const themesDir = path.resolve(projectDir + '/src/lib/themes');
const carbonDir = path.resolve(themesDir + '/svelte/carbon');

//
// main
//
(async () => {
let themeType = ((process.argv[2] || '').trim() || await ask('Theme type? (svelte, react, vue)')).toLowerCase();
let themeName = ((process.argv[3] || '').trim() || await ask('What is the name of your new theme? (only lowercase letters and underscores)')).toLowerCase();

if (!themeName) {
throw new Error('No theme name provided.');
}

if (!themeType) {
throw new Error('No theme type provided. Allowed: svelte, react, vue');
}
if (!themeType.match(/^svelte|react|vue$/gi)) {
throw new Error('Wrong template type provided. Allowed: svelte, react, vue');
}

const newThemePath = carbonDir.replace(/\\/g, '/').replace(/\/svelte\/carbon$/g, `/${themeType}/${themeName}`).replace(/\//g, path.sep);

const files = (await getAllFiles(carbonDir));

for (const file of files) {
if (!file.match(/\.svelte$/gi)) {
continue;
}
const newPath = path.resolve(file.replace(carbonDir, newThemePath));
const basename = newPath.replace(projectDir + path.sep, '').replace(new RegExp('\\\\', 'g'), '/');
const dir = path.dirname(newPath);
await fs.mkdir(dir, {recursive: true});
await fs.writeFile(newPath, `TODO: Implement template "${basename}" for "${themeType}/${themeName}" theme.\n`);
}

await fs.copyFile(carbonDir+'/index.ts', newThemePath+'/index.ts');

const themesIndex = themesDir+'/'+themeType+'/index.ts';
let indexContent = (await fs.readFile(themesIndex)).toString();
if (!indexContent.match(new RegExp(`export *\\{ *default as ${themeName}`), 'gi')) {
indexContent += `\nexport { default as ${themeName} } from './${themeName}';`
}
indexContent = indexContent.replace(/\n\n+/, "\n").trim()+"\n";
await fs.writeFile(themesIndex, indexContent);
})();

async function ask(question) {
let value = '';

const max = 3;
let i = 0;
while (!value || !value.trim()) {
if (i >= max) {
process.stderr.write(' [ERROR] No answer. Stopping.\n');
process.exit(1);
}

const answer = await prompts({
type: 'text',
name: 'answer',
message: question
});

value = (answer.answer || '').trim();

i++;
}

return value;
}

async function getAllFiles(dirPath, arrayOfFiles = []) {
const files = await fs.readdir(dirPath)

arrayOfFiles = arrayOfFiles || []

for (const file of files) {
const stat = await fs.stat(dirPath + path.sep + file);
if (stat.isDirectory()) {
arrayOfFiles = await getAllFiles(dirPath + path.sep + file, arrayOfFiles)
} else {
arrayOfFiles.push(path.join(dirPath, path.sep, file))
}
}

return arrayOfFiles
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"create:field": "node bin/create_field.mjs",
"create:theme": "node bin/create_theme.mjs",
"dev": "vite dev",
"format": "prettier --plugin=prettier-plugin-svelte --write .",
"lint": "prettier --plugin=prettier-plugin-svelte . --check . && eslint -c .eslintrc.cjs src",
Expand Down

0 comments on commit 68d5ada

Please sign in to comment.