Git Product home page Git Product logo

janephp's Introduction

janephp's People

Contributors

bastnic avatar dbu avatar discordier avatar dstollie avatar eg-check24 avatar fbnfgc avatar gounlaf avatar gplanchat avatar jeroeny avatar jevrard avatar jmsche avatar joelwurtz avatar johanlopes avatar joshuabehrens avatar korbeil avatar lkck24 avatar localheinz avatar lyrixx avatar michaelthieulin avatar nikophil avatar pawelsuwinski avatar pyrech avatar qboot avatar serl avatar squifouma avatar uuf6429 avatar welcomattic avatar xavismeh avatar xavren avatar yoshz 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  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

janephp's Issues

[Roadmap] Server generator

Add a server generator which should generate

  • An interface / abstract class extendable for each endpoint
  • A bridge for each endpoint implementing PSR15 handler interface https://www.php-fig.org/psr/psr-15/ which transform request to object / parameters needed for the endpoint, and object returned by the endpoint into a ResponseInterface
  • A router implementing PSR15 middleware which redirect to the correct endpoint bridge

"full-featured" support arrays of objects

I took a quick look through the existing issue and didn't see anything addressing this, please let me know if I'm missing something.

When using the JSON Schema generation functionality with the following schema (we'll call it testschema):

{
  "type": "object",
  "properties": {
    "foo": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "bar": {
            "type": "string"
          }
        }
      }
    }
  }
}

The generated testschema object only has an array of object for the property foo, vs an array of Foo of the Foo type that in turn has a bar that is a string:

class Testschema
{
    /**
     * 
     *
     * @var object[]
     */
    protected $foo;
    /**
     * 
     *
     * @return object[]
     */
    public function getFoo() : ?array
    {
        return $this->foo;
    }
    /**
     * 
     *
     * @param object[] $foo
     *
     * @return self
     */
    public function setFoo(?array $foo) : self
    {
        $this->foo = $foo;
        return $this;
    }
}

Is support for "full-featured" arrays of object something I'm missing/not doing correctly? Or is it not implemented? I have yet to test with definitions and $ref for the array items.

Cheers,
Andrew

Normalizer Array error

Hey

I am actually using subtree split open api and having some errors due to the fact that Normalizers does not check data type before calling get_class($data)

    public function supportsNormalization($data, $format = null)
    {
        return get_class($data) === FQDN_CLASS
    }

A better approach should be

    public function supportsNormalization($data, $format = null)
    {
        return is_object($data) && get_class($data) === FQDN_CLASS
    }

Unconsistent case of properties and constructor in generated endpoints

Hi everyone,

first, thanks for your awesome tool.

I encounter a problem when generating endpoint from OpenAPI specs.
I have in the json file a parameter with upper case first letter :

"/..../..../..../{Id}": {
  "get": {
    ....
    "parameters": [
      {
        "type": "string",
        "name": "Id",
        "in": "path",
        "required": true,
        "format": "guid",
        "x-nullable": false
      }
    ],
    ....
  },
  ....
}

Note the Id property with the upper case "I"
When using the tool to generate endpoints, I obtain something like this :

    // The property here is good, like in the url provided by specs
    protected $Id;

    /**
     * In the constructor, it's a camel case version with a lower case first letter 
     * @param string $id
     */
    public function __construct(string $id)
    {
        // This assigns a value to an undefined property
        $this->id = $id;
    }

Everywhere in the file, the property "Id" is used, but due to the difference in the constructor, I'm unable to initialize properly this class.

After digging a little bit in the EndpointGenerator class, I think the problem comes from the line 149 :

$methodStatements[] = new Expr\Assign(new Expr\PropertyFetch(new Expr\Variable('this'), Inflector::camelize($parameter->getName())), new Expr\Variable(Inflector::camelize($parameter->getName())));

It can be fixed like this :

$methodStatements[] = new Expr\Assign(new Expr\PropertyFetch(new Expr\Variable('this'), $parameter->getName()), new Expr\Variable(Inflector::camelize($parameter->getName())));

(removing Inflector::camelize() on the property).

What do you think ?

