🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@bamboocss/config

Package Overview
Dependencies
Maintainers
1
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@bamboocss/config - npm Package Compare versions

Comparing version
1.11.4
to
1.12.0
+186
-2
dist/diff-config.cjs
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const require_diff_config = require("./diff-config-Co_3mDXE.cjs");
exports.diffConfigs = require_diff_config.diffConfigs;
//#region \0rolldown/runtime.js
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
//#endregion
let _bamboocss_shared = require("@bamboocss/shared");
let microdiff = require("microdiff");
microdiff = __toESM(microdiff);
//#region src/create-matcher.ts
/**
* Acts like a .gitignore matcher
* e.g a list of string to search for nested path with glob and exclusion allowed
* ["outdir", "theme.recipes", '*.css', '!aaa.*.bbb']
*/
function createMatcher(id, patterns) {
if (!patterns?.length) return () => void 0;
const includePatterns = [];
const excludePatterns = [];
new Set(patterns).forEach((pattern) => {
const regexString = pattern.replace(/\*/g, ".*");
if (pattern.startsWith("!")) excludePatterns.push(regexString.slice(1));
else includePatterns.push(regexString);
});
const include = new RegExp(includePatterns.join("|"));
const exclude = new RegExp(excludePatterns.join("|"));
return (path) => {
if (excludePatterns.length && exclude.test(path)) return;
return include.test(path) ? id : void 0;
};
}
//#endregion
//#region src/config-deps.ts
const all = [
"clean",
"cwd",
"eject",
"outdir",
"forceConsistentTypeExtension",
"outExtension",
"emitTokensOnly",
"presets",
"plugins",
"hooks"
];
const format = [
"syntax",
"hash",
"prefix",
"separator",
"strictTokens",
"strictPropertyValues",
"shorthands"
];
const tokens = [
"utilities",
"conditions",
"theme.tokens",
"theme.semanticTokens",
"theme.breakpoints",
"theme.containerNames",
"theme.containerSizes"
];
const jsx = [
"jsxFramework",
"jsxFactory",
"jsxStyleProps",
"syntax"
];
const common = tokens.concat(jsx, format);
const artifactConfigDeps = {
helpers: ["syntax", "jsxFramework"],
keyframes: ["theme.keyframes", "layers"],
"design-tokens": ["layers", "!utilities.*.className"].concat(tokens),
types: ["!utilities.*.className"].concat(common),
"css-fn": common,
cva: ["syntax"],
sva: ["syntax"],
cx: [],
"create-recipe": [
"separator",
"prefix",
"hash"
],
"recipes-index": ["theme.recipes", "theme.slotRecipes"],
recipes: ["theme.recipes", "theme.slotRecipes"],
"patterns-index": ["syntax", "patterns"],
patterns: ["syntax", "patterns"],
"jsx-is-valid-prop": common,
"jsx-factory": jsx,
"jsx-helpers": jsx,
"jsx-patterns": jsx.concat("patterns"),
"jsx-patterns-index": jsx.concat("patterns"),
"jsx-create-style-context": jsx,
"css-index": ["syntax"],
"package.json": ["forceConsistentTypeExtension", "outExtension"],
"types-styles": ["shorthands"],
"types-conditions": ["conditions"],
"types-jsx": jsx,
"types-entry": [],
"types-gen": [],
"types-gen-system": [],
themes: ["themes"].concat(tokens),
"static-css": [
"staticCss",
"patterns",
"theme.recipes",
"theme.slotRecipes"
].concat(tokens),
styles: [],
"styles.css": []
};
const artifactMatchers = Object.entries(artifactConfigDeps).map(([key, paths]) => {
if (!paths.length) return () => void 0;
return createMatcher(key, paths.concat(all));
});
//#endregion
//#region src/diff-config.ts
const runIfFn = (fn) => typeof fn === "function" ? fn() : fn;
/**
* Check if recipes were empty before and non-empty now (or vice versa)
*/
const hasRecipeStateTransition = (prevConfig, nextConfig) => {
const prevRecipes = prevConfig.theme?.recipes ?? {};
const prevSlotRecipes = prevConfig.theme?.slotRecipes ?? {};
const prevHasRecipes = Object.keys(prevRecipes).length > 0 || Object.keys(prevSlotRecipes).length > 0;
const nextRecipes = nextConfig.theme?.recipes ?? {};
const nextSlotRecipes = nextConfig.theme?.slotRecipes ?? {};
return prevHasRecipes !== (Object.keys(nextRecipes).length > 0 || Object.keys(nextSlotRecipes).length > 0);
};
/**
* Diff the two config objects and return the list of affected properties
*/
function diffConfigs(config, prevConfig) {
const affected = {
artifacts: /* @__PURE__ */ new Set(),
hasConfigChanged: false,
diffs: []
};
if (!prevConfig) {
affected.hasConfigChanged = true;
return affected;
}
const configDiff = (0, microdiff.default)(prevConfig, runIfFn(config));
if (!configDiff.length) return affected;
affected.hasConfigChanged = true;
affected.diffs = configDiff;
configDiff.forEach((change) => {
const changePath = change.path.join(".");
artifactMatchers.forEach((matcher) => {
const id = matcher(changePath);
if (!id) return;
if (id === "recipes") {
const name = (0, _bamboocss_shared.dashCase)(change.path.slice(1, 3).join("."));
affected.artifacts.add(name);
}
if (id === "patterns") {
const name = (0, _bamboocss_shared.dashCase)(change.path.slice(0, 2).join("."));
affected.artifacts.add(name);
}
affected.artifacts.add(id);
});
});
if (affected.artifacts.has("recipes") || affected.artifacts.has("recipes-index")) {
if (hasRecipeStateTransition(prevConfig, runIfFn(config))) affected.artifacts.add("create-recipe");
}
return affected;
}
//#endregion
exports.diffConfigs = diffConfigs;

@@ -1,2 +0,163 @@

import { t as diffConfigs } from "./diff-config-KDQWMnQN.mjs";
import { dashCase } from "@bamboocss/shared";
import microdiff from "microdiff";
//#region src/create-matcher.ts
/**
* Acts like a .gitignore matcher
* e.g a list of string to search for nested path with glob and exclusion allowed
* ["outdir", "theme.recipes", '*.css', '!aaa.*.bbb']
*/
function createMatcher(id, patterns) {
if (!patterns?.length) return () => void 0;
const includePatterns = [];
const excludePatterns = [];
new Set(patterns).forEach((pattern) => {
const regexString = pattern.replace(/\*/g, ".*");
if (pattern.startsWith("!")) excludePatterns.push(regexString.slice(1));
else includePatterns.push(regexString);
});
const include = new RegExp(includePatterns.join("|"));
const exclude = new RegExp(excludePatterns.join("|"));
return (path) => {
if (excludePatterns.length && exclude.test(path)) return;
return include.test(path) ? id : void 0;
};
}
//#endregion
//#region src/config-deps.ts
const all = [
"clean",
"cwd",
"eject",
"outdir",
"forceConsistentTypeExtension",
"outExtension",
"emitTokensOnly",
"presets",
"plugins",
"hooks"
];
const format = [
"syntax",
"hash",
"prefix",
"separator",
"strictTokens",
"strictPropertyValues",
"shorthands"
];
const tokens = [
"utilities",
"conditions",
"theme.tokens",
"theme.semanticTokens",
"theme.breakpoints",
"theme.containerNames",
"theme.containerSizes"
];
const jsx = [
"jsxFramework",
"jsxFactory",
"jsxStyleProps",
"syntax"
];
const common = tokens.concat(jsx, format);
const artifactConfigDeps = {
helpers: ["syntax", "jsxFramework"],
keyframes: ["theme.keyframes", "layers"],
"design-tokens": ["layers", "!utilities.*.className"].concat(tokens),
types: ["!utilities.*.className"].concat(common),
"css-fn": common,
cva: ["syntax"],
sva: ["syntax"],
cx: [],
"create-recipe": [
"separator",
"prefix",
"hash"
],
"recipes-index": ["theme.recipes", "theme.slotRecipes"],
recipes: ["theme.recipes", "theme.slotRecipes"],
"patterns-index": ["syntax", "patterns"],
patterns: ["syntax", "patterns"],
"jsx-is-valid-prop": common,
"jsx-factory": jsx,
"jsx-helpers": jsx,
"jsx-patterns": jsx.concat("patterns"),
"jsx-patterns-index": jsx.concat("patterns"),
"jsx-create-style-context": jsx,
"css-index": ["syntax"],
"package.json": ["forceConsistentTypeExtension", "outExtension"],
"types-styles": ["shorthands"],
"types-conditions": ["conditions"],
"types-jsx": jsx,
"types-entry": [],
"types-gen": [],
"types-gen-system": [],
themes: ["themes"].concat(tokens),
"static-css": [
"staticCss",
"patterns",
"theme.recipes",
"theme.slotRecipes"
].concat(tokens),
styles: [],
"styles.css": []
};
const artifactMatchers = Object.entries(artifactConfigDeps).map(([key, paths]) => {
if (!paths.length) return () => void 0;
return createMatcher(key, paths.concat(all));
});
//#endregion
//#region src/diff-config.ts
const runIfFn = (fn) => typeof fn === "function" ? fn() : fn;
/**
* Check if recipes were empty before and non-empty now (or vice versa)
*/
const hasRecipeStateTransition = (prevConfig, nextConfig) => {
const prevRecipes = prevConfig.theme?.recipes ?? {};
const prevSlotRecipes = prevConfig.theme?.slotRecipes ?? {};
const prevHasRecipes = Object.keys(prevRecipes).length > 0 || Object.keys(prevSlotRecipes).length > 0;
const nextRecipes = nextConfig.theme?.recipes ?? {};
const nextSlotRecipes = nextConfig.theme?.slotRecipes ?? {};
return prevHasRecipes !== (Object.keys(nextRecipes).length > 0 || Object.keys(nextSlotRecipes).length > 0);
};
/**
* Diff the two config objects and return the list of affected properties
*/
function diffConfigs(config, prevConfig) {
const affected = {
artifacts: /* @__PURE__ */ new Set(),
hasConfigChanged: false,
diffs: []
};
if (!prevConfig) {
affected.hasConfigChanged = true;
return affected;
}
const configDiff = microdiff(prevConfig, runIfFn(config));
if (!configDiff.length) return affected;
affected.hasConfigChanged = true;
affected.diffs = configDiff;
configDiff.forEach((change) => {
const changePath = change.path.join(".");
artifactMatchers.forEach((matcher) => {
const id = matcher(changePath);
if (!id) return;
if (id === "recipes") {
const name = dashCase(change.path.slice(1, 3).join("."));
affected.artifacts.add(name);
}
if (id === "patterns") {
const name = dashCase(change.path.slice(0, 2).join("."));
affected.artifacts.add(name);
}
affected.artifacts.add(id);
});
});
if (affected.artifacts.has("recipes") || affected.artifacts.has("recipes-index")) {
if (hasRecipeStateTransition(prevConfig, runIfFn(config))) affected.artifacts.add("create-recipe");
}
return affected;
}
//#endregion
export { diffConfigs };
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const require_diff_config = require("./diff-config-Co_3mDXE.cjs");
const require_resolve_ts_path_pattern = require("./resolve-ts-path-pattern.cjs");
const require_merge_config = require("./merge-config-CcNpHJit.cjs");
//#region \0rolldown/runtime.js
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
//#endregion
let _bamboocss_logger = require("@bamboocss/logger");

@@ -9,9 +28,11 @@ let _bamboocss_shared = require("@bamboocss/shared");

let escalade_sync = require("escalade/sync");
escalade_sync = require_diff_config.__toESM(escalade_sync);
escalade_sync = __toESM(escalade_sync);
let path = require("path");
path = require_diff_config.__toESM(path);
path = __toESM(path);
let microdiff = require("microdiff");
microdiff = __toESM(microdiff);
let fs = require("fs");
fs = require_diff_config.__toESM(fs);
fs = __toESM(fs);
let typescript = require("typescript");
typescript = require_diff_config.__toESM(typescript);
typescript = __toESM(typescript);
let _bamboocss_preset_base = require("@bamboocss/preset-base");

@@ -69,2 +90,179 @@ let _bamboocss_preset_bamboo = require("@bamboocss/preset-bamboo");

