mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Merge branch '1.7.x' into fix-SER-67-prevent-sub-subdomains-appwrite-network
This commit is contained in:
+25
-1
@@ -9,7 +9,31 @@ You can [find issues using this query](https://github.com/search?q=org%3Aappwrit
|
||||
|
||||
## How to Start?
|
||||
|
||||
If you are worried or don’t know where to start, check out the next section that explains what kind of help we could use and where you can get involved. You can send your questions to [@appwrite on Twitter](https://twitter.com/appwrite) or to anyone from the [Appwrite team on Discord](https://appwrite.io/discord). You can also submit an issue, and a maintainer can guide you!
|
||||
Welcome! We're excited that you're interested in contributing to Appwrite. To make sure your time is valued and your contributions are successful, please follow these steps before writing any code:
|
||||
|
||||
### 🔍 Step 1: Find an Issue
|
||||
|
||||
Browse open issues and look for ones labeled [good first issue](https://github.com/search?q=org%3Aappwrite+is%3Aopen+type%3Aissue+label%3A%22good+first+issue%22&type=issues) or [help wanted](https://github.com/search?q=org%3Aappwrite+is%3Aopen+type%3Aissue+label%3A%22help+wanted%22&type=issues).
|
||||
|
||||
If you're not sure which issue to pick, ask in our [maintainers channel](https://discord.com/channels/564160730845151244/636852860709240842) on Discord.
|
||||
|
||||
### 📝 Step 2: Ask to Be Assigned
|
||||
|
||||
Before working on an issue, comment on the GitHub issue asking to be assigned. This prevents multiple people working on the same task.
|
||||
|
||||
Then, create a thread in the [maintainers channel](https://discord.com/channels/564160730845151244/636852860709240842) on Discord with a link to the issue.
|
||||
|
||||
Our team is small and may not see your GitHub comment right away - posting in the [maintainers channel](https://discord.com/channels/564160730845151244/636852860709240842) ensures it gets seen.
|
||||
|
||||
### 💬 Step 3: Don’t Submit Random PRs
|
||||
|
||||
If you're not working on an assigned issue, create a GitHub issue first.
|
||||
|
||||
PRs submitted without context or discussion may not align with our roadmap and may be closed without review.
|
||||
|
||||
### ⚠️ Please Note
|
||||
|
||||
We’re a very small team managing a large project. Many PRs are submitted, and while we appreciate every effort, we can only review contributions that follow the process above. This helps us keep things fair and organized.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
|
||||
+9
-3
@@ -191,9 +191,15 @@ CLI::setResource('getLogsDB', function (Group $pools, Cache $cache) {
|
||||
CLI::setResource('publisher', function (Group $pools) {
|
||||
return new BrokerPool(publisher: $pools->get('publisher'));
|
||||
}, ['pools']);
|
||||
CLI::setResource('publisherRedis', function () {
|
||||
// Stub
|
||||
});
|
||||
CLI::setResource('publisherDatabases', function (BrokerPool $publisher) {
|
||||
return $publisher;
|
||||
}, ['publisher']);
|
||||
CLI::setResource('publisherMigrations', function (BrokerPool $publisher) {
|
||||
return $publisher;
|
||||
}, ['publisher']);
|
||||
CLI::setResource('publisherStatsUsage', function (BrokerPool $publisher) {
|
||||
return $publisher;
|
||||
}, ['publisher']);
|
||||
CLI::setResource('queueForStatsUsage', function (Publisher $publisher) {
|
||||
return new StatsUsage($publisher);
|
||||
}, ['publisher']);
|
||||
|
||||
@@ -120,6 +120,11 @@
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div style="display: none; overflow: hidden; max-height: 0; max-width: 0; opacity: 0; line-height: 1px;">
|
||||
{{preview}}
|
||||
<div>{{previewWhitespace}}</div>
|
||||
</div>
|
||||
|
||||
<div class="main">
|
||||
<table>
|
||||
<tr>
|
||||
|
||||
@@ -121,6 +121,11 @@
|
||||
|
||||
<body style="direction: {{direction}}">
|
||||
|
||||
<div style="display: none; overflow: hidden; max-height: 0; max-width: 0; opacity: 0; line-height: 1px;">
|
||||
{{preview}}
|
||||
<div>{{previewWhitespace}}</div>
|
||||
</div>
|
||||
|
||||
<div style="max-width:650px; word-wrap: break-word; overflow-wrap: break-word;
|
||||
word-break: normal; margin:0 auto;">
|
||||
<table style="margin-top: 32px">
|
||||
|
||||
@@ -9,4 +9,4 @@
|
||||
<p>If you have trouble with the sender's image, ensure it is set in the <a href="https://gravatar.com/">Gravatar database</a>.</p>
|
||||
|
||||
<p style="margin-block-end: 0;">Best regards,</p>
|
||||
<p style="margin-block-start: 0;">Appwrtite team</p>
|
||||
<p style="margin-block-start: 0;">Appwrite team</p>
|
||||
@@ -14,7 +14,7 @@
|
||||
<table border="0" cellspacing="0" cellpadding="0" style="padding-top: 10px; padding-bottom: 10px; margin-top: 32px">
|
||||
<tr>
|
||||
<td style="border-radius: 8px; display: block; width: 100%;">
|
||||
<a class="mobile-full-width" rel="noopener" target="_blank" href="{{host}}{{path}}" style="font-size: 14px; font-family: Inter; color: #ffffff; text-decoration: none; background-color: #FD366E; border-radius: 8px; padding: 9px 14px; border: 1px solid #FD366E; display: inline-block; text-align:center; box-sizing: border-box;">Webhook settings</a>
|
||||
<a class="mobile-full-width" rel="noopener" target="_blank" href="{{host}}{{path}}" style="font-size: 14px; font-family: Inter; color: #ffffff; text-decoration: none; background-color: #2D2D31; border-radius: 8px; padding: 9px 14px; border: 1px solid #414146; display: inline-block; text-align:center; box-sizing: border-box;">Webhook settings</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -4,6 +4,7 @@
|
||||
"settings.direction": "ltr",
|
||||
"emails.sender": "%s Team",
|
||||
"emails.verification.subject": "Account Verification",
|
||||
"emails.verification.preview": "Verify your email to activate your {{project}} account.",
|
||||
"emails.verification.hello": "Hello {{user}},",
|
||||
"emails.verification.body": "Follow this link to verify your email address to your {{b}}{{project}}{{/b}} account.",
|
||||
"emails.verification.footer": "If you didn’t ask to verify this address, you can ignore this message.",
|
||||
@@ -11,6 +12,7 @@
|
||||
"emails.verification.buttonText": "Confirm email address",
|
||||
"emails.verification.signature": "{{project}} team",
|
||||
"emails.magicSession.subject": "{{project}} Login",
|
||||
"emails.magicSession.preview": "Sign in to {{project}} with your secure link. Expires in 1 hour.",
|
||||
"emails.magicSession.hello": "Hello {{user}},",
|
||||
"emails.magicSession.optionButton": "Click the button below to securely sign in to your {{b}}{{project}}{{/b}} account. This link will expire in 1 hour.",
|
||||
"emails.magicSession.buttonText": "Sign in to {{project}}",
|
||||
@@ -20,6 +22,7 @@
|
||||
"emails.magicSession.thanks": "Thanks,",
|
||||
"emails.magicSession.signature": "{{project}} team",
|
||||
"emails.sessionAlert.subject": "Security alert: new session on your {{project}} account",
|
||||
"emails.sessionAlert.preview": "New login detected on {{project}} at {{time}} UTC.",
|
||||
"emails.sessionAlert.hello": "Hello {{user}},",
|
||||
"emails.sessionAlert.body": "A new session has been created on your {{b}}{{project}}{{/b}} account, {{b}}on {{date}}, {{year}} at {{time}} UTC{{/b}}.\nHere are the details of the new session: ",
|
||||
"emails.sessionAlert.listDevice": "Device: {{b}}{{device}}{{/b}}",
|
||||
@@ -29,6 +32,7 @@
|
||||
"emails.sessionAlert.thanks": "Thanks,",
|
||||
"emails.sessionAlert.signature": "{{project}} team",
|
||||
"emails.otpSession.subject": "OTP for {{project}} Login",
|
||||
"emails.otpSession.preview": "Use OTP {{otp}} to sign in to {{project}}. Expires in 15 minutes.",
|
||||
"emails.otpSession.hello": "Hello {{user}},",
|
||||
"emails.otpSession.description": "Enter the following verification code when prompted to securely sign in to your {{b}}{{project}}{{/b}} account. This code will expire in 15 minutes.",
|
||||
"emails.otpSession.clientInfo": "This sign in was requested using {{b}}{{agentClient}}{{/b}} on {{b}}{{agentDevice}}{{/b}} {{b}}{{agentOs}}{{/b}}. If you didn't request the sign in, you can safely ignore this email.",
|
||||
@@ -36,12 +40,14 @@
|
||||
"emails.otpSession.thanks": "Thanks,",
|
||||
"emails.otpSession.signature": "{{project}} team",
|
||||
"emails.mfaChallenge.subject": "Verification Code for {{project}}",
|
||||
"emails.mfaChallenge.preview": "Use code {{otp}} for two-step verification in {{project}}. Expires in 15 minutes.",
|
||||
"emails.mfaChallenge.hello": "Hello {{user}},",
|
||||
"emails.mfaChallenge.description": "Enter the following verification code to verify your email and activate two-step verification in {{b}}{{project}}{{/b}}. This code will expire in 15 minutes.",
|
||||
"emails.mfaChallenge.description": "Enter the following code to confirm your two-step verification in {{b}}{{project}}{{/b}}. This code will expire in 15 minutes.",
|
||||
"emails.mfaChallenge.clientInfo": "This verification code was requested using {{b}}{{agentClient}}{{/b}} on {{b}}{{agentDevice}}{{/b}} {{b}}{{agentOs}}{{/b}}. If you didn't request the verification code, you can safely ignore this email.",
|
||||
"emails.mfaChallenge.thanks": "Thanks,",
|
||||
"emails.mfaChallenge.signature": "{{project}} team",
|
||||
"emails.recovery.subject": "Password Reset",
|
||||
"emails.recovery.preview": "Reset your {{project}} password using the link.",
|
||||
"emails.recovery.hello": "Hello {{user}},",
|
||||
"emails.recovery.body": "Follow this link to reset your {{b}}{{project}}{{/b}} password.",
|
||||
"emails.recovery.footer": "If you didn't ask to reset your password, you can ignore this message.",
|
||||
@@ -49,6 +55,7 @@
|
||||
"emails.recovery.buttonText": "Reset password",
|
||||
"emails.recovery.signature": "{{project}} team",
|
||||
"emails.invitation.subject": "Invitation to %s Team at %s",
|
||||
"emails.invitation.preview": "{{owner}} invited you to join {{team}} at {{project}}",
|
||||
"emails.invitation.hello": "Hello {{user}},",
|
||||
"emails.invitation.body": "This mail was sent to you because {{b}}{{owner}}{{/b}} wanted to invite you to become a member of the {{b}}{{team}}{{/b}} team at {{b}}{{project}}{{/b}}.",
|
||||
"emails.invitation.footer": "If you are not interested, you can ignore this message.",
|
||||
@@ -56,6 +63,7 @@
|
||||
"emails.invitation.buttonText": "Accept invite to {{team}}",
|
||||
"emails.invitation.signature": "{{project}} team",
|
||||
"emails.certificate.subject": "Certificate failure for %s",
|
||||
"emails.certificate.preview": "Your domain %s certificate generation has failed.",
|
||||
"emails.certificate.hello": "Hello,",
|
||||
"emails.certificate.body": "Certificate for your domain '{{domain}}' could not be generated. This is attempt no. {{attempt}}, and the failure was caused by: {{error}}",
|
||||
"emails.certificate.footer": "Your previous certificate will be valid for 30 days since the first failure. We highly recommend investigating this case, otherwise your domain will end up without a valid SSL communication.",
|
||||
|
||||
@@ -4467,10 +4467,7 @@
|
||||
{
|
||||
"name": "createDocument",
|
||||
"auth": {
|
||||
"Admin": [],
|
||||
"Session": [],
|
||||
"Key": [],
|
||||
"JWT": []
|
||||
"Project": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
|
||||
@@ -8026,10 +8026,7 @@
|
||||
{
|
||||
"name": "createDocument",
|
||||
"auth": {
|
||||
"Admin": [],
|
||||
"Session": [],
|
||||
"Key": [],
|
||||
"JWT": []
|
||||
"Project": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
@@ -8055,8 +8052,7 @@
|
||||
{
|
||||
"name": "createDocuments",
|
||||
"auth": {
|
||||
"Admin": [],
|
||||
"Key": []
|
||||
"Project": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
|
||||
@@ -7507,10 +7507,8 @@
|
||||
{
|
||||
"name": "createDocument",
|
||||
"auth": {
|
||||
"Admin": [],
|
||||
"Session": [],
|
||||
"Key": [],
|
||||
"JWT": []
|
||||
"Project": [],
|
||||
"Session": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
@@ -7536,7 +7534,7 @@
|
||||
{
|
||||
"name": "createDocuments",
|
||||
"auth": {
|
||||
"Admin": [],
|
||||
"Project": [],
|
||||
"Key": []
|
||||
},
|
||||
"parameters": [
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -4467,10 +4467,7 @@
|
||||
{
|
||||
"name": "createDocument",
|
||||
"auth": {
|
||||
"Admin": [],
|
||||
"Session": [],
|
||||
"Key": [],
|
||||
"JWT": []
|
||||
"Project": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
@@ -4492,6 +4489,30 @@
|
||||
}
|
||||
],
|
||||
"description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
|
||||
},
|
||||
{
|
||||
"name": "createDocuments",
|
||||
"auth": {
|
||||
"Admin": [],
|
||||
"Key": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
"collectionId",
|
||||
"documents"
|
||||
],
|
||||
"required": [
|
||||
"databaseId",
|
||||
"collectionId",
|
||||
"documents"
|
||||
],
|
||||
"responses": [
|
||||
{
|
||||
"code": 201,
|
||||
"model": "#\/components\/schemas\/documentList"
|
||||
}
|
||||
],
|
||||
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nCreate new Documents. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
|
||||
}
|
||||
],
|
||||
"auth": {
|
||||
|
||||
@@ -8026,10 +8026,7 @@
|
||||
{
|
||||
"name": "createDocument",
|
||||
"auth": {
|
||||
"Admin": [],
|
||||
"Session": [],
|
||||
"Key": [],
|
||||
"JWT": []
|
||||
"Project": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
@@ -8055,8 +8052,7 @@
|
||||
{
|
||||
"name": "createDocuments",
|
||||
"auth": {
|
||||
"Admin": [],
|
||||
"Key": []
|
||||
"Project": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
@@ -39702,6 +39698,11 @@
|
||||
"description": "Is VCS (Version Control System) repository private?",
|
||||
"x-example": true
|
||||
},
|
||||
"defaultBranch": {
|
||||
"type": "string",
|
||||
"description": "VCS (Version Control System) repository's default branch name.",
|
||||
"x-example": "main"
|
||||
},
|
||||
"pushedAt": {
|
||||
"type": "string",
|
||||
"description": "Last commit date in ISO 8601 format.",
|
||||
@@ -39714,6 +39715,7 @@
|
||||
"organization",
|
||||
"provider",
|
||||
"private",
|
||||
"defaultBranch",
|
||||
"pushedAt"
|
||||
]
|
||||
},
|
||||
@@ -39746,6 +39748,11 @@
|
||||
"description": "Is VCS (Version Control System) repository private?",
|
||||
"x-example": true
|
||||
},
|
||||
"defaultBranch": {
|
||||
"type": "string",
|
||||
"description": "VCS (Version Control System) repository's default branch name.",
|
||||
"x-example": "main"
|
||||
},
|
||||
"pushedAt": {
|
||||
"type": "string",
|
||||
"description": "Last commit date in ISO 8601 format.",
|
||||
@@ -39763,6 +39770,7 @@
|
||||
"organization",
|
||||
"provider",
|
||||
"private",
|
||||
"defaultBranch",
|
||||
"pushedAt",
|
||||
"framework"
|
||||
]
|
||||
@@ -39796,6 +39804,11 @@
|
||||
"description": "Is VCS (Version Control System) repository private?",
|
||||
"x-example": true
|
||||
},
|
||||
"defaultBranch": {
|
||||
"type": "string",
|
||||
"description": "VCS (Version Control System) repository's default branch name.",
|
||||
"x-example": "main"
|
||||
},
|
||||
"pushedAt": {
|
||||
"type": "string",
|
||||
"description": "Last commit date in ISO 8601 format.",
|
||||
@@ -39813,6 +39826,7 @@
|
||||
"organization",
|
||||
"provider",
|
||||
"private",
|
||||
"defaultBranch",
|
||||
"pushedAt",
|
||||
"runtime"
|
||||
]
|
||||
|
||||
@@ -7507,10 +7507,8 @@
|
||||
{
|
||||
"name": "createDocument",
|
||||
"auth": {
|
||||
"Admin": [],
|
||||
"Session": [],
|
||||
"Key": [],
|
||||
"JWT": []
|
||||
"Project": [],
|
||||
"Session": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
@@ -7536,7 +7534,7 @@
|
||||
{
|
||||
"name": "createDocuments",
|
||||
"auth": {
|
||||
"Admin": [],
|
||||
"Project": [],
|
||||
"Key": []
|
||||
},
|
||||
"parameters": [
|
||||
|
||||
@@ -4604,10 +4604,7 @@
|
||||
{
|
||||
"name": "createDocument",
|
||||
"auth": {
|
||||
"Admin": [],
|
||||
"Session": [],
|
||||
"Key": [],
|
||||
"JWT": []
|
||||
"Project": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
|
||||
@@ -8146,10 +8146,7 @@
|
||||
{
|
||||
"name": "createDocument",
|
||||
"auth": {
|
||||
"Admin": [],
|
||||
"Session": [],
|
||||
"Key": [],
|
||||
"JWT": []
|
||||
"Project": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
@@ -8175,8 +8172,7 @@
|
||||
{
|
||||
"name": "createDocuments",
|
||||
"auth": {
|
||||
"Admin": [],
|
||||
"Key": []
|
||||
"Project": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
|
||||
@@ -7617,10 +7617,8 @@
|
||||
{
|
||||
"name": "createDocument",
|
||||
"auth": {
|
||||
"Admin": [],
|
||||
"Session": [],
|
||||
"Key": [],
|
||||
"JWT": []
|
||||
"Project": [],
|
||||
"Session": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
@@ -7646,7 +7644,7 @@
|
||||
{
|
||||
"name": "createDocuments",
|
||||
"auth": {
|
||||
"Admin": [],
|
||||
"Project": [],
|
||||
"Key": []
|
||||
},
|
||||
"parameters": [
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -4604,10 +4604,7 @@
|
||||
{
|
||||
"name": "createDocument",
|
||||
"auth": {
|
||||
"Admin": [],
|
||||
"Session": [],
|
||||
"Key": [],
|
||||
"JWT": []
|
||||
"Project": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
@@ -4629,6 +4626,30 @@
|
||||
}
|
||||
],
|
||||
"description": "Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
|
||||
},
|
||||
{
|
||||
"name": "createDocuments",
|
||||
"auth": {
|
||||
"Admin": [],
|
||||
"Key": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
"collectionId",
|
||||
"documents"
|
||||
],
|
||||
"required": [
|
||||
"databaseId",
|
||||
"collectionId",
|
||||
"documents"
|
||||
],
|
||||
"responses": [
|
||||
{
|
||||
"code": 201,
|
||||
"model": "#\/definitions\/documentList"
|
||||
}
|
||||
],
|
||||
"description": "**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions.\n\nCreate new Documents. Before using this route, you should create a new collection resource using either a [server integration](https:\/\/appwrite.io\/docs\/server\/databases#databasesCreateCollection) API or directly from your database console."
|
||||
}
|
||||
],
|
||||
"auth": {
|
||||
|
||||
@@ -8146,10 +8146,7 @@
|
||||
{
|
||||
"name": "createDocument",
|
||||
"auth": {
|
||||
"Admin": [],
|
||||
"Session": [],
|
||||
"Key": [],
|
||||
"JWT": []
|
||||
"Project": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
@@ -8175,8 +8172,7 @@
|
||||
{
|
||||
"name": "createDocuments",
|
||||
"auth": {
|
||||
"Admin": [],
|
||||
"Key": []
|
||||
"Project": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
@@ -39878,6 +39874,11 @@
|
||||
"description": "Is VCS (Version Control System) repository private?",
|
||||
"x-example": true
|
||||
},
|
||||
"defaultBranch": {
|
||||
"type": "string",
|
||||
"description": "VCS (Version Control System) repository's default branch name.",
|
||||
"x-example": "main"
|
||||
},
|
||||
"pushedAt": {
|
||||
"type": "string",
|
||||
"description": "Last commit date in ISO 8601 format.",
|
||||
@@ -39890,6 +39891,7 @@
|
||||
"organization",
|
||||
"provider",
|
||||
"private",
|
||||
"defaultBranch",
|
||||
"pushedAt"
|
||||
]
|
||||
},
|
||||
@@ -39922,6 +39924,11 @@
|
||||
"description": "Is VCS (Version Control System) repository private?",
|
||||
"x-example": true
|
||||
},
|
||||
"defaultBranch": {
|
||||
"type": "string",
|
||||
"description": "VCS (Version Control System) repository's default branch name.",
|
||||
"x-example": "main"
|
||||
},
|
||||
"pushedAt": {
|
||||
"type": "string",
|
||||
"description": "Last commit date in ISO 8601 format.",
|
||||
@@ -39939,6 +39946,7 @@
|
||||
"organization",
|
||||
"provider",
|
||||
"private",
|
||||
"defaultBranch",
|
||||
"pushedAt",
|
||||
"framework"
|
||||
]
|
||||
@@ -39972,6 +39980,11 @@
|
||||
"description": "Is VCS (Version Control System) repository private?",
|
||||
"x-example": true
|
||||
},
|
||||
"defaultBranch": {
|
||||
"type": "string",
|
||||
"description": "VCS (Version Control System) repository's default branch name.",
|
||||
"x-example": "main"
|
||||
},
|
||||
"pushedAt": {
|
||||
"type": "string",
|
||||
"description": "Last commit date in ISO 8601 format.",
|
||||
@@ -39989,6 +40002,7 @@
|
||||
"organization",
|
||||
"provider",
|
||||
"private",
|
||||
"defaultBranch",
|
||||
"pushedAt",
|
||||
"runtime"
|
||||
]
|
||||
|
||||
@@ -7617,10 +7617,8 @@
|
||||
{
|
||||
"name": "createDocument",
|
||||
"auth": {
|
||||
"Admin": [],
|
||||
"Session": [],
|
||||
"Key": [],
|
||||
"JWT": []
|
||||
"Project": [],
|
||||
"Session": []
|
||||
},
|
||||
"parameters": [
|
||||
"databaseId",
|
||||
@@ -7646,7 +7644,7 @@
|
||||
{
|
||||
"name": "createDocuments",
|
||||
"auth": {
|
||||
"Admin": [],
|
||||
"Project": [],
|
||||
"Key": []
|
||||
},
|
||||
"parameters": [
|
||||
|
||||
@@ -71,6 +71,7 @@ $oauthDefaultFailure = '/console/auth/oauth2/failure';
|
||||
function sendSessionAlert(Locale $locale, Document $user, Document $project, Document $session, Mail $queueForMails)
|
||||
{
|
||||
$subject = $locale->getText("emails.sessionAlert.subject");
|
||||
$preview = $locale->getText("emails.sessionAlert.preview");
|
||||
$customTemplate = $project->getAttribute('templates', [])['email.sessionAlert-' . $locale->default] ?? [];
|
||||
|
||||
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-session-alert.tpl');
|
||||
@@ -132,6 +133,16 @@ function sendSessionAlert(Locale $locale, Document $user, Document $project, Doc
|
||||
->setSmtpSenderName($senderName);
|
||||
}
|
||||
|
||||
// session alerts should always have a client name!
|
||||
$clientName = $session->getAttribute('clientName');
|
||||
if (empty($clientName)) {
|
||||
// fallback to the user agent and then unknown!
|
||||
$userAgent = $session->getAttribute('userAgent');
|
||||
$clientName = !empty($userAgent) ? $userAgent : 'UNKNOWN';
|
||||
|
||||
$session->setAttribute('clientName', $clientName);
|
||||
}
|
||||
|
||||
$emailVariables = [
|
||||
'direction' => $locale->getText('settings.direction'),
|
||||
'date' => (new \DateTime())->format('F j'),
|
||||
@@ -148,6 +159,7 @@ function sendSessionAlert(Locale $locale, Document $user, Document $project, Doc
|
||||
|
||||
$queueForMails
|
||||
->setSubject($subject)
|
||||
->setPreview($preview)
|
||||
->setBody($body)
|
||||
->setVariables($emailVariables)
|
||||
->setRecipient($email)
|
||||
@@ -2025,6 +2037,7 @@ App::post('/v1/account/tokens/magic-url')
|
||||
$url = Template::unParseURL($url);
|
||||
|
||||
$subject = $locale->getText("emails.magicSession.subject");
|
||||
$preview = $locale->getText("emails.magicSession.preview");
|
||||
$customTemplate = $project->getAttribute('templates', [])['email.magicSession-' . $locale->default] ?? [];
|
||||
|
||||
$detector = new Detector($request->getUserAgent('UNKNOWN'));
|
||||
@@ -2113,6 +2126,7 @@ App::post('/v1/account/tokens/magic-url')
|
||||
|
||||
$queueForMails
|
||||
->setSubject($subject)
|
||||
->setPreview($preview)
|
||||
->setBody($body)
|
||||
->setVariables($emailVariables)
|
||||
->setRecipient($email)
|
||||
@@ -2254,6 +2268,7 @@ App::post('/v1/account/tokens/email')
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$subject = $locale->getText("emails.otpSession.subject");
|
||||
$preview = $locale->getText("emails.otpSession.preview");
|
||||
$customTemplate = $project->getAttribute('templates', [])['email.otpSession-' . $locale->default] ?? [];
|
||||
|
||||
$detector = new Detector($request->getUserAgent('UNKNOWN'));
|
||||
@@ -2339,6 +2354,7 @@ App::post('/v1/account/tokens/email')
|
||||
|
||||
$queueForMails
|
||||
->setSubject($subject)
|
||||
->setPreview($preview)
|
||||
->setBody($body)
|
||||
->setVariables($emailVariables)
|
||||
->setRecipient($email)
|
||||
@@ -3265,6 +3281,7 @@ App::post('/v1/account/recovery')
|
||||
$projectName = $project->isEmpty() ? 'Console' : $project->getAttribute('name', '[APP-NAME]');
|
||||
$body = $locale->getText("emails.recovery.body");
|
||||
$subject = $locale->getText("emails.recovery.subject");
|
||||
$preview = $locale->getText("emails.recovery.preview");
|
||||
$customTemplate = $project->getAttribute('templates', [])['email.recovery-' . $locale->default] ?? [];
|
||||
|
||||
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
|
||||
@@ -3339,6 +3356,7 @@ App::post('/v1/account/recovery')
|
||||
->setBody($body)
|
||||
->setVariables($emailVariables)
|
||||
->setSubject($subject)
|
||||
->setPreview($preview)
|
||||
->trigger();
|
||||
|
||||
$recovery->setAttribute('secret', $secret);
|
||||
@@ -3520,6 +3538,7 @@ App::post('/v1/account/verification')
|
||||
|
||||
$projectName = $project->isEmpty() ? 'Console' : $project->getAttribute('name', '[APP-NAME]');
|
||||
$body = $locale->getText("emails.verification.body");
|
||||
$preview = $locale->getText("emails.verification.preview");
|
||||
$subject = $locale->getText("emails.verification.subject");
|
||||
$customTemplate = $project->getAttribute('templates', [])['email.verification-' . $locale->default] ?? [];
|
||||
|
||||
@@ -3592,6 +3611,7 @@ App::post('/v1/account/verification')
|
||||
|
||||
$queueForMails
|
||||
->setSubject($subject)
|
||||
->setPreview($preview)
|
||||
->setBody($body)
|
||||
->setVariables($emailVariables)
|
||||
->setRecipient($user->getAttribute('email'))
|
||||
@@ -4437,6 +4457,7 @@ App::post('/v1/account/mfa/challenge')
|
||||
}
|
||||
|
||||
$subject = $locale->getText("emails.mfaChallenge.subject");
|
||||
$preview = $locale->getText("emails.mfaChallenge.preview");
|
||||
$customTemplate = $project->getAttribute('templates', [])['email.mfaChallenge-' . $locale->default] ?? [];
|
||||
|
||||
$detector = new Detector($request->getUserAgent('UNKNOWN'));
|
||||
@@ -4513,6 +4534,7 @@ App::post('/v1/account/mfa/challenge')
|
||||
|
||||
$queueForMails
|
||||
->setSubject($subject)
|
||||
->setPreview($preview)
|
||||
->setBody($body)
|
||||
->setVariables($emailVariables)
|
||||
->setRecipient($user->getAttribute('email'))
|
||||
|
||||
@@ -522,17 +522,11 @@ App::get('/v1/health/queue/databases')
|
||||
))
|
||||
->param('name', 'database_db_main', new Text(256), 'Queue name for which to check the queue size', true)
|
||||
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
|
||||
->inject('publisher')
|
||||
->inject('publisherRedis')
|
||||
->inject('publisherDatabases')
|
||||
->inject('response')
|
||||
->action(function (string $name, int|string $threshold, Publisher $publisher, ?Publisher $publisherRedis, Response $response) {
|
||||
->action(function (string $name, int|string $threshold, Publisher $publisherDatabases, Response $response) {
|
||||
$threshold = \intval($threshold);
|
||||
|
||||
$isRedisFallback = \str_contains(System::getEnv('_APP_WORKER_REDIS_FALLBACK', ''), 'databases');
|
||||
|
||||
$size = $isRedisFallback
|
||||
? $publisherRedis->getQueueSize(new Queue($name))
|
||||
: $publisher->getQueueSize(new Queue($name));
|
||||
$size = $publisherDatabases->getQueueSize(new Queue($name));
|
||||
|
||||
if ($size >= $threshold) {
|
||||
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
@@ -659,17 +653,12 @@ App::get('/v1/health/queue/migrations')
|
||||
contentType: ContentType::JSON
|
||||
))
|
||||
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
|
||||
->inject('publisher')
|
||||
->inject('publisherRedis')
|
||||
->inject('publisherMigrations')
|
||||
->inject('response')
|
||||
->action(function (int|string $threshold, Publisher $publisher, ?Publisher $publisherRedis, Response $response) {
|
||||
->action(function (int|string $threshold, Publisher $publisherMigrations, Response $response) {
|
||||
$threshold = \intval($threshold);
|
||||
|
||||
$isRedisFallback = \str_contains(System::getEnv('_APP_WORKER_REDIS_FALLBACK', ''), 'migrations');
|
||||
|
||||
$size = $isRedisFallback
|
||||
? $publisherRedis->getQueueSize(new Queue(Event::MIGRATIONS_QUEUE_NAME))
|
||||
: $publisher->getQueueSize(new Queue(Event::MIGRATIONS_QUEUE_NAME));
|
||||
$size = $publisherMigrations->getQueueSize(new Queue(Event::MIGRATIONS_QUEUE_NAME));
|
||||
|
||||
if ($size >= $threshold) {
|
||||
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
|
||||
@@ -2175,7 +2175,7 @@ App::post('/v1/projects/:projectId/smtp/tests')
|
||||
->setSmtpSenderName($senderName)
|
||||
->setRecipient($email)
|
||||
->setName('')
|
||||
->setbodyTemplate(__DIR__ . '/../../config/locale/templates/email-base-styled.tpl')
|
||||
->setBodyTemplate(__DIR__ . '/../../config/locale/templates/email-base-styled.tpl')
|
||||
->setBody($template->render())
|
||||
->setVariables([])
|
||||
->setSubject($subject)
|
||||
@@ -2268,16 +2268,53 @@ App::get('/v1/projects/:projectId/templates/email/:type/:locale')
|
||||
|
||||
$localeObj = new Locale($locale);
|
||||
if (is_null($template)) {
|
||||
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/email-inner-base.tpl');
|
||||
/**
|
||||
* different templates, different placeholders.
|
||||
*/
|
||||
$templateConfigs = [
|
||||
'magicSession' => [
|
||||
'file' => 'email-magic-url.tpl',
|
||||
'placeholders' => ['optionButton', 'buttonText', 'optionUrl', 'clientInfo', 'securityPhrase']
|
||||
],
|
||||
'mfaChallenge' => [
|
||||
'file' => 'email-mfa-challenge.tpl',
|
||||
'placeholders' => ['description', 'clientInfo']
|
||||
],
|
||||
'otpSession' => [
|
||||
'file' => 'email-otp.tpl',
|
||||
'placeholders' => ['description', 'clientInfo', 'securityPhrase']
|
||||
],
|
||||
'sessionAlert' => [
|
||||
'file' => 'email-session-alert.tpl',
|
||||
'placeholders' => ['body', 'listDevice', 'listIpAddress', 'listCountry', 'footer']
|
||||
],
|
||||
];
|
||||
|
||||
// fallback to the base template.
|
||||
$config = $templateConfigs[$type] ?? [
|
||||
'file' => 'email-inner-base.tpl',
|
||||
'placeholders' => ['buttonText', 'body', 'footer']
|
||||
];
|
||||
|
||||
$templateString = file_get_contents(__DIR__ . '/../../config/locale/templates/' . $config['file']);
|
||||
|
||||
// We use `fromString` due to the replace above
|
||||
$message = Template::fromString($templateString);
|
||||
|
||||
// Set type-specific parameters
|
||||
foreach ($config['placeholders'] as $param) {
|
||||
$escapeHtml = !in_array($param, ['clientInfo', 'body', 'footer', 'description']);
|
||||
$message->setParam("{{{$param}}}", $localeObj->getText("emails.{$type}.{$param}"), escapeHtml: $escapeHtml);
|
||||
}
|
||||
|
||||
$message
|
||||
// common placeholders on all the templates
|
||||
->setParam('{{hello}}', $localeObj->getText("emails.{$type}.hello"))
|
||||
->setParam('{{footer}}', $localeObj->getText("emails.{$type}.footer"))
|
||||
->setParam('{{body}}', $localeObj->getText('emails.' . $type . '.body'), escapeHtml: false)
|
||||
->setParam('{{thanks}}', $localeObj->getText("emails.{$type}.thanks"))
|
||||
->setParam('{{buttonText}}', $localeObj->getText("emails.{$type}.buttonText"))
|
||||
->setParam('{{signature}}', $localeObj->getText("emails.{$type}.signature"))
|
||||
->setParam('{{direction}}', $localeObj->getText('settings.direction'));
|
||||
$message = $message->render();
|
||||
->setParam('{{signature}}', $localeObj->getText("emails.{$type}.signature"));
|
||||
|
||||
// `useContent: false` will strip new lines!
|
||||
$message = $message->render(useContent: true);
|
||||
|
||||
$template = [
|
||||
'message' => $message,
|
||||
|
||||
@@ -1870,7 +1870,7 @@ App::get('/v1/storage/usage')
|
||||
$total = [];
|
||||
Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats, &$total) {
|
||||
foreach ($metrics as $metric) {
|
||||
$result = $dbForProject->findOne('stats', [
|
||||
$result = $dbForProject->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', ['inf'])
|
||||
]);
|
||||
@@ -1899,7 +1899,7 @@ App::get('/v1/storage/usage')
|
||||
};
|
||||
|
||||
foreach ($metrics as $metric) {
|
||||
$usage[$metric]['total'] = $stats[$metric]['total'];
|
||||
$usage[$metric]['total'] = $stats[$metric]['total'];
|
||||
$usage[$metric]['data'] = [];
|
||||
$leap = time() - ($days['limit'] * $days['factor']);
|
||||
while ($leap < time()) {
|
||||
@@ -1917,8 +1917,8 @@ App::get('/v1/storage/usage')
|
||||
'filesTotal' => $usage[$metrics[1]]['total'],
|
||||
'filesStorageTotal' => $usage[$metrics[2]]['total'],
|
||||
'buckets' => $usage[$metrics[0]]['data'],
|
||||
'files' => $usage[$metrics[1]]['data'],
|
||||
'storage' => $usage[$metrics[2]]['data'],
|
||||
'files' => $usage[$metrics[1]]['data'],
|
||||
'storage' => $usage[$metrics[2]]['data'],
|
||||
]), Response::MODEL_USAGE_STORAGE);
|
||||
});
|
||||
|
||||
@@ -1970,7 +1970,7 @@ App::get('/v1/storage/:bucketId/usage')
|
||||
? $dbForLogs
|
||||
: $dbForProject;
|
||||
|
||||
$result = $db->findOne('stats', [
|
||||
$result = $db->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', ['inf'])
|
||||
]);
|
||||
@@ -2000,7 +2000,7 @@ App::get('/v1/storage/:bucketId/usage')
|
||||
};
|
||||
|
||||
foreach ($metrics as $metric) {
|
||||
$usage[$metric]['total'] = $stats[$metric]['total'];
|
||||
$usage[$metric]['total'] = $stats[$metric]['total'];
|
||||
$usage[$metric]['data'] = [];
|
||||
$leap = time() - ($days['limit'] * $days['factor']);
|
||||
while ($leap < time()) {
|
||||
|
||||
@@ -657,6 +657,7 @@ App::post('/v1/teams/:teamId/memberships')
|
||||
$projectName = $project->isEmpty() ? 'Console' : $project->getAttribute('name', '[APP-NAME]');
|
||||
|
||||
$body = $locale->getText("emails.invitation.body");
|
||||
$preview = $locale->getText("emails.invitation.preview");
|
||||
$subject = \sprintf($locale->getText("emails.invitation.subject"), $team->getAttribute('name'), $projectName);
|
||||
$customTemplate = $project->getAttribute('templates', [])['email.invitation-' . $locale->default] ?? [];
|
||||
|
||||
@@ -729,6 +730,7 @@ App::post('/v1/teams/:teamId/memberships')
|
||||
$queueForMails
|
||||
->setSubject($subject)
|
||||
->setBody($body)
|
||||
->setPreview($preview)
|
||||
->setRecipient($invitee->getAttribute('email'))
|
||||
->setName($invitee->getAttribute('name', ''))
|
||||
->setVariables($emailVariables)
|
||||
|
||||
@@ -1137,6 +1137,7 @@ App::get('/v1/vcs/github/installations/:installationId/providerRepositories/:pro
|
||||
$repository['pushedAt'] = $repository['pushed_at'] ?? '';
|
||||
$repository['organization'] = $installation->getAttribute('organization', '');
|
||||
$repository['provider'] = $installation->getAttribute('provider', '');
|
||||
$repository['defaultBranch'] = $repository['default_branch'] ?? '';
|
||||
|
||||
$response->dynamic(new Document($repository), Response::MODEL_PROVIDER_REPOSITORY);
|
||||
});
|
||||
@@ -1234,7 +1235,8 @@ App::post('/v1/vcs/github/events')
|
||||
$providerRepositoryUrl = $parsedPayload["repositoryUrl"] ?? '';
|
||||
$providerCommitHash = $parsedPayload["commitHash"] ?? '';
|
||||
$providerRepositoryOwner = $parsedPayload["owner"] ?? '';
|
||||
$providerCommitAuthor = $parsedPayload["headCommitAuthor"] ?? '';
|
||||
$providerCommitAuthorName = $parsedPayload["headCommitAuthorName"] ?? '';
|
||||
$providerCommitAuthorEmail = $parsedPayload["headCommitAuthorEmail"] ?? '';
|
||||
$providerCommitAuthorUrl = $parsedPayload["authorUrl"] ?? '';
|
||||
$providerCommitMessage = $parsedPayload["headCommitMessage"] ?? '';
|
||||
$providerCommitUrl = $parsedPayload["headCommitUrl"] ?? '';
|
||||
@@ -1247,9 +1249,9 @@ App::post('/v1/vcs/github/events')
|
||||
Query::limit(100),
|
||||
]));
|
||||
|
||||
// create new deployment only on push and not when branch is created or deleted
|
||||
if (!$providerBranchCreated && !$providerBranchDeleted) {
|
||||
$createGitDeployments($github, $providerInstallationId, $repositories, $providerBranch, $providerBranchUrl, $providerRepositoryName, $providerRepositoryUrl, $providerRepositoryOwner, $providerCommitHash, $providerCommitAuthor, $providerCommitAuthorUrl, $providerCommitMessage, $providerCommitUrl, '', false, $dbForPlatform, $queueForBuilds, $getProjectDB, $request);
|
||||
// create new deployment only on push (not committed by us) and not when branch is created or deleted
|
||||
if ($providerCommitAuthorEmail !== APP_VCS_GITHUB_EMAIL && !$providerBranchCreated && !$providerBranchDeleted) {
|
||||
$createGitDeployments($github, $providerInstallationId, $repositories, $providerBranch, $providerBranchUrl, $providerRepositoryName, $providerRepositoryUrl, $providerRepositoryOwner, $providerCommitHash, $providerCommitAuthorName, $providerCommitAuthorUrl, $providerCommitMessage, $providerCommitUrl, '', false, $dbForPlatform, $queueForBuilds, $getProjectDB, $request);
|
||||
}
|
||||
} elseif ($event == $github::EVENT_INSTALLATION) {
|
||||
if ($parsedPayload["action"] == "deleted") {
|
||||
|
||||
@@ -80,6 +80,8 @@ const APP_COMPUTE_SPECIFICATION_DEFAULT = Specification::S_1VCPU_512MB;
|
||||
const APP_PLATFORM_SERVER = 'server';
|
||||
const APP_PLATFORM_CLIENT = 'client';
|
||||
const APP_PLATFORM_CONSOLE = 'console';
|
||||
const APP_VCS_GITHUB_USERNAME = 'Appwrite';
|
||||
const APP_VCS_GITHUB_EMAIL = 'team@appwrite.io';
|
||||
|
||||
// Database Reconnect
|
||||
const DATABASE_RECONNECT_SLEEP = 2;
|
||||
|
||||
+18
-6
@@ -80,15 +80,27 @@ App::setResource('localeCodes', function () {
|
||||
App::setResource('publisher', function (Group $pools) {
|
||||
return new BrokerPool(publisher: $pools->get('publisher'));
|
||||
}, ['pools']);
|
||||
App::setResource('publisherRedis', function () {
|
||||
// Stub
|
||||
});
|
||||
App::setResource('publisherDatabases', function (BrokerPool $publisher) {
|
||||
return $publisher;
|
||||
}, ['publisher']);
|
||||
App::setResource('publisherMigrations', function (BrokerPool $publisher) {
|
||||
return $publisher;
|
||||
}, ['publisher']);
|
||||
App::setResource('publisherStatsUsage', function (BrokerPool $publisher) {
|
||||
return $publisher;
|
||||
}, ['publisher']);
|
||||
App::setResource('consumer', function (Group $pools) {
|
||||
return new BrokerPool(consumer: $pools->get('consumer'));
|
||||
}, ['pools']);
|
||||
App::setResource('consumerRedis', function () {
|
||||
// Stub
|
||||
});
|
||||
App::setResource('consumerDatabases', function (BrokerPool $consumer) {
|
||||
return $consumer;
|
||||
}, ['consumer']);
|
||||
App::setResource('consumerMigrations', function (BrokerPool $consumer) {
|
||||
return $consumer;
|
||||
}, ['publisher']);
|
||||
App::setResource('consumerStatsUsage', function (BrokerPool $consumer) {
|
||||
return $consumer;
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForMessaging', function (Publisher $publisher) {
|
||||
return new Messaging($publisher);
|
||||
}, ['publisher']);
|
||||
|
||||
+22
-6
@@ -247,17 +247,33 @@ Server::setResource('publisher', function (Group $pools) {
|
||||
return new BrokerPool(publisher: $pools->get('publisher'));
|
||||
}, ['pools']);
|
||||
|
||||
Server::setResource('publisherRedis', function () {
|
||||
// Stub
|
||||
});
|
||||
Server::setResource('publisherDatabases', function (BrokerPool $publisher) {
|
||||
return $publisher;
|
||||
}, ['publisher']);
|
||||
|
||||
Server::setResource('publisherMigrations', function (BrokerPool $publisher) {
|
||||
return $publisher;
|
||||
}, ['publisher']);
|
||||
|
||||
Server::setResource('publisherStatsUsage', function (BrokerPool $publisher) {
|
||||
return $publisher;
|
||||
}, ['publisher']);
|
||||
|
||||
Server::setResource('consumer', function (Group $pools) {
|
||||
return new BrokerPool(consumer: $pools->get('consumer'));
|
||||
}, ['pools']);
|
||||
|
||||
Server::setResource('consumerRedis', function () {
|
||||
// Stub
|
||||
});
|
||||
Server::setResource('consumerDatabases', function (BrokerPool $consumer) {
|
||||
return $consumer;
|
||||
}, ['consumer']);
|
||||
|
||||
Server::setResource('consumerMigrations', function (BrokerPool $consumer) {
|
||||
return $consumer;
|
||||
}, ['consumer']);
|
||||
|
||||
Server::setResource('consumerStatsUsage', function (BrokerPool $consumer) {
|
||||
return $consumer;
|
||||
}, ['consumer']);
|
||||
|
||||
Server::setResource('queueForStatsUsage', function (Publisher $publisher) {
|
||||
return new StatsUsage($publisher);
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@
|
||||
"utopia-php/swoole": "0.8.*",
|
||||
"utopia-php/system": "0.9.*",
|
||||
"utopia-php/telemetry": "0.1.*",
|
||||
"utopia-php/vcs": "0.10.*",
|
||||
"utopia-php/vcs": "0.11.*",
|
||||
"utopia-php/websocket": "0.3.*",
|
||||
"matomo/device-detector": "6.1.*",
|
||||
"dragonmantank/cron-expression": "3.3.*",
|
||||
|
||||
Generated
+19
-19
@@ -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": "f53e1ccd394581428d9efcb53b46d479",
|
||||
"content-hash": "edbe5912c45e1f467f398541a75a77de",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
@@ -3942,16 +3942,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/messaging",
|
||||
"version": "0.18.1",
|
||||
"version": "0.18.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/messaging.git",
|
||||
"reference": "5d1245207a61d7ca065daddad7ac5f1d5640152f"
|
||||
"reference": "0d364edacf4d4867964c7e17f653031dd39394bf"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/messaging/zipball/5d1245207a61d7ca065daddad7ac5f1d5640152f",
|
||||
"reference": "5d1245207a61d7ca065daddad7ac5f1d5640152f",
|
||||
"url": "https://api.github.com/repos/utopia-php/messaging/zipball/0d364edacf4d4867964c7e17f653031dd39394bf",
|
||||
"reference": "0d364edacf4d4867964c7e17f653031dd39394bf",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3987,9 +3987,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/messaging/issues",
|
||||
"source": "https://github.com/utopia-php/messaging/tree/0.18.1"
|
||||
"source": "https://github.com/utopia-php/messaging/tree/0.18.2"
|
||||
},
|
||||
"time": "2025-06-26T18:26:07+00:00"
|
||||
"time": "2025-07-21T18:27:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/migration",
|
||||
@@ -4587,16 +4587,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/vcs",
|
||||
"version": "0.10.5",
|
||||
"version": "0.11.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/vcs.git",
|
||||
"reference": "b358439dc387f6097019eb83ebb9fc258fe9da05"
|
||||
"reference": "0e665eaa7d906168525bf6aac50b6bcc3e4fe528"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/vcs/zipball/b358439dc387f6097019eb83ebb9fc258fe9da05",
|
||||
"reference": "b358439dc387f6097019eb83ebb9fc258fe9da05",
|
||||
"url": "https://api.github.com/repos/utopia-php/vcs/zipball/0e665eaa7d906168525bf6aac50b6bcc3e4fe528",
|
||||
"reference": "0e665eaa7d906168525bf6aac50b6bcc3e4fe528",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4630,9 +4630,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/vcs/issues",
|
||||
"source": "https://github.com/utopia-php/vcs/tree/0.10.5"
|
||||
"source": "https://github.com/utopia-php/vcs/tree/0.11.0"
|
||||
},
|
||||
"time": "2025-06-10T15:01:16+00:00"
|
||||
"time": "2025-07-23T13:54:58+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/websocket",
|
||||
@@ -4810,16 +4810,16 @@
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "appwrite/sdk-generator",
|
||||
"version": "0.41.17",
|
||||
"version": "0.41.19",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/sdk-generator.git",
|
||||
"reference": "ef5e9d952032deecffee7f825a941c40ed4c84b8"
|
||||
"reference": "ae6d44b373ae09f28d8b2dbb781ea3e2491b842d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/ef5e9d952032deecffee7f825a941c40ed4c84b8",
|
||||
"reference": "ef5e9d952032deecffee7f825a941c40ed4c84b8",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/ae6d44b373ae09f28d8b2dbb781ea3e2491b842d",
|
||||
"reference": "ae6d44b373ae09f28d8b2dbb781ea3e2491b842d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4855,9 +4855,9 @@
|
||||
"description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms",
|
||||
"support": {
|
||||
"issues": "https://github.com/appwrite/sdk-generator/issues",
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/0.41.17"
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/0.41.19"
|
||||
},
|
||||
"time": "2025-07-18T08:18:48+00:00"
|
||||
"time": "2025-07-23T06:33:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
|
||||
@@ -4,9 +4,7 @@ import io.appwrite.services.Databases;
|
||||
|
||||
Client client = new Client(context)
|
||||
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
.setSession("") // The user session to authenticate with
|
||||
.setKey("") //
|
||||
.setJWT("<YOUR_JWT>"); // Your secret JSON Web Token
|
||||
.setProject("<YOUR_PROJECT_ID>"); // Your project ID
|
||||
|
||||
Databases databases = new Databases(client);
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import io.appwrite.Client;
|
||||
import io.appwrite.coroutines.CoroutineCallback;
|
||||
import io.appwrite.services.Databases;
|
||||
|
||||
Client client = new Client(context)
|
||||
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
.setProject("<YOUR_PROJECT_ID>"); // Your project ID
|
||||
|
||||
Databases databases = new Databases(client);
|
||||
|
||||
databases.decrementDocumentAttribute(
|
||||
"<DATABASE_ID>", // databaseId
|
||||
"<COLLECTION_ID>", // collectionId
|
||||
"<DOCUMENT_ID>", // documentId
|
||||
"", // attribute
|
||||
0, // value (optional)
|
||||
0, // min (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
error.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
Log.d("Appwrite", result.toString());
|
||||
})
|
||||
);
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import io.appwrite.Client;
|
||||
import io.appwrite.coroutines.CoroutineCallback;
|
||||
import io.appwrite.services.Databases;
|
||||
|
||||
Client client = new Client(context)
|
||||
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
.setProject("<YOUR_PROJECT_ID>"); // Your project ID
|
||||
|
||||
Databases databases = new Databases(client);
|
||||
|
||||
databases.incrementDocumentAttribute(
|
||||
"<DATABASE_ID>", // databaseId
|
||||
"<COLLECTION_ID>", // collectionId
|
||||
"<DOCUMENT_ID>", // documentId
|
||||
"", // attribute
|
||||
0, // value (optional)
|
||||
0, // max (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
error.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
Log.d("Appwrite", result.toString());
|
||||
})
|
||||
);
|
||||
|
||||
@@ -4,9 +4,7 @@ import io.appwrite.services.Databases
|
||||
|
||||
val client = Client(context)
|
||||
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
.setSession("") // The user session to authenticate with
|
||||
.setKey("") //
|
||||
.setJWT("<YOUR_JWT>") // Your secret JSON Web Token
|
||||
.setProject("<YOUR_PROJECT_ID>") // Your project ID
|
||||
|
||||
val databases = Databases(client)
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import io.appwrite.Client
|
||||
import io.appwrite.coroutines.CoroutineCallback
|
||||
import io.appwrite.services.Databases
|
||||
|
||||
val client = Client(context)
|
||||
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
.setProject("<YOUR_PROJECT_ID>") // Your project ID
|
||||
|
||||
val databases = Databases(client)
|
||||
|
||||
val result = databases.decrementDocumentAttribute(
|
||||
databaseId = "<DATABASE_ID>",
|
||||
collectionId = "<COLLECTION_ID>",
|
||||
documentId = "<DOCUMENT_ID>",
|
||||
attribute = "",
|
||||
value = 0, // (optional)
|
||||
min = 0, // (optional)
|
||||
)
|
||||
@@ -0,0 +1,18 @@
|
||||
import io.appwrite.Client
|
||||
import io.appwrite.coroutines.CoroutineCallback
|
||||
import io.appwrite.services.Databases
|
||||
|
||||
val client = Client(context)
|
||||
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
.setProject("<YOUR_PROJECT_ID>") // Your project ID
|
||||
|
||||
val databases = Databases(client)
|
||||
|
||||
val result = databases.incrementDocumentAttribute(
|
||||
databaseId = "<DATABASE_ID>",
|
||||
collectionId = "<COLLECTION_ID>",
|
||||
documentId = "<DOCUMENT_ID>",
|
||||
attribute = "",
|
||||
value = 0, // (optional)
|
||||
max = 0, // (optional)
|
||||
)
|
||||
@@ -2,9 +2,7 @@ import Appwrite
|
||||
|
||||
let client = Client()
|
||||
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
.setSession("") // The user session to authenticate with
|
||||
.setKey("") //
|
||||
.setJWT("<YOUR_JWT>") // Your secret JSON Web Token
|
||||
.setProject("<YOUR_PROJECT_ID>") // Your project ID
|
||||
|
||||
let databases = Databases(client)
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import Appwrite
|
||||
|
||||
let client = Client()
|
||||
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
.setProject("<YOUR_PROJECT_ID>") // Your project ID
|
||||
|
||||
let databases = Databases(client)
|
||||
|
||||
let document = try await databases.decrementDocumentAttribute(
|
||||
databaseId: "<DATABASE_ID>",
|
||||
collectionId: "<COLLECTION_ID>",
|
||||
documentId: "<DOCUMENT_ID>",
|
||||
attribute: "",
|
||||
value: 0, // optional
|
||||
min: 0 // optional
|
||||
)
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import Appwrite
|
||||
|
||||
let client = Client()
|
||||
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
.setProject("<YOUR_PROJECT_ID>") // Your project ID
|
||||
|
||||
let databases = Databases(client)
|
||||
|
||||
let document = try await databases.incrementDocumentAttribute(
|
||||
databaseId: "<DATABASE_ID>",
|
||||
collectionId: "<COLLECTION_ID>",
|
||||
documentId: "<DOCUMENT_ID>",
|
||||
attribute: "",
|
||||
value: 0, // optional
|
||||
max: 0 // optional
|
||||
)
|
||||
|
||||
@@ -2,9 +2,7 @@ import 'package:appwrite/appwrite.dart';
|
||||
|
||||
Client client = Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
.setSession('') // The user session to authenticate with
|
||||
.setKey('') //
|
||||
.setJWT('<YOUR_JWT>'); // Your secret JSON Web Token
|
||||
.setProject('<YOUR_PROJECT_ID>'); // Your project ID
|
||||
|
||||
Databases databases = Databases(client);
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
Client client = Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
.setProject('<YOUR_PROJECT_ID>'); // Your project ID
|
||||
|
||||
Databases databases = Databases(client);
|
||||
|
||||
Document result = await databases.decrementDocumentAttribute(
|
||||
databaseId: '<DATABASE_ID>',
|
||||
collectionId: '<COLLECTION_ID>',
|
||||
documentId: '<DOCUMENT_ID>',
|
||||
attribute: '',
|
||||
value: 0, // optional
|
||||
min: 0, // optional
|
||||
);
|
||||
@@ -0,0 +1,16 @@
|
||||
import 'package:appwrite/appwrite.dart';
|
||||
|
||||
Client client = Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
.setProject('<YOUR_PROJECT_ID>'); // Your project ID
|
||||
|
||||
Databases databases = Databases(client);
|
||||
|
||||
Document result = await databases.incrementDocumentAttribute(
|
||||
databaseId: '<DATABASE_ID>',
|
||||
collectionId: '<COLLECTION_ID>',
|
||||
documentId: '<DOCUMENT_ID>',
|
||||
attribute: '',
|
||||
value: 0, // optional
|
||||
max: 0, // optional
|
||||
);
|
||||
@@ -7,6 +7,7 @@ mutation {
|
||||
permissions: ["read("any")"]
|
||||
) {
|
||||
_id
|
||||
_sequence
|
||||
_collectionId
|
||||
_databaseId
|
||||
_createdAt
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
mutation {
|
||||
databasesDecrementDocumentAttribute(
|
||||
databaseId: "<DATABASE_ID>",
|
||||
collectionId: "<COLLECTION_ID>",
|
||||
documentId: "<DOCUMENT_ID>",
|
||||
attribute: "",
|
||||
value: 0,
|
||||
min: 0
|
||||
) {
|
||||
_id
|
||||
_sequence
|
||||
_collectionId
|
||||
_databaseId
|
||||
_createdAt
|
||||
_updatedAt
|
||||
_permissions
|
||||
data
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
mutation {
|
||||
databasesIncrementDocumentAttribute(
|
||||
databaseId: "<DATABASE_ID>",
|
||||
collectionId: "<COLLECTION_ID>",
|
||||
documentId: "<DOCUMENT_ID>",
|
||||
attribute: "",
|
||||
value: 0,
|
||||
max: 0
|
||||
) {
|
||||
_id
|
||||
_sequence
|
||||
_collectionId
|
||||
_databaseId
|
||||
_createdAt
|
||||
_updatedAt
|
||||
_permissions
|
||||
data
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ mutation {
|
||||
permissions: ["read("any")"]
|
||||
) {
|
||||
_id
|
||||
_sequence
|
||||
_collectionId
|
||||
_databaseId
|
||||
_createdAt
|
||||
|
||||
@@ -7,6 +7,7 @@ mutation {
|
||||
permissions: ["read("any")"]
|
||||
) {
|
||||
_id
|
||||
_sequence
|
||||
_collectionId
|
||||
_databaseId
|
||||
_createdAt
|
||||
|
||||
@@ -2,9 +2,7 @@ import { Client, Databases } from "react-native-appwrite";
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
.setSession('') // The user session to authenticate with
|
||||
.setKey('') //
|
||||
.setJWT('<YOUR_JWT>'); // Your secret JSON Web Token
|
||||
.setProject('<YOUR_PROJECT_ID>'); // Your project ID
|
||||
|
||||
const databases = new Databases(client);
|
||||
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import { Client, Databases } from "react-native-appwrite";
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
.setProject('<YOUR_PROJECT_ID>'); // Your project ID
|
||||
|
||||
const databases = new Databases(client);
|
||||
|
||||
const result = await databases.decrementDocumentAttribute(
|
||||
'<DATABASE_ID>', // databaseId
|
||||
'<COLLECTION_ID>', // collectionId
|
||||
'<DOCUMENT_ID>', // documentId
|
||||
'', // attribute
|
||||
null, // value (optional)
|
||||
null // min (optional)
|
||||
);
|
||||
|
||||
console.log(result);
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import { Client, Databases } from "react-native-appwrite";
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
.setProject('<YOUR_PROJECT_ID>'); // Your project ID
|
||||
|
||||
const databases = new Databases(client);
|
||||
|
||||
const result = await databases.incrementDocumentAttribute(
|
||||
'<DATABASE_ID>', // databaseId
|
||||
'<COLLECTION_ID>', // collectionId
|
||||
'<DOCUMENT_ID>', // documentId
|
||||
'', // attribute
|
||||
null, // value (optional)
|
||||
null // max (optional)
|
||||
);
|
||||
|
||||
console.log(result);
|
||||
@@ -0,0 +1,12 @@
|
||||
PATCH /v1/databases/{databaseId}/collections/{collectionId}/documents/{documentId}/{attribute}/decrement HTTP/1.1
|
||||
Host: cloud.appwrite.io
|
||||
Content-Type: application/json
|
||||
X-Appwrite-Response-Format: 1.7.0
|
||||
X-Appwrite-Project: <YOUR_PROJECT_ID>
|
||||
X-Appwrite-Session:
|
||||
X-Appwrite-JWT: <YOUR_JWT>
|
||||
|
||||
{
|
||||
"value": 0,
|
||||
"min": 0
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
PATCH /v1/databases/{databaseId}/collections/{collectionId}/documents/{documentId}/{attribute}/increment HTTP/1.1
|
||||
Host: cloud.appwrite.io
|
||||
Content-Type: application/json
|
||||
X-Appwrite-Response-Format: 1.7.0
|
||||
X-Appwrite-Project: <YOUR_PROJECT_ID>
|
||||
X-Appwrite-Session:
|
||||
X-Appwrite-JWT: <YOUR_JWT>
|
||||
|
||||
{
|
||||
"value": 0,
|
||||
"max": 0
|
||||
}
|
||||
@@ -2,9 +2,7 @@ import { Client, Databases } from "appwrite";
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
.setSession('') // The user session to authenticate with
|
||||
.setKey('') //
|
||||
.setJWT('<YOUR_JWT>'); // Your secret JSON Web Token
|
||||
.setProject('<YOUR_PROJECT_ID>'); // Your project ID
|
||||
|
||||
const databases = new Databases(client);
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Client, Databases } from "appwrite";
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
.setProject('<YOUR_PROJECT_ID>'); // Your project ID
|
||||
|
||||
const databases = new Databases(client);
|
||||
|
||||
const result = await databases.decrementDocumentAttribute(
|
||||
'<DATABASE_ID>', // databaseId
|
||||
'<COLLECTION_ID>', // collectionId
|
||||
'<DOCUMENT_ID>', // documentId
|
||||
'', // attribute
|
||||
null, // value (optional)
|
||||
null // min (optional)
|
||||
);
|
||||
|
||||
console.log(result);
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Client, Databases } from "appwrite";
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
.setProject('<YOUR_PROJECT_ID>'); // Your project ID
|
||||
|
||||
const databases = new Databases(client);
|
||||
|
||||
const result = await databases.incrementDocumentAttribute(
|
||||
'<DATABASE_ID>', // databaseId
|
||||
'<COLLECTION_ID>', // collectionId
|
||||
'<DOCUMENT_ID>', // documentId
|
||||
'', // attribute
|
||||
null, // value (optional)
|
||||
null // max (optional)
|
||||
);
|
||||
|
||||
console.log(result);
|
||||
@@ -0,0 +1,7 @@
|
||||
appwrite databases decrementDocumentAttribute \
|
||||
--databaseId <DATABASE_ID> \
|
||||
--collectionId <COLLECTION_ID> \
|
||||
--documentId <DOCUMENT_ID> \
|
||||
--attribute '' \
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
appwrite databases incrementDocumentAttribute \
|
||||
--databaseId <DATABASE_ID> \
|
||||
--collectionId <COLLECTION_ID> \
|
||||
--documentId <DOCUMENT_ID> \
|
||||
--attribute '' \
|
||||
|
||||
|
||||
@@ -2,9 +2,7 @@ import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
.setSession('') //
|
||||
.setKey('<YOUR_API_KEY>') // Your secret API key
|
||||
.setJWT('<YOUR_JWT>'); // Your secret JSON Web Token
|
||||
.setProject('<YOUR_PROJECT_ID>'); // Your project ID
|
||||
|
||||
const databases = new Databases(client);
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
.setKey('<YOUR_API_KEY>'); // Your secret API key
|
||||
.setProject('<YOUR_PROJECT_ID>'); // Your project ID
|
||||
|
||||
const databases = new Databases(client);
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
.setProject('<YOUR_PROJECT_ID>'); // Your project ID
|
||||
|
||||
const databases = new Databases(client);
|
||||
|
||||
const result = await databases.decrementDocumentAttribute(
|
||||
'<DATABASE_ID>', // databaseId
|
||||
'<COLLECTION_ID>', // collectionId
|
||||
'<DOCUMENT_ID>', // documentId
|
||||
'', // attribute
|
||||
null, // value (optional)
|
||||
null // min (optional)
|
||||
);
|
||||
|
||||
console.log(result);
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
.setProject('<YOUR_PROJECT_ID>'); // Your project ID
|
||||
|
||||
const databases = new Databases(client);
|
||||
|
||||
const result = await databases.incrementDocumentAttribute(
|
||||
'<DATABASE_ID>', // databaseId
|
||||
'<COLLECTION_ID>', // collectionId
|
||||
'<DOCUMENT_ID>', // documentId
|
||||
'', // attribute
|
||||
null, // value (optional)
|
||||
null // max (optional)
|
||||
);
|
||||
|
||||
console.log(result);
|
||||
@@ -0,0 +1,17 @@
|
||||
import { Client, Databases } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
.setProject('<YOUR_PROJECT_ID>'); // Your project ID
|
||||
|
||||
const databases = new Databases(client);
|
||||
|
||||
const result = await databases.upsertDocument(
|
||||
'<DATABASE_ID>', // databaseId
|
||||
'<COLLECTION_ID>', // collectionId
|
||||
'<DOCUMENT_ID>', // documentId
|
||||
{}, // data
|
||||
["read("any")"] // permissions (optional)
|
||||
);
|
||||
|
||||
console.log(result);
|
||||
@@ -9,7 +9,7 @@ const databases = new Databases(client);
|
||||
const result = await databases.upsertDocuments(
|
||||
'<DATABASE_ID>', // databaseId
|
||||
'<COLLECTION_ID>', // collectionId
|
||||
[] // documents (optional)
|
||||
[] // documents
|
||||
);
|
||||
|
||||
console.log(result);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Client, Proxy, } from "@appwrite.io/console";
|
||||
import { Client, Proxy, , ProxyResourceType } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
@@ -9,7 +9,9 @@ const proxy = new Proxy(client);
|
||||
const result = await proxy.createRedirectRule(
|
||||
'', // domain
|
||||
'https://example.com', // url
|
||||
.MovedPermanently301 // statusCode
|
||||
.MovedPermanently301, // statusCode
|
||||
'<RESOURCE_ID>', // resourceId
|
||||
ProxyResourceType.Site // resourceType
|
||||
);
|
||||
|
||||
console.log(result);
|
||||
|
||||
@@ -9,7 +9,8 @@ const vcs = new Vcs(client);
|
||||
const result = await vcs.getRepositoryContents(
|
||||
'<INSTALLATION_ID>', // installationId
|
||||
'<PROVIDER_REPOSITORY_ID>', // providerRepositoryId
|
||||
'<PROVIDER_ROOT_DIRECTORY>' // providerRootDirectory (optional)
|
||||
'<PROVIDER_ROOT_DIRECTORY>', // providerRootDirectory (optional)
|
||||
'<PROVIDER_REFERENCE>' // providerReference (optional)
|
||||
);
|
||||
|
||||
console.log(result);
|
||||
|
||||
@@ -2,9 +2,8 @@ import 'package:dart_appwrite/dart_appwrite.dart';
|
||||
|
||||
Client client = Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
.setSession('') // The user session to authenticate with
|
||||
.setKey('<YOUR_API_KEY>') // Your secret API key
|
||||
.setJWT('<YOUR_JWT>'); // Your secret JSON Web Token
|
||||
.setProject('<YOUR_PROJECT_ID>') // Your project ID
|
||||
.setSession(''); // The user session to authenticate with
|
||||
|
||||
Databases databases = Databases(client);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:dart_appwrite/dart_appwrite.dart';
|
||||
|
||||
Client client = Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
.setProject('<YOUR_PROJECT_ID>') // Your project ID
|
||||
.setKey('<YOUR_API_KEY>'); // Your secret API key
|
||||
|
||||
Databases databases = Databases(client);
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import 'package:dart_appwrite/dart_appwrite.dart';
|
||||
|
||||
Client client = Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
.setProject('<YOUR_PROJECT_ID>') // Your project ID
|
||||
.setKey('<YOUR_API_KEY>'); // Your secret API key
|
||||
|
||||
Databases databases = Databases(client);
|
||||
|
||||
Document result = await databases.decrementDocumentAttribute(
|
||||
databaseId: '<DATABASE_ID>',
|
||||
collectionId: '<COLLECTION_ID>',
|
||||
documentId: '<DOCUMENT_ID>',
|
||||
attribute: '',
|
||||
value: 0, // (optional)
|
||||
min: 0, // (optional)
|
||||
);
|
||||
@@ -0,0 +1,17 @@
|
||||
import 'package:dart_appwrite/dart_appwrite.dart';
|
||||
|
||||
Client client = Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
.setProject('<YOUR_PROJECT_ID>') // Your project ID
|
||||
.setKey('<YOUR_API_KEY>'); // Your secret API key
|
||||
|
||||
Databases databases = Databases(client);
|
||||
|
||||
Document result = await databases.incrementDocumentAttribute(
|
||||
databaseId: '<DATABASE_ID>',
|
||||
collectionId: '<COLLECTION_ID>',
|
||||
documentId: '<DOCUMENT_ID>',
|
||||
attribute: '',
|
||||
value: 0, // (optional)
|
||||
max: 0, // (optional)
|
||||
);
|
||||
@@ -2,9 +2,8 @@ import { Client, Databases } from "https://deno.land/x/appwrite/mod.ts";
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
.setSession('') // The user session to authenticate with
|
||||
.setKey('<YOUR_API_KEY>') // Your secret API key
|
||||
.setJWT('<YOUR_JWT>'); // Your secret JSON Web Token
|
||||
.setProject('<YOUR_PROJECT_ID>') // Your project ID
|
||||
.setSession(''); // The user session to authenticate with
|
||||
|
||||
const databases = new Databases(client);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Client, Databases } from "https://deno.land/x/appwrite/mod.ts";
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
.setProject('<YOUR_PROJECT_ID>') // Your project ID
|
||||
.setKey('<YOUR_API_KEY>'); // Your secret API key
|
||||
|
||||
const databases = new Databases(client);
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import { Client, Databases } from "https://deno.land/x/appwrite/mod.ts";
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
.setProject('<YOUR_PROJECT_ID>') // Your project ID
|
||||
.setKey('<YOUR_API_KEY>'); // Your secret API key
|
||||
|
||||
const databases = new Databases(client);
|
||||
|
||||
const response = await databases.decrementDocumentAttribute(
|
||||
'<DATABASE_ID>', // databaseId
|
||||
'<COLLECTION_ID>', // collectionId
|
||||
'<DOCUMENT_ID>', // documentId
|
||||
'', // attribute
|
||||
null, // value (optional)
|
||||
null // min (optional)
|
||||
);
|
||||
@@ -0,0 +1,17 @@
|
||||
import { Client, Databases } from "https://deno.land/x/appwrite/mod.ts";
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
.setProject('<YOUR_PROJECT_ID>') // Your project ID
|
||||
.setKey('<YOUR_API_KEY>'); // Your secret API key
|
||||
|
||||
const databases = new Databases(client);
|
||||
|
||||
const response = await databases.incrementDocumentAttribute(
|
||||
'<DATABASE_ID>', // databaseId
|
||||
'<COLLECTION_ID>', // collectionId
|
||||
'<DOCUMENT_ID>', // documentId
|
||||
'', // attribute
|
||||
null, // value (optional)
|
||||
null // max (optional)
|
||||
);
|
||||
@@ -0,0 +1,16 @@
|
||||
import { Client, Databases } from "https://deno.land/x/appwrite/mod.ts";
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
.setProject('<YOUR_PROJECT_ID>') // Your project ID
|
||||
.setSession(''); // The user session to authenticate with
|
||||
|
||||
const databases = new Databases(client);
|
||||
|
||||
const response = await databases.upsertDocument(
|
||||
'<DATABASE_ID>', // databaseId
|
||||
'<COLLECTION_ID>', // collectionId
|
||||
'<DOCUMENT_ID>', // documentId
|
||||
{}, // data
|
||||
["read("any")"] // permissions (optional)
|
||||
);
|
||||
@@ -10,5 +10,5 @@ const databases = new Databases(client);
|
||||
const response = await databases.upsertDocuments(
|
||||
'<DATABASE_ID>', // databaseId
|
||||
'<COLLECTION_ID>', // collectionId
|
||||
[] // documents (optional)
|
||||
[] // documents
|
||||
);
|
||||
|
||||
@@ -4,9 +4,8 @@ using Appwrite.Services;
|
||||
|
||||
Client client = new Client()
|
||||
.SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
.SetSession("") // The user session to authenticate with
|
||||
.SetKey("<YOUR_API_KEY>") // Your secret API key
|
||||
.SetJWT("<YOUR_JWT>"); // Your secret JSON Web Token
|
||||
.SetProject("<YOUR_PROJECT_ID>") // Your project ID
|
||||
.SetSession(""); // The user session to authenticate with
|
||||
|
||||
Databases databases = new Databases(client);
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ using Appwrite.Services;
|
||||
|
||||
Client client = new Client()
|
||||
.SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
.SetProject("<YOUR_PROJECT_ID>") // Your project ID
|
||||
.SetKey("<YOUR_API_KEY>"); // Your secret API key
|
||||
|
||||
Databases databases = new Databases(client);
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
using Appwrite;
|
||||
using Appwrite.Models;
|
||||
using Appwrite.Services;
|
||||
|
||||
Client client = new Client()
|
||||
.SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
.SetProject("<YOUR_PROJECT_ID>") // Your project ID
|
||||
.SetKey("<YOUR_API_KEY>"); // Your secret API key
|
||||
|
||||
Databases databases = new Databases(client);
|
||||
|
||||
Document result = await databases.DecrementDocumentAttribute(
|
||||
databaseId: "<DATABASE_ID>",
|
||||
collectionId: "<COLLECTION_ID>",
|
||||
documentId: "<DOCUMENT_ID>",
|
||||
attribute: "",
|
||||
value: 0, // optional
|
||||
min: 0 // optional
|
||||
);
|
||||
@@ -0,0 +1,19 @@
|
||||
using Appwrite;
|
||||
using Appwrite.Models;
|
||||
using Appwrite.Services;
|
||||
|
||||
Client client = new Client()
|
||||
.SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
.SetProject("<YOUR_PROJECT_ID>") // Your project ID
|
||||
.SetKey("<YOUR_API_KEY>"); // Your secret API key
|
||||
|
||||
Databases databases = new Databases(client);
|
||||
|
||||
Document result = await databases.IncrementDocumentAttribute(
|
||||
databaseId: "<DATABASE_ID>",
|
||||
collectionId: "<COLLECTION_ID>",
|
||||
documentId: "<DOCUMENT_ID>",
|
||||
attribute: "",
|
||||
value: 0, // optional
|
||||
max: 0 // optional
|
||||
);
|
||||
@@ -9,9 +9,8 @@ import (
|
||||
func main() {
|
||||
client := client.New(
|
||||
client.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
client.WithProject("<YOUR_PROJECT_ID>") // Your project ID
|
||||
client.WithSession("") // The user session to authenticate with
|
||||
client.WithKey("<YOUR_API_KEY>") // Your secret API key
|
||||
client.WithJWT("<YOUR_JWT>") // Your secret JSON Web Token
|
||||
)
|
||||
|
||||
service := databases.New(client)
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
func main() {
|
||||
client := client.New(
|
||||
client.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
client.WithProject("<YOUR_PROJECT_ID>") // Your project ID
|
||||
client.WithKey("<YOUR_API_KEY>") // Your secret API key
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/appwrite/sdk-for-go/client"
|
||||
"github.com/appwrite/sdk-for-go/databases"
|
||||
)
|
||||
|
||||
func main() {
|
||||
client := client.New(
|
||||
client.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
client.WithProject("<YOUR_PROJECT_ID>") // Your project ID
|
||||
client.WithKey("<YOUR_API_KEY>") // Your secret API key
|
||||
)
|
||||
|
||||
service := databases.New(client)
|
||||
response, error := service.DecrementDocumentAttribute(
|
||||
"<DATABASE_ID>",
|
||||
"<COLLECTION_ID>",
|
||||
"<DOCUMENT_ID>",
|
||||
"",
|
||||
databases.WithDecrementDocumentAttributeValue(0),
|
||||
databases.WithDecrementDocumentAttributeMin(0),
|
||||
)
|
||||
|
||||
if error != nil {
|
||||
panic(error)
|
||||
}
|
||||
|
||||
fmt.Println(response)
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/appwrite/sdk-for-go/client"
|
||||
"github.com/appwrite/sdk-for-go/databases"
|
||||
)
|
||||
|
||||
func main() {
|
||||
client := client.New(
|
||||
client.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
client.WithProject("<YOUR_PROJECT_ID>") // Your project ID
|
||||
client.WithKey("<YOUR_API_KEY>") // Your secret API key
|
||||
)
|
||||
|
||||
service := databases.New(client)
|
||||
response, error := service.IncrementDocumentAttribute(
|
||||
"<DATABASE_ID>",
|
||||
"<COLLECTION_ID>",
|
||||
"<DOCUMENT_ID>",
|
||||
"",
|
||||
databases.WithIncrementDocumentAttributeValue(0),
|
||||
databases.WithIncrementDocumentAttributeMax(0),
|
||||
)
|
||||
|
||||
if error != nil {
|
||||
panic(error)
|
||||
}
|
||||
|
||||
fmt.Println(response)
|
||||
}
|
||||
@@ -17,7 +17,7 @@ func main() {
|
||||
response, error := service.UpsertDocuments(
|
||||
"<DATABASE_ID>",
|
||||
"<COLLECTION_ID>",
|
||||
databases.WithUpsertDocumentsDocuments([]interface{}{}),
|
||||
[]interface{}{},
|
||||
)
|
||||
|
||||
if error != nil {
|
||||
|
||||
@@ -7,6 +7,7 @@ mutation {
|
||||
permissions: ["read("any")"]
|
||||
) {
|
||||
_id
|
||||
_sequence
|
||||
_collectionId
|
||||
_databaseId
|
||||
_createdAt
|
||||
|
||||
@@ -7,6 +7,7 @@ mutation {
|
||||
total
|
||||
documents {
|
||||
_id
|
||||
_sequence
|
||||
_collectionId
|
||||
_databaseId
|
||||
_createdAt
|
||||
|
||||
@@ -19,5 +19,6 @@ mutation {
|
||||
_updatedAt
|
||||
size
|
||||
default
|
||||
encrypt
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
mutation {
|
||||
databasesDecrementDocumentAttribute(
|
||||
databaseId: "<DATABASE_ID>",
|
||||
collectionId: "<COLLECTION_ID>",
|
||||
documentId: "<DOCUMENT_ID>",
|
||||
attribute: "",
|
||||
value: 0,
|
||||
min: 0
|
||||
) {
|
||||
_id
|
||||
_sequence
|
||||
_collectionId
|
||||
_databaseId
|
||||
_createdAt
|
||||
_updatedAt
|
||||
_permissions
|
||||
data
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ mutation {
|
||||
total
|
||||
documents {
|
||||
_id
|
||||
_sequence
|
||||
_collectionId
|
||||
_databaseId
|
||||
_createdAt
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
mutation {
|
||||
databasesIncrementDocumentAttribute(
|
||||
databaseId: "<DATABASE_ID>",
|
||||
collectionId: "<COLLECTION_ID>",
|
||||
documentId: "<DOCUMENT_ID>",
|
||||
attribute: "",
|
||||
value: 0,
|
||||
max: 0
|
||||
) {
|
||||
_id
|
||||
_sequence
|
||||
_collectionId
|
||||
_databaseId
|
||||
_createdAt
|
||||
_updatedAt
|
||||
_permissions
|
||||
data
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ mutation {
|
||||
permissions: ["read("any")"]
|
||||
) {
|
||||
_id
|
||||
_sequence
|
||||
_collectionId
|
||||
_databaseId
|
||||
_createdAt
|
||||
|
||||
@@ -8,6 +8,7 @@ mutation {
|
||||
total
|
||||
documents {
|
||||
_id
|
||||
_sequence
|
||||
_collectionId
|
||||
_databaseId
|
||||
_createdAt
|
||||
|
||||
@@ -18,5 +18,6 @@ mutation {
|
||||
_updatedAt
|
||||
size
|
||||
default
|
||||
encrypt
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
mutation {
|
||||
databasesUpsertDocument(
|
||||
databaseId: "<DATABASE_ID>",
|
||||
collectionId: "<COLLECTION_ID>",
|
||||
documentId: "<DOCUMENT_ID>",
|
||||
data: "{}",
|
||||
permissions: ["read("any")"]
|
||||
) {
|
||||
_id
|
||||
_sequence
|
||||
_collectionId
|
||||
_databaseId
|
||||
_createdAt
|
||||
_updatedAt
|
||||
_permissions
|
||||
data
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user