Edit : put the real existing (wrong) code for constructor instead of my own result after testing the fix

Normalizer name generation for bad class names is inconsistent

When generating a normalizer for a class name with a protected keyword, the normalizer class name is not consistent with the file name. Example:
Model name: List
Generated class name: _List (correct)
Generated class filename: _List.php (correct)
Normalizer class Name: ListNormalizer (correct)
Normalizer File name: _ListNormalizer.php (incorrect)

Be able to have nullable fields with strict parameter to true

I have a JSON to declare my model with some nullable fields, but on the Model, the getter does not return nullable field.
Here is a part of my JSON :

{
  "$schema": "http://json-schema.org/2019-09/schema#",
  "definitions": {
    "Document": {
      "type": "object",
      "properties": {
        [...]
        "attributes": {
          "type": ["array", "null"],
          "items": {
            "$ref": "#/definitions/Attributes"
          }
        },
        [...]
      }
    },
    "Attributes": {
      "type": "object",
      "properties": {
        [...]
      }
    }
  }
}

But in the model, getter and setter are in that form :

<?php

// [...]

class Document
{
    
	// [...]

    /**
     * @var Attributes[]
     */
    protected $attributes;
	
	// [...]

    /**
     * @return Attributes[]
     */
    public function getAttributes(): array
    {
        return $this->attributes;
    }

    /**
     * @param Attributes[] $attributes
     *
     * @return self
     */
    public function setAttributes(array $attributes): self
    {
        $this->attributes = $attributes;

        return $this;
    }

	// [...]
}

I work with strict default value (true).

To be able to use my model, I actually changed strict config to false :

<?php

return [
    // [...]
    'strict' => false,
];

[RFC] Decoupling request / response transformation from endpoint

Actually an endpoint is hard to extends, and sometimes require to rewrite the full method.

However when you need to rewrite an endpoint, you just need to transform some of the parameters to the request, or transform the response into a specific object.

This can be achieved by generating specific encoder / decoder for the symfony serializer component.

Endpoint of an api will always takes two arguments

public function doAnEndpointCall($endpointObject, string $fetchMode)

$endpointObject can either be an instance of EndpointObject which have all parameters for the current endpoint or it can be a PSR7 Request Interface, the endpoint code will look like this

public function doAnEndpointCall($endpointObject, string $fetchMode = self::FETCH_OBJECT)
{
      if (!$endpointObject instanceof RequestInterface) {
          $endpointObject = $this->serializer->serialize($endpointObject,  'doAnEndpointCall', 'PSR7');
      }

       $response = $this->htttpClient->sendRequest($endpointObject);

       if ($fetchMode === self::FETCH_OBJECT) {
             return $this->serializer->deserialize($response,  'doAnEndpointCall', 'PSR7');
       }

       return $response;
}

Then Jane will generate specific encoders to transform endpoint object into a RequestInterface and ResponseInterface into specific objects.

Endpoint Object will have as its constructor, the same signature than previsouly, so usage looks like:

$responseObject = $this->apiClient->doAnEndpointCall(new EndpointObject($pathParameters, $queryParameters));

WDYT ?

How to use generated client?

Thanks for building this! I generated a client from https://github.com/Nexmo/api-specification/blob/master/definitions/verify.yml but I can't find the docs on how to use the client now I have it. A bit of googling error messages showed that I needed to add more dependencies (php-http/curl-client and guzzlehttp/psr7 and php-http/message) and I can instantiate the client but then how do I set the URL? The query parameters? Any headers? Am I just missing some documentation somewhere? If you can point me in the right direction I promise to update the docs if/when I have a working example :)

Feature to port from `4.x` to `master` branch

  • Discriminator for inheritance #60 (fixed by #91)
  • Use of CacheableSupportsMethodInterface for Normalizers #54 (fixed by #93)
  • Add support for default value in model (only scalar) #57
  • Allow httplug 2.0 #58 (fixed by #99)
  • Fix generated endpoint in case of uppercase in path parameter #97 (fixed by #98)

This list is probably not complete but this is a good way to know what to focus on !

Generate normalizer with snake_case discriminator