//#endregion
//#region src/create-matcher.ts
/**
* Acts like a .gitignore matcher
* e.g a list of string to search for nested path with glob and exclusion allowed
* ["outdir", "theme.recipes", '*.css', '!aaa.*.bbb']
*/
function createMatcher(id, patterns) {
if (!patterns?.length) return () => void 0;
const includePatterns = [];
const excludePatterns = [];
new Set(patterns).forEach((pattern) => {
const regexString = pattern.replace(/\*/g, ".*");
if (pattern.startsWith("!")) excludePatterns.push(regexString.slice(1));
else includePatterns.push(regexString);
});
const include = new RegExp(includePatterns.join("|"));
const exclude = new RegExp(excludePatterns.join("|"));
return (path) => {
if (excludePatterns.length && exclude.test(path)) return;
return include.test(path) ? id : void 0;
};
}
//#endregion
//#region src/config-deps.ts
const all = [
"clean",
"cwd",
"eject",
"outdir",
"forceConsistentTypeExtension",
"outExtension",
"emitTokensOnly",
"presets",
"plugins",
"hooks"
];
const format = [
"syntax",
"hash",
"prefix",
"separator",
"strictTokens",
"strictPropertyValues",
"shorthands"
];
const tokens = [
"utilities",
"conditions",
"theme.tokens",
"theme.semanticTokens",
"theme.breakpoints",
"theme.containerNames",
"theme.containerSizes"
];
const jsx = [
"jsxFramework",
"jsxFactory",
"jsxStyleProps",
"syntax"
];
const common = tokens.concat(jsx, format);
const artifactConfigDeps = {
helpers: ["syntax", "jsxFramework"],
keyframes: ["theme.keyframes", "layers"],
"design-tokens": ["layers", "!utilities.*.className"].concat(tokens),
types: ["!utilities.*.className"].concat(common),
"css-fn": common,
cva: ["syntax"],
sva: ["syntax"],
cx: [],
"create-recipe": [
"separator",
"prefix",
"hash"
],
"recipes-index": ["theme.recipes", "theme.slotRecipes"],
recipes: ["theme.recipes", "theme.slotRecipes"],
"patterns-index": ["syntax", "patterns"],
patterns: ["syntax", "patterns"],
"jsx-is-valid-prop": common,
"jsx-factory": jsx,
"jsx-helpers": jsx,
"jsx-patterns": jsx.concat("patterns"),
"jsx-patterns-index": jsx.concat("patterns"),
"jsx-create-style-context": jsx,
"css-index": ["syntax"],
"package.json": ["forceConsistentTypeExtension", "outExtension"],
"types-styles": ["shorthands"],
"types-conditions": ["conditions"],
"types-jsx": jsx,
"types-entry": [],
"types-gen": [],
"types-gen-system": [],
themes: ["themes"].concat(tokens),
"static-css": [
"staticCss",
"patterns",
"theme.recipes",
"theme.slotRecipes"
].concat(tokens),
styles: [],
"styles.css": []
};
const artifactMatchers = Object.entries(artifactConfigDeps).map(([key, paths]) => {
if (!paths.length) return () => void 0;
return createMatcher(key, paths.concat(all));
});
//#endregion
//#region src/diff-config.ts
const runIfFn = (fn) => typeof fn === "function" ? fn() : fn;
/**
* Check if recipes were empty before and non-empty now (or vice versa)
*/
const hasRecipeStateTransition = (prevConfig, nextConfig) => {
const prevRecipes = prevConfig.theme?.recipes ?? {};
const prevSlotRecipes = prevConfig.theme?.slotRecipes ?? {};
const prevHasRecipes = Object.keys(prevRecipes).length > 0 || Object.keys(prevSlotRecipes).length > 0;
const nextRecipes = nextConfig.theme?.recipes ?? {};
const nextSlotRecipes = nextConfig.theme?.slotRecipes ?? {};
return prevHasRecipes !== (Object.keys(nextRecipes).length > 0 || Object.keys(nextSlotRecipes).length > 0);
};
/**
* Diff the two config objects and return the list of affected properties
*/
function diffConfigs(config, prevConfig) {
const affected = {
artifacts: /* @__PURE__ */ new Set(),
hasConfigChanged: false,
diffs: []
};
if (!prevConfig) {
affected.hasConfigChanged = true;
return affected;
}
const configDiff = (0, microdiff.default)(prevConfig, runIfFn(config));
if (!configDiff.length) return affected;
affected.hasConfigChanged = true;
affected.diffs = configDiff;
configDiff.forEach((change) => {
const changePath = change.path.join(".");
artifactMatchers.forEach((matcher) => {
const id = matcher(changePath);
if (!id) return;
if (id === "recipes") {
const name = (0, _bamboocss_shared.dashCase)(change.path.slice(1, 3).join("."));
affected.artifacts.add(name);
}
if (id === "patterns") {
const name = (0, _bamboocss_shared.dashCase)(change.path.slice(0, 2).join("."));
affected.artifacts.add(name);
}
affected.artifacts.add(id);
});
});
if (affected.artifacts.has("recipes") || affected.artifacts.has("recipes-index")) {
if (hasRecipeStateTransition(prevConfig, runIfFn(config))) affected.artifacts.add("create-recipe");
}
return affected;
}
//#endregion
//#region src/resolve-ts-path-pattern.ts
/**
* @see https://github.com/aleclarson/vite-tsconfig-paths/blob/e8f0acf7adfcfbf77edbe937f64b4e5d39557ad0/src/index.ts#LL231C57-L231C57
*/
const resolveTsPathPattern = (pathMappings, moduleSpecifier) => {
for (const mapping of pathMappings) {
const match = moduleSpecifier.match(mapping.pattern);
if (!match) continue;
for (const pathTemplate of mapping.paths) {
let starCount = 0;
return pathTemplate.replace(/\*/g, () => {
return match[Math.min(++starCount, match.length - 1)];
}).split(path.sep).join(path.posix.sep);
}
}
};
//#endregion
//#region src/ts-config-paths.ts

@@ -175,3 +373,3 @@ /**

if (!opts.pathMappings) return;
const filename = require_resolve_ts_path_pattern.resolveTsPathPattern(opts.pathMappings, mod);
const filename = resolveTsPathPattern(opts.pathMappings, mod);
if (!filename) return;

@@ -206,2 +404,269 @@ getDeps(Object.assign({}, nextOpts, { filename }), mod);

//#endregion
//#region src/merge-hooks.ts
const mergeHooks = (plugins) => {
const hooksFns = {};
plugins.forEach(({ name, hooks }) => {
Object.entries(hooks ?? {}).forEach(([key, value]) => {
if (!hooksFns[key]) hooksFns[key] = [];
hooksFns[key].push([name, value]);
});
});
return Object.fromEntries(Object.entries(hooksFns).map(([key, entries]) => {
const fns = entries.map(([name, fn]) => tryCatch(name, fn));
const reducer = key in reducers ? reducers[key] : void 0;
if (reducer) return [key, reducer(fns)];
return [key, syncHooks.includes(key) ? callAll(...fns) : callAllAsync(...fns)];
}));
};
const createReducer = (reducer) => reducer;
const reducers = {
"config:resolved": createReducer((fns) => async (_args) => {
const args = Object.assign({}, _args);
const original = _args.config;
let config = args.config;
for (const hookFn of fns) {
const result = await hookFn(Object.assign(args, {
config,
original
}));
if (result !== void 0) config = result;
}
return config;
}),
"parser:before": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.content;
let content = args.content;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
content,
original
}));
if (result !== void 0) content = result;
}
return content;
}),
"parser:preprocess": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.data;
let data = args.data;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
data,
original
}));
if (result !== void 0) data = result;
}
return data;
}),
"cssgen:done": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.content;
let content = args.content;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
content,
original
}));
if (result !== void 0) content = result;
}
return content;
}),
"codegen:prepare": createReducer((fns) => async (_args) => {
const args = Object.assign({}, _args);
const original = _args.artifacts;
let artifacts = args.artifacts;
for (const hookFn of fns) {
const result = await hookFn(Object.assign(args, {
artifacts,
original
}));
if (result) artifacts = result;
}
return artifacts;
}),
"preset:resolved": createReducer((fns) => async (_args) => {
const args = Object.assign({}, _args);
const original = _args.preset;
let preset = args.preset;
for (const hookFn of fns) {
const result = await hookFn(Object.assign(args, {
preset,
original
}));
if (result !== void 0) preset = result;
}
return preset;
}),
"css:optimize": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.css;
let css = args.css;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
css,
original
}));
if (result !== void 0) css = result;
}
return css;
})
};
const syncHooks = [
"context:created",
"parser:before",
"parser:preprocess",
"parser:after",
"cssgen:done",
"css:optimize"
];
const callAllAsync = (...fns) => async (...a) => {
for (const fn of fns) await fn?.(...a);
};
const callAll = (...fns) => (...a) => {
fns.forEach((fn) => fn?.(...a));
};
const tryCatch = (name, fn) => {
return (...args) => {
try {
return fn(...args);
} catch (e) {
_bamboocss_logger.logger.caughtError("hooks", `Error in plugin "${name}"`, e);
}
};
};
//#endregion
//#region src/validation/utils.ts
const REFERENCE_REGEX = /({([^}]*)})/g;
const curlyBracketRegex = /[{}]/g;
const isValidToken = (token) => (0, _bamboocss_shared.isObject)(token) && Object.hasOwnProperty.call(token, "value");
const isTokenReference = (value) => typeof value === "string" && REFERENCE_REGEX.test(value);
const formatPath = (path) => path;
function getReferences(value) {
if (typeof value !== "string") return [];
const matches = value.match(REFERENCE_REGEX);
if (!matches) return [];
return matches.map((match) => match.replace(curlyBracketRegex, "")).map((value) => {
return value.trim().split("/")[0];
});
}
const serializeTokenValue = (value) => {
if ((0, _bamboocss_shared.isString)(value)) return value;
if ((0, _bamboocss_shared.isObject)(value)) return Object.values(value).map((v) => serializeTokenValue(v)).join(" ");
if (Array.isArray(value)) return value.map((v) => serializeTokenValue(v)).join(" ");
return value.toString();
};
//#endregion
//#region src/merge-config.ts
/**
* Collect all `extend` properties into an array (to avoid mutation)
*/
function getExtends(items) {
return items.reduce((merged, { extend }) => {
if (!extend) return merged;
return (0, _bamboocss_shared.mergeWith)(merged, extend, (originalValue, newValue) => {
if (newValue === void 0) return originalValue ?? [];
if (originalValue === void 0) return [newValue];
if (Array.isArray(originalValue)) return [newValue, ...originalValue];
return [newValue, originalValue];
});
}, {});
}
/**
* Separate the `extend` properties from the rest of the object
*/
function mergeRecords(records) {
return {
...records.reduce((acc, record) => (0, _bamboocss_shared.assign)(acc, record), {}),
extend: getExtends(records)
};
}
/**
* Merge all `extend` properties into the rest of the object
*/
function mergeExtensions(records) {
const { extend = [], ...restProps } = mergeRecords(records);
return (0, _bamboocss_shared.mergeWith)(restProps, extend, (obj, extensions) => {
return (0, _bamboocss_shared.mergeAndConcat)({}, obj, ...extensions);
});
}
const isEmptyObject = (obj) => typeof obj === "object" && Object.keys(obj).length === 0;
const compact = (obj) => {
return Object.keys(obj).reduce((acc, key) => {
if (obj[key] !== void 0 && !isEmptyObject(obj[key])) acc[key] = obj[key];
return acc;
}, {});
};
const tokenKeys = [
"description",
"extensions",
"type",
"value",
"deprecated"
];
/**
* Merge all configs into a single config
*/
function mergeConfigs(configs) {
const userConfig = configs.at(-1);
const pluginHooks = userConfig.plugins ?? [];
if (userConfig.hooks) pluginHooks.push({
name: _bamboocss_shared.BAMBOO_CONFIG_NAME,
hooks: userConfig.hooks
});
const reversed = Array.from(configs).reverse();
const withoutEmpty = compact((0, _bamboocss_shared.assign)({
conditions: mergeExtensions(reversed.map((config) => config.conditions ?? {})),
theme: mergeExtensions(reversed.map((config) => config.theme ?? {})),
patterns: mergeExtensions(reversed.map((config) => config.patterns ?? {})),
utilities: mergeExtensions(reversed.map((config) => config.utilities ?? {})),
globalCss: mergeExtensions(reversed.map((config) => config.globalCss ?? {})),
globalVars: mergeExtensions(reversed.map((config) => config.globalVars ?? {})),
globalFontface: mergeExtensions(reversed.map((config) => config.globalFontface ?? {})),
globalPositionTry: mergeExtensions(reversed.map((config) => config.globalPositionTry ?? {})),
staticCss: mergeExtensions(reversed.map((config) => config.staticCss ?? {})),
themes: mergeExtensions(reversed.map((config) => config.themes ?? {})),
hooks: mergeHooks(pluginHooks)
}, ...reversed));
/**
* Properly merge tokens between flat/nested forms by setting the flat form as the default
* preset:
* ```
* tokens: {
* black: {
* value: "black"
* }
* }
* // color: "black"
* ```
*
* config:
* ```
* tokens: {
* black: {
* 0: { value: "black" },
* 10: { value: "black/10" },
* 20: { value: "black/20" },
* // ...
* }
* }
*
* // color: "black.20"
* ```
*/
if (withoutEmpty.theme?.tokens) (0, _bamboocss_shared.walkObject)(withoutEmpty.theme.tokens, (args) => args, { stop(token) {
if (!isValidToken(token)) return false;
if (Object.keys(token).filter((k) => !tokenKeys.includes(k)).length > 0) {
token.DEFAULT ||= {};
tokenKeys.forEach((key) => {
if (token[key] == null) return;
token.DEFAULT[key] ||= token[key];
delete token[key];
});
}
return true;
} });
return withoutEmpty;
}
//#endregion
//#region src/get-resolved-config.ts

