@genexus/mercury 0.12.9 → 0.13.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.
- package/dist/bundles/css/all.css +1 -1
- package/dist/bundles/css/base/base.css +1 -1
- package/dist/bundles/css/base/icons.css +1 -1
- package/dist/bundles/css/chameleon/scrollbar.css +1 -1
- package/dist/bundles/css/components/accordion.css +1 -1
- package/dist/bundles/css/components/button.css +1 -1
- package/dist/bundles/css/components/chat.css +1 -1
- package/dist/bundles/css/components/checkbox.css +1 -1
- package/dist/bundles/css/components/code.css +1 -1
- package/dist/bundles/css/components/combo-box.css +1 -1
- package/dist/bundles/css/components/dialog.css +1 -1
- package/dist/bundles/css/components/dropdown.css +1 -1
- package/dist/bundles/css/components/edit.css +1 -1
- package/dist/bundles/css/components/flexible-layout.css +1 -1
- package/dist/bundles/css/components/icon.css +1 -1
- package/dist/bundles/css/components/layout-splitter.css +1 -1
- package/dist/bundles/css/components/list-box.css +1 -1
- package/dist/bundles/css/components/markdown-viewer.css +1 -1
- package/dist/bundles/css/components/navigation-list.css +1 -1
- package/dist/bundles/css/components/pills.css +1 -1
- package/dist/bundles/css/components/radio-group.css +1 -1
- package/dist/bundles/css/components/segmented-control.css +1 -1
- package/dist/bundles/css/components/sidebar.css +1 -1
- package/dist/bundles/css/components/slider.css +1 -1
- package/dist/bundles/css/components/switch.css +1 -1
- package/dist/bundles/css/components/tab.css +1 -1
- package/dist/bundles/css/components/tabular-grid.css +1 -1
- package/dist/bundles/css/components/ticket-list.css +1 -1
- package/dist/bundles/css/components/tooltip.css +1 -1
- package/dist/bundles/css/components/tree-view.css +1 -1
- package/dist/bundles/css/components/widget.css +1 -1
- package/dist/bundles/css/resets/box-sizing.css +1 -1
- package/dist/bundles/css/utils/elevation.css +1 -1
- package/dist/bundles/css/utils/form--full.css +1 -1
- package/dist/bundles/css/utils/form.css +1 -1
- package/dist/bundles/css/utils/layout.css +1 -1
- package/dist/bundles/css/utils/spacing.css +1 -1
- package/dist/bundles/css/utils/typography.css +1 -1
- package/dist/bundles/js/all.js +1 -0
- package/dist/bundles/js/base/base.js +1 -0
- package/dist/bundles/js/base/icons.js +1 -0
- package/dist/bundles/js/bundle-mappings.js +231 -0
- package/dist/bundles/js/chameleon/scrollbar.js +1 -0
- package/dist/bundles/js/components/accordion.js +1 -0
- package/dist/bundles/js/components/button.js +1 -0
- package/dist/bundles/js/components/chat.js +1 -0
- package/dist/bundles/js/components/checkbox.js +1 -0
- package/dist/bundles/js/components/code.js +1 -0
- package/dist/bundles/js/components/combo-box.js +1 -0
- package/dist/bundles/js/components/dialog.js +1 -0
- package/dist/bundles/js/components/dropdown.js +1 -0
- package/dist/bundles/js/components/edit.js +1 -0
- package/dist/bundles/js/components/flexible-layout.js +1 -0
- package/dist/bundles/js/components/icon.js +1 -0
- package/dist/bundles/js/components/layout-splitter.js +1 -0
- package/dist/bundles/js/components/list-box.js +1 -0
- package/dist/bundles/js/components/markdown-viewer.js +1 -0
- package/dist/bundles/js/components/navigation-list.js +1 -0
- package/dist/bundles/js/components/pills.js +1 -0
- package/dist/bundles/js/components/radio-group.js +1 -0
- package/dist/bundles/js/components/segmented-control.js +1 -0
- package/dist/bundles/js/components/sidebar.js +1 -0
- package/dist/bundles/js/components/slider.js +1 -0
- package/dist/bundles/js/components/switch.js +1 -0
- package/dist/bundles/js/components/tab.js +1 -0
- package/dist/bundles/js/components/tabular-grid.js +1 -0
- package/dist/bundles/js/components/ticket-list.js +1 -0
- package/dist/bundles/js/components/tooltip.js +1 -0
- package/dist/bundles/js/components/tree-view.js +1 -0
- package/dist/bundles/js/components/widget.js +1 -0
- package/dist/bundles/js/resets/box-sizing.js +1 -0
- package/dist/bundles/js/utils/elevation.js +1 -0
- package/dist/bundles/js/utils/form--full.js +1 -0
- package/dist/bundles/js/utils/form.js +1 -0
- package/dist/bundles/js/utils/layout.js +1 -0
- package/dist/bundles/js/utils/spacing.js +1 -0
- package/dist/bundles/js/utils/typography.js +1 -0
- package/dist/bundles.d.ts +153 -146
- package/dist/bundles.js +1 -1
- package/dist/cli/bundle.d.ts +2 -0
- package/dist/cli/bundle.js +20 -0
- package/dist/cli/internal/constants.d.ts +28 -0
- package/dist/cli/internal/constants.js +33 -0
- package/dist/cli/internal/create-bundles-with-custom-paths.d.ts +2 -0
- package/dist/cli/internal/create-bundles-with-custom-paths.js +67 -0
- package/dist/cli/internal/file-management.d.ts +4 -0
- package/dist/cli/internal/file-management.js +20 -0
- package/dist/cli/internal/print-utils.d.ts +18 -0
- package/dist/cli/internal/print-utils.js +33 -0
- package/dist/cli/internal/transpile-bundle-and-create-mappings.d.ts +3 -0
- package/dist/cli/internal/transpile-bundle-and-create-mappings.js +85 -0
- package/dist/cli/internal/types.d.ts +21 -0
- package/dist/cli/internal/types.js +1 -0
- package/dist/cli/internal/utils.d.ts +11 -0
- package/dist/cli/internal/utils.js +42 -0
- package/dist/cli/internal/validate-args.d.ts +2 -0
- package/dist/cli/internal/validate-args.js +119 -0
- package/dist/cli/mercury.d.ts +2 -0
- package/dist/cli/mercury.js +14 -0
- package/dist/mercury.scss +2 -0
- package/dist/types.d.ts +3 -0
- package/package.json +13 -3
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
// @ts-expect-error: This file does exists after the bundle transpilation process
|
|
4
|
+
import { bundleMappings } from "../../bundles/js/bundle-mappings.js";
|
|
5
|
+
import { BASE_BUNDLE, BASE_GLOBANT_BUNDLE, BUNDLE_MAPPING_TO_HASH_FILE } from "./constants.js";
|
|
6
|
+
import { getBundleNameWithHash, getHash, replacePlaceholdersInBundle } from "./utils.js";
|
|
7
|
+
import { printBundleToHashMappingsWasCreated, printBundleWasCreated } from "./print-utils.js";
|
|
8
|
+
const findLargestPath = () => {
|
|
9
|
+
let largestBundleLength = 0;
|
|
10
|
+
bundleMappings.forEach(entry => {
|
|
11
|
+
largestBundleLength = Math.max(largestBundleLength, entry.bundleName.length);
|
|
12
|
+
});
|
|
13
|
+
return largestBundleLength;
|
|
14
|
+
};
|
|
15
|
+
const getActualBundleName = (bundleName) => bundleName === BASE_BUNDLE || bundleName === BASE_GLOBANT_BUNDLE
|
|
16
|
+
? BASE_BUNDLE
|
|
17
|
+
: bundleName;
|
|
18
|
+
const shouldSkipBundleCreation = (bundleName, globant) => (bundleName === BASE_BUNDLE && globant) ||
|
|
19
|
+
(bundleName === BASE_GLOBANT_BUNDLE && !globant);
|
|
20
|
+
export const createBundlesWithCustomPaths = (args) => {
|
|
21
|
+
const { avoidHash, fontFacePath, iconsPath, globant } = args;
|
|
22
|
+
const outDir = path.join(args.outDirPath);
|
|
23
|
+
const CREATED_DIRS = new Set();
|
|
24
|
+
const largestBundleLength = findLargestPath();
|
|
25
|
+
let bundleMappingToHashObjectEntries = "";
|
|
26
|
+
bundleMappings.forEach(entry => {
|
|
27
|
+
const { bundleName, fileDir, transpiledBundle } = entry;
|
|
28
|
+
if (shouldSkipBundleCreation(bundleName, globant)) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const actualBundleName = getActualBundleName(bundleName);
|
|
32
|
+
const compiledBundleWithoutPlaceholders = replacePlaceholdersInBundle(transpiledBundle, fontFacePath, iconsPath);
|
|
33
|
+
const hash = getHash(compiledBundleWithoutPlaceholders);
|
|
34
|
+
if (fileDir && !CREATED_DIRS.has(fileDir)) {
|
|
35
|
+
fs.mkdirSync(path.join(outDir, fileDir), { recursive: true });
|
|
36
|
+
CREATED_DIRS.add(fileDir);
|
|
37
|
+
}
|
|
38
|
+
const bundleNameWithHash = avoidHash.has(actualBundleName)
|
|
39
|
+
? actualBundleName
|
|
40
|
+
: getBundleNameWithHash(actualBundleName, hash);
|
|
41
|
+
const filePathToCreateBundle = path.join(outDir, `${bundleNameWithHash}.css`);
|
|
42
|
+
fs.writeFileSync(filePathToCreateBundle, compiledBundleWithoutPlaceholders);
|
|
43
|
+
printBundleWasCreated({
|
|
44
|
+
outDir,
|
|
45
|
+
bundleName: actualBundleName,
|
|
46
|
+
compiledBundleWithoutPlaceholders,
|
|
47
|
+
filePathToCreateBundle,
|
|
48
|
+
// WA to improve style
|
|
49
|
+
largestBundleLength: largestBundleLength + (avoidHash.has(actualBundleName) ? 17 : 0)
|
|
50
|
+
});
|
|
51
|
+
// Store the bundle mapping.
|
|
52
|
+
// For example: "components/button" --> "components/button-9f82641938b85445"
|
|
53
|
+
const bundleToHashEntry = ` "${actualBundleName}": "${bundleNameWithHash}"`;
|
|
54
|
+
// Concat entries in the object
|
|
55
|
+
bundleMappingToHashObjectEntries +=
|
|
56
|
+
bundleMappingToHashObjectEntries === ""
|
|
57
|
+
? bundleToHashEntry
|
|
58
|
+
: ",\n" + bundleToHashEntry;
|
|
59
|
+
});
|
|
60
|
+
bundleMappingToHashObjectEntries = `export const bundleToHashMappings = {\n${bundleMappingToHashObjectEntries}\n} as const;\n`;
|
|
61
|
+
const bundleMappingFilePath = path.join(outDir, BUNDLE_MAPPING_TO_HASH_FILE);
|
|
62
|
+
fs.writeFileSync(bundleMappingFilePath, bundleMappingToHashObjectEntries);
|
|
63
|
+
printBundleToHashMappingsWasCreated({
|
|
64
|
+
outDir,
|
|
65
|
+
filePath: bundleMappingFilePath
|
|
66
|
+
});
|
|
67
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { FileMetadata } from "./types";
|
|
2
|
+
export declare const ensureDirectoryExistsAndItsClear: (dirPath: string) => void;
|
|
3
|
+
export declare function walkSync(dir: string): Generator<FileMetadata>;
|
|
4
|
+
export declare const copyDirectories: (srcDir: string, outDir: string) => void;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
export const ensureDirectoryExistsAndItsClear = (dirPath) => {
|
|
4
|
+
if (fs.existsSync(dirPath)) {
|
|
5
|
+
fs.rmSync(dirPath, { recursive: true });
|
|
6
|
+
}
|
|
7
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
8
|
+
};
|
|
9
|
+
export function* walkSync(dir) {
|
|
10
|
+
const files = fs.readdirSync(dir, { withFileTypes: true });
|
|
11
|
+
for (const file of files) {
|
|
12
|
+
if (file.isDirectory()) {
|
|
13
|
+
yield* walkSync(path.join(dir, file.name));
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
yield { dir, fileName: file.name, filePath: path.join(dir, file.name) };
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export const copyDirectories = (srcDir, outDir) => fs.cpSync(srcDir, outDir, { recursive: true });
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare const printBundleWasCreated: (args: {
|
|
2
|
+
outDir: string;
|
|
3
|
+
bundleName: string;
|
|
4
|
+
largestBundleLength: number;
|
|
5
|
+
filePathToCreateBundle: string;
|
|
6
|
+
compiledBundleWithoutPlaceholders: string;
|
|
7
|
+
}) => void;
|
|
8
|
+
export declare const printBundleToHashMappingsWasCreated: (args: {
|
|
9
|
+
outDir: string;
|
|
10
|
+
filePath: string;
|
|
11
|
+
}) => void;
|
|
12
|
+
export declare const printBundleWasTranspiled: (filePath: string) => void;
|
|
13
|
+
export declare const printArgumentDoesNotExistsError: (arg: string) => void;
|
|
14
|
+
export declare const printDuplicatedArgumentError: (arg: string) => void;
|
|
15
|
+
export declare const printInvalidArgumentError: (arg: string) => void;
|
|
16
|
+
export declare const printMissingFontPathArgumentWarning: () => void;
|
|
17
|
+
export declare const printMissingIconsPathArgumentWarning: () => void;
|
|
18
|
+
export declare const printMissingOutDirPathArgumentWarning: () => void;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { styleText } from "node:util";
|
|
2
|
+
import { getFileSize } from "./utils.js";
|
|
3
|
+
import { DEFAULT_FONT_FACE_PATH, DEFAULT_ICONS_PATH, DEFAULT_OUT_DIR_PATH, SCSS_BUNDLES_OUT_DIR } from "./constants.js";
|
|
4
|
+
export const printBundleWasCreated = (args) => console.log(styleText("greenBright", " Created: ") +
|
|
5
|
+
styleText("white", args.outDir) +
|
|
6
|
+
styleText("whiteBright", args.filePathToCreateBundle.replace(args.outDir, "")) +
|
|
7
|
+
styleText("cyan", " ".repeat(1 + args.largestBundleLength - args.bundleName.length) +
|
|
8
|
+
getFileSize(args.compiledBundleWithoutPlaceholders)));
|
|
9
|
+
export const printBundleToHashMappingsWasCreated = (args) => console.log("\n" +
|
|
10
|
+
styleText("greenBright", " Created: ") +
|
|
11
|
+
styleText("white", args.outDir) +
|
|
12
|
+
styleText("whiteBright", args.filePath.replace(args.outDir, "")));
|
|
13
|
+
export const printBundleWasTranspiled = (filePath) => console.log(styleText("greenBright", " Transpiled: ") +
|
|
14
|
+
styleText("white", SCSS_BUNDLES_OUT_DIR) +
|
|
15
|
+
styleText("whiteBright", filePath.replace(SCSS_BUNDLES_OUT_DIR, "")));
|
|
16
|
+
export const printArgumentDoesNotExistsError = (arg) => console.log(styleText("red", " error ") +
|
|
17
|
+
styleText("gray", "Argument does not exists: ") +
|
|
18
|
+
`'${arg}'`);
|
|
19
|
+
export const printDuplicatedArgumentError = (arg) => console.log(styleText("red", " error ") +
|
|
20
|
+
styleText("gray", "Duplicated argument type: ") +
|
|
21
|
+
`'${arg}'`);
|
|
22
|
+
export const printInvalidArgumentError = (arg) => console.log(styleText("red", " error ") +
|
|
23
|
+
styleText("gray", "Invalid argument: ") +
|
|
24
|
+
`'${arg}'`);
|
|
25
|
+
export const printMissingFontPathArgumentWarning = () => console.log(styleText("yellow", " [warning]: Missing --font-face-path argument. The path ") +
|
|
26
|
+
styleText("cyan", `'${DEFAULT_FONT_FACE_PATH}'`) +
|
|
27
|
+
styleText("yellow", " will be used as default."));
|
|
28
|
+
export const printMissingIconsPathArgumentWarning = () => console.log(styleText("yellow", " [warning]: Missing --icons-path argument. The path ") +
|
|
29
|
+
styleText("cyan", `'${DEFAULT_ICONS_PATH}'`) +
|
|
30
|
+
styleText("yellow", " will be used as default."));
|
|
31
|
+
export const printMissingOutDirPathArgumentWarning = () => console.log(styleText("yellow", " [warning]: Missing --outDir argument. The path ") +
|
|
32
|
+
styleText("cyan", `'${DEFAULT_OUT_DIR_PATH}'`) +
|
|
33
|
+
styleText("yellow", " will be used as default."));
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import * as sass from "sass";
|
|
4
|
+
import { BASE_BUNDLE_WITH_BACK_SLASH, BASE_GLOBANT_CSS_FILE, BASE_GLOBANT_FILE, BASE_GLOBANT_JS_FILE, BASE_GLOBANT_SCSS_FILE, BASE_SCSS_FILE, BUNDLE_MAPPING_ENTRIES, BUNDLE_MAPPING_FILE, CSS_BUNDLES_OUT_DIR, DEFAULT_FONT_FACE_PATH, DEFAULT_ICONS_PATH, JS_BUNDLES_OUT_DIR, SCSS_BUNDLES_OUT_DIR } from "./constants.js";
|
|
5
|
+
import { getBundleNameWithoutSpecialChars, replacePlaceholdersInBundle } from "./utils.js";
|
|
6
|
+
import { printBundleWasTranspiled } from "./print-utils.js";
|
|
7
|
+
const transpileBundle = (filePath, globant) => sass.compile(filePath, {
|
|
8
|
+
loadPaths: [globant ? "src/config/globant" : "src/config/default"],
|
|
9
|
+
style: "compressed"
|
|
10
|
+
}).css;
|
|
11
|
+
const CSS_CREATED_DIRS = new Set();
|
|
12
|
+
const JS_CREATED_DIRS = new Set();
|
|
13
|
+
const BUNDLES = [];
|
|
14
|
+
const addBaseGlobantFile = (fileMetadata, cssOutDir, jsOutDir) => {
|
|
15
|
+
const { filePath } = fileMetadata;
|
|
16
|
+
BUNDLES.push({
|
|
17
|
+
fileDir: fileMetadata.dir
|
|
18
|
+
.replace(SCSS_BUNDLES_OUT_DIR, "")
|
|
19
|
+
.replace("\\", "/"),
|
|
20
|
+
bundleNameWithBackSlash: filePath
|
|
21
|
+
.replace(SCSS_BUNDLES_OUT_DIR, "")
|
|
22
|
+
.replace(BASE_SCSS_FILE, BASE_GLOBANT_FILE)
|
|
23
|
+
});
|
|
24
|
+
const transpiledBundle = transpileBundle(filePath, true);
|
|
25
|
+
// Store the CSS file with its default values
|
|
26
|
+
fs.writeFileSync(path.join(cssOutDir, BASE_GLOBANT_CSS_FILE), replacePlaceholdersInBundle(transpiledBundle, DEFAULT_FONT_FACE_PATH, DEFAULT_ICONS_PATH));
|
|
27
|
+
// Store the CSS file in a JS file with placeholders for the values
|
|
28
|
+
fs.writeFileSync(path.join(jsOutDir, BASE_GLOBANT_JS_FILE), `export const bundle = \`${transpiledBundle}\`;`);
|
|
29
|
+
printBundleWasTranspiled(filePath.replace(BASE_SCSS_FILE, BASE_GLOBANT_SCSS_FILE));
|
|
30
|
+
};
|
|
31
|
+
export const transpileCssBundleWithPlaceholder = (fileMetadata) => {
|
|
32
|
+
const { fileName, filePath } = fileMetadata;
|
|
33
|
+
const cssOutDir = fileMetadata.dir.replace(SCSS_BUNDLES_OUT_DIR, CSS_BUNDLES_OUT_DIR);
|
|
34
|
+
const jsOutDir = fileMetadata.dir.replace(SCSS_BUNDLES_OUT_DIR, JS_BUNDLES_OUT_DIR);
|
|
35
|
+
const fileNameCssExt = fileName.replace(".scss", ".css");
|
|
36
|
+
const fileNameJsExt = fileName.replace(".scss", ".js");
|
|
37
|
+
const bundleNameWithBackSlash = filePath
|
|
38
|
+
.replace(SCSS_BUNDLES_OUT_DIR, "")
|
|
39
|
+
.replace(".scss", "");
|
|
40
|
+
BUNDLES.push({
|
|
41
|
+
fileDir: fileMetadata.dir
|
|
42
|
+
.replace(SCSS_BUNDLES_OUT_DIR, "")
|
|
43
|
+
.replace("\\", "/"),
|
|
44
|
+
bundleNameWithBackSlash
|
|
45
|
+
});
|
|
46
|
+
// Create the file directory if it does not exists
|
|
47
|
+
if (!CSS_CREATED_DIRS.has(cssOutDir)) {
|
|
48
|
+
fs.mkdirSync(cssOutDir, { recursive: true });
|
|
49
|
+
fs.mkdirSync(jsOutDir, { recursive: true });
|
|
50
|
+
CSS_CREATED_DIRS.add(cssOutDir);
|
|
51
|
+
JS_CREATED_DIRS.add(jsOutDir);
|
|
52
|
+
}
|
|
53
|
+
const transpiledBundle = transpileBundle(filePath, false);
|
|
54
|
+
// Store the CSS file with its default values
|
|
55
|
+
fs.writeFileSync(path.join(cssOutDir, fileNameCssExt), replacePlaceholdersInBundle(transpiledBundle, DEFAULT_FONT_FACE_PATH, DEFAULT_ICONS_PATH));
|
|
56
|
+
// Store the CSS file in a JS file with placeholders for the values
|
|
57
|
+
fs.writeFileSync(path.join(jsOutDir, fileNameJsExt), `export const bundle = \`${transpiledBundle}\`;`);
|
|
58
|
+
printBundleWasTranspiled(filePath);
|
|
59
|
+
if (bundleNameWithBackSlash === BASE_BUNDLE_WITH_BACK_SLASH) {
|
|
60
|
+
addBaseGlobantFile(fileMetadata, cssOutDir, jsOutDir);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
const createBundleEntryInMappingFile = (bundleName, fileDir, transpiledBundleRef) => ` {
|
|
64
|
+
${BUNDLE_MAPPING_ENTRIES.BUNDLE_NAME}: "${bundleName}",
|
|
65
|
+
${BUNDLE_MAPPING_ENTRIES.FILE_DIR}: "${fileDir}",
|
|
66
|
+
${BUNDLE_MAPPING_ENTRIES.TRANSPILED_BUNDLE}: ${transpiledBundleRef}
|
|
67
|
+
}`;
|
|
68
|
+
export const createBundleMappingsFile = () => {
|
|
69
|
+
let bundleAssociationImports = "";
|
|
70
|
+
let bundleMappingObjectEntries = "";
|
|
71
|
+
BUNDLES.forEach(bundleMetadata => {
|
|
72
|
+
const bundleName = bundleMetadata.bundleNameWithBackSlash
|
|
73
|
+
.replaceAll("\\", "/")
|
|
74
|
+
.substring(1);
|
|
75
|
+
const transpiledBundleRef = getBundleNameWithoutSpecialChars(bundleName);
|
|
76
|
+
const bundleEntry = createBundleEntryInMappingFile(bundleName, bundleMetadata.fileDir, transpiledBundleRef);
|
|
77
|
+
bundleAssociationImports += `import { bundle as ${transpiledBundleRef} } from "./${bundleName}.js";\n`;
|
|
78
|
+
// Concat entries in the object
|
|
79
|
+
bundleMappingObjectEntries +=
|
|
80
|
+
bundleMappingObjectEntries === "" ? bundleEntry : ",\n" + bundleEntry;
|
|
81
|
+
});
|
|
82
|
+
bundleMappingObjectEntries = `\nexport const bundleMappings = [\n${bundleMappingObjectEntries}\n];`;
|
|
83
|
+
// Create the JS file that contains all mappings for the bundle
|
|
84
|
+
fs.writeFileSync(path.join(JS_BUNDLES_OUT_DIR, BUNDLE_MAPPING_FILE), bundleAssociationImports + bundleMappingObjectEntries);
|
|
85
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export type BundleMetadata = {
|
|
2
|
+
fileDir: string;
|
|
3
|
+
bundleNameWithBackSlash: string;
|
|
4
|
+
};
|
|
5
|
+
export type BundleAssociationMetadata = {
|
|
6
|
+
bundleName: string;
|
|
7
|
+
fileDir: string;
|
|
8
|
+
transpiledBundle: string;
|
|
9
|
+
};
|
|
10
|
+
export type FileMetadata = {
|
|
11
|
+
dir: string;
|
|
12
|
+
fileName: string;
|
|
13
|
+
filePath: string;
|
|
14
|
+
};
|
|
15
|
+
export type CLIArguments = {
|
|
16
|
+
avoidHash: Set<string>;
|
|
17
|
+
globant: boolean;
|
|
18
|
+
iconsPath: string;
|
|
19
|
+
fontFacePath: string;
|
|
20
|
+
outDirPath: string;
|
|
21
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const getFileSize: (fileContent: string) => string;
|
|
2
|
+
export declare const getHash: (fileContent: string) => string;
|
|
3
|
+
export declare const getBundleNameWithHash: <B extends string, H extends string>(bundleName: B, hash: H) => `${B}-${H}`;
|
|
4
|
+
export declare const replacePlaceholdersInBundle: (transpiledBundle: string, fontFaceValue: string, iconsValue: string) => string;
|
|
5
|
+
/**
|
|
6
|
+
* @example
|
|
7
|
+
* "base/icons" --> "baseIcons"
|
|
8
|
+
* "utils/form--full" --> "utilsFormFull"
|
|
9
|
+
*/
|
|
10
|
+
export declare const getBundleNameWithoutSpecialChars: (bundleName: string) => string;
|
|
11
|
+
export declare const measureTime: (callback: () => void) => void;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import { styleText } from "node:util";
|
|
3
|
+
import { FONT_FACE_PATH_PLACEHOLDER, ICONS_PATH_PLACEHOLDER, KB, SPECIAL_CHARS_IN_BUNDLE_NAME_REGEX } from "./constants.js";
|
|
4
|
+
export const getFileSize = (fileContent) => {
|
|
5
|
+
const fileLength = fileContent.length;
|
|
6
|
+
if (fileLength < KB) {
|
|
7
|
+
return fileLength + "B";
|
|
8
|
+
}
|
|
9
|
+
const fileLengthInKB = fileLength / KB;
|
|
10
|
+
if (fileLengthInKB < KB) {
|
|
11
|
+
return fileLengthInKB + "KB";
|
|
12
|
+
}
|
|
13
|
+
const fileLengthInMB = fileLengthInKB / KB;
|
|
14
|
+
if (fileLengthInMB < KB) {
|
|
15
|
+
return fileLengthInMB.toFixed(3) + "MB";
|
|
16
|
+
}
|
|
17
|
+
const fileLengthInGB = fileLengthInMB / KB;
|
|
18
|
+
return fileLengthInGB.toFixed(3) + "GB";
|
|
19
|
+
};
|
|
20
|
+
export const getHash = (fileContent) => crypto.createHash("md5").update(fileContent).digest("hex").substring(16);
|
|
21
|
+
export const getBundleNameWithHash = (bundleName, hash) => `${bundleName}-${hash}`;
|
|
22
|
+
export const replacePlaceholdersInBundle = (transpiledBundle, fontFaceValue, iconsValue) => transpiledBundle
|
|
23
|
+
.replaceAll(ICONS_PATH_PLACEHOLDER, iconsValue)
|
|
24
|
+
.replaceAll(FONT_FACE_PATH_PLACEHOLDER, fontFaceValue);
|
|
25
|
+
/**
|
|
26
|
+
* @example
|
|
27
|
+
* "base/icons" --> "baseIcons"
|
|
28
|
+
* "utils/form--full" --> "utilsFormFull"
|
|
29
|
+
*/
|
|
30
|
+
export const getBundleNameWithoutSpecialChars = (bundleName) => {
|
|
31
|
+
const bundleNameNoSpecialChars = bundleName
|
|
32
|
+
.split(SPECIAL_CHARS_IN_BUNDLE_NAME_REGEX)
|
|
33
|
+
.map(subPath => subPath.charAt(0).toUpperCase() + subPath.slice(1))
|
|
34
|
+
.join("");
|
|
35
|
+
return (bundleNameNoSpecialChars.charAt(0).toLowerCase() +
|
|
36
|
+
bundleNameNoSpecialChars.slice(1));
|
|
37
|
+
};
|
|
38
|
+
export const measureTime = (callback) => {
|
|
39
|
+
console.time(styleText("green", "Done in"));
|
|
40
|
+
callback();
|
|
41
|
+
console.timeEnd(styleText("green", "Done in"));
|
|
42
|
+
};
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { DEFAULT_FONT_FACE_PATH, DEFAULT_ICONS_PATH, DEFAULT_OUT_DIR_PATH, SEPARATE_BY_COMMA_REGEX } from "./constants.js";
|
|
2
|
+
import { printArgumentDoesNotExistsError, printDuplicatedArgumentError, printInvalidArgumentError, printMissingFontPathArgumentWarning, printMissingIconsPathArgumentWarning, printMissingOutDirPathArgumentWarning } from "./print-utils.js";
|
|
3
|
+
const ARGUMENT_VALUE_AND_NAME_SEPARATOR_REGEX = /\s*=\s*/g;
|
|
4
|
+
const ERROR_IN_CHECK = false;
|
|
5
|
+
const SUCCESS_CHECK = true;
|
|
6
|
+
const [, , ...args] = process.argv;
|
|
7
|
+
const AVOID_HASH_ARGUMENTS = new Set(["--avoid-hash", "--ah", "-ah"]);
|
|
8
|
+
const ICONS_PATH_ARGUMENTS = new Set(["--icons-path", "--icons", "--i", "-i"]);
|
|
9
|
+
const FONT_FACE_PATH_ARGUMENTS = new Set([
|
|
10
|
+
"--font-face-path",
|
|
11
|
+
"--font-face",
|
|
12
|
+
"--f",
|
|
13
|
+
"-f"
|
|
14
|
+
]);
|
|
15
|
+
const OUT_DIR_ARGUMENTS = new Set(["--outdir", "--o", "-o"]);
|
|
16
|
+
const GLOBANT_ARGUMENTS = new Set(["--globant", "--gl", "-gl"]);
|
|
17
|
+
const isAvoidHashArgument = (arg) => AVOID_HASH_ARGUMENTS.has(arg.toLowerCase());
|
|
18
|
+
const isFontFaceArgument = (arg) => FONT_FACE_PATH_ARGUMENTS.has(arg.toLowerCase());
|
|
19
|
+
const isGlobantArgument = (arg) => GLOBANT_ARGUMENTS.has(arg.toLowerCase());
|
|
20
|
+
const isIconsArgument = (arg) => ICONS_PATH_ARGUMENTS.has(arg.toLowerCase());
|
|
21
|
+
const isOutDirArgument = (arg) => OUT_DIR_ARGUMENTS.has(arg.toLowerCase());
|
|
22
|
+
let hasAvoidHash = false;
|
|
23
|
+
let hasGlobant = false;
|
|
24
|
+
let hasFontFacePath = false;
|
|
25
|
+
let hasIconsPath = false;
|
|
26
|
+
let hasOutDirPath = false;
|
|
27
|
+
let anyWarning = false;
|
|
28
|
+
let avoidHash = [];
|
|
29
|
+
let fontFacePath = "";
|
|
30
|
+
let iconsPath = "";
|
|
31
|
+
let outDirPath = "";
|
|
32
|
+
const checkArgument = (argument) => {
|
|
33
|
+
if (isGlobantArgument(argument)) {
|
|
34
|
+
if (hasGlobant) {
|
|
35
|
+
printDuplicatedArgumentError(argument);
|
|
36
|
+
return ERROR_IN_CHECK;
|
|
37
|
+
}
|
|
38
|
+
hasGlobant = true;
|
|
39
|
+
return SUCCESS_CHECK;
|
|
40
|
+
}
|
|
41
|
+
const argNameWithValue = argument.split(ARGUMENT_VALUE_AND_NAME_SEPARATOR_REGEX);
|
|
42
|
+
if (argNameWithValue.length !== 2) {
|
|
43
|
+
printInvalidArgumentError(argument);
|
|
44
|
+
return ERROR_IN_CHECK;
|
|
45
|
+
}
|
|
46
|
+
const argName = argNameWithValue[0];
|
|
47
|
+
const argValue = argNameWithValue[1];
|
|
48
|
+
if (isAvoidHashArgument(argName)) {
|
|
49
|
+
if (hasAvoidHash) {
|
|
50
|
+
printDuplicatedArgumentError(argument);
|
|
51
|
+
return ERROR_IN_CHECK;
|
|
52
|
+
}
|
|
53
|
+
avoidHash = argValue.split(SEPARATE_BY_COMMA_REGEX);
|
|
54
|
+
hasAvoidHash = true;
|
|
55
|
+
return SUCCESS_CHECK;
|
|
56
|
+
}
|
|
57
|
+
if (isFontFaceArgument(argName)) {
|
|
58
|
+
if (hasFontFacePath) {
|
|
59
|
+
printDuplicatedArgumentError(argument);
|
|
60
|
+
return ERROR_IN_CHECK;
|
|
61
|
+
}
|
|
62
|
+
fontFacePath = argValue;
|
|
63
|
+
hasFontFacePath = true;
|
|
64
|
+
return SUCCESS_CHECK;
|
|
65
|
+
}
|
|
66
|
+
if (isIconsArgument(argName)) {
|
|
67
|
+
if (hasIconsPath) {
|
|
68
|
+
printDuplicatedArgumentError(argument);
|
|
69
|
+
return ERROR_IN_CHECK;
|
|
70
|
+
}
|
|
71
|
+
iconsPath = argValue;
|
|
72
|
+
hasIconsPath = true;
|
|
73
|
+
return SUCCESS_CHECK;
|
|
74
|
+
}
|
|
75
|
+
if (isOutDirArgument(argName)) {
|
|
76
|
+
if (hasOutDirPath) {
|
|
77
|
+
printDuplicatedArgumentError(argument);
|
|
78
|
+
return ERROR_IN_CHECK;
|
|
79
|
+
}
|
|
80
|
+
outDirPath = argValue;
|
|
81
|
+
hasOutDirPath = true;
|
|
82
|
+
return SUCCESS_CHECK;
|
|
83
|
+
}
|
|
84
|
+
printArgumentDoesNotExistsError(argument);
|
|
85
|
+
return ERROR_IN_CHECK;
|
|
86
|
+
};
|
|
87
|
+
export const getArguments = () => {
|
|
88
|
+
for (let index = 0; index < args.length; index++) {
|
|
89
|
+
if (checkArgument(args[index]) === ERROR_IN_CHECK) {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (!fontFacePath) {
|
|
94
|
+
printMissingFontPathArgumentWarning();
|
|
95
|
+
fontFacePath = DEFAULT_FONT_FACE_PATH;
|
|
96
|
+
anyWarning = true;
|
|
97
|
+
}
|
|
98
|
+
if (!iconsPath) {
|
|
99
|
+
printMissingIconsPathArgumentWarning();
|
|
100
|
+
iconsPath = DEFAULT_ICONS_PATH;
|
|
101
|
+
anyWarning = true;
|
|
102
|
+
}
|
|
103
|
+
if (!outDirPath) {
|
|
104
|
+
printMissingOutDirPathArgumentWarning();
|
|
105
|
+
outDirPath = DEFAULT_OUT_DIR_PATH;
|
|
106
|
+
anyWarning = true;
|
|
107
|
+
}
|
|
108
|
+
// Print a line break to better visualize warnings
|
|
109
|
+
if (anyWarning) {
|
|
110
|
+
console.log("");
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
avoidHash: new Set(avoidHash),
|
|
114
|
+
globant: hasGlobant,
|
|
115
|
+
fontFacePath,
|
|
116
|
+
iconsPath,
|
|
117
|
+
outDirPath
|
|
118
|
+
};
|
|
119
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createBundlesWithCustomPaths } from "./internal/create-bundles-with-custom-paths.js";
|
|
3
|
+
import { ensureDirectoryExistsAndItsClear } from "./internal/file-management.js";
|
|
4
|
+
import { getArguments } from "./internal/validate-args.js";
|
|
5
|
+
import { measureTime } from "./internal/utils.js";
|
|
6
|
+
measureTime(() => {
|
|
7
|
+
// Improve process visualization
|
|
8
|
+
console.log("");
|
|
9
|
+
const args = getArguments();
|
|
10
|
+
if (args) {
|
|
11
|
+
ensureDirectoryExistsAndItsClear(args.outDirPath);
|
|
12
|
+
createBundlesWithCustomPaths(args);
|
|
13
|
+
}
|
|
14
|
+
});
|
package/dist/mercury.scss
CHANGED
|
@@ -4309,6 +4309,8 @@
|
|
|
4309
4309
|
--code__border: var(--mer-border__width--sm) solid
|
|
4310
4310
|
var(--mer-surface__elevation--03);
|
|
4311
4311
|
--code__border-radius: var(--mer-border__radius--sm);
|
|
4312
|
+
|
|
4313
|
+
// TODO: Fix this. It MUST be two separated properties (padding-block and padding-inline)
|
|
4312
4314
|
--code__padding: var(--mer-spacing--xs) var(--mer-spacing--sm);
|
|
4313
4315
|
|
|
4314
4316
|
--ch-code__doctag: var(--code__color-blue);
|
package/dist/types.d.ts
CHANGED
|
@@ -7,6 +7,9 @@ export type MercuryBundleComponentForm = "components/button" | "components/check
|
|
|
7
7
|
export type MercuryBundleReset = "resets/box-sizing";
|
|
8
8
|
export type MercuryBundleUtil = "utils/elevation" | "utils/form" | "utils/layout" | "utils/spacing" | "utils/typography" | "chameleon/scrollbar";
|
|
9
9
|
export type MercuryBundleUtilFormFull = "utils/form--full";
|
|
10
|
+
export type MercuryBundleMapping = {
|
|
11
|
+
[key in MercuryBundleComponent | MercuryBundleComponentForm | MercuryBundleReset | MercuryBundleUtil | MercuryBundleUtilFormFull]: `${key}-${string}` | key;
|
|
12
|
+
};
|
|
10
13
|
export type AssetsMetadata = {
|
|
11
14
|
category: string;
|
|
12
15
|
name: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@genexus/mercury",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.1",
|
|
4
4
|
"description": "Mercury is the design system designed for GeneXus IDE Web and GeneXus Next",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -9,6 +9,9 @@
|
|
|
9
9
|
"dist/"
|
|
10
10
|
],
|
|
11
11
|
"type": "module",
|
|
12
|
+
"bin": {
|
|
13
|
+
"mercury": "./dist/cli/mercury.js"
|
|
14
|
+
},
|
|
12
15
|
"exports": {
|
|
13
16
|
".": {
|
|
14
17
|
"import": {
|
|
@@ -16,6 +19,12 @@
|
|
|
16
19
|
"default": "./dist/index.js"
|
|
17
20
|
}
|
|
18
21
|
},
|
|
22
|
+
"./MERCURY_ASSETS.js": {
|
|
23
|
+
"import": {
|
|
24
|
+
"types": "./dist/assets/MERCURY_ASSETS.d.ts",
|
|
25
|
+
"default": "./dist/assets/MERCURY_ASSETS.js"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
19
28
|
"./assets-manager.js": {
|
|
20
29
|
"import": {
|
|
21
30
|
"types": "./dist/assets-manager.d.ts",
|
|
@@ -40,8 +49,8 @@
|
|
|
40
49
|
"build": "npm run build.js && npm run icons-svg && npm run icons-sass && npm run build.scss && npm run copy-tasks && npm run showcase.scss",
|
|
41
50
|
"build.js": "tsc && esbuild dist/*.js --allow-overwrite --minify --outdir=dist && esbuild dist/assets/*.js --allow-overwrite --minify --outdir=dist/assets",
|
|
42
51
|
"build-no-svg": "npm run build.js && npm run build.scss && npm run copy-tasks",
|
|
43
|
-
"build.scss": "scss-bundle -e ./src/mercury.scss -o dist/mercury.scss && npm run build.bundles
|
|
44
|
-
"build.bundles": "
|
|
52
|
+
"build.scss": "scss-bundle -e ./src/mercury.scss -o dist/mercury.scss && npm run build.bundles",
|
|
53
|
+
"build.bundles": "node dist/cli/bundle.js",
|
|
45
54
|
"start": "vite --port 5200 --open showcase/button.html",
|
|
46
55
|
"validate.ci": "npm run build-no-svg",
|
|
47
56
|
"icons-svg": "ssg-svg --srcDir=src/icons/svg-source --outDir=src/assets/icons/_generated/ --configFilePath=src/icons/svg-source/.config/color-states.json --showcaseDir=showcase/icons/ --showcaseBaseHref=../assets/icons/ --logDir=./log --objectFilePath=src/assets/MERCURY_ASSETS.ts --defaultColorType=on-surface",
|
|
@@ -57,6 +66,7 @@
|
|
|
57
66
|
"@atao60/fse-cli": "^0.1.9",
|
|
58
67
|
"@genexus/chameleon-controls-library": "6.0.0-next.55",
|
|
59
68
|
"@genexus/svg-sass-generator": "1.1.24",
|
|
69
|
+
"@types/node": "~22.10.5",
|
|
60
70
|
"chokidar": "^3.6.0",
|
|
61
71
|
"chokidar-cli": "^3.0.0",
|
|
62
72
|
"esbuild": "0.24.0",
|