├── .gitignore ├── LICENSE ├── README.md ├── angularjs ├── angular-with-Results-complete-league.html ├── angular-with-Results.html ├── minimal-angular-v1.html └── minimal-angular-with-notifications.html ├── csharp ├── OpenLigaDB.Samples.DemoConsole │ ├── App.config │ ├── Match.cs │ ├── OpenLigaDB.Samples.DemoConsole.csproj │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Team.cs │ └── packages.config └── OpenLigaDB.Samples.sln ├── javascript └── live-server │ ├── bun │ ├── .gitignore │ ├── README.md │ ├── bun.lockb │ ├── bunfig.toml │ ├── index.ts │ ├── package.json │ └── tsconfig.json │ └── node │ ├── .npmrc │ ├── README.md │ ├── index.js │ ├── index.ts │ ├── package-lock.json │ └── package.json ├── php └── openligadb-example.php └── react ├── .babelrc ├── app ├── components │ ├── Game.jsx │ └── Games.jsx └── index.jsx ├── package.json ├── public └── index.html ├── test ├── components │ ├── Game.test.js │ └── Games.test.js ├── test-setup.js └── testUtils │ ├── multipleStubResponse.json │ └── validStubResponse.json └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | *.VC.VC.opendb 85 | 86 | # Visual Studio profiler 87 | *.psess 88 | *.vsp 89 | *.vspx 90 | *.sap 91 | 92 | # TFS 2012 Local Workspace 93 | $tf/ 94 | 95 | # Guidance Automation Toolkit 96 | *.gpState 97 | 98 | # ReSharper is a .NET coding add-in 99 | _ReSharper*/ 100 | *.[Rr]e[Ss]harper 101 | *.DotSettings.user 102 | 103 | # JustCode is a .NET coding add-in 104 | .JustCode 105 | 106 | # TeamCity is a build add-in 107 | _TeamCity* 108 | 109 | # DotCover is a Code Coverage Tool 110 | *.dotCover 111 | 112 | # NCrunch 113 | _NCrunch_* 114 | .*crunch*.local.xml 115 | nCrunchTemp_* 116 | 117 | # MightyMoose 118 | *.mm.* 119 | AutoTest.Net/ 120 | 121 | # Web workbench (sass) 122 | .sass-cache/ 123 | 124 | # Installshield output folder 125 | [Ee]xpress/ 126 | 127 | # DocProject is a documentation generator add-in 128 | DocProject/buildhelp/ 129 | DocProject/Help/*.HxT 130 | DocProject/Help/*.HxC 131 | DocProject/Help/*.hhc 132 | DocProject/Help/*.hhk 133 | DocProject/Help/*.hhp 134 | DocProject/Help/Html2 135 | DocProject/Help/html 136 | 137 | # Click-Once directory 138 | publish/ 139 | 140 | # Publish Web Output 141 | *.[Pp]ublish.xml 142 | *.azurePubxml 143 | # TODO: Comment the next line if you want to checkin your web deploy settings 144 | # but database connection strings (with potential passwords) will be unencrypted 145 | *.pubxml 146 | *.publishproj 147 | 148 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 149 | # checkin your Azure Web App publish settings, but sensitive information contained 150 | # in these scripts will be unencrypted 151 | PublishScripts/ 152 | 153 | # NuGet Packages 154 | *.nupkg 155 | # The packages folder can be ignored because of Package Restore 156 | **/packages/* 157 | # except build/, which is used as an MSBuild target. 158 | !**/packages/build/ 159 | # Uncomment if necessary however generally it will be regenerated when needed 160 | #!**/packages/repositories.config 161 | # NuGet v3's project.json files produces more ignoreable files 162 | *.nuget.props 163 | *.nuget.targets 164 | 165 | # Microsoft Azure Build Output 166 | csx/ 167 | *.build.csdef 168 | 169 | # Microsoft Azure Emulator 170 | ecf/ 171 | rcf/ 172 | 173 | # Windows Store app package directories and files 174 | AppPackages/ 175 | BundleArtifacts/ 176 | Package.StoreAssociation.xml 177 | _pkginfo.txt 178 | 179 | # Visual Studio cache files 180 | # files ending in .cache can be ignored 181 | *.[Cc]ache 182 | # but keep track of directories ending in .cache 183 | !*.[Cc]ache/ 184 | 185 | # Others 186 | ClientBin/ 187 | ~$* 188 | *~ 189 | *.dbmdl 190 | *.dbproj.schemaview 191 | *.pfx 192 | *.publishsettings 193 | node_modules/ 194 | orleans.codegen.cs 195 | 196 | # Since there are multiple workflows, uncomment next line to ignore bower_components 197 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 198 | #bower_components/ 199 | 200 | # RIA/Silverlight projects 201 | Generated_Code/ 202 | 203 | # Backup & report files from converting an old project file 204 | # to a newer Visual Studio version. Backup files are not needed, 205 | # because we have git ;-) 206 | _UpgradeReport_Files/ 207 | Backup*/ 208 | UpgradeLog*.XML 209 | UpgradeLog*.htm 210 | 211 | # SQL Server files 212 | *.mdf 213 | *.ldf 214 | 215 | # Business Intelligence projects 216 | *.rdl.data 217 | *.bim.layout 218 | *.bim_*.settings 219 | 220 | # Microsoft Fakes 221 | FakesAssemblies/ 222 | 223 | # GhostDoc plugin setting file 224 | *.GhostDoc.xml 225 | 226 | # Node.js Tools for Visual Studio 227 | .ntvs_analysis.dat 228 | 229 | # Visual Studio 6 build log 230 | *.plg 231 | 232 | # Visual Studio 6 workspace options file 233 | *.opt 234 | 235 | # Visual Studio LightSwitch build output 236 | **/*.HTMLClient/GeneratedArtifacts 237 | **/*.DesktopClient/GeneratedArtifacts 238 | **/*.DesktopClient/ModelManifest.xml 239 | **/*.Server/GeneratedArtifacts 240 | **/*.Server/ModelManifest.xml 241 | _Pvt_Extensions 242 | 243 | # Paket dependency manager 244 | .paket/paket.exe 245 | paket-files/ 246 | 247 | # FAKE - F# Make 248 | .fake/ 249 | 250 | # JetBrains Rider 251 | .idea/ 252 | *.sln.iml 253 | 254 | # File system 255 | .DS_Store 256 | *.swp 257 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Dokumentation zur OpenligaDB und deren Api 2 | 3 | ## Allgemeines 4 | 5 | Zum Abrufen der Liga-Daten der OpenligaDB werden im wesentlichen folgende Parameter verwendet: 6 | - **LeagueShortcut** - ein vom Ersteller der Liga vergebener, kurzer string, für die 1. Fußball-Bundesliga z.B. 'bl1' 7 | - **LeagueSeason** - die Jahreszahl der Saison der Liga 8 | - **GroupOrderId** - Die OrderId der 'Gruppierung' - entspricht z.B. in der Fußball-Bundesliga dem 'Spieltag' 9 | 10 | Der Abruf der Daten per JSON-Api erfolgt dann je nach Detailtiefe dem Schema 11 | 12 | > https://api.openligadb.de/getmatchdata/LeagueShortcut/LeagueSeason/GroupOrderId 13 | 14 | Eine Swagger-Online-Dokumentation der Api gibt es unter https://api.openligadb.de/ 15 | 16 | ### Berechtigungen 17 | Jeder angemeldete User darf Ligen anlegen, ist dann der "Administrator" seiner Ligen und nur dieser darf Teams und Spielansetzungen hinzufügen sowie die Ergebnistypen für seine Ligen festlegen. 18 | 19 | Anders ist es bei den Spielergebnissen, diese können von JEDEM angemeldeten User editiert werden. Nach einer Zeit von 6 Tagen nach Spielende ist das Editieren der Ergebnisse nur noch dem Administrator der Liga möglich. 20 | 21 | Auf [Anfrage](mailto:info@openligadb.de) werden hier auch relativ "locker" Rechte zum Editieren der Spielansetzungen für Ligen verteilt, um 22 | die Arbeit auf mehrere Schultern zu verteilen. Es kann also auch mehrere Administratoren einer Liga geben. 23 | 24 | ### Ligen-Priorität 25 | Die OpenligaDB ermöglicht es jedem interessierten Nutzer, eine eigene Liga anzulegen und zu pflegen. Dies führt in vielen 26 | Fällen zum Vorhandensein gleichartiger Ligen, welche dann unter Umständen nicht vollständig gepflegt werden. 27 | 28 | Um zu erkennen, welche Liga "produktiv" ist, gibt es intern eine Priorisierung der Ligen anhand der 29 | Anzahl ihrer Abfragen. So erfolgt z.B. die Sortierung der Ligen im Auswahl-Fenster nach diesem 30 | Prioritäts-Index - die "offiziellen" Ligen stehen hier oben. Dieser Index wird demnächst in weiteren Teilen 31 | der Oberfläche Einzug halten und die Auswahl transparenter machen. 32 | 33 | Für die Fußball-Bundesligen hat sich z.B. ein durchgehendes Namens-Schema entwickelt. So haben die erste bis 34 | dritte Bundesliga stets den LeaguShortcut "bl1", "bl2" und "bl3". Der Parameter LeagueSeason bestimmt dann 35 | die aktuelle Saison. Leider ist das z.B. bei der Champions League oder beim DFB-Pokal nicht so eindeutig 36 | angelegt worden. 37 | 38 | ## Api-Schema 39 | Nachfolgend wird das Api-Schema anhand von Beispielen dargestellt: 40 | 41 | --- 42 | Spiele des aktuellen Spieltages der ersten Bundesliga: 43 | > [https://api.openligadb.de/getmatchdata/bl1](https://api.openligadb.de/getmatchdata/bl1) 44 | 45 | Der aktuelle Spieltag wird jeweils zur Hälfte der Zeit zwischen dem letzten Spiel des letzten Spieltages und dem ersten Spiel des nächsten Spieltages erhöht. 46 | 47 | --- 48 | Spiele des 8. Spieltages der ersten Bundesliga 2022/2023: 49 | > [https://api.openligadb.de/getmatchdata/bl1/2022/8](https://api.openligadb.de/getmatchdata/bl1/2022/8) 50 | 51 | --- 52 | Alle Spiele der ersten Bundesliga 2022/2023: 53 | > [https://api.openligadb.de/getmatchdata/bl1/2022](https://api.openligadb.de/getmatchdata/bl1/2022) 54 | 55 | --- 56 | Spiel mit der Id 39738: 57 | > [https://api.openligadb.de/getmatchdata/39738](https://api.openligadb.de/getmatchdata/39738) 58 | 59 | --- 60 | Die aktuelle Group (entspricht z.B. bei der Fussball-Bundesliga dem 'Spieltag') des als Parameter zu übergebenden leagueShortcuts (z.B. 'bl1'): 61 | > [https://api.openligadb.de/getcurrentgroup/bl1](https://api.openligadb.de/getcurrentgroup/bl1) 62 | 63 | Der aktuelle Spieltag wird jeweils zur Hälfte der Zeit zwischen dem letzten Spiel des letzten Spieltages und dem ersten Spiel des nächsten Spieltages erhöht. 64 | 65 | 66 | --- 67 | Eine Liste der Spiel-Einteilungen (Spieltag, Vorrunde, Finale, ...) der als Parameter zu übergebenden Liga + Saison 68 | > [https://api.openligadb.de/getavailablegroups/bl1/2022](https://api.openligadb.de/getavailablegroups/bl1/2022) 69 | 70 | --- 71 | Datum und Uhrzeit der letzten Änderung in den Daten des 8. Spieltages der ersten Bundesliga 2022/2023. 72 | > [https://api.openligadb.de/getlastchangedate/bl1/2022/8](https://api.openligadb.de/getlastchangedate/bl1/2022/8) 73 | 74 | Diese Methode dient zur Ermittlung der Änderung von Spieldaten, um unnötiges Pollen der o.g. Service-Methoden zu vermeiden. 75 | 76 | --- 77 | Das nächste anstehende Spiel des als Parameter zu übergebenden Teams der ebenfalls zu übergebenen Liga: 78 | > [https://api.openligadb.de/getnextmatchbyleagueteam/3005/7](https://api.openligadb.de/getnextmatchbyleagueteam/3005/7) 79 | 80 | - '3005' entspricht der LeagueId der 1. Fußball Bundesliga 2016/2017 81 | - '7' entspricht der TeamId von Borussia Dortmund 82 | 83 | --- 84 | Alle Teams einer Liga: 85 | > [https://api.openligadb.de/getavailableteams/bl1/2022](https://api.openligadb.de/getavailableteams/bl1/2022) 86 | 87 | 88 | --- 89 | Die Spiele, bei welchen die als Parameter übergebenen Teams gegeneinander spielten: 90 | > [https://api.openligadb.de/getmatchdata/40/7](https://api.openligadb.de/getmatchdata/40/7) 91 | 92 | --- 93 | Die Torschützen der übergebenen Liga: 94 | > [https://api.openligadb.de/getgoalgetters/bl1/2022](https://api.openligadb.de/getgoalgetters/bl1/2022) 95 | 96 | 97 | --- 98 | Die Tabelle ersten Bundesliga 2022/2023 99 | > [https://api.openligadb.de/getbltable/bl1/2022](https://api.openligadb.de/getbltable/bl1/2022) 100 | 101 | 102 | ## Api-Rückgabetypen 103 | 104 | ### Match 105 | Das Match-Objekt enthält alle für ein Spiel relevanten Daten wie der 106 | - *matchID* - eine eindeutige Spiel-ID 107 | - *matchDateTime* - der Startzeitpunkt 108 | - *team1* und *team2* - die beteiligten Teams 109 | - *leaugeId, leagueName, leagueSeason, leagueShortcut* - Informationen über die Liga 110 | - *matchIdFinished* - Information, ob das Spiel beendet ist 111 | - *matchResults* - enthält die Ergebnisse des Spiels in Form eines Arrays von *MatchResult* 112 | - Dieses Array enthält die in den Liga-Einstellungen definierten Ergebnisse des Spiels. So führt folgende Deklaration zu nachfolgendem MatchResults-Array: 113 | ![image](https://user-images.githubusercontent.com/7813965/231270437-2768b27d-2940-4d7b-90ab-303bd9521e6d.png) 114 | ```json 115 | "matchResults": [ 116 | { 117 | "resultID": 98331, 118 | "resultName": "Halbzeitergebnis", 119 | "pointsTeam1": 0, 120 | "pointsTeam2": 1, 121 | "resultOrderID": 1, 122 | "resultTypeID": 1, 123 | "resultDescription": "Ergebnis nach Ende der 1. Halbzeit" 124 | }, 125 | { 126 | "resultID": 98330, 127 | "resultName": "Endergebnis", 128 | "pointsTeam1": 0, 129 | "pointsTeam2": 2, 130 | "resultOrderID": 2, 131 | "resultTypeID": 2, 132 | "resultDescription": "Ergebnis nach Ende des Spiels" 133 | } 134 | ] 135 | ``` 136 | - Die Reihenfolge der Array-Elemente entspricht der deklarierten OrderId, welche auch in *resultOrderID* im Api-Objekt mit ausgegeben wird. Wird eine neue Liga angelegt, sollte die Reihenfolge der Ergebnistypen (und damit der OrderId) der im Spiel auftretenden logischen Abfolge entsprechen. 137 | 138 | - Weiterhin sollte in den Liga-Einstellungen zu jedem Ergebnis der Liga-übergreifendende *Ergebnistyp* festgelegt werden. Dieser ermöglicht es, in jeder Liga der OpenLigaDB beispielsweise nach der *resultTypeID == 1* zu filtern und damit immer das Halbzeitergebnis zu ermitteln. 139 | So erfolgt auch basierend auf der *resultTypeID == 2* die Berechnung der Punkte für die Bundesliga-Tabelle. 140 | 141 | - Zur Abfrage eines spezifischen Ergebnistyps wird empfohlen, die "resultTypeID" zu verwenden und damit unabhängig von der Reihenfolge der matchResults-Elemente zu sein. 142 | - *goals* - die gefallenen Tore 143 | - und einiges mehr - siehe https://api.openligadb.de/ unter "Schemas" 144 | 145 | 146 | -------------------------------------------------------------------------------- /angularjs/angular-with-Results-complete-league.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | OpenLigaDB - Minimal Angularjs-V1-Sample 7 | 8 | 18 | 19 | 20 | 21 |

