@salty-css/core 0.1.0-alpha.16 → 0.1.0-alpha.18

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.
@@ -21,3 +21,14 @@ export interface ConfirmInstallOptions {
21
21
  * (case-insensitive); anything else throws to abort the command.
22
22
  */
23
23
  export declare const confirmInstall: (packages: string[], yes: boolean, options?: ConfirmInstallOptions) => Promise<void>;
24
+ export interface ConfirmYesNoOptions extends ConfirmInstallOptions {
25
+ /** When true, resolves true without prompting. */
26
+ yes?: boolean;
27
+ /** When true, an empty answer counts as yes. Defaults to false (empty = no). */
28
+ defaultYes?: boolean;
29
+ }
30
+ /**
31
+ * Generic yes/no prompt. Unlike `confirmInstall`, non-TTY without `yes`
32
+ * resolves `false` instead of throwing — callers can choose policy.
33
+ */
34
+ export declare const confirmYesNo: (question: string, options?: ConfirmYesNoOptions) => Promise<boolean>;
package/bin/main.cjs CHANGED
@@ -311,7 +311,7 @@ const confirmInstall = async (packages, yes, options = {}) => {
311
311
  if (packages.length === 0) return;
312
312
  const input = options.input ?? process.stdin;
313
313
  const output = options.output ?? process.stdout;
314
- const isTTY = options.isTTY ?? (process.stdin.isTTY ?? false);
314
+ const isTTY = options.isTTY ?? process.stdin.isTTY ?? false;
315
315
  if (!isTTY) {
316
316
  throw new Error("Cannot prompt for install confirmation: stdin is not a TTY. Re-run with --yes to install the listed packages without prompting.");
317
317
  }
@@ -328,6 +328,22 @@ ${renderPackageList(packages)}
328
328
  rl.close();
329
329
  }
330
330
  };
331
+ const confirmYesNo = async (question, options = {}) => {
332
+ if (options.yes) return true;
333
+ const input = options.input ?? process.stdin;
334
+ const output = options.output ?? process.stdout;
335
+ const isTTY = options.isTTY ?? process.stdin.isTTY ?? false;
336
+ if (!isTTY) return false;
337
+ const suffix = options.defaultYes ? "(Y/n)" : "(y/N)";
338
+ const rl = promises$1.createInterface({ input, output, terminal: false });
339
+ try {
340
+ const answer = (await rl.question(`${question} ${suffix} `)).trim().toLowerCase();
341
+ if (answer === "") return !!options.defaultYes;
342
+ return answer === "y" || answer === "yes";
343
+ } finally {
344
+ rl.close();
345
+ }
346
+ };
331
347
  const CSS_FILE_FOLDERS = ["src", "public", "assets", "styles", "css", "app"];
332
348
  const CSS_SECOND_LEVEL_FOLDERS = ["styles", "css", "app", "pages"];
333
349
  const CSS_FILE_NAMES = ["index", "styles", "main", "app", "global", "globals"];
@@ -667,8 +683,8 @@ const getSaltyCssPackages = async () => {
667
683
  return saltyCssPackages;
668
684
  };
669
685
  const registerUpdateCommand = (program) => {
670
- 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).option("-y, --yes", "Skip the install confirmation prompt.").action(async function(_version = "latest") {
671
- const { legacyPeerDeps, version = _version, yes = false } = this.opts();
686
+ 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).option("-y, --yes", "Skip confirmation prompts (install and rebuild).").option("-d, --dir <dir>", "Project directory to rebuild after updating.").action(async function(_version = "latest") {
687
+ const { legacyPeerDeps, version = _version, yes = false, dir } = this.opts();
672
688
  const saltyCssPackages = await getSaltyCssPackages();
673
689
  if (!saltyCssPackages) return compiler_saltyCompiler.logError("Could not update Salty-CSS packages as any were found in package.json.");
674
690
  const cli = await readThisPackageJson();
@@ -703,6 +719,17 @@ const registerUpdateCommand = (program) => {
703
719
  compiler_saltyCompiler.logger.info(`Updated to ${v.replace(/^\^/, "")}: ${names.join(", ")}`);
704
720
  }
705
721
  }
722
+ const project = dir ?? await getDefaultProject();
723
+ if (!project) {
724
+ compiler_saltyCompiler.logger.warn("Skipping rebuild: no project directory configured. Run `salty-css build [dir]` manually.");
725
+ return;
726
+ }
727
+ const shouldRebuild = await confirmYesNo("Rebuild Salty CSS now?", { yes });
728
+ if (!shouldRebuild) return;
729
+ const projectDir = resolveProjectDir(project);
730
+ compiler_saltyCompiler.logger.info("Rebuilding Salty-CSS project...");
731
+ await new compiler_saltyCompiler.SaltyCompiler(projectDir).generateCss();
732
+ compiler_saltyCompiler.logger.info("Rebuild complete.");
706
733
  });
