Skip to content

Commit 3b007d6

Browse files
authored
Merge pull request #28 from jolicode/feat/spec-update-20240328
feat(spec) update the spec as of today
2 parents ae5d9f0 + b0c9028 commit 3b007d6

File tree

4 files changed

+86
-19
lines changed

4 files changed

+86
-19
lines changed

composer.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616
}
1717
},
1818
"require": {
19-
"symfony/console": "^6.1",
20-
"symfony/dom-crawler": "^6.1",
21-
"symfony/css-selector": "^6.1",
22-
"symfony/yaml": "^6.1"
19+
"symfony/console": "^7.0.4",
20+
"symfony/dom-crawler": "^7.0.4",
21+
"symfony/css-selector": "^7.0.3",
22+
"symfony/yaml": "^7.0.3"
2323
},
2424
"require-dev": {
25-
"friendsofphp/php-cs-fixer": "^3.13"
25+
"friendsofphp/php-cs-fixer": "^3.52.1"
2626
}
2727
}

generated/harvest-openapi.yaml

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,7 +1044,7 @@ components:
10441044
nullable: true
10451045
is_closed:
10461046
type: boolean
1047-
description: 'Whether the expense has been approved or closed for some other reason.'
1047+
description: 'Whether the expense has been approved or not.'
10481048
nullable: true
10491049
is_locked:
10501050
type: boolean
@@ -1293,7 +1293,7 @@ components:
12931293
nullable: true
12941294
timer_started_at:
12951295
type: string
1296-
description: 'Date and time the timer was started (if tracking by duration). Use the ISO 8601 Format.'
1296+
description: 'Date and time the running timer was started (if tracking by duration). Use the ISO 8601 Format. Returns null for stopped timers.'
12971297
nullable: true
12981298
format: date-time
12991299
started_time:
@@ -7330,6 +7330,10 @@ paths:
73307330
type: string
73317331
description: 'Any notes to be associated with the payment.'
73327332
nullable: true
7333+
send_thank_you:
7334+
type: boolean
7335+
description: 'Whether or not to send a thank you email (if enabled for your account in Invoices > Configure > Messages). Only sends an email if the invoice will be fully paid after creating this payment. Defaults to true.'
7336+
nullable: true
73337337
required:
73347338
- amount
73357339
'/invoices/{invoiceId}/payments/{paymentId}':
@@ -9126,6 +9130,13 @@ paths:
91269130
in: query
91279131
schema:
91289132
type: string
9133+
-
9134+
name: include_fixed_fee
9135+
description: 'When true, billable amounts will be calculated and included for fixed fee projects.'
9136+
required: false
9137+
in: query
9138+
schema:
9139+
type: string
91299140
-
91309141
name: page
91319142
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)'
@@ -9220,6 +9231,13 @@ paths:
92209231
in: query
92219232
schema:
92229233
type: string
9234+
-
9235+
name: include_fixed_fee
9236+
description: 'When true, billable amounts will be calculated and included for fixed fee projects.'
9237+
required: false
9238+
in: query
9239+
schema:
9240+
type: string
92239241
-
92249242
name: page
92259243
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)'
@@ -9322,6 +9340,13 @@ paths:
93229340
in: query
93239341
schema:
93249342
type: string
9343+
-
9344+
name: include_fixed_fee
9345+
description: 'When true, billable amounts will be calculated and included for fixed fee projects.'
9346+
required: false
9347+
in: query
9348+
schema:
9349+
type: string
93259350
-
93269351
name: page
93279352
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)'
@@ -9419,6 +9444,13 @@ paths:
94199444
in: query
94209445
schema:
94219446
type: string
9447+
-
9448+
name: include_fixed_fee
9449+
description: 'When true, billable amounts will be calculated and included for fixed fee projects.'
9450+
required: false
9451+
in: query
9452+
schema:
9453+
type: string
94229454
-
94239455
name: page
94249456
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)'

src/Command/GenerateCommand.php

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,20 @@
1919

