anubis-ui 1.3.0 → 1.4.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.
Files changed (60) hide show
  1. package/README.md +206 -74
  2. package/dist/interfaces/color.interface.d.ts +8 -0
  3. package/dist/interfaces/color.interface.js +2 -0
  4. package/{src/interfaces/config.interface.ts → dist/interfaces/config.interface.d.ts} +0 -3
  5. package/dist/interfaces/config.interface.js +2 -0
  6. package/dist/interfaces/files.interface.d.ts +4 -0
  7. package/dist/interfaces/files.interface.js +2 -0
  8. package/{src/interfaces/preset.interface.ts → dist/interfaces/preset.interface.d.ts} +3 -7
  9. package/dist/interfaces/preset.interface.js +2 -0
  10. package/dist/tools/config.tool.d.ts +4 -0
  11. package/dist/tools/config.tool.js +64 -0
  12. package/dist/tools/extraction/extractClasses.d.ts +5 -0
  13. package/dist/tools/extraction/extractClasses.js +134 -0
  14. package/dist/tools/fileStuff/config.file.d.ts +5 -0
  15. package/dist/tools/fileStuff/config.file.js +41 -0
  16. package/dist/tools/fileStuff/file.tools.d.ts +19 -0
  17. package/dist/tools/fileStuff/file.tools.js +88 -0
  18. package/dist/tools/fileStuff/quasar-variables.file.d.ts +1 -0
  19. package/dist/tools/fileStuff/quasar-variables.file.js +12 -0
  20. package/dist/tools/logger.d.ts +5 -0
  21. package/dist/tools/logger.js +27 -0
  22. package/dist/tools/main.d.ts +1 -0
  23. package/dist/tools/main.js +54 -0
  24. package/dist/tools/mapping/mapClassIntoRule.d.ts +5 -0
  25. package/dist/tools/mapping/mapClassIntoRule.js +256 -0
  26. package/dist/tools/mapping/mapColors.d.ts +3 -0
  27. package/dist/tools/mapping/mapColors.js +18 -0
  28. package/dist/tools/mapping/mapUtilities.d.ts +1 -0
  29. package/dist/tools/mapping/mapUtilities.js +17 -0
  30. package/dist/tools/output/css.output.d.ts +11 -0
  31. package/dist/tools/output/css.output.js +118 -0
  32. package/dist/tools/validation/color.validation.d.ts +12 -0
  33. package/{src/tools/validation/color.validation.ts → dist/tools/validation/color.validation.js} +14 -31
  34. package/dist/version.d.ts +5 -0
  35. package/dist/version.js +7 -0
  36. package/index.js +5 -18
  37. package/package.json +10 -3
  38. package/index.html +0 -20
  39. package/scripts/generate-version.js +0 -15
  40. package/src/config/colors.config.json +0 -242
  41. package/src/config/files.config.json +0 -5
  42. package/src/config/force.config.json +0 -1
  43. package/src/config/states.config.json +0 -4
  44. package/src/config/utilities.config.json +0 -152
  45. package/src/interfaces/color.interface.ts +0 -9
  46. package/src/interfaces/files.interface.ts +0 -4
  47. package/src/manual/build.js +0 -4
  48. package/src/tools/config.tool.ts +0 -70
  49. package/src/tools/extraction/extractClasses.ts +0 -215
  50. package/src/tools/fileStuff/config.file.ts +0 -44
  51. package/src/tools/fileStuff/css.file.ts +0 -47
  52. package/src/tools/fileStuff/file.tools.ts +0 -12
  53. package/src/tools/logger.ts +0 -23
  54. package/src/tools/mapping/mapClassIntoRule.ts +0 -335
  55. package/src/tools/mapping/mapColorIntoDeclaration.ts +0 -14
  56. package/src/tools/output/css.output.ts +0 -104
  57. package/tests/README.md +0 -54
  58. package/tests/validation/color.validation.test.ts +0 -182
  59. package/tsconfig.json +0 -22
  60. package/vitest.config.ts +0 -19
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.handleVariations = exports.getExportedVariations = exports.init = void 0;
7
+ const file_tools_1 = require("../fileStuff/file.tools");
8
+ const mapClassIntoRule_1 = require("../mapping/mapClassIntoRule");
9
+ const config_tool_1 = require("../config.tool");
10
+ const mapColors_1 = require("../mapping/mapColors");
11
+ const fs_1 = __importDefault(require("fs"));
12
+ const css_output_1 = require("../output/css.output");
13
+ const logger_1 = require("../logger");
14
+ // Cache for regex compilation
15
+ let cachedRegex = null;
16
+ let cachedConfigHash = null;
17
+ /** Fetch vue file based on config target patterns */
18
+ const init = async () => {
19
+ const files = await (0, file_tools_1.getFiles)(config_tool_1.config.files);
20
+ const uniqueClasses = await getUniqueClasses(files);
21
+ const { rules, variationsFromRules } = (0, mapClassIntoRule_1.mapClassesIntoRules)(uniqueClasses);
22
+ const colors = `${css_output_1.comments.colors}\n${(0, mapColors_1.mapColorsIntoMixinDeclaration)(config_tool_1.config.colors)}`;
23
+ const skipVariations = false;
24
+ const variations = skipVariations ? '' : (0, exports.handleVariations)(variationsFromRules);
25
+ const wrappedRules = rules ? `${css_output_1.comments.rules}\n${rules}` : '';
26
+ const fileContent = `${(0, css_output_1.getHeader)()}\n${colors}\n\n${variations}\n\n${wrappedRules}`;
27
+ const file = (0, file_tools_1.writeFile)(file_tools_1.outputFile, fileContent);
28
+ return file;
29
+ };
30
+ exports.init = init;
31
+ /** Extract detected class and map into a flat set */
32
+ const getUniqueClasses = async (files) => {
33
+ /** Find matching classes from a given file based on config states and prefixes */
34
+ const extractClasses = async (filePath) => {
35
+ const file = await fs_1.default.promises.readFile(filePath, 'utf-8');
36
+ if (!file) {
37
+ return [];
38
+ }
39
+ const classDetectionRegex = getClassDetectionRegex();
40
+ const matches = file.match(classDetectionRegex) || [];
41
+ return matches;
42
+ };
43
+ const extractedClasses = (await (0, file_tools_1.pLimit)(files, extractClasses)).flat();
44
+ const exportedClasses = getExportedClasses();
45
+ const classes = [
46
+ ...extractedClasses,
47
+ ...exportedClasses,
48
+ ...config_tool_1.config.force,
49
+ ].sort();
50
+ const uniqueClasses = Array.from(new Set(classes));
51
+ return uniqueClasses;
52
+ };
53
+ /** Build regex pattern from config */
54
+ const buildClassDetectionRegex = () => {
55
+ var _a, _b;
56
+ const { states, utilities } = config_tool_1.config;
57
+ const partialUtilities = utilities === null || utilities === void 0 ? void 0 : utilities.map(u => {
58
+ const { prefix, variations: variationEntries, declaration } = u;
59
+ if (!prefix && !variationEntries) {
60
+ (0, logger_1.log)(`Something doesn't look good -> ${u}`);
61
+ }
62
+ const variations = Array.isArray(variationEntries) ? variationEntries : Object.keys(variationEntries || {});
63
+ const hasVariations = !!(variations === null || variations === void 0 ? void 0 : variations.length);
64
+ const hasDefaultVariation = hasVariations && variations.includes('default');
65
+ const needColor = declaration.includes('${color}');
66
+ /** If variation has default key and doesn't need color, can be used solo */
67
+ if (hasVariations && hasDefaultVariation && !needColor) {
68
+ return `${prefix}`;
69
+ }
70
+ return `${prefix}-`;
71
+ });
72
+ const mappedUtilities = (_a = [...partialUtilities]) === null || _a === void 0 ? void 0 : _a.join('|');
73
+ const mappedStates = `(${(_b = states === null || states === void 0 ? void 0 : states.map(s => `${s}:`)) === null || _b === void 0 ? void 0 : _b.join('|')})`;
74
+ const regexp = new RegExp(`${mappedStates}?(${mappedUtilities})(-?(\\w+(-+)?)+)?`, 'g');
75
+ return regexp;
76
+ };
77
+ /** Get cached regex or build a new one if config changed */
78
+ const getClassDetectionRegex = () => {
79
+ const { states, utilities } = config_tool_1.config;
80
+ const configHash = JSON.stringify({ states, utilities });
81
+ if (cachedRegex && cachedConfigHash === configHash) {
82
+ return cachedRegex;
83
+ }
84
+ cachedRegex = buildClassDetectionRegex();
85
+ cachedConfigHash = configHash;
86
+ return cachedRegex;
87
+ };
88
+ /** Get all variations from utilities with export: "all" */
89
+ const getExportedClasses = () => {
90
+ const possiblesClasses = [];
91
+ const utilities = [...config_tool_1.config.utilities];
92
+ const colors = Object.keys(config_tool_1.config.colors);
93
+ for (const utility of utilities) {
94
+ const exportValue = utility['export'];
95
+ /** export every possible colors variations */
96
+ if (exportValue === 'all') {
97
+ possiblesClasses.push(...colors.map(color => `${utility.prefix}-${color}`));
98
+ }
99
+ }
100
+ return possiblesClasses;
101
+ };
102
+ /** Get all variations from utilities with export: "variations" */
103
+ const getExportedVariations = () => {
104
+ const exportAllVariations = {};
105
+ const utilities = [...config_tool_1.config.utilities];
106
+ for (const utility of utilities) {
107
+ const exportValue = utility['export'];
108
+ // Pour "variations", exporter toutes les variations
109
+ if (exportValue === 'variations' && utility.variations) {
110
+ for (const [variantName, variantValue] of Object.entries(utility.variations)) {
111
+ const variableName = `${utility.prefix}-${variantName}`;
112
+ exportAllVariations[variableName] = variantValue;
113
+ }
114
+ }
115
+ }
116
+ return exportAllVariations;
117
+ };
118
+ exports.getExportedVariations = getExportedVariations;
119
+ const handleVariations = (extractedVariations) => {
120
+ const exportedVariations = (0, exports.getExportedVariations)();
121
+ const variations = {
122
+ ...extractedVariations,
123
+ ...exportedVariations
124
+ };
125
+ // Generate CSS variables for variations
126
+ const variationsCss = Object.entries(variations)
127
+ .map(([varName, varValue]) => ` --${varName}: ${varValue};`)
128
+ .join('\n');
129
+ const wrappedVariations = variationsCss
130
+ ? `${css_output_1.comments.variations}\n:root {\n${variationsCss}\n}`
131
+ : '';
132
+ return wrappedVariations;
133
+ };
134
+ exports.handleVariations = handleVariations;
@@ -0,0 +1,5 @@
1
+ declare let userConfig: any;
2
+ declare const readUserConfigFile: () => any;
3
+ /** Print a warning if the config file has unknow keys */
4
+ declare const checkUserConfigFile: (configFile: string[]) => void;
5
+ export { userConfig, readUserConfigFile, checkUserConfigFile };
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.checkUserConfigFile = exports.readUserConfigFile = exports.userConfig = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const logger_1 = require("../logger");
10
+ const userConfigPath = path_1.default.join(process.cwd(), 'anubis.config.json');
11
+ let userConfig = null;
12
+ exports.userConfig = userConfig;
13
+ const readUserConfigFile = () => {
14
+ const userConfigExists = fs_1.default.existsSync(userConfigPath);
15
+ if (!userConfigExists) {
16
+ (0, logger_1.log)('No user config file found, using default configuration.');
17
+ (0, logger_1.log)('---');
18
+ return;
19
+ }
20
+ const config = fs_1.default.readFileSync(userConfigPath, { encoding: 'utf-8' });
21
+ exports.userConfig = userConfig = JSON.parse(config);
22
+ return userConfig;
23
+ };
24
+ exports.readUserConfigFile = readUserConfigFile;
25
+ /** Print a warning if the config file has unknow keys */
26
+ const checkUserConfigFile = (configFile) => {
27
+ if (!userConfig) {
28
+ return;
29
+ }
30
+ // todo - also check values
31
+ const userConfigKeys = Object.keys(userConfig);
32
+ const unknownKeys = userConfigKeys === null || userConfigKeys === void 0 ? void 0 : userConfigKeys.filter(key => !configFile.includes(key) && key !== 'force');
33
+ if (!(unknownKeys === null || unknownKeys === void 0 ? void 0 : unknownKeys.length)) {
34
+ return;
35
+ }
36
+ (0, logger_1.log)(`${unknownKeys === null || unknownKeys === void 0 ? void 0 : unknownKeys.length} unknown config keys found in user config file`);
37
+ for (const key of unknownKeys) {
38
+ (0, logger_1.log)(`- ${key}`);
39
+ }
40
+ };
41
+ exports.checkUserConfigFile = checkUserConfigFile;
@@ -0,0 +1,19 @@
1
+ import { IFileConfig } from '../../interfaces/files.interface';
2
+ export declare const srcDir: string;
3
+ export declare const outputDir: string;
4
+ export declare const quasarFile = "quasar.variables.scss";
5
+ export declare const outputFile = "_anubis.scss";
6
+ export declare const tokensFile = "anubis/_tokens.scss";
7
+ export declare const mixinsFile = "anubis/_mixins.scss";
8
+ export declare const overridesFile = "anubis/_overrides.scss";
9
+ export declare const checkOrCreateFile: (filePath: string) => boolean;
10
+ export declare const getFiles: (routeConfig: IFileConfig) => Promise<string[]>;
11
+ export declare const readFile: (fileName: string) => string;
12
+ export declare const writeFile: (fileName: string, content: string) => string;
13
+ /**
14
+ * Execute promises with concurrency limit
15
+ * @param items - Items to process
16
+ * @param fn - Async function to execute for each item
17
+ * @param limit - Maximum number of concurrent operations
18
+ */
19
+ export declare const pLimit: <T, R>(items: T[], fn: (item: T) => Promise<R>, limit?: number) => Promise<R[]>;
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.pLimit = exports.writeFile = exports.readFile = exports.getFiles = exports.checkOrCreateFile = exports.overridesFile = exports.mixinsFile = exports.tokensFile = exports.outputFile = exports.quasarFile = exports.outputDir = exports.srcDir = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const fast_glob_1 = __importDefault(require("fast-glob"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const logger_1 = require("../logger");
11
+ exports.srcDir = path_1.default.join(process.cwd(), 'src', 'css');
12
+ exports.outputDir = path_1.default.join(exports.srcDir, 'anubis');
13
+ exports.quasarFile = 'quasar.variables.scss';
14
+ exports.outputFile = '_anubis.scss';
15
+ exports.tokensFile = 'anubis/_tokens.scss';
16
+ exports.mixinsFile = 'anubis/_mixins.scss';
17
+ exports.overridesFile = 'anubis/_overrides.scss';
18
+ const checkOrCreateFile = (filePath) => {
19
+ try {
20
+ fs_1.default.mkdirSync(exports.outputDir, { recursive: true });
21
+ if (fs_1.default.existsSync(filePath)) {
22
+ return true;
23
+ }
24
+ (0, logger_1.log)(`Generating missing file ${filePath}`);
25
+ fs_1.default.writeFileSync(filePath, '');
26
+ return true;
27
+ }
28
+ catch (err) {
29
+ throw new Error(`Erreur lors de la vérification du fichier: ${err.message}`);
30
+ }
31
+ };
32
+ exports.checkOrCreateFile = checkOrCreateFile;
33
+ const getFiles = async (routeConfig) => {
34
+ return await (0, fast_glob_1.default)(routeConfig.targets || '*.vue', {
35
+ absolute: true,
36
+ onlyFiles: true,
37
+ ignore: routeConfig.ignore || [],
38
+ });
39
+ };
40
+ exports.getFiles = getFiles;
41
+ const readFile = (fileName) => {
42
+ const filePath = path_1.default.join(exports.srcDir, fileName);
43
+ (0, exports.checkOrCreateFile)(filePath);
44
+ return fs_1.default.readFileSync(filePath, { encoding: 'utf-8' });
45
+ };
46
+ exports.readFile = readFile;
47
+ const writeFile = (fileName, content) => {
48
+ try {
49
+ const filePath = path_1.default.join(exports.srcDir, fileName);
50
+ (0, exports.checkOrCreateFile)(filePath);
51
+ fs_1.default.writeFileSync(filePath, content);
52
+ return filePath;
53
+ }
54
+ catch (err) {
55
+ throw new Error(`Erreur lors de l'écriture du fichier: ${err.message}`);
56
+ }
57
+ };
58
+ exports.writeFile = writeFile;
59
+ // Performance optimization: limit concurrent file reads to avoid overwhelming the system
60
+ const maxConcurrrentFiles = 10;
61
+ /**
62
+ * Execute promises with concurrency limit
63
+ * @param items - Items to process
64
+ * @param fn - Async function to execute for each item
65
+ * @param limit - Maximum number of concurrent operations
66
+ */
67
+ const pLimit = async (items, fn, limit = maxConcurrrentFiles) => {
68
+ const results = [];
69
+ let index = 0;
70
+ const executeNext = async () => {
71
+ if (index >= items.length)
72
+ return;
73
+ const currentIndex = index++;
74
+ const item = items[currentIndex];
75
+ const result = await fn(item);
76
+ results[currentIndex] = result;
77
+ };
78
+ const workers = Array(Math.min(limit, items.length))
79
+ .fill(null)
80
+ .map(async () => {
81
+ while (index < items.length) {
82
+ await executeNext();
83
+ }
84
+ });
85
+ await Promise.all(workers);
86
+ return results;
87
+ };
88
+ exports.pLimit = pLimit;
@@ -0,0 +1 @@
1
+ export declare const init: () => void;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.init = void 0;
4
+ const file_tools_1 = require("./file.tools");
5
+ const init = () => {
6
+ var _a, _b, _c, _d, _e;
7
+ const currentFileContent = (0, file_tools_1.readFile)(file_tools_1.quasarFile);
8
+ const imports = (_d = (_c = (_b = (_a = [file_tools_1.overridesFile, file_tools_1.tokensFile]) === null || _a === void 0 ? void 0 : _a.filter(Boolean)) === null || _b === void 0 ? void 0 : _b.map(i => `@use "${i}";`)) === null || _c === void 0 ? void 0 : _c.filter(i => !currentFileContent.includes(i))) === null || _d === void 0 ? void 0 : _d.join('\n');
9
+ const newContent = (_e = `${imports}\n${currentFileContent}`) === null || _e === void 0 ? void 0 : _e.trim();
10
+ (0, file_tools_1.writeFile)(file_tools_1.quasarFile, newContent);
11
+ };
12
+ exports.init = init;
@@ -0,0 +1,5 @@
1
+ export declare const logPrefix = "\u262F\uFE0E [ANUBIS]";
2
+ export declare const log: (str: string) => void;
3
+ export declare const logo: () => void;
4
+ /** Execute a callback function and measure it's duration */
5
+ export declare const measureDuration: (section: string, cb: () => any, linebreak?: boolean) => Promise<void>;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.measureDuration = exports.logo = exports.log = exports.logPrefix = void 0;
4
+ const version_1 = require("../version");
5
+ exports.logPrefix = '☯︎ [ANUBIS]';
6
+ const log = (str) => console.log(`${exports.logPrefix} ${str}`);
7
+ exports.log = log;
8
+ const logo = () => {
9
+ (0, exports.log)(' ___ _ ____ ______ _________');
10
+ (0, exports.log)(' / | / | / / / / / __ )/ _/ ___/');
11
+ (0, exports.log)(' / /| | / |/ / / / / __ |/ / \\__ \\');
12
+ (0, exports.log)(' / ___ |/ /| / /_/ / /_/ // / ___/ /');
13
+ (0, exports.log)('/_/ |_/_/ |_/\\____/_____/___//____/');
14
+ (0, exports.log)('');
15
+ (0, exports.log)(`Welcome to Anubis v${version_1.version}`);
16
+ (0, exports.log)('Autonomous Nominative Utility Based Intuitive Styler');
17
+ (0, exports.log)('---');
18
+ };
19
+ exports.logo = logo;
20
+ /** Execute a callback function and measure it's duration */
21
+ const measureDuration = async (section, cb, linebreak = true) => {
22
+ console.time(`${exports.logPrefix} ${section} initialized in`);
23
+ await cb();
24
+ console.timeEnd(`${exports.logPrefix} ${section} initialized in`);
25
+ linebreak && (0, exports.log)('---');
26
+ };
27
+ exports.measureDuration = measureDuration;
@@ -0,0 +1 @@
1
+ export declare const init: () => Promise<void>;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.init = void 0;
4
+ const file_tools_1 = require("./fileStuff/file.tools");
5
+ const logger_1 = require("./logger");
6
+ const mapColors_1 = require("./mapping/mapColors");
7
+ const mapUtilities_1 = require("./mapping/mapUtilities");
8
+ const css_output_1 = require("./output/css.output");
9
+ const { init: initClassExtraction } = require('./extraction/extractClasses');
10
+ const { init: initConfig } = require('./config.tool');
11
+ const { init: initQuasarVariables } = require('./fileStuff/quasar-variables.file');
12
+ const init = async () => {
13
+ /** Extract and set global configurations */
14
+ await (0, logger_1.measureDuration)('Config', initConfig, false);
15
+ /**
16
+ * Write static mixins to designated file
17
+ * @output anubis/_mixins.scss
18
+ */
19
+ await (0, logger_1.measureDuration)('Mixins', initMixins, false);
20
+ /**
21
+ * Map every colors entries from the config into tokens
22
+ * @output anubis/_tokens.scss
23
+ * */
24
+ await (0, logger_1.measureDuration)('Tokens', initTokens, false);
25
+ /**
26
+ * Map configured utilities overrides into a file
27
+ * @output anubis/_overrides.scss
28
+ */
29
+ await (0, logger_1.measureDuration)('Overrides', initOverrides, false);
30
+ /**
31
+ * Add imports to quasar.variables.scss file
32
+ * @imports tokens, overrides
33
+ * @output quasar.variables.scss
34
+ */
35
+ await (0, logger_1.measureDuration)('Quasar imports', initQuasarVariables, false);
36
+ /**
37
+ * Extract classes from the project to remap them into css declaration
38
+ * @output _anubis.scss
39
+ * */
40
+ await (0, logger_1.measureDuration)('Rules', initClassExtraction);
41
+ return;
42
+ };
43
+ exports.init = init;
44
+ const initMixins = () => {
45
+ (0, file_tools_1.writeFile)(file_tools_1.mixinsFile, css_output_1.mixins);
46
+ };
47
+ const initTokens = () => {
48
+ const tokenizedColors = (0, mapColors_1.mapColorsIntoTokens)();
49
+ (0, file_tools_1.writeFile)(file_tools_1.tokensFile, tokenizedColors);
50
+ };
51
+ const initOverrides = () => {
52
+ const mappedOverrides = (0, mapUtilities_1.mapUtilitiesIntoOverride)();
53
+ (0, file_tools_1.writeFile)(file_tools_1.overridesFile, mappedOverrides);
54
+ };
@@ -0,0 +1,5 @@
1
+ declare const mapClassesIntoRules: (classes: string[]) => {
2
+ rules: string;
3
+ variationsFromRules: Record<string, string>;
4
+ };
5
+ export { mapClassesIntoRules };
@@ -0,0 +1,256 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mapClassesIntoRules = void 0;
4
+ const config_tool_1 = require("../config.tool");
5
+ const logger_1 = require("../logger");
6
+ const mapClassesIntoRules = (classes) => {
7
+ const usedVariations = new Map();
8
+ const ruleInfos = classes
9
+ .map(cssClass => mapClassIntoRule(cssClass))
10
+ .filter(ruleInfo => ruleInfo !== null);
11
+ // Collecter les variations utilisés dans les règles générées
12
+ ruleInfos.forEach(ruleInfo => {
13
+ if (ruleInfo.variant && ruleInfo.variant.shouldExport) {
14
+ const variableName = `${ruleInfo.variant.prefix}-${ruleInfo.variant.variantName}`;
15
+ usedVariations.set(variableName, ruleInfo.variant.variantValue);
16
+ }
17
+ });
18
+ // Générer les règles CSS
19
+ const rules = generateCssRules(ruleInfos);
20
+ (0, logger_1.log)(`${ruleInfos.length} rules generated`);
21
+ return {
22
+ rules,
23
+ variationsFromRules: Object.fromEntries(usedVariations),
24
+ };
25
+ };
26
+ exports.mapClassesIntoRules = mapClassesIntoRules;
27
+ const generateCssRules = (ruleInfos) => {
28
+ return ruleInfos
29
+ .map(ruleInfo => `.${ruleInfo.selector} { ${ruleInfo.declaration} }`)
30
+ .join('\n');
31
+ };
32
+ const mapClassIntoRule = (stringClass) => {
33
+ var _a, _b, _c, _d;
34
+ const params = getClassInfos(stringClass);
35
+ if (!params.utility) {
36
+ return null;
37
+ }
38
+ const needsColor = (_b = (_a = params.utility) === null || _a === void 0 ? void 0 : _a.declaration) === null || _b === void 0 ? void 0 : _b.includes('${color}');
39
+ const usesVariation = params.variationName;
40
+ const hasDefaultVariation = !((_c = params.utility) === null || _c === void 0 ? void 0 : _c.variations) || Object.keys(((_d = params.utility) === null || _d === void 0 ? void 0 : _d.variations) || []).includes('default');
41
+ /**
42
+ * If need color but doesn't have one or if need a variation but doesn't have one either
43
+ * this is a no go
44
+ */
45
+ if ((needsColor && !params.color) || (!hasDefaultVariation && !usesVariation)) {
46
+ return null;
47
+ }
48
+ const ruleInfo = buildRuleInfo(params);
49
+ return ruleInfo;
50
+ };
51
+ const getClassInfos = (stringClass) => {
52
+ const { cleanedClass, state } = getStateInfos(stringClass);
53
+ const { cleanedColor, prefix } = getPrefixInfos(cleanedClass);
54
+ const { color, baseColor, utility, variation, variationName } = getUtilityInfos({
55
+ cleanedColor,
56
+ prefix,
57
+ });
58
+ return {
59
+ state,
60
+ color,
61
+ baseColor,
62
+ prefix,
63
+ utility,
64
+ variation,
65
+ variationName,
66
+ };
67
+ };
68
+ const getStateInfos = (stringClass) => {
69
+ const state = config_tool_1.config.states.find(configState => stringClass.startsWith(configState));
70
+ const cleanedClass = state
71
+ ? stringClass.slice(state.length + 1)
72
+ : stringClass;
73
+ return {
74
+ cleanedClass,
75
+ state,
76
+ };
77
+ };
78
+ const getPrefixInfos = (stringClass) => {
79
+ const prefixes = [
80
+ ...config_tool_1.config.utilities.map(u => u.prefix)
81
+ ];
82
+ for (const prefix of prefixes) {
83
+ if (!stringClass.startsWith(prefix)) {
84
+ continue;
85
+ }
86
+ return {
87
+ cleanedColor: stringClass.slice(prefix.length + 1),
88
+ prefix,
89
+ };
90
+ }
91
+ (0, logger_1.log)(`No matching prefix found for class: ${stringClass}`);
92
+ return { cleanedColor: stringClass, prefix: null };
93
+ };
94
+ const getUtilityInfos = ({ cleanedColor, prefix, }) => {
95
+ /**
96
+ * Find utility variations matching the prefix from the config
97
+ * Since a prefix can be in multiple utilities, filter every matching prefixes
98
+ */
99
+ const possibleUtility = [...config_tool_1.config.utilities].filter(p => p.prefix === prefix);
100
+ if (!possibleUtility.length) {
101
+ return { matchingUtility: null, variation: null };
102
+ }
103
+ const { colorExists } = getColorInfos(cleanedColor);
104
+ const possibleUtilityVariations = possibleUtility.filter(({ variations }) => { var _a; return (_a = Object.keys(variations || {})) === null || _a === void 0 ? void 0 : _a.length; });
105
+ /**
106
+ * Find the utility where the variations exist
107
+ * Logic:
108
+ * 1. If
109
+ * OR we have a valid color
110
+ * OR no color specified
111
+ * OR no possible utilities have variation
112
+ * Then use the first utility
113
+ * 2. Otherwise, find a utility with a matching variation
114
+ */
115
+ let matchingUtility;
116
+ if (colorExists || !cleanedColor || (possibleUtilityVariations === null || possibleUtilityVariations === void 0 ? void 0 : possibleUtilityVariations.length) <= 0) {
117
+ matchingUtility = possibleUtility[0];
118
+ }
119
+ else {
120
+ // Find utility with matching variation
121
+ matchingUtility = possibleUtilityVariations.find(({ variations }) => {
122
+ if (!variations)
123
+ return true;
124
+ const mappedVariations = Array.isArray(variations) ? variations : Object.keys(variations);
125
+ return mappedVariations.some(v => cleanedColor === v || cleanedColor.endsWith(v));
126
+ });
127
+ }
128
+ if (!matchingUtility) {
129
+ // log(`No utility found for ${cleanedColor || prefix}`);
130
+ return {
131
+ matchingUtility,
132
+ variation: null,
133
+ };
134
+ }
135
+ if (!colorExists && !matchingUtility.variations) {
136
+ // log(`Unknow stuff -> ${[prefix, cleanedColor].join('-')}`);
137
+ return {
138
+ matchingUtility,
139
+ variation: null,
140
+ };
141
+ }
142
+ const possibleVariations = matchingUtility.variations || { default: '' };
143
+ const defaultVariation = 'default';
144
+ /**
145
+ * Variation matching logic:
146
+ * 1. Check for exact match first (prevents "xl" matching when looking for "2xl")
147
+ * 2. Fall back to endsWith for edge cases where variation is a suffix
148
+ */
149
+ const exactVariation = Object.keys(possibleVariations).find(v => cleanedColor === v);
150
+ const closestVariation = Object.keys(possibleVariations).find(v => cleanedColor.endsWith(v));
151
+ const matchingVariation = exactVariation || closestVariation;
152
+ const variation = possibleVariations[matchingVariation || defaultVariation];
153
+ const color = matchingVariation
154
+ ? cleanedColor.slice(0, -matchingVariation.length - 1)
155
+ : cleanedColor;
156
+ const { baseColor } = getColorInfos(color);
157
+ return {
158
+ color,
159
+ baseColor,
160
+ utility: matchingUtility,
161
+ variationName: matchingVariation,
162
+ variation,
163
+ };
164
+ };
165
+ // Map state names to CSS pseudo-selectors
166
+ const stateSelectors = {
167
+ hover: ':hover',
168
+ 'not-hover': ':not(:hover)',
169
+ };
170
+ const buildRuleInfo = ({ state, prefix, color, baseColor, utility, variation, variationName, }) => {
171
+ // Get state selector from mapping
172
+ const stateSelector = state ? stateSelectors[state] || '' : '';
173
+ let selector = `${prefix}${color ? `-${color}` : ''}${variationName ? `-${variationName}` : ''}`;
174
+ if (state) {
175
+ selector = `${state}\\:${selector}${stateSelector}`;
176
+ }
177
+ // Vérifier que la couleur existe dans la config
178
+ if (baseColor && !config_tool_1.config.colors[baseColor]) {
179
+ (0, logger_1.log)(`Color '${baseColor}' not found in colors config - skipping rule generation`);
180
+ return null;
181
+ }
182
+ // Gérer les variations avec variables CSS ou valeurs directes
183
+ let variableToUse = variation;
184
+ let variantInfo = undefined;
185
+ // Vérifier si on doit exporter les variations en tant que variables CSS
186
+ const exportVariations = utility['export'];
187
+ const useVariables = exportVariations === 'variations' || exportVariations === 'all';
188
+ if (variationName && variationName !== 'default') {
189
+ const variablePrefix = prefix;
190
+ const variableName = `${variablePrefix}-${variationName}`;
191
+ // Si export-variations: true, utiliser une variable CSS, sinon la valeur directe
192
+ if (useVariables) {
193
+ variableToUse = `var(--${variableName})`;
194
+ variantInfo = {
195
+ prefix,
196
+ variantName: variationName,
197
+ variantValue: variation,
198
+ shouldExport: true,
199
+ };
200
+ }
201
+ else {
202
+ // Utiliser la valeur directe, pas de variable CSS
203
+ variableToUse = variation;
204
+ }
205
+ }
206
+ else if (variation && variationName === 'default') {
207
+ // Pour les variations par défaut
208
+ const variableName = `${prefix}-default`;
209
+ if (useVariables) {
210
+ variableToUse = `var(--${variableName})`;
211
+ variantInfo = {
212
+ prefix,
213
+ variantName: 'default',
214
+ variantValue: variation,
215
+ shouldExport: true,
216
+ };
217
+ }
218
+ else {
219
+ variableToUse = variation;
220
+ }
221
+ }
222
+ let declaration = utility.declaration
223
+ .replace('${value}', variableToUse)
224
+ .replace('${color}', color ? `var(--${color})` : '');
225
+ if (!declaration.endsWith(';')) {
226
+ declaration += ';';
227
+ }
228
+ if (!declaration.includes('!important')) {
229
+ declaration = declaration.replace(';', ' !important;');
230
+ }
231
+ return {
232
+ selector,
233
+ declaration,
234
+ color: color || undefined,
235
+ variant: variantInfo,
236
+ };
237
+ };
238
+ /**
239
+ * _ Check if a color includes opacity (ends with 2 digits)
240
+ * * Opacity is included in the color name during mixin declaration
241
+ * */
242
+ // Cache regex outside function to avoid recompilation on every call
243
+ const OPACITY_DETECTION_REGEX = /(?:(\w-?)+)-\d{2}$/; // Strings that end with two digits (e.g., primary-50)
244
+ const OPACITY_SUFFIX_LENGTH = 3; // Length of "-NN" format
245
+ const getColorInfos = (color) => {
246
+ const isOpacity = OPACITY_DETECTION_REGEX.test(color);
247
+ const baseColor = isOpacity
248
+ ? color.slice(0, -OPACITY_SUFFIX_LENGTH)
249
+ : color;
250
+ const colorExists = Object.keys(config_tool_1.config.colors).some(configColor => configColor === baseColor);
251
+ return {
252
+ colorExists,
253
+ isOpacity,
254
+ baseColor,
255
+ };
256
+ };
@@ -0,0 +1,3 @@
1
+ import { IColor } from "../../interfaces/color.interface";
2
+ export declare const mapColorsIntoMixinDeclaration: (colors: IColor) => string;
3
+ export declare const mapColorsIntoTokens: () => string;