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