707
734
  };
708
735
  const registerVersionOption = (program) => {
package/bin/main.js CHANGED
@@ -308,7 +308,7 @@ const confirmInstall = async (packages, yes, options = {}) => {
308
308
  if (packages.length === 0) return;
309
309
  const input = options.input ?? process.stdin;
310
310
  const output = options.output ?? process.stdout;
311
- const isTTY = options.isTTY ?? (process.stdin.isTTY ?? false);
311
+ const isTTY = options.isTTY ?? process.stdin.isTTY ?? false;
312
312
  if (!isTTY) {
313
313
  throw new Error("Cannot prompt for install confirmation: stdin is not a TTY. Re-run with --yes to install the listed packages without prompting.");
314
314
  }
@@ -325,6 +325,22 @@ ${renderPackageList(packages)}
325
325
  rl.close();
326
326
  }
327
327
  };
328
+ const confirmYesNo = async (question, options = {}) => {
329
+ if (options.yes) return true;
330
+ const input = options.input ?? process.stdin;
331
+ const output = options.output ?? process.stdout;
332
+ const isTTY = options.isTTY ?? process.stdin.isTTY ?? false;
333
+ if (!isTTY) return false;
334
+ const suffix = options.defaultYes ? "(Y/n)" : "(y/N)";
335
+ const rl = createInterface({ input, output, terminal: false });
336
+ try {
337
+ const answer = (await rl.question(`${question} ${suffix} `)).trim().toLowerCase();
338
+ if (answer === "") return !!options.defaultYes;
339
+ return answer === "y" || answer === "yes";
340
+ } finally {
341
+ rl.close();
342
+ }
343
+ };
328
344
  const CSS_FILE_FOLDERS = ["src", "public", "assets", "styles", "css", "app"];
329
345
  const CSS_SECOND_LEVEL_FOLDERS = ["styles", "css", "app", "pages"];
330
346
  const CSS_FILE_NAMES = ["index", "styles", "main", "app", "global", "globals"];
@@ -664,8 +680,8 @@ const getSaltyCssPackages = async () => {
664
680
  return saltyCssPackages;
665
681
  };
666
682
  const registerUpdateCommand = (program) => {
667
- 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).option("-y, --yes", "Skip the install confirmation prompt.").action(async function(_version = "latest") {
668
- const { legacyPeerDeps, version = _version, yes = false } = this.opts();
683
+ 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).option("-y, --yes", "Skip confirmation prompts (install and rebuild).").option("-d, --dir <dir>", "Project directory to rebuild after updating.").action(async function(_version = "latest") {
684
+ const { legacyPeerDeps, version = _version, yes = false, dir } = this.opts();
669
685
  const saltyCssPackages = await getSaltyCssPackages();
670
686
  if (!saltyCssPackages) return logError("Could not update Salty-CSS packages as any were found in package.json.");
671
687
  const cli = await readThisPackageJson();
@@ -700,6 +716,17 @@ const registerUpdateCommand = (program) => {
700
716
  logger.info(`Updated to ${v.replace(/^\^/, "")}: ${names.join(", ")}`);
701
717
  }
702
718
  }
719
+ const project = dir ?? await getDefaultProject();
720
+ if (!project) {
721
+ logger.warn("Skipping rebuild: no project directory configured. Run `salty-css build [dir]` manually.");
722
+ return;
723
+ }
724
+ const shouldRebuild = await confirmYesNo("Rebuild Salty CSS now?", { yes });
725
+ if (!shouldRebuild) return;
726
+ const projectDir = resolveProjectDir(project);
727
+ logger.info("Rebuilding Salty-CSS project...");
728
+ await new SaltyCompiler(projectDir).generateCss();
729
+ logger.info("Rebuild complete.");
703
730
  });
704
731
  };
