2022-01-02 01:07:11 +13:00
< ? php
global $cli ;
use Utopia\Validator\Text ;
use Appwrite\Specification\Format\OpenAPI3 ;
use Appwrite\Specification\Format\Swagger2 ;
use Appwrite\Specification\Specification ;
use Appwrite\Utopia\Response ;
use Swoole\Http\Response as HttpResponse ;
use Utopia\App ;
use Utopia\CLI\Console ;
use Utopia\Config\Config ;
use Utopia\Request ;
use Utopia\Validator\WhiteList ;
$cli
-> task ( 'specs' )
2022-09-01 16:49:24 +12:00
-> param ( 'version' , 'latest' , new Text ( 16 ), 'Spec version' , true )
2022-01-02 06:41:32 +13:00
-> param ( 'mode' , 'normal' , new WhiteList ([ 'normal' , 'mocks' ]), 'Spec Mode' , true )
2022-01-02 01:07:11 +13:00
-> action ( function ( $version , $mode ) use ( $register ) {
$db = $register -> get ( 'db' );
$redis = $register -> get ( 'cache' );
$appRoutes = App :: getRoutes ();
$response = new Response ( new HttpResponse ());
2022-01-02 06:41:32 +13:00
$mocks = ( $mode === 'mocks' );
2022-01-02 01:07:11 +13:00
2022-05-24 02:54:50 +12:00
App :: setResource ( 'request' , fn () => new Request ());
2022-01-04 04:51:00 +13:00
App :: setResource ( 'response' , fn () => $response );
App :: setResource ( 'db' , fn () => $db );
App :: setResource ( 'cache' , fn () => $redis );
2022-01-02 01:07:11 +13:00
$platforms = [
'client' => APP_PLATFORM_CLIENT ,
'server' => APP_PLATFORM_SERVER ,
'console' => APP_PLATFORM_CONSOLE ,
];
$authCounts = [
'client' => 1 ,
'server' => 2 ,
'console' => 1 ,
];
$keys = [
APP_PLATFORM_CLIENT => [
'Project' => [
'type' => 'apiKey' ,
'name' => 'X-Appwrite-Project' ,
'description' => 'Your project ID' ,
'in' => 'header' ,
],
'JWT' => [
'type' => 'apiKey' ,
'name' => 'X-Appwrite-JWT' ,
'description' => 'Your secret JSON Web Token' ,
'in' => 'header' ,
],
'Locale' => [
'type' => 'apiKey' ,
'name' => 'X-Appwrite-Locale' ,
'description' => '' ,
'in' => 'header' ,
],
],
APP_PLATFORM_SERVER => [
'Project' => [
'type' => 'apiKey' ,
'name' => 'X-Appwrite-Project' ,
'description' => 'Your project ID' ,
'in' => 'header' ,
],
'Key' => [
'type' => 'apiKey' ,
'name' => 'X-Appwrite-Key' ,
'description' => 'Your secret API key' ,
'in' => 'header' ,
],
'JWT' => [
'type' => 'apiKey' ,
'name' => 'X-Appwrite-JWT' ,
'description' => 'Your secret JSON Web Token' ,
'in' => 'header' ,
],
'Locale' => [
'type' => 'apiKey' ,
'name' => 'X-Appwrite-Locale' ,
'description' => '' ,
'in' => 'header' ,
],
],
APP_PLATFORM_CONSOLE => [
'Project' => [
'type' => 'apiKey' ,
'name' => 'X-Appwrite-Project' ,
'description' => 'Your project ID' ,
'in' => 'header' ,
],
'Key' => [
'type' => 'apiKey' ,
'name' => 'X-Appwrite-Key' ,
'description' => 'Your secret API key' ,
'in' => 'header' ,
],
'JWT' => [
'type' => 'apiKey' ,
'name' => 'X-Appwrite-JWT' ,
'description' => 'Your secret JSON Web Token' ,
'in' => 'header' ,
],
'Locale' => [
'type' => 'apiKey' ,
'name' => 'X-Appwrite-Locale' ,
'description' => '' ,
'in' => 'header' ,
],
'Mode' => [
'type' => 'apiKey' ,
'name' => 'X-Appwrite-Mode' ,
'description' => '' ,
'in' => 'header' ,
],
],
];
2022-06-30 11:41:49 +12:00
foreach ( $platforms as $platform ) {
$routes = [];
$models = [];
$services = [];
foreach ( $appRoutes as $key => $method ) {
foreach ( $method as $route ) {
/** @var \Utopia\Route $route */
$routeSecurity = $route -> getLabel ( 'sdk.auth' , []);
2022-06-30 20:51:35 +12:00
$sdkPlaforms = [];
2022-06-30 11:41:49 +12:00
foreach ( $routeSecurity as $value ) {
switch ( $value ) {
case APP_AUTH_TYPE_SESSION :
2022-06-30 20:51:35 +12:00
$sdkPlaforms [] = APP_PLATFORM_CLIENT ;
2022-06-30 11:41:49 +12:00
break ;
case APP_AUTH_TYPE_KEY :
2022-06-30 20:51:35 +12:00
$sdkPlaforms [] = APP_PLATFORM_SERVER ;
2022-06-30 11:41:49 +12:00
break ;
case APP_AUTH_TYPE_JWT :
2022-06-30 20:51:35 +12:00
$sdkPlaforms [] = APP_PLATFORM_SERVER ;
2022-06-30 11:41:49 +12:00
break ;
case APP_AUTH_TYPE_ADMIN :
2022-06-30 20:51:35 +12:00
$sdkPlaforms [] = APP_PLATFORM_CONSOLE ;
2022-06-30 11:41:49 +12:00
break ;
2022-01-02 01:07:11 +13:00
}
2022-06-30 11:41:49 +12:00
}
2022-01-04 04:51:00 +13:00
2022-06-30 11:41:49 +12:00
if ( empty ( $routeSecurity )) {
2022-06-30 20:51:35 +12:00
$sdkPlaforms [] = APP_PLATFORM_CLIENT ;
2022-06-30 11:41:49 +12:00
}
2022-01-04 04:51:00 +13:00
2022-06-30 11:41:49 +12:00
if ( ! $route -> getLabel ( 'docs' , true )) {
continue ;
}
2022-01-04 04:51:00 +13:00
2022-06-30 11:41:49 +12:00
if ( $route -> getLabel ( 'sdk.mock' , false ) && ! $mocks ) {
continue ;
}
2022-01-04 04:51:00 +13:00
2022-06-30 11:41:49 +12:00
if ( ! $route -> getLabel ( 'sdk.mock' , false ) && $mocks ) {
continue ;
}
2022-01-04 04:51:00 +13:00
2022-06-30 11:41:49 +12:00
if ( empty ( $route -> getLabel ( 'sdk.namespace' , null ))) {
continue ;
2022-01-02 01:07:11 +13:00
}
2022-01-04 04:51:00 +13:00
2022-06-30 20:51:35 +12:00
if ( $platform !== APP_PLATFORM_CONSOLE && ! \in_array ( $platforms [ $platform ], $sdkPlaforms )) {
2022-01-02 01:07:11 +13:00
continue ;
}
2022-01-04 04:51:00 +13:00
2022-06-30 11:41:49 +12:00
$routes [] = $route ;
2022-01-02 01:07:11 +13:00
}
2022-06-30 11:41:49 +12:00
}
foreach ( Config :: getParam ( 'services' , []) as $service ) {
if (
! isset ( $service [ 'docs' ]) // Skip service if not part of the public API
|| ! isset ( $service [ 'sdk' ])
|| ! $service [ 'docs' ]
|| ! $service [ 'sdk' ]
) {
continue ;
2022-01-02 01:07:11 +13:00
}
2022-01-04 04:51:00 +13:00
2022-06-30 11:41:49 +12:00
$services [] = [
'name' => $service [ 'key' ] ? ? '' ,
'description' => $service [ 'subtitle' ] ? ? '' ,
'x-globalAttributes' => $service [ 'globalAttributes' ] ? ? [],
];
}
2022-01-04 04:51:00 +13:00
2022-06-30 11:41:49 +12:00
$models = $response -> getModels ();
2022-01-04 04:51:00 +13:00
2022-06-30 11:41:49 +12:00
foreach ( $models as $key => $value ) {
if ( $platform !== APP_PLATFORM_CONSOLE && ! $value -> isPublic ()) {
unset ( $models [ $key ]);
2022-01-02 01:07:11 +13:00
}
2022-06-30 11:41:49 +12:00
}
// var_dump($models);
$arguments = [ new App ( 'UTC' ), $services , $routes , $models , $keys [ $platform ], $authCounts [ $platform ] ? ? 0 ];
foreach ([ 'swagger2' , 'open-api3' ] as $format ) {
2022-06-30 11:46:04 +12:00
$formatInstance = match ( $format ) {
2022-06-30 11:41:49 +12:00
'swagger2' => new Swagger2 ( ... $arguments ),
'open-api3' => new OpenAPI3 ( ... $arguments ),
default => throw new Exception ( 'Format not found: ' . $format )
};
2022-01-04 04:51:00 +13:00
2022-01-02 01:07:11 +13:00
$specs = new Specification ( $formatInstance );
$endpoint = App :: getEnv ( '_APP_HOME' , '[HOSTNAME]' );
$email = App :: getEnv ( '_APP_SYSTEM_EMAIL_ADDRESS' , APP_EMAIL_TEAM );
2022-01-04 04:51:00 +13:00
2022-01-02 01:07:11 +13:00
$formatInstance
-> setParam ( 'name' , APP_NAME )
-> setParam ( 'description' , 'Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https://appwrite.io/docs](https://appwrite.io/docs)' )
-> setParam ( 'endpoint' , 'https://HOSTNAME/v1' )
-> setParam ( 'version' , APP_VERSION_STABLE )
2022-01-04 04:51:00 +13:00
-> setParam ( 'terms' , $endpoint . '/policy/terms' )
2022-01-02 01:07:11 +13:00
-> setParam ( 'support.email' , $email )
2022-01-04 04:51:00 +13:00
-> setParam ( 'support.url' , $endpoint . '/support' )
-> setParam ( 'contact.name' , APP_NAME . ' Team' )
2022-01-02 01:07:11 +13:00
-> setParam ( 'contact.email' , $email )
2022-01-04 04:51:00 +13:00
-> setParam ( 'contact.url' , $endpoint . '/support' )
2022-01-02 01:07:11 +13:00
-> setParam ( 'license.name' , 'BSD-3-Clause' )
-> setParam ( 'license.url' , 'https://raw.githubusercontent.com/appwrite/appwrite/master/LICENSE' )
-> setParam ( 'docs.description' , 'Full API docs, specs and tutorials' )
2022-01-04 04:51:00 +13:00
-> setParam ( 'docs.url' , $endpoint . '/docs' );
2022-01-02 01:07:11 +13:00
2022-01-04 04:51:00 +13:00
if ( $mocks ) {
$path = __DIR__ . '/../config/specs/' . $format . '-mocks-' . $platform . '.json' ;
2022-01-02 01:07:11 +13:00
2022-01-04 04:51:00 +13:00
if ( ! file_put_contents ( $path , json_encode ( $specs -> parse ()))) {
throw new Exception ( 'Failed to save mocks spec file: ' . $path );
2022-01-02 01:07:11 +13:00
}
2022-01-04 04:51:00 +13:00
2022-01-02 06:41:32 +13:00
Console :: success ( 'Saved mocks spec file: ' . realpath ( $path ));
2022-01-02 01:07:11 +13:00
continue ;
}
2022-01-04 04:51:00 +13:00
$path = __DIR__ . '/../config/specs/' . $format . '-' . $version . '-' . $platform . '.json' ;
2022-01-02 01:07:11 +13:00
2022-01-04 04:51:00 +13:00
if ( ! file_put_contents ( $path , json_encode ( $specs -> parse ()))) {
throw new Exception ( 'Failed to save spec file: ' . $path );
2022-01-02 01:07:11 +13:00
}
Console :: success ( 'Saved spec file: ' . realpath ( $path ));
}
}
2022-01-04 04:51:00 +13:00
});