Git Product home page Git Product logo

api-platform / api-doc-parser Goto Github PK

View Code? Open in Web Editor NEW
98.0 13.0 71.0 602 KB

Transforms a Hydra API doc in an intermediate representation that can be used for various tasks such as creating smart API clients, scaffolding code or building administration interfaces.

License: MIT License

JavaScript 0.73% TypeScript 99.27%
javascript api hydra api-platform json-ld rest-api rest openapi swagger parser

api-doc-parser's Introduction

API Platform

API Platform is a next-generation web framework designed to easily create API-first projects without compromising extensibility and flexibility:

The official project documentation is available on the API Platform website.

API Platform embraces open web standards and the Linked Data movement. Your API will automatically expose structured data. It means that your API Platform application is usable out of the box with technologies of the semantic web.

It also means that your SEO will be improved because Google leverages these formats.

Last but not least, the server component of API Platform is built on top of the Symfony framework, while client components leverage React (Vue.js flavors are also available). It means that you can:

  • Use thousands of Symfony bundles and React components with API Platform.
  • Integrate API Platform in any existing Symfony, React, or Vue application.
  • Reuse all your Symfony and JavaScript skills, and benefit from the incredible amount of documentation available.
  • Enjoy the popular Doctrine ORM (used by default, but fully optional: you can use the data provider you want, including but not limited to MongoDB and Elasticsearch)

Install

Read the official "Getting Started" guide.

Credits

Created by Kévin Dunglas. Commercial support is available at Les-Tilleuls.coop.

api-doc-parser's People

Contributors

alanpoulain avatar arojunior avatar bcobzh avatar bpolaszek avatar caseywebb avatar clementtalleu avatar dependabot-preview[bot] avatar dunglas avatar gregcop1 avatar helios1101 avatar j3m5 avatar jfthuillier avatar julienfalque avatar kraynel avatar lharz avatar luca-nardelli avatar lutangar avatar mauchede avatar mysiar avatar omack avatar pawelsuwinski avatar pborreli avatar ragboyjr avatar simperfit avatar slim avatar snakegit1 avatar soyuka avatar strikerrus avatar thcolin avatar vincentchalamon avatar

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  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

api-doc-parser's Issues

Module not found: Can't resolve 'jsonref'

Version(s) affected: 0.15.7

Description

Trying to upgrade from 0.15.2 to 0.15.7 gives me the following compilation error in our API platform admin app:

./node_modules/@api-platform/api-doc-parser/lib/esm/openapi3/handleJson.js
Module not found: Can't resolve 'jsonref' in '/usr/src/admin/node_modules/@api-platform/api-doc-parser/lib/esm/openapi3'

I verified that node_modules/jsonref exists. I saw that jsonref was recently added and some importing adaptions were done as well. I don't know much about different JS module types and their imports, but could this be one of the ESM/CJS incompatibilities or something like that?

How to reproduce

sorry, leaving this out for now since I'm not sure yet if this is a bug or not.

Possible Solution

Additional Context

Error "Unable to find the URL for" for custom resource without get operation

Hello,

I've created an API Resource for ChangePassword Request
for add entrypoint with POST operation with custom controller.
There are no GET operations (as item or collection)

<?php

declare(strict_types=1);

namespace App\User\Request;

use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ApiResource(
 *     collectionOperations={
 *         "post"={
 *             "method"="POST",
 *             "path"="/token/verify",
 *             "controller"="App\User\Action\Account\VerifyTokenAction"
 *         }
 *     },
 *     itemOperations={}
 * )
 */
final class VerifyTokenRequest
{
    /**
     * @var string
     * @Assert\NotBlank
     */
    public $token;
}

But into api-doc-parser, (used by API Platform Admin), in this case, i have a error cause by this new entry into documentation. And display Unable to retrieve API documentation. into browser.

Error: "Unable to find the URL for "http://localhost:8080/docs.jsonld#Entrypoint/VerifyTokenRequest"."
    parseHydraDocumentation parseHydraDocumentation.js:398
index.js:2178
    __stack_frame_overlay_proxy_console__ React
    componentDidMount HydraAdmin.js:86

Support for Swagger documenation format

API Doc Parser is designed to parse any API documentation format and convert it in the same intermediate representation. For now, only Hydra is supported but if you develop a parser for another format, please open a Pull Request to include it in the library.

I want to work in a parser for swagger documentation to be compatible with client-generator

There is some documentation about the layout of this "intermediate representation"? How it should be?

Extensive API calls due to filter preparation

I came across a rather unexpected change in the api-doc-parser which suddenly (I mean, of course after an update ;)) issues dedicate GET collection requests in order to determine the filter-parameters... for all the known api resources.

I'm pretty much aware that those filter parameters are only populated in the hydra-specs for the collection endpoint but as far as I can see there seems no option to turn that off. Right now, my client application issues around 100 additional API calls (~50 OPTIONS + ~50 GET) for the initialization which slows down the ramp up of my app tremendously...

As I can't find that much of information except the PRs in the admin and api-doc-parser components I'd like to know any suggestion to fail forward on that topic. I can imagine an option/flag to activate/deactivate the filter-parameter lookups or an additional hook that allows the subsequent enrichment of particular Resource objects whenever needed. I'm fine to work on that and to provide PRs, but I'd like to collect some info first.

This relates to #33

fetchResource loads actual items from the API due to wrong queryParameter

API Platform version(s) affected: 2.6.8

Description

The API doc parser uses fetch() via the fetchResource() method to load API metadata, and fails to apply the query parameter { itemsperpage: 0 } correctly to limit the request to only metadata and no API items.

fetchResource() tries to set the query parameter via a secondary options parameter, however fetch() doesn't support that - params have to be part of the url instead.

// Current code:
fetchJsonLd(
  resourceUrl,
  Object.assign({ itemsPerPage: 0 }, options)
)

// Fixed code:
fetchJsonLd(
  resourceUrl + "?itemsPerPage=0",
  options
)

How to reproduce

Possible Solution

Replace the Object.assign() call with an URL including the query parameter, possibly by building an URL:

const url = new URL(resource.url);
const params = new URLSearchParams(["itemsPerPage", 0]);
url.search = params.toString();

fetchJsonLd(url, options)

Additional Context

Please excuse that my code examples are in plain JS, not TS, since I'm not familiar enough with typescript.

TypeError: Cannot read property '0' of undefined

This is duplication of issue for api-platform/admin api-platform/admin#8

I have followed a guide, I have a tiny simple API build with api-platform but when I try to run Admin I have error in this line:

var range = supportedProperty['http://www.w3.org/ns/hydra/core#property'][0]['http://www.w3.org/2000/01/rdf-schema#range'][0]['@id'];

https://www.dropbox.com/s/9f5muw1ns0wkghv/%D0%A1%D0%BA%D1%80%D0%B8%D0%BD%D1%88%D0%BE%D1%82%202017-05-08%2008.53.59.png?dl=0

API entry point is correct, what else should I do to run this admin interface

Hydra document:

{
"@context":{
"@vocab":"http://localhost:8080/docs.jsonld#",
"hydra":"http://www.w3.org/ns/hydra/core#",
"rdf":"http://www.w3.org/1999/02/22-rdf-syntax-ns#",
"rdfs":"http://www.w3.org/2000/01/rdf-schema#",
"xmls":"http://www.w3.org/2001/XMLSchema#",
"owl":"http://www.w3.org/2002/07/owl#",
"domain":{
"@id":"rdfs:domain",
"@type":"@id"
},
"range":{
"@id":"rdfs:range",
"@type":"@id"
},
"subClassOf":{
"@id":"rdfs:subClassOf",
"@type":"@id"
},
"expects":{
"@id":"hydra:expects",
"@type":"@id"
},
"returns":{
"@id":"hydra:returns",
"@type":"@id"
}
},
"@id":"/docs.jsonld",
"hydra:title":"YourTour API",
"hydra:description":"YourTour system management API",
"hydra:entrypoint":"/",
"hydra:supportedClass":[
{
"@id":"http://schema.org/image",
"@type":"hydra:Class",
"rdfs:label":"OfferImage",
"hydra:title":"OfferImage",
"hydra:supportedProperty":[
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#OfferImage/url",
"@type":"rdf:Property",
"rdfs:label":"url",
"domain":"http://schema.org/image",
"range":"xmls:string"
},
"hydra:title":"url",
"hydra:required":true,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Image path"
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#OfferImage/offer",
"@type":"rdf:Property",
"rdfs:label":"offer",
"domain":"http://schema.org/image"
},
"hydra:title":"offer",
"hydra:required":false,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Offer relation"
}
],
"hydra:supportedOperation":[
{
"@type":"hydra:Operation",
"hydra:method":"GET",
"hydra:title":"Retrieves OfferImage resource.",
"rdfs:label":"Retrieves OfferImage resource.",
"returns":"http://schema.org/image"
},
{
"@type":"hydra:ReplaceResourceOperation",
"expects":"http://schema.org/image",
"hydra:method":"PUT",
"hydra:title":"Replaces the OfferImage resource.",
"rdfs:label":"Replaces the OfferImage resource.",
"returns":"http://schema.org/image"
},
{
"@type":"hydra:Operation",
"hydra:method":"DELETE",
"hydra:title":"Deletes the OfferImage resource.",
"rdfs:label":"Deletes the OfferImage resource.",
"returns":"owl:Nothing"
}
],
"hydra:description":"Class TourImages"
},
{
"@id":"http://schema.org/Offer",
"@type":"hydra:Class",
"rdfs:label":"Product",
"hydra:title":"Product",
"hydra:supportedProperty":[
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Product/image",
"@type":"rdf:Property",
"rdfs:label":"image",
"domain":"http://schema.org/Offer"
},
"hydra:title":"image",
"hydra:required":false,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get offer images collection."
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Product/catalogImage",
"@type":"rdf:Property",
"rdfs:label":"catalogImage",
"domain":"http://schema.org/Offer",
"range":"xmls:string"
},
"hydra:title":"catalogImage",
"hydra:required":false,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get catalog image."
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Product/catalogueImage",
"@type":"rdf:Property",
"rdfs:label":"catalogueImage",
"domain":"http://schema.org/Offer",
"range":"xmls:string"
},
"hydra:title":"catalogueImage",
"hydra:required":false,
"hydra:readable":false,
"hydra:writable":true,
"hydra:description":"Set offer catalogue image."
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Product/shortDescription",
"@type":"rdf:Property",
"rdfs:label":"shortDescription",
"domain":"http://schema.org/Offer",
"range":"xmls:string"
},
"hydra:title":"shortDescription",
"hydra:required":true,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get offer short description."
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Product/fullPrice",
"@type":"rdf:Property",
"rdfs:label":"fullPrice",
"domain":"http://schema.org/Offer",
"range":"xmls:decimal"
},
"hydra:title":"fullPrice",
"hydra:required":true,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get offer full price."
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Product/discountedPrice",
"@type":"rdf:Property",
"rdfs:label":"discountedPrice",
"domain":"http://schema.org/Offer",
"range":"xmls:decimal"
},
"hydra:title":"discountedPrice",
"hydra:required":false,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get offer discounted price"
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Product/discountAmount",
"@type":"rdf:Property",
"rdfs:label":"discountAmount",
"domain":"http://schema.org/Offer",
"range":"xmls:decimal"
},
"hydra:title":"discountAmount",
"hydra:required":true,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get offer discount amount"
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Product/soldAmount",
"@type":"rdf:Property",
"rdfs:label":"soldAmount",
"domain":"http://schema.org/Offer",
"range":"xmls:integer"
},
"hydra:title":"soldAmount",
"hydra:required":false,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get offer sold amount."
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Product/fullDescription",
"@type":"rdf:Property",
"rdfs:label":"fullDescription",
"domain":"http://schema.org/Offer",
"range":"xmls:string"
},
"hydra:title":"fullDescription",
"hydra:required":true,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get offer full description."
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Product/discountPercentage",
"@type":"rdf:Property",
"rdfs:label":"discountPercentage",
"domain":"http://schema.org/Offer",
"range":"xmls:decimal"
},
"hydra:title":"discountPercentage",
"hydra:required":false,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get offer discount percentage"
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Product/endDate",
"@type":"rdf:Property",
"rdfs:label":"endDate",
"domain":"http://schema.org/Offer",
"range":"xmls:dateTime"
},
"hydra:title":"endDate",
"hydra:required":false,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get offer end date."
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Product/startDate",
"@type":"rdf:Property",
"rdfs:label":"startDate",
"domain":"http://schema.org/Offer",
"range":"xmls:dateTime"
},
"hydra:title":"startDate",
"hydra:required":true,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get offer start date."
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Product/images",
"@type":"hydra:Link",
"rdfs:label":"images",
"domain":"http://schema.org/Offer",
"range":"http://schema.org/image"
},
"hydra:title":"images",
"hydra:required":false,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get images"
}
],
"hydra:supportedOperation":[
{
"@type":"hydra:Operation",
"hydra:method":"GET",
"hydra:title":"Retrieves Product resource.",
"rdfs:label":"Retrieves Product resource.",
"returns":"http://schema.org/Offer"
},
{
"@type":"hydra:ReplaceResourceOperation",
"expects":"http://schema.org/Offer",
"hydra:method":"PUT",
"hydra:title":"Replaces the Product resource.",
"rdfs:label":"Replaces the Product resource.",
"returns":"http://schema.org/Offer"
},
{
"@type":"hydra:Operation",
"hydra:method":"DELETE",
"hydra:title":"Deletes the Product resource.",
"rdfs:label":"Deletes the Product resource.",
"returns":"owl:Nothing"
}
],
"hydra:description":"Class Product"
},
{
"@id":"http://schema.org/Offer",
"@type":"hydra:Class",
"rdfs:label":"Tour",
"hydra:title":"Tour",
"hydra:supportedProperty":[
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Tour/days",
"@type":"hydra:Link",
"rdfs:label":"days",
"domain":"http://schema.org/Offer",
"range":"http://schema.org/Offer"
},
"hydra:title":"days",
"hydra:required":false,
"hydra:readable":true,
"hydra:writable":false,
"hydra:description":"Offer images collection"
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Tour/image",
"@type":"rdf:Property",
"rdfs:label":"image",
"domain":"http://schema.org/Offer"
},
"hydra:title":"image",
"hydra:required":false,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get offer images collection."
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Tour/catalogImage",
"@type":"rdf:Property",
"rdfs:label":"catalogImage",
"domain":"http://schema.org/Offer",
"range":"xmls:string"
},
"hydra:title":"catalogImage",
"hydra:required":false,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get catalog image."
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Tour/catalogueImage",
"@type":"rdf:Property",
"rdfs:label":"catalogueImage",
"domain":"http://schema.org/Offer",
"range":"xmls:string"
},
"hydra:title":"catalogueImage",
"hydra:required":false,
"hydra:readable":false,
"hydra:writable":true,
"hydra:description":"Set offer catalogue image."
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Tour/shortDescription",
"@type":"rdf:Property",
"rdfs:label":"shortDescription",
"domain":"http://schema.org/Offer",
"range":"xmls:string"
},
"hydra:title":"shortDescription",
"hydra:required":true,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get offer short description."
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Tour/fullPrice",
"@type":"rdf:Property",
"rdfs:label":"fullPrice",
"domain":"http://schema.org/Offer",
"range":"xmls:decimal"
},
"hydra:title":"fullPrice",
"hydra:required":true,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get offer full price."
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Tour/discountedPrice",
"@type":"rdf:Property",
"rdfs:label":"discountedPrice",
"domain":"http://schema.org/Offer",
"range":"xmls:decimal"
},
"hydra:title":"discountedPrice",
"hydra:required":false,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get offer discounted price"
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Tour/discountAmount",
"@type":"rdf:Property",
"rdfs:label":"discountAmount",
"domain":"http://schema.org/Offer",
"range":"xmls:decimal"
},
"hydra:title":"discountAmount",
"hydra:required":true,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get offer discount amount"
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Tour/soldAmount",
"@type":"rdf:Property",
"rdfs:label":"soldAmount",
"domain":"http://schema.org/Offer",
"range":"xmls:integer"
},
"hydra:title":"soldAmount",
"hydra:required":false,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get offer sold amount."
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Tour/fullDescription",
"@type":"rdf:Property",
"rdfs:label":"fullDescription",
"domain":"http://schema.org/Offer",
"range":"xmls:string"
},
"hydra:title":"fullDescription",
"hydra:required":true,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get offer full description."
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Tour/discountPercentage",
"@type":"rdf:Property",
"rdfs:label":"discountPercentage",
"domain":"http://schema.org/Offer",
"range":"xmls:decimal"
},
"hydra:title":"discountPercentage",
"hydra:required":false,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get offer discount percentage"
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Tour/endDate",
"@type":"rdf:Property",
"rdfs:label":"endDate",
"domain":"http://schema.org/Offer",
"range":"xmls:dateTime"
},
"hydra:title":"endDate",
"hydra:required":false,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get offer end date."
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Tour/startDate",
"@type":"rdf:Property",
"rdfs:label":"startDate",
"domain":"http://schema.org/Offer",
"range":"xmls:dateTime"
},
"hydra:title":"startDate",
"hydra:required":true,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get offer start date."
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Tour/images",
"@type":"hydra:Link",
"rdfs:label":"images",
"domain":"http://schema.org/Offer",
"range":"http://schema.org/image"
},
"hydra:title":"images",
"hydra:required":false,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Get images"
}
],
"hydra:supportedOperation":[
{
"@type":"hydra:Operation",
"hydra:method":"GET",
"hydra:title":"Retrieves Tour resource.",
"rdfs:label":"Retrieves Tour resource.",
"returns":"http://schema.org/Offer"
},
{
"@type":"hydra:ReplaceResourceOperation",
"expects":"http://schema.org/Offer",
"hydra:method":"PUT",
"hydra:title":"Replaces the Tour resource.",
"rdfs:label":"Replaces the Tour resource.",
"returns":"http://schema.org/Offer"
},
{
"@type":"hydra:Operation",
"hydra:method":"DELETE",
"hydra:title":"Deletes the Tour resource.",
"rdfs:label":"Deletes the Tour resource.",
"returns":"owl:Nothing"
}
],
"hydra:description":"Tour"
},
{
"@id":"http://schema.org/Offer",
"@type":"hydra:Class",
"rdfs:label":"TourDay",
"hydra:title":"TourDay",
"hydra:supportedProperty":[
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#TourDay/tour",
"@type":"hydra:Link",
"rdfs:label":"tour",
"domain":"http://schema.org/Offer",
"range":"http://schema.org/Offer"
},
"hydra:title":"tour",
"hydra:required":false,
"hydra:readable":true,
"hydra:writable":false,
"hydra:description":"Tour relation"
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#TourDay/dayNumber",
"@type":"rdf:Property",
"rdfs:label":"dayNumber",
"domain":"http://schema.org/Offer",
"range":"xmls:integer"
},
"hydra:title":"dayNumber",
"hydra:required":false,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Tour day number"
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#TourDay/dayDescription",
"@type":"rdf:Property",
"rdfs:label":"dayDescription",
"domain":"http://schema.org/Offer",
"range":"xmls:string"
},
"hydra:title":"dayDescription",
"hydra:required":false,
"hydra:readable":true,
"hydra:writable":true,
"hydra:description":"Tour day description"
}
],
"hydra:supportedOperation":[
{
"@type":"hydra:Operation",
"hydra:method":"GET",
"hydra:title":"Retrieves TourDay resource.",
"rdfs:label":"Retrieves TourDay resource.",
"returns":"http://schema.org/Offer"
},
{
"@type":"hydra:ReplaceResourceOperation",
"expects":"http://schema.org/Offer",
"hydra:method":"PUT",
"hydra:title":"Replaces the TourDay resource.",
"rdfs:label":"Replaces the TourDay resource.",
"returns":"http://schema.org/Offer"
},
{
"@type":"hydra:Operation",
"hydra:method":"DELETE",
"hydra:title":"Deletes the TourDay resource.",
"rdfs:label":"Deletes the TourDay resource.",
"returns":"owl:Nothing"
}
],
"hydra:description":"Tour program day."
},
{
"@id":"#Entrypoint",
"@type":"hydra:Class",
"hydra:title":"The API entrypoint",
"hydra:supportedProperty":[
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Entrypoint/offerImage",
"@type":"hydra:Link",
"domain":"#Entrypoint",
"rdfs:label":"The collection of OfferImage resources",
"range":"hydra:PagedCollection",
"hydra:supportedOperation":[
{
"@type":"hydra:Operation",
"hydra:method":"GET",
"hydra:title":"Retrieves the collection of OfferImage resources.",
"rdfs:label":"Retrieves the collection of OfferImage resources.",
"returns":"hydra:PagedCollection"
},
{
"@type":"hydra:CreateResourceOperation",
"expects":"http://schema.org/image",
"hydra:method":"POST",
"hydra:title":"Creates a OfferImage resource.",
"rdfs:label":"Creates a OfferImage resource.",
"returns":"http://schema.org/image"
}
]
},
"hydra:title":"The collection of OfferImage resources",
"hydra:readable":true,
"hydra:writable":false
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Entrypoint/product",
"@type":"hydra:Link",
"domain":"#Entrypoint",
"rdfs:label":"The collection of Product resources",
"range":"hydra:PagedCollection",
"hydra:supportedOperation":[
{
"@type":"hydra:Operation",
"hydra:method":"GET",
"hydra:title":"Retrieves the collection of Product resources.",
"rdfs:label":"Retrieves the collection of Product resources.",
"returns":"hydra:PagedCollection"
},
{
"@type":"hydra:CreateResourceOperation",
"expects":"http://schema.org/Offer",
"hydra:method":"POST",
"hydra:title":"Creates a Product resource.",
"rdfs:label":"Creates a Product resource.",
"returns":"http://schema.org/Offer"
}
]
},
"hydra:title":"The collection of Product resources",
"hydra:readable":true,
"hydra:writable":false
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Entrypoint/tour",
"@type":"hydra:Link",
"domain":"#Entrypoint",
"rdfs:label":"The collection of Tour resources",
"range":"hydra:PagedCollection",
"hydra:supportedOperation":[
{
"@type":"hydra:Operation",
"hydra:method":"GET",
"hydra:title":"Retrieves the collection of Tour resources.",
"rdfs:label":"Retrieves the collection of Tour resources.",
"returns":"hydra:PagedCollection"
},
{
"@type":"hydra:CreateResourceOperation",
"expects":"http://schema.org/Offer",
"hydra:method":"POST",
"hydra:title":"Creates a Tour resource.",
"rdfs:label":"Creates a Tour resource.",
"returns":"http://schema.org/Offer"
}
]
},
"hydra:title":"The collection of Tour resources",
"hydra:readable":true,
"hydra:writable":false
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#Entrypoint/tourDay",
"@type":"hydra:Link",
"domain":"#Entrypoint",
"rdfs:label":"The collection of TourDay resources",
"range":"hydra:PagedCollection",
"hydra:supportedOperation":[
{
"@type":"hydra:Operation",
"hydra:method":"GET",
"hydra:title":"Retrieves the collection of TourDay resources.",
"rdfs:label":"Retrieves the collection of TourDay resources.",
"returns":"hydra:PagedCollection"
},
{
"@type":"hydra:CreateResourceOperation",
"expects":"http://schema.org/Offer",
"hydra:method":"POST",
"hydra:title":"Creates a TourDay resource.",
"rdfs:label":"Creates a TourDay resource.",
"returns":"http://schema.org/Offer"
}
]
},
"hydra:title":"The collection of TourDay resources",
"hydra:readable":true,
"hydra:writable":false
}
],
"hydra:supportedOperation":{
"@type":"hydra:Operation",
"hydra:method":"GET",
"rdfs:label":"The API entrypoint.",
"returns":"#EntryPoint"
}
},
{
"@id":"#ConstraintViolation",
"@type":"hydra:Class",
"hydra:title":"A constraint violation",
"hydra:supportedProperty":[
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#ConstraintViolation/propertyPath",
"@type":"rdf:Property",
"rdfs:label":"propertyPath",
"domain":"#ConstraintViolation",
"range":"xmls:string"
},
"hydra:title":"propertyPath",
"hydra:description":"The property path of the violation",
"hydra:readable":true,
"hydra:writable":false
},
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#ConstraintViolation/message",
"@type":"rdf:Property",
"rdfs:label":"message",
"domain":"#ConstraintViolation",
"range":"xmls:string"
},
"hydra:title":"message",
"hydra:description":"The message associated with the violation",
"hydra:readable":true,
"hydra:writable":false
}
]
},
{
"@id":"#ConstraintViolationList",
"@type":"hydra:Class",
"subClassOf":"hydra:Error",
"hydra:title":"A constraint violation list",
"hydra:supportedProperty":[
{
"@type":"hydra:SupportedProperty",
"hydra:property":{
"@id":"#ConstraintViolationList/violations",
"@type":"rdf:Property",
"rdfs:label":"violations",
"domain":"#ConstraintViolationList",
"range":"#ConstraintViolation"
},
"hydra:title":"violations",
"hydra:description":"The violations",
"hydra:readable":true,
"hydra:writable":false
}
]
}
]
}