jane-php/open-api: 5.0.0
openapi v3

Hi,
I want to generate a client model with discriminator.
On my openapi schema I have a snake_case discriminator model.

{
    "openapi": "3.0.0",
    "info": {
        "title": "My test app"
    },
    "paths": {
    },
    "components": {
        "schemas": {
            "pet": {
                "type": "object",
                "discriminator": {
                    "propertyName": "type"
                },
                "enum": [
                    "dog_labrador",
                    "dog_carlin",
                    "cat"
                ],
                "properties": {
                    "uuid": {
                        "type": "string",
                        "format": "uuid",
                        "readOnly": true
                    },
                    "type": {
                        "type": "string"
                    }
                }
            },
            "dog_labrador": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/pet"
                    },
                    {
                        "type": "object"
                    }
                ]
            },
            "dog_carlin": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/pet"
                    },
                    {
                        "type": "object"
                    }
                ]
            },
            "cat": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/pet"
                    },
                    {
                        "type": "object"
                    }
                ]
            }
        }
    }
}

But when I generate my client with the vendor/bin/jane-openapi generate command I get this

public function denormalize($data, $class, $format = null, array $context = [])
    {
        if (!is_object($data)) {
            throw new InvalidArgumentException();
        }
        if (property_exists($data, 'type') and 'dog_labrador' === $data->{'type'}) {
            return $this->denormalizer->denormalize($data, 'TestGenerated\\Model\\dog_labrador', $format, $context);
        }
        if (property_exists($data, 'type') and 'dog_carlin' === $data->{'type'}) {
            return $this->denormalizer->denormalize($data, 'TestGenerated\\Model\\dog_carlin', $format, $context);
        }
        if (property_exists($data, 'type') and 'cat' === $data->{'type'}) {
            return $this->denormalizer->denormalize($data, 'TestGenerated\\Model\\cat', $format, $context);
        }
        $object = new \TestGenerated\Model\Pet();
        if (property_exists($data, 'uuid')) {
            $object->setUuid($data->{'uuid'});
        }
        if (property_exists($data, 'type')) {
            $object->setType($data->{'type'});
        }

        return $object;
    }

return $this->denormalizer->denormalize($data, 'TestGenerated\\Model\\dog_labrador', $format, $context);

The classname generated is actually incorrect.

How can I do to have it in camelCase ? Is this possible ? Or is this a bug ?

Thanks for your help

How do you define Nullable properties

I understand support for OpenAPI v3 is in the works and a solution to may already be in the works considering a similar issue described in #28

How would one describe a nullable component?
I'm attempting generation for a v3 client using 5.x-dev and describing an endpoint as follows:

paths:
  '/component/{parentComponentId}':
    get:
      parameters:
      - name: parentComponentId
        in: path
        required: true
        schema:
          type: integer
          format: int64
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/ParentComponent'
components:
  schemas:
    ParentComponent:
      type: object
      properties:
        id:
          type: integer
        child:
          nullable: true
          oneOf:
          - $ref: '#/components/schemas/Component'

but the generated code only accepts null values for the nullable property since it doesn't try to denormalize non null values.

// section of code generated for ParentNormalizer.php
if (property_exists($data, 'child')) {
    $object->setComponent($data->{'child'});
}

this causes issues since setComponent method is type hinted with the Component model class

Parametrizing the host address

We have several places running the same API and we want to be able to configure our applications which one to use based on the environment (dev, test, prod). This is not possible when hardcoding the host: xxx field into the spec.

The documentation mentions that it should be possible to handle these cases. However, I could not find a way to do:

  • Keep the basePath in the spec (it will not change)
  • Be able to parametrize the host, probably while the Client class is being created.

Looking at the code, I seem to have the following problem. When host is not provided, the Client::create() factory method will not contain the AddHostPlugin() call. There is no way for me to pass this plugin into the create call, however. I can only provide the whole $httpClient instance. I don't understand how to keep most of the default client creation and only provide the host URL, the single plugin.

It seems to me that with the current functionality, I have two options:

  • Provide both host and basePath and be locked to a single host url
  • Manually parse the spec file for basePath and create a custom $httpClient instance. I have to parse the spec because I cannot read the basePath value anywhere

