@salty-css/core 0.1.0-alpha.9 → 0.1.0-refactor-add-additional-paths-to-config-cache.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.
- package/bin/confirm-install.d.ts +34 -0
- package/bin/context.d.ts +3 -0
- package/bin/integrations/index.d.ts +11 -3
- package/bin/integrations/types.d.ts +14 -2
- package/bin/main.cjs +197 -95
- package/bin/main.js +151 -49
- package/cache/resolve-dynamic-config-cache.cjs +64 -16
- package/cache/resolve-dynamic-config-cache.d.ts +20 -1
- package/cache/resolve-dynamic-config-cache.js +65 -17
- package/{class-name-generator-YeSQe_Ik.js → class-name-generator-CMWY5KTJ.js} +1 -1
- package/{class-name-generator-B2Pb2obX.cjs → class-name-generator-DB5aQwC_.cjs} +1 -1
- package/compiler/copy-config-cache.cjs +39 -0
- package/compiler/copy-config-cache.d.ts +17 -0
- package/compiler/copy-config-cache.js +39 -0
- package/compiler/salty-compiler.cjs +22 -21
- package/compiler/salty-compiler.d.ts +11 -1
- package/compiler/salty-compiler.js +20 -19
- package/css/dynamic-styles.cjs +21 -8
- package/css/dynamic-styles.d.ts +39 -0
- package/css/dynamic-styles.js +22 -9
- package/css/index.cjs +1 -0
- package/css/index.js +2 -1
- package/css/keyframes.cjs +1 -1
- package/css/keyframes.js +1 -1
- package/generators/index.cjs +1 -1
- package/generators/index.js +2 -2
- package/instances/classname-instance.cjs +1 -1
- package/instances/classname-instance.js +1 -1
- package/logger-7xz0pyAz.cjs +12 -0
- package/logger-hHmCwThj.js +13 -0
- package/package.json +5 -1
- package/{parse-styles-CA3TP5n1.cjs → parse-styles-C54MOrPg.cjs} +106 -7
- package/{parse-styles-BTIoYnBr.js → parse-styles-CLMTHo2H.js} +107 -8
- package/parsers/index.cjs +2 -1
- package/parsers/index.d.ts +1 -0
- package/parsers/index.js +4 -3
- package/parsers/parser-regexes.d.ts +3 -0
- package/parsers/strict.d.ts +2 -0
- package/runtime/index.cjs +1 -1
- package/runtime/index.js +1 -1
- package/{salty.config-cqavVm2t.cjs → salty.config-DogY_sSQ.cjs} +1 -1
- package/salty.config-GV37Q-D2.js +4 -0
- package/types/config-types.d.ts +9 -0
- package/salty.config-DjosWdPw.js +0 -4
package/bin/main.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import { existsSync, watch } from "fs";
|
|
3
|
-
import {
|
|
3
|
+
import { SaltyCompiler } from "../compiler/salty-compiler.js";
|
|
4
4
|
import { isSaltyFile } from "../compiler/helpers.js";
|
|
5
5
|
import { c as checkShouldRestart } from "../should-restart-CXIO0jxY.js";
|
|
6
6
|
import { join, relative, parse, format } from "path";
|
|
7
7
|
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
8
8
|
import { exec } from "child_process";
|
|
9
9
|
import ora from "ora";
|
|
10
|
+
import { l as logger, a as logError } from "../logger-hHmCwThj.js";
|
|
10
11
|
import { p as pascalCase } from "../pascal-case-F3Usi5Wf.js";
|
|
11
12
|
import ejs from "ejs";
|
|
13
|
+
import { createInterface } from "readline/promises";
|
|
12
14
|
const defaultPackageJsonPath = join(process.cwd(), "package.json");
|
|
13
15
|
const readPackageJson = async (filePath = defaultPackageJsonPath) => {
|
|
14
16
|
const content = await readFile(filePath, "utf-8").then(JSON.parse).catch(() => void 0);
|
|
@@ -138,17 +140,21 @@ const buildContext = async (opts) => {
|
|
|
138
140
|
packageJson,
|
|
139
141
|
rcFile,
|
|
140
142
|
cliVersion: cliPackageJson.version || "0.0.0",
|
|
141
|
-
skipInstall: !!opts.skipInstall
|
|
143
|
+
skipInstall: !!opts.skipInstall,
|
|
144
|
+
yes: !!opts.yes
|
|
142
145
|
};
|
|
143
146
|
};
|
|
144
147
|
const registerBuildCommand = (program, defaultProject) => {
|
|
145
|
-
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) {
|
|
148
|
+
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.").option("--mode <mode>", 'Build mode: "production" or "development". Defaults to NODE_ENV-based detection.').action(async function(_dir = defaultProject) {
|
|
146
149
|
logger.info("Building the Salty-CSS project...");
|
|
147
|
-
const { dir = _dir, watch: watch$1 } = this.opts();
|
|
150
|
+
const { dir = _dir, watch: watch$1, mode } = this.opts();
|
|
151
|
+
if (mode !== void 0 && mode !== "production" && mode !== "development") {
|
|
152
|
+
return logError(`Invalid --mode "${mode}". Expected "production" or "development".`);
|
|
153
|
+
}
|
|
148
154
|
const resolved = dir ?? await getDefaultProject();
|
|
149
155
|
if (!resolved) return logError("Project directory must be provided. Add it as the first argument after build command or use the --dir option.");
|
|
150
156
|
const projectDir = resolveProjectDir(resolved);
|
|
151
|
-
const compiler = new SaltyCompiler(projectDir);
|
|
157
|
+
const compiler = new SaltyCompiler(projectDir, { mode });
|
|
152
158
|
await compiler.generateCss();
|
|
153
159
|
if (watch$1) {
|
|
154
160
|
logger.info("Watching for changes in the project directory...");
|
|
@@ -222,7 +228,7 @@ const getFramework = (name) => {
|
|
|
222
228
|
return frameworksByName[name];
|
|
223
229
|
};
|
|
224
230
|
const templateLoaders = {
|
|
225
|
-
"salty.config.ts": () => import("../salty.config-
|
|
231
|
+
"salty.config.ts": () => import("../salty.config-GV37Q-D2.js"),
|
|
226
232
|
"saltygen/index.css": () => import("../index-DKz1QXqs.js"),
|
|
227
233
|
"react/styled-file.ts": () => import("../styled-file-Cda3EeR6.js"),
|
|
228
234
|
"react/vanilla-file.ts": () => import("../vanilla-file-1kOqbCIM.js"),
|
|
@@ -290,6 +296,52 @@ const registerGenerateCommand = (program, defaultProject) => {
|
|
|
290
296
|
await formatWithPrettier(formattedStyledFilePath);
|
|
291
297
|
});
|
|
292
298
|
};
|
|
299
|
+
const formatPackageForDisplay = (spec) => {
|
|
300
|
+
const trimmed = spec.trim();
|
|
301
|
+
if (trimmed.startsWith("-D ")) return `${trimmed.slice(3).trim()} (dev)`;
|
|
302
|
+
return trimmed;
|
|
303
|
+
};
|
|
304
|
+
const renderPackageList = (packages) => {
|
|
305
|
+
return packages.map((p) => ` + ${formatPackageForDisplay(p)}`).join("\n");
|
|
306
|
+
};
|
|
307
|
+
const confirmInstall = async (packages, yes, options = {}) => {
|
|
308
|
+
if (yes) return;
|
|
309
|
+
if (packages.length === 0) return;
|
|
310
|
+
const input = options.input ?? process.stdin;
|
|
311
|
+
const output = options.output ?? process.stdout;
|
|
312
|
+
const isTTY = options.isTTY ?? process.stdin.isTTY ?? false;
|
|
313
|
+
if (!isTTY) {
|
|
314
|
+
throw new Error("Cannot prompt for install confirmation: stdin is not a TTY. Re-run with --yes to install the listed packages without prompting.");
|
|
315
|
+
}
|
|
316
|
+
output.write(`The following packages will be installed:
|
|
317
|
+
${renderPackageList(packages)}
|
|
318
|
+
`);
|
|
319
|
+
const rl = createInterface({ input, output, terminal: false });
|
|
320
|
+
try {
|
|
321
|
+
const answer = (await rl.question("Proceed? (y/N) ")).trim().toLowerCase();
|
|
322
|
+
if (answer !== "y" && answer !== "yes") {
|
|
323
|
+
throw new Error("Install cancelled by user.");
|
|
324
|
+
}
|
|
325
|
+
} finally {
|
|
326
|
+
rl.close();
|
|
327
|
+
}
|
|
328
|
+
};
|
|
329
|
+
const confirmYesNo = async (question, options = {}) => {
|
|
330
|
+
if (options.yes) return true;
|
|
331
|
+
const input = options.input ?? process.stdin;
|
|
332
|
+
const output = options.output ?? process.stdout;
|
|
333
|
+
const isTTY = options.isTTY ?? process.stdin.isTTY ?? false;
|
|
334
|
+
if (!isTTY) return false;
|
|
335
|
+
const suffix = options.defaultYes ? "(Y/n)" : "(y/N)";
|
|
336
|
+
const rl = createInterface({ input, output, terminal: false });
|
|
337
|
+
try {
|
|
338
|
+
const answer = (await rl.question(`${question} ${suffix} `)).trim().toLowerCase();
|
|
339
|
+
if (answer === "") return !!options.defaultYes;
|
|
340
|
+
return answer === "y" || answer === "yes";
|
|
341
|
+
} finally {
|
|
342
|
+
rl.close();
|
|
343
|
+
}
|
|
344
|
+
};
|
|
293
345
|
const CSS_FILE_FOLDERS = ["src", "public", "assets", "styles", "css", "app"];
|
|
294
346
|
const CSS_SECOND_LEVEL_FOLDERS = ["styles", "css", "app", "pages"];
|
|
295
347
|
const CSS_FILE_NAMES = ["index", "styles", "main", "app", "global", "globals"];
|
|
@@ -336,17 +388,22 @@ const editAstroConfig = (existing) => {
|
|
|
336
388
|
const astroIntegration = {
|
|
337
389
|
name: "astro",
|
|
338
390
|
detect: (ctx) => findAstroConfig(ctx.projectDir),
|
|
339
|
-
|
|
391
|
+
plan: async (ctx, configPath) => {
|
|
340
392
|
const existing = await readFile(configPath, "utf-8").catch(() => void 0);
|
|
341
|
-
if (existing === void 0) return
|
|
393
|
+
if (existing === void 0) return null;
|
|
342
394
|
const result = editAstroConfig(existing);
|
|
343
395
|
if (result.warning) logger.warn(result.warning);
|
|
344
|
-
if (result.content === null) return
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
396
|
+
if (result.content === null) return null;
|
|
397
|
+
const newContent = result.content;
|
|
398
|
+
return {
|
|
399
|
+
packages: [`-D ${astroPackage(ctx.cliVersion)}`],
|
|
400
|
+
execute: async () => {
|
|
401
|
+
logger.info("Adding Salty-CSS integration to Astro config: " + configPath);
|
|
402
|
+
await writeFile(configPath, newContent);
|
|
403
|
+
await formatWithPrettier(configPath);
|
|
404
|
+
return { changed: true };
|
|
405
|
+
}
|
|
406
|
+
};
|
|
350
407
|
}
|
|
351
408
|
};
|
|
352
409
|
const ESLINT_CONFIG_CANDIDATES = [
|
|
@@ -405,20 +462,25 @@ const eslintIntegration = {
|
|
|
405
462
|
const candidates = eslintConfigCandidates(ctx.projectDir, ctx.cwd);
|
|
406
463
|
return candidates.find((p) => existsSync(p)) ?? null;
|
|
407
464
|
},
|
|
408
|
-
|
|
465
|
+
plan: async (ctx, configPath) => {
|
|
409
466
|
const existing = await readFile(configPath, "utf-8").catch(() => void 0);
|
|
410
467
|
if (existing === void 0) {
|
|
411
468
|
logger.error("Could not read ESLint config file.");
|
|
412
|
-
return
|
|
469
|
+
return null;
|
|
413
470
|
}
|
|
414
|
-
if (!ctx.skipInstall) await npmInstall(corePackages.eslintConfigCore(ctx.cliVersion));
|
|
415
471
|
const result = editEslintConfig(existing, configPath.endsWith("js"));
|
|
416
472
|
if (result.warning) logger.warn(result.warning);
|
|
417
|
-
if (result.content === null) return
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
473
|
+
if (result.content === null) return null;
|
|
474
|
+
const newContent = result.content;
|
|
475
|
+
return {
|
|
476
|
+
packages: [corePackages.eslintConfigCore(ctx.cliVersion)],
|
|
477
|
+
execute: async () => {
|
|
478
|
+
logger.info("Edit file: " + configPath);
|
|
479
|
+
await writeFile(configPath, newContent);
|
|
480
|
+
await formatWithPrettier(configPath);
|
|
481
|
+
return { changed: true };
|
|
482
|
+
}
|
|
483
|
+
};
|
|
422
484
|
}
|
|
423
485
|
};
|
|
424
486
|
const nextConfigFiles = ["next.config.js", "next.config.cjs", "next.config.ts", "next.config.mjs"];
|
|
@@ -448,16 +510,20 @@ const nextIntegration = {
|
|
|
448
510
|
const found = nextConfigFiles.map((file) => join(ctx.projectDir, file)).find((p) => existsSync(p));
|
|
449
511
|
return found ?? null;
|
|
450
512
|
},
|
|
451
|
-
|
|
513
|
+
plan: async (ctx, configPath) => {
|
|
452
514
|
const existing = await readFile(configPath, "utf-8").catch(() => void 0);
|
|
453
|
-
if (existing === void 0) return
|
|
515
|
+
if (existing === void 0) return null;
|
|
454
516
|
const { content } = editNextConfig(existing);
|
|
455
|
-
if (content === null) return
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
517
|
+
if (content === null) return null;
|
|
518
|
+
return {
|
|
519
|
+
packages: [`-D ${nextPackage(ctx.cliVersion)}`],
|
|
520
|
+
execute: async () => {
|
|
521
|
+
logger.info("Adding Salty-CSS plugin to Next.js config...");
|
|
522
|
+
await writeFile(configPath, content);
|
|
523
|
+
await formatWithPrettier(configPath);
|
|
524
|
+
return { changed: true };
|
|
525
|
+
}
|
|
526
|
+
};
|
|
461
527
|
}
|
|
462
528
|
};
|
|
463
529
|
const vitePackage = (version) => `@salty-css/vite@${version}`;
|
|
@@ -475,27 +541,40 @@ const viteIntegration = {
|
|
|
475
541
|
const path = join(ctx.projectDir, "vite.config.ts");
|
|
476
542
|
return existsSync(path) ? path : null;
|
|
477
543
|
},
|
|
478
|
-
|
|
544
|
+
plan: async (ctx, configPath) => {
|
|
479
545
|
const existing = await readFile(configPath, "utf-8").catch(() => void 0);
|
|
480
|
-
if (existing === void 0) return
|
|
546
|
+
if (existing === void 0) return null;
|
|
481
547
|
const { content } = editViteConfig(existing);
|
|
482
|
-
if (content === null) return
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
548
|
+
if (content === null) return null;
|
|
549
|
+
return {
|
|
550
|
+
packages: [`-D ${vitePackage(ctx.cliVersion)}`],
|
|
551
|
+
execute: async () => {
|
|
552
|
+
logger.info("Edit file: " + configPath);
|
|
553
|
+
logger.info("Adding Salty-CSS plugin to Vite config...");
|
|
554
|
+
await writeFile(configPath, content);
|
|
555
|
+
await formatWithPrettier(configPath);
|
|
556
|
+
return { changed: true };
|
|
557
|
+
}
|
|
558
|
+
};
|
|
489
559
|
}
|
|
490
560
|
};
|
|
491
561
|
const buildIntegrationRegistry = [eslintIntegration, viteIntegration, nextIntegration, astroIntegration];
|
|
492
|
-
const
|
|
493
|
-
const
|
|
562
|
+
const planIntegrations = async (ctx) => {
|
|
563
|
+
const planned = [];
|
|
494
564
|
for (const integration of buildIntegrationRegistry) {
|
|
495
565
|
const configPath = await integration.detect(ctx);
|
|
496
566
|
if (!configPath) continue;
|
|
497
|
-
const
|
|
498
|
-
|
|
567
|
+
const plan = await integration.plan(ctx, configPath);
|
|
568
|
+
if (!plan) continue;
|
|
569
|
+
planned.push({ name: integration.name, configPath, plan });
|
|
570
|
+
}
|
|
571
|
+
return planned;
|
|
572
|
+
};
|
|
573
|
+
const applyIntegrationPlans = async (planned) => {
|
|
574
|
+
const results = [];
|
|
575
|
+
for (const { name, configPath, plan } of planned) {
|
|
576
|
+
const result = await plan.execute();
|
|
577
|
+
results.push({ name, configPath, changed: result.changed });
|
|
499
578
|
}
|
|
500
579
|
return results;
|
|
501
580
|
};
|
|
@@ -546,17 +625,24 @@ const wirePrepareScript = async () => {
|
|
|
546
625
|
await updatePackageJson(next);
|
|
547
626
|
};
|
|
548
627
|
const registerInitCommand = (program) => {
|
|
549
|
-
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 = ".") {
|
|
628
|
+
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.").option("-y, --yes", "Skip the install confirmation prompt.").action(async function(_dir = ".") {
|
|
550
629
|
try {
|
|
551
630
|
const opts = this.opts();
|
|
552
631
|
const dir = opts.dir ?? _dir;
|
|
553
632
|
if (!dir) return logError("Project directory must be provided. Add it as the first argument after init command or use the --dir option.");
|
|
554
|
-
const ctx = await buildContext({ dir, skipInstall: opts.skipInstall });
|
|
633
|
+
const ctx = await buildContext({ dir, skipInstall: opts.skipInstall, yes: opts.yes });
|
|
555
634
|
logger.info("Initializing a new Salty-CSS project!");
|
|
556
635
|
const framework = await detectFramework(ctx);
|
|
557
636
|
logger.info(`Detected framework: ${framework.name}`);
|
|
637
|
+
const plannedIntegrations = await planIntegrations(ctx);
|
|
558
638
|
if (!ctx.skipInstall) {
|
|
559
|
-
|
|
639
|
+
const packages = [
|
|
640
|
+
corePackages.core(ctx.cliVersion),
|
|
641
|
+
framework.runtimePackage(ctx.cliVersion),
|
|
642
|
+
...plannedIntegrations.flatMap((p) => p.plan.packages)
|
|
643
|
+
];
|
|
644
|
+
await confirmInstall(packages, ctx.yes);
|
|
645
|
+
await npmInstall(...packages);
|
|
560
646
|
}
|
|
561
647
|
const projectFiles = await Promise.all([readTemplate("salty.config.ts"), readTemplate("saltygen/index.css")]);
|
|
562
648
|
await mkdir(ctx.projectDir, { recursive: true });
|
|
@@ -564,7 +650,7 @@ const registerInitCommand = (program) => {
|
|
|
564
650
|
await writeProjectToRc(ctx.cwd, ctx.relativeProjectPath, framework);
|
|
565
651
|
await ensureGitignoreSaltygen(ctx.cwd);
|
|
566
652
|
await importSaltygenIntoCss(ctx.projectDir, opts.cssFile);
|
|
567
|
-
await
|
|
653
|
+
await applyIntegrationPlans(plannedIntegrations);
|
|
568
654
|
await wirePrepareScript();
|
|
569
655
|
logger.info("Running the build to generate initial CSS...");
|
|
570
656
|
const compiler = new SaltyCompiler(ctx.projectDir);
|
|
@@ -595,8 +681,8 @@ const getSaltyCssPackages = async () => {
|
|
|
595
681
|
return saltyCssPackages;
|
|
596
682
|
};
|
|
597
683
|
const registerUpdateCommand = (program) => {
|
|
598
|
-
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") {
|
|
599
|
-
const { legacyPeerDeps, version = _version } = this.opts();
|
|
684
|
+
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") {
|
|
685
|
+
const { legacyPeerDeps, version = _version, yes = false, dir } = this.opts();
|
|
600
686
|
const saltyCssPackages = await getSaltyCssPackages();
|
|
601
687
|
if (!saltyCssPackages) return logError("Could not update Salty-CSS packages as any were found in package.json.");
|
|
602
688
|
const cli = await readThisPackageJson();
|
|
@@ -604,6 +690,11 @@ const registerUpdateCommand = (program) => {
|
|
|
604
690
|
if (version === "@") return `${name}@${cli.version}`;
|
|
605
691
|
return `${name}@${version.replace(/^@/, "")}`;
|
|
606
692
|
});
|
|
693
|
+
try {
|
|
694
|
+
await confirmInstall(packagesToUpdate, yes);
|
|
695
|
+
} catch (err) {
|
|
696
|
+
return logError(err instanceof Error ? err.message : String(err));
|
|
697
|
+
}
|
|
607
698
|
if (legacyPeerDeps) {
|
|
608
699
|
logger.warn("Using legacy peer dependencies to update packages.");
|
|
609
700
|
await npmInstall(...packagesToUpdate, "--legacy-peer-deps");
|
|
@@ -626,6 +717,17 @@ const registerUpdateCommand = (program) => {
|
|
|
626
717
|
logger.info(`Updated to ${v.replace(/^\^/, "")}: ${names.join(", ")}`);
|
|
627
718
|
}
|
|
628
719
|
}
|
|
720
|
+
const project = dir ?? await getDefaultProject();
|
|
721
|
+
if (!project) {
|
|
722
|
+
logger.warn("Skipping rebuild: no project directory configured. Run `salty-css build [dir]` manually.");
|
|
723
|
+
return;
|
|
724
|
+
}
|
|
725
|
+
const shouldRebuild = await confirmYesNo("Rebuild Salty CSS now?", { yes });
|
|
726
|
+
if (!shouldRebuild) return;
|
|
727
|
+
const projectDir = resolveProjectDir(project);
|
|
728
|
+
logger.info("Rebuilding Salty-CSS project...");
|
|
729
|
+
await new SaltyCompiler(projectDir).generateCss();
|
|
730
|
+
logger.info("Rebuild complete.");
|
|
629
731
|
});
|
|
630
732
|
};
|
|
631
733
|
const registerVersionOption = (program) => {
|
|
@@ -2,23 +2,71 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const promises = require("fs/promises");
|
|
4
4
|
const path = require("path");
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
5
|
+
const CACHE_FILENAME = "config-cache.json";
|
|
6
|
+
const ENV_VAR = "SALTY_CONFIG_CACHE_PATH";
|
|
7
|
+
const defaultPatterns = [
|
|
8
|
+
"",
|
|
9
|
+
"saltygen",
|
|
10
|
+
"src",
|
|
11
|
+
"src/saltygen",
|
|
12
|
+
"cache",
|
|
13
|
+
"src/cache",
|
|
14
|
+
"saltygen/cache",
|
|
15
|
+
"src/saltygen/cache",
|
|
16
|
+
"dist",
|
|
17
|
+
"dist/cache",
|
|
18
|
+
"dist/saltygen/cache",
|
|
19
|
+
"build",
|
|
20
|
+
"build/cache",
|
|
21
|
+
"build/saltygen/cache",
|
|
22
|
+
"public/saltygen/cache",
|
|
23
|
+
".next",
|
|
24
|
+
".next/server",
|
|
25
|
+
".next/server/cache",
|
|
26
|
+
".vercel/output/functions"
|
|
27
|
+
];
|
|
28
|
+
const memo = /* @__PURE__ */ new Map();
|
|
29
|
+
let warned = false;
|
|
30
|
+
const toAbsolute = (p, cwd) => path.isAbsolute(p) ? p : path.join(cwd, p);
|
|
31
|
+
const candidatePathsFrom = (entry, cwd) => {
|
|
32
|
+
const abs = toAbsolute(entry, cwd);
|
|
33
|
+
if (abs.endsWith(".json")) return [abs];
|
|
34
|
+
return [path.join(abs, CACHE_FILENAME), path.join(abs, "cache", CACHE_FILENAME), path.join(abs, "saltygen", "cache", CACHE_FILENAME)];
|
|
35
|
+
};
|
|
36
|
+
const tryRead = async (path2) => {
|
|
37
|
+
if (memo.has(path2)) return memo.get(path2);
|
|
38
|
+
try {
|
|
39
|
+
const contents = await promises.readFile(path2, "utf8");
|
|
40
|
+
if (!contents) return void 0;
|
|
41
|
+
const parsed = JSON.parse(contents);
|
|
42
|
+
memo.set(path2, parsed);
|
|
43
|
+
return parsed;
|
|
44
|
+
} catch {
|
|
45
|
+
return void 0;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const resolveDynamicConfigCache = async (options = {}) => {
|
|
49
|
+
var _a;
|
|
50
|
+
const cwd = options.cwd ?? process.cwd();
|
|
51
|
+
const envPath = typeof process !== "undefined" ? (_a = process.env) == null ? void 0 : _a[ENV_VAR] : void 0;
|
|
52
|
+
const ordered = [];
|
|
53
|
+
if (options.primaryPath) ordered.push(...candidatePathsFrom(options.primaryPath, cwd));
|
|
54
|
+
if (envPath) ordered.push(...candidatePathsFrom(envPath, cwd));
|
|
55
|
+
if (options.extraPaths) for (const p of options.extraPaths) ordered.push(...candidatePathsFrom(p, cwd));
|
|
56
|
+
for (const pattern of defaultPatterns) ordered.push(path.join(cwd, pattern, CACHE_FILENAME));
|
|
57
|
+
for (const candidate of ordered) {
|
|
58
|
+
const result = await tryRead(candidate);
|
|
59
|
+
if (result) return result;
|
|
17
60
|
}
|
|
18
|
-
if (!
|
|
19
|
-
|
|
20
|
-
|
|
61
|
+
if (!warned) {
|
|
62
|
+
warned = true;
|
|
63
|
+
console.warn(`Could not find config cache file (${CACHE_FILENAME}) in any of the expected locations.`);
|
|
21
64
|
}
|
|
22
|
-
return
|
|
65
|
+
return {};
|
|
66
|
+
};
|
|
67
|
+
const _resetDynamicConfigCacheMemo = () => {
|
|
68
|
+
memo.clear();
|
|
69
|
+
warned = false;
|
|
23
70
|
};
|
|
71
|
+
exports._resetDynamicConfigCacheMemo = _resetDynamicConfigCacheMemo;
|
|
24
72
|
exports.resolveDynamicConfigCache = resolveDynamicConfigCache;
|
|
@@ -1 +1,20 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface ResolveDynamicConfigCacheOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Highest-priority path checked first. If it resolves, no other paths are tried.
|
|
4
|
+
* Absolute, or relative to `cwd`.
|
|
5
|
+
*/
|
|
6
|
+
primaryPath?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Extra paths checked before the built-in defaults. Absolute, or relative to `cwd`.
|
|
9
|
+
*/
|
|
10
|
+
extraPaths?: string[];
|
|
11
|
+
/**
|
|
12
|
+
* Base directory for resolving relative paths. Defaults to `process.cwd()`.
|
|
13
|
+
*/
|
|
14
|
+
cwd?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare const resolveDynamicConfigCache: (options?: ResolveDynamicConfigCacheOptions) => Promise<Record<string, unknown>>;
|
|
17
|
+
/**
|
|
18
|
+
* Clear the in-memory cache of parsed config-cache.json files. Test-only.
|
|
19
|
+
*/
|
|
20
|
+
export declare const _resetDynamicConfigCacheMemo: () => void;
|
|
@@ -1,24 +1,72 @@
|
|
|
1
1
|
import { readFile } from "fs/promises";
|
|
2
|
-
import { join } from "path";
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
2
|
+
import { join, isAbsolute } from "path";
|
|
3
|
+
const CACHE_FILENAME = "config-cache.json";
|
|
4
|
+
const ENV_VAR = "SALTY_CONFIG_CACHE_PATH";
|
|
5
|
+
const defaultPatterns = [
|
|
6
|
+
"",
|
|
7
|
+
"saltygen",
|
|
8
|
+
"src",
|
|
9
|
+
"src/saltygen",
|
|
10
|
+
"cache",
|
|
11
|
+
"src/cache",
|
|
12
|
+
"saltygen/cache",
|
|
13
|
+
"src/saltygen/cache",
|
|
14
|
+
"dist",
|
|
15
|
+
"dist/cache",
|
|
16
|
+
"dist/saltygen/cache",
|
|
17
|
+
"build",
|
|
18
|
+
"build/cache",
|
|
19
|
+
"build/saltygen/cache",
|
|
20
|
+
"public/saltygen/cache",
|
|
21
|
+
".next",
|
|
22
|
+
".next/server",
|
|
23
|
+
".next/server/cache",
|
|
24
|
+
".vercel/output/functions"
|
|
25
|
+
];
|
|
26
|
+
const memo = /* @__PURE__ */ new Map();
|
|
27
|
+
let warned = false;
|
|
28
|
+
const toAbsolute = (p, cwd) => isAbsolute(p) ? p : join(cwd, p);
|
|
29
|
+
const candidatePathsFrom = (entry, cwd) => {
|
|
30
|
+
const abs = toAbsolute(entry, cwd);
|
|
31
|
+
if (abs.endsWith(".json")) return [abs];
|
|
32
|
+
return [join(abs, CACHE_FILENAME), join(abs, "cache", CACHE_FILENAME), join(abs, "saltygen", "cache", CACHE_FILENAME)];
|
|
33
|
+
};
|
|
34
|
+
const tryRead = async (path) => {
|
|
35
|
+
if (memo.has(path)) return memo.get(path);
|
|
36
|
+
try {
|
|
37
|
+
const contents = await readFile(path, "utf8");
|
|
38
|
+
if (!contents) return void 0;
|
|
39
|
+
const parsed = JSON.parse(contents);
|
|
40
|
+
memo.set(path, parsed);
|
|
41
|
+
return parsed;
|
|
42
|
+
} catch {
|
|
43
|
+
return void 0;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
const resolveDynamicConfigCache = async (options = {}) => {
|
|
47
|
+
var _a;
|
|
48
|
+
const cwd = options.cwd ?? process.cwd();
|
|
49
|
+
const envPath = typeof process !== "undefined" ? (_a = process.env) == null ? void 0 : _a[ENV_VAR] : void 0;
|
|
50
|
+
const ordered = [];
|
|
51
|
+
if (options.primaryPath) ordered.push(...candidatePathsFrom(options.primaryPath, cwd));
|
|
52
|
+
if (envPath) ordered.push(...candidatePathsFrom(envPath, cwd));
|
|
53
|
+
if (options.extraPaths) for (const p of options.extraPaths) ordered.push(...candidatePathsFrom(p, cwd));
|
|
54
|
+
for (const pattern of defaultPatterns) ordered.push(join(cwd, pattern, CACHE_FILENAME));
|
|
55
|
+
for (const candidate of ordered) {
|
|
56
|
+
const result = await tryRead(candidate);
|
|
57
|
+
if (result) return result;
|
|
15
58
|
}
|
|
16
|
-
if (!
|
|
17
|
-
|
|
18
|
-
|
|
59
|
+
if (!warned) {
|
|
60
|
+
warned = true;
|
|
61
|
+
console.warn(`Could not find config cache file (${CACHE_FILENAME}) in any of the expected locations.`);
|
|
19
62
|
}
|
|
20
|
-
return
|
|
63
|
+
return {};
|
|
64
|
+
};
|
|
65
|
+
const _resetDynamicConfigCacheMemo = () => {
|
|
66
|
+
memo.clear();
|
|
67
|
+
warned = false;
|
|
21
68
|
};
|
|
22
69
|
export {
|
|
70
|
+
_resetDynamicConfigCacheMemo,
|
|
23
71
|
resolveDynamicConfigCache
|
|
24
72
|
};
|
|
@@ -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-
|
|
4
|
+
import { p as parseAndJoinStyles } from "./parse-styles-CLMTHo2H.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 {
|
|
@@ -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-
|
|
5
|
+
const parseStyles = require("./parse-styles-C54MOrPg.cjs");
|
|
6
6
|
const dashCase = require("./dash-case-DIwKaYgE.cjs");
|
|
7
7
|
const toHash = require("./to-hash-C05Y906F.cjs");
|
|
8
8
|
class StylesGenerator {
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const promises = require("fs/promises");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const logger = require("../logger-7xz0pyAz.cjs");
|
|
6
|
+
const DEFAULT_SUBPATH = path.join("saltygen", "cache", "config-cache.json");
|
|
7
|
+
const resolveCopyConfigCacheDestinations = (option, defaultOutDir, cwd = process.cwd()) => {
|
|
8
|
+
if (option === false) return [];
|
|
9
|
+
const userPaths = [];
|
|
10
|
+
if (typeof option === "string") userPaths.push(option);
|
|
11
|
+
else if (Array.isArray(option)) userPaths.push(...option);
|
|
12
|
+
const destinations = [];
|
|
13
|
+
const useDefault = option === void 0 || option === true;
|
|
14
|
+
if (useDefault && defaultOutDir) destinations.push(defaultOutDir);
|
|
15
|
+
destinations.push(...userPaths);
|
|
16
|
+
return destinations.map((entry) => {
|
|
17
|
+
const abs = path.isAbsolute(entry) ? entry : path.resolve(cwd, entry);
|
|
18
|
+
if (abs.endsWith(".json")) return abs;
|
|
19
|
+
return path.join(abs, DEFAULT_SUBPATH);
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
const copyConfigCacheTo = async (compiler, destinations) => {
|
|
23
|
+
if (destinations.length === 0) return;
|
|
24
|
+
const source = await compiler.getConfigCachePath();
|
|
25
|
+
await Promise.all(
|
|
26
|
+
destinations.map(async (destination) => {
|
|
27
|
+
if (destination === source) return;
|
|
28
|
+
try {
|
|
29
|
+
await promises.mkdir(path.dirname(destination), { recursive: true });
|
|
30
|
+
await promises.copyFile(source, destination);
|
|
31
|
+
logger.logger.info(`Copied Salty config cache → ${destination}`);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
logger.logger.warn(`Failed to copy Salty config cache to ${destination}: ${error.message}`);
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
exports.copyConfigCacheTo = copyConfigCacheTo;
|
|
39
|
+
exports.resolveCopyConfigCacheDestinations = resolveCopyConfigCacheDestinations;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { SaltyCompiler } from './salty-compiler';
|
|
2
|
+
/**
|
|
3
|
+
* `copyConfigCache` plugin option:
|
|
4
|
+
* - `true` → copy to the bundler's resolved output dir (default).
|
|
5
|
+
* - `false` → no-op.
|
|
6
|
+
* - `string | string[]` → copy to the default destination PLUS each listed path.
|
|
7
|
+
*
|
|
8
|
+
* Each path can be a directory (the file is written as `saltygen/cache/config-cache.json` inside)
|
|
9
|
+
* or a path ending in `.json` (used verbatim).
|
|
10
|
+
*/
|
|
11
|
+
export type CopyConfigCacheOption = boolean | string | string[];
|
|
12
|
+
export declare const resolveCopyConfigCacheDestinations: (option: CopyConfigCacheOption | undefined, defaultOutDir: string | undefined, cwd?: string) => string[];
|
|
13
|
+
/**
|
|
14
|
+
* Copy the compiler's `config-cache.json` to each absolute destination path.
|
|
15
|
+
* Creates parent directories as needed; silently skips destinations equal to the source.
|
|
16
|
+
*/
|
|
17
|
+
export declare const copyConfigCacheTo: (compiler: SaltyCompiler, destinations: string[]) => Promise<void>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { mkdir, copyFile } from "fs/promises";
|
|
2
|
+
import { join, dirname, isAbsolute, resolve } from "path";
|
|
3
|
+
import { l as logger } from "../logger-hHmCwThj.js";
|
|
4
|
+
const DEFAULT_SUBPATH = join("saltygen", "cache", "config-cache.json");
|
|
5
|
+
const resolveCopyConfigCacheDestinations = (option, defaultOutDir, cwd = process.cwd()) => {
|
|
6
|
+
if (option === false) return [];
|
|
7
|
+
const userPaths = [];
|
|
8
|
+
if (typeof option === "string") userPaths.push(option);
|
|
9
|
+
else if (Array.isArray(option)) userPaths.push(...option);
|
|
10
|
+
const destinations = [];
|
|
11
|
+
const useDefault = option === void 0 || option === true;
|
|
12
|
+
if (useDefault && defaultOutDir) destinations.push(defaultOutDir);
|
|
13
|
+
destinations.push(...userPaths);
|
|
14
|
+
return destinations.map((entry) => {
|
|
15
|
+
const abs = isAbsolute(entry) ? entry : resolve(cwd, entry);
|
|
16
|
+
if (abs.endsWith(".json")) return abs;
|
|
17
|
+
return join(abs, DEFAULT_SUBPATH);
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
const copyConfigCacheTo = async (compiler, destinations) => {
|
|
21
|
+
if (destinations.length === 0) return;
|
|
22
|
+
const source = await compiler.getConfigCachePath();
|
|
23
|
+
await Promise.all(
|
|
24
|
+
destinations.map(async (destination) => {
|
|
25
|
+
if (destination === source) return;
|
|
26
|
+
try {
|
|
27
|
+
await mkdir(dirname(destination), { recursive: true });
|
|
28
|
+
await copyFile(source, destination);
|
|
29
|
+
logger.info(`Copied Salty config cache → ${destination}`);
|
|
30
|
+
} catch (error) {
|
|
31
|
+
logger.warn(`Failed to copy Salty config cache to ${destination}: ${error.message}`);
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
export {
|
|
37
|
+
copyConfigCacheTo,
|
|
38
|
+
resolveCopyConfigCacheDestinations
|
|
39
|
+
};
|