Skip to content
Snippets Groups Projects
Verified Commit 073e3c19 authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

fix: monster.mjs

parent c590f994
No related branches found
No related tags found
No related merge requests found
Showing
with 1227 additions and 493 deletions
const regex = /^\s*(?<exp>(export\s+{[^}]+)})/gm; import {license, projectRoot, sourcePath} from "./import.mjs";
const fs = require('fs'); import {normalize,join} from "path";
const path = require('path') import {opendirSync,writeFileSync,readFileSync} from "fs";
const basename = __dirname + '/../../source/' import {extname, relative} from "path";
let exportLines = [] let exportLines = []
const regex = /^\s*(?<exp>(export\s+{[^}]+)})/gm;
function scanSymbols(root) { function scanSymbols(root) {
let f; let f;
const dir = fs.opendirSync(root); const dir = opendirSync(root);
while ((f = dir.readSync()) !== null) { while ((f = dir.readSync()) !== null) {
if (f.isDirectory()) { if (f.isDirectory()) {
scanSymbols(path.join(root, f.name)); scanSymbols(join(root, f.name));
continue; continue;
} else if (!f.isFile()) { } else if (!f.isFile()) {
continue; continue;
...@@ -21,38 +23,34 @@ function scanSymbols(root) { ...@@ -21,38 +23,34 @@ function scanSymbols(root) {
if(f.name==="monster.mjs") continue; if(f.name==="monster.mjs") continue;
if ((path.extname(f.name) !== ".mjs")) { if ((extname(f.name) !== ".mjs")) {
continue; continue;
} }
const fn = path.join(root, f.name); const fn = join(root, f.name);
let content = fs.readFileSync(fn, 'utf8'); let content = readFileSync(fn, 'utf8');
let m;
while ((m = regex.exec(content)) !== null) { while ((m = regex.exec(content)) !== null) {
let exp = m.groups?.exp; let exp = m.groups?.exp;
if (!exp) { if (!exp) {
continue; continue;
} }
exportLines.push("__PLACEHOLDER__" + " from \"./" + path.relative(basename, fn) + "\";"); exportLines.push("__PLACEHOLDER__" + " from \"./" + relative(sourcePath, fn) + "\";");
} }
} }
dir.closeSync();
} }
scanSymbols(path.normalize(basename)) scanSymbols(normalize(sourcePath))
const content = exportLines.join("\n"); const content = exportLines.join("\n");
const copyRightYear = new Date().getFullYear(); const copyRightYear = new Date().getFullYear();
const licenseText = license.replace("{{copyRightYear}}", copyRightYear);
let fileContent=` let fileContent=`${licenseText}
/**
* Copyright schukai GmbH and contributors ${copyRightYear}. All Rights Reserved.
* Node module: @schukai/monster
* This file is licensed under the AGPLv3 License.
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
* SPDX-License-Identifier: AGPL-3.0-only or COMMERCIAL
*/
/** THIS FILE IS AUTOGENERATED AND SHOULD NOT BE EDITED DIRECTLY. **/ // THIS FILE IS AUTOGENERATED. DO NOT EDIT THIS FILE DIRECTLY.
/** /**
* Main namespace for Monster. * Main namespace for Monster.
...@@ -67,7 +65,7 @@ export { Monster }; ...@@ -67,7 +65,7 @@ export { Monster };
/** /**
* This class has no other purpose than to exist. * This class has no other purpose than to exist.
* *
* @license AGPLv3 * @license AGPLv3 or commercial license
* @since 2.0.0 * @since 2.0.0
* @copyright schukai GmbH * @copyright schukai GmbH
* @memberOf Monster * @memberOf Monster
...@@ -77,5 +75,5 @@ class Monster {} ...@@ -77,5 +75,5 @@ class Monster {}
// write fileContent to file // write fileContent to file
fs.writeFileSync(basename + "monster.mjs", fileContent, 'utf8') writeFileSync(sourcePath + "/monster.mjs", fileContent, 'utf8')
import path from "path";
import {runPostCSS} from "./runPostCSS.mjs";
import {projectRoot,license} from "./import.mjs";
import {writeFileSync, existsSync, mkdirSync} from "fs";
const codeTemplate = `{{LicenseText}}
import {addAttributeToken} from "{{backToRootPath}}dom/attributes.mjs";
import {ATTRIBUTE_ERRORMESSAGE} from "{{backToRootPath}}dom/constants.mjs";
export {{{ClassName}}StyleSheet}
/**
* @private
* @type {CSSStyleSheet}
*/
const {{ClassName}}StyleSheet = new CSSStyleSheet();
try {
{{ClassName}}StyleSheet.insertRule(\`
@layer {{LayerName}} {
{{css}}
}\`, 0);
} catch (e) {
addAttributeToken(document.getRootNode().querySelector('html'), ATTRIBUTE_ERRORMESSAGE, e + "");
}
`;
/**
* @param {string} sourceFile
* @return {string} destinationFile
*/
export function createScriptFilenameFromStyleFilename(sourceFile) {
const parts = sourceFile.split('/');
const lastIndex = parts.lastIndexOf('style', parts.length - 2);
if (lastIndex !== -1) {
parts[lastIndex] = 'stylesheet';
}
const basename = path.basename(parts[parts.length - 1]);
const basenameParts = basename.split('.');
basenameParts[basenameParts.length - 1] = 'mjs';
parts[parts.length - 1] = basenameParts.join('.');
return parts.join('/');
}
/**
*
* @param {string} destinationFile
* @param {string} sourceFile
* @returns {Promise<>}
*/
export function buildCSS(sourceFile, destinationFile) {
return new Promise((resolve, reject) => {
return runPostCSS(sourceFile, destinationFile).then(result => {
if (result === undefined || result.css === undefined) {
reject("Error processing file " + sourceFile);
return;
}
let className = path.basename(destinationFile, path.extname(destinationFile));
className = className.charAt(0).toUpperCase() + className.slice(1);
className = className.replace(/-([a-z])/g, function (g) {
return g[1].toUpperCase();
});
let layerName = className.toLowerCase();
const styleSheetRoot = path.dirname(destinationFile);
let relPath=""
if (styleSheetRoot.includes("/development/source-files")) {
relPath = path.relative(styleSheetRoot, projectRoot + "/development/source-files") + "/";
} else {
relPath = path.relative(styleSheetRoot, projectRoot + "/source") + "/";
}
let css = result.css.replace(/"/g, '\\"');
const code = codeTemplate
.replaceAll("{{backToRootPath}}", relPath)
.replaceAll("{{copyRightYear}}", String(new Date().getFullYear()))
.replaceAll("{{ClassName}}", className)
.replaceAll("{{LayerName}}", layerName)
.replaceAll("{{LicenseText}}", license)
.replaceAll("{{css}}", css);
const destinationDirectory = path.dirname(destinationFile);
if (!existsSync(destinationDirectory)) {
mkdirSync(destinationDirectory, {recursive: true});
}
try {
writeFileSync(destinationFile, code);
} catch (e) {
reject("Error writing file " + destinationFile);
return;
}
resolve();
}).catch(reject);
})
}
import {buildCSS, createScriptFilenameFromStyleFilename} from "./buildStylePostCSS.mjs";
import {projectRoot} from "./import.mjs";
import {existsSync} from "fs";
// get arg 1 if the filename
const filename = process.argv[2];
if (!filename) {
console.error("No filename provided");
process.exit(1);
}
if (!filename.endsWith(".pcss")) {
console.error("Filename must end with .pcss");
process.exit(1);
}
if (existsSync(`${projectRoot}/dist`) === false) {
console.error("Creating dist directory");
process.exit(1);
}
buildCSS(filename, createScriptFilenameFromStyleFilename(filename)).then(() => {
}).catch((e) => {
console.error(e.message);
process.exit(1);
})
/nix/store/0ifm782v0x3snkb3gmahqrhvv0s5cvwz-import.mjs
\ No newline at end of file
import autoprefixer from "autoprefixer";
import cssnano from "cssnano";
import fs from "fs";
import path from "path";
import postcss from "postcss";
import postcssFluid from "postcss-fluid";
import postcssFor from "postcss-for";
import importCss from "postcss-import";
import postcssMixins from "postcss-mixins";
import postcssNesting from "postcss-nesting";
import normalizeCss from "postcss-normalize";
import postcssStripUnits from "postcss-strip-units";
import {projectRoot} from "./import.mjs";
/**
*
* @param sourceFile
* @param destinationFile
* @returns {Promise<>}
*/
export function runPostCSS(sourceFile, destinationFile) {
if (sourceFile === undefined || sourceFile === null || sourceFile === "") {
throw new Error("sourceFile is required");
}
if (!fs.existsSync(sourceFile)) {
throw new Error("File not found: " + sourceFile);
}
if (destinationFile === undefined || destinationFile === null || destinationFile === "") {
throw new Error("destinationFile is required");
}
const content = fs.readFileSync(sourceFile, 'utf8');
return postcss([
importCss({
path: destinationFile,
root: projectRoot,
resolve: (id, basedir, importOptions, astNode) => {
const firstTry = path.join(basedir, id);
if (fs.existsSync(firstTry)) {
return firstTry;
}
const dir = path.dirname(sourceFile);
const fn = path.join(dir, id);
console.log("Trying to resolve " + fn);
return fs.realpathSync(fn);
}
}),
normalizeCss,
postcssMixins,
postcssNesting(),
postcssFor(),
postcssStripUnits({
functionName: 'strip-units',
}),
postcssFluid({
min: '320px',
max: '1800px',
functionName: 'fluid',
}),
autoprefixer,
cssnano
]).process(content, {
from: sourceFile,
})
}
\ No newline at end of file
../source/
\ No newline at end of file
...@@ -14,12 +14,12 @@ import postcssFor from 'postcss-for'; ...@@ -14,12 +14,12 @@ import postcssFor from 'postcss-for';
import autoprefixer from 'autoprefixer'; import autoprefixer from 'autoprefixer';
import postcssMixins from 'postcss-mixins'; import postcssMixins from 'postcss-mixins';
import postcssResponsiveType from 'postcss-responsive-type'; import postcssResponsiveType from 'postcss-responsive-type';
import {ViteMinifyPlugin} from 'vite-plugin-minify' import {ViteMinifyPlugin} from 'vite-plugin-minify'
import {viteMockServe} from 'vite-plugin-mock'; import {viteMockServe} from 'vite-plugin-mock';
import directoryIndex from 'vite-plugin-directory-index'; import {buildCSS,createScriptFilenameFromStyleFilename} from './scripts/buildStylePostCSS.mjs';
import directoryIndex from 'vite-plugin-directory-index';
function getAppRootDir() { function getAppRootDir() {
let currentDir = __dirname let currentDir = __dirname
...@@ -32,7 +32,6 @@ function getAppRootDir() { ...@@ -32,7 +32,6 @@ function getAppRootDir() {
const rootDir = getAppRootDir() const rootDir = getAppRootDir()
const developmentDir = join(rootDir, 'development') const developmentDir = join(rootDir, 'development')
const buildStyleSheetScript = rootDir+"/opt/scripts/build-stylesheets.cjs";
export default defineConfig({ export default defineConfig({
clearScreen: false, clearScreen: false,
...@@ -56,24 +55,28 @@ export default defineConfig({ ...@@ -56,24 +55,28 @@ export default defineConfig({
ViteMinifyPlugin(), ViteMinifyPlugin(),
directoryIndex({}), directoryIndex({}),
viteMockServe({
mockPath: developmentDir + "/mock",
}),
{ {
name: 'postbuild-commands', name: 'run-script-on-pcss-change',
closeBundle: async () => { handleHotUpdate({file, server}) {
exec('node '+buildStyleSheetScript, (error, stdout, stderr) => {
if (error) { if (file.endsWith('.pcss')) {
console.error(`exec error: ${error}`);
return; const source = file;
const dest = createScriptFilenameFromStyleFilename(file);
buildCSS(source, dest).then(() => {
}).catch((e) => {
console.error(e.message);
})
} }
console.log(`stdout: ${stdout}`);
console.error(`stderr: ${stderr}`);
});
}, },
}, }
viteMockServe({
mockPath:developmentDir+ "/mock",
}),
], ],
......
...@@ -12,6 +12,35 @@ ...@@ -12,6 +12,35 @@
then pkgs.stdenv.system then pkgs.stdenv.system
else builtins.currentSystem; else builtins.currentSystem;
importJSScript = pkgs.writeTextFile {
name = "import.mjs";
text = ''
// THIS FILE IS AUTOGENERATED. DO NOT EDIT THIS FILE DIRECTLY.
export const projectRoot = "${config.devenv.root}";
export const sourcePath = "${config.devenv.root}/source";
export const developmentPath = "${config.devenv.root}/development";
export const pnpxBin = "${pkgs.nodePackages.pnpm}/bin/pnpx";
export const nodeBin = "${pkgs.nodejs_20}/bin/node";
export const license = "/**" +
" * Copyright © schukai GmbH and all contributing authors, {{copyRightYear}}. All rights reserved." + "\n" +
" * Node module: @schukai/monster" + "\n" +
" *" + "\n" +
" * This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3)." + "\n" +
" * The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html" + "\n" +
" *" + "\n" +
" * For those who do not wish to adhere to the AGPLv3, a commercial license is available." + "\n" +
" * Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms." + "\n" +
" * For more information about purchasing a commercial license, please contact schukai GmbH." + "\n" +
" */";
;
// THIS FILE IS AUTOGENERATED. DO NOT EDIT THIS FILE DIRECTLY.
'';
};
commonFunctionsScript = pkgs.writeScript "common-functions" '' commonFunctionsScript = pkgs.writeScript "common-functions" ''
...@@ -108,7 +137,6 @@ ...@@ -108,7 +137,6 @@
fi fi
''; '';
in { in {
env.APP_NAME = "monster"; env.APP_NAME = "monster";
env.dddd = "@schukai/monster"; env.dddd = "@schukai/monster";
...@@ -137,6 +165,7 @@ in { ...@@ -137,6 +165,7 @@ in {
gnused gnused
go-task go-task
gum gum
lightningcss
httpie httpie
hurl hurl
jq jq
...@@ -166,7 +195,6 @@ in { ...@@ -166,7 +195,6 @@ in {
}; };
}; };
difftastic.enable = false; difftastic.enable = false;
enterShell = '' enterShell = ''
...@@ -190,55 +218,110 @@ in { ...@@ -190,55 +218,110 @@ in {
${pkgs.git-chglog}/bin/git-chglog --config ${config.devenv.root}/.chglog/config.yml -o ${config.devenv.root}/CHANGELOG.md ${pkgs.git-chglog}/bin/git-chglog --config ${config.devenv.root}/.chglog/config.yml -o ${config.devenv.root}/CHANGELOG.md
''; '';
scripts.update-files.exec = ''
#!${pkgs.bash}/bin/bash
source ${commonFunctionsScript}
scripts.build-and-publish.exec = '' echo_section "Update files"
if [ -t 1 ]; then create_symlink() {
RED='\033[0;31m' if ${pkgs.coreutils}/bin/ln -s "$1" "$2" 2>/dev/null; then
GREEN='\033[0;32m' echo_ok "$2 created"
RESET='\033[0m'
BOLD='\033[1m'
else else
RED="" echo_fail "$2 already exists"
GREEN="" fi
RESET="" }
update_symlink() {
echo_section "Update $1"
local source_path="$1"
local target_path="$2"
local file_name="$(basename "$target_path")"
local source_dir="$(dirname "$source_path")"
${pkgs.coreutils}/bin/mkdir -p "$source_dir" || true
if [[ ! -d "$source_dir" ]]; then
echo_fail "$source_dir is not a directory. Please remove it manually and run the script again."
exit 1
fi fi
if [[ -L "$source_path" ]]; then
if [[ "$(readlink "$source_path")" != "$target_path" ]]; then
echo_step "Remove old symlink $file_name"
${pkgs.coreutils}/bin/rm "$source_path"
echo_step "Create new symlink $file_name"
create_symlink "$target_path" "$source_path"
echo_ok "$source_path updated$RESET"
else
echo_ok "$source_path is up to date$RESET"
fi
elif [[ -e "$source_path" ]]; then
echo_fail "$source_path already exists and is not a symlink. Please remove it manually and run the script again."
exit 1
else
create_symlink "$target_path" "$source_path"
echo_ok "$source_path created$RESET"
fi
}
update_symlink "${config.devenv.root}/development/scripts/import.mjs" "${importJSScript}"
'';
scripts.build-and-publish.exec = ''
#!${pkgs.bash}/bin/bash
source ${commonFunctionsScript}
echo_section "Build and publish"
echo_step "Update auto-generated files"
update-files
build-stylesheets
build-monster-file
echo_step "Check if git is clean"
if [[ -n "$(git status --porcelain)" ]]; then if [[ -n "$(git status --porcelain)" ]]; then
echo -e "''${RED}✖ Git is not clean. Exiting.''${RESET}" echo_fail "Git is not clean. Exiting."
echo -e " You must commit all changes before you can publish a new version." echo_hint "You must commit all changes before you can publish a new version."
exit 1 exit 1
fi fi
echo_step "Get next version"
NEXTVERSION="$(${inputs.version.defaultPackage."${builtins.currentSystem}"}/bin/version predict --git -0)" NEXTVERSION="$(${inputs.version.defaultPackage."${builtins.currentSystem}"}/bin/version predict --git -0)"
EXITCODE=$? EXITCODE=$?
if [ $EXITCODE -ne 0 ]; then if [ $EXITCODE -ne 0 ]; then
echo -e "''${RED}✖ No notable changes found. Exiting.''${RESET}" echo_fail "Version prediction failed. Exiting."
echo -e " Check this repository for changes. You must add a new commit with" echo_hint "You must add a new commit with feat: or fix: in the commit message to trigger a new version."
echo -e " feat: or fix: in the commit message to trigger a new version." echo_hint "You can also run the version script manually to see the error message."
exit 1 exit 1
fi fi
echo -e "''${GREEN}✔''${RESET} New version: $NEXTVERSION" echo_ok "New version: $NEXTVERSION"
echo_step "Update package.json and version.mjs"
LASTVERSION=$(cat "${config.devenv.root}/package.json" | jq -r '.version') LASTVERSION=$(cat "${config.devenv.root}/package.json" | jq -r '.version')
jq ".version = \"$NEXTVERSION\"" "${config.devenv.root}/package.json" | ${pkgs.moreutils}/bin/sponge "${config.devenv.root}/package.json" jq ".version = \"$NEXTVERSION\"" "${config.devenv.root}/package.json" | ${pkgs.moreutils}/bin/sponge "${config.devenv.root}/package.json"
update-versions update-versions
echo_ok "Package.json and version.mjs updated"
PROJECT_ROOT="${config.devenv.root}/" PROJECT_ROOT="${config.devenv.root}/"
TEST_PATH="${config.devenv.root}/test/" TEST_PATH="${config.devenv.root}/test/"
BUILD_PATH="${config.devenv.root}/dist/" BUILD_PATH="${config.devenv.root}/dist/"
if [ -d "$BUILD_PATH" ]; then if [ -d "$BUILD_PATH" ]; then
echo_step "Remove old build directory"
rm -rf "$BUILD_PATH" rm -rf "$BUILD_PATH"
fi fi
echo_step "Create new build directory"
mkdir -p "''${BUILD_PATH}" mkdir -p "''${BUILD_PATH}"
echo_step "Build changelog"
${pkgs.git-chglog}/bin/git-chglog --next-tag ''$NEXTVERSION --config "${config.devenv.root}/.chglog/config.yml" \ ${pkgs.git-chglog}/bin/git-chglog --next-tag ''$NEXTVERSION --config "${config.devenv.root}/.chglog/config.yml" \
-o "${config.devenv.root}/CHANGELOG.md" -o "${config.devenv.root}/CHANGELOG.md"
echo_step "Copy files to build directory"
${pkgs.rsync}/bin/rsync -a --exclude-from="${config.devenv.root}/.gitignore" "${config.devenv.root}/source" "''${BUILD_PATH}" ${pkgs.rsync}/bin/rsync -a --exclude-from="${config.devenv.root}/.gitignore" "${config.devenv.root}/source" "''${BUILD_PATH}"
${pkgs.rsync}/bin/rsync -a --exclude-from="${config.devenv.root}/.gitignore" "${config.devenv.root}/test" "''${BUILD_PATH}" ${pkgs.rsync}/bin/rsync -a --exclude-from="${config.devenv.root}/.gitignore" "${config.devenv.root}/test" "''${BUILD_PATH}"
${pkgs.rsync}/bin/rsync -a --exclude-from="${config.devenv.root}/.gitignore" "${config.devenv.root}/example" "''${BUILD_PATH}" ${pkgs.rsync}/bin/rsync -a --exclude-from="${config.devenv.root}/.gitignore" "${config.devenv.root}/example" "''${BUILD_PATH}"
...@@ -260,16 +343,22 @@ in { ...@@ -260,16 +343,22 @@ in {
cd ''${BUILD_PATH} || exit 1 cd ''${BUILD_PATH} || exit 1
echo_ok "Files copied to build directory"
OPTIONS="" OPTIONS=""
if [ ! -f "${config.devenv.root}/.npmrc" ]; then if [ ! -f "${config.devenv.root}/.npmrc" ]; then
echo -e "''${RED}✖ No .npmrc file found.''${RESET}" echo_fail "No .npmrc file found."
echo -e " If you want to publish to npm, you need to create a .npmrc file in the root of the project." echo_hint "You must create a .npmrc file in the root of the project to publish to npm."
echo -e " //registry.npmjs.org/:_authToken=$NPM_TOKEN" echo_hint "You can find the token in the npm account settings."
echo -e " You can find the token in the npm account settings." echo_hint "If you want to publish to npm, you need to create a .npmrc file in the root of the project."
echo -e "\n We run in dry-run mode now." echo_hint " //registry.npmjs.org/:_authToken=$NPM_TOKEN"
echo_hint "You can find the token in the npm account settings."
echo_step "We run in dry-run mode now."
OPTIONS="--dry-run --no-git-checks" OPTIONS="--dry-run --no-git-checks"
fi fi
echo_section "Publish to npm"
pnpm publish $OPTIONS --access public pnpm publish $OPTIONS --access public
exitcode=$? exitcode=$?
cd - || exit 1 cd - || exit 1
...@@ -279,20 +368,22 @@ in { ...@@ -279,20 +368,22 @@ in {
## reset to last version ## reset to last version
jq ".version = \"$LASTVERSION\"" "${config.devenv.root}/package.json" | ${pkgs.moreutils}/bin/sponge "${config.devenv.root}/package.json" jq ".version = \"$LASTVERSION\"" "${config.devenv.root}/package.json" | ${pkgs.moreutils}/bin/sponge "${config.devenv.root}/package.json"
update-versions update-versions
echo_fail "Publishing failed. Exiting."
echo -e "''${RED}✖ Publishing failed. Exiting.''${RESET}" echo_step "Reset to last version"
git reset --hard HEAD~1 git reset --hard HEAD~1
exit 1 exit 1
fi fi
git tag -a ''$NEXTVERSION -m "chore tag new version $NEXTVERSION" echo_step "Tag new version"
if ! git tag -a ''$NEXTVERSION -m "chore tag new version $NEXTVERSION"
echo -e "''${GREEN}✔''${RESET} Publishing successful." then
echo_fail "Tag creation failed. Exiting."
exit 1
fi
echo_ok "Tag created"
echo_ok "Publish successful"
''; '';
scripts.update-versions.exec = '' scripts.update-versions.exec = ''
VERSION=$(${pkgs.coreutils}/bin/cat "${config.devenv.root}/package.json" | jq -r '.version') VERSION=$(${pkgs.coreutils}/bin/cat "${config.devenv.root}/package.json" | jq -r '.version')
...@@ -415,7 +506,6 @@ EOF ...@@ -415,7 +506,6 @@ EOF
''; '';
scripts.create-polyfill.exec = '' scripts.create-polyfill.exec = ''
TMPFILE=${config.devenv.root}/.devenv/monster.js TMPFILE=${config.devenv.root}/.devenv/monster.js
...@@ -435,15 +525,30 @@ EOF ...@@ -435,15 +525,30 @@ EOF
''; '';
scripts.build-stylesheets.exec = '' scripts.build-stylesheets.exec = ''
#!${pkgs.bash}/bin/bash
components=$(${pkgs.coreutils}/bin/ls -d ${config.devenv.root}/source/components/*/ | \ TEST_PATH="${config.devenv.root}/test"
${pkgs.gnused}/bin/sed -E "s|${config.devenv.root}/source/||g" | \ TEST_CASES_PATH="''${TEST_PATH}/cases/"
${pkgs.gnused}/bin/sed -E "s|/$||g" | ${pkgs.gnugrep}/bin/grep -v style )
for component in $components; do
${pkgs.nodejs_20}/bin/node ${config.devenv.root}/opt/scripts/build-stylesheets.cjs ${config.devenv.root} --rel-path $component
done
${pkgs.nodejs_20}/bin/node ${config.devenv.root}/opt/scripts/build-stylesheets.cjs ${config.devenv.root} --rel-path "components/" source ${commonFunctionsScript}
echo_section "build stylesheets"
function build() {
source ${commonFunctionsScript}
local prefix="${config.devenv.root}/source/"
echo_step "build stylesheet ''${1#$prefix}"
${pkgs.nodejs_20}/bin/node ${config.devenv.root}/development/scripts/buildStylesheets.mjs "$1"
}
export -f build
if ! ${pkgs.fd}/bin/fd --absolute-path --full-path ${config.devenv.root}/source --type file --extension pcss -0 | xargs -0 -I {} bash -c 'build "$@"' _ {}; then
echo_fail "Stylesheet build failed. Exiting."
exit 1
fi
echo_ok "Stylesheet build successful"
''; '';
...@@ -500,11 +605,19 @@ EOF ...@@ -500,11 +605,19 @@ EOF
''; '';
scripts.build-monster-mjs.exec = '' scripts.build-monster-file.exec = ''
if ! $(${pkgs.nodejs_20}/bin/node ${config.devenv.root}/opt/scripts/build-exports.cjs) ; then #!${pkgs.bash}/bin/bash
echo "ERROR: build-exports failed, check your JS!" source ${commonFunctionsScript}
set -x
echo_section "build monster file"
if ! $(${pkgs.nodejs_20}/bin/node ${config.devenv.root}/development/scripts/buildMonsterFile.mjs)
then
echo "ERROR: script buildMonsterFile.mjs failed, check your JS!"
exit 1 exit 1
fi fi
echo_ok "Monster file created"
''; '';
scripts.run-web-tests.exec = '' scripts.run-web-tests.exec = ''
...@@ -515,8 +628,8 @@ EOF ...@@ -515,8 +628,8 @@ EOF
VERSION=$(cat "${config.devenv.root}/package.json" | jq -r '.version') VERSION=$(cat "${config.devenv.root}/package.json" | jq -r '.version')
update-versions update-versions
if ! build-monster-mjs ; then if ! build-monster-file ; then
echo "ERROR: build-monster-mjs failed, check your JS!" echo "ERROR: build-monster-file failed, check your JS!"
exit 1 exit 1
fi fi
create-polyfill create-polyfill
...@@ -548,7 +661,6 @@ EOF ...@@ -548,7 +661,6 @@ EOF
''; '';
scripts.publish-doc.exec = '' scripts.publish-doc.exec = ''
#!${pkgs.bash}/bin/bash #!${pkgs.bash}/bin/bash
...@@ -603,7 +715,7 @@ EOF ...@@ -603,7 +715,7 @@ EOF
''; '';
scripts.do-commit.exec = '' scripts.do-commit.exec = ''
#!/usr/bin/env bash #!${pkgs.bash}/bin/bash
# Define colors if the terminal supports it # Define colors if the terminal supports it
if [ -t 1 ]; then if [ -t 1 ]; then
......
const fs = require('fs'); // const fs = require('fs');
const os = require('os'); // const path = require('path');
const path = require('path'); // const args = process.argv.slice(2);
const postcss = require('postcss'); //
const cssnano = require('cssnano'); // if (args.length < 1) {
const normalizeCss = require('postcss-normalize'); // console.log("Usage: node build-stylesheets.js <project-root>");
const postcssFluid = require('postcss-fluid'); // process.exit(1);
const importCss = require('postcss-import'); // }
const postcssNesting = require('postcss-nesting'); //
const postcssFor = require('postcss-for'); // const projectRoot = args[0];
//const postcssRtlcss = require('postcss-rtlcss'); //
const autoprefixer = require('autoprefixer'); // if (!fs.existsSync(projectRoot)) {
const postcssMixins = require('postcss-mixins'); // console.log("Project root " + projectRoot + " does not exist");
const postcssStripUnits = require('postcss-strip-units'); // process.exit(1);
// }
const args = process.argv.slice(2); //
// let relPath = null;
if (args.length < 1) { // for (let i = 0; i < args.length; i++) {
console.log("Usage: node build-stylesheets.js <project-root>"); // if (args[i] === '--rel-path') {
process.exit(1); // relPath = args[i + 1];
} // }
// }
const projectRoot = args[0]; //
// if (relPath === null || relPath === undefined || relPath === "") {
if (!fs.existsSync(projectRoot)) { // console.error("Relativ path must be set");
console.log("Project root " + projectRoot + " does not exist"); // console.log("Usage: node build-stylesheets.js --relPath <relativ-path>");
process.exit(1); // process.exit(1);
} // }
//
let relPath = null; // if (relPath.substr(-1) !== '/') {
for (let i = 0; i < args.length; i++) { // relPath += '/';
if (args[i] === '--rel-path') { // }
relPath = args[i + 1]; //
} // if (relPath.substr(0, 1) === '/') {
} // console.error("Relativ path must not start with /");
// console.log("Usage: node build-stylesheets.js --relPath <relativ-path>");
if (relPath === null || relPath === undefined || relPath === "") { // process.exit(1);
console.error("Relativ path must be set"); // }
console.log("Usage: node build-stylesheets.js --relPath <relativ-path>"); //
process.exit(1); // // build rel, return path ../ to root
} // let backToRootPath = "";
// const parts = relPath.split("/");
if (relPath.substr(-1) !== '/') { // for (let i = 0; i < parts.length; i++) {
relPath += '/'; // backToRootPath += "../";
} // }
//
if (relPath.substr(0, 1) === '/') { // const absoluteProjectRoot = path.resolve(projectRoot) + "/";
console.error("Relativ path must not start with /"); // const absoluteSourcePath = absoluteProjectRoot + 'source/';
console.log("Usage: node build-stylesheets.js --relPath <relativ-path>"); // const styleSourceRoot = absoluteSourcePath + relPath + 'style/'
process.exit(1); // const styleSheetRoot = absoluteSourcePath + relPath + 'stylesheet/'
} // const nodeModuleStyleSourceRoot = absoluteProjectRoot + 'node_modules/'
//
// build rel, return path ../ to root // if (!fs.existsSync(styleSourceRoot)) {
let backToRootPath = ""; // console.log("Style source root " + styleSourceRoot + " does not exist");
const parts = relPath.split("/"); // process.exit(1);
for (let i = 0; i < parts.length; i++) { // }
backToRootPath += "../"; //
} // if (!fs.existsSync(nodeModuleStyleSourceRoot)) {
// console.log("Node module style source root " + nodeModuleStyleSourceRoot + " does not exist");
const absoluteProjectRoot = path.resolve(projectRoot) + "/"; // process.exit(1);
const absoluteSourcePath = absoluteProjectRoot + 'source/'; // }
const styleSourceRoot = absoluteSourcePath + relPath + 'style/' //
const styleSheetRoot = absoluteSourcePath + relPath + 'stylesheet/' // if (!fs.existsSync(styleSheetRoot)) {
const nodeModuleStyleSourceRoot = absoluteProjectRoot + 'node_modules/' // fs.mkdirSync(styleSheetRoot);
// }
if (!fs.existsSync(styleSourceRoot)) { //
console.log("Style source root " + styleSourceRoot + " does not exist"); // let promises = [];
process.exit(1); // let styles = new Map();
} //
//
if (!fs.existsSync(nodeModuleStyleSourceRoot)) { // export function buildScriptCSS(styleSheetRoot, styles) {
console.log("Node module style source root " + nodeModuleStyleSourceRoot + " does not exist"); // styles.forEach((css, fn) => {
process.exit(1); //
} // let className = path.parse(fn).name;
// className = className.charAt(0).toUpperCase() + className.slice(1);
if (!fs.existsSync(styleSheetRoot)) { // className = className.replace(/-([a-z])/g, function (g) {
fs.mkdirSync(styleSheetRoot); // return g[1].toUpperCase();
} // });
// let layerName = className.toLowerCase();
let promises = []; //
let styles = new Map(); // css = css.replace(/"/g, '\\"');
// const code = codeTemplate
const packageJsonPath = absoluteProjectRoot + 'package.json'; // .replaceAll("{{backToRootPath}}", path.relative(styleSheetRoot, projectRoot) + "/")
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); // .replaceAll("{{copyRightYear}}", new Date().getFullYear())
const copyRightYear = new Date().getFullYear(); // .replaceAll("{{ClassName}}", className)
// .replaceAll("{{LayerName}}", layerName)
const codeTemplate = ` // .replaceAll("{{css}}", css);
/** //
* Copyright schukai GmbH and contributors ${copyRightYear}. All Rights Reserved. // const targetFile = path.normalize(path.join(styleSheetRoot, fn));
* Node module: ${packageJson.name} // fs.mkdirSync(path.dirname(targetFile), {recursive: true});
* This file is licensed under the AGPLv3 License. // fs.writeFileSync(targetFile, code);
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html // })
*/ // }
//
import {addAttributeToken} from "` + backToRootPath + `dom/attributes.mjs"; //
import {ATTRIBUTE_ERRORMESSAGE} from "` + backToRootPath + `dom/constants.mjs"; // function scanFiles(root, keyPath) {
//
export {{{ClassName}}StyleSheet} // if (keyPath === undefined) {
// keyPath = [];
/** // }
* @private //
* @type {CSSStyleSheet} // return new Promise((resolve, reject) => {
*/ //
const {{ClassName}}StyleSheet = new CSSStyleSheet(); // let localPromises = [];
// let f;
try { //
{{ClassName}}StyleSheet.insertRule(\` // const dir = fs.opendirSync(root);
@layer {{LayerName}} { // while ((f = dir.readSync()) !== null) {
{{css}} //
}\`, 0); // const key = f.name;
} catch (e) { // const fn = path.join(root, f.name);
addAttributeToken(document.getRootNode().querySelector('html'), ATTRIBUTE_ERRORMESSAGE, e + ""); // const currentPath = [...keyPath]
} // currentPath.push(key);
`; //
// if (f.isDirectory()) {
//
function scanFiles(root, keyPath) { // if (["node_modules", "mixin"].includes(f.name)) {
// continue;
if (keyPath === undefined) { // }
keyPath = []; //
} // localPromises.push(scanFiles(fn, currentPath));
// continue;
return new Promise((resolve, reject) => { // } else if (!f.isFile()) {
// continue;
let localPromises = []; // }
let f; //
// if ((path.extname(f.name) !== ".css" && path.extname(f.name) !== ".pcss")) {
const dir = fs.opendirSync(root); // continue;
while ((f = dir.readSync()) !== null) { // }
//
const key = f.name; // //console.log("Found file: " + fn);
const fn = path.join(root, f.name); // let content = fs.readFileSync(fn, 'utf8');
const currentPath = [...keyPath] // localPromises.push(new Promise((resolve, reject) => {
currentPath.push(key); // (async () => {
// const {rewriteCSS} = await import('./rewriteCSS.mjs');
if (f.isDirectory()) { // resolve(rewriteCSS(styles, content, fn, currentPath, absoluteSourcePath, nodeModuleStyleSourceRoot, styleSourceRoot, absoluteProjectRoot));
//
if (["node_modules", "mixin"].includes(f.name)) { // })();
continue; // }));
} //
// }
localPromises.push(scanFiles(fn, currentPath)); //
continue; // dir.closeSync();
} else if (!f.isFile()) { //
continue; // Promise.all(localPromises).then(resolve).catch(reject);
} //
// })
if ((path.extname(f.name) !== ".css" && path.extname(f.name) !== ".pcss")) { // }
continue; //
} //
// scanFiles(path.normalize(styleSourceRoot)).then(() => {
//console.log("Found file: " + fn); //
let content = fs.readFileSync(fn, 'utf8'); // buildScriptCSS(styleSheetRoot, styles);
localPromises.push(rewriteCSS(content, fn, currentPath)); //
} // }).catch(e => {
// console.log("Error creating stylesheets");
dir.closeSync(); // console.error(e);
// })
Promise.all(localPromises).then(resolve).catch(reject);
})
}
function rewriteCSS(content, sourceFile, keyPath) {
const newPath = path.format({...path.parse(keyPath.join("/")), base: '', ext: '.mjs'})
return new Promise((resolve, reject) => {
return postcss([
importCss({
path: [absoluteSourcePath, nodeModuleStyleSourceRoot, styleSourceRoot],
root: absoluteProjectRoot,
resolve: (id, basedir, importOptions, astNode) => {
firstTry = path.join(basedir, id);
if (fs.existsSync(firstTry)) {
return firstTry;
}
const dir = path.dirname(sourceFile);
const fn = path.join(dir, id);
return fs.realpathSync(fn);
}
}),
normalizeCss,
postcssMixins,
postcssNesting(),
postcssFor(),
postcssStripUnits({
functionName: 'strip-units',
}),
postcssFluid({
// Defaults:
min: '320px', // Min media size
max: '1800px', // Max media size
functionName: 'fluid', // function name, may be anything
}), // https://github.com/notiv-nt/postcss-fluid
autoprefixer,
//postcssRtlcss,
cssnano
]).process(content, {
from: undefined,
}).catch((e) => {
reject(e + " in file " + sourceFile);
}).then(result => {
if (result === undefined || result.css === undefined) {
reject("Error processing file " + sourceFile);
return;
}
styles.set(newPath, result.css);
resolve();
}).catch((e) => {
console.error(e);
});
})
}
scanFiles(path.normalize(styleSourceRoot)).then(() => {
styles.forEach((css, fn) => {
let className = path.parse(fn).name;
className = className.charAt(0).toUpperCase() + className.slice(1);
className = className.replace(/-([a-z])/g, function (g) {
return g[1].toUpperCase();
});
let layerName = className.toLowerCase();
css = css.replace(/"/g, '\\"');
const code = codeTemplate
.replaceAll("{{ClassName}}", className)
.replaceAll("{{LayerName}}", layerName)
.replaceAll("{{css}}", css);
const targetFile = path.normalize(path.join(styleSheetRoot, fn));
fs.mkdirSync(path.dirname(targetFile), {recursive: true});
fs.writeFileSync(targetFile, code);
})
}).catch(e => {
console.log("Error creating stylesheets");
console.error(e);
})
This diff is collapsed.
/** /**
* Copyright schukai GmbH and contributors 2024. All Rights Reserved. * Copyright © schukai GmbH and all contributing authors, 2024. All rights reserved.
* Node module: @schukai/monster * Node module: @schukai/monster
* This file is licensed under the AGPLv3 License. *
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html * This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
*
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
* For more information about purchasing a commercial license, please contact schukai GmbH.
*/ */
import {addAttributeToken} from "../../../dom/attributes.mjs"; import {addAttributeToken} from "../../../dom/attributes.mjs";
import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs"; import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs";
......
/** /**
* Copyright schukai GmbH and contributors 2024. All Rights Reserved. * Copyright © schukai GmbH and all contributing authors, 2024. All rights reserved.
* Node module: @schukai/monster * Node module: @schukai/monster
* This file is licensed under the AGPLv3 License. *
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html * This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
*
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
* For more information about purchasing a commercial license, please contact schukai GmbH.
*/ */
import {addAttributeToken} from "../../../dom/attributes.mjs"; import {addAttributeToken} from "../../../dom/attributes.mjs";
import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs"; import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs";
......
/** /**
* Copyright schukai GmbH and contributors 2024. All Rights Reserved. * Copyright © schukai GmbH and all contributing authors, 2024. All rights reserved.
* Node module: @schukai/monster * Node module: @schukai/monster
* This file is licensed under the AGPLv3 License. *
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html * This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
*
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
* For more information about purchasing a commercial license, please contact schukai GmbH.
*/ */
import {addAttributeToken} from "../../../dom/attributes.mjs"; import {addAttributeToken} from "../../../dom/attributes.mjs";
import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs"; import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs";
......
/** /**
* Copyright schukai GmbH and contributors 2024. All Rights Reserved. * Copyright © schukai GmbH and all contributing authors, 2024. All rights reserved.
* Node module: @schukai/monster * Node module: @schukai/monster
* This file is licensed under the AGPLv3 License. *
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html * This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
*
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
* For more information about purchasing a commercial license, please contact schukai GmbH.
*/ */
import {addAttributeToken} from "../../../dom/attributes.mjs"; import {addAttributeToken} from "../../../dom/attributes.mjs";
import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs"; import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs";
......
/** /**
* Copyright schukai GmbH and contributors 2024. All Rights Reserved. * Copyright © schukai GmbH and all contributing authors, 2024. All rights reserved.
* Node module: @schukai/monster * Node module: @schukai/monster
* This file is licensed under the AGPLv3 License. *
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html * This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
*
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
* For more information about purchasing a commercial license, please contact schukai GmbH.
*/ */
import {addAttributeToken} from "../../../dom/attributes.mjs"; import {addAttributeToken} from "../../../dom/attributes.mjs";
import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs"; import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs";
......
/** /**
* Copyright schukai GmbH and contributors 2024. All Rights Reserved. * Copyright © schukai GmbH and all contributing authors, 2024. All rights reserved.
* Node module: @schukai/monster * Node module: @schukai/monster
* This file is licensed under the AGPLv3 License. *
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html * This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
*
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
* For more information about purchasing a commercial license, please contact schukai GmbH.
*/ */
import {addAttributeToken} from "../../../dom/attributes.mjs"; import {addAttributeToken} from "../../../dom/attributes.mjs";
import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs"; import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs";
......
/** /**
* Copyright schukai GmbH and contributors 2024. All Rights Reserved. * Copyright © schukai GmbH and all contributing authors, 2024. All rights reserved.
* Node module: @schukai/monster * Node module: @schukai/monster
* This file is licensed under the AGPLv3 License. *
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html * This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
*
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
* For more information about purchasing a commercial license, please contact schukai GmbH.
*/ */
import {addAttributeToken} from "../../../dom/attributes.mjs"; import {addAttributeToken} from "../../../dom/attributes.mjs";
import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs"; import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs";
......
/** /**
* Copyright schukai GmbH and contributors 2024. All Rights Reserved. * Copyright © schukai GmbH and all contributing authors, 2024. All rights reserved.
* Node module: @schukai/monster * Node module: @schukai/monster
* This file is licensed under the AGPLv3 License. *
* License text available at https://www.gnu.org/licenses/agpl-3.0.en.html * This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
* The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
*
* For those who do not wish to adhere to the AGPLv3, a commercial license is available.
* Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
* For more information about purchasing a commercial license, please contact schukai GmbH.
*/ */
import {addAttributeToken} from "../../../dom/attributes.mjs"; import {addAttributeToken} from "../../../dom/attributes.mjs";
import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs"; import {ATTRIBUTE_ERRORMESSAGE} from "../../../dom/constants.mjs";
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment