@tbela99/css-parser 1.3.4 → 1.4.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.
@@ -138,23 +138,27 @@ function* consumeString(quoteStr, buffer, parseInfo) {
138
138
  }
139
139
  }
140
140
  function match(parseInfo, input) {
141
- return parseInfo.stream.slice(parseInfo.currentPosition.ind + 1, parseInfo.currentPosition.ind + input.length + 1) == input;
141
+ const position = parseInfo.currentPosition.ind - parseInfo.offset;
142
+ return parseInfo.stream.slice(position + 1, position + input.length + 1) == input;
142
143
  }
143
144
  function peek(parseInfo, count = 1) {
144
145
  if (count == 1) {
145
- return parseInfo.stream.charAt(parseInfo.currentPosition.ind + 1);
146
+ return parseInfo.stream.charAt(parseInfo.currentPosition.ind - parseInfo.offset + 1);
146
147
  }
147
- return parseInfo.stream.slice(parseInfo.currentPosition.ind + 1, parseInfo.currentPosition.ind + count + 1);
148
+ const position = parseInfo.currentPosition.ind - parseInfo.offset;
149
+ return parseInfo.stream.slice(position + 1, position + count + 1);
148
150
  }
149
151
  function prev(parseInfo) {
150
- return parseInfo.stream.charAt(parseInfo.currentPosition.ind - 1);
152
+ return parseInfo.offset == parseInfo.currentPosition.ind ? parseInfo.buffer.slice(-1) : parseInfo.stream.charAt(parseInfo.currentPosition.ind - parseInfo.offset - 1);
151
153
  }
152
154
  function next(parseInfo, count = 1) {
153
155
  let char = '';
154
156
  let chr = '';
155
- while (count-- && (chr = parseInfo.stream.charAt(parseInfo.currentPosition.ind + 1))) {
157
+ let position = parseInfo.currentPosition.ind - parseInfo.offset;
158
+ while (count-- && (chr = parseInfo.stream.charAt(position + 1))) {
156
159
  char += chr;
157
- const codepoint = parseInfo.stream.charCodeAt(++parseInfo.currentPosition.ind);
160
+ const codepoint = parseInfo.stream.charCodeAt(++position);
161
+ ++parseInfo.currentPosition.ind;
158
162
  if (isNewLine(codepoint)) {
159
163
  parseInfo.currentPosition.lin++;
160
164
  parseInfo.currentPosition.col = 0;
@@ -570,6 +574,7 @@ async function* tokenizeStream(input) {
570
574
  const parseInfo = {
571
575
  stream: '',
572
576
  buffer: '',
577
+ offset: 0,
573
578
  position: { ind: 0, lin: 1, col: 1 },
574
579
  currentPosition: { ind: -1, lin: 1, col: 0 }
575
580
  };
@@ -577,7 +582,17 @@ async function* tokenizeStream(input) {
577
582
  const reader = input.getReader();
578
583
  while (true) {
579
584
  const { done, value } = await reader.read();
580
- parseInfo.stream += ArrayBuffer.isView(value) ? decoder.decode(value, { stream: true }) : value;
585
+ const stream = ArrayBuffer.isView(value) ? decoder.decode(value, { stream: true }) : value;
586
+ if (!done) {
587
+ if (parseInfo.stream.length > 2) {
588
+ parseInfo.stream = parseInfo.stream.slice(-2) + stream;
589
+ parseInfo.offset = parseInfo.currentPosition.ind - 1;
590
+ }
591
+ else {
592
+ parseInfo.stream = stream;
593
+ parseInfo.offset = Math.max(0, parseInfo.currentPosition.ind);
594
+ }
595
+ }
581
596
  yield* tokenize(parseInfo, done);
582
597
  if (done) {
583
598
  break;
@@ -20,6 +20,60 @@ function parseDeclarationNode(node, errors, location) {
20
20
  });
21
21
  return null;
22
22
  }
23
+ if ('composes' == node.nam.toLowerCase()) {
24
+ let left = [];
25
+ let right = [];
26
+ let current = 0;
27
+ let hasFrom = 0;
28
+ for (; current < node.val.length; current++) {
29
+ if (EnumToken.WhitespaceTokenType == node.val[current].typ || EnumToken.CommentTokenType == node.val[current].typ) {
30
+ if (!hasFrom) {
31
+ left.push(node.val[current]);
32
+ }
33
+ else {
34
+ right.push(node.val[current]);
35
+ }
36
+ continue;
37
+ }
38
+ if (EnumToken.IdenTokenType == node.val[current].typ || EnumToken.DashedIdenTokenType == node.val[current].typ || EnumToken.StringTokenType == node.val[current].typ) {
39
+ if (EnumToken.IdenTokenType == node.val[current].typ) {
40
+ if ('from' == node.val[current].val) {
41
+ if (hasFrom) {
42
+ return null;
43
+ }
44
+ hasFrom++;
45
+ continue;
46
+ }
47
+ }
48
+ if (hasFrom) {
49
+ right.push(node.val[current]);
50
+ }
51
+ else {
52
+ left.push(node.val[current]);
53
+ }
54
+ continue;
55
+ }
56
+ break;
57
+ }
58
+ if (hasFrom <= 1 && current > 0) {
59
+ if (hasFrom == 0) {
60
+ node.val.splice(0, left.length, {
61
+ typ: EnumToken.ComposesSelectorNodeType,
62
+ l: left,
63
+ r: null
64
+ });
65
+ }
66
+ else {
67
+ node.val.splice(0, current, {
68
+ typ: EnumToken.ComposesSelectorNodeType,
69
+ l: left,
70
+ r: right.reduce((a, b) => {
71
+ return a == null ? b : b.typ == EnumToken.WhitespaceTokenType || b.typ == EnumToken.CommentTokenType ? a : b;
72
+ }, null)
73
+ });
74
+ }
75
+ }
76
+ }
23
77
  for (const { value: val, parent } of walkValues(node.val, node)) {
24
78
  if (val.typ == EnumToken.AttrTokenType && val.chi.every((t) => [EnumToken.IdenTokenType, EnumToken.WhitespaceTokenType, EnumToken.CommentTokenType].includes(t.typ))) {
25
79
  // @ts-ignore
@@ -0,0 +1,86 @@
1
+ // Alphabet: a-z, A-Z, 0-9, _, -
2
+ const LOWER = "abcdefghijklmnopqrstuvwxyz";
3
+ const DIGITS = "0123456789";
4
+ const FULL_ALPHABET = (LOWER + DIGITS).split(""); // 64 chars
5
+ const FIRST_ALPHABET = (LOWER).split(""); // 54 chars (no digits)
6
+ /**
7
+ * supported hash algorithms
8
+ */
9
+ const hashAlgorithms = ['hex', 'base64', 'base64url', 'sha1', 'sha256', 'sha384', 'sha512'];
10
+ // simple deterministic hash → number
11
+ function hashCode(str) {
12
+ let hash = 0;
13
+ let l = str.length;
14
+ let i = 0;
15
+ while (i < l) {
16
+ hash = (hash * 31 + str.charCodeAt(i++)) >>> 0;
17
+ }
18
+ return hash;
19
+ }
20
+ /**
21
+ * generate a hash id
22
+ * @param input
23
+ * @param length
24
+ */
25
+ function hashId(input, length = 6) {
26
+ let n = hashCode(input);
27
+ const chars = [];
28
+ // First character: must not be a digit
29
+ chars.push(FIRST_ALPHABET[n % FIRST_ALPHABET.length]);
30
+ // Remaining characters
31
+ for (let i = 1; i < length; i++) {
32
+ n = (n + chars.length + i) % FULL_ALPHABET.length;
33
+ chars.push(FULL_ALPHABET[n]);
34
+ }
35
+ return chars.join("");
36
+ }
37
+ /**
38
+ * convert input to hex
39
+ * @param input
40
+ */
41
+ function toHex(input) {
42
+ let result = '';
43
+ if (input instanceof ArrayBuffer || ArrayBuffer.isView(input)) {
44
+ for (const byte of Array.from(new Uint8Array(input))) {
45
+ result += byte.toString(16).padStart(2, '0');
46
+ }
47
+ }
48
+ else {
49
+ for (const char of String(input)) {
50
+ result += char.charCodeAt(0).toString(16).padStart(2, '0');
51
+ }
52
+ }
53
+ return result;
54
+ }
55
+ /**
56
+ * generate a hash
57
+ * @param input
58
+ * @param length
59
+ * @param algo
60
+ */
61
+ async function hash(input, length = 6, algo) {
62
+ let result;
63
+ if (algo != null) {
64
+ switch (algo) {
65
+ case 'hex':
66
+ return toHex(input).slice(0, length);
67
+ case 'base64':
68
+ case 'base64url':
69
+ result = btoa(input);
70
+ if (algo == 'base64url') {
71
+ result = result.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
72
+ }
73
+ return result.slice(0, length);
74
+ case 'sha1':
75
+ case 'sha256':
76
+ case 'sha384':
77
+ case 'sha512':
78
+ return toHex(await crypto.subtle.digest(algo.replace('sha', 'SHA-'), new TextEncoder().encode(input))).slice(0, length);
79
+ default:
80
+ throw new Error(`Unsupported hash algorithm: ${algo}`);
81
+ }
82
+ }
83
+ return hashId(input, length);
84
+ }
85
+
86
+ export { hash, hashAlgorithms, hashId };
@@ -0,0 +1,8 @@
1
+ function dasherize(value) {
2
+ return value.replace(/([A-Z])/g, (all, one) => `-${one.toLowerCase()}`);
3
+ }
4
+ function camelize(value) {
5
+ return value.replace(/-([a-z])/g, (all, one) => one.toUpperCase());
6
+ }
7
+
8
+ export { camelize, dasherize };
@@ -29,9 +29,10 @@ function update(position, str) {
29
29
  * render ast
30
30
  * @param data
31
31
  * @param options
32
+ * @param mapping
32
33
  * @private
33
34
  */
34
- function doRender(data, options = {}) {
35
+ function doRender(data, options = {}, mapping) {
35
36
  const minify = options.minify ?? true;
36
37
  const beautify = options.beautify ?? !minify;
37
38
  options = {
@@ -68,12 +69,23 @@ function doRender(data, options = {}) {
68
69
  const errors = [];
69
70
  const sourcemap = options.sourcemap ? new SourceMap : null;
70
71
  const cache = Object.create(null);
72
+ const position = {
73
+ ind: 0,
74
+ lin: 1,
75
+ col: 1
76
+ };
77
+ let code = '';
78
+ if (mapping != null) {
79
+ if (mapping.importMapping != null) {
80
+ for (const [key, value] of Object.entries(mapping.importMapping)) {
81
+ code += `:import("${key}")${options.indent}{${options.newLine}${Object.entries(value).reduce((acc, [k, v]) => acc + (acc.length > 0 ? options.newLine : '') + `${options.indent}${v}:${options.indent}${k};`, '')}${options.newLine}}${options.newLine}`;
82
+ }
83
+ }
84
+ code += `:export${options.indent}{${options.newLine}${Object.entries(mapping.mapping).reduce((acc, [k, v]) => acc + (acc.length > 0 ? options.newLine : '') + `${options.indent}${k}:${options.indent}${v};`, '')}${options.newLine}}${options.newLine}`;
85
+ update(position, code);
86
+ }
71
87
  const result = {
72
- code: renderAstNode(options.expandNestingRules && [EnumToken.StyleSheetNodeType, EnumToken.AtRuleNodeType, EnumToken.RuleNodeType].includes(data.typ) && 'chi' in data ? expand(data) : data, options, sourcemap, {
73
- ind: 0,
74
- lin: 1,
75
- col: 1
76
- }, errors, function reducer(acc, curr) {
88
+ code: code + renderAstNode(options.expandNestingRules && [EnumToken.StyleSheetNodeType, EnumToken.AtRuleNodeType, EnumToken.RuleNodeType].includes(data.typ) && 'chi' in data ? expand(data) : data, options, sourcemap, position, errors, function reducer(acc, curr) {
77
89
  if (curr.typ == EnumToken.CommentTokenType && options.removeComments) {
78
90
  if (!options.preserveLicense || !curr.val.startsWith('/*!')) {
79
91
  return acc;
@@ -232,6 +244,11 @@ function renderAstNode(data, options, sourcemap, position, errors, reducer, cach
232
244
  return `@${data.nam}${data.val === '' ? '' : options.indent || ' '}${data.val}${options.indent}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`;
233
245
  }
234
246
  return data.sel + `${options.indent}{${options.newLine}` + (children === '' ? '' : indentSub + children + options.newLine) + indent + `}`;
247
+ case EnumToken.CssVariableTokenType:
248
+ case EnumToken.CssVariableImportTokenType:
249
+ return `@value ${data.nam}:${options.indent}${filterValues((options.minify ? data.val : data.val)).reduce(reducer, '').trim()};`;
250
+ case EnumToken.CssVariableDeclarationMapTokenType:
251
+ return `@value ${filterValues(data.vars).reduce((acc, curr) => acc + renderToken(curr), '').trim()} from ${filterValues(data.from).reduce((acc, curr) => acc + renderToken(curr), '').trim()};`;
235
252
  case EnumToken.InvalidDeclarationNodeType:
236
253
  case EnumToken.InvalidRuleTokenType:
237
254
  case EnumToken.InvalidAtRuleTokenType:
@@ -386,6 +403,8 @@ function renderToken(token, options = {}, cache = Object.create(null), reducer,
386
403
  case EnumToken.NameSpaceAttributeTokenType:
387
404
  return (token.l == null ? '' : renderToken(token.l, options, cache, reducer, errors)) + '|' +
388
405
  renderToken(token.r, options, cache, reducer, errors);
406
+ case EnumToken.ComposesSelectorNodeType:
407
+ return token.l.reduce((acc, curr) => acc + renderToken(curr, options, cache), '') + (token.r == null ? '' : ' from ' + renderToken(token.r, options, cache, reducer, errors));
389
408
  case EnumToken.BlockStartTokenType:
390
409
  return '{';
391
410
  case EnumToken.BlockEndTokenType:
@@ -77,10 +77,7 @@ function computeComponentValue(expr, converted, values) {
77
77
  // normalize hue
78
78
  for (const k of walkValues([object.h])) {
79
79
  if (k.value.typ == EnumToken.AngleTokenType && k.value.unit == 'deg') {
80
- // @ts-ignore
81
80
  k.value.typ = EnumToken.NumberTokenType;
82
- // @ts-ignore
83
- delete k.value.unit;
84
81
  }
85
82
  }
86
83
  }
@@ -753,7 +753,7 @@ var declarations = {
753
753
  syntax: "[ <counter-name> <integer>? ]+ | none"
754
754
  },
755
755
  cursor: {
756
- syntax: "[ [ <url> [ <x> <y> ]? , ]* [ auto | default | none | context-menu | help | pointer | progress | wait | cell | crosshair | text | vertical-text | alias | copy | move | no-drop | not-allowed | e-resize | n-resize | ne-resize | nw-resize | s-resize | se-resize | sw-resize | w-resize | ew-resize | ns-resize | nesw-resize | nwse-resize | col-resize | row-resize | all-scroll | zoom-in | zoom-out | grab | grabbing ] ] [ [ <url> [ <x> <y> ]? , ]* [ auto | default | none | context-menu | help | pointer | progress | wait | cell | crosshair | text | vertical-text | alias | copy | move | no-drop | not-allowed | e-resize | n-resize | ne-resize | nw-resize | s-resize | se-resize | sw-resize | w-resize | ew-resize | ns-resize | nesw-resize | nwse-resize | col-resize | row-resize | all-scroll | zoom-in | zoom-out | grab | grabbing | hand | -webkit-grab | -webkit-grabbing | -webkit-zoom-in | -webkit-zoom-out | -moz-grab | -moz-grabbing | -moz-zoom-in | -moz-zoom-out ] ]"
756
+ syntax: "[ [ <url> [ <x> <y> ]? , ]* <cursor-predefined> ] [ [ <url> [ <x> <y> ]? , ]* [ auto | default | none | context-menu | help | pointer | progress | wait | cell | crosshair | text | vertical-text | alias | copy | move | no-drop | not-allowed | e-resize | n-resize | ne-resize | nw-resize | s-resize | se-resize | sw-resize | w-resize | ew-resize | ns-resize | nesw-resize | nwse-resize | col-resize | row-resize | all-scroll | zoom-in | zoom-out | grab | grabbing | hand | -webkit-grab | -webkit-grabbing | -webkit-zoom-in | -webkit-zoom-out | -moz-grab | -moz-grabbing | -moz-zoom-in | -moz-zoom-out ] ]"
757
757
  },
758
758
  cx: {
759
759
  syntax: "<length> | <percentage>"
@@ -1981,6 +1981,12 @@ var declarations = {
1981
1981
  },
1982
1982
  "white-space-trim": {
1983
1983
  syntax: "none | discard-before || discard-after || discard-inner"
1984
+ },
1985
+ composes: {
1986
+ syntax: "<composes-selector>#"
1987
+ },
1988
+ "composes-selector": {
1989
+ syntax: "<ident>+ [from [global&&<string>]]?"
1984
1990
  }
1985
1991
  };
1986
1992
  var functions = {
@@ -2006,7 +2012,7 @@ var functions = {
2006
2012
  syntax: "atan2( <calc-sum>, <calc-sum> )"
2007
2013
  },
2008
2014
  attr: {
2009
- syntax: "attr( <attr-name> <type-or-unit>? [, <attr-fallback> ]? )"
2015
+ syntax: "attr( <attr-name> <attr-type>? , <declaration-value>? )"
2010
2016
  },
2011
2017
  blur: {
2012
2018
  syntax: "blur( <length>? )"
@@ -2359,7 +2365,7 @@ var syntaxes = {
2359
2365
  syntax: "scroll | fixed | local"
2360
2366
  },
2361
2367
  "attr()": {
2362
- syntax: "attr( <attr-name> <type-or-unit>? [, <attr-fallback> ]? )"
2368
+ syntax: "attr( <attr-name> <attr-type>? , <declaration-value>? )"
2363
2369
  },
2364
2370
  "attr-matcher": {
2365
2371
  syntax: "[ '~' | '|' | '^' | '$' | '*' ]? '='"
@@ -2367,6 +2373,9 @@ var syntaxes = {
2367
2373
  "attr-modifier": {
2368
2374
  syntax: "i | s"
2369
2375
  },
2376
+ "attr-type": {
2377
+ syntax: "type( <syntax> ) | raw-string | number | <attr-unit>"
2378
+ },
2370
2379
  "attribute-selector": {
2371
2380
  syntax: "'[' <wq-name> ']' | '[' <wq-name> <attr-matcher> [ <string-token> | <ident-token> ] <attr-modifier>? ']'"
2372
2381
  },
@@ -2580,6 +2589,9 @@ var syntaxes = {
2580
2589
  "cubic-bezier-easing-function": {
2581
2590
  syntax: "ease | ease-in | ease-out | ease-in-out | cubic-bezier( <number [0,1]> , <number> , <number [0,1]> , <number> )"
2582
2591
  },
2592
+ "cursor-predefined": {
2593
+ syntax: "auto | default | none | context-menu | help | pointer | progress | wait | cell | crosshair | text | vertical-text | alias | copy | move | no-drop | not-allowed | e-resize | n-resize | ne-resize | nw-resize | s-resize | se-resize | sw-resize | w-resize | ew-resize | ns-resize | nesw-resize | nwse-resize | col-resize | row-resize | all-scroll | zoom-in | zoom-out | grab | grabbing"
2594
+ },
2583
2595
  "custom-color-space": {
2584
2596
  syntax: "<dashed-ident>"
2585
2597
  },
@@ -11,6 +11,7 @@ import '../renderer/sourcemap/lib/encode.js';
11
11
  import { getSyntaxConfig, getParsedSyntax, getSyntax } from './config.js';
12
12
  import './syntaxes/complex-selector.js';
13
13
  import { funcLike, colorsFunc } from '../syntax/color/utils/constants.js';
14
+ import '../../types.js';
14
15
  import '../ast/features/type.js';
15
16
 
16
17
  const config = getSyntaxConfig();
@@ -615,6 +616,7 @@ function matchPropertyType(syntax, context, options) {
615
616
  'color',
616
617
  'integer',
617
618
  'bg-position',
619
+ 'composes-selector',
618
620
  'length-percentage', 'flex', 'calc-sum', 'color',
619
621
  'color-base', 'system-color', 'deprecated-system-color',
620
622
  'pseudo-class-selector', 'pseudo-element-selector', 'feature-value-declaration'
@@ -645,6 +647,9 @@ function matchPropertyType(syntax, context, options) {
645
647
  return { ...result, context };
646
648
  }
647
649
  switch (syntax.val) {
650
+ case 'composes-selector':
651
+ success = token.typ == EnumToken.ComposesSelectorNodeType;
652
+ break;
648
653
  case 'bg-position': {
649
654
  let val;
650
655
  let keyworkMatchCount = 0;
@@ -812,7 +817,7 @@ function matchPropertyType(syntax, context, options) {
812
817
  }
813
818
  break;
814
819
  case 'integer':
815
- success = (token.typ == EnumToken.NumberTokenType && Number.isInteger(+token.val) && token.val > 0) || (token.typ == EnumToken.FunctionTokenType && mathFuncs.includes(token.val.toLowerCase()) || (token.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val)));
820
+ success = (token.typ == EnumToken.NumberTokenType && /^[+-]?\d+$/.test(token.val.toString())) || (token.typ == EnumToken.FunctionTokenType && mathFuncs.includes(token.val.toLowerCase()) || (token.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val)));
816
821
  if ('range' in syntax) {
817
822
  success = success && +token.val >= +syntax.range[0] && +token.val <= +syntax.range[1];
818
823
  }
@@ -20,8 +20,7 @@ function validateCompoundSelector(tokens, root, options) {
20
20
  node: root,
21
21
  // @ts-ignore
22
22
  syntax: null,
23
- error: 'expected selector',
24
- tokens
23
+ error: 'expected selector'
25
24
  };
26
25
  }
27
26
  tokens = tokens.slice();
@@ -19,15 +19,12 @@ function validateRelativeSelectorList(tokens, root, options) {
19
19
  return result;
20
20
  }
21
21
  }
22
+ // @ts-ignore
22
23
  return {
23
24
  valid: SyntaxValidationResult.Valid,
24
- matches: [],
25
- // @ts-ignore
26
25
  node: root,
27
- // @ts-ignore
28
26
  syntax: null,
29
- error: '',
30
- tokens
27
+ error: ''
31
28
  };
32
29
  }
33
30
 
package/dist/node.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import process from 'node:process';
2
- export { ColorType, EnumToken, ValidationLevel } from './lib/ast/types.js';
2
+ import { ModuleScopeEnumOptions } from './lib/ast/types.js';
3
+ export { ColorType, EnumToken, ModuleCaseTransformEnum, ValidationLevel } from './lib/ast/types.js';
3
4
  export { minify } from './lib/ast/minify.js';
4
5
  export { WalkerEvent, WalkerOptionEnum, walk, walkValues } from './lib/ast/walk.js';
5
6
  export { expand } from './lib/ast/expand.js';
@@ -21,34 +22,47 @@ import { resolve, matchUrl, dirname } from './lib/fs/resolve.js';
21
22
  import { Readable } from 'node:stream';
22
23
  import { createReadStream } from 'node:fs';
23
24
  import { readFile, lstat } from 'node:fs/promises';
25
+ import { ResponseType } from './types.js';
24
26
  export { FeatureWalkMode } from './lib/ast/features/type.js';
25
27
 
26
28
  /**
27
29
  * load file or url as stream
28
30
  * @param url
29
31
  * @param currentFile
30
- * @param asStream
32
+ * @param responseType
31
33
  * @throws Error file not found
32
34
  *
33
35
  * @private
34
36
  */
35
- async function load(url, currentFile = '.', asStream = false) {
37
+ async function load(url, currentFile = '.', responseType = false) {
36
38
  const resolved = resolve(url, currentFile);
39
+ if (typeof responseType == 'boolean') {
40
+ responseType = responseType ? ResponseType.ReadableStream : ResponseType.Text;
41
+ }
37
42
  if (matchUrl.test(resolved.absolute)) {
38
43
  return fetch(resolved.absolute).then(async (response) => {
39
44
  if (!response.ok) {
40
45
  throw new Error(`${response.status} ${response.statusText} ${response.url}`);
41
46
  }
42
- return asStream ? response.body : await response.text();
47
+ if (responseType == ResponseType.ArrayBuffer) {
48
+ return response.arrayBuffer();
49
+ }
50
+ return responseType == ResponseType.ReadableStream ? response.body : await response.text();
43
51
  });
44
52
  }
45
53
  try {
46
- if (!asStream) {
54
+ if (responseType == ResponseType.Text) {
47
55
  return readFile(resolved.absolute, 'utf-8');
48
56
  }
57
+ if (responseType == ResponseType.ArrayBuffer) {
58
+ return readFile(resolved.absolute).then(buffer => buffer.buffer);
59
+ }
49
60
  const stats = await lstat(resolved.absolute);
50
61
  if (stats.isFile()) {
51
- return Readable.toWeb(createReadStream(resolved.absolute, { encoding: 'utf-8', highWaterMark: 64 * 1024 }));
62
+ return Readable.toWeb(createReadStream(resolved.absolute, {
63
+ encoding: 'utf-8',
64
+ highWaterMark: 64 * 1024
65
+ }));
52
66
  }
53
67
  }
54
68
  catch (error) {
@@ -60,6 +74,7 @@ async function load(url, currentFile = '.', asStream = false) {
60
74
  * render the ast tree
61
75
  * @param data
62
76
  * @param options
77
+ * @param mapping
63
78
  *
64
79
  * Example:
65
80
  *
@@ -84,8 +99,8 @@ async function load(url, currentFile = '.', asStream = false) {
84
99
  * // }
85
100
  * ```
86
101
  */
87
- function render(data, options = {}) {
88
- return doRender(data, Object.assign(options, { resolve, dirname, cwd: options.cwd ?? process.cwd() }));
102
+ function render(data, options = {}, mapping) {
103
+ return doRender(data, Object.assign(options, { resolve, dirname, cwd: options.cwd ?? process.cwd() }), mapping);
89
104
  }
90
105
  /**
91
106
  * parse css file
@@ -160,9 +175,18 @@ async function parse(stream, options = {}) {
160
175
  return doParse(stream instanceof ReadableStream ? tokenizeStream(stream) : tokenize({
161
176
  stream,
162
177
  buffer: '',
178
+ offset: 0,
163
179
  position: { ind: 0, lin: 1, col: 1 },
164
180
  currentPosition: { ind: -1, lin: 1, col: 0 }
165
- }), Object.assign(options, { load, resolve, dirname, cwd: options.cwd ?? process.cwd() }));
181
+ }), Object.assign(options, {
182
+ load,
183
+ resolve,
184
+ dirname,
185
+ cwd: options.cwd ?? process.cwd()
186
+ })).then(result => {
187
+ const { revMapping, ...res } = result;
188
+ return res;
189
+ });
166
190
  }
167
191
  /**
168
192
  * transform css file
@@ -237,8 +261,21 @@ async function transform(css, options = {}) {
237
261
  options = { minify: true, removeEmpty: true, removeCharset: true, ...options };
238
262
  const startTime = performance.now();
239
263
  return parse(css, options).then((parseResult) => {
264
+ let mapping = null;
265
+ let importMapping = null;
266
+ if (typeof options.module == 'number' && (options.module & ModuleScopeEnumOptions.ICSS)) {
267
+ mapping = parseResult.mapping;
268
+ importMapping = parseResult.importMapping;
269
+ }
270
+ else if (typeof options.module == 'object' && typeof options.module.scoped == 'number' && (options.module.scoped & ModuleScopeEnumOptions.ICSS)) {
271
+ mapping = parseResult.mapping;
272
+ importMapping = parseResult.importMapping;
273
+ }
240
274
  // ast already expanded by parse
241
- const rendered = render(parseResult.ast, { ...options, expandNestingRules: false });
275
+ const rendered = render(parseResult.ast, {
276
+ ...options,
277
+ expandNestingRules: false
278
+ }, mapping != null ? { mapping, importMapping } : null);
242
279
  return {
243
280
  ...parseResult,
244
281
  ...rendered,
@@ -253,4 +290,4 @@ async function transform(css, options = {}) {
253
290
  });
254
291
  }
255
292
 
256
- export { dirname, load, parse, parseFile, render, resolve, transform, transformFile };
293
+ export { ModuleScopeEnumOptions, ResponseType, dirname, load, parse, parseFile, render, resolve, transform, transformFile };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * response type
3
+ */
4
+ export declare enum ResponseType {
5
+ /**
6
+ * return text
7
+ */
8
+ Text = 0,
9
+ /**
10
+ * return a readable stream
11
+ */
12
+ ReadableStream = 1,
13
+ /**
14
+ * return an arraybuffer
15
+ */
16
+ ArrayBuffer = 2
17
+ }
package/dist/types.js ADDED
@@ -0,0 +1,20 @@
1
+ /**
2
+ * response type
3
+ */
4
+ var ResponseType;
5
+ (function (ResponseType) {
6
+ /**
7
+ * return text
8
+ */
9
+ ResponseType[ResponseType["Text"] = 0] = "Text";
10
+ /**
11
+ * return a readable stream
12
+ */
13
+ ResponseType[ResponseType["ReadableStream"] = 1] = "ReadableStream";
14
+ /**
15
+ * return an arraybuffer
16
+ */
17
+ ResponseType[ResponseType["ArrayBuffer"] = 2] = "ArrayBuffer";
18
+ })(ResponseType || (ResponseType = {}));
19
+
20
+ export { ResponseType };