@@ -244,3 +709,3 @@ const hookUtils$1 = {

}
const merged = require_merge_config.mergeConfigs(configs);
const merged = mergeConfigs(configs);
merged.presets = configs.slice(0, -1);

@@ -360,3 +825,3 @@ return merged;

}
if (require_merge_config.isTokenReference(value) && !refsByPath.has(value)) addError("tokens", `Unknown token reference: \`${currentPath}\` used in \`${value}\``);
if (isTokenReference(value) && !refsByPath.has(value)) addError("tokens", `Unknown token reference: \`${currentPath}\` used in \`${value}\``);
const deps = refsByPath.get(currentPath);

@@ -388,8 +853,8 @@ if (!deps) continue;

if (path.includes("DEFAULT")) valueAtPath.set(path.replace(".DEFAULT", ""), value);
}, { stop: require_merge_config.isValidToken });
}, { stop: isValidToken });
tokenPaths.forEach((path) => {
const itemValue = valueAtPath.get(path);
const formattedPath = require_merge_config.formatPath(path);
const formattedPath = formatPath(path);
typeByPath.set(formattedPath, "tokens");
if (!require_merge_config.isValidToken(itemValue)) {
if (!isValidToken(itemValue)) {
addError("tokens", `Token must contain 'value': \`theme.tokens.${formattedPath}\``);

@@ -402,7 +867,7 @@ return;

}
const valueStr = require_merge_config.serializeTokenValue(itemValue.value || itemValue);
if (require_merge_config.isTokenReference(valueStr)) refsByPath.set(formattedPath, /* @__PURE__ */ new Set([]));
const valueStr = serializeTokenValue(itemValue.value || itemValue);
if (isTokenReference(valueStr)) refsByPath.set(formattedPath, /* @__PURE__ */ new Set([]));
const references = refsByPath.get(formattedPath);
if (!references) return;
require_merge_config.getReferences(valueStr).forEach((reference) => {
getReferences(valueStr).forEach((reference) => {
references.add(reference);

@@ -420,15 +885,15 @@ });

if (path.includes("DEFAULT")) valueAtPath.set(path.replace(".DEFAULT", ""), value);
if (!require_merge_config.isValidToken(value)) return;
if (!isValidToken(value)) return;
(0, _bamboocss_shared.walkObject)(value, (itemValue, paths) => {
const valuePath = paths.join(".");
const formattedPath = require_merge_config.formatPath(path);
const formattedPath = formatPath(path);
typeByPath.set(formattedPath, "semanticTokens");
const fullPath = formattedPath + "." + paths.join(".");
if (valuePath.includes("value.value")) addError("tokens", `You used \`value\` twice resulting in an invalid token \`theme.tokens.${fullPath}\``);
const valueStr = require_merge_config.serializeTokenValue(itemValue.value || itemValue);
if (require_merge_config.isTokenReference(valueStr)) {
const valueStr = serializeTokenValue(itemValue.value || itemValue);
if (isTokenReference(valueStr)) {
if (!refsByPath.has(formattedPath)) refsByPath.set(formattedPath, /* @__PURE__ */ new Set());
const references = refsByPath.get(formattedPath);
if (!references) return;
require_merge_config.getReferences(valueStr).forEach((reference) => {
getReferences(valueStr).forEach((reference) => {
references.add(reference);

@@ -438,5 +903,5 @@ });

});
}, { stop: require_merge_config.isValidToken });
}, { stop: isValidToken });
tokenPaths.forEach((path) => {
const formattedPath = require_merge_config.formatPath(path);
const formattedPath = formatPath(path);
const value = valueAtPath.get(path);

@@ -537,3 +1002,3 @@ if (path.includes(" ")) {

});
const earlyHooks = require_merge_config.mergeHooks(pluginHooks);
const earlyHooks = mergeHooks(pluginHooks);
const mergedConfig = await getResolvedConfig(result.config, cwd, earlyHooks);

@@ -579,3 +1044,3 @@ const hooks = mergedConfig.hooks ?? {};

exports.convertTsPathsToRegexes = convertTsPathsToRegexes;
exports.diffConfigs = require_diff_config.diffConfigs;
exports.diffConfigs = diffConfigs;
exports.findConfig = findConfig;

@@ -585,4 +1050,4 @@ exports.getConfigDependencies = getConfigDependencies;

exports.loadConfig = loadConfig;
exports.mergeConfigs = require_merge_config.mergeConfigs;
exports.mergeHooks = require_merge_config.mergeHooks;
exports.mergeConfigs = mergeConfigs;
exports.mergeHooks = mergeHooks;
exports.resolveConfig = resolveConfig;

@@ -1,5 +0,2 @@

import { diffConfigs } from "./diff-config.cjs";
import { n as convertTsPathsToRegexes, t as PathMapping } from "./ts-config-paths-wVx39QZ0.cjs";
import { n as mergeHooks, t as mergeConfigs } from "./merge-config-DVOlBQJY.cjs";
import { BambooHooks, Config, ConfigTsOptions, LoadConfigResult as LoadConfigResult$1 } from "@bamboocss/types";
import { BambooHooks as BambooHooks$1, BambooPlugin, Config, ConfigTsOptions, DiffConfigResult, LoadConfigResult as LoadConfigResult$1 } from "@bamboocss/types";
import { CompilerOptions, TypeAcquisition } from "typescript";

@@ -21,2 +18,9 @@

//#endregion
//#region src/diff-config.d.ts
type ConfigOrFn = Config | (() => Config);
/**
* Diff the two config objects and return the list of affected properties
*/
declare function diffConfigs(config: ConfigOrFn, prevConfig: Config | undefined): DiffConfigResult;
//#endregion
//#region src/find-config.d.ts

@@ -45,2 +49,12 @@ declare function findConfig(options: Partial<ConfigFileOptions>): string;

//#endregion
//#region src/ts-config-paths.d.ts
interface PathMapping {
pattern: RegExp;
paths: string[];
}
/**
* @see https://github.com/aleclarson/vite-tsconfig-paths/blob/e8f0acf7adfcfbf77edbe937f64b4e5d39557ad0/src/mappings.ts
*/
declare function convertTsPathsToRegexes(paths: Record<string, string[]>, baseUrl: string): PathMapping[];
//#endregion
//#region src/get-mod-deps.d.ts

@@ -63,10 +77,10 @@ interface GetDepsOptions {

//#region src/get-resolved-config.d.ts
type Extendable<T> = T & {
type Extendable$1<T> = T & {
extend?: T;
};
type ExtendableConfig = Extendable<Config>;
type ExtendableConfig$1 = Extendable$1<Config>;
/**
* Recursively merge all presets into a single config (depth-first using stack)
*/
declare function getResolvedConfig(config: ExtendableConfig, cwd: string, hooks?: Partial<BambooHooks>): Promise<Config>;
declare function getResolvedConfig(config: ExtendableConfig$1, cwd: string, hooks?: Partial<BambooHooks$1>): Promise<Config>;
//#endregion

@@ -87,2 +101,15 @@ //#region src/load-config.d.ts

//#endregion
//#region src/merge-hooks.d.ts
declare const mergeHooks: (plugins: BambooPlugin[]) => BambooHooks;
//#endregion
//#region src/merge-config.d.ts
type Extendable<T> = T & {
extend?: T;
};
type ExtendableConfig = Extendable<Config>;
/**
* Merge all configs into a single config
*/
declare function mergeConfigs(configs: ExtendableConfig[]): any;
//#endregion
export { type BundleConfigResult, type GetDepsOptions, bundleConfig, convertTsPathsToRegexes, diffConfigs, findConfig, getConfigDependencies, getResolvedConfig, loadConfig, mergeConfigs, mergeHooks, resolveConfig };

@@ -1,6 +0,3 @@

import { diffConfigs } from "./diff-config.mjs";
import { n as convertTsPathsToRegexes, t as PathMapping } from "./ts-config-paths-CvGId8kq.mjs";
import { n as mergeHooks, t as mergeConfigs } from "./merge-config-oEiBYbfB.mjs";
import { CompilerOptions, TypeAcquisition } from "typescript";
import { BambooHooks, Config, ConfigTsOptions, LoadConfigResult as LoadConfigResult$1 } from "@bamboocss/types";
import { BambooHooks as BambooHooks$1, BambooPlugin, Config, ConfigTsOptions, DiffConfigResult, LoadConfigResult as LoadConfigResult$1 } from "@bamboocss/types";

@@ -21,2 +18,9 @@ //#region src/types.d.ts

//#endregion
//#region src/diff-config.d.ts
type ConfigOrFn = Config | (() => Config);
/**
* Diff the two config objects and return the list of affected properties
*/
declare function diffConfigs(config: ConfigOrFn, prevConfig: Config | undefined): DiffConfigResult;
//#endregion
//#region src/find-config.d.ts

@@ -45,2 +49,12 @@ declare function findConfig(options: Partial<ConfigFileOptions>): string;

//#endregion
//#region src/ts-config-paths.d.ts
interface PathMapping {
pattern: RegExp;
paths: string[];
}
/**
* @see https://github.com/aleclarson/vite-tsconfig-paths/blob/e8f0acf7adfcfbf77edbe937f64b4e5d39557ad0/src/mappings.ts
*/
declare function convertTsPathsToRegexes(paths: Record<string, string[]>, baseUrl: string): PathMapping[];
//#endregion
//#region src/get-mod-deps.d.ts

@@ -63,10 +77,10 @@ interface GetDepsOptions {

//#region src/get-resolved-config.d.ts
type Extendable<T> = T & {
type Extendable$1<T> = T & {
extend?: T;
};
type ExtendableConfig = Extendable<Config>;
type ExtendableConfig$1 = Extendable$1<Config>;
/**
* Recursively merge all presets into a single config (depth-first using stack)
*/
declare function getResolvedConfig(config: ExtendableConfig, cwd: string, hooks?: Partial<BambooHooks>): Promise<Config>;
declare function getResolvedConfig(config: ExtendableConfig$1, cwd: string, hooks?: Partial<BambooHooks$1>): Promise<Config>;
//#endregion

@@ -87,2 +101,15 @@ //#region src/load-config.d.ts

//#endregion
//#region src/merge-hooks.d.ts
declare const mergeHooks: (plugins: BambooPlugin[]) => BambooHooks;
//#endregion
//#region src/merge-config.d.ts
type Extendable<T> = T & {
extend?: T;
};
type ExtendableConfig = Extendable<Config>;
/**
* Merge all configs into a single config
*/
declare function mergeConfigs(configs: ExtendableConfig[]): any;
//#endregion
export { type BundleConfigResult, type GetDepsOptions, bundleConfig, convertTsPathsToRegexes, diffConfigs, findConfig, getConfigDependencies, getResolvedConfig, loadConfig, mergeConfigs, mergeHooks, resolveConfig };

@@ -1,9 +0,7 @@

import { t as diffConfigs } from "./diff-config-KDQWMnQN.mjs";
import { resolveTsPathPattern } from "./resolve-ts-path-pattern.mjs";
import { a as isValidToken, i as isTokenReference, n as formatPath, o as serializeTokenValue, r as getReferences, s as mergeHooks, t as mergeConfigs } from "./merge-config-DI__LOWx.mjs";
import { logger } from "@bamboocss/logger";
import { BAMBOO_CONFIG_NAME, BambooError, getUnit, isObject, isString, omit, parseJson, pick, stringifyJson, traverse, walkObject } from "@bamboocss/shared";
import { BAMBOO_CONFIG_NAME, BambooError, assign, dashCase, getUnit, isObject, isString, mergeAndConcat, mergeWith, omit, parseJson, pick, stringifyJson, traverse, walkObject } from "@bamboocss/shared";
import { bundleNRequire } from "bundle-n-require";
import findUp from "escalade/sync";
import path, { resolve } from "path";
import path, { posix, resolve, sep } from "path";
import microdiff from "microdiff";
import fs from "fs";

@@ -63,2 +61,179 @@ import ts from "typescript";

//#endregion
//#region src/create-matcher.ts
/**
* Acts like a .gitignore matcher
* e.g a list of string to search for nested path with glob and exclusion allowed
* ["outdir", "theme.recipes", '*.css', '!aaa.*.bbb']
*/
function createMatcher(id, patterns) {
if (!patterns?.length) return () => void 0;
const includePatterns = [];
const excludePatterns = [];
new Set(patterns).forEach((pattern) => {
const regexString = pattern.replace(/\*/g, ".*");
if (pattern.startsWith("!")) excludePatterns.push(regexString.slice(1));
else includePatterns.push(regexString);
});
const include = new RegExp(includePatterns.join("|"));
const exclude = new RegExp(excludePatterns.join("|"));
return (path) => {
if (excludePatterns.length && exclude.test(path)) return;
return include.test(path) ? id : void 0;
};
}
//#endregion
//#region src/config-deps.ts
const all = [
"clean",
"cwd",
"eject",
"outdir",
"forceConsistentTypeExtension",
"outExtension",
"emitTokensOnly",
"presets",
"plugins",
"hooks"
];
const format = [
"syntax",
"hash",
"prefix",
"separator",
"strictTokens",
"strictPropertyValues",
"shorthands"
];
const tokens = [
"utilities",
"conditions",
"theme.tokens",
"theme.semanticTokens",
"theme.breakpoints",
"theme.containerNames",
"theme.containerSizes"
];
const jsx = [
"jsxFramework",
"jsxFactory",
"jsxStyleProps",
"syntax"
];
const common = tokens.concat(jsx, format);
const artifactConfigDeps = {
helpers: ["syntax", "jsxFramework"],
keyframes: ["theme.keyframes", "layers"],
"design-tokens": ["layers", "!utilities.*.className"].concat(tokens),
types: ["!utilities.*.className"].concat(common),
"css-fn": common,
cva: ["syntax"],
sva: ["syntax"],
cx: [],
"create-recipe": [
"separator",
"prefix",
"hash"
],
"recipes-index": ["theme.recipes", "theme.slotRecipes"],
recipes: ["theme.recipes", "theme.slotRecipes"],
"patterns-index": ["syntax", "patterns"],
patterns: ["syntax", "patterns"],
"jsx-is-valid-prop": common,
"jsx-factory": jsx,
"jsx-helpers": jsx,
"jsx-patterns": jsx.concat("patterns"),
"jsx-patterns-index": jsx.concat("patterns"),
"jsx-create-style-context": jsx,
"css-index": ["syntax"],
"package.json": ["forceConsistentTypeExtension", "outExtension"],
"types-styles": ["shorthands"],
"types-conditions": ["conditions"],
"types-jsx": jsx,
"types-entry": [],
"types-gen": [],
"types-gen-system": [],
themes: ["themes"].concat(tokens),
"static-css": [
"staticCss",
"patterns",
"theme.recipes",
"theme.slotRecipes"
].concat(tokens),
styles: [],
"styles.css": []
};
const artifactMatchers = Object.entries(artifactConfigDeps).map(([key, paths]) => {
if (!paths.length) return () => void 0;
return createMatcher(key, paths.concat(all));
});
//#endregion
//#region src/diff-config.ts
const runIfFn = (fn) => typeof fn === "function" ? fn() : fn;
/**
* Check if recipes were empty before and non-empty now (or vice versa)
*/
const hasRecipeStateTransition = (prevConfig, nextConfig) => {
const prevRecipes = prevConfig.theme?.recipes ?? {};
const prevSlotRecipes = prevConfig.theme?.slotRecipes ?? {};
const prevHasRecipes = Object.keys(prevRecipes).length > 0 || Object.keys(prevSlotRecipes).length > 0;
const nextRecipes = nextConfig.theme?.recipes ?? {};
const nextSlotRecipes = nextConfig.theme?.slotRecipes ?? {};
return prevHasRecipes !== (Object.keys(nextRecipes).length > 0 || Object.keys(nextSlotRecipes).length > 0);
};
/**
* Diff the two config objects and return the list of affected properties
*/
function diffConfigs(config, prevConfig) {
const affected = {
artifacts: /* @__PURE__ */ new Set(),
hasConfigChanged: false,
diffs: []
};
if (!prevConfig) {
affected.hasConfigChanged = true;
return affected;
}
const configDiff = microdiff(prevConfig, runIfFn(config));
if (!configDiff.length) return affected;
affected.hasConfigChanged = true;
affected.diffs = configDiff;
configDiff.forEach((change) => {
const changePath = change.path.join(".");
artifactMatchers.forEach((matcher) => {
const id = matcher(changePath);
if (!id) return;
if (id === "recipes") {
const name = dashCase(change.path.slice(1, 3).join("."));
affected.artifacts.add(name);
}
if (id === "patterns") {
const name = dashCase(change.path.slice(0, 2).join("."));
affected.artifacts.add(name);
}
affected.artifacts.add(id);
});
});
if (affected.artifacts.has("recipes") || affected.artifacts.has("recipes-index")) {
if (hasRecipeStateTransition(prevConfig, runIfFn(config))) affected.artifacts.add("create-recipe");
}
return affected;
}
//#endregion
//#region src/resolve-ts-path-pattern.ts
/**
* @see https://github.com/aleclarson/vite-tsconfig-paths/blob/e8f0acf7adfcfbf77edbe937f64b4e5d39557ad0/src/index.ts#LL231C57-L231C57
*/
const resolveTsPathPattern = (pathMappings, moduleSpecifier) => {
for (const mapping of pathMappings) {
const match = moduleSpecifier.match(mapping.pattern);
if (!match) continue;
for (const pathTemplate of mapping.paths) {
let starCount = 0;
return pathTemplate.replace(/\*/g, () => {
return match[Math.min(++starCount, match.length - 1)];
}).split(sep).join(posix.sep);
}
}
};
//#endregion
//#region src/ts-config-paths.ts

@@ -199,2 +374,269 @@ /**

//#endregion
//#region src/merge-hooks.ts
const mergeHooks = (plugins) => {
const hooksFns = {};
plugins.forEach(({ name, hooks }) => {
Object.entries(hooks ?? {}).forEach(([key, value]) => {
if (!hooksFns[key]) hooksFns[key] = [];
hooksFns[key].push([name, value]);
});
});
return Object.fromEntries(Object.entries(hooksFns).map(([key, entries]) => {
const fns = entries.map(([name, fn]) => tryCatch(name, fn));
const reducer = key in reducers ? reducers[key] : void 0;
if (reducer) return [key, reducer(fns)];
return [key, syncHooks.includes(key) ? callAll(...fns) : callAllAsync(...fns)];
}));
};
const createReducer = (reducer) => reducer;
const reducers = {
"config:resolved": createReducer((fns) => async (_args) => {
const args = Object.assign({}, _args);
const original = _args.config;
let config = args.config;
for (const hookFn of fns) {
const result = await hookFn(Object.assign(args, {
config,
original
}));
if (result !== void 0) config = result;
}
return config;
}),
"parser:before": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.content;
let content = args.content;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
content,
original
}));
if (result !== void 0) content = result;
}
return content;
}),
"parser:preprocess": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.data;
let data = args.data;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
data,
original
}));
if (result !== void 0) data = result;
}
return data;
}),
"cssgen:done": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.content;
let content = args.content;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
content,
original
}));
if (result !== void 0) content = result;
}
return content;
}),
"codegen:prepare": createReducer((fns) => async (_args) => {
const args = Object.assign({}, _args);
const original = _args.artifacts;
let artifacts = args.artifacts;
for (const hookFn of fns) {
const result = await hookFn(Object.assign(args, {
artifacts,
original
}));
if (result) artifacts = result;
}
return artifacts;
}),
"preset:resolved": createReducer((fns) => async (_args) => {
const args = Object.assign({}, _args);
const original = _args.preset;
let preset = args.preset;
for (const hookFn of fns) {
const result = await hookFn(Object.assign(args, {
preset,
original
}));
if (result !== void 0) preset = result;
}
return preset;
}),
"css:optimize": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.css;
let css = args.css;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
css,
original
}));
if (result !== void 0) css = result;
}
return css;
})
};
const syncHooks = [
"context:created",
"parser:before",
"parser:preprocess",
"parser:after",
"cssgen:done",
"css:optimize"
];
const callAllAsync = (...fns) => async (...a) => {
for (const fn of fns) await fn?.(...a);
};
const callAll = (...fns) => (...a) => {
fns.forEach((fn) => fn?.(...a));
};
const tryCatch = (name, fn) => {
return (...args) => {
try {
return fn(...args);
} catch (e) {
logger.caughtError("hooks", `Error in plugin "${name}"`, e);
}
};
};
//#endregion
//#region src/validation/utils.ts
const REFERENCE_REGEX = /({([^}]*)})/g;
const curlyBracketRegex = /[{}]/g;
const isValidToken = (token) => isObject(token) && Object.hasOwnProperty.call(token, "value");
const isTokenReference = (value) => typeof value === "string" && REFERENCE_REGEX.test(value);
const formatPath = (path) => path;
function getReferences(value) {
if (typeof value !== "string") return [];
const matches = value.match(REFERENCE_REGEX);
if (!matches) return [];
return matches.map((match) => match.replace(curlyBracketRegex, "")).map((value) => {
return value.trim().split("/")[0];
});
}
const serializeTokenValue = (value) => {
if (isString(value)) return value;
if (isObject(value)) return Object.values(value).map((v) => serializeTokenValue(v)).join(" ");
if (Array.isArray(value)) return value.map((v) => serializeTokenValue(v)).join(" ");
return value.toString();
};
//#endregion
//#region src/merge-config.ts
/**
* Collect all `extend` properties into an array (to avoid mutation)
*/
function getExtends(items) {
return items.reduce((merged, { extend }) => {
if (!extend) return merged;
return mergeWith(merged, extend, (originalValue, newValue) => {
if (newValue === void 0) return originalValue ?? [];
if (originalValue === void 0) return [newValue];
if (Array.isArray(originalValue)) return [newValue, ...originalValue];
return [newValue, originalValue];
});
}, {});
}
/**
* Separate the `extend` properties from the rest of the object
*/
function mergeRecords(records) {
return {
...records.reduce((acc, record) => assign(acc, record), {}),
extend: getExtends(records)
};
}
/**
* Merge all `extend` properties into the rest of the object
*/
function mergeExtensions(records) {
const { extend = [], ...restProps } = mergeRecords(records);
return mergeWith(restProps, extend, (obj, extensions) => {
return mergeAndConcat({}, obj, ...extensions);
});
}
const isEmptyObject = (obj) => typeof obj === "object" && Object.keys(obj).length === 0;
const compact = (obj) => {
return Object.keys(obj).reduce((acc, key) => {
if (obj[key] !== void 0 && !isEmptyObject(obj[key])) acc[key] = obj[key];
return acc;
}, {});
};
const tokenKeys = [
"description",
"extensions",
"type",
"value",
"deprecated"
];
/**
* Merge all configs into a single config
*/
function mergeConfigs(configs) {
const userConfig = configs.at(-1);
const pluginHooks = userConfig.plugins ?? [];
if (userConfig.hooks) pluginHooks.push({
name: BAMBOO_CONFIG_NAME,
hooks: userConfig.hooks
});
const reversed = Array.from(configs).reverse();
const withoutEmpty = compact(assign({
conditions: mergeExtensions(reversed.map((config) => config.conditions ?? {})),
theme: mergeExtensions(reversed.map((config) => config.theme ?? {})),
patterns: mergeExtensions(reversed.map((config) => config.patterns ?? {})),
utilities: mergeExtensions(reversed.map((config) => config.utilities ?? {})),
globalCss: mergeExtensions(reversed.map((config) => config.globalCss ?? {})),
globalVars: mergeExtensions(reversed.map((config) => config.globalVars ?? {})),
globalFontface: mergeExtensions(reversed.map((config) => config.globalFontface ?? {})),
globalPositionTry: mergeExtensions(reversed.map((config) => config.globalPositionTry ?? {})),
staticCss: mergeExtensions(reversed.map((config) => config.staticCss ?? {})),
themes: mergeExtensions(reversed.map((config) => config.themes ?? {})),
hooks: mergeHooks(pluginHooks)
}, ...reversed));
/**
* Properly merge tokens between flat/nested forms by setting the flat form as the default
* preset:
* ```
* tokens: {
* black: {
* value: "black"
* }
* }
* // color: "black"
* ```
*
* config:
* ```
* tokens: {
* black: {
* 0: { value: "black" },
* 10: { value: "black/10" },
* 20: { value: "black/20" },
* // ...
* }
* }
*
* // color: "black.20"
* ```
*/
if (withoutEmpty.theme?.tokens) walkObject(withoutEmpty.theme.tokens, (args) => args, { stop(token) {
if (!isValidToken(token)) return false;
if (Object.keys(token).filter((k) => !tokenKeys.includes(k)).length > 0) {
token.DEFAULT ||= {};
tokenKeys.forEach((key) => {
if (token[key] == null) return;
token.DEFAULT[key] ||= token[key];
delete token[key];
});
}
return true;
} });
return withoutEmpty;
}
//#endregion
//#region src/get-resolved-config.ts

@@ -201,0 +643,0 @@ const hookUtils$1 = {

Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const require_merge_config = require("./merge-config-CcNpHJit.cjs");
exports.mergeConfigs = require_merge_config.mergeConfigs;
exports.mergeHooks = require_merge_config.mergeHooks;
let _bamboocss_shared = require("@bamboocss/shared");
let _bamboocss_logger = require("@bamboocss/logger");
//#region src/merge-hooks.ts
const mergeHooks = (plugins) => {
const hooksFns = {};
plugins.forEach(({ name, hooks }) => {
Object.entries(hooks ?? {}).forEach(([key, value]) => {
if (!hooksFns[key]) hooksFns[key] = [];
hooksFns[key].push([name, value]);
});
});
return Object.fromEntries(Object.entries(hooksFns).map(([key, entries]) => {
const fns = entries.map(([name, fn]) => tryCatch(name, fn));
const reducer = key in reducers ? reducers[key] : void 0;
if (reducer) return [key, reducer(fns)];
return [key, syncHooks.includes(key) ? callAll(...fns) : callAllAsync(...fns)];
}));
};
const createReducer = (reducer) => reducer;
const reducers = {
"config:resolved": createReducer((fns) => async (_args) => {
const args = Object.assign({}, _args);
const original = _args.config;
let config = args.config;
for (const hookFn of fns) {
const result = await hookFn(Object.assign(args, {
config,
original
}));
if (result !== void 0) config = result;
}
return config;
}),
"parser:before": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.content;
let content = args.content;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
content,
original
}));
if (result !== void 0) content = result;
}
return content;
}),
"parser:preprocess": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.data;
let data = args.data;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
data,
original
}));
if (result !== void 0) data = result;
}
return data;
}),
"cssgen:done": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.content;
let content = args.content;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
content,
original
}));
if (result !== void 0) content = result;
}
return content;
}),
"codegen:prepare": createReducer((fns) => async (_args) => {
const args = Object.assign({}, _args);
const original = _args.artifacts;
let artifacts = args.artifacts;
for (const hookFn of fns) {
const result = await hookFn(Object.assign(args, {
artifacts,
original
}));
if (result) artifacts = result;
}
return artifacts;
}),
"preset:resolved": createReducer((fns) => async (_args) => {
const args = Object.assign({}, _args);
const original = _args.preset;
let preset = args.preset;
for (const hookFn of fns) {
const result = await hookFn(Object.assign(args, {
preset,
original
}));
if (result !== void 0) preset = result;
}
return preset;
}),
"css:optimize": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.css;
let css = args.css;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
css,
original
}));
if (result !== void 0) css = result;
}
return css;
})
};
const syncHooks = [
"context:created",
"parser:before",
"parser:preprocess",
"parser:after",
"cssgen:done",
"css:optimize"
];
const callAllAsync = (...fns) => async (...a) => {
for (const fn of fns) await fn?.(...a);
};
const callAll = (...fns) => (...a) => {
fns.forEach((fn) => fn?.(...a));
};
const tryCatch = (name, fn) => {
return (...args) => {
try {
return fn(...args);
} catch (e) {
_bamboocss_logger.logger.caughtError("hooks", `Error in plugin "${name}"`, e);
}
};
};
//#endregion
//#region src/validation/utils.ts
const isValidToken = (token) => (0, _bamboocss_shared.isObject)(token) && Object.hasOwnProperty.call(token, "value");
//#endregion
//#region src/merge-config.ts
/**
* Collect all `extend` properties into an array (to avoid mutation)
*/
function getExtends(items) {
return items.reduce((merged, { extend }) => {
if (!extend) return merged;
return (0, _bamboocss_shared.mergeWith)(merged, extend, (originalValue, newValue) => {
if (newValue === void 0) return originalValue ?? [];
if (originalValue === void 0) return [newValue];
if (Array.isArray(originalValue)) return [newValue, ...originalValue];
return [newValue, originalValue];
});
}, {});
}
/**
* Separate the `extend` properties from the rest of the object
*/
function mergeRecords(records) {
return {
...records.reduce((acc, record) => (0, _bamboocss_shared.assign)(acc, record), {}),
extend: getExtends(records)
};
}
/**
* Merge all `extend` properties into the rest of the object
*/
function mergeExtensions(records) {
const { extend = [], ...restProps } = mergeRecords(records);
return (0, _bamboocss_shared.mergeWith)(restProps, extend, (obj, extensions) => {
return (0, _bamboocss_shared.mergeAndConcat)({}, obj, ...extensions);
});
}
const isEmptyObject = (obj) => typeof obj === "object" && Object.keys(obj).length === 0;
const compact = (obj) => {
return Object.keys(obj).reduce((acc, key) => {
if (obj[key] !== void 0 && !isEmptyObject(obj[key])) acc[key] = obj[key];
return acc;
}, {});
};
const tokenKeys = [
"description",
"extensions",
"type",
"value",
"deprecated"
];
/**
* Merge all configs into a single config
*/
function mergeConfigs(configs) {
const userConfig = configs.at(-1);
const pluginHooks = userConfig.plugins ?? [];
if (userConfig.hooks) pluginHooks.push({
name: _bamboocss_shared.BAMBOO_CONFIG_NAME,
hooks: userConfig.hooks
});
const reversed = Array.from(configs).reverse();
const withoutEmpty = compact((0, _bamboocss_shared.assign)({
conditions: mergeExtensions(reversed.map((config) => config.conditions ?? {})),
theme: mergeExtensions(reversed.map((config) => config.theme ?? {})),
patterns: mergeExtensions(reversed.map((config) => config.patterns ?? {})),
utilities: mergeExtensions(reversed.map((config) => config.utilities ?? {})),
globalCss: mergeExtensions(reversed.map((config) => config.globalCss ?? {})),
globalVars: mergeExtensions(reversed.map((config) => config.globalVars ?? {})),
globalFontface: mergeExtensions(reversed.map((config) => config.globalFontface ?? {})),
globalPositionTry: mergeExtensions(reversed.map((config) => config.globalPositionTry ?? {})),
staticCss: mergeExtensions(reversed.map((config) => config.staticCss ?? {})),
themes: mergeExtensions(reversed.map((config) => config.themes ?? {})),
hooks: mergeHooks(pluginHooks)
}, ...reversed));
/**
* Properly merge tokens between flat/nested forms by setting the flat form as the default
* preset:
* ```
* tokens: {
* black: {
* value: "black"
* }
* }
* // color: "black"
* ```
*
* config:
* ```
* tokens: {
* black: {
* 0: { value: "black" },
* 10: { value: "black/10" },
* 20: { value: "black/20" },
* // ...
* }
* }
*
* // color: "black.20"
* ```
*/
if (withoutEmpty.theme?.tokens) (0, _bamboocss_shared.walkObject)(withoutEmpty.theme.tokens, (args) => args, { stop(token) {
if (!isValidToken(token)) return false;
if (Object.keys(token).filter((k) => !tokenKeys.includes(k)).length > 0) {
token.DEFAULT ||= {};
tokenKeys.forEach((key) => {
if (token[key] == null) return;
token.DEFAULT[key] ||= token[key];
delete token[key];
});
}
return true;
} });
return withoutEmpty;
}
//#endregion
exports.mergeConfigs = mergeConfigs;
exports.mergeHooks = mergeHooks;