705
732
  const registerVersionOption = (program) => {
@@ -2,7 +2,7 @@
2
2
  var __defProp = Object.defineProperty;
3
3
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
4
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
- const parseStyles = require("./parse-styles-CA3TP5n1.cjs");
5
+ const parseStyles = require("./parse-styles-BD9M4FTQ.cjs");
6
6
  const dashCase = require("./dash-case-DIwKaYgE.cjs");
7
7
  const toHash = require("./to-hash-C05Y906F.cjs");
8
8
  class StylesGenerator {
@@ -1,7 +1,7 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { p as parseAndJoinStyles } from "./parse-styles-BTIoYnBr.js";
4
+ import { p as parseAndJoinStyles } from "./parse-styles-D4No4G35.js";
5
5
  import { d as dashCase } from "./dash-case-DblXvymC.js";
6
6
  import { t as toHash } from "./to-hash-DAN2LcHK.js";
7
7
  class StylesGenerator {
@@ -13,7 +13,7 @@ const compiler_helpers = require("./helpers.cjs");
13
13
  const defineTemplates = require("../define-templates-Deq1aCbN.cjs");
14
14
  const dashCase = require("../dash-case-DIwKaYgE.cjs");
15
15
  const toHash = require("../to-hash-C05Y906F.cjs");
16
- const parseStyles = require("../parse-styles-CA3TP5n1.cjs");
16
+ const parseStyles = require("../parse-styles-BD9M4FTQ.cjs");
17
17
  const css_merge = require("../css/merge.cjs");
18
18
  const parsers_index = require("../parsers/index.cjs");
19
19
  const compiler_getFiles = require("./get-files.cjs");
@@ -11,7 +11,7 @@ import { isSaltyFile, resolveExportValue, getCorePackageRoot, saltyFileExtension
11
11
  import { d as defineTemplates } from "../define-templates-CVhhgPnd.js";
12
12
  import { d as dashCase } from "../dash-case-DblXvymC.js";
13
13
  import { t as toHash } from "../to-hash-DAN2LcHK.js";
14
- import { p as parseAndJoinStyles, b as parseVariableTokens } from "../parse-styles-BTIoYnBr.js";
14
+ import { p as parseAndJoinStyles, b as parseVariableTokens } from "../parse-styles-D4No4G35.js";
15
15
  import { mergeObjects, mergeFactories } from "../css/merge.js";
16
16
  import { parseTemplates, getTemplateTypes } from "../parsers/index.js";
17
17
  import { getPackageJson } from "./get-files.js";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const parseStyles = require("../parse-styles-CA3TP5n1.cjs");
3
+ const parseStyles = require("../parse-styles-BD9M4FTQ.cjs");
4
4
  const toHash = require("../to-hash-C05Y906F.cjs");
5
5
  const cache_resolveDynamicConfigCache = require("../cache/resolve-dynamic-config-cache.cjs");
6
6
  const getDynamicStylesClassName = (styles) => {
@@ -1,4 +1,4 @@
1
- import { a as parseStyles } from "../parse-styles-BTIoYnBr.js";
1
+ import { a as parseStyles } from "../parse-styles-D4No4G35.js";
2
2
  import { t as toHash } from "../to-hash-DAN2LcHK.js";
3
3
  import { resolveDynamicConfigCache } from "../cache/resolve-dynamic-config-cache.js";
4
4
  const getDynamicStylesClassName = (styles) => {
package/css/keyframes.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const parseStyles = require("../parse-styles-CA3TP5n1.cjs");
3
+ const parseStyles = require("../parse-styles-BD9M4FTQ.cjs");
4
4
  const toHash = require("../to-hash-C05Y906F.cjs");
5
5
  const keyframes = ({ animationName: _name, params: _params, appendInitialStyles, ...keyframes2 }) => {
6
6
  const modifyKeyframes = async (params = {}) => {
package/css/keyframes.js CHANGED
@@ -1,4 +1,4 @@
1
- import { p as parseAndJoinStyles } from "../parse-styles-BTIoYnBr.js";
1
+ import { p as parseAndJoinStyles } from "../parse-styles-D4No4G35.js";
2
2
  import { t as toHash } from "../to-hash-DAN2LcHK.js";
3
3
  const keyframes = ({ animationName: _name, params: _params, appendInitialStyles, ...keyframes2 }) => {
4
4
  const modifyKeyframes = async (params = {}) => {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const classNameGenerator = require("../class-name-generator-B2Pb2obX.cjs");
3
+ const classNameGenerator = require("../class-name-generator-0oGsYErm.cjs");
4
4
  const dashCase = require("../dash-case-DIwKaYgE.cjs");
5
5
  class StyledGenerator extends classNameGenerator.StylesGenerator {
6
6
  constructor(tagName, _params) {
@@ -1,5 +1,5 @@
1
- import { S as StylesGenerator } from "../class-name-generator-YeSQe_Ik.js";
2
- import { C } from "../class-name-generator-YeSQe_Ik.js";
1
+ import { S as StylesGenerator } from "../class-name-generator-D6ytQ7rP.js";
2
+ import { C } from "../class-name-generator-D6ytQ7rP.js";
3
3
  import { d as dashCase } from "../dash-case-DblXvymC.js";
4
4
  class StyledGenerator extends StylesGenerator {
5
5
  constructor(tagName, _params) {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const classNameGenerator = require("../class-name-generator-B2Pb2obX.cjs");
3
+ const classNameGenerator = require("../class-name-generator-0oGsYErm.cjs");
4
4
  const classNameInstance = (params) => {
5
5
  const generator = new classNameGenerator.ClassNameGenerator(params);
6
6
  const createClass = (classNameStr) => {
@@ -1,4 +1,4 @@
1
- import { C as ClassNameGenerator } from "../class-name-generator-YeSQe_Ik.js";
1
+ import { C as ClassNameGenerator } from "../class-name-generator-D6ytQ7rP.js";
2
2
  const classNameInstance = (params) => {
3
3
  const generator = new ClassNameGenerator(params);
4
4
  const createClass = (classNameStr) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salty-css/core",
3
- "version": "0.1.0-alpha.16",
3
+ "version": "0.1.0-alpha.18",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "typings": "./dist/index.d.ts",
@@ -173,7 +173,7 @@ const parseStyles = async (styles, currentScope = "", config, omitTemplates = fa
173
173
  cssStyles.add(query);
174
174
  return void 0;
175
175
  }
176
- const scope = key.includes("&") ? _key.replaceAll("&", currentScope) : _key.startsWith(":") ? `${currentScope}${_key}` : `${currentScope} ${_key}`;
176
+ const scope = combineSelectors(currentScope, _key);
177
177
  const results = await parseStyles(value, scope, config);
178
178
  results.forEach((result) => cssStyles.add(result));
179
179
  return void 0;
@@ -224,6 +224,45 @@ const parseAndJoinStyles = async (styles, currentClass, config, omitTemplates =
224
224
  const css = await parseStyles(styles, currentClass, config, omitTemplates);
225
225
  return css.join("\n");
226
226
  };
227
+ const splitTopLevelCommas = (selector) => {
228
+ const parts = [];
229
+ let depth = 0;
230
+ let buf = "";
231
+ for (const ch of selector) {
232
+ if (ch === "(" || ch === "[") depth++;
233
+ else if (ch === ")" || ch === "]") depth = Math.max(0, depth - 1);
234
+ if (ch === "," && depth === 0) {
235
+ const trimmed2 = buf.trim();
236
+ if (trimmed2) parts.push(trimmed2);
237
+ buf = "";
238
+ } else {
239
+ buf += ch;
240
+ }
241
+ }
242
+ const trimmed = buf.trim();
243
+ if (trimmed) parts.push(trimmed);
244
+ return parts;
245
+ };
246
+ const joinSelector = (parent, child) => {
247
+ if (child.includes("&")) return child.replaceAll("&", parent);
248
+ if (child.startsWith(":")) return `${parent}${child}`;
249
+ return `${parent} ${child}`;
250
+ };
251
+ const combineSelectors = (currentScope, key) => {
252
+ if (!currentScope) return key;
253
+ const parents = splitTopLevelCommas(currentScope);
254
+ const children = splitTopLevelCommas(key);
255
+ if (parents.length <= 1 && children.length <= 1) {
256
+ return joinSelector(currentScope, key);
257
+ }
258
+ const combos = [];
259
+ for (const p of parents) {
260
+ for (const c of children) {
261
+ combos.push(joinSelector(p, c));
262
+ }
263
+ }
264
+ return combos.join(", ");
265
+ };
227
266
  exports.parseAndJoinStyles = parseAndJoinStyles;
228
267
  exports.parseStyles = parseStyles;
229
268
  exports.parseValueModifiers = parseValueModifiers;
@@ -172,7 +172,7 @@ const parseStyles = async (styles, currentScope = "", config, omitTemplates = fa
172
172
  cssStyles.add(query);
173
173
  return void 0;
174
174
  }
175
- const scope = key.includes("&") ? _key.replaceAll("&", currentScope) : _key.startsWith(":") ? `${currentScope}${_key}` : `${currentScope} ${_key}`;
175
+ const scope = combineSelectors(currentScope, _key);
176
176
  const results = await parseStyles(value, scope, config);
177
177
  results.forEach((result) => cssStyles.add(result));
178
178
  return void 0;
@@ -223,6 +223,45 @@ const parseAndJoinStyles = async (styles, currentClass, config, omitTemplates =
223
223
  const css = await parseStyles(styles, currentClass, config, omitTemplates);
224
224
  return css.join("\n");
225
225
  };
226
+ const splitTopLevelCommas = (selector) => {
227
+ const parts = [];
228
+ let depth = 0;
229
+ let buf = "";
230
+ for (const ch of selector) {
231
+ if (ch === "(" || ch === "[") depth++;
232
+ else if (ch === ")" || ch === "]") depth = Math.max(0, depth - 1);
233
+ if (ch === "," && depth === 0) {
234
+ const trimmed2 = buf.trim();
235
+ if (trimmed2) parts.push(trimmed2);
236
+ buf = "";
237
+ } else {
238
+ buf += ch;
239
+ }
240
+ }
241
+ const trimmed = buf.trim();
242
+ if (trimmed) parts.push(trimmed);
243
+ return parts;
244
+ };
245
+ const joinSelector = (parent, child) => {
246
+ if (child.includes("&")) return child.replaceAll("&", parent);
247
+ if (child.startsWith(":")) return `${parent}${child}`;
248
+ return `${parent} ${child}`;
249
+ };
250
+ const combineSelectors = (currentScope, key) => {
251
+ if (!currentScope) return key;
252
+ const parents = splitTopLevelCommas(currentScope);
253
+ const children = splitTopLevelCommas(key);
254
+ if (parents.length <= 1 && children.length <= 1) {
255
+ return joinSelector(currentScope, key);
256
+ }
257
+ const combos = [];
258
+ for (const p of parents) {
259
+ for (const c of children) {
260
+ combos.push(joinSelector(p, c));
261
+ }
262
+ }
263
+ return combos.join(", ");
264
+ };
226
265
  export {
227
266
  parseStyles as a,
228
267
  parseVariableTokens as b,
package/parsers/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const parseStyles = require("../parse-styles-CA3TP5n1.cjs");
3
+ const parseStyles = require("../parse-styles-BD9M4FTQ.cjs");
4
4
  const dashCase = require("../dash-case-DIwKaYgE.cjs");
5
5
  const toHash = require("../to-hash-C05Y906F.cjs");
6
6
  const parseTemplates = async (obj, path = []) => {
package/parsers/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { p as parseAndJoinStyles } from "../parse-styles-BTIoYnBr.js";
2
- import { a, c, d, b } from "../parse-styles-BTIoYnBr.js";
1
+ import { p as parseAndJoinStyles } from "../parse-styles-D4No4G35.js";
2
+ import { a, c, d, b } from "../parse-styles-D4No4G35.js";
3
3
  import { d as dashCase } from "../dash-case-DblXvymC.js";
4
4
  import { t as toHash } from "../to-hash-DAN2LcHK.js";
5
5
  const parseTemplates = async (obj, path = []) => {
package/runtime/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const parseStyles = require("../parse-styles-CA3TP5n1.cjs");
3
+ const parseStyles = require("../parse-styles-BD9M4FTQ.cjs");
4
4
  const defineRuntime = (config) => {
5
5
  const getDynamicStylesCss = async (styles, scope) => {
6
6
  const parsed = await parseStyles.parseStyles(styles, scope, config);
package/runtime/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as parseStyles } from "../parse-styles-BTIoYnBr.js";
1
+ import { a as parseStyles } from "../parse-styles-D4No4G35.js";
2
2
  const defineRuntime = (config) => {
3
3
  const getDynamicStylesCss = async (styles, scope) => {
4
4
  const parsed = await parseStyles(styles, scope, config);