{{ title }}

22 |

Spielergebnisse, Tore und mehr unter OpenLigaDB!

23 | 24 |
25 | League: 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 50 | 51 | 52 |
SpieltagDatumTeam1Team2Ergebnisse
{{ match.group.groupName}}{{ match.matchDateTime}}{{ match.team1.teamName}}{{ match.team2.teamName}} 46 |
47 | {{ result.resultName}}: {{ result.pointsTeam1}}:{{ result.pointsTeam2}} 48 |
49 |
53 |
54 | 55 | 56 | 57 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /angularjs/angular-with-Results.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | OpenLigaDB - Minimal Angularjs-V1-Sample 7 | 8 | 18 | 19 | 20 | 21 |

{{ title }}

22 |

Spielergebnisse, Tore und mehr unter OpenLigaDB!

23 | 24 |
25 | Spieltag: 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 48 | 49 | 50 |
DatumTeam1Team2Ergebnisse
{{ match.matchDateTime}}{{ match.team1.teamName}}{{ match.team2.teamName}} 44 |
45 | {{ result.resultName}}: {{ result.pointsTeam1}}:{{ result.pointsTeam2}} 46 |
47 |
51 |
52 | 53 | 54 | 55 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /angularjs/minimal-angular-v1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | OpenLigaDB - Minimal Angularjs-V1-Sample 7 | 8 | 18 | 19 | 20 | 21 |

{{ title }}

22 |

Spielergebnisse, Tore und mehr unter OpenLigaDB!

