@rws-framework/client
Version:
This package provides the core client-side framework for Realtime Web Suit (RWS), enabling modular, asynchronous web components, state management, and integration with backend services. It is located in `.dev/client`.
222 lines (158 loc) • 7.67 kB
JavaScript
const { rwsPath } = require('@rws-framework/console');
const chalk = require('chalk');
const _scss_fs_builder = require('./_fs');
let _scss_fs = null;
const fs = require('fs');
const path = require('path');
const CSS_IMPORT_REGEX = /^(?!.*\/\/)(?!.*\/\*).*@import\s+['"]((?![^'"]*:[^'"]*).+?)['"];?/gm;
const SCSS_USE_REGEX = /^(?!.*\/\/)(?!.*\/\*).*@use\s+['"]?([^'"\s]+)['"]?;?/gm;
function processImportPath(importPath, rwsWorkspaceDir, appRootDir, fileRootDir = null, noext = false, pubDir = null) {
_scss_fs = _scss_fs_builder(this);
const workspaceDir = this.getRWSWorkspaceDir ? this.getRWSWorkspaceDir() : rwsWorkspaceDir;
const appRoot = this.getRWSWorkspaceDir ? this.getRWSRootDir() : appRootDir;
if (importPath.split('')[0] === '~') {
return fillSCSSExt(replaceWithNodeModules(importPath, appRoot, null, true), noext);
}
if (importPath.indexOf('@rws-mixins') === 0) {
return path.resolve(rwsPath.findPackageDir(__dirname), 'src', 'styles', 'includes.scss');
}
if (importPath.indexOf('@workspace') === 0) {
return path.join(workspaceDir, 'src', importPath.replace('@workspace', ''));
}
if (importPath.indexOf('@public') === 0) {
return path.resolve(path.join(workspaceDir, pubDir, importPath.replace('@public', '')));
}
if (importPath.indexOf('@cwd') === 0) {
return fillSCSSExt(path.join(this.appRootDir, importPath.slice(4)), noext);
}
if (importPath.split('')[0] === '/' || importPath.split('')[1] === ':') {
const originalImport = fillSCSSExt(importPath, noext);
if(!fs.existsSync(originalImport)){
const absoluteImport = fillSCSSExt(path.join(workspaceDir, 'src', importPath), noext);
return absoluteImport;
}
return originalImport;
}
if (fileRootDir) {
const relativized = path.join(path.resolve(fileRootDir), importPath);
if (importPath.split('')[0] === '.') {
return fillSCSSExt(relativized, noext);
}
if (!fs.existsSync(relativized)) {
const partSplit = relativized.split(path.sep);
partSplit[partSplit.length - 1] = '_' + partSplit[partSplit.length - 1] + '.scss';
const newPath = underscorePath(relativized);
if (fs.existsSync(newPath)) {
return newPath;
}
}
return fillSCSSExt(relativized, noext);
}
return importPath;
}
function underscorePath(underPath, noext = false) {
const partSplit = underPath.split(path.sep);
const repl = (partSplit[partSplit.length - 1].split('')[0] !== '_' ? '_' : '') + partSplit[partSplit.length - 1];
partSplit[partSplit.length - 1] = repl + (underPath.indexOf('.scss') > - 1 || noext ? '' : '.scss');
return partSplit.join(path.sep);
}
function fillSCSSExt(scssPath, noext = false) {
const underscoredPath = underscorePath(scssPath, noext);
let ext = scssPath;
if (!fs.existsSync(scssPath) && fs.existsSync(underscoredPath)) {
ext = underscoredPath;
}
if (noext) {
ext = scssPath;
}
if ((!fs.existsSync(scssPath) || (fs.existsSync(scssPath) && fs.statSync(scssPath).isDirectory())) && fs.existsSync(`${scssPath}.scss`)) {
ext = `${scssPath}.scss`;
}
if (fs.existsSync(`_${scssPath}.scss`)) {
ext = `${scssPath}.scss`;
}
return ext;
}
function extractScssImports(fileContent, rwsWorkspaceDir, appRootDir, importRootPath, publicDir) {
_scss_fs = _scss_fs_builder(this);
let match;
const imports = [];
while ((match = CSS_IMPORT_REGEX.exec(fileContent)) !== null) {
const importPath = match[1];
const importLine = match[0];
if (fs.statSync(importRootPath).isFile()) {
importRootPath = path.dirname(importRootPath);
}
const processedImportPath = processImportPath(importPath, rwsWorkspaceDir, appRootDir, importRootPath, false, publicDir);
imports.push([processedImportPath, importLine, path.resolve(processedImportPath), rwsWorkspaceDir, appRootDir]);
}
return [imports, fileContent];
}
function extractScssUses(fileContent) {
_scss_fs = _scss_fs_builder(this);
let match;
const uses = [];
while ((match = SCSS_USE_REGEX.exec(fileContent)) !== null) {
const usesPath = match[1];
const usesLine = match[0];
if (!uses.find((item) => {
return item[0] == usesPath
}) && !usesPath !== 'sass:math') {
uses.push([usesPath, usesLine]);
}
}
return [uses];
}
function detectImports(code) {
return CSS_IMPORT_REGEX.test(code);
}
function replaceWithNodeModules(input, appRootDir, fileDir = null, absolute = false, token = '~') {
_scss_fs = _scss_fs_builder(this);
return input.replace(token, absolute ? `${path.join(appRootDir, 'node_modules')}${path.sep}` : this.node_modules_dir(fileDir ? fileDir : appRootDir));
}
function processImports(imports, fileRootDir, rwsWorkspaceDir, importStorage = {}, sub = false, pubDir = null) {
_scss_fs = _scss_fs_builder(this);
const importResults = [];
const getStorage = (sourceComponentPath, importedFileContent) => {
const sourceComponentPathFormatted = sourceComponentPath.replace(path.sep, '_');
if (!(sourceComponentPathFormatted in importStorage)) {
importStorage[sourceComponentPathFormatted] = importedFileContent;
return importedFileContent;
}
return '';
}
imports.forEach(importData => {
const originalImportPath = importData[0];
const workspaceDir = this.getRWSWorkspaceDir ? this.getRWSWorkspaceDir() : importData[3];
const appRoot = this.getRWSWorkspaceDir ? this.getRWSRootDir() : importData[4];
let importPath = processImportPath(originalImportPath, workspaceDir, appRoot, fileRootDir, false, pubDir);
// console.log({originalImportPath, importPath});
let replacedScssContent = getStorage(importPath, _scss_fs.getCodeFromFile(importPath, workspaceDir, appRoot, pubDir).replace(/\/\*[\s\S]*?\*\//g, ''));
const recursiveImports = extractScssImports(replacedScssContent, workspaceDir, appRoot, importPath, pubDir)[0];
if (recursiveImports.length) {
replacedScssContent = replaceImports(processImports(recursiveImports, path.dirname(importPath), workspaceDir, importStorage, true, pubDir), replacedScssContent);
}
importResults.push({
line: importData[1],
code: replacedScssContent
});
});
return importResults;
}
function replaceImports(processedImports, code) {
processedImports.forEach(importObj => {
code = code.replace(importObj.line, importObj.code);
});
return code;
}
module.exports = (element) => ({
processImportPath: processImportPath.bind(element),
fillSCSSExt: fillSCSSExt.bind(element),
underscorePath: underscorePath.bind(element),
detectImports: detectImports.bind(element),
extractScssUses: extractScssUses.bind(element),
extractScssImports: extractScssImports.bind(element),
replaceImports: replaceImports.bind(element),
processImports: processImports.bind(element),
replaceWithNodeModules: replaceWithNodeModules.bind(element)
});