@rws-framework/client 2.6.4 → 2.7.1

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.
File without changes
package/package.json CHANGED
@@ -1,100 +1,100 @@
1
1
  {
2
2
  "name": "@rws-framework/client",
3
3
  "private": false,
4
- "version": "2.6.4",
4
+ "version": "2.7.1",
5
5
  "main": "src/index.ts",
6
6
  "scripts": {
7
- "docs": "typedoc --tsconfig ./tsconfig.json"
7
+ "docs": "typedoc --tsconfig ./tsconfig.json"
8
8
  },
9
9
  "bin": {
10
- "rws-client": "./console.js"
10
+ "rws-client": "./console.js"
11
11
  },
12
12
  "repository": {
13
- "type": "git",
14
- "url": "git+https://github.com/papablack/rws-client.git"
13
+ "type": "git",
14
+ "url": "git+https://github.com/papablack/rws-client.git"
15
15
  },
16
16
  "keywords": [
17
- "frontend",
18
- "rws",
19
- "client",
20
- "typescript"
17
+ "frontend",
18
+ "rws",
19
+ "client",
20
+ "typescript"
21
21
  ],
22
22
  "author": "papablack",
23
23
  "license": "ISC",
24
24
  "bugs": {
25
- "url": "https://github.com/papablack/rws-client/issues"
25
+ "url": "https://github.com/papablack/rws-client/issues"
26
26
  },
27
27
  "homepage": "https://github.com/papablack/rws-client#readme",
28
28
  "dependencies": {
29
- "@microsoft/fast-element": "^1.12.0",
30
- "@microsoft/fast-foundation": "^2.46.2",
31
- "@rws-framework/console": "^0.3.5",
32
- "@types/moment": "^2.13.0",
33
- "dragula": "^3.7.3",
34
- "he": "^1.2.0",
35
- "json5": "^2.2.3",
36
- "lodash": "^4.17.21",
37
- "moment": "^2.29.4",
38
- "partial-json-parser": "^1.0.0",
39
- "reflect-metadata": "^0.1.13",
40
- "resolve-url-loader": "^5.0.0",
41
- "sanitize-html": "^2.12.1",
42
- "sass": "^1.69.7",
43
- "scss-loading-animations": "^1.0.1",
44
- "socket.io-client": "^4.7.2",
45
- "ts-loader": "^9.4.4",
46
- "tsc-watch": "^6.0.4",
47
- "tslib": "^2.6.2",
48
- "upload": "^1.3.2",
49
- "url-router": "^13.0.0",
50
- "uuid": "^9.0.1",
51
- "v4": "^0.0.1"
29
+ "@microsoft/fast-element": "^1.12.0",
30
+ "@microsoft/fast-foundation": "^2.46.2",
31
+ "@rws-framework/console": "^0.3.5",
32
+ "@types/moment": "^2.13.0",
33
+ "dragula": "^3.7.3",
34
+ "he": "^1.2.0",
35
+ "json5": "^2.2.3",
36
+ "lodash": "^4.17.21",
37
+ "moment": "^2.29.4",
38
+ "partial-json-parser": "^1.0.0",
39
+ "reflect-metadata": "^0.1.13",
40
+ "resolve-url-loader": "^5.0.0",
41
+ "sanitize-html": "^2.12.1",
42
+ "sass": "^1.69.7",
43
+ "scss-loading-animations": "^1.0.1",
44
+ "socket.io-client": "^4.7.2",
45
+ "ts-loader": "^9.4.4",
46
+ "tsc-watch": "^6.0.4",
47
+ "tslib": "^2.6.2",
48
+ "upload": "^1.3.2",
49
+ "url-router": "^13.0.0",
50
+ "uuid": "^9.0.1",
51
+ "v4": "^0.0.1"
52
52
  },
53
53
  "devDependencies": {
54
- "@types/dragula": "^3.7.4",
55
- "@types/eslint": "^6.0.0",
56
- "@types/express-fileupload": "^1.4.4",
57
- "@types/glob": "^8.1.0",
58
- "@types/he": "^1.2.3",
59
- "@types/sanitize-html": "^2.11.0",
60
- "@types/uuid": "^9.0.7",
61
- "@typescript-eslint/parser": "^5.0.0",
62
- "clean-webpack-plugin": "^4.0.0",
63
- "css-loader": "^6.8.1",
64
- "css-minimizer-webpack-plugin": "^5.0.1",
65
- "eslint": "^6.0.0",
66
- "file-loader": "^6.2.0",
67
- "html-webpack-plugin": "^5.5.3",
68
- "loader-utils": "^3.2.1",
69
- "mini-css-extract-plugin": "^2.7.6",
70
- "minimatch": "^9.0.4",
71
- "node-sass": "^9.0.0",
72
- "sass-loader": "^13.3.2",
73
- "source-map": "^0.7.4",
74
- "style-loader": "^3.3.3",
75
- "terser-webpack-plugin": "^5.3.9",
76
- "ts-loader": "^9.4.4",
77
- "ts-node": "^10.9.1",
78
- "tsconfig-paths": "^4.2.0",
79
- "tsconfig-paths-webpack-plugin": "^4.1.0",
80
- "typedoc": "^0.25.4",
81
- "typedoc-plugin-mermaid": "^1.10.0",
82
- "typedoc-plugin-not-exported": "^0.1.6",
83
- "typedoc-plugin-rename-defaults": "^0.7.0",
84
- "typedoc-theme-hierarchy": "^4.1.2",
85
- "typescript": "^5.1.6",
86
- "url-loader": "^4.1.1",
87
- "webpack": "^5.75.0",
88
- "webpack-bundle-analyzer": "^4.10.1",
89
- "webpack-cli": "^5.1.4",
90
- "webpack-dev-server": "^4.15.1",
91
- "webpack-node-externals": "^3.0.0"
54
+ "@types/dragula": "^3.7.4",
55
+ "@types/eslint": "^6.0.0",
56
+ "@types/express-fileupload": "^1.4.4",
57
+ "@types/glob": "^8.1.0",
58
+ "@types/he": "^1.2.3",
59
+ "@types/sanitize-html": "^2.11.0",
60
+ "@types/uuid": "^9.0.7",
61
+ "@typescript-eslint/parser": "^5.0.0",
62
+ "clean-webpack-plugin": "^4.0.0",
63
+ "css-loader": "^6.8.1",
64
+ "css-minimizer-webpack-plugin": "^5.0.1",
65
+ "eslint": "^6.0.0",
66
+ "file-loader": "^6.2.0",
67
+ "html-webpack-plugin": "^5.5.3",
68
+ "loader-utils": "^3.2.1",
69
+ "mini-css-extract-plugin": "^2.7.6",
70
+ "minimatch": "^9.0.4",
71
+ "node-sass": "^9.0.0",
72
+ "sass-loader": "^13.3.2",
73
+ "source-map": "^0.7.4",
74
+ "style-loader": "^3.3.3",
75
+ "terser-webpack-plugin": "^5.3.9",
76
+ "ts-loader": "^9.4.4",
77
+ "ts-node": "^10.9.1",
78
+ "tsconfig-paths": "^4.2.0",
79
+ "tsconfig-paths-webpack-plugin": "^4.1.0",
80
+ "typedoc": "^0.25.4",
81
+ "typedoc-plugin-mermaid": "^1.10.0",
82
+ "typedoc-plugin-not-exported": "^0.1.6",
83
+ "typedoc-plugin-rename-defaults": "^0.7.0",
84
+ "typedoc-theme-hierarchy": "^4.1.2",
85
+ "typescript": "^5.1.6",
86
+ "url-loader": "^4.1.1",
87
+ "base64-font-laoder": "",
88
+ "webpack": "^5.75.0",
89
+ "webpack-bundle-analyzer": "^4.10.1",
90
+ "webpack-cli": "^5.1.4",
91
+ "webpack-dev-server": "^4.15.1",
92
+ "webpack-node-externals": "^3.0.0"
92
93
  },
93
94
  "resolutions": {
94
- "lodash": "^4.17.21"
95
+ "lodash": "^4.17.21"
95
96
  },
96
97
  "overrides": {
97
- "lodash": "^4.17.21"
98
+ "lodash": "^4.17.21"
98
99
  }
99
- }
100
-
100
+ }
@@ -220,7 +220,8 @@ const RWSWebpackWrapper = (config) => {
220
220
  throw new Error('RWS Webpack build failed.');
221
221
  }
