@pandacss/config 2.0.0-beta.7 → 2.0.0-beta.9

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.
@@ -1,27 +1,9 @@
1
- // src/error.ts
2
- var PandaError = class extends Error {
3
- code;
4
- hint;
5
- diagnostics;
6
- constructor(code, message, opts) {
7
- super(message, { cause: opts?.cause });
8
- this.code = `ERR_PANDA_${code}`;
9
- this.hint = opts?.hint;
10
- this.diagnostics = opts?.diagnostics;
11
- }
12
- };
13
- function createConfigError(message, diagnostics) {
14
- return new PandaError("CONFIG_ERROR", `\u{1F4A5} ${message}`, { diagnostics });
15
- }
16
- function createConfigDiagnostic(code, message, help) {
17
- return {
18
- code,
19
- message,
20
- severity: "error",
21
- category: "config",
22
- ...help ? { help } : {}
23
- };
24
- }
1
+ import {
2
+ PandaError,
3
+ clone,
4
+ isPlainObject,
5
+ omitKeys
6
+ } from "./chunk-R4R5RHIS.js";
25
7
 
26
8
  // src/sources.ts
27
9
  var sectionKeySet = /* @__PURE__ */ new Set([
@@ -36,7 +18,6 @@ var sectionKeySet = /* @__PURE__ */ new Set([
36
18
  "staticCss",
37
19
  "themes"
38
20
  ]);
39
- var omitKeys = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
40
21
  var tokenKeys = /* @__PURE__ */ new Set(["description", "extensions", "type", "value", "deprecated"]);
41
22
  var directFieldSections = /* @__PURE__ */ new Set(["patterns", "utilities"]);
42
23
  var themeEntryKeys = /* @__PURE__ */ new Set([
@@ -115,37 +96,6 @@ function shouldTrackThemePath(rest, value, current) {
115
96
  if (key === "containerNames" || key === "colorPalette") return rest.length <= 2;
116
97
  return rest.length <= 2;
117
98
  }
118
- function isPlainObject(value) {
119
- if (!value || typeof value !== "object" || Array.isArray(value)) return false;
120
- const proto = Object.getPrototypeOf(value);
121
- return proto === Object.prototype || proto === null;
122
- }
123
-
124
- // src/shared.ts
125
- var omitKeys2 = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
126
- function isPlainObject2(value) {
127
- if (!value || typeof value !== "object" || Array.isArray(value)) return false;
128
- const proto = Object.getPrototypeOf(value);
129
- return proto === Object.prototype || proto === null;
130
- }
131
- function clone(value) {
132
- if (Array.isArray(value)) return value.map((item) => clone(item));
133
- if (isPlainObject2(value)) {
134
- const result = {};
135
- for (const [key, item] of Object.entries(value)) {
136
- if (item !== void 0 && !omitKeys2.has(key)) result[key] = clone(item);
137
- }
138
- return result;
139
- }
140
- return value;
141
- }
142
- function ensureConfigObject(config, name) {
143
- if (isPlainObject2(config)) return config;
144
- throw new PandaError("CONFIG_ERROR", `\u{1F4A5} Preset ${JSON.stringify(name)} must resolve to an object.`);
145
- }
146
- function errorMessage(error) {
147
- return error instanceof Error ? error.message : String(error);
148
- }
149
99
 
150
100
  // src/merge.ts
151
101
  var sectionKeys = [
@@ -175,13 +125,13 @@ function mergeConfigs(configs, tracker) {
175
125
  const config = tracker ? configs[index].config : configs[index];
176
126
  const context = tracker ? { tracker, sourceId: index, path: [] } : void 0;
177
127
  for (const [key, value] of Object.entries(config)) {
178
- if (value === void 0 || sectionKeySet2.has(key) || runtimeOnlyKeys.has(key) || omitKeys2.has(key)) continue;
128
+ if (value === void 0 || sectionKeySet2.has(key) || runtimeOnlyKeys.has(key) || omitKeys.has(key)) continue;
179
129
  result[key] = clone(value);
180
130
  context?.tracker.record([key], context.sourceId, "replace");
181
131
  }
182
132
  for (const key of sectionKeys) {
183
133
  const section = config[key];
184
- if (isPlainObject2(section)) mergeSectionInto(key, sections[key], section, context);
134
+ if (isPlainObject(section)) mergeSectionInto(key, sections[key], section, context);
185
135
  }
186
136
  }
187
137
  for (const key of sectionKeys) {
@@ -193,15 +143,15 @@ function mergeConfigs(configs, tracker) {
193
143
  function mergeSectionInto(sectionName, target, section, context) {
194
144
  const childContext = context && { ...context, path: [sectionName] };
195
145
  for (const [key, value] of Object.entries(section)) {
196
- if (key === "extend" || value === void 0 || omitKeys2.has(key)) continue;
146
+ if (key === "extend" || value === void 0 || omitKeys.has(key)) continue;
197
147
  mergeValue(target, key, value, "replace", childContext);
198
148
  }
199
149
  if (section.extend === void 0) return;
200
- if (!isPlainObject2(section.extend)) {
150
+ if (!isPlainObject(section.extend)) {
201
151
  throw new PandaError("CONFIG_ERROR", `\u{1F4A5} Config section \`${sectionName}.extend\` must be an object.`);
202
152
  }
203
153
  for (const [key, value] of Object.entries(section.extend)) {
204
- if (value === void 0 || omitKeys2.has(key)) continue;
154
+ if (value === void 0 || omitKeys.has(key)) continue;
205
155
  mergeValue(target, key, value, "concat", childContext);
206
156
  }
207
157
  }
@@ -213,11 +163,11 @@ function mergeValue(target, key, value, arrayMode, context) {
213
163
  recordSource(context, path, value, current, arrayMode === "concat" ? "append" : "replace");
214
164
  return;
215
165
  }
216
- if (isPlainObject2(current) && isPlainObject2(value)) {
166
+ if (isPlainObject(current) && isPlainObject(value)) {
217
167
  recordSource(context, path, value, current, "append");
218
168
  const childContext = context && path ? { ...context, path } : void 0;
219
169
  for (const [childKey, childValue] of Object.entries(value)) {
220
- if (childValue !== void 0 && !omitKeys2.has(childKey))
170
+ if (childValue !== void 0 && !omitKeys.has(childKey))
221
171
  mergeValue(current, childKey, childValue, arrayMode, childContext);
222
172
  }
223
173
  return;
@@ -231,7 +181,7 @@ function normalizeNestedTokens(tokens, tracker) {
231
181
  while (stack.length > 0) {
232
182
  const current = stack.pop();
233
183
  for (const [key, value] of Object.entries(current.value)) {
234
- if (!isPlainObject2(value)) continue;
184
+ if (!isPlainObject(value)) continue;
235
185
  if (isValidToken(value)) {
236
186
  normalizeToken(value, tracker, current.path.concat(key));
237
187
  } else {
@@ -264,12 +214,6 @@ function isValidToken(token) {
264
214
  }
265
215
 
266
216
  export {
267
- PandaError,
268
- createConfigError,
269
- createConfigDiagnostic,
270
- isPlainObject2 as isPlainObject,
271
- ensureConfigObject,
272
- errorMessage,
273
217
  mergeConfigsWithSources,
274
218
  mergeConfigs
275
219
  };
@@ -0,0 +1,73 @@
1
+ // src/error.ts
2
+ var PandaError = class extends Error {
3
+ code;
4
+ hint;
5
+ diagnostics;
6
+ constructor(code, message, opts) {
7
+ super(message, { cause: opts?.cause });
8
+ this.code = `ERR_PANDA_${code}`;
9
+ this.hint = opts?.hint;
10
+ this.diagnostics = opts?.diagnostics;
11
+ }
12
+ };
13
+ function createConfigError(message, diagnostics) {
14
+ return new PandaError("CONFIG_ERROR", `\u{1F4A5} ${message}`, { diagnostics });
15
+ }
16
+ function createConfigDiagnostic(code, message, help) {
17
+ return {
18
+ code,
19
+ message,
20
+ severity: "error",
21
+ category: "config",
22
+ ...help ? { help } : {}
23
+ };
24
+ }
25
+
26
+ // src/shared.ts
27
+ var omitKeys = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
28
+ function isPlainObject(value) {
29
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
30
+ const proto = Object.getPrototypeOf(value);
31
+ return proto === Object.prototype || proto === null;
32
+ }
33
+ function clone(value) {
34
+ if (Array.isArray(value)) {
35
+ const len = value.length;
36
+ const out2 = new Array(len);
37
+ for (let i = 0; i < len; i++) out2[i] = clone(value[i]);
38
+ return out2;
39
+ }
40
+ if (!isPlainObject(value)) return value;
41
+ const source = value;
42
+ const out = {};
43
+ const keys = Object.keys(source);
44
+ for (let i = 0; i < keys.length; i++) {
45
+ const key = keys[i];
46
+ if (omitKeys.has(key)) continue;
47
+ const item = source[key];
48
+ if (item !== void 0) out[key] = clone(item);
49
+ }
50
+ return out;
51
+ }
52
+ function ensureConfigObject(config, name) {
53
+ if (isPlainObject(config)) return config;
54
+ throw new PandaError("CONFIG_ERROR", `\u{1F4A5} Preset ${JSON.stringify(name)} must resolve to an object.`);
55
+ }
56
+ function errorMessage(error) {
57
+ return error instanceof Error ? error.message : String(error);
58
+ }
59
+ function compact(value) {
60
+ return Object.fromEntries(Object.entries(value ?? {}).filter(([, item]) => item !== void 0));
61
+ }
62
+
63
+ export {
64
+ PandaError,
65
+ createConfigError,
66
+ createConfigDiagnostic,
67
+ omitKeys,
68
+ isPlainObject,
69
+ clone,
70
+ ensureConfigObject,
71
+ errorMessage,
72
+ compact
73
+ };
@@ -1,3 +1,7 @@
1
+ import {
2
+ compact
3
+ } from "./chunk-R4R5RHIS.js";
4
+
1
5
  // src/serialize.ts
2
6
  import {
3
7
  normalizeImportMap
@@ -5,7 +9,6 @@ import {
5
9
  import { stringify } from "javascript-stringify";
6
10
 
7
11
  // src/hooks.ts
8
- var compact = (value) => Object.fromEntries(Object.entries(value ?? {}).filter(([, item]) => item !== void 0));
9
12
  function serializeHooks(config, callbacks, sanitize2, hashCallbackSource2) {
10
13
  const parserBefore = collectPluginHookHandlers(config, "parser:before").map((entry, index) => {
11
14
  const hook = normalizeHook(entry.value, "parser:before");
@@ -47,7 +50,6 @@ function normalizeHook(value, name) {
47
50
  }
48
51
 
49
52
  // src/serialize.ts
50
- var compact2 = (value) => Object.fromEntries(Object.entries(value ?? {}).filter(([, item]) => item !== void 0));
51
53
  var runtimeOnlyKeys = /* @__PURE__ */ new Set(["hooks", "plugins", "presets", "name"]);
52
54
  function createConfigSnapshot(config) {
53
55
  const callbacks = {};
@@ -94,7 +96,7 @@ function attachPatternCodegenSource(serialized, config) {
94
96
  if (!patterns || !serializedPatterns) return;
95
97
  for (const [name, pattern] of Object.entries(patterns)) {
96
98
  if (typeof pattern?.transform !== "function") continue;
97
- const source = stringify(compact2({ transform: pattern.transform, defaultValues: pattern.defaultValues })) ?? "";
99
+ const source = stringify(compact({ transform: pattern.transform, defaultValues: pattern.defaultValues })) ?? "";
98
100
  if (serializedPatterns[name]) serializedPatterns[name].codegenSource = source;
99
101
  }
100
102
  }
package/dist/index.d.ts CHANGED
@@ -13,6 +13,7 @@ interface PluginHookEntry<Name extends keyof HookRegistry> {
13
13
  type HostHooks = {
14
14
  'codegen:prepare'?: Array<PluginHookEntry<'codegen:prepare'>>;
15
15
  'codegen:done'?: Array<PluginHookEntry<'codegen:done'>>;
16
+ 'cssgen:done'?: Array<PluginHookEntry<'cssgen:done'>>;
16
17
  };
17
18
 
18
19
  interface ResolvedDesignSystem {
@@ -24,6 +25,9 @@ interface ResolvedDesignSystem {
24
25
  files: string[];
25
26
  tokenPaths: string[];
26
27
  importMap?: DesignSystemManifest['importMap'];
28
+ /** Class-name options (`hash`/`prefix`/`separator`) the consumer overrode away
29
+ * from this design system's, which would break its prebuilt class names. */
30
+ optionMismatch?: string[];
27
31
  }
28
32
 
29
33
  interface LoadConfigOptions {
@@ -94,14 +98,6 @@ interface BundleConfigResult<T = Config> {
94
98
  */
95
99
  declare function bundleConfig<T extends Config = Config>(filepath: string, cwd: string): Promise<BundleConfigResult<T>>;
96
100
 
97
- interface SmartIncludeResult {
98
- include: string[];
99
- excludes: string[];
100
- changed: boolean;
101
- }
102
- declare function resolveSmartInclude(include: string[], cwd: string, deps: Set<string>): SmartIncludeResult;
103
- declare function mergeExcludes(existing: string[] | undefined, additions: string[]): string[];
104
-
105
101
  declare function readPandaVersion(): string | undefined;
106
102
 
107
103
  interface CompilePresetResult {
@@ -119,22 +115,59 @@ interface PackageIdentity {
119
115
  version?: string;
120
116
  pandaPeer?: string;
121
117
  packagePath: string;
118
+ /** package.json `"files"` when it's a string array; used for lib fallback publish checks. */
119
+ publishFiles?: string[];
122
120
  }
121
+ declare function resolvePublishedPandaRange(range: string | undefined, currentVersion: string | undefined): string;
123
122
  declare function readPackageIdentity(cwd: string): PackageIdentity;
124
123
  declare function defaultImportMap(name: string): DesignSystemManifestImportMap;
125
124
  interface SyncExportsResult {
126
125
  changed: boolean;
127
126
  json: string;
127
+ /** Existing subpaths whose value differed from the one Panda wrote (overwritten). */
128
+ conflicts: string[];
128
129
  }
129
130
  interface SyncExportsOptions {
130
131
  packageJson: string;
131
132
  entries: Record<string, string>;
132
133
  }
133
134
  declare function syncExports(options: SyncExportsOptions): SyncExportsResult;
135
+
136
+ interface FilterPublishableLibFilesOptions {
137
+ /** Fallback paths relative to the lib outdir (same form as manifest `files`). */
138
+ files: string[];
139
+ packageRoot: string;
140
+ outRoot: string;
141
+ /** package.json `"files"`; omit when the whole package is packed. */
142
+ publishFiles?: string[];
143
+ }
144
+ interface FilterPublishableLibFilesResult {
145
+ files: string[];
146
+ unpublished: string[];
147
+ }
148
+ /**
149
+ * Drop inferred lib fallback paths that would not ship in the npm tarball when
150
+ * package.json `"files"` is set. Explicit `--files` should skip this filter.
151
+ *
152
+ * Runs once at `panda lib` time (not on consume/cssgen). Patterns are compiled
153
+ * once per call; the common `"files": ["dist"]` case is prefix-only.
154
+ */
155
+ declare function filterPublishableLibFiles(options: FilterPublishableLibFilesOptions): FilterPublishableLibFilesResult;
156
+ /** Read package.json `"files"` when it is a non-empty string array. */
157
+ declare function readPublishFilesField(value: unknown): string[] | undefined;
158
+
159
+ interface SmartIncludeResult {
160
+ include: string[];
161
+ excludes: string[];
162
+ changed: boolean;
163
+ }
164
+ declare function resolveSmartInclude(include: string[], cwd: string, deps: Set<string>): SmartIncludeResult;
165
+ declare function mergeExcludes(existing: string[] | undefined, additions: string[]): string[];
166
+
167
+ declare function collectTokenPaths(config: Pick<UserConfig, 'theme'> | undefined): string[];
168
+
134
169
  declare function toPosixPath(path: string): string;
135
170
  declare function toPosixRelative(from: string, to: string): string;
136
171
  declare function toRelativeKey(key: string, cwd: string): string;
137
172
 
138
- declare function collectTokenPaths(config: Pick<UserConfig, 'theme'> | undefined): string[];
139
-
140
- export { type BundleConfigResult, type CompilePresetOptions, type CompilePresetResult, ConfigSources, type HostHooks, type LoadConfigOptions, type LoadConfigResult, type PackageIdentity, type SyncExportsOptions, type SyncExportsResult, bundleConfig, collectTokenPaths, compilePreset, defaultImportMap, diffConfig, findConfig, loadConfig, mergeExcludes, readPackageIdentity, readPandaVersion, resolveSmartInclude, syncExports, toPosixPath, toPosixRelative, toRelativeKey };
173
+ export { type BundleConfigResult, type CompilePresetOptions, type CompilePresetResult, ConfigSources, type FilterPublishableLibFilesOptions, type FilterPublishableLibFilesResult, type HostHooks, type LoadConfigOptions, type LoadConfigResult, type PackageIdentity, type SyncExportsOptions, type SyncExportsResult, bundleConfig, collectTokenPaths, compilePreset, defaultImportMap, diffConfig, filterPublishableLibFiles, findConfig, loadConfig, mergeExcludes, readPackageIdentity, readPandaVersion, readPublishFilesField, resolvePublishedPandaRange, resolveSmartInclude, syncExports, toPosixPath, toPosixRelative, toRelativeKey };
package/dist/index.js CHANGED
@@ -1,18 +1,21 @@
1
1
  import {
2
- PandaError,
3
- createConfigDiagnostic,
4
- createConfigError,
5
- ensureConfigObject,
6
- errorMessage,
7
- isPlainObject,
8
2
  mergeConfigs,
9
3
  mergeConfigsWithSources
10
- } from "./chunk-YKIDLZNO.js";
4
+ } from "./chunk-PER4IFQZ.js";
11
5
  import {
12
6
  collectPluginHookHandlers,
13
7
  createConfigSnapshot,
14
8
  normalizeHook
15
- } from "./chunk-VYX3JX5J.js";
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";
16
19
 
17
20
  // src/load.ts
18
21
  import { applyConfigDefaults } from "@pandacss/compiler-shared";
@@ -24,7 +27,6 @@ import { builtinModules } from "module";
24
27
  import { tmpdir } from "os";
25
28
  import { dirname, isAbsolute as isAbsolute2, join, normalize, relative } from "path";
26
29
  import { pathToFileURL as pathToFileURL2 } from "url";
27
- import { rolldown } from "rolldown";
28
30
 
29
31
  // src/bundle-plugins.ts
30
32
  import { parse } from "acorn";
@@ -75,6 +77,7 @@ function isNode(value, type) {
75
77
  // src/bundle.ts
76
78
  var nodeBuiltins = /* @__PURE__ */ new Set([...builtinModules, ...builtinModules.map((mod) => `node:${mod}`)]);
77
79
  async function bundleConfig(filepath, cwd) {
80
+ const { rolldown } = await import("rolldown");
78
81
  const build = await rolldown({
79
82
  input: filepath,
80
83
  cwd,
@@ -210,11 +213,11 @@ function findConfig(options) {
210
213
  // src/hook-utils.ts
211
214
  var configResolvedUtils = {
212
215
  omit(obj, paths) {
213
- const clone = cloneValue(obj);
216
+ const next = clone(obj);
214
217
  for (const path of paths) {
215
- deleteAtPath(clone, path);
218
+ deleteAtPath(next, path);
216
219
  }
217
- return clone;
220
+ return next;
218
221
  },
219
222
  pick(obj, paths) {
220
223
  const result = {};
@@ -230,23 +233,6 @@ var configResolvedUtils = {
230
233
  traverseValue(obj, callback, options);
231
234
  }
232
235
  };
233
- function cloneValue(value) {
234
- if (Array.isArray(value)) {
235
- const len = value.length;
236
- const out2 = new Array(len);
237
- for (let i = 0; i < len; i++) out2[i] = cloneValue(value[i]);
238
- return out2;
239
- }
240
- if (!isPlainObject(value)) return value;
241
- const source = value;
242
- const out = {};
243
- const keys = Object.keys(source);
244
- for (let i = 0; i < keys.length; i++) {
245
- const key = keys[i];
246
- out[key] = cloneValue(source[key]);
247
- }
248
- return out;
249
- }
250
236
  function pathParts(path) {
251
237
  return path.split(".").filter(Boolean);
252
238
  }
@@ -263,7 +249,7 @@ function setAtPath(target, path, value) {
263
249
  let current = target;
264
250
  parts.forEach((part, index) => {
265
251
  if (index === parts.length - 1) {
266
- current[part] = cloneValue(value);
252
+ current[part] = clone(value);
267
253
  return;
268
254
  }
269
255
  const next = current[part];
@@ -337,10 +323,50 @@ function attachRuntimeHooks(config, configs) {
337
323
  return config;
338
324
  }
339
325
 
326
+ // src/normalize.ts
327
+ var CLASS_NAME_OPTION_KEYS = ["hash", "prefix", "separator"];
328
+ function normalizeClassNameOptions(config) {
329
+ return {
330
+ hash: normalizeHash(config.hash),
331
+ prefix: normalizePrefix(config.prefix),
332
+ separator: config.separator ?? "_"
333
+ };
334
+ }
335
+ function diffClassNameOptions(consumer, designSystem, scope) {
336
+ const normalized = normalizeClassNameOptions(consumer);
337
+ return CLASS_NAME_OPTION_KEYS.filter((key) => {
338
+ if (scope === "explicit" && consumer[key] === void 0) {
339
+ return false;
340
+ }
341
+ if (key === "separator") {
342
+ return normalized.separator !== designSystem.separator;
343
+ }
344
+ return normalized[key].cssVar !== designSystem[key].cssVar || normalized[key].className !== designSystem[key].className;
345
+ });
346
+ }
347
+ function normalizeHash(value) {
348
+ if (typeof value === "boolean") {
349
+ return { cssVar: value, className: value };
350
+ }
351
+ if (value && typeof value === "object") {
352
+ return { cssVar: value.cssVar === true, className: value.className === true };
353
+ }
354
+ return { cssVar: false, className: false };
355
+ }
356
+ function normalizePrefix(value) {
357
+ if (typeof value === "string") {
358
+ return { cssVar: value, className: value };
359
+ }
360
+ if (value && typeof value === "object") {
361
+ return { cssVar: value.cssVar ?? "", className: value.className ?? "" };
362
+ }
363
+ return { cssVar: "", className: "" };
364
+ }
365
+
340
366
  // src/preset.ts
341
- import { normalize as normalize2, relative as relative3 } from "path";
367
+ import { normalize as normalize2, relative as relative4 } from "path";
342
368
 
343
- // src/design-system.ts
369
+ // src/design-system/chain.ts
344
370
  import {
345
371
  outdirBasename
346
372
  } from "@pandacss/compiler-shared";
@@ -360,14 +386,29 @@ function tryResolveFrom(request, fromDir) {
360
386
  }
361
387
  }
362
388
  function isResolveMiss(error) {
363
- const code = typeof error === "object" && error !== null && "code" in error ? error.code : void 0;
389
+ const code = errorCode(error);
364
390
  return code === "MODULE_NOT_FOUND" || code === "ERR_PACKAGE_PATH_NOT_EXPORTED";
365
391
  }
392
+ function resolveFrom(request, fromDir) {
393
+ try {
394
+ return { kind: "resolved", path: createRequire(resolve2(fromDir, "noop.js")).resolve(request, { paths: [fromDir] }) };
395
+ } catch (error) {
396
+ const code = errorCode(error);
397
+ if (code === "ERR_PACKAGE_PATH_NOT_EXPORTED") return { kind: "not-exported" };
398
+ if (code === "MODULE_NOT_FOUND") return { kind: "not-installed" };
399
+ throw error;
400
+ }
401
+ }
402
+ function errorCode(error) {
403
+ return typeof error === "object" && error !== null && "code" in error ? error.code : void 0;
404
+ }
366
405
 
367
- // src/design-system.ts
406
+ // src/design-system/chain.ts
407
+ var SPECIFIER_PROTOCOL = /^([a-z][a-z0-9+.-]*):/i;
368
408
  async function loadDesignSystemChain(spec, cwd, deps) {
369
409
  const levels = [];
370
410
  const seenAt = /* @__PURE__ */ new Map();
411
+ const seenNames = /* @__PURE__ */ new Map();
371
412
  let currentSpec = spec;
372
413
  let fromDir = cwd;
373
414
  let declaredBy;
@@ -383,6 +424,11 @@ async function loadDesignSystemChain(spec, cwd, deps) {
383
424
  seenAt.set(manifestPath, levels.length);
384
425
  deps.add(manifestPath);
385
426
  const { level, parent } = await loadManifestLevel(currentSpec, manifestPath, deps);
427
+ const priorPath = seenNames.get(level.info.name);
428
+ if (priorPath !== void 0 && priorPath !== manifestPath) {
429
+ throw duplicateNameError(level.info.name, priorPath, manifestPath);
430
+ }
431
+ seenNames.set(level.info.name, manifestPath);
386
432
  levels.push(level);
387
433
  if (parent === void 0) break;
388
434
  declaredBy = level.info.name;
@@ -399,26 +445,38 @@ function withDesignSystemImportMap(config, infos) {
399
445
  return { ...config, importMap: [...roots, outdirBasename(config.outdir ?? "styled-system"), ...existing] };
400
446
  }
401
447
  function resolveManifestPath(spec, fromDir) {
448
+ const protocol = specifierProtocol(spec);
449
+ if (protocol) throw unsupportedSpecifierError(spec, protocol);
450
+ let outcome;
402
451
  try {
403
- return tryResolveFrom(`${spec}/panda.lib.json`, fromDir);
452
+ outcome = resolveFrom(`${spec}/panda.lib.json`, fromDir);
404
453
  } catch (error) {
405
454
  const message = `Failed to resolve designSystem ${JSON.stringify(spec)} from ${JSON.stringify(fromDir)}: ${errorMessage(error)}`;
406
455
  throw createConfigError(message, [createConfigDiagnostic("design_system_resolve_failed", message)]);
407
456
  }
457
+ if (outcome.kind === "resolved") return outcome.path;
458
+ if (outcome.kind === "not-exported") throw manifestNotExportedError(spec);
459
+ return void 0;
460
+ }
461
+ function manifestNotExportedError(spec) {
462
+ const message = `designSystem ${JSON.stringify(spec)} is installed but doesn't expose \`./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.`;
463
+ return createConfigError(message, [
464
+ createConfigDiagnostic("design_system_manifest_not_exported", message, [
465
+ `Rebuild ${JSON.stringify(spec)} with \`panda lib\`, or check its package.json \`exports\` includes \`./panda.lib.json\`.`
466
+ ])
467
+ ]);
408
468
  }
409
469
  async function loadManifestLevel(spec, manifestPath, deps) {
410
- let manifest;
470
+ let parsed;
411
471
  try {
412
- manifest = JSON.parse(readFileSync(manifestPath, "utf8"));
472
+ parsed = JSON.parse(readFileSync(manifestPath, "utf8"));
413
473
  } catch (error) {
414
- throw new PandaError("CONFIG_ERROR", `\u{1F4A5} Failed to read ${JSON.stringify(manifestPath)}: ${errorMessage(error)}`);
415
- }
416
- if (typeof manifest.preset !== "string") {
417
- throw invalidManifestError(spec, "preset");
418
- }
419
- if (typeof manifest.buildInfo !== "string") {
420
- throw invalidManifestError(spec, "buildInfo");
474
+ 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\`.`;
475
+ throw createConfigError(message, [
476
+ { ...createConfigDiagnostic("design_system_manifest_invalid", message), file: manifestPath }
477
+ ]);
421
478
  }
479
+ const manifest = validateManifest(spec, manifestPath, parsed);
422
480
  const presetPath = resolve3(dirname3(manifestPath), manifest.preset);
423
481
  const buildInfoPath = resolve3(dirname3(manifestPath), manifest.buildInfo);
424
482
  deps.add(presetPath);
@@ -426,13 +484,15 @@ async function loadManifestLevel(spec, manifestPath, deps) {
426
484
  let preset;
427
485
  try {
428
486
  const mod = await import(presetImportUrl(presetPath));
429
- preset = ensureConfigObject(mod.default ?? mod, manifest.name ?? spec);
487
+ preset = ensureConfigObject("default" in mod ? mod.default : mod, manifest.name ?? spec);
430
488
  } catch (error) {
431
- if (error instanceof PandaError) throw error;
432
- throw new PandaError(
433
- "CONFIG_ERROR",
434
- `\u{1F4A5} Failed to load preset for designSystem ${JSON.stringify(spec)}: ${errorMessage(error)}`
435
- );
489
+ if (error instanceof PandaError && error.diagnostics?.length) throw error;
490
+ const message = `Failed to load the preset for designSystem ${JSON.stringify(spec)} (${JSON.stringify(manifest.preset)}): ${errorMessage(error)}`;
491
+ throw createConfigError(message, [
492
+ createConfigDiagnostic("design_system_preset_load_failed", message, [
493
+ `Check that ${JSON.stringify(manifest.preset)} is valid and rebuild ${JSON.stringify(spec)} with \`panda lib\`.`
494
+ ])
495
+ ]);
436
496
  }
437
497
  const parent = typeof manifest.designSystem === "string" && manifest.designSystem.length > 0 ? manifest.designSystem : void 0;
438
498
  return {
@@ -466,6 +526,53 @@ function designSystemImportMap(map, spec) {
466
526
  tokens: map.tokens ?? `${spec}/tokens`
467
527
  };
468
528
  }
529
+ var IMPORT_MAP_FIELDS = ["css", "recipes", "patterns", "jsx", "tokens"];
530
+ function validateManifest(spec, manifestPath, value) {
531
+ if (!isPlainObject(value)) {
532
+ throw invalidManifestError(spec, manifestPath, ["must contain a JSON object"]);
533
+ }
534
+ const issues = [];
535
+ requiredString(value, "name", issues);
536
+ requiredString(value, "panda", issues);
537
+ requiredString(value, "preset", issues);
538
+ requiredString(value, "buildInfo", issues);
539
+ if (!Number.isInteger(value.schemaVersion) || value.schemaVersion < 1) {
540
+ issues.push('must contain a positive integer "schemaVersion" entry');
541
+ }
542
+ if (value.version !== void 0 && typeof value.version !== "string") {
543
+ issues.push('has a "version" entry that must be a string');
544
+ }
545
+ if (value.designSystem !== void 0 && !isNonEmptyString(value.designSystem)) {
546
+ issues.push('has a "designSystem" entry that must be a non-empty string');
547
+ }
548
+ if (value.files !== void 0 && (!Array.isArray(value.files) || !value.files.every((file) => isNonEmptyString(file)))) {
549
+ issues.push('has a "files" entry that must be an array of non-empty strings');
550
+ }
551
+ if (value.importMap !== void 0) {
552
+ if (!isPlainObject(value.importMap)) {
553
+ issues.push('has an "importMap" entry that must be an object');
554
+ } else {
555
+ for (const field of IMPORT_MAP_FIELDS) {
556
+ const entry = value.importMap[field];
557
+ if (entry !== void 0 && !isNonEmptyString(entry)) {
558
+ issues.push(`has an "importMap.${field}" entry that must be a non-empty string`);
559
+ }
560
+ }
561
+ }
562
+ }
563
+ if (issues.length > 0) {
564
+ throw invalidManifestError(spec, manifestPath, issues);
565
+ }
566
+ return value;
567
+ }
568
+ function requiredString(value, field, issues) {
569
+ if (!isNonEmptyString(value[field])) {
570
+ issues.push(`is missing a "${field}" entry or it is empty`);
571
+ }
572
+ }
573
+ function isNonEmptyString(value) {
574
+ return typeof value === "string" && value.trim().length > 0;
575
+ }
469
576
  function notResolvedError(spec) {
470
577
  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\`.`;
471
578
  return createConfigError(message, [
@@ -486,22 +593,51 @@ function cycleError(cycle) {
486
593
  const message = `Design-system cycle: ${cycle.join(" \u2192 ")}. A design system can't depend on itself.`;
487
594
  return createConfigError(message, [createConfigDiagnostic("design_system_cycle", message)]);
488
595
  }
489
- function invalidManifestError(spec, field) {
490
- const message = `${JSON.stringify(spec)} manifest is missing a "${field}" entry.`;
596
+ function invalidManifestError(spec, manifestPath, issues) {
597
+ const message = `${JSON.stringify(spec)} manifest ${issues.join("; ")}.`;
491
598
  return createConfigError(message, [
492
- createConfigDiagnostic("design_system_manifest_invalid", message, [
493
- `Rebuild ${JSON.stringify(spec)} with \`panda lib\`.`
494
- ])
599
+ {
600
+ ...createConfigDiagnostic("design_system_manifest_invalid", message, [
601
+ `Rebuild ${JSON.stringify(spec)} with \`panda lib\`.`
602
+ ]),
603
+ file: manifestPath
604
+ }
495
605
  ]);
496
606
  }
607
+ function duplicateNameError(name, firstPath, secondPath) {
608
+ 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.`;
609
+ return createConfigError(message, [createConfigDiagnostic("design_system_duplicate_name", message)]);
610
+ }
611
+ function specifierProtocol(spec) {
612
+ const match = spec.match(SPECIFIER_PROTOCOL);
613
+ return match ? match[1] : void 0;
614
+ }
615
+ function unsupportedSpecifierError(spec, protocol) {
616
+ 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\`.`;
617
+ return createConfigError(message, [createConfigDiagnostic("design_system_unsupported_specifier", message)]);
618
+ }
497
619
 
498
- // src/smart-include.ts
620
+ // src/design-system/smart-include.ts
499
621
  import { existsSync as existsSync2 } from "fs";
500
- import { dirname as dirname4, isAbsolute as isAbsolute3, join as join2, relative as relative2, resolve as resolve4, sep } from "path";
622
+ import { dirname as dirname4, isAbsolute as isAbsolute4, join as join2, relative as relative3, resolve as resolve4, sep } from "path";
623
+
624
+ // src/paths.ts
625
+ import { isAbsolute as isAbsolute3, relative as relative2 } from "path";
626
+ function toPosixPath(path) {
627
+ return path.includes("\\") ? path.split("\\").join("/") : path;
628
+ }
629
+ function toPosixRelative(from, to) {
630
+ const rel = toPosixPath(relative2(from, to));
631
+ return rel.startsWith(".") ? rel : `./${rel}`;
632
+ }
633
+ function toRelativeKey(key, cwd) {
634
+ return toPosixPath(isAbsolute3(key) ? relative2(cwd, key) : key);
635
+ }
636
+
637
+ // src/design-system/smart-include.ts
501
638
  var SMART_INCLUDE_EXTENSIONS = ["js", "mjs", "cjs", "jsx", "ts", "cts", "mts", "tsx", "vue", "svelte", "astro"];
502
639
  var MANIFEST = "panda.lib.json";
503
640
  var PACKAGE_SPECIFIER = /^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/i;
504
- var PATH_SEPARATOR = /[\\/]/;
505
641
  function resolveSmartInclude(include, cwd, deps) {
506
642
  const offenders = [];
507
643
  const next = [];
@@ -548,7 +684,7 @@ function mergeExcludes(existing, additions) {
548
684
  return [...existing ?? [], ...additions];
549
685
  }
550
686
  function isLocalPath(entry, cwd) {
551
- return existsSync2(isAbsolute3(entry) ? entry : resolve4(cwd, entry));
687
+ return existsSync2(isAbsolute4(entry) ? entry : resolve4(cwd, entry));
552
688
  }
553
689
  function resolvePackageDir(spec, cwd) {
554
690
  const fromPackageJson = tryResolve(`${spec}/package.json`, cwd);
@@ -566,7 +702,7 @@ function tryResolve(request, cwd) {
566
702
  }
567
703
  function isInsideCwd(relativePath) {
568
704
  if (relativePath === "" || relativePath === "..") return false;
569
- if (isAbsolute3(relativePath)) return false;
705
+ if (isAbsolute4(relativePath)) return false;
570
706
  return !relativePath.startsWith(`..${sep}`);
571
707
  }
572
708
  function nearestPackageDir(from) {
@@ -579,12 +715,9 @@ function nearestPackageDir(from) {
579
715
  }
580
716
  }
581
717
  function globBase(packageDir, cwd) {
582
- const rel = relative2(cwd, packageDir);
718
+ const rel = relative3(cwd, packageDir);
583
719
  const base = isInsideCwd(rel) ? rel : packageDir;
584
- return toPosix(base);
585
- }
586
- function toPosix(path) {
587
- return path.split(PATH_SEPARATOR).join("/");
720
+ return toPosixPath(base);
588
721
  }
589
722
  function inIncludeError(specs) {
590
723
  const list = specs.map((spec) => JSON.stringify(spec)).join(", ");
@@ -602,18 +735,46 @@ function inIncludeError(specs) {
602
735
  );
603
736
  }
604
737
 
605
- // src/token-paths.ts
738
+ // src/design-system/token-paths.ts
739
+ import { isDeepStrictEqual } from "util";
606
740
  function collectTokenPaths(config) {
607
- if (!isPlainObject(config?.theme)) return [];
608
- const paths = /* @__PURE__ */ new Set();
609
- collect(config.theme.tokens, [], paths);
610
- collect(config.theme.semanticTokens, [], paths);
741
+ return [...collectTokenEntries(config).keys()].sort();
742
+ }
743
+ function collectTokenEntries(config) {
744
+ const entries = /* @__PURE__ */ new Map();
745
+ if (!isPlainObject(config?.theme)) {
746
+ return entries;
747
+ }
748
+ collect(config.theme.tokens, [], entries);
749
+ collect(config.theme.semanticTokens, [], entries);
750
+ return entries;
751
+ }
752
+ function resolveUserTokenPathsAfterHooks(userTokenPaths, beforeHooks, afterHooks) {
753
+ const paths = new Set(userTokenPaths);
754
+ const after = collectTokenEntries(afterHooks);
755
+ for (const path of paths) {
756
+ if (!after.has(path)) {
757
+ paths.delete(path);
758
+ }
759
+ }
760
+ for (const [path, values] of after) {
761
+ if (!beforeHooks.has(path) || !isDeepStrictEqual(beforeHooks.get(path), values)) {
762
+ paths.add(path);
763
+ }
764
+ }
611
765
  return [...paths].sort();
612
766
  }
613
767
  function collect(node, trail, out) {
614
- if (!isPlainObject(node)) return;
768
+ if (!isPlainObject(node)) {
769
+ return;
770
+ }
615
771
  if ("value" in node) {
616
- if (trail.length > 0) out.add(trail.join("."));
772
+ if (trail.length > 0) {
773
+ const path = trail.join(".");
774
+ const entries = out.get(path) ?? [];
775
+ entries.push(node.value);
776
+ out.set(path, entries);
777
+ }
617
778
  return;
618
779
  }
619
780
  for (const [key, child] of Object.entries(node)) {
@@ -622,7 +783,7 @@ function collect(node, trail, out) {
622
783
  }
623
784
 
624
785
  // src/preset.ts
625
- async function resolveAuthoredPresets(config, cwd, options = {}) {
786
+ async function resolveAuthoredPresetsForLoad(config, cwd, options = {}) {
626
787
  const ctx = {
627
788
  cwd,
628
789
  configs: [],
@@ -631,38 +792,54 @@ async function resolveAuthoredPresets(config, cwd, options = {}) {
631
792
  ...options.trackSources ? { sourcedConfigs: [] } : {}
632
793
  };
633
794
  const rootSource = { kind: "config" };
634
- if (options.configFile) rootSource.file = normalize2(relative3(cwd, options.configFile));
795
+ if (options.configFile) {
796
+ rootSource.file = normalize2(relative4(cwd, options.configFile));
797
+ }
635
798
  const designSystem = config.designSystem;
636
799
  let dsChain = [];
800
+ const designSystemCompatibility = [];
637
801
  if (typeof designSystem === "string" && designSystem.length > 0) {
638
802
  dsChain = await loadDesignSystemChain(designSystem, cwd, ctx.dependencies);
639
803
  for (const level of dsChain) {
640
- const block = await collectConfigBlock(
804
+ const resolution = await resolveConfigEntry(
641
805
  level.preset,
642
806
  { kind: "preset", specifier: level.info.name },
643
807
  cwd,
644
808
  ctx.dependencies,
645
809
  options.trackSources
646
810
  );
647
- level.info.tokenPaths = collectTokenPaths(block.resolved);
648
- appendConfigBlock(ctx, block);
811
+ level.info.tokenPaths = collectTokenPaths(resolution.config);
812
+ appendConfigResolution(ctx, resolution);
813
+ designSystemCompatibility.push({
814
+ designSystem: level.info,
815
+ classNameOptions: normalizeClassNameOptions(mergeConfigs(ctx.configs))
816
+ });
817
+ }
818
+ }
819
+ const rootResolution = await resolveConfigEntry(config, rootSource, cwd, ctx.dependencies, options.trackSources);
820
+ appendConfigResolution(ctx, rootResolution);
821
+ for (const { designSystem: designSystem2, classNameOptions } of designSystemCompatibility) {
822
+ const mismatch = diffClassNameOptions(rootResolution.config, classNameOptions, "explicit");
823
+ if (mismatch.length > 0) {
824
+ designSystem2.optionMismatch = mismatch;
649
825
  }
650
826
  }
651
- const rootBlock = await collectConfigBlock(config, rootSource, cwd, ctx.dependencies, options.trackSources);
652
- appendConfigBlock(ctx, rootBlock);
653
827
  const dsInfos = dsChain.map((level) => level.info);
654
828
  const finalize = (resolved) => {
655
829
  const withImportMap = dsInfos.length > 0 ? withDesignSystemImportMap(resolved, dsInfos) : resolved;
656
830
  return expandSmartInclude(withImportMap, cwd, ctx.dependencies);
657
831
  };
658
- const dsMetadata = dsInfos.length > 0 ? { designSystem: dsInfos, userTokenPaths: collectTokenPaths(rootBlock.resolved) } : void 0;
832
+ const dsMetadata = dsInfos.length > 0 ? { designSystem: dsInfos, userTokenPaths: collectTokenPaths(rootResolution.config) } : void 0;
659
833
  if (ctx.sourcedConfigs) {
660
834
  const merged = mergeConfigsWithSources(ctx.sourcedConfigs);
661
- if (options.preserveRuntimeHooks) attachRuntimeHooks(merged.config, ctx.configs);
835
+ if (options.preserveRuntimeHooks) {
836
+ attachRuntimeHooks(merged.config, ctx.configs);
837
+ }
662
838
  return {
663
839
  config: finalize(merged.config),
664
840
  dependencies: Array.from(ctx.dependencies),
665
- metadata: { sources: merged.sources, ...dsMetadata }
841
+ metadata: { sources: merged.sources, ...dsMetadata },
842
+ designSystemCompatibility
666
843
  };
667
844
  }
668
845
  return {
@@ -670,10 +847,11 @@ async function resolveAuthoredPresets(config, cwd, options = {}) {
670
847
  options.preserveRuntimeHooks ? attachRuntimeHooks(mergeConfigs(ctx.configs), ctx.configs) : mergeConfigs(ctx.configs)
671
848
  ),
672
849
  dependencies: Array.from(ctx.dependencies),
673
- ...dsMetadata ? { metadata: dsMetadata } : {}
850
+ ...dsMetadata ? { metadata: dsMetadata } : {},
851
+ designSystemCompatibility
674
852
  };
675
853
  }
676
- async function collectConfigBlock(config, source, cwd, dependencies, trackSources) {
854
+ async function resolveConfigEntry(config, source, cwd, dependencies, trackSources) {
677
855
  const ctx = {
678
856
  cwd,
679
857
  configs: [],
@@ -685,13 +863,13 @@ async function collectConfigBlock(config, source, cwd, dependencies, trackSource
685
863
  return {
686
864
  configs: ctx.configs,
687
865
  ...ctx.sourcedConfigs ? { sourcedConfigs: ctx.sourcedConfigs } : {},
688
- resolved: mergeConfigs(ctx.configs)
866
+ config: mergeConfigs(ctx.configs)
689
867
  };
690
868
  }
691
- function appendConfigBlock(ctx, block) {
692
- ctx.configs.push(...block.configs);
693
- if (ctx.sourcedConfigs && block.sourcedConfigs) {
694
- ctx.sourcedConfigs.push(...block.sourcedConfigs);
869
+ function appendConfigResolution(ctx, resolution) {
870
+ ctx.configs.push(...resolution.configs);
871
+ if (ctx.sourcedConfigs && resolution.sourcedConfigs) {
872
+ ctx.sourcedConfigs.push(...resolution.sourcedConfigs);
695
873
  }
696
874
  }
697
875
  async function collectConfigs(config, source, ctx, active) {
@@ -777,7 +955,7 @@ async function loadConfig(options) {
777
955
  if (!isPlainObject(config)) {
778
956
  throw new PandaError("CONFIG_ERROR", "\u{1F4A5} Config must export or return an object.");
779
957
  }
780
- const authored = await resolveAuthoredPresets(config, cwd, {
958
+ const authored = await resolveAuthoredPresetsForLoad(config, cwd, {
781
959
  configFile: path,
782
960
  trackSources: options.trackSources,
783
961
  preserveRuntimeHooks: true
@@ -785,7 +963,14 @@ async function loadConfig(options) {
785
963
  const authoredDependencies = Array.from(
786
964
  /* @__PURE__ */ new Set([...dependencies, ...authored.dependencies, ...authored.config.dependencies ?? []])
787
965
  );
966
+ const tokenEntriesBeforeHooks = collectTokenEntries(authored.config);
788
967
  const userConfig = await runConfigResolvedHooks(authored.config, path, authoredDependencies);
968
+ refreshDesignSystemMetadata(
969
+ authored.metadata,
970
+ authored.designSystemCompatibility,
971
+ userConfig,
972
+ tokenEntriesBeforeHooks
973
+ );
789
974
  const resolved = applyConfigDefaults(userConfig, cwd);
790
975
  const dependencyList = Array.from(
791
976
  /* @__PURE__ */ new Set([...dependencies, ...authored.dependencies, ...resolved.dependencies ?? []])
@@ -798,12 +983,29 @@ async function loadConfig(options) {
798
983
  ...snapshot.hooks ? { hooks: snapshot.hooks } : {},
799
984
  hostHooks: {
800
985
  "codegen:prepare": collectPluginHookHandlers(resolved, "codegen:prepare"),
801
- "codegen:done": collectPluginHookHandlers(resolved, "codegen:done")
986
+ "codegen:done": collectPluginHookHandlers(resolved, "codegen:done"),
987
+ "cssgen:done": collectPluginHookHandlers(resolved, "cssgen:done")
802
988
  },
803
989
  dependencies: dependencyList,
804
990
  ...authored.metadata ? { metadata: authored.metadata } : {}
805
991
  };
806
992
  }
993
+ function refreshDesignSystemMetadata(metadata, designSystemCompatibility, config, tokenEntriesBeforeHooks) {
994
+ if (!metadata?.designSystem?.length) return;
995
+ metadata.userTokenPaths = resolveUserTokenPathsAfterHooks(
996
+ metadata.userTokenPaths ?? [],
997
+ tokenEntriesBeforeHooks,
998
+ config
999
+ );
1000
+ for (const { designSystem, classNameOptions } of designSystemCompatibility) {
1001
+ const mismatch = diffClassNameOptions(config, classNameOptions, "effective");
1002
+ if (mismatch.length > 0) {
1003
+ designSystem.optionMismatch = mismatch;
1004
+ } else {
1005
+ delete designSystem.optionMismatch;
1006
+ }
1007
+ }
1008
+ }
807
1009
  async function runConfigResolvedHooks(config, path, dependencies) {
808
1010
  let current = config;
809
1011
  for (const entry of collectPluginHookHandlers(current, "config:resolved")) {
@@ -937,15 +1139,15 @@ function readPandaVersion() {
937
1139
  }
938
1140
  }
939
1141
 
940
- // src/lib-preset.ts
1142
+ // src/design-system/compile-preset.ts
941
1143
  import { builtinModules as builtinModules2 } from "module";
942
- import { rolldown as rolldown2 } from "rolldown";
943
1144
  var APP_FIELDS = ["designSystem", "include", "exclude", "outdir", "cwd", "watch", "clean", "gitignore", "importMap"];
944
1145
  var VIRTUAL_ENTRY = "\0panda-lib-preset-entry";
945
1146
  var nodeBuiltins2 = /* @__PURE__ */ new Set([...builtinModules2, ...builtinModules2.map((mod) => `node:${mod}`)]);
946
1147
  async function compilePreset(options) {
947
1148
  const { configPath, cwd } = options;
948
- const build = await rolldown2({
1149
+ const { rolldown } = await import("rolldown");
1150
+ const build = await rolldown({
949
1151
  input: VIRTUAL_ENTRY,
950
1152
  cwd,
951
1153
  platform: "node",
@@ -996,16 +1198,114 @@ async function validatePreset(code) {
996
1198
  try {
997
1199
  await import(`data:text/javascript;base64,${Buffer.from(code).toString("base64")}`);
998
1200
  } catch (error) {
999
- throw new PandaError("CONFIG_ERROR", `\u{1F4A5} Failed to compile design system preset: ${errorMessage2(error)}`);
1201
+ throw new PandaError("CONFIG_ERROR", `\u{1F4A5} Failed to compile design system preset: ${errorMessage(error)}`);
1000
1202
  }
1001
1203
  }
1002
- function errorMessage2(error) {
1003
- return error instanceof Error ? error.message : String(error);
1004
- }
1005
1204
 
1006
- // src/lib-manifest.ts
1205
+ // src/design-system/package.ts
1007
1206
  import { existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
1008
- import { dirname as dirname6, isAbsolute as isAbsolute4, join as join4, relative as relative4 } from "path";
1207
+ import { dirname as dirname6, join as join4 } from "path";
1208
+
1209
+ // src/design-system/publishable-files.ts
1210
+ import { relative as relative5, resolve as resolve5 } from "path";
1211
+ var GLOB_START = /[*?{]/;
1212
+ var HAS_WILDCARD = /[*?]/;
1213
+ var TRAILING_SLASH = /\/$/;
1214
+ var REGEX_META = /[.+^${}()|[\]\\]/g;
1215
+ var GLOBSTAR = /\*\*/g;
1216
+ var GLOB_STAR = /\*/g;
1217
+ var GLOB_QMARK = /\?/g;
1218
+ var GLOBSTAR_TOKEN = /<<<DS>>>/g;
1219
+ function filterPublishableLibFiles(options) {
1220
+ const { files, packageRoot, outRoot, publishFiles } = options;
1221
+ if (!publishFiles?.length) {
1222
+ return { files, unpublished: [] };
1223
+ }
1224
+ const rules = compilePackageFilesRules(publishFiles);
1225
+ const kept = [];
1226
+ const unpublished = [];
1227
+ for (const file of files) {
1228
+ const packageRelative = libFileToPackageRelative(file, packageRoot, outRoot);
1229
+ if (packageRelative !== void 0 && matchesCompiledRules(packageRelative, rules)) {
1230
+ kept.push(file);
1231
+ } else {
1232
+ unpublished.push(file);
1233
+ }
1234
+ }
1235
+ return { files: kept, unpublished };
1236
+ }
1237
+ function readPublishFilesField(value) {
1238
+ if (!Array.isArray(value) || value.length === 0) return void 0;
1239
+ for (const entry of value) {
1240
+ if (typeof entry !== "string") return void 0;
1241
+ }
1242
+ return value;
1243
+ }
1244
+ function libFileToPackageRelative(file, packageRoot, outRoot) {
1245
+ const normalized = toPosixPath(file);
1246
+ const withoutDot = normalized.startsWith("./") ? normalized.slice(2) : normalized;
1247
+ const globAt = withoutDot.search(GLOB_START);
1248
+ const literalPrefix = globAt === -1 ? withoutDot : withoutDot.slice(0, globAt);
1249
+ const abs = resolve5(outRoot, literalPrefix || ".");
1250
+ const rel = toPosixPath(relative5(packageRoot, abs));
1251
+ if (rel === "") return "";
1252
+ if (rel.startsWith("..")) return void 0;
1253
+ return rel;
1254
+ }
1255
+ function compilePackageFilesRules(patterns) {
1256
+ const rules = [];
1257
+ for (const raw of patterns) {
1258
+ const negated = raw.startsWith("!");
1259
+ const pattern = toPosixPath(negated ? raw.slice(1) : raw);
1260
+ const normalized = pattern.startsWith("./") ? pattern.slice(2) : pattern;
1261
+ if (!normalized) continue;
1262
+ if (!HAS_WILDCARD.test(normalized)) {
1263
+ rules.push({ kind: "prefix", negated, value: normalized.replace(TRAILING_SLASH, "") });
1264
+ continue;
1265
+ }
1266
+ const escaped = normalized.replace(REGEX_META, "\\$&").replace(GLOBSTAR, "<<<DS>>>").replace(GLOB_STAR, "[^/]*").replace(GLOB_QMARK, "[^/]").replace(GLOBSTAR_TOKEN, ".*");
1267
+ rules.push({ kind: "regex", negated, value: new RegExp(`^${escaped}(?:/.*)?$`) });
1268
+ }
1269
+ return rules;
1270
+ }
1271
+ function matchesCompiledRules(packageRelativePath, rules) {
1272
+ const path = packageRelativePath.startsWith("./") ? packageRelativePath.slice(2) : packageRelativePath;
1273
+ let included = false;
1274
+ for (const rule of rules) {
1275
+ const hit = rule.kind === "prefix" ? path === rule.value || path.startsWith(`${rule.value}/`) : rule.value.test(path);
1276
+ if (!hit) continue;
1277
+ included = !rule.negated;
1278
+ }
1279
+ return included;
1280
+ }
1281
+
1282
+ // src/design-system/package.ts
1283
+ var PACKAGE_MANAGER_RANGE_PATTERN = /^(?:workspace|catalog):/;
1284
+ var PORTABLE_WORKSPACE_RANGE_PATTERN = /^[~^]?\d/;
1285
+ var VERSION_CORE_PATTERN = /^(\d+)\.(\d+)\.(\d+)/;
1286
+ function resolvePublishedPandaRange(range, currentVersion) {
1287
+ const authored = range?.trim();
1288
+ if (!authored) return "*";
1289
+ if (authored.startsWith("npm:")) {
1290
+ return resolveNpmAliasRange(authored) ?? portableRangeFromInstalled(currentVersion, "^");
1291
+ }
1292
+ if (!PACKAGE_MANAGER_RANGE_PATTERN.test(authored)) return authored;
1293
+ if (authored.startsWith("workspace:")) {
1294
+ const workspaceRange = authored.slice("workspace:".length);
1295
+ if (PORTABLE_WORKSPACE_RANGE_PATTERN.test(workspaceRange)) return workspaceRange;
1296
+ }
1297
+ const operator = authored === "workspace:~" ? "~" : "^";
1298
+ return portableRangeFromInstalled(currentVersion, operator);
1299
+ }
1300
+ function resolveNpmAliasRange(spec) {
1301
+ const at = spec.lastIndexOf("@");
1302
+ if (at <= "npm:".length) return void 0;
1303
+ return spec.slice(at + 1);
1304
+ }
1305
+ function portableRangeFromInstalled(currentVersion, operator) {
1306
+ const core = currentVersion?.match(VERSION_CORE_PATTERN)?.[0];
1307
+ return core ? `${operator}${core}` : "*";
1308
+ }
1009
1309
  function readPackageIdentity(cwd) {
1010
1310
  const packagePath = nearestPackageJson(cwd);
1011
1311
  if (packagePath === void 0) {
@@ -1021,7 +1321,8 @@ function readPackageIdentity(cwd) {
1021
1321
  name,
1022
1322
  version: typeof pkg.version === "string" ? pkg.version : void 0,
1023
1323
  pandaPeer: typeof peer === "string" ? peer : void 0,
1024
- packagePath
1324
+ packagePath,
1325
+ publishFiles: readPublishFilesField(pkg.files)
1025
1326
  };
1026
1327
  }
1027
1328
  function defaultImportMap(name) {
@@ -1038,29 +1339,23 @@ function syncExports(options) {
1038
1339
  const pkg = JSON.parse(packageJson);
1039
1340
  const existing = normalizeExports(pkg.exports);
1040
1341
  const merged = { ...existing };
1041
- for (const [key, value] of Object.entries(entries)) merged[key] = value;
1342
+ const conflicts = [];
1343
+ for (const [key, value] of Object.entries(entries)) {
1344
+ if (key in existing && existing[key] !== value) {
1345
+ conflicts.push(key);
1346
+ }
1347
+ merged[key] = value;
1348
+ }
1042
1349
  const changed = JSON.stringify(pkg.exports) !== JSON.stringify(merged);
1043
1350
  const out = { ...pkg, exports: merged };
1044
1351
  return { changed, json: `${JSON.stringify(out, null, 2)}
1045
- ` };
1046
- }
1047
- function toPosixPath(path) {
1048
- return path.split("\\").join("/");
1049
- }
1050
- function toPosixRelative(from, to) {
1051
- const rel = toPosixPath(relative4(from, to));
1052
- return rel.startsWith(".") ? rel : `./${rel}`;
1053
- }
1054
- function toRelativeKey(key, cwd) {
1055
- return toPosixPath(isAbsolute4(key) ? relative4(cwd, key) : key);
1056
- }
1057
- function isPlainObject2(value) {
1058
- return typeof value === "object" && value !== null && !Array.isArray(value);
1352
+ `, conflicts };
1059
1353
  }
1060
1354
  function normalizeExports(exports) {
1061
1355
  if (exports === void 0) return {};
1062
1356
  if (typeof exports === "string") return { ".": exports };
1063
- if (!isPlainObject2(exports)) return {};
1357
+ if (Array.isArray(exports)) return { ".": exports };
1358
+ if (!isPlainObject(exports)) return {};
1064
1359
  if (isSubpathExportMap(exports)) return exports;
1065
1360
  return { ".": exports };
1066
1361
  }
@@ -1084,12 +1379,15 @@ export {
1084
1379
  createConfigSnapshot,
1085
1380
  defaultImportMap,
1086
1381
  diffConfig,
1382
+ filterPublishableLibFiles,
1087
1383
  findConfig,
1088
1384
  loadConfig,
1089
1385
  mergeConfigs,
1090
1386
  mergeExcludes,
1091
1387
  readPackageIdentity,
1092
1388
  readPandaVersion,
1389
+ readPublishFilesField,
1390
+ resolvePublishedPandaRange,
1093
1391
  resolveSmartInclude,
1094
1392
  syncExports,
1095
1393
  toPosixPath,
package/dist/merge.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  mergeConfigs,
3
3
  mergeConfigsWithSources
4
- } from "./chunk-YKIDLZNO.js";
4
+ } from "./chunk-PER4IFQZ.js";
5
+ import "./chunk-R4R5RHIS.js";
5
6
  export {
6
7
  mergeConfigs,
7
8
  mergeConfigsWithSources
package/dist/serialize.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  createConfigSnapshot
3
- } from "./chunk-VYX3JX5J.js";
3
+ } from "./chunk-U6KCSKCU.js";
4
+ import "./chunk-R4R5RHIS.js";
4
5
  export {
5
6
  createConfigSnapshot
6
7
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pandacss/config",
3
- "version": "2.0.0-beta.7",
3
+ "version": "2.0.0-beta.9",
4
4
  "description": "Self-contained loader that bundles and serializes a Panda config for the Rust compiler",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -45,8 +45,8 @@
45
45
  "magic-string": "^0.30.21",
46
46
  "microdiff": "1.5.0",
47
47
  "rolldown": "1.0.0-rc.17",
48
- "@pandacss/compiler-shared": "2.0.0-beta.7",
49
- "@pandacss/types": "2.0.0-beta.7"
48
+ "@pandacss/compiler-shared": "2.0.0-beta.9",
49
+ "@pandacss/types": "2.0.0-beta.9"
50
50
  },
51
51
  "engines": {
52
52
  "node": ">=22"