├── .gitignore
├── .jshintrc
├── .npmignore
├── Gruntfile.js
├── LICENSE
├── README.md
├── bin
└── swagger2js.js
├── circle.yml
├── lib
├── cli.js
├── codegen.js
├── flow.js
└── typescript.js
├── package-lock.json
├── package.json
├── templates
├── angular-class.mustache
├── flow-class.mustache
├── flow-method.mustache
├── flow-type.mustache
├── method.mustache
├── node-class.mustache
├── react-class.mustache
├── type.mustache
├── typescript-class.mustache
└── typescript-method.mustache
├── tests
├── apis
│ ├── _batch.json
│ ├── _datasources.json
│ ├── _jobs.json
│ ├── _modules.json
│ ├── _queries.json
│ ├── account.json
│ ├── auth.json
│ ├── package.json
│ ├── ping.json
│ ├── project.json
│ ├── protected.json
│ ├── queries.json
│ ├── ref.json
│ ├── test.json
│ ├── uber.json
│ └── users.json
└── generation.js
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea/
2 | node_modules/
3 | *.iml
4 | wks.*
5 | .DS_Store
6 | *.swp
7 |
8 | tmp-*
9 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "node": true,
3 | "browser": false,
4 | "esnext": true,
5 | "bitwise": false,
6 | "camelcase": false,
7 | "curly": true,
8 | "eqeqeq": true,
9 | "immed": true,
10 | "indent": 4,
11 | "latedef": true,
12 | "newcap": false,
13 | "noarg": true,
14 | "quotmark": "single",
15 | "regexp": true,
16 | "undef": true,
17 | "unused": true,
18 | "strict": true,
19 | "trailing": true,
20 | "smarttabs": true,
21 | "globals": {
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .git*
2 | test/
3 | .DS_Store
4 | *.swp
5 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | module.exports = function (grunt) {
2 | 'use strict';
3 |
4 | require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
5 | // Load local tasks.
6 | //grunt.loadTasks('tasks');
7 |
8 | // Project configuration.
9 | grunt.initConfig({
10 | jshint: {
11 | all: ['Gruntfile.js', 'lib/**/*.js', 'tests/**/*.js'],
12 | options: {
13 | jshintrc: '.jshintrc'
14 | }
15 | },
16 | vows: {
17 | all: {
18 | options: {
19 | verbose: true,
20 | colors: true,
21 | coverage: 'json'
22 | },
23 | // String or array of strings
24 | // determining which files to include.
25 | // This option is grunt's "full" file format.
26 | src: ['tests/*.js']
27 | }
28 | },
29 | jsonlint: {
30 | all: {
31 | src: ['package.json', 'tests/apis/*.json', '.jshintrc']
32 | }
33 | }
34 | });
35 |
36 | // Default task.
37 | grunt.registerTask('default', ['jsonlint', 'jshint', 'vows']);
38 | };
39 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Swagger to JS & Typescript Codegen
2 | [](https://circleci.com/gh/wcandillon/swagger-js-codegen) [](http://badge.fury.io/js/swagger-js-codegen)
3 |
4 | ## We are looking for a new maintainer
5 |
6 | This project is no longer actively maintained by its creator. Please let us know if you would like to become a maintainer.
7 | At the time we wrote this package, the swagger didn't have generators for JavaScript nor TypeScript. Now there are [great alternatives of this package available](https://github.com/swagger-api/swagger-codegen).
8 |
9 | This package generates a nodejs, reactjs or angularjs class from a [swagger specification file](https://github.com/wordnik/swagger-spec). The code is generated using [mustache templates](https://github.com/wcandillon/swagger-js-codegen/tree/master/templates) and is quality checked by [jshint](https://github.com/jshint/jshint/) and beautified by [js-beautify](https://github.com/beautify-web/js-beautify).
10 |
11 | The typescript generator is based on [superagent](https://github.com/visionmedia/superagent) and can be used for both nodejs and the browser via browserify/webpack.
12 |
13 | ## Installation
14 | ```bash
15 | npm install swagger-js-codegen
16 | ```
17 |
18 | ## Example
19 | ```javascript
20 | var fs = require('fs');
21 | var CodeGen = require('swagger-js-codegen').CodeGen;
22 |
23 | var file = 'swagger/spec.json';
24 | var swagger = JSON.parse(fs.readFileSync(file, 'UTF-8'));
25 | var nodejsSourceCode = CodeGen.getNodeCode({ className: 'Test', swagger: swagger });
26 | var angularjsSourceCode = CodeGen.getAngularCode({ className: 'Test', swagger: swagger });
27 | var reactjsSourceCode = CodeGen.getReactCode({ className: 'Test', swagger: swagger });
28 | var tsSourceCode = CodeGen.getTypescriptCode({ className: 'Test', swagger: swagger, imports: ['../../typings/tsd.d.ts'] });
29 | console.log(nodejsSourceCode);
30 | console.log(angularjsSourceCode);
31 | console.log(reactjsSourceCode);
32 | console.log(tsSourceCode);
33 | ```
34 |
35 | ## Custom template
36 | ```javascript
37 | var source = CodeGen.getCustomCode({
38 | moduleName: 'Test',
39 | className: 'Test',
40 | swagger: swaggerSpec,
41 | template: {
42 | class: fs.readFileSync('my-class.mustache', 'utf-8'),
43 | method: fs.readFileSync('my-method.mustache', 'utf-8'),
44 | type: fs.readFileSync('my-type.mustache', 'utf-8')
45 | }
46 | });
47 | ```
48 |
49 | ## Options
50 | In addition to the common options listed below, `getCustomCode()` *requires* a `template` field:
51 |
52 | template: { class: "...", method: "..." }
53 |
54 | `getAngularCode()`, `getNodeCode()`, and `getCustomCode()` each support the following options:
55 |
56 | ```yaml
57 | moduleName:
58 | type: string
59 | description: Your AngularJS module name
60 | className:
61 | type: string
62 | lint:
63 | type: boolean
64 | description: whether or not to run jslint on the generated code
65 | esnext:
66 | type: boolean
67 | description: passed through to jslint
68 | beautify:
69 | type: boolean
70 | description: whether or not to beautify the generated code
71 | mustache:
72 | type: object
73 | description: See the 'Custom Mustache Variables' section below
74 | imports:
75 | type: array
76 | description: Typescript definition files to be imported.
77 | swagger:
78 | type: object
79 | required: true
80 | description: swagger object
81 | ```
82 |
83 | ### Template Variables
84 | The following data are passed to the [mustache templates](https://github.com/janl/mustache.js):
85 |
86 | ```yaml
87 | isNode:
88 | type: boolean
89 | isES6:
90 | type: boolean
91 | description:
92 | type: string
93 | description: Provided by your options field: 'swagger.info.description'
94 | isSecure:
95 | type: boolean
96 | description: false unless 'swagger.securityDefinitions' is defined
97 | moduleName:
98 | type: string
99 | description: Your AngularJS module name - provided by your options field
100 | className:
101 | type: string
102 | description: Provided by your options field
103 | domain:
104 | type: string
105 | description: If all options defined: swagger.schemes[0] + '://' + swagger.host + swagger.basePath
106 | methods:
107 | type: array
108 | items:
109 | type: object
110 | properties:
111 | path:
112 | type: string
113 | className:
114 | type: string
115 | description: Provided by your options field
116 | methodName:
117 | type: string
118 | description: Generated from the HTTP method and path elements or 'x-swagger-js-method-name' field
119 | method:
120 | type: string
121 | description: 'GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'COPY', 'HEAD', 'OPTIONS', 'LINK', 'UNLIK', 'PURGE', 'LOCK', 'UNLOCK', 'PROPFIND'
122 | enum:
123 | - GET
124 | - POST
125 | - PUT
126 | - DELETE
127 | - PATCH
128 | - COPY
129 | - HEAD
130 | - OPTIONS
131 | - LINK
132 | - UNLIK
133 | - PURGE
134 | - LOCK
135 | - UNLOCK
136 | - PROPFIND
137 | isGET:
138 | type: string
139 | description: true if method === 'GET'
140 | summary:
141 | type: string
142 | description: Provided by the 'description' or 'summary' field in the schema
143 | externalDocs:
144 | type: object
145 | properties:
146 | url:
147 | type: string
148 | description: The URL for the target documentation. Value MUST be in the format of a URL.
149 | required: true
150 | description:
151 | type: string
152 | description: A short description of the target documentation. GitHub-Markdown syntax can be used for rich text representation.
153 | isSecure:
154 | type: boolean
155 | description: true if the 'security' is defined for the method in the schema
156 | parameters:
157 | type: array
158 | description: Includes all of the properties defined for the parameter in the schema plus:
159 | items:
160 | camelCaseName:
161 | type: string
162 | isSingleton:
163 | type: boolean
164 | description: true if there was only one 'enum' defined for the parameter
165 | singleton:
166 | type: string
167 | description: the one and only 'enum' defined for the parameter (if there is only one)
168 | isBodyParameter:
169 | type: boolean
170 | isPathParameter:
171 | type: boolean
172 | isQueryParameter:
173 | type: boolean
174 | isPatternType:
175 | type: boolean
176 | description: true if *in* is 'query', and 'pattern' is defined
177 | isHeaderParameter:
178 | type: boolean
179 | isFormParameter:
180 | type: boolean
181 | ```
182 |
183 | #### Custom Mustache Variables
184 | You can also pass in your own variables for the mustache templates by adding a `mustache` object:
185 |
186 | ```javascript
187 | var source = CodeGen.getCustomCode({
188 | ...
189 | mustache: {
190 | foo: 'bar',
191 | app_build_id: env.BUILD_ID,
192 | app_version: pkg.version
193 | }
194 | });
195 | ```
196 |
197 | ## Swagger Extensions
198 |
199 | ### x-proxy-header
200 | Some proxies and application servers inject HTTP headers into the requests. Server-side code
201 | may use these fields, but they are not required in the client API.
202 |
203 | eg: https://cloud.google.com/appengine/docs/go/requests#Go_Request_headers
204 |
205 | ```yaml
206 | /locations:
207 | get:
208 | parameters:
209 | - name: X-AppEngine-Country
210 | in: header
211 | x-proxy-header: true
212 | type: string
213 | description: Provided by AppEngine eg - US, AU, GB
214 | - name: country
215 | in: query
216 | type: string
217 | description: |
218 | 2 character country code.
219 | If not specified, will default to the country provided in the X-AppEngine-Country header
220 | ...
221 | ```
222 |
223 |
224 | ## Grunt task
225 | [There is a grunt task](https://github.com/wcandillon/grunt-swagger-js-codegen) that enables you to integrate the code generation in your development pipeline. This is extremely convenient if your application is using APIs which are documented/specified in the swagger format.
226 |
227 | ## Who is using it?
228 | [28.io](http://28.io) is using this project to generate their [nodejs](https://github.com/28msec/28.io-nodejs) and [angularjs language bindings](https://github.com/28msec/28.io-angularjs).
229 |
--------------------------------------------------------------------------------
/bin/swagger2js.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | var path = require('path');
3 | var fs = require('fs');
4 | var lib = path.join(path.dirname(fs.realpathSync(__filename)), '../lib');
5 | var updateNotifier = require('update-notifier');
6 |
7 | //1. Update Notifier
8 | var pkg = require('../package.json');
9 | updateNotifier({packageName: pkg.name, packageVersion: pkg.version}).notify();
10 |
11 | //4. CLI Script
12 | require(lib + '/cli.js');
--------------------------------------------------------------------------------
/circle.yml:
--------------------------------------------------------------------------------
1 | machine:
2 | node:
3 | version: 5.7.0
4 | dependencies:
5 | post:
6 | - npm install grunt-cli -g
7 |
--------------------------------------------------------------------------------
/lib/cli.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | const fs = require('fs');
4 | const pkg = require('../package.json');
5 | const cli = require('commander');
6 | const yaml = require('js-yaml').safeLoad;
7 | const CodeGen = require('./codegen').CodeGen;
8 |
9 | cli
10 | .version(pkg.version)
11 | .command('generate These resources can be used to perform batch operations. The endpoint of these resources is based on your project name. For instance, if your 28.io project is named This method imports modules and public/private queries from an archive. The archive can either be specified through the The following archive formats and compression algorithms are supported: myproject
, your endpoint for this API will be will be: http://myproject.28.io/v1/_batch
.url
query parameter or through the request body.
When importing, modules will be loaded from the lib
and modules
folders (if any), whereas public and private queries will loaded from the public
and private
folders, respectively. These folders will be first searched in the root of the archive. If none of these folders is found and the archive root contains a single folder, the search will be repeated in that folder. If the archive has a different structure you can specify the path inside the archive where the modules and queries folders are located through the root parameter.
The subfolder structure will be preserved during the import.
The behaviour of the import can be controlled through the overwrite
and delete-orphaned
parameters. By default, orphaned file are removed and existing modules and queries are overwritten. To see the changes that will be performed by a request before they are made, you can use the simulate
query parameter.
The response contains the list of queries and modules of the project along with the taken action. Additionally a list of the files contained in the archive which have been ignored is returned. If the operation succeeds any precompiled query which source has been updated or depending on an updated module will be deleted.
", 19 | "type": "ProjectImport", 20 | "nickname": "importProject", 21 | "parameters": [ 22 | { 23 | "name": "url", 24 | "description": "The archive url.", 25 | "required": false, 26 | "type": "string", 27 | "paramType": "query" 28 | }, 29 | { 30 | "name": "archive", 31 | "description": "The archive contents.", 32 | "required": false, 33 | "type": "string", 34 | "paramType": "body" 35 | }, 36 | { 37 | "name": "root", 38 | "description": "The path inside the archive that contains the modules and queries folders. Use '/' as folder separator.", 39 | "required": false, 40 | "type": "string", 41 | "paramType": "query" 42 | }, 43 | { 44 | "name": "overwrite", 45 | "description": "Whether to overwrite current project queries and modules. Default is true.", 46 | "required": false, 47 | "type": "string", 48 | "enum": [ 49 | "yes", 50 | "if-newer", 51 | "no" 52 | ], 53 | "paramType": "query" 54 | }, 55 | { 56 | "name": "delete-orphaned", 57 | "description": "Whether to delete orphaned file or not. Default is false.", 58 | "required": false, 59 | "type": "boolean", 60 | "paramType": "query" 61 | }, 62 | { 63 | "name": "simulate", 64 | "description": "Whether to simulate the operation or not. Default is false.", 65 | "required": false, 66 | "type": "boolean", 67 | "paramType": "query" 68 | }, 69 | { 70 | "name": "token", 71 | "description": "A project token.", 72 | "required": true, 73 | "type": "string", 74 | "paramType": "query" 75 | }, 76 | { 77 | "name": "Content-Type", 78 | "type": "string", 79 | "paramType": "header", 80 | "enum": [ 81 | "application/zip", 82 | "application/x-gzip" 83 | ] 84 | } 85 | ], 86 | "responseMessages": [ 87 | { 88 | "code": 400, 89 | "message": "Bad request: a parameter is missing or invalid.", 90 | "responseModel": "Error" 91 | }, 92 | { 93 | "code": 401, 94 | "message": "Unauthorized: the specified project token is invalid or expired.", 95 | "responseModel": "Error" 96 | }, 97 | { 98 | "code": 409, 99 | "message": "The specified archive contains the same module in the lib and modules folder.", 100 | "responseModel": "Error" 101 | }, 102 | { 103 | "code": 422, 104 | "message": "The specified archive cannot be downloaded or is corrupted.", 105 | "responseModel": "Error" 106 | }, 107 | { 108 | "code": 500, 109 | "message": "An internal error occurred during the processing of the request.", 110 | "responseModel": "Error" 111 | } 112 | ], 113 | "successMessages": [ 114 | { 115 | "code": 200, 116 | "message": "The project contents have been imported." 117 | } 118 | ], 119 | "examples": [ 120 | { 121 | "description": "The following request imports the project contents from an archive accessible through an URL.", 122 | "title": "Importing the project contents from an archive", 123 | "request": "curl -X PUT \"http://myproject.28.io/v1/_batch/project?url=http%3A%2F%2Fexample.com%2Farchive.zip&token=Rldtayt1YzV5a05FYlRvUFdqc0d4aGcveHJjPToyMDEzLTExLTA2VDA1OjM1OjUzLjk4Njg3N1o%3D\"", 124 | "response": "{ \"removedCompiledQueries\" : [], \"created\": [\"public/query.jq\", \"lib/module.jq\"], \"updated\": [], \"deleted\": [], \"not-updated\": [], \"kept\": [], \"root\": \"/\", \"ignored\": [] }" 125 | } 126 | ] 127 | } 128 | ] 129 | } 130 | ], 131 | "models": { 132 | "Error": { 133 | "id": "Error", 134 | "description": "Error information", 135 | "required": [ 136 | "request_id", 137 | "context", 138 | "message", 139 | "description" 140 | ], 141 | "properties": { 142 | "request_id": { 143 | "type": "string", 144 | "description": "The request identifier" 145 | }, 146 | "context": { 147 | "type": "string", 148 | "description": "The complete domain name of the project" 149 | }, 150 | "message": { 151 | "type": "string", 152 | "description": "A formatted string which contain the error code (always) and the module name, line and column-number and error description (when available)" 153 | }, 154 | "type": { 155 | "type": "string", 156 | "description": "For XQuery errors, the type of the error (e.g. static)" 157 | }, 158 | "code": { 159 | "type": "string", 160 | "description": "For XQuery errors, the error code" 161 | }, 162 | "location": { 163 | "type": "Location", 164 | "description": "For XQuery errors, the error location (if available)" 165 | }, 166 | "stack-trace": { 167 | "type": "array", 168 | "items": { 169 | "$ref": "StackEntry" 170 | }, 171 | "description": "For XQuery errors, the error stack trace (if available)" 172 | } 173 | } 174 | }, 175 | "Location": { 176 | "id": "Location", 177 | "description": "Error information", 178 | "required": [ 179 | "module", 180 | "line-number", 181 | "line-number-end", 182 | "column-number", 183 | "column-number-end" 184 | ], 185 | "properties": { 186 | "module": { 187 | "type": "string", 188 | "description": "The error module" 189 | }, 190 | "line-number": { 191 | "type": "string", 192 | "description": "The error first line number" 193 | }, 194 | "line-number-end": { 195 | "type": "string", 196 | "description": "The error last line number" 197 | }, 198 | "column-number": { 199 | "type": "string", 200 | "description": "The error first column number" 201 | }, 202 | "column-number-end": { 203 | "type": "string", 204 | "description": "The error last column number" 205 | } 206 | } 207 | }, 208 | "StackEntry": { 209 | "id": "StackEntry", 210 | "description": "A stack entry", 211 | "required": [ 212 | "function", 213 | "location" 214 | ], 215 | "properties": { 216 | "function": { 217 | "type": "Function", 218 | "description": "The function of the call" 219 | }, 220 | "type": { 221 | "type": "Location", 222 | "description": "The location of the call" 223 | } 224 | } 225 | }, 226 | "ProjectImport": { 227 | "id": "ProjectImport", 228 | "description": "A project import results", 229 | "required": [ 230 | "removedCompiledQueries", 231 | "created", 232 | "updated", 233 | "not-updated", 234 | "deleted", 235 | "kept", 236 | "root", 237 | "ignored" 238 | ], 239 | "properties": { 240 | "removedCompiledQueries": { 241 | "type": "array", 242 | "items": { 243 | "$ref": "string" 244 | }, 245 | "description": "The list of precompiled queries that have been removed" 246 | }, 247 | "created": { 248 | "type": "array", 249 | "items": { 250 | "$ref": "string" 251 | }, 252 | "description": "The list of files that existed only in the archive that have been created" 253 | }, 254 | "updated": { 255 | "type": "array", 256 | "items": { 257 | "$ref": "string" 258 | }, 259 | "description": "The list of files that existed both in the project and in the archive that have been updated" 260 | }, 261 | "not-updated": { 262 | "type": "array", 263 | "items": { 264 | "$ref": "string" 265 | }, 266 | "description": "The list of files that existed both in the project and in the archive that have not been updated" 267 | }, 268 | "deleted": { 269 | "type": "array", 270 | "items": { 271 | "$ref": "string" 272 | }, 273 | "description": "The list of files that existed only in the project that have been deleted" 274 | }, 275 | "kept": { 276 | "type": "array", 277 | "items": { 278 | "$ref": "string" 279 | }, 280 | "description": "The list of files that existed only in the project that have been kept" 281 | }, 282 | "root" : { 283 | "type": "string", 284 | "description": "The autodetected or specified path to the folder in which the queries and modules have been searched" 285 | }, 286 | "ignored": { 287 | "type": "array", 288 | "items": { 289 | "$ref": "string" 290 | }, 291 | "description": "The list of files in the archive that have been ignored. This happens if the file has an unsupported extension or is a system module" 292 | } 293 | } 294 | } 295 | } 296 | } -------------------------------------------------------------------------------- /tests/apis/_modules.json: -------------------------------------------------------------------------------- 1 | { 2 | "apiVersion": "1.0", 3 | "swaggerVersion": "1.2", 4 | "basePath": "http://portal.28.io/v1", 5 | "resourcePath": "/_modules", 6 | "produces": [ 7 | "application/json" 8 | ], 9 | "description": "These resources can be used to manage JSONiq and XQuery library modules. The endpoint of these resources is based on your project name. For instance, if your 28.io project is named myproject
, your endpoint for this API will be: http://myproject.28.io/v1/_modules
.
This API does not allow to retrieve the source code, modify or delete system modules.
", 10 | "apis": [ 11 | { 12 | "path": "/_modules", 13 | "description": "Module Listing", 14 | "operations": [ 15 | { 16 | "method": "GET", 17 | "summary": "Lists available modules", 18 | "nickname": "listModules", 19 | "notes": "This method retrieves the list of modules which can be imported by a project.
By default, only modules defined in the project will be listed. To also list system-provided modules, you can set the include-system
query parameter to true
.
To include module source codes, you can set the include-src
query parameter to true
. Regardless of the value of the include-src
parameter, the source code of system modules will not be returned.
To perform namespace analysis and report for each module whether it has a namespace, the evenutal namespace URI and whether the module can be imported without location hints, set the include-ns
query parameter to true
.
To filter the returned modules you can use the starts-with
query parameter. In this case, only the modules which path starts with the specified string will be returned.
If two or more module have the same namespace and thus the same path, the details of the module which would be imported by a query are shown.
", 20 | "type": "ModuleListing", 21 | "parameters": [ 22 | { 23 | "name": "starts-with", 24 | "description": "Filter the available module by their module path.", 25 | "required": false, 26 | "type": "string", 27 | "paramType": "query" 28 | }, 29 | { 30 | "name": "include-system", 31 | "description": "Include modules provided by the platform.", 32 | "required": false, 33 | "type": "boolean", 34 | "default": false, 35 | "paramType": "query" 36 | }, 37 | { 38 | "name": "include-ns", 39 | "description": "Include each module's namespace in the listing.", 40 | "required": false, 41 | "type": "boolean", 42 | "default": false, 43 | "paramType": "query" 44 | }, 45 | { 46 | "name": "include-src", 47 | "description": "Include each module's source code in the listing.", 48 | "required": false, 49 | "type": "boolean", 50 | "default": false, 51 | "paramType": "query" 52 | }, 53 | { 54 | "name": "token", 55 | "description": "A project token.", 56 | "required": true, 57 | "type": "string", 58 | "paramType": "query" 59 | } 60 | ], 61 | "responseMessages": [ 62 | { 63 | "code": 400, 64 | "message": "Bad request: a parameter is missing or invalid.", 65 | "responseModel": "Error" 66 | }, 67 | { 68 | "code": 403, 69 | "message": "Unauthorized: the specified project token is invalid or expired.", 70 | "responseModel": "Error" 71 | }, 72 | { 73 | "code": 500, 74 | "message": "An internal error occurred during the processing of the request.", 75 | "responseModel": "Error" 76 | } 77 | ], 78 | "successMessages": [ 79 | { 80 | "code": 200, 81 | "message": "Returns available module listing." 82 | } 83 | ], 84 | "examples": [ 85 | { 86 | "title": "Listing all project modules", 87 | "description": "The following request retrieves the list of all modules defined in the projectmyproject
.",
88 | "request": "curl -X GET \"http://myproject.28.io/v1/_modules?token=dGZKZ0VYT1VWV2l1R1BLQ1NBTjVmcEJlWU04PToyMDEzLTExLTA2VDAxOjU0OjI5LjgzOTQ1Wg==\"",
89 | "response": "< 200 OK\n{\"/io/myproject/module\": {\n \"system\": false,\n \"language\": \"jsoniq\",\n \"lastModified\": \"2013-12-16T15:41:15Z\"\n}}"
90 | }]
91 | }
92 | ]
93 | }
94 | ,
95 | {
96 | "path": "/_modules/{module-path}",
97 | "description": "Module Management",
98 | "operations": [
99 | {
100 | "method": "GET",
101 | "summary": "Retrieves the source code of the specified project module",
102 | "notes": "This method retrieves the source code of a project module. The response content type is set according to the query language of the module. If the query does not declare its own dialect or cannot be parsed, the query language is considered to be XQuery
.
This operation cannot be used to retrieve the source code of system modules.
", 103 | "type": "string", 104 | "produces": [ 105 | "text/x-jsoniq;charset=UTF-8", 106 | "text/x-xquery;charset=UTF-8" 107 | ], 108 | "nickname": "getModule", 109 | "parameters": [ 110 | { 111 | "name": "module-path", 112 | "description": "The module path.", 113 | "required": true, 114 | "type": "string", 115 | "paramType": "path" 116 | }, 117 | { 118 | "name": "token", 119 | "description": "A project token.", 120 | "required": true, 121 | "type": "string", 122 | "paramType": "query" 123 | } 124 | ], 125 | "responseMessages": [ 126 | { 127 | "code": 400, 128 | "message": "Bad request: a parameter is missing or invalid.", 129 | "responseModel": "Error" 130 | }, 131 | { 132 | "code": 403, 133 | "message": "Unauthorized: the specified project token is invalid or expired or the module path corresponds to a system module.", 134 | "responseModel": "Error" 135 | }, 136 | { 137 | "code": 404, 138 | "message": "The specified module cannot be found.", 139 | "responseModel": "Error" 140 | }, 141 | { 142 | "code": 500, 143 | "message": "An internal error occurred during the processing of the request.", 144 | "responseModel": "Error" 145 | } 146 | ], 147 | "successMessages": [ 148 | { 149 | "code": 200, 150 | "message": "Returns module source code." 151 | } 152 | ], 153 | "examples": [ 154 | { 155 | "title": "Retrieving a project module source code", 156 | "description": "The following request retrieves the source code of the \"/io/myproject/module\" module defined in themyproject
project.",
157 | "request": "curl -X GET \"http://myproject.28.io/v1/_modules/io/myproject/module?token=dGZKZ0VYT1VWV2l1R1BLQ1NBTjVmcEJlWU04PToyMDEzLTExLTA2VDAxOjU0OjI5LjgzOTQ1Wg==\"",
158 | "response": "< 200 OK\nmodule namespace m = \"http://myproject.io/module\"; declare function m:one() {1};"
159 | }
160 | ]
161 | },
162 | {
163 | "method": "POST",
164 | "summary": "Creates a new project module",
165 | "notes": "This method creates a new project module. If the compile
option is none
, the module will not be compiled, if it is lax
it will be compiled and any potential compilation error reported. In this case, compilation errors will not prevent the module to be created. To only create the module if no compilation errors are present, set the compile
option to strict
. The default is lax
.
It is not allowed to create a project module with the same path of an existing system or project module, even if the existing module has a different extension. If the operation succeeds any precompiled query depending on the updated module will be deleted.
", 166 | "type": "ModuleUpdate", 167 | "nickname": "createModule", 168 | "parameters": [ 169 | { 170 | "name": "module-path", 171 | "description": "The module path.", 172 | "required": true, 173 | "type": "string", 174 | "paramType": "path" 175 | }, 176 | { 177 | "name": "compile", 178 | "description": "The kind of compilation to perform. The default is \"lax\".", 179 | "required": false, 180 | "type": "string", 181 | "enum": [ 182 | "strict", 183 | "lax", 184 | "none" 185 | ], 186 | "paramType": "query" 187 | }, 188 | { 189 | "name": "extension", 190 | "description": "The new module extension. The default is \"jq\".", 191 | "required": false, 192 | "type": "string", 193 | "enum": [ 194 | "jq", 195 | "xq", 196 | "module" 197 | ], 198 | "paramType": "query" 199 | }, 200 | { 201 | "name": "token", 202 | "description": "A project token.", 203 | "required": true, 204 | "type": "string", 205 | "paramType": "query" 206 | }, 207 | { 208 | "name": "module-body", 209 | "description": "The source code of the module.", 210 | "required": false, 211 | "type": "string", 212 | "paramType": "body" 213 | }, 214 | { 215 | "name": "Content-Type", 216 | "paramType": "header", 217 | "enum": [ 218 | "text/plain; charset=utf-8" 219 | ], 220 | "type": "string" 221 | } 222 | 223 | ], 224 | "responseMessages": [ 225 | { 226 | "code": 400, 227 | "message": "Bad request: a parameter is missing or invalid.", 228 | "responseModel": "Error" 229 | }, 230 | { 231 | "code": 403, 232 | "message": "Unauthorized: the specified project token is invalid or expired or the module path corresponds to a system module.", 233 | "responseModel": "Error" 234 | }, 235 | { 236 | "code": 409, 237 | "message": "The specified module already exists.", 238 | "responseModel": "Error" 239 | }, 240 | { 241 | "code": 422, 242 | "message": "A compilation error occurred in strict mode.", 243 | "responseModel": "Error" 244 | }, 245 | { 246 | "code": 500, 247 | "message": "An internal error occurred during the processing of the request.", 248 | "responseModel": "Error" 249 | } 250 | ], 251 | "successMessages": [ 252 | { 253 | "code": 201, 254 | "message": "The module has been created." 255 | } 256 | ], 257 | "examples": [ 258 | { 259 | "title": "Creating a new module", 260 | "description": "The following request retrieves the source code of the \"/io/myproject/module\" module of themyproject
project.",
261 | "request": "curl -X POST -H \"Content-Type: text/plain\" -d \"module namespace m = \\\"http://myproject.io/module\\\"; declare function m:one() {1};\" \"http://myproject.28.io/v1/_modules/io/myproject/module?token=dGZKZ0VYT1VWV2l1R1BLQ1NBTjVmcEJlWU04PToyMDEzLTExLTA2VDAxOjU0OjI5LjgzOTQ1Wg==\"",
262 | "response": "< 201 Created"
263 | }
264 | ]
265 | },
266 | {
267 | "method": "PUT",
268 | "summary": "Creates or updates the specified project module",
269 | "notes": "This method creates or updates a project module. If the compile
option is none
, the module will not be compiled, if it is lax
it will be compiled and any potential compilation error reported. In this case, compilation errors will not prevent the module to be created or updated. To only create the module if no compilation errors are present, set the compile
option to strict
. The default is lax
.
It is not allowed to update system modules. If the operation succeeds all existing modules with the same path, even with different extensions, are removed. Moreover, all precompiled queries depending on the updated module will be become non precompiled.
", 270 | "type": "ModuleUpdate", 271 | "nickname": "saveModule", 272 | "parameters": [ 273 | { 274 | "name": "module-path", 275 | "description": "The module path.", 276 | "required": true, 277 | "type": "string", 278 | "paramType": "path" 279 | }, 280 | { 281 | "name": "compile", 282 | "description": "The kind of compilation to perform. The default is \"lax\".", 283 | "required": false, 284 | "type": "string", 285 | "enum": [ 286 | "strict", 287 | "lax", 288 | "none" 289 | ], 290 | "paramType": "query" 291 | }, 292 | { 293 | "name": "extension", 294 | "description": "The new module extension. The default is \"jq\".", 295 | "required": false, 296 | "type": "string", 297 | "enum": [ 298 | "jq", 299 | "xq", 300 | "module" 301 | ], 302 | "paramType": "query" 303 | }, 304 | { 305 | "name": "token", 306 | "description": "A project token.", 307 | "required": true, 308 | "type": "string", 309 | "paramType": "query" 310 | }, 311 | { 312 | "name": "module-body", 313 | "description": "The module source code", 314 | "required": false, 315 | "type": "string", 316 | "paramType": "body" 317 | }, 318 | { 319 | "name": "Content-Type", 320 | "type": "string", 321 | "paramType": "header", 322 | "enum": [ 323 | "text/plain; charset=utf-8" 324 | ] 325 | } 326 | 327 | ], 328 | "responseMessages": [ 329 | { 330 | "code": 400, 331 | "message": "Bad request: a parameter is missing or invalid.", 332 | "responseModel": "Error" 333 | }, 334 | { 335 | "code": 403, 336 | "message": "Unauthorized: the specified project token is invalid or expired or the module path corresponds to a system module.", 337 | "responseModel": "Error" 338 | }, 339 | { 340 | "code": 404, 341 | "message": "The specified module cannot be found.", 342 | "responseModel": "Error" 343 | }, 344 | { 345 | "code": 422, 346 | "message": "A compilation error occurred in strict mode.", 347 | "responseModel": "Error" 348 | }, 349 | { 350 | "code": 500, 351 | "message": "An internal error occurred during the processing of the request.", 352 | "responseModel": "Error" 353 | } 354 | ], 355 | "successMessages": [ 356 | { 357 | "code": 200, 358 | "message": "The module has been saved." 359 | } 360 | ], 361 | "examples": [ 362 | { 363 | "title": "Saving a module", 364 | "description": "The following request saves the \"/io/myproject/module\" module in themyproject
project.",
365 | "request": "curl -X POST -H \"Content-Type: text/plain\" -d \"module namespace m = \\\"http://myproject.io/module\\\"; declare function m:one() {1};\" \"http://myproject.28.io/_modules/io/myproject/module?token=dGZKZ0VYT1VWV2l1R1BLQ1NBTjVmcEJlWU04PToyMDEzLTExLTA2VDAxOjU0OjI5LjgzOTQ1Wg==\"",
366 | "response": "< 201 Created"
367 | }]
368 | },
369 | {
370 | "method": "DELETE",
371 | "summary": "Removes the specified project module",
372 | "notes": "This method removes the specified project module. If the operation succeeds any precompiled query depending on the updated module will be deleted.
", 373 | "type": "ModuleDelete", 374 | "nickname": "removeModule", 375 | "parameters": [ 376 | { 377 | "name": "module-path", 378 | "description": "The module path.", 379 | "required": true, 380 | "type": "string", 381 | "paramType": "path" 382 | }, 383 | { 384 | "name": "token", 385 | "description": "A project token.", 386 | "required": true, 387 | "type": "string", 388 | "paramType": "query" 389 | } 390 | ], 391 | "responseMessages": [ 392 | { 393 | "code": 400, 394 | "message": "Bad request: a parameter is missing or invalid.", 395 | "responseModel": "Error" 396 | }, 397 | { 398 | "code": 403, 399 | "message": "Unauthorized: the specified project token is invalid or expired or the module path corresponds to a system module.", 400 | "responseModel": "Error" 401 | }, 402 | { 403 | "code": 404, 404 | "message": "The specified module cannot be found.", 405 | "responseModel": "Error" 406 | }, 407 | { 408 | "code": 500, 409 | "message": "An internal error occurred during the processing of the request.", 410 | "responseModel": "Error" 411 | } 412 | ], 413 | "successMessages": [ 414 | { 415 | "code": 200, 416 | "message": "The module has been deleted." 417 | } 418 | ], 419 | "examples": [ 420 | { 421 | "title": "Deleting a module", 422 | "description": "The following request deletes the \"/io/myproject/module\" module from themyproject
project.",
423 | "request": "curl -X DELETE \"http://myproject.28.io/v1/_modules/io/myproject/module?token=dGZKZ0VYT1VWV2l1R1BLQ1NBTjVmcEJlWU04PToyMDEzLTExLTA2VDAxOjU0OjI5LjgzOTQ1Wg==\"",
424 | "response": "< 200 OK"
425 | }
426 | ]
427 | }
428 | ]
429 | }
430 | ],
431 | "models": {
432 | "ModuleListing": {
433 | "id": "ModuleListing",
434 | "description": "A list of modules",
435 | "required": [],
436 | "properties": {
437 | "modulePath": {
438 | "type": "Module",
439 | "description": "A different field is present for each listed module. The name of the field is the module path"
440 | }
441 | }
442 | },
443 | "Module": {
444 | "id": "Module",
445 | "description": "Module metadata",
446 | "required": [
447 | "system"
448 | ],
449 | "properties": {
450 | "system": {
451 | "type": "boolean",
452 | "description": "Whether the module is provided by the system or defined in the project"
453 | },
454 | "language": {
455 | "type": "string",
456 | "enum": [
457 | "jsoniq",
458 | "xquery"
459 | ],
460 | "description": "The module language. This field is only present for non-system modules. If no language definition is contained in the module, \"xquery\" is assumed"
461 | },
462 | "extension": {
463 | "type": "string",
464 | "enum": [
465 | "jq",
466 | "xq",
467 | "module"
468 | ],
469 | "description": "The module extension. This field is only present for non-system modules."
470 | },
471 | "lastModified": {
472 | "type": "date-time",
473 | "description": "The date and time the module was last modified. This field is only present for non-system modules"
474 | },
475 | "hasNamespace": {
476 | "type": "boolean",
477 | "description": "Whether the module can be parsed without errors and contains a namespace declaration. This field is only present if the \"include-ns\" parameter has been set to true in the request"
478 | },
479 | "namespace": {
480 | "type": "string",
481 | "description": "The module namespace, provided that the module can be parsed without errors and contains a namespace declaration. This field is only present if the \"include-ns\" parameter has been set to true in the request"
482 | },
483 | "autoResolution": {
484 | "type": "boolean",
485 | "description": "Whether the module can be imported without location hints. This field is only present if the \"include-ns\" parameter has been set to true in the request"
486 | },
487 | "source": {
488 | "type": "string",
489 | "description": "The module source code. This field is only present for non-system modules and if the \"include-src\" parameter has been set to true in the request"
490 | }
491 | }
492 | },
493 | "ModuleUpdate": {
494 | "id": "ModuleUpdate",
495 | "description": "The result of the module compilation",
496 | "required": [
497 | "success",
498 | "autoResolution",
499 | "removedCompiledQueries"
500 | ],
501 | "properties": {
502 | "success": {
503 | "type": "boolean",
504 | "enum": [
505 | "true"
506 | ]
507 | },
508 | "request_id": {
509 | "type": "string",
510 | "description": "The request identifier. Present only if the compilation fails"
511 | },
512 | "autoResolution": {
513 | "type": "boolean",
514 | "description": "Whether the module can be imported without location hints"
515 | },
516 | "compilationError" : {
517 | "type": "CompilationError",
518 | "description": "The compilation error occurred during the module compilation, if any"
519 | },
520 | "removedCompiledQueries" : {
521 | "type": "array",
522 | "items": { "$ref": "string" },
523 | "description": "The list of compiled queries which have been removed"
524 | }
525 | }
526 | },
527 | "ModuleDelete": {
528 | "id": "ModuleDelete",
529 | "description": "The result of the module compilation",
530 | "required": [
531 | "success"
532 | ],
533 | "properties": {
534 | "success": {
535 | "type": "boolean",
536 | "enum": [
537 | "true"
538 | ]
539 | },
540 | "removedCompiledQueries" : {
541 | "type": "array",
542 | "items": { "$ref": "string" },
543 | "description": "The list of compiled queries which have been removed"
544 | }
545 | }
546 | },
547 | "CompilationError": {
548 | "id": "CompilationError",
549 | "description": "Compilation error information",
550 | "required": [
551 | "context",
552 | "message",
553 | "description"
554 | ],
555 | "properties": {
556 | "context": {
557 | "type": "string",
558 | "description": "The complete domain name of the project"
559 | },
560 | "message": {
561 | "type": "string",
562 | "description": "A formatted string which contain the error code (always) and the module name, line and column-number and error description (when available)"
563 | },
564 | "type": {
565 | "type": "string",
566 | "description": "For XQuery errors, the type of the error (e.g. static)"
567 | },
568 | "code": {
569 | "type": "string",
570 | "description": "For XQuery errors, the error code"
571 | },
572 | "location": {
573 | "type": "Location",
574 | "description": "For XQuery errors, the error location (if available)"
575 | }
576 | }
577 | },
578 | "Success": {
579 | "id": "Success",
580 | "description": "Default success response",
581 | "required": [
582 | "success"
583 | ],
584 | "properties": {
585 | "success": {
586 | "type": "boolean",
587 | "enum": [
588 | "true"
589 | ]
590 | }
591 | }
592 | },
593 | "Error": {
594 | "id": "Error",
595 | "description": "Error information",
596 | "required": [
597 | "request_id",
598 | "context",
599 | "message",
600 | "description"
601 | ],
602 | "properties": {
603 | "request_id": {
604 | "type": "string",
605 | "description": "The request identifier"
606 | },
607 | "context": {
608 | "type": "string",
609 | "description": "The complete domain name of the project"
610 | },
611 | "message": {
612 | "type": "string",
613 | "description": "A formatted string which contain the error code (always) and the module name, line and column-number and error description (when available)"
614 | },
615 | "type": {
616 | "type": "string",
617 | "description": "For XQuery errors, the type of the error (e.g. static)"
618 | },
619 | "code": {
620 | "type": "string",
621 | "description": "For XQuery errors, the error code"
622 | },
623 | "location": {
624 | "type": "Location",
625 | "description": "For XQuery errors, the error location (if available)"
626 | },
627 | "stack-trace": {
628 | "type": "array",
629 | "items": {
630 | "$ref": "StackEntry"
631 | },
632 | "description": "For XQuery errors, the error stack trace (if available)"
633 | }
634 | }
635 | },
636 | "Location": {
637 | "id": "Location",
638 | "description": "Error information",
639 | "required": [
640 | "module",
641 | "line-number",
642 | "line-number-end",
643 | "column-number",
644 | "column-number-end"
645 | ],
646 | "properties": {
647 | "module": {
648 | "type": "string",
649 | "description": "The error module"
650 | },
651 | "line-number": {
652 | "type": "string",
653 | "description": "The error first line number"
654 | },
655 | "line-number-end": {
656 | "type": "string",
657 | "description": "The error last line number"
658 | },
659 | "column-number": {
660 | "type": "string",
661 | "description": "The error first column number"
662 | },
663 | "column-number-end": {
664 | "type": "string",
665 | "description": "The error last column number"
666 | }
667 | }
668 | },
669 | "StackEntry": {
670 | "id": "StackEntry",
671 | "description": "A stack entry",
672 | "required": [
673 | "function",
674 | "location"
675 | ],
676 | "properties": {
677 | "function": {
678 | "type": "Function",
679 | "description": "The function of the call"
680 | },
681 | "type": {
682 | "type": "Location",
683 | "description": "The location of the call"
684 | }
685 | }
686 | }
687 | }
688 | }
689 |
--------------------------------------------------------------------------------
/tests/apis/auth.json:
--------------------------------------------------------------------------------
1 | {
2 | "apiVersion": "1.0",
3 | "swaggerVersion": "1.2",
4 | "basePath": "http://portal.28.io",
5 | "resourcePath": "/auth",
6 | "produces": ["application/json"],
7 | "description": "This OAuth2 compliant API can be used to authorize requests. The endpoint for these methods is http://portal.28.io/auth
.
This OAuth2 compliant endpoint can be used both create new authorization tokens or to refresh an existing ones. There are three types of authorization tokens provided by this endpoint.
myproject
can be used to authorize any request to the http://myproject.28.io
endpoint.Any successful request to this endpoint will return the access, refresh, and project tokens.
To create new authorization tokens, the grant_type
parameter must be set to client_credentials
and the email
. The password
parameters must be specified as well.
To refresh the validity of your authorized tokens, the grant_type
parameter must be set to refresh_token
and the refresh_token
parameter must be specified. In this scenario, new authorization tokens will be granted.
The format of the expiration date of a token is ISO 8601 compliant.
", 16 | "type": "Authentication", 17 | "nickname": "authenticate", 18 | "parameters": [ 19 | { 20 | "name": "grant_type", 21 | "description": "Authorization grant type. Useclient_credentials
to create a token or refresh_token
to refresh a token",
22 | "required": true,
23 | "type": "string",
24 | "enum": ["client_credentials", "refresh_token"],
25 | "paramType": "query"
26 | },
27 | {
28 | "name": "email",
29 | "description": "The account email. Mandatory if grant_type=client_credentials
.",
30 | "required": false,
31 | "type": "string",
32 | "paramType": "query"
33 | },
34 | {
35 | "name": "password",
36 | "description": "The account password. Mandatory if grant_type=client_credentials
.",
37 | "required": false,
38 | "type": "string",
39 | "paramType": "query"
40 | },
41 | {
42 | "name": "refresh_token",
43 | "description": "The refresh_token
obtained in the last successful request to this endpoint. Mandatory if grant_type=refresh_token
.",
44 | "required": false,
45 | "type": "string",
46 | "paramType": "query"
47 | }
48 | ],
49 | "successMessages": [
50 | {
51 | "code": 200,
52 | "message": "New authorization tokens have been granted.",
53 | "responseModel": "Authentication"
54 | }
55 | ],
56 | "responseMessages": [
57 | {
58 | "code": 400,
59 | "message": "Bad request: a parameter is missing or invalid.",
60 | "responseModel": "Error"
61 | },
62 | {
63 | "code": 403,
64 | "message": "The specified password or refresh token is invalid.",
65 | "responseModel": "Error"
66 | },
67 | {
68 | "code": 409,
69 | "message": "The specified user has not been confirmed.",
70 | "responseModel": "Error"
71 | },
72 | {
73 | "code": 404,
74 | "message": "The specified account cannot be found.",
75 | "responseModel": "Error"
76 | },
77 | {
78 | "code": 500,
79 | "message": "An internal error occurred during the processing of the request.",
80 | "responseModel": "Error"
81 | }
82 | ],
83 | "examples": [
84 | {
85 | "title": "Granting a new authorization token",
86 | "description": "The following request creates a new authorization token.",
87 | "request": "curl -X POST http://portal.28.io/auth?email=my@email.com&password=mypassword&grant_type=client_credentials",
88 | "response": "< 200 OK\n{\n \"token_type\" : \"bearer\",\n \"expiration_date\" : \"2013-11-06T01:54:29.83945Z\",\n \"access_token\" : \"dGZKZ0VYT1VWV2l1R1BLQ1NBTjVmcEJlWU04PToyMDEzLTExLTA2VDAxOjU0OjI5LjgzOTQ1Wg==\",\n \"refresh_token\" : \"dGZKZ0VYT1VWV2l1R1BLQ1NBTjVmcEJlWU04PToyMDEzLTExLTA2VDAxOjU0OjI5LjgzOTQ1Wg==\",\n \"project_tokens\" : {\n \"project_zurich\" : \"QllXcXM3OHV4N2IweitabGZKeExkZVBreGZJPToyMDEzLTExLTA2VDAxOjU0OjI5LjgzOTQ1Wg==\" },\n \"accountMetadata\" : {\n \"id\" : \"1\",\n \"email\" : \"my@email.com\",\n \"firstname\" : \"John\",\n \"lastname\" : \"Smith\",\n \"company\" : \"Acme\",\n \"createdAt\" : \"2013-10-31T15:26:12.702226Z\",\n \"type\" : \"free\",\n \"confirmedAt\" : \"2013-10-31T15:26:31.081456Z\"\n },\n \"projectsMetadata\" : [{\n \"name\" : \"zurich\",\n \"created\" : \"2013-10-31T15:59:55.117077Z\",\n \"package\" : \"free\",\n \"status\" : \"active\",\n \"avatarKey\" : 8,\n \"version\" : \"1.0\",\n \"sausaVesion\" : \"2.8.0\",\n \"lastUpdated\" : \"2013-10-31T15:59:55.117077Z\",\n \"lastModified\" : \"2013-10-31T15:59:55.117077Z\",\n \"databaseType\" : \"28msec\"\n }]\n}"
89 | }
90 | ,
91 | {
92 | "title": "Refreshing an authorization token",
93 | "description": "The following request refreshes the validity of an authorization token.",
94 | "request": "curl -X POST http://portal.28.io/auth?refresh_token=dGZKZ0VYT1VWV2l1R1BLQ1NBTjVmcEJlWU04PToyMDEzLTExLTA2VDAxOjU0OjI5LjgzOTQ1Wg==&grant_type=refresh_token",
95 | "response": "< 200 OK\n{\n \"token_type\" : \"bearer\",\n \"expiration_date\" : \"2013-11-06T02:17:50.769451Z\",\n \"access_token\" : \"ejRISUlaY2FFNUs2dGZOQ0FrTnRRY2hRVkNnPToyMDEzLTExLTA2VDAyOjE3OjUwLjc2OTQ1MVo=\",\n \"refresh_token\" : \"ejRISUlaY2FFNUs2dGZOQ0FrTnRRY2hRVkNnPToyMDEzLTExLTA2VDAyOjE3OjUwLjc2OTQ1MVo=\",\n \"project_tokens\" : {\n \"project_zurich\" : \"aUhxKzRJRU1VbHhwWS9OWGNsS2lDdXpKVXNrPToyMDEzLTExLTA2VDAyOjE3OjUwLjc2OTQ1MVo=\"\n }\n}"
96 | }
97 | ]
98 | }
99 | ]
100 | }
101 | ],
102 | "models": {
103 | "Error": {
104 | "id": "Error",
105 | "description": "Error information",
106 | "required": [
107 | "code",
108 | "message"
109 | ],
110 | "properties": {
111 | "code": {
112 | "type": "string",
113 | "description": "The XQuery error code of the error"
114 | },
115 | "message": {
116 | "type": "string",
117 | "description": "A formatted string which contain the error code (always) and the module name, line and column-number and error description (when available)"
118 | },
119 | "description": {
120 | "type": "string",
121 | "description": "The error description"
122 | },
123 | "module": {
124 | "type": "string",
125 | "description": "The error module"
126 | },
127 | "line-number": {
128 | "type": "string",
129 | "description": "The error line number"
130 | },
131 | "column-number": {
132 | "type": "string",
133 | "description": "The error column number"
134 | }
135 | }
136 | },
137 | "Authentication": {
138 | "id": "Authentication",
139 | "description": "Authentication data",
140 | "required": [
141 | "token_type",
142 | "expiration_date",
143 | "access_token",
144 | "refresh_token",
145 | "project_tokens"
146 | ],
147 | "properties": {
148 | "token_type": {
149 | "type": "string",
150 | "description": "The API token type",
151 | "enum": [
152 | "bearer"
153 | ]
154 | },
155 | "expiration_date": {
156 | "type": "date-time",
157 | "description": "The expiration date of all the tokens in the response"
158 | },
159 | "access_token": {
160 | "type": "string",
161 | "description": "The API token"
162 | },
163 | "refresh_token": {
164 | "type": "string",
165 | "description": "The refresh token which can be used to refresh both the API and project tokens"
166 | },
167 | "project_tokens": {
168 | "type": "ProjectTokens",
169 | "description": "The project tokens which can be used to make request to the APIs on the project endpoints"
170 | }
171 | }
172 | },
173 | "ProjectTokens": {
174 | "id": "ProjectTokens",
175 | "description": "An object containing zero or more project tokens. Each project token is stored in a different field project_{name}, where {name} is the project name, (e.g.: portal).",
176 | "properties": {
177 | "project_{name}": {
178 | "type": "string",
179 | "description": "The token for the project {name}. One field for each project owned by the account will be present"
180 | }
181 | }
182 | }
183 | }
184 | }
185 |
--------------------------------------------------------------------------------
/tests/apis/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "apiVersion": "1.0",
3 | "swaggerVersion": "1.2",
4 | "basePath": "http://api.xbrl.io",
5 | "resourcePath": "/packages",
6 | "produces": [
7 | "application/json"
8 | ],
9 | "apis": [
10 | {
11 | "path": "/package",
12 | "operations": [
13 | {
14 | "method": "GET",
15 | "summary": "Lists available packages",
16 | "notes": "This method requires no authentication.",
17 | "type": "array",
18 | "items": {
19 | "$ref": "Package"
20 | },
21 | "nickname": "listPackages",
22 | "parameters": [],
23 | "responseMessages": [
24 | {
25 | "code": 500,
26 | "message": "An internal error occurred during the processing of the request.",
27 | "responseModel": "Error"
28 | }
29 | ]
30 | }
31 | ]
32 | }
33 | ],
34 | "models": {
35 | "Error": {
36 | "id": "Error",
37 | "description": "Error information",
38 | "required": [
39 | "code",
40 | "message",
41 | "description"
42 | ],
43 | "properties": {
44 | "code": {
45 | "type": "string",
46 | "description": "The XQuery error code of the error"
47 | },
48 | "message": {
49 | "type": "string",
50 | "description": "A formatted string which contain the error code (always) and the module name, line and column-number and error description (when available)"
51 | },
52 | "description": {
53 | "type": "string",
54 | "description": "The error description"
55 | },
56 | "module": {
57 | "type": "string",
58 | "description": "The error module"
59 | },
60 | "line-number": {
61 | "type": "string",
62 | "description": "The error line number"
63 | },
64 | "column-number": {
65 | "type": "string",
66 | "description": "The error column number"
67 | }
68 | }
69 | },
70 | "Package": {
71 | "id": "Package",
72 | "description": "A package",
73 | "required": [
74 | "id",
75 | "name",
76 | "demo",
77 | "description"
78 | ],
79 | "properties": {
80 | "id": {
81 | "type": "string",
82 | "description": "The package id"
83 | },
84 | "name": {
85 | "type": "string",
86 | "description": "The package name"
87 | },
88 | "demo": {
89 | "type": "boolean",
90 | "description": "Whether the package is a demo package or not"
91 | },
92 | "description": {
93 | "type": "string",
94 | "description": "The package description"
95 | },
96 | "price": {
97 | "type": "string",
98 | "description": "The package price"
99 | },
100 | "details" : {
101 | "type": "object",
102 | "description": "The package details"
103 | }
104 | }
105 | }
106 | }
107 | }
--------------------------------------------------------------------------------
/tests/apis/ping.json:
--------------------------------------------------------------------------------
1 | {
2 | "apiVersion": "1.0",
3 | "swaggerVersion": "1.2",
4 | "basePath": "http://api.xbrl.io",
5 | "resourcePath": "/ping",
6 | "produces": ["application/json"],
7 | "apis": [
8 | {
9 | "path": "/ping",
10 | "operations":[
11 | {
12 | "method": "GET",
13 | "summary": "Checks if the service is available.",
14 | "type": "Success",
15 | "nickname": "ping"
16 | }
17 | ]
18 | }
19 | ],
20 | "models": {
21 | "Success": {
22 | "id": "Success",
23 | "description": "Default success response",
24 | "required": ["success"],
25 | "properties": {
26 | "success": {
27 | "type": "boolean",
28 | "enum": [
29 | "true"
30 | ]
31 | }
32 | }
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/tests/apis/protected.json:
--------------------------------------------------------------------------------
1 | {
2 | "swagger": "2.0",
3 | "info": {
4 | "version": "0.0.1",
5 | "title": "title"
6 | },
7 | "host": "portal.28.io",
8 | "basePath": "/api",
9 | "schemes": [
10 | "http"
11 | ],
12 | "securityDefinitions": {
13 | "oauth2": {
14 | "type": "oauth2",
15 | "scopes": {},
16 | "flow": "password",
17 | "tokenUrl": ""
18 | }
19 | },
20 | "paths": {
21 | "/auth": {
22 | "post": {
23 | "description": "Get token",
24 | "operationId": "auth",
25 | "parameters": [
26 | {
27 | "name": "grant_type",
28 | "description": "Authorization grant type. Use client_credentials
to create a token or refresh_token
to refresh a token",
29 | "required": true,
30 | "type": "string",
31 | "enum": ["client_credentials", "refresh_token"],
32 | "in": "query"
33 | },
34 | {
35 | "name": "email",
36 | "description": "The account email. Mandatory if grant_type=client_credentials
.",
37 | "required": false,
38 | "type": "string",
39 | "in": "query"
40 | },
41 | {
42 | "name": "password",
43 | "description": "The account password. Mandatory if grant_type=client_credentials
.",
44 | "required": false,
45 | "type": "string",
46 | "in": "query"
47 | },
48 | {
49 | "name": "refresh_token",
50 | "description": "The refresh_token
obtained in the last successful request to this endpoint. Mandatory if grant_type=refresh_token
.",
51 | "required": false,
52 | "type": "string",
53 | "in": "query"
54 | }
55 | ],
56 | "responses": {
57 | "200": {
58 | "description": "Token",
59 | "schema": {
60 | "$ref": "#/definitions/Authentication"
61 | }
62 | },
63 | "security": [
64 | {
65 | "oauth2": []
66 | }
67 | ],
68 | "401": {
69 | "description": "Unauthorized",
70 | "schema": {
71 | "$ref": "#/definitions/Error"
72 | }
73 | },
74 | "default": {
75 | "description": "Error",
76 | "schema": {
77 | "$ref": "#/definitions/Error"
78 | }
79 | }
80 | }
81 | }
82 | },
83 | "/project": {
84 | "get": {
85 | "description": "Get secure",
86 | "operationId": "getSecure",
87 | "parameters": [
88 | {
89 | "name": "token",
90 | "description": "Auth token",
91 | "required": false,
92 | "type": "string",
93 | "in": "query"
94 | }
95 | ],
96 | "security": [
97 | {
98 | "oauth2": []
99 | }
100 | ],
101 | "responses": {
102 | "200": {
103 | "description": "Secure response returned"
104 | },
105 | "401": {
106 | "description": "Unauthorized"
107 | }
108 | }
109 | }
110 | }
111 | },
112 | "definitions": {
113 | "Authentication": {
114 | "required": [
115 | "token_type",
116 | "expiration_date",
117 | "access_token",
118 | "refresh_token",
119 | "project_tokens"
120 | ],
121 | "properties": {
122 | "token_type": {
123 | "type": "string",
124 | "description": "The API token type",
125 | "enum": [
126 | "bearer"
127 | ]
128 | },
129 | "expiration_date": {
130 | "type": "date-time",
131 | "description": "The expiration date of all the tokens in the response"
132 | },
133 | "access_token": {
134 | "type": "string",
135 | "description": "The API token"
136 | },
137 | "refresh_token": {
138 | "type": "string",
139 | "description": "The refresh token which can be used to refresh both the API and project tokens"
140 | },
141 | "project_tokens": {
142 | "type": "ProjectTokens",
143 | "description": "The project tokens which can be used to make request to the APIs on the project endpoints"
144 | }
145 | }
146 | },
147 | "Error": {
148 | "required": [
149 | "code",
150 | "message"
151 | ],
152 | "properties": {
153 | "code": {
154 | "type": "string",
155 | "description": "The XQuery error code of the error"
156 | },
157 | "message": {
158 | "type": "string",
159 | "description": "A formatted string which contain the error code (always) and the module name, line and column-number and error description (when available)"
160 | },
161 | "description": {
162 | "type": "string",
163 | "description": "The error description"
164 | },
165 | "module": {
166 | "type": "string",
167 | "description": "The error module"
168 | },
169 | "line-number": {
170 | "type": "string",
171 | "description": "The error line number"
172 | },
173 | "column-number": {
174 | "type": "string",
175 | "description": "The error column number"
176 | }
177 | }
178 | }
179 | }
180 | }
181 |
--------------------------------------------------------------------------------
/tests/apis/ref.json:
--------------------------------------------------------------------------------
1 | {
2 | "swagger": "2.0",
3 | "info": {
4 | "version": "0.0.0",
5 | "title": "