23 | 24 |
25 | Spieltag: 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
DatumTeam1Team2
{{ match.matchDateTime}}{{ match.team1.teamName}}{{ match.team2.teamName}}
45 |
46 | 47 | 48 | 49 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /angularjs/minimal-angular-with-notifications.html: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /csharp/OpenLigaDB.Samples.DemoConsole/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /csharp/OpenLigaDB.Samples.DemoConsole/Match.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace OpenLigaDB.Samples.DemoConsole 8 | { 9 | public class Match 10 | { 11 | public int MatchID { get; set; } 12 | public DateTime MatchDateTime { get; set; } 13 | 14 | public Team Team1 { get; set; } 15 | public Team Team2 { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /csharp/OpenLigaDB.Samples.DemoConsole/OpenLigaDB.Samples.DemoConsole.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {5064F68B-8CEC-4E63-98E7-6B7D543DB9A5} 8 | Exe 9 | Properties 10 | OpenLigaDB.Samples.DemoConsole 11 | OpenLigaDB.Samples.DemoConsole 12 | v4.8 13 | 512 14 | true 15 | 16 | 17 | 18 | AnyCPU 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | ..\packages\Newtonsoft.Json.13.0.3\lib\net45\Newtonsoft.Json.dll 39 | 40 | 41 | 42 | 43 | ..\packages\Microsoft.AspNet.WebApi.Client.5.2.9\lib\net45\System.Net.Http.Formatting.dll 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 70 | -------------------------------------------------------------------------------- /csharp/OpenLigaDB.Samples.DemoConsole/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net.Http; 5 | using System.Net.Http.Headers; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace OpenLigaDB.Samples.DemoConsole 10 | { 11 | class Program 12 | { 13 | static HttpClient client = new HttpClient(); 14 | static void Main() 15 | { 16 | RunAsync().Wait(); 17 | } 18 | 19 | static async Task RunAsync() 20 | { 21 | client.BaseAddress = new Uri("https://api.openligadb.de/"); 22 | client.DefaultRequestHeaders.Accept.Clear(); 23 | client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 24 | 25 | do 26 | { 27 | try 28 | { 29 | var matches = await GetMatchesAsync("getmatchdata/bl1/2022/11"); 30 | 31 | foreach (var match in matches) 32 | { 33 | Console.WriteLine(string.Concat(match.MatchDateTime, ": ", match.Team1.TeamName, " : ", match.Team2.TeamName)); 34 | } 35 | 36 | System.Threading.Thread.Sleep(5000); 37 | } 38 | catch (Exception ex) 39 | { 40 | Console.WriteLine(ex); 41 | System.Threading.Thread.Sleep(5000); 42 | 43 | } 44 | 45 | } while (true); 46 | } 47 | 48 | static async Task> GetMatchesAsync(string path) 49 | { 50 | List matches = null; 51 | HttpResponseMessage response = await client.GetAsync(path); 52 | if (response.IsSuccessStatusCode) 53 | { 54 | matches = await response.Content.ReadAsAsync>(); 55 | } 56 | return matches; 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /csharp/OpenLigaDB.Samples.DemoConsole/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Allgemeine Informationen über eine Assembly werden über die folgenden 6 | // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, 7 | // die einer Assembly zugeordnet sind. 8 | [assembly: AssemblyTitle("OpenLigaDB.Samples.DemoConsole")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("OpenLigaDB.Samples.DemoConsole")] 13 | [assembly: AssemblyCopyright("Copyright © 2016")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar 18 | // für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von 19 | // COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen. 20 | [assembly: ComVisible(false)] 21 | 22 | // Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird 23 | [assembly: Guid("5064f68b-8cec-4e63-98e7-6b7d543db9a5")] 24 | 25 | // Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten: 26 | // 27 | // Hauptversion 28 | // Nebenversion 29 | // Buildnummer 30 | // Revision 31 | // 32 | // Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern 33 | // übernehmen, indem Sie "*" eingeben: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /csharp/OpenLigaDB.Samples.DemoConsole/Team.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace OpenLigaDB.Samples.DemoConsole 8 | { 9 | public class Team 10 | { 11 | public int TeamId { get; set; } 12 | public string TeamName { get; set; } 13 | public string TeamIconUrl { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /csharp/OpenLigaDB.Samples.DemoConsole/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /csharp/OpenLigaDB.Samples.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenLigaDB.Samples.DemoConsole", "OpenLigaDB.Samples.DemoConsole\OpenLigaDB.Samples.DemoConsole.csproj", "{5064F68B-8CEC-4E63-98E7-6B7D543DB9A5}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {5064F68B-8CEC-4E63-98E7-6B7D543DB9A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {5064F68B-8CEC-4E63-98E7-6B7D543DB9A5}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {5064F68B-8CEC-4E63-98E7-6B7D543DB9A5}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {5064F68B-8CEC-4E63-98E7-6B7D543DB9A5}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /javascript/live-server/bun/.gitignore: -------------------------------------------------------------------------------- 1 | # Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore 2 | 3 | # Logs 4 | 5 | logs 6 | _.log 7 | npm-debug.log_ 8 | yarn-debug.log* 9 | yarn-error.log* 10 | lerna-debug.log* 11 | .pnpm-debug.log* 12 | 13 | # Caches 14 | 15 | .cache 16 | 17 | # Diagnostic reports (https://nodejs.org/api/report.html) 18 | 19 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 20 | 21 | # Runtime data 22 | 23 | pids 24 | _.pid 25 | _.seed 26 | *.pid.lock 27 | 28 | # Directory for instrumented libs generated by jscoverage/JSCover 29 | 30 | lib-cov 31 | 32 | # Coverage directory used by tools like istanbul 33 | 34 | coverage 35 | *.lcov 36 | 37 | # nyc test coverage 38 | 39 | .nyc_output 40 | 41 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 42 | 43 | .grunt 44 | 45 | # Bower dependency directory (https://bower.io/) 46 | 47 | bower_components 48 | 49 | # node-waf configuration 50 | 51 | .lock-wscript 52 | 53 | # Compiled binary addons (https://nodejs.org/api/addons.html) 54 | 55 | build/Release 56 | 57 | # Dependency directories 58 | 59 | node_modules/ 60 | jspm_packages/ 61 | 62 | # Snowpack dependency directory (https://snowpack.dev/) 63 | 64 | web_modules/ 65 | 66 | # TypeScript cache 67 | 68 | *.tsbuildinfo 69 | 70 | # Optional npm cache directory 71 | 72 | .npm 73 | 74 | # Optional eslint cache 75 | 76 | .eslintcache 77 | 78 | # Optional stylelint cache 79 | 80 | .stylelintcache 81 | 82 | # Microbundle cache 83 | 84 | .rpt2_cache/ 85 | .rts2_cache_cjs/ 86 | .rts2_cache_es/ 87 | .rts2_cache_umd/ 88 | 89 | # Optional REPL history 90 | 91 | .node_repl_history 92 | 93 | # Output of 'npm pack' 94 | 95 | *.tgz 96 | 97 | # Yarn Integrity file 98 | 99 | .yarn-integrity 100 | 101 | # dotenv environment variable files 102 | 103 | .env 104 | .env.development.local 105 | .env.test.local 106 | .env.production.local 107 | .env.local 108 | 109 | # parcel-bundler cache (https://parceljs.org/) 110 | 111 | .parcel-cache 112 | 113 | # Next.js build output 114 | 115 | .next 116 | out 117 | 118 | # Nuxt.js build / generate output 119 | 120 | .nuxt 121 | dist 122 | 123 | # Gatsby files 124 | 125 | # Comment in the public line in if your project uses Gatsby and not Next.js 126 | 127 | # https://nextjs.org/blog/next-9-1#public-directory-support 128 | 129 | # public 130 | 131 | # vuepress build output 132 | 133 | .vuepress/dist 134 | 135 | # vuepress v2.x temp and cache directory 136 | 137 | .temp 138 | 139 | # Docusaurus cache and generated files 140 | 141 | .docusaurus 142 | 143 | # Serverless directories 144 | 145 | .serverless/ 146 | 147 | # FuseBox cache 148 | 149 | .fusebox/ 150 | 151 | # DynamoDB Local files 152 | 153 | .dynamodb/ 154 | 155 | # TernJS port file 156 | 157 | .tern-port 158 | 159 | # Stores VSCode versions used for testing VSCode extensions 160 | 161 | .vscode-test 162 | 163 | # yarn v2 164 | 165 | .yarn/cache 166 | .yarn/unplugged 167 | .yarn/build-state.yml 168 | .yarn/install-state.gz 169 | .pnp.* 170 | 171 | # IntelliJ based IDEs 172 | .idea 173 | 174 | # Finder (MacOS) folder config 175 | .DS_Store 176 | -------------------------------------------------------------------------------- /javascript/live-server/bun/README.md: -------------------------------------------------------------------------------- 1 | # bun 2 | 3 | To install dependencies: 4 | 5 | ```bash 6 | bun install 7 | ``` 8 | 9 | To run: 10 | 11 | ```bash 12 | bun run index.ts 13 | ``` 14 | 15 | You're connected to OLDB's HiveMQ and receive live updates. 16 | -------------------------------------------------------------------------------- /javascript/live-server/bun/bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenLigaDB/OpenLigaDB-Samples/961e3815afab023abde4f1cd0c6ddc902a059e76/javascript/live-server/bun/bun.lockb -------------------------------------------------------------------------------- /javascript/live-server/bun/bunfig.toml: -------------------------------------------------------------------------------- 1 | [install.scopes] 2 | "@jsr" = "https://npm.jsr.io" 3 | -------------------------------------------------------------------------------- /javascript/live-server/bun/index.ts: -------------------------------------------------------------------------------- 1 | import { OLDB, type OldbData } from "@wgd/oldb"; 2 | 3 | const oldbClient = new OLDB({ 4 | leagueShorts: ['bl1', 'bl2'] 5 | // baseUrl: settings.baseUrl, 6 | // topic: settings.topic, 7 | // port: settings.port 8 | }) 9 | 10 | oldbClient.on('oldb:update', (msg: OldbData) => { 11 | console.log(msg) 12 | }) -------------------------------------------------------------------------------- /javascript/live-server/bun/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bun", 3 | "module": "index.ts", 4 | "type": "module", 5 | "devDependencies": { 6 | "@types/bun": "latest" 7 | }, 8 | "peerDependencies": { 9 | "typescript": "^5.0.0" 10 | }, 11 | "dependencies": { 12 | "@wgd/oldb": "npm:@jsr/wgd__oldb" 13 | } 14 | } -------------------------------------------------------------------------------- /javascript/live-server/bun/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | // Enable latest features 4 | "lib": ["ESNext", "DOM"], 5 | "target": "ESNext", 6 | "module": "ESNext", 7 | "moduleDetection": "force", 8 | "jsx": "react-jsx", 9 | "allowJs": true, 10 | 11 | // Bundler mode 12 | "moduleResolution": "bundler", 13 | "allowImportingTsExtensions": true, 14 | "verbatimModuleSyntax": true, 15 | "noEmit": true, 16 | 17 | // Best practices 18 | "strict": true, 19 | "skipLibCheck": true, 20 | "noFallthroughCasesInSwitch": true, 21 | 22 | // Some stricter flags (disabled by default) 23 | "noUnusedLocals": false, 24 | "noUnusedParameters": false, 25 | "noPropertyAccessFromIndexSignature": false 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /javascript/live-server/node/.npmrc: -------------------------------------------------------------------------------- 1 | @jsr:registry=https://npm.jsr.io 2 | -------------------------------------------------------------------------------- /javascript/live-server/node/README.md: -------------------------------------------------------------------------------- 1 | # node 2 | 3 | To install dependencies: 4 | 5 | ```bash 6 | npm install 7 | ``` 8 | 9 | To run: 10 | 11 | ```bash 12 | npm index.js 13 | ``` 14 | 15 | You're connected to OLDB's HiveMQ and receive live updates. 16 | -------------------------------------------------------------------------------- /javascript/live-server/node/index.js: -------------------------------------------------------------------------------- 1 | import { OLDB } from "@wgd/oldb"; 2 | 3 | const oldbClient = new OLDB({ 4 | leagueShorts: ['bl1', 'em'] 5 | // baseUrl: settings.baseUrl, 6 | // topic: settings.topic, 7 | // port: settings.port 8 | }) 9 | 10 | oldbClient.on('oldb:update', (msg) => { 11 | console.log(msg) 12 | }) -------------------------------------------------------------------------------- /javascript/live-server/node/index.ts: -------------------------------------------------------------------------------- 1 | import { OLDB, type OldbData } from "@wgd/oldb"; 2 | 3 | const oldbClient = new OLDB({ 4 | leagueShorts: ['bl1', 'em'] 5 | // baseUrl: settings.baseUrl, 6 | // topic: settings.topic, 7 | // port: settings.port 8 | }) 9 | 10 | oldbClient.on('oldb:update', (msg: OldbData) => { 11 | console.log(msg) 12 | }) -------------------------------------------------------------------------------- /javascript/live-server/node/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "node", 9 | "version": "1.0.0", 10 | "license": "ISC", 11 | "dependencies": { 12 | "@wgd/oldb": "npm:@jsr/wgd__oldb@^0.2.6" 13 | } 14 | }, 15 | "node_modules/@babel/runtime": { 16 | "version": "7.24.7", 17 | "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz", 18 | "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==", 19 | "dependencies": { 20 | "regenerator-runtime": "^0.14.0" 21 | }, 22 | "engines": { 23 | "node": ">=6.9.0" 24 | } 25 | }, 26 | "node_modules/@types/node": { 27 | "version": "20.14.9", 28 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz", 29 | "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==", 30 | "dependencies": { 31 | "undici-types": "~5.26.4" 32 | } 33 | }, 34 | "node_modules/@types/readable-stream": { 35 | "version": "4.0.14", 36 | "resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.14.tgz", 37 | "integrity": "sha512-xZn/AuUbCMShGsqH/ehZtGDwQtbx00M9rZ2ENLe4tOjFZ/JFeWMhEZkk2fEe1jAUqqEAURIkFJ7Az/go8mM1/w==", 38 | "dependencies": { 39 | "@types/node": "*", 40 | "safe-buffer": "~5.1.1" 41 | } 42 | }, 43 | "node_modules/@types/ws": { 44 | "version": "8.5.10", 45 | "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz", 46 | "integrity": "sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==", 47 | "dependencies": { 48 | "@types/node": "*" 49 | } 50 | }, 51 | "node_modules/@wgd/oldb": { 52 | "name": "@jsr/wgd__oldb", 53 | "version": "0.2.6", 54 | "resolved": "https://npm.jsr.io/~/11/@jsr/wgd__oldb/0.2.6.tgz", 55 | "integrity": "sha512-fRlwHv1DSMobEGYvQe5kryBg3lSYAK5OiBVnWpZCAUAVY0It9vvWpdiNjmyrNaMUiHuyxtTvJLunspnMZovwyA==", 56 | "dependencies": { 57 | "mitt": "^3.0.1", 58 | "mqtt": "^5.6.2" 59 | } 60 | }, 61 | "node_modules/abort-controller": { 62 | "version": "3.0.0", 63 | "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", 64 | "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", 65 | "dependencies": { 66 | "event-target-shim": "^5.0.0" 67 | }, 68 | "engines": { 69 | "node": ">=6.5" 70 | } 71 | }, 72 | "node_modules/base64-js": { 73 | "version": "1.5.1", 74 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 75 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", 76 | "funding": [ 77 | { 78 | "type": "github", 79 | "url": "https://github.com/sponsors/feross" 80 | }, 81 | { 82 | "type": "patreon", 83 | "url": "https://www.patreon.com/feross" 84 | }, 85 | { 86 | "type": "consulting", 87 | "url": "https://feross.org/support" 88 | } 89 | ] 90 | }, 91 | "node_modules/bl": { 92 | "version": "6.0.13", 93 | "resolved": "https://registry.npmjs.org/bl/-/bl-6.0.13.tgz", 94 | "integrity": "sha512-tMncAcpsyjZgAVbVFupVIaB2xud13xxT59fdHkuszY2jdZkqIWfpQdmII1fOe3kOGAz0mNLTIHEm+KxpYsQKKg==", 95 | "dependencies": { 96 | "@types/readable-stream": "^4.0.0", 97 | "buffer": "^6.0.3", 98 | "inherits": "^2.0.4", 99 | "readable-stream": "^4.2.0" 100 | } 101 | }, 102 | "node_modules/buffer": { 103 | "version": "6.0.3", 104 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", 105 | "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", 106 | "funding": [ 107 | { 108 | "type": "github", 109 | "url": "https://github.com/sponsors/feross" 110 | }, 111 | { 112 | "type": "patreon", 113 | "url": "https://www.patreon.com/feross" 114 | }, 115 | { 116 | "type": "consulting", 117 | "url": "https://feross.org/support" 118 | } 119 | ], 120 | "dependencies": { 121 | "base64-js": "^1.3.1", 122 | "ieee754": "^1.2.1" 123 | } 124 | }, 125 | "node_modules/buffer-from": { 126 | "version": "1.1.2", 127 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", 128 | "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" 129 | }, 130 | "node_modules/commist": { 131 | "version": "3.2.0", 132 | "resolved": "https://registry.npmjs.org/commist/-/commist-3.2.0.tgz", 133 | "integrity": "sha512-4PIMoPniho+LqXmpS5d3NuGYncG6XWlkBSVGiWycL22dd42OYdUGil2CWuzklaJoNxyxUSpO4MKIBU94viWNAw==" 134 | }, 135 | "node_modules/concat-stream": { 136 | "version": "2.0.0", 137 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", 138 | "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", 139 | "engines": [ 140 | "node >= 6.0" 141 | ], 142 | "dependencies": { 143 | "buffer-from": "^1.0.0", 144 | "inherits": "^2.0.3", 145 | "readable-stream": "^3.0.2", 146 | "typedarray": "^0.0.6" 147 | } 148 | }, 149 | "node_modules/concat-stream/node_modules/readable-stream": { 150 | "version": "3.6.2", 151 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", 152 | "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", 153 | "dependencies": { 154 | "inherits": "^2.0.3", 155 | "string_decoder": "^1.1.1", 156 | "util-deprecate": "^1.0.1" 157 | }, 158 | "engines": { 159 | "node": ">= 6" 160 | } 161 | }, 162 | "node_modules/debug": { 163 | "version": "4.3.5", 164 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", 165 | "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", 166 | "dependencies": { 167 | "ms": "2.1.2" 168 | }, 169 | "engines": { 170 | "node": ">=6.0" 171 | }, 172 | "peerDependenciesMeta": { 173 | "supports-color": { 174 | "optional": true 175 | } 176 | } 177 | }, 178 | "node_modules/event-target-shim": { 179 | "version": "5.0.1", 180 | "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", 181 | "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", 182 | "engines": { 183 | "node": ">=6" 184 | } 185 | }, 186 | "node_modules/events": { 187 | "version": "3.3.0", 188 | "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", 189 | "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", 190 | "engines": { 191 | "node": ">=0.8.x" 192 | } 193 | }, 194 | "node_modules/fast-unique-numbers": { 195 | "version": "8.0.13", 196 | "resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-8.0.13.tgz", 197 | "integrity": "sha512-7OnTFAVPefgw2eBJ1xj2PGGR9FwYzSUso9decayHgCDX4sJkHLdcsYTytTg+tYv+wKF3U8gJuSBz2jJpQV4u/g==", 198 | "dependencies": { 199 | "@babel/runtime": "^7.23.8", 200 | "tslib": "^2.6.2" 201 | }, 202 | "engines": { 203 | "node": ">=16.1.0" 204 | } 205 | }, 206 | "node_modules/help-me": { 207 | "version": "5.0.0", 208 | "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", 209 | "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==" 210 | }, 211 | "node_modules/ieee754": { 212 | "version": "1.2.1", 213 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 214 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", 215 | "funding": [ 216 | { 217 | "type": "github", 218 | "url": "https://github.com/sponsors/feross" 219 | }, 220 | { 221 | "type": "patreon", 222 | "url": "https://www.patreon.com/feross" 223 | }, 224 | { 225 | "type": "consulting", 226 | "url": "https://feross.org/support" 227 | } 228 | ] 229 | }, 230 | "node_modules/inherits": { 231 | "version": "2.0.4", 232 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 233 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 234 | }, 235 | "node_modules/js-sdsl": { 236 | "version": "4.3.0", 237 | "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.3.0.tgz", 238 | "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==", 239 | "funding": { 240 | "type": "opencollective", 241 | "url": "https://opencollective.com/js-sdsl" 242 | } 243 | }, 244 | "node_modules/lru-cache": { 245 | "version": "10.2.2", 246 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", 247 | "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", 248 | "engines": { 249 | "node": "14 || >=16.14" 250 | } 251 | }, 252 | "node_modules/minimist": { 253 | "version": "1.2.8", 254 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", 255 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", 256 | "funding": { 257 | "url": "https://github.com/sponsors/ljharb" 258 | } 259 | }, 260 | "node_modules/mitt": { 261 | "version": "3.0.1", 262 | "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", 263 | "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==" 264 | }, 265 | "node_modules/mqtt": { 266 | "version": "5.7.3", 267 | "resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.7.3.tgz", 268 | "integrity": "sha512-v+5la6Q6zjl0AWsI7ICDA/K3hclkNj7CMa0khMugCC+LKPLrQF+sSQb/9ckezZLMvcBC1tXhRzqmcagQoDl9fQ==", 269 | "dependencies": { 270 | "@types/readable-stream": "^4.0.5", 271 | "@types/ws": "^8.5.9", 272 | "commist": "^3.2.0", 273 | "concat-stream": "^2.0.0", 274 | "debug": "^4.3.4", 275 | "help-me": "^5.0.0", 276 | "lru-cache": "^10.0.1", 277 | "minimist": "^1.2.8", 278 | "mqtt": "^5.2.0", 279 | "mqtt-packet": "^9.0.0", 280 | "number-allocator": "^1.0.14", 281 | "readable-stream": "^4.4.2", 282 | "reinterval": "^1.1.0", 283 | "rfdc": "^1.3.0", 284 | "split2": "^4.2.0", 285 | "worker-timers": "^7.1.4", 286 | "ws": "^8.17.1" 287 | }, 288 | "bin": { 289 | "mqtt": "build/bin/mqtt.js", 290 | "mqtt_pub": "build/bin/pub.js", 291 | "mqtt_sub": "build/bin/sub.js" 292 | }, 293 | "engines": { 294 | "node": ">=16.0.0" 295 | } 296 | }, 297 | "node_modules/mqtt-packet": { 298 | "version": "9.0.0", 299 | "resolved": "https://registry.npmjs.org/mqtt-packet/-/mqtt-packet-9.0.0.tgz", 300 | "integrity": "sha512-8v+HkX+fwbodsWAZIZTI074XIoxVBOmPeggQuDFCGg1SqNcC+uoRMWu7J6QlJPqIUIJXmjNYYHxBBLr1Y/Df4w==", 301 | "dependencies": { 302 | "bl": "^6.0.8", 303 | "debug": "^4.3.4", 304 | "process-nextick-args": "^2.0.1" 305 | } 306 | }, 307 | "node_modules/ms": { 308 | "version": "2.1.2", 309 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 310 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 311 | }, 312 | "node_modules/number-allocator": { 313 | "version": "1.0.14", 314 | "resolved": "https://registry.npmjs.org/number-allocator/-/number-allocator-1.0.14.tgz", 315 | "integrity": "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==", 316 | "dependencies": { 317 | "debug": "^4.3.1", 318 | "js-sdsl": "4.3.0" 319 | } 320 | }, 321 | "node_modules/process": { 322 | "version": "0.11.10", 323 | "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", 324 | "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", 325 | "engines": { 326 | "node": ">= 0.6.0" 327 | } 328 | }, 329 | "node_modules/process-nextick-args": { 330 | "version": "2.0.1", 331 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 332 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 333 | }, 334 | "node_modules/readable-stream": { 335 | "version": "4.5.2", 336 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz", 337 | "integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==", 338 | "dependencies": { 339 | "abort-controller": "^3.0.0", 340 | "buffer": "^6.0.3", 341 | "events": "^3.3.0", 342 | "process": "^0.11.10", 343 | "string_decoder": "^1.3.0" 344 | }, 345 | "engines": { 346 | "node": "^12.22.0 || ^14.17.0 || >=16.0.0" 347 | } 348 | }, 349 | "node_modules/regenerator-runtime": { 350 | "version": "0.14.1", 351 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", 352 | "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" 353 | }, 354 | "node_modules/reinterval": { 355 | "version": "1.1.0", 356 | "resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz", 357 | "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==" 358 | }, 359 | "node_modules/rfdc": { 360 | "version": "1.4.1", 361 | "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", 362 | "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==" 363 | }, 364 | "node_modules/safe-buffer": { 365 | "version": "5.1.2", 366 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 367 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 368 | }, 369 | "node_modules/split2": { 370 | "version": "4.2.0", 371 | "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", 372 | "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", 373 | "engines": { 374 | "node": ">= 10.x" 375 | } 376 | }, 377 | "node_modules/string_decoder": { 378 | "version": "1.3.0", 379 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", 380 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 381 | "dependencies": { 382 | "safe-buffer": "~5.2.0" 383 | } 384 | }, 385 | "node_modules/string_decoder/node_modules/safe-buffer": { 386 | "version": "5.2.1", 387 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 388 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 389 | "funding": [ 390 | { 391 | "type": "github", 392 | "url": "https://github.com/sponsors/feross" 393 | }, 394 | { 395 | "type": "patreon", 396 | "url": "https://www.patreon.com/feross" 397 | }, 398 | { 399 | "type": "consulting", 400 | "url": "https://feross.org/support" 401 | } 402 | ] 403 | }, 404 | "node_modules/tslib": { 405 | "version": "2.6.3", 406 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", 407 | "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==" 408 | }, 409 | "node_modules/typedarray": { 410 | "version": "0.0.6", 411 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", 412 | "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" 413 | }, 414 | "node_modules/undici-types": { 415 | "version": "5.26.5", 416 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 417 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" 418 | }, 419 | "node_modules/util-deprecate": { 420 | "version": "1.0.2", 421 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 422 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" 423 | }, 424 | "node_modules/worker-timers": { 425 | "version": "7.1.8", 426 | "resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-7.1.8.tgz", 427 | "integrity": "sha512-R54psRKYVLuzff7c1OTFcq/4Hue5Vlz4bFtNEIarpSiCYhpifHU3aIQI29S84o1j87ePCYqbmEJPqwBTf+3sfw==", 428 | "dependencies": { 429 | "@babel/runtime": "^7.24.5", 430 | "tslib": "^2.6.2", 431 | "worker-timers-broker": "^6.1.8", 432 | "worker-timers-worker": "^7.0.71" 433 | } 434 | }, 435 | "node_modules/worker-timers-broker": { 436 | "version": "6.1.8", 437 | "resolved": "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-6.1.8.tgz", 438 | "integrity": "sha512-FUCJu9jlK3A8WqLTKXM9E6kAmI/dR1vAJ8dHYLMisLNB/n3GuaFIjJ7pn16ZcD1zCOf7P6H62lWIEBi+yz/zQQ==", 439 | "dependencies": { 440 | "@babel/runtime": "^7.24.5", 441 | "fast-unique-numbers": "^8.0.13", 442 | "tslib": "^2.6.2", 443 | "worker-timers-worker": "^7.0.71" 444 | } 445 | }, 446 | "node_modules/worker-timers-worker": { 447 | "version": "7.0.71", 448 | "resolved": "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-7.0.71.tgz", 449 | "integrity": "sha512-ks/5YKwZsto1c2vmljroppOKCivB/ma97g9y77MAAz2TBBjPPgpoOiS1qYQKIgvGTr2QYPT3XhJWIB6Rj2MVPQ==", 450 | "dependencies": { 451 | "@babel/runtime": "^7.24.5", 452 | "tslib": "^2.6.2" 453 | } 454 | }, 455 | "node_modules/ws": { 456 | "version": "8.17.1", 457 | "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", 458 | "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", 459 | "engines": { 460 | "node": ">=10.0.0" 461 | }, 462 | "peerDependencies": { 463 | "bufferutil": "^4.0.1", 464 | "utf-8-validate": ">=5.0.2" 465 | }, 466 | "peerDependenciesMeta": { 467 | "bufferutil": { 468 | "optional": true 469 | }, 470 | "utf-8-validate": { 471 | "optional": true 472 | } 473 | } 474 | } 475 | } 476 | } 477 | -------------------------------------------------------------------------------- /javascript/live-server/node/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "type": "module", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "description": "", 13 | "dependencies": { 14 | "@wgd/oldb": "npm:@jsr/wgd__oldb@^0.2.6" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /php/openligadb-example.php: -------------------------------------------------------------------------------- 1 | 0 && $spieltag <= $matchCount) { 10 | $current = $spieltag; 11 | } else { 12 | $error = true; 13 | } 14 | } 15 | 16 | // Retrieve the data for the current matchday from the OpenLigaDB API 17 | $url = sprintf("https://api.openligadb.de/getmatchdata/bl1/2022/%d", $current); 18 | $ch = curl_init(); 19 | curl_setopt($ch, CURLOPT_URL, $url); 20 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 21 | 22 | $output = curl_exec($ch); 23 | 24 | if ($output === false) { 25 | die("Error when requesting the API: " . curl_error($ch)); 26 | } 27 | 28 | curl_close($ch); 29 | 30 | // Decoding the API response 31 | $matches = json_decode($output, true); 32 | 33 | if ($matches === null) { 34 | die("Error processing API response: " . json_last_error_msg()); 35 | } 36 | ?> 37 | 38 | 39 | 40 | 41 | OpenLigaDB - PHP Sample 42 | 43 | 60 | 61 | 62 | 63 |

Fußballdaten per PHP abrufen

64 |

Spielergebnisse, Tore und mehr unter OpenLigaDB!

65 | 66 |
67 |
"> 68 | 69 | " type="text" id="spieltag" name="spieltag"/> 70 | 71 |
72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 84 | 85 | 86 | 87 | 88 | 89 | 92 | 93 |
DatumTeam1Team2
94 |
95 | 96 | 97 | -------------------------------------------------------------------------------- /react/.babelrc: -------------------------------------------------------------------------------- 1 | { "presets": ["es2015", "react"] } 2 | -------------------------------------------------------------------------------- /react/app/components/Game.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import {Card, CardText} from 'material-ui/Card'; 3 | 4 | const Game = (props) => { 5 | 6 | const { 7 | homeiconsrc, 8 | guesticonsrc, 9 | hometeamname, 10 | guestteamname, 11 | isGameFinished, 12 | hometeamgoals, 13 | guestteamgoals 14 | } = props; 15 | 16 | const style = { 17 | imgStyle: { 18 | height: '75px', 19 | padding: '10px' 20 | }, 21 | imgDiv: { 22 | display: 'flex', 23 | justifyContent: 'center' 24 | }, 25 | nameDiv: { 26 | display: 'flex', 27 | justifyContent: 'center', 28 | padding: '20px' 29 | } 30 | }; 31 | 32 | let homeGoals = isGameFinished ? hometeamgoals : '-'; 33 | let guestGoals = isGameFinished ? guestteamgoals : '-'; 34 | 35 | return ( 36 |
37 | 38 | 39 |
40 | 45 | 50 |
51 |
52 |

{hometeamname}

53 |

:

54 |

{guestteamname}

55 |
56 |
57 |

{homeGoals}

58 |

59 |

{guestGoals}

60 |
61 |
62 |
63 |
64 | ); 65 | } 66 | 67 | export default Game; 68 | -------------------------------------------------------------------------------- /react/app/components/Games.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import axios from 'axios'; 3 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 4 | import Game from './Game.jsx' 5 | 6 | export default class Games extends React.Component{ 7 | 8 | constructor(props){ 9 | super(props); 10 | 11 | this.state = { 12 | games: [] 13 | }; 14 | 15 | this.fetchAllGames = this.fetchAllGames.bind(this); 16 | } 17 | 18 | fetchAllGames(){ 19 | 20 | return axios.get(this.props.url); 21 | } 22 | 23 | componentDidMount(){ 24 | this.fetchAllGames() 25 | .then(result => { 26 | this.setState({ 27 | games: result.data 28 | }); 29 | }) 30 | .catch(error => { 31 | return error; 32 | }); 33 | } 34 | 35 | render(){ 36 | 37 | const listOfGames = this.state.games.map((game, index) => { 38 | 39 | const props = { 40 | key: game.MatchID, 41 | homeiconsrc: game.Team1.TeamIconUrl, 42 | guesticonsrc: game.Team2.TeamIconUrl, 43 | hometeamname: game.Team1.TeamName, 44 | guestteamname: game.Team2.TeamName, 45 | isGameFinished: game.MatchIsFinished, 46 | hometeamgoals: game.MatchResults[1].PointsTeam1, 47 | guestteamgoals: game.MatchResults[1].PointsTeam2 48 | } 49 | 50 | return ( 51 | 52 | ); 53 | }); 54 | 55 | return( 56 | 57 |
58 | {listOfGames} 59 |
60 |
61 | ); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /react/app/index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import Games from './components/Games.jsx'; 4 | 5 | ReactDOM.render( 6 | , 7 | document.getElementById('app') 8 | ); 9 | -------------------------------------------------------------------------------- /react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "OpenLigaDB-GameCard", 3 | "version": "1.0.0", 4 | "main": "app/index.jsx", 5 | "dependencies": { 6 | "react": "^15.4.2", 7 | "react-dom": "^15.4.2" 8 | }, 9 | "devDependencies": { 10 | "axios": "^0.19.0", 11 | "axios-mock-adapter": "^1.8.1", 12 | "babel-cli": "^6.24.0", 13 | "babel-core": "^6.24.1", 14 | "babel-loader": "^7.0.0", 15 | "babel-preset-es2015": "^6.24.0", 16 | "babel-preset-react": "^6.23.0", 17 | "chai": "^3.5.0", 18 | "enzyme": "^2.4.1", 19 | "jsdom": "^9.4.1", 20 | "material-ui": "^0.18.1", 21 | "mocha": "^2.5.3", 22 | "react-dom": "^15.5.4", 23 | "react-test-renderer": "^15.5.4", 24 | "sinon": "^2.2.0", 25 | "webpack": "^2.1.0-beta.27", 26 | "webpack-dev-server": "^1.14.1" 27 | }, 28 | "scripts": { 29 | "start": "webpack-dev-server --content-base public", 30 | "test": "mocha --compilers js:babel-core/register --require test/test-setup.js test/*/*.test.js" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /react/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | OpenLigaDB React.js example 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /react/test/components/Game.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { shallow, mount } from 'enzyme'; 3 | import sinon from 'sinon'; 4 | import { expect } from 'chai'; 5 | import Game from '../../app/components/Game.jsx'; 6 | 7 | describe('The component',() => { 8 | 9 | let wrapper; 10 | 11 | before(() => { 12 | wrapper = shallow(); 13 | }); 14 | 15 | it('Must render a ',() => { 16 | expect(wrapper.find('Card')).to.have.length(1); 17 | }); 18 | 19 | it('Must render a ',() => { 20 | expect(wrapper.find('Card').find('CardText')).to.have.length(1); 21 | }); 22 | 23 | describe('Must display icon of hometeam',() => { 24 | 25 | it('Must render the homeicon',() => { 26 | expect(wrapper.find('img#homeicon')).to.have.length(1); 27 | }); 28 | 29 | it('homeicon must have src of props.homeiconsrc',() => { 30 | wrapper = shallow(); 31 | expect(wrapper.find('img#homeicon').prop('src')).to.equal('beautifulIcon.png'); 32 | }); 33 | 34 | }); 35 | 36 | describe('Must display icon of guestteam',() => { 37 | 38 | it('Must render the guesticon',() => { 39 | expect(wrapper.find('img#guesticon')).to.have.length(1); 40 | }); 41 | 42 | it('homeicon must have src of props.guesticonsrc',() => { 43 | wrapper = shallow(); 44 | expect(wrapper.find('img#guesticon').prop('src')).to.equal('beautifulIconTwo.JPEG'); 45 | }); 46 | 47 | }); 48 | 49 | describe('Must display name of hometeam',() => { 50 | 51 | it('Must render the name of the hometeam',() => { 52 | expect(wrapper.find('#hometeamname')).to.have.length(1); 53 | }); 54 | 55 | it('hometeamname must have text of props.hometeamname',() => { 56 | wrapper = shallow(); 57 | expect(wrapper.find('#hometeamname').text()).to.equal('Team01'); 58 | }); 59 | 60 | }); 61 | 62 | describe('Must display name of guestteam',() => { 63 | 64 | it('Must render the name of the guestteam',() => { 65 | expect(wrapper.find('#guestteamname')).to.have.length(1); 66 | }); 67 | 68 | it('guestteamname must have text of props.guestteamname',() => { 69 | wrapper = shallow(); 70 | expect(wrapper.find('#guestteamname').text()).to.equal('Whatever'); 71 | }); 72 | 73 | }); 74 | 75 | describe('Must display goals of hometeam',() => { 76 | 77 | it('Must render the hometeam goals',() => { 78 | expect(wrapper.find('#hometeamgoals')).to.have.length(1); 79 | }); 80 | 81 | describe('hometeamgoals must have value of props.hometeamgoals',() => { 82 | 83 | it('goals must be displayed if game is finished',() => { 84 | const testProps = { 85 | isGameFinished: true, 86 | hometeamgoals: 99 87 | } 88 | wrapper = shallow(); 89 | expect(wrapper.find('#hometeamgoals').text()).to.equal('99'); 90 | }); 91 | 92 | it('no goals must be displayed if game is not finished',() => { 93 | const testProps = { 94 | isGameFinished: false, 95 | hometeamgoals: 13 96 | } 97 | wrapper = shallow(); 98 | expect(wrapper.find('#hometeamgoals').text()).to.equal('-'); 99 | }); 100 | 101 | }); 102 | 103 | }); 104 | 105 | describe('Must display goals of guestteam',() => { 106 | 107 | it('Must render the guestteam goals',() => { 108 | expect(wrapper.find('#guestteamgoals')).to.have.length(1); 109 | }); 110 | 111 | describe('guestteamgoals must have value of props.guestteamgoals',() => { 112 | 113 | it('goals must be displayed if game is finished',() => { 114 | const testProps = { 115 | isGameFinished: true, 116 | guestteamgoals: 7 117 | } 118 | wrapper = shallow(); 119 | expect(wrapper.find('#guestteamgoals').text()).to.equal('7'); 120 | }); 121 | 122 | it('no goals must be displayed if game is not finished',() => { 123 | const testProps = { 124 | isGameFinished: false, 125 | guestteamgoals: 7 126 | } 127 | wrapper = shallow(); 128 | expect(wrapper.find('#guestteamgoals').text()).to.equal('-'); 129 | }); 130 | 131 | }); 132 | }); 133 | 134 | }); 135 | -------------------------------------------------------------------------------- /react/test/components/Games.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { shallow, mount } from 'enzyme'; 3 | import sinon from 'sinon'; 4 | import { expect } from 'chai'; 5 | import axios from 'axios'; 6 | import MockAdapter from 'axios-mock-adapter'; 7 | import Games from '../../app/components/Games.jsx'; 8 | 9 | describe('Games',() => { 10 | 11 | it('must have [] as default value for state.games',() => { 12 | const wrapper = shallow(); 13 | expect(wrapper.state().games).to.have.length(0); 14 | }); 15 | 16 | describe('API call on componentDidMount',() => { 17 | 18 | it('must call ´fetchAllGames´ when component is loaded',() => { 19 | let spyForAPICall = sinon.spy(Games.prototype, 'fetchAllGames'); 20 | 21 | const wrapper = mount(); 22 | 23 | expect(spyForAPICall.calledOnce).to.be.true; 24 | 25 | spyForAPICall.restore(); 26 | }); 27 | 28 | it('must call ´axios.get()´ with props.url',() => { 29 | let spyForAxiosCall = sinon.spy(axios, 'get'); 30 | 31 | const wrapper = mount(); 32 | 33 | expect(spyForAxiosCall.calledWith("validUrl")).to.be.true; 34 | 35 | spyForAxiosCall.restore(); 36 | }); 37 | 38 | describe('when API call successful',() => { 39 | 40 | let mock, 41 | stubResponse, 42 | wrapper; 43 | 44 | before(() => { 45 | mock = new MockAdapter(axios); 46 | stubResponse = require('../testUtils/validStubResponse.json'); 47 | 48 | mock.onGet('validUrl').reply(200, stubResponse); 49 | 50 | wrapper = mount(); 51 | }); 52 | 53 | after(() => { 54 | mock.restore(); 55 | }); 56 | 57 | it('must update the state.game if API call was successfull',() => { 58 | 59 | return wrapper.instance().fetchAllGames().then(resp => { 60 | expect(resp.data).not.to.be.null; 61 | expect(resp.data).not.to.be.undefined; 62 | expect(wrapper.state().games).to.equal(resp.data); 63 | }); 64 | 65 | }); 66 | 67 | it('must render prop homeiconsrc to component',() => { 68 | 69 | return wrapper.instance().fetchAllGames().then(resp => { 70 | expect(wrapper.find('Game').at(0).prop('homeiconsrc')).to.equal("http://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Chemnitzer_FC_Logo.svg/200px-Chemnitzer_FC_Logo.svg.png"); 71 | }); 72 | 73 | }); 74 | 75 | it('must render prop guesticonsrc to component',() => { 76 | 77 | return wrapper.instance().fetchAllGames().then(resp => { 78 | expect(wrapper.find('Game').at(0).prop('guesticonsrc')).to.equal("http://www.openligadb.de/images/teamicons/MSV_Duisburg.gif"); 79 | }); 80 | 81 | }); 82 | 83 | it('must render prop hometeamname to component',() => { 84 | 85 | return wrapper.instance().fetchAllGames().then(resp => { 86 | expect(wrapper.find('Game').at(0).prop('hometeamname')).to.equal("Chemnitzer FC"); 87 | }); 88 | 89 | }); 90 | 91 | it('must render prop guestteamname to component',() => { 92 | 93 | return wrapper.instance().fetchAllGames().then(resp => { 94 | expect(wrapper.find('Game').at(0).prop('guestteamname')).to.equal("MSV Duisburg"); 95 | }); 96 | 97 | }); 98 | 99 | it('must render prop isGameFinished to component',() => { 100 | return wrapper.instance().fetchAllGames().then(resp => { 101 | expect(wrapper.find('Game').at(0).prop('isGameFinished')).to.equal(true); 102 | }); 103 | }); 104 | 105 | it('must render prop hometeamgoals to component',() => { 106 | return wrapper.instance().fetchAllGames().then(resp => { 107 | expect(wrapper.find('Game').at(0).prop('hometeamgoals')).to.equal(2); 108 | }); 109 | }); 110 | 111 | it('must render prop guestteamgoals to component',() => { 112 | return wrapper.instance().fetchAllGames().then(resp => { 113 | expect(wrapper.find('Game').at(0).prop('guestteamgoals')).to.equal(3); 114 | }); 115 | }); 116 | 117 | }); 118 | 119 | it('must not update the state.game if API call was not successfull',() => { 120 | const mock = new MockAdapter(axios); 121 | 122 | mock.onGet('invalidUrl').reply(404); 123 | 124 | const wrapper = mount(); 125 | 126 | return wrapper.instance().fetchAllGames().catch(error => { 127 | expect(wrapper.state().games).to.have.length(0); 128 | }); 129 | 130 | mock.restore(); 131 | }); 132 | 133 | }); 134 | 135 | describe('render function', function(){ 136 | 137 | let wrapper; 138 | 139 | before(() => { 140 | wrapper = shallow(); 141 | }); 142 | 143 | it('must render a ',() => { 144 | expect(wrapper.find('MuiThemeProvider')).to.have.length(1); 145 | }); 146 | 147 | describe('must render as much elements as games are available',() => { 148 | 149 | it('for 0 games',() => { 150 | wrapper.setState({ 151 | games: [] 152 | }); 153 | 154 | expect(wrapper.find('MuiThemeProvider').find('Game')).to.have.length(0); 155 | }); 156 | 157 | it('for 1 game',() => { 158 | const oneGameStub = require('../testUtils/validStubResponse.json'); 159 | 160 | wrapper.setState({ 161 | games: oneGameStub 162 | }); 163 | 164 | expect(wrapper.find('MuiThemeProvider').find('Game')).to.have.length(1); 165 | }); 166 | 167 | it('for 3 games',() => { 168 | const multipleGamesStub = require('../testUtils/multipleStubResponse.json'); 169 | 170 | wrapper.setState({ 171 | games: multipleGamesStub 172 | }); 173 | 174 | expect(wrapper.find('MuiThemeProvider').find('Game')).to.have.length(3); 175 | }); 176 | 177 | }); 178 | 179 | }); 180 | 181 | }); 182 | -------------------------------------------------------------------------------- /react/test/test-setup.js: -------------------------------------------------------------------------------- 1 | var jsdom = require('jsdom').jsdom; 2 | 3 | var exposedProperties = ['window', 'navigator', 'document']; 4 | 5 | global.document = jsdom(''); 6 | global.window = document.defaultView; 7 | Object.keys(document.defaultView).forEach((property) => { 8 | if (typeof global[property] === 'undefined') { 9 | exposedProperties.push(property); 10 | global[property] = document.defaultView[property]; 11 | } 12 | }); 13 | 14 | global.navigator = { 15 | userAgent: 'node.js' 16 | }; -------------------------------------------------------------------------------- /react/test/testUtils/multipleStubResponse.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "MatchID":40493, 4 | "MatchDateTime":"2017-03-25T14:00:00", 5 | "TimeZoneID":"W. Europe Standard Time", 6 | "LeagueId":3015, 7 | "MatchDateTimeUTC":"2017-03-25T13:00:00Z", 8 | "Group":{ 9 | "GroupName":"29. Spieltag", 10 | "GroupOrderID":29, 11 | "GroupID":24084 12 | }, 13 | "Team1":{ 14 | "TeamId":202, 15 | "TeamName":"Chemnitzer FC", 16 | "ShortName":"", 17 | "TeamIconUrl":"http://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Chemnitzer_FC_Logo.svg/200px-Chemnitzer_FC_Logo.svg.png" 18 | }, 19 | "Team2":{ 20 | "TeamId":107, 21 | "TeamName":"MSV Duisburg", 22 | "ShortName":"", 23 | "TeamIconUrl":"http://www.openligadb.de/images/teamicons/MSV_Duisburg.gif" 24 | }, 25 | "LastUpdateDateTime":"2017-03-25T15:56:09.103", 26 | "MatchIsFinished":true, 27 | "MatchResults":[ 28 | { 29 | "ResultID":73601, 30 | "ResultName":"Halbzeitergebnis", 31 | "PointsTeam1":1, 32 | "PointsTeam2":1, 33 | "ResultOrderID":1, 34 | "ResultTypeID":1, 35 | "ResultDescription":"Ergebnis nach Ende der ersten Halbzeit" 36 | }, 37 | { 38 | "ResultID":73616, 39 | "ResultName":"Endergebnis", 40 | "PointsTeam1":2, 41 | "PointsTeam2":3, 42 | "ResultOrderID":2, 43 | "ResultTypeID":2, 44 | "ResultDescription":"Ergebnis nach Ende der offiziellen Spielzeit" 45 | } 46 | ], 47 | "Goals":[ 48 | { 49 | "GoalID":58341, 50 | "ScoreTeam1":0, 51 | "ScoreTeam2":1, 52 | "MatchMinute":23, 53 | "GoalGetterID":2319, 54 | "GoalGetterName":"Wiegel", 55 | "IsPenalty":false, 56 | "IsOwnGoal":false, 57 | "IsOvertime":false, 58 | "Comment":null 59 | }, 60 | { 61 | "GoalID":58342, 62 | "ScoreTeam1":1, 63 | "ScoreTeam2":1, 64 | "MatchMinute":41, 65 | "GoalGetterID":14383, 66 | "GoalGetterName":"Türpitz", 67 | "IsPenalty":false, 68 | "IsOwnGoal":false, 69 | "IsOvertime":false, 70 | "Comment":null 71 | }, 72 | { 73 | "GoalID":58352, 74 | "ScoreTeam1":2, 75 | "ScoreTeam2":1, 76 | "MatchMinute":52, 77 | "GoalGetterID":14383, 78 | "GoalGetterName":"Türpitz", 79 | "IsPenalty":false, 80 | "IsOwnGoal":false, 81 | "IsOvertime":false, 82 | "Comment":null 83 | }, 84 | { 85 | "GoalID":58353, 86 | "ScoreTeam1":2, 87 | "ScoreTeam2":2, 88 | "MatchMinute":68, 89 | "GoalGetterID":11438, 90 | "GoalGetterName":"Brandstetter", 91 | "IsPenalty":false, 92 | "IsOwnGoal":false, 93 | "IsOvertime":false, 94 | "Comment":null 95 | }, 96 | { 97 | "GoalID":58354, 98 | "ScoreTeam1":2, 99 | "ScoreTeam2":3, 100 | "MatchMinute":74, 101 | "GoalGetterID":1394, 102 | "GoalGetterName":"Onuegbu", 103 | "IsPenalty":false, 104 | "IsOwnGoal":false, 105 | "IsOvertime":false, 106 | "Comment":null 107 | } 108 | ], 109 | "Location":null, 110 | "NumberOfViewers":null 111 | }, 112 | { 113 | "MatchID":40493, 114 | "MatchDateTime":"2017-03-25T14:00:00", 115 | "TimeZoneID":"W. Europe Standard Time", 116 | "LeagueId":3015, 117 | "MatchDateTimeUTC":"2017-03-25T13:00:00Z", 118 | "Group":{ 119 | "GroupName":"29. Spieltag", 120 | "GroupOrderID":29, 121 | "GroupID":24084 122 | }, 123 | "Team1":{ 124 | "TeamId":202, 125 | "TeamName":"Chemnitzer FC", 126 | "ShortName":"", 127 | "TeamIconUrl":"http://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Chemnitzer_FC_Logo.svg/200px-Chemnitzer_FC_Logo.svg.png" 128 | }, 129 | "Team2":{ 130 | "TeamId":107, 131 | "TeamName":"MSV Duisburg", 132 | "ShortName":"", 133 | "TeamIconUrl":"http://www.openligadb.de/images/teamicons/MSV_Duisburg.gif" 134 | }, 135 | "LastUpdateDateTime":"2017-03-25T15:56:09.103", 136 | "MatchIsFinished":true, 137 | "MatchResults":[ 138 | { 139 | "ResultID":73601, 140 | "ResultName":"Halbzeitergebnis", 141 | "PointsTeam1":1, 142 | "PointsTeam2":1, 143 | "ResultOrderID":1, 144 | "ResultTypeID":1, 145 | "ResultDescription":"Ergebnis nach Ende der ersten Halbzeit" 146 | }, 147 | { 148 | "ResultID":73616, 149 | "ResultName":"Endergebnis", 150 | "PointsTeam1":2, 151 | "PointsTeam2":3, 152 | "ResultOrderID":2, 153 | "ResultTypeID":2, 154 | "ResultDescription":"Ergebnis nach Ende der offiziellen Spielzeit" 155 | } 156 | ], 157 | "Goals":[ 158 | { 159 | "GoalID":58341, 160 | "ScoreTeam1":0, 161 | "ScoreTeam2":1, 162 | "MatchMinute":23, 163 | "GoalGetterID":2319, 164 | "GoalGetterName":"Wiegel", 165 | "IsPenalty":false, 166 | "IsOwnGoal":false, 167 | "IsOvertime":false, 168 | "Comment":null 169 | }, 170 | { 171 | "GoalID":58342, 172 | "ScoreTeam1":1, 173 | "ScoreTeam2":1, 174 | "MatchMinute":41, 175 | "GoalGetterID":14383, 176 | "GoalGetterName":"Türpitz", 177 | "IsPenalty":false, 178 | "IsOwnGoal":false, 179 | "IsOvertime":false, 180 | "Comment":null 181 | }, 182 | { 183 | "GoalID":58352, 184 | "ScoreTeam1":2, 185 | "ScoreTeam2":1, 186 | "MatchMinute":52, 187 | "GoalGetterID":14383, 188 | "GoalGetterName":"Türpitz", 189 | "IsPenalty":false, 190 | "IsOwnGoal":false, 191 | "IsOvertime":false, 192 | "Comment":null 193 | }, 194 | { 195 | "GoalID":58353, 196 | "ScoreTeam1":2, 197 | "ScoreTeam2":2, 198 | "MatchMinute":68, 199 | "GoalGetterID":11438, 200 | "GoalGetterName":"Brandstetter", 201 | "IsPenalty":false, 202 | "IsOwnGoal":false, 203 | "IsOvertime":false, 204 | "Comment":null 205 | }, 206 | { 207 | "GoalID":58354, 208 | "ScoreTeam1":2, 209 | "ScoreTeam2":3, 210 | "MatchMinute":74, 211 | "GoalGetterID":1394, 212 | "GoalGetterName":"Onuegbu", 213 | "IsPenalty":false, 214 | "IsOwnGoal":false, 215 | "IsOvertime":false, 216 | "Comment":null 217 | } 218 | ], 219 | "Location":null, 220 | "NumberOfViewers":null 221 | }, 222 | { 223 | "MatchID":40493, 224 | "MatchDateTime":"2017-03-25T14:00:00", 225 | "TimeZoneID":"W. Europe Standard Time", 226 | "LeagueId":3015, 227 | "MatchDateTimeUTC":"2017-03-25T13:00:00Z", 228 | "Group":{ 229 | "GroupName":"29. Spieltag", 230 | "GroupOrderID":29, 231 | "GroupID":24084 232 | }, 233 | "Team1":{ 234 | "TeamId":202, 235 | "TeamName":"Chemnitzer FC", 236 | "ShortName":"", 237 | "TeamIconUrl":"http://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Chemnitzer_FC_Logo.svg/200px-Chemnitzer_FC_Logo.svg.png" 238 | }, 239 | "Team2":{ 240 | "TeamId":107, 241 | "TeamName":"MSV Duisburg", 242 | "ShortName":"", 243 | "TeamIconUrl":"http://www.openligadb.de/images/teamicons/MSV_Duisburg.gif" 244 | }, 245 | "LastUpdateDateTime":"2017-03-25T15:56:09.103", 246 | "MatchIsFinished":true, 247 | "MatchResults":[ 248 | { 249 | "ResultID":73601, 250 | "ResultName":"Halbzeitergebnis", 251 | "PointsTeam1":1, 252 | "PointsTeam2":1, 253 | "ResultOrderID":1, 254 | "ResultTypeID":1, 255 | "ResultDescription":"Ergebnis nach Ende der ersten Halbzeit" 256 | }, 257 | { 258 | "ResultID":73616, 259 | "ResultName":"Endergebnis", 260 | "PointsTeam1":2, 261 | "PointsTeam2":3, 262 | "ResultOrderID":2, 263 | "ResultTypeID":2, 264 | "ResultDescription":"Ergebnis nach Ende der offiziellen Spielzeit" 265 | } 266 | ], 267 | "Goals":[ 268 | { 269 | "GoalID":58341, 270 | "ScoreTeam1":0, 271 | "ScoreTeam2":1, 272 | "MatchMinute":23, 273 | "GoalGetterID":2319, 274 | "GoalGetterName":"Wiegel", 275 | "IsPenalty":false, 276 | "IsOwnGoal":false, 277 | "IsOvertime":false, 278 | "Comment":null 279 | }, 280 | { 281 | "GoalID":58342, 282 | "ScoreTeam1":1, 283 | "ScoreTeam2":1, 284 | "MatchMinute":41, 285 | "GoalGetterID":14383, 286 | "GoalGetterName":"Türpitz", 287 | "IsPenalty":false, 288 | "IsOwnGoal":false, 289 | "IsOvertime":false, 290 | "Comment":null 291 | }, 292 | { 293 | "GoalID":58352, 294 | "ScoreTeam1":2, 295 | "ScoreTeam2":1, 296 | "MatchMinute":52, 297 | "GoalGetterID":14383, 298 | "GoalGetterName":"Türpitz", 299 | "IsPenalty":false, 300 | "IsOwnGoal":false, 301 | "IsOvertime":false, 302 | "Comment":null 303 | }, 304 | { 305 | "GoalID":58353, 306 | "ScoreTeam1":2, 307 | "ScoreTeam2":2, 308 | "MatchMinute":68, 309 | "GoalGetterID":11438, 310 | "GoalGetterName":"Brandstetter", 311 | "IsPenalty":false, 312 | "IsOwnGoal":false, 313 | "IsOvertime":false, 314 | "Comment":null 315 | }, 316 | { 317 | "GoalID":58354, 318 | "ScoreTeam1":2, 319 | "ScoreTeam2":3, 320 | "MatchMinute":74, 321 | "GoalGetterID":1394, 322 | "GoalGetterName":"Onuegbu", 323 | "IsPenalty":false, 324 | "IsOwnGoal":false, 325 | "IsOvertime":false, 326 | "Comment":null 327 | } 328 | ], 329 | "Location":null, 330 | "NumberOfViewers":null 331 | } 332 | ] 333 | -------------------------------------------------------------------------------- /react/test/testUtils/validStubResponse.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "MatchID":40493, 3 | "MatchDateTime":"2017-03-25T14:00:00", 4 | "TimeZoneID":"W. Europe Standard Time", 5 | "LeagueId":3015, 6 | "MatchDateTimeUTC":"2017-03-25T13:00:00Z", 7 | "Group":{ 8 | "GroupName":"29. Spieltag", 9 | "GroupOrderID":29, 10 | "GroupID":24084 11 | }, 12 | "Team1":{ 13 | "TeamId":202, 14 | "TeamName":"Chemnitzer FC", 15 | "ShortName":"", 16 | "TeamIconUrl":"http://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Chemnitzer_FC_Logo.svg/200px-Chemnitzer_FC_Logo.svg.png" 17 | }, 18 | "Team2":{ 19 | "TeamId":107, 20 | "TeamName":"MSV Duisburg", 21 | "ShortName":"", 22 | "TeamIconUrl":"http://www.openligadb.de/images/teamicons/MSV_Duisburg.gif" 23 | }, 24 | "LastUpdateDateTime":"2017-03-25T15:56:09.103", 25 | "MatchIsFinished":true, 26 | "MatchResults":[ 27 | { 28 | "ResultID":73601, 29 | "ResultName":"Halbzeitergebnis", 30 | "PointsTeam1":1, 31 | "PointsTeam2":1, 32 | "ResultOrderID":1, 33 | "ResultTypeID":1, 34 | "ResultDescription":"Ergebnis nach Ende der ersten Halbzeit" 35 | }, 36 | { 37 | "ResultID":73616, 38 | "ResultName":"Endergebnis", 39 | "PointsTeam1":2, 40 | "PointsTeam2":3, 41 | "ResultOrderID":2, 42 | "ResultTypeID":2, 43 | "ResultDescription":"Ergebnis nach Ende der offiziellen Spielzeit" 44 | } 45 | ], 46 | "Goals":[ 47 | { 48 | "GoalID":58341, 49 | "ScoreTeam1":0, 50 | "ScoreTeam2":1, 51 | "MatchMinute":23, 52 | "GoalGetterID":2319, 53 | "GoalGetterName":"Wiegel", 54 | "IsPenalty":false, 55 | "IsOwnGoal":false, 56 | "IsOvertime":false, 57 | "Comment":null 58 | }, 59 | { 60 | "GoalID":58342, 61 | "ScoreTeam1":1, 62 | "ScoreTeam2":1, 63 | "MatchMinute":41, 64 | "GoalGetterID":14383, 65 | "GoalGetterName":"Türpitz", 66 | "IsPenalty":false, 67 | "IsOwnGoal":false, 68 | "IsOvertime":false, 69 | "Comment":null 70 | }, 71 | { 72 | "GoalID":58352, 73 | "ScoreTeam1":2, 74 | "ScoreTeam2":1, 75 | "MatchMinute":52, 76 | "GoalGetterID":14383, 77 | "GoalGetterName":"Türpitz", 78 | "IsPenalty":false, 79 | "IsOwnGoal":false, 80 | "IsOvertime":false, 81 | "Comment":null 82 | }, 83 | { 84 | "GoalID":58353, 85 | "ScoreTeam1":2, 86 | "ScoreTeam2":2, 87 | "MatchMinute":68, 88 | "GoalGetterID":11438, 89 | "GoalGetterName":"Brandstetter", 90 | "IsPenalty":false, 91 | "IsOwnGoal":false, 92 | "IsOvertime":false, 93 | "Comment":null 94 | }, 95 | { 96 | "GoalID":58354, 97 | "ScoreTeam1":2, 98 | "ScoreTeam2":3, 99 | "MatchMinute":74, 100 | "GoalGetterID":1394, 101 | "GoalGetterName":"Onuegbu", 102 | "IsPenalty":false, 103 | "IsOwnGoal":false, 104 | "IsOvertime":false, 105 | "Comment":null 106 | } 107 | ], 108 | "Location":null, 109 | "NumberOfViewers":null 110 | }] 111 | -------------------------------------------------------------------------------- /react/webpack.config.js: -------------------------------------------------------------------------------- 1 | var webpack = require('webpack'); 2 | var path = require('path'); 3 | 4 | var BUILD_DIR = path.resolve(__dirname, 'public'); 5 | var APP_DIR = path.resolve(__dirname, 'app'); 6 | 7 | var config = { 8 | entry: APP_DIR + '/index.jsx', 9 | output: { 10 | path: BUILD_DIR, 11 | filename: 'bundle.js' 12 | }, 13 | devServer: { 14 | inline:true, 15 | port: 8008 16 | }, 17 | module : { 18 | loaders : [ 19 | { 20 | test : /\.js?/, 21 | include : APP_DIR, 22 | loader: 'babel-loader' 23 | } 24 | ] 25 | } 26 | }; 27 | 28 | module.exports = config; 29 | --------------------------------------------------------------------------------