222
222
 
223
- const cfgExport = {
223
+ const cfgExport = {
224
+ context: executionDir,
224
225
  entry: {
225
226
  client: config.entry,
226
227
  ...automatedEntries
@@ -233,7 +234,7 @@ const RWSWebpackWrapper = (config) => {
233
234
  filename: isParted ? (partedPrefix || 'rws') + '.[name].js' : outputFileName,
234
235
  sourceMapFilename: '[file].map',
235
236
  },
236
- resolve: {
237
+ resolve: {
237
238
  extensions: ['.ts', '.js'],
238
239
  modules: modules_setup,
239
240
  alias: {
@@ -253,7 +254,7 @@ const RWSWebpackWrapper = (config) => {
253
254
  use: [
254
255
  'css-loader',
255
256
  ],
256
- },
257
+ },
257
258
  {
258
259
  test: /\.scss$/,
259
260
  use: [
@@ -1,5 +1,3 @@
1
- @import "../../../styles/includes.scss";
2
-
3
1
  //loader
4
2
 
5
3
  $loader-color: var(--primary-color, #eb7b13);
@@ -55,9 +55,11 @@ export class RouterComponent extends RWSViewComponent {
55
55
  component: childComponent
56
56
  });
57
57
 
58
- const newComponent = document.createElement((childComponent as any).definition.name);
59
- newComponent.routeParams = routeParams;
60
-
58
+ const newComponent = document.createElement((childComponent as any).definition.name);
59
+ if(Object.keys(routeParams).length){
60
+ newComponent.routeParams = routeParams;
61
+ }
62
+
61
63
  if(this.currentComponent){
62
64
  this.getShadowRoot().removeChild(this.currentComponent);
63
65
 
@@ -1,6 +1,4 @@
1
- @import "../../../styles/includes.scss";
2
-
3
-
1
+ @import "@rws-mixins";
4
2
 
5
3
  .upload_area {
6
4
  padding: 25px;
@@ -1,16 +1,16 @@
1
1
  $mdWidth: 1120px;
2
2
 
3
3
  @function px-to-em($pixels, $base-font-size: 16) {
4
- @return #{calc($pixels / $base-font-size)}em;
5
- }
6
-
4
+ @return #{calc($pixels / $base-font-size)}em;
5
+ }
6
+
7
7
  // Mixin for the grid container
8
8
  @mixin grid-container {
9
- display: flex;
10
- flex-wrap: wrap;
11
- // gap: px-to-em(15);
12
- // margin-right: -#{px-to-em(15)}; // Adjust as needed
13
- // margin-left: -#{px-to-em(15)}; // Adjust as needed
9
+ display: flex;
10
+ flex-wrap: wrap;
11
+ // gap: px-to-em(15);
12
+ // margin-right: -#{px-to-em(15)}; // Adjust as needed
13
+ // margin-left: -#{px-to-em(15)}; // Adjust as needed
14
14
  }
15
15
 
16
16
  // Mixin for grid columns
@@ -23,80 +23,77 @@ $mdWidth: 1120px;
23
23
  }
24
24
 
25
25
  @mixin grid-column($columns: 12, $mdColumns: 12) {
26
- flex: 0 0 calc(100% / 12 * $columns);
27
- max-width: calc(100% / 12 * $columns);
28
- // padding-right: #{px-to-em(15)}; // Adjust as needed
29
- // padding-left: #{px-to-em(15)}; // Adjust as needed
30
-
31
- @media screen and (max-width: $mdWidth) {
32
- flex: 0 0 calc(100% / 12 * $mdColumns);
33
- max-width: calc(100% / 12 * $mdColumns);
34
- }
26
+ flex: 0 0 calc(100% / 12 * $columns);
27
+ max-width: calc(100% / 12 * $columns);
28
+ // padding-right: #{px-to-em(15)}; // Adjust as needed
29
+ // padding-left: #{px-to-em(15)}; // Adjust as needed
30
+
31
+ @media screen and (max-width: $mdWidth) {
32
+ flex: 0 0 calc(100% / 12 * $mdColumns);
33
+ max-width: calc(100% / 12 * $mdColumns);
34
+ }
35
35
  }
36
36
 
37
37
  @mixin grid-flex-self-align($alignment) {
38
- align-self: $alignment;
38
+ align-self: $alignment;
39
39
  }
40
40
 
41
41
  @mixin grid-flex-align-items($horizontal, $vertical: top) {
42
- justify-content: $horizontal;
43
- align-items: $vertical;
42
+ justify-content: $horizontal;
43
+ align-items: $vertical;
44
44
  }
45
45
 
46
46
  @mixin auto-left() {
47
- margin-left: auto;
47
+ margin-left: auto;
48
48
  }
49
49
 
50
50
  @mixin auto-right() {
51
- margin-right: auto;
51
+ margin-right: auto;
52
52
  }
53
53
 
54
54
  @mixin center-container() {
55
- margin-left: auto;
56
- margin-right: auto;
55
+ margin-left: auto;
56
+ margin-right: auto;
57
57
  }
58
58
 
59
59
  @mixin customScrollbars($width: 10px, $trackColor: #f1f1f1, $thumbColor: #888) {
60
- /* WebKit (Safari/Chrome) */
61
- &::-webkit-scrollbar {
62
- width: $width;
63
- }
64
-
65
- &::-webkit-scrollbar-track {
66
- background: $trackColor;
67
- }
68
-
69
- &::-webkit-scrollbar-thumb {
70
- background: $thumbColor;
71
- }
72
-
73
- /* Firefox */
74
- &::-moz-scrollbar {
75
- width: $width;
76
- }
77
-
78
- &::-moz-scrollbar-track {
79
- background: $trackColor;
80
- }
81
-
82
- &::-moz-scrollbar-thumb {
83
- background: $thumbColor;
84
- }
85
-
86
- /* IE/Edge */
87
- &::-ms-scrollbar {
88
- width: $width;
89
- }
90
-
91
- &::-ms-scrollbar-track {
92
- background: $trackColor;
93
- }
94
-
95
- &::-ms-scrollbar-thumb {
96
- background: $thumbColor;
97
- }
60
+
61
+ /* WebKit (Safari/Chrome) */
62
+ &::-webkit-scrollbar {
63
+ width: $width;
64
+ }
65
+
66
+ &::-webkit-scrollbar-track {
67
+ background: $trackColor;
68
+ }
69
+
70
+ &::-webkit-scrollbar-thumb {
71
+ background: $thumbColor;
72
+ }
73
+
74
+ /* Firefox */
75
+ &::-moz-scrollbar {
76
+ width: $width;
77
+ }
78
+
79
+ &::-moz-scrollbar-track {
80
+ background: $trackColor;
81
+ }
82
+
83
+ &::-moz-scrollbar-thumb {
84
+ background: $thumbColor;
85
+ }
86
+
87
+ /* IE/Edge */
88
+ &::-ms-scrollbar {
89
+ width: $width;
98
90
  }
99
91
 
100
- * {
101
- box-sizing: border-box;
92
+ &::-ms-scrollbar-track {
93
+ background: $trackColor;
94
+ }
95
+
96
+ &::-ms-scrollbar-thumb {
97
+ background: $thumbColor;
98
+ }
102
99
  }
@@ -4,13 +4,29 @@ const fs = require('fs');
4
4
  const ts = require('typescript');
5
5
  const tools = require('../../_tools');
6
6
 
7
-
8
7
  const _defaultRWSLoaderOptions = {
9
8
  templatePath: 'template.html',
10
9
  stylesPath: 'styles.scss',
11
10
  fastOptions: { shadowOptions: { mode: 'open' } }
12
11
  }
13
12
 
13
+ const ERROR_HANDLER_CODE = (htmlContent) => {
14
+ return `
15
+ async function handleError(error: Error | any) {
16
+ const errorMessage = \`RWS HTML Error:\n\${error.stack}\`;
17
+ console.error('RWS HTML error', errorMessage);
18
+ return T.html\`<div class="rws-error"><h1>RWS HTML template error</h1>\${errorMessage}</div>\`;
19
+ }
20
+
21
+ try {
22
+ //@ts-ignore
23
+ rwsTemplate = T.html\`${htmlContent}\`;
24
+ } catch (error: Error | any) {
25
+ rwsTemplate = handleError(error);
26
+ }
27
+ `;
28
+ };
29
+
14
30
  module.exports = async function(content) {
15
31
  let processedContent = content;
16
32
  const filePath = this.resourcePath;
@@ -59,7 +75,7 @@ module.exports = async function(content) {
59
75
  if(tagName){
60
76
 
61
77
  const lines = content.split('\n');
62
- const textToInsert = `static definition = { name: '${tagName}', template, styles${addedParams.length? ', ' + (addedParams.join(', ')) : ''} };`;
78
+ const textToInsert = `static definition = { name: '${tagName}', template: rwsTemplate, styles${addedParams.length? ', ' + (addedParams.join(', ')) : ''} };`;
63
79
 
64
80
  let modifiedContent = '';
65
81
  let insertIndex = -1;
@@ -94,14 +110,17 @@ module.exports = async function(content) {
94
110
  this.addDependency(templatePath);
95
111
 
96
112
  let htmlContent = fs.readFileSync(templatePath, 'utf-8');
113
+ const originalContent = htmlContent;
97
114
 
98
115
  if(!isDev){
99
116
  htmlContent = htmlContent.replace(/\n/g, '');
100
117
  }
101
118
 
102
- template = `import './${templateName}.html';
103
- //@ts-ignore
104
- const template: any = T.html\`${htmlContent}\`;`;
119
+ template = `import './${templateName}.html';
120
+ let rwsTemplate:any = null;
121
+
122
+ ${ERROR_HANDLER_CODE(originalContent)}
123
+ `;
105
124
  }
106
125
 
107
126
  processedContent = `import * as T from '@microsoft/fast-element';\n${template}\n${styles}\n${addedParamDefs.join('\n')}\n` + replaced;
@@ -3,6 +3,7 @@ const fs = require('fs');
3
3
  const path = require('path');
4
4
  const { getTokenSourceMapRange } = require('typescript');
5
5
  const _tools = require('../_tools');
6
+ const { rwsPath } = require('@rws-framework/console');
6
7
  const _COMPILE_DIR_NAME = 'compiled';
7
8
 
8
9
  const FONT_REGEX = /url\(['"]?(.+?\.(woff|woff2|eot|ttf|otf))['"]?\)/gm;
@@ -11,85 +12,89 @@ const SCSS_USE_REGEX = /@use\s+['"]?([^'"\s]+)['"]?;?/gm;
11
12
  const _DEV = true;
12
13
 
13
14
  const log = (args) => {
14
- if(_DEV){
15
+ if (_DEV) {
15
16
  console.log(args);
16
17
  }
17
18
  }
18
19
  class RWSScssPlugin {
19
20
  autoCompile = [];
20
21
 
21
- constructor(params){
22
+ constructor(params) {
22
23
  this.node_modules_dir = (fileDir) => path.relative(fileDir, _tools.findRootWorkspacePath(process.cwd())) + '/node_modules/'
23
-
24
- if(!params){
24
+
25
+ if (!params) {
25
26
  params = {};
26
27
  }
27
28
 
28
- if(!!params.autoCompile && params.autoCompile.length > 0){
29
+ if (!!params.autoCompile && params.autoCompile.length > 0) {
29
30
  this.autoCompile = params.autoCompile;
30
31
  }
31
32
 
32
- for (let index in this.autoCompile){
33
+ for (let index in this.autoCompile) {
33
34
  const sassFile = this.autoCompile[index];
34
35
  this.compileFile(sassFile, true);
35
36
  }
36
37
  }
37
38
 
38
- extractScssImports(fileContent) {
39
+ extractScssImports(fileContent, importRootPath) {
39
40
  let match;
40
41
  const imports = [];
41
-
42
- while ((match = CSS_IMPORT_REGEX.exec(fileContent)) !== null) {
42
+
43
+ while ((match = CSS_IMPORT_REGEX.exec(fileContent)) !== null) {
43
44
  const importPath = match[1];
44
45
  const importLine = match[0];
45
-
46
- imports.push([importPath, importLine]);
47
- }
48
-
46
+
47
+ if(fs.statSync(importRootPath).isFile()){
48
+ importRootPath = path.dirname(importRootPath);
49
+ }
50
+
51
+ imports.push([this.processImportPath(importPath, importRootPath), importLine]);
52
+ }
53
+
49
54
  return [imports, fileContent];
50
55
  }
51
56
 
52
- extractScssUses(fileContent) {
57
+ extractScssUses(fileContent) {
53
58
  let match;
54
59
  const uses = [];
55
-
56
- while ((match = SCSS_USE_REGEX.exec(fileContent)) !== null) {
60
+
61
+ while ((match = SCSS_USE_REGEX.exec(fileContent)) !== null) {
57
62
  const usesPath = match[1];
58
63
  const usesLine = match[0];
59
-
64
+
60
65
  uses.push([usesPath, usesLine]);
61
- }
62
-
66
+ }
67
+
63
68
  return [uses];
64
69
  }
65
70
 
66
- detectImports(code){
71
+ detectImports(code) {
67
72
  return CSS_IMPORT_REGEX.test(code);
68
73
  }
69
-
70
- writeCssFile(scssFilePath, cssContent) {
74
+
75
+ writeCssFile(scssFilePath, cssContent) {
71
76
  const cssFilePath = scssFilePath.replace('.scss', '.css');
72
77
  let endCssFilePath = cssFilePath.split('/');
73
78
  let endCssDir = [...endCssFilePath];
74
79
  endCssDir[endCssDir.length - 1] = `${_COMPILE_DIR_NAME}`;
75
80
  endCssDir = endCssDir.join('/');
76
-
81
+
77
82
  if (!fs.existsSync(endCssDir)) {
78
83
  fs.mkdirSync(endCssDir);
79
84
  }
80
-
85
+
81
86
  endCssFilePath[endCssFilePath.length - 1] = `${_COMPILE_DIR_NAME}/` + endCssFilePath[endCssFilePath.length - 1];
82
87
  endCssFilePath = endCssFilePath.join('/');
83
-
88
+
84
89
  fs.writeFileSync(endCssFilePath, cssContent);
85
- log('Saved CSS file: ' + endCssFilePath);
90
+ log('Saved CSS file: ' + endCssFilePath);
86
91
  }
87
92
 
88
- hasFontEmbeds(css){
93
+ hasFontEmbeds(css) {
89
94
  return FONT_REGEX.test()
90
95
  }
91
96
 
92
- embedFontsInCss(css, cssFilePath) {
97
+ embedFontsInCss(css, cssFilePath) {
93
98
  let match;
94
99
 
95
100
  while ((match = FONT_REGEX.exec(css)) !== null) {
@@ -126,16 +131,16 @@ class RWSScssPlugin {
126
131
  return;
127
132
  }
128
133
 
129
- readSCSSFilesFromDirectory(dirPath) {
134
+ readSCSSFilesFromDirectory(dirPath) {
130
135
  let scssFiles = [];
131
-
136
+
132
137
  try {
133
138
  const files = fs.readdirSync(dirPath);
134
-
139
+
135
140
  files.forEach(file => {
136
141
  const filePath = path.join(dirPath, file);
137
142
  const stat = fs.statSync(filePath);
138
-
143
+
139
144
  if (stat.isFile() && path.extname(file) === '.scss') {
140
145
  scssFiles.push(filePath);
141
146
  } else if (stat.isDirectory()) {
@@ -145,21 +150,25 @@ class RWSScssPlugin {
145
150
  } catch (e) {
146
151
  console.error(`Failed to read directory ${dirPath}:`, e);
147
152
  }
148
-
153
+
149
154
  return scssFiles;
150
155
  };
151
-
152
156
 
153
- getCodeFromFile(filePath){
154
- filePath = filePath.replace('//', '/');
155
-
156
- const fileStat = fs.statSync(filePath);
157
157
 
158
- if(!fs.existsSync(filePath)){
159
- throw new Error(`SCSS loader: File path "${filePath}" was not found.`);
158
+ getCodeFromFile(filePath) {
159
+ filePath = filePath.replace('//', '/');
160
+
161
+ if (!fs.existsSync(filePath)) {
162
+ const processedImportPath = this.processImportPath(filePath, path.dirname(filePath));
163
+
164
+ if (!fs.existsSync(processedImportPath)) {
165
+ throw new Error(`SCSS loader: File path "${filePath}" was not found.`);
166
+ }
167
+
168
+ filePath = processedImportPath;
160
169
  }
161
170
 
162
- if(filePath[filePath.length - 1] === '/' && fs.statSync(filePath).isDirectory()){
171
+ if (filePath[filePath.length - 1] === '/' && fs.statSync(filePath).isDirectory()) {
163
172
  let collectedCode = '';
164
173
 
165
174
  this.readSCSSFilesFromDirectory(filePath).forEach(scssPath => {
@@ -167,159 +176,214 @@ class RWSScssPlugin {
167
176
  });
168
177
 
169
178
  return collectedCode;
170
- }else if(fs.statSync(filePath).isDirectory()){
171
- throw new Error(`Non-directory path (not ending with "/") "${filePath}" is and should not be a directory`)
172
- }
179
+ } else if (fs.statSync(filePath).isDirectory()) {
180
+ throw new Error(`Non-directory path (not ending with "/") "${filePath}" is and should not be a directory`)
181
+ }
173
182
 
174
183
  return fs.readFileSync(filePath, 'utf-8');
175
184
  }
176
185
 
177
- replaceWithNodeModules(input, fileDir, absolute = false, token = '~'){
178
- return input.replace(token, absolute ? `${path.resolve(_tools.findRootWorkspacePath(process.cwd()), 'node_modules')}/` : this.node_modules_dir(fileDir));
186
+ replaceWithNodeModules(input, fileDir = null, absolute = false, token = '~') {
187
+ return input.replace(token, absolute ? `${path.resolve(_tools.findRootWorkspacePath(process.cwd()), 'node_modules')}/` : this.node_modules_dir(fileDir ? fileDir : process.cwd()));
179
188
  }
180
189
 
181
- compileFile(scssPath){
190
+ async compileFile(scssPath) {
182
191
  scssPath = this.processImportPath(scssPath, path.dirname(scssPath))
183
192
 
184
- let scssCode = this.getCodeFromFile(scssPath);
193
+ let scssCode = this.getCodeFromFile(scssPath);
185
194
 
186
- return this.compileScssCode(scssCode, path.dirname(scssPath));
195
+ return await this.compileScssCode(scssCode, path.dirname(scssPath));
187
196
  }
188
197
 
189
- processImports(imports, fileRootDir, importStorage = {}, sub = false){
198
+ processImports(imports, fileRootDir, importStorage = {}, sub = false) {
190
199
  const importResults = [];
191
200
 
192
201
  const getStorage = (sourceComponentPath, importedFileContent) => {
193
- const sourceComponentPathFormatted = sourceComponentPath.replace('/','_');
202
+ const sourceComponentPathFormatted = sourceComponentPath.replace('/', '_');
194
203
 
195
- if(!(sourceComponentPathFormatted in importStorage)){
204
+ if (!(sourceComponentPathFormatted in importStorage)) {
196
205
  importStorage[sourceComponentPathFormatted] = importedFileContent;
197
-
206
+
198
207
  return importedFileContent;
199
- }
208
+ }
200
209
 
201
210
  return '';
202
- }
211
+ }
203
212
 
204
- imports.forEach(importData => {
213
+ imports.forEach(importData => {
205
214
  const originalImportPath = importData[0];
206
- let importPath = this.processImportPath(originalImportPath, fileRootDir);
207
- let replacedScssContent = getStorage(importPath, this.getCodeFromFile(importPath).replace(/\/\*[\s\S]*?\*\//g, ''));
215
+ let importPath = this.processImportPath(originalImportPath, fileRootDir);
216
+ let replacedScssContent = getStorage(importPath, this.getCodeFromFile(importPath).replace(/\/\*[\s\S]*?\*\//g, ''));
217
+
218
+ const recursiveImports = this.extractScssImports(replacedScssContent, importPath)[0];
208
219
 
209
- const recursiveImports = this.extractScssImports(replacedScssContent)[0];
220
+ if (recursiveImports.length) {
221
+
222
+ replacedScssContent = this.replaceImports(this.processImports(recursiveImports, path.dirname(importPath), importStorage, true), replacedScssContent);
223
+ }
210
224
 
211
- if(recursiveImports.length){
212
-
213
- replacedScssContent = this.replaceImports(this.processImports(recursiveImports, path.dirname(importPath), importStorage, true), replacedScssContent);
214
- }
215
-
216
225
  importResults.push({
217
226
  line: importData[1],
218
227
  code: replacedScssContent
219
- });
220
- });
228
+ });
229
+ });
221
230
 
222
231
  return importResults;
223
232
  }
224
233
 
225
- replaceImports(processedImports, code){
226
- processedImports.forEach(importObj => {
234
+ replaceImports(processedImports, code) {
235
+ processedImports.forEach(importObj => {
227
236
  code = code.replace(importObj.line, importObj.code);
228
237
  });
229
-
238
+
230
239
  return code;
231
240
  }
232
241
 
233
- processImportPath(importPath, fileRootDir){
234
- const cwdRequest = importPath.indexOf('@cwd');
242
+ convertFontToBase64(fontPath) {
243
+ return fs.readFileSync(fontPath, { encoding: 'base64' });
244
+ }
245
+
246
+ replaceFontUrlWithBase64(cssContent) {
247
+ const urlRegex = /url\(([^)]+)\)/g;
248
+ let match;
249
+
250
+ const fontFaceRegex = /@font-face\s*\{[^}]*\}/g;
251
+ let fontFaces = [...cssContent.matchAll(fontFaceRegex)];
252
+
253
+ for(const fontFace of fontFaces){
254
+ const fontFaceContent = fontFace[0];
255
+ const urlRegex = /url\((['"]?)([^)'"]+)(\1)\)/g;
256
+ let match;
257
+
258
+ let modifiedFontFaceContent = fontFaceContent;
259
+
260
+ while ((match = urlRegex.exec(fontFaceContent)) !== null) {
261
+ // Create a promise to convert each font to Base64 and replace in CSS
262
+ const base64 = this.convertFontToBase64(this.processImportPath(match[2], null, true));
263
+ const base64Font = `data:font/woff2;base64,${base64}`;
264
+
265
+ modifiedFontFaceContent = modifiedFontFaceContent.replace(match[2], base64Font);
266
+ }
267
+
268
+ cssContent = cssContent.replace(fontFaceContent, modifiedFontFaceContent)
269
+ };
270
+
271
+ return cssContent;
272
+ }
235
273
 
236
- if(importPath.split('')[0] === '~'){
237
- return this.fillSCSSExt(this.replaceWithNodeModules(importPath, path.dirname(fileRootDir), true));
238
- } else if ( cwdRequest > -1){
239
- return this.fillSCSSExt(process.cwd() + '/' + importPath.slice(cwdRequest+4));
240
- }
274
+ processImportPath(importPath, fileRootDir = null, noext = false) {
275
+ if (importPath.split('')[0] === '~') {
276
+ return this.fillSCSSExt(this.replaceWithNodeModules(importPath, null, true), noext);
277
+ }
241
278
 
242
- if(importPath.split('')[0] === '/'){
243
- return this.fillSCSSExt(importPath);
279
+ if (importPath.indexOf('@rws-mixins') === 0) {
280
+ return path.resolve(rwsPath.findPackageDir(__dirname), 'src', 'styles', 'includes.scss');
244
281
  }
245
282
 
246
- if(importPath.split('')[0] === '.'){
247
- return this.fillSCSSExt(path.resolve(fileRootDir, importPath));
283
+ if (importPath.indexOf('@cwd') === 0) {
284
+ return this.fillSCSSExt(process.cwd() + '/' + importPath.slice(4), noext);
248
285
  }
249
286
 
250
- const relativized = path.resolve(fileRootDir) + '/' + importPath;
287
+ if (importPath.split('')[0] === '/') {
251
288
 
252
- if(!fs.existsSync(relativized)){
253
- const partSplit = relativized.split('/');
254
- partSplit[partSplit.length-1] = '_' + partSplit[partSplit.length-1] + '.scss';
289
+ return this.fillSCSSExt(importPath, noext);
290
+ }
255
291
 
256
- const newPath = partSplit.join('/');
292
+ if(fileRootDir){
293
+ const relativized = path.resolve(fileRootDir) + '/' + importPath;
257
294
 
258
- if(fs.existsSync(newPath)){
259
- return newPath;
260
- }
295
+ if (importPath.split('')[0] === '.') {
296
+ return this.fillSCSSExt(relativized, noext);
297
+ }
298
+
299
+ if (!fs.existsSync(relativized)) {
300
+ const partSplit = relativized.split('/');
301
+ partSplit[partSplit.length - 1] = '_' + partSplit[partSplit.length - 1] + '.scss';
302
+
303
+ const newPath = this.underscorePath(relativized);
304
+
305
+ if (fs.existsSync(newPath)) {
306
+ return newPath;
307
+ }
308
+ }
309
+ return this.fillSCSSExt(relativized, noext);
261
310
  }
262
311
 
263
- return this.fillSCSSExt(relativized);
312
+ return importPath;
264
313
  }
265
314
 
266
- fillSCSSExt(scssPath){
267
- if((!fs.existsSync(scssPath) || (fs.existsSync(scssPath) && fs.statSync(scssPath).isDirectory())) && fs.existsSync(`${scssPath}.scss`)){
268
- return `${scssPath}.scss`;
315
+ underscorePath(path, noext = false) {
316
+ const partSplit = path.split('/');
317
+ partSplit[partSplit.length - 1] = '_' + partSplit[partSplit.length - 1] + (path.indexOf('.scss') > - 1 || noext ? '' : '.scss');
318
+ return partSplit.join('/');
319
+ }
320
+
321
+ fillSCSSExt(scssPath, noext = false) {
322
+ const underscoredPath = this.underscorePath(scssPath, noext);
323
+ if (!fs.existsSync(scssPath) && fs.existsSync(underscoredPath)) {
324
+ return underscoredPath;
325
+ }
326
+
327
+ if(noext){
328
+ return scssPath;
269
329
  }
270
330
 
271
- if(fs.existsSync(`_${scssPath}.scss`)){
331
+ if ((!fs.existsSync(scssPath) || (fs.existsSync(scssPath) && fs.statSync(scssPath).isDirectory())) && fs.existsSync(`${scssPath}.scss`)) {
272
332
  return `${scssPath}.scss`;
273
333
  }
274
334
 
335
+ if (fs.existsSync(`_${scssPath}.scss`)) {
336
+ return `${scssPath}.scss`;
337
+ }
338
+
275
339
  return scssPath;
276
340
  }
277
341
 
278
- compileScssCode(scssCode, fileRootDir, createFile = false, filePath = null, minify = false){
279
- const _self = this;
280
- const [scssImports] = this.extractScssImports(scssCode);
342
+ compileScssCode(scssCode, fileRootDir, createFile = false, filePath = null, minify = false) {
343
+ const _self = this;
344
+ const [scssImports] = this.extractScssImports(scssCode, fileRootDir);
281
345
 
282
- if(scssImports && scssImports.length){
283
- scssCode = this.replaceImports(this.processImports(scssImports, fileRootDir), scssCode);
284
- }
346
+ if (scssImports && scssImports.length) {
347
+ scssCode = this.replaceImports(this.processImports(scssImports, fileRootDir), scssCode);
348
+ }
285
349
 
286
- const uses = this.extractScssUses(scssCode)[0];
287
- let scssUses = '';
288
-
350
+ const uses = this.extractScssUses(scssCode)[0];
351
+ let scssUses = '';
289
352
 
290
- uses.forEach(scssUse => {
291
- const useLine = scssUse[1];
292
- scssUses += useLine + '\n';
293
- scssCode = scssCode.replace(useLine, '');
294
- });
295
-
296
- scssCode = scssUses + scssCode;
297
353
 
298
- try {
354
+ uses.forEach(scssUse => {
355
+ const useLine = scssUse[1];
356
+ scssUses += useLine + '\n';
357
+ scssCode = scssCode.replace(useLine, '');
358
+ });
299
359
 
300
- const result = sass.compileString(scssCode, { loadPaths: [fileRootDir], style: minify ? 'compressed' : 'expanded' });
301
- let finalCss = result.css;
360
+ scssCode = scssUses + scssCode;
302
361
 
303
- return finalCss;
304
- } catch(err) {
305
- console.error('SASS Error in', fileRootDir);
306
-
307
- console.error(err);
308
- throw err;
309
- return '';
310
- };
362
+ try {
363
+
364
+ const result = sass.compileString(scssCode, { loadPaths: [fileRootDir], style: minify ? 'compressed' : 'expanded' });
365
+ let finalCss = result.css;
366
+
367
+ return this.replaceFontUrlWithBase64(finalCss);
368
+ } catch (err) {
369
+ console.error('SASS Error in', fileRootDir);
370
+
371
+ console.error(err);
372
+ throw err;
373
+ return '';
374
+ };
311
375
  }
312
376
 
313
- checkForImporterType(_module, checkTypeExt){
377
+ checkForImporterType(_module, checkTypeExt) {
314
378
  let importingFileExtension = '';
315
379
 
316
380
  if (_module && _module.issuer && _module.issuer.resource) {
317
- importingFileExtension = path.extname(_module.issuer.resource);
318
- if(importingFileExtension === ('.' + checkTypeExt)){
319
- return true;
320
- }
321
- }else{
322
- return false;
381
+ importingFileExtension = path.extname(_module.issuer.resource);
382
+ if (importingFileExtension === ('.' + checkTypeExt)) {
383
+ return true;
384
+ }
385
+ } else {
386
+ return false;
323
387
  }
324
388
 
325
389
  return false