@stylexswc/postcss-plugin 0.15.1 → 0.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # PostCSS plugin with NAPI-RS StyleX compiler integration
2
2
 
3
+ > Part of the
4
+ > [StyleX SWC Plugin](https://github.com/Dwlad90/stylex-swc-plugin#readme)
5
+ > workspace
6
+
3
7
  `PostCSS plugin` for an unofficial
4
8
  [`napi-rs`](https://github.com/dwlad90/stylex-swc-plugin/tree/develop/crates/stylex-rs-compiler)
5
9
  compiler that includes the StyleX SWC code transformation under the hood.
@@ -103,33 +107,46 @@ import '[fileName].css';
103
107
  The plugin accepts the following configuration options:
104
108
 
105
109
  > [!NOTE]
106
- > **Features:** The `include` and `exclude` options are exclusive to this NAPI-RS compiler implementation and are not available in the official StyleX Babel plugin.
110
+ > **Features:** The `include` and `exclude` options are exclusive to
111
+ > this NAPI-RS compiler implementation and are not available in the official
112
+ > StyleX Babel plugin.
107
113
 
108
114
  ### `include`
109
115
 
110
116
  - Type: `(string | RegExp)[]`
111
- - Optional
112
- - Description: **RS-compiler Only** An array of glob patterns or regular expressions to include specific files for StyleX transformation.
113
- When specified, only files matching at least one of these patterns will be discovered and transformed.
114
- Patterns are matched against paths relative to the current working directory.
115
- Supports regex lookahead/lookbehind for advanced filtering.
117
+ - Default: auto-discovered
118
+ - Description: **RS-compiler Only** An array of glob patterns or regular
119
+ expressions to include specific files for StyleX transformation. When
120
+ specified, only files matching at least one of these patterns will be
121
+ discovered and transformed. Patterns are matched against paths relative to the
122
+ current working directory. Supports regex lookahead/lookbehind for advanced
123
+ filtering.
124
+
125
+ When omitted, the plugin auto-discovers source files in the project `cwd` and
126
+ direct dependencies that use StyleX.
116
127
 
117
128
  ### `exclude`
118
129
 
119
130
  - Type: `(string | RegExp)[]`
120
131
  - Optional
121
- - Description: **RS-compiler Only** An array of glob patterns or regular expressions to exclude specific files from StyleX transformation.
122
- Files matching any of these patterns will not be transformed, even if they match an `include` pattern.
123
- Patterns are matched against paths relative to the current working directory.
124
- Supports regex lookahead/lookbehind for advanced filtering.
132
+ - Description: **RS-compiler Only** An array of glob patterns or regular
133
+ expressions to exclude specific files from StyleX transformation. Files
134
+ matching any of these patterns will not be transformed, even if they match an
135
+ `include` pattern. Patterns are matched against paths relative to the current
136
+ working directory. Supports regex lookahead/lookbehind for advanced filtering.
137
+
138
+ When `include` is omitted, the plugin automatically excludes common build and
139
+ dependency folders (for example `node_modules`, `.next`, `dist`, `build`) to
140
+ keep discovery focused on source files.
125
141
 
126
142
  ### `rsOptions`
127
143
 
128
144
  - Type: `StyleXOptions`
129
145
  - Optional
130
146
  - Default: `{}`
131
- - Description: StyleX compiler options passed to the StyleX compiler.
132
- For standard StyleX options, see the [official StyleX documentation](https://stylexjs.com/docs/api/configuration/babel-plugin/).
147
+ - Description: StyleX compiler options passed to the StyleX compiler. For
148
+ standard StyleX options, see the
149
+ [official StyleX documentation](https://stylexjs.com/docs/api/configuration/babel-plugin/).
133
150
 
134
151
  ### `useCSSLayers`
135
152
 
@@ -143,7 +160,8 @@ The plugin accepts the following configuration options:
143
160
  - Type: `string`
144
161
  - Optional
145
162
  - Default: `process.cwd()`
146
- - Description: Current working directory for resolving files
163
+ - Description: Current working directory for resolving files. Dependency paths
164
+ and config resolution use this value.
147
165
 
148
166
  ### `isDev`
149
167
 
@@ -151,6 +169,16 @@ The plugin accepts the following configuration options:
151
169
  - Optional
152
170
  - Description: Whether the plugin is running in development mode
153
171
 
172
+ ### `importSources`
173
+
174
+ - Type: `Array<string | { from: string, as: string }>`
175
+ - Optional
176
+ - Description: Override import sources at the PostCSS plugin level.
177
+
178
+ When provided, takes precedence over `rsOptions.importSources`. When omitted,
179
+ falls back to `rsOptions.importSources`, then the built-in defaults
180
+ (`@stylexjs/stylex`, `stylex`).
181
+
154
182
  ## Path Filtering Examples
155
183
 
156
184
  **Include only specific directories:**
@@ -211,3 +239,16 @@ The plugin accepts the following configuration options:
211
239
  },
212
240
  }
213
241
  ```
242
+
243
+ ## Debugging auto-discovery
244
+
245
+ Set `STYLEX_POSTCSS_DEBUG=1` to print resolved plugin inputs, including:
246
+
247
+ - resolved `importSources` and where they came from
248
+ - final `include` and `exclude` globs
249
+ - discovered dependency directories
250
+
251
+ ## License
252
+
253
+ MIT — see
254
+ [LICENSE](https://github.com/Dwlad90/stylex-swc-plugin/blob/develop/LICENSE)
@@ -1 +1 @@
1
- {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/builder.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAU1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAoDpE,iBAAS,aAAa;6BAsBY,OAAO,CAAC,IAAI,KAAG,MAAM,GAAG,IAAI;yBAdhC,kBAAkB;0CA4DD,gBAAgB;;cAlFjD,gBAAgB;aAAO,MAAM;cAAQ,MAAM;;cAC3C,YAAY;cAAQ,MAAM;;EAoKvC;AAED,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/builder.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,EAAE,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAU1C,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AA2GpE,iBAAS,aAAa;6BAsBY,OAAO,CAAC,IAAI,KAAG,MAAM,GAAG,IAAI;yBAdhC,kBAAkB;0CA8FD,gBAAgB;;cAtKjD,gBAAgB;aAAO,MAAM;cAAQ,MAAM;;cAC3C,YAAY;cAAQ,MAAM;;EA0PvC;AAED,eAAe,aAAa,CAAC"}
package/dist/builder.js CHANGED
@@ -11,6 +11,10 @@ const is_glob_1 = __importDefault(require("is-glob"));
11
11
  const glob_parent_1 = __importDefault(require("glob-parent"));
12
12
  const bundler_1 = __importDefault(require("./bundler"));
13
13
  const rs_compiler_1 = require("@stylexswc/rs-compiler");
14
+ const NODE_MODULES_CATCH_ALL_EXCLUDE_PATTERNS = new Set([
15
+ 'node_modules/**',
16
+ '**/node_modules/**',
17
+ ]);
14
18
  // Parses a glob pattern and extracts its base directory and pattern.
15
19
  // Returns an object with `base` and `glob` properties.
16
20
  function parseGlob(pattern) {
@@ -34,7 +38,7 @@ function parseGlob(pattern) {
34
38
  return { base, glob };
35
39
  }
36
40
  // Parses a file path or glob pattern into a PostCSS dependency message.
37
- function parseDependency(fileOrGlob) {
41
+ function parseDependency(fileOrGlob, cwd) {
38
42
  // License: MIT
39
43
  // Based on:
40
44
  // https://github.com/chakra-ui/panda/blob/6ab003795c0b076efe6879a2e6a2a548cb96580e/packages/node/src/parse-dependency.ts
@@ -44,13 +48,57 @@ function parseDependency(fileOrGlob) {
44
48
  let message;
45
49
  if ((0, is_glob_1.default)(fileOrGlob)) {
46
50
  const { base, glob } = parseGlob(fileOrGlob);
47
- message = { type: 'dir-dependency', dir: (0, path_1.normalize)((0, path_1.resolve)(base)), glob };
51
+ message = {
52
+ type: 'dir-dependency',
53
+ dir: (0, path_1.normalize)((0, path_1.resolve)(cwd, base)),
54
+ glob,
55
+ };
48
56
  }
49
57
  else {
50
- message = { type: 'dependency', file: (0, path_1.normalize)((0, path_1.resolve)(fileOrGlob)) };
58
+ message = { type: 'dependency', file: (0, path_1.normalize)((0, path_1.resolve)(cwd, fileOrGlob)) };
51
59
  }
52
60
  return message;
53
61
  }
62
+ function normalizeGlobPattern(pattern) {
63
+ return String(pattern).replace(/\\/g, '/').replace(/^\.\//, '');
64
+ }
65
+ function isNodeModulesCatchAllExcludePattern(pattern) {
66
+ return NODE_MODULES_CATCH_ALL_EXCLUDE_PATTERNS.has(normalizeGlobPattern(pattern));
67
+ }
68
+ function toCanonicalFilePath(file, cwd) {
69
+ return (0, path_1.normalize)((0, path_1.resolve)(cwd, file));
70
+ }
71
+ /**
72
+ * When an absolute include pattern points into node_modules, we remove the broad
73
+ * catch-all excludes (node_modules/** and **\/node_modules/**) so the specific
74
+ * package path can be matched. However that also allows deeply nested
75
+ * node_modules within the discovered package (e.g. transitive deps that
76
+ * themselves have their own node_modules) to be scanned.
77
+ *
78
+ * This helper computes a *specific* absolute exclude pattern that prevents
79
+ * scanning the nested node_modules inside the matched package's base directory,
80
+ * while still letting the package's own source files through.
81
+ *
82
+ * The pattern must be absolute because fast-glob does not apply relative ignore
83
+ * patterns to absolute match results (which occur when the include pattern is
84
+ * itself absolute).
85
+ *
86
+ * Example:
87
+ * includePattern = '/app/node_modules/@acme/ui/**\/*.{ts,tsx}'
88
+ * → '/app/node_modules/@acme/ui/node_modules/**'
89
+ */
90
+ function nestedNodeModulesExcludeFor(includePattern) {
91
+ if (!node_path_1.default.isAbsolute(includePattern)) {
92
+ return null;
93
+ }
94
+ // globParent gives the base directory before the glob wildcards begin.
95
+ // e.g. '/app/node_modules/@acme/ui/**/*.ts' → '/app/node_modules/@acme/ui'
96
+ const baseDir = (0, glob_parent_1.default)(includePattern);
97
+ // Return an absolute ignore pattern so fast-glob matches it correctly
98
+ // when the include pattern is absolute (relative ignore patterns are not
99
+ // applied to absolute match results).
100
+ return `${baseDir.split(node_path_1.default.sep).join('/')}/node_modules/**`;
101
+ }
54
102
  // Creates a builder for transforming files and bundling StyleX CSS.
55
103
  function createBuilder() {
56
104
  let config = null;
@@ -86,24 +134,55 @@ function createBuilder() {
86
134
  const isGlobPattern = (p) => !isRegexPattern(p);
87
135
  const globPatterns = (include || []).filter(isGlobPattern).map(p => String(p));
88
136
  const hasRegexPatterns = (include || []).some(isRegexPattern) || (exclude || []).some(isRegexPattern);
137
+ if (globPatterns.length === 0 && !hasRegexPatterns) {
138
+ return [];
139
+ }
89
140
  // Use fast-glob with glob patterns for initial discovery
90
141
  const globExclude = (exclude || []).filter(isGlobPattern).map(p => String(p));
91
- let files = (0, fast_glob_1.globSync)(globPatterns.length > 0 ? globPatterns : [], {
92
- onlyFiles: true,
93
- ignore: globExclude,
94
- cwd,
95
- });
96
- // Normalize file paths
97
- files = files.map(file => (file.includes(cwd || '/') ? file : node_path_1.default.resolve(cwd || '/', file)));
142
+ const ignoreWithoutNodeModulesCatchAll = globExclude.filter((pattern) => !isNodeModulesCatchAllExcludePattern(pattern));
143
+ const files = new Set();
144
+ for (const includePattern of globPatterns) {
145
+ const isAbsolutePattern = node_path_1.default.isAbsolute(includePattern);
146
+ const pointsToNodeModules = /(^|[/\\])node_modules([/\\]|$)/.test(includePattern);
147
+ let ignore;
148
+ if (isAbsolutePattern && pointsToNodeModules) {
149
+ // Remove broad catch-all patterns so this specific node_modules path
150
+ // can be matched, but add back a targeted exclude for any nested
151
+ // node_modules *within* the matched package to avoid scanning
152
+ // transitive dependencies' source files.
153
+ const nestedExclude = nestedNodeModulesExcludeFor(includePattern);
154
+ ignore = [
155
+ ...ignoreWithoutNodeModulesCatchAll,
156
+ ...(nestedExclude != null ? [nestedExclude] : []),
157
+ ];
158
+ }
159
+ else {
160
+ ignore = globExclude;
161
+ }
162
+ const matchedFiles = (0, fast_glob_1.globSync)(includePattern, {
163
+ onlyFiles: true,
164
+ ignore,
165
+ cwd,
166
+ });
167
+ for (const file of matchedFiles) {
168
+ files.add(toCanonicalFilePath(file, cwd || '/'));
169
+ }
170
+ }
171
+ let result = Array.from(files);
98
172
  // If there are regex patterns, filter using shouldTransformFile
99
173
  if (hasRegexPatterns) {
100
- files = files.filter(file => (0, rs_compiler_1.shouldTransformFile)(file, include, exclude));
174
+ result = result.filter(file => (0, rs_compiler_1.shouldTransformFile)(file, include, exclude));
101
175
  }
102
- return files;
176
+ return result;
103
177
  }
104
178
  // Transforms the included files, bundles the CSS, and returns the result.
105
179
  function build({ shouldSkipTransformError }) {
106
180
  const { cwd, rsOptions, useCSSLayers, isDev } = getConfig();
181
+ const transformedOptions = {
182
+ useLayers: useCSSLayers,
183
+ enableLTRRTLComments: rsOptions?.enableLTRRTLComments,
184
+ legacyDisableLayers: rsOptions?.legacyDisableLayers,
185
+ };
107
186
  const files = getFiles();
108
187
  const filesToTransform = [];
109
188
  // Remove deleted files since the last build
@@ -143,20 +222,16 @@ function createBuilder() {
143
222
  });
144
223
  return transformedResult;
145
224
  });
146
- const css = bundler.bundle({
147
- useCSSLayers,
148
- enableLTRRTLComments: rsOptions?.enableLTRRTLComments,
149
- legacyDisableLayers: rsOptions?.legacyDisableLayers,
150
- });
225
+ const css = bundler.bundle(transformedOptions);
151
226
  return css;
152
227
  }
153
228
  // Retrieves the dependencies that PostCSS should watch.
154
229
  function getDependencies() {
155
- const { include } = getConfig();
230
+ const { include, cwd } = getConfig();
156
231
  const dependencies = [];
157
232
  for (const fileOrGlob of include || []) {
158
233
  const fileOrGlobString = fileOrGlob.toString();
159
- const dependency = parseDependency(fileOrGlobString);
234
+ const dependency = parseDependency(fileOrGlobString, cwd || process.cwd());
160
235
  if (dependency != null) {
161
236
  dependencies.push(dependency);
162
237
  }
package/dist/bundler.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- import type { StyleXOptions } from '@stylexswc/rs-compiler';
1
+ import type { StyleXOptions, TransformedOptions } from '@stylexswc/rs-compiler';
2
2
  import type { TransformOptions, StyleXPluginOption } from './types';
3
3
  export default function createBundler(): {
4
4
  shouldTransform: (sourceCode: string, rsOptions?: StyleXPluginOption["rsOptions"]) => boolean | undefined;
5
5
  transform: (id: string, sourceCode: string, rsOptions: StyleXOptions, options: TransformOptions) => import("@stylexswc/rs-compiler").StyleXTransformResult;
6
6
  remove: (id: string) => void;
7
- bundle: ({ useCSSLayers, enableLTRRTLComments, legacyDisableLayers, }: Pick<StyleXPluginOption, "useCSSLayers"> & Pick<NonNullable<StyleXPluginOption["rsOptions"]>, "enableLTRRTLComments" | "legacyDisableLayers">) => string;
7
+ bundle: (transformedOptions: TransformedOptions) => string;
8
8
  };
9
9
  //# sourceMappingURL=bundler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bundler.d.ts","sourceRoot":"","sources":["../../src/bundler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAGpE,MAAM,CAAC,OAAO,UAAU,aAAa;kCAIE,MAAM,cAAc,kBAAkB,CAAC,WAAW,CAAC;oBAqClF,MAAM,cACE,MAAM,aACP,aAAa,WACf,gBAAgB;iBAqCP,MAAM;2EASvB,IAAI,CAAC,kBAAkB,EAAE,cAAc,CAAC,GACzC,IAAI,CACF,WAAW,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC,EAC5C,sBAAsB,GAAG,qBAAqB,CAC/C;EAiBJ"}
1
+ {"version":3,"file":"bundler.d.ts","sourceRoot":"","sources":["../../src/bundler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEhF,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAGpE,MAAM,CAAC,OAAO,UAAU,aAAa;kCAIE,MAAM,cAAc,kBAAkB,CAAC,WAAW,CAAC;oBAoClF,MAAM,cACE,MAAM,aACP,aAAa,WACf,gBAAgB;iBAqCP,MAAM;iCAKU,kBAAkB;EAavD"}
package/dist/bundler.js CHANGED
@@ -15,11 +15,11 @@ function createBundler() {
15
15
  let parsedImportSources;
16
16
  try {
17
17
  parsedImportSources = importSources?.map(importSource => {
18
- const a = typeof importSource === 'string' ? JSON.parse(importSource) : importSource;
19
- return a;
18
+ return typeof importSource === 'string' ? JSON.parse(importSource) : importSource;
20
19
  });
21
20
  }
22
21
  catch (error) {
22
+ console.warn(error);
23
23
  parsedImportSources = importSources;
24
24
  }
25
25
  const shouldTransform = parsedImportSources?.some(importSource => {
@@ -69,13 +69,9 @@ function createBundler() {
69
69
  styleXRulesMap.delete(id);
70
70
  }
71
71
  // Bundles all collected StyleX rules into a single CSS string.
72
- function bundle({ useCSSLayers, enableLTRRTLComments, legacyDisableLayers, }) {
72
+ function bundle(transformedOptions) {
73
73
  const rules = Array.from(styleXRulesMap.values()).flat();
74
- const css = babel_plugin_1.default.processStylexRules(rules, {
75
- useLayers: useCSSLayers,
76
- enableLTRRTLComments,
77
- legacyDisableLayers,
78
- });
74
+ const css = babel_plugin_1.default.processStylexRules(rules, transformedOptions);
79
75
  return css;
80
76
  }
81
77
  return {
@@ -0,0 +1,49 @@
1
+ import type { StyleXPluginOption } from './types';
2
+ type ImportSource = string | {
3
+ from: string;
4
+ as?: string;
5
+ };
6
+ export declare const DEFAULT_IMPORT_SOURCES: string[];
7
+ export declare const DEFAULT_INCLUDE_GLOB = "**/*.{js,jsx,mjs,cjs,ts,tsx,mts,cts}";
8
+ export declare const AUTO_DISCOVERY_EXCLUDES: string[];
9
+ export interface ImportSourcesResolution {
10
+ importSources: ImportSource[];
11
+ source: 'postcss-option' | 'rs-options' | 'defaults';
12
+ }
13
+ /**
14
+ * Resolves the effective importSources with metadata about where they came from.
15
+ *
16
+ * Precedence:
17
+ * 1. Explicit PostCSS `importSources` option
18
+ * 2. Inferred from `rsOptions.importSources`
19
+ * 3. Built-in defaults (`@stylexjs/stylex`, `stylex`)
20
+ */
21
+ export declare function resolveImportSourcesWithMetadata({ importSources, rsOptions, }: {
22
+ importSources?: ImportSource[];
23
+ rsOptions?: StyleXPluginOption['rsOptions'];
24
+ }): ImportSourcesResolution;
25
+ export declare function resolveImportSources({ importSources, rsOptions, }: {
26
+ importSources?: ImportSource[];
27
+ rsOptions?: StyleXPluginOption['rsOptions'];
28
+ }): ImportSource[];
29
+ export interface IncludeResolution {
30
+ include: Array<string | RegExp>;
31
+ discoveredDependencyDirectories: string[];
32
+ hasExplicitInclude: boolean;
33
+ }
34
+ export declare function resolveIncludeWithMetadata({ cwd, include, importSources, }: {
35
+ cwd: string;
36
+ include?: StyleXPluginOption['include'];
37
+ importSources: ImportSource[];
38
+ }): IncludeResolution;
39
+ export declare function resolveInclude({ cwd, include, importSources, }: {
40
+ cwd: string;
41
+ include?: StyleXPluginOption['include'];
42
+ importSources: ImportSource[];
43
+ }): Array<string | RegExp>;
44
+ export declare function resolveExclude({ include, exclude, }: {
45
+ include?: StyleXPluginOption['include'];
46
+ exclude?: StyleXPluginOption['exclude'];
47
+ }): Array<string | RegExp>;
48
+ export {};
49
+ //# sourceMappingURL=discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/discovery.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD,KAAK,YAAY,GAAG,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3D,eAAO,MAAM,sBAAsB,EAAE,MAAM,EAAmC,CAAC;AAe/E,eAAO,MAAM,oBAAoB,yCAAyC,CAAC;AAI3E,eAAO,MAAM,uBAAuB,UAcnC,CAAC;AA2OF,MAAM,WAAW,uBAAuB;IACtC,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,MAAM,EAAE,gBAAgB,GAAG,YAAY,GAAG,UAAU,CAAC;CACtD;AAED;;;;;;;GAOG;AACH,wBAAgB,gCAAgC,CAAC,EAC/C,aAAa,EACb,SAAS,GACV,EAAE;IACD,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,SAAS,CAAC,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC;CAC7C,GAAG,uBAAuB,CAuB1B;AAED,wBAAgB,oBAAoB,CAAC,EACnC,aAAa,EACb,SAAS,GACV,EAAE;IACD,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,SAAS,CAAC,EAAE,kBAAkB,CAAC,WAAW,CAAC,CAAC;CAC7C,GAAG,YAAY,EAAE,CAEjB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;IAChC,+BAA+B,EAAE,MAAM,EAAE,CAAC;IAC1C,kBAAkB,EAAE,OAAO,CAAC;CAC7B;AAED,wBAAgB,0BAA0B,CAAC,EACzC,GAAG,EACH,OAAO,EACP,aAAa,GACd,EAAE;IACD,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACxC,aAAa,EAAE,YAAY,EAAE,CAAC;CAC/B,GAAG,iBAAiB,CA4BpB;AAED,wBAAgB,cAAc,CAAC,EAC7B,GAAG,EACH,OAAO,EACP,aAAa,GACd,EAAE;IACD,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACxC,aAAa,EAAE,YAAY,EAAE,CAAC;CAC/B,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAEzB;AAED,wBAAgB,cAAc,CAAC,EAC7B,OAAO,EACP,OAAO,GACR,EAAE;IACD,OAAO,CAAC,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;IACxC,OAAO,CAAC,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAC;CACzC,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CASzB"}
@@ -0,0 +1,277 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.AUTO_DISCOVERY_EXCLUDES = exports.DEFAULT_INCLUDE_GLOB = exports.DEFAULT_IMPORT_SOURCES = void 0;
7
+ exports.resolveImportSourcesWithMetadata = resolveImportSourcesWithMetadata;
8
+ exports.resolveImportSources = resolveImportSources;
9
+ exports.resolveIncludeWithMetadata = resolveIncludeWithMetadata;
10
+ exports.resolveInclude = resolveInclude;
11
+ exports.resolveExclude = resolveExclude;
12
+ const node_path_1 = __importDefault(require("node:path"));
13
+ const node_fs_1 = __importDefault(require("node:fs"));
14
+ const node_module_1 = require("node:module");
15
+ exports.DEFAULT_IMPORT_SOURCES = ['@stylexjs/stylex', 'stylex'];
16
+ const DEFAULT_IMPORT_SOURCE_PACKAGES = new Set(exports.DEFAULT_IMPORT_SOURCES.map((source) => {
17
+ if (source.startsWith('@')) {
18
+ const parts = source.split('/');
19
+ const scope = parts[0];
20
+ const name = parts[1];
21
+ return scope != null && name != null ? `${scope}/${name}` : null;
22
+ }
23
+ const packageName = source.split('/')[0];
24
+ return packageName ?? null;
25
+ }).filter(Boolean));
26
+ exports.DEFAULT_INCLUDE_GLOB = '**/*.{js,jsx,mjs,cjs,ts,tsx,mts,cts}';
27
+ // Keep auto-discovery focused on source files.
28
+ // Explicit include values from users are always respected.
29
+ exports.AUTO_DISCOVERY_EXCLUDES = [
30
+ 'node_modules/**',
31
+ '**/node_modules/**',
32
+ '.git/**',
33
+ '.next/**',
34
+ '.nuxt/**',
35
+ '.svelte-kit/**',
36
+ '.turbo/**',
37
+ '.cache/**',
38
+ 'dist/**',
39
+ 'build/**',
40
+ 'coverage/**',
41
+ 'tmp/**',
42
+ 'temp/**',
43
+ ];
44
+ function toArray(value) {
45
+ if (value == null) {
46
+ return [];
47
+ }
48
+ return Array.isArray(value) ? value : [value];
49
+ }
50
+ function dedupe(items) {
51
+ return Array.from(new Set(items));
52
+ }
53
+ function readJSON(file) {
54
+ try {
55
+ const content = node_fs_1.default.readFileSync(file, 'utf8');
56
+ return JSON.parse(content);
57
+ }
58
+ catch {
59
+ return null;
60
+ }
61
+ }
62
+ function toPackageName(importSource) {
63
+ const source = typeof importSource === 'string'
64
+ ? importSource
65
+ : importSource?.from;
66
+ if (source == null || source.startsWith('.') || source.startsWith('/')) {
67
+ return null;
68
+ }
69
+ if (source.startsWith('@')) {
70
+ const parts = source.split('/');
71
+ const scope = parts[0];
72
+ const name = parts[1];
73
+ if (scope != null && name != null) {
74
+ return `${scope}/${name}`;
75
+ }
76
+ return null;
77
+ }
78
+ const packageName = source.split('/')[0];
79
+ return packageName ?? null;
80
+ }
81
+ function hasStylexDependency(manifest, targetPackages) {
82
+ if (manifest == null || typeof manifest !== 'object') {
83
+ return false;
84
+ }
85
+ const dependencyFields = ['dependencies', 'peerDependencies', 'optionalDependencies'];
86
+ return dependencyFields.some((field) => {
87
+ const deps = manifest[field];
88
+ if (deps == null || typeof deps !== 'object') {
89
+ return false;
90
+ }
91
+ return Object.keys(deps).some((depName) => targetPackages.has(depName));
92
+ });
93
+ }
94
+ function findDependencyManifestPathFromEntry(entryPath, dependencyName) {
95
+ let dir = node_path_1.default.dirname(entryPath);
96
+ for (;;) {
97
+ const candidate = node_path_1.default.join(dir, 'package.json');
98
+ const manifest = readJSON(candidate);
99
+ if (manifest != null && manifest.name === dependencyName) {
100
+ return candidate;
101
+ }
102
+ const parent = node_path_1.default.dirname(dir);
103
+ if (parent === dir) {
104
+ return null;
105
+ }
106
+ dir = parent;
107
+ }
108
+ }
109
+ function resolveDependencyManifestPath(requireFromRoot, dependencyName) {
110
+ try {
111
+ return requireFromRoot.resolve(`${dependencyName}/package.json`);
112
+ }
113
+ catch {
114
+ // fall through
115
+ }
116
+ try {
117
+ const entryPath = requireFromRoot.resolve(dependencyName);
118
+ return findDependencyManifestPathFromEntry(entryPath, dependencyName);
119
+ }
120
+ catch {
121
+ // fall through
122
+ }
123
+ return null;
124
+ }
125
+ function includePackageFromImportSource({ importSource, cwd, requireFromRoot, discoveredDirectories, }) {
126
+ const source = typeof importSource === 'string'
127
+ ? importSource
128
+ : importSource?.from;
129
+ if (typeof source !== 'string') {
130
+ return;
131
+ }
132
+ if (source.startsWith('.') || source.startsWith('/')) {
133
+ return;
134
+ }
135
+ const packageName = toPackageName(source);
136
+ if (packageName == null) {
137
+ return;
138
+ }
139
+ if (DEFAULT_IMPORT_SOURCE_PACKAGES.has(packageName)) {
140
+ return;
141
+ }
142
+ const manifestPath = resolveDependencyManifestPath(requireFromRoot, packageName);
143
+ if (manifestPath == null) {
144
+ return;
145
+ }
146
+ const directory = node_path_1.default.dirname(manifestPath);
147
+ if (directory !== node_path_1.default.resolve(cwd)) {
148
+ discoveredDirectories.add(directory);
149
+ }
150
+ }
151
+ function getDirectDependencies(manifest) {
152
+ if (manifest == null || typeof manifest !== 'object') {
153
+ return [];
154
+ }
155
+ const dependencyFields = [
156
+ 'dependencies',
157
+ 'devDependencies',
158
+ 'peerDependencies',
159
+ 'optionalDependencies',
160
+ ];
161
+ const dependencies = new Set();
162
+ for (const field of dependencyFields) {
163
+ const deps = manifest[field];
164
+ if (deps == null || typeof deps !== 'object') {
165
+ continue;
166
+ }
167
+ for (const name of Object.keys(deps)) {
168
+ dependencies.add(name);
169
+ }
170
+ }
171
+ return Array.from(dependencies);
172
+ }
173
+ function toAbsoluteGlob(directory, globPattern) {
174
+ const normalizedDir = node_path_1.default.resolve(directory).split(node_path_1.default.sep).join('/');
175
+ return `${normalizedDir}/${globPattern}`;
176
+ }
177
+ function discoverStylexPackageDirectories({ cwd, importSources, }) {
178
+ const rootPackageJsonPath = node_path_1.default.join(node_path_1.default.resolve(cwd), 'package.json');
179
+ if (!node_fs_1.default.existsSync(rootPackageJsonPath)) {
180
+ return [];
181
+ }
182
+ const rootPackageDir = node_path_1.default.dirname(rootPackageJsonPath);
183
+ const requireFromRoot = (0, node_module_1.createRequire)(rootPackageJsonPath);
184
+ const rootManifest = readJSON(rootPackageJsonPath);
185
+ const dependencyNames = getDirectDependencies(rootManifest);
186
+ const targetPackages = new Set(importSources.map(toPackageName).filter(Boolean).concat(exports.DEFAULT_IMPORT_SOURCES));
187
+ const discoveredDirectories = new Set();
188
+ for (const dependencyName of dependencyNames) {
189
+ const manifestPath = resolveDependencyManifestPath(requireFromRoot, dependencyName);
190
+ if (manifestPath == null) {
191
+ continue;
192
+ }
193
+ const manifest = readJSON(manifestPath);
194
+ if (!hasStylexDependency(manifest, targetPackages)) {
195
+ continue;
196
+ }
197
+ const dependencyDir = node_path_1.default.dirname(manifestPath);
198
+ // Avoid accidentally re-scanning the project root in monorepo edge cases.
199
+ if (dependencyDir !== rootPackageDir) {
200
+ discoveredDirectories.add(dependencyDir);
201
+ }
202
+ }
203
+ for (const importSource of importSources) {
204
+ includePackageFromImportSource({
205
+ importSource,
206
+ cwd,
207
+ requireFromRoot,
208
+ discoveredDirectories,
209
+ });
210
+ }
211
+ return Array.from(discoveredDirectories);
212
+ }
213
+ /**
214
+ * Resolves the effective importSources with metadata about where they came from.
215
+ *
216
+ * Precedence:
217
+ * 1. Explicit PostCSS `importSources` option
218
+ * 2. Inferred from `rsOptions.importSources`
219
+ * 3. Built-in defaults (`@stylexjs/stylex`, `stylex`)
220
+ */
221
+ function resolveImportSourcesWithMetadata({ importSources, rsOptions, }) {
222
+ // 1. Explicit importSources from PostCSS plugin options
223
+ if (Array.isArray(importSources) && importSources.length > 0) {
224
+ return {
225
+ importSources: dedupe(importSources),
226
+ source: 'postcss-option',
227
+ };
228
+ }
229
+ // 2. Inferred from rsOptions.importSources
230
+ const rsImportSources = rsOptions?.importSources;
231
+ if (Array.isArray(rsImportSources) && rsImportSources.length > 0) {
232
+ return {
233
+ importSources: dedupe([...exports.DEFAULT_IMPORT_SOURCES, ...rsImportSources]),
234
+ source: 'rs-options',
235
+ };
236
+ }
237
+ // 3. Built-in defaults
238
+ return {
239
+ importSources: exports.DEFAULT_IMPORT_SOURCES,
240
+ source: 'defaults',
241
+ };
242
+ }
243
+ function resolveImportSources({ importSources, rsOptions, }) {
244
+ return resolveImportSourcesWithMetadata({ importSources, rsOptions }).importSources;
245
+ }
246
+ function resolveIncludeWithMetadata({ cwd, include, importSources, }) {
247
+ const normalizedInclude = toArray(include);
248
+ const hasExplicitInclude = normalizedInclude.length > 0;
249
+ if (hasExplicitInclude) {
250
+ return {
251
+ include: dedupe(normalizedInclude),
252
+ discoveredDependencyDirectories: [],
253
+ hasExplicitInclude,
254
+ };
255
+ }
256
+ const discoveredDependencyDirectories = discoverStylexPackageDirectories({
257
+ cwd,
258
+ importSources: importSources.filter((s) => typeof s === 'string' || typeof s === 'object'),
259
+ });
260
+ const discoveredDependencyGlobs = discoveredDependencyDirectories.map((dir) => toAbsoluteGlob(dir, exports.DEFAULT_INCLUDE_GLOB));
261
+ return {
262
+ include: dedupe([exports.DEFAULT_INCLUDE_GLOB, ...discoveredDependencyGlobs]),
263
+ discoveredDependencyDirectories,
264
+ hasExplicitInclude,
265
+ };
266
+ }
267
+ function resolveInclude({ cwd, include, importSources, }) {
268
+ return resolveIncludeWithMetadata({ cwd, include, importSources }).include;
269
+ }
270
+ function resolveExclude({ include, exclude, }) {
271
+ const normalizedExclude = toArray(exclude);
272
+ const hasExplicitInclude = toArray(include).length > 0;
273
+ if (hasExplicitInclude) {
274
+ return normalizedExclude;
275
+ }
276
+ return dedupe([...exports.AUTO_DISCOVERY_EXCLUDES, ...normalizedExclude]);
277
+ }