Skip to content
Open
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
132 changes: 76 additions & 56 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Original idea: https://github.com/RSuter/NSwag/issues/691

## Sample

Hub:
Hub:

```csharp
public class ChatHub : Hub<IChatClient>
Expand All @@ -29,12 +29,14 @@ public class ChatHub : Hub<IChatClient>

public Task AddPerson(Person person)
{
Clients.Others.PersonAdded(person);
return Task.CompletedTask;
}

public ChannelReader<Event> GetEvents()
{
var channel = Channel.CreateUnbounded<Event>();
// TODO: Write events
return channel.Reader;
}
}
Expand All @@ -58,10 +60,12 @@ public interface IChatClient
Task Welcome();

Task Send(string message);

Task PersonAdded(Person person);
}
```

Generated spec:
Generated spec:

```json
{
Expand All @@ -74,10 +78,7 @@ Generated spec:
"description": "",
"parameters": {
"message": {
"type": [
"null",
"string"
],
"type": "string",
"description": ""
}
}
Expand All @@ -88,9 +89,6 @@ Generated spec:
"person": {
"description": "",
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/definitions/Person"
}
Expand All @@ -102,11 +100,8 @@ Generated spec:
"description": "",
"parameters": {},
"returntype": {
"description": "",
"description": "Provides a base class for reading from a channel.",
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/definitions/Event"
}
Expand All @@ -124,13 +119,23 @@ Generated spec:
"description": "",
"parameters": {
"message": {
"type": [
"null",
"string"
],
"type": "string",
"description": ""
}
}
},
"PersonAdded": {
"description": "",
"parameters": {
"person": {
"description": "",
"oneOf": [
{
"$ref": "#/definitions/Person"
}
]
}
}
}
}
}
Expand All @@ -141,78 +146,93 @@ Generated spec:
"additionalProperties": false,
"properties": {
"firstName": {
"type": [
"null",
"string"
]
"type": ["null", "string"]
},
"lastName": {
"type": [
"null",
"string"
]
"type": ["null", "string"]
}
}
},
"Event": {
"type": "object",
"additionalProperties": false,
"properties": {
"Type": {
"type": [
"null",
"string"
]
"type": {
"type": ["null", "string"]
}
}
}
}
}
```

Generated TypeScript code:
Generated TypeScript code:

```typescript
import { HubConnection, IStreamResult } from "@aspnet/signalr"
import { HubConnection, IStreamResult } from "@microsoft/signalr";

export class ChatHub {
constructor(private connection: HubConnection) {
}
constructor(private connection: HubConnection) {}

send(message: string): Promise<void> {
return this.connection.invoke('Send', message);
}
send(message: string): Promise<void> {
return this.connection.invoke("Send", message);
}

addPerson(person: Person): Promise<void> {
return this.connection.invoke('AddPerson', person);
}
addPerson(person: Person): Promise<void> {
return this.connection.invoke("AddPerson", person);
}

getEvents(): IStreamResult<Event> {
return this.connection.stream('GetEvents');
}
getEvents(): IStreamResult<Event> {
return this.connection.stream("GetEvents");
}

registerCallbacks(implementation: IChatHubCallbacks) {
this.connection.on('Welcome', () => implementation.welcome());
this.connection.on('Send', (message) => implementation.send(message));
}
onWelcome(func: () => void): void {
this.connection.on("Welcome", func);
}

unregisterCallbacks(implementation: IChatHubCallbacks) {
this.connection.off('Welcome', () => implementation.welcome());
this.connection.off('Send', (message) => implementation.send(message));
}
unregisterWelcome(func: () => void): void {
this.connection.off("Welcome", func);
}
onSend(func: (message: string) => void): void {
this.connection.on("Send", func);
}

unregisterSend(func: (message: string) => void): void {
this.connection.off("Send", func);
}
onPersonAdded(func: (person: Person) => void): void {
this.connection.on("PersonAdded", func);
}

unregisterPersonAdded(func: (person: Person) => void): void {
this.connection.off("PersonAdded", func);
}

registerCallbacks(implementation: IChatHubCallbacks) {
this.connection.on("Welcome", () => implementation.welcome());
this.connection.on("Send", message => implementation.send(message));
this.connection.on("PersonAdded", person => implementation.personAdded(person));
}

unregisterCallbacks(implementation: IChatHubCallbacks) {
this.connection.off("Welcome", () => implementation.welcome());
this.connection.off("Send", message => implementation.send(message));
this.connection.off("PersonAdded", person => implementation.personAdded(person));
}
}

export interface IChatHubCallbacks {
welcome(): void;
send(message: string): void;
welcome(): void;
send(message: string): void;
personAdded(person: Person): void;
}

export interface Person {
firstName: string;
lastName: string;
firstName: string | null;
lastName: string | null;
}

export interface Event {
Type: string;
type: string | null;
}
```
3 changes: 3 additions & 0 deletions src/HelloSignalR/ChatHub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public Task Send(string message)

public Task AddPerson(Person person)
{
Clients.Others.PersonAdded(person);
return Task.CompletedTask;
}

Expand Down Expand Up @@ -49,5 +50,7 @@ public interface IChatClient
Task Welcome();

Task Send(string message);

Task PersonAdded(Person person);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public SigSpecToTypeScriptGeneratorSettings()
typeof(TypeScriptGeneratorSettings).GetTypeInfo().Assembly,
typeof(SigSpecToTypeScriptGeneratorSettingsBase).GetTypeInfo().Assembly,
});
TypeScriptGeneratorSettings.NullValue = TypeScriptNullValue.Null;
}

public TypeScriptGeneratorSettings TypeScriptGeneratorSettings => (TypeScriptGeneratorSettings)CodeGeneratorSettings;
Expand Down
15 changes: 13 additions & 2 deletions src/SigSpec.CodeGeneration.TypeScript/Templates/Hub.liquid
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
export class {{ Name }}Hub {
constructor(private connection: HubConnection) {
}
constructor(private connection: HubConnection) {}
{% for operation in Operations -%}

{% if operation.IsObservable -%}
Expand All @@ -18,6 +17,17 @@
{% endif -%}
{% endfor -%}

{% for operation in Callbacks -%}
on{{operation.Name}}(func : ({% for parameter in operation.Parameters %}{{ parameter.Name }}: {{ parameter.Type }}{% if forloop.last == false %}, {% endif %}{% endfor %}) => void ): void {
this.connection.on('{{ operation.Name }}', func);
}

unregister{{operation.Name}}(func : ({% for parameter in operation.Parameters %}{{ parameter.Name }}: {{ parameter.Type }}{% if forloop.last == false %}, {% endif %}{% endfor %}) => void ): void {
this.connection.off('{{ operation.Name }}', func);
}
{% endfor -%}


registerCallbacks(implementation: I{{ Name }}HubCallbacks) {
{% for operation in Callbacks -%}
this.connection.on('{{ operation.Name }}', ({% for parameter in operation.Parameters %}{{ parameter.Name }}{% if forloop.last == false %}, {% endif %}{% endfor %}) => implementation.{{operation.MethodName}}({% for parameter in operation.Parameters %}{{ parameter.Name }}{% if forloop.last == false %}, {% endif %}{% endfor %}));
Expand All @@ -31,6 +41,7 @@
}
}


export interface I{{ Name }}HubCallbacks {
{% for operation in Callbacks -%}
{{ operation.MethodName }}({% for parameter in operation.Parameters %}{{ parameter.Name }}: {{ parameter.Type }}{% if forloop.last == false %}, {% endif %}{% endfor %}): void;
Expand Down