@putout/printer 3.8.0 → 4.0.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.
package/ChangeLog CHANGED
@@ -1,3 +1,9 @@
1
+ 2023.09.03, v4.0.0
2
+
3
+ feature:
4
+ - d935f8f @putout/printer: semantics: trailingComma
5
+ - 9aa52e4 @putout/printer: format: quote: add
6
+
1
7
  2023.09.01, v3.8.0
2
8
 
3
9
  feature:
package/README.md CHANGED
@@ -8,7 +8,7 @@ Prints [**Babel AST**](https://github.com/coderaiser/estree-to-babel) to readabl
8
8
  - ☝️ Similar to **Recast**, but [twice faster](#speed-comparison), also simpler and easier in maintenance, since it supports only **Babel**.
9
9
  - ☝️ As opinionated as **Prettier**, but has more user-friendly output and works directly with **AST**.
10
10
  - ☝️ Like **ESLint** but works directly with **Babel AST**.
11
- - ☝️ Easily extandable with help of [Overrides](h#overrides).
11
+ - ☝️ Easily extendable with help of [Overrides](h#overrides).
12
12
 
13
13
  Supports:
14
14
 
@@ -81,6 +81,7 @@ print(ast, {
81
81
  splitter: '\n',
82
82
  roundBraceOpen: '(',
83
83
  roundBraceClose: ')',
84
+ quote: `'`,
84
85
  },
85
86
  semantics: {
86
87
  comments: true,
@@ -88,6 +89,7 @@ print(ast, {
88
89
  maxElementsInOneLine: 3,
89
90
  maxVariablesInOneLine: 4,
90
91
  maxPropertiesInOneLine: 2,
92
+ trailingComma: true,
91
93
  },
92
94
  visitors: {
93
95
  AssignmentPattern(path, {print}) {
package/lib/is-json.js ADDED
@@ -0,0 +1,32 @@
1
+ 'use strict';
2
+
3
+ const {
4
+ isCallExpression,
5
+ isIdentifier,
6
+ } = require('@babel/types');
7
+ const {isJSON} = require('@putout/processor-json/is-json');
8
+
9
+ module.exports.isASTJSON = (ast) => {
10
+ const {program} = ast;
11
+
12
+ if (!program)
13
+ return false;
14
+
15
+ const {body} = ast.program;
16
+
17
+ if (!body.length)
18
+ return false;
19
+
20
+ const {expression} = ast.program.body[0];
21
+
22
+ if (!isCallExpression(expression))
23
+ return false;
24
+
25
+ const {callee} = expression;
26
+
27
+ if (!isIdentifier(callee))
28
+ return false;
29
+
30
+ return isJSON(callee.name);
31
+ };
32
+
package/lib/printer.js CHANGED
@@ -2,8 +2,19 @@
2
2
 
3
3
  const {tokenize} = require('./tokenize/tokenize');
4
4
  const {printTokens} = require('./print-tokens');
5
+ const {isASTJSON} = require('./is-json');
6
+ const {assign} = Object;
5
7
 
6
- module.exports.print = (ast, overrides) => {
8
+ module.exports.print = (ast, overrides = {}) => {
9
+ if (isASTJSON(ast))
10
+ assign(overrides, {
11
+ format: {
12
+ quote: `"`,
13
+ },
14
+ });
15
+
7
16
  const tokens = tokenize(ast, overrides);
17
+
8
18
  return printTokens(tokens);
9
19
  };
20
+
@@ -53,7 +53,10 @@ module.exports.ArrayExpression = {
53
53
  print.breakline();
54
54
  },
55
55
  print(path, {print, maybe, indent}, semantics) {
56
- const {maxElementsInOneLine} = semantics;
56
+ const {
57
+ maxElementsInOneLine,
58
+ trailingComma,
59
+ } = semantics;
57
60
  const elements = path.get('elements');
58
61
  const shouldIncreaseIndent = !isIncreaseIndent(path);
59
62
 
@@ -78,7 +81,10 @@ module.exports.ArrayExpression = {
78
81
  const is = isNewLine && isCurrentNewLine(element);
79
82
  maybe.indent(is);
80
83
  print(element);
81
- maybe.print(is, ',');
84
+
85
+ if (index < n || trailingComma)
86
+ maybe.print(is, ',');
87
+
82
88
  maybe.print.newline(is && !isNextObject(element));
83
89
  maybe.print.space(element.isSpreadElement() && isNextObject(element));
84
90
 
@@ -19,6 +19,7 @@ const isValue = (path) => path.get('properties.0.value').node;
19
19
  const isParentExpression = (path) => path.parentPath.isExpressionStatement();
20
20
 
21
21
  module.exports.ObjectExpression = (path, {print, maybe, indent, write}, semantics) => {
22
+ const {trailingComma} = semantics;
22
23
  indent.inc();
23
24
 
24
25
  const properties = path.get('properties');
@@ -31,7 +32,9 @@ module.exports.ObjectExpression = (path, {print, maybe, indent, write}, semantic
31
32
  parseComments(path, {write}, semantics);
32
33
  maybe.print.newline(manyLines);
33
34
 
34
- for (const property of properties) {
35
+ const n = properties.length - 1;
36
+
37
+ for (const [index, property] of properties.entries()) {
35
38
  if (property.isSpreadElement()) {
36
39
  const logical = isLogical(property);
37
40
 
@@ -39,7 +42,7 @@ module.exports.ObjectExpression = (path, {print, maybe, indent, write}, semantic
39
42
  print(property);
40
43
 
41
44
  if (length > 1 || manyLines) {
42
- print(',');
45
+ maybe.print(index !== n || trailingComma, ',');
43
46
  print.newline();
44
47
  }
45
48
 
@@ -3,7 +3,8 @@
3
3
  const {isConcatenation} = require('../binary-expression/concatanate');
4
4
  const {isOneLine} = require('./object-expression');
5
5
 
6
- module.exports.ObjectProperty = (path, {maybe, traverse, write}) => {
6
+ module.exports.ObjectProperty = (path, {maybe, traverse, write}, semantics) => {
7
+ const {trailingComma} = semantics;
7
8
  const {shorthand, computed} = path.node;
8
9
 
9
10
  const key = path.get('key');
@@ -24,7 +25,7 @@ module.exports.ObjectProperty = (path, {maybe, traverse, write}) => {
24
25
  }
25
26
 
26
27
  if (manyLines)
27
- write(',');
28
+ maybe.write(!isLast || trailingComma, ',');
28
29
  else if (!isLast && properties.length)
29
30
  write(', ');
30
31
  };
@@ -39,7 +39,23 @@ module.exports = {
39
39
  StringLiteral(path, {write}) {
40
40
  const {raw, value} = path.node;
41
41
 
42
- write(raw || `'${value}'`);
42
+ if (raw && path.parentPath.isJSXAttribute()) {
43
+ write(raw);
44
+ return;
45
+ }
46
+
47
+ if (raw) {
48
+ const value = raw.slice(1, -1);
49
+ write.quote();
50
+ write(value);
51
+ write.quote();
52
+
53
+ return;
54
+ }
55
+
56
+ write.quote();
57
+ write(value);
58
+ write.quote();
43
59
  },
44
60
  RegExpLiteral(path, {print}) {
45
61
  print(path.node.raw);
@@ -22,6 +22,7 @@ function initFormat(format) {
22
22
  splitter: '\n',
23
23
  roundBraceOpen: '(',
24
24
  roundBraceClose: ')',
25
+ quote: `'`,
25
26
  ...format,
26
27
  };
27
28
  }
@@ -33,6 +34,7 @@ function initSemantics(semantics = {}) {
33
34
  maxSpecifiersInOneLine: 2,
34
35
  maxElementsInOneLine: 5,
35
36
  maxVariablesInOneLine: 4,
37
+ trailingComma: true,
36
38
  ...semantics,
37
39
  };
38
40
  }
@@ -131,6 +131,13 @@ module.exports.tokenize = (ast, overrides) => {
131
131
  indent();
132
132
  };
133
133
 
134
+ const quote = () => {
135
+ addToken({
136
+ type: TYPES.QUOTE,
137
+ value: format.quote,
138
+ });
139
+ };
140
+
134
141
  const newline = () => {
135
142
  addToken({
136
143
  type: TYPES.NEWLINE,
@@ -145,6 +152,7 @@ module.exports.tokenize = (ast, overrides) => {
145
152
  breakline,
146
153
  space,
147
154
  splitter,
155
+ quote,
148
156
  });
149
157
 
150
158
  assign(maybeWrite, {
@@ -173,6 +181,7 @@ module.exports.tokenize = (ast, overrides) => {
173
181
  debug,
174
182
  traverse,
175
183
  maybe,
184
+ quote,
176
185
  store: fullstore(),
177
186
  };
178
187
 
package/lib/types.js CHANGED
@@ -8,6 +8,7 @@ module.exports.TYPES = {
8
8
  INDENT: 'Indent',
9
9
  DEBUG: 'Debug',
10
10
  SPACE: 'Space',
11
- ROUND_BRACE_OPEN: '(',
12
- ROUND_BRACE_CLOSE: ')',
11
+ ROUND_BRACE_OPEN: 'RoundBraceOpen',
12
+ ROUND_BRACE_CLOSE: 'RoundBraceClose',
13
+ QUOTE: 'Quote',
13
14
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@putout/printer",
3
- "version": "3.8.0",
3
+ "version": "4.0.0",
4
4
  "type": "commonjs",
5
5
  "author": "coderaiser <mnemonic.enemy@gmail.com> (https://github.com/coderaiser)",
6
6
  "description": "Simplest possible opinionated Babel AST printer for 🐊Putout",
@@ -32,6 +32,7 @@
32
32
  "@babel/types": "^7.21.3",
33
33
  "@putout/compare": "^12.0.4",
34
34
  "@putout/operate": "^10.0.2",
35
+ "@putout/processor-json": "^7.0.0",
35
36
  "fullstore": "^3.0.0",
36
37
  "just-snake-case": "^3.2.0",
37
38
  "parse-import-specifiers": "^1.0.1",