Giter Site home page Giter Site logo

loopback-component-explorer's Introduction

loopback-component-explorer

⚠️ LoopBack 3 is in Maintenance LTS mode, only critical bugs and critical security fixes will be provided. (See Module Long Term Support Policy below.)

We urge all LoopBack 3 users to migrate their applications to LoopBack 4 as soon as possible. Refer to our Migration Guide for more information on how to upgrade.

Overview

Browse and test your LoopBack app's APIs.

Basic Usage

Below is a simple LoopBack application. The explorer is mounted at /explorer.

var loopback = require('loopback');
var app = loopback();
var explorer = require('../');
var port = 3000;

var Product = loopback.Model.extend('product');
Product.attachTo(loopback.memory());
app.model(Product);

app.use('/api', loopback.rest());

// Register explorer using component-centric API:
explorer(app, { basePath: '/api', mountPath: '/explorer' });
// Alternatively, register as a middleware:
app.use('/explorer', explorer.routes(app, { basePath: '/api' }));

console.log("Explorer mounted at localhost:" + port + "/explorer");

app.listen(port);

A note on swagger-ui vulnerabilities

API Explorer for LoopBack 3 is built on top of swagger-ui version 2.x which is no longer maintained. While there are known security vulnerabilities in swagger-ui, we believe they don't affect LoopBack users.

We would love to upgrade our (LB3) API Explorer to v3 of swagger-ui, but unfortunately such upgrade requires too much effort and more importantly addition of new features to LB3 runtime, which would break our LTS guarantees. For more details, see discussion in loopback-component-explorer#263.

npm advisory 985

Link: https://www.npmjs.com/advisories/985

Versions of swagger-ui prior to 3.0.13 are vulnerable to Cross-Site Scripting (XSS). The package fails to sanitize YAML files imported from URLs or copied-pasted. This may allow attackers to execute arbitrary JavaScript.

LoopBack's API Explorer does not allow clients to import swagger spec from YAML URL/pasted-content. That means loopback-component-explorer IS NOT AFFECTED by this vulnerability.

npm advisory 975

Link: https://www.npmjs.com/advisories/975

Versions of swagger-ui prior to 3.18.0 are vulnerable to Reverse Tabnapping. The package uses target='_blank' in anchor tags, allowing attackers to access window.opener for the original page. This is commonly used for phishing attacks.

This vulnerability affects anchor tags created from metadata provided by the Swagger spec, for example info.termsOfServiceUrl. LoopBack's API Explorer does not allow clients to provide custom swagger spec, URLs like info.termsOfServiceUrl are fully in control of the LoopBack application developer. That means loopback-component-explorer IS NOT AFFECTED by this vulnerability.

npm advisory 976

Link: https://www.npmjs.com/advisories/976

Versions of swagger-ui prior to 3.20.9 are vulnerable to Cross-Site Scripting (XSS). The package fails to sanitize URLs used in the OAuth auth flow, which may allow attackers to execute arbitrary JavaScript.

LoopBack 3 API Explorer does not support OAuth auth flow, that means loopback-component-explorer IS NOT AFFECTED by this vulnerability.

GitHub advisory CVE-2019-17495

Link: https://github.com/advisories/GHSA-c427-hjc3-wrfw

A Cascading Style Sheets (CSS) injection vulnerability in Swagger UI before 3.23.11 allows attackers to use the Relative Path Overwrite (RPO) technique to perform CSS-based input field value exfiltration, such as exfiltration of a CSRF token value.

Quoting from the disclosure:

We’ve observed that the ?url= parameter in SwaggerUI allows an attacker to override an otherwise hard-coded schema file. We realize that Swagger UI allows users to embed untrusted Json format from remote servers This means we can inject json content via the GET parameter to victim Swagger UI. etc.

LoopBack 3 API Explorer does not suport ?url= parameter, it always loads the Swagger spec file from the LoopBack server serving the Explorer UI. That means loopback-component-explorer IS NOT AFFECTED by this vulnerability.

Upgrading from v1.x

To upgrade your application using loopback-explorer version 1.x, just replace explorer() with explorer.routes() in your server script:

var explorer = require('loopback-component-explorer');  // Module was loopback-explorer in v. 2.0.1 and earlier

// v1.x - does not work anymore
app.use('/explorer', explorer(app, options));
// v2.x
app.use('/explorer', explorer.routes(app, options));

In applications scaffolded by lb app, the idiomatic way is to register loopback-component-explorer in server/component-config.json:

{
  "loopback-component-explorer": {
    "mountPath": "/explorer"
  }
}

Advanced Usage

Many aspects of the explorer are configurable.

See options for a description of these options:

