@tbela99/css-parser 1.3.3 → 1.3.4

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.
Files changed (46) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +20 -17
  3. package/dist/index-umd-web.js +1031 -571
  4. package/dist/index.cjs +1031 -566
  5. package/dist/index.d.ts +247 -171
  6. package/dist/lib/ast/expand.js +5 -10
  7. package/dist/lib/ast/features/calc.js +3 -2
  8. package/dist/lib/ast/features/inlinecssvariables.js +5 -3
  9. package/dist/lib/ast/features/prefix.js +1 -1
  10. package/dist/lib/ast/features/shorthand.js +1 -0
  11. package/dist/lib/ast/features/transform.js +13 -19
  12. package/dist/lib/ast/minify.js +5 -2
  13. package/dist/lib/ast/transform/compute.js +2 -4
  14. package/dist/lib/ast/transform/matrix.js +20 -20
  15. package/dist/lib/ast/transform/minify.js +105 -12
  16. package/dist/lib/ast/transform/rotate.js +11 -11
  17. package/dist/lib/ast/transform/scale.js +6 -6
  18. package/dist/lib/ast/transform/skew.js +4 -4
  19. package/dist/lib/ast/transform/translate.js +3 -3
  20. package/dist/lib/ast/transform/utils.js +30 -37
  21. package/dist/lib/ast/types.js +14 -2
  22. package/dist/lib/ast/walk.js +61 -49
  23. package/dist/lib/fs/resolve.js +6 -3
  24. package/dist/lib/parser/declaration/list.js +3 -1
  25. package/dist/lib/parser/parse.js +345 -305
  26. package/dist/lib/parser/tokenize.js +11 -13
  27. package/dist/lib/renderer/render.js +2 -2
  28. package/dist/lib/syntax/syntax.js +36 -18
  29. package/dist/lib/validation/at-rules/container.js +11 -0
  30. package/dist/lib/validation/at-rules/counter-style.js +11 -0
  31. package/dist/lib/validation/at-rules/font-feature-values.js +11 -0
  32. package/dist/lib/validation/at-rules/keyframes.js +11 -0
  33. package/dist/lib/validation/at-rules/layer.js +11 -0
  34. package/dist/lib/validation/at-rules/media.js +11 -0
  35. package/dist/lib/validation/at-rules/page-margin-box.js +11 -0
  36. package/dist/lib/validation/at-rules/page.js +11 -0
  37. package/dist/lib/validation/at-rules/supports.js +11 -0
  38. package/dist/lib/validation/at-rules/when.js +11 -0
  39. package/dist/lib/validation/config.js +0 -2
  40. package/dist/lib/validation/config.json.js +21 -1
  41. package/dist/lib/validation/parser/parse.js +53 -2
  42. package/dist/lib/validation/syntax.js +199 -36
  43. package/dist/node.js +17 -12
  44. package/dist/web.js +11 -11
  45. package/package.json +6 -3
  46. package/dist/lib/validation/parser/types.js +0 -54
@@ -1,12 +1,11 @@
1
- import { ValidationTokenEnum } from './parser/types.js';
2
- import { renderSyntax } from './parser/parse.js';
3
- import { EnumToken, SyntaxValidationResult, ColorType } from '../ast/types.js';
1
+ import { ValidationTokenEnum, renderSyntax } from './parser/parse.js';
2
+ import { SyntaxValidationResult, EnumToken, ColorType } from '../ast/types.js';
4
3
  import '../ast/minify.js';
5
4
  import '../ast/walk.js';
6
5
  import '../parser/parse.js';
7
6
  import '../parser/tokenize.js';
8
7
  import '../parser/utils/config.js';
9
- import { wildCardFuncs, isIdentColor, mathFuncs } from '../syntax/syntax.js';
8
+ import { wildCardFuncs, isIdentColor, mathFuncs, isColor } from '../syntax/syntax.js';
10
9
  import { renderToken } from '../renderer/render.js';
11
10
  import '../renderer/sourcemap/lib/encode.js';
12
11
  import { getSyntaxConfig, getParsedSyntax, getSyntax } from './config.js';
@@ -17,6 +16,116 @@ import '../ast/features/type.js';
17
16
  const config = getSyntaxConfig();
18
17
  // @ts-ignore
19
18
  const allValues = getSyntaxConfig()["declarations" /* ValidationSyntaxGroupEnum.Declarations */].all.syntax.trim().split(/[\s|]+/g);
