mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Merge branch '1.6.x' into feat-1.5.x-mfa-emails
This commit is contained in:
+19
-16
@@ -16,22 +16,22 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Build Appwrite
|
||||
uses: docker/build-push-action@v3
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
push: false
|
||||
tags: ${{ env.IMAGE }}
|
||||
load: true
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
cache-from: type=gha,scope=appwrite
|
||||
cache-to: type=gha,mode=max,scope=appwrite
|
||||
outputs: type=docker,dest=/tmp/${{ env.IMAGE }}.tar
|
||||
build-args: |
|
||||
DEBUG=false
|
||||
@@ -39,9 +39,11 @@ jobs:
|
||||
VERSION=dev
|
||||
|
||||
- name: Cache Docker Image
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
key: ${{ env.CACHE_KEY }}
|
||||
restore-keys: |
|
||||
appwrite-dev-
|
||||
path: /tmp/${{ env.IMAGE }}.tar
|
||||
|
||||
unit_test:
|
||||
@@ -51,10 +53,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Load Cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
key: ${{ env.CACHE_KEY }}
|
||||
path: /tmp/${{ env.IMAGE }}.tar
|
||||
@@ -81,10 +83,10 @@ jobs:
|
||||
needs: setup
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Load Cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
key: ${{ env.CACHE_KEY }}
|
||||
path: /tmp/${{ env.IMAGE }}.tar
|
||||
@@ -113,6 +115,7 @@ jobs:
|
||||
Console,
|
||||
Databases,
|
||||
Functions,
|
||||
FunctionsSchedule,
|
||||
GraphQL,
|
||||
Health,
|
||||
Locale,
|
||||
@@ -128,10 +131,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Load Cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
key: ${{ env.CACHE_KEY }}
|
||||
path: /tmp/${{ env.IMAGE }}.tar
|
||||
@@ -141,7 +144,7 @@ jobs:
|
||||
run: |
|
||||
docker load --input /tmp/${{ env.IMAGE }}.tar
|
||||
docker compose up -d
|
||||
sleep 25
|
||||
sleep 30
|
||||
|
||||
- name: Run ${{matrix.service}} Tests
|
||||
run: docker compose exec -T appwrite test /usr/src/code/tests/e2e/Services/${{matrix.service}} --debug
|
||||
@@ -149,15 +152,15 @@ jobs:
|
||||
- name: Run ${{matrix.service}} Shared Tables Tests
|
||||
run: _APP_DATABASE_SHARED_TABLES=database_db_main docker compose exec -T appwrite test /usr/src/code/tests/e2e/Services/${{matrix.service}} --debug
|
||||
|
||||
benchamrking:
|
||||
benchmarking:
|
||||
name: Benchmark
|
||||
runs-on: ubuntu-latest
|
||||
needs: setup
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
- name: Load Cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
key: ${{ env.CACHE_KEY }}
|
||||
path: /tmp/${{ env.IMAGE }}.tar
|
||||
|
||||
@@ -4109,13 +4109,24 @@ $projectCollections = array_merge([
|
||||
'$id' => ID::custom('source'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 8192,
|
||||
'size' => 8192, // reduce size
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('destination'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false, // make true after patch script
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('credentials'),
|
||||
'type' => Database::VAR_STRING,
|
||||
@@ -4138,6 +4149,28 @@ $projectCollections = array_merge([
|
||||
'array' => true,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('resourceId'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('resourceType'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('statusCounters'),
|
||||
'type' => Database::VAR_STRING,
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
<?php
|
||||
|
||||
const APP_PLATFORM_SERVER = 'server';
|
||||
const APP_PLATFORM_CLIENT = 'client';
|
||||
const APP_PLATFORM_CONSOLE = 'console';
|
||||
|
||||
return [
|
||||
APP_PLATFORM_CLIENT => [
|
||||
'key' => APP_PLATFORM_CLIENT,
|
||||
|
||||
@@ -75,7 +75,7 @@ $admins = [
|
||||
'topics.write',
|
||||
'topics.read',
|
||||
'subscribers.write',
|
||||
'subscribers.read'
|
||||
'subscribers.read',
|
||||
];
|
||||
|
||||
return [
|
||||
|
||||
@@ -32948,6 +32948,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"size": {
|
||||
"type": "integer",
|
||||
"description": "Attribute size.",
|
||||
@@ -32967,6 +32977,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"size"
|
||||
]
|
||||
},
|
||||
@@ -33005,6 +33017,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"min": {
|
||||
"type": "integer",
|
||||
"description": "Minimum value to enforce for new documents.",
|
||||
@@ -33032,7 +33054,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeFloat": {
|
||||
@@ -33070,6 +33094,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"min": {
|
||||
"type": "number",
|
||||
"description": "Minimum value to enforce for new documents.",
|
||||
@@ -33097,7 +33131,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeBoolean": {
|
||||
@@ -33135,6 +33171,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"default": {
|
||||
"type": "boolean",
|
||||
"description": "Default value for attribute when not provided. Cannot be set when attribute is required.",
|
||||
@@ -33147,7 +33193,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeEmail": {
|
||||
@@ -33185,6 +33233,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -33203,6 +33261,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -33241,6 +33301,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"elements": {
|
||||
"type": "array",
|
||||
"description": "Array of elements in enumerated type.",
|
||||
@@ -33267,6 +33337,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"elements",
|
||||
"format"
|
||||
]
|
||||
@@ -33306,6 +33378,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -33324,6 +33406,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -33362,6 +33446,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -33380,6 +33474,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -33418,6 +33514,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "ISO 8601 format.",
|
||||
@@ -33436,6 +33542,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -33474,6 +33582,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"relatedCollection": {
|
||||
"type": "string",
|
||||
"description": "The ID of the related collection.",
|
||||
@@ -33511,6 +33629,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"relatedCollection",
|
||||
"relationType",
|
||||
"twoWay",
|
||||
@@ -33559,6 +33679,16 @@
|
||||
},
|
||||
"x-example": [],
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Index creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Index update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -33566,7 +33696,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"attributes"
|
||||
"attributes",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"document": {
|
||||
|
||||
@@ -23678,6 +23678,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"size": {
|
||||
"type": "integer",
|
||||
"description": "Attribute size.",
|
||||
@@ -23697,6 +23707,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"size"
|
||||
]
|
||||
},
|
||||
@@ -23735,6 +23747,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"min": {
|
||||
"type": "integer",
|
||||
"description": "Minimum value to enforce for new documents.",
|
||||
@@ -23762,7 +23784,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeFloat": {
|
||||
@@ -23800,6 +23824,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"min": {
|
||||
"type": "number",
|
||||
"description": "Minimum value to enforce for new documents.",
|
||||
@@ -23827,7 +23861,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeBoolean": {
|
||||
@@ -23865,6 +23901,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"default": {
|
||||
"type": "boolean",
|
||||
"description": "Default value for attribute when not provided. Cannot be set when attribute is required.",
|
||||
@@ -23877,7 +23923,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeEmail": {
|
||||
@@ -23915,6 +23963,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -23933,6 +23991,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -23971,6 +24031,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"elements": {
|
||||
"type": "array",
|
||||
"description": "Array of elements in enumerated type.",
|
||||
@@ -23997,6 +24067,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"elements",
|
||||
"format"
|
||||
]
|
||||
@@ -24036,6 +24108,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -24054,6 +24136,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -24092,6 +24176,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -24110,6 +24204,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -24148,6 +24244,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "ISO 8601 format.",
|
||||
@@ -24166,6 +24272,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -24204,6 +24312,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"relatedCollection": {
|
||||
"type": "string",
|
||||
"description": "The ID of the related collection.",
|
||||
@@ -24241,6 +24359,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"relatedCollection",
|
||||
"relationType",
|
||||
"twoWay",
|
||||
@@ -24289,6 +24409,16 @@
|
||||
},
|
||||
"x-example": [],
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Index creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Index update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -24296,7 +24426,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"attributes"
|
||||
"attributes",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"document": {
|
||||
|
||||
@@ -32948,6 +32948,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"size": {
|
||||
"type": "integer",
|
||||
"description": "Attribute size.",
|
||||
@@ -32967,6 +32977,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"size"
|
||||
]
|
||||
},
|
||||
@@ -33005,6 +33017,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"min": {
|
||||
"type": "integer",
|
||||
"description": "Minimum value to enforce for new documents.",
|
||||
@@ -33032,7 +33054,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeFloat": {
|
||||
@@ -33070,6 +33094,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"min": {
|
||||
"type": "number",
|
||||
"description": "Minimum value to enforce for new documents.",
|
||||
@@ -33097,7 +33131,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeBoolean": {
|
||||
@@ -33135,6 +33171,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"default": {
|
||||
"type": "boolean",
|
||||
"description": "Default value for attribute when not provided. Cannot be set when attribute is required.",
|
||||
@@ -33147,7 +33193,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeEmail": {
|
||||
@@ -33185,6 +33233,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -33203,6 +33261,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -33241,6 +33301,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"elements": {
|
||||
"type": "array",
|
||||
"description": "Array of elements in enumerated type.",
|
||||
@@ -33267,6 +33337,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"elements",
|
||||
"format"
|
||||
]
|
||||
@@ -33306,6 +33378,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -33324,6 +33406,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -33362,6 +33446,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -33380,6 +33474,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -33418,6 +33514,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "ISO 8601 format.",
|
||||
@@ -33436,6 +33542,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -33474,6 +33582,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"relatedCollection": {
|
||||
"type": "string",
|
||||
"description": "The ID of the related collection.",
|
||||
@@ -33511,6 +33629,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"relatedCollection",
|
||||
"relationType",
|
||||
"twoWay",
|
||||
@@ -33559,6 +33679,16 @@
|
||||
},
|
||||
"x-example": [],
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Index creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Index update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -33566,7 +33696,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"attributes"
|
||||
"attributes",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"document": {
|
||||
|
||||
@@ -23678,6 +23678,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"size": {
|
||||
"type": "integer",
|
||||
"description": "Attribute size.",
|
||||
@@ -23697,6 +23707,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"size"
|
||||
]
|
||||
},
|
||||
@@ -23735,6 +23747,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"min": {
|
||||
"type": "integer",
|
||||
"description": "Minimum value to enforce for new documents.",
|
||||
@@ -23762,7 +23784,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeFloat": {
|
||||
@@ -23800,6 +23824,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"min": {
|
||||
"type": "number",
|
||||
"description": "Minimum value to enforce for new documents.",
|
||||
@@ -23827,7 +23861,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeBoolean": {
|
||||
@@ -23865,6 +23901,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"default": {
|
||||
"type": "boolean",
|
||||
"description": "Default value for attribute when not provided. Cannot be set when attribute is required.",
|
||||
@@ -23877,7 +23923,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeEmail": {
|
||||
@@ -23915,6 +23963,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -23933,6 +23991,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -23971,6 +24031,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"elements": {
|
||||
"type": "array",
|
||||
"description": "Array of elements in enumerated type.",
|
||||
@@ -23997,6 +24067,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"elements",
|
||||
"format"
|
||||
]
|
||||
@@ -24036,6 +24108,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -24054,6 +24136,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -24092,6 +24176,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -24110,6 +24204,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -24148,6 +24244,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "ISO 8601 format.",
|
||||
@@ -24166,6 +24272,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -24204,6 +24312,16 @@
|
||||
"x-example": false,
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"relatedCollection": {
|
||||
"type": "string",
|
||||
"description": "The ID of the related collection.",
|
||||
@@ -24241,6 +24359,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"relatedCollection",
|
||||
"relationType",
|
||||
"twoWay",
|
||||
@@ -24289,6 +24409,16 @@
|
||||
},
|
||||
"x-example": [],
|
||||
"nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Index creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Index update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -24296,7 +24426,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"attributes"
|
||||
"attributes",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"document": {
|
||||
|
||||
@@ -33458,6 +33458,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"size": {
|
||||
"type": "integer",
|
||||
"description": "Attribute size.",
|
||||
@@ -33477,6 +33487,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"size"
|
||||
]
|
||||
},
|
||||
@@ -33515,6 +33527,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"min": {
|
||||
"type": "integer",
|
||||
"description": "Minimum value to enforce for new documents.",
|
||||
@@ -33542,7 +33564,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeFloat": {
|
||||
@@ -33580,6 +33604,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"min": {
|
||||
"type": "number",
|
||||
"description": "Minimum value to enforce for new documents.",
|
||||
@@ -33607,7 +33641,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeBoolean": {
|
||||
@@ -33645,6 +33681,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"default": {
|
||||
"type": "boolean",
|
||||
"description": "Default value for attribute when not provided. Cannot be set when attribute is required.",
|
||||
@@ -33657,7 +33703,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeEmail": {
|
||||
@@ -33695,6 +33743,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -33713,6 +33771,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -33751,6 +33811,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"elements": {
|
||||
"type": "array",
|
||||
"description": "Array of elements in enumerated type.",
|
||||
@@ -33777,6 +33847,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"elements",
|
||||
"format"
|
||||
]
|
||||
@@ -33816,6 +33888,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -33834,6 +33916,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -33872,6 +33956,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -33890,6 +33984,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -33928,6 +34024,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "ISO 8601 format.",
|
||||
@@ -33946,6 +34052,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -33984,6 +34092,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"relatedCollection": {
|
||||
"type": "string",
|
||||
"description": "The ID of the related collection.",
|
||||
@@ -34021,6 +34139,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"relatedCollection",
|
||||
"relationType",
|
||||
"twoWay",
|
||||
@@ -34069,6 +34189,16 @@
|
||||
},
|
||||
"x-example": [],
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Index creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Index update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -34076,7 +34206,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"attributes"
|
||||
"attributes",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"document": {
|
||||
|
||||
@@ -24167,6 +24167,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"size": {
|
||||
"type": "integer",
|
||||
"description": "Attribute size.",
|
||||
@@ -24186,6 +24196,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"size"
|
||||
]
|
||||
},
|
||||
@@ -24224,6 +24236,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"min": {
|
||||
"type": "integer",
|
||||
"description": "Minimum value to enforce for new documents.",
|
||||
@@ -24251,7 +24273,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeFloat": {
|
||||
@@ -24289,6 +24313,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"min": {
|
||||
"type": "number",
|
||||
"description": "Minimum value to enforce for new documents.",
|
||||
@@ -24316,7 +24350,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeBoolean": {
|
||||
@@ -24354,6 +24390,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"default": {
|
||||
"type": "boolean",
|
||||
"description": "Default value for attribute when not provided. Cannot be set when attribute is required.",
|
||||
@@ -24366,7 +24412,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeEmail": {
|
||||
@@ -24404,6 +24452,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -24422,6 +24480,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -24460,6 +24520,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"elements": {
|
||||
"type": "array",
|
||||
"description": "Array of elements in enumerated type.",
|
||||
@@ -24486,6 +24556,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"elements",
|
||||
"format"
|
||||
]
|
||||
@@ -24525,6 +24597,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -24543,6 +24625,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -24581,6 +24665,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -24599,6 +24693,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -24637,6 +24733,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "ISO 8601 format.",
|
||||
@@ -24655,6 +24761,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -24693,6 +24801,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"relatedCollection": {
|
||||
"type": "string",
|
||||
"description": "The ID of the related collection.",
|
||||
@@ -24730,6 +24848,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"relatedCollection",
|
||||
"relationType",
|
||||
"twoWay",
|
||||
@@ -24778,6 +24898,16 @@
|
||||
},
|
||||
"x-example": [],
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Index creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Index update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -24785,7 +24915,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"attributes"
|
||||
"attributes",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"document": {
|
||||
|
||||
@@ -33458,6 +33458,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"size": {
|
||||
"type": "integer",
|
||||
"description": "Attribute size.",
|
||||
@@ -33477,6 +33487,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"size"
|
||||
]
|
||||
},
|
||||
@@ -33515,6 +33527,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"min": {
|
||||
"type": "integer",
|
||||
"description": "Minimum value to enforce for new documents.",
|
||||
@@ -33542,7 +33564,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeFloat": {
|
||||
@@ -33580,6 +33604,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"min": {
|
||||
"type": "number",
|
||||
"description": "Minimum value to enforce for new documents.",
|
||||
@@ -33607,7 +33641,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeBoolean": {
|
||||
@@ -33645,6 +33681,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"default": {
|
||||
"type": "boolean",
|
||||
"description": "Default value for attribute when not provided. Cannot be set when attribute is required.",
|
||||
@@ -33657,7 +33703,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeEmail": {
|
||||
@@ -33695,6 +33743,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -33713,6 +33771,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -33751,6 +33811,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"elements": {
|
||||
"type": "array",
|
||||
"description": "Array of elements in enumerated type.",
|
||||
@@ -33777,6 +33847,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"elements",
|
||||
"format"
|
||||
]
|
||||
@@ -33816,6 +33888,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -33834,6 +33916,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -33872,6 +33956,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -33890,6 +33984,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -33928,6 +34024,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "ISO 8601 format.",
|
||||
@@ -33946,6 +34052,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -33984,6 +34092,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"relatedCollection": {
|
||||
"type": "string",
|
||||
"description": "The ID of the related collection.",
|
||||
@@ -34021,6 +34139,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"relatedCollection",
|
||||
"relationType",
|
||||
"twoWay",
|
||||
@@ -34069,6 +34189,16 @@
|
||||
},
|
||||
"x-example": [],
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Index creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Index update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -34076,7 +34206,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"attributes"
|
||||
"attributes",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"document": {
|
||||
|
||||
@@ -24167,6 +24167,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"size": {
|
||||
"type": "integer",
|
||||
"description": "Attribute size.",
|
||||
@@ -24186,6 +24196,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"size"
|
||||
]
|
||||
},
|
||||
@@ -24224,6 +24236,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"min": {
|
||||
"type": "integer",
|
||||
"description": "Minimum value to enforce for new documents.",
|
||||
@@ -24251,7 +24273,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeFloat": {
|
||||
@@ -24289,6 +24313,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"min": {
|
||||
"type": "number",
|
||||
"description": "Minimum value to enforce for new documents.",
|
||||
@@ -24316,7 +24350,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeBoolean": {
|
||||
@@ -24354,6 +24390,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"default": {
|
||||
"type": "boolean",
|
||||
"description": "Default value for attribute when not provided. Cannot be set when attribute is required.",
|
||||
@@ -24366,7 +24412,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"required"
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"attributeEmail": {
|
||||
@@ -24404,6 +24452,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -24422,6 +24480,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -24460,6 +24520,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"elements": {
|
||||
"type": "array",
|
||||
"description": "Array of elements in enumerated type.",
|
||||
@@ -24486,6 +24556,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"elements",
|
||||
"format"
|
||||
]
|
||||
@@ -24525,6 +24597,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -24543,6 +24625,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -24581,6 +24665,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "String format.",
|
||||
@@ -24599,6 +24693,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -24637,6 +24733,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"description": "ISO 8601 format.",
|
||||
@@ -24655,6 +24761,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"format"
|
||||
]
|
||||
},
|
||||
@@ -24693,6 +24801,16 @@
|
||||
"x-example": false,
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Attribute update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"relatedCollection": {
|
||||
"type": "string",
|
||||
"description": "The ID of the related collection.",
|
||||
@@ -24730,6 +24848,8 @@
|
||||
"status",
|
||||
"error",
|
||||
"required",
|
||||
"$createdAt",
|
||||
"$updatedAt",
|
||||
"relatedCollection",
|
||||
"relationType",
|
||||
"twoWay",
|
||||
@@ -24778,6 +24898,16 @@
|
||||
},
|
||||
"x-example": [],
|
||||
"x-nullable": true
|
||||
},
|
||||
"$createdAt": {
|
||||
"type": "string",
|
||||
"description": "Index creation date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
},
|
||||
"$updatedAt": {
|
||||
"type": "string",
|
||||
"description": "Index update date in ISO 8601 format.",
|
||||
"x-example": "2020-10-15T06:38:00.000+00:00"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
@@ -24785,7 +24915,9 @@
|
||||
"type",
|
||||
"status",
|
||||
"error",
|
||||
"attributes"
|
||||
"attributes",
|
||||
"$createdAt",
|
||||
"$updatedAt"
|
||||
]
|
||||
},
|
||||
"document": {
|
||||
|
||||
@@ -2509,7 +2509,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/indexes')
|
||||
'required' => true,
|
||||
'array' => false,
|
||||
'default' => null,
|
||||
'size' => 36
|
||||
'size' => Database::LENGTH_KEY
|
||||
];
|
||||
|
||||
$oldAttributes[] = [
|
||||
|
||||
@@ -60,6 +60,7 @@ App::post('/v1/migrations/appwrite')
|
||||
'status' => 'pending',
|
||||
'stage' => 'init',
|
||||
'source' => Appwrite::getName(),
|
||||
'destination' => Appwrite::getName(),
|
||||
'credentials' => [
|
||||
'endpoint' => $endpoint,
|
||||
'projectId' => $projectId,
|
||||
@@ -164,6 +165,7 @@ App::post('/v1/migrations/firebase/oauth')
|
||||
'status' => 'pending',
|
||||
'stage' => 'init',
|
||||
'source' => Firebase::getName(),
|
||||
'destination' => Appwrite::getName(),
|
||||
'credentials' => [
|
||||
'serviceAccount' => json_encode($serviceAccount),
|
||||
],
|
||||
@@ -224,6 +226,7 @@ App::post('/v1/migrations/firebase')
|
||||
'status' => 'pending',
|
||||
'stage' => 'init',
|
||||
'source' => Firebase::getName(),
|
||||
'destination' => Appwrite::getName(),
|
||||
'credentials' => [
|
||||
'serviceAccount' => $serviceAccount,
|
||||
],
|
||||
@@ -279,6 +282,7 @@ App::post('/v1/migrations/supabase')
|
||||
'status' => 'pending',
|
||||
'stage' => 'init',
|
||||
'source' => Supabase::getName(),
|
||||
'destination' => Appwrite::getName(),
|
||||
'credentials' => [
|
||||
'endpoint' => $endpoint,
|
||||
'apiKey' => $apiKey,
|
||||
@@ -340,6 +344,7 @@ App::post('/v1/migrations/nhost')
|
||||
'status' => 'pending',
|
||||
'stage' => 'init',
|
||||
'source' => NHost::getName(),
|
||||
'destination' => Appwrite::getName(),
|
||||
'credentials' => [
|
||||
'subdomain' => $subdomain,
|
||||
'region' => $region,
|
||||
|
||||
@@ -923,6 +923,7 @@ App::delete('/v1/projects/:projectId')
|
||||
}
|
||||
|
||||
$queueForDeletes
|
||||
->setProject($project)
|
||||
->setType(DELETE_TYPE_DOCUMENT)
|
||||
->setDocument($project);
|
||||
|
||||
|
||||
+5
-2
@@ -152,6 +152,9 @@ const APP_HOSTNAME_INTERNAL = 'appwrite';
|
||||
const APP_FUNCTION_SPECIFICATION_DEFAULT = Specification::S_05VCPU_512MB;
|
||||
const APP_FUNCTION_CPUS_DEFAULT = 0.5;
|
||||
const APP_FUNCTION_MEMORY_DEFAULT = 512;
|
||||
const APP_PLATFORM_SERVER = 'server';
|
||||
const APP_PLATFORM_CLIENT = 'client';
|
||||
const APP_PLATFORM_CONSOLE = 'console';
|
||||
|
||||
// Database Reconnect
|
||||
const DATABASE_RECONNECT_SLEEP = 2;
|
||||
@@ -1525,9 +1528,9 @@ App::setResource('deviceForBuilds', function ($project) {
|
||||
return getDevice(APP_STORAGE_BUILDS . '/app-' . $project->getId());
|
||||
}, ['project']);
|
||||
|
||||
function getDevice($root): Device
|
||||
function getDevice(string $root, string $connection = ''): Device
|
||||
{
|
||||
$connection = System::getEnv('_APP_CONNECTIONS_STORAGE', '');
|
||||
$connection = !empty($connection) ? $connection : System::getEnv('_APP_CONNECTIONS_STORAGE', '');
|
||||
|
||||
if (!empty($connection)) {
|
||||
$acl = 'private';
|
||||
|
||||
+11
-4
@@ -40,7 +40,7 @@ require_once __DIR__ . '/init.php';
|
||||
Runtime::enableCoroutine(SWOOLE_HOOK_ALL);
|
||||
|
||||
// Allows overriding
|
||||
if (!function_exists("getConsoleDB")) {
|
||||
if (!function_exists('getConsoleDB')) {
|
||||
function getConsoleDB(): Database
|
||||
{
|
||||
global $register;
|
||||
@@ -66,7 +66,7 @@ if (!function_exists("getConsoleDB")) {
|
||||
}
|
||||
|
||||
// Allows overriding
|
||||
if (!function_exists("getProjectDB")) {
|
||||
if (!function_exists('getProjectDB')) {
|
||||
function getProjectDB(Document $project): Database
|
||||
{
|
||||
global $register;
|
||||
@@ -113,7 +113,7 @@ if (!function_exists("getProjectDB")) {
|
||||
}
|
||||
|
||||
// Allows overriding
|
||||
if (!function_exists("getCache")) {
|
||||
if (!function_exists('getCache')) {
|
||||
function getCache(): Cache
|
||||
{
|
||||
global $register;
|
||||
@@ -135,7 +135,14 @@ if (!function_exists("getCache")) {
|
||||
}
|
||||
}
|
||||
|
||||
$realtime = new Realtime();
|
||||
if (!function_exists('getRealtime')) {
|
||||
function getRealtime(): Realtime
|
||||
{
|
||||
return new Realtime();
|
||||
}
|
||||
}
|
||||
|
||||
$realtime = getRealtime();
|
||||
|
||||
/**
|
||||
* Table for statistics across all workers.
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@ Server::setResource('project', function (Message $message, Database $dbForConsol
|
||||
$payload = $message->getPayload() ?? [];
|
||||
$project = new Document($payload['project'] ?? []);
|
||||
|
||||
if ($project->getId() === 'console') {
|
||||
if ($project->getId() === 'console' || $project->isEmpty() || ! empty($project->getInternalId())) {
|
||||
return $project;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@
|
||||
"utopia-php/locale": "0.4.*",
|
||||
"utopia-php/logger": "0.6.*",
|
||||
"utopia-php/messaging": "0.12.*",
|
||||
"utopia-php/migration": "0.5.*",
|
||||
"utopia-php/migration": "0.6.*",
|
||||
"utopia-php/orchestration": "0.9.*",
|
||||
"utopia-php/platform": "0.7.*",
|
||||
"utopia-php/pools": "0.5.*",
|
||||
|
||||
Generated
+29
-20
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "66e31af1f7d0d1617694a1c5a975f887",
|
||||
"content-hash": "1884e3a2966762c4a955842426b64f6c",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
@@ -65,16 +65,16 @@
|
||||
},
|
||||
{
|
||||
"name": "appwrite/appwrite",
|
||||
"version": "10.1.0",
|
||||
"version": "11.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/sdk-for-php.git",
|
||||
"reference": "da579af70723cfc117b5af84375bdef117e27312"
|
||||
"reference": "1d043f543acdb17b9fdb440b1b2dd208e400bad3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-for-php/zipball/da579af70723cfc117b5af84375bdef117e27312",
|
||||
"reference": "da579af70723cfc117b5af84375bdef117e27312",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-for-php/zipball/1d043f543acdb17b9fdb440b1b2dd208e400bad3",
|
||||
"reference": "1d043f543acdb17b9fdb440b1b2dd208e400bad3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -83,7 +83,8 @@
|
||||
"php": ">=7.1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "3.7.35"
|
||||
"mockery/mockery": "^1.6.6",
|
||||
"phpunit/phpunit": "^10"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -99,10 +100,10 @@
|
||||
"support": {
|
||||
"email": "team@appwrite.io",
|
||||
"issues": "https://github.com/appwrite/sdk-for-php/issues",
|
||||
"source": "https://github.com/appwrite/sdk-for-php/tree/10.1.0",
|
||||
"source": "https://github.com/appwrite/sdk-for-php/tree/11.1.0",
|
||||
"url": "https://appwrite.io/support"
|
||||
},
|
||||
"time": "2023-11-20T09:56:12+00:00"
|
||||
"time": "2024-06-26T07:03:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "appwrite/php-clamav",
|
||||
@@ -2174,27 +2175,35 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/migration",
|
||||
"version": "0.5.3",
|
||||
"version": "0.6.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/migration.git",
|
||||
"reference": "b30e7834da69e25084b0c8e9ba29e4a7b54c6eb6"
|
||||
"reference": "e43ef283f1386084e11d1ffe093fb6c6d7a6ce6c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/migration/zipball/b30e7834da69e25084b0c8e9ba29e4a7b54c6eb6",
|
||||
"reference": "b30e7834da69e25084b0c8e9ba29e4a7b54c6eb6",
|
||||
"url": "https://api.github.com/repos/utopia-php/migration/zipball/e43ef283f1386084e11d1ffe093fb6c6d7a6ce6c",
|
||||
"reference": "e43ef283f1386084e11d1ffe093fb6c6d7a6ce6c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"appwrite/appwrite": "10.1.0",
|
||||
"php": "8.*"
|
||||
"appwrite/appwrite": "11.1.*",
|
||||
"ext-curl": "*",
|
||||
"ext-openssl": "*",
|
||||
"php": "8.3.*",
|
||||
"utopia-php/database": "0.53.*",
|
||||
"utopia-php/dsn": "0.2.*",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
"utopia-php/storage": "0.18.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.*",
|
||||
"phpunit/phpunit": "9.*",
|
||||
"utopia-php/cli": "^0.18.0",
|
||||
"vlucas/phpdotenv": "5.*"
|
||||
"ext-pdo": "*",
|
||||
"laravel/pint": "1.17.*",
|
||||
"phpstan/phpstan": "1.11.*",
|
||||
"phpunit/phpunit": "11.2.*",
|
||||
"utopia-php/cli": "0.16.*",
|
||||
"vlucas/phpdotenv": "5.6.*"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -2216,9 +2225,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/migration/issues",
|
||||
"source": "https://github.com/utopia-php/migration/tree/0.5.3"
|
||||
"source": "https://github.com/utopia-php/migration/tree/0.6.4"
|
||||
},
|
||||
"time": "2024-09-10T10:45:18+00:00"
|
||||
"time": "2024-10-02T15:16:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/mongo",
|
||||
|
||||
@@ -81,7 +81,7 @@ class Migration extends Event
|
||||
return $client->enqueue([
|
||||
'project' => $this->project,
|
||||
'user' => $this->user,
|
||||
'migration' => $this->migration
|
||||
'migration' => $this->migration,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,7 +243,11 @@ class Realtime extends Adapter
|
||||
* @param string $event
|
||||
* @param Document $payload
|
||||
* @param Document|null $project
|
||||
* @param Document|null $database
|
||||
* @param Document|null $collection
|
||||
* @param Document|null $bucket
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function fromPayload(string $event, Document $payload, Document $project = null, Document $database = null, Document $collection = null, Document $bucket = null): array
|
||||
{
|
||||
@@ -262,6 +266,7 @@ class Realtime extends Adapter
|
||||
break;
|
||||
case 'rules':
|
||||
$channels[] = 'console';
|
||||
$channels[] = 'projects.' . $project->getId();
|
||||
$projectId = 'console';
|
||||
$roles = [Role::team($project->getAttribute('teamId'))->toString()];
|
||||
break;
|
||||
@@ -280,6 +285,7 @@ class Realtime extends Adapter
|
||||
case 'databases':
|
||||
if (in_array($parts[4] ?? [], ['attributes', 'indexes'])) {
|
||||
$channels[] = 'console';
|
||||
$channels[] = 'projects.' . $project->getId();
|
||||
$projectId = 'console';
|
||||
$roles = [Role::team($project->getAttribute('teamId'))->toString()];
|
||||
} elseif (($parts[4] ?? '') === 'documents') {
|
||||
@@ -319,6 +325,7 @@ class Realtime extends Adapter
|
||||
if ($parts[2] === 'executions') {
|
||||
if (!empty($payload->getRead())) {
|
||||
$channels[] = 'console';
|
||||
$channels[] = 'projects.' . $project->getId();
|
||||
$channels[] = 'executions';
|
||||
$channels[] = 'executions.' . $payload->getId();
|
||||
$channels[] = 'functions.' . $payload->getAttribute('functionId');
|
||||
@@ -326,6 +333,7 @@ class Realtime extends Adapter
|
||||
}
|
||||
} elseif ($parts[2] === 'deployments') {
|
||||
$channels[] = 'console';
|
||||
$channels[] = 'projects.' . $project->getId();
|
||||
$projectId = 'console';
|
||||
$roles = [Role::team($project->getAttribute('teamId'))->toString()];
|
||||
}
|
||||
@@ -333,6 +341,7 @@ class Realtime extends Adapter
|
||||
break;
|
||||
case 'migrations':
|
||||
$channels[] = 'console';
|
||||
$channels[] = 'projects.' . $project->getId();
|
||||
$projectId = 'console';
|
||||
$roles = [Role::team($project->getAttribute('teamId'))->toString()];
|
||||
break;
|
||||
|
||||
@@ -49,12 +49,7 @@ class Maintenance extends Action
|
||||
$this->foreachProject($dbForConsole, function (Document $project) use ($queueForDeletes, $usageStatsRetentionHourly) {
|
||||
$queueForDeletes->setProject($project);
|
||||
|
||||
$this->notifyDeleteTargets($queueForDeletes);
|
||||
$this->notifyDeleteExecutionLogs($queueForDeletes);
|
||||
$this->notifyDeleteAbuseLogs($queueForDeletes);
|
||||
$this->notifyDeleteAuditLogs($queueForDeletes);
|
||||
$this->notifyDeleteUsageStats($usageStatsRetentionHourly, $queueForDeletes);
|
||||
$this->notifyDeleteExpiredSessions($queueForDeletes);
|
||||
$this->notifyProjects($queueForDeletes, $usageStatsRetentionHourly);
|
||||
});
|
||||
|
||||
$this->notifyDeleteConnections($queueForDeletes);
|
||||
@@ -64,6 +59,19 @@ class Maintenance extends Action
|
||||
}, $interval, $delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to allow sub-classes to extend project-level maintenance functionality.
|
||||
*/
|
||||
protected function notifyProjects(Delete $queueForDeletes, int $usageStatsRetentionHourly): void
|
||||
{
|
||||
$this->notifyDeleteTargets($queueForDeletes);
|
||||
$this->notifyDeleteExecutionLogs($queueForDeletes);
|
||||
$this->notifyDeleteAbuseLogs($queueForDeletes);
|
||||
$this->notifyDeleteAuditLogs($queueForDeletes);
|
||||
$this->notifyDeleteUsageStats($usageStatsRetentionHourly, $queueForDeletes);
|
||||
$this->notifyDeleteExpiredSessions($queueForDeletes);
|
||||
}
|
||||
|
||||
protected function foreachProject(Database $dbForConsole, callable $callback): void
|
||||
{
|
||||
// TODO: @Meldiron name of this method no longer matches. It does not delete, and it gives whole document
|
||||
|
||||
@@ -24,11 +24,8 @@ abstract class ScheduleBase extends Action
|
||||
|
||||
abstract public static function getName(): string;
|
||||
abstract public static function getSupportedResource(): string;
|
||||
|
||||
abstract protected function enqueueResources(
|
||||
Group $pools,
|
||||
Database $dbForConsole
|
||||
);
|
||||
abstract public static function getCollectionId(): string;
|
||||
abstract protected function enqueueResources(Group $pools, Database $dbForConsole, callable $getProjectDB): void;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
@@ -62,14 +59,8 @@ abstract class ScheduleBase extends Action
|
||||
$getSchedule = function (Document $schedule) use ($dbForConsole, $getProjectDB): array {
|
||||
$project = $dbForConsole->getDocument('projects', $schedule->getAttribute('projectId'));
|
||||
|
||||
$collectionId = match ($schedule->getAttribute('resourceType')) {
|
||||
'function' => 'functions',
|
||||
'message' => 'messages',
|
||||
'execution' => 'executions'
|
||||
};
|
||||
|
||||
$resource = $getProjectDB($project)->getDocument(
|
||||
$collectionId,
|
||||
static::getCollectionId(),
|
||||
$schedule->getAttribute('resourceId')
|
||||
);
|
||||
|
||||
@@ -113,12 +104,7 @@ abstract class ScheduleBase extends Action
|
||||
try {
|
||||
$this->schedules[$document->getInternalId()] = $getSchedule($document);
|
||||
} catch (\Throwable $th) {
|
||||
$collectionId = match ($document->getAttribute('resourceType')) {
|
||||
'function' => 'functions',
|
||||
'message' => 'messages',
|
||||
'execution' => 'executions'
|
||||
};
|
||||
|
||||
$collectionId = static::getCollectionId();
|
||||
Console::error("Failed to load schedule for project {$document['projectId']} {$collectionId} {$document['resourceId']}");
|
||||
Console::error($th->getMessage());
|
||||
}
|
||||
@@ -133,7 +119,7 @@ abstract class ScheduleBase extends Action
|
||||
|
||||
Console::success("Starting timers at " . DateTime::now());
|
||||
|
||||
run(function () use ($dbForConsole, &$lastSyncUpdate, $getSchedule, $pools) {
|
||||
run(function () use ($dbForConsole, &$lastSyncUpdate, $getSchedule, $pools, $getProjectDB) {
|
||||
/**
|
||||
* The timer synchronize $schedules copy with database collection.
|
||||
*/
|
||||
@@ -172,10 +158,10 @@ abstract class ScheduleBase extends Action
|
||||
$new = \strtotime($document['resourceUpdatedAt']);
|
||||
|
||||
if (!$document['active']) {
|
||||
Console::info("Removing: {$document['resourceId']}");
|
||||
Console::info("Removing: {$document['resourceType']}::{$document['resourceId']}");
|
||||
unset($this->schedules[$document->getInternalId()]);
|
||||
} elseif ($new !== $org) {
|
||||
Console::info("Updating: {$document['resourceId']}");
|
||||
Console::info("Updating: {$document['resourceType']}::{$document['resourceId']}");
|
||||
$this->schedules[$document->getInternalId()] = $getSchedule($document);
|
||||
}
|
||||
}
|
||||
@@ -193,10 +179,10 @@ abstract class ScheduleBase extends Action
|
||||
|
||||
Timer::tick(
|
||||
static::ENQUEUE_TIMER * 1000,
|
||||
fn () => $this->enqueueResources($pools, $dbForConsole)
|
||||
fn () => $this->enqueueResources($pools, $dbForConsole, $getProjectDB)
|
||||
);
|
||||
|
||||
$this->enqueueResources($pools, $dbForConsole);
|
||||
$this->enqueueResources($pools, $dbForConsole, $getProjectDB);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,12 @@ class ScheduleExecutions extends ScheduleBase
|
||||
return 'execution';
|
||||
}
|
||||
|
||||
protected function enqueueResources(Group $pools, Database $dbForConsole): void
|
||||
public static function getCollectionId(): string
|
||||
{
|
||||
return 'executions';
|
||||
}
|
||||
|
||||
protected function enqueueResources(Group $pools, Database $dbForConsole, callable $getProjectDB): void
|
||||
{
|
||||
$queue = $pools->get('queue')->pop();
|
||||
$connection = $queue->getResource();
|
||||
|
||||
@@ -26,7 +26,12 @@ class ScheduleFunctions extends ScheduleBase
|
||||
return 'function';
|
||||
}
|
||||
|
||||
protected function enqueueResources(Group $pools, Database $dbForConsole): void
|
||||
public static function getCollectionId(): string
|
||||
{
|
||||
return 'functions';
|
||||
}
|
||||
|
||||
protected function enqueueResources(Group $pools, Database $dbForConsole, callable $getProjectDB): void
|
||||
{
|
||||
$timerStart = \microtime(true);
|
||||
$time = DateTime::now();
|
||||
|
||||
@@ -21,7 +21,12 @@ class ScheduleMessages extends ScheduleBase
|
||||
return 'message';
|
||||
}
|
||||
|
||||
protected function enqueueResources(Group $pools, Database $dbForConsole): void
|
||||
public static function getCollectionId(): string
|
||||
{
|
||||
return 'messages';
|
||||
}
|
||||
|
||||
protected function enqueueResources(Group $pools, Database $dbForConsole, callable $getProjectDB): void
|
||||
{
|
||||
foreach ($this->schedules as $schedule) {
|
||||
if (!$schedule['active']) {
|
||||
|
||||
@@ -5,9 +5,11 @@ namespace Appwrite\Platform\Tasks;
|
||||
use Appwrite\Specification\Format\OpenAPI3;
|
||||
use Appwrite\Specification\Format\Swagger2;
|
||||
use Appwrite\Specification\Specification;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Appwrite\Utopia\Request as AppwriteRequest;
|
||||
use Appwrite\Utopia\Response as AppwriteResponse;
|
||||
use Exception;
|
||||
use Swoole\Http\Response as HttpResponse;
|
||||
use Swoole\Http\Request as SwooleRequest;
|
||||
use Swoole\Http\Response as SwooleResponse;
|
||||
use Utopia\App;
|
||||
use Utopia\Cache\Adapter\None;
|
||||
use Utopia\Cache\Cache;
|
||||
@@ -17,7 +19,8 @@ use Utopia\Database\Adapter\MySQL;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Registry\Registry;
|
||||
use Utopia\Request;
|
||||
use Utopia\Request as UtopiaRequest;
|
||||
use Utopia\Response as UtopiaResponse;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\WhiteList;
|
||||
@@ -29,6 +32,16 @@ class Specs extends Action
|
||||
return 'specs';
|
||||
}
|
||||
|
||||
public function getRequest(): UtopiaRequest
|
||||
{
|
||||
return new AppwriteRequest(new SwooleRequest());
|
||||
}
|
||||
|
||||
public function getResponse(): UtopiaResponse
|
||||
{
|
||||
return new AppwriteResponse(new SwooleResponse());
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
@@ -42,11 +55,11 @@ class Specs extends Action
|
||||
public function action(string $version, string $mode, Registry $register): void
|
||||
{
|
||||
$appRoutes = App::getRoutes();
|
||||
$response = new Response(new HttpResponse());
|
||||
$response = $this->getResponse();
|
||||
$mocks = ($mode === 'mocks');
|
||||
|
||||
// Mock dependencies
|
||||
App::setResource('request', fn () => new Request());
|
||||
App::setResource('request', fn () => $this->getRequest());
|
||||
App::setResource('response', fn () => $response);
|
||||
App::setResource('dbForConsole', fn () => new Database(new MySQL(''), new Cache(new None())));
|
||||
App::setResource('dbForProject', fn () => new Database(new MySQL(''), new Cache(new None())));
|
||||
@@ -183,10 +196,8 @@ class Specs extends Action
|
||||
case APP_AUTH_TYPE_SESSION:
|
||||
$sdkPlatforms[] = APP_PLATFORM_CLIENT;
|
||||
break;
|
||||
case APP_AUTH_TYPE_KEY:
|
||||
$sdkPlatforms[] = APP_PLATFORM_SERVER;
|
||||
break;
|
||||
case APP_AUTH_TYPE_JWT:
|
||||
case APP_AUTH_TYPE_KEY:
|
||||
$sdkPlatforms[] = APP_PLATFORM_SERVER;
|
||||
break;
|
||||
case APP_AUTH_TYPE_ADMIN:
|
||||
|
||||
@@ -480,6 +480,7 @@ class Deletes extends Action
|
||||
private function deleteProject(Database $dbForConsole, callable $getProjectDB, Device $deviceForFiles, Device $deviceForFunctions, Device $deviceForBuilds, Device $deviceForCache, Document $document): void
|
||||
{
|
||||
$projectInternalId = $document->getInternalId();
|
||||
$projectId = $document->getId();
|
||||
|
||||
try {
|
||||
$dsn = new DSN($document->getAttribute('database', 'console'));
|
||||
@@ -568,6 +569,11 @@ class Deletes extends Action
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
], $dbForConsole);
|
||||
|
||||
// Delete Schedules (No projectInternalId in this collection)
|
||||
$this->deleteByGroup('schedules', [
|
||||
Query::equal('projectId', [$projectId]),
|
||||
], $dbForConsole);
|
||||
|
||||
// Delete metadata table
|
||||
if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) {
|
||||
$dbForProject->deleteCollection('_metadata');
|
||||
@@ -966,7 +972,7 @@ class Deletes extends Action
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
private function deleteByGroup(string $collection, array $queries, Database $database, callable $callback = null): void
|
||||
protected function deleteByGroup(string $collection, array $queries, Database $database, callable $callback = null): void
|
||||
{
|
||||
$count = 0;
|
||||
$chunk = 0;
|
||||
@@ -1008,7 +1014,7 @@ class Deletes extends Action
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
private function listByGroup(string $collection, array $queries, Database $database, callable $callback = null): void
|
||||
protected function listByGroup(string $collection, array $queries, Database $database, callable $callback = null): void
|
||||
{
|
||||
$count = 0;
|
||||
$chunk = 0;
|
||||
|
||||
@@ -587,7 +587,8 @@ class Functions extends Action
|
||||
$target = Realtime::fromPayload(
|
||||
// Pass first, most verbose event pattern
|
||||
event: $allEvents[0],
|
||||
payload: $execution
|
||||
payload: $execution,
|
||||
project: $project
|
||||
);
|
||||
Realtime::send(
|
||||
projectId: 'console',
|
||||
|
||||
@@ -8,6 +8,7 @@ use Appwrite\Permission;
|
||||
use Appwrite\Role;
|
||||
use Exception;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception\Authorization;
|
||||
@@ -16,11 +17,11 @@ use Utopia\Database\Exception\Restricted;
|
||||
use Utopia\Database\Exception\Structure;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Logger\Log;
|
||||
use Utopia\Logger\Log\Breadcrumb;
|
||||
use Utopia\Migration\Destinations\Appwrite as DestinationsAppwrite;
|
||||
use Utopia\Migration\Destination;
|
||||
use Utopia\Migration\Destinations\Appwrite as DestinationAppwrite;
|
||||
use Utopia\Migration\Exception as MigrationException;
|
||||
use Utopia\Migration\Source;
|
||||
use Utopia\Migration\Sources\Appwrite;
|
||||
use Utopia\Migration\Sources\Appwrite as SourceAppwrite;
|
||||
use Utopia\Migration\Sources\Firebase;
|
||||
use Utopia\Migration\Sources\NHost;
|
||||
use Utopia\Migration\Sources\Supabase;
|
||||
@@ -30,8 +31,11 @@ use Utopia\Queue\Message;
|
||||
|
||||
class Migrations extends Action
|
||||
{
|
||||
private ?Database $dbForProject = null;
|
||||
private ?Database $dbForConsole = null;
|
||||
protected Database $dbForProject;
|
||||
|
||||
protected Database $dbForConsole;
|
||||
|
||||
protected Document $project;
|
||||
|
||||
public static function getName(): string
|
||||
{
|
||||
@@ -53,11 +57,6 @@ class Migrations extends Action
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Message $message
|
||||
* @param Database $dbForProject
|
||||
* @param Database $dbForConsole
|
||||
* @param Log $log
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public function action(Message $message, Database $dbForProject, Database $dbForConsole, Log $log): void
|
||||
@@ -78,6 +77,7 @@ class Migrations extends Action
|
||||
|
||||
$this->dbForProject = $dbForProject;
|
||||
$this->dbForConsole = $dbForConsole;
|
||||
$this->project = $project;
|
||||
|
||||
/**
|
||||
* Handle Event execution.
|
||||
@@ -89,17 +89,17 @@ class Migrations extends Action
|
||||
$log->addTag('migrationId', $migration->getId());
|
||||
$log->addTag('projectId', $project->getId());
|
||||
|
||||
$this->processMigration($project, $migration, $log);
|
||||
$this->processMigration($migration, $log);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $source
|
||||
* @param array $credentials
|
||||
* @return Source
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function processSource(string $source, array $credentials): Source
|
||||
protected function processSource(Document $migration): Source
|
||||
{
|
||||
$source = $migration->getAttribute('source');
|
||||
$credentials = $migration->getAttribute('credentials');
|
||||
|
||||
return match ($source) {
|
||||
Firebase::getName() => new Firebase(
|
||||
json_decode($credentials['serviceAccount'], true),
|
||||
@@ -122,11 +122,35 @@ class Migrations extends Action
|
||||
$credentials['password'],
|
||||
$credentials['port'],
|
||||
),
|
||||
Appwrite::getName() => new Appwrite($credentials['projectId'], str_starts_with($credentials['endpoint'], 'http://localhost/v1') ? 'http://appwrite/v1' : $credentials['endpoint'], $credentials['apiKey']),
|
||||
SourceAppwrite::getName() => new SourceAppwrite(
|
||||
$credentials['projectId'],
|
||||
$credentials['endpoint'],
|
||||
$credentials['apiKey'],
|
||||
),
|
||||
default => throw new \Exception('Invalid source type'),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function processDestination(Document $migration): Destination
|
||||
{
|
||||
$destination = $migration->getAttribute('destination');
|
||||
$credentials = $migration->getAttribute('credentials');
|
||||
|
||||
return match ($destination) {
|
||||
DestinationAppwrite::getName() => new DestinationAppwrite(
|
||||
$credentials['projectId'],
|
||||
$credentials['endpoint'],
|
||||
$credentials['apiKey'],
|
||||
$this->dbForProject,
|
||||
Config::getParam('collections', [])['databases']['collections'],
|
||||
),
|
||||
default => throw new \Exception('Invalid destination type'),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Authorization
|
||||
* @throws Structure
|
||||
@@ -167,8 +191,6 @@ class Migrations extends Action
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Document $apiKey
|
||||
* @return void
|
||||
* @throws \Utopia\Database\Exception
|
||||
* @throws Authorization
|
||||
* @throws Conflict
|
||||
@@ -181,8 +203,6 @@ class Migrations extends Action
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Document $project
|
||||
* @return Document
|
||||
* @throws Authorization
|
||||
* @throws Structure
|
||||
* @throws \Utopia\Database\Exception
|
||||
@@ -233,99 +253,116 @@ class Migrations extends Action
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Document $project
|
||||
* @param Document $migration
|
||||
* @param Log $log
|
||||
* @return void
|
||||
* @throws Authorization
|
||||
* @throws Conflict
|
||||
* @throws Restricted
|
||||
* @throws Structure
|
||||
* @throws \Utopia\Database\Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function processMigration(Document $project, Document $migration, Log $log): void
|
||||
protected function processMigration(Document $migration, Log $log): void
|
||||
{
|
||||
/**
|
||||
* @var Document $migrationDocument
|
||||
* @var Transfer $transfer
|
||||
*/
|
||||
$migrationDocument = null;
|
||||
$transfer = null;
|
||||
$project = $this->project;
|
||||
$projectDocument = $this->dbForConsole->getDocument('projects', $project->getId());
|
||||
$tempAPIKey = $this->generateAPIKey($projectDocument);
|
||||
|
||||
$transfer = $source = $destination = null;
|
||||
|
||||
try {
|
||||
$migrationDocument = $this->dbForProject->getDocument('migrations', $migration->getId());
|
||||
$migrationDocument->setAttribute('stage', 'processing');
|
||||
$migrationDocument->setAttribute('status', 'processing');
|
||||
$log->addBreadcrumb(new Breadcrumb("debug", "migration", "Migration hit stage 'processing'", \microtime(true)));
|
||||
$this->updateMigrationDocument($migrationDocument, $projectDocument);
|
||||
$migration = $this->dbForProject->getDocument('migrations', $migration->getId());
|
||||
|
||||
$log->addTag('type', $migrationDocument->getAttribute('source'));
|
||||
if (
|
||||
$migration->getAttribute('source') === SourceAppwrite::getName() ||
|
||||
$migration->getAttribute('destination') === DestinationAppwrite::getName()
|
||||
) {
|
||||
$credentials = $migration->getAttribute('credentials', []);
|
||||
|
||||
$source = $this->processSource($migrationDocument->getAttribute('source'), $migrationDocument->getAttribute('credentials'));
|
||||
$credentials['projectId'] = $credentials['projectId'] ?? $projectDocument->getId();
|
||||
$credentials['endpoint'] = $credentials['endpoint'] ?? 'http://appwrite/v1';
|
||||
$credentials['apiKey'] = $credentials['apiKey'] ?? $tempAPIKey['secret'];
|
||||
|
||||
$migration->setAttribute('credentials', $credentials);
|
||||
}
|
||||
|
||||
$migration->setAttribute('stage', 'processing');
|
||||
$migration->setAttribute('status', 'processing');
|
||||
$this->updateMigrationDocument($migration, $projectDocument);
|
||||
|
||||
$log->addTag('type', $migration->getAttribute('source'));
|
||||
|
||||
$source = $this->processSource($migration);
|
||||
$destination = $this->processDestination($migration);
|
||||
|
||||
$source->report();
|
||||
|
||||
$destination = new DestinationsAppwrite(
|
||||
$projectDocument->getId(),
|
||||
'http://appwrite/v1',
|
||||
$tempAPIKey['secret'],
|
||||
);
|
||||
|
||||
$transfer = new Transfer(
|
||||
$source,
|
||||
$destination
|
||||
);
|
||||
|
||||
/** Start Transfer */
|
||||
$migrationDocument->setAttribute('stage', 'migrating');
|
||||
$log->addBreadcrumb(new Breadcrumb("debug", "migration", "Migration hit stage 'migrating'", \microtime(true)));
|
||||
$this->updateMigrationDocument($migrationDocument, $projectDocument);
|
||||
$transfer->run($migrationDocument->getAttribute('resources'), function () use ($migrationDocument, $transfer, $projectDocument) {
|
||||
$migrationDocument->setAttribute('resourceData', json_encode($transfer->getCache()));
|
||||
$migrationDocument->setAttribute('statusCounters', json_encode($transfer->getStatusCounters()));
|
||||
$migration->setAttribute('stage', 'migrating');
|
||||
$this->updateMigrationDocument($migration, $projectDocument);
|
||||
|
||||
$this->updateMigrationDocument($migrationDocument, $projectDocument);
|
||||
});
|
||||
$transfer->run(
|
||||
$migration->getAttribute('resources'),
|
||||
function () use ($migration, $transfer, $projectDocument) {
|
||||
$migration->setAttribute('resourceData', json_encode($transfer->getCache()));
|
||||
$migration->setAttribute('statusCounters', json_encode($transfer->getStatusCounters()));
|
||||
$this->updateMigrationDocument($migration, $projectDocument);
|
||||
},
|
||||
$migration->getAttribute('resourceId'),
|
||||
$migration->getAttribute('resourceType')
|
||||
);
|
||||
|
||||
$destination->shutDown();
|
||||
$source->shutDown();
|
||||
|
||||
$sourceErrors = $source->getErrors();
|
||||
$destinationErrors = $destination->getErrors();
|
||||
|
||||
if (!empty($sourceErrors) || !empty($destinationErrors)) {
|
||||
$migrationDocument->setAttribute('status', 'failed');
|
||||
$migrationDocument->setAttribute('stage', 'finished');
|
||||
$log->addBreadcrumb(new Breadcrumb("debug", "migration", "Migration hit stage 'finished' and failed", \microtime(true)));
|
||||
if (! empty($sourceErrors) || ! empty($destinationErrors)) {
|
||||
$migration->setAttribute('status', 'failed');
|
||||
$migration->setAttribute('stage', 'finished');
|
||||
|
||||
$errorMessages = [];
|
||||
foreach ($sourceErrors as $error) {
|
||||
/** @var MigrationException $error */
|
||||
$errorMessages[] = "Error occurred while fetching '{$error->getResourceGroup()}:{$error->getResourceId()}' from source with message: '{$error->getMessage()}'";
|
||||
/** @var $sourceErrors $error */
|
||||
$message = "Error occurred while fetching '{$error->getResourceName()}:{$error->getResourceId()}' from source with message: '{$error->getMessage()}'";
|
||||
if ($error->getPrevious()) {
|
||||
$message .= " Message: ".$error->getPrevious()->getMessage() . " File: ".$error->getPrevious()->getFile() . " Line: ".$error->getPrevious()->getLine();
|
||||
}
|
||||
|
||||
$errorMessages[] = $message;
|
||||
}
|
||||
foreach ($destinationErrors as $error) {
|
||||
$message = "Error occurred while pushing '{$error->getResourceName()}:{$error->getResourceId()}' to destination with message: '{$error->getMessage()}'";
|
||||
|
||||
if ($error->getPrevious()) {
|
||||
$message .= " Message: ".$error->getPrevious()->getMessage() . " File: ".$error->getPrevious()->getFile() . " Line: ".$error->getPrevious()->getLine();
|
||||
}
|
||||
|
||||
/** @var MigrationException $error */
|
||||
$errorMessages[] = "Error occurred while pushing '{$error->getResourceGroup()}:{$error->getResourceId()}' to destination with message: '{$error->getMessage()}'";
|
||||
$errorMessages[] = $message;
|
||||
}
|
||||
|
||||
$migrationDocument->setAttribute('errors', $errorMessages);
|
||||
$migration->setAttribute('errors', $errorMessages);
|
||||
$log->addExtra('migrationErrors', json_encode($errorMessages));
|
||||
$this->updateMigrationDocument($migrationDocument, $projectDocument);
|
||||
$this->updateMigrationDocument($migration, $projectDocument);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$migrationDocument->setAttribute('status', 'completed');
|
||||
$migrationDocument->setAttribute('stage', 'finished');
|
||||
$log->addBreadcrumb(new Breadcrumb("debug", "migration", "Migration hit stage 'finished' and succeeded", \microtime(true)));
|
||||
$migration->setAttribute('status', 'completed');
|
||||
$migration->setAttribute('stage', 'finished');
|
||||
} catch (\Throwable $th) {
|
||||
Console::error($th->getMessage());
|
||||
Console::error($th->getTraceAsString());
|
||||
|
||||
if ($migrationDocument) {
|
||||
Console::error($th->getMessage());
|
||||
Console::error($th->getTraceAsString());
|
||||
$migrationDocument->setAttribute('status', 'failed');
|
||||
$migrationDocument->setAttribute('stage', 'finished');
|
||||
$migrationDocument->setAttribute('errors', [$th->getMessage()]);
|
||||
if (! $migration->isEmpty()) {
|
||||
$migration->setAttribute('status', 'failed');
|
||||
$migration->setAttribute('stage', 'finished');
|
||||
$migration->setAttribute('errors', [$th->getMessage()]);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -337,26 +374,30 @@ class Migrations extends Action
|
||||
$errorMessages = [];
|
||||
foreach ($sourceErrors as $error) {
|
||||
/** @var MigrationException $error */
|
||||
$errorMessages[] = "Error occurred while fetching '{$error->getResourceGroup()}:{$error->getResourceId()}' from source with message '{$error->getMessage()}'";
|
||||
$errorMessages[] = "Error occurred while fetching '{$error->getResourceName()}:{$error->getResourceId()}' from source with message '{$error->getMessage()}'";
|
||||
}
|
||||
foreach ($destinationErrors as $error) {
|
||||
/** @var MigrationException $error */
|
||||
$errorMessages[] = "Error occurred while pushing '{$error->getResourceGroup()}:{$error->getResourceId()}' to destination with message '{$error->getMessage()}'";
|
||||
$errorMessages[] = "Error occurred while pushing '{$error->getResourceName()}:{$error->getResourceId()}' to destination with message '{$error->getMessage()}'";
|
||||
}
|
||||
|
||||
$migrationDocument->setAttribute('errors', $errorMessages);
|
||||
$migration->setAttribute('errors', $errorMessages);
|
||||
$log->addTag('migrationErrors', json_encode($errorMessages));
|
||||
}
|
||||
} finally {
|
||||
if ($tempAPIKey) {
|
||||
if (! $tempAPIKey->isEmpty()) {
|
||||
$this->removeAPIKey($tempAPIKey);
|
||||
}
|
||||
if ($migrationDocument) {
|
||||
$this->updateMigrationDocument($migrationDocument, $projectDocument);
|
||||
|
||||
if ($migrationDocument->getAttribute('status', '') == 'failed') {
|
||||
throw new Exception("Migration failed");
|
||||
}
|
||||
$this->updateMigrationDocument($migration, $projectDocument);
|
||||
|
||||
if ($migration->getAttribute('status', '') === 'failed') {
|
||||
Console::error('Migration('.$migration->getInternalId().':'.$migration->getId().') failed, Project('.$this->project->getInternalId().':'.$this->project->getId().')');
|
||||
|
||||
$destination->error();
|
||||
$source->error();
|
||||
|
||||
throw new Exception('Migration failed');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -286,13 +286,26 @@ class Swagger2 extends Format
|
||||
$validator = $validator->getValidator();
|
||||
}
|
||||
|
||||
$validatorClass = (!empty($validator)) ? \get_class($validator) : '';
|
||||
if ($validatorClass === 'Utopia\Validator\AnyOf') {
|
||||
$validator = $param['validator']->getValidators()[0];
|
||||
$validatorClass = \get_class($validator);
|
||||
$class = !empty($validator)
|
||||
? \get_class($validator)
|
||||
: '';
|
||||
|
||||
$base = !empty($class)
|
||||
? \get_parent_class($class)
|
||||
: '';
|
||||
|
||||
switch ($base) {
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Base':
|
||||
$class = $base;
|
||||
break;
|
||||
}
|
||||
|
||||
switch ($validatorClass) {
|
||||
if ($class === 'Utopia\Validator\AnyOf') {
|
||||
$validator = $param['validator']->getValidators()[0];
|
||||
$class = \get_class($validator);
|
||||
}
|
||||
|
||||
switch ($class) {
|
||||
case 'Utopia\Validator\Text':
|
||||
case 'Utopia\Database\Validator\UID':
|
||||
$node['type'] = $validator->getType();
|
||||
@@ -348,29 +361,7 @@ class Swagger2 extends Format
|
||||
$consumes = ['multipart/form-data'];
|
||||
$node['type'] = 'payload';
|
||||
break;
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Attributes':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Buckets':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Collections':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Databases':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Deployments':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Executions':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Files':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Functions':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Identities':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Indexes':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Installations':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Memberships':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Messages':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Migrations':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Projects':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Providers':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Rules':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Subscribers':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Targets':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Teams':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Topics':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Users':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Variables':
|
||||
case 'Appwrite\Utopia\Database\Validator\Queries\Base':
|
||||
case 'Utopia\Database\Validator\Queries':
|
||||
case 'Utopia\Database\Validator\Queries\Document':
|
||||
case 'Utopia\Database\Validator\Queries\Documents':
|
||||
|
||||
@@ -122,7 +122,11 @@ class Request extends UtopiaRequest
|
||||
*/
|
||||
public function getHeaders(): array
|
||||
{
|
||||
$headers = $this->generateHeaders();
|
||||
try {
|
||||
$headers = $this->generateHeaders();
|
||||
} catch (\Throwable) {
|
||||
$headers = [];
|
||||
}
|
||||
|
||||
if (empty($this->swoole->cookie)) {
|
||||
return $headers;
|
||||
|
||||
@@ -47,7 +47,18 @@ class Attribute extends Model
|
||||
'required' => false,
|
||||
'example' => false,
|
||||
])
|
||||
;
|
||||
->addRule('$createdAt', [
|
||||
'type' => self::TYPE_DATETIME,
|
||||
'description' => 'Attribute creation date in ISO 8601 format.',
|
||||
'default' => '',
|
||||
'example' => self::TYPE_DATETIME_EXAMPLE,
|
||||
])
|
||||
->addRule('$updatedAt', [
|
||||
'type' => self::TYPE_DATETIME,
|
||||
'description' => 'Attribute update date in ISO 8601 format.',
|
||||
'default' => '',
|
||||
'example' => self::TYPE_DATETIME_EXAMPLE,
|
||||
]);
|
||||
}
|
||||
|
||||
public array $conditions = [];
|
||||
|
||||
@@ -49,13 +49,22 @@ class Index extends Model
|
||||
'array' => true,
|
||||
'required' => false,
|
||||
])
|
||||
;
|
||||
->addRule('$createdAt', [
|
||||
'type' => self::TYPE_DATETIME,
|
||||
'description' => 'Index creation date in ISO 8601 format.',
|
||||
'default' => '',
|
||||
'example' => self::TYPE_DATETIME_EXAMPLE,
|
||||
])
|
||||
->addRule('$updatedAt', [
|
||||
'type' => self::TYPE_DATETIME,
|
||||
'description' => 'Index update date in ISO 8601 format.',
|
||||
'default' => '',
|
||||
'example' => self::TYPE_DATETIME_EXAMPLE,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
@@ -64,8 +73,6 @@ class Index extends Model
|
||||
|
||||
/**
|
||||
* Get Collection
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
|
||||
@@ -883,9 +883,6 @@ class UsageTest extends Scope
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertNotEmpty($response['body']['$id']);
|
||||
|
||||
$code = realpath(__DIR__ . '/../../resources/functions') . "/php/code.tar.gz";
|
||||
$this->packageCode('php');
|
||||
|
||||
$response = $this->client->call(
|
||||
Client::METHOD_POST,
|
||||
'/functions/' . $functionId . '/deployments',
|
||||
@@ -895,8 +892,8 @@ class UsageTest extends Scope
|
||||
], $this->getHeaders()),
|
||||
[
|
||||
'entrypoint' => 'index.php',
|
||||
'code' => new CURLFile($code, 'application/x-gzip', \basename($code)),
|
||||
'activate' => true
|
||||
'code' => $this->packageFunction('php'),
|
||||
'activate' => true,
|
||||
]
|
||||
);
|
||||
|
||||
@@ -934,7 +931,7 @@ class UsageTest extends Scope
|
||||
'x-appwrite-project' => $this->getProject()['$id']
|
||||
], $this->getHeaders()),
|
||||
[
|
||||
'async' => false,
|
||||
'async' => 'false',
|
||||
]
|
||||
);
|
||||
|
||||
@@ -958,7 +955,7 @@ class UsageTest extends Scope
|
||||
'x-appwrite-project' => $this->getProject()['$id']
|
||||
], $this->getHeaders()),
|
||||
[
|
||||
'async' => false,
|
||||
'async' => 'false',
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
@@ -2,234 +2,207 @@
|
||||
|
||||
namespace Tests\E2E\Services\Functions;
|
||||
|
||||
use Appwrite\Tests\Async;
|
||||
use CURLFile;
|
||||
use Tests\E2E\Client;
|
||||
use Utopia\CLI\Console;
|
||||
|
||||
trait FunctionsBase
|
||||
{
|
||||
use Async;
|
||||
|
||||
protected string $stdout = '';
|
||||
protected string $stderr = '';
|
||||
|
||||
protected function packageCode($folder)
|
||||
protected function setupFunction(mixed $params): string
|
||||
{
|
||||
Console::execute('cd ' . realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->stdout, $this->stderr);
|
||||
$function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]), $params);
|
||||
|
||||
$this->assertEquals($function['headers']['status-code'], 201, 'Setup function failed with status code: ' . $function['headers']['status-code'] . ' and response: ' . json_encode($function['body'], JSON_PRETTY_PRINT));
|
||||
|
||||
$functionId = $function['body']['$id'];
|
||||
|
||||
return $functionId;
|
||||
}
|
||||
|
||||
protected function awaitDeploymentIsBuilt($functionId, $deploymentId, $checkForSuccess = true): void
|
||||
protected function setupDeployment(string $functionId, mixed $params): string
|
||||
{
|
||||
while (true) {
|
||||
$deployment = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/deployments/' . $deploymentId, [
|
||||
$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'],
|
||||
]), $params);
|
||||
$this->assertEquals($deployment['headers']['status-code'], 202, 'Setup deployment failed with status code: ' . $deployment['headers']['status-code'] . ' and response: ' . json_encode($deployment['body'], JSON_PRETTY_PRINT));
|
||||
$deploymentId = $deployment['body']['$id'] ?? '';
|
||||
|
||||
$this->assertEventually(function () use ($functionId, $deploymentId) {
|
||||
$deployment = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/deployments/' . $deploymentId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
]));
|
||||
$this->assertEquals('ready', $deployment['body']['status'], 'Deployment status is not ready, deployment: ' . json_encode($deployment['body'], JSON_PRETTY_PRINT));
|
||||
}, 50000, 500);
|
||||
|
||||
if (
|
||||
$deployment['headers']['status-code'] >= 400
|
||||
|| \in_array($deployment['body']['status'], ['ready', 'failed'])
|
||||
) {
|
||||
break;
|
||||
}
|
||||
|
||||
\sleep(1);
|
||||
}
|
||||
|
||||
if ($checkForSuccess) {
|
||||
$this->assertEquals(200, $deployment['headers']['status-code']);
|
||||
$this->assertEquals('ready', $deployment['body']['status'], \json_encode($deployment['body']));
|
||||
}
|
||||
return $deploymentId;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @depends testCreateTeam
|
||||
// */
|
||||
// public function testGetTeam($data):array
|
||||
// {
|
||||
// $id = $data['teamUid'] ?? '';
|
||||
protected function cleanupFunction(string $functionId): void
|
||||
{
|
||||
$function = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]));
|
||||
|
||||
// /**
|
||||
// * Test for SUCCESS
|
||||
// */
|
||||
// $response = $this->client->call(Client::METHOD_GET, '/teams/'.$id, array_merge([
|
||||
// 'content-type' => 'application/json',
|
||||
// 'x-appwrite-project' => $this->getProject()['$id'],
|
||||
// ], $this->getHeaders()));
|
||||
$this->assertEquals($function['headers']['status-code'], 204);
|
||||
}
|
||||
|
||||
// $this->assertEquals(200, $response['headers']['status-code']);
|
||||
// $this->assertNotEmpty($response['body']['$id']);
|
||||
// $this->assertEquals('Arsenal', $response['body']['name']);
|
||||
// $this->assertGreaterThan(-1, $response['body']['total']);
|
||||
// $this->assertIsInt($response['body']['total']);
|
||||
// $this->assertIsInt($response['body']['dateCreated']);
|
||||
protected function createFunction(mixed $params): mixed
|
||||
{
|
||||
$function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), $params);
|
||||
|
||||
// /**
|
||||
// * Test for FAILURE
|
||||
// */
|
||||
return $function;
|
||||
}
|
||||
|
||||
// return [];
|
||||
// }
|
||||
protected function createVariable(string $functionId, mixed $params): mixed
|
||||
{
|
||||
$variable = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/variables', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), $params);
|
||||
|
||||
// /**
|
||||
// * @depends testCreateTeam
|
||||
// */
|
||||
// public function testListTeams($data):array
|
||||
// {
|
||||
// /**
|
||||
// * Test for SUCCESS
|
||||
// */
|
||||
// $response = $this->client->call(Client::METHOD_GET, '/teams', array_merge([
|
||||
// 'content-type' => 'application/json',
|
||||
// 'x-appwrite-project' => $this->getProject()['$id'],
|
||||
// ], $this->getHeaders()));
|
||||
return $variable;
|
||||
}
|
||||
|
||||
// $this->assertEquals(200, $response['headers']['status-code']);
|
||||
// $this->assertGreaterThan(0, $response['body']['total']);
|
||||
// $this->assertIsInt($response['body']['total']);
|
||||
// $this->assertCount(3, $response['body']['teams']);
|
||||
protected function getFunction(string $functionId): mixed
|
||||
{
|
||||
$function = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
// $response = $this->client->call(Client::METHOD_GET, '/teams', array_merge([
|
||||
// 'content-type' => 'application/json',
|
||||
// 'x-appwrite-project' => $this->getProject()['$id'],
|
||||
// ], $this->getHeaders()), [
|
||||
// 'limit' => 2,
|
||||
// ]);
|
||||
return $function;
|
||||
}
|
||||
|
||||
// $this->assertEquals(200, $response['headers']['status-code']);
|
||||
// $this->assertGreaterThan(0, $response['body']['total']);
|
||||
// $this->assertIsInt($response['body']['total']);
|
||||
// $this->assertCount(2, $response['body']['teams']);
|
||||
protected function getDeployment(string $functionId, string $deploymentId): mixed
|
||||
{
|
||||
$deployment = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/deployments/' . $deploymentId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
// $response = $this->client->call(Client::METHOD_GET, '/teams', array_merge([
|
||||
// 'content-type' => 'application/json',
|
||||
// 'x-appwrite-project' => $this->getProject()['$id'],
|
||||
// ], $this->getHeaders()), [
|
||||
// 'offset' => 1,
|
||||
// ]);
|
||||
return $deployment;
|
||||
}
|
||||
|
||||
// $this->assertEquals(200, $response['headers']['status-code']);
|
||||
// $this->assertGreaterThan(0, $response['body']['total']);
|
||||
// $this->assertIsInt($response['body']['total']);
|
||||
// $this->assertCount(2, $response['body']['teams']);
|
||||
protected function getExecution(string $functionId, $executionId): mixed
|
||||
{
|
||||
$execution = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions/' . $executionId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
// $response = $this->client->call(Client::METHOD_GET, '/teams', array_merge([
|
||||
// 'content-type' => 'application/json',
|
||||
// 'x-appwrite-project' => $this->getProject()['$id'],
|
||||
// ], $this->getHeaders()), [
|
||||
// 'search' => 'Manchester',
|
||||
// ]);
|
||||
return $execution;
|
||||
}
|
||||
|
||||
// $this->assertEquals(200, $response['headers']['status-code']);
|
||||
// $this->assertGreaterThan(0, $response['body']['total']);
|
||||
// $this->assertIsInt($response['body']['total']);
|
||||
// $this->assertCount(1, $response['body']['teams']);
|
||||
// $this->assertEquals('Manchester United', $response['body']['teams'][0]['name']);
|
||||
protected function listFunctions(mixed $params = []): mixed
|
||||
{
|
||||
$functions = $this->client->call(Client::METHOD_GET, '/functions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), $params);
|
||||
|
||||
// $response = $this->client->call(Client::METHOD_GET, '/teams', array_merge([
|
||||
// 'content-type' => 'application/json',
|
||||
// 'x-appwrite-project' => $this->getProject()['$id'],
|
||||
// ], $this->getHeaders()), [
|
||||
// 'search' => 'United',
|
||||
// ]);
|
||||
return $functions;
|
||||
}
|
||||
|
||||
// $this->assertEquals(200, $response['headers']['status-code']);
|
||||
// $this->assertGreaterThan(0, $response['body']['total']);
|
||||
// $this->assertIsInt($response['body']['total']);
|
||||
// $this->assertCount(1, $response['body']['teams']);
|
||||
// $this->assertEquals('Manchester United', $response['body']['teams'][0]['name']);
|
||||
protected function listDeployments(string $functionId, $params = []): mixed
|
||||
{
|
||||
$deployments = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/deployments', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), $params);
|
||||
|
||||
// /**
|
||||
// * Test for FAILURE
|
||||
// */
|
||||
return $deployments;
|
||||
}
|
||||
|
||||
// return [];
|
||||
// }
|
||||
protected function listExecutions(string $functionId, mixed $params = []): mixed
|
||||
{
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), $params);
|
||||
|
||||
// public function testUpdateTeam():array
|
||||
// {
|
||||
// /**
|
||||
// * Test for SUCCESS
|
||||
// */
|
||||
// $response = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
|
||||
// 'content-type' => 'application/json',
|
||||
// 'x-appwrite-project' => $this->getProject()['$id'],
|
||||
// ], $this->getHeaders()), [
|
||||
// 'name' => 'Demo'
|
||||
// ]);
|
||||
return $executions;
|
||||
}
|
||||
|
||||
// $this->assertEquals(201, $response['headers']['status-code']);
|
||||
// $this->assertNotEmpty($response['body']['$id']);
|
||||
// $this->assertEquals('Demo', $response['body']['name']);
|
||||
// $this->assertGreaterThan(-1, $response['body']['total']);
|
||||
// $this->assertIsInt($response['body']['total']);
|
||||
// $this->assertIsInt($response['body']['dateCreated']);
|
||||
protected function packageFunction(string $function): CURLFile
|
||||
{
|
||||
$folderPath = realpath(__DIR__ . '/../../../resources/functions') . "/$function";
|
||||
$tarPath = "$folderPath/code.tar.gz";
|
||||
|
||||
// $response = $this->client->call(Client::METHOD_PUT, '/teams/'.$response['body']['$id'], array_merge([
|
||||
// 'content-type' => 'application/json',
|
||||
// 'x-appwrite-project' => $this->getProject()['$id'],
|
||||
// ], $this->getHeaders()), [
|
||||
// 'name' => 'Demo New'
|
||||
// ]);
|
||||
Console::execute("cd $folderPath && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->stdout, $this->stderr);
|
||||
|
||||
// $this->assertEquals(200, $response['headers']['status-code']);
|
||||
// $this->assertNotEmpty($response['body']['$id']);
|
||||
// $this->assertEquals('Demo New', $response['body']['name']);
|
||||
// $this->assertGreaterThan(-1, $response['body']['total']);
|
||||
// $this->assertIsInt($response['body']['total']);
|
||||
// $this->assertIsInt($response['body']['dateCreated']);
|
||||
if (filesize($tarPath) > 1024 * 1024 * 5) {
|
||||
throw new \Exception('Code package is too large. Use the chunked upload method instead.');
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Test for FAILURE
|
||||
// */
|
||||
// $response = $this->client->call(Client::METHOD_PUT, '/teams/'.$response['body']['$id'], array_merge([
|
||||
// 'content-type' => 'application/json',
|
||||
// 'x-appwrite-project' => $this->getProject()['$id'],
|
||||
// ], $this->getHeaders()), [
|
||||
// ]);
|
||||
return new CURLFile($tarPath, 'application/x-gzip', \basename($tarPath));
|
||||
}
|
||||
|
||||
// $this->assertEquals(400, $response['headers']['status-code']);
|
||||
protected function createDeployment(string $functionId, mixed $params = []): mixed
|
||||
{
|
||||
$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()), $params);
|
||||
|
||||
// return [];
|
||||
// }
|
||||
return $deployment;
|
||||
}
|
||||
|
||||
// public function testDeleteTeam():array
|
||||
// {
|
||||
// /**
|
||||
// * Test for SUCCESS
|
||||
// */
|
||||
// $response = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
|
||||
// 'content-type' => 'application/json',
|
||||
// 'x-appwrite-project' => $this->getProject()['$id'],
|
||||
// ], $this->getHeaders()), [
|
||||
// 'name' => 'Demo'
|
||||
// ]);
|
||||
protected function getFunctionUsage(string $functionId, mixed $params): mixed
|
||||
{
|
||||
$usage = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/usage', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), $params);
|
||||
|
||||
// $teamUid = $response['body']['$id'];
|
||||
return $usage;
|
||||
}
|
||||
|
||||
// $this->assertEquals(201, $response['headers']['status-code']);
|
||||
// $this->assertNotEmpty($response['body']['$id']);
|
||||
// $this->assertEquals('Demo', $response['body']['name']);
|
||||
// $this->assertGreaterThan(-1, $response['body']['total']);
|
||||
// $this->assertIsInt($response['body']['total']);
|
||||
// $this->assertIsInt($response['body']['dateCreated']);
|
||||
protected function getTemplate(string $templateId)
|
||||
{
|
||||
$template = $this->client->call(Client::METHOD_GET, '/functions/templates/' . $templateId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
// $response = $this->client->call(Client::METHOD_DELETE, '/teams/'.$teamUid, array_merge([
|
||||
// 'content-type' => 'application/json',
|
||||
// 'x-appwrite-project' => $this->getProject()['$id'],
|
||||
// ], $this->getHeaders()));
|
||||
return $template;
|
||||
}
|
||||
|
||||
// $this->assertEquals(204, $response['headers']['status-code']);
|
||||
// $this->assertEmpty($response['body']);
|
||||
protected function createExecution(string $functionId, mixed $params = []): mixed
|
||||
{
|
||||
$execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), $params);
|
||||
|
||||
// /**
|
||||
// * Test for FAILURE
|
||||
// */
|
||||
// $response = $this->client->call(Client::METHOD_GET, '/teams/'.$teamUid, array_merge([
|
||||
// 'content-type' => 'application/json',
|
||||
// 'x-appwrite-project' => $this->getProject()['$id'],
|
||||
// ], $this->getHeaders()));
|
||||
return $execution;
|
||||
}
|
||||
|
||||
// $this->assertEquals(404, $response['headers']['status-code']);
|
||||
protected function deleteFunction(string $functionId): mixed
|
||||
{
|
||||
$function = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
// return [];
|
||||
// }
|
||||
return $function;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,13 +13,11 @@ class FunctionsConsoleClientTest extends Scope
|
||||
{
|
||||
use ProjectCustom;
|
||||
use SideConsole;
|
||||
use FunctionsBase;
|
||||
|
||||
public function testCreateFunction(): array
|
||||
{
|
||||
$function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
$function = $this->createFunction([
|
||||
'functionId' => ID::unique(),
|
||||
'name' => 'Test',
|
||||
'execute' => [Role::user($this->getUser()['$id'])->toString()],
|
||||
@@ -35,10 +33,9 @@ class FunctionsConsoleClientTest extends Scope
|
||||
|
||||
$this->assertEquals(201, $function['headers']['status-code']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_POST, '/functions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
$functionId = $function['body']['$id'];
|
||||
|
||||
$function2 = $this->createFunction([
|
||||
'functionId' => ID::unique(),
|
||||
'name' => 'Test Failure',
|
||||
'execute' => ['some-random-string'],
|
||||
@@ -46,73 +43,59 @@ class FunctionsConsoleClientTest extends Scope
|
||||
'entrypoint' => 'index.php',
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
$this->assertEquals(400, $function2['headers']['status-code']);
|
||||
|
||||
return [
|
||||
'functionId' => $function['body']['$id']
|
||||
'functionId' => $functionId,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateFunction
|
||||
*/
|
||||
public function testGetCollectionUsage(array $data)
|
||||
public function testFunctionUsage(array $data)
|
||||
{
|
||||
/**
|
||||
* Test for FAILURE
|
||||
*/
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/usage', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id']
|
||||
], $this->getHeaders()), [
|
||||
'range' => '232h'
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/functions/randomFunctionId/usage', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id']
|
||||
], $this->getHeaders()), [
|
||||
'range' => '24h'
|
||||
]);
|
||||
|
||||
$this->assertEquals(404, $response['headers']['status-code']);
|
||||
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/usage', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id']
|
||||
], $this->getHeaders()), [
|
||||
$usage = $this->getFunctionUsage($data['functionId'], [
|
||||
'range' => '24h'
|
||||
]);
|
||||
$this->assertEquals(200, $usage['headers']['status-code']);
|
||||
$this->assertEquals(19, count($usage['body']));
|
||||
$this->assertEquals('24h', $usage['body']['range']);
|
||||
$this->assertIsNumeric($usage['body']['deploymentsTotal']);
|
||||
$this->assertIsNumeric($usage['body']['deploymentsStorageTotal']);
|
||||
$this->assertIsNumeric($usage['body']['buildsTotal']);
|
||||
$this->assertIsNumeric($usage['body']['buildsStorageTotal']);
|
||||
$this->assertIsNumeric($usage['body']['buildsTimeTotal']);
|
||||
$this->assertIsNumeric($usage['body']['buildsMbSecondsTotal']);
|
||||
$this->assertIsNumeric($usage['body']['executionsTotal']);
|
||||
$this->assertIsNumeric($usage['body']['executionsTimeTotal']);
|
||||
$this->assertIsNumeric($usage['body']['executionsMbSecondsTotal']);
|
||||
$this->assertIsArray($usage['body']['deployments']);
|
||||
$this->assertIsArray($usage['body']['deploymentsStorage']);
|
||||
$this->assertIsArray($usage['body']['builds']);
|
||||
$this->assertIsArray($usage['body']['buildsTime']);
|
||||
$this->assertIsArray($usage['body']['buildsStorage']);
|
||||
$this->assertIsArray($usage['body']['buildsTime']);
|
||||
$this->assertIsArray($usage['body']['buildsMbSeconds']);
|
||||
$this->assertIsArray($usage['body']['executions']);
|
||||
$this->assertIsArray($usage['body']['executionsTime']);
|
||||
$this->assertIsArray($usage['body']['executionsMbSeconds']);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(19, count($response['body']));
|
||||
$this->assertEquals('24h', $response['body']['range']);
|
||||
$this->assertIsNumeric($response['body']['deploymentsTotal']);
|
||||
$this->assertIsNumeric($response['body']['deploymentsStorageTotal']);
|
||||
$this->assertIsNumeric($response['body']['buildsTotal']);
|
||||
$this->assertIsNumeric($response['body']['buildsStorageTotal']);
|
||||
$this->assertIsNumeric($response['body']['buildsTimeTotal']);
|
||||
$this->assertIsNumeric($response['body']['buildsMbSecondsTotal']);
|
||||
$this->assertIsNumeric($response['body']['executionsTotal']);
|
||||
$this->assertIsNumeric($response['body']['executionsTimeTotal']);
|
||||
$this->assertIsNumeric($response['body']['executionsMbSecondsTotal']);
|
||||
$this->assertIsArray($response['body']['deployments']);
|
||||
$this->assertIsArray($response['body']['deploymentsStorage']);
|
||||
$this->assertIsArray($response['body']['builds']);
|
||||
$this->assertIsArray($response['body']['buildsTime']);
|
||||
$this->assertIsArray($response['body']['buildsStorage']);
|
||||
$this->assertIsArray($response['body']['buildsTime']);
|
||||
$this->assertIsArray($response['body']['buildsMbSeconds']);
|
||||
$this->assertIsArray($response['body']['executions']);
|
||||
$this->assertIsArray($response['body']['executionsTime']);
|
||||
$this->assertIsArray($response['body']['executionsMbSeconds']);
|
||||
/**
|
||||
* Test for FAILURE
|
||||
*/
|
||||
$usage = $this->getFunctionUsage($data['functionId'], [
|
||||
'range' => '232h'
|
||||
]);
|
||||
$this->assertEquals(400, $usage['headers']['status-code']);
|
||||
|
||||
$usage = $this->getFunctionUsage('randomFunctionId', [
|
||||
'range' => '24h'
|
||||
]);
|
||||
$this->assertEquals(404, $usage['headers']['status-code']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,31 +106,53 @@ class FunctionsConsoleClientTest extends Scope
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$variable = $this->createVariable(
|
||||
$data['functionId'],
|
||||
[
|
||||
'key' => 'APP_TEST',
|
||||
'value' => 'TESTINGVALUE'
|
||||
]
|
||||
);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/variables', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'key' => 'APP_TEST',
|
||||
'value' => 'TESTINGVALUE'
|
||||
]);
|
||||
$this->assertEquals(201, $variable['headers']['status-code']);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$variableId = $response['body']['$id'];
|
||||
$variableId = $variable['body']['$id'];
|
||||
|
||||
/**
|
||||
* Test for FAILURE
|
||||
*/
|
||||
// Test for duplicate key
|
||||
$variable = $this->createVariable(
|
||||
$data['functionId'],
|
||||
[
|
||||
'key' => 'APP_TEST',
|
||||
'value' => 'ANOTHERTESTINGVALUE'
|
||||
]
|
||||
);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/variables', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'key' => 'APP_TEST',
|
||||
'value' => 'ANOTHER_TESTINGVALUE'
|
||||
]);
|
||||
$this->assertEquals(409, $variable['headers']['status-code']);
|
||||
|
||||
$this->assertEquals(409, $response['headers']['status-code']);
|
||||
// Test for invalid key
|
||||
$variable = $this->createVariable(
|
||||
$data['functionId'],
|
||||
[
|
||||
'key' => str_repeat("A", 256),
|
||||
'value' => 'TESTINGVALUE'
|
||||
]
|
||||
);
|
||||
|
||||
$this->assertEquals(400, $variable['headers']['status-code']);
|
||||
|
||||
// Test for invalid value
|
||||
$variable = $this->createVariable(
|
||||
$data['functionId'],
|
||||
[
|
||||
'key' => 'LONGKEY',
|
||||
'value' => str_repeat("#", 8193),
|
||||
]
|
||||
);
|
||||
|
||||
$this->assertEquals(400, $variable['headers']['status-code']);
|
||||
|
||||
return array_merge(
|
||||
$data,
|
||||
@@ -155,28 +160,6 @@ class FunctionsConsoleClientTest extends Scope
|
||||
'variableId' => $variableId
|
||||
]
|
||||
);
|
||||
|
||||
$longKey = str_repeat("A", 256);
|
||||
$response = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/variables', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'key' => $longKey,
|
||||
'value' => 'TESTINGVALUE'
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
$longValue = str_repeat("#", 8193);
|
||||
$response = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/variables', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'key' => 'LONGKEY',
|
||||
'value' => $longValue
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,214 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\E2E\Services\Functions;
|
||||
|
||||
use Appwrite\ID;
|
||||
use Tests\E2E\Client;
|
||||
use Tests\E2E\Scopes\ProjectCustom;
|
||||
use Tests\E2E\Scopes\Scope;
|
||||
use Tests\E2E\Scopes\SideServer;
|
||||
use Utopia\Database\Helpers\Role;
|
||||
|
||||
class FunctionsScheduleTest extends Scope
|
||||
{
|
||||
use FunctionsBase;
|
||||
use ProjectCustom;
|
||||
use SideServer;
|
||||
|
||||
public function testCreateScheduledExecution()
|
||||
{
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$functionId = $this->setupFunction([
|
||||
'functionId' => ID::unique(),
|
||||
'name' => 'Test',
|
||||
'execute' => [Role::user($this->getUser()['$id'])->toString()],
|
||||
'runtime' => 'php-8.0',
|
||||
'entrypoint' => 'index.php',
|
||||
'events' => [
|
||||
'users.*.create',
|
||||
'users.*.delete',
|
||||
],
|
||||
'schedule' => '* * * * *', // Execute every 60 seconds
|
||||
'timeout' => 10,
|
||||
]);
|
||||
|
||||
$this->setupDeployment($functionId, [
|
||||
'entrypoint' => 'index.php',
|
||||
'code' => $this->packageFunction('php'),
|
||||
'activate' => true
|
||||
]);
|
||||
|
||||
// Wait for scheduled execution
|
||||
\sleep(60);
|
||||
|
||||
$this->assertEventually(function () use ($functionId) {
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $executions['headers']['status-code']);
|
||||
$this->assertCount(1, $executions['body']['executions']);
|
||||
|
||||
$asyncExecution = $executions['body']['executions'][0];
|
||||
|
||||
$this->assertEquals('schedule', $asyncExecution['trigger']);
|
||||
$this->assertEquals('completed', $asyncExecution['status']);
|
||||
$this->assertEquals(200, $asyncExecution['responseStatusCode']);
|
||||
$this->assertEquals('', $asyncExecution['responseBody']);
|
||||
$this->assertNotEmpty($asyncExecution['logs']);
|
||||
$this->assertNotEmpty($asyncExecution['errors']);
|
||||
$this->assertGreaterThan(0, $asyncExecution['duration']);
|
||||
}, 60000, 500);
|
||||
|
||||
$this->cleanupFunction($functionId);
|
||||
}
|
||||
|
||||
public function testCreateScheduledAtExecution(): void
|
||||
{
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$functionId = $this->setupFunction([
|
||||
'functionId' => ID::unique(),
|
||||
'name' => 'Test',
|
||||
'execute' => [Role::user($this->getUser()['$id'])->toString()],
|
||||
'runtime' => 'php-8.0',
|
||||
'entrypoint' => 'index.php',
|
||||
'timeout' => 10,
|
||||
'logging' => true,
|
||||
]);
|
||||
$this->setupDeployment($functionId, [
|
||||
'entrypoint' => 'index.php',
|
||||
'code' => $this->packageFunction('php'),
|
||||
'activate' => true
|
||||
]);
|
||||
|
||||
// Schedule execution for the future
|
||||
\date_default_timezone_set('UTC');
|
||||
$futureTime = (new \DateTime())->add(new \DateInterval('PT2M')); // 2 minute in the future
|
||||
$futureTime->setTime($futureTime->format('H'), $futureTime->format('i'), 0, 0);
|
||||
|
||||
|
||||
$execution = $this->client->call(
|
||||
Client::METHOD_POST,
|
||||
'/functions/' . $functionId . '/executions',
|
||||
[
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'origin' => 'http://localhost',
|
||||
'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $this->getUser()['session'],
|
||||
],
|
||||
[
|
||||
'async' => true,
|
||||
'scheduledAt' => $futureTime->format(\DateTime::ATOM),
|
||||
'path' => '/custom-path',
|
||||
'method' => 'PATCH',
|
||||
'body' => 'custom-body',
|
||||
'headers' => [
|
||||
'x-custom-header' => 'custom-value'
|
||||
]
|
||||
]
|
||||
);
|
||||
$executionId = $execution['body']['$id'];
|
||||
|
||||
$this->assertEquals(202, $execution['headers']['status-code']);
|
||||
$this->assertEquals('scheduled', $execution['body']['status']);
|
||||
$this->assertEquals('PATCH', $execution['body']['requestMethod']);
|
||||
$this->assertEquals('/custom-path', $execution['body']['requestPath']);
|
||||
$this->assertCount(0, $execution['body']['requestHeaders']);
|
||||
|
||||
\sleep(120);
|
||||
|
||||
$this->assertEventually(function () use ($functionId, $executionId) {
|
||||
$execution = $this->getExecution($functionId, $executionId);
|
||||
|
||||
$this->assertEquals(200, $execution['headers']['status-code']);
|
||||
$this->assertEquals(200, $execution['body']['responseStatusCode']);
|
||||
$this->assertEquals('completed', $execution['body']['status']);
|
||||
$this->assertEquals('/custom-path', $execution['body']['requestPath']);
|
||||
$this->assertEquals('PATCH', $execution['body']['requestMethod']);
|
||||
$this->assertStringContainsString('body-is-custom-body', $execution['body']['logs']);
|
||||
$this->assertStringContainsString('custom-header-is-custom-value', $execution['body']['logs']);
|
||||
$this->assertStringContainsString('method-is-patch', $execution['body']['logs']);
|
||||
$this->assertStringContainsString('path-is-/custom-path', $execution['body']['logs']);
|
||||
$this->assertStringContainsString('user-is-' . $this->getUser()['$id'], $execution['body']['logs']);
|
||||
$this->assertStringContainsString('jwt-is-valid', $execution['body']['logs']);
|
||||
$this->assertGreaterThan(0, $execution['body']['duration']);
|
||||
}, 10000, 500);
|
||||
|
||||
/* Test for FAILURE */
|
||||
// Schedule synchronous execution
|
||||
$execution = $this->createExecution($functionId, [
|
||||
'async' => 'false',
|
||||
'scheduledAt' => $futureTime->format(\DateTime::ATOM),
|
||||
]);
|
||||
$this->assertEquals(400, $execution['headers']['status-code']);
|
||||
|
||||
// Execution with seconds precision
|
||||
$execution = $this->createExecution($functionId, [
|
||||
'async' => true,
|
||||
'scheduledAt' => (new \DateTime("2100-12-08 16:12:02"))->format(\DateTime::ATOM)
|
||||
]);
|
||||
$this->assertEquals(400, $execution['headers']['status-code']);
|
||||
|
||||
// Execution with milliseconds precision
|
||||
$execution = $this->createExecution($functionId, [
|
||||
'async' => true,
|
||||
'scheduledAt' => (new \DateTime("2100-12-08 16:12:02.255"))->format(\DateTime::ATOM)
|
||||
]);
|
||||
$this->assertEquals(400, $execution['headers']['status-code']);
|
||||
|
||||
// Execution too soon
|
||||
$execution = $this->createExecution($functionId, [
|
||||
'async' => true,
|
||||
'scheduledAt' => (new \DateTime())->add(new \DateInterval('PT1S'))->format(\DateTime::ATOM)
|
||||
]);
|
||||
$this->assertEquals(400, $execution['headers']['status-code']);
|
||||
|
||||
$this->cleanupFunction($functionId, $executionId);
|
||||
}
|
||||
|
||||
public function testDeleteScheduledExecution()
|
||||
{
|
||||
$functionId = $this->setupFunction([
|
||||
'functionId' => ID::unique(),
|
||||
'name' => 'Test',
|
||||
'execute' => [Role::user($this->getUser()['$id'])->toString()],
|
||||
'runtime' => 'php-8.0',
|
||||
'entrypoint' => 'index.php',
|
||||
'timeout' => 10,
|
||||
'logging' => true,
|
||||
]);
|
||||
|
||||
$this->setupDeployment($functionId, [
|
||||
'entrypoint' => 'index.php',
|
||||
'code' => $this->packageFunction('php'),
|
||||
'activate' => true
|
||||
]);
|
||||
|
||||
$futureTime = (new \DateTime())->add(new \DateInterval('PT10H'));
|
||||
$futureTime->setTime($futureTime->format('H'), $futureTime->format('i'), 0, 0);
|
||||
|
||||
$execution = $this->createExecution($functionId, [
|
||||
'async' => true,
|
||||
'scheduledAt' => $futureTime->format('Y-m-d H:i:s'),
|
||||
]);
|
||||
|
||||
$this->assertEquals(202, $execution['headers']['status-code']);
|
||||
|
||||
$executionId = $execution['body']['$id'] ?? '';
|
||||
|
||||
$execution = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId . '/executions/' . $executionId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(204, $execution['headers']['status-code']);
|
||||
|
||||
$this->cleanupFunction($functionId);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Tests\E2E\Services\GraphQL;
|
||||
|
||||
use CURLFile;
|
||||
use Utopia\CLI\Console;
|
||||
|
||||
trait Base
|
||||
@@ -2496,8 +2497,17 @@ trait Base
|
||||
protected string $stdout = '';
|
||||
protected string $stderr = '';
|
||||
|
||||
protected function packageCode($folder): void
|
||||
protected function packageFunction(string $function): CURLFile
|
||||
{
|
||||
Console::execute('cd ' . realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->stdout, $this->stderr);
|
||||
$folderPath = realpath(__DIR__ . '/../../../resources/functions') . "/$function";
|
||||
$tarPath = "$folderPath/code.tar.gz";
|
||||
|
||||
Console::execute("cd $folderPath && tar --exclude code.tar.gz -czf code.tar.gz .", '', $this->stdout, $this->stderr);
|
||||
|
||||
if (filesize($tarPath) > 1024 * 1024 * 5) {
|
||||
throw new \Exception('Code package is too large. Use the chunked upload method instead.');
|
||||
}
|
||||
|
||||
return new CURLFile($tarPath, 'application/x-gzip', \basename($tarPath));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Tests\E2E\Services\GraphQL;
|
||||
|
||||
use CURLFile;
|
||||
use Tests\E2E\Client;
|
||||
use Tests\E2E\Scopes\ProjectCustom;
|
||||
use Tests\E2E\Scopes\Scope;
|
||||
@@ -83,10 +82,6 @@ class FunctionsClientTest extends Scope
|
||||
$projectId = $this->getProject()['$id'];
|
||||
$query = $this->getQuery(self::$CREATE_DEPLOYMENT);
|
||||
|
||||
$folder = 'php';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz";
|
||||
$this->packageCode($folder);
|
||||
|
||||
$gqlPayload = [
|
||||
'operations' => \json_encode([
|
||||
'query' => $query,
|
||||
@@ -99,7 +94,7 @@ class FunctionsClientTest extends Scope
|
||||
'map' => \json_encode([
|
||||
'code' => ["variables.code"]
|
||||
]),
|
||||
'code' => new CURLFile($code, 'application/gzip', 'code.tar.gz'),
|
||||
'code' => $this->packageFunction('php')
|
||||
];
|
||||
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/graphql', [
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Tests\E2E\Services\GraphQL;
|
||||
|
||||
use CURLFile;
|
||||
use Tests\E2E\Client;
|
||||
use Tests\E2E\Scopes\ProjectCustom;
|
||||
use Tests\E2E\Scopes\Scope;
|
||||
@@ -82,10 +81,6 @@ class FunctionsServerTest extends Scope
|
||||
$projectId = $this->getProject()['$id'];
|
||||
$query = $this->getQuery(self::$CREATE_DEPLOYMENT);
|
||||
|
||||
$folder = 'php';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz";
|
||||
$this->packageCode($folder);
|
||||
|
||||
$gqlPayload = [
|
||||
'operations' => \json_encode([
|
||||
'query' => $query,
|
||||
@@ -98,7 +93,7 @@ class FunctionsServerTest extends Scope
|
||||
'map' => \json_encode([
|
||||
'code' => ["variables.code"]
|
||||
]),
|
||||
'code' => new CURLFile($code, 'application/gzip', 'code.tar.gz'),
|
||||
'code' => $this->packageFunction('php'),
|
||||
];
|
||||
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/graphql', \array_merge([
|
||||
|
||||
@@ -7,25 +7,34 @@ use WebSocket\ConnectionException;
|
||||
|
||||
trait RealtimeBase
|
||||
{
|
||||
private function getWebsocket($channels = [], $headers = [], $projectId = null): WebSocketClient
|
||||
{
|
||||
private function getWebsocket(
|
||||
array $channels = [],
|
||||
array $headers = [],
|
||||
string $projectId = null
|
||||
): WebSocketClient {
|
||||
if (is_null($projectId)) {
|
||||
$projectId = $this->getProject()['$id'];
|
||||
}
|
||||
|
||||
$headers = array_merge([
|
||||
'Origin' => 'appwrite.test'
|
||||
], $headers);
|
||||
$headers = array_merge(
|
||||
[
|
||||
"Origin" => "appwrite.test",
|
||||
],
|
||||
$headers
|
||||
);
|
||||
|
||||
$query = [
|
||||
'project' => $projectId,
|
||||
'channels' => $channels
|
||||
"project" => $projectId,
|
||||
"channels" => $channels,
|
||||
];
|
||||
|
||||
return new WebSocketClient('ws://appwrite-traefik/v1/realtime?' . http_build_query($query), [
|
||||
'headers' => $headers,
|
||||
'timeout' => 30,
|
||||
]);
|
||||
return new WebSocketClient(
|
||||
"ws://appwrite-traefik/v1/realtime?" . http_build_query($query),
|
||||
[
|
||||
"headers" => $headers,
|
||||
"timeout" => 30,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function testConnection(): void
|
||||
@@ -33,7 +42,7 @@ trait RealtimeBase
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$client = $this->getWebsocket(['documents']);
|
||||
$client = $this->getWebsocket(["documents"]);
|
||||
$this->assertNotEmpty($client->receive());
|
||||
$client->close();
|
||||
}
|
||||
@@ -43,11 +52,11 @@ trait RealtimeBase
|
||||
$client = $this->getWebsocket();
|
||||
$payload = json_decode($client->receive(), true);
|
||||
|
||||
$this->assertArrayHasKey('type', $payload);
|
||||
$this->assertArrayHasKey('data', $payload);
|
||||
$this->assertEquals('error', $payload['type']);
|
||||
$this->assertEquals(1008, $payload['data']['code']);
|
||||
$this->assertEquals('Missing channels', $payload['data']['message']);
|
||||
$this->assertArrayHasKey("type", $payload);
|
||||
$this->assertArrayHasKey("data", $payload);
|
||||
$this->assertEquals("error", $payload["type"]);
|
||||
$this->assertEquals(1008, $payload["data"]["code"]);
|
||||
$this->assertEquals("Missing channels", $payload["data"]["message"]);
|
||||
\usleep(250000); // 250ms
|
||||
$this->expectException(ConnectionException::class); // Check if server disconnnected client
|
||||
$client->close();
|
||||
@@ -55,18 +64,24 @@ trait RealtimeBase
|
||||
|
||||
public function testConnectionFailureUnknownProject(): void
|
||||
{
|
||||
$client = new WebSocketClient('ws://appwrite-traefik/v1/realtime?project=123', [
|
||||
'headers' => [
|
||||
'Origin' => 'appwrite.test'
|
||||
$client = new WebSocketClient(
|
||||
"ws://appwrite-traefik/v1/realtime?project=123",
|
||||
[
|
||||
"headers" => [
|
||||
"Origin" => "appwrite.test",
|
||||
],
|
||||
]
|
||||
]);
|
||||
);
|
||||
$payload = json_decode($client->receive(), true);
|
||||
|
||||
$this->assertArrayHasKey('type', $payload);
|
||||
$this->assertArrayHasKey('data', $payload);
|
||||
$this->assertEquals('error', $payload['type']);
|
||||
$this->assertEquals(1008, $payload['data']['code']);
|
||||
$this->assertEquals('Missing or unknown project ID', $payload['data']['message']);
|
||||
$this->assertArrayHasKey("type", $payload);
|
||||
$this->assertArrayHasKey("data", $payload);
|
||||
$this->assertEquals("error", $payload["type"]);
|
||||
$this->assertEquals(1008, $payload["data"]["code"]);
|
||||
$this->assertEquals(
|
||||
"Missing or unknown project ID",
|
||||
$payload["data"]["message"]
|
||||
);
|
||||
\usleep(250000); // 250ms
|
||||
$this->expectException(ConnectionException::class); // Check if server disconnnected client
|
||||
$client->close();
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Tests\E2E\Services\Realtime;
|
||||
|
||||
use CURLFile;
|
||||
use Tests\E2E\Client;
|
||||
use Tests\E2E\Scopes\ProjectCustom;
|
||||
use Tests\E2E\Scopes\Scope;
|
||||
@@ -19,7 +18,7 @@ class RealtimeConsoleClientTest extends Scope
|
||||
use ProjectCustom;
|
||||
use SideConsole;
|
||||
|
||||
public function testManualAuthentication()
|
||||
public function testManualAuthentication(): void
|
||||
{
|
||||
$user = $this->getUser();
|
||||
$userId = $user['$id'] ?? '';
|
||||
@@ -124,7 +123,7 @@ class RealtimeConsoleClientTest extends Scope
|
||||
$client->close();
|
||||
}
|
||||
|
||||
public function testAttributes()
|
||||
public function testAttributes(): array
|
||||
{
|
||||
$user = $this->getUser();
|
||||
$projectId = 'console';
|
||||
@@ -184,6 +183,7 @@ class RealtimeConsoleClientTest extends Scope
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
$projectId = $this->getProject()['$id'];
|
||||
$attributeKey = $name['body']['key'];
|
||||
|
||||
$this->assertEquals($name['headers']['status-code'], 202);
|
||||
@@ -198,8 +198,9 @@ class RealtimeConsoleClientTest extends Scope
|
||||
$this->assertEquals('event', $response['type']);
|
||||
$this->assertNotEmpty($response['data']);
|
||||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertCount(1, $response['data']['channels']);
|
||||
$this->assertCount(2, $response['data']['channels']);
|
||||
$this->assertContains('console', $response['data']['channels']);
|
||||
$this->assertContains("projects.{$projectId}", $response['data']['channels']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}.attributes.*.create", $response['data']['events']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}.attributes.*", $response['data']['events']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}", $response['data']['events']);
|
||||
@@ -218,8 +219,9 @@ class RealtimeConsoleClientTest extends Scope
|
||||
$this->assertEquals('event', $response['type']);
|
||||
$this->assertNotEmpty($response['data']);
|
||||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertCount(1, $response['data']['channels']);
|
||||
$this->assertCount(2, $response['data']['channels']);
|
||||
$this->assertContains('console', $response['data']['channels']);
|
||||
$this->assertContains("projects.{$projectId}", $response['data']['channels']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}.attributes.*.update", $response['data']['events']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}.attributes.*", $response['data']['events']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}", $response['data']['events']);
|
||||
@@ -276,6 +278,8 @@ class RealtimeConsoleClientTest extends Scope
|
||||
]);
|
||||
|
||||
$this->assertEquals($index['headers']['status-code'], 202);
|
||||
|
||||
$projectId = $this->getProject()['$id'];
|
||||
$indexKey = $index['body']['key'];
|
||||
|
||||
$response = json_decode($client->receive(), true);
|
||||
@@ -285,8 +289,9 @@ class RealtimeConsoleClientTest extends Scope
|
||||
$this->assertEquals('event', $response['type']);
|
||||
$this->assertNotEmpty($response['data']);
|
||||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertCount(1, $response['data']['channels']);
|
||||
$this->assertCount(2, $response['data']['channels']);
|
||||
$this->assertContains('console', $response['data']['channels']);
|
||||
$this->assertContains("projects.{$projectId}", $response['data']['channels']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}.indexes.*.create", $response['data']['events']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}.indexes.*", $response['data']['events']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}", $response['data']['events']);
|
||||
@@ -303,8 +308,9 @@ class RealtimeConsoleClientTest extends Scope
|
||||
$this->assertEquals('event', $response['type']);
|
||||
$this->assertNotEmpty($response['data']);
|
||||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertCount(1, $response['data']['channels']);
|
||||
$this->assertCount(2, $response['data']['channels']);
|
||||
$this->assertContains('console', $response['data']['channels']);
|
||||
$this->assertContains("projects.{$projectId}", $response['data']['channels']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}.indexes.*.update", $response['data']['events']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}.indexes.*", $response['data']['events']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}", $response['data']['events']);
|
||||
@@ -343,6 +349,8 @@ class RealtimeConsoleClientTest extends Scope
|
||||
$this->assertContains('console', $response['data']['channels']);
|
||||
$this->assertNotEmpty($response['data']['user']);
|
||||
|
||||
$projectId = $this->getProject()['$id'];
|
||||
|
||||
/**
|
||||
* Test Delete Index
|
||||
*/
|
||||
@@ -353,6 +361,7 @@ class RealtimeConsoleClientTest extends Scope
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals($attribute['headers']['status-code'], 204);
|
||||
|
||||
$response = json_decode($client->receive(), true);
|
||||
|
||||
$this->assertArrayHasKey('type', $response);
|
||||
@@ -360,8 +369,9 @@ class RealtimeConsoleClientTest extends Scope
|
||||
$this->assertEquals('event', $response['type']);
|
||||
$this->assertNotEmpty($response['data']);
|
||||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertCount(1, $response['data']['channels']);
|
||||
$this->assertCount(2, $response['data']['channels']);
|
||||
$this->assertContains('console', $response['data']['channels']);
|
||||
$this->assertContains("projects.{$projectId}", $response['data']['channels']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}.indexes.*.update", $response['data']['events']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}.indexes.*", $response['data']['events']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}", $response['data']['events']);
|
||||
@@ -377,8 +387,9 @@ class RealtimeConsoleClientTest extends Scope
|
||||
$this->assertEquals('event', $response['type']);
|
||||
$this->assertNotEmpty($response['data']);
|
||||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertCount(1, $response['data']['channels']);
|
||||
$this->assertCount(2, $response['data']['channels']);
|
||||
$this->assertContains('console', $response['data']['channels']);
|
||||
$this->assertContains("projects.{$projectId}", $response['data']['channels']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}.indexes.*.delete", $response['data']['events']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}.indexes.*", $response['data']['events']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}", $response['data']['events']);
|
||||
@@ -416,10 +427,12 @@ class RealtimeConsoleClientTest extends Scope
|
||||
$this->assertContains('console', $response['data']['channels']);
|
||||
$this->assertNotEmpty($response['data']['user']);
|
||||
|
||||
$attributeKey = 'name';
|
||||
$projectId = $this->getProject()['$id'];
|
||||
|
||||
/**
|
||||
* Test Delete Attribute
|
||||
*/
|
||||
$attributeKey = 'name';
|
||||
$attribute = $this->client->call(Client::METHOD_DELETE, '/databases/' . $databaseId . '/collections/' . $data['actorsId'] . '/attributes/' . $attributeKey, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
@@ -433,8 +446,9 @@ class RealtimeConsoleClientTest extends Scope
|
||||
$this->assertEquals('event', $response['type']);
|
||||
$this->assertNotEmpty($response['data']);
|
||||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertCount(1, $response['data']['channels']);
|
||||
$this->assertCount(2, $response['data']['channels']);
|
||||
$this->assertContains('console', $response['data']['channels']);
|
||||
$this->assertContains("projects.{$projectId}", $response['data']['channels']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}.attributes.*.update", $response['data']['events']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}.attributes.*", $response['data']['events']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}", $response['data']['events']);
|
||||
@@ -450,8 +464,9 @@ class RealtimeConsoleClientTest extends Scope
|
||||
$this->assertEquals('event', $response['type']);
|
||||
$this->assertNotEmpty($response['data']);
|
||||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertCount(1, $response['data']['channels']);
|
||||
$this->assertCount(2, $response['data']['channels']);
|
||||
$this->assertContains('console', $response['data']['channels']);
|
||||
$this->assertContains("projects.{$projectId}", $response['data']['channels']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}.attributes.*.delete", $response['data']['events']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}.attributes.*", $response['data']['events']);
|
||||
$this->assertContains("databases.{$databaseId}.collections.{$actorsId}", $response['data']['events']);
|
||||
@@ -505,22 +520,16 @@ class RealtimeConsoleClientTest extends Scope
|
||||
/**
|
||||
* Test Create Deployment
|
||||
*/
|
||||
|
||||
$folder = 'php';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz";
|
||||
$this->packageCode($folder);
|
||||
|
||||
$projectId = $this->getProject()['$id'];
|
||||
$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-project' => $projectId,
|
||||
], $this->getHeaders()), [
|
||||
'entrypoint' => 'index.php',
|
||||
'code' => new CURLFile($code, 'application/x-gzip', \basename($code)),
|
||||
'code' => $this->packageFunction('php'),
|
||||
'activate' => true
|
||||
]);
|
||||
|
||||
$deploymentId = $deployment['body']['$id'] ?? '';
|
||||
|
||||
$this->assertEquals(202, $deployment['headers']['status-code']);
|
||||
|
||||
$response = json_decode($client->receive(), true);
|
||||
@@ -530,8 +539,9 @@ class RealtimeConsoleClientTest extends Scope
|
||||
$this->assertEquals('event', $response['type']);
|
||||
$this->assertNotEmpty($response['data']);
|
||||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertCount(1, $response['data']['channels']);
|
||||
$this->assertCount(2, $response['data']['channels']);
|
||||
$this->assertContains('console', $response['data']['channels']);
|
||||
$this->assertContains("projects.{$projectId}", $response['data']['channels']);
|
||||
// $this->assertContains("functions.{$functionId}.deployments.{$deploymentId}.create", $response['data']['events']); TODO @christyjacob4 : enable test once we allow functions.* events
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ use Tests\E2E\Client;
|
||||
use Tests\E2E\Scopes\ProjectCustom;
|
||||
use Tests\E2E\Scopes\Scope;
|
||||
use Tests\E2E\Scopes\SideClient;
|
||||
use Utopia\CLI\Console;
|
||||
use Tests\E2E\Services\Functions\FunctionsBase;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Helpers\Permission;
|
||||
use Utopia\Database\Helpers\Role;
|
||||
@@ -15,6 +15,7 @@ use WebSocket\ConnectionException;
|
||||
|
||||
class RealtimeCustomClientTest extends Scope
|
||||
{
|
||||
use FunctionsBase;
|
||||
use RealtimeBase;
|
||||
use ProjectCustom;
|
||||
use SideClient;
|
||||
@@ -1271,20 +1272,13 @@ class RealtimeCustomClientTest extends Scope
|
||||
$this->assertEquals($function['headers']['status-code'], 201);
|
||||
$this->assertNotEmpty($function['body']['$id']);
|
||||
|
||||
$folder = 'timeout';
|
||||
$stderr = '';
|
||||
$stdout = '';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions') . "/{$folder}/code.tar.gz";
|
||||
|
||||
Console::execute('cd ' . realpath(__DIR__ . "/../../../resources/functions") . "/{$folder} && tar --exclude code.tar.gz -czf code.tar.gz .", '', $stdout, $stderr);
|
||||
|
||||
$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']
|
||||
]), [
|
||||
'entrypoint' => 'index.php',
|
||||
'code' => new CURLFile($code, 'application/x-gzip', basename($code)),
|
||||
'code' => $this->packageFunction('timeout'),
|
||||
'activate' => true
|
||||
]);
|
||||
|
||||
@@ -1340,8 +1334,9 @@ class RealtimeCustomClientTest extends Scope
|
||||
$this->assertEquals('event', $response['type']);
|
||||
$this->assertNotEmpty($response['data']);
|
||||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertCount(4, $response['data']['channels']);
|
||||
$this->assertCount(5, $response['data']['channels']);
|
||||
$this->assertContains('console', $response['data']['channels']);
|
||||
$this->assertContains("projects.{$this->getProject()['$id']}", $response['data']['channels']);
|
||||
$this->assertContains('executions', $response['data']['channels']);
|
||||
$this->assertContains("executions.{$executionId}", $response['data']['channels']);
|
||||
$this->assertContains("functions.{$functionId}", $response['data']['channels']);
|
||||
@@ -1362,8 +1357,9 @@ class RealtimeCustomClientTest extends Scope
|
||||
$this->assertEquals('event', $responseUpdate['type']);
|
||||
$this->assertNotEmpty($responseUpdate['data']);
|
||||
$this->assertArrayHasKey('timestamp', $responseUpdate['data']);
|
||||
$this->assertCount(4, $responseUpdate['data']['channels']);
|
||||
$this->assertCount(5, $responseUpdate['data']['channels']);
|
||||
$this->assertContains('console', $responseUpdate['data']['channels']);
|
||||
$this->assertContains("projects.{$this->getProject()['$id']}", $response['data']['channels']);
|
||||
$this->assertContains('executions', $responseUpdate['data']['channels']);
|
||||
$this->assertContains("executions.{$executionId}", $responseUpdate['data']['channels']);
|
||||
$this->assertContains("functions.{$functionId}", $responseUpdate['data']['channels']);
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Tests;
|
||||
|
||||
use Appwrite\Tests\Async\Eventually;
|
||||
use PHPUnit\Framework\Assert;
|
||||
|
||||
const DEFAULT_TIMEOUT_MS = 10000;
|
||||
const DEFAULT_WAIT_MS = 500;
|
||||
|
||||
trait Async
|
||||
{
|
||||
public static function assertEventually(callable $probe, int $timeoutMs = DEFAULT_TIMEOUT_MS, int $waitMs = DEFAULT_WAIT_MS): void
|
||||
{
|
||||
Assert::assertThat($probe, new Eventually($timeoutMs, $waitMs));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Tests\Async;
|
||||
|
||||
use PHPUnit\Framework\Constraint\Constraint;
|
||||
|
||||
final class Eventually extends Constraint
|
||||
{
|
||||
public function __construct(private int $timeoutMs, private int $waitMs)
|
||||
{
|
||||
}
|
||||
|
||||
public function evaluate(mixed $probe, string $description = '', bool $returnResult = false): ?bool
|
||||
{
|
||||
if (!is_callable($probe)) {
|
||||
throw new \Exception('Probe must be a callable');
|
||||
}
|
||||
|
||||
$start = microtime(true);
|
||||
$lastException = null;
|
||||
|
||||
do {
|
||||
try {
|
||||
$probe();
|
||||
return true;
|
||||
} catch (\Exception $exception) {
|
||||
$lastException = $exception;
|
||||
}
|
||||
|
||||
usleep($this->waitMs * 1000);
|
||||
} while (microtime(true) - $start < $this->timeoutMs / 1000);
|
||||
|
||||
if ($returnResult) {
|
||||
return false;
|
||||
}
|
||||
|
||||
throw $lastException;
|
||||
}
|
||||
|
||||
protected function failureDescription(mixed $other): string
|
||||
{
|
||||
return 'the given probe was satisfied within ' . $this->timeoutMs . 'ms.';
|
||||
}
|
||||
|
||||
public function toString(): string
|
||||
{
|
||||
return 'Eventually';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user