@dunglas

[DataProvider] Empty Headers and 401 response

API Platform version(s) affected: 2.6.4

Description
I try to add JWT token to the header, but it stays empty no matter what returning 401 response.

How to reproduce

function App() {

    const getHeaders = () => localStorage.getItem("token") ? {
        Authorization: `Bearer ${localStorage.getItem("token")}`,
    } : {};

    const customFetchHydra = (url, options = {}) => {
        fetchHydra(url, {
            ...options,
            headers: new Headers(getHeaders()),
        })
    };

    const dataProvider = hydraDataProvider(API_ENTRYPOINT, customFetchHydra);

    return (
        <HydraAdmin ... dataProvide={dataProvider} ...>
            ...
        </HydraAdmin>
    );
}

Possible Solution
~

Additional Context
I tried to debug compiled fetchJsonLd.js:
image

then I was trying to show all headers in the chrome console at that moment:
image

I have no idea where "next" comes from...

Test `src/openapi3/handleJson.test.ts` fails

API Doc Parser version(s) affected: 0.5.0

Description

Test src/openapi3/handleJson.test.ts fails

How to reproduce

yarn install
yarn run test

Possible Solution

Fixing typescript code.

Additional Context

tsc -v

Version 4.8.4

yarn run test

yarn run v1.22.19
$ NODE_OPTIONS=--experimental-vm-modules jest
(node:8739) ExperimentalWarning: VM Modules is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
 PASS  src/swagger/handleJson.test.ts
 PASS  src/hydra/fetchJsonLd.test.ts
 PASS  src/utils/getResources.test.ts
 FAIL  src/openapi3/handleJson.test.ts
  ● Test suite failed to run

    src/openapi3/handleJson.ts:14:15 - error TS2322: Type 'T | ReferenceObject' is not assignable to type 'object'.
      Type 'T' is not assignable to type 'object'.

    14   !("$ref" in maybeRef);
                     ~~~~~~~~

      src/openapi3/handleJson.ts:13:16
        13 const isRef = <T>(maybeRef: T | OpenAPIV3.ReferenceObject): maybeRef is T =>
                          ~
        This type parameter might need an `extends object` constraint.
    src/openapi3/handleJson.ts:180:10 - error TS2352: Conversion of type 'undefined' to type 'SchemaObject' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.

    180       ? (get(
                 ~~~~
    181           editOperation,
        ~~~~~~~~~~~~~~~~~~~~~~~~
    182           "requestBody.content.application/json.schema"
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    183         ) as OpenAPIV3.SchemaObject)
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 FAIL  src/hydra/parseHydraDocumentation.test.ts
  ● Test suite failed to run

    src/hydra/parseHydraDocumentation.ts:149:26 - error TS2352: Conversion of type 'undefined' to type 'string' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.

    149       const onProperty = get(
                                 ~~~~
    150         range,
        ~~~~~~~~~~~~~~
    151         '["http://www.w3.org/2002/07/owl#equivalentClass"][0]["http://www.w3.org/2002/07/owl#onProperty"][0]["@id"]'
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    152       ) as string;
        ~~~~~~~~~~~~~~~~~
    src/hydra/parseHydraDocumentation.ts:153:29 - error TS2352: Conversion of type 'undefined' to type 'string' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.

    153       const allValuesFrom = get(
                                    ~~~~
    154         range,
        ~~~~~~~~~~~~~~
    155         '["http://www.w3.org/2002/07/owl#equivalentClass"][0]["http://www.w3.org/2002/07/owl#allValuesFrom"][0]["@id"]'
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    156       ) as string;
        ~~~~~~~~~~~~~~~~~
    src/hydra/parseHydraDocumentation.ts:256:37 - error TS2352: Conversion of type 'undefined' to type 'ExpandedRdfProperty' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.

    256           const supportedProperty = get(
                                            ~~~~
    257             supportedProperties,
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    258             '["http://www.w3.org/ns/hydra/core#property"][0]'
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    259           ) as ExpandedRdfProperty;
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    src/hydra/parseHydraDocumentation.ts:261:25 - error TS2352: Conversion of type 'null' to type 'string' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.

    261           const range = get(
                                ~~~~
    262             supportedProperty,
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ... 
    264             null
        ~~~~~~~~~~~~~~~~
    265           ) as string;
        ~~~~~~~~~~~~~~~~~~~~~

