From c449b0309ec53e498cf8b03ac739c41bb0d6420b Mon Sep 17 00:00:00 2001 From: Elson Correia Date: Fri, 16 Jul 2021 21:04:29 -0400 Subject: [PATCH 01/13] hp config file support --- core/engine/index.js | 53 +++++++++++++++++++++----------- core/utils/merge-objects.js | 19 ++++++++++++ core/utils/merge-objects.spec.js | 40 ++++++++++++++++++++++++ hp.config.js | 27 ++++++++++++++++ website/server-test.js | 25 --------------- 5 files changed, 121 insertions(+), 43 deletions(-) create mode 100644 core/utils/merge-objects.js create mode 100644 core/utils/merge-objects.spec.js create mode 100644 hp.config.js diff --git a/core/engine/index.js b/core/engine/index.js index 56018ecf..d4d05c5a 100644 --- a/core/engine/index.js +++ b/core/engine/index.js @@ -7,6 +7,8 @@ const {transform} = require('../transform'); const {getDirectoryFilesDetail} = require('../utils/getDirectoryFilesDetail'); const {File} = require('../File'); const validUrl = require('valid-url'); +const {isObject, isArray, isFunction} = require("util"); +const {mergeObjects} = require("../utils/merge-objects"); const defaultOptions = { staticData: {}, @@ -17,22 +19,37 @@ const defaultOptions = { } } -const engine = (app, pagesDirectoryPath, opt = defaultOptions) => { +const engine = (app, pagesDirectoryPath, opt = {}) => { if (!app) { throw new Error('engine first argument must be provided and be a valid express app.') } - opt = {...defaultOptions, ...opt} + let hbConfig = {}; - if (typeof opt.staticData !== 'object') { - throw new Error('HTML+ static data must be an javascript object') + try { + hbConfig = require(path.join(process.cwd(), 'hp.config.js')); + } catch (e) { + if (e.code !== 'MODULE_NOT_FOUND') { + e.message = `hp.config.js file loading failed: ${e.message}` + throw new Error(e) + } + } + + opt = {...defaultOptions, ...mergeObjects(hbConfig, opt)}; + + if (!isObject(opt.staticData)) { + throw new Error('HTML+ static data option must be a javascript object') + } + + if (!isArray(opt.customTags)) { + throw new Error('HTML+ custom tags option must be an array of valid tags.') } - if (!Array.isArray(opt.customTags)) { - throw new Error('HTML+ custom tags must be an array of valid tags.') + if (!isArray(opt.customAttributes)) { + throw new Error('HTML+ custom attributes option must be an array of valid attributes.') } - if (typeof opt.onPageRequest !== 'function') { + if (!isFunction(opt.onPageRequest)) { throw new Error('"onPageRequest" option must be a function') } @@ -54,7 +71,7 @@ const engine = (app, pagesDirectoryPath, opt = defaultOptions) => { filePath = filePath.replace(pagesDirectoryPath, ''); const template = `${filePath.replace('.html', '')}`.slice(1); let tempPath = ''; - + if (filePath.endsWith('index.html')) { tempPath = filePath.replace('/index.html', ''); pagesRoutes[tempPath || '/'] = template; @@ -73,11 +90,11 @@ const engine = (app, pagesDirectoryPath, opt = defaultOptions) => { .then(() => { app.engine('html', (filePath, {settings, _locals, cache, ...context}, callback) => { const fileName = path.basename(filePath); - + if (fileName.startsWith('_')) { callback(new Error(`Cannot render partial(${fileName}) file as page. Partial files can only be included.`)); } - + fs.readFile(filePath, (err, content) => { if (err) return callback(err); const file = new File(filePath, settings.views); @@ -92,25 +109,25 @@ const engine = (app, pagesDirectoryPath, opt = defaultOptions) => { partialFiles: partials, onBeforeRender: (node, nodeFile) => { let attrName = ''; - + if (node.tagName === 'link') { attrName = 'href'; } else if (node.tagName === 'script') { attrName = 'src'; } - + const srcPath = node.attributes[attrName]; - + if (srcPath && !validUrl.isUri(srcPath)) { const resourceFullPath = path.resolve(nodeFile.fileDirectoryPath, srcPath); - + if (resourceFullPath.startsWith(pagesDirectoryPath)) { node.setAttribute(attrName, resourceFullPath.replace(pagesDirectoryPath, '')) } } } }) - + callback(null, result); } catch (e) { console.error(e.message); @@ -121,17 +138,17 @@ const engine = (app, pagesDirectoryPath, opt = defaultOptions) => { } }) }); - + app.set('views', pagesDirectoryPath); app.set('view engine', 'html'); - + app.use(pageAndResourcesMiddleware( pagesRoutes, pagesDirectoryPath, opt )); app.use(express.static(pagesDirectoryPath)) - + console.log('HTML+ engine is ready'); }) }; diff --git a/core/utils/merge-objects.js b/core/utils/merge-objects.js new file mode 100644 index 00000000..b4fc4369 --- /dev/null +++ b/core/utils/merge-objects.js @@ -0,0 +1,19 @@ +const {isObject, isArray} = require("util"); + +const isObjectLiteral = x => isObject(x) && x.toString() === '[object Object]'; + +function mergeObjects(a, b) { + if(!isObjectLiteral(a) || !isObjectLiteral(b)) return b ?? {}; + + const obj = isArray(a) ? [...a] : a; + + for(const key in b) { + if(b.hasOwnProperty(key)) { + obj[key] = mergeObjects(obj[key], b[key]); + } + } + + return obj; +} + +module.exports.mergeObjects = mergeObjects; diff --git a/core/utils/merge-objects.spec.js b/core/utils/merge-objects.spec.js new file mode 100644 index 00000000..86a03dac --- /dev/null +++ b/core/utils/merge-objects.spec.js @@ -0,0 +1,40 @@ +const {mergeObjects} = require('./merge-objects'); + +describe('mergeObjects', () => { + it('should return second object if one is null or not an object', () => { + expect(mergeObjects(null, {b: 10})).toEqual({b: 10}) + expect(mergeObjects(12, {b: 10})).toEqual({b: 10}) + expect(mergeObjects('12', {b: 10})).toEqual({b: 10}) + expect(mergeObjects(() => {}, {b: 10})).toEqual({b: 10}) + + expect(mergeObjects({a: 10}, null)).toEqual({}) + }); + + it('should merge arrays', () => { + expect(mergeObjects([1, 2, 4], [1, 9, 0])).toEqual([1, 9, 0]) + expect(mergeObjects([6, 2, 4], [9, 0])).toEqual([9, 0, 4]) + expect(mergeObjects([6, [2, 4]], [9, [0, 9]])).toEqual([9, [0, 9]]) + expect(mergeObjects([6, [2, [3, 1]]], [9, [0, 9]])).toEqual( [9, [0, 9]]) + expect(mergeObjects([6, [2, 6]], [9, [0, [3, 1]]])).toEqual([9, [0, [3, 1]]]) + expect(mergeObjects([6, [2, 6]], [9])).toEqual([9, [2, 6]]) + expect(mergeObjects([6, [2, 6]], [9, [1]])).toEqual([9, [1, 6]]) + }); + + it('should merge object literals', () => { + expect(mergeObjects({a: 12}, {b: 34})).toEqual({a: 12, b: 34}) + expect(mergeObjects({a: 12}, {a: 34})).toEqual({a: 34}) + expect(mergeObjects({a: [12, 67, 10]}, {a: [34, 90]})).toEqual({a: [34, 90, 10]}) + expect(mergeObjects({a: 10}, {a: [34, 90]})).toEqual({a: [34, 90]}) + expect(mergeObjects({a: [34, 90]}, {a: 10})).toEqual({a: 10}) + expect(mergeObjects({a: {b: 100}}, {a: {c: 200, b: 13}})).toEqual({a: {b: 13, c: 200}}) + expect(mergeObjects({a: {c: 200, b: 13}}, {a: {b: 100}})).toEqual({a: {b: 100, c: 200}}) + }); + + it('should leave other objects intact', () => { + const m = new Map([['a', 56]]); + expect(mergeObjects(new Map([['a', 12]]), m)).toEqual(m); + + const s = new Set([2, 4]); + expect(mergeObjects(new Set([2, 4, 6]), s)).toEqual(s); + }); +}); \ No newline at end of file diff --git a/hp.config.js b/hp.config.js new file mode 100644 index 00000000..4d76ce1c --- /dev/null +++ b/hp.config.js @@ -0,0 +1,27 @@ +const homePage = require('./website/data/home.page'); +const documentationPage = require('./website/data/documentation.page'); +const learnPage = require('./website/data/learn.page'); +const site = require('./website/data/site.json'); +const packageJSON = require('./package.json'); +const {CodeSnippet} = require('./website/tags/code-snippet'); + +const env = process.env.NODE_ENV || 'development'; + +module.exports = { + env, + staticData: { + pages: { + documentation: documentationPage, + home: homePage, + learn: learnPage, + }, + site: { + ...site, + version: packageJSON.version, + license: packageJSON.license + } + }, + customTags: [ + CodeSnippet, + ] +} \ No newline at end of file diff --git a/website/server-test.js b/website/server-test.js index fd952f00..bfa0a5fc 100644 --- a/website/server-test.js +++ b/website/server-test.js @@ -2,16 +2,10 @@ const express = require('express'); const http = require('http'); const path = require('path'); const {engine} = require('../core/engine'); -const homePage = require('./data/home.page'); const documentationPage = require('./data/documentation.page'); -const learnPage = require('./data/learn.page'); -const {CodeSnippet} = require('./tags/code-snippet'); -const site = require('./data/site.json'); -const packageJSON = require('./../package.json'); const {collectPaths} = require("./data/collect-paths"); const app = express(); -const env = process.env.NODE_ENV || 'development'; const paths = collectPaths(documentationPage.menu.list); (async () => { @@ -34,25 +28,6 @@ const paths = collectPaths(documentationPage.menu.list); }) await engine(app, path.resolve(__dirname, './pages'), { - env, - staticData: { - pages: { - documentation: documentationPage, - home: homePage, - learn: learnPage, - }, - site: { - ...site, - version: packageJSON.version, - license: packageJSON.license - }, - params: {}, - query: {}, - path: '/' - }, - customTags: [ - CodeSnippet, - ], onPageRequest: (req) => { const fullPath = req.path.replace(/(\/|\.html)$/, ''); return { From 28e1a938bbfa895df6eeb9e2df0d10b592df3852 Mon Sep 17 00:00:00 2001 From: Elson Correia Date: Fri, 16 Jul 2021 21:39:30 -0400 Subject: [PATCH 02/13] documentation --- .../_partials/docs/_engine-function.html | 32 +++++++++++++++++-- .../_partials/docs/_getting-started.html | 24 ++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/website/pages/_partials/docs/_engine-function.html b/website/pages/_partials/docs/_engine-function.html index 914236f8..22f42668 100644 --- a/website/pages/_partials/docs/_engine-function.html +++ b/website/pages/_partials/docs/_engine-function.html @@ -50,11 +50,15 @@

Arguments

{ concept: 'options', type: 'type: object, optional', - description: 'Object with different options to be consumed by the engine.' + description: 'Object with different options to be consumed by the engine. If not provided, the engine will try to find for the hp.config.js file on the project root directory.' }, ] }">

Options

+

Options can be provided directly to the engine function as third argument or you can simply create a hp.config.js +at the root directory and export(using module.exports = {...}) an object with the following properties.

+

If you provide options both, by providing the hp.config.js file and engine options, these are deeply merged + and the engine options will override the hp.config.js file where they match in properties.

Return

-

The engine returns undefined.

+

The engine returns a Promise.

Usage Examples

+

How hp.config.js file may look like. Right now you must always export with module.exports.

+ +// hp.config.js +const homePage = require('./website/data/home.page'); +const aboutPage = require('./website/data/about.page'); +const {CodeSnippet} = require('./website/tags/code-snippet'); + +const env = process.env.NODE_ENV || 'development'; + +module.exports = { + env, + staticData: { + pages: { + home: homePage, + about: aboutPage, + }, + }, + customTags: [ + CodeSnippet, + ] +} + +

Providing static data to the engine.

engine(app, path.resolve(__dirname, './pages'), { staticData: { @@ -97,6 +124,7 @@

Usage Examples

} });
+

Providing a page request handler which inject context data to the templates.

engine(app, path.resolve(__dirname, './pages'), { onPageRequest: (req) => { diff --git a/website/pages/_partials/docs/_getting-started.html b/website/pages/_partials/docs/_getting-started.html index 2a55db97..0a948a41 100644 --- a/website/pages/_partials/docs/_getting-started.html +++ b/website/pages/_partials/docs/_getting-started.html @@ -63,4 +63,28 @@

Server Setup

HTML+ engine will setup your Routes for your pages and all handlers for CSS(including preprocessors), Javascript and Typescript files.

+

Config file

+

The engine function takes an option object as third argument +which you can also provide by creating a hp.config.js file on the root of your project with same properties.

+ +// hp.config.js +const homePage = require('./website/data/home.page'); +const aboutPage = require('./website/data/about.page'); +const {CodeSnippet} = require('./website/tags/code-snippet'); + +const env = process.env.NODE_ENV || 'development'; + +module.exports = { + env, + staticData: { + pages: { + home: homePage, + about: aboutPage, + }, + }, + customTags: [ + CodeSnippet, + ] +}; + \ No newline at end of file From 96820fcc66d76b5bbff2d9fb2710b9f597ff6684 Mon Sep 17 00:00:00 2001 From: Elson Correia Date: Fri, 16 Jul 2021 21:40:57 -0400 Subject: [PATCH 03/13] bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fec6d946..c61030b4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@beforesemicolon/html-plus", - "version": "0.4.6", + "version": "0.4.7", "description": "HTML Template Engine/Language", "main": "dist/index.js", "files": [ From fa7dc4a73d09988ca7773ffe11152748fb5b594b Mon Sep 17 00:00:00 2001 From: Elson Correia Date: Fri, 16 Jul 2021 23:08:35 -0400 Subject: [PATCH 04/13] setup options --- core/engine/index.js | 28 +++++++++++ core/engine/page-and-resources-middleware.js | 6 +-- core/transformers/less.transformer.js | 14 ++++-- core/transformers/sass.transformer.js | 7 +++ core/transformers/stylus.transformer.js | 52 ++++++++++++++++---- 5 files changed, 90 insertions(+), 17 deletions(-) diff --git a/core/engine/index.js b/core/engine/index.js index d4d05c5a..c183db55 100644 --- a/core/engine/index.js +++ b/core/engine/index.js @@ -15,6 +15,34 @@ const defaultOptions = { customTags: [], customAttributes: [], env: 'development', + sass: { + indentWidth: 2, + precision: 5, + indentType: 'space', + linefeed: 'lf', + sourceComments: false, + includePaths: [], + functions: {}, + }, + less: { + strictUnits: false, + insecure: false, + paths: [], + math: 1, + urlArgs: '', + modifyVars: null, + lint: false, + }, + stylus: { + functions: {}, + set: {}, + define: {}, + includes: [], + imports: [], + }, + postCSS: { + plugins: [] + }, onPageRequest() { } } diff --git a/core/engine/page-and-resources-middleware.js b/core/engine/page-and-resources-middleware.js index 9b7615e7..4d8629db 100644 --- a/core/engine/page-and-resources-middleware.js +++ b/core/engine/page-and-resources-middleware.js @@ -17,7 +17,7 @@ const sourcesExtensions = new Set([ ]); const cache = {}; -function pageAndResourcesMiddleware(pagesRoutes, pagesDirectoryPath, {env, onPageRequest}) { +function pageAndResourcesMiddleware(pagesRoutes, pagesDirectoryPath, {env, onPageRequest, sass, less}) { return async (req, res, next) => { if (req.method === 'GET') { const ext = path.extname(req.path); @@ -45,11 +45,11 @@ function pageAndResourcesMiddleware(pagesRoutes, pagesDirectoryPath, {env, onPag switch (ext) { case '.scss': case '.sass': - content = await transformResource.sass({file}); + content = await transformResource.sass({file, ...sass}); content = (await transformResource.css(content, {file, env})).content; break; case '.less': - content = await transformResource.less({file}); + content = await transformResource.less({file, ...less}); content = (await transformResource.css(content, {file, env})).content; break; case '.styl': diff --git a/core/transformers/less.transformer.js b/core/transformers/less.transformer.js index d63a8334..a0e95c9f 100644 --- a/core/transformers/less.transformer.js +++ b/core/transformers/less.transformer.js @@ -5,7 +5,14 @@ const render = promisify(less.render); const defaultOptions = { env: 'development', - file: null + file: null, + strictUnits: false, + insecure: false, + paths: [], + math: 1, + urlArgs: '', + modifyVars: null, + lint: false, } async function lessTransformer(content, opt = defaultOptions) { @@ -22,10 +29,9 @@ async function lessTransformer(content, opt = defaultOptions) { content = content ?? ''; const options = { - ...defaultOptions, - env: opt.env, + ...opt, filename: opt.file?.fileAbsolutePath, - // ...(opt.env === 'development' && {sourceMap: {}}) + ...(opt.env === 'production' && {sourceMap: {}}) } return render(content, options).then(res => { diff --git a/core/transformers/sass.transformer.js b/core/transformers/sass.transformer.js index 8a317ccc..b3a470d8 100644 --- a/core/transformers/sass.transformer.js +++ b/core/transformers/sass.transformer.js @@ -6,6 +6,13 @@ const render = promisify(nodeSass.render); const defaultOptions = { env: 'development', file: null, + indentWidth: 2, + precision: 5, + indentType: 'space', + linefeed: 'lf', + sourceComments: false, + functions: {}, + includePaths: [], } async function sassTransformer(content, opt = defaultOptions) { diff --git a/core/transformers/stylus.transformer.js b/core/transformers/stylus.transformer.js index 3a4ce983..eb385566 100644 --- a/core/transformers/stylus.transformer.js +++ b/core/transformers/stylus.transformer.js @@ -1,18 +1,20 @@ const stylus = require('stylus'); -const {promisify} = require('util'); - -const render = promisify(stylus.render); const defaultOptions = { env: 'development', file: null, + functions: {}, + set: {}, + define: {}, + includes: [], + imports: [], } async function stylusTransformer(content = null, opt = defaultOptions) { if (content && typeof content === 'object') { opt = content; content = null; - + if (!opt.file) { throw new Error('If no string content is provided, the "file" option must be provided.') } @@ -21,13 +23,43 @@ async function stylusTransformer(content = null, opt = defaultOptions) { opt = {...defaultOptions, ...opt}; content = content ?? ''; - return await render(content, { - filename: opt.file?.fileAbsolutePath, - // ...(opt.env === 'development' && {sourceMap: 'inline'}), - }) - .then(css => { - return css; + return await (new Promise((res, rej) => { + const {set, define, includes, imports, ...options} = opt; + + const styl = stylus(content, { + ...options, + filename: opt.file?.fileAbsolutePath, + ...(opt.env === 'production' && {sourceMap: 'inline'}), }); + + for (let x in set) { + if (set.hasOwnProperty(x)) { + styl.set(x, opt.set[x]) + } + } + + for (let x in define) { + if (define.hasOwnProperty(x)) { + styl.define(x, define[x]) + } + } + + includes.forEach(inc => { + styl.include(inc) + }) + + imports.forEach(imp => { + styl.import(imp) + }) + + styl.render((err, css) => { + if (err) { + return rej(err); + } + + res(css) + }) + })) } module.exports.stylusTransformer = stylusTransformer; From dfacd30c5e356e1e87c18e8ce0b46c1c8441c06d Mon Sep 17 00:00:00 2001 From: Elson Correia Date: Sat, 17 Jul 2021 11:22:07 -0400 Subject: [PATCH 05/13] easy up stylus and sass tests --- core/engine/index.js | 6 +-- core/transformers/sass.transformer.spec.js | 57 ++++++++++++++++++++++ core/transformers/stylus.transformer.js | 30 ++---------- 3 files changed, 61 insertions(+), 32 deletions(-) diff --git a/core/engine/index.js b/core/engine/index.js index c183db55..6dbbffa0 100644 --- a/core/engine/index.js +++ b/core/engine/index.js @@ -34,11 +34,7 @@ const defaultOptions = { lint: false, }, stylus: { - functions: {}, - set: {}, - define: {}, - includes: [], - imports: [], + paths: [], }, postCSS: { plugins: [] diff --git a/core/transformers/sass.transformer.spec.js b/core/transformers/sass.transformer.spec.js index cb39bb1c..3166f522 100644 --- a/core/transformers/sass.transformer.spec.js +++ b/core/transformers/sass.transformer.spec.js @@ -87,4 +87,61 @@ describe('sassTransformer', () => { return expect(sassTransformer({})).rejects.toThrowError('If no string content is provided, the "file" option must be provided.') }); + describe('should work with other options', () => { + it('indentWidth', () => { + return sassTransformer(` + body { + background: #edd; + } + `, { + indentWidth: 8 + }).then(res => { + expect(res).toEqual('body {\n' + + ' background: #edd; }\n'); + }) + }); + + it('precision', () => { + return sassTransformer(` + $w: (10 / 3); + body { + width: #{$w}px; + } + `, { + precision: 5 + }).then(res => { + expect(res).toEqual('body {\n' + + ' width: 3.33333px; }\n'); + }) + }); + + it('indentType', () => { + return sassTransformer(` + body { + width: 300px; + } + `, { + indentWidth: 1, + indentType: 'tab' + }).then(res => { + expect(res).toEqual('body {\n' + + '\twidth: 300px; }\n'); + }) + }); + + it('sourceComments', () => { + return sassTransformer(` + body { + width: 300px; + } + `, { + sourceComments: true + }).then(res => { + expect(res).toEqual('/* line 2, stdin */\n' + + 'body {\n' + + ' width: 300px; }\n'); + }) + }); + }); + }); \ No newline at end of file diff --git a/core/transformers/stylus.transformer.js b/core/transformers/stylus.transformer.js index eb385566..16eb4bf9 100644 --- a/core/transformers/stylus.transformer.js +++ b/core/transformers/stylus.transformer.js @@ -3,11 +3,7 @@ const stylus = require('stylus'); const defaultOptions = { env: 'development', file: null, - functions: {}, - set: {}, - define: {}, - includes: [], - imports: [], + paths: [] } async function stylusTransformer(content = null, opt = defaultOptions) { @@ -24,33 +20,13 @@ async function stylusTransformer(content = null, opt = defaultOptions) { content = content ?? ''; return await (new Promise((res, rej) => { - const {set, define, includes, imports, ...options} = opt; const styl = stylus(content, { - ...options, + ...opt, filename: opt.file?.fileAbsolutePath, ...(opt.env === 'production' && {sourceMap: 'inline'}), }); - - for (let x in set) { - if (set.hasOwnProperty(x)) { - styl.set(x, opt.set[x]) - } - } - - for (let x in define) { - if (define.hasOwnProperty(x)) { - styl.define(x, define[x]) - } - } - - includes.forEach(inc => { - styl.include(inc) - }) - - imports.forEach(imp => { - styl.import(imp) - }) + styl.render((err, css) => { if (err) { From 14f3738cfed3385a5110d7b7fab931113af48256 Mon Sep 17 00:00:00 2001 From: Elson Correia Date: Sat, 17 Jul 2021 11:45:07 -0400 Subject: [PATCH 06/13] doc update --- .../_partials/docs/_engine-function.html | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/website/pages/_partials/docs/_engine-function.html b/website/pages/_partials/docs/_engine-function.html index 22f42668..6001d0de 100644 --- a/website/pages/_partials/docs/_engine-function.html +++ b/website/pages/_partials/docs/_engine-function.html @@ -86,6 +86,26 @@

Options

type: 'type: function', description: 'A callback function that will be called on every page request with a express request that must return an object representing the context data to be passed to the template to be rendered on that page request.' }, + { + concept: 'sass', + type: 'type: object', + description: 'object of sass options but only these are supported: indentWidth, precision, indentType, linefeed, sourceComments, includePaths, functions.' + }, + { + concept: 'less', + type: 'type: object', + description: 'object of less options but only these are supported: strictUnits, insecure, paths, urlArgs, sourceComments, modifyVars, lint.' + }, + { + concept: 'stylus', + type: 'type: object', + description: 'object of stylus options but only these are supported: paths.' + }, + { + concept: 'postCSS', + type: 'type: object', + description: 'object of postCSS options but only these are supported: plugins. It already uses atImport, postcssPresetEnv, autoprefixer, purgeCSS, cssnano and Discard Comments plugins by default.' + }, ] }">

Return

From 11f64bfd0fec579aa223c6f819b31d90ab334d3a Mon Sep 17 00:00:00 2001 From: Elson Correia Date: Sat, 17 Jul 2021 12:14:34 -0400 Subject: [PATCH 07/13] additional doc for postCSS --- website/pages/_partials/docs/_engine-function.html | 4 ++++ website/pages/_partials/docs/_getting-started.html | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/website/pages/_partials/docs/_engine-function.html b/website/pages/_partials/docs/_engine-function.html index 6001d0de..189c1672 100644 --- a/website/pages/_partials/docs/_engine-function.html +++ b/website/pages/_partials/docs/_engine-function.html @@ -117,6 +117,7 @@

Usage Examples

const homePage = require('./website/data/home.page'); const aboutPage = require('./website/data/about.page'); const {CodeSnippet} = require('./website/tags/code-snippet'); +const tailwind = require('tailwindcss'); const env = process.env.NODE_ENV || 'development'; @@ -130,6 +131,9 @@

Usage Examples

}, customTags: [ CodeSnippet, + ], + postCSS: [ + plugins: [tailwind] ] } diff --git a/website/pages/_partials/docs/_getting-started.html b/website/pages/_partials/docs/_getting-started.html index 0a948a41..7b58e652 100644 --- a/website/pages/_partials/docs/_getting-started.html +++ b/website/pages/_partials/docs/_getting-started.html @@ -71,6 +71,7 @@

Config file

const homePage = require('./website/data/home.page'); const aboutPage = require('./website/data/about.page'); const {CodeSnippet} = require('./website/tags/code-snippet'); +const tailwind = require('tailwindcss'); const env = process.env.NODE_ENV || 'development'; @@ -84,6 +85,9 @@

Config file

}, customTags: [ CodeSnippet, + ], + postCSS: [ + plugins: [tailwind] ] }; From 523cd6d2e464e60271de53ed5215e0c8c7758741 Mon Sep 17 00:00:00 2001 From: Elson Correia Date: Sat, 17 Jul 2021 12:22:17 -0400 Subject: [PATCH 08/13] ignore hp-config file --- tsconfig.json | 1 + 1 file changed, 1 insertion(+) diff --git a/tsconfig.json b/tsconfig.json index 0d015b55..09529c52 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -73,6 +73,7 @@ "exclude": [ "./website", "./docs", + "./hp.config.js", "**/*.spec.js" ] } From e9f6dce7c33b12174b4ec7b7d665f59ad2557ea7 Mon Sep 17 00:00:00 2001 From: Elson Correia Date: Sat, 17 Jul 2021 12:26:23 -0400 Subject: [PATCH 09/13] only checks on node 14 --- .github/workflows/linux.yml | 4 ++-- .github/workflows/mac.yml | 4 ++-- .github/workflows/window.yml | 41 ++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/window.yml diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 9e4f0cd0..857c2391 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -8,7 +8,7 @@ on: push: branches: [ master, develop ] pull_request: - branches: [ master, develop ] + branches: [ master, develop, release-* ] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: @@ -22,7 +22,7 @@ jobs: strategy: matrix: - node: [10.x, 12.x, 14.x] + node: [14.x] # Steps represent a sequence of tasks that will be executed as part of the job steps: diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml index 6c6f33a0..25d2a157 100644 --- a/.github/workflows/mac.yml +++ b/.github/workflows/mac.yml @@ -8,7 +8,7 @@ on: push: branches: [ master, develop ] pull_request: - branches: [ master, develop ] + branches: [ master, develop, release-* ] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: @@ -22,7 +22,7 @@ jobs: strategy: matrix: - node: [10.x, 12.x, 14.x] + node: [14.x] # Steps represent a sequence of tasks that will be executed as part of the job steps: diff --git a/.github/workflows/window.yml b/.github/workflows/window.yml new file mode 100644 index 00000000..1689bc6e --- /dev/null +++ b/.github/workflows/window.yml @@ -0,0 +1,41 @@ +# This is a basic workflow to help you get started with Actions + +name: CI + +# Controls when the action will run. +on: + # Triggers the workflow on push or pull request events but only for the master branch + push: + branches: [ master, develop ] + pull_request: + branches: [ master, develop, release-* ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: windows-latest + + strategy: + matrix: + node: [14.x] + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + with: + node-version: ${{ matrix.node }} + + # Runs a single command using the runners shell + - name: Install packages + run: npm install + + # Runs a single command using the runners shell + - name: Test code + run: npm run tests + From 0d086bffe37a8fb05eb96eb4156a69fe209b35c1 Mon Sep 17 00:00:00 2001 From: Elson Correia Date: Sat, 17 Jul 2021 12:37:35 -0400 Subject: [PATCH 10/13] fix tests --- .github/workflows/linux.yml | 2 +- .github/workflows/mac.yml | 2 +- .github/workflows/window.yml | 2 +- core/utils/merge-objects.js | 4 +--- core/utils/merge-objects.spec.js | 8 -------- 5 files changed, 4 insertions(+), 14 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 857c2391..6ca60d86 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -8,7 +8,7 @@ on: push: branches: [ master, develop ] pull_request: - branches: [ master, develop, release-* ] + branches: [ master, develop ] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: diff --git a/.github/workflows/mac.yml b/.github/workflows/mac.yml index 25d2a157..9fe9a819 100644 --- a/.github/workflows/mac.yml +++ b/.github/workflows/mac.yml @@ -8,7 +8,7 @@ on: push: branches: [ master, develop ] pull_request: - branches: [ master, develop, release-* ] + branches: [ master, develop ] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: diff --git a/.github/workflows/window.yml b/.github/workflows/window.yml index 1689bc6e..6a191446 100644 --- a/.github/workflows/window.yml +++ b/.github/workflows/window.yml @@ -8,7 +8,7 @@ on: push: branches: [ master, develop ] pull_request: - branches: [ master, develop, release-* ] + branches: [ master, develop ] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: diff --git a/core/utils/merge-objects.js b/core/utils/merge-objects.js index b4fc4369..5fcd3255 100644 --- a/core/utils/merge-objects.js +++ b/core/utils/merge-objects.js @@ -1,9 +1,7 @@ const {isObject, isArray} = require("util"); -const isObjectLiteral = x => isObject(x) && x.toString() === '[object Object]'; - function mergeObjects(a, b) { - if(!isObjectLiteral(a) || !isObjectLiteral(b)) return b ?? {}; + if(!isObject(a) || !isObject(b)) return b ?? {}; const obj = isArray(a) ? [...a] : a; diff --git a/core/utils/merge-objects.spec.js b/core/utils/merge-objects.spec.js index 86a03dac..b514fd29 100644 --- a/core/utils/merge-objects.spec.js +++ b/core/utils/merge-objects.spec.js @@ -29,12 +29,4 @@ describe('mergeObjects', () => { expect(mergeObjects({a: {b: 100}}, {a: {c: 200, b: 13}})).toEqual({a: {b: 13, c: 200}}) expect(mergeObjects({a: {c: 200, b: 13}}, {a: {b: 100}})).toEqual({a: {b: 100, c: 200}}) }); - - it('should leave other objects intact', () => { - const m = new Map([['a', 56]]); - expect(mergeObjects(new Map([['a', 12]]), m)).toEqual(m); - - const s = new Set([2, 4]); - expect(mergeObjects(new Set([2, 4, 6]), s)).toEqual(s); - }); }); \ No newline at end of file From 681d5172396735cf32a0ae3c1780b8466b21285a Mon Sep 17 00:00:00 2001 From: Elson Correia Date: Sat, 17 Jul 2021 12:45:40 -0400 Subject: [PATCH 11/13] add google analytics --- website/pages/_partials/_layout.html | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/website/pages/_partials/_layout.html b/website/pages/_partials/_layout.html index 59f434ab..0a0bf113 100644 --- a/website/pages/_partials/_layout.html +++ b/website/pages/_partials/_layout.html @@ -51,5 +51,13 @@ + + \ No newline at end of file From d4576ae6c81b51e01317ad7b3c6ac057b784f712 Mon Sep 17 00:00:00 2001 From: Elson Correia Date: Sat, 17 Jul 2021 12:52:31 -0400 Subject: [PATCH 12/13] no win --- .github/workflows/window.yml | 41 ------------------------------------ 1 file changed, 41 deletions(-) delete mode 100644 .github/workflows/window.yml diff --git a/.github/workflows/window.yml b/.github/workflows/window.yml deleted file mode 100644 index 6a191446..00000000 --- a/.github/workflows/window.yml +++ /dev/null @@ -1,41 +0,0 @@ -# This is a basic workflow to help you get started with Actions - -name: CI - -# Controls when the action will run. -on: - # Triggers the workflow on push or pull request events but only for the master branch - push: - branches: [ master, develop ] - pull_request: - branches: [ master, develop ] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "build" - build: - # The type of runner that the job will run on - runs-on: windows-latest - - strategy: - matrix: - node: [14.x] - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - with: - node-version: ${{ matrix.node }} - - # Runs a single command using the runners shell - - name: Install packages - run: npm install - - # Runs a single command using the runners shell - - name: Test code - run: npm run tests - From 21cb1796aba983d05b6f1627422232c8c901e172 Mon Sep 17 00:00:00 2001 From: Elson Correia Date: Sat, 17 Jul 2021 13:03:00 -0400 Subject: [PATCH 13/13] version 5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c61030b4..4c88f751 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@beforesemicolon/html-plus", - "version": "0.4.7", + "version": "0.5.0", "description": "HTML Template Engine/Language", "main": "dist/index.js", "files": [