@salty-css/core 0.1.0-feat-define-import.0 → 0.1.0-feat-template-variants.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/README.md +0 -44
- package/{class-name-generator-CMWY5KTJ.js → class-name-generator-Bk5QMTEg.js} +1 -1
- package/{class-name-generator-DB5aQwC_.cjs → class-name-generator-DtC44Fgz.cjs} +1 -1
- package/compiler/salty-compiler.cjs +50 -83
- package/compiler/salty-compiler.d.ts +0 -1
- package/compiler/salty-compiler.js +51 -85
- package/config/index.cjs +0 -2
- package/config/index.js +1 -3
- package/css/dynamic-styles.cjs +1 -1
- package/css/dynamic-styles.js +1 -1
- package/css/keyframes.cjs +1 -1
- package/css/keyframes.js +1 -1
- package/factories/index.cjs +0 -19
- package/factories/index.d.ts +0 -1
- package/factories/index.js +0 -19
- 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/package.json +1 -1
- package/{parse-styles-CLMTHo2H.js → parse-styles-DSyVPjDG.js} +187 -6
- package/{parse-styles-C54MOrPg.cjs → parse-styles-DxyVq07D.cjs} +187 -6
- package/parsers/index.cjs +80 -3
- package/parsers/index.js +81 -4
- package/parsers/parse-templates.d.ts +10 -0
- package/parsers/resolve-template-variants.d.ts +21 -0
- package/runtime/index.cjs +1 -1
- package/runtime/index.js +1 -1
- package/types/config-types.d.ts +32 -1
- package/compiler/resolve-import.d.ts +0 -17
- package/factories/define-import.d.ts +0 -14
package/README.md
CHANGED
|
@@ -57,7 +57,6 @@ To get help with problems, [Join Salty CSS Discord server](https://discord.gg/R6
|
|
|
57
57
|
- [defineVariables](#variables) - create CSS variables (tokens) that can be used in any styling function
|
|
58
58
|
- [defineMediaQuery](#media-queries) - create CSS media queries and use them in any styling function
|
|
59
59
|
- [defineTemplates](#templates) - create reusable templates that can be applied when same styles are used over and over again
|
|
60
|
-
- [defineImport](#importing-additional-css) - pull in external CSS files (relative, public, node_modules, or URL)
|
|
61
60
|
- [keyframes](#keyframes-animations) - create CSS keyframes animation that can be used and imported in any styling function
|
|
62
61
|
|
|
63
62
|
### Styling helpers & utility
|
|
@@ -320,49 +319,6 @@ Example usage:
|
|
|
320
319
|
styled('div', { base: { textStyle: 'headline.large', card: '20px' } });
|
|
321
320
|
```
|
|
322
321
|
|
|
323
|
-
## Importing additional CSS
|
|
324
|
-
|
|
325
|
-
Use `defineImport` to pull in CSS that lives outside of Salty's authoring API — a reset stylesheet from npm, a Google Fonts URL, an asset in your app's `public/` folder, or a sibling `.css` file. The compiler turns each spec into an `@import` rule in the generated `saltygen/index.css`, so the imported stylesheets travel with the rest of your build.
|
|
326
|
-
|
|
327
|
-
```ts
|
|
328
|
-
// /styles/imports.css.ts
|
|
329
|
-
import { defineImport } from '@salty-css/core/factories';
|
|
330
|
-
|
|
331
|
-
export default defineImport(
|
|
332
|
-
// Relative to this file
|
|
333
|
-
'./reset.css',
|
|
334
|
-
// From node_modules (bare specifier — same as Vite / native CSS @import)
|
|
335
|
-
'modern-normalize/modern-normalize.css',
|
|
336
|
-
// From node_modules (~ prefix — same resolver, webpack-style)
|
|
337
|
-
'~normalize.css/normalize.css',
|
|
338
|
-
// From your app's public/ folder (served at the host root)
|
|
339
|
-
'/fonts/inter.css',
|
|
340
|
-
// External URL
|
|
341
|
-
'https://fonts.googleapis.com/css2?family=Inter&display=swap',
|
|
342
|
-
// Object form — attach media or supports() conditions
|
|
343
|
-
{ url: './print.css', media: 'print' },
|
|
344
|
-
{ url: './p3.css', supports: 'color(display-p3 1 1 1)' }
|
|
345
|
-
);
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
Path resolution:
|
|
349
|
-
|
|
350
|
-
| Pattern | Behaviour |
|
|
351
|
-
| --------------------------- | ---------------------------------------------------------------------------------------- |
|
|
352
|
-
| `http://`, `https://`, `//` | Emitted verbatim |
|
|
353
|
-
| Starts with `/` | Public-folder URL — emitted verbatim, the browser resolves it against your host |
|
|
354
|
-
| Starts with `./` or `../` | Resolved at build time relative to the file that called `defineImport` |
|
|
355
|
-
| `~package/file.css` | Stripped of the leading `~`, then resolved from `node_modules` and copied into the build |
|
|
356
|
-
| `package/file.css` (bare) | Same `node_modules` resolution as the `~` form |
|
|
357
|
-
|
|
358
|
-
All imports are placed inside a new `imports` cascade layer that sits **before** `reset`, `global`, `templates`, and your component styles. This means your own styles always win over third-party CSS you pull in — which is what most teams expect when they drop in something like `modern-normalize`.
|
|
359
|
-
|
|
360
|
-
The full layer order in the generated `index.css` is:
|
|
361
|
-
|
|
362
|
-
```css
|
|
363
|
-
@layer imports, reset, global, templates, l0, l1, l2, l3, l4, l5, l6, l7, l8;
|
|
364
|
-
```
|
|
365
|
-
|
|
366
322
|
## Keyframes animations
|
|
367
323
|
|
|
368
324
|
```ts
|
|
@@ -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-DSyVPjDG.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-DxyVq07D.cjs");
|
|
6
6
|
const dashCase = require("./dash-case-DIwKaYgE.cjs");
|
|
7
7
|
const toHash = require("./to-hash-C05Y906F.cjs");
|
|
8
8
|
class StylesGenerator {
|
|
@@ -11,14 +11,14 @@ const fs = require("fs");
|
|
|
11
11
|
const child_process = require("child_process");
|
|
12
12
|
const compiler_helpers = require("./helpers.cjs");
|
|
13
13
|
const defineTemplates = require("../define-templates-Deq1aCbN.cjs");
|
|
14
|
-
const module$1 = require("module");
|
|
15
|
-
const toHash = require("../to-hash-C05Y906F.cjs");
|
|
16
14
|
const dashCase = require("../dash-case-DIwKaYgE.cjs");
|
|
17
|
-
const
|
|
15
|
+
const toHash = require("../to-hash-C05Y906F.cjs");
|
|
16
|
+
const parseStyles = require("../parse-styles-DxyVq07D.cjs");
|
|
18
17
|
const css_merge = require("../css/merge.cjs");
|
|
19
18
|
const parsers_index = require("../parsers/index.cjs");
|
|
20
|
-
const
|
|
19
|
+
const compiler_getFiles = require("./get-files.cjs");
|
|
21
20
|
const console = require("console");
|
|
21
|
+
var _documentCurrentScript = typeof document !== "undefined" ? document.currentScript : null;
|
|
22
22
|
function _interopNamespaceDefault(e) {
|
|
23
23
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
24
24
|
if (e) {
|
|
@@ -44,53 +44,19 @@ const logger = winston.createLogger({
|
|
|
44
44
|
const logError = (message) => {
|
|
45
45
|
logger.error(message);
|
|
46
46
|
};
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
if (
|
|
50
|
-
return
|
|
51
|
-
};
|
|
52
|
-
const ensureRelativePrefix = (path2) => {
|
|
53
|
-
if (path2.startsWith(".") || path2.startsWith("/")) return path2;
|
|
54
|
-
return `./${path2}`;
|
|
55
|
-
};
|
|
56
|
-
const toPosix = (path2) => path2.split("\\").join("/");
|
|
57
|
-
const defaultResolveModule = (specifier, sourceFile) => {
|
|
58
|
-
return module$1.createRequire(sourceFile).resolve(specifier);
|
|
59
|
-
};
|
|
60
|
-
const defaultCopyAsset = (from, to) => {
|
|
61
|
-
const dir = path.dirname(to);
|
|
62
|
-
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
63
|
-
fs.copyFileSync(from, to);
|
|
47
|
+
const readPackageJsonModule = async (dirname) => {
|
|
48
|
+
const packageJsonContent = await compiler_getFiles.getPackageJson(dirname);
|
|
49
|
+
if (!packageJsonContent) return void 0;
|
|
50
|
+
return packageJsonContent.type;
|
|
64
51
|
};
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const { url } = opts;
|
|
74
|
-
const resolveModule = options.resolveModule ?? defaultResolveModule;
|
|
75
|
-
const copyAsset = options.copyAsset ?? defaultCopyAsset;
|
|
76
|
-
if (EXTERNAL_URL.test(url)) {
|
|
77
|
-
return { rule: buildRule(url, opts) };
|
|
78
|
-
}
|
|
79
|
-
if (url.startsWith("/")) {
|
|
80
|
-
return { rule: buildRule(url, opts) };
|
|
81
|
-
}
|
|
82
|
-
if (url.startsWith("./") || url.startsWith("../")) {
|
|
83
|
-
const absolute2 = path.resolve(path.dirname(sourceFile), url);
|
|
84
|
-
const fromImportsFile = path.relative(path.join(destDir, "css"), absolute2);
|
|
85
|
-
return { rule: buildRule(ensureRelativePrefix(toPosix(fromImportsFile)), opts) };
|
|
86
|
-
}
|
|
87
|
-
const specifier = url.startsWith("~") ? url.slice(1) : url;
|
|
88
|
-
const absolute = resolveModule(specifier, sourceFile);
|
|
89
|
-
const hash = toHash.toHash(absolute, 6);
|
|
90
|
-
const fileName = `${hash}-${path.basename(absolute)}`;
|
|
91
|
-
const destPath = path.join(destDir, "imports", fileName);
|
|
92
|
-
copyAsset(absolute, destPath);
|
|
93
|
-
return { rule: buildRule(`../imports/${fileName}`, opts) };
|
|
52
|
+
let cachedModuleType;
|
|
53
|
+
const detectCurrentModuleType = async (dirname) => {
|
|
54
|
+
if (cachedModuleType) return cachedModuleType;
|
|
55
|
+
const packageJsonModule = await readPackageJsonModule(dirname);
|
|
56
|
+
if (packageJsonModule === "module") cachedModuleType = "esm";
|
|
57
|
+
else if (packageJsonModule === "commonjs") 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";
|
|
59
|
+
return cachedModuleType || "esm";
|
|
94
60
|
};
|
|
95
61
|
function dotCase(str) {
|
|
96
62
|
if (!str) return "";
|
|
@@ -207,7 +173,7 @@ class SaltyCompiler {
|
|
|
207
173
|
const destDir = await this.getDestDir();
|
|
208
174
|
const coreConfigPath = path.join(this.projectRootDir, (rcProject == null ? void 0 : rcProject.configDir) || "", "salty.config.ts");
|
|
209
175
|
const coreConfigDest = path.join(destDir, "salty.config.js");
|
|
210
|
-
const moduleType
|
|
176
|
+
const moduleType = await detectCurrentModuleType(this.projectRootDir);
|
|
211
177
|
const externalModules = this.getExternalModules(coreConfigPath);
|
|
212
178
|
await esbuild__namespace.build({
|
|
213
179
|
entryPoints: [coreConfigPath],
|
|
@@ -215,7 +181,7 @@ class SaltyCompiler {
|
|
|
215
181
|
treeShaking: true,
|
|
216
182
|
bundle: true,
|
|
217
183
|
outfile: coreConfigDest,
|
|
218
|
-
format: moduleType
|
|
184
|
+
format: moduleType,
|
|
219
185
|
external: externalModules
|
|
220
186
|
});
|
|
221
187
|
const { config } = await this.importFile(coreConfigDest);
|
|
@@ -267,7 +233,6 @@ ${currentFile}`;
|
|
|
267
233
|
fs.mkdirSync(path.join(destDir, "types"));
|
|
268
234
|
fs.mkdirSync(path.join(destDir, "js"));
|
|
269
235
|
fs.mkdirSync(path.join(destDir, "cache"));
|
|
270
|
-
fs.mkdirSync(path.join(destDir, "imports"));
|
|
271
236
|
};
|
|
272
237
|
if (clean) clearDistDir();
|
|
273
238
|
const files = /* @__PURE__ */ new Set();
|
|
@@ -383,7 +348,7 @@ ${currentFile}`;
|
|
|
383
348
|
});
|
|
384
349
|
}
|
|
385
350
|
const otherGlobalCssFiles = globalCssFiles.map((file) => `@import url('./css/${file}');`).join("\n");
|
|
386
|
-
const globalCssFilenames = ["
|
|
351
|
+
const globalCssFilenames = ["_variables.css", "_reset.css", "_global.css", "_templates.css"];
|
|
387
352
|
const importsWithData = globalCssFilenames.filter((file) => {
|
|
388
353
|
try {
|
|
389
354
|
const data = fs.readFileSync(path.join(destDir, "css", file), "utf8");
|
|
@@ -392,12 +357,9 @@ ${currentFile}`;
|
|
|
392
357
|
return false;
|
|
393
358
|
}
|
|
394
359
|
});
|
|
395
|
-
const globalImports = importsWithData.map((file) => {
|
|
396
|
-
const layerSuffix = file === "_imports.css" ? " layer(imports)" : "";
|
|
397
|
-
return `@import url('./css/${file}')${layerSuffix};`;
|
|
398
|
-
});
|
|
360
|
+
const globalImports = importsWithData.map((file) => `@import url('./css/${file}');`);
|
|
399
361
|
const generatorText = "/*!\n * Generated with Salty CSS (https://salty-css.dev)\n * Do not edit this file directly\n */\n";
|
|
400
|
-
let cssContent = `${generatorText}@layer
|
|
362
|
+
let cssContent = `${generatorText}@layer reset, global, templates, l0, l1, l2, l3, l4, l5, l6, l7, l8;
|
|
401
363
|
|
|
402
364
|
${globalImports.join(
|
|
403
365
|
"\n"
|
|
@@ -443,8 +405,7 @@ ${css}
|
|
|
443
405
|
mediaQueries: [],
|
|
444
406
|
globalStyles: [],
|
|
445
407
|
variables: [],
|
|
446
|
-
templates: []
|
|
447
|
-
imports: []
|
|
408
|
+
templates: []
|
|
448
409
|
};
|
|
449
410
|
await Promise.all(
|
|
450
411
|
[...configFiles].map(async (src) => {
|
|
@@ -454,7 +415,6 @@ ${css}
|
|
|
454
415
|
else if (value.isGlobalDefine) generationResults.globalStyles.push(value);
|
|
455
416
|
else if (value.isDefineVariables) generationResults.variables.push(value);
|
|
456
417
|
else if (value.isDefineTemplates) generationResults.templates.push(value._setPath(`${name};;${outputFilePath}`));
|
|
457
|
-
else if (value.isDefineImport) generationResults.imports.push(value._setPath(src));
|
|
458
418
|
});
|
|
459
419
|
})
|
|
460
420
|
);
|
|
@@ -551,39 +511,46 @@ ${css}
|
|
|
551
511
|
const templates = css_merge.mergeObjects(config.templates, generationResults.templates);
|
|
552
512
|
const templateStylesString = await parsers_index.parseTemplates(templates);
|
|
553
513
|
const templateTokens = parsers_index.getTemplateTypes(templates);
|
|
514
|
+
const templateVariantMaps = parsers_index.getTemplateVariantMaps(templates);
|
|
554
515
|
fs.writeFileSync(templateStylesPath, `@layer templates { ${templateStylesString} }`);
|
|
555
516
|
configCacheContent.templates = templates;
|
|
556
|
-
const importsPath = path.join(destDir, "css/_imports.css");
|
|
557
|
-
const importRules = [];
|
|
558
|
-
for (const factory of generationResults.imports) {
|
|
559
|
-
const sourceFile = factory._path;
|
|
560
|
-
if (!sourceFile) continue;
|
|
561
|
-
for (const spec of factory._current) {
|
|
562
|
-
try {
|
|
563
|
-
const { rule } = resolveImport(spec, sourceFile, destDir);
|
|
564
|
-
importRules.push(rule);
|
|
565
|
-
} catch (e) {
|
|
566
|
-
const url = typeof spec === "string" ? spec : spec.url;
|
|
567
|
-
logger.error(`Failed to resolve defineImport(${JSON.stringify(url)}) from ${sourceFile}: ${e.message}`);
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
fs.writeFileSync(importsPath, importRules.join("\n"));
|
|
572
517
|
const configTemplateFactories = config.templates ? [defineTemplates.defineTemplates(config.templates)._setPath(`config;;${configPath}`)] : [];
|
|
573
518
|
const templateFactories = css_merge.mergeFactories(generationResults.templates, configTemplateFactories);
|
|
574
519
|
configCacheContent.templatePaths = Object.fromEntries(Object.entries(templateFactories).map(([key, faktory]) => [key, faktory._path]));
|
|
575
520
|
const tsTokensPath = path.join(destDir, "types/css-tokens.d.ts");
|
|
576
521
|
const tsVariableTokens = [...variableTokens].join("|");
|
|
522
|
+
const pascal = (str) => str.split(/[.\-_]/).filter(Boolean).map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("");
|
|
523
|
+
const templateVariantMapEntries = Object.entries(templateVariantMaps);
|
|
524
|
+
const hasVariantMaps = templateVariantMapEntries.some(([, pathMap]) => Object.keys(pathMap).length > 0);
|
|
525
|
+
const tsTemplateVariantMap = hasVariantMaps ? `type TemplateVariantTokens = {
|
|
526
|
+
${templateVariantMapEntries.filter(([, pathMap]) => Object.keys(pathMap).length > 0).map(([templateKey, pathMap]) => {
|
|
527
|
+
const pathEntries = Object.entries(pathMap).map(
|
|
528
|
+
([dotPath, axes]) => `'${dotPath}': { ${Object.entries(axes).map(([axis, valueType]) => `${axis}?: ${valueType}`).join("; ")} }`
|
|
529
|
+
).join(";\n ");
|
|
530
|
+
return `${templateKey}: {
|
|
531
|
+
${pathEntries}
|
|
532
|
+
}`;
|
|
533
|
+
}).join(";\n ")}
|
|
534
|
+
}` : `type TemplateVariantTokens = Record<string, Record<string, Record<string, never>>>;`;
|
|
535
|
+
const tsTemplateVariantAliases = templateVariantMapEntries.flatMap(
|
|
536
|
+
([templateKey, pathMap]) => Object.keys(pathMap).map(
|
|
537
|
+
(dotPath) => `type ${pascal(templateKey)}${pascal(dotPath)}Variants = TemplateVariantTokens['${templateKey}']['${dotPath}'];`
|
|
538
|
+
)
|
|
539
|
+
).join("\n ");
|
|
577
540
|
const tsTokensTypes = `
|
|
578
541
|
// Variable types
|
|
579
|
-
type VariableTokens = ${tsVariableTokens || `''`};
|
|
542
|
+
type VariableTokens = ${tsVariableTokens || `''`};
|
|
580
543
|
type PropertyValueToken = \`{\${VariableTokens}}\`;
|
|
581
|
-
|
|
544
|
+
|
|
582
545
|
// Template types
|
|
583
546
|
type TemplateTokens = {
|
|
584
547
|
${Object.entries(templateTokens).map(([key, value]) => `${key}?: ${value}`).join("\n")}
|
|
585
548
|
}
|
|
586
|
-
|
|
549
|
+
|
|
550
|
+
// Template variant types (per docs/template-variants-spec.md §7)
|
|
551
|
+
${tsTemplateVariantMap}
|
|
552
|
+
${tsTemplateVariantAliases}
|
|
553
|
+
|
|
587
554
|
// Media query types
|
|
588
555
|
type MediaQueryKeys = ${mediaQueryKeys || `''`};
|
|
589
556
|
`;
|
|
@@ -607,7 +574,7 @@ ${css}
|
|
|
607
574
|
const rcProject = await this.getRCProjectConfig(this.projectRootDir);
|
|
608
575
|
const coreConfigPath = path.join(this.projectRootDir, (rcProject == null ? void 0 : rcProject.configDir) || "", "salty.config.ts");
|
|
609
576
|
const externalModules = this.getExternalModules(coreConfigPath);
|
|
610
|
-
const moduleType
|
|
577
|
+
const moduleType = await detectCurrentModuleType(this.projectRootDir);
|
|
611
578
|
await esbuild__namespace.build({
|
|
612
579
|
stdin: {
|
|
613
580
|
contents: currentFile,
|
|
@@ -619,7 +586,7 @@ ${css}
|
|
|
619
586
|
treeShaking: true,
|
|
620
587
|
bundle: true,
|
|
621
588
|
outfile: outputFilePath,
|
|
622
|
-
format: moduleType
|
|
589
|
+
format: moduleType,
|
|
623
590
|
target: ["node20"],
|
|
624
591
|
keepNames: true,
|
|
625
592
|
external: externalModules,
|
|
@@ -2,20 +2,19 @@ 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
4
|
import * as esbuild from "esbuild";
|
|
5
|
-
import {
|
|
5
|
+
import { join, parse } from "path";
|
|
6
6
|
import { createLogger, transports, format } from "winston";
|
|
7
7
|
import { readFile } from "fs/promises";
|
|
8
|
-
import { existsSync, mkdirSync,
|
|
8
|
+
import { readFileSync, existsSync, mkdirSync, statSync, readdirSync, writeFileSync } from "fs";
|
|
9
9
|
import { execSync } from "child_process";
|
|
10
10
|
import { isSaltyFile, resolveExportValue, getCorePackageRoot, saltyFileExtensions } from "./helpers.js";
|
|
11
11
|
import { d as defineTemplates } from "../define-templates-CVhhgPnd.js";
|
|
12
|
-
import { createRequire } from "module";
|
|
13
|
-
import { t as toHash } from "../to-hash-DAN2LcHK.js";
|
|
14
12
|
import { d as dashCase } from "../dash-case-DblXvymC.js";
|
|
15
|
-
import {
|
|
13
|
+
import { t as toHash } from "../to-hash-DAN2LcHK.js";
|
|
14
|
+
import { p as parseAndJoinStyles, b as parseVariableTokens } from "../parse-styles-DSyVPjDG.js";
|
|
16
15
|
import { mergeObjects, mergeFactories } from "../css/merge.js";
|
|
17
|
-
import { parseTemplates, getTemplateTypes } from "../parsers/index.js";
|
|
18
|
-
import {
|
|
16
|
+
import { parseTemplates, getTemplateTypes, getTemplateVariantMaps } from "../parsers/index.js";
|
|
17
|
+
import { getPackageJson } from "./get-files.js";
|
|
19
18
|
import console from "console";
|
|
20
19
|
const logger = createLogger({
|
|
21
20
|
level: "debug",
|
|
@@ -25,53 +24,19 @@ const logger = createLogger({
|
|
|
25
24
|
const logError = (message) => {
|
|
26
25
|
logger.error(message);
|
|
27
26
|
};
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
if (
|
|
31
|
-
return
|
|
32
|
-
};
|
|
33
|
-
const ensureRelativePrefix = (path) => {
|
|
34
|
-
if (path.startsWith(".") || path.startsWith("/")) return path;
|
|
35
|
-
return `./${path}`;
|
|
36
|
-
};
|
|
37
|
-
const toPosix = (path) => path.split("\\").join("/");
|
|
38
|
-
const defaultResolveModule = (specifier, sourceFile) => {
|
|
39
|
-
return createRequire(sourceFile).resolve(specifier);
|
|
40
|
-
};
|
|
41
|
-
const defaultCopyAsset = (from, to) => {
|
|
42
|
-
const dir = dirname(to);
|
|
43
|
-
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
44
|
-
copyFileSync(from, to);
|
|
27
|
+
const readPackageJsonModule = async (dirname) => {
|
|
28
|
+
const packageJsonContent = await getPackageJson(dirname);
|
|
29
|
+
if (!packageJsonContent) return void 0;
|
|
30
|
+
return packageJsonContent.type;
|
|
45
31
|
};
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const { url } = opts;
|
|
55
|
-
const resolveModule = options.resolveModule ?? defaultResolveModule;
|
|
56
|
-
const copyAsset = options.copyAsset ?? defaultCopyAsset;
|
|
57
|
-
if (EXTERNAL_URL.test(url)) {
|
|
58
|
-
return { rule: buildRule(url, opts) };
|
|
59
|
-
}
|
|
60
|
-
if (url.startsWith("/")) {
|
|
61
|
-
return { rule: buildRule(url, opts) };
|
|
62
|
-
}
|
|
63
|
-
if (url.startsWith("./") || url.startsWith("../")) {
|
|
64
|
-
const absolute2 = resolve(dirname(sourceFile), url);
|
|
65
|
-
const fromImportsFile = relative(join(destDir, "css"), absolute2);
|
|
66
|
-
return { rule: buildRule(ensureRelativePrefix(toPosix(fromImportsFile)), opts) };
|
|
67
|
-
}
|
|
68
|
-
const specifier = url.startsWith("~") ? url.slice(1) : url;
|
|
69
|
-
const absolute = resolveModule(specifier, sourceFile);
|
|
70
|
-
const hash = toHash(absolute, 6);
|
|
71
|
-
const fileName = `${hash}-${basename(absolute)}`;
|
|
72
|
-
const destPath = join(destDir, "imports", fileName);
|
|
73
|
-
copyAsset(absolute, destPath);
|
|
74
|
-
return { rule: buildRule(`../imports/${fileName}`, opts) };
|
|
32
|
+
let cachedModuleType;
|
|
33
|
+
const detectCurrentModuleType = async (dirname) => {
|
|
34
|
+
if (cachedModuleType) return cachedModuleType;
|
|
35
|
+
const packageJsonModule = await readPackageJsonModule(dirname);
|
|
36
|
+
if (packageJsonModule === "module") cachedModuleType = "esm";
|
|
37
|
+
else if (packageJsonModule === "commonjs") cachedModuleType = "cjs";
|
|
38
|
+
else if (import.meta.url.endsWith(".cjs")) cachedModuleType = "cjs";
|
|
39
|
+
return cachedModuleType || "esm";
|
|
75
40
|
};
|
|
76
41
|
function dotCase(str) {
|
|
77
42
|
if (!str) return "";
|
|
@@ -156,10 +121,10 @@ class SaltyCompiler {
|
|
|
156
121
|
* Get the project configuration from the .saltyrc.json file based on the current directory.
|
|
157
122
|
* If no specific project configuration is found, it falls back to the default project.
|
|
158
123
|
*/
|
|
159
|
-
__publicField(this, "getRCProjectConfig", async (
|
|
124
|
+
__publicField(this, "getRCProjectConfig", async (dirname) => {
|
|
160
125
|
var _a, _b;
|
|
161
|
-
const rcFile = await this.readRCFile(
|
|
162
|
-
const projectConfig = (_a = rcFile.projects) == null ? void 0 : _a.find((project) =>
|
|
126
|
+
const rcFile = await this.readRCFile(dirname);
|
|
127
|
+
const projectConfig = (_a = rcFile.projects) == null ? void 0 : _a.find((project) => dirname.endsWith(project.dir || ""));
|
|
163
128
|
if (!projectConfig) return (_b = rcFile.projects) == null ? void 0 : _b.find((project) => project.dir === rcFile.defaultProject);
|
|
164
129
|
return projectConfig;
|
|
165
130
|
});
|
|
@@ -248,7 +213,6 @@ ${currentFile}`;
|
|
|
248
213
|
mkdirSync(join(destDir, "types"));
|
|
249
214
|
mkdirSync(join(destDir, "js"));
|
|
250
215
|
mkdirSync(join(destDir, "cache"));
|
|
251
|
-
mkdirSync(join(destDir, "imports"));
|
|
252
216
|
};
|
|
253
217
|
if (clean) clearDistDir();
|
|
254
218
|
const files = /* @__PURE__ */ new Set();
|
|
@@ -364,7 +328,7 @@ ${currentFile}`;
|
|
|
364
328
|
});
|
|
365
329
|
}
|
|
366
330
|
const otherGlobalCssFiles = globalCssFiles.map((file) => `@import url('./css/${file}');`).join("\n");
|
|
367
|
-
const globalCssFilenames = ["
|
|
331
|
+
const globalCssFilenames = ["_variables.css", "_reset.css", "_global.css", "_templates.css"];
|
|
368
332
|
const importsWithData = globalCssFilenames.filter((file) => {
|
|
369
333
|
try {
|
|
370
334
|
const data = readFileSync(join(destDir, "css", file), "utf8");
|
|
@@ -373,12 +337,9 @@ ${currentFile}`;
|
|
|
373
337
|
return false;
|
|
374
338
|
}
|
|
375
339
|
});
|
|
376
|
-
const globalImports = importsWithData.map((file) => {
|
|
377
|
-
const layerSuffix = file === "_imports.css" ? " layer(imports)" : "";
|
|
378
|
-
return `@import url('./css/${file}')${layerSuffix};`;
|
|
379
|
-
});
|
|
340
|
+
const globalImports = importsWithData.map((file) => `@import url('./css/${file}');`);
|
|
380
341
|
const generatorText = "/*!\n * Generated with Salty CSS (https://salty-css.dev)\n * Do not edit this file directly\n */\n";
|
|
381
|
-
let cssContent = `${generatorText}@layer
|
|
342
|
+
let cssContent = `${generatorText}@layer reset, global, templates, l0, l1, l2, l3, l4, l5, l6, l7, l8;
|
|
382
343
|
|
|
383
344
|
${globalImports.join(
|
|
384
345
|
"\n"
|
|
@@ -424,8 +385,7 @@ ${css}
|
|
|
424
385
|
mediaQueries: [],
|
|
425
386
|
globalStyles: [],
|
|
426
387
|
variables: [],
|
|
427
|
-
templates: []
|
|
428
|
-
imports: []
|
|
388
|
+
templates: []
|
|
429
389
|
};
|
|
430
390
|
await Promise.all(
|
|
431
391
|
[...configFiles].map(async (src) => {
|
|
@@ -435,7 +395,6 @@ ${css}
|
|
|
435
395
|
else if (value.isGlobalDefine) generationResults.globalStyles.push(value);
|
|
436
396
|
else if (value.isDefineVariables) generationResults.variables.push(value);
|
|
437
397
|
else if (value.isDefineTemplates) generationResults.templates.push(value._setPath(`${name};;${outputFilePath}`));
|
|
438
|
-
else if (value.isDefineImport) generationResults.imports.push(value._setPath(src));
|
|
439
398
|
});
|
|
440
399
|
})
|
|
441
400
|
);
|
|
@@ -532,39 +491,46 @@ ${css}
|
|
|
532
491
|
const templates = mergeObjects(config.templates, generationResults.templates);
|
|
533
492
|
const templateStylesString = await parseTemplates(templates);
|
|
534
493
|
const templateTokens = getTemplateTypes(templates);
|
|
494
|
+
const templateVariantMaps = getTemplateVariantMaps(templates);
|
|
535
495
|
writeFileSync(templateStylesPath, `@layer templates { ${templateStylesString} }`);
|
|
536
496
|
configCacheContent.templates = templates;
|
|
537
|
-
const importsPath = join(destDir, "css/_imports.css");
|
|
538
|
-
const importRules = [];
|
|
539
|
-
for (const factory of generationResults.imports) {
|
|
540
|
-
const sourceFile = factory._path;
|
|
541
|
-
if (!sourceFile) continue;
|
|
542
|
-
for (const spec of factory._current) {
|
|
543
|
-
try {
|
|
544
|
-
const { rule } = resolveImport(spec, sourceFile, destDir);
|
|
545
|
-
importRules.push(rule);
|
|
546
|
-
} catch (e) {
|
|
547
|
-
const url = typeof spec === "string" ? spec : spec.url;
|
|
548
|
-
logger.error(`Failed to resolve defineImport(${JSON.stringify(url)}) from ${sourceFile}: ${e.message}`);
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
writeFileSync(importsPath, importRules.join("\n"));
|
|
553
497
|
const configTemplateFactories = config.templates ? [defineTemplates(config.templates)._setPath(`config;;${configPath}`)] : [];
|
|
554
498
|
const templateFactories = mergeFactories(generationResults.templates, configTemplateFactories);
|
|
555
499
|
configCacheContent.templatePaths = Object.fromEntries(Object.entries(templateFactories).map(([key, faktory]) => [key, faktory._path]));
|
|
556
500
|
const tsTokensPath = join(destDir, "types/css-tokens.d.ts");
|
|
557
501
|
const tsVariableTokens = [...variableTokens].join("|");
|
|
502
|
+
const pascal = (str) => str.split(/[.\-_]/).filter(Boolean).map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("");
|
|
503
|
+
const templateVariantMapEntries = Object.entries(templateVariantMaps);
|
|
504
|
+
const hasVariantMaps = templateVariantMapEntries.some(([, pathMap]) => Object.keys(pathMap).length > 0);
|
|
505
|
+
const tsTemplateVariantMap = hasVariantMaps ? `type TemplateVariantTokens = {
|
|
506
|
+
${templateVariantMapEntries.filter(([, pathMap]) => Object.keys(pathMap).length > 0).map(([templateKey, pathMap]) => {
|
|
507
|
+
const pathEntries = Object.entries(pathMap).map(
|
|
508
|
+
([dotPath, axes]) => `'${dotPath}': { ${Object.entries(axes).map(([axis, valueType]) => `${axis}?: ${valueType}`).join("; ")} }`
|
|
509
|
+
).join(";\n ");
|
|
510
|
+
return `${templateKey}: {
|
|
511
|
+
${pathEntries}
|
|
512
|
+
}`;
|
|
513
|
+
}).join(";\n ")}
|
|
514
|
+
}` : `type TemplateVariantTokens = Record<string, Record<string, Record<string, never>>>;`;
|
|
515
|
+
const tsTemplateVariantAliases = templateVariantMapEntries.flatMap(
|
|
516
|
+
([templateKey, pathMap]) => Object.keys(pathMap).map(
|
|
517
|
+
(dotPath) => `type ${pascal(templateKey)}${pascal(dotPath)}Variants = TemplateVariantTokens['${templateKey}']['${dotPath}'];`
|
|
518
|
+
)
|
|
519
|
+
).join("\n ");
|
|
558
520
|
const tsTokensTypes = `
|
|
559
521
|
// Variable types
|
|
560
|
-
type VariableTokens = ${tsVariableTokens || `''`};
|
|
522
|
+
type VariableTokens = ${tsVariableTokens || `''`};
|
|
561
523
|
type PropertyValueToken = \`{\${VariableTokens}}\`;
|
|
562
|
-
|
|
524
|
+
|
|
563
525
|
// Template types
|
|
564
526
|
type TemplateTokens = {
|
|
565
527
|
${Object.entries(templateTokens).map(([key, value]) => `${key}?: ${value}`).join("\n")}
|
|
566
528
|
}
|
|
567
|
-
|
|
529
|
+
|
|
530
|
+
// Template variant types (per docs/template-variants-spec.md §7)
|
|
531
|
+
${tsTemplateVariantMap}
|
|
532
|
+
${tsTemplateVariantAliases}
|
|
533
|
+
|
|
568
534
|
// Media query types
|
|
569
535
|
type MediaQueryKeys = ${mediaQueryKeys || `''`};
|
|
570
536
|
`;
|
package/config/index.cjs
CHANGED
|
@@ -6,10 +6,8 @@ const defineConfig = (config) => {
|
|
|
6
6
|
return config;
|
|
7
7
|
};
|
|
8
8
|
exports.GlobalStylesFactory = factories_index.GlobalStylesFactory;
|
|
9
|
-
exports.ImportFactory = factories_index.ImportFactory;
|
|
10
9
|
exports.VariablesFactory = factories_index.VariablesFactory;
|
|
11
10
|
exports.defineGlobalStyles = factories_index.defineGlobalStyles;
|
|
12
|
-
exports.defineImport = factories_index.defineImport;
|
|
13
11
|
exports.defineMediaQuery = factories_index.defineMediaQuery;
|
|
14
12
|
exports.defineVariables = factories_index.defineVariables;
|
|
15
13
|
exports.TemplateFactory = defineTemplates.TemplateFactory;
|
package/config/index.js
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import { GlobalStylesFactory,
|
|
1
|
+
import { GlobalStylesFactory, VariablesFactory, defineGlobalStyles, defineMediaQuery, defineVariables } from "../factories/index.js";
|
|
2
2
|
import { T, a, d } from "../define-templates-CVhhgPnd.js";
|
|
3
3
|
const defineConfig = (config) => {
|
|
4
4
|
return config;
|
|
5
5
|
};
|
|
6
6
|
export {
|
|
7
7
|
GlobalStylesFactory,
|
|
8
|
-
ImportFactory,
|
|
9
8
|
T as TemplateFactory,
|
|
10
9
|
a as TemplatesFactory,
|
|
11
10
|
VariablesFactory,
|
|
12
11
|
defineConfig,
|
|
13
12
|
defineGlobalStyles,
|
|
14
|
-
defineImport,
|
|
15
13
|
defineMediaQuery,
|
|
16
14
|
d as defineTemplates,
|
|
17
15
|
defineVariables
|
package/css/dynamic-styles.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-
|
|
3
|
+
const parseStyles = require("../parse-styles-DxyVq07D.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) => {
|
package/css/dynamic-styles.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as parseStyles } from "../parse-styles-
|
|
1
|
+
import { a as parseStyles } from "../parse-styles-DSyVPjDG.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-
|
|
3
|
+
const parseStyles = require("../parse-styles-DxyVq07D.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-
|
|
1
|
+
import { p as parseAndJoinStyles } from "../parse-styles-DSyVPjDG.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 = {}) => {
|
package/factories/index.cjs
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
|
-
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
5
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
6
3
|
const css_media = require("../css/media.cjs");
|
|
7
4
|
const defineTemplates = require("../define-templates-Deq1aCbN.cjs");
|
|
@@ -16,20 +13,6 @@ class GlobalStylesFactory {
|
|
|
16
13
|
const defineGlobalStyles = (styles) => {
|
|
17
14
|
return new GlobalStylesFactory(styles);
|
|
18
15
|
};
|
|
19
|
-
class ImportFactory {
|
|
20
|
-
constructor(_current) {
|
|
21
|
-
__publicField(this, "_path");
|
|
22
|
-
this._current = _current;
|
|
23
|
-
}
|
|
24
|
-
get isDefineImport() {
|
|
25
|
-
return true;
|
|
26
|
-
}
|
|
27
|
-
_setPath(path) {
|
|
28
|
-
this._path = path;
|
|
29
|
-
return this;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
const defineImport = (...specs) => new ImportFactory(specs);
|
|
33
16
|
const defineMediaQuery = (mediaFactory) => {
|
|
34
17
|
return mediaFactory(css_media.media);
|
|
35
18
|
};
|
|
@@ -48,9 +31,7 @@ exports.TemplateFactory = defineTemplates.TemplateFactory;
|
|
|
48
31
|
exports.TemplatesFactory = defineTemplates.TemplatesFactory;
|
|
49
32
|
exports.defineTemplates = defineTemplates.defineTemplates;
|
|
50
33
|
exports.GlobalStylesFactory = GlobalStylesFactory;
|
|
51
|
-
exports.ImportFactory = ImportFactory;
|
|
52
34
|
exports.VariablesFactory = VariablesFactory;
|
|
53
35
|
exports.defineGlobalStyles = defineGlobalStyles;
|
|
54
|
-
exports.defineImport = defineImport;
|
|
55
36
|
exports.defineMediaQuery = defineMediaQuery;
|
|
56
37
|
exports.defineVariables = defineVariables;
|