@salty-css/core 0.0.1-alpha.310 → 0.0.1-alpha.311

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.
@@ -1,27 +0,0 @@
1
- import { CachedConfig, SaltyConfig } from '../config';
2
- export declare const getDestDir: (dirname: string) => Promise<string>;
3
- export declare const saltyFileExtensions: string[];
4
- export declare const saltyFileRegExp: (additional?: string[]) => RegExp;
5
- export declare const isSaltyFile: (file: string, additional?: string[]) => boolean;
6
- export declare const generateConfigStyles: (dirname: string, configFiles: Set<string>) => Promise<void>;
7
- export declare const compileSaltyFile: (dirname: string, sourceFilePath: string, outputDirectory: string) => Promise<{
8
- contents: {
9
- [key: string]: {
10
- generator: any;
11
- isClassName?: boolean;
12
- isMedia?: boolean;
13
- isGlobalDefine?: boolean;
14
- isDefineVariables?: boolean;
15
- isDefineTemplates?: boolean;
16
- isKeyframes?: boolean;
17
- animationName?: string;
18
- css?: Promise<string>;
19
- styles?: any;
20
- };
21
- };
22
- outputFilePath: string;
23
- }>;
24
- export declare const getConfig: (dirname: string) => Promise<SaltyConfig & CachedConfig>;
25
- export declare const generateCss: (dirname: string, prod?: boolean, clean?: boolean) => Promise<void>;
26
- export declare const generateFile: (dirname: string, file: string, prod?: boolean) => Promise<void>;
27
- export declare const minimizeFile: (dirname: string, file: string, prod?: boolean) => Promise<string | undefined>;
package/compiler/index.js DELETED
@@ -1,651 +0,0 @@
1
- import * as esbuild from "esbuild";
2
- import { execSync } from "child_process";
3
- import { Script } from "vm";
4
- import { t as toHash, d as dashCase } from "../to-hash-DSoCPs8D.js";
5
- import { join, parse } from "path";
6
- import { writeFileSync, existsSync, mkdirSync, readFileSync, statSync, readdirSync } from "fs";
7
- import { readFile } from "fs/promises";
8
- import { p as parseAndJoinStyles, a as parseVariableTokens } from "../parse-styles-CS97_e4S.js";
9
- import { parseTemplates, getTemplateTypes } from "../parsers/index.js";
10
- import { d as detectCurrentModuleType, l as logger, s as saltyReset, a as dotCase } from "../salty-reset-D1VR51zL.js";
11
- import { mergeObjects, mergeFactories } from "../css/merge.js";
12
- import { d as defineTemplates } from "../define-templates-CVhhgPnd.js";
13
- import { getFunctionRange } from "./get-function-range.js";
14
- import { getCorePackageRoot, resolveExportValue } from "./helpers.js";
15
- const cache = {
16
- externalModules: [],
17
- rcFile: void 0,
18
- destDir: void 0
19
- };
20
- const getExternalModules = (coreConfigPath) => {
21
- if (cache.externalModules.length > 0) return cache.externalModules;
22
- const content = readFileSync(coreConfigPath, "utf8");
23
- const match = content.match(/externalModules:\s?\[(.*)\]/);
24
- if (!match) return [];
25
- const externalModules = match[1].split(",").map((d) => d.replace(/['"`]/g, "").trim());
26
- cache.externalModules = externalModules;
27
- return externalModules;
28
- };
29
- const getDestDir = async (dirname) => {
30
- if (cache.destDir) return cache.destDir;
31
- const projectConfig = await getRCProjectConfig(dirname);
32
- const destDir = join(dirname, (projectConfig == null ? void 0 : projectConfig.saltygenDir) || "saltygen");
33
- cache.destDir = destDir;
34
- return destDir;
35
- };
36
- const saltyFileExtensions = ["salty", "css", "styles", "styled"];
37
- const saltyFileRegExp = (additional = []) => new RegExp(`\\.(${[...saltyFileExtensions, ...additional].join("|")})\\.`);
38
- const isSaltyFile = (file, additional = []) => saltyFileRegExp(additional).test(file);
39
- const readRCFile = async (currentDir) => {
40
- if (cache.rcFile) return cache.rcFile;
41
- if (currentDir === "/") throw new Error("Could not find .saltyrc.json file");
42
- const rcPath = join(currentDir, ".saltyrc.json");
43
- const rcContent = await readFile(rcPath, "utf-8").then(JSON.parse).catch(() => void 0);
44
- if (!rcContent) return readRCFile(join(currentDir, ".."));
45
- cache.rcFile = rcContent;
46
- return rcContent;
47
- };
48
- const getRCProjectConfig = async (dirname) => {
49
- var _a, _b;
50
- const rcFile = await readRCFile(dirname);
51
- const projectConfig = (_a = rcFile.projects) == null ? void 0 : _a.find((project) => dirname.endsWith(project.dir || ""));
52
- if (!projectConfig) return (_b = rcFile.projects) == null ? void 0 : _b.find((project) => project.dir === rcFile.defaultProject);
53
- return projectConfig;
54
- };
55
- const generateConfig = async (dirname) => {
56
- const rcProject = await getRCProjectConfig(dirname);
57
- const destDir = await getDestDir(dirname);
58
- const coreConfigPath = join(dirname, (rcProject == null ? void 0 : rcProject.configDir) || "", "salty.config.ts");
59
- const coreConfigDest = join(destDir, "salty.config.js");
60
- await detectCurrentModuleType(dirname);
61
- const externalModules = getExternalModules(coreConfigPath);
62
- await esbuild.build({
63
- entryPoints: [coreConfigPath],
64
- minify: true,
65
- treeShaking: true,
66
- bundle: true,
67
- outfile: coreConfigDest,
68
- format: "cjs",
69
- external: externalModules
70
- });
71
- const raw = await readFile(coreConfigDest, "utf8");
72
- const scriptReal = new Script(raw);
73
- const context = { module: { exports: {} } };
74
- scriptReal.runInNewContext(context);
75
- const { config } = context.module.exports;
76
- return {
77
- config,
78
- path: coreConfigDest
79
- };
80
- };
81
- const generateConfigStyles = async (dirname, configFiles) => {
82
- var _a, _b;
83
- const destDir = await getDestDir(dirname);
84
- const generationResults = {
85
- mediaQueries: [],
86
- globalStyles: [],
87
- variables: [],
88
- templates: []
89
- };
90
- await Promise.all(
91
- [...configFiles].map(async (src) => {
92
- const { contents, outputFilePath } = await compileSaltyFile(dirname, src, destDir);
93
- Object.entries(contents).forEach(([name, value]) => {
94
- if (value.isMedia) generationResults.mediaQueries.push([name, value]);
95
- else if (value.isGlobalDefine) generationResults.globalStyles.push(value);
96
- else if (value.isDefineVariables) generationResults.variables.push(value);
97
- else if (value.isDefineTemplates) generationResults.templates.push(value._setPath(`${name};;${outputFilePath}`));
98
- });
99
- })
100
- );
101
- const { config, path: configPath } = await generateConfig(dirname);
102
- const configCacheContent = { ...config };
103
- const { mediaQueries } = generationResults;
104
- configCacheContent.mediaQueries = Object.fromEntries(mediaQueries.map(([name, value]) => [`@${name}`, value]));
105
- const mediaQueryKeys = mediaQueries.map(([name]) => `'@${name}'`).join(" | ");
106
- const variableTokens = /* @__PURE__ */ new Set();
107
- const parseVariables = async (obj, path = []) => {
108
- if (!obj) return [];
109
- const promises = Object.entries(obj).map(async ([key, value]) => {
110
- const parseVariable = async (value2) => {
111
- if (!value2) return void 0;
112
- if (value2 instanceof Promise) return await parseVariable(await value2);
113
- if (typeof value2 === "function") return await parseVariable(await value2());
114
- if (typeof value2 === "object") return await parseVariables(value2, [...path, key]);
115
- const dottedKey = dotCase(key);
116
- const dashedKey = dashCase(key);
117
- const tsName = [...path, dottedKey].join(".");
118
- variableTokens.add(`"${tsName}"`);
119
- const cssName = [...path.map(dashCase), dashedKey].join("-");
120
- const result = parseVariableTokens(value2);
121
- if (!result) return `--${cssName}: ${value2};`;
122
- return `--${cssName}: ${result.transformed};`;
123
- };
124
- return await parseVariable(value);
125
- });
126
- const results = await Promise.all(promises);
127
- return results.flat();
128
- };
129
- const parseResponsiveVariables = async (obj) => {
130
- if (!obj) return [];
131
- const promises = Object.entries(obj).map(async ([mediaQuery, values]) => {
132
- const variables = await parseVariables(values);
133
- if (mediaQuery === "base") return variables.join("");
134
- if (configCacheContent.mediaQueries[mediaQuery]) {
135
- const mediaQueryValue = configCacheContent.mediaQueries[mediaQuery];
136
- return `${mediaQueryValue} { ${variables.join("")} }`;
137
- }
138
- return `${mediaQuery} { ${variables.join("")} }`;
139
- });
140
- const results = await Promise.all(promises);
141
- return results.flat();
142
- };
143
- const parseConditionalVariables = async (obj) => {
144
- if (!obj) return [];
145
- const promises = Object.entries(obj).map(async ([property, conditions]) => {
146
- const promises2 = Object.entries(conditions).map(async ([condition, values]) => {
147
- const variables = await parseVariables(values, [property]);
148
- const conditionScope = `.${property}-${condition}, [data-${property}="${condition}"]`;
149
- const combined = variables.join("");
150
- return `${conditionScope} { ${combined} }`;
151
- });
152
- const result = await Promise.all(promises2);
153
- return result.flat();
154
- });
155
- const results = await Promise.all(promises);
156
- return results.flat();
157
- };
158
- const getStaticVariables = (variables = {}) => {
159
- return { ...variables, responsive: void 0, conditional: void 0 };
160
- };
161
- const getGeneratedVariables = (type) => {
162
- return generationResults.variables.map((factory) => {
163
- if (type === "static") return getStaticVariables(factory._current);
164
- return factory._current[type];
165
- });
166
- };
167
- const _staticVariables = mergeObjects(getStaticVariables(config.variables), getGeneratedVariables("static"));
168
- const staticVariables = await parseVariables(_staticVariables);
169
- const _responsiveVariables = mergeObjects((_a = config.variables) == null ? void 0 : _a.responsive, getGeneratedVariables("responsive"));
170
- const responsiveVariables = await parseResponsiveVariables(_responsiveVariables);
171
- const _conditionalVariables = mergeObjects((_b = config.variables) == null ? void 0 : _b.conditional, getGeneratedVariables("conditional"));
172
- const conditionalVariables = await parseConditionalVariables(_conditionalVariables);
173
- const variablesPath = join(destDir, "css/_variables.css");
174
- const variablesCss = `:root { ${staticVariables.join("")} ${responsiveVariables.join("")} } ${conditionalVariables.join("")}`;
175
- writeFileSync(variablesPath, variablesCss);
176
- configCacheContent.staticVariables = _staticVariables;
177
- const globalStylesPath = join(destDir, "css/_global.css");
178
- const mergedGlobalStyles = mergeObjects(config.global, generationResults.globalStyles);
179
- const globalStylesString = await parseAndJoinStyles(mergedGlobalStyles, "");
180
- writeFileSync(globalStylesPath, `@layer global { ${globalStylesString} }`);
181
- const resetStylesPath = join(destDir, "css/_reset.css");
182
- const getResetStyles = () => {
183
- if (config.reset === "none") return {};
184
- if (typeof config.reset === "object") return config.reset;
185
- return saltyReset;
186
- };
187
- const resetStyles = getResetStyles();
188
- const resetStylesString = await parseAndJoinStyles(resetStyles, "");
189
- writeFileSync(resetStylesPath, `@layer reset { ${resetStylesString} }`);
190
- const templateStylesPath = join(destDir, "css/_templates.css");
191
- const templates = mergeObjects(config.templates, generationResults.templates);
192
- const templateStylesString = await parseTemplates(templates);
193
- const templateTokens = getTemplateTypes(templates);
194
- writeFileSync(templateStylesPath, `@layer templates { ${templateStylesString} }`);
195
- configCacheContent.templates = templates;
196
- const configTemplateFactories = config.templates ? [defineTemplates(config.templates)._setPath(`config;;${configPath}`)] : [];
197
- const templateFactories = mergeFactories(generationResults.templates, configTemplateFactories);
198
- configCacheContent.templatePaths = Object.fromEntries(Object.entries(templateFactories).map(([key, faktory]) => [key, faktory._path]));
199
- const tsTokensPath = join(destDir, "types/css-tokens.d.ts");
200
- const tsVariableTokens = [...variableTokens].join("|");
201
- const tsTokensTypes = `
202
- // Variable types
203
- type VariableTokens = ${tsVariableTokens || `''`};
204
- type PropertyValueToken = \`{\${VariableTokens}}\`;
205
-
206
- // Template types
207
- type TemplateTokens = {
208
- ${Object.entries(templateTokens).map(([key, value]) => `${key}?: ${value}`).join("\n")}
209
- }
210
-
211
- // Media query types
212
- type MediaQueryKeys = ${mediaQueryKeys || `''`};
213
- `;
214
- writeFileSync(tsTokensPath, tsTokensTypes);
215
- const configCachePath = join(destDir, "cache/config-cache.json");
216
- writeFileSync(configCachePath, JSON.stringify(configCacheContent, null, 2));
217
- const corePackageRoot = getCorePackageRoot();
218
- const configCacheSecondaryPath = join(corePackageRoot, "cache/config-cache.json");
219
- writeFileSync(configCacheSecondaryPath, JSON.stringify(configCacheContent, null, 2));
220
- };
221
- const replaceStyledTag = (currentFile) => {
222
- return currentFile.replace(/styled\(([^"'`{,]+),/g, (match, tag) => {
223
- const isString = /^['"`]/.test(tag);
224
- if (isString) return match;
225
- const isImportedRegExp = new RegExp(`import[^;]*${tag}[,\\s{][^;]*from\\s?([^{};]+);`);
226
- const isImported = isImportedRegExp.test(currentFile);
227
- if (!isImported) return match;
228
- const importResult = isImportedRegExp.exec(currentFile);
229
- if (importResult) {
230
- const importPath = importResult.at(1);
231
- const isSaltyImport = saltyFileExtensions.some((ext) => importPath == null ? void 0 : importPath.includes(ext));
232
- if (isSaltyImport) return match;
233
- }
234
- return "styled('div',";
235
- });
236
- };
237
- const addConfigCache = (currentFile, dirname) => {
238
- try {
239
- const saltyCachedConfig = readFileSync(join(dirname, "saltygen/cache/config-cache.json"), "utf8");
240
- if (!saltyCachedConfig) return `globalThis.saltyConfig = {};
241
-
242
- ${currentFile}`;
243
- return `globalThis.saltyConfig = ${saltyCachedConfig};
244
-
245
- ${currentFile}`;
246
- } catch {
247
- return currentFile;
248
- }
249
- };
250
- const compileSaltyFile = async (dirname, sourceFilePath, outputDirectory) => {
251
- const hashedName = toHash(sourceFilePath);
252
- const tempDir = join(outputDirectory, "./temp");
253
- if (!existsSync(tempDir)) mkdirSync(tempDir);
254
- const parsed = parse(sourceFilePath);
255
- let currentFile = readFileSync(sourceFilePath, "utf8");
256
- currentFile = replaceStyledTag(currentFile);
257
- currentFile = addConfigCache(currentFile, dirname);
258
- const outputFilePath = join(outputDirectory, "js", hashedName + ".js");
259
- const rcProject = await getRCProjectConfig(dirname);
260
- const coreConfigPath = join(dirname, (rcProject == null ? void 0 : rcProject.configDir) || "", "salty.config.ts");
261
- const externalModules = getExternalModules(coreConfigPath);
262
- await detectCurrentModuleType(dirname);
263
- await esbuild.build({
264
- stdin: {
265
- contents: currentFile,
266
- sourcefile: parsed.base,
267
- resolveDir: parsed.dir,
268
- loader: "tsx"
269
- },
270
- minify: false,
271
- treeShaking: true,
272
- bundle: true,
273
- outfile: outputFilePath,
274
- format: "cjs",
275
- target: ["node20"],
276
- keepNames: true,
277
- external: externalModules,
278
- packages: "external",
279
- plugins: [
280
- {
281
- name: "test",
282
- setup: (build) => {
283
- build.onLoad({ filter: /.*\.css|salty|styles|styled\.ts/ }, (args) => {
284
- const original = readFileSync(args.path, "utf8");
285
- const modified = replaceStyledTag(original);
286
- return { contents: modified, loader: "ts" };
287
- });
288
- }
289
- }
290
- ]
291
- });
292
- const context = { module: { exports: {} } };
293
- const raw = await readFile(outputFilePath, "utf8");
294
- new Script(raw).runInNewContext(context);
295
- return {
296
- contents: context.module.exports,
297
- outputFilePath
298
- };
299
- };
300
- const getConfigCache = async (dirname) => {
301
- const destDir = await getDestDir(dirname);
302
- const coreConfigDest = join(destDir, "cache/config-cache.json");
303
- const contents = readFileSync(coreConfigDest, "utf8");
304
- if (!contents) throw new Error("Could not find config cache file");
305
- return JSON.parse(contents);
306
- };
307
- const getConfig = async (dirname) => {
308
- const cached = await getConfigCache(dirname);
309
- const destDir = await getDestDir(dirname);
310
- const coreConfigDest = join(destDir, "salty.config.js");
311
- const context = { module: { exports: {} } };
312
- const raw = await readFile(coreConfigDest, "utf8");
313
- new Script(raw).runInNewContext(context);
314
- const { config } = context.module.exports;
315
- return mergeObjects(config, cached);
316
- };
317
- const isProduction = () => {
318
- try {
319
- return process.env["NODE_ENV"] === "production";
320
- } catch {
321
- return false;
322
- }
323
- };
324
- const generateCss = async (dirname, prod = isProduction(), clean = true) => {
325
- try {
326
- const start = Date.now();
327
- if (prod) logger.info("Generating CSS in production mode! 🔥");
328
- else logger.info("Generating CSS in development mode! 🚀");
329
- const globalCssFiles = [];
330
- const cssFiles = [];
331
- const destDir = await getDestDir(dirname);
332
- const cssFile = join(destDir, "index.css");
333
- const clearDistDir = () => {
334
- if (existsSync(destDir)) execSync("rm -rf " + destDir);
335
- mkdirSync(destDir, { recursive: true });
336
- mkdirSync(join(destDir, "css"));
337
- mkdirSync(join(destDir, "types"));
338
- mkdirSync(join(destDir, "js"));
339
- mkdirSync(join(destDir, "cache"));
340
- };
341
- if (clean) clearDistDir();
342
- const files = /* @__PURE__ */ new Set();
343
- const configFiles = /* @__PURE__ */ new Set();
344
- async function collectFiles(src) {
345
- const foldersToSkip = ["node_modules", "saltygen"];
346
- const stats = statSync(src);
347
- if (stats.isDirectory()) {
348
- const files2 = readdirSync(src);
349
- const shouldSkip = foldersToSkip.some((folder) => src.includes(folder));
350
- if (shouldSkip) return;
351
- await Promise.all(files2.map((file) => collectFiles(join(src, file))));
352
- } else if (stats.isFile()) {
353
- const validFile = isSaltyFile(src);
354
- if (validFile) {
355
- files.add(src);
356
- const contents = readFileSync(src, "utf8");
357
- const hasDefineFunction = /define[\w\d]+\(/.test(contents);
358
- if (hasDefineFunction) configFiles.add(src);
359
- }
360
- }
361
- }
362
- await collectFiles(dirname);
363
- await generateConfigStyles(dirname, configFiles);
364
- const generationResults = {
365
- keyframes: [],
366
- components: [],
367
- classNames: []
368
- };
369
- await Promise.all(
370
- [...files].map(async (src) => {
371
- const { contents } = await compileSaltyFile(dirname, src, destDir);
372
- for (let [name, value] of Object.entries(contents)) {
373
- const resolved = await resolveExportValue(value, 1);
374
- if (resolved.isKeyframes) {
375
- generationResults.keyframes.push({
376
- value: resolved,
377
- src,
378
- name
379
- });
380
- } else if (resolved.isClassName) {
381
- generationResults.classNames.push({
382
- ...value,
383
- src,
384
- name
385
- });
386
- } else if (resolved.generator) {
387
- generationResults.components.push({
388
- ...value,
389
- src,
390
- name
391
- });
392
- }
393
- }
394
- })
395
- );
396
- const config = await getConfig(dirname);
397
- for (const keyframes of generationResults.keyframes) {
398
- const { value } = keyframes;
399
- const fileName = `a_${value.animationName}.css`;
400
- const filePath = `css/${fileName}`;
401
- const cssPath = join(destDir, filePath);
402
- globalCssFiles.push(fileName);
403
- writeFileSync(cssPath, value.css);
404
- }
405
- const localCssFiles = {};
406
- for (const componentResult of generationResults.components) {
407
- const { src, name } = componentResult;
408
- if (!localCssFiles[src]) localCssFiles[src] = [];
409
- const generator = componentResult.generator._withBuildContext({
410
- callerName: name,
411
- isProduction: prod,
412
- config
413
- });
414
- if (!cssFiles[generator.priority]) cssFiles[generator.priority] = [];
415
- const styles = await generator.css;
416
- if (!styles) continue;
417
- cssFiles[generator.priority].push(generator.cssFileName);
418
- const filePath = `css/${generator.cssFileName}`;
419
- const cssPath = join(destDir, filePath);
420
- writeFileSync(cssPath, styles);
421
- if (config.importStrategy === "component") {
422
- localCssFiles[src].push(generator.cssFileName);
423
- }
424
- }
425
- for (const classNameResult of generationResults.classNames) {
426
- const { src, name } = classNameResult;
427
- if (!localCssFiles[src]) localCssFiles[src] = [];
428
- const generator = classNameResult.generator._withBuildContext({
429
- callerName: name,
430
- isProduction: prod,
431
- config
432
- });
433
- const styles = await generator.css;
434
- if (!styles) continue;
435
- if (!cssFiles[generator.priority]) cssFiles[generator.priority] = [];
436
- cssFiles[generator.priority].push(generator.cssFileName);
437
- const filePath = `css/${generator.cssFileName}`;
438
- const cssPath = join(destDir, filePath);
439
- writeFileSync(cssPath, styles);
440
- if (config.importStrategy === "component") {
441
- localCssFiles[src].push(generator.cssFileName);
442
- }
443
- }
444
- if (config.importStrategy === "component") {
445
- Object.entries(localCssFiles).forEach(([src, localCssFile]) => {
446
- const cssContent2 = localCssFile.map((file) => `@import url('./${file}');`).join("\n");
447
- const hashName = toHash(src, 6);
448
- const parsedPath = parse(src);
449
- const dasherized = dashCase(parsedPath.name);
450
- const cssFile2 = join(destDir, `css/f_${dasherized}-${hashName}.css`);
451
- writeFileSync(cssFile2, cssContent2 || `/* Empty file */`);
452
- });
453
- }
454
- const otherGlobalCssFiles = globalCssFiles.map((file) => `@import url('./css/${file}');`).join("\n");
455
- const globalCssFilenames = ["_variables.css", "_reset.css", "_global.css", "_templates.css"];
456
- const importsWithData = globalCssFilenames.filter((file) => {
457
- try {
458
- const data = readFileSync(join(destDir, "css", file), "utf8");
459
- return data.length > 0;
460
- } catch {
461
- return false;
462
- }
463
- });
464
- const globalImports = importsWithData.map((file) => `@import url('./css/${file}');`);
465
- const generatorText = "/*!\n * Generated with Salty CSS (https://salty-css.dev)\n * Do not edit this file directly\n */\n";
466
- let cssContent = `${generatorText}@layer reset, global, templates, l0, l1, l2, l3, l4, l5, l6, l7, l8;
467
-
468
- ${globalImports.join(
469
- "\n"
470
- )}
471
- ${otherGlobalCssFiles}`;
472
- if (config.importStrategy !== "component") {
473
- const mergedContent = cssFiles.reduce((acc, val, layer) => {
474
- const layerContent = val.reduce((layerAcc, file) => {
475
- var _a;
476
- const filepath = join(destDir, "css", file);
477
- const css = readFileSync(filepath, "utf8");
478
- const filepathHash = ((_a = /.*-([^-]+)-\d+.css/.exec(file)) == null ? void 0 : _a.at(1)) || toHash(filepath, 6);
479
- if (layerAcc.includes(filepathHash)) return layerAcc;
480
- return `${layerAcc}
481
- /*start:${filepathHash}-${file}*/
482
- ${css}
483
- /*end:${filepathHash}*/
484
- `;
485
- }, "");
486
- const layerFileName = `l_${layer}.css`;
487
- const layerFilePath = join(destDir, "css", layerFileName);
488
- const layerContentWithLayer = `@layer l${layer} { ${layerContent}
489
- }`;
490
- writeFileSync(layerFilePath, layerContentWithLayer);
491
- return `${acc}
492
- @import url('./css/${layerFileName}');`;
493
- }, "");
494
- cssContent += mergedContent;
495
- }
496
- writeFileSync(cssFile, cssContent);
497
- const end = Date.now();
498
- const time = end - start;
499
- const emoji = time < 200 ? "🔥" : time < 500 ? "🚀" : time < 1e3 ? "🎉" : time < 2e3 ? "🚗" : time < 5e3 ? "🤔" : "🥴";
500
- logger.info(`Generated CSS in ${time}ms! ${emoji}`);
501
- } catch (e) {
502
- console.error(e);
503
- }
504
- };
505
- const generateFile = async (dirname, file, prod = isProduction()) => {
506
- try {
507
- const destDir = await getDestDir(dirname);
508
- const validFile = isSaltyFile(file);
509
- if (validFile) {
510
- const cssFiles = [];
511
- const config = await getConfig(dirname);
512
- const { contents } = await compileSaltyFile(dirname, file, destDir);
513
- for (const [name, value] of Object.entries(contents)) {
514
- const resolved = await resolveExportValue(value, 1);
515
- if (resolved.isKeyframes && resolved.css) {
516
- const fileName = `a_${resolved.animationName}.css`;
517
- const filePath2 = `css/${fileName}`;
518
- const cssPath2 = join(destDir, filePath2);
519
- writeFileSync(cssPath2, await resolved.css);
520
- continue;
521
- }
522
- if (resolved.isClassName) {
523
- const generator2 = resolved.generator._withBuildContext({
524
- callerName: name,
525
- isProduction: prod,
526
- config
527
- });
528
- const styles2 = await generator2.css;
529
- if (!styles2) continue;
530
- if (!cssFiles[generator2.priority]) cssFiles[generator2.priority] = [];
531
- cssFiles[generator2.priority].push(generator2.cssFileName);
532
- const filePath2 = `css/${generator2.cssFileName}`;
533
- const cssPath2 = join(destDir, filePath2);
534
- writeFileSync(cssPath2, styles2);
535
- continue;
536
- }
537
- if (!resolved.generator) continue;
538
- const generator = resolved.generator._withBuildContext({
539
- callerName: name,
540
- isProduction: prod,
541
- config
542
- });
543
- const styles = await generator.css;
544
- if (!styles) continue;
545
- const filePath = `css/${generator.cssFileName}`;
546
- const cssPath = join(destDir, filePath);
547
- writeFileSync(cssPath, styles);
548
- if (!cssFiles[generator.priority]) cssFiles[generator.priority] = [];
549
- cssFiles[generator.priority].push(generator.cssFileName);
550
- }
551
- if (config.importStrategy !== "component") {
552
- cssFiles.forEach((val, layer) => {
553
- const layerFileName = `l_${layer}.css`;
554
- const layerFilePath = join(destDir, "css", layerFileName);
555
- let currentLayerFileContent = readFileSync(layerFilePath, "utf8");
556
- val.forEach((file2) => {
557
- var _a;
558
- const filepath = join(destDir, "css", file2);
559
- const filepathHash = ((_a = /.*-([^-]+)-\d+.css/.exec(file2)) == null ? void 0 : _a.at(1)) || toHash(filepath, 6);
560
- const found = currentLayerFileContent.includes(filepathHash);
561
- if (!found) {
562
- const css = readFileSync(filepath, "utf8");
563
- const newContent = `/*start:${filepathHash}-${file2}*/
564
- ${css}
565
- /*end:${filepathHash}*/
566
- `;
567
- currentLayerFileContent = `${currentLayerFileContent.replace(/\}$/, "")}
568
- ${newContent}
569
- }`;
570
- }
571
- });
572
- writeFileSync(layerFilePath, currentLayerFileContent);
573
- });
574
- } else {
575
- const cssContent = cssFiles.flat().map((file2) => `@import url('./${file2}');`).join("\n");
576
- const hashName = toHash(file, 6);
577
- const parsedPath = parse(file);
578
- const dasherized = dashCase(parsedPath.name);
579
- const cssFile = join(destDir, `css/f_${dasherized}-${hashName}.css`);
580
- writeFileSync(cssFile, cssContent || `/* Empty file */`);
581
- }
582
- }
583
- } catch (e) {
584
- console.error(e);
585
- }
586
- };
587
- const minimizeFile = async (dirname, file, prod = isProduction()) => {
588
- var _a, _b;
589
- try {
590
- const destDir = await getDestDir(dirname);
591
- const validFile = isSaltyFile(file);
592
- if (validFile) {
593
- const original = readFileSync(file, "utf8");
594
- const config = await getConfig(dirname);
595
- const { contents } = await compileSaltyFile(dirname, file, destDir);
596
- let current = original;
597
- for (const [name, value] of Object.entries(contents)) {
598
- const resolved = await resolveExportValue(value, 1);
599
- if (resolved.isKeyframes) continue;
600
- if (!resolved.generator) continue;
601
- const generator = resolved.generator._withBuildContext({
602
- callerName: name,
603
- isProduction: prod,
604
- config
605
- });
606
- const [start, end] = await getFunctionRange(current, name);
607
- const range = current.slice(start, end);
608
- if (resolved.isClassName) {
609
- const copy = current;
610
- const clientVersion = ` ${name} = className("${generator.classNames}")`;
611
- current = current.replace(range, clientVersion);
612
- if (copy === current) console.error("Minimize file failed to change content", { name });
613
- }
614
- if (range.includes("styled")) {
615
- const tagName = (_b = (_a = /styled\(([^,]+),/.exec(range)) == null ? void 0 : _a.at(1)) == null ? void 0 : _b.trim();
616
- const copy = current;
617
- const clientVersion = ` ${name} = styled(${tagName}, "${generator.classNames}", ${JSON.stringify(generator.clientProps)})`;
618
- current = current.replace(range, clientVersion);
619
- if (copy === current) console.error("Minimize file failed to change content", { name, tagName });
620
- }
621
- }
622
- if (config.importStrategy === "component") {
623
- const fileHash = toHash(file, 6);
624
- const parsed = parse(file);
625
- const dasherized = dashCase(parsed.name);
626
- const cssFileName = `f_${dasherized}-${fileHash}.css`;
627
- current = `import '../../saltygen/css/${cssFileName}';
628
- ${current}`;
629
- }
630
- current = current.replace(`@salty-css/react/class-name`, `@salty-css/react/class-name-client`);
631
- current = current.replace(`{ styled }`, `{ styledClient as styled }`);
632
- current = current.replace(`@salty-css/react/styled`, `@salty-css/react/styled-client`);
633
- return current;
634
- }
635
- } catch (e) {
636
- console.error("Error in minimizeFile:", e);
637
- }
638
- return void 0;
639
- };
640
- export {
641
- compileSaltyFile,
642
- generateConfigStyles,
643
- generateCss,
644
- generateFile,
645
- getConfig,
646
- getDestDir,
647
- isSaltyFile,
648
- minimizeFile,
649
- saltyFileExtensions,
650
- saltyFileRegExp
651
- };