@bamboocss/config 1.11.1 → 1.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/diff-config-Co_3mDXE.cjs +197 -0
- package/dist/diff-config-KDQWMnQN.mjs +163 -0
- package/dist/diff-config.cjs +3 -0
- package/dist/diff-config.d.cts +10 -0
- package/dist/diff-config.d.mts +10 -0
- package/dist/diff-config.mjs +2 -6
- package/dist/index.cjs +575 -0
- package/dist/index.d.cts +84 -0
- package/dist/index.d.mts +84 -0
- package/dist/index.mjs +520 -589
- package/dist/merge-config-CcNpHJit.cjs +312 -0
- package/dist/merge-config-DI__LOWx.mjs +270 -0
- package/dist/merge-config-DVOlBQJY.d.cts +16 -0
- package/dist/merge-config-oEiBYbfB.d.mts +16 -0
- package/dist/merge-config.cjs +4 -0
- package/dist/merge-config.d.cts +2 -0
- package/dist/merge-config.d.mts +2 -0
- package/dist/merge-config.mjs +2 -8
- package/dist/resolve-ts-path-pattern.cjs +21 -0
- package/dist/resolve-ts-path-pattern.d.cts +9 -0
- package/dist/resolve-ts-path-pattern.d.mts +9 -0
- package/dist/resolve-ts-path-pattern.mjs +18 -5
- package/dist/ts-config-paths-CvGId8kq.d.mts +11 -0
- package/dist/ts-config-paths-wVx39QZ0.d.cts +11 -0
- package/package.json +19 -19
- package/dist/chunk-6TQW6KOI.mjs +0 -154
- package/dist/chunk-RIBK22OM.mjs +0 -265
- package/dist/chunk-RPIVZP2I.mjs +0 -22
- package/dist/diff-config.js +0 -188
- package/dist/index.js +0 -1086
- package/dist/merge-config.js +0 -259
- package/dist/resolve-ts-path-pattern.js +0 -46
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,575 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_diff_config = require("./diff-config-Co_3mDXE.cjs");
|
|
3
|
+
const require_resolve_ts_path_pattern = require("./resolve-ts-path-pattern.cjs");
|
|
4
|
+
const require_merge_config = require("./merge-config-CcNpHJit.cjs");
|
|
5
|
+
let _bamboocss_logger = require("@bamboocss/logger");
|
|
6
|
+
let _bamboocss_shared = require("@bamboocss/shared");
|
|
7
|
+
let bundle_n_require = require("bundle-n-require");
|
|
8
|
+
let escalade_sync = require("escalade/sync");
|
|
9
|
+
escalade_sync = require_diff_config.__toESM(escalade_sync);
|
|
10
|
+
let path = require("path");
|
|
11
|
+
path = require_diff_config.__toESM(path);
|
|
12
|
+
let fs = require("fs");
|
|
13
|
+
fs = require_diff_config.__toESM(fs);
|
|
14
|
+
let typescript = require("typescript");
|
|
15
|
+
typescript = require_diff_config.__toESM(typescript);
|
|
16
|
+
let _bamboocss_preset_base = require("@bamboocss/preset-base");
|
|
17
|
+
let _bamboocss_preset_bamboo = require("@bamboocss/preset-bamboo");
|
|
18
|
+
//#region src/is-bamboo-config.ts
|
|
19
|
+
const configName = "bamboo";
|
|
20
|
+
const bambooConfigFiles = new Set([
|
|
21
|
+
`${configName}.config.ts`,
|
|
22
|
+
`${configName}.config.js`,
|
|
23
|
+
`${configName}.config.mts`,
|
|
24
|
+
`${configName}.config.mjs`,
|
|
25
|
+
`${configName}.config.cts`,
|
|
26
|
+
`${configName}.config.cjs`
|
|
27
|
+
]);
|
|
28
|
+
const isBambooConfig = (file) => bambooConfigFiles.has(file);
|
|
29
|
+
//#endregion
|
|
30
|
+
//#region src/find-config.ts
|
|
31
|
+
function findConfig(options) {
|
|
32
|
+
const { cwd = process.cwd(), file } = options;
|
|
33
|
+
if (file) return (0, path.resolve)(cwd, file);
|
|
34
|
+
const configPath = (0, escalade_sync.default)(cwd, (_dir, paths) => paths.find(isBambooConfig));
|
|
35
|
+
if (!configPath) throw new _bamboocss_shared.BambooError("CONFIG_NOT_FOUND", `Cannot find config file \`bamboo.config.{ts,js,mjs,mts}\`. Did you forget to run \`bamboo init\`?`);
|
|
36
|
+
return configPath;
|
|
37
|
+
}
|
|
38
|
+
//#endregion
|
|
39
|
+
//#region src/bundle-config.ts
|
|
40
|
+
async function bundle(filepath, cwd) {
|
|
41
|
+
const { mod, dependencies } = await (0, bundle_n_require.bundleNRequire)(filepath, {
|
|
42
|
+
cwd,
|
|
43
|
+
interopDefault: true
|
|
44
|
+
});
|
|
45
|
+
return {
|
|
46
|
+
config: mod?.default ?? mod,
|
|
47
|
+
dependencies
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
async function bundleConfig(options) {
|
|
51
|
+
const { cwd, file } = options;
|
|
52
|
+
const filePath = findConfig({
|
|
53
|
+
cwd,
|
|
54
|
+
file
|
|
55
|
+
});
|
|
56
|
+
_bamboocss_logger.logger.debug("config:path", filePath);
|
|
57
|
+
const result = await bundle(filePath, cwd);
|
|
58
|
+
if (typeof result.config !== "object") throw new _bamboocss_shared.BambooError("CONFIG_ERROR", `💥 Config must export or return an object.`);
|
|
59
|
+
result.config.outdir ??= "styled-system";
|
|
60
|
+
result.config.validation ??= "warn";
|
|
61
|
+
return {
|
|
62
|
+
...result,
|
|
63
|
+
config: result.config,
|
|
64
|
+
path: filePath
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
//#endregion
|
|
68
|
+
//#region src/ts-config-paths.ts
|
|
69
|
+
/**
|
|
70
|
+
* @see https://github.com/aleclarson/vite-tsconfig-paths/blob/e8f0acf7adfcfbf77edbe937f64b4e5d39557ad0/src/mappings.ts
|
|
71
|
+
*/
|
|
72
|
+
function convertTsPathsToRegexes(paths, baseUrl) {
|
|
73
|
+
const sortedPatterns = Object.keys(paths).sort((a, b) => getPrefixLength(b) - getPrefixLength(a));
|
|
74
|
+
const resolved = [];
|
|
75
|
+
for (let pattern of sortedPatterns) {
|
|
76
|
+
const relativePaths = paths[pattern];
|
|
77
|
+
pattern = escapeStringRegexp(pattern).replace(/\*/g, "(.+)");
|
|
78
|
+
resolved.push({
|
|
79
|
+
pattern: new RegExp("^" + pattern + "$"),
|
|
80
|
+
paths: relativePaths.map((relativePath) => (0, path.resolve)(baseUrl, relativePath))
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
return resolved;
|
|
84
|
+
}
|
|
85
|
+
function getPrefixLength(pattern) {
|
|
86
|
+
const prefixLength = pattern.indexOf("*");
|
|
87
|
+
return pattern.substr(0, prefixLength).length;
|
|
88
|
+
}
|
|
89
|
+
function escapeStringRegexp(string) {
|
|
90
|
+
return string.replace(/[|\\{}()[\]^$+?.]/g, "\\$&").replace(/-/g, "\\x2d");
|
|
91
|
+
}
|
|
92
|
+
//#endregion
|
|
93
|
+
//#region src/get-mod-deps.ts
|
|
94
|
+
const jsExtensions = [
|
|
95
|
+
".js",
|
|
96
|
+
".cjs",
|
|
97
|
+
".mjs"
|
|
98
|
+
];
|
|
99
|
+
const jsResolutionOrder = [
|
|
100
|
+
"",
|
|
101
|
+
".js",
|
|
102
|
+
".cjs",
|
|
103
|
+
".mjs",
|
|
104
|
+
".ts",
|
|
105
|
+
".cts",
|
|
106
|
+
".mts",
|
|
107
|
+
".jsx",
|
|
108
|
+
".tsx"
|
|
109
|
+
];
|
|
110
|
+
const tsResolutionOrder = [
|
|
111
|
+
"",
|
|
112
|
+
".ts",
|
|
113
|
+
".cts",
|
|
114
|
+
".mts",
|
|
115
|
+
".tsx",
|
|
116
|
+
".js",
|
|
117
|
+
".cjs",
|
|
118
|
+
".mjs",
|
|
119
|
+
".jsx"
|
|
120
|
+
];
|
|
121
|
+
function resolveWithExtension(file, extensions) {
|
|
122
|
+
for (const ext of extensions) {
|
|
123
|
+
const full = `${file}${ext}`;
|
|
124
|
+
if (fs.default.existsSync(full) && fs.default.statSync(full).isFile()) return full;
|
|
125
|
+
}
|
|
126
|
+
for (const ext of extensions) {
|
|
127
|
+
const full = `${file}/index${ext}`;
|
|
128
|
+
if (fs.default.existsSync(full)) return full;
|
|
129
|
+
}
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
const importRegex = /import[\s\S]*?['"](.{3,}?)['"]/gi;
|
|
133
|
+
const importFromRegex = /import[\s\S]*from[\s\S]*?['"](.{3,}?)['"]/gi;
|
|
134
|
+
const requireRegex = /require\(['"`](.+)['"`]\)/gi;
|
|
135
|
+
const exportRegex = /export[\s\S]*from[\s\S]*?['"](.{3,}?)['"]/gi;
|
|
136
|
+
function getDeps(opts, fromAlias) {
|
|
137
|
+
const { filename, seen } = opts;
|
|
138
|
+
const { moduleResolution: _, ...compilerOptions } = opts.compilerOptions ?? {};
|
|
139
|
+
const absoluteFile = resolveWithExtension(path.default.resolve(opts.cwd, filename), jsExtensions.includes(opts.ext) ? jsResolutionOrder : tsResolutionOrder);
|
|
140
|
+
if (absoluteFile === null) return;
|
|
141
|
+
if (fromAlias) opts.foundModuleAliases.set(fromAlias, absoluteFile);
|
|
142
|
+
if (seen.size > 1 && seen.has(absoluteFile)) return;
|
|
143
|
+
seen.add(absoluteFile);
|
|
144
|
+
const contents = fs.default.readFileSync(absoluteFile, "utf-8");
|
|
145
|
+
const fileDeps = [
|
|
146
|
+
...contents.matchAll(importRegex),
|
|
147
|
+
...contents.matchAll(importFromRegex),
|
|
148
|
+
...contents.matchAll(requireRegex),
|
|
149
|
+
...contents.matchAll(exportRegex)
|
|
150
|
+
];
|
|
151
|
+
if (!fileDeps.length) return;
|
|
152
|
+
const nextOpts = {
|
|
153
|
+
cwd: path.default.dirname(absoluteFile),
|
|
154
|
+
ext: path.default.extname(absoluteFile),
|
|
155
|
+
seen,
|
|
156
|
+
baseUrl: opts.baseUrl,
|
|
157
|
+
pathMappings: opts.pathMappings,
|
|
158
|
+
foundModuleAliases: opts.foundModuleAliases
|
|
159
|
+
};
|
|
160
|
+
fileDeps.forEach((match) => {
|
|
161
|
+
const mod = match[1];
|
|
162
|
+
if (mod[0] === ".") {
|
|
163
|
+
getDeps(Object.assign({}, nextOpts, { filename: mod }));
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
try {
|
|
167
|
+
const found = typescript.default.resolveModuleName(mod, absoluteFile, compilerOptions, typescript.default.sys).resolvedModule;
|
|
168
|
+
if (found && found.extension.endsWith("ts")) {
|
|
169
|
+
getDeps(Object.assign({}, nextOpts, { filename: found.resolvedFileName }));
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
if (!opts.pathMappings) return;
|
|
173
|
+
const filename = require_resolve_ts_path_pattern.resolveTsPathPattern(opts.pathMappings, mod);
|
|
174
|
+
if (!filename) return;
|
|
175
|
+
getDeps(Object.assign({}, nextOpts, { filename }), mod);
|
|
176
|
+
} catch {}
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
function getConfigDependencies(filePath, tsOptions = { pathMappings: [] }, compilerOptions) {
|
|
180
|
+
if (filePath === null) return {
|
|
181
|
+
deps: /* @__PURE__ */ new Set(),
|
|
182
|
+
aliases: /* @__PURE__ */ new Map()
|
|
183
|
+
};
|
|
184
|
+
const foundModuleAliases = /* @__PURE__ */ new Map();
|
|
185
|
+
const deps = /* @__PURE__ */ new Set();
|
|
186
|
+
deps.add(filePath);
|
|
187
|
+
getDeps({
|
|
188
|
+
filename: filePath,
|
|
189
|
+
ext: path.default.extname(filePath),
|
|
190
|
+
cwd: path.default.dirname(filePath),
|
|
191
|
+
seen: deps,
|
|
192
|
+
baseUrl: tsOptions.baseUrl,
|
|
193
|
+
pathMappings: tsOptions.pathMappings ?? [],
|
|
194
|
+
foundModuleAliases,
|
|
195
|
+
compilerOptions
|
|
196
|
+
});
|
|
197
|
+
return {
|
|
198
|
+
deps,
|
|
199
|
+
aliases: foundModuleAliases
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
//#endregion
|
|
203
|
+
//#region src/get-resolved-config.ts
|
|
204
|
+
const hookUtils$1 = {
|
|
205
|
+
omit: _bamboocss_shared.omit,
|
|
206
|
+
pick: _bamboocss_shared.pick,
|
|
207
|
+
traverse: _bamboocss_shared.traverse
|
|
208
|
+
};
|
|
209
|
+
/**
|
|
210
|
+
* Recursively merge all presets into a single config (depth-first using stack)
|
|
211
|
+
*/
|
|
212
|
+
async function getResolvedConfig(config, cwd, hooks) {
|
|
213
|
+
const stack = [config];
|
|
214
|
+
const configs = [];
|
|
215
|
+
while (stack.length > 0) {
|
|
216
|
+
const current = stack.pop();
|
|
217
|
+
const subPresets = current.presets ?? [];
|
|
218
|
+
for (const subPreset of subPresets) {
|
|
219
|
+
let presetConfig;
|
|
220
|
+
let presetName;
|
|
221
|
+
if (typeof subPreset === "string") {
|
|
222
|
+
presetConfig = (await bundle(subPreset, cwd)).config;
|
|
223
|
+
presetName = subPreset;
|
|
224
|
+
} else {
|
|
225
|
+
presetConfig = await subPreset;
|
|
226
|
+
presetName = presetConfig.name || "unknown-preset";
|
|
227
|
+
}
|
|
228
|
+
if (hooks?.["preset:resolved"]) {
|
|
229
|
+
const resolvedPreset = await hooks["preset:resolved"]({
|
|
230
|
+
preset: presetConfig,
|
|
231
|
+
name: presetName,
|
|
232
|
+
utils: hookUtils$1
|
|
233
|
+
});
|
|
234
|
+
if (resolvedPreset !== void 0) presetConfig = resolvedPreset;
|
|
235
|
+
}
|
|
236
|
+
stack.push(presetConfig);
|
|
237
|
+
}
|
|
238
|
+
configs.unshift(current);
|
|
239
|
+
}
|
|
240
|
+
const merged = require_merge_config.mergeConfigs(configs);
|
|
241
|
+
merged.presets = configs.slice(0, -1);
|
|
242
|
+
return merged;
|
|
243
|
+
}
|
|
244
|
+
//#endregion
|
|
245
|
+
//#region src/bundled-preset.ts
|
|
246
|
+
const bundledPresets = {
|
|
247
|
+
"@bamboocss/preset-base": _bamboocss_preset_base.preset,
|
|
248
|
+
"@bamboocss/preset-bamboo": _bamboocss_preset_bamboo.preset,
|
|
249
|
+
"@bamboocss/dev/presets": _bamboocss_preset_bamboo.preset
|
|
250
|
+
};
|
|
251
|
+
const bundledPresetsNames = Object.keys(bundledPresets);
|
|
252
|
+
const isBundledPreset = (preset) => bundledPresetsNames.includes(preset);
|
|
253
|
+
const getBundledPreset = (preset) => {
|
|
254
|
+
return typeof preset === "string" && isBundledPreset(preset) ? bundledPresets[preset] : void 0;
|
|
255
|
+
};
|
|
256
|
+
//#endregion
|
|
257
|
+
//#region src/validation/validate-artifact.ts
|
|
258
|
+
const validateArtifactNames = (names, addError) => {
|
|
259
|
+
names.recipes.forEach((recipeName) => {
|
|
260
|
+
if (names.slotRecipes.has(recipeName)) addError("recipes", `This recipe name is already used in \`theme.slotRecipes\`: ${recipeName}`);
|
|
261
|
+
if (names.patterns.has(recipeName)) addError("recipes", `This recipe name is already used in \`patterns\`: \`${recipeName}\``);
|
|
262
|
+
});
|
|
263
|
+
names.slotRecipes.forEach((recipeName) => {
|
|
264
|
+
if (names.patterns.has(recipeName)) addError("recipes", `This recipe name is already used in \`patterns\`: ${recipeName}`);
|
|
265
|
+
});
|
|
266
|
+
};
|
|
267
|
+
//#endregion
|
|
268
|
+
//#region src/validation/validate-breakpoints.ts
|
|
269
|
+
const validateBreakpoints = (breakpoints, addError) => {
|
|
270
|
+
if (!breakpoints) return;
|
|
271
|
+
const units = /* @__PURE__ */ new Set();
|
|
272
|
+
const values = Object.values(breakpoints);
|
|
273
|
+
for (const value of values) {
|
|
274
|
+
const unit = (0, _bamboocss_shared.getUnit)(value) ?? "px";
|
|
275
|
+
units.add(unit);
|
|
276
|
+
}
|
|
277
|
+
if (units.size > 1) addError("breakpoints", `All breakpoints must use the same unit: \`${values.join(", ")}\``);
|
|
278
|
+
};
|
|
279
|
+
//#endregion
|
|
280
|
+
//#region src/validation/validate-condition.ts
|
|
281
|
+
const validateObjectCondition = (obj, addError) => {
|
|
282
|
+
let hasSlot = false;
|
|
283
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
284
|
+
if (!key.startsWith("@") && !key.includes("&")) addError("conditions", `Selectors should contain the \`&\` character: \`${key}\``);
|
|
285
|
+
if (value === "@slot") {
|
|
286
|
+
hasSlot = true;
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
if (typeof value === "string") {
|
|
290
|
+
addError("conditions", `Object condition leaves must be the literal string \`'@slot'\`, got \`${JSON.stringify(value)}\` at \`${key}\``);
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
if (typeof value === "object" && value !== null) {
|
|
294
|
+
if (validateObjectCondition(value, addError).hasSlot) hasSlot = true;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return { hasSlot };
|
|
298
|
+
};
|
|
299
|
+
const validateConditions = (conditions, addError) => {
|
|
300
|
+
if (!conditions) return;
|
|
301
|
+
Object.values(conditions).forEach((condition) => {
|
|
302
|
+
if ((0, _bamboocss_shared.isString)(condition)) {
|
|
303
|
+
if (!condition.startsWith("@") && !condition.includes("&")) addError("conditions", `Selectors should contain the \`&\` character: \`${condition}\``);
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
if (Array.isArray(condition)) {
|
|
307
|
+
condition.forEach((c) => {
|
|
308
|
+
if (!c.startsWith("@") && !c.includes("&")) addError("conditions", `Selectors should contain the \`&\` character: \`${c}\``);
|
|
309
|
+
});
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
312
|
+
const { hasSlot } = validateObjectCondition(condition, addError);
|
|
313
|
+
if (!hasSlot) addError("conditions", `Object conditions must contain at least one \`'@slot'\` marker`);
|
|
314
|
+
});
|
|
315
|
+
};
|
|
316
|
+
//#endregion
|
|
317
|
+
//#region src/validation/validate-patterns.ts
|
|
318
|
+
const validatePatterns = (patterns, names) => {
|
|
319
|
+
if (!patterns) return;
|
|
320
|
+
Object.keys(patterns).forEach((patternName) => {
|
|
321
|
+
names.patterns.add(patternName);
|
|
322
|
+
});
|
|
323
|
+
};
|
|
324
|
+
//#endregion
|
|
325
|
+
//#region src/validation/validate-recipes.ts
|
|
326
|
+
const validateRecipes = (options) => {
|
|
327
|
+
const { config: { theme }, artifacts } = options;
|
|
328
|
+
if (!theme) return;
|
|
329
|
+
if (theme.recipes) Object.keys(theme.recipes).forEach((recipeName) => {
|
|
330
|
+
artifacts.recipes.add(recipeName);
|
|
331
|
+
});
|
|
332
|
+
if (theme.slotRecipes) Object.keys(theme.slotRecipes).forEach((recipeName) => {
|
|
333
|
+
artifacts.slotRecipes.add(recipeName);
|
|
334
|
+
});
|
|
335
|
+
return artifacts;
|
|
336
|
+
};
|
|
337
|
+
//#endregion
|
|
338
|
+
//#region src/validation/validate-token-references.ts
|
|
339
|
+
const validateTokenReferences = (props) => {
|
|
340
|
+
const { valueAtPath, refsByPath, addError, typeByPath } = props;
|
|
341
|
+
refsByPath.forEach((refs, path) => {
|
|
342
|
+
if (refs.has(path)) addError("tokens", `Self token reference: \`${path}\``);
|
|
343
|
+
const stack = [path];
|
|
344
|
+
while (stack.length > 0) {
|
|
345
|
+
let currentPath = stack.pop();
|
|
346
|
+
if (currentPath.includes("/")) {
|
|
347
|
+
const [tokenPath] = currentPath.split("/");
|
|
348
|
+
currentPath = tokenPath;
|
|
349
|
+
}
|
|
350
|
+
const value = valueAtPath.get(currentPath);
|
|
351
|
+
if (!value) {
|
|
352
|
+
const configKey = typeByPath.get(path);
|
|
353
|
+
addError("tokens", `Missing token: \`${currentPath}\` used in \`theme.${configKey}.${path}\``);
|
|
354
|
+
}
|
|
355
|
+
if (require_merge_config.isTokenReference(value) && !refsByPath.has(value)) addError("tokens", `Unknown token reference: \`${currentPath}\` used in \`${value}\``);
|
|
356
|
+
const deps = refsByPath.get(currentPath);
|
|
357
|
+
if (!deps) continue;
|
|
358
|
+
for (const transitiveDep of deps) {
|
|
359
|
+
if (path === transitiveDep) {
|
|
360
|
+
addError("tokens", `Circular token reference: \`${transitiveDep}\` -> \`${currentPath}\` -> ... -> \`${path}\``);
|
|
361
|
+
break;
|
|
362
|
+
}
|
|
363
|
+
stack.push(transitiveDep);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
};
|
|
368
|
+
//#endregion
|
|
369
|
+
//#region src/validation/validate-tokens.ts
|
|
370
|
+
const validateTokens = (options) => {
|
|
371
|
+
const { config: { theme }, tokens, addError } = options;
|
|
372
|
+
if (!theme) return;
|
|
373
|
+
const { tokenNames, semanticTokenNames, valueAtPath, refsByPath, typeByPath } = tokens;
|
|
374
|
+
if (theme.tokens) {
|
|
375
|
+
const tokenPaths = /* @__PURE__ */ new Set();
|
|
376
|
+
(0, _bamboocss_shared.walkObject)(theme.tokens, (value, paths) => {
|
|
377
|
+
const path = paths.join(".");
|
|
378
|
+
tokenNames.add(path);
|
|
379
|
+
tokenPaths.add(path);
|
|
380
|
+
valueAtPath.set(path, value);
|
|
381
|
+
if (path.includes("DEFAULT")) valueAtPath.set(path.replace(".DEFAULT", ""), value);
|
|
382
|
+
}, { stop: require_merge_config.isValidToken });
|
|
383
|
+
tokenPaths.forEach((path) => {
|
|
384
|
+
const itemValue = valueAtPath.get(path);
|
|
385
|
+
const formattedPath = require_merge_config.formatPath(path);
|
|
386
|
+
typeByPath.set(formattedPath, "tokens");
|
|
387
|
+
if (!require_merge_config.isValidToken(itemValue)) {
|
|
388
|
+
addError("tokens", `Token must contain 'value': \`theme.tokens.${formattedPath}\``);
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
if (path.includes(" ")) {
|
|
392
|
+
addError("tokens", `Token key must not contain spaces: \`theme.tokens.${formattedPath}\``);
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
const valueStr = require_merge_config.serializeTokenValue(itemValue.value || itemValue);
|
|
396
|
+
if (require_merge_config.isTokenReference(valueStr)) refsByPath.set(formattedPath, /* @__PURE__ */ new Set([]));
|
|
397
|
+
const references = refsByPath.get(formattedPath);
|
|
398
|
+
if (!references) return;
|
|
399
|
+
require_merge_config.getReferences(valueStr).forEach((reference) => {
|
|
400
|
+
references.add(reference);
|
|
401
|
+
});
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
if (theme.semanticTokens) {
|
|
405
|
+
const tokenPaths = /* @__PURE__ */ new Set();
|
|
406
|
+
(0, _bamboocss_shared.walkObject)(theme.semanticTokens, (value, paths) => {
|
|
407
|
+
const path = paths.join(".");
|
|
408
|
+
semanticTokenNames.add(path);
|
|
409
|
+
valueAtPath.set(path, value);
|
|
410
|
+
tokenPaths.add(path);
|
|
411
|
+
if (path.includes("DEFAULT")) valueAtPath.set(path.replace(".DEFAULT", ""), value);
|
|
412
|
+
if (!require_merge_config.isValidToken(value)) return;
|
|
413
|
+
(0, _bamboocss_shared.walkObject)(value, (itemValue, paths) => {
|
|
414
|
+
const valuePath = paths.join(".");
|
|
415
|
+
const formattedPath = require_merge_config.formatPath(path);
|
|
416
|
+
typeByPath.set(formattedPath, "semanticTokens");
|
|
417
|
+
const fullPath = formattedPath + "." + paths.join(".");
|
|
418
|
+
if (valuePath.includes("value.value")) addError("tokens", `You used \`value\` twice resulting in an invalid token \`theme.tokens.${fullPath}\``);
|
|
419
|
+
const valueStr = require_merge_config.serializeTokenValue(itemValue.value || itemValue);
|
|
420
|
+
if (require_merge_config.isTokenReference(valueStr)) {
|
|
421
|
+
if (!refsByPath.has(formattedPath)) refsByPath.set(formattedPath, /* @__PURE__ */ new Set());
|
|
422
|
+
const references = refsByPath.get(formattedPath);
|
|
423
|
+
if (!references) return;
|
|
424
|
+
require_merge_config.getReferences(valueStr).forEach((reference) => {
|
|
425
|
+
references.add(reference);
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
}, { stop: require_merge_config.isValidToken });
|
|
430
|
+
tokenPaths.forEach((path) => {
|
|
431
|
+
const formattedPath = require_merge_config.formatPath(path);
|
|
432
|
+
const value = valueAtPath.get(path);
|
|
433
|
+
if (path.includes(" ")) {
|
|
434
|
+
addError("tokens", `Token key must not contain spaces: \`theme.tokens.${formattedPath}\``);
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
if (!(0, _bamboocss_shared.isObject)(value) && !path.includes("value")) addError("tokens", `Token must contain 'value': \`theme.semanticTokens.${formattedPath}\``);
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
validateTokenReferences({
|
|
441
|
+
valueAtPath,
|
|
442
|
+
refsByPath,
|
|
443
|
+
addError,
|
|
444
|
+
typeByPath
|
|
445
|
+
});
|
|
446
|
+
};
|
|
447
|
+
//#endregion
|
|
448
|
+
//#region src/validate-config.ts
|
|
449
|
+
/**
|
|
450
|
+
* Validate the config
|
|
451
|
+
* - Check for duplicate between token & semanticTokens names
|
|
452
|
+
* - Check for duplicate between recipes/patterns/slots names
|
|
453
|
+
* - Check for token / semanticTokens paths (must end/contain 'value')
|
|
454
|
+
* - Check for self/circular token references
|
|
455
|
+
* - Check for missing tokens references
|
|
456
|
+
* - Check for conditions selectors (must contain '&')
|
|
457
|
+
* - Check for breakpoints units (must be the same)
|
|
458
|
+
*/
|
|
459
|
+
const validateConfig = (config) => {
|
|
460
|
+
if (config.validation === "none") return;
|
|
461
|
+
const warnings = /* @__PURE__ */ new Set();
|
|
462
|
+
const addError = (scope, message) => {
|
|
463
|
+
warnings.add(`[${scope}] ` + message);
|
|
464
|
+
};
|
|
465
|
+
validateBreakpoints(config.theme?.breakpoints, addError);
|
|
466
|
+
validateConditions(config.conditions, addError);
|
|
467
|
+
const artifacts = {
|
|
468
|
+
recipes: /* @__PURE__ */ new Set(),
|
|
469
|
+
slotRecipes: /* @__PURE__ */ new Set(),
|
|
470
|
+
patterns: /* @__PURE__ */ new Set()
|
|
471
|
+
};
|
|
472
|
+
const tokens = {
|
|
473
|
+
tokenNames: /* @__PURE__ */ new Set(),
|
|
474
|
+
semanticTokenNames: /* @__PURE__ */ new Set(),
|
|
475
|
+
valueAtPath: /* @__PURE__ */ new Map(),
|
|
476
|
+
refsByPath: /* @__PURE__ */ new Map(),
|
|
477
|
+
typeByPath: /* @__PURE__ */ new Map()
|
|
478
|
+
};
|
|
479
|
+
if (config.theme) {
|
|
480
|
+
validateTokens({
|
|
481
|
+
config,
|
|
482
|
+
tokens,
|
|
483
|
+
addError
|
|
484
|
+
});
|
|
485
|
+
validateRecipes({
|
|
486
|
+
config,
|
|
487
|
+
tokens,
|
|
488
|
+
artifacts,
|
|
489
|
+
addError
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
validatePatterns(config.patterns, artifacts);
|
|
493
|
+
validateArtifactNames(artifacts, addError);
|
|
494
|
+
if (warnings.size) {
|
|
495
|
+
const errors = `⚠️ Invalid config:\n${Array.from(warnings).map((err) => "- " + err).join("\n")}\n`;
|
|
496
|
+
if (config.validation === "error") throw new _bamboocss_shared.BambooError("CONFIG_ERROR", errors);
|
|
497
|
+
_bamboocss_logger.logger.warn("config", errors);
|
|
498
|
+
return warnings;
|
|
499
|
+
}
|
|
500
|
+
};
|
|
501
|
+
//#endregion
|
|
502
|
+
//#region src/resolve-config.ts
|
|
503
|
+
const hookUtils = {
|
|
504
|
+
omit: _bamboocss_shared.omit,
|
|
505
|
+
pick: _bamboocss_shared.pick,
|
|
506
|
+
traverse: _bamboocss_shared.traverse
|
|
507
|
+
};
|
|
508
|
+
/**
|
|
509
|
+
* Resolve the final config (including presets)
|
|
510
|
+
* @bamboocss/preset-base: ALWAYS included if NOT using eject: true
|
|
511
|
+
* @bamboocss/preset-bamboo: only included by default if no presets
|
|
512
|
+
*/
|
|
513
|
+
async function resolveConfig(result, cwd) {
|
|
514
|
+
const presets = /* @__PURE__ */ new Set();
|
|
515
|
+
if (!result.config.eject) presets.add(_bamboocss_preset_base.preset);
|
|
516
|
+
if (result.config.presets) result.config.presets.forEach((preset) => {
|
|
517
|
+
presets.add(getBundledPreset(preset) ?? preset);
|
|
518
|
+
});
|
|
519
|
+
else if (!result.config.eject) presets.add(_bamboocss_preset_bamboo.preset);
|
|
520
|
+
result.config.presets = Array.from(presets);
|
|
521
|
+
const userConfig = result.config;
|
|
522
|
+
const pluginHooks = userConfig.plugins ?? [];
|
|
523
|
+
if (userConfig.hooks) pluginHooks.push({
|
|
524
|
+
name: _bamboocss_shared.BAMBOO_CONFIG_NAME,
|
|
525
|
+
hooks: userConfig.hooks
|
|
526
|
+
});
|
|
527
|
+
const earlyHooks = require_merge_config.mergeHooks(pluginHooks);
|
|
528
|
+
const mergedConfig = await getResolvedConfig(result.config, cwd, earlyHooks);
|
|
529
|
+
const hooks = mergedConfig.hooks ?? {};
|
|
530
|
+
if (mergedConfig.logLevel) _bamboocss_logger.logger.level = mergedConfig.logLevel;
|
|
531
|
+
validateConfig(mergedConfig);
|
|
532
|
+
const loadConfigResult = {
|
|
533
|
+
...result,
|
|
534
|
+
config: mergedConfig
|
|
535
|
+
};
|
|
536
|
+
if (hooks["config:resolved"]) {
|
|
537
|
+
const result = await hooks["config:resolved"]({
|
|
538
|
+
config: loadConfigResult.config,
|
|
539
|
+
path: loadConfigResult.path,
|
|
540
|
+
dependencies: loadConfigResult.dependencies,
|
|
541
|
+
utils: hookUtils
|
|
542
|
+
});
|
|
543
|
+
if (result) loadConfigResult.config = result;
|
|
544
|
+
}
|
|
545
|
+
const serialized = (0, _bamboocss_shared.stringifyJson)(Object.assign({}, loadConfigResult.config, {
|
|
546
|
+
name: _bamboocss_shared.BAMBOO_CONFIG_NAME,
|
|
547
|
+
presets: []
|
|
548
|
+
}));
|
|
549
|
+
const deserialize = () => (0, _bamboocss_shared.parseJson)(serialized);
|
|
550
|
+
return {
|
|
551
|
+
...loadConfigResult,
|
|
552
|
+
serialized,
|
|
553
|
+
deserialize,
|
|
554
|
+
hooks
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
//#endregion
|
|
558
|
+
//#region src/load-config.ts
|
|
559
|
+
/**
|
|
560
|
+
* Find, load and resolve the final config (including presets)
|
|
561
|
+
*/
|
|
562
|
+
async function loadConfig(options) {
|
|
563
|
+
return resolveConfig(await bundleConfig(options), options.cwd);
|
|
564
|
+
}
|
|
565
|
+
//#endregion
|
|
566
|
+
exports.bundleConfig = bundleConfig;
|
|
567
|
+
exports.convertTsPathsToRegexes = convertTsPathsToRegexes;
|
|
568
|
+
exports.diffConfigs = require_diff_config.diffConfigs;
|
|
569
|
+
exports.findConfig = findConfig;
|
|
570
|
+
exports.getConfigDependencies = getConfigDependencies;
|
|
571
|
+
exports.getResolvedConfig = getResolvedConfig;
|
|
572
|
+
exports.loadConfig = loadConfig;
|
|
573
|
+
exports.mergeConfigs = require_merge_config.mergeConfigs;
|
|
574
|
+
exports.mergeHooks = require_merge_config.mergeHooks;
|
|
575
|
+
exports.resolveConfig = resolveConfig;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { diffConfigs } from "./diff-config.cjs";
|
|
2
|
+
import { n as convertTsPathsToRegexes, t as PathMapping } from "./ts-config-paths-wVx39QZ0.cjs";
|
|
3
|
+
import { n as mergeHooks, t as mergeConfigs } from "./merge-config-DVOlBQJY.cjs";
|
|
4
|
+
import { BambooHooks, Config, ConfigTsOptions, LoadConfigResult as LoadConfigResult$1 } from "@bamboocss/types";
|
|
5
|
+
import { CompilerOptions, TypeAcquisition } from "typescript";
|
|
6
|
+
|
|
7
|
+
//#region src/types.d.ts
|
|
8
|
+
interface ConfigFileOptions {
|
|
9
|
+
cwd: string;
|
|
10
|
+
file?: string;
|
|
11
|
+
}
|
|
12
|
+
interface BundleConfigResult<T = Config> {
|
|
13
|
+
config: T;
|
|
14
|
+
dependencies: string[];
|
|
15
|
+
path: string;
|
|
16
|
+
}
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region src/bundle-config.d.ts
|
|
19
|
+
declare function bundleConfig(options: ConfigFileOptions): Promise<BundleConfigResult>;
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/find-config.d.ts
|
|
22
|
+
declare function findConfig(options: Partial<ConfigFileOptions>): string;
|
|
23
|
+
//#endregion
|
|
24
|
+
//#region ../../node_modules/.pnpm/pkg-types@2.3.0/node_modules/pkg-types/dist/index.d.mts
|
|
25
|
+
type StripEnums<T extends Record<string, any>> = { [K in keyof T]: T[K] extends boolean ? T[K] : T[K] extends string ? T[K] : T[K] extends object ? T[K] : T[K] extends Array<any> ? T[K] : T[K] extends undefined ? undefined : any };
|
|
26
|
+
interface TSConfig {
|
|
27
|
+
compilerOptions?: StripEnums<CompilerOptions>;
|
|
28
|
+
exclude?: string[];
|
|
29
|
+
compileOnSave?: boolean;
|
|
30
|
+
extends?: string | string[];
|
|
31
|
+
files?: string[];
|
|
32
|
+
include?: string[];
|
|
33
|
+
typeAcquisition?: TypeAcquisition;
|
|
34
|
+
references?: {
|
|
35
|
+
path: string;
|
|
36
|
+
}[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Defines a TSConfig structure.
|
|
40
|
+
* @param tsconfig - The contents of `tsconfig.json` as an object. See {@link TSConfig}.
|
|
41
|
+
* @returns the same `tsconfig.json` object.
|
|
42
|
+
*/
|
|
43
|
+
//#endregion
|
|
44
|
+
//#region src/get-mod-deps.d.ts
|
|
45
|
+
interface GetDepsOptions {
|
|
46
|
+
filename: string;
|
|
47
|
+
ext: string;
|
|
48
|
+
cwd: string;
|
|
49
|
+
seen: Set<string>;
|
|
50
|
+
baseUrl: string | undefined;
|
|
51
|
+
pathMappings: PathMapping[];
|
|
52
|
+
foundModuleAliases: Map<string, string>;
|
|
53
|
+
compilerOptions?: TSConfig['compilerOptions'];
|
|
54
|
+
}
|
|
55
|
+
declare function getConfigDependencies(filePath: string, tsOptions?: ConfigTsOptions, compilerOptions?: TSConfig['compilerOptions']): {
|
|
56
|
+
deps: Set<string>;
|
|
57
|
+
aliases: Map<string, string>;
|
|
58
|
+
};
|
|
59
|
+
//#endregion
|
|
60
|
+
//#region src/get-resolved-config.d.ts
|
|
61
|
+
type Extendable<T> = T & {
|
|
62
|
+
extend?: T;
|
|
63
|
+
};
|
|
64
|
+
type ExtendableConfig = Extendable<Config>;
|
|
65
|
+
/**
|
|
66
|
+
* Recursively merge all presets into a single config (depth-first using stack)
|
|
67
|
+
*/
|
|
68
|
+
declare function getResolvedConfig(config: ExtendableConfig, cwd: string, hooks?: Partial<BambooHooks>): Promise<Config>;
|
|
69
|
+
//#endregion
|
|
70
|
+
//#region src/load-config.d.ts
|
|
71
|
+
/**
|
|
72
|
+
* Find, load and resolve the final config (including presets)
|
|
73
|
+
*/
|
|
74
|
+
declare function loadConfig(options: ConfigFileOptions): Promise<LoadConfigResult>;
|
|
75
|
+
//#endregion
|
|
76
|
+
//#region src/resolve-config.d.ts
|
|
77
|
+
/**
|
|
78
|
+
* Resolve the final config (including presets)
|
|
79
|
+
* @bamboocss/preset-base: ALWAYS included if NOT using eject: true
|
|
80
|
+
* @bamboocss/preset-bamboo: only included by default if no presets
|
|
81
|
+
*/
|
|
82
|
+
declare function resolveConfig(result: BundleConfigResult, cwd: string): Promise<LoadConfigResult$1>;
|
|
83
|
+
//#endregion
|
|
84
|
+
export { type BundleConfigResult, type GetDepsOptions, bundleConfig, convertTsPathsToRegexes, diffConfigs, findConfig, getConfigDependencies, getResolvedConfig, loadConfig, mergeConfigs, mergeHooks, resolveConfig };
|