esrap 1.4.9 → 2.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.
@@ -0,0 +1,2 @@
1
+ export * from './index';
2
+ export { Comment } from '../types';
@@ -0,0 +1,139 @@
1
+ /** @import { TSESTree } from '@typescript-eslint/types' */
2
+ /** @import { Visitors } from '../../types.js' */
3
+ /** @import { TSOptions } from '../types.js' */
4
+ import ts from '../ts/index.js';
5
+
6
+ /** @typedef {TSESTree.Node} Node */
7
+
8
+ /**
9
+ * @param {TSOptions} [options]
10
+ * @returns {Visitors<TSESTree.Node>}
11
+ */
12
+ export default (options) => ({
13
+ ...ts(options),
14
+
15
+ JSXElement(node, context) {
16
+ context.visit(node.openingElement);
17
+
18
+ if (node.children.length > 0) {
19
+ context.indent();
20
+ }
21
+
22
+ for (const child of node.children) {
23
+ context.visit(child);
24
+ }
25
+
26
+ if (node.children.length > 0) {
27
+ context.dedent();
28
+ }
29
+
30
+ if (node.closingElement) {
31
+ context.visit(node.closingElement);
32
+ }
33
+ },
34
+
35
+ JSXOpeningElement(node, context) {
36
+ context.write('<');
37
+
38
+ context.visit(node.name);
39
+
40
+ for (const attribute of node.attributes) {
41
+ context.write(' ');
42
+ context.visit(attribute);
43
+ }
44
+
45
+ if (node.selfClosing) {
46
+ context.write(' /');
47
+ }
48
+
49
+ context.write('>');
50
+ },
51
+
52
+ JSXClosingElement(node, context) {
53
+ context.write('</');
54
+
55
+ context.visit(node.name);
56
+
57
+ context.write('>');
58
+ },
59
+
60
+ JSXNamespacedName(node, context) {
61
+ context.visit(node.namespace);
62
+ context.write(':');
63
+ context.visit(node.name);
64
+ },
65
+
66
+ JSXIdentifier(node, context) {
67
+ context.write(node.name, node);
68
+ },
69
+
70
+ JSXMemberExpression(node, context) {
71
+ context.visit(node.object);
72
+ context.write('.');
73
+ context.visit(node.property);
74
+ },
75
+
76
+ JSXText(node, context) {
77
+ context.write(node.value, node);
78
+ },
79
+
80
+ JSXAttribute(node, context) {
81
+ context.visit(node.name);
82
+ if (node.value) {
83
+ context.write('=');
84
+ context.visit(node.value);
85
+ }
86
+ },
87
+
88
+ JSXEmptyExpression(node, context) {},
89
+
90
+ JSXFragment(node, context) {
91
+ context.visit(node.openingFragment);
92
+
93
+ if (node.children.length > 0) {
94
+ context.indent();
95
+ }
96
+
97
+ for (const child of node.children) {
98
+ context.visit(child);
99
+ }
100
+
101
+ if (node.children.length > 0) {
102
+ context.dedent();
103
+ }
104
+
105
+ context.visit(node.closingFragment);
106
+ },
107
+
108
+ JSXOpeningFragment(node, context) {
109
+ context.write('<>');
110
+ },
111
+
112
+ JSXClosingFragment(node, context) {
113
+ context.write('</>');
114
+ },
115
+
116
+ JSXExpressionContainer(node, context) {
117
+ context.write('{');
118
+
119
+ context.visit(node.expression);
120
+
121
+ context.write('}');
122
+ },
123
+
124
+ JSXSpreadChild(node, context) {
125
+ context.write('{...');
126
+
127
+ context.visit(node.expression);
128
+
129
+ context.write('}');
130
+ },
131
+
132
+ JSXSpreadAttribute(node, context) {
133
+ context.write('{...');
134
+
135
+ context.visit(node.argument);
136
+
137
+ context.write('}');
138
+ }
139
+ });
@@ -0,0 +1,2 @@
1
+ export * from './index';
2
+ export { Comment } from '../types';
@@ -0,0 +1,22 @@
1
+ export type TSOptions = {
2
+ quotes?: 'double' | 'single';
3
+ comments?: Comment[];
4
+ };
5
+
6
+ interface Position {
7
+ line: number;
8
+ column: number;
9
+ }
10
+
11
+ // this exists in TSESTree but because of the inanity around enums
12
+ // it's easier to do this ourselves
13
+ export interface Comment {
14
+ type: 'Line' | 'Block';
15
+ value: string;
16
+ start?: number;
17
+ end?: number;
18
+ loc: {
19
+ start: Position;
20
+ end: Position;
21
+ };
22
+ }
package/src/public.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { PrintOptions } from './types';
1
+ export { PrintOptions, Visitors } from './types';
2
2
  export * from './index';
