@azure-tools/typespec-ts 0.56.0-dev.5 → 0.56.0-dev.6
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/dist/src/framework/declaration.d.ts.map +1 -1
- package/dist/src/framework/declaration.js +6 -20
- package/dist/src/framework/declaration.js.map +1 -1
- package/dist/src/framework/source-file-batch.d.ts +35 -0
- package/dist/src/framework/source-file-batch.d.ts.map +1 -0
- package/dist/src/framework/source-file-batch.js +128 -0
- package/dist/src/framework/source-file-batch.js.map +1 -0
- package/dist/src/modular/build-root-index.d.ts.map +1 -1
- package/dist/src/modular/build-root-index.js +37 -9
- package/dist/src/modular/build-root-index.js.map +1 -1
- package/dist/src/modular/build-subpath-index.d.ts.map +1 -1
- package/dist/src/modular/build-subpath-index.js +15 -2
- package/dist/src/modular/build-subpath-index.js.map +1 -1
- package/dist/src/modular/emit-models.d.ts.map +1 -1
- package/dist/src/modular/emit-models.js +24 -17
- package/dist/src/modular/emit-models.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/framework/declaration.ts +8 -20
- package/src/framework/source-file-batch.ts +140 -0
- package/src/modular/build-root-index.ts +52 -14
- package/src/modular/build-subpath-index.ts +24 -3
- package/src/modular/emit-models.ts +24 -18
package/package.json
CHANGED
|
@@ -8,12 +8,14 @@ import {
|
|
|
8
8
|
InterfaceDeclaration,
|
|
9
9
|
InterfaceDeclarationStructure,
|
|
10
10
|
SourceFile,
|
|
11
|
+
StatementStructures,
|
|
11
12
|
StructureKind,
|
|
12
13
|
TypeAliasDeclaration,
|
|
13
14
|
TypeAliasDeclarationStructure,
|
|
14
15
|
} from "ts-morph";
|
|
15
16
|
import { useBinder } from "./hooks/binder.js";
|
|
16
17
|
import { refkey as getRefKey } from "./refkey.js";
|
|
18
|
+
import { enqueueStatement } from "./source-file-batch.js";
|
|
17
19
|
export type DeclarationStructures =
|
|
18
20
|
| ClassDeclarationStructure
|
|
19
21
|
| EnumDeclarationStructure
|
|
@@ -80,25 +82,11 @@ export function addDeclaration(
|
|
|
80
82
|
// Update the declaration name to be unique
|
|
81
83
|
const trackedDeclaration = { ...declaration, name: trackedDeclarationName };
|
|
82
84
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
case StructureKind.Enum:
|
|
88
|
-
sourceFile.addEnum(trackedDeclaration);
|
|
89
|
-
break;
|
|
90
|
-
case StructureKind.Function:
|
|
91
|
-
sourceFile.addFunction(trackedDeclaration);
|
|
92
|
-
break;
|
|
93
|
-
case StructureKind.Interface:
|
|
94
|
-
sourceFile.addInterface(trackedDeclaration);
|
|
95
|
-
break;
|
|
96
|
-
case StructureKind.TypeAlias:
|
|
97
|
-
if (trackedDeclaration.type) {
|
|
98
|
-
sourceFile.addTypeAlias(trackedDeclaration);
|
|
99
|
-
}
|
|
100
|
-
break;
|
|
101
|
-
default:
|
|
102
|
-
throw new Error(`Unsupported declaration kind ${(trackedDeclaration as any).kind}`);
|
|
85
|
+
// Skip empty type aliases (they have no body to emit). Done before
|
|
86
|
+
// dispatching so behaviour is identical whether batching or not.
|
|
87
|
+
if (trackedDeclaration.kind === StructureKind.TypeAlias && !trackedDeclaration.type) {
|
|
88
|
+
return;
|
|
103
89
|
}
|
|
90
|
+
|
|
91
|
+
enqueueStatement(sourceFile, trackedDeclaration as StatementStructures);
|
|
104
92
|
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ExportDeclarationStructure,
|
|
3
|
+
SourceFile,
|
|
4
|
+
StatementStructures,
|
|
5
|
+
StructureKind,
|
|
6
|
+
} from "ts-morph";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Generic per-source-file batch for ts-morph `add*` mutations.
|
|
10
|
+
*
|
|
11
|
+
* Each individual `sourceFile.addInterface/addFunction/addExportDeclaration/...`
|
|
12
|
+
* call re-parses the entire source file in ts-morph. Calling them in a loop
|
|
13
|
+
* therefore grows as O(N × file_size). This module collects structures while
|
|
14
|
+
* a batch is open and, on flush, issues a single `addStatements` call per file,
|
|
15
|
+
* collapsing N re-parses into 1.
|
|
16
|
+
*
|
|
17
|
+
* The batch is reference-counted so nested begin/flush pairs compose safely.
|
|
18
|
+
* Statements flush in insertion order and produce byte-identical output.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
let batchDepth = 0;
|
|
22
|
+
const pendingByFile = new Map<SourceFile, StatementStructures[]>();
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Opens a batching scope. Subsequent `enqueueStatement` calls queue rather
|
|
26
|
+
* than mutate the AST until the matching `flushSourceFileBatch` is called.
|
|
27
|
+
*/
|
|
28
|
+
export function beginSourceFileBatch(): void {
|
|
29
|
+
batchDepth++;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Closes the most recent batching scope. When the outermost scope closes,
|
|
34
|
+
* all pending structures are written to their source files in bulk.
|
|
35
|
+
*/
|
|
36
|
+
export function flushSourceFileBatch(): void {
|
|
37
|
+
if (batchDepth === 0) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
batchDepth--;
|
|
41
|
+
if (batchDepth > 0) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
for (const [sourceFile, statements] of pendingByFile) {
|
|
46
|
+
if (statements.length === 0) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
sourceFile.addStatements(statements);
|
|
50
|
+
}
|
|
51
|
+
} finally {
|
|
52
|
+
pendingByFile.clear();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Queues a statement structure for bulk-add on flush, or writes it
|
|
58
|
+
* immediately when no batch is open.
|
|
59
|
+
* @param sourceFile - Target source file.
|
|
60
|
+
* @param structure - The statement structure to add.
|
|
61
|
+
*/
|
|
62
|
+
export function enqueueStatement(sourceFile: SourceFile, structure: StatementStructures): void {
|
|
63
|
+
if (batchDepth > 0) {
|
|
64
|
+
let pending = pendingByFile.get(sourceFile);
|
|
65
|
+
if (!pending) {
|
|
66
|
+
pending = [];
|
|
67
|
+
pendingByFile.set(sourceFile, pending);
|
|
68
|
+
}
|
|
69
|
+
pending.push(structure);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
sourceFile.addStatements([structure]);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Returns the set of names exported from `sourceFile` considering both the
|
|
77
|
+
* declarations already present in its AST and any export declarations queued
|
|
78
|
+
* by the current batch. Use this in place of reading `getExportDeclarations`
|
|
79
|
+
* directly when callers dedup against existing exports inside a batch.
|
|
80
|
+
* @param sourceFile - The file to inspect.
|
|
81
|
+
*/
|
|
82
|
+
export function getEffectiveExportedNames(sourceFile: SourceFile): Set<string> {
|
|
83
|
+
const names = new Set<string>();
|
|
84
|
+
for (const decl of sourceFile.getExportDeclarations()) {
|
|
85
|
+
for (const named of decl.getNamedExports()) {
|
|
86
|
+
names.add(named.getAliasNode()?.getText() ?? named.getName());
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const pending = pendingByFile.get(sourceFile);
|
|
90
|
+
if (pending) {
|
|
91
|
+
for (const structure of pending) {
|
|
92
|
+
if (structure.kind !== StructureKind.ExportDeclaration) {
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
collectNamedExportNames(structure.namedExports, names);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return names;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Returns the set of named exports queued in the current batch for
|
|
103
|
+
* `sourceFile`. Use this to union with any AST-based view of exports
|
|
104
|
+
* (e.g. `getExportedDeclarations`) when deduplicating against still-pending
|
|
105
|
+
* writes inside a batch.
|
|
106
|
+
* @param sourceFile - The file to inspect.
|
|
107
|
+
*/
|
|
108
|
+
export function getQueuedExportNames(sourceFile: SourceFile): Set<string> {
|
|
109
|
+
const names = new Set<string>();
|
|
110
|
+
const pending = pendingByFile.get(sourceFile);
|
|
111
|
+
if (!pending) {
|
|
112
|
+
return names;
|
|
113
|
+
}
|
|
114
|
+
for (const structure of pending) {
|
|
115
|
+
if (structure.kind !== StructureKind.ExportDeclaration) {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
collectNamedExportNames(structure.namedExports, names);
|
|
119
|
+
}
|
|
120
|
+
return names;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function collectNamedExportNames(
|
|
124
|
+
named: ExportDeclarationStructure["namedExports"],
|
|
125
|
+
into: Set<string>,
|
|
126
|
+
): void {
|
|
127
|
+
if (!named || typeof named === "function") {
|
|
128
|
+
// WriterFunction form is opaque to us; callers can't dedup by name.
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
for (const item of named) {
|
|
132
|
+
if (typeof item === "string") {
|
|
133
|
+
into.add(item);
|
|
134
|
+
} else if (typeof item === "function") {
|
|
135
|
+
continue;
|
|
136
|
+
} else if (item) {
|
|
137
|
+
into.add(item.alias ?? item.name);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import { SdkClientType, SdkServiceOperation } from "@azure-tools/typespec-client-generator-core";
|
|
2
2
|
import { joinPaths, NoTarget } from "@typespec/compiler";
|
|
3
|
-
import { Project, SourceFile } from "ts-morph";
|
|
3
|
+
import { Project, SourceFile, StructureKind } from "ts-morph";
|
|
4
4
|
import { useContext } from "../context-manager.js";
|
|
5
5
|
import { resolveReference } from "../framework/reference.js";
|
|
6
|
+
import {
|
|
7
|
+
beginSourceFileBatch,
|
|
8
|
+
enqueueStatement,
|
|
9
|
+
flushSourceFileBatch,
|
|
10
|
+
getEffectiveExportedNames,
|
|
11
|
+
getQueuedExportNames,
|
|
12
|
+
} from "../framework/source-file-batch.js";
|
|
6
13
|
import { reportDiagnostic } from "../lib.js";
|
|
7
14
|
import { getClientModuleInfo } from "../utils/client-utils.js";
|
|
8
15
|
import { SdkContext } from "../utils/interfaces.js";
|
|
@@ -24,6 +31,20 @@ export function buildRootIndex(
|
|
|
24
31
|
emitterOptions: ModularEmitterOptions,
|
|
25
32
|
rootIndexFile: SourceFile,
|
|
26
33
|
clientMap?: [string[], SdkClientType<SdkServiceOperation>],
|
|
34
|
+
) {
|
|
35
|
+
beginSourceFileBatch();
|
|
36
|
+
try {
|
|
37
|
+
buildRootIndexImpl(context, emitterOptions, rootIndexFile, clientMap);
|
|
38
|
+
} finally {
|
|
39
|
+
flushSourceFileBatch();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function buildRootIndexImpl(
|
|
44
|
+
context: SdkContext,
|
|
45
|
+
emitterOptions: ModularEmitterOptions,
|
|
46
|
+
rootIndexFile: SourceFile,
|
|
47
|
+
clientMap?: [string[], SdkClientType<SdkServiceOperation>],
|
|
27
48
|
) {
|
|
28
49
|
if (!clientMap) {
|
|
29
50
|
// we still need to export the models if no client is provided
|
|
@@ -109,7 +130,8 @@ function exportRestErrorTypes(rootIndexFile: SourceFile) {
|
|
|
109
130
|
const existingExports = getExistingExports(rootIndexFile);
|
|
110
131
|
const namedExports = ["RestError", "isRestError"].filter((name) => !existingExports.has(name));
|
|
111
132
|
if (namedExports.length > 0) {
|
|
112
|
-
rootIndexFile
|
|
133
|
+
enqueueStatement(rootIndexFile, {
|
|
134
|
+
kind: StructureKind.ExportDeclaration,
|
|
113
135
|
moduleSpecifier: "@azure/core-rest-pipeline",
|
|
114
136
|
namedExports,
|
|
115
137
|
});
|
|
@@ -165,13 +187,7 @@ function exportFileContentsType(context: SdkContext, rootIndexFile: SourceFile)
|
|
|
165
187
|
}
|
|
166
188
|
|
|
167
189
|
function getExistingExports(rootIndexFile: SourceFile): Set<string> {
|
|
168
|
-
return
|
|
169
|
-
rootIndexFile
|
|
170
|
-
.getExportDeclarations()
|
|
171
|
-
.flatMap((exportDecl) =>
|
|
172
|
-
exportDecl.getNamedExports().map((namedExport) => namedExport.getName()),
|
|
173
|
-
),
|
|
174
|
-
);
|
|
190
|
+
return getEffectiveExportedNames(rootIndexFile);
|
|
175
191
|
}
|
|
176
192
|
|
|
177
193
|
function getNewNamedExports(namedExports: string[], existingExports: Set<string>): string[] {
|
|
@@ -186,7 +202,8 @@ function addExportsToRootIndexFile(
|
|
|
186
202
|
const existingExports = getExistingExports(rootIndexFile);
|
|
187
203
|
const newNamedExports = getNewNamedExports(namedExports, existingExports);
|
|
188
204
|
if (newNamedExports.length > 0) {
|
|
189
|
-
rootIndexFile
|
|
205
|
+
enqueueStatement(rootIndexFile, {
|
|
206
|
+
kind: StructureKind.ExportDeclaration,
|
|
190
207
|
isTypeOnly,
|
|
191
208
|
namedExports: newNamedExports,
|
|
192
209
|
});
|
|
@@ -222,7 +239,8 @@ function exportSimplePollerLike(
|
|
|
222
239
|
const moduleSpecifier = `./${
|
|
223
240
|
isTopLevel && subfolder && subfolder !== "" ? subfolder + "/" : ""
|
|
224
241
|
}static-helpers/simplePollerHelpers.js`;
|
|
225
|
-
indexFile
|
|
242
|
+
enqueueStatement(indexFile, {
|
|
243
|
+
kind: StructureKind.ExportDeclaration,
|
|
226
244
|
isTypeOnly: true,
|
|
227
245
|
moduleSpecifier,
|
|
228
246
|
namedExports: ["SimplePollerLike"],
|
|
@@ -243,7 +261,10 @@ function exportRestoreHelpers(
|
|
|
243
261
|
if (!helperFile) {
|
|
244
262
|
return;
|
|
245
263
|
}
|
|
246
|
-
const exported = new Set(
|
|
264
|
+
const exported = new Set([
|
|
265
|
+
...indexFile.getExportedDeclarations().keys(),
|
|
266
|
+
...getQueuedExportNames(indexFile),
|
|
267
|
+
]);
|
|
247
268
|
const allEntries = [...helperFile.getExportedDeclarations().entries()];
|
|
248
269
|
const moduleSpecifier = `./${
|
|
249
270
|
isTopLevel && subfolder && subfolder !== "" ? subfolder + "/" : ""
|
|
@@ -259,7 +280,8 @@ function exportClassicalClient(
|
|
|
259
280
|
isSubClient: boolean = false,
|
|
260
281
|
) {
|
|
261
282
|
const clientName = client.name;
|
|
262
|
-
indexFile
|
|
283
|
+
enqueueStatement(indexFile, {
|
|
284
|
+
kind: StructureKind.ExportDeclaration,
|
|
263
285
|
namedExports: [clientName],
|
|
264
286
|
moduleSpecifier: `./${
|
|
265
287
|
subfolder && subfolder !== "" && !isSubClient ? subfolder + "/" : ""
|
|
@@ -321,7 +343,10 @@ function exportModules(
|
|
|
321
343
|
continue;
|
|
322
344
|
}
|
|
323
345
|
|
|
324
|
-
const exported = new Set(
|
|
346
|
+
const exported = new Set([
|
|
347
|
+
...indexFile.getExportedDeclarations().keys(),
|
|
348
|
+
...getQueuedExportNames(indexFile),
|
|
349
|
+
]);
|
|
325
350
|
const serializerOrDeserializerRegex = /.*(Serializer|Deserializer)(_\d+)?$/;
|
|
326
351
|
const filteredEntries = [...modelsFile.getExportedDeclarations().entries()].filter(
|
|
327
352
|
(exDeclaration) => {
|
|
@@ -362,6 +387,19 @@ export function buildSubClientIndexFile(
|
|
|
362
387
|
context: SdkContext,
|
|
363
388
|
clientMap: [string[], SdkClientType<SdkServiceOperation>],
|
|
364
389
|
emitterOptions: ModularEmitterOptions,
|
|
390
|
+
) {
|
|
391
|
+
beginSourceFileBatch();
|
|
392
|
+
try {
|
|
393
|
+
buildSubClientIndexFileImpl(context, clientMap, emitterOptions);
|
|
394
|
+
} finally {
|
|
395
|
+
flushSourceFileBatch();
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
function buildSubClientIndexFileImpl(
|
|
400
|
+
context: SdkContext,
|
|
401
|
+
clientMap: [string[], SdkClientType<SdkServiceOperation>],
|
|
402
|
+
emitterOptions: ModularEmitterOptions,
|
|
365
403
|
) {
|
|
366
404
|
const project = useContext("outputProject");
|
|
367
405
|
const [_, client] = clientMap;
|
|
@@ -2,8 +2,13 @@ import { SdkClientType, SdkServiceOperation } from "@azure-tools/typespec-client
|
|
|
2
2
|
import { joinPaths } from "@typespec/compiler";
|
|
3
3
|
import { ModularEmitterOptions } from "./interfaces.js";
|
|
4
4
|
|
|
5
|
-
import { Node, SourceFile } from "ts-morph";
|
|
5
|
+
import { Node, SourceFile, StructureKind } from "ts-morph";
|
|
6
6
|
import { useContext } from "../context-manager.js";
|
|
7
|
+
import {
|
|
8
|
+
beginSourceFileBatch,
|
|
9
|
+
enqueueStatement,
|
|
10
|
+
flushSourceFileBatch,
|
|
11
|
+
} from "../framework/source-file-batch.js";
|
|
7
12
|
import { getClientModuleInfo } from "../utils/client-utils.js";
|
|
8
13
|
|
|
9
14
|
export interface buildSubpathIndexFileOptions {
|
|
@@ -17,6 +22,20 @@ export function buildSubpathIndexFile(
|
|
|
17
22
|
subpath: string,
|
|
18
23
|
clientMap?: [string[], SdkClientType<SdkServiceOperation>],
|
|
19
24
|
options: buildSubpathIndexFileOptions = {},
|
|
25
|
+
) {
|
|
26
|
+
beginSourceFileBatch();
|
|
27
|
+
try {
|
|
28
|
+
buildSubpathIndexFileImpl(emitterOptions, subpath, clientMap, options);
|
|
29
|
+
} finally {
|
|
30
|
+
flushSourceFileBatch();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function buildSubpathIndexFileImpl(
|
|
35
|
+
emitterOptions: ModularEmitterOptions,
|
|
36
|
+
subpath: string,
|
|
37
|
+
clientMap?: [string[], SdkClientType<SdkServiceOperation>],
|
|
38
|
+
options: buildSubpathIndexFileOptions = {},
|
|
20
39
|
) {
|
|
21
40
|
const project = useContext("outputProject");
|
|
22
41
|
const subfolder = clientMap ? (getClientModuleInfo(clientMap).subfolder ?? "") : "";
|
|
@@ -137,14 +156,16 @@ export function partitionAndEmitExports(
|
|
|
137
156
|
}
|
|
138
157
|
}
|
|
139
158
|
if (typeOnlyExports.length > 0) {
|
|
140
|
-
indexFile
|
|
159
|
+
enqueueStatement(indexFile, {
|
|
160
|
+
kind: StructureKind.ExportDeclaration,
|
|
141
161
|
isTypeOnly: true,
|
|
142
162
|
moduleSpecifier,
|
|
143
163
|
namedExports: typeOnlyExports,
|
|
144
164
|
});
|
|
145
165
|
}
|
|
146
166
|
if (valueExports.length > 0) {
|
|
147
|
-
indexFile
|
|
167
|
+
enqueueStatement(indexFile, {
|
|
168
|
+
kind: StructureKind.ExportDeclaration,
|
|
148
169
|
moduleSpecifier,
|
|
149
170
|
namedExports: valueExports,
|
|
150
171
|
});
|
|
@@ -46,6 +46,7 @@ import {
|
|
|
46
46
|
pagedModelsKeptPublic,
|
|
47
47
|
} from "../framework/hooks/sdk-types.js";
|
|
48
48
|
import { refkey } from "../framework/refkey.js";
|
|
49
|
+
import { beginSourceFileBatch, flushSourceFileBatch } from "../framework/source-file-batch.js";
|
|
49
50
|
import { reportDiagnostic } from "../lib.js";
|
|
50
51
|
import { getClientHierarchyMap } from "../utils/client-utils.js";
|
|
51
52
|
import { SdkContext } from "../utils/interfaces.js";
|
|
@@ -117,32 +118,37 @@ export function emitTypes(context: SdkContext, { sourceRoot }: { sourceRoot: str
|
|
|
117
118
|
|
|
118
119
|
let sourceFile;
|
|
119
120
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
beginSourceFileBatch();
|
|
122
|
+
try {
|
|
123
|
+
for (const type of emitQueue) {
|
|
124
|
+
if (!isGenerableType(type)) {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
124
127
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
128
|
+
const namespaces = getModelNamespaces(context, type);
|
|
129
|
+
const filepath = getModelsPath(sourceRoot, namespaces);
|
|
130
|
+
sourceFile = outputProject.getSourceFile(filepath);
|
|
131
|
+
if (!sourceFile) {
|
|
132
|
+
sourceFile = outputProject.createSourceFile(filepath);
|
|
133
|
+
sourceFile.addStatements(`/*
|
|
131
134
|
* This file contains only generated model types and their (de)serializers.
|
|
132
135
|
* Disable the following rules for internal models with '_' prefix and deserializers which require 'any' for raw JSON input.
|
|
133
136
|
*/
|
|
134
137
|
/* eslint-disable @typescript-eslint/naming-convention */
|
|
135
138
|
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */`);
|
|
139
|
+
}
|
|
140
|
+
emitType(context, type, sourceFile);
|
|
136
141
|
}
|
|
137
|
-
emitType(context, type, sourceFile);
|
|
138
|
-
}
|
|
139
142
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
143
|
+
// Emit serialization/deserialization functions for flattened properties
|
|
144
|
+
for (const [property, _] of flattenPropertyModelMap) {
|
|
145
|
+
const namespaces = getModelNamespaces(context, property.type);
|
|
146
|
+
const filepath = getModelsPath(sourceRoot, namespaces);
|
|
147
|
+
sourceFile = outputProject.getSourceFile(filepath);
|
|
148
|
+
addSerializationFunctions(context, property, sourceFile!);
|
|
149
|
+
}
|
|
150
|
+
} finally {
|
|
151
|
+
flushSourceFileBatch();
|
|
146
152
|
}
|
|
147
153
|
|
|
148
154
|
const modelFiles = outputProject.getSourceFiles(sourceRoot + "/models/**/*.ts");
|