@@ -1,2 +0,16 @@

import { n as mergeHooks, t as mergeConfigs } from "./merge-config-DVOlBQJY.cjs";
import { BambooPlugin, Config } from "@bamboocss/types";
//#region src/merge-hooks.d.ts
declare const mergeHooks: (plugins: BambooPlugin[]) => BambooHooks;
//#endregion
//#region src/merge-config.d.ts
type Extendable<T> = T & {
extend?: T;
};
type ExtendableConfig = Extendable<Config>;
/**
* Merge all configs into a single config
*/
declare function mergeConfigs(configs: ExtendableConfig[]): any;
//#endregion
export { mergeConfigs, mergeHooks };

@@ -1,2 +0,16 @@

import { n as mergeHooks, t as mergeConfigs } from "./merge-config-oEiBYbfB.mjs";
import { BambooPlugin, Config } from "@bamboocss/types";
//#region src/merge-hooks.d.ts
declare const mergeHooks: (plugins: BambooPlugin[]) => BambooHooks;
//#endregion
//#region src/merge-config.d.ts
type Extendable<T> = T & {
extend?: T;
};
type ExtendableConfig = Extendable<Config>;
/**
* Merge all configs into a single config
*/
declare function mergeConfigs(configs: ExtendableConfig[]): any;
//#endregion
export { mergeConfigs, mergeHooks };

