@rws-framework/client 2.6.4 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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.0",
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,7 @@ const RWSWebpackWrapper = (config) => {
220
220
  throw new Error('RWS Webpack build failed.');
221
221
  }
222
222
 
223
- const cfgExport = {
223
+ const cfgExport = {
224
224
  entry: {
225
225
  client: config.entry,
226
226
  ...automatedEntries
@@ -253,7 +253,7 @@ const RWSWebpackWrapper = (config) => {
253
253
  use: [
254
254
  'css-loader',
255
255
  ],
256
- },
256
+ },
257
257
  {
258
258
  test: /\.scss$/,
259
259
  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,85 @@ 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
+ imports.push([this.processImportPath(importPath, path.dirname(importRootPath)), importLine]);
48
+ }
49
+
49
50
  return [imports, fileContent];
50
51
  }
51
52
 
52
- extractScssUses(fileContent) {
53
+ extractScssUses(fileContent) {
53
54
  let match;
54
55
  const uses = [];
55
-
56
- while ((match = SCSS_USE_REGEX.exec(fileContent)) !== null) {
56
+
57
+ while ((match = SCSS_USE_REGEX.exec(fileContent)) !== null) {
57
58
  const usesPath = match[1];
58
59
  const usesLine = match[0];
59
-
60
+
60
61
  uses.push([usesPath, usesLine]);
61
- }
62
-
62
+ }
63
+
63
64
  return [uses];
64
65
  }
65
66
 
66
- detectImports(code){
67
+ detectImports(code) {
67
68
  return CSS_IMPORT_REGEX.test(code);
68
69
  }
69
-
70
- writeCssFile(scssFilePath, cssContent) {
70
+
71
+ writeCssFile(scssFilePath, cssContent) {
71
72
  const cssFilePath = scssFilePath.replace('.scss', '.css');
72
73
  let endCssFilePath = cssFilePath.split('/');
73
74
  let endCssDir = [...endCssFilePath];
74
75
  endCssDir[endCssDir.length - 1] = `${_COMPILE_DIR_NAME}`;
75
76
  endCssDir = endCssDir.join('/');
76
-
77
+
77
78
  if (!fs.existsSync(endCssDir)) {
78
79
  fs.mkdirSync(endCssDir);
79
80
  }
80
-
81
+
81
82
  endCssFilePath[endCssFilePath.length - 1] = `${_COMPILE_DIR_NAME}/` + endCssFilePath[endCssFilePath.length - 1];
82
83
  endCssFilePath = endCssFilePath.join('/');
83
-
84
+
84
85
  fs.writeFileSync(endCssFilePath, cssContent);
85
- log('Saved CSS file: ' + endCssFilePath);
86
+ log('Saved CSS file: ' + endCssFilePath);
86
87
  }
87
88
 
88
- hasFontEmbeds(css){
89
+ hasFontEmbeds(css) {
89
90
  return FONT_REGEX.test()
90
91
  }
91
92
 
92
- embedFontsInCss(css, cssFilePath) {
93
+ embedFontsInCss(css, cssFilePath) {
93
94
  let match;
94
95
 
95
96
  while ((match = FONT_REGEX.exec(css)) !== null) {
@@ -126,16 +127,16 @@ class RWSScssPlugin {
126
127
  return;
127
128
  }
128
129
 
129
- readSCSSFilesFromDirectory(dirPath) {
130
+ readSCSSFilesFromDirectory(dirPath) {
130
131
  let scssFiles = [];
131
-
132
+
132
133
  try {
133
134
  const files = fs.readdirSync(dirPath);
134
-
135
+
135
136
  files.forEach(file => {
136
137
  const filePath = path.join(dirPath, file);
137
138
  const stat = fs.statSync(filePath);
138
-
139
+
139
140
  if (stat.isFile() && path.extname(file) === '.scss') {
140
141
  scssFiles.push(filePath);
141
142
  } else if (stat.isDirectory()) {
@@ -145,21 +146,25 @@ class RWSScssPlugin {
145
146
  } catch (e) {
146
147
  console.error(`Failed to read directory ${dirPath}:`, e);
147
148
  }
148
-
149
+
149
150
  return scssFiles;
150
151
  };
151
-
152
152
 
153
- getCodeFromFile(filePath){
154
- filePath = filePath.replace('//', '/');
155
-
156
- const fileStat = fs.statSync(filePath);
157
153
 
158
- if(!fs.existsSync(filePath)){
159
- throw new Error(`SCSS loader: File path "${filePath}" was not found.`);
154
+ getCodeFromFile(filePath) {
155
+ filePath = filePath.replace('//', '/');
156
+
157
+ if (!fs.existsSync(filePath)) {
158
+ const processedImportPath = this.processImportPath(filePath, path.dirname(filePath));
159
+
160
+ if (!fs.existsSync(processedImportPath)) {
161
+ throw new Error(`SCSS loader: File path "${filePath}" was not found.`);
162
+ }
163
+
164
+ filePath = processedImportPath;
160
165
  }
161
166
 
162
- if(filePath[filePath.length - 1] === '/' && fs.statSync(filePath).isDirectory()){
167
+ if (filePath[filePath.length - 1] === '/' && fs.statSync(filePath).isDirectory()) {
163
168
  let collectedCode = '';
164
169
 
165
170
  this.readSCSSFilesFromDirectory(filePath).forEach(scssPath => {
@@ -167,159 +172,215 @@ class RWSScssPlugin {
167
172
  });
168
173
 
169
174
  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
- }
175
+ } else if (fs.statSync(filePath).isDirectory()) {
176
+ throw new Error(`Non-directory path (not ending with "/") "${filePath}" is and should not be a directory`)
177
+ }
173
178
 
174
179
  return fs.readFileSync(filePath, 'utf-8');
175
180
  }
176
181
 
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));
182
+ replaceWithNodeModules(input, fileDir = null, absolute = false, token = '~') {
183
+ return input.replace(token, absolute ? `${path.resolve(_tools.findRootWorkspacePath(process.cwd()), 'node_modules')}/` : this.node_modules_dir(fileDir ? fileDir : process.cwd()));
179
184
  }
180
185
 
181
- compileFile(scssPath){
186
+ async compileFile(scssPath) {
182
187
  scssPath = this.processImportPath(scssPath, path.dirname(scssPath))
183
188
 
184
- let scssCode = this.getCodeFromFile(scssPath);
189
+ let scssCode = this.getCodeFromFile(scssPath);
185
190
 
186
- return this.compileScssCode(scssCode, path.dirname(scssPath));
191
+ return await this.compileScssCode(scssCode, path.dirname(scssPath));
187
192
  }
188
193
 
189
- processImports(imports, fileRootDir, importStorage = {}, sub = false){
194
+ processImports(imports, fileRootDir, importStorage = {}, sub = false) {
190
195
  const importResults = [];
191
196
 
192
197
  const getStorage = (sourceComponentPath, importedFileContent) => {
193
- const sourceComponentPathFormatted = sourceComponentPath.replace('/','_');
198
+ const sourceComponentPathFormatted = sourceComponentPath.replace('/', '_');
194
199
 
195
- if(!(sourceComponentPathFormatted in importStorage)){
200
+ if (!(sourceComponentPathFormatted in importStorage)) {
196
201
  importStorage[sourceComponentPathFormatted] = importedFileContent;
197
-
202
+
198
203
  return importedFileContent;
199
- }
204
+ }
200
205
 
201
206
  return '';
202
- }
207
+ }
203
208
 
204
- imports.forEach(importData => {
209
+ imports.forEach(importData => {
205
210
  const originalImportPath = importData[0];
206
- let importPath = this.processImportPath(originalImportPath, fileRootDir);
207
- let replacedScssContent = getStorage(importPath, this.getCodeFromFile(importPath).replace(/\/\*[\s\S]*?\*\//g, ''));
211
+ let importPath = this.processImportPath(originalImportPath, fileRootDir);
208
212
 
209
- const recursiveImports = this.extractScssImports(replacedScssContent)[0];
213
+ let replacedScssContent = getStorage(importPath, this.getCodeFromFile(importPath).replace(/\/\*[\s\S]*?\*\//g, ''));
214
+
215
+ const recursiveImports = this.extractScssImports(replacedScssContent, importPath)[0];
216
+
217
+ if (recursiveImports.length) {
218
+
219
+ replacedScssContent = this.replaceImports(this.processImports(recursiveImports, path.dirname(importPath), importStorage, true), replacedScssContent);
220
+ }
210
221
 
211
- if(recursiveImports.length){
212
-
213
- replacedScssContent = this.replaceImports(this.processImports(recursiveImports, path.dirname(importPath), importStorage, true), replacedScssContent);
214
- }
215
-
216
222
  importResults.push({
217
223
  line: importData[1],
218
224
  code: replacedScssContent
219
- });
220
- });
225
+ });
226
+ });
221
227
 
222
228
  return importResults;
223
229
  }
224
230
 
225
- replaceImports(processedImports, code){
226
- processedImports.forEach(importObj => {
231
+ replaceImports(processedImports, code) {
232
+ processedImports.forEach(importObj => {
227
233
  code = code.replace(importObj.line, importObj.code);
228
234
  });
229
-
235
+
230
236
  return code;
231
237
  }
232
238
 
233
- processImportPath(importPath, fileRootDir){
234
- const cwdRequest = importPath.indexOf('@cwd');
239
+ convertFontToBase64(fontPath) {
240
+ return fs.readFileSync(fontPath, { encoding: 'base64' });
241
+ }
242
+
243
+ replaceFontUrlWithBase64(cssContent) {
244
+ const urlRegex = /url\(([^)]+)\)/g;
245
+ let match;
246
+
247
+ const fontFaceRegex = /@font-face\s*\{[^}]*\}/g;
248
+ let fontFaces = [...cssContent.matchAll(fontFaceRegex)];
249
+
250
+ for(const fontFace of fontFaces){
251
+ const fontFaceContent = fontFace[0];
252
+ const urlRegex = /url\((['"]?)([^)'"]+)(\1)\)/g;
253
+ let match;
254
+
255
+ let modifiedFontFaceContent = fontFaceContent;
256
+
257
+ while ((match = urlRegex.exec(fontFaceContent)) !== null) {
258
+ // Create a promise to convert each font to Base64 and replace in CSS
259
+ const base64 = this.convertFontToBase64(this.processImportPath(match[2], null, true));
260
+ const base64Font = `data:font/woff2;base64,${base64}`;
261
+
262
+ modifiedFontFaceContent = modifiedFontFaceContent.replace(match[2], base64Font);
263
+ }
264
+
265
+ cssContent = cssContent.replace(fontFaceContent, modifiedFontFaceContent)
266
+ };
267
+
268
+ return cssContent;
269
+ }
235
270
 
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
- }
271
+ processImportPath(importPath, fileRootDir = null, noext = false) {
272
+ if (importPath.split('')[0] === '~') {
273
+ return this.fillSCSSExt(this.replaceWithNodeModules(importPath, null, true), noext);
274
+ }
241
275
 
242
- if(importPath.split('')[0] === '/'){
243
- return this.fillSCSSExt(importPath);
276
+ if (importPath.indexOf('@rws-mixins') === 0) {
277
+ return path.resolve(rwsPath.findPackageDir(__dirname), 'src', 'styles', 'includes.scss');
244
278
  }
245
279
 
246
- if(importPath.split('')[0] === '.'){
247
- return this.fillSCSSExt(path.resolve(fileRootDir, importPath));
280
+ if (importPath.indexOf('@cwd') === 0) {
281
+ return this.fillSCSSExt(process.cwd() + '/' + importPath.slice(4), noext);
282
+ }
283
+
284
+ if (importPath.split('')[0] === '/') {
285
+
286
+ return this.fillSCSSExt(importPath, noext);
248
287
  }
249
288
 
250
- const relativized = path.resolve(fileRootDir) + '/' + importPath;
289
+ if(fileRootDir){
290
+ if (importPath.split('')[0] === '.') {
291
+ return this.fillSCSSExt(path.resolve(fileRootDir, importPath), noext);
292
+ }
293
+
294
+ const relativized = path.resolve(fileRootDir) + '/' + importPath;
251
295
 
252
- if(!fs.existsSync(relativized)){
253
- const partSplit = relativized.split('/');
254
- partSplit[partSplit.length-1] = '_' + partSplit[partSplit.length-1] + '.scss';
296
+ if (!fs.existsSync(relativized)) {
297
+ const partSplit = relativized.split('/');
298
+ partSplit[partSplit.length - 1] = '_' + partSplit[partSplit.length - 1] + '.scss';
255
299
 
256
- const newPath = partSplit.join('/');
300
+ const newPath = this.underscorePath(relativized);
257
301
 
258
- if(fs.existsSync(newPath)){
259
- return newPath;
260
- }
302
+ if (fs.existsSync(newPath)) {
303
+ return newPath;
304
+ }
305
+ }
306
+ return this.fillSCSSExt(relativized, noext);
261
307
  }
262
308
 
263
- return this.fillSCSSExt(relativized);
309
+ return importPath;
264
310
  }
265
311
 
266
- fillSCSSExt(scssPath){
267
- if((!fs.existsSync(scssPath) || (fs.existsSync(scssPath) && fs.statSync(scssPath).isDirectory())) && fs.existsSync(`${scssPath}.scss`)){
268
- return `${scssPath}.scss`;
312
+ underscorePath(path, noext = false) {
313
+ const partSplit = path.split('/');
314
+ partSplit[partSplit.length - 1] = '_' + partSplit[partSplit.length - 1] + (path.indexOf('.scss') > - 1 || noext ? '' : '.scss');
315
+ return partSplit.join('/');
316
+ }
317
+
318
+ fillSCSSExt(scssPath, noext = false) {
319
+ const underscoredPath = this.underscorePath(scssPath, noext);
320
+ if (!fs.existsSync(scssPath) && fs.existsSync(underscoredPath)) {
321
+ return underscoredPath;
269
322
  }
270
323
 
271
- if(fs.existsSync(`_${scssPath}.scss`)){
324
+ if(noext){
325
+ return scssPath;
326
+ }
327
+
328
+ if ((!fs.existsSync(scssPath) || (fs.existsSync(scssPath) && fs.statSync(scssPath).isDirectory())) && fs.existsSync(`${scssPath}.scss`)) {
272
329
  return `${scssPath}.scss`;
273
330
  }
274
331
 
332
+ if (fs.existsSync(`_${scssPath}.scss`)) {
333
+ return `${scssPath}.scss`;
334
+ }
335
+
275
336
  return scssPath;
276
337
  }
277
338
 
278
- compileScssCode(scssCode, fileRootDir, createFile = false, filePath = null, minify = false){
279
- const _self = this;
280
- const [scssImports] = this.extractScssImports(scssCode);
339
+ compileScssCode(scssCode, fileRootDir, createFile = false, filePath = null, minify = false) {
340
+ const _self = this;
341
+ const [scssImports] = this.extractScssImports(scssCode, fileRootDir);
281
342
 
282
- if(scssImports && scssImports.length){
283
- scssCode = this.replaceImports(this.processImports(scssImports, fileRootDir), scssCode);
284
- }
343
+ if (scssImports && scssImports.length) {
344
+ scssCode = this.replaceImports(this.processImports(scssImports, fileRootDir), scssCode);
345
+ }
285
346
 
286
- const uses = this.extractScssUses(scssCode)[0];
287
- let scssUses = '';
288
-
347
+ const uses = this.extractScssUses(scssCode)[0];
348
+ let scssUses = '';
289
349
 
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
350
 
298
- try {
351
+ uses.forEach(scssUse => {
352
+ const useLine = scssUse[1];
353
+ scssUses += useLine + '\n';
354
+ scssCode = scssCode.replace(useLine, '');
355
+ });
299
356
 
300
- const result = sass.compileString(scssCode, { loadPaths: [fileRootDir], style: minify ? 'compressed' : 'expanded' });
301
- let finalCss = result.css;
357
+ scssCode = scssUses + scssCode;
302
358
 
303
- return finalCss;
304
- } catch(err) {
305
- console.error('SASS Error in', fileRootDir);
306
-
307
- console.error(err);
308
- throw err;
309
- return '';
310
- };
359
+ try {
360
+
361
+ const result = sass.compileString(scssCode, { loadPaths: [fileRootDir], style: minify ? 'compressed' : 'expanded' });
362
+ let finalCss = result.css;
363
+
364
+ return this.replaceFontUrlWithBase64(finalCss);
365
+ } catch (err) {
366
+ console.error('SASS Error in', fileRootDir);
367
+
368
+ console.error(err);
369
+ throw err;
370
+ return '';
371
+ };
311
372
  }
312
373
 
313
- checkForImporterType(_module, checkTypeExt){
374
+ checkForImporterType(_module, checkTypeExt) {
314
375
  let importingFileExtension = '';
315
376
 
316
377
  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;
378
+ importingFileExtension = path.extname(_module.issuer.resource);
379
+ if (importingFileExtension === ('.' + checkTypeExt)) {
380
+ return true;
381
+ }
382
+ } else {
383
+ return false;
323
384
  }
324
385
 
325
386
  return false