@aws/nx-plugin 0.78.0 → 0.79.1
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/package.json +27 -27
- package/src/infra/app/__snapshots__/generator.spec.ts.snap +32 -8
- package/src/open-api/ts-client/__snapshots__/generator.streaming.spec.ts.snap +401 -0
- package/src/open-api/ts-client/files/client.gen.ts.template +27 -4
- package/src/open-api/utils/codegen-data/types.d.ts +4 -0
- package/src/open-api/utils/codegen-data/types.js +8 -1
- package/src/open-api/utils/codegen-data/types.js.map +1 -1
- package/src/open-api/utils/codegen-data.js +21 -1
- package/src/open-api/utils/codegen-data.js.map +1 -1
- package/src/preset/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/py/fast-api/__snapshots__/generator.spec.ts.snap +26 -17
- package/src/py/fast-api/files/app/__name__/init.py.template +23 -17
- package/src/py/fast-api/files/app/__name__/main.py.template +2 -0
- package/src/py/fast-api/files/app/tests/test_main.py +1 -0
- package/src/py/project/generator.js +9 -17
- package/src/py/project/generator.js.map +1 -1
- package/src/py/strands-agent/__snapshots__/generator.spec.ts.snap +16 -9
- package/src/py/strands-agent/files/app/agentcore_mcp_client.py.template +4 -12
- package/src/py/strands-agent/files/app/init.py.template +51 -1
- package/src/py/strands-agent/files/app/main.py.template +16 -9
- package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +11 -1
- package/src/ts/lib/__snapshots__/generator.spec.ts.snap +42 -14
- package/src/ts/lib/eslint.js +15 -13
- package/src/ts/lib/eslint.js.map +1 -1
- package/src/ts/lib/generator.js +0 -17
- package/src/ts/lib/generator.js.map +1 -1
- package/src/ts/lib/vitest.js +6 -2
- package/src/ts/lib/vitest.js.map +1 -1
- package/src/ts/nx-plugin/__snapshots__/generator.spec.ts.snap +1 -1
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +82 -58
- package/src/utils/versions.d.ts +4 -4
- package/src/utils/versions.js +3 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aws/nx-plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.79.1",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/awslabs/nx-plugin-for-aws.git",
|
|
@@ -19,36 +19,36 @@
|
|
|
19
19
|
},
|
|
20
20
|
"generators": "./generators.json",
|
|
21
21
|
"peerDependencies": {
|
|
22
|
-
"nx": "
|
|
23
|
-
"prettier": "
|
|
22
|
+
"nx": "22.5.3",
|
|
23
|
+
"prettier": "3.8.1"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@apidevtools/swagger-parser": "
|
|
26
|
+
"@apidevtools/swagger-parser": "10.1.1",
|
|
27
27
|
"@hey-api/openapi-ts": "0.64.13",
|
|
28
|
-
"@iarna/toml": "
|
|
29
|
-
"@modelcontextprotocol/sdk": "
|
|
30
|
-
"@nx/devkit": "
|
|
31
|
-
"@nx/eslint": "
|
|
32
|
-
"@nx/js": "
|
|
33
|
-
"@nx/react": "
|
|
34
|
-
"@nx/vite": "
|
|
35
|
-
"@nxlv/python": "
|
|
28
|
+
"@iarna/toml": "2.2.5",
|
|
29
|
+
"@modelcontextprotocol/sdk": "1.27.0",
|
|
30
|
+
"@nx/devkit": "22.5.3",
|
|
31
|
+
"@nx/eslint": "22.5.3",
|
|
32
|
+
"@nx/js": "22.5.3",
|
|
33
|
+
"@nx/react": "22.5.3",
|
|
34
|
+
"@nx/vite": "22.5.3",
|
|
35
|
+
"@nxlv/python": "22.1.0",
|
|
36
36
|
"@phenomnomnominal/tsquery": "6.1.4",
|
|
37
|
-
"enquirer": "
|
|
38
|
-
"fast-glob": "
|
|
39
|
-
"lodash.camelcase": "
|
|
40
|
-
"lodash.clonedeepwith": "
|
|
41
|
-
"lodash.deburr": "
|
|
42
|
-
"lodash.orderby": "
|
|
43
|
-
"lodash.trim": "
|
|
44
|
-
"lodash.uniqby": "
|
|
45
|
-
"minimatch": "
|
|
46
|
-
"openapi-types": "
|
|
47
|
-
"pip-requirements-js": "
|
|
48
|
-
"typescript": "
|
|
49
|
-
"vite": "
|
|
50
|
-
"vitest": "
|
|
51
|
-
"zod": "
|
|
37
|
+
"enquirer": "2.4.1",
|
|
38
|
+
"fast-glob": "3.3.3",
|
|
39
|
+
"lodash.camelcase": "4.3.0",
|
|
40
|
+
"lodash.clonedeepwith": "4.5.0",
|
|
41
|
+
"lodash.deburr": "4.1.0",
|
|
42
|
+
"lodash.orderby": "4.6.0",
|
|
43
|
+
"lodash.trim": "4.5.1",
|
|
44
|
+
"lodash.uniqby": "4.7.0",
|
|
45
|
+
"minimatch": "10.2.3",
|
|
46
|
+
"openapi-types": "12.1.3",
|
|
47
|
+
"pip-requirements-js": "0.2.1",
|
|
48
|
+
"typescript": "5.9.3",
|
|
49
|
+
"vite": "7.3.1",
|
|
50
|
+
"vitest": "4.0.18",
|
|
51
|
+
"zod": "4.3.6"
|
|
52
52
|
},
|
|
53
53
|
"types": "./src/index.d.ts"
|
|
54
54
|
}
|
|
@@ -13,10 +13,10 @@ exports[`infra generator > should add required dependencies to package.json > de
|
|
|
13
13
|
exports[`infra generator > should add required dependencies to package.json > dev-dependencies 1`] = `
|
|
14
14
|
{
|
|
15
15
|
"@eslint/js": "^9.8.0",
|
|
16
|
-
"@nx/eslint": "22.5.
|
|
17
|
-
"@nx/eslint-plugin": "22.5.
|
|
18
|
-
"@nx/js": "22.5.
|
|
19
|
-
"@nx/vitest": "22.5.
|
|
16
|
+
"@nx/eslint": "22.5.3",
|
|
17
|
+
"@nx/eslint-plugin": "22.5.3",
|
|
18
|
+
"@nx/js": "22.5.3",
|
|
19
|
+
"@nx/vitest": "22.5.3",
|
|
20
20
|
"@swc-node/register": "~1.11.1",
|
|
21
21
|
"@swc/core": "~1.15.5",
|
|
22
22
|
"@swc/helpers": "~0.5.18",
|
|
@@ -47,10 +47,10 @@ exports[`infra generator > should add required dependencies to package.json > pa
|
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@eslint/js": "^9.8.0",
|
|
50
|
-
"@nx/eslint": "22.5.
|
|
51
|
-
"@nx/eslint-plugin": "22.5.
|
|
52
|
-
"@nx/js": "22.5.
|
|
53
|
-
"@nx/vitest": "22.5.
|
|
50
|
+
"@nx/eslint": "22.5.3",
|
|
51
|
+
"@nx/eslint-plugin": "22.5.3",
|
|
52
|
+
"@nx/js": "22.5.3",
|
|
53
|
+
"@nx/vitest": "22.5.3",
|
|
54
54
|
"@swc-node/register": "~1.11.1",
|
|
55
55
|
"@swc/core": "~1.15.5",
|
|
56
56
|
"@swc/helpers": "~0.5.18",
|
|
@@ -230,7 +230,19 @@ exports[`infra generator > should configure project.json with correct targets >
|
|
|
230
230
|
},
|
|
231
231
|
},
|
|
232
232
|
"lint": {
|
|
233
|
+
"cache": true,
|
|
234
|
+
"configurations": {
|
|
235
|
+
"fix": {
|
|
236
|
+
"fix": true,
|
|
237
|
+
},
|
|
238
|
+
"skip-lint": {
|
|
239
|
+
"force": true,
|
|
240
|
+
},
|
|
241
|
+
},
|
|
233
242
|
"executor": "@nx/eslint:lint",
|
|
243
|
+
"inputs": [
|
|
244
|
+
"eslint",
|
|
245
|
+
],
|
|
234
246
|
},
|
|
235
247
|
"synth": {
|
|
236
248
|
"cache": true,
|
|
@@ -780,7 +792,19 @@ exports[`infra generator > should handle custom project names correctly > custom
|
|
|
780
792
|
},
|
|
781
793
|
},
|
|
782
794
|
"lint": {
|
|
795
|
+
"cache": true,
|
|
796
|
+
"configurations": {
|
|
797
|
+
"fix": {
|
|
798
|
+
"fix": true,
|
|
799
|
+
},
|
|
800
|
+
"skip-lint": {
|
|
801
|
+
"force": true,
|
|
802
|
+
},
|
|
803
|
+
},
|
|
783
804
|
"executor": "@nx/eslint:lint",
|
|
805
|
+
"inputs": [
|
|
806
|
+
"eslint",
|
|
807
|
+
],
|
|
784
808
|
},
|
|
785
809
|
"synth": {
|
|
786
810
|
"cache": true,
|
|
@@ -1,5 +1,406 @@
|
|
|
1
1
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
|
+
exports[`openApiTsClientGenerator - streaming > OpenAPI 3.2 JSONL streaming (application/jsonl with itemSchema) > should detect and handle application/jsonl with itemSchema 1`] = `
|
|
4
|
+
"export type StreamChunk = {
|
|
5
|
+
content: string;
|
|
6
|
+
};
|
|
7
|
+
export type StreamDataRequestContent = {
|
|
8
|
+
prompt: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type StreamDataRequest = StreamDataRequestContent | undefined;
|
|
12
|
+
export type StreamDataError = never;
|
|
13
|
+
"
|
|
14
|
+
`;
|
|
15
|
+
|
|
16
|
+
exports[`openApiTsClientGenerator - streaming > OpenAPI 3.2 JSONL streaming (application/jsonl with itemSchema) > should detect and handle application/jsonl with itemSchema 2`] = `
|
|
17
|
+
"import type {
|
|
18
|
+
StreamChunk,
|
|
19
|
+
StreamDataRequestContent,
|
|
20
|
+
StreamDataRequest,
|
|
21
|
+
} from './types.gen.js';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Utility for serialisation and deserialisation of API types.
|
|
25
|
+
*/
|
|
26
|
+
export class $IO {
|
|
27
|
+
protected static $mapValues = (data: any, fn: (item: any) => any) =>
|
|
28
|
+
Object.fromEntries(Object.entries(data).map(([k, v]) => [k, fn(v)]));
|
|
29
|
+
|
|
30
|
+
public static StreamChunk = {
|
|
31
|
+
toJson: (model: StreamChunk): any => {
|
|
32
|
+
if (model === undefined || model === null) {
|
|
33
|
+
return model;
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
...(model.content === undefined
|
|
37
|
+
? {}
|
|
38
|
+
: {
|
|
39
|
+
content: model.content,
|
|
40
|
+
}),
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
fromJson: (json: any): StreamChunk => {
|
|
44
|
+
if (json === undefined || json === null) {
|
|
45
|
+
return json;
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
content: json['content'],
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
public static StreamDataRequestContent = {
|
|
54
|
+
toJson: (model: StreamDataRequestContent): any => {
|
|
55
|
+
if (model === undefined || model === null) {
|
|
56
|
+
return model;
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
...(model.prompt === undefined
|
|
60
|
+
? {}
|
|
61
|
+
: {
|
|
62
|
+
prompt: model.prompt,
|
|
63
|
+
}),
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
fromJson: (json: any): StreamDataRequestContent => {
|
|
67
|
+
if (json === undefined || json === null) {
|
|
68
|
+
return json;
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
prompt: json['prompt'],
|
|
72
|
+
};
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Client configuration for TestApi
|
|
79
|
+
*/
|
|
80
|
+
export interface TestApiConfig {
|
|
81
|
+
/**
|
|
82
|
+
* Base URL for the API
|
|
83
|
+
*/
|
|
84
|
+
url: string;
|
|
85
|
+
/**
|
|
86
|
+
* Custom instance of fetch. By default the global 'fetch' is used.
|
|
87
|
+
* You can override this to add custom middleware for use cases such as adding authentication headers.
|
|
88
|
+
*/
|
|
89
|
+
fetch?: typeof fetch;
|
|
90
|
+
/**
|
|
91
|
+
* Additional configuration
|
|
92
|
+
*/
|
|
93
|
+
options?: {
|
|
94
|
+
/**
|
|
95
|
+
* By default, the client will add a Content-Type header, set to the media type defined for
|
|
96
|
+
* the request in the OpenAPI specification.
|
|
97
|
+
* Set this to false to omit this header.
|
|
98
|
+
*/
|
|
99
|
+
omitContentTypeHeader?: boolean;
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* API Client for TestApi
|
|
105
|
+
*/
|
|
106
|
+
export class TestApi {
|
|
107
|
+
private $config: TestApiConfig;
|
|
108
|
+
|
|
109
|
+
constructor(config: TestApiConfig) {
|
|
110
|
+
this.$config = config;
|
|
111
|
+
|
|
112
|
+
this.streamData = this.streamData.bind(this);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
private $url = (
|
|
116
|
+
path: string,
|
|
117
|
+
pathParameters: { [key: string]: any },
|
|
118
|
+
queryParameters: { [key: string]: any },
|
|
119
|
+
collectionFormats?: { [key: string]: 'multi' | 'csv' },
|
|
120
|
+
): string => {
|
|
121
|
+
const baseUrl = this.$config.url.endsWith('/')
|
|
122
|
+
? this.$config.url.slice(0, -1)
|
|
123
|
+
: this.$config.url;
|
|
124
|
+
const pathWithParameters = Object.entries(pathParameters).reduce(
|
|
125
|
+
(withParams, [key, value]) =>
|
|
126
|
+
withParams.replace(\`{\${key}}\`, encodeURIComponent(\`\${value}\`)),
|
|
127
|
+
path,
|
|
128
|
+
);
|
|
129
|
+
const queryString = Object.entries(queryParameters)
|
|
130
|
+
.map(([key, value]) => {
|
|
131
|
+
if (Array.isArray(value) && collectionFormats?.[key] === 'multi') {
|
|
132
|
+
return value
|
|
133
|
+
.map(
|
|
134
|
+
(v) => \`\${encodeURIComponent(key)}=\${encodeURIComponent(\`\${v}\`)}\`,
|
|
135
|
+
)
|
|
136
|
+
.join('&');
|
|
137
|
+
}
|
|
138
|
+
return \`\${encodeURIComponent(key)}=\${encodeURIComponent(Array.isArray(value) ? value.map(String).join(',') : String(value))}\`;
|
|
139
|
+
})
|
|
140
|
+
.join('&');
|
|
141
|
+
return (
|
|
142
|
+
baseUrl + pathWithParameters + (queryString ? \`?\${queryString}\` : '')
|
|
143
|
+
);
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
private $headers = (
|
|
147
|
+
headerParameters: { [key: string]: any },
|
|
148
|
+
collectionFormats?: { [key: string]: 'multi' | 'csv' },
|
|
149
|
+
): [string, string][] => {
|
|
150
|
+
return Object.entries(headerParameters).flatMap(([key, value]) => {
|
|
151
|
+
if (Array.isArray(value) && collectionFormats?.[key] === 'multi') {
|
|
152
|
+
return value.map((v) => [key, String(v)]) as [string, string][];
|
|
153
|
+
}
|
|
154
|
+
return [[key, String(value)]];
|
|
155
|
+
});
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
private $fetch: typeof fetch = (...args) =>
|
|
159
|
+
(this.$config.fetch ?? fetch)(...args);
|
|
160
|
+
|
|
161
|
+
public async *streamData(
|
|
162
|
+
input?: StreamDataRequest,
|
|
163
|
+
): AsyncIterableIterator<StreamChunk> {
|
|
164
|
+
const pathParameters: { [key: string]: any } = {};
|
|
165
|
+
const queryParameters: { [key: string]: any } = {};
|
|
166
|
+
const headerParameters: { [key: string]: any } = {};
|
|
167
|
+
if (!this.$config.options?.omitContentTypeHeader) {
|
|
168
|
+
headerParameters['Content-Type'] = 'application/json';
|
|
169
|
+
}
|
|
170
|
+
const body =
|
|
171
|
+
input === undefined
|
|
172
|
+
? undefined
|
|
173
|
+
: typeof input === 'object'
|
|
174
|
+
? JSON.stringify($IO.StreamDataRequestContent.toJson(input))
|
|
175
|
+
: String($IO.StreamDataRequestContent.toJson(input));
|
|
176
|
+
|
|
177
|
+
const response = await this.$fetch(
|
|
178
|
+
this.$url('/stream', pathParameters, queryParameters),
|
|
179
|
+
{
|
|
180
|
+
headers: this.$headers(headerParameters),
|
|
181
|
+
method: 'POST',
|
|
182
|
+
body,
|
|
183
|
+
},
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
if (response.status === 200) {
|
|
187
|
+
const reader = response.body
|
|
188
|
+
?.pipeThrough(new TextDecoderStream())
|
|
189
|
+
.getReader();
|
|
190
|
+
let buffer = '';
|
|
191
|
+
while (reader) {
|
|
192
|
+
const { value: chunk, done } = await reader.read();
|
|
193
|
+
if (done) {
|
|
194
|
+
if (buffer.trim()) {
|
|
195
|
+
yield $IO.StreamChunk.fromJson(JSON.parse(buffer));
|
|
196
|
+
}
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
if (chunk) {
|
|
200
|
+
buffer += chunk;
|
|
201
|
+
}
|
|
202
|
+
const lines = buffer.split('\\n');
|
|
203
|
+
buffer = lines.pop() ?? '';
|
|
204
|
+
for (const line of lines) {
|
|
205
|
+
if (line.trim()) {
|
|
206
|
+
yield $IO.StreamChunk.fromJson(JSON.parse(line));
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
throw new Error(
|
|
213
|
+
\`Unknown response status \${response.status} returned by API\`,
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
"
|
|
218
|
+
`;
|
|
219
|
+
|
|
220
|
+
exports[`openApiTsClientGenerator - streaming > OpenAPI 3.2 JSONL streaming (application/jsonl with itemSchema) > should handle application/x-ndjson with itemSchema 1`] = `
|
|
221
|
+
"import type { Event } from './types.gen.js';
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Utility for serialisation and deserialisation of API types.
|
|
225
|
+
*/
|
|
226
|
+
export class $IO {
|
|
227
|
+
protected static $mapValues = (data: any, fn: (item: any) => any) =>
|
|
228
|
+
Object.fromEntries(Object.entries(data).map(([k, v]) => [k, fn(v)]));
|
|
229
|
+
|
|
230
|
+
public static Event = {
|
|
231
|
+
toJson: (model: Event): any => {
|
|
232
|
+
if (model === undefined || model === null) {
|
|
233
|
+
return model;
|
|
234
|
+
}
|
|
235
|
+
return {
|
|
236
|
+
...(model.id === undefined
|
|
237
|
+
? {}
|
|
238
|
+
: {
|
|
239
|
+
id: model.id,
|
|
240
|
+
}),
|
|
241
|
+
...(model.type === undefined
|
|
242
|
+
? {}
|
|
243
|
+
: {
|
|
244
|
+
type: model.type,
|
|
245
|
+
}),
|
|
246
|
+
...(model.data === undefined
|
|
247
|
+
? {}
|
|
248
|
+
: {
|
|
249
|
+
data: model.data,
|
|
250
|
+
}),
|
|
251
|
+
};
|
|
252
|
+
},
|
|
253
|
+
fromJson: (json: any): Event => {
|
|
254
|
+
if (json === undefined || json === null) {
|
|
255
|
+
return json;
|
|
256
|
+
}
|
|
257
|
+
return {
|
|
258
|
+
id: json['id'],
|
|
259
|
+
type: json['type'],
|
|
260
|
+
...(json['data'] === undefined
|
|
261
|
+
? {}
|
|
262
|
+
: {
|
|
263
|
+
data: json['data'],
|
|
264
|
+
}),
|
|
265
|
+
};
|
|
266
|
+
},
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Client configuration for TestApi
|
|
272
|
+
*/
|
|
273
|
+
export interface TestApiConfig {
|
|
274
|
+
/**
|
|
275
|
+
* Base URL for the API
|
|
276
|
+
*/
|
|
277
|
+
url: string;
|
|
278
|
+
/**
|
|
279
|
+
* Custom instance of fetch. By default the global 'fetch' is used.
|
|
280
|
+
* You can override this to add custom middleware for use cases such as adding authentication headers.
|
|
281
|
+
*/
|
|
282
|
+
fetch?: typeof fetch;
|
|
283
|
+
/**
|
|
284
|
+
* Additional configuration
|
|
285
|
+
*/
|
|
286
|
+
options?: {
|
|
287
|
+
/**
|
|
288
|
+
* By default, the client will add a Content-Type header, set to the media type defined for
|
|
289
|
+
* the request in the OpenAPI specification.
|
|
290
|
+
* Set this to false to omit this header.
|
|
291
|
+
*/
|
|
292
|
+
omitContentTypeHeader?: boolean;
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* API Client for TestApi
|
|
298
|
+
*/
|
|
299
|
+
export class TestApi {
|
|
300
|
+
private $config: TestApiConfig;
|
|
301
|
+
|
|
302
|
+
constructor(config: TestApiConfig) {
|
|
303
|
+
this.$config = config;
|
|
304
|
+
|
|
305
|
+
this.getEvents = this.getEvents.bind(this);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
private $url = (
|
|
309
|
+
path: string,
|
|
310
|
+
pathParameters: { [key: string]: any },
|
|
311
|
+
queryParameters: { [key: string]: any },
|
|
312
|
+
collectionFormats?: { [key: string]: 'multi' | 'csv' },
|
|
313
|
+
): string => {
|
|
314
|
+
const baseUrl = this.$config.url.endsWith('/')
|
|
315
|
+
? this.$config.url.slice(0, -1)
|
|
316
|
+
: this.$config.url;
|
|
317
|
+
const pathWithParameters = Object.entries(pathParameters).reduce(
|
|
318
|
+
(withParams, [key, value]) =>
|
|
319
|
+
withParams.replace(\`{\${key}}\`, encodeURIComponent(\`\${value}\`)),
|
|
320
|
+
path,
|
|
321
|
+
);
|
|
322
|
+
const queryString = Object.entries(queryParameters)
|
|
323
|
+
.map(([key, value]) => {
|
|
324
|
+
if (Array.isArray(value) && collectionFormats?.[key] === 'multi') {
|
|
325
|
+
return value
|
|
326
|
+
.map(
|
|
327
|
+
(v) => \`\${encodeURIComponent(key)}=\${encodeURIComponent(\`\${v}\`)}\`,
|
|
328
|
+
)
|
|
329
|
+
.join('&');
|
|
330
|
+
}
|
|
331
|
+
return \`\${encodeURIComponent(key)}=\${encodeURIComponent(Array.isArray(value) ? value.map(String).join(',') : String(value))}\`;
|
|
332
|
+
})
|
|
333
|
+
.join('&');
|
|
334
|
+
return (
|
|
335
|
+
baseUrl + pathWithParameters + (queryString ? \`?\${queryString}\` : '')
|
|
336
|
+
);
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
private $headers = (
|
|
340
|
+
headerParameters: { [key: string]: any },
|
|
341
|
+
collectionFormats?: { [key: string]: 'multi' | 'csv' },
|
|
342
|
+
): [string, string][] => {
|
|
343
|
+
return Object.entries(headerParameters).flatMap(([key, value]) => {
|
|
344
|
+
if (Array.isArray(value) && collectionFormats?.[key] === 'multi') {
|
|
345
|
+
return value.map((v) => [key, String(v)]) as [string, string][];
|
|
346
|
+
}
|
|
347
|
+
return [[key, String(value)]];
|
|
348
|
+
});
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
private $fetch: typeof fetch = (...args) =>
|
|
352
|
+
(this.$config.fetch ?? fetch)(...args);
|
|
353
|
+
|
|
354
|
+
public async *getEvents(): AsyncIterableIterator<Event> {
|
|
355
|
+
const pathParameters: { [key: string]: any } = {};
|
|
356
|
+
const queryParameters: { [key: string]: any } = {};
|
|
357
|
+
const headerParameters: { [key: string]: any } = {};
|
|
358
|
+
|
|
359
|
+
const body = undefined;
|
|
360
|
+
|
|
361
|
+
const response = await this.$fetch(
|
|
362
|
+
this.$url('/events', pathParameters, queryParameters),
|
|
363
|
+
{
|
|
364
|
+
headers: this.$headers(headerParameters),
|
|
365
|
+
method: 'GET',
|
|
366
|
+
body,
|
|
367
|
+
},
|
|
368
|
+
);
|
|
369
|
+
|
|
370
|
+
if (response.status === 200) {
|
|
371
|
+
const reader = response.body
|
|
372
|
+
?.pipeThrough(new TextDecoderStream())
|
|
373
|
+
.getReader();
|
|
374
|
+
let buffer = '';
|
|
375
|
+
while (reader) {
|
|
376
|
+
const { value: chunk, done } = await reader.read();
|
|
377
|
+
if (done) {
|
|
378
|
+
if (buffer.trim()) {
|
|
379
|
+
yield $IO.Event.fromJson(JSON.parse(buffer));
|
|
380
|
+
}
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
if (chunk) {
|
|
384
|
+
buffer += chunk;
|
|
385
|
+
}
|
|
386
|
+
const lines = buffer.split('\\n');
|
|
387
|
+
buffer = lines.pop() ?? '';
|
|
388
|
+
for (const line of lines) {
|
|
389
|
+
if (line.trim()) {
|
|
390
|
+
yield $IO.Event.fromJson(JSON.parse(line));
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
throw new Error(
|
|
397
|
+
\`Unknown response status \${response.status} returned by API\`,
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
"
|
|
402
|
+
`;
|
|
403
|
+
|
|
3
404
|
exports[`openApiTsClientGenerator - streaming > should handle error responses for streaming operations 1`] = `
|
|
4
405
|
"export type GetStream400Response = {
|
|
5
406
|
code: string;
|
|
@@ -147,11 +147,11 @@ const renderResponse = (response, options) => {
|
|
|
147
147
|
}
|
|
148
148
|
return renderFromJsonValue(response, `(${opts.asJson})`);
|
|
149
149
|
};
|
|
150
|
-
const renderStreamingResponseChunk = (response) => {
|
|
150
|
+
const renderStreamingResponseChunk = (response, chunkVariableName = 'value') => {
|
|
151
151
|
return renderResponse(response, {
|
|
152
|
-
asJson:
|
|
153
|
-
asText:
|
|
154
|
-
asBlob:
|
|
152
|
+
asJson: `JSON.parse(${chunkVariableName})`,
|
|
153
|
+
asText: chunkVariableName,
|
|
154
|
+
asBlob: `new Blob([${chunkVariableName}])`,
|
|
155
155
|
});
|
|
156
156
|
};
|
|
157
157
|
const matchPattern = (pattern, value) => {
|
|
@@ -433,11 +433,34 @@ export class <%- className %> {
|
|
|
433
433
|
return;
|
|
434
434
|
<%_ } else { _%>
|
|
435
435
|
const reader = response.body?<% if (response.type !== 'binary') { %>.pipeThrough(new TextDecoderStream())<% } %>.getReader();
|
|
436
|
+
<%_ if (response.isJsonlStreaming) { _%>
|
|
437
|
+
let buffer = '';
|
|
438
|
+
while (reader) {
|
|
439
|
+
const { value: chunk, done } = await reader.read();
|
|
440
|
+
if (done) {
|
|
441
|
+
if (buffer.trim()) {
|
|
442
|
+
yield <%- renderStreamingResponseChunk(response.itemSchemaModel, 'buffer') %>;
|
|
443
|
+
}
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
if (chunk) {
|
|
447
|
+
buffer += chunk;
|
|
448
|
+
}
|
|
449
|
+
const lines = buffer.split('\n');
|
|
450
|
+
buffer = lines.pop() ?? '';
|
|
451
|
+
for (const line of lines) {
|
|
452
|
+
if (line.trim()) {
|
|
453
|
+
yield <%- renderStreamingResponseChunk(response.itemSchemaModel, 'line') %>;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
<%_ } else { _%>
|
|
436
458
|
while (reader) {
|
|
437
459
|
const { value, done } = await reader.read();
|
|
438
460
|
if (done) return;
|
|
439
461
|
yield <%- renderStreamingResponseChunk(response) %>;
|
|
440
462
|
}
|
|
463
|
+
<%_ } _%>
|
|
441
464
|
return;
|
|
442
465
|
<%_ } _%>
|
|
443
466
|
<%_ } else { _%>
|
|
@@ -23,6 +23,10 @@ export declare const flattenModelLink: (link?: Model | Model[]) => Model;
|
|
|
23
23
|
export declare const COMPOSED_SCHEMA_TYPES: Set<string>;
|
|
24
24
|
export declare const COLLECTION_TYPES: Set<string>;
|
|
25
25
|
export declare const PRIMITIVE_TYPES: Set<string>;
|
|
26
|
+
/**
|
|
27
|
+
* Content types that indicate JSON Lines streaming (OpenAPI 3.2)
|
|
28
|
+
*/
|
|
29
|
+
export declare const STREAMING_CONTENT_TYPES: Set<string>;
|
|
26
30
|
/**
|
|
27
31
|
* Vendor extensions which are used to customise generated code
|
|
28
32
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.VENDOR_EXTENSIONS = exports.PRIMITIVE_TYPES = exports.COLLECTION_TYPES = exports.COMPOSED_SCHEMA_TYPES = exports.flattenModelLink = void 0;
|
|
3
|
+
exports.VENDOR_EXTENSIONS = exports.STREAMING_CONTENT_TYPES = exports.PRIMITIVE_TYPES = exports.COLLECTION_TYPES = exports.COMPOSED_SCHEMA_TYPES = exports.flattenModelLink = void 0;
|
|
4
4
|
const flattenModelLink = (link) => link === undefined ? undefined : Array.isArray(link) ? link[0] : link;
|
|
5
5
|
exports.flattenModelLink = flattenModelLink;
|
|
6
6
|
// Model types which indicate it is composed (ie inherits/mixin's another schema)
|
|
@@ -16,6 +16,13 @@ exports.PRIMITIVE_TYPES = new Set([
|
|
|
16
16
|
'binary',
|
|
17
17
|
'void',
|
|
18
18
|
]);
|
|
19
|
+
/**
|
|
20
|
+
* Content types that indicate JSON Lines streaming (OpenAPI 3.2)
|
|
21
|
+
*/
|
|
22
|
+
exports.STREAMING_CONTENT_TYPES = new Set([
|
|
23
|
+
'application/jsonl',
|
|
24
|
+
'application/x-ndjson',
|
|
25
|
+
]);
|
|
19
26
|
/**
|
|
20
27
|
* Vendor extensions which are used to customise generated code
|
|
21
28
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../../../packages/nx-plugin/src/open-api/utils/codegen-data/types.ts"],"names":[],"mappings":";;;AAoBO,MAAM,gBAAgB,GAAG,CAAC,IAAsB,EAAS,EAAE,CAChE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAD3D,QAAA,gBAAgB,oBAC2C;AAExE,iFAAiF;AACpE,QAAA,qBAAqB,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;AAChE,QAAA,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;AACpD,QAAA,eAAe,GAAG,IAAI,GAAG,CAAC;IACrC,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,SAAS;IACT,MAAM;IACN,KAAK;IACL,QAAQ;IACR,MAAM;CACP,CAAC,CAAC;AAEH;;GAEG;AACU,QAAA,iBAAiB,GAAG;IAC/B;;OAEG;IACH,SAAS,EAAE,aAAa;IACxB;;OAEG;IACH,QAAQ,EAAE,YAAY;IACtB;;OAEG;IACH,KAAK,EAAE,SAAS;IAChB;;;;;;OAMG;IACH,MAAM,EAAE,UAAU;CACV,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../../../packages/nx-plugin/src/open-api/utils/codegen-data/types.ts"],"names":[],"mappings":";;;AAoBO,MAAM,gBAAgB,GAAG,CAAC,IAAsB,EAAS,EAAE,CAChE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAD3D,QAAA,gBAAgB,oBAC2C;AAExE,iFAAiF;AACpE,QAAA,qBAAqB,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;AAChE,QAAA,gBAAgB,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;AACpD,QAAA,eAAe,GAAG,IAAI,GAAG,CAAC;IACrC,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,SAAS;IACT,MAAM;IACN,KAAK;IACL,QAAQ;IACR,MAAM;CACP,CAAC,CAAC;AAEH;;GAEG;AACU,QAAA,uBAAuB,GAAG,IAAI,GAAG,CAAC;IAC7C,mBAAmB;IACnB,sBAAsB;CACvB,CAAC,CAAC;AAEH;;GAEG;AACU,QAAA,iBAAiB,GAAG;IAC/B;;OAEG;IACH,SAAS,EAAE,aAAa;IACxB;;OAEG;IACH,QAAQ,EAAE,YAAY;IACtB;;OAEG;IACH,KAAK,EAAE,SAAS;IAChB;;;;;;OAMG;IACH,MAAM,EAAE,UAAU;CACV,CAAC"}
|
|
@@ -85,6 +85,12 @@ const buildOpenApiCodeGenData = (inSpec) => tslib_1.__awaiter(void 0, void 0, vo
|
|
|
85
85
|
if (responseSchema) {
|
|
86
86
|
yield mutateWithOpenapiSchemaProperties(spec, response, responseSchema, modelsByName);
|
|
87
87
|
}
|
|
88
|
+
if (types_1.STREAMING_CONTENT_TYPES.has(mediaType) &&
|
|
89
|
+
'itemSchema' in responseContent) {
|
|
90
|
+
response.isJsonlStreaming = true;
|
|
91
|
+
response.itemSchemaModel =
|
|
92
|
+
yield buildOrReferenceModel(spec, modelsByName, responseContent.itemSchema);
|
|
93
|
+
}
|
|
88
94
|
}
|
|
89
95
|
}
|
|
90
96
|
}
|
|
@@ -738,7 +744,21 @@ const mutateOperationWithAdditionalData = (op) => {
|
|
|
738
744
|
op.isMutation = isMutation;
|
|
739
745
|
op.isQuery = !isMutation;
|
|
740
746
|
// Streaming responses
|
|
741
|
-
op.isStreaming =
|
|
747
|
+
op.isStreaming =
|
|
748
|
+
!!((_a = op.vendorExtensions) === null || _a === void 0 ? void 0 : _a[types_1.VENDOR_EXTENSIONS.STREAMING]) ||
|
|
749
|
+
op.responses.some((res) => res.isJsonlStreaming);
|
|
750
|
+
// Set the result type for the client method to the item schema so that
|
|
751
|
+
// it will resolve to AsyncIterableIterator<{itemSchemaModel.name}>
|
|
752
|
+
const jsonlResponse = op.responses.find((res) => res.isJsonlStreaming);
|
|
753
|
+
if (jsonlResponse) {
|
|
754
|
+
const itemSchemaModel = jsonlResponse.itemSchemaModel;
|
|
755
|
+
const result = op.result;
|
|
756
|
+
if (result && itemSchemaModel) {
|
|
757
|
+
result.type = itemSchemaModel.name;
|
|
758
|
+
result.typescriptType = itemSchemaModel.name;
|
|
759
|
+
result.export = 'reference';
|
|
760
|
+
}
|
|
761
|
+
}
|
|
742
762
|
// Add infinite query details if applicable
|
|
743
763
|
if (!isMutation) {
|
|
744
764
|
mutateOperationWithInfiniteQueryDetails(op);
|