2020
class GenerateCommand extends Command
2121
{
22-
/**
23-
* {@inheritdoc}
24-
*/
2522
public function configure()
2623
{
2724
$this->setName('generate');
2825
$this->setDescription('Generate a Harvest\'s swagger.yaml definition.');
2926
}
3027

31-
/**
32-
* {@inheritdoc}
33-
*/
34-
public function execute(InputInterface $input, OutputInterface $output)
28+
public function execute(InputInterface $input, OutputInterface $output): int
3529
{
3630
$extractor = new Extractor();
3731
$dumper = new Dumper(__DIR__.'/../../generated/harvest-openapi.yaml');
3832
$warnings = $dumper->dump($extractor->extract());
3933

4034
if (\count($warnings) > 0) {
35+
/** @var \Symfony\Component\Console\Helper\FormatterHelper */
4136
$formatter = $this->getHelper('formatter');
4237
$output->writeln($formatter->formatBlock($warnings, 'bg=yellow;fg=black', true));
4338
}

src/Extractor/Extractor.php

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public static function buildDefinitionProperty($name, $type, $description, $path
107107

108108
if (null !== $arrayof) {
109109
$property['items'] = ['type' => $arrayof];
110-
} else if ('array' === $type && 'payment_options' === $name) {
110+
} elseif ('array' === $type && 'payment_options' === $name) {
111111
$property['items'] = [
112112
'type' => 'string',
113113
'enum' => [
@@ -399,6 +399,8 @@ public static function buildPath($url, $path, $method, $node, $title)
399399
{
400400
$description = [];
401401
$parentNode = $node->ancestors()->filter('.highlighter-rouge')->first();
402+
$summary = '';
403+
$summaryId = '';
402404

403405
foreach ($parentNode->previousAll() as $previous) {
404406
if ('h2' === $previous->tagName) {
@@ -442,6 +444,7 @@ public static function buildPath($url, $path, $method, $node, $title)
442444
}
443445

444446
if ('figure' === $next->tagName) {
447+
$next = self::decodeEmailAddresses($next);
445448
$example = $next->textContent;
446449
break;
447450
}
@@ -526,7 +529,7 @@ public static function buildRequestBody($method, $path, $explicitParameters, $ex
526529

527530
if ('required' === $required) {
528531
$requiredProperties[] = $parameter;
529-
} else if (!\in_array($required, ['optional', 'required'])) {
532+
} elseif (!\in_array($required, ['optional', 'required'], true)) {
530533
$description = $required;
531534
}
532535
}
@@ -801,7 +804,7 @@ public static function guessPathResponseSchema($summary, $title)
801804

802805
public static function guessPathResponseStatus($method, $summary)
803806
{
804-
if (0 === strpos($summary, 'Create a')) {
807+
if (str_starts_with($summary, 'Create a')) {
805808
return 201;
806809
}
807810

@@ -870,7 +873,7 @@ private function printOperationsIdList()
870873
echo " * $family\n";
871874

872875
foreach ($familyOperations as $operation) {
873-
echo " * $operation\n";
876+
echo " * `$operation()`\n";
874877
}
875878
}
876879
}
@@ -912,14 +915,51 @@ private static function cleanupSummary($summary)
912915
return isset($summaries[$summary]) ? $summaries[$summary] : $summary;
913916
}
914917

918+
private static function getPower(string $email, int $position): int
919+
{
920+
$char = substr($email, $position, 2);
921+
922+
return \intval($char, 16);
923+
}
924+
925+
private static function decodeEmailAddress(string $email): string
926+
{
927+
$output = '';
928+
$power = self::getPower($email, 0);
929+
$i = 2;
930+
931+
while ($i < \strlen($email)) {
932+
$char = self::getPower($email, $i) ^ $power;
933+
$output .= \chr($char);
934+
$i += 2;
935+
}
936+
937+
return $output;
938+
}
939+
940+
private static function decodeEmailAddresses(\DOMElement $next)
941+
{
942+
foreach ($next->childNodes as $child) {
943+
if ($child instanceof \DOMElement) {
944+
if ('a' === $child->tagName && $child->hasAttribute('data-cfemail')) {
945+
$child->textContent = self::decodeEmailAddress($child->getAttribute('data-cfemail'));
946+
}
947+
948+
$child = self::decodeEmailAddresses($child);
949+
}
950+
}
951+
952+
return $next;
953+
}
954+
915955
private function buildItemsTypes()
916956
{
917957
foreach ($this->definitions as $definitionName => $definition) {
918958
foreach ($definition['properties'] as $propertyName => $property) {
919959
if (isset($property['items']) && isset($property['items']['type'])) {
920960
if (isset($this->definitions[$property['items']['type']])) {
921961
$this->definitions[$definitionName]['properties'][$propertyName]['items'] = ['$ref' => '#/components/schemas/'.$property['items']['type']];
922-
} else if (!\in_array($property['items']['type'], self::BASE_TYPES, true)) {
962+
} elseif (!\in_array($property['items']['type'], self::BASE_TYPES, true)) {
923963
echo $property['items']['type']."\n";
924964
}
925965
}

0 commit comments

Comments
 (0)