Skip to content

Commit 6c33d1a

Browse files
authored
feat(core): executor to generate swagger json (#437)
Adds a new target to projects created with the `webapi` template by default called `swagger`. You can add this target (and supporting library) to any existing apis by running via `nx g @nx-dotnet/core:add-swagger-target` This generates/updates a `swagger.json` file inside a supporting library. The end goal is that you would use this generated file to generate typescript interfaces. > Generation of `swagger.json` assumes that your webapi project uses `Swashbuckle.AspNetCore`, and does have swagger setup. If it does not, this target + supporting library **will not** function out of the box.
1 parent 8bacf69 commit 6c33d1a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+654
-476
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# @nx-dotnet/core:update-swagger
2+
3+
## Swagger executor
4+
5+
Extract openapi swagger documentation from the webapi
6+
7+
## Options
8+
9+
### output
10+
11+
- (string): Where should the swagger output be stored
12+
13+
### swaggerDoc
14+
15+
- (string): Which swagger doc should be used?
16+
17+
### startupAssembly
18+
19+
- (string): Path from workspace root to the built api's startup dll file
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# @nx-dotnet/core:add-swagger-target
2+
3+
## Swagger Target Generator
4+
5+
Generates a swagger setup for a given project
6+
7+
## Options
8+
9+
### swaggerDoc
10+
11+
- (string): Which swagger doc should be used?
12+
13+
### startupAssembly
14+
15+
- (string): Path from workspace root to the built api's startup dll file
16+
17+
### <span className="required">project</span>
18+
19+
- (string): Which project should the target be added to?
20+
21+
### swaggerProject
22+
23+
- (string): What should the project created to hold the swagger files be called?
24+
25+
### target
26+
27+
- (string): What should the project be called?

docs/core/generators/application.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,7 @@ Generate a dotnet project under the application directory.
4343
- (string): The name of the solution file to add the project to
4444

4545
- (boolean): Should the project be added to the default solution file?
46+
47+
### skipSwaggerLib
48+
49+
- (): By default, if using webapi template, an additional library is scaffolded for swagger files. This skips that setup.

docs/core/generators/library.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,7 @@ Generate a dotnet project under the library directory.
3939
- (string): The name of the solution file to add the project to
4040

4141
- (boolean): Should the project be added to the default solution file?
42+
43+
### skipSwaggerLib
44+
45+
- (): By default, if using webapi template, an additional library is scaffolded for swagger files. This skips that setup.

docs/core/index.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ Generate a .NET test project for an existing application or library
117117

118118
Import existing projects into your nx workspace
119119

120+
### [add-swagger-target](./generators/add-swagger-target.md)
121+
122+
Generate a target to extract the swagger.json file from a .NET webapi
123+
120124
## Executors
121125

122126
### [build](./executors/build.md)
@@ -138,3 +142,7 @@ publish executor
138142
### [format](./executors/format.md)
139143

140144
Formats and lints a project using the dotnet-format tool
145+
146+
### [update-swagger](./executors/update-swagger.md)
147+
148+
Generates a swagger document for an API project

docs/index.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ slug: /
77

88
## [@nx-dotnet/core](./core)
99

10-
- 5 Executors
11-
- 9 Generators
10+
- 6 Executors
11+
- 10 Generators
1212

1313
## [@nx-dotnet/nx-ghpages](./nx-ghpages)
1414

@@ -17,5 +17,3 @@ slug: /
1717
## [@nx-dotnet/nxdoc](./nxdoc)
1818

1919
- 1 Generator
20-
21-
## [@nx-dotnet/typescript](./typescript)

docs/typescript/_category_.yml

Lines changed: 0 additions & 1 deletion
This file was deleted.

docs/typescript/index.md

Lines changed: 0 additions & 8 deletions
This file was deleted.

e2e/core-e2e/jest.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ module.exports = {
1111
},
1212
moduleFileExtensions: ['ts', 'js', 'html'],
1313
coverageDirectory: '../../coverage/e2ecore-e2e',
14-
testTimeout: 120000,
14+
testTimeout: 150000,
1515
};

