@melcanz85/chaincss 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/chaincss.js +94 -0
  2. package/package.json +22 -0
  3. package/transpiler.js +226 -0
package/chaincss.js ADDED
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env node
2
+
3
+ // INCLUDE SEVERAL NODEJS MODULES
4
+ const vm = require('vm');
5
+ const path = require('path');
6
+ const fs = require('fs');
7
+ const chokidar = require('chokidar');
8
+ const CleanCSS = require('clean-css');
9
+
10
+ // CUSTOM MADE MODULE INSIDE JSS FOLDER
11
+ const transpilerModule = require('./transpiler.js');
12
+
13
+ console.log(__dirname);
14
+ // FUNCTION TO PROCESS CHUNKS OF SCRIPTS FROM THE INPUT FILE USING THE VM MODULE
15
+ const processScript = (scriptBlock) => {
16
+ //const output = 'cssOutput = undefined;';
17
+ const context = vm.createContext({
18
+ ...transpilerModule // Only expose what's needed
19
+ });
20
+ //vm.runInContext('cssOutput = undefined;', context);
21
+ const jsCode = scriptBlock.trim(); //`(function() { ${scriptBlock.trim()} })();`; Wrap script in IIFE
22
+ const chainScript = new vm.Script(jsCode);
23
+ chainScript.runInContext(context); // Execute in isolated context
24
+ return context.chain.cssOutput; // Return the processed output
25
+ };
26
+
27
+ // CSS Minification Function
28
+ const minifyCss = (css) => {
29
+ const output = new CleanCSS().minify(css);
30
+ if (output.errors.length > 0) {
31
+ console.error('CSS Minification Errors:', output.errors);
32
+ return null;
33
+ }
34
+ return output.styles;
35
+ };
36
+
37
+ // FUNCTION TO CONVERT JS CODES TO CSS CODE
38
+ const processor = (inputFile, outputFile) => {
39
+ const input = path.resolve(inputFile);
40
+ const content = fs.readFileSync(input, 'utf8');
41
+ const blocks = content.split(/<@([\s\S]*?)@>/gm);
42
+ let outputCSS = '';
43
+
44
+ for (let i = 0; i < blocks.length; i++) {
45
+ if (i % 2 === 0) {
46
+ outputCSS += blocks[i]; // Write the existing CSS as is
47
+ } else {
48
+ const scriptBlock = blocks[i];
49
+ try {
50
+ const outputProcessScript = processScript(scriptBlock);
51
+ if (typeof outputProcessScript !== 'object' && typeof outputProcessScript !== 'undefined') {
52
+ outputCSS += outputProcessScript;
53
+ }
54
+ } catch (err) {
55
+ console.error(`Error processing script block in ${inputFile}:`, err.stack);
56
+ throw err; // Stop the process by re-throwing the error
57
+ }
58
+ }
59
+ }
60
+ const outputDir = path.resolve(outputFile);
61
+ const trimmedCSS = outputCSS.trim();
62
+ const minCSS = minifyCss(trimmedCSS);
63
+ fs.writeFileSync(outputDir, minCSS, 'utf8'); // Write processed CSS
64
+ };
65
+
66
+ // Watch function
67
+ function watch(inputFile, outputFile) {
68
+ console.log(`Watching for changes in ${inputFile}...`);
69
+ chokidar.watch(inputFile).on('change', () => {
70
+ console.log(`File changed: ${inputFile}`);
71
+ processor(inputFile, outputFile);
72
+ });
73
+ }
74
+
75
+ // Main CLI logic
76
+ if (require.main === module) {
77
+ const args = process.argv.slice(2);
78
+ const inputFile = args[0];
79
+ const outputFile = args[1];
80
+ const watchMode = args.includes('--watch');
81
+
82
+ if (!inputFile || !outputFile) {
83
+ console.error('Usage: chaincss <inputFile> <outputFile> [--watch]');
84
+ process.exit(1);
85
+ }
86
+
87
+ processor(inputFile, outputFile);
88
+
89
+ if (watchMode) {
90
+ watch(inputFile, outputFile);
91
+ }
92
+ }
93
+
94
+ module.exports = { processor, watch };
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@melcanz85/chaincss",
3
+ "version": "1.5.0",
4
+ "description": "A simple package transpiler for js to css",
5
+ "main": "chaincss.js",
6
+ "bin": {
7
+ "chaincss": "./chaincss.js"
8
+ },
9
+ "dependencies": {
10
+ "chokidar": "^3.5.3",
11
+ "clean-css": "^5.3.3"
12
+ },
13
+ "keywords": [
14
+ "css",
15
+ "js",
16
+ "transpiler",
17
+ "compiler"
18
+ ],
19
+ "author": "Rommel Caneos",
20
+ "license": "MIT"
21
+ }
22
+
package/transpiler.js ADDED
@@ -0,0 +1,226 @@
1
+ const chain = {
2
+ cssOutput : undefined,
3
+ catcher: {},
4
+
5
+ // Backgrounds
6
+ bg(bg){ this.catcher.background = bg; return this; },
7
+ bgColor(bgc){ this.catcher.backgroundColor = bgc; return this; },
8
+ bgImage(bgi){ this.catcher.backgroundImage = bgi; return this; },
9
+ bgRepeat(bgr){ this.catcher.backgroundRepeat = bgr; return this; },
10
+ bgAttachment(bga){ this.catcher.backgroundAttachment = bga; return this; },
11
+ bgPosition(bgp){ this.catcher.backgroundPosition = bgp; return this; },
12
+
13
+ // Text
14
+ color(c){ this.catcher.color = c; return this; },
15
+ direction(d){ this.catcher.direction = d; return this; },
16
+ unicodeBidi(ub){ this.catcher.unicodeBidi = ub; return this; },
17
+ verticalAlign(va){ this.catcher.verticalAlign = va; return this; },
18
+ textTransform(t){ this.catcher.textTransform = t; return this; },
19
+ textShadow(s){ this.catcher.textShadow = s; return this; },
20
+ textAlign(ta){ this.catcher.textAlign = ta; return this; },
21
+ textAlignLast(tal){ this.catcher.textAlignLast = tal; return this; },
22
+ textDecoration(value, style){
23
+ if (style === undefined) {
24
+ this.catcher.textDecoration = value;
25
+ } else {
26
+ this.catcher.textDecorationStyle = value;
27
+ }
28
+ return this;
29
+ },
30
+
31
+ // Text-spacing
32
+ textIndent(ti){ this.catcher.textIndent = ti; return this; },
33
+ letterSpacing(ls){ this.catcher.letterSpacing = ls; return this; },
34
+ lineHeight(lh){ this.catcher.lineHeight = lh; return this; },
35
+ wordSpacing(ws){ this.catcher.wordSpacing = ws; return this; },
36
+ whiteSpace(sws){ this.catcher.whiteSpace = sws; return this; },
37
+
38
+ // Border
39
+ border(b){ this.catcher.border = b; return this; },
40
+ borderStyle(bs){ this.catcher.borderStyle = bs; return this; },
41
+ borderWidth(bw){ this.catcher.borderWidth = bw; return this; },
42
+ borderColor(bc){ this.catcher.borderColor = bc; return this; },
43
+ borderRadius(br){ this.catcher.borderRadius = br; return this; },
44
+ borderSideStyle(side, value){
45
+ if (side === 'top') {
46
+ this.catcher.borderTopStyle = value;
47
+ } else if (side === 'right') {
48
+ this.catcher.borderRightStyle = value;
49
+ } else if (side === 'bottom') {
50
+ this.catcher.borderBottomStyle = value;
51
+ } else if (side === 'left') {
52
+ this.catcher.borderLeftStyle = value;
53
+ }
54
+ return this;
55
+ },
56
+
57
+ // Font
58
+ fontFamily(f){ this.catcher.fontFamily = f; return this; },
59
+ fontStyle(s){ this.catcher.fontStyle = s; return this; },
60
+ fontWeight(w){ this.catcher.fontWeight = w; return this; },
61
+ fontVariant(v){ this.catcher.fontVariant = v; return this; },
62
+ fontSize(si){ this.catcher.fontSize = si; return this; },
63
+
64
+ // Display
65
+ display(d){ this.catcher.display = d; return this; },
66
+ flex(f){ this.catcher.flex = f; return this; },
67
+ alignContent(ac){ this.catcher.alignContent = ac; return this; },
68
+ alignSelf(as){ this.catcher.alignSelf = as; return this; },
69
+ alignItems(ai){ this.catcher.alignItems = ai; return this; },
70
+ justifyContent(jc){ this.catcher.justifyContent = jc; return this; },
71
+ flexWrap(fw){ this.catcher.flexWrap = fw; return this; },
72
+ flexGrow(fg){ this.catcher.flexGrow = fg; return this; },
73
+ flexDirection(fd){ this.catcher.flexDirection = fd; return this; },
74
+ order(o){ this.catcher.order = o; return this; },
75
+ visibility(v){ this.catcher.visibility = v; return this; },
76
+
77
+ // Height, Width and Max-width
78
+ width(w){ this.catcher.width = w; return this; },
79
+ minWidth(mnw){ this.catcher.minWidth = mnw; return this; },
80
+ maxWidth(mxw){ this.catcher.maxWidth = mxw; return this; },
81
+ height(h){ this.catcher.height = h; return this; },
82
+ minHeight(mnh){ this.catcher.minHeight = mnh; return this; },
83
+ maxHeight(mxh){ this.catcher.maxHeight = mxh; return this; },
84
+
85
+ // Padding
86
+ padding(p){ this.catcher.padding = p; return this; },
87
+ paddingTop(pt){ this.catcher.paddingTop = pt; return this; },
88
+ paddingRight(pr){ this.catcher.paddingRight = pr; return this; },
89
+ paddingBottom(pb){ this.catcher.paddingBottom = pb; return this; },
90
+ paddingLeft(pl){ this.catcher.paddingLeft = pl; return this; },
91
+
92
+ // Margin
93
+ margin(m){ this.catcher.margin = m; return this; },
94
+ marginTop(mt){ this.catcher.marginTop = mt; return this; },
95
+ marginRight(mr){ this.catcher.marginRight = mr; return this; },
96
+ marginBottom(mb){ this.catcher.marginBottom = mb; return this; },
97
+ marginLeft(ml){ this.catcher.marginLeft = ml; return this; },
98
+
99
+ // Overflow
100
+ overflow(o){ this.catcher.overflow = o; return this; },
101
+ overflowX(ox){ this.catcher.overflowX = ox; return this; },
102
+ overflowY(oy){ this.catcher.overflowY = oy; return this; },
103
+ overflowWrap(ow){ this.catcher.overflowWrap = ow; return this; },
104
+
105
+ // List Style
106
+ listStyle(ls){ this.catcher.listStyle = ls; return this; },
107
+ listStyleType(lst){ this.catcher.listStyleType = lst; return this; },
108
+ listStyleImage(lsi){ this.catcher.listStyleImage = lsi; return this; },
109
+ listStylePosition(lsp){ this.catcher.listStylePosition = lsp; return this; },
110
+
111
+ // Outline
112
+ outline(o){ this.catcher.outline = o; return this; },
113
+ outlineColor(oc){ this.catcher.outlineColor = oc; return this; },
114
+ outlineStyle(os){ this.catcher.outlineStyle = os; return this; },
115
+ outlineWidth(ow){ this.catcher.outlineWidth = ow; return this; },
116
+ outlineOffset(oo){ this.catcher.outlineOffset = oo; return this; },
117
+
118
+ // Float
119
+ float(f){ this.catcher.float = f; return this; },
120
+ clear(c){ this.catcher.clear = c; return this; },
121
+
122
+ // Position
123
+ position(p){ this.catcher.position = p; return this; },
124
+ top(t){ this.catcher.top = t; return this; },
125
+ left(l){ this.catcher.left = l; return this; },
126
+ bottom(b){ this.catcher.bottom = b; return this; },
127
+
128
+ // Z-index
129
+ zIndex(zi){ this.catcher.zIndex = zi; return this; },
130
+
131
+ // Box-sizing
132
+ boxSizing(bs){ this.catcher.boxSizing = bs; return this; },
133
+
134
+ // Opacity
135
+ opacity(o){ this.catcher.opacity = o; return this; },
136
+
137
+ // Transition
138
+ transition(t){ this.catcher.transition = t; return this; },
139
+
140
+ // Cursor
141
+ cursor(c){ this.catcher.cursor = c; return this; },
142
+
143
+ content(c){ this.catcher.content = c; return this; },
144
+
145
+ accentColor(ac){ this.catcher.accentColor = ac; return this; },
146
+
147
+ all(a){ this.catcher.all = a; return this; },
148
+
149
+ // Block
150
+ block(...args) {
151
+ let objectCss = args.length === 0 ? {} : {selectors: args};
152
+ Object.assign(objectCss, this.catcher);
153
+ this.catcher = {};
154
+ return objectCss;
155
+ },
156
+
157
+ // Navbar
158
+ navBar(...args) {
159
+ if (arguments.length === 0 && args.length === 0) {
160
+ throw new Error('navBar() requires selector argument.');
161
+ }
162
+ let objectResult = {};
163
+ objectResult.navUl = this.display('flex').listStyle('none').margin('0').padding('0').block(`${args[0]} ${args[1]}`);
164
+ objectResult.navLi = this.margin('0 10px').block(`${args[0]} ${args[1]} ${args[2]}`);
165
+ objectResult.navA = this.color('#fff').textDecoration('none').fontWeight('bold').borderRadius('3px').block(`${args[0]} ${args[1]} ${args[2]} ${args[3]}`);
166
+ objectResult.navAhover = this.textDecoration('underline').bgColor('#555').block(`${args[0]} ${args[1]} ${args[2]} ${args[3]}:hover`);
167
+ return objectResult;
168
+ }
169
+ };
170
+
171
+
172
+ const run = (...args) => {
173
+ let str1 = '';
174
+ args.forEach(
175
+ (value)=>{
176
+ let str2 = `${value.selectors.toString()} {\n`;
177
+ for (let key in value) {
178
+ if(key !== 'selectors'){
179
+ const kebabKey = key.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
180
+ str2 += `\t${kebabKey}: ${value[key]};\n`;
181
+ }
182
+ }
183
+ str2 += `}\n\n`;
184
+ str1 += str2;
185
+ }
186
+ );
187
+ chain.cssOutput = str1.trim();
188
+ };
189
+
190
+ const compile = (obj) => {
191
+ let cssString = '';
192
+
193
+ for (const key in obj) {
194
+ if (obj.hasOwnProperty(key)) {
195
+ const element = obj[key];
196
+ let selectors = element.selectors || []; // Provide default empty array if selectors is undefined
197
+ let elementCSS = '';
198
+
199
+ for (let prop in element) {
200
+ if (element.hasOwnProperty(prop) && prop !== 'selectors') {
201
+ // Convert camelCase to kebab-case
202
+ const kebabKey = prop.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
203
+ elementCSS += ` ${kebabKey}: ${element[prop]};\n`;
204
+ }
205
+ }
206
+ selectors = selectors.join();
207
+ cssString += `${selectors} {\n${elementCSS}}\n`;
208
+
209
+ }
210
+ }
211
+
212
+ chain.cssOutput = cssString;
213
+ };
214
+
215
+ const get = require;
216
+
217
+ if (typeof global !== 'undefined') {
218
+ global.chain = chain;
219
+ }
220
+
221
+ module.exports = {
222
+ chain,
223
+ run,
224
+ compile,
225
+ get
226
+ };