@pandacss/config 2.0.0-beta.0 → 2.0.0-beta.10
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/{chunk-LUSBBUHX.js → chunk-PER4IFQZ.js} +14 -45
- package/dist/chunk-R4R5RHIS.js +73 -0
- package/dist/{chunk-VYX3JX5J.js → chunk-U6KCSKCU.js} +5 -3
- package/dist/index.d.ts +129 -5
- package/dist/index.js +1346 -226
- package/dist/{merge-Bt4BM1CH.d.ts → merge-Bbdo_XHY.d.ts} +6 -7
- package/dist/merge.d.ts +1 -1
- package/dist/merge.js +2 -1
- package/dist/serialize.js +2 -1
- package/package.json +6 -3
package/dist/index.js
CHANGED
|
@@ -1,29 +1,83 @@
|
|
|
1
1
|
import {
|
|
2
|
-
PandaError,
|
|
3
|
-
isPlainObject,
|
|
4
2
|
mergeConfigs,
|
|
5
3
|
mergeConfigsWithSources
|
|
6
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-PER4IFQZ.js";
|
|
7
5
|
import {
|
|
8
6
|
collectPluginHookHandlers,
|
|
9
7
|
createConfigSnapshot,
|
|
10
8
|
normalizeHook
|
|
11
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-U6KCSKCU.js";
|
|
10
|
+
import {
|
|
11
|
+
PandaError,
|
|
12
|
+
clone,
|
|
13
|
+
createConfigDiagnostic,
|
|
14
|
+
createConfigError,
|
|
15
|
+
ensureConfigObject,
|
|
16
|
+
errorMessage,
|
|
17
|
+
isPlainObject
|
|
18
|
+
} from "./chunk-R4R5RHIS.js";
|
|
12
19
|
|
|
13
20
|
// src/load.ts
|
|
14
|
-
import { applyConfigDefaults } from "@pandacss/compiler-shared";
|
|
21
|
+
import { applyConfigDefaults as applyConfigDefaults2 } from "@pandacss/compiler-shared";
|
|
15
22
|
|
|
16
23
|
// src/bundle.ts
|
|
24
|
+
import { existsSync, realpathSync } from "fs";
|
|
25
|
+
import { mkdir, unlink, writeFile } from "fs/promises";
|
|
26
|
+
import { builtinModules } from "module";
|
|
27
|
+
import { tmpdir } from "os";
|
|
28
|
+
import { dirname, isAbsolute as isAbsolute2, join, normalize, relative } from "path";
|
|
29
|
+
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
30
|
+
|
|
31
|
+
// src/bundle-plugins.ts
|
|
17
32
|
import { parse } from "acorn";
|
|
18
33
|
import { simple } from "acorn-walk";
|
|
19
34
|
import MagicString from "magic-string";
|
|
20
|
-
import {
|
|
21
|
-
import { builtinModules } from "module";
|
|
22
|
-
import { isAbsolute, normalize, relative } from "path";
|
|
35
|
+
import { isAbsolute } from "path";
|
|
23
36
|
import { pathToFileURL } from "url";
|
|
24
|
-
|
|
37
|
+
function importMetaUrlPlugin() {
|
|
38
|
+
return {
|
|
39
|
+
name: "panda-import-meta-url",
|
|
40
|
+
transform(code, id) {
|
|
41
|
+
if (!isAbsolute(id) || !code.includes("import.meta.url")) return;
|
|
42
|
+
const replacement = JSON.stringify(pathToFileURL(id).href);
|
|
43
|
+
const patched = replaceImportMetaUrl(code, replacement);
|
|
44
|
+
if (patched === code) return;
|
|
45
|
+
return { code: patched, map: null };
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function replaceImportMetaUrl(code, replacement) {
|
|
50
|
+
const ast = parse(code, {
|
|
51
|
+
ecmaVersion: "latest",
|
|
52
|
+
sourceType: "module"
|
|
53
|
+
});
|
|
54
|
+
const output = new MagicString(code);
|
|
55
|
+
let changed = false;
|
|
56
|
+
simple(ast, {
|
|
57
|
+
MemberExpression(node) {
|
|
58
|
+
if (!isImportMetaUrl(node)) return;
|
|
59
|
+
output.overwrite(node.start, node.end, replacement);
|
|
60
|
+
changed = true;
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
return changed ? output.toString() : code;
|
|
64
|
+
}
|
|
65
|
+
function isImportMetaUrl(node) {
|
|
66
|
+
if (node.computed || !isIdentifier(node.property, "url")) return false;
|
|
67
|
+
const object = node.object;
|
|
68
|
+
return isNode(object, "MetaProperty") && isIdentifier(object.meta, "import") && isIdentifier(object.property, "meta");
|
|
69
|
+
}
|
|
70
|
+
function isIdentifier(value, name) {
|
|
71
|
+
return isNode(value, "Identifier") && value.name === name;
|
|
72
|
+
}
|
|
73
|
+
function isNode(value, type) {
|
|
74
|
+
return !!value && typeof value === "object" && value.type === type;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// src/bundle.ts
|
|
25
78
|
var nodeBuiltins = /* @__PURE__ */ new Set([...builtinModules, ...builtinModules.map((mod) => `node:${mod}`)]);
|
|
26
79
|
async function bundleConfig(filepath, cwd) {
|
|
80
|
+
const { rolldown } = await import("rolldown");
|
|
27
81
|
const build = await rolldown({
|
|
28
82
|
input: filepath,
|
|
29
83
|
cwd,
|
|
@@ -43,174 +97,1186 @@ async function bundleConfig(filepath, cwd) {
|
|
|
43
97
|
throw new PandaError("CONFIG_ERROR", "\u{1F4A5} Config bundle did not produce an executable module.");
|
|
44
98
|
}
|
|
45
99
|
const dependencies = collectDependencies(chunks.output, filepath, cwd);
|
|
46
|
-
const mod = await
|
|
100
|
+
const mod = await loadBundledModule(filepath, output.code);
|
|
47
101
|
const hasDefaultExport = Object.prototype.hasOwnProperty.call(mod ?? {}, "default");
|
|
48
102
|
const exported = hasDefaultExport ? mod.default : mod;
|
|
49
103
|
const config = hasDefaultExport && isPromiseLike(exported) ? await exported : exported;
|
|
50
104
|
return { config, dependencies };
|
|
51
105
|
}
|
|
52
|
-
async function
|
|
106
|
+
async function loadBundledModule(filepath, code) {
|
|
107
|
+
const target = tempTargetFor(filepath);
|
|
108
|
+
if (target) {
|
|
109
|
+
try {
|
|
110
|
+
await mkdir(dirname(target), { recursive: true });
|
|
111
|
+
await writeFile(target, code);
|
|
112
|
+
try {
|
|
113
|
+
return await import(
|
|
114
|
+
/* @vite-ignore */
|
|
115
|
+
pathToFileURL2(target).href
|
|
116
|
+
);
|
|
117
|
+
} finally {
|
|
118
|
+
void unlink(target).catch(() => void 0);
|
|
119
|
+
}
|
|
120
|
+
} catch {
|
|
121
|
+
}
|
|
122
|
+
}
|
|
53
123
|
const dataUrl = `data:text/javascript;base64,${Buffer.from(code).toString("base64")}`;
|
|
54
|
-
return import(
|
|
124
|
+
return await import(
|
|
55
125
|
/* @vite-ignore */
|
|
56
126
|
dataUrl
|
|
57
127
|
);
|
|
58
128
|
}
|
|
59
|
-
function
|
|
129
|
+
function tempTargetFor(filepath) {
|
|
130
|
+
const unique = `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
|
|
131
|
+
const name = `panda.config.bundled.${unique}.mjs`;
|
|
132
|
+
const nodeModules = nearestNodeModules(dirname(filepath));
|
|
133
|
+
const base = nodeModules ? join(nodeModules, ".panda") : join(tmpdir(), "panda-config");
|
|
134
|
+
return join(base, name);
|
|
135
|
+
}
|
|
136
|
+
function nearestNodeModules(start) {
|
|
137
|
+
let current = start;
|
|
138
|
+
while (true) {
|
|
139
|
+
const candidate = join(current, "node_modules");
|
|
140
|
+
if (existsSync(candidate)) return candidate;
|
|
141
|
+
const parent = dirname(current);
|
|
142
|
+
if (parent === current) return void 0;
|
|
143
|
+
current = parent;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
function isPromiseLike(value) {
|
|
147
|
+
return value != null && typeof value === "object" && typeof value.then === "function";
|
|
148
|
+
}
|
|
149
|
+
function collectDependencies(output, entry, cwd) {
|
|
150
|
+
const dependencies = /* @__PURE__ */ new Set();
|
|
151
|
+
const base = canonical(cwd);
|
|
152
|
+
const add = (id) => dependencies.add(normalize(relative(base, canonical(id))));
|
|
153
|
+
for (const item of output) {
|
|
154
|
+
if (item.type !== "chunk") continue;
|
|
155
|
+
Object.keys(item.modules ?? {}).forEach((id) => {
|
|
156
|
+
if (isAbsolute2(id)) add(id);
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
if (isAbsolute2(entry)) add(entry);
|
|
160
|
+
return Array.from(dependencies);
|
|
161
|
+
}
|
|
162
|
+
function canonical(filepath) {
|
|
163
|
+
try {
|
|
164
|
+
return realpathSync(filepath);
|
|
165
|
+
} catch {
|
|
166
|
+
return filepath;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// src/find.ts
|
|
171
|
+
import { readdirSync } from "fs";
|
|
172
|
+
import { dirname as dirname2, resolve } from "path";
|
|
173
|
+
var configFiles = /* @__PURE__ */ new Set([
|
|
174
|
+
"panda.config.ts",
|
|
175
|
+
"panda.config.js",
|
|
176
|
+
"panda.config.mts",
|
|
177
|
+
"panda.config.mjs",
|
|
178
|
+
"panda.config.cts",
|
|
179
|
+
"panda.config.cjs"
|
|
180
|
+
]);
|
|
181
|
+
var isPandaConfig = (file) => configFiles.has(file);
|
|
182
|
+
function findUp(cwd) {
|
|
183
|
+
let dir = resolve(cwd);
|
|
184
|
+
while (true) {
|
|
185
|
+
let entries;
|
|
186
|
+
try {
|
|
187
|
+
entries = readdirSync(dir);
|
|
188
|
+
} catch {
|
|
189
|
+
entries = [];
|
|
190
|
+
}
|
|
191
|
+
const match = entries.find(isPandaConfig);
|
|
192
|
+
if (match) return resolve(dir, match);
|
|
193
|
+
const parent = dirname2(dir);
|
|
194
|
+
if (parent === dir) return void 0;
|
|
195
|
+
dir = parent;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function findConfig(options) {
|
|
199
|
+
const { cwd, file } = options;
|
|
200
|
+
if (file) {
|
|
201
|
+
return resolve(cwd, file);
|
|
202
|
+
}
|
|
203
|
+
const configPath = findUp(cwd);
|
|
204
|
+
if (!configPath) {
|
|
205
|
+
throw new PandaError(
|
|
206
|
+
"CONFIG_NOT_FOUND",
|
|
207
|
+
"Cannot find config file `panda.config.{ts,js,mjs,mts}`. Did you forget to run `panda init`?"
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
return configPath;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// src/hook-utils.ts
|
|
214
|
+
var configResolvedUtils = {
|
|
215
|
+
omit(obj, paths) {
|
|
216
|
+
const next = clone(obj);
|
|
217
|
+
for (const path of paths) {
|
|
218
|
+
deleteAtPath(next, path);
|
|
219
|
+
}
|
|
220
|
+
return next;
|
|
221
|
+
},
|
|
222
|
+
pick(obj, paths) {
|
|
223
|
+
const result = {};
|
|
224
|
+
for (const path of paths) {
|
|
225
|
+
const value = getAtPath(obj, path);
|
|
226
|
+
if (value !== void 0) {
|
|
227
|
+
setAtPath(result, path, value);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return result;
|
|
231
|
+
},
|
|
232
|
+
traverse(obj, callback, options = {}) {
|
|
233
|
+
traverseValue(obj, callback, options);
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
function pathParts(path) {
|
|
237
|
+
return path.split(".").filter(Boolean);
|
|
238
|
+
}
|
|
239
|
+
function getAtPath(value, path) {
|
|
240
|
+
let current = value;
|
|
241
|
+
for (const part of pathParts(path)) {
|
|
242
|
+
if (!isPlainObject(current) && !Array.isArray(current)) return void 0;
|
|
243
|
+
current = current[part];
|
|
244
|
+
}
|
|
245
|
+
return current;
|
|
246
|
+
}
|
|
247
|
+
function setAtPath(target, path, value) {
|
|
248
|
+
const parts = pathParts(path);
|
|
249
|
+
let current = target;
|
|
250
|
+
parts.forEach((part, index) => {
|
|
251
|
+
if (index === parts.length - 1) {
|
|
252
|
+
current[part] = clone(value);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
const next = current[part];
|
|
256
|
+
if (!isPlainObject(next)) {
|
|
257
|
+
current[part] = {};
|
|
258
|
+
}
|
|
259
|
+
current = current[part];
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
function deleteAtPath(target, path) {
|
|
263
|
+
const parts = pathParts(path);
|
|
264
|
+
const key = parts.pop();
|
|
265
|
+
if (!key) return;
|
|
266
|
+
let current = target;
|
|
267
|
+
for (const part of parts) {
|
|
268
|
+
if (!isPlainObject(current) && !Array.isArray(current)) return;
|
|
269
|
+
current = current[part];
|
|
270
|
+
}
|
|
271
|
+
if (isPlainObject(current) || Array.isArray(current)) {
|
|
272
|
+
delete current[key];
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
function traverseValue(value, callback, options, parent, key, path = "", depth = 0) {
|
|
276
|
+
if (parent && key !== void 0) {
|
|
277
|
+
callback({ value, path, depth, parent, key });
|
|
278
|
+
}
|
|
279
|
+
if (options.maxDepth !== void 0 && depth >= options.maxDepth) return;
|
|
280
|
+
if (!isPlainObject(value) && !Array.isArray(value)) return;
|
|
281
|
+
const separator = options.separator ?? ".";
|
|
282
|
+
const container = value;
|
|
283
|
+
const keys = Object.keys(container);
|
|
284
|
+
for (let i = 0; i < keys.length; i++) {
|
|
285
|
+
const childKey = keys[i];
|
|
286
|
+
traverseValue(
|
|
287
|
+
container[childKey],
|
|
288
|
+
callback,
|
|
289
|
+
options,
|
|
290
|
+
container,
|
|
291
|
+
childKey,
|
|
292
|
+
joinPath(path, childKey, separator),
|
|
293
|
+
depth + 1
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
function joinPath(parent, key, separator) {
|
|
298
|
+
return parent ? `${parent}${separator}${key}` : key;
|
|
299
|
+
}
|
|
300
|
+
function attachRuntimeHooks(config, configs) {
|
|
301
|
+
const plugins = configs.flatMap((item) => {
|
|
302
|
+
if ("hooks" in item && item.hooks != null) {
|
|
303
|
+
const message = '`config.hooks` was removed in v2. Use `plugins: [{ name: "local", hooks: { ... } }]` instead.';
|
|
304
|
+
throw createConfigError(message, [
|
|
305
|
+
createConfigDiagnostic("config_hooks_removed", message, [
|
|
306
|
+
'Move root `hooks` into `plugins: [{ name: "local", hooks: { ... } }]`.'
|
|
307
|
+
])
|
|
308
|
+
]);
|
|
309
|
+
}
|
|
310
|
+
return [...item.plugins ?? [], ...item.extend?.plugins ?? []];
|
|
311
|
+
});
|
|
312
|
+
for (const plugin of plugins) {
|
|
313
|
+
if (!isPlainObject(plugin) || typeof plugin.name !== "string" || plugin.name.length === 0) {
|
|
314
|
+
throw new PandaError(
|
|
315
|
+
"CONFIG_ERROR",
|
|
316
|
+
"\u{1F4A5} Every plugin in `config.plugins` must be an object with a non-empty `name`."
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
if (plugins.length > 0) {
|
|
321
|
+
config.plugins = plugins;
|
|
322
|
+
}
|
|
323
|
+
return config;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// src/design-system/overlay-input.ts
|
|
327
|
+
import { applyConfigDefaults } from "@pandacss/compiler-shared";
|
|
328
|
+
|
|
329
|
+
// src/normalize.ts
|
|
330
|
+
var CLASS_NAME_OPTION_KEYS = ["hash", "prefix", "separator"];
|
|
331
|
+
function normalizeClassNameOptions(config) {
|
|
60
332
|
return {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
333
|
+
hash: normalizeHash(config.hash),
|
|
334
|
+
prefix: normalizePrefix(config.prefix),
|
|
335
|
+
separator: config.separator ?? "_"
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
function diffClassNameOptions(consumer, designSystem, scope) {
|
|
339
|
+
const normalized = normalizeClassNameOptions(consumer);
|
|
340
|
+
return CLASS_NAME_OPTION_KEYS.filter((key) => {
|
|
341
|
+
if (scope === "explicit" && consumer[key] === void 0) {
|
|
342
|
+
return false;
|
|
343
|
+
}
|
|
344
|
+
if (key === "separator") {
|
|
345
|
+
return normalized.separator !== designSystem.separator;
|
|
346
|
+
}
|
|
347
|
+
return normalized[key].cssVar !== designSystem[key].cssVar || normalized[key].className !== designSystem[key].className;
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
function normalizeHash(value) {
|
|
351
|
+
if (typeof value === "boolean") {
|
|
352
|
+
return { cssVar: value, className: value };
|
|
353
|
+
}
|
|
354
|
+
if (value && typeof value === "object") {
|
|
355
|
+
return { cssVar: value.cssVar === true, className: value.className === true };
|
|
356
|
+
}
|
|
357
|
+
return { cssVar: false, className: false };
|
|
358
|
+
}
|
|
359
|
+
function normalizePrefix(value) {
|
|
360
|
+
if (typeof value === "string") {
|
|
361
|
+
return { cssVar: value, className: value };
|
|
362
|
+
}
|
|
363
|
+
if (value && typeof value === "object") {
|
|
364
|
+
return { cssVar: value.cssVar ?? "", className: value.className ?? "" };
|
|
365
|
+
}
|
|
366
|
+
return { cssVar: "", className: "" };
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// src/design-system/overlay-input.ts
|
|
370
|
+
var CLASS_NAME_OPTION_KEYS2 = ["hash", "prefix", "separator"];
|
|
371
|
+
var RUNTIME_OPTION_KEYS = [
|
|
372
|
+
...CLASS_NAME_OPTION_KEYS2,
|
|
373
|
+
"jsxFramework",
|
|
374
|
+
"jsxFactory",
|
|
375
|
+
"jsxStyleProps",
|
|
376
|
+
"syntax",
|
|
377
|
+
"strictTokens",
|
|
378
|
+
"strictPropertyValues",
|
|
379
|
+
"shorthands"
|
|
380
|
+
];
|
|
381
|
+
function designSystemSourceIds(chain) {
|
|
382
|
+
const ids = /* @__PURE__ */ new Set();
|
|
383
|
+
for (const ds of chain) {
|
|
384
|
+
ids.add(ds.name);
|
|
385
|
+
ids.add(ds.specifier);
|
|
386
|
+
}
|
|
387
|
+
return ids;
|
|
388
|
+
}
|
|
389
|
+
function authoredByApp(sources, prefix, dsIds) {
|
|
390
|
+
return Object.entries(sources.paths).some(([path, ids]) => {
|
|
391
|
+
if (path !== prefix && !path.startsWith(`${prefix}.`)) return false;
|
|
392
|
+
const idList = Array.isArray(ids) ? ids : [ids];
|
|
393
|
+
return idList.some((id) => isAppSource(sources.entries[id], dsIds));
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
function isAppSource(entry, dsIds) {
|
|
397
|
+
if (!entry) return false;
|
|
398
|
+
if (entry.kind === "config") return true;
|
|
399
|
+
if (entry.kind !== "preset") return false;
|
|
400
|
+
return entry.specifier === void 0 || !dsIds.has(entry.specifier);
|
|
401
|
+
}
|
|
402
|
+
function buildOverlayInput(sources, appConfig, chain, leafPreset, cwd) {
|
|
403
|
+
const dsIds = designSystemSourceIds(chain);
|
|
404
|
+
const authored = {
|
|
405
|
+
conditions: authoredByApp(sources, "conditions", dsIds),
|
|
406
|
+
breakpoints: authoredByApp(sources, "theme.breakpoints", dsIds),
|
|
407
|
+
utilities: authoredByApp(sources, "utilities", dsIds),
|
|
408
|
+
tokens: authoredByApp(sources, "theme.tokens", dsIds) || authoredByApp(sources, "theme.semanticTokens", dsIds)
|
|
409
|
+
};
|
|
410
|
+
const mismatches = diffRuntimeOptions(appConfig, leafPreset, sources, dsIds, cwd);
|
|
411
|
+
return { authored, compatible: mismatches.length === 0 };
|
|
412
|
+
}
|
|
413
|
+
function diffRuntimeOptions(appConfig, leafPreset, sources, dsIds, cwd) {
|
|
414
|
+
const app = applyConfigDefaults({ ...appConfig }, cwd);
|
|
415
|
+
const ds = applyConfigDefaults({ ...leafPreset }, cwd);
|
|
416
|
+
const appClass = normalizeClassNameOptions(app);
|
|
417
|
+
const dsClass = normalizeClassNameOptions(ds);
|
|
418
|
+
return RUNTIME_OPTION_KEYS.filter((key) => {
|
|
419
|
+
if (!authoredByApp(sources, key, dsIds)) return false;
|
|
420
|
+
if (key === "hash" || key === "prefix" || key === "separator") {
|
|
421
|
+
if (key === "separator") return appClass.separator !== dsClass.separator;
|
|
422
|
+
return appClass[key].cssVar !== dsClass[key].cssVar || appClass[key].className !== dsClass[key].className;
|
|
423
|
+
}
|
|
424
|
+
return JSON.stringify(app[key]) !== JSON.stringify(ds[key]);
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// src/preset.ts
|
|
429
|
+
import { normalize as normalize2, relative as relative5 } from "path";
|
|
430
|
+
|
|
431
|
+
// src/design-system/chain.ts
|
|
432
|
+
import {
|
|
433
|
+
outdirBasename
|
|
434
|
+
} from "@pandacss/compiler-shared";
|
|
435
|
+
import { readFileSync as readFileSync2, statSync } from "fs";
|
|
436
|
+
import { dirname as dirname4, resolve as resolve4 } from "path";
|
|
437
|
+
import { pathToFileURL as pathToFileURL3 } from "url";
|
|
438
|
+
|
|
439
|
+
// src/resolve.ts
|
|
440
|
+
import { createRequire } from "module";
|
|
441
|
+
import { resolve as resolve2 } from "path";
|
|
442
|
+
function tryResolveFrom(request, fromDir) {
|
|
443
|
+
try {
|
|
444
|
+
return createRequire(resolve2(fromDir, "noop.js")).resolve(request, { paths: [fromDir] });
|
|
445
|
+
} catch (error) {
|
|
446
|
+
if (isResolveMiss(error)) return void 0;
|
|
447
|
+
throw error;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
function isResolveMiss(error) {
|
|
451
|
+
const code = errorCode(error);
|
|
452
|
+
return code === "MODULE_NOT_FOUND" || code === "ERR_PACKAGE_PATH_NOT_EXPORTED";
|
|
453
|
+
}
|
|
454
|
+
function resolveFrom(request, fromDir) {
|
|
455
|
+
try {
|
|
456
|
+
return { kind: "resolved", path: createRequire(resolve2(fromDir, "noop.js")).resolve(request, { paths: [fromDir] }) };
|
|
457
|
+
} catch (error) {
|
|
458
|
+
const code = errorCode(error);
|
|
459
|
+
if (code === "ERR_PACKAGE_PATH_NOT_EXPORTED") return { kind: "not-exported" };
|
|
460
|
+
if (code === "MODULE_NOT_FOUND") return { kind: "not-installed" };
|
|
461
|
+
throw error;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
function errorCode(error) {
|
|
465
|
+
return typeof error === "object" && error !== null && "code" in error ? error.code : void 0;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
// src/design-system/package.ts
|
|
469
|
+
import { existsSync as existsSync2, readFileSync } from "fs";
|
|
470
|
+
import { dirname as dirname3, join as join2 } from "path";
|
|
471
|
+
|
|
472
|
+
// src/design-system/publishable-files.ts
|
|
473
|
+
import { relative as relative3, resolve as resolve3 } from "path";
|
|
474
|
+
|
|
475
|
+
// src/paths.ts
|
|
476
|
+
import { isAbsolute as isAbsolute3, relative as relative2 } from "path";
|
|
477
|
+
function toPosixPath(path) {
|
|
478
|
+
return path.includes("\\") ? path.split("\\").join("/") : path;
|
|
479
|
+
}
|
|
480
|
+
function toPosixRelative(from, to) {
|
|
481
|
+
const rel = toPosixPath(relative2(from, to));
|
|
482
|
+
return rel.startsWith(".") ? rel : `./${rel}`;
|
|
483
|
+
}
|
|
484
|
+
function toRelativeKey(key, cwd) {
|
|
485
|
+
return toPosixPath(isAbsolute3(key) ? relative2(cwd, key) : key);
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// src/design-system/publishable-files.ts
|
|
489
|
+
var GLOB_START = /[*?{]/;
|
|
490
|
+
var HAS_WILDCARD = /[*?]/;
|
|
491
|
+
var TRAILING_SLASH = /\/$/;
|
|
492
|
+
var REGEX_META = /[.+^${}()|[\]\\]/g;
|
|
493
|
+
var GLOBSTAR = /\*\*/g;
|
|
494
|
+
var GLOB_STAR = /\*/g;
|
|
495
|
+
var GLOB_QMARK = /\?/g;
|
|
496
|
+
var GLOBSTAR_TOKEN = /<<<DS>>>/g;
|
|
497
|
+
function filterPublishableLibFiles(options) {
|
|
498
|
+
const { files, packageRoot, outRoot, publishFiles } = options;
|
|
499
|
+
if (!publishFiles?.length) {
|
|
500
|
+
return { files, unpublished: [] };
|
|
501
|
+
}
|
|
502
|
+
const rules = compilePackageFilesRules(publishFiles);
|
|
503
|
+
const kept = [];
|
|
504
|
+
const unpublished = [];
|
|
505
|
+
for (const file of files) {
|
|
506
|
+
const packageRelative = libFileToPackageRelative(file, packageRoot, outRoot);
|
|
507
|
+
if (packageRelative !== void 0 && matchesCompiledRules(packageRelative, rules)) {
|
|
508
|
+
kept.push(file);
|
|
509
|
+
} else {
|
|
510
|
+
unpublished.push(file);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
return { files: kept, unpublished };
|
|
514
|
+
}
|
|
515
|
+
function readPublishFilesField(value) {
|
|
516
|
+
if (!Array.isArray(value) || value.length === 0) return void 0;
|
|
517
|
+
for (const entry of value) {
|
|
518
|
+
if (typeof entry !== "string") return void 0;
|
|
519
|
+
}
|
|
520
|
+
return value;
|
|
521
|
+
}
|
|
522
|
+
function libFileToPackageRelative(file, packageRoot, outRoot) {
|
|
523
|
+
const normalized = toPosixPath(file);
|
|
524
|
+
const withoutDot = normalized.startsWith("./") ? normalized.slice(2) : normalized;
|
|
525
|
+
const globAt = withoutDot.search(GLOB_START);
|
|
526
|
+
const literalPrefix = globAt === -1 ? withoutDot : withoutDot.slice(0, globAt);
|
|
527
|
+
const abs = resolve3(outRoot, literalPrefix || ".");
|
|
528
|
+
const rel = toPosixPath(relative3(packageRoot, abs));
|
|
529
|
+
if (rel === "") return "";
|
|
530
|
+
if (rel.startsWith("..")) return void 0;
|
|
531
|
+
return rel;
|
|
532
|
+
}
|
|
533
|
+
function compilePackageFilesRules(patterns) {
|
|
534
|
+
const rules = [];
|
|
535
|
+
for (const raw of patterns) {
|
|
536
|
+
const negated = raw.startsWith("!");
|
|
537
|
+
const pattern = toPosixPath(negated ? raw.slice(1) : raw);
|
|
538
|
+
const normalized = pattern.startsWith("./") ? pattern.slice(2) : pattern;
|
|
539
|
+
if (!normalized) continue;
|
|
540
|
+
if (!HAS_WILDCARD.test(normalized)) {
|
|
541
|
+
rules.push({ kind: "prefix", negated, value: normalized.replace(TRAILING_SLASH, "") });
|
|
542
|
+
continue;
|
|
543
|
+
}
|
|
544
|
+
const escaped = normalized.replace(REGEX_META, "\\$&").replace(GLOBSTAR, "<<<DS>>>").replace(GLOB_STAR, "[^/]*").replace(GLOB_QMARK, "[^/]").replace(GLOBSTAR_TOKEN, ".*");
|
|
545
|
+
rules.push({ kind: "regex", negated, value: new RegExp(`^${escaped}(?:/.*)?$`) });
|
|
546
|
+
}
|
|
547
|
+
return rules;
|
|
548
|
+
}
|
|
549
|
+
function matchesCompiledRules(packageRelativePath, rules) {
|
|
550
|
+
const path = packageRelativePath.startsWith("./") ? packageRelativePath.slice(2) : packageRelativePath;
|
|
551
|
+
let included = false;
|
|
552
|
+
for (const rule of rules) {
|
|
553
|
+
const hit = rule.kind === "prefix" ? path === rule.value || path.startsWith(`${rule.value}/`) : rule.value.test(path);
|
|
554
|
+
if (!hit) continue;
|
|
555
|
+
included = !rule.negated;
|
|
556
|
+
}
|
|
557
|
+
return included;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// src/design-system/package.ts
|
|
561
|
+
var PACKAGE_MANAGER_RANGE_PATTERN = /^(?:workspace|catalog):/;
|
|
562
|
+
var PORTABLE_WORKSPACE_RANGE_PATTERN = /^[~^]?\d/;
|
|
563
|
+
var VERSION_CORE_PATTERN = /^(\d+)\.(\d+)\.(\d+)/;
|
|
564
|
+
function resolvePublishedPandaRange(range, currentVersion) {
|
|
565
|
+
const authored = range?.trim();
|
|
566
|
+
if (!authored) return "*";
|
|
567
|
+
if (authored.startsWith("npm:")) {
|
|
568
|
+
return resolveNpmAliasRange(authored) ?? portableRangeFromInstalled(currentVersion, "^");
|
|
569
|
+
}
|
|
570
|
+
if (!PACKAGE_MANAGER_RANGE_PATTERN.test(authored)) return authored;
|
|
571
|
+
if (authored.startsWith("workspace:")) {
|
|
572
|
+
const workspaceRange = authored.slice("workspace:".length);
|
|
573
|
+
if (PORTABLE_WORKSPACE_RANGE_PATTERN.test(workspaceRange)) return workspaceRange;
|
|
574
|
+
}
|
|
575
|
+
const operator = authored === "workspace:~" ? "~" : "^";
|
|
576
|
+
return portableRangeFromInstalled(currentVersion, operator);
|
|
577
|
+
}
|
|
578
|
+
function resolveNpmAliasRange(spec) {
|
|
579
|
+
const at = spec.lastIndexOf("@");
|
|
580
|
+
if (at <= "npm:".length) return void 0;
|
|
581
|
+
return spec.slice(at + 1);
|
|
582
|
+
}
|
|
583
|
+
function portableRangeFromInstalled(currentVersion, operator) {
|
|
584
|
+
const core = currentVersion?.match(VERSION_CORE_PATTERN)?.[0];
|
|
585
|
+
return core ? `${operator}${core}` : "*";
|
|
586
|
+
}
|
|
587
|
+
function readPackageIdentity(cwd) {
|
|
588
|
+
const packagePath = nearestPackageJson(cwd);
|
|
589
|
+
if (packagePath === void 0) {
|
|
590
|
+
throw new Error(`Could not find a package.json from ${JSON.stringify(cwd)} to build the design system manifest.`);
|
|
591
|
+
}
|
|
592
|
+
const pkg = JSON.parse(readFileSync(packagePath, "utf8"));
|
|
593
|
+
const name = pkg.name;
|
|
594
|
+
if (typeof name !== "string" || name.length === 0) {
|
|
595
|
+
throw new Error(`${JSON.stringify(packagePath)} has no "name"; a design system must be a named package.`);
|
|
596
|
+
}
|
|
597
|
+
const peer = pkg.peerDependencies?.["@pandacss/dev"];
|
|
598
|
+
return {
|
|
599
|
+
name,
|
|
600
|
+
version: typeof pkg.version === "string" ? pkg.version : void 0,
|
|
601
|
+
pandaPeer: typeof peer === "string" ? peer : void 0,
|
|
602
|
+
packagePath,
|
|
603
|
+
publishFiles: readPublishFilesField(pkg.files)
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
function defaultImportMap(name) {
|
|
607
|
+
return {
|
|
608
|
+
css: `${name}/css`,
|
|
609
|
+
recipes: `${name}/recipes`,
|
|
610
|
+
patterns: `${name}/patterns`,
|
|
611
|
+
jsx: `${name}/jsx`,
|
|
612
|
+
tokens: `${name}/tokens`
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
function syncExports(options) {
|
|
616
|
+
const { packageJson, entries } = options;
|
|
617
|
+
const pkg = JSON.parse(packageJson);
|
|
618
|
+
const existing = normalizeExports(pkg.exports);
|
|
619
|
+
const merged = { ...existing };
|
|
620
|
+
const conflicts = [];
|
|
621
|
+
for (const [key, value] of Object.entries(entries)) {
|
|
622
|
+
if (key in merged && !exportsValueEqual(merged[key], value)) {
|
|
623
|
+
conflicts.push(key);
|
|
624
|
+
}
|
|
625
|
+
merged[key] = value;
|
|
626
|
+
}
|
|
627
|
+
const changed = JSON.stringify(pkg.exports) !== JSON.stringify(merged);
|
|
628
|
+
const out = { ...pkg, exports: merged };
|
|
629
|
+
return { changed, json: `${JSON.stringify(out, null, 2)}
|
|
630
|
+
`, conflicts };
|
|
631
|
+
}
|
|
632
|
+
function exportsValueEqual(left, right) {
|
|
633
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
634
|
+
}
|
|
635
|
+
function normalizeExports(exports) {
|
|
636
|
+
if (exports === void 0) return {};
|
|
637
|
+
if (typeof exports === "string") return { ".": exports };
|
|
638
|
+
if (Array.isArray(exports)) return { ".": exports };
|
|
639
|
+
if (!isPlainObject(exports)) return {};
|
|
640
|
+
if (isSubpathExportMap(exports)) return exports;
|
|
641
|
+
return { ".": exports };
|
|
642
|
+
}
|
|
643
|
+
function isSubpathExportMap(exports) {
|
|
644
|
+
return Object.keys(exports).some((key) => key === "." || key.startsWith("./"));
|
|
645
|
+
}
|
|
646
|
+
function nearestPackageJson(start) {
|
|
647
|
+
let current = start;
|
|
648
|
+
while (true) {
|
|
649
|
+
const candidate = join2(current, "package.json");
|
|
650
|
+
if (existsSync2(candidate)) return candidate;
|
|
651
|
+
const parent = dirname3(current);
|
|
652
|
+
if (parent === current) return void 0;
|
|
653
|
+
current = parent;
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
// src/design-system/chain.ts
|
|
658
|
+
var SPECIFIER_PROTOCOL = /^([a-z][a-z0-9+.-]*):/i;
|
|
659
|
+
async function loadDesignSystemChain(spec, cwd, deps) {
|
|
660
|
+
const levels = [];
|
|
661
|
+
const seenAt = /* @__PURE__ */ new Map();
|
|
662
|
+
const seenNames = /* @__PURE__ */ new Map();
|
|
663
|
+
let currentSpec = spec;
|
|
664
|
+
let fromDir = cwd;
|
|
665
|
+
let declaredBy;
|
|
666
|
+
while (true) {
|
|
667
|
+
const manifestPath = resolveManifestPath(currentSpec, fromDir);
|
|
668
|
+
if (manifestPath === void 0) {
|
|
669
|
+
throw declaredBy === void 0 ? notResolvedError(currentSpec) : parentNotResolvedError(declaredBy, currentSpec);
|
|
670
|
+
}
|
|
671
|
+
const seen = seenAt.get(manifestPath);
|
|
672
|
+
if (seen !== void 0) {
|
|
673
|
+
throw cycleError([...levels.slice(seen).map((level2) => level2.info.name), levels[seen].info.name]);
|
|
674
|
+
}
|
|
675
|
+
seenAt.set(manifestPath, levels.length);
|
|
676
|
+
deps.add(manifestPath);
|
|
677
|
+
const { level, parent } = await loadManifestLevel(currentSpec, manifestPath, deps);
|
|
678
|
+
const priorPath = seenNames.get(level.info.name);
|
|
679
|
+
if (priorPath !== void 0 && priorPath !== manifestPath) {
|
|
680
|
+
throw duplicateNameError(level.info.name, priorPath, manifestPath);
|
|
681
|
+
}
|
|
682
|
+
seenNames.set(level.info.name, manifestPath);
|
|
683
|
+
levels.push(level);
|
|
684
|
+
if (parent === void 0) break;
|
|
685
|
+
declaredBy = level.info.name;
|
|
686
|
+
fromDir = dirname4(manifestPath);
|
|
687
|
+
currentSpec = parent;
|
|
688
|
+
}
|
|
689
|
+
return levels.reverse();
|
|
690
|
+
}
|
|
691
|
+
function withDesignSystemImportMap(config, infos) {
|
|
692
|
+
const existing = config.importMap === void 0 ? [] : Array.isArray(config.importMap) ? config.importMap : [config.importMap];
|
|
693
|
+
const roots = infos.map(
|
|
694
|
+
(info) => info.importMap ? designSystemImportMap(info.importMap, info.specifier) : info.specifier
|
|
695
|
+
);
|
|
696
|
+
return { ...config, importMap: [...roots, outdirBasename(config.outdir ?? "styled-system"), ...existing] };
|
|
697
|
+
}
|
|
698
|
+
function buildCodegenOverlay(metadata) {
|
|
699
|
+
const chain = metadata?.designSystem;
|
|
700
|
+
if (!chain || chain.length !== 1) return void 0;
|
|
701
|
+
if (metadata?.overlayInput && !metadata.overlayInput.compatible) return void 0;
|
|
702
|
+
const [ds] = chain;
|
|
703
|
+
const appRecipes = new Set(metadata?.userRecipeNames ?? []);
|
|
704
|
+
const appPatterns = new Set(metadata?.userPatternNames ?? []);
|
|
705
|
+
const authored = metadata?.overlayInput?.authored;
|
|
706
|
+
const runtimeDirty = !!(authored?.conditions || authored?.breakpoints || authored?.utilities || authored?.tokens);
|
|
707
|
+
return {
|
|
708
|
+
...overlayRoots(ds),
|
|
709
|
+
ownedRecipes: ds.recipeNames.filter((name) => !appRecipes.has(name)),
|
|
710
|
+
ownedPatterns: ds.patternNames.filter((name) => !appPatterns.has(name)),
|
|
711
|
+
virtualizeHelpers: true,
|
|
712
|
+
virtualizeCss: !runtimeDirty
|
|
713
|
+
};
|
|
714
|
+
}
|
|
715
|
+
function collectArtifactConflicts(metadata) {
|
|
716
|
+
const appRecipes = new Set(metadata?.userRecipeNames ?? []);
|
|
717
|
+
const appPatterns = new Set(metadata?.userPatternNames ?? []);
|
|
718
|
+
return (metadata?.designSystem ?? []).map((ds) => ({
|
|
719
|
+
name: ds.name,
|
|
720
|
+
recipes: ds.recipeNames.filter((name) => appRecipes.has(name)),
|
|
721
|
+
patterns: ds.patternNames.filter((name) => appPatterns.has(name))
|
|
722
|
+
})).filter((entry) => entry.recipes.length > 0 || entry.patterns.length > 0);
|
|
723
|
+
}
|
|
724
|
+
function collectExportMissingDiagnostics(metadata) {
|
|
725
|
+
const overlay = buildCodegenOverlay(metadata);
|
|
726
|
+
if (!overlay) return [];
|
|
727
|
+
const [ds] = metadata.designSystem;
|
|
728
|
+
const required = [];
|
|
729
|
+
if (overlay.virtualizeHelpers) required.push("./helpers");
|
|
730
|
+
if (overlay.virtualizeCss) {
|
|
731
|
+
required.push("./css", "./css/*");
|
|
732
|
+
}
|
|
733
|
+
if (overlay.ownedRecipes.length > 0) {
|
|
734
|
+
required.push("./recipes", "./recipes/*");
|
|
735
|
+
}
|
|
736
|
+
if (overlay.ownedPatterns.length > 0) {
|
|
737
|
+
required.push("./patterns", "./patterns/*");
|
|
738
|
+
}
|
|
739
|
+
const appPatterns = metadata?.userPatternNames?.length ?? 0;
|
|
740
|
+
const dsPatterns = ds.patternNames?.length ?? 0;
|
|
741
|
+
if (overlay.ownedPatterns.length > 0 || overlay.virtualizeCss && (appPatterns > 0 || dsPatterns > 0)) {
|
|
742
|
+
required.push("./jsx", "./jsx/*");
|
|
743
|
+
}
|
|
744
|
+
return required.filter((subpath) => !hasExport(ds.packageExports, subpath)).map((subpath) => exportMissingDiagnostic(ds.name, subpath));
|
|
745
|
+
}
|
|
746
|
+
function collectNameCollisionDiagnostics(metadata) {
|
|
747
|
+
const overlay = buildCodegenOverlay(metadata);
|
|
748
|
+
if (!overlay) return [];
|
|
749
|
+
return [
|
|
750
|
+
...identCollisions("recipe", [...overlay.ownedRecipes, ...metadata?.userRecipeNames ?? []]),
|
|
751
|
+
...identCollisions("pattern", [...overlay.ownedPatterns, ...metadata?.userPatternNames ?? []])
|
|
752
|
+
];
|
|
753
|
+
}
|
|
754
|
+
function jsIdent(value) {
|
|
755
|
+
let out = "";
|
|
756
|
+
for (let i = 0; i < value.length; i++) {
|
|
757
|
+
const code = value.charCodeAt(i);
|
|
758
|
+
const isIdent = code === 36 || // $
|
|
759
|
+
code === 95 || // _
|
|
760
|
+
code >= 48 && code <= 57 || // 0-9
|
|
761
|
+
code >= 65 && code <= 90 || // A-Z
|
|
762
|
+
code >= 97 && code <= 122;
|
|
763
|
+
if (isIdent) {
|
|
764
|
+
if (i === 0 && code >= 48 && code <= 57) out += "_";
|
|
765
|
+
out += value[i];
|
|
766
|
+
} else {
|
|
767
|
+
out += "_";
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
return out === "" ? "_" : out;
|
|
771
|
+
}
|
|
772
|
+
function identCollisions(kind, names) {
|
|
773
|
+
const byIdent = /* @__PURE__ */ new Map();
|
|
774
|
+
for (const name of names) {
|
|
775
|
+
const ident = jsIdent(name);
|
|
776
|
+
const set = byIdent.get(ident) ?? /* @__PURE__ */ new Set();
|
|
777
|
+
set.add(name);
|
|
778
|
+
byIdent.set(ident, set);
|
|
779
|
+
}
|
|
780
|
+
const collisions = [];
|
|
781
|
+
for (const [ident, raw] of byIdent) {
|
|
782
|
+
if (raw.size < 2) continue;
|
|
783
|
+
const list = [...raw].map((name) => JSON.stringify(name)).join(", ");
|
|
784
|
+
const message = `${kind} names ${list} both generate the export ${JSON.stringify(ident)}; one would overwrite the other in the generated barrel. Rename one so they produce distinct identifiers.`;
|
|
785
|
+
collisions.push(createConfigDiagnostic("design_system_name_collision", message));
|
|
786
|
+
}
|
|
787
|
+
return collisions;
|
|
788
|
+
}
|
|
789
|
+
function hasExport(packageExports, subpath) {
|
|
790
|
+
return packageExports != null && Object.prototype.hasOwnProperty.call(packageExports, subpath);
|
|
791
|
+
}
|
|
792
|
+
function exportMissingDiagnostic(dsName, subpath) {
|
|
793
|
+
const message = `designSystem ${JSON.stringify(dsName)} doesn't export ${JSON.stringify(subpath)}, which this app's codegen needs. Rebuild it with \`panda lib\`.`;
|
|
794
|
+
return createConfigDiagnostic("design_system_export_missing", message, [
|
|
795
|
+
`Rebuild ${JSON.stringify(dsName)} with \`panda lib\` to add the ${JSON.stringify(subpath)} export.`
|
|
796
|
+
]);
|
|
797
|
+
}
|
|
798
|
+
function overlayRoots(ds) {
|
|
799
|
+
const map = ds.importMap;
|
|
800
|
+
const root = (value, subpath) => {
|
|
801
|
+
const resolved = Array.isArray(value) ? value[0] : value;
|
|
802
|
+
return resolved ?? `${ds.specifier}/${subpath}`;
|
|
803
|
+
};
|
|
804
|
+
return {
|
|
805
|
+
jsx: root(map?.jsx, "jsx"),
|
|
806
|
+
recipes: root(map?.recipes, "recipes"),
|
|
807
|
+
patterns: root(map?.patterns, "patterns"),
|
|
808
|
+
css: root(map?.css, "css"),
|
|
809
|
+
helpers: `${ds.specifier}/helpers`
|
|
810
|
+
};
|
|
811
|
+
}
|
|
812
|
+
function resolveManifestPath(spec, fromDir) {
|
|
813
|
+
const protocol = specifierProtocol(spec);
|
|
814
|
+
if (protocol) throw unsupportedSpecifierError(spec, protocol);
|
|
815
|
+
let outcome;
|
|
816
|
+
try {
|
|
817
|
+
outcome = resolveFrom(`${spec}/panda/lib.json`, fromDir);
|
|
818
|
+
} catch (error) {
|
|
819
|
+
const message = `Failed to resolve designSystem ${JSON.stringify(spec)} from ${JSON.stringify(fromDir)}: ${errorMessage(error)}`;
|
|
820
|
+
throw createConfigError(message, [createConfigDiagnostic("design_system_resolve_failed", message)]);
|
|
821
|
+
}
|
|
822
|
+
if (outcome.kind === "resolved") return outcome.path;
|
|
823
|
+
if (outcome.kind === "not-exported") throw manifestNotExportedError(spec);
|
|
824
|
+
return void 0;
|
|
825
|
+
}
|
|
826
|
+
function manifestNotExportedError(spec) {
|
|
827
|
+
const message = `designSystem ${JSON.stringify(spec)} is installed but doesn't expose \`./panda/*\` (missing \`panda/lib.json\`). If it's a Panda design system, rebuild it with \`panda lib\`; otherwise it can't be consumed as a design system.`;
|
|
828
|
+
return createConfigError(message, [
|
|
829
|
+
createConfigDiagnostic("design_system_manifest_not_exported", message, [
|
|
830
|
+
`Rebuild ${JSON.stringify(spec)} with \`panda lib\`, or check its package.json \`exports\` includes \`./panda/*\`.`
|
|
831
|
+
])
|
|
832
|
+
]);
|
|
833
|
+
}
|
|
834
|
+
async function loadManifestLevel(spec, manifestPath, deps) {
|
|
835
|
+
let parsed;
|
|
836
|
+
try {
|
|
837
|
+
parsed = JSON.parse(readFileSync2(manifestPath, "utf8"));
|
|
838
|
+
} catch (error) {
|
|
839
|
+
const message = `Failed to parse ${JSON.stringify(manifestPath)} as JSON: ${errorMessage(error)}. This file must be generated by \`panda lib\`, not hand-written or added to \`include\`.`;
|
|
840
|
+
throw createConfigError(message, [
|
|
841
|
+
{ ...createConfigDiagnostic("design_system_manifest_invalid", message), file: manifestPath }
|
|
842
|
+
]);
|
|
843
|
+
}
|
|
844
|
+
const manifest = validateManifest(spec, manifestPath, parsed);
|
|
845
|
+
const presetPath = resolve4(dirname4(manifestPath), manifest.preset);
|
|
846
|
+
const buildInfoPath = resolve4(dirname4(manifestPath), manifest.buildInfo);
|
|
847
|
+
deps.add(presetPath);
|
|
848
|
+
deps.add(buildInfoPath);
|
|
849
|
+
let preset;
|
|
850
|
+
try {
|
|
851
|
+
const mod = await import(presetImportUrl(presetPath));
|
|
852
|
+
preset = ensureConfigObject("default" in mod ? mod.default : mod, manifest.name ?? spec);
|
|
853
|
+
} catch (error) {
|
|
854
|
+
if (error instanceof PandaError && error.diagnostics?.length) throw error;
|
|
855
|
+
const message = `Failed to load the preset for designSystem ${JSON.stringify(spec)} (${JSON.stringify(manifest.preset)}): ${errorMessage(error)}`;
|
|
856
|
+
throw createConfigError(message, [
|
|
857
|
+
createConfigDiagnostic("design_system_preset_load_failed", message, [
|
|
858
|
+
`Check that ${JSON.stringify(manifest.preset)} is valid and rebuild ${JSON.stringify(spec)} with \`panda lib\`.`
|
|
859
|
+
])
|
|
860
|
+
]);
|
|
861
|
+
}
|
|
862
|
+
const parent = typeof manifest.designSystem === "string" && manifest.designSystem.length > 0 ? manifest.designSystem : void 0;
|
|
863
|
+
const packageExports = readPackageExports(manifestPath);
|
|
864
|
+
return {
|
|
865
|
+
parent,
|
|
866
|
+
level: {
|
|
867
|
+
preset,
|
|
868
|
+
info: {
|
|
869
|
+
name: manifest.name ?? spec,
|
|
870
|
+
specifier: spec,
|
|
871
|
+
manifest,
|
|
872
|
+
manifestPath,
|
|
873
|
+
buildInfoPath,
|
|
874
|
+
files: manifest.files ?? [],
|
|
875
|
+
tokenPaths: [],
|
|
876
|
+
recipeNames: [],
|
|
877
|
+
patternNames: [],
|
|
878
|
+
...manifest.importMap ? { importMap: manifest.importMap } : {},
|
|
879
|
+
...packageExports ? { packageExports } : {}
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
};
|
|
883
|
+
}
|
|
884
|
+
function readPackageExports(manifestPath) {
|
|
885
|
+
try {
|
|
886
|
+
const packageJsonPath = nearestPackageJson(dirname4(manifestPath));
|
|
887
|
+
if (packageJsonPath === void 0) return void 0;
|
|
888
|
+
const pkg = JSON.parse(readFileSync2(packageJsonPath, "utf8"));
|
|
889
|
+
return isExportsMap(pkg.exports) ? pkg.exports : void 0;
|
|
890
|
+
} catch {
|
|
891
|
+
return void 0;
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
function isExportsMap(value) {
|
|
895
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
896
|
+
}
|
|
897
|
+
function presetImportUrl(path) {
|
|
898
|
+
const url = pathToFileURL3(path);
|
|
899
|
+
url.searchParams.set("mtime", String(statSync(path).mtimeMs));
|
|
900
|
+
return url.href;
|
|
901
|
+
}
|
|
902
|
+
function designSystemImportMap(map, spec) {
|
|
903
|
+
return {
|
|
904
|
+
css: map.css ?? `${spec}/css`,
|
|
905
|
+
recipes: map.recipes ?? `${spec}/recipes`,
|
|
906
|
+
patterns: map.patterns ?? `${spec}/patterns`,
|
|
907
|
+
jsx: map.jsx ?? `${spec}/jsx`,
|
|
908
|
+
tokens: map.tokens ?? `${spec}/tokens`
|
|
909
|
+
};
|
|
910
|
+
}
|
|
911
|
+
var IMPORT_MAP_FIELDS = ["css", "recipes", "patterns", "jsx", "tokens"];
|
|
912
|
+
function validateManifest(spec, manifestPath, value) {
|
|
913
|
+
if (!isPlainObject(value)) {
|
|
914
|
+
throw invalidManifestError(spec, manifestPath, ["must contain a JSON object"]);
|
|
915
|
+
}
|
|
916
|
+
const issues = [];
|
|
917
|
+
requiredString(value, "name", issues);
|
|
918
|
+
requiredString(value, "panda", issues);
|
|
919
|
+
requiredString(value, "preset", issues);
|
|
920
|
+
requiredString(value, "buildInfo", issues);
|
|
921
|
+
if (!Number.isInteger(value.schemaVersion) || value.schemaVersion < 1) {
|
|
922
|
+
issues.push('must contain a positive integer "schemaVersion" entry');
|
|
923
|
+
}
|
|
924
|
+
if (value.version !== void 0 && typeof value.version !== "string") {
|
|
925
|
+
issues.push('has a "version" entry that must be a string');
|
|
926
|
+
}
|
|
927
|
+
if (value.designSystem !== void 0 && !isNonEmptyString(value.designSystem)) {
|
|
928
|
+
issues.push('has a "designSystem" entry that must be a non-empty string');
|
|
929
|
+
}
|
|
930
|
+
if (value.files !== void 0 && (!Array.isArray(value.files) || !value.files.every((file) => isNonEmptyString(file)))) {
|
|
931
|
+
issues.push('has a "files" entry that must be an array of non-empty strings');
|
|
932
|
+
}
|
|
933
|
+
if (value.importMap !== void 0) {
|
|
934
|
+
if (!isPlainObject(value.importMap)) {
|
|
935
|
+
issues.push('has an "importMap" entry that must be an object');
|
|
936
|
+
} else {
|
|
937
|
+
for (const field of IMPORT_MAP_FIELDS) {
|
|
938
|
+
const entry = value.importMap[field];
|
|
939
|
+
if (entry !== void 0 && !isNonEmptyString(entry)) {
|
|
940
|
+
issues.push(`has an "importMap.${field}" entry that must be a non-empty string`);
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
}
|
|
945
|
+
if (issues.length > 0) {
|
|
946
|
+
throw invalidManifestError(spec, manifestPath, issues);
|
|
947
|
+
}
|
|
948
|
+
return value;
|
|
949
|
+
}
|
|
950
|
+
function requiredString(value, field, issues) {
|
|
951
|
+
if (!isNonEmptyString(value[field])) {
|
|
952
|
+
issues.push(`is missing a "${field}" entry or it is empty`);
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
function isNonEmptyString(value) {
|
|
956
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
957
|
+
}
|
|
958
|
+
function notResolvedError(spec) {
|
|
959
|
+
const message = `designSystem ${JSON.stringify(spec)} could not be resolved. Install it, or \u2014 if it isn't a Panda design system \u2014 build it with \`panda lib\`.`;
|
|
960
|
+
return createConfigError(message, [
|
|
961
|
+
createConfigDiagnostic("design_system_manifest_not_found", message, [
|
|
962
|
+
`Install ${JSON.stringify(spec)}, or build it with \`panda lib\` if it is a Panda design system.`
|
|
963
|
+
])
|
|
964
|
+
]);
|
|
965
|
+
}
|
|
966
|
+
function parentNotResolvedError(child, parent) {
|
|
967
|
+
const message = `designSystem ${JSON.stringify(child)} extends ${JSON.stringify(parent)}, which isn't installed alongside it. Install it where ${JSON.stringify(child)} can resolve it, or rebuild that library with \`panda lib\`.`;
|
|
968
|
+
return createConfigError(message, [
|
|
969
|
+
createConfigDiagnostic("design_system_parent_not_found", message, [
|
|
970
|
+
`Install ${JSON.stringify(parent)} where ${JSON.stringify(child)} can resolve it, or rebuild ${JSON.stringify(child)} with \`panda lib\`.`
|
|
971
|
+
])
|
|
972
|
+
]);
|
|
973
|
+
}
|
|
974
|
+
function cycleError(cycle) {
|
|
975
|
+
const message = `Design-system cycle: ${cycle.join(" \u2192 ")}. A design system can't depend on itself.`;
|
|
976
|
+
return createConfigError(message, [createConfigDiagnostic("design_system_cycle", message)]);
|
|
977
|
+
}
|
|
978
|
+
function invalidManifestError(spec, manifestPath, issues) {
|
|
979
|
+
const message = `${JSON.stringify(spec)} manifest ${issues.join("; ")}.`;
|
|
980
|
+
return createConfigError(message, [
|
|
981
|
+
{
|
|
982
|
+
...createConfigDiagnostic("design_system_manifest_invalid", message, [
|
|
983
|
+
`Rebuild ${JSON.stringify(spec)} with \`panda lib\`.`
|
|
984
|
+
]),
|
|
985
|
+
file: manifestPath
|
|
68
986
|
}
|
|
69
|
-
|
|
987
|
+
]);
|
|
70
988
|
}
|
|
71
|
-
function
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const
|
|
989
|
+
function duplicateNameError(name, firstPath, secondPath) {
|
|
990
|
+
const message = `Two different packages in the design-system chain are both named ${JSON.stringify(name)} (${JSON.stringify(firstPath)} and ${JSON.stringify(secondPath)}). Their styles would overwrite each other; give each package a unique name.`;
|
|
991
|
+
return createConfigError(message, [createConfigDiagnostic("design_system_duplicate_name", message)]);
|
|
992
|
+
}
|
|
993
|
+
function specifierProtocol(spec) {
|
|
994
|
+
const match = spec.match(SPECIFIER_PROTOCOL);
|
|
995
|
+
return match ? match[1] : void 0;
|
|
996
|
+
}
|
|
997
|
+
function unsupportedSpecifierError(spec, protocol) {
|
|
998
|
+
const message = `designSystem ${JSON.stringify(spec)} uses the "${protocol}:" protocol, which isn't supported. Use the published package name (e.g. "@acme/design-system") that resolves to its \`panda/lib.json\`.`;
|
|
999
|
+
return createConfigError(message, [createConfigDiagnostic("design_system_unsupported_specifier", message)]);
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
// src/design-system/smart-include.ts
|
|
1003
|
+
import { existsSync as existsSync3 } from "fs";
|
|
1004
|
+
import { dirname as dirname5, isAbsolute as isAbsolute4, join as join3, relative as relative4, resolve as resolve5, sep } from "path";
|
|
1005
|
+
var SMART_INCLUDE_EXTENSIONS = ["js", "mjs", "cjs", "jsx", "ts", "cts", "mts", "tsx", "vue", "svelte", "astro"];
|
|
1006
|
+
var MANIFEST_SUBPATH = "panda/lib.json";
|
|
1007
|
+
var PACKAGE_SPECIFIER = /^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/i;
|
|
1008
|
+
function resolveSmartInclude(include, cwd, deps) {
|
|
1009
|
+
const offenders = [];
|
|
1010
|
+
const next = [];
|
|
1011
|
+
const excludes = [];
|
|
77
1012
|
let changed = false;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
changed = true;
|
|
1013
|
+
for (const entry of include) {
|
|
1014
|
+
if (!PACKAGE_SPECIFIER.test(entry)) {
|
|
1015
|
+
next.push(entry);
|
|
1016
|
+
continue;
|
|
83
1017
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
1018
|
+
if (isLocalPath(entry, cwd)) {
|
|
1019
|
+
next.push(entry);
|
|
1020
|
+
continue;
|
|
1021
|
+
}
|
|
1022
|
+
if (tryResolveFrom(`${entry}/${MANIFEST_SUBPATH}`, cwd) !== void 0) {
|
|
1023
|
+
offenders.push(entry);
|
|
1024
|
+
continue;
|
|
1025
|
+
}
|
|
1026
|
+
const packageDir = resolvePackageDir(entry, cwd);
|
|
1027
|
+
if (packageDir === void 0) {
|
|
1028
|
+
next.push(entry);
|
|
1029
|
+
continue;
|
|
1030
|
+
}
|
|
1031
|
+
if (existsSync3(join3(packageDir, ...MANIFEST_SUBPATH.split("/")))) {
|
|
1032
|
+
offenders.push(entry);
|
|
1033
|
+
continue;
|
|
1034
|
+
}
|
|
1035
|
+
deps.add(join3(packageDir, "package.json"));
|
|
1036
|
+
const base = globBase(packageDir, cwd);
|
|
1037
|
+
next.push(`${base}/**/*.{${SMART_INCLUDE_EXTENSIONS.join(",")}}`);
|
|
1038
|
+
excludes.push(`${base}/**/node_modules/**`);
|
|
1039
|
+
changed = true;
|
|
1040
|
+
}
|
|
1041
|
+
if (offenders.length > 0) throw inIncludeError(offenders);
|
|
1042
|
+
return { include: changed ? next : include, excludes, changed };
|
|
91
1043
|
}
|
|
92
|
-
function
|
|
93
|
-
|
|
1044
|
+
function expandSmartInclude(config, cwd, deps) {
|
|
1045
|
+
if (!config.include || config.include.length === 0) return config;
|
|
1046
|
+
const resolved = resolveSmartInclude(config.include, cwd, deps);
|
|
1047
|
+
if (!resolved.changed) return config;
|
|
1048
|
+
return { ...config, include: resolved.include, exclude: mergeExcludes(config.exclude, resolved.excludes) };
|
|
94
1049
|
}
|
|
95
|
-
function
|
|
96
|
-
return
|
|
1050
|
+
function mergeExcludes(existing, additions) {
|
|
1051
|
+
return [...existing ?? [], ...additions];
|
|
97
1052
|
}
|
|
98
|
-
function
|
|
99
|
-
return
|
|
1053
|
+
function isLocalPath(entry, cwd) {
|
|
1054
|
+
return existsSync3(isAbsolute4(entry) ? entry : resolve5(cwd, entry));
|
|
100
1055
|
}
|
|
101
|
-
function
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
if (item.type !== "chunk") continue;
|
|
107
|
-
Object.keys(item.modules ?? {}).forEach((id) => {
|
|
108
|
-
if (isAbsolute(id)) add(id);
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
if (isAbsolute(entry)) add(entry);
|
|
112
|
-
return Array.from(dependencies);
|
|
1056
|
+
function resolvePackageDir(spec, cwd) {
|
|
1057
|
+
const fromPackageJson = tryResolve(`${spec}/package.json`, cwd);
|
|
1058
|
+
if (fromPackageJson !== void 0) return dirname5(fromPackageJson);
|
|
1059
|
+
const fromEntry = tryResolve(spec, cwd);
|
|
1060
|
+
return fromEntry === void 0 ? void 0 : nearestPackageDir(fromEntry);
|
|
113
1061
|
}
|
|
114
|
-
function
|
|
1062
|
+
function tryResolve(request, cwd) {
|
|
115
1063
|
try {
|
|
116
|
-
return
|
|
117
|
-
} catch {
|
|
118
|
-
|
|
1064
|
+
return tryResolveFrom(request, cwd);
|
|
1065
|
+
} catch (error) {
|
|
1066
|
+
const message = `Failed to resolve include package ${JSON.stringify(request)} from ${JSON.stringify(cwd)}: ${errorMessage(error)}`;
|
|
1067
|
+
throw createConfigError(message, [createConfigDiagnostic("include_package_resolution_failed", message)]);
|
|
119
1068
|
}
|
|
120
1069
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
"panda.config.mts",
|
|
129
|
-
"panda.config.mjs",
|
|
130
|
-
"panda.config.cts",
|
|
131
|
-
"panda.config.cjs"
|
|
132
|
-
]);
|
|
133
|
-
var isPandaConfig = (file) => configFiles.has(file);
|
|
134
|
-
function findUp(cwd) {
|
|
135
|
-
let dir = resolve(cwd);
|
|
1070
|
+
function isInsideCwd(relativePath) {
|
|
1071
|
+
if (relativePath === "" || relativePath === "..") return false;
|
|
1072
|
+
if (isAbsolute4(relativePath)) return false;
|
|
1073
|
+
return !relativePath.startsWith(`..${sep}`);
|
|
1074
|
+
}
|
|
1075
|
+
function nearestPackageDir(from) {
|
|
1076
|
+
let dir = dirname5(from);
|
|
136
1077
|
while (true) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
entries = readdirSync(dir);
|
|
140
|
-
} catch {
|
|
141
|
-
entries = [];
|
|
142
|
-
}
|
|
143
|
-
const match = entries.find(isPandaConfig);
|
|
144
|
-
if (match) return resolve(dir, match);
|
|
145
|
-
const parent = dirname(dir);
|
|
1078
|
+
if (existsSync3(join3(dir, "package.json"))) return dir;
|
|
1079
|
+
const parent = dirname5(dir);
|
|
146
1080
|
if (parent === dir) return void 0;
|
|
147
1081
|
dir = parent;
|
|
148
1082
|
}
|
|
149
1083
|
}
|
|
150
|
-
function
|
|
151
|
-
const
|
|
152
|
-
|
|
153
|
-
|
|
1084
|
+
function globBase(packageDir, cwd) {
|
|
1085
|
+
const rel = relative4(cwd, packageDir);
|
|
1086
|
+
const base = isInsideCwd(rel) ? rel : packageDir;
|
|
1087
|
+
return toPosixPath(base);
|
|
1088
|
+
}
|
|
1089
|
+
function inIncludeError(specs) {
|
|
1090
|
+
const list = specs.map((spec) => JSON.stringify(spec)).join(", ");
|
|
1091
|
+
const plural = specs.length > 1;
|
|
1092
|
+
const message = `Design system${plural ? "s" : ""} in \`include\`: ${list}. ${plural ? "They each ship" : "It ships"} a ${MANIFEST_SUBPATH}, so ${plural ? "they belong" : "it belongs"} in \`designSystem\`, not \`include\`. \`include\` is for files, not design systems.`;
|
|
1093
|
+
return createConfigError(
|
|
1094
|
+
message,
|
|
1095
|
+
specs.map(
|
|
1096
|
+
(spec) => createConfigDiagnostic(
|
|
1097
|
+
"design_system_in_include",
|
|
1098
|
+
`Design system ${JSON.stringify(spec)} is listed in \`include\`. Move it to \`designSystem\`; \`include\` is for files, not design systems.`,
|
|
1099
|
+
[`Move ${JSON.stringify(spec)} to \`designSystem\`.`]
|
|
1100
|
+
)
|
|
1101
|
+
)
|
|
1102
|
+
);
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
// src/design-system/token-paths.ts
|
|
1106
|
+
import { isDeepStrictEqual } from "util";
|
|
1107
|
+
function collectTokenPaths(config) {
|
|
1108
|
+
return [...collectTokenEntries(config).keys()].sort();
|
|
1109
|
+
}
|
|
1110
|
+
function collectTokenEntries(config) {
|
|
1111
|
+
const entries = /* @__PURE__ */ new Map();
|
|
1112
|
+
if (!isPlainObject(config?.theme)) {
|
|
1113
|
+
return entries;
|
|
154
1114
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
1115
|
+
collect(config.theme.tokens, [], entries);
|
|
1116
|
+
collect(config.theme.semanticTokens, [], entries);
|
|
1117
|
+
return entries;
|
|
1118
|
+
}
|
|
1119
|
+
function resolveUserTokenPathsAfterHooks(userTokenPaths, beforeHooks, afterHooks) {
|
|
1120
|
+
const paths = new Set(userTokenPaths);
|
|
1121
|
+
const after = collectTokenEntries(afterHooks);
|
|
1122
|
+
for (const path of paths) {
|
|
1123
|
+
if (!after.has(path)) {
|
|
1124
|
+
paths.delete(path);
|
|
1125
|
+
}
|
|
161
1126
|
}
|
|
162
|
-
|
|
1127
|
+
for (const [path, values] of after) {
|
|
1128
|
+
if (!beforeHooks.has(path) || !isDeepStrictEqual(beforeHooks.get(path), values)) {
|
|
1129
|
+
paths.add(path);
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
return [...paths].sort();
|
|
1133
|
+
}
|
|
1134
|
+
function collect(node, trail, out) {
|
|
1135
|
+
if (!isPlainObject(node)) {
|
|
1136
|
+
return;
|
|
1137
|
+
}
|
|
1138
|
+
if ("value" in node) {
|
|
1139
|
+
if (trail.length > 0) {
|
|
1140
|
+
const path = trail.join(".");
|
|
1141
|
+
const entries = out.get(path) ?? [];
|
|
1142
|
+
entries.push(node.value);
|
|
1143
|
+
out.set(path, entries);
|
|
1144
|
+
}
|
|
1145
|
+
return;
|
|
1146
|
+
}
|
|
1147
|
+
for (const [key, child] of Object.entries(node)) {
|
|
1148
|
+
collect(child, [...trail, key], out);
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
// src/artifact-names.ts
|
|
1153
|
+
function collectRecipeNames(config) {
|
|
1154
|
+
const theme = config?.theme;
|
|
1155
|
+
if (!theme) return [];
|
|
1156
|
+
const names = /* @__PURE__ */ new Set([...Object.keys(theme.recipes ?? {}), ...Object.keys(theme.slotRecipes ?? {})]);
|
|
1157
|
+
return [...names].sort();
|
|
1158
|
+
}
|
|
1159
|
+
function collectPatternNames(config) {
|
|
1160
|
+
return Object.keys(config?.patterns ?? {}).sort();
|
|
163
1161
|
}
|
|
164
1162
|
|
|
165
1163
|
// src/preset.ts
|
|
166
|
-
|
|
167
|
-
|
|
1164
|
+
async function resolveAuthoredPresetsForLoad(config, cwd, options = {}) {
|
|
1165
|
+
const designSystem = config.designSystem;
|
|
1166
|
+
const hasDesignSystem = typeof designSystem === "string" && designSystem.length > 0;
|
|
1167
|
+
const trackSources = options.trackSources ?? hasDesignSystem;
|
|
168
1168
|
const ctx = {
|
|
169
1169
|
cwd,
|
|
170
1170
|
configs: [],
|
|
171
1171
|
dependencies: /* @__PURE__ */ new Set(),
|
|
172
1172
|
presetResolvedHooks: [],
|
|
173
|
-
...
|
|
1173
|
+
...trackSources ? { sourcedConfigs: [] } : {}
|
|
174
1174
|
};
|
|
175
1175
|
const rootSource = { kind: "config" };
|
|
176
|
-
if (options.configFile)
|
|
177
|
-
|
|
1176
|
+
if (options.configFile) {
|
|
1177
|
+
rootSource.file = normalize2(relative5(cwd, options.configFile));
|
|
1178
|
+
}
|
|
1179
|
+
let dsChain = [];
|
|
1180
|
+
const designSystemCompatibility = [];
|
|
1181
|
+
if (hasDesignSystem) {
|
|
1182
|
+
dsChain = await loadDesignSystemChain(designSystem, cwd, ctx.dependencies);
|
|
1183
|
+
for (const level of dsChain) {
|
|
1184
|
+
const dsSource = { kind: "preset", specifier: level.info.name, name: level.info.name };
|
|
1185
|
+
const resolution = await resolveConfigEntry(level.preset, dsSource, cwd, ctx.dependencies, trackSources);
|
|
1186
|
+
if (resolution.sourcedConfigs) {
|
|
1187
|
+
for (const sourced of resolution.sourcedConfigs) {
|
|
1188
|
+
sourced.source = dsSource;
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
level.info.tokenPaths = collectTokenPaths(resolution.config);
|
|
1192
|
+
level.info.recipeNames = collectRecipeNames(resolution.config);
|
|
1193
|
+
level.info.patternNames = collectPatternNames(resolution.config);
|
|
1194
|
+
appendConfigResolution(ctx, resolution);
|
|
1195
|
+
designSystemCompatibility.push({
|
|
1196
|
+
designSystem: level.info,
|
|
1197
|
+
classNameOptions: normalizeClassNameOptions(mergeConfigs(ctx.configs)),
|
|
1198
|
+
presetConfig: resolution.config
|
|
1199
|
+
});
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
const rootResolution = await resolveConfigEntry(config, rootSource, cwd, ctx.dependencies, trackSources);
|
|
1203
|
+
appendConfigResolution(ctx, rootResolution);
|
|
1204
|
+
for (const { designSystem: designSystem2, classNameOptions } of designSystemCompatibility) {
|
|
1205
|
+
const mismatch = diffClassNameOptions(rootResolution.config, classNameOptions, "explicit");
|
|
1206
|
+
if (mismatch.length > 0) {
|
|
1207
|
+
designSystem2.optionMismatch = mismatch;
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
const dsInfos = dsChain.map((level) => level.info);
|
|
1211
|
+
const finalize = (resolved) => {
|
|
1212
|
+
const withImportMap = dsInfos.length > 0 ? withDesignSystemImportMap(resolved, dsInfos) : resolved;
|
|
1213
|
+
return expandSmartInclude(withImportMap, cwd, ctx.dependencies);
|
|
1214
|
+
};
|
|
1215
|
+
const leafCompatibility = designSystemCompatibility[designSystemCompatibility.length - 1];
|
|
178
1216
|
if (ctx.sourcedConfigs) {
|
|
179
1217
|
const merged = mergeConfigsWithSources(ctx.sourcedConfigs);
|
|
180
|
-
if (options.preserveRuntimeHooks)
|
|
1218
|
+
if (options.preserveRuntimeHooks) {
|
|
1219
|
+
attachRuntimeHooks(merged.config, ctx.configs);
|
|
1220
|
+
}
|
|
1221
|
+
const finalized2 = finalize(merged.config);
|
|
1222
|
+
let overlayInput;
|
|
1223
|
+
if (leafCompatibility) {
|
|
1224
|
+
const input = buildOverlayInput(merged.sources, finalized2, dsInfos, leafCompatibility.presetConfig, cwd);
|
|
1225
|
+
const leafClassMismatch = leafCompatibility.designSystem.optionMismatch ?? [];
|
|
1226
|
+
overlayInput = {
|
|
1227
|
+
authored: input.authored,
|
|
1228
|
+
compatible: input.compatible && leafClassMismatch.length === 0
|
|
1229
|
+
};
|
|
1230
|
+
}
|
|
1231
|
+
const dsMetadata2 = dsInfos.length > 0 ? {
|
|
1232
|
+
designSystem: dsInfos,
|
|
1233
|
+
userTokenPaths: collectTokenPaths(rootResolution.config),
|
|
1234
|
+
userRecipeNames: collectRecipeNames(rootResolution.config),
|
|
1235
|
+
userPatternNames: collectPatternNames(rootResolution.config),
|
|
1236
|
+
...overlayInput ? { overlayInput } : {}
|
|
1237
|
+
} : void 0;
|
|
181
1238
|
return {
|
|
182
|
-
config:
|
|
1239
|
+
config: finalized2,
|
|
183
1240
|
dependencies: Array.from(ctx.dependencies),
|
|
184
|
-
metadata: { sources: merged.sources }
|
|
1241
|
+
metadata: { sources: merged.sources, ...dsMetadata2 },
|
|
1242
|
+
designSystemCompatibility
|
|
185
1243
|
};
|
|
186
1244
|
}
|
|
1245
|
+
const mergedConfig = options.preserveRuntimeHooks ? attachRuntimeHooks(mergeConfigs(ctx.configs), ctx.configs) : mergeConfigs(ctx.configs);
|
|
1246
|
+
const finalized = finalize(mergedConfig);
|
|
1247
|
+
const dsMetadata = dsInfos.length > 0 ? {
|
|
1248
|
+
designSystem: dsInfos,
|
|
1249
|
+
userTokenPaths: collectTokenPaths(rootResolution.config),
|
|
1250
|
+
userRecipeNames: collectRecipeNames(rootResolution.config),
|
|
1251
|
+
userPatternNames: collectPatternNames(rootResolution.config)
|
|
1252
|
+
} : void 0;
|
|
187
1253
|
return {
|
|
188
|
-
config:
|
|
189
|
-
dependencies: Array.from(ctx.dependencies)
|
|
1254
|
+
config: finalized,
|
|
1255
|
+
dependencies: Array.from(ctx.dependencies),
|
|
1256
|
+
...dsMetadata ? { metadata: dsMetadata } : {},
|
|
1257
|
+
designSystemCompatibility
|
|
190
1258
|
};
|
|
191
1259
|
}
|
|
192
|
-
function
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
config.plugins = plugins;
|
|
1260
|
+
async function resolveConfigEntry(config, source, cwd, dependencies, trackSources) {
|
|
1261
|
+
const ctx = {
|
|
1262
|
+
cwd,
|
|
1263
|
+
configs: [],
|
|
1264
|
+
dependencies,
|
|
1265
|
+
presetResolvedHooks: [],
|
|
1266
|
+
...trackSources ? { sourcedConfigs: [] } : {}
|
|
1267
|
+
};
|
|
1268
|
+
await collectConfigs(config, source, ctx, /* @__PURE__ */ new WeakSet());
|
|
1269
|
+
return {
|
|
1270
|
+
configs: ctx.configs,
|
|
1271
|
+
...ctx.sourcedConfigs ? { sourcedConfigs: ctx.sourcedConfigs } : {},
|
|
1272
|
+
config: mergeConfigs(ctx.configs)
|
|
1273
|
+
};
|
|
1274
|
+
}
|
|
1275
|
+
function appendConfigResolution(ctx, resolution) {
|
|
1276
|
+
ctx.configs.push(...resolution.configs);
|
|
1277
|
+
if (ctx.sourcedConfigs && resolution.sourcedConfigs) {
|
|
1278
|
+
ctx.sourcedConfigs.push(...resolution.sourcedConfigs);
|
|
212
1279
|
}
|
|
213
|
-
return config;
|
|
214
1280
|
}
|
|
215
1281
|
async function collectConfigs(config, source, ctx, active) {
|
|
216
1282
|
if (active.has(config)) {
|
|
@@ -238,7 +1304,7 @@ async function runPresetResolvedHooks(preset, source, hooks) {
|
|
|
238
1304
|
const name = source.name ?? source.specifier ?? presetName(current) ?? "unknown-preset";
|
|
239
1305
|
for (const entry of hooks) {
|
|
240
1306
|
const hook = normalizeHook(entry.value, "preset:resolved");
|
|
241
|
-
const next = await hook.handler({ preset: current, name });
|
|
1307
|
+
const next = await hook.handler({ preset: current, name, utils: configResolvedUtils });
|
|
242
1308
|
if (next !== void 0) {
|
|
243
1309
|
current = ensureConfigObject(next, name);
|
|
244
1310
|
}
|
|
@@ -256,10 +1322,7 @@ async function resolvePreset(preset, cwd) {
|
|
|
256
1322
|
};
|
|
257
1323
|
} catch (error) {
|
|
258
1324
|
if (error instanceof PandaError) throw error;
|
|
259
|
-
throw
|
|
260
|
-
"CONFIG_ERROR",
|
|
261
|
-
`\u{1F4A5} Failed to resolve preset ${JSON.stringify(preset)}: ${errorMessage(error)}`
|
|
262
|
-
);
|
|
1325
|
+
throw presetResolutionError(JSON.stringify(preset), error);
|
|
263
1326
|
}
|
|
264
1327
|
}
|
|
265
1328
|
try {
|
|
@@ -271,12 +1334,12 @@ async function resolvePreset(preset, cwd) {
|
|
|
271
1334
|
};
|
|
272
1335
|
} catch (error) {
|
|
273
1336
|
if (error instanceof PandaError) throw error;
|
|
274
|
-
throw
|
|
1337
|
+
throw presetResolutionError('"unknown-preset"', error);
|
|
275
1338
|
}
|
|
276
1339
|
}
|
|
277
|
-
function
|
|
278
|
-
|
|
279
|
-
|
|
1340
|
+
function presetResolutionError(name, error) {
|
|
1341
|
+
const message = `Failed to resolve preset ${name}: ${errorMessage(error)}`;
|
|
1342
|
+
return createConfigError(message, [createConfigDiagnostic("preset_resolution_failed", message)]);
|
|
280
1343
|
}
|
|
281
1344
|
function presetName(config) {
|
|
282
1345
|
return isPlainObject(config) && typeof config.name === "string" ? config.name : void 0;
|
|
@@ -289,9 +1352,6 @@ function presetSource(config, specifier, file) {
|
|
|
289
1352
|
if (file) source.file = file;
|
|
290
1353
|
return source;
|
|
291
1354
|
}
|
|
292
|
-
function errorMessage(error) {
|
|
293
|
-
return error instanceof Error ? error.message : String(error);
|
|
294
|
-
}
|
|
295
1355
|
|
|
296
1356
|
// src/load.ts
|
|
297
1357
|
async function loadConfig(options) {
|
|
@@ -301,7 +1361,7 @@ async function loadConfig(options) {
|
|
|
301
1361
|
if (!isPlainObject(config)) {
|
|
302
1362
|
throw new PandaError("CONFIG_ERROR", "\u{1F4A5} Config must export or return an object.");
|
|
303
1363
|
}
|
|
304
|
-
const authored = await
|
|
1364
|
+
const authored = await resolveAuthoredPresetsForLoad(config, cwd, {
|
|
305
1365
|
configFile: path,
|
|
306
1366
|
trackSources: options.trackSources,
|
|
307
1367
|
preserveRuntimeHooks: true
|
|
@@ -309,8 +1369,16 @@ async function loadConfig(options) {
|
|
|
309
1369
|
const authoredDependencies = Array.from(
|
|
310
1370
|
/* @__PURE__ */ new Set([...dependencies, ...authored.dependencies, ...authored.config.dependencies ?? []])
|
|
311
1371
|
);
|
|
1372
|
+
const tokenEntriesBeforeHooks = collectTokenEntries(authored.config);
|
|
312
1373
|
const userConfig = await runConfigResolvedHooks(authored.config, path, authoredDependencies);
|
|
313
|
-
const resolved =
|
|
1374
|
+
const resolved = applyConfigDefaults2(userConfig, cwd);
|
|
1375
|
+
refreshDesignSystemMetadata(
|
|
1376
|
+
authored.metadata,
|
|
1377
|
+
authored.designSystemCompatibility,
|
|
1378
|
+
resolved,
|
|
1379
|
+
tokenEntriesBeforeHooks,
|
|
1380
|
+
cwd
|
|
1381
|
+
);
|
|
314
1382
|
const dependencyList = Array.from(
|
|
315
1383
|
/* @__PURE__ */ new Set([...dependencies, ...authored.dependencies, ...resolved.dependencies ?? []])
|
|
316
1384
|
);
|
|
@@ -322,12 +1390,40 @@ async function loadConfig(options) {
|
|
|
322
1390
|
...snapshot.hooks ? { hooks: snapshot.hooks } : {},
|
|
323
1391
|
hostHooks: {
|
|
324
1392
|
"codegen:prepare": collectPluginHookHandlers(resolved, "codegen:prepare"),
|
|
325
|
-
"codegen:done": collectPluginHookHandlers(resolved, "codegen:done")
|
|
1393
|
+
"codegen:done": collectPluginHookHandlers(resolved, "codegen:done"),
|
|
1394
|
+
"cssgen:done": collectPluginHookHandlers(resolved, "cssgen:done")
|
|
326
1395
|
},
|
|
327
1396
|
dependencies: dependencyList,
|
|
328
1397
|
...authored.metadata ? { metadata: authored.metadata } : {}
|
|
329
1398
|
};
|
|
330
1399
|
}
|
|
1400
|
+
function refreshDesignSystemMetadata(metadata, designSystemCompatibility, config, tokenEntriesBeforeHooks, cwd) {
|
|
1401
|
+
if (!metadata?.designSystem?.length) return;
|
|
1402
|
+
metadata.userTokenPaths = resolveUserTokenPathsAfterHooks(
|
|
1403
|
+
metadata.userTokenPaths ?? [],
|
|
1404
|
+
tokenEntriesBeforeHooks,
|
|
1405
|
+
config
|
|
1406
|
+
);
|
|
1407
|
+
const chain = metadata.designSystem;
|
|
1408
|
+
const sources = metadata.sources;
|
|
1409
|
+
const leaf = designSystemCompatibility[designSystemCompatibility.length - 1];
|
|
1410
|
+
for (const { designSystem, classNameOptions } of designSystemCompatibility) {
|
|
1411
|
+
const mismatch = diffClassNameOptions(config, classNameOptions, "effective");
|
|
1412
|
+
if (mismatch.length > 0) {
|
|
1413
|
+
designSystem.optionMismatch = mismatch;
|
|
1414
|
+
} else {
|
|
1415
|
+
delete designSystem.optionMismatch;
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
if (sources && leaf) {
|
|
1419
|
+
const input = buildOverlayInput(sources, config, chain, leaf.presetConfig, cwd);
|
|
1420
|
+
const leafClassMismatch = leaf.designSystem.optionMismatch ?? [];
|
|
1421
|
+
metadata.overlayInput = {
|
|
1422
|
+
authored: input.authored,
|
|
1423
|
+
compatible: input.compatible && leafClassMismatch.length === 0
|
|
1424
|
+
};
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
331
1427
|
async function runConfigResolvedHooks(config, path, dependencies) {
|
|
332
1428
|
let current = config;
|
|
333
1429
|
for (const entry of collectPluginHookHandlers(current, "config:resolved")) {
|
|
@@ -342,89 +1438,6 @@ async function runConfigResolvedHooks(config, path, dependencies) {
|
|
|
342
1438
|
}
|
|
343
1439
|
return current;
|
|
344
1440
|
}
|
|
345
|
-
var configResolvedUtils = {
|
|
346
|
-
omit(obj, paths) {
|
|
347
|
-
const clone = cloneValue(obj);
|
|
348
|
-
for (const path of paths) {
|
|
349
|
-
deleteAtPath(clone, path);
|
|
350
|
-
}
|
|
351
|
-
return clone;
|
|
352
|
-
},
|
|
353
|
-
pick(obj, paths) {
|
|
354
|
-
const result = {};
|
|
355
|
-
for (const path of paths) {
|
|
356
|
-
const value = getAtPath(obj, path);
|
|
357
|
-
if (value !== void 0) {
|
|
358
|
-
setAtPath(result, path, value);
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
return result;
|
|
362
|
-
},
|
|
363
|
-
traverse(obj, callback, options = {}) {
|
|
364
|
-
traverseValue(obj, callback, options);
|
|
365
|
-
}
|
|
366
|
-
};
|
|
367
|
-
function cloneValue(value) {
|
|
368
|
-
if (Array.isArray(value)) return value.map((item) => cloneValue(item));
|
|
369
|
-
if (!isPlainObject(value)) return value;
|
|
370
|
-
return Object.fromEntries(
|
|
371
|
-
Object.entries(value).map(([key, child]) => [key, cloneValue(child)])
|
|
372
|
-
);
|
|
373
|
-
}
|
|
374
|
-
function pathParts(path) {
|
|
375
|
-
return path.split(".").filter(Boolean);
|
|
376
|
-
}
|
|
377
|
-
function getAtPath(value, path) {
|
|
378
|
-
let current = value;
|
|
379
|
-
for (const part of pathParts(path)) {
|
|
380
|
-
if (!isPlainObject(current) && !Array.isArray(current)) return void 0;
|
|
381
|
-
current = current[part];
|
|
382
|
-
}
|
|
383
|
-
return current;
|
|
384
|
-
}
|
|
385
|
-
function setAtPath(target, path, value) {
|
|
386
|
-
const parts = pathParts(path);
|
|
387
|
-
let current = target;
|
|
388
|
-
parts.forEach((part, index) => {
|
|
389
|
-
if (index === parts.length - 1) {
|
|
390
|
-
current[part] = cloneValue(value);
|
|
391
|
-
return;
|
|
392
|
-
}
|
|
393
|
-
const next = current[part];
|
|
394
|
-
if (!isPlainObject(next)) {
|
|
395
|
-
current[part] = {};
|
|
396
|
-
}
|
|
397
|
-
current = current[part];
|
|
398
|
-
});
|
|
399
|
-
}
|
|
400
|
-
function deleteAtPath(target, path) {
|
|
401
|
-
const parts = pathParts(path);
|
|
402
|
-
const key = parts.pop();
|
|
403
|
-
if (!key) return;
|
|
404
|
-
let current = target;
|
|
405
|
-
for (const part of parts) {
|
|
406
|
-
if (!isPlainObject(current) && !Array.isArray(current)) return;
|
|
407
|
-
current = current[part];
|
|
408
|
-
}
|
|
409
|
-
if (isPlainObject(current) || Array.isArray(current)) {
|
|
410
|
-
delete current[key];
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
function traverseValue(value, callback, options, parent, key, path = "", depth = 0) {
|
|
414
|
-
if (parent && key !== void 0) {
|
|
415
|
-
callback({ value, path, depth, parent, key });
|
|
416
|
-
}
|
|
417
|
-
if (options.maxDepth !== void 0 && depth >= options.maxDepth) return;
|
|
418
|
-
if (!isPlainObject(value) && !Array.isArray(value)) return;
|
|
419
|
-
const separator = options.separator ?? ".";
|
|
420
|
-
const container = value;
|
|
421
|
-
Object.entries(value).forEach(([childKey, child]) => {
|
|
422
|
-
traverseValue(child, callback, options, container, childKey, joinPath(path, childKey, separator), depth + 1);
|
|
423
|
-
});
|
|
424
|
-
}
|
|
425
|
-
function joinPath(parent, key, separator) {
|
|
426
|
-
return parent ? `${parent}${separator}${key}` : key;
|
|
427
|
-
}
|
|
428
1441
|
|
|
429
1442
|
// src/diff.ts
|
|
430
1443
|
import diff from "microdiff";
|
|
@@ -530,11 +1543,118 @@ function diffInput(input) {
|
|
|
530
1543
|
function isConfigSnapshot(input) {
|
|
531
1544
|
return !!input && typeof input === "object" && !Array.isArray(input) && ("callbacks" in input || "hooks" in input) && "config" in input && !!input.config && typeof input.config === "object" && !Array.isArray(input.config);
|
|
532
1545
|
}
|
|
1546
|
+
|
|
1547
|
+
// src/version.ts
|
|
1548
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
1549
|
+
import { dirname as dirname6, join as join4 } from "path";
|
|
1550
|
+
import { fileURLToPath } from "url";
|
|
1551
|
+
var MAJOR_VERSION_RE = /\d+/;
|
|
1552
|
+
var STAMPABLE_PANDA_RANGE_RE = /^[v=><~^]|^\d/;
|
|
1553
|
+
function readPandaVersion() {
|
|
1554
|
+
try {
|
|
1555
|
+
const pkgPath = join4(dirname6(fileURLToPath(import.meta.url)), "../package.json");
|
|
1556
|
+
return JSON.parse(readFileSync3(pkgPath, "utf8")).version;
|
|
1557
|
+
} catch {
|
|
1558
|
+
return void 0;
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
function getPandaMajorRange() {
|
|
1562
|
+
const match = readPandaVersion()?.match(MAJOR_VERSION_RE);
|
|
1563
|
+
return match ? `^${match[0]}.0.0` : void 0;
|
|
1564
|
+
}
|
|
1565
|
+
function isStampablePandaRange(range) {
|
|
1566
|
+
return range !== void 0 && STAMPABLE_PANDA_RANGE_RE.test(range.trim());
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1569
|
+
// src/design-system/compile-preset.ts
|
|
1570
|
+
import { builtinModules as builtinModules2 } from "module";
|
|
1571
|
+
var APP_FIELDS = ["designSystem", "include", "exclude", "outdir", "cwd", "watch", "clean", "gitignore", "importMap"];
|
|
1572
|
+
var VIRTUAL_ENTRY = "\0panda-lib-preset-entry";
|
|
1573
|
+
var nodeBuiltins2 = /* @__PURE__ */ new Set([...builtinModules2, ...builtinModules2.map((mod) => `node:${mod}`)]);
|
|
1574
|
+
async function compilePreset(options) {
|
|
1575
|
+
const { configPath, cwd } = options;
|
|
1576
|
+
const { rolldown } = await import("rolldown");
|
|
1577
|
+
const build = await rolldown({
|
|
1578
|
+
input: VIRTUAL_ENTRY,
|
|
1579
|
+
cwd,
|
|
1580
|
+
platform: "node",
|
|
1581
|
+
external: (id) => nodeBuiltins2.has(id),
|
|
1582
|
+
treeshake: true,
|
|
1583
|
+
plugins: [importMetaUrlPlugin(), presetEntryPlugin(configPath)]
|
|
1584
|
+
});
|
|
1585
|
+
let chunks;
|
|
1586
|
+
try {
|
|
1587
|
+
chunks = await build.generate({ format: "esm", exports: "named", codeSplitting: false });
|
|
1588
|
+
} finally {
|
|
1589
|
+
await build.close?.();
|
|
1590
|
+
}
|
|
1591
|
+
const output = chunks.output.find((item) => item.type === "chunk");
|
|
1592
|
+
if (!output || output.type !== "chunk") {
|
|
1593
|
+
throw new PandaError("CONFIG_ERROR", "\u{1F4A5} Preset bundle did not produce an executable module.");
|
|
1594
|
+
}
|
|
1595
|
+
await validatePreset(output.code);
|
|
1596
|
+
const dependencies = Object.keys(output.modules ?? {}).filter((id) => id !== VIRTUAL_ENTRY);
|
|
1597
|
+
return { code: output.code, dependencies };
|
|
1598
|
+
}
|
|
1599
|
+
function presetEntryPlugin(configPath) {
|
|
1600
|
+
return {
|
|
1601
|
+
name: "panda-lib-preset-entry",
|
|
1602
|
+
resolveId(id) {
|
|
1603
|
+
return id === VIRTUAL_ENTRY ? VIRTUAL_ENTRY : null;
|
|
1604
|
+
},
|
|
1605
|
+
load(id) {
|
|
1606
|
+
if (id !== VIRTUAL_ENTRY) return null;
|
|
1607
|
+
const fields = APP_FIELDS.join(", ");
|
|
1608
|
+
return `import __panda_lib_config from ${JSON.stringify(configPath)}
|
|
1609
|
+
const __panda_lib_resolved = await __panda_lib_config
|
|
1610
|
+
if (!${isPlainObjectSource()}(__panda_lib_resolved)) throw new Error('Config must export or return an object.')
|
|
1611
|
+
const { ${fields}, ...preset } = __panda_lib_resolved
|
|
1612
|
+
export default preset
|
|
1613
|
+
`;
|
|
1614
|
+
}
|
|
1615
|
+
};
|
|
1616
|
+
}
|
|
1617
|
+
function isPlainObjectSource() {
|
|
1618
|
+
return `((value) => {
|
|
1619
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) return false
|
|
1620
|
+
const proto = Object.getPrototypeOf(value)
|
|
1621
|
+
return proto === Object.prototype || proto === null
|
|
1622
|
+
})`;
|
|
1623
|
+
}
|
|
1624
|
+
async function validatePreset(code) {
|
|
1625
|
+
try {
|
|
1626
|
+
await import(`data:text/javascript;base64,${Buffer.from(code).toString("base64")}`);
|
|
1627
|
+
} catch (error) {
|
|
1628
|
+
throw new PandaError("CONFIG_ERROR", `\u{1F4A5} Failed to compile design system preset: ${errorMessage(error)}`);
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
533
1631
|
export {
|
|
1632
|
+
buildCodegenOverlay,
|
|
534
1633
|
bundleConfig,
|
|
1634
|
+
collectArtifactConflicts,
|
|
1635
|
+
collectExportMissingDiagnostics,
|
|
1636
|
+
collectNameCollisionDiagnostics,
|
|
1637
|
+
collectPatternNames,
|
|
1638
|
+
collectRecipeNames,
|
|
1639
|
+
collectTokenPaths,
|
|
1640
|
+
compilePreset,
|
|
535
1641
|
createConfigSnapshot,
|
|
1642
|
+
defaultImportMap,
|
|
536
1643
|
diffConfig,
|
|
1644
|
+
filterPublishableLibFiles,
|
|
537
1645
|
findConfig,
|
|
1646
|
+
getPandaMajorRange,
|
|
1647
|
+
isStampablePandaRange,
|
|
538
1648
|
loadConfig,
|
|
539
|
-
mergeConfigs
|
|
1649
|
+
mergeConfigs,
|
|
1650
|
+
mergeExcludes,
|
|
1651
|
+
readPackageIdentity,
|
|
1652
|
+
readPandaVersion,
|
|
1653
|
+
readPublishFilesField,
|
|
1654
|
+
resolvePublishedPandaRange,
|
|
1655
|
+
resolveSmartInclude,
|
|
1656
|
+
syncExports,
|
|
1657
|
+
toPosixPath,
|
|
1658
|
+
toPosixRelative,
|
|
1659
|
+
toRelativeKey
|
|
540
1660
|
};
|