vanilla-jet 1.2.1 → 1.3.0-beta

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.
@@ -0,0 +1,30 @@
1
+ module.exports = function(grunt) {
2
+ grunt.registerTask('buildLess', 'Compile admin.less and add .section.less', function() {
3
+
4
+ // -- Functions
5
+ function getCleanedCWD() {
6
+ const cwd = process.cwd();
7
+ return cwd
8
+ .replace('/node_modules', '')
9
+ .replace('/vanilla-jet', '')
10
+ .replace('/.grunt', '');
11
+ }
12
+
13
+ // -- Content
14
+ let adminContent = grunt.file.read(`${getCleanedCWD()}/assets/styles/less/admin.less`);
15
+ let sectionFiles = grunt.file.expand([
16
+ `${getCleanedCWD()}/assets/styles/less/sections/**/*.section.less`,
17
+ `${getCleanedCWD()}/assets/styles/less/sections/*.section.less`
18
+ ]);
19
+
20
+ let combinedContent = adminContent + '\n';
21
+ sectionFiles.forEach(function(filePath) {
22
+ let sectionContent = grunt.file.read(filePath);
23
+ combinedContent += `\n/* ${filePath} */\n` + sectionContent;
24
+ });
25
+
26
+ // -- New file
27
+ grunt.file.write(`${getCleanedCWD()}/assets/styles/less/admin_build.less`, combinedContent);
28
+ grunt.task.run(['less']);
29
+ });
30
+ };
@@ -0,0 +1,308 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const nunjucks = require('nunjucks');
4
+ const beautify = require('js-beautify').html;
5
+ const minify = require('html-minifier-terser').minify;
6
+ const identifier = 'templates';
7
+ const chalk = require('chalk');
8
+ const zlib = require('zlib');
9
+
10
+ // Get environment from command line argument
11
+ const env = process.argv[2] || 'development';
12
+ if (env === 'dev') { env = 'development'; }
13
+ if (env === 'build:qa') { env = 'qa'; }
14
+ if (env === 'build:staging') { env = 'staging'; }
15
+ if (env === 'build:prod') { env = 'production'; }
16
+
17
+ function getCwd() {
18
+ return process.cwd()
19
+ .replace('/node_modules', '')
20
+ .replace('/vanilla-jet', '')
21
+ .replace('/.gulp', '');
22
+ }
23
+
24
+ const base = getCwd();
25
+ const pagesDir = path.join(base, 'assets/pages');
26
+ const templatesDir = path.join(base, 'assets/templates');
27
+ const outputDir = path.join(base, 'public');
28
+
29
+ // Configure nunjucks
30
+ nunjucks.configure(templatesDir, {
31
+ autoescape: true,
32
+ watch: false
33
+ });
34
+
35
+ // Create output directory if it doesn't exist
36
+ if (!fs.existsSync(outputDir)) {
37
+ fs.mkdirSync(outputDir, { recursive: true });
38
+ }
39
+
40
+ // Read all HTML files from pages directory
41
+ fs.readdir(pagesDir, (err, files) => {
42
+ if (err) {
43
+ console.error('Error reading pages directory:', err);
44
+ process.exit(1);
45
+ }
46
+
47
+ files.forEach(file => {
48
+ if (path.extname(file) === '.html') {
49
+ const templatePath = path.join(pagesDir, file);
50
+ const outputPath = path.join(outputDir, file);
51
+
52
+ // Read template file
53
+ fs.readFile(templatePath, 'utf8', (err, content) => {
54
+ if (err) {
55
+ console.error(`Error reading template ${file}:`, err);
56
+ return;
57
+ }
58
+
59
+ try {
60
+ // Render template with nunjucks
61
+ const rendered = nunjucks.renderString(content);
62
+
63
+ // Process the HTML based on environment
64
+ let processedHtml;
65
+ if (env === 'development') {
66
+ // In development, beautify the HTML
67
+ processedHtml = beautify(rendered, {
68
+ indent_size: 2,
69
+ preserve_newlines: true,
70
+ max_preserve_newlines: 2,
71
+ wrap_line_length: 0
72
+ });
73
+ } else {
74
+ // In other environments, minify the HTML
75
+ processedHtml = minify(rendered, {
76
+ collapseWhitespace: true,
77
+ removeComments: true,
78
+ minifyCSS: true,
79
+ minifyJS: true
80
+ });
81
+ }
82
+
83
+ // Write the processed HTML to output file
84
+ fs.writeFile(outputPath, processedHtml, err => {
85
+ if (err) {
86
+ console.error(`Error writing file ${file}:`, err);
87
+ } else {
88
+ console.log(`Successfully compiled ${file}`);
89
+ }
90
+ });
91
+ } catch (err) {
92
+ console.error(`Error processing template ${file}:`, err);
93
+ }
94
+ });
95
+ }
96
+ });
97
+ });
98
+
99
+ let Functions = require('../framework/functions.js');
100
+ let Dipper = require('../framework/dipper.js');
101
+ let Config = require(processCwd() + '/config.js');
102
+
103
+ // -- Init Dipper
104
+ let settings = Config.settings;
105
+ settings['shared']['environment'] = env;
106
+
107
+ let opts = settings[env] || {},
108
+ shared = settings['shared'] || {};
109
+ const dipper = new Dipper(opts, shared);
110
+
111
+ // -- Hydrate dipper
112
+ Functions.hydrate(dipper);
113
+
114
+ // -- Making nunjucks
115
+ let nunjucksPath = path.join(processCwd(), '/assets');
116
+ nunjucks.configure(nunjucksPath, {
117
+ autoescape: false,
118
+ throwOnUndefined: true,
119
+ noCache: true
120
+ });
121
+
122
+ // -- Template directory
123
+ const templatesDirectoryPath = '/assets/templates/';
124
+
125
+ // -- Call main function
126
+ main();
127
+
128
+ // -- Define mainfunctions on other functions
129
+ function main() {
130
+
131
+ // -- Get template files
132
+ const templates = getTemplates(templatesDirectoryPath);
133
+ //console.log(templates);
134
+
135
+ // -- Get home.html
136
+ let homePageName = 'home.html';
137
+ getHtmlFromPage(homePageName).then((htmlContent) => {
138
+ if (htmlContent) {
139
+ // -- Divide content line by line
140
+ const htmlContentLines = htmlContent.split('\n');
141
+ let lines = Array.from(htmlContentLines);
142
+ // -- Iterate over each line
143
+ for (let line of htmlContentLines) {
144
+ let originalLine = line;
145
+ // -- Remove spaces and tabs
146
+ line = cleanALine(line);
147
+ // -- Check is not empty and not a tag
148
+ if (line.length != 0 && !line.includes('<')) {
149
+
150
+ // -- Get template name
151
+ var templateName = line.replace('include::', '');
152
+ // -- Check if its name "templates" add all templates if not add specific one
153
+ if (templateName === identifier) {
154
+
155
+ let allTemplatesCompiled = '';
156
+ for (let templateName in templates) {
157
+ if (templateName.includes('template.html')) {
158
+ let templatePath = templates[templateName];
159
+ let templateCompiled = compileTemplate(templatePath);
160
+ allTemplatesCompiled += templateCompiled;
161
+ }
162
+ }
163
+ lines = replaceInclude(lines, originalLine, allTemplatesCompiled);
164
+
165
+ } else {
166
+ let templatePath = templates[templateName];
167
+ let templateCompiled = compileTemplate(templatePath);
168
+ lines = replaceInclude(lines, originalLine, templateCompiled);
169
+ }
170
+ }
171
+ }
172
+ // -- Join lines
173
+ const newHtml = lines.join('\n');
174
+ // -- Create HTML file
175
+ createHTMLFile(newHtml, homePageName);
176
+ // -- Console finish
177
+ console.log(chalk.green("\n\nVanillaJet - Finish build"));
178
+ }
179
+ });
180
+ }
181
+
182
+ // -- Step 0
183
+ function getTemplates(directory) {
184
+
185
+ const results = {};
186
+
187
+ // -- Sub functions
188
+ function exploreDirectory(dir) {
189
+ const files = fs.readdirSync(dir);
190
+ files.forEach(function (file) {
191
+ //console.log(file);
192
+ if (!checkExcludes(file)) {
193
+ const filePath = path.join(dir, file);
194
+ //console.log(filePath);
195
+ const stats = fs.statSync(filePath);
196
+ if (stats.isFile()) {
197
+ const extension = path.extname(file).toLowerCase();
198
+ if (extension === '.html') {
199
+ results[file] = filePath;
200
+ }
201
+ } else if (stats.isDirectory()) {
202
+ exploreDirectory(filePath);
203
+ }
204
+ }
205
+ });
206
+ }
207
+
208
+ function checkExcludes(file) {
209
+
210
+ const excludes = ['.DS_Store'];
211
+ for (const esclude of excludes) {
212
+ if (file.includes(esclude)) {
213
+ return true;
214
+ }
215
+ }
216
+ return false;
217
+ }
218
+
219
+ // -- Main code
220
+ const templatesPath = path.join(processCwd(), directory);
221
+ exploreDirectory(templatesPath);
222
+ return results;
223
+ }
224
+
225
+ // -- Step 1
226
+ async function getHtmlFromPage(page) {
227
+
228
+ const filename = path.join(processCwd(), '/assets/');
229
+ const exists = await fs.promises.access(filename, fs.constants.F_OK).then(() => true).catch(() => false);
230
+ if (!exists) {
231
+ console.log("Assets folder doesnt exists");
232
+ return null;
233
+ }
234
+
235
+ let fileContent;
236
+ if (await fs.promises.stat(filename).then((stats) => stats.isDirectory())) {
237
+ const filePath = path.join(filename, 'pages/' + page);
238
+ try {
239
+ fileContent = await fs.promises.readFile(filePath, { encoding: 'utf8' });
240
+ } catch (err) {
241
+ console.log("Error in Home");
242
+ return null;
243
+ }
244
+ }
245
+ return fileContent;
246
+ }
247
+
248
+ // -- Step 2
249
+ function compileTemplate(path) {
250
+
251
+ // -- Data
252
+ let data = { 'app': dipper }
253
+
254
+ // -- Render
255
+ return nunjucks.render(path, data);
256
+ }
257
+
258
+ // -- Step 3
259
+ function replaceInclude(lines, originalLine, templateCompiled) {
260
+ const index = lines.indexOf(originalLine);
261
+ if (index !== -1) {
262
+ lines.splice(index, 1, templateCompiled);
263
+ }
264
+ return lines;
265
+ }
266
+
267
+ // -- Step 4
268
+ async function createHTMLFile(content, filePath) {
269
+ const { minify } = require('html-minifier-terser');
270
+ const minified = await minify(content, {
271
+ collapseWhitespace: true,
272
+ collapseInlineTagWhitespace: true,
273
+ removeComments: true,
274
+ collapseBooleanAttributes: true,
275
+ useShortDoctype: true,
276
+ removeEmptyAttributes: true,
277
+ removeOptionalTags: true,
278
+ minifyJS: true
279
+ });
280
+
281
+ const publicPath = path.join(processCwd(), '/public/pages');
282
+ fs.mkdirSync(publicPath, { recursive: true });
283
+ const absolutePath = path.join(publicPath, filePath);
284
+
285
+ // Write the minified HTML file
286
+ fs.writeFileSync(absolutePath, minified, 'utf8');
287
+
288
+ // Create gzipped version
289
+ const gzipped = zlib.gzipSync(minified, { level: 9 }); // Maximum compression level
290
+ fs.writeFileSync(`${absolutePath}.gz`, gzipped);
291
+
292
+ console.log(chalk.green(`Created HTML file at: ${absolutePath}`));
293
+ console.log(chalk.green(`Created gzipped version at: ${absolutePath}.gz`));
294
+ }
295
+
296
+ // -- Helpers
297
+ function cleanALine(line) {
298
+ line = line.replaceAll(' ', '');
299
+ line = line.replaceAll('\t', '');
300
+ line = line.replaceAll('\n', '');
301
+ return line;
302
+ }
303
+
304
+ function processCwd() {
305
+ return process.cwd()
306
+ .replace('/.grunt', '')
307
+ .replace('/node_modules/vanilla-jet', '');
308
+ }
package/bin.js CHANGED
@@ -15,33 +15,33 @@ switch (args[0]) {
15
15
 
16
16
  case 'dev':
17
17
  try {
18
- execSync('grunt --env=development', { stdio: 'inherit', cwd: __dirname });
18
+ execSync('gulp dev --env development', { stdio: 'inherit', cwd: __dirname });
19
19
  } catch (error) {
20
- console.error('Error ejecutando grunt:', error.message);
20
+ console.error('Error ejecutando gulp:', error.message);
21
21
  }
22
22
  break;
23
23
 
24
24
  case 'build:qa':
25
25
  try {
26
- execSync('grunt build --env=qa', { stdio: 'inherit', cwd: __dirname });
26
+ execSync('gulp build --env qa', { stdio: 'inherit', cwd: __dirname });
27
27
  } catch (error) {
28
- console.error('Error ejecutando grunt:', error.message);
28
+ console.error('Error ejecutando gulp:', error.message);
29
29
  }
30
30
  break;
31
31
 
32
32
  case 'build:staging':
33
33
  try {
34
- execSync('grunt build --env=staging', { stdio: 'inherit', cwd: __dirname });
34
+ execSync('gulp build --env staging', { stdio: 'inherit', cwd: __dirname });
35
35
  } catch (error) {
36
- console.error('Error ejecutando grunt:', error.message);
36
+ console.error('Error ejecutando gulp:', error.message);
37
37
  }
38
38
  break;
39
39
 
40
40
  case 'build:prod':
41
41
  try {
42
- execSync('grunt build --env=production', { stdio: 'inherit', cwd: __dirname });
42
+ execSync('gulp build --env production', { stdio: 'inherit', cwd: __dirname });
43
43
  } catch (error) {
44
- console.error('Error ejecutando grunt:', error.message);
44
+ console.error('Error ejecutando gulp:', error.message);
45
45
  }
46
46
  break;
47
47
  }