19
+ /**
20
+ * Check if a node is allowed as child in a given context
21
+ * @param node
22
+ * @param context
23
+ */
24
+ function isNodeAllowedInContext(node, context) {
25
+ if (node.typ == EnumToken.CommentNodeType || context == null) {
26
+ return true;
27
+ }
28
+ switch (context?.typ) {
29
+ case EnumToken.StyleSheetNodeType:
30
+ case EnumToken.RuleNodeType:
31
+ return node.typ == EnumToken.RuleNodeType ||
32
+ node.typ == EnumToken.AtRuleNodeType ||
33
+ node.typ == EnumToken.KeyframesAtRuleNodeType ||
34
+ (node.typ == EnumToken.DeclarationNodeType && context.typ == EnumToken.RuleNodeType) ||
35
+ (node.typ == EnumToken.CDOCOMMNodeType && context.typ == EnumToken.StyleSheetNodeType);
36
+ case EnumToken.KeyframesAtRuleNodeType:
37
+ return node.typ == EnumToken.KeyFramesRuleNodeType;
38
+ case EnumToken.KeyFramesRuleNodeType:
39
+ return node.typ == EnumToken.DeclarationNodeType;
40
+ case EnumToken.AtRuleNodeType:
41
+ // @ts-ignore
42
+ const syntax = getParsedSyntax("atRules" /* ValidationSyntaxGroupEnum.AtRules */, '@' + context.nam)?.[0].chi ?? null;
43
+ //
44
+ if (syntax == null) {
45
+ // console.error(`syntax: Not found ${ValidationSyntaxGroupEnum.AtRules}@${(context as AstAtRule).nam}`);
46
+ return true;
47
+ }
48
+ const stack = syntax.slice();
49
+ for (const child of stack) {
50
+ if (Array.isArray(child)) {
51
+ stack.push(...child);
52
+ continue;
53
+ }
54
+ if ('chi' in child && Array.isArray(child.chi)) {
55
+ stack.push(...child.chi);
56
+ continue;
57
+ }
58
+ // @ts-ignore
59
+ if (child.l != null) {
60
+ // @ts-ignore
61
+ stack.push(child.l);
62
+ // @ts-ignore
63
+ if (child.r != null) {
64
+ // @ts-ignore
65
+ stack.push(...(Array.isArray(child.r) ? child.r : [child.r]));
66
+ }
67
+ continue;
68
+ }
69
+ if (node.typ == EnumToken.DeclarationNodeType) {
70
+ if (child.typ == ValidationTokenEnum.DeclarationDefinitionToken) {
71
+ if (node.nam == child.nam) {
72
+ return true;
73
+ }
74
+ }
75
+ }
76
+ if (child.typ == ValidationTokenEnum.PropertyType) {
77
+ if (['group-rule-body', 'block-contents', 'rule-list', 'stylesheet'].includes(child.val)) {
78
+ if ((node.typ == EnumToken.RuleNodeType ||
79
+ node.typ == EnumToken.AtRuleNodeType ||
80
+ node.typ == EnumToken.KeyframesAtRuleNodeType)) {
81
+ return true;
82
+ }
83
+ if (node.typ == EnumToken.DeclarationNodeType) {
84
+ let parent = node.parent;
85
+ while (parent != null) {
86
+ if (parent.parent?.typ == EnumToken.RuleNodeType) {
87
+ return true;
88
+ }
89
+ parent = parent.parent;
90
+ }
91
+ }
92
+ }
93
+ if (['declaration-list', 'feature-value-declaration'].includes(child.val) && node.typ == EnumToken.DeclarationNodeType) {
94
+ return true;
95
+ }
96
+ if (child.val == 'page-body' && (node.typ == EnumToken.DeclarationNodeType || (node.typ == EnumToken.AtRuleNodeType && [
97
+ 'top-left-corner', 'top-left', 'top-center', 'top-right', 'top-right-corner',
98
+ 'bottom-left-corner', 'bottom-left', 'bottom-center', 'bottom-right', 'bottom-right-corner',
99
+ 'left-top', 'left-middle', 'left-bottom', 'right-top', 'right-middle', 'right-bottom'
100
+ ].includes(node.nam)))) {
101
+ return true;
102
+ }
103
+ if (child.val == 'feature-value-block-list' &&
104
+ (node.typ == EnumToken.AtRuleNodeType && ['stylistic', 'historical-forms', 'styleset', 'character-variant', 'swash', 'ornaments', 'annotation'].includes(node.nam))) {
105
+ return true;
106
+ }
107
+ if (['feature-value-declaration-list', 'feature-value-declaration'].includes(child.val) && node.typ == EnumToken.DeclarationNodeType) {
108
+ return true;
109
+ }
110
+ if (child.val == 'page-body') {
111
+ if (node.typ == EnumToken.DeclarationNodeType) {
112
+ return true;
113
+ }
114
+ }
115
+ // console.error(`isNodeAllowedInContext: Not found ${(child as ValidationPropertyToken).val}`, {
116
+ // child,
117
+ // node
118
+ // });
119
+ }
120
+ }
121
+ break;
122
+ }
123
+ return false;
124
+ }
125
+ /**
126
+ * Create a syntax validation context from a list of tokens
127
+ * @param input
128
+ */
20
129
  function createContext(input) {
21
130
  const values = input.slice();
22
131
  const result = values.filter(token => token.typ != EnumToken.CommentTokenType).slice();
@@ -77,7 +186,22 @@ function createContext(input) {
77
186
  }
78
187
  };
