├── .gitignore ├── .vscode ├── launch.json ├── settings.json ├── symbols.json └── tasks.json ├── .vscodeignore ├── CHANGELOG.md ├── README.md ├── dist ├── odatajs-4.0.0.js ├── odatajs.d.ts ├── odataproxybase.ts ├── odataproxybaseAsync.ts ├── odataproxybaseAsyncModular.ts └── templates │ ├── interfaces.ot │ ├── promise │ ├── odatajs.d.ts │ ├── odatajs.js │ ├── proxy.ot │ └── templateinfo.json │ └── proxy.ot ├── images ├── demo1.gif └── odata.png ├── package.json ├── recentlyused.json ├── src ├── Settings.ts ├── extension.ts ├── helper.ts ├── log.ts ├── v040 │ ├── odataCrawler.ts │ └── proxyGenerator.ts ├── v100 │ ├── odataCrawler.ts │ └── proxyGenerator.ts └── v200 │ ├── odataCrawler.ts │ ├── outtypes.ts │ ├── proxyGenerator.ts │ ├── templateProvider.ts │ └── v200commands.ts ├── templateProvider ├── index.json └── ts-promise │ ├── README.md │ ├── odatajs.d.ts │ ├── odatajs.js │ └── proxy.ot ├── test ├── ODataTestService │ ├── ODataExtensions │ │ ├── ExpandSourceAttribute.cs │ │ ├── ExtendedODataConventionModelBuilder.cs │ │ ├── ExternalSource.cs │ │ ├── ODataBaseController.cs │ │ ├── ODataExtensions.csproj │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── app.config │ │ └── packages.config │ ├── ODataTestService.Tests │ │ ├── ODataTestService.Tests.csproj │ │ ├── Properties │ │ │ └── AssemblyInfo.cs │ │ ├── UnitTest1.cs │ │ └── app.config │ ├── ODataTestService.sln │ └── ODataTestService │ │ ├── App_Start │ │ └── WebApiConfig.cs │ │ ├── ApplicationInsights.config │ │ ├── Controllers │ │ ├── AddressesController.cs │ │ ├── CustomersController.cs │ │ ├── MoviesController.cs │ │ └── UnboundController.cs │ │ ├── Global.asax │ │ ├── Global.asax.cs │ │ ├── Models │ │ ├── Address.cs │ │ ├── Customer.cs │ │ ├── Gender.cs │ │ └── Movie.cs │ │ ├── ODataTestService.csproj │ │ ├── ODataTestService.csproj.user │ │ ├── Properties │ │ └── AssemblyInfo.cs │ │ ├── Web.Debug.config │ │ ├── Web.Release.config │ │ ├── Web.config │ │ └── packages.config └── testproject │ ├── .vscode │ ├── launch.json │ ├── odatatools │ │ ├── recentlyused.json │ │ └── templates │ │ │ ├── odatajs.d.ts │ │ │ ├── odatajs.js │ │ │ ├── proxy.ot │ │ │ ├── proxy.ot.json │ │ │ ├── proxy2.ot │ │ │ └── templateinfo.json │ ├── settings.json │ └── tasks.json │ ├── debug.log │ ├── index.js │ ├── index.js.map │ ├── index.ts │ ├── interfaces.d.ts │ ├── package.json │ ├── proxy │ ├── northwind.ts │ ├── odatajs.js │ ├── odataproxybase.js.map │ ├── proxy.js.map │ ├── testproxy.js │ ├── testproxy.js.map │ ├── testproxy.ts │ └── testproxy2.js.map │ ├── test │ ├── odataproxybase.js.map │ ├── odataservicetests.html │ ├── odataservicetests.js │ ├── odataservicetests.js.map │ ├── odataservicetests.ts │ └── qunit-2.1.1.js │ ├── tsconfig.json │ └── typings │ ├── globals │ └── qunit │ │ ├── index.d.ts │ │ └── typings.json │ └── index.d.ts ├── testrequests.http ├── tsconfig.json ├── typings └── edm.d.ts └── wiki ├── Graphics.pptx └── clientGenerator.png /.gitignore: -------------------------------------------------------------------------------- 1 | out 2 | node_modules 3 | /test/ODataTestService/.vs 4 | /test/ODataTestService/ODataExtensions/bin/Debug 5 | /test/ODataTestService/ODataExtensions/obj/Debug 6 | /test/ODataTestService/ODataTestService/bin 7 | /test/ODataTestService/ODataTestService/obj/Debug 8 | /test/ODataTestService/ODataTestService/obj/Debug 9 | /test/ODataTestService/ODataTestService.Tests/obj/Debug 10 | /test/ODataTestService/ODataTestService/obj/Debug/TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs 11 | /test/ODataTestService/ODataTestService/obj/Debug/TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs 12 | /test/ODataTestService/ODataTestService/obj/Debug/TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs 13 | /test/ODataTestService/ODataTestService/obj/Debug/ODataTestService.pdb 14 | /test/ODataTestService/ODataTestService/obj/Debug/ODataTestService.dll 15 | /test/ODataTestService/ODataTestService/obj/Debug/ODataTestService.csprojResolveAssemblyReference.cache 16 | /test/ODataTestService/ODataTestService/obj/Debug/ODataTestService.csproj.FileListAbsolute.txt 17 | /test/ODataTestService/ODataTestService/obj/Debug/DesignTimeResolveAssemblyReferencesInput.cache 18 | /test/ODataTestService/packages 19 | /test/ODataTestService/ODataTestService.Tests/bin/Debug 20 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that compiles the extension and then opens it inside a new window 2 | { 3 | "version": "0.2.0", 4 | "configurations": [ 5 | { 6 | "name": "Launch Extension", 7 | "type": "extensionHost", 8 | "request": "launch", 9 | "runtimeExecutable": "${execPath}", 10 | "args": ["--extensionDevelopmentPath=${workspaceRoot}" ], 11 | "stopOnEntry": false, 12 | "sourceMaps": true, 13 | "outFiles": ["${workspaceRoot}/out/src"], 14 | "preLaunchTask": "npm" 15 | }, 16 | { 17 | "name": "Launch Tests", 18 | "type": "extensionHost", 19 | "request": "launch", 20 | "runtimeExecutable": "${execPath}", 21 | "args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/test" ], 22 | "stopOnEntry": false, 23 | "sourceMaps": true, 24 | "outFiles": ["${workspaceRoot}/test"], 25 | "preLaunchTask": "npm" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.exclude": { 4 | "out": true, // set this to true to hide the "out" folder with the compiled JS files 5 | "node_modules": true 6 | }, 7 | "search.exclude": { 8 | "out": true // set this to false to include "out" folder in search results 9 | }, 10 | "typescript.tsdk": "./node_modules/typescript/lib", // we want to use the TS server from our node_modules folder to control its version 11 | "markdown-toc.orderedList": true, 12 | "markdown-toc.anchorMode": "github.com", 13 | "markdown-toc.depthFrom": 2, 14 | "markdown-toc.depthTo": 4, 15 | "vsicons.presets.angular": false, 16 | "markdownlint.config": { 17 | "MD013": false, 18 | "MD024": false 19 | } 20 | } -------------------------------------------------------------------------------- /.vscode/symbols.json: -------------------------------------------------------------------------------- 1 | {"symbols":{"odatatools.ProxyBase":{"hasNamespace":true,"type":0,"moduleName":"odataproxybase","relativePath":"test\\testproject\\proxy\\odataproxybase"},"odatatools.EntitySet":{"hasNamespace":true,"type":0,"moduleName":"odataproxybase","relativePath":"test\\testproject\\proxy\\odataproxybase"},"odatatools.EntityContainer":{"hasNamespace":true,"type":0,"moduleName":"odataproxybase","relativePath":"test\\testproject\\proxy\\odataproxybase"},"odatatools.ThenableCaller":{"hasNamespace":true,"type":0,"moduleName":"odataproxybase","relativePath":"test\\testproject\\proxy\\odataproxybase"},"odatatools.Thenable":{"hasNamespace":true,"type":1,"moduleName":"odataproxybase","relativePath":"test\\testproject\\proxy\\odataproxybase"},"odatajs.oData":{"hasNamespace":true,"type":0,"moduleName":"odataproxybase","relativePath":"test\\testproject\\proxy\\odataproxybase"},"odatajs.Request":{"hasNamespace":true,"type":1,"moduleName":"odataproxybase","relativePath":"test\\testproject\\proxy\\odataproxybase"},"odatajs.Header":{"hasNamespace":true,"type":1,"moduleName":"odataproxybase","relativePath":"test\\testproject\\proxy\\odataproxybase"},"Global":{"hasNamespace":false,"type":0,"moduleName":"extension","relativePath":"src\\extension"},"EntitySet":{"hasNamespace":false,"type":1,"moduleName":"edm.d","relativePath":"typings\\edm.d"},"EdmxBase":{"hasNamespace":false,"type":1,"moduleName":"edm.d","relativePath":"typings\\edm.d"},"Edmx":{"hasNamespace":false,"type":1,"moduleName":"edm.d","relativePath":"typings\\edm.d"},"DataService":{"hasNamespace":false,"type":1,"moduleName":"edm.d","relativePath":"typings\\edm.d"},"Schema":{"hasNamespace":false,"type":1,"moduleName":"edm.d","relativePath":"typings\\edm.d"},"EntityContainer":{"hasNamespace":false,"type":1,"moduleName":"edm.d","relativePath":"typings\\edm.d"},"NavigationPropertyBinding":{"hasNamespace":false,"type":1,"moduleName":"edm.d","relativePath":"typings\\edm.d"},"EnumType":{"hasNamespace":false,"type":1,"moduleName":"edm.d","relativePath":"typings\\edm.d"},"NavigationProperty":{"hasNamespace":false,"type":1,"moduleName":"edm.d","relativePath":"typings\\edm.d"},"ComplexType":{"hasNamespace":false,"type":1,"moduleName":"edm.d","relativePath":"typings\\edm.d"},"Property":{"hasNamespace":false,"type":1,"moduleName":"edm.d","relativePath":"typings\\edm.d"},"EntityType":{"hasNamespace":false,"type":1,"moduleName":"edm.d","relativePath":"typings\\edm.d"},"Method":{"hasNamespace":false,"type":1,"moduleName":"edm.d","relativePath":"typings\\edm.d"},"ReturnType":{"hasNamespace":false,"type":1,"moduleName":"edm.d","relativePath":"typings\\edm.d"},"Parameter":{"hasNamespace":false,"type":1,"moduleName":"edm.d","relativePath":"typings\\edm.d"},"Ifmdatalink.Linerecorder.Backend.PlugIn.dto.HostDto":{"hasNamespace":true,"type":1,"moduleName":"interfaces.d","relativePath":"test\\testproject\\interfaces.d"},"Ifmdatalink.Linerecorder.Backend.PlugIn.dto.DeltaHostDto":{"hasNamespace":true,"type":1,"moduleName":"interfaces.d","relativePath":"test\\testproject\\interfaces.d"},"Ifmdatalink.Linerecorder.Backend.PlugIn.dto.AgentDto":{"hasNamespace":true,"type":1,"moduleName":"interfaces.d","relativePath":"test\\testproject\\interfaces.d"},"Ifmdatalink.Linerecorder.Backend.PlugIn.dto.DeltaAgentDto":{"hasNamespace":true,"type":1,"moduleName":"interfaces.d","relativePath":"test\\testproject\\interfaces.d"},"Ifmdatalink.Linerecorder.Backend.PlugIn.dto.AgentTemplateDto":{"hasNamespace":true,"type":1,"moduleName":"interfaces.d","relativePath":"test\\testproject\\interfaces.d"},"Ifmdatalink.Linerecorder.Backend.PlugIn.dto.DeltaAgentTemplateDto":{"hasNamespace":true,"type":1,"moduleName":"interfaces.d","relativePath":"test\\testproject\\interfaces.d"},"Ifmdatalink.Linerecorder.Backend.PlugIn.dto.AgentTemplateVersionDto":{"hasNamespace":true,"type":1,"moduleName":"interfaces.d","relativePath":"test\\testproject\\interfaces.d"},"Ifmdatalink.Linerecorder.Backend.PlugIn.dto.DeltaAgentTemplateVersionDto":{"hasNamespace":true,"type":1,"moduleName":"interfaces.d","relativePath":"test\\testproject\\interfaces.d"},"Ifmdatalink.Linerecorder.Backend.PlugIn.dto.UserUserDto":{"hasNamespace":true,"type":1,"moduleName":"interfaces.d","relativePath":"test\\testproject\\interfaces.d"},"Ifmdatalink.Linerecorder.Backend.PlugIn.dto.DeltaUserUserDto":{"hasNamespace":true,"type":1,"moduleName":"interfaces.d","relativePath":"test\\testproject\\interfaces.d"},"Ifmdatalink.Linerecorder.Backend.PlugIn.dto.AgentVersionDto":{"hasNamespace":true,"type":1,"moduleName":"interfaces.d","relativePath":"test\\testproject\\interfaces.d"},"Ifmdatalink.Linerecorder.Backend.PlugIn.dto.DeltaAgentVersionDto":{"hasNamespace":true,"type":1,"moduleName":"interfaces.d","relativePath":"test\\testproject\\interfaces.d"},"Ifmdatalink.Linerecorder.Backend.PlugIn.dto.RuntimeInfoDto":{"hasNamespace":true,"type":1,"moduleName":"interfaces.d","relativePath":"test\\testproject\\interfaces.d"},"Ifmdatalink.Linerecorder.Backend.PlugIn.dto.DeltaRuntimeInfoDto":{"hasNamespace":true,"type":1,"moduleName":"interfaces.d","relativePath":"test\\testproject\\interfaces.d"},"Ifmdatalink.Linerecorder.Backend.PlugIn.dto.LayoutObjectDto":{"hasNamespace":true,"type":1,"moduleName":"interfaces.d","relativePath":"test\\testproject\\interfaces.d"},"Ifmdatalink.Linerecorder.Backend.PlugIn.dto.DeltaLayoutObjectDto":{"hasNamespace":true,"type":1,"moduleName":"interfaces.d","relativePath":"test\\testproject\\interfaces.d"},"Ifmdatalink.Linerecorder.Backend.PlugIn.Version":{"hasNamespace":true,"type":1,"moduleName":"interfaces.d","relativePath":"test\\testproject\\interfaces.d"},"Ifmdatalink.Linerecorder.Backend.PlugIn.AgentParameter":{"hasNamespace":true,"type":1,"moduleName":"interfaces.d","relativePath":"test\\testproject\\interfaces.d"},"Ifmdatalink.Linerecorder.Backend.PlugIn.AgentMetaInfo":{"hasNamespace":true,"type":1,"moduleName":"interfaces.d","relativePath":"test\\testproject\\interfaces.d"},"node-rest-client.Client":{"hasNamespace":true,"type":0,"moduleName":"node-rest-client.d","relativePath":"typings\\node-rest-client\\node-rest-client.d"},"amsgateway.Gateway":{"hasNamespace":true,"type":0,"moduleName":"proxy","relativePath":"test\\testproject\\proxy\\proxy"},"amsgateway.AgentDtoEntitySet":{"hasNamespace":true,"type":0,"moduleName":"proxy","relativePath":"test\\testproject\\proxy\\proxy"},"Assert":{"hasNamespace":false,"type":1,"moduleName":"index.d","relativePath":"test\\testproject\\typings\\globals\\qunit\\index.d"},"Config":{"hasNamespace":false,"type":1,"moduleName":"index.d","relativePath":"test\\testproject\\typings\\globals\\qunit\\index.d"},"Hooks":{"hasNamespace":false,"type":1,"moduleName":"index.d","relativePath":"test\\testproject\\typings\\globals\\qunit\\index.d"},"NestedHooks":{"hasNamespace":false,"type":1,"moduleName":"index.d","relativePath":"test\\testproject\\typings\\globals\\qunit\\index.d"},"QUnit":{"hasNamespace":false,"type":1,"moduleName":"index.d","relativePath":"test\\testproject\\typings\\globals\\qunit\\index.d"}},"files":{"dist\\odataproxybase.ts":"2017-02-12T21:57:17.316Z","src\\odataCrawler.ts":"2017-01-24T21:33:55.000Z","src\\extension.ts":"2016-12-18T19:28:23.458Z","src\\proxyGenerator.ts":"2017-02-13T11:16:13.000Z","typings\\edm.d.ts":"2017-02-12T21:30:43.733Z","typings\\index.d.ts":"2017-01-16T20:39:34.969Z","test\\testproject\\interfaces.d.ts":"2017-02-13T11:12:44.067Z","test\\testproject\\index.ts":"2016-12-18T23:15:55.855Z","typings\\node-rest-client\\node-rest-client.d.ts":"2016-12-16T20:45:18.596Z","test\\testproject\\proxy\\odataproxybase.ts":"2017-02-13T11:16:41.420Z","test\\testproject\\proxy\\proxy.ts":"2017-02-13T11:15:13.362Z","test\\testproject\\test\\odataservicetests.ts":"2017-02-12T17:12:11.000Z","typings\\globals\\qunit\\index.d.ts":"2017-01-16T20:39:34.962Z","test\\testproject\\typings\\index.d.ts":"2017-01-16T21:10:51.310Z","test\\testproject\\typings\\globals\\qunit\\index.d.ts":"2017-01-16T21:10:51.302Z"}} -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // Available variables which can be used inside of strings. 2 | // ${workspaceRoot}: the root folder of the team 3 | // ${file}: the current opened file 4 | // ${fileBasename}: the current opened file's basename 5 | // ${fileDirname}: the current opened file's dirname 6 | // ${fileExtname}: the current opened file's extension 7 | // ${cwd}: the current working directory of the spawned process 8 | 9 | // A task runner that calls a custom npm script that compiles the extension. 10 | { 11 | "version": "0.1.0", 12 | 13 | // we want to run npm 14 | "command": "npm", 15 | 16 | // the command is a shell script 17 | "isShellCommand": true, 18 | 19 | // show the output window only if unrecognized errors occur. 20 | "showOutput": "silent", 21 | 22 | // we run the custom script "compile" as defined in package.json 23 | "args": ["run", "compile", "--loglevel", "silent"], 24 | 25 | // The tsc compiler is started in watching mode 26 | "isWatching": true, 27 | 28 | // use the standard tsc in watch mode problem matcher to find compile problems in the output. 29 | "problemMatcher": "$tsc-watch" 30 | } -------------------------------------------------------------------------------- /.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | out/test/** 4 | test/** 5 | src/** 6 | **/*.map 7 | .gitignore 8 | tsconfig.json 9 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Release Notes 2 | 3 | All notable changes to the "odatatools" will be documented in this file. 4 | 5 | Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. 6 | 7 | ## [2.0.1] 2017-01-18 8 | 9 | ### Fixed 10 | 11 | * Wrong Template was distributed 12 | * Array types were not generated correctly in template 13 | 14 | ## [2.0.0] 2017-12-15 15 | 16 | ### Added 17 | 18 | * Version 2.0: Recently Used menu 19 | * ISimpleType for simple types 20 | 21 | ### Changed 22 | 23 | * Version 2.0 is now standard 24 | 25 | ### Deprecated 26 | 27 | * Version 1.0 will not be supported anymore 28 | 29 | ### Fixed 30 | 31 | * Nullable of Properties was not boolean, but string 32 | * Template error: key did not set name in Child of Proxybase on entityset 33 | * Expand in default typescript template does now allow any string 34 | * Type collection of simple type could not be converted. Added ISimpleType interface to do so 35 | * Typescript template handled if response did return undefined 36 | * Fixed problems with void type (data was undefined) 37 | 38 | ## [1.1.0] 2017-12-05 39 | 40 | ### Added 41 | 42 | * Version 2.0 in Insider mode supporting customizable templates 43 | 44 | ## [1.0.4] 2017-06-06 45 | 46 | ### Fixed 47 | 48 | * Reject and resolve were mixed up in OData Actions and Functions 49 | * Get does not return the entity array 50 | 51 | ## [1.0.3] 2017-06-06 - Hotfix 3 52 | 53 | ### Fixed 54 | 55 | * Errors in package.json 56 | * Error outputs to terminal 57 | 58 | ## [1.0.2] 2017-06-06 - Hotfix 2 59 | 60 | ### Added 61 | 62 | * Missing module `'request'` 63 | 64 | ## [1.0.1] 2017-06-06 - Hotfix 1 65 | 66 | ### Changed 67 | 68 | * Changelog is now closer to keepachangelog style 69 | 70 | ### Fixed 71 | 72 | * Select method did return wrong class 73 | 74 | ## [1.0.0] 2017-06-05 - Typescript 2.1+ overhaul 75 | 76 | ### Added 77 | 78 | * Setting: Extension Version selection to be able geting old behavior (0.x) 79 | * Setting: Insider mode (Not used for anything so far) 80 | * Async and await ES3/5/6+ Proxy 81 | * Additional request options for interface generation (only version 1.0+) **Not tested** 82 | * Additional request options for proxy generation (only version 1.0+) **Not tested** 83 | * Options in proxy file header 84 | 85 | ### Changed 86 | 87 | * Changelog file is now structured as suggested by keep a changelog 88 | * Hook in interface file is now json format (only version 1.0+) 89 | * Hooks are now pasted at the start with generation notes (only version 1.0+) 90 | * Last address is now saved permanently (recently used list) 91 | * Request syntax in proxy (only version 1.0+) 92 | 93 | ### Deprecated 94 | 95 | * Version 0.4.0 and below custom classes (Thenable caller, etc.) 96 | * Support for version 0.4.0 and below 97 | 98 | ### Removed 99 | 100 | * Delta classes generation when generating interfaces (only Version 1.0+) 101 | 102 | ## [0.4.0] OData Actions and Functions 103 | 104 | ### Added 105 | 106 | * OData V4 client generator can now handle bound and unbound actions and Functions 107 | * OData V4 client allows custom headers in constructor (experimental - not tested) 108 | 109 | ### Changed 110 | 111 | * OData V4 Client generator takes now namespace and container name for generated proxy 112 | 113 | ## [0.3.0] OData Client 114 | 115 | ### Added 116 | 117 | * OData V4 client generator (experimental) 118 | 119 | ### Fixed 120 | 121 | * Enums are now string Enums 122 | * Errors when creating interfaces are now caught and printed out 123 | 124 | ### [0.3.1] Hotfix 125 | 126 | ### Fixed 127 | 128 | * OData Client switched name and address in constructor 129 | 130 | ## [0.2.0] Ambient and modular declarations 131 | 132 | ### Fixed 133 | 134 | * d.ts files will now cause `declare` statements before `namespace` 135 | 136 | ## [0.1.0] Interface Generator 137 | 138 | * Added Interface Generator -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Odata V4 Client Generator for VSCode 2 | 3 | This extension targets to speed up access to an oData service to use it within *typescript*. 4 | 5 | > **Important Note**: Version 1.0 will not be supported anymore. Please use Version 2.0. The generated typescript client is fully compatible to the old version + additional bound functions and actions. You can now modify the template and customize it to fit your needs. Just have a look at `${workspaceFolder}/.vscode/odatatools/templates/proxy.ot` and at the [ODataTools Wiki](https://github.com/apazureck/odatatools/wiki). 6 | 7 | Changes from Version 1.0.0 are incompatible with earlier releases (0.4.0 and below). Please migrate your applications! Please use legacy settings, if you cannot migrate. **Older versions will not be extended or supported anymore!** 8 | 9 | - Supported oData standards: **V4.0** 10 | - Supported Languages: **Typescript** 11 | - Create/Update *typescript* Interface declarations from oData service 12 | - Create/Update *typescript* OData V4 client 13 | - Entity sets GET, PUT, POST, DELETE 14 | - Bound and unbound OData Actions and Functions 15 | - Asynchronous calls using `async await` (ES6+ and ES5/ES3 Promise shim) 16 | - Linq-like syntax for creating requests 17 | - **[Version 2.0: Create your own proxy using handlebars templates](https://github.com/apazureck/odatatools/wiki/Custom-Templates)** 18 | 19 | ## Usage / Quickstart 20 | 21 | ### Simple Service 22 | 23 | 1. Create a file (for example `proxy.ts`) 24 | 1. Run command `Create proxy client from OData V4.0 Service` 25 | 1. Select `New Entry...` 26 | 1. Type in the address for your service $metadata (don't forget 'http://'!). For example: `http://services.odata.org/Experimental/OData/(S(oekaxtj3dth11xxesirucjwq))/OData.svc/$meatadata` 27 | 1. The data should now get pasted in your currently opened document. 28 | 29 | After that a folder `${workspaceFolder}/.vscode/odatatools/`, which contains a file in the folder `templates` called proxy.ot. You can modify this file to your liking using handlebars. See the [Wiki](https://github.com/apazureck/odatatools/wiki/Custom-Templates) for more detail. 30 | 31 | ### Update 32 | 33 | Just run the command `Update proxy client from OData V4.0 Service`. 34 | 35 | ### Custom headers / protected access 36 | 37 | 1. Run the create command to your Odata Url as described above. Your request will fail, but the header should be created in the file. 38 | 1. Edit the `requestOptions` in the generated header. See [Wiki](https://github.com/apazureck/odatatools/wiki#update-and-header-manipulation) for more information. 39 | 40 | ### Older versions 41 | 42 | Do not use Version 1.0 anymore. Version 2.0 will provide the same client + you can customize your client. 43 | 44 | For legacy usage (Version 0.4.0 and below) refer to the [ODataTools Wiki - Usage Version 0.4.0 and below](https://github.com/apazureck/odatatools/wiki/Usage-Version-0.4.0-and-below). 45 | 46 | For instructions how to use this extensions have a look at the [ODataTools Wiki](https://github.com/apazureck/odatatools/wiki). 47 | 48 | ## Known Issues 49 | 50 | - None 51 | 52 | The service is tested against the service in the repo. In future release I hope to create some kind of test framework to check custom templates again, [please report issues on the github page](https://github.com/apazureck/odatatools/issues) 53 | 54 | ## Contribution 55 | 56 | I created this extensions to fill my need using this with our oData services (ASP.NET oData V4.0). I tested it against the [northwind service](http://services.odata.org/V4/Northwind/Northwind.svc/) (mostly). I will extend this in the future, if I have any need to get things done. So please file an issue on github, I will have a look at it, how much work it will be to extend this. Or fork it and extend it on your own. Contribution is always welcome. 57 | 58 | - [**Report a bug**](https://github.com/apazureck/odatatools/issues) 59 | - [**Repository**](https://github.com/apazureck/odatatools/) -------------------------------------------------------------------------------- /dist/odatajs.d.ts: -------------------------------------------------------------------------------- 1 | export class oData { 2 | static request(request: Request, success?: (data: any, response: any) => void, error?: (error: any) => void, handler?, httpClient?, metadata?); 3 | } 4 | 5 | export interface Request { 6 | requestUri: string, 7 | method: string, 8 | headers: Header | Header[], 9 | data?: any 10 | } 11 | 12 | export interface Header { [name: string]: string } 13 | -------------------------------------------------------------------------------- /dist/odataproxybase.ts: -------------------------------------------------------------------------------- 1 | namespace odatatools { 2 | enum Method { 3 | GET, POST, PUT, PATCH, DELETE 4 | } 5 | 6 | export class ProxyBase { 7 | constructor(public readonly Address: string, public readonly Name?: string, additonalHeaders?: odatajs.Header) { 8 | this.Name = this.Name || "ProxyService"; 9 | 10 | this.Headers = { "Content-Type": "application/json", Accept: "application/json" }; 11 | 12 | for (var attrname in additonalHeaders) { this.Headers[attrname] = additonalHeaders[attrname]; }; 13 | } 14 | 15 | /** 16 | * All headers appended to each request. 17 | * 18 | * @type {odatajs.Header} 19 | * @memberOf EntitySet 20 | */ 21 | readonly Headers: odatajs.Header; 22 | } 23 | 24 | /** 25 | * 26 | * A generic entity set which represents the content of the entity container. 27 | * 28 | * @export 29 | * @class EntitySet 30 | * @template T 31 | */ 32 | export class EntitySet { 33 | 34 | /** 35 | * Creates an instance of EntitySet. 36 | * 37 | * @param {string} name of the EntitySet (Will determine the address of the entityset, too -> address + "/" + name) 38 | * @param {string} address of the service 39 | * @param {string} key of the EntitySet 40 | * @param {odatajs.Header} [headers] additional headers: Per default there are "Content-Type" and "Accept". 41 | * 42 | * @memberOf EntitySet 43 | */ 44 | constructor(name: string, address: string, key: string, additionalHeaders?: odatajs.Header) { 45 | this.Name = name; 46 | this.Address = address.replace(/\/$/, "") + "/" + name; 47 | this.Key = key; 48 | this.Headers = { "Content-Type": "application/json", Accept: "application/json" }; 49 | 50 | for (var attrname in additionalHeaders) { this.Headers[attrname] = additionalHeaders[attrname]; }; 51 | } 52 | 53 | /** 54 | * Name of the Entity Set (which is appended to the URI) 55 | * @memberOf EntitySet 56 | */ 57 | readonly Name: string; 58 | /** 59 | * Address of the OData Service 60 | * @memberOf EntitySet 61 | */ 62 | readonly Address: string; 63 | 64 | /** 65 | * All headers appended to each request. 66 | * 67 | * @type {odatajs.Header} 68 | * @memberOf EntitySet 69 | */ 70 | readonly Headers: odatajs.Header; 71 | 72 | /** 73 | * Key of the entity 74 | * @memberOf EntitySet 75 | */ 76 | readonly Key: string; 77 | 78 | /** 79 | * Gets the entities from the oData service. Expand gets the navigation properties. 80 | * 81 | * @param {string} [parameters] It is attached to the request as `http://your.uri.com/EntitySet?`. For complex expands use the odata syntax. For example: `Prop1($expand=SubProp1,SubProp2),Prop2(...)` or `$select=Prop1,Prop2,Prop3&$expand=Prop2` 82 | * @returns {Thenable} for async Operation. Use `await` keyword to get value or `.then` callback. 83 | * 84 | * @memberOf EntitySet 85 | */ 86 | Get(parametersOrId?: string): Thenable 87 | Get(id: string, parameters: string): Thenable; 88 | Get(idOrParams?: string, parameters?: string): Thenable { 89 | let requri: string; 90 | 91 | let paramsonly = idOrParams && idOrParams.match(/^\$/); 92 | if (!idOrParams) { 93 | requri = this.Address; 94 | } else if (paramsonly) { 95 | requri = this.Address + (idOrParams ? "?" + idOrParams : ""); 96 | } else if (parameters) { 97 | requri = this.Address + "(" + idOrParams + ")" + "?" + parameters; 98 | } else { 99 | requri = this.Address + "(" + idOrParams + ")" 100 | } 101 | let request: odatajs.Request = { 102 | headers: this.Headers, 103 | method: Method[Method.GET], 104 | requestUri: requri 105 | } 106 | // if id starts with $ it is additional odata parameters 107 | if (!paramsonly) { 108 | let callback = new ThenableCaller(); 109 | odatajs.oData.request(request, (data, response) => { 110 | if (callback.then) { 111 | callback.resolve(data); 112 | } 113 | }, (error) => { 114 | console.error(error.name + " " + error.message + " | " + (error.response | error.response.statusText) + ":\n" + (error.response | error.response.body)); 115 | if (callback.catch) { 116 | callback.reject(error); 117 | } 118 | }); 119 | return callback; 120 | } else { 121 | let callback = new ThenableCaller(); 122 | odatajs.oData.request(request, (data, response) => { 123 | if (callback.then) { 124 | callback.resolve(data); 125 | } 126 | }, (error) => { 127 | console.error(error.name + " " + error.message + " | " + (error.response | error.response.statusText) + ":\n" + (error.response | error.response.body)); 128 | if (callback.catch) { 129 | callback.reject(error); 130 | } 131 | }); 132 | return callback; 133 | } 134 | } 135 | 136 | 137 | /** 138 | * Replaces an existing value in the entity collection. 139 | * 140 | * @param {T} value to replace 141 | * @returns {Thenable} for async Operation. Use `await` keyword to get value or `.then` callback. 142 | * 143 | * @memberOf EntitySet 144 | */ 145 | Put(value: T): Thenable { 146 | let callback = new ThenableCaller(); 147 | 148 | let request: odatajs.Request = { 149 | headers: this.Headers, 150 | method: Method[Method.PUT], 151 | requestUri: this.Address + "(" + value[this.Key] + ")", 152 | data: value 153 | } 154 | odatajs.oData.request(request, (data, response) => { 155 | callback.resolve(); 156 | }, (error) => { 157 | console.error(error.name + " " + error.message + " | " + (error.response | error.response.statusText) + ":\n" + (error.response | error.response.body)); 158 | callback.reject(error); 159 | }); 160 | return callback; 161 | } 162 | 163 | /** 164 | * Adds a new entry to an EntitySet 165 | * 166 | * @param {T} value to ad to the EntitySet 167 | * @returns {Thenable} for async Operation. Use `await` keyword to get value or `.then` callback. 168 | * 169 | * @memberOf EntitySet 170 | */ 171 | Post(value: T): Thenable { 172 | let callback = new ThenableCaller(); 173 | let request: odatajs.Request = { 174 | headers: this.Headers, 175 | method: Method[Method.POST], 176 | requestUri: this.Address, 177 | data: value 178 | } 179 | odatajs.oData.request(request, (data, response) => { 180 | callback.resolve(data as T); 181 | }, (error) => { 182 | console.error(error.name + " " + error.message + " | " + (error.response | error.response.statusText) + ":\n" + (error.response | error.response.body)); 183 | callback.reject(error); 184 | }); 185 | return callback; 186 | } 187 | Patch(delta: deltaT): Thenable 188 | Patch(oldvalue: T, newValue: T): Thenable 189 | Patch(oldvalordelta: T | deltaT, newval?: T): Thenable { 190 | if (newval) 191 | oldvalordelta = this.getDelta(oldvalordelta as T, newval); 192 | 193 | let callback = new ThenableCaller(); 194 | let request: odatajs.Request = { 195 | headers: this.Headers, 196 | method: Method[Method.PATCH], 197 | requestUri: this.Address, 198 | data: oldvalordelta 199 | } 200 | odatajs.oData.request(request, (data, response) => { 201 | callback.resolve(); 202 | }, (error) => { 203 | console.error(error.name + " " + error.message + " | " + (error.response | error.response.statusText) + ":\n" + (error.response | error.response.body)); 204 | callback.reject(error); 205 | }); 206 | return callback; 207 | } 208 | 209 | private getDelta(oldval: T, newVal: T): deltaT { 210 | let ret: any = {}; 211 | for (let prop in newVal) 212 | if (oldval[prop] != newVal[prop]) 213 | ret[prop] = newVal[prop]; 214 | return ret; 215 | } 216 | /** 217 | * Deletes a value from the entity set. 218 | * 219 | * @param {T} value to delete 220 | * @returns {Promise} for async Operation. Use `await` keyword to get value or `.then` callback. 221 | * 222 | * @memberOf EntitySet 223 | */ 224 | Delete(value: T): Thenable { 225 | let callback = new ThenableCaller(); 226 | let request: odatajs.Request = { 227 | headers: this.Headers, 228 | method: Method[Method.DELETE], 229 | requestUri: this.Address + "(" + value[this.Key] + ")" 230 | } 231 | odatajs.oData.request(request, (data, response) => { 232 | callback.resolve(); 233 | }, (error) => { 234 | console.error(error.name + " " + error.message + " | " + (error.response | error.response.statusText) + ":\n" + (error.response | error.response.body)); 235 | callback.reject(error); 236 | }); 237 | return callback; 238 | } 239 | 240 | Count(parameters?: string): Thenable { 241 | const callback = new ThenableCaller(); 242 | 243 | const requri = this.Address + "/$count/" + (parameters ? "?" + parameters : ""); 244 | 245 | let request: odatajs.Request = { 246 | headers: this.Headers, 247 | method: Method[Method.GET], 248 | requestUri: requri 249 | } 250 | 251 | odatajs.oData.request(request, (data, response) => { 252 | callback.resolve(data); 253 | }, (error) => { 254 | console.error(error.name + " " + error.message + " | " + (error.response | error.response.statusText) + ":\n" + (error.response | error.response.body)); 255 | callback.reject(error); 256 | }); 257 | 258 | return callback; 259 | } 260 | } 261 | 262 | class EntityContainer { 263 | constructor(name: string, uri: string) { 264 | this.Name = name; 265 | this.Uri = uri; 266 | } 267 | readonly Name: string; 268 | readonly Uri: string; 269 | } 270 | 271 | 272 | /** 273 | * Class that implements thenable callbacks is used to call the callbacks handed by the user. 274 | * 275 | * @class ThenableCaller 276 | * @implements {Thenable} 277 | * @template T 278 | */ 279 | export class ThenableCaller implements Thenable { 280 | private _then?: ((value: T) => void)[] = []; 281 | private _catch?: ((error: any) => void)[] = []; 282 | public then(then?: (value: T) => void): Thenable { 283 | this._then.push(then); 284 | return this; 285 | } 286 | public catch(reject: (error: any) => void): Thenable { 287 | this._catch.push(reject); 288 | return this; 289 | } 290 | public resolve(value?: T) { 291 | if (this._then) 292 | for (let t of this._then) 293 | t(value); 294 | } 295 | public reject(error: any) { 296 | if (this._catch) 297 | for (let c of this._catch) 298 | c(error); 299 | } 300 | } 301 | 302 | /** 303 | * An interface to add callbacks as in ES6 Promiselike 304 | * 305 | * @interface Thenable 306 | * @template T 307 | */ 308 | export interface Thenable { 309 | 310 | /** 311 | * Gets called if async function returns successfully 312 | * 313 | * @param {(value: T) => void} then 314 | * @returns {Thenable} for method stacking 315 | * 316 | * @memberOf Thenable 317 | */ 318 | then(then: (value?: T) => void): Thenable; 319 | 320 | /** 321 | * Gets called if async function returns an error 322 | * 323 | * @param {(error: any) => void} reject 324 | * @returns {Thenable} for method stacking 325 | * 326 | * @memberOf Thenable 327 | */ 328 | catch(reject: (error: any) => void): Thenable; 329 | } 330 | } 331 | 332 | declare namespace odatajs { 333 | class oData { 334 | static request(request: Request, success?: (data: any, response: any) => void, error?: (error: any) => void, handler?, httpClient?, metadata?); 335 | } 336 | 337 | interface Request { 338 | requestUri: string, 339 | method: string, 340 | headers: Header | Header[], 341 | data?: any 342 | } 343 | 344 | interface Header { [name: string]: string } 345 | } 346 | console.log("Loaded odataproxybase"); -------------------------------------------------------------------------------- /dist/templates/interfaces.ot: -------------------------------------------------------------------------------- 1 | {{Header}} 2 | 3 | declare namespace {{Namespace}} { 4 | {{#each EntityTypes}} 5 | export interface {{this.Name}} { 6 | {{#each this.Properties}} 7 | {{this.Name}}: {{this.Type}}; 8 | {{/each}} 9 | {{#each this.NavigationProperties}} 10 | {{this.Name}}{{#if Nullable}}?{{/if}}: {{this.Type}}; 11 | {{/each}} 12 | {{#if this.OpenType}}[x: string]: any;{{/if}} 13 | } 14 | {{/each}} 15 | {{#each ComplexTypes}} 16 | export interface {{this.Name}} { 17 | {{#each this.Properties}} 18 | {{this.Name}}: {{this.Type}}; 19 | {{/each}} 20 | {{#if this.OpenType}}[x: string]: any;{{/if}} 21 | } 22 | {{/each}} 23 | {{#each EnumTypes}} 24 | // Enum Values: {{#each this.Members}}{{this.Key}} = {{this.Value}}{{#unless @last}}, {{/unless}}{{/each}} 25 | export type {{this.Name}} = {{#each this.Members}}"{{this.Key}}"{{#unless @last}} | {{/unless}}{{/each}}; 26 | {{/each}} 27 | } 28 | 29 | type JSDate = Date; 30 | 31 | declare namespace Edm { 32 | export type Duration = string; 33 | export type Binary = string; 34 | export type Boolean = boolean; 35 | export type Byte = number; 36 | export type Date = JSDate; 37 | export type DateTimeOffset = JSDate; 38 | export type Decimal = number; 39 | export type Double = number; 40 | export type Guid = string; 41 | export type Int16 = number; 42 | export type Int32 = number; 43 | export type Int64 = number; 44 | export type SByte = number; 45 | export type Single = number; 46 | export type String = string; 47 | export type TimeOfDay = string; 48 | export type Stream = string; 49 | export type GeographyPoint = any; 50 | } -------------------------------------------------------------------------------- /dist/templates/promise/odatajs.d.ts: -------------------------------------------------------------------------------- 1 | export class oData { 2 | static request(request: Request, success?: (data: any, response: any) => void, error?: (error: any) => void, handler?, httpClient?, metadata?); 3 | } 4 | 5 | export interface Request { 6 | requestUri: string, 7 | method: string, 8 | headers: Header | Header[], 9 | data?: any 10 | } 11 | 12 | export interface Header { [name: string]: string } 13 | -------------------------------------------------------------------------------- /dist/templates/promise/templateinfo.json: -------------------------------------------------------------------------------- 1 | { 2 | "Author": "Andreas Pazureck", 3 | "Language": "Typescript", 4 | "Description": "A Promise based Template for an OData Service using ambient namespaces and odatajs", 5 | "Version": "1.0.1", 6 | "files": [ 7 | "proxy.ot", 8 | "odata.js" 9 | ] 10 | } -------------------------------------------------------------------------------- /images/demo1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apazureck/odatatools/e749f080fbe0146656f2cec5dc523b10a316b553/images/demo1.gif -------------------------------------------------------------------------------- /images/odata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apazureck/odatatools/e749f080fbe0146656f2cec5dc523b10a316b553/images/odata.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "odatatools", 3 | "displayName": "OData Client Generator", 4 | "description": "Tools for generating clients for OData Webservices", 5 | "version": "2.0.1", 6 | "publisher": "apazureck", 7 | "engines": { 8 | "vscode": "^1.5.0" 9 | }, 10 | "categories": [ 11 | "Other" 12 | ], 13 | "activationEvents": [ 14 | "onCommand:odatatools.GetInterfaces", 15 | "onCommand:odatatools.UpdateInterfaces", 16 | "onCommand:odatatools.GetProxy", 17 | "onCommand:odatatools.UpdateProxy" 18 | ], 19 | "main": "./out/src/extension", 20 | "contributes": { 21 | "commands": [ 22 | { 23 | "command": "odatatools.GetInterfaces", 24 | "category": "OData", 25 | "title": "Create Interfaces from OData V4.0 Service", 26 | "icon": "images/odata.png" 27 | }, 28 | { 29 | "command": "odatatools.UpdateInterfaces", 30 | "category": "OData", 31 | "title": "Update Interfaces from OData V4.0 Service", 32 | "icon": "images/odata.png" 33 | }, 34 | { 35 | "command": "odatatools.GetProxy", 36 | "category": "OData", 37 | "title": "Create proxy client from OData V4.0 Service", 38 | "icon": "images/odata.png" 39 | }, 40 | { 41 | "command": "odatatools.UpdateProxy", 42 | "category": "OData", 43 | "title": "Update proxy client from OData V4.0 Service", 44 | "icon": "images/odata.png" 45 | } 46 | ], 47 | "configuration": { 48 | "properties": { 49 | "odatatools.insiders": { 50 | "type": "boolean", 51 | "default": false, 52 | "description": "Sets the extension in insiders mode and makes [Insiders] features usable. See changelog for functions in insiders mode." 53 | }, 54 | "odatatools.version": { 55 | "type": "string", 56 | "default": "2.0", 57 | "description": "For legacy reasons. To use old behavior set to version '0.4'. See extension description for more details.", 58 | "enum": [ 59 | "2.0", 60 | "1.0", 61 | "0.4" 62 | ] 63 | }, 64 | "odatatools.recentlyUsedLength": { 65 | "type": "number", 66 | "default": 5, 67 | "minimum": 1, 68 | "maximum": 20, 69 | "description": "Length of recently used server addresses (This does not have any effect yet, hopefully in later vscode releases)" 70 | }, 71 | "odatatools.logLevel": { 72 | "type": "string", 73 | "default": "Info", 74 | "enum": [ 75 | "Trace", 76 | "Debug", 77 | "Info", 78 | "Warning", 79 | "Error", 80 | "Fatal" 81 | ], 82 | "description": "The loglevel to use in the output window" 83 | } 84 | } 85 | } 86 | }, 87 | "scripts": { 88 | "vscode:prepublish": "tsc -p ./", 89 | "compile": "tsc -watch -p ./", 90 | "postinstall": "node ./node_modules/vscode/bin/install" 91 | }, 92 | "devDependencies": { 93 | "@types/fs-extra": "4.0.5", 94 | "@types/handlebars": "4.0.36", 95 | "@types/mkdirp": "^0.5.2", 96 | "@types/mocha": "2.2.44", 97 | "@types/ncp": "2.0.1", 98 | "@types/node": "8.0.55", 99 | "@types/request": "^2.0.9", 100 | "assert": "1.4.1", 101 | "jasmine-core": "2.8.0", 102 | "mocha": "4.0.1", 103 | "qunitjs": "2.4.1", 104 | "typescript": "2.6.2" 105 | }, 106 | "dependencies": { 107 | "fs-extra": "4.0.3", 108 | "handlebars": "4.0.11", 109 | "linq-es2015": "2.4.29", 110 | "ncp": "2.0.0", 111 | "node-rest-client": "3.1.0", 112 | "request": "2.83.0", 113 | "vscode": "1.1.10", 114 | "xml2js": "0.4.19", 115 | "mkdirp": "0.5.1" 116 | }, 117 | "author": { 118 | "email": "andreas@pazureck.de", 119 | "name": "Andreas Pazureck" 120 | }, 121 | "keywords": [ 122 | "oData", 123 | "proxyclient" 124 | ], 125 | "preview": true, 126 | "galleryBanner": { 127 | "color": "white", 128 | "theme": "light" 129 | }, 130 | "license": "MIT", 131 | "bugs": "https://github.com/apazureck/odatatools/issues", 132 | "repository": "https://github.com/apazureck/odatatools", 133 | "icon": "images/odata.png" 134 | } -------------------------------------------------------------------------------- /recentlyused.json: -------------------------------------------------------------------------------- 1 | ["http://services.odata.org/Experimental/OData/(S(oekaxtj3dth11xxesirucjwq))/OData.svc/$metadata"] -------------------------------------------------------------------------------- /src/Settings.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from 'vscode'; 2 | import { LogLevel } from './log'; 3 | import { workspace } from 'vscode'; 4 | 5 | export type UsageVersion = "0.4" | "1.0" | "2.0"; 6 | export class Settings { 7 | private static get configuration(): vscode.WorkspaceConfiguration { 8 | return vscode.workspace.getConfiguration("odatatools"); 9 | } 10 | static get IsInInsiderMode(): boolean { 11 | return Settings.configuration.get("insiders", false); 12 | } 13 | 14 | static get UsageVersion(): UsageVersion { 15 | return Settings.configuration.get("version", "2.0"); 16 | } 17 | 18 | static get recentlyUsedLength(): number { 19 | return Settings.configuration.get("recentlyUsedLength", 5); 20 | } 21 | 22 | static get logLevel(): LogLevel { 23 | return LogLevel[Settings.configuration.get("logLevel", "Info")]; 24 | } 25 | } -------------------------------------------------------------------------------- /src/extension.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | // The module 'vscode' contains the VS Code extensibility API 3 | // Import the module and reference it with the alias vscode in your code below 4 | import * as vscode from 'vscode'; 5 | import * as v040Crawler from './v040/odataCrawler'; 6 | import * as v040ProxyGenerator from './v040/proxyGenerator'; 7 | import * as v100Crawler from './v100/odataCrawler'; 8 | import * as v100ProxyGenerator from './v100/proxyGenerator'; 9 | import * as v200ProxyGenerator from './v200/v200commands'; 10 | import { Settings } from './settings'; 11 | import * as fs from 'fs'; 12 | import * as path from 'path'; 13 | import * as mkd from 'mkdirp'; 14 | import { Log, LogLevel } from './log'; 15 | 16 | const logger = vscode.window.createOutputChannel("oData Tools"); 17 | logger.show(); 18 | 19 | Log.activate((message: string, logLevel: LogLevel) => { 20 | logger.appendLine(message); 21 | switch (logLevel) { 22 | case LogLevel.Trace: 23 | case LogLevel.Debug: 24 | console.log(message); 25 | break; 26 | case LogLevel.Info: 27 | console.info(message); 28 | break; 29 | case LogLevel.Warning: 30 | console.warn(message); 31 | break; 32 | case LogLevel.Error: 33 | case LogLevel.Fatal: 34 | console.error(message); 35 | break; 36 | default: 37 | break; 38 | } 39 | }); 40 | 41 | const log = new Log("extension"); 42 | 43 | if (!('toJSON' in Error.prototype)) 44 | Object.defineProperty(Error.prototype, 'toJSON', { 45 | value: function () { 46 | var alt = {}; 47 | 48 | Object.getOwnPropertyNames(this).forEach(function (key) { 49 | alt[key] = this[key]; 50 | }, this); 51 | 52 | return alt; 53 | }, 54 | configurable: true, 55 | writable: true 56 | }); 57 | 58 | 59 | export class Global { 60 | static lastval: string = null; 61 | static context: vscode.ExtensionContext = null; 62 | private static readonly recentlyUsedJsonPath = path.join(vscode.workspace.rootPath, ".vscode", "odatatools", "recentlyused.json"); 63 | /** 64 | * Gets recently used address from project folder ${workspaceRoot}/.vscode/odatatools/recentlyused.json 65 | * 66 | * @readonly 67 | * @static 68 | * @type {string[]} 69 | * @memberof Global 70 | */ 71 | static get recentlyUsedAddresses(): string[] { 72 | log.TraceEnterFunction(); 73 | if (fs.existsSync(this.recentlyUsedJsonPath)) 74 | return (JSON.parse(fs.readFileSync(this.recentlyUsedJsonPath, 'utf-8')) as string[]).reverse(); 75 | else 76 | return []; 77 | } 78 | 79 | static AddToRecentlyUsedAddresses(address: string) { 80 | log.TraceEnterFunction(); 81 | // Check if recently used json exists and create if not 82 | if(!fs.existsSync(this.recentlyUsedJsonPath)) { 83 | mkd.sync(path.dirname(this.recentlyUsedJsonPath)); 84 | fs.writeFileSync(this.recentlyUsedJsonPath, "[]"); 85 | } 86 | 87 | // Read recently used json file 88 | let recentlyused = JSON.parse(fs.readFileSync(this.recentlyUsedJsonPath, 'utf-8')) as string[]; 89 | 90 | // Check if already in list and push it to the top. 91 | const foundelement = recentlyused.indexOf(address); 92 | if (foundelement >= 0) { 93 | recentlyused.splice(foundelement, 1); 94 | recentlyused.push(address); 95 | // Else check if max number is exceeded 96 | } else if (recentlyused.length > Settings.recentlyUsedLength) { 97 | recentlyused.splice(0, 1); 98 | recentlyused.push(address); 99 | } else { 100 | recentlyused.push(address); 101 | } 102 | 103 | fs.writeFile(path.join(this.recentlyUsedJsonPath), JSON.stringify(recentlyused), (error) => { 104 | log.Error(() => ("An error occurred writing recently used file: " + JSON.stringify(error))); 105 | }); 106 | } 107 | } 108 | 109 | export var lastval: string = null; 110 | 111 | // this method is called when your extension is activated 112 | // your extension is activated the very first time the command is executed 113 | export function activate(context: vscode.ExtensionContext) { 114 | log.TraceEnterFunction(); 115 | Global.context = context; 116 | // Use the console to output diagnostic information (console.log) and errors (console.error) 117 | // This line of code will only be executed once when your extension is activated 118 | log.Info('Extension "odatatools" is now active!'); 119 | 120 | vscode.workspace.onDidChangeConfiguration(onDidChangeConfiguration); 121 | onDidChangeConfiguration(); 122 | } 123 | 124 | // this method is called when your extension is deactivated 125 | export function deactivate() { 126 | log.TraceEnterFunction(); 127 | } 128 | 129 | function onDidChangeConfiguration() { 130 | log.TraceEnterFunction(); 131 | log.Info("Using Extension Version: " + Settings.UsageVersion); 132 | log.Info("Insider mode active: " + (Settings.IsInInsiderMode ? "Yes" : "No")); 133 | switch (Settings.UsageVersion) { 134 | case "0.4": 135 | try { 136 | registerV40Commands(); 137 | } catch (error) { 138 | for (const cmd of Global.context.subscriptions) 139 | cmd.dispose(); 140 | Global.context.subscriptions = []; 141 | registerV40Commands(); 142 | } 143 | break; 144 | case "1.0": 145 | try { 146 | registerV100Commands(); 147 | } catch (error) { 148 | for (const cmd of Global.context.subscriptions) 149 | cmd.dispose(); 150 | Global.context.subscriptions = []; 151 | registerV100Commands(); 152 | } 153 | break; 154 | case "2.0": 155 | try { 156 | registerV200Commands(); 157 | } catch (error) { 158 | for (const cmd of Global.context.subscriptions) 159 | cmd.dispose(); 160 | Global.context.subscriptions = []; 161 | registerV200Commands(); 162 | } 163 | break; 164 | default: 165 | vscode.window.showErrorMessage("Could not determine version " + Settings.UsageVersion + ". Please use valid version entries"); 166 | break; 167 | } 168 | } 169 | 170 | function registerV40Commands(): void { 171 | log.TraceEnterFunction(); 172 | Global.context.subscriptions.push(vscode.commands.registerCommand('odatatools.GetInterfaces', v040Crawler.getInterfaces)); 173 | Global.context.subscriptions.push(vscode.commands.registerCommand('odatatools.UpdateInterfaces', v040Crawler.updateInterfaces)); 174 | Global.context.subscriptions.push(vscode.commands.registerCommand('odatatools.GetProxy', v040ProxyGenerator.createProxy)); 175 | Global.context.subscriptions.push(vscode.commands.registerCommand('odatatools.UpdateProxy', () => vscode.window.showErrorMessage("Update proxy is not available for V0.4 legacy support"))); 176 | } 177 | 178 | function registerV100Commands(): void { 179 | log.TraceEnterFunction(); 180 | Global.context.subscriptions.push(vscode.commands.registerCommand('odatatools.GetInterfaces', v100Crawler.getInterfaces)); 181 | Global.context.subscriptions.push(vscode.commands.registerCommand('odatatools.UpdateInterfaces', v100Crawler.updateInterfaces)); 182 | Global.context.subscriptions.push(vscode.commands.registerCommand('odatatools.GetProxy', v100ProxyGenerator.createProxy)); 183 | Global.context.subscriptions.push(vscode.commands.registerCommand('odatatools.UpdateProxy', v100ProxyGenerator.updateProxy)); 184 | } 185 | function registerV200Commands(): void { 186 | log.TraceEnterFunction(); 187 | Global.context.subscriptions.push(vscode.commands.registerCommand('odatatools.GetInterfaces', () => vscode.window.showErrorMessage("Get Interfaces is deprecated. Use Get Proxy instead."))); 188 | Global.context.subscriptions.push(vscode.commands.registerCommand('odatatools.UpdateInterfaces', () => vscode.window.showErrorMessage("Update Interfaces is deprecated. Use Update Proxy instead."))); 189 | Global.context.subscriptions.push(vscode.commands.registerCommand('odatatools.GetProxy', v200ProxyGenerator.createProxy)); 190 | Global.context.subscriptions.push(vscode.commands.registerCommand('odatatools.UpdateProxy', v200ProxyGenerator.updateProxy)); 191 | } -------------------------------------------------------------------------------- /src/helper.ts: -------------------------------------------------------------------------------- 1 | import { IEntityType, ISimpleType } from './v200/outtypes'; 2 | import { Log } from './log'; 3 | import * as xml2js from 'xml2js'; 4 | import * as request from 'request'; 5 | import { window, workspace } from "vscode"; 6 | import * as path from 'path'; 7 | import { Global } from './extension'; 8 | import * as fs from 'fs'; 9 | import * as fse from 'fs-extra'; 10 | import * as mkd from 'mkdirp'; 11 | 12 | export type Modularity = "Ambient" | "Modular"; 13 | 14 | const log = new Log("helpers"); 15 | 16 | export interface GeneratorSettings { 17 | source: string, 18 | modularity: Modularity, 19 | requestOptions: request.CoreOptions 20 | } 21 | 22 | 23 | export interface TemplateGeneratorSettings extends GeneratorSettings { 24 | useTemplate: string; 25 | } 26 | 27 | export class NoHeaderError extends Error { 28 | constructor(message?: string) { 29 | super(message); 30 | } 31 | } 32 | 33 | export function createHeader(options: GeneratorSettings): string { 34 | log.TraceEnterFunction(); 35 | // Create update information 36 | const headerobject = JSON.stringify(options, null, '\t'); 37 | let header = `/************************************************************************** 38 | Created by odatatools: https://marketplace.visualstudio.com/items?itemName=apazureck.odatatools\n`; 39 | header += "Use Command 'odata: xyUpdate to refresh data while this file is active in the editor.\n" 40 | header += "Creation Time: " + Date() + "\n"; 41 | header += "DO NOT DELETE THIS IN ORDER TO UPDATE YOUR SERVICE\n"; 42 | header += "#ODATATOOLSOPTIONS\n" 43 | header += headerobject + "\n"; 44 | header += "#ODATATOOLSOPTIONSEND\n"; 45 | return header + "**************************************************************************/\n\n" 46 | } 47 | 48 | export function getGeneratorSettingsFromDocumentText(input: string): TemplateGeneratorSettings { 49 | log.TraceEnterFunction(); 50 | const header = input.match(/#ODATATOOLSOPTIONS([\s\S]*)#ODATATOOLSOPTIONSEND/m); 51 | if (!header) 52 | throw new NoHeaderError("No valid odata tools header found."); 53 | return JSON.parse(header[1]); 54 | } 55 | 56 | export async function getMetadata(maddr: string, options?: request.CoreOptions): Promise { 57 | log.TraceEnterFunction(); 58 | return new Promise((resolve, reject) => { 59 | let rData = ''; 60 | request.get(maddr, options) 61 | .on('data', (data) => { 62 | rData += data; 63 | }) 64 | .on('complete', (resp) => { 65 | xml2js.parseString(rData, (err, data) => { 66 | try { 67 | if (!data["edmx:Edmx"]) { 68 | log.Error("Received invalid data:\n"); 69 | log.Error(data.toString()); 70 | return reject(window.showErrorMessage("Response is not valid oData metadata. See output for more information")); 71 | } 72 | if (data["edmx:Edmx"]) 73 | return resolve(data["edmx:Edmx"]); 74 | return reject("Not valid metadata") 75 | } 76 | catch (error) { 77 | reject(error); 78 | } 79 | }); 80 | }) 81 | .on('error', (resp) => { 82 | return 0; 83 | }); 84 | }); 85 | } 86 | 87 | export async function GetOutputStyleFromUser(): Promise { 88 | log.TraceEnterFunction(); 89 | return await window.showQuickPick(["Modular", "Ambient"], { 90 | placeHolder: "Select to generate the service as a modular or ambient version." 91 | }) as Modularity; 92 | } 93 | 94 | export function getModifiedTemplates(): { [x: string]: string } { 95 | log.TraceEnterFunction(); 96 | let files: string[]; 97 | const rootpath = workspace.rootPath; 98 | let ret: { [x: string]: string } = {}; 99 | try { 100 | files = fs.readdirSync(path.join(rootpath, ".vscode", "odatatools", "templates")); 101 | if (files.length == 0) 102 | throw new Error("No templates found"); 103 | } catch (error) { 104 | try { 105 | fs.mkdirSync(path.join(rootpath, ".vscode", "odatatools")); 106 | fs.mkdirSync(path.join(rootpath, ".vscode", "odatatools", "templates")); 107 | } catch (error) { 108 | 109 | } 110 | fse.copySync(path.join(Global.context.extensionPath, "dist", "templates", "promise"), path.join(rootpath, ".vscode", "odatatools", "templates"), { recursive: false }); 111 | files = fs.readdirSync(path.join(rootpath, ".vscode", "odatatools", "templates")); 112 | } 113 | for (const file of files) { 114 | // Get all OData Templates 115 | if (path.extname(file) === ".ot") 116 | ret[file] = fs.readFileSync(path.join(rootpath, ".vscode", "odatatools", "templates", file), 'utf-8'); 117 | } 118 | return ret; 119 | } 120 | 121 | export function getType(typestring: string): ISimpleType { 122 | log.TraceEnterFunction(); 123 | let m = typestring.match(/Collection\((.*)\)/); 124 | if (m) { 125 | return { 126 | IsCollection: true, 127 | Name: m[1], 128 | IsVoid: m[1] === "void", 129 | } 130 | } 131 | return { 132 | Name: typestring, 133 | IsCollection: false, 134 | IsVoid: typestring === "void", 135 | } 136 | } 137 | 138 | export async function getHostAddressFromUser(): Promise { 139 | log.TraceEnterFunction(); 140 | let pick: string = "New Entry..."; 141 | const rul = Global.recentlyUsedAddresses 142 | if (rul && rul.length > 0) 143 | pick = await window.showQuickPick(["New Entry..."].concat(Global.recentlyUsedAddresses), { 144 | placeHolder: "Select from recently used addresses or add new entry" 145 | }); 146 | if (pick === "New Entry...") 147 | pick = await window.showInputBox({ 148 | placeHolder: "http://my.odata.service/service.svc", 149 | value: Global.recentlyUsedAddresses.pop(), 150 | prompt: "Please enter uri of your oData service.", 151 | ignoreFocusOut: true, 152 | }); 153 | 154 | if (!pick) 155 | throw new Error("User did not input valid address"); 156 | 157 | pick = pick.replace("$metadata", ""); 158 | if (pick.endsWith("/")) 159 | pick = pick.substr(0, pick.length - 1); 160 | 161 | return pick + "/$metadata"; 162 | } 163 | 164 | export function getEntityTypeInterface(type: EntityType, schema: Schema): IEntityType { 165 | log.TraceEnterFunction(); 166 | const p: Partial = { 167 | // Key: type.Key ? type.Key[0].PropertyRef[0].$.Name : undefined, 168 | Name: type.$.Name, 169 | Fullname: schema.$.Namespace + "." + type.$.Name, 170 | Properties: [], 171 | NavigationProperties: [], 172 | BaseTypeFullName: type.$.BaseType || undefined, 173 | OpenType: type.$.OpenType || false, 174 | Actions: [], 175 | Functions: [], 176 | }; 177 | if (type.Property) 178 | for (let prop of type.Property) 179 | p.Properties.push({ 180 | Name: prop.$.Name, 181 | Type: getType(prop.$.Type), 182 | Nullable: prop.$.Nullable ? (prop.$.Nullable == "false" ? false : true) : true, 183 | }); 184 | if (type.Key) { 185 | p.Key = p.Properties[0]; 186 | } 187 | if (type.NavigationProperty) 188 | for (const prop of type.NavigationProperty) { 189 | let navprop = prop as Property; 190 | p.NavigationProperties.push({ 191 | Name: navprop.$.Name, 192 | Type: getType(navprop.$.Type), 193 | Nullable: true, 194 | }); 195 | } 196 | return p as IEntityType; 197 | } -------------------------------------------------------------------------------- /src/log.ts: -------------------------------------------------------------------------------- 1 | import * as vscode from "vscode"; 2 | import { Settings } from "./Settings"; 3 | 4 | export class Log { 5 | constructor( 6 | public readonly name?: string, 7 | private readonly logLevel?: LogLevel 8 | ) { 9 | this.name = name || "Log"; 10 | this.logLevel = logLevel || Settings.logLevel; 11 | } 12 | static activate( 13 | logFunction: (message: string, level: LogLevel) => void 14 | ): void { 15 | this.log = logFunction; 16 | } 17 | private static log: (message: string, level: LogLevel) => void; 18 | /** 19 | * Use this to automatically generate message entering function "foo" 20 | * 21 | * @memberof Log 22 | */ 23 | Trace(message: (() => any) | string): void { 24 | if (this.logLevel <= LogLevel.Trace) { 25 | // If no message is given get caller name 26 | 27 | this.LogMessage( 28 | "[TRACE] " + this.getLogName() + this.getMessageString(message), 29 | LogLevel.Trace 30 | ); 31 | } 32 | } 33 | 34 | TraceEnterFunction(functionName?: any): void { 35 | if (this.logLevel <= LogLevel.Trace) { 36 | // If no message is given get caller name 37 | if (!functionName) { 38 | try { 39 | let re = /Log\.Trace[\s\S]+?at (?:(?!Generator\.next|__awaiter|Promise|Function.get|(?:\w+[:\\.,?!<>])+)(\w+))/g; 40 | let aRegexResult = re.exec(new Error().stack); 41 | functionName = "Entering function '" + aRegexResult[1] + "'"; 42 | } catch (error) { 43 | functionName = 44 | "Could not determine Function Name at " + new Error().stack; 45 | } 46 | } 47 | 48 | this.LogMessage( 49 | "[TRACE] " + 50 | this.getLogName() + 51 | this.getMessageString(() => functionName), 52 | LogLevel.Trace 53 | ); 54 | } 55 | } 56 | 57 | Debug(message: (() => any) | string): void { 58 | if (this.logLevel <= LogLevel.Debug) { 59 | this.LogMessage( 60 | "[DEBUG] " + this.getLogName() + this.getMessageString(message), 61 | LogLevel.Debug 62 | ); 63 | } 64 | } 65 | 66 | Info(message: (() => any) | string): void { 67 | if (this.logLevel <= LogLevel.Info) { 68 | this.LogMessage( 69 | "[INFO ] " + this.getLogName() + this.getMessageString(message), 70 | LogLevel.Info 71 | ); 72 | } 73 | } 74 | 75 | Warn(message: (() => any) | string): void { 76 | if (this.logLevel <= LogLevel.Warning) { 77 | this.LogMessage( 78 | "[WARN ] " + this.getMessageString(message), 79 | LogLevel.Warning 80 | ); 81 | } 82 | } 83 | 84 | Error(message: (() => any) | string): void { 85 | if (this.logLevel <= LogLevel.Error) { 86 | this.LogMessage( 87 | "[ERROR] " + this.getMessageString(message), 88 | LogLevel.Error 89 | ); 90 | } 91 | } 92 | 93 | Fatal(message: (() => any) | string): void { 94 | if (this.logLevel <= LogLevel.Fatal) { 95 | this.LogMessage( 96 | "[FATAL] " + this.getMessageString(message), 97 | LogLevel.Fatal 98 | ); 99 | } 100 | } 101 | 102 | private getMessageString(message: (() => any) | string): string { 103 | let msg: any; 104 | if (typeof message === "string") msg = message; 105 | else msg = message(); 106 | return typeof msg === "string" ? msg : msg.toString(); 107 | } 108 | 109 | private getLogName(): string { 110 | return this.name + ": "; 111 | } 112 | 113 | LogMessage(message: string, logLevel: LogLevel): void { 114 | Log.log(message, logLevel); 115 | } 116 | } 117 | 118 | export enum LogLevel { 119 | Trace, 120 | Debug, 121 | Info, 122 | Warning, 123 | Error, 124 | Fatal, 125 | None 126 | } 127 | -------------------------------------------------------------------------------- /src/v040/odataCrawler.ts: -------------------------------------------------------------------------------- 1 | import { Client } from 'node-rest-client'; 2 | import { window, TextEdit, Range, commands } from 'vscode'; 3 | import { Global } from '../extension'; 4 | import { Log } from '../log'; 5 | 6 | const log = new Log("odataCrawlerV040"); 7 | 8 | export async function getInterfaces() { 9 | try { 10 | let input = await window.showInputBox({ 11 | placeHolder: "http://my.odata.service/service.svc", 12 | value: Global.lastval, 13 | prompt: "Please enter uri of your oData service.", 14 | ignoreFocusOut: true 15 | }); 16 | 17 | if (!input) 18 | return; 19 | 20 | input = input.replace("$metadata", ""); 21 | if (input.endsWith("/")) 22 | input = input.substr(0, input.length - 1); 23 | 24 | input = input + "/$metadata"; 25 | 26 | Global.lastval = input; 27 | 28 | let interfacesstring = await receiveInterfaces(input, window.activeTextEditor.document.uri.fsPath.endsWith("d.ts")); 29 | 30 | log.Info("Putting generated code to the current Editor window."); 31 | if (!window.activeTextEditor) 32 | return window.showErrorMessage("No active window selected."); 33 | 34 | window.activeTextEditor.edit((editBuilder) => { 35 | editBuilder.replace(window.activeTextEditor.selection, interfacesstring); 36 | }).then((value) => { 37 | commands.executeCommand("editor.action.formatDocument"); 38 | }); 39 | } catch (error) { 40 | window.showErrorMessage("Could not create interfaces. See output window for detail."); 41 | log.Error("Creating proxy returned following error:"); 42 | log.Error(() => JSON.stringify(error)); 43 | } 44 | } 45 | 46 | async function receiveInterfaces(input: string, ambient?: boolean): Promise { 47 | if (!ambient) ambient = false; 48 | return new Promise((resolve, reject) => { 49 | let client = new Client(); 50 | client.get(input, (data, response) => { 51 | try { 52 | if (!data["edmx:Edmx"]) { 53 | log.Error("Received invalid data:\n"); 54 | log.Error(data.toString()); 55 | return reject(window.showErrorMessage("Response is not valid oData metadata. See output for more information")); 56 | } 57 | let edmx: Edmx = data["edmx:Edmx"]; 58 | let version = edmx.$.Version; 59 | log.Info("oData version: " + version); 60 | if (version != "4.0") 61 | window.showWarningMessage("WARNING! Current oDate Service Version is '" + version + "'. Trying to get interfaces, but service only supports Version 4.0! Outcome might be unexpected."); 62 | 63 | log.Info("Creating Interfaces"); 64 | let interfacesstring = getInterfacesString(edmx["edmx:DataServices"][0].Schema, ambient); 65 | 66 | log.Info("Creating Edm Types"); 67 | interfacesstring += edmTypes(ambient); 68 | 69 | log.Info("Creating source line"); 70 | interfacesstring += "\n/// Do not modify this line to being able to update your interfaces again:" 71 | interfacesstring += "\n/// #odata.source = '" + input + "'"; 72 | resolve(interfacesstring) 73 | } catch (error) { 74 | log.Error("Unknown error:\n" + error.toString()) 75 | window.showErrorMessage("Unknown error occurred, see console output for more information."); 76 | reject(error); 77 | } 78 | }); 79 | }); 80 | } 81 | 82 | export async function updateInterfaces() { 83 | try { 84 | log.Info("Looking for #odata.source hook"); 85 | let m = window.activeTextEditor.document.getText().match("/// #odata.source = '(.*?)'"); 86 | if (!m) 87 | return window.showErrorMessage("Did not find odata source in document: '" + window.activeTextEditor.document.fileName + "'"); 88 | 89 | let interfacesstring = await receiveInterfaces(m[1], window.activeTextEditor.document.uri.fsPath.endsWith("d.ts")); 90 | 91 | log.Info("Updating current file."); 92 | window.activeTextEditor.edit((editbuilder) => { 93 | editbuilder.replace(new Range(0, 0, window.activeTextEditor.document.lineCount - 1, window.activeTextEditor.document.lineAt(window.activeTextEditor.document.lineCount - 1).text.length), interfacesstring) 94 | }).then((value) => { 95 | log.Info("Successfully pasted data. Formatting Document.") 96 | commands.executeCommand("editor.action.formatDocument").then(() => log.Info("Finished")); 97 | }); 98 | } catch (error) { 99 | window.showErrorMessage("Could not update interfaces. See output window for detail."); 100 | log.Error("Creating proxy returned following error:"); 101 | log.Error(() => JSON.stringify(error)); 102 | } 103 | } 104 | 105 | var typedefs = { 106 | Duration: "string", 107 | Binary: "string", 108 | Boolean: "boolean", 109 | Byte: "number", 110 | Date: "JSDate", 111 | DateTimeOffset: "JSDate", 112 | Decimal: "number", 113 | Double: "number", 114 | Guid: "string", 115 | Int16: "number", 116 | Int32: "number", 117 | Int64: "number", 118 | SByte: "number", 119 | Single: "number", 120 | String: "string", 121 | TimeOfDay: "string" 122 | } 123 | 124 | function edmTypes(ambient: boolean): string { 125 | let input = "\n"; 126 | input += "type JSDate = Date;\n\n" 127 | input += (ambient ? "declare " : "") + "namespace Edm {\n"; 128 | for (let key in typedefs) 129 | input += "export type " + key + " = " + typedefs[key] + ";\n"; 130 | input += "}"; 131 | return input; 132 | } 133 | 134 | function getInterfacesString(schemas: Schema[], ambient: boolean): string { 135 | let ret = ""; 136 | for (let schema of schemas) { 137 | ret += (ambient ? "declare " : "") + "namespace " + schema.$.Namespace + " {\n"; 138 | if (schema.EntityType) 139 | for (let type of schema.EntityType) { 140 | ret += "export interface " + type.$.Name + " {\n"; 141 | if (type.Property) 142 | for (let prop of type.Property) 143 | ret += getProperty(prop); 144 | if (type.NavigationProperty) 145 | for (let prop of type.NavigationProperty) 146 | ret += getProperty(prop); 147 | ret += "}\n"; 148 | 149 | ret += "export interface Delta" + type.$.Name + " {\n"; 150 | if (type.Property) 151 | for (let prop of type.Property) 152 | ret += getProperty(prop, true); 153 | if (type.NavigationProperty) 154 | for (let prop of type.NavigationProperty) 155 | ret += getProperty(prop, true); 156 | ret += "}\n"; 157 | } 158 | if (schema.ComplexType) 159 | for (let type of schema.ComplexType) { 160 | ret += "export interface " + type.$.Name + " {\n"; 161 | if (type.Property) 162 | for (let prop of type.Property) 163 | ret += getProperty(prop); 164 | ret += "}\n"; 165 | } 166 | if (schema.EnumType) 167 | for (let enumtype of schema.EnumType) { 168 | ret += "type " + enumtype.$.Name + " = "; 169 | let i = 0; 170 | if (enumtype.$.Name) 171 | for (let member of enumtype.Member) 172 | ret += "\"" + member.$.Name + "\"" + (++i < enumtype.Member.length ? " | " : "") 173 | ret += ";\n"; 174 | } 175 | ret += "}\n"; 176 | } 177 | return ret; 178 | } 179 | 180 | function getType(typestring: string): string { 181 | let m = typestring.match(/Collection\((.*)\)/); 182 | if (m) { 183 | checkEdmType(m[1]); 184 | return m[1] + "[]"; 185 | } 186 | checkEdmType(typestring); 187 | return typestring; 188 | } 189 | 190 | function checkEdmType(typestring: string) { 191 | if (!typestring) 192 | return; 193 | if (!typestring.startsWith("Edm.")) 194 | return; 195 | let typename = typestring.replace("Edm.", ""); 196 | if (!typedefs[typename]) 197 | typedefs[typename] = "any"; 198 | } 199 | 200 | function getProperty(inprop: Property | NavigationProperty, forceoptional?: boolean) { 201 | let prop = inprop as Property; 202 | return prop.$.Name + (typeof prop.$.Nullable !== 'undefined' ? (forceoptional ? "?" : (prop.$.Nullable ? "" : "?")) : "?") + ": " + getType(prop.$.Type) + ";\n" 203 | } -------------------------------------------------------------------------------- /src/v100/odataCrawler.ts: -------------------------------------------------------------------------------- 1 | import { createHeader, getGeneratorSettingsFromDocumentText, getMetadata, GeneratorSettings, GetOutputStyleFromUser } from '../helper'; 2 | import * as request from 'request'; 3 | import * as xml2js from 'xml2js'; 4 | import { window, TextEdit, Range, commands } from 'vscode'; 5 | import { Global } from '../extension'; 6 | import { Log } from '../log'; 7 | 8 | const log = new Log("odataCrawlerV100"); 9 | 10 | export async function getInterfaces() { 11 | log.TraceEnterFunction(); 12 | try { 13 | let input = await window.showInputBox({ 14 | placeHolder: "http://my.odata.service/service.svc", 15 | value: Global.recentlyUsedAddresses.pop(), 16 | prompt: "Please enter uri of your oData service.", 17 | ignoreFocusOut: true 18 | }); 19 | 20 | if (!input) 21 | return; 22 | 23 | input = input.replace("$metadata", ""); 24 | if (input.endsWith("/")) 25 | input = input.substr(0, input.length - 1); 26 | 27 | input = input + "/$metadata"; 28 | 29 | Global.lastval = input; 30 | 31 | let generatorSettings: GeneratorSettings = { 32 | source: input, 33 | modularity: await GetOutputStyleFromUser(), 34 | requestOptions: {} 35 | } 36 | 37 | let interfacesstring = await receiveInterfaces(generatorSettings); 38 | 39 | log.Info("Putting generated code to the current Editor window."); 40 | if (!window.activeTextEditor) 41 | return window.showErrorMessage("No active window selected."); 42 | 43 | window.activeTextEditor.edit((editBuilder) => { 44 | editBuilder.replace(window.activeTextEditor.selection, interfacesstring); 45 | }).then((value) => { 46 | commands.executeCommand("editor.action.formatDocument"); 47 | }); 48 | } catch (error) { 49 | window.showErrorMessage("Could not create interfaces. See output window for detail."); 50 | log.Error("Creating proxy returned following error:"); 51 | log.Error(() => JSON.stringify(error)); 52 | } 53 | } 54 | 55 | async function receiveInterfaces(options: GeneratorSettings): Promise { 56 | log.TraceEnterFunction(); 57 | try { 58 | const edmx = await getMetadata(options.source); 59 | log.Info("Creating Interfaces"); 60 | let interfacesstring = getInterfacesString(edmx["edmx:DataServices"][0].Schema, options); 61 | 62 | log.Info("Creating Edm Types"); 63 | interfacesstring += edmTypes(options.modularity === "Ambient"); 64 | 65 | log.Info("Creating source line"); 66 | interfacesstring += "\n/// Do not modify this line to being able to update your interfaces again:" 67 | return createHeader(options) + interfacesstring; 68 | } catch (error) { 69 | log.Error("Unknown error:\n" + error.toString()); 70 | window.showErrorMessage("Error occurred, see console output for more information."); 71 | return createHeader(options); 72 | } 73 | } 74 | 75 | export async function updateInterfaces() { 76 | log.TraceEnterFunction(); 77 | try { 78 | log.Info("Looking for header."); 79 | let generatorSettings = getGeneratorSettingsFromDocumentText(window.activeTextEditor.document.getText()); 80 | if (!generatorSettings) 81 | return window.showErrorMessage("Did not find odata source in document: '" + window.activeTextEditor.document.fileName + "'"); 82 | 83 | let interfacesstring = await receiveInterfaces(generatorSettings); 84 | 85 | log.Info("Updating current file."); 86 | window.activeTextEditor.edit((editbuilder) => { 87 | editbuilder.replace(new Range(0, 0, window.activeTextEditor.document.lineCount - 1, window.activeTextEditor.document.lineAt(window.activeTextEditor.document.lineCount - 1).text.length), interfacesstring) 88 | }).then((value) => { 89 | log.Info("Successfully pasted data. Formatting Document.") 90 | commands.executeCommand("editor.action.formatDocument").then(() => log.Info("Finished")); 91 | }); 92 | } catch (error) { 93 | window.showErrorMessage("Could not update interfaces. See output window for detail."); 94 | log.Error("Creating proxy returned following error:"); 95 | if (error.originalStack) 96 | log.Error(error.originalStack); 97 | else 98 | log.Error(error.toString()); 99 | } 100 | } 101 | 102 | var typedefs = { 103 | Duration: "string", 104 | Binary: "string", 105 | Boolean: "boolean", 106 | Byte: "number", 107 | Date: "JSDate", 108 | DateTimeOffset: "JSDate", 109 | Decimal: "number", 110 | Double: "number", 111 | Guid: "string", 112 | Int16: "number", 113 | Int32: "number", 114 | Int64: "number", 115 | SByte: "number", 116 | Single: "number", 117 | String: "string", 118 | TimeOfDay: "string" 119 | } 120 | 121 | function edmTypes(ambient: boolean): string { 122 | log.TraceEnterFunction(); 123 | let input = "\n"; 124 | input += "type JSDate = Date;\n\n" 125 | input += (ambient ? "declare " : "") + "namespace Edm {\n"; 126 | for (let key in typedefs) 127 | input += "export type " + key + " = " + typedefs[key] + ";\n"; 128 | input += "}"; 129 | return input; 130 | } 131 | 132 | function getInterfacesString(schemas: Schema[], generatorSettings: GeneratorSettings): string { 133 | log.TraceEnterFunction(); 134 | let ret = ""; 135 | for (let schema of schemas) { 136 | ret += (generatorSettings.modularity === "Ambient" ? "declare " : "") + "namespace " + schema.$.Namespace + " {\n"; 137 | if (schema.EntityType) 138 | for (let type of schema.EntityType) { 139 | ret += "export interface " + type.$.Name + " {\n"; 140 | if (type.Property) 141 | for (let prop of type.Property) 142 | ret += getProperty(prop); 143 | if (type.NavigationProperty) 144 | for (let prop of type.NavigationProperty) 145 | ret += getProperty(prop); 146 | ret += "}\n"; 147 | } 148 | if (schema.ComplexType) 149 | for (let type of schema.ComplexType) { 150 | ret += "export interface " + type.$.Name + " {\n"; 151 | if (type.Property) 152 | for (let prop of type.Property) 153 | ret += getProperty(prop); 154 | ret += "}\n"; 155 | } 156 | if (schema.EnumType) 157 | for (let enumtype of schema.EnumType) { 158 | ret += "type " + enumtype.$.Name + " = "; 159 | let i = 0; 160 | if (enumtype.$.Name) 161 | for (let member of enumtype.Member) 162 | ret += "\"" + member.$.Name + "\"" + (++i < enumtype.Member.length ? " | " : "") 163 | ret += ";\n"; 164 | } 165 | ret += "}\n"; 166 | } 167 | return ret; 168 | } 169 | 170 | function getType(typestring: string): string { 171 | log.TraceEnterFunction(); 172 | let m = typestring.match(/Collection\((.*)\)/); 173 | if (m) { 174 | checkEdmType(m[1]); 175 | return m[1] + "[]"; 176 | } 177 | checkEdmType(typestring); 178 | return typestring; 179 | } 180 | 181 | function checkEdmType(typestring: string) { 182 | log.TraceEnterFunction(); 183 | if (!typestring) 184 | return; 185 | if (!typestring.startsWith("Edm.")) 186 | return; 187 | let typename = typestring.replace("Edm.", ""); 188 | if (!typedefs[typename]) 189 | typedefs[typename] = "any"; 190 | } 191 | 192 | function getProperty(inprop: Property | NavigationProperty, forceoptional?: boolean) { 193 | log.TraceEnterFunction(); 194 | let prop = inprop as Property; 195 | return prop.$.Name + (typeof prop.$.Nullable !== 'undefined' ? (forceoptional ? "?" : (prop.$.Nullable ? "" : "?")) : "?") + ": " + getType(prop.$.Type) + ";\n" 196 | } -------------------------------------------------------------------------------- /src/v200/odataCrawler.ts: -------------------------------------------------------------------------------- 1 | import { 2 | createHeader, 3 | GeneratorSettings, 4 | getEntityTypeInterface, 5 | getGeneratorSettingsFromDocumentText, 6 | getMetadata, 7 | getModifiedTemplates, 8 | GetOutputStyleFromUser, 9 | getType, 10 | TemplateGeneratorSettings, 11 | } from '../helper'; 12 | import * as request from 'request'; 13 | import * as xml2js from 'xml2js'; 14 | import { window, TextEdit, Range, commands, workspace } from 'vscode'; 15 | import { Global } from '../extension'; 16 | import { Log } from '../log'; 17 | import * as fs from 'fs'; 18 | import * as path from 'path'; 19 | import { ncp } from 'ncp'; 20 | import * as hb from 'handlebars'; 21 | import { IODataEntities, IEntityType, IComplexType, IEnum } from './outtypes' 22 | 23 | export async function getInterfaces() { 24 | window.showErrorMessage("Deprecated in Version 2.0. Please use the Proxy functions to get metadata from your OData Service"); 25 | } 26 | 27 | export async function updateInterfaces() { 28 | window.showErrorMessage("Deprecated in Version 2.0. Please use the Proxy functions to get metadata from your OData Service"); 29 | } 30 | 31 | type Partial = {[P in keyof T]?: T[P]} 32 | 33 | export function getEdmTypes(schema: Schema, generatorSettings: GeneratorSettings): IODataEntities { 34 | let metadata: IODataEntities = { 35 | Header: "", 36 | EntityTypes: [], 37 | ComplexTypes: [], 38 | EnumTypes: [], 39 | }; 40 | 41 | if (schema.EntityType) { 42 | for (let type of schema.EntityType) { 43 | const p = getEntityTypeInterface(type, schema); 44 | metadata.EntityTypes.push(p as IEntityType); 45 | } 46 | } 47 | if (schema.ComplexType) { 48 | for (let type of schema.ComplexType) { 49 | const p: IComplexType = { 50 | Namespace: schema.$.Namespace, 51 | Fullname: schema.$.Namespace + "." + type.$.Name, 52 | Name: type.$.Name, 53 | Properties: [], 54 | BaseTypeFullName: type.$.BaseType || undefined, 55 | OpenType: type.$.OpenType || false, 56 | } 57 | if (type.Property) 58 | for (let prop of type.Property) 59 | p.Properties.push({ 60 | Name: prop.$.Name, 61 | Type: getType(prop.$.Type), 62 | Nullable: prop.$.Nullable ? (prop.$.Nullable == "true" ? true : false) : true, 63 | }); 64 | metadata.ComplexTypes.push(p); 65 | } 66 | } 67 | if (schema.EnumType) { 68 | for (let enumtype of schema.EnumType) { 69 | const p: IEnum = { 70 | Name: enumtype.$.Name, 71 | Members: [], 72 | } 73 | for (const member of enumtype.Member) { 74 | p.Members.push({ 75 | Key: member.$.Name, 76 | Value: member.$.Value, 77 | }) 78 | } 79 | metadata.EnumTypes.push(p); 80 | } 81 | } 82 | return metadata; 83 | } 84 | 85 | function getProperty(inprop: Property | NavigationProperty, forceoptional?: boolean) { 86 | let prop = inprop as Property; 87 | return prop.$.Name + (typeof prop.$.Nullable !== 'undefined' ? (forceoptional ? "?" : (prop.$.Nullable ? "" : "?")) : "?") + ": " + getType(prop.$.Type) + ";\n" 88 | } -------------------------------------------------------------------------------- /src/v200/outtypes.ts: -------------------------------------------------------------------------------- 1 | import { IODataSchema } from './outtypes'; 2 | export interface IInterfaces { 3 | ComplexTypes: ComplexType[]; 4 | EntityTypes: EntityType[]; 5 | EnumTypes: EnumType[]; 6 | } 7 | 8 | export interface IMethod { 9 | Name: string; 10 | IsBoundToCollection: boolean; 11 | IsBound: boolean; 12 | ReturnType: ISimpleType; 13 | } 14 | 15 | export interface IEntityType extends IComplexType { 16 | Key: IProperty; 17 | NavigationProperties: INavigationProperty[]; 18 | Actions: IMethod[]; 19 | Functions: IMethod[]; 20 | } 21 | 22 | export interface IComplexType { 23 | Name: string; 24 | Fullname: string; 25 | Namespace: string; 26 | Properties: IProperty[]; 27 | BaseType?: IComplexType; 28 | BaseTypeFullName: string; 29 | OpenType: boolean; 30 | } 31 | 32 | export interface IEnumType { 33 | Name: string; 34 | Value: number; 35 | } 36 | 37 | export interface IProperty { 38 | Name: string; 39 | Type: ISimpleType; 40 | Nullable: boolean; 41 | } 42 | 43 | export interface IEnum { 44 | Name: string; 45 | Members: { 46 | Key: string; 47 | Value: number; 48 | }[]; 49 | } 50 | 51 | export interface INavigationProperty extends IProperty { 52 | 53 | } 54 | 55 | export interface IODataSchema extends IODataEntities { 56 | Namespace: string; 57 | EntityContainer?: IEntityContainer; 58 | Functions: IFunction[]; 59 | Actions: IAction[]; 60 | } 61 | 62 | export interface IAction extends IMethod { } 63 | export interface IFunction extends IMethod { } 64 | 65 | export interface IMethod { 66 | Parameters: IParameter[]; 67 | ReturnType: ISimpleType; 68 | FullName: string; 69 | } 70 | 71 | export interface IParameter { 72 | Name: string; 73 | Type: ISimpleType; 74 | Nullable?: boolean; 75 | Unicode?: boolean; 76 | Precision?: number; 77 | MaxLength?: number; 78 | Scale?: number | "variable" | "floating"; 79 | SRID?: string; 80 | } 81 | 82 | export interface IODataEntities { 83 | Header: string; 84 | EntityTypes: IEntityType[]; 85 | ComplexTypes: IComplexType[]; 86 | EnumTypes: IEnum[]; 87 | } 88 | 89 | 90 | /// Proxy generator 91 | 92 | export interface IEntityContainer extends ISchemaChild { 93 | Name: string; 94 | EntitySets: IEntitySet[]; 95 | Singletons: ISingleton[]; 96 | FunctionImports: IFunctionImport[]; 97 | ActionImports: IActionImport[]; 98 | } 99 | 100 | export interface IEntitySet extends ISchemaChild { 101 | Name: string; 102 | EntityType: IEntityType; 103 | NavigationPropertyBindings: INavigationPropertyBinding[]; 104 | Actions: IMethod[]; 105 | Functions: IMethod[]; 106 | } 107 | 108 | export interface ISchemaChild { 109 | Namespace: string; 110 | FullName: string; 111 | } 112 | 113 | export interface IFunctionImport extends IMethodImport { 114 | Function: IFunction; 115 | IncludeInServiceDocument?: boolean; 116 | } 117 | 118 | export interface IActionImport extends IMethodImport { 119 | Action: IAction; 120 | } 121 | 122 | export interface IMethodImport { 123 | Name: string; 124 | EntitySet?: IEntitySet; 125 | } 126 | 127 | export interface ISingleton { 128 | Name: string; 129 | Type: string; 130 | NavigationPropertyBindings: INavigationPropertyBinding[]; 131 | } 132 | 133 | export interface INavigationPropertyBinding { 134 | Path: string; 135 | Target: string; 136 | } 137 | 138 | export interface ISimpleType { 139 | Name: string; 140 | IsCollection: boolean; 141 | IsVoid: boolean; 142 | } -------------------------------------------------------------------------------- /src/v200/templateProvider.ts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apazureck/odatatools/e749f080fbe0146656f2cec5dc523b10a316b553/src/v200/templateProvider.ts -------------------------------------------------------------------------------- /src/v200/v200commands.ts: -------------------------------------------------------------------------------- 1 | import { generateProxy } from './proxyGenerator'; 2 | import { Global } from '../extension'; 3 | import { Log } from '../log'; 4 | import { TemplateGeneratorSettings, getModifiedTemplates, getMetadata, createHeader, getGeneratorSettingsFromDocumentText, NoHeaderError, getHostAddressFromUser } from '../helper'; 5 | import { window, Range, commands } from 'vscode'; 6 | 7 | const log = new Log("v200commands"); 8 | 9 | export async function createProxy() { 10 | let generatorSettings: TemplateGeneratorSettings = { 11 | modularity: "Ambient", 12 | requestOptions: {}, 13 | source: "unknown", 14 | useTemplate: undefined 15 | }; 16 | try { 17 | // TODO: Change to quickpick to provide full file list 18 | let maddr = await getHostAddressFromUser(); 19 | 20 | if (!maddr) 21 | return; 22 | 23 | maddr = maddr.replace("$metadata", ""); 24 | if (maddr.endsWith("/")) 25 | maddr = maddr.substr(0, maddr.length - 1); 26 | 27 | maddr = maddr + "/$metadata"; 28 | 29 | Global.lastval = maddr; 30 | generatorSettings.source = maddr; 31 | 32 | const templates: { [key: string]: string } = getModifiedTemplates(); 33 | 34 | log.Info("Getting Metadata from '" + maddr + "'"); 35 | const metadata = await getMetadata(maddr); 36 | 37 | await generateProxy(metadata, generatorSettings, templates); 38 | 39 | Global.AddToRecentlyUsedAddresses(maddr); 40 | 41 | } catch (error) { 42 | window.showErrorMessage("Could not create proxy. See output window for detail."); 43 | log.Error("Creating proxy returned following error:"); 44 | if (error.originalStack) 45 | log.Error(error.originalStack); 46 | else 47 | log.Error(error.toString()); 48 | 49 | log.Info("Updating current file."); 50 | await window.activeTextEditor.edit((editbuilder) => { 51 | editbuilder.replace(new Range(0, 0, window.activeTextEditor.document.lineCount - 1, window.activeTextEditor.document.lineAt(window.activeTextEditor.document.lineCount - 1).text.length), createHeader(generatorSettings)); 52 | }); 53 | 54 | log.Info("Successfully pasted data. Formatting Document.") 55 | commands.executeCommand("editor.action.formatDocument").then(() => log.Info("Finished")); 56 | } 57 | } 58 | 59 | export async function updateProxy() { 60 | let header: TemplateGeneratorSettings; 61 | try { 62 | header = getGeneratorSettingsFromDocumentText(window.activeTextEditor.document.getText()); 63 | 64 | if (!header) 65 | return window.showErrorMessage("Could not find valid odatatools header to generate proxy from. Use 'Create Proxy' command instead."); 66 | 67 | if (!header.source) 68 | return window.showErrorMessage("No source property in odatatools header. Use 'Create Proxy' command instead."); 69 | 70 | log.Info("Getting Metadata from '" + header.source + "'"); 71 | const metadata = await getMetadata(header.source, header.requestOptions); 72 | 73 | generateProxy(metadata, header, getModifiedTemplates()); 74 | 75 | } catch (error) { 76 | window.showErrorMessage("Could not create proxy. See output window for detail."); 77 | log.Error("Creating proxy returned following error:"); 78 | if (error.originalStack) 79 | log.Error(error.originalStack); 80 | else 81 | log.Error(error.toString()); 82 | 83 | log.Info("Updating current file."); 84 | await window.activeTextEditor.edit((editbuilder) => { 85 | editbuilder.replace(new Range(0, 0, window.activeTextEditor.document.lineCount - 1, window.activeTextEditor.document.lineAt(window.activeTextEditor.document.lineCount - 1).text.length), createHeader(error instanceof NoHeaderError ? { 86 | source: "unknown", modularity: "Ambient", requestOptions: {} 87 | } : header)); 88 | }); 89 | 90 | log.Info("Created header"); 91 | commands.executeCommand("editor.action.formatDocument").then(() => log.Info("Finished")); 92 | } 93 | } -------------------------------------------------------------------------------- /templateProvider/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "availableTemplates": [ 3 | { 4 | "name": "promise", 5 | "language": "ts/Typescript", 6 | "author": "Andreas Pazureck", 7 | "email": "andreas@pazureck.de", 8 | "source": "ts-promise", 9 | "description": "A simple Typescript/ES6 Promise temlate using a fluent-like syntax to retreive data from a OData V4 service" 10 | } 11 | ] 12 | } -------------------------------------------------------------------------------- /templateProvider/ts-promise/README.md: -------------------------------------------------------------------------------- 1 | # Typescript - ODataJS Template 2 | 3 | This template is a simple implementation using Typescript, ES6 Promises and a fluent-like syntax to retreive data from a OData V4 Service. -------------------------------------------------------------------------------- /templateProvider/ts-promise/odatajs.d.ts: -------------------------------------------------------------------------------- 1 | export class oData { 2 | static request(request: Request, success?: (data: any, response: any) => void, error?: (error: any) => void, handler?, httpClient?, metadata?); 3 | } 4 | 5 | export interface Request { 6 | requestUri: string, 7 | method: string, 8 | headers: Header | Header[], 9 | data?: any 10 | } 11 | 12 | export interface Header { [name: string]: string } 13 | -------------------------------------------------------------------------------- /test/ODataTestService/ODataExtensions/ExpandSourceAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace System.ComponentModel.DataAnnotations.Schema 4 | { 5 | public class ExpandSourceAttribute : Attribute 6 | { 7 | /// 8 | /// Expand source attribute calls an external source (OData) to get the data when expanding. 9 | /// 10 | /// Entryset of the source. Start with http:// to address external source from another service. 11 | /// If the entityset is a collection, this property tells which property is the key to the current model to determine the entries of this collection on the other entity set. 12 | public ExpandSourceAttribute(string sourceentityset, string foreignkey = null) 13 | { 14 | if (!sourceentityset.StartsWith("http://")) 15 | IsLocal = true; 16 | else 17 | IsLocal = false; 18 | SourceEntitySet = sourceentityset; 19 | ForeignKey = foreignkey; 20 | } 21 | public string SourceEntitySet { get; set; } 22 | public bool IsLocal { get; private set; } 23 | 24 | public string ForeignKey { get; set; } 25 | } 26 | } -------------------------------------------------------------------------------- /test/ODataTestService/ODataExtensions/ExtendedODataConventionModelBuilder.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.OData.Edm; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Web.Http; 8 | using System.Web.OData; 9 | using System.Web.OData.Batch; 10 | using System.Web.OData.Builder; 11 | using System.Web.OData.Extensions; 12 | 13 | namespace System.Web.Odata.Builder 14 | { 15 | public class ExtendedODataConventionModelBuilder : ODataConventionModelBuilder 16 | { 17 | /// 18 | /// A dictionary hierarchy. First Dictionary is a Type - string dictionary. It will take the model type and go through all found bindings there. 19 | /// 20 | public static Dictionary> CustomNavigationReferences { get; } = new Dictionary>(); 21 | public override IEdmModel GetEdmModel() 22 | { 23 | var basemodel = base.GetEdmModel(); 24 | foreach (EntitySetConfiguration set in EntitySets) 25 | { 26 | Dictionary navdictionary; 27 | // If the referenced Model Type is not listed in the targetdictionary add it, otherwise set the targetdictionary 28 | //TODO [ap] Perhaps better to change it to entity set, as types may be used in multiple locations? 29 | if (!CustomNavigationReferences.TryGetValue(set.ClrType, out navdictionary)) 30 | { 31 | navdictionary = new Dictionary(); 32 | CustomNavigationReferences.Add(set.ClrType, navdictionary); 33 | } 34 | 35 | Dictionary foreignKeys = new Dictionary(); 36 | foreach(PropertyInfo pi in set.ClrType.GetProperties(BindingFlags.Instance | BindingFlags.Public)) 37 | { 38 | ForeignKeyAttribute fk = pi.GetCustomAttribute(typeof(ForeignKeyAttribute), true) as ForeignKeyAttribute; 39 | if (fk != null) 40 | foreignKeys.Add(fk.Name, pi); 41 | } 42 | 43 | string key = null; 44 | try 45 | { 46 | key = set.ClrType.GetProperties().FirstOrDefault(x => { return x.GetCustomAttribute(typeof(KeyAttribute), true) != null; }).Name; 47 | } 48 | catch (Exception) 49 | { 50 | } 51 | // Get all expand source attributes 52 | foreach (PropertyInfo pi in set.ClrType.GetProperties(BindingFlags.Instance | BindingFlags.Public)) 53 | { 54 | 55 | foreach (ExpandSourceAttribute a in pi.GetCustomAttributes(true)) 56 | { 57 | var exs = new ExternalSource { EntitySet = a.SourceEntitySet, IsLocal = a.IsLocal, NavigationProperty = pi, Key = key, ForeignKey = a.ForeignKey }; 58 | PropertyInfo fk; 59 | if (foreignKeys.TryGetValue(pi.Name, out fk)) 60 | { 61 | exs.ForeignKeyProperty = fk; 62 | try 63 | { 64 | exs.ForeignKey = pi.PropertyType.GetProperties().FirstOrDefault(x => x.GetCustomAttribute(typeof(KeyAttribute), true) != null).Name; 65 | } 66 | catch (Exception ex) 67 | { 68 | throw new ArgumentException(pi.PropertyType.Name + " has no KeyAttribute defined and, thus, cannot be used as ExpandSource.", pi.PropertyType.Name, ex); 69 | } 70 | } 71 | navdictionary.Add(pi.Name, exs); 72 | } 73 | } 74 | } 75 | return basemodel; 76 | } 77 | 78 | public static string RoutePrefix { get; private set; } 79 | 80 | public void CreateODataRoute(string routeName, string routePrefix, HttpConfiguration config, DefaultODataBatchHandler batchhandler = null) 81 | { 82 | RoutePrefix = routePrefix; 83 | config.MapODataServiceRoute( 84 | routeName: routeName, 85 | routePrefix: routePrefix, 86 | model: this.GetEdmModel(), 87 | batchHandler: batchhandler); 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /test/ODataTestService/ODataExtensions/ExternalSource.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | namespace System.Web.OData 4 | { 5 | public class ExternalSource 6 | { 7 | /// 8 | /// The name of the entity set 9 | /// 10 | public string EntitySet { get; set; } 11 | 12 | /// 13 | /// The source of the entity set. If null the current host will be used 14 | /// 15 | public bool IsLocal { get; set; } 16 | 17 | /// 18 | /// The property information of the foreign key to get the value 19 | /// 20 | public PropertyInfo ForeignKeyProperty { get; set; } 21 | 22 | /// 23 | /// The property information of the navigation property 24 | /// 25 | public PropertyInfo NavigationProperty { get; set; } 26 | 27 | public string ForeignKey { get; set; } 28 | 29 | public bool IsCollection { get { return ForeignKeyProperty == null; } } 30 | 31 | public string Key { get; set; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /test/ODataTestService/ODataExtensions/ODataExtensions.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {CAB5CA2C-45CE-45A1-8C8E-D1DCE7D9DE69} 8 | Library 9 | Properties 10 | ODataExtensions 11 | ODataExtensions 12 | v4.5.2 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | ..\packages\Microsoft.Data.Edm.5.8.1\lib\net40\Microsoft.Data.Edm.dll 35 | True 36 | 37 | 38 | ..\packages\Microsoft.Extensions.DependencyInjection.1.1.0\lib\netstandard1.1\Microsoft.Extensions.DependencyInjection.dll 39 | True 40 | 41 | 42 | ..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.1.1.0\lib\netstandard1.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll 43 | True 44 | 45 | 46 | ..\packages\Microsoft.OData.Core.7.0.0\lib\portable-net45+win8+wpa81\Microsoft.OData.Core.dll 47 | True 48 | 49 | 50 | ..\packages\Microsoft.OData.Edm.7.0.0\lib\portable-net45+win8+wpa81\Microsoft.OData.Edm.dll 51 | True 52 | 53 | 54 | ..\packages\Microsoft.Spatial.7.0.0\lib\portable-net45+win8+wpa81\Microsoft.Spatial.dll 55 | True 56 | 57 | 58 | ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll 59 | True 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | ..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll 68 | True 69 | 70 | 71 | 72 | ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll 73 | True 74 | 75 | 76 | ..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll 77 | True 78 | 79 | 80 | ..\packages\Microsoft.AspNet.OData.6.0.0\lib\net45\System.Web.OData.dll 81 | True 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 109 | -------------------------------------------------------------------------------- /test/ODataTestService/ODataExtensions/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ODataExtensions")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ODataExtensions")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("cab5ca2c-45ce-45a1-8c8e-d1dce7d9de69")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /test/ODataTestService/ODataExtensions/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /test/ODataTestService/ODataExtensions/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 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 | -------------------------------------------------------------------------------- /test/ODataTestService/ODataTestService.Tests/ODataTestService.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | {F28AC5C7-90F1-4594-9C87-BDA9209625D6} 7 | Library 8 | Properties 9 | ODataTestService.Tests 10 | ODataTestService.Tests 11 | v4.5.2 12 | 512 13 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | False 15 | UnitTest 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | {856F1AF4-4145-40F4-9C84-C4C0229BB9A2} 57 | ODataTestService 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 72 | -------------------------------------------------------------------------------- /test/ODataTestService/ODataTestService.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ODataTestService.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ODataTestService.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("f28ac5c7-90f1-4594-9c87-bda9209625d6")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /test/ODataTestService/ODataTestService.Tests/UnitTest1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using System.Linq; 4 | using System.Text.RegularExpressions; 5 | using System.Collections.Generic; 6 | 7 | namespace ODataTestService.Tests 8 | { 9 | [TestClass] 10 | public class UnitTest1 11 | { 12 | [TestMethod] 13 | public void TestExpandAlgorithm() 14 | { 15 | string[] teststrings = 16 | { 17 | "http://host/service/Categories?$skip=0&$take=5", 18 | "http://host/service/Categories?$expand = Products($filter = DiscontinuedDate eq null)&$skip=0&$xy=5", 19 | "http://host/service/Categories?$expand=Products/$ref,Versions($levels=3)", 20 | "http://host/service/Categories?$expand = Products / Sales.PremierProduct /$ref($filter = CurrentPromotion eq null&$skip=1&$take=5)", 21 | "http://host/service/Employees?$expand=Model.Manager/DirectReports($levels=3),Versions($levels=3)&$top=3", 22 | "http://host/service/Categories?$expand=*/$ref,Supplier", 23 | "http://host/service/Categories?$expand=*($levels=2)" 24 | }; 25 | 26 | foreach(string s in teststrings) 27 | { 28 | //var res = getexpand(s); 29 | 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /test/ODataTestService/ODataTestService.Tests/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /test/ODataTestService/ODataTestService.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}") = "ODataTestService", "ODataTestService\ODataTestService.csproj", "{856F1AF4-4145-40F4-9C84-C4C0229BB9A2}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ODataTestService.Tests", "ODataTestService.Tests\ODataTestService.Tests.csproj", "{F28AC5C7-90F1-4594-9C87-BDA9209625D6}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ODataExtensions", "ODataExtensions\ODataExtensions.csproj", "{CAB5CA2C-45CE-45A1-8C8E-D1DCE7D9DE69}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {856F1AF4-4145-40F4-9C84-C4C0229BB9A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {856F1AF4-4145-40F4-9C84-C4C0229BB9A2}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {856F1AF4-4145-40F4-9C84-C4C0229BB9A2}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {856F1AF4-4145-40F4-9C84-C4C0229BB9A2}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {F28AC5C7-90F1-4594-9C87-BDA9209625D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {F28AC5C7-90F1-4594-9C87-BDA9209625D6}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {F28AC5C7-90F1-4594-9C87-BDA9209625D6}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {F28AC5C7-90F1-4594-9C87-BDA9209625D6}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {CAB5CA2C-45CE-45A1-8C8E-D1DCE7D9DE69}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {CAB5CA2C-45CE-45A1-8C8E-D1DCE7D9DE69}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {CAB5CA2C-45CE-45A1-8C8E-D1DCE7D9DE69}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {CAB5CA2C-45CE-45A1-8C8E-D1DCE7D9DE69}.Release|Any CPU.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /test/ODataTestService/ODataTestService/App_Start/WebApiConfig.cs: -------------------------------------------------------------------------------- 1 | using ODataTestService.Models; 2 | using System; 3 | using System.Web.Http; 4 | using System.Web.Odata.Builder; 5 | using System.Web.OData.Extensions; 6 | 7 | namespace ODataTestService 8 | { 9 | public static class WebApiConfig 10 | { 11 | public static void Register(HttpConfiguration config) 12 | { 13 | // Web API configuration and services 14 | 15 | // Web API routes 16 | config.MapHttpAttributeRoutes(); 17 | 18 | config.Routes.MapHttpRoute( 19 | name: "DefaultApi", 20 | routeTemplate: "api/{controller}/{id}", 21 | defaults: new { id = RouteParameter.Optional } 22 | ); 23 | 24 | // enable query options for all properties 25 | config.Filter().Expand().Select().OrderBy().MaxTop(null).Count(); 26 | 27 | ExtendedODataConventionModelBuilder builder = new ExtendedODataConventionModelBuilder(); 28 | builder.Namespace = "MovieService"; 29 | builder.ContainerName = "MovieContainer"; 30 | Movie.Map(builder, builder.EntitySet("Movies")); 31 | Customer.Map(builder, builder.EntitySet("Customers")); 32 | Address.Map(builder, builder.EntitySet
("Addresses")); 33 | 34 | builder.Function("CurrentTime").Returns(); 35 | builder.Function("GetSomething").Returns().Parameter("value"); 36 | builder.Action("SetSomething").Returns().Parameter("value"); 37 | builder.CreateODataRoute("ODataRoute", "moviedb", config); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/ODataTestService/ODataTestService/ApplicationInsights.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 12 | search|spider|crawl|Bot|Monitor|AlwaysOn 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 54 | System.Web.Handlers.TransferRequestHandler 55 | Microsoft.VisualStudio.Web.PageInspector.Runtime.Tracing.RequestDataHttpHandler 56 | System.Web.StaticFileHandler 57 | System.Web.Handlers.AssemblyResourceLoader 58 | System.Web.Optimization.BundleHandler 59 | System.Web.Script.Services.ScriptHandlerFactory 60 | System.Web.Handlers.TraceHandler 61 | System.Web.Services.Discovery.DiscoveryRequestHandler 62 | System.Web.HttpDebugHandler 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 5 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /test/ODataTestService/ODataTestService/Controllers/AddressesController.cs: -------------------------------------------------------------------------------- 1 | using ODataTestService.Models; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Web; 6 | using System.Web.OData; 7 | 8 | namespace ODataTestService.Controllers 9 | { 10 | public class AddressesController : ODataBaseController 11 | { 12 | private List
datasource = new List
(); 13 | 14 | public AddressesController() 15 | { 16 | datasource.Add(new Address() 17 | { 18 | Id = 1, 19 | Street = "Fakestreet", 20 | Zip = "0000" 21 | }); 22 | datasource.Add(new Address() 23 | { 24 | Id = 2, 25 | Street = "Topstreet", 26 | Zip = "0001" 27 | }); 28 | } 29 | 30 | protected override IEnumerable
EntitySet 31 | { 32 | get 33 | { 34 | return datasource.AsQueryable(); 35 | } 36 | } 37 | 38 | protected override Address add(Address entity) 39 | { 40 | datasource.Add(entity); 41 | entity.Id = datasource.Count; 42 | return entity; 43 | } 44 | 45 | protected override int getKey(Address entity) 46 | { 47 | return entity.Id; 48 | } 49 | 50 | protected override void remove(Address entity) 51 | { 52 | datasource.Remove(entity); 53 | } 54 | 55 | protected override void replace(Address entity) 56 | { 57 | datasource[entity.Id - 1] = entity; 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /test/ODataTestService/ODataTestService/Controllers/CustomersController.cs: -------------------------------------------------------------------------------- 1 | using ODataTestService.Models; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web.OData; 5 | 6 | namespace ODataTestService.Controllers 7 | { 8 | public class CustomersController : ODataBaseController 9 | { 10 | public CustomersController() 11 | { 12 | datasource.Add(new Customer 13 | { 14 | AddressId = 1, 15 | Age = 10, 16 | Balance = 0.0, 17 | Gender = Gender.Other, 18 | Id = 1, 19 | Name = "Lance Uppercut" 20 | }); 21 | } 22 | private List datasource = new List(); 23 | protected override IEnumerable EntitySet 24 | { 25 | get 26 | { 27 | return datasource.AsQueryable(); 28 | } 29 | } 30 | 31 | protected override Customer add(Customer entity) 32 | { 33 | datasource.Add(entity); 34 | entity.Id = datasource.Count; 35 | return entity; 36 | } 37 | 38 | protected override int getKey(Customer entity) 39 | { 40 | return entity.Id; 41 | } 42 | 43 | protected override void remove(Customer entity) 44 | { 45 | datasource.Remove(entity); 46 | } 47 | 48 | protected override void replace(Customer entity) 49 | { 50 | datasource[entity.Id - 1] = entity; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /test/ODataTestService/ODataTestService/Controllers/MoviesController.cs: -------------------------------------------------------------------------------- 1 | using ODataTestService.Models; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Web.Http; 6 | using System.Web.OData; 7 | 8 | namespace ODataTestService.Controllers 9 | { 10 | public class MoviesController : ODataBaseController 11 | { 12 | public MoviesController() 13 | { 14 | datasource.Add(new Movie 15 | { 16 | Avaiable = true, 17 | Id = 1, 18 | LenderId = 1, 19 | Rating = 1 20 | }); 21 | datasource.Add(new Movie 22 | { 23 | Avaiable = false, 24 | Id = 2, 25 | LenderId = 1, 26 | Rating = 2 27 | }); 28 | } 29 | private List datasource = new List(); 30 | protected override IEnumerable EntitySet 31 | { 32 | get 33 | { 34 | return datasource; 35 | } 36 | } 37 | 38 | protected override Movie add(Movie entity) 39 | { 40 | datasource.Add(entity); 41 | entity.Id = datasource.Count; 42 | return entity; 43 | } 44 | 45 | protected override int getKey(Movie entity) 46 | { 47 | return entity.Id; 48 | } 49 | 50 | protected override void remove(Movie entity) 51 | { 52 | datasource.Remove(entity); 53 | } 54 | 55 | protected override void replace(Movie entity) 56 | { 57 | datasource[entity.Id - 1] = entity; 58 | } 59 | 60 | [HttpPost] 61 | public async Task ResetRating([FromODataUri] int key, ODataActionParameters parameters) 62 | { 63 | return await Task.Run(() => 64 | { 65 | return Ok(); 66 | }); 67 | } 68 | 69 | [HttpPost] 70 | public async Task Rate([FromODataUri] int key, ODataActionParameters parameters) 71 | { 72 | string ret = await Task.Run(() => 73 | { 74 | var entry = datasource[key]; 75 | entry.Rating = (float)parameters["rating"]; 76 | entry.Reason = (string)parameters["reason"]; 77 | datasource[key] = entry; 78 | return "Rated successfully"; 79 | }); 80 | return Ok(ret); 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /test/ODataTestService/ODataTestService/Controllers/UnboundController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Http; 6 | using System.Web.OData; 7 | using System.Web.OData.Routing; 8 | 9 | namespace ODataTestService.Controllers 10 | { 11 | public class UnboundController : ODataController 12 | { 13 | [HttpGet] 14 | [ODataRoute("CurrentTime")] 15 | public IHttpActionResult CurrentTime() 16 | { 17 | return Ok(DateTime.Now); 18 | } 19 | 20 | [HttpPost] 21 | [ODataRoute("SetSomething")] 22 | public IHttpActionResult SetSomething(ODataActionParameters parameters) 23 | { 24 | var l = new List(); 25 | l.Add((int)parameters["value"]); 26 | return Ok(SingleResult.Create(l.AsQueryable())); 27 | } 28 | 29 | [HttpGet] 30 | [ODataRoute("GetSomething(value={value})")] 31 | public IHttpActionResult GetSomething([FromODataUri]int value) 32 | { 33 | var l = new List(); 34 | l.Add(value); 35 | return Ok(SingleResult.Create(l.AsQueryable())); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /test/ODataTestService/ODataTestService/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="ODataTestService.WebApiApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /test/ODataTestService/ODataTestService/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Http; 6 | using System.Web.Routing; 7 | 8 | namespace ODataTestService 9 | { 10 | public class WebApiApplication : System.Web.HttpApplication 11 | { 12 | protected void Application_Start() 13 | { 14 | GlobalConfiguration.Configure(WebApiConfig.Register); 15 | } 16 | 17 | protected void Application_BeginRequest(object sender, EventArgs e) 18 | { 19 | Context.Response.AddHeader("Access-Control-Allow-Origin", "*"); 20 | if (Context.Request.HttpMethod == "OPTIONS") 21 | { 22 | Context.Response.AddHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-CSRF-Token, OData-Version, OData-MaxVersion"); 23 | Context.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, PATCH"); 24 | Context.Response.AddHeader("Access-Control-Allow-Credentials", "true"); 25 | Context.Response.End(); 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/ODataTestService/ODataTestService/Models/Address.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Runtime.Serialization; 6 | using System.Web.OData.Builder; 7 | 8 | namespace ODataTestService.Models 9 | { 10 | public class Address 11 | { 12 | [Key] 13 | public int Id { get; set; } 14 | public string Street { get; set; } 15 | public string Zip { get; set; } 16 | [ExpandSource("Customers", "AddressId")] 17 | public List Inhabitants { get; set; } 18 | 19 | internal static void Map(ODataModelBuilder builder, EntitySetConfiguration
entitySetConfiguration) 20 | { 21 | entitySetConfiguration.EntityType.HasMany(x => x.Inhabitants); 22 | } 23 | 24 | public void GetObjectData(SerializationInfo info, StreamingContext context) 25 | { 26 | throw new NotImplementedException(); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /test/ODataTestService/ODataTestService/Models/Customer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Web.OData.Builder; 6 | 7 | namespace ODataTestService.Models 8 | { 9 | public class Customer 10 | { 11 | [Key] 12 | public int Id { get; set; } 13 | public string Name { get; set; } 14 | public int Age { get; set; } 15 | public Gender Gender { get; set; } 16 | public double Balance { get; set; } 17 | [ExpandSource("Addresses")] 18 | public Address Address { get; set; } 19 | [ForeignKey(nameof(Address))] 20 | public int AddressId { get; set; } 21 | [ExpandSource("Movies", "LenderId")] 22 | public List Borrowed { get; set; } 23 | 24 | internal static void Map(ODataModelBuilder builder, EntitySetConfiguration entitySetConfiguration) 25 | { 26 | entitySetConfiguration.EntityType.HasRequired(x => x.Address); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /test/ODataTestService/ODataTestService/Models/Gender.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | 6 | namespace ODataTestService.Models 7 | { 8 | public enum Gender 9 | { 10 | Male, Female, Other 11 | } 12 | } -------------------------------------------------------------------------------- /test/ODataTestService/ODataTestService/Models/Movie.cs: -------------------------------------------------------------------------------- 1 | using ODataTestService.Controllers; 2 | using System; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.ComponentModel.DataAnnotations.Schema; 5 | using System.Web.OData.Builder; 6 | 7 | namespace ODataTestService.Models 8 | { 9 | public class Movie 10 | { 11 | [Key] 12 | public int Id { get; set; } 13 | [ForeignKey(nameof(Lender))] 14 | public int LenderId { get; set; } 15 | [ExpandSource("Customers")] 16 | public Customer Lender { get; set; } 17 | public bool Avaiable { get; set; } 18 | public float Rating { get; set; } 19 | 20 | public string Genre { get; set; } 21 | public string Reason { get; set; } 22 | 23 | internal static void Map(ODataModelBuilder builder, EntitySetConfiguration entitySetConfiguration) 24 | { 25 | entitySetConfiguration.EntityType.HasOptional(x => x.Lender); 26 | //entitySetConfiguration.EntityType.Action("Rate").Parameter("rating"); 27 | //entitySetConfiguration.EntityType.Action("ResetRating"); 28 | var a = builder.EntityType().Action("Rate"); 29 | a.Parameter("rating"); 30 | a.Parameter("reason"); 31 | a.Returns(); 32 | builder.EntityType().Action("ResetRating"); 33 | var f = builder.EntityType().Collection.Function("GetBestMovie"); 34 | f.Parameter("Genre"); 35 | f.Returns(); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /test/ODataTestService/ODataTestService/ODataTestService.csproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | true 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | URL 13 | True 14 | False 15 | False 16 | False 17 | 18 | 19 | http://localhost:2200/moviedb/$metadata 20 | 21 | 22 | 23 | 24 | True 25 | True 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /test/ODataTestService/ODataTestService/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ODataTestService")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ODataTestService")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("856f1af4-4145-40f4-9c84-c4c0229bb9a2")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /test/ODataTestService/ODataTestService/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /test/ODataTestService/ODataTestService/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /test/ODataTestService/ODataTestService/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 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 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /test/ODataTestService/ODataTestService/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 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 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /test/testproject/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "firefox", 6 | "request": "launch", 7 | "name": "Launch odataservicetests.html", 8 | "file": "${workspaceRoot}/test/odataservicetests.html" 9 | }, 10 | { 11 | "type": "chrome", 12 | "request": "launch", 13 | "name": "Launch Chrome", 14 | "file": "${workspaceRoot}/test/odataservicetests.html", 15 | "sourceMaps": true 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /test/testproject/.vscode/odatatools/recentlyused.json: -------------------------------------------------------------------------------- 1 | ["http://services.odata.org/Experimental/OData/(S(oekaxtj3dth11xxesirucjwq))/OData.svc/$metadata","http://services.odata.org/TripPinRESTierService/(S(tq0v4cxv3cph5pkpi1qziqzc))/$metadata"] -------------------------------------------------------------------------------- /test/testproject/.vscode/odatatools/templates/odatajs.d.ts: -------------------------------------------------------------------------------- 1 | export class oData { 2 | static request(request: Request, success?: (data: any, response: any) => void, error?: (error: any) => void, handler?, httpClient?, metadata?); 3 | } 4 | 5 | export interface Request { 6 | requestUri: string, 7 | method: string, 8 | headers: Header | Header[], 9 | data?: any 10 | } 11 | 12 | export interface Header { [name: string]: string } 13 | -------------------------------------------------------------------------------- /test/testproject/.vscode/odatatools/templates/templateinfo.json: -------------------------------------------------------------------------------- 1 | { 2 | "Author": "Andreas Pazureck", 3 | "Language": "Typescript", 4 | "Description": "A Promise based Template for an OData Service using ambient namespaces and odatajs", 5 | "Version": "1.0.0", 6 | "files": [ 7 | "proxy.ot", 8 | "odata.js" 9 | ] 10 | } -------------------------------------------------------------------------------- /test/testproject/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "./node_modules/typescript/lib", 3 | "files.exclude": { 4 | "**/.git": true, 5 | "**/.DS_Store": true, 6 | "**/*.js.map": true, 7 | "**/*.js": { "when": "$(basename).ts" } 8 | }, 9 | "vsicons.presets.angular": false, 10 | "odatatools.logLevel": "Trace", 11 | "handlebarsPreview.language": "typescript" 12 | } -------------------------------------------------------------------------------- /test/testproject/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // Available variables which can be used inside of strings. 2 | // ${workspaceRoot}: the root folder of the team 3 | // ${file}: the current opened file 4 | // ${fileBasename}: the current opened file's basename 5 | // ${fileDirname}: the current opened file's dirname 6 | // ${fileExtname}: the current opened file's extension 7 | // ${cwd}: the current working directory of the spawned process 8 | 9 | // A task runner that calls a custom npm script that compiles the extension. 10 | { 11 | "version": "0.1.0", 12 | 13 | // we want to run npm 14 | "command": "npm", 15 | 16 | // the command is a shell script 17 | "isShellCommand": true, 18 | 19 | // show the output window only if unrecognized errors occur. 20 | "showOutput": "silent", 21 | 22 | // we run the custom script "compile" as defined in package.json 23 | "args": ["run", "compile", "--loglevel", "silent"], 24 | 25 | // The tsc compiler is started in watching mode 26 | "isWatching": true, 27 | 28 | // use the standard tsc in watch mode problem matcher to find compile problems in the output. 29 | "problemMatcher": "$tsc-watch" 30 | } -------------------------------------------------------------------------------- /test/testproject/index.js: -------------------------------------------------------------------------------- 1 | // 2 | // PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING 3 | // 4 | // This file is providing the test runner to use when running extension tests. 5 | // By default the test runner in use is Mocha based. 6 | // 7 | // You can provide your own test runner if you want to override it by exporting 8 | // a function run(testRoot: string, clb: (error:Error) => void) that the extension 9 | // host can call to run the tests. The test runner is expected to use console.log 10 | // to report the results back to the caller. When the tests are finished, return 11 | // a possible error to the callback or null if none. 12 | var testRunner = require('vscode/lib/testrunner'); 13 | // You can directly control Mocha options by uncommenting the following lines 14 | // See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info 15 | testRunner.configure({ 16 | ui: 'tdd', 17 | useColors: true // colored output from test results 18 | }); 19 | module.exports = testRunner; 20 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /test/testproject/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,EAAE;AACF,mEAAmE;AACnE,EAAE;AACF,8EAA8E;AAC9E,oDAAoD;AACpD,EAAE;AACF,+EAA+E;AAC/E,kFAAkF;AAClF,iFAAiF;AACjF,gFAAgF;AAChF,oDAAoD;AAEpD,IAAI,UAAU,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;AAElD,6EAA6E;AAC7E,mGAAmG;AACnG,UAAU,CAAC,SAAS,CAAC;IACjB,EAAE,EAAE,KAAK;IACT,SAAS,EAAE,IAAI,CAAC,mCAAmC;CACtD,CAAC,CAAC;AAEH,MAAM,CAAC,OAAO,GAAG,UAAU,CAAC"} -------------------------------------------------------------------------------- /test/testproject/index.ts: -------------------------------------------------------------------------------- 1 | // 2 | // PLEASE DO NOT MODIFY / DELETE UNLESS YOU KNOW WHAT YOU ARE DOING 3 | // 4 | // This file is providing the test runner to use when running extension tests. 5 | // By default the test runner in use is Mocha based. 6 | // 7 | // You can provide your own test runner if you want to override it by exporting 8 | // a function run(testRoot: string, clb: (error:Error) => void) that the extension 9 | // host can call to run the tests. The test runner is expected to use console.log 10 | // to report the results back to the caller. When the tests are finished, return 11 | // a possible error to the callback or null if none. 12 | 13 | var testRunner = require('vscode/lib/testrunner'); 14 | 15 | // You can directly control Mocha options by uncommenting the following lines 16 | // See https://github.com/mochajs/mocha/wiki/Using-mocha-programmatically#set-options for more info 17 | testRunner.configure({ 18 | ui: 'tdd', // the TDD UI is being used in extension.test.ts (suite, test, etc.) 19 | useColors: true // colored output from test results 20 | }); 21 | 22 | module.exports = testRunner; -------------------------------------------------------------------------------- /test/testproject/interfaces.d.ts: -------------------------------------------------------------------------------- 1 | // /************************************************************************** 2 | // Created by odatatools: https://marketplace.visualstudio.com/items?itemName=apazureck.odatatools 3 | // Use Command 'odata: xyUpdate to refresh data while this file is active in the editor. 4 | // Creation Time: Mon Oct 16 2017 22:26:15 GMT+0200 (Mitteleuropäische Sommerzeit) 5 | // DO NOT DELETE THIS IN ORDER TO UPDATE YOUR SERVICE 6 | // #ODATATOOLSOPTIONS 7 | // { 8 | // "source": "http://services.odata.org/TripPinRESTierService/(S(tq0v4cxv3cph5pkpi1qziqzc))/$metadata", 9 | // "requestOptions": {}, 10 | // "useTemplate": "interfaces.ot" 11 | // } 12 | // #ODATATOOLSOPTIONSEND 13 | // **************************************************************************/ 14 | 15 | 16 | 17 | // declare namespace Microsoft.OData.Service.Sample.TrippinInMemory.Models { 18 | // export interface Person { 19 | // UserName: Edm.String; 20 | // FirstName: Edm.String; 21 | // LastName: Edm.String; 22 | // MiddleName: Edm.String; 23 | // Gender: Microsoft.OData.Service.Sample.TrippinInMemory.Models.PersonGender; 24 | // Age: Edm.Int64; 25 | // Emails: Edm.String[]; 26 | // AddressInfo: Microsoft.OData.Service.Sample.TrippinInMemory.Models.Location[]; 27 | // HomeAddress: Microsoft.OData.Service.Sample.TrippinInMemory.Models.Location; 28 | // FavoriteFeature: Microsoft.OData.Service.Sample.TrippinInMemory.Models.Feature; 29 | // Features: Microsoft.OData.Service.Sample.TrippinInMemory.Models.Feature[]; 30 | // Friends?: Microsoft.OData.Service.Sample.TrippinInMemory.Models.Person[]; 31 | // BestFriend?: Microsoft.OData.Service.Sample.TrippinInMemory.Models.Person; 32 | // Trips?: Microsoft.OData.Service.Sample.TrippinInMemory.Models.Trip[]; 33 | 34 | // } 35 | // export interface Airline { 36 | // AirlineCode: Edm.String; 37 | // Name: Edm.String; 38 | 39 | // } 40 | // export interface Airport { 41 | // Name: Edm.String; 42 | // IcaoCode: Edm.String; 43 | // IataCode: Edm.String; 44 | // Location: Microsoft.OData.Service.Sample.TrippinInMemory.Models.AirportLocation; 45 | 46 | // } 47 | // export interface Trip { 48 | // TripId: Edm.Int32; 49 | // ShareId: Edm.Guid; 50 | // Name: Edm.String; 51 | // Budget: Edm.Single; 52 | // Description: Edm.String; 53 | // Tags: Edm.String[]; 54 | // StartsAt: Edm.DateTimeOffset; 55 | // EndsAt: Edm.DateTimeOffset; 56 | // PlanItems?: Microsoft.OData.Service.Sample.TrippinInMemory.Models.PlanItem[]; 57 | 58 | // } 59 | // export interface PlanItem { 60 | // PlanItemId: Edm.Int32; 61 | // ConfirmationCode: Edm.String; 62 | // StartsAt: Edm.DateTimeOffset; 63 | // EndsAt: Edm.DateTimeOffset; 64 | // Duration: Edm.Duration; 65 | 66 | // } 67 | // export interface Event { 68 | // OccursAt: Microsoft.OData.Service.Sample.TrippinInMemory.Models.EventLocation; 69 | // Description: Edm.String; 70 | 71 | // } 72 | // export interface PublicTransportation { 73 | // SeatNumber: Edm.String; 74 | 75 | // } 76 | // export interface Flight { 77 | // FlightNumber: Edm.String; 78 | // Airline?: Microsoft.OData.Service.Sample.TrippinInMemory.Models.Airline; 79 | // From?: Microsoft.OData.Service.Sample.TrippinInMemory.Models.Airport; 80 | // To?: Microsoft.OData.Service.Sample.TrippinInMemory.Models.Airport; 81 | 82 | // } 83 | // export interface Employee { 84 | // Cost: Edm.Int64; 85 | // Peers?: Microsoft.OData.Service.Sample.TrippinInMemory.Models.Person[]; 86 | 87 | // } 88 | // export interface Manager { 89 | // Budget: Edm.Int64; 90 | // BossOffice: Microsoft.OData.Service.Sample.TrippinInMemory.Models.Location; 91 | // DirectReports?: Microsoft.OData.Service.Sample.TrippinInMemory.Models.Person[]; 92 | 93 | // } 94 | // export interface Location { 95 | // Address: Edm.String; 96 | // City: Microsoft.OData.Service.Sample.TrippinInMemory.Models.City; 97 | 98 | // } 99 | // export interface City { 100 | // Name: Edm.String; 101 | // CountryRegion: Edm.String; 102 | // Region: Edm.String; 103 | 104 | // } 105 | // export interface AirportLocation { 106 | // Loc: Edm.GeographyPoint; 107 | 108 | // } 109 | // export interface EventLocation { 110 | // BuildingInfo: Edm.String; 111 | 112 | // } 113 | // // Enum Values: Male = 0, Female = 1, Unknow = 2 114 | // export type PersonGender = "Male" | "Female" | "Unknow"; 115 | // // Enum Values: Feature1 = 0, Feature2 = 1, Feature3 = 2, Feature4 = 3 116 | // export type Feature = "Feature1" | "Feature2" | "Feature3" | "Feature4"; 117 | // } 118 | 119 | // type JSDate = Date; 120 | 121 | // declare namespace Edm { 122 | // export type Duration = string; 123 | // export type Binary = string; 124 | // export type Boolean = boolean; 125 | // export type Byte = number; 126 | // export type Date = JSDate; 127 | // export type DateTimeOffset = JSDate; 128 | // export type Decimal = number; 129 | // export type Double = number; 130 | // export type Guid = string; 131 | // export type Int16 = number; 132 | // export type Int32 = number; 133 | // export type Int64 = number; 134 | // export type SByte = number; 135 | // export type Single = number; 136 | // export type String = string; 137 | // export type TimeOfDay = string; 138 | // export type Stream = string; 139 | // export type GeographyPoint = any; 140 | // } -------------------------------------------------------------------------------- /test/testproject/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "testodataproxy", 3 | "version": "0.0.1", 4 | "devDependencies": { 5 | "@types/mocha": "^2.2.32", 6 | "@types/node": "^6.0.40", 7 | "assert": "^1.4.1", 8 | "mocha": "^2.3.3", 9 | "typescript": "^2.0.3", 10 | "vscode": "^1.0.0" 11 | }, 12 | "scripts": { 13 | "vscode:prepublish": "tsc -p ./", 14 | "compile": "tsc -watch -p ./", 15 | "postinstall": "node ./node_modules/vscode/bin/install" 16 | } 17 | } -------------------------------------------------------------------------------- /test/testproject/proxy/odataproxybase.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"odataproxybase.js","sourceRoot":"","sources":["odataproxybase.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /test/testproject/proxy/proxy.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"proxy.js","sourceRoot":"","sources":["proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;2EAQ2E"} -------------------------------------------------------------------------------- /test/testproject/proxy/testproxy.js: -------------------------------------------------------------------------------- 1 | /************************************************************************** 2 | Created by odatatools: https://marketplace.visualstudio.com/items?itemName=apazureck.odatatools 3 | Use Command 'odata: xyUpdate to refresh data while this file is active in the editor. 4 | Creation Time: Mon Jan 15 2018 20:23:58 GMT+0100 (Mitteleuropäische Zeit) 5 | DO NOT DELETE THIS IN ORDER TO UPDATE YOUR SERVICE 6 | #ODATATOOLSOPTIONS 7 | { 8 | "modularity": "Ambient", 9 | "requestOptions": {}, 10 | "source": "unknown" 11 | } 12 | #ODATATOOLSOPTIONSEND 13 | **************************************************************************/ 14 | //# sourceMappingURL=testproxy.js.map -------------------------------------------------------------------------------- /test/testproject/proxy/testproxy.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"testproxy.js","sourceRoot":"","sources":["testproxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;2EAY2E"} -------------------------------------------------------------------------------- /test/testproject/proxy/testproxy2.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"testproxy2.js","sourceRoot":"","sources":["testproxy2.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /test/testproject/test/odataproxybase.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"odataproxybase.js","sourceRoot":"","sources":["odataproxybase.ts"],"names":[],"mappings":"AAAA,IAAU,UAAU,CAoTnB;AApTD,WAAU,UAAU;IAChB,IAAK,MAEJ;IAFD,WAAK,MAAM;QACP,iCAAG,CAAA;QAAE,mCAAI,CAAA;QAAE,iCAAG,CAAA;QAAE,qCAAK,CAAA;QAAE,uCAAM,CAAA;IACjC,CAAC,EAFI,MAAM,KAAN,MAAM,QAEV;IAED;QACI,YAA4B,OAAe,EAAkB,IAAa,EAAE,gBAAiC;YAAjF,YAAO,GAAP,OAAO,CAAQ;YAAkB,SAAI,GAAJ,IAAI,CAAS;YACtE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,cAAc,CAAC;YAExC,IAAI,CAAC,OAAO,GAAG,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;YAElF,GAAG,CAAC,CAAC,IAAI,QAAQ,IAAI,gBAAgB,CAAC,CAAC,CAAC;gBAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAAC,CAAC;YAAA,CAAC;QACpG,CAAC;KASJ;IAhBY,oBAAS,YAgBrB,CAAA;IAED;;;;;;;OAOG;IACH;QAEI;;;;;;;;;WASG;QACH,YAAY,IAAY,EAAE,OAAe,EAAE,GAAW,EAAE,iBAAkC;YACtF,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC;YACvD,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;YACf,IAAI,CAAC,OAAO,GAAG,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;YAElF,GAAG,CAAC,CAAC,IAAI,QAAQ,IAAI,iBAAiB,CAAC,CAAC,CAAC;gBAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YAAC,CAAC;YAAA,CAAC;QACtG,CAAC;QAqCD,GAAG,CAAC,UAAmB,EAAE,UAAmB;YACxC,IAAI,MAAc,CAAC;YAEnB,IAAI,UAAU,GAAG,UAAU,IAAI,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACvD,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;gBACd,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC;YAC1B,CAAC;YAAC,IAAI,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;gBACpB,MAAM,GAAG,IAAI,CAAC,OAAO,GAAG,CAAC,UAAU,GAAG,GAAG,GAAG,UAAU,GAAG,EAAE,CAAC,CAAC;YACjE,CAAC;YAAC,IAAI,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;gBACpB,MAAM,GAAG,IAAI,CAAC,OAAO,GAAG,GAAG,GAAG,UAAU,GAAG,GAAG,GAAG,GAAG,GAAG,UAAU,CAAC;YACtE,CAAC;YAAC,IAAI,CAAC,CAAC;gBACJ,MAAM,GAAG,IAAI,CAAC,OAAO,GAAG,GAAG,GAAG,UAAU,GAAG,GAAG,CAAA;YAClD,CAAC;YACD,IAAI,OAAO,GAAoB;gBAC3B,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;gBAC1B,UAAU,EAAE,MAAM;aACrB,CAAA;YACD,wDAAwD;YACxD,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;gBACd,IAAI,QAAQ,GAAG,IAAI,cAAc,EAAK,CAAC;gBACvC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,QAAQ;oBAC1C,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;wBAChB,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;oBAC3B,CAAC;gBACL,CAAC,EAAE,CAAC,KAAK;oBACL,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,GAAG,KAAK,CAAC,OAAO,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;oBACxJ,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;wBACjB,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBAC3B,CAAC;gBACL,CAAC,CAAC,CAAC;gBACH,MAAM,CAAC,QAAQ,CAAC;YACpB,CAAC;YAAC,IAAI,CAAC,CAAC;gBACJ,IAAI,QAAQ,GAAG,IAAI,cAAc,EAAO,CAAC;gBACzC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,QAAQ;oBAC1C,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;wBAChB,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;oBAC3B,CAAC;gBACL,CAAC,EAAE,CAAC,KAAK;oBACL,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,GAAG,KAAK,CAAC,OAAO,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;oBACxJ,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;wBACjB,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBAC3B,CAAC;gBACL,CAAC,CAAC,CAAC;gBACH,MAAM,CAAC,QAAQ,CAAC;YACpB,CAAC;QACL,CAAC;QAGD;;;;;;;WAOG;QACH,GAAG,CAAC,KAAQ;YACR,IAAI,QAAQ,GAAG,IAAI,cAAc,EAAQ,CAAC;YAE1C,IAAI,OAAO,GAAoB;gBAC3B,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;gBAC1B,UAAU,EAAE,IAAI,CAAC,OAAO,GAAG,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG;gBACtD,IAAI,EAAE,KAAK;aACd,CAAA;YACD,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,QAAQ;gBAC1C,QAAQ,CAAC,OAAO,EAAE,CAAC;YACvB,CAAC,EAAE,CAAC,KAAK;gBACL,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,GAAG,KAAK,CAAC,OAAO,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;gBACxJ,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC3B,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,QAAQ,CAAC;QACpB,CAAC;QAED;;;;;;;WAOG;QACH,IAAI,CAAC,KAAQ;YACT,IAAI,QAAQ,GAAG,IAAI,cAAc,EAAK,CAAC;YACvC,IAAI,OAAO,GAAoB;gBAC3B,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;gBAC3B,UAAU,EAAE,IAAI,CAAC,OAAO;gBACxB,IAAI,EAAE,KAAK;aACd,CAAA;YACD,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,QAAQ;gBAC1C,QAAQ,CAAC,OAAO,CAAC,IAAS,CAAC,CAAC;YAChC,CAAC,EAAE,CAAC,KAAK;gBACL,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,GAAG,KAAK,CAAC,OAAO,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;gBACxJ,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC3B,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,QAAQ,CAAC;QACpB,CAAC;QAGD,KAAK,CAAC,aAAyB,EAAE,MAAU;YACvC,EAAE,CAAC,CAAC,MAAM,CAAC;gBACP,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAkB,EAAE,MAAM,CAAC,CAAC;YAE9D,IAAI,QAAQ,GAAG,IAAI,cAAc,EAAQ,CAAC;YAC1C,IAAI,OAAO,GAAoB;gBAC3B,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;gBAC5B,UAAU,EAAE,IAAI,CAAC,OAAO;gBACxB,IAAI,EAAE,aAAa;aACtB,CAAA;YACD,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,QAAQ;gBAC1C,QAAQ,CAAC,OAAO,EAAE,CAAC;YACvB,CAAC,EAAE,CAAC,KAAK;gBACL,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,GAAG,KAAK,CAAC,OAAO,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;gBACxJ,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC3B,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,QAAQ,CAAC;QACpB,CAAC;QAEO,QAAQ,CAAC,MAAS,EAAE,MAAS;YACjC,IAAI,GAAG,GAAQ,EAAE,CAAC;YAClB,GAAG,CAAC,CAAC,IAAI,IAAI,IAAI,MAAM,CAAC;gBACpB,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;oBAC7B,GAAG,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;YACjC,MAAM,CAAC,GAAG,CAAC;QACf,CAAC;QACD;;;;;;;WAOG;QACH,MAAM,CAAC,KAAQ;YACX,IAAI,QAAQ,GAAG,IAAI,cAAc,EAAQ,CAAA;YACzC,IAAI,OAAO,GAAoB;gBAC3B,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;gBAC7B,UAAU,EAAE,IAAI,CAAC,OAAO,GAAG,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG;aACzD,CAAA;YACD,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,QAAQ;gBAC1C,QAAQ,CAAC,OAAO,EAAE,CAAC;YACvB,CAAC,EAAE,CAAC,KAAK;gBACL,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,GAAG,KAAK,CAAC,OAAO,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;gBACxJ,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC3B,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,QAAQ,CAAC;QACpB,CAAC;KACJ;IA/MY,oBAAS,YA+MrB,CAAA;IAED;QACI,YAAY,IAAY,EAAE,GAAW;YACjC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;YACjB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACnB,CAAC;KAGJ;IAGD;;;;;;OAMG;IACH;QAAA;YACY,UAAK,GAA4B,EAAE,CAAC;YACpC,WAAM,GAA8B,EAAE,CAAC;QAmBnD,CAAC;QAlBU,IAAI,CAAC,IAAyB;YACjC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtB,MAAM,CAAC,IAAI,CAAC;QAChB,CAAC;QACM,KAAK,CAAC,MAA4B;YACrC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC;QAChB,CAAC;QACM,OAAO,CAAC,KAAS;YACpB,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;gBACX,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC;oBACrB,CAAC,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;QACM,MAAM,CAAC,KAAU;YACpB,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;gBACZ,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC;oBACtB,CAAC,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;KACJ;IArBY,yBAAc,iBAqB1B,CAAA;AA8BL,CAAC,EApTS,UAAU,KAAV,UAAU,QAoTnB;AAgBD,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC"} -------------------------------------------------------------------------------- /test/testproject/test/odataservicetests.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | QUnit Example 7 | 8 | 9 | 10 |
11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /test/testproject/test/odataservicetests.js: -------------------------------------------------------------------------------- 1 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 2 | return new (P || (P = Promise))(function (resolve, reject) { 3 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } 4 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } 5 | function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } 6 | step((generator = generator.apply(thisArg, _arguments || [])).next()); 7 | }); 8 | }; 9 | var MovieProxy = MovieService.MovieContainer; 10 | var serviceuri = "http://localhost:2200/moviedb"; 11 | console.log("Starting Tests"); 12 | QUnit.test("Default test", function (assert) { 13 | assert.ok(1 === 1, "Passed!"); 14 | }); 15 | QUnit.test("Test Get", (assert) => __awaiter(this, void 0, void 0, function* () { 16 | let comm = new MovieProxy(serviceuri, "Testproxy"); 17 | let done = assert.async(); 18 | try { 19 | yield comm.Addresses.Get(); 20 | assert.ok(true, "Passed get all"); 21 | yield comm.Addresses.Select("Id").Get("1"); 22 | assert.ok(true, "Passed get one with select"); 23 | done(); 24 | } 25 | catch (error) { 26 | assert.ok(false, JSON.stringify(error)); 27 | done(); 28 | } 29 | })); 30 | QUnit.test("Test Post", (assert) => { 31 | let comm = new MovieProxy(serviceuri, "Testproxy"); 32 | let done = assert.async(); 33 | comm.Addresses.Post({ 34 | Id: 0, Street: "123 Fakestreet", Zip: "123456" 35 | }).then((value) => { 36 | assert.ok(true); 37 | done(); 38 | }).catch((err) => { 39 | assert.ok(false, JSON.stringify(err)); 40 | done(); 41 | }); 42 | }); 43 | QUnit.test("Test Rate Action", (assert) => { 44 | let comm = new MovieProxy(serviceuri, "Testproxy"); 45 | let done = assert.async(); 46 | comm.Movies.Rate(0, 2.5, "This is not a good movie.").then((value) => { 47 | assert.ok(value === "Rated successfully"); 48 | done(); 49 | }).catch((err) => { 50 | assert.ok(false, JSON.stringify(err)); 51 | done(); 52 | }); 53 | }); 54 | QUnit.test("Test Unbound Action", (assert) => { 55 | let comm = new MovieProxy(serviceuri, "Testproxy"); 56 | let done = assert.async(); 57 | comm.SetSomething(25).then((value) => { 58 | assert.ok(value === 25); 59 | done(); 60 | }).catch((err) => { 61 | assert.ok(false, JSON.stringify(err)); 62 | done(); 63 | }); 64 | }); 65 | QUnit.test("Test Unbound Function", (assert) => { 66 | let comm = new MovieProxy(serviceuri, "Testproxy"); 67 | let done = assert.async(); 68 | comm.CurrentTime().then((value) => { 69 | let curtime = new Date(value); 70 | assert.ok(curtime != undefined); 71 | done(); 72 | }).catch((err) => { 73 | assert.ok(false, JSON.stringify(err)); 74 | done(); 75 | }); 76 | }); 77 | //# sourceMappingURL=odataservicetests.js.map -------------------------------------------------------------------------------- /test/testproject/test/odataservicetests.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"odataservicetests.js","sourceRoot":"","sources":["odataservicetests.ts"],"names":[],"mappings":";;;;;;;;AAAA,IAAO,UAAU,GAAG,YAAY,CAAC,cAAc,CAAC;AAEhD,IAAI,UAAU,GAAG,+BAA+B,CAAC;AACjD,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;AAC9B,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,UAAU,MAAM;IACzC,MAAM,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;AAChC,CAAC,CAAC,CAAC;AAEH,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,CAAO,MAAM,EAAE,EAAE;IACtC,IAAI,IAAI,GAAG,IAAI,UAAU,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IACnD,IAAI,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IAE1B,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC;QAC3B,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;QAClC,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,4BAA4B,CAAC,CAAC;QAC9C,IAAI,EAAE,CAAA;IACR,CAAC;IAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QACf,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QACxC,IAAI,EAAE,CAAC;IACT,CAAC;AACH,CAAC,CAAA,CAAC,CAAC;AAEH,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,MAAM,EAAE,EAAE;IACjC,IAAI,IAAI,GAAG,IAAI,UAAU,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IAEnD,IAAI,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IAE1B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;QAClB,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,gBAAgB,EAAE,GAAG,EAAE,QAAQ;KAC/C,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;QAChB,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;QAChB,IAAI,EAAE,CAAC;IACT,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACf,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QACtC,IAAI,EAAE,CAAC;IACT,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAC;AAEH,KAAK,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,MAAM,EAAE,EAAE;IACxC,IAAI,IAAI,GAAG,IAAI,UAAU,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IAEnD,IAAI,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IAE1B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,2BAA2B,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;QACnE,MAAM,CAAC,EAAE,CAAC,KAAK,KAAK,qBAAqB,CAAC,CAAC;QAC3C,IAAI,EAAE,CAAC;IACT,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACf,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QACtC,IAAI,EAAE,CAAC;IACT,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAC;AAEH,KAAK,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,MAAM,EAAE,EAAE;IAC3C,IAAI,IAAI,GAAG,IAAI,UAAU,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IAEnD,IAAI,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IAC1B,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;QACnC,MAAM,CAAC,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;QACxB,IAAI,EAAE,CAAC;IACT,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACf,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QACtC,IAAI,EAAE,CAAC;IACT,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAC;AAEH,KAAK,CAAC,IAAI,CAAC,uBAAuB,EAAE,CAAC,MAAM,EAAE,EAAE;IAC7C,IAAI,IAAI,GAAG,IAAI,UAAU,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IAEnD,IAAI,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IAE1B,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE;QAChC,IAAI,OAAO,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;QAC9B,MAAM,CAAC,EAAE,CAAC,OAAO,IAAI,SAAS,CAAC,CAAC;QAChC,IAAI,EAAE,CAAC;IACT,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACf,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QACtC,IAAI,EAAE,CAAC;IACT,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAC"} -------------------------------------------------------------------------------- /test/testproject/test/odataservicetests.ts: -------------------------------------------------------------------------------- 1 | import MovieProxy = MovieService.MovieContainer; 2 | 3 | var serviceuri = "http://localhost:2200/moviedb"; 4 | console.log("Starting Tests"); 5 | QUnit.test("Default test", function (assert) { 6 | assert.ok(1 === 1, "Passed!"); 7 | }); 8 | 9 | QUnit.test("Test Get", async (assert) => { 10 | let comm = new MovieProxy(serviceuri, "Testproxy"); 11 | let done = assert.async(); 12 | 13 | try { 14 | await comm.Addresses.Get(); 15 | assert.ok(true, "Passed get all"); 16 | await comm.Addresses.Select("Id").Get("1"); 17 | assert.ok(true, "Passed get one with select"); 18 | done() 19 | } catch (error) { 20 | assert.ok(false, JSON.stringify(error)); 21 | done(); 22 | } 23 | }); 24 | 25 | QUnit.test("Test Post", (assert) => { 26 | let comm = new MovieProxy(serviceuri, "Testproxy"); 27 | 28 | let done = assert.async(); 29 | 30 | comm.Addresses.Post({ 31 | Id: 0, Street: "123 Fakestreet", Zip: "123456" 32 | }).then((value) => { 33 | assert.ok(true); 34 | done(); 35 | }).catch((err) => { 36 | assert.ok(false, JSON.stringify(err)); 37 | done(); 38 | }) 39 | }); 40 | 41 | QUnit.test("Test Rate Action", (assert) => { 42 | let comm = new MovieProxy(serviceuri, "Testproxy"); 43 | 44 | let done = assert.async(); 45 | 46 | comm.Movies.Rate(0, 2.5, "This is not a good movie.").then((value) => { 47 | assert.ok(value === "Rated successfully"); 48 | done(); 49 | }).catch((err) => { 50 | assert.ok(false, JSON.stringify(err)); 51 | done(); 52 | }) 53 | }); 54 | 55 | QUnit.test("Test Unbound Action", (assert) => { 56 | let comm = new MovieProxy(serviceuri, "Testproxy"); 57 | 58 | let done = assert.async(); 59 | comm.SetSomething(25).then((value) => { 60 | assert.ok(value === 25); 61 | done(); 62 | }).catch((err) => { 63 | assert.ok(false, JSON.stringify(err)); 64 | done(); 65 | }) 66 | }); 67 | 68 | QUnit.test("Test Unbound Function", (assert) => { 69 | let comm = new MovieProxy(serviceuri, "Testproxy"); 70 | 71 | let done = assert.async(); 72 | 73 | comm.CurrentTime().then((value) => { 74 | let curtime = new Date(value); 75 | assert.ok(curtime != undefined); 76 | done(); 77 | }).catch((err) => { 78 | assert.ok(false, JSON.stringify(err)); 79 | done(); 80 | }) 81 | }); -------------------------------------------------------------------------------- /test/testproject/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "sourceMap": true 6 | }, 7 | "exclude": [ 8 | "node_modules", 9 | ".vscode", 10 | "out" 11 | ], 12 | "lib": [ 13 | "es6" 14 | ], 15 | "rootDir": "." 16 | } -------------------------------------------------------------------------------- /test/testproject/typings/globals/qunit/typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "resolution": "main", 3 | "tree": { 4 | "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/253e456e3c0bf4bd34afaceb7dcbae282da14066/qunit/index.d.ts", 5 | "raw": "registry:dt/qunit#2.0.1+20161119044246", 6 | "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/253e456e3c0bf4bd34afaceb7dcbae282da14066/qunit/index.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/testproject/typings/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /testrequests.http: -------------------------------------------------------------------------------- 1 | GET http://localhost:2200/moviedb/$metadata HTTP/1.1 2 | content-type: application/json 3 | 4 | ### 5 | 6 | GET http://localhost:2200/moviedb/Customers HTTP/1.1 7 | content-type: application/json -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es6", 5 | "outDir": "out", 6 | "lib": [ 7 | "es6" 8 | ], 9 | "sourceMap": true, 10 | "rootDir": "." 11 | }, 12 | "exclude": [ 13 | "node_modules", 14 | ".vscode-test", 15 | "test/testproject", 16 | "dist" 17 | ] 18 | } -------------------------------------------------------------------------------- /typings/edm.d.ts: -------------------------------------------------------------------------------- 1 | interface EdmxBase { 2 | 3 | } 4 | 5 | type ftype = "Action" | "Function" 6 | 7 | interface Edmx extends EdmxBase { 8 | $: { 9 | Version: string; 10 | "xmlns:edmx": string; 11 | } 12 | "edmx:DataServices": DataService[]; 13 | } 14 | 15 | interface DataService { 16 | Schema: Schema[], 17 | Address: string 18 | } 19 | 20 | interface Schema extends EdmxBase { 21 | $: { Namespace: string; } 22 | ComplexType?: ComplexType[]; 23 | EntityType?: EntityType[]; 24 | EnumType?: EnumType[]; 25 | EntityContainer?: EntityContainer[]; 26 | Action?: Method[]; 27 | Function?: Method[]; 28 | } 29 | 30 | interface EntityContainer { 31 | $: { 32 | Name: string; 33 | }, 34 | EntitySet: EntitySet[], 35 | FunctionImport: FunctionImport[], 36 | ActionImport: ActionImport[], 37 | } 38 | 39 | interface EntitySet { 40 | $: { 41 | Name: string, 42 | EntityType: string 43 | } 44 | NavigationPropertyBinding: NavigationPropertyBinding[]; 45 | FunctionImport: FunctionImport[] 46 | } 47 | 48 | interface FunctionImport { 49 | $: { 50 | Name: string; 51 | Function: string; 52 | EntitySet?: string; 53 | IncludeInServiceDocument?: boolean; 54 | } 55 | } 56 | 57 | interface ActionImport { 58 | $: { 59 | Name: string; 60 | Action: string; 61 | EntitySet?: string; 62 | } 63 | } 64 | 65 | interface NavigationPropertyBinding { 66 | $: { 67 | Path: string 68 | Target: string 69 | } 70 | } 71 | 72 | interface EnumType { 73 | $: { Name: string; } 74 | Member: { 75 | $: { 76 | Name: string; 77 | Value: number; 78 | } 79 | }[] 80 | } 81 | 82 | interface NavigationProperty { 83 | ReferentialConstraint?: { 84 | $: { 85 | Name: string; 86 | Type: string; 87 | Property: string; 88 | ReferencedProperty: string; 89 | } 90 | } 91 | } 92 | 93 | interface ComplexType extends EdmxBase { 94 | $: { 95 | Name: string; 96 | BaseType?: string; 97 | OpenType?: boolean; 98 | } 99 | Property: Property[]; 100 | } 101 | 102 | interface Property extends EdmxBase { 103 | $: { 104 | Name: string; 105 | Type: string; 106 | Nullable?: boolean | string; 107 | } 108 | } 109 | 110 | interface EntityType extends ComplexType { 111 | Key?: { PropertyRef: { $: { Name: string } }[] }[]; 112 | NavigationProperty: NavigationProperty[]; 113 | } 114 | 115 | interface Method { 116 | $: { 117 | Name: string; 118 | IsBound: boolean; 119 | } 120 | Parameter?: Parameter[] 121 | ReturnType?: ReturnType[] 122 | 123 | // added by proxygenerator: 124 | IsBoundToCollection?: boolean; 125 | Namespace: string 126 | 127 | //Added by the proxygenerator 128 | Type: ftype 129 | } 130 | 131 | interface ReturnType { 132 | $: { 133 | Type: string; 134 | } 135 | } 136 | 137 | interface Parameter { 138 | $: { 139 | Name: string; 140 | Type: string; 141 | Unicode?: boolean; 142 | Nullable?: boolean; 143 | Precision?: number; 144 | MaxLength?: number; 145 | Scale?: number | "variable" | "floating"; 146 | SRID?: string; 147 | } 148 | } -------------------------------------------------------------------------------- /wiki/Graphics.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apazureck/odatatools/e749f080fbe0146656f2cec5dc523b10a316b553/wiki/Graphics.pptx -------------------------------------------------------------------------------- /wiki/clientGenerator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apazureck/odatatools/e749f080fbe0146656f2cec5dc523b10a316b553/wiki/clientGenerator.png --------------------------------------------------------------------------------