Skip to content

Commit b243415

Browse files
committed
refactor: Split parse file to multiple files
1 parent c9cdd8d commit b243415

File tree

3 files changed

+104
-94
lines changed

3 files changed

+104
-94
lines changed

src/parameter.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { ParseContext } from './parse';
2+
3+
export const parseParameter = (value: string) => {
4+
const alias_param = value.split(':');
5+
const param = alias_param.pop()!;
6+
const alias = alias_param.pop();
7+
8+
const item = param.split('_');
9+
10+
if (item.length < 2) {
11+
throw new Error(`Parmeter ${value} is invalid, try to define it like: "a_Int", "b_String", "alias:c_Int" and so on.`);
12+
}
13+
14+
const itemType = item.pop()!;
15+
const itemName = item.join('_');
16+
17+
return {
18+
name: itemName,
19+
variable: alias || itemName,
20+
type: itemType,
21+
};
22+
};
23+
24+
export const collectParams = (params: (string | undefined)[] | undefined, ctx: ParseContext) => {
25+
params && params.forEach((param) => {
26+
param && (~ctx.params.indexOf(param) || ctx.params.push(param));
27+
});
28+
};

src/parse.ts

Lines changed: 26 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import { FragmentMeta, isFragment } from './fragment';
2+
import { collectParams, parseParameter } from './parameter';
3+
import { renderObject, renderDirectives } from './render';
24
import { Template, TemplateObj, Types } from './types';
35

