@newlogic-digital/core 0.9.13 → 1.0.0-beta.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. package/README.md +15 -45
  2. package/index.js +262 -43
  3. package/package.json +13 -58
  4. package/LICENSE +0 -674
  5. package/modules/Core.js +0 -626
  6. package/modules/Emails.js +0 -110
  7. package/modules/Icons.js +0 -140
  8. package/modules/Scripts.js +0 -321
  9. package/modules/Serve.js +0 -124
  10. package/modules/Styles.js +0 -298
  11. package/modules/Templates.js +0 -468
  12. package/modules/Utils.js +0 -299
  13. package/modules/Watch.js +0 -75
  14. package/modules/tailwind/index.cjs +0 -84
  15. package/modules/tailwind/index.js +0 -75
  16. package/packages/gulp-clean-css/LICENSE +0 -20
  17. package/packages/gulp-clean-css/README.md +0 -79
  18. package/packages/gulp-clean-css/index.js +0 -66
  19. package/packages/gulp-clean-css/package.json +0 -68
  20. package/packages/gulp-twig2html/CHANGELOG.md +0 -77
  21. package/packages/gulp-twig2html/LICENSE +0 -22
  22. package/packages/gulp-twig2html/README.md +0 -112
  23. package/packages/gulp-twig2html/index.js +0 -30
  24. package/packages/gulp-twig2html/package.json +0 -47
  25. package/packages/postcss-inset/CHANGELOG.md +0 -5
  26. package/packages/postcss-inset/LICENSE.md +0 -106
  27. package/packages/postcss-inset/README.md +0 -121
  28. package/packages/postcss-inset/index.cjs.js +0 -49
  29. package/packages/postcss-inset/index.es.mjs +0 -47
  30. package/packages/postcss-inset/index.js +0 -47
  31. package/packages/postcss-inset/package.json +0 -58
  32. package/packages/twig-renderer/CHANGELOG.md +0 -66
  33. package/packages/twig-renderer/LICENSE +0 -22
  34. package/packages/twig-renderer/README.md +0 -93
  35. package/packages/twig-renderer/package.json +0 -49
  36. package/packages/twig-renderer/twig-renderer.js +0 -90
package/README.md CHANGED
@@ -10,9 +10,7 @@
10
10
 
11
11
  # ⚙️ Newlogic Core
12
12
 
13
- > Still in very early development.
14
-
15
- Modern principles for creating web applications
13
+ Modern principles for creating web applications. Powered by Vite and Vituum
16
14
 
17
15
  - 💡 Modern principles
18
16
  - 🚀️ Fast development
@@ -21,16 +19,14 @@ Modern principles for creating web applications
21
19
  - ✉️ Email templates
22
20
  - ⚡ Vite as webserver
23
21
 
