├── .gitignore ├── .nuke ├── .paket ├── Paket.Restore.targets ├── paket.bootstrapper.exe └── paket.targets ├── Directory.Build.targets ├── JsonProvider.sln ├── LICENSE.txt ├── README.md ├── after.JsonProvider.sln.targets ├── azure-pipelines.yml ├── build.ps1 ├── build.sh ├── build ├── Build.cs ├── build.csproj ├── build.csproj.DotSettings └── paket.references ├── docs └── preview.png ├── examples ├── JsonProvider.Example │ ├── JsonProvider.Example.csproj │ ├── Program.cs │ └── paket.references ├── JsonProvider.Examples.sln └── JsonProvider.Provider │ ├── JsonProvider.Provider.fsproj │ ├── Library.fs │ ├── files │ └── example.json │ └── paket.references ├── netfx.props ├── paket.dependencies ├── paket.lock ├── pipelines.non-windows.template.yml ├── pipelines.windows.template.yml ├── src ├── JsonProvider.DesignTime │ ├── AssemblyInfo.fs │ ├── JsonProvider.DesignTime.fs │ ├── JsonProvider.DesignTime.fsproj │ ├── Logging.fs │ ├── TypeInference.fs │ ├── TypeProviderHelpers.fs │ └── paket.references └── JsonProvider.Runtime │ ├── AssemblyInfo.fs │ ├── JsonProvider.Runtime.fs │ ├── JsonProvider.Runtime.fsproj │ ├── paket.references │ └── paket.template └── tests ├── JsonProvider.Tests.Templates ├── JsonProvider.Tests.Templates.fsproj ├── example_embed.json └── paket.references └── JsonProvider.Tests ├── JsonProvider.Tests.fs ├── JsonProvider.Tests.fsproj ├── app.config ├── files └── example.json └── paket.references /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | #GitExtensions 7 | *.orig 8 | 9 | #Paket 10 | 11 | packages/ 12 | paket-files/ 13 | paket.exe 14 | 15 | #Output 16 | output/ 17 | 18 | # User-specific files 19 | *.suo 20 | *.user 21 | *.userosscache 22 | *.sln.docstates 23 | .idea/ 24 | global.json 25 | 26 | # User-specific files (MonoDevelop/Xamarin Studio) 27 | *.userprefs 28 | 29 | # Build results 30 | [Dd]ebug/ 31 | [Dd]ebugPublic/ 32 | [Rr]elease/ 33 | [Rr]eleases/ 34 | x64/ 35 | x86/ 36 | bld/ 37 | [Bb]in/ 38 | [Oo]bj/ 39 | [Ll]og/ 40 | 41 | # Visual Studio 2015/2017 cache/options directory 42 | .vs/ 43 | # Uncomment if you have tasks that create the project's static files in wwwroot 44 | #wwwroot/ 45 | 46 | # Visual Studio 2017 auto generated files 47 | Generated\ Files/ 48 | 49 | # MSTest test Results 50 | [Tt]est[Rr]esult*/ 51 | [Bb]uild[Ll]og.* 52 | 53 | # NUNIT 54 | *.VisualState.xml 55 | TestResult.xml 56 | 57 | # Build Results of an ATL Project 58 | [Dd]ebugPS/ 59 | [Rr]eleasePS/ 60 | dlldata.c 61 | 62 | # Benchmark Results 63 | BenchmarkDotNet.Artifacts/ 64 | 65 | # .NET Core 66 | project.lock.json 67 | project.fragment.lock.json 68 | artifacts/ 69 | **/Properties/launchSettings.json 70 | 71 | # StyleCop 72 | StyleCopReport.xml 73 | 74 | # Files built by Visual Studio 75 | *_i.c 76 | *_p.c 77 | *_i.h 78 | *.ilk 79 | *.meta 80 | *.obj 81 | *.iobj 82 | *.pch 83 | *.pdb 84 | *.ipdb 85 | *.pgc 86 | *.pgd 87 | *.rsp 88 | *.sbr 89 | *.tlb 90 | *.tli 91 | *.tlh 92 | *.tmp 93 | *.tmp_proj 94 | *.log 95 | *.vspscc 96 | *.vssscc 97 | .builds 98 | *.pidb 99 | *.svclog 100 | *.scc 101 | 102 | # Chutzpah Test files 103 | _Chutzpah* 104 | 105 | # Visual C++ cache files 106 | ipch/ 107 | *.aps 108 | *.ncb 109 | *.opendb 110 | *.opensdf 111 | *.sdf 112 | *.cachefile 113 | *.VC.db 114 | *.VC.VC.opendb 115 | 116 | # Visual Studio profiler 117 | *.psess 118 | *.vsp 119 | *.vspx 120 | *.sap 121 | 122 | # Visual Studio Trace Files 123 | *.e2e 124 | 125 | # TFS 2012 Local Workspace 126 | $tf/ 127 | 128 | # Guidance Automation Toolkit 129 | *.gpState 130 | 131 | # ReSharper is a .NET coding add-in 132 | _ReSharper*/ 133 | *.[Rr]e[Ss]harper 134 | *.DotSettings.user 135 | 136 | # JustCode is a .NET coding add-in 137 | .JustCode 138 | 139 | # TeamCity is a build add-in 140 | _TeamCity* 141 | 142 | # DotCover is a Code Coverage Tool 143 | *.dotCover 144 | 145 | # AxoCover is a Code Coverage Tool 146 | .axoCover/* 147 | !.axoCover/settings.json 148 | 149 | # Visual Studio code coverage results 150 | *.coverage 151 | *.coveragexml 152 | 153 | # NCrunch 154 | _NCrunch_* 155 | .*crunch*.local.xml 156 | nCrunchTemp_* 157 | 158 | # MightyMoose 159 | *.mm.* 160 | AutoTest.Net/ 161 | 162 | # Web workbench (sass) 163 | .sass-cache/ 164 | 165 | # Installshield output folder 166 | [Ee]xpress/ 167 | 168 | # DocProject is a documentation generator add-in 169 | DocProject/buildhelp/ 170 | DocProject/Help/*.HxT 171 | DocProject/Help/*.HxC 172 | DocProject/Help/*.hhc 173 | DocProject/Help/*.hhk 174 | DocProject/Help/*.hhp 175 | DocProject/Help/Html2 176 | DocProject/Help/html 177 | 178 | # Click-Once directory 179 | publish/ 180 | 181 | # Publish Web Output 182 | *.[Pp]ublish.xml 183 | *.azurePubxml 184 | # Note: Comment the next line if you want to checkin your web deploy settings, 185 | # but database connection strings (with potential passwords) will be unencrypted 186 | *.pubxml 187 | *.publishproj 188 | 189 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 190 | # checkin your Azure Web App publish settings, but sensitive information contained 191 | # in these scripts will be unencrypted 192 | PublishScripts/ 193 | 194 | # NuGet Packages 195 | *.nupkg 196 | # The packages folder can be ignored because of Package Restore 197 | **/[Pp]ackages/* 198 | # except build/, which is used as an MSBuild target. 199 | !**/[Pp]ackages/build/ 200 | # Uncomment if necessary however generally it will be regenerated when needed 201 | #!**/[Pp]ackages/repositories.config 202 | # NuGet v3's project.json files produces more ignorable files 203 | *.nuget.props 204 | *.nuget.targets 205 | 206 | # Microsoft Azure Build Output 207 | csx/ 208 | *.build.csdef 209 | 210 | # Microsoft Azure Emulator 211 | ecf/ 212 | rcf/ 213 | 214 | # Windows Store app package directories and files 215 | AppPackages/ 216 | BundleArtifacts/ 217 | Package.StoreAssociation.xml 218 | _pkginfo.txt 219 | *.appx 220 | 221 | # Visual Studio cache files 222 | # files ending in .cache can be ignored 223 | *.[Cc]ache 224 | # but keep track of directories ending in .cache 225 | !*.[Cc]ache/ 226 | 227 | # Others 228 | ClientBin/ 229 | ~$* 230 | *~ 231 | *.dbmdl 232 | *.dbproj.schemaview 233 | *.jfm 234 | *.pfx 235 | *.publishsettings 236 | orleans.codegen.cs 237 | 238 | # Including strong name files can present a security risk 239 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 240 | #*.snk 241 | 242 | # Since there are multiple workflows, uncomment next line to ignore bower_components 243 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 244 | #bower_components/ 245 | 246 | # RIA/Silverlight projects 247 | Generated_Code/ 248 | 249 | # Backup & report files from converting an old project file 250 | # to a newer Visual Studio version. Backup files are not needed, 251 | # because we have git ;-) 252 | _UpgradeReport_Files/ 253 | Backup*/ 254 | UpgradeLog*.XML 255 | UpgradeLog*.htm 256 | ServiceFabricBackup/ 257 | *.rptproj.bak 258 | 259 | # SQL Server files 260 | *.mdf 261 | *.ldf 262 | *.ndf 263 | 264 | # Business Intelligence projects 265 | *.rdl.data 266 | *.bim.layout 267 | *.bim_*.settings 268 | *.rptproj.rsuser 269 | 270 | # Microsoft Fakes 271 | FakesAssemblies/ 272 | 273 | # GhostDoc plugin setting file 274 | *.GhostDoc.xml 275 | 276 | # Node.js Tools for Visual Studio 277 | .ntvs_analysis.dat 278 | node_modules/ 279 | 280 | # Visual Studio 6 build log 281 | *.plg 282 | 283 | # Visual Studio 6 workspace options file 284 | *.opt 285 | 286 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 287 | *.vbw 288 | 289 | # Visual Studio LightSwitch build output 290 | **/*.HTMLClient/GeneratedArtifacts 291 | **/*.DesktopClient/GeneratedArtifacts 292 | **/*.DesktopClient/ModelManifest.xml 293 | **/*.Server/GeneratedArtifacts 294 | **/*.Server/ModelManifest.xml 295 | _Pvt_Extensions 296 | 297 | # Paket dependency manager 298 | .paket/paket.exe 299 | paket-files/ 300 | 301 | # FAKE - F# Make 302 | .fake/ 303 | 304 | # JetBrains Rider 305 | .idea/ 306 | *.sln.iml 307 | 308 | # CodeRush 309 | .cr/ 310 | 311 | # Python Tools for Visual Studio (PTVS) 312 | __pycache__/ 313 | *.pyc 314 | 315 | # Cake - Uncomment if you are using it 316 | # tools/** 317 | # !tools/packages.config 318 | 319 | # Tabs Studio 320 | *.tss 321 | 322 | # Telerik's JustMock configuration file 323 | *.jmconfig 324 | 325 | # BizTalk build output 326 | *.btp.cs 327 | *.btm.cs 328 | *.odx.cs 329 | *.xsd.cs 330 | 331 | # OpenCover UI analysis results 332 | OpenCover/ 333 | 334 | # Azure Stream Analytics local run output 335 | ASALocalRun/ 336 | 337 | # MSBuild Binary and Structured Log 338 | *.binlog 339 | 340 | # NVidia Nsight GPU debugger configuration file 341 | *.nvuser 342 | 343 | # MFractors (Xamarin productivity tool) working folder 344 | .mfractor/ 345 | -------------------------------------------------------------------------------- /.nuke: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liminiens/json-provider/a72cf5e1de26eea63bf1989730b4d5f4260e2c61/.nuke -------------------------------------------------------------------------------- /.paket/Paket.Restore.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | $(MSBuildAllProjects);$(MSBuildThisFileFullPath) 8 | 9 | true 10 | $(MSBuildThisFileDirectory) 11 | $(MSBuildThisFileDirectory)..\ 12 | $(PaketRootPath)paket-files\paket.restore.cached 13 | $(PaketRootPath)paket.lock 14 | classic 15 | proj 16 | assembly 17 | native 18 | /Library/Frameworks/Mono.framework/Commands/mono 19 | mono 20 | 21 | 22 | $(PaketRootPath)paket.bootstrapper.exe 23 | $(PaketToolsPath)paket.bootstrapper.exe 24 | $([System.IO.Path]::GetDirectoryName("$(PaketBootStrapperExePath)"))\ 25 | 26 | 27 | 28 | 29 | $(PaketRootPath)paket.exe 30 | $(PaketToolsPath)paket.exe 31 | $(PaketToolsPath)paket.exe 32 | $(_PaketBootStrapperExeDir)paket.exe 33 | paket.exe 34 | 35 | 36 | $(PaketRootPath)paket 37 | $(PaketToolsPath)paket 38 | $(PaketToolsPath)paket 39 | 40 | 41 | $(PaketRootPath)paket.exe 42 | $(PaketToolsPath)paket.exe 43 | 44 | 45 | $(PaketBootStrapperExeDir)paket.exe 46 | 47 | 48 | paket 49 | 50 | 51 | <_PaketExeExtension>$([System.IO.Path]::GetExtension("$(PaketExePath)")) 52 | dotnet "$(PaketExePath)" 53 | $(MonoPath) --runtime=v4.0.30319 "$(PaketExePath)" 54 | "$(PaketExePath)" 55 | 56 | 57 | "$(PaketBootStrapperExePath)" 58 | $(MonoPath) --runtime=v4.0.30319 "$(PaketBootStrapperExePath)" 59 | 60 | 61 | 62 | 63 | true 64 | true 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | true 76 | $(NoWarn);NU1603;NU1604;NU1605;NU1608 77 | 78 | 79 | 80 | 81 | /usr/bin/shasum "$(PaketRestoreCacheFile)" | /usr/bin/awk '{ print $1 }' 82 | /usr/bin/shasum "$(PaketLockFilePath)" | /usr/bin/awk '{ print $1 }' 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | $([System.IO.File]::ReadAllText('$(PaketRestoreCacheFile)')) 99 | $([System.IO.File]::ReadAllText('$(PaketLockFilePath)')) 100 | true 101 | false 102 | true 103 | 104 | 105 | 106 | true 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | $(MSBuildProjectDirectory)\obj\$(MSBuildProjectFile).paket.references.cached 123 | 124 | $(MSBuildProjectFullPath).paket.references 125 | 126 | $(MSBuildProjectDirectory)\$(MSBuildProjectName).paket.references 127 | 128 | $(MSBuildProjectDirectory)\paket.references 129 | 130 | false 131 | true 132 | true 133 | references-file-or-cache-not-found 134 | 135 | 136 | 137 | 138 | $([System.IO.File]::ReadAllText('$(PaketReferencesCachedFilePath)')) 139 | $([System.IO.File]::ReadAllText('$(PaketOriginalReferencesFilePath)')) 140 | references-file 141 | false 142 | 143 | 144 | 145 | 146 | false 147 | 148 | 149 | 150 | 151 | true 152 | target-framework '$(TargetFramework)' or '$(TargetFrameworks)' files @(PaketResolvedFilePaths) 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | false 163 | true 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',').Length) 175 | $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[0]) 176 | $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[1]) 177 | $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[4]) 178 | $([System.String]::Copy('%(PaketReferencesFileLines.Identity)').Split(',')[5]) 179 | 180 | 181 | %(PaketReferencesFileLinesInfo.PackageVersion) 182 | All 183 | runtime 184 | runtime 185 | true 186 | 187 | 188 | 189 | 190 | $(MSBuildProjectDirectory)/obj/$(MSBuildProjectFile).paket.clitools 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | $([System.String]::Copy('%(PaketCliToolFileLines.Identity)').Split(',')[0]) 200 | $([System.String]::Copy('%(PaketCliToolFileLines.Identity)').Split(',')[1]) 201 | 202 | 203 | %(PaketCliToolFileLinesInfo.PackageVersion) 204 | 205 | 206 | 207 | 211 | 212 | 213 | 214 | 215 | 216 | false 217 | $(MSBuildVersion) 218 | 15.8.0 219 | 220 | 221 | 222 | 223 | 224 | <_NuspecFilesNewLocation Include="$(BaseIntermediateOutputPath)$(Configuration)\*.nuspec"/> 225 | 226 | 227 | 228 | 229 | 230 | $(MSBuildProjectDirectory)/$(MSBuildProjectFile) 231 | true 232 | false 233 | true 234 | false 235 | true 236 | false 237 | true 238 | $(BaseIntermediateOutputPath)$(Configuration) 239 | $(BaseIntermediateOutputPath) 240 | 241 | 242 | 243 | <_NuspecFiles Include="$(AdjustedNuspecOutputPath)\*.nuspec"/> 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 296 | 297 | 339 | 340 | 381 | 382 | 383 | 384 | -------------------------------------------------------------------------------- /.paket/paket.bootstrapper.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liminiens/json-provider/a72cf5e1de26eea63bf1989730b4d5f4260e2c61/.paket/paket.bootstrapper.exe -------------------------------------------------------------------------------- /.paket/paket.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | true 6 | 7 | true 8 | $(MSBuildThisFileDirectory) 9 | $(MSBuildThisFileDirectory)..\ 10 | 11 | 12 | 13 | $(PaketToolsPath)paket.exe 14 | $(PaketToolsPath)paket.bootstrapper.exe 15 | "$(PaketExePath)" 16 | "$(PaketBootStrapperExePath)" 17 | 18 | $(PaketCommand) restore 19 | $(PaketBootStrapperCommand) 20 | 21 | RestorePackages; $(BuildDependsOn); 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /Directory.Build.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /JsonProvider.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28010.2048 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{63297B98-5CED-492C-A5B7-A5B4F73CF142}" 7 | ProjectSection(SolutionItems) = preProject 8 | paket.dependencies = paket.dependencies 9 | EndProjectSection 10 | EndProject 11 | Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "JsonProvider.Runtime", "src\JsonProvider.Runtime\JsonProvider.Runtime.fsproj", "{E4AA5589-440D-4D80-A542-B6B1EFE328F2}" 12 | EndProject 13 | Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "JsonProvider.DesignTime", "src\JsonProvider.DesignTime\JsonProvider.DesignTime.fsproj", "{21D622D9-B030-4AFF-B425-F065AEE27486}" 14 | EndProject 15 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{ED8079DD-2B06-4030-9F0F-DC548F98E1C4}" 16 | EndProject 17 | Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "JsonProvider.Tests", "tests\JsonProvider.Tests\JsonProvider.Tests.fsproj", "{CD444F1B-5F75-4977-9D31-4A9B658E7536}" 18 | EndProject 19 | Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "JsonProvider.Tests.Templates", "tests\JsonProvider.Tests.Templates\JsonProvider.Tests.Templates.fsproj", "{21114FD5-C1CB-4B34-AD8C-61D805D7D36B}" 20 | EndProject 21 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "build", "build\build.csproj", "{10AE8ADD-9138-4D09-86A2-1B69B4DF15AA}" 22 | EndProject 23 | Global 24 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 25 | Debug|Any CPU = Debug|Any CPU 26 | Release|Any CPU = Release|Any CPU 27 | EndGlobalSection 28 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 29 | {E4AA5589-440D-4D80-A542-B6B1EFE328F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 30 | {E4AA5589-440D-4D80-A542-B6B1EFE328F2}.Debug|Any CPU.Build.0 = Debug|Any CPU 31 | {E4AA5589-440D-4D80-A542-B6B1EFE328F2}.Release|Any CPU.ActiveCfg = Release|Any CPU 32 | {E4AA5589-440D-4D80-A542-B6B1EFE328F2}.Release|Any CPU.Build.0 = Release|Any CPU 33 | {21D622D9-B030-4AFF-B425-F065AEE27486}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 34 | {21D622D9-B030-4AFF-B425-F065AEE27486}.Debug|Any CPU.Build.0 = Debug|Any CPU 35 | {21D622D9-B030-4AFF-B425-F065AEE27486}.Release|Any CPU.ActiveCfg = Release|Any CPU 36 | {21D622D9-B030-4AFF-B425-F065AEE27486}.Release|Any CPU.Build.0 = Release|Any CPU 37 | {CD444F1B-5F75-4977-9D31-4A9B658E7536}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 38 | {CD444F1B-5F75-4977-9D31-4A9B658E7536}.Debug|Any CPU.Build.0 = Debug|Any CPU 39 | {CD444F1B-5F75-4977-9D31-4A9B658E7536}.Release|Any CPU.ActiveCfg = Release|Any CPU 40 | {CD444F1B-5F75-4977-9D31-4A9B658E7536}.Release|Any CPU.Build.0 = Release|Any CPU 41 | {21114FD5-C1CB-4B34-AD8C-61D805D7D36B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 42 | {21114FD5-C1CB-4B34-AD8C-61D805D7D36B}.Debug|Any CPU.Build.0 = Debug|Any CPU 43 | {21114FD5-C1CB-4B34-AD8C-61D805D7D36B}.Release|Any CPU.ActiveCfg = Release|Any CPU 44 | {21114FD5-C1CB-4B34-AD8C-61D805D7D36B}.Release|Any CPU.Build.0 = Release|Any CPU 45 | {10AE8ADD-9138-4D09-86A2-1B69B4DF15AA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 46 | {10AE8ADD-9138-4D09-86A2-1B69B4DF15AA}.Release|Any CPU.ActiveCfg = Debug|Any CPU 47 | EndGlobalSection 48 | GlobalSection(SolutionProperties) = preSolution 49 | HideSolutionNode = FALSE 50 | EndGlobalSection 51 | GlobalSection(NestedProjects) = preSolution 52 | {CD444F1B-5F75-4977-9D31-4A9B658E7536} = {ED8079DD-2B06-4030-9F0F-DC548F98E1C4} 53 | {21114FD5-C1CB-4B34-AD8C-61D805D7D36B} = {ED8079DD-2B06-4030-9F0F-DC548F98E1C4} 54 | EndGlobalSection 55 | GlobalSection(ExtensibilityGlobals) = postSolution 56 | SolutionGuid = {7CAE914F-591E-4D24-AE04-462926E52B4E} 57 | EndGlobalSection 58 | EndGlobal 59 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Vlad Khapin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![NuGet](https://img.shields.io/nuget/v/FSharp.Data.JsonProvider.svg)](https://www.nuget.org/packages/FSharp.Data.JsonProvider) 2 | 3 | # Json generative type provider 4 | 5 | This is a F# type provider which allows you to generate types from string json sample and then use them in F# or C# project. 6 | 7 | ![Screenshot](docs/preview.png) 8 | 9 | ## Usage 10 | 11 | You can use it to generate types from json samples (files, web resources, string literals) at design time and then use them in your F#\C# projects. 12 | 13 | ## Examples 14 | 15 | In F#: 16 | 17 | open FSharp.Data.JsonProvider 18 | 19 | type FileType = JsonProvider<"file.txt"> 20 | 21 | type RelativeFileType = JsonProvider<"../file.txt"> 22 | 23 | type WebType = JsonProvider<"https://jsonplaceholder.typicode.com/todos/1"> 24 | 25 | type StringType = JsonProvider<""" { "Data": 1 } """> 26 | 27 | ## Status 28 | 29 | | OS | Build & Test | 30 | |---------|--------------| 31 | | Mac OS | [![Build Status](https://dev.azure.com/GithubProjects/JsonProvider/_apis/build/status/Liminiens.json-provider)](https://dev.azure.com/GithubProjects/JsonProvider/_build/latest?definitionId=1&branchName=master&jobname=macOS_10_13) | 32 | | Linux | [![Build Status](https://dev.azure.com/GithubProjects/JsonProvider/_apis/build/status/Liminiens.json-provider)](https://dev.azure.com/GithubProjects/JsonProvider/_build/latest?definitionId=1&branchName=master&jobname=ubuntu_16_04) | 33 | | Windows | [![Build Status](https://dev.azure.com/GithubProjects/JsonProvider/_apis/build/status/Liminiens.json-provider)](https://dev.azure.com/GithubProjects/JsonProvider/_build/latest?definitionId=1&branchName=master&jobname=vs2017_win2016) | 34 | 35 | Paket is used to acquire the type provider SDK and build the nuget package. 36 | 37 | Build: 38 | 39 | .\build.ps1 --target Build --Configuration Release 40 | 41 | Pack: 42 | 43 | .\build.ps1 --target Pack --Configuration Release 44 | 45 | 46 | [![Built with NUKE](http://nuke.build/squared)](https://nuke.build) 47 | 48 | -------------------------------------------------------------------------------- /after.JsonProvider.sln.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | # Add steps that run tests, create a NuGet package, deploy, and more: 2 | # https://docs.microsoft.com/azure/devops/pipelines/languages/dotnet-core 3 | 4 | variables: 5 | buildConfiguration: 'Release' 6 | 7 | trigger: 8 | paths: 9 | exclude: 10 | - README.md 11 | 12 | jobs: 13 | - job: 14 | displayName: ubuntu_16_04 15 | pool: 16 | vmImage: 'Ubuntu 16.04' 17 | 18 | steps: 19 | - template: pipelines.non-windows.template.yml 20 | 21 | - script: bash build.sh --target Test --Configuration $(buildConfiguration) 22 | displayName: 'build.sh --target Test --Configuration $(buildConfiguration)' 23 | 24 | - job: 25 | displayName: macOS_10_13 26 | pool: 27 | vmImage: 'macOS-10.13' 28 | 29 | steps: 30 | - template: pipelines.non-windows.template.yml 31 | 32 | - script: bash build.sh --target Test --Configuration $(buildConfiguration) 33 | displayName: 'build.sh --target Test --Configuration $(buildConfiguration)' 34 | 35 | - job: 36 | displayName: vs2017_win2016 37 | pool: 38 | vmImage: 'vs2017-win2016' 39 | 40 | steps: 41 | - template: pipelines.windows.template.yml 42 | 43 | - script: powershell .\build.ps1 --target Test --Configuration $(buildConfiguration) 44 | displayName: 'build.ps1 --target Test --Configuration $(buildConfiguration)' 45 | -------------------------------------------------------------------------------- /build.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | Param( 3 | #[switch]$CustomParam, 4 | [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] 5 | [string[]]$BuildArguments 6 | ) 7 | 8 | Write-Output "Windows PowerShell $($Host.Version)" 9 | 10 | Set-StrictMode -Version 2.0; $ErrorActionPreference = "Stop"; $ConfirmPreference = "None"; trap { $host.SetShouldExit(1) } 11 | $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent 12 | 13 | ########################################################################### 14 | # CONFIGURATION 15 | ########################################################################### 16 | 17 | $BuildProjectFile = "$PSScriptRoot\build\build.csproj" 18 | $TempDirectory = "$PSScriptRoot\\.tmp" 19 | 20 | $DotNetGlobalFile = "$PSScriptRoot\\global.json" 21 | $DotNetInstallUrl = "https://raw.githubusercontent.com/dotnet/cli/master/scripts/obtain/dotnet-install.ps1" 22 | $DotNetReleasesUrl = "https://raw.githubusercontent.com/dotnet/core/master/release-notes/releases.json" 23 | 24 | $env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = 1 25 | $env:DOTNET_CLI_TELEMETRY_OPTOUT = 1 26 | $env:NUGET_XMLDOC_MODE = "skip" 27 | 28 | ########################################################################### 29 | # EXECUTION 30 | ########################################################################### 31 | 32 | function ExecSafe([scriptblock] $cmd) { 33 | & $cmd 34 | if ($LASTEXITCODE) { exit $LASTEXITCODE } 35 | } 36 | 37 | # If global.json exists, load expected version 38 | if (Test-Path $DotNetGlobalFile) { 39 | $DotNetVersion = $(Get-Content $DotNetGlobalFile | Out-String | ConvertFrom-Json).sdk.version 40 | } 41 | 42 | # If dotnet is installed locally, and expected version is not set or installation matches the expected version 43 | if ((Get-Command "dotnet" -ErrorAction SilentlyContinue) -ne $null -and ` 44 | (!(Test-Path variable:DotNetVersion) -or $(& dotnet --version) -eq $DotNetVersion)) { 45 | $env:DOTNET_EXE = (Get-Command "dotnet").Path 46 | } 47 | else { 48 | $DotNetDirectory = "$TempDirectory\dotnet-win" 49 | $env:DOTNET_EXE = "$DotNetDirectory\dotnet.exe" 50 | 51 | # If expected version is not set, get latest version 52 | if (!(Test-Path variable:DotNetVersion)) { 53 | $DotNetVersion = $(Invoke-WebRequest -UseBasicParsing $DotNetReleasesUrl | ConvertFrom-Json)[0]."version-sdk" 54 | } 55 | 56 | # Download and execute install script 57 | $DotNetInstallFile = "$TempDirectory\dotnet-install.ps1" 58 | md -force $TempDirectory > $null 59 | (New-Object System.Net.WebClient).DownloadFile($DotNetInstallUrl, $DotNetInstallFile) 60 | ExecSafe { & $DotNetInstallFile -InstallDir $DotNetDirectory -Version $DotNetVersion -NoPath } 61 | } 62 | 63 | Write-Output "Microsoft (R) .NET Core SDK version $(& $env:DOTNET_EXE --version)" 64 | 65 | ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile -- $BuildArguments } 66 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | echo $(bash --version 2>&1 | head -n 1) 4 | 5 | #CUSTOMPARAM=0 6 | BUILD_ARGUMENTS=() 7 | for i in "$@"; do 8 | case $(echo $1 | awk '{print tolower($0)}') in 9 | # -custom-param) CUSTOMPARAM=1;; 10 | *) BUILD_ARGUMENTS+=("$1") ;; 11 | esac 12 | shift 13 | done 14 | 15 | set -eo pipefail 16 | SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd) 17 | 18 | ########################################################################### 19 | # CONFIGURATION 20 | ########################################################################### 21 | 22 | BUILD_PROJECT_FILE="$SCRIPT_DIR/build/build.csproj" 23 | TEMP_DIRECTORY="$SCRIPT_DIR//.tmp" 24 | 25 | DOTNET_GLOBAL_FILE="$SCRIPT_DIR//global.json" 26 | DOTNET_INSTALL_URL="https://raw.githubusercontent.com/dotnet/cli/master/scripts/obtain/dotnet-install.sh" 27 | DOTNET_RELEASES_URL="https://raw.githubusercontent.com/dotnet/core/master/release-notes/releases.json" 28 | 29 | export DOTNET_CLI_TELEMETRY_OPTOUT=1 30 | export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 31 | export NUGET_XMLDOC_MODE="skip" 32 | 33 | ########################################################################### 34 | # EXECUTION 35 | ########################################################################### 36 | 37 | function FirstJsonValue { 38 | perl -nle 'print $1 if m{"'$1'": "([^"\-]+)",?}' <<< ${@:2} 39 | } 40 | 41 | # If global.json exists, load expected version 42 | if [ -f "$DOTNET_GLOBAL_FILE" ]; then 43 | DOTNET_VERSION=$(FirstJsonValue "version" $(cat "$DOTNET_GLOBAL_FILE")) 44 | fi 45 | 46 | # If dotnet is installed locally, and expected version is not set or installation matches the expected version 47 | if [[ -x "$(command -v dotnet)" && (-z ${DOTNET_VERSION+x} || $(dotnet --version) == "$DOTNET_VERSION") ]]; then 48 | export DOTNET_EXE="$(command -v dotnet)" 49 | else 50 | DOTNET_DIRECTORY="$TEMP_DIRECTORY/dotnet-unix" 51 | export DOTNET_EXE="$DOTNET_DIRECTORY/dotnet" 52 | 53 | # If expected version is not set, get latest version 54 | if [ -z ${DOTNET_VERSION+x} ]; then 55 | DOTNET_VERSION=$(FirstJsonValue "version-sdk" $(curl -s "$DOTNET_RELEASES_URL")) 56 | fi 57 | 58 | # Download and execute install script 59 | DOTNET_INSTALL_FILE="$TEMP_DIRECTORY/dotnet-install.sh" 60 | mkdir -p "$TEMP_DIRECTORY" 61 | curl -Lsfo "$DOTNET_INSTALL_FILE" "$DOTNET_INSTALL_URL" 62 | chmod +x "$DOTNET_INSTALL_FILE" 63 | "$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --version "$DOTNET_VERSION" --no-path 64 | fi 65 | 66 | echo "Microsoft (R) .NET Core SDK version $("$DOTNET_EXE" --version)" 67 | 68 | "$DOTNET_EXE" run --project "$BUILD_PROJECT_FILE" -- ${BUILD_ARGUMENTS[@]} 69 | -------------------------------------------------------------------------------- /build/Build.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Nuke.Common; 3 | using Nuke.Common.Git; 4 | using Nuke.Common.ProjectModel; 5 | using Nuke.Common.Tooling; 6 | using Nuke.Common.Tools.DotNet; 7 | using Nuke.Common.Tools.Git; 8 | using Nuke.Common.Tools.GitVersion; 9 | using Nuke.Common.Tools.Paket; 10 | using static Nuke.Common.IO.FileSystemTasks; 11 | using static Nuke.Common.IO.PathConstruction; 12 | using static Nuke.Common.Tools.DotNet.DotNetTasks; 13 | 14 | class Build : NukeBuild 15 | { 16 | public static int Main() => Execute(x => x.Compile); 17 | static Build() 18 | { 19 | Environment.SetEnvironmentVariable("GITVERSION_EXE", RootDirectory / "packages" / "nukebuild" / "GitVersion.CommandLine.DotNetCore" / "tools" / "GitVersion.dll"); 20 | Environment.SetEnvironmentVariable("PAKET_EXE", RootDirectory / ".paket" / "paket.exe"); 21 | } 22 | 23 | [Parameter("Configuration to build - Default is 'Debug' (local) or 'Release' (server)")] 24 | readonly string Configuration = IsLocalBuild ? "Debug" : "Release"; 25 | 26 | [Solution("JsonProvider.sln")] readonly Solution Solution; 27 | [GitRepository] readonly GitRepository GitRepository; 28 | [GitVersion] readonly GitVersion GitVersion; 29 | 30 | AbsolutePath SourceDirectory => RootDirectory / "src"; 31 | AbsolutePath TestsDirectory => RootDirectory / "tests"; 32 | AbsolutePath OutputDirectory => RootDirectory / "output"; 33 | 34 | Target Clean => _ => _ 35 | .Executes(() => 36 | { 37 | DeleteDirectories(GlobDirectories(SourceDirectory, "**/bin", "**/obj")); 38 | DeleteDirectories(GlobDirectories(TestsDirectory, "**/bin", "**/obj")); 39 | EnsureCleanDirectory(OutputDirectory); 40 | }); 41 | 42 | Target Restore => _ => _ 43 | .DependsOn(Clean) 44 | .Executes(() => 45 | { 46 | DotNetRestore(); 47 | }); 48 | 49 | Target Compile => _ => _ 50 | .DependsOn(Restore) 51 | .Executes(() => 52 | { 53 | DotNetBuild(s => s 54 | .SetProjectFile(Solution) 55 | .EnableNoRestore() 56 | .SetConfiguration(Configuration) 57 | .SetAssemblyVersion(GitVersion.GetNormalizedAssemblyVersion()) 58 | .SetFileVersion(GitVersion.GetNormalizedFileVersion()) 59 | .SetInformationalVersion(GitVersion.InformationalVersion)); 60 | }); 61 | 62 | Target Test => _ => _ 63 | .DependsOn(Compile) 64 | .Executes(() => 65 | { 66 | DotNetTest(s => s 67 | .SetConfiguration(Configuration) 68 | .EnableNoBuild() 69 | .SetResultsDirectory(OutputDirectory / "tests")); 70 | }); 71 | 72 | Target Pack => _ => _ 73 | .DependsOn(Compile) 74 | .Executes(() => 75 | { 76 | PaketTasks.PaketPack(s => s 77 | .SetTemplateFile(RootDirectory / "src" / "JsonProvider.Runtime" / "paket.template") 78 | .SetBuildConfiguration(Configuration) 79 | .EnableSymbols() 80 | .SetOutputDirectory(OutputDirectory) 81 | .SetPackageVersion(GitVersion.NuGetVersionV2)); 82 | }); 83 | } 84 | -------------------------------------------------------------------------------- /build/build.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | netcoreapp2.0 6 | false 7 | 8 | 9 | False 10 | CS0649;CS0169 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /build/build.csproj.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | False 3 | Implicit 4 | Implicit 5 | ExpressionBody 6 | 0 7 | NEXT_LINE 8 | True 9 | False 10 | 120 11 | IF_OWNER_IS_SINGLE_LINE 12 | WRAP_IF_LONG 13 | False 14 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 15 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> 16 | True 17 | True 18 | True 19 | True 20 | True 21 | True 22 | True 23 | True 24 | True 25 | -------------------------------------------------------------------------------- /build/paket.references: -------------------------------------------------------------------------------- 1 | group NukeBuild 2 | Nuke.Common 3 | GitVersion.CommandLine.DotNetCore -------------------------------------------------------------------------------- /docs/preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liminiens/json-provider/a72cf5e1de26eea63bf1989730b4d5f4260e2c61/docs/preview.png -------------------------------------------------------------------------------- /examples/JsonProvider.Example/JsonProvider.Example.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Exe 5 | netcoreapp2.1;net45 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/JsonProvider.Example/Program.cs: -------------------------------------------------------------------------------- 1 | using JsonProvider.Provider; 2 | using System; 3 | using System.Linq; 4 | 5 | namespace JsonProvider.Example 6 | { 7 | class Program 8 | { 9 | static void Main(string[] args) 10 | { 11 | var sample = JsonType.GetSample(); 12 | Print(sample); 13 | var parsed = JsonType.Parse("{ \"Data\": [{ \"Test\": 1, \"Array\": [2, 3] }] }"); 14 | Print(parsed); 15 | Console.WriteLine(); 16 | 17 | var fileSample = JsonFromFile.GetSample(); 18 | fileSample.WebApp.Servlet 19 | .Select(x => x.ServletName) 20 | .ToList() 21 | .ForEach(Console.WriteLine); 22 | Console.WriteLine(); 23 | 24 | foreach (var comment in JsonFromWeb.GetSample()) 25 | { 26 | Console.WriteLine($"Name: {comment.Name}; Body: {comment.Body}\n"); 27 | } 28 | 29 | foreach (var item in JsonNullableType.GetSample().Data) 30 | { 31 | Console.WriteLine(item); 32 | } 33 | } 34 | 35 | static void Print(JsonType.SuperRoot data) 36 | { 37 | foreach (var el in data.Data) 38 | { 39 | foreach (var value in el.Array) 40 | { 41 | Console.WriteLine(value); 42 | } 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /examples/JsonProvider.Example/paket.references: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liminiens/json-provider/a72cf5e1de26eea63bf1989730b4d5f4260e2c61/examples/JsonProvider.Example/paket.references -------------------------------------------------------------------------------- /examples/JsonProvider.Examples.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.28218.60 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "JsonProvider.Provider", "JsonProvider.Provider\JsonProvider.Provider.fsproj", "{36D53772-2786-4155-A660-13C892894480}" 7 | EndProject 8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JsonProvider.Example", "JsonProvider.Example\JsonProvider.Example.csproj", "{580A7715-2296-4B35-92DC-0C7F1D36AB8D}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {36D53772-2786-4155-A660-13C892894480}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {36D53772-2786-4155-A660-13C892894480}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {36D53772-2786-4155-A660-13C892894480}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {36D53772-2786-4155-A660-13C892894480}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {580A7715-2296-4B35-92DC-0C7F1D36AB8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {580A7715-2296-4B35-92DC-0C7F1D36AB8D}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {580A7715-2296-4B35-92DC-0C7F1D36AB8D}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {580A7715-2296-4B35-92DC-0C7F1D36AB8D}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {A7F04388-F0EC-4725-BE34-E2ADE13DC6CA} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /examples/JsonProvider.Provider/JsonProvider.Provider.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0;net45 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/JsonProvider.Provider/Library.fs: -------------------------------------------------------------------------------- 1 | namespace JsonProvider.Provider 2 | 3 | open FSharp.Data.JsonProvider 4 | 5 | type JsonType = JsonProvider<"""{ "Data": [{ "Test": 1, "Array": [1.3, 1] }] }""", "SuperRoot"> 6 | 7 | type JsonNullableType = JsonProvider<"""{ "Data": [null, 1, 2] }""", NullableValueTypes = true> 8 | 9 | type JsonFromFile = JsonProvider<"files/example.json"> 10 | 11 | type JsonFromWeb = JsonProvider<"https://jsonplaceholder.typicode.com/comments"> -------------------------------------------------------------------------------- /examples/JsonProvider.Provider/files/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "web-app": { 3 | "servlet": [ 4 | { 5 | "servlet-name": "cofaxCDS", 6 | "servlet-class": "org.cofax.cds.CDSServlet", 7 | "init-param": { 8 | "configGlossary:installationAt": "Philadelphia, PA", 9 | "configGlossary:adminEmail": "ksm@pobox.com", 10 | "configGlossary:poweredBy": "Cofax", 11 | "configGlossary:poweredByIcon": "/images/cofax.gif", 12 | "configGlossary:staticPath": "/content/static", 13 | "templateProcessorClass": "org.cofax.WysiwygTemplate", 14 | "templateLoaderClass": "org.cofax.FilesTemplateLoader", 15 | "templatePath": "templates", 16 | "templateOverridePath": "", 17 | "defaultListTemplate": "listTemplate.htm", 18 | "defaultFileTemplate": "articleTemplate.htm", 19 | "useJSP": false, 20 | "jspListTemplate": "listTemplate.jsp", 21 | "jspFileTemplate": "articleTemplate.jsp", 22 | "cachePackageTagsTrack": 200, 23 | "cachePackageTagsStore": 200, 24 | "cachePackageTagsRefresh": 60, 25 | "cacheTemplatesTrack": 100, 26 | "cacheTemplatesStore": 50, 27 | "cacheTemplatesRefresh": 15, 28 | "cachePagesTrack": 200, 29 | "cachePagesStore": 100, 30 | "cachePagesRefresh": 10, 31 | "cachePagesDirtyRead": 10, 32 | "searchEngineListTemplate": "forSearchEnginesList.htm", 33 | "searchEngineFileTemplate": "forSearchEngines.htm", 34 | "searchEngineRobotsDb": "WEB-INF/robots.db", 35 | "useDataStore": true, 36 | "dataStoreClass": "org.cofax.SqlDataStore", 37 | "redirectionClass": "org.cofax.SqlRedirection", 38 | "dataStoreName": "cofax", 39 | "dataStoreDriver": "com.microsoft.jdbc.sqlserver.SQLServerDriver", 40 | "dataStoreUrl": "jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon", 41 | "dataStoreUser": "sa", 42 | "dataStorePassword": "dataStoreTestQuery", 43 | "dataStoreTestQuery": "SET NOCOUNT ON;select test='test';", 44 | "dataStoreLogFile": "/usr/local/tomcat/logs/datastore.log", 45 | "dataStoreInitConns": 10, 46 | "dataStoreMaxConns": 100, 47 | "dataStoreConnUsageLimit": 100, 48 | "dataStoreLogLevel": "debug", 49 | "maxUrlLength": 500 50 | } 51 | }, 52 | { 53 | "servlet-name": "cofaxEmail", 54 | "servlet-class": "org.cofax.cds.EmailServlet", 55 | "init-param": { 56 | "mailHost": "mail1", 57 | "mailHostOverride": "mail2" 58 | } 59 | }, 60 | { 61 | "servlet-name": "cofaxAdmin", 62 | "servlet-class": "org.cofax.cds.AdminServlet" 63 | }, 64 | 65 | { 66 | "servlet-name": "fileServlet", 67 | "servlet-class": "org.cofax.cds.FileServlet" 68 | }, 69 | { 70 | "servlet-name": "cofaxTools", 71 | "servlet-class": "org.cofax.cms.CofaxToolsServlet", 72 | "init-param": { 73 | "templatePath": "toolstemplates/", 74 | "log": 1, 75 | "logLocation": "/usr/local/tomcat/logs/CofaxTools.log", 76 | "logMaxSize": "", 77 | "dataLog": 1, 78 | "dataLogLocation": "/usr/local/tomcat/logs/dataLog.log", 79 | "dataLogMaxSize": "", 80 | "removePageCache": "/content/admin/remove?cache=pages&id=", 81 | "removeTemplateCache": "/content/admin/remove?cache=templates&id=", 82 | "fileTransferFolder": "/usr/local/tomcat/webapps/content/fileTransferFolder", 83 | "lookInContext": 1, 84 | "adminGroupID": 4, 85 | "betaServer": true 86 | } 87 | } 88 | ], 89 | "servlet-mapping": { 90 | "cofaxCDS": "/", 91 | "cofaxEmail": "/cofaxutil/aemail/*", 92 | "cofaxAdmin": "/admin/*", 93 | "fileServlet": "/static/*", 94 | "cofaxTools": "/tools/*" 95 | }, 96 | 97 | "taglib": { 98 | "taglib-uri": "cofax.tld", 99 | "taglib-location": "/WEB-INF/tlds/cofax.tld" 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /examples/JsonProvider.Provider/paket.references: -------------------------------------------------------------------------------- 1 | group Example 2 | FSharp.Data.JsonProvider -------------------------------------------------------------------------------- /netfx.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | true 8 | 9 | 10 | /Library/Frameworks/Mono.framework/Versions/Current/lib/mono 11 | /usr/lib/mono 12 | /usr/local/lib/mono 13 | 14 | 15 | $(BaseFrameworkPathOverrideForMono)/4.5-api 16 | $(BaseFrameworkPathOverrideForMono)/4.5.1-api 17 | $(BaseFrameworkPathOverrideForMono)/4.5.2-api 18 | $(BaseFrameworkPathOverrideForMono)/4.6-api 19 | $(BaseFrameworkPathOverrideForMono)/4.6.1-api 20 | $(BaseFrameworkPathOverrideForMono)/4.6.2-api 21 | $(BaseFrameworkPathOverrideForMono)/4.7-api 22 | $(BaseFrameworkPathOverrideForMono)/4.7.1-api 23 | true 24 | 25 | 26 | $(FrameworkPathOverride)/Facades;$(AssemblySearchPaths) 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /paket.dependencies: -------------------------------------------------------------------------------- 1 | source https://nuget.org/api/v2 2 | 3 | frameworks: net45, netcoreapp2.0, netstandard2.0 4 | 5 | # Add the nuget packages you use here 6 | nuget FSharp.Core 4.3.4 7 | nuget Newtonsoft.Json >= 11 8 | 9 | nuget NETStandard.Library.NETFramework 10 | 11 | # This lines are used by Paket to get the latest version of the Type Provider SDK files 12 | github fsprojects/FSharp.TypeProviders.SDK:4c8d754453da9761a62e360b739e36bacc2a38f8 src/ProvidedTypes.fsi 13 | github fsprojects/FSharp.TypeProviders.SDK:4c8d754453da9761a62e360b739e36bacc2a38f8 src/ProvidedTypes.fs 14 | 15 | group Test 16 | source https://nuget.org/api/v2 17 | frameworks: net461, netcoreapp2.0 18 | 19 | nuget FSharp.Core 4.3.4 20 | nuget NUnit 3.6.1 21 | nuget NUnit.Console 3.6.1 22 | nuget NUnit3TestAdapter 3.7.0 version_in_path: true 23 | 24 | group Example 25 | source https://nuget.org/api/v2 26 | 27 | nuget FSharp.Data.JsonProvider >= 0.4 prerelease 28 | 29 | group NukeBuild 30 | source https://api.nuget.org/v3/index.json 31 | 32 | nuget GitVersion.CommandLine.DotNetCore 33 | nuget Nuke.Common -------------------------------------------------------------------------------- /pipelines.non-windows.template.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - script: mono .paket/paket.bootstrapper.exe 3 | displayName: 'Download paket' -------------------------------------------------------------------------------- /pipelines.windows.template.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - script: .paket\paket.bootstrapper.exe 3 | displayName: 'Download paket' -------------------------------------------------------------------------------- /src/JsonProvider.DesignTime/AssemblyInfo.fs: -------------------------------------------------------------------------------- 1 | // Auto-Generated by FAKE; do not edit 2 | namespace System 3 | open System.Reflection 4 | 5 | do () -------------------------------------------------------------------------------- /src/JsonProvider.DesignTime/JsonProvider.DesignTime.fs: -------------------------------------------------------------------------------- 1 | module JsonProviderImplementation 2 | #nowarn "0025" 3 | 4 | open System.Linq 5 | open System.IO 6 | open System.Text 7 | open System.Reflection 8 | open Newtonsoft.Json.Linq 9 | open FSharp.Core.CompilerServices 10 | open FSharp.Data.JsonProvider 11 | open ProviderImplementation.ProvidedTypes 12 | open System 13 | 14 | // Put any utility helpers here 15 | module internal Sample = 16 | open System.Net 17 | open TypeInference 18 | 19 | let (|RelativeFileResource|FileResource|WebResource|Json|) (sample: string, ctx: Context) = 20 | let invalidPathChars = Path.GetInvalidPathChars() 21 | let isValidPath = 22 | sample 23 | |> Seq.tryFind (fun ch -> Array.contains ch invalidPathChars) 24 | |> Option.isNone 25 | 26 | if sample.StartsWith("http") then 27 | WebResource 28 | elif sample.StartsWith("{") || sample.StartsWith("[") then 29 | Json 30 | elif isValidPath && File.Exists(ctx.GetRelativeFilePath sample) then 31 | RelativeFileResource 32 | elif isValidPath && File.Exists(sample) then 33 | FileResource 34 | else 35 | Json 36 | 37 | let load (encoding: Encoding) (ctx: Context) (sample: string) (resource: string option) = 38 | let load() = 39 | let sample = sample.Trim() 40 | let readFile file = 41 | if File.Exists(file) then 42 | File.OpenRead(file) |> readStream encoding 43 | else 44 | invalidArg "sample" <| sprintf """Couldn't find file \"%s\" """ file 45 | match (sample, ctx) with 46 | | WebResource -> 47 | let response = WebRequest.Create(sample).GetResponse() 48 | response.GetResponseStream() |> readStream encoding 49 | | RelativeFileResource -> 50 | let file = ctx.GetRelativeFilePath sample 51 | readFile file 52 | | FileResource -> 53 | readFile sample 54 | | Json -> 55 | sample 56 | 57 | match resource with 58 | | Some(resource) -> 59 | Logging.log <| sprintf "Looking for resource: %s" resource 60 | match ctx.ReadResource(resource, encoding) with 61 | | Some(sample) -> 62 | Logging.log <| sprintf "Returning from resource: %s" sample 63 | sample 64 | | None -> 65 | load() 66 | | None -> 67 | load() 68 | 69 | let parse (sample: string): JToken = 70 | let sample = sample.Trim() 71 | let parseAsJObject str = JObject.Parse(str) :> JToken 72 | let parseAsJArray str = JArray.Parse(str) :> JToken 73 | let parseAsJValue str = JValue.Parse(str) 74 | 75 | match tryFirst sample [parseAsJObject; parseAsJArray; parseAsJValue] with 76 | | Ok(token) -> 77 | token 78 | | Error(message) -> 79 | failwith message 80 | 81 | let getDeserializeQuotation (token: JToken) sample sampleType = 82 | match TypeInference.readToken token with 83 | | Value(Boolean(value)) -> 84 | <@@ value @@> 85 | | Value(Int(value)) -> 86 | <@@ value @@> 87 | | Value(Long(value)) -> 88 | <@@ value @@> 89 | | Value(Float(value)) -> 90 | <@@ value @@> 91 | | Value(String(value)) -> 92 | <@@ value @@> 93 | | _ -> 94 | <@@ Json.deserialize sample sampleType @@> 95 | 96 | 97 | [] 98 | type JsonProvider (config : TypeProviderConfig) as this = 99 | inherit TypeProviderForNamespaces (config, assemblyReplacementMap=[("JsonProvider.DesignTime", "JsonProvider.Runtime")], addDefaultProbingLocation=true) 100 | 101 | let providerTypeName = "JsonProvider" 102 | let ns = "FSharp.Data.JsonProvider" 103 | let execAsm = Assembly.GetExecutingAssembly() 104 | 105 | do execAsm.Location |> Path.GetDirectoryName |> this.RegisterProbingFolder 106 | 107 | // check we contain a copy of runtime files, and are not referencing the runtime DLL 108 | do assert (typeof<``Asm marker``>.Assembly.GetName().Name = execAsm.GetName().Name) 109 | 110 | let buildStaticParameters (typeName: string) (args: obj[]) = 111 | let context = Context(this, config.ResolutionFolder) 112 | 113 | let resource = args.[3] :?> string |> Option.ofObj 114 | let encoding = Encoding.GetEncoding(args.[2] :?> string) 115 | let rootTypeName = args.[1] :?> string 116 | let sample = Sample.load encoding context (args.[0] :?> string) resource 117 | let tokenizedSample = Sample.parse sample 118 | 119 | let asm = ProvidedAssembly() 120 | // Create root TP type specifing asm and ns 121 | let tpType = ProvidedTypeDefinition(asm, ns, typeName, Some typeof, isErased = false) 122 | 123 | let settings = { RootTypeName = rootTypeName; NullableTypes = args.[4] :?> bool } 124 | let sampleType = TypeInference.inferType tokenizedSample.Root tpType settings 125 | 126 | let sampleMethod = 127 | ProvidedMethod( 128 | methodName = "GetSampleJson", 129 | parameters = [], 130 | returnType = typeof, 131 | isStatic = true, 132 | invokeCode = 133 | fun args -> <@@ sample @@>) 134 | sampleMethod.AddXmlDoc("Returns json sample") 135 | tpType.AddMember(sampleMethod) 136 | 137 | let sampleValueMethod = 138 | ProvidedMethod( 139 | methodName = "GetSample", 140 | parameters = [], 141 | returnType = sampleType, 142 | isStatic = true, 143 | invokeCode = 144 | fun args -> Sample.getDeserializeQuotation tokenizedSample sample sampleType) 145 | sampleValueMethod.AddXmlDoc("Returns deserialized sample") 146 | tpType.AddMember(sampleValueMethod) 147 | 148 | let canBeParsed = 149 | (not sampleType.IsValueType) && (sampleType.FullName <> "System.String") 150 | 151 | if canBeParsed then 152 | let parseMethod = 153 | ProvidedMethod( 154 | methodName = "Parse", 155 | parameters = [ProvidedParameter("input", typeof)], 156 | returnType = sampleType, 157 | isStatic = true, 158 | invokeCode = 159 | fun args -> <@@ Json.deserialize (%%args.[0]: string) sampleType @@>) 160 | 161 | parseMethod.AddXmlDoc("Deserializes json input string to provided type") 162 | tpType.AddMember(parseMethod) 163 | 164 | asm.AddTypes([tpType]) 165 | tpType 166 | 167 | let staticParameters = 168 | [ ProvidedStaticParameter("Sample", typeof, parameterDefaultValue = String.Empty); 169 | ProvidedStaticParameter("RootTypeName", typeof, parameterDefaultValue = TypeInference.defaultRootTypeName); 170 | ProvidedStaticParameter("Encoding", typeof, parameterDefaultValue = "UTF-8"); 171 | ProvidedStaticParameter("EmbeddedResource", typeof, parameterDefaultValue = String.Empty); 172 | ProvidedStaticParameter("NullableValueTypes", typeof, parameterDefaultValue = false);] 173 | 174 | let summaryText = 175 | """A json typed representation 176 | Json sample, http url to json resource, relative or absolute path to a file 177 | The name to be used for the root type. Defaults to 'Root'. 178 | Sample encoding, default is 'UTF-8' 179 | Embedded resource which will be used as sample. Example: "MyLib, resource.json" 180 | Make value types nullable""" 181 | 182 | let generatedType = 183 | let providedType = ProvidedTypeDefinition(execAsm, ns, providerTypeName, baseType = Some typeof, isErased = false) 184 | providedType.DefineStaticParameters(staticParameters, buildStaticParameters) 185 | providedType.AddXmlDoc summaryText 186 | providedType 187 | do 188 | this.AddNamespace(ns, [generatedType]) 189 | 190 | 191 | [] 192 | do () 193 | -------------------------------------------------------------------------------- /src/JsonProvider.DesignTime/JsonProvider.DesignTime.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Library 6 | netstandard2.0;netcoreapp2.0;net45 7 | true 8 | true 9 | true 10 | PackageReference 11 | true 12 | 13 | 14 | 15 | 16 | True 17 | paket-files/ProvidedTypes.fsi 18 | 19 | 20 | True 21 | paket-files/ProvidedTypes.fs 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | PreserveNewest 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/JsonProvider.DesignTime/Logging.fs: -------------------------------------------------------------------------------- 1 | namespace FSharp.Data.JsonProvider 2 | 3 | module internal Logging = 4 | open System 5 | open System.IO 6 | open System.Threading 7 | 8 | let log = 9 | #if DEBUG 10 | let home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) 11 | let log = Path.Combine(home, "jsoninference_log.txt") 12 | fun (msg: string) -> 13 | let message = 14 | let time = DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss.fff") 15 | sprintf "[%s]: %s" time msg 16 | 17 | use mutex = new Mutex(false, "jsoninference_log.txt") 18 | mutex.WaitOne(TimeSpan.FromSeconds(3.0)) |> ignore 19 | File.AppendAllLines(log, [message]) 20 | mutex.ReleaseMutex() 21 | 22 | #else 23 | fun (msg: string) -> () 24 | #endif 25 | 26 | -------------------------------------------------------------------------------- /src/JsonProvider.DesignTime/TypeInference.fs: -------------------------------------------------------------------------------- 1 | namespace FSharp.Data.JsonProvider 2 | 3 | type internal TypeInferenceSettings = { RootTypeName: string; NullableTypes: bool } 4 | 5 | module internal TypeInference = 6 | open System 7 | open System.Linq 8 | open Newtonsoft.Json.Linq 9 | open ProviderImplementation.ProvidedTypes 10 | open System.Globalization 11 | open System.Threading 12 | open System.Collections.Generic 13 | 14 | type JsonValue = 15 | | String of string 16 | | Float of decimal 17 | | Int of int 18 | | Boolean of bool 19 | | Long of int64 20 | | Null 21 | 22 | type JsonTokenType = 23 | | Object of JObject 24 | | Property of JProperty 25 | | Array of JArray 26 | | Value of JsonValue 27 | 28 | let defaultRootTypeName = "Root" 29 | 30 | let readToken = 31 | let minValue = int64 Int32.MinValue 32 | let maxValue = int64 Int32.MaxValue 33 | 34 | fun (jToken: JToken) -> 35 | match jToken.Type with 36 | | JTokenType.Object -> 37 | Object(jToken :?> JObject) 38 | | JTokenType.Property -> 39 | Property(jToken :?> JProperty) 40 | | JTokenType.Array -> 41 | Array(jToken :?> JArray) 42 | | JTokenType.Integer -> 43 | let value = jToken.Value() 44 | if value > maxValue || value < minValue then 45 | Value(Long(value)) 46 | else 47 | Value(Int(int value)) 48 | | JTokenType.Float -> 49 | Value(Float(jToken.Value())) 50 | | JTokenType.Boolean -> 51 | Value(Boolean(jToken.Value())) 52 | | JTokenType.Undefined 53 | | JTokenType.Null -> 54 | Value(Null) 55 | | _ -> 56 | let strValue = jToken.Value() 57 | match stringToBool strValue with 58 | | BoolValue(value) -> 59 | Value(Boolean(value)) 60 | | NotBoolValue -> 61 | Value(String(strValue)) 62 | | NullValue -> 63 | Value(Null) 64 | 65 | let (|IntType|LongType|DecimalType|BooleanType|StringType|ObjectType|MixedType|) (tokens: JsonTokenType list) = 66 | let tokens = tokens |> List.filter (function Value(Null) -> false | _ -> true) 67 | 68 | let checkType predicate = 69 | tokens |> List.forall predicate 70 | 71 | let isPrimitive = 72 | function Value(_) -> true | _ -> false 73 | 74 | let isInt = 75 | function (Value(Int(_))) -> true | _ -> false 76 | 77 | let isLong = 78 | function (Value(Long(_))) -> true | _ -> false 79 | 80 | let isFloat = 81 | function (Value(Float(_))) -> true | _ -> false 82 | 83 | let isBoolean = 84 | function (Value(Boolean(_))) -> true | _ -> false 85 | 86 | let isFloatOrInt value = 87 | match value with 88 | | Value(valueType) -> 89 | match valueType with 90 | | Float(_) 91 | | Int(_) 92 | | Long(_) -> 93 | true 94 | | _ -> 95 | false 96 | | _ -> 97 | false 98 | 99 | let isInt32OrInt64 value = 100 | match value with 101 | | Value(valueType) -> 102 | match valueType with 103 | | Int(_) 104 | | Long(_) -> 105 | true 106 | | _ -> 107 | false 108 | | _ -> 109 | false 110 | 111 | let isObject = (function (Object(_)) -> true | _ -> false) 112 | 113 | if tokens.Length = 0 then 114 | StringType 115 | else 116 | match checkType isPrimitive with 117 | | true -> 118 | if checkType isFloat then 119 | DecimalType 120 | elif checkType isLong then 121 | LongType 122 | elif checkType isInt then 123 | IntType 124 | elif checkType isInt32OrInt64 then 125 | LongType 126 | elif checkType isFloatOrInt then 127 | DecimalType 128 | elif checkType isBoolean then 129 | BooleanType 130 | else 131 | StringType 132 | | false -> 133 | if checkType isObject then 134 | ObjectType 135 | else 136 | MixedType 137 | 138 | let getParentNameOrDefault (jToken: JToken) defaultName = 139 | match Option.ofObj jToken.Parent with 140 | | Some(parent) -> 141 | match (readToken parent) with 142 | | Property(jProperty) -> 143 | prettyName jProperty.Name 144 | | _ -> 145 | defaultName 146 | | None -> 147 | defaultName 148 | 149 | let inferType root (tpType: ProvidedTypeDefinition) (settings: TypeInferenceSettings)= 150 | Logging.log <| sprintf "Start type inference" 151 | 152 | let inline preprocessType typ = 153 | if settings.NullableTypes then 154 | createNullableType typ 155 | else 156 | typ 157 | 158 | let getUniqueTypeName = 159 | let store = new Dictionary() 160 | fun name -> 161 | if store.ContainsKey(name) then 162 | sprintf "%s%i" name (Interlocked.Increment(store.[name])) 163 | else 164 | store.Add(name, ref 0) 165 | name 166 | 167 | let createTypeDefinition typeName = 168 | let typeName = typeName |> getUniqueTypeName 169 | let genType = createType typeName 170 | tpType.AddMember(genType) 171 | Logging.log <| sprintf "Generated type full name: %s" genType.FullName 172 | genType 173 | 174 | let createRootType() = 175 | let typeName = 176 | match String.IsNullOrWhiteSpace(settings.RootTypeName) with 177 | | true -> 178 | defaultRootTypeName 179 | | false -> 180 | settings.RootTypeName 181 | Logging.log <| sprintf "Root type name: %s" typeName 182 | createTypeDefinition typeName 183 | 184 | let rec processToken (token: JToken) (generatedType: ProvidedTypeDefinition option) = 185 | match readToken token with 186 | | Property(jProperty) -> 187 | let name = jProperty.Name 188 | Logging.log <| sprintf "Property name: %s" name 189 | 190 | let generatedType = Option.get generatedType 191 | Logging.log <| sprintf "Property parent type name: %s" generatedType.FullName 192 | 193 | let inferredType = processToken jProperty.First (Some(generatedType)) 194 | 195 | let field, prop = createAutoProperty name (generatedType :> Type) inferredType 196 | 197 | Logging.log <| sprintf "Property type full name: %s" field.FieldType.FullName 198 | 199 | generatedType.AddMember(prop) 200 | generatedType.AddMember(field) 201 | 202 | Logging.log <| sprintf "Property declaring type full name: %s" field.DeclaringType.FullName 203 | 204 | generatedType :> Type 205 | | Object(jObject) -> 206 | let generatedType = 207 | match generatedType with 208 | | None -> 209 | createRootType() 210 | | Some(_) -> 211 | let typeName = getParentNameOrDefault jObject "ProvidedType" 212 | Logging.log <| sprintf "Object type name: %s" typeName 213 | createTypeDefinition typeName 214 | Logging.log <| sprintf "Object type full name: %s" generatedType.FullName 215 | 216 | jObject 217 | |> Seq.iter (fun prop -> processToken prop (Some(generatedType)) |> ignore) 218 | 219 | generatedType :> Type 220 | | Array(jArray) -> 221 | processArrayToken jArray generatedType 222 | | Value(value) -> 223 | match value with 224 | | Boolean(_) -> 225 | typeof |> preprocessType 226 | | Int(_) -> 227 | typeof |> preprocessType 228 | | Long(_) -> 229 | typeof |> preprocessType 230 | | Float(_) -> 231 | typeof |> preprocessType 232 | | String(_) | Null -> 233 | typeof 234 | 235 | and processArrayToken (jArray: JArray) generatedType = 236 | let tokens = 237 | jArray 238 | |> Seq.map readToken 239 | |> List.ofSeq 240 | 241 | match tokens with 242 | | DecimalType -> 243 | typeof |> preprocessType |> createArrayType 244 | | LongType -> 245 | typeof |> preprocessType |> createArrayType 246 | | IntType -> 247 | typeof |> preprocessType |> createArrayType 248 | | BooleanType -> 249 | typeof |> preprocessType |> createArrayType 250 | | StringType -> 251 | typeof |> createArrayType 252 | | MixedType -> 253 | typeof 254 | | ObjectType -> 255 | let jObj = 256 | jArray 257 | |> Seq.collect (fun jobj -> (jobj :?> JObject).Properties()) 258 | |> Seq.distinctBy (fun prop -> prop.Name) 259 | |> List.ofSeq 260 | |> JObject 261 | 262 | //stub property so we infer type name later 263 | let name = getParentNameOrDefault jArray "ProvidedArray" 264 | let parent = JProperty(name, jObj) 265 | processToken (parent.First) generatedType |> createArrayType 266 | 267 | processToken root None 268 | -------------------------------------------------------------------------------- /src/JsonProvider.DesignTime/TypeProviderHelpers.fs: -------------------------------------------------------------------------------- 1 | #nowarn "0025" 2 | #nowarn "0067" 3 | 4 | namespace FSharp.Data.JsonProvider 5 | 6 | open Microsoft.FSharp.Quotations 7 | open ProviderImplementation.ProvidedTypes.UncheckedQuotations 8 | open ProviderImplementation.ProvidedTypes 9 | open System 10 | open System.IO 11 | open System.Text 12 | 13 | [] 14 | module internal TypeProviderHelpers = 15 | open System.Collections.Generic 16 | 17 | let prettyName (name: string) = 18 | let mutable fx = Char.ToUpper 19 | String 20 | [| for c in Seq.skipWhile (not << Char.IsLetter) name do 21 | if Char.IsLetter c then 22 | yield fx c 23 | fx <- id 24 | elif Char.IsDigit c then 25 | yield c 26 | else 27 | fx <- Char.ToUpper 28 | |] 29 | 30 | let getPropertyNameAttribute name = 31 | { new Reflection.CustomAttributeData() with 32 | member __.Constructor = typeof.GetConstructor([|typeof|]) 33 | member __.ConstructorArguments = [|Reflection.CustomAttributeTypedArgument(typeof, name)|] :> IList<_> 34 | member __.NamedArguments = [||] :> IList<_> } 35 | 36 | let createType typeName = 37 | let typ = ProvidedTypeDefinition(typeName, baseType = Some typeof, isErased = false, isSealed = false) 38 | // Add default constructor (Otherwise Json.NET deserializer will noy be able to create an instance) 39 | typ.AddMember <| ProvidedConstructor([], invokeCode = fun _ -> <@@ () @@>) 40 | typ 41 | 42 | let createAutoProperty (propName: string) (targetType: Type) typ = 43 | let typeProperties = 44 | targetType.GetProperties() 45 | |> Seq.map (fun prop -> prop.Name) 46 | |> List.ofSeq 47 | 48 | let propertyName = 49 | let prettyPropName = prettyName propName 50 | 51 | let checkName name = 52 | typeProperties |> List.contains name 53 | 54 | if not <| checkName prettyPropName then 55 | prettyPropName 56 | else 57 | let rec getNextProprtyName name count = 58 | let uniqueName = sprintf "%s%i" name count 59 | if not <| checkName uniqueName then 60 | uniqueName 61 | else 62 | getNextProprtyName name (count + 1) 63 | getNextProprtyName prettyPropName 1 64 | 65 | let providedField = ProvidedField("_" + propertyName, typ) 66 | let providedProperty = 67 | ProvidedProperty(propertyName, typ, 68 | getterCode = (fun [this] -> Expr.FieldGetUnchecked(this, providedField)), 69 | setterCode = (fun [this; v] -> Expr.FieldSetUnchecked(this, providedField, v))) 70 | providedProperty.AddXmlDoc(sprintf """Corresponds to property "%s" in object""" propName) 71 | 72 | if propName <> propertyName then 73 | getPropertyNameAttribute propName 74 | |> providedProperty.AddCustomAttribute 75 | 76 | providedField, providedProperty 77 | 78 | let createArrayType (ty: Type) = ty.MakeArrayType() 79 | 80 | let createNullableType (ty: Type) = 81 | if ty.IsValueType then 82 | typedefof>.MakeGenericType(ty) 83 | else 84 | ty 85 | 86 | [] 87 | module Utility = 88 | open System.Globalization 89 | 90 | let readStream (encoding: Encoding) (stream: Stream) = 91 | use reader = new StreamReader(stream, encoding) 92 | reader.ReadToEnd() 93 | 94 | let tryFirst (parameter: 'T) (actions: list<'T -> 'TResult>) = 95 | let rec tryExecute actionsToTry lastErrorMsg = 96 | match actionsToTry with 97 | | action :: tail -> 98 | try 99 | Ok(action parameter) 100 | with 101 | | :? Exception as e -> 102 | tryExecute tail e.Message 103 | | [] -> 104 | Error(lastErrorMsg) 105 | tryExecute actions String.Empty 106 | 107 | type BoolParseResult = 108 | | BoolValue of bool 109 | | NotBoolValue 110 | | NullValue 111 | 112 | let stringToBool (str: string) = 113 | let str = str.ToLower(CultureInfo.InvariantCulture).Trim() 114 | if String.IsNullOrWhiteSpace(str) then NullValue 115 | elif str = "false" then BoolValue(false) 116 | elif str = "true" then BoolValue(true) 117 | else NotBoolValue 118 | 119 | type internal Context(tp: TypeProviderForNamespaces, resolutionFolder: string) = 120 | 121 | member __.ResolutionFolder = resolutionFolder 122 | 123 | member __.GetRelativeFilePath(relativePath: string) = 124 | let replaceAltChars (str: string) = 125 | match Environment.OSVersion.Platform with 126 | | PlatformID.Unix | PlatformID.MacOSX -> 127 | str.Replace('\\', Path.DirectorySeparatorChar) 128 | | _ -> 129 | str.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar) 130 | Path.GetFullPath(Path.Combine(resolutionFolder, replaceAltChars relativePath)) 131 | 132 | member __.ReadResource(resourceName: string, encoding: Encoding) = 133 | match resourceName.Split(',') with 134 | | [| asmName; name |] -> 135 | let asmName = asmName.Trim() 136 | let bindingContext = tp.TargetContext 137 | match bindingContext.TryBindSimpleAssemblyNameToTarget(asmName) with 138 | | Choice1Of2 asm -> 139 | let name = name.Trim() 140 | Logging.log <| sprintf "Found assembly for resource: %s" asm.FullName 141 | asm.GetManifestResourceStream(sprintf "%s.%s" asmName name) 142 | |> readStream encoding 143 | |> Some 144 | | _ -> 145 | None 146 | | _ -> 147 | None -------------------------------------------------------------------------------- /src/JsonProvider.DesignTime/paket.references: -------------------------------------------------------------------------------- 1 | FSharp.Core 2 | Newtonsoft.Json 3 | File:ProvidedTypes.fsi 4 | File:ProvidedTypes.fs -------------------------------------------------------------------------------- /src/JsonProvider.Runtime/AssemblyInfo.fs: -------------------------------------------------------------------------------- 1 | // Auto-Generated by FAKE; do not edit 2 | namespace System 3 | open System.Reflection 4 | 5 | do () 6 | -------------------------------------------------------------------------------- /src/JsonProvider.Runtime/JsonProvider.Runtime.fs: -------------------------------------------------------------------------------- 1 | namespace FSharp.Data.JsonProvider 2 | 3 | open Newtonsoft.Json 4 | open Newtonsoft.Json.Linq 5 | open System 6 | 7 | // Put any runtime constructs here 8 | type ``Asm marker``() = 9 | let dummy = () 10 | 11 | // Put any utility helpers here 12 | module Json = 13 | let inline deserialize (json: string) (typ: Type) = 14 | let settings = new JsonSerializerSettings() 15 | //https://github.com/JamesNK/Newtonsoft.Json/issues/862 16 | settings.DateParseHandling <- DateParseHandling.None 17 | JsonConvert.DeserializeObject(json, typ, settings) 18 | 19 | // Put the TypeProviderAssemblyAttribute in the runtime DLL, pointing to the design-time DLL 20 | [] 21 | do () 22 | -------------------------------------------------------------------------------- /src/JsonProvider.Runtime/JsonProvider.Runtime.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | Library 8 | netstandard2.0; net45 9 | true 10 | 11 | 12 | 13 | 14 | 15 | True 16 | paket-files/ProvidedTypes.fsi 17 | 18 | 19 | True 20 | paket-files/ProvidedTypes.fs 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/JsonProvider.Runtime/paket.references: -------------------------------------------------------------------------------- 1 | FSharp.Core 2 | Newtonsoft.Json 3 | File:ProvidedTypes.fsi 4 | File:ProvidedTypes.fs -------------------------------------------------------------------------------- /src/JsonProvider.Runtime/paket.template: -------------------------------------------------------------------------------- 1 | type file 2 | id FSharp.Data.JsonProvider 3 | include-pdbs true 4 | authors 5 | Liminiens, github contributors 6 | language 7 | F# 8 | owners 9 | Liminiens, github contributors 10 | projectUrl 11 | https://github.com/Liminiens/json-provider 12 | licenseUrl 13 | https://github.com/Liminiens/json-provider/blob/master/LICENSE.txt 14 | requireLicenseAcceptance 15 | false 16 | tags 17 | F# fsharp typeproviders JsonProvider json json.net 18 | summary 19 | Json generative type provider for F# and .NET. 20 | description 21 | Json generative type provider for F# and .NET. 22 | releaseNotes 23 | Added Nullable<'T> support 24 | tags 25 | F# fsharp typeproviders JsonProvider json json.net 26 | files 27 | bin/Release/net45/JsonProvider.Runtime.* ==> lib/net45 28 | bin/Release/netstandard2.0/JsonProvider.Runtime.* ==> lib/netstandard2.0 29 | bin/Release/typeproviders/fsharp41/netstandard2.0/*.dll ==> typeproviders/fsharp41/netstandard2.0 30 | bin/Release/typeproviders/fsharp41/netcoreapp2.0/*.dll ==> typeproviders/fsharp41/netcoreapp2.0 31 | bin/Release/typeproviders/fsharp41/net45/*.dll ==> typeproviders/fsharp41/net45 32 | references 33 | JsonProvider.Runtime.dll 34 | dependencies 35 | FSharp.Core >= LOCKEDVERSION 36 | Newtonsoft.Json >= LOCKEDVERSION 37 | -------------------------------------------------------------------------------- /tests/JsonProvider.Tests.Templates/JsonProvider.Tests.Templates.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /tests/JsonProvider.Tests.Templates/example_embed.json: -------------------------------------------------------------------------------- 1 | { 2 | "userId": 2, 3 | "id": 2, 4 | "title": "Title", 5 | "body": "Body" 6 | } -------------------------------------------------------------------------------- /tests/JsonProvider.Tests.Templates/paket.references: -------------------------------------------------------------------------------- 1 | FSharp.Core -------------------------------------------------------------------------------- /tests/JsonProvider.Tests/JsonProvider.Tests.fs: -------------------------------------------------------------------------------- 1 | module JsonProviderTests 2 | 3 | open FSharp.Data.JsonProvider 4 | open NUnit.Framework 5 | open Newtonsoft.Json.Linq 6 | 7 | module ArrayTests = 8 | type ArrayIntType = JsonProvider<"""{ "Data": [1, 2, 3] }"""> 9 | 10 | [] 11 | let ``Array int test`` () = 12 | let expected = [1; 2; 3] 13 | let data = ArrayIntType.GetSample().Data 14 | 15 | Assert.AreEqual(typeof, data.GetType()) 16 | CollectionAssert.AreEquivalent(expected, data) 17 | 18 | type ArrayDecimalType = JsonProvider<"""{ "Data": [1.2, 2, 3] }"""> 19 | 20 | [] 21 | let ``Array decimal test`` () = 22 | let expected = [1.2M; 2M; 3M] 23 | let data = ArrayDecimalType.GetSample().Data 24 | 25 | Assert.AreEqual(typeof, data.GetType()) 26 | CollectionAssert.AreEquivalent(expected, data) 27 | 28 | type ArrayLongType = JsonProvider<"""{ "Data": [100000000000, 2, 3] }"""> 29 | 30 | [] 31 | let ``Array long test`` () = 32 | let expected = [100000000000L; 2L; 3L] 33 | let data = ArrayLongType.GetSample().Data 34 | 35 | Assert.AreEqual(typeof, data.GetType()) 36 | CollectionAssert.AreEquivalent(expected, data) 37 | 38 | type ArrayObjectType = JsonProvider<"""{ "Data": [{"Test": 1}, {"Test": 2}] }"""> 39 | 40 | [] 41 | let ``Array simple object test`` () = 42 | let data = ArrayObjectType.GetSample().Data 43 | 44 | Assert.AreEqual("Data", data.[0].GetType().Name) 45 | Assert.AreEqual(1, data.[0].Test) 46 | Assert.AreEqual(2, data.[1].Test) 47 | 48 | 49 | type ArrayMixedType = JsonProvider<"""{ "Data": [{"Test": 1}, 2] }"""> 50 | 51 | [] 52 | let ``Array mixed test`` () = 53 | let data = ArrayMixedType.GetSample().Data 54 | 55 | Assert.AreEqual(1, data.SelectToken("[0].Test").Value()) 56 | Assert.AreEqual(2, data.[1].Value()) 57 | 58 | type ArrayBoolType = JsonProvider<"""{ "Data": ["true", false] }"""> 59 | 60 | [] 61 | let ``Array bool test`` () = 62 | let data = ArrayBoolType.GetSample().Data 63 | 64 | Assert.True(data.[0]) 65 | Assert.False(data.[1]) 66 | 67 | type ArraySampleObjectType = JsonProvider<"""[{"Test": 1}, {"Test": 2}]""", "Array"> 68 | 69 | [] 70 | let ``Array object sample test`` () = 71 | let sample = ArraySampleObjectType.GetSample() 72 | 73 | Assert.AreEqual(1, sample.[0].Test) 74 | Assert.AreEqual(2, sample.[1].Test) 75 | 76 | type ArraySampleIntType = JsonProvider<"""[1, 2]"""> 77 | 78 | [] 79 | let ``Array int sample test`` () = 80 | let sample = ArraySampleIntType.GetSample() 81 | 82 | Assert.AreEqual(1, sample.[0]) 83 | Assert.AreEqual(2, sample.[1]) 84 | 85 | type PlainObjectArrayType = JsonProvider<"""[{"Data": 1}]"""> 86 | 87 | [] 88 | let ``Plain object array test`` () = 89 | let sample = PlainObjectArrayType.GetSample() 90 | 91 | Assert.AreEqual(1, sample.[0].Data) 92 | 93 | type ArrayInPropertyTestType = JsonProvider<"""[{"Data": 1}]"""> 94 | 95 | [] 96 | let ``Type name of array in proprty test`` () = 97 | let sample = ArrayInPropertyTestType.GetSample() 98 | 99 | Assert.AreEqual(1, sample.[0].Data) 100 | 101 | module ObjectTests = 102 | type NullType = JsonProvider<"""{"Data": null}"""> 103 | 104 | [] 105 | let ``Property null test`` () = 106 | let data = NullType.GetSample().Data 107 | 108 | Assert.IsNull(data) 109 | 110 | type SameNameDifferentCaseType = JsonProvider<"""{"data": 1, "Data ": 2, "dAtA": 3, "DaTa": 4}"""> 111 | 112 | [] 113 | let ``Same name different case test`` () = 114 | let sample = SameNameDifferentCaseType.Parse("""{"data": 10, "Data ": 11, "dAtA": 12, "DaTa": 13}""") 115 | 116 | Assert.AreEqual(10, sample.Data) 117 | Assert.AreEqual(11, sample.Data1) 118 | Assert.AreEqual(12, sample.DAtA) 119 | Assert.AreEqual(13, sample.DaTa) 120 | 121 | module MiscTests = 122 | type RootNameCheckType = JsonProvider<"{}", "Something"> 123 | 124 | [] 125 | let ``Root name setting test`` () = 126 | RootNameCheckType.Something() |> ignore 127 | Assert.True(true) 128 | 129 | type RootNameEmptyType = JsonProvider<"{}", ""> 130 | 131 | [] 132 | let ``Root name empty test`` () = 133 | RootNameEmptyType.Root() |> ignore 134 | Assert.True(true) 135 | 136 | type RootNameWhitespaceType = JsonProvider<"{}", " "> 137 | 138 | [] 139 | let ``Root name whitespace test`` () = 140 | RootNameWhitespaceType.Root() |> ignore 141 | Assert.True(true) 142 | 143 | type StrangeBoolType = JsonProvider<"""["fAlSe", false, "TrUE"]"""> 144 | 145 | [] 146 | let ``Strange bool parsed correctly`` () = 147 | let data = StrangeBoolType.GetSample() 148 | 149 | Assert.False(data.[0]) 150 | Assert.False(data.[1]) 151 | Assert.True(data.[2]) 152 | 153 | let parsed = StrangeBoolType.Parse("""["TruE", false, "TRUE"]""") 154 | 155 | Assert.True(parsed.[0]) 156 | Assert.False(parsed.[1]) 157 | Assert.True(parsed.[2]) 158 | 159 | type CaseTestType = JsonProvider<"""{"11__)123 data1-test_1value space": 10}"""> 160 | 161 | [] 162 | let ``Symbols and property case test`` () = 163 | let data = CaseTestType.GetSample() 164 | 165 | Assert.AreEqual(10, data.Data1Test1ValueSpace) 166 | 167 | type NumbersInNameTestType = JsonProvider<"""{"100Data1Value100": 10}"""> 168 | 169 | [] 170 | let ``Name with numbers parsed correctly`` () = 171 | let data = NumbersInNameTestType.GetSample() 172 | 173 | Assert.AreEqual(10, data.Data1Value100) 174 | 175 | module JsonValueTests = 176 | type BoolType = JsonProvider<"false"> 177 | type IntType = JsonProvider<"123"> 178 | type StringType = JsonProvider< """ "Test" """> 179 | 180 | [] 181 | let ``Test value parser`` () = 182 | let boolValue = BoolType.GetSample() 183 | let intValue = IntType.GetSample() 184 | let stringValue = StringType.GetSample() 185 | 186 | Assert.AreEqual(123, intValue) 187 | Assert.AreEqual("Test", stringValue) 188 | Assert.IsFalse(boolValue) 189 | 190 | module JsonNetTests = 191 | type DateCheckType = JsonProvider<"""{ "x": "2016-03-31T07:02:00+07:00" }"""> 192 | 193 | [] 194 | let ``Date parsed correctly by Json.NET`` () = 195 | let value = DateCheckType.GetSample().X 196 | 197 | Assert.AreEqual("2016-03-31T07:02:00+07:00", value) 198 | 199 | module HttpTests = 200 | type HttpType = JsonProvider<"""https://jsonplaceholder.typicode.com/posts/1"""> 201 | 202 | [] 203 | let ``Http resource loads`` () = 204 | let data = HttpType.GetSample() 205 | 206 | Assert.AreEqual(1, data.UserId) 207 | Assert.AreEqual(1, data.Id) 208 | Assert.IsNotNull(data.Body) 209 | Assert.IsNotNull(data.Title) 210 | 211 | module FileTests = 212 | type RelativeFileTestType = JsonProvider<"""files\example.json"""> 213 | 214 | [] 215 | let ``File resource loads`` () = 216 | let data = RelativeFileTestType.GetSample() 217 | 218 | Assert.AreEqual(1, data.UserId) 219 | Assert.AreEqual(1, data.Id) 220 | Assert.AreEqual("Body", data.Body) 221 | Assert.AreEqual("Title", data.Title) 222 | 223 | type FileAltCharTestType = JsonProvider<"""files/example.json"""> 224 | 225 | [] 226 | let ``File with alt char path loads`` () = 227 | let data = FileAltCharTestType.GetSample() 228 | 229 | Assert.AreEqual(1, data.UserId) 230 | Assert.AreEqual(1, data.Id) 231 | Assert.AreEqual("Body", data.Body) 232 | Assert.AreEqual("Title", data.Title) 233 | 234 | type RelativeFileTestBelowType = JsonProvider<"""../JsonProvider.Tests.Templates/example_embed.json"""> 235 | 236 | [] 237 | let ``Can use folders below resolution root`` () = 238 | let data = RelativeFileTestBelowType.GetSample() 239 | 240 | Assert.AreEqual(2, data.UserId) 241 | Assert.AreEqual(2, data.Id) 242 | Assert.AreEqual("Body", data.Body) 243 | Assert.AreEqual("Title", data.Title) 244 | 245 | module EmbeddedResources = 246 | type EmbedTestType = JsonProvider 247 | 248 | [] 249 | let ``Can read from embeded resource`` () = 250 | let data = EmbedTestType.GetSample() 251 | 252 | Assert.AreEqual(2, data.UserId) 253 | Assert.AreEqual(2, data.Id) 254 | Assert.AreEqual("Body", data.Body) 255 | Assert.AreEqual("Title", data.Title) 256 | 257 | module NullableValueTypes = 258 | open System 259 | 260 | type NullableType = JsonProvider<""" { "Value": 123, "Array": [5], "Obj": { Value: 11.5 }, "ArrayWithNulls": [null, 2] } """, NullableValueTypes = true> 261 | 262 | [] 263 | let ``Nullable of T tests`` () = 264 | let data = NullableType.GetSample() 265 | 266 | let getValue (value: Nullable<'T>) = value.Value 267 | 268 | Assert.AreEqual(123, getValue data.Value) 269 | Assert.AreEqual(11.5, getValue data.Obj.Value) 270 | Assert.AreEqual(5, getValue data.Array.[0]) 271 | Assert.AreEqual(5, getValue data.Array.[0]) 272 | Assert.IsNull(data.ArrayWithNulls.[0]) 273 | Assert.AreEqual(2, getValue data.ArrayWithNulls.[1]) -------------------------------------------------------------------------------- /tests/JsonProvider.Tests/JsonProvider.Tests.fsproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp2.0;net461 5 | true 6 | true 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | JsonProvider.Runtime 19 | {7e90d6ce-a10b-4858-a5bc-41df7250cbca} 20 | True 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /tests/JsonProvider.Tests/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /tests/JsonProvider.Tests/files/example.json: -------------------------------------------------------------------------------- 1 | { 2 | "userId": 1, 3 | "id": 1, 4 | "title": "Title", 5 | "body": "Body" 6 | } -------------------------------------------------------------------------------- /tests/JsonProvider.Tests/paket.references: -------------------------------------------------------------------------------- 1 | group Test 2 | NUnit 3 | FSharp.Core 4 | --------------------------------------------------------------------------------