Skip to content

Commit e31ed28

Browse files
committed
Added support for template
1 parent 019d21e commit e31ed28

File tree

4 files changed

+227
-61
lines changed

4 files changed

+227
-61
lines changed

bin/index.js

Lines changed: 110 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,71 +2,140 @@
22
const fs = require('fs');
33
const {program} = require('commander');
44

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

1524

25+
const settings = {
26+
input: program.getOptionValue('input'),
27+
output: program.getOptionValue('output'),
28+
name: program.getOptionValue('name') || 'content',
29+
typescript: program.getOptionValue('output').endsWith('.ts'),
30+
delay: program.getOptionValue('delay') ? parseInt(program.getOptionValue('delay')) : 5,
31+
isTemplate: !!program.getOptionValue('template'),
32+
html: program.getOptionValue('html'),
33+
css: program.getOptionValue('css')
34+
};
35+
36+
37+
/**
38+
* Check if file exists and is readable
39+
*
40+
* @param filepath
41+
* @returns {boolean}
42+
*/
43+
function fileExists(filepath) {
44+
let flag = true;
45+
try {
46+
fs.accessSync(filepath, fs.constants.F_OK);
47+
} catch (e) {
48+
flag = false;
49+
}
50+
try {
51+
fs.accessSync(filepath, fs.constants.R_OK);
52+
} catch (e) {
53+
flag = false;
54+
}
55+
return flag;
56+
}
57+
58+
59+
/*
60+
|--------------------------------------------------------------------------
61+
| Validate input
62+
|--------------------------------------------------------------------------
63+
*/
64+
65+
/** Validate output */
66+
if (!settings.output.endsWith('.ts') && !settings.output.endsWith('.js')) {
67+
throw new Error('Output file must end with .ts or .js');
68+
}
69+
70+
/** Make sure input file is defined if not --template is specified */
71+
if (!settings.isTemplate && !settings.input) {
72+
throw new Error('Either --input or --template must be specified');
73+
}
74+
75+
/** Make sure input file exists if not --template is specified */
76+
if (!settings.isTemplate && !fileExists(settings.input)) {
77+
throw new Error(`${settings.input} file does not exist or is not readable`);
78+
}
79+
80+
if (settings.isTemplate) {
81+
/** Make sure either --css or --html is specified if --template is specified */
82+
if (!settings.css && !settings.html) {
83+
throw new Error(`Either a --css or --html file must be specified when using --template`);
84+
}
85+
86+
/** Make sure either --css or --html exists if --template is specified */
87+
if ((settings.css && !fileExists(settings.css)) && (settings.html && !fileExists(settings.html))) {
88+
throw new Error(`Either a --css or --html file does not exist or is not readable`);
89+
}
90+
}
91+
92+
93+
/*
94+
|--------------------------------------------------------------------------
95+
| Generate output
96+
|--------------------------------------------------------------------------
97+
*/
98+
1699
/**
17100
* Get file content
18101
* @param {string} file
19102
* @returns {string}
20103
*/
21104
function fileContent(file) {
22-
return fs.readFileSync(file, 'utf-8');
105+
if (!fileExists(file)) return '';
106+
return fs.readFileSync(file, 'utf-8').trim();
23107
}
24108

25109
/**
26-
* Create js/ts module content
27-
* @param {{inputFile: string, outputFile: string, language: (any|string), type: string}} s
28-
* @param {string} content
110+
* Create js/ts module with single type
111+
* @param s
29112
* @returns {string}
30113
*/
31-
function template(s, content) {
32-
let temp = '';
33-
if (s.language) temp += `// language=${s.language}\r\n`;
34-
if (s.type === 'ts') {
35-
temp += `export const ${s.name}: string = \`${content}\`;`;
36-
} else {
37-
temp += `export const ${s.name} = \`${content}\`;`;
38-
}
39-
return temp;
114+
function single(s) {
115+
let lang = s.input.split('.').pop();
116+
if (s.typescript) return `// language=${lang}\nexport const ${s.name}: string = \`${fileContent(s.input)}\`;`;
117+
return `// language=${lang}\nexport const ${s.name} = \`${fileContent(s.input)}\`;`;
40118
}
41119

120+
42121
/**
43-
* Convert settings and content to output file
44-
*
45-
* @param {{inputFile: string, outputFile: string, language: (any|string), type: string}} s
122+
* Create js/ts module with template
123+
* @param s
124+
* @returns {string}
46125
*/
47-
function convert(s) {
48-
const content = fileContent(s.inputFile);
49-
fs.writeFile(s.outputFile, template(s, content), (err) => {
50-
if (err) {
51-
console.error(err);
52-
return;
53-
}
54-
console.log(`Converted file complete: ${s.outputFile}`);
55-
});
126+
function template(s) {
127+
const content = `<style>${fileContent(s.css)}</style>${fileContent(s.html)}`.replace('<style></style>', '');
128+
if (s.typescript) return `export const template: HTMLTemplateElement = document.createElement('template');\ntemplate.innerHTML = \`${content}\`;`;
129+
return `export const template = document.createElement('template');\ntemplate.innerHTML =\`${content}\`;`;
56130
}
57131

132+
58133
/**
59-
* Settings default
60-
*
61-
* @type {{inputFile: string, outputFile: string, delay: (any|number), language: string, type: string}}
134+
* Create js/ts module content
62135
*/
63-
const settings = {
64-
inputFile: program.getOptionValue('input'),
65-
outputFile: program.getOptionValue('output'),
66-
language: program.getOptionValue('language'),
67-
name: program.getOptionValue('name') || 'css',
68-
type: program.getOptionValue('output').endsWith('.ts') ? 'ts' : 'js',
69-
delay: program.getOptionValue('delay') || 5
70-
};
71-
72-
setTimeout(() => convert(settings), settings.delay);
136+
setTimeout(() => {
137+
fs.writeFile(settings.output, settings.isTemplate ? template(settings) : single(settings), (err) => {
138+
if (err) throw err;
139+
console.log(`Converted file complete: ${settings.output}`);
140+
});
141+
}, settings.delay);

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "csshtml-module",
3-
"version": "1.0.1",
3+
"version": "1.5.0",
44
"description": "Easily compile CSS or HTML files to JavaScript/TypeScript modules with this CLI tool.",
55
"license": "MIT",
66
"repository": "rammewerk/csshtml-module",
@@ -32,6 +32,8 @@
3232
"webstorm",
3333
"JetBrains",
3434
"jet brains",
35-
"transform"
35+
"transform",
36+
"template-generator",
37+
"template"
3638
]
3739
}

0 commit comments

Comments
 (0)