Test Suites: 2 failed, 3 passed, 5 total
Tests:       6 passed, 6 total
Snapshots:   0 total
Time:        3.349 s
Ran all test suites.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
ricfio@LENOVO:~/projects/api-platform/api-doc-parser$ yarn run test
yarn run v1.22.19
$ NODE_OPTIONS=--experimental-vm-modules jest
(node:8874) ExperimentalWarning: VM Modules is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
 PASS  src/swagger/handleJson.test.ts
 PASS  src/hydra/fetchJsonLd.test.ts
 PASS  src/utils/getResources.test.ts
 FAIL  src/openapi3/handleJson.test.ts
  ● Test suite failed to run

    src/openapi3/handleJson.ts:14:15 - error TS2322: Type 'ReferenceObject | T' is not assignable to type 'object'.
      Type 'T' is not assignable to type 'object'.

    14   !("$ref" in maybeRef);
                     ~~~~~~~~

      src/openapi3/handleJson.ts:13:16
        13 const isRef = <T>(maybeRef: T | OpenAPIV3.ReferenceObject): maybeRef is T =>
                          ~
        This type parameter might need an `extends object` constraint.
    src/openapi3/handleJson.ts:180:10 - error TS2352: Conversion of type 'undefined' to type 'SchemaObject' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.

    180       ? (get(
                 ~~~~
    181           editOperation,
        ~~~~~~~~~~~~~~~~~~~~~~~~
    182           "requestBody.content.application/json.schema"
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    183         ) as OpenAPIV3.SchemaObject)
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 FAIL  src/hydra/parseHydraDocumentation.test.ts
  ● Test suite failed to run

    src/hydra/parseHydraDocumentation.ts:149:26 - error TS2352: Conversion of type 'undefined' to type 'string' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.

    149       const onProperty = get(
                                 ~~~~
    150         range,
        ~~~~~~~~~~~~~~
    151         '["http://www.w3.org/2002/07/owl#equivalentClass"][0]["http://www.w3.org/2002/07/owl#onProperty"][0]["@id"]'
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    152       ) as string;
        ~~~~~~~~~~~~~~~~~
    src/hydra/parseHydraDocumentation.ts:153:29 - error TS2352: Conversion of type 'undefined' to type 'string' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.

    153       const allValuesFrom = get(
                                    ~~~~
    154         range,
        ~~~~~~~~~~~~~~
    155         '["http://www.w3.org/2002/07/owl#equivalentClass"][0]["http://www.w3.org/2002/07/owl#allValuesFrom"][0]["@id"]'
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    156       ) as string;
        ~~~~~~~~~~~~~~~~~
    src/hydra/parseHydraDocumentation.ts:256:37 - error TS2352: Conversion of type 'undefined' to type 'ExpandedRdfProperty' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.

    256           const supportedProperty = get(
                                            ~~~~
    257             supportedProperties,
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    258             '["http://www.w3.org/ns/hydra/core#property"][0]'
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    259           ) as ExpandedRdfProperty;
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    src/hydra/parseHydraDocumentation.ts:261:25 - error TS2352: Conversion of type 'null' to type 'string' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.

    261           const range = get(
                                ~~~~
    262             supportedProperty,
        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    ... 
    264             null
        ~~~~~~~~~~~~~~~~
    265           ) as string;
        ~~~~~~~~~~~~~~~~~~~~~

