@salty-css/core 0.0.1 → 0.1.0-alpha.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/bin/main.cjs CHANGED
@@ -6,7 +6,7 @@ const promises = require("fs/promises");
6
6
  const path = require("path");
7
7
  const ejs = require("ejs");
8
8
  const pascalCase = require("../pascal-case-By_l58S-.cjs");
9
- const compiler_asClass = require("../compiler/as-class.cjs");
9
+ const compiler_saltyCompiler = require("../compiler/salty-compiler.cjs");
10
10
  const child_process = require("child_process");
11
11
  const ora = require("ora");
12
12
  const shouldRestart = require("../should-restart-CQsyHls3.cjs");
@@ -35,9 +35,9 @@ async function formatWithPrettier(filePath) {
35
35
  const hasPrettier = hasPrettierInstalled();
36
36
  if (!hasPrettier) return;
37
37
  await execAsync(`./node_modules/.bin/prettier --write "${filePath}"`);
38
- compiler_asClass.logger.info(`Formatted ${filePath} with Prettier`);
38
+ compiler_saltyCompiler.logger.info(`Formatted ${filePath} with Prettier`);
39
39
  } catch (error) {
40
- compiler_asClass.logger.error(`Error formatting ${filePath} with Prettier:`, error);
40
+ compiler_saltyCompiler.logger.error(`Error formatting ${filePath} with Prettier:`, error);
41
41
  }
42
42
  }