Am I missing something?

This gist shows the create functions I am talking about: https://gist.github.com/melkamar/f98e8996dc55a2e457a6efeed2154ee1

Thanks!

Reusing the same model as response (GET) and request (POST, PUT, PATCH) object

The OAS 3.0 defines a boolean readOnly property for schema objects:

Relevant only for Schema "properties" definitions. Declares the property as "read only". This means that it MAY be sent as part of a response but SHOULD NOT be sent as part of the request. If the property is marked as readOnly being true and is in the required list, the required will take effect on the response only. A property MUST NOT be marked as both readOnly and writeOnly being true. Default value is false.

When you use the same schema in you OAS responses and requests of an endpoint this will lead to errors when trying to execute POST, PUT or PATCH actions. The readOnly setting is not taken into account when normalizing the generated models.

For a simple model like this:

class WebHookModel
{
    /**
     * The id of the web hook
     *
     * @var int
     */
    protected $webHookId;
    /**
     * The name of the web hook
     *
     * @var string
     */
    protected $name;
    /**
     * The id of the web hook
     *
     * @return int
     */
    public function getWebHookId() : int
    {
        return $this->webHookId;
    }
    /**
     * The id of the web hook
     *
     * @param int $webHookId
     *
     * @return self
     */
    public function setWebHookId(int $webHookId) : self
    {
        $this->webHookId = $webHookId;
        return $this;
    }
    /**
     * The name of the web hook
     *
     * @return string
     */
    public function getName() : string
    {
        return $this->name;
    }
    /**
     * The name of the web hook
     *
     * @param string $name
     *
     * @return self
     */
    public function setName(string $name) : self
    {
        $this->name = $name;
        return $this;
    }
}

you will get an error similar to this:

TypeError: Return value of \WebHookModel::getWebHookId() must be of the type int, null returned in file /WebHookModel.php on line 44

I have just started to investigate this issue, so am not sure what would be the best approach here? If we want to allow a property marked as readOnly to be included in the response we could just exclude it from the normalize function of the generated normalizer, but leave it in the denormalize function.

securityDefinitions ignored when using an OpenAPI spec

When generating a client from a spec which contains a securityDefinitions entry, this option is ignored. Example spec snippet:

host: "127.0.0.1:8080"
basePath: "/some/path/v1"
paths:
  /resource/details:
    get:
      summary: "getDetails"
      operationId: "getDetailsUsingGET"
      parameters:
      - description: "resourceNumber"
        name: "resourceNumber"
        format: "int32"
        required: false
        type: "integer"
        in: "query"
      - description: "X-CUSTOM"
        name: "X-CUSTOM"
        required: true
        type: "string"
        in: "header"
      responses:
        ...
      deprecated: false
      security:
      - ClientId: []

securityDefinitions:
  ClientId:
    type: "apiKey"
    name: "X-SEC-Client-Id"
    in: "header"
    description: ""

This results in a generated class that only allows X-CUSTOM header to be passed in, but X-SEC-Client-Id should be required to be passed in as well.

When I manually add the ClientId definition as a parameter of the resource path, the request is sent correctly and correct data is parsed. Therefore I think this is an issue related to adding the security headers to the request headers array.

optional date-time not handling NULL properly

I'm running into a normalization issue, the model as described below will throw an error during normalization when the value for disabled_at is NULL. Although the error message states that a NULL-value is accepted, it results in an error when the actual value is NULL.

Returned data:

object(stdClass)#49 (7) {
  ["id"]=>
  string(9) "569528063"
  ["disabled_at"]=>
  NULL
  ["created_at"]=>
  string(25) "2018-07-03T09:34:51+00:00"
  ["updated_at"]=>
  string(25) "2018-07-03T09:59:04+00:00"
}

Regarding the exception:
Uncaught TypeError: Argument 1 passed to ...\Account::setDisabledAt() must be an instance of DateTime or null, boolean given, called in .../Normalizer/AccountNormalizer.php

Regarding the model description:

definitions:
  Account:
    type: "object"
    required:
    - "id"
    properties:
      id:
        type: "string"
      disabled_at:
        type: "string"
        default: "null"
        format: "date-time"
      created_at:
        type: "string"
        format: "date-time"
      updated_at:
        type: "string"
        format: "date-time"

Any suggestions? Thanks!

Handling responses with charset Content-Type parameter

I have to deal with an API which returns content encoded as application/json;charset=UTF-8.

If I describe a response with such content-type, Jane fails to generate a working code:

                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json;charset=UTF-8": {
                                "schema": {
                                    "$ref": "#/components/schemas/Response"
                                }
                            }
                        }
                    },
        if (200 === $status) {
        }

Support PSR-18 client and PSR-17 message factories

This is a request to see if this is (or could be) possibly on your project timeline.

The idea is that any PSR-18 client could be passed in by the application or framework, and that would be used for all requests. If no PSR-18 client were passed in, then either auto-discovery could be used or your chosen client could be optionally installed and used. It's about not locking this package to a specific client. For example, I have a PSR-18 client that handles all the authentication and token renewals for a Xero connection. It would be great just to be able to pass that client into this library and say, "use this".

PSR-17 is a factory that creates PSR-7 messages - requests, responses and server requests. Again, the application could pass you a factory of its choice, or you could auto-discover one, or fall back to one of your choice using an optionally installed package.

Could this idea run?

Mixed parameter type hint for response bodies added to endpoint construction and related client function signatures

I came across the following issue when using a specification like this to describe a response model for an endpoint:

"anyOf": [
  {
    "title": "Country Pricelist",
    "type": "object",
    "properties": {
    ...
    },
  },
  {
    "title": "Customer Pricelist",
    "type": "object",
    "properties": {
      ...
    },
  }
]

This leads to a contructor signature of an endpoint Generated\Endpoint\CreatePricelist

/**
 * Create a pricelist. Retrieves the created `Pricelist` object
 *
 * @param mixed $requestBody 
 */
public function __construct(mixed $requestBody)
{
    $this->body = $requestBody;
}

and the follwing signature of the related client method:

/**
 * Create a pricelist. Retrieves the created `Pricelist` object
 *
 * @param mixed $requestBody 
 * @param string $fetch Fetch mode to use (can be OBJECT or RESPONSE)
 * @throws Generated\Exception\CreatePricelistBadRequestException
 *
 * @return null|Generated\Model\PricelistModelItem|\Psr\Http\Message\ResponseInterface
 */
public function createPricelist(mixed $requestBody, string $fetch = self::FETCH_OBJECT)
{
    return $this->executePsr7Endpoint(new Generated\Endpoint\CreatePricelist($requestBody), $fetch);
}

seems like this is related to the type for this schema being null when resolving the request body types via:

[$newTypes, $isArray] = $generator->getTypes($content, $reference . '/content/' . $contentType, $context);

here:

if (!isset($convertArray[$type]) || !isset($convertArray[$type][$format])) {
return ['mixed'];
}

When setting the type hint for the parameter this results in the above signatures:

$paramType = \count($types) === 1 ? $types[0] : null;

Normalizer won't work

When using the generated openapi client in combination with the guzzle6 adapter I continuously run into the following error:

Fatal error: Uncaught InvalidArgumentException: Invalid resource type: object in vendor/guzzlehttp/psr7/src/functions.php:116

I loaded the the client like this:

$adapter = \Http\Adapter\Guzzle6\Client::createWithConfig([
    'uri'     => 'http://my-service',
]);
$client = \Dummy\Api\Client::create($adapter);

Here is my generated client:
src.zip
And the openapi file:
openapi.yml.zip

Any help would be greatly appreciated!

5.x release

Hello,

I would like to know if there is any roadmap and if help is needed for a 5.0 release?

Thanks for this amazing library.

Call to a member function format() on null

With the following configuration

.jane-openapi

<?php

return [
    'openapi-file' => __DIR__ . '/schema.yaml',
    'namespace' => 'Test\Api',
    'directory' => __DIR__ . '/generated/',
    'date-format' => \DateTimeInterface::RFC3339_EXTENDED,
    'client' => 'psr18',
];

