2019-05-09 18:54:39 +12:00
< ? php
2019-12-17 08:35:33 +13:00
include_once __DIR__ . '/../shared/web.php' ;
2019-05-09 18:54:39 +12:00
2020-03-29 01:42:16 +13:00
global $utopia , $response , $request , $layout ;
2019-05-09 18:54:39 +12:00
use Utopia\View ;
2020-03-29 01:42:16 +13:00
use Utopia\Config\Config ;
2020-05-17 17:27:10 +12:00
use Utopia\Validator\WhiteList ;
use Utopia\Validator\Range ;
2019-05-09 18:54:39 +12:00
2019-12-17 08:35:33 +13:00
$header = new View ( __DIR__ . '/../../views/home/comps/header.phtml' );
$footer = new View ( __DIR__ . '/../../views/home/comps/footer.phtml' );
2019-11-13 07:41:48 +13:00
$footer
2020-03-29 01:42:16 +13:00
-> setParam ( 'version' , Config :: getParam ( 'version' ))
2019-11-13 07:41:48 +13:00
;
2019-05-09 18:54:39 +12:00
$layout
-> setParam ( 'title' , APP_NAME )
2019-09-27 06:47:48 +12:00
-> setParam ( 'description' , '' )
2019-05-09 18:54:39 +12:00
-> setParam ( 'class' , 'home' )
2020-03-29 01:42:16 +13:00
-> setParam ( 'platforms' , Config :: getParam ( 'platforms' ))
2019-11-13 07:41:48 +13:00
-> setParam ( 'header' , [ $header ])
-> setParam ( 'footer' , [ $footer ])
2019-05-09 18:54:39 +12:00
;
2019-11-29 20:35:26 +13:00
$utopia -> shutdown ( function () use ( $response , $layout ) {
2019-05-09 18:54:39 +12:00
$response -> send ( $layout -> render ());
});
$utopia -> get ( '/' )
-> label ( 'permission' , 'public' )
-> label ( 'scope' , 'home' )
-> action (
2019-09-07 05:10:41 +12:00
function () use ( $response ) {
2019-05-09 18:54:39 +12:00
$response -> redirect ( '/auth/signin' );
}
);
$utopia -> get ( '/auth/signin' )
-> desc ( 'Login page' )
-> label ( 'permission' , 'public' )
-> label ( 'scope' , 'home' )
2019-09-07 05:10:41 +12:00
-> action ( function () use ( $layout ) {
2019-12-17 08:35:33 +13:00
$page = new View ( __DIR__ . '/../../views/home/auth/signin.phtml' );
2019-05-09 18:54:39 +12:00
$layout
2019-09-27 06:47:48 +12:00
-> setParam ( 'title' , 'Sign In - ' . APP_NAME )
2019-05-09 18:54:39 +12:00
-> setParam ( 'body' , $page );
});
$utopia -> get ( '/auth/signup' )
-> desc ( 'Registration page' )
-> label ( 'permission' , 'public' )
-> label ( 'scope' , 'home' )
2019-09-07 05:10:41 +12:00
-> action ( function () use ( $layout ) {
2019-12-17 08:35:33 +13:00
$page = new View ( __DIR__ . '/../../views/home/auth/signup.phtml' );
2019-05-09 18:54:39 +12:00
$layout
2019-09-27 06:47:48 +12:00
-> setParam ( 'title' , 'Sign Up - ' . APP_NAME )
2019-05-09 18:54:39 +12:00
-> setParam ( 'body' , $page );
});
$utopia -> get ( '/auth/recovery' )
-> desc ( 'Password recovery page' )
-> label ( 'permission' , 'public' )
-> label ( 'scope' , 'home' )
2019-09-07 05:10:41 +12:00
-> action ( function () use ( $request , $layout ) {
2019-12-17 08:35:33 +13:00
$page = new View ( __DIR__ . '/../../views/home/auth/recovery.phtml' );
2019-05-09 18:54:39 +12:00
$layout
2019-09-27 06:47:48 +12:00
-> setParam ( 'title' , 'Password Recovery - ' . APP_NAME )
2019-05-09 18:54:39 +12:00
-> setParam ( 'body' , $page );
});
$utopia -> get ( '/auth/confirm' )
-> desc ( 'Account confirmation page' )
-> label ( 'permission' , 'public' )
-> label ( 'scope' , 'home' )
2019-09-07 05:10:41 +12:00
-> action ( function () use ( $layout ) {
2019-12-17 08:35:33 +13:00
$page = new View ( __DIR__ . '/../../views/home/auth/confirm.phtml' );
2019-05-09 18:54:39 +12:00
$layout
2019-09-27 06:47:48 +12:00
-> setParam ( 'title' , 'Account Confirmation - ' . APP_NAME )
2019-05-09 18:54:39 +12:00
-> setParam ( 'body' , $page );
});
$utopia -> get ( '/auth/join' )
-> desc ( 'Account team join page' )
-> label ( 'permission' , 'public' )
-> label ( 'scope' , 'home' )
2019-09-07 05:10:41 +12:00
-> action ( function () use ( $layout ) {
2019-12-17 08:35:33 +13:00
$page = new View ( __DIR__ . '/../../views/home/auth/join.phtml' );
2019-05-09 18:54:39 +12:00
$layout
2019-09-27 06:47:48 +12:00
-> setParam ( 'title' , 'Invitation - ' . APP_NAME )
2019-05-09 18:54:39 +12:00
-> setParam ( 'body' , $page );
});
$utopia -> get ( '/auth/recovery/reset' )
-> desc ( 'Password recovery page' )
-> label ( 'permission' , 'public' )
-> label ( 'scope' , 'home' )
2019-09-07 05:10:41 +12:00
-> action ( function () use ( $layout ) {
2019-12-17 08:35:33 +13:00
$page = new View ( __DIR__ . '/../../views/home/auth/recovery/reset.phtml' );
2019-05-09 18:54:39 +12:00
$layout
2019-09-27 06:47:48 +12:00
-> setParam ( 'title' , 'Password Reset - ' . APP_NAME )
2019-05-09 18:54:39 +12:00
-> setParam ( 'body' , $page );
});
2020-04-08 23:00:50 +12:00
2020-04-09 01:14:52 +12:00
$utopia -> get ( '/auth/oauth2/success' )
2020-04-08 23:00:50 +12:00
-> desc ( 'Registration page' )
-> label ( 'permission' , 'public' )
-> label ( 'scope' , 'home' )
-> action ( function () use ( $layout ) {
2020-04-09 01:14:52 +12:00
$page = new View ( __DIR__ . '/../../views/home/auth/oauth2.phtml' );
2020-04-08 23:00:50 +12:00
$layout
-> setParam ( 'title' , APP_NAME )
-> setParam ( 'body' , $page )
-> setParam ( 'header' , [])
-> setParam ( 'footer' , [])
;
});
2020-04-09 01:14:52 +12:00
$utopia -> get ( '/auth/oauth2/failure' )
2020-04-08 23:00:50 +12:00
-> desc ( 'Registration page' )
-> label ( 'permission' , 'public' )
-> label ( 'scope' , 'home' )
-> action ( function () use ( $layout ) {
2020-04-09 01:14:52 +12:00
$page = new View ( __DIR__ . '/../../views/home/auth/oauth2.phtml' );
2020-04-08 23:00:50 +12:00
$layout
-> setParam ( 'title' , APP_NAME )
-> setParam ( 'body' , $page )
-> setParam ( 'header' , [])
-> setParam ( 'footer' , [])
;
});
2019-05-09 18:54:39 +12:00
$utopia -> get ( '/error/:code' )
-> desc ( 'Error page' )
-> label ( 'permission' , 'public' )
-> label ( 'scope' , 'home' )
-> param ( 'code' , null , new \Utopia\Validator\Numeric (), 'Valid status code number' , false )
2019-09-07 05:10:41 +12:00
-> action ( function ( $code ) use ( $layout ) {
2019-12-17 08:35:33 +13:00
$page = new View ( __DIR__ . '/../../views/error.phtml' );
2019-05-09 18:54:39 +12:00
$page
-> setParam ( 'code' , $code )
;
$layout
2019-09-07 05:10:41 +12:00
-> setParam ( 'title' , 'Error' . ' - ' . APP_NAME )
2019-05-09 18:54:39 +12:00
-> setParam ( 'body' , $page );
2019-09-07 05:10:41 +12:00
});
2020-05-17 17:27:10 +12:00
$utopia -> get ( '/open-api-2.json' )
-> label ( 'scope' , 'public' )
-> label ( 'docs' , false )
-> param ( 'platform' , APP_PLATFORM_CLIENT , function () { return new WhiteList ([ APP_PLATFORM_CLIENT , APP_PLATFORM_SERVER , APP_PLATFORM_CONSOLE ]);}, 'Choose target platform.' , true )
-> param ( 'extensions' , 0 , function () { return new Range ( 0 , 1 );}, 'Show extra data.' , true )
-> param ( 'tests' , 0 , function () { return new Range ( 0 , 1 );}, 'Include only test services.' , true )
-> action (
function ( $platform , $extensions , $tests ) use ( $response , $request , $utopia , $services ) {
function fromCamelCase ( $input )
{
2020-06-20 23:20:49 +12:00
\preg_match_all ( '!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!' , $input , $matches );
2020-05-17 17:27:10 +12:00
$ret = $matches [ 0 ];
foreach ( $ret as & $match ) {
2020-06-20 23:20:49 +12:00
$match = $match == \strtoupper ( $match ) ? \strtolower ( $match ) : \lcfirst ( $match );
2020-05-17 17:27:10 +12:00
}
2020-06-20 23:20:49 +12:00
return \implode ( '_' , $ret );
2020-05-17 17:27:10 +12:00
}
function fromCamelCaseToDash ( $input )
{
2020-06-20 23:20:49 +12:00
return \str_replace ([ ' ' , '_' ], '-' , \strtolower ( \preg_replace ( '/([a-zA-Z])(?=[A-Z])/' , '$1-' , $input )));
2020-05-17 17:27:10 +12:00
}
foreach ( $services as $service ) { /* @noinspection PhpIncludeInspection */
if ( $tests && ! isset ( $service [ 'tests' ])) {
continue ;
}
if ( $tests && ! $service [ 'tests' ]) {
continue ;
}
if ( ! $tests && ! $service [ 'sdk' ]) {
continue ;
}
/** @noinspection PhpIncludeInspection */
2020-06-20 23:20:49 +12:00
include_once \realpath ( __DIR__ . '/../../' . $service [ 'controller' ]);
2020-05-17 17:27:10 +12:00
}
$security = [
APP_PLATFORM_CLIENT => [ 'Project' => []],
APP_PLATFORM_SERVER => [ 'Project' => [], 'Key' => []],
APP_PLATFORM_CONSOLE => [ 'Project' => [], 'Key' => []],
];
$platforms = [
'client' => APP_PLATFORM_CLIENT ,
'server' => APP_PLATFORM_SERVER ,
'all' => APP_PLATFORM_CONSOLE ,
];
$keys = [
APP_PLATFORM_CLIENT => [
'Project' => [
'type' => 'apiKey' ,
'name' => 'X-Appwrite-Project' ,
'description' => 'Your project ID' ,
'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' ,
],
'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' ,
],
'Locale' => [
'type' => 'apiKey' ,
'name' => 'X-Appwrite-Locale' ,
'description' => '' ,
'in' => 'header' ,
],
'Mode' => [
'type' => 'apiKey' ,
'name' => 'X-Appwrite-Mode' ,
'description' => '' ,
'in' => 'header' ,
],
],
];
/*
* Specifications ( v3 . 0.0 ) :
* https :// github . com / OAI / OpenAPI - Specification / blob / master / versions / 3.0 . 0. md
*/
$output = [
'swagger' => '2.0' ,
'info' => [
'version' => APP_VERSION_STABLE ,
'title' => APP_NAME ,
'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)' ,
'termsOfService' => 'https://appwrite.io/policy/terms' ,
'contact' => [
'name' => 'Appwrite Team' ,
'url' => 'https://appwrite.io/support' ,
'email' => $request -> getServer ( '_APP_SYSTEM_EMAIL_ADDRESS' , APP_EMAIL_TEAM ),
],
'license' => [
'name' => 'BSD-3-Clause' ,
'url' => 'https://raw.githubusercontent.com/appwrite/appwrite/master/LICENSE' ,
],
],
2020-06-20 23:20:49 +12:00
'host' => \parse_url ( $request -> getServer ( '_APP_HOME' , Config :: getParam ( 'domain' )), PHP_URL_HOST ),
2020-05-17 17:27:10 +12:00
'basePath' => '/v1' ,
'schemes' => [ 'https' ],
'consumes' => [ 'application/json' , 'multipart/form-data' ],
'produces' => [ 'application/json' ],
'securityDefinitions' => $keys [ $platform ],
'paths' => [],
'definitions' => [
// 'Pet' => [
// 'required' => ['id', 'name'],
// 'properties' => [
// 'id' => [
// 'type' => 'integer',
// 'format' => 'int64',
// ],
// 'name' => [
// 'type' => 'string',
// ],
// 'tag' => [
// 'type' => 'string',
// ],
// ],
// ],
// 'Pets' => array(
// 'type' => 'array',
// 'items' => array(
// '$ref' => '#/definitions/Pet',
// ),
// ),
'Error' => array (
'required' => array (
0 => 'code' ,
1 => 'message' ,
),
'properties' => array (
'code' => array (
'type' => 'integer' ,
'format' => 'int32' ,
),
'message' => array (
'type' => 'string' ,
),
),
),
],
'externalDocs' => [
'description' => 'Full API docs, specs and tutorials' ,
'url' => Config :: getParam ( 'protocol' ) . '://' . Config :: getParam ( 'domain' ) . '/docs' ,
],
];
if ( $extensions ) {
if ( isset ( $output [ 'securityDefinitions' ][ 'Project' ])) {
$output [ 'securityDefinitions' ][ 'Project' ][ 'extensions' ] = [ 'demo' => '5df5acd0d48c2' ];
}
if ( isset ( $output [ 'securityDefinitions' ][ 'Key' ])) {
$output [ 'securityDefinitions' ][ 'Key' ][ 'extensions' ] = [ 'demo' => '919c2d18fb5d4...a2ae413da83346ad2' ];
}
if ( isset ( $output [ 'securityDefinitions' ][ 'Locale' ])) {
$output [ 'securityDefinitions' ][ 'Locale' ][ 'extensions' ] = [ 'demo' => 'en' ];
}
if ( isset ( $output [ 'securityDefinitions' ][ 'Mode' ])) {
$output [ 'securityDefinitions' ][ 'Mode' ][ 'extensions' ] = [ 'demo' => '' ];
}
}
foreach ( $utopia -> getRoutes () as $key => $method ) {
foreach ( $method as $route ) { /* @var $route \Utopia\Route */
if ( ! $route -> getLabel ( 'docs' , true )) {
continue ;
}
if ( empty ( $route -> getLabel ( 'sdk.namespace' , null ))) {
continue ;
}
2020-06-20 23:20:49 +12:00
if ( $platform !== APP_PLATFORM_CONSOLE && ! \in_array ( $platforms [ $platform ], $route -> getLabel ( 'sdk.platform' , []))) {
2020-05-17 17:27:10 +12:00
continue ;
}
2020-06-20 23:20:49 +12:00
$url = \str_replace ( '/v1' , '' , $route -> getURL ());
2020-05-17 17:27:10 +12:00
$scope = $route -> getLabel ( 'scope' , '' );
$hide = $route -> getLabel ( 'sdk.hide' , false );
$consumes = [ 'application/json' ];
if ( $hide ) {
continue ;
}
2020-06-20 23:20:49 +12:00
$desc = ( ! empty ( $route -> getLabel ( 'sdk.description' , '' ))) ? \realpath ( '../' . $route -> getLabel ( 'sdk.description' , '' )) : null ;
2020-05-17 17:27:10 +12:00
$temp = [
'summary' => $route -> getDesc (),
2020-06-20 23:20:49 +12:00
'operationId' => $route -> getLabel ( 'sdk.method' , \uniqid ()),
2020-05-17 17:27:10 +12:00
'consumes' => [],
'tags' => [ $route -> getLabel ( 'sdk.namespace' , 'default' )],
2020-06-20 23:20:49 +12:00
'description' => ( $desc ) ? \file_get_contents ( $desc ) : '' ,
2020-05-17 17:27:10 +12:00
// 'responses' => [
// 200 => [
// 'description' => 'An paged array of pets',
// 'schema' => [
// '$ref' => '#/definitions/Pet',
// ],
// ],
// ],
];
if ( $extensions ) {
$platformList = $route -> getLabel ( 'sdk.platform' , []);
$temp [ 'extensions' ] = [
'weight' => $route -> getOrder (),
'cookies' => $route -> getLabel ( 'sdk.cookies' , false ),
'type' => $route -> getLabel ( 'sdk.methodType' , '' ),
'demo' => 'docs/examples/' . fromCamelCaseToDash ( $route -> getLabel ( 'sdk.namespace' , 'default' )) . '/' . fromCamelCaseToDash ( $temp [ 'operationId' ]) . '.md' ,
'edit' => 'https://github.com/appwrite/appwrite/edit/master' . $route -> getLabel ( 'sdk.description' , '' ),
'rate-limit' => $route -> getLabel ( 'abuse-limit' , 0 ),
'rate-time' => $route -> getLabel ( 'abuse-time' , 3600 ),
2020-06-06 18:35:06 +12:00
'rate-key' => $route -> getLabel ( 'abuse-key' , 'url:{url},ip:{ip}' ),
2020-05-17 17:27:10 +12:00
'scope' => $route -> getLabel ( 'scope' , '' ),
'platforms' => $platformList ,
];
}
if (( ! empty ( $scope ))) { // && 'public' != $scope
$temp [ 'security' ][] = $route -> getLabel ( 'sdk.security' , $security [ $platform ]);
}
$requestBody = [
'content' => [
'application/x-www-form-urlencoded' => [
'schema' => [
'type' => 'object' ,
'properties' => [],
],
'required' => [],
],
],
];
foreach ( $route -> getParams () as $name => $param ) {
2020-06-20 23:20:49 +12:00
$validator = ( \is_callable ( $param [ 'validator' ])) ? $param [ 'validator' ]() : $param [ 'validator' ]; /* @var $validator \Utopia\Validator */
2020-05-17 17:27:10 +12:00
$node = [
'name' => $name ,
'description' => $param [ 'description' ],
'required' => ! $param [ 'optional' ],
];
2020-06-20 23:20:49 +12:00
switch (( ! empty ( $validator )) ? \get_class ( $validator ) : '' ) {
2020-05-17 17:27:10 +12:00
case 'Utopia\Validator\Text' :
$node [ 'type' ] = 'string' ;
2020-06-20 23:20:49 +12:00
$node [ 'x-example' ] = '[' . \strtoupper ( fromCamelCase ( $node [ 'name' ])) . ']' ;
2020-05-17 17:27:10 +12:00
break ;
case 'Appwrite\Database\Validator\UID' :
$node [ 'type' ] = 'string' ;
2020-06-20 23:20:49 +12:00
$node [ 'x-example' ] = '[' . \strtoupper ( fromCamelCase ( $node [ 'name' ])) . ']' ;
2020-05-17 17:27:10 +12:00
break ;
case 'Utopia\Validator\Email' :
$node [ 'type' ] = 'string' ;
$node [ 'format' ] = 'email' ;
$node [ 'x-example' ] = 'email@example.com' ;
break ;
case 'Utopia\Validator\URL' :
$node [ 'type' ] = 'string' ;
$node [ 'format' ] = 'url' ;
$node [ 'x-example' ] = 'https://example.com' ;
break ;
case 'Utopia\Validator\JSON' :
case 'Utopia\Validator\Mock' :
case 'Utopia\Validator\Assoc' :
$node [ 'type' ] = 'object' ;
$node [ 'type' ] = 'object' ;
$node [ 'x-example' ] = '{}' ;
//$node['format'] = 'json';
break ;
2020-06-12 07:36:10 +12:00
case 'Appwrite\Storage\Validator\File' :
2020-05-17 17:27:10 +12:00
$consumes = [ 'multipart/form-data' ];
$node [ 'type' ] = 'file' ;
break ;
case 'Utopia\Validator\ArrayList' :
$node [ 'type' ] = 'array' ;
$node [ 'collectionFormat' ] = 'multi' ;
$node [ 'items' ] = [
'type' => 'string' ,
];
break ;
case 'Appwrite\Auth\Validator\Password' :
$node [ 'type' ] = 'string' ;
$node [ 'format' ] = 'format' ;
$node [ 'x-example' ] = 'password' ;
break ;
case 'Utopia\Validator\Range' : /* @var $validator \Utopia\Validator\Range */
$node [ 'type' ] = 'integer' ;
$node [ 'format' ] = 'int32' ;
$node [ 'x-example' ] = $validator -> getMin ();
break ;
case 'Utopia\Validator\Numeric' :
$node [ 'type' ] = 'integer' ;
$node [ 'format' ] = 'int32' ;
break ;
case 'Utopia\Validator\Length' :
$node [ 'type' ] = 'string' ;
break ;
case 'Utopia\Validator\Host' :
$node [ 'type' ] = 'string' ;
$node [ 'format' ] = 'url' ;
$node [ 'x-example' ] = 'https://example.com' ;
break ;
case 'Utopia\Validator\WhiteList' : /* @var $validator \Utopia\Validator\WhiteList */
$node [ 'type' ] = 'string' ;
$node [ 'x-example' ] = $validator -> getList ()[ 0 ];
break ;
default :
$node [ 'type' ] = 'string' ;
break ;
}
2020-06-20 23:20:49 +12:00
if ( $param [ 'optional' ] && ! \is_null ( $param [ 'default' ])) { // Param has default value
2020-05-17 17:27:10 +12:00
$node [ 'default' ] = $param [ 'default' ];
}
2020-06-20 23:20:49 +12:00
if ( false !== \strpos ( $url , ':' . $name )) { // Param is in URL path
2020-05-17 17:27:10 +12:00
$node [ 'in' ] = 'path' ;
$temp [ 'parameters' ][] = $node ;
} elseif ( $key == 'GET' ) { // Param is in query
$node [ 'in' ] = 'query' ;
$temp [ 'parameters' ][] = $node ;
} else { // Param is in payload
$node [ 'in' ] = 'formData' ;
$temp [ 'parameters' ][] = $node ;
$requestBody [ 'content' ][ 'application/x-www-form-urlencoded' ][ 'schema' ][ 'properties' ][] = $node ;
if ( ! $param [ 'optional' ]) {
$requestBody [ 'content' ][ 'application/x-www-form-urlencoded' ][ 'required' ][] = $name ;
}
}
2020-06-20 23:20:49 +12:00
$url = \str_replace ( ':' . $name , '{' . $name . '}' , $url );
2020-05-17 17:27:10 +12:00
}
$temp [ 'consumes' ] = $consumes ;
2020-06-20 23:20:49 +12:00
$output [ 'paths' ][ $url ][ \strtolower ( $route -> getMethod ())] = $temp ;
2020-05-17 17:27:10 +12:00
}
}
/* foreach ( $consoleDB -> getMocks () as $mock ) {
var_dump ( $mock [ 'name' ]);
} */
2020-06-20 23:20:49 +12:00
\ksort ( $output [ 'paths' ]);
2020-05-17 17:27:10 +12:00
$response
-> json ( $output );
}
);