Skip to content
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
6 changes: 3 additions & 3 deletions .github/workflows/dotnet-core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v6
- name: Setup .NET
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v5
with:
dotnet-version: 8.0.x
dotnet-version: 10.0.x
- name: Install dependencies
run: dotnet restore
- name: Build
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
![.NET Core](https://github.com/Dolfik1/Funogram/workflows/.NET/badge.svg)
[![NuGet](https://img.shields.io/nuget/v/Funogram.svg)](https://www.nuget.org/packages/Funogram/)
[![NuGet](https://img.shields.io/nuget/v/Funogram.Telegram.svg)](https://www.nuget.org/packages/Funogram.Telegram/)
[![NuGet](https://img.shields.io/badge/Bot%20API-9.2-blue?logo=telegram)](https://www.nuget.org/packages/Funogram.Telegram/)
[![NuGet](https://img.shields.io/badge/Bot%20API-10.1-blue?logo=telegram)](https://www.nuget.org/packages/Funogram.Telegram/)

<img src="https://github.com/Dolfik1/Funogram/raw/master/docs/files/img/logo.png" alt="Funogram Logo" width="200" align="right" />

Expand Down
18 changes: 18 additions & 0 deletions src/Funogram.Generator/CustomFields.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,23 @@
]
]
}
},
{
"Name": "RichText",
"Kind": {
"Case": "Cases",
"Fields": [
[
{
"Name": "Plain",
"CaseType": "string"
},
{
"Name": "ArrayOf",
"CaseType": "RichText array"
}
]
]
}
}
]
9 changes: 5 additions & 4 deletions src/Funogram.Generator/Funogram.Generator.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
Expand All @@ -24,9 +24,10 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Argu" Version="6.1.1" />
<PackageReference Include="FSharp.Data" Version="4.2.8" />
<PackageReference Include="FSharp.SystemTextJson" Version="0.19.13" />
<PackageReference Include="Argu" Version="6.2.5" />
<PackageReference Include="FSharp.Data" Version="8.1.14" />
<PackageReference Include="FSharp.SystemTextJson" Version="1.4.36" />
<PackageReference Update="FSharp.Core" Version="10.1.301" />
</ItemGroup>

</Project>
11 changes: 7 additions & 4 deletions src/Funogram.Generator/Helpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,13 @@ let convertTLTypeToFSharpType (typeString: string) (description: string) (option
typeString

let getJsonSerializerOptions () =
let serializerOptions = JsonSerializerOptions()
serializerOptions.Converters.Add(JsonFSharpConverter(allowNullFields = true))
serializerOptions.WriteIndented <- true
serializerOptions
let options =
JsonSerializerOptions(
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)
let fsharpOpts = JsonFSharpOptions.Default().WithSkippableOptionFields()
options.Converters.Add(JsonFSharpConverter(fsharpOpts))
options

let compareWildcard (expression: string) (value: string) =
FileSystemName.MatchesSimpleExpression(expression, value, false)
Expand Down
3 changes: 2 additions & 1 deletion src/Funogram.Generator/Methods/MethodsParser.fs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ let loadRemapData remapPath config =
{ config with RemapMethods = result }
with
| e ->
printfn "ERR: Could not deserialize file! %A" e
printfn "ERR: Can't deserialize methods file! %A" e
config
else
printfn "WARN: Remap file not found at path %s" remapPath
Expand All @@ -63,6 +63,7 @@ let private returnTypeRegexes =
Regex("([A|a]rray of \w+|\w+) is returned, otherwise ([A|a]rray of \w+|\w+)")

Regex("[R|r]eturns a ([A|a]rray of \w+|\w+)\s")
Regex("[R|r]eturns the .+ as (?:an? )?([A|a]rray of \w+|\w+)")
Regex("[R|r]eturns the uploaded (\w+)\s")
Regex("[R|r]eturns the ([A|a]rray of \w+|\w+)\s")
Regex("[R|r]eturns an ([A|a]rray of \w+|\w+)\s")
Expand Down
6 changes: 6 additions & 0 deletions src/Funogram.Generator/RemapMethods.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,11 @@
"ConvertedFieldType": "ParseMode"
}
]
},
{
"OriginalName": "sendMediaGroup",
"Fields": [
{ "OriginalName": "media", "ConvertedFieldType": "InputMedia[]" }
]
}
]
59 changes: 59 additions & 0 deletions src/Funogram.Generator/RemapTypes.json
Original file line number Diff line number Diff line change
Expand Up @@ -148,5 +148,64 @@
]
]
}
},
{
"Name": "MaybeInaccessibleMessage",
"Kind": {
"Case": "Cases",
"Fields": [
[
{ "CaseType": "Message", "Name": "Message" },
{ "CaseType": "InaccessibleMessage", "Name": "InaccessibleMessage" }
]
]
}
},
{
"Name": "InputPollMedia",
"Kind": {
"Case": "Cases",
"Fields": [
[
{ "CaseType": "InputMediaAnimation", "Name": "Animation" },
{ "CaseType": "InputMediaAudio", "Name": "Audio" },
{ "CaseType": "InputMediaDocument", "Name": "Document" },
{ "CaseType": "InputMediaLivePhoto", "Name": "LivePhoto" },
{ "CaseType": "InputMediaLocation", "Name": "Location" },
{ "CaseType": "InputMediaPhoto", "Name": "Photo" },
{ "CaseType": "InputMediaVenue", "Name": "Venue" },
{ "CaseType": "InputMediaVideo", "Name": "Video" }
]
]
}
},
{
"Name": "InputPollOptionMedia",
"Kind": {
"Case": "Cases",
"Fields": [
[
{ "CaseType": "InputMediaAnimation", "Name": "Animation" },
{ "CaseType": "InputMediaLink", "Name": "Link" },
{ "CaseType": "InputMediaLivePhoto", "Name": "LivePhoto" },
{ "CaseType": "InputMediaLocation", "Name": "Location" },
{ "CaseType": "InputMediaPhoto", "Name": "Photo" },
{ "CaseType": "InputMediaSticker", "Name": "Sticker" },
{ "CaseType": "InputMediaVenue", "Name": "Venue" },
{ "CaseType": "InputMediaVideo", "Name": "Video" }
]
]
}
},
{
"Name": "RichText",
"Kind": {
"Case": "Cases",
"Fields": [
[
{ "CaseType": "RichTextDateTime", "Name": "DateTimeText" }
]
]
}
}
]
28 changes: 20 additions & 8 deletions src/Funogram.Generator/Types/TypesParser.fs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ let loadRemapData remapPath config =
{ config with RemapTypes = result }
with
| e ->
printfn "ERR: Could not deserialize file! %A" e
printfn "ERR: Can't deserialize file! %A" e
config
else
printfn "WARN: Remap file not found at path %s" remapPath
Expand All @@ -47,11 +47,7 @@ let private splitCaseNameAndType (typeName: string) (nameAndType: string) =
| "InputMessageContent" -> "Input"
| _ -> typeName

