Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

General Updates V2 #1279

Merged
merged 3 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .template.config/template.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@
"generator": "constant",
"replaces": "caPackageVersion",
"parameters": {
"value": "9.0.3"
"value": "9.0.4"
}
}
},
Expand Down Expand Up @@ -210,7 +210,8 @@
"src/Infrastructure/Data/Migrations/**",
"src/Web/appsettings.json",
"tests/Application.FunctionalTests/SqlServerTestDatabase.cs",
"tests/Application.FunctionalTests/TestcontainersTestDatabase.cs"
"tests/Application.FunctionalTests/TestcontainersTestDatabase.cs",
"tests/Application.FunctionalTests/appsettings.json"
],
"rename": {
"src/Infrastructure/Data/SQLite/" : "src/Infrastructure/Data/Migrations/",
Expand Down
10 changes: 3 additions & 7 deletions CleanArchitecture.nuspec
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,16 @@
<metadata>

<id>Clean.Architecture.Solution.Template</id>
<version>9.0.3</version>
<version>9.0.4</version>
<title>Clean Architecture Solution Template</title>
<authors>JasonTaylorDev</authors>
<description>Clean Architecture Solution Template for .NET 9.</description>
<summary>
A Clean Architecture Solution Template for creating apps using Angular, React, or Web API only with ASP.NET Core.
</summary>
<releaseNotes>
πŸ§‘β€πŸ’» Use TypedResults for Minimal API
πŸ› Create separate Open API spec for API only template
πŸ› Regenerate Open API spec / clients for Angular / React (excludes Users endpoint)
πŸ§‘β€πŸ’» Fix default pipeline provider (default to github)
πŸ‘· Build.cake - fix defaults and improve naming
πŸ“¦ React client - npm audit fix
πŸ› Fix Open API spec / client generation
πŸ§‘β€πŸ’» Tweak code for Sqlite option
</releaseNotes>

<projectUrl>https://github.com/JasonTaylorDev/CleanArchitecture</projectUrl>
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ The following prerequisites are required to build and run the solution:

The easiest way to get started is to install the [.NET template](https://www.nuget.org/packages/Clean.Architecture.Solution.Template):
```
dotnet new install Clean.Architecture.Solution.Template::9.0.3
dotnet new install Clean.Architecture.Solution.Template::9.0.4
```

Once installed, create a new solution using the template. You can choose to use Angular, React, or create a Web API-only solution. Specify the client framework using the `-cf` or `--client-framework` option, and provide the output directory where your project will be created. Here are some examples:
Expand Down
2 changes: 1 addition & 1 deletion src/AppHost/Program.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
var builder = DistributedApplication.CreateBuilder(args);

#if (!UseSqlite)
// Note: To run without Docker, simply remove sql and database:
// builder.AddProject<Projects.Web>("web");

#if (!UseSqlite)
var sql = builder.AddSqlServer("sql");

var database = sql.AddDatabase("CleanArchitectureDb");
Expand Down
170 changes: 58 additions & 112 deletions src/Web/ClientApp-React/src/web-api-client.ts

Large diffs are not rendered by default.

113 changes: 19 additions & 94 deletions src/Web/ClientApp/src/app/web-api-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,9 @@ export const API_BASE_URL = new InjectionToken<string>('API_BASE_URL');

export interface ITodoItemsClient {
getTodoItemsWithPagination(listId: number, pageNumber: number, pageSize: number): Observable<PaginatedListOfTodoItemBriefDto>;
/**
* @return OK
*/
createTodoItem(command: CreateTodoItemCommand): Observable<void>;
/**
* @return OK
*/
createTodoItem(command: CreateTodoItemCommand): Observable<number>;
updateTodoItem(id: number, command: UpdateTodoItemCommand): Observable<void>;
/**
* @return OK
*/
deleteTodoItem(id: number): Observable<void>;
/**
* @return OK
*/
updateTodoItemDetail(id: number, command: UpdateTodoItemDetailCommand): Observable<void>;
}

Expand Down Expand Up @@ -108,10 +96,7 @@ export class TodoItemsClient implements ITodoItemsClient {
return _observableOf(null as any);
}

/**
* @return OK
*/
createTodoItem(command: CreateTodoItemCommand): Observable<void> {
createTodoItem(command: CreateTodoItemCommand): Observable<number> {
let url_ = this.baseUrl + "/api/TodoItems";
url_ = url_.replace(/[?&]$/, "");

Expand All @@ -134,31 +119,27 @@ export class TodoItemsClient implements ITodoItemsClient {
try {
return this.processCreateTodoItem(response_ as any);
} catch (e) {
return _observableThrow(e) as any as Observable<void>;
return _observableThrow(e) as any as Observable<number>;
}
} else
return _observableThrow(response_) as any as Observable<void>;
return _observableThrow(response_) as any as Observable<number>;
}));
}