@@ -1,2 +0,252 @@

import { s as mergeHooks, t as mergeConfigs } from "./merge-config-DI__LOWx.mjs";
import { BAMBOO_CONFIG_NAME, assign, isObject, mergeAndConcat, mergeWith, walkObject } from "@bamboocss/shared";
import { logger } from "@bamboocss/logger";
//#region src/merge-hooks.ts
const mergeHooks = (plugins) => {
const hooksFns = {};
plugins.forEach(({ name, hooks }) => {
Object.entries(hooks ?? {}).forEach(([key, value]) => {
if (!hooksFns[key]) hooksFns[key] = [];
hooksFns[key].push([name, value]);
});
});
return Object.fromEntries(Object.entries(hooksFns).map(([key, entries]) => {
const fns = entries.map(([name, fn]) => tryCatch(name, fn));
const reducer = key in reducers ? reducers[key] : void 0;
if (reducer) return [key, reducer(fns)];
return [key, syncHooks.includes(key) ? callAll(...fns) : callAllAsync(...fns)];
}));
};
const createReducer = (reducer) => reducer;
const reducers = {
"config:resolved": createReducer((fns) => async (_args) => {
const args = Object.assign({}, _args);
const original = _args.config;
let config = args.config;
for (const hookFn of fns) {
const result = await hookFn(Object.assign(args, {
config,
original
}));
if (result !== void 0) config = result;
}
return config;
}),
"parser:before": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.content;
let content = args.content;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
content,
original
}));
if (result !== void 0) content = result;
}
return content;
}),
"parser:preprocess": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.data;
let data = args.data;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
data,
original
}));
if (result !== void 0) data = result;
}
return data;
}),
"cssgen:done": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.content;
let content = args.content;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
content,
original
}));
if (result !== void 0) content = result;
}
return content;
}),
"codegen:prepare": createReducer((fns) => async (_args) => {
const args = Object.assign({}, _args);
const original = _args.artifacts;
let artifacts = args.artifacts;
for (const hookFn of fns) {
const result = await hookFn(Object.assign(args, {
artifacts,
original
}));
if (result) artifacts = result;
}
return artifacts;
}),
"preset:resolved": createReducer((fns) => async (_args) => {
const args = Object.assign({}, _args);
const original = _args.preset;
let preset = args.preset;
for (const hookFn of fns) {
const result = await hookFn(Object.assign(args, {
preset,
original
}));
if (result !== void 0) preset = result;
}
return preset;
}),
"css:optimize": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.css;
let css = args.css;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
css,
original
}));
if (result !== void 0) css = result;
}
return css;
})
};
const syncHooks = [
"context:created",
"parser:before",
"parser:preprocess",
"parser:after",
"cssgen:done",
"css:optimize"
];
const callAllAsync = (...fns) => async (...a) => {
for (const fn of fns) await fn?.(...a);
};
const callAll = (...fns) => (...a) => {
fns.forEach((fn) => fn?.(...a));
};
const tryCatch = (name, fn) => {
return (...args) => {
try {
return fn(...args);
} catch (e) {
logger.caughtError("hooks", `Error in plugin "${name}"`, e);
}
};
};
//#endregion
//#region src/validation/utils.ts
const isValidToken = (token) => isObject(token) && Object.hasOwnProperty.call(token, "value");
//#endregion
//#region src/merge-config.ts
/**
* Collect all `extend` properties into an array (to avoid mutation)
*/
function getExtends(items) {
return items.reduce((merged, { extend }) => {
if (!extend) return merged;
return mergeWith(merged, extend, (originalValue, newValue) => {
if (newValue === void 0) return originalValue ?? [];
if (originalValue === void 0) return [newValue];
if (Array.isArray(originalValue)) return [newValue, ...originalValue];
return [newValue, originalValue];
});
}, {});
}
/**
* Separate the `extend` properties from the rest of the object
*/
function mergeRecords(records) {
return {
...records.reduce((acc, record) => assign(acc, record), {}),
extend: getExtends(records)
};
}
/**
* Merge all `extend` properties into the rest of the object
*/
function mergeExtensions(records) {
const { extend = [], ...restProps } = mergeRecords(records);
return mergeWith(restProps, extend, (obj, extensions) => {
return mergeAndConcat({}, obj, ...extensions);
});
}
const isEmptyObject = (obj) => typeof obj === "object" && Object.keys(obj).length === 0;
const compact = (obj) => {
return Object.keys(obj).reduce((acc, key) => {
if (obj[key] !== void 0 && !isEmptyObject(obj[key])) acc[key] = obj[key];
return acc;
}, {});
};
const tokenKeys = [
"description",
"extensions",
"type",
"value",
"deprecated"
];
/**
* Merge all configs into a single config
*/
function mergeConfigs(configs) {
const userConfig = configs.at(-1);
const pluginHooks = userConfig.plugins ?? [];
if (userConfig.hooks) pluginHooks.push({
name: BAMBOO_CONFIG_NAME,
hooks: userConfig.hooks
});
const reversed = Array.from(configs).reverse();
const withoutEmpty = compact(assign({
conditions: mergeExtensions(reversed.map((config) => config.conditions ?? {})),
theme: mergeExtensions(reversed.map((config) => config.theme ?? {})),
patterns: mergeExtensions(reversed.map((config) => config.patterns ?? {})),
utilities: mergeExtensions(reversed.map((config) => config.utilities ?? {})),
globalCss: mergeExtensions(reversed.map((config) => config.globalCss ?? {})),
globalVars: mergeExtensions(reversed.map((config) => config.globalVars ?? {})),
globalFontface: mergeExtensions(reversed.map((config) => config.globalFontface ?? {})),
globalPositionTry: mergeExtensions(reversed.map((config) => config.globalPositionTry ?? {})),
staticCss: mergeExtensions(reversed.map((config) => config.staticCss ?? {})),
themes: mergeExtensions(reversed.map((config) => config.themes ?? {})),
hooks: mergeHooks(pluginHooks)
}, ...reversed));
/**
* Properly merge tokens between flat/nested forms by setting the flat form as the default
* preset:
* ```
* tokens: {
* black: {
* value: "black"
* }
* }
* // color: "black"
* ```
*
* config:
* ```
* tokens: {
* black: {
* 0: { value: "black" },
* 10: { value: "black/10" },
* 20: { value: "black/20" },
* // ...
* }
* }
*
* // color: "black.20"
* ```
*/
if (withoutEmpty.theme?.tokens) walkObject(withoutEmpty.theme.tokens, (args) => args, { stop(token) {
if (!isValidToken(token)) return false;
if (Object.keys(token).filter((k) => !tokenKeys.includes(k)).length > 0) {
token.DEFAULT ||= {};
tokenKeys.forEach((key) => {
if (token[key] == null) return;
token.DEFAULT[key] ||= token[key];
delete token[key];
});
}
return true;
} });
return withoutEmpty;
}
//#endregion
export { mergeConfigs, mergeHooks };
+0
-1
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
require("./diff-config-Co_3mDXE.cjs");
let path = require("path");

