UNPKG

6.13 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.MetadataManager = void 0;
4const typescript_1 = require("typescript");
5class MetadataManager {
6 constructor(content) {
7 this.content = content;
8 }
9 insert(metadata, symbol, staticOptions) {
10 const source = (0, typescript_1.createSourceFile)('filename.ts', this.content, typescript_1.ScriptTarget.ES2017);
11 const decoratorNodes = this.getDecoratorMetadata(source, '@Module');
12 const node = decoratorNodes[0];
13 if (!node) {
14 return;
15 }
16 const matchingProperties = node.properties
17 .filter((prop) => prop.kind === typescript_1.SyntaxKind.PropertyAssignment)
18 .filter((prop) => {
19 const name = prop.name;
20 switch (name.kind) {
21 case typescript_1.SyntaxKind.Identifier:
22 return name.getText(source) === metadata;
23 case typescript_1.SyntaxKind.StringLiteral:
24 return name.text === metadata;
25 default:
26 return false;
27 }
28 });
29 symbol = this.mergeSymbolAndExpr(symbol, staticOptions);
30 const addBlankLinesIfDynamic = () => {
31 symbol = staticOptions ? this.addBlankLines(symbol) : symbol;
32 };
33 if (matchingProperties.length === 0) {
34 const expr = node;
35 if (expr.properties.length === 0) {
36 addBlankLinesIfDynamic();
37 return this.insertMetadataToEmptyModuleDecorator(expr, metadata, symbol);
38 }
39 else {
40 addBlankLinesIfDynamic();
41 return this.insertNewMetadataToDecorator(expr, source, metadata, symbol);
42 }
43 }
44 else {
45 return this.insertSymbolToMetadata(source, matchingProperties, symbol, staticOptions);
46 }
47 }
48 getDecoratorMetadata(source, identifier) {
49 return this.getSourceNodes(source)
50 .filter((node) => node.kind === typescript_1.SyntaxKind.Decorator &&
51 node.expression.kind === typescript_1.SyntaxKind.CallExpression)
52 .map((node) => node.expression)
53 .filter((expr) => expr.arguments[0] &&
54 expr.arguments[0].kind === typescript_1.SyntaxKind.ObjectLiteralExpression)
55 .map((expr) => expr.arguments[0]);
56 }
57 getSourceNodes(sourceFile) {
58 const nodes = [sourceFile];
59 const result = [];
60 while (nodes.length > 0) {
61 const node = nodes.shift();
62 if (node) {
63 result.push(node);
64 if (node.getChildCount(sourceFile) >= 0) {
65 nodes.unshift(...node.getChildren());
66 }
67 }
68 }
69 return result;
70 }
71 insertMetadataToEmptyModuleDecorator(expr, metadata, symbol) {
72 const position = expr.getEnd() - 1;
73 const toInsert = ` ${metadata}: [${symbol}]`;
74 return this.content.split('').reduce((content, char, index) => {
75 if (index === position) {
76 return `${content}\n${toInsert}\n${char}`;
77 }
78 else {
79 return `${content}${char}`;
80 }
81 }, '');
82 }
83 insertNewMetadataToDecorator(expr, source, metadata, symbol) {
84 const node = expr.properties[expr.properties.length - 1];
85 const position = node.getEnd();
86 const text = node.getFullText(source);
87 const matches = text.match(/^\r?\n\s*/);
88 let toInsert;
89 if (matches) {
90 toInsert = `,${matches[0]}${metadata}: [${symbol}]`;
91 }
92 else {
93 toInsert = `, ${metadata}: [${symbol}]`;
94 }
95 return this.content.split('').reduce((content, char, index) => {
96 if (index === position) {
97 return `${content}${toInsert}${char}`;
98 }
99 else {
100 return `${content}${char}`;
101 }
102 }, '');
103 }
104 insertSymbolToMetadata(source, matchingProperties, symbol, staticOptions) {
105 const assignment = matchingProperties[0];
106 let node;
107 const arrLiteral = assignment.initializer;
108 if (!arrLiteral.elements) {
109 return this.content;
110 }
111 if (arrLiteral.elements.length === 0) {
112 node = arrLiteral;
113 }
114 else {
115 node = arrLiteral.elements;
116 }
117 if (Array.isArray(node)) {
118 const nodeArray = node;
119 const symbolsArray = nodeArray.map((childNode) => childNode.getText(source));
120 if (symbolsArray.includes(symbol)) {
121 return this.content;
122 }
123 node = node[node.length - 1];
124 }
125 let toInsert;
126 let position = node.getEnd();
127 if (node.kind === typescript_1.SyntaxKind.ArrayLiteralExpression) {
128 position--;
129 toInsert = staticOptions ? this.addBlankLines(symbol) : `${symbol}`;
130 }
131 else {
132 const text = node.getFullText(source);
133 const itemSeparator = (text.match(/^\r?\n(\r?)\s+/) ||
134 text.match(/^\r?\n/) ||
135 ' ')[0];
136 toInsert = `,${itemSeparator}${symbol}`;
137 }
138 return this.content.split('').reduce((content, char, index) => {
139 if (index === position) {
140 return `${content}${toInsert}${char}`;
141 }
142 else {
143 return `${content}${char}`;
144 }
145 }, '');
146 }
147 mergeSymbolAndExpr(symbol, staticOptions) {
148 if (!staticOptions) {
149 return symbol;
150 }
151 const spacing = 6;
152 let options = JSON.stringify(staticOptions.value, null, spacing);
153 options = options.replace(/\"([^(\")"]+)\":/g, '$1:');
154 options = options.replace(/\"/g, `'`);
155 options = options.slice(0, options.length - 1) + ' }';
156 symbol += `.${staticOptions.name}(${options})`;
157 return symbol;
158 }
159 addBlankLines(expr) {
160 return `\n ${expr}\n `;
161 }
162}
163exports.MetadataManager = MetadataManager;