24
- Newlogic Core is a set of tools that can be used to create modern web applications. Use of modern Javascript, CSS, ES modules, dynamic imports, etc.
22
+ Newlogic Core is an integration for [Vituum](https://vituum.dev), and contains set of tools that can be used to create modern web applications. Use of modern Javascript, CSS, ES modules, dynamic imports, etc.
25
23
 
26
24
  ## 🛠️ Integrated tools
25
+ * **[Vite](https://vitejs.dev)** next-generation frontend tooling
26
+ * **[Vituum](https://vituum.dev)** fast prototyping with template engines
27
27
  * **[PostCSS](https://postcss.org/)** with basic plugins and [Tailwind CSS](https://tailwindcss.com/) for utility classes.
28
- * **[Rollup](https://rollupjs.org/)** for javascript build and minification
29
- * **[Importmaps](https://github.com/WICG/import-maps)** generator for javascript buildless development
30
- * **[CleanCSS](https://github.com/jakubpawlowicz/clean-css)** for css optimization and minification
31
- * **[PurgeCSS](https://purgecss.com/)** for removing unused CSS
32
- * **[TwigJS](https://purgecss.com/)** as template engine
33
- * **[Vite](https://vitejs.dev)** for local webserver
28
+ * **[TwigJS](https://github.com/vituum/vite-plugin-twig)** as template engine twig
29
+ * **[Latte](https://github.com/vituum/vite-plugin-latte)** as template engine latte
34
30
 
35
31
  ### 💡 Basic principle
36
32
 
@@ -40,28 +36,13 @@ PHP programmers often **don't want to configure anything**, basic idea is to add
40
36
 
41
37
  It doesn't matter if you use Nette, Symfony or Laravel - the structure can be freely adjusted as needed - `resources` and` public`, `src` and` dist` or `app/assets` and` www`
42
38
 
43
- It's up to you - all paths are freely configurable in `gulpfile.js` config
39
+ It's up to you - all paths are freely configurable in `vite.config.js` config
44
40
 
45
41
  ### 📦 Modularity
46
42
 
47
- Newlogic Core uses currently [Gulp](https://gulpjs.com/) as smart task system, tasks are generated automatically depending on which modules you use.
48
-
49
- Source files are divided by modules inside `src` directory - styles, scripts, templates, icons, emails, assets. It is optional which modules you want to use for the project, simple delete the directory. You really only use what you want to use.
50
-
51
- If you use [PhpStorm](https://www.jetbrains.com/phpstorm/) tasks will load for you automatically and dynamically according to the availability of individual modules.
52
-
53
- ### ⚡ Without compilation - no building and bundling
54
-
55
- Lets face the facts. PHP programmers **hate javascript compilation**.
43
+ Newlogic Core uses [Vituum](https://vituum.dev) and [Vite](https://vitejs.dev) for frontend tooling.
56
44
 
57
- Principle of Newlogic Core is to write javascript and css source code in next-gen standardized format that works in browsers or will work in the future.
58
-
59
- Javascript sources are executable in browsers via modern solutions like **[Importmaps](https://github.com/WICG/import-maps)** - changes are instant, no waiting for build.
60
-
61
- CSS sources still need to be compiled, because most of standardized features are not yet ready in browsers, but it's getting there.
62
-
63
- ### 🧬 Single Page Apps
64
- For single page applications, [Vite](https://vitejs.dev/) is integrated, and you can use any SPA framework you want. From Newlogic Core, you can only use additional functionalities such as auto-generation of imports into files within folders, iconfont, etc. Or automate some processes by writing new tasks in `gulpfile.js`.
45
+ Source files are divided by modules inside `src` directory - styles, scripts, templates, emails, assets. It is optional which modules you want to use for the project, simple delete the directory. You really only use what you want to use.
65
46
 
66
47
  ## 🪄 Instalation
67
48
 
@@ -71,33 +52,22 @@ npm i @newlogic-digital/core --save-dev
71
52
 
72
53
  ### Requirements
73
54
 
74
- - [Node.js LTS (14.x)](https://nodejs.org/en/download/)
75
- - [NPM (7.x)](https://www.npmjs.com/package/npm) or [Yarn (2.x)](https://yarnpkg.com/)
55
+ - [Node.js LTS (16.x)](https://nodejs.org/en/download/)
76
56
 
77
57
  ### Config
78
58
 
79
- Each Newlogic Core project has to have config via `gulpfile.js`
59
+ Each Newlogic Core project has to have config via `vite.config.js`
80
60
 
81
61
  ```js
82
- import {defineConfig} from "@newlogic-digital/core";
62
+ import { defineConfig } from 'vituum'
63
+ import core from "@newlogic-digital/core"
83
64
 
84
- // minimum configuration example
85
65
  export default defineConfig({
86
- styles: {
87
- purge: {
88
- content: ['src/scripts/**/*.js', 'src/templates/**/*.twig', 'app/Presenters/templates/**/*.latte', 'temp/cdn/*.js']
89
- }
90
- }
66
+ integrations: [core()]
91
67
  })
92
68
  ```
93
69
 
94
70
  You can also try minimal example project [core-starter](https://github.com/newlogic-digital/core-starter)
95
71
 
96
- ## 📌 Future plans
97
- - translating docs to english
98
- - refactor or rewrite everything 😂
99
- - concept is good, but realization could be way better
100
- - future rewrite could drop gulp completely and use esbuild for css, js build and vite for dev server
101
-
102
72
  ## Licence
103
- GNU GPLv3
73
+ MIT
package/index.js CHANGED
@@ -1,44 +1,263 @@
1
- import {
2
- Core,
3
- Utils,
4
- Styles,
5
- Scripts,
6
- Templates,
7
- Icons,
8
- Watch,
9
- Emails,
10
- Functions,
11
- Exists,
12
- Modules,
13
- Package,
14
- Config,
15
- root
16
- } from "./modules/Core.js";
17
-
18
- import { tailwindColors, tailwindColorsRgba, tailwindVariables, tailwindColorsAccent, tailwindColorsCurrent, tailwindAnimations } from './modules/tailwind/index.js'
19
-
20
- const defineConfig = (config) => new Core().init(config);
21
-
22
- export {
23
- defineConfig,
24
- tailwindColors,
25
- tailwindVariables,
26
- tailwindColorsRgba,
27
- tailwindColorsAccent,
28
- tailwindColorsCurrent,
29
- tailwindAnimations,
30
- Core,
31
- Utils,
32
- Styles,
33
- Scripts,
34
- Templates,
35
- Icons,
36
- Watch,
37
- Emails,
38
- Functions,
39
- Exists,
40
- Modules,
41
- Package,
42
- Config,
43
- root
1
+ import tailwind from '@vituum/tailwind'
2
+ import posthtml from '@vituum/posthtml'
3
+ import juice from '@vituum/juice'
4
+ import twig from '@vituum/twig'
5
+ import latte from '@vituum/latte'
6
+ import lodash from 'lodash'
7
+ import minifier from 'html-minifier-terser'
8
+ import fs from 'fs'
9
+ import { dirname, resolve } from 'path'
10
+ import Prism from 'prismjs'
11
+ import loadLanguages from 'prismjs/components/index.js'
12
+ import NormalizeWhitespace from 'prismjs/plugins/normalize-whitespace/prism-normalize-whitespace.js'
13
+
14
+ loadLanguages(['markup', 'css', 'javascript'])
15
+
16
+ const stripIndent = (string) => {
17
+ const indent = () => {
18
+ const match = string.match(/^[ \t]*(?=\S)/gm)
19
+
20
+ if (!match) {
21
+ return 0
22
+ }
23
+
24
+ return match.reduce((r, a) => Math.min(r, a.length), Infinity)
25
+ }
26
+
27
+ if (indent() === 0) {
28
+ return string
29
+ }
30
+
31
+ const regex = new RegExp(`^[ \\t]{${indent()}}`, 'gm')
32
+
33
+ return string.replace(regex, '')
34
+ }
35
+
36
+ const defaultConfig = {
37
+ posthtml: {},
38
+ juice: {},
39
+ tailwind: {},
40
+ twig: {
41
+ namespaces: {
42
+ src: resolve(process.cwd(), 'src'),
43
+ templates: resolve(process.cwd(), 'src/templates')
44
+ },
45
+ functions: {
46
+ pages: () => {
47
+ return fs.readdirSync('src/views').filter(file => fs.statSync('src/views/' + file).isFile())
48
+ },
49
+ fetch: (data) => {
50
+ if (typeof data !== 'undefined') {
51
+ if (data.indexOf('http') > -1) {
52
+ return data
53
+ } else {
54
+ let slash = data.indexOf('/') + 1
55
+ if (slash > 1) {
56
+ slash = 0
57
+ }
58
+
59
+ return fs.readFileSync(process.cwd() + '/' + data.substring(slash, data.length), 'utf8').toString()
60
+ }
61
+ }
62
+ },
63
+ randomColor: () => {
64
+ return '#' + Math.random().toString(16).slice(2, 8)
65
+ },
66
+ placeholder: (width, height) => {
67
+ const colors = ['333', '444', '666', '222', '777', '888', '111']
68
+ return 'https://via.placeholder.com/' + width + 'x' + height + '/' + colors[Math.floor(Math.random() * colors.length)] + '.webp'
69
+ },
70
+ lazy: (width, height) => {
71
+ const svg = encodeURIComponent(stripIndent('<svg width="' + width + '" height="' + height + '" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ' + width + ' ' + height + '"></svg>'))
72
+
73
+ return 'data:image/svg+xml;charset=UTF-8,' + svg
74
+ },
75
+ ratio: (width, height) => {
76
+ return (height / width) * 100
77
+ }
78
+ },
79
+ filters: {
80
+ asset: (url) => {
81
+ return url.replace('/src/', '/')
82
+ },
83
+ rem: (value) => {
84
+ return `${value / 16}rem`
85
+ },
86
+ encode64: (path) => {
87
+ const svg = encodeURIComponent(stripIndent(path))
88
+
89
+ return 'data:image/svg+xml;charset=UTF-8,' + svg
90
+ },
91
+ exists: (path) => {
92
+ if (path.indexOf('/') === 0) {
93
+ path = path.slice(1)
94
+ }
95
+
96
+ return fs.existsSync(resolve(process.cwd(), path))
97
+ },
98
+ tel: (value) => {
99
+ return value.replace(/\s+/g, '').replace('(', '').replace(')', '')
100
+ }
101
+ },
102
+ extensions: [
103
+ (Twig) => {
104
+ Twig.exports.extendTag({
105
+ type: 'json',
106
+ regex: /^json\s+(.+)$|^json$/,
107
+ next: ['endjson'],
108
+ open: true,
109
+ compile: function(token) {
110
+ const expression = token.match[1] ?? '\'_null\''
111
+
112
+ token.stack = Reflect.apply(Twig.expression.compile, this, [{
113
+ type: Twig.expression.type.expression,
114
+ value: expression
115
+ }]).stack
116
+
117
+ delete token.match
118
+ return token
119
+ },
120
+ parse: async function(token, context, chain) {
121
+ const name = Reflect.apply(Twig.expression.parse, this, [token.stack, context])
122
+ const output = this.parse(token.output, context)
123
+
124
+ const minify = await minifier.minify(output, {
125
+ collapseWhitespace: true,
126
+ collapseInlineTagWhitespace: false,
127
+ minifyCSS: true,
128
+ removeAttributeQuotes: true,
129
+ quoteCharacter: '\'',
130
+ minifyJS: true
131
+ })
132
+
133
+ if (name === '_null') {
134
+ return {
135
+ chain,
136
+ output: JSON.stringify(minify)
137
+ }
138
+ } else {
139
+ return {
140
+ chain,
141
+ output: JSON.stringify({
142
+ [name]: minify
143
+ })
144
+ }
145
+ }
146
+ }
147
+ })
148
+ Twig.exports.extendTag({
149
+ type: 'endjson',
150
+ regex: /^endjson$/,
151
+ next: [],
152
+ open: false
153
+ })
154
+ },
155
+ (Twig) => {
156
+ Twig.exports.extendTag({
157
+ type: "code",
158
+ regex: /^code\s+(.+)$/,
159
+ next: ["endcode"], // match the type of the end tag
160
+ open: true,
161
+ compile: function (token) {
162
+ const expression = token.match[1];
163
+
164
+ token.stack = Reflect.apply(Twig.expression.compile, this, [{
165
+ type: Twig.expression.type.expression,
166
+ value: expression
167
+ }]).stack;
168
+
169
+ delete token.match;
170
+ return token;
171
+ },
172
+ parse: function (token, context, chain) {
173
+ let type = Reflect.apply(Twig.expression.parse, this, [token.stack, context]);
174
+ let output = this.parse(token.output, context);
175
+ let mirror = false;
176
+
177
+ if (type.includes(":mirror")) {
178
+ mirror = true;
179
+ type = type.replace(":mirror", "")
180
+ }
181
+
182
+ const Normalize = new NormalizeWhitespace({
183
+ 'remove-trailing': true,
184
+ 'remove-indent': true,
185
+ 'left-trim': true,
186
+ 'right-trim': true,
187
+ });
188
+
189
+ const wrap = (code, lang) => {
190
+ return `<pre class="language-${lang}"><code>${code}</code></pre>`
191
+ }
192
+
193
+ const highlight = (str, lang) => {
194
+ if (!lang) {
195
+ return wrap(str, 'text')
196
+ }
197
+ lang = lang.toLowerCase()
198
+ const rawLang = lang
199
+ if (lang === 'vue' || lang === 'html') {
200
+ lang = 'markup'
201
+ }
202
+ if (lang === 'md') {
203
+ lang = 'markdown'
204
+ }
205
+ if (lang === 'ts') {
206
+ lang = 'typescript'
207
+ }
208
+ if (lang === 'py') {
209
+ lang = 'python'
210
+ }
211
+ if (!Prism.languages[lang]) {
212
+ try {
213
+ loadLanguages([lang])
214
+ } catch (e) {
215
+ console.warn(`Syntax highlight for language "${lang}" is not supported.`)
216
+ }
217
+ }
218
+ if (Prism.languages[lang]) {
219
+ const code = Prism.highlight(Normalize.normalize(str), Prism.languages[lang], lang)
220
+ return wrap(code, rawLang)
221
+ }
222
+ return wrap(str, 'text')
223
+ }
224
+
225
+ return {
226
+ chain: chain,
227
+ output: `${mirror ? output : ""}${highlight(output, type)}`
228
+ };
229
+ }
230
+ });
231
+ Twig.exports.extendTag({
232
+ type: "endcode",
233
+ regex: /^endcode$/,
234
+ next: [ ],
235
+ open: false
236
+ });
237
+ }
238
+ ]
239
+ },
240
+ latte: {
241
+ isStringFilter: (filename) => dirname(filename).endsWith('emails')
242
+ }
44
243
  }
244
+
245
+ const integration = (userConfig = {}) => {
246
+ userConfig = lodash.merge(defaultConfig, userConfig)
247
+
248
+ return {
249
+ config: {
250
+ integrations: [posthtml(userConfig.posthtml), juice(userConfig.juice), tailwind(userConfig.tailwind), twig(userConfig.twig), latte(userConfig.latte)],
251
+ server: {
252
+ open: true,
253
+ https: true,
254
+ reload: file => (file.endsWith('.tpl') || file.endsWith('.latte')) && !file.includes('temp/')
255
+ },
256
+ templates: {
257
+ format: 'twig'
258
+ }
259
+ }
260
+ }
261
+ }
262
+
263
+ export default integration
package/package.json CHANGED
@@ -1,72 +1,27 @@
1
1
  {
2
2
  "name": "@newlogic-digital/core",
3
3
  "type": "module",
4
- "version": "0.9.13",
4
+ "version": "1.0.0-beta.2",
5
5
  "main": "index.js",
6
6
  "author": "New Logic Studio s.r.o.",
7
7
  "description": "Set of tools that can be used to create modern web applications",
8
- "license": "GNU GPLv3",
9
- "scripts": {
10
- "docs:dev": "vitepress dev docs",
11
- "docs:build": "vitepress build docs",
12
- "docs:serve": "vitepress serve docs",
13
- "tailwind": "rollup modules/tailwind/index.js --file modules/tailwind/index.cjs --format cjs"
14
- },
8
+ "license": "MIT",
15
9
  "dependencies": {
16
- "@babel/core": "^7.17.12",
17
- "@babel/preset-env": "^7.17.12",
18
- "@rollup/plugin-babel": "^5.3.1",
19
- "@rollup/plugin-commonjs": "^22.0.0",
20
- "@rollup/plugin-node-resolve": "^13.3.0",
21
- "@rollup/plugin-replace": "^4.0.0",
22
- "adm-zip": "^0.5.9",
23
- "clean-css": "^5.3.0",
24
- "fs-extra": "^10.1.0",
25
- "plugin-error": "^1.0.1",
26
- "through2": "^4.0.2",
27
- "twig": "^1.15.4",
28
- "gulp": "^4.0.2",
29
- "gulp-data": "^1.3.1",
30
- "gulp-htmlmin": "^5.0.1",
31
- "gulp-if": "^3.0.0",
32
- "gulp-inline-css": "^4.0.0",
33
- "gulp-plumber": "^1.2.1",
34
- "gulp-postcss": "^9.0.1",
35
- "gulp-purgecss": "^4.1.3",
36
- "gulp-rename": "^2.0.0",
37
- "gulp-replace": "^1.1.3",
38
- "gulp-rev": "^9.0.0",
39
- "gulp-rev-rewrite": "^5.0.0",
40
- "lazypipe": "^1.0.2",
41
- "lodash": "^4.17.21",
42
- "postcss-custom-media": "^8.0.0",
43
- "postcss-custom-properties": "^12.1.7",
44
- "postcss-custom-selectors": "^6.0.0",
45
- "postcss-import": "^14.1.0",
46
- "postcss-nesting": "^10.1.6",
47
- "rollup": "^2.73.0",
48
- "rollup-plugin-import-map": "^2.2.2",
49
- "rollup-plugin-terser": "^7.0.2",
50
- "vite": "~2.9.9",
51
- "prismjs": "^1.28.0"
52
- },
53
- "peerDependencies": {
54
- "autoprefixer": "^10.4.7",
55
- "postcss": "^8.4.13",
56
- "tailwindcss": "^3.0.24"
57
- },
58
- "devDependencies": {
59
- "vitepress": "^0.22.4"
10
+ "@vituum/tailwind": "^0.1.2",
11
+ "@vituum/posthtml": "^0.1.0",
12
+ "@vituum/juice": "^0.1.3",
13
+ "@vituum/twig": "^0.1.0",
14
+ "@vituum/latte": "^0.1.0",
15
+ "prismjs": "~1.28.0",
16
+ "html-minifier-terser": "^7.0.0",
17
+ "lodash": "^4.17.21"
60
18
  },
61
19
  "files": [
62
- "index.js",
63
- "modules",
64
- "packages"
20
+ "index.js"
65
21
  ],
66
22
  "engines": {
67
- "node": ">=14.0.0",
68
- "npm": ">=7.10.0",
69
- "yarn": ">=2.3.0"
23
+ "node": ">=16.0.0",
24
+ "npm": ">=8.0.0"
70
25
  },
71
26
  "repository": {
72
27
  "type": "git",