protected processCreateTodoItem(response: HttpResponseBase): Observable<void> {
protected processCreateTodoItem(response: HttpResponseBase): Observable<number> {
const status = response.status;
const responseBlob =
response instanceof HttpResponse ? response.body :
(response as any).error instanceof Blob ? (response as any).error : undefined;

let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }}
if (status === 200) {
return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => {
return _observableOf(null as any);
}));
} else if (status === 201) {
if (status === 201) {
return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => {
let result201: any = null;
let resultData201 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
result201 = resultData201 !== undefined ? resultData201 : <any>null;

return throwException("A server side error occurred.", status, _responseText, _headers, result201);
return _observableOf(result201);
}));
} else if (status !== 200 && status !== 204) {
return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => {
Expand All @@ -168,9 +149,6 @@ export class TodoItemsClient implements ITodoItemsClient {
return _observableOf(null as any);
}

/**
* @return OK
*/
updateTodoItem(id: number, command: UpdateTodoItemCommand): Observable<void> {
let url_ = this.baseUrl + "/api/TodoItems/{id}";
if (id === undefined || id === null)
Expand All @@ -186,7 +164,6 @@ export class TodoItemsClient implements ITodoItemsClient {
responseType: "blob",
headers: new HttpHeaders({
"Content-Type": "application/json",
"Accept": "application/json"
})
};

Expand All @@ -211,11 +188,7 @@ export class TodoItemsClient implements ITodoItemsClient {
(response as any).error instanceof Blob ? (response as any).error : undefined;

let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }}
if (status === 200) {
return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => {
return _observableOf(null as any);
}));
} else if (status === 204) {
if (status === 204) {
return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => {
return _observableOf(null as any);
}));
Expand All @@ -231,9 +204,6 @@ export class TodoItemsClient implements ITodoItemsClient {
return _observableOf(null as any);
}

/**
* @return OK
*/
deleteTodoItem(id: number): Observable<void> {
let url_ = this.baseUrl + "/api/TodoItems/{id}";
if (id === undefined || id === null)
Expand All @@ -245,7 +215,6 @@ export class TodoItemsClient implements ITodoItemsClient {
observe: "response",
responseType: "blob",
headers: new HttpHeaders({
"Accept": "application/json"
})
};

Expand All @@ -270,11 +239,7 @@ export class TodoItemsClient implements ITodoItemsClient {
(response as any).error instanceof Blob ? (response as any).error : undefined;

let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }}
if (status === 200) {
return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => {
return _observableOf(null as any);
}));
} else if (status === 204) {
if (status === 204) {
return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => {
return _observableOf(null as any);
}));
Expand All @@ -286,9 +251,6 @@ export class TodoItemsClient implements ITodoItemsClient {
return _observableOf(null as any);
}

/**
* @return OK
*/
updateTodoItemDetail(id: number, command: UpdateTodoItemDetailCommand): Observable<void> {
let url_ = this.baseUrl + "/api/TodoItems/UpdateDetail/{id}";
if (id === undefined || id === null)
Expand All @@ -304,7 +266,6 @@ export class TodoItemsClient implements ITodoItemsClient {
responseType: "blob",
headers: new HttpHeaders({
"Content-Type": "application/json",
"Accept": "application/json"
})
};

Expand All @@ -329,11 +290,7 @@ export class TodoItemsClient implements ITodoItemsClient {
(response as any).error instanceof Blob ? (response as any).error : undefined;

let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }}
if (status === 200) {
return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => {
return _observableOf(null as any);
}));
} else if (status === 204) {
if (status === 204) {
return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => {
return _observableOf(null as any);
}));
Expand All @@ -352,17 +309,8 @@ export class TodoItemsClient implements ITodoItemsClient {

export interface ITodoListsClient {
getTodoLists(): Observable<TodosVm>;
/**
* @return OK
*/
createTodoList(command: CreateTodoListCommand): Observable<void>;
/**
* @return OK
*/
createTodoList(command: CreateTodoListCommand): Observable<number>;
updateTodoList(id: number, command: UpdateTodoListCommand): Observable<void>;
/**
* @return OK
*/
deleteTodoList(id: number): Observable<void>;
}

Expand Down Expand Up @@ -427,10 +375,7 @@ export class TodoListsClient implements ITodoListsClient {
return _observableOf(null as any);
}

/**
* @return OK
*/
createTodoList(command: CreateTodoListCommand): Observable<void> {
createTodoList(command: CreateTodoListCommand): Observable<number> {
let url_ = this.baseUrl + "/api/TodoLists";
url_ = url_.replace(/[?&]$/, "");

Expand All @@ -453,31 +398,27 @@ export class TodoListsClient implements ITodoListsClient {
try {
return this.processCreateTodoList(response_ as any);
} catch (e) {
return _observableThrow(e) as any as Observable<void>;
return _observableThrow(e) as any as Observable<number>;
}
} else
return _observableThrow(response_) as any as Observable<void>;
return _observableThrow(response_) as any as Observable<number>;
}));
}

