Skip to content

Commit

Permalink
Added support for template
Browse files Browse the repository at this point in the history
  • Loading branch information
follestad committed Feb 9, 2023
1 parent 019d21e commit e31ed28
Show file tree
Hide file tree
Showing 4 changed files with 227 additions and 61 deletions.
151 changes: 110 additions & 41 deletions bin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,71 +2,140 @@
const fs = require('fs');
const {program} = require('commander');


/*
|--------------------------------------------------------------------------
| Settings
|--------------------------------------------------------------------------
*/

program
.version(require('../package').version)
.description(require('../package').description + '\n\nUSAGE: csshtml-module -i [inputFile] -o [outputFile]')
.requiredOption('-i, --input <file>', 'input file to convert (required)')
.option('-i, --input <file>', 'input file to convert (will be ignored if --template is set)')
.requiredOption('-o, --output <file>', 'destination file. Should end with .ts or .js (required)')
.option('-n, --name <string>', 'the name of the JS constant')
.option(' --template', 'compile to a web component template containing css and html. The --input should be added without .html and .css extension')
.option('-d, --delay <int>', 'the time, in milliseconds, that the script should wait before compiling')
.option('-l, --language <string>', 'typehint the language - to help IDE\'s understand the content' )
.option('-n, --name <string>', 'the name of the JS constant (will be ignored if --template is set)')
.option('--html <string>', 'html file to use in template')
.option('--css <string>', 'css file to use in template ')
.parse(process.argv);


const settings = {
input: program.getOptionValue('input'),
output: program.getOptionValue('output'),
name: program.getOptionValue('name') || 'content',
typescript: program.getOptionValue('output').endsWith('.ts'),
delay: program.getOptionValue('delay') ? parseInt(program.getOptionValue('delay')) : 5,
isTemplate: !!program.getOptionValue('template'),
html: program.getOptionValue('html'),
css: program.getOptionValue('css')
};


/**
* Check if file exists and is readable
*
* @param filepath
* @returns {boolean}
*/
function fileExists(filepath) {
let flag = true;
try {
fs.accessSync(filepath, fs.constants.F_OK);
} catch (e) {
flag = false;
}
try {
fs.accessSync(filepath, fs.constants.R_OK);
} catch (e) {
flag = false;
}
return flag;
}


/*
|--------------------------------------------------------------------------
| Validate input
|--------------------------------------------------------------------------
*/

/** Validate output */
if (!settings.output.endsWith('.ts') && !settings.output.endsWith('.js')) {
throw new Error('Output file must end with .ts or .js');
}

/** Make sure input file is defined if not --template is specified */
if (!settings.isTemplate && !settings.input) {
throw new Error('Either --input or --template must be specified');
}

/** Make sure input file exists if not --template is specified */
if (!settings.isTemplate && !fileExists(settings.input)) {
throw new Error(`${settings.input} file does not exist or is not readable`);
}

if (settings.isTemplate) {
/** Make sure either --css or --html is specified if --template is specified */
if (!settings.css && !settings.html) {
throw new Error(`Either a --css or --html file must be specified when using --template`);
}

/** Make sure either --css or --html exists if --template is specified */
if ((settings.css && !fileExists(settings.css)) && (settings.html && !fileExists(settings.html))) {
throw new Error(`Either a --css or --html file does not exist or is not readable`);
}
}


/*
|--------------------------------------------------------------------------
| Generate output
|--------------------------------------------------------------------------
*/

/**
* Get file content
* @param {string} file
* @returns {string}
*/
function fileContent(file) {
return fs.readFileSync(file, 'utf-8');
if (!fileExists(file)) return '';
return fs.readFileSync(file, 'utf-8').trim();
}

/**
* Create js/ts module content
* @param {{inputFile: string, outputFile: string, language: (any|string), type: string}} s
* @param {string} content
* Create js/ts module with single type
* @param s
* @returns {string}
*/
function template(s, content) {
let temp = '';
if (s.language) temp += `// language=${s.language}\r\n`;
if (s.type === 'ts') {
temp += `export const ${s.name}: string = \`${content}\`;`;
} else {
temp += `export const ${s.name} = \`${content}\`;`;
}
return temp;
function single(s) {
let lang = s.input.split('.').pop();
if (s.typescript) return `// language=${lang}\nexport const ${s.name}: string = \`${fileContent(s.input)}\`;`;
return `// language=${lang}\nexport const ${s.name} = \`${fileContent(s.input)}\`;`;
}


/**
* Convert settings and content to output file
*
* @param {{inputFile: string, outputFile: string, language: (any|string), type: string}} s
* Create js/ts module with template
* @param s
* @returns {string}
*/
function convert(s) {
const content = fileContent(s.inputFile);
fs.writeFile(s.outputFile, template(s, content), (err) => {
if (err) {
console.error(err);
return;
}
console.log(`Converted file complete: ${s.outputFile}`);
});
function template(s) {
const content = `<style>${fileContent(s.css)}</style>${fileContent(s.html)}`.replace('<style></style>', '');
if (s.typescript) return `export const template: HTMLTemplateElement = document.createElement('template');\ntemplate.innerHTML = \`${content}\`;`;
return `export const template = document.createElement('template');\ntemplate.innerHTML =\`${content}\`;`;
}


/**
* Settings default
*
* @type {{inputFile: string, outputFile: string, delay: (any|number), language: string, type: string}}
* Create js/ts module content
*/
const settings = {
inputFile: program.getOptionValue('input'),
outputFile: program.getOptionValue('output'),
language: program.getOptionValue('language'),
name: program.getOptionValue('name') || 'css',
type: program.getOptionValue('output').endsWith('.ts') ? 'ts' : 'js',
delay: program.getOptionValue('delay') || 5
};

setTimeout(() => convert(settings), settings.delay);
setTimeout(() => {
fs.writeFile(settings.output, settings.isTemplate ? template(settings) : single(settings), (err) => {
if (err) throw err;
console.log(`Converted file complete: ${settings.output}`);
});
}, settings.delay);
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "csshtml-module",
"version": "1.0.1",
"version": "1.5.0",
"description": "Easily compile CSS or HTML files to JavaScript/TypeScript modules with this CLI tool.",
"license": "MIT",
"repository": "rammewerk/csshtml-module",
Expand Down Expand Up @@ -32,6 +32,8 @@
"webstorm",
"JetBrains",
"jet brains",
"transform"
"transform",
"template-generator",
"template"
]
}
Loading

0 comments on commit e31ed28

Please sign in to comment.