79
188
  }
80
- function evaluateSyntax(node, options) {
189
+ /**
190
+ * Evaluate the validity of the syntax of a node
191
+ * @param node
192
+ * @param parent
193
+ * @param options
194
+ */
195
+ function evaluateSyntax(node, parent, options) {
196
+ if (node.validSyntax) {
197
+ return {
198
+ valid: SyntaxValidationResult.Valid,
199
+ node,
200
+ syntax: null,
201
+ error: '',
202
+ context: []
203
+ };
204
+ }
81
205
  let ast;
82
206
  let result;
83
207
  switch (node.typ) {
@@ -85,25 +209,34 @@ function evaluateSyntax(node, options) {
85
209
  if (node.nam.startsWith('--')) {
86
210
  break;
87
211
  }
212
+ let token = null;
213
+ let values = node.val.slice();
88
214
  ast = getParsedSyntax("declarations" /* ValidationSyntaxGroupEnum.Declarations */, node.nam);
89
- if (ast != null) {
90
- let token = null;
91
- const values = node.val.slice();
92
- while (values.length > 0) {
93
- token = values.at(-1);
94
- if (token.typ == EnumToken.WhitespaceTokenType || token.typ == EnumToken.CommentTokenType) {
215
+ while (values.length > 0) {
216
+ token = values.at(-1);
217
+ if (token.typ == EnumToken.WhitespaceTokenType || token.typ == EnumToken.CommentTokenType) {
218
+ values.pop();
219
+ }
220
+ else {
221
+ if (token.typ == EnumToken.ImportantTokenType) {
95
222
  values.pop();
96
- }
97
- else {
98
- if (token.typ == EnumToken.ImportantTokenType) {
223
+ if (values.at(-1)?.typ == EnumToken.WhitespaceTokenType) {
99
224
  values.pop();
100
- if (values.at(-1)?.typ == EnumToken.WhitespaceTokenType) {
101
- values.pop();
102
- }
103
225
  }
104
- break;
226
+ }
227
+ break;
228
+ }
229
+ }
230
+ if (ast == null) {
231
+ if (parent?.typ == EnumToken.AtRuleNodeType) {
232
+ ast = (getParsedSyntax("atRules" /* ValidationSyntaxGroupEnum.AtRules */, ['@' + parent.nam, 'descriptors', node.nam]));
233
+ if (ast == null) {
234
+ ast = (getParsedSyntax("atRules" /* ValidationSyntaxGroupEnum.AtRules */, ['@' + parent.nam, 'descriptors', node.nam]) ?? getParsedSyntax("atRules" /* ValidationSyntaxGroupEnum.AtRules */, '@' + parent.nam))?.[0]?.chi;
235
+ values = [{ ...node, val: values }];
105
236
  }
106
237
  }
238
+ }
239
+ if (ast != null) {
107
240
  result = doEvaluateSyntax(ast, createContext(values), { ...options, visited: new WeakMap() });
108
241
  if (result.valid == SyntaxValidationResult.Valid && !result.context.done()) {
109
242
  let token = null;
@@ -195,7 +328,7 @@ function doEvaluateSyntax(syntaxes, context, options) {
195
328
  continue;
196
329
  }
197
330
  }
198
- else if (options.occurence !== false && syntax.occurence != null) {
331
+ else if (options.occurrence !== false && syntax.occurence != null) {
199
332
  result = matchOccurence(syntax, context, options);
200
333
  }
201
334
  else if (options.atLeastOnce !== false && syntax.atLeastOnce) {
@@ -284,7 +417,7 @@ function matchList(syntax, context, options) {
284
417
  result = doEvaluateSyntax([syntax], createContext(tokens), {
285
418
  ...options,
286
419
  isList: false,
287
- occurence: false
420
+ occurrence: false
288
421
  });
289
422
  if (result.valid == SyntaxValidationResult.Valid) {
290
423
  context = con.clone();
@@ -319,7 +452,7 @@ function matchOccurence(syntax, context, options) {
319
452
  let counter = 0;
320
453
  let result;
321
454
  do {
322
- result = match(syntax, context.clone(), { ...options, occurence: false });
455
+ result = match(syntax, context.clone(), { ...options, occurrence: false });
323
456
  if (result.valid == SyntaxValidationResult.Drop) {
324
457
  break;
325
458
  }
@@ -370,7 +503,7 @@ function match(syntax, context, options) {
370
503
  ...options,
371
504
  isRepeatable: null,
372
505
  isList: null,
373
- occurence: null,
506
+ occurrence: null,
374
507
  atLeastOnce: null
375
508
  });
376
509
  if (result.valid == SyntaxValidationResult.Valid) {
@@ -382,7 +515,7 @@ function match(syntax, context, options) {
382
515
  case ValidationTokenEnum.Keyword:
383
516
  success = (token.typ == EnumToken.IdenTokenType || token.typ == EnumToken.DashedIdenTokenType || isIdentColor(token)) &&
384
517
  (token.val == syntax.val ||
385
- syntax.val === token.val?.toLowerCase?.() ||
518
+ syntax.val.toLowerCase() === token.val?.toLowerCase?.() ||
386
519
  // config.declarations.all
387
520
  allValues.includes(token.val.toLowerCase()));
388
521
  if (success) {
@@ -421,7 +554,7 @@ function match(syntax, context, options) {
421
554
  ...options,
422
555
  isRepeatable: null,
423
556
  isList: null,
424
- occurence: null,
557
+ occurrence: null,
425
558
  atLeastOnce: null
426
559
  });
427
560
  case ValidationTokenEnum.Comma:
@@ -456,7 +589,7 @@ function match(syntax, context, options) {
456
589
  ...options,
457
590
  isRepeatable: null,
458
591
  isList: null,
459
- occurence: null,
592
+ occurrence: null,
460
593
  atLeastOnce: null
461
594
  }).valid == SyntaxValidationResult.Valid;
462
595
  if (success) {
@@ -479,18 +612,19 @@ function match(syntax, context, options) {
479
612
  }
480
613
  function matchPropertyType(syntax, context, options) {
481
614
  if (![
482
- 'bg-position',
615
+ 'color',
483
616
  'integer',
617
+ 'bg-position',
484
618
  'length-percentage', 'flex', 'calc-sum', 'color',
485
619
  'color-base', 'system-color', 'deprecated-system-color',
486
- 'pseudo-class-selector', 'pseudo-element-selector'
620
+ 'pseudo-class-selector', 'pseudo-element-selector', 'feature-value-declaration'
487
621
  ].includes(syntax.val)) {
488
622
  if (syntax.val in config["syntaxes" /* ValidationSyntaxGroupEnum.Syntaxes */]) {
489
623
  return doEvaluateSyntax(getParsedSyntax("syntaxes" /* ValidationSyntaxGroupEnum.Syntaxes */, syntax.val), context, {
490
624
  ...options,
491
625
  isRepeatable: null,
492
626
  isList: null,
493
- occurence: null,
627
+ occurrence: null,
494
628
  atLeastOnce: null
495
629
  });
496
630
  }
@@ -502,7 +636,7 @@ function matchPropertyType(syntax, context, options) {
502
636
  ...options,
503
637
  isRepeatable: null,
504
638
  isList: null,
505
- occurence: null,
639
+ occurrence: null,
506
640
  atLeastOnce: null
507
641
  });
508
642
  if (result.valid == SyntaxValidationResult.Valid) {
@@ -607,6 +741,14 @@ function matchPropertyType(syntax, context, options) {
607
741
  (token.typ == EnumToken.IdenTokenType && typeof Math[token.val.toUpperCase()] == 'number') ||
608
742
  [EnumToken.BinaryExpressionTokenType, EnumToken.NumberTokenType, EnumToken.PercentageTokenType, EnumToken.DimensionTokenType, EnumToken.LengthTokenType, EnumToken.AngleTokenType, EnumToken.TimeTokenType, EnumToken.ResolutionTokenType, EnumToken.FrequencyTokenType].includes(token.typ);
609
743
  break;
744
+ case 'declaration':
745
+ {
746
+ success = token.typ == EnumToken.DeclarationNodeType;
747
+ if (success) {
748
+ success = evaluateSyntax(token, null, options).valid == SyntaxValidationResult.Valid;
749
+ }
750
+ }
751
+ break;
610
752
  case 'declaration-value':
611
753
  while (!context.done()) {
612
754
  context.next();
@@ -633,13 +775,17 @@ function matchPropertyType(syntax, context, options) {
633
775
  break;
634
776
  case 'color':
635
777
  case 'color-base':
636
- success = token.typ == EnumToken.ColorTokenType || (token.typ == EnumToken.IdenTokenType && 'currentcolor' === token.val.toLowerCase()) || (token.typ == EnumToken.IdenTokenType && 'transparent' === token.val.toLowerCase()) || (token.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val));
778
+ success = token.typ == EnumToken.ColorTokenType ||
779
+ (token.typ == EnumToken.IdenTokenType && 'currentcolor' === token.val.toLowerCase()) ||
780
+ (token.typ == EnumToken.IdenTokenType && 'transparent' === token.val.toLowerCase()) ||
781
+ (token.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val) ||
782
+ isColor(token));
637
783
  if (!success && token.typ == EnumToken.FunctionTokenType && colorsFunc.includes(token.val)) {
638
784
  success = doEvaluateSyntax(getParsedSyntax("functions" /* ValidationSyntaxGroupEnum.Functions */, token.val)?.[0]?.chi, createContext(token.chi), {
639
785
  ...options,
640
786
  isRepeatable: null,
641
787
  isList: null,
642
- occurence: null,
788
+ occurrence: null,
643
789
  atLeastOnce: null
644
790
  }).valid == SyntaxValidationResult.Valid;
645
791
  }
@@ -647,8 +793,26 @@ function matchPropertyType(syntax, context, options) {
647
793
  case 'hex-color':
648
794
  success = (token.typ == EnumToken.ColorTokenType && token.kin == ColorType.HEX) || (token.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val));
649
795
  break;
796
+ case 'feature-value-declaration':
797
+ {
798
+ let hasNumber = false;
799
+ success = token.typ == EnumToken.DeclarationNodeType && token.val.length > 0 && token.val.every((val) => {
800
+ if (val.typ == EnumToken.WhitespaceTokenType || val.typ == EnumToken.CommentTokenType) {
801
+ return true;
802
+ }
803
+ const success = (val.typ == EnumToken.NumberTokenType && Number.isInteger(+val.val) && val.val > 0) || (val.typ == EnumToken.FunctionTokenType && mathFuncs.includes(val.val.toLowerCase()) || (val.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(val.val)));
804
+ if (success) {
805
+ hasNumber = true;
806
+ }
807
+ if ('range' in syntax) {
808
+ return success && +val.val >= +syntax.range[0] && +val.val <= +syntax.range[1];
809
+ }
810
+ return success;
811
+ }) && hasNumber;
812
+ }
813
+ break;
650
814
  case 'integer':
651
- success = (token.typ == EnumToken.NumberTokenType && Number.isInteger(+(token.val))) || (token.typ == EnumToken.FunctionTokenType && mathFuncs.includes(token.val.toLowerCase()) || (token.typ == EnumToken.FunctionTokenType && wildCardFuncs.includes(token.val)));
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)));
652
816
  if ('range' in syntax) {
653
817
  success = success && +token.val >= +syntax.range[0] && +token.val <= +syntax.range[1];
654
818
  }
@@ -712,7 +876,7 @@ function matchPropertyType(syntax, context, options) {
712
876
  ...options,
713
877
  isRepeatable: null,
714
878
  isList: null,
715
- occurence: null,
879
+ occurrence: null,
716
880
  atLeastOnce: null
717
881
  }).valid == SyntaxValidationResult.Valid;
718
882
  }
@@ -728,7 +892,7 @@ function matchPropertyType(syntax, context, options) {
728
892
  ...options,
729
893
  isRepeatable: null,
730
894
  isList: null,
731
- occurence: null,
895
+ occurrence: null,
732
896
  atLeastOnce: null
733
897
  }).valid == SyntaxValidationResult.Valid;
734
898
  }
@@ -875,7 +1039,6 @@ function allOf(syntax, context, options) {
875
1039
  i = -1;
876
1040
  }
877
1041
  }
878
- // console.error()
879
1042
  const success = syntax.length == 0;
880
1043
  return {
881
1044
  valid: success ? SyntaxValidationResult.Valid : SyntaxValidationResult.Drop,
@@ -902,4 +1065,4 @@ function flatten(syntax) {
902
1065
  return data;
903
1066
  }
904
1067
 
905
- export { createContext, doEvaluateSyntax, evaluateSyntax };
1068
+ export { createContext, doEvaluateSyntax, evaluateSyntax, isNodeAllowedInContext };
package/dist/node.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import process from 'node:process';
2
2
  export { ColorType, EnumToken, ValidationLevel } from './lib/ast/types.js';
3
3
  export { minify } from './lib/ast/minify.js';
4
- export { WalkerOptionEnum, WalkerValueEvent, walk, walkValues } from './lib/ast/walk.js';
4
+ export { WalkerEvent, WalkerOptionEnum, walk, walkValues } from './lib/ast/walk.js';
5
5
  export { expand } from './lib/ast/expand.js';
6
6
  import { doRender } from './lib/renderer/render.js';
7
7
  export { renderToken } from './lib/renderer/render.js';
@@ -14,42 +14,45 @@ export { convertColor } from './lib/syntax/color/color.js';
14
14
  import './lib/syntax/color/utils/constants.js';
15
15
  export { isOkLabClose, okLabDistance } from './lib/syntax/color/utils/distance.js';
16
16
  import './lib/validation/config.js';
17
- import './lib/validation/parser/types.js';
18
17
  import './lib/validation/parser/parse.js';
19
18
  import './lib/validation/syntaxes/complex-selector.js';
20
19
  import './lib/validation/syntax.js';
21
20
  import { resolve, matchUrl, dirname } from './lib/fs/resolve.js';
22
21
  import { Readable } from 'node:stream';
23
22
  import { createReadStream } from 'node:fs';
24
- import { lstat } from 'node:fs/promises';
23
+ import { readFile, lstat } from 'node:fs/promises';
25
24
  export { FeatureWalkMode } from './lib/ast/features/type.js';
26
25
 
27
26
  /**
28
27
  * load file or url as stream
29
28
  * @param url
30
29
  * @param currentFile
30
+ * @param asStream
31
31
  * @throws Error file not found
32
32
  *
33
33
  * @private
34
34
  */
35
- async function load(url, currentFile = '.') {
35
+ async function load(url, currentFile = '.', asStream = false) {
36
36
  const resolved = resolve(url, currentFile);
37
- // @ts-ignore
38
37
  if (matchUrl.test(resolved.absolute)) {
39
- return fetch(resolved.absolute).then((response) => {
38
+ return fetch(resolved.absolute).then(async (response) => {
40
39
  if (!response.ok) {
41
40
  throw new Error(`${response.status} ${response.statusText} ${response.url}`);
42
41
  }
43
- return response.body;
42
+ return asStream ? response.body : await response.text();
44
43
  });
45
44
  }
46
45
  try {
46
+ if (!asStream) {
47
+ return readFile(resolved.absolute, 'utf-8');
48
+ }
47
49
  const stats = await lstat(resolved.absolute);
48
50
  if (stats.isFile()) {
49
- return Readable.toWeb(createReadStream(resolved.absolute));
51
+ return Readable.toWeb(createReadStream(resolved.absolute, { encoding: 'utf-8', highWaterMark: 64 * 1024 }));
50
52
  }
51
53
  }
52
54
  catch (error) {
55
+ console.warn(error);
53
56
  }
54
57
  throw new Error(`File not found: '${resolved.absolute || url}'`);
55
58
  }
@@ -88,6 +91,7 @@ function render(data, options = {}) {
88
91
  * parse css file
89
92
  * @param file url or path
90
93
  * @param options
94
+ * @param asStream load file as stream
91
95
  *
92
96
  * @throws Error file not found
93
97
  *
@@ -106,8 +110,8 @@ function render(data, options = {}) {
106
110
  * console.log(result.ast);
107
111
  * ```
108
112
  */
109
- async function parseFile(file, options = {}) {
110
- return load(file).then(stream => parse(stream, { src: file, ...options }));
113
+ async function parseFile(file, options = {}, asStream = false) {
114
+ return Promise.resolve((options.load ?? load)(file, '.', asStream)).then(stream => parse(stream, { src: file, ...options }));
111
115
  }
112
116
  /**
113
117
  * parse css
@@ -164,6 +168,7 @@ async function parse(stream, options = {}) {
164
168
  * transform css file
165
169
  * @param file url or path
166
170
  * @param options
171
+ * @param asStream load file as stream
167
172
  *
168
173
  * @throws Error file not found
169
174
  *
@@ -182,8 +187,8 @@ async function parse(stream, options = {}) {
182
187
  * console.log(result.code);
183
188
  * ```
184
189
  */
185
- async function transformFile(file, options = {}) {
186
- return load(file).then(stream => transform(stream, { src: file, ...options }));
190
+ async function transformFile(file, options = {}, asStream = false) {
191
+ return Promise.resolve((options.load ?? load)(file, '.', asStream)).then(stream => transform(stream, { src: file, ...options }));
187
192
  }
188
193
  /**
189
194
  * transform css
package/dist/web.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export { ColorType, EnumToken, ValidationLevel } from './lib/ast/types.js';
2
2
  export { minify } from './lib/ast/minify.js';
3
- export { WalkerOptionEnum, WalkerValueEvent, walk, walkValues } from './lib/ast/walk.js';
3
+ export { WalkerEvent, WalkerOptionEnum, walk, walkValues } from './lib/ast/walk.js';
4
4
  export { expand } from './lib/ast/expand.js';
5
5
  import { doRender } from './lib/renderer/render.js';
6
6
  export { renderToken } from './lib/renderer/render.js';
@@ -13,7 +13,6 @@ export { convertColor } from './lib/syntax/color/color.js';
13
13
  import './lib/syntax/color/utils/constants.js';
14
14
  export { isOkLabClose, okLabDistance } from './lib/syntax/color/utils/distance.js';
15
15
  import './lib/validation/config.js';
16
- import './lib/validation/parser/types.js';
17
16
  import './lib/validation/parser/parse.js';
18
17
  import './lib/validation/syntaxes/complex-selector.js';
19
18
  import './lib/validation/syntax.js';
@@ -25,9 +24,10 @@ export { FeatureWalkMode } from './lib/ast/features/type.js';
25
24
  * @param url
26
25
  * @param currentFile
27
26
  *
27
+ * @param asStream
28
28
  * @private
29
29
  */
30
- async function load(url, currentFile = '.') {
30
+ async function load(url, currentFile = '.', asStream = false) {
31
31
  let t;
32
32
  if (matchUrl.test(url)) {
33
33
  t = new URL(url);
@@ -37,15 +37,13 @@ async function load(url, currentFile = '.') {
37
37
  }
38
38
  else {
39
39
  const path = resolve(url, currentFile).absolute;
40
- // @ts-ignore
41
40
  t = new URL(path, self.origin);
42
41
  }
43
- // @ts-ignore
44
- return fetch(t, t.origin != self.origin ? { mode: 'cors' } : {}).then((response) => {
42
+ return fetch(t, t.origin != self.origin ? { mode: 'cors' } : {}).then(async (response) => {
45
43
  if (!response.ok) {
46
44
  throw new Error(`${response.status} ${response.statusText} ${response.url}`);
47
45
  }
48
- return response.body;
46
+ return asStream ? response.body : await response.text();
49
47
  });
50
48
  }
51
49
  /**
@@ -87,6 +85,7 @@ function render(data, options = {}) {
87
85
  * parse css file
88
86
  * @param file url or path
89
87
  * @param options
88
+ * @param asStream load file as stream
90
89
  *
91
90
  * @throws Error file not found
92
91
  *
@@ -105,8 +104,8 @@ function render(data, options = {}) {
105
104
  * console.log(result.ast);
106
105
  * ```
107
106
  */
108
- async function parseFile(file, options = {}) {
109
- return load(file).then(stream => parse(stream, { src: file, ...options }));
107
+ async function parseFile(file, options = {}, asStream = false) {
108
+ return Promise.resolve((options.load ?? load)(file, '.', asStream)).then(stream => parse(stream, { src: file, ...options }));
110
109
  }
111
110
  /**
112
111
  * parse css
@@ -153,6 +152,7 @@ async function parse(stream, options = {}) {
153
152
  * transform css file
154
153
  * @param file url or path
155
154
  * @param options
155
+ * @param asStream load file as stream
156
156
  *
157
157
  * Example:
158
158
  *
@@ -169,8 +169,8 @@ async function parse(stream, options = {}) {
169
169
  * console.log(result.code);
170
170
  * ```
171
171
  */
172
- async function transformFile(file, options = {}) {
173
- return load(file).then(stream => transform(stream, { src: file, ...options }));
172
+ async function transformFile(file, options = {}, asStream = false) {
173
+ return Promise.resolve((options.load ?? load)(file, '.', asStream)).then(stream => transform(stream, { src: file, ...options }));
174
174
  }
175
175
  /**
176
176
  * transform css
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tbela99/css-parser",
3
3
  "description": "CSS parser, minifier and validator for node and the browser",
4
- "version": "v1.3.3",
4
+ "version": "v1.3.4",
5
5
  "exports": {
6
6
  ".": "./dist/node.js",
7
7
  "./node": "./dist/node.js",
@@ -42,7 +42,10 @@
42
42
  "css-nesting",
43
43
  "css-compiler",
44
44
  "nested-css",
45
- "walker"
45
+ "walker",
46
+ "stream",
47
+ "streaming",
48
+ "streaming-parser"
46
49
  ],
47
50
  "author": "Thierry Bela",
48
51
  "license": "MIT OR LGPL-3.0",
@@ -69,7 +72,7 @@
69
72
  "rollup": "^4.48.0",
70
73
  "rollup-plugin-dts": "^6.2.1",
71
74
  "tslib": "^2.8.1",
72
- "typedoc": "^0.28.10",
75
+ "typedoc": "^0.28.13",
73
76
  "typedoc-material-theme": "^1.4.0"
74
77
  }
75
78
  }
@@ -1,54 +0,0 @@
1
- var ValidationTokenEnum;
2
- (function (ValidationTokenEnum) {
3
- ValidationTokenEnum[ValidationTokenEnum["Root"] = 0] = "Root";
4
- ValidationTokenEnum[ValidationTokenEnum["Keyword"] = 1] = "Keyword";
5
- ValidationTokenEnum[ValidationTokenEnum["PropertyType"] = 2] = "PropertyType";
6
- ValidationTokenEnum[ValidationTokenEnum["DeclarationType"] = 3] = "DeclarationType";
7
- ValidationTokenEnum[ValidationTokenEnum["AtRule"] = 4] = "AtRule";
8
- ValidationTokenEnum[ValidationTokenEnum["ValidationFunctionDefinition"] = 5] = "ValidationFunctionDefinition";
9
- ValidationTokenEnum[ValidationTokenEnum["OpenBracket"] = 6] = "OpenBracket";
10
- ValidationTokenEnum[ValidationTokenEnum["CloseBracket"] = 7] = "CloseBracket";
11
- ValidationTokenEnum[ValidationTokenEnum["OpenParenthesis"] = 8] = "OpenParenthesis";
12
- ValidationTokenEnum[ValidationTokenEnum["CloseParenthesis"] = 9] = "CloseParenthesis";
13
- ValidationTokenEnum[ValidationTokenEnum["Comma"] = 10] = "Comma";
14
- ValidationTokenEnum[ValidationTokenEnum["Pipe"] = 11] = "Pipe";
15
- ValidationTokenEnum[ValidationTokenEnum["Column"] = 12] = "Column";
16
- ValidationTokenEnum[ValidationTokenEnum["Star"] = 13] = "Star";
17
- ValidationTokenEnum[ValidationTokenEnum["OpenCurlyBrace"] = 14] = "OpenCurlyBrace";
18
- ValidationTokenEnum[ValidationTokenEnum["CloseCurlyBrace"] = 15] = "CloseCurlyBrace";
19
- ValidationTokenEnum[ValidationTokenEnum["HashMark"] = 16] = "HashMark";
20
- ValidationTokenEnum[ValidationTokenEnum["QuestionMark"] = 17] = "QuestionMark";
21
- ValidationTokenEnum[ValidationTokenEnum["Function"] = 18] = "Function";
22
- ValidationTokenEnum[ValidationTokenEnum["Number"] = 19] = "Number";
23
- ValidationTokenEnum[ValidationTokenEnum["Whitespace"] = 20] = "Whitespace";
24
- ValidationTokenEnum[ValidationTokenEnum["Parenthesis"] = 21] = "Parenthesis";
25
- ValidationTokenEnum[ValidationTokenEnum["Bracket"] = 22] = "Bracket";
26
- ValidationTokenEnum[ValidationTokenEnum["Block"] = 23] = "Block";
27
- ValidationTokenEnum[ValidationTokenEnum["AtLeastOnce"] = 24] = "AtLeastOnce";
28
- ValidationTokenEnum[ValidationTokenEnum["Separator"] = 25] = "Separator";
29
- ValidationTokenEnum[ValidationTokenEnum["Exclamation"] = 26] = "Exclamation";
30
- ValidationTokenEnum[ValidationTokenEnum["Ampersand"] = 27] = "Ampersand";
31
- ValidationTokenEnum[ValidationTokenEnum["PipeToken"] = 28] = "PipeToken";
32
- ValidationTokenEnum[ValidationTokenEnum["ColumnToken"] = 29] = "ColumnToken";
33
- ValidationTokenEnum[ValidationTokenEnum["AmpersandToken"] = 30] = "AmpersandToken";
34
- ValidationTokenEnum[ValidationTokenEnum["Parens"] = 31] = "Parens";
35
- ValidationTokenEnum[ValidationTokenEnum["PseudoClassToken"] = 32] = "PseudoClassToken";
36
- ValidationTokenEnum[ValidationTokenEnum["PseudoClassFunctionToken"] = 33] = "PseudoClassFunctionToken";
37
- ValidationTokenEnum[ValidationTokenEnum["StringToken"] = 34] = "StringToken";
38
- ValidationTokenEnum[ValidationTokenEnum["AtRuleDefinition"] = 35] = "AtRuleDefinition";
39
- ValidationTokenEnum[ValidationTokenEnum["DeclarationNameToken"] = 36] = "DeclarationNameToken";
40
- ValidationTokenEnum[ValidationTokenEnum["DeclarationDefinitionToken"] = 37] = "DeclarationDefinitionToken";
41
- ValidationTokenEnum[ValidationTokenEnum["SemiColon"] = 38] = "SemiColon";
42
- ValidationTokenEnum[ValidationTokenEnum["Character"] = 39] = "Character";
43
- ValidationTokenEnum[ValidationTokenEnum["InfinityToken"] = 40] = "InfinityToken";
44
- })(ValidationTokenEnum || (ValidationTokenEnum = {}));
45
- var ValidationSyntaxGroupEnum;
46
- (function (ValidationSyntaxGroupEnum) {
47
- ValidationSyntaxGroupEnum["Declarations"] = "declarations";
48
- ValidationSyntaxGroupEnum["Functions"] = "functions";
49
- ValidationSyntaxGroupEnum["Syntaxes"] = "syntaxes";
50
- ValidationSyntaxGroupEnum["Selectors"] = "selectors";
51
- ValidationSyntaxGroupEnum["AtRules"] = "atRules";
52
- })(ValidationSyntaxGroupEnum || (ValidationSyntaxGroupEnum = {}));
53
-
54
- export { ValidationSyntaxGroupEnum, ValidationTokenEnum };