Test Suites: 2 failed, 3 passed, 5 total
Tests:       6 passed, 6 total
Snapshots:   0 total
Time:        3.679 s
Ran all test suites.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Support for swagger JSON needs more documentation and error handling

re: 0c999c9#r29816386

There is not always a definition for every title. Often, the title and the route names differ, or there is a route with no corresponding model. When they do correspond, they are linked by 'ref' -- take for example the simple petstore definition:

https://github.com/OAI/OpenAPI-Specification/blob/master/examples/v2.0/json/petstore.json

For starters, the route name and the definition name differ by capitalization.

In many other APIs, some routes do not have associated model definitions. For example the 'store' route in: https://petstore.swagger.io/v2/swagger.json

I do see how this could be used by ensuring every route is tagged with the same name, so this fact needs to be documented. Also, it should fallback to checking alternate forms based on capitalization/pluralization. Finally, it should fail more gracefully when a route does NOT have a related model definition, so those that do still are processed correctly.

Cannot find name 'Nullable'

API Platform version(s) affected: 0.8.2

Description
When using api-doc-parser in a Project set up with VueCLI with Typescript, I get the compile error Cannot find name 'Nullable' in the following files:

  • Api.d.ts
  • Field.d.ts
  • Operation.d.ts
  • Resource.d.ts