@@ -4,0 +3,0 @@ //#region src/resolve-ts-path-pattern.ts

@@ -1,3 +0,7 @@

import { t as PathMapping } from "./ts-config-paths-wVx39QZ0.cjs";
//#region src/ts-config-paths.d.ts
interface PathMapping {
pattern: RegExp;
paths: string[];
}
//#endregion
//#region src/resolve-ts-path-pattern.d.ts

@@ -4,0 +8,0 @@ /**

@@ -1,3 +0,7 @@

import { t as PathMapping } from "./ts-config-paths-CvGId8kq.mjs";
//#region src/ts-config-paths.d.ts
interface PathMapping {
pattern: RegExp;
paths: string[];
}
//#endregion
//#region src/resolve-ts-path-pattern.d.ts

@@ -4,0 +8,0 @@ /**

{
"name": "@bamboocss/config",
"version": "1.11.4",
"version": "1.12.0",
"description": "Find and load bamboo config",

@@ -67,7 +67,7 @@ "homepage": "https://bamboo-css.com",

"typescript": "6.0.2",
"@bamboocss/preset-bamboo": "1.11.4",
"@bamboocss/shared": "1.11.4",
"@bamboocss/logger": "1.11.4",
"@bamboocss/preset-base": "1.11.4",
"@bamboocss/types": "1.11.4"
"@bamboocss/logger": "1.12.0",
"@bamboocss/preset-bamboo": "1.12.0",
"@bamboocss/preset-base": "1.12.0",
"@bamboocss/shared": "1.12.0",
"@bamboocss/types": "1.12.0"
},

@@ -74,0 +74,0 @@ "devDependencies": {

//#region \0rolldown/runtime.js
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
//#endregion
let _bamboocss_shared = require("@bamboocss/shared");
let microdiff = require("microdiff");
microdiff = __toESM(microdiff);
//#region src/create-matcher.ts
/**
* Acts like a .gitignore matcher
* e.g a list of string to search for nested path with glob and exclusion allowed
* ["outdir", "theme.recipes", '*.css', '!aaa.*.bbb']
*/
function createMatcher(id, patterns) {
if (!patterns?.length) return () => void 0;
const includePatterns = [];
const excludePatterns = [];
new Set(patterns).forEach((pattern) => {
const regexString = pattern.replace(/\*/g, ".*");
if (pattern.startsWith("!")) excludePatterns.push(regexString.slice(1));
else includePatterns.push(regexString);
});
const include = new RegExp(includePatterns.join("|"));
const exclude = new RegExp(excludePatterns.join("|"));
return (path) => {
if (excludePatterns.length && exclude.test(path)) return;
return include.test(path) ? id : void 0;
};
}
//#endregion
//#region src/config-deps.ts
const all = [
"clean",
"cwd",
"eject",
"outdir",
"forceConsistentTypeExtension",
"outExtension",
"emitTokensOnly",
"presets",
"plugins",
"hooks"
];
const format = [
"syntax",
"hash",
"prefix",
"separator",
"strictTokens",
"strictPropertyValues",
"shorthands"
];
const tokens = [
"utilities",
"conditions",
"theme.tokens",
"theme.semanticTokens",
"theme.breakpoints",
"theme.containerNames",
"theme.containerSizes"
];
const jsx = [
"jsxFramework",
"jsxFactory",
"jsxStyleProps",
"syntax"
];
const common = tokens.concat(jsx, format);
const artifactConfigDeps = {
helpers: ["syntax", "jsxFramework"],
keyframes: ["theme.keyframes", "layers"],
"design-tokens": ["layers", "!utilities.*.className"].concat(tokens),
types: ["!utilities.*.className"].concat(common),
"css-fn": common,
cva: ["syntax"],
sva: ["syntax"],
cx: [],
"create-recipe": [
"separator",
"prefix",
"hash"
],
"recipes-index": ["theme.recipes", "theme.slotRecipes"],
recipes: ["theme.recipes", "theme.slotRecipes"],
"patterns-index": ["syntax", "patterns"],
patterns: ["syntax", "patterns"],
"jsx-is-valid-prop": common,
"jsx-factory": jsx,
"jsx-helpers": jsx,
"jsx-patterns": jsx.concat("patterns"),
"jsx-patterns-index": jsx.concat("patterns"),
"jsx-create-style-context": jsx,
"css-index": ["syntax"],
"package.json": ["forceConsistentTypeExtension", "outExtension"],
"types-styles": ["shorthands"],
"types-conditions": ["conditions"],
"types-jsx": jsx,
"types-entry": [],
"types-gen": [],
"types-gen-system": [],
themes: ["themes"].concat(tokens),
"static-css": [
"staticCss",
"patterns",
"theme.recipes",
"theme.slotRecipes"
].concat(tokens),
styles: [],
"styles.css": []
};
const artifactMatchers = Object.entries(artifactConfigDeps).map(([key, paths]) => {
if (!paths.length) return () => void 0;
return createMatcher(key, paths.concat(all));
});
//#endregion
//#region src/diff-config.ts
const runIfFn = (fn) => typeof fn === "function" ? fn() : fn;
/**
* Check if recipes were empty before and non-empty now (or vice versa)
*/
const hasRecipeStateTransition = (prevConfig, nextConfig) => {
const prevRecipes = prevConfig.theme?.recipes ?? {};
const prevSlotRecipes = prevConfig.theme?.slotRecipes ?? {};
const prevHasRecipes = Object.keys(prevRecipes).length > 0 || Object.keys(prevSlotRecipes).length > 0;
const nextRecipes = nextConfig.theme?.recipes ?? {};
const nextSlotRecipes = nextConfig.theme?.slotRecipes ?? {};
return prevHasRecipes !== (Object.keys(nextRecipes).length > 0 || Object.keys(nextSlotRecipes).length > 0);
};
/**
* Diff the two config objects and return the list of affected properties
*/
function diffConfigs(config, prevConfig) {
const affected = {
artifacts: /* @__PURE__ */ new Set(),
hasConfigChanged: false,
diffs: []
};
if (!prevConfig) {
affected.hasConfigChanged = true;
return affected;
}
const configDiff = (0, microdiff.default)(prevConfig, runIfFn(config));
if (!configDiff.length) return affected;
affected.hasConfigChanged = true;
affected.diffs = configDiff;
configDiff.forEach((change) => {
const changePath = change.path.join(".");
artifactMatchers.forEach((matcher) => {
const id = matcher(changePath);
if (!id) return;
if (id === "recipes") {
const name = (0, _bamboocss_shared.dashCase)(change.path.slice(1, 3).join("."));
affected.artifacts.add(name);
}
if (id === "patterns") {
const name = (0, _bamboocss_shared.dashCase)(change.path.slice(0, 2).join("."));
affected.artifacts.add(name);
}
affected.artifacts.add(id);
});
});
if (affected.artifacts.has("recipes") || affected.artifacts.has("recipes-index")) {
if (hasRecipeStateTransition(prevConfig, runIfFn(config))) affected.artifacts.add("create-recipe");
}
return affected;
}
//#endregion
Object.defineProperty(exports, "__toESM", {
enumerable: true,
get: function() {
return __toESM;
}
});
Object.defineProperty(exports, "diffConfigs", {
enumerable: true,
get: function() {
return diffConfigs;
}
});
import { dashCase } from "@bamboocss/shared";
import microdiff from "microdiff";
//#region src/create-matcher.ts
/**
* Acts like a .gitignore matcher
* e.g a list of string to search for nested path with glob and exclusion allowed
* ["outdir", "theme.recipes", '*.css', '!aaa.*.bbb']
*/
function createMatcher(id, patterns) {
if (!patterns?.length) return () => void 0;
const includePatterns = [];
const excludePatterns = [];
new Set(patterns).forEach((pattern) => {
const regexString = pattern.replace(/\*/g, ".*");
if (pattern.startsWith("!")) excludePatterns.push(regexString.slice(1));
else includePatterns.push(regexString);
});
const include = new RegExp(includePatterns.join("|"));
const exclude = new RegExp(excludePatterns.join("|"));
return (path) => {
if (excludePatterns.length && exclude.test(path)) return;
return include.test(path) ? id : void 0;
};
}
//#endregion
//#region src/config-deps.ts
const all = [
"clean",
"cwd",
"eject",
"outdir",
"forceConsistentTypeExtension",
"outExtension",
"emitTokensOnly",
"presets",
"plugins",
"hooks"
];
const format = [
"syntax",
"hash",
"prefix",
"separator",
"strictTokens",
"strictPropertyValues",
"shorthands"
];
const tokens = [
"utilities",
"conditions",
"theme.tokens",
"theme.semanticTokens",
"theme.breakpoints",
"theme.containerNames",
"theme.containerSizes"
];
const jsx = [
"jsxFramework",
"jsxFactory",
"jsxStyleProps",
"syntax"
];
const common = tokens.concat(jsx, format);
const artifactConfigDeps = {
helpers: ["syntax", "jsxFramework"],
keyframes: ["theme.keyframes", "layers"],
"design-tokens": ["layers", "!utilities.*.className"].concat(tokens),
types: ["!utilities.*.className"].concat(common),
"css-fn": common,
cva: ["syntax"],
sva: ["syntax"],
cx: [],
"create-recipe": [
"separator",
"prefix",
"hash"
],
"recipes-index": ["theme.recipes", "theme.slotRecipes"],
recipes: ["theme.recipes", "theme.slotRecipes"],
"patterns-index": ["syntax", "patterns"],
patterns: ["syntax", "patterns"],
"jsx-is-valid-prop": common,
"jsx-factory": jsx,
"jsx-helpers": jsx,
"jsx-patterns": jsx.concat("patterns"),
"jsx-patterns-index": jsx.concat("patterns"),
"jsx-create-style-context": jsx,
"css-index": ["syntax"],
"package.json": ["forceConsistentTypeExtension", "outExtension"],
"types-styles": ["shorthands"],
"types-conditions": ["conditions"],
"types-jsx": jsx,
"types-entry": [],
"types-gen": [],
"types-gen-system": [],
themes: ["themes"].concat(tokens),
"static-css": [
"staticCss",
"patterns",
"theme.recipes",
"theme.slotRecipes"
].concat(tokens),
styles: [],
"styles.css": []
};
const artifactMatchers = Object.entries(artifactConfigDeps).map(([key, paths]) => {
if (!paths.length) return () => void 0;
return createMatcher(key, paths.concat(all));
});
//#endregion
//#region src/diff-config.ts
const runIfFn = (fn) => typeof fn === "function" ? fn() : fn;
/**
* Check if recipes were empty before and non-empty now (or vice versa)
*/
const hasRecipeStateTransition = (prevConfig, nextConfig) => {
const prevRecipes = prevConfig.theme?.recipes ?? {};
const prevSlotRecipes = prevConfig.theme?.slotRecipes ?? {};
const prevHasRecipes = Object.keys(prevRecipes).length > 0 || Object.keys(prevSlotRecipes).length > 0;
const nextRecipes = nextConfig.theme?.recipes ?? {};
const nextSlotRecipes = nextConfig.theme?.slotRecipes ?? {};
return prevHasRecipes !== (Object.keys(nextRecipes).length > 0 || Object.keys(nextSlotRecipes).length > 0);
};
/**
* Diff the two config objects and return the list of affected properties
*/
function diffConfigs(config, prevConfig) {
const affected = {
artifacts: /* @__PURE__ */ new Set(),
hasConfigChanged: false,
diffs: []
};
if (!prevConfig) {
affected.hasConfigChanged = true;
return affected;
}
const configDiff = microdiff(prevConfig, runIfFn(config));
if (!configDiff.length) return affected;
affected.hasConfigChanged = true;
affected.diffs = configDiff;
configDiff.forEach((change) => {
const changePath = change.path.join(".");
artifactMatchers.forEach((matcher) => {
const id = matcher(changePath);
if (!id) return;
if (id === "recipes") {
const name = dashCase(change.path.slice(1, 3).join("."));
affected.artifacts.add(name);
}
if (id === "patterns") {
const name = dashCase(change.path.slice(0, 2).join("."));
affected.artifacts.add(name);
}
affected.artifacts.add(id);
});
});
if (affected.artifacts.has("recipes") || affected.artifacts.has("recipes-index")) {
if (hasRecipeStateTransition(prevConfig, runIfFn(config))) affected.artifacts.add("create-recipe");
}
return affected;
}
//#endregion
export { diffConfigs as t };
require("./diff-config-Co_3mDXE.cjs");
let _bamboocss_logger = require("@bamboocss/logger");
let _bamboocss_shared = require("@bamboocss/shared");
//#region src/merge-hooks.ts
const mergeHooks = (plugins) => {
const hooksFns = {};
plugins.forEach(({ name, hooks }) => {
Object.entries(hooks ?? {}).forEach(([key, value]) => {
if (!hooksFns[key]) hooksFns[key] = [];
hooksFns[key].push([name, value]);
});
});
return Object.fromEntries(Object.entries(hooksFns).map(([key, entries]) => {
const fns = entries.map(([name, fn]) => tryCatch(name, fn));
const reducer = key in reducers ? reducers[key] : void 0;
if (reducer) return [key, reducer(fns)];
return [key, syncHooks.includes(key) ? callAll(...fns) : callAllAsync(...fns)];
}));
};
const createReducer = (reducer) => reducer;
const reducers = {
"config:resolved": createReducer((fns) => async (_args) => {
const args = Object.assign({}, _args);
const original = _args.config;
let config = args.config;
for (const hookFn of fns) {
const result = await hookFn(Object.assign(args, {
config,
original
}));
if (result !== void 0) config = result;
}
return config;
}),
"parser:before": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.content;
let content = args.content;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
content,
original
}));
if (result !== void 0) content = result;
}
return content;
}),
"parser:preprocess": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.data;
let data = args.data;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
data,
original
}));
if (result !== void 0) data = result;
}
return data;
}),
"cssgen:done": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.content;
let content = args.content;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
content,
original
}));
if (result !== void 0) content = result;
}
return content;
}),
"codegen:prepare": createReducer((fns) => async (_args) => {
const args = Object.assign({}, _args);
const original = _args.artifacts;
let artifacts = args.artifacts;
for (const hookFn of fns) {
const result = await hookFn(Object.assign(args, {
artifacts,
original
}));
if (result) artifacts = result;
}
return artifacts;
}),
"preset:resolved": createReducer((fns) => async (_args) => {
const args = Object.assign({}, _args);
const original = _args.preset;
let preset = args.preset;
for (const hookFn of fns) {
const result = await hookFn(Object.assign(args, {
preset,
original
}));
if (result !== void 0) preset = result;
}
return preset;
}),
"css:optimize": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.css;
let css = args.css;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
css,
original
}));
if (result !== void 0) css = result;
}
return css;
})
};
const syncHooks = [
"context:created",
"parser:before",
"parser:preprocess",
"parser:after",
"cssgen:done",
"css:optimize"
];
const callAllAsync = (...fns) => async (...a) => {
for (const fn of fns) await fn?.(...a);
};
const callAll = (...fns) => (...a) => {
fns.forEach((fn) => fn?.(...a));
};
const tryCatch = (name, fn) => {
return (...args) => {
try {
return fn(...args);
} catch (e) {
_bamboocss_logger.logger.caughtError("hooks", `Error in plugin "${name}"`, e);
}
};
};
//#endregion
//#region src/validation/utils.ts
const REFERENCE_REGEX = /({([^}]*)})/g;
const curlyBracketRegex = /[{}]/g;
const isValidToken = (token) => (0, _bamboocss_shared.isObject)(token) && Object.hasOwnProperty.call(token, "value");
const isTokenReference = (value) => typeof value === "string" && REFERENCE_REGEX.test(value);
const formatPath = (path) => path;
function getReferences(value) {
if (typeof value !== "string") return [];
const matches = value.match(REFERENCE_REGEX);
if (!matches) return [];
return matches.map((match) => match.replace(curlyBracketRegex, "")).map((value) => {
return value.trim().split("/")[0];
});
}
const serializeTokenValue = (value) => {
if ((0, _bamboocss_shared.isString)(value)) return value;
if ((0, _bamboocss_shared.isObject)(value)) return Object.values(value).map((v) => serializeTokenValue(v)).join(" ");
if (Array.isArray(value)) return value.map((v) => serializeTokenValue(v)).join(" ");
return value.toString();
};
//#endregion
//#region src/merge-config.ts
/**
* Collect all `extend` properties into an array (to avoid mutation)
*/
function getExtends(items) {
return items.reduce((merged, { extend }) => {
if (!extend) return merged;
return (0, _bamboocss_shared.mergeWith)(merged, extend, (originalValue, newValue) => {
if (newValue === void 0) return originalValue ?? [];
if (originalValue === void 0) return [newValue];
if (Array.isArray(originalValue)) return [newValue, ...originalValue];
return [newValue, originalValue];
});
}, {});
}
/**
* Separate the `extend` properties from the rest of the object
*/
function mergeRecords(records) {
return {
...records.reduce((acc, record) => (0, _bamboocss_shared.assign)(acc, record), {}),
extend: getExtends(records)
};
}
/**
* Merge all `extend` properties into the rest of the object
*/
function mergeExtensions(records) {
const { extend = [], ...restProps } = mergeRecords(records);
return (0, _bamboocss_shared.mergeWith)(restProps, extend, (obj, extensions) => {
return (0, _bamboocss_shared.mergeAndConcat)({}, obj, ...extensions);
});
}
const isEmptyObject = (obj) => typeof obj === "object" && Object.keys(obj).length === 0;
const compact = (obj) => {
return Object.keys(obj).reduce((acc, key) => {
if (obj[key] !== void 0 && !isEmptyObject(obj[key])) acc[key] = obj[key];
return acc;
}, {});
};
const tokenKeys = [
"description",
"extensions",
"type",
"value",
"deprecated"
];
/**
* Merge all configs into a single config
*/
function mergeConfigs(configs) {
const userConfig = configs.at(-1);
const pluginHooks = userConfig.plugins ?? [];
if (userConfig.hooks) pluginHooks.push({
name: _bamboocss_shared.BAMBOO_CONFIG_NAME,
hooks: userConfig.hooks
});
const reversed = Array.from(configs).reverse();
const withoutEmpty = compact((0, _bamboocss_shared.assign)({
conditions: mergeExtensions(reversed.map((config) => config.conditions ?? {})),
theme: mergeExtensions(reversed.map((config) => config.theme ?? {})),
patterns: mergeExtensions(reversed.map((config) => config.patterns ?? {})),
utilities: mergeExtensions(reversed.map((config) => config.utilities ?? {})),
globalCss: mergeExtensions(reversed.map((config) => config.globalCss ?? {})),
globalVars: mergeExtensions(reversed.map((config) => config.globalVars ?? {})),
globalFontface: mergeExtensions(reversed.map((config) => config.globalFontface ?? {})),
globalPositionTry: mergeExtensions(reversed.map((config) => config.globalPositionTry ?? {})),
staticCss: mergeExtensions(reversed.map((config) => config.staticCss ?? {})),
themes: mergeExtensions(reversed.map((config) => config.themes ?? {})),
hooks: mergeHooks(pluginHooks)
}, ...reversed));
/**
* Properly merge tokens between flat/nested forms by setting the flat form as the default
* preset:
* ```
* tokens: {
* black: {
* value: "black"
* }
* }
* // color: "black"
* ```
*
* config:
* ```
* tokens: {
* black: {
* 0: { value: "black" },
* 10: { value: "black/10" },
* 20: { value: "black/20" },
* // ...
* }
* }
*
* // color: "black.20"
* ```
*/
if (withoutEmpty.theme?.tokens) (0, _bamboocss_shared.walkObject)(withoutEmpty.theme.tokens, (args) => args, { stop(token) {
if (!isValidToken(token)) return false;
if (Object.keys(token).filter((k) => !tokenKeys.includes(k)).length > 0) {
token.DEFAULT ||= {};
tokenKeys.forEach((key) => {
if (token[key] == null) return;
token.DEFAULT[key] ||= token[key];
delete token[key];
});
}
return true;
} });
return withoutEmpty;
}
//#endregion
Object.defineProperty(exports, "formatPath", {
enumerable: true,
get: function() {
return formatPath;
}
});
Object.defineProperty(exports, "getReferences", {
enumerable: true,
get: function() {
return getReferences;
}
});
Object.defineProperty(exports, "isTokenReference", {
enumerable: true,
get: function() {
return isTokenReference;
}
});
Object.defineProperty(exports, "isValidToken", {
enumerable: true,
get: function() {
return isValidToken;
}
});
Object.defineProperty(exports, "mergeConfigs", {
enumerable: true,
get: function() {
return mergeConfigs;
}
});
Object.defineProperty(exports, "mergeHooks", {
enumerable: true,
get: function() {
return mergeHooks;
}
});
Object.defineProperty(exports, "serializeTokenValue", {
enumerable: true,
get: function() {
return serializeTokenValue;
}
});
import { logger } from "@bamboocss/logger";
import { BAMBOO_CONFIG_NAME, assign, isObject, isString, mergeAndConcat, mergeWith, walkObject } from "@bamboocss/shared";
//#region src/merge-hooks.ts
const mergeHooks = (plugins) => {
const hooksFns = {};
plugins.forEach(({ name, hooks }) => {
Object.entries(hooks ?? {}).forEach(([key, value]) => {
if (!hooksFns[key]) hooksFns[key] = [];
hooksFns[key].push([name, value]);
});
});
return Object.fromEntries(Object.entries(hooksFns).map(([key, entries]) => {
const fns = entries.map(([name, fn]) => tryCatch(name, fn));
const reducer = key in reducers ? reducers[key] : void 0;
if (reducer) return [key, reducer(fns)];
return [key, syncHooks.includes(key) ? callAll(...fns) : callAllAsync(...fns)];
}));
};
const createReducer = (reducer) => reducer;
const reducers = {
"config:resolved": createReducer((fns) => async (_args) => {
const args = Object.assign({}, _args);
const original = _args.config;
let config = args.config;
for (const hookFn of fns) {
const result = await hookFn(Object.assign(args, {
config,
original
}));
if (result !== void 0) config = result;
}
return config;
}),
"parser:before": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.content;
let content = args.content;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
content,
original
}));
if (result !== void 0) content = result;
}
return content;
}),
"parser:preprocess": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.data;
let data = args.data;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
data,
original
}));
if (result !== void 0) data = result;
}
return data;
}),
"cssgen:done": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.content;
let content = args.content;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
content,
original
}));
if (result !== void 0) content = result;
}
return content;
}),
"codegen:prepare": createReducer((fns) => async (_args) => {
const args = Object.assign({}, _args);
const original = _args.artifacts;
let artifacts = args.artifacts;
for (const hookFn of fns) {
const result = await hookFn(Object.assign(args, {
artifacts,
original
}));
if (result) artifacts = result;
}
return artifacts;
}),
"preset:resolved": createReducer((fns) => async (_args) => {
const args = Object.assign({}, _args);
const original = _args.preset;
let preset = args.preset;
for (const hookFn of fns) {
const result = await hookFn(Object.assign(args, {
preset,
original
}));
if (result !== void 0) preset = result;
}
return preset;
}),
"css:optimize": createReducer((fns) => (_args) => {
const args = Object.assign({}, _args);
const original = _args.css;
let css = args.css;
for (const hookFn of fns) {
const result = hookFn(Object.assign(args, {
css,
original
}));
if (result !== void 0) css = result;
}
return css;
})
};
const syncHooks = [
"context:created",
"parser:before",
"parser:preprocess",
"parser:after",
"cssgen:done",
"css:optimize"
];
const callAllAsync = (...fns) => async (...a) => {
for (const fn of fns) await fn?.(...a);
};
const callAll = (...fns) => (...a) => {
fns.forEach((fn) => fn?.(...a));
};
const tryCatch = (name, fn) => {
return (...args) => {
try {
return fn(...args);
} catch (e) {
logger.caughtError("hooks", `Error in plugin "${name}"`, e);
}
};
};
//#endregion
//#region src/validation/utils.ts
const REFERENCE_REGEX = /({([^}]*)})/g;
const curlyBracketRegex = /[{}]/g;
const isValidToken = (token) => isObject(token) && Object.hasOwnProperty.call(token, "value");
const isTokenReference = (value) => typeof value === "string" && REFERENCE_REGEX.test(value);
const formatPath = (path) => path;
function getReferences(value) {
if (typeof value !== "string") return [];
const matches = value.match(REFERENCE_REGEX);
if (!matches) return [];
return matches.map((match) => match.replace(curlyBracketRegex, "")).map((value) => {
return value.trim().split("/")[0];
});
}
const serializeTokenValue = (value) => {
if (isString(value)) return value;
if (isObject(value)) return Object.values(value).map((v) => serializeTokenValue(v)).join(" ");
if (Array.isArray(value)) return value.map((v) => serializeTokenValue(v)).join(" ");
return value.toString();
};
//#endregion
//#region src/merge-config.ts
/**
* Collect all `extend` properties into an array (to avoid mutation)
*/
function getExtends(items) {
return items.reduce((merged, { extend }) => {
if (!extend) return merged;
return mergeWith(merged, extend, (originalValue, newValue) => {
if (newValue === void 0) return originalValue ?? [];
if (originalValue === void 0) return [newValue];
if (Array.isArray(originalValue)) return [newValue, ...originalValue];
return [newValue, originalValue];
});
}, {});
}
/**
* Separate the `extend` properties from the rest of the object
*/
function mergeRecords(records) {
return {
...records.reduce((acc, record) => assign(acc, record), {}),
extend: getExtends(records)
};
}
/**
* Merge all `extend` properties into the rest of the object
*/
function mergeExtensions(records) {
const { extend = [], ...restProps } = mergeRecords(records);
return mergeWith(restProps, extend, (obj, extensions) => {
return mergeAndConcat({}, obj, ...extensions);
});
}
const isEmptyObject = (obj) => typeof obj === "object" && Object.keys(obj).length === 0;
const compact = (obj) => {
return Object.keys(obj).reduce((acc, key) => {
if (obj[key] !== void 0 && !isEmptyObject(obj[key])) acc[key] = obj[key];
return acc;
}, {});
};
const tokenKeys = [
"description",
"extensions",
"type",
"value",
"deprecated"
];
/**
* Merge all configs into a single config
*/
function mergeConfigs(configs) {
const userConfig = configs.at(-1);
const pluginHooks = userConfig.plugins ?? [];
if (userConfig.hooks) pluginHooks.push({
name: BAMBOO_CONFIG_NAME,
hooks: userConfig.hooks
});
const reversed = Array.from(configs).reverse();
const withoutEmpty = compact(assign({
conditions: mergeExtensions(reversed.map((config) => config.conditions ?? {})),
theme: mergeExtensions(reversed.map((config) => config.theme ?? {})),
patterns: mergeExtensions(reversed.map((config) => config.patterns ?? {})),
utilities: mergeExtensions(reversed.map((config) => config.utilities ?? {})),
globalCss: mergeExtensions(reversed.map((config) => config.globalCss ?? {})),
globalVars: mergeExtensions(reversed.map((config) => config.globalVars ?? {})),
globalFontface: mergeExtensions(reversed.map((config) => config.globalFontface ?? {})),
globalPositionTry: mergeExtensions(reversed.map((config) => config.globalPositionTry ?? {})),
staticCss: mergeExtensions(reversed.map((config) => config.staticCss ?? {})),
themes: mergeExtensions(reversed.map((config) => config.themes ?? {})),
hooks: mergeHooks(pluginHooks)
}, ...reversed));
/**
* Properly merge tokens between flat/nested forms by setting the flat form as the default
* preset:
* ```
* tokens: {
* black: {
* value: "black"
* }
* }
* // color: "black"
* ```
*
* config:
* ```
* tokens: {
* black: {
* 0: { value: "black" },
* 10: { value: "black/10" },
* 20: { value: "black/20" },
* // ...
* }
* }
*
* // color: "black.20"
* ```
*/
if (withoutEmpty.theme?.tokens) walkObject(withoutEmpty.theme.tokens, (args) => args, { stop(token) {
if (!isValidToken(token)) return false;
if (Object.keys(token).filter((k) => !tokenKeys.includes(k)).length > 0) {
token.DEFAULT ||= {};
tokenKeys.forEach((key) => {
if (token[key] == null) return;
token.DEFAULT[key] ||= token[key];
delete token[key];
});
}
return true;
} });
return withoutEmpty;
}
//#endregion
export { isValidToken as a, isTokenReference as i, formatPath as n, serializeTokenValue as o, getReferences as r, mergeHooks as s, mergeConfigs as t };
import { BambooPlugin, Config } from "@bamboocss/types";
//#region src/merge-hooks.d.ts
declare const mergeHooks: (plugins: BambooPlugin[]) => BambooHooks;
//#endregion
//#region src/merge-config.d.ts
type Extendable<T> = T & {
extend?: T;
};
type ExtendableConfig = Extendable<Config>;
/**
* Merge all configs into a single config
*/
declare function mergeConfigs(configs: ExtendableConfig[]): any;
//#endregion
export { mergeHooks as n, mergeConfigs as t };
import { BambooPlugin, Config } from "@bamboocss/types";
//#region src/merge-hooks.d.ts
declare const mergeHooks: (plugins: BambooPlugin[]) => BambooHooks;
//#endregion
//#region src/merge-config.d.ts
type Extendable<T> = T & {
extend?: T;
};
type ExtendableConfig = Extendable<Config>;
/**
* Merge all configs into a single config
*/
declare function mergeConfigs(configs: ExtendableConfig[]): any;
//#endregion
export { mergeHooks as n, mergeConfigs as t };
//#region src/ts-config-paths.d.ts
interface PathMapping {
pattern: RegExp;
paths: string[];
}
/**
* @see https://github.com/aleclarson/vite-tsconfig-paths/blob/e8f0acf7adfcfbf77edbe937f64b4e5d39557ad0/src/mappings.ts
*/
declare function convertTsPathsToRegexes(paths: Record<string, string[]>, baseUrl: string): PathMapping[];
//#endregion
export { convertTsPathsToRegexes as n, PathMapping as t };
//#region src/ts-config-paths.d.ts
interface PathMapping {
pattern: RegExp;
paths: string[];
}
/**
* @see https://github.com/aleclarson/vite-tsconfig-paths/blob/e8f0acf7adfcfbf77edbe937f64b4e5d39557ad0/src/mappings.ts
*/
declare function convertTsPathsToRegexes(paths: Record<string, string[]>, baseUrl: string): PathMapping[];
//#endregion
export { convertTsPathsToRegexes as n, PathMapping as t };