protected processCreateTodoList(response: HttpResponseBase): Observable<void> {
protected processCreateTodoList(response: HttpResponseBase): Observable<number> {
const status = response.status;
const responseBlob =
response instanceof HttpResponse ? response.body :
(response as any).error instanceof Blob ? (response as any).error : undefined;

let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }}
if (status === 200) {
return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => {
return _observableOf(null as any);
}));
} else if (status === 201) {
if (status === 201) {
return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => {
let result201: any = null;
let resultData201 = _responseText === "" ? null : JSON.parse(_responseText, this.jsonParseReviver);
result201 = resultData201 !== undefined ? resultData201 : <any>null;

return throwException("A server side error occurred.", status, _responseText, _headers, result201);
return _observableOf(result201);
}));
} else if (status !== 200 && status !== 204) {
return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => {
Expand All @@ -487,9 +428,6 @@ export class TodoListsClient implements ITodoListsClient {
return _observableOf(null as any);
}

/**
* @return OK
*/
updateTodoList(id: number, command: UpdateTodoListCommand): Observable<void> {
let url_ = this.baseUrl + "/api/TodoLists/{id}";
if (id === undefined || id === null)
Expand All @@ -505,7 +443,6 @@ export class TodoListsClient implements ITodoListsClient {
responseType: "blob",
headers: new HttpHeaders({
"Content-Type": "application/json",
"Accept": "application/json"
})
};

Expand All @@ -530,11 +467,7 @@ export class TodoListsClient implements ITodoListsClient {
(response as any).error instanceof Blob ? (response as any).error : undefined;

let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }}
if (status === 200) {
return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => {
return _observableOf(null as any);
}));
} else if (status === 204) {
if (status === 204) {
return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => {
return _observableOf(null as any);
}));
Expand All @@ -550,9 +483,6 @@ export class TodoListsClient implements ITodoListsClient {
return _observableOf(null as any);
}

/**
* @return OK
*/
deleteTodoList(id: number): Observable<void> {
let url_ = this.baseUrl + "/api/TodoLists/{id}";
if (id === undefined || id === null)
Expand All @@ -564,7 +494,6 @@ export class TodoListsClient implements ITodoListsClient {
observe: "response",
responseType: "blob",
headers: new HttpHeaders({
"Accept": "application/json"
})
};

Expand All @@ -589,11 +518,7 @@ export class TodoListsClient implements ITodoListsClient {
(response as any).error instanceof Blob ? (response as any).error : undefined;

let _headers: any = {}; if (response.headers) { for (let key of response.headers.keys()) { _headers[key] = response.headers.get(key); }}
if (status === 200) {
return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => {
return _observableOf(null as any);
}));
} else if (status === 204) {
if (status === 204) {
return blobToText(responseBlob).pipe(_observableMergeMap((_responseText: string) => {
return _observableOf(null as any);
}));
Expand Down
3 changes: 1 addition & 2 deletions src/Web/Infrastructure/WebApplicationExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ public static RouteGroupBuilder MapGroup(this WebApplication app, EndpointGroupB
return app
.MapGroup($"/api/{groupName}")
.WithGroupName(groupName)
.WithTags(groupName)
.WithOpenApi();
.WithTags(groupName);
}

public static WebApplication MapEndpoints(this WebApplication app)
Expand Down
Loading