Compare commits

...
Author SHA1 Message Date
Khushboo Verma 8a4c5bec27 Revert /deployments from function logs 2025-03-13 18:58:56 +05:30
Khushboo Verma 97acbd42ba Fix github comment 2025-03-13 17:58:05 +05:30
Matej Bačo 79e066a4d7 Post-merge fixes 2025-03-13 12:04:20 +01:00
Matej Bačo 725dff7f0f Merge branch '1.7.x' into feat-sites 2025-03-13 11:41:28 +01:00
Matej Bačo 358e096301 Merge branch '1.6.x' into 1.7.x 2025-03-13 11:34:14 +01:00
Matej Bačo 74c050ffb6 Improve tests 2025-03-13 11:19:55 +01:00
Matej Bačo 8376b176cb Support commit type 2025-03-13 11:17:10 +01:00
Matej Bačo 69ed3bb776 New deployment status while queued 2025-03-13 10:53:25 +01:00
Matej Bačo 262b2e6cff Fix error messag coloring 2025-03-13 10:53:15 +01:00
Matej Bačo acb9548e85 Fix preview deicison-maker; speed-up tests 2025-03-13 10:33:28 +01:00
Matej Bačo ee1ee7ecfe Fix ping 5xx error 2025-03-13 10:20:45 +01:00
Matej BačoandGitHub b14d76af0d Merge pull request #9500 from appwrite/chore-improve-readability
Improve params readability
2025-03-13 09:56:11 +01:00
Khushboo Verma f2ba319e6e Improve params readability 2025-03-13 12:16:17 +05:30
Matej Bačo f1877476d0 Upgrade console 2025-03-12 13:36:16 +01:00
Matej BačoandGitHub 75b3e78098 Merge pull request #9492 from appwrite/chore-add-invalid-ssr-site-test
Throw build error for adapter mismatch
2025-03-12 13:10:27 +01:00
Matej Bačo 82e16e6d9e Merge branch 'feat-sites' of github.com:appwrite/appwrite into feat-sites 2025-03-12 13:07:37 +01:00
Matej Bačo 63710e8ff8 Fix response filter version 2025-03-12 13:07:15 +01:00
Khushboo Verma 794329be82 Updated check 2025-03-12 17:25:39 +05:30
Khushboo Verma 5549cd8900 Merge branch 'feat-sites' into chore-add-invalid-ssr-site-test 2025-03-12 17:16:03 +05:30
Matej BačoandGitHub a840d9de20 Merge pull request #9490 from appwrite/chore-avoid-repetition-in-workers
Avoid code repetition in workers and tasks
2025-03-12 12:40:29 +01:00
Matej Bačo 1a90c8aab5 Add Vite framework 2025-03-12 12:39:33 +01:00
Matej Bačo 7f2fdf623c Update specs 2025-03-12 12:27:15 +01:00
Khushboo Verma 39699d16ba Simplify callback syntax in tasks 2025-03-12 16:55:48 +05:30
Matej BačoandGitHub 8f391db39a Merge pull request #9484 from appwrite/chore-attribute-conistency
Chore: Attribute name consistency
2025-03-12 12:23:56 +01:00
Khushboo Verma 2f9802afa2 Use empty check 2025-03-12 16:50:20 +05:30
Khushboo Verma 3af1910cf9 Throw build error for adapter mismatch 2025-03-12 16:43:46 +05:30
Matej Bačo 796a845bcf Setup request & response filters 2025-03-12 12:10:10 +01:00
Matej BačoandGitHub 56736a79e2 Merge pull request #9485 from appwrite/feat-opr-v5
Feat: OPR v5
2025-03-12 11:44:07 +01:00
Matej Bačo 536319b440 PR review changes 2025-03-12 11:32:43 +01:00
Matej Bačo ea35b6226d Fix flutter screenshots 2025-03-12 11:16:55 +01:00
Khushboo Verma 42cd1df77d Remove duplication from workers 2025-03-12 15:24:52 +05:30
Matej Bačo 994e2faa42 OPR v5 + Flutter starter 2025-03-11 18:19:25 +01:00
Matej Bačo ba26dd6df5 Apply consistency of attributes 2025-03-11 16:26:49 +01:00
Matej BačoandGitHub 0170b4c9e8 Merge pull request #9483 from appwrite/chore-add-template-tests-to-sites
Add get and list template tests for sites
2025-03-11 14:56:24 +01:00
Matej Bačo ab7041d653 Merge branch 'feat-sites' into chore-add-template-tests-to-sites 2025-03-11 14:17:40 +01:00
Matej Bačo 1a56be197c Fix failing tests 2025-03-11 14:17:23 +01:00
Matej Bačo b79b320414 Tempaltes: Fix react native, add Angular 2025-03-11 14:16:27 +01:00
Khushboo Verma 1b04ae6d96 Add get and list template tests for sites 2025-03-11 17:21:28 +05:30
Matej Bačo 95e96b3bfb Fix missing deployment domains 2025-03-11 11:53:26 +01:00
Matej Bačo 18e4be2eab Add JS template 2025-03-11 11:49:31 +01:00
Matej Bačo 7f05a74b31 Increase rate limit for 0.5s debounce in UI 2025-03-11 10:27:08 +01:00
Matej Bačo 733c5ad97d Add enforced minimal specs 2025-03-11 10:24:18 +01:00
Matej Bačo 71b56fc504 Remove log/execution search 2025-03-11 10:22:28 +01:00
Matej Bačo 62eb159e6a Merge branch 'feat-sites' of github.com:appwrite/appwrite into feat-sites 2025-03-11 10:08:47 +01:00
Matej Bačo f61db29498 Rename config to follow folder pattern 2025-03-11 09:50:02 +01:00
Matej BačoandGitHub d8418a222c Merge pull request #9433 from appwrite/chore-truncate-git-commit-message
Truncate commit message to 252 characters
2025-03-11 09:42:21 +01:00
Matej Bačo 63c7f4c8bc Fix remix detection false postive 2025-03-10 15:33:11 +01:00
Matej Bačo b11ad4b1c9 Fix a bug 2025-03-10 15:16:47 +01:00
Matej Bačo 93510d170e Quality fixes 2025-03-10 14:53:44 +01:00
Matej Bačo be3d18ab41 Fix test 2025-03-10 12:56:20 +01:00
Matej Bačo efc5b9e353 Add frameworks 2025-03-10 12:32:12 +01:00
Matej Bačo d86cf7b437 Fix 5xx error on authroization 2025-03-09 18:51:49 +01:00
Matej Bačo aabee0ac37 Fix order of site commands 2025-03-09 16:15:08 +01:00
Matej Bačo 4e1168654d Fix tests 2025-03-09 15:42:17 +01:00
Matej Bačo 254018071a Fix tests; upgrade console 2025-03-09 15:33:06 +01:00
Matej Bačo e904ab6232 Fix path issue 2025-03-09 15:07:25 +01:00
Matej Bačo fed6cefa81 Fix cors issues 2025-03-09 14:50:45 +01:00
Matej Bačo 640f09c49b Fix specs 2025-03-09 13:57:19 +01:00
Matej Bačo 06bb001d0b Improve enums 2025-03-09 00:35:55 +01:00
Matej Bačo 3730ff4895 Fix SDK generation 2025-03-09 00:19:54 +01:00
Matej Bačo 05771c46d6 Update specs 2025-03-09 00:02:39 +01:00
Matej BačoandGitHub 4ff0b6283a Merge pull request #9474 from appwrite/fix-sites-tests
Fix: site tests
2025-03-08 23:57:59 +01:00
Matej Bačo 852a16d01b Remove leftovers 2025-03-08 23:34:37 +01:00
Matej Bačo 084b6c799a Revert "Simplify tests further"
This reverts commit 7e460f6155.
2025-03-08 23:33:37 +01:00
Matej Bačo eddeac6e4f Revert temp changes 2025-03-08 23:33:33 +01:00
Matej Bačo 874f60dce6 Upgrade detection lib 2025-03-08 23:26:25 +01:00
Matej Bačo d21814c51f Improve logs 2025-03-08 23:04:32 +01:00
Matej Bačo 65bcf7898e Improve CI/CD logs 2025-03-08 22:56:16 +01:00
Matej Bačo 7e460f6155 Simplify tests further 2025-03-08 22:43:35 +01:00
Matej Bačo 1a271ff272 Temporarly simplify CI/CD 2025-03-08 22:26:04 +01:00
Matej Bačo 5963631c70 Fix site tests 2025-03-08 22:25:52 +01:00
Matej BačoandGitHub 0fa5460a7e Merge pull request #9461 from appwrite/chore-rules-rehaul
Chore: 2nd rules rehaul
2025-03-08 21:52:47 +01:00
Matej Bačo 12e3d70032 Post-merge fixes 2025-03-08 21:33:43 +01:00
Matej Bačo 5f766f6a13 Merge branch 'feat-sites' into chore-rules-rehaul 2025-03-08 21:33:13 +01:00
Matej BačoandGitHub 7d27ceef43 Merge pull request #9315 from appwrite/feat-add-detection-logic
Integrate detection library with Appwrite
2025-03-08 21:30:19 +01:00
Matej BačoandGitHub 9c3cfc4f83 Merge pull request #9357 from appwrite/feat-authroized-previews
Feat: Authorized previews
2025-03-08 21:04:25 +01:00
Matej BačoandGitHub b4d366eea1 Merge pull request #9457 from appwrite/chore-remove-builds-collection
Chore Remove builds collection
2025-03-08 20:45:10 +01:00
Matej Bačo 8a4954d4e8 PR review changes 2025-03-08 20:44:54 +01:00
Matej Bačo 1943e00e40 Fix tests 2025-03-08 19:58:54 +01:00
Matej Bačo f75acfa503 Remove deploymentUpdatePolicy, add trigger 2025-03-08 19:19:05 +01:00
Matej Bačo b69c40345f Improve docs 2025-03-08 18:45:38 +01:00
Matej Bačo 83dd6a9897 FIx tests 2025-03-08 18:39:13 +01:00
Matej Bačo 75f543c6b0 Upgrade lib version 2025-03-08 18:01:50 +01:00
Matej Bačo 232f99c6c9 Finalize PR, review changes, fix tests 2025-03-08 16:50:39 +01:00
Matej Bačo faa1b0a59b Merge branch 'feat-sites' into feat-add-detection-logic 2025-03-08 14:58:49 +01:00
Matej Bačo fe210e0cf0 Merge branch 'feat-sites' into feat-authroized-previews 2025-03-08 13:04:00 +01:00
Matej Bačo f85bf337b7 Migrate authorize endpoint to http lib 2025-03-08 13:03:23 +01:00
Matej Bačo 06020e2b62 Add preview auth tests, finish todos, improve quality 2025-03-08 12:57:55 +01:00
Matej BačoandGitHub 8ff4d60dbb Merge pull request #9469 from appwrite/feat-site-specifications
Feat: Merge specs
2025-03-08 10:58:49 +01:00
Matej Bačo 43cd7ac8b3 Linter fix 2025-03-07 23:45:19 +01:00
Matej Bačo 393c4012d9 Merge branch 'feat-sites' into feat-authroized-previews 2025-03-07 23:44:52 +01:00
Matej Bačo c6a862a0a3 Specifications test, fix failures 2025-03-07 23:17:15 +01:00
Matej Bačo 1d983a949e Merge site & function specs 2025-03-07 22:36:13 +01:00
Matej Bačo 5e30fc5350 Fix graphQL test 2025-03-07 21:20:37 +01:00
Matej Bačo a5457da91c Linter fix 2025-03-07 21:12:13 +01:00
Matej Bačo a37a6d9d7c Merge branch 'feat-sites' into chore-remove-builds-collection 2025-03-07 21:05:15 +01:00
Matej Bačo c1ee2f2b41 Failing test fixes 2025-03-07 21:04:24 +01:00
Matej Bačo 6a584c83c1 Attribute renaming 2025-03-07 20:14:11 +01:00
Matej Bačo 777fb3fcdd Update proxy rule tests 2025-03-07 18:00:20 +01:00
Matej BačoandGitHub 6ea20659e6 Merge branch 'feat-sites' into chore-rules-rehaul 2025-03-07 17:34:37 +01:00
Matej BačoandGitHub dade177af2 Merge pull request #9463 from appwrite/feat-reuse-node
Feat: Reuse Node runtime
2025-03-07 16:03:56 +01:00
Matej Bačo 97ffbbc44b Remove need for ssr runtime 2025-03-07 15:46:49 +01:00
Matej Bačo f07c351c94 Linter fix 2025-03-07 11:22:13 +01:00
Matej Bačo a42522feaa Fix test failures 2025-03-07 11:11:32 +01:00
Matej Bačo 9400fdbbe5 Leftover bugs after rework 2025-03-07 10:43:54 +01:00
Matej Bačo 92b696ea21 Introduce type-relevant attributes to rules 2025-03-07 10:14:45 +01:00
Matej Bačo 50ec55d595 Fix site tests 2025-03-06 18:35:57 +01:00
Matej Bačo a7fc8cf84b Fix functions 2025-03-06 18:17:01 +01:00
Matej Bačo 794c6536fb Fixbugs 2025-03-06 17:55:53 +01:00
Matej Bačo 2e30c1ba1f Reapply "Remove builds collection"
This reverts commit 654d178cf2.
2025-03-06 15:34:06 +01:00
Matej Bačo 654d178cf2 Revert "Remove builds collection"
This reverts commit 02e740f8b0.
2025-03-06 15:33:48 +01:00
Matej Bačo 02e740f8b0 Remove builds collection 2025-03-06 15:32:23 +01:00
Matej BačoandGitHub 62b639ce48 Merge pull request #9455 from appwrite/chore-migrate-cancel-deployment-endpoint
Chore: Move cancel build to update deployment status
2025-03-06 14:04:35 +01:00
Matej Bačo 825e9639b1 Move cancel build to deployment endpoint 2025-03-06 12:20:08 +01:00
Matej Bačo 9a8a2b5a49 Upgrade http lib 2025-03-06 09:32:05 +01:00
Matej BačoandGitHub 4428ed1f7d Merge pull request #9445 from appwrite/chore-rename-redeploy-endpoint
Chore: Migrate redeploy endpoint
2025-03-06 09:29:38 +01:00
Khushboo Verma de5f33f206 keep truncation only during create document 2025-03-05 22:45:48 +05:30
Khushboo Verma 9a44e8130f Add tests for framework, runtime and rendering detection 2025-03-05 22:35:49 +05:30
Matej Bačo 2f3c43d0db Fix failing tests 2025-03-05 13:00:06 +01:00
Matej Bačo 77d27bdd20 Post-merge formatting 2025-03-05 12:33:32 +01:00
Matej Bačo 87a9d72523 Merge branch 'feat-sites' into chore-rename-redeploy-endpoint 2025-03-05 12:33:17 +01:00
Matej Bačo f6674f07e4 Add redeploy tests 2025-03-05 12:29:27 +01:00
Matej Bačo 049ad14121 Fix tests 2025-03-05 11:47:51 +01:00
Matej Bačo a0a82b86dc Migrate redeploy endpoint 2025-03-05 11:29:43 +01:00
Matej BačoandGitHub 326e62334f Merge pull request #9436 from appwrite/chore-rename-activate-endpoint
Chore: Rename deployment activate endpoint
2025-03-05 11:26:00 +01:00
Matej Bačo b29b5da006 Improve code quality 2025-03-05 10:48:26 +01:00
Matej Bačo 46039ded2f Fix rule updating 2025-03-05 10:35:01 +01:00
Matej Bačo dfce78c421 Merge branch 'feat-sites' into chore-rename-activate-endpoint 2025-03-05 10:01:54 +01:00
Matej Bačo ce3bff13dd upgrade http lib 2025-03-05 10:01:50 +01:00
Matej BačoandGitHub a031682596 Merge pull request #9432 from appwrite/chore-add-resource-type-to-sites
Add resource type label in sites endpoints
2025-03-05 09:35:30 +01:00
Khushboo Verma 9b8dd02a88 Don't throw exception from list repos detection 2025-03-05 13:48:44 +05:30
Khushboo Verma bbf37e0a0e Update length to 255 2025-03-05 13:40:15 +05:30
Khushboo Verma 826b034cd2 Re-add files deleted by mistake 2025-03-05 11:46:31 +05:30
Khushboo Verma 9ee9a8e0ed Resolve merge conflicts 2025-03-05 11:38:28 +05:30
Matej Bačo dfc2e87170 Upgrade http library 2025-03-04 21:56:51 +01:00
Matej Bačo 520b96f0d9 Finish tests 2025-03-04 16:12:57 +01:00
Matej Bačo ea30d976a8 Fix wrong path, implement tests 2025-03-04 16:04:37 +01:00
Matej Bačo 9b8e4dd862 Rename active deployment path 2025-03-04 15:22:20 +01:00
Matej Bačo ef7b9537f7 Upgrade executor 2025-03-04 15:17:01 +01:00
Matej BačoandGitHub 03c9e57773 Merge pull request #9434 from appwrite/chore-combine-download-endpoints
Chore: Combine download endpoints
2025-03-04 15:10:24 +01:00
Matej Bačo 54413f4c5e Fix bug 2025-03-04 14:31:00 +01:00
Matej Bačo a2abd982cf Backwards compatibility 2025-03-04 14:13:47 +01:00
Matej BačoandGitHub f5a0008445 Merge pull request #9417 from appwrite/feat-screenshot-task
Feat: Screenshot task for templates
2025-03-04 13:56:59 +01:00
Matej Bačo 64183f2946 Fix tests, remove leftovers 2025-03-04 13:45:44 +01:00
Matej Bačo d9eb942e8c Merge deployment download endpoints 2025-03-04 13:43:13 +01:00
Khushboo Verma 84e1b050a9 Truncate commit message to 252 characters 2025-03-04 17:28:06 +05:30
Khushboo Verma e94438927e Add resource type label in sites endpoints 2025-03-04 17:05:09 +05:30
Khushboo Verma 20ad91a906 Simplify logic to fetch versionedRuntime 2025-03-04 13:45:56 +05:30
Matej Bačo 2ae61164d4 Merge branch 'feat-sites' into feat-screenshot-task 2025-03-03 16:45:49 +01:00
Matej BačoandGitHub 774a6af333 Merge pull request #9421 from appwrite/chore-ssr-log-tests
Chore: Add SSR logs test
2025-03-03 16:45:23 +01:00
Matej Bačo 8e03db6c9e Fix tests 2025-03-03 16:42:29 +01:00
Matej Bačo 5dd4348d5c Remove leftover 2025-03-03 16:16:02 +01:00
Matej Bačo 64e2f904c5 Merge branch 'feat-sites' into feat-screenshot-task 2025-03-03 16:05:19 +01:00
Matej Bačo 07ceb1991d Linter fix 2025-03-03 16:04:28 +01:00
Matej Bačo 60f34ced91 Merge branch 'feat-sites' into chore-ssr-log-tests 2025-03-03 15:52:22 +01:00
Matej Bačo 084dcdffd9 Fix tests 2025-03-03 15:52:11 +01:00
Matej Bačo c303aa57ce Fix template CORS 2025-03-03 12:59:36 +01:00
Matej Bačo 2384113a04 Fix flaky tests 2025-03-03 12:44:28 +01:00
Khushboo Verma ef37139592 Resolve merge conflicts 2025-03-03 13:57:29 +05:30
Khushboo Verma 8b8f632abe Add providerRepository model and extend it for framework and runtime 2025-03-03 13:54:07 +05:30
Matej Bačo 7e00bc493c Add SSR tests 2025-02-28 18:29:17 +01:00
Matej Bačo 8d47d62d7a Upgrade executor 2025-02-28 17:12:17 +01:00
Matej Bačo ef030f4a08 Improve flaky test 2025-02-28 16:06:11 +01:00
Matej Bačo 580204912c Leftover 2025-02-28 15:20:38 +01:00
Matej BačoandGitHub f91e8be136 Merge pull request #9419 from appwrite/feat-function-download
Feat: Build download endpoint in Functions
2025-02-28 12:31:39 +01:00
d75b601a7b Update src/Appwrite/Platform/Modules/Functions/Http/Deployments/Builds/Download/Get.php
Co-authored-by: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com>
2025-02-28 12:10:24 +01:00
Matej Bačo 72d2ba0159 Add missing download endpoints, ensure with tests 2025-02-28 12:04:17 +01:00
Khushboo Verma dc71c50123 Resolve merge conflicts 2025-02-28 16:20:24 +05:30
Matej Bačo d6e7db8900 Fix persistent screenshot 2025-02-28 11:29:42 +01:00
Matej BačoandGitHub 559396295f Merge pull request #9416 from appwrite/feat-move-functions-endpoints-to-modules
Move function endpoints from controller to modules
2025-02-28 10:54:03 +01:00
Matej Bačo dc6143c773 Improve tests 2025-02-28 10:47:48 +01:00
Matej Bačo a1c621fab2 Fix static sites 2025-02-28 10:40:28 +01:00
Matej Bačo 2510cb9687 Avoid 404 race condition during screenshot 2025-02-28 10:18:06 +01:00
Matej Bačo 4efa0a7231 Leftover 2025-02-28 09:32:40 +01:00
Khushboo Verma 4afd9771c6 Remove functions.php 2025-02-27 23:42:43 +05:30
Matej Bačo dd75081609 Formatting fix 2025-02-27 17:46:47 +01:00
Matej Bačo a3c176a2bd Finalize PR 2025-02-27 17:46:41 +01:00
Matej Bačo 8081759c5c Fix failing templates 2025-02-27 17:28:25 +01:00
Matej Bačo bf3b21cdb1 Implement screenshot task and initial run 2025-02-27 15:58:33 +01:00
Khushboo Verma 26a822e4b2 Move all function endpoints to modules structure 2025-02-27 18:53:11 +05:30
Khushboo Verma cede07b520 Add more endpoints to modules 2025-02-27 18:11:47 +05:30
Matej Bačo 92daef51f0 Fix screenshot security 2025-02-27 12:44:22 +01:00
Khushboo Verma 0dbb9dadf6 Move function endpoints from controller to modules 2025-02-27 17:01:15 +05:30
Matej Bačo 496cfa92bc Fix QA instance setup 2025-02-27 10:55:49 +01:00
Matej Bačo ac51fcbf4e Preps for Console SDK 2025-02-27 10:04:11 +01:00
Matej BačoandGitHub 93d00abfe1 Merge pull request #9314 from appwrite/feat-spa
Feat: SPA support
2025-02-25 22:15:40 +01:00
Matej Bačo d79ab99202 Test fix after merge 2025-02-25 18:22:40 +01:00
Matej Bačo 1e111294df Merge branch 'feat-sites' into feat-spa 2025-02-25 17:57:14 +01:00
Matej BačoandGitHub 1752e8ed83 Merge pull request #9407 from appwrite/fix-sites-device
Fix: deviceForSites
2025-02-25 17:55:49 +01:00
Matej Bačo 22598ae41d Leftover 2025-02-25 17:34:28 +01:00
Matej Bačo a89f591f63 Use deviceForSites properly 2025-02-25 16:42:25 +01:00
Matej BačoandGitHub ac9ac3e279 Merge pull request #9395 from appwrite/fix-apex-rules
Feat: Enhance rules
2025-02-25 15:34:24 +01:00
Matej Bačo 859a9c72e1 Update ProxyCustomServerTest.php 2025-02-25 15:22:24 +01:00
Matej Bačo 19928bd7dc Add delete worker tests for rules 2025-02-25 15:13:59 +01:00
88b3791a24 Update src/Appwrite/Utopia/Response/Model/Rule.php
Co-authored-by: Khushboo Verma <43381712+vermakhushboo@users.noreply.github.com>
2025-02-25 14:37:54 +01:00
Matej Bačo 765a0fa891 Merge branch 'feat-sites' into fix-apex-rules 2025-02-25 14:05:08 +01:00
Matej BačoandGitHub fac42f7ad5 Merge pull request #9405 from appwrite/chore-remove-subquery
Chore: Remove subquery
2025-02-25 13:59:25 +01:00
Matej Bačo d7c163be95 PR review changes 2025-02-25 13:52:51 +01:00
Matej Bačo 16934af49f Fix flaky test 2025-02-25 13:14:33 +01:00
Matej Bačo 29f660cfd6 leftover 2025-02-25 13:04:18 +01:00
Matej Bačo 743ded1e79 Remove domain from deployment model 2025-02-25 13:03:44 +01:00
Matej Bačo 88ae06af57 Improve formatting 2025-02-25 12:53:12 +01:00
Khushboo Verma a54f84fce8 Resolve merge conflicts 2025-02-25 16:20:58 +05:30
Khushboo Verma f830918c7c Add logic to detect rendering strategy and fallback file 2025-02-25 16:19:30 +05:30
Matej Bačo 2ba84bf93f Rule search param fix 2025-02-25 10:47:47 +01:00
Matej Bačo 474e04479f Linter fix 2025-02-24 18:44:11 +01:00
Matej Bačo 40beecdddc Fix tests 2025-02-24 18:42:20 +01:00
Matej Bačo 427e781b5b Add git domains, improve tests 2025-02-24 16:22:23 +01:00
Matej Bačo 9e909ee3fc Specs update 2025-02-24 12:15:50 +01:00
Matej Bačo eb7daf3edd Finalize rules overhauls 2025-02-24 11:55:59 +01:00
Matej Bačo a56086f8bf Basics of rules rework 2025-02-23 21:34:14 +01:00
Matej Bačo ae835f6cf0 Fix tests 2025-02-23 17:08:12 +01:00
Matej Bačo 666e8f3ec9 Separate proxy rule creation 2025-02-22 18:56:51 +01:00
Matej Bačo aeebdadae1 Add nameservers variable 2025-02-22 18:32:10 +01:00
Matej Bačo 0a25463b8d Apex domain exception + proxy tests 2025-02-22 18:26:51 +01:00
Matej Bačo 7e3b693216 Disable internal httpx 2025-02-21 23:45:45 +01:00
Matej Bačo a5fc9463c7 Support for deployment screenshots 2025-02-21 22:35:05 +01:00
Matej Bačo 08ec153585 update specs 2025-02-21 22:14:02 +01:00
Matej BačoandGitHub c8f4667b6a Merge pull request #9366 from appwrite/feat-site-screenshots
Feat: Site screenshots
2025-02-21 22:11:03 +01:00
Matej Bačo f9bc5d0cce Fix tests 2025-02-21 22:10:39 +01:00
Matej Bačo 7397d52c0c Fix tests 2025-02-21 21:41:39 +01:00
Matej Bačo 8661ae6840 Disable banner for screenshots 2025-02-21 20:50:43 +01:00
Matej Bačo 498c1456ed Merge branch 'feat-sites' into feat-site-screenshots 2025-02-21 20:22:50 +01:00
Matej Bačo 2917c66202 Remove unnessessary complexity 2025-02-21 20:21:13 +01:00
Matej Bačo 26c99dca84 Add onelink template 2025-02-21 18:55:59 +01:00
Matej Bačo 67d6404c70 Add further templates 2025-02-21 12:46:44 +01:00
Khushboo Verma 1394b4349c Separate response models for list repos 2025-02-21 15:22:15 +05:30
Matej Bačo ede068d5f4 Add react native, vue template 2025-02-21 10:51:53 +01:00
Matej Bačo 1c6204118f PR code review 2025-02-21 10:09:35 +01:00
Matej Bačo cdc3cb23ec React starter template 2025-02-21 09:58:24 +01:00
Khushboo Verma 9d4806c792 Merge branch 'feat-sites' into feat-add-detection-logic 2025-02-21 11:39:06 +05:30
Matej Bačo 54d877fe3e PR review fixes 2025-02-20 16:49:20 +01:00
Matej Bačo c3df0a71e3 Address leftover 2025-02-20 14:34:59 +01:00
Matej Bačo 732e74f114 Finalize screenshot tests 2025-02-20 14:22:30 +01:00
Matej Bačo d941d18e8c WIP: screenshot tests 2025-02-20 13:44:31 +01:00
Matej Bačo 3ccd49e4a5 Rework screenshots to use api key resource from recent 1.6.x merge 2025-02-20 13:44:22 +01:00
Matej Bačo 2d761b48d8 Merge branch 'feat-sites' into feat-site-screenshots 2025-02-20 13:17:23 +01:00
Matej BačoandGitHub 556bcbf33b Merge pull request #9382 from appwrite/fix-flaky-tests-sites
Fix: Improve tests OPR setup
2025-02-20 12:57:04 +01:00
Matej Bačo e6a53a8c15 Enable sites on non-shared tables 2025-02-20 12:33:00 +01:00
Matej Bačo f5f37d6a79 Simplify OPR startup check 2025-02-20 12:25:13 +01:00
Matej Bačo f0d8c7382b Simplify YML file 2025-02-20 12:19:32 +01:00
Matej Bačo fb19f8d6a6 Run sites in non-shared mode tests 2025-02-20 09:13:50 +01:00
Khushboo Verma 68de687bdf Resolve merge conflicts 2025-02-20 12:57:18 +05:30
Khushboo Verma a7c1bd94ed Add framework detection to list repos 2025-02-20 12:54:26 +05:30
Matej Bačo 95aab45cc2 Fix merge issue 2025-02-19 16:01:05 +01:00
Matej Bačo 4a0d33213a Fix tests 2025-02-19 15:50:16 +01:00
Matej Bačo 322b726196 Fix test 2025-02-19 15:37:43 +01:00
Matej Bačo cd25a79694 Improve tests OPR setup 2025-02-19 15:29:42 +01:00
Matej Bačo 47395c5442 Fix failing tests regarding specs and failed builds 2025-02-19 14:58:59 +01:00
Matej Bačo d13e8641fd Allow inactive vcs deployments 2025-02-19 13:39:11 +01:00
Matej Bačo acd1dd2479 Formatting fix 2025-02-19 12:56:27 +01:00
Matej Bačo 3cc1fb6fb4 Post-merge update 2025-02-19 12:55:39 +01:00
Matej Bačo 3932b8bdc1 Merge branch '1.7.x' into feat-sites 2025-02-19 12:54:05 +01:00
Khushboo Verma 3bb4fde7e6 Merge branch 'feat-sites' into feat-add-detection-logic 2025-02-19 17:12:45 +05:30
Matej Bačo 165caef9ab Merge branch '1.6.x' into 1.7.x 2025-02-19 12:40:07 +01:00
Matej BačoandGitHub 055411fbe4 Merge pull request #9380 from appwrite/feat-add-createVcsDeployment
Add createVcsDeployment endpoints for sites and functions
2025-02-19 12:31:25 +01:00
Matej Bačo 63a91e30fa Add reference params 2025-02-19 11:50:25 +01:00
Khushboo Verma f7749bbbef Add createVcsDeployment endpoints for sites and functions 2025-02-19 14:55:44 +05:30
Khushboo Verma c0b574fe9b Update detector library version 2025-02-19 12:19:41 +05:30
Khushboo Verma 34b8453666 Merge branch 'feat-sites' into feat-add-detection-logic 2025-02-18 20:19:11 +05:30
Matej Bačo ae1eb53e31 Update specs 2025-02-18 09:31:56 +01:00
Matej BačoandGitHub 3b87b42dac Merge pull request #9352 from appwrite/feat-all-rules-in-proxy
Move rule creation to create rule
2025-02-18 09:28:39 +01:00
Khushboo Verma db8010f7c6 Fix site tests 2025-02-18 13:03:57 +05:30
Khushboo Verma c24cebf6ce Fix site tests 2025-02-18 12:50:09 +05:30
Khushboo Verma 262b152cd9 Add more rule tests 2025-02-18 12:12:12 +05:30
Matej Bačo 2e4a8dec78 Fix CORS 2025-02-17 15:05:19 +01:00
Khushboo Verma 2ea18c4761 Fix domain generation 2025-02-17 18:12:29 +05:30
Khushboo Verma 28ef7da231 Fix new site tests 2025-02-17 18:03:13 +05:30
Khushboo Verma 76b154bfce Add framework detection to list repos 2025-02-17 17:54:13 +05:30
Matej Bačo c2a60a8569 Screenshot deletion in worker 2025-02-17 13:03:56 +01:00
Khushboo Verma 71103b037f Make switch case simpler 2025-02-17 17:17:27 +05:30
Khushboo Verma 9459c87b50 Re-add correct project tests 2025-02-17 17:15:23 +05:30
Matej Bačo e5e7c50ca4 previewHostname security 2025-02-17 11:54:07 +01:00
Matej Bačo 30cb7e8ff2 Todos 2025-02-17 09:47:38 +01:00
Matej Bačo 2f2a743a7f Merge branch 'feat-sites' into feat-all-rules-in-proxy 2025-02-17 09:47:33 +01:00
Khushboo Verma feffab137f Resolve merge conflicts 2025-02-17 14:00:30 +05:30
Khushboo Verma 6155fad3e0 Resolve merge conflicts 2025-02-17 14:00:05 +05:30
Matej Bačo d1978b102f Dark screenshot, upgrade screnshot image, fix redeploy missing domain 2025-02-15 22:27:16 +01:00
Khushboo Verma b1854fee10 Add helper methods in functionBase 2025-02-15 23:23:02 +05:30
Matej BačoandGitHub 62b1c19357 Merge pull request #9364 from appwrite/feat-template-deployment
Feat: Template deployments
2025-02-15 15:15:13 +01:00
Matej Bačo e1dedd2fbb Remove unnessessary check 2025-02-15 04:41:36 +01:00
Matej Bačo 51e89f5110 Revert "Initial branch rule implementation"
This reverts commit 81a7ba536c.
2025-02-15 04:38:21 +01:00
Matej Bačo 81a7ba536c Initial branch rule implementation 2025-02-15 04:36:38 +01:00
Matej Bačo fb2649ab41 Add leftover 2025-02-15 03:44:40 +01:00
Matej Bačo b746642979 Fix missing response 2025-02-15 02:01:11 +01:00
Matej Bačo a6bcc3ce97 Fix bugs 2025-02-15 01:57:41 +01:00
Matej Bačo b30d9eb8ad Initial screenshot implementation 2025-02-15 01:19:21 +01:00
Matej Bačo 28339f0ed7 createTemplateDeployment for sites and deployments 2025-02-15 00:36:46 +01:00
Matej Bačo da9d442473 Re-add starter templates 2025-02-15 00:34:43 +01:00
Matej Bačo 47a6168137 Update console and templates 2025-02-14 21:42:39 +01:00
Matej BačoandGitHub 9222fec7f8 Merge pull request #9359 from appwrite/fix-site-cors
Fix: Site CORS
2025-02-14 12:40:37 +01:00
Matej Bačo 94f3cf7baf Merge branch 'feat-sites' into fix-site-cors 2025-02-14 12:05:21 +01:00
Matej Bačo 399afa1b14 Merge branch 'feat-sites' of github.com:appwrite/appwrite into feat-sites 2025-02-14 12:04:31 +01:00
Matej Bačo 410388a587 Upgrade Console 2025-02-14 12:03:59 +01:00
Matej BačoandGitHub 4bd08642be Merge pull request #9326 from appwrite/feat-preview-branding
Feat: preview branding
2025-02-14 12:03:33 +01:00
Matej Bačo 3ab8503f61 Code quality fixes 2025-02-14 10:36:34 +01:00
Matej Bačo 75320db428 Update transformation lib structure 2025-02-14 10:01:27 +01:00
Matej Bačo 43f0dc0846 Add CORS tests 2025-02-14 09:47:37 +01:00
Matej Bačo a10882d7ee Update general.php 2025-02-13 19:59:29 +01:00
Matej Bačo ec05a3d668 Enable CORS for sites 2025-02-13 19:57:41 +01:00
Khushboo Verma 3531d223e2 Fix general tests 2025-02-13 20:27:25 +05:30
Khushboo Verma e87fe7467e Merge branch 'feat-sites' into feat-all-rules-in-proxy 2025-02-13 16:54:12 +05:30
Matej Bačo f6fbc253f7 Update Console 2025-02-13 11:33:22 +01:00
Matej Bačo 313444cb12 Fix envCommands set too late 2025-02-13 11:14:08 +01:00
Khushboo Verma bd58ba32c8 Remove older test 2025-02-13 14:21:52 +05:30
Matej Bačo 80241e37c3 Update tempalte auto-values 2025-02-13 09:47:37 +01:00
Khushboo Verma 4b909ed7dc Create rule in function logging test 2025-02-13 00:23:13 +05:30
Khushboo Verma f9ce932ac1 Create site rule 2025-02-13 00:11:43 +05:30
Khushboo Verma f67870925f Resolve merge conflicts 2025-02-13 00:01:18 +05:30
Khushboo Verma f416e39098 Move create rule to module 2025-02-12 23:58:25 +05:30
Matej BačoandGitHub c4142565aa Merge pull request #8970 from appwrite/feat-console-availability-endpoint
Add new console endpoint to check resource availability
2025-02-12 17:17:05 +01:00
Matej BačoandGitHub 81bfa5c48d Merge branch 'feat-sites' into feat-preview-branding 2025-02-12 16:35:31 +01:00
Khushboo VermaandGitHub 0106dc7803 Update Get.php 2025-02-12 19:41:55 +05:30
Khushboo Verma 3b0d760065 Increase deployment build timeout 2025-02-12 19:18:16 +05:30
Matej Bačo e0369ec14f Avoid JS link 2025-02-12 14:09:32 +01:00
Khushboo Verma c78701ded7 Increase time to assert 2025-02-12 17:54:03 +05:30
Khushboo Verma adb861b785 Use getSiteDomain 2025-02-12 17:29:19 +05:30
Khushboo Verma aae3b40d16 Refactor console availability endpoint 2025-02-12 16:10:44 +05:30
Matej Bačo 6415009f07 Add SvelteKit Appwrite template 2025-02-12 11:01:26 +01:00
Khushboo Verma b46eebb23c Resolve merge conflicts 2025-02-12 11:49:33 +05:30
Matej Bačo 86a1fbe86a Fix preview domains 2025-02-11 16:26:00 +01:00
Matej Bačo 14e4854947 Upgrade Console 2025-02-11 15:18:44 +01:00
Matej BačoandGitHub 1c1f9aee2c Merge pull request #9322 from appwrite/feat-add-secret-to-update-variable
Add secret param to update variable endpoint
2025-02-11 14:50:49 +01:00
Matej Bačo 084b62116f Convert to library approach 2025-02-11 14:26:49 +01:00
Khushboo Verma 3d6351bbe0 Merge branch 'feat-add-secret-to-update-variable' of github.com:appwrite/appwrite into feat-add-secret-to-update-variable 2025-02-11 18:47:31 +05:30
Khushboo Verma 187f4c841e Remove error message validation 2025-02-11 18:46:31 +05:30
Matej BačoandGitHub 15a0c28093 Merge branch 'feat-sites' into feat-add-secret-to-update-variable 2025-02-11 14:14:46 +01:00
Khushboo Verma c440a3933b Fix functions tests 2025-02-11 18:42:18 +05:30
Khushboo Verma 11477d67c9 Address PR comments 2025-02-11 18:20:54 +05:30
Khushboo Verma f1989d0aba Fix project tests 2025-02-10 22:07:07 +05:30
Khushboo Verma 75219b800a Fix failing tests 2025-02-10 19:59:28 +05:30
Matej Bačo 4c3fa5f246 Update composer.lock 2025-02-10 15:12:55 +01:00
Matej Bačo 06ed493cfe Merge branch '1.6.x' into feat-sites 2025-02-10 15:12:36 +01:00
Matej Bačo 7be0fbf616 Implementation of authorized previews 2025-02-10 15:07:01 +01:00
Khushboo Verma 6cf53bbb81 Add E2E variable test for functions 2025-02-10 19:05:27 +05:30
Khushboo Verma 3a766bf970 Add E2E test for secret env var 2025-02-10 18:43:31 +05:30
Khushboo Verma f96291af88 Add tests for function variables 2025-02-10 16:24:14 +05:30
Khushboo Verma 8557a9e1b1 Add secret param to update variable in function and projects 2025-02-10 16:06:31 +05:30
Matej Bačo e8af2338ec Add oauth attributes to installation 2025-02-10 11:05:35 +01:00
Matej Bačo aec9d91a68 Formatting fix 2025-02-10 09:17:59 +01:00
Matej Bačo 950255fab9 Merge branch 'feat-sites' into feat-spa 2025-02-10 09:17:28 +01:00
Khushboo Verma 7c9d6ccde2 Merge branch 'feat-sites' into feat-add-secret-to-update-variable 2025-02-10 12:32:19 +05:30
Matej Bačo 5c286c3334 Implement preview branding 2025-02-08 15:53:55 +01:00
Matej BačoandGitHub f8b27c0b76 Merge pull request #9324 from appwrite/chore-improve-tests
Chore: Improve tsts
2025-02-08 13:23:39 +01:00
Matej Bačo 6e5d4fb358 Fix formatting 2025-02-08 12:18:39 +01:00
Matej Bačo 5e2abc539f Add helper for site domain 2025-02-08 12:16:25 +01:00
Matej Bačo 2f03a33c15 Add template site and domain reclaiming tests 2025-02-08 12:11:09 +01:00
Khushboo Verma 7ce0e3c38c Add strict checks for value of secret 2025-02-08 16:28:04 +05:30
Matej BačoandGitHub e269614a51 Update tests/e2e/Services/Sites/SitesCustomServerTest.php 2025-02-08 10:48:49 +01:00
Matej Bačo 21c224709f Finish SPA integration 2025-02-08 10:36:11 +01:00
Khushboo Verma ac8a29f047 Add site variables tests 2025-02-07 23:27:46 +05:30
Khushboo Verma 681f4b9eda Change to module structure 2025-02-07 21:29:48 +05:30
Khushboo Verma 2b46bd2643 Add secret param to update var 2025-02-07 20:36:57 +05:30
Khushboo Verma a322b022eb Rename to getResourceAvailability 2025-02-07 19:25:10 +05:30
Khushboo Verma 0dc43432e2 Update SDK method structure 2025-02-07 19:06:57 +05:30
Khushboo Verma 27de266cb0 Add tests 2025-02-07 18:53:33 +05:30
Matej Bačo 2e048b0895 Upgrade console 2025-02-07 14:10:39 +01:00
Matej Bačo f8bf532fc0 Sync specs 2025-02-07 12:56:31 +01:00
Matej Bačo 210349dc70 Merge branch '1.6.x' into feat-sites 2025-02-07 12:53:52 +01:00
Khushboo Verma eaa4795eb6 Resolve merge conflicts 2025-02-07 16:32:35 +05:30
Matej Bačo 293f75954d Post-merge specs update 2025-02-07 11:01:41 +01:00
Matej Bačo f93eb2072c Merge branch '1.6.x' into feat-sites 2025-02-07 11:00:35 +01:00
Khushboo Verma 0a3f284e14 Update composer.json 2025-02-07 11:18:07 +05:30
Khushboo Verma 11ed6b8f47 Resolve merge conflicts 2025-02-07 11:16:30 +05:30
Khushboo Verma 8dd99b7d2a Add framework detection to Appwrite 2025-02-06 23:59:43 +05:30
Matej Bačo df99907120 Update composer.lock 2025-02-06 14:24:08 +01:00
Matej Bačo 7ac83d7a9f Merge branch '1.6.x' into feat-sites 2025-02-06 14:23:50 +01:00
Matej Bačo f2445c2a37 Add SPA tests 2025-02-06 14:22:35 +01:00
Matej Bačo efb30e7f8e Updat deps 2025-02-06 12:19:02 +01:00
Matej Bačo 719a771613 Update version 2025-02-06 12:05:31 +01:00
Matej BačoandGitHub e0131aa749 Merge pull request #9307 from appwrite/chore-http-descriptions
Chore: Deprecate markdown docs refferences
2025-02-05 16:51:49 +01:00
Matej Bačo 5882fda501 Fix site router 2025-02-05 16:17:03 +01:00
Matej Bačo eeed8dbc16 Fix site creation namespace 2025-02-05 14:15:25 +01:00
Matej Bačo 7239b9d7cc Fix sites 5xx error 2025-02-05 13:56:17 +01:00
Matej Bačo 480c7eac21 Fix usage rename bug 2025-02-05 13:15:17 +01:00
Matej Bačo 412c75ebdd Formatting fix 2025-02-05 12:28:52 +01:00
Matej Bačo f33e4b6f5a Update specs 2025-02-05 12:28:22 +01:00
Matej Bačo 30f34d5764 Deprecate markdown docs refferences 2025-02-05 12:27:20 +01:00
Matej Bačo 2e62837de6 Migrate module names 2025-02-05 11:30:19 +01:00
Matej Bačo 3d319e25a9 SDK labels rework 2025-02-05 09:51:14 +01:00
Matej Bačo 36c9c002d1 Fix frozen 404 errors 2025-02-04 14:16:17 +01:00
Matej Bačo 7019cea5fa Update specs 2025-02-04 12:34:07 +01:00
Matej BačoandGitHub d30af2c561 Merge pull request #9182 from appwrite/feat-add-tests-for-sites
Add tests for sites
2025-02-04 11:57:02 +01:00
Matej Bačo d272a474ab Update phpunit.xml 2025-02-04 10:51:44 +01:00
Matej Bačo 66c4003789 Fix site tests 2025-02-04 10:51:33 +01:00
Matej Bačo c5d4378069 Remove leftover 2025-02-03 16:38:07 +01:00
Matej Bačo 58dc4a0280 Fix tests 2025-02-03 16:33:28 +01:00
Matej Bačo 3ed5e1b65a Merge branch 'feat-sites' into feat-add-tests-for-sites 2025-02-03 14:29:32 +01:00
Matej Bačo 2ad3b68821 Temporarly disable assertion 2025-02-03 13:57:35 +01:00
Matej Bačo f51900a69c Fix more tests 2025-02-03 13:43:35 +01:00
Matej Bačo 0fe072b17b Fix more tests 2025-02-03 12:38:27 +01:00
Matej Bačo 124cff7bf2 temporary disable test 2025-02-03 11:49:20 +01:00
Matej Bačo 3aafceab40 Improve CI/CD flaky tests 2025-02-03 11:38:36 +01:00
Matej Bačo 3b961d18f9 Publish pre-release image 2025-02-03 11:26:28 +01:00
Matej Bačo e311790365 Merge remote-tracking branch 'origin/1.7.x' into feat-sites 2025-02-03 11:04:21 +01:00
Matej Bačo 47f4e67a52 Fixing bug post-merge 2025-02-03 11:03:58 +01:00
Matej Bačo 9f9ce61c3a Post-merge fixes 2025-02-03 10:32:01 +01:00
Matej Bačo f9430d4d20 Merge branch '1.6.x' into fix-site-tests 2025-02-03 10:05:30 +01:00
Matej Bačo d5f1b56b90 Re-add secret after merge 2025-02-03 09:03:18 +00:00
Matej Bačo 1946df83a7 Merge remote-tracking branch 'origin/1.6.x' into 1.7.x 2025-02-03 09:03:04 +00:00
Matej Bačo 59d87a8af1 Fix issues with tests 2025-02-03 09:26:57 +01:00
Khushboo Verma 7be0f4a193 Add rules.read scope to console member 2025-01-29 14:56:01 +05:30
Khushboo Verma fcd920460f Addressed PR comments 2025-01-28 09:53:33 +05:30
Khushboo Verma 0124d5254c Resolve merge conflicts 2025-01-24 11:21:49 +05:30
Khushboo Verma 246dc07018 Remove unnecessary check 2025-01-23 18:47:12 +05:30
Matej Bačo 3ee67e620c Resolve conflicts 2025-01-21 15:28:37 +00:00
Matej Bačo 9a94023bde Merge remote-tracking branch 'origin/feat-sites' into feat-add-tests-for-sites 2025-01-21 13:41:08 +00:00
Matej BačoandGitHub 70f1b0c2fc Merge pull request #9193 from appwrite/fix-manual-qa
Fix: Sites manual QA
2025-01-21 14:17:57 +01:00
Matej BačoandGitHub 7009d1edf1 Merge branch 'feat-sites' into fix-manual-qa 2025-01-21 13:50:00 +01:00
Matej Bačo d652a17fd7 Remove unneeded runtime 2025-01-21 09:13:20 +01:00
Khushboo Verma e49d9f39a8 Fix usageTest 2025-01-20 01:18:43 +05:30
Khushboo Verma 4a3ea540bf Fix specification tests 2025-01-20 01:01:21 +05:30
Khushboo VermaandGitHub 04f9e9b62a Merge pull request #8939 from appwrite/feat-delete-rules
Delete rules when site or deployment is deleted
2025-01-17 23:20:40 +05:30
Khushboo Verma 76a0167700 Remove redundant check 2025-01-14 15:15:18 +05:30
Khushboo Verma aa130075e8 Add abuse limit 2025-01-13 01:20:13 +05:30
Khushboo Verma dd26a564dc Remove desc as private endpoint 2025-01-13 00:31:45 +05:30
Khushboo Verma 652ab4946d Resolve merge conflict 2025-01-13 00:10:03 +05:30
Matej Bačo efe24db5a1 Fix site starting crashes 2025-01-10 15:28:09 +01:00
Matej Bačo 0f8ce0e93e Fix Sites 2025-01-09 16:59:40 +00:00
Matej Bačo 9089eb4228 New specs 2025-01-09 15:44:13 +00:00
Khushboo Verma 8a260ceece Remove unrelated changes to site deletion 2025-01-09 17:41:45 +05:30
Khushboo Verma 426bcffd1a Resolve merge conflicts 2025-01-09 17:25:24 +05:30
Matej Bačo 9c37c3a740 Fix basic configs 2025-01-08 16:14:33 +00:00
Khushboo Verma 3c9ea6caba Fix tests 2025-01-08 16:16:26 +05:30
Khushboo Verma 857046ecb8 Address PR comments 2025-01-08 13:55:21 +05:30
Khushboo Verma f196cfe993 Use ssr-22 runtime 2025-01-07 20:07:23 +05:30
Khushboo Verma 140b850cef More tests 2025-01-07 15:35:31 +05:30
Khushboo Verma 0929ba995a More tests 2025-01-07 02:33:32 +05:30
Khushboo Verma 6bf9adfb51 Added some sites tests 2025-01-02 02:21:30 +05:30
Matej Bačo 96956dbda5 Temporary QA server fix 2024-12-06 20:58:01 +01:00
Matej Bačo 15cc64e68b Increase minimal memory 2024-12-06 19:56:46 +01:00
Matej Bačo 65d4bcef47 Fix terminology of env vars 2024-12-06 15:19:45 +01:00
Matej Bačo 5f39affe74 Fix missing build env vars 2024-12-06 15:17:50 +01:00
Matej Bačo ef21ab7f3b Update version for templates 2024-12-02 18:26:36 +01:00
Matej Bačo 554a24e44c Fix double compression 2024-12-02 17:56:52 +01:00
Matej Bačo ee731b8530 Add optional adapter 2024-12-02 17:21:54 +01:00
Matej Bačo dd3f2c6538 Force update specs 2024-12-02 17:01:18 +01:00
Matej BačoandGitHub 5a4958090e Merge pull request #9033 from appwrite/feat-ssr
Feat: Server-side rendering for site frameworks
2024-12-02 16:02:04 +01:00
Matej Bačo cd4f78d619 Update specs 2024-12-02 15:34:39 +01:00
Matej BačoandGitHub eb46ba354a Merge branch 'feat-sites' into feat-ssr 2024-12-02 15:33:12 +01:00
Matej BačoandGitHub f0b3c95035 Merge pull request #9047 from appwrite/feat-site-logs
Logs for sites
2024-12-02 15:31:21 +01:00
Matej Bačo e15fdc493c Fix missing key in specs 2024-12-02 15:28:00 +01:00
Matej Bačo fdff1664ea Add other framework 2024-12-02 15:05:26 +01:00
Khushboo Verma 4bdc9b0c84 Add logs and errors to site logs 2024-12-02 18:48:50 +05:30
Matej Bačo 563031f214 Remove local mount 2024-12-02 14:12:46 +01:00
Khushboo Verma 33273c1be1 Site logs 2024-12-02 18:30:06 +05:30
Matej Bačo 1b95790de3 Add CI/CD logs 2024-12-02 13:56:03 +01:00
Matej Bačo 2ef1cf5da0 bug fixes 2024-12-02 13:45:03 +01:00
Matej Bačo 4a117adb28 Support SSR 2024-12-02 13:20:54 +01:00
Khushboo Verma 86bc775791 Add sites resource type and logs scope 2024-11-29 18:57:10 +05:30
Khushboo Verma 9a57b09b92 Logs for sites 2024-11-29 18:27:51 +05:30
Matej Bačo 36e3d9c603 WIP: Server-side rendering for sites 2024-11-27 16:27:40 +01:00
Khushboo VermaandGitHub df4c36d71b Merge pull request #9030 from appwrite/chore-sentence-case-templates
Change case to sentence case for site template titles
2024-11-26 20:03:48 +05:30
793eb53790 Update app/config/site-templates.php
Co-authored-by: Matej Bačo <matejbacocom@gmail.com>
2024-11-26 19:59:50 +05:30
Khushboo Verma 6b568e8b7f Change case to sentence case 2024-11-26 19:55:13 +05:30
Matej Bačo fec74ee9e4 Fix naming mistake 2024-11-25 18:39:24 +01:00
Matej Bačo 10ef570485 Linter fix 2024-11-25 18:22:49 +01:00
Matej Bačo d719fd9be4 Update enum specs for frameworks 2024-11-25 18:19:18 +01:00
Matej Bačo 135023b3ed Fix start issue 2024-11-25 18:15:12 +01:00
Matej Bačo 2bd2092263 Dart support 2024-11-25 17:48:15 +01:00
Matej Bačo eee7d0422c Fix paths 2024-11-22 15:45:28 +01:00
Matej Bačo 0d314c00a6 Add more defaults to frameworks 2024-11-22 14:55:52 +01:00
Matej Bačo a5fc2e0ef7 Add missing frameworks 2024-11-22 14:15:37 +01:00
Matej Bačo e168ab9ffc Update default frameworks 2024-11-22 14:08:07 +01:00
Matej Bačo 644c18fc69 Update specs 2024-11-22 12:20:12 +01:00
Matej Bačo 57717f4690 Separate starter templates, add demo URLs 2024-11-22 12:19:59 +01:00
Matej Bačo c46a9bdb45 Add all starters 2024-11-22 11:58:54 +01:00
Matej Bačo d431b53434 Switch to official starter template for sites 2024-11-22 11:52:33 +01:00
Matej Bačo 18d9ebaab3 Add template fallback file 2024-11-21 21:43:06 +01:00
Matej Bačo 40e343d17d Fix response model missing fallbackFile 2024-11-20 15:02:26 +01:00
Matej Bačo f6122157c7 Ensure latest specs after merges 2024-11-20 14:37:47 +01:00
Matej BačoandGitHub cbaad2dfb9 Merge pull request #8995 from appwrite/feat-add-fallbackFile-attribute
Add fallbackFile for SPA
2024-11-20 14:33:28 +01:00
Matej BačoandGitHub c509ec56bd Merge branch 'feat-sites' into feat-add-fallbackFile-attribute 2024-11-20 14:33:19 +01:00
Matej BačoandGitHub a25b786fca Merge pull request #9010 from appwrite/chore-add-site-domains-var
Add _APP_DOMAIN_SITES to console variables
2024-11-20 14:33:02 +01:00
Matej Bačo 06224aa34e formatting fix 2024-11-20 14:19:15 +01:00
Matej Bačo 4bcbd49d6d Formatting fix 2024-11-20 14:18:43 +01:00
Matej BačoandGitHub 09e2ded206 Merge branch 'feat-sites' into feat-add-fallbackFile-attribute 2024-11-20 14:14:28 +01:00
Matej BačoandGitHub 4a8c063d51 Merge branch 'feat-sites' into chore-add-site-domains-var 2024-11-20 14:13:39 +01:00
Matej Bačo 2e9e6d38e2 Fix site URLs 2024-11-20 13:48:42 +01:00
Matej Bačo 53917d6d90 Update specs 2024-11-20 12:25:28 +01:00
Matej Bačo d20714eed6 Merge branch 'feat-sites' into chore-add-site-domains-var 2024-11-20 12:21:13 +01:00
Matej Bačo 2f328bf4cf Fix double rule IDs 2024-11-20 12:20:29 +01:00
Matej Bačo e3c4cdb040 Update template-runtimes.php 2024-11-20 12:10:09 +01:00
Matej Bačo c8cf645414 Merge branch '1.6.x' into feat-sites 2024-11-20 12:07:13 +01:00
Khushboo Verma aa47d9f07a Add _APP_OPTIONS_FORCE_HTTPS to console vars 2024-11-20 16:12:35 +05:30
Khushboo Verma 338559967a Update var count in tests 2024-11-20 14:52:03 +05:30
Khushboo Verma a736a42e26 Update test 2024-11-20 14:46:04 +05:30
Khushboo Verma 00c6549610 Add _APP_DOMAIN_SITES to console variables 2024-11-20 14:44:22 +05:30
Matej BačoandGitHub 510d871379 Merge pull request #9001 from appwrite/chore-move-preview-url-to-create-deployment
Create preview url rule when deployment is created
2024-11-20 09:52:03 +01:00
Khushboo Verma 43e2d7454a Create preview url rule when deployment is created 2024-11-18 20:27:07 +05:30
Khushboo Verma cb359e40ba Add fallbackFile for SPA 2024-11-18 00:23:45 +05:30
Khushboo Verma 7836e48559 Use resourceId in the endpoint url 2024-11-17 22:45:03 +05:30
Khushboo Verma d95cdc3296 WIP: Add new console endpoint 2024-11-13 21:46:07 +05:30
Khushboo Verma 2ad0428727 Merge 1.6.x into feat-sites 2024-11-13 13:18:21 +05:30
Khushboo Verma ba74ffd4bf Address PR comments 2024-11-11 11:48:26 +05:30
Khushboo Verma b88cd8e544 Add subdomain param in functions and tests 2024-11-07 21:55:41 +05:30
Khushboo Verma a031b54feb Add sitesBase test file 2024-11-07 00:04:26 +05:30
Khushboo Verma 081cf5c6aa Delete rules when site or deployment is deleted 2024-11-06 23:35:30 +05:30
Matej BačoandGitHub 6874b4f6fb Merge pull request #8885 from appwrite/feat-add-sites-comments
Feat add sites comments
2024-10-28 15:47:16 +01:00
Matej BačoandGitHub eeba650f6c Merge branch 'feat-sites' into feat-add-sites-comments 2024-10-28 15:43:46 +01:00
Matej Bačo 54b07e6b99 Add protocol 2024-10-28 15:24:34 +01:00
Khushboo Verma dc8b9478ee Fix builds 2024-10-28 15:20:36 +01:00
Torsten DittmannandGitHub d97b02add9 Merge pull request #8884 from appwrite/fix-sites-get-template
Fix: sites get template missing key
2024-10-28 15:07:10 +01:00
Matej Bačo 8427ade0fa Fix sites get template missing key 2024-10-28 15:04:48 +01:00
Khushboo Verma 44d6a0dea1 Merge branch 'feat-add-sites-comments' of github.com:appwrite/appwrite into feat-add-sites-comments 2024-10-28 15:02:00 +01:00
Khushboo Verma f710ce266b Merge branch 'feat-sites' into feat-add-sites-comments 2024-10-28 14:54:08 +01:00
Matej Bačo 45dc9a39d9 Get preview URL 2024-10-28 14:53:06 +01:00
Matej Bačo d703a118c4 Merge branch 'feat-sites' into feat-add-sites-comments 2024-10-28 14:52:07 +01:00
Matej Bačo c20e580a9e Fix missing params in VCS comment flow 2024-10-28 14:45:18 +01:00
Matej Bačo 9b4de5d7bf Fix comments 2024-10-28 14:39:12 +01:00
Matej BačoandGitHub 7c9f396b40 Merge pull request #8883 from appwrite/feat-sites-logs-styled
Feat: Styled&timestamped logs
2024-10-28 14:35:30 +01:00
Matej Bačo 31b9f2b4f9 Fix comments 2024-10-28 14:19:44 +01:00
Khushboo Verma 6ff15f9b53 WIP: GitHub Comments for Sites 2024-10-28 14:00:23 +01:00
Matej BačoandGitHub 1ebd6c252c Merge branch 'feat-sites' into feat-sites-logs-styled 2024-10-28 12:27:06 +01:00
Matej BačoandGitHub 8424351d49 Merge pull request #8882 from appwrite/fix-sites-logs-realtime
Fix: sites deployment logs realtime
2024-10-28 12:26:54 +01:00
Matej Bačo 0c4e597819 Implemented styled and timestamped logs, fix cosistency 2024-10-28 12:22:34 +01:00
Matej BačoandGitHub d1917d1a2b Merge branch 'feat-sites' into fix-sites-logs-realtime 2024-10-28 12:08:27 +01:00
Matej Bačo bb3503f0c4 Fix sites deployment logs realtime 2024-10-28 12:00:06 +01:00
Torsten DittmannandGitHub 7c22776254 Merge pull request #8880 from appwrite/fix-deployment-domains
Fix: deployment domain incorrect
2024-10-28 11:59:21 +01:00
Matej BačoandGitHub 2294586371 Merge branch 'feat-sites' into fix-deployment-domains 2024-10-28 11:21:08 +01:00
Torsten DittmannandGitHub b7f519f86e Merge pull request #8879 from appwrite/fix-check-domain-availability
Throw exception for error
2024-10-28 11:19:04 +01:00
Matej Bačo febd5294f4 Ensure function executor is ready 2024-10-28 11:18:15 +01:00
Matej Bačo 690a23fe89 Fix deployments showing wrong domains 2024-10-28 11:17:44 +01:00
Khushboo Verma 39c1a88dae Throw exception for error 2024-10-28 10:55:58 +01:00
Khushboo VermaandGitHub d0808e0c1a Merge pull request #8878 from appwrite/fix-sites-notice
Fix: unwanted notice
2024-10-27 22:11:50 +01:00
Matej Bačo 34fd22e4e9 Fix unwanted object instead of array 2024-10-27 21:49:44 +01:00
Matej Bačo d4fb0d37c2 Fix notice 2024-10-27 21:44:59 +01:00
Matej BačoandGitHub fd02ca00f0 Merge pull request #8877 from appwrite/feat-preview-deployments
Feat: Implement preview deployments
2024-10-27 21:25:27 +01:00
Matej Bačo 8a53d02d0c Remove leftover 2024-10-27 21:25:12 +01:00
Matej Bačo 58ee53876b Implement preview deployments 2024-10-27 21:10:53 +01:00
Matej BačoandGitHub 853b730def Merge pull request #8875 from appwrite/chore-add-build-runtime
Add build and serve runtime to updateSite
2024-10-27 19:17:13 +01:00
Khushboo Verma be5fdbfd4f Add build and serve runtime to updateSite 2024-10-27 18:54:20 +01:00
Khushboo VermaandGitHub e6d123b5e8 Merge pull request #8873 from appwrite/chore-rename-common-vars-to-compute
Use compute vars for functions and sites
2024-10-27 18:35:27 +01:00
Khushboo Verma d8a844a2f9 Fix functions tests 2024-10-27 18:14:47 +01:00
Khushboo Verma dd87cdbebf Fix remaining vars 2024-10-27 18:04:40 +01:00
Khushboo Verma 4c1881324e Use compute vars for functions and sites 2024-10-27 17:22:45 +01:00
Matej BačoandGitHub bd27a36d16 Merge pull request #8872 from appwrite/fix-site-leftovers
Fix: leftover structure
2024-10-27 16:58:12 +01:00
Matej Bačo 2f999ba3db Fix crashing containers 2024-10-27 16:34:49 +01:00
Matej Bačo d8ec390cd6 Merge branch 'feat-sites' into fix-site-leftovers 2024-10-27 16:22:53 +01:00
Matej Bačo 7a0e7bfb95 Add runtimes to templates 2024-10-27 16:15:49 +01:00
Khushboo VermaandGitHub da7ae6b953 Merge pull request #8863 from appwrite/feat-sites-endpoints
Add timeout and add sites scopes
2024-10-27 16:15:00 +01:00
Khushboo Verma 2dead545f0 Resolve PR comments 2024-10-27 15:51:17 +01:00
Matej Bačo 9c566ec17c Merge branch 'feat-sites' into fix-site-leftovers 2024-10-27 15:49:53 +01:00
Matej Bačo 385fe303cc Fix leftover fields and attributes 2024-10-27 15:48:39 +01:00
Khushboo Verma 81e3709d25 Remove scopes from updateSite endpoint 2024-10-27 15:48:06 +01:00
Khushboo Verma 7f17efcdd8 Resolve merge conflicts 2024-10-27 15:43:52 +01:00
Khushboo VermaandGitHub a566ac1078 Merge pull request #8865 from appwrite/feat-check-domain-availability
Add custom domain param in create site endpoint
2024-10-27 15:38:14 +01:00
Khushboo Verma 44e76b4eaa Add a todo 2024-10-27 15:35:18 +01:00
Khushboo Verma e7e1cfa12e Update desc 2024-10-27 15:32:29 +01:00
Khushboo Verma 77a70cad71 Add endpoint to check subdomain availability 2024-10-27 15:31:00 +01:00
Khushboo Verma 0c2db53ee8 Address PR Comments 2024-10-27 14:11:53 +01:00
Khushboo Verma 83807ed247 Fix projects tests 2024-10-27 12:56:56 +01:00
Khushboo Verma 302a135e5a Fix health tests 2024-10-27 11:52:22 +01:00
Khushboo Verma 6b2160f388 Fix vcs deployments 2024-10-27 11:33:56 +01:00
Khushboo Verma 86a68c50bc Rename subdomain 2024-10-27 11:32:43 +01:00
Khushboo Verma e2e7d6578c Resolve merge conflicts 2024-10-27 11:30:17 +01:00
Matej BačoandGitHub a171e17666 Merge pull request #8860 from appwrite/feat-sites-static
Feat: Static sites
2024-10-26 21:26:48 +02:00
Matej Bačo d8610e0f2a Upgrade executor to fix tests 2024-10-26 18:57:37 +00:00
Matej Bačo 93222bf3f9 Fix response format; formatting 2024-10-26 20:47:43 +02:00
Matej Bačo ea6765c68a Support static sites 2024-10-26 18:43:30 +02:00
Khushboo Verma 6ac81dea19 Check if subdomain exists before creating site 2024-10-26 18:34:58 +02:00
Khushboo Verma e4dd9bc9f9 Use custom domain in create site endpoint 2024-10-26 17:07:15 +02:00
Khushboo Verma 03d4d4c8fa Add build env vars for sites 2024-10-26 12:29:42 +02:00
Khushboo Verma fcc51d3352 Add sites build timeout env var 2024-10-26 11:14:55 +02:00
Khushboo Verma 08630cd686 Add timeout and add sites scopes 2024-10-26 11:01:14 +02:00
Matej Bačo 9295a4e7ce Update depenrencies 2024-10-25 19:25:51 +02:00
Matej BačoandGitHub 826a1a02a2 Merge pull request #8844 from appwrite/feat-site-endpointsa
Add new endpoints in HTTP structure
2024-10-25 18:46:11 +02:00
Khushboo Verma 4ed08cefa7 Fix getTemplate endpoint 2024-10-25 18:04:32 +02:00
Khushboo Verma 1a33a0c4d1 Fix range and frameworks 2024-10-25 16:23:29 +02:00
Khushboo Verma 4d3d710211 Add missing group to templates API 2024-10-25 16:05:45 +02:00
Khushboo Verma ac93e70dd2 Update listframeworks endpoint 2024-10-25 15:56:28 +02:00
Khushboo Verma dd3ffbb391 Add getTemplate endpoint for sites 2024-10-25 14:55:09 +02:00
Khushboo Verma 9d1d101586 Update VCS endpoin to work for both functions and sites 2024-10-25 14:41:14 +02:00
Khushboo VermaandGitHub 32da7b8fe2 Merge pull request #8852 from appwrite/fix-sites-commands-and-hardcoded
fix: commands and todos
2024-10-25 11:59:02 +02:00
Torsten Dittmann 41484113a0 chore: add comments 2024-10-25 10:55:31 +02:00
Torsten Dittmann 5d6a8be66d fix: function command 2024-10-24 19:43:12 +02:00
Torsten Dittmann aba3a31663 fix: deployment/deploymentId 2024-10-24 19:28:20 +02:00
Torsten Dittmann 8950f71b0a revert: comments 2024-10-24 19:24:24 +02:00
Torsten Dittmann 54d3668693 fix: todos for sites 2024-10-24 19:20:00 +02:00
Khushboo Verma b16169f867 Add secret to templateVariable model 2024-10-24 18:09:43 +02:00
Khushboo Verma bbd589f6a8 Add download build endpoint to sites 2024-10-24 18:02:26 +02:00
Khushboo Verma 765d8241f2 Add secret param to site variables 2024-10-24 16:32:53 +02:00
Khushboo Verma 8e041ddeb6 Merge branch 'feat-sites' into feat-site-endpointsa 2024-10-24 15:24:37 +02:00
Khushboo Verma a4a7fe0c48 Merge branch '1.7.x' into feat-sites 2024-10-24 15:24:25 +02:00
Khushboo Verma a247fc3b48 Merge branch 'feat-site-endpointsa' of github.com:appwrite/appwrite into feat-site-endpointsa 2024-10-24 15:22:16 +02:00
Khushboo Verma d876085f6d Add usage endpoints 2024-10-24 15:21:40 +02:00
Torsten DittmannandGitHub bba9c3d57a Merge pull request #8831 from appwrite/feat-add-secret-environment-vars
Add secret attribute to variables
2024-10-24 12:53:10 +02:00
Khushboo VermaandGitHub 944e971124 Merge pull request #8849 from appwrite/feat-site-static-runtime
feat: static runtime
2024-10-24 12:38:57 +02:00
Torsten Dittmann e512ab1816 Merge branch 'feat-site-static-runtime' of https://github.com/appwrite/appwrite into feat-site-static-runtime 2024-10-24 12:19:19 +02:00
Torsten Dittmann 83b5aecbfd chore: add todo comment 2024-10-24 12:19:10 +02:00
Khushboo Verma 2f9d00fc07 Update the description for secret var 2024-10-24 12:08:33 +02:00
Khushboo VermaandGitHub 23b57692ec Merge branch 'feat-site-endpointsa' into feat-site-static-runtime 2024-10-24 12:06:02 +02:00
Khushboo Verma 8bda7f1e1e Add listSiteTemplates endpoint and response models 2024-10-24 11:47:09 +02:00
Khushboo Verma 12bddc3b1f Change secret type to bool 2024-10-24 10:59:47 +02:00
Khushboo Verma 8f5fa84996 Add variable endpoints for sites 2024-10-24 10:49:43 +02:00
Khushboo VermaandGitHub 3af34f078c Merge branch 'feat-site-endpointsa' into feat-site-static-runtime 2024-10-23 18:37:45 +02:00
Torsten Dittmann 57e596fea2 feat: static runtime for site 2024-10-23 18:36:26 +02:00
Khushboo Verma 9793cf4ece Add all deployment endpoints for sites 2024-10-23 17:07:28 +02:00
Khushboo Verma a4bdc23aef Add more endpoints and models for sites 2024-10-23 12:19:07 +02:00
Khushboo Verma 4240089d41 Add create deployment endpoint 2024-10-22 19:45:49 +02:00
Khushboo VermaandGitHub 09ebfac307 Merge pull request #8843 from appwrite/fix-builds-worker
fix: builds worker new structure
2024-10-22 18:57:37 +02:00
Torsten Dittmann 89b6291488 fix: khusboo review comments 2024-10-22 18:56:34 +02:00
Torsten Dittmann 1434b6bbff fix: builds worker new structure 2024-10-22 18:03:40 +02:00
Torsten DittmannandGitHub de164ff936 Merge pull request #8842 from appwrite/fix-workers
Fix workers
2024-10-22 17:37:01 +02:00
Torsten Dittmann a8e2fb1ee5 Merge branch 'feat-sites' of https://github.com/appwrite/appwrite into fix-workers 2024-10-22 17:35:54 +02:00
Torsten Dittmann 7da8b44c63 chore: run formatter 2024-10-22 17:35:24 +02:00
Torsten Dittmann 8f0c1a4224 fix: gitignore 2024-10-22 17:34:22 +02:00
Torsten Dittmann c57cb3d2d9 fix: workers 2024-10-22 17:33:33 +02:00
Torsten DittmannandGitHub 5172189e36 Merge pull request #8839 from appwrite/feat-add-sites-endpoints
Move functions endpoints to modules
2024-10-22 17:31:43 +02:00
Khushboo Verma 6c6723e181 Refactor callback 2024-10-22 17:10:50 +02:00
Khushboo Verma 5b0a05b4b3 Create site endpoint working 2024-10-22 17:01:38 +02:00
Khushboo Verma 87cbd8fbf3 Move create function, create deployment to modules 2024-10-22 13:00:10 +02:00
Torsten DittmannandGitHub 9060250806 Merge pull request #8832 from appwrite/feat-add-sites-collection
Add new collection
2024-10-21 19:08:34 +02:00
Khushboo Verma bc63c3b383 Add sites collection 2024-10-21 19:01:37 +02:00
Khushboo Verma a503803725 Add secret attribute to variables 2024-10-21 16:33:57 +02:00
274 changed files with 36946 additions and 8075 deletions
+14 -11
View File
@@ -18,11 +18,12 @@ _APP_SYSTEM_RESPONSE_FORMAT=
_APP_OPTIONS_ABUSE=disabled
_APP_OPTIONS_ROUTER_PROTECTION=disabled
_APP_OPTIONS_FORCE_HTTPS=disabled
_APP_OPTIONS_FUNCTIONS_FORCE_HTTPS=disabled
_APP_OPTIONS_COMPUTE_FORCE_HTTPS=disabled
_APP_OPENSSL_KEY_V1=your-secret-key
_APP_DOMAIN=traefik
_APP_DOMAIN_FUNCTIONS=functions.localhost
_APP_DOMAIN_TARGET=localhost
_APP_DOMAIN_SITES=sites.localhost
_APP_DOMAIN_TARGET=test.appwrite.io
_APP_RULES_FORMAT=md5
_APP_REDIS_HOST=redis
_APP_REDIS_PORT=6379
@@ -69,17 +70,19 @@ _APP_SMS_FROM=+123456789
_APP_SMS_PROJECTS_DENY_LIST=
_APP_STORAGE_LIMIT=30000000
_APP_STORAGE_PREVIEW_LIMIT=20000000
_APP_FUNCTIONS_SIZE_LIMIT=30000000
_APP_FUNCTIONS_TIMEOUT=900
_APP_FUNCTIONS_BUILD_TIMEOUT=900
_APP_FUNCTIONS_CPUS=8
_APP_FUNCTIONS_MEMORY=8192
_APP_FUNCTIONS_INACTIVE_THRESHOLD=600
_APP_FUNCTIONS_MAINTENANCE_INTERVAL=600
_APP_FUNCTIONS_RUNTIMES_NETWORK=runtimes
_APP_COMPUTE_SIZE_LIMIT=30000000
_APP_COMPUTE_TIMEOUT=900
_APP_COMPUTE_BUILD_TIMEOUT=900
_APP_COMPUTE_CPUS=8
_APP_COMPUTE_MEMORY=8192
_APP_COMPUTE_INACTIVE_THRESHOLD=600
_APP_COMPUTE_MAINTENANCE_INTERVAL=600
_APP_COMPUTE_RUNTIMES_NETWORK=runtimes
_APP_EXECUTOR_SECRET=your-secret-key
_APP_EXECUTOR_HOST=http://proxy/v1
_APP_EXECUTOR_HOST=http://exc1/v1
_APP_FUNCTIONS_RUNTIMES=php-8.0,node-18.0,python-3.9,ruby-3.1
_APP_SITES_RUNTIMES=static-1,node-22,flutter-3.29
_APP_SITES_FRAMEWORKS=sveltekit,nextjs,nuxt,astro,remix,flutter,other,react,vue,analog,angular,vite
_APP_MAINTENANCE_INTERVAL=86400
_APP_MAINTENANCE_DELAY=
_APP_MAINTENANCE_RETENTION_CACHE=2592000
+16
View File
@@ -0,0 +1,16 @@
name: "Static code analysis"
on: [pull_request]
jobs:
lint:
name: CodeQL
runs-on: ubuntu-latest
steps:
- name: Check out the repo
uses: actions/checkout@v2
- name: Run CodeQL
run: |
docker run --rm -v $PWD:/app composer:2.6 sh -c \
"composer install --profile --ignore-platform-reqs && composer check"
+24 -1
View File
@@ -90,6 +90,9 @@ jobs:
docker compose up -d
sleep 10
- name: Logs
run: docker compose logs appwrite
- name: Doctor
run: docker compose exec -T appwrite doctor
@@ -142,6 +145,8 @@ jobs:
Locale,
Projects,
Realtime,
Sites,
Proxy,
Storage,
Teams,
Users,
@@ -167,6 +172,14 @@ jobs:
docker compose up -d
sleep 30
- name: Wait for Open Runtimes
timeout-minutes: 3
run: |
while ! docker compose logs openruntimes-executor | grep -q "Executor is ready."; do
echo "Waiting for Executor to come online"
sleep 1
done
- name: Run ${{ matrix.service }} tests with Project table mode
run: |
echo "Using project tables"
@@ -199,6 +212,8 @@ jobs:
Locale,
Projects,
Realtime,
Sites,
Proxy,
Storage,
Teams,
Users,
@@ -229,6 +244,14 @@ jobs:
docker compose up -d
sleep 30
- name: Wait for Open Runtimes
timeout-minutes: 3
run: |
while ! docker compose logs openruntimes-executor | grep -q "Executor is ready."; do
echo "Waiting for Executor to come online"
sleep 1
done
- name: Run ${{ matrix.service }} tests with ${{ matrix.tables-mode }} table mode
run: |
if [ "${{ matrix.tables-mode }}" == "Shared V1" ]; then
@@ -240,7 +263,7 @@ jobs:
export _APP_DATABASE_SHARED_TABLES=database_db_main
export _APP_DATABASE_SHARED_TABLES_V1=
fi
docker compose exec -T \
-e _APP_DATABASE_SHARED_TABLES \
-e _APP_DATABASE_SHARED_TABLES_V1 \
+1
View File
@@ -3,6 +3,7 @@
/node_modules/
/tests/resources/storage/
/tests/resources/functions/**/code.tar.gz
/tests/resources/sites/**/code.tar.gz
/app/sdks/*
/.idea/
!/.idea/workspace.xml
+22
View File
@@ -163,6 +163,28 @@ Other containes should be named the same as their service, for example `redis` s
- [Encryption](https://medium.com/searchencrypt/what-is-encryption-how-does-it-work-e8f20e340537#:~:text=Encryption%20is%20a%20process%20that,%2C%20or%20decrypt%2C%20the%20information.)
- [Hashing](https://searchsqlserver.techtarget.com/definition/hashing#:~:text=Hashing%20is%20the%20transformation%20of,it%20using%20the%20original%20value.)
## Modules
As Appwrite grows, we noticed approach of having all service endpoints in `app/controllers/api/[service].php` is not maintainable. Not only it creates massive files, it also doesnt contain all product's features such as workers or tasks. While there might still be some occurances of those controller files, we avoid it in all new development, and gradually migrate existing controllers to **HTTP modules**.
### HTTP Endpoints
Every endpoint file follows below structure, making it consistent with HTTP REST endpoint path:
```
src/Appwrite/Platform/Modules/[service]/Http/[resource]/[action].php
```
Tips and tricks:
1. If endpoint doesn't have resource, use service name as resource name too
> Example: `Modules/Sites/Http/Sites/Get.php`
2. If there are multiple resources, use then all in folder structure
> Example: `Modules/Sites/Http/Deployments/Builds/Create.php`
3. Action can only be `Get`, `Create`, `Update`, `Delete` or `XList`
## Architecture
Appwrite's current structure is a combination of both [Monolithic](https://en.wikipedia.org/wiki/Monolithic_application) and [Microservice](https://en.wikipedia.org/wiki/Microservices) architectures.
+1
View File
@@ -68,6 +68,7 @@ RUN chmod +x /usr/local/bin/doctor && \
chmod +x /usr/local/bin/sdks && \
chmod +x /usr/local/bin/specs && \
chmod +x /usr/local/bin/ssl && \
chmod +x /usr/local/bin/screenshot && \
chmod +x /usr/local/bin/test && \
chmod +x /usr/local/bin/upgrade && \
chmod +x /usr/local/bin/vars && \
+1 -1
View File
@@ -26,7 +26,7 @@ use Utopia\Registry\Registry;
use Utopia\System\System;
// overwriting runtimes to be architectur agnostic for CLI
Config::setParam('runtimes', (new Runtimes('v4'))->getAll(supported: false));
Config::setParam('runtimes', (new Runtimes('v5'))->getAll(supported: false));
// require controllers after overwriting runtimes
require_once __DIR__ . '/controllers/general.php';
+144 -14
View File
@@ -1013,10 +1013,10 @@ return [
'filters' => [],
],
[
'$id' => ID::custom('resourceType'),
'$id' => ID::custom('type'), // 'api', 'redirect', 'deployment' (site or function)
'type' => Database::VAR_STRING,
'format' => '',
'size' => 100,
'size' => 32,
'signed' => true,
'required' => true,
'default' => null,
@@ -1024,10 +1024,32 @@ return [
'filters' => [],
],
[
'$id' => ID::custom('resourceInternalId'),
'$id' => ID::custom('trigger'), // 'manual', 'deployment', '' (empty)
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'size' => 32,
'signed' => true,
'required' => false,
'default' => '',
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('redirectUrl'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 2048,
'signed' => true,
'required' => false,
'default' => '',
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('redirectStatusCode'),
'type' => Database::VAR_INTEGER,
'format' => '',
'size' => 0,
'signed' => true,
'required' => false,
'default' => null,
@@ -1035,13 +1057,68 @@ return [
'filters' => [],
],
[
'$id' => ID::custom('resourceId'),
'$id' => ID::custom('deploymentResourceType'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 32,
'signed' => true,
'required' => false,
'default' => '',
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('deploymentId'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => null,
'default' => '',
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('deploymentInternalId'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => '',
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('deploymentResourceId'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => '',
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('deploymentResourceInternalId'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => '',
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('deploymentVcsProviderBranch'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => '',
'array' => false,
'filters' => [],
],
@@ -1066,9 +1143,27 @@ return [
'default' => null,
'array' => false,
'filters' => [],
]
],
[
'$id' => ID::custom('search'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 16384,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
],
'indexes' => [
[
'$id' => ID::custom('_key_search'),
'type' => Database::INDEX_FULLTEXT,
'attributes' => ['search'],
'lengths' => [],
'orders' => [],
],
[
'$id' => ID::custom('_key_domain'),
'type' => Database::INDEX_UNIQUE,
@@ -1091,24 +1186,59 @@ return [
'orders' => [Database::ORDER_ASC],
],
[
'$id' => '_key_resourceInternalId',
'$id' => '_key_type',
'type' => Database::INDEX_KEY,
'attributes' => ['resourceInternalId'],
'attributes' => ['type'],
'lengths' => [32],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => '_key_trigger',
'type' => Database::INDEX_KEY,
'attributes' => ['trigger'],
'lengths' => [32],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => '_key_deploymentResourceType',
'type' => Database::INDEX_KEY,
'attributes' => ['deploymentResourceType'],
'lengths' => [32],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => '_key_deploymentResourceId',
'type' => Database::INDEX_KEY,
'attributes' => ['deploymentResourceId'],
'lengths' => [Database::LENGTH_KEY],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => '_key_resourceId',
'$id' => '_key_deploymentResourceInternalId',
'type' => Database::INDEX_KEY,
'attributes' => ['resourceId'],
'attributes' => ['deploymentResourceInternalId'],
'lengths' => [Database::LENGTH_KEY],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => '_key_resourceType',
'$id' => '_key_deploymentId',
'type' => Database::INDEX_KEY,
'attributes' => ['resourceType'],
'lengths' => [],
'attributes' => ['deploymentId'],
'lengths' => [Database::LENGTH_KEY],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => '_key_deploymentInternalId',
'type' => Database::INDEX_KEY,
'attributes' => ['deploymentInternalId'],
'lengths' => [Database::LENGTH_KEY],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => '_key_deploymentVcsProviderBranch',
'type' => Database::INDEX_KEY,
'attributes' => ['deploymentVcsProviderBranch'],
'lengths' => [Database::LENGTH_KEY],
'orders' => [Database::ORDER_ASC],
],
],
+527 -207
View File
@@ -569,7 +569,7 @@ return [
'filters' => [],
],
[
'$id' => ID::custom('deployment'),
'$id' => ID::custom('deploymentId'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
@@ -674,7 +674,7 @@ return [
'size' => 8,
'signed' => true,
'required' => false,
'default' => 'v4',
'default' => 'v5',
'array' => false,
'filters' => [],
],
@@ -708,7 +708,7 @@ return [
'size' => 128,
'signed' => false,
'required' => false,
'default' => APP_FUNCTION_SPECIFICATION_DEFAULT,
'default' => APP_COMPUTE_SPECIFICATION_DEFAULT,
'filters' => [],
],
[
@@ -788,15 +788,372 @@ return [
'orders' => [Database::ORDER_ASC],
],
[
'$id' => ID::custom('_key_deployment'),
'$id' => ID::custom('_key_deploymentId'),
'type' => Database::INDEX_KEY,
'attributes' => ['deployment'],
'attributes' => ['deploymentId'],
'lengths' => [],
'orders' => [Database::ORDER_ASC],
]
],
],
'sites' => [
'$collection' => ID::custom(Database::METADATA),
'$id' => ID::custom('sites'),
'name' => 'Sites',
'attributes' => [
[
'$id' => ID::custom('name'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 2048,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('enabled'),
'type' => Database::VAR_BOOLEAN,
'signed' => true,
'size' => 0,
'format' => '',
'filters' => [],
'required' => true,
'array' => false,
],
[
'$id' => ID::custom('live'),
'type' => Database::VAR_BOOLEAN,
'signed' => true,
'size' => 0,
'format' => '',
'filters' => [],
'required' => true,
'array' => false,
],
[
'$id' => ID::custom('installationId'),
'type' => Database::VAR_STRING,
'signed' => true,
'size' => Database::LENGTH_KEY,
'format' => '',
'filters' => [],
'required' => false,
'array' => false,
],
[
'$id' => ID::custom('installationInternalId'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('providerRepositoryId'),
'type' => Database::VAR_STRING,
'signed' => true,
'size' => Database::LENGTH_KEY,
'format' => '',
'filters' => [],
'required' => false,
'array' => false,
],
[
'$id' => ID::custom('repositoryId'),
'type' => Database::VAR_STRING,
'signed' => true,
'size' => Database::LENGTH_KEY,
'format' => '',
'filters' => [],
'required' => false,
'array' => false,
],
[
'$id' => ID::custom('repositoryInternalId'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('providerBranch'),
'type' => Database::VAR_STRING,
'signed' => true,
'size' => Database::LENGTH_KEY,
'format' => '',
'filters' => [],
'required' => false,
'array' => false,
],
[
'$id' => ID::custom('providerRootDirectory'),
'type' => Database::VAR_STRING,
'signed' => true,
'size' => Database::LENGTH_KEY,
'format' => '',
'filters' => [],
'required' => false,
'array' => false,
],
[
'$id' => ID::custom('providerSilentMode'),
'type' => Database::VAR_BOOLEAN,
'signed' => true,
'size' => 0,
'format' => '',
'filters' => [],
'required' => false,
'default' => false,
'array' => false,
],
// [
// '$id' => ID::custom('logging'),
// 'type' => Database::VAR_BOOLEAN,
// 'signed' => true,
// 'size' => 0,
// 'format' => '',
// 'filters' => [],
// 'required' => true,
// 'array' => false,
// ],
[
'$id' => ID::custom('framework'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 2048,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'array' => false,
'$id' => ID::custom('outputDirectory'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 16384,
'signed' => true,
'required' => false,
'default' => null,
'filters' => [],
],
[
'array' => false,
'$id' => ID::custom('buildCommand'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 16384,
'signed' => true,
'required' => false,
'default' => null,
'filters' => [],
],
[
'array' => false,
'$id' => ID::custom('installCommand'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 16384,
'signed' => true,
'required' => false,
'default' => null,
'filters' => [],
],
[
'$id' => ID::custom('fallbackFile'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('deploymentInternalId'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('deploymentId'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('vars'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 16384,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => ['subQueryVariables'],
],
[
'$id' => ID::custom('varsProject'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 16384,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => ['subQueryProjectVariables'],
],
[
'$id' => ID::custom('timeout'),
'type' => Database::VAR_INTEGER,
'format' => '',
'size' => 0,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('search'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 16384,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'array' => false,
'$id' => ID::custom('specification'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 128,
'signed' => false,
'required' => false,
'default' => APP_COMPUTE_SPECIFICATION_DEFAULT,
'filters' => [],
],
[
'$id' => ID::custom('buildRuntime'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 2048,
'signed' => true,
'required' => true,
'default' => '',
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('adapter'), // ssr or static
'type' => Database::VAR_STRING,
'format' => '',
'size' => 128,
'signed' => true,
'required' => false,
'default' => '',
'array' => false,
'filters' => [],
],
],
'indexes' => [
[
'$id' => ID::custom('_key_search'),
'type' => Database::INDEX_FULLTEXT,
'attributes' => ['search'],
'lengths' => [],
'orders' => [],
],
[
'$id' => ID::custom('_key_name'),
'type' => Database::INDEX_KEY,
'attributes' => ['name'],
'lengths' => [256],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => ID::custom('_key_enabled'),
'type' => Database::INDEX_KEY,
'attributes' => ['enabled'],
'lengths' => [],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => ID::custom('_key_installationId'),
'type' => Database::INDEX_KEY,
'attributes' => ['installationId'],
'lengths' => [Database::LENGTH_KEY],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => ID::custom('_key_installationInternalId'),
'type' => Database::INDEX_KEY,
'attributes' => ['installationInternalId'],
'lengths' => [Database::LENGTH_KEY],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => ID::custom('_key_providerRepositoryId'),
'type' => Database::INDEX_KEY,
'attributes' => ['providerRepositoryId'],
'lengths' => [Database::LENGTH_KEY],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => ID::custom('_key_repositoryId'),
'type' => Database::INDEX_KEY,
'attributes' => ['repositoryId'],
'lengths' => [Database::LENGTH_KEY],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => ID::custom('_key_repositoryInternalId'),
'type' => Database::INDEX_KEY,
'attributes' => ['repositoryInternalId'],
'lengths' => [Database::LENGTH_KEY],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => ID::custom('_key_framework'),
'type' => Database::INDEX_KEY,
'attributes' => ['framework'],
'lengths' => [64],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => ID::custom('_key_deploymentId'),
'type' => Database::INDEX_KEY,
'attributes' => ['deploymentId'],
'lengths' => [],
'orders' => [Database::ORDER_ASC],
]
],
],
'deployments' => [
'$collection' => ID::custom(Database::METADATA),
'$id' => ID::custom('deployments'),
@@ -835,28 +1192,6 @@ return [
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('buildInternalId'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('buildId'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'array' => false,
'$id' => ID::custom('entrypoint'),
@@ -870,17 +1205,28 @@ return [
],
[
'array' => false,
'$id' => ID::custom('commands'),
'$id' => ID::custom('buildCommands'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 2048,
'size' => 16384,
'signed' => true,
'required' => false,
'default' => null,
'filters' => [],
],
[
'$id' => ID::custom('path'),
'array' => false,
'$id' => ID::custom('buildOutput'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 16384,
'signed' => true,
'required' => false,
'default' => null,
'filters' => [],
],
[
'$id' => ID::custom('sourcePath'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 2048,
@@ -894,7 +1240,7 @@ return [
'$id' => ID::custom('type'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 2048,
'size' => 32,
'signed' => true,
'required' => true,
'default' => null,
@@ -1073,7 +1419,7 @@ return [
'array' => false,
],
[
'$id' => ID::custom('size'),
'$id' => ID::custom('sourceSize'),
'type' => Database::VAR_INTEGER,
'format' => '',
'size' => 0,
@@ -1084,7 +1430,7 @@ return [
'filters' => [],
],
[
'$id' => ID::custom('metadata'),
'$id' => ID::custom('sourceMetadata'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 16384, // https://tools.ietf.org/html/rfc4288#section-4.2
@@ -1095,7 +1441,7 @@ return [
'filters' => ['json'],
],
[
'$id' => ID::custom('chunksTotal'),
'$id' => ID::custom('sourceChunksTotal'),
'type' => Database::VAR_INTEGER,
'format' => '',
'size' => 0,
@@ -1106,7 +1452,7 @@ return [
'filters' => [],
],
[
'$id' => ID::custom('chunksUploaded'),
'$id' => ID::custom('sourceChunksUploaded'),
'type' => Database::VAR_INTEGER,
'format' => '',
'size' => 0,
@@ -1137,6 +1483,105 @@ return [
'default' => false,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('screenshotLight'), // File ID from 'screenshots' Console bucket
'type' => Database::VAR_STRING,
'format' => '',
'size' => 32,
'signed' => false,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('screenshotDark'), // File ID from 'screenshots' Console bucket
'type' => Database::VAR_STRING,
'format' => '',
'size' => 32,
'signed' => false,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('buildStartAt'),
'type' => Database::VAR_DATETIME,
'format' => '',
'size' => 0,
'signed' => false,
'required' => false,
'default' => null,
'array' => false,
'filters' => ['datetime'],
],
[
'$id' => ID::custom('buildEndAt'),
'type' => Database::VAR_DATETIME,
'format' => '',
'size' => 0,
'signed' => false,
'required' => false,
'default' => null,
'array' => false,
'filters' => ['datetime'],
],
[
'$id' => ID::custom('buildDuration'),
'type' => Database::VAR_INTEGER,
'format' => '',
'size' => 0,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('buildSize'),
'type' => Database::VAR_INTEGER,
'format' => '',
'size' => 0,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('status'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 16,
'signed' => true,
'required' => true,
'default' => 'waiting',
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('buildPath'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => '',
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('buildLogs'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 1000000,
'signed' => true,
'required' => false,
'default' => '',
'array' => false,
'filters' => [],
]
],
'indexes' => [
@@ -1162,16 +1607,23 @@ return [
'orders' => [],
],
[
'$id' => ID::custom('_key_size'),
'$id' => ID::custom('_key_sourceSize'),
'type' => Database::INDEX_KEY,
'attributes' => ['size'],
'attributes' => ['sourceSize'],
'lengths' => [],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => ID::custom('_key_buildId'),
'$id' => ID::custom('_key_buildSize'),
'type' => Database::INDEX_KEY,
'attributes' => ['buildId'],
'attributes' => ['buildSize'],
'lengths' => [],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => ID::custom('_key_buildDuration'),
'type' => Database::INDEX_KEY,
'attributes' => ['buildDuration'],
'lengths' => [],
'orders' => [Database::ORDER_ASC],
],
@@ -1182,155 +1634,19 @@ return [
'lengths' => [],
'orders' => [Database::ORDER_ASC],
],
],
],
'builds' => [
'$collection' => ID::custom(Database::METADATA),
'$id' => ID::custom('builds'),
'name' => 'Builds',
'attributes' => [
[
'$id' => ID::custom('startTime'),
'type' => Database::VAR_DATETIME,
'format' => '',
'size' => 0,
'signed' => false,
'required' => false,
'default' => null,
'array' => false,
'filters' => ['datetime'],
],
[
'$id' => ID::custom('endTime'),
'type' => Database::VAR_DATETIME,
'format' => '',
'size' => 0,
'signed' => false,
'required' => false,
'default' => null,
'array' => false,
'filters' => ['datetime'],
],
[
'$id' => ID::custom('duration'),
'type' => Database::VAR_INTEGER,
'format' => '',
'size' => 0,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('size'),
'type' => Database::VAR_INTEGER,
'format' => '',
'size' => 0,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('deploymentInternalId'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('deploymentId'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('runtime'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 2048,
'signed' => true,
'required' => true,
'default' => '',
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('status'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 256,
'signed' => true,
'required' => true,
'default' => 'processing',
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('path'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 2048,
'signed' => true,
'required' => false,
'default' => '',
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('logs'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 1000000,
'signed' => true,
'required' => false,
'default' => '',
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('sourceType'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 2048,
'signed' => true,
'required' => true,
'default' => 'local',
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('source'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 2048,
'signed' => true,
'required' => true,
'default' => '',
'array' => false,
'filters' => [],
]
],
'indexes' => [
[
'$id' => ID::custom('_key_deployment'),
'$id' => ID::custom('_key_type'),
'type' => Database::INDEX_KEY,
'attributes' => ['deploymentId'],
'lengths' => [Database::LENGTH_KEY],
'attributes' => ['type'],
'lengths' => [32],
'orders' => [Database::ORDER_ASC],
]
], [
'$id' => ID::custom('_key_status'),
'type' => Database::INDEX_KEY,
'attributes' => ['status'],
'lengths' => [16],
'orders' => [Database::ORDER_ASC],
],
],
],
@@ -1340,7 +1656,7 @@ return [
'name' => 'Executions',
'attributes' => [
[
'$id' => ID::custom('functionInternalId'),
'$id' => ID::custom('resourceInternalId'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
@@ -1351,7 +1667,18 @@ return [
'filters' => [],
],
[
'$id' => ID::custom('functionId'),
'$id' => ID::custom('resourceId'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('resourceType'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
@@ -1493,17 +1820,6 @@ return [
'array' => false,
'filters' => ['json'],
],
[
'$id' => ID::custom('search'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 16384,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('scheduledAt'),
'type' => Database::VAR_DATETIME,
@@ -1540,19 +1856,12 @@ return [
],
'indexes' => [
[
'$id' => ID::custom('_key_function'),
'$id' => ID::custom('_key_resource'),
'type' => Database::INDEX_KEY,
'attributes' => ['functionId'],
'attributes' => ['resourceInternalId', 'resourceType', 'resourceId'],
'lengths' => [Database::LENGTH_KEY],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => ID::custom('_fulltext_search'),
'type' => Database::INDEX_FULLTEXT,
'attributes' => ['search'],
'lengths' => [],
'orders' => [],
],
[
'$id' => ID::custom('_key_trigger'),
'type' => Database::INDEX_KEY,
@@ -1665,6 +1974,17 @@ return [
'array' => false,
'filters' => ['encrypt']
],
[
'$id' => ID::custom('secret'),
'type' => Database::VAR_BOOLEAN,
'format' => '',
'size' => 0,
'signed' => true,
'required' => false,
'default' => false,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('search'),
'type' => Database::VAR_STRING,
+42 -1
View File
@@ -375,6 +375,13 @@ return [
'code' => 409,
],
/** Console */
Exception::RESOURCE_ALREADY_EXISTS => [
'name' => Exception::RESOURCE_ALREADY_EXISTS,
'description' => 'Resource with the requested ID already exists. Please choose a different ID and try again.',
'code' => 409,
],
/** Membership */
Exception::MEMBERSHIP_NOT_FOUND => [
'name' => Exception::MEMBERSHIP_NOT_FOUND,
@@ -520,7 +527,7 @@ return [
'code' => 404,
],
Exception::FUNCTION_ENTRYPOINT_MISSING => [
'name' => Exception::FUNCTION_RUNTIME_UNSUPPORTED,
'name' => Exception::FUNCTION_ENTRYPOINT_MISSING,
'description' => 'Entrypoint for your Appwrite Function is missing. Please specify it when making deployment or update the entrypoint under your function\'s "Settings" > "Configuration" > "Entrypoint".',
'code' => 404,
],
@@ -534,6 +541,28 @@ return [
'description' => 'Function Template with the requested ID could not be found.',
'code' => 404,
],
Exception::FUNCTION_RUNTIME_NOT_DETECTED => [
'name' => Exception::FUNCTION_RUNTIME_NOT_DETECTED,
'description' => 'Function runtime could not be detected.',
'code' => 400,
],
/** Sites */
Exception::SITE_NOT_FOUND => [
'name' => Exception::SITE_NOT_FOUND,
'description' => 'Site with the requested ID could not be found.',
'code' => 404,
],
Exception::SITE_FRAMEWORK_UNSUPPORTED => [
'name' => Exception::SITE_FRAMEWORK_UNSUPPORTED,
'description' => 'The requested framework is either inactive or unsupported. Please check the value of the _APP_SITES_FRAMEWORKS environment variable.',
'code' => 404,
],
Exception::SITE_TEMPLATE_NOT_FOUND => [
'name' => Exception::SITE_TEMPLATE_NOT_FOUND,
'description' => 'Site Template with the requested ID could not be found.',
'code' => 404,
],
/** Builds */
Exception::BUILD_NOT_FOUND => [
@@ -577,6 +606,13 @@ return [
'code' => 400,
],
/** Logs */
Exception::LOG_NOT_FOUND => [
'name' => Exception::LOG_NOT_FOUND,
'description' => 'Log with the requested ID could not be found.',
'code' => 404,
],
/** Databases */
Exception::DATABASE_NOT_FOUND => [
'name' => Exception::DATABASE_NOT_FOUND,
@@ -844,6 +880,11 @@ return [
'description' => 'Variable with the same ID already exists in this project. Try again with a different ID.',
'code' => 409,
],
Exception::VARIABLE_CANNOT_UNSET_SECRET => [
'name' => Exception::VARIABLE_CANNOT_UNSET_SECRET,
'description' => 'Secret variables cannot be marked as non-secret. Please re-create the variable if this is your intention.',
'code' => 400,
],
Exception::GRAPHQL_NO_QUERY => [
'name' => Exception::GRAPHQL_NO_QUERY,
'description' => 'Param "query" is not optional.',
+28
View File
@@ -217,6 +217,34 @@ return [
],
]
],
'sites' => [
'$model' => Response::MODEL_SITE,
'$resource' => true,
'$description' => 'This event triggers on any sites event.',
'deployments' => [
'$model' => Response::MODEL_DEPLOYMENT,
'$resource' => true,
'$description' => 'This event triggers on any deployments event.',
'create' => [
'$description' => 'This event triggers when a deployment is created.',
],
'delete' => [
'$description' => 'This event triggers when a deployment is deleted.'
],
'update' => [
'$description' => 'This event triggers when a deployment is updated.'
],
],
'create' => [
'$description' => 'This event triggers when a site is created.'
],
'delete' => [
'$description' => 'This event triggers when a site is deleted.',
],
'update' => [
'$description' => 'This event triggers when a site is updated.',
]
],
'functions' => [
'$model' => Response::MODEL_FUNCTION,
'$resource' => true,
+266
View File
@@ -0,0 +1,266 @@
<?php
/**
* List of Appwrite Sites supported frameworks
*/
use Utopia\Config\Config;
$templateRuntimes = Config::getParam('template-runtimes');
function getVersions(array $versions, string $prefix)
{
return array_map(function ($version) use ($prefix) {
return $prefix . '-' . $version;
}, $versions);
}
return [
'analog' => [
'key' => 'analog',
'name' => 'Analog',
'buildRuntime' => 'node-22',
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
'bundleCommand' => 'sh /usr/local/server/helpers/analog/bundle.sh',
'envCommand' => 'source /usr/local/server/helpers/analog/env.sh',
'adapters' => [
'ssr' => [
'key' => 'ssr',
'buildCommand' => 'npm run build',
'installCommand' => 'npm install',
'outputDirectory' => './dist/analog',
'startCommand' => 'sh helpers/analog/server.sh',
],
'static' => [
'key' => 'static',
'buildCommand' => 'npm run build',
'installCommand' => 'npm install',
'outputDirectory' => './dist/analog/public',
'startCommand' => 'sh helpers/server.sh',
'fallbackFile' => 'index.html'
]
]
],
'angular' => [
'key' => 'angular',
'name' => 'Angular',
'buildRuntime' => 'node-22',
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
'bundleCommand' => 'sh /usr/local/server/helpers/angular/bundle.sh',
'envCommand' => 'source /usr/local/server/helpers/angular/env.sh',
'adapters' => [
'ssr' => [
'key' => 'ssr',
'buildCommand' => 'npm run build',
'installCommand' => 'npm install',
'outputDirectory' => './dist/angular',
'startCommand' => 'sh helpers/angular/server.sh',
],
'static' => [
'key' => 'static',
'buildCommand' => 'npm run build',
'installCommand' => 'npm install',
'outputDirectory' => './dist/angular/browser',
'startCommand' => 'sh helpers/server.sh',
'fallbackFile' => 'index.csr.html'
]
]
],
'nextjs' => [
'key' => 'nextjs',
'name' => 'Next.js',
'buildRuntime' => 'node-22',
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
'bundleCommand' => 'sh /usr/local/server/helpers/next-js/bundle.sh',
'envCommand' => 'source /usr/local/server/helpers/next-js/env.sh',
'adapters' => [
'ssr' => [
'key' => 'ssr',
'buildCommand' => 'npm run build',
'installCommand' => 'npm install',
'outputDirectory' => './.next',
'startCommand' => 'sh helpers/next-js/server.sh',
],
'static' => [
'key' => 'static',
'buildCommand' => 'npm run build',
'installCommand' => 'npm install',
'outputDirectory' => './out',
'startCommand' => 'sh helpers/server.sh',
]
]
],
'react' => [
'key' => 'react',
'name' => 'React',
'buildRuntime' => 'node-22',
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
'adapters' => [
'static' => [
'key' => 'static',
'buildCommand' => 'npm run build',
'installCommand' => 'npm install',
'outputDirectory' => './dist',
'startCommand' => 'sh helpers/server.sh',
'fallbackFile' => 'index.html'
]
]
],
'nuxt' => [
'key' => 'nuxt',
'name' => 'Nuxt',
'buildRuntime' => 'node-22',
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
'bundleCommand' => 'sh /usr/local/server/helpers/nuxt/bundle.sh',
'envCommand' => 'source /usr/local/server/helpers/nuxt/env.sh',
'adapters' => [
'ssr' => [
'key' => 'ssr',
'buildCommand' => 'npm run build',
'installCommand' => 'npm install',
'outputDirectory' => './.output',
'startCommand' => 'sh helpers/nuxt/server.sh',
],
'static' => [
'key' => 'static',
'buildCommand' => 'npm run generate',
'installCommand' => 'npm install',
'outputDirectory' => './output/public',
'startCommand' => 'sh helpers/server.sh',
]
]
],
'vue' => [
'key' => 'vue',
'name' => 'Vue.js',
'buildRuntime' => 'node-22',
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
'adapters' => [
'static' => [
'key' => 'static',
'buildCommand' => 'npm run build',
'installCommand' => 'npm install',
'outputDirectory' => './dist',
'startCommand' => 'sh helpers/server.sh',
'fallbackFile' => 'index.html'
]
]
],
'sveltekit' => [
'key' => 'sveltekit',
'name' => 'SvelteKit',
'buildRuntime' => 'node-22',
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
'bundleCommand' => 'sh /usr/local/server/helpers/sveltekit/bundle.sh',
'envCommand' => 'source /usr/local/server/helpers/sveltekit/env.sh',
'adapters' => [
'ssr' => [
'key' => 'ssr',
'buildCommand' => 'npm run build',
'installCommand' => 'npm install',
'outputDirectory' => './build',
'startCommand' => 'sh helpers/sveltekit/server.sh',
],
'static' => [
'key' => 'static',
'buildCommand' => 'npm run build',
'installCommand' => 'npm install',
'outputDirectory' => './build',
'startCommand' => 'sh helpers/server.sh',
]
]
],
'astro' => [
'key' => 'astro',
'name' => 'Astro',
'buildRuntime' => 'node-22',
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
'bundleCommand' => 'sh /usr/local/server/helpers/astro/bundle.sh',
'envCommand' => 'source /usr/local/server/helpers/astro/env.sh',
'adapters' => [
'ssr' => [
'key' => 'ssr',
'buildCommand' => 'npm run build',
'installCommand' => 'npm install',
'outputDirectory' => './dist',
'startCommand' => 'sh helpers/astro/server.sh',
],
'static' => [
'key' => 'static',
'buildCommand' => 'npm run build',
'installCommand' => 'npm install',
'outputDirectory' => './dist',
'startCommand' => 'sh helpers/server.sh',
]
]
],
'remix' => [
'key' => 'remix',
'name' => 'Remix',
'buildRuntime' => 'node-22',
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
'bundleCommand' => 'sh /usr/local/server/helpers/remix/bundle.sh',
'envCommand' => 'source /usr/local/server/helpers/remix/env.sh',
'adapters' => [
'ssr' => [
'key' => 'ssr',
'buildCommand' => 'npm run build',
'installCommand' => 'npm install',
'outputDirectory' => './build',
'startCommand' => 'sh helpers/remix/server.sh',
],
'static' => [
'key' => 'static',
'buildCommand' => 'npm run build',
'installCommand' => 'npm install',
'outputDirectory' => './build/client',
'startCommand' => 'sh helpers/server.sh',
]
]
],
'flutter' => [
'key' => 'flutter',
'name' => 'Flutter',
'buildRuntime' => 'flutter-3.29',
'runtimes' => getVersions($templateRuntimes['FLUTTER']['versions'], 'flutter'),
'adapters' => [
'static' => [
'key' => 'static',
'buildCommand' => 'flutter build web',
'installCommand' => '',
'outputDirectory' => './build/web',
'startCommand' => 'sh helpers/server.sh',
],
],
],
'vite' => [
'key' => 'vite',
'name' => 'Vite',
'buildRuntime' => 'node-22',
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
'adapters' => [
'static' => [
'key' => 'static',
'buildCommand' => 'npm run build',
'installCommand' => 'npm install',
'outputDirectory' => './dist',
'startCommand' => 'sh helpers/server.sh',
],
]
],
'other' => [
'key' => 'other',
'name' => 'Other',
'buildRuntime' => 'node-22',
'runtimes' => getVersions($templateRuntimes['NODE']['versions'], 'node'),
'adapters' => [
'static' => [
'key' => 'static',
'buildCommand' => '',
'installCommand' => '',
'outputDirectory' => './',
'startCommand' => 'sh helpers/server.sh',
],
]
],
];
+5
View File
@@ -26,6 +26,7 @@ $member = [
'subscribers.write',
'subscribers.read',
'assistant.read',
'rules.read'
];
$admins = [
@@ -58,6 +59,10 @@ $admins = [
'health.read',
'functions.read',
'functions.write',
'sites.read',
'sites.write',
'log.read',
'log.write',
'execution.read',
'execution.write',
'rules.read',
+1 -1
View File
@@ -6,4 +6,4 @@
use Appwrite\Runtimes\Runtimes;
return (new Runtimes('v4'))->getAll();
return (new Runtimes('v5'))->getAll();
+12
View File
@@ -64,6 +64,18 @@ return [ // List of publicly visible scopes
'functions.write' => [
'description' => 'Access to create, update, and delete your project\'s functions and code deployments',
],
'sites.read' => [
'description' => 'Access to read your project\'s sites and deployments',
],
'sites.write' => [
'description' => 'Access to create, update, and delete your project\'s sites and deployments',
],
'log.read' => [
'description' => 'Access to read your site\'s logs',
],
'log.write' => [
'description' => 'Access to update, and delete your site\'s logs',
],
'execution.read' => [
'description' => 'Access to read your project\'s execution logs',
],
+14 -1
View File
@@ -173,12 +173,25 @@ return [
'optional' => false,
'icon' => '',
],
'sites' => [
'key' => 'sites',
'name' => 'Sites',
'subtitle' => 'The Sites Service allows you view, create and manage your web applications.',
'description' => '/docs/services/sites.md',
'controller' => '', // Uses modules
'sdk' => true,
'docs' => true,
'docsUrl' => 'https://appwrite.io/docs/sites',
'tests' => false,
'optional' => true,
'icon' => '', // TODO: Update icon later
],
'functions' => [
'key' => 'functions',
'name' => 'Functions',
'subtitle' => 'The Functions Service allows you view, create and manage your Cloud Functions.',
'description' => '/docs/services/functions.md',
'controller' => 'api/functions.php',
'controller' => '', // Uses modules
'sdk' => true,
'docs' => true,
'docsUrl' => 'https://appwrite.io/docs/functions',
@@ -1,6 +1,6 @@
<?php
use Appwrite\Functions\Specification;
use Appwrite\Platform\Modules\Compute\Specification;
return [
Specification::S_05VCPU_512MB => [
+108 -114
View File
@@ -1,7 +1,7 @@
{
"openapi": "3.0.0",
"info": {
"version": "1.6.1",
"version": "1.7.0",
"title": "Appwrite",
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
@@ -43,7 +43,7 @@
},
"x-appwrite": {
"method": "get",
"weight": 9,
"weight": 10,
"cookies": false,
"type": "",
"deprecated": false,
@@ -91,7 +91,7 @@
},
"x-appwrite": {
"method": "create",
"weight": 8,
"weight": 9,
"cookies": false,
"type": "",
"deprecated": false,
@@ -175,7 +175,7 @@
},
"x-appwrite": {
"method": "updateEmail",
"weight": 34,
"weight": 35,
"cookies": false,
"type": "",
"deprecated": false,
@@ -250,7 +250,7 @@
},
"x-appwrite": {
"method": "listIdentities",
"weight": 57,
"weight": 58,
"cookies": false,
"type": "",
"deprecated": false,
@@ -308,7 +308,7 @@
},
"x-appwrite": {
"method": "deleteIdentity",
"weight": 58,
"weight": 59,
"cookies": false,
"type": "",
"deprecated": false,
@@ -370,7 +370,7 @@
},
"x-appwrite": {
"method": "createJWT",
"weight": 29,
"weight": 30,
"cookies": false,
"type": "",
"deprecated": false,
@@ -418,7 +418,7 @@
},
"x-appwrite": {
"method": "listLogs",
"weight": 31,
"weight": 32,
"cookies": false,
"type": "",
"deprecated": false,
@@ -483,7 +483,7 @@
},
"x-appwrite": {
"method": "updateMFA",
"weight": 44,
"weight": 45,
"cookies": false,
"type": "",
"deprecated": false,
@@ -552,7 +552,7 @@
},
"x-appwrite": {
"method": "createMfaAuthenticator",
"weight": 46,
"weight": 47,
"cookies": false,
"type": "",
"deprecated": false,
@@ -617,7 +617,7 @@
},
"x-appwrite": {
"method": "updateMfaAuthenticator",
"weight": 47,
"weight": 48,
"cookies": false,
"type": "",
"deprecated": false,
@@ -694,7 +694,7 @@
},
"x-appwrite": {
"method": "deleteMfaAuthenticator",
"weight": 51,
"weight": 52,
"cookies": false,
"type": "",
"deprecated": false,
@@ -761,7 +761,7 @@
},
"x-appwrite": {
"method": "createMfaChallenge",
"weight": 52,
"weight": 53,
"cookies": false,
"type": "",
"deprecated": false,
@@ -834,7 +834,7 @@
},
"x-appwrite": {
"method": "updateMfaChallenge",
"weight": 53,
"weight": 54,
"cookies": false,
"type": "",
"deprecated": false,
@@ -909,7 +909,7 @@
},
"x-appwrite": {
"method": "listMfaFactors",
"weight": 45,
"weight": 46,
"cookies": false,
"type": "",
"deprecated": false,
@@ -959,7 +959,7 @@
},
"x-appwrite": {
"method": "getMfaRecoveryCodes",
"weight": 50,
"weight": 51,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1007,7 +1007,7 @@
},
"x-appwrite": {
"method": "createMfaRecoveryCodes",
"weight": 48,
"weight": 49,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1055,7 +1055,7 @@
},
"x-appwrite": {
"method": "updateMfaRecoveryCodes",
"weight": 49,
"weight": 50,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1105,7 +1105,7 @@
},
"x-appwrite": {
"method": "updateName",
"weight": 32,
"weight": 33,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1174,7 +1174,7 @@
},
"x-appwrite": {
"method": "updatePassword",
"weight": 33,
"weight": 34,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1248,7 +1248,7 @@
},
"x-appwrite": {
"method": "updatePhone",
"weight": 35,
"weight": 36,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1323,7 +1323,7 @@
},
"x-appwrite": {
"method": "getPrefs",
"weight": 30,
"weight": 31,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1371,7 +1371,7 @@
},
"x-appwrite": {
"method": "updatePrefs",
"weight": 36,
"weight": 37,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1440,7 +1440,7 @@
},
"x-appwrite": {
"method": "createRecovery",
"weight": 38,
"weight": 39,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1516,7 +1516,7 @@
},
"x-appwrite": {
"method": "updateRecovery",
"weight": 39,
"weight": 40,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1597,7 +1597,7 @@
},
"x-appwrite": {
"method": "listSessions",
"weight": 11,
"weight": 12,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1638,7 +1638,7 @@
},
"x-appwrite": {
"method": "deleteSessions",
"weight": 12,
"weight": 13,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1688,7 +1688,7 @@
},
"x-appwrite": {
"method": "createAnonymousSession",
"weight": 17,
"weight": 18,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1736,7 +1736,7 @@
},
"x-appwrite": {
"method": "createEmailPasswordSession",
"weight": 16,
"weight": 17,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1809,7 +1809,7 @@
},
"x-appwrite": {
"method": "updateMagicURLSession",
"weight": 26,
"weight": 27,
"cookies": false,
"type": "",
"deprecated": true,
@@ -1875,7 +1875,7 @@
},
"x-appwrite": {
"method": "createOAuth2Session",
"weight": 19,
"weight": 20,
"cookies": false,
"type": "webAuth",
"deprecated": false,
@@ -2015,7 +2015,7 @@
},
"x-appwrite": {
"method": "updatePhoneSession",
"weight": 27,
"weight": 28,
"cookies": false,
"type": "",
"deprecated": true,
@@ -2088,7 +2088,7 @@
},
"x-appwrite": {
"method": "createSession",
"weight": 18,
"weight": 19,
"cookies": false,
"type": "",
"deprecated": false,
@@ -2161,7 +2161,7 @@
},
"x-appwrite": {
"method": "getSession",
"weight": 13,
"weight": 14,
"cookies": false,
"type": "",
"deprecated": false,
@@ -2221,7 +2221,7 @@
},
"x-appwrite": {
"method": "updateSession",
"weight": 15,
"weight": 16,
"cookies": false,
"type": "",
"deprecated": false,
@@ -2274,7 +2274,7 @@
},
"x-appwrite": {
"method": "deleteSession",
"weight": 14,
"weight": 15,
"cookies": false,
"type": "",
"deprecated": false,
@@ -2336,7 +2336,7 @@
},
"x-appwrite": {
"method": "updateStatus",
"weight": 37,
"weight": 38,
"cookies": false,
"type": "",
"deprecated": false,
@@ -2386,7 +2386,7 @@
},
"x-appwrite": {
"method": "createPushTarget",
"weight": 54,
"weight": 55,
"cookies": false,
"type": "",
"deprecated": false,
@@ -2464,7 +2464,7 @@
},
"x-appwrite": {
"method": "updatePushTarget",
"weight": 55,
"weight": 56,
"cookies": false,
"type": "",
"deprecated": false,
@@ -2534,7 +2534,7 @@
},
"x-appwrite": {
"method": "deletePushTarget",
"weight": 56,
"weight": 57,
"cookies": false,
"type": "",
"deprecated": false,
@@ -2594,7 +2594,7 @@
},
"x-appwrite": {
"method": "createEmailToken",
"weight": 25,
"weight": 26,
"cookies": false,
"type": "",
"deprecated": false,
@@ -2672,7 +2672,7 @@
},
"x-appwrite": {
"method": "createMagicURLToken",
"weight": 24,
"weight": 25,
"cookies": false,
"type": "",
"deprecated": false,
@@ -2751,7 +2751,7 @@
},
"x-appwrite": {
"method": "createOAuth2Token",
"weight": 23,
"weight": 24,
"cookies": false,
"type": "webAuth",
"deprecated": false,
@@ -2891,7 +2891,7 @@
},
"x-appwrite": {
"method": "createPhoneToken",
"weight": 28,
"weight": 29,
"cookies": false,
"type": "",
"deprecated": false,
@@ -2967,7 +2967,7 @@
},
"x-appwrite": {
"method": "createVerification",
"weight": 40,
"weight": 41,
"cookies": false,
"type": "",
"deprecated": false,
@@ -3034,7 +3034,7 @@
},
"x-appwrite": {
"method": "updateVerification",
"weight": 41,
"weight": 42,
"cookies": false,
"type": "",
"deprecated": false,
@@ -3109,7 +3109,7 @@
},
"x-appwrite": {
"method": "createPhoneVerification",
"weight": 42,
"weight": 43,
"cookies": false,
"type": "",
"deprecated": false,
@@ -3160,7 +3160,7 @@
},
"x-appwrite": {
"method": "updatePhoneVerification",
"weight": 43,
"weight": 44,
"cookies": false,
"type": "",
"deprecated": false,
@@ -3228,7 +3228,7 @@
},
"x-appwrite": {
"method": "getBrowser",
"weight": 60,
"weight": 61,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -3353,7 +3353,7 @@
},
"x-appwrite": {
"method": "getCreditCard",
"weight": 59,
"weight": 60,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -3484,7 +3484,7 @@
},
"x-appwrite": {
"method": "getFavicon",
"weight": 63,
"weight": 64,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -3541,7 +3541,7 @@
},
"x-appwrite": {
"method": "getFlag",
"weight": 61,
"weight": 62,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -4028,7 +4028,7 @@
},
"x-appwrite": {
"method": "getImage",
"weight": 62,
"weight": 63,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -4109,7 +4109,7 @@
},
"x-appwrite": {
"method": "getInitials",
"weight": 65,
"weight": 66,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -4200,7 +4200,7 @@
},
"x-appwrite": {
"method": "getQR",
"weight": 64,
"weight": 65,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -4298,7 +4298,7 @@
},
"x-appwrite": {
"method": "listDocuments",
"weight": 109,
"weight": 110,
"cookies": false,
"type": "",
"deprecated": false,
@@ -4382,7 +4382,7 @@
},
"x-appwrite": {
"method": "createDocument",
"weight": 108,
"weight": 109,
"cookies": false,
"type": "",
"deprecated": false,
@@ -4488,7 +4488,7 @@
},
"x-appwrite": {
"method": "getDocument",
"weight": 110,
"weight": 111,
"cookies": false,
"type": "",
"deprecated": false,
@@ -4582,7 +4582,7 @@
},
"x-appwrite": {
"method": "updateDocument",
"weight": 112,
"weight": 113,
"cookies": false,
"type": "",
"deprecated": false,
@@ -4680,7 +4680,7 @@
},
"x-appwrite": {
"method": "deleteDocument",
"weight": 113,
"weight": 114,
"cookies": false,
"type": "",
"deprecated": false,
@@ -4748,7 +4748,7 @@
"tags": [
"functions"
],
"description": "Get a list of all the current user function execution logs. You can use the query params to filter your results.",
"description": "",
"responses": {
"200": {
"description": "Executions List",
@@ -4763,12 +4763,12 @@
},
"x-appwrite": {
"method": "listExecutions",
"weight": 306,
"weight": 383,
"cookies": false,
"type": "",
"deprecated": false,
"demo": "functions\/list-executions.md",
"edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/functions\/list-executions.md",
"edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterGet a list of all the current user function execution logs. You can use the query params to filter your results.",
"rate-limit": 0,
"rate-time": 3600,
"rate-key": "url:{url},ip:{ip}",
@@ -4813,17 +4813,6 @@
"default": []
},
"in": "query"
},
{
"name": "search",
"description": "Search term to filter your list results. Max length: 256 chars.",
"required": false,
"schema": {
"type": "string",
"x-example": "<SEARCH>",
"default": ""
},
"in": "query"
}
]
},
@@ -4833,7 +4822,7 @@
"tags": [
"functions"
],
"description": "Trigger a function execution. The returned object will return you the current execution status. You can ping the `Get Execution` endpoint to get updates on the current execution status. Once this endpoint is called, your function execution process will start asynchronously.",
"description": "",
"responses": {
"201": {
"description": "Execution",
@@ -4848,12 +4837,12 @@
},
"x-appwrite": {
"method": "createExecution",
"weight": 305,
"weight": 381,
"cookies": false,
"type": "",
"deprecated": false,
"demo": "functions\/create-execution.md",
"edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/functions\/create-execution.md",
"edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterTrigger a function execution. The returned object will return you the current execution status. You can ping the `Get Execution` endpoint to get updates on the current execution status. Once this endpoint is called, your function execution process will start asynchronously.",
"rate-limit": 0,
"rate-time": 3600,
"rate-key": "url:{url},ip:{ip}",
@@ -4947,7 +4936,7 @@
"tags": [
"functions"
],
"description": "Get a function execution log by its unique ID.",
"description": "",
"responses": {
"200": {
"description": "Execution",
@@ -4962,12 +4951,12 @@
},
"x-appwrite": {
"method": "getExecution",
"weight": 307,
"weight": 382,
"cookies": false,
"type": "",
"deprecated": false,
"demo": "functions\/get-execution.md",
"edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/functions\/get-execution.md",
"edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterGet a function execution log by its unique ID.",
"rate-limit": 0,
"rate-time": 3600,
"rate-key": "url:{url},ip:{ip}",
@@ -5035,7 +5024,7 @@
},
"x-appwrite": {
"method": "query",
"weight": 331,
"weight": 303,
"cookies": false,
"type": "graphql",
"deprecated": false,
@@ -5086,7 +5075,7 @@
},
"x-appwrite": {
"method": "mutation",
"weight": 330,
"weight": 302,
"cookies": false,
"type": "graphql",
"deprecated": false,
@@ -5137,7 +5126,7 @@
},
"x-appwrite": {
"method": "get",
"weight": 117,
"weight": 118,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5188,7 +5177,7 @@
},
"x-appwrite": {
"method": "listCodes",
"weight": 118,
"weight": 119,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5239,7 +5228,7 @@
},
"x-appwrite": {
"method": "listContinents",
"weight": 122,
"weight": 123,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5290,7 +5279,7 @@
},
"x-appwrite": {
"method": "listCountries",
"weight": 119,
"weight": 120,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5341,7 +5330,7 @@
},
"x-appwrite": {
"method": "listCountriesEU",
"weight": 120,
"weight": 121,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5392,7 +5381,7 @@
},
"x-appwrite": {
"method": "listCountriesPhones",
"weight": 121,
"weight": 122,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5443,7 +5432,7 @@
},
"x-appwrite": {
"method": "listCurrencies",
"weight": 123,
"weight": 124,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5494,7 +5483,7 @@
},
"x-appwrite": {
"method": "listLanguages",
"weight": 124,
"weight": 125,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5545,7 +5534,7 @@
},
"x-appwrite": {
"method": "createSubscriber",
"weight": 376,
"weight": 348,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5627,7 +5616,7 @@
},
"x-appwrite": {
"method": "deleteSubscriber",
"weight": 380,
"weight": 352,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5701,7 +5690,7 @@
},
"x-appwrite": {
"method": "listFiles",
"weight": 208,
"weight": 209,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5786,7 +5775,7 @@
},
"x-appwrite": {
"method": "createFile",
"weight": 207,
"weight": 208,
"cookies": false,
"type": "upload",
"deprecated": false,
@@ -5883,7 +5872,7 @@
},
"x-appwrite": {
"method": "getFile",
"weight": 209,
"weight": 210,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5954,7 +5943,7 @@
},
"x-appwrite": {
"method": "updateFile",
"weight": 214,
"weight": 215,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6042,7 +6031,7 @@
},
"x-appwrite": {
"method": "deleteFile",
"weight": 215,
"weight": 216,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6108,7 +6097,7 @@
},
"x-appwrite": {
"method": "getFileDownload",
"weight": 211,
"weight": 212,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -6174,7 +6163,7 @@
},
"x-appwrite": {
"method": "getFilePreview",
"weight": 210,
"weight": 211,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -6390,7 +6379,7 @@
},
"x-appwrite": {
"method": "getFileView",
"weight": 212,
"weight": 213,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -6463,7 +6452,7 @@
},
"x-appwrite": {
"method": "list",
"weight": 219,
"weight": 220,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6538,7 +6527,7 @@
},
"x-appwrite": {
"method": "create",
"weight": 218,
"weight": 219,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6622,7 +6611,7 @@
},
"x-appwrite": {
"method": "get",
"weight": 220,
"weight": 221,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6683,7 +6672,7 @@
},
"x-appwrite": {
"method": "updateName",
"weight": 222,
"weight": 223,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6756,7 +6745,7 @@
},
"x-appwrite": {
"method": "delete",
"weight": 224,
"weight": 225,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6819,7 +6808,7 @@
},
"x-appwrite": {
"method": "listMemberships",
"weight": 226,
"weight": 227,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6904,7 +6893,7 @@
},
"x-appwrite": {
"method": "createMembership",
"weight": 225,
"weight": 226,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7014,7 +7003,7 @@
},
"x-appwrite": {
"method": "getMembership",
"weight": 227,
"weight": 228,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7085,7 +7074,7 @@
},
"x-appwrite": {
"method": "updateMembership",
"weight": 228,
"weight": 229,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7171,7 +7160,7 @@
},
"x-appwrite": {
"method": "deleteMembership",
"weight": 230,
"weight": 231,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7244,7 +7233,7 @@
},
"x-appwrite": {
"method": "updateMembershipStatus",
"weight": 229,
"weight": 230,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7341,7 +7330,7 @@
},
"x-appwrite": {
"method": "getPrefs",
"weight": 221,
"weight": 222,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7401,7 +7390,7 @@
},
"x-appwrite": {
"method": "updatePrefs",
"weight": 223,
"weight": 224,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7514,6 +7503,11 @@
"description": "The Users service allows you to manage your project users.",
"x-globalAttributes": []
},
{
"name": "sites",
"description": "The Sites Service allows you view, create and manage your web applications.",
"x-globalAttributes": []
},
{
"name": "functions",
"description": "The Functions Service allows you view, create and manage your Cloud Functions.",
@@ -9143,7 +9137,7 @@
},
"duration": {
"type": "number",
"description": "Function execution duration in seconds.",
"description": "Resource(function\/site) execution duration in seconds.",
"x-example": 0.4,
"format": "double"
},
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+108 -112
View File
@@ -1,7 +1,7 @@
{
"swagger": "2.0",
"info": {
"version": "1.6.1",
"version": "1.7.0",
"title": "Appwrite",
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
@@ -87,7 +87,7 @@
},
"x-appwrite": {
"method": "get",
"weight": 9,
"weight": 10,
"cookies": false,
"type": "",
"deprecated": false,
@@ -137,7 +137,7 @@
},
"x-appwrite": {
"method": "create",
"weight": 8,
"weight": 9,
"cookies": false,
"type": "",
"deprecated": false,
@@ -227,7 +227,7 @@
},
"x-appwrite": {
"method": "updateEmail",
"weight": 34,
"weight": 35,
"cookies": false,
"type": "",
"deprecated": false,
@@ -306,7 +306,7 @@
},
"x-appwrite": {
"method": "listIdentities",
"weight": 57,
"weight": 58,
"cookies": false,
"type": "",
"deprecated": false,
@@ -367,7 +367,7 @@
},
"x-appwrite": {
"method": "deleteIdentity",
"weight": 58,
"weight": 59,
"cookies": false,
"type": "",
"deprecated": false,
@@ -429,7 +429,7 @@
},
"x-appwrite": {
"method": "createJWT",
"weight": 29,
"weight": 30,
"cookies": false,
"type": "",
"deprecated": false,
@@ -479,7 +479,7 @@
},
"x-appwrite": {
"method": "listLogs",
"weight": 31,
"weight": 32,
"cookies": false,
"type": "",
"deprecated": false,
@@ -545,7 +545,7 @@
},
"x-appwrite": {
"method": "updateMFA",
"weight": 44,
"weight": 45,
"cookies": false,
"type": "",
"deprecated": false,
@@ -617,7 +617,7 @@
},
"x-appwrite": {
"method": "createMfaAuthenticator",
"weight": 46,
"weight": 47,
"cookies": false,
"type": "",
"deprecated": false,
@@ -682,7 +682,7 @@
},
"x-appwrite": {
"method": "updateMfaAuthenticator",
"weight": 47,
"weight": 48,
"cookies": false,
"type": "",
"deprecated": false,
@@ -760,7 +760,7 @@
},
"x-appwrite": {
"method": "deleteMfaAuthenticator",
"weight": 51,
"weight": 52,
"cookies": false,
"type": "",
"deprecated": false,
@@ -827,7 +827,7 @@
},
"x-appwrite": {
"method": "createMfaChallenge",
"weight": 52,
"weight": 53,
"cookies": false,
"type": "",
"deprecated": false,
@@ -903,7 +903,7 @@
},
"x-appwrite": {
"method": "updateMfaChallenge",
"weight": 53,
"weight": 54,
"cookies": false,
"type": "",
"deprecated": false,
@@ -982,7 +982,7 @@
},
"x-appwrite": {
"method": "listMfaFactors",
"weight": 45,
"weight": 46,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1034,7 +1034,7 @@
},
"x-appwrite": {
"method": "getMfaRecoveryCodes",
"weight": 50,
"weight": 51,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1084,7 +1084,7 @@
},
"x-appwrite": {
"method": "createMfaRecoveryCodes",
"weight": 48,
"weight": 49,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1134,7 +1134,7 @@
},
"x-appwrite": {
"method": "updateMfaRecoveryCodes",
"weight": 49,
"weight": 50,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1186,7 +1186,7 @@
},
"x-appwrite": {
"method": "updateName",
"weight": 32,
"weight": 33,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1258,7 +1258,7 @@
},
"x-appwrite": {
"method": "updatePassword",
"weight": 33,
"weight": 34,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1336,7 +1336,7 @@
},
"x-appwrite": {
"method": "updatePhone",
"weight": 35,
"weight": 36,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1415,7 +1415,7 @@
},
"x-appwrite": {
"method": "getPrefs",
"weight": 30,
"weight": 31,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1465,7 +1465,7 @@
},
"x-appwrite": {
"method": "updatePrefs",
"weight": 36,
"weight": 37,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1537,7 +1537,7 @@
},
"x-appwrite": {
"method": "createRecovery",
"weight": 38,
"weight": 39,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1617,7 +1617,7 @@
},
"x-appwrite": {
"method": "updateRecovery",
"weight": 39,
"weight": 40,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1703,7 +1703,7 @@
},
"x-appwrite": {
"method": "listSessions",
"weight": 11,
"weight": 12,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1748,7 +1748,7 @@
},
"x-appwrite": {
"method": "deleteSessions",
"weight": 12,
"weight": 13,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1800,7 +1800,7 @@
},
"x-appwrite": {
"method": "createAnonymousSession",
"weight": 17,
"weight": 18,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1850,7 +1850,7 @@
},
"x-appwrite": {
"method": "createEmailPasswordSession",
"weight": 16,
"weight": 17,
"cookies": false,
"type": "",
"deprecated": false,
@@ -1927,7 +1927,7 @@
},
"x-appwrite": {
"method": "updateMagicURLSession",
"weight": 26,
"weight": 27,
"cookies": false,
"type": "",
"deprecated": true,
@@ -2001,7 +2001,7 @@
},
"x-appwrite": {
"method": "createOAuth2Session",
"weight": 19,
"weight": 20,
"cookies": false,
"type": "webAuth",
"deprecated": false,
@@ -2136,7 +2136,7 @@
},
"x-appwrite": {
"method": "updatePhoneSession",
"weight": 27,
"weight": 28,
"cookies": false,
"type": "",
"deprecated": true,
@@ -2213,7 +2213,7 @@
},
"x-appwrite": {
"method": "createSession",
"weight": 18,
"weight": 19,
"cookies": false,
"type": "",
"deprecated": false,
@@ -2290,7 +2290,7 @@
},
"x-appwrite": {
"method": "getSession",
"weight": 13,
"weight": 14,
"cookies": false,
"type": "",
"deprecated": false,
@@ -2350,7 +2350,7 @@
},
"x-appwrite": {
"method": "updateSession",
"weight": 15,
"weight": 16,
"cookies": false,
"type": "",
"deprecated": false,
@@ -2405,7 +2405,7 @@
},
"x-appwrite": {
"method": "deleteSession",
"weight": 14,
"weight": 15,
"cookies": false,
"type": "",
"deprecated": false,
@@ -2467,7 +2467,7 @@
},
"x-appwrite": {
"method": "updateStatus",
"weight": 37,
"weight": 38,
"cookies": false,
"type": "",
"deprecated": false,
@@ -2519,7 +2519,7 @@
},
"x-appwrite": {
"method": "createPushTarget",
"weight": 54,
"weight": 55,
"cookies": false,
"type": "",
"deprecated": false,
@@ -2602,7 +2602,7 @@
},
"x-appwrite": {
"method": "updatePushTarget",
"weight": 55,
"weight": 56,
"cookies": false,
"type": "",
"deprecated": false,
@@ -2673,7 +2673,7 @@
},
"x-appwrite": {
"method": "deletePushTarget",
"weight": 56,
"weight": 57,
"cookies": false,
"type": "",
"deprecated": false,
@@ -2733,7 +2733,7 @@
},
"x-appwrite": {
"method": "createEmailToken",
"weight": 25,
"weight": 26,
"cookies": false,
"type": "",
"deprecated": false,
@@ -2816,7 +2816,7 @@
},
"x-appwrite": {
"method": "createMagicURLToken",
"weight": 24,
"weight": 25,
"cookies": false,
"type": "",
"deprecated": false,
@@ -2905,7 +2905,7 @@
},
"x-appwrite": {
"method": "createOAuth2Token",
"weight": 23,
"weight": 24,
"cookies": false,
"type": "webAuth",
"deprecated": false,
@@ -3040,7 +3040,7 @@
},
"x-appwrite": {
"method": "createPhoneToken",
"weight": 28,
"weight": 29,
"cookies": false,
"type": "",
"deprecated": false,
@@ -3120,7 +3120,7 @@
},
"x-appwrite": {
"method": "createVerification",
"weight": 40,
"weight": 41,
"cookies": false,
"type": "",
"deprecated": false,
@@ -3190,7 +3190,7 @@
},
"x-appwrite": {
"method": "updateVerification",
"weight": 41,
"weight": 42,
"cookies": false,
"type": "",
"deprecated": false,
@@ -3269,7 +3269,7 @@
},
"x-appwrite": {
"method": "createPhoneVerification",
"weight": 42,
"weight": 43,
"cookies": false,
"type": "",
"deprecated": false,
@@ -3322,7 +3322,7 @@
},
"x-appwrite": {
"method": "updatePhoneVerification",
"weight": 43,
"weight": 44,
"cookies": false,
"type": "",
"deprecated": false,
@@ -3401,7 +3401,7 @@
},
"x-appwrite": {
"method": "getBrowser",
"weight": 60,
"weight": 61,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -3527,7 +3527,7 @@
},
"x-appwrite": {
"method": "getCreditCard",
"weight": 59,
"weight": 60,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -3659,7 +3659,7 @@
},
"x-appwrite": {
"method": "getFavicon",
"weight": 63,
"weight": 64,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -3723,7 +3723,7 @@
},
"x-appwrite": {
"method": "getFlag",
"weight": 61,
"weight": 62,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -4211,7 +4211,7 @@
},
"x-appwrite": {
"method": "getImage",
"weight": 62,
"weight": 63,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -4295,7 +4295,7 @@
},
"x-appwrite": {
"method": "getInitials",
"weight": 65,
"weight": 66,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -4387,7 +4387,7 @@
},
"x-appwrite": {
"method": "getQR",
"weight": 64,
"weight": 65,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -4479,7 +4479,7 @@
},
"x-appwrite": {
"method": "listDocuments",
"weight": 109,
"weight": 110,
"cookies": false,
"type": "",
"deprecated": false,
@@ -4560,7 +4560,7 @@
},
"x-appwrite": {
"method": "createDocument",
"weight": 108,
"weight": 109,
"cookies": false,
"type": "",
"deprecated": false,
@@ -4665,7 +4665,7 @@
},
"x-appwrite": {
"method": "getDocument",
"weight": 110,
"weight": 111,
"cookies": false,
"type": "",
"deprecated": false,
@@ -4754,7 +4754,7 @@
},
"x-appwrite": {
"method": "updateDocument",
"weight": 112,
"weight": 113,
"cookies": false,
"type": "",
"deprecated": false,
@@ -4850,7 +4850,7 @@
},
"x-appwrite": {
"method": "deleteDocument",
"weight": 113,
"weight": 114,
"cookies": false,
"type": "",
"deprecated": false,
@@ -4918,7 +4918,7 @@
"tags": [
"functions"
],
"description": "Get a list of all the current user function execution logs. You can use the query params to filter your results.",
"description": "",
"responses": {
"200": {
"description": "Executions List",
@@ -4929,12 +4929,12 @@
},
"x-appwrite": {
"method": "listExecutions",
"weight": 306,
"weight": 383,
"cookies": false,
"type": "",
"deprecated": false,
"demo": "functions\/list-executions.md",
"edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/functions\/list-executions.md",
"edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterGet a list of all the current user function execution logs. You can use the query params to filter your results.",
"rate-limit": 0,
"rate-time": 3600,
"rate-key": "url:{url},ip:{ip}",
@@ -4976,15 +4976,6 @@
},
"default": [],
"in": "query"
},
{
"name": "search",
"description": "Search term to filter your list results. Max length: 256 chars.",
"required": false,
"type": "string",
"x-example": "<SEARCH>",
"default": "",
"in": "query"
}
]
},
@@ -5000,7 +4991,7 @@
"tags": [
"functions"
],
"description": "Trigger a function execution. The returned object will return you the current execution status. You can ping the `Get Execution` endpoint to get updates on the current execution status. Once this endpoint is called, your function execution process will start asynchronously.",
"description": "",
"responses": {
"201": {
"description": "Execution",
@@ -5011,12 +5002,12 @@
},
"x-appwrite": {
"method": "createExecution",
"weight": 305,
"weight": 381,
"cookies": false,
"type": "",
"deprecated": false,
"demo": "functions\/create-execution.md",
"edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/functions\/create-execution.md",
"edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterTrigger a function execution. The returned object will return you the current execution status. You can ping the `Get Execution` endpoint to get updates on the current execution status. Once this endpoint is called, your function execution process will start asynchronously.",
"rate-limit": 0,
"rate-time": 3600,
"rate-key": "url:{url},ip:{ip}",
@@ -5118,7 +5109,7 @@
"tags": [
"functions"
],
"description": "Get a function execution log by its unique ID.",
"description": "",
"responses": {
"200": {
"description": "Execution",
@@ -5129,12 +5120,12 @@
},
"x-appwrite": {
"method": "getExecution",
"weight": 307,
"weight": 382,
"cookies": false,
"type": "",
"deprecated": false,
"demo": "functions\/get-execution.md",
"edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/functions\/get-execution.md",
"edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/masterGet a function execution log by its unique ID.",
"rate-limit": 0,
"rate-time": 3600,
"rate-key": "url:{url},ip:{ip}",
@@ -5200,7 +5191,7 @@
},
"x-appwrite": {
"method": "query",
"weight": 331,
"weight": 303,
"cookies": false,
"type": "graphql",
"deprecated": false,
@@ -5273,7 +5264,7 @@
},
"x-appwrite": {
"method": "mutation",
"weight": 330,
"weight": 302,
"cookies": false,
"type": "graphql",
"deprecated": false,
@@ -5346,7 +5337,7 @@
},
"x-appwrite": {
"method": "get",
"weight": 117,
"weight": 118,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5399,7 +5390,7 @@
},
"x-appwrite": {
"method": "listCodes",
"weight": 118,
"weight": 119,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5452,7 +5443,7 @@
},
"x-appwrite": {
"method": "listContinents",
"weight": 122,
"weight": 123,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5505,7 +5496,7 @@
},
"x-appwrite": {
"method": "listCountries",
"weight": 119,
"weight": 120,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5558,7 +5549,7 @@
},
"x-appwrite": {
"method": "listCountriesEU",
"weight": 120,
"weight": 121,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5611,7 +5602,7 @@
},
"x-appwrite": {
"method": "listCountriesPhones",
"weight": 121,
"weight": 122,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5664,7 +5655,7 @@
},
"x-appwrite": {
"method": "listCurrencies",
"weight": 123,
"weight": 124,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5717,7 +5708,7 @@
},
"x-appwrite": {
"method": "listLanguages",
"weight": 124,
"weight": 125,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5770,7 +5761,7 @@
},
"x-appwrite": {
"method": "createSubscriber",
"weight": 376,
"weight": 348,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5854,7 +5845,7 @@
},
"x-appwrite": {
"method": "deleteSubscriber",
"weight": 380,
"weight": 352,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5926,7 +5917,7 @@
},
"x-appwrite": {
"method": "listFiles",
"weight": 208,
"weight": 209,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6008,7 +5999,7 @@
},
"x-appwrite": {
"method": "createFile",
"weight": 207,
"weight": 208,
"cookies": false,
"type": "upload",
"deprecated": false,
@@ -6099,7 +6090,7 @@
},
"x-appwrite": {
"method": "getFile",
"weight": 209,
"weight": 210,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6168,7 +6159,7 @@
},
"x-appwrite": {
"method": "updateFile",
"weight": 214,
"weight": 215,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6256,7 +6247,7 @@
},
"x-appwrite": {
"method": "deleteFile",
"weight": 215,
"weight": 216,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6327,7 +6318,7 @@
},
"x-appwrite": {
"method": "getFileDownload",
"weight": 211,
"weight": 212,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -6398,7 +6389,7 @@
},
"x-appwrite": {
"method": "getFilePreview",
"weight": 210,
"weight": 211,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -6597,7 +6588,7 @@
},
"x-appwrite": {
"method": "getFileView",
"weight": 212,
"weight": 213,
"cookies": false,
"type": "location",
"deprecated": false,
@@ -6668,7 +6659,7 @@
},
"x-appwrite": {
"method": "list",
"weight": 219,
"weight": 220,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6742,7 +6733,7 @@
},
"x-appwrite": {
"method": "create",
"weight": 218,
"weight": 219,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6833,7 +6824,7 @@
},
"x-appwrite": {
"method": "get",
"weight": 220,
"weight": 221,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6894,7 +6885,7 @@
},
"x-appwrite": {
"method": "updateName",
"weight": 222,
"weight": 223,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6968,7 +6959,7 @@
},
"x-appwrite": {
"method": "delete",
"weight": 224,
"weight": 225,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7031,7 +7022,7 @@
},
"x-appwrite": {
"method": "listMemberships",
"weight": 226,
"weight": 227,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7113,7 +7104,7 @@
},
"x-appwrite": {
"method": "createMembership",
"weight": 225,
"weight": 226,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7227,7 +7218,7 @@
},
"x-appwrite": {
"method": "getMembership",
"weight": 227,
"weight": 228,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7296,7 +7287,7 @@
},
"x-appwrite": {
"method": "updateMembership",
"weight": 228,
"weight": 229,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7381,7 +7372,7 @@
},
"x-appwrite": {
"method": "deleteMembership",
"weight": 230,
"weight": 231,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7452,7 +7443,7 @@
},
"x-appwrite": {
"method": "updateMembershipStatus",
"weight": 229,
"weight": 230,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7547,7 +7538,7 @@
},
"x-appwrite": {
"method": "getPrefs",
"weight": 221,
"weight": 222,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7607,7 +7598,7 @@
},
"x-appwrite": {
"method": "updatePrefs",
"weight": 223,
"weight": 224,
"cookies": false,
"type": "",
"deprecated": false,
@@ -7717,6 +7708,11 @@
"description": "The Users service allows you to manage your project users.",
"x-globalAttributes": []
},
{
"name": "sites",
"description": "The Sites Service allows you view, create and manage your web applications.",
"x-globalAttributes": []
},
{
"name": "functions",
"description": "The Functions Service allows you view, create and manage your Cloud Functions.",
@@ -9332,7 +9328,7 @@
},
"duration": {
"type": "number",
"description": "Function execution duration in seconds.",
"description": "Resource(function\/site) execution duration in seconds.",
"x-example": 0.4,
"format": "double"
},
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+40
View File
@@ -0,0 +1,40 @@
<?php
return [
'NODE' => [
'name' => 'node',
'versions' => ['22', '21.0', '20.0', '19.0', '18.0', '16.0', '14.5']
],
'PYTHON' => [
'name' => 'python',
'versions' => ['3.12', '3.11', '3.10', '3.9', '3.8']
],
'DART' => [
'name' => 'dart',
'versions' => ['3.5', '3.3', '3.1', '3.0', '2.19', '2.18', '2.17', '2.16']
],
'GO' => [
'name' => 'go',
'versions' => ['1.23']
],
'PHP' => [
'name' => 'php',
'versions' => ['8.3', '8.2', '8.1', '8.0']
],
'DENO' => [
'name' => 'deno',
'versions' => ['2.0', '1.46', '1.40', '1.35', '1.24', '1.21']
],
'BUN' => [
'name' => 'bun',
'versions' => ['1.1', '1.0']
],
'RUBY' => [
'name' => 'ruby',
'versions' => ['3.3', '3.2', '3.1', '3.0']
],
'FLUTTER' => [
'name' => 'flutter',
'versions' => ['3.24']
],
];
@@ -1,39 +1,8 @@
<?php
const TEMPLATE_RUNTIMES = [
'NODE' => [
'name' => 'node',
'versions' => ['22', '21.0', '20.0', '19.0', '18.0', '16.0', '14.5']
],
'PYTHON' => [
'name' => 'python',
'versions' => ['3.12', '3.11', '3.10', '3.9', '3.8']
],
'DART' => [
'name' => 'dart',
'versions' => ['3.5', '3.3', '3.1', '3.0', '2.19', '2.18', '2.17', '2.16']
],
'GO' => [
'name' => 'go',
'versions' => ['1.23']
],
'PHP' => [
'name' => 'php',
'versions' => ['8.3', '8.2', '8.1', '8.0']
],
'DENO' => [
'name' => 'deno',
'versions' => ['2.0', '1.46', '1.40', '1.35', '1.24', '1.21']
],
'BUN' => [
'name' => 'bun',
'versions' => ['1.1', '1.0']
],
'RUBY' => [
'name' => 'ruby',
'versions' => ['3.3', '3.2', '3.1', '3.0']
],
];
use Utopia\Config\Config;
$templateRuntimes = Config::getParam('template-runtimes');
function getRuntimes($runtime, $commands, $entrypoint, $providerRootDirectory, $versionsDenyList = [])
{
@@ -62,24 +31,24 @@ return [
'timeout' => 15,
'useCases' => ['starter'],
'runtimes' => [
...getRuntimes(TEMPLATE_RUNTIMES['NODE'], 'npm install', 'src/main.js', 'node/starter'),
...getRuntimes($templateRuntimes['NODE'], 'npm install', 'src/main.js', 'node/starter'),
...getRuntimes(
TEMPLATE_RUNTIMES['PYTHON'],
$templateRuntimes['PYTHON'],
'pip install -r requirements.txt',
'src/main.py',
'python/starter'
),
...getRuntimes(TEMPLATE_RUNTIMES['DART'], 'dart pub get', 'lib/main.dart', 'dart/starter'),
...getRuntimes(TEMPLATE_RUNTIMES['GO'], '', 'main.go', 'go/starter'),
...getRuntimes($templateRuntimes['DART'], 'dart pub get', 'lib/main.dart', 'dart/starter'),
...getRuntimes($templateRuntimes['GO'], '', 'main.go', 'go/starter'),
...getRuntimes(
TEMPLATE_RUNTIMES['PHP'],
$templateRuntimes['PHP'],
'composer install',
'src/index.php',
'php/starter'
),
...getRuntimes(TEMPLATE_RUNTIMES['DENO'], 'deno cache src/main.ts', 'src/main.ts', 'deno/starter'),
...getRuntimes(TEMPLATE_RUNTIMES['BUN'], 'bun install', 'src/main.ts', 'bun/starter'),
...getRuntimes(TEMPLATE_RUNTIMES['RUBY'], 'bundle install', 'lib/main.rb', 'ruby/starter'),
...getRuntimes($templateRuntimes['DENO'], 'deno cache src/main.ts', 'src/main.ts', 'deno/starter'),
...getRuntimes($templateRuntimes['BUN'], 'bun install', 'src/main.ts', 'bun/starter'),
...getRuntimes($templateRuntimes['RUBY'], 'bundle install', 'lib/main.rb', 'ruby/starter'),
],
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/starter">file</a>.',
'vcsProvider' => 'github',
@@ -101,7 +70,7 @@ return [
'useCases' => ['databases'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/query-upstash-vector'
@@ -145,7 +114,7 @@ return [
'useCases' => ['databases'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/query-redis-labs'
@@ -188,7 +157,7 @@ return [
'useCases' => ['databases'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/query-neo4j-auradb'
@@ -240,7 +209,7 @@ return [
'useCases' => ['databases'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/query-mongo-atlas'
@@ -277,7 +246,7 @@ return [
'useCases' => ['databases'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/query-neon-postgres'
@@ -344,25 +313,25 @@ return [
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/prompt-chatgpt'
),
...getRuntimes(
TEMPLATE_RUNTIMES['PYTHON'],
$templateRuntimes['PYTHON'],
'pip install -r requirements.txt',
'src/main.py',
'python/prompt_chatgpt'
),
...getRuntimes(
TEMPLATE_RUNTIMES['PHP'],
$templateRuntimes['PHP'],
'composer install',
'src/index.php',
'php/prompt-chatgpt'
),
...getRuntimes(
TEMPLATE_RUNTIMES['DART'],
$templateRuntimes['DART'],
'dart pub get',
'lib/main.dart',
'dart/prompt_chatgpt'
@@ -405,19 +374,19 @@ return [
'useCases' => ['messaging'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install && npm run setup',
'src/main.js',
'node/discord-command-bot'
),
...getRuntimes(
TEMPLATE_RUNTIMES['PYTHON'],
$templateRuntimes['PYTHON'],
'pip install -r requirements.txt && python src/setup.py',
'src/main.py',
'python/discord_command_bot'
),
...getRuntimes(
TEMPLATE_RUNTIMES['GO'],
$templateRuntimes['GO'],
'',
'main.go',
'go/discord-command-bot'
@@ -468,7 +437,7 @@ return [
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/analyze-with-perspectiveapi'
@@ -504,19 +473,19 @@ return [
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/censor-with-redact'
),
...getRuntimes(
TEMPLATE_RUNTIMES['PYTHON'],
$templateRuntimes['PYTHON'],
'pip install -r requirements.txt',
'src/main.py',
'python/censor_with_redact'
),
...getRuntimes(
TEMPLATE_RUNTIMES['DART'],
$templateRuntimes['DART'],
'dart pub get',
'lib/main.dart',
'dart/censor_with_redact'
@@ -550,7 +519,7 @@ return [
'timeout' => 15,
'useCases' => ['utilities'],
'runtimes' => [
...getRuntimes(TEMPLATE_RUNTIMES['NODE'], 'npm install', 'src/main.js', 'node/generate-pdf')
...getRuntimes($templateRuntimes['NODE'], 'npm install', 'src/main.js', 'node/generate-pdf')
],
'instructions' => 'For documentation and instructions check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/node/generate-pdf">file</a>.',
'vcsProvider' => 'github',
@@ -573,7 +542,7 @@ return [
'useCases' => ['dev-tools'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/github-issue-bot'
@@ -616,7 +585,7 @@ return [
'useCases' => ['utilities'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/url-shortener'
@@ -667,19 +636,19 @@ return [
'useCases' => ['databases'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/sync-with-algolia'
),
...getRuntimes(
TEMPLATE_RUNTIMES['PYTHON'],
$templateRuntimes['PYTHON'],
'pip install -r requirements.txt',
'src/main.py',
'python/sync_with_algolia'
),
...getRuntimes(
TEMPLATE_RUNTIMES['PHP'],
$templateRuntimes['PHP'],
'composer install',
'src/index.php',
'php/sync-with-algolia'
@@ -748,31 +717,31 @@ return [
'useCases' => ['databases'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/sync-with-meilisearch'
),
...getRuntimes(
TEMPLATE_RUNTIMES['PYTHON'],
$templateRuntimes['PYTHON'],
'pip install -r requirements.txt',
'src/main.py',
'python/sync-with-meilisearch'
),
...getRuntimes(
TEMPLATE_RUNTIMES['PHP'],
$templateRuntimes['PHP'],
'composer install',
'src/index.php',
'php/sync-with-meilisearch'
),
...getRuntimes(
TEMPLATE_RUNTIMES['BUN'],
$templateRuntimes['BUN'],
'bun install',
'src/main.ts',
'bun/sync-with-meilisearch'
),
...getRuntimes(
TEMPLATE_RUNTIMES['RUBY'],
$templateRuntimes['RUBY'],
'bundle install',
'lib/main.rb',
'ruby/sync-with-meilisearch'
@@ -841,37 +810,37 @@ return [
'useCases' => ['messaging'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/whatsapp-with-vonage'
),
...getRuntimes(
TEMPLATE_RUNTIMES['PYTHON'],
$templateRuntimes['PYTHON'],
'pip install -r requirements.txt',
'src/main.py',
'python/whatsapp_with_vonage'
),
...getRuntimes(
TEMPLATE_RUNTIMES['DART'],
$templateRuntimes['DART'],
'dart pub get',
'lib/main.dart',
'dart/whatsapp-with-vonage'
),
...getRuntimes(
TEMPLATE_RUNTIMES['PHP'],
$templateRuntimes['PHP'],
'composer install',
'src/index.php',
'php/whatsapp-with-vonage'
),
...getRuntimes(
TEMPLATE_RUNTIMES['BUN'],
$templateRuntimes['BUN'],
'bun install',
'src/main.ts',
'bun/whatsapp-with-vonage'
),
...getRuntimes(
TEMPLATE_RUNTIMES['RUBY'],
$templateRuntimes['RUBY'],
'bundle install',
'lib/main.rb',
'ruby/whatsapp-with-vonage'
@@ -927,7 +896,7 @@ return [
'useCases' => ['messaging'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/push-notification-with-fcm'
@@ -983,19 +952,19 @@ return [
'useCases' => ['utilities'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/email-contact-form'
),
...getRuntimes(
TEMPLATE_RUNTIMES['PYTHON'],
$templateRuntimes['PYTHON'],
'pip install -r requirements.txt',
'src/main.py',
'python/email_contact_form'
),
...getRuntimes(
TEMPLATE_RUNTIMES['PHP'],
$templateRuntimes['PHP'],
'composer install',
'src/index.php',
'php/email-contact-form'
@@ -1066,7 +1035,7 @@ return [
'useCases' => ['utilities'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/subscriptions-with-stripe'
@@ -1107,7 +1076,7 @@ return [
'useCases' => ['utilities'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/payments-with-stripe'
@@ -1164,7 +1133,7 @@ return [
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/text-generation-with-huggingface'
@@ -1198,7 +1167,7 @@ return [
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/language-translation-with-huggingface'
@@ -1232,7 +1201,7 @@ return [
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install && npm run setup',
'src/main.js',
'node/image-classification-with-huggingface'
@@ -1290,7 +1259,7 @@ return [
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install && npm run setup',
'src/main.js',
'node/object-detection-with-huggingface'
@@ -1348,7 +1317,7 @@ return [
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install && npm run setup',
'src/main.js',
'node/speech-recognition-with-huggingface'
@@ -1406,7 +1375,7 @@ return [
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install && npm run setup',
'src/main.js',
'node/text-to-speech-with-huggingface'
@@ -1464,7 +1433,7 @@ return [
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/generate-with-replicate'
@@ -1499,7 +1468,7 @@ return [
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/generate-with-together-ai'
@@ -1541,7 +1510,7 @@ return [
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/chat-with-perplexity-ai'
@@ -1582,7 +1551,7 @@ return [
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/generate-with-replicate'
@@ -1617,7 +1586,7 @@ return [
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/sync-with-pinecone'
@@ -1680,7 +1649,7 @@ return [
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/rag-with-langchain'
@@ -1743,7 +1712,7 @@ return [
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/speak-with-elevenlabs'
@@ -1798,7 +1767,7 @@ return [
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/speak-with-lmnt'
@@ -1839,7 +1808,7 @@ return [
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/chat-with-anyscale'
@@ -1880,7 +1849,7 @@ return [
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install && npm run setup',
'src/main.js',
'node/music-generation-with-huggingface'
@@ -1922,7 +1891,7 @@ return [
'useCases' => ['ai'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/generate-with-fal-ai'
@@ -1957,7 +1926,7 @@ return [
'useCases' => ['utilities'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/subscriptions-with-lemon-squeezy'
@@ -2012,7 +1981,7 @@ return [
'useCases' => ['utilities'],
'runtimes' => [
...getRuntimes(
TEMPLATE_RUNTIMES['NODE'],
$templateRuntimes['NODE'],
'npm install',
'src/main.js',
'node/payments-with-lemon-squeezy'
+753
View File
@@ -0,0 +1,753 @@
<?php
use Utopia\System\System;
/**
* List of Appwrite Sites templates
*/
$protocol = System::getEnv('_APP_OPTIONS_FORCE_HTTPS') == 'disabled' ? 'http' : 'https';
$hostname = System::getEnv('_APP_DOMAIN');
// TODO: Development override
if (System::getEnv('_APP_ENV') === 'development') {
$hostname = 'localhost';
}
$url = $protocol . '://' . $hostname;
const TEMPLATE_FRAMEWORKS = [
'SVELTEKIT' => [
'key' => 'sveltekit',
'name' => 'SvelteKit',
'installCommand' => 'npm install',
'buildCommand' => 'npm run build',
'outputDirectory' => './build',
'buildRuntime' => 'node-22',
'adapter' => 'ssr',
'fallbackFile' => '',
],
'NEXTJS' => [
'key' => 'nextjs',
'name' => 'Next.js',
'installCommand' => 'npm install',
'buildCommand' => 'npm run build',
'outputDirectory' => './.next',
'buildRuntime' => 'node-22',
'adapter' => 'ssr',
'fallbackFile' => '',
],
'NUXT' => [
'key' => 'nuxt',
'name' => 'Nuxt',
'installCommand' => 'npm install',
'buildCommand' => 'npm run build',
'outputDirectory' => './.output',
'buildRuntime' => 'node-22',
'adapter' => 'ssr',
'fallbackFile' => '',
],
'REMIX' => [
'key' => 'remix',
'name' => 'Remix',
'installCommand' => 'npm install',
'buildCommand' => 'npm run build',
'outputDirectory' => './build',
'buildRuntime' => 'node-22',
'adapter' => 'ssr',
'fallbackFile' => '',
],
'ASTRO' => [
'key' => 'astro',
'name' => 'Astro',
'installCommand' => 'npm install',
'buildCommand' => 'npm run build',
'outputDirectory' => './dist',
'buildRuntime' => 'node-22',
'adapter' => 'ssr',
'fallbackFile' => '',
],
'FLUTTER' => [
'key' => 'flutter',
'name' => 'Flutter',
'installCommand' => '',
'buildCommand' => 'flutter build web',
'outputDirectory' => './build/web',
'buildRuntime' => 'flutter-3.29',
'adapter' => 'static',
'fallbackFile' => '',
],
'OTHER' => [
'key' => 'other',
'name' => 'Other',
'installCommand' => 'npm install',
'buildCommand' => 'npm run build',
'buildRuntime' => 'node-22',
'adapter' => 'static',
'fallbackFile' => 'index.html',
],
'VITE' => [
'key' => 'vite',
'name' => 'Vite',
'installCommand' => 'npm install',
'buildCommand' => 'npm run build',
'buildRuntime' => 'node-22',
'adapter' => 'static',
'outputDirectory' => './dist',
],
'REACT' => [
'key' => 'react',
'name' => 'React',
'installCommand' => 'npm install',
'buildCommand' => 'npm run build',
'buildRuntime' => 'node-22',
'adapter' => 'static',
'outputDirectory' => './dist',
'fallbackFile' => 'index.html',
],
'ANGULAR' => [
'key' => 'angular',
'name' => 'Angular',
'installCommand' => 'npm install',
'buildCommand' => 'npm run build',
'buildRuntime' => 'node-22',
'adapter' => 'static',
'outputDirectory' => './dist/angular/browser',
'fallbackFile' => 'index.html',
],
'VUE' => [
'key' => 'vue',
'name' => 'Vue.js',
'installCommand' => 'npm install',
'buildCommand' => 'npm run build',
'buildRuntime' => 'node-22',
'adapter' => 'static',
'outputDirectory' => './dist',
'fallbackFile' => 'index.html',
],
];
function getFramework(string $frameworkEnum, array $overrides)
{
$settings = \array_merge(TEMPLATE_FRAMEWORKS[$frameworkEnum], $overrides);
return $settings;
}
return [
[
'key' => 'template-for-onelink',
'name' => 'Onelink template',
'useCases' => ['starter'],
'screenshotDark' => $url . '/images/sites/templates/template-for-onelink-dark.png',
'screenshotLight' => $url . '/images/sites/templates/template-for-onelink-light.png',
'frameworks' => [
getFramework('NUXT', [
'providerRootDirectory' => './onelink',
'buildCommand' => 'npm run generate',
'outputDirectory' => './dist',
'adapter' => 'static',
]),
],
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'Meldiron',
'providerVersion' => '0.1.*',
'variables' => []
],
[
'key' => 'starter-for-flutter',
'name' => 'Flutter starter',
'useCases' => ['starter'],
'screenshotDark' => $url . '/images/sites/templates/starter-for-flutter-dark.png',
'screenshotLight' => $url . '/images/sites/templates/starter-for-flutter-light.png',
'frameworks' => [
getFramework('FLUTTER', [
'providerRootDirectory' => './',
'buildCommand' => 'sh build.sh',
]),
],
'vcsProvider' => 'github',
'providerRepositoryId' => 'starter-for-flutter',
'providerOwner' => 'appwrite',
'providerVersion' => '0.1.*',
'variables' => [
[
'name' => 'APPWRITE_PUBLIC_ENDPOINT',
'description' => 'Endpoint of Appwrite server',
'value' => '{apiEndpoint}',
'placeholder' => '{apiEndpoint}',
'required' => true,
'type' => 'text'
],
[
'name' => 'APPWRITE_PROJECT_ID',
'description' => 'Your Appwrite project ID',
'value' => '{projectId}',
'placeholder' => '{projectId}',
'required' => true,
'type' => 'text'
],
[
'name' => 'APPWRITE_PROJECT_NAME',
'description' => 'Your Appwrite project name',
'value' => '{projectName}',
'placeholder' => '{projectName}',
'required' => true,
'type' => 'text'
],
]
],
[
'key' => 'starter-for-js',
'name' => 'JavaScript starter',
'useCases' => ['starter'],
'screenshotDark' => $url . '/images/sites/templates/starter-for-js-dark.png',
'screenshotLight' => $url . '/images/sites/templates/starter-for-js-light.png',
'frameworks' => [
getFramework('VITE', [
'providerRootDirectory' => './',
]),
],
'vcsProvider' => 'github',
'providerRepositoryId' => 'starter-for-js',
'providerOwner' => 'appwrite',
'providerVersion' => '0.1.*',
'variables' => [
[
'name' => 'VITE_APPWRITE_ENDPOINT',
'description' => 'Endpoint of Appwrite server',
'value' => '{apiEndpoint}',
'placeholder' => '{apiEndpoint}',
'required' => true,
'type' => 'text'
],
[
'name' => 'VITE_APPWRITE_PROJECT_ID',
'description' => 'Your Appwrite project ID',
'value' => '{projectId}',
'placeholder' => '{projectId}',
'required' => true,
'type' => 'text'
],
[
'name' => 'VITE_APPWRITE_PROJECT_NAME',
'description' => 'Your Appwrite project name',
'value' => '{projectName}',
'placeholder' => '{projectName}',
'required' => true,
'type' => 'text'
],
]
],
[
'key' => 'starter-for-angular',
'name' => 'Angular starter',
'useCases' => ['starter'],
'screenshotDark' => $url . '/images/sites/templates/starter-for-angular-dark.png',
'screenshotLight' => $url . '/images/sites/templates/starter-for-angular-light.png',
'frameworks' => [
getFramework('ANGULAR', [
'providerRootDirectory' => './',
'outputDirectory' => './dist/angular-starter-kit-for-appwrite/browser',
'buildCommand' => 'sh prepare-env.sh && npm run build'
]),
],
'vcsProvider' => 'github',
'providerRepositoryId' => 'starter-for-angular',
'providerOwner' => 'appwrite',
'providerVersion' => '0.1.*',
'variables' => [
[
'name' => 'APPWRITE_ENDPOINT',
'description' => 'Endpoint of Appwrite server',
'value' => '{apiEndpoint}',
'placeholder' => '{apiEndpoint}',
'required' => true,
'type' => 'text'
],
[
'name' => 'APPWRITE_PROJECT_ID',
'description' => 'Your Appwrite project ID',
'value' => '{projectId}',
'placeholder' => '{projectId}',
'required' => true,
'type' => 'text'
],
[
'name' => 'APPWRITE_PROJECT_NAME',
'description' => 'Your Appwrite project name',
'value' => '{projectName}',
'placeholder' => '{projectName}',
'required' => true,
'type' => 'text'
],
]
],
[
'key' => 'starter-for-svelte',
'name' => 'Svelte starter',
'useCases' => ['starter'],
'screenshotDark' => $url . '/images/sites/templates/starter-for-svelte-dark.png',
'screenshotLight' => $url . '/images/sites/templates/starter-for-svelte-light.png',
'frameworks' => [
getFramework('SVELTEKIT', [
'providerRootDirectory' => './',
]),
],
'vcsProvider' => 'github',
'providerRepositoryId' => 'starter-for-svelte',
'providerOwner' => 'appwrite',
'providerVersion' => '0.1.*',
'variables' => [
[
'name' => 'PUBLIC_APPWRITE_ENDPOINT',
'description' => 'Endpoint of Appwrite server',
'value' => '{apiEndpoint}',
'placeholder' => '{apiEndpoint}',
'required' => true,
'type' => 'text'
],
[
'name' => 'PUBLIC_APPWRITE_PROJECT_ID',
'description' => 'Your Appwrite project ID',
'value' => '{projectId}',
'placeholder' => '{projectId}',
'required' => true,
'type' => 'text'
],
[
'name' => 'PUBLIC_APPWRITE_PROJECT_NAME',
'description' => 'Your Appwrite project name',
'value' => '{projectName}',
'placeholder' => '{projectName}',
'required' => true,
'type' => 'text'
],
]
],
[
'key' => 'starter-for-react',
'name' => 'React starter',
'useCases' => ['starter'],
'screenshotDark' => $url . '/images/sites/templates/starter-for-react-dark.png',
'screenshotLight' => $url . '/images/sites/templates/starter-for-react-light.png',
'frameworks' => [
getFramework('REACT', [
'providerRootDirectory' => './',
]),
],
'vcsProvider' => 'github',
'providerRepositoryId' => 'starter-for-react',
'providerOwner' => 'appwrite',
'providerVersion' => '0.1.*',
'variables' => [
[
'name' => 'VITE_APPWRITE_ENDPOINT',
'description' => 'Endpoint of Appwrite server',
'value' => '{apiEndpoint}',
'placeholder' => '{apiEndpoint}',
'required' => true,
'type' => 'text'
],
[
'name' => 'VITE_APPWRITE_PROJECT_ID',
'description' => 'Your Appwrite project ID',
'value' => '{projectId}',
'placeholder' => '{projectId}',
'required' => true,
'type' => 'text'
],
[
'name' => 'VITE_APPWRITE_PROJECT_NAME',
'description' => 'Your Appwrite project name',
'value' => '{projectName}',
'placeholder' => '{projectName}',
'required' => true,
'type' => 'text'
],
]
],
[
'key' => 'starter-for-vue',
'name' => 'Vue starter',
'useCases' => ['starter'],
'screenshotDark' => $url . '/images/sites/templates/starter-for-vue-dark.png',
'screenshotLight' => $url . '/images/sites/templates/starter-for-vue-light.png',
'frameworks' => [
getFramework('VUE', [
'providerRootDirectory' => './',
]),
],
'vcsProvider' => 'github',
'providerRepositoryId' => 'starter-for-vue',
'providerOwner' => 'appwrite',
'providerVersion' => '0.1.*',
'variables' => [
[
'name' => 'VITE_APPWRITE_ENDPOINT',
'description' => 'Endpoint of Appwrite server',
'value' => '{apiEndpoint}',
'placeholder' => '{apiEndpoint}',
'required' => true,
'type' => 'text'
],
[
'name' => 'VITE_APPWRITE_PROJECT_ID',
'description' => 'Your Appwrite project ID',
'value' => '{projectId}',
'placeholder' => '{projectId}',
'required' => true,
'type' => 'text'
],
[
'name' => 'VITE_APPWRITE_PROJECT_NAME',
'description' => 'Your Appwrite project name',
'value' => '{projectName}',
'placeholder' => '{projectName}',
'required' => true,
'type' => 'text'
],
]
],
[
'key' => 'starter-for-react-native',
'name' => 'React Native starter',
'useCases' => ['starter'],
'screenshotDark' => $url . '/images/sites/templates/starter-for-react-native-dark.png',
'screenshotLight' => $url . '/images/sites/templates/starter-for-react-native-light.png',
'frameworks' => [
getFramework('REACT', [
'providerRootDirectory' => './',
'fallbackFile' => '+not-found.html',
]),
],
'vcsProvider' => 'github',
'providerRepositoryId' => 'starter-for-react-native',
'providerOwner' => 'appwrite',
'providerVersion' => '0.1.*',
'variables' => [
[
'name' => 'EXPO_PUBLIC_APPWRITE_ENDPOINT',
'description' => 'Endpoint of Appwrite server',
'value' => '{apiEndpoint}',
'placeholder' => '{apiEndpoint}',
'required' => true,
'type' => 'text'
],
[
'name' => 'EXPO_PUBLIC_APPWRITE_PROJECT_ID',
'description' => 'Your Appwrite project ID',
'value' => '{projectId}',
'placeholder' => '{projectId}',
'required' => true,
'type' => 'text'
],
[
'name' => 'EXPO_PUBLIC_APPWRITE_PROJECT_NAME',
'description' => 'Your Appwrite project name',
'value' => '{projectName}',
'placeholder' => '{projectName}',
'required' => true,
'type' => 'text'
],
]
],
[
'key' => 'starter-for-nextjs',
'name' => 'Next.js starter',
'useCases' => ['starter'],
'screenshotDark' => $url . '/images/sites/templates/starter-for-nextjs-dark.png',
'screenshotLight' => $url . '/images/sites/templates/starter-for-nextjs-light.png',
'frameworks' => [
getFramework('NEXTJS', [
'providerRootDirectory' => './',
]),
],
'vcsProvider' => 'github',
'providerRepositoryId' => 'starter-for-nextjs',
'providerOwner' => 'appwrite',
'providerVersion' => '0.1.*',
'variables' => [
[
'name' => 'NEXT_PUBLIC_APPWRITE_ENDPOINT',
'description' => 'Endpoint of Appwrite server',
'value' => '{apiEndpoint}',
'placeholder' => '{apiEndpoint}',
'required' => true,
'type' => 'text'
],
[
'name' => 'NEXT_PUBLIC_APPWRITE_PROJECT_ID',
'description' => 'Your Appwrite project ID',
'value' => '{projectId}',
'placeholder' => '{projectId}',
'required' => true,
'type' => 'text'
],
[
'name' => 'NEXT_PUBLIC_APPWRITE_PROJECT_NAME',
'description' => 'Your Appwrite project name',
'value' => '{projectName}',
'placeholder' => '{projectName}',
'required' => true,
'type' => 'text'
],
]
],
[
'key' => 'starter-for-nuxt',
'name' => 'Nuxt starter',
'useCases' => ['starter'],
'screenshotDark' => $url . '/images/sites/templates/starter-for-nuxt-dark.png',
'screenshotLight' => $url . '/images/sites/templates/starter-for-nuxt-light.png',
'frameworks' => [
getFramework('NUXT', [
'providerRootDirectory' => './',
]),
],
'vcsProvider' => 'github',
'providerRepositoryId' => 'starter-for-nuxt',
'providerOwner' => 'appwrite',
'providerVersion' => '0.1.*',
'variables' => [
[
'name' => 'NUXT_PUBLIC_APPWRITE_ENDPOINT',
'description' => 'Endpoint of Appwrite server',
'value' => '{apiEndpoint}',
'placeholder' => '{apiEndpoint}',
'required' => true,
'type' => 'text'
],
[
'name' => 'NUXT_PUBLIC_APPWRITE_PROJECT_ID',
'description' => 'Your Appwrite project ID',
'value' => '{projectId}',
'placeholder' => '{projectId}',
'required' => true,
'type' => 'text'
],
[
'name' => 'NUXT_PUBLIC_APPWRITE_PROJECT_NAME',
'description' => 'Your Appwrite project name',
'value' => '{projectName}',
'placeholder' => '{projectName}',
'required' => true,
'type' => 'text'
],
]
],
[
'key' => 'template-for-event',
'name' => 'Event template',
'useCases' => ['starter'],
'screenshotDark' => $url . '/images/sites/templates/template-for-event-dark.png',
'screenshotLight' => $url . '/images/sites/templates/template-for-event-light.png',
'frameworks' => [
getFramework('NEXTJS', [
'providerRootDirectory' => './',
'installCommand' => 'pnpm install',
'buildCommand' => 'npm run build',
]),
],
'vcsProvider' => 'github',
'providerRepositoryId' => 'template-for-event',
'providerOwner' => 'appwrite',
'providerVersion' => '0.1.*',
'variables' => [
[
'name' => 'NEXT_PUBLIC_APPWRITE_FUNCTION_PROJECT_ID',
'description' => 'Endpoint of Appwrite server',
'value' => '{apiEndpoint}',
'placeholder' => '{apiEndpoint}',
'required' => true,
'type' => 'text'
],
[
'name' => 'NEXT_PUBLIC_APPWRITE_FUNCTION_API_ENDPOINT',
'description' => 'Your Appwrite project ID',
'value' => '{projectId}',
'placeholder' => '{projectId}',
'required' => true,
'type' => 'text'
],
]
],
[
'key' => 'template-for-portfolio',
'name' => 'Portfolio template',
'useCases' => ['starter'],
'screenshotDark' => $url . '/images/sites/templates/template-for-portfolio-dark.png',
'screenshotLight' => $url . '/images/sites/templates/template-for-portfolio-light.png',
'frameworks' => [
getFramework('NEXTJS', [
'providerRootDirectory' => './',
]),
],
'vcsProvider' => 'github',
'providerRepositoryId' => 'template-for-portfolio',
'providerOwner' => 'appwrite',
'providerVersion' => '0.1.*',
'variables' => []
],
[
'key' => 'template-for-store',
'name' => 'Store template',
'useCases' => ['starter'],
'screenshotDark' => $url . '/images/sites/templates/template-for-store-dark.png',
'screenshotLight' => $url . '/images/sites/templates/template-for-store-light.png',
'frameworks' => [
getFramework('SVELTEKIT', [
'providerRootDirectory' => './',
]),
],
'vcsProvider' => 'github',
'providerRepositoryId' => 'template-for-store',
'providerOwner' => 'appwrite',
'providerVersion' => '0.1.*',
'variables' => [
[
'name' => 'STRIPE_SECRET_KEY',
'description' => 'Your Stripe secret key',
'value' => 'disabled',
'placeholder' => 'sk_.....',
'required' => false,
'type' => 'password'
],
[
'name' => 'PUBLIC_APPWRITE_ENDPOINT',
'description' => 'Endpoint of Appwrite server',
'value' => '{apiEndpoint}',
'placeholder' => '{apiEndpoint}',
'required' => true,
'type' => 'text'
],
[
'name' => 'PUBLIC_APPWRITE_PROJECT_ID',
'description' => 'Your Appwrite project ID',
'value' => '{projectId}',
'placeholder' => '{projectId}',
'required' => true,
'type' => 'text'
],
]
],
[
'key' => 'template-for-blog',
'name' => 'Blog template',
'useCases' => ['starter'],
'screenshotDark' => $url . '/images/sites/templates/template-for-blog-dark.png',
'screenshotLight' => $url . '/images/sites/templates/template-for-blog-light.png',
'frameworks' => [
getFramework('SVELTEKIT', [
'providerRootDirectory' => './',
]),
],
'vcsProvider' => 'github',
'providerRepositoryId' => 'template-for-blog',
'providerOwner' => 'appwrite',
'providerVersion' => '0.1.*',
'variables' => []
],
[
'key' => 'astro-starter',
'name' => 'Astro starter',
'useCases' => ['starter'],
'screenshotDark' => $url . '/images/sites/templates/astro-starter-dark.png',
'screenshotLight' => $url . '/images/sites/templates/astro-starter-light.png',
'frameworks' => [
getFramework('ASTRO', [
'providerRootDirectory' => './astro/starter',
]),
],
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.2.*',
'variables' => [],
],
[
'key' => 'remix-starter',
'name' => 'Remix starter',
'useCases' => ['starter'],
'screenshotDark' => $url . '/images/sites/templates/remix-starter-dark.png',
'screenshotLight' => $url . '/images/sites/templates/remix-starter-light.png',
'frameworks' => [
getFramework('REMIX', [
'providerRootDirectory' => './remix/starter',
]),
],
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.2.*',
'variables' => [],
],
[
'key' => 'flutter-starter',
'name' => 'Flutter starter',
'useCases' => ['starter'],
'screenshotDark' => $url . '/images/sites/templates/flutter-starter-dark.png',
'screenshotLight' => $url . '/images/sites/templates/flutter-starter-light.png',
'frameworks' => [
getFramework('FLUTTER', [
'providerRootDirectory' => './flutter/starter',
]),
],
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.2.*',
'variables' => [],
],
[
'key' => 'nextjs-starter',
'name' => 'Next.js starter website',
'useCases' => ['starter'],
'screenshotDark' => $url . '/images/sites/templates/nextjs-starter-dark.png',
'screenshotLight' => $url . '/images/sites/templates/nextjs-starter-light.png',
'frameworks' => [
getFramework('NEXTJS', [
'providerRootDirectory' => './nextjs/starter',
]),
],
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.2.*',
'variables' => [],
],
[
'key' => 'nuxt-starter',
'name' => 'Nuxt starter website',
'useCases' => ['starter'],
'screenshotDark' => $url . '/images/sites/templates/nuxt-starter-dark.png',
'screenshotLight' => $url . '/images/sites/templates/nuxt-starter-light.png',
'frameworks' => [
getFramework('NUXT', [
'providerRootDirectory' => './nuxt/starter',
]),
],
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.2.*',
'variables' => [],
],
[
'key' => 'sveltekit-starter',
'name' => 'SvelteKit starter website',
'useCases' => ['starter'],
'screenshotDark' => $url . '/images/sites/templates/sveltekit-starter-dark.png',
'screenshotLight' => $url . '/images/sites/templates/sveltekit-starter-light.png',
'frameworks' => [
getFramework('SVELTEKIT', [
'providerRootDirectory' => './sveltekit/starter',
]),
],
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates-for-sites',
'providerOwner' => 'appwrite',
'providerVersion' => '0.2.*',
'variables' => [],
],
];
+5 -2
View File
@@ -56,11 +56,14 @@ App::get('/v1/console/variables')
$variables = new Document([
'_APP_DOMAIN_TARGET' => System::getEnv('_APP_DOMAIN_TARGET'),
'_APP_STORAGE_LIMIT' => +System::getEnv('_APP_STORAGE_LIMIT'),
'_APP_FUNCTIONS_SIZE_LIMIT' => +System::getEnv('_APP_FUNCTIONS_SIZE_LIMIT'),
'_APP_COMPUTE_SIZE_LIMIT' => +System::getEnv('_APP_COMPUTE_SIZE_LIMIT'),
'_APP_USAGE_STATS' => System::getEnv('_APP_USAGE_STATS'),
'_APP_VCS_ENABLED' => $isVcsEnabled,
'_APP_DOMAIN_ENABLED' => $isDomainEnabled,
'_APP_ASSISTANT_ENABLED' => $isAssistantEnabled
'_APP_ASSISTANT_ENABLED' => $isAssistantEnabled,
'_APP_DOMAIN_SITES' => System::getEnv('_APP_DOMAIN_SITES'),
'_APP_OPTIONS_FORCE_HTTPS' => System::getEnv('_APP_OPTIONS_FORCE_HTTPS'),
'_APP_DOMAINS_NAMESERVERS' => System::getEnv('_APP_DOMAINS_NAMESERVERS'),
]);
$response->dynamic($variables, Response::MODEL_CONSOLE_VARIABLES);
File diff suppressed because it is too large Load Diff
+3 -2
View File
@@ -857,9 +857,10 @@ App::get('/v1/health/storage')
->inject('response')
->inject('deviceForFiles')
->inject('deviceForFunctions')
->inject('deviceForSites')
->inject('deviceForBuilds')
->action(function (Response $response, Device $deviceForFiles, Device $deviceForFunctions, Device $deviceForBuilds) {
$devices = [$deviceForFiles, $deviceForFunctions, $deviceForBuilds];
->action(function (Response $response, Device $deviceForFiles, Device $deviceForFunctions, Device $deviceForSites, Device $deviceForBuilds) {
$devices = [$deviceForFiles, $deviceForFunctions, $deviceForSites, $deviceForBuilds];
$checkStart = \microtime(true);
foreach ($devices as $device) {
+11 -2
View File
@@ -17,6 +17,7 @@ use Utopia\Database\Query;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Datetime as DateTimeValidator;
use Utopia\Database\Validator\UID;
use Utopia\Validator\Boolean;
use Utopia\Validator\Text;
use Utopia\Validator\WhiteList;
@@ -399,11 +400,12 @@ App::post('/v1/project/variables')
))
->param('key', null, new Text(Database::LENGTH_KEY), 'Variable key. Max length: ' . Database::LENGTH_KEY . ' chars.', false)
->param('value', null, new Text(8192, 0), 'Variable value. Max length: 8192 chars.', false)
->param('secret', true, new Boolean(), 'Secret variables can be updated or deleted, but only projects can read them during build and runtime.', true)
->inject('project')
->inject('response')
->inject('dbForProject')
->inject('dbForPlatform')
->action(function (string $key, string $value, Document $project, Response $response, Database $dbForProject, Database $dbForPlatform) {
->action(function (string $key, string $value, bool $secret, Document $project, Response $response, Database $dbForProject, Database $dbForPlatform) {
$variableId = ID::unique();
$variable = new Document([
@@ -418,6 +420,7 @@ App::post('/v1/project/variables')
'resourceType' => 'project',
'key' => $key,
'value' => $value,
'secret' => $secret,
'search' => implode(' ', [$variableId, $key, 'project']),
]);
@@ -518,19 +521,25 @@ App::put('/v1/project/variables/:variableId')
->param('variableId', '', new UID(), 'Variable unique ID.', false)
->param('key', null, new Text(255), 'Variable key. Max length: 255 chars.', false)
->param('value', null, new Text(8192, 0), 'Variable value. Max length: 8192 chars.', true)
->param('secret', null, new Boolean(), 'Secret variables can be updated or deleted, but only projects can read them during build and runtime.', true)
->inject('project')
->inject('response')
->inject('dbForProject')
->inject('dbForPlatform')
->action(function (string $variableId, string $key, ?string $value, Document $project, Response $response, Database $dbForProject, Database $dbForPlatform) {
->action(function (string $variableId, string $key, ?string $value, ?bool $secret, Document $project, Response $response, Database $dbForProject, Database $dbForPlatform) {
$variable = $dbForProject->getDocument('variables', $variableId);
if ($variable === false || $variable->isEmpty() || $variable->getAttribute('resourceType') !== 'project') {
throw new Exception(Exception::VARIABLE_NOT_FOUND);
}
if ($variable->getAttribute('secret') === true && $secret === false) {
throw new Exception(Exception::VARIABLE_CANNOT_UNSET_SECRET);
}
$variable
->setAttribute('key', $key)
->setAttribute('value', $value ?? $variable->getAttribute('value'))
->setAttribute('secret', $secret ?? $variable->getAttribute('secret'))
->setAttribute('search', implode(' ', [$variableId, $key, 'project']));
try {
-142
View File
@@ -15,155 +15,13 @@ use Utopia\App;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Exception\Query as QueryException;
use Utopia\Database\Helpers\ID;
use Utopia\Database\Query;
use Utopia\Database\Validator\Query\Cursor;
use Utopia\Database\Validator\UID;
use Utopia\Domains\Domain;
use Utopia\Logger\Log;
use Utopia\System\System;
use Utopia\Validator\Domain as ValidatorDomain;
use Utopia\Validator\Text;
use Utopia\Validator\WhiteList;
App::post('/v1/proxy/rules')
->groups(['api', 'proxy'])
->desc('Create rule')
->label('scope', 'rules.write')
->label('event', 'rules.[ruleId].create')
->label('audits.event', 'rule.create')
->label('audits.resource', 'rule/{response.$id}')
->label('sdk', new Method(
namespace: 'proxy',
name: 'createRule',
description: '/docs/references/proxy/create-rule.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_CREATED,
model: Response::MODEL_PROXY_RULE,
)
]
))
->param('domain', null, new ValidatorDomain(), 'Domain name.')
->param('resourceType', null, new WhiteList(['api', 'function']), 'Action definition for the rule. Possible values are "api", "function"')
->param('resourceId', '', new UID(), 'ID of resource for the action type. If resourceType is "api", leave empty. If resourceType is "function", provide ID of the function.', true)
->inject('response')
->inject('project')
->inject('queueForCertificates')
->inject('queueForEvents')
->inject('dbForPlatform')
->inject('dbForProject')
->action(function (string $domain, string $resourceType, string $resourceId, Response $response, Document $project, Certificate $queueForCertificates, Event $queueForEvents, Database $dbForPlatform, Database $dbForProject) {
$mainDomain = System::getEnv('_APP_DOMAIN', '');
if ($domain === $mainDomain) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'You cannot assign your main domain to specific resource. Please use subdomain or a different domain.');
}
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
if ($functionsDomain != '' && str_ends_with($domain, $functionsDomain)) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'You cannot assign your functions domain or it\'s subdomain to specific resource. Please use different domain.');
}
if ($domain === 'localhost' || $domain === APP_HOSTNAME_INTERNAL) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'This domain name is not allowed. Please pick another one.');
}
// TODO: @christyjacob remove once we migrate the rules in 1.7.x
if (System::getEnv('_APP_RULES_FORMAT') === 'md5') {
$document = $dbForPlatform->getDocument('rules', md5($domain));
} else {
$document = $dbForPlatform->findOne('rules', [
Query::equal('domain', [$domain]),
]);
}
if (!$document->isEmpty()) {
if ($document->getAttribute('projectId') === $project->getId()) {
$resourceType = $document->getAttribute('resourceType');
$resourceId = $document->getAttribute('resourceId');
$message = "Domain already assigned to '{$resourceType}' service";
if (!empty($resourceId)) {
$message .= " with ID '{$resourceId}'";
}
$message .= '.';
} else {
$message = 'Domain already assigned to different project.';
}
throw new Exception(Exception::RULE_ALREADY_EXISTS, $message);
}
$resourceInternalId = '';
if ($resourceType == 'function') {
if (empty($resourceId)) {
throw new Exception(Exception::FUNCTION_NOT_FOUND);
}
$function = $dbForProject->getDocument('functions', $resourceId);
if ($function->isEmpty()) {
throw new Exception(Exception::RULE_RESOURCE_NOT_FOUND);
}
$resourceInternalId = $function->getInternalId();
}
try {
$domain = new Domain($domain);
} catch (\Throwable) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Domain may not start with http:// or https://.');
}
// TODO: @christyjacob remove once we migrate the rules in 1.7.x
$ruleId = System::getEnv('_APP_RULES_FORMAT') === 'md5' ? md5($domain->get()) : ID::unique();
$rule = new Document([
'$id' => $ruleId,
'projectId' => $project->getId(),
'projectInternalId' => $project->getInternalId(),
'domain' => $domain->get(),
'resourceType' => $resourceType,
'resourceId' => $resourceId,
'resourceInternalId' => $resourceInternalId,
'certificateId' => '',
]);
$status = 'created';
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS');
if (!empty($functionsDomain) && \str_ends_with($domain->get(), $functionsDomain)) {
$status = 'verified';
}
if ($status === 'created') {
$target = new Domain(System::getEnv('_APP_DOMAIN_TARGET', ''));
$validator = new CNAME($target->get()); // Verify Domain with DNS records
if ($validator->isValid($domain->get())) {
$status = 'verifying';
$queueForCertificates
->setDomain(new Document([
'domain' => $rule->getAttribute('domain')
]))
->trigger();
}
}
$rule->setAttribute('status', $status);
$rule = $dbForPlatform->createDocument('rules', $rule);
$queueForEvents->setParam('ruleId', $rule->getId());
$rule->setAttribute('logs', '');
$response
->setStatusCode(Response::STATUS_CODE_CREATED)
->dynamic($rule, Response::MODEL_PROXY_RULE);
});
App::get('/v1/proxy/rules')
->groups(['api', 'proxy'])
+353 -108
View File
@@ -14,11 +14,11 @@ use Appwrite\Utopia\Request;
use Appwrite\Utopia\Response;
use Appwrite\Vcs\Comment;
use Utopia\App;
use Utopia\CLI\Console;
use Utopia\Config\Config;
use Utopia\Database\Database;
use Utopia\Database\DateTime;
use Utopia\Database\Document;
use Utopia\Database\Exception\Duplicate;
use Utopia\Database\Exception\Query as QueryException;
use Utopia\Database\Helpers\ID;
use Utopia\Database\Helpers\Permission;
@@ -26,22 +26,35 @@ use Utopia\Database\Helpers\Role;
use Utopia\Database\Query;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Query\Cursor;
use Utopia\Detector\Adapter\Bun;
use Utopia\Detector\Adapter\CPP;
use Utopia\Detector\Adapter\Dart;
use Utopia\Detector\Adapter\Deno;
use Utopia\Detector\Adapter\Dotnet;
use Utopia\Detector\Adapter\Java;
use Utopia\Detector\Adapter\JavaScript;
use Utopia\Detector\Adapter\PHP;
use Utopia\Detector\Adapter\Python;
use Utopia\Detector\Adapter\Ruby;
use Utopia\Detector\Adapter\Swift;
use Utopia\Detector\Detector;
use Utopia\Detector\Detection\Framework\Astro;
use Utopia\Detector\Detection\Framework\Flutter;
use Utopia\Detector\Detection\Framework\NextJs;
use Utopia\Detector\Detection\Framework\Nuxt;
use Utopia\Detector\Detection\Framework\Remix;
use Utopia\Detector\Detection\Framework\SvelteKit;
use Utopia\Detector\Detection\Packager\NPM;
use Utopia\Detector\Detection\Packager\PNPM;
use Utopia\Detector\Detection\Packager\Yarn;
use Utopia\Detector\Detection\Runtime\Bun;
use Utopia\Detector\Detection\Runtime\CPP;
use Utopia\Detector\Detection\Runtime\Dart;
use Utopia\Detector\Detection\Runtime\Deno;
use Utopia\Detector\Detection\Runtime\Dotnet;
use Utopia\Detector\Detection\Runtime\Java;
use Utopia\Detector\Detection\Runtime\Node;
use Utopia\Detector\Detection\Runtime\PHP;
use Utopia\Detector\Detection\Runtime\Python;
use Utopia\Detector\Detection\Runtime\Ruby;
use Utopia\Detector\Detection\Runtime\Swift;
use Utopia\Detector\Detector\Framework;
use Utopia\Detector\Detector\Packager;
use Utopia\Detector\Detector\Runtime;
use Utopia\Detector\Detector\Strategy;
use Utopia\System\System;
use Utopia\Validator\Boolean;
use Utopia\Validator\Host;
use Utopia\Validator\Text;
use Utopia\Validator\WhiteList;
use Utopia\VCS\Adapter\Git\GitHub;
use Utopia\VCS\Exception\RepositoryNotFound;
@@ -49,29 +62,30 @@ use function Swoole\Coroutine\batch;
$createGitDeployments = function (GitHub $github, string $providerInstallationId, array $repositories, string $providerBranch, string $providerBranchUrl, string $providerRepositoryName, string $providerRepositoryUrl, string $providerRepositoryOwner, string $providerCommitHash, string $providerCommitAuthor, string $providerCommitAuthorUrl, string $providerCommitMessage, string $providerCommitUrl, string $providerPullRequestId, bool $external, Database $dbForPlatform, Build $queueForBuilds, callable $getProjectDB, Request $request) {
$errors = [];
foreach ($repositories as $resource) {
foreach ($repositories as $repository) {
try {
$resourceType = $resource->getAttribute('resourceType');
$resourceType = $repository->getAttribute('resourceType');
if ($resourceType !== "function") {
if ($resourceType !== "function" && $resourceType !== "site") {
continue;
}
$projectId = $resource->getAttribute('projectId');
$projectId = $repository->getAttribute('projectId');
$project = Authorization::skip(fn () => $dbForPlatform->getDocument('projects', $projectId));
$dbForProject = $getProjectDB($project);
$functionId = $resource->getAttribute('resourceId');
$function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId));
$functionInternalId = $function->getInternalId();
$resourceCollection = $resourceType === "function" ? 'functions' : 'sites';
$resourceId = $repository->getAttribute('resourceId');
$resource = Authorization::skip(fn () => $dbForProject->getDocument($resourceCollection, $resourceId));
$resourceInternalId = $resource->getInternalId();
$deploymentId = ID::unique();
$repositoryId = $resource->getId();
$repositoryInternalId = $resource->getInternalId();
$providerRepositoryId = $resource->getAttribute('providerRepositoryId');
$installationId = $resource->getAttribute('installationId');
$installationInternalId = $resource->getAttribute('installationInternalId');
$productionBranch = $function->getAttribute('providerBranch');
$repositoryId = $repository->getId();
$repositoryInternalId = $repository->getInternalId();
$providerRepositoryId = $repository->getAttribute('providerRepositoryId');
$installationId = $repository->getAttribute('installationId');
$installationInternalId = $repository->getAttribute('installationInternalId');
$productionBranch = $resource->getAttribute('providerBranch');
$activate = false;
if ($providerBranch == $productionBranch && $external === false) {
@@ -95,7 +109,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
$isAuthorized = !$external;
if (!$isAuthorized && !empty($providerPullRequestId)) {
if (\in_array($providerPullRequestId, $resource->getAttribute('providerPullRequestIds', []))) {
if (\in_array($providerPullRequestId, $repository->getAttribute('providerPullRequestIds', []))) {
$isAuthorized = true;
}
}
@@ -108,7 +122,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
$latestCommentId = '';
if (!empty($providerPullRequestId) && $function->getAttribute('providerSilentMode', false) === false) {
if (!empty($providerPullRequestId) && $resource->getAttribute('providerSilentMode', false) === false) {
$latestComment = Authorization::skip(fn () => $dbForPlatform->findOne('vcsComments', [
Query::equal('providerRepositoryId', [$providerRepositoryId]),
Query::equal('providerPullRequestId', [$providerPullRequestId]),
@@ -117,14 +131,15 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
if (!$latestComment->isEmpty()) {
$latestCommentId = $latestComment->getAttribute('providerCommentId', '');
$comment = new Comment();
$comment->parseComment($github->getComment($owner, $repositoryName, $latestCommentId));
$comment->addBuild($project, $function, $commentStatus, $deploymentId, $action);
$comment->addBuild($project, $resource, $resourceType, $commentStatus, $deploymentId, $action, '', '');
$latestCommentId = \strval($github->updateComment($owner, $repositoryName, $latestCommentId, $comment->generateComment()));
} else {
$comment = new Comment();
$comment->addBuild($project, $function, $commentStatus, $deploymentId, $action);
$comment->addBuild($project, $resource, $resourceType, $commentStatus, $deploymentId, $action, '', '');
$latestCommentId = \strval($github->createComment($owner, $repositoryName, $providerPullRequestId, $comment->generateComment()));
if (!empty($latestCommentId)) {
@@ -161,19 +176,19 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
$latestCommentId = $comment->getAttribute('providerCommentId', '');
$comment = new Comment();
$comment->parseComment($github->getComment($owner, $repositoryName, $latestCommentId));
$comment->addBuild($project, $function, $commentStatus, $deploymentId, $action);
$comment->addBuild($project, $resource, $resourceType, $commentStatus, $deploymentId, $action, '', '');
$latestCommentId = \strval($github->updateComment($owner, $repositoryName, $latestCommentId, $comment->generateComment()));
}
}
if (!$isAuthorized) {
$functionName = $function->getAttribute('name');
$resourceName = $resource->getAttribute('name');
$projectName = $project->getAttribute('name');
$name = "{$functionName} ({$projectName})";
$name = "{$resourceName} ({$projectName})";
$message = 'Authorization required for external contributor.';
$providerRepositoryId = $resource->getAttribute('providerRepositoryId');
$providerRepositoryId = $repository->getAttribute('providerRepositoryId');
try {
$repositoryName = $github->getRepositoryName($providerRepositoryId) ?? '';
if (empty($repositoryName)) {
@@ -193,6 +208,17 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
$providerRepositoryOwner = $pullRequestResponse['head']['repo']['name'];
}
$commands = [];
if (!empty($resource->getAttribute('installCommand', ''))) {
$commands[] = $resource->getAttribute('installCommand', '');
}
if (!empty($resource->getAttribute('buildCommand', ''))) {
$commands[] = $resource->getAttribute('buildCommand', '');
}
if (!empty($resource->getAttribute('commands', ''))) {
$commands[] = $resource->getAttribute('commands', '');
}
$deployment = $dbForProject->createDocument('deployments', new Document([
'$id' => $deploymentId,
'$permissions' => [
@@ -200,11 +226,12 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
Permission::update(Role::any()),
Permission::delete(Role::any()),
],
'resourceId' => $functionId,
'resourceInternalId' => $functionInternalId,
'resourceType' => 'functions',
'entrypoint' => $function->getAttribute('entrypoint'),
'commands' => $function->getAttribute('commands'),
'resourceId' => $resourceId,
'resourceInternalId' => $resourceInternalId,
'resourceType' => $resourceCollection,
'entrypoint' => $resource->getAttribute('entrypoint', ''),
'buildCommands' => \implode(' && ', $commands),
'buildOutput' => $resource->getAttribute('outputDirectory', ''),
'type' => 'vcs',
'installationId' => $installationId,
'installationInternalId' => $installationInternalId,
@@ -218,21 +245,107 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
'providerCommitHash' => $providerCommitHash,
'providerCommitAuthorUrl' => $providerCommitAuthorUrl,
'providerCommitAuthor' => $providerCommitAuthor,
'providerCommitMessage' => $providerCommitMessage,
'providerCommitMessage' => mb_strimwidth($providerCommitMessage, 0, 255, '...'),
'providerCommitUrl' => $providerCommitUrl,
'providerCommentId' => \strval($latestCommentId),
'providerBranch' => $providerBranch,
'search' => implode(' ', [$deploymentId, $function->getAttribute('entrypoint')]),
'search' => implode(' ', [$deploymentId, $resource->getAttribute('entrypoint', '')]),
'activate' => $activate,
]));
if (!empty($providerCommitHash) && $function->getAttribute('providerSilentMode', false) === false) {
$functionName = $function->getAttribute('name');
if ($resource->getCollection() === 'sites') {
$projectId = $project->getId();
// Deployment preview
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
$domain = ID::unique() . "." . $sitesDomain;
$ruleId = md5($domain);
Authorization::skip(
fn () => $dbForPlatform->createDocument('rules', new Document([
'$id' => $ruleId,
'projectId' => $project->getId(),
'projectInternalId' => $project->getInternalId(),
'domain' => $domain,
'type' => 'deployment',
'trigger' => 'deployment',
'deploymentId' => $deployment->getId(),
'deploymentInternalId' => $deployment->getInternalId(),
'deploymentResourceType' => 'site',
'deploymentResourceId' => $resourceId,
'deploymentResourceInternalId' => $resourceInternalId,
'deploymentVcsProviderBranch' => $providerBranch,
'status' => 'verified',
'certificateId' => '',
'search' => implode(' ', [$ruleId, $domain]),
]))
);
// VCS branch preview
if (!empty($providerBranch)) {
$domain = "branch-{$providerBranch}-{$resource->getId()}-{$project->getId()}.{$sitesDomain}";
$ruleId = md5($domain);
try {
Authorization::skip(
fn () => $dbForPlatform->createDocument('rules', new Document([
'$id' => $ruleId,
'projectId' => $project->getId(),
'projectInternalId' => $project->getInternalId(),
'domain' => $domain,
'type' => 'deployment',
'trigger' => 'deployment',
'deploymentId' => $deployment->getId(),
'deploymentInternalId' => $deployment->getInternalId(),
'deploymentResourceType' => 'site',
'deploymentResourceId' => $resourceId,
'deploymentResourceInternalId' => $resourceInternalId,
'deploymentVcsProviderBranch' => $providerBranch,
'status' => 'verified',
'certificateId' => '',
'search' => implode(' ', [$ruleId, $domain]),
]))
);
} catch (Duplicate $err) {
// Ignore, rule already exists; will be updated by builds worker
}
}
// VCS commit preview
if (!empty($providerCommitHash)) {
$domain = "commit-{$providerCommitHash}-{$resource->getId()}-{$project->getId()}.{$sitesDomain}";
$ruleId = md5($domain);
try {
Authorization::skip(
fn () => $dbForPlatform->createDocument('rules', new Document([
'$id' => $ruleId,
'projectId' => $project->getId(),
'projectInternalId' => $project->getInternalId(),
'domain' => $domain,
'type' => 'deployment',
'trigger' => 'deployment',
'deploymentId' => $deployment->getId(),
'deploymentInternalId' => $deployment->getInternalId(),
'deploymentResourceType' => 'site',
'deploymentResourceId' => $resourceId,
'deploymentResourceInternalId' => $resourceInternalId,
'deploymentVcsProviderBranch' => $providerBranch,
'status' => 'verified',
'certificateId' => '',
'search' => implode(' ', [$ruleId, $domain]),
]))
);
} catch (Duplicate $err) {
// Ignore, rule already exists; will be updated by builds worker
}
}
}
if (!empty($providerCommitHash) && $resource->getAttribute('providerSilentMode', false) === false) {
$resourceName = $resource->getAttribute('name');
$projectName = $project->getAttribute('name');
$name = "{$functionName} ({$projectName})";
$name = "{$resourceName} ({$projectName})";
$message = 'Starting...';
$providerRepositoryId = $resource->getAttribute('providerRepositoryId');
$providerRepositoryId = $repository->getAttribute('providerRepositoryId');
try {
$repositoryName = $github->getRepositoryName($providerRepositoryId) ?? '';
if (empty($repositoryName)) {
@@ -243,17 +356,17 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
}
$owner = $github->getOwnerName($providerInstallationId);
$providerTargetUrl = $request->getProtocol() . '://' . $request->getHostname() . "/console/project-$projectId/functions/function-$functionId";
$providerTargetUrl = $request->getProtocol() . '://' . $request->getHostname() . "/console/project-$projectId/$resourceCollection/$resourceType-$resourceId";
$github->updateCommitStatus($repositoryName, $providerCommitHash, $owner, 'pending', $message, $providerTargetUrl, $name);
}
$queueForBuilds
->setType(BUILD_TYPE_DEPLOYMENT)
->setResource($function)
->setResource($resource)
->setDeployment($deployment)
->setProject($project); // set the project because it won't be set for git deployments
$queueForBuilds->trigger(); // must trigger here so that we create a build for each function
$queueForBuilds->trigger(); // must trigger here so that we create a build for each function/site
//TODO: Add event?
} catch (Throwable $e) {
@@ -516,8 +629,9 @@ App::get('/v1/vcs/github/installations/:installationId/providerRepositories/:pro
]), Response::MODEL_VCS_CONTENT_LIST);
});
App::post('/v1/vcs/github/installations/:installationId/providerRepositories/:providerRepositoryId/detection')
->desc('Detect runtime settings from source code')
App::post('/v1/vcs/github/installations/:installationId/detections')
->alias('/v1/vcs/github/installations/:installationId/providerRepositories/:providerRepositoryId/detection')
->desc('Create repository detection')
->groups(['api', 'vcs'])
->label('scope', 'vcs.write')
->label('sdk', new Method(
@@ -528,18 +642,22 @@ App::post('/v1/vcs/github/installations/:installationId/providerRepositories/:pr
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_DETECTION,
model: Response::MODEL_DETECTION_RUNTIME,
),
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_DETECTION_FRAMEWORK,
)
]
))
->param('installationId', '', new Text(256), 'Installation Id')
->param('providerRepositoryId', '', new Text(256), 'Repository Id')
->param('type', '', new WhiteList(['runtime', 'framework']), 'Detector type. Must be one of the following: runtime, framework')
->param('providerRootDirectory', '', new Text(256, 0), 'Path to Root Directory', true)
->inject('gitHub')
->inject('response')
->inject('project')
->inject('dbForPlatform')
->action(function (string $installationId, string $providerRepositoryId, string $providerRootDirectory, GitHub $github, Response $response, Document $project, Database $dbForPlatform) {
->action(function (string $installationId, string $providerRepositoryId, string $type, string $providerRootDirectory, GitHub $github, Response $response, Database $dbForPlatform) {
$installation = $dbForPlatform->getDocument('installations', $installationId);
if ($installation->isEmpty()) {
@@ -565,32 +683,108 @@ App::post('/v1/vcs/github/installations/:installationId/providerRepositories/:pr
$files = \array_column($files, 'name');
$languages = $github->listRepositoryLanguages($owner, $repositoryName);
$detectorFactory = new Detector($files, $languages);
$detector = new Packager($files);
$detector
->addOption(new Yarn())
->addOption(new PNPM())
->addOption(new NPM());
$detection = $detector->detect();
$detectorFactory
->addDetector(new JavaScript())
->addDetector(new Bun())
->addDetector(new PHP())
->addDetector(new Python())
->addDetector(new Dart())
->addDetector(new Swift())
->addDetector(new Ruby())
->addDetector(new Java())
->addDetector(new CPP())
->addDetector(new Deno())
->addDetector(new Dotnet());
$packager = !\is_null($detection) ? $detection->getName() : 'npm';
$runtime = $detectorFactory->detect();
if ($type === 'framework') {
$output = new Document([
'framework' => '',
'installCommand' => '',
'buildCommand' => '',
'outputDirectory' => '',
]);
$runtimes = Config::getParam('runtimes');
$runtimeDetail = \array_reverse(\array_filter(\array_keys($runtimes), function ($key) use ($runtime, $runtimes) {
return $runtimes[$key]['key'] === $runtime;
}))[0] ?? '';
$detector = new Framework($files, $packager);
$detector
->addOption(new Flutter())
->addOption(new Nuxt())
->addOption(new Astro())
->addOption(new SvelteKit())
->addOption(new NextJs())
->addOption(new Remix());
$detection = [];
$detection['runtime'] = $runtimeDetail;
$framework = $detector->detect();
$response->dynamic(new Document($detection), Response::MODEL_DETECTION);
if (!\is_null($framework)) {
$output->setAttribute('installCommand', $framework->getInstallCommand());
$output->setAttribute('buildCommand', $framework->getBuildCommand());
$output->setAttribute('outputDirectory', $framework->getOutputDirectory());
$framework = $framework->getName();
} else {
$framework = 'other';
$output->setAttribute('installCommand', '');
$output->setAttribute('buildCommand', '');
$output->setAttribute('outputDirectory', '');
}
$frameworks = Config::getParam('frameworks');
if (!\in_array($framework, array_keys($frameworks), true)) {
$framework = 'other';
}
$output->setAttribute('framework', $framework);
} else {
$output = new Document([
'runtime' => '',
'commands' => '',
'entrypoint' => '',
]);
$strategies = [
new Strategy(Strategy::FILEMATCH),
new Strategy(Strategy::LANGUAGES),
new Strategy(Strategy::EXTENSION),
];
foreach ($strategies as $strategy) {
$detector = new Runtime($strategy === Strategy::LANGUAGES ? $languages : $files, $strategy, $packager);
$detector
->addOption(new Node())
->addOption(new Bun())
->addOption(new Deno())
->addOption(new PHP())
->addOption(new Python())
->addOption(new Dart())
->addOption(new Swift())
->addOption(new Ruby())
->addOption(new Java())
->addOption(new CPP())
->addOption(new Dotnet());
$runtime = $detector->detect();
if (!\is_null($runtime)) {
$output->setAttribute('commands', $runtime->getCommands());
$output->setAttribute('entrypoint', $runtime->getEntrypoint());
$runtime = $runtime->getName();
break;
}
}
if (!empty($runtime)) {
$runtimes = Config::getParam('runtimes');
$runtimeWithVersion = '';
foreach ($runtimes as $runtimeKey => $runtimeConfig) {
if ($runtimeConfig['key'] === $runtime) {
$runtimeWithVersion = $runtimeKey;
}
}
if (empty($runtimeWithVersion)) {
throw new Exception(Exception::FUNCTION_RUNTIME_NOT_DETECTED);
}
$output->setAttribute('runtime', $runtimeWithVersion);
} else {
throw new Exception(Exception::FUNCTION_RUNTIME_NOT_DETECTED);
}
}
$response->dynamic($output, $type === 'framework' ? Response::MODEL_DETECTION_FRAMEWORK : Response::MODEL_DETECTION_RUNTIME);
});
App::get('/v1/vcs/github/installations/:installationId/providerRepositories')
@@ -605,17 +799,21 @@ App::get('/v1/vcs/github/installations/:installationId/providerRepositories')
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROVIDER_REPOSITORY_LIST,
model: Response::MODEL_PROVIDER_REPOSITORY_RUNTIME_LIST,
),
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROVIDER_REPOSITORY_FRAMEWORK_LIST,
)
]
))
->param('installationId', '', new Text(256), 'Installation Id')
->param('type', '', new WhiteList(['runtime', 'framework']), 'Detector type. Must be one of the following: runtime, framework')
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->inject('gitHub')
->inject('response')
->inject('project')
->inject('dbForPlatform')
->action(function (string $installationId, string $search, GitHub $github, Response $response, Document $project, Database $dbForPlatform) {
->action(function (string $installationId, string $type, string $search, GitHub $github, Response $response, Database $dbForPlatform) {
if (empty($search)) {
$search = "";
}
@@ -645,39 +843,86 @@ App::get('/v1/vcs/github/installations/:installationId/providerRepositories')
return $repo;
}, $repos);
$repos = batch(\array_map(function ($repo) use ($github) {
return function () use ($repo, $github) {
try {
$files = $github->listRepositoryContents($repo['organization'], $repo['name'], '');
$files = \array_column($files, 'name');
$repos = batch(\array_map(function ($repo) use ($type, $github) {
return function () use ($repo, $type, $github) {
$files = $github->listRepositoryContents($repo['organization'], $repo['name'], '');
$files = \array_column($files, 'name');
$detector = new Packager($files);
$detector
->addOption(new Yarn())
->addOption(new PNPM())
->addOption(new NPM());
$detection = $detector->detect();
$packager = !\is_null($detection) ? $detection->getName() : 'npm';
if ($type === 'framework') {
$frameworkDetector = new Framework($files, $packager);
$frameworkDetector
->addOption(new Flutter())
->addOption(new Nuxt())
->addOption(new Astro())
->addOption(new SvelteKit())
->addOption(new NextJs())
->addOption(new Remix());
$detectedFramework = $frameworkDetector->detect();
if (!\is_null($detectedFramework)) {
$framework = $detectedFramework->getName();
} else {
$framework = 'other';
}
$frameworks = Config::getParam('frameworks');
if (!\in_array($framework, array_keys($frameworks), true)) {
$framework = 'other';
}
$repo['framework'] = $framework;
} else {
$languages = $github->listRepositoryLanguages($repo['organization'], $repo['name']);
$detectorFactory = new Detector($files, $languages);
$strategies = [
new Strategy(Strategy::FILEMATCH),
new Strategy(Strategy::LANGUAGES),
new Strategy(Strategy::EXTENSION),
];
$detectorFactory
->addDetector(new JavaScript())
->addDetector(new Bun())
->addDetector(new PHP())
->addDetector(new Python())
->addDetector(new Dart())
->addDetector(new Swift())
->addDetector(new Ruby())
->addDetector(new Java())
->addDetector(new CPP())
->addDetector(new Deno())
->addDetector(new Dotnet());
foreach ($strategies as $strategy) {
$detector = new Runtime($strategy === Strategy::LANGUAGES ? $languages : $files, $strategy, $packager);
$detector
->addOption(new Node())
->addOption(new Bun())
->addOption(new Deno())
->addOption(new PHP())
->addOption(new Python())
->addOption(new Dart())
->addOption(new Swift())
->addOption(new Ruby())
->addOption(new Java())
->addOption(new CPP())
->addOption(new Dotnet());
$runtime = $detectorFactory->detect();
$runtime = $detector->detect();
$runtimes = Config::getParam('runtimes');
$runtimeDetail = \array_reverse(\array_filter(\array_keys($runtimes), function ($key) use ($runtime, $runtimes) {
return $runtimes[$key]['key'] === $runtime;
}))[0] ?? '';
if (!\is_null($runtime)) {
$runtime = $runtime->getName();
break;
}
}
$repo['runtime'] = $runtimeDetail;
} catch (Throwable $error) {
$repo['runtime'] = "";
Console::warning("Runtime not detected for " . $repo['organization'] . "/" . $repo['name']);
if (!empty($runtime)) {
$runtimes = Config::getParam('runtimes');
$runtimeWithVersion = '';
foreach ($runtimes as $runtimeKey => $runtimeConfig) {
if ($runtimeConfig['key'] === $runtime) {
$runtimeWithVersion = $runtimeKey;
}
}
$repo['runtime'] = $runtimeWithVersion ?? '';
}
}
return $repo;
};
@@ -688,9 +933,9 @@ App::get('/v1/vcs/github/installations/:installationId/providerRepositories')
}, $repos);
$response->dynamic(new Document([
'providerRepositories' => $repos,
$type === 'framework' ? 'frameworkProviderRepositories' : 'runtimeProviderRepositories' => $repos,
'total' => \count($repos),
]), Response::MODEL_PROVIDER_REPOSITORY_LIST);
]), ($type === 'framework') ? Response::MODEL_PROVIDER_REPOSITORY_FRAMEWORK_LIST : Response::MODEL_PROVIDER_REPOSITORY_RUNTIME_LIST);
});
App::post('/v1/vcs/github/installations/:installationId/providerRepositories')
@@ -957,7 +1202,7 @@ App::post('/v1/vcs/github/events')
$github->initializeVariables($providerInstallationId, $privateKey, $githubAppId);
//find functionId from functions table
//find resourceId from relevant resources table
$repositories = Authorization::skip(fn () => $dbForPlatform->find('repositories', [
Query::equal('providerRepositoryId', [$providerRepositoryId]),
Query::limit(100),
@@ -969,7 +1214,7 @@ App::post('/v1/vcs/github/events')
}
} elseif ($event == $github::EVENT_INSTALLATION) {
if ($parsedPayload["action"] == "deleted") {
// TODO: Use worker for this job instead (update function as well)
// TODO: Use worker for this job instead (update function/site as well)
$providerInstallationId = $parsedPayload["installationId"];
$installations = $dbForPlatform->find('installations', [
+377 -145
View File
@@ -3,25 +3,30 @@
require_once __DIR__ . '/../init.php';
use Ahc\Jwt\JWT;
use Ahc\Jwt\JWTException;
use Appwrite\Auth\Auth;
use Appwrite\Auth\Key;
use Appwrite\Event\Certificate;
use Appwrite\Event\Event;
use Appwrite\Event\Func;
use Appwrite\Event\StatsUsage;
use Appwrite\Extend\Exception as AppwriteException;
use Appwrite\Network\Validator\Origin;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\ContentType;
use Appwrite\Platform\Appwrite;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Transformation\Adapter\Preview;
use Appwrite\Transformation\Transformation;
use Appwrite\Utopia\Request;
use Appwrite\Utopia\Request\Filters\V16 as RequestV16;
use Appwrite\Utopia\Request\Filters\V17 as RequestV17;
use Appwrite\Utopia\Request\Filters\V18 as RequestV18;
use Appwrite\Utopia\Request\Filters\V19 as RequestV19;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Filters\V16 as ResponseV16;
use Appwrite\Utopia\Response\Filters\V17 as ResponseV17;
use Appwrite\Utopia\Response\Filters\V18 as ResponseV18;
use Appwrite\Utopia\Response\Filters\V19 as ResponseV19;
use Appwrite\Utopia\View;
use Executor\Executor;
use MaxMind\Db\Reader;
@@ -42,6 +47,7 @@ use Utopia\Logger\Adapter\Sentry;
use Utopia\Logger\Log;
use Utopia\Logger\Log\User;
use Utopia\Logger\Logger;
use Utopia\Platform\Service;
use Utopia\System\System;
use Utopia\Validator\Hostname;
use Utopia\Validator\Text;
@@ -50,7 +56,7 @@ Config::setParam('domainVerification', false);
Config::setParam('cookieDomain', 'localhost');
Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE);
function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, SwooleRequest $swooleRequest, Request $request, Response $response, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Reader $geodb, callable $isResourceBlocked, string $previewHostname)
function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, SwooleRequest $swooleRequest, Request $request, Response $response, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Reader $geodb, callable $isResourceBlocked, string $previewHostname, ?Key $apiKey)
{
$utopia->getRoute()?->label('error', __DIR__ . '/../views/general/error.phtml');
@@ -61,9 +67,9 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
// TODO: @christyjacob remove once we migrate the rules in 1.7.x
if (System::getEnv('_APP_RULES_FORMAT') === 'md5') {
$route = Authorization::skip(fn () => $dbForPlatform->getDocument('rules', md5($host)));
$rule = Authorization::skip(fn () => $dbForPlatform->getDocument('rules', md5($host)));
} else {
$route = Authorization::skip(
$rule = Authorization::skip(
fn () => $dbForPlatform->find('rules', [
Query::equal('domain', [$host]),
Query::limit(1)
@@ -71,12 +77,12 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
)[0] ?? new Document();
}
if ($route->isEmpty()) {
if ($host === System::getEnv('_APP_DOMAIN_FUNCTIONS', '')) {
if ($rule->isEmpty()) {
if ($host === System::getEnv('_APP_DOMAIN_FUNCTIONS', '') || $host === System::getEnv('_APP_DOMAIN_SITES', '')) {
throw new AppwriteException(AppwriteException::GENERAL_ACCESS_FORBIDDEN, 'This domain cannot be used for security reasons. Please use any subdomain instead.');
}
if (\str_ends_with($host, System::getEnv('_APP_DOMAIN_FUNCTIONS', ''))) {
if (\str_ends_with($host, System::getEnv('_APP_DOMAIN_FUNCTIONS', '')) || \str_ends_with($host, System::getEnv('_APP_DOMAIN_SITES', ''))) {
throw new AppwriteException(AppwriteException::GENERAL_ACCESS_FORBIDDEN, 'This domain is not connected to any Appwrite resource yet. Please configure custom domain or function domain to allow this request.');
}
@@ -88,10 +94,11 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
// Act as API - no Proxy logic
$utopia->getRoute()?->label('error', '');
return false;
}
$projectId = $route->getAttribute('projectId');
$projectId = $rule->getAttribute('projectId');
$project = Authorization::skip(
fn () => $dbForPlatform->getDocument('projects', $projectId)
);
@@ -117,45 +124,34 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
return false;
}
$type = $route->getAttribute('resourceType');
$type = $rule->getAttribute('type', '');
if ($type === 'function') {
$method = $utopia->getRoute()?->getLabel('sdk', null);
if (empty($method)) {
$utopia->getRoute()?->label('sdk', new Method(
namespace: 'functions',
name: 'createExecution',
description: '/docs/references/functions/create-execution.md',
auth: [AuthType::SESSION, AuthType::KEY, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_CREATED,
model: Response::MODEL_EXECUTION,
)
],
contentType: ContentType::MULTIPART,
requestType: 'application/json',
));
} else {
/** @var Method $method */
$method->setNamespace('functions');
$method->setMethodName('createExecution');
$utopia->getRoute()?->label('sdk', $method);
}
if (System::getEnv('_APP_OPTIONS_FUNCTIONS_FORCE_HTTPS', 'disabled') === 'enabled') { // Force HTTPS
if ($request->getProtocol() !== 'https') {
if ($type === 'deployment') {
if (System::getEnv('_APP_OPTIONS_COMPUTE_FORCE_HTTPS', 'disabled') === 'enabled') { // Force HTTPS
if ($request->getProtocol() !== 'https' && $request->getHostname() !== APP_HOSTNAME_INTERNAL) {
if ($request->getMethod() !== Request::METHOD_GET) {
throw new AppwriteException(AppwriteException::GENERAL_PROTOCOL_UNSUPPORTED, 'Method unsupported over HTTP. Please use HTTPS instead.');
}
return $response->redirect('https://' . $request->getHostname() . $request->getURI());
}
}
$functionId = $route->getAttribute('resourceId');
$projectId = $route->getAttribute('projectId');
/** @var Database $dbForProject */
$dbForProject = $getProjectDB($project);
$deployment = Authorization::skip(fn () => $dbForProject->getDocument('deployments', $rule->getAttribute('deploymentId')));
if ($deployment->getAttribute('resourceType', '') === 'functions') {
$type = 'function';
} elseif ($deployment->getAttribute('resourceType', '') === 'sites') {
$type = 'site';
}
$resource = $type === 'function' ?
Authorization::skip(fn () => $dbForProject->getDocument('functions', $deployment->getAttribute('resourceId', ''))) :
Authorization::skip(fn () => $dbForProject->getDocument('sites', $deployment->getAttribute('resourceId', '')));
$isPreview = $type === 'function' ? false : ($rule->getAttribute('trigger', '') !== 'manual');
$path = ($swooleRequest->server['request_uri'] ?? '/');
$query = ($swooleRequest->server['query_string'] ?? '');
@@ -163,78 +159,143 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
$path .= '?' . $query;
}
$protocol = $request->getProtocol();
/**
Ensure preview authorization
- Authorization is skippable for tests, and build screenshot
- If cookie is not sent by client -> not authorized
- If JWT in cookie is invalid or expired -> not authorized
- If user is blocked or removed -> not authorized
- If user's session is removed or expired -> not authorized
- If user is not member of team of this deployment -> not authorized
- If not authorized, redirect to Console redirect UI
- If authorized, continue as if auth was not required
*/
$requirePreview = \is_null($apiKey) || !$apiKey->isPreviewAuthDisabled();
if ($isPreview && $requirePreview) {
$cookie = $request->getCookie(Auth::$cookieNamePreview, '');
$authorized = false;
// Security checks to mark authorized true
if (!empty($cookie)) {
$jwt = new JWT(System::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 3600, 0);
$payload = [];
try {
$payload = $jwt->decode($cookie);
} catch (JWTException $error) {
// Authorized remains false
}
$userExists = false;
$userId = $payload['userId'] ?? '';
if (!empty($userId)) {
$user = Authorization::skip(fn () => $dbForPlatform->getDocument('users', $userId));
if (!$user->isEmpty() && $user->getAttribute('status', false)) {
$userExists = true;
}
}
$sessionExists = false;
$jwtSessionId = $payload['sessionId'] ?? '';
if (!empty($jwtSessionId) && !empty($user->find('$id', $jwtSessionId, 'sessions'))) {
$sessionExists = true;
}
$membershipExists = false;
$project = Authorization::skip(fn () => $dbForPlatform->getDocument('projects', $projectId));
if (!$project->isEmpty() && isset($user)) {
$teamId = $project->getAttribute('teamId', '');
$membership = $user->find('teamId', $teamId, 'memberships');
if (!empty($membership)) {
$membershipExists = true;
}
}
if ($userExists && $sessionExists && $membershipExists) {
$authorized = true;
}
}
if (!$authorized) {
$url = (System::getEnv('_APP_OPTIONS_FORCE_HTTPS') == 'disabled' ? 'http' : 'https') . "://" . System::getEnv('_APP_DOMAIN');
$response
->addHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
->addHeader('Pragma', 'no-cache')
->redirect($url . '/console/auth/preview?'
. \http_build_query([
'projectId' => $projectId,
'origin' => $protocol . '://' . $host,
'path' => $path
]));
return true;
}
}
$body = $swooleRequest->getContent() ?? '';
$method = $swooleRequest->server['request_method'];
$requestHeaders = $request->getHeaders();
$project = Authorization::skip(fn () => $dbForPlatform->getDocument('projects', $projectId));
$dbForProject = $getProjectDB($project);
$function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId));
if ($function->isEmpty() || !$function->getAttribute('enabled')) {
if ($resource->isEmpty() || !$resource->getAttribute('enabled')) {
throw new AppwriteException(AppwriteException::FUNCTION_NOT_FOUND);
}
if ($isResourceBlocked($project, RESOURCE_TYPE_FUNCTIONS, $functionId)) {
if ($isResourceBlocked($project, $type === 'function' ? RESOURCE_TYPE_FUNCTIONS : RESOURCE_TYPE_SITES, $resource->getId())) {
throw new AppwriteException(AppwriteException::GENERAL_RESOURCE_BLOCKED);
}
$version = $function->getAttribute('version', 'v2');
$runtimes = Config::getParam($version === 'v2' ? 'runtimes-v2' : 'runtimes', []);
$spec = Config::getParam('runtime-specifications')[$function->getAttribute('specification', APP_FUNCTION_SPECIFICATION_DEFAULT)];
$version = match ($type) {
'function' => $resource->getAttribute('version', 'v2'),
'site' => 'v5',
};
$runtime = (isset($runtimes[$function->getAttribute('runtime', '')])) ? $runtimes[$function->getAttribute('runtime', '')] : null;
$runtimes = Config::getParam($version === 'v2' ? 'runtimes-v2' : 'runtimes', []);
$spec = Config::getParam('specifications')[$resource->getAttribute('specification', APP_COMPUTE_SPECIFICATION_DEFAULT)];
$runtime = match ($type) {
'function' => $runtimes[$resource->getAttribute('runtime')] ?? null,
'site' => $runtimes[$resource->getAttribute('buildRuntime')] ?? null,
default => null
};
// Static site enforced runtime
if ($resource->getAttribute('adapter', '') === 'static') {
$runtime = $runtimes['static-1'] ?? null;
}
if (\is_null($runtime)) {
throw new AppwriteException(AppwriteException::FUNCTION_RUNTIME_UNSUPPORTED, 'Runtime "' . $function->getAttribute('runtime', '') . '" is not supported');
throw new AppwriteException(AppwriteException::FUNCTION_RUNTIME_UNSUPPORTED, 'Runtime "' . $resource->getAttribute('runtime', '') . '" is not supported');
}
$deployment = Authorization::skip(fn () => $dbForProject->getDocument('deployments', $function->getAttribute('deployment', '')));
if ($deployment->getAttribute('resourceId') !== $function->getId()) {
throw new AppwriteException(AppwriteException::DEPLOYMENT_NOT_FOUND, 'Deployment not found. Create a deployment before trying to execute a function');
}
if ($deployment->isEmpty()) {
throw new AppwriteException(AppwriteException::DEPLOYMENT_NOT_FOUND, 'Deployment not found. Create a deployment before trying to execute a function');
}
/** Check if build has completed */
$build = Authorization::skip(fn () => $dbForProject->getDocument('builds', $deployment->getAttribute('buildId', '')));
if ($build->isEmpty()) {
throw new AppwriteException(AppwriteException::BUILD_NOT_FOUND);
}
if ($build->getAttribute('status') !== 'ready') {
if ($deployment->getAttribute('status') !== 'ready') {
throw new AppwriteException(AppwriteException::BUILD_NOT_READY);
}
$permissions = $function->getAttribute('execute');
if (!(\in_array('any', $permissions)) && !(\in_array('guests', $permissions))) {
throw new AppwriteException(AppwriteException::USER_UNAUTHORIZED, 'To execute function using domain, execute permissions must include "any" or "guests"');
if ($type === 'function') {
$permissions = $resource->getAttribute('execute');
if (!(\in_array('any', $permissions)) && !(\in_array('guests', $permissions))) {
throw new AppwriteException(AppwriteException::USER_UNAUTHORIZED, 'To execute function using domain, execute permissions must include "any" or "guests"');
}
}
$jwtExpiry = $function->getAttribute('timeout', 900);
$jwtObj = new JWT(System::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', $jwtExpiry, 0);
$apiKey = $jwtObj->encode([
'projectId' => $project->getId(),
'scopes' => $function->getAttribute('scopes', [])
]);
$headers = \array_merge([], $requestHeaders);
$headers['x-appwrite-key'] = API_KEY_DYNAMIC . '_' . $apiKey;
$headers['x-appwrite-trigger'] = 'http';
$headers['x-appwrite-user-id'] = '';
$headers['x-appwrite-user-jwt'] = '';
$headers['x-appwrite-country-code'] = '';
$headers['x-appwrite-continent-code'] = '';
$headers['x-appwrite-continent-eu'] = 'false';
$jwtExpiry = $resource->getAttribute('timeout', 900);
$jwtObj = new JWT(System::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', $jwtExpiry, 0);
$jwtKey = $jwtObj->encode([
'projectId' => $project->getId(),
'scopes' => $resource->getAttribute('scopes', [])
]);
$headers['x-appwrite-key'] = API_KEY_DYNAMIC . '_' . $jwtKey;
$headers['x-appwrite-trigger'] = 'http';
$headers['x-appwrite-user-jwt'] = '';
$ip = $headers['x-real-ip'] ?? '';
if (!empty($ip)) {
$record = $geodb->get($ip);
@@ -260,12 +321,10 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
$execution = new Document([
'$id' => $executionId,
'$permissions' => [],
'functionInternalId' => $function->getInternalId(),
'functionId' => $function->getId(),
'resourceInternalId' => $resource->getInternalId(),
'resourceId' => $resource->getId(),
'deploymentInternalId' => $deployment->getInternalId(),
'deploymentId' => $deployment->getId(),
'trigger' => 'http', // http / schedule / event
'status' => 'processing', // waiting / processing / completed / failed
'responseStatusCode' => 0,
'responseHeaders' => [],
'requestPath' => $path,
@@ -274,13 +333,25 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
'errors' => '',
'logs' => '',
'duration' => 0.0,
'search' => implode(' ', [$functionId, $executionId]),
]);
$queueForEvents
->setParam('functionId', $function->getId())
->setParam('executionId', $execution->getId())
->setContext('function', $function);
if ($type === 'function') {
$execution->setAttribute('resourceType', 'functions');
$execution->setAttribute('trigger', 'http'); // http / schedule / event
$execution->setAttribute('status', 'processing'); // waiting / processing / completed / failed
$queueForEvents
->setParam('functionId', $resource->getId())
->setParam('executionId', $execution->getId())
->setContext('function', $resource);
} elseif ($type === 'site') {
$execution->setAttribute('resourceType', 'sites');
$queueForEvents
->setParam('siteId', $resource->getId())
->setParam('executionId', $execution->getId())
->setContext('site', $resource);
}
$durationStart = \microtime(true);
@@ -297,12 +368,12 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
}
// Shared vars
foreach ($function->getAttribute('varsProject', []) as $var) {
foreach ($resource->getAttribute('varsProject', []) as $var) {
$vars[$var->getAttribute('key')] = $var->getAttribute('value', '');
}
// Function vars
foreach ($function->getAttribute('vars', []) as $var) {
foreach ($resource->getAttribute('vars', []) as $var) {
$vars[$var->getAttribute('key')] = $var->getAttribute('value', '');
}
@@ -313,14 +384,14 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
// Appwrite vars
$vars = \array_merge($vars, [
'APPWRITE_FUNCTION_API_ENDPOINT' => $endpoint,
'APPWRITE_FUNCTION_ID' => $functionId,
'APPWRITE_FUNCTION_NAME' => $function->getAttribute('name'),
'APPWRITE_FUNCTION_ID' => $resource->getId(),
'APPWRITE_FUNCTION_NAME' => $resource->getAttribute('name'),
'APPWRITE_FUNCTION_DEPLOYMENT' => $deployment->getId(),
'APPWRITE_FUNCTION_PROJECT_ID' => $project->getId(),
'APPWRITE_FUNCTION_RUNTIME_NAME' => $runtime['name'] ?? '',
'APPWRITE_FUNCTION_RUNTIME_VERSION' => $runtime['version'] ?? '',
'APPWRITE_FUNCTION_CPUS' => $spec['cpus'] ?? APP_FUNCTION_CPUS_DEFAULT,
'APPWRITE_FUNCTION_MEMORY' => $spec['memory'] ?? APP_FUNCTION_MEMORY_DEFAULT,
'APPWRITE_FUNCTION_CPUS' => $spec['cpus'] ?? APP_COMPUTE_CPUS_DEFAULT,
'APPWRITE_FUNCTION_MEMORY' => $spec['memory'] ?? APP_COMPUTE_MEMORY_DEFAULT,
'APPWRITE_VERSION' => APP_VERSION_STABLE,
'APPWRITE_REGION' => $project->getAttribute('region'),
'APPWRITE_DEPLOYMENT_TYPE' => $deployment->getAttribute('type', ''),
@@ -338,32 +409,93 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
'APPWRITE_VCS_ROOT_DIRECTORY' => $deployment->getAttribute('providerRootDirectory', ''),
]);
// SPA fallbackFile override
if ($resource->getAttribute('adapter', '') === 'static' && $resource->getAttribute('fallbackFile', '') !== '') {
$vars['OPEN_RUNTIMES_STATIC_FALLBACK'] = $resource->getAttribute('fallbackFile', '');
}
/** Execute function */
$executor = new Executor(System::getEnv('_APP_EXECUTOR_HOST'));
try {
$version = $function->getAttribute('version', 'v2');
$command = $runtime['startCommand'];
$command = $version === 'v2' ? '' : 'cp /tmp/code.tar.gz /mnt/code/code.tar.gz && nohup helpers/start.sh "' . $command . '"';
$version = match ($type) {
'function' => $resource->getAttribute('version', 'v2'),
'site' => 'v5',
};
$entrypoint = match ($type) {
'function' => $deployment->getAttribute('entrypoint', ''),
'site' => '',
};
if ($type === 'function') {
$runtimeEntrypoint = match ($version) {
'v2' => '',
default => 'cp /tmp/code.tar.gz /mnt/code/code.tar.gz && nohup helpers/start.sh "' . $runtime['startCommand'] . '"'
};
} elseif ($type === 'site') {
$frameworks = Config::getParam('frameworks', []);
$framework = $frameworks[$resource->getAttribute('framework', '')] ?? null;
$startCommand = $runtime['startCommand'];
if (!is_null($framework)) {
$adapter = ($framework['adapters'] ?? [])[$resource->getAttribute('adapter', '')] ?? null;
if (!is_null($adapter) && isset($adapter['startCommand'])) {
$startCommand = $adapter['startCommand'];
}
}
$runtimeEntrypoint = 'cp /tmp/code.tar.gz /mnt/code/code.tar.gz && nohup helpers/start.sh "' . $startCommand . '"';
}
$entrypoint = match ($type) {
'function' => $deployment->getAttribute('entrypoint', ''),
'site' => '',
};
$executionResponse = $executor->createExecution(
projectId: $project->getId(),
deploymentId: $deployment->getId(),
body: \strlen($body) > 0 ? $body : null,
variables: $vars,
timeout: $function->getAttribute('timeout', 0),
timeout: $resource->getAttribute('timeout', 30),
image: $runtime['image'],
source: $build->getAttribute('path', ''),
entrypoint: $deployment->getAttribute('entrypoint', ''),
source: $deployment->getAttribute('buildPath', ''),
entrypoint: $entrypoint,
version: $version,
path: $path,
method: $method,
headers: $headers,
runtimeEntrypoint: $command,
cpus: $spec['cpus'] ?? APP_FUNCTION_CPUS_DEFAULT,
memory: $spec['memory'] ?? APP_FUNCTION_MEMORY_DEFAULT,
logging: $function->getAttribute('logging', true),
runtimeEntrypoint: $runtimeEntrypoint,
cpus: $spec['cpus'] ?? APP_COMPUTE_CPUS_DEFAULT,
memory: $spec['memory'] ?? APP_COMPUTE_MEMORY_DEFAULT,
logging: $resource->getAttribute('logging', true),
requestTimeout: 30
);
// Branded 404 override
if ($executionResponse['statusCode'] === 404 && $resource->getAttribute('adapter', '') === 'static') {
$layout = new View(__DIR__ . '/../views/general/404.phtml');
$executionResponse['body'] = $layout->render();
$executionResponse['headers']['content-length'] = \strlen($executionResponse['body']);
}
// Branded banner for previews
if (\is_null($apiKey) || $apiKey->isBannerDisabled() === false) {
$transformation = new Transformation();
$transformation->addAdapter(new Preview());
$transformation->setInput($executionResponse['body']);
$transformation->setTraits($executionResponse['headers']);
if ($isPreview && $transformation->transform()) {
$executionResponse['body'] = $transformation->getOutput();
foreach ($executionResponse['headers'] as $key => $value) {
if (\strtolower($key) === 'content-length') {
$executionResponse['headers'][$key] = \strlen($executionResponse['body']);
}
}
}
}
$headersFiltered = [];
foreach ($executionResponse['headers'] as $key => $value) {
if (\in_array(\strtolower($key), FUNCTION_ALLOWLIST_HEADERS_RESPONSE)) {
@@ -374,31 +506,38 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
/** Update execution status */
$status = $executionResponse['statusCode'] >= 500 ? 'failed' : 'completed';
$execution->setAttribute('status', $status);
$execution->setAttribute('responseStatusCode', $executionResponse['statusCode']);
$execution->setAttribute('responseHeaders', $headersFiltered);
$execution->setAttribute('logs', $executionResponse['logs']);
$execution->setAttribute('errors', $executionResponse['errors']);
$execution->setAttribute('responseStatusCode', $executionResponse['statusCode']);
$execution->setAttribute('responseHeaders', $headersFiltered);
$execution->setAttribute('duration', $executionResponse['duration']);
} catch (\Throwable $th) {
$durationEnd = \microtime(true);
$execution
->setAttribute('duration', $durationEnd - $durationStart)
->setAttribute('status', 'failed')
->setAttribute('responseStatusCode', 500)
->setAttribute('errors', $th->getMessage() . '\nError Code: ' . $th->getCode());
->setAttribute('responseStatusCode', 500);
if ($type === 'function') {
$execution
->setAttribute('status', 'failed')
->setAttribute('errors', $th->getMessage() . '\nError Code: ' . $th->getCode());
}
Console::error($th->getMessage());
if ($th instanceof AppwriteException) {
throw $th;
}
} finally {
$queueForFunctions
->setType(Func::TYPE_ASYNC_WRITE)
->setExecution($execution)
->setProject($project)
->trigger();
if ($type === 'function') {
$queueForFunctions
->setType(Func::TYPE_ASYNC_WRITE)
->setExecution($execution)
->setProject($project)
->trigger();
} elseif ($type === 'site') { // TODO: Move it to logs worker later
$dbForProject->createDocument('executions', $execution);
}
}
$execution->setAttribute('logs', '');
@@ -420,7 +559,11 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
$contentType = $header['value'];
}
$response->setHeader($header['name'], $header['value']);
if (\strtolower($header['name']) === 'transfer-encoding') {
continue;
}
$response->addHeader(\strtolower($header['name']), $header['value']);
}
$response
@@ -439,19 +582,28 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
->addMetric(METRIC_NETWORK_INBOUND, $request->getSize() + $fileSize)
->addMetric(METRIC_NETWORK_OUTBOUND, $response->getSize())
->addMetric(METRIC_EXECUTIONS, 1)
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS), 1)
->addMetric(str_replace('{functionInternalId}', $resource->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS), 1)
->addMetric(METRIC_EXECUTIONS_COMPUTE, (int)($execution->getAttribute('duration') * 1000)) // per project
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_COMPUTE), (int)($execution->getAttribute('duration') * 1000)) // per function
->addMetric(METRIC_EXECUTIONS_MB_SECONDS, (int)(($spec['memory'] ?? APP_FUNCTION_MEMORY_DEFAULT) * $execution->getAttribute('duration', 0) * ($spec['cpus'] ?? APP_FUNCTION_CPUS_DEFAULT)))
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_MB_SECONDS), (int)(($spec['memory'] ?? APP_FUNCTION_MEMORY_DEFAULT) * $execution->getAttribute('duration', 0) * ($spec['cpus'] ?? APP_FUNCTION_CPUS_DEFAULT)))
->addMetric(str_replace('{functionInternalId}', $resource->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_COMPUTE), (int)($execution->getAttribute('duration') * 1000)) // per function
->addMetric(METRIC_EXECUTIONS_MB_SECONDS, (int)(($spec['memory'] ?? APP_COMPUTE_MEMORY_DEFAULT) * $execution->getAttribute('duration', 0) * ($spec['cpus'] ?? APP_COMPUTE_CPUS_DEFAULT)))
->addMetric(str_replace('{functionInternalId}', $resource->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_MB_SECONDS), (int)(($spec['memory'] ?? APP_COMPUTE_MEMORY_DEFAULT) * $execution->getAttribute('duration', 0) * ($spec['cpus'] ?? APP_COMPUTE_CPUS_DEFAULT)))
->setProject($project)
->trigger()
;
->trigger();
return true;
} elseif ($type === 'api') {
$utopia->getRoute()?->label('error', '');
return false;
} elseif ($type === 'redirect') {
$url = $rule->getAttribute('redirectUrl', '');
$query = ($swooleRequest->server['query_string'] ?? '');
if (!empty($query)) {
$url .= '?' . $query;
}
$response->redirect($url, \intval($rule->getAttribute('redirectStatusCode', 301)));
return true;
} else {
throw new AppwriteException(AppwriteException::GENERAL_SERVER_ERROR, 'Unknown resource type ' . $type);
}
@@ -460,7 +612,6 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
return false;
}
/*
App::init()
->groups(['api'])
->inject('project')
@@ -470,10 +621,9 @@ App::init()
throw new AppwriteException(AppwriteException::GENERAL_BAD_REQUEST, 'Admin mode is not allowed for console project');
}
});
*/
App::init()
->groups(['database', 'functions', 'storage', 'messaging'])
->groups(['database', 'functions', 'sites', 'messaging'])
->inject('project')
->inject('request')
->action(function (Document $project, Request $request) {
@@ -505,7 +655,8 @@ App::init()
->inject('queueForFunctions')
->inject('isResourceBlocked')
->inject('previewHostname')
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForPlatform, callable $getProjectDB, Locale $locale, array $localeCodes, array $clients, Reader $geodb, StatsUsage $queueForStatsUsage, Event $queueForEvents, Certificate $queueForCertificates, Func $queueForFunctions, callable $isResourceBlocked, string $previewHostname) {
->inject('apiKey')
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForPlatform, callable $getProjectDB, Locale $locale, array $localeCodes, array $clients, Reader $geodb, StatsUsage $queueForStatsUsage, Event $queueForEvents, Certificate $queueForCertificates, Func $queueForFunctions, callable $isResourceBlocked, string $previewHostname, ?Key $apiKey) {
/*
* Appwrite Router
*/
@@ -513,8 +664,8 @@ App::init()
$mainDomain = System::getEnv('_APP_DOMAIN', '');
// Only run Router when external domain
if ($host !== $mainDomain || !empty($previewHostname)) {
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $geodb, $isResourceBlocked, $previewHostname)) {
return;
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
$utopia->getRoute()?->label('router', true);
}
}
@@ -541,6 +692,9 @@ App::init()
if (version_compare($requestFormat, '1.6.0', '<')) {
$request->addFilter(new RequestV18());
}
if (version_compare($requestFormat, '1.7.0', '<')) {
$request->addFilter(new RequestV19());
}
}
$domain = $request->getHostname();
@@ -583,14 +737,16 @@ App::init()
}
if ($domainDocument->isEmpty()) {
$ruleId = System::getEnv('_APP_RULES_FORMAT') === 'md5' ? md5($domain->get()) : ID::unique();
$domainDocument = new Document([
// TODO: @christyjacob remove once we migrate the rules in 1.7.x
'$id' => System::getEnv('_APP_RULES_FORMAT') === 'md5' ? md5($domain->get()) : ID::unique(),
'$id' => $ruleId,
'domain' => $domain->get(),
'resourceType' => 'api',
'type' => 'api',
'status' => 'verifying',
'projectId' => 'console',
'projectInternalId' => 'console'
'projectInternalId' => 'console',
'search' => implode(' ', [$ruleId, $domain->get()]),
]);
$domainDocument = $dbForPlatform->createDocument('rules', $domainDocument);
@@ -624,6 +780,22 @@ App::init()
$validator = new Hostname($clients);
if ($validator->isValid($origin)) {
$refDomainOrigin = $origin;
} elseif (!empty($origin)) {
// Auto-allow domains with linked rule
if (System::getEnv('_APP_RULES_FORMAT') === 'md5') {
$rule = Authorization::skip(fn () => $dbForPlatform->getDocument('rules', md5($origin ?? '')));
} else {
$rule = Authorization::skip(
fn () => $dbForPlatform->find('rules', [
Query::equal('domain', [$origin]),
Query::limit(1)
])
)[0] ?? new Document();
}
if (!$rule->isEmpty() && $rule->getAttribute('projectInternalId') === $project->getInternalId()) {
$refDomainOrigin = $origin;
}
}
$refDomain = (!empty($protocol) ? $protocol : $request->getProtocol()) . '://' . $refDomainOrigin . (!empty($port) ? ':' . $port : '');
@@ -672,8 +844,11 @@ App::init()
if (version_compare($responseFormat, '1.6.0', '<')) {
$response->addFilter(new ResponseV18());
}
if (version_compare($responseFormat, '1.7.0', '<')) {
$response->addFilter(new ResponseV19());
}
if (version_compare($responseFormat, APP_VERSION_STABLE, '>')) {
$response->addHeader('X-Appwrite-Warning', "The current SDK is built for Appwrite " . $responseFormat . ". However, the current Appwrite server version is ". APP_VERSION_STABLE . ". Please downgrade your SDK to match the Appwrite version: https://appwrite.io/docs/sdks");
$response->addHeader('X-Appwrite-Warning', "The current SDK is built for Appwrite " . $responseFormat . ". However, the current Appwrite server version is " . APP_VERSION_STABLE . ". Please downgrade your SDK to match the Appwrite version: https://appwrite.io/docs/sdks");
}
}
@@ -738,7 +913,8 @@ App::options()
->inject('isResourceBlocked')
->inject('previewHostname')
->inject('project')
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Reader $geodb, callable $isResourceBlocked, string $previewHostname, Document $project) {
->inject('apiKey')
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Reader $geodb, callable $isResourceBlocked, string $previewHostname, Document $project, ?Key $apiKey) {
/*
* Appwrite Router
*/
@@ -746,8 +922,8 @@ App::options()
$mainDomain = System::getEnv('_APP_DOMAIN', '');
// Only run Router when external domain
if ($host !== $mainDomain || !empty($previewHostname)) {
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $geodb, $isResourceBlocked, $previewHostname)) {
return;
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
$utopia->getRoute()?->label('router', true);
}
}
@@ -1032,6 +1208,7 @@ App::error()
->setParam('trace', $output['trace'] ?? []);
$response->html($layout->render());
return;
}
$response->dynamic(
@@ -1056,7 +1233,8 @@ App::get('/robots.txt')
->inject('geodb')
->inject('isResourceBlocked')
->inject('previewHostname')
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Reader $geodb, callable $isResourceBlocked, string $previewHostname) {
->inject('apiKey')
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Reader $geodb, callable $isResourceBlocked, string $previewHostname, ?Key $apiKey) {
$host = $request->getHostname() ?? '';
$mainDomain = System::getEnv('_APP_DOMAIN', '');
@@ -1064,7 +1242,9 @@ App::get('/robots.txt')
$template = new View(__DIR__ . '/../views/general/robots.phtml');
$response->text($template->render(false));
} else {
router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $geodb, $isResourceBlocked, $previewHostname);
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
$utopia->getRoute()?->label('router', true);
}
}
});
@@ -1084,7 +1264,8 @@ App::get('/humans.txt')
->inject('geodb')
->inject('isResourceBlocked')
->inject('previewHostname')
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Reader $geodb, callable $isResourceBlocked, string $previewHostname) {
->inject('apiKey')
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Reader $geodb, callable $isResourceBlocked, string $previewHostname, ?Key $apiKey) {
$host = $request->getHostname() ?? '';
$mainDomain = System::getEnv('_APP_DOMAIN', '');
@@ -1092,7 +1273,9 @@ App::get('/humans.txt')
$template = new View(__DIR__ . '/../views/general/humans.phtml');
$response->text($template->render(false));
} else {
router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $geodb, $isResourceBlocked, $previewHostname);
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
$utopia->getRoute()?->label('router', true);
}
}
});
@@ -1154,6 +1337,21 @@ App::get('/v1/ping')
->desc('Test the connection between the Appwrite and the SDK.')
->label('scope', 'global')
->label('event', 'projects.[projectId].ping')
->label('sdk', new Method(
namespace: 'ping',
name: 'get',
hide: true,
description: <<<EOT
Send a ping to project as part of onboarding.
EOT,
auth: [],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_ANY,
)
],
))
->inject('response')
->inject('project')
->inject('dbForPlatform')
@@ -1181,6 +1379,34 @@ App::get('/v1/ping')
$response->text('Pong!');
});
// Preview authorization
App::get('/_appwrite/authorize')
->inject('request')
->inject('response')
->inject('previewHostname')
->action(function (Request $request, Response $response, string $previewHostname) {
$host = $request->getHostname() ?? '';
if (!empty($previewHostname)) {
$host = $previewHostname;
}
$referrer = $request->getReferer();
$protocol = \parse_url($request->getOrigin($referrer), PHP_URL_SCHEME);
$jwt = $request->getParam('jwt', '');
$path = $request->getParam('path', '');
$duration = 60 * 60 * 24; // 1 day in seconds
$expire = DateTime::formatTz(DateTime::addSeconds(new \DateTime(), $duration));
$response
->addCookie(Auth::$cookieNamePreview, $jwt, (new \DateTime($expire))->getTimestamp(), '/', $host, ('https' === $protocol), true, null)
->addHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
->addHeader('Pragma', 'no-cache')
->redirect($protocol . '://' . $host . $path);
});
App::wildcard()
->groups(['api'])
->label('scope', 'global')
@@ -1189,9 +1415,15 @@ App::wildcard()
});
foreach (Config::getParam('services', []) as $service) {
include_once $service['controller'];
if (!empty($service['controller'])) {
include_once $service['controller'];
}
}
// Modules
$platform = new Appwrite();
$platform->init(Service::TYPE_HTTP);
// Check for any errors found while we were initialising the SDK Methods.
if (!empty(Method::getErrors())) {
throw new \Exception('Errors found during SDK initialization:' . PHP_EOL . implode(PHP_EOL, Method::getErrors()));
+9
View File
@@ -157,6 +157,15 @@ $usageDatabaseListener = function (string $event, Document $document, StatsUsage
$queueForStatsUsage
->addMetric(METRIC_FUNCTIONS, $value); // per project
if ($event === Database::EVENT_DOCUMENT_DELETE) {
$queueForStatsUsage
->addReduce($document);
}
break;
case $document->getCollection() === 'sites':
$queueForStatsUsage
->addMetric(METRIC_SITES, $value); // per project
if ($event === Database::EVENT_DOCUMENT_DELETE) {
$queueForStatsUsage
->addReduce($document);
+53 -4
View File
@@ -13,6 +13,7 @@ use Swoole\Table;
use Utopia\App;
use Utopia\Audit\Audit;
use Utopia\CLI\Console;
use Utopia\Compression\Compression;
use Utopia\Config\Config;
use Utopia\Database\Database;
use Utopia\Database\DateTime;
@@ -28,6 +29,8 @@ use Utopia\Pools\Group;
use Utopia\Swoole\Files;
use Utopia\System\System;
Files::load(__DIR__.'/../public');
const DOMAIN_SYNC_TIMER = 30; // 30 seconds
$domains = new Table(1_000_000); // 1 million rows
@@ -249,8 +252,7 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg
$audit->setup();
}
if ($dbForPlatform->getDocument('buckets', 'default')->isEmpty() &&
!$dbForPlatform->exists($dbForPlatform->getDatabase(), 'bucket_1')) {
if ($dbForPlatform->getDocument('buckets', 'default')->isEmpty()) {
Console::info(" └── Creating default bucket...");
$dbForPlatform->createDocument('buckets', new Document([
'$id' => ID::custom('default'),
@@ -302,6 +304,54 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg
$dbForPlatform->createCollection('bucket_' . $bucket->getInternalId(), $attributes, $indexes);
}
if (Authorization::skip(fn () => $dbForPlatform->getDocument('buckets', 'screenshots')->isEmpty())) {
Console::info(" └── Creating screenshots bucket...");
Authorization::skip(fn () => $dbForPlatform->createDocument('buckets', new Document([
'$id' => ID::custom('screenshots'),
'$collection' => ID::custom('buckets'),
'name' => 'Screenshots',
'maximumFileSize' => 5000000, // ~5MB
'allowedFileExtensions' => [ 'png' ],
'enabled' => true,
'compression' => Compression::GZIP,
'encryption' => false,
'antivirus' => false,
'fileSecurity' => true,
'$permissions' => [],
'search' => 'buckets Screenshots',
])));
$bucket = Authorization::skip(fn () => $dbForPlatform->getDocument('buckets', 'screenshots'));
Console::info(" └── Creating files collection for screenshots bucket...");
$files = $collections['buckets']['files'] ?? [];
if (empty($files)) {
throw new Exception('Files collection is not configured.');
}
$attributes = array_map(fn ($attr) => new Document([
'$id' => ID::custom($attr['$id']),
'type' => $attr['type'],
'size' => $attr['size'],
'required' => $attr['required'],
'signed' => $attr['signed'],
'array' => $attr['array'],
'filters' => $attr['filters'],
'default' => $attr['default'] ?? null,
'format' => $attr['format'] ?? ''
]), $files['attributes']);
$indexes = array_map(fn ($index) => new Document([
'$id' => ID::custom($index['$id']),
'type' => $index['type'],
'attributes' => $index['attributes'],
'lengths' => $index['lengths'],
'orders' => $index['orders'],
]), $files['indexes']);
Authorization::skip(fn () => $dbForPlatform->createCollection('bucket_' . $bucket->getInternalId(), $attributes, $indexes));
}
});
$projectCollections = $collections['projects'];
@@ -514,7 +564,6 @@ $http->on('Task', function () use ($register, $domains) {
if ($lastSyncUpdate != null) {
$queries[] = Query::greaterThanEqual('$updatedAt', $lastSyncUpdate);
}
$queries[] = Query::equal('resourceType', ['function']);
$results = [];
try {
$results = Authorization::skip(fn () => $dbForPlatform->find('rules', $queries));
@@ -525,7 +574,7 @@ $http->on('Task', function () use ($register, $domains) {
$sum = count($results);
foreach ($results as $document) {
$domain = $document->getAttribute('domain');
if (str_ends_with($domain, System::getEnv('_APP_DOMAIN_FUNCTIONS'))) {
if (str_ends_with($domain, System::getEnv('_APP_DOMAIN_FUNCTIONS')) || str_ends_with($domain, System::getEnv('_APP_DOMAIN_SITES'))) {
continue;
}
$domains->set(md5($domain), ['value' => 1]);
+46 -12
View File
@@ -36,13 +36,13 @@ use Appwrite\Event\Realtime;
use Appwrite\Event\StatsUsage;
use Appwrite\Event\Webhook;
use Appwrite\Extend\Exception;
use Appwrite\Functions\Specification;
use Appwrite\GraphQL\Promises\Adapter\Swoole;
use Appwrite\GraphQL\Schema;
use Appwrite\Hooks\Hooks;
use Appwrite\Network\Validator\Email;
use Appwrite\Network\Validator\Origin;
use Appwrite\OpenSSL\OpenSSL;
use Appwrite\Platform\Modules\Compute\Specification;
use Appwrite\PubSub\Adapter\Redis as PubSub;
use Appwrite\URL\URL as AppwriteURL;
use Appwrite\Utopia\Request;
@@ -125,7 +125,7 @@ const APP_PROJECT_ACCESS = 24 * 60 * 60; // 24 hours
const APP_FILE_ACCESS = 24 * 60 * 60; // 24 hours
const APP_CACHE_UPDATE = 24 * 60 * 60; // 24 hours
const APP_CACHE_BUSTER = 4318;
const APP_VERSION_STABLE = '1.6.2';
const APP_VERSION_STABLE = '1.7.0';
const APP_DATABASE_ATTRIBUTE_EMAIL = 'email';
const APP_DATABASE_ATTRIBUTE_ENUM = 'enum';
const APP_DATABASE_ATTRIBUTE_IP = 'ip';
@@ -137,6 +137,7 @@ const APP_DATABASE_ATTRIBUTE_STRING_MAX_LENGTH = 1_073_741_824; // 2^32 bits / 4
const APP_DATABASE_TIMEOUT_MILLISECONDS = 15_000;
const APP_DATABASE_QUERY_MAX_VALUES = 500;
const APP_STORAGE_UPLOADS = '/storage/uploads';
const APP_STORAGE_SITES = '/storage/sites';
const APP_STORAGE_FUNCTIONS = '/storage/functions';
const APP_STORAGE_BUILDS = '/storage/builds';
const APP_STORAGE_CACHE = '/storage/cache';
@@ -155,9 +156,9 @@ const APP_SOCIAL_DEV = 'https://dev.to/appwrite';
const APP_SOCIAL_STACKSHARE = 'https://stackshare.io/appwrite';
const APP_SOCIAL_YOUTUBE = 'https://www.youtube.com/c/appwrite?sub_confirmation=1';
const APP_HOSTNAME_INTERNAL = 'appwrite';
const APP_FUNCTION_SPECIFICATION_DEFAULT = Specification::S_1VCPU_512MB;
const APP_FUNCTION_CPUS_DEFAULT = 0.5;
const APP_FUNCTION_MEMORY_DEFAULT = 512;
const APP_COMPUTE_CPUS_DEFAULT = 0.5;
const APP_COMPUTE_MEMORY_DEFAULT = 512;
const APP_COMPUTE_SPECIFICATION_DEFAULT = Specification::S_1VCPU_512MB;
const APP_PLATFORM_SERVER = 'server';
const APP_PLATFORM_CLIENT = 'client';
const APP_PLATFORM_CONSOLE = 'console';
@@ -183,6 +184,7 @@ const DELETE_TYPE_DATABASES = 'databases';
const DELETE_TYPE_DOCUMENT = 'document';
const DELETE_TYPE_COLLECTIONS = 'collections';
const DELETE_TYPE_PROJECTS = 'projects';
const DELETE_TYPE_SITES = 'sites';
const DELETE_TYPE_FUNCTIONS = 'functions';
const DELETE_TYPE_DEPLOYMENTS = 'deployments';
const DELETE_TYPE_USERS = 'users';
@@ -272,6 +274,7 @@ const METRIC_FILES_IMAGES_TRANSFORMED = 'files.imagesTransformed';
const METRIC_BUCKET_ID_FILES_IMAGES_TRANSFORMED = '{bucketInternalId}.files.imagesTransformed';
const METRIC_BUCKET_ID_FILES = '{bucketInternalId}.files';
const METRIC_BUCKET_ID_FILES_STORAGE = '{bucketInternalId}.files.storage';
const METRIC_SITES = 'sites';
const METRIC_FUNCTIONS = 'functions';
const METRIC_DEPLOYMENTS = 'deployments';
const METRIC_DEPLOYMENTS_STORAGE = 'deployments.storage';
@@ -290,15 +293,29 @@ const METRIC_FUNCTION_ID_BUILDS_STORAGE = '{functionInternalId}.builds.storage';
const METRIC_FUNCTION_ID_BUILDS_COMPUTE = '{functionInternalId}.builds.compute';
const METRIC_FUNCTION_ID_BUILDS_COMPUTE_SUCCESS = '{functionInternalId}.builds.compute.success';
const METRIC_FUNCTION_ID_BUILDS_COMPUTE_FAILED = '{functionInternalId}.builds.compute.failed';
const METRIC_FUNCTION_ID_BUILDS_MB_SECONDS = '{functionInternalId}.builds.mbSeconds';
const METRIC_SITES_ID_BUILDS = 'sites.{siteInternalId}.builds';
const METRIC_SITES_ID_BUILDS_SUCCESS = 'sites.{siteInternalId}.builds.success';
const METRIC_SITES_ID_BUILDS_FAILED = 'sites.{siteInternalId}.builds.failed';
const METRIC_SITES_ID_BUILDS_STORAGE = 'sites.{siteInternalId}.builds.storage';
const METRIC_SITES_ID_BUILDS_COMPUTE = 'sites.{siteInternalId}.builds.compute';
const METRIC_SITES_ID_BUILDS_COMPUTE_SUCCESS = 'sites.{siteInternalId}.builds.compute.success';
const METRIC_SITES_ID_BUILDS_COMPUTE_FAILED = 'sites.{siteInternalId}.builds.compute.failed';
const METRIC_SITES_ID_BUILDS_MB_SECONDS = 'sites.{siteInternalId}.builds.mbSeconds';
const METRIC_FUNCTION_ID_DEPLOYMENTS = '{resourceType}.{resourceInternalId}.deployments';
const METRIC_FUNCTION_ID_DEPLOYMENTS_STORAGE = '{resourceType}.{resourceInternalId}.deployments.storage';
const METRIC_FUNCTION_ID_BUILDS_MB_SECONDS = '{functionInternalId}.builds.mbSeconds';
const METRIC_EXECUTIONS = 'executions';
const METRIC_EXECUTIONS_COMPUTE = 'executions.compute';
const METRIC_EXECUTIONS_MB_SECONDS = 'executions.mbSeconds';
const METRIC_FUNCTION_ID_EXECUTIONS = '{functionInternalId}.executions';
const METRIC_FUNCTION_ID_EXECUTIONS_COMPUTE = '{functionInternalId}.executions.compute';
const METRIC_FUNCTION_ID_EXECUTIONS_MB_SECONDS = '{functionInternalId}.executions.mbSeconds';
const METRIC_SITE_ID_DEPLOYMENTS = '{resourceType}.{resourceInternalId}.deployments';
const METRIC_SITE_ID_DEPLOYMENTS_STORAGE = '{resourceType}.{resourceInternalId}.deployments.storage';
const METRIC_SITE_ID_BUILDS = '{siteInternalId}.builds';
const METRIC_SITE_ID_BUILDS_STORAGE = '{siteInternalId}.builds.storage';
const METRIC_SITE_ID_BUILDS_COMPUTE = '{siteInternalId}.builds.compute';
const METRIC_SITE_ID_BUILDS_MB_SECONDS = '{siteInternalId}.builds.mbSeconds';
const METRIC_NETWORK_REQUESTS = 'network.requests';
const METRIC_NETWORK_INBOUND = 'network.inbound';
const METRIC_NETWORK_OUTBOUND = 'network.outbound';
@@ -321,6 +338,7 @@ const METRIC_RESOURCE_TYPE_ID_DEPLOYMENTS_STORAGE = '{resourceType}.{resourceIn
const RESOURCE_TYPE_PROJECTS = 'projects';
const RESOURCE_TYPE_FUNCTIONS = 'functions';
const RESOURCE_TYPE_SITES = 'sites';
const RESOURCE_TYPE_DATABASES = 'databases';
const RESOURCE_TYPE_BUCKETS = 'buckets';
const RESOURCE_TYPE_PROVIDERS = 'providers';
@@ -341,6 +359,7 @@ if (!App::isProduction()) {
/*
* ENV vars
*/
Config::load('template-runtimes', __DIR__ . '/config/template-runtimes.php');
Config::load('events', __DIR__ . '/config/events.php');
Config::load('auth', __DIR__ . '/config/auth.php');
Config::load('apis', __DIR__ . '/config/apis.php'); // List of APIs
@@ -349,6 +368,7 @@ Config::load('oAuthProviders', __DIR__ . '/config/oAuthProviders.php');
Config::load('platforms', __DIR__ . '/config/platforms.php');
Config::load('console', __DIR__ . '/config/console.php');
Config::load('collections', __DIR__ . '/config/collections.php');
Config::load('frameworks', __DIR__ . '/config/frameworks.php');
Config::load('runtimes', __DIR__ . '/config/runtimes.php');
Config::load('runtimes-v2', __DIR__ . '/config/runtimes-v2.php');
Config::load('usage', __DIR__ . '/config/usage.php');
@@ -372,8 +392,9 @@ Config::load('storage-logos', __DIR__ . '/config/storage/logos.php');
Config::load('storage-mimes', __DIR__ . '/config/storage/mimes.php');
Config::load('storage-inputs', __DIR__ . '/config/storage/inputs.php');
Config::load('storage-outputs', __DIR__ . '/config/storage/outputs.php');
Config::load('runtime-specifications', __DIR__ . '/config/runtimes/specifications.php');
Config::load('function-templates', __DIR__ . '/config/function-templates.php');
Config::load('specifications', __DIR__ . '/config/specifications.php');
Config::load('templates-function', __DIR__ . '/config/templates/function.php');
Config::load('templates-site', __DIR__ . '/config/templates/site.php');
/**
* New DB Filters
@@ -596,7 +617,7 @@ Database::addFilter(
return $database
->find('variables', [
Query::equal('resourceInternalId', [$document->getInternalId()]),
Query::equal('resourceType', ['function']),
Query::equal('resourceType', ['function', 'site']),
Query::limit(APP_LIMIT_SUBQUERY),
]);
}
@@ -1605,6 +1626,10 @@ App::setResource('deviceForFiles', function ($project) {
return getDevice(APP_STORAGE_UPLOADS . '/app-' . $project->getId());
}, ['project']);
App::setResource('deviceForSites', function ($project) {
return getDevice(APP_STORAGE_SITES . '/app-' . $project->getId());
}, ['project']);
App::setResource('deviceForFunctions', function ($project) {
return getDevice(APP_STORAGE_FUNCTIONS . '/app-' . $project->getId());
}, ['project']);
@@ -1901,16 +1926,25 @@ App::setResource(
fn () => fn (Document $project, string $resourceType, ?string $resourceId) => false
);
App::setResource('previewHostname', function (Request $request) {
App::setResource('previewHostname', function (Request $request, ?Key $apiKey) {
$allowed = false;
if (App::isDevelopment()) {
$host = $request->getQuery('appwrite-hostname') ?? '';
$allowed = true;
} elseif (!\is_null($apiKey) && $apiKey->getHostnameOverride() === true) {
$allowed = true;
}
if ($allowed) {
$host = $request->getQuery('appwrite-hostname', $request->getHeader('x-appwrite-hostname', ''));
if (!empty($host)) {
return $host;
}
}
return '';
}, ['request']);
}, ['request', 'apiKey']);
App::setResource('apiKey', function (Request $request, Document $project): ?Key {
$key = $request->getHeader('x-appwrite-key');
+185
View File
@@ -0,0 +1,185 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>404 Not Found</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: #FFFFFF;
}
.main {
display: flex;
min-height: 100vh;
width: 100vw;
align-items: center;
justify-content: center;
}
.content {
margin-left: auto;
margin-right: auto;
max-width: 400px;
}
span {
padding: var(--space-1, 2px) var(--space-3, 6px);
border-radius: var(--border-radius-XS, 6px);
background: var(--color-overlay-on-neutral, rgba(0, 0, 0, 0.06));
color: var(--color-fgColor-neutral-secondary, #56565C);
text-align: center;
font-family: var(--font-family-sansSerif, Inter);
font-size: var(--font-size-S, 14px);
font-style: normal;
font-weight: 400;
line-height: 140%;
letter-spacing: -0.063px;
}
h1 {
color: var(--color-fgColor-neutral-primary, #2D2D31);
text-align: center;
font-family: var(--font-family-sansSerif, Inter);
font-size: var(--font-size-XXXL, 32px);
font-style: normal;
font-weight: 400;
line-height: 140%;
letter-spacing: -0.144px;
margin-top: 8px;
margin-bottom: 32px;
}
button {
border-radius: var(--border-radius-S, 8px);
font-family: var(--font-family-sansSerif, Inter);
font-size: var(--font-size-S, 14px);
font-style: normal;
font-weight: 500;
line-height: 140%;
letter-spacing: -0.063px;
padding: var(--space-3, 6px) var(--space-5, 10px);
cursor: pointer;
border: var(--border-width-S, 1px) solid var(--color-border-neutral-strong, #D8D8DB);
background: var(--color-bgColor-neutral-primary, #FFF);
color: var(--color-fgColor-neutral-secondary, #56565C);
}
.center {
display: flex;
justify-content: center;
}
.brand {
position: absolute;
width: 100%;
bottom: 32px;
display: flex;
justify-content: center;
align-items: center;
gap: 8px;
}
.brand p {
font-family: var(--font-family-monospace, "Aeonik Fono");
font-size: var(--font-size-XS, 12px);
font-style: normal;
font-weight: 400;
line-height: 130%;
letter-spacing: 0.96px;
text-transform: uppercase;
color: var(--color-fgColor-neutral-secondary, #56565C);
}
.brand svg {
height: 20px;
}
.logo-dark {
display: none;
}
@media (prefers-color-scheme: dark) {
body {
background-color: #1D1D21;
}
h1 {
color: var(--color-fgColor-neutral-primary, #EDEDF0);
}
button {
border: var(--border-width-S, 1px) solid var(--color-border-neutral-strong, #414146);
background: var(--color-bgColor-neutral-primary, #1D1D21);
color: var(--color-fgColor-neutral-secondary, #C3C3C6);
}
.brand p {
color: var(--color-fgColor-neutral-secondary, #C3C3C6);
}
span {
background: var(--color-overlay-on-neutral, rgba(255, 255, 255, 0.20));
color: var(--color-fgColor-neutral-secondary, #C3C3C6);
}
.logo-light {
display: none;
}
.logo-dark {
display: block;
}
}
</style>
</head>
<body>
<div class="main">
<div class="content">
<div class="center"><span>Page not found</span></div>
<h1>The page youre looking for doesnt exist.</h1>
<div class="center"><a href="/"><button>Go to homepage</button></a></div>
</div>
</div>
<div class="brand">
<p>Powered by</p>
<svg class="logo-dark" width="110" height="20" viewBox="0 0 110 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M31.8649 16.2461C33.6492 16.2461 34.5511 15.3184 34.9433 14.6867H35.1197C35.1981 15.3578 35.6687 15.9895 36.5903 15.9895H38.3353V14.0156H37.8843C37.5706 14.0156 37.4138 13.838 37.4138 13.5617V5.64661H35.1001V6.90986H34.9236C34.4727 6.27823 33.5315 5.39001 31.8061 5.39001C29.0611 5.39001 27.022 7.67965 27.022 10.818C27.022 13.9564 29.1003 16.2461 31.8649 16.2461ZM32.2767 13.9959C30.6493 13.9959 29.3748 12.7919 29.3748 10.8378C29.3748 8.92316 30.6101 7.62044 32.2571 7.62044C33.8256 7.62044 35.1393 8.78499 35.1393 10.8378C35.1393 12.5945 34.0217 13.9959 32.2767 13.9959Z" fill="#EDEDF0" />
<path d="M39.7013 20H42.0149V14.6867H42.1914C42.6227 15.3184 43.5443 16.2461 45.3677 16.2461C48.1127 16.2461 50.1127 13.9169 50.1127 10.818C50.1127 7.69939 47.9755 5.39001 45.2109 5.39001C43.4462 5.39001 42.5835 6.35719 42.1718 6.89012H41.9953V5.64661H39.7013V20ZM44.8776 14.0551C43.2894 14.0551 41.9757 12.8708 41.9757 10.818C41.9757 9.06133 43.0933 7.58096 44.8383 7.58096C46.4657 7.58096 47.7402 8.86395 47.7402 10.818C47.7402 12.7326 46.5049 14.0551 44.8776 14.0551Z" fill="#EDEDF0" />
<path d="M51.3065 20H53.6202V14.6867H53.7966C54.228 15.3184 55.1495 16.2461 56.973 16.2461C59.718 16.2461 61.5273 13.9169 61.5273 10.818C61.5273 7.69939 59.5807 5.39001 56.8161 5.39001C55.0515 5.39001 54.1888 6.35719 53.777 6.89012H53.6005V5.64661H51.3065V20ZM56.4828 14.0551C54.8946 14.0551 53.5809 12.8708 53.5809 10.818C53.5809 9.06133 54.6985 7.58096 56.4436 7.58096C58.071 7.58096 59.3454 8.86395 59.3454 10.818C59.3454 12.7326 58.1102 14.0551 56.4828 14.0551Z" fill="#EDEDF0" />
<path d="M64.5857 16.2296H67.8601L69.7227 8.11721H69.8404L71.7031 16.2296H74.9579L77.5642 5.88678H75.2323L73.3697 14.0189H73.1932L71.3305 5.88678H68.2522L66.3699 14.0189H66.1935L64.3504 5.88678H61.8799L64.5857 16.2296Z" fill="#EDEDF0" />
<path d="M78.7363 16.2296H81.0499V11.1174C81.0499 9.16334 81.9519 7.9593 83.6381 7.9593H84.6576V5.63019H83.893C82.5793 5.63019 81.5793 6.53815 81.1872 7.40663H81.0303V5.88678H78.7363V16.2296Z" fill="#EDEDF0" />
<path d="M96.1391 16.2296H97.943V14.1571H96.1587C95.4529 14.1571 95.1588 13.8413 95.1588 13.111V7.93956H98.0606V5.88678H95.1588V2.98526H92.9628V5.88678H91.0413V7.93956H92.8255V13.1307C92.8255 15.3217 94.1392 16.2296 96.1391 16.2296Z" fill="#EDEDF0" />
<path d="M104.15 16.2461C106.287 16.2461 108.17 15.1802 108.836 13.0287L106.719 12.5155C106.346 13.6603 105.268 14.2525 104.13 14.2525C102.444 14.2525 101.327 13.1472 101.307 11.4102H109.091V10.7588C109.091 7.67965 107.189 5.39001 104.052 5.39001C101.287 5.39001 98.915 7.58096 98.915 10.8378C98.915 13.9959 101.013 16.2461 104.15 16.2461ZM101.327 9.71269C101.464 8.46918 102.581 7.42305 104.052 7.42305C105.464 7.42305 106.621 8.31128 106.738 9.71269H101.327Z" fill="#EDEDF0" />
<path fill-rule="evenodd" clip-rule="evenodd" d="M90.0125 16.2296H87.6989V7.93956H85.895V5.88678H90.0125V16.2296Z" fill="#EDEDF0" />
<path d="M88.6834 4.45145C89.5265 4.45145 90.154 3.81983 90.154 2.99082C90.154 2.18155 89.5265 1.54993 88.6834 1.54993C87.8403 1.54993 87.2129 2.18155 87.2129 2.99082C87.2129 3.81983 87.8403 4.45145 88.6834 4.45145Z" fill="#EDEDF0" />
<path d="M20.2007 13.6935V18.258H8.88588C5.5894 18.258 2.71111 16.4222 1.17116 13.6935C0.947288 13.2968 0.751353 12.8806 0.586995 12.4486C0.26435 11.6021 0.0615332 10.6938 0 9.74603V8.51195C0.0133592 8.30074 0.03441 8.09119 0.0619381 7.88413C0.118209 7.45921 0.203222 7.04343 0.314953 6.63926C1.37195 2.80758 4.8089 0 8.88588 0C12.9629 0 16.3994 2.80758 17.4564 6.63926H12.6184C11.8241 5.39025 10.4493 4.5645 8.88588 4.5645C7.32245 4.5645 5.94767 5.39025 5.15341 6.63926C4.91132 7.01895 4.72349 7.43764 4.60042 7.88413C4.49112 8.27999 4.43282 8.69744 4.43282 9.12899C4.43282 10.4373 4.96962 11.6166 5.83027 12.4486C6.62778 13.2209 7.70299 13.6935 8.88588 13.6935H20.2007Z" fill="#FD366E" />
<path d="M20.2006 7.88412V12.4486H11.9414C12.8021 11.6166 13.3389 10.4373 13.3389 9.12899C13.3389 8.69744 13.2806 8.27999 13.1713 7.88412H20.2006Z" fill="#FD366E" />
</svg>
<svg class="logo-light" width="110" height="20" viewBox="0 0 110 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M31.8648 16.2461C33.649 16.2461 34.5509 15.3184 34.9431 14.6867H35.1195C35.198 15.3578 35.6685 15.9895 36.5901 15.9895H38.3351V14.0156H37.8841C37.5704 14.0156 37.4136 13.838 37.4136 13.5617V5.64661H35.0999V6.90986H34.9235C34.4725 6.27823 33.5314 5.39001 31.8059 5.39001C29.0609 5.39001 27.0218 7.67965 27.0218 10.818C27.0218 13.9564 29.1001 16.2461 31.8648 16.2461ZM32.2765 13.9959C30.6491 13.9959 29.3746 12.7919 29.3746 10.8378C29.3746 8.92316 30.6099 7.62044 32.2569 7.62044C33.8255 7.62044 35.1391 8.78499 35.1391 10.8378C35.1391 12.5945 34.0215 13.9959 32.2765 13.9959Z" fill="#2D2D31" />
<path d="M39.7011 20H42.0147V14.6867H42.1912C42.6226 15.3184 43.5441 16.2461 45.3676 16.2461C48.1126 16.2461 50.1125 13.9169 50.1125 10.818C50.1125 7.69939 47.9753 5.39001 45.2107 5.39001C43.4461 5.39001 42.5833 6.35719 42.1716 6.89012H41.9951V5.64661H39.7011V20ZM44.8774 14.0551C43.2892 14.0551 41.9755 12.8708 41.9755 10.818C41.9755 9.06133 43.0931 7.58096 44.8382 7.58096C46.4656 7.58096 47.74 8.86395 47.74 10.818C47.74 12.7326 46.5048 14.0551 44.8774 14.0551Z" fill="#2D2D31" />
<path d="M51.3063 20H53.62V14.6867H53.7964C54.2278 15.3184 55.1493 16.2461 56.9728 16.2461C59.7178 16.2461 61.5271 13.9169 61.5271 10.818C61.5271 7.69939 59.5805 5.39001 56.8159 5.39001C55.0513 5.39001 54.1886 6.35719 53.7768 6.89012H53.6004V5.64661H51.3063V20ZM56.4826 14.0551C54.8944 14.0551 53.5808 12.8708 53.5808 10.818C53.5808 9.06133 54.6984 7.58096 56.4434 7.58096C58.0708 7.58096 59.3453 8.86395 59.3453 10.818C59.3453 12.7326 58.11 14.0551 56.4826 14.0551Z" fill="#2D2D31" />
<path d="M64.5855 16.2296H67.8599L69.7226 8.11721H69.8402L71.7029 16.2296H74.9577L77.564 5.88678H75.2322L73.3695 14.0189H73.193L71.3303 5.88678H68.252L66.3697 14.0189H66.1933L64.3502 5.88678H61.8797L64.5855 16.2296Z" fill="#2D2D31" />
<path d="M78.7361 16.2296H81.0498V11.1174C81.0498 9.16334 81.9517 7.9593 83.6379 7.9593H84.6575V5.63019H83.8928C82.5791 5.63019 81.5791 6.53815 81.187 7.40663H81.0301V5.88678H78.7361V16.2296Z" fill="#2D2D31" />
<path d="M96.1389 16.2296H97.9428V14.1571H96.1585C95.4527 14.1571 95.1586 13.8413 95.1586 13.111V7.93956H98.0604V5.88678H95.1586V2.98526H92.9626V5.88678H91.0411V7.93956H92.8253V13.1307C92.8253 15.3217 94.139 16.2296 96.1389 16.2296Z" fill="#2D2D31" />
<path d="M104.15 16.2461C106.287 16.2461 108.169 15.1802 108.836 13.0287L106.718 12.5155C106.346 13.6603 105.268 14.2525 104.13 14.2525C102.444 14.2525 101.326 13.1472 101.307 11.4102H109.091V10.7588C109.091 7.67965 107.189 5.39001 104.052 5.39001C101.287 5.39001 98.9148 7.58096 98.9148 10.8378C98.9148 13.9959 101.013 16.2461 104.15 16.2461ZM101.326 9.71269C101.464 8.46918 102.581 7.42305 104.052 7.42305C105.464 7.42305 106.62 8.31128 106.738 9.71269H101.326Z" fill="#2D2D31" />
<path fill-rule="evenodd" clip-rule="evenodd" d="M90.0123 16.2296H87.6987V7.93956H85.8948V5.88678H90.0123V16.2296Z" fill="#2D2D31" />
<path d="M88.6835 4.45145C89.5266 4.45145 90.154 3.81983 90.154 2.99082C90.154 2.18155 89.5266 1.54993 88.6835 1.54993C87.8404 1.54993 87.213 2.18155 87.213 2.99082C87.213 3.81983 87.8404 4.45145 88.6835 4.45145Z" fill="#2D2D31" />
<path d="M20.2007 13.6935V18.258H8.88588C5.5894 18.258 2.71111 16.4222 1.17116 13.6935C0.947288 13.2968 0.751353 12.8806 0.586995 12.4486C0.26435 11.6021 0.0615332 10.6938 0 9.74603V8.51195C0.0133592 8.30074 0.03441 8.09119 0.0619381 7.88413C0.118209 7.45921 0.203222 7.04343 0.314953 6.63926C1.37195 2.80758 4.8089 0 8.88588 0C12.9629 0 16.3994 2.80758 17.4564 6.63926H12.6184C11.8241 5.39025 10.4493 4.5645 8.88588 4.5645C7.32245 4.5645 5.94767 5.39025 5.15341 6.63926C4.91132 7.01895 4.72349 7.43764 4.60042 7.88413C4.49112 8.27999 4.43282 8.69744 4.43282 9.12899C4.43282 10.4373 4.96962 11.6166 5.83027 12.4486C6.62778 13.2209 7.70299 13.6935 8.88588 13.6935H20.2007Z" fill="#FD366E" />
<path d="M20.2007 7.88412V12.4486H11.9415C12.8022 11.6166 13.339 10.4373 13.339 9.12899C13.339 8.69744 13.2807 8.27999 13.1714 7.88412H20.2007Z" fill="#FD366E" />
</svg>
</div>
</body>
</html>
+22 -20
View File
@@ -86,7 +86,7 @@ $image = $this->getParam('image', '');
- _APP_OPTIONS_ABUSE
- _APP_OPTIONS_ROUTER_PROTECTION
- _APP_OPTIONS_FORCE_HTTPS
- _APP_OPTIONS_FUNCTIONS_FORCE_HTTPS
- _APP_OPTIONS_COMPUTE_FORCE_HTTPS
- _APP_OPENSSL_KEY_V1
- _APP_DOMAIN
- _APP_DOMAIN_TARGET
@@ -133,12 +133,14 @@ $image = $this->getParam('image', '');
- _APP_STORAGE_WASABI_SECRET
- _APP_STORAGE_WASABI_REGION
- _APP_STORAGE_WASABI_BUCKET
- _APP_FUNCTIONS_SIZE_LIMIT
- _APP_FUNCTIONS_TIMEOUT
- _APP_FUNCTIONS_BUILD_TIMEOUT
- _APP_FUNCTIONS_CPUS
- _APP_FUNCTIONS_MEMORY
- _APP_COMPUTE_SIZE_LIMIT
- _APP_COMPUTE_TIMEOUT
- _APP_COMPUTE_BUILD_TIMEOUT
- _APP_COMPUTE_CPUS
- _APP_COMPUTE_MEMORY
- _APP_FUNCTIONS_RUNTIMES
- _APP_SITES_FRAMEWORKS
- _APP_SITES_RUNTIMES
- _APP_EXECUTOR_SECRET
- _APP_EXECUTOR_HOST
- _APP_LOGGING_CONFIG
@@ -402,13 +404,13 @@ $image = $this->getParam('image', '');
- _APP_VCS_GITHUB_APP_NAME
- _APP_VCS_GITHUB_PRIVATE_KEY
- _APP_VCS_GITHUB_APP_ID
- _APP_FUNCTIONS_TIMEOUT
- _APP_FUNCTIONS_BUILD_TIMEOUT
- _APP_FUNCTIONS_CPUS
- _APP_FUNCTIONS_MEMORY
- _APP_FUNCTIONS_SIZE_LIMIT
- _APP_COMPUTE_TIMEOUT
- _APP_COMPUTE_BUILD_TIMEOUT
- _APP_COMPUTE_CPUS
- _APP_COMPUTE_MEMORY
- _APP_COMPUTE_SIZE_LIMIT
- _APP_OPTIONS_FORCE_HTTPS
- _APP_OPTIONS_FUNCTIONS_FORCE_HTTPS
- _APP_OPTIONS_COMPUTE_FORCE_HTTPS
- _APP_DOMAIN
- _APP_STORAGE_DEVICE
- _APP_STORAGE_S3_ACCESS_KEY
@@ -493,10 +495,10 @@ $image = $this->getParam('image', '');
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_FUNCTIONS_TIMEOUT
- _APP_FUNCTIONS_BUILD_TIMEOUT
- _APP_FUNCTIONS_CPUS
- _APP_FUNCTIONS_MEMORY
- _APP_COMPUTE_TIMEOUT
- _APP_COMPUTE_BUILD_TIMEOUT
- _APP_COMPUTE_CPUS
- _APP_COMPUTE_MEMORY
- _APP_EXECUTOR_SECRET
- _APP_EXECUTOR_HOST
- _APP_USAGE_STATS
@@ -859,7 +861,7 @@ $image = $this->getParam('image', '');
<<: *x-logging
restart: unless-stopped
stop_signal: SIGINT
image: openruntimes/executor:0.6.11
image: openruntimes/executor:0.7.0
networks:
- appwrite
- runtimes
@@ -871,9 +873,9 @@ $image = $this->getParam('image', '');
# It's not possible to share mount file between 2 containers without host mount (copying is too slow)
- /tmp:/tmp:rw
environment:
- OPR_EXECUTOR_INACTIVE_TRESHOLD=$_APP_FUNCTIONS_INACTIVE_THRESHOLD
- OPR_EXECUTOR_MAINTENANCE_INTERVAL=$_APP_FUNCTIONS_MAINTENANCE_INTERVAL
- OPR_EXECUTOR_NETWORK=$_APP_FUNCTIONS_RUNTIMES_NETWORK
- OPR_EXECUTOR_INACTIVE_TRESHOLD=$_APP_COMPUTE_INACTIVE_THRESHOLD
- OPR_EXECUTOR_MAINTENANCE_INTERVAL=$_APP_COMPUTE_MAINTENANCE_INTERVAL
- OPR_EXECUTOR_NETWORK=$_APP_COMPUTE_RUNTIMES_NETWORK
- OPR_EXECUTOR_DOCKER_HUB_USERNAME=$_APP_DOCKER_HUB_USERNAME
- OPR_EXECUTOR_DOCKER_HUB_PASSWORD=$_APP_DOCKER_HUB_PASSWORD
- OPR_EXECUTOR_ENV=$_APP_ENV
+4
View File
@@ -333,6 +333,10 @@ Server::setResource('pools', function (Registry $register) {
return $register->get('pools');
}, ['register']);
Server::setResource('deviceForSites', function (Document $project) {
return getDevice(APP_STORAGE_SITES . '/app-' . $project->getId());
}, ['project']);
Server::setResource('deviceForFunctions', function (Document $project) {
return getDevice(APP_STORAGE_FUNCTIONS . '/app-' . $project->getId());
}, ['project']);
Executable
+3
View File
@@ -0,0 +1,3 @@
#!/bin/sh
php /usr/src/code/app/cli.php screenshot $@
+7 -4
View File
@@ -14,7 +14,8 @@
"test": "vendor/bin/phpunit",
"lint": "vendor/bin/pint --test",
"format": "vendor/bin/pint",
"bench": "vendor/bin/phpbench run --report=benchmark"
"bench": "vendor/bin/phpbench run --report=benchmark",
"check": "./vendor/bin/phpstan analyse -c phpstan.neon"
},
"autoload": {
"psr-4": {
@@ -43,7 +44,7 @@
"ext-openssl": "*",
"ext-zlib": "*",
"ext-sockets": "*",
"appwrite/php-runtimes": "0.16.*",
"appwrite/php-runtimes": "0.18.*",
"appwrite/php-clamav": "2.0.*",
"utopia-php/abuse": "0.51.*",
"utopia-php/analytics": "0.10.*",
@@ -51,6 +52,7 @@
"utopia-php/cache": "0.12.*",
"utopia-php/cli": "0.15.*",
"utopia-php/config": "0.2.*",
"utopia-php/detector": "0.1.*",
"utopia-php/database": "0.60.*",
"utopia-php/domains": "0.5.*",
"utopia-php/dsn": "0.2.1",
@@ -87,6 +89,7 @@
"appwrite/sdk-generator": "0.40.*",
"phpunit/phpunit": "9.*",
"swoole/ide-helper": "5.1.2",
"phpstan/phpstan": "1.8.*",
"textalk/websocket": "1.5.*",
"laravel/pint": "1.*",
"phpbench/phpbench": "1.*"
@@ -99,8 +102,8 @@
"php": "8.3"
},
"allow-plugins": {
"php-http/discovery": false,
"tbachert/spi": false
"php-http/discovery": true,
"tbachert/spi": true
}
}
}
Generated
+133 -29
View File
@@ -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": "58ad2e1375ec47d944b96864d4aae63f",
"content-hash": "6e6444246ba207b6bf88c20340835fb5",
"packages": [
{
"name": "adhocore/jwt",
@@ -157,16 +157,16 @@
},
{
"name": "appwrite/php-runtimes",
"version": "0.16.5",
"version": "0.18.1",
"source": {
"type": "git",
"url": "https://github.com/appwrite/runtimes.git",
"reference": "1e430646fdf847a7caf3c611dcf3d6d5a28c3fd9"
"reference": "97b5d97ae2c0fc9a2a374769eadff024f95783aa"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/appwrite/runtimes/zipball/1e430646fdf847a7caf3c611dcf3d6d5a28c3fd9",
"reference": "1e430646fdf847a7caf3c611dcf3d6d5a28c3fd9",
"url": "https://api.github.com/repos/appwrite/runtimes/zipball/97b5d97ae2c0fc9a2a374769eadff024f95783aa",
"reference": "97b5d97ae2c0fc9a2a374769eadff024f95783aa",
"shasum": ""
},
"require": {
@@ -206,9 +206,9 @@
],
"support": {
"issues": "https://github.com/appwrite/runtimes/issues",
"source": "https://github.com/appwrite/runtimes/tree/0.16.5"
"source": "https://github.com/appwrite/runtimes/tree/0.18.1"
},
"time": "2024-11-25T15:17:06+00:00"
"time": "2025-03-11T14:05:46+00:00"
},
{
"name": "beberlei/assert",
@@ -3759,6 +3759,51 @@
},
"time": "2025-03-05T01:23:14+00:00"
},
{
"name": "utopia-php/detector",
"version": "0.1.1",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/detector.git",
"reference": "5dcabbfcf99731f3a37d86b7cb1e93c968baf64b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/detector/zipball/5dcabbfcf99731f3a37d86b7cb1e93c968baf64b",
"reference": "5dcabbfcf99731f3a37d86b7cb1e93c968baf64b",
"shasum": ""
},
"require": {
"php": ">=8.0"
},
"require-dev": {
"laravel/pint": "1.2.*",
"phpstan/phpstan": "1.8.*",
"phpunit/phpunit": "^9.4"
},
"type": "library",
"autoload": {
"psr-4": {
"Utopia\\Detector\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "A simple library for fast and reliable environment identification.",
"keywords": [
"detector",
"framework",
"php",
"utopia"
],
"support": {
"issues": "https://github.com/utopia-php/detector/issues",
"source": "https://github.com/utopia-php/detector/tree/0.1.1"
},
"time": "2025-03-08T22:25:49+00:00"
},
{
"name": "utopia-php/domains",
"version": "0.5.0",
@@ -5043,16 +5088,16 @@
"packages-dev": [
{
"name": "appwrite/sdk-generator",
"version": "0.40.2",
"version": "0.40.7",
"source": {
"type": "git",
"url": "https://github.com/appwrite/sdk-generator.git",
"reference": "56f09482d9e2f223911277ab887f197402708049"
"reference": "9e89b0bc4d8e6c81817d27096629f34a149fa873"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/56f09482d9e2f223911277ab887f197402708049",
"reference": "56f09482d9e2f223911277ab887f197402708049",
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/9e89b0bc4d8e6c81817d27096629f34a149fa873",
"reference": "9e89b0bc4d8e6c81817d27096629f34a149fa873",
"shasum": ""
},
"require": {
@@ -5088,9 +5133,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.40.2"
"source": "https://github.com/appwrite/sdk-generator/tree/0.40.7"
},
"time": "2025-03-06T16:31:03+00:00"
"time": "2025-03-12T08:43:55+00:00"
},
{
"name": "doctrine/annotations",
@@ -5317,16 +5362,16 @@
},
{
"name": "laravel/pint",
"version": "v1.21.0",
"version": "v1.21.1",
"source": {
"type": "git",
"url": "https://github.com/laravel/pint.git",
"reference": "531fa0871fbde719c51b12afa3a443b8f4e4b425"
"reference": "c44bffbb2334e90fba560933c45948fa4a3f3e86"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/pint/zipball/531fa0871fbde719c51b12afa3a443b8f4e4b425",
"reference": "531fa0871fbde719c51b12afa3a443b8f4e4b425",
"url": "https://api.github.com/repos/laravel/pint/zipball/c44bffbb2334e90fba560933c45948fa4a3f3e86",
"reference": "c44bffbb2334e90fba560933c45948fa4a3f3e86",
"shasum": ""
},
"require": {
@@ -5337,9 +5382,9 @@
"php": "^8.2.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.68.5",
"illuminate/view": "^11.42.0",
"larastan/larastan": "^3.0.4",
"friendsofphp/php-cs-fixer": "^3.70.2",
"illuminate/view": "^11.44.1",
"larastan/larastan": "^3.1.0",
"laravel-zero/framework": "^11.36.1",
"mockery/mockery": "^1.6.12",
"nunomaduro/termwind": "^2.3",
@@ -5379,7 +5424,7 @@
"issues": "https://github.com/laravel/pint/issues",
"source": "https://github.com/laravel/pint"
},
"time": "2025-02-18T03:18:57+00:00"
"time": "2025-03-11T03:22:21+00:00"
},
{
"name": "matthiasmullie/minify",
@@ -5794,16 +5839,16 @@
},
{
"name": "phpbench/phpbench",
"version": "1.4.0",
"version": "1.4.1",
"source": {
"type": "git",
"url": "https://github.com/phpbench/phpbench.git",
"reference": "4248817222514421cba466bfa7adc7d8932345d4"
"reference": "78cd98a9aa34e0f8f80ca01972a8b88d2c30194b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpbench/phpbench/zipball/4248817222514421cba466bfa7adc7d8932345d4",
"reference": "4248817222514421cba466bfa7adc7d8932345d4",
"url": "https://api.github.com/repos/phpbench/phpbench/zipball/78cd98a9aa34e0f8f80ca01972a8b88d2c30194b",
"reference": "78cd98a9aa34e0f8f80ca01972a8b88d2c30194b",
"shasum": ""
},
"require": {
@@ -5880,7 +5925,7 @@
],
"support": {
"issues": "https://github.com/phpbench/phpbench/issues",
"source": "https://github.com/phpbench/phpbench/tree/1.4.0"
"source": "https://github.com/phpbench/phpbench/tree/1.4.1"
},
"funding": [
{
@@ -5888,7 +5933,66 @@
"type": "github"
}
],
"time": "2025-01-26T19:54:45+00:00"
"time": "2025-03-12T08:01:40+00:00"
},
{
"name": "phpstan/phpstan",
"version": "1.8.11",
"source": {
"type": "git",
"url": "https://github.com/phpstan/phpstan.git",
"reference": "46e223dd68a620da18855c23046ddb00940b4014"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/46e223dd68a620da18855c23046ddb00940b4014",
"reference": "46e223dd68a620da18855c23046ddb00940b4014",
"shasum": ""
},
"require": {
"php": "^7.2|^8.0"
},
"conflict": {
"phpstan/phpstan-shim": "*"
},
"bin": [
"phpstan",
"phpstan.phar"
],
"type": "library",
"autoload": {
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"description": "PHPStan - PHP Static Analysis Tool",
"keywords": [
"dev",
"static analysis"
],
"support": {
"issues": "https://github.com/phpstan/phpstan/issues",
"source": "https://github.com/phpstan/phpstan/tree/1.8.11"
},
"funding": [
{
"url": "https://github.com/ondrejmirtes",
"type": "github"
},
{
"url": "https://github.com/phpstan",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan",
"type": "tidelift"
}
],
"time": "2022-10-24T15:45:13+00:00"
},
{
"name": "phpunit/php-code-coverage",
@@ -8402,7 +8506,7 @@
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {},
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
@@ -8426,5 +8530,5 @@
"platform-overrides": {
"php": "8.3"
},
"plugin-api-version": "2.6.0"
"plugin-api-version": "2.3.0"
}
+41 -23
View File
@@ -76,6 +76,8 @@ services:
- appwrite-config:/storage/config:rw
- appwrite-certificates:/storage/certificates:rw
- appwrite-functions:/storage/functions:rw
- appwrite-sites:/storage/sites:rw
- appwrite-builds:/storage/builds:rw
- ./phpunit.xml:/usr/src/code/phpunit.xml
- ./tests:/usr/src/code/tests
- ./app:/usr/src/code/app
@@ -110,7 +112,7 @@ services:
- _APP_OPTIONS_ABUSE
- _APP_OPTIONS_ROUTER_PROTECTION
- _APP_OPTIONS_FORCE_HTTPS
- _APP_OPTIONS_FUNCTIONS_FORCE_HTTPS
- _APP_OPTIONS_COMPUTE_FORCE_HTTPS
- _APP_OPENSSL_KEY_V1
- _APP_DOMAIN
- _APP_DOMAIN_TARGET
@@ -157,12 +159,15 @@ services:
- _APP_STORAGE_WASABI_SECRET
- _APP_STORAGE_WASABI_REGION
- _APP_STORAGE_WASABI_BUCKET
- _APP_FUNCTIONS_SIZE_LIMIT
- _APP_FUNCTIONS_TIMEOUT
- _APP_FUNCTIONS_BUILD_TIMEOUT
- _APP_FUNCTIONS_CPUS
- _APP_FUNCTIONS_MEMORY
- _APP_COMPUTE_SIZE_LIMIT
- _APP_COMPUTE_TIMEOUT
- _APP_COMPUTE_BUILD_TIMEOUT
- _APP_COMPUTE_CPUS
- _APP_COMPUTE_MEMORY
- _APP_FUNCTIONS_RUNTIMES
- _APP_SITES_RUNTIMES
- _APP_SITES_FRAMEWORKS
- _APP_DOMAIN_SITES
- _APP_EXECUTOR_SECRET
- _APP_EXECUTOR_HOST
- _APP_LOGGING_CONFIG
@@ -201,7 +206,7 @@ services:
appwrite-console:
<<: *x-logging
container_name: appwrite-console
image: appwrite/console:5.2.27
image: appwrite/console:5.3.0-sites-rc.24
restart: unless-stopped
networks:
- appwrite
@@ -344,6 +349,7 @@ services:
- appwrite-uploads:/storage/uploads:rw
- appwrite-cache:/storage/cache:rw
- appwrite-functions:/storage/functions:rw
- appwrite-sites:/storage/sites:rw
- appwrite-builds:/storage/builds:rw
- appwrite-certificates:/storage/certificates:rw
- ./app:/usr/src/code/app
@@ -430,7 +436,9 @@ services:
- appwrite
volumes:
- appwrite-functions:/storage/functions:rw
- appwrite-sites:/storage/sites:rw
- appwrite-builds:/storage/builds:rw
- appwrite-uploads:/storage/uploads:rw
- ./app:/usr/src/code/app
- ./src:/usr/src/code/src
depends_on:
@@ -455,13 +463,13 @@ services:
- _APP_VCS_GITHUB_APP_NAME
- _APP_VCS_GITHUB_PRIVATE_KEY
- _APP_VCS_GITHUB_APP_ID
- _APP_FUNCTIONS_TIMEOUT
- _APP_FUNCTIONS_BUILD_TIMEOUT
- _APP_FUNCTIONS_CPUS
- _APP_FUNCTIONS_MEMORY
- _APP_FUNCTIONS_SIZE_LIMIT
- _APP_COMPUTE_TIMEOUT
- _APP_COMPUTE_BUILD_TIMEOUT
- _APP_COMPUTE_CPUS
- _APP_COMPUTE_MEMORY
- _APP_COMPUTE_SIZE_LIMIT
- _APP_OPTIONS_FORCE_HTTPS
- _APP_OPTIONS_FUNCTIONS_FORCE_HTTPS
- _APP_OPTIONS_COMPUTE_FORCE_HTTPS
- _APP_DOMAIN
- _APP_STORAGE_DEVICE
- _APP_STORAGE_S3_ACCESS_KEY
@@ -486,6 +494,7 @@ services:
- _APP_STORAGE_WASABI_REGION
- _APP_STORAGE_WASABI_BUCKET
- _APP_DATABASE_SHARED_TABLES
- _APP_DOMAIN_SITES
appwrite-worker-certificates:
entrypoint: worker-certificates
@@ -551,10 +560,10 @@ services:
- _APP_DB_SCHEMA
- _APP_DB_USER
- _APP_DB_PASS
- _APP_FUNCTIONS_TIMEOUT
- _APP_FUNCTIONS_BUILD_TIMEOUT
- _APP_FUNCTIONS_CPUS
- _APP_FUNCTIONS_MEMORY
- _APP_COMPUTE_TIMEOUT
- _APP_COMPUTE_BUILD_TIMEOUT
- _APP_COMPUTE_CPUS
- _APP_COMPUTE_MEMORY
- _APP_EXECUTOR_SECRET
- _APP_EXECUTOR_HOST
- _APP_USAGE_STATS
@@ -942,12 +951,18 @@ services:
environment:
- _APP_ASSISTANT_OPENAI_API_KEY
appwrite-browser:
container_name: appwrite-browser
image: appwrite/browser:0.2.2
networks:
- appwrite
openruntimes-executor:
container_name: openruntimes-executor
hostname: exc1
<<: *x-logging
stop_signal: SIGINT
image: openruntimes/executor:0.6.11
image: openruntimes/executor:0.7.10
restart: unless-stopped
networks:
- appwrite
@@ -956,19 +971,21 @@ services:
- /var/run/docker.sock:/var/run/docker.sock
- appwrite-builds:/storage/builds:rw
- appwrite-functions:/storage/functions:rw
- appwrite-sites:/storage/sites:rw
# Host mount nessessary to share files between executor and runtimes.
# It's not possible to share mount file between 2 containers without host mount (copying is too slow)
- /tmp:/tmp:rw
environment:
- OPR_EXECUTOR_INACTIVE_TRESHOLD=$_APP_FUNCTIONS_INACTIVE_THRESHOLD
- OPR_EXECUTOR_MAINTENANCE_INTERVAL=$_APP_FUNCTIONS_MAINTENANCE_INTERVAL
- OPR_EXECUTOR_NETWORK=$_APP_FUNCTIONS_RUNTIMES_NETWORK
- OPR_EXECUTOR_IMAGE_PULL=enabled
- OPR_EXECUTOR_INACTIVE_TRESHOLD=$_APP_COMPUTE_INACTIVE_THRESHOLD
- OPR_EXECUTOR_MAINTENANCE_INTERVAL=$_APP_COMPUTE_MAINTENANCE_INTERVAL
- OPR_EXECUTOR_NETWORK=$_APP_COMPUTE_RUNTIMES_NETWORK
- OPR_EXECUTOR_DOCKER_HUB_USERNAME=$_APP_DOCKER_HUB_USERNAME
- OPR_EXECUTOR_DOCKER_HUB_PASSWORD=$_APP_DOCKER_HUB_PASSWORD
- OPR_EXECUTOR_ENV=$_APP_ENV
- OPR_EXECUTOR_RUNTIMES=$_APP_FUNCTIONS_RUNTIMES
- OPR_EXECUTOR_RUNTIMES=$_APP_FUNCTIONS_RUNTIMES,$_APP_SITES_RUNTIMES
- OPR_EXECUTOR_SECRET=$_APP_EXECUTOR_SECRET
- OPR_EXECUTOR_RUNTIME_VERSIONS=v2,v4
- OPR_EXECUTOR_RUNTIME_VERSIONS=v2,v5
- OPR_EXECUTOR_LOGGING_CONFIG=$_APP_LOGGING_CONFIG
- OPR_EXECUTOR_STORAGE_DEVICE=$_APP_STORAGE_DEVICE
- OPR_EXECUTOR_STORAGE_S3_ACCESS_KEY=$_APP_STORAGE_S3_ACCESS_KEY
@@ -1126,5 +1143,6 @@ volumes:
appwrite-uploads:
appwrite-certificates:
appwrite-functions:
appwrite-sites:
appwrite-builds:
appwrite-config:
+1 -1
View File
@@ -1 +1 @@
Create a new build for an existing function deployment. This endpoint allows you to rebuild a deployment with the updated function configuration, including its entrypoint and build commands if they have been modified The build process will be queued and executed asynchronously. The original deployment's code will be preserved and used for the new build.
Create a new build for an existing function deployment. This endpoint allows you to rebuild a deployment with the updated function configuration, including its entrypoint and build commands if they have been modified. The build process will be queued and executed asynchronously. The original deployment's code will be preserved and used for the new build.
@@ -1 +1 @@
Get a list of all the project's code deployments. You can use the query params to filter your results.
Get a list of all the function's code deployments. You can use the query params to filter your results.
-1
View File
@@ -1 +0,0 @@
Create a new proxy rule.
+8
View File
@@ -0,0 +1,8 @@
parameters:
level: 8
paths:
- src/Appwrite/Transformation
scanDirectories:
- vendor/swoole/ide-helper
excludePaths:
- tests/resources
Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

+5
View File
@@ -103,6 +103,11 @@ class Auth
*/
public static $cookieName = 'a_session';
/**
* @var string
*/
public static $cookieNamePreview = 'a_jwt_console';
/**
* User Unique ID.
*
+36 -2
View File
@@ -20,6 +20,10 @@ class Key
protected string $name,
protected bool $expired = false,
protected array $disabledMetrics = [],
protected bool $hostnameOverride = false,
protected bool $bannerDisabled = false,
protected bool $projectCheckDisabled = false,
protected bool $previewAuthDisabled = false,
) {
}
@@ -58,6 +62,28 @@ class Key
return $this->disabledMetrics;
}
public function getHostnameOverride(): bool
{
return $this->hostnameOverride;
}
public function isBannerDisabled(): bool
{
return $this->bannerDisabled;
}
public function isPreviewAuthDisabled(): bool
{
return $this->previewAuthDisabled;
}
public function isProjectCheckDisabled(): bool
{
return $this->projectCheckDisabled;
}
/**
* Decode the given secret key into a Key object, containing the project ID, type, role, scopes, and name.
* Can be a stored API key or a dynamic key (JWT).
@@ -109,9 +135,13 @@ class Key
$name = $payload['name'] ?? 'Dynamic Key';
$projectId = $payload['projectId'] ?? '';
$disabledMetrics = $payload['disabledMetrics'] ?? [];
$hostnameOverride = $payload['hostnameOverride'] ?? false;
$bannerDisabled = $payload['bannerDisabled'] ?? false;
$projectCheckDisabled = $payload['projectCheckDisabled'] ?? false;
$previewAuthDisabled = $payload['previewAuthDisabled'] ?? false;
$scopes = \array_merge($payload['scopes'] ?? [], $scopes);
if ($projectId !== $project->getId()) {
if (!$projectCheckDisabled && $projectId !== $project->getId()) {
return $guestKey;
}
@@ -122,7 +152,11 @@ class Key
$scopes,
$name,
$expired,
$disabledMetrics
$disabledMetrics,
$hostnameOverride,
$bannerDisabled,
$projectCheckDisabled,
$previewAuthDisabled
);
case API_KEY_STANDARD:
$key = $project->find(
+3
View File
@@ -24,6 +24,9 @@ class Event
public const FUNCTIONS_QUEUE_NAME = 'v1-functions';
public const FUNCTIONS_CLASS_NAME = 'FunctionsV1';
public const SITES_QUEUE_NAME = 'v1-sites';
public const SITES_CLASS_NAME = 'SitesV1';
/** remove */
public const USAGE_QUEUE_NAME = 'v1-usage';
public const USAGE_CLASS_NAME = 'UsageV1';
+1 -1
View File
@@ -35,7 +35,7 @@ class Realtime extends Event
* Set subscribers for this realtime event.
*
* @param array $subscribers
* @return array
* @return self
*/
public function setSubscribers(array $subscribers): self
{
+13
View File
@@ -118,6 +118,9 @@ class Exception extends \Exception
public const TEAM_INVITE_MISMATCH = 'team_invite_mismatch';
public const TEAM_ALREADY_EXISTS = 'team_already_exists';
/** Console */
public const RESOURCE_ALREADY_EXISTS = 'resource_already_exists';
/** Membership */
public const MEMBERSHIP_NOT_FOUND = 'membership_not_found';
public const MEMBERSHIP_ALREADY_CONFIRMED = 'membership_already_confirmed';
@@ -151,12 +154,18 @@ class Exception extends \Exception
public const PROVIDER_CONTRIBUTION_CONFLICT = 'provider_contribution_conflict';
public const GENERAL_PROVIDER_FAILURE = 'general_provider_failure';
/** Sites */
public const SITE_NOT_FOUND = 'site_not_found';
public const SITE_FRAMEWORK_UNSUPPORTED = 'site_framework_unsupported';
public const SITE_TEMPLATE_NOT_FOUND = 'site_template_not_found';
/** Functions */
public const FUNCTION_NOT_FOUND = 'function_not_found';
public const FUNCTION_RUNTIME_UNSUPPORTED = 'function_runtime_unsupported';
public const FUNCTION_ENTRYPOINT_MISSING = 'function_entrypoint_missing';
public const FUNCTION_SYNCHRONOUS_TIMEOUT = 'function_synchronous_timeout';
public const FUNCTION_TEMPLATE_NOT_FOUND = 'function_template_not_found';
public const FUNCTION_RUNTIME_NOT_DETECTED = 'function_runtime_not_detected';
/** Deployments */
public const DEPLOYMENT_NOT_FOUND = 'deployment_not_found';
@@ -171,6 +180,9 @@ class Exception extends \Exception
public const EXECUTION_NOT_FOUND = 'execution_not_found';
public const EXECUTION_IN_PROGRESS = 'execution_in_progress';
/** Log */
public const LOG_NOT_FOUND = 'log_not_found';
/** Databases */
public const DATABASE_NOT_FOUND = 'database_not_found';
public const DATABASE_ALREADY_EXISTS = 'database_already_exists';
@@ -247,6 +259,7 @@ class Exception extends \Exception
/** Variables */
public const VARIABLE_NOT_FOUND = 'variable_not_found';
public const VARIABLE_ALREADY_EXISTS = 'variable_already_exists';
public const VARIABLE_CANNOT_UNSET_SECRET = 'variable_cannot_unset_secret';
/** Platform */
public const PLATFORM_NOT_FOUND = 'platform_not_found';
@@ -349,6 +349,16 @@ class Realtime extends Adapter
$roles = [Role::team($project->getAttribute('teamId'))->toString()];
}
break;
case 'sites':
if ($parts[2] === 'deployments') {
$channels[] = 'console';
$channels[] = 'projects.' . $project->getId();
$projectId = 'console';
$roles = [Role::team($project->getAttribute('teamId'))->toString()];
}
break;
case 'migrations':
$channels[] = 'console';
+1 -1
View File
@@ -186,7 +186,7 @@ class V21 extends Migration
$document->setAttribute('scopes', []);
// Add size attribute
$document->setAttribute('specification', APP_FUNCTION_SPECIFICATION_DEFAULT);
$document->setAttribute('specification', APP_COMPUTE_SPECIFICATION_DEFAULT);
}
return $document;
+8
View File
@@ -2,7 +2,11 @@
namespace Appwrite\Platform;
use Appwrite\Platform\Modules\Console;
use Appwrite\Platform\Modules\Core;
use Appwrite\Platform\Modules\Functions;
use Appwrite\Platform\Modules\Proxy;
use Appwrite\Platform\Modules\Sites;
use Utopia\Platform\Platform;
class Appwrite extends Platform
@@ -10,5 +14,9 @@ class Appwrite extends Platform
public function __construct()
{
parent::__construct(new Core());
$this->addModule(new Functions\Module());
$this->addModule(new Sites\Module());
$this->addModule(new Console\Module());
$this->addModule(new Proxy\Module());
}
}
@@ -0,0 +1,255 @@
<?php
namespace Appwrite\Platform\Modules\Compute;
use Appwrite\Event\Build;
use Appwrite\Extend\Exception;
use Appwrite\Query;
use Utopia\CLI\Console;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Helpers\ID;
use Utopia\Database\Helpers\Permission;
use Utopia\Database\Helpers\Role;
use Utopia\Database\Validator\Authorization;
use Utopia\Platform\Action;
use Utopia\Swoole\Request;
use Utopia\System\System;
use Utopia\VCS\Adapter\Git\GitHub;
use Utopia\VCS\Exception\RepositoryNotFound;
class Base extends Action
{
public function redeployVcsFunction(Request $request, Document $function, Document $project, Document $installation, Database $dbForProject, Build $queueForBuilds, Document $template, GitHub $github, bool $activate, string $referenceType = 'branch', string $reference = ''): Document
{
$deploymentId = ID::unique();
$entrypoint = $function->getAttribute('entrypoint', '');
$providerInstallationId = $installation->getAttribute('providerInstallationId', '');
$privateKey = System::getEnv('_APP_VCS_GITHUB_PRIVATE_KEY');
$githubAppId = System::getEnv('_APP_VCS_GITHUB_APP_ID');
$github->initializeVariables($providerInstallationId, $privateKey, $githubAppId);
$owner = $github->getOwnerName($providerInstallationId);
$providerRepositoryId = $function->getAttribute('providerRepositoryId', '');
try {
$repositoryName = $github->getRepositoryName($providerRepositoryId) ?? '';
if (empty($repositoryName)) {
throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND);
}
} catch (RepositoryNotFound $e) {
throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND);
}
// TODO: Support tag and commit in future
if ($referenceType === 'branch') {
$providerBranch = empty($reference) ? $function->getAttribute('providerBranch', 'main') : $reference;
}
$authorUrl = "https://github.com/$owner";
$repositoryUrl = "https://github.com/$owner/$repositoryName";
$branchUrl = "https://github.com/$owner/$repositoryName/tree/$providerBranch";
$commitDetails = [];
if ($template->isEmpty()) {
try {
$commitDetails = $github->getLatestCommit($owner, $repositoryName, $providerBranch);
} catch (\Throwable $error) {
Console::warning('Failed to get latest commit details');
Console::warning($error->getMessage());
Console::warning($error->getTraceAsString());
}
}
$deployment = $dbForProject->createDocument('deployments', new Document([
'$id' => $deploymentId,
'$permissions' => [
Permission::read(Role::any()),
Permission::update(Role::any()),
Permission::delete(Role::any()),
],
'resourceId' => $function->getId(),
'resourceInternalId' => $function->getInternalId(),
'resourceType' => 'functions',
'entrypoint' => $entrypoint,
'buildCommands' => $function->getAttribute('commands', ''),
'type' => 'vcs',
'installationId' => $installation->getId(),
'installationInternalId' => $installation->getInternalId(),
'providerRepositoryId' => $providerRepositoryId,
'repositoryId' => $function->getAttribute('repositoryId', ''),
'repositoryInternalId' => $function->getAttribute('repositoryInternalId', ''),
'providerBranchUrl' => $branchUrl,
'providerRepositoryName' => $repositoryName,
'providerRepositoryOwner' => $owner,
'providerRepositoryUrl' => $repositoryUrl,
'providerCommitHash' => $commitDetails['commitHash'] ?? '',
'providerCommitAuthorUrl' => $authorUrl,
'providerCommitAuthor' => $commitDetails['commitAuthor'] ?? '',
'providerCommitMessage' => mb_strimwidth($commitDetails['commitMessage'] ?? '', 0, 255, '...'),
'providerCommitUrl' => $commitDetails['commitUrl'] ?? '',
'providerBranch' => $providerBranch,
'providerRootDirectory' => $function->getAttribute('providerRootDirectory', ''),
'search' => implode(' ', [$deploymentId, $entrypoint]),
'activate' => $activate,
]));
$queueForBuilds
->setType(BUILD_TYPE_DEPLOYMENT)
->setResource($function)
->setDeployment($deployment)
->setTemplate($template);
return $deployment;
}
public function redeployVcsSite(Request $request, Document $site, Document $project, Document $installation, Database $dbForProject, Database $dbForPlatform, Build $queueForBuilds, Document $template, GitHub $github, bool $activate, string $referenceType = 'branch', string $reference = ''): Document
{
$deploymentId = ID::unique();
$providerInstallationId = $installation->getAttribute('providerInstallationId', '');
$privateKey = System::getEnv('_APP_VCS_GITHUB_PRIVATE_KEY');
$githubAppId = System::getEnv('_APP_VCS_GITHUB_APP_ID');
$github->initializeVariables($providerInstallationId, $privateKey, $githubAppId);
$owner = $github->getOwnerName($providerInstallationId);
$providerRepositoryId = $site->getAttribute('providerRepositoryId', '');
try {
$repositoryName = $github->getRepositoryName($providerRepositoryId) ?? '';
if (empty($repositoryName)) {
throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND);
}
} catch (RepositoryNotFound $e) {
throw new Exception(Exception::PROVIDER_REPOSITORY_NOT_FOUND);
}
$commitDetails = [];
$branchUrl = "";
$providerBranch = "";
// TODO: Support tag in future
if ($referenceType === 'branch') {
$providerBranch = empty($reference) ? $site->getAttribute('providerBranch', 'main') : $reference;
$branchUrl = "https://github.com/$owner/$repositoryName/tree/$providerBranch";
try {
$commitDetails = $github->getLatestCommit($owner, $repositoryName, $providerBranch);
} catch (\Throwable $error) {
// Ignore; deployment can continue
}
} elseif ($referenceType === 'commit') {
try {
$commitDetails = $github->getCommit($owner, $repositoryName, $reference);
} catch (\Throwable $error) {
// Ignore; deployment can continue
}
}
$authorUrl = "https://github.com/$owner";
$repositoryUrl = "https://github.com/$owner/$repositoryName";
$commands = [];
if (!empty($site->getAttribute('installCommand', ''))) {
$commands[] = $site->getAttribute('installCommand', '');
}
if (!empty($site->getAttribute('buildCommand', ''))) {
$commands[] = $site->getAttribute('buildCommand', '');
}
$deployment = $dbForProject->createDocument('deployments', new Document([
'$id' => $deploymentId,
'$permissions' => [
Permission::read(Role::any()),
Permission::update(Role::any()),
Permission::delete(Role::any()),
],
'resourceId' => $site->getId(),
'resourceInternalId' => $site->getInternalId(),
'resourceType' => 'sites',
'buildCommands' => implode(' && ', $commands),
'buildOutput' => $site->getAttribute('outputDirectory', ''),
'type' => 'vcs',
'installationId' => $installation->getId(),
'installationInternalId' => $installation->getInternalId(),
'providerRepositoryId' => $providerRepositoryId,
'repositoryId' => $site->getAttribute('repositoryId', ''),
'repositoryInternalId' => $site->getAttribute('repositoryInternalId', ''),
'providerBranchUrl' => $branchUrl,
'providerRepositoryName' => $repositoryName,
'providerRepositoryOwner' => $owner,
'providerRepositoryUrl' => $repositoryUrl,
'providerCommitHash' => $commitDetails['commitHash'] ?? '',
'providerCommitAuthorUrl' => $authorUrl,
'providerCommitAuthor' => $commitDetails['commitAuthor'] ?? '',
'providerCommitMessage' => mb_strimwidth($commitDetails['commitMessage'] ?? '', 0, 255, '...'),
'providerCommitUrl' => $commitDetails['commitUrl'] ?? '',
'providerBranch' => $providerBranch,
'providerRootDirectory' => $site->getAttribute('providerRootDirectory', ''),
'search' => implode(' ', [$deploymentId]),
'activate' => $activate,
]));
$sitesDomain = System::getEnv('_APP_DOMAIN_SITES', '');
$domain = ID::unique() . "." . $sitesDomain;
// TODO: @christyjacob remove once we migrate the rules in 1.7.x
$ruleId = System::getEnv('_APP_RULES_FORMAT') === 'md5' ? md5($domain) : ID::unique();
Authorization::skip(
fn () => $dbForPlatform->createDocument('rules', new Document([
'$id' => $ruleId,
'projectId' => $project->getId(),
'projectInternalId' => $project->getInternalId(),
'domain' => $domain,
'trigger' => 'deployment',
'type' => 'deployment',
'deploymentId' => $deployment->getId(),
'deploymentInternalId' => $deployment->getInternalId(),
'deploymentResourceType' => 'site',
'deploymentResourceId' => $site->getId(),
'deploymentResourceInternalId' => $site->getInternalId(),
'deploymentVcsProviderBranch' => $providerBranch,
'status' => 'verified',
'certificateId' => '',
'search' => implode(' ', [$ruleId, $domain]),
]))
);
$queueForBuilds
->setType(BUILD_TYPE_DEPLOYMENT)
->setResource($site)
->setDeployment($deployment)
->setTemplate($template);
return $deployment;
}
protected function listRules(Document $project, array $queries, Database $database, callable $callback): void
{
$limit = 100;
$cursor = null;
do {
$queries = \array_merge([
Query::limit($limit),
Query::equal("projectInternalId", [$project->getInternalId()])
], $queries);
if ($cursor !== null) {
$queries[] = Query::cursorAfter($cursor);
}
$results = $database->find('rules', $queries);
$total = \count($results);
if ($total > 0) {
$cursor = $results[$total - 1];
}
if ($total < $limit) {
$cursor = null;
}
foreach ($results as $document) {
if (is_callable($callback)) {
$callback($document);
}
}
} while (!\is_null($cursor));
}
}
@@ -1,6 +1,6 @@
<?php
namespace Appwrite\Functions;
namespace Appwrite\Platform\Modules\Compute;
class Specification
{
@@ -1,10 +1,10 @@
<?php
namespace Appwrite\Functions\Validator;
namespace Appwrite\Platform\Modules\Compute\Validator;
use Utopia\Validator;
class RuntimeSpecification extends Validator
class Specification extends Validator
{
private array $plan;
@@ -35,8 +35,8 @@ class RuntimeSpecification extends Validator
foreach ($this->specifications as $size => $values) {
if ($values['cpus'] <= $this->maxCpus && $values['memory'] <= $this->maxMemory) {
if (!empty($this->plan) && array_key_exists('runtimeSpecifications', $this->plan)) {
if (!\in_array($size, $this->plan['runtimeSpecifications'])) {
if (!empty($this->plan) && array_key_exists('specifications', $this->plan)) {
if (!\in_array($size, $this->plan['specifications'])) {
continue;
}
}
@@ -0,0 +1,89 @@
<?php
namespace Appwrite\Platform\Modules\Console\Http\Resources;
use Appwrite\Extend\Exception;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\ContentType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Response;
use Utopia\Database\Database;
use Utopia\Database\Query;
use Utopia\Database\Validator\Authorization;
use Utopia\Platform\Action;
use Utopia\Platform\Scope\HTTP;
use Utopia\Validator\Domain;
use Utopia\Validator\Text;
use Utopia\Validator\WhiteList;
class Get extends Action
{
use HTTP;
public static function getName()
{
return 'getResource';
}
public function __construct()
{
$this
->setHttpMethod(Action::HTTP_REQUEST_METHOD_GET)
->setHttpPath('/v1/console/resources')
->desc('Check resource ID availability')
->groups(['api', 'projects'])
->label('scope', 'rules.read')
->label('sdk', new Method(
namespace: 'console',
name: 'getResource',
description: <<<EOT
Check if a resource ID is available.
EOT,
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_NOCONTENT,
model: Response::MODEL_NONE,
)
],
contentType: ContentType::NONE,
))
->label('abuse-limit', 120)
->label('abuse-key', 'userId:{userId}, url:{url}')
->label('abuse-time', 60)
->param('value', '', new Text(256), 'Resource value.')
->param('type', '', new WhiteList(['rules']), 'Resource type.')
->inject('response')
->inject('dbForPlatform')
->callback([$this, 'action']);
}
public function action(
string $value,
string $type,
Response $response,
Database $dbForPlatform
) {
if ($type === 'rules') {
$validator = new Domain($value);
if (!$validator->isValid($value)) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, $validator->getDescription());
}
$document = Authorization::skip(fn () => $dbForPlatform->findOne('rules', [
Query::equal('domain', [$value]),
]));
if (!$document->isEmpty()) {
throw new Exception(Exception::RESOURCE_ALREADY_EXISTS);
}
$response->noContent();
}
// Only occurs if type is added into whitelist, but not supported in action
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Invalid type');
}
}
@@ -0,0 +1,14 @@
<?php
namespace Appwrite\Platform\Modules\Console;
use Appwrite\Platform\Modules\Console\Services\Http;
use Utopia\Platform;
class Module extends Platform\Module
{
public function __construct()
{
$this->addService('http', new Http());
}
}

Some files were not shown because too many files have changed in this diff Show More