schema.yaml

openapi: 3.0.0
info:
    version: 1.0.0
components:
    schemas:
        Test:
            type: object
            properties:
                date:
                    type: string
                    nullable: true
                    format: date-time

In the generated code, the model is correct
public function getDate() : ?\DateTime

but in the normalize function of the TestNormalizer we have
$data->{'date'} = $object->getDate()->format("Y-m-d\TH:i:s.vP");

If the getDate return null, an error occured.

Compatibility with nikic/php-parser v4.0.x

Hi,

any plans to make jane-php/json-schema compatible with nikic/php-parser v4.0.x in the near future which is required by symfony/maker-bundle v1.5.x so we can use jane-php/open-api with modern Sf4 apps?

Best

Generator hangs and lacks any output

Hi,
I am trying to generate an API client for the Oracle Sales Cloud REST API. The API specification uses the Swagger 2.0 (OpenApi 2.0) format. I am using version 4.5.0 of jane.

Here is my config:

<?php

return [
    'openapi-file' => 'https://docs.oracle.com/en/cloud/saas/engagement/19c/faaps/swagger.json',
    'namespace' => 'Vendor\SalesCloudAPIServiceClient',
    'directory' => __DIR__ . '/src/php',
    'client' => 'psr18',
    'use-fixer' => true,
];

After executing php vendor/bin/jane-openapi generate just nothing happens. The script keeps running, but I waited for 30 minutes with absolutely no output. No data gets written to the target dir.

Please investigate.

No filename set when calling MultipartStreamBuilder::addResource from endpoints getBody function

I have an OAS which defines a createMediaFile endpoint:

"/media-files": {
      "post": {
        "operationId": "createMediaFile",
        "summary": "Create a media file",
        "description": "Creates a new `Media File` object",
        "responses": {
          "201": {
            "description": "The created media file is returned",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MediaFileModelItem"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        },
        "requestBody": {
          "description": "The media file to upload",
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/MediaFileUploadModel"
              }
            }
          }
        },
        "tags": [
          "Media Files"
        ]
      }
    },
...
      "MediaFileUploadModel": {
        "type": "object",
        "properties": {
          "file": {
            "type": "string",
            "format": "binary",
            "example": "[binary data]"
          }
        }
      },
}

The generated function of the endpoint looks like this:

    public function getBody(\Symfony\Component\Serializer\SerializerInterface $serializer, \Http\Message\StreamFactory $streamFactory = null) : array
    {
        if ($this->body instanceof \Starweb\Api\Client\Model\MediaFileUploadModel) {
            $bodyBuilder = new \Http\Message\MultipartStream\MultipartStreamBuilder($streamFactory);
            $formParameters = $serializer->normalize($this->body, 'json');
            foreach ($formParameters as $key => $value) {
                $bodyBuilder->addResource($key, $value);
            }
            return array(array('Content-Type' => array('multipart/form-data; boundary="' . ($bodyBuilder->getBoundary() . '""'))), $bodyBuilder->build());
        }
        return array(array(), null);
    }

When calling the endpoint on the client the the filename in the Content-Disposition body header is not set and the file parameter ending up as normal $_POST data and not as an entry of $_FILES.

The MultipartStreamBuilder checks for a filename in the $options array to set it:

https://github.com/php-http/multipart-stream-builder/blob/60d37c0d405c36fd5e4693bc0cede613492e68d8/src/MultipartStreamBuilder.php#L68-L75

Changing the $bodyBuilder->addResource($key, $value) call to something like $bodyBuilder->addResource($key, $value, ['filename' => 'foo.jpg']) fixes the issue, but I was wondering if this is something that could be fixed on the generation level maybe?

Working set of versions

Please, could you add to documentation, how to install a working set of jane-php/open-api and dependent packages?

When trying to install stable version (4.2) I have run into issue, that it is dependent on nikic/php-parser - old version 3.0 only.

When trying to install development version, then I have trouble with
Fatal error: require(): Failed opening required โ€˜.../vendor/composer/../jane-php/open-api/helpers.php' (include_path='.:/usr/share/php') in .../vendor/composer/autoload_real.php on line 66