46
export interface ParseContext {
@@ -10,7 +12,10 @@ export interface ParseContext {
1012
}
1113

1214
export const parse = (type: string, name: string | undefined, nodes: TemplateObj, ctx: ParseContext): string => {
13-
name = name || capitalize(Object.keys(nodes)[0]);
15+
if (!name) {
16+
const firstName = Object.keys(nodes)[0];
17+
name = firstName.substr(0, 1).toUpperCase() + firstName.substr(1);
18+
}
1419

1520
const body = cycleParse(nodes, ctx, -2);
1621
const params = ctx.params.map((key) => {
@@ -29,7 +34,7 @@ const cycleParse = (nodes: Template, ctx: ParseContext, space: number): string =
2934
collectParams(nodes.totalParams, ctx);
3035

3136
const realName = nodes.realName ? `: ${nodes.realName}` : '';
32-
const directives = renderInclude(nodes.includeParam) + renderSkip(nodes.skipParam);
37+
const directives = renderDirectives(nodes.includeParam, nodes.skipParam);
3338

3439
// function
3540
if (nodes.fnParams) {
@@ -50,7 +55,7 @@ const cycleParse = (nodes: Template, ctx: ParseContext, space: number): string =
5055
return realName + directives;
5156
}
5257

53-
const newNodes: Record<string, string> = {};
58+
const stringNodes: Record<string, string> = {};
5459

5560
// object
5661
Object.keys(nodes).forEach((key) => {
@@ -60,112 +65,39 @@ const cycleParse = (nodes: Template, ctx: ParseContext, space: number): string =
6065
if (isFragment(key)) {
6166
// @ts-ignore
6267
const fragment: FragmentMeta = node;
63-
const directives = renderInclude(fragment.includeParam) + renderSkip(fragment.skipParam);
68+
const directives = renderDirectives(fragment.includeParam, fragment.skipParam);
6469

6570
collectParams([fragment.includeParam, fragment.skipParam], ctx);
6671

6772
if (fragment.inline) {
68-
newNodes[key] = `... on ${fragment.on}${directives}${cycleParse(fragment.template, ctx, space + 2)}`;
73+
stringNodes[key] = `... on ${fragment.on}${directives}${cycleParse(fragment.template, ctx, space + 2)}`;
6974
} else {
70-
if (!~ctx.fragmentObjs.indexOf(fragment)) {
71-
ctx.fragmentObjs.push(fragment);
72-
ctx.fragmentStrs.push(parseFragment(fragment, ctx));
73-
}
74-
newNodes[key] = `...${fragment.tmpName}${directives}`;
75+
parseFragment(fragment, ctx);
76+
stringNodes[key] = `...${fragment.tmpName}${directives}`;
7577
}
7678
} else {
77-
newNodes[key] = cycleParse(node, ctx, space + 2);
79+
stringNodes[key] = cycleParse(node, ctx, space + 2);
7880
}
7981
});
8082

81-
return render(newNodes, space + 2);
82-
};
83-
84-
const parseFragment = (fragment: FragmentMeta, ctx: ParseContext): string => {
85-
const on = fragment.on;
86-
const index = ctx.fragmentIndex[on] = ctx.fragmentIndex[on] === undefined ? 0 : ctx.fragmentIndex[on] + 1;
87-
const suffix = index === 0 ? '' : `_${index}`;
88-
fragment.tmpName = fragment.name || `${fragment.on}Fragment${suffix}`;
89-
90-
return `\n\nfragment ${fragment.tmpName} on ${fragment.on}${cycleParse(fragment.template, ctx, -2)}`;
83+
return renderObject(stringNodes, space + 2);
9184
};
9285

93-
const parseParameter = (value: string) => {
94-
const alias_param = value.split(':');
95-
const param = alias_param.pop()!;
96-
const alias = alias_param.pop();
86+
const parseFragment = (fragment: FragmentMeta, ctx: ParseContext): void => {
87+
const fragmentObjs = ctx.fragmentObjs;
9788

98-
const item = param.split('_');
99-
100-
if (item.length < 2) {
101-
throw new Error(`Parmeter ${value} is invalid, try to define it like: "a_Int", "b_String", "alias:c_Int" and so on.`);
89+
if (~fragmentObjs.indexOf(fragment)) {
90+
return;
10291
}
10392

104-
const itemType = item.pop()!;
105-
const itemName = item.join('_');
106-
107-
return {
108-
name: itemName,
109-
variable: alias || itemName,
110-
type: itemType,
111-
};
112-
};
113-
114-
const render = (nodes: Record<string, string>, space: number): string => {
115-
let tpl = ` {`;
116-
117-
Object.keys(nodes).forEach((key) => {
118-
const node = nodes[key];
119-
120-
if (node === '') {
121-
tpl += `\n${addSpace(space + 2)}${key}`;
122-
return;
123-
}
124-
125-
if (isFragment(key)) {
126-
tpl += `\n${addSpace(space + 2)}${node}`;
127-
return;
128-
}
129-
130-
tpl += `\n${addSpace(space + 2)}${key}${node}`;
131-
});
132-
133-
tpl += `\n${addSpace(space)}}`;
134-
135-
return tpl;
136-
};
137-
138-
const renderInclude = (param?: string) => {
139-
return param ? ` @include(if: $${parseParameter(param).variable})` : '';
140-
};
141-
142-
const renderSkip = (param?: string) => {
143-
return param ? ` @skip(if: $${parseParameter(param).variable})` : '';
144-
};
93+
const { on, template, name } = fragment;
94+
const indexes = ctx.fragmentIndex;
14595

146-
const collectParams = (params: (string | undefined)[] | undefined, ctx: ParseContext) => {
147-
params && params.forEach((param) => {
148-
param && (~ctx.params.indexOf(param) || ctx.params.push(param));
149-
});
150-
};
151-
152-
const preDefinedSpaces = [
153-
'',
154-
' ',
155-
' ',
156-
' ',
157-
' ',
158-
' ',
159-
' ',
160-
' ',
161-
' ',
162-
' ',
163-
];
164-
165-
const addSpace = (length: number) => {
166-
return preDefinedSpaces[length / 2] || '';
167-
}
96+
indexes[on] = indexes[on] === undefined ? 0 : indexes[on] + 1;
97+
const tmpName = fragment.tmpName = name || `${on}Fragment${indexes[on] === 0 ? '' : `_${indexes[on]}`}`;
16898

169-
const capitalize = (value: string) => {
170-
return value.substr(0, 1).toUpperCase() + value.substr(1);
99+
fragmentObjs.push(fragment);
100+
ctx.fragmentStrs.push(
101+
`\n\nfragment ${tmpName} on ${on}${cycleParse(template, ctx, -2)}`
102+
);
171103
};

src/render.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { isFragment } from './fragment';
2+
import { parseParameter } from './parameter';
3+
4+
export const renderObject = (nodes: Record<string, string>, space: number): string => {
5+
let tpl = ` {`;
6+
7+
Object.keys(nodes).forEach((key) => {
8+
const node = nodes[key];
9+
10+
if (node === '') {
11+
tpl += `\n${renderSpace(space + 2)}${key}`;
12+
return;
13+
}
14+
15+
if (isFragment(key)) {
16+
tpl += `\n${renderSpace(space + 2)}${node}`;
17+
return;
18+
}
19+
20+
tpl += `\n${renderSpace(space + 2)}${key}${node}`;
21+
});
22+
23+
tpl += `\n${renderSpace(space)}}`;
24+
25+
return tpl;
26+
};
27+
28+
export const renderDirectives = (includeParam?: string, skipParam?: string): string => {
29+
const include = includeParam ? ` @include(if: $${parseParameter(includeParam).variable})` : '';
30+
const skip = skipParam ? ` @skip(if: $${parseParameter(skipParam).variable})` : '';
31+
32+
return include + skip;
33+
};
34+
35+
const spaces = [
36+
'',
37+
' ',
38+
' ',
39+
' ',
40+
' ',
41+
' ',
42+
' ',
43+
' ',
44+
' ',
45+
' ',
46+
];
47+
48+
export const renderSpace = (length: number) => {
49+
return spaces[length / 2] || '';
50+
}

0 commit comments

Comments
 (0)