123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- <?php
- namespace Knuckles\Camel;
- use Illuminate\Support\Arr;
- use Illuminate\Support\Collection;
- use Illuminate\Support\Str;
- use Knuckles\Camel\Extraction\ExtractedEndpointData;
- use Knuckles\Camel\Output\OutputEndpointData;
- use Knuckles\Scribe\Tools\Utils;
- use Symfony\Component\Yaml\Yaml;
- class Camel
- {
- /**
- * Mapping of group names to their generated file names. Helps us respect user reordering.
- * @var array<string, string>
- */
- public static array $groupFileNames = [];
- /**
- * @deprecated Use the cacheDir() method instead
- */
- public static string $cacheDir = ".scribe/endpoints.cache";
- /**
- * @deprecated Use the camelDir() method instead
- */
- public static string $camelDir = ".scribe/endpoints";
- public static function cacheDir(string $docsName = 'scribe')
- {
- return ".$docsName/endpoints.cache";
- }
- public static function camelDir(string $docsName = 'scribe')
- {
- return ".$docsName/endpoints";
- }
- /**
- * Load endpoints from the Camel files into groups (arrays).
- *
- * @param string $folder
- *
- * @return array[]
- */
- public static function loadEndpointsIntoGroups(string $folder): array
- {
- $groups = [];
- self::loadEndpointsFromCamelFiles($folder, function ($group) use (&$groups) {
- $group['endpoints'] = array_map(function (array $endpoint) {
- return OutputEndpointData::fromExtractedEndpointArray($endpoint);
- }, $group['endpoints']);
- $groups[] = $group;
- });
- return $groups;
- }
- /**
- * Load endpoints from the Camel files into a flat list of endpoint arrays.
- *
- * @param string $folder
- *
- * @return array[]
- */
- public static function loadEndpointsToFlatPrimitivesArray(string $folder, bool $isFromCache = false): array
- {
- $endpoints = [];
- self::loadEndpointsFromCamelFiles($folder, function ($group) use (&$endpoints) {
- foreach ($group['endpoints'] as $endpoint) {
- $endpoints[] = $endpoint;
- }
- }, !$isFromCache);
- return $endpoints;
- }
- public static function loadEndpointsFromCamelFiles(string $folder, callable $callback, bool $storeGroupFilePaths = true)
- {
- $contents = Utils::listDirectoryContents($folder);
- foreach ($contents as $object) {
- // Flysystem v1 had items as arrays; v2 has objects.
- // v2 allows ArrayAccess, but when we drop v1 support (Laravel <9), we should switch to methods
- if (
- $object['type'] == 'file'
- && Str::endsWith(basename($object['path']), '.yaml')
- && !Str::startsWith(basename($object['path']), 'custom.')
- ) {
- $group = Yaml::parseFile($object['path']);
- if ($storeGroupFilePaths) {
- $filePathParts = explode('/', $object['path']);
- self::$groupFileNames[$group['name']] = end($filePathParts);
- }
- $callback($group);
- }
- }
- }
- public static function loadUserDefinedEndpoints(string $folder): array
- {
- $contents = Utils::listDirectoryContents($folder);
- $userDefinedEndpoints = [];
- foreach ($contents as $object) {
- // Flysystem v1 had items as arrays; v2 has objects.
- // v2 allows ArrayAccess, but when we drop v1 support (Laravel <9), we should switch to methods
- if (
- $object['type'] == 'file'
- && Str::endsWith(basename($object['path']), '.yaml')
- && Str::startsWith(basename($object['path']), 'custom.')
- ) {
- $endpoints = Yaml::parseFile($object['path']);
- foreach (($endpoints ?: []) as $endpoint) {
- $userDefinedEndpoints[] = $endpoint;
- }
- }
- }
- return $userDefinedEndpoints;
- }
- public static function doesGroupContainEndpoint(array $group, OutputEndpointData $endpoint): bool
- {
- return boolval(Arr::first($group['endpoints'], function ($e) use ($endpoint) {
- return $e->endpointId() === $endpoint->endpointId();
- }));
- }
- public static function getEndpointIndexInGroup(array $groups, OutputEndpointData $endpoint): ?int
- {
- foreach ($groups as $group) {
- foreach ($group['endpoints'] as $index => $endpointInGroup) {
- if ($endpointInGroup->endpointId() === $endpoint->endpointId()) {
- return $index;
- }
- }
- }
- return null;
- }
- /**
- * @param array[] $endpoints
- * @param array $endpointGroupIndexes Mapping of endpoint IDs to their index within their group
- *
- * @return array[]
- */
- public static function groupEndpoints(array $endpoints, array $endpointGroupIndexes): array
- {
- $groupedEndpoints = collect($endpoints)
- ->groupBy('metadata.groupName')
- ->sortKeys(SORT_NATURAL);
- return $groupedEndpoints->map(function (Collection $endpointsInGroup) use ($endpointGroupIndexes) {
- /** @var Collection<(int|string),ExtractedEndpointData> $endpointsInGroup */
- $sortedEndpoints = $endpointsInGroup;
- if (!empty($endpointGroupIndexes)) {
- $sortedEndpoints = $endpointsInGroup->sortBy(
- fn(ExtractedEndpointData $e) => $endpointGroupIndexes[$e->endpointId()] ?? INF,
- );
- }
- return [
- 'name' => Arr::first($endpointsInGroup, function (ExtractedEndpointData $endpointData) {
- return !empty($endpointData->metadata->groupName);
- })->metadata->groupName ?? '',
- 'description' => Arr::first($endpointsInGroup, function (ExtractedEndpointData $endpointData) {
- return !empty($endpointData->metadata->groupDescription);
- })->metadata->groupDescription ?? '',
- 'endpoints' => $sortedEndpoints->map(
- fn(ExtractedEndpointData $endpointData) => $endpointData->forSerialisation()->toArray()
- )->values()->all(),
- ];
- })->values()->all();
- }
- public static function prepareGroupedEndpointsForOutput(array $groupedEndpoints): array
- {
- $groups = array_map(function (array $group) {
- return [
- 'name' => $group['name'],
- 'description' => $group['description'],
- 'fileName' => self::$groupFileNames[$group['name']] ?? null,
- 'endpoints' => array_map(function (array $endpoint) {
- return OutputEndpointData::fromExtractedEndpointArray($endpoint);
- }, $group['endpoints']),
- ];
- }, $groupedEndpoints);
- return array_values(Arr::sort($groups, 'fileName'));
- }
- }
|