- Remove excessive logic and 1-minute expiration hack as requested
- Simplify token expiry handling to directly use existing value
- Remove problematic test that creates tokens with past expiry dates
- Update existing test to properly verify JWT expiration behavior
- Use proper base64url decoding for JWT payload testing
- Added event queue injections in Bulk Update and Create classes for better event handling.
- Modified getUser method in Scope class to allow for user retrieval with an override option.
- Expanded RealtimeCustomClientTest to include comprehensive tests for bulk create, update, and delete operations, ensuring proper event emissions for multiple clients.
- Improved assertions in tests to validate event data and permissions for created, updated, and deleted documents.
- Implemented `testDateTimeRow` to validate the behavior of datetime columns, including creation, retrieval, and modification of rows with custom createdAt and updatedAt timestamps.
- Added `testSingleRowDateOperations` to cover various scenarios for single row operations with custom date handling.
- Created `testBulkRowDateOperations` to test bulk creation and updates of rows with date fields.
- Introduced `testUpsertRowDateOperations` to verify upsert functionality with custom date fields.
- Cleaned up legacy test file by removing unnecessary blank lines.
@@ -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.
> We just announced Timestamp Overrides for Appwrite Databases - [Learn more](https://appwrite.io/blog/post/announcing-timestamp-overrides)
> Appwrite Cloud is now Generally Available - [Learn more](https://appwrite.io/cloud-ga)
> [Get started with Appwrite](https://apwr.dev/appcloud)
> [Join the Init kick off event 19th of May: The future of Appwrite with Founder & CEO Eldad Fux](https://www.youtube.com/watch?v=1g8tuogsp7A)
<br />
<p align="center">
<a href="https://appwrite.io" target="_blank"><img src="./public/images/banner.png" alt="Appwrite banner, with logo and text saying "Build Like a Team of Hundreds"></a>
<br />
<br />
<b>Appwrite is a backend platform for developing Web, Mobile, and Flutter applications. Built with the open source community and optimized for developer experience in the coding languages you love.</b>
<b>Appwrite is an all-in-one development platform for Web, Mobile, and Flutter applications. Use built-in backend infrastructure and web hosting, all from a single place. Built with the open source community and optimized for developer experience in the coding languages you love.</b>
<br />
<br />
</p>
@@ -25,7 +28,7 @@
English | [简体中文](README-CN.md)
Appwrite is an end-to-end backend server for Web, Mobile, Native, or Backend apps packaged as a set of Docker<nobr> microservices. Appwrite abstracts the complexity and repetitiveness required to build a modern backend API from scratch and allows you to build secure apps faster.
Appwrite is an end-to-end platform for building Web, Mobile, Native, or Backend apps, packaged as a set of Docker microservices. It includes both a backend server and a fully integrated hosting solution for deploying static and server-side rendered frontends. Appwrite abstracts the complexity and repetitiveness required to build modern apps from scratch and allows you to build secure, full-stack applications faster.
Using Appwrite, you can easily integrate your app with user authentication and multiple sign-in methods, a database for storing and querying users and team data, storage and file management, image manipulation, Cloud Functions, messaging, and [more services](https://appwrite.io/docs).
@@ -42,7 +45,7 @@ Find out more at: [https://appwrite.io](https://appwrite.io).
Table of Contents:
- [Getting Started](#getting-started)
- [Installation \& Setup](#installation--setup)
- [Self-Hosting](#self-hosting)
- [Unix](#unix)
- [Windows](#windows)
@@ -62,8 +65,9 @@ Table of Contents:
- [Follow Us](#follow-us)
- [License](#license)
## Getting Started
The easiest way to get started with Appwrite is by [signing up for Appwrite Cloud](https://cloud.appwrite.io/). While Appwrite Cloud is in public beta, you can build with Appwrite completely free, and we won't collect you credit card information.
## Installation & Setup
The easiest way to get started with Appwrite is by [signing up for Appwrite Cloud](https://cloud.appwrite.io/). While Appwrite Cloud is in public beta, you can build with Appwrite completely free, and we won't collect your credit card information.
Once the Docker installation is complete, go to http://localhost to access the Appwrite console from your browser. Please note that on non-Linux native hosts, the server might take a few minutes to start after completing the installation.
@@ -128,19 +132,19 @@ Choose from one of the providers below:
@@ -186,6 +190,8 @@ Getting started with Appwrite is as easy as creating a new project, choosing you
- [**Realtime**](https://appwrite.io/docs/realtime) - Listen to real-time events for any of your Appwrite services including users, storage, functions, databases, and more.
- [**Locale**](https://appwrite.io/docs/references/cloud/client-web/locale) - Track your user's location and manage your app locale-based data.
- [**Avatars**](https://appwrite.io/docs/references/cloud/client-web/avatars) - Manage your users' avatars, countries' flags, browser icons, and credit card symbols. Generate QR codes from links or plaintext strings.
- [**MCP**](https://appwrite.io/docs/tooling/mcp) - Use Appwrite's Model Context Protocol (MCP) server to allow LLMs and AI tools like Claude Desktop, Cursor, and Windsurf Editor to directly interact with your Appwrite project through natural language.
- [**Sites**](https://appwrite.io/docs/products/sites) - Develop, deploy, and scale your web applications directly from Appwrite, alongside your backend.
For the complete API documentation, visit [https://appwrite.io/docs](https://appwrite.io/docs). For more tutorials, news and announcements check out our [blog](https://medium.com/appwrite-io) and [Discord Server](https://discord.gg/GSeTUeA).
'description'=>'The order attribute had a null value. Cursor pagination requires all documents order attribute values are non-null.',
'description'=>'The order attribute/column had a null value. Cursor pagination requires all documents/rows order attribute/column values are non-null.',
'code'=>400,
],
@@ -689,6 +699,23 @@ return [
'code'=>400,
],
/** Tables */
Exception::TABLE_NOT_FOUND=>[
'name'=>Exception::TABLE_NOT_FOUND,
'description'=>'Table with the requested ID could not be found.',
'code'=>404,
],
Exception::TABLE_ALREADY_EXISTS=>[
'name'=>Exception::TABLE_ALREADY_EXISTS,
'description'=>'A table with the requested ID already exists. Try again with a different ID or use ID.unique() to generate a unique ID.',
'code'=>409,
],
Exception::TABLE_LIMIT_EXCEEDED=>[
'name'=>Exception::TABLE_LIMIT_EXCEEDED,
'description'=>'The maximum number of tables has been reached.',
'code'=>400,
],
/** Documents */
Exception::DOCUMENT_NOT_FOUND=>[
'name'=>Exception::DOCUMENT_NOT_FOUND,
@@ -726,6 +753,43 @@ return [
'code'=>403,
],
/** Rows */
Exception::ROW_NOT_FOUND=>[
'name'=>Exception::ROW_NOT_FOUND,
'description'=>'Row with the requested ID could not be found.',
'code'=>404,
],
Exception::ROW_INVALID_STRUCTURE=>[
'name'=>Exception::ROW_INVALID_STRUCTURE,
'description'=>'The row structure is invalid. Please ensure the columns match the table definition.',
'code'=>400,
],
Exception::ROW_MISSING_DATA=>[
'name'=>Exception::ROW_MISSING_DATA,
'description'=>'The row data is missing. Try again with row data populated',
'code'=>400,
],
Exception::ROW_MISSING_PAYLOAD=>[
'name'=>Exception::ROW_MISSING_PAYLOAD,
'description'=>'The row data and permissions are missing. You must provide either row data or permissions to be updated.',
'code'=>400,
],
Exception::ROW_ALREADY_EXISTS=>[
'name'=>Exception::ROW_ALREADY_EXISTS,
'description'=>'Row with the requested ID already exists. Try again with a different ID or use ID.unique() to generate a unique ID.',
'code'=>409,
],
Exception::ROW_UPDATE_CONFLICT=>[
'name'=>Exception::ROW_UPDATE_CONFLICT,
'description'=>'Remote row is newer than local.',
'code'=>409,
],
Exception::ROW_DELETE_RESTRICTED=>[
'name'=>Exception::ROW_DELETE_RESTRICTED,
'description'=>'Row cannot be deleted because it is referenced by another row.',
'code'=>403,
],
/** Attributes */
Exception::ATTRIBUTE_NOT_FOUND=>[
'name'=>Exception::ATTRIBUTE_NOT_FOUND,
@@ -772,16 +836,81 @@ return [
'description'=>'The attribute type is invalid.',
'code'=>400,
],
Exception::ATTRIBUTE_INVALID_RESIZE=>[
'name'=>Exception::ATTRIBUTE_INVALID_RESIZE,
'description'=>'Existing data is too large for new size, truncate your existing data then try again.',
'code'=>400,
],
Exception::ATTRIBUTE_TYPE_NOT_SUPPORTED=>[
'name'=>Exception::ATTRIBUTE_TYPE_NOT_SUPPORTED,
'description'=>'Attribute type is not supported.',
'code'=>400,
],
/** Exists for both Attributes & Columns */
Exception::RELATIONSHIP_VALUE_INVALID=>[
'name'=>Exception::RELATIONSHIP_VALUE_INVALID,
'description'=>'The relationship value is invalid.',
'code'=>400,
],
Exception::ATTRIBUTE_INVALID_RESIZE=>[
'name'=>Exception::ATTRIBUTE_INVALID_RESIZE,
/** Columns */
Exception::COLUMN_NOT_FOUND=>[
'name'=>Exception::COLUMN_NOT_FOUND,
'description'=>'Column with the requested ID could not be found.',
'code'=>404,
],
Exception::COLUMN_UNKNOWN=>[
'name'=>Exception::COLUMN_UNKNOWN,
'description'=>'The column required for the index could not be found. Please confirm all your columns are in the available state.',
'code'=>400,
],
Exception::COLUMN_NOT_AVAILABLE=>[
'name'=>Exception::COLUMN_NOT_AVAILABLE,
'description'=>'The requested column is not yet available. Please try again later.',
'code'=>400,
],
Exception::COLUMN_FORMAT_UNSUPPORTED=>[
'name'=>Exception::COLUMN_FORMAT_UNSUPPORTED,
'description'=>'The requested column format is not supported.',
'code'=>400,
],
Exception::COLUMN_DEFAULT_UNSUPPORTED=>[
'name'=>Exception::COLUMN_DEFAULT_UNSUPPORTED,
'description'=>'Default values cannot be set for array or required columns.',
'code'=>400,
],
Exception::COLUMN_ALREADY_EXISTS=>[
'name'=>Exception::COLUMN_ALREADY_EXISTS,
'description'=>'Column with the requested key already exists. Column keys must be unique, try again with a different key.',
'code'=>409,
],
Exception::COLUMN_LIMIT_EXCEEDED=>[
'name'=>Exception::COLUMN_LIMIT_EXCEEDED,
'description'=>'The maximum number or size of columns for this table has been reached.',
'code'=>400,
],
Exception::COLUMN_VALUE_INVALID=>[
'name'=>Exception::COLUMN_VALUE_INVALID,
'description'=>'The column value is invalid. Please check the type, range and value of the column.',
'code'=>400,
],
Exception::COLUMN_TYPE_INVALID=>[
'name'=>Exception::COLUMN_TYPE_INVALID,
'description'=>'The column type is invalid.',
'code'=>400,
],
Exception::COLUMN_INVALID_RESIZE=>[
'name'=>Exception::COLUMN_INVALID_RESIZE,
'description'=>"Existing data is too large for new size, truncate your existing data then try again.",
'code'=>400,
],
Exception::COLUMN_TYPE_NOT_SUPPORTED=>[
'name'=>Exception::COLUMN_TYPE_NOT_SUPPORTED,
'description'=>'Column type is not supported.',
'code'=>400,
],
/** Indexes */
Exception::INDEX_NOT_FOUND=>[
@@ -810,6 +939,33 @@ return [
'code'=>409,
],
/** Column Indexes, same as Indexes but with different type */
Exception::COLUMN_INDEX_NOT_FOUND=>[
'name'=>Exception::COLUMN_INDEX_NOT_FOUND,
'description'=>'Index with the requested ID could not be found.',
'code'=>404,
],
Exception::COLUMN_INDEX_LIMIT_EXCEEDED=>[
'name'=>Exception::COLUMN_INDEX_LIMIT_EXCEEDED,
'description'=>'The maximum number of indexes has been reached.',
'code'=>400,
],
Exception::COLUMN_INDEX_ALREADY_EXISTS=>[
'name'=>Exception::COLUMN_INDEX_ALREADY_EXISTS,
'description'=>'Index with the requested key already exists. Try again with a different key.',
'code'=>409,
],
Exception::COLUMN_INDEX_INVALID=>[
'name'=>Exception::COLUMN_INDEX_INVALID,
'description'=>'Index invalid.',
'code'=>400,
],
Exception::COLUMN_INDEX_DEPENDENCY=>[
'name'=>Exception::COLUMN_INDEX_DEPENDENCY,
'description'=>'Column cannot be renamed or deleted. Please remove the associated index first.',
"emails.invitation.subject":"Uitnodiging om by die %s span aan te sluit by %s",
"emails.invitation.subject":"Uitnodiging om by die {{team}} span aan te sluit by {{project}}",
"emails.invitation.hello":"Goeie dag,",
"emails.invitation.body":"Hierdie boodskap is aan u gestuur omdat {{owner}} u uitnooi om 'n lid van die {{team}} groep by die {{project}} projek te wees.",
"emails.invitation.footer":"As u nie belang stel nie, kan u gerus hierdie boodskap ignoreer.",
"emails.recovery.buttonText":"إعادة تعيين كلمة السر",
"emails.recovery.signature":"فرقة {{project}}",
"emails.invitation.subject":"عراضة ل فرقة %s ف %s",
"emails.invitation.subject":"عراضة ل فرقة {{team}} ف {{project}}",
"emails.invitation.hello":"السلام،",
"emails.invitation.body":"هاد البرية تصيفطات ليك حيت {{owner}} بغى يعرض عليك تولّي عضو ف فرقة {{team}} عند {{project}}.",
"emails.invitation.footer":"إلا كنتي ما مسوّقش, ممكن تنخّل هاد البرية.",
"emails.invitation.thanks":"شكرا،",
"emails.invitation.buttonText":"اقبل الدعوة إلى {{team}}",
"emails.invitation.signature":"فرقة {{project}}",
"emails.certificate.subject":"السرتافيكة فشلات ل %s",
"emails.certificate.subject":"السرتافيكة فشلات ل {{domain}}",
"emails.certificate.hello":"السلام،",
"emails.certificate.body":"السرتافيكة ديال الضومين ديالك '{{domain}}' ما قدّاتش تجينيرا. هادي هي المحاولة نمرة {{attempt}}, السبب ديال هاد الفشل هو: {{error}}",
"emails.certificate.footer":"السرتافيكة الفايتة ديالك غاتبقى مزيانة لمدة 30 يوم من عند أول فشل. كانشجعوك بزاف أنك تبقشش فهاد الموضوع, وا إلّا الضومين ديالك ما غايبقاش خدّام فيه الـ SSL.",
"emails.invitation.subject":"Запрошення до Команди %s у %s",
"emails.invitation.subject":"Запрошення до Команди {{team}} у {{project}}",
"emails.invitation.hello":"Прывітанне,",
"emails.invitation.body":"Гэта паведамленне было адпраўлена вам, таму што {{owner}} хацеў запрасіць вас стаць членам каманды {{team}} у {{project}}.",
"emails.invitation.footer":"Калі вам гэта не цікава, вы можаце праігнараваць гэтае паведамленне.",
@@ -247,7 +245,7 @@
"emails.otpSession.securityPhrase":"Фраза бяспекі для гэтага ліста - {{phrase}}. Вы можаце давяраць гэтаму лісту, калі гэтая фраза супадае з фразай, паказанай пры ўваходзе.",
"emails.certificate.subject":"Сведчанне няўдалае для %s",
"emails.certificate.subject":"Сведчанне няўдалае для {{domain}}",
"emails.certificate.hello":"Прывітанне,",
"emails.certificate.body":"Сертыфікат для вашага дамена '{{domain}}' не можа быць створаны. Гэта спроба нумар {{attempt}}, і прычынай няўдачы з'яўляецца: {{error}}",
"emails.certificate.footer":"Ваш папярэдні сертыфікат будзе дзейнічаць 30 дзён з моманту першай няўдачы. Мы высока рэкамендуем расследаваць гэтую сітуацыю, інакш ваш дамен апынецца без дзейнага сертыфіката SSL-злучэння.",
"emails.invitation.subject":"%s टीम क %s पे न्योता देवे क लेल|",
"emails.invitation.subject":"{{team}} टीम क {{project}} पे न्योता देवे क लेल|",
"emails.invitation.hello":"प्रणाम,",
"emails.invitation.body":"ई मेल आपके एही लेल भेजल गईल रहल काहे क {{owner}} आपके {{project}} क {{team}} टीम का सदस्य बनावे चाहित रहे|",
"emails.invitation.footer":"अगर आवे क इच्छा ना होवत, तो आप ई संदेश क अनदेखा कर सकत अछि।",
@@ -247,7 +245,7 @@
"emails.otpSession.securityPhrase":"एही ईमेल खातिर सुरक्षा वाक्य {{phrase}} हऽ। अगर ई वाक्य साइन इन कइला के समय देखावल गेल वाक्य से मेल खाता, त एह ईमेल पर भरोसा कर सकैत छी।",
"emails.certificate.body":"आपके डोमेन '{{domain}}' के लिए प्रमाणपत्र नहीं बनाया जा सका। ई प्रयास संख्या {{attempt}} है, और ई असफलता के कारण रहे: {{error}}",
"emails.certificate.footer":"तोहार पिछलका प्रमाणपत्र पहिल असफलता से 30 दिन धरी मान्य होईत। हम बहुत जोर देके सलाह देतानी कि एह मामला के जांच करीं, नहीं त तोहार डोमेन बिना कोनो मान्य SSL संवाद के रहि जाईत।",
"emails.invitation.body":"এই মেইলটি আপনাকে পাঠানো হয়েছে কারণ {{owner}} আপনাকে {{project}} এর সাথে যুক্ত {{team}} টিমের সদস্য হওয়ার জন্য আমন্ত্রণ জানাতে চেয়েছিলেন।",
"emails.invitation.footer":"যদি এটি আপনার জন্য প্রয়োজনীয় না হয়, আপনি এই বার্তাটি উপেক্ষা করতে পারেন।",
"emails.invitation.subject":"Einladung zum %s-Team auf %s",
"emails.invitation.subject":"Einladung zum {{team}}-Team auf {{project}}",
"emails.invitation.hello":"Hello,",
"emails.invitation.body":"Du erhälst diese E-Mail, weil {{owner}} dich in das Team {{team}} auf {{project}} eingeladen hat.",
"emails.invitation.footer":"Wenn du nicht interessiert bist, kannst du diese Nachricht ignorieren.",
@@ -247,5 +245,6 @@
"emails.otpSession.clientInfo":"Diese Anmeldung wurde über {{agentClient}} auf {{agentDevice}} {{agentOs}} angefordert. Wenn Sie die Anmeldung nicht angefordert haben, können Sie diese E-Mail getrost ignorieren.",
"emails.otpSession.securityPhrase":"Die Sicherheitsphrase für diese E-Mail lautet {{phrase}}. Sie können dieser E-Mail vertrauen, wenn diese Phrase mit der Phrase übereinstimmt, die beim Anmelden angezeigt wird.",
"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}}",
"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.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,26 +40,30 @@
"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.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.",
"emails.recovery.thanks":"Thanks,",
"emails.recovery.buttonText":"Reset password",
"emails.recovery.signature":"{{project}} team",
"emails.invitation.subject":"Invitation to %s Team at %s",
"emails.invitation.subject":"Invitation to {{team}} Team at {{project}}",
"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.body":"This mail was sent to you because {{b}}{{owner}}{{/b}} invited 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.",
"emails.invitation.thanks":"Thanks,",
"emails.invitation.buttonText":"Accept invite to {{team}}",
"emails.invitation.signature":"{{project}} team",
"emails.certificate.subject":"Certificate failure for %s",
"emails.certificate.subject":"Certificate failure for {{domain}}",
"emails.certificate.preview":"Your domain {{domain}} 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.",
"emails.recovery.signature":"El equipo de {{project}}",
"emails.invitation.subject":"Invitación al equipo %s en %s",
"emails.invitation.subject":"Invitación al equipo {{team}} en {{project}}",
"emails.invitation.hello":"Hola,",
"emails.invitation.body":"Este correo ha sido enviado a petición de {{owner}} quién quiere invitarte a formar parte del equipo {{team}} en {{project}}.",
"emails.invitation.footer":"Si no estás interesado, puedes ignorar este mensaje.",
"emails.invitation.subject":"Invitation à l'équipe %s de %s",
"emails.invitation.subject":"Invitation à l'équipe {{team}} de {{project}}",
"emails.invitation.hello":"Bonjour,",
"emails.invitation.body":"Cet e-mail vous a été envoyé parce que {{owner}} souhaite vous inviter à devenir membre de l'équipe {{team}} pour {{project}}.",
"emails.invitation.footer":"Si vous n'êtes pas intéressé, vous pouvez ignorer ce message.",
"emails.invitation.subject":"Cuireadh do %s foireann ag %s",
"emails.invitation.subject":"Cuireadh do {{team}} foireann ag {{project}}",
"emails.invitation.hello":"Haigh,",
"emails.invitation.body":"Seoladh an ríomhphost seo chugat mar ba mhaith le {{owner}} cuireadh a thabhairt duit bheith mar bhall den fhoireann {{team}} ag obair ar {{project}}.",
"emails.invitation.footer":"Is cuma leat? Déan neamhaird den teachtaireacht seo.",
"emails.invitation.subject":"%s ટીમને %s પર આમંત્રણ",
"emails.invitation.subject":"{{team}} ટીમને {{project}} પર આમંત્રણ",
"emails.invitation.hello":"નમસ્કાર,",
"emails.invitation.body":"આ મેઇલ તમને મોકલવામાં આવ્યો હતો કારણ કે {{owner}} તમને {{project}} માં {{team}} ટીમના સભ્ય બનવા માટે આમંત્રિત કરવા માંગતા હતો.",
"emails.invitation.footer":"જો તમને રસ નથી, તો તમે આ સંદેશને અવગણી શકો છો.",
"emails.invitation.subject":"Invitatio pro %s in quadrigis %s",
"emails.invitation.subject":"Invitatio pro {{team}} in quadrigis {{project}}",
"emails.invitation.hello":"Salve ibi,",
"emails.invitation.body":"Haec inscriptio ad te missa est quia dominus incepto {{owner}} te invitare vult ut membrum {{team}} quadrigis fias ad {{project}}",
"emails.invitation.footer":"Si non quaero, potes hunc nuntium ignorare",
@@ -247,7 +245,7 @@
"emails.otpSession.securityPhrase":"Sententia securitatis huius epistulae est {{phrase}}. Epistulae confidere potes si haec sententia cum ea quae ostensa est in signo ingressus convenit.",
"emails.otpSession.thanks":"Gratias,",
"emails.otpSession.signature":"{{project}} team -> {{project}} grex",
"emails.certificate.subject":"Defectio testimonii pro %s",
"emails.certificate.subject":"Defectio testimonii pro {{domain}}",
"emails.certificate.hello":"Salve,",
"emails.certificate.body":"Certificatum pro dominio tuo '{{domain}}' generari non potuit. Hoc conatus num. {{attempt}} est, et defectus causatus est ab: {{error}}",
"emails.certificate.footer":"Praeclarum tuum testificationem valet ad XXX dies a primo defectu. Magnopere suademus ut hoc casum investiges, alioquin dominium tuum sine valida SSL communicatione erit.",
"emails.invitation.subject":"Invitatioun un %s équipe bei %s",
"emails.invitation.subject":"Invitatioun un {{team}} équipe bei {{project}}",
"emails.invitation.hello":"Hallo,",
"emails.invitation.body":"Dës E -Mail gouf un Iech geschéckt well {{owner}} Iech invitéiere wëllt fir Member vum {{team}} Team bei {{project}} ze ginn.",
"emails.invitation.footer":"Wann Dir net interesséiert sidd, kënnt Dir dëse Message ignoréieren.",
"emails.invitation.subject":"Pakvietimas į %s komandą %s projekte",
"emails.invitation.subject":"Pakvietimas į {{team}} komandą {{project}} projekte",
"emails.invitation.hello":"Labas,",
"emails.invitation.body":"Šis el. laiškas buvo atsiųstas jums, nes {{owner}} norėjo jus pakviesti tapti projekto {{project}} dalimi {{team}} komandoje.",
"emails.invitation.footer":"Jei jūsų tai nedomina, galite ignoruoti šį pranešimą.",
"emails.invitation.subject":"%s -ലെ %s ടീമിലേക്കുള്ള ക്ഷണം",
"emails.invitation.subject":"{{project}} -ലെ {{team}} ടീമിലേക്കുള്ള ക്ഷണം",
"emails.invitation.hello":"നമസ്കാരം,",
"emails.invitation.body":"നിങ്ങളെ {{project}} -ലെ {{team}} ടീമിലെ അംഗമാകുവാന് ക്ഷണിക്കാൻ {{owner}} ആഗ്രഹിക്കുന്നതിനാലാണ് ഈ മെയിൽ നിങ്ങൾക്ക് അയക്കുന്നത്.",
"emails.invitation.footer":"നിങ്ങൾക്ക് താൽപ്പര്യമില്ലെങ്കിൽ, ഈ സന്ദേശം അവഗണിക്കാവുന്നതാണ്.",
@@ -247,7 +245,7 @@
"emails.otpSession.securityPhrase":"ഈ ഇമെയിലിന്റെ സുരക്ഷാ വാചകം {{phrase}} ആണ്. സൈൻ ഇൻ ചെയ്യുമ്പോൾ കാണിച്ച വാചകവുമായി ഈ വാചകം പൊരുത്തപ്പെടുന്നുണ്ടെങ്കിൽ ഈ ഇമെയിലിന് വിശ്വസിക്കാം.",
"emails.otpSession.thanks":"നന്ദി,",
"emails.otpSession.signature":"പ്രോജക്ട് ടീം",
"emails.certificate.subject":"%s ന് സർട്ടിഫിക്കറ്റ് പരാജയപ്പെട്ടു",
"emails.certificate.subject":"{{domain}} ന് സർട്ടിഫിക്കറ്റ് പരാജയപ്പെട്ടു",
"emails.certificate.hello":"ഹലോ,",
"emails.certificate.body":"നിങ്ങളുടെ ഡൊമൈൻ '{{domain}}'നു വേണ്ടിയുള്ള സർട്ടിഫിക്കറ്റ് ഉണ്ടാക്കാനായില്ല. ഇത് ശ്രമം നമ്പർ {{attempt}} ആണ്, പരാജയപ്പെട്ടത് ഇതു മൂലമാണ്: {{error}}",
"emails.certificate.footer":"നിങ്ങളുടെ മുൻപത്തെ സർട്ടിഫിക്കറ്റ് ആദ്യ പരാജയത്തിനു ശേഷം 30 ദിവസം വരെ സാധുവായിരിക്കും. ഈ കേസ് അന്വേഷിച്ചു നോക്കുന്നത് ഞങ്ങൾ ശക്തമായി ശുപാർശ ചെയ്യുന്നു, അല്ലെങ്കിൽ നിങ്ങളുടെ ഡൊമെയ്ൻ സാധുവായ SSL കമ്മ്യൂണിക്കേഷനില്ലാത്ത ഒരു അവസ്ഥയിലാകും.",
"emails.invitation.subject":"%s संघ %s येथे सामील होण्यासाठी आमंत्रण",
"emails.invitation.subject":"{{team}} संघ {{project}} येथे सामील होण्यासाठी आमंत्रण",
"emails.invitation.hello":"नमस्कार,",
"emails.invitation.body":"हा मेल तुम्हाला पाठवला होता कारण {{owner}} तुम्हाला {{project}} येथे {{team}} टीमचे सदस्य होण्यासाठी आमंत्रित करू इच्छित होते.",
"emails.invitation.footer":"आपल्याला स्वारस्य नसल्यास, आपण या संदेशाकडे दुर्लक्ष करू शकता.",
"emails.invitation.subject":"%s समूहको लागि %s मा निमन्त्रणा",
"emails.invitation.subject":"{{team}} समूहको लागि {{project}} मा निमन्त्रणा",
"emails.invitation.hello":"नमस्ते,",
"emails.invitation.body":"{{owner}}ले तपाइँलाई {{project}}मा {{team}}को सदस्य बन्न आमन्त्रित गर्न चाहनु भएको छ। त्येसैले तपाइँलाई यो सन्देश पठाइएको हो।",
"emails.invitation.footer":"यदि तपाइँ इच्छुक हुनुहुन्न भने, तपाइँले यो सन्देशलाई बेवास्ता गर्न सक्नुहुन्छ।",
"emails.invitation.subject":"Innbyding til %s Team ved %s",
"emails.invitation.subject":"Innbyding til {{team}} Team ved {{project}}",
"emails.invitation.hello":"Hallo,",
"emails.invitation.body":"Denne meldinga ble sendt til deg fordi {{owner}} ynskja å invitera deg til å bli medlem av {{team}} team i {{project}}.",
"emails.invitation.footer":"Om du ikkje er interessert, kan du ignorera denne meldinga.",
@@ -247,7 +245,7 @@
"emails.otpSession.securityPhrase":"Tryggingsfrasen for denne e-posten er {{phrase}}. Du kan stole på denne e-posten om frasen stemmer med frasen vist under pålogging.",
"emails.certificate.subject":"Sertifikatfeil for %s",
"emails.certificate.subject":"Sertifikatfeil for {{domain}}",
"emails.certificate.hello":"Hei,",
"emails.certificate.body":"Sertifikatet for domenet ditt '{{domain}}' kunne ikkje opprettast. Dette er forsøk nr. {{attempt}}, og feilen blei forårsaka av: {{error}}",
"emails.certificate.footer":"Førre sertifikatet ditt vil vere gyldig i 30 dagar sidan den første feilen. Vi rår sterkt til at du undersøkjer denne saka, elles vil domenet ditt ende opp utan gyldig SSL-kommunikasjon.",
"emails.otpSession.securityPhrase":"هن ای میل لاءِ سیکيورٽي جملو {{phrase}} آھي. توهان هن ای میل تي اعتماد ڪري سگهو ٿا جيڪڏهن هن جملو لاڳو ٿيندڙ جملي سان ميل کاندي.",
"emails.otpSession.thanks":"مهرباني,",
"emails.otpSession.signature":"پروجيڪٽ جي ٽيم",
"emails.certificate.subject":"%s لاءِ سند جو ناکامی",
"emails.certificate.subject":"{{domain}} لاءِ سند جو ناکامی",
"emails.certificate.hello":"هيلو,",
"emails.certificate.body":"توهان جي ڊومين '{{domain}}' لاءِ سرٽيفڪيٽ ٺاهڻ جو نه ٿي سگهيو. هي ڪوشش نمبر {{attempt}} آهي، ۽ ناڪامي جو سبب ٿيو: {{error}}",
"emails.certificate.footer":"توهان جو اڳيون سرٽيفڪيٽ اولهو فئيلر جي ݙينهن کان ٣٠ ݙينهن لاءِ ماني ويندو. اسان ان جي چھان بني جي بھرپور خواهش ڪنداسين، نہ ته توهان جو ݙومين بغير ڪوري SSL ڪميونڪيشن آڻي ويندي.",
"emails.invitation.subject":"அழைப்பிதழ் %s குழு %s ",
"emails.invitation.subject":"அழைப்பிதழ் {{team}} குழு {{project}} ",
"emails.invitation.hello":"வணக்கம்,",
"emails.invitation.body":"{{project}} இல் {{team}} குழுவில் உறுப்பினராக உங்களை {{owner}} அழைக்க விரும்புவதால், இந்த அஞ்சல் உங்களுக்கு அனுப்பப்பட்டது.",
"emails.invitation.footer":"உங்களுக்கு ஆர்வம் இல்லை என்றால், இந்த செய்தியை நீங்கள் புறக்கணிக்கலாம்.",
"settings.inspire":"\"Ang sining ng pagiging matalino ay ang sining ng pag-alam kung ano ang dapat kaligtaan.\"",
"settings.locale":"tl",
"settings.direction":"ltr",
"emails.sender":"Pangkat ng %s",
"emails.sender":"Pangkat ng {{project}}",
"emails.verification.subject":"Pagpapatunay ng account",
"emails.verification.hello":"Kamusta {{user}},",
"emails.verification.body":"Sundin ang link na ito upang ma-verify ang iyong email address.",
@@ -12,8 +12,6 @@
"emails.verification.signature":"Pangkat ng {{project}}",
"emails.magicSession.subject":"Mag log in",
"emails.magicSession.hello":"Kamusta ,",
"emails.magicSession.body":"Sundin ang link na ito upang mag-login.",
"emails.magicSession.footer":"Kung hindi mo hiningi na mag-login gamit ang email na ito, maaari mong balewalain ang mensahe na ito.",
"emails.magicSession.thanks":"Salamat,",
"emails.magicSession.signature":"Pangkat ng {{project}}",
"emails.recovery.subject":"I-reset ang password",
@@ -23,7 +21,7 @@
"emails.recovery.thanks":"Salamat,",
"emails.recovery.buttonText":"I-reset ang password",
"emails.recovery.signature":"Pangkat ng {{project}}",
"emails.invitation.subject":"Imbitasyon para sa Pangkat %s sa %s",
"emails.invitation.subject":"Imbitasyon para sa Pangkat {{team}} sa {{project}}",
"emails.invitation.hello":"Kamusta,",
"emails.invitation.body":"Ipinadala sa iyo ang mail na ito dahil gusto kang imbitahan ni {{owner}} na maging miyembro ng Pangkat {{team}} sa ilalim ng proyektong {{project}}.",
"emails.invitation.footer":"Kung ikaw ay hindi interesado, maaari mong balewalain ang mensaheng ito.",
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.