// Mount middleware before calling `explorer()` to add custom headers, auth, etc.
app.use('/explorer', loopback.basicAuth('user', 'password'));
explorer(app, {
  basePath: '/custom-api-root',
  uiDirs: [
    path.resolve(__dirname, 'public'),
    path.resolve(__dirname, 'node_modules', 'swagger-ui')
  ]
  apiInfo: {
    'title': 'My API',
    'description': 'Explorer example app.'
  },
  resourcePath: 'swagger.json',
  version: '0.1-unreleasable'
}));
app.use('/custom-api-root', loopback.rest());

In applications scaffolded by lb app, you can edit the server/component-config.json:

{
  "loopback-component-explorer": {
    "mountPath": "/explorer",
    "apiInfo": {
      "title": "My App",
      "description": "Description of my app APIs.",
      "termsOfServiceUrl": "http://api.mycompany.io/terms/",
      "contact": "[email protected]",
      "license": "Apache 2.0",
      "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0.html"
    }
  }
}

Options

Options are passed to explorer(app, options).

basePath: String

Default: app.get('restAPIRoot') or '/api'.

Sets the API's base path. This must be set if you are mounting your api to a path different than '/api', e.g. with `loopback.use('/custom-api-root', loopback.rest());

mountPath: String

Default: /explorer

Set the path where to mount the explorer component.

protocol: String

Default: null

A hard override for the outgoing protocol (http or https) that is designated in Swagger resource documents. By default, loopback-component-explorer will write the protocol that was used to retrieve the doc. This option is useful if, for instance, your API sits behind an SSL terminator and thus needs to report its endpoints as https, even though incoming traffic is auto-detected as http.

uiDirs: Array of Strings

Sets a list of paths within your application for overriding Swagger UI files.

If present, will search uiDirs first when attempting to load Swagger UI, allowing you to pick and choose overrides to the interface. Use this to style your explorer or add additional functionality.

See index.html, where you may want to begin your overrides. The rest of the UI is provided by Swagger UI.

apiInfo: Object

Additional information about your API. See the spec.

resourcePath: String

Default: 'resources'

Sets a different path for the resource listing. You generally shouldn't have to change this.

version: String

Default: Read from package.json

Sets your API version. If not present, will read from your app's package.json.

auth: Object

Optional config for setting api access token, can be used to rename the query parameter or set an auth header.

The object has 2 keys:

  • in: either header or query
  • name: the name of the query parameter or header

The default sets the token as a query parameter with the name access_token

Example for setting the api key in a header named x-api-key:

{
  "loopback-component-explorer": {
    "mountPath": "/explorer",
    "auth": {
      "in": "header",
      "name": "x-api-key"
    }
  }
}

Module Long Term Support Policy

This module adopts the Module Long Term Support (LTS) policy, with the following End Of Life (EOL) dates:

Version Status Published EOL
6.x Maintenance LTS Apr 2018 Dec 2020
5.x End-of-Life Sep 2017 Dec 2019

Learn more about our LTS plan in docs.

loopback-component-explorer's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

loopback-component-explorer's Issues

2.0 leftovers

List of loopback-explorer improvements to possibly implement on top of #115:

Swagger UI breaks when using a http context argument in a remote method

Defined a remote method as:

this.remoteMethod('foo', {
  isStatic: false,
  http: [
    {path: '/foo', verb: 'get'},
    {path: '/foo', verb: 'post'},
    {path: '/foo', verb: 'put'}
  ],
  accepts: {arg: 'ctx', http: {source: 'context'}}
});

causes swagger UI to report an error on JS console and stop responding properly:

Uncaught TypeError: Cannot read property 'toLowerCase' of undefined     swagger.js:716
SwaggerOperation                                                        swagger.js:716
SwaggerResource.addOperations                                           swagger.js:481
SwaggerResource.addApiDeclaration                                       swagger.js:412
obj.on.response                                                         swagger.js:361
res.response                                                            swagger.js:1479
EventEmitter.emit                                                       shred.bundle.js:1391
emit                                                                    shred.bundle.js:1191
(anonymous function)                                                    shred.bundle.js:1211
setBodyAndFinish                                                        shred.bundle.js:1815
(anonymous function)                                                    shred.bundle.js:1832
EventEmitter.emit                                                       shred.bundle.js:1388
Response.handle                                                         shred.bundle.js:2715
xhr.onreadystatechange                                                  shred.bundle.js:2584

/cc @ritch

Add option to support authorization header instead of query params for access tokens

Currently, access tokens (set in the top right of the explorer) are passed as query parameters (e.g. /api/test?access_token=1234).

Many exposed APIs, especially those using OAuth, should pass this token as an authorization header (e.g. token would be set in UI as normal, but would be passed as OAuth or Bearer authorization header).