@@ -9,12 +9,7 @@ function Dipper(options, shared) {
9
9
  this.page_title = this.site_title;
10
10
  this.description = shared.description;
11
11
  this.fbAppId = shared.fbAppId;
12
-
13
- this.site_url = ((this.options.site_url == 'localhost') ?
14
- 'http://localhost' :
15
- this.options.site_url) + ':' + this.options.port;
16
12
  this.base_dir = path.join(process.cwd(), '/');
17
- this.base_url = this.site_url + this.options.base_url;
18
13
 
19
14
  // Dirs
20
15
  this.dirs = {
@@ -44,27 +39,19 @@ function Dipper(options, shared) {
44
39
  }
45
40
 
46
41
  Dipper.prototype.getPageTitle = function() {
47
-
48
- var obj = this;
49
- return obj.page_title;
42
+ return this.page_title;
50
43
  }
51
44
 
52
45
  Dipper.prototype.getSiteTitle = function() {
53
-
54
- var obj = this;
55
- return obj.site_title;
46
+ return this.site_title;
56
47
  }
57
48
 
58
49
  Dipper.prototype.getDescription = function() {
59
-
60
- var obj = this;
61
- return obj.description;
50
+ return this.description;
62
51
  }
63
52
 
64
53
  Dipper.prototype.getFbAppId = function() {
65
-
66
- var obj = this;
67
- return obj.fbAppId;
54
+ return this.fbAppId;
68
55
  }
69
56
 
70
57
  Dipper.prototype.addMeta = function({name, content, attribute}) {
@@ -100,11 +87,8 @@ Dipper.prototype.metaTags = function() {
100
87
  }
101
88
 
102
89
  Dipper.prototype.img = function(filename) {
103
-
104
- var obj = this,
105
- dir = this.getDir('images', false);
106
- ret = this.urlTo(dir + filename);
107
- return ret;
90
+ let dir = this.getDir('images', false);
91
+ return this.urlTo(dir + filename);
108
92
  }
109
93
 
110
94
  Dipper.prototype.script = function(filename) {
@@ -119,17 +103,14 @@ Dipper.prototype.style = function(filename) {
119
103
 
120
104
  Dipper.prototype.pdf = function(filename) {
121
105
 
122
- var obj = this,
123
- dir = '/assets/pdf/'
124
- ret = this.urlTo(dir + filename);
125
- //console.log(ret);
126
- return ret;
106
+ let dir = '/assets/pdf/';
107
+ return this.urlTo(dir + filename);
127
108
  }
128
109
 
129
110
  Dipper.prototype.getDir = function(dir, full) {
130
111
 
131
- var obj = this,
132
- full = (full == undefined) ? true : full;
112
+ let obj = this;
113
+ full = (full == undefined) ? true : full;
133
114
 
134
115
  if ( obj.dirs[dir] != undefined ) {
135
116
  return (full == true ? obj.baseDir(obj.dirs[dir]) : obj.dirs[dir]);
@@ -138,32 +119,14 @@ Dipper.prototype.getDir = function(dir, full) {
138
119
  }
139
120
 
140
121
  Dipper.prototype.baseDir = function(path) {
141
-
142
- var obj = this,
143
- path = path || '',
144
- ret = obj.base_dir + path;
145
- return ret;
146
- }
147
-
148
- Dipper.prototype.isSecureRequest = function() {
149
-
150
- var obj = this;
151
- // Cheking for http or https
152
- if (/^((http):\/\/)/.test(obj.options.site_url) || /^((localhost))/.test(obj.options.site_url)) {
153
- return false;
154
- } else if (/^((https):\/\/)/.test(obj.options.site_url)) {
155
- return true;
156
- }
122
+ path = path || '';
123
+ return this.base_dir + path;
157
124
  }
158
125
 
159
- Dipper.prototype.urlTo = function(route, protocol) {
160
-
161
- var obj = this,
162
- protocol = protocol || undefined,
163
- url = obj.base_url + route;
164
- //url = obj.baseUrl(route, protocol);
165
- return url;
166
- }
126
+ Dipper.prototype.urlTo = function (route) {
127
+ if (/^(?:[a-z][a-z0-9+.-]*:)?\/\//i.test(route)) return route;
128
+ return '/' + route.replace(/^\/+/, '');
129
+ };
167
130
 
168
131
  Dipper.prototype.registerStyle = function(
169
132
  name, url, requires,
@@ -52,10 +52,13 @@ class Router {
52
52
 
53
53
  addRoute(method, route, handler, insert) {
54
54
 
55
- var obj = this, insert = insert || false, method = method.toLowerCase(), prev = (obj.server.options.base_url && obj.server.options.base_url != '' && obj.server.options.base_url != '/') ? obj.server.options.base_url : '', instance = {
56
- regexp: obj.routeToRegExp(prev + route),
57
- handler: handler
58
- };
55
+ var obj = this,
56
+ insert = insert || false,
57
+ method = method.toLowerCase(),
58
+ instance = {
59
+ regexp: obj.routeToRegExp(route),
60
+ handler: handler
61
+ };
59
62
  // Add the route, may be at the beginning or at the end
60
63
  if (insert) { // Adding the route at the beginning of the route's array
61
64
  obj.routes[method].unshift(instance);
@@ -71,9 +74,7 @@ class Router {
71
74
  let response = new Response(res);
72
75
  let request = new Request(req, {
73
76
  onDataReceived: function () {
74
- if (request.path == obj.server.options.base_url) {
75
- request.path = obj.server.options.base_url + obj.defaultRoute;
76
- }
77
+ if (request.path == '') { request.path = obj.defaultRoute; }
77
78
  // -- Check GET or POST routes
78
79
  _.each(obj.routes[request.type], function (route) {
79
80
  if (request.path.match(route.regexp)) {
@@ -104,7 +105,7 @@ class Router {
104
105
  if (extHandled) {
105
106
 
106
107
  let rep = obj.cwd.replace('core/framework', ''),
107
- route = request.path.replace(obj.server.options.base_url, ''),
108
+ route = request.path,
108
109
  filename = path.join(rep, route),
109
110
  filePrivate = obj.isProtectedFile(route);
110
111
 
@@ -172,10 +173,7 @@ class Router {
172
173
  }
173
174
 
174
175
  getDefaultRoute() {
175
-
176
- let obj = this,
177
- prev = (obj.server.options.base_url && obj.server.options.base_url != '' && obj.server.options.base_url != '/') ? obj.server.options.base_url : '';
178
- return (prev + obj.defaultRoute);
176
+ return this.defaultRoute;
179
177
  }
180
178
 
181
179
  onNotFound(response) {
@@ -7,7 +7,6 @@ const path = require('path');
7
7
 
8
8
  let Router = require('./router.js');
9
9
  let Dipper = require('./dipper.js');
10
- let Functions = require('./functions.js');
11
10
 
12
11
  class Server {
13
12
 
@@ -31,10 +30,8 @@ class Server {
31
30
  security = settings['security'] || {};
32
31
 
33
32
  _.defaults(opts, {
34
- base_url: '',
35
- site_url: '',
36
- wsServer: false,
37
- onNotFound: obj.onNotFound
33
+ https_server: false,
34
+ wsServer: false
38
35
  });
39
36
  obj.options = opts;
40
37
 
@@ -57,9 +54,6 @@ class Server {
57
54
  // -- Create the server
58
55
  obj.createServer();
59
56
 
60
- // -- Not found callback
61
- obj.onNotFound = opts.onNotFound;
62
-
63
57
  // Initialize router
64
58
  obj.router = new Router(obj);
65
59
 
@@ -69,56 +63,35 @@ class Server {
69
63
  endpoints_built[endpoint.name] = new endpoint(obj.router);
70
64
  }
71
65
  this.endpoints = endpoints_built;
72
-
73
- // Setting endpoints
74
- obj.functions = new Functions();
75
66
  }
76
67
 
77
68
  start() {
78
-
79
- let obj = this;
80
- let port = (obj.options.port && obj.options.port != '') ? obj.options.port : 8080;
81
-
82
- // Listen on the specified port
83
- obj.httpx.listen(port);
84
-
85
- // Logging
86
- obj.log('__________________ VanillaJet server started ___________________');
87
- obj.log(` > Listening on ${obj.options.site_url}:${obj.options.port}${obj.options.base_url} < `);
88
- obj.log('-----------------------------------------------------------------');
69
+ this.log('__________________ VanillaJet Server started ___________________');
70
+ this.log(` > Running on 0.0.0.0:${this.options.port}/ < `);
71
+ this.log('------------------------------------------------------------------');
89
72
  }
90
73
 
91
74
  createServer() {
92
75
 
93
76
  let obj = this;
94
- // -- Http server
95
- let isLocalhost = /^((http):\/\/)/.test(obj.options.site_url) || /^((localhost))/.test(obj.options.site_url);
96
- if (isLocalhost) {
97
- obj.httpx = http.createServer((req, res) => {
98
- obj.router.onRequest.call(obj.router, req, res);
99
- });
100
- return;
101
- }
102
77
 
103
78
  // -- Https server (self managed certs)
104
79
  if (obj.security.self_managed_certs) {
105
- let certs = {
106
- key: fs.readFileSync(obj.security.key, 'utf8'),
107
- cert: fs.readFileSync(obj.security.cert, 'utf8'),
108
- allowHTTP1: true
109
- };
80
+ console.log('HTTPs server created - Self managed certs');
81
+ let certs = obj.getCertificates();
110
82
  obj.httpx = http2.createSecureServer(certs, (req, res) => {
111
83
  obj.router.onRequest.call(obj.router, req, res);
112
84
  });
113
- return;
85
+ } else {
86
+ console.log('HTTP server created - Without self managed certs');
87
+ obj.httpx = http.createServer((req, res) => {
88
+ console.log('Request received: ', req.url);
89
+ obj.router.onRequest.call(obj.router, req, res);
90
+ });
114
91
  }
115
-
116
- // -- Certs managed by NGINX, Google Cloud Run, etc.
117
- console.log('HTTP server created - Without self managed certs');
118
- obj.httpx = http.createServer((req, res) => {
119
- console.log('Request received: ', req.url);
120
- obj.router.onRequest.call(obj.router, req, res);
121
- });
92
+
93
+ // -- Set the port
94
+ obj.httpx.listen(obj.options.port || 8080);
122
95
  }
123
96
 
124
97
  log(value) {
@@ -129,11 +102,15 @@ class Server {
129
102
  }
130
103
  }
131
104
 
132
- onNotFound(request, response) {
133
-
134
- response.setStatus(404);
135
- response.respond();
136
- }
105
+ getCertificates() {
106
+
107
+ let obj = this;
108
+ return {
109
+ key: fs.readFileSync(obj.security.key, 'utf8'),
110
+ cert: fs.readFileSync(obj.security.cert, 'utf8'),
111
+ allowHTTP1: true
112
+ }
113
+ }
137
114
  }
138
115
 
139
116
  module.exports = Server;
package/gulpfile.js ADDED
@@ -0,0 +1,187 @@
1
+ const gulp = require('gulp');
2
+ const less = require('gulp-less');
3
+ const uglify = require('gulp-uglify');
4
+ const concat = require('gulp-concat');
5
+ const gzip = require('gulp-gzip');
6
+ const cleanCSS = require('gulp-clean-css');
7
+ const rename = require('gulp-rename');
8
+ const newer = require('gulp-newer');
9
+ const shell = require('gulp-shell');
10
+ const watch = require('gulp-watch');
11
+ const livereload = require('gulp-livereload');
12
+ const del = require('del');
13
+ const gulpif = require('gulp-if');
14
+ const minimist = require('minimist');
15
+
16
+ // Parse command line arguments
17
+ const knownOptions = {
18
+ string: 'env',
19
+ default: { env: process.env.NODE_ENV || 'development' }
20
+ };
21
+ const options = minimist(process.argv.slice(2), knownOptions);
22
+
23
+ // Helper functions
24
+ function getCwd() {
25
+ return process.cwd()
26
+ .replace('/node_modules', '')
27
+ .replace('/vanilla-jet', '')
28
+ .replace('/.gulp', '');
29
+ }
30
+
31
+ const base = getCwd();
32
+ const cssDestination = `${getCwd()}/public/styles/app.min.css`;
33
+ const cssOrigin = `${getCwd()}/assets/styles/less/admin.less`;
34
+ const jsDestination = `${getCwd()}/public/`;
35
+
36
+ // Clean tasks
37
+ function cleanBuild() {
38
+ return del([`${getCwd()}/public/scripts/vanilla.min.js`], { force: true });
39
+ }
40
+
41
+ function cleanMinified() {
42
+ return del([
43
+ `${getCwd()}/public/scripts/api`,
44
+ `${getCwd()}/public/scripts/controllers`,
45
+ `${getCwd()}/public/scripts/views`,
46
+ `${getCwd()}/public/scripts/app.min.js`
47
+ ], { force: true });
48
+ }
49
+
50
+ // LESS compilation
51
+ function buildLess() {
52
+ return gulp.src(cssOrigin)
53
+ .pipe(less({
54
+ compress: true,
55
+ optimization: 2
56
+ }))
57
+ .pipe(rename('app.min.css'))
58
+ .pipe(gulp.dest(`${getCwd()}/public/styles`))
59
+ .pipe(livereload());
60
+ }
61
+
62
+ // JavaScript tasks
63
+ function uglifyJs() {
64
+ return gulp.src([
65
+ `${getCwd()}/assets/scripts/*.js`,
66
+ `${getCwd()}/assets/scripts/**/*.js`,
67
+ `${getCwd()}/assets/scripts/**/**/*.js`,
68
+ `${getCwd()}/assets/scripts/**/**/**/*.js`
69
+ ])
70
+ .pipe(newer({
71
+ dest: `${getCwd()}/public`,
72
+ ext: '.min.js'
73
+ }))
74
+ .pipe(uglify({
75
+ compress: {
76
+ drop_console: false,
77
+ sequences: true,
78
+ dead_code: true,
79
+ conditionals: true,
80
+ booleans: true,
81
+ unused: true,
82
+ if_return: true,
83
+ join_vars: true
84
+ },
85
+ output: { ascii_only: true }
86
+ }))
87
+ .pipe(rename(function(path) {
88
+ path.basename += '.min';
89
+ }))
90
+ .pipe(gulp.dest(`${getCwd()}/public/scripts`));
91
+ }
92
+
93
+ // Concatenation task
94
+ function concatJs() {
95
+ return gulp.src([
96
+ `${getCwd()}/public/scripts/controllers/**/*.min.js`,
97
+ `${getCwd()}/public/scripts/views/**/*.min.js`,
98
+ `${getCwd()}/public/scripts/api/**/*.min.js`,
99
+ `${getCwd()}/public/scripts/*.min.js`,
100
+ `!${getCwd()}/public/scripts/core/**`,
101
+ `!${getCwd()}/public/scripts/plugins/**`,
102
+ `!${getCwd()}/public/scripts/plugins/ui/**`
103
+ ])
104
+ .pipe(concat('vanilla.min.js'))
105
+ .pipe(gulp.dest(`${getCwd()}/public/scripts`));
106
+ }
107
+
108
+ // Compression tasks
109
+ function compressJs() {
110
+ return gulp.src(`${getCwd()}/public/scripts/vanilla.min.js`)
111
+ .pipe(gzip({ gzipOptions: { level: 9 } }))
112
+ .pipe(gulp.dest(`${getCwd()}/public/scripts`));
113
+ }
114
+
115
+ function compressCss() {
116
+ return gulp.src(`${getCwd()}/public/styles/app.min.css`)
117
+ .pipe(gzip({ gzipOptions: { level: 9 } }))
118
+ .pipe(gulp.dest(`${getCwd()}/public/styles`));
119
+ }
120
+
121
+ // Template compilation
122
+ function compileTemplates() {
123
+ return gulp.src('.')
124
+ .pipe(shell([`node .grunt/compile_html.js ${options.env}`]));
125
+ }
126
+
127
+ // Watch task
128
+ function watchFiles(cb) {
129
+ if (options.env === 'development') {
130
+ livereload.listen();
131
+
132
+ // Watch LESS files
133
+ watch([`${base}/assets/styles/less/**/*.less`], gulp.series(
134
+ buildLess,
135
+ 'newer:uglifyJs',
136
+ cleanBuild,
137
+ concatJs,
138
+ cleanMinified,
139
+ compressCss
140
+ ));
141
+
142
+ // Watch HTML files
143
+ watch([
144
+ `${base}/assets/pages/*.html`,
145
+ `${base}/assets/templates/**/*.html`
146
+ ], compileTemplates);
147
+
148
+ // Watch JS files
149
+ watch([`${base}/assets/scripts/**/*.js`], gulp.series(
150
+ 'newer:uglifyJs',
151
+ cleanBuild,
152
+ concatJs,
153
+ cleanMinified,
154
+ compressJs
155
+ ));
156
+ }
157
+ cb();
158
+ }
159
+
160
+ // Define complex tasks
161
+ const build = gulp.series(
162
+ buildLess,
163
+ uglifyJs,
164
+ cleanBuild,
165
+ concatJs,
166
+ cleanMinified,
167
+ compileTemplates,
168
+ gulp.parallel(compressJs, compressCss)
169
+ );
170
+
171
+ const dev = gulp.series(
172
+ build,
173
+ watchFiles
174
+ );
175
+
176
+ // Export tasks
177
+ exports.cleanBuild = cleanBuild;
178
+ exports.cleanMinified = cleanMinified;
179
+ exports.buildLess = buildLess;
180
+ exports.uglifyJs = uglifyJs;
181
+ exports.concatJs = concatJs;
182
+ exports.compressJs = compressJs;
183
+ exports.compressCss = compressCss;
184
+ exports.compileTemplates = compileTemplates;
185
+ exports.build = build;
186
+ exports.dev = dev;
187
+ exports.default = dev;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vanilla-jet",
3
- "version": "1.2.1",
3
+ "version": "1.3.0-beta",
4
4
  "description": "VannilaJet framework",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -8,10 +8,10 @@
8
8
  },
9
9
  "scripts": {
10
10
  "setup": "node ./.scripts/generate_packages_json.js",
11
- "dev": "grunt --env=development",
12
- "build:qa": "grunt build --env=qa",
13
- "build:staging": "grunt build --env=staging",
14
- "build:prod": "grunt build --env=production",
11
+ "dev": "gulp dev --env development",
12
+ "build:qa": "gulp build --env qa",
13
+ "build:staging": "gulp build --env staging",
14
+ "build:prod": "gulp build --env production",
15
15
  "test": "npm run test"
16
16
  },
17
17
  "repository": {
@@ -31,19 +31,7 @@
31
31
  "dependencies": {
32
32
  "blueimp-md5": "2.19.0",
33
33
  "chalk": "4.1.2",
34
- "grunt": "1.6.1",
35
- "grunt-cli": "1.5.0",
36
- "grunt-contrib-clean": "2.0.1",
37
- "grunt-contrib-compress": "2.0.0",
38
- "grunt-contrib-concat": "2.1.0",
39
- "grunt-contrib-cssmin": "5.0.0",
40
- "grunt-contrib-less": "3.0.0",
41
- "grunt-contrib-uglify": "5.2.2",
42
- "grunt-contrib-watch": "1.1.0",
43
- "grunt-run": "0.8.1",
44
- "grunt-shell": "4.0.0",
45
34
  "html-minifier-terser": "7.2.0",
46
- "jit-grunt": "0.10.0",
47
35
  "js-beautify": "1.15.4",
48
36
  "jsrsasign": "11.1.0",
49
37
  "jwt-simple": "0.5.6",
@@ -52,5 +40,21 @@
52
40
  "nunjucks": "3.2.4",
53
41
  "underscore": ">= 1.12.x",
54
42
  "zlib": "1.0.5"
43
+ },
44
+ "devDependencies": {
45
+ "del": "^6.0.0",
46
+ "gulp": "^4.0.2",
47
+ "gulp-clean-css": "^4.3.0",
48
+ "gulp-concat": "^2.6.1",
49
+ "gulp-gzip": "^1.4.2",
50
+ "gulp-if": "^3.0.0",
51
+ "gulp-less": "^5.0.0",
52
+ "gulp-livereload": "^4.0.2",
53
+ "gulp-newer": "^1.4.0",
54
+ "gulp-rename": "^2.0.0",
55
+ "gulp-shell": "^0.8.0",
56
+ "gulp-uglify": "^3.0.2",
57
+ "gulp-watch": "^5.0.1",
58
+ "minimist": "^1.2.8"
55
59
  }
56
60
  }
package/Gruntfile.js DELETED
@@ -1,182 +0,0 @@
1
- module.exports = function(grunt) {
2
-
3
- require('jit-grunt')(grunt, {
4
- concat: 'grunt-contrib-concat',
5
- //compress: 'grunt-contrib-compress',
6
- clean: 'grunt-contrib-clean'
7
- });
8
- grunt.option('force', true);
9
-
10
- // -- Load modules
11
- grunt.loadNpmTasks('grunt-contrib-cssmin');
12
- grunt.loadNpmTasks('grunt-contrib-uglify');
13
- grunt.loadNpmTasks('grunt-contrib-watch');
14
- grunt.loadNpmTasks('grunt-shell');
15
- grunt.loadNpmTasks('grunt-run');
16
- require('./.grunt/build_styles_task')(grunt);
17
-
18
- // -- Functions
19
- function getCwd() {
20
- const cwd = process.cwd();
21
- let newCwd = cwd
22
- .replace('/node_modules', '')
23
- .replace('/vanilla-jet', '')
24
- .replace('/.grunt', '');
25
- //console.log('cwd: ', newCwd);
26
- return newCwd;
27
- }
28
-
29
- // -- Vars
30
- const cssDestination = `${getCwd()}/public/styles/app.min.css`;
31
- const cssOrigin = `${getCwd()}/assets/styles/less/admin_build.less`;
32
- const jsDestination = `${getCwd()}/public/`;
33
-
34
- // -- Init
35
- grunt.initConfig({
36
- clean: {
37
- build: [`${getCwd()}/public/scripts/vanilla.min.js`],
38
- minified: [
39
- `${getCwd()}/public/scripts/api`,
40
- `${getCwd()}/public/scripts/controllers`,
41
- `${getCwd()}/public/scripts/views`,
42
- `${getCwd()}/public/scripts/app.min.js`
43
- ],
44
- //minified: ['public/scripts/**/*.min.js', 'public/scripts/*', '!public/scripts/vanilla.min.js']
45
- },
46
- less: {
47
- development: {
48
- options: {
49
- compress: true,
50
- yuicompress: true,
51
- optimization: 2,
52
- strictImports: true
53
- },
54
- files: {
55
- [cssDestination] : cssOrigin
56
- },
57
- }
58
- },
59
- watch: {
60
- options: {
61
- livereload: true
62
- },
63
- styles: {
64
- files: [
65
- `${getCwd()}/assets/styles/less/*.less`,
66
- `${getCwd()}/assets/styles/less/**/*.less`,
67
- `${getCwd()}/assets/styles/less/**/**/*.less`,
68
- `${getCwd()}/!assets/styles/less/admin_build.less`
69
- ],
70
- tasks: ['buildLess'],
71
- options: {
72
- nospawn: true
73
- }
74
- },
75
- scripts: {
76
- files: [
77
- `${getCwd()}/assets/pages/*.html`,
78
- `${getCwd()}/assets/templates/**/*.html`,
79
- `${getCwd()}/assets/templates/**/**/*.html`,
80
- `${getCwd()}/external/view/*.js`,
81
- `${getCwd()}/external/*.js`,
82
- `${getCwd()}/framework/*.js`
83
- ],
84
- tasks: ['shell:compileTemplates']
85
- },
86
- specificScripts: {
87
- files: [
88
- `${getCwd()}/assets/scripts/*.js`,
89
- `${getCwd()}/assets/scripts/**/*.js`,
90
- `${getCwd()}/assets/scripts/**/**/*.js`
91
- ],
92
- tasks: ['uglify', 'cleanForce:build', 'concat', 'cleanForce:minified']
93
- }
94
- },
95
- uglify: {
96
- build: {
97
- options: {
98
- sourceMap: false,
99
- compress: {
100
- drop_console: false,
101
- sequences: true,
102
- dead_code: true,
103
- conditionals: true,
104
- booleans: true,
105
- unused: true,
106
- if_return: true,
107
- join_vars: true
108
- },
109
- output: {
110
- ascii_only: true
111
- }
112
- },
113
- files: [{
114
- expand: true,
115
- src: [
116
- `${getCwd()}/assets/scripts/*.js`,
117
- `${getCwd()}/assets/scripts/**/*.js`,
118
- `${getCwd()}/assets/scripts/**/**/*.js`,
119
- `${getCwd()}/assets/scripts/**/**/**/*.js`
120
- ],
121
- dest: getCwd() + '/public',
122
- rename : function (dest, src) {
123
-
124
- var folder = src.substring(0, src.lastIndexOf('/')),
125
- filename = src.substring(src.lastIndexOf('/'), src.length);
126
- filename = filename.substring(0, filename.lastIndexOf('.'));
127
- folder = folder.replaceAll('assets/', 'public/');
128
- let file = folder + filename + '.min.js';
129
- //console.log('file: ', file);
130
- return file;
131
- }
132
- }]
133
- }
134
- },
135
- concat: {
136
- build: {
137
- src: [
138
- // Order
139
- `${getCwd()}/public/scripts/controllers/**/*.min.js`,
140
- `${getCwd()}/public/scripts/views/**/*.min.js`,
141
- `${getCwd()}/public/scripts/api/**/*.min.js`,
142
- `${getCwd()}/public/scripts/*.min.js`,
143
-
144
- // Ignore files
145
- `!${getCwd()}/public/scripts/core/**`,
146
- `!${getCwd()}/public/scripts/plugins/**`,
147
- `!${getCwd()}/public/scripts/plugins/ui/**`
148
- ],
149
- dest: `${getCwd()}/public/scripts/vanilla.min.js`
150
- }
151
- },
152
- compress: {
153
- main: {
154
- options: {
155
- mode: 'gzip',
156
- compressionLevel: 9
157
- },
158
- files: [{
159
- expand: true,
160
- src: [`${getCwd()}/public/scripts/vanilla.min.js`, `${getCwd()}/public/styles/app.min.css`],
161
- dest: '',
162
- rename: function(dest, src) {
163
- return src + '.gz';
164
- }
165
- }]
166
- }
167
- },
168
- shell: {
169
- compileTemplates: {
170
- command: 'node .grunt/compile_html.js <%= grunt.option("env") %>'
171
- }
172
- }
173
- });
174
-
175
- grunt.registerTask('cleanForce', function(target) {
176
- grunt.option('force', true);
177
- grunt.task.run('clean:' + target);
178
- });
179
- grunt.registerTask('default', ['buildLess', 'uglify', 'cleanForce:build', 'concat', 'cleanForce:minified', 'shell:compileTemplates', 'watch']);
180
- grunt.registerTask('build', ['buildLess', 'uglify', 'cleanForce:build', 'concat', 'cleanForce:minified', 'shell:compileTemplates']);
181
- grunt.registerTask('server', ['buildLess']);
182
- };