package/src/types.d.ts CHANGED
@@ -1,11 +1,28 @@
1
1
  import { TSESTree } from '@typescript-eslint/types';
2
+ import { Context } from 'esrap';
3
+
4
+ export type BaseNode = {
5
+ type: string;
6
+ loc?: null | {
7
+ start: { line: number; column: number };
8
+ end: { line: number; column: number };
9
+ };
10
+ };
2
11
 
3
- type Handler<T> = (node: T, state: State) => undefined;
12
+ type NodeOf<T extends string, X> = X extends { type: T } ? X : never;
4
13
 
5
- export type Handlers = {
6
- [T in TSESTree.Node['type']]: Handler<Extract<TSESTree.Node, { type: T }>>;
14
+ type SpecialisedVisitors<T extends BaseNode> = {
15
+ [K in T['type']]?: Visitor<NodeOf<K, T>>;
7
16
  };
8
17
 
18
+ export type Visitor<T> = (node: T, context: Context) => void;
19
+
20
+ export type Visitors<T extends BaseNode = BaseNode> = T['type'] extends '_'
21
+ ? never
22
+ : SpecialisedVisitors<T> & { _?: (node: T, context: Context, visit: (node: T) => void) => void };
23
+
24
+ export { Context };
25
+
9
26
  export type TypeAnnotationNodes =
10
27
  | TSESTree.TypeNode
11
28
  | TSESTree.TypeElement
@@ -24,54 +41,22 @@ type TSExpressionWithTypeArguments = {
24
41
  expression: any;
25
42
  };
26
43
 
27
- // `@typescript-eslint/types` differs from the official `estree` spec by handling
28
- // comments differently. This is a node which we can use to ensure type saftey.
29
- export type NodeWithComments = {
30
- leadingComments?: TSESTree.Comment[] | undefined;
31
- trailingComments?: TSESTree.Comment[] | undefined;
32
- } & TSESTree.Node;
33
-
34
- export interface State {
35
- commands: Command[];
36
- comments: TSESTree.Comment[];
37
- multiline: boolean;
38
- quote: "'" | '"';
39
- }
40
-
41
44
  export interface Location {
42
45
  type: 'Location';
43
46
  line: number;
44
47
  column: number;
45
48
  }
46
49
 
47
- export interface Newline {
48
- type: 'Newline';
49
- }
50
-
51
- export interface Indent {
52
- type: 'Indent';
53
- }
54
-
55
- export interface Dedent {
56
- type: 'Dedent';
57
- }
58
-
59
50
  export interface IndentChange {
60
51
  type: 'IndentChange';
61
52
  offset: number;
62
53
  }
63
54
 
64
- export interface CommentChunk {
65
- type: 'Comment';
66
- comment: TSESTree.Comment;
67
- }
68
-
69
- export type Command = string | Location | Newline | Indent | Dedent | CommentChunk | Command[];
55
+ export type Command = string | number | Location | Command[];
70
56
 
71
57
  export interface PrintOptions {
72
58
  sourceMapSource?: string;
73
59
  sourceMapContent?: string;
74
60
  sourceMapEncodeMappings?: boolean; // default true
75
61
  indent?: string; // default tab
76
- quotes?: 'single' | 'double'; // default single
77
62
  }
package/types/index.d.ts CHANGED
@@ -1,21 +1,169 @@
1
1
  declare module 'esrap' {
2
+ type BaseNode = {
3
+ type: string;
4
+ loc?: null | {
5
+ start: { line: number; column: number };
6
+ end: { line: number; column: number };
7
+ };
8
+ };
9
+
10
+ type NodeOf<T extends string, X> = X extends { type: T } ? X : never;
11
+
12
+ type SpecialisedVisitors<T extends BaseNode> = {
13
+ [K in T['type']]?: Visitor<NodeOf<K, T>>;
14
+ };
15
+
16
+ type Visitor<T> = (node: T, context: Context) => void;
17
+
18
+ export type Visitors<T extends BaseNode = BaseNode> = T['type'] extends '_'
19
+ ? never
20
+ : SpecialisedVisitors<T> & { _?: (node: T, context: Context, visit: (node: T) => void) => void };
21
+
22
+ interface Location {
23
+ type: 'Location';
24
+ line: number;
25
+ column: number;
26
+ }
27
+
28
+ type Command = string | number | Location | Command[];
29
+
2
30
  export interface PrintOptions {
3
31
  sourceMapSource?: string;
4
32
  sourceMapContent?: string;
5
33
  sourceMapEncodeMappings?: boolean; // default true
6
34
  indent?: string; // default tab
7
- quotes?: 'single' | 'double'; // default single
8
35
  }
9
36
  /**
10
37
  * @returns // TODO
11
38
  */
12
- export function print(node: {
13
- type: string;
14
- [key: string]: any;
15
- }, opts?: PrintOptions): {
39
+ export function print<T extends BaseNode = BaseNode>(node: T, visitors: Visitors<T>, opts?: PrintOptions): {
16
40
  code: string;
17
41
  map: any;
18
42
  };
43
+ export class Context {
44
+
45
+ constructor(visitors: Visitors, commands?: Command[]);
46
+ multiline: boolean;
47
+ indent(): void;
48
+ dedent(): void;
49
+ margin(): void;
50
+ newline(): void;
51
+
52
+ append(context: Context): void;
53
+
54
+ write(content: string, node?: BaseNode): void;
55
+
56
+ location(line: number, column: number): void;
57
+
58
+ visit(node: {
59
+ type: string;
60
+ }): void;
61
+ empty(): boolean;
62
+ measure(): number;
63
+ "new"(): Context;
64
+ #private;
65
+ }
66
+
67
+ export {};
68
+ }
69
+
70
+ declare module 'esrap/languages/ts' {
71
+ import type { TSESTree } from '@typescript-eslint/types';
72
+ import type { Context } from 'esrap';
73
+ export const EXPRESSIONS_PRECEDENCE: Record<TSESTree.Expression["type"] | "Super" | "RestElement", number>;
74
+ export default function _default(options?: TSOptions): Visitors<TSESTree.Node>;
75
+ export type Node = TSESTree.Node;
76
+ type TSOptions = {
77
+ quotes?: 'double' | 'single';
78
+ comments?: Comment[];
79
+ };
80
+
81
+ interface Position {
82
+ line: number;
83
+ column: number;
84
+ }
85
+
86
+ // this exists in TSESTree but because of the inanity around enums
87
+ // it's easier to do this ourselves
88
+ export interface Comment {
89
+ type: 'Line' | 'Block';
90
+ value: string;
91
+ start?: number;
92
+ end?: number;
93
+ loc: {
94
+ start: Position;
95
+ end: Position;
96
+ };
97
+ }
98
+ type BaseNode = {
99
+ type: string;
100
+ loc?: null | {
101
+ start: { line: number; column: number };
102
+ end: { line: number; column: number };
103
+ };
104
+ };
105
+
106
+ type NodeOf<T extends string, X> = X extends { type: T } ? X : never;
107
+
108
+ type SpecialisedVisitors<T extends BaseNode> = {
109
+ [K in T['type']]?: Visitor<NodeOf<K, T>>;
110
+ };
111
+
112
+ type Visitor<T> = (node: T, context: Context) => void;
113
+
114
+ type Visitors<T extends BaseNode = BaseNode> = T['type'] extends '_'
115
+ ? never
116
+ : SpecialisedVisitors<T> & { _?: (node: T, context: Context, visit: (node: T) => void) => void };
117
+
118
+ export {};
119
+ }
120
+
121
+ declare module 'esrap/languages/tsx' {
122
+ import type { TSESTree } from '@typescript-eslint/types';
123
+ import type { Context } from 'esrap';
124
+ export default function _default(options?: TSOptions): Visitors<TSESTree.Node>;
125
+ export type Node = TSESTree.Node;
126
+ type TSOptions = {
127
+ quotes?: 'double' | 'single';
128
+ comments?: Comment[];
129
+ };
130
+
131
+ interface Position {
132
+ line: number;
133
+ column: number;
134
+ }
135
+
136
+ // this exists in TSESTree but because of the inanity around enums
137
+ // it's easier to do this ourselves
138
+ export interface Comment {
139
+ type: 'Line' | 'Block';
140
+ value: string;
141
+ start?: number;
142
+ end?: number;
143
+ loc: {
144
+ start: Position;
145
+ end: Position;
146
+ };
147
+ }
148
+ type BaseNode = {
149
+ type: string;
150
+ loc?: null | {
151
+ start: { line: number; column: number };
152
+ end: { line: number; column: number };
153
+ };
154
+ };
155
+
156
+ type NodeOf<T extends string, X> = X extends { type: T } ? X : never;
157
+
158
+ type SpecialisedVisitors<T extends BaseNode> = {
159
+ [K in T['type']]?: Visitor<NodeOf<K, T>>;
160
+ };
161
+
162
+ type Visitor<T> = (node: T, context: Context) => void;
163
+
164
+ type Visitors<T extends BaseNode = BaseNode> = T['type'] extends '_'
165
+ ? never
166
+ : SpecialisedVisitors<T> & { _?: (node: T, context: Context, visit: (node: T) => void) => void };
19
167
 
20
168
  export {};
21
169
  }
@@ -2,17 +2,38 @@
2
2
  "version": 3,
3
3
  "file": "index.d.ts",
4
4
  "names": [
5
+ "BaseNode",
6
+ "NodeOf",
7
+ "SpecialisedVisitors",
8
+ "Visitor",
9
+ "Visitors",
10
+ "Location",
11
+ "Command",
5
12
  "PrintOptions",
6
- "print"
13
+ "print",
14
+ "Context",
15
+ "EXPRESSIONS_PRECEDENCE",
16
+ "Node",
17
+ "TSOptions",
18
+ "Position",
19
+ "Comment"
7
20
  ],
8
21
  "sources": [
9
22
  "../src/types.d.ts",
10
- "../src/index.js"
23
+ "../src/index.js",
24
+ "../src/context.js",
25
+ "../src/languages/ts/index.js",
26
+ "../src/languages/types.d.ts",
27
+ "../src/languages/tsx/index.js"
11
28
  ],
12
29
  "sourcesContent": [
30
+ null,
31
+ null,
32
+ null,
33
+ null,
13
34
  null,
14
35
  null
15
36
  ],
16
- "mappings": ";kBAsEiBA,YAAYA;;;;;;;;;;iBC/CbC,KAAKA",
37
+ "mappings": ";MAGYA,QAAQA;;;;;;;;MAQfC,MAAMA;;MAENC,mBAAmBA;;;;MAIZC,OAAOA;;aAEPC,QAAQA;;;;WAwBHC,QAAQA;;;;;;MAWbC,OAAOA;;kBAEFC,YAAYA;;;;;;;;;iBCHbC,KAAKA;;;;cC7CRC,OAAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cCAPC,sBAAsBA;;aAHZC,IAAIA;MCLfC,SAASA;;;;;WAKXC,QAAQA;;;;;;;kBAODC,OAAOA;;;;;;;;;;MJTZd,QAAQA;;;;;;;;MAQfC,MAAMA;;MAENC,mBAAmBA;;;;MAIZC,OAAOA;;MAEPC,QAAQA;;;;;;;;;;;aKdGO,IAAIA;MDLfC,SAASA;;;;;WAKXC,QAAQA;;;;;;;kBAODC,OAAOA;;;;;;;;;;MJTZd,QAAQA;;;;;;;;MAQfC,MAAMA;;MAENC,mBAAmBA;;;;MAIZC,OAAOA;;MAEPC,QAAQA",
17
38
  "ignoreList": []
18
39
  }