Merge pull request #2684 from appwrite/feat-rename-tags

Feat rename tags to deployments
This commit is contained in:
Eldad A. Fux 2022-01-26 11:37:25 +02:00 committed by GitHub
commit 4147faafdc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
46 changed files with 717 additions and 707 deletions

View file

@ -3,6 +3,12 @@
- Introduced new execution model for functions
- Improved functions execution times
- Improved functions execution times
- **[ Breaking ]** **Tags** have been renamed to **Deployments**
- Rename `tagId` to `deplyomentId` in collections
- Rename tags to deployments in the docs
- Updated endpoints to reflect the new terminology
- Updated UI with these changes
- Updated event names from `function.tags.*` to `function.deployments.*`
# Version 0.12.1
## Bugs

View file

@ -1322,8 +1322,8 @@ $collections = [
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Tag',
'key' => 'tag',
'label' => 'Deployment',
'key' => 'deployment',
'type' => Database::SYSTEM_VAR_TYPE_KEY,
'default' => '',
'required' => false,
@ -1386,11 +1386,11 @@ $collections = [
],
],
],
Database::SYSTEM_COLLECTION_TAGS => [
Database::SYSTEM_COLLECTION_DEPLOYMENTS => [
'$collection' => Database::SYSTEM_COLLECTION_COLLECTIONS,
'$id' => Database::SYSTEM_COLLECTION_TAGS,
'$id' => Database::SYSTEM_COLLECTION_DEPLOYMENTS,
'$permissions' => ['read' => ['role:all']],
'name' => 'Tags',
'name' => 'Deployments',
'structure' => true,
'rules' => [
[
@ -1467,8 +1467,8 @@ $collections = [
],
[
'$collection' => Database::SYSTEM_COLLECTION_RULES,
'label' => 'Tag ID',
'key' => 'tagId',
'label' => 'Deployment ID',
'key' => 'deploymentId',
'type' => Database::SYSTEM_VAR_TYPE_KEY,
'default' => '',
'required' => false,

View file

@ -1799,7 +1799,7 @@ $collections = [
'filters' => [],
],
[
'$id' => 'tag',
'$id' => 'deployment',
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
@ -1898,10 +1898,10 @@ $collections = [
],
],
'tags' => [
'deployments' => [
'$collection' => Database::METADATA,
'$id' => 'tags',
'name' => 'Tags',
'$id' => 'deployments',
'name' => 'Deployments',
'attributes' => [
[
'$id' => 'dateCreated',
@ -2217,7 +2217,7 @@ $collections = [
'filters' => [],
],
[
'$id' => 'tagId',
'$id' => 'deploymentId',
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,

View file

@ -147,18 +147,18 @@ return [
'model' => Response::MODEL_ANY,
'note' => 'version >= 0.7',
],
'functions.tags.create' => [
'description' => 'This event triggers when a function tag is created.',
'model' => Response::MODEL_TAG,
'functions.deployments.create' => [
'description' => 'This event triggers when a function delpoyment is created.',
'model' => Response::MODEL_DEPLOYMENT,
'note' => 'version >= 0.7',
],
'functions.tags.update' => [
'description' => 'This event triggers when a function tag is updated.',
'functions.deployments.update' => [
'description' => 'This event triggers when a function delpoyment is updated.',
'model' => Response::MODEL_FUNCTION,
'note' => 'version >= 0.7',
],
'functions.tags.delete' => [
'description' => 'This event triggers when a function tag is deleted.',
'functions.deployments.delete' => [
'description' => 'This event triggers when a function delpoyment is deleted.',
'model' => Response::MODEL_ANY,
'note' => 'version >= 0.7',
],

View file

@ -44,10 +44,10 @@ return [ // List of publicly visible scopes
'description' => 'Access to create, update, and delete your project\'s storage files',
],
'functions.read' => [
'description' => 'Access to read your project\'s functions and code tags',
'description' => 'Access to read your project\'s functions and code deployments',
],
'functions.write' => [
'description' => 'Access to create, update, and delete your project\'s functions and code tags',
'description' => 'Access to create, update, and delete your project\'s functions and code deployments',
],
'execution.read' => [
'description' => 'Access to read your project\'s execution logs',

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -64,7 +64,7 @@ App::post('/v1/functions')
'status' => 'disabled',
'name' => $name,
'runtime' => $runtime,
'tag' => '',
'deployment' => '',
'vars' => $vars,
'events' => $events,
'schedule' => $schedule,
@ -314,8 +314,8 @@ App::put('/v1/functions/:functionId')
}
$original = $function->getAttribute('schedule', '');
$cron = (!empty($function->getAttribute('tag', null)) && !empty($schedule)) ? new CronExpression($schedule) : null;
$next = (!empty($function->getAttribute('tag', null)) && !empty($schedule)) ? $cron->getNextRunDate()->format('U') : 0;
$cron = (!empty($function->getAttribute('deployment', null)) && !empty($schedule)) ? new CronExpression($schedule) : null;
$next = (!empty($function->getAttribute('deployment', null)) && !empty($schedule)) ? $cron->getNextRunDate()->format('U') : 0;
$function = $dbForProject->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [
'execute' => $execute,
@ -343,38 +343,38 @@ App::put('/v1/functions/:functionId')
$response->dynamic($function, Response::MODEL_FUNCTION);
});
App::patch('/v1/functions/:functionId/tag')
App::patch('/v1/functions/:functionId/deployment')
->groups(['api', 'functions'])
->desc('Update Function Tag')
->desc('Update Function Deployment')
->label('scope', 'functions.write')
->label('event', 'functions.tags.update')
->label('event', 'functions.deployments.update')
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'functions')
->label('sdk.method', 'updateTag')
->label('sdk.description', '/docs/references/functions/update-function-tag.md')
->label('sdk.method', 'updateDeployment')
->label('sdk.description', '/docs/references/functions/update-function-deployment.md')
->label('sdk.response.code', Response::STATUS_CODE_OK)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_FUNCTION)
->param('functionId', '', new UID(), 'Function ID.')
->param('tag', '', new UID(), 'Tag ID.')
->param('deployment', '', new UID(), 'Deployment ID.')
->inject('response')
->inject('dbForProject')
->inject('project')
->action(function ($functionId, $tag, $response, $dbForProject, $project) {
->action(function ($functionId, $deployment, $response, $dbForProject, $project) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForProject */
/** @var Utopia\Database\Document $project */
$function = $dbForProject->getDocument('functions', $functionId);
$tag = $dbForProject->getDocument('tags', $tag);
$build = $dbForProject->getDocument('builds', $tag->getAttribute('buildId'));
$deployment = $dbForProject->getDocument('deployments', $deployment);
$build = $dbForProject->getDocument('builds', $deployment->getAttribute('buildId'));
if ($function->isEmpty()) {
throw new Exception('Function not found', 404);
}
if ($tag->isEmpty()) {
throw new Exception('Tag not found', 404);
if ($deployment->isEmpty()) {
throw new Exception('Deployment not found', 404);
}
if ($build->isEmpty()) {
@ -386,11 +386,11 @@ App::patch('/v1/functions/:functionId/tag')
}
$schedule = $function->getAttribute('schedule', '');
$cron = (empty($function->getAttribute('tag')) && !empty($schedule)) ? new CronExpression($schedule) : null;
$next = (empty($function->getAttribute('tag')) && !empty($schedule)) ? $cron->getNextRunDate()->format('U') : 0;
$cron = (empty($function->getAttribute('deployment')) && !empty($schedule)) ? new CronExpression($schedule) : null;
$next = (empty($function->getAttribute('deployment')) && !empty($schedule)) ? $cron->getNextRunDate()->format('U') : 0;
$function = $dbForProject->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [
'tag' => $tag->getId(),
'deployment' => $deployment->getId(),
'scheduleNext' => (int)$next,
])));
@ -431,7 +431,7 @@ App::delete('/v1/functions/:functionId')
$function = $dbForProject->getDocument('functions', $functionId);
// Request executor to delete tag containers
// Request executor to delete deployment containers
$ch = \curl_init();
\curl_setopt($ch, CURLOPT_URL, "http://appwrite-executor/v1/cleanup/function");
\curl_setopt($ch, CURLOPT_POST, true);
@ -479,20 +479,20 @@ App::delete('/v1/functions/:functionId')
$response->noContent();
});
App::post('/v1/functions/:functionId/tags')
App::post('/v1/functions/:functionId/deployments')
->groups(['api', 'functions'])
->desc('Create Tag')
->desc('Create Deployment')
->label('scope', 'functions.write')
->label('event', 'functions.tags.create')
->label('event', 'functions.deployments.create')
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'functions')
->label('sdk.method', 'createTag')
->label('sdk.description', '/docs/references/functions/create-tag.md')
->label('sdk.method', 'createDeployment')
->label('sdk.description', '/docs/references/functions/create-deployment.md')
->label('sdk.packaging', true)
->label('sdk.request.type', 'multipart/form-data')
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_TAG)
->label('sdk.response.model', Response::MODEL_DEPLOYMENT)
->param('functionId', '', new UID(), 'Function ID.')
->param('entrypoint', '', new Text('1028'), 'Entrypoint File.')
->param('code', [], new File(), 'Gzip file with your code package. When used with the Appwrite CLI, pass the path to your code directory, and the CLI will automatically package your code. Use a path that is within the current directory.', false)
@ -553,21 +553,21 @@ App::post('/v1/functions/:functionId/tags')
}
if ((bool) $deploy) {
// Remove deploy for all other tags.
$tags = $dbForProject->find('tags', [
// Remove deploy for all other deployments.
$deployments = $dbForProject->find('deployments', [
new Query('deploy', Query::TYPE_EQUAL, [true]),
new Query('functionId', Query::TYPE_EQUAL, [$functionId])
]);
foreach ($tags as $tag) {
$tag->setAttribute('deploy', false);
$dbForProject->updateDocument('tags', $tag->getId(), $tag);
foreach ($deployments as $deployment) {
$deployment->setAttribute('deploy', false);
$dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
}
}
$tagId = $dbForProject->getId();
$tag = $dbForProject->createDocument('tags', new Document([
'$id' => $tagId,
$deploymentId = $dbForProject->getId();
$deployment = $dbForProject->createDocument('deployments', new Document([
'$id' => $deploymentId,
'$read' => ['role:all'],
'$write' => ['role:all'],
'functionId' => $function->getId(),
@ -575,7 +575,7 @@ App::post('/v1/functions/:functionId/tags')
'entrypoint' => $entrypoint,
'path' => $path,
'size' => $size,
'search' => implode(' ', [$tagId, $entrypoint]),
'search' => implode(' ', [$deploymentId, $entrypoint]),
'status' => 'processing',
'buildStdout' => '',
'buildStderr' => '',
@ -583,18 +583,18 @@ App::post('/v1/functions/:functionId/tags')
]));
$usage
->setParam('storage', $tag->getAttribute('size', 0))
->setParam('storage', $deployment->getAttribute('size', 0))
;
// Send start build reqeust to executor using /v1/tag
// Send start build reqeust to executor using /v1/deployment
$function = $dbForProject->getDocument('functions', $functionId);
$ch = \curl_init();
\curl_setopt($ch, CURLOPT_URL, "http://appwrite-executor/v1/tag");
\curl_setopt($ch, CURLOPT_URL, "http://appwrite-executor/v1/deployment");
\curl_setopt($ch, CURLOPT_POST, true);
\curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'functionId' => $function->getId(),
'tagId' => $tag->getId(),
'deploymentId' => $deployment->getId(),
'userId' => $user->getId(),
]));
\curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
@ -623,25 +623,25 @@ App::post('/v1/functions/:functionId/tags')
\curl_close($ch);
$response->setStatusCode(Response::STATUS_CODE_CREATED);
$response->dynamic($tag, Response::MODEL_TAG);
$response->dynamic($deployment, Response::MODEL_DEPLOYMENT);
});
App::get('/v1/functions/:functionId/tags')
App::get('/v1/functions/:functionId/deployments')
->groups(['api', 'functions'])
->desc('List Tags')
->desc('List Deployments')
->label('scope', 'functions.read')
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'functions')
->label('sdk.method', 'listTags')
->label('sdk.description', '/docs/references/functions/list-tags.md')
->label('sdk.method', 'listDeployments')
->label('sdk.description', '/docs/references/functions/list-deployments.md')
->label('sdk.response.code', Response::STATUS_CODE_OK)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_TAG_LIST)
->label('sdk.response.model', Response::MODEL_DEPLOYMENT_LIST)
->param('functionId', '', new UID(), 'Function ID.')
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->param('limit', 25, new Range(0, 100), 'Maximum number of tags to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
->param('limit', 25, new Range(0, 100), 'Maximum number of deployments to return in response. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true)
->param('offset', 0, new Range(0, APP_LIMIT_COUNT), 'Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
->param('cursor', '', new UID(), 'ID of the tag used as the starting point for the query, excluding the tag itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
->param('cursor', '', new UID(), 'ID of the deployment used as the starting point for the query, excluding the deployment itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
->param('cursorDirection', Database::CURSOR_AFTER, new WhiteList([Database::CURSOR_AFTER, Database::CURSOR_BEFORE]), 'Direction of the cursor.', true)
->param('orderType', 'ASC', new WhiteList(['ASC', 'DESC'], true), 'Order result by ASC or DESC order.', true)
->inject('response')
@ -657,10 +657,10 @@ App::get('/v1/functions/:functionId/tags')
}
if (!empty($cursor)) {
$cursorTag = $dbForProject->getDocument('tags', $cursor);
$cursorDeployment = $dbForProject->getDocument('deployments', $cursor);
if ($cursorTag->isEmpty()) {
throw new Exception("Tag '{$cursor}' for the 'cursor' value not found.", 400);
if ($cursorDeployment->isEmpty()) {
throw new Exception("Deployment '{$cursor}' for the 'cursor' value not found.", 400);
}
}
@ -672,40 +672,40 @@ App::get('/v1/functions/:functionId/tags')
$queries[] = new Query('functionId', Query::TYPE_EQUAL, [$function->getId()]);
$results = $dbForProject->find('tags', $queries, $limit, $offset, [], [$orderType], $cursorTag ?? null, $cursorDirection);
$sum = $dbForProject->count('tags', $queries, APP_LIMIT_COUNT);
$results = $dbForProject->find('deployments', $queries, $limit, $offset, [], [$orderType], $cursorDeployment ?? null, $cursorDirection);
$sum = $dbForProject->count('deployments', $queries, APP_LIMIT_COUNT);
// Get Current Build Data
foreach ($results as &$tag) {
$build = $dbForProject->getDocument('builds', $tag->getAttribute('buildId', ''));
foreach ($results as &$deployment) {
$build = $dbForProject->getDocument('builds', $deployment->getAttribute('buildId', ''));
$tag['status'] = $build->getAttribute('status', 'processing');
$tag['buildStdout'] = $build->getAttribute('stdout', '');
$tag['buildStderr'] = $build->getAttribute('stderr', '');
$deployment['status'] = $build->getAttribute('status', 'processing');
$deployment['buildStdout'] = $build->getAttribute('stdout', '');
$deployment['buildStderr'] = $build->getAttribute('stderr', '');
}
$response->dynamic(new Document([
'tags' => $results,
'deployments' => $results,
'sum' => $sum,
]), Response::MODEL_TAG_LIST);
]), Response::MODEL_DEPLOYMENT_LIST);
});
App::get('/v1/functions/:functionId/tags/:tagId')
App::get('/v1/functions/:functionId/deployments/:deploymentId')
->groups(['api', 'functions'])
->desc('Get Tag')
->desc('Get Deployment')
->label('scope', 'functions.read')
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'functions')
->label('sdk.method', 'getTag')
->label('sdk.description', '/docs/references/functions/get-tag.md')
->label('sdk.method', 'getDeployment')
->label('sdk.description', '/docs/references/functions/get-deployment.md')
->label('sdk.response.code', Response::STATUS_CODE_OK)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_TAG)
->label('sdk.response.model', Response::MODEL_DEPLOYMENT_LIST)
->param('functionId', '', new UID(), 'Function ID.')
->param('tagId', '', new UID(), 'Tag ID.')
->param('deploymentId', '', new UID(), 'Deployment ID.')
->inject('response')
->inject('dbForProject')
->action(function ($functionId, $tagId, $response, $dbForProject) {
->action(function ($functionId, $deploymentId, $response, $dbForProject) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForProject */
@ -715,37 +715,37 @@ App::get('/v1/functions/:functionId/tags/:tagId')
throw new Exception('Function not found', 404);
}
$tag = $dbForProject->getDocument('tags', $tagId);
$deployment = $dbForProject->getDocument('deployments', $deploymentId);
if ($tag->getAttribute('functionId') !== $function->getId()) {
throw new Exception('Tag not found', 404);
if ($deployment->getAttribute('functionId') !== $function->getId()) {
throw new Exception('Deployment not found', 404);
}
if ($tag->isEmpty()) {
throw new Exception('Tag not found', 404);
if ($deployment->isEmpty()) {
throw new Exception('Deployment not found', 404);
}
$response->dynamic($tag, Response::MODEL_TAG);
$response->dynamic($deployment, Response::MODEL_DEPLOYMENT);
});
App::delete('/v1/functions/:functionId/tags/:tagId')
App::delete('/v1/functions/:functionId/deployments/:deploymentId')
->groups(['api', 'functions'])
->desc('Delete Tag')
->desc('Delete Deployment')
->label('scope', 'functions.write')
->label('event', 'functions.tags.delete')
->label('event', 'functions.deployments.delete')
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'functions')
->label('sdk.method', 'deleteTag')
->label('sdk.description', '/docs/references/functions/delete-tag.md')
->label('sdk.method', 'deleteDeployment')
->label('sdk.description', '/docs/references/functions/delete-deployment.md')
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
->label('sdk.response.model', Response::MODEL_NONE)
->param('functionId', '', new UID(), 'Function ID.')
->param('tagId', '', new UID(), 'Tag ID.')
->param('deploymentId', '', new UID(), 'Deployment ID.')
->inject('response')
->inject('dbForProject')
->inject('usage')
->inject('project')
->action(function ($functionId, $tagId, $response, $dbForProject, $usage, $project) {
->action(function ($functionId, $deploymentId, $response, $dbForProject, $usage, $project) {
/** @var Appwrite\Utopia\Response $response */
/** @var Utopia\Database\Database $dbForProject */
/** @var Appwrite\Event\Event $usage */
@ -757,22 +757,22 @@ App::delete('/v1/functions/:functionId/tags/:tagId')
throw new Exception('Function not found', 404);
}
$tag = $dbForProject->getDocument('tags', $tagId);
$deployment = $dbForProject->getDocument('deployments', $deploymentId);
if ($tag->getAttribute('functionId') !== $function->getId()) {
throw new Exception('Tag not found', 404);
if ($deployment->getAttribute('functionId') !== $function->getId()) {
throw new Exception('Deployment not found', 404);
}
if ($tag->isEmpty()) {
throw new Exception('Tag not found', 404);
if ($deployment->isEmpty()) {
throw new Exception('deployment not found', 404);
}
// Request executor to delete tag containers
// Request executor to delete deployment containers
$ch = \curl_init();
\curl_setopt($ch, CURLOPT_URL, "http://appwrite-executor/v1/cleanup/tag");
\curl_setopt($ch, CURLOPT_URL, "http://appwrite-executor/v1/cleanup/deployment");
\curl_setopt($ch, CURLOPT_POST, true);
\curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'tagId' => $tagId
'deploymentId' => $deploymentId
]));
\curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
\curl_setopt($ch, CURLOPT_TIMEOUT, 900);
@ -801,20 +801,20 @@ App::delete('/v1/functions/:functionId/tags/:tagId')
$device = Storage::getDevice('functions');
if ($device->delete($tag->getAttribute('path', ''))) {
if (!$dbForProject->deleteDocument('tags', $tag->getId())) {
throw new Exception('Failed to remove tag from DB', 500);
if ($device->delete($deployment->getAttribute('path', ''))) {
if (!$dbForProject->deleteDocument('deployments', $deployment->getId())) {
throw new Exception('Failed to remove deployment from DB', 500);
}
}
if($function->getAttribute('tag') === $tag->getId()) { // Reset function tag
if($function->getAttribute('deployment') === $deployment->getId()) { // Reset function deployment
$function = $dbForProject->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [
'tag' => '',
'deployment' => '',
])));
}
$usage
->setParam('storage', $tag->getAttribute('size', 0) * -1)
->setParam('storage', $deployment->getAttribute('size', 0) * -1)
;
$response->noContent();
@ -853,14 +853,14 @@ App::post('/v1/functions/:functionId/executions')
throw new Exception('Function not found', 404);
}
$tag = Authorization::skip(fn() => $dbForProject->getDocument('tags', $function->getAttribute('tag')));
$deployment = Authorization::skip(fn() => $dbForProject->getDocument('deployments', $function->getAttribute('deployment')));
if ($tag->getAttribute('functionId') !== $function->getId()) {
throw new Exception('Tag not found. Deploy tag before trying to execute a function', 404);
if ($deployment->getAttribute('functionId') !== $function->getId()) {
throw new Exception('Deployment not found. Deploy deployment before trying to execute a function', 404);
}
if ($tag->isEmpty()) {
throw new Exception('Tag not found. Deploy tag before trying to execute a function', 404);
if ($deployment->isEmpty()) {
throw new Exception('Deployment not found. Deploy deployment before trying to execute a function', 404);
}
$validator = new Authorization('execute');
@ -877,7 +877,7 @@ App::post('/v1/functions/:functionId/executions')
'$write' => ['role:all'],
'dateCreated' => time(),
'functionId' => $function->getId(),
'tagId' => $tag->getId(),
'deploymentId' => $deployment->getId(),
'trigger' => 'http', // http / schedule / event
'status' => 'waiting', // waiting / processing / completed / failed
'statusCode' => 0,
@ -1129,7 +1129,7 @@ App::post('/v1/builds/:buildId')
->groups(['api', 'functions'])
->desc('Retry Build')
->label('scope', 'functions.write')
->label('event', 'functions.tags.update')
->label('event', 'functions.deployments.update')
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
->label('sdk.namespace', 'functions')
->label('sdk.method', 'retryBuild')

View file

@ -153,7 +153,7 @@ try {
call_user_func($logError, $error, "startupError");
}
function createRuntimeServer(string $functionId, string $projectId, string $tagId, Database $database): void
function createRuntimeServer(string $functionId, string $projectId, string $deploymentId, Database $database): void
{
global $orchestrationPool;
global $runtimes;
@ -162,17 +162,17 @@ function createRuntimeServer(string $functionId, string $projectId, string $tagI
try {
$orchestration = $orchestrationPool->get();
$function = $database->getDocument('functions', $functionId);
$tag = $database->getDocument('tags', $tagId);
$deployment = $database->getDocument('deployments', $deploymentId);
if ($tag->getAttribute('buildId') === null) {
throw new Exception('Tag has no buildId');
if ($deployment->getAttribute('buildId') === null) {
throw new Exception('Deployment has no buildId');
}
// Grab Build Document
$build = $database->getDocument('builds', $tag->getAttribute('buildId'));
$build = $database->getDocument('builds', $deployment->getAttribute('buildId'));
// Check if function isn't already created
$functions = $orchestration->list(['label' => 'appwrite-type=function', 'name' => 'appwrite-function-' . $tag->getId()]);
$functions = $orchestration->list(['label' => 'appwrite-type=function', 'name' => 'appwrite-function-' . $deployment->getId()]);
if (\count($functions) > 0) {
return;
@ -184,8 +184,8 @@ function createRuntimeServer(string $functionId, string $projectId, string $tagI
// Check if runtime is active
$runtime = $runtimes[$function->getAttribute('runtime', '')] ?? null;
if ($tag->getAttribute('functionId') !== $function->getId()) {
throw new Exception('Tag not found', 404);
if ($deployment->getAttribute('functionId') !== $function->getId()) {
throw new Exception('deployment not found', 404);
}
if (\is_null($runtime)) {
@ -196,7 +196,7 @@ function createRuntimeServer(string $functionId, string $projectId, string $tagI
$vars = \array_merge($function->getAttribute('vars', []), [
'APPWRITE_FUNCTION_ID' => $function->getId(),
'APPWRITE_FUNCTION_NAME' => $function->getAttribute('name', ''),
'APPWRITE_FUNCTION_TAG' => $tag->getId(),
'APPWRITE_FUNCTION_DEPLOYMENT' => $deployment->getId(),
'APPWRITE_FUNCTION_RUNTIME_NAME' => $runtime['name'],
'APPWRITE_FUNCTION_RUNTIME_VERSION' => $runtime['version'],
'APPWRITE_FUNCTION_PROJECT_ID' => $projectId,
@ -205,7 +205,7 @@ function createRuntimeServer(string $functionId, string $projectId, string $tagI
$vars = \array_merge($vars, $build->getAttribute('vars', [])); // for gettng endpoint.
$container = 'appwrite-function-' . $tag->getId();
$container = 'appwrite-function-' . $deployment->getId();
if ($activeFunctions->exists($container) && !(\substr($activeFunctions->get($container)['status'], 0, 2) === 'Up')) { // Remove container if not online
// If container is online then stop and remove it
@ -222,41 +222,41 @@ function createRuntimeServer(string $functionId, string $projectId, string $tagI
$activeFunctions->del($container);
}
// Check if tag hasn't failed
// Check if deployment hasn't failed
if ($build->getAttribute('status') === 'failed') {
throw new Exception('Tag build failed, please check your logs.', 500);
throw new Exception('Deployment build failed, please check your logs.', 500);
}
// Check if tag is built yet.
// Check if deployment is built yet.
if ($build->getAttribute('status') !== 'ready') {
throw new Exception('Tag is not built yet', 500);
throw new Exception('Deployment is not built yet', 500);
}
// Grab Tag Files
$tagPath = $build->getAttribute('outputPath', '');
// Grab Deployment Files
$deploymentPath = $build->getAttribute('outputPath', '');
$tagPathTarget = '/tmp/project-' . $projectId . '/' . $build->getId() . '/builtCode/code.tar.gz';
$tagPathTargetDir = \pathinfo($tagPathTarget, PATHINFO_DIRNAME);
$container = 'appwrite-function-' . $tag->getId();
$deploymentPathTarget = '/tmp/project-' . $projectId . '/' . $build->getId() . '/builtCode/code.tar.gz';
$deploymentPathTargetDir = \pathinfo($deploymentPathTarget, PATHINFO_DIRNAME);
$container = 'appwrite-function-' . $deployment->getId();
$device = Storage::getDevice('builds');
if (!\file_exists($tagPathTargetDir)) {
if (@\mkdir($tagPathTargetDir, 0777, true)) {
\chmod($tagPathTargetDir, 0777);
if (!\file_exists($deploymentPathTargetDir)) {
if (@\mkdir($deploymentPathTargetDir, 0777, true)) {
\chmod($deploymentPathTargetDir, 0777);
} else {
throw new Exception('Can\'t create directory ' . $tagPathTargetDir);
throw new Exception('Can\'t create directory ' . $deploymentPathTargetDir);
}
}
if (!\file_exists($tagPathTarget)) {
if (!\file_exists($deploymentPathTarget)) {
if (App::getEnv('_APP_STORAGE_DEVICE', Storage::DEVICE_LOCAL) === Storage::DEVICE_LOCAL) {
if (!\copy($tagPath, $tagPathTarget)) {
throw new Exception('Can\'t create temporary code file ' . $tagPathTarget);
if (!\copy($deploymentPath, $deploymentPathTarget)) {
throw new Exception('Can\'t create temporary code file ' . $deploymentPathTarget);
}
} else {
$buffer = $device->read($tagPath);
\file_put_contents($tagPathTarget, $buffer);
$buffer = $device->read($deploymentPath);
\file_put_contents($deploymentPathTarget, $buffer);
}
};
@ -290,10 +290,10 @@ function createRuntimeServer(string $functionId, string $projectId, string $tagI
'appwrite-created' => strval($executionTime),
'appwrite-runtime' => $function->getAttribute('runtime', ''),
'appwrite-project' => $projectId,
'appwrite-tag' => $tag->getId(),
'appwrite-deployment' => $deployment->getId(),
],
hostname: $container,
mountFolder: $tagPathTargetDir,
mountFolder: $deploymentPathTargetDir,
);
if (empty($id)) {
@ -332,11 +332,11 @@ function execute(string $trigger, string $projectId, string $executionId, string
global $register;
$function = $database->getDocument('functions', $functionId);
$tag = $database->getDocument('tags', $function->getAttribute('tag', ''));
$build = $database->getDocument('builds', $tag->getAttribute('buildId', ''));
$deployment = $database->getDocument('deployments', $function->getAttribute('deployment', ''));
$build = $database->getDocument('builds', $deployment->getAttribute('buildId', ''));
if ($tag->getAttribute('functionId') !== $function->getId()) {
throw new Exception('Tag not found', 404);
if ($deployment->getAttribute('functionId') !== $function->getId()) {
throw new Exception('Deployment not found', 404);
}
// Grab execution document if exists
@ -349,7 +349,7 @@ function execute(string $trigger, string $projectId, string $executionId, string
'$write' => ['role:all'],
'dateCreated' => time(),
'functionId' => $function->getId(),
'tagId' => $tag->getId(),
'deploymentId' => $deployment->getId(),
'trigger' => $trigger, // http / schedule / event
'status' => 'processing', // waiting / processing / completed / failed
'statusCode' => 0,
@ -369,12 +369,12 @@ function execute(string $trigger, string $projectId, string $executionId, string
$execution
->setAttribute('status', 'failed')
->setAttribute('statusCode', 500)
->setAttribute('stderr', 'Tag is still being built.')
->setAttribute('stderr', 'Deployment is still being built.')
->setAttribute('time', 0);
$database->updateDocument('executions', $execution->getId(), $execution);
throw new Exception('Execution Failed. Reason: Tag is still being built.');
throw new Exception('Execution Failed. Reason: Deployment is still being built.');
}
// Check if runtime is active
@ -388,7 +388,7 @@ function execute(string $trigger, string $projectId, string $executionId, string
$vars = \array_merge($function->getAttribute('vars', []), [
'APPWRITE_FUNCTION_ID' => $function->getId(),
'APPWRITE_FUNCTION_NAME' => $function->getAttribute('name', ''),
'APPWRITE_FUNCTION_TAG' => $tag->getId(),
'APPWRITE_FUNCTION_DEPLOYMENT' => $deployment->getId(),
'APPWRITE_FUNCTION_TRIGGER' => $trigger,
'APPWRITE_FUNCTION_RUNTIME_NAME' => $runtime['name'],
'APPWRITE_FUNCTION_RUNTIME_VERSION' => $runtime['version'],
@ -402,7 +402,7 @@ function execute(string $trigger, string $projectId, string $executionId, string
$vars = \array_merge($vars, $build->getAttribute('vars', []));
$container = 'appwrite-function-' . $tag->getId();
$container = 'appwrite-function-' . $deployment->getId();
try {
if ($build->getAttribute('status') !== 'ready') {
@ -416,13 +416,13 @@ function execute(string $trigger, string $projectId, string $executionId, string
'status' => 'processing',
'outputPath' => '',
'runtime' => $function->getAttribute('runtime', ''),
'source' => $tag->getAttribute('path'),
'source' => $deployment->getAttribute('path'),
'sourceType' => Storage::DEVICE_LOCAL,
'stdout' => '',
'stderr' => '',
'time' => 0,
'vars' => [
'ENTRYPOINT_NAME' => $tag->getAttribute('entrypoint'),
'ENTRYPOINT_NAME' => $deployment->getAttribute('entrypoint'),
'APPWRITE_FUNCTION_ID' => $function->getId(),
'APPWRITE_FUNCTION_NAME' => $function->getAttribute('name', ''),
'APPWRITE_FUNCTION_RUNTIME_NAME' => $runtime['name'],
@ -431,9 +431,9 @@ function execute(string $trigger, string $projectId, string $executionId, string
]
]));
$tag->setAttribute('buildId', $buildId);
$deployment->setAttribute('buildId', $buildId);
$database->updateDocument('tags', $tag->getId(), $tag);
$database->updateDocument('deployments', $deployment->getId(), $deployment);
runBuildStage($buildId, $projectId);
}
@ -451,7 +451,7 @@ function execute(string $trigger, string $projectId, string $executionId, string
try {
if (!$activeFunctions->exists($container)) { // Create container if not ready
createRuntimeServer($functionId, $projectId, $tag->getId(), $database);
createRuntimeServer($functionId, $projectId, $deployment->getId(), $database);
} else if ($activeFunctions->get($container)['status'] === 'Down') {
sleep(1);
} else {
@ -478,13 +478,13 @@ function execute(string $trigger, string $projectId, string $executionId, string
];
}
$key = $activeFunctions->get('appwrite-function-' . $tag->getId(), 'key');
$key = $activeFunctions->get('appwrite-function-' . $deployment->getId(), 'key');
// Process environment variables
$vars = \array_merge($function->getAttribute('vars', []), [
'APPWRITE_FUNCTION_ID' => $function->getId(),
'APPWRITE_FUNCTION_NAME' => $function->getAttribute('name', ''),
'APPWRITE_FUNCTION_TAG' => $tag->getId(),
'APPWRITE_FUNCTION_DEPLOYMENT' => $deployment->getId(),
'APPWRITE_FUNCTION_TRIGGER' => $trigger,
'APPWRITE_FUNCTION_RUNTIME_NAME' => $runtime['name'],
'APPWRITE_FUNCTION_RUNTIME_VERSION' => $runtime['version'],
@ -602,7 +602,7 @@ function execute(string $trigger, string $projectId, string $executionId, string
Console::info('Function executed in ' . ($executionEnd - $executionStart) . ' seconds, status: ' . $functionStatus);
$execution->setAttribute('tagId', $tag->getId())
$execution->setAttribute('deploymentId', $deployment->getId())
->setAttribute('status', $functionStatus)
->setAttribute('statusCode', $statusCode)
->setAttribute('stdout', \utf8_encode(\mb_substr($stdout, -8000)))
@ -700,37 +700,37 @@ function runBuildStage(string $buildId, string $projectID): Document
}
// Grab Tag Files
$tagPath = $build->getAttribute('source', '');
$deploymentPath = $build->getAttribute('source', '');
$sourceType = $build->getAttribute('sourceType', '');
$device = Storage::getDevice('builds');
$tagPathTarget = '/tmp/project-' . $projectID . '/' . $build->getId() . '/code.tar.gz';
$tagPathTargetDir = \pathinfo($tagPathTarget, PATHINFO_DIRNAME);
$deploymentPathTarget = '/tmp/project-' . $projectID . '/' . $build->getId() . '/code.tar.gz';
$deploymentPathTargetDir = \pathinfo($deploymentPathTarget, PATHINFO_DIRNAME);
$container = 'build-stage-' . $build->getId();
// Perform various checks
if (!\file_exists($tagPathTargetDir)) {
if (@\mkdir($tagPathTargetDir, 0777, true)) {
\chmod($tagPathTargetDir, 0777);
if (!\file_exists($deploymentPathTargetDir)) {
if (@\mkdir($deploymentPathTargetDir, 0777, true)) {
\chmod($deploymentPathTargetDir, 0777);
} else {
throw new Exception('Can\'t create directory ' . $tagPathTargetDir);
throw new Exception('Can\'t create directory ' . $deploymentPathTargetDir);
}
}
if (!\file_exists($tagPathTarget)) {
if (!\file_exists($deploymentPathTarget)) {
if (App::getEnv('_APP_STORAGE_DEVICE', Storage::DEVICE_LOCAL) === Storage::DEVICE_LOCAL) {
if (!\copy($tagPath, $tagPathTarget)) {
throw new Exception('Can\'t create temporary code file ' . $tagPathTarget);
if (!\copy($deploymentPath, $deploymentPathTarget)) {
throw new Exception('Can\'t create temporary code file ' . $deploymentPathTarget);
}
} else {
$buffer = $device->read($tagPath);
\file_put_contents($tagPathTarget, $buffer);
$buffer = $device->read($deploymentPath);
\file_put_contents($deploymentPathTarget, $buffer);
}
}
if (!$device->exists($tagPath)) {
if (!$device->exists($deploymentPath)) {
throw new Exception('Code is not readable: ' . $build->getAttribute('source', ''));
}
@ -775,7 +775,7 @@ function runBuildStage(string $buildId, string $projectID): Document
'/dev/null'
],
hostname: $container,
mountFolder: $tagPathTargetDir,
mountFolder: $deploymentPathTargetDir,
volumes: [
'/tmp/project-' . $projectID . '/' . $build->getId() . '/builtCode' . ':/usr/builtCode:rw'
]
@ -944,7 +944,7 @@ App::post('/v1/execute') // Define Route
}
);
// Cleanup Endpoints used internally by appwrite when a function or tag gets deleted to also clean up their containers
// Cleanup Endpoints used internally by appwrite when a function or deployment gets deleted to also clean up their containers
App::post('/v1/cleanup/function')
->param('functionId', '', new UID())
->inject('response')
@ -963,29 +963,29 @@ App::post('/v1/cleanup/function')
throw new Exception('Function not found', 404);
}
$results = $dbForProject->find('tags', [new Query('functionId', Query::TYPE_EQUAL, [$functionId])], 999);
$results = $dbForProject->find('deployments', [new Query('functionId', Query::TYPE_EQUAL, [$functionId])], 999);
// If amount is 0 then we simply return true
if (count($results) === 0) {
return $response->json(['success' => true]);
}
// Delete the containers of all tags
foreach ($results as $tag) {
// Delete the containers of all deployments
foreach ($results as $deployment) {
try {
// Remove any ongoing builds
if ($tag->getAttribute('buildId')) {
$build = $dbForProject->getDocument('builds', $tag->getAttribute('buildId'));
if ($deployment->getAttribute('buildId')) {
$build = $dbForProject->getDocument('builds', $deployment->getAttribute('buildId'));
if ($build->getAttribute('status') === 'building') {
// Remove the build
$orchestration->remove('build-stage-' . $tag->getAttribute('buildId'), true);
Console::info('Removed build for tag ' . $tag['$id']);
$orchestration->remove('build-stage-' . $deployment->getAttribute('buildId'), true);
Console::info('Removed build for deployment ' . $deployment['$id']);
}
}
$orchestration->remove('appwrite-function-' . $tag['$id'], true);
Console::info('Removed container for tag ' . $tag['$id']);
$orchestration->remove('appwrite-function-' . $deployment['$id'], true);
Console::info('Removed container for deployment ' . $deployment['$id']);
} catch (Exception $e) {
// Do nothing, we don't care that much if it fails
}
@ -1002,38 +1002,38 @@ App::post('/v1/cleanup/function')
}
);
App::post('/v1/cleanup/tag')
->param('tagId', '', new UID(), 'Tag unique ID.')
App::post('/v1/cleanup/deployment')
->param('deploymentId', '', new UID(), 'Deployment unique ID.')
->inject('response')
->inject('dbForProject')
->action(function (string $tagId, Response $response, Database $dbForProject) use ($orchestrationPool) {
->action(function (string $deploymentId, Response $response, Database $dbForProject) use ($orchestrationPool) {
try {
/** @var Orchestration $orchestration */
$orchestration = $orchestrationPool->get();
// Get tag document
$tag = $dbForProject->getDocument('tags', $tagId);
// Get deployment document
$deployment = $dbForProject->getDocument('deployments', $deploymentId);
// Check if tag exists
if ($tag->isEmpty()) {
throw new Exception('Tag not found', 404);
// Check if deployment exists
if ($deployment->isEmpty()) {
throw new Exception('Deployment not found', 404);
}
try {
// Remove any ongoing builds
if ($tag->getAttribute('buildId')) {
$build = $dbForProject->getDocument('builds', $tag->getAttribute('buildId'));
if ($deployment->getAttribute('buildId')) {
$build = $dbForProject->getDocument('builds', $deployment->getAttribute('buildId'));
if ($build->getAttribute('status') == 'building') {
// Remove the build
$orchestration->remove('build-stage-' . $tag->getAttribute('buildId'), true);
Console::info('Removed build for tag ' . $tag['$id']);
$orchestration->remove('build-stage-' . $deployment->getAttribute('buildId'), true);
Console::info('Removed build for deployment ' . $deployment['$id']);
}
}
// Remove the container of the tag
$orchestration->remove('appwrite-function-' . $tag['$id'], true);
Console::info('Removed container for tag ' . $tag['$id']);
// Remove the container of the deployment
$orchestration->remove('appwrite-function-' . $deployment['$id'], true);
Console::info('Removed container for deployment ' . $deployment['$id']);
} catch (Exception $e) {
// Do nothing, we don't care that much if it fails
}
@ -1048,27 +1048,27 @@ App::post('/v1/cleanup/tag')
return $response->json(['success' => true]);
});
App::post('/v1/tag')
App::post('/v1/deployment')
->param('functionId', '', new UID(), 'Function unique ID.')
->param('tagId', '', new UID(), 'Tag unique ID.')
->param('deploymentId', '', new UID(), 'Deployment unique ID.')
->param('userId', '', new UID(), 'User unique ID.', true)
->inject('response')
->inject('dbForProject')
->inject('projectID')
->inject('register')
->action(function (string $functionId, string $tagId, string $userId, Response $response, Database $dbForProject, string $projectID, Registry $register) use ($runtimes) {
->action(function (string $functionId, string $deploymentId, string $userId, Response $response, Database $dbForProject, string $projectID, Registry $register) use ($runtimes) {
// Get function document
$function = $dbForProject->getDocument('functions', $functionId);
// Get tag document
$tag = $dbForProject->getDocument('tags', $tagId);
// Get deployment document
$deployment = $dbForProject->getDocument('deployments', $deploymentId);
// Check if both documents exist
if ($function->isEmpty()) {
throw new Exception('Function not found', 404);
}
if ($tag->isEmpty()) {
throw new Exception('Tag not found', 404);
if ($deployment->isEmpty()) {
throw new Exception('Deployment not found', 404);
}
$runtime = $runtimes[$function->getAttribute('runtime')] ?? null;
@ -1080,8 +1080,8 @@ App::post('/v1/tag')
// Create a new build entry
$buildId = $dbForProject->getId();
if ($tag->getAttribute('buildId')) {
$buildId = $tag->getAttribute('buildId');
if ($deployment->getAttribute('buildId')) {
$buildId = $deployment->getAttribute('buildId');
} else {
try {
$dbForProject->createDocument('builds', new Document([
@ -1092,13 +1092,13 @@ App::post('/v1/tag')
'status' => 'processing',
'runtime' => $function->getAttribute('runtime'),
'outputPath' => '',
'source' => $tag->getAttribute('path'),
'source' => $deployment->getAttribute('path'),
'sourceType' => Storage::DEVICE_LOCAL,
'stdout' => '',
'stderr' => '',
'time' => 0,
'vars' => [
'ENTRYPOINT_NAME' => $tag->getAttribute('entrypoint'),
'ENTRYPOINT_NAME' => $deployment->getAttribute('entrypoint'),
'APPWRITE_FUNCTION_ID' => $function->getId(),
'APPWRITE_FUNCTION_NAME' => $function->getAttribute('name', ''),
'APPWRITE_FUNCTION_RUNTIME_NAME' => $runtime['name'],
@ -1107,17 +1107,17 @@ App::post('/v1/tag')
]
]));
$tag->setAttribute('buildId', $buildId);
$deployment->setAttribute('buildId', $buildId);
$dbForProject->updateDocument('tags', $tag->getId(), $tag);
$dbForProject->updateDocument('deployments', $deployment->getId(), $deployment);
} catch (\Throwable $th) {
var_dump($tag->getArrayCopy());
var_dump($deployment->getArrayCopy());
throw $th;
}
}
// Build Code
go(function () use ($projectID, $tagId, $buildId, $functionId, $function, $register) {
go(function () use ($projectID, $deploymentId, $buildId, $functionId, $function, $register) {
try {
$db = $register->get('dbPool')->get();
$redis = $register->get('redisPool')->get();
@ -1131,11 +1131,11 @@ App::post('/v1/tag')
// Update the schedule
$schedule = $function->getAttribute('schedule', '');
$cron = (empty($function->getAttribute('tag')) && !empty($schedule)) ? new CronExpression($schedule) : null;
$next = (empty($function->getAttribute('tag')) && !empty($schedule)) ? $cron->getNextRunDate()->format('U') : 0;
$cron = (empty($function->getAttribute('deployment')) && !empty($schedule)) ? new CronExpression($schedule) : null;
$next = (empty($function->getAttribute('deployment')) && !empty($schedule)) ? $cron->getNextRunDate()->format('U') : 0;
// Grab tag
$tag = $dbForProject->getDocument('tags', $tagId);
// Grab deployment
$deployment = $dbForProject->getDocument('deployments', $deploymentId);
// Grab build
$build = $dbForProject->getDocument('builds', $buildId);
@ -1145,16 +1145,16 @@ App::post('/v1/tag')
return;
}
if ($tag->getAttribute('automaticDeploy') === true) {
// Update the function document setting the tag as the active one
if ($deployment->getAttribute('automaticDeploy') === true) {
// Update the function document setting the deployment as the active one
$function
->setAttribute('tag', $tag->getId())
->setAttribute('deployment', $deployment->getId())
->setAttribute('scheduleNext', (int)$next);
$function = $dbForProject->updateDocument('functions', $function->getId(), $function);
}
// Deploy Runtime Server
createRuntimeServer($functionId, $projectID, $tagId, $dbForProject);
createRuntimeServer($functionId, $projectID, $deploymentId, $dbForProject);
} catch (\Throwable $th) {
} finally {
$register->get('dbPool')->put($db);
@ -1258,7 +1258,7 @@ function handleShutdown()
// Get list of all processing executions
$executions = $database->find('executions', [
new Query('tagId', Query::TYPE_EQUAL, [$container->getLabels()["appwrite-tag"]]),
new Query('deploymentId', Query::TYPE_EQUAL, [$container->getLabels()["appwrite-deployment"]]),
new Query('status', Query::TYPE_EQUAL, ['waiting'])
]);

View file

@ -62,7 +62,7 @@ const APP_PAGING_LIMIT = 12;
const APP_LIMIT_COUNT = 5000;
const APP_LIMIT_USERS = 10000;
const APP_CACHE_BUSTER = 201;
const APP_VERSION_STABLE = '0.13.0';
const APP_VERSION_STABLE = '0.12.1';
const APP_DATABASE_ATTRIBUTE_EMAIL = 'email';
const APP_DATABASE_ATTRIBUTE_ENUM = 'enum';
const APP_DATABASE_ATTRIBUTE_IP = 'ip';

View file

@ -370,7 +370,7 @@ $cli
// Get total storage
$dbForProject->setNamespace('_project_' . $projectId);
$storageTotal = $dbForProject->sum('files', 'sizeOriginal') + $dbForProject->sum('tags', 'size');
$storageTotal = $dbForProject->sum('files', 'sizeOriginal') + $dbForProject->sum('deployments', 'size');
$time = (int) (floor(time() / 1800) * 1800); // Time rounded to nearest 30 minutes
$id = \md5($time . '_30m_storage.total'); //Construct unique id for each metric using time, period and metric

View file

@ -8,7 +8,7 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
<div
data-service="functions.get"
data-name="project-function"
data-event="load,functions.update,functions.createTag,functions.updateTag,functions.deleteTag,functions.retryBuild"
data-event="load,functions.update,functions.createDeployment,functions.updateDeployment,functions.deleteDeployment,functions.retryBuild"
data-param-function-id="{{router.params.id}}"
data-success="trigger"
data-success-param-trigger-events="functions.get">
@ -50,77 +50,77 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
<p class="text-fade margin-bottom-small" data-ls-bind="{{project-function.runtime|runtimeName}} {{project-function.runtime|runtimeVersion}}">
</p>
<div data-ls-if="{{project-function.tag}} !== ''" class="margin-top">
<div data-ls-if="{{project-function.deployment}} !== ''" class="margin-top">
<button data-ls-ui-trigger="execute-now">Execute Now</button> &nbsp; <a data-ls-attrs="href=/console/functions/function/logs?id={{router.params.id}}&project={{router.params.project}}" class="button reverse" style="vertical-align: top;">View Logs</a>
</div>
</div>
</div>
<div class="margin-bottom"
data-service="functions.listTags"
data-service="functions.listDeployments"
data-scope="sdk"
data-event="load,functions.createTag,functions.deleteTag,functions.updateTag,functions.retryBuild"
data-name="project-function-tags"
data-event="load,functions.createDeployment,functions.deleteDeployment,functions.updateDeployment,functions.retryBuild"
data-name="project-function-deployments"
data-param-function-id="{{router.params.id}}"
data-param-limit="<?php echo APP_PAGING_LIMIT; ?>"
data-param-offset=""
data-param-order-type="DESC"
data-success="trigger"
data-success-param-trigger-events="functions.listTags">
data-success-param-trigger-events="functions.listDeployments">
<h3>Tags <span class="text-fade text-size-small pull-end margin-top-small" data-ls-bind="{{project-function-tags.sum}} tags found"></span></h3>
<h3>Deployments <span class="text-fade text-size-small pull-end margin-top-small" data-ls-bind="{{project-function-deployments.sum}} deployments found"></span></h3>
<div data-ls-if="0 == {{project-function-tags.tags.length}} || undefined == {{project-function-tags.tags.length}}" class="box margin-top margin-bottom">
<h3 class="margin-bottom-small text-bold">No Tags Found</h3>
<div data-ls-if="0 == {{project-function-deployments.deployments.length}} || undefined == {{project-function-deployments.deployments.length}}" class="box margin-top margin-bottom">
<h3 class="margin-bottom-small text-bold">No Deployments Found</h3>
<p class="margin-bottom-no">You haven't deployed any tags for your function yet.</p>
<p class="margin-bottom-no">You haven't deployed any deployments for your function yet.</p>
</div>
<div data-ls-if="(0 != {{project-function-tags.tags.length}}) && (undefined !== {{project-function-tags.tags.length}})">
<div data-ls-if="(0 != {{project-function-deployments.deployments.length}}) && (undefined !== {{project-function-deployments.deployments.length}})">
<div class="box margin-bottom">
<ul data-ls-loop="project-function-tags.tags" data-ls-as="tag" class="list">
<ul data-ls-loop="project-function-deployments.deployments" data-ls-as="deployment" class="list">
<li class="clear">
<div data-ui-modal class="modal width-large box close" data-button-hide="on" data-open-event="open-stderr-{{tag.$id}}">
<div data-ui-modal class="modal width-large box close" data-button-hide="on" data-open-event="open-stderr-{{deployment.$id}}">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
<h2>Build Error Log</h2>
<div class="margin-bottom">
<input type="hidden" data-ls-bind="{{tag.buildStderr}}" data-forms-code="bash" data-lang="bash" data-lang-label="Bash" />
<input type="hidden" data-ls-bind="{{deployment.buildStderr}}" data-forms-code="bash" data-lang="bash" data-lang-label="Bash" />
</div>
<button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</div>
<div data-ui-modal class="modal width-large box close" data-button-hide="on" data-open-event="open-stdout-{{tag.$id}}">
<div data-ui-modal class="modal width-large box close" data-button-hide="on" data-open-event="open-stdout-{{deployment.$id}}">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
<h2>Build Log</h2>
<div class="margin-bottom">
<input type="hidden" data-ls-bind="{{tag.buildStdout}}" data-forms-code="bash" data-lang="bash" data-lang-label="Bash" />
<input type="hidden" data-ls-bind="{{deployment.buildStdout}}" data-forms-code="bash" data-lang="bash" data-lang-label="Bash" />
</div>
<button data-ui-modal-close="" type="button" class="reverse">Cancel</button>
</div>
<form data-ls-if="({{tag.$id}} !== {{project-function.tag}} && {{tag.status}} == 'ready')" name="functions.updateTag" class="pull-end"
<form data-ls-if="({{deployment.$id}} !== {{project-function.deployment}} && {{deployment.status}} == 'ready')" name="functions.updateDeployment" class="pull-end"
data-analytics
data-analytics-activity
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Create Function Execution"
data-service="functions.updateTag"
data-service="functions.updateDeployment"
data-event="submit"
data-param-function-id="{{router.params.id}}"
data-success="alert,trigger"
data-success-param-alert-text="Tag updated successfully"
data-success-param-trigger-events="functions.updateTag"
data-success-param-alert-text="Deployment updated successfully"
data-success-param-trigger-events="functions.updateDeployment"
data-failure="alert"
data-failure-param-alert-text="Failed to update tag"
data-failure-param-alert-text="Failed to update deployment"
data-failure-param-alert-classname="error">
<input type="hidden" name="tag" data-ls-bind="{{tag.$id}}">
<input type="hidden" name="deployment" data-ls-bind="{{deployment.$id}}">
<button>Activate</button>
</form>
<form data-ls-if="({{tag.$id}} !== {{project-function.tag}} && {{tag.status}} == 'failed')" name="functions.retryBuild" class="pull-end"
<form data-ls-if="({{deployment.$id}} !== {{project-function.deployment}} && {{deployment.status}} == 'failed')" name="functions.retryBuild" class="pull-end"
data-analytics
data-analytics-activity
data-analytics-event="submit"
@ -134,38 +134,38 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
data-failure="alert"
data-failure-param-alert-text="Failed to retry build"
data-failure-param-alert-classname="error">
<input type="hidden" name="buildId" data-ls-bind="{{tag.buildId}}">
<input type="hidden" name="buildId" data-ls-bind="{{deployment.buildId}}">
<button>Retry Build</button>
</form>
<b data-ls-bind="{{tag.$id}}"></b> &nbsp;
<span class="text-fade" data-ls-bind="{{tag.entrypoint}}"></span>
<b data-ls-bind="{{deployment.$id}}"></b> &nbsp;
<span class="text-fade" data-ls-bind="{{deployment.entrypoint}}"></span>
<div class="text-size-small margin-top-small clear">
<span data-ls-if="{{tag.status}} == 'failed'" style="color: var(--config-color-danger)" class="pull-start" data-ls-bind="{{tag.status}}"></span>
<span data-ls-if="{{tag.status}} == 'ready'" style="color: var(--config-color-success)" class="pull-start" data-ls-bind="{{tag.status}}"></span>
<span data-ls-if="{{tag.status}} == 'processing' || {{tag.status}} == 'building'" style="color: var(--config-color-info)" class="pull-start" data-ls-bind="{{tag.status}}"></span>
<span class="pull-start" data-ls-bind="&nbsp; | &nbsp; Created {{tag.dateCreated|timeSince}} &nbsp; | &nbsp; {{tag.size|humanFileSize}}{{tag.size|humanFileUnit}}"></span>
<span data-ls-if="{{deployment.status}} == 'failed'" style="color: var(--config-color-danger)" class="pull-start" data-ls-bind="{{deployment.status}}"></span>
<span data-ls-if="{{deployment.status}} == 'ready'" style="color: var(--config-color-success)" class="pull-start" data-ls-bind="{{deployment.status}}"></span>
<span data-ls-if="{{deployment.status}} == 'processing' || {{deployment.status}} == 'building'" style="color: var(--config-color-info)" class="pull-start" data-ls-bind="{{deployment.status}}"></span>
<span class="pull-start" data-ls-bind="&nbsp; | &nbsp; Created {{deployment.dateCreated|timeSince}} &nbsp; | &nbsp; {{deployment.size|humanFileSize}}{{deployment.size|humanFileUnit}}"></span>
<span data-ls-if="{{tag.status}} == 'failed'">&nbsp; | &nbsp;<button type="button" class="link text-size-small" data-ls-ui-trigger="open-stderr-{{tag.$id}}">Logs</button></span>
<span data-ls-if="{{tag.status}} == 'ready'">&nbsp; | &nbsp;<button type="button" class="link text-size-small" data-ls-ui-trigger="open-stdout-{{tag.$id}}">Logs</button></span>
<span data-ls-if="{{deployment.status}} == 'failed'">&nbsp; | &nbsp;<button type="button" class="link text-size-small" data-ls-ui-trigger="open-stderr-{{deployment.$id}}">Logs</button></span>
<span data-ls-if="{{deployment.status}} == 'ready'">&nbsp; | &nbsp;<button type="button" class="link text-size-small" data-ls-ui-trigger="open-stdout-{{deployment.$id}}">Logs</button></span>
<form data-ls-if="{{tag.$id}} !== {{project-function.tag}}" name="functions.deleteTag" class="pull-start"
<form data-ls-if="{{deployment.$id}} !== {{project-function.deployment}}" name="functions.deleteDeployment" class="pull-start"
data-analytics
data-analytics-activity
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Delete Function Tag"
data-service="functions.deleteTag"
data-analytics-label="Delete Function Deployment"
data-service="functions.deleteDeployment"
data-event="submit"
data-param-function-id="{{router.params.id}}"
data-confirm="Are you sure you want to delete this function tag?"
data-confirm="Are you sure you want to delete this function deployment?"
data-success="alert,trigger"
data-success-param-alert-text="Function tag deleted successfully"
data-success-param-trigger-events="functions.deleteTag"
data-success-param-alert-text="Function deployment deleted successfully"
data-success-param-trigger-events="functions.deleteDeployment"
data-failure="alert"
data-failure-param-alert-text="Failed to delete function tag"
data-failure-param-alert-text="Failed to delete function deployment"
data-failure-param-alert-classname="error">
<input type="hidden" name="tagId" data-ls-bind="{{tag.$id}}" />
<input type="hidden" name="deploymentId" data-ls-bind="{{deployment.$id}}" />
&nbsp; | &nbsp;<button type="submit" class="link text-danger text-size-small">Delete</button>
</form>
@ -177,38 +177,38 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
</div>
<div class="pull-start">
<button data-ls-ui-trigger="deploy-tag">Deploy Tag</button>
<button data-ls-ui-trigger="deploy-deployment">Create Deployment</button>
</div>
<div class="pull-end paging">
<form
data-service="functions.listTags"
data-service="functions.listDeployments"
data-event="submit"
data-param-function-id="{{router.params.id}}"
data-param-search="{{router.params.search}}"
data-param-limit="<?php echo APP_PAGING_LIMIT; ?>"
data-param-order-type="DESC"
data-scope="sdk"
data-name="project-function-tags"
data-name="project-function-deployments"
data-success="state"
data-success-param-state-keys="search,offset">
<button name="offset" data-paging-back data-offset="{{router.params.offset}}" data-sum="{{project-function-tags.sum}}" class="margin-end round small" aria-label="Back"><i class="icon-left-open"></i></button>
<button name="offset" data-paging-back data-offset="{{router.params.offset}}" data-sum="{{project-function-deployments.sum}}" class="margin-end round small" aria-label="Back"><i class="icon-left-open"></i></button>
</form>
<span data-ls-bind="{{router.params.offset|pageCurrent}} / {{project-function-tags.sum|pageTotal}}"></span>
<span data-ls-bind="{{router.params.offset|pageCurrent}} / {{project-function-deployments.sum|pageTotal}}"></span>
<form
data-service="functions.listTags"
data-service="functions.listDeployments"
data-event="submit"
data-param-function-id="{{router.params.id}}"
data-param-search="{{router.params.search}}"
data-param-limit="<?php echo APP_PAGING_LIMIT; ?>"
data-param-order-type="DESC"
data-scope="sdk"
data-name="project-function-tags"
data-name="project-function-deployments"
data-success="state"
data-success-param-state-keys="search,offset">
<button name="offset" data-paging-next data-offset="{{router.params.offset}}" data-sum="{{project-function-tags.sum}}" class="margin-start round small" aria-label="Next"><i class="icon-right-open"></i></button>
<button name="offset" data-paging-next data-offset="{{router.params.offset}}" data-sum="{{project-function-deployments.sum}}" class="margin-start round small" aria-label="Next"><i class="icon-right-open"></i></button>
</form>
</div>
</div>
@ -607,7 +607,7 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
<div data-ui-modal class="modal close box sticky-footer" data-button-hide="on" data-open-event="execute-now">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
<h1 class="margin-bottom">Execute Function</h1>
<form data-ls-if="{{project-function.tag}} !== ''" name="functions.createExecution" class="margin-top"
<form data-ls-if="{{project-function.deployment}} !== ''" name="functions.createExecution" class="margin-top"
data-analytics
data-analytics-activity
data-analytics-event="submit"
@ -629,10 +629,10 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
<button type="submit" style="vertical-align: top;">Execute Now</button>
</form>
</div>
<div data-ui-modal class="modal close box sticky-footer" data-button-hide="on" data-open-event="deploy-tag">
<div data-ui-modal class="modal close box sticky-footer" data-button-hide="on" data-open-event="deploy-deployment">
<button type="button" class="close pull-end" data-ui-modal-close=""><i class="icon-cancel"></i></button>
<h1 class="margin-bottom-xl">Deploy a New Tag</h1>
<h1 class="margin-bottom-xl">Create a New Deployment</h1>
<ul class="phases padding margin-top-negative-small" data-ui-phases>
<li>
@ -641,7 +641,7 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
<p><b>Unix</b></p>
<div class="margin-bottom">
<textarea type="hidden" data-ls-bind="appwrite functions createTag \
<textarea type="hidden" data-ls-bind="appwrite functions createDeployment \
--functionId={{project-function.$id}} \
--entrypoint='scriptFile' \
--code='/myrepo/myfunction'" data-forms-code="bash" data-lang="bash" data-lang-label="Bash"></textarea>
@ -650,13 +650,13 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
<p><b>PowerShell</b></p>
<div class="margin-bottom">
<textarea type="hidden" data-ls-bind="appwrite functions createTag `
<textarea type="hidden" data-ls-bind="appwrite functions createDeployment `
--functionId={{project-function.$id}} `
--entrypoint='scriptFile' `
--code='/myrepo/myfunction'" data-forms-code="powershell" data-lang="powershell" data-lang-label="PowerShell"></textarea>
</div>
<p>Learn more about <a href="https://appwrite.io/docs/server/functions#functionsCreateTag" target="_blank">creating tags</a>, installing and using the <a href="https://appwrite.io/docs/command-line" target="_blank">Appwrite CLI</a>.</p>
<p>Learn more about <a href="https://appwrite.io/docs/server/functions#functionsCreateDeployment" target="_blank">creating deployments</a>, installing and using the <a href="https://appwrite.io/docs/command-line" target="_blank">Appwrite CLI</a>.</p>
</li>
<li>
<h2 style="display: none">Manual</h2>
@ -665,27 +665,27 @@ $usageStatsEnabled = $this->getParam('usageStatsEnabled', true);
data-analytics-activity
data-analytics-event="submit"
data-analytics-category="console"
data-analytics-label="Create Function Tag"
data-service="functions.createTag"
data-analytics-label="Create Function Deployment"
data-service="functions.createDeployment"
data-scope="sdk"
data-event="submit"
data-success="alert,trigger,reset"
data-success-param-alert-text="Created function tag successfully"
data-success-param-trigger-events="functions.createTag"
data-success-param-alert-text="Created function deployment successfully"
data-success-param-trigger-events="functions.createDeployment"
data-failure="alert"
data-failure-param-alert-text="Failed to create function tag"
data-failure-param-alert-text="Failed to create function deployment"
data-failure-param-alert-classname="error">
<input type="hidden" name="functionId" data-ls-bind="{{router.params.id}}" />
<label for="tag-entrypoint">Entrypoint</label>
<input type="text" id="tag-entrypoint" name="entrypoint" required autocomplete="off" class="margin-bottom" placeholder="main.js" />
<label for="deployment-entrypoint">Entrypoint</label>
<input type="text" id="deployment-entrypoint" name="entrypoint" required autocomplete="off" class="margin-bottom" placeholder="main.js" />
<label for="tag-code">Gzipped Code (tar.gz file)</label>
<input type="file" name="code" id="tag-code" size="1" required accept="application/x-gzip,.gz">
<label for="deployment-code">Gzipped Code (tar.gz file)</label>
<input type="file" name="code" id="deployment-code" size="1" required accept="application/x-gzip,.gz">
<div class="text-fade text-size-xs margin-top-negative-small margin-bottom">(Max file size allowed: <?php echo $fileLimitHuman; ?>)</div>
<label for="tag-deploy" class="margin-bottom-large">Auto Deploy Tag after build <input type="checkbox" class="margin-start-small" id="tag-deploy" name="deploy" /></label>
<label for="deployment-deploy" class="margin-bottom-large">Auto Deploy Deployment after build <input type="checkbox" class="margin-start-small" id="deployment-deploy" name="deploy" /></label>
<footer>
<button type="submit">Create</button> &nbsp; <button data-ui-modal-close="" type="button" class="reverse">Cancel</button>

View file

@ -309,15 +309,15 @@ class DeletesV1 extends Worker
$dbForProject = $this->getProjectDB($projectId);
$device = new Local(APP_STORAGE_FUNCTIONS . '/app-' . $projectId);
// Delete Tags
$this->deleteByGroup('tags', [
// Delete Deployments
$this->deleteByGroup('deployments', [
new Query('functionId', Query::TYPE_EQUAL, [$document->getId()])
], $dbForProject, function (Document $document) use ($device) {
if ($device->delete($document->getAttribute('path', ''))) {
Console::success('Delete code tag: ' . $document->getAttribute('path', ''));
Console::success('Delete code deployment: ' . $document->getAttribute('path', ''));
} else {
Console::error('Failed to delete code tag: ' . $document->getAttribute('path', ''));
Console::error('Failed to delete code deployment: ' . $document->getAttribute('path', ''));
}
});

View file

@ -84,11 +84,11 @@ class FunctionsV1 extends Worker
foreach ($functions as $function) {
$events = $function->getAttribute('events', []);
$tag = $function->getAttribute('tag', []);
$deployment = $function->getAttribute('deployment', []);
Console::success('Itterating function: ' . $function->getAttribute('name'));
if (!\in_array($event, $events) || empty($tag)) {
if (!\in_array($event, $events) || empty($deployment)) {
continue;
}
@ -205,7 +205,7 @@ class FunctionsV1 extends Worker
}
/**
* Execute function tag
* Execute function deployment
*
* @param string $trigger
* @param string $projectId

View file

@ -1,4 +1,4 @@
Create a new function code tag. Use this endpoint to upload a new version of your code function. To execute your newly uploaded code, you'll need to update the function's tag to use your new tag UID.
Create a new function code deployment. Use this endpoint to upload a new version of your code function. To execute your newly uploaded code, you'll need to update the function's deployment to use your new deployment UID.
This endpoint accepts a tar.gz file compressed with your code. Make sure to include any dependencies your code has within the compressed file. You can learn more about code packaging in the [Appwrite Cloud Functions tutorial](/docs/functions).

View file

@ -0,0 +1 @@
Delete a code deployment by its unique ID.

View file

@ -1 +0,0 @@
Delete a code tag by its unique ID.

View file

@ -0,0 +1 @@
Get a code deployment by its unique ID.

View file

@ -1 +0,0 @@
Get a code tag by its unique ID.

View file

@ -0,0 +1 @@
Get a list of all the project's code deployments. You can use the query params to filter your results.

View file

@ -1 +0,0 @@
Get a list of all the project's code tags. You can use the query params to filter your results.

View file

@ -0,0 +1 @@
Update the function code deployment ID using the unique function ID. Use this endpoint to switch the code deployment that should be executed by the execution endpoint.

View file

@ -1 +0,0 @@
Update the function code tag ID using the unique function ID. Use this endpoint to switch the code tag that should be executed by the execution endpoint.

View file

@ -106,11 +106,12 @@ if(typeof size!=='undefined'){payload['size']=size;}
if(typeof margin!=='undefined'){payload['margin']=margin;}
if(typeof download!=='undefined'){payload['download']=download;}
const uri=new URL(this.config.endpoint+path);payload['project']=this.config.project;for(const[key,value]of Object.entries(this.flatten(payload))){uri.searchParams.append(key,value);}
return uri;}};this.functions={listBuilds:(limit,offset,search,cursor,cursorDirection)=>__awaiter(this,void 0,void 0,function*(){let path='/builds';let payload={};if(typeof limit!=='undefined'){payload['limit']=limit;}
return uri;}};this.functions={builds:(search,limit,offset,cursor,cursorDirection,orderType)=>__awaiter(this,void 0,void 0,function*(){let path='/builds';let payload={};if(typeof search!=='undefined'){payload['search']=search;}
if(typeof limit!=='undefined'){payload['limit']=limit;}
if(typeof offset!=='undefined'){payload['offset']=offset;}
if(typeof search!=='undefined'){payload['search']=search;}
if(typeof cursor!=='undefined'){payload['cursor']=cursor;}
if(typeof cursorDirection!=='undefined'){payload['cursorDirection']=cursorDirection;}
if(typeof orderType!=='undefined'){payload['orderType']=orderType;}
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getBuild:(buildId)=>__awaiter(this,void 0,void 0,function*(){if(typeof buildId==='undefined'){throw new AppwriteException('Missing required parameter: "buildId"');}
let path='/builds/{buildId}'.replace('{buildId}',buildId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),retryBuild:(buildId)=>__awaiter(this,void 0,void 0,function*(){if(typeof buildId==='undefined'){throw new AppwriteException('Missing required parameter: "buildId"');}
let path='/builds/{buildId}'.replace('{buildId}',buildId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),list:(search,limit,offset,cursor,cursorDirection,orderType)=>__awaiter(this,void 0,void 0,function*(){let path='/functions';let payload={};if(typeof search!=='undefined'){payload['search']=search;}
@ -142,7 +143,28 @@ if(typeof events!=='undefined'){payload['events']=events;}
if(typeof schedule!=='undefined'){payload['schedule']=schedule;}
if(typeof timeout!=='undefined'){payload['timeout']=timeout;}
const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);}),delete:(functionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
let path='/functions/{functionId}'.replace('{functionId}',functionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listExecutions:(functionId,limit,offset,search,cursor,cursorDirection)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
let path='/functions/{functionId}'.replace('{functionId}',functionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listDeployments:(functionId,search,limit,offset,cursor,cursorDirection,orderType)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
let path='/functions/{functionId}/deployments'.replace('{functionId}',functionId);let payload={};if(typeof search!=='undefined'){payload['search']=search;}
if(typeof limit!=='undefined'){payload['limit']=limit;}
if(typeof offset!=='undefined'){payload['offset']=offset;}
if(typeof cursor!=='undefined'){payload['cursor']=cursor;}
if(typeof cursorDirection!=='undefined'){payload['cursorDirection']=cursorDirection;}
if(typeof orderType!=='undefined'){payload['orderType']=orderType;}
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createDeployment:(functionId,entrypoint,code,deploy)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
if(typeof entrypoint==='undefined'){throw new AppwriteException('Missing required parameter: "entrypoint"');}
if(typeof code==='undefined'){throw new AppwriteException('Missing required parameter: "code"');}
if(typeof deploy==='undefined'){throw new AppwriteException('Missing required parameter: "deploy"');}
let path='/functions/{functionId}/deployments'.replace('{functionId}',functionId);let payload={};if(typeof entrypoint!=='undefined'){payload['entrypoint']=entrypoint;}
if(typeof code!=='undefined'){payload['code']=code;}
if(typeof deploy!=='undefined'){payload['deploy']=deploy;}
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'multipart/form-data',},payload);}),updateDeployment:(functionId,deployment)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
if(typeof deployment==='undefined'){throw new AppwriteException('Missing required parameter: "deployment"');}
let path='/functions/{functionId}/deployments'.replace('{functionId}',functionId);let payload={};if(typeof deployment!=='undefined'){payload['deployment']=deployment;}
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),getDeployment:(functionId,deploymentId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
if(typeof deploymentId==='undefined'){throw new AppwriteException('Missing required parameter: "deploymentId"');}
let path='/functions/{functionId}/deployments/{deploymentId}'.replace('{functionId}',functionId).replace('{deploymentId}',deploymentId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),deleteDeployment:(functionId,deploymentId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
if(typeof deploymentId==='undefined'){throw new AppwriteException('Missing required parameter: "deploymentId"');}
let path='/functions/{functionId}/deployments/{deploymentId}'.replace('{functionId}',functionId).replace('{deploymentId}',deploymentId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listExecutions:(functionId,limit,offset,search,cursor,cursorDirection)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
let path='/functions/{functionId}/executions'.replace('{functionId}',functionId);let payload={};if(typeof limit!=='undefined'){payload['limit']=limit;}
if(typeof offset!=='undefined'){payload['offset']=offset;}
if(typeof search!=='undefined'){payload['search']=search;}
@ -153,28 +175,7 @@ let path='/functions/{functionId}/executions'.replace('{functionId}',functionId)
if(typeof async!=='undefined'){payload['async']=async;}
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getExecution:(functionId,executionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
if(typeof executionId==='undefined'){throw new AppwriteException('Missing required parameter: "executionId"');}
let path='/functions/{functionId}/executions/{executionId}'.replace('{functionId}',functionId).replace('{executionId}',executionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateTag:(functionId,tag)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
if(typeof tag==='undefined'){throw new AppwriteException('Missing required parameter: "tag"');}
let path='/functions/{functionId}/tag'.replace('{functionId}',functionId);let payload={};if(typeof tag!=='undefined'){payload['tag']=tag;}
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),listTags:(functionId,search,limit,offset,cursor,cursorDirection,orderType)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
let path='/functions/{functionId}/tags'.replace('{functionId}',functionId);let payload={};if(typeof search!=='undefined'){payload['search']=search;}
if(typeof limit!=='undefined'){payload['limit']=limit;}
if(typeof offset!=='undefined'){payload['offset']=offset;}
if(typeof cursor!=='undefined'){payload['cursor']=cursor;}
if(typeof cursorDirection!=='undefined'){payload['cursorDirection']=cursorDirection;}
if(typeof orderType!=='undefined'){payload['orderType']=orderType;}
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createTag:(functionId,entrypoint,code,deploy)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
if(typeof entrypoint==='undefined'){throw new AppwriteException('Missing required parameter: "entrypoint"');}
if(typeof code==='undefined'){throw new AppwriteException('Missing required parameter: "code"');}
if(typeof deploy==='undefined'){throw new AppwriteException('Missing required parameter: "deploy"');}
let path='/functions/{functionId}/tags'.replace('{functionId}',functionId);let payload={};if(typeof entrypoint!=='undefined'){payload['entrypoint']=entrypoint;}
if(typeof code!=='undefined'){payload['code']=code;}
if(typeof deploy!=='undefined'){payload['deploy']=deploy;}
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'multipart/form-data',},payload);}),getTag:(functionId,tagId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
if(typeof tagId==='undefined'){throw new AppwriteException('Missing required parameter: "tagId"');}
let path='/functions/{functionId}/tags/{tagId}'.replace('{functionId}',functionId).replace('{tagId}',tagId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),deleteTag:(functionId,tagId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
if(typeof tagId==='undefined'){throw new AppwriteException('Missing required parameter: "tagId"');}
let path='/functions/{functionId}/tags/{tagId}'.replace('{functionId}',functionId).replace('{tagId}',tagId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),getUsage:(functionId,range)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
let path='/functions/{functionId}/executions/{executionId}'.replace('{functionId}',functionId).replace('{executionId}',executionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getUsage:(functionId,range)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
let path='/functions/{functionId}/usage'.replace('{functionId}',functionId);let payload={};if(typeof range!=='undefined'){payload['range']=range;}
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);})};this.database={listCollections:(search,limit,offset,cursor,cursorDirection,orderType)=>__awaiter(this,void 0,void 0,function*(){let path='/database/collections';let payload={};if(typeof search!=='undefined'){payload['search']=search;}
if(typeof limit!=='undefined'){payload['limit']=limit;}

View file

@ -106,11 +106,12 @@ if(typeof size!=='undefined'){payload['size']=size;}
if(typeof margin!=='undefined'){payload['margin']=margin;}
if(typeof download!=='undefined'){payload['download']=download;}
const uri=new URL(this.config.endpoint+path);payload['project']=this.config.project;for(const[key,value]of Object.entries(this.flatten(payload))){uri.searchParams.append(key,value);}
return uri;}};this.functions={listBuilds:(limit,offset,search,cursor,cursorDirection)=>__awaiter(this,void 0,void 0,function*(){let path='/builds';let payload={};if(typeof limit!=='undefined'){payload['limit']=limit;}
return uri;}};this.functions={builds:(search,limit,offset,cursor,cursorDirection,orderType)=>__awaiter(this,void 0,void 0,function*(){let path='/builds';let payload={};if(typeof search!=='undefined'){payload['search']=search;}
if(typeof limit!=='undefined'){payload['limit']=limit;}
if(typeof offset!=='undefined'){payload['offset']=offset;}
if(typeof search!=='undefined'){payload['search']=search;}
if(typeof cursor!=='undefined'){payload['cursor']=cursor;}
if(typeof cursorDirection!=='undefined'){payload['cursorDirection']=cursorDirection;}
if(typeof orderType!=='undefined'){payload['orderType']=orderType;}
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getBuild:(buildId)=>__awaiter(this,void 0,void 0,function*(){if(typeof buildId==='undefined'){throw new AppwriteException('Missing required parameter: "buildId"');}
let path='/builds/{buildId}'.replace('{buildId}',buildId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),retryBuild:(buildId)=>__awaiter(this,void 0,void 0,function*(){if(typeof buildId==='undefined'){throw new AppwriteException('Missing required parameter: "buildId"');}
let path='/builds/{buildId}'.replace('{buildId}',buildId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),list:(search,limit,offset,cursor,cursorDirection,orderType)=>__awaiter(this,void 0,void 0,function*(){let path='/functions';let payload={};if(typeof search!=='undefined'){payload['search']=search;}
@ -142,7 +143,28 @@ if(typeof events!=='undefined'){payload['events']=events;}
if(typeof schedule!=='undefined'){payload['schedule']=schedule;}
if(typeof timeout!=='undefined'){payload['timeout']=timeout;}
const uri=new URL(this.config.endpoint+path);return yield this.call('put',uri,{'content-type':'application/json',},payload);}),delete:(functionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
let path='/functions/{functionId}'.replace('{functionId}',functionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listExecutions:(functionId,limit,offset,search,cursor,cursorDirection)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
let path='/functions/{functionId}'.replace('{functionId}',functionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listDeployments:(functionId,search,limit,offset,cursor,cursorDirection,orderType)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
let path='/functions/{functionId}/deployments'.replace('{functionId}',functionId);let payload={};if(typeof search!=='undefined'){payload['search']=search;}
if(typeof limit!=='undefined'){payload['limit']=limit;}
if(typeof offset!=='undefined'){payload['offset']=offset;}
if(typeof cursor!=='undefined'){payload['cursor']=cursor;}
if(typeof cursorDirection!=='undefined'){payload['cursorDirection']=cursorDirection;}
if(typeof orderType!=='undefined'){payload['orderType']=orderType;}
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createDeployment:(functionId,entrypoint,code,deploy)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
if(typeof entrypoint==='undefined'){throw new AppwriteException('Missing required parameter: "entrypoint"');}
if(typeof code==='undefined'){throw new AppwriteException('Missing required parameter: "code"');}
if(typeof deploy==='undefined'){throw new AppwriteException('Missing required parameter: "deploy"');}
let path='/functions/{functionId}/deployments'.replace('{functionId}',functionId);let payload={};if(typeof entrypoint!=='undefined'){payload['entrypoint']=entrypoint;}
if(typeof code!=='undefined'){payload['code']=code;}
if(typeof deploy!=='undefined'){payload['deploy']=deploy;}
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'multipart/form-data',},payload);}),updateDeployment:(functionId,deployment)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
if(typeof deployment==='undefined'){throw new AppwriteException('Missing required parameter: "deployment"');}
let path='/functions/{functionId}/deployments'.replace('{functionId}',functionId);let payload={};if(typeof deployment!=='undefined'){payload['deployment']=deployment;}
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),getDeployment:(functionId,deploymentId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
if(typeof deploymentId==='undefined'){throw new AppwriteException('Missing required parameter: "deploymentId"');}
let path='/functions/{functionId}/deployments/{deploymentId}'.replace('{functionId}',functionId).replace('{deploymentId}',deploymentId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),deleteDeployment:(functionId,deploymentId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
if(typeof deploymentId==='undefined'){throw new AppwriteException('Missing required parameter: "deploymentId"');}
let path='/functions/{functionId}/deployments/{deploymentId}'.replace('{functionId}',functionId).replace('{deploymentId}',deploymentId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),listExecutions:(functionId,limit,offset,search,cursor,cursorDirection)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
let path='/functions/{functionId}/executions'.replace('{functionId}',functionId);let payload={};if(typeof limit!=='undefined'){payload['limit']=limit;}
if(typeof offset!=='undefined'){payload['offset']=offset;}
if(typeof search!=='undefined'){payload['search']=search;}
@ -153,28 +175,7 @@ let path='/functions/{functionId}/executions'.replace('{functionId}',functionId)
if(typeof async!=='undefined'){payload['async']=async;}
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'application/json',},payload);}),getExecution:(functionId,executionId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
if(typeof executionId==='undefined'){throw new AppwriteException('Missing required parameter: "executionId"');}
let path='/functions/{functionId}/executions/{executionId}'.replace('{functionId}',functionId).replace('{executionId}',executionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),updateTag:(functionId,tag)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
if(typeof tag==='undefined'){throw new AppwriteException('Missing required parameter: "tag"');}
let path='/functions/{functionId}/tag'.replace('{functionId}',functionId);let payload={};if(typeof tag!=='undefined'){payload['tag']=tag;}
const uri=new URL(this.config.endpoint+path);return yield this.call('patch',uri,{'content-type':'application/json',},payload);}),listTags:(functionId,search,limit,offset,cursor,cursorDirection,orderType)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
let path='/functions/{functionId}/tags'.replace('{functionId}',functionId);let payload={};if(typeof search!=='undefined'){payload['search']=search;}
if(typeof limit!=='undefined'){payload['limit']=limit;}
if(typeof offset!=='undefined'){payload['offset']=offset;}
if(typeof cursor!=='undefined'){payload['cursor']=cursor;}
if(typeof cursorDirection!=='undefined'){payload['cursorDirection']=cursorDirection;}
if(typeof orderType!=='undefined'){payload['orderType']=orderType;}
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),createTag:(functionId,entrypoint,code,deploy)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
if(typeof entrypoint==='undefined'){throw new AppwriteException('Missing required parameter: "entrypoint"');}
if(typeof code==='undefined'){throw new AppwriteException('Missing required parameter: "code"');}
if(typeof deploy==='undefined'){throw new AppwriteException('Missing required parameter: "deploy"');}
let path='/functions/{functionId}/tags'.replace('{functionId}',functionId);let payload={};if(typeof entrypoint!=='undefined'){payload['entrypoint']=entrypoint;}
if(typeof code!=='undefined'){payload['code']=code;}
if(typeof deploy!=='undefined'){payload['deploy']=deploy;}
const uri=new URL(this.config.endpoint+path);return yield this.call('post',uri,{'content-type':'multipart/form-data',},payload);}),getTag:(functionId,tagId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
if(typeof tagId==='undefined'){throw new AppwriteException('Missing required parameter: "tagId"');}
let path='/functions/{functionId}/tags/{tagId}'.replace('{functionId}',functionId).replace('{tagId}',tagId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),deleteTag:(functionId,tagId)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
if(typeof tagId==='undefined'){throw new AppwriteException('Missing required parameter: "tagId"');}
let path='/functions/{functionId}/tags/{tagId}'.replace('{functionId}',functionId).replace('{tagId}',tagId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('delete',uri,{'content-type':'application/json',},payload);}),getUsage:(functionId,range)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
let path='/functions/{functionId}/executions/{executionId}'.replace('{functionId}',functionId).replace('{executionId}',executionId);let payload={};const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);}),getUsage:(functionId,range)=>__awaiter(this,void 0,void 0,function*(){if(typeof functionId==='undefined'){throw new AppwriteException('Missing required parameter: "functionId"');}
let path='/functions/{functionId}/usage'.replace('{functionId}',functionId);let payload={};if(typeof range!=='undefined'){payload['range']=range;}
const uri=new URL(this.config.endpoint+path);return yield this.call('get',uri,{'content-type':'application/json',},payload);})};this.database={listCollections:(search,limit,offset,cursor,cursorDirection,orderType)=>__awaiter(this,void 0,void 0,function*(){let path='/database/collections';let payload={};if(typeof search!=='undefined'){payload['search']=search;}
if(typeof limit!=='undefined'){payload['limit']=limit;}

View file

@ -1,29 +1,29 @@
(function (exports, isomorphicFormData, crossFetch) {
'use strict';
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
class AppwriteException extends Error {
@ -1126,32 +1126,36 @@
* all of the project's executions. [Learn more about different API
* modes](/docs/admin).
*
* @param {string} search
* @param {number} limit
* @param {number} offset
* @param {string} search
* @param {string} cursor
* @param {string} cursorDirection
* @param {string} orderType
* @throws {AppwriteException}
* @returns {Promise}
*/
listBuilds: (limit, offset, search, cursor, cursorDirection) => __awaiter(this, void 0, void 0, function* () {
builds: (search, limit, offset, cursor, cursorDirection, orderType) => __awaiter(this, void 0, void 0, function* () {
let path = '/builds';
let payload = {};
if (typeof search !== 'undefined') {
payload['search'] = search;
}
if (typeof limit !== 'undefined') {
payload['limit'] = limit;
}
if (typeof offset !== 'undefined') {
payload['offset'] = offset;
}
if (typeof search !== 'undefined') {
payload['search'] = search;
}
if (typeof cursor !== 'undefined') {
payload['cursor'] = cursor;
}
if (typeof cursorDirection !== 'undefined') {
payload['cursorDirection'] = cursorDirection;
}
if (typeof orderType !== 'undefined') {
payload['orderType'] = orderType;
}
const uri = new URL(this.config.endpoint + path);
return yield this.call('get', uri, {
'content-type': 'application/json',
@ -1404,6 +1408,178 @@
'content-type': 'application/json',
}, payload);
}),
/**
* List Deployments
*
* Get a list of all the project's code deployments. You can use the query
* params to filter your results.
*
* @param {string} functionId
* @param {string} search
* @param {number} limit
* @param {number} offset
* @param {string} cursor
* @param {string} cursorDirection
* @param {string} orderType
* @throws {AppwriteException}
* @returns {Promise}
*/
listDeployments: (functionId, search, limit, offset, cursor, cursorDirection, orderType) => __awaiter(this, void 0, void 0, function* () {
if (typeof functionId === 'undefined') {
throw new AppwriteException('Missing required parameter: "functionId"');
}
let path = '/functions/{functionId}/deployments'.replace('{functionId}', functionId);
let payload = {};
if (typeof search !== 'undefined') {
payload['search'] = search;
}
if (typeof limit !== 'undefined') {
payload['limit'] = limit;
}
if (typeof offset !== 'undefined') {
payload['offset'] = offset;
}
if (typeof cursor !== 'undefined') {
payload['cursor'] = cursor;
}
if (typeof cursorDirection !== 'undefined') {
payload['cursorDirection'] = cursorDirection;
}
if (typeof orderType !== 'undefined') {
payload['orderType'] = orderType;
}
const uri = new URL(this.config.endpoint + path);
return yield this.call('get', uri, {
'content-type': 'application/json',
}, payload);
}),
/**
* Create Deployment
*
* Create a new function deployment. Use this endpoint to upload a new version
* of your code function. To execute your newly uploaded code, you'll need to
* update the function's deployment to use your new deployment UID.
*
* This endpoint accepts a tar.gz file compressed with your code. Make sure to
* include any dependencies your code has within the compressed file. You can
* learn more about code packaging in the [Appwrite Cloud Functions
* tutorial](/docs/functions).
*
* Use the "command" param to set the entry point used to execute your code.
*
* @param {string} functionId
* @param {string} entrypoint
* @param {File} code
* @param {boolean} deploy
* @throws {AppwriteException}
* @returns {Promise}
*/
createDeployment: (functionId, entrypoint, code, deploy) => __awaiter(this, void 0, void 0, function* () {
if (typeof functionId === 'undefined') {
throw new AppwriteException('Missing required parameter: "functionId"');
}
if (typeof entrypoint === 'undefined') {
throw new AppwriteException('Missing required parameter: "entrypoint"');
}
if (typeof code === 'undefined') {
throw new AppwriteException('Missing required parameter: "code"');
}
if (typeof deploy === 'undefined') {
throw new AppwriteException('Missing required parameter: "deploy"');
}
let path = '/functions/{functionId}/deployments'.replace('{functionId}', functionId);
let payload = {};
if (typeof entrypoint !== 'undefined') {
payload['entrypoint'] = entrypoint;
}
if (typeof code !== 'undefined') {
payload['code'] = code;
}
if (typeof deploy !== 'undefined') {
payload['deploy'] = deploy;
}
const uri = new URL(this.config.endpoint + path);
return yield this.call('post', uri, {
'content-type': 'multipart/form-data',
}, payload);
}),
/**
* Update Function Deployment
*
* Update the function deployment ID using the unique function ID. Use this
* endpoint to switch the deployment that should be executed by the execution
* endpoint.
*
* @param {string} functionId
* @param {string} deployment
* @throws {AppwriteException}
* @returns {Promise}
*/
updateDeployment: (functionId, deployment) => __awaiter(this, void 0, void 0, function* () {
if (typeof functionId === 'undefined') {
throw new AppwriteException('Missing required parameter: "functionId"');
}
if (typeof deployment === 'undefined') {
throw new AppwriteException('Missing required parameter: "deployment"');
}
let path = '/functions/{functionId}/deployments'.replace('{functionId}', functionId);
let payload = {};
if (typeof deployment !== 'undefined') {
payload['deployment'] = deployment;
}
const uri = new URL(this.config.endpoint + path);
return yield this.call('patch', uri, {
'content-type': 'application/json',
}, payload);
}),
/**
* Get Deployment
*
* Get a code deployment by its unique ID.
*
* @param {string} functionId
* @param {string} deploymentId
* @throws {AppwriteException}
* @returns {Promise}
*/
getDeployment: (functionId, deploymentId) => __awaiter(this, void 0, void 0, function* () {
if (typeof functionId === 'undefined') {
throw new AppwriteException('Missing required parameter: "functionId"');
}
if (typeof deploymentId === 'undefined') {
throw new AppwriteException('Missing required parameter: "deploymentId"');
}
let path = '/functions/{functionId}/deployments/{deploymentId}'.replace('{functionId}', functionId).replace('{deploymentId}', deploymentId);
let payload = {};
const uri = new URL(this.config.endpoint + path);
return yield this.call('get', uri, {
'content-type': 'application/json',
}, payload);
}),
/**
* Delete Deployment
*
* Delete a code deployment by its unique ID.
*
* @param {string} functionId
* @param {string} deploymentId
* @throws {AppwriteException}
* @returns {Promise}
*/
deleteDeployment: (functionId, deploymentId) => __awaiter(this, void 0, void 0, function* () {
if (typeof functionId === 'undefined') {
throw new AppwriteException('Missing required parameter: "functionId"');
}
if (typeof deploymentId === 'undefined') {
throw new AppwriteException('Missing required parameter: "deploymentId"');
}
let path = '/functions/{functionId}/deployments/{deploymentId}'.replace('{functionId}', functionId).replace('{deploymentId}', deploymentId);
let payload = {};
const uri = new URL(this.config.endpoint + path);
return yield this.call('delete', uri, {
'content-type': 'application/json',
}, payload);
}),
/**
* List Executions
*
@ -1502,178 +1678,6 @@
'content-type': 'application/json',
}, payload);
}),
/**
* Update Function Tag
*
* Update the function code tag ID using the unique function ID. Use this
* endpoint to switch the code tag that should be executed by the execution
* endpoint.
*
* @param {string} functionId
* @param {string} tag
* @throws {AppwriteException}
* @returns {Promise}
*/
updateTag: (functionId, tag) => __awaiter(this, void 0, void 0, function* () {
if (typeof functionId === 'undefined') {
throw new AppwriteException('Missing required parameter: "functionId"');
}
if (typeof tag === 'undefined') {
throw new AppwriteException('Missing required parameter: "tag"');
}
let path = '/functions/{functionId}/tag'.replace('{functionId}', functionId);
let payload = {};
if (typeof tag !== 'undefined') {
payload['tag'] = tag;
}
const uri = new URL(this.config.endpoint + path);
return yield this.call('patch', uri, {
'content-type': 'application/json',
}, payload);
}),
/**
* List Tags
*
* Get a list of all the project's code tags. You can use the query params to
* filter your results.
*
* @param {string} functionId
* @param {string} search
* @param {number} limit
* @param {number} offset
* @param {string} cursor
* @param {string} cursorDirection
* @param {string} orderType
* @throws {AppwriteException}
* @returns {Promise}
*/
listTags: (functionId, search, limit, offset, cursor, cursorDirection, orderType) => __awaiter(this, void 0, void 0, function* () {
if (typeof functionId === 'undefined') {
throw new AppwriteException('Missing required parameter: "functionId"');
}
let path = '/functions/{functionId}/tags'.replace('{functionId}', functionId);
let payload = {};
if (typeof search !== 'undefined') {
payload['search'] = search;
}
if (typeof limit !== 'undefined') {
payload['limit'] = limit;
}
if (typeof offset !== 'undefined') {
payload['offset'] = offset;
}
if (typeof cursor !== 'undefined') {
payload['cursor'] = cursor;
}
if (typeof cursorDirection !== 'undefined') {
payload['cursorDirection'] = cursorDirection;
}
if (typeof orderType !== 'undefined') {
payload['orderType'] = orderType;
}
const uri = new URL(this.config.endpoint + path);
return yield this.call('get', uri, {
'content-type': 'application/json',
}, payload);
}),
/**
* Create Tag
*
* Create a new function code tag. Use this endpoint to upload a new version
* of your code function. To execute your newly uploaded code, you'll need to
* update the function's tag to use your new tag UID.
*
* This endpoint accepts a tar.gz file compressed with your code. Make sure to
* include any dependencies your code has within the compressed file. You can
* learn more about code packaging in the [Appwrite Cloud Functions
* tutorial](/docs/functions).
*
* Use the "command" param to set the entry point used to execute your code.
*
* @param {string} functionId
* @param {string} entrypoint
* @param {File} code
* @param {boolean} deploy
* @throws {AppwriteException}
* @returns {Promise}
*/
createTag: (functionId, entrypoint, code, deploy) => __awaiter(this, void 0, void 0, function* () {
if (typeof functionId === 'undefined') {
throw new AppwriteException('Missing required parameter: "functionId"');
}
if (typeof entrypoint === 'undefined') {
throw new AppwriteException('Missing required parameter: "entrypoint"');
}
if (typeof code === 'undefined') {
throw new AppwriteException('Missing required parameter: "code"');
}
if (typeof deploy === 'undefined') {
throw new AppwriteException('Missing required parameter: "deploy"');
}
let path = '/functions/{functionId}/tags'.replace('{functionId}', functionId);
let payload = {};
if (typeof entrypoint !== 'undefined') {
payload['entrypoint'] = entrypoint;
}
if (typeof code !== 'undefined') {
payload['code'] = code;
}
if (typeof deploy !== 'undefined') {
payload['deploy'] = deploy;
}
const uri = new URL(this.config.endpoint + path);
return yield this.call('post', uri, {
'content-type': 'multipart/form-data',
}, payload);
}),
/**
* Get Tag
*
* Get a code tag by its unique ID.
*
* @param {string} functionId
* @param {string} tagId
* @throws {AppwriteException}
* @returns {Promise}
*/
getTag: (functionId, tagId) => __awaiter(this, void 0, void 0, function* () {
if (typeof functionId === 'undefined') {
throw new AppwriteException('Missing required parameter: "functionId"');
}
if (typeof tagId === 'undefined') {
throw new AppwriteException('Missing required parameter: "tagId"');
}
let path = '/functions/{functionId}/tags/{tagId}'.replace('{functionId}', functionId).replace('{tagId}', tagId);
let payload = {};
const uri = new URL(this.config.endpoint + path);
return yield this.call('get', uri, {
'content-type': 'application/json',
}, payload);
}),
/**
* Delete Tag
*
* Delete a code tag by its unique ID.
*
* @param {string} functionId
* @param {string} tagId
* @throws {AppwriteException}
* @returns {Promise}
*/
deleteTag: (functionId, tagId) => __awaiter(this, void 0, void 0, function* () {
if (typeof functionId === 'undefined') {
throw new AppwriteException('Missing required parameter: "functionId"');
}
if (typeof tagId === 'undefined') {
throw new AppwriteException('Missing required parameter: "tagId"');
}
let path = '/functions/{functionId}/tags/{tagId}'.replace('{functionId}', functionId).replace('{tagId}', tagId);
let payload = {};
const uri = new URL(this.config.endpoint + path);
return yield this.call('delete', uri, {
'content-type': 'application/json',
}, payload);
}),
/**
* Get Function Usage
*

View file

@ -39,7 +39,7 @@ class Database
// Functions
const SYSTEM_COLLECTION_FUNCTIONS = 'functions';
const SYSTEM_COLLECTION_TAGS = 'tags';
const SYSTEM_COLLECTION_DEPLOYMENTS = 'deployments';
const SYSTEM_COLLECTION_EXECUTIONS = 'executions';
// Realtime

View file

@ -51,7 +51,7 @@ use Appwrite\Utopia\Response\Model\Phone;
use Appwrite\Utopia\Response\Model\Platform;
use Appwrite\Utopia\Response\Model\Project;
use Appwrite\Utopia\Response\Model\Rule;
use Appwrite\Utopia\Response\Model\Tag;
use Appwrite\Utopia\Response\Model\Deployment;
use Appwrite\Utopia\Response\Model\Token;
use Appwrite\Utopia\Response\Model\Webhook;
use Appwrite\Utopia\Response\Model\Preferences;
@ -151,8 +151,8 @@ class Response extends SwooleResponse
const MODEL_FUNCTION_LIST = 'functionList';
const MODEL_RUNTIME = 'runtime';
const MODEL_RUNTIME_LIST = 'runtimeList';
const MODEL_TAG = 'tag';
const MODEL_TAG_LIST = 'tagList';
const MODEL_DEPLOYMENT = 'deployment';
const MODEL_DEPLOYMENT_LIST = 'deploymentList';
const MODEL_EXECUTION = 'execution';
const MODEL_SYNC_EXECUTION = 'syncExecution';
const MODEL_EXECUTION_LIST = 'executionList';
@ -222,7 +222,7 @@ class Response extends SwooleResponse
->setModel(new BaseList('Memberships List', self::MODEL_MEMBERSHIP_LIST, 'memberships', self::MODEL_MEMBERSHIP))
->setModel(new BaseList('Functions List', self::MODEL_FUNCTION_LIST, 'functions', self::MODEL_FUNCTION))
->setModel(new BaseList('Runtimes List', self::MODEL_RUNTIME_LIST, 'runtimes', self::MODEL_RUNTIME))
->setModel(new BaseList('Tags List', self::MODEL_TAG_LIST, 'tags', self::MODEL_TAG))
->setModel(new BaseList('Deployments List', self::MODEL_DEPLOYMENT_LIST, 'deployments', self::MODEL_DEPLOYMENT))
->setModel(new BaseList('Executions List', self::MODEL_EXECUTION_LIST, 'executions', self::MODEL_EXECUTION))
->setModel(new BaseList('Builds List', self::MODEL_BUILD_LIST, 'builds', self::MODEL_BUILD))
->setModel(new BaseList('Projects List', self::MODEL_PROJECT_LIST, 'projects', self::MODEL_PROJECT, true, false))
@ -262,7 +262,7 @@ class Response extends SwooleResponse
->setModel(new Membership())
->setModel(new Func())
->setModel(new Runtime())
->setModel(new Tag())
->setModel(new Deployment())
->setModel(new Execution())
->setModel(new SyncExecution())
->setModel(new Build())

View file

@ -28,8 +28,8 @@ class V07 extends Filter
case Response::MODEL_COLLECTION:
case Response::MODEL_FILE_LIST:
case Response::MODEL_FILE:
case Response::MODEL_TAG_LIST:
case Response::MODEL_TAG:
case Response::MODEL_DEPLOYMENT_LIST:
case Response::MODEL_DEPLOYMENT:
case Response::MODEL_EXECUTION_LIST:
case Response::MODEL_EXECUTION:
case Response::MODEL_TEAM_LIST:

View file

@ -24,8 +24,8 @@ class V08 extends Filter
case Response::MODEL_COLLECTION:
case Response::MODEL_FILE_LIST:
case Response::MODEL_FILE:
case Response::MODEL_TAG_LIST:
case Response::MODEL_TAG:
case Response::MODEL_DEPLOYMENT_LIST:
case Response::MODEL_DEPLOYMENT:
case Response::MODEL_EXECUTION_LIST:
case Response::MODEL_EXECUTION:
case Response::MODEL_TEAM_LIST:

View file

@ -18,15 +18,15 @@ class Build extends Model
])
->addRule('dateCreated', [
'type' => self::TYPE_INTEGER,
'description' => 'The tag creation date in Unix timestamp.',
'description' => 'The deployment creation date in Unix timestamp.',
'default' => 0,
'example' => 1592981250,
])
// Build Status
// Failed - The tag build has failed. More details can usually be found in buildStderr
// Ready - The tag build was successful and the tag is ready to be deployed
// Processing - The tag is currently waiting to have a build triggered
// Building - The tag is currently being built
// Failed - The deployment build has failed. More details can usually be found in buildStderr
// Ready - The deployment build was successful and the deployment is ready to be deployed
// Processing - The deployment is currently waiting to have a build triggered
// Building - The deployment is currently being built
->addRule('status', [
'type' => self::TYPE_STRING,
'description' => 'The build status.',

View file

@ -5,14 +5,14 @@ namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
class Tag extends Model
class Deployment extends Model
{
public function __construct()
{
$this
->addRule('$id', [
'type' => self::TYPE_STRING,
'description' => 'Tag ID.',
'description' => 'Deployment ID.',
'default' => '',
'example' => '5e5ea5c16897e',
])
@ -24,13 +24,13 @@ class Tag extends Model
])
->addRule('dateCreated', [
'type' => self::TYPE_INTEGER,
'description' => 'The tag creation date in Unix timestamp.',
'description' => 'The deployment creation date in Unix timestamp.',
'default' => 0,
'example' => 1592981250,
])
->addRule('entrypoint', [
'type' => self::TYPE_STRING,
'description' => 'The entrypoint file to use to execute the tag code.',
'description' => 'The entrypoint file to use to execute the delpoyment code.',
'default' => '',
'example' => 'enabled',
])
@ -41,13 +41,13 @@ class Tag extends Model
'example' => 128,
])
// Build Status
// Failed - The tag build has failed. More details can usually be found in buildStderr
// Ready - The tag build was successful and the tag is ready to be deployed
// Processing - The tag is currently waiting to have a build triggered
// Building - The tag is currently being built
// Failed - The deployment build has failed. More details can usually be found in buildStderr
// Ready - The deployment build was successful and the deployment is ready to be deployed
// Processing - The deployment is currently waiting to have a build triggered
// Building - The deployment is currently being built
->addRule('status', [
'type' => self::TYPE_STRING,
'description' => 'The tags current built status',
'description' => 'The deployment\'s current built status',
'default' => '',
'example' => 'ready',
])
@ -71,7 +71,7 @@ class Tag extends Model
])
->addRule('deploy', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Whether the tag should be automatically deployed.',
'description' => 'Whether the deployment should be automatically deployed.',
'default' => false,
'example' => true,
])
@ -85,7 +85,7 @@ class Tag extends Model
*/
public function getName():string
{
return 'Tag';
return 'Deployment';
}
/**
@ -95,6 +95,6 @@ class Tag extends Model
*/
public function getType():string
{
return Response::MODEL_TAG;
return Response::MODEL_DEPLOYMENT;
}
}

View file

@ -55,9 +55,9 @@ class Func extends Model
'default' => '',
'example' => 'python-3.8',
])
->addRule('tag', [
->addRule('deployment', [
'type' => self::TYPE_STRING,
'description' => 'Function active tag ID.',
'description' => 'Function\'s active deployment ID.',
'default' => '',
'example' => '5e5ea5c16897e',
])

View file

@ -121,9 +121,9 @@ trait ProjectCustom
'functions.create',
'functions.update',
'functions.delete',
'functions.tags.create',
'functions.tags.update',
'functions.tags.delete',
'functions.deployments.create',
'functions.deployments.update',
'functions.deployments.delete',
'functions.executions.create',
'functions.executions.update',
'storage.files.create',

View file

@ -73,7 +73,7 @@ class FunctionsCustomClientTest extends Scope
$this->assertEquals(201, $function['headers']['status-code']);
$tag = $this->client->call(Client::METHOD_POST, '/functions/'.$function['body']['$id'].'/tags', [
$deployment = $this->client->call(Client::METHOD_POST, '/functions/'.$function['body']['$id'].'/deployments', [
'content-type' => 'multipart/form-data',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey'],
@ -82,19 +82,19 @@ class FunctionsCustomClientTest extends Scope
'code' => new CURLFile(realpath(__DIR__ . '/../../../resources/functions/php.tar.gz'), 'application/x-gzip', 'php-fx.tar.gz'),
]);
$tagId = $tag['body']['$id'] ?? '';
$deploymentId = $deployment['body']['$id'] ?? '';
$this->assertEquals(201, $tag['headers']['status-code']);
$this->assertEquals(201, $deployment['headers']['status-code']);
// Wait for tag to be built.
// Wait for deployment to be built.
sleep(5);
$function = $this->client->call(Client::METHOD_PATCH, '/functions/'.$function['body']['$id'].'/tag', [
$function = $this->client->call(Client::METHOD_PATCH, '/functions/'.$function['body']['$id'].'/deployment', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey'],
], [
'tag' => $tagId,
'deployment' => $deploymentId,
]);
$this->assertEquals(200, $function['headers']['status-code']);
@ -158,7 +158,7 @@ class FunctionsCustomClientTest extends Scope
$this->assertEquals(201, $function['headers']['status-code']);
$tag = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/tags', [
$deployment = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/deployments', [
'content-type' => 'multipart/form-data',
'x-appwrite-project' => $projectId,
'x-appwrite-key' => $apikey,
@ -167,19 +167,19 @@ class FunctionsCustomClientTest extends Scope
'code' => new CURLFile(realpath(__DIR__ . '/../../../resources/functions/php-fn.tar.gz'), 'application/x-gzip', 'php-fx.tar.gz'), //different tarball names intentional
]);
$tagId = $tag['body']['$id'] ?? '';
$deploymentId = $deployment['body']['$id'] ?? '';
// Wait for tag to be built.
// Wait for deployment to be built.
sleep(5);
$this->assertEquals(201, $tag['headers']['status-code']);
$this->assertEquals(201, $deployment['headers']['status-code']);
$function = $this->client->call(Client::METHOD_PATCH, '/functions/'.$functionId.'/tag', [
$function = $this->client->call(Client::METHOD_PATCH, '/functions/'.$functionId.'/deployment', [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-key' => $apikey,
], [
'tag' => $tagId,
'deployment' => $deploymentId,
]);
$this->assertEquals(200, $function['headers']['status-code']);
@ -208,7 +208,7 @@ class FunctionsCustomClientTest extends Scope
$this->assertEquals('completed', $executions['body']['status']);
$this->assertEquals($functionId, $output['APPWRITE_FUNCTION_ID']);
$this->assertEquals('Test', $output['APPWRITE_FUNCTION_NAME']);
$this->assertEquals($tagId, $output['APPWRITE_FUNCTION_TAG']);
$this->assertEquals($deploymentId, $output['APPWRITE_FUNCTION_DEPLOYMENT']);
$this->assertEquals('http', $output['APPWRITE_FUNCTION_TRIGGER']);
$this->assertEquals('PHP', $output['APPWRITE_FUNCTION_RUNTIME_NAME']);
$this->assertEquals('8.0', $output['APPWRITE_FUNCTION_RUNTIME_VERSION']);
@ -332,7 +332,7 @@ class FunctionsCustomClientTest extends Scope
$this->assertEquals(201, $function['headers']['status-code']);
$tag = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/tags', [
$deployment = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/deployments', [
'content-type' => 'multipart/form-data',
'x-appwrite-project' => $projectId,
'x-appwrite-key' => $apikey,
@ -341,19 +341,19 @@ class FunctionsCustomClientTest extends Scope
'code' => new CURLFile(realpath(__DIR__ . '/../../../resources/functions/php-fn.tar.gz'), 'application/x-gzip', 'php-fx.tar.gz'), //different tarball names intentional
]);
$tagId = $tag['body']['$id'] ?? '';
$deploymentId = $deployment['body']['$id'] ?? '';
$this->assertEquals(201, $tag['headers']['status-code']);
$this->assertEquals(201, $deployment['headers']['status-code']);
// Wait for tag to be built.
// Wait for deployment to be built.
sleep(5);
$function = $this->client->call(Client::METHOD_PATCH, '/functions/'.$functionId.'/tag', [
$function = $this->client->call(Client::METHOD_PATCH, '/functions/'.$functionId.'/deployment', [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-key' => $apikey,
], [
'tag' => $tagId,
'deployment' => $deploymentId,
]);
$this->assertEquals(200, $function['headers']['status-code']);
@ -371,7 +371,7 @@ class FunctionsCustomClientTest extends Scope
$this->assertEquals('completed', $execution['body']['status']);
$this->assertEquals($functionId, $output['APPWRITE_FUNCTION_ID']);
$this->assertEquals('Test', $output['APPWRITE_FUNCTION_NAME']);
$this->assertEquals($tagId, $output['APPWRITE_FUNCTION_TAG']);
$this->assertEquals($deploymentId, $output['APPWRITE_FUNCTION_DEPLOYMENT']);
$this->assertEquals('http', $output['APPWRITE_FUNCTION_TRIGGER']);
$this->assertEquals('PHP', $output['APPWRITE_FUNCTION_RUNTIME_NAME']);
$this->assertEquals('8.0', $output['APPWRITE_FUNCTION_RUNTIME_VERSION']);

View file

@ -48,7 +48,7 @@ class FunctionsCustomServerTest extends Scope
$this->assertEquals('php-8.0', $response1['body']['runtime']);
$this->assertIsInt($response1['body']['dateCreated']);
$this->assertIsInt($response1['body']['dateUpdated']);
$this->assertEquals('', $response1['body']['tag']);
$this->assertEquals('', $response1['body']['deployment']);
$this->assertEquals([
'funcKey1' => 'funcValue1',
'funcKey2' => 'funcValue2',
@ -249,7 +249,7 @@ class FunctionsCustomServerTest extends Scope
$this->assertEquals('Test1', $response1['body']['name']);
$this->assertIsInt($response1['body']['dateCreated']);
$this->assertIsInt($response1['body']['dateUpdated']);
$this->assertEquals('', $response1['body']['tag']);
$this->assertEquals('', $response1['body']['deployment']);
$this->assertEquals([
'key4' => 'value4',
'key5' => 'value5',
@ -272,12 +272,12 @@ class FunctionsCustomServerTest extends Scope
/**
* @depends testUpdate
*/
public function testCreateTag($data):array
public function testCreateDeployment($data):array
{
/**
* Test for SUCCESS
*/
$tag = $this->client->call(Client::METHOD_POST, '/functions/'.$data['functionId'].'/tags', array_merge([
$deployment = $this->client->call(Client::METHOD_POST, '/functions/'.$data['functionId'].'/deployments', array_merge([
'content-type' => 'multipart/form-data',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
@ -285,44 +285,44 @@ class FunctionsCustomServerTest extends Scope
'code' => new CURLFile(realpath(__DIR__ . '/../../../resources/functions/php.tar.gz'), 'application/x-gzip', 'php-fx.tar.gz'),
]);
$tagId = $tag['body']['$id'] ?? '';
$deploymentId = $deployment['body']['$id'] ?? '';
$this->assertEquals(201, $tag['headers']['status-code']);
$this->assertNotEmpty($tag['body']['$id']);
$this->assertIsInt($tag['body']['dateCreated']);
$this->assertEquals('index.php', $tag['body']['entrypoint']);
// $this->assertGreaterThan(10000, $tag['body']['size']);
$this->assertEquals(201, $deployment['headers']['status-code']);
$this->assertNotEmpty($deployment['body']['$id']);
$this->assertIsInt($deployment['body']['dateCreated']);
$this->assertEquals('index.php', $deployment['body']['entrypoint']);
// $this->assertGreaterThan(10000, $deployment['body']['size']);
// Wait for tag to build.
// Wait for deployment to build.
sleep(5);
/**
* Test for FAILURE
*/
return array_merge($data, ['tagId' => $tagId]);
return array_merge($data, ['deploymentId' => $deploymentId]);
}
/**
* @depends testCreateTag
* @depends testCreateDeployment
*/
public function testUpdateTag($data):array
public function testUpdateDeployment($data):array
{
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_PATCH, '/functions/'.$data['functionId'].'/tag', array_merge([
$response = $this->client->call(Client::METHOD_PATCH, '/functions/'.$data['functionId'].'/deployment', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'tag' => $data['tagId'],
'deployment' => $data['deploymentId'],
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertNotEmpty($response['body']['$id']);
$this->assertIsInt($response['body']['dateCreated']);
$this->assertIsInt($response['body']['dateUpdated']);
$this->assertEquals($data['tagId'], $response['body']['tag']);
$this->assertEquals($data['deploymentId'], $response['body']['deployment']);
/**
* Test for FAILURE
@ -332,7 +332,7 @@ class FunctionsCustomServerTest extends Scope
}
/**
* @depends testCreateTag
* @depends testCreateDeployment
*/
public function testListBuild(array $data):array
{
@ -364,27 +364,27 @@ class FunctionsCustomServerTest extends Scope
}
/**
* @depends testCreateTag
* @depends testCreateDeployment
*/
public function testListTags(array $data):array
public function testListDeployments(array $data):array
{
/**
* Test for SUCCESS
*/
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/tags', array_merge([
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/deployments', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals($function['headers']['status-code'], 200);
$this->assertEquals($function['body']['sum'], 1);
$this->assertIsArray($function['body']['tags']);
$this->assertCount(1, $function['body']['tags']);
$this->assertIsArray($function['body']['deployments']);
$this->assertCount(1, $function['body']['deployments']);
/**
* Test search queries
*/
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/tags', array_merge([
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/deployments', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders(), [
@ -393,11 +393,11 @@ class FunctionsCustomServerTest extends Scope
$this->assertEquals($function['headers']['status-code'], 200);
$this->assertEquals($function['body']['sum'], 1);
$this->assertIsArray($function['body']['tags']);
$this->assertCount(1, $function['body']['tags']);
$this->assertEquals($function['body']['tags'][0]['$id'], $data['tagId']);
$this->assertIsArray($function['body']['deployments']);
$this->assertCount(1, $function['body']['deployments']);
$this->assertEquals($function['body']['deployments'][0]['$id'], $data['deploymentId']);
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/tags', array_merge([
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/deployments', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders(), [
@ -406,11 +406,11 @@ class FunctionsCustomServerTest extends Scope
$this->assertEquals($function['headers']['status-code'], 200);
$this->assertEquals($function['body']['sum'], 1);
$this->assertIsArray($function['body']['tags']);
$this->assertCount(1, $function['body']['tags']);
$this->assertEquals($function['body']['tags'][0]['$id'], $data['tagId']);
$this->assertIsArray($function['body']['deployments']);
$this->assertCount(1, $function['body']['deployments']);
$this->assertEquals($function['body']['deployments'][0]['$id'], $data['deploymentId']);
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/tags', array_merge([
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/deployments', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders(), [
@ -419,22 +419,22 @@ class FunctionsCustomServerTest extends Scope
$this->assertEquals($function['headers']['status-code'], 200);
$this->assertEquals($function['body']['sum'], 1);
$this->assertIsArray($function['body']['tags']);
$this->assertCount(1, $function['body']['tags']);
$this->assertEquals($function['body']['tags'][0]['$id'], $data['tagId']);
$this->assertIsArray($function['body']['deployments']);
$this->assertCount(1, $function['body']['deployments']);
$this->assertEquals($function['body']['deployments'][0]['$id'], $data['deploymentId']);
return $data;
}
/**
* @depends testCreateTag
* @depends testCreateDeployment
*/
public function testGetTag(array $data):array
public function testGetDeployment(array $data):array
{
/**
* Test for SUCCESS
*/
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/tags/' . $data['tagId'], array_merge([
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/deployments/' . $data['deploymentId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
@ -444,7 +444,7 @@ class FunctionsCustomServerTest extends Scope
/**
* Test for FAILURE
*/
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/tags/x', array_merge([
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/deployments/x', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
@ -455,7 +455,7 @@ class FunctionsCustomServerTest extends Scope
}
/**
* @depends testUpdateTag
* @depends testUpdateDeployment
*/
public function testCreateExecution($data):array
{
@ -496,7 +496,7 @@ class FunctionsCustomServerTest extends Scope
$this->assertEquals('completed', $execution['body']['status']);
$this->assertEquals(200, $execution['body']['statusCode']);
$this->assertStringContainsString($execution['body']['functionId'], $execution['body']['stdout']);
$this->assertStringContainsString($data['tagId'], $execution['body']['stdout']);
$this->assertStringContainsString($data['deploymentId'], $execution['body']['stdout']);
$this->assertStringContainsString('Test1', $execution['body']['stdout']);
$this->assertStringContainsString('http', $execution['body']['stdout']);
$this->assertStringContainsString('PHP', $execution['body']['stdout']);
@ -567,7 +567,7 @@ class FunctionsCustomServerTest extends Scope
}
/**
* @depends testUpdateTag
* @depends testUpdateDeployment
*/
public function testSyncCreateExecution($data):array
{
@ -582,7 +582,7 @@ class FunctionsCustomServerTest extends Scope
]);
$this->assertEquals('completed', $execution['body']['status']);
$this->assertStringContainsString($data['tagId'], $execution['body']['response']);
$this->assertStringContainsString($data['deploymentId'], $execution['body']['response']);
$this->assertStringContainsString('Test1', $execution['body']['response']);
$this->assertStringContainsString('http', $execution['body']['response']);
$this->assertStringContainsString('PHP', $execution['body']['response']);
@ -625,12 +625,12 @@ class FunctionsCustomServerTest extends Scope
/**
* @depends testGetExecution
*/
public function testDeleteTag($data):array
public function testDeleteDeployment($data):array
{
/**
* Test for SUCCESS
*/
$function = $this->client->call(Client::METHOD_DELETE, '/functions/'.$data['functionId'].'/tags/' . $data['tagId'], array_merge([
$function = $this->client->call(Client::METHOD_DELETE, '/functions/'.$data['functionId'].'/deployments/' . $data['deploymentId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
@ -638,7 +638,7 @@ class FunctionsCustomServerTest extends Scope
$this->assertEquals(204, $function['headers']['status-code']);
$this->assertEmpty($function['body']);
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/tags/' . $data['tagId'], array_merge([
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/deployments/' . $data['deploymentId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
@ -653,7 +653,7 @@ class FunctionsCustomServerTest extends Scope
}
/**
* @depends testCreateTag
* @depends testCreateDeployment
*/
public function testDelete($data):array
{
@ -706,7 +706,7 @@ class FunctionsCustomServerTest extends Scope
$this->assertEquals(201, $function['headers']['status-code']);
$tag = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/tags', array_merge([
$deployment = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/deployments', array_merge([
'content-type' => 'multipart/form-data',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
@ -714,21 +714,21 @@ class FunctionsCustomServerTest extends Scope
'code' => new CURLFile($code, 'application/x-gzip', basename($code)),
]);
$tagId = $tag['body']['$id'] ?? '';
$this->assertEquals(201, $tag['headers']['status-code']);
$deploymentId = $deployment['body']['$id'] ?? '';
$this->assertEquals(201, $deployment['headers']['status-code']);
// Allow build step to run
sleep(5);
$tag = $this->client->call(Client::METHOD_PATCH, '/functions/'.$functionId.'/tag', array_merge([
$deployment = $this->client->call(Client::METHOD_PATCH, '/functions/'.$functionId.'/deployment', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'functionId' => $functionId,
'tag' => $tagId,
'deployment' => $deploymentId,
]);
$this->assertEquals(200, $tag['headers']['status-code']);
$this->assertEquals(200, $deployment['headers']['status-code']);
$execution = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/executions', array_merge([
'content-type' => 'application/json',
@ -789,7 +789,7 @@ class FunctionsCustomServerTest extends Scope
$this->assertEquals(201, $function['headers']['status-code']);
$tag = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/tags', array_merge([
$deployment = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/deployments', array_merge([
'content-type' => 'multipart/form-data',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
@ -797,20 +797,20 @@ class FunctionsCustomServerTest extends Scope
'code' => new CURLFile($code, 'application/x-gzip', basename($code)),
]);
$tagId = $tag['body']['$id'] ?? '';
$this->assertEquals(201, $tag['headers']['status-code']);
$deploymentId = $deployment['body']['$id'] ?? '';
$this->assertEquals(201, $deployment['headers']['status-code']);
// Allow build step to run
sleep(5);
$tag = $this->client->call(Client::METHOD_PATCH, '/functions/'.$functionId.'/tag', array_merge([
$deployment = $this->client->call(Client::METHOD_PATCH, '/functions/'.$functionId.'/deployment', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'tag' => $tagId,
'deployment' => $deploymentId,
]);
$this->assertEquals(200, $tag['headers']['status-code']);
$this->assertEquals(200, $deployment['headers']['status-code']);
$execution = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/executions', array_merge([
'content-type' => 'application/json',
@ -838,7 +838,7 @@ class FunctionsCustomServerTest extends Scope
$this->assertEquals('completed', $executions['body']['status']);
$this->assertEquals($functionId, $output['APPWRITE_FUNCTION_ID']);
$this->assertEquals('Test '.$name, $output['APPWRITE_FUNCTION_NAME']);
$this->assertEquals($tagId, $output['APPWRITE_FUNCTION_TAG']);
$this->assertEquals($deploymentId, $output['APPWRITE_FUNCTION_DEPLOYMENT']);
$this->assertEquals('http', $output['APPWRITE_FUNCTION_TRIGGER']);
$this->assertEquals('PHP', $output['APPWRITE_FUNCTION_RUNTIME_NAME']);
$this->assertEquals('8.0', $output['APPWRITE_FUNCTION_RUNTIME_VERSION']);

View file

@ -985,7 +985,7 @@ class RealtimeCustomClientTest extends Scope
$this->assertEquals($function['headers']['status-code'], 201);
$this->assertNotEmpty($function['body']['$id']);
$tag = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/tags', array_merge([
$deployment = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/deployments', array_merge([
'content-type' => 'multipart/form-data',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
@ -994,20 +994,20 @@ class RealtimeCustomClientTest extends Scope
'code' => new CURLFile(realpath(__DIR__ . '/../../../resources/functions/timeout.tar.gz'), 'application/x-gzip', 'php-fx.tar.gz'),
]);
$tagId = $tag['body']['$id'] ?? '';
$deploymentId = $deployment['body']['$id'] ?? '';
$this->assertEquals($tag['headers']['status-code'], 201);
$this->assertNotEmpty($tag['body']['$id']);
$this->assertEquals($deployment['headers']['status-code'], 201);
$this->assertNotEmpty($deployment['body']['$id']);
// Wait for tag to be built.
// Wait for deployment to be built.
sleep(5);
$response = $this->client->call(Client::METHOD_PATCH, '/functions/'.$functionId.'/tag', array_merge([
$response = $this->client->call(Client::METHOD_PATCH, '/functions/'.$functionId.'/deployment', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'tag' => $tagId,
'deployment' => $deploymentId,
]);
$this->assertEquals($response['headers']['status-code'], 200);

View file

@ -393,12 +393,12 @@ class WebhooksCustomServerTest extends Scope
/**
* @depends testUpdateFunction
*/
public function testCreateTag($data):array
public function testCreateDeployment($data):array
{
/**
* Test for SUCCESS
*/
$tag = $this->client->call(Client::METHOD_POST, '/functions/'.$data['functionId'].'/tags', array_merge([
$deployment = $this->client->call(Client::METHOD_POST, '/functions/'.$data['functionId'].'/deployments', array_merge([
'content-type' => 'multipart/form-data',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
@ -406,47 +406,45 @@ class WebhooksCustomServerTest extends Scope
'code' => new CURLFile(realpath(__DIR__ . '/../../../resources/functions/timeout.tar.gz'), 'application/x-gzip', 'php-fx.tar.gz'),
]);
$tagId = $tag['body']['$id'] ?? '';
$deploymentId = $deployment['body']['$id'] ?? '';
$this->assertEquals($tag['headers']['status-code'], 201);
$this->assertNotEmpty($tag['body']['$id']);
$this->assertEquals($deployment['headers']['status-code'], 201);
$this->assertNotEmpty($deployment['body']['$id']);
$webhook = $this->getLastRequest();
$this->assertEquals($webhook['method'], 'POST');
$this->assertEquals($webhook['headers']['Content-Type'], 'application/json');
$this->assertEquals($webhook['headers']['User-Agent'], 'Appwrite-Server vdev. Please report abuse at security@appwrite.io');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Event'], 'functions.tags.create');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Event'], 'functions.deployments.create');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], 'not-yet-implemented');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']);
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']);
/**
* Test for FAILURE
*/
sleep(5);
return array_merge($data, ['tagId' => $tagId]);
return array_merge($data, ['deploymentId' => $deploymentId]);
}
/**
* @depends testCreateTag
* @depends testCreateDeployment
*/
public function testUpdateTag($data):array
public function testUpdateDeployment($data):array
{
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_PATCH, '/functions/'.$data['functionId'].'/tag', array_merge([
$response = $this->client->call(Client::METHOD_PATCH, '/functions/'.$data['functionId'].'/deployment', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'tag' => $data['tagId'],
'deployment' => $data['deploymentId'],
]);
$this->assertEquals($response['headers']['status-code'], 200);
$this->assertNotEmpty($response['body']['$id']);
// Wait for tag to be built.
// Wait for deployment to be built.
sleep(5);
$webhook = $this->getLastRequest();
@ -454,7 +452,7 @@ class WebhooksCustomServerTest extends Scope
$this->assertEquals($webhook['method'], 'POST');
$this->assertEquals($webhook['headers']['Content-Type'], 'application/json');
$this->assertEquals($webhook['headers']['User-Agent'], 'Appwrite-Server vdev. Please report abuse at security@appwrite.io');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Event'], 'functions.tags.update');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Event'], 'functions.deployments.update');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], 'not-yet-implemented');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']);
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']);
@ -467,7 +465,7 @@ class WebhooksCustomServerTest extends Scope
}
/**
* @depends testUpdateTag
* @depends testUpdateDeployment
*/
public function testExecutions($data):array
{
@ -516,25 +514,25 @@ class WebhooksCustomServerTest extends Scope
/**
* @depends testExecutions
*/
public function testDeleteTag($data):array
public function testDeleteDeployment($data):array
{
/**
* Test for SUCCESS
*/
$tag = $this->client->call(Client::METHOD_DELETE, '/functions/'.$data['functionId'].'/tags/'.$data['tagId'], array_merge([
$deployment = $this->client->call(Client::METHOD_DELETE, '/functions/'.$data['functionId'].'/deployments/'.$data['deploymentId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals($tag['headers']['status-code'], 204);
$this->assertEmpty($tag['body']);
$this->assertEquals($deployment['headers']['status-code'], 204);
$this->assertEmpty($deployment['body']);
$webhook = $this->getLastRequest();
$this->assertEquals($webhook['method'], 'POST');
$this->assertEquals($webhook['headers']['Content-Type'], 'application/json');
$this->assertEquals($webhook['headers']['User-Agent'], 'Appwrite-Server vdev. Please report abuse at security@appwrite.io');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Event'], 'functions.tags.delete');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Event'], 'functions.deployments.delete');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Signature'], 'not-yet-implemented');
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Id'] ?? '', $this->getProject()['webhookId']);
$this->assertEquals($webhook['headers']['X-Appwrite-Webhook-Project-Id'] ?? '', $this->getProject()['$id']);
@ -547,7 +545,7 @@ class WebhooksCustomServerTest extends Scope
}
/**
* @depends testDeleteTag
* @depends testDeleteDeployment
*/
public function testDeleteFunction($data):array
{

View file

@ -4,7 +4,7 @@ return function ($request, $response) {
$response->json([
'APPWRITE_FUNCTION_ID' => $request->env['APPWRITE_FUNCTION_ID'],
'APPWRITE_FUNCTION_NAME' => $request->env['APPWRITE_FUNCTION_NAME'],
'APPWRITE_FUNCTION_TAG' => $request->env['APPWRITE_FUNCTION_TAG'],
'APPWRITE_FUNCTION_DEPLOYMENT' => $request->env['APPWRITE_FUNCTION_DEPLOYMENT'],
'APPWRITE_FUNCTION_TRIGGER' => $request->env['APPWRITE_FUNCTION_TRIGGER'],
'APPWRITE_FUNCTION_RUNTIME_NAME' => $request->env['APPWRITE_FUNCTION_RUNTIME_NAME'],
'APPWRITE_FUNCTION_RUNTIME_VERSION' => $request->env['APPWRITE_FUNCTION_RUNTIME_VERSION'],

Binary file not shown.

View file

@ -4,7 +4,7 @@ return function ($request, $response) {
return $response->json([
'APPWRITE_FUNCTION_ID' => $request->env['APPWRITE_FUNCTION_ID'],
'APPWRITE_FUNCTION_NAME' => $request->env['APPWRITE_FUNCTION_NAME'],
'APPWRITE_FUNCTION_TAG' => $request->env['APPWRITE_FUNCTION_TAG'],
'APPWRITE_FUNCTION_DEPLOYMENT' => $request->env['APPWRITE_FUNCTION_DEPLOYMENT'],
'APPWRITE_FUNCTION_TRIGGER' => $request->env['APPWRITE_FUNCTION_TRIGGER'],
'APPWRITE_FUNCTION_RUNTIME_NAME' => $request->env['APPWRITE_FUNCTION_RUNTIME_NAME'],
'APPWRITE_FUNCTION_RUNTIME_VERSION' => $request->env['APPWRITE_FUNCTION_RUNTIME_VERSION'],