Skip to content

feat(spec update) Update the spec #48

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Dec 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
strategy:
max-parallel: 15
matrix:
php-versions: ['8.1', '8.2', '8.3']
php-versions: ['8.1', '8.2', '8.3', '8.4']
steps:
- name: Checkout
uses: actions/checkout@v3
Expand Down
41 changes: 22 additions & 19 deletions .php-cs-fixer.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
<?php

/*
* This file is part of JoliCode's Harvest PHP API project.
*
* (c) JoliCode <coucou@jolicode.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

$header = <<<'EOF'
This file is part of JoliCode's Harvest PHP API project.

Expand All @@ -9,35 +18,29 @@
file that was distributed with this source code.
EOF;

$finder = (new PhpCsFixer\Finder())
$finder = PhpCsFixer\Finder::create()
->ignoreVCSIgnored(true)
->in(__DIR__)
->exclude('doc')
->append([
__FILE__,
])
;

return (new PhpCsFixer\Config())
->setParallelConfig(PhpCsFixer\Runner\Parallel\ParallelConfigFactory::detect())
->setRiskyAllowed(true)
->setRules([
'@PhpCsFixer' => true,
'@Symfony' => true,
'@Symfony:risky' => true,
'array_syntax' => ['syntax' => 'short'],
'combine_consecutive_unsets' => true,
'echo_tag_syntax' => ['format' => 'long'],
'blank_line_before_statement' => true, // Symfony(PSR12) override the default value, but we don't want
'concat_space' => ['spacing' => 'one'],
'header_comment' => ['header' => $header],
'heredoc_to_nowdoc' => true,
'no_extra_blank_lines' => ['tokens' => ['break', 'continue', 'extra', 'return', 'throw', 'use', 'parenthesis_brace_block', 'square_brace_block', 'curly_brace_block']],
'no_unreachable_default_argument_value' => true,
'no_useless_else' => true,
'no_useless_return' => true,
'ordered_class_elements' => true,
'ordered_imports' => true,
'php_unit_construct' => true,
'php_unit_strict' => true,
'phpdoc_add_missing_param_annotation' => true,
'phpdoc_order' => true,
'semicolon_after_instruction' => true,
'strict_comparison' => true,
'strict_param' => true,
'ordered_class_elements' => true, // Symfony(PSR12) override the default value, but we don't want
'php_unit_internal_class' => false, // From @PhpCsFixer but we don't want it
'php_unit_test_class_requires_covers' => false, // From @PhpCsFixer but we don't want it
'phpdoc_add_missing_param_annotation' => false, // From @PhpCsFixer but we don't want it
])
->setUsingCache(true)
->setFinder($finder)
;
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changes between versions

## 7.1.0 (2024-12-07)

* update the SDK based on the latest spec updates - see jolicode/harvest-openapi-generator#29 in #48
* upgrade CS tooling

## 7.0.0 (2024-03-29)

* upgrade to `janephp/open-api` 7.6
Expand Down
35 changes: 15 additions & 20 deletions Resources/harvest-openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ components:
nullable: true
event_type:
type: string
description: 'The type of invoice event that occurred with the message: send, close, draft, re-open, or view.'
description: 'The type of invoice event that occurred with the message: close, draft, re-open, or send (marked the invoice as sent). If event_type was omitted in the request, a null value is returned, meaning the invoice was sent.'
nullable: true
reminder:
type: boolean
Expand Down Expand Up @@ -6975,19 +6975,19 @@ paths:
schema:
type: integer
post:
summary: 'Create an invoice message or change invoice status'
summary: 'Create and send an invoice message'
operationId: createInvoiceMessage
description: 'Creates a new invoice message object. Returns an invoice message object and a 201 Created response code if the call succeeded.'
description: "Creates a new invoice message object and sends it. Returns an invoice message object and a 201 Created response code if the call succeeded.\n\nA note about the optional event_type parameter: If event_type is omitted in a request, its default value of null means the message will be sent. In such a request, if the recipients array is omitted or empty and send_me_a_copy is also omitted or set to false, the request will fail because the message has no recipients. When omitting event_type to create and send a message, be sure to include a recipients array as a parameter or ensure the send_me_a_copy parameter is included and set to true."
externalDocs:
description: 'Create an invoice message'
url: 'https://help.getharvest.com/api-v2/invoices-api/invoices/invoice-messages/#create-an-invoice-message'
description: 'Create and send an invoice message'
url: 'https://help.getharvest.com/api-v2/invoices-api/invoices/invoice-messages/#create-and-send-an-invoice-message'
security:
-
BearerAuth: []
AccountAuth: []
responses:
201:
description: 'Create an invoice message or change invoice status'
description: 'Create and send an invoice message'
content:
application/json:
schema:
Expand Down Expand Up @@ -7039,11 +7039,11 @@ paths:
properties:
event_type:
type: string
description: 'If provided, runs an event against the invoice. Options: close, draft, re-open, or send.'
description: 'Omit when intending to create and send a message. If omitted, the default value is null and the message will be sent. See other sections below for including this parameter with the following options: close, draft, re-open, or send (which marks a draft invoice as sent, it does not send the message).'
nullable: true
recipients:
type: array
description: 'Array of recipient parameters. See below for details.'
description: 'Array of recipient parameters. See below for more details.'
nullable: true
items:
type: object
Expand Down Expand Up @@ -7082,8 +7082,6 @@ paths:
type: boolean
description: 'If set to true, a thank you message email will be sent. Defaults to false.'
nullable: true
required:
- recipients
'/invoices/{invoiceId}/messages/new':
get:
summary: 'Retrieve invoice message subject and body for specific invoice'
Expand Down Expand Up @@ -9548,6 +9546,13 @@ paths:
in: query
schema:
type: string
-
name: include_fixed_fee
description: 'Whether or not to include fixed-fee projects in the response. (Default: true)'
required: false
in: query
schema:
type: boolean
-
name: page
description: 'The page number to use in pagination. For instance, if you make a list request and receive 2000 records, your subsequent call can include page=2 to retrieve the next page of the list. (Default: 1)'
Expand Down Expand Up @@ -12135,16 +12140,6 @@ paths:
description: 'The number of hours per week this person is available to work in seconds.'
nullable: true
format: int32
default_hourly_rate:
type: number
description: 'The billable rate to use for this user when they are added to a project.'
nullable: true
format: float
cost_rate:
type: number
description: 'The cost rate to use for this user when calculating a project’s costs vs billable amount.'
nullable: true
format: float
roles:
type: array
description: 'Descriptive names of the business roles assigned to this person. They can be used for filtering reports, and have no effect in their permissions in Harvest.'
Expand Down
8 changes: 4 additions & 4 deletions castor.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@

use function Castor\exit_code;
use function Castor\fs;
use function Castor\http_request;
use function Castor\import;
use function Castor\io;
use function Castor\request;

import(__DIR__.'/tools/php-cs-fixer/castor.php');
import(__DIR__ . '/tools/php-cs-fixer/castor.php');

const SPEC_URL = 'https://raw.githubusercontent.com/jolicode/harvest-openapi-generator/master/generated/harvest-openapi.yaml';

Expand All @@ -34,10 +34,10 @@ function update(): int
#[AsTask(description: 'Downloads the last specification from Github')]
function update_specification(): void
{
io()->comment(sprintf('Download the spec from %s', SPEC_URL));
io()->comment(\sprintf('Download the spec from %s', SPEC_URL));
fs()->dumpFile(
'Resources/harvest-openapi.yaml',
request('GET', SPEC_URL)->getContent()
http_request('GET', SPEC_URL)->getContent()
);
io()->success('Successfully updated the OpenAPI specification file.');
}
Expand Down
12 changes: 6 additions & 6 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@
"require": {
"php": ">=8.1",
"jane-php/open-api-runtime": "^7.6",
"php-http/client-implementation": "*",
"php-http/client-common": "^1.9 || ^2.0"
"php-http/client-common": "^1.9 || ^2.0",
"php-http/client-implementation": "*"
},
"require-dev": {
"jane-php/open-api-3": "^7.6",
"symfony/http-client": "^5.4 || ^6.0 || ^7.0",
"nyholm/psr7": "^1.6",
"symfony/phpunit-bridge": "^5.4 || ^6.0 || ^7.0",
"symfony/yaml": "^5.4 || ^6.0 || ^7.0"
"symfony/http-client": "^6.4 || ^7.0",
"symfony/phpunit-bridge": "^6.4 || ^7.0"
},
"config": {
"allow-plugins": {
"php-http/discovery": true
}
},
"sort-packages": true
}
}
2 changes: 2 additions & 0 deletions doc/updating-sdk.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ running the following command:

```bash
castor update
castor qa:cs
```

This will both update the specification and re-generate the library code.
Expand All @@ -37,4 +38,5 @@ and re-generate the library code. This can be done with the following commands:
```bash
castor sdk:update-specification
castor sdk:generate
castor qa:cs
```
4 changes: 1 addition & 3 deletions generated/Authentication/AccountAuthAuthentication.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ public function __construct(string $apiKey)

public function authentication(\Psr\Http\Message\RequestInterface $request): \Psr\Http\Message\RequestInterface
{
$request = $request->withHeader('Harvest-Account-Id', $this->{'apiKey'});

return $request;
return $request->withHeader('Harvest-Account-Id', $this->{'apiKey'});
}

public function getScope(): string
Expand Down
4 changes: 1 addition & 3 deletions generated/Authentication/BearerAuthAuthentication.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ public function __construct(string $apiKey)

public function authentication(\Psr\Http\Message\RequestInterface $request): \Psr\Http\Message\RequestInterface
{
$request = $request->withHeader('Authorization', $this->{'apiKey'});

return $request;
return $request->withHeader('Authorization', $this->{'apiKey'});
}

public function getScope(): string
Expand Down
5 changes: 4 additions & 1 deletion generated/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,9 @@ public function listMessagesForInvoice(string $invoiceId, array $queryParameters
}

/**
* Creates a new invoice message object. Returns an invoice message object and a 201 Created response code if the call succeeded.
* Creates a new invoice message object and sends it. Returns an invoice message object and a 201 Created response code if the call succeeded.
*
* A note about the optional event_type parameter: If event_type is omitted in a request, its default value of null means the message will be sent. In such a request, if the recipients array is omitted or empty and send_me_a_copy is also omitted or set to false, the request will fail because the message has no recipients. When omitting event_type to create and send a message, be sure to include a recipients array as a parameter or ensure the send_me_a_copy parameter is included and set to true.
*
* @param string $fetch Fetch mode to use (can be OBJECT or RESPONSE)
*
Expand Down Expand Up @@ -1157,6 +1159,7 @@ public function teamTimeReport(array $queryParameters = [], string $fetch = self
*
* @var string $from only report on time entries and expenses with a spent_date on or after the given date
* @var string $to only report on time entries and expenses with a spent_date on or before the given date
* @var bool $include_fixed_fee Whether or not to include fixed-fee projects in the response. (Default: true)
* @var int $page The page number to use in pagination. For instance, if you make a list request and receive 2000 records, your subsequent call can include page=2 to retrieve the next page of the list. (Default: 1)
* @var int $per_page The number of records to return per page. Can range between 1 and 2000. (Default: 2000)
* }
Expand Down
4 changes: 2 additions & 2 deletions generated/Endpoint/ClientsExpensesReport.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ protected function transformResponseBody(\Psr\Http\Message\ResponseInterface $re
$status = $response->getStatusCode();
$body = (string) $response->getBody();
if ((null === $contentType) === false && (200 === $status && false !== mb_strpos($contentType, 'application/json'))) {
return $serializer->deserialize($body, 'JoliCode\\Harvest\\Api\\Model\\ExpenseReportsResults', 'json');
return $serializer->deserialize($body, 'JoliCode\Harvest\Api\Model\ExpenseReportsResults', 'json');
}
if (false !== mb_strpos($contentType, 'application/json')) {
return $serializer->deserialize($body, 'JoliCode\\Harvest\\Api\\Model\\Error', 'json');
return $serializer->deserialize($body, 'JoliCode\Harvest\Api\Model\Error', 'json');
}
}
}
4 changes: 2 additions & 2 deletions generated/Endpoint/ClientsTimeReport.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ protected function transformResponseBody(\Psr\Http\Message\ResponseInterface $re
$status = $response->getStatusCode();
$body = (string) $response->getBody();
if ((null === $contentType) === false && (200 === $status && false !== mb_strpos($contentType, 'application/json'))) {
return $serializer->deserialize($body, 'JoliCode\\Harvest\\Api\\Model\\TimeReportsResults', 'json');
return $serializer->deserialize($body, 'JoliCode\Harvest\Api\Model\TimeReportsResults', 'json');
}
if (false !== mb_strpos($contentType, 'application/json')) {
return $serializer->deserialize($body, 'JoliCode\\Harvest\\Api\\Model\\Error', 'json');
return $serializer->deserialize($body, 'JoliCode\Harvest\Api\Model\Error', 'json');
}
}
}
4 changes: 2 additions & 2 deletions generated/Endpoint/CreateBillableRate.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ protected function transformResponseBody(\Psr\Http\Message\ResponseInterface $re
$status = $response->getStatusCode();
$body = (string) $response->getBody();
if ((null === $contentType) === false && (201 === $status && false !== mb_strpos($contentType, 'application/json'))) {
return $serializer->deserialize($body, 'JoliCode\\Harvest\\Api\\Model\\BillableRate', 'json');
return $serializer->deserialize($body, 'JoliCode\Harvest\Api\Model\BillableRate', 'json');
}
if (false !== mb_strpos($contentType, 'application/json')) {
return $serializer->deserialize($body, 'JoliCode\\Harvest\\Api\\Model\\Error', 'json');
return $serializer->deserialize($body, 'JoliCode\Harvest\Api\Model\Error', 'json');
}
}
}
4 changes: 2 additions & 2 deletions generated/Endpoint/CreateClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ protected function transformResponseBody(\Psr\Http\Message\ResponseInterface $re
$status = $response->getStatusCode();
$body = (string) $response->getBody();
if ((null === $contentType) === false && (201 === $status && false !== mb_strpos($contentType, 'application/json'))) {
return $serializer->deserialize($body, 'JoliCode\\Harvest\\Api\\Model\\Client', 'json');
return $serializer->deserialize($body, 'JoliCode\Harvest\Api\Model\Client', 'json');
}
if (false !== mb_strpos($contentType, 'application/json')) {
return $serializer->deserialize($body, 'JoliCode\\Harvest\\Api\\Model\\Error', 'json');
return $serializer->deserialize($body, 'JoliCode\Harvest\Api\Model\Error', 'json');
}
}
}
4 changes: 2 additions & 2 deletions generated/Endpoint/CreateContact.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ protected function transformResponseBody(\Psr\Http\Message\ResponseInterface $re
$status = $response->getStatusCode();
$body = (string) $response->getBody();
if ((null === $contentType) === false && (201 === $status && false !== mb_strpos($contentType, 'application/json'))) {
return $serializer->deserialize($body, 'JoliCode\\Harvest\\Api\\Model\\Contact', 'json');
return $serializer->deserialize($body, 'JoliCode\Harvest\Api\Model\Contact', 'json');
}
if (false !== mb_strpos($contentType, 'application/json')) {
return $serializer->deserialize($body, 'JoliCode\\Harvest\\Api\\Model\\Error', 'json');
return $serializer->deserialize($body, 'JoliCode\Harvest\Api\Model\Error', 'json');
}
}
}
4 changes: 2 additions & 2 deletions generated/Endpoint/CreateCostRate.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,10 @@ protected function transformResponseBody(\Psr\Http\Message\ResponseInterface $re
$status = $response->getStatusCode();
$body = (string) $response->getBody();
if ((null === $contentType) === false && (201 === $status && false !== mb_strpos($contentType, 'application/json'))) {
return $serializer->deserialize($body, 'JoliCode\\Harvest\\Api\\Model\\CostRate', 'json');
return $serializer->deserialize($body, 'JoliCode\Harvest\Api\Model\CostRate', 'json');
}
if (false !== mb_strpos($contentType, 'application/json')) {
return $serializer->deserialize($body, 'JoliCode\\Harvest\\Api\\Model\\Error', 'json');
return $serializer->deserialize($body, 'JoliCode\Harvest\Api\Model\Error', 'json');
}
}
}
4 changes: 2 additions & 2 deletions generated/Endpoint/CreateEstimate.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ protected function transformResponseBody(\Psr\Http\Message\ResponseInterface $re
$status = $response->getStatusCode();
$body = (string) $response->getBody();
if ((null === $contentType) === false && (201 === $status && false !== mb_strpos($contentType, 'application/json'))) {
return $serializer->deserialize($body, 'JoliCode\\Harvest\\Api\\Model\\Estimate', 'json');
return $serializer->deserialize($body, 'JoliCode\Harvest\Api\Model\Estimate', 'json');
}
if (false !== mb_strpos($contentType, 'application/json')) {
return $serializer->deserialize($body, 'JoliCode\\Harvest\\Api\\Model\\Error', 'json');
return $serializer->deserialize($body, 'JoliCode\Harvest\Api\Model\Error', 'json');
}
}
}
4 changes: 2 additions & 2 deletions generated/Endpoint/CreateEstimateItemCategory.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ protected function transformResponseBody(\Psr\Http\Message\ResponseInterface $re
$status = $response->getStatusCode();
$body = (string) $response->getBody();
if ((null === $contentType) === false && (201 === $status && false !== mb_strpos($contentType, 'application/json'))) {
return $serializer->deserialize($body, 'JoliCode\\Harvest\\Api\\Model\\EstimateItemCategory', 'json');
return $serializer->deserialize($body, 'JoliCode\Harvest\Api\Model\EstimateItemCategory', 'json');
}
if (false !== mb_strpos($contentType, 'application/json')) {
return $serializer->deserialize($body, 'JoliCode\\Harvest\\Api\\Model\\Error', 'json');
return $serializer->deserialize($body, 'JoliCode\Harvest\Api\Model\Error', 'json');
}
}
}
4 changes: 2 additions & 2 deletions generated/Endpoint/CreateEstimateMessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ protected function transformResponseBody(\Psr\Http\Message\ResponseInterface $re
$status = $response->getStatusCode();
$body = (string) $response->getBody();
if ((null === $contentType) === false && (201 === $status && false !== mb_strpos($contentType, 'application/json'))) {
return $serializer->deserialize($body, 'JoliCode\\Harvest\\Api\\Model\\EstimateMessage', 'json');
return $serializer->deserialize($body, 'JoliCode\Harvest\Api\Model\EstimateMessage', 'json');
}
if (false !== mb_strpos($contentType, 'application/json')) {
return $serializer->deserialize($body, 'JoliCode\\Harvest\\Api\\Model\\Error', 'json');
return $serializer->deserialize($body, 'JoliCode\Harvest\Api\Model\Error', 'json');
}
}
}
Loading
Loading