diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 4876b92f..00000000 --- a/.eslintrc +++ /dev/null @@ -1,32 +0,0 @@ -{ - "parser": "babel-eslint", - "extends": "eslint:recommended", - "env": { - "browser": true, - "jasmine": true - }, - // currently eslint doesn't support extension-typed configs - "globals": { - "should": true, - "expect": true, - "sinon": true, - "Reflect": true - }, - "rules": { - "quotes": [2, "single"], - "no-console": 0, - "comma-spacing": 2, - "comma-style": [2, "last"], - "consistent-return": 2, - "strict": [2, "global"], - "eqeqeq": [2, "smart"], - "curly": [2, "multi-line"], - "semi-spacing": [2, {"before": false, "after": true}], - "semi": [2, "always"], - "no-extra-semi": 2, - "comma-dangle": [2, "never"], - "no-sequences": 2, - "comma-spacing": [2, {"before": false, "after": true}], - "comma-style": [2, "last"] - } -} diff --git a/README.md b/README.md index a4c4908a..5db3d241 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # ReDoc -[![Build Status](https://travis-ci.org/Rebilly/ReDoc.svg?branch=master)](https://travis-ci.org/Rebilly/ReDoc) [![Coverage Status](https://coveralls.io/repos/Rebilly/ReDoc/badge.svg?branch=master&service=github)](https://coveralls.io/github/Rebilly/ReDoc?branch=master) [![Tested on APIs.guru](http://apis-guru.github.io/api-models/banners/tested_on_banner.svg)](https://github.com/APIs-guru/api-models) [![Code Climate](https://codeclimate.com/github/Rebilly/ReDoc/badges/gpa.svg)](https://codeclimate.com/github/Rebilly/ReDoc) [![David](https://david-dm.org/Rebilly/ReDoc/dev-status.svg)](https://david-dm.org/Rebilly/ReDoc#info=devDependencies) [![Stories in Ready](https://badge.waffle.io/Rebilly/ReDoc.png?label=ready&title=Ready)](https://waffle.io/Rebilly/ReDoc) +[![Build Status](https://travis-ci.org/Rebilly/ReDoc.svg?branch=master)](https://travis-ci.org/Rebilly/ReDoc) [![Coverage Status](https://coveralls.io/repos/Rebilly/ReDoc/badge.svg?branch=master&service=github)](https://coveralls.io/github/Rebilly/ReDoc?branch=master) [![Tested on APIs.guru](http://api.apis.guru/badges/tested_on.svg)](https://APIs.guru) [![Code Climate](https://codeclimate.com/github/Rebilly/ReDoc/badges/gpa.svg)](https://codeclimate.com/github/Rebilly/ReDoc) [![David](https://david-dm.org/Rebilly/ReDoc/dev-status.svg)](https://david-dm.org/Rebilly/ReDoc#info=devDependencies) [![Stories in Ready](https://badge.waffle.io/Rebilly/ReDoc.png?label=ready&title=Ready)](https://waffle.io/Rebilly/ReDoc) [![npm](http://img.shields.io/npm/v/redoc.svg)](https://www.npmjs.com/package/redoc) [![Bower](http://img.shields.io/bower/v/redoc.svg)](http://bower.io/) [![License](https://img.shields.io/npm/l/redoc.svg)](https://github.com/Rebilly/ReDoc/blob/master/LICENSE) diff --git a/build/paths.js b/build/paths.js index 988f2cc8..63a59b59 100644 --- a/build/paths.js +++ b/build/paths.js @@ -1,7 +1,7 @@ var path = require('path'); var paths = { - source: 'lib/**/*.js', + source: 'lib/**/*.ts', html: 'lib/**/*.html', scss: 'lib/**/*.scss', sourceEntryPoint: 'lib/index.js', @@ -9,7 +9,7 @@ var paths = { output: 'dist/', tmp: '.tmp/', demo: 'demo/**/*', - tests: '{lib,tests}/**/*.spec.js', + tests: '{lib,tests}/**/*.spec.ts', releases: 'demo/releases/' } diff --git a/build/tasks/build.js b/build/tasks/build.js index 3ab8725c..b51a3e35 100644 --- a/build/tasks/build.js +++ b/build/tasks/build.js @@ -13,6 +13,8 @@ var replace = require('gulp-replace'); var rename = require('gulp-rename'); var argv = require('yargs').argv; var gulpIf = require('gulp-if'); +var sassCopm = require('node-sass'); +var ts = require('typescript'); gulp.task('build', function (callback) { if (argv.skipRebuild) { @@ -21,7 +23,8 @@ gulp.task('build', function (callback) { } return runSequence( 'clean', - 'concatPrism', + 'tsc', + 'inlineTemplates', 'bundle', 'concatDeps', 'copyDebug', @@ -38,19 +41,73 @@ gulp.task('copyDebug', () => { gulp.task('rebuild', function(done) { return runSequence( + 'inlineTemplates', 'bundle', 'concatDeps', + 'copyDebug', done ); }); -gulp.task('inlineTemplates', ['sass'], function() { - return gulp.src(paths.source, { base: './' }) - .pipe(replace(/'(.*?\.css)'/g, '\'.tmp/$1\'')) - .pipe(inlineNg2Template({ base: '/' })) +gulp.task('tsc', function() { + exec('tsc -p ./tsconfig.json'); +}); + + +// function compileTs(files, es5) { +// var tsProject = ts.createProject('tsconfig.json'); +// var allFiles = [].concat(files, ['typings/**/*.d.ts']); +// var res = gulp.src(allFiles, { +// base: config.src, +// outDir: config.tmp +// }) +// .pipe(tslint()) +// .pipe(tslint.report('prose', { +// summarizeFailureOutput: true, +// emitError: !watchMode +// })) +// .pipe(sourcemaps.init()) +// .pipe(ts(tsProject)) +// .on('error', function () { +// if (watchMode) { +// return; +// } +// process.exit(1); +// }); +// return res.js +// .pipe(sourcemaps.write('.', { +// includeContent: inline +// })) +// .pipe(gulp.dest(config.tmp)); +// } + +gulp.task('inlineTemplates', ['tsc', 'sass'], function() { + return gulp.src('.tmp/**/*.js', { base: './tmp' }) + .pipe(replace(/'(.*?)\.css'/g, '\'$1.scss\'')) + .pipe(inlineNg2Template({ + base: './', + useRelativePaths: true, + styleProcessor: compileSass, + customFilePath: function(ext, file) { + var cwd = process.cwd(); + var relative = path.relative(cwd, file); + relative = relative.substring('5'); + return path.join(cwd, relative); + } + })) .pipe(gulp.dest(paths.tmp)); }); +function compileSass(ext, file) { + file = file.replace('../../shared/styles/variables', 'lib/shared/styles/variables'); + file = file.replace('json-schema-common', 'lib/components/JsonSchema/json-schema-common'); + file = file.replace('../../shared/styles/share-link', 'lib/shared/styles/share-link'); + file = file.replace('../JsonSchema/lib/components/JsonSchema/json-schema-common', 'lib/components/JsonSchema/json-schema-common'); + file = file.replace('../../styles/variables', 'lib/shared/styles/variables'); + + return sassCopm.renderSync({data: file}).css; +} + var JS_DEPS = argv.prod ? [ 'lib/utils/browser-update.js', 'node_modules/zone.js/dist/zone.min.js', @@ -59,7 +116,7 @@ var JS_DEPS = argv.prod ? [ ]: [ 'lib/utils/browser-update.js', 'node_modules/zone.js/dist/zone.js', - 'node_modules/zone.js/dist/long-stack-trace-zone.js', + //'node_modules/zone.js/dist/long-stack-trace-zone.js', 'node_modules/reflect-metadata/Reflect.js', 'node_modules/babel-polyfill/dist/polyfill.js' ]; @@ -73,16 +130,17 @@ gulp.task('sass', function () { }); // concatenate angular2 deps -gulp.task('concatDeps', function() { - return gulp.src(JS_DEPS.concat([outputFileName])) +gulp.task('concatDeps', ['concatPrism'], function() { + return gulp.src(JS_DEPS.concat([path.join(paths.tmp, 'prismjs-bundle.js'), outputFileName])) .pipe(gulpIf(!argv.prod, sourcemaps.init({loadMaps: true}))) .pipe(concat(outputFileName)) .pipe(gulpIf(!argv.prod, sourcemaps.write('.'))) .pipe(gulp.dest('.')) }); -gulp.task('bundle', ['injectVersionFile', 'inlineTemplates'], function bundle(done) { - fs.existsSync('dist') || fs.mkdirSync('dist'); +gulp.task('bundle', function bundle(done) { + mkdir('-p', 'dist'); + cp('lib/index.js', path.join(paths.tmp, paths.sourceEntryPoint)); var builder = new Builder('./', 'system.config.js'); builder @@ -126,7 +184,7 @@ gulp.task('concatPrism', function() { return gulp.src(prismFiles) .pipe(concat(path.join(paths.tmp, 'prismjs-bundle.js'))) - .pipe(gulp.dest('.')) + .pipe(gulp.dest('.')); }); // needs inlineTemplates run before to create .tmp/lib folder diff --git a/build/tasks/lint.js b/build/tasks/lint.js index 63559646..526dc523 100644 --- a/build/tasks/lint.js +++ b/build/tasks/lint.js @@ -1,10 +1,15 @@ var gulp = require('gulp'); -var eslint = require('gulp-eslint'); +var tslint = require('gulp-tslint'); var paths = require('../paths'); gulp.task('lint', function () { return gulp.src([paths.source, paths.tests]) - .pipe(eslint()) - .pipe(eslint.format()) - .pipe(eslint.failAfterError()); + .pipe(tslint({ + rulesDirectory: 'node_modules/codelyzer' + })) + .pipe(tslint.report(require('tslint-stylish'), { + emitError: true, + sort: true, + bell: true + })); }); diff --git a/build/tasks/test.js b/build/tasks/test.js index 444b2307..58270bb3 100644 --- a/build/tasks/test.js +++ b/build/tasks/test.js @@ -1,6 +1,7 @@ var gulp = require('gulp'); var Server = require('karma').Server; +var remapIstanbul = require('remap-istanbul/lib/gulpRemapIstanbul'); /** * Run test once and exit @@ -9,5 +10,34 @@ gulp.task('test', ['concatPrism', 'inlineTemplates', 'injectVersionFile'], funct new Server({ configFile: __dirname + '/../../karma.conf.js', singleRun: true - }, done).start(); + }, karmaDone).start(); + + function karmaDone (exitCode) { + remapCoverage(done, exitCode); + } }); + +function remapCoverage(done, statusCode) { + console.log('Remapping coverage to TypeScript format...'); + gulp.src('coverage/**/coverage-final.json') + .pipe(remapIstanbul({ + reports: { + 'lcovonly': 'coverage/lcov.info', + 'text-summary': 'coverage/text-summary.txt', + 'html': 'coverage' + } + })) + .on('finish', function () { + console.log('Remapping done!'); + console.log(cat('coverage/text-summary.txt').stdout); + console.log('Test Done with exit code: ' + statusCode); + if (process.env.TRAVIS) { + console.log('uploading to coveralls') + var out = cat('coverage/lcov.info').exec('coveralls'); + if (out.code !== 0) { + console.warn('Failed upload to coveralls'); + } + } + done(statusCode); + }); +}; diff --git a/demo/index.html b/demo/index.html index cbcd26f1..0b3bf995 100644 --- a/demo/index.html +++ b/demo/index.html @@ -4,6 +4,11 @@ ReDoc + + - + - + diff --git a/demo/main.css b/demo/main.css index 02ec91ec..e927f4e6 100644 --- a/demo/main.css +++ b/demo/main.css @@ -1,5 +1,5 @@ -@import url(http://fonts.googleapis.com/css?family=Roboto:300,400,700); -@import url(http://fonts.googleapis.com/css?family=Montserrat:300,400); +/*@import url(http://fonts.googleapis.com/css?family=Roboto:300,400,700); +@import url(http://fonts.googleapis.com/css?family=Montserrat:300,400);*/ body { margin: 0; diff --git a/demo/swagger.yaml b/demo/swagger.yaml new file mode 100644 index 00000000..34e3414f --- /dev/null +++ b/demo/swagger.yaml @@ -0,0 +1,828 @@ +swagger: '2.0' +schemes: + - http +host: petstore.swagger.io +basePath: /v2 +info: + description: 'This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.' + version: 1.0.0 + title: Swagger Petstore + termsOfService: 'http://swagger.io/terms/' + contact: + email: apiteam@swagger.io + x-logo: + url: 'https://rebilly.github.io/ReDoc/petstore-logo.png' + license: + name: Apache 2.0 + url: 'http://www.apache.org/licenses/LICENSE-2.0.html' +externalDocs: + description: Find out more about Swagger + url: 'http://swagger.io' +tags: + - name: Pagination + x-traitTag: true + description: |- + Sometimes you just can't get enough. For this reason, we've provided a convenient way to access more data in any request for sequential data. Simply call the url in the next_url parameter and we'll respond with the next set of data. + ```json + { + + ... + + "pagination": { + + "next_url": + "https://api.instagram.com/v1/tags/puppy/media/recent?access_token=fb2e77d.47a0479900504cb3ab4a1f626d174d2d&max_id=13872296", + + "next_max_id": "13872296" + + } + + } + ``` + + On views where pagination is present, we also support the `count` + parameter. Simply set this to the number of items you'd like to receive. Note that the default values should be fine for most applications - but if you decide to increase this number there is a maximum value defined on each endpoint. + externalDocs: + description: Find out more + url: 'http://swagger.io' + - name: JSONP + x-traitTag: true + description: "If you're writing an AJAX application, and you'd like to wrap our response with a callback, all you have to do is specify a callback parameter with any API call:\n```\n https://api.instagram.com/v1/tags/coffee/media/recent?access_token=fb2e77d.47a0479900504cb3ab4a1f626d174d2d&callback=callbackFunction\n```\nWould respond with:\n```js\ncallbackFunction({\n ...\n});\n``` \n > Example of markdown blockquote" + externalDocs: + description: Find out more + url: 'http://swagger.io' + - name: pet + description: Everything about your Pets + externalDocs: + description: Find out more + url: 'http://swagger.io' + - name: store + description: Access to Petstore orders + - name: user + description: Operations about user + externalDocs: + description: Find out more about our store + url: 'http://swagger.io' +securityDefinitions: + petstore_auth: + type: oauth2 + authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog' + flow: implicit + scopes: + 'write:pets': modify pets in your account + 'read:pets': read your pets + api_key: + type: apiKey + name: api_key + in: header +paths: + /pet: + post: + tags: + - pet + summary: Add a new pet to the store + description: '' + operationId: addPet + consumes: + - application/json + - application/xml + produces: + - application/xml + - application/json + parameters: + - in: body + name: body + description: Pet object that needs to be added to the store + required: true + schema: + $ref: '#/definitions/Pet' + responses: + '405': + description: Invalid input + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + x-code-samples: + - lang: 'C#' + source: | + PetStore.v1.Pet pet = new PetStore.v1.Pet(); + pet.setApiKey("your api key"); + pet.petType = PetStore.v1.Pet.TYPE_DOG; + pet.name = "Rex"; + // set other fields + PetStoreResponse response = pet.create(); + if (response.statusCode == HttpStatusCode.Created) + { + // Successfully created + } + else + { + // Something wrong -- check response for errors + Console.WriteLine(response.getRawResponse()); + } + - lang: PHP + source: "$form = new \\PetStore\\Entities\\Pet();\n$form->setPetType(\"Dog\");\n$form->setName(\"Rex\");\n// set other fields\ntry {\n $pet = $client->pets()->create($form);\n} catch (UnprocessableEntityException $e) {\n var_dump($e->getErrors());\n}\n" + put: + tags: + - pet + summary: Update an existing pet + description: '' + operationId: updatePet + consumes: + - application/json + - application/xml + produces: + - application/xml + - application/json + parameters: + - in: body + name: body + description: Pet object that needs to be added to the store + required: true + schema: + $ref: '#/definitions/Pet' + responses: + '400': + description: Invalid ID supplied + '404': + description: Pet not found + '405': + description: Validation exception + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + x-code-samples: + - lang: PHP + source: "$form = new \\PetStore\\Entities\\Pet();\n$form->setPetId(1);\n$form->setPetType(\"Dog\");\n$form->setName(\"Rex\");\n// set other fields\ntry {\n $pet = $client->pets()->update($form);\n} catch (UnprocessableEntityException $e) {\n var_dump($e->getErrors());\n}\n" + '/pet/{petId}': + get: + tags: + - pet + - JSONP + summary: Find pet by ID + description: Returns a single pet + operationId: getPetById + produces: + - application/xml + - application/json + parameters: + - name: petId + in: path + description: ID of pet to return + required: true + type: integer + format: int64 + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + security: + - api_key: [] + post: + tags: + - pet + summary: Updates a pet in the store with form data + description: '' + operationId: updatePetWithForm + consumes: + - application/x-www-form-urlencoded + produces: + - application/xml + - application/json + parameters: + - name: petId + in: path + description: ID of pet that needs to be updated + required: true + type: integer + format: int64 + - name: name + in: formData + description: Updated name of the pet + required: false + type: string + - name: status + in: formData + description: Updated status of the pet + required: false + type: string + responses: + '405': + description: Invalid input + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + delete: + tags: + - pet + summary: Deletes a pet + description: '' + operationId: deletePet + produces: + - application/xml + - application/json + parameters: + - name: api_key + in: header + required: false + type: string + - name: petId + in: path + description: Pet id to delete + required: true + type: integer + format: int64 + responses: + '400': + description: Invalid pet value + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + '/pet/{petId}/uploadImage': + get: + tags: + - pet + summary: uploads an image + description: '' + operationId: uploadFile + consumes: + - image/jpeg + - image/png + produces: + - image/jpeg + - image/png + parameters: + - name: petId + in: path + description: ID of pet to update + required: true + type: integer + format: int64 + - name: file + in: body + description: file to upload + required: false + schema: + type: file + responses: + '200': + description: successful operation + schema: + type: file + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + post: + tags: + - pet + summary: uploads an image + description: '' + operationId: uploadFile + consumes: + - multipart/form-data + produces: + - application/json + parameters: + - name: petId + in: path + description: ID of pet to update + required: true + type: integer + format: int64 + - name: additionalMetadata + in: formData + description: Additional data to pass to server + required: false + type: string + - name: file + in: formData + description: file to upload + required: false + type: file + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/ApiResponse' + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + /pet/findByStatus: + get: + tags: + - pet + - Pagination + - JSONP + summary: Finds Pets by status + description: Multiple status values can be provided with comma seperated strings + operationId: findPetsByStatus + produces: + - application/xml + - application/json + parameters: + - name: status + in: query + description: Status values that need to be considered for filter + required: true + type: array + items: + type: string + enum: + - available + - pending + - sold + default: available + collectionFormat: csv + responses: + '200': + description: successful operation + schema: + type: array + items: + $ref: '#/definitions/Pet' + '400': + description: Invalid status value + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + /pet/findByTags: + get: + tags: + - pet + - Pagination + - JSONP + summary: Finds Pets by tags + description: 'Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.' + operationId: findPetsByTags + produces: + - application/xml + - application/json + parameters: + - name: tags + in: query + description: Tags to filter by + required: true + type: array + items: + type: string + collectionFormat: csv + responses: + '200': + description: successful operation + schema: + type: array + items: + $ref: '#/definitions/Pet' + '400': + description: Invalid tag value + security: + - petstore_auth: + - 'write:pets' + - 'read:pets' + /store/inventory: + get: + tags: + - store + - JSONP + summary: Returns pet inventories by status + description: Returns a map of status codes to quantities + operationId: getInventory + produces: + - application/json + parameters: [] + responses: + '200': + description: successful operation + schema: + type: object + additionalProperties: + type: integer + format: int32 + security: + - api_key: [] + /store/order: + post: + tags: + - store + summary: Place an order for a pet + description: '' + operationId: placeOrder + produces: + - application/xml + - application/json + parameters: + - in: body + name: body + description: order placed for purchasing the pet + required: true + schema: + $ref: '#/definitions/Order' + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/Order' + '400': + description: Invalid Order + '/store/order/{orderId}': + get: + tags: + - store + - JSONP + summary: Find purchase order by ID + description: 'For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions' + operationId: getOrderById + produces: + - application/xml + - application/json + parameters: + - name: orderId + in: path + description: ID of pet that needs to be fetched + required: true + type: integer + maximum: 5 + minimum: 1 + format: int64 + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/Order' + '400': + description: Invalid ID supplied + '404': + description: Order not found + delete: + tags: + - store + summary: Delete purchase order by ID + description: For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + operationId: deleteOrder + produces: + - application/xml + - application/json + parameters: + - name: orderId + in: path + description: ID of the order that needs to be deleted + required: true + type: string + minimum: 1 + responses: + '400': + description: Invalid ID supplied + '404': + description: Order not found + /user: + post: + tags: + - user + summary: Create user + description: This can only be done by the logged in user. + operationId: createUser + produces: + - application/xml + - application/json + parameters: + - in: body + name: body + description: Created user object + required: true + schema: + $ref: '#/definitions/User' + responses: + default: + description: successful operation + '/user/{username}': + get: + tags: + - user + - JSONP + summary: Get user by user name + description: '' + operationId: getUserByName + produces: + - application/xml + - application/json + parameters: + - name: username + in: path + description: 'The name that needs to be fetched. Use user1 for testing. ' + required: true + type: string + responses: + '200': + description: successful operation + schema: + $ref: '#/definitions/User' + '400': + description: Invalid username supplied + '404': + description: User not found + put: + tags: + - user + summary: Updated user + description: This can only be done by the logged in user. + operationId: updateUser + produces: + - application/xml + - application/json + parameters: + - name: username + in: path + description: name that need to be deleted + required: true + type: string + - in: body + name: body + description: Updated user object + required: true + schema: + $ref: '#/definitions/User' + responses: + '400': + description: Invalid user supplied + '404': + description: User not found + delete: + tags: + - user + summary: Delete user + description: This can only be done by the logged in user. + operationId: deleteUser + produces: + - application/xml + - application/json + parameters: + - name: username + in: path + description: The name that needs to be deleted + required: true + type: string + responses: + '400': + description: Invalid username supplied + '404': + description: User not found + /user/createWithArray: + post: + tags: + - user + summary: Creates list of users with given input array + description: '' + operationId: createUsersWithArrayInput + produces: + - application/xml + - application/json + parameters: + - in: body + name: body + description: List of user object + required: true + schema: + type: array + items: + $ref: '#/definitions/User' + responses: + default: + description: successful operation + /user/createWithList: + post: + tags: + - user + summary: Creates list of users with given input array + description: '' + operationId: createUsersWithListInput + produces: + - application/xml + - application/json + parameters: + - in: body + name: body + description: List of user object + required: true + schema: + type: array + items: + $ref: '#/definitions/User' + responses: + default: + description: successful operation + /user/login: + get: + tags: + - user + summary: Logs user into the system + description: '' + operationId: loginUser + produces: + - application/xml + - application/json + parameters: + - name: username + in: query + description: The user name for login + required: true + type: string + - name: password + in: query + description: The password for login in clear text + required: true + type: string + responses: + '200': + description: successful operation + schema: + type: string + headers: + X-Rate-Limit: + type: integer + format: int32 + description: calls per hour allowed by the user + X-Expires-After: + type: string + format: date-time + description: date in UTC when toekn expires + '400': + description: Invalid username/password supplied + /user/logout: + get: + tags: + - user + summary: Logs out current logged in user session + description: '' + operationId: logoutUser + produces: + - application/xml + - application/json + parameters: [] + responses: + default: + description: successful operation +definitions: + ApiResponse: + type: object + properties: + code: + type: integer + format: int32 + type: + type: string + message: + type: string + Cat: + description: A representation of a cat + allOf: + - $ref: '#/definitions/Pet' + - type: object + properties: + huntingSkill: + type: string + description: The measured skill for hunting + default: lazy + enum: + - clueless + - lazy + - adventurous + - aggressive + required: + - huntingSkill + Category: + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + xml: + name: Category + Dog: + description: A representation of a dog + allOf: + - $ref: '#/definitions/Pet' + - type: object + properties: + packSize: + type: integer + format: int32 + description: the size of the pack the dog is from + default: 0 + minimum: 0 + required: + - packSize + Order: + type: object + properties: + id: + type: integer + format: int64 + petId: + type: integer + format: int64 + quantity: + type: integer + format: int32 + shipDate: + type: string + format: date-time + status: + type: string + description: Order Status + enum: + - placed + - approved + - delivered + complete: + type: boolean + default: false + xml: + name: Order + Pet: + type: object + required: + - name + - photoUrls + discriminator: petType + properties: + petType: + type: string + id: + type: integer + format: int64 + category: + $ref: '#/definitions/Category' + name: + type: string + example: doggie + photoUrls: + type: array + xml: + name: photoUrl + wrapped: true + items: + type: string + tags: + type: array + xml: + name: tag + wrapped: true + items: + $ref: '#/definitions/Tag' + status: + type: string + description: pet status in the store + enum: + - available + - pending + - sold + xml: + name: Pet + Tag: + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + xml: + name: Tag + User: + type: object + properties: + id: + type: integer + format: int64 + username: + type: string + firstName: + type: string + lastName: + type: string + email: + type: string + password: + type: string + phone: + type: string + userStatus: + type: integer + format: int32 + description: User Status + xml: + name: User diff --git a/karma.conf.js b/karma.conf.js index a8dde48c..fa926f1b 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -1,15 +1,8 @@ module.exports = function (config) { - var travis = process.env.TRAVIS; config.set({ frameworks: ['phantomjs-shim', 'jspm', 'jasmine', 'sinon', 'should'], preprocessors: { - 'lib/**/!(*spec).js': ['babel', 'regex', 'coverage'] - }, - - regexPreprocessor: { - rules: [ - [ /'\.(.*?)\.css'/g, '\'.tmp$1.css\''] - ] + '.tmp/lib/**/!(*spec).js': ['babel', 'coverage'] }, babelPreprocessor: { options: { @@ -29,13 +22,13 @@ module.exports = function (config) { coverageReporter: { instrumenters: { isparta : require('isparta') }, instrumenter: { - 'lib/**/!(*spec).js': 'isparta' + '.tmp/lib/**/!(*spec).js': 'isparta' }, dir: 'coverage/', reporters: [ {type: 'html'}, - {type: 'text-summary'}, - {type: 'lcov'} + {type: 'lcov'}, + {type: 'json'} ] }, client: { @@ -51,28 +44,28 @@ module.exports = function (config) { 'node_modules/zone.js/dist/jasmine-patch.js', 'node_modules/zone.js/dist/long-stack-trace-zone.js', 'node_modules/babel-polyfill/dist/polyfill.js', - './node_modules/reflect-metadata/Reflect.js' + './node_modules/reflect-metadata/Reflect.js', + '.tmp/prismjs-bundle.js' ], jspm: { config: 'system.config.js', - loadFiles: ['tests/setup.js', 'tests/helpers.js', 'tests/unit/*.spec.js', 'lib/**/*.js'], + loadFiles: ['.tmp/tests/setup.js', '.tmp/tests/helpers.js', '.tmp/lib/**/*.js', + '.tmp/tests/unit/*.js'], serveFiles: ['tests/schemas/**/*.json','tests/schemas/**/*.yml', 'lib/**/*.html', - '.tmp/lib/**/*.json', '.tmp/*js', '.tmp/lib/**/*.css'], - nocache: true + '.tmp/lib/**/*.json', '.tmp/*js', '.tmp/lib/**/*.css'] }, proxies: { - '/tests/': '/base/tests/', - '/lib/components/Redoc/redoc-initial-styles.css': '/base/.tmp/lib/components/Redoc/redoc-initial-styles.css', + '/.tmp/': '/base/.tmp/', + '/tests/schemas': '/base/tests/schemas', + '/lib/components/redoc/redoc-initial-styles.scss': '/base/.tmp/lib/components/Redoc/redoc-initial-styles.scss', '/lib/version.json': '/base/.tmp/lib/version.json', '/lib/': '/base/lib/', '/jspm_packages/': '/base/jspm_packages/', - '/node_modules/': '/base/node_modules/', - '/prismjs-bundle.js': '/base/.tmp/prismjs-bundle.js', - '/.tmp/': '/base/.tmp/' + '/node_modules/': '/base/node_modules/' }, - reporters: travis ? ['mocha', 'coverage', 'coveralls'] : ['mocha', 'coverage'], + reporters: ['mocha', 'coverage'], browsers: ['PhantomJS'], diff --git a/lib/components/ApiInfo/api-info.spec.js b/lib/components/ApiInfo/api-info.spec.ts similarity index 80% rename from lib/components/ApiInfo/api-info.spec.js rename to lib/components/ApiInfo/api-info.spec.ts index a9c2d990..15e2611b 100644 --- a/lib/components/ApiInfo/api-info.spec.js +++ b/lib/components/ApiInfo/api-info.spec.ts @@ -1,11 +1,12 @@ 'use strict'; -import { getChildDebugElement } from 'tests/helpers'; +import { getChildDebugElement } from '../../../tests/helpers'; import { Component, provide } from '@angular/core'; import { inject, async, + expect, beforeEach, beforeEachProviders, it @@ -13,11 +14,9 @@ import { import { TestComponentBuilder } from '@angular/compiler/testing'; -import { ApiInfo } from 'lib/components/ApiInfo/api-info'; -import SchemaManager from 'lib/utils/SchemaManager'; -import { OptionsService } from 'lib/services/index'; - -let optionsService = new OptionsService(); +import { ApiInfo } from './api-info'; +import { SchemaManager } from '../../utils/SchemaManager'; +import { OptionsService } from '../../services/index'; describe('Redoc components', () => { describe('ApiInfo Component', () => { @@ -26,7 +25,7 @@ describe('Redoc components', () => { let fixture; beforeEachProviders(() => [ provide(SchemaManager, {useValue: new SchemaManager()}), - provide(OptionsService, {useValue: optionsService}) + provide(OptionsService, {useClass: OptionsService}) ]); beforeEach(async(inject([TestComponentBuilder, SchemaManager], (tcb, schemaMgr) => { @@ -35,7 +34,7 @@ describe('Redoc components', () => { }))); beforeEach((done) => { - builder.createAsync(TestApp).then(_fixture => { + builder.createAsync(TestAppComponent).then(_fixture => { fixture = _fixture; component = getChildDebugElement(fixture.debugElement, 'api-info').componentInstance; fixture.detectChanges(); @@ -68,5 +67,5 @@ describe('Redoc components', () => { template: `` }) -class TestApp { +class TestAppComponent { } diff --git a/lib/components/ApiInfo/api-info.js b/lib/components/ApiInfo/api-info.ts similarity index 59% rename from lib/components/ApiInfo/api-info.js rename to lib/components/ApiInfo/api-info.ts index 89d39f6d..8d8c4a3e 100644 --- a/lib/components/ApiInfo/api-info.js +++ b/lib/components/ApiInfo/api-info.ts @@ -5,14 +5,14 @@ import { OptionsService } from '../../services/index'; @RedocComponent({ selector: 'api-info', - styleUrls: ['./lib/components/ApiInfo/api-info.css'], - templateUrl: './lib/components/ApiInfo/api-info.html' + styleUrls: ['./api-info.css'], + templateUrl: './api-info.html' }) -@Reflect.metadata('parameters', [[SchemaManager], [OptionsService]]) export class ApiInfo extends BaseComponent { - constructor(schemaMgr, optionsService) { + data: any; + specUrl: String; + constructor(schemaMgr:SchemaManager, private optionsService:OptionsService) { super(schemaMgr); - this.optionsService = optionsService; } prepareModel() { diff --git a/lib/components/ApiLogo/api-logo.spec.js b/lib/components/ApiLogo/api-logo.spec.ts similarity index 86% rename from lib/components/ApiLogo/api-logo.spec.js rename to lib/components/ApiLogo/api-logo.spec.ts index a156aacb..e53a24a7 100644 --- a/lib/components/ApiLogo/api-logo.spec.js +++ b/lib/components/ApiLogo/api-logo.spec.ts @@ -1,6 +1,6 @@ 'use strict'; -import { getChildDebugElement } from 'tests/helpers'; +import { getChildDebugElement } from '../../../tests/helpers'; import {Component, provide} from '@angular/core'; import { @@ -13,8 +13,8 @@ import { import { TestComponentBuilder } from '@angular/compiler/testing'; -import { ApiLogo } from 'lib/components/ApiLogo/api-logo'; -import SchemaManager from 'lib/utils/SchemaManager'; +import { ApiLogo } from './api-logo'; +import { SchemaManager } from '../../utils/SchemaManager'; describe('Redoc components', () => { @@ -34,7 +34,7 @@ describe('Redoc components', () => { return schemaMgr.load(schemaUrl); }))); beforeEach((done) => { - builder.createAsync(TestApp).then(_fixture => { + builder.createAsync(TestAppComponent).then(_fixture => { fixture = _fixture; component = getChildDebugElement(fixture.debugElement, 'api-logo').componentInstance; fixture.detectChanges(); @@ -49,7 +49,7 @@ describe('Redoc components', () => { }); it('should not display image when no x-logo', () => { - component.data.should.be.empty; + component.data.should.be.empty(); let nativeElement = getChildDebugElement(fixture.debugElement, 'api-logo').nativeElement; let imgElement = nativeElement.querySelector('img'); expect(imgElement).toBeNull(); @@ -74,5 +74,5 @@ describe('Redoc components', () => { template: `` }) -class TestApp { +class TestAppComponent { } diff --git a/lib/components/ApiLogo/api-logo.js b/lib/components/ApiLogo/api-logo.ts similarity index 61% rename from lib/components/ApiLogo/api-logo.js rename to lib/components/ApiLogo/api-logo.ts index dcf5a0bc..929e8626 100644 --- a/lib/components/ApiLogo/api-logo.js +++ b/lib/components/ApiLogo/api-logo.ts @@ -1,19 +1,20 @@ 'use strict'; -import {RedocComponent, BaseComponent} from '../base'; +import {RedocComponent, BaseComponent, SchemaManager} from '../base'; @RedocComponent({ selector: 'api-logo', - styleUrls: ['./lib/components/ApiLogo/api-logo.css'], - templateUrl: './lib/components/ApiLogo/api-logo.html' + styleUrls: ['./api-logo.css'], + templateUrl: './api-logo.html' }) export class ApiLogo extends BaseComponent { - constructor(schemaMgr) { + data:any = {}; + + constructor(schemaMgr:SchemaManager) { super(schemaMgr); } prepareModel() { - this.data = {}; let logoInfo = this.componentSchema.info['x-logo']; if (!logoInfo) return; this.data.imgUrl = logoInfo.url; diff --git a/lib/components/JsonSchema/json-schema-lazy.spec.js b/lib/components/JsonSchema/json-schema-lazy.spec.ts similarity index 69% rename from lib/components/JsonSchema/json-schema-lazy.spec.js rename to lib/components/JsonSchema/json-schema-lazy.spec.ts index 5e09b679..5b45428c 100644 --- a/lib/components/JsonSchema/json-schema-lazy.spec.js +++ b/lib/components/JsonSchema/json-schema-lazy.spec.ts @@ -1,9 +1,8 @@ 'use strict'; -import { getChildDebugElement } from 'tests/helpers'; +import { getChildDebugElement } from '../../../tests/helpers'; import { Component, provide } from '@angular/core'; import { DynamicComponentLoader } from '@angular/core'; -import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter'; import { inject, @@ -15,9 +14,8 @@ import { import { TestComponentBuilder } from '@angular/compiler/testing'; -import { JsonSchemaLazy } from 'lib/components/JsonSchema/json-schema-lazy'; -import SchemaManager from 'lib/utils/SchemaManager'; -import { OptionsService } from 'lib/services/index'; +import { JsonSchemaLazy } from './json-schema-lazy'; +import { SchemaManager } from '../../utils/SchemaManager'; describe('Redoc components', () => { describe('JsonSchemaLazy Component', () => { @@ -26,25 +24,25 @@ describe('Redoc components', () => { let schemaMgr = new SchemaManager(); let fixture; let loader; - let appRef = { - instance: {}, - hostView: {changeDetectorRef: {detectChanges : function() {} }} + let appRefMock = { + instance: { + pointer: '' + }, + hostView: { changeDetectorRef: {detectChanges : () => undefined} } }; beforeEachProviders(() => [ - provide(SchemaManager, {useValue: schemaMgr}), - provide(BrowserDomAdapter, {useClass: BrowserDomAdapter}), - provide(OptionsService, {useClass: OptionsService}) + provide(SchemaManager, {useValue: schemaMgr}) ]); beforeEach(inject([TestComponentBuilder, DynamicComponentLoader], (tcb, dcl) => { builder = tcb; loader = dcl; - spyOn(loader, 'loadNextToLocation').and.returnValue({then: (fn) => fn(appRef)}); + spyOn(loader, 'loadNextToLocation').and.returnValue({then: (fn) => fn(appRefMock)}); })); beforeEach((done) => { - builder.createAsync(TestApp).then(_fixture => { + builder.createAsync(TestAppComponent).then(_fixture => { fixture = _fixture; let debugEl = getChildDebugElement(fixture.debugElement, 'json-schema-lazy'); - component = debugEl.componentInstance; + component = debugEl.componentInstance; done(); }, err => done.fail(err)); }); @@ -76,7 +74,7 @@ describe('Redoc components', () => { component.pointer = '#/def'; fixture.detectChanges(); component.load(); - expect(appRef.instance.pointer).toEqual(component.pointer); + expect(appRefMock.instance.pointer).toEqual(component.pointer); }); }); }); @@ -89,5 +87,5 @@ describe('Redoc components', () => { template: `` }) -class TestApp { +class TestAppComponent { } diff --git a/lib/components/JsonSchema/json-schema-lazy.js b/lib/components/JsonSchema/json-schema-lazy.ts similarity index 69% rename from lib/components/JsonSchema/json-schema-lazy.js rename to lib/components/JsonSchema/json-schema-lazy.ts index 209180d3..af01a9dd 100644 --- a/lib/components/JsonSchema/json-schema-lazy.js +++ b/lib/components/JsonSchema/json-schema-lazy.ts @@ -1,12 +1,12 @@ 'use strict'; -import { Component, ElementRef, ViewContainerRef } from '@angular/core'; +import { Component, ElementRef, ViewContainerRef, OnDestroy, AfterViewInit } from '@angular/core'; import { CORE_DIRECTIVES } from '@angular/common'; -import { DynamicComponentLoader } from '@angular/core'; +import { DynamicComponentLoader, Input } from '@angular/core'; import { JsonSchema } from './json-schema'; -import { OptionsService } from '../../services/index'; -import SchemaManager from '../../utils/SchemaManager'; +import { OptionsService } from '../../services/options.service'; +import { SchemaManager } from '../../utils/SchemaManager'; var cache = {}; @@ -14,20 +14,16 @@ var cache = {}; @Component({ selector: 'json-schema-lazy', - inputs: ['pointer', 'auto', 'isRequestSchema'], template: '', directives: [CORE_DIRECTIVES] }) -@Reflect.metadata('parameters', [[SchemaManager], [ViewContainerRef], [ - ElementRef], [DynamicComponentLoader], [OptionsService]]) -export class JsonSchemaLazy { - - constructor(schemaMgr, viewRef, elementRef, dcl, optionsService) { - this.viewRef = viewRef; - this.elementRef = elementRef; - this.dcl = dcl; - this.optionsService = optionsService; - this.schemaMgr = schemaMgr; +export class JsonSchemaLazy implements OnDestroy, AfterViewInit { + @Input() pointer: string; + @Input() auto: boolean; + @Input() isRequestSchema: boolean; + loaded: boolean = false; + constructor(private schemaMgr:SchemaManager, private viewRef:ViewContainerRef, private elementRef:ElementRef, + private dcl:DynamicComponentLoader, private optionsService:OptionsService) { } normalizePointer() { @@ -40,8 +36,6 @@ export class JsonSchemaLazy { this.initComponent(compRef); if (compRef.changeDetectorRef) { compRef.changeDetectorRef.detectChanges(); - } else { - compRef.hostView.changeDetectorRef.detectChanges(); } return compRef; }); @@ -58,7 +52,7 @@ export class JsonSchemaLazy { // cache JsonSchema view loadCached() { - this.pointer = this.normalizePointer(this.pointer); + this.pointer = this.normalizePointer(); if (cache[this.pointer]) { cache[this.pointer].then((compRef) => { setTimeout( ()=> { diff --git a/lib/components/JsonSchema/json-schema.html b/lib/components/JsonSchema/json-schema.html index 3a0e67cd..4605645c 100644 --- a/lib/components/JsonSchema/json-schema.html +++ b/lib/components/JsonSchema/json-schema.html @@ -43,10 +43,10 @@
This field value determines the exact schema: - + - +
diff --git a/lib/components/JsonSchema/json-schema.spec.js b/lib/components/JsonSchema/json-schema.spec.ts similarity index 73% rename from lib/components/JsonSchema/json-schema.spec.js rename to lib/components/JsonSchema/json-schema.spec.ts index dcca663f..ebb0d13b 100644 --- a/lib/components/JsonSchema/json-schema.spec.js +++ b/lib/components/JsonSchema/json-schema.spec.ts @@ -9,12 +9,11 @@ import { } from '@angular/core/testing'; import { TestComponentBuilder } from '@angular/compiler/testing'; -import { OptionsService } from 'lib/services/index'; -import { getChildDebugElement } from 'tests/helpers'; +import { getChildDebugElement } from '../../../tests/helpers'; -import { JsonSchema } from 'lib/components/JsonSchema/json-schema'; -import SchemaManager from 'lib/utils/SchemaManager'; +import { JsonSchema } from './json-schema'; +import { SchemaManager } from '../../utils/SchemaManager';; describe('Redoc components', () => { describe('JsonSchema Component', () => { @@ -23,14 +22,13 @@ describe('Redoc components', () => { let schemaMgr = new SchemaManager(); let fixture; beforeEachProviders(() => [ - provide(SchemaManager, {useValue: schemaMgr}), - provide(OptionsService, {useClass: OptionsService}) + provide(SchemaManager, {useValue: schemaMgr}) ]); beforeEach(inject([TestComponentBuilder], (tcb) => { builder = tcb; })); beforeEach((done) => { - builder.createAsync(TestApp).then(_fixture => { + builder.createAsync(TestAppComponent).then(_fixture => { fixture = _fixture; let debugEl = getChildDebugElement(fixture.debugElement, 'json-schema'); component = debugEl.componentInstance; @@ -40,21 +38,21 @@ describe('Redoc components', () => { it('should init component', () => { component.pointer = ''; - schemaMgr._schema = {type: 'object'}; + (schemaMgr)._schema = {type: 'object'}; fixture.detectChanges(); expect(component).not.toBeNull(); }); it('should set isTrivial for non-object/array types', () => { component.pointer = ''; - schemaMgr._schema = {type: 'string'}; + (schemaMgr)._schema = {type: 'string'}; fixture.detectChanges(); component.schema.isTrivial.should.be.true(); }); it('should use < * > notation for prop without type', () => { component.pointer = ''; - schemaMgr._schema = {type: 'object', properties: { + (schemaMgr)._schema = {type: 'object', properties: { test: {} }}; fixture.detectChanges(); @@ -72,5 +70,5 @@ describe('Redoc components', () => { template: `` }) -class TestApp { +class TestAppComponent { } diff --git a/lib/components/JsonSchema/json-schema.js b/lib/components/JsonSchema/json-schema.ts similarity index 95% rename from lib/components/JsonSchema/json-schema.js rename to lib/components/JsonSchema/json-schema.ts index c313c350..cac43224 100644 --- a/lib/components/JsonSchema/json-schema.js +++ b/lib/components/JsonSchema/json-schema.ts @@ -1,6 +1,6 @@ 'use strict'; -import { ElementRef } from '@angular/core'; +import { ElementRef, Input } from '@angular/core'; import { RedocComponent, BaseComponent, SchemaManager } from '../base'; import { DropDown } from '../../shared/components/index'; @@ -8,18 +8,33 @@ import JsonPointer from '../../utils/JsonPointer'; @RedocComponent({ selector: 'json-schema', - templateUrl: './lib/components/JsonSchema/json-schema.html', - styleUrls: ['./lib/components/JsonSchema/json-schema.css'], + templateUrl: './json-schema.html', + styleUrls: ['./json-schema.css'], directives: [JsonSchema, DropDown], - inputs: ['isArray', 'final', 'nestOdd', 'childFor', 'isRequestSchema'], detect: true }) -@Reflect.metadata('parameters', [[SchemaManager], [ElementRef]]) export class JsonSchema extends BaseComponent { - constructor(schemaMgr, elementRef) { + $element: any; + schema: any; + derivedEmtpy: boolean; + @Input() isArray: boolean; + @Input() final: boolean = false; + @Input() nestOdd: boolean; + @Input() childFor: string; + @Input() isRequestSchema: boolean; + + static injectPropertyData(propertySchema, propertyName, propPointer, hostPointer?) { + propertySchema = Object.assign({}, propertySchema); + + propertySchema._name = propertyName; + runInjectors(propertySchema, propertySchema, propPointer, hostPointer); + + return propertySchema; + } + + constructor(schemaMgr:SchemaManager, elementRef:ElementRef) { super(schemaMgr); this.$element = elementRef.nativeElement; - this.final = false; } selectDerived(subClassIdx) { @@ -131,24 +146,6 @@ export class JsonSchema extends BaseComponent { return JsonSchema.injectPropertyData(addProps, ' *', JsonPointer.join(addProps._pointer || schema._pointer || this.pointer, ['additionalProperties'])); } - - static injectPropertyData(propertySchema, propertyName, propPointer, hostPointer) { - propertySchema = Object.assign({}, propertySchema); - - propertySchema._name = propertyName; - runInjectors(propertySchema, propertySchema, propPointer, hostPointer); - - return propertySchema; - } -} - -function runInjectors(injectTo, propertySchema, propertyPointer, hostPointer) { - for (var injName in injectors) { - let injector = injectors[injName]; - if (injector.check(propertySchema)) { - injector.inject(injectTo, propertySchema, propertyPointer, hostPointer); - } - } } const injectors = { @@ -277,3 +274,12 @@ const injectors = { } } }; + +function runInjectors(injectTo, propertySchema, propertyPointer, hostPointer?) { + for (var injName in injectors) { + let injector = injectors[injName]; + if (injector.check(propertySchema)) { + injector.inject(injectTo, propertySchema, propertyPointer, hostPointer); + } + } +} diff --git a/lib/components/Method/method.spec.js b/lib/components/Method/method.spec.ts similarity index 66% rename from lib/components/Method/method.spec.js rename to lib/components/Method/method.spec.ts index dd17c099..6ce561e9 100644 --- a/lib/components/Method/method.spec.js +++ b/lib/components/Method/method.spec.ts @@ -1,7 +1,6 @@ 'use strict'; import { Component, provide } from '@angular/core'; -import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter'; import { inject, async, @@ -11,28 +10,24 @@ import { } from '@angular/core/testing'; import { TestComponentBuilder } from '@angular/compiler/testing'; -import { getChildDebugElement } from 'tests/helpers'; +import { getChildDebugElement } from '../../../tests/helpers'; -import { Method } from 'lib/components/Method/method'; -import SchemaManager from 'lib/utils/SchemaManager'; -import { OptionsService, RedocEventsService } from 'lib/services/index'; +import { Method } from './method'; +import { SchemaManager } from '../../utils/SchemaManager';; describe('Redoc components', () => { describe('Method Component', () => { let builder; let component; beforeEachProviders(() => [ - provide(SchemaManager, {useValue: new SchemaManager()}), - provide(BrowserDomAdapter, {useClass: BrowserDomAdapter}), - provide(OptionsService, {useClass: OptionsService}), - provide(RedocEventsService, {useClass: RedocEventsService}) + provide(SchemaManager, {useValue: new SchemaManager()}) ]); beforeEach(async(inject([TestComponentBuilder, SchemaManager], (tcb, schemaMgr) => { builder = tcb; return schemaMgr.load('/tests/schemas/extended-petstore.yml'); }))); beforeEach((done) => { - builder.createAsync(TestApp).then(fixture => { + builder.createAsync(TestAppComponent).then(fixture => { component = getChildDebugElement(fixture.debugElement, 'method').componentInstance; fixture.detectChanges(); done(); @@ -52,7 +47,7 @@ describe('Redoc components', () => { it('should main tag', () => { - component.data.methodInfo.tags.should.be.empty; + component.data.methodInfo.tags.should.be.empty(); }); }); }); @@ -66,5 +61,5 @@ describe('Redoc components', () => { template: `` }) -class TestApp { +class TestAppComponent { } diff --git a/lib/components/Method/method.js b/lib/components/Method/method.ts similarity index 83% rename from lib/components/Method/method.js rename to lib/components/Method/method.ts index 9b2ce7fa..04c85077 100644 --- a/lib/components/Method/method.js +++ b/lib/components/Method/method.ts @@ -1,7 +1,7 @@ 'use strict'; - -import { JsonPointer } from '../../utils/JsonPointer'; -import { RedocComponent, BaseComponent } from '../base'; +import { Input } from '@angular/core'; +import JsonPointer from '../../utils/JsonPointer'; +import { RedocComponent, BaseComponent, SchemaManager} from '../base'; import { ParamsList } from '../ParamsList/params-list'; import { ResponsesList } from '../ResponsesList/responses-list'; @@ -11,14 +11,15 @@ import { RequestSamples } from '../RequestSamples/request-samples'; @RedocComponent({ selector: 'method', - templateUrl: './lib/components/Method/method.html', - styleUrls: ['./lib/components/Method/method.css'], + templateUrl: './method.html', + styleUrls: ['./method.css'], directives: [ ParamsList, ResponsesList, ResponsesSamples, SchemaSample, RequestSamples ], - inputs: ['tag'], detect: true }) export class Method extends BaseComponent { - constructor(schemaMgr) { + data:any; + @Input() tag:string; + constructor(schemaMgr:SchemaManager) { super(schemaMgr); } diff --git a/lib/components/MethodsList/methods-list.spec.js b/lib/components/MethodsList/methods-list.spec.ts similarity index 66% rename from lib/components/MethodsList/methods-list.spec.js rename to lib/components/MethodsList/methods-list.spec.ts index 76aaccbc..aea0b207 100644 --- a/lib/components/MethodsList/methods-list.spec.js +++ b/lib/components/MethodsList/methods-list.spec.ts @@ -1,7 +1,6 @@ 'use strict'; import { Component, provide } from '@angular/core'; -import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter'; import { inject, async, @@ -11,11 +10,11 @@ import { } from '@angular/core/testing'; import { TestComponentBuilder } from '@angular/compiler/testing'; -import { getChildDebugElement } from 'tests/helpers'; +import { getChildDebugElement } from '../../../tests/helpers'; -import { OptionsService, RedocEventsService } from 'lib/services/index'; -import { MethodsList } from 'lib/components/MethodsList/methods-list'; -import SchemaManager from 'lib/utils/SchemaManager'; + +import { MethodsList } from './methods-list'; +import { SchemaManager } from '../../utils/SchemaManager'; describe('Redoc components', () => { describe('MethodsList Component', () => { @@ -23,17 +22,14 @@ describe('Redoc components', () => { let component; let fixture; beforeEachProviders(() => [ - provide(SchemaManager, {useValue: new SchemaManager()}), - provide(OptionsService, {useClass: OptionsService}), - provide(BrowserDomAdapter, {useClass: BrowserDomAdapter}), - provide(RedocEventsService, {useClass: RedocEventsService}) + provide(SchemaManager, {useValue: new SchemaManager()}) ]); beforeEach(async(inject([TestComponentBuilder, SchemaManager], (tcb, schemaMgr) => { builder = tcb; return schemaMgr.load('/tests/schemas/methods-list-component.json'); }))); beforeEach((done) => { - builder.createAsync(TestApp).then(_fixture => { + builder.createAsync(TestAppComponent).then(_fixture => { fixture = _fixture; component = getChildDebugElement(fixture.debugElement, 'methods-list').componentInstance; fixture.detectChanges(); @@ -50,7 +46,7 @@ describe('Redoc components', () => { expect(component.data.tags).not.toBeNull(); component.data.tags.should.have.lengthOf(2); component.data.tags[0].name.should.be.equal('traitTag'); - component.data.tags[0].methods.should.be.empty; + component.data.tags[0].methods.should.be.empty(); component.data.tags[1].name.should.be.equal('tag1'); component.data.tags[1].methods.should.have.lengthOf(2); }); @@ -63,5 +59,5 @@ describe('Redoc components', () => { template: `` }) -class TestApp { +class TestAppComponent { } diff --git a/lib/components/MethodsList/methods-list.js b/lib/components/MethodsList/methods-list.ts similarity index 79% rename from lib/components/MethodsList/methods-list.js rename to lib/components/MethodsList/methods-list.ts index 3c036b99..fe80c592 100644 --- a/lib/components/MethodsList/methods-list.js +++ b/lib/components/MethodsList/methods-list.ts @@ -1,21 +1,21 @@ 'use strict'; import { forwardRef } from '@angular/core'; -import { RedocComponent, BaseComponent } from '../base'; +import { RedocComponent, BaseComponent, SchemaManager } from '../base'; import { Method } from '../Method/method'; import { EncodeURIComponentPipe } from '../../utils/pipes'; @RedocComponent({ selector: 'methods-list', - templateUrl: './lib/components/MethodsList/methods-list.html', - styleUrls: ['./lib/components/MethodsList/methods-list.css'], + templateUrl: './methods-list.html', + styleUrls: ['./methods-list.css'], directives: [ forwardRef(() => Method) ], pipes: [ EncodeURIComponentPipe ], detect: true }) export class MethodsList extends BaseComponent { - - constructor(schemaMgr) { + data:any; + constructor(schemaMgr:SchemaManager) { super(schemaMgr); } @@ -25,7 +25,7 @@ export class MethodsList extends BaseComponent { // duplicate methods let menuStructure = this.schemaMgr.buildMenuTree(); - let tags = Array.from(menuStructure.entries()) + let tags = Array.from(menuStructure.entries()) .map((entry) => { let [tag, {description, methods}] = entry; // inject tag name into method info diff --git a/lib/components/ParamsList/params-list.js b/lib/components/ParamsList/params-list.ts similarity index 90% rename from lib/components/ParamsList/params-list.js rename to lib/components/ParamsList/params-list.ts index 99b147c2..d9b6ce27 100644 --- a/lib/components/ParamsList/params-list.js +++ b/lib/components/ParamsList/params-list.ts @@ -1,6 +1,6 @@ 'use strict'; -import { RedocComponent, BaseComponent } from '../base'; +import { RedocComponent, BaseComponent, SchemaManager } from '../base'; import { JsonSchema } from '../JsonSchema/json-schema'; import {JsonSchemaLazy} from '../JsonSchema/json-schema-lazy'; @@ -11,12 +11,15 @@ function safePush(obj, prop, item) { @RedocComponent({ selector: 'params-list', - templateUrl: './lib/components/ParamsList/params-list.html', - styleUrls: ['./lib/components/ParamsList/params-list.css'], + templateUrl: './params-list.html', + styleUrls: ['./params-list.css'], directives: [JsonSchema, JsonSchemaLazy] }) export class ParamsList extends BaseComponent { - constructor(schemaMgr) { + + data:any; + + constructor(schemaMgr:SchemaManager) { super(schemaMgr); } @@ -62,7 +65,7 @@ export class ParamsList extends BaseComponent { this.data.params = params; } - orderParams(params) { + orderParams(params):any { let res = {}; params.forEach((param) => safePush(res, param.in, param)); return res; diff --git a/lib/components/Redoc/redoc.spec.js b/lib/components/Redoc/redoc.spec.ts similarity index 81% rename from lib/components/Redoc/redoc.spec.js rename to lib/components/Redoc/redoc.spec.ts index 12723b6f..5b6c463e 100644 --- a/lib/components/Redoc/redoc.spec.js +++ b/lib/components/Redoc/redoc.spec.ts @@ -1,7 +1,7 @@ 'use strict'; -import { getChildDebugElement } from 'tests/helpers'; -import { Component, provide } from '@angular/core'; +import { getChildDebugElement } from '../../../tests/helpers'; +import { Component, provide, ComponentRef } from '@angular/core'; import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter'; import { @@ -14,31 +14,35 @@ import { import { TestComponentBuilder } from '@angular/compiler/testing'; -import { Redoc } from 'lib/components/Redoc/redoc'; -import SchemaManager from 'lib/utils/SchemaManager'; -import { OptionsService } from 'lib/services/index'; +import { Redoc } from './redoc'; +import { SchemaManager } from '../../utils/SchemaManager'; +import { OptionsService } from '../../services/index'; -let optsMgr = new OptionsService(new BrowserDomAdapter()); +let optsMgr:OptionsService; describe('Redoc components', () => { describe('Redoc Component', () => { let builder; + let schemaMgr; beforeEachProviders(() => [ provide(SchemaManager, {useValue: new SchemaManager()}), - provide(BrowserDomAdapter, {useValue: new BrowserDomAdapter()}), - provide(OptionsService, {useValue: optsMgr}) ]); - beforeEachProviders(() => [ - provide(OptionsService, {useValue: optsMgr}) - ]); - beforeEach(async(inject([TestComponentBuilder, SchemaManager], (tcb, schemaMgr) => { + beforeEach(async(inject([TestComponentBuilder, SchemaManager, OptionsService], + (tcb, _schemaMgr, _optsMgr) => { + optsMgr = _optsMgr; builder = tcb; - return schemaMgr.load('/tests/schemas/extended-petstore.yml'); + schemaMgr = _schemaMgr; }))); + beforeEach((done) => { + return schemaMgr.load('/tests/schemas/extended-petstore.yml') + .then(() => done()) + .catch(err => done.fail(err)); + }); + it('should init component', (done) => { - builder.createAsync(TestApp).then(fixture => { + builder.createAsync(TestAppComponent).then(fixture => { let component = getChildDebugElement(fixture.debugElement, 'redoc').componentInstance; expect(component).not.toBeNull(); fixture.destroy(); @@ -47,11 +51,13 @@ describe('Redoc components', () => { }); it('should init components tree without errors', (done) => { - builder.createAsync(TestApp).then(fixture => { + builder.createAsync(TestAppComponent).then(fixture => { (() => fixture.detectChanges()).should.not.throw(); fixture.destroy(); done(); - }, err => done.fail(err)); + }, err => { + return done.fail(err); + }); }); }); @@ -110,11 +116,11 @@ describe('Redoc components', () => { }))); beforeEach((done) => { - builder.createAsync(TestApp).then(_fixture => { + builder.createAsync(TestAppComponent).then(_fixture => { fixture = _fixture; element = getChildDebugElement(fixture.debugElement, 'methods-list').nativeElement; destroySpy = jasmine.createSpy('spy'); - Redoc.appRef = { + Redoc.appRef = >{ destroy: destroySpy }; fixture.detectChanges(); @@ -148,7 +154,9 @@ describe('Redoc components', () => { describe('Redoc autoInit', () => { const testURL = 'testurl'; let dom = new BrowserDomAdapter(); - let elem; + //let redocInitSpy; + let elem: HTMLElement; + beforeEach(() => { spyOn(Redoc, 'init').and.stub(); elem = dom.createElement('redoc'); @@ -159,7 +167,7 @@ describe('Redoc components', () => { it('should call Redoc.init with url from param spec-url', () => { Redoc.autoInit(); expect(Redoc.init).toHaveBeenCalled(); - expect(Redoc.init.calls.argsFor(0)).toEqual([testURL]); + expect((Redoc.init).calls.argsFor(0)).toEqual([testURL]); }); it('should not call Redoc.init when spec-url param is not provided', () => { @@ -169,7 +177,7 @@ describe('Redoc components', () => { }); afterEach(() => { - Redoc.init.and.callThrough(); + (Redoc.init).and.callThrough(); dom.defaultDoc().body.removeChild(elem); }); }); @@ -182,5 +190,5 @@ describe('Redoc components', () => { template: `` }) -class TestApp { +class TestAppComponent { } diff --git a/lib/components/Redoc/redoc.js b/lib/components/Redoc/redoc.ts similarity index 82% rename from lib/components/Redoc/redoc.js rename to lib/components/Redoc/redoc.ts index 456d1c18..54f66ba3 100644 --- a/lib/components/Redoc/redoc.js +++ b/lib/components/Redoc/redoc.ts @@ -1,6 +1,7 @@ 'use strict'; -import { provide, enableProdMode, ElementRef } from '@angular/core'; +import { provide, enableProdMode, ElementRef, + ComponentRef, AfterViewInit } from '@angular/core'; import { bootstrap } from '@angular/platform-browser-dynamic'; import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter'; import { RedocComponent, BaseComponent } from '../base'; @@ -13,12 +14,9 @@ import { MethodsList } from '../MethodsList/methods-list'; import { SideMenu } from '../SideMenu/side-menu'; import { StickySidebar } from '../../shared/components/index'; -import SchemaManager from '../../utils/SchemaManager'; +import {SchemaManager} from '../../utils/SchemaManager'; import { OptionsService, RedocEventsService } from '../../services/index'; -import redocVersion from '../../version.json!json'; - - -import './redoc-initial-styles.css!css'; +//import redocVersion from '../../version.js'; var dom = new BrowserDomAdapter(); var _modeLocked = false; @@ -30,30 +28,18 @@ var _modeLocked = false; BrowserDomAdapter, RedocEventsService ], - templateUrl: './lib/components/Redoc/redoc.html', - styleUrls: ['./lib/components/Redoc/redoc.css'], + templateUrl: './redoc.html', + styleUrls: ['./redoc.css'], directives: [ ApiInfo, ApiLogo, MethodsList, SideMenu, StickySidebar ], detect: true, onPushOnly: false }) -@Reflect.metadata('parameters', [ - [SchemaManager], [OptionsService], [ElementRef], [RedocEventsService]]) -export class Redoc extends BaseComponent { - constructor(schemaMgr, optionsMgr, elementRef, events) { - super(schemaMgr); - this.element = elementRef.nativeElement; - //parse options (top level component doesn't support inputs) - optionsMgr.parseOptions( this.element ); - optionsMgr.options.$scrollParent = detectScollParent( this.element ); - this.options = optionsMgr.options; - this.events = events; - } +export class Redoc extends BaseComponent implements AfterViewInit { + static appRef: ComponentRef; - ngAfterViewInit() { - setTimeout( () => { - this.events.bootstrapped.next(); - }); - } + options: any; + + private element: any; static showLoadingAnimation() { let elem = dom.query('redoc'); @@ -69,7 +55,7 @@ export class Redoc extends BaseComponent { }, 400); } - static init(specUrl, options) { + static init(specUrl?, options?) { var optionsService = new OptionsService(dom); optionsService.options = options; optionsService.options.specUrl = optionsService.options.specUrl || specUrl; @@ -121,9 +107,9 @@ export class Redoc extends BaseComponent { redocEl.innerHTML = erroHtml; } - static get version() { - return redocVersion; - } + // static get version() { + // return redocVersion; + // } static destroy() { let el = dom.query('redoc'); @@ -143,7 +129,24 @@ export class Redoc extends BaseComponent { // Redoc destroy removes host element, so need to restore it elClone.innerHTML = 'Loading...'; - parent && parent.insertBefore(elClone, nextSibling); + if (parent) parent.insertBefore(elClone, nextSibling); } } + + constructor(schemaMgr: SchemaManager, optionsMgr:OptionsService, elementRef:ElementRef, + public events:RedocEventsService) { + super(schemaMgr); + this.element = elementRef.nativeElement; + //parse options (top level component doesn't support inputs) + optionsMgr.parseOptions( this.element ); + optionsMgr.options.$scrollParent = detectScollParent( this.element ); + this.options = optionsMgr.options; + this.events = events; + } + + ngAfterViewInit() { + setTimeout( () => { + this.events.bootstrapped.next({}); + }); + } } diff --git a/lib/components/RequestSamples/request-samples.html b/lib/components/RequestSamples/request-samples.html index d1175c8c..cc9bbb45 100644 --- a/lib/components/RequestSamples/request-samples.html +++ b/lib/components/RequestSamples/request-samples.html @@ -1,8 +1,8 @@
Request samples
- + - +

diff --git a/lib/components/RequestSamples/request-samples.js b/lib/components/RequestSamples/request-samples.ts
similarity index 67%
rename from lib/components/RequestSamples/request-samples.js
rename to lib/components/RequestSamples/request-samples.ts
index f31de1ac..c7631ace 100644
--- a/lib/components/RequestSamples/request-samples.js
+++ b/lib/components/RequestSamples/request-samples.ts
@@ -1,6 +1,6 @@
 'use strict';
 
-import { ViewChildren, QueryList } from '@angular/core';
+import { ViewChildren, QueryList, EventEmitter, Input} from '@angular/core';
 
 import { RedocComponent, BaseComponent, SchemaManager } from '../base';
 import JsonPointer from '../../utils/JsonPointer';
@@ -11,22 +11,23 @@ import { RedocEventsService } from '../../services/index';
 
 @RedocComponent({
   selector: 'request-samples',
-  templateUrl: './lib/components/RequestSamples/request-samples.html',
-  styleUrls: ['./lib/components/RequestSamples/request-samples.css'],
+  templateUrl: './request-samples.html',
+  styleUrls: ['./request-samples.css'],
   directives: [SchemaSample, Tabs, Tab],
   inputs: ['schemaPointer'],
   pipes: [PrismPipe],
   detect: true,
   onPushOnly: false
 })
-@Reflect.metadata('parameters', [[SchemaManager], [RedocEventsService], [new ViewChildren(Tabs), QueryList]])
 export class RequestSamples extends BaseComponent {
-  constructor(schemaMgr, events, childQuery) {
+  childTabs: Tabs;
+  selectedLang: EventEmitter;
+  data: any;
+  @Input() schemaPointer:string;
+  @ViewChildren(Tabs) childQuery:QueryList;
+  constructor(schemaMgr:SchemaManager, public events:RedocEventsService) {
     super(schemaMgr);
-    childQuery.changes.subscribe(() => {
-      this.childTabs = childQuery.first;
-    });
-    this.events = events;
+
     this.selectedLang = this.events.samplesLanguageChanged;
   }
 
diff --git a/lib/components/ResponsesList/responses-list.js b/lib/components/ResponsesList/responses-list.ts
similarity index 87%
rename from lib/components/ResponsesList/responses-list.js
rename to lib/components/ResponsesList/responses-list.ts
index 473fae84..aa80497c 100644
--- a/lib/components/ResponsesList/responses-list.js
+++ b/lib/components/ResponsesList/responses-list.ts
@@ -14,14 +14,15 @@ function isNumeric(n) {
 
 @RedocComponent({
   selector: 'responses-list',
-  templateUrl: './lib/components/ResponsesList/responses-list.html',
-  styleUrls: ['./lib/components/ResponsesList/responses-list.css'],
+  templateUrl: './responses-list.html',
+  styleUrls: ['./responses-list.css'],
   directives: [JsonSchema, Zippy, JsonSchemaLazy],
   detect: true
 })
-@Reflect.metadata('parameters', [[SchemaManager], [OptionsService]])
 export class ResponsesList extends BaseComponent {
-  constructor(schemaMgr, optionsMgr) {
+  data: any;
+  options: any;
+  constructor(schemaMgr:SchemaManager, optionsMgr:OptionsService) {
     super(schemaMgr);
     this.options = optionsMgr.options;
   }
diff --git a/lib/components/ResponsesSamples/responses-samples.js b/lib/components/ResponsesSamples/responses-samples.ts
similarity index 85%
rename from lib/components/ResponsesSamples/responses-samples.js
rename to lib/components/ResponsesSamples/responses-samples.ts
index 3515f5e9..ab1d0827 100644
--- a/lib/components/ResponsesSamples/responses-samples.js
+++ b/lib/components/ResponsesSamples/responses-samples.ts
@@ -1,7 +1,7 @@
 'use strict';
 
 import { forwardRef } from '@angular/core';
-import { RedocComponent, BaseComponent } from '../base';
+import { RedocComponent, BaseComponent, SchemaManager } from '../base';
 import JsonPointer from '../../utils/JsonPointer';
 import { Tabs, Tab } from '../../shared/components/index';
 import { SchemaSample } from '../index';
@@ -19,12 +19,13 @@ function hasExample(response) {
 
 @RedocComponent({
   selector: 'responses-samples',
-  templateUrl: './lib/components/ResponsesSamples/responses-samples.html',
-  styleUrls: ['./lib/components/ResponsesSamples/responses-samples.css'],
+  templateUrl: './responses-samples.html',
+  styleUrls: ['./responses-samples.css'],
   directives: [forwardRef( ()=> SchemaSample), Tabs, Tab]
 })
 export class ResponsesSamples extends BaseComponent {
-  constructor(schemaMgr) {
+  data: any;
+  constructor(schemaMgr:SchemaManager) {
     super(schemaMgr);
   }
 
diff --git a/lib/components/SchemaSample/schema-sample.html b/lib/components/SchemaSample/schema-sample.html
index 9fe51cae..bcdc23f0 100644
--- a/lib/components/SchemaSample/schema-sample.html
+++ b/lib/components/SchemaSample/schema-sample.html
@@ -1,5 +1,5 @@
 
-
 Sample unavailable 
+
 Sample unavailable 

 
diff --git a/lib/components/SchemaSample/schema-sample.js b/lib/components/SchemaSample/schema-sample.ts similarity index 76% rename from lib/components/SchemaSample/schema-sample.js rename to lib/components/SchemaSample/schema-sample.ts index 034d8fa4..0347be94 100644 --- a/lib/components/SchemaSample/schema-sample.js +++ b/lib/components/SchemaSample/schema-sample.ts @@ -1,6 +1,6 @@ 'use strict'; -import { ElementRef } from '@angular/core'; +import { ElementRef, Input } from '@angular/core'; import * as OpenAPISampler from 'openapi-sampler'; @@ -9,13 +9,15 @@ import { JsonFormatter } from '../../utils/JsonFormatterPipe'; @RedocComponent({ selector: 'schema-sample', - templateUrl: './lib/components/SchemaSample/schema-sample.html', + templateUrl: './schema-sample.html', pipes: [JsonFormatter], - styleUrls: ['./lib/components/SchemaSample/schema-sample.css'] + styleUrls: ['./schema-sample.css'] }) -@Reflect.metadata('parameters', [[SchemaManager], [ElementRef]]) export class SchemaSample extends BaseComponent { - constructor(schemaMgr, elementRef) { + element: any; + data: any; + @Input() skipReadOnly:boolean; + constructor(schemaMgr:SchemaManager, elementRef:ElementRef) { super(schemaMgr); this.element = elementRef.nativeElement; } @@ -23,7 +25,7 @@ export class SchemaSample extends BaseComponent { init() { this.data = {}; - let base = {}; + let base:any = {}; let sample; // got pointer not directly to the schema but e.g. to response obj @@ -37,9 +39,11 @@ export class SchemaSample extends BaseComponent { } else { this.dereference(this.componentSchema); try { - sample = OpenAPISampler.sample(this.componentSchema); + sample = OpenAPISampler.sample(this.componentSchema, { + skipReadOnly: this.skipReadOnly + }); } catch(e) { - console.error('@@@@@@@@@@@@@@@@@@@' + e); + // no sample available } } diff --git a/lib/components/SideMenu/side-menu.spec.js b/lib/components/SideMenu/side-menu.spec.ts similarity index 60% rename from lib/components/SideMenu/side-menu.spec.js rename to lib/components/SideMenu/side-menu.spec.ts index a43fc357..1d7ae5f2 100644 --- a/lib/components/SideMenu/side-menu.spec.js +++ b/lib/components/SideMenu/side-menu.spec.ts @@ -1,9 +1,8 @@ 'use strict'; -import { getChildDebugElement } from 'tests/helpers'; +import { getChildDebugElement } from '../../../tests/helpers'; import { Component, provide } from '@angular/core'; -import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter'; -import { OptionsService, RedocEventsService } from 'lib/services/index'; +import { OptionsService } from '../../services/index'; import { inject, @@ -15,17 +14,11 @@ import { import { TestComponentBuilder } from '@angular/compiler/testing'; -import { MethodsList, SideMenu } from 'lib/components/index'; +import { MethodsList, SideMenu } from '../index'; -import SchemaManager from 'lib/utils/SchemaManager'; +import { SchemaManager } from '../../utils/SchemaManager';; -let testOptions = new OptionsService(); -testOptions.options = { - scrollYOffset: () => 0, - scrollParent: window -}; - -let redocEvents = new RedocEventsService(); +let testOptions; describe('Redoc components', () => { describe('SideMenu Component', () => { @@ -33,18 +26,21 @@ describe('Redoc components', () => { let component; let fixture; beforeEachProviders(() => [ - provide(SchemaManager, {useValue: new SchemaManager()}), - provide(BrowserDomAdapter, {useValue: new BrowserDomAdapter()}), - provide(OptionsService, {useValue: testOptions}), - provide(RedocEventsService, {useValue: redocEvents}) + provide(SchemaManager, {useValue: new SchemaManager()}) ]); - beforeEach(async(inject([TestComponentBuilder, SchemaManager], (tcb, schemaMgr) => { + beforeEach(async(inject([TestComponentBuilder, SchemaManager, OptionsService], + (tcb, schemaMgr, opts) => { builder = tcb; + testOptions = opts; + testOptions.options = { + scrollYOffset: () => 0, + scrollParent: window + }; return schemaMgr.load('/tests/schemas/extended-petstore.yml'); }))); beforeEach((done) => { - builder.createAsync(TestApp).then(_fixture => { + builder.createAsync(TestAppComponent).then(_fixture => { fixture = _fixture; component = getChildDebugElement(fixture.debugElement, 'side-menu').componentInstance; fixture.detectChanges(); @@ -73,5 +69,5 @@ describe('Redoc components', () => { ` ` }) -class TestApp { +class TestAppComponent { } diff --git a/lib/components/SideMenu/side-menu.js b/lib/components/SideMenu/side-menu.ts similarity index 82% rename from lib/components/SideMenu/side-menu.js rename to lib/components/SideMenu/side-menu.ts index 9834f61b..3a793d68 100644 --- a/lib/components/SideMenu/side-menu.js +++ b/lib/components/SideMenu/side-menu.ts @@ -9,29 +9,31 @@ import { ScrollService, Hash, MenuService, OptionsService } from '../../services @RedocComponent({ selector: 'side-menu', - templateUrl: './lib/components/SideMenu/side-menu.html', + templateUrl: './side-menu.html', providers: [ScrollService, MenuService, Hash], - styleUrls: ['./lib/components/SideMenu/side-menu.css'], + styleUrls: ['./side-menu.css'], detect: true, onPushOnly: false }) -@Reflect.metadata('parameters', [[SchemaManager], [ElementRef], [BrowserDomAdapter], - [ScrollService], [MenuService], [Hash], [OptionsService], [ChangeDetectorRef]]) export class SideMenu extends BaseComponent { - constructor(schemaMgr, elementRef, dom, scrollService, - menuService, hash, optionsService, detectorRef) { + $element: any; + $mobileNav: any; + $resourcesNav: any; + $scrollParent: any; + activeCatCaption: string; + activeItemCaption: string; + options: any; + data: any; + constructor(schemaMgr:SchemaManager, elementRef:ElementRef, private dom:BrowserDomAdapter, + private scrollService:ScrollService, private menuService:MenuService, private hash:Hash, + optionsService:OptionsService, private detectorRef:ChangeDetectorRef) { super(schemaMgr); this.$element = elementRef.nativeElement; - this.dom = dom; - this.scrollService = scrollService; - this.menuService = menuService; - this.hash = hash; this.activeCatCaption = ''; this.activeItemCaption = ''; this.options = optionsService.options; - this.detectorRef = detectorRef; this.menuService.changed.subscribe((evt) => this.changed(evt)); } diff --git a/lib/components/base.spec.js b/lib/components/base.spec.ts similarity index 96% rename from lib/components/base.spec.js rename to lib/components/base.spec.ts index 6038dbbd..ae70221d 100644 --- a/lib/components/base.spec.js +++ b/lib/components/base.spec.ts @@ -1,7 +1,7 @@ 'use strict'; -import SchemaManager from 'lib/utils/SchemaManager'; -import { BaseComponent } from 'lib/components/base'; +import { SchemaManager } from '../utils/SchemaManager'; +import { BaseComponent } from '../components/base'; describe('Redoc components', () => { describe('BaseComponent', () => { @@ -30,11 +30,14 @@ describe('Redoc components', () => { }); it('should call prepareModel and init virtual methods after init', () => { - sinon.spy(component, 'prepareModel'); - sinon.spy(component, 'init'); + spyOn(component, 'prepareModel'); + spyOn(component, 'init'); component.ngOnInit(); - component.prepareModel.calledOnce.should.be.true; - component.init.calledOnce.should.be.true; + + component.prepareModel.calls.count().should.be.equal(1); + component.init.calls.count().should.be.equal(1); + component.prepareModel.and.callThrough(); + component.init.and.callThrough(); }); describe('dereference', () => { @@ -281,6 +284,7 @@ describe('Redoc components', () => { }); xdescribe('Merge array allOf', () => { + //emtpy }); }); }); diff --git a/lib/components/base.js b/lib/components/base.ts similarity index 90% rename from lib/components/base.js rename to lib/components/base.ts index 38bd2b57..f3d6fdf8 100644 --- a/lib/components/base.js +++ b/lib/components/base.ts @@ -1,7 +1,7 @@ 'use strict'; -import { Component, ChangeDetectionStrategy } from '@angular/core'; +import { Component, ChangeDetectionStrategy, OnInit, OnDestroy } from '@angular/core'; import { CORE_DIRECTIVES, JsonPipe, AsyncPipe } from '@angular/common'; -import SchemaManager from '../utils/SchemaManager'; +import { SchemaManager } from '../utils/SchemaManager'; import JsonPointer from '../utils/JsonPointer'; import { MarkedPipe, JsonPointerEscapePipe } from '../utils/pipes'; @@ -13,7 +13,7 @@ let commonInputs = ['pointer']; // json pointer to the schema chunk // internal helper function function safeConcat(a, b) { let res = a && a.slice() || []; - b = (b == null) ? [] : b; + b = (b == undefined) ? [] : b; return res.concat(b); } @@ -33,7 +33,7 @@ function defaults(target, src) { } function snapshot(obj) { - if(obj == null || typeof(obj) != 'object') { + if(obj == undefined || typeof(obj) !== 'object') { return obj; } @@ -94,11 +94,74 @@ export function RedocComponent(options) { * Generic Component * @class */ -@Reflect.metadata('parameters', [[SchemaManager]]) -export class BaseComponent { - constructor(schemaMgr) { - this.schemaMgr = schemaMgr; - this.componentSchema = null; +export class BaseComponent implements OnInit, OnDestroy { + componentSchema: any = null; + pointer: String; + + static joinAllOf(schema: any, opts?: any) { + function merge(into, schemas) { + for (let subSchema of schemas) { + if (opts && opts.omitParent && subSchema.discriminator) continue; + // TODO: add support for merge array schemas + if (typeof subSchema !== 'object') { + let errMessage = `Items of allOf should be Object: ${typeof subSchema} found + ${subSchema}`; + throw new Error(errMessage); + } + + if (into.type && subSchema.type && into.type !== subSchema.type) { + let errMessage = `allOf merging error: schemas with different types can't be merged`; + throw new Error(errMessage); + } + + + if (into.type === 'array') { + console.warn('allOf: subschemas with type array are not supported yet'); + } + + // TODO: add check if can be merged correctly (no different properties with the same name) + into.type = into.type || subSchema.type; + if (into.type === 'object' && subSchema.properties) { + if (!into.properties) into.properties = {}; + Object.assign(into.properties, subSchema.properties); + Object.keys(subSchema.properties).forEach(propName => { + if (!subSchema.properties[propName]._pointer) { + subSchema.properties[propName]._pointer = subSchema._pointer ? + JsonPointer.join(subSchema._pointer, ['properties', propName]) : null; + } + }); + } + if (into.type === 'object' && subSchema.required) { + if (!into.required) into.required = []; + into.required.push(...subSchema.required); + } + // don't merge _pointer + subSchema._pointer = null; + defaults(into, subSchema); + } + into.allOf = null; + } + + function traverse(obj) { + if (obj == undefined || typeof(obj) !== 'object') { + return; + } + + for(var key in obj) { + if (obj.hasOwnProperty(key)) { + traverse(obj[key]); + } + } + + if (obj.allOf) { + merge(obj, obj.allOf); + } + } + + traverse(schema); + } + + constructor(public schemaMgr: SchemaManager) { } /** @@ -166,87 +229,30 @@ export class BaseComponent { return schema; }; - this.componentSchema = snapshot(resolve(schema, 1)); - } - - static joinAllOf(schema, opts) { - function merge(into, schemas) { - for (let subSchema of schemas) { - if (opts && opts.omitParent && subSchema.discriminator) continue; - // TODO: add support for merge array schemas - if (typeof subSchema !== 'object') { - let errMessage = `Items of allOf should be Object: ${typeof subSchema} found - ${subSchema}`; - throw new Error(errMessage); - } - - if (into.type && subSchema.type && into.type !== subSchema.type) { - let errMessage = `allOf merging error: schemas with different types can't be merged`; - throw new Error(errMessage); - } - - - if (into.type === 'array') { - console.warn('allOf: subschemas with type array are not supported yet'); - } - - // TODO: add check if can be merged correctly (no different properties with the same name) - into.type = into.type || subSchema.type; - if (into.type === 'object' && subSchema.properties) { - into.properties || (into.properties = {}); - Object.assign(into.properties, subSchema.properties); - Object.keys(subSchema.properties).forEach(propName => { - if (!subSchema.properties[propName]._pointer) { - subSchema.properties[propName]._pointer = subSchema._pointer ? - JsonPointer.join(subSchema._pointer, ['properties', propName]) : null; - } - }); - } - if (into.type === 'object' && subSchema.required) { - into.required || (into.required = []); - into.required.push(...subSchema.required); - } - // don't merge _pointer - subSchema._pointer = null; - defaults(into, subSchema); - } - into.allOf = null; - } - - function traverse(obj) { - if (obj === null || typeof(obj) !== 'object') { - return; - } - - for(var key in obj) { - if (obj.hasOwnProperty(key)) { - traverse(obj[key]); - } - } - - if (obj.allOf) { - merge(obj, obj.allOf); - } - } - - traverse(schema); + this.componentSchema = snapshot(resolve(schema)); } /** * Used to prepare model based on component schema * @abstract */ - prepareModel() {} + prepareModel():any { + // emtpy + } /** * Used to initialize component. Run after prepareModel * @abstract */ - init() {} + init() { + // empty + } /** + Used to destroy component * @abstract */ - destroy() {} + destroy() { + // emtpy + } } diff --git a/lib/components/index.js b/lib/components/index.ts similarity index 100% rename from lib/components/index.js rename to lib/components/index.ts diff --git a/lib/index.js b/lib/index.js index 1a0b8775..6d97e58e 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,7 +1,12 @@ 'use strict'; +import 'dropkickjs/build/css/dropkick.css!css'; +import 'prismjs/themes/prism-dark.css!css'; +import 'hint.css/hint.base.css!css'; +import './components/Redoc/redoc-initial-styles.css!css'; + +import { Redoc } from './components/index'; -import {Redoc} from './components/index'; export var init = Redoc.init; -window.Redoc = Redoc; +window['Redoc'] = Redoc; Redoc.autoInit(); diff --git a/lib/services/events.service.js b/lib/services/events.service.js deleted file mode 100644 index 57cf41f9..00000000 --- a/lib/services/events.service.js +++ /dev/null @@ -1,10 +0,0 @@ -'use strict'; - -import { EventEmitter } from '@angular/core'; - -export class RedocEventsService { - constructor() { - this.bootstrapped = new EventEmitter(); - this.samplesLanguageChanged = new EventEmitter(); - } -} diff --git a/lib/services/events.service.ts b/lib/services/events.service.ts new file mode 100644 index 00000000..0bc86e1d --- /dev/null +++ b/lib/services/events.service.ts @@ -0,0 +1,8 @@ +'use strict'; + +import { EventEmitter, Output } from '@angular/core'; + +export class RedocEventsService { + @Output() bootstrapped = new EventEmitter(); + @Output() samplesLanguageChanged = new EventEmitter(); +} diff --git a/lib/services/hash.service.spec.js b/lib/services/hash.service.spec.ts similarity index 95% rename from lib/services/hash.service.spec.js rename to lib/services/hash.service.spec.ts index 80fba625..9086ab32 100644 --- a/lib/services/hash.service.spec.js +++ b/lib/services/hash.service.spec.ts @@ -19,7 +19,7 @@ describe('Hash Service', () => { it('should trigger changed event after ReDoc bootstrapped', (done) => { spyOn(hashService.changed, 'next').and.callThrough(); - events.bootstrapped.next(); + events.bootstrapped.next({}); setTimeout(() => { expect(hashService.changed.next).toHaveBeenCalled(); done(); diff --git a/lib/services/hash.service.js b/lib/services/hash.service.ts similarity index 73% rename from lib/services/hash.service.js rename to lib/services/hash.service.ts index 588df861..a61fc392 100644 --- a/lib/services/hash.service.js +++ b/lib/services/hash.service.ts @@ -1,16 +1,15 @@ 'use strict'; -import { Injectable, EventEmitter } from '@angular/core'; +import { Injectable, EventEmitter, Output } from '@angular/core'; import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter'; import { global } from '@angular/core/src/facade/lang'; import { RedocEventsService } from './events.service'; -@Reflect.metadata('parameters', [[BrowserDomAdapter], [RedocEventsService]]) @Injectable() export class Hash { - constructor(dom, events) { - this.changed = new EventEmitter(); - this.dom = dom; + @Output() changed = new EventEmitter(); + private _cancel: any; + constructor(private dom:BrowserDomAdapter, private events:RedocEventsService) { this.bind(); events.bootstrapped.subscribe(() => this.changed.next(this.hash)); diff --git a/lib/services/index.js b/lib/services/index.js deleted file mode 100644 index c9962f48..00000000 --- a/lib/services/index.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict'; - -export * from './events.service.js'; -export * from './options.service.js'; -export * from './menu.service.js'; -export * from './scroll.service.js'; -export * from './hash.service.js'; diff --git a/lib/services/index.ts b/lib/services/index.ts new file mode 100644 index 00000000..fed26281 --- /dev/null +++ b/lib/services/index.ts @@ -0,0 +1,7 @@ +'use strict'; + +export * from './events.service'; +export * from './options.service'; +export * from './menu.service'; +export * from './scroll.service'; +export * from './hash.service'; diff --git a/lib/services/menu.service.spec.js b/lib/services/menu.service.spec.ts similarity index 90% rename from lib/services/menu.service.spec.js rename to lib/services/menu.service.spec.ts index 62c70384..3adafe2c 100644 --- a/lib/services/menu.service.spec.js +++ b/lib/services/menu.service.spec.ts @@ -16,8 +16,8 @@ import { MenuService } from './menu.service'; import { Hash } from './hash.service'; import { ScrollService } from './scroll.service'; import { RedocEventsService } from './events.service'; -import { MethodsList } from 'lib/components/index'; -import SchemaManager from 'lib/utils/SchemaManager'; +import { MethodsList } from '../components/index'; +import { SchemaManager } from '../utils/SchemaManager';; describe('Menu service', () => { let menu, hashService, scroll; @@ -50,7 +50,7 @@ describe('Menu service', () => { }); beforeEach((done) => { - builder.createAsync(TestApp).then((fixture) => { + builder.createAsync(TestAppComponent).then((fixture) => { fixture.detectChanges(); done(); }).catch((err) => done.fail(err)); @@ -73,9 +73,9 @@ describe('Menu service', () => { spyOn(window, 'scrollTo').and.stub(); hashService.changed.subscribe(() => { expect(menu.hashScroll).toHaveBeenCalled(); - let scrollY = window.scrollTo.calls.argsFor(0)[1]; + let scrollY = (window.scrollTo).calls.argsFor(0)[1]; expect(scrollY).toBeGreaterThan(0); - window.scrollTo.and.callThrough(); + (window.scrollTo).and.callThrough(); done(); }); hashService.changed.next(hash); @@ -87,7 +87,7 @@ describe('Menu service', () => { spyOn(window, 'scrollTo').and.stub(); hashService.changed.subscribe(() => { expect(menu.hashScroll).toHaveBeenCalled(); - let scrollY = window.scrollTo.calls.argsFor(0)[1]; + let scrollY = (window.scrollTo).calls.argsFor(0)[1]; expect(scrollY).toBeGreaterThan(0); done(); }); @@ -122,5 +122,5 @@ describe('Menu service', () => { ` }) -class TestApp { +class TestAppComponent { } diff --git a/lib/services/menu.service.js b/lib/services/menu.service.ts similarity index 91% rename from lib/services/menu.service.js rename to lib/services/menu.service.ts index 5c2ea128..880cf777 100644 --- a/lib/services/menu.service.js +++ b/lib/services/menu.service.ts @@ -1,8 +1,8 @@ 'use strict'; import { Injectable, EventEmitter } from '@angular/core'; -import { ScrollService, INVIEW_POSITION } from './scroll.service.js'; -import { Hash } from './hash.service.js'; -import SchemaManager from '../utils/SchemaManager'; +import { ScrollService, INVIEW_POSITION } from './scroll.service'; +import { Hash } from './hash.service'; +import { SchemaManager } from '../utils/SchemaManager'; const CHANGE = { NEXT : 1, @@ -10,16 +10,17 @@ const CHANGE = { INITIAL : 0 }; -@Reflect.metadata('parameters', [[Hash], [ScrollService], [SchemaManager]]) @Injectable() export class MenuService { - constructor(hash, scrollService, schemaMgr) { - this.hash = hash; - this.scrollService = scrollService; + changed: EventEmitter = new EventEmitter(); + categories: any; - this.activeCatIdx = 0; - this.activeMethodIdx = -1; - this.changed = new EventEmitter(); + activeCatIdx: number = 0; + activeMethodIdx: number = -1; + activeMethodPtr: string; + + constructor(private hash:Hash, private scrollService:ScrollService, schemaMgr:SchemaManager) { + this.hash = hash; this.categories = Array.from(schemaMgr.buildMenuTree().entries()).map( el => ({name: el[0], description: el[1].description, methods: el[1].methods}) diff --git a/lib/services/options.service.spec.js b/lib/services/options.service.spec.ts similarity index 100% rename from lib/services/options.service.spec.js rename to lib/services/options.service.spec.ts diff --git a/lib/services/options.service.js b/lib/services/options.service.ts similarity index 91% rename from lib/services/options.service.js rename to lib/services/options.service.ts index 71288bba..4ebcb511 100644 --- a/lib/services/options.service.js +++ b/lib/services/options.service.ts @@ -2,20 +2,20 @@ import { Injectable } from '@angular/core'; import { isFunction, isString } from '@angular/core/src/facade/lang'; import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter'; -import { global } from '@angular/core/src/facade/lang'; const defaults = { scrollYOffset: 0, disableLazySchemas: false, - debugMode: global && global.redocDebugMode + debugMode: false//global && global.redocDebugMode }; const OPTION_NAMES = new Set(['scrollYOffset', 'disableLazySchemas', 'specUrl']); @Injectable() -@Reflect.metadata('parameters', [[BrowserDomAdapter]]) export class OptionsService { - constructor(dom) { + private _options: any; + + constructor(private dom:BrowserDomAdapter) { this._options = defaults; this.dom = dom; } diff --git a/lib/services/scroll.service.js b/lib/services/scroll.service.ts similarity index 78% rename from lib/services/scroll.service.js rename to lib/services/scroll.service.ts index 6daa83fb..4d9a9198 100644 --- a/lib/services/scroll.service.js +++ b/lib/services/scroll.service.ts @@ -1,7 +1,7 @@ 'use strict'; -import { Injectable, EventEmitter } from '@angular/core'; +import { Injectable, EventEmitter, Output } from '@angular/core'; import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter'; -import { OptionsService } from './options.service.js'; +import { OptionsService } from './options.service'; export const INVIEW_POSITION = { ABOVE : 1, @@ -9,11 +9,14 @@ export const INVIEW_POSITION = { INVIEW: 0 }; -@Reflect.metadata('parameters', [ - [BrowserDomAdapter], [OptionsService]]) @Injectable() export class ScrollService { - constructor(dom, optionsService) { + scrollYOffset: any; + $scrollParent: any; + @Output() scroll = new EventEmitter(); + private prevOffsetY: number; + private _cancel:any; + constructor(private dom:BrowserDomAdapter, optionsService:OptionsService) { //events.bootstrapped.subscribe(() => this.hashScroll()); this.scrollYOffset = () => optionsService.options.scrollYOffset(); this.$scrollParent = optionsService.options.$scrollParent; @@ -23,7 +26,7 @@ export class ScrollService { } scrollY() { - return (this.$scrollParent.pageYOffset != null) ? this.$scrollParent.pageYOffset : this.$scrollParent.scrollTop; + return (this.$scrollParent.pageYOffset != undefined) ? this.$scrollParent.pageYOffset : this.$scrollParent.scrollTop; } /* returns 1 if element if above the view, 0 if in view and -1 below the view */ diff --git a/lib/shared/components/DropDown/drop-down.js b/lib/shared/components/DropDown/drop-down.js deleted file mode 100644 index 349dd0a3..00000000 --- a/lib/shared/components/DropDown/drop-down.js +++ /dev/null @@ -1,37 +0,0 @@ -'use strict'; - -import {Component, EventEmitter, ElementRef} from '@angular/core'; -import {CORE_DIRECTIVES} from '@angular/common'; -import DropKick from 'Robdel12/DropKick'; -import 'Robdel12/DropKick/build/css/dropkick.css!css'; - -@Component({ - selector: 'dropdown', - events: ['change'], - template: ` - - `, - directives: [CORE_DIRECTIVES], - styleUrls: ['./lib/shared/components/DropDown/drop-down.css'] -}) -@Reflect.metadata('parameters', [[ElementRef]]) -export class DropDown { - constructor(elem) { - this.change = new EventEmitter(); - this.elem = elem.nativeElement; - } - - ngAfterContentInit() { - this.inst = new DropKick(this.elem.firstElementChild, {autoWidth: true}); - } - - onChange(value) { - this.change.next(value); - } - - destroy() { - this.inst.dispose(); - } -} diff --git a/lib/shared/components/DropDown/drop-down.ts b/lib/shared/components/DropDown/drop-down.ts new file mode 100644 index 00000000..17a05eb0 --- /dev/null +++ b/lib/shared/components/DropDown/drop-down.ts @@ -0,0 +1,36 @@ +'use strict'; + +import { Component, EventEmitter, ElementRef, Output, AfterContentInit } from '@angular/core'; +import { CORE_DIRECTIVES } from '@angular/common'; +import DropKick from 'dropkickjs'; + +@Component({ + selector: 'drop-down', + template: ` + + `, + directives: [CORE_DIRECTIVES], + styleUrls: ['./drop-down.css'] +}) +export class DropDown implements AfterContentInit { + @Output() change = new EventEmitter(); + elem: any; + inst: any; + constructor(elem:ElementRef) { + this.elem = elem.nativeElement; + } + + ngAfterContentInit() { + this.inst = new DropKick(this.elem.firstElementChild, {autoWidth: true}); + } + + onChange(value) { + this.change.next(value); + } + + destroy() { + this.inst.dispose(); + } +} diff --git a/lib/shared/components/StickySidebar/sticky-sidebar.spec.js b/lib/shared/components/StickySidebar/sticky-sidebar.spec.ts similarity index 93% rename from lib/shared/components/StickySidebar/sticky-sidebar.spec.js rename to lib/shared/components/StickySidebar/sticky-sidebar.spec.ts index 5cebe3ff..a35fdea5 100644 --- a/lib/shared/components/StickySidebar/sticky-sidebar.spec.js +++ b/lib/shared/components/StickySidebar/sticky-sidebar.spec.ts @@ -1,6 +1,6 @@ 'use strict'; -import { getChildDebugElementByType } from 'tests/helpers'; +import { getChildDebugElementByType } from '../../../../tests/helpers'; import { Component, provide } from '@angular/core'; import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter'; @@ -13,7 +13,7 @@ import { import { TestComponentBuilder } from '@angular/compiler/testing'; -import { StickySidebar } from 'lib/shared/components/index'; +import { StickySidebar } from '../index'; describe('Common components', () => { describe('StickySidebar Component', () => { @@ -75,6 +75,8 @@ describe('Common components', () => { }) class TestApp { + options: any; + scrollParent: Window; constructor() { this.options = {}; this.scrollParent = window; diff --git a/lib/shared/components/StickySidebar/sticky-sidebar.js b/lib/shared/components/StickySidebar/sticky-sidebar.ts similarity index 62% rename from lib/shared/components/StickySidebar/sticky-sidebar.js rename to lib/shared/components/StickySidebar/sticky-sidebar.ts index 6aa8a274..7f9c7a9c 100644 --- a/lib/shared/components/StickySidebar/sticky-sidebar.js +++ b/lib/shared/components/StickySidebar/sticky-sidebar.ts @@ -1,17 +1,20 @@ 'use strict'; -import {Directive, ElementRef} from '@angular/core'; +import { Directive, ElementRef, Input, OnInit, OnDestroy } from '@angular/core'; import {BrowserDomAdapter} from '@angular/platform-browser/src/browser/browser_adapter'; @Directive({ - selector: '[sticky-sidebar]', - inputs: ['scrollParent', 'scrollYOffset'] + selector: '[sticky-sidebar]' }) -@Reflect.metadata('parameters', [[ElementRef], [BrowserDomAdapter]]) -export class StickySidebar { - constructor(elementRef, dom) { +export class StickySidebar implements OnInit, OnDestroy { + $element: any; + cancelScrollBinding: any; + $redocEl: any; + @Input() scrollParent:any; + @Input() scrollYOffset:any; + + constructor(elementRef:ElementRef, private dom:BrowserDomAdapter) { this.$element = elementRef.nativeElement; - this.dom = dom; // initial styling this.dom.setStyle(this.$element, 'position', 'absolute'); @@ -26,7 +29,7 @@ export class StickySidebar { } unbind() { - this.cancelScrollBinding && this.cancelScrollBinding(); + if (this.cancelScrollBinding) this.cancelScrollBinding(); } updatePosition() { @@ -44,16 +47,16 @@ export class StickySidebar { unstick() { this.dom.setStyle(this.$element, 'position', 'absolute'); - this.dom.setStyle(this.$element, 'top', 0); + this.dom.setStyle(this.$element, 'top', '0'); } get scrollY() { - return (this.scrollParent.pageYOffset != null) ? this.scrollParent.pageYOffset : this.scrollParent.scrollTop; + return (this.scrollParent.pageYOffset != undefined) ? this.scrollParent.pageYOffset : this.scrollParent.scrollTop; } ngOnInit() { // FIXME use more reliable code - this.$redocEl = this.$element.offsetParent; + this.$redocEl = this.$element.offsetParent || this.dom.defaultDoc().body; this.bind(); } diff --git a/lib/shared/components/Tabs/tabs.spec.js b/lib/shared/components/Tabs/tabs.spec.ts similarity index 95% rename from lib/shared/components/Tabs/tabs.spec.js rename to lib/shared/components/Tabs/tabs.spec.ts index 7b3e55ea..05a1f196 100644 --- a/lib/shared/components/Tabs/tabs.spec.js +++ b/lib/shared/components/Tabs/tabs.spec.ts @@ -1,7 +1,7 @@ 'use strict'; -import { getChildDebugElement, getChildDebugElementAll } from 'tests/helpers'; -import {Component} from '@angular/core'; +import { getChildDebugElement, getChildDebugElementAll } from '../../../../tests/helpers'; +import { Component } from '@angular/core'; import { inject, @@ -11,7 +11,7 @@ import { import { TestComponentBuilder } from '@angular/compiler/testing'; -import {Tabs, Tab} from 'lib/shared/components/index'; +import {Tabs, Tab} from '../index'; describe('Common components', () => { describe('Tabs Component', () => { @@ -148,6 +148,7 @@ describe('Common components', () => {
` }) class TestApp { + eventLog: any; constructor() { this.eventLog = []; } diff --git a/lib/shared/components/Tabs/tabs.js b/lib/shared/components/Tabs/tabs.ts similarity index 73% rename from lib/shared/components/Tabs/tabs.js rename to lib/shared/components/Tabs/tabs.ts index 5cf174ec..386d87ca 100644 --- a/lib/shared/components/Tabs/tabs.js +++ b/lib/shared/components/Tabs/tabs.ts @@ -1,13 +1,11 @@ 'use strict'; -import { Component, EventEmitter } from '@angular/core'; +import { Component, EventEmitter, Input, Output, OnInit } from '@angular/core'; import { CORE_DIRECTIVES } from '@angular/common'; import { ChangeDetectorRef, ChangeDetectionStrategy } from '@angular/core'; @Component({ selector: 'tabs', - events: ['change'], - inputs: ['selected'], template: `
  • `, directives: [CORE_DIRECTIVES], - styleUrls: ['./lib/shared/components/Tabs/tabs.css'], + styleUrls: ['tabs.css'], changeDetection: ChangeDetectionStrategy.OnPush }) -@Reflect.metadata('parameters', [[ChangeDetectorRef]]) -export class Tabs { - constructor(changeDetector) { - this.tabs = []; - this.change = new EventEmitter(); - this.changeDetector = changeDetector; - } +export class Tabs implements OnInit { + @Input() selected: any; + @Output() change = new EventEmitter(); + tabs: Tab[] = []; + constructor(private changeDetector:ChangeDetectorRef) {} selectTab(tab, notify = true) { if (tab.active) return; @@ -33,7 +29,7 @@ export class Tabs { tab.active = false; }); tab.active = true; - notify && this.change.next(tab.tabTitle); + if (notify) this.change.next(tab.tabTitle); } selectyByTitle(tabTitle, notify = false) { @@ -51,7 +47,7 @@ export class Tabs { } else { prevActive.active = true; } - notify && this.change.next(tabTitle); + if (notify) this.change.next(tabTitle); this.changeDetector.markForCheck(); } @@ -69,7 +65,6 @@ export class Tabs { @Component({ selector: 'tab', - inputs: ['tabTitle', 'tabStatus'], template: `
    @@ -86,10 +81,11 @@ export class Tabs { }` ] }) -@Reflect.metadata('parameters', [ [Tabs] ]) export class Tab { - constructor(tabs) { - this.active = false; + @Input() active: boolean = false; + @Input() tabTitle: string; + @Input() tabStatus: string; + constructor(tabs: Tabs) { tabs.addTab(this); } } diff --git a/lib/shared/components/Zippy/zippy.js b/lib/shared/components/Zippy/zippy.js deleted file mode 100644 index 9fdc2a65..00000000 --- a/lib/shared/components/Zippy/zippy.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict'; - -import {Component, EventEmitter} from '@angular/core'; -import {CORE_DIRECTIVES} from '@angular/common'; - -@Component({ - selector: 'zippy', - events: ['open', 'close'], - inputs: ['title', 'visible', 'type', 'empty'], - templateUrl: './lib/shared/components/Zippy/zippy.html', - styleUrls: ['./lib/shared/components/Zippy/zippy.css'], - directives: [CORE_DIRECTIVES] -}) -export class Zippy { - - constructor() { - this.type = 'general'; - this.visible = false; - this.empty = false; - this.open = new EventEmitter(); - this.close = new EventEmitter(); - } - - toggle() { - this.visible = !this.visible; - if (this.empty) return; - (this.visible) ? this.open.next() : this.close.next(); - } -} diff --git a/lib/shared/components/Zippy/zippy.spec.js b/lib/shared/components/Zippy/zippy.spec.ts similarity index 74% rename from lib/shared/components/Zippy/zippy.spec.js rename to lib/shared/components/Zippy/zippy.spec.ts index b3c41dd4..7be746b1 100644 --- a/lib/shared/components/Zippy/zippy.spec.js +++ b/lib/shared/components/Zippy/zippy.spec.ts @@ -1,16 +1,17 @@ 'use strict'; -import { getChildDebugElement, mouseclick } from 'tests/helpers'; +import { getChildDebugElement, mouseclick } from '../../../../tests/helpers'; import { Component } from '@angular/core'; import { inject, beforeEach, - it + it, + expect } from '@angular/core/testing'; import { TestComponentBuilder } from '@angular/compiler/testing'; -import { Zippy } from 'lib/shared/components/index'; +import { Zippy } from '../index'; describe('Common components', () => { describe('Zippy Component', () => { @@ -38,15 +39,15 @@ describe('Common components', () => { }); it('should init component defaults', () => { - component.empty.should.be.false; - component.visible.should.be.false; + component.empty.should.be.false(); + component.visible.should.be.false(); component.type.should.be.equal('general'); }); it('should init properties from dom params', () => { fixture.detectChanges(); - component.visible.should.be.true; - component.empty.should.be.true; + component.visible.should.be.true(); + component.empty.should.be.true(); component.title.should.be.equal('Zippy'); component.type.should.be.equal('test'); }); @@ -54,10 +55,10 @@ describe('Common components', () => { it('project inner content', () => { fixture.detectChanges(); let contentEl = nativeElement.querySelector('.zippy-content'); - expect(contentEl).toHaveText('\n test\n '); + expect(contentEl.innerText).toMatch('test'); }); - it('should open and close zippy', () => { + it('should open and close zippy', (done) => { fixture.detectChanges(); component.empty = false; component.visible = true; @@ -68,13 +69,17 @@ describe('Common components', () => { let titleEl = nativeElement.querySelector('.zippy-title'); mouseclick(titleEl); fixture.detectChanges(); - component.visible.should.be.false; - testComponent.opened.should.be.false; + component.visible.should.be.false(); + testComponent.opened.should.be.false(); mouseclick(titleEl); fixture.detectChanges(); - component.visible.should.be.true; - testComponent.opened.should.be.true; + setTimeout(() => { + component.visible.should.be.true(); + testComponent.opened.should.be.true(); + testComponent.clickCount.should.be.equal(2); + done(); + }); }); it('should disable empty zippy', () => { @@ -98,9 +103,11 @@ describe('Common components', () => { selector: 'test-app', directives: [Zippy], template: - `test` + `test` }) class TestApp { + opened: boolean; + clickCount: number; constructor() { this.opened = false; this.clickCount = 0; diff --git a/lib/shared/components/Zippy/zippy.ts b/lib/shared/components/Zippy/zippy.ts new file mode 100644 index 00000000..f23ccc1f --- /dev/null +++ b/lib/shared/components/Zippy/zippy.ts @@ -0,0 +1,25 @@ +'use strict'; + +import { Component, EventEmitter, Output, Input } from '@angular/core'; +import { CORE_DIRECTIVES } from '@angular/common'; + +@Component({ + selector: 'zippy', + templateUrl: './zippy.html', + styleUrls: ['./zippy.css'], + directives: [CORE_DIRECTIVES] +}) +export class Zippy { + @Input() type = 'general'; + @Input() visible = false; + @Input() empty = false; + @Input() title; + @Output() open = new EventEmitter(); + @Output() close = new EventEmitter(); + + toggle() { + this.visible = !this.visible; + if (this.empty) return; + (this.visible) ? this.open.next({}) : this.close.next({}); + } +} diff --git a/lib/shared/components/index.js b/lib/shared/components/index.ts similarity index 100% rename from lib/shared/components/index.js rename to lib/shared/components/index.ts diff --git a/lib/utils/JsonFormatterPipe.js b/lib/utils/JsonFormatterPipe.ts similarity index 80% rename from lib/utils/JsonFormatterPipe.js rename to lib/utils/JsonFormatterPipe.ts index 08208ab1..d1270d0d 100644 --- a/lib/utils/JsonFormatterPipe.js +++ b/lib/utils/JsonFormatterPipe.ts @@ -1,12 +1,12 @@ 'use strict'; -import {Pipe} from '@angular/core'; -import {isBlank} from '@angular/core/src/facade/lang'; +import { Pipe, PipeTransform } from '@angular/core'; +import { isBlank } from '@angular/core/src/facade/lang'; var level = 1; const COLLAPSE_LEVEL = 2; @Pipe({ name: 'jsonFormatter' }) -export class JsonFormatter { +export class JsonFormatter implements PipeTransform { transform(value) { if (isBlank(value)) return value; return jsonToHTML(value); @@ -14,7 +14,8 @@ export class JsonFormatter { } function htmlEncode(t) { - return t != null ? t.toString().replace(/&/g, '&').replace(/"/g, '"').replace(//g, '>') : ''; + return t != undefined ? + t.toString().replace(/&/g, '&').replace(/"/g, '"').replace(//g, '>') : ''; } function decorateWithSpan(value, className) { @@ -23,25 +24,22 @@ function decorateWithSpan(value, className) { function valueToHTML(value) { var valueType = typeof value, output = ''; - if (value == null) { + if (value == undefined) { output += decorateWithSpan('null', 'type-null'); - } - else if (value && value.constructor === Array) { + } else if (value && value.constructor === Array) { level++; output += arrayToHTML(value); level--; - } - else if (valueType === 'object') { + } else if (valueType === 'object') { level++; output += objectToHTML(value); level--; - } - else if (valueType === 'number') { + } else if (valueType === 'number') { output += decorateWithSpan(value, 'type-number'); - } - else if (valueType === 'string') { + } else if (valueType === 'string') { if (/^(http|https):\/\/[^\\s]+$/.test(value)) { - output += decorateWithSpan('"', 'type-string') + '' + htmlEncode(value) + '' + decorateWithSpan('"', 'type-string'); + output += decorateWithSpan('"', 'type-string') + '' + htmlEncode(value) + '' + + decorateWithSpan('"', 'type-string'); } else { output += decorateWithSpan('"' + value + '"', 'type-string'); } diff --git a/lib/utils/JsonPointer.js b/lib/utils/JsonPointer.ts similarity index 77% rename from lib/utils/JsonPointer.js rename to lib/utils/JsonPointer.ts index 8dd8fc90..d6331c0a 100644 --- a/lib/utils/JsonPointer.js +++ b/lib/utils/JsonPointer.ts @@ -1,10 +1,12 @@ 'use strict'; import JsonPointerLib from 'json-pointer'; +const origParse = JsonPointerLib.parse; /** * Wrapper for JsonPointer. Provides common operations */ -export class JsonPointer extends JsonPointerLib { + +export class JsonPointer { /** * returns last JsonPointer token * if level > 1 returns levels last (second last/third last) @@ -30,7 +32,7 @@ export class JsonPointer extends JsonPointerLib { */ static dirName(pointer, level=1) { let tokens = JsonPointer.parse(pointer); - return JsonPointer.compile(tokens.slice(0, tokens.length - level)); + return JsonPointerLib.compile(tokens.slice(0, tokens.length - level)); } /** @@ -42,7 +44,7 @@ export class JsonPointer extends JsonPointerLib { if (ptr.charAt(0) === '#') { ptr = ptr.substring(1); } - return JsonPointerLib._origParse(ptr); + return origParse(ptr); } /** @@ -56,13 +58,21 @@ export class JsonPointer extends JsonPointerLib { // TODO: optimize let baseTokens = JsonPointer.parse(base); let resTokens = baseTokens.concat(tokens); - return JsonPointer.compile(resTokens); + return JsonPointerLib.compile(resTokens); + } + + static get(object: Object, pointer:string) { + return JsonPointerLib.get(object, pointer); + } + + static compile(tokens: string[]) { + return JsonPointerLib.compile(tokens); + } + + static escape(pointer: string) { + return JsonPointerLib.escape(pointer); } } - -JsonPointerLib._origParse = JsonPointerLib.parse; JsonPointerLib.parse = JsonPointer.parse; - - Object.assign(JsonPointer, JsonPointerLib); export default JsonPointer; diff --git a/lib/utils/SchemaManager.js b/lib/utils/SchemaManager.ts similarity index 96% rename from lib/utils/SchemaManager.js rename to lib/utils/SchemaManager.ts index ecef93df..b96d9ea4 100644 --- a/lib/utils/SchemaManager.js +++ b/lib/utils/SchemaManager.ts @@ -1,21 +1,24 @@ 'use strict'; + import JsonSchemaRefParser from 'json-schema-ref-parser'; import JsonPointer from './JsonPointer'; import {methods as swaggerMethods} from './swagger-defs'; -export default class SchemaManager { +export class SchemaManager { + public _schema:any = {}; + public apiUrl: string; + private _instance:any; + + static instance() { + return new SchemaManager(); + } + constructor() { if (SchemaManager.prototype._instance) { return SchemaManager.prototype._instance; } SchemaManager.prototype._instance = this; - - this._schema = {}; - } - - static instance() { - return new SchemaManager(); } load(url) { @@ -117,7 +120,7 @@ export default class SchemaManager { } /* returns ES6 Map */ - buildMenuTree() { + buildMenuTree():Map { let tag2MethodMapping = new Map(); let definedTags = this._schema.tags || []; @@ -142,7 +145,7 @@ export default class SchemaManager { tags = ['[Other]']; } let methodPointer = JsonPointer.compile(['paths', path, method]); - let methodSummary = methodInfo.summary; + let methodSummary = methodInfo.summary || methodInfo.operationId; for (let tag of tags) { let tagDetails = tag2MethodMapping.get(tag); if (!tagDetails) { diff --git a/lib/utils/browser-update.js b/lib/utils/browser-update.js index 7e08bc7c..bf54a275 100644 --- a/lib/utils/browser-update.js +++ b/lib/utils/browser-update.js @@ -7,4 +7,4 @@ function $buo_f(){ document.body.appendChild(e); } try {document.addEventListener('DOMContentLoaded', $buo_f, false);} -catch(e){window.attachEvent('onload', $buo_f);} +catch(e){window['attachEvent']('onload', $buo_f);} diff --git a/lib/utils/helpers.js b/lib/utils/helpers.ts similarity index 100% rename from lib/utils/helpers.js rename to lib/utils/helpers.ts diff --git a/lib/utils/pipes.js b/lib/utils/pipes.ts similarity index 76% rename from lib/utils/pipes.js rename to lib/utils/pipes.ts index fb30e0a9..ab09fbb8 100644 --- a/lib/utils/pipes.js +++ b/lib/utils/pipes.ts @@ -1,21 +1,18 @@ 'use strict'; -import {Pipe} from '@angular/core'; -import {isString, stringify, isBlank} from '@angular/core/src/facade/lang'; -import {BaseException} from '@angular/core/src/facade/exceptions'; -import {JsonPointer} from './JsonPointer'; +import { Pipe, PipeTransform } from '@angular/core'; +import { isString, stringify, isBlank } from '@angular/core/src/facade/lang'; +import { BaseException } from '@angular/core/src/facade/exceptions'; +import JsonPointer from './JsonPointer'; -import Prism from '../../prismjs-bundle'; - -import 'prismjs/themes/prism-dark.css!css'; -import 'hint.css/hint.base.css!css'; +declare var Prism: any; import marked from 'marked'; // in gfm mode marked doesn't parse #Heading (without space after #) as heading // https://github.com/chjj/marked/issues/642 -marked.Lexer.rules.gfm.heading = marked.Lexer.rules.normal.heading; -marked.Lexer.rules.tables.heading = marked.Lexer.rules.normal.heading; +marked['Lexer'].rules.gfm.heading = marked['Lexer'].rules.normal.heading; +marked['Lexer'].rules.tables.heading = marked['Lexer'].rules.normal.heading; marked.setOptions({ renderer: new marked.Renderer(), @@ -34,7 +31,7 @@ class InvalidPipeArgumentException extends BaseException { } @Pipe({ name: 'keys' }) -export class KeysPipe { +export class KeysPipe implements PipeTransform { transform(value) { if (isBlank(value)) return value; if (typeof value !== 'object') { @@ -45,7 +42,7 @@ export class KeysPipe { } @Pipe({ name: 'values' }) -export class ValuesPipe { +export class ValuesPipe implements PipeTransform { transform(value) { if (isBlank(value)) return value; if (typeof value !== 'object') { @@ -56,7 +53,7 @@ export class ValuesPipe { } @Pipe({ name: 'jsonPointerEscape' }) -export class JsonPointerEscapePipe { +export class JsonPointerEscapePipe implements PipeTransform { transform(value) { if (isBlank(value)) return value; if (!isString(value)) { @@ -67,7 +64,7 @@ export class JsonPointerEscapePipe { } @Pipe({ name: 'marked' }) -export class MarkedPipe { +export class MarkedPipe implements PipeTransform { transform(value) { if (isBlank(value)) return value; if (!isString(value)) { @@ -86,7 +83,7 @@ const langMap = { }; @Pipe({ name: 'prism' }) -export class PrismPipe { +export class PrismPipe implements PipeTransform { transform(value, args) { if (isBlank(args) || args.length === 0) { throw new BaseException('Prism pipe requires one argument'); @@ -106,7 +103,7 @@ export class PrismPipe { } @Pipe({ name: 'encodeURIComponent' }) -export class EncodeURIComponentPipe { +export class EncodeURIComponentPipe implements PipeTransform { transform(value) { if (isBlank(value)) return value; if (!isString(value)) { diff --git a/lib/utils/prismjs-bundle.ts b/lib/utils/prismjs-bundle.ts new file mode 100644 index 00000000..e69de29b diff --git a/lib/utils/swagger-defs.js b/lib/utils/swagger-defs.ts similarity index 100% rename from lib/utils/swagger-defs.js rename to lib/utils/swagger-defs.ts diff --git a/package.json b/package.json index 1f09a58a..39fb14df 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "redoc", "description": "Swagger-generated API Reference Documentation", - "version": "0.13.0", + "version": "0.14.0", "repository": { "type": "git", "url": "git://github.com/Rebilly/ReDoc" @@ -37,15 +37,14 @@ "@angular/core": "npm:@angular/core@^2.0.0-rc.1", "@angular/platform-browser": "npm:@angular/platform-browser@^2.0.0-rc.1", "@angular/platform-browser-dynamic": "npm:@angular/platform-browser-dynamic@^2.0.0-rc.1", - "Robdel12/DropKick": "github:Robdel12/DropKick@^2.1.7", + "dropkickjs": "npm:dropkickjs@^2.1.8", "es6-shim": "github:es-shims/es6-shim@^0.33.6", "hint.css": "npm:hint.css@^2.2.1", "json": "github:systemjs/plugin-json@^0.1.0", - "json-formatter-js": "npm:json-formatter-js@^0.2.0", "json-pointer": "npm:json-pointer@^0.3.0", "json-schema-ref-parser": "npm:json-schema-ref-parser@^3.1.2", "marked": "npm:marked@^0.3.5", - "openapi-sampler": "npm:openapi-sampler@^0.1.2", + "openapi-sampler": "npm:openapi-sampler@0.2.0", "prismjs": "npm:prismjs@^1.3.0", "rxjs": "npm:rxjs@5.0.0-beta.6", "scrollparent": "npm:scrollparent@^0.1.0", @@ -55,65 +54,92 @@ "devDependencies": { "babel": "npm:babel-core@^5.8.34", "babel-runtime": "npm:babel-runtime@^5.8.24", - "clean-css": "npm:clean-css@^3.4.6", + "clean-css": "npm:clean-css@^3.4.17", "core-js": "npm:core-js@^1.2.6", "css": "github:systemjs/plugin-css@^0.1.18", "systemjs/plugin-json": "github:systemjs/plugin-json@^0.1.0" }, "overrides": { - "github:Robdel12/DropKick@2.1.7": { - "format": "global" - }, - "npm:openapi-sampler@0.1.2": { + "npm:openapi-sampler@0.2.0": { "main": "src/openapi-sampler", "format": "esm" + }, + "npm:dropkickjs@2.1.8": { + "format": "global" + }, + "npm:json-schema-ref-parser@3.1.2": { + "map": { + "http": "stream-http", + "https": "stream-http" + } } } }, "devDependencies": { + "@angular/common": "2.0.0-rc.1", + "@angular/compiler": "2.0.0-rc.1", + "@angular/core": "2.0.0-rc.1", + "@angular/platform-browser": "2.0.0-rc.1", + "@angular/platform-browser-dynamic": "2.0.0-rc.1", + "@angular/platform-server": "2.0.0-rc.1", "babel-eslint": "^4.1.6", "babel-polyfill": "^6.3.14", - "branch-release": "^0.3.2", + "branch-release": "^1.0.3", "browser-sync": "^2.10.1", + "codelyzer": "0.0.23", + "coveralls": "^2.11.9", "del": "^2.2.0", "deploy-to-gh-pages": "^1.1.2", "gulp": "^3.9.1", "gulp-concat": "^2.6.0", "gulp-eslint": "^1.1.1", "gulp-if": "^2.0.1", - "gulp-inline-ng2-template": "^1.1.2", + "gulp-inline-ng2-template": "^1.1.5", "gulp-protractor": "^2.1.0", "gulp-rename": "^1.2.2", "gulp-replace": "^0.5.4", "gulp-sass": "^2.1.1", "gulp-sourcemaps": "^1.6.0", + "gulp-tslint": "^5.0.0", "isparta": "^4.0.0", "istanbul": "github:gotwarlost/istanbul#source-map", "jasmine-core": "^2.4.1", "jasmine-spec-reporter": "^2.4.0", - "jspm": "^0.16.34", + "json-pointer": "^0.5.0", + "json-schema-instantiator": "^0.3.0", + "json-schema-ref-parser": "^3.1.2", + "jspm": "^0.16.36", "karma": "^0.13.15", "karma-babel-preprocessor": "^5.2.2", "karma-chrome-launcher": "^0.2.2", "karma-coverage": "github:douglasduteil/karma-coverage#next", - "karma-coveralls": "^1.1.2", "karma-jasmine": "^0.3.6", - "karma-jspm": "^2.0.2", + "karma-jspm": "^2.1.1", "karma-mocha-reporter": "^2.0.0", "karma-phantomjs-launcher": "^1.0.0", "karma-phantomjs-shim": "^1.1.2", "karma-regex-preprocessor": "github:makern/karma-regex-preprocessor", "karma-should": "^1.0.0", "karma-sinon": "^1.0.4", + "marked": "^0.3.5", + "node-sass": "^3.7.0", + "openapi-sampler": "^0.2.0", "phantomjs-prebuilt": "^2.1.7", "protractor": "^3.0.0", "reflect-metadata": "^0.1.2", + "remap-istanbul": "^0.6.4", "require-dir": "^0.3.0", + "rollup-plugin-commonjs": "^2.2.1", "run-sequence": "^1.1.5", + "rxjs": "5.0.0-beta.6", + "scrollparent": "^1.0.0", "shelljs": "^0.7.0", "should": "^8.0.2", "sinon": "^1.17.2", "systemjs-builder": "^0.15.16", + "tslint": "^3.11.0", + "tslint-stylish": "^2.1.0-beta", + "typescript": "^1.8.10", "vinyl-paths": "^2.0.0", "yargs": "^4.7.1", "zone.js": "^0.6.12" diff --git a/protractor.conf.js b/protractor.conf.js index a8f30179..aac8415f 100644 --- a/protractor.conf.js +++ b/protractor.conf.js @@ -11,7 +11,7 @@ let config = { // add jasmine spec reporter jasmine.getEnv().addReporter(new SpecReporter({displaySpecDuration: true})); // load APIs.guru list - return loadJson('https://apis-guru.github.io/api-models/api/v1/list.json').then((list) => { + return loadJson('https://api.apis.guru/v2/list.json').then((list) => { global.apisGuruList = list; return browser.getCapabilities().then(function (cap) { browser.isIE = cap.browserName === 'internet explorer' diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 00000000..d2f27ae8 --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,58 @@ +import nodeResolve from 'rollup-plugin-node-resolve'; +import commonjs from 'rollup-plugin-commonjs'; + +class RollupNG2 { + constructor(options) { + this.options = options; + } + resolveId(id, from) { + if (id.startsWith('rxjs/')) { + return `${__dirname}/node_modules/rxjs-es/${id.replace('rxjs/', '')}.js`; + } + + if(id.startsWith('@angular/core')){ + if(id === '@angular/core'){ + return `${__dirname}/node_modules/@angular/core/esm/index.js`; + } + return `${__dirname}/node_modules/@angular/core/esm/${id.split('@angular/core').pop()}.js`; + } + if(id.startsWith('@angular/common')){ + if(id === '@angular/common'){ + return `${__dirname}/node_modules/@angular/common/esm/index.js`; + } + return `${__dirname}/node_modules/@angular/common/esm/${id.split('@angular/common').pop()}.js`; + } + if(id.startsWith('@angular/platform-browser-dynamic')){ + if(id === '@angular/platform-browser-dynamic'){ + return `${__dirname}/node_modules/@angular/platform-browser-dynamic/esm/index.js`; + } + return `${__dirname}/node_modules/@angular/platform-browser-dynamic/esm/${id.split('@angular/platform-browser-dynamic').pop()}.js`; + } + if(id.startsWith('@angular/platform-browser')){ + if(id === '@angular/platform-browser'){ + return `${__dirname}/node_modules/@angular/platform-browser/esm/index.js`; + } + return `${__dirname}/node_modules/@angular/platform-browser/esm/${id.split('@angular/platform-browser').pop()}.js`; + } + } +} + +const rollupNG2 = (config) => new RollupNG2(config); +export default { + entry: './.tmp-es/index.js', + dest: 'dist/vendor.es2015.js', + format: 'iife', + moduleName: 'ReDoc', + plugins: [ + //typescript(), + rollupNG2(), + nodeResolve({ jsnext: true, main: true, browser: true }), + commonjs({ + // non-CommonJS modules will be ignored, but you can also + // specifically include/exclude files + include: 'node_modules/**', // Default: undefined + exclude: [ 'node_modules/@angular/**', 'node_modules/rxjs/**', 'node_modules/rxjs-es/**' ], // Default: undefined + namedExports: { 'marked': ['marked'] } // Default: undefined + }) + ] +} \ No newline at end of file diff --git a/system.config.js b/system.config.js index 6ff4a4b0..0fe298f5 100644 --- a/system.config.js +++ b/system.config.js @@ -15,39 +15,18 @@ System.config({ "npm:*": "jspm_packages/npm/*" }, - packages: { - "npm:swagger-schema-official@2.0.0-bab6bed": { - "defaultExtension": "json", - "main": "schema.json", - "meta": { - "*": { - "loader": "json" - } - } - } - }, - - meta: { - "jspm_packages/npm/json-formatter-js@0.2.0/src/*": { - "format": "esm" - }, - "jspm_packages/npm/json-schema-view-js@0.2.0/src/*": { - "format": "esm" - } - }, - map: { "@angular/common": "npm:@angular/common@2.0.0-rc.1", "@angular/compiler": "npm:@angular/compiler@2.0.0-rc.1", "@angular/core": "npm:@angular/core@2.0.0-rc.1", "@angular/platform-browser": "npm:@angular/platform-browser@2.0.0-rc.1", "@angular/platform-browser-dynamic": "npm:@angular/platform-browser-dynamic@2.0.0-rc.1", - "Robdel12/DropKick": "github:Robdel12/DropKick@2.1.7", "babel": "npm:babel-core@5.8.34", "babel-runtime": "npm:babel-runtime@5.8.34", - "clean-css": "npm:clean-css@3.4.6", + "clean-css": "npm:clean-css@3.4.17", "core-js": "npm:core-js@1.2.6", "css": "github:systemjs/plugin-css@0.1.18", + "dropkickjs": "npm:dropkickjs@2.1.8", "es6-shim": "github:es-shims/es6-shim@0.33.6", "hint.css": "npm:hint.css@2.2.1", "json": "github:systemjs/plugin-json@0.1.2", @@ -55,7 +34,7 @@ System.config({ "json-pointer": "npm:json-pointer@0.3.0", "json-schema-ref-parser": "npm:json-schema-ref-parser@3.1.2", "marked": "npm:marked@0.3.5", - "openapi-sampler": "npm:openapi-sampler@0.1.2", + "openapi-sampler": "npm:openapi-sampler@0.2.0", "prismjs": "npm:prismjs@1.3.0", "rxjs": "npm:rxjs@5.0.0-beta.6", "scrollparent": "npm:scrollparent@0.1.0", @@ -63,7 +42,7 @@ System.config({ "systemjs/plugin-json": "github:systemjs/plugin-json@0.1.2", "zone.js": "npm:zone.js@0.6.12", "github:jspm/nodelibs-assert@0.1.0": { - "assert": "npm:assert@1.4.0" + "assert": "npm:assert@1.4.1" }, "github:jspm/nodelibs-buffer@0.1.0": { "buffer": "npm:buffer@3.6.0" @@ -105,7 +84,7 @@ System.config({ "path-browserify": "npm:path-browserify@0.0.0" }, "github:jspm/nodelibs-process@0.1.2": { - "process": "npm:process@0.11.3" + "process": "npm:process@0.11.5" }, "github:jspm/nodelibs-punycode@0.1.0": { "punycode": "npm:punycode@1.3.2" @@ -176,14 +155,13 @@ System.config({ "sprintf-js": "npm:sprintf-js@1.0.3", "util": "github:jspm/nodelibs-util@0.1.0" }, - "npm:asn1.js@4.6.0": { + "npm:asn1.js@4.6.2": { "assert": "github:jspm/nodelibs-assert@0.1.0", - "bn.js": "npm:bn.js@4.11.3", + "bn.js": "npm:bn.js@4.11.4", "buffer": "github:jspm/nodelibs-buffer@0.1.0", "fs": "github:jspm/nodelibs-fs@0.1.2", "inherits": "npm:inherits@2.0.1", "minimalistic-assert": "npm:minimalistic-assert@1.0.0", - "systemjs-json": "github:systemjs/plugin-json@0.1.2", "vm": "github:jspm/nodelibs-vm@0.1.0" }, "npm:asn1@0.2.3": { @@ -206,10 +184,9 @@ System.config({ "stream": "github:jspm/nodelibs-stream@0.1.0", "util": "github:jspm/nodelibs-util@0.1.0" }, - "npm:assert@1.4.0": { + "npm:assert@1.4.1": { "assert": "github:jspm/nodelibs-assert@0.1.0", "buffer": "github:jspm/nodelibs-buffer@0.1.0", - "buffer-shims": "npm:buffer-shims@1.0.0", "process": "github:jspm/nodelibs-process@0.1.2", "util": "npm:util@0.10.3" }, @@ -235,9 +212,8 @@ System.config({ "readable-stream": "npm:readable-stream@2.0.6", "util": "github:jspm/nodelibs-util@0.1.0" }, - "npm:bn.js@4.11.3": { - "buffer": "github:jspm/nodelibs-buffer@0.1.0", - "systemjs-json": "github:systemjs/plugin-json@0.1.2" + "npm:bn.js@4.11.4": { + "buffer": "github:jspm/nodelibs-buffer@0.1.0" }, "npm:boom@2.10.1": { "hoek": "npm:hoek@2.16.3", @@ -270,7 +246,7 @@ System.config({ "systemjs-json": "github:systemjs/plugin-json@0.1.2" }, "npm:browserify-rsa@4.0.1": { - "bn.js": "npm:bn.js@4.11.3", + "bn.js": "npm:bn.js@4.11.4", "buffer": "github:jspm/nodelibs-buffer@0.1.0", "constants": "github:jspm/nodelibs-constants@0.1.0", "crypto": "github:jspm/nodelibs-crypto@0.1.0", @@ -278,13 +254,13 @@ System.config({ "systemjs-json": "github:systemjs/plugin-json@0.1.2" }, "npm:browserify-sign@4.0.0": { - "bn.js": "npm:bn.js@4.11.3", + "bn.js": "npm:bn.js@4.11.4", "browserify-rsa": "npm:browserify-rsa@4.0.1", "buffer": "github:jspm/nodelibs-buffer@0.1.0", "create-hash": "npm:create-hash@1.1.2", "create-hmac": "npm:create-hmac@1.1.4", "crypto": "github:jspm/nodelibs-crypto@0.1.0", - "elliptic": "npm:elliptic@6.2.3", + "elliptic": "npm:elliptic@6.3.1", "inherits": "npm:inherits@2.0.1", "parse-asn1": "npm:parse-asn1@5.0.0", "stream": "github:jspm/nodelibs-stream@0.1.0" @@ -297,9 +273,6 @@ System.config({ "readable-stream": "npm:readable-stream@2.0.6", "util": "github:jspm/nodelibs-util@0.1.0" }, - "npm:buffer-shims@1.0.0": { - "buffer": "github:jspm/nodelibs-buffer@0.1.0" - }, "npm:buffer-xor@1.0.3": { "buffer": "github:jspm/nodelibs-buffer@0.1.0", "systemjs-json": "github:systemjs/plugin-json@0.1.2" @@ -338,7 +311,7 @@ System.config({ "string_decoder": "github:jspm/nodelibs-string_decoder@0.1.0", "systemjs-json": "github:systemjs/plugin-json@0.1.2" }, - "npm:clean-css@3.4.6": { + "npm:clean-css@3.4.17": { "buffer": "github:jspm/nodelibs-buffer@0.1.0", "commander": "npm:commander@2.8.1", "fs": "github:jspm/nodelibs-fs@0.1.2", @@ -386,10 +359,10 @@ System.config({ "buffer": "github:jspm/nodelibs-buffer@0.1.0" }, "npm:create-ecdh@4.0.0": { - "bn.js": "npm:bn.js@4.11.3", + "bn.js": "npm:bn.js@4.11.4", "buffer": "github:jspm/nodelibs-buffer@0.1.0", "crypto": "github:jspm/nodelibs-crypto@0.1.0", - "elliptic": "npm:elliptic@6.2.3" + "elliptic": "npm:elliptic@6.3.1" }, "npm:create-hash@1.1.2": { "buffer": "github:jspm/nodelibs-buffer@0.1.0", @@ -424,7 +397,7 @@ System.config({ "randombytes": "npm:randombytes@2.0.3", "systemjs-json": "github:systemjs/plugin-json@0.1.2" }, - "npm:dashdash@1.13.1": { + "npm:dashdash@1.14.0": { "assert-plus": "npm:assert-plus@1.0.0", "fs": "github:jspm/nodelibs-fs@0.1.2", "path": "github:jspm/nodelibs-path@0.1.0", @@ -432,12 +405,7 @@ System.config({ "util": "github:jspm/nodelibs-util@0.1.0" }, "npm:debug@2.2.0": { - "fs": "github:jspm/nodelibs-fs@0.1.2", - "ms": "npm:ms@0.7.1", - "net": "github:jspm/nodelibs-net@0.1.2", - "process": "github:jspm/nodelibs-process@0.1.2", - "tty": "github:jspm/nodelibs-tty@0.1.0", - "util": "github:jspm/nodelibs-util@0.1.0" + "ms": "npm:ms@0.7.1" }, "npm:delayed-stream@1.0.0": { "stream": "github:jspm/nodelibs-stream@0.1.0", @@ -449,20 +417,23 @@ System.config({ "minimalistic-assert": "npm:minimalistic-assert@1.0.0" }, "npm:diffie-hellman@5.0.2": { - "bn.js": "npm:bn.js@4.11.3", + "bn.js": "npm:bn.js@4.11.4", "buffer": "github:jspm/nodelibs-buffer@0.1.0", "crypto": "github:jspm/nodelibs-crypto@0.1.0", "miller-rabin": "npm:miller-rabin@4.0.0", "randombytes": "npm:randombytes@2.0.3", "systemjs-json": "github:systemjs/plugin-json@0.1.2" }, + "npm:dropkickjs@2.1.8": { + "process": "github:jspm/nodelibs-process@0.1.2" + }, "npm:ecc-jsbn@0.1.1": { "buffer": "github:jspm/nodelibs-buffer@0.1.0", "crypto": "github:jspm/nodelibs-crypto@0.1.0", "jsbn": "npm:jsbn@0.1.0" }, - "npm:elliptic@6.2.3": { - "bn.js": "npm:bn.js@4.11.3", + "npm:elliptic@6.3.1": { + "bn.js": "npm:bn.js@4.11.4", "brorand": "npm:brorand@1.0.5", "hash.js": "npm:hash.js@1.0.3", "inherits": "npm:inherits@2.0.1", @@ -615,8 +586,6 @@ System.config({ "es6-promise": "npm:es6-promise@3.2.1", "events": "github:jspm/nodelibs-events@0.1.1", "fs": "github:jspm/nodelibs-fs@0.1.2", - "http": "npm:stream-http@2.3.0", - "https": "npm:stream-http@2.3.0", "js-yaml": "npm:js-yaml@3.6.1", "ono": "npm:ono@2.2.1", "process": "github:jspm/nodelibs-process@0.1.2", @@ -650,7 +619,7 @@ System.config({ "lodash._stringtopath": "npm:lodash._stringtopath@4.8.0" }, "npm:miller-rabin@4.0.0": { - "bn.js": "npm:bn.js@4.11.3", + "bn.js": "npm:bn.js@4.11.4", "brorand": "npm:brorand@1.0.5" }, "npm:mime-db@1.23.0": { @@ -672,6 +641,9 @@ System.config({ "process": "github:jspm/nodelibs-process@0.1.2", "util": "github:jspm/nodelibs-util@0.1.0" }, + "npm:openapi-sampler@0.2.0": { + "process": "github:jspm/nodelibs-process@0.1.2" + }, "npm:os-browserify@0.1.2": { "os": "github:jspm/nodelibs-os@0.1.0" }, @@ -680,7 +652,7 @@ System.config({ "process": "github:jspm/nodelibs-process@0.1.2" }, "npm:parse-asn1@5.0.0": { - "asn1.js": "npm:asn1.js@4.6.0", + "asn1.js": "npm:asn1.js@4.6.2", "browserify-aes": "npm:browserify-aes@1.0.6", "buffer": "github:jspm/nodelibs-buffer@0.1.0", "create-hash": "npm:create-hash@1.1.2", @@ -713,13 +685,16 @@ System.config({ "systemjs-json": "github:systemjs/plugin-json@0.1.2" }, "npm:process-nextick-args@1.0.7": { - "process": "github:jspm/nodelibs-process@0.1.2" + "process": "github:jspm/nodelibs-process@0.1.2", + "systemjs-json": "github:systemjs/plugin-json@0.1.2" }, - "npm:process@0.11.3": { - "assert": "github:jspm/nodelibs-assert@0.1.0" + "npm:process@0.11.5": { + "assert": "github:jspm/nodelibs-assert@0.1.0", + "fs": "github:jspm/nodelibs-fs@0.1.2", + "vm": "github:jspm/nodelibs-vm@0.1.0" }, "npm:public-encrypt@4.0.0": { - "bn.js": "npm:bn.js@4.11.3", + "bn.js": "npm:bn.js@4.11.4", "browserify-rsa": "npm:browserify-rsa@4.0.1", "buffer": "github:jspm/nodelibs-buffer@0.1.0", "create-hash": "npm:create-hash@1.1.2", @@ -832,7 +807,7 @@ System.config({ "assert-plus": "npm:assert-plus@1.0.0", "buffer": "github:jspm/nodelibs-buffer@0.1.0", "crypto": "github:jspm/nodelibs-crypto@0.1.0", - "dashdash": "npm:dashdash@1.13.1", + "dashdash": "npm:dashdash@1.14.0", "ecc-jsbn": "npm:ecc-jsbn@0.1.1", "getpass": "npm:getpass@0.1.6", "jodid25519": "npm:jodid25519@1.0.2", @@ -877,7 +852,7 @@ System.config({ "process": "github:jspm/nodelibs-process@0.1.2" }, "npm:timers-browserify@1.4.2": { - "process": "npm:process@0.11.3" + "process": "npm:process@0.11.5" }, "npm:to-arraybuffer@1.0.1": { "buffer": "github:jspm/nodelibs-buffer@0.1.0", @@ -932,7 +907,7 @@ System.config({ "process": "github:jspm/nodelibs-process@0.1.2", "request": "npm:request@2.72.0", "systemjs-json": "github:systemjs/plugin-json@0.1.2", - "validator": "npm:validator@5.2.0" + "validator": "npm:validator@5.4.0" }, "npm:zone.js@0.6.12": { "buffer": "github:jspm/nodelibs-buffer@0.1.0", diff --git a/tests/helpers.js b/tests/helpers.ts similarity index 76% rename from tests/helpers.js rename to tests/helpers.ts index 3d702a42..0d3b3662 100644 --- a/tests/helpers.js +++ b/tests/helpers.ts @@ -1,6 +1,7 @@ 'use strict'; import {By} from '@angular/platform-browser'; +import {getDOM} from '@angular/platform-browser/src/dom/dom_adapter'; /** Gets a child DebugElement by tag name. */ export function getChildDebugElement(parent, tagName) { @@ -19,9 +20,7 @@ export function getChildDebugElementAll(parent, tagName) { export function mouseclick( element ) { // create a mouse click event - var event = document.createEvent( 'MouseEvents' ); - event.initMouseEvent( 'click', true, true, window, 1, 0, 0 ); - + var dispatchedEvent = getDOM().createMouseEvent('click'); // send click to element - element.dispatchEvent( event ); + getDOM().dispatchEvent(element, dispatchedEvent); } diff --git a/tests/setup.js b/tests/setup.js deleted file mode 100644 index 78f72f56..00000000 --- a/tests/setup.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict'; - -import {setBaseTestProviders} from '@angular/core/testing'; - -import { - TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, - TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS -} from '@angular/platform-browser-dynamic/testing'; - - -setBaseTestProviders(TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, [TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS]); diff --git a/tests/setup.ts b/tests/setup.ts new file mode 100644 index 00000000..ec80345a --- /dev/null +++ b/tests/setup.ts @@ -0,0 +1,20 @@ +'use strict'; + +import {setBaseTestProviders} from '@angular/core/testing'; +import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter'; +import { OptionsService, RedocEventsService} from '../lib/services/index'; +import { provide } from '@angular/core'; + +import { + TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, + TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS +} from '@angular/platform-browser-dynamic/testing'; + +setBaseTestProviders( + [ + TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS, + provide(BrowserDomAdapter, {useClass: BrowserDomAdapter}), + provide(OptionsService, {useClass: OptionsService}), + provide(RedocEventsService, {useClass: RedocEventsService}) + ], + [TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS]); diff --git a/tests/unit/JsonPointer.spec.js b/tests/unit/JsonPointer.spec.ts similarity index 94% rename from tests/unit/JsonPointer.spec.js rename to tests/unit/JsonPointer.spec.ts index 5669ae4d..a87fe204 100644 --- a/tests/unit/JsonPointer.spec.js +++ b/tests/unit/JsonPointer.spec.ts @@ -1,6 +1,6 @@ 'use strict'; -import {JsonPointer} from 'lib/utils/JsonPointer'; +import {JsonPointer} from '../../lib/utils/JsonPointer'; // test extended JsonPointer describe('Utils', () => { describe('JsonPointer', () => { diff --git a/tests/unit/SchemaManager.spec.js b/tests/unit/SchemaManager.spec.ts similarity index 94% rename from tests/unit/SchemaManager.spec.js rename to tests/unit/SchemaManager.spec.ts index e436093d..ab8a5946 100644 --- a/tests/unit/SchemaManager.spec.js +++ b/tests/unit/SchemaManager.spec.ts @@ -1,6 +1,6 @@ 'use strict'; -import SchemaManager from 'lib/utils/SchemaManager'; +import { SchemaManager } from '../../lib/utils/SchemaManager'; describe('Utils', () => { describe('Schema manager', () => { let schemaMgr; @@ -9,10 +9,6 @@ describe('Utils', () => { schemaMgr = new SchemaManager(); }); - it('Should initialize with empty schema', ()=> { - schemaMgr.schema.should.be.empty; - }); - it('Should be a singleton', ()=> { (new SchemaManager()).should.be.equal(schemaMgr); SchemaManager.instance().should.be.equal(schemaMgr); @@ -50,7 +46,7 @@ describe('Utils', () => { it('should contain non-empty schema', ()=> { schemaMgr.schema.should.be.an.Object(); - schemaMgr.schema.should.be.not.empty; + schemaMgr.schema.should.be.not.empty(); }); it('should correctly init api url', ()=> { @@ -93,7 +89,7 @@ describe('Utils', () => { it('should return empty array for non-specified tags', () => { delete schemaMgr._schema.tags; let tagsMap = schemaMgr.getTagsMap(); - tagsMap.should.be.empty; + tagsMap.should.be.empty(); }); }); @@ -155,8 +151,8 @@ describe('Utils', () => { it('should map x-traitTag to empty methods list', () => { let [, info] = entries[0]; - info['x-traitTag'].should.be.true; - info.methods.should.be.empty; + info['x-traitTag'].should.be.true(); + info.methods.should.be.empty(); }); it('methods for tag should contain valid pointer and summary', () => { @@ -238,13 +234,16 @@ describe('Utils', () => { let deriveDefs = schemaMgr.findDerivedDefinitions('#/definitions/Pet'); deriveDefs.should.be.instanceof(Array); deriveDefs.should.not.be.empty(); - deriveDefs.should.be.deepEqual([{name: 'Cat', empty: false, $ref: '#/definitions/Cat'}, {name: 'Dog', empty: false, $ref: '#/definitions/Dog'}]); + deriveDefs.should.be.deepEqual([ + {name: 'Cat', empty: false, $ref: '#/definitions/Cat'}, + {name: 'Dog', empty: false, $ref: '#/definitions/Dog'} + ]); }); it('should return emtpy array for definitions that dont have discriminator', () => { let deriveDefs = schemaMgr.findDerivedDefinitions('#/definitions/Order'); deriveDefs.should.be.instanceof(Array); - deriveDefs.should.be.empty; + deriveDefs.should.be.empty(); }); }); }); diff --git a/tests/unit/helpers.spec.js b/tests/unit/helpers.spec.ts similarity index 95% rename from tests/unit/helpers.spec.js rename to tests/unit/helpers.spec.ts index 5a4a79b8..ac577bb5 100644 --- a/tests/unit/helpers.spec.js +++ b/tests/unit/helpers.spec.ts @@ -1,6 +1,6 @@ 'use strict'; -import {statusCodeType} from 'lib/utils/helpers'; +import {statusCodeType} from '../../lib/utils/helpers'; describe('Utils', () => { describe('statusCodeType', () => { it('Should return info for status codes within 100 and 200', ()=> { diff --git a/tests/unit/pipes.spec.js b/tests/unit/pipes.spec.js index e1f40cb1..eae19eba 100644 --- a/tests/unit/pipes.spec.js +++ b/tests/unit/pipes.spec.js @@ -1,6 +1,6 @@ 'use strict'; -import {KeysPipe, ValuesPipe, JsonPointerEscapePipe, MarkedPipe} from 'lib/utils/pipes'; +import {KeysPipe, ValuesPipe, JsonPointerEscapePipe, MarkedPipe} from '../../lib/utils/pipes'; describe('Pipes', () => { describe('KeysPipe and ValuesPipe', () => { diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..3ffbe052 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "module": "es6", + "target": "es6", + "noImplicitAny": false, + "sourceMap": true, + "outDir": ".tmp/", + "moduleResolution": "node" + }, + "exclude": [ + "node_modules", + "jspm_packages", + ".tmp", + "build", + "docs", + "*.spec.js", + "lib/index.js" + ] +} diff --git a/tslint.json b/tslint.json new file mode 100644 index 00000000..4783bdfb --- /dev/null +++ b/tslint.json @@ -0,0 +1,49 @@ +{ + "rulesDirectory": ["node_modules/codelyzer"], + "rules": { + "class-name": true, + "curly": false, + "eofline": true, + "indent": ["spaces"], + "max-line-length": [true, 140], + "member-ordering": [true, + "public-before-private", + "static-before-instance", + "variables-before-functions" + ], + "no-arg": true, + "no-construct": true, + "no-duplicate-key": true, + "no-duplicate-variable": true, + "no-empty": true, + "no-eval": true, + "no-trailing-whitespace": true, + "no-unused-expression": true, + "no-unused-variable": true, + "no-unreachable": true, + "no-use-before-declare": true, + "one-line": [true, + "check-open-brace", + "check-catch", + "check-else", + "check-whitespace" + ], + "quotemark": [true, "single"], + "semicolon": true, + "trailing-comma": true, + "triple-equals": [true, + "allow-undefined-check" + ], + "variable-name": false, + + "directive-selector-type": [true, "attribute"], + "component-selector-type": [true, "element"], + "use-input-property-decorator": true, + "use-output-property-decorator": true, + "use-host-property-decorator": true, + "no-input-rename": true, + "no-output-rename": true, + "use-life-cycle-interface": true, + "use-pipe-transform-interface": true + } +} diff --git a/typings.json b/typings.json new file mode 100644 index 00000000..0c9f302b --- /dev/null +++ b/typings.json @@ -0,0 +1,12 @@ +{ + "globalDevDependencies": { + "jasmine": "registry:dt/jasmine#2.2.0+20160505161446" + }, + "globalDependencies": { + "marked": "registry:dt/marked#0.0.0+20160325085301", + "should": "registry:dt/should#8.1.1+20160521152556" + }, + "ambientDevDependencies": { + "es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#6697d6f7dadbf5773cb40ecda35a76027e0783b2" + } +} diff --git a/typings/dropkickjs.d.ts b/typings/dropkickjs.d.ts new file mode 100644 index 00000000..eda2ba9a --- /dev/null +++ b/typings/dropkickjs.d.ts @@ -0,0 +1,4 @@ +declare module "dropkickjs" { + var x: any; + export default x; +} diff --git a/typings/globals/jasmine/index.d.ts b/typings/globals/jasmine/index.d.ts new file mode 100644 index 00000000..d1a7c8ae --- /dev/null +++ b/typings/globals/jasmine/index.d.ts @@ -0,0 +1,501 @@ +// Generated by typings +// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/36a1be34dbe202c665b3ddafd50824f78c09eea3/jasmine/jasmine.d.ts +declare function describe(description: string, specDefinitions: () => void): void; +declare function fdescribe(description: string, specDefinitions: () => void): void; +declare function xdescribe(description: string, specDefinitions: () => void): void; + +declare function it(expectation: string, assertion?: () => void, timeout?: number): void; +declare function it(expectation: string, assertion?: (done: DoneFn) => void, timeout?: number): void; +declare function fit(expectation: string, assertion?: () => void, timeout?: number): void; +declare function fit(expectation: string, assertion?: (done: DoneFn) => void, timeout?: number): void; +declare function xit(expectation: string, assertion?: () => void, timeout?: number): void; +declare function xit(expectation: string, assertion?: (done: DoneFn) => void, timeout?: number): void; + +/** If you call the function pending anywhere in the spec body, no matter the expectations, the spec will be marked pending. */ +declare function pending(reason?: string): void; + +declare function beforeEach(action: () => void, timeout?: number): void; +declare function beforeEach(action: (done: DoneFn) => void, timeout?: number): void; +declare function afterEach(action: () => void, timeout?: number): void; +declare function afterEach(action: (done: DoneFn) => void, timeout?: number): void; + +declare function beforeAll(action: () => void, timeout?: number): void; +declare function beforeAll(action: (done: DoneFn) => void, timeout?: number): void; +declare function afterAll(action: () => void, timeout?: number): void; +declare function afterAll(action: (done: DoneFn) => void, timeout?: number): void; + +declare function expect(spy: Function): jasmine.Matchers; +declare function expect(actual: any): jasmine.Matchers; + +declare function fail(e?: any): void; +/** Action method that should be called when the async work is complete */ +interface DoneFn extends Function { + (): void; + + /** fails the spec and indicates that it has completed. If the message is an Error, Error.message is used */ + fail: (message?: Error|string) => void; +} + +declare function spyOn(object: any, method: string): jasmine.Spy; + +declare function runs(asyncMethod: Function): void; +declare function waitsFor(latchMethod: () => boolean, failureMessage?: string, timeout?: number): void; +declare function waits(timeout?: number): void; + +declare namespace jasmine { + + var clock: () => Clock; + + function any(aclass: any): Any; + function anything(): Any; + function arrayContaining(sample: any[]): ArrayContaining; + function objectContaining(sample: any): ObjectContaining; + function createSpy(name: string, originalFn?: Function): Spy; + function createSpyObj(baseName: string, methodNames: any[]): any; + function createSpyObj(baseName: string, methodNames: any[]): T; + function pp(value: any): string; + function getEnv(): Env; + function addCustomEqualityTester(equalityTester: CustomEqualityTester): void; + function addMatchers(matchers: CustomMatcherFactories): void; + function stringMatching(str: string): Any; + function stringMatching(str: RegExp): Any; + + interface Any { + + new (expectedClass: any): any; + + jasmineMatches(other: any): boolean; + jasmineToString(): string; + } + + // taken from TypeScript lib.core.es6.d.ts, applicable to CustomMatchers.contains() + interface ArrayLike { + length: number; + [n: number]: T; + } + + interface ArrayContaining { + new (sample: any[]): any; + + asymmetricMatch(other: any): boolean; + jasmineToString(): string; + } + + interface ObjectContaining { + new (sample: any): any; + + jasmineMatches(other: any, mismatchKeys: any[], mismatchValues: any[]): boolean; + jasmineToString(): string; + } + + interface Block { + + new (env: Env, func: SpecFunction, spec: Spec): any; + + execute(onComplete: () => void): void; + } + + interface WaitsBlock extends Block { + new (env: Env, timeout: number, spec: Spec): any; + } + + interface WaitsForBlock extends Block { + new (env: Env, timeout: number, latchFunction: SpecFunction, message: string, spec: Spec): any; + } + + interface Clock { + install(): void; + uninstall(): void; + /** Calls to any registered callback are triggered when the clock is ticked forward via the jasmine.clock().tick function, which takes a number of milliseconds. */ + tick(ms: number): void; + mockDate(date?: Date): void; + } + + interface CustomEqualityTester { + (first: any, second: any): boolean; + } + + interface CustomMatcher { + compare(actual: T, expected: T): CustomMatcherResult; + compare(actual: any, expected: any): CustomMatcherResult; + } + + interface CustomMatcherFactory { + (util: MatchersUtil, customEqualityTesters: Array): CustomMatcher; + } + + interface CustomMatcherFactories { + [index: string]: CustomMatcherFactory; + } + + interface CustomMatcherResult { + pass: boolean; + message?: string; + } + + interface MatchersUtil { + equals(a: any, b: any, customTesters?: Array): boolean; + contains(haystack: ArrayLike | string, needle: any, customTesters?: Array): boolean; + buildFailureMessage(matcherName: string, isNot: boolean, actual: any, ...expected: Array): string; + } + + interface Env { + setTimeout: any; + clearTimeout: void; + setInterval: any; + clearInterval: void; + updateInterval: number; + + currentSpec: Spec; + + matchersClass: Matchers; + + version(): any; + versionString(): string; + nextSpecId(): number; + addReporter(reporter: Reporter): void; + execute(): void; + describe(description: string, specDefinitions: () => void): Suite; + // ddescribe(description: string, specDefinitions: () => void): Suite; Not a part of jasmine. Angular team adds these + beforeEach(beforeEachFunction: () => void): void; + beforeAll(beforeAllFunction: () => void): void; + currentRunner(): Runner; + afterEach(afterEachFunction: () => void): void; + afterAll(afterAllFunction: () => void): void; + xdescribe(desc: string, specDefinitions: () => void): XSuite; + it(description: string, func: () => void): Spec; + // iit(description: string, func: () => void): Spec; Not a part of jasmine. Angular team adds these + xit(desc: string, func: () => void): XSpec; + compareRegExps_(a: RegExp, b: RegExp, mismatchKeys: string[], mismatchValues: string[]): boolean; + compareObjects_(a: any, b: any, mismatchKeys: string[], mismatchValues: string[]): boolean; + equals_(a: any, b: any, mismatchKeys: string[], mismatchValues: string[]): boolean; + contains_(haystack: any, needle: any): boolean; + addCustomEqualityTester(equalityTester: CustomEqualityTester): void; + addMatchers(matchers: CustomMatcherFactories): void; + specFilter(spec: Spec): boolean; + } + + interface FakeTimer { + + new (): any; + + reset(): void; + tick(millis: number): void; + runFunctionsWithinRange(oldMillis: number, nowMillis: number): void; + scheduleFunction(timeoutKey: any, funcToCall: () => void, millis: number, recurring: boolean): void; + } + + interface HtmlReporter { + new (): any; + } + + interface HtmlSpecFilter { + new (): any; + } + + interface Result { + type: string; + } + + interface NestedResults extends Result { + description: string; + + totalCount: number; + passedCount: number; + failedCount: number; + + skipped: boolean; + + rollupCounts(result: NestedResults): void; + log(values: any): void; + getItems(): Result[]; + addResult(result: Result): void; + passed(): boolean; + } + + interface MessageResult extends Result { + values: any; + trace: Trace; + } + + interface ExpectationResult extends Result { + matcherName: string; + passed(): boolean; + expected: any; + actual: any; + message: string; + trace: Trace; + } + + interface Trace { + name: string; + message: string; + stack: any; + } + + interface PrettyPrinter { + + new (): any; + + format(value: any): void; + iterateObject(obj: any, fn: (property: string, isGetter: boolean) => void): void; + emitScalar(value: any): void; + emitString(value: string): void; + emitArray(array: any[]): void; + emitObject(obj: any): void; + append(value: any): void; + } + + interface StringPrettyPrinter extends PrettyPrinter { + } + + interface Queue { + + new (env: any): any; + + env: Env; + ensured: boolean[]; + blocks: Block[]; + running: boolean; + index: number; + offset: number; + abort: boolean; + + addBefore(block: Block, ensure?: boolean): void; + add(block: any, ensure?: boolean): void; + insertNext(block: any, ensure?: boolean): void; + start(onComplete?: () => void): void; + isRunning(): boolean; + next_(): void; + results(): NestedResults; + } + + interface Matchers { + + new (env: Env, actual: any, spec: Env, isNot?: boolean): any; + + env: Env; + actual: any; + spec: Env; + isNot?: boolean; + message(): any; + + toBe(expected: any, expectationFailOutput?: any): boolean; + toEqual(expected: any, expectationFailOutput?: any): boolean; + toMatch(expected: string | RegExp, expectationFailOutput?: any): boolean; + toBeDefined(expectationFailOutput?: any): boolean; + toBeUndefined(expectationFailOutput?: any): boolean; + toBeNull(expectationFailOutput?: any): boolean; + toBeNaN(): boolean; + toBeTruthy(expectationFailOutput?: any): boolean; + toBeFalsy(expectationFailOutput?: any): boolean; + toHaveBeenCalled(): boolean; + toHaveBeenCalledWith(...params: any[]): boolean; + toHaveBeenCalledTimes(expected: number): boolean; + toContain(expected: any, expectationFailOutput?: any): boolean; + toBeLessThan(expected: number, expectationFailOutput?: any): boolean; + toBeGreaterThan(expected: number, expectationFailOutput?: any): boolean; + toBeCloseTo(expected: number, precision: any, expectationFailOutput?: any): boolean; + toThrow(expected?: any): boolean; + toThrowError(message?: string | RegExp): boolean; + toThrowError(expected?: new (...args: any[]) => Error, message?: string | RegExp): boolean; + not: Matchers; + + Any: Any; + } + + interface Reporter { + reportRunnerStarting(runner: Runner): void; + reportRunnerResults(runner: Runner): void; + reportSuiteResults(suite: Suite): void; + reportSpecStarting(spec: Spec): void; + reportSpecResults(spec: Spec): void; + log(str: string): void; + } + + interface MultiReporter extends Reporter { + addReporter(reporter: Reporter): void; + } + + interface Runner { + + new (env: Env): any; + + execute(): void; + beforeEach(beforeEachFunction: SpecFunction): void; + afterEach(afterEachFunction: SpecFunction): void; + beforeAll(beforeAllFunction: SpecFunction): void; + afterAll(afterAllFunction: SpecFunction): void; + finishCallback(): void; + addSuite(suite: Suite): void; + add(block: Block): void; + specs(): Spec[]; + suites(): Suite[]; + topLevelSuites(): Suite[]; + results(): NestedResults; + } + + interface SpecFunction { + (spec?: Spec): void; + } + + interface SuiteOrSpec { + id: number; + env: Env; + description: string; + queue: Queue; + } + + interface Spec extends SuiteOrSpec { + + new (env: Env, suite: Suite, description: string): any; + + suite: Suite; + + afterCallbacks: SpecFunction[]; + spies_: Spy[]; + + results_: NestedResults; + matchersClass: Matchers; + + getFullName(): string; + results(): NestedResults; + log(arguments: any): any; + runs(func: SpecFunction): Spec; + addToQueue(block: Block): void; + addMatcherResult(result: Result): void; + expect(actual: any): any; + waits(timeout: number): Spec; + waitsFor(latchFunction: SpecFunction, timeoutMessage?: string, timeout?: number): Spec; + fail(e?: any): void; + getMatchersClass_(): Matchers; + addMatchers(matchersPrototype: CustomMatcherFactories): void; + finishCallback(): void; + finish(onComplete?: () => void): void; + after(doAfter: SpecFunction): void; + execute(onComplete?: () => void): any; + addBeforesAndAftersToQueue(): void; + explodes(): void; + spyOn(obj: any, methodName: string, ignoreMethodDoesntExist: boolean): Spy; + removeAllSpies(): void; + } + + interface XSpec { + id: number; + runs(): void; + } + + interface Suite extends SuiteOrSpec { + + new (env: Env, description: string, specDefinitions: () => void, parentSuite: Suite): any; + + parentSuite: Suite; + + getFullName(): string; + finish(onComplete?: () => void): void; + beforeEach(beforeEachFunction: SpecFunction): void; + afterEach(afterEachFunction: SpecFunction): void; + beforeAll(beforeAllFunction: SpecFunction): void; + afterAll(afterAllFunction: SpecFunction): void; + results(): NestedResults; + add(suiteOrSpec: SuiteOrSpec): void; + specs(): Spec[]; + suites(): Suite[]; + children(): any[]; + execute(onComplete?: () => void): void; + } + + interface XSuite { + execute(): void; + } + + interface Spy { + (...params: any[]): any; + + identity: string; + and: SpyAnd; + calls: Calls; + mostRecentCall: { args: any[]; }; + argsForCall: any[]; + wasCalled: boolean; + } + + interface SpyAnd { + /** By chaining the spy with and.callThrough, the spy will still track all calls to it but in addition it will delegate to the actual implementation. */ + callThrough(): Spy; + /** By chaining the spy with and.returnValue, all calls to the function will return a specific value. */ + returnValue(val: any): Spy; + /** By chaining the spy with and.returnValues, all calls to the function will return specific values in order until it reaches the end of the return values list. */ + returnValues(...values: any[]): Spy; + /** By chaining the spy with and.callFake, all calls to the spy will delegate to the supplied function. */ + callFake(fn: Function): Spy; + /** By chaining the spy with and.throwError, all calls to the spy will throw the specified value. */ + throwError(msg: string): Spy; + /** When a calling strategy is used for a spy, the original stubbing behavior can be returned at any time with and.stub. */ + stub(): Spy; + } + + interface Calls { + /** By chaining the spy with calls.any(), will return false if the spy has not been called at all, and then true once at least one call happens. **/ + any(): boolean; + /** By chaining the spy with calls.count(), will return the number of times the spy was called **/ + count(): number; + /** By chaining the spy with calls.argsFor(), will return the arguments passed to call number index **/ + argsFor(index: number): any[]; + /** By chaining the spy with calls.allArgs(), will return the arguments to all calls **/ + allArgs(): any[]; + /** By chaining the spy with calls.all(), will return the context (the this) and arguments passed all calls **/ + all(): CallInfo[]; + /** By chaining the spy with calls.mostRecent(), will return the context (the this) and arguments for the most recent call **/ + mostRecent(): CallInfo; + /** By chaining the spy with calls.first(), will return the context (the this) and arguments for the first call **/ + first(): CallInfo; + /** By chaining the spy with calls.reset(), will clears all tracking for a spy **/ + reset(): void; + } + + interface CallInfo { + /** The context (the this) for the call */ + object: any; + /** All arguments passed to the call */ + args: any[]; + /** The return value of the call */ + returnValue: any; + } + + interface Util { + inherit(childClass: Function, parentClass: Function): any; + formatException(e: any): any; + htmlEscape(str: string): string; + argsToArray(args: any): any; + extend(destination: any, source: any): any; + } + + interface JsApiReporter extends Reporter { + + started: boolean; + finished: boolean; + result: any; + messages: any; + + new (): any; + + suites(): Suite[]; + summarize_(suiteOrSpec: SuiteOrSpec): any; + results(): any; + resultsForSpec(specId: any): any; + log(str: any): any; + resultsForSpecs(specIds: any): any; + summarizeResult_(result: any): any; + } + + interface Jasmine { + Spec: Spec; + clock: Clock; + util: Util; + } + + export var HtmlReporter: HtmlReporter; + export var HtmlSpecFilter: HtmlSpecFilter; + export var DEFAULT_TIMEOUT_INTERVAL: number; +} \ No newline at end of file diff --git a/typings/globals/jasmine/typings.json b/typings/globals/jasmine/typings.json new file mode 100644 index 00000000..4570b84e --- /dev/null +++ b/typings/globals/jasmine/typings.json @@ -0,0 +1,8 @@ +{ + "resolution": "main", + "tree": { + "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/36a1be34dbe202c665b3ddafd50824f78c09eea3/jasmine/jasmine.d.ts", + "raw": "registry:dt/jasmine#2.2.0+20160505161446", + "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/36a1be34dbe202c665b3ddafd50824f78c09eea3/jasmine/jasmine.d.ts" + } +} diff --git a/typings/globals/json-pointer/index.d.ts b/typings/globals/json-pointer/index.d.ts new file mode 100644 index 00000000..8b93d3eb --- /dev/null +++ b/typings/globals/json-pointer/index.d.ts @@ -0,0 +1,80 @@ +// Generated by typings +// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/json-pointer/json-pointer.d.ts +declare module "json-pointer" { + function JSON_Pointer(object: Object): JSON_Pointer.JSON_PointerWrap; + + namespace JSON_Pointer { + /** + * Wrap an object with accessors + */ + /** + * Looks up a JSON pointer in an object. + */ + function get(object: Object, pointer: string): any; + /** + * Set a value for a JSON pointer on object. + */ + function set(object: Object, pointer: string, value: any): void; + /** + * Removes an attribute of object referenced by pointer + */ + function remove(object: Object, pointer: string): void; + /** + * Creates a dictionary object (pointer -> value). + */ + function dict(object: Object): Object; + /** + * Just like: each(pointer.dict(obj), iterator); + */ + function walk(object: Object, iterator: (value: any, key: string) => void): void; + /** + * Tests if an object has a value for a JSON pointer. + */ + function has(object: Object, pointer: string): boolean; + /** + * Escapes a reference token. + */ + function escape(str: string): string; + /** + * Unescape a reference token. + */ + function unescape(str: string): string; + /** + * Converts a JSON pointer into an array of reference tokens. + */ + function parse(str: string): string[]; + /** + * Builds a json pointer from an array of reference tokens. + */ + function compile(str: string[]): string; + + interface JSON_PointerWrap { + /** + * Looks up a JSON pointer in an object. + */ + get(pointer: string): any; + /** + * Set a value for a JSON pointer on object. + */ + set(pointer: string, value: any): void; + /** + * Removes an attribute of object referenced by pointer + */ + remove(pointer: string): void; + /** + * Creates a dictionary object (pointer -> value). + */ + dict(): Object; + /** + * Just like: each(pointer.dict(obj), iterator); + */ + walk(iterator: (value: any, key: string) => void): void; + /** + * Tests if an object has a value for a JSON pointer. + */ + has(pointer: string): boolean; + } + } + + export default JSON_Pointer; +} \ No newline at end of file diff --git a/typings/globals/json-pointer/typings.json b/typings/globals/json-pointer/typings.json new file mode 100644 index 00000000..3f323b65 --- /dev/null +++ b/typings/globals/json-pointer/typings.json @@ -0,0 +1,8 @@ +{ + "resolution": "main", + "tree": { + "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/json-pointer/json-pointer.d.ts", + "raw": "registry:dt/json-pointer#1.0.0+20160317120654", + "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/json-pointer/json-pointer.d.ts" + } +} diff --git a/typings/globals/should/index.d.ts b/typings/globals/should/index.d.ts new file mode 100644 index 00000000..35e3d491 --- /dev/null +++ b/typings/globals/should/index.d.ts @@ -0,0 +1,168 @@ +// Generated by typings +// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/445ed7e54c1b2a8e84610afab0aab2b2ee2ffb4e/should/should.d.ts +interface Object { + should: ShouldAssertion; +} + +interface ShouldAssertion { + // basic grammar + a: ShouldAssertion; + an: ShouldAssertion; + and: ShouldAssertion; + be: ShouldAssertion; + has: ShouldAssertion; + have: ShouldAssertion; + is: ShouldAssertion; + it: ShouldAssertion; + with: ShouldAssertion; + which: ShouldAssertion; + the: ShouldAssertion; + of: ShouldAssertion; + not: ShouldAssertion; + + // validators + arguments(): ShouldAssertion; + empty(): ShouldAssertion; + ok(): ShouldAssertion; + true(): ShouldAssertion; + false(): ShouldAssertion; + NaN(): ShouldAssertion; + Infinity(): ShouldAssertion; + Array(): ShouldAssertion; + Object(): ShouldAssertion; + String(): ShouldAssertion; + Boolean(): ShouldAssertion; + Number(): ShouldAssertion; + Error(): ShouldAssertion; + Function(): ShouldAssertion; + Date(): ShouldAssertion; + Class(): ShouldAssertion; + Undefined(): ShouldAssertion; + generator(): ShouldAssertion; + iterable(): ShouldAssertion; + iterator(): ShouldAssertion; + eql(expected: any, description?: string): ShouldAssertion; + equal(expected: any, description?: string): ShouldAssertion; + equalOneOf(...values: any[]): ShouldAssertion; + within(start: number, finish: number, description?: string): ShouldAssertion; + approximately(value: number, delta: number, description?: string): ShouldAssertion; + type(expected: any, description?: string): ShouldAssertion; + instanceof(constructor: Function, description?: string): ShouldAssertion; + above(n: number, description?: string): ShouldAssertion; + below(n: number, description?: string): ShouldAssertion; + aboveOrEqual(n: number, description?: string): ShouldAssertion; + greaterThanOrEqual(n: number, description?: string): ShouldAssertion; + belowOrEqual(n: number, description?: string): ShouldAssertion; + lessThanOrEqual(n: number, description?: string): ShouldAssertion; + match(other: {}, description?: string): ShouldAssertion; + match(other: (val: any) => any, description?: string): ShouldAssertion; + match(regexp: RegExp, description?: string): ShouldAssertion; + match(other: any, description?: string): ShouldAssertion; + matchEach(other: {}, description?: string): ShouldAssertion; + matchEach(other: (val: any) => any, description?: string): ShouldAssertion; + matchEach(regexp: RegExp, description?: string): ShouldAssertion; + matchEach(other: any, description?: string): ShouldAssertion; + matchAny(other: {}, description?: string): ShouldAssertion; + matchAny(other: (val: any) => any, description?: string): ShouldAssertion; + matchAny(regexp: RegExp, description?: string): ShouldAssertion; + matchAny(other: any, description?: string): ShouldAssertion; + length(n: number, description?: string): ShouldAssertion; + property(name: string, description?: string): ShouldAssertion; + property(name: string, val: any, description?: string): ShouldAssertion; + properties(names: string[]): ShouldAssertion; + properties(name: string): ShouldAssertion; + properties(descriptor: any): ShouldAssertion; + properties(...properties: string[]): ShouldAssertion; + propertyByPath(...properties: string[]): ShouldAssertion; + propertyWithDescriptor(name: string, descriptor: PropertyDescriptor): ShouldAssertion; + oneOf(...values: any[]): ShouldAssertion; + ownProperty(name: string, description?: string): ShouldAssertion; + containEql(obj: any): ShouldAssertion; + containDeep(obj: any): ShouldAssertion; + containDeepOrdered(obj: any): ShouldAssertion; + keys(...allKeys: string[]): ShouldAssertion; + keys(allKeys: string[]): ShouldAssertion; + enumerable(property: string, value?: any): ShouldAssertion; + enumerables(...properties: string[]): ShouldAssertion; + startWith(expected: string, message?: any): ShouldAssertion; + endWith(expected: string, message?: any): ShouldAssertion; + throw(message?: any): ShouldAssertion; + + //http + header(field: string, val?: string): ShouldAssertion; + status(code: number): ShouldAssertion; + json(): ShouldAssertion; + html(): ShouldAssertion; + + //stubs + alwaysCalledOn(thisTarget: any): ShouldAssertion; + alwaysCalledWith(...arguments: any[]): ShouldAssertion; + alwaysCalledWithExactly(...arguments: any[]): ShouldAssertion; + alwaysCalledWithMatch(...arguments: any[]): ShouldAssertion; + alwaysCalledWithNew(): ShouldAssertion; + alwaysThrew(exception?: any): ShouldAssertion; + callCount(count: number): ShouldAssertion; + called(): ShouldAssertion; + calledOn(thisTarget: any): ShouldAssertion; + calledOnce(): ShouldAssertion; + calledTwice(): ShouldAssertion; + calledThrice(): ShouldAssertion; + calledWith(...arguments: any[]): ShouldAssertion; + calledWithExactly(...arguments: any[]): ShouldAssertion; + calledWithMatch(...arguments: any[]): ShouldAssertion; + calledWithNew(): ShouldAssertion; + neverCalledWith(...arguments: any[]): ShouldAssertion; + neverCalledWithMatch(...arguments: any[]): ShouldAssertion; + threw(exception?: any): ShouldAssertion; + + // aliases + True(): ShouldAssertion; + False(): ShouldAssertion; + Arguments(): ShouldAssertion; + class(): ShouldAssertion; + deepEqual(expected: any, description?: string): ShouldAssertion; + exactly(expected: any, description?: string): ShouldAssertion; + instanceOf(constructor: Function, description?: string): ShouldAssertion; + throwError(message?: any): ShouldAssertion; + lengthOf(n: number, description?: string): ShouldAssertion; + key(key: string): ShouldAssertion; + hasOwnProperty(name: string, description?: string): ShouldAssertion; + greaterThan(n: number, description?: string): ShouldAssertion; + lessThan(n: number, description?: string): ShouldAssertion; +} + +interface ShouldInternal { + // should.js's extras + exist(actual: any, msg?: string): void; + exists(actual: any, msg?: string): void; + not: ShouldInternal; +} + +interface Internal extends ShouldInternal { + (obj: any): ShouldAssertion; + + // node.js's assert functions + fail(actual: any, expected: any, message: string, operator: string): void; + assert(value: any, message: string): void; + ok(value: any, message?: string): void; + equal(actual: any, expected: any, message?: string): void; + notEqual(actual: any, expected: any, message?: string): void; + deepEqual(actual: any, expected: any, message?: string): void; + notDeepEqual(actual: any, expected: any, message?: string): void; + strictEqual(actual: any, expected: any, message?: string): void; + notStrictEqual(actual: any, expected: any, message?: string): void; + throws(block: any, error?: any, message?: string): void; + doesNotThrow(block: any, message?: string): void; + ifError(value: any): void; + inspect(value: any, obj: any): any; +} + +declare var should: Internal; +declare var Should: Internal; +interface Window { + Should: Internal; +} + +declare module "should" { + export = should; +} \ No newline at end of file diff --git a/typings/globals/should/typings.json b/typings/globals/should/typings.json new file mode 100644 index 00000000..c7a9db7c --- /dev/null +++ b/typings/globals/should/typings.json @@ -0,0 +1,8 @@ +{ + "resolution": "main", + "tree": { + "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/445ed7e54c1b2a8e84610afab0aab2b2ee2ffb4e/should/should.d.ts", + "raw": "registry:dt/should#8.1.1+20160521152556", + "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/445ed7e54c1b2a8e84610afab0aab2b2ee2ffb4e/should/should.d.ts" + } +} diff --git a/typings/index.d.ts b/typings/index.d.ts new file mode 100644 index 00000000..840dcf67 --- /dev/null +++ b/typings/index.d.ts @@ -0,0 +1,3 @@ +/// +/// +/// diff --git a/typings/json-schema-ref-parser.d.ts b/typings/json-schema-ref-parser.d.ts new file mode 100644 index 00000000..faf03b64 --- /dev/null +++ b/typings/json-schema-ref-parser.d.ts @@ -0,0 +1,4 @@ +declare module 'json-schema-ref-parser' { + var x: any; + export default x; +} diff --git a/typings/marked.d.ts b/typings/marked.d.ts new file mode 100644 index 00000000..be77f66a --- /dev/null +++ b/typings/marked.d.ts @@ -0,0 +1,7 @@ +// Generated by typings +// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/json-pointer/json-pointer.d.ts + +declare module "marked" { + var x: any; + export default x; +} \ No newline at end of file diff --git a/typings/openapi-sampler.d.ts b/typings/openapi-sampler.d.ts new file mode 100644 index 00000000..46fe48b9 --- /dev/null +++ b/typings/openapi-sampler.d.ts @@ -0,0 +1,3 @@ +declare module "openapi-sampler" { + export function sample(schema:any, options?:any):any; +} diff --git a/typings/scrollparent.d.ts b/typings/scrollparent.d.ts new file mode 100644 index 00000000..05b8f986 --- /dev/null +++ b/typings/scrollparent.d.ts @@ -0,0 +1,6 @@ +// Generated by typings +// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/7de6c3dd94feaeb21f20054b9f30d5dabc5efabd/json-pointer/json-pointer.d.ts +declare module "scrollparent" { + var x: any; + export default x; +} \ No newline at end of file