e2e/core-e2e/tests/nx-dotnet.spec.ts

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ describe('nx-dotnet e2e', () => {
4141
const testLib = uniq('lib');
4242

4343
await runNxCommandAsync(
44-
`generate @nx-dotnet/core:app ${testApp} --language="C#" --template="webapi"`,
44+
`generate @nx-dotnet/core:app ${testApp} --language="C#" --template="webapi" --skipSwaggerLib`,
4545
);
4646

4747
await runNxCommandAsync(
@@ -73,7 +73,7 @@ describe('nx-dotnet e2e', () => {
7373
);
7474

7575
await runNxCommandAsync(
76-
`generate @nx-dotnet/core:app ${testApp} --language="C#" --template="webapi"`,
76+
`generate @nx-dotnet/core:app ${testApp} --language="C#" --template="webapi" --skipSwaggerLib`,
7777
);
7878

7979
await runNxCommandAsync(
@@ -93,26 +93,29 @@ describe('nx-dotnet e2e', () => {
9393
it('should obey dry-run', async () => {
9494
const app = uniq('app');
9595
await runNxCommandAsync(
96-
`generate @nx-dotnet/core:app ${app} --language="C#" --template="webapi" --dry-run`,
96+
`generate @nx-dotnet/core:app ${app} --language="C#" --template="webapi" --skipSwaggerLib --dry-run`,
9797
);
9898

9999
expect(() => checkFilesExist(`apps/${app}`)).toThrow();
100100
});
101101

102-
it('should generate an app', async () => {
102+
it('should generate an app without swagger library', async () => {
103103
const app = uniq('app');
104104
await runNxCommandAsync(
105-
`generate @nx-dotnet/core:app ${app} --language="C#" --template="webapi"`,
105+
`generate @nx-dotnet/core:app ${app} --language="C#" --template="webapi" --skip-swagger-lib`,
106106
);
107107

108108
expect(() => checkFilesExist(`apps/${app}`)).not.toThrow();
109+
expect(() =>
110+
checkFilesExist(`libs/generated/${app}-swaggger/project.json`),
111+
).toThrow();
109112
});
110113

111114
it('should build and test an app', async () => {
112115
const app = uniq('app');
113116
const testProj = `${app}-test`;
114117
await runNxCommandAsync(
115-
`generate @nx-dotnet/core:app ${app} --language="C#" --template="webapi"`,
118+
`generate @nx-dotnet/core:app ${app} --language="C#" --template="webapi" --skip-swagger-lib`,
116119
);
117120

118121
await runNxCommandAsync(`build ${app}`);
@@ -126,7 +129,7 @@ describe('nx-dotnet e2e', () => {
126129
const app = uniq('app');
127130
const lib = uniq('lib');
128131
await runNxCommandAsync(
129-
`generate @nx-dotnet/core:app ${app} --language="C#" --template="webapi"`,
132+
`generate @nx-dotnet/core:app ${app} --language="C#" --template="webapi" --skip-swagger-lib`,
130133
);
131134
await runNxCommandAsync(
132135
`generate @nx-dotnet/core:lib ${lib} --language="C#" --template="classlib"`,
@@ -145,7 +148,7 @@ describe('nx-dotnet e2e', () => {
145148
it('should update output paths', async () => {
146149
const app = uniq('app');
147150
await runNxCommandAsync(
148-
`generate @nx-dotnet/core:app ${app} --language="C#" --template="webapi"`,
151+
`generate @nx-dotnet/core:app ${app} --language="C#" --template="webapi" --skip-swagger-lib`,
149152
);
150153
const configFilePath = findProjectFileInPathSync(
151154
join(e2eDir, 'apps', app),
@@ -161,9 +164,10 @@ describe('nx-dotnet e2e', () => {
161164
it('should lint', async () => {
162165
const app = uniq('app');
163166
await runNxCommandAsync(
164-
`generate @nx-dotnet/core:app ${app} --language="C#" --template="webapi"`,
167+
`generate @nx-dotnet/core:app ${app} --template webapi --language="C#" --skip-swagger-lib`,
165168
);
166-
const promise = runNxCommandAsync(`lint ${app}`).then((x) => x.stderr);
169+
console.log('LINT TEST PROJECT GENERATED', app);
170+
const promise = runNxCommandAsync(`lint ${app}`);
167171
await expect(promise).rejects.toThrow(
168172
expect.objectContaining({
169173
message: expect.stringContaining('WHITESPACE'),
@@ -176,7 +180,7 @@ describe('nx-dotnet e2e', () => {
176180
it('should add a reference to the target project', async () => {
177181
const app = uniq('app');
178182
await runNxCommandAsync(
179-
`generate @nx-dotnet/core:app ${app} --language="C#" --template="webapi" --test-template="none"`,
183+
`generate @nx-dotnet/core:app ${app} --language="C#" --template="webapi" --skip-swagger-lib --test-template="none"`,
180184
);
181185
await runNxCommandAsync(
182186
`generate @nx-dotnet/core:test ${app} --language="C#" --template="nunit"`,
@@ -200,7 +204,7 @@ describe('nx-dotnet e2e', () => {
200204
it('should create test project using suffix', async () => {
201205
const app = uniq('app');
202206
await runNxCommandAsync(
203-
`generate @nx-dotnet/core:app ${app} --language="C#" --template="webapi" --test-template="none"`,
207+
`generate @nx-dotnet/core:app ${app} --language="C#" --template="webapi" --skip-swagger-lib --test-template="none"`,
204208
);
205209
await runNxCommandAsync(
206210
`generate @nx-dotnet/core:test ${app} --language="C#" --template="nunit" --suffix="integration-tests"`,
@@ -222,7 +226,7 @@ describe('nx-dotnet e2e', () => {
222226
it('should obey dry-run', async () => {
223227
const lib = uniq('lib');
224228
await runNxCommandAsync(
225-
`generate @nx-dotnet/core:lib ${lib} --language="C#" --template="webapi" --dry-run`,
229+
`generate @nx-dotnet/core:lib ${lib} --language="C#" --template="webapi" --skip-swagger-lib --dry-run`,
226230
);
227231

228232
expect(() => checkFilesExist(`libs/${lib}`)).toThrow();
@@ -231,7 +235,7 @@ describe('nx-dotnet e2e', () => {
231235
it('should generate an lib', async () => {
232236
const lib = uniq('lib');
233237
await runNxCommandAsync(
234-
`generate @nx-dotnet/core:lib ${lib} --language="C#" --template="webapi"`,
238+
`generate @nx-dotnet/core:lib ${lib} --language="C#" --template="classlib"`,
235239
);
236240

237241
expect(() => checkFilesExist(`libs/${lib}`)).not.toThrow();
@@ -284,7 +288,7 @@ describe('nx-dotnet e2e', () => {
284288
it("shouldn't create a solution by default if not specified", async () => {
285289
const app = uniq('app');
286290
await runNxCommandAsync(
287-
`generate @nx-dotnet/core:app ${app} --language="C#" --template="webapi"`,
291+
`generate @nx-dotnet/core:app ${app} --language="C#" --skip-swagger-lib --template="webapi"`,
288292
);
289293

290294
expect(() => checkFilesExist(`apps/${app}`)).not.toThrow();
@@ -294,7 +298,7 @@ describe('nx-dotnet e2e', () => {
294298
it('should create a default solution file if specified as true', async () => {
295299
const app = uniq('app');
296300
await runNxCommandAsync(
297-
`generate @nx-dotnet/core:app ${app} --language="C#" --template="webapi" --solutionFile`,
301+
`generate @nx-dotnet/core:app ${app} --language="C#" --template="webapi" --skip-swagger-lib --solutionFile`,
298302
);
299303

300304
expect(() => checkFilesExist(`apps/${app}`)).not.toThrow();
@@ -315,12 +319,12 @@ describe('nx-dotnet e2e', () => {
315319
it('should add successive projects to default solution file', async () => {
316320
const app1 = uniq('app');
317321
await runNxCommandAsync(
318-
`generate @nx-dotnet/core:app ${app1} --language="C#" --template="webapi" --solutionFile`,
322+
`generate @nx-dotnet/core:app ${app1} --language="C#" --skip-swagger-lib --template="webapi" --solutionFile`,
319323
);
320324

321325
const app2 = uniq('app2');
322326
await runNxCommandAsync(
323-
`generate @nx-dotnet/core:app ${app2} --language="C#" --template="webapi" --solutionFile`,
327+
`generate @nx-dotnet/core:app ${app2} --language="C#" --skip-swagger-lib --template="webapi" --solutionFile`,
324328
);
325329

326330
const slnFile = readFile('proj.nx-dotnet.sln');
@@ -333,7 +337,7 @@ describe('nx-dotnet e2e', () => {
333337
it('should add test project to same solution as app project', async () => {
334338
const app = uniq('app');
335339
await runNxCommandAsync(
336-
`generate @nx-dotnet/core:app ${app} --language="C#" --template="webapi" --test-template="xunit" --solutionFile`,
340+
`generate @nx-dotnet/core:app ${app} --language="C#" --template="webapi" --skip-swagger-lib --test-template="xunit" --solutionFile`,
337341
);
338342

339343
const slnFile = readFile('proj.nx-dotnet.sln');
@@ -399,7 +403,7 @@ describe('nx-dotnet e2e', () => {
399403
const appProject = uniq('app');
400404
const testProject = `${appProject}-test`;
401405
runNxCommand(
402-
`generate @nx-dotnet/core:app ${appProject} --language="C#" --template="webapi" --test-runner xunit`,
406+
`generate @nx-dotnet/core:app ${appProject} --language="C#" --template="webapi" --skip-swagger-lib --test-runner xunit`,
403407
);
404408

405409
expect(() => runNxCommand(`test ${testProject}`)).not.toThrow();
@@ -428,7 +432,7 @@ public class UnitTest1
428432
const appProject = uniq('app');
429433
const testProject = `${appProject}-test`;
430434
runNxCommand(
431-
`generate @nx-dotnet/core:app ${appProject} --language="C#" --template="webapi" --test-runner xunit`,
435+
`generate @nx-dotnet/core:app ${appProject} --language="C#" --template="webapi" --skip-swagger-lib --test-runner xunit`,
432436
);
433437
const p = runCommandUntil(
434438
`test ${testProject} --watch`,
@@ -441,6 +445,24 @@ public class UnitTest1
441445
await expect(p).resolves.not.toThrow();
442446
});
443447
});
448+
449+
describe('swagger integration', () => {
450+
it('should generate swagger project for webapi', async () => {
451+
const api = uniq('api');
452+
await runNxCommandAsync(
453+
`generate @nx-dotnet/core:app ${api} --language="C#" --template="webapi"`,
454+
);
455+
456+
expect(() => checkFilesExist(`apps/${api}`)).not.toThrow();
457+
expect(() =>
458+
checkFilesExist(`libs/generated/${api}-swagger`),
459+
).not.toThrow();
460+
expect(() => runNxCommand(`swagger ${api}`)).not.toThrow();
461+
expect(() =>
462+
checkFilesExist(`libs/generated/${api}-swagger/swagger.json`),
463+
).not.toThrow();
464+
});
465+
});
444466
});
445467

446468
function initializeGitRepo(cwd: string) {

0 commit comments

Comments
 (0)