@tbela99/css-parser 1.3.1 → 1.3.3

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,5 +1,5 @@
1
1
  import { hwb2hsv } from './hsv.js';
2
- import { color2srgbvalues, toPrecisionAngle, getNumber } from './color.js';
2
+ import { color2srgbvalues, toPrecisionAngle, toPrecisionValue, getNumber } from './color.js';
3
3
  import { lch2rgbvalues, lab2rgbvalues, cmyk2rgbvalues } from './rgb.js';
4
4
  import './utils/constants.js';
5
5
  import { getComponents } from './utils/components.js';
@@ -76,12 +76,15 @@ function color2HslToken(token) {
76
76
  function hslToken(values) {
77
77
  values[0] = toPrecisionAngle(values[0] * 360);
78
78
  const chi = [
79
- { typ: EnumToken.NumberTokenType, val: values[0] },
80
- { typ: EnumToken.PercentageTokenType, val: values[1] * 100 },
81
- { typ: EnumToken.PercentageTokenType, val: values[2] * 100 },
79
+ { typ: EnumToken.NumberTokenType, val: toPrecisionValue(values[0]) },
80
+ { typ: EnumToken.PercentageTokenType, val: toPrecisionValue(values[1]) * 100 },
81
+ { typ: EnumToken.PercentageTokenType, val: toPrecisionValue(values[2]) * 100 },
82
82
  ];
83
83
  if (values.length == 4 && values[3] != 1) {
84
- chi.push({ typ: EnumToken.LiteralTokenType, val: '/' }, { typ: EnumToken.PercentageTokenType, val: values[3] * 100 });
84
+ chi.push({ typ: EnumToken.LiteralTokenType, val: '/' }, {
85
+ typ: EnumToken.PercentageTokenType,
86
+ val: values[3] * 100
87
+ });
85
88
  }
86
89
  return {
87
90
  typ: EnumToken.ColorTokenType,
@@ -147,12 +150,20 @@ function hwb2hslvalues(token) {
147
150
  return hsv2hsl(...hwb2hsv(...Object.values(hslvalues(token))));
148
151
  }
149
152
  function lab2hslvalues(token) {
153
+ const values = lab2rgbvalues(token);
154
+ if (values == null) {
155
+ return null;
156
+ }
150
157
  // @ts-ignore
151
- return rgbvalues2hslvalues(...lab2rgbvalues(token));
158
+ return rgbvalues2hslvalues(...values);
152
159
  }
153
160
  function lch2hslvalues(token) {
161
+ const values = lch2rgbvalues(token);
162
+ if (values == null) {
163
+ return null;
164
+ }
154
165
  // @ts-ignore
155
- return rgbvalues2hslvalues(...lch2rgbvalues(token));
166
+ return rgbvalues2hslvalues(...values);
156
167
  }
157
168
  function oklab2hslvalues(token) {
158
169
  const t = oklab2srgbvalues(token);
@@ -1,7 +1,7 @@
1
1
  import { hsl2hsv } from './hsv.js';
2
2
  import './utils/constants.js';
3
3
  import { getComponents } from './utils/components.js';
4
- import { color2srgbvalues, toPrecisionAngle, getAngle, getNumber } from './color.js';
4
+ import { color2srgbvalues, toPrecisionAngle, toPrecisionValue, getAngle, getNumber } from './color.js';
5
5
  import { cmyk2srgbvalues, lch2srgbvalues, lab2srgbvalues, oklch2srgbvalues, oklab2srgbvalues } from './srgb.js';
6
6
  import { EnumToken, ColorType } from '../../ast/types.js';
7
7
  import '../../ast/minify.js';
@@ -71,8 +71,8 @@ function hwbToken(values) {
71
71
  values[0] = toPrecisionAngle(values[0] * 360);
72
72
  const chi = [
73
73
  { typ: EnumToken.NumberTokenType, val: values[0] },
74
- { typ: EnumToken.PercentageTokenType, val: values[1] * 100 },
75
- { typ: EnumToken.PercentageTokenType, val: values[2] * 100 },
74
+ { typ: EnumToken.PercentageTokenType, val: toPrecisionValue(values[1]) * 100 },
75
+ { typ: EnumToken.PercentageTokenType, val: toPrecisionValue(values[2]) * 100 },
76
76
  ];
77
77
  if (values.length == 4) {
78
78
  chi.push({ typ: EnumToken.LiteralTokenType, val: '/' }, {
@@ -1,6 +1,6 @@
1
1
  import { e, k, D50 } from './utils/constants.js';
2
2
  import { getComponents } from './utils/components.js';
3
- import { color2srgbvalues, getNumber } from './color.js';
3
+ import { color2srgbvalues, toPrecisionValue, getNumber } from './color.js';
4
4
  import { getOKLABComponents, OKLab_to_XYZ } from './oklab.js';
5
5
  import { EnumToken, ColorType } from '../../ast/types.js';
6
6
  import '../../ast/minify.js';
@@ -76,9 +76,9 @@ function color2labToken(token) {
76
76
  }
77
77
  function labToken(values) {
78
78
  const chi = [
79
- { typ: EnumToken.NumberTokenType, val: values[0] },
80
- { typ: EnumToken.NumberTokenType, val: values[1] },
81
- { typ: EnumToken.NumberTokenType, val: values[2] },
79
+ { typ: EnumToken.NumberTokenType, val: toPrecisionValue(values[0]) },
80
+ { typ: EnumToken.NumberTokenType, val: toPrecisionValue(values[1]) },
81
+ { typ: EnumToken.NumberTokenType, val: toPrecisionValue(values[2]) },
82
82
  ];
83
83
  if (values.length == 4) {
84
84
  chi.push({ typ: EnumToken.LiteralTokenType, val: '/' }, {
@@ -1,6 +1,6 @@
1
1
  import './utils/constants.js';
2
2
  import { getComponents } from './utils/components.js';
3
- import { color2srgbvalues, toPrecisionAngle, getNumber, getAngle } from './color.js';
3
+ import { color2srgbvalues, toPrecisionAngle, toPrecisionValue, getNumber, getAngle } from './color.js';
4
4
  import { cmyk2srgbvalues } from './srgb.js';
5
5
  import { EnumToken, ColorType } from '../../ast/types.js';
6
6
  import '../../ast/minify.js';
@@ -77,12 +77,15 @@ function color2lchToken(token) {
77
77
  function lchToken(values) {
78
78
  values[2] = toPrecisionAngle(values[2]);
79
79
  const chi = [
80
- { typ: EnumToken.NumberTokenType, val: values[0] },
81
- { typ: EnumToken.NumberTokenType, val: values[1] },
80
+ { typ: EnumToken.NumberTokenType, val: toPrecisionValue(values[0]) },
81
+ { typ: EnumToken.NumberTokenType, val: toPrecisionValue(values[1]) },
82
82
  { typ: EnumToken.NumberTokenType, val: values[2] },
83
83
  ];
84
84
  if (values.length == 4) {
85
- chi.push({ typ: EnumToken.LiteralTokenType, val: '/' }, { typ: EnumToken.PercentageTokenType, val: values[3] * 100 });
85
+ chi.push({ typ: EnumToken.LiteralTokenType, val: '/' }, {
86
+ typ: EnumToken.PercentageTokenType,
87
+ val: values[3] * 100
88
+ });
86
89
  }
87
90
  return {
88
91
  typ: EnumToken.ColorTokenType,
@@ -1,7 +1,7 @@
1
1
  import { multiplyMatrices } from './utils/matrix.js';
2
2
  import './utils/constants.js';
3
3
  import { getComponents } from './utils/components.js';
4
- import { color2srgbvalues, getNumber } from './color.js';
4
+ import { color2srgbvalues, toPrecisionValue, getNumber } from './color.js';
5
5
  import { srgb2lsrgbvalues, lch2srgbvalues, lab2srgbvalues, cmyk2srgbvalues, hwb2srgbvalues, hsl2srgb, rgb2srgb, hex2srgbvalues, lsrgb2srgbvalues } from './srgb.js';
6
6
  import { EnumToken, ColorType } from '../../ast/types.js';
7
7
  import '../../ast/minify.js';
@@ -78,9 +78,9 @@ function color2oklabToken(token) {
78
78
  }
79
79
  function oklabToken(values) {
80
80
  const chi = [
81
- { typ: EnumToken.NumberTokenType, val: values[0] },
82
- { typ: EnumToken.NumberTokenType, val: values[1] },
83
- { typ: EnumToken.NumberTokenType, val: values[2] },
81
+ { typ: EnumToken.NumberTokenType, val: toPrecisionValue(values[0]) },
82
+ { typ: EnumToken.NumberTokenType, val: toPrecisionValue(values[1]) },
83
+ { typ: EnumToken.NumberTokenType, val: toPrecisionValue(values[2]) },
84
84
  ];
85
85
  if (values.length == 4) {
86
86
  chi.push({ typ: EnumToken.LiteralTokenType, val: '/' }, {
@@ -1,6 +1,6 @@
1
1
  import './utils/constants.js';
2
2
  import { getComponents } from './utils/components.js';
3
- import { color2srgbvalues, toPrecisionAngle, getNumber, getAngle } from './color.js';
3
+ import { color2srgbvalues, toPrecisionAngle, toPrecisionValue, getNumber, getAngle } from './color.js';
4
4
  import { srgb2oklab, lch2oklabvalues, getOKLABComponents, lab2oklabvalues, hwb2oklabvalues, hsl2oklabvalues, rgb2oklabvalues, hex2oklabvalues } from './oklab.js';
5
5
  import { EnumToken, ColorType } from '../../ast/types.js';
6
6
  import '../../ast/minify.js';
@@ -76,8 +76,8 @@ function color2oklchToken(token) {
76
76
  function oklchToken(values) {
77
77
  values[2] = toPrecisionAngle(values[2]);
78
78
  const chi = [
79
- { typ: EnumToken.NumberTokenType, val: values[0] },
80
- { typ: EnumToken.NumberTokenType, val: values[1] },
79
+ { typ: EnumToken.NumberTokenType, val: toPrecisionValue(values[0]) },
80
+ { typ: EnumToken.NumberTokenType, val: toPrecisionValue(values[1]) },
81
81
  { typ: EnumToken.NumberTokenType, val: values[2] },
82
82
  ];
83
83
  if (values.length == 4) {
@@ -119,16 +119,28 @@ function cmyk2oklchvalues(token) {
119
119
  return values == null ? null : srgb2oklch(...values);
120
120
  }
121
121
  function lab2oklchvalues(token) {
122
+ const values = lab2oklabvalues(token);
123
+ if (values == null) {
124
+ return null;
125
+ }
122
126
  // @ts-ignore
123
- return labvalues2lchvalues(...lab2oklabvalues(token));
127
+ return labvalues2lchvalues(...values);
124
128
  }
125
129
  function lch2oklchvalues(token) {
130
+ const values = lch2oklabvalues(token);
131
+ if (values == null) {
132
+ return null;
133
+ }
126
134
  // @ts-ignore
127
- return labvalues2lchvalues(...lch2oklabvalues(token));
135
+ return labvalues2lchvalues(...values);
128
136
  }
129
137
  function oklab2oklchvalues(token) {
138
+ const values = getOKLABComponents(token);
139
+ if (values == null) {
140
+ return null;
141
+ }
130
142
  // @ts-ignore
131
- return labvalues2lchvalues(...getOKLABComponents(token));
143
+ return labvalues2lchvalues(...values);
132
144
  }
133
145
  function srgb2oklch(r, g, blue, alpha) {
134
146
  // @ts-ignore
@@ -18,7 +18,7 @@ function parseRelativeColor(relativeKeys, original, rExp, gExp, bExp, aExp) {
18
18
  let keys = {};
19
19
  let values = {};
20
20
  // colorFuncColorSpace x,y,z or r,g,b
21
- const names = relativeKeys.startsWith('xyz') ? 'xyz' : relativeKeys.slice(-3);
21
+ const names = relativeKeys.startsWith('xyz') ? 'xyz' : ['srgb', 'srgb-linear', 'display-p3', 'a98-rgb', 'prophoto-rgb', 'rec2020', 'rgb'].includes(relativeKeys.toLowerCase()) ? 'rgb' : relativeKeys.slice(-3);
22
22
  const converted = convertColor(original, ColorType[relativeKeys.toUpperCase().replaceAll('-', '_')]);
23
23
  if (converted == null) {
24
24
  return null;
@@ -32,13 +32,13 @@ function parseRelativeColor(relativeKeys, original, rExp, gExp, bExp, aExp) {
32
32
  // @ts-ignore
33
33
  alpha: alpha == null ? {
34
34
  typ: EnumToken.NumberTokenType,
35
- val: '1'
35
+ val: 1
36
36
  } : (alpha.typ == EnumToken.IdenTokenType && alpha.val == 'none') ? {
37
37
  typ: EnumToken.NumberTokenType,
38
- val: '0'
38
+ val: 0
39
39
  } : (alpha.typ == EnumToken.PercentageTokenType ? {
40
40
  typ: EnumToken.NumberTokenType,
41
- val: String(getNumber(alpha))
41
+ val: getNumber(alpha)
42
42
  } : alpha)
43
43
  };
44
44
  keys = {
@@ -48,19 +48,15 @@ function parseRelativeColor(relativeKeys, original, rExp, gExp, bExp, aExp) {
48
48
  // @ts-ignore
49
49
  alpha: getValue(aExp == null ? {
50
50
  typ: EnumToken.NumberTokenType,
51
- val: '1'
51
+ val: 1
52
52
  } : (aExp.typ == EnumToken.IdenTokenType && aExp.val == 'none') ? {
53
53
  typ: EnumToken.NumberTokenType,
54
- val: '0'
54
+ val: 0
55
55
  } : aExp)
56
56
  };
57
57
  return computeComponentValue(keys, converted, values);
58
58
  }
59
59
  function getValue(t, converted, component) {
60
- // if (t == null) {
61
- //
62
- // return t;
63
- // }
64
60
  if (t.typ == EnumToken.PercentageTokenType) {
65
61
  let value = getNumber(t);
66
62
  let colorSpace = ColorType[converted.kin].toLowerCase().replaceAll('-', '_');
@@ -90,55 +86,13 @@ function computeComponentValue(expr, converted, values) {
90
86
  }
91
87
  }
92
88
  for (const [key, exp] of Object.entries(expr)) {
93
- /*
94
- if (exp == null) {
95
-
96
- if (key in values) {
97
-
98
- if (typeof values[<RelativeColorTypes>key] == 'number') {
99
-
100
- expr[<RelativeColorTypes>key] = {
101
- typ: EnumToken.NumberTokenType,
102
- val: reduceNumber(<number>values[<RelativeColorTypes>key])
103
- };
104
- } else {
105
-
106
- expr[<RelativeColorTypes>key] = <Token>values[<RelativeColorTypes>key];
107
- }
108
- }
109
-
110
- } else
111
- */
112
89
  if ([EnumToken.NumberTokenType, EnumToken.PercentageTokenType, EnumToken.AngleTokenType, EnumToken.LengthTokenType].includes(exp.typ)) ;
113
90
  else if (exp.typ == EnumToken.IdenTokenType && exp.val in values) {
114
- // if (typeof values[<RelativeColorTypes>exp.val] == 'number') {
115
- //
116
- // expr[<RelativeColorTypes>key] = {
117
- // typ: EnumToken.NumberTokenType,
118
- // val: reduceNumber(<number>values[<RelativeColorTypes>exp.val])
119
- // };
120
- // } else {
121
91
  expr[key] = values[exp.val];
122
- // }
123
92
  }
124
93
  else if (exp.typ == EnumToken.FunctionTokenType && mathFuncs.includes(exp.val)) {
125
94
  for (let { value, parent } of walkValues(exp.chi, exp)) {
126
- // if (parent == null) {
127
- //
128
- // parent = exp;
129
- // }
130
- /*
131
- if (value.typ == EnumToken.PercentageTokenType) {
132
-
133
- replaceValue(parent as BinaryExpressionToken | FunctionToken | ParensToken, value, getValue(value, converted, <RelativeColorTypes>key));
134
- } else
135
- */
136
95
  if (value.typ == EnumToken.IdenTokenType) {
137
- // @ts-ignore
138
- // if (!(value.val in values || typeof Math[(value as IdentToken).val.toUpperCase()] == 'number')) {
139
- //
140
- // return null;
141
- // }
142
96
  // @ts-ignore
143
97
  replaceValue(parent, value, values[value.val] ?? {
144
98
  typ: EnumToken.NumberTokenType,
@@ -152,10 +106,6 @@ function computeComponentValue(expr, converted, values) {
152
106
  if (result.length == 1 && result[0].typ != EnumToken.BinaryExpressionTokenType) {
153
107
  expr[key] = result[0];
154
108
  }
155
- // else {
156
- //
157
- // return null;
158
- // }
159
109
  }
160
110
  }
161
111
  return expr;
@@ -166,13 +116,16 @@ function replaceValue(parent, value, newValue) {
166
116
  if (pr.typ == EnumToken.BinaryExpressionTokenType) {
167
117
  if (pr.l == val) {
168
118
  pr.l = newValue;
119
+ return;
169
120
  }
170
121
  else {
171
122
  pr.r = newValue;
123
+ return;
172
124
  }
173
125
  }
174
126
  else {
175
127
  pr.chi.splice(pr.chi.indexOf(val), 1, newValue);
128
+ return;
176
129
  }
177
130
  }
178
131
  }
@@ -235,7 +235,7 @@ function lab2srgbvalues(token) {
235
235
  return null;
236
236
  }
237
237
  const rgb = Lab_to_sRGB(l, a, b);
238
- if (alpha != null && alpha != 1) {
238
+ if (alpha != null && alpha < 1) {
239
239
  rgb.push(alpha);
240
240
  }
241
241
  return rgb;
@@ -1619,6 +1619,9 @@ var declarations = {
1619
1619
  "text-anchor": {
1620
1620
  syntax: "start | middle | end"
1621
1621
  },
1622
+ "text-autospace": {
1623
+ syntax: "normal | <autospace> | auto"
1624
+ },
1622
1625
  "text-box": {
1623
1626
  syntax: "normal | <'text-box-trim'> || <'text-box-edge'>"
1624
1627
  },
@@ -4186,19 +4189,8 @@ var atRules = {
4186
4189
  }
4187
4190
  }
4188
4191
  },
4189
- charset: {
4190
- syntax: "<string>"
4191
- },
4192
- container: {
4193
- syntax: "[ <container-name> ]? <container-condition>"
4194
- },
4195
- nest: {
4192
+ "@nest": {
4196
4193
  syntax: "<complex-selector-list>"
4197
- },
4198
- scope: {
4199
- syntax: "[ ( <scope-start> ) ]? [ to ( <scope-end> ) ]?"
4200
- },
4201
- "position-try": {
4202
4194
  }
4203
4195
  };
4204
4196
  var config = {
package/dist/node.js CHANGED
@@ -21,31 +21,40 @@ import './lib/validation/syntax.js';
21
21
  import { resolve, matchUrl, dirname } from './lib/fs/resolve.js';
22
22
  import { Readable } from 'node:stream';
23
23
  import { createReadStream } from 'node:fs';
24
+ import { lstat } from 'node:fs/promises';
24
25
  export { FeatureWalkMode } from './lib/ast/features/type.js';
25
26
 
26
- /**
27
- * node module entry point
28
- * @module node
29
- */
30
27
  /**
31
28
  * load file or url as stream
32
29
  * @param url
33
30
  * @param currentFile
31
+ * @throws Error file not found
34
32
  *
35
33
  * @private
36
34
  */
37
- async function getStream(url, currentFile = '.') {
35
+ async function load(url, currentFile = '.') {
38
36
  const resolved = resolve(url, currentFile);
39
37
  // @ts-ignore
40
- return matchUrl.test(resolved.absolute) ? fetch(resolved.absolute).then((response) => {
41
- if (!response.ok) {
42
- throw new Error(`${response.status} ${response.statusText} ${response.url}`);
38
+ if (matchUrl.test(resolved.absolute)) {
39
+ return fetch(resolved.absolute).then((response) => {
40
+ if (!response.ok) {
41
+ throw new Error(`${response.status} ${response.statusText} ${response.url}`);
42
+ }
43
+ return response.body;
44
+ });
45
+ }
46
+ try {
47
+ const stats = await lstat(resolved.absolute);
48
+ if (stats.isFile()) {
49
+ return Readable.toWeb(createReadStream(resolved.absolute));
43
50
  }
44
- return response.body;
45
- }) : Readable.toWeb(createReadStream(resolved.absolute));
51
+ }
52
+ catch (error) {
53
+ }
54
+ throw new Error(`File not found: '${resolved.absolute || url}'`);
46
55
  }
47
56
  /**
48
- * render ast tree
57
+ * render the ast tree
49
58
  * @param data
50
59
  * @param options
51
60
  *
@@ -55,23 +64,33 @@ async function getStream(url, currentFile = '.') {
55
64
  *
56
65
  * import {render, ColorType} from '@tbela99/css-parser';
57
66
  *
58
- * // remote file
59
- * let result = render(ast);
60
- * console.log(result.code);
67
+ * const css = 'body { color: color(from hsl(0 100% 50%) xyz x y z); }';
68
+ * const parseResult = await parse(css);
61
69
  *
62
- * // local file
63
- * result = await parseFile(ast, {beatify: true, convertColor: ColorType.SRGB});
70
+ * let renderResult = render(parseResult.ast);
64
71
  * console.log(result.code);
72
+ *
73
+ * // body{color:red}
74
+ *
75
+ *
76
+ * renderResult = render(parseResult.ast, {beautify: true, convertColor: ColorType.SRGB});
77
+ * console.log(renderResult.code);
78
+ *
79
+ * // body {
80
+ * // color: color(srgb 1 0 0)
81
+ * // }
65
82
  * ```
66
83
  */
67
84
  function render(data, options = {}) {
68
- return doRender(data, Object.assign(options, { getStream, resolve, dirname, cwd: options.cwd ?? process.cwd() }));
85
+ return doRender(data, Object.assign(options, { resolve, dirname, cwd: options.cwd ?? process.cwd() }));
69
86
  }
70
87
  /**
71
88
  * parse css file
72
89
  * @param file url or path
73
90
  * @param options
74
91
  *
92
+ * @throws Error file not found
93
+ *
75
94
  * Example:
76
95
  *
77
96
  * ```ts
@@ -88,22 +107,22 @@ function render(data, options = {}) {
88
107
  * ```
89
108
  */
90
109
  async function parseFile(file, options = {}) {
91
- return getStream(file).then(stream => parse(stream, { src: file, ...options }));
110
+ return load(file).then(stream => parse(stream, { src: file, ...options }));
92
111
  }
93
112
  /**
94
113
  * parse css
95
114
  * @param stream
96
- * @param opt
115
+ * @param options
97
116
  *
98
117
  * Example:
99
118
  *
100
119
  * ```ts
101
120
  *
102
- * import {transform} from '@tbela99/css-parser';
121
+ * import {parse} from '@tbela99/css-parser';
103
122
  *
104
123
  * // css string
105
- * let result = await transform(css);
106
- * console.log(result.code);
124
+ * let result = await parse(css);
125
+ * console.log(result.ast);
107
126
  * ```
108
127
  *
109
128
  * Example using stream
@@ -116,36 +135,38 @@ async function parseFile(file, options = {}) {
116
135
  * // usage: node index.ts < styles.css or cat styles.css | node index.ts
117
136
  *
118
137
  * const readableStream = Readable.toWeb(process.stdin);
119
- * const result = await parse(readableStream, {beautify: true});
138
+ * let result = await parse(readableStream, {beautify: true});
120
139
  *
121
140
  * console.log(result.ast);
122
141
  * ```
123
142
  *
124
- * Example using fetch
143
+ * Example using fetch and readable stream
125
144
  *
126
145
  * ```ts
127
146
  *
128
147
  * import {parse} from '@tbela99/css-parser';
129
148
  *
130
149
  * const response = await fetch('https://docs.deno.com/styles.css');
131
- * result = await parse(response.body, {beautify: true});
150
+ * const result = await parse(response.body, {beautify: true});
132
151
  *
133
152
  * console.log(result.ast);
134
153
  * ```
135
154
  */
136
- async function parse(stream, opt = {}) {
155
+ async function parse(stream, options = {}) {
137
156
  return doParse(stream instanceof ReadableStream ? tokenizeStream(stream) : tokenize({
138
157
  stream,
139
158
  buffer: '',
140
159
  position: { ind: 0, lin: 1, col: 1 },
141
160
  currentPosition: { ind: -1, lin: 1, col: 0 }
142
- }), Object.assign(opt, { getStream, resolve, dirname, cwd: opt.cwd ?? process.cwd() }));
161
+ }), Object.assign(options, { load, resolve, dirname, cwd: options.cwd ?? process.cwd() }));
143
162
  }
144
163
  /**
145
164
  * transform css file
146
165
  * @param file url or path
147
166
  * @param options
148
167
  *
168
+ * @throws Error file not found
169
+ *
149
170
  * Example:
150
171
  *
151
172
  * ```ts
@@ -162,7 +183,7 @@ async function parse(stream, opt = {}) {
162
183
  * ```
163
184
  */
164
185
  async function transformFile(file, options = {}) {
165
- return getStream(file).then(stream => transform(stream, { src: file, ...options }));
186
+ return load(file).then(stream => transform(stream, { src: file, ...options }));
166
187
  }
167
188
  /**
168
189
  * transform css
@@ -176,7 +197,7 @@ async function transformFile(file, options = {}) {
176
197
  * import {transform} from '@tbela99/css-parser';
177
198
  *
178
199
  * // css string
179
- * let result = await transform(css);
200
+ * const result = await transform(css);
180
201
  * console.log(result.code);
181
202
  * ```
182
203
  *
@@ -211,7 +232,8 @@ async function transform(css, options = {}) {
211
232
  options = { minify: true, removeEmpty: true, removeCharset: true, ...options };
212
233
  const startTime = performance.now();
213
234
  return parse(css, options).then((parseResult) => {
214
- const rendered = render(parseResult.ast, options);
235
+ // ast already expanded by parse
236
+ const rendered = render(parseResult.ast, { ...options, expandNestingRules: false });
215
237
  return {
216
238
  ...parseResult,
217
239
  ...rendered,
@@ -226,4 +248,4 @@ async function transform(css, options = {}) {
226
248
  });
227
249
  }
228
250
 
229
- export { dirname, getStream, parse, parseFile, render, resolve, transform, transformFile };
251
+ export { dirname, load, parse, parseFile, render, resolve, transform, transformFile };