match typeName, nameAndType with
| "MaybeInaccessibleMessage", "Message" -> "Message"
| "MaybeInaccessibleMessage", "InaccessibleMessage" -> "InaccessibleMessage"
| _ ->
try nameAndType.Substring(typeName.Length) with | _ -> "ERROR!"
try nameAndType.Substring(typeName.Length) with | _ -> $"ERROR({typeName}, {nameAndType})!"

let private isValidTypeNode (typeNodeInfo: ApiTypeNodeInfo) =
let name = Helpers.innerText typeNodeInfo.TypeName
Expand Down Expand Up @@ -141,7 +137,21 @@ let private remap (remapTypes: ApiType[]) (types: ApiType[]) =

{ tp with Kind = ApiTypeKind.Fields fields }

| ApiTypeKind.Cases cases, ApiTypeKind.Cases remapCases -> tp
| ApiTypeKind.Cases cases, ApiTypeKind.Cases remapCases ->
let cases =
cases
|> Array.map (fun case ->
remapCases
|> Array.fold (fun case remapCase ->
let matched = not (String.IsNullOrEmpty remapCase.CaseType) && Helpers.compareWildcard remapCase.CaseType case.CaseType
if matched then
{ case with
Name = remapCase.Name |> Option.ofObj |> Option.defaultValue case.Name }
else
case
) case
)
{ tp with Kind = ApiTypeKind.Cases cases }
| _ -> tp
else
tp
Expand Down Expand Up @@ -258,12 +268,14 @@ let mergeCustomFields (customFieldsPath: string) (types: ApiType[]) =
match tp.Kind, typeWithCustomFields.Kind with
| ApiTypeKind.Fields fields, ApiTypeKind.Fields extraFields ->
let mergedFields = Array.append fields extraFields
let mergedFieldsDistinct = mergedFields |> Array.distinctBy (_.ConvertedName)
let mergedFieldsDistinct = mergedFields |> Array.distinctBy _.ConvertedName

if mergedFields.Length <> mergedFieldsDistinct.Length then
failwith $"Custom fields must be unique (type {tp.Name}).\nTelegram API fields:\n%A{fields}\nCustom fields:\n%A{extraFields}"

yield { tp with Kind = ApiTypeKind.Fields mergedFields }
| ApiTypeKind.Cases cases, ApiTypeKind.Cases extraCases ->
yield { tp with Kind = ApiTypeKind.Cases (Array.append cases extraCases) }
| ApiTypeKind.Stub, kind ->
yield { tp with Kind = kind }
| _ ->
Expand Down
Loading