How to reproduce

  1. Create Project with VueCLI using this Preset
{
  "useTaobaoRegistry": false,
  "packageManager": "yarn",
  "latestVersion": "4.3.1",
  "lastChecked": 1586624138305,
  "presets": {
    "api-doc-parser-preset": {
      "useConfigFiles": true,
      "plugins": {
        "@vue/cli-plugin-babel": {},
        "@vue/cli-plugin-typescript": {
          "classComponent": true,
          "useTsWithBabel": true
        },
        "@vue/cli-plugin-eslint": {
          "config": "airbnb",
          "lintOn": [
            "save"
          ]
        }
      }
    }
  }
}
  1. Add api-doc-parser to dependencies with yarn add @api-platform/api-doc-parser (or npm install @api-platform/api-doc-parser

  2. Add the following code to the generated App.vue file between the <script lang="ts"></script> tags:

import { Component, Vue } from 'vue-property-decorator';
import HelloWorld from './components/HelloWorld.vue';
import parseHydraDocumentation
  from '@api-platform/api-doc-parser/lib/hydra/parseHydraDocumentation';

@Component({
  components: {
    HelloWorld,
  },
})
export default class App extends Vue {
  async mounted() {
    const docs = parseHydraDocumentation('http://localhost:8000/api');
    console.log(docs);
  }

  1. Run yarn serve (or npm run serve)

  2. The errors show up in the console:

screenshoot

Possible Solution
I managed to work around this issue by creating a global.d.ts file, making sure it is used by deleting the types key in tsconfig.json and adding the following code in global.d.ts:

type Nullable<T>  = {
  [P in keyof T]: T[P] | null
}

use 'OpenAPI link' to detect relations between entities

Description
Why do you not use OpenAPI links to detect relations between entities instead of use the current conventions name based?

See:

## OpenAPI Support

In order to reference the resources between themselves (embeddeds or relations), the library guesses embeddeds or references from property names.
For instance if a book schema has a reviews property, the library tries to find a Review resource.
If there is, a relation or an embedded between Book and Review resources is made for the reviews field.
The property name can also be like review_id, reviewId, review_ids or reviewIds for references.

I'm discussing about this possibility on platformatic repository, here:
platformatic/platformatic#446

Why aren't hydra and openapi3 generating the same components

Description
here I am testing the client generator and I am noticing that the hydra generates only this
`Interface for the "Book" resource type has been generated!

Interface for the "Review" resource type has been generated!

Interface for the "TopBook" resource type has been generated!`

and the openapi3 generate this:
`Interface for the "Book" resource type has been generated!;

Interface for the "Parchment" resource type has been generated!;

Interface for the "Review" resource type has been generated!;

Interface for the "TopBook" resource type has been generated!;
`

and when i looked at the endpoints on the api https://demo.api-platform.com/
i saw that there are 5
/books*
/parchments* // deprecated
/reviews*
/stats*
/top_books*

How to reproduce
I lunched the test-gen and test-gen-openapi3 commands

First letter of Resource/Entity doesn't appear

Hello,

Because of the function guessNameFromUrl :

guessNameFromUrl(entrypoint[0][property['@id']][0]['@id'], entrypointUrl),

The first letter of every entity/resource in the @api-platform/admin doesn't appear.

Is it normal ?

When I change 1 to 0, the admin works as expected in

return url.substr(entrypointUrl.length + 1);

I use Api-Platform 2.1

Swagger support

The Swagger parser is already in the project. Can we update the Docs?

TypeError: Cannot read property 'properties' of undefined; swagger.io openapi3

API Platform version(s) affected: latest at this moment

Running command:

npx @api-platform/client-generator https://petstore3.swagger.io/api/v3/openapi.json vue_openapi3/ --generator vue --format openapi3

Output :

typeError: Cannot read property 'properties' of undefined
    at /Users/blaaa/.npm/_npx/6097/lib/node_modules/@api-platform/client-generator/node_modules/@api-platform/api-doc-parser/lib/openapi3/handleJson.js:32:33
    at Array.map (<anonymous>)
    at Object.default_1 [as default] (/Users/blaaa/.npm/_npx/6097/lib/node_modules/@api-platform/client-generator/node_modules/@api-platform/api-doc-parser/lib/openapi3/handleJson.js:16:27)
    at /Users/blaaa/.npm/_npx/6097/lib/node_modules/@api-platform/client-generator/node_modules/@api-platform/api-doc-parser/lib/openapi3/parseOpenApi3Documentation.js:12:45
    at processTicksAndRejections (internal/process/task_queues.js:97:5)

Possible Solution
Pls have a look api-platform/create-client#104 (comment)

The response has no "Link" HTTP header

I'm using api-platform 2.1beta1 and I have completed all admin instruction steps.
I'm getting an error:

parseHydraDocumentation.js:71 Uncaught (in promise) Error: The response has no "Link" HTTP header.
    at getDocumentationUrlFromHeaders (parseHydraDocumentation.js:71)
    at parseHydraDocumentation.js:95
    at <anonymous>

because getDocumentationUrlFromHeaders needs Link header, but at this line headers are empty
image

Although it's not true, see the response headers:
image
and response body, for the reference:
image

Bug parsing OpenAPI https://netcoreblockly.herokuapp.com/swagger/v1/swagger.json

API Platform version(s) affected: "0.12.0",

Description
When parsing https://netcoreblockly.herokuapp.com/swagger/v1/swagger.json it gives error when reading "properties" in

\node_modules@api-platform\api-doc-parser\lib\openapi3\handleJson.js

var properties = schema.properties;

The tags does not show always the schema.

var title = responsePathItem.tags[0];

If you look at the json https://netcoreblockly.herokuapp.com/swagger/v1/swagger.json the tags[0] is DB_Departments
"/api/DB_Departments": {
"get": {
"tags": [
"DB_Departments"
],

This is not in the "components": {
"schemas": {

Rather, the program should be reading from responses:
"items": {
"$ref": "#/components/schemas/Department"
}

How to reproduce

    const SwaggerParser = require("@api-platform/api-doc-parser/lib/openapi3/parseOpenApi3Documentation");
    var q = await SwaggerParser.default('https://netcoreblockly.herokuapp.com/swagger/v1/swagger.json');

Possible Solution

As an workaround, until a real solve, we can try to alleviate by parsing what we can

var schema = response.components.schemas[title];
//added code
		if(schema == undefined){
			console.error ('cannot find schema for ' + title)
			return null;
		}
//more code
return resources.filter(it=>it != null);

Additional Context

All fields are merged in case of related entity with the same iri

In case of subresources using the same "iri" of the parent, all fields are merged into the same resource.

Test case, two entities with the same iri:

// entities
User:
    id
    username
    password
    userProfile (OneToOne)

UserProfile:
    id
    photo
    firstname
    ...
// resources file
App\Entity\User:
    iri: 'http://schema.org/Person'

App\Entity\UserProfile:
    iri: 'http://schema.org/Person'

Result is all the fields of the latest entity (with the same iri) parsed by the parseHydraDocumentation(), in my case the fields are from "UserProfile" entity.

TypeScript: Cannot find name 'Nullable'

API Platform version(s) affected: 0.10.0

Description
Getting this error when running my Typescript build:

ERROR in [at-loader] ./node_modules/@api-platform/api-doc-parser/lib/Field.d.ts:2:39 
    TS2304: Cannot find name 'Nullable'.

ERROR in [at-loader] ./node_modules/@api-platform/api-doc-parser/lib/Operation.d.ts:1:43 
    TS2304: Cannot find name 'Nullable'.

ERROR in [at-loader] ./node_modules/@api-platform/api-doc-parser/lib/Resource.d.ts:4:42 
    TS2304: Cannot find name 'Nullable'.

ERROR in [at-loader] ./node_modules/@api-platform/api-doc-parser/lib/Api.d.ts:2:37 
    TS2304: Cannot find name 'Nullable'.

There is a Nullable type defined, but completely outside this package as in /@types/nullable.d.ts

But it looks like it's attempting to parse these lib files first and there's no imports of this nullable type.

How to reproduce
run typescript using this package.

Add OpenAPI v3 support

api-doc-parser already supports (partially, see #37) OpenAPI v2. Now that API Platform Core also supports OpenAPI v3, this library should be able to deal with it it too.

Ability to cache for offline usage

Hi,

I'd like to be able to initialize the API specs from an existing cache in order to get the most recently known state of the api docs in case of offline usage.

Basically I need to be able to serialize the specs into JSON and deserialize from JSON. As far as I can see the tests currently utilize JSON.stringify() already which is nice but in my case I'm getting issues with an API spec which has circular references internally (e.g. a Resource is referencing another Resource its Field.reference property).

As the parseHydraDocumentation is capable of creating those references properly based on the api docs I'm currently thinking that utilizing the collected response(s) for caching and instantiate a new instance of Api with its belongings from that state.

If I see it correctly it should be sufficient to separate the "fetch" and "parse" capabilities that are currently handled implicitly in the parseHydraDocumentation - like having one separately exported function that does only the parsing which is currently done here:

({ entrypoint, docs, response }) => {
const resources = [],
fields = [],
operations = [];
const title = get(
docs,
'[0]["http://www.w3.org/ns/hydra/core#title"][0]["@value"]',
"API Platform"
);
const entrypointType = get(entrypoint, '[0]["@type"][0]');
if (!entrypointType) {
throw new Error('The API entrypoint has no "@type" key.');
}
const entrypointClass = findSupportedClass(docs, entrypointType);
if (
!Array.isArray(
entrypointClass["http://www.w3.org/ns/hydra/core#supportedProperty"]
)
) {
throw new Error(
'The entrypoint definition has no "http://www.w3.org/ns/hydra/core#supportedProperty" key or it is not an array.'
);
}
// Add resources
for (const properties of entrypointClass[
"http://www.w3.org/ns/hydra/core#supportedProperty"
]) {
const readableFields = [],
resourceFields = [],
writableFields = [],
resourceOperations = [];
const property = get(
properties,
'["http://www.w3.org/ns/hydra/core#property"][0]'
);
if (!property) {
continue;
}
// Add fields
const relatedClass = findRelatedClass(docs, property);
for (const supportedProperties of relatedClass[
"http://www.w3.org/ns/hydra/core#supportedProperty"
]) {
const supportedProperty = get(
supportedProperties,
'["http://www.w3.org/ns/hydra/core#property"][0]'
);
const range = get(
supportedProperty,
'["http://www.w3.org/2000/01/rdf-schema#range"][0]["@id"]',
null
);
const field = new Field(
supportedProperty[
"http://www.w3.org/2000/01/rdf-schema#label"
][0]["@value"],
{
id: supportedProperty["@id"],
range: range,
reference:
"http://www.w3.org/ns/hydra/core#Link" ===
get(property, '["@type"][0]')
? range
: null, // Will be updated in a subsequent pass
required: get(
supportedProperties,
'["http://www.w3.org/ns/hydra/core#required"][0]["@value"]',
false
),
description: get(
supportedProperties,
'["http://www.w3.org/ns/hydra/core#description"][0]["@value"]',
""
),
maxCardinality: get(
supportedProperty,
'["http://www.w3.org/2002/07/owl#maxCardinality"][0]["@value"]',
null
),
deprecated: get(
supportedProperties,
'["http://www.w3.org/2002/07/owl#deprecated"][0]["@value"]',
false
)
}
);
fields.push(field);
resourceFields.push(field);
if (
get(
supportedProperties,
'["http://www.w3.org/ns/hydra/core#readable"][0]["@value"]'
)
) {
readableFields.push(field);
}
if (
get(
supportedProperties,
'["http://www.w3.org/ns/hydra/core#writable"][0]["@value"]'
)
) {
writableFields.push(field);
}
}
// parse entrypoint's operations (a.k.a. collection operations)
if (property["http://www.w3.org/ns/hydra/core#supportedOperation"]) {
for (const entrypointOperation of property[
"http://www.w3.org/ns/hydra/core#supportedOperation"
]) {
if (
!entrypointOperation["http://www.w3.org/ns/hydra/core#returns"]
) {
continue;
}
const range =
entrypointOperation[
"http://www.w3.org/ns/hydra/core#returns"
][0]["@id"];
const operation = new Operation(
entrypointOperation[
"http://www.w3.org/2000/01/rdf-schema#label"
][0]["@value"],
{
method:
entrypointOperation[
"http://www.w3.org/ns/hydra/core#method"
][0]["@value"],
expects:
entrypointOperation[
"http://www.w3.org/ns/hydra/core#expects"
] &&
entrypointOperation[
"http://www.w3.org/ns/hydra/core#expects"
][0]["@id"],
returns: range,
types: entrypointOperation["@type"],
deprecated: get(
entrypointOperation,
'["http://www.w3.org/2002/07/owl#deprecated"][0]["@value"]',
false
)
}
);
resourceOperations.push(operation);
operations.push(operation);
}
}
// parse resource operations (a.k.a. item operations)
for (const supportedOperation of relatedClass[
"http://www.w3.org/ns/hydra/core#supportedOperation"
]) {
if (
!supportedOperation["http://www.w3.org/ns/hydra/core#returns"]
) {
continue;
}
const range =
supportedOperation["http://www.w3.org/ns/hydra/core#returns"][0][
"@id"
];
const operation = new Operation(
supportedOperation[
"http://www.w3.org/2000/01/rdf-schema#label"
][0]["@value"],
{
method:
supportedOperation[
"http://www.w3.org/ns/hydra/core#method"
][0]["@value"],
expects:
supportedOperation[
"http://www.w3.org/ns/hydra/core#expects"
] &&
supportedOperation[
"http://www.w3.org/ns/hydra/core#expects"
][0]["@id"],
returns: range,
types: supportedOperation["@type"],
deprecated: get(
supportedOperation,
'["http://www.w3.org/2002/07/owl#deprecated"][0]["@value"]',
false
)
}
);
resourceOperations.push(operation);
operations.push(operation);
}
const url = get(entrypoint, `[0]["${property["@id"]}"][0]["@id"]`);
if (!url) {
throw new Error(`Unable to find the URL for "${property["@id"]}".`);
}
resources.push(
new Resource(guessNameFromUrl(url, entrypointUrl), url, {
id: relatedClass["@id"],
title: get(
relatedClass,
'["http://www.w3.org/ns/hydra/core#title"][0]["@value"]',
""
),
fields: resourceFields,
readableFields,
writableFields,
operations: resourceOperations,
deprecated: get(
relatedClass,
'["http://www.w3.org/2002/07/owl#deprecated"][0]["@value"]',
false
),
parameters: []
})
);
}
// Resolve references
for (const field of fields) {
if (null !== field.reference) {
field.reference =
resources.find(resource => resource.id === field.reference) ||
null;
}
}
return Promise.resolve({
api: new Api(entrypointUrl, { title, resources }),
response,
status: response.status
});
},

I could try to come up with a PR for this but I'd like to get some opinions on that first.

Best

Cannot find module 'lodash'

I've tried to run the command through npx on my machine but it doesn't work.

$ npx @api-platform/client-generator
npx: installed 284 in 10.132s
Cannot find module 'lodash'

If I install the package globally I get the following error

$ generate-api-platform-client 
internal/modules/cjs/loader.js:615
    throw err;
    ^

Error: Cannot find module 'lodash'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:613:15)
    at Function.Module._load (internal/modules/cjs/loader.js:539:25)
    at Module.require (internal/modules/cjs/loader.js:667:17)
    at require (internal/modules/cjs/helpers.js:20:18)
    at Object.<anonymous> (/home/luca/.nvm/versions/node/v11.10.0/lib/node_modules/@api-platform/client-generator/node_modules/@api-platform/api-doc-parser/lib/swagger/handleJson.js:48:15)
    at Module._compile (internal/modules/cjs/loader.js:738:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:749:10)
    at Module.load (internal/modules/cjs/loader.js:630:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:570:12)
    at Function.Module._load (internal/modules/cjs/loader.js:562:3)

However, I can solve this by globally installing lodash

addParameter in parseHydraDocumentation ignoring options parameter

Hi !

I was having issues with fetchResource calls getting 401 responses for every requests ; turned out that it was caused by addParameter (called at the end of parseHydraDocumentation) ignoring my Authorization headers (given in options parameter).

Am I doing this wrong or did I missed something ?

Thanks. :-)

list and create endpoints aren't correctly matched

Api Doc-parser version: 0.16.1

Description
Following the guidelines for creating the endpoint names, I am just getting the operations defined for the /.../users/{id] endpoint (e.g. get, put, delete). The operations that are defined for the .../users endpoint (get, post) are not detected by the doc parser.

Possible Solution
This fork takes care of these issues. While you can inject the customized doc-parser in the following way:

import { parseOpenApi3Documentation } from '@emdgroup-liquid/api-doc-parser';
import { ApiPlatformAdminDataProvider, openApiDataProvider } from '@api-platform/admin';

const customDataProvider: ApiPlatformAdminDataProvider = openApiDataProvider({
  ...
  apiDocumentationParser: parseOpenApi3Documentation,
});

const Admin = () => {
  return (
    <OpenApiAdmin
      ...
      dataProvider={customDataProvider} />
  );
};

It would be nice to integrate the changes into this main repo.

Cannot convert undefined or null to object.

Attempting to run API Platform client generation on a very basic API Platform with no particularly complex entities set up, running into this error when attempting to parse with OpenAPI version 3:

TypeError: Cannot convert undefined or null to object
    at Function.keys (<anonymous>)
    at /home/node/.npm/_npx/233/lib/node_modules/@api-platform/client-generator/node_modules/@api-platform/api-doc-parser/lib/openapi3/handleJson.js:19:34
    at Array.map (<anonymous>)
    at Object.default_1 [as default] (/home/node/.npm/_npx/233/lib/node_modules/@api-platform/client-generator/node_modules/@api-platform/api-doc-parser/lib/openapi3/handleJson.js:16:27)
    at /home/node/.npm/_npx/233/lib/node_modules/@api-platform/client-generator/node_modules/@api-platform/api-doc-parser/lib/openapi3/parseOpenApi3Documentation.js:12:45
    at processTicksAndRejections (internal/process/task_queues.js:94:5)

the JSON I'm handing it, which is autogenerated by API Platform, is valid and the OpenAPI spec says it's completely fine, except it's missing "description" fields on the properties (though these aren't necessary by my understanding).

Given the relative opacity of this error it's not clear where it's failing to parse my JSON. I've spent several hours spinning my wheels on this with no progress, and I'm starting to feel quite bad about it, so any help would be much appreciated.

API authentication error not properly handled

When calling parseHydraDocumentation on an API that requires authentication and authentication fails, this leads to the following confusing error:

TypeError: Cannot read property 'http://www.w3.org/ns/hydra/core#title' of undefined
    at parseHydraDocumentation.js:137
    at <anonymous>

Throwing the original 401 Unauthorised error might be a better choice since it would uncover the underlying issue.

Entrypoint trailling slash is stripped from original entrypoint fetch.

API doc parser version(s) affected: 0.15.1

Description

Since the entrypoint prefix is stripped here it means that the request to fetch the API doc is made to the URL without this slash.

It means that in the case were the API only replies to the URL with the slash the request will fails and the admin won't load.

How to reproduce

Create an Admin with an entrypoint that ends with a slash and an API that returns a error when the request is done without this slash.

Possible Solution

Since the slash is removed intentionally we need to keep it, but maybe we could keep the original supplied URL for the original fetch of the entry point.

Use the path specified in OpenAPI schema as the URL

Description
I was trying to get the api-platform admin working with my api, but all api requests by the admin were to http://<resource_name>. Intermediate paths like /api/ and /v1/ are ignored.

My openapi json file specifies paths for each resource. Looking over the code the intermediate paths are stipped, I'm not sure why:

  let serverUrlOrRelative = "/";
  if (document.servers) {
    serverUrlOrRelative = document.servers[0].url;
  }
  
  ....
 const splittedPath = removeTrailingSlash(path).split("/");
 const name = inflection.pluralize(splittedPath[splittedPath.length - 2]);
 const url = `${removeTrailingSlash(serverUrl)}/${name}`;```

So "/api/v1/users" becomes "http://users" which of course is incorrect and very few schemas have just the resource name at the base path of the domain.

It seems the only way to have an intermediate path is to add a server to the openapi json document, but I don't see why this should be necessary when the openapi schema already includes the path to use. Also even if servers are specified, the code only picks the first server, so this means urls with different base paths will be converted to using the same base path based on the first server making it less flexible. Many common frameworks don't include servers when generating the openapi spec, making the api-platform admin unusable. It's also not mentioned in the README that a server needs to be specificied in order to have the correct urls.

I also find it strange that it pluralises it, why change the path at all? These paths are used by the admin to make api requests so they should be the same as that given in the schema.

Example
parseOpenApi3Documentation could accept a property:

parseOpenApi3Documentation("http://localhost/openapi.json", keepPathsAsUrls=true)

Or maybe it could accept a function:

const convertUrl = (path) => {
     return path;
}
parseOpenApi3Documentation("http://localhost/openapi.json", convertUrls=convertUrl)

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.