It would be great to have an option in explorer to support this.

Can't properly create fields filter from Explorer

The Docs say that if you want to include or exclude a field from a resource then one have to create a filter like this:

api/pages?filter[fields][title]=false

However, there is no way to create this filter from the UI, because it always appends an equeal sign after filter. Resulting in this query string:

api/pages?filter=[fields][title]=false

orderBy vs order typo?

For example, in the Strongloop API explorer, it lists "orderBy" as an option in find or findOne,
however, it only works when I enter "order".

Explorer shows disabled routes/methods

In my app.js I remove

// Expose a rest api
app.use(apiPath, loopback.rest());

So all models are not exposed over REST but Explorer still shows "default" REST routes. It should be hidden as routes are unavailable.

length of undefined error on timeout

I came across the case where my server wasn't responding to put requests and noticed the api-explorer has no or a huge timeout on api calls. I was wondering it took so long, didn't expect it had no timeout. Well, the actual bug I wanted to report is:

PUT http://blabla:3000/api/pages/273541696466681878 net::ERR_EMPTY_RESPONSE shred.bundle.js:2608
Uncaught TypeError: Cannot read property 'length' of undefined swagger-ui.js:2018
    OperationView.showStatus swagger-ui.js:2018
    OperationView.showErrorStatus swagger-ui.js:1899
    obj.on.error swagger.js:1159res.error swagger.js:1467
    EventEmitter.emit shred.bundle.js:1408
    emit shred.bundle.js:1189
    (anonymous function) shred.bundle.js:1208
    setBodyAndFinish shred.bundle.js:1815
    (anonymous function) shred.bundle.js:1832
    EventEmitter.emit shred.bundle.js:1388
    Response.handle shred.bundle.js:2715
    xhr.onreadystatechange shred.bundle.js:2584

File upload feature in explorer (nice to have)

We can create API for file upload and download. But there is no way to test it from explorer.
It'd be nice to have that feature.

Right now there is an example with angular but that requires some work.

Sorry, if it is already duplicated.

Hide properties per method.

Explorer/Models should allow to hide/show properties per method.

For example POST /book will auto-generate ID property. So ID should not be available as property in POST method.

Move Route discovery / introspection to workspace

The ability to introspect routes, swagger resources, and other related meta data, should be made available from the workspace API. The explorer should use the workspace API to get the metadata it needs instead of interacting with the app directly.

/cc @raymondfeng

Naming a Loopback model `api` breaks the Loopback Explorer

If I name one of my models api, the explorer will no longer expand / collapse any API groups, so no APIs can be seen or tested within the explorer.

This is potentially just an issue within Swagger UI. I haven't checked that angle.

Example model api.json

{
  "name": "api",
  "plural": "apis",
  "base": "PersistedModel",
  ...
}

Extension hook: custom swagger-ui [GoDaddy]

Many loopback-explorer users want to tweak the appearance of Swagger UI, see
the discussion in #52 for an example.

To accommodate such users, loopback-explorer should provide a configuration option allowing users to provide their own version (fork) of swagger-ui.

Model Schemas

The explorer should use the model's schema.

Details TBD.

Explorer unusable because of Uncaught TypeError(s)