43
43
  async function main() {
@@ -96,26 +96,26 @@ async function main() {
96
96
  };
97
97
  program.command("init [directory]").description("Initialize a new Salty-CSS project.").option("-d, --dir <dir>", "Project directory to initialize the project in.").option("--css-file <css-file>", "Existing CSS file where to import the generated CSS. Path must be relative to the given project directory.").option("--skip-install", "Skip installing dependencies.").action(async function(_dir = ".") {
98
98
  const packageJson = await readPackageJson().catch(() => void 0);
99
- if (!packageJson) return compiler_asClass.logError("Salty CSS project must be initialized in a directory with a package.json file.");
100
- compiler_asClass.logger.info("Initializing a new Salty-CSS project!");
99
+ if (!packageJson) return compiler_saltyCompiler.logError("Salty CSS project must be initialized in a directory with a package.json file.");
100
+ compiler_saltyCompiler.logger.info("Initializing a new Salty-CSS project!");
101
101
  const { dir = _dir, cssFile, skipInstall } = this.opts();
102
- if (!dir) return compiler_asClass.logError("Project directory must be provided. Add it as the first argument after init command or use the --dir option.");
102
+ if (!dir) return compiler_saltyCompiler.logError("Project directory must be provided. Add it as the first argument after init command or use the --dir option.");
103
103
  if (!skipInstall) await npmInstall(packages.core, packages.react);
104
104
  const rootDir = process.cwd();
105
105
  const projectDir = resolveProjectDir(dir);
106
106
  const projectFiles = await Promise.all([readTemplate("salty.config.ts"), readTemplate("saltygen/index.css")]);
107
- const saltyCompiler = new compiler_asClass.SaltyCompiler(projectDir);
107
+ const saltyCompiler = new compiler_saltyCompiler.SaltyCompiler(projectDir);
108
108
  await promises.mkdir(projectDir, { recursive: true });
109
109
  const writeFiles = projectFiles.map(async ({ fileName, content }) => {
110
110
  const filePath = path.join(projectDir, fileName);
111
111
  const existingContent = await promises.readFile(filePath, "utf-8").catch(() => void 0);
112
112
  if (existingContent !== void 0) {
113
- compiler_asClass.logger.debug("File already exists: " + filePath);
113
+ compiler_saltyCompiler.logger.debug("File already exists: " + filePath);
114
114
  return;
115
115
  }
116
116
  const additionalFolders = fileName.split("/").slice(0, -1).join("/");
117
117
  if (additionalFolders) await promises.mkdir(path.join(projectDir, additionalFolders), { recursive: true });
118
- compiler_asClass.logger.info("Creating file: " + filePath);
118
+ compiler_saltyCompiler.logger.info("Creating file: " + filePath);
119
119
  await promises.writeFile(filePath, content);
120
120
  await formatWithPrettier(filePath);
121
121
  });
@@ -124,7 +124,7 @@ async function main() {
124
124
  const saltyrcPath = path.join(rootDir, ".saltyrc.json");
125
125
  const existingSaltyrc = await promises.readFile(saltyrcPath, "utf-8").catch(() => void 0);
126
126
  if (existingSaltyrc === void 0) {
127
- compiler_asClass.logger.info("Creating file: " + saltyrcPath);
127
+ compiler_saltyCompiler.logger.info("Creating file: " + saltyrcPath);
128
128
  const rcContent = {
129
129
  $schema: "./node_modules/@salty-css/core/.saltyrc.schema.json",
130
130
  info: "This file is used to define projects and their configurations for Salty CSS cli. Do not delete, modify or add this file to .gitignore.",
@@ -148,7 +148,7 @@ async function main() {
148
148
  rcContent.projects = [...projects];
149
149
  const content = JSON.stringify(rcContent, null, 2);
150
150
  if (content !== existingSaltyrc) {
151
- compiler_asClass.logger.info("Edit file: " + saltyrcPath);
151
+ compiler_saltyCompiler.logger.info("Edit file: " + saltyrcPath);
152
152
  await promises.writeFile(saltyrcPath, content);
153
153
  await formatWithPrettier(saltyrcPath);
154
154
  }
@@ -159,7 +159,7 @@ async function main() {
159
159
  if (gitIgnoreContent !== void 0) {
160
160
  const alreadyIgnoresSaltygen = gitIgnoreContent.includes("saltygen");
161
161
  if (!alreadyIgnoresSaltygen) {
162
- compiler_asClass.logger.info("Edit file: " + gitIgnorePath);
162
+ compiler_saltyCompiler.logger.info("Edit file: " + gitIgnorePath);
163
163
  await promises.writeFile(gitIgnorePath, gitIgnoreContent + "\n\n# Salty-CSS\nsaltygen\n");
164
164
  }
165
165
  }
@@ -195,13 +195,13 @@ async function main() {
195
195
  const cssFileFolder = path.join(cssFilePath, "..");
196
196
  const relativePath = path.relative(cssFileFolder, path.join(projectDir, "saltygen/index.css"));
197
197
  const importStatement = `@import '${relativePath}';`;
198
- compiler_asClass.logger.info("Adding global import statement to CSS file: " + cssFilePath);
198
+ compiler_saltyCompiler.logger.info("Adding global import statement to CSS file: " + cssFilePath);
199
199
  await promises.writeFile(cssFilePath, importStatement + "\n" + cssFileContent);
200
200
  await formatWithPrettier(cssFilePath);
201
201
  }
202
202
  }
203
203
  } else {
204
- compiler_asClass.logger.warn("Could not find a CSS file to import the generated CSS. Please add it manually.");
204
+ compiler_saltyCompiler.logger.warn("Could not find a CSS file to import the generated CSS. Please add it manually.");
205
205
  }
206
206
  const eslintConfigs = {
207
207
  projectJs: path.join(projectDir, "eslint.config.js"),
@@ -215,10 +215,10 @@ async function main() {
215
215
  if (eslintConfigToUse) {
216
216
  if (!skipInstall) await npmInstall(packages.eslintConfigCore);
217
217
  const eslintConfigContent = await promises.readFile(eslintConfigToUse, "utf-8").catch(() => void 0);
218
- if (!eslintConfigContent) return compiler_asClass.logError("Could not read ESLint config file.");
218
+ if (!eslintConfigContent) return compiler_saltyCompiler.logError("Could not read ESLint config file.");
219
219
  const alreadyHasSaltyConfig = eslintConfigContent.includes("salty-css");
220
220
  if (!alreadyHasSaltyConfig) {
221
- compiler_asClass.logger.info("Edit file: " + eslintConfigToUse);
221
+ compiler_saltyCompiler.logger.info("Edit file: " + eslintConfigToUse);
222
222
  if (eslintConfigToUse.endsWith("js")) {
223
223
  const importStatement = 'import saltyCss from "@salty-css/eslint-config-core/flat";';
224
224
  let newContent = `${importStatement}
@@ -226,11 +226,11 @@ ${eslintConfigContent}`;
226
226
  const isTsEslint = eslintConfigContent.includes("typescript-eslint");
227
227
  if (isTsEslint) {
228
228
  if (newContent.includes(".config(")) newContent = newContent.replace(".config(", ".config(saltyCss,");
229
- else compiler_asClass.logger.warn("Could not find the correct place to add the Salty-CSS config for ESLint. Please add it manually.");
229
+ else compiler_saltyCompiler.logger.warn("Could not find the correct place to add the Salty-CSS config for ESLint. Please add it manually.");
230
230
  } else {
231
231
  if (newContent.includes("export default [")) newContent = newContent.replace("export default [", "export default [ saltyCss,");
232
232
  else if (newContent.includes("eslintConfig = [")) newContent = newContent.replace("eslintConfig = [", "eslintConfig = [ saltyCss,");
233
- else compiler_asClass.logger.warn("Could not find the correct place to add the Salty-CSS config for ESLint. Please add it manually.");
233
+ else compiler_saltyCompiler.logger.warn("Could not find the correct place to add the Salty-CSS config for ESLint. Please add it manually.");
234
234
  }
235
235
  await promises.writeFile(eslintConfigToUse, newContent);
236
236
  await formatWithPrettier(eslintConfigToUse);
@@ -249,13 +249,13 @@ ${eslintConfigContent}`;
249
249
  if (viteConfigContent !== void 0) {
250
250
  const alreadyHasPlugin = viteConfigContent.includes("saltyPlugin");
251
251
  if (!alreadyHasPlugin) {
252
- compiler_asClass.logger.info("Edit file: " + viteConfigPath);
252
+ compiler_saltyCompiler.logger.info("Edit file: " + viteConfigPath);
253
253
  const pluginImport = "import { saltyPlugin } from '@salty-css/vite';\n";
254
254
  const pluginConfig = "saltyPlugin(__dirname),";
255
255
  const newContent = viteConfigContent.replace(/(plugins: \[)/, `$1
256
256
  ${pluginConfig}`);
257
257
  if (!skipInstall) await npmInstall(`-D ${packages.vite}`);
258
- compiler_asClass.logger.info("Adding Salty-CSS plugin to Vite config...");
258
+ compiler_saltyCompiler.logger.info("Adding Salty-CSS plugin to Vite config...");
259
259
  await promises.writeFile(viteConfigPath, pluginImport + newContent);
260
260
  await formatWithPrettier(viteConfigPath);
261
261
  }
@@ -288,46 +288,46 @@ ${eslintConfigContent}`;
288
288
  });
289
289
  }
290
290
  if (!skipInstall) await npmInstall(`-D ${packages.next}`);
291
- compiler_asClass.logger.info("Adding Salty-CSS plugin to Next.js config...");
291
+ compiler_saltyCompiler.logger.info("Adding Salty-CSS plugin to Next.js config...");
292
292
  await promises.writeFile(nextConfigPath, pluginImport + nextConfigContent);
293
293
  await formatWithPrettier(nextConfigPath);
294
294
  }
295
295
  }
296
296
  }
297
- const packageJsonContent = await readPackageJson().catch(() => compiler_asClass.logError("Could not read package.json file.")).then((content) => {
297
+ const packageJsonContent = await readPackageJson().catch(() => compiler_saltyCompiler.logError("Could not read package.json file.")).then((content) => {
298
298
  if (!content.scripts) content.scripts = {};
299
299
  if (content.scripts.prepare) {
300
300
  const alreadyHasSaltyCss = content.scripts.prepare.includes("salty-css");
301
301
  if (!alreadyHasSaltyCss) {
302
- compiler_asClass.logger.info("Edit file: " + defaultPackageJsonPath);
302
+ compiler_saltyCompiler.logger.info("Edit file: " + defaultPackageJsonPath);
303
303
  content.scripts.prepare = content.scripts.prepare + " && npx salty-css build";
304
304
  }
305
305
  } else {
306
- compiler_asClass.logger.info("Edit file: " + defaultPackageJsonPath);
306
+ compiler_saltyCompiler.logger.info("Edit file: " + defaultPackageJsonPath);
307
307
  content.scripts.prepare = "npx salty-css build";
308
308
  }
309
309
  return content;
310
310
  });
311
311
  await updatePackageJson(packageJsonContent);
312
- compiler_asClass.logger.info("Running the build to generate initial CSS...");
312
+ compiler_saltyCompiler.logger.info("Running the build to generate initial CSS...");
313
313
  await saltyCompiler.generateCss();
314
- compiler_asClass.logger.info("🎉 Salty CSS project initialized successfully!");
315
- compiler_asClass.logger.info("Next steps:");
316
- compiler_asClass.logger.info("1. Configure variables and templates in `salty.config.ts`");
317
- compiler_asClass.logger.info("2. Create a new component with `npx salty-css generate [component-name]`");
318
- compiler_asClass.logger.info("3. Run `npx salty-css build` to generate the CSS");
319
- compiler_asClass.logger.info("4. Read about the features in the documentation: https://salty-css.dev");
320
- compiler_asClass.logger.info("5. Star the project on GitHub: https://github.com/margarita-form/salty-css ⭐");
314
+ compiler_saltyCompiler.logger.info("🎉 Salty CSS project initialized successfully!");
315
+ compiler_saltyCompiler.logger.info("Next steps:");
316
+ compiler_saltyCompiler.logger.info("1. Configure variables and templates in `salty.config.ts`");
317
+ compiler_saltyCompiler.logger.info("2. Create a new component with `npx salty-css generate [component-name]`");
318
+ compiler_saltyCompiler.logger.info("3. Run `npx salty-css build` to generate the CSS");
319
+ compiler_saltyCompiler.logger.info("4. Read about the features in the documentation: https://salty-css.dev");
320
+ compiler_saltyCompiler.logger.info("5. Star the project on GitHub: https://github.com/margarita-form/salty-css ⭐");
321
321
  });
322
322
  program.command("build [directory]").alias("b").description("Build the Salty-CSS project.").option("-d, --dir <dir>", "Project directory to build the project in.").option("--watch", "Watch for changes and rebuild the project.").action(async function(_dir = defaultProject) {
323
- compiler_asClass.logger.info("Building the Salty-CSS project...");
323
+ compiler_saltyCompiler.logger.info("Building the Salty-CSS project...");
324
324
  const { dir = _dir, watch } = this.opts();
325
- if (!dir) return compiler_asClass.logError("Project directory must be provided. Add it as the first argument after build command or use the --dir option.");
325
+ if (!dir) return compiler_saltyCompiler.logError("Project directory must be provided. Add it as the first argument after build command or use the --dir option.");
326
326
  const projectDir = resolveProjectDir(dir);
327
- const saltyCompiler = new compiler_asClass.SaltyCompiler(projectDir);
327
+ const saltyCompiler = new compiler_saltyCompiler.SaltyCompiler(projectDir);
328
328
  await saltyCompiler.generateCss();
329
329
  if (watch) {
330
- compiler_asClass.logger.info("Watching for changes in the project directory...");
330
+ compiler_saltyCompiler.logger.info("Watching for changes in the project directory...");
331
331
  fs.watch(projectDir, { recursive: true }, async (event, filePath) => {
332
332
  const shouldRestart$1 = await shouldRestart.checkShouldRestart(filePath);
333
333
  if (shouldRestart$1) {
@@ -341,8 +341,8 @@ ${eslintConfigContent}`;
341
341
  });
342
342
  program.command("generate [file] [directory]").alias("g").description("Generate a new component file.").option("-f, --file <file>", "File to generate.").option("-d, --dir <dir>", "Project directory to generate the file in.").option("-t, --tag <tag>", "HTML tag of the component.", "div").option("-n, --name <name>", "Name of the component.").option("-c, --className <className>", "CSS class of the component.").option("-r, --reactComponent", "Generate a React component as well.").action(async function(_file, _dir = defaultProject) {
343
343
  const { file = _file, dir = _dir, tag, name, className, reactComponent = false } = this.opts();
344
- if (!file) return compiler_asClass.logError("File to generate must be provided. Add it as the first argument after generate command or use the --file option.");
345
- if (!dir) return compiler_asClass.logError("Project directory must be provided. Add it as the second argument after generate command or use the --dir option.");
344
+ if (!file) return compiler_saltyCompiler.logError("File to generate must be provided. Add it as the first argument after generate command or use the --file option.");
345
+ if (!dir) return compiler_saltyCompiler.logError("Project directory must be provided. Add it as the second argument after generate command or use the --dir option.");
346
346
  const projectDir = resolveProjectDir(dir);
347
347
  const additionalFolders = file.split("/").slice(0, -1).join("/");
348
348
  if (additionalFolders) await promises.mkdir(path.join(projectDir, additionalFolders), { recursive: true });
@@ -358,7 +358,7 @@ ${eslintConfigContent}`;
358
358
  const formattedStyledFilePath = path.format(parsedFilePath);
359
359
  const alreadyExists = await promises.readFile(formattedStyledFilePath, "utf-8").catch(() => void 0);
360
360
  if (alreadyExists !== void 0) {
361
- compiler_asClass.logger.error("File already exists:", formattedStyledFilePath);
361
+ compiler_saltyCompiler.logger.error("File already exists:", formattedStyledFilePath);
362
362
  return;
363
363
  }
364
364
  let styledComponentName = pascalCase.pascalCase(name || parsedFilePath.base.replace(/\.css\.\w+$/, ""));
@@ -371,23 +371,23 @@ ${eslintConfigContent}`;
371
371
  parsedFilePath.ext = ".tsx";
372
372
  parsedFilePath.base = parsedFilePath.name + parsedFilePath.ext;
373
373
  const formattedReactFilePath = path.format(parsedFilePath);
374
- compiler_asClass.logger.info("Generating a new file: " + formattedReactFilePath);
374
+ compiler_saltyCompiler.logger.info("Generating a new file: " + formattedReactFilePath);
375
375
  await promises.writeFile(formattedReactFilePath, reactContent);
376
376
  await formatWithPrettier(formattedReactFilePath);
377
377
  }
378
378
  const { content } = await readTemplate("react/react-styled-file.ts", { tag, name: styledComponentName, className });
379
- compiler_asClass.logger.info("Generating a new file: " + formattedStyledFilePath);
379
+ compiler_saltyCompiler.logger.info("Generating a new file: " + formattedStyledFilePath);
380
380
  await promises.writeFile(formattedStyledFilePath, content);
381
381
  await formatWithPrettier(formattedStyledFilePath);
382
382
  });
383
383
  const getSaltyCssPackages = async () => {
384
384
  const packageJSONPath = path.join(process.cwd(), "package.json");
385
- const packageJson = await readPackageJson(packageJSONPath).catch((err) => compiler_asClass.logError(err));
386
- if (!packageJson) return compiler_asClass.logError("Could not read package.json file.");
385
+ const packageJson = await readPackageJson(packageJSONPath).catch((err) => compiler_saltyCompiler.logError(err));
386
+ if (!packageJson) return compiler_saltyCompiler.logError("Could not read package.json file.");
387
387
  const allDependencies = { ...packageJson.dependencies, ...packageJson.devDependencies };
388
388
  const saltyCssPackages = Object.entries(allDependencies).filter(([name]) => name === "salty-css" || name.startsWith("@salty-css/"));
389
389
  if (!saltyCssPackages.length) {
390
- return compiler_asClass.logError(
390
+ return compiler_saltyCompiler.logError(
391
391
  "No Salty-CSS packages found in package.json. Make sure you are running update command in the same directory! Used package.json path: " + packageJSONPath
392
392
  );
393
393
  }
@@ -396,19 +396,19 @@ ${eslintConfigContent}`;
396
396
  program.command("update [version]").alias("up").description("Update Salty-CSS packages to the latest or specified version.").option("-v, --version <version>", "Version to update to.").option("--legacy-peer-deps <legacyPeerDeps>", "Use legacy peer dependencies (not recommended).", false).action(async function(_version = "latest") {
397
397
  const { legacyPeerDeps, version = _version } = this.opts();
398
398
  const saltyCssPackages = await getSaltyCssPackages();
399
- if (!saltyCssPackages) return compiler_asClass.logError("Could not update Salty-CSS packages as any were found in package.json.");
399
+ if (!saltyCssPackages) return compiler_saltyCompiler.logError("Could not update Salty-CSS packages as any were found in package.json.");
400
400
  const packagesToUpdate = saltyCssPackages.map(([name]) => {
401
401
  if (version === "@") return `${name}@${currentPackageJson.version}`;
402
402
  return `${name}@${version.replace(/^@/, "")}`;
403
403
  });
404
404
  if (legacyPeerDeps) {
405
- compiler_asClass.logger.warn("Using legacy peer dependencies to update packages.");
405
+ compiler_saltyCompiler.logger.warn("Using legacy peer dependencies to update packages.");
406
406
  await npmInstall(...packagesToUpdate, "--legacy-peer-deps");
407
407
  } else {
408
408
  await npmInstall(...packagesToUpdate);
409
409
  }
410
410
  const updatedPackages = await getSaltyCssPackages();
411
- if (!updatedPackages) return compiler_asClass.logError("Something went wrong while reading the updated packages.");
411
+ if (!updatedPackages) return compiler_saltyCompiler.logError("Something went wrong while reading the updated packages.");
412
412
  const mappedByVersions = updatedPackages.reduce((acc, [name, version2]) => {
413
413
  if (!acc[version2]) acc[version2] = [];
414
414
  acc[version2].push(name);
@@ -418,29 +418,29 @@ ${eslintConfigContent}`;
418
418
  if (versionsCount === 1) {
419
419
  const version2 = Object.keys(mappedByVersions)[0];
420
420
  const versionString = version2.replace(/^\^/, "");
421
- compiler_asClass.logger.info(`Updated to all Salty CSS packages successfully to ${versionString}`);
421
+ compiler_saltyCompiler.logger.info(`Updated to all Salty CSS packages successfully to ${versionString}`);
422
422
  } else {
423
423
  for (const [version2, names] of Object.entries(mappedByVersions)) {
424
424
  const versionString = version2.replace(/^\^/, "");
425
- compiler_asClass.logger.info(`Updated to ${versionString}: ${names.join(", ")}`);
425
+ compiler_saltyCompiler.logger.info(`Updated to ${versionString}: ${names.join(", ")}`);
426
426
  }
427
427
  }
428
428
  });
429
429
  program.option("-v, --version", "Show the current version of Salty-CSS.").action(async function() {
430
430
  const currentPackageJson2 = await readThisPackageJson();
431
- compiler_asClass.logger.info("CLI is running: " + currentPackageJson2.version);
431
+ compiler_saltyCompiler.logger.info("CLI is running: " + currentPackageJson2.version);
432
432
  const packageJSONPath = path.join(process.cwd(), "package.json");
433
- const packageJson = await readPackageJson(packageJSONPath).catch((err) => compiler_asClass.logError(err));
433
+ const packageJson = await readPackageJson(packageJSONPath).catch((err) => compiler_saltyCompiler.logError(err));
434
434
  if (!packageJson) return;
435
435
  const allDependencies = { ...packageJson.dependencies, ...packageJson.devDependencies };
436
436
  const saltyCssPackages = Object.keys(allDependencies).filter((dep) => dep === "salty-css" || dep.startsWith("@salty-css/"));
437
437
  if (!saltyCssPackages.length) {
438
- return compiler_asClass.logError(
438
+ return compiler_saltyCompiler.logError(
439
439
  "No Salty-CSS packages found in package.json. Make sure you are running update command in the same directory! Used package.json path: " + packageJSONPath
440
440
  );
441
441
  }
442
442
  for (const dep of saltyCssPackages) {
443
- compiler_asClass.logger.info(`${dep}: ${allDependencies[dep]}`);
443
+ compiler_saltyCompiler.logger.info(`${dep}: ${allDependencies[dep]}`);
444
444
  }
445
445
  });
446
446
  program.parseAsync(process.argv);
package/bin/main.js CHANGED
@@ -4,7 +4,7 @@ import { mkdir, readFile, writeFile } from "fs/promises";
4
4
  import { join, relative, parse, format } from "path";
5
5
  import ejs from "ejs";
6
6
  import { p as pascalCase } from "../pascal-case-F3Usi5Wf.js";
7
- import { l as logger, a as logError, SaltyCompiler } from "../compiler/as-class.js";
7
+ import { l as logger, a as logError, SaltyCompiler } from "../compiler/salty-compiler.js";
8
8
  import { exec } from "child_process";
9
9
  import ora from "ora";
10
10
  import { c as checkShouldRestart } from "../should-restart-CXIO0jxY.js";
@@ -16,7 +16,8 @@ const resolveExportValue = async (value, maxLevel = 10, _level = 0) => {
16
16
  return value;
17
17
  };
18
18
  const saltyFileExtensions = ["salty", "css", "styles", "styled"];
19
- const saltyFileRegExp = (additional = []) => new RegExp(`\\.(${[...saltyFileExtensions, ...additional].join("|")})\\.`);
19
+ const escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
20
+ const saltyFileRegExp = (additional = []) => new RegExp(`\\.(${[...saltyFileExtensions, ...additional].map(escapeRegExp).join("|")})\\.`);
20
21
  const isSaltyFile = (file, additional = []) => saltyFileRegExp(additional).test(file);
21
22
  exports.getCorePackageRoot = getCorePackageRoot;
22
23
  exports.isSaltyFile = isSaltyFile;
@@ -13,7 +13,8 @@ const resolveExportValue = async (value, maxLevel = 10, _level = 0) => {
13
13
  return value;
14
14
  };
15
15
  const saltyFileExtensions = ["salty", "css", "styles", "styled"];
16
- const saltyFileRegExp = (additional = []) => new RegExp(`\\.(${[...saltyFileExtensions, ...additional].join("|")})\\.`);
16
+ const escapeRegExp = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
17
+ const saltyFileRegExp = (additional = []) => new RegExp(`\\.(${[...saltyFileExtensions, ...additional].map(escapeRegExp).join("|")})\\.`);
17
18
  const isSaltyFile = (file, additional = []) => saltyFileRegExp(additional).test(file);
18
19
  export {
19
20
  getCorePackageRoot,
@@ -18,7 +18,6 @@ const css_merge = require("../css/merge.cjs");
18
18
  const compiler_getFiles = require("./get-files.cjs");
19
19
  const parsers_index = require("../parsers/index.cjs");
20
20
  const console = require("console");
21
- const compiler_getFunctionRange = require("./get-function-range.cjs");
22
21
  var _documentCurrentScript = typeof document !== "undefined" ? document.currentScript : null;
23
22
  function _interopNamespaceDefault(e) {
24
23
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
@@ -56,7 +55,7 @@ const detectCurrentModuleType = async (dirname) => {
56
55
  const packageJsonModule = await readPackageJsonModule(dirname);
57
56
  if (packageJsonModule === "module") cachedModuleType = "esm";
58
57
  else if (packageJsonModule === "commonjs") cachedModuleType = "cjs";
59
- else if ((typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("compiler/as-class.cjs", document.baseURI).href).endsWith(".cjs")) cachedModuleType = "cjs";
58
+ else if ((typeof document === "undefined" ? require("url").pathToFileURL(__filename).href : _documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === "SCRIPT" && _documentCurrentScript.src || new URL("compiler/salty-compiler.cjs", document.baseURI).href).endsWith(".cjs")) cachedModuleType = "cjs";
60
59
  return cachedModuleType || "esm";
61
60
  };
62
61
  function dotCase(str) {
@@ -584,58 +583,13 @@ ${css}
584
583
  const contents = await this.importFile(outputFilePath);
585
584
  return { contents, outputFilePath };
586
585
  });
587
- __publicField(this, "minimizeFile", async (file) => {
588
- var _a, _b;
589
- try {
590
- const destDir = await this.getDestDir();
591
- const validFile = compiler_helpers.isSaltyFile(file);
592
- if (validFile) {
593
- const original = fs.readFileSync(file, "utf8");
594
- const config = await this.getConfig();
595
- const { contents } = await this.compileSaltyFile(file, destDir);
596
- let current = original;
597
- for (const [name, value] of Object.entries(contents)) {
598
- const resolved = await compiler_helpers.resolveExportValue(value, 1);
599
- if (resolved.isKeyframes) continue;
600
- if (!resolved.generator) continue;
601
- const generator = resolved.generator._withBuildContext({
602
- callerName: name,
603
- isProduction: this.isProduction,
604
- config
605
- });
606
- const [start, end] = await compiler_getFunctionRange.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.toHash(file, 6);
624
- const parsed = path.parse(file);
625
- const dasherized = dashCase.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;
586
+ /**
587
+ * Read the framework field from the current project's entry in `.saltyrc.json`.
588
+ * Used by framework-aware bundler plugins to dispatch to the right transform.
589
+ */
590
+ __publicField(this, "getFramework", async () => {
591
+ const projectConfig = await this.getRCProjectConfig(this.projectRootDir);
592
+ return projectConfig == null ? void 0 : projectConfig.framework;
639
593
  });
640
594
  __publicField(this, "generateFile", async (file) => {
641
595
  try {
@@ -1,9 +1,10 @@
1
+ import { CachedConfig, SaltyConfig } from '../config';
1
2
  export declare class SaltyCompiler {
2
3
  projectRootDir: string;
3
4
  importFile: (path: string) => Promise<any>;
4
5
  private cache;
5
6
  constructor(projectRootDir: string);
6
- private get isProduction();
7
+ get isProduction(): boolean;
7
8
  /**
8
9
  * Locate and read the .saltyrc.json file starting from the current directory and moving up the directory tree.
9
10
  * Caches the result to avoid redundant file reads.
@@ -23,7 +24,7 @@ export declare class SaltyCompiler {
23
24
  private generateConfig;
24
25
  private addConfigCache;
25
26
  private getConfigCache;
26
- private getConfig;
27
+ getConfig: () => Promise<SaltyConfig & CachedConfig>;
27
28
  /**
28
29
  * Generate CSS files based on the Salty CSS configuration and source files.
29
30
  */
@@ -46,7 +47,11 @@ export declare class SaltyCompiler {
46
47
  };
47
48
  outputFilePath: string;
48
49
  }>;
49
- minimizeFile: (file: string) => Promise<string | undefined>;
50
+ /**
51
+ * Read the framework field from the current project's entry in `.saltyrc.json`.
52
+ * Used by framework-aware bundler plugins to dispatch to the right transform.
53
+ */
54
+ getFramework: () => Promise<string | undefined>;
50
55
  generateFile: (file: string) => Promise<void>;
51
56
  private replaceStyledTag;
52
57
  }
@@ -16,7 +16,6 @@ import { mergeObjects, mergeFactories } from "../css/merge.js";
16
16
  import { getPackageJson } from "./get-files.js";
17
17
  import { parseTemplates, getTemplateTypes } from "../parsers/index.js";
18
18
  import console from "console";
19
- import { getFunctionRange } from "./get-function-range.js";
20
19
  const logger = createLogger({
21
20
  level: "debug",
22
21
  format: format.combine(format.colorize(), format.cli()),
@@ -564,58 +563,13 @@ ${css}
564
563
  const contents = await this.importFile(outputFilePath);
565
564
  return { contents, outputFilePath };
566
565
  });
567
- __publicField(this, "minimizeFile", async (file) => {
568
- var _a, _b;
569
- try {
570
- const destDir = await this.getDestDir();
571
- const validFile = isSaltyFile(file);
572
- if (validFile) {
573
- const original = readFileSync(file, "utf8");
574
- const config = await this.getConfig();
575
- const { contents } = await this.compileSaltyFile(file, destDir);
576
- let current = original;
577
- for (const [name, value] of Object.entries(contents)) {
578
- const resolved = await resolveExportValue(value, 1);
579
- if (resolved.isKeyframes) continue;
580
- if (!resolved.generator) continue;
581
- const generator = resolved.generator._withBuildContext({
582
- callerName: name,
583
- isProduction: this.isProduction,
584
- config
585
- });
586
- const [start, end] = await getFunctionRange(current, name);
587
- const range = current.slice(start, end);
588
- if (resolved.isClassName) {
589
- const copy = current;
590
- const clientVersion = ` ${name} = className("${generator.classNames}")`;
591
- current = current.replace(range, clientVersion);
592
- if (copy === current) console.error("Minimize file failed to change content", { name });
593
- }
594
- if (range.includes("styled")) {
595
- const tagName = (_b = (_a = /styled\(([^,]+),/.exec(range)) == null ? void 0 : _a.at(1)) == null ? void 0 : _b.trim();
596
- const copy = current;
597
- const clientVersion = ` ${name} = styled(${tagName}, "${generator.classNames}", ${JSON.stringify(generator.clientProps)})`;
598
- current = current.replace(range, clientVersion);
599
- if (copy === current) console.error("Minimize file failed to change content", { name, tagName });
600
- }
601
- }
602
- if (config.importStrategy === "component") {
603
- const fileHash = toHash(file, 6);
604
- const parsed = parse(file);
605
- const dasherized = dashCase(parsed.name);
606
- const cssFileName = `f_${dasherized}-${fileHash}.css`;
607
- current = `import '../../saltygen/css/${cssFileName}';
608
- ${current}`;
609
- }
610
- current = current.replace(`@salty-css/react/class-name`, `@salty-css/react/class-name-client`);
611
- current = current.replace(`{ styled }`, `{ styledClient as styled }`);
612
- current = current.replace(`@salty-css/react/styled`, `@salty-css/react/styled-client`);
613
- return current;
614
- }
615
- } catch (e) {
616
- console.error("Error in minimizeFile:", e);
617
- }
618
- return void 0;
566
+ /**
567
+ * Read the framework field from the current project's entry in `.saltyrc.json`.
568
+ * Used by framework-aware bundler plugins to dispatch to the right transform.
569
+ */
570
+ __publicField(this, "getFramework", async () => {
571
+ const projectConfig = await this.getRCProjectConfig(this.projectRootDir);
572
+ return projectConfig == null ? void 0 : projectConfig.framework;
619
573
  });
620
574
  __publicField(this, "generateFile", async (file) => {
621
575
  try {
package/css/keyframes.cjs CHANGED
@@ -26,7 +26,7 @@ const keyframes = ({ animationName: _name, params: _params, appendInitialStyles,
26
26
  const promises = entries.map(async ([key, value]) => {
27
27
  if (!value) return "";
28
28
  const styles = await parseStyles.parseAndJoinStyles(value, "");
29
- const keyStr = typeof key === "number" ? `${key}%` : key;
29
+ const keyStr = /^-?\d+$/.test(key) ? `${key}%` : key;
30
30
  return `${keyStr}{${styles}}`;
31
31
  });
32
32
  const resolved = await Promise.all(promises);
package/css/keyframes.js CHANGED
@@ -24,7 +24,7 @@ const keyframes = ({ animationName: _name, params: _params, appendInitialStyles,
24
24
  const promises = entries.map(async ([key, value]) => {
25
25
  if (!value) return "";
26
26
  const styles = await parseAndJoinStyles(value, "");
27
- const keyStr = typeof key === "number" ? `${key}%` : key;
27
+ const keyStr = /^-?\d+$/.test(key) ? `${key}%` : key;
28
28
  return `${keyStr}{${styles}}`;
29
29
  });
30
30
  const resolved = await Promise.all(promises);
package/css/merge.cjs CHANGED
@@ -2,7 +2,8 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const mergeObjects = (...styles) => {
4
4
  return styles.flat().reduce((acc, style) => {
5
- if (style == null ? void 0 : style._current) return { ...acc, ...style._current };
5
+ if (!style || typeof style !== "object") return acc;
6
+ if ("_current" in style && style._current && typeof style._current === "object") return { ...acc, ...style._current };
6
7
  return { ...acc, ...style };
7
8
  }, {});
8
9
  };
package/css/merge.js CHANGED
@@ -1,6 +1,7 @@
1
1
  const mergeObjects = (...styles) => {
2
2
  return styles.flat().reduce((acc, style) => {
3
- if (style == null ? void 0 : style._current) return { ...acc, ...style._current };
3
+ if (!style || typeof style !== "object") return acc;
4
+ if ("_current" in style && style._current && typeof style._current === "object") return { ...acc, ...style._current };
4
5
  return { ...acc, ...style };
5
6
  }, {});
6
7
  };
@@ -11,7 +11,7 @@ class StyledGenerator extends classNameGenerator.StylesGenerator {
11
11
  get priority() {
12
12
  var _a;
13
13
  if (this.params.priority) return this.params.priority;
14
- if (typeof this.tagName === "function" || typeof this.tagName === "object") {
14
+ if (this.tagName && (typeof this.tagName === "function" || typeof this.tagName === "object")) {
15
15
  const prev = ((_a = this.tagName.generator) == null ? void 0 : _a.priority) || 0;
16
16
  return prev + 1;
17
17
  }
@@ -10,7 +10,7 @@ class StyledGenerator extends StylesGenerator {
10
10
  get priority() {
11
11
  var _a;
12
12
  if (this.params.priority) return this.params.priority;
13
- if (typeof this.tagName === "function" || typeof this.tagName === "object") {
13
+ if (this.tagName && (typeof this.tagName === "function" || typeof this.tagName === "object")) {
14
14
  const prev = ((_a = this.tagName.generator) == null ? void 0 : _a.priority) || 0;
15
15
  return prev + 1;
16
16
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salty-css/core",
3
- "version": "0.0.1",
3
+ "version": "0.1.0-alpha.1",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "typings": "./dist/index.d.ts",
@@ -47,9 +47,9 @@
47
47
  "import": "./bin/main.js",
48
48
  "require": "./bin/main.cjs"
49
49
  },
50
- "./compiler/as-class": {
51
- "import": "./compiler/as-class.js",
52
- "require": "./compiler/as-class.cjs"
50
+ "./compiler/salty-compiler": {
51
+ "import": "./compiler/salty-compiler.js",
52
+ "require": "./compiler/salty-compiler.cjs"
53
53
  },
54
54
  "./compiler/get-files": {
55
55
  "import": "./compiler/get-files.js",