@wix/zero-config-implementation 1.22.0 → 1.24.0

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.
@@ -0,0 +1,2 @@
1
+ import { Result } from 'neverthrow';
2
+ export declare function compileSass(filePath: string): Result<string, Error>;
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "registry": "https://registry.npmjs.org/",
5
5
  "access": "public"
6
6
  },
7
- "version": "1.22.0",
7
+ "version": "1.24.0",
8
8
  "description": "Core library for extracting component manifests from JS and CSS files",
9
9
  "type": "module",
10
10
  "main": "dist/index.js",
@@ -35,8 +35,14 @@
35
35
  "peerDependencies": {
36
36
  "react": "^18.0.0 || ^19.0.0",
37
37
  "react-dom": "^18.0.0 || ^19.0.0",
38
+ "sass": "^1.71.1",
38
39
  "typescript": "^5.0.0"
39
40
  },
41
+ "peerDependenciesMeta": {
42
+ "sass": {
43
+ "optional": true
44
+ }
45
+ },
40
46
  "dependencies": {
41
47
  "@wix/zero-config-schema": "1.1.0",
42
48
  "lightningcss": "^1.31.1"
@@ -53,6 +59,7 @@
53
59
  "neverthrow": "^8.2.0",
54
60
  "parse5": "^7.1.2",
55
61
  "react-docgen-typescript": "^2.4.0",
62
+ "sass": "^1.98.0",
56
63
  "tsconfck": "^3.1.6",
57
64
  "typedoc": "^0.28.16",
58
65
  "typedoc-plugin-markdown": "^4.9.0",
@@ -76,5 +83,5 @@
76
83
  ]
77
84
  }
78
85
  },
79
- "falconPackageHash": "96e638a26c56c097934553199ad6afa8864eeed45a42d5b9246f0f31"
86
+ "falconPackageHash": "79d9ab055f999610e162c914b9c616eed125490c1816f8b91e2dac53"
80
87
  }
@@ -0,0 +1,40 @@
1
+ import { existsSync } from 'node:fs'
2
+ import { createRequire } from 'node:module'
3
+ import { dirname, join } from 'node:path'
4
+ import { Result, err } from 'neverthrow'
5
+
6
+ function collectNodeModulesPaths(filePath: string): string[] {
7
+ const paths: string[] = []
8
+ let dir = dirname(filePath)
9
+ while (true) {
10
+ const candidate = join(dir, 'node_modules')
11
+ if (existsSync(candidate)) paths.push(candidate)
12
+ const parent = dirname(dir)
13
+ if (parent === dir) break
14
+ dir = parent
15
+ }
16
+ return paths
17
+ }
18
+
19
+ const require = createRequire(import.meta.url)
20
+
21
+ export function compileSass(filePath: string): Result<string, Error> {
22
+ let sass: typeof import('sass')
23
+ try {
24
+ sass = require('sass')
25
+ } catch {
26
+ return err(
27
+ new Error(
28
+ `Cannot process Sass file "${filePath}": the "sass" package is not installed. Install it with: npm install sass (or yarn add sass)`,
29
+ ),
30
+ )
31
+ }
32
+ const loadPaths = collectNodeModulesPaths(filePath)
33
+ return Result.fromThrowable(
34
+ () =>
35
+ sass.compile(filePath, {
36
+ loadPaths,
37
+ }).css,
38
+ (thrown) => (thrown instanceof Error ? thrown : new Error(String(thrown))),
39
+ )()
40
+ }
@@ -16,7 +16,7 @@ export function extractCssImports(program: Program): string[] {
16
16
  if (!ts.isImportDeclaration(node) || !ts.isStringLiteral(node.moduleSpecifier)) return
17
17
  const importPath = node.moduleSpecifier.text
18
18
 
19
- if (importPath.endsWith('.css')) {
19
+ if (importPath.endsWith('.css') || importPath.endsWith('.scss') || importPath.endsWith('.sass')) {
20
20
  const fullPath = path.resolve(path.dirname(sourceFile.fileName), importPath)
21
21
  cssFiles.add(fullPath)
22
22
  return
@@ -15,6 +15,7 @@ import type { CoupledComponentInfo, CoupledProp, DOMBinding, TrackingStores } fr
15
15
 
16
16
  import { matchCssSelectors, parseCss } from './information-extractors/css'
17
17
  import type { CSSParserAPI } from './information-extractors/css'
18
+ import { compileSass } from './information-extractors/css/sass-adapter'
18
19
 
19
20
  import type { ComponentType } from 'react'
20
21
 
@@ -336,8 +337,23 @@ function extractCssInfo(
336
337
 
337
338
  for (const cssPath of cssImportPaths) {
338
339
  try {
339
- // Read CSS file
340
- const cssContent = fs.readFileSync(cssPath, 'utf-8')
340
+ // Read and compile CSS file
341
+ let cssContent: string
342
+ if (cssPath.endsWith('.scss') || cssPath.endsWith('.sass')) {
343
+ const compiledCssResult = compileSass(cssPath)
344
+ if (compiledCssResult.isErr()) {
345
+ warnings.push({
346
+ componentName,
347
+ phase: 'css',
348
+ error: `Failed to parse ${cssPath}: ${compiledCssResult.error.message}`,
349
+ stack: compiledCssResult.error.stack,
350
+ })
351
+ continue
352
+ }
353
+ cssContent = compiledCssResult.value
354
+ } else {
355
+ cssContent = fs.readFileSync(cssPath, 'utf-8')
356
+ }
341
357
 
342
358
  // Parse CSS
343
359
  const api = parseCss(cssContent)