I cannot use Explorer anymore (no sections open), because swagger.js trips over parameters without a type declaration (string value). More specifically on line 734 (SwaggerOperation):

    if(type.toLowerCase() === 'boolean') {

Uncaught TypeError: Cannot read property 'toLowerCase' of undefined

This can be traced back to the following declarations, which I'm why this is the case:

Model.remoteMethod('count', {
        isStatic: true,
        description: 'Count all instances of the model.',
        accessType: 'READ',
        http: { verb: 'get', path: '/count' },
        accepts: {},
        returns: { arg: 'count', type: 'number' }
});

(Payment is a custom model, not based on PersistantModel)

{
  "path": "/payments/count",
  "operations": [
    {
      "method": "GET",
      "nickname": "count",
      "parameters": [
        {
          "paramType": "query",
          "required": false,
          "allowMultiple": false,
          // NO TYPE
        }
      ],
      "responseMessages": [
        {
          "code": 200,
          "message": "Request was successful"
        }
      ],
      "summary": "Count all instances of the model.",
      "type": "number",
      "format": "double"
    }
  ]
}

{
  "method": "PUT",
  "nickname": "prototype.__link__reviewers",
  "parameters": [
    {
      "paramType": "path",
      "name": "fk",
      "description": "Foreign key for reviewers",
      "required": true,
      "allowMultiple": false,
      "type": "any"
    },
    {
      "paramType": "body",
      "name": "data",
      "required": false,
      "allowMultiple": false
      // NO TYPE
    },
    {
      "paramType": "path",
      "name": "id",
      "description": "PersistedModel id",
      "required": true,
      "allowMultiple": false,
      "type": "any"
    }
  ],
  "responseMessages": [
    {
      "code": 200,
      "message": "Request was successful"
    }
  ],
  "summary": "Add a related item by id for reviewers."
}

Hide port number

Hi there,

Just want to know is there way that i can hide the port number?
i got a domain www.web.com will normally host static content.
and i want to use api.web.com as loopback server.
But at this moment, i only can use api.web.com:3000, can't use 80 because 80 is already in use.

Thanks.

Update to Swagger spec v2

I think we should wait a few weeks on this anyway because there's some instability (like a recent bug in swagger-ui that defaulted all routes to GET regardless of their verb), but eventually we'll want to update loopback-explorer's JSON output to Swagger v2.

Unable to install any version beyond 1.1.1 (on mac)

It seems impossible to install any version beyond 1.1.1 (on a mac at least, I didn't test on other systems). Using NodeJS 0.10.30 and the corresponding version of npm I get this:

... lots of logging ...
2115 error Error: ENOENT, lstat '/private/tmp/test/node_modules/loopback-explorer/node_modules/express/node_modules/mkdirp/readme.markdown'
2116 error If you need help, you may report this entire log,
2116 error including the npm and node versions, at:
2116 error http://github.com/npm/npm/issues
2117 error System Darwin 13.3.0
2118 error command "node" "/usr/local/bin/npm" "install" "[email protected]"
2119 error cwd /private/tmp/test
2120 error node -v v0.10.30
2121 error npm -v 1.4.21
2122 error path /private/tmp/test/node_modules/loopback-explorer/node_modules/express/node_modules/mkdirp/readme.markdown
2123 error fstream_path /private/tmp/test/node_modules/loopback-explorer/node_modules/express/node_modules/mkdirp/readme.markdown
2124 error fstream_type File
2125 error fstream_class FileWriter
2126 error code ENOENT
2127 error errno 34
2128 error fstream_stack /usr/local/lib/node_modules/npm/node_modules/fstream/lib/writer.js:284:26
2128 error fstream_stack Object.oncomplete (evalmachine.:107:15)
2129 verbose exit [ 34, true ]

Restore `type` attributes on operations object to remain compliant with 1.2 spec.

Discussion migrated from this commit comment.

As mentioned on this swagger-spec issue, this is required to be compliant with the spec but simply not quite clearly worded.

I don't think we should put this behind an option as we would essentially be allowing users to create noncompliant output, which can break outside tooling.

It seems to me that GoDaddy doesn't need multiple response types, so much as they need one response type and multiple error types. Would it not make sense to do something more like the following:

{
  "path": "/user/walletHistory",
  "operations": [{
    "method": "GET",
    "nickname": "getWalletHistory",
    "parameters": [],
    "responseMessages": [{
      "code": 200,
      "message": "Request was successful"
    }, {
      "code": 401,
      "message": "Unauthorized",
      "responseModel": "error"
    }, {
      "code": 404,
      "message": "Not Found",
      "responseModel": "error"
    }],
    "type": "array",
    "items": {
      "type": "transaction"
    }
  }]
}

This produces something like this, which eliminates the redundancy by excluding the responseModel from the 200.

Imgur

loopback-explorer is no longer exposes as express router

The loopback standard example expects loopbac-explorer as express middle ware.

The explorer.js has the following code:
var explorer = require('loopback-explorer'); var explorerApp = explorer(server, { basePath: restApiRoot }); server.use('/explorer', explorerApp);
This is failing with error saying explorerApp is undefined.

Examples not working

Hi there,

First of all, this is an awesome project! I was looking for a Swagger client like yours!!! Super cool! I was looking for the similar project as http://docs.strongloop.com/display/LB/Create+a+simple+API#CreateasimpleAPI-Createnewapplication.

So, I tried running the examples and they don't seem to work... The explorer does NOT expand the APIs for the "Product" or "User" example....

screen shot 2014-10-15 at 3 37 33 am

However, I noticed that the server outputs the swagger API... The resources list seem to be ok...

$ curl http://localhost:3000/explorer/resources
{
  "swaggerVersion": "1.2",
  "apiVersion": "1.3.0",
  "apis": [
    {
      "path": "/products"
    }
  ],
  "info": {}
}

However, the "api" object is missing...

$ curl http://localhost:3000/explorer/resources/products
{
  "apiVersion": "1.3.0",
  "swaggerVersion": "1.2",
  "basePath": "http://localhost:3000/api",
  "resourcePath": "/resources",
  "apis": [],
  "consumes": [
    "application/json",
    "application/x-www-form-urlencoded",
    "application/xml",
    "text/xml"
  ],
  "produces": [
    "application/json",
    "application/xml",
    "text/xml",
    "application/javascript",
    "text/javascript"
  ],
  "models": {
    "product": {
      "id": "product",
      "properties": {
        "name": {
          "type": "string",
          "required": true
        },
        "id": {
          "type": "number",
          "id": 1,
          "generated": true,
          "format": "double"
        }
      },
      "required": [
        "name"
      ]
    }
  }
}

Is this something not supported here? How to add the operations? It should be great to have it in the examples...
thanks!

Params not properly added from the UI

module.exports = function(Customer) {
  Customer.greet = function(msg, cb) {
    cb(null, 'hello ' + msg); // => prints "hello undefined"
  }

  Customer.remoteMethod('greet', {
    accepts: [{arg: 'msg', type: 'string', http: {source: 'query'}}],
    returns: [{arg: 'greeting', type: 'string'}]
  });
}

When using a model like this with a simple remote method, the UI doesn't properly add the msg param to the request.

Uncaught TypeError: Cannot read property 'length' of undefined

I am testing remote hook with 'loopback-getting-started-intermediate' & loopback-faq-model-hooks examples.

I came across the case where my server wasn't responding to delete requests. delete action is done, but i can't catch a remote hook for destroy method. I think you can produce it.

Well, the actual bug I wanted to report is:

Uncaught TypeError: Cannot read property 'length' of undefined ( swagger-ui.js : 2028 )

if (opts.highlightSizeThreshold && response.data.length > opts.highlightSizeThreshold) {
return response_body_el;
} else {
return hljs.highlightBlock(response_body_el);
}

Although no content, It seems that swagger-ui check 'length' in response.

Upgrade the Swagger UI

It would be nice to get a newer swagger UI in the explorer. The one we have now is incredibly old.

Edit: ok its not that old... but still.

I'm guessing the following people will be interested in this (please chime in if you have specifics):

@bajtos @raymondfeng @shelbys @STRML

model and model schema don't show details of nested attributes, only "modelconstructor"

Currently, the detail of array attributes and object attributes don't show on the API Explorer.

// common/models/xxxx.json
image: [{ url: 'string', ... }],
address: {
  city: { type: 'string' }
}

Model on API Explorer:

images (array[modelconstructor], optional)
address (modelconstructor, optional)

Model Schema on API Explorer:

"images": [
  "modelconstructor"
],
"address": "modelconstructor"

Incorrect model used for "hasMany through" relation methods

Consider the example of HasManyThrough relationship described in docs:

The “through” model, Appointment, has two foreign key properties, physicianId and patientId, that reference the primary keys in the declaring model, Physician, and the target model, Patient.

In the explorer UI, the route POST /patients/{id}/physicians shows Appointment instead of Physician as the expected request model.

screen shot 2014-08-13 at 9 54 56

This issue is based on this StackOverflow question.

Swagger validation error when running on 0.0.0.0

screen shot 2015-09-08 at 4 47 58 pm

Clicking on the ERROR box, opens http://online.swagger.io/validator/debug?url=http://0.0.0.0:3000/api/swagger.json, with the following message:

[{"level":"error","message":"Can't read from file http://0.0.0.0:3000/api/swagger.json"}]

package.json:

  "dependencies": {
    "compression": "^1.0.3",
    "cors": "^2.5.2",
    "errorhandler": "^1.1.1",
    "loopback": "^2.14.0",
    "loopback-boot": "^2.6.5",
    "loopback-datasource-juggler": "^2.19.0",
    "serve-favicon": "^2.0.1"
  },
  "optionalDependencies": {
    "loopback-explorer": "^2.0.0"
  }

Custom routes in bootscripts

It would be nice if we had a way to add custom routes defined in a bootscript to the explorer.
It would also be nice if we could specify some options like params, headers, response and a description to the explorer.

StrongLoop API Explorer returning this.type.split error

I have just tried to use the StrongLoop API Explorer as explained on http://docs.strongloop.com/display/LB/Use+API+Explorer; I have followed all the steps indicated in the document starting from downloading the sample code from https://github.com/strongloop/loopback-explorer.

When I hit "Try it out" I keep getting a JS error (from firebug)

TypeError: this.type.split is not a function
http://localhost:3000/explorer/lib/shred.bundle.js
Line 2034

and the following is the response body that I keep getting

{
    "error": {
"name": "ValidationError",
"status": 422,
"message": "The `Person` instance is not valid. Details: `FirstName` can't be blank; `LastName` can't be blank; `Age` can't be blank; `DOB` can't be blank.",
"statusCode": 422,
"details": {
  "context": "Person",
  "codes": {
    "FirstName": [
      "presence"
    ],
    "LastName": [
      "presence"
    ],
    "Age": [
      "presence"
    ],
    "DOB": [
      "presence"
    ]
  },
  "messages": {
    "FirstName": [
      "can't be blank"
    ],
    "LastName": [
      "can't be blank"
    ],
    "Age": [
      "can't be blank"
    ],
    "DOB": [
      "can't be blank"
    ]
  }
},
"stack": "ValidationError: The `Person` instance is not valid. Details: `FirstName` can't be blank; `LastName` can't be blank; `Age` can't be blank; `DOB` can't be blank.\n    at D:\\explorerAPI\\node_modules\\loopback-datasource-juggler\\lib\\dao.js:156:16\n    at ModelConstructor.<anonymous> (D:\\explorerAPI\\node_modules\\loopback-datasource-juggler\\lib\\validations.js:453:11)\n    at ModelConstructor.next (D:\\explorerAPI\\node_modules\\loopback-datasource-juggler\\lib\\hooks.js:66:12)\n    at ModelConstructor.<anonymous> (D:\\explorerAPI\\node_modules\\loopback-datasource-juggler\\lib\\validations.js:450:23)\n    at ModelConstructor.trigger (D:\\explorerAPI\\node_modules\\loopback-datasource-juggler\\lib\\hooks.js:56:12)\n    at ModelConstructor.Validatable.isValid (D:\\explorerAPI\\node_modules\\loopback-datasource-juggler\\lib\\validations.js:430:8)\n    at Function.DataAccessObject.create (D:\\explorerAPI\\node_modules\\loopback-datasource-juggler\\lib\\dao.js:152:7)\n    at SharedMethod.invoke (D:\\explorerAPI\\node_modules\\loopback\\node_modules\\strong-remoting\\lib\\shared-method.js:207:17)\n    at HttpContext.invoke (D:\\explorerAPI\\node_modules\\loopback\\node_modules\\strong-remoting\\lib\\http-context.js:243:12)\n    at D:\\explorerAPI\\node_modules\\loopback\\node_modules\\strong-remoting\\lib\\remote-objects.js:475:9"

}
}

Any help in fixing this would be highly appreciated.

Thank you in advance

Remote method does not show up in swagger

  1. If you create a remote method in a boot (server/boot/your-script.js) script, it does not show up in the explorer.
  2. If you create a remote method in server/server.js, it does not show up in explorer.

For point 1, @raymondfeng suggested you can get around it by make sure your script loads first (like changing your-script.js to a.js to make sure it loads first). I confirmed the workaround and it does work, but there needs to be a better solution than naming your scripts to load first.

Polymorphic belongsTo relation cause explorer fails to mount

common/models/comment.json

  "relations": {
    "parent": {
      "type": "belongsTo",
      "model": "commentable",
      "polymorphic": true
    }
  }
/Developer/Projects/WebStormProjects/utopia-loopback/node_modules/loopback-explorer/lib/model-helper.js:21
    var def = modelClass.definition;
                        ^
TypeError: Cannot read property 'definition' of null
    at generateModelDefinition (/Developer/Projects/WebStormProjects/utopia-loopback/node_modules/loopback-explorer/lib/model-helper.js:21:25)
    at generateModelDefinition (/Developer/Projects/WebStormProjects/utopia-loopback/node_modules/loopback-explorer/lib/model-helper.js:70:7)
    at generateModelDefinition (/Developer/Projects/WebStormProjects/utopia-loopback/node_modules/loopback-explorer/lib/model-helper.js:70:7)
    at Object.generateModelDefinition (/Developer/Projects/WebStormProjects/utopia-loopback/node_modules/loopback-explorer/lib/model-helper.js:70:7)
    at Object.module.exports.generateAPIDoc (/Developer/Projects/WebStormProjects/utopia-loopback/node_modules/loopback-explorer/lib/class-helper.js:33:27)
    at routes.forEach.className (/Developer/Projects/WebStormProjects/utopia-loopback/node_modules/loopback-explorer/lib/swagger.js:47:50)
    at Array.forEach (native)
    at Swagger (/Developer/Projects/WebStormProjects/utopia-loopback/node_modules/loopback-explorer/lib/swagger.js:46:11)
    at explorer (/Developer/Projects/WebStormProjects/utopia-loopback/node_modules/loopback-explorer/index.js:32:3)
    at mountLoopBackExplorer (/Developer/Projects/WebStormProjects/utopia-loopback/server/boot/explorer.js:14:21)

use of require('lodash.X') bloats the dependency tree

Would you accept a PR to switch over to using lodash directly, basically converting require('lodash.clonedeep') to require('lodash').cloneDeep?

Using the lodash.X modules doesn't save diskspace,lodash is < 1M, and loopback-explorer ends up depending on ~3M of lodash dependencies by using the individual modules. It also effects install time, because npm ends up downloading and installing 136 (!!) individual lodash modules while satisfying the 4 high-level deps.

924K   node_modules/lodash
% du -hs loopback-explorer/node_modules/lodash.*
584K    lodash.assign
900K    lodash.clonedeep
128K    lodash.defaults
1.4M    lodash.pick
[email protected][email protected]
├─┬ [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ └── [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ ├── [email protected]
│ │ │ │ │ └── [email protected]
│ │ │ │ └── [email protected]
│ │ │ └── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ └─┬ [email protected]
│   └── [email protected]
├── [email protected]
└─┬ [email protected]
  ├── [email protected]
  ├── [email protected]
  └── [email protected][email protected]
├─┬ [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ └── [email protected]
│ ├── [email protected]
│ ├── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ └─┬ [email protected]
│ │   ├── [email protected]
│ │   └── [email protected]
│ ├─┬ [email protected]
│ │ └── [email protected]
│ └─┬ [email protected]
│   └── [email protected]
└─┬ [email protected]
  ├─┬ [email protected]
  │ ├── [email protected]
  │ └── [email protected]
  ├─┬ [email protected]
  │ ├─┬ [email protected]
  │ │ ├─┬ [email protected]
  │ │ │ ├─┬ [email protected]
  │ │ │ │ ├── [email protected]
  │ │ │ │ └── [email protected]
  │ │ │ └─┬ [email protected]
  │ │ │   └── [email protected]
  │ │ ├─┬ [email protected]
  │ │ │ ├─┬ [email protected]
  │ │ │ │ ├── [email protected]
  │ │ │ │ └── [email protected]
  │ │ │ └─┬ [email protected]
  │ │ │   └── [email protected]
  │ │ └── [email protected]
  │ └── [email protected]
  ├── [email protected]
  └─┬ [email protected]
    └── [email protected][email protected]
├── [email protected]
└─┬ [email protected]
  ├── [email protected]
  ├── [email protected]
  └── [email protected][email protected]
├─┬ [email protected]
│ ├── [email protected]
│ └─┬ [email protected]
│   └── [email protected]
├─┬ [email protected]
│ ├─┬ [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └─┬ [email protected]
│ │ │ │ │   ├── [email protected]
│ │ │ │ │   └── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └─┬ [email protected]
│ │ │ │ │   ├── [email protected]
│ │ │ │ │   └── [email protected]
│ │ │ │ └── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ └─┬ [email protected]
│ │   └── [email protected]
│ ├─┬ [email protected]
│ │ ├─┬ [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ └── [email protected]
│ ├─┬ [email protected]
│ │ ├── [email protected]
│ │ └─┬ [email protected]
│ │   └── [email protected]
│ └── [email protected]
├─┬ [email protected]
│ ├─┬ [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├── [email protected]
│ │ │ └── [email protected]
│ │ ├─┬ [email protected]
│ │ │ ├─┬ [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └─┬ [email protected]
│ │ │ │ │   ├── [email protected]
│ │ │ │ │   └── [email protected]
│ │ │ │ ├─┬ [email protected]
│ │ │ │ │ └─┬ [email protected]
│ │ │ │ │   ├── [email protected]
│ │ │ │ │   └── [email protected]
│ │ │ │ └── [email protected]
│ │ │ └── [email protected]
│ │ ├── [email protected]
│ │ └─┬ [email protected]
│ │   └── [email protected]
│ └── [email protected]
└─┬ [email protected]
  └── [email protected]

Remember Access Token

It will be very very helpful when explorer remember access token after page was reloaded. Maybe store token in cookies. For example when i change my model configuration i need to reload explorer and always to set token again.

Many thanks guys!

Support OPTIONS verb

Although OPTIONS is supported in screen.css by swagger-ui, it is not currently supported by loopback-explorer.

Compare Swagger UI 1.0 and 2.0

We are planning on upgrading to the latest version of the swagger-ui. Since we added several UI enhancements, we need to do a comparison of our swagger-ui 1.x fork and the current swagger-ui 2.x.

The two major UI additions I am aware of are:

  • visualizing response models
  • visualizing validation / json schema restrictions

Even if these are not implemented in in the swagger-ui 2.0, we are still going to upgrade to this version. This will provide a clear path to supporting swagger 2.0 spec in the explorer.

At this point we will evaluate how to re-implment our enhancements. We should try to upstream them, but might end up with another fork in order to add them in.

/cc @raymondfeng @ijroth @altsang @bajtos

TypeError: Cannot read property 'name' of undefined

I get a TypeError: Cannot read property 'name' of undefined when I do the following:

Added var tools = require('./tools'); to server.js

The tools.js file contained:
Array.prototype.containsId = function(needle) {
for (i in this) {
if (this[i] == needle) return true;
}
return false;
}

Array.prototype.containsDroneId = function(needle) {
for (i in this) {
if (i === needle) return true;
}
return false;
} (edited)

And it produced:

/Users/dashby/workarea/StrongLoop2.0/StrongDroneAPI/node_modules/loopback-explorer/lib/model-helper.js:22
var name = def.name;
^
TypeError: Cannot read property 'name' of undefined
at generateModelDefinition (/Users/dashby/workarea/StrongLoop2.0/StrongDroneAPI/node_modules/loopback-explorer/lib/model-helper.js:22:19)
at generateModelDefinition (/Users/dashby/workarea/StrongLoop2.0/StrongDroneAPI/node_modules/loopback-explorer/lib/model-helper.js:106:7)
at Object.generateModelDefinition (/Users/dashby/workarea/StrongLoop2.0/StrongDroneAPI/node_modules/loopback-explorer/lib/model-helper.js:99:9)
at Object.module.exports.generateAPIDoc (/Users/dashby/workarea/StrongLoop2.0/StrongDroneAPI/node_modules/loopback-explorer/lib/class-helper.js:33:27)
at /Users/dashby/workarea/StrongLoop2.0/StrongDroneAPI/node_modules/loopback-explorer/lib/swagger.js:47:50
at Array.forEach (native)
at Swagger (/Users/dashby/workarea/StrongLoop2.0/StrongDroneAPI/node_modules/loopback-explorer/lib/swagger.js:46:11)
at explorer (/Users/dashby/workarea/StrongLoop2.0/StrongDroneAPI/node_modules/loopback-explorer/index.js:31:3)
at mountLoopBackExplorer (/Users/dashby/workarea/StrongLoop2.0/StrongDroneAPI/server/boot/explorer.js:14:21)
at /Users/dashby/workarea/StrongLoop2.0/StrongDroneAPI/node_modules/loopback-boot/lib/executor.js:184:7

Cannot read property 'name' of undefined (again)

I just updated to the latest version and got


TypeError: Cannot read property 'name' of undefined
    at generateModelDefinition (C:\bla\node_modules\loopback-explorer\lib\model-helper.js:24:19)
    at Object.generateModelDefinition (C:\bla\node_modules\loopback-explorer\lib\model-helper.js:110:7)
    at Object.module.exports.generateAPIDoc (C:\bla\node_modules\loopback-explorer\lib\class-helper.js:34:27)
    at C:\bla\node_modules\loopback-explorer\lib\swagger.js:63:50
    at Array.forEach (native)
    at Swagger (C:\bla\node_modules\loopback-explorer\lib\swagger.js:62:11)
    at explorer (C:\bla\node_modules\loopback-explorer\index.js:31:3)
    at Object.mountLoopBackExplorer [as func] (C:\bla\server\boot\explorer.js:14:21)
    at C:\bla\node_modules\loopback-boot\lib\executor.js:225:9
    at iterate (C:\bla\node_modules\loopback-boot\node_modules\async\lib\async.js:149:13)  

related to #49/#50
Still don't know why, but hot-fixed it (lib/model-helper.js @ line 108) with


   for (var i = 0, n = referencedModels.length; i < n; i++) {
      if(referencedModels[i].definition)
      generateModelDefinition(referencedModels[i], out);
    }

for now...

unable to put / post data

I've installed the standard example app (using yo loopback:example ).

using the explorer, the get and delete examples work well.

However, trying to use put or post nothing happens, and this error appears in the dev console:

Uncaught TypeError: undefined is not a function shred.bundle.js:2034
Object.defineProperties.processor.get shred.bundle.js:2034
Object.defineProperties.body.get shred.bundle.js:2008
Object.defineProperties.length.get shred.bundle.js:2052
Object.defineProperties.body.set shred.bundle.js:975
processOptions shred.bundle.js:1126
Request shred.bundle.js:846
Shred.request shred.bundle.js:388
ShredHttpClient.execute swagger.js:1485
SwaggerHttp.execute swagger.js:1287
SwaggerRequest swagger.js:1181
SwaggerOperation.do swagger.js:898
(anonymous function) swagger.js:6
OperationView.submitOperation swagger-ui.js:1765
p.event.dispatch jquery-1.8.0.min.js:2
g.handle.h jquery-1.8.0.min.js:2

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.