Yet another combination of versions (this time including jane-php/open-api-runtime 5.x-dev) requires php-http/httplug old version 1.0 only, installation of which creates further problems down the road on attempt to install some version of php-http/guzzle6-adapter

To sum it up:

  1. Please, could you provide a reference of installable set of package versions, working together out of the box.

  2. Please, could you provide a hint on which branches it is actually being actively worked on
    (version 5 in open-api-runtime seems to be stale, however active in related project)

Thank you

Slavo

Support empty array as default value in JsonSchema

If I specify an empty array as default value for an array property, Jane does not care and not include the default value in the generated Model.

I've made a little tweak for testing in the PropertyGenerator and everything works fine

#src/JsonSchema/Generator/Model/PropertyGenerator.php
if (null !== $default && (is_scalar($default) || is_array($default))) {

What do you think ?

Upgrade JsonSchema & OpenAPI specs

We are still using JsonSchema draft-04 (~2 years old) and OpenApi 3.0.0 (3.0.2 is out)
Let's try to update everything to the last version !

  • JsonSchema
    • draft-06
    • draft-07
    • 2019-09
  • OpenAPI
    • 3.0.2

Question: How do I tell Jane to generate models with required/ nullable fields?

In my JSON file I have the OpenApi "required" section to define the required fields. But when Jane generates the JSON Models it makes everything nullable, which is a problem, when I want the required fields to be not nullable. Also it doesn't put |null in the doc block.

Is there a config option? Or is this a bug?

yaml support emits php warning in dev-master

I wanted to check if I can switch from swagger 2.0 to openapi 3.0, but the latest stable version 4.4 only supports swagger 2.0. If I update janephp-openapi to dev-master to get openapi 3.0 support I get a php error:
First parameter must either be an object or the name of an existing class in vendor/jane-php/open-api/SchemaParser/SchemaParser.php on line 66

The reason why it fails is that my spec file is in yaml format but the SchemaParser tries json first. Because it is not json json_decode on line 57 in method deserialize returns null. property_exists throws the error if $openApiSpecData is null. Because it is not an exception, but an error, it is not caught in line 35.

Tests with fake API on CI

Let's step up our tests !

Today we are running Client generation and check that generated Clients are matching what we think was ok (based on excepted folder).
I would like to test generated Client aswell, and running them against some "fake" API.

For this "fake" API, I think https://github.com/typicode/json-server would fit perfectly ! We just need a way to make this clean and working for most of our test fixtures.

Ability to fetch promises as in the deprecated library

Hi,

I've been using your previous package version (now deprecated) for more than one year. I was planning to move to your new version but I can't as I have many parts of my code which are using promises ("FETCH_PROMISE" as the last parameter of the method).

I've been reading the new docs and migrating my current code to the new async way (Amp/Artax) is not an option for me. It would suppose a huge effort. I'd like to know if you'd be open to adding support to promises in this new library. This way many users could benefit from this new version.

What do you think about this?

Thanks

Warn about two variables condense to same camel case

In certain cases it could happen that properties collide with their camel cased version.

type: object
properties:
  msgref:
    type: string
    description: Indicates the ID of the referenced original mail.
  msg_ref:
    type: string
    description: Message reference on reply/forward.
required:
  - msgref

Example from https://documentation.open-xchange.com/components/middleware/http/7.8.4/openapi.json

This creates a class like this:

<?php

namespace SomeNamespace;

class MailReplyData
{
    /**
     * Indicates the ID of the referenced original mail.
     *
     * @var string
     */
    protected $msgref;
    /**
     * Message reference on reply/forward.
     *
     * @var string
     */
    protected $msgRef;

    /**
     * Indicates the ID of the referenced original mail.
     *
     * @return string
     */
    public function getMsgref(): ?string
    {
        return $this->msgref;
    }

    /**
     * Indicates the ID of the referenced original mail.
     *
     * @param string $msgref
     *
     * @return self
     */
    public function setMsgref(?string $msgref): self
    {
        $this->msgref = $msgref;

        return $this;
    }

    /**
     * Message reference on reply/forward.
     *
     * @return string
     */
    public function getMsgRef(): ?string
    {
        return $this->msgRef;
    }

    /**
     * Message reference on reply/forward.
     *
     * @param string $msgRef
     *
     * @return self
     */
    public function setMsgRef(?string $msgRef): self
    {
        $this->msgRef = $msgRef;

        return $this;
    }
}

PHP is unable to load this class with the following error:

PHP Fatal error:  Cannot redeclare SomeNamespace\MailReplyData::getMsgRef() in lib/generated/MailReplyData.php on line xy
Errors parsing lib/generated/MailReplyData.php

According to http://www.php.net/manual/en/functions.user-defined.php function names in PHP are case insensitive.

    Note: Function names are case-insensitive, though it is usually good form to call functions as they appear in their declaration. 

At the moment I don't see any possibility to fix this in a sane matter.
I would recommend to detect this problem and print a warning.

AmpArtaxEndpointTrait is not compatible with Psr7HttplugEndpointTrait

Fatal error: Declaration of Jane\OpenApiRuntime\Client\AmpArtaxEndpointTrait::transformResponseBody(string $body, int $status, Symfony\Component\Serializer\SerializerInterface $serializer) must be compatible with Jane\OpenApiRuntime\Client\Psr7HttplugEndpointTrait::transformResponseBody(string $body, int $status, Symfony\Component\Serializer\SerializerInterface $serializer, ?string $contentType = NULL) in /vendor/docker-php/docker-php-api/src/Endpoint/ContainerList.php on line 13
Looks like 358f33d#diff-8a99bfbf066d77301bed25fe155a83cd broke bc.

Fatal error on generating.

I'm getting this error:

PHP Fatal error: Uncaught Error: Call to undefined method Jane\JsonSchemaRuntime\Reference::getType() in .../vendor/jane-php/open-api/Generator/Parameter/BodyParameterGenerator.php:94

https://github.com/janephp/open-api/blob/v4.0.1/Generator/Parameter/BodyParameterGenerator.php#L94

I changed the line to

return [$this->convertParameterType($resolvedSchema->getType(), $resolvedSchema->getFormat()), null];

and it's working as expected now.

Am I correct in this is what is intended?

undefined method Reference::getType()

Hi,

I want to generate a client for my API using an OpenApi V3 schema with janephp master branch

I get a fatal error

PHP Fatal error:  Uncaught Error: Call to undefined method Jane\JsonSchemaRuntime\Reference::getType() in /workspace/my-api-client/vendor/jane-php/jane-php/src/OpenApi/Generator/Parameter/NonBodyParameterGenerator.php:122
Stack trace:
#0 /workspace/my-api-client/vendor/jane-php/jane-php/src/OpenApi/Generator/EndpointGenerator.php(154): Jane\OpenApi\Generator\Parameter\NonBodyParameterGenerator->generateOptionDocParameter(Object(Jane\OpenApi\JsonSchema\Version3\Model\ParameterWithSchemaWithExampleInQuery))
#1 /workspace/my-api-client/vendor/jane-php/jane-php/src/OpenApi/Generator/EndpointGenerator.php(76): Jane\OpenApi\Generator\EndpointGenerator->getConstructor(Object(Jane\OpenApi\Operation\Operation), Object(Jane\JsonSchema\Generator\Context\Context))
#2 /workspace/my-api-client/vendor/jane-php/jane-php/src/OpenApi/Generator/OperationGenerator.php(31): Jane\OpenApi\Generator\EndpointGenerator->createEndpointClass(Object(Jane\OpenApi\Operation\Operation), Object(Jane\JsonSchema\G in /workspace/my-api-client/vendor/jane-php/jane-php/src/OpenApi/Generator/Parameter/NonBodyParameterGenerator.php on line 122

It could be the same kind of issue encountered in #41

[Roadmap] Add Validation Support

Add support for validating schema

  • Should use the Symfony/Validator component
  • Should support Normalized and Denormalized data, so validation can be done before deserialization and before serialization

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.