Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8a4c5bec27 | ||
|
|
97acbd42ba | ||
|
|
79e066a4d7 | ||
|
|
725dff7f0f | ||
|
|
358e096301 | ||
|
|
74c050ffb6 | ||
|
|
8376b176cb | ||
|
|
69ed3bb776 | ||
|
|
262b2e6cff | ||
|
|
acb9548e85 | ||
|
|
ee1ee7ecfe | ||
|
|
b14d76af0d | ||
|
|
f2ba319e6e | ||
|
|
f1877476d0 | ||
|
|
75b3e78098 | ||
|
|
82e16e6d9e | ||
|
|
63710e8ff8 | ||
|
|
794329be82 | ||
|
|
5549cd8900 | ||
|
|
a840d9de20 | ||
|
|
1a90c8aab5 | ||
|
|
7f2fdf623c | ||
|
|
39699d16ba | ||
|
|
8f391db39a | ||
|
|
2f9802afa2 | ||
|
|
3af1910cf9 | ||
|
|
796a845bcf | ||
|
|
56736a79e2 | ||
|
|
536319b440 | ||
|
|
ea35b6226d | ||
|
|
42cd1df77d | ||
|
|
994e2faa42 | ||
|
|
ba26dd6df5 | ||
|
|
0170b4c9e8 | ||
|
|
ab7041d653 | ||
|
|
1a56be197c | ||
|
|
b79b320414 | ||
|
|
1b04ae6d96 | ||
|
|
95e96b3bfb | ||
|
|
18e4be2eab | ||
|
|
7f05a74b31 | ||
|
|
733c5ad97d | ||
|
|
71b56fc504 | ||
|
|
62eb159e6a | ||
|
|
f61db29498 | ||
|
|
d8418a222c | ||
|
|
63c7f4c8bc | ||
|
|
b11ad4b1c9 | ||
|
|
93510d170e | ||
|
|
be3d18ab41 | ||
|
|
efc5b9e353 | ||
|
|
d86cf7b437 | ||
|
|
aabee0ac37 | ||
|
|
4e1168654d | ||
|
|
254018071a | ||
|
|
e904ab6232 | ||
|
|
fed6cefa81 | ||
|
|
640f09c49b | ||
|
|
06bb001d0b | ||
|
|
3730ff4895 | ||
|
|
05771c46d6 | ||
|
|
4ff0b6283a | ||
|
|
852a16d01b | ||
|
|
084b6c799a | ||
|
|
eddeac6e4f | ||
|
|
874f60dce6 | ||
|
|
d21814c51f | ||
|
|
65bcf7898e | ||
|
|
7e460f6155 | ||
|
|
1a271ff272 | ||
|
|
5963631c70 | ||
|
|
0fa5460a7e | ||
|
|
12e3d70032 | ||
|
|
5f766f6a13 | ||
|
|
7d27ceef43 | ||
|
|
9c3cfc4f83 | ||
|
|
b4d366eea1 | ||
|
|
8a4954d4e8 | ||
|
|
1943e00e40 | ||
|
|
f75acfa503 | ||
|
|
b69c40345f | ||
|
|
83dd6a9897 | ||
|
|
75f543c6b0 | ||
|
|
232f99c6c9 | ||
|
|
faa1b0a59b | ||
|
|
fe210e0cf0 | ||
|
|
f85bf337b7 | ||
|
|
06020e2b62 | ||
|
|
8ff4d60dbb | ||
|
|
43cd7ac8b3 | ||
|
|
393c4012d9 | ||
|
|
c6a862a0a3 | ||
|
|
1d983a949e | ||
|
|
5e30fc5350 | ||
|
|
a5457da91c | ||
|
|
a37a6d9d7c | ||
|
|
c1ee2f2b41 | ||
|
|
6a584c83c1 | ||
|
|
777fb3fcdd | ||
|
|
6ea20659e6 | ||
|
|
dade177af2 | ||
|
|
97ffbbc44b | ||
|
|
f07c351c94 | ||
|
|
a42522feaa | ||
|
|
9400fdbbe5 | ||
|
|
92b696ea21 | ||
|
|
50ec55d595 | ||
|
|
a7fc8cf84b | ||
|
|
794c6536fb | ||
|
|
2e30c1ba1f | ||
|
|
654d178cf2 | ||
|
|
02e740f8b0 | ||
|
|
62b639ce48 | ||
|
|
825e9639b1 | ||
|
|
9a8a2b5a49 | ||
|
|
4428ed1f7d | ||
|
|
de5f33f206 | ||
|
|
9a44e8130f | ||
|
|
2f3c43d0db | ||
|
|
77d27bdd20 | ||
|
|
87a9d72523 | ||
|
|
f6674f07e4 | ||
|
|
049ad14121 | ||
|
|
a0a82b86dc | ||
|
|
326e62334f | ||
|
|
b29b5da006 | ||
|
|
46039ded2f | ||
|
|
dfce78c421 | ||
|
|
ce3bff13dd | ||
|
|
a031682596 | ||
|
|
9b8dd02a88 | ||
|
|
bbf37e0a0e | ||
|
|
826b034cd2 | ||
|
|
9ee9a8e0ed | ||
|
|
dfc2e87170 | ||
|
|
520b96f0d9 | ||
|
|
ea30d976a8 | ||
|
|
9b8e4dd862 | ||
|
|
ef7b9537f7 | ||
|
|
03c9e57773 | ||
|
|
54413f4c5e | ||
|
|
a2abd982cf | ||
|
|
f5a0008445 | ||
|
|
64183f2946 | ||
|
|
d9eb942e8c | ||
|
|
84e1b050a9 | ||
|
|
e94438927e | ||
|
|
20ad91a906 | ||
|
|
2ae61164d4 | ||
|
|
774a6af333 | ||
|
|
8e03db6c9e | ||
|
|
5dd4348d5c | ||
|
|
64e2f904c5 | ||
|
|
07ceb1991d | ||
|
|
60f34ced91 | ||
|
|
084dcdffd9 | ||
|
|
c303aa57ce | ||
|
|
2384113a04 | ||
|
|
ef37139592 | ||
|
|
8b8f632abe | ||
|
|
7e00bc493c | ||
|
|
8d47d62d7a | ||
|
|
ef030f4a08 | ||
|
|
580204912c | ||
|
|
f91e8be136 | ||
|
|
d75b601a7b | ||
|
|
72d2ba0159 | ||
|
|
dc71c50123 | ||
|
|
d6e7db8900 | ||
|
|
559396295f | ||
|
|
dc6143c773 | ||
|
|
a1c621fab2 | ||
|
|
2510cb9687 | ||
|
|
4efa0a7231 | ||
|
|
4afd9771c6 | ||
|
|
dd75081609 | ||
|
|
a3c176a2bd | ||
|
|
8081759c5c | ||
|
|
bf3b21cdb1 | ||
|
|
26a822e4b2 | ||
|
|
cede07b520 | ||
|
|
92daef51f0 | ||
|
|
0dbb9dadf6 | ||
|
|
496cfa92bc | ||
|
|
ac51fcbf4e | ||
|
|
93d00abfe1 | ||
|
|
d79ab99202 | ||
|
|
1e111294df | ||
|
|
1752e8ed83 | ||
|
|
22598ae41d | ||
|
|
a89f591f63 | ||
|
|
ac9ac3e279 | ||
|
|
859a9c72e1 | ||
|
|
19928bd7dc | ||
|
|
88b3791a24 | ||
|
|
765a0fa891 | ||
|
|
fac42f7ad5 | ||
|
|
d7c163be95 | ||
|
|
16934af49f | ||
|
|
29f660cfd6 | ||
|
|
743ded1e79 | ||
|
|
88ae06af57 | ||
|
|
a54f84fce8 | ||
|
|
f830918c7c | ||
|
|
2ba84bf93f | ||
|
|
474e04479f | ||
|
|
40beecdddc | ||
|
|
427e781b5b | ||
|
|
9e909ee3fc | ||
|
|
eb7daf3edd | ||
|
|
a56086f8bf | ||
|
|
ae835f6cf0 | ||
|
|
666e8f3ec9 | ||
|
|
aeebdadae1 | ||
|
|
0a25463b8d | ||
|
|
7e3b693216 | ||
|
|
a5fc9463c7 | ||
|
|
08ec153585 | ||
|
|
c8f4667b6a | ||
|
|
f9bc5d0cce | ||
|
|
7397d52c0c | ||
|
|
8661ae6840 | ||
|
|
498c1456ed | ||
|
|
2917c66202 | ||
|
|
26c99dca84 | ||
|
|
67d6404c70 | ||
|
|
1394b4349c | ||
|
|
ede068d5f4 | ||
|
|
1c6204118f | ||
|
|
cdc3cb23ec | ||
|
|
9d4806c792 | ||
|
|
54d877fe3e | ||
|
|
c3df0a71e3 | ||
|
|
732e74f114 | ||
|
|
d941d18e8c | ||
|
|
3ccd49e4a5 | ||
|
|
2d761b48d8 | ||
|
|
556bcbf33b | ||
|
|
e6a53a8c15 | ||
|
|
f5f37d6a79 | ||
|
|
f0d8c7382b | ||
|
|
fb19f8d6a6 | ||
|
|
68de687bdf | ||
|
|
a7c1bd94ed | ||
|
|
95aab45cc2 | ||
|
|
4a0d33213a | ||
|
|
322b726196 | ||
|
|
cd25a79694 | ||
|
|
47395c5442 | ||
|
|
d13e8641fd | ||
|
|
acd1dd2479 | ||
|
|
3cc1fb6fb4 | ||
|
|
3932b8bdc1 | ||
|
|
3bb4fde7e6 | ||
|
|
165caef9ab | ||
|
|
055411fbe4 | ||
|
|
63a91e30fa | ||
|
|
f7749bbbef | ||
|
|
c0b574fe9b | ||
|
|
34b8453666 | ||
|
|
ae1eb53e31 | ||
|
|
3b87b42dac | ||
|
|
db8010f7c6 | ||
|
|
c24cebf6ce | ||
|
|
262b152cd9 | ||
|
|
2e4a8dec78 | ||
|
|
2ea18c4761 | ||
|
|
28ef7da231 | ||
|
|
76b154bfce | ||
|
|
c2a60a8569 | ||
|
|
71103b037f | ||
|
|
9459c87b50 | ||
|
|
e5e7c50ca4 | ||
|
|
30cb7e8ff2 | ||
|
|
2f2a743a7f | ||
|
|
feffab137f | ||
|
|
6155fad3e0 | ||
|
|
d1978b102f | ||
|
|
b1854fee10 | ||
|
|
62b1c19357 | ||
|
|
e1dedd2fbb | ||
|
|
51e89f5110 | ||
|
|
81a7ba536c | ||
|
|
fb2649ab41 | ||
|
|
b746642979 | ||
|
|
a6bcc3ce97 | ||
|
|
b30d9eb8ad | ||
|
|
28339f0ed7 | ||
|
|
da9d442473 | ||
|
|
47a6168137 | ||
|
|
9222fec7f8 | ||
|
|
94f3cf7baf | ||
|
|
399afa1b14 | ||
|
|
410388a587 | ||
|
|
4bd08642be | ||
|
|
3ab8503f61 | ||
|
|
75320db428 | ||
|
|
43f0dc0846 | ||
|
|
a10882d7ee | ||
|
|
ec05a3d668 | ||
|
|
3531d223e2 | ||
|
|
e87fe7467e | ||
|
|
f6fbc253f7 | ||
|
|
313444cb12 | ||
|
|
bd58ba32c8 | ||
|
|
80241e37c3 | ||
|
|
4b909ed7dc | ||
|
|
f9ce932ac1 | ||
|
|
f67870925f | ||
|
|
f416e39098 | ||
|
|
c4142565aa | ||
|
|
81bfa5c48d | ||
|
|
0106dc7803 | ||
|
|
3b0d760065 | ||
|
|
e0369ec14f | ||
|
|
c78701ded7 | ||
|
|
adb861b785 | ||
|
|
aae3b40d16 | ||
|
|
6415009f07 | ||
|
|
b46eebb23c | ||
|
|
86a1fbe86a | ||
|
|
14e4854947 | ||
|
|
1c1f9aee2c | ||
|
|
084b62116f | ||
|
|
3d6351bbe0 | ||
|
|
187f4c841e | ||
|
|
15a0c28093 | ||
|
|
c440a3933b | ||
|
|
11477d67c9 | ||
|
|
f1989d0aba | ||
|
|
75219b800a | ||
|
|
4c3fa5f246 | ||
|
|
06ed493cfe | ||
|
|
7be0fbf616 | ||
|
|
6cf53bbb81 | ||
|
|
3a766bf970 | ||
|
|
f96291af88 | ||
|
|
8557a9e1b1 | ||
|
|
e8af2338ec | ||
|
|
aec9d91a68 | ||
|
|
950255fab9 | ||
|
|
7c9d6ccde2 | ||
|
|
5c286c3334 | ||
|
|
f8b27c0b76 | ||
|
|
6e5d4fb358 | ||
|
|
5e2abc539f | ||
|
|
2f03a33c15 | ||
|
|
7ce0e3c38c | ||
|
|
e269614a51 | ||
|
|
21c224709f | ||
|
|
ac8a29f047 | ||
|
|
681f4b9eda | ||
|
|
2b46bd2643 | ||
|
|
a322b022eb | ||
|
|
0dc43432e2 | ||
|
|
27de266cb0 | ||
|
|
2e048b0895 | ||
|
|
f8bf532fc0 | ||
|
|
210349dc70 | ||
|
|
eaa4795eb6 | ||
|
|
293f75954d | ||
|
|
f93eb2072c | ||
|
|
0a3f284e14 | ||
|
|
11ed6b8f47 | ||
|
|
8dd99b7d2a | ||
|
|
df99907120 | ||
|
|
7ac83d7a9f | ||
|
|
f2445c2a37 | ||
|
|
efb30e7f8e | ||
|
|
719a771613 | ||
|
|
e0131aa749 | ||
|
|
5882fda501 | ||
|
|
eeed8dbc16 | ||
|
|
7239b9d7cc | ||
|
|
480c7eac21 | ||
|
|
412c75ebdd | ||
|
|
f33e4b6f5a | ||
|
|
30f34d5764 | ||
|
|
2e62837de6 | ||
|
|
3d319e25a9 | ||
|
|
36c9c002d1 | ||
|
|
7019cea5fa | ||
|
|
d30af2c561 | ||
|
|
d272a474ab | ||
|
|
66c4003789 | ||
|
|
c5d4378069 | ||
|
|
58dc4a0280 | ||
|
|
3ed5e1b65a | ||
|
|
2ad3b68821 | ||
|
|
f51900a69c | ||
|
|
0fe072b17b | ||
|
|
124cff7bf2 | ||
|
|
3aafceab40 | ||
|
|
3b961d18f9 | ||
|
|
e311790365 | ||
|
|
47f4e67a52 | ||
|
|
9f9ce61c3a | ||
|
|
f9430d4d20 | ||
|
|
d5f1b56b90 | ||
|
|
1946df83a7 | ||
|
|
59d87a8af1 | ||
|
|
7be0f4a193 | ||
|
|
fcd920460f | ||
|
|
0124d5254c | ||
|
|
246dc07018 | ||
|
|
3ee67e620c | ||
|
|
9a94023bde | ||
|
|
70f1b0c2fc | ||
|
|
7009d1edf1 | ||
|
|
d652a17fd7 | ||
|
|
e49d9f39a8 | ||
|
|
4a3ea540bf | ||
|
|
04f9e9b62a | ||
|
|
76a0167700 | ||
|
|
aa130075e8 | ||
|
|
dd26a564dc | ||
|
|
652ab4946d | ||
|
|
efe24db5a1 | ||
|
|
0f8ce0e93e | ||
|
|
9089eb4228 | ||
|
|
8a260ceece | ||
|
|
426bcffd1a | ||
|
|
9c37c3a740 | ||
|
|
3c9ea6caba | ||
|
|
857046ecb8 | ||
|
|
f196cfe993 | ||
|
|
140b850cef | ||
|
|
0929ba995a | ||
|
|
6bf9adfb51 | ||
|
|
96956dbda5 | ||
|
|
15cc64e68b | ||
|
|
65d4bcef47 | ||
|
|
5f39affe74 | ||
|
|
ef21ab7f3b | ||
|
|
554a24e44c | ||
|
|
ee731b8530 | ||
|
|
dd3f2c6538 | ||
|
|
5a4958090e | ||
|
|
cd4f78d619 | ||
|
|
eb46ba354a | ||
|
|
f0b3c95035 | ||
|
|
e15fdc493c | ||
|
|
fdff1664ea | ||
|
|
4bdc9b0c84 | ||
|
|
563031f214 | ||
|
|
33273c1be1 | ||
|
|
1b95790de3 | ||
|
|
2ef1cf5da0 | ||
|
|
4a117adb28 | ||
|
|
86bc775791 | ||
|
|
9a57b09b92 | ||
|
|
36e3d9c603 | ||
|
|
df4c36d71b | ||
|
|
793eb53790 | ||
|
|
6b568e8b7f | ||
|
|
fec74ee9e4 | ||
|
|
10ef570485 | ||
|
|
d719fd9be4 | ||
|
|
135023b3ed | ||
|
|
2bd2092263 | ||
|
|
eee7d0422c | ||
|
|
0d314c00a6 | ||
|
|
a5fc2e0ef7 | ||
|
|
e168ab9ffc | ||
|
|
644c18fc69 | ||
|
|
57717f4690 | ||
|
|
c46a9bdb45 | ||
|
|
d431b53434 | ||
|
|
18d9ebaab3 | ||
|
|
40e343d17d | ||
|
|
f6122157c7 | ||
|
|
cbaad2dfb9 | ||
|
|
c509ec56bd | ||
|
|
a25b786fca | ||
|
|
06224aa34e | ||
|
|
4bcbd49d6d | ||
|
|
09e2ded206 | ||
|
|
4a8c063d51 | ||
|
|
2e9e6d38e2 | ||
|
|
53917d6d90 | ||
|
|
d20714eed6 | ||
|
|
2f328bf4cf | ||
|
|
e3c4cdb040 | ||
|
|
c8cf645414 | ||
|
|
aa47d9f07a | ||
|
|
338559967a | ||
|
|
a736a42e26 | ||
|
|
00c6549610 | ||
|
|
510d871379 | ||
|
|
43e2d7454a | ||
|
|
cb359e40ba | ||
|
|
7836e48559 | ||
|
|
d95cdc3296 | ||
|
|
2ad0428727 | ||
|
|
ba74ffd4bf | ||
|
|
b88cd8e544 | ||
|
|
a031b54feb | ||
|
|
081cf5c6aa | ||
|
|
6874b4f6fb | ||
|
|
eeba650f6c | ||
|
|
54b07e6b99 | ||
|
|
dc8b9478ee | ||
|
|
d97b02add9 | ||
|
|
8427ade0fa | ||
|
|
44d6a0dea1 | ||
|
|
f710ce266b | ||
|
|
45dc9a39d9 | ||
|
|
d703a118c4 | ||
|
|
c20e580a9e | ||
|
|
9b4de5d7bf | ||
|
|
7c9f396b40 | ||
|
|
31b9f2b4f9 | ||
|
|
6ff15f9b53 | ||
|
|
1ebd6c252c | ||
|
|
8424351d49 | ||
|
|
0c4e597819 | ||
|
|
d1917d1a2b | ||
|
|
bb3503f0c4 | ||
|
|
7c22776254 | ||
|
|
2294586371 | ||
|
|
b7f519f86e | ||
|
|
febd5294f4 | ||
|
|
690a23fe89 | ||
|
|
39c1a88dae | ||
|
|
d0808e0c1a | ||
|
|
34fd22e4e9 | ||
|
|
d4fb0d37c2 | ||
|
|
fd02ca00f0 | ||
|
|
8a53d02d0c | ||
|
|
58ee53876b | ||
|
|
853b730def | ||
|
|
be5fdbfd4f | ||
|
|
e6d123b5e8 | ||
|
|
d8a844a2f9 | ||
|
|
dd87cdbebf | ||
|
|
4c1881324e | ||
|
|
bd27a36d16 | ||
|
|
2f999ba3db | ||
|
|
d8ec390cd6 | ||
|
|
7a0e7bfb95 | ||
|
|
da7ae6b953 | ||
|
|
2dead545f0 | ||
|
|
9c566ec17c | ||
|
|
385fe303cc | ||
|
|
81e3709d25 | ||
|
|
7f17efcdd8 | ||
|
|
a566ac1078 | ||
|
|
44e76b4eaa | ||
|
|
e7e1cfa12e | ||
|
|
77a70cad71 | ||
|
|
0c2db53ee8 | ||
|
|
83807ed247 | ||
|
|
302a135e5a | ||
|
|
6b2160f388 | ||
|
|
86a68c50bc | ||
|
|
e2e7d6578c | ||
|
|
a171e17666 | ||
|
|
d8610e0f2a | ||
|
|
93222bf3f9 | ||
|
|
ea6765c68a | ||
|
|
6ac81dea19 | ||
|
|
e4dd9bc9f9 | ||
|
|
03d4d4c8fa | ||
|
|
fcc51d3352 | ||
|
|
08630cd686 | ||
|
|
9295a4e7ce | ||
|
|
826a1a02a2 | ||
|
|
4ed08cefa7 | ||
|
|
1a33a0c4d1 | ||
|
|
4d3d710211 | ||
|
|
ac93e70dd2 | ||
|
|
dd3ffbb391 | ||
|
|
9d1d101586 | ||
|
|
32da7b8fe2 | ||
|
|
41484113a0 | ||
|
|
5d6a8be66d | ||
|
|
aba3a31663 | ||
|
|
8950f71b0a | ||
|
|
54d3668693 | ||
|
|
b16169f867 | ||
|
|
bbd589f6a8 | ||
|
|
765d8241f2 | ||
|
|
8e041ddeb6 | ||
|
|
a4a7fe0c48 | ||
|
|
a247fc3b48 | ||
|
|
d876085f6d | ||
|
|
bba9c3d57a | ||
|
|
944e971124 | ||
|
|
e512ab1816 | ||
|
|
83b5aecbfd | ||
|
|
2f9d00fc07 | ||
|
|
23b57692ec | ||
|
|
8bda7f1e1e | ||
|
|
12bddc3b1f | ||
|
|
8f5fa84996 | ||
|
|
3af34f078c | ||
|
|
57e596fea2 | ||
|
|
9793cf4ece | ||
|
|
a4bdc23aef | ||
|
|
4240089d41 | ||
|
|
09ebfac307 | ||
|
|
89b6291488 | ||
|
|
1434b6bbff | ||
|
|
de164ff936 | ||
|
|
a8e2fb1ee5 | ||
|
|
7da8b44c63 | ||
|
|
8f0c1a4224 | ||
|
|
c57cb3d2d9 | ||
|
|
5172189e36 | ||
|
|
6c6723e181 | ||
|
|
5b0a05b4b3 | ||
|
|
87cbd8fbf3 | ||
|
|
9060250806 | ||
|
|
bc63c3b383 | ||
|
|
a503803725 |
@@ -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
|
||||
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ vars.DOCKERHUB_USERNAME }}
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
username: ${{ vars.DOCKERHUB_USERNAME }}
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
|
||||
@@ -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"
|
||||
@@ -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 \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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,4 +1,4 @@
|
||||
> [Get started with Appwrite](https://apwr.dev/appcloud)
|
||||
> Appwrite Init has concluded! You can check out all the latest announcements [on our Init website](https://appwrite.io/init) :rocket:
|
||||
|
||||
<br />
|
||||
<p align="center">
|
||||
@@ -24,9 +24,11 @@
|
||||
|
||||
English | [简体中文](README-CN.md)
|
||||
|
||||
[**Announcing Appwrite Cloud Public Beta! Sign up today!**](https://cloud.appwrite.io)
|
||||
|
||||
Appwrite is an end-to-end backend server for Web, Mobile, Native, or Backend apps packaged as a set of Docker<nobr> microservices. Appwrite abstracts the complexity and repetitiveness required to build a modern backend API from scratch and allows you to build secure apps faster.
|
||||
|
||||
Using Appwrite, you can easily integrate your app with user authentication and multiple sign-in methods, a database for storing and querying users and team data, storage and file management, image manipulation, Cloud Functions, messaging, and [more services](https://appwrite.io/docs).
|
||||
Using Appwrite, you can easily integrate your app with user authentication and multiple sign-in methods, a database for storing and querying users and team data, storage and file management, image manipulation, Cloud Functions, and [more services](https://appwrite.io/docs).
|
||||
|
||||
<p align="center">
|
||||
<br />
|
||||
@@ -50,7 +52,7 @@ Table of Contents:
|
||||
- [Upgrade from an Older Version](#upgrade-from-an-older-version)
|
||||
- [One-Click Setups](#one-click-setups)
|
||||
- [Getting Started](#getting-started)
|
||||
- [Products](#products)
|
||||
- [Services](#services)
|
||||
- [SDKs](#sdks)
|
||||
- [Client](#client)
|
||||
- [Server](#server)
|
||||
|
||||
@@ -25,8 +25,8 @@ use Utopia\Queue\Publisher;
|
||||
use Utopia\Registry\Registry;
|
||||
use Utopia\System\System;
|
||||
|
||||
// Overwriting runtimes to be architecture agnostic for CLI
|
||||
Config::setParam('runtimes', (new Runtimes('v4'))->getAll(supported: false));
|
||||
// overwriting runtimes to be architectur agnostic for CLI
|
||||
Config::setParam('runtimes', (new Runtimes('v5'))->getAll(supported: false));
|
||||
|
||||
// require controllers after overwriting runtimes
|
||||
require_once __DIR__ . '/controllers/general.php';
|
||||
@@ -43,7 +43,8 @@ CLI::setResource('cache', function ($pools) {
|
||||
$adapters[] = $pools
|
||||
->get($value)
|
||||
->pop()
|
||||
->getResource();
|
||||
->getResource()
|
||||
;
|
||||
}
|
||||
|
||||
return new Cache(new Sharding($adapters));
|
||||
@@ -186,7 +187,7 @@ CLI::setResource('getLogsDB', function (Group $pools, Cache $cache) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setNamespace('logsV1')
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_TASK)
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS)
|
||||
->setMaxQueryValues(APP_DATABASE_QUERY_MAX_VALUES);
|
||||
|
||||
// set tenant
|
||||
|
||||
@@ -356,13 +356,6 @@ return [
|
||||
'attributes' => ['pingedAt'],
|
||||
'lengths' => [],
|
||||
'orders' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('_key_database'),
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['database'],
|
||||
'lengths' => [],
|
||||
'orders' => [],
|
||||
]
|
||||
],
|
||||
],
|
||||
@@ -1020,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,
|
||||
@@ -1031,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,
|
||||
@@ -1042,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' => [],
|
||||
],
|
||||
@@ -1075,29 +1145,25 @@ return [
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('owner'),
|
||||
'$id' => ID::custom('search'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 16,
|
||||
'size' => 16384,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => '', // "Appwrite" or empty string
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('region'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 16,
|
||||
'signed' => true,
|
||||
'required' => true,
|
||||
'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,
|
||||
@@ -1120,38 +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' => ID::custom('_key_owner'),
|
||||
'$id' => '_key_deploymentInternalId',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['owner'],
|
||||
'lengths' => [16],
|
||||
'attributes' => ['deploymentInternalId'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('_key_region'),
|
||||
'$id' => '_key_deploymentVcsProviderBranch',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['region'],
|
||||
'lengths' => [16],
|
||||
'attributes' => ['deploymentVcsProviderBranch'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
],
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -27,7 +27,6 @@ $console = [
|
||||
'hostname' => 'localhost',
|
||||
], // Current host is added on app init
|
||||
],
|
||||
'region' => 'fra',
|
||||
'legalName' => '',
|
||||
'legalCountry' => '',
|
||||
'legalState' => '',
|
||||
|
||||
@@ -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.',
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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',
|
||||
],
|
||||
]
|
||||
],
|
||||
];
|
||||
@@ -1,46 +1,11 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Continent codes with names and approximate central coordinates
|
||||
*
|
||||
* Coordinates represent approximate geographical centers of each continent
|
||||
* Note: These are simplified centroids and may not represent the exact geographical center
|
||||
*/
|
||||
|
||||
return [
|
||||
'AF' => [
|
||||
'name' => 'Africa',
|
||||
'latitude' => 8.7832,
|
||||
'longitude' => 34.5085
|
||||
],
|
||||
'AN' => [
|
||||
'name' => 'Antarctica',
|
||||
'latitude' => -82.8628,
|
||||
'longitude' => 135.0000
|
||||
],
|
||||
'AS' => [
|
||||
'name' => 'Asia',
|
||||
'latitude' => 34.0479,
|
||||
'longitude' => 100.6197
|
||||
],
|
||||
'EU' => [
|
||||
'name' => 'Europe',
|
||||
'latitude' => 54.5260,
|
||||
'longitude' => 15.2551
|
||||
],
|
||||
'NA' => [
|
||||
'name' => 'North America',
|
||||
'latitude' => 54.5260,
|
||||
'longitude' => -105.2551
|
||||
],
|
||||
'OC' => [
|
||||
'name' => 'Oceania',
|
||||
'latitude' => -22.7359,
|
||||
'longitude' => 140.0188
|
||||
],
|
||||
'SA' => [
|
||||
'name' => 'South America',
|
||||
'latitude' => -8.7832,
|
||||
'longitude' => -55.4915
|
||||
],
|
||||
'AF',
|
||||
'AN',
|
||||
'AS',
|
||||
'EU',
|
||||
'NA',
|
||||
'OC',
|
||||
'SA',
|
||||
];
|
||||
|
||||
@@ -1,210 +1,209 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* ISO 3166 standard country codes with country names and coordinates
|
||||
* ISO 3166 standard country codes
|
||||
* https://www.iso.org/iso-3166-country-codes.html
|
||||
*
|
||||
* Source:
|
||||
* https://www.iso.org/obp/ui/#search/code/
|
||||
* Coordinates source: Natural Earth Data (approximate country centroids)
|
||||
*/
|
||||
|
||||
return [
|
||||
'AF' => ['name' => 'Afghanistan', 'latitude' => 33.0, 'longitude' => 66.0],
|
||||
'AO' => ['name' => 'Angola', 'latitude' => -12.5, 'longitude' => 18.5],
|
||||
'AL' => ['name' => 'Albania', 'latitude' => 41.0, 'longitude' => 20.0],
|
||||
'AD' => ['name' => 'Andorra', 'latitude' => 42.5, 'longitude' => 1.6],
|
||||
'AE' => ['name' => 'United Arab Emirates', 'latitude' => 24.0, 'longitude' => 54.0],
|
||||
'AR' => ['name' => 'Argentina', 'latitude' => -34.0, 'longitude' => -64.0],
|
||||
'AM' => ['name' => 'Armenia', 'latitude' => 40.0, 'longitude' => 45.0],
|
||||
'AG' => ['name' => 'Antigua and Barbuda', 'latitude' => 17.05, 'longitude' => -61.8],
|
||||
'AU' => ['name' => 'Australia', 'latitude' => -25.0, 'longitude' => 135.0],
|
||||
'AT' => ['name' => 'Austria', 'latitude' => 47.3, 'longitude' => 13.3],
|
||||
'AZ' => ['name' => 'Azerbaijan', 'latitude' => 40.5, 'longitude' => 47.5],
|
||||
'BI' => ['name' => 'Burundi', 'latitude' => -3.5, 'longitude' => 30.0],
|
||||
'BE' => ['name' => 'Belgium', 'latitude' => 50.8, 'longitude' => 4.0],
|
||||
'BJ' => ['name' => 'Benin', 'latitude' => 9.5, 'longitude' => 2.25],
|
||||
'BF' => ['name' => 'Burkina Faso', 'latitude' => 13.0, 'longitude' => -2.0],
|
||||
'BD' => ['name' => 'Bangladesh', 'latitude' => 24.0, 'longitude' => 90.0],
|
||||
'BG' => ['name' => 'Bulgaria', 'latitude' => 43.0, 'longitude' => 25.0],
|
||||
'BH' => ['name' => 'Bahrain', 'latitude' => 26.0, 'longitude' => 50.5],
|
||||
'BS' => ['name' => 'Bahamas', 'latitude' => 24.25, 'longitude' => -76.0],
|
||||
'BA' => ['name' => 'Bosnia and Herzegovina', 'latitude' => 44.0, 'longitude' => 18.0],
|
||||
'BY' => ['name' => 'Belarus', 'latitude' => 53.0, 'longitude' => 28.0],
|
||||
'BZ' => ['name' => 'Belize', 'latitude' => 17.25, 'longitude' => -88.75],
|
||||
'BO' => ['name' => 'Bolivia', 'latitude' => -17.0, 'longitude' => -65.0],
|
||||
'BR' => ['name' => 'Brazil', 'latitude' => -10.0, 'longitude' => -55.0],
|
||||
'BB' => ['name' => 'Barbados', 'latitude' => 13.17, 'longitude' => -59.53],
|
||||
'BN' => ['name' => 'Brunei', 'latitude' => 4.5, 'longitude' => 114.67],
|
||||
'BT' => ['name' => 'Bhutan', 'latitude' => 27.5, 'longitude' => 90.5],
|
||||
'BW' => ['name' => 'Botswana', 'latitude' => -22.0, 'longitude' => 24.0],
|
||||
'CF' => ['name' => 'Central African Republic', 'latitude' => 7.0, 'longitude' => 21.0],
|
||||
'CA' => ['name' => 'Canada', 'latitude' => 60.0, 'longitude' => -95.0],
|
||||
'CH' => ['name' => 'Switzerland', 'latitude' => 47.0, 'longitude' => 8.0],
|
||||
'CL' => ['name' => 'Chile', 'latitude' => -30.0, 'longitude' => -71.0],
|
||||
'CN' => ['name' => 'China', 'latitude' => 35.0, 'longitude' => 105.0],
|
||||
'CI' => ['name' => 'Côte d\'Ivoire', 'latitude' => 8.0, 'longitude' => -5.0],
|
||||
'CM' => ['name' => 'Cameroon', 'latitude' => 6.0, 'longitude' => 12.0],
|
||||
'CD' => ['name' => 'Democratic Republic of the Congo', 'latitude' => -2.5, 'longitude' => 23.5],
|
||||
'CG' => ['name' => 'Republic of the Congo', 'latitude' => -1.0, 'longitude' => 15.0],
|
||||
'CO' => ['name' => 'Colombia', 'latitude' => 4.0, 'longitude' => -72.0],
|
||||
'KM' => ['name' => 'Comoros', 'latitude' => -12.17, 'longitude' => 44.25],
|
||||
'CV' => ['name' => 'Cape Verde', 'latitude' => 16.0, 'longitude' => -24.0],
|
||||
'CR' => ['name' => 'Costa Rica', 'latitude' => 10.0, 'longitude' => -84.0],
|
||||
'CU' => ['name' => 'Cuba', 'latitude' => 21.5, 'longitude' => -80.0],
|
||||
'CY' => ['name' => 'Cyprus', 'latitude' => 35.0, 'longitude' => 33.0],
|
||||
'CZ' => ['name' => 'Czech Republic', 'latitude' => 49.75, 'longitude' => 15.5],
|
||||
'DE' => ['name' => 'Germany', 'latitude' => 51.0, 'longitude' => 9.0],
|
||||
'DJ' => ['name' => 'Djibouti', 'latitude' => 11.5, 'longitude' => 43.0],
|
||||
'DM' => ['name' => 'Dominica', 'latitude' => 15.42, 'longitude' => -61.33],
|
||||
'DK' => ['name' => 'Denmark', 'latitude' => 56.0, 'longitude' => 10.0],
|
||||
'DO' => ['name' => 'Dominican Republic', 'latitude' => 19.0, 'longitude' => -70.67],
|
||||
'DZ' => ['name' => 'Algeria', 'latitude' => 28.0, 'longitude' => 3.0],
|
||||
'EC' => ['name' => 'Ecuador', 'latitude' => -2.0, 'longitude' => -77.5],
|
||||
'EG' => ['name' => 'Egypt', 'latitude' => 27.0, 'longitude' => 30.0],
|
||||
'ER' => ['name' => 'Eritrea', 'latitude' => 15.0, 'longitude' => 39.0],
|
||||
'ES' => ['name' => 'Spain', 'latitude' => 40.0, 'longitude' => -4.0],
|
||||
'EE' => ['name' => 'Estonia', 'latitude' => 59.0, 'longitude' => 26.0],
|
||||
'ET' => ['name' => 'Ethiopia', 'latitude' => 8.0, 'longitude' => 38.0],
|
||||
'FI' => ['name' => 'Finland', 'latitude' => 64.0, 'longitude' => 26.0],
|
||||
'FJ' => ['name' => 'Fiji', 'latitude' => -18.0, 'longitude' => 175.0],
|
||||
'FR' => ['name' => 'France', 'latitude' => 46.0, 'longitude' => 2.0],
|
||||
'FM' => ['name' => 'Micronesia', 'latitude' => 6.92, 'longitude' => 158.25],
|
||||
'GA' => ['name' => 'Gabon', 'latitude' => -1.0, 'longitude' => 11.75],
|
||||
'GB' => ['name' => 'United Kingdom', 'latitude' => 54.0, 'longitude' => -2.0],
|
||||
'GE' => ['name' => 'Georgia', 'latitude' => 42.0, 'longitude' => 43.5],
|
||||
'GH' => ['name' => 'Ghana', 'latitude' => 8.0, 'longitude' => -2.0],
|
||||
'GN' => ['name' => 'Guinea', 'latitude' => 11.0, 'longitude' => -10.0],
|
||||
'GM' => ['name' => 'Gambia', 'latitude' => 13.47, 'longitude' => -16.57],
|
||||
'GW' => ['name' => 'Guinea-Bissau', 'latitude' => 12.0, 'longitude' => -15.0],
|
||||
'GQ' => ['name' => 'Equatorial Guinea', 'latitude' => 2.0, 'longitude' => 10.0],
|
||||
'GR' => ['name' => 'Greece', 'latitude' => 39.0, 'longitude' => 22.0],
|
||||
'GD' => ['name' => 'Grenada', 'latitude' => 12.12, 'longitude' => -61.67],
|
||||
'GT' => ['name' => 'Guatemala', 'latitude' => 15.5, 'longitude' => -90.25],
|
||||
'GY' => ['name' => 'Guyana', 'latitude' => 5.0, 'longitude' => -59.0],
|
||||
'HK' => ['name' => 'Hong Kong', 'latitude' => 22.25, 'longitude' => 114.17],
|
||||
'HN' => ['name' => 'Honduras', 'latitude' => 15.0, 'longitude' => -86.5],
|
||||
'HR' => ['name' => 'Croatia', 'latitude' => 45.17, 'longitude' => 15.5],
|
||||
'HT' => ['name' => 'Haiti', 'latitude' => 19.0, 'longitude' => -72.42],
|
||||
'HU' => ['name' => 'Hungary', 'latitude' => 47.0, 'longitude' => 20.0],
|
||||
'ID' => ['name' => 'Indonesia', 'latitude' => -5.0, 'longitude' => 120.0],
|
||||
'IN' => ['name' => 'India', 'latitude' => 20.0, 'longitude' => 77.0],
|
||||
'IE' => ['name' => 'Ireland', 'latitude' => 53.0, 'longitude' => -8.0],
|
||||
'IR' => ['name' => 'Iran', 'latitude' => 32.0, 'longitude' => 53.0],
|
||||
'IQ' => ['name' => 'Iraq', 'latitude' => 33.0, 'longitude' => 44.0],
|
||||
'IS' => ['name' => 'Iceland', 'latitude' => 65.0, 'longitude' => -18.0],
|
||||
'IL' => ['name' => 'Israel', 'latitude' => 31.5, 'longitude' => 34.75],
|
||||
'IT' => ['name' => 'Italy', 'latitude' => 42.83, 'longitude' => 12.83],
|
||||
'JM' => ['name' => 'Jamaica', 'latitude' => 18.25, 'longitude' => -77.5],
|
||||
'JO' => ['name' => 'Jordan', 'latitude' => 31.0, 'longitude' => 36.0],
|
||||
'JP' => ['name' => 'Japan', 'latitude' => 36.0, 'longitude' => 138.0],
|
||||
'KZ' => ['name' => 'Kazakhstan', 'latitude' => 48.0, 'longitude' => 68.0],
|
||||
'KE' => ['name' => 'Kenya', 'latitude' => 1.0, 'longitude' => 38.0],
|
||||
'KG' => ['name' => 'Kyrgyzstan', 'latitude' => 41.0, 'longitude' => 75.0],
|
||||
'KH' => ['name' => 'Cambodia', 'latitude' => 13.0, 'longitude' => 105.0],
|
||||
'KI' => ['name' => 'Kiribati', 'latitude' => 1.42, 'longitude' => 173.0],
|
||||
'KN' => ['name' => 'Saint Kitts and Nevis', 'latitude' => 17.33, 'longitude' => -62.75],
|
||||
'KR' => ['name' => 'South Korea', 'latitude' => 37.0, 'longitude' => 127.5],
|
||||
'KW' => ['name' => 'Kuwait', 'latitude' => 29.34, 'longitude' => 47.66],
|
||||
'LA' => ['name' => 'Laos', 'latitude' => 18.0, 'longitude' => 105.0],
|
||||
'LB' => ['name' => 'Lebanon', 'latitude' => 33.83, 'longitude' => 35.83],
|
||||
'LR' => ['name' => 'Liberia', 'latitude' => 6.5, 'longitude' => -9.5],
|
||||
'LY' => ['name' => 'Libya', 'latitude' => 25.0, 'longitude' => 17.0],
|
||||
'LC' => ['name' => 'Saint Lucia', 'latitude' => 13.88, 'longitude' => -61.13],
|
||||
'LI' => ['name' => 'Liechtenstein', 'latitude' => 47.17, 'longitude' => 9.53],
|
||||
'LK' => ['name' => 'Sri Lanka', 'latitude' => 7.0, 'longitude' => 81.0],
|
||||
'LS' => ['name' => 'Lesotho', 'latitude' => -29.5, 'longitude' => 28.5],
|
||||
'LT' => ['name' => 'Lithuania', 'latitude' => 56.0, 'longitude' => 24.0],
|
||||
'LU' => ['name' => 'Luxembourg', 'latitude' => 49.75, 'longitude' => 6.17],
|
||||
'LV' => ['name' => 'latitudevia', 'latitude' => 57.0, 'longitude' => 25.0],
|
||||
'MA' => ['name' => 'Morocco', 'latitude' => 32.0, 'longitude' => -5.0],
|
||||
'MC' => ['name' => 'Monaco', 'latitude' => 43.73, 'longitude' => 7.4],
|
||||
'MD' => ['name' => 'Moldova', 'latitude' => 47.0, 'longitude' => 29.0],
|
||||
'MG' => ['name' => 'Madagascar', 'latitude' => -20.0, 'longitude' => 47.0],
|
||||
'MV' => ['name' => 'Maldives', 'latitude' => 3.25, 'longitude' => 73.0],
|
||||
'MX' => ['name' => 'Mexico', 'latitude' => 23.0, 'longitude' => -102.0],
|
||||
'MH' => ['name' => 'Marshall Islands', 'latitude' => 9.0, 'longitude' => 168.0],
|
||||
'MK' => ['name' => 'North Macedonia', 'latitude' => 41.83, 'longitude' => 22.0],
|
||||
'ML' => ['name' => 'Mali', 'latitude' => 17.0, 'longitude' => -4.0],
|
||||
'MT' => ['name' => 'Malta', 'latitude' => 35.83, 'longitude' => 14.58],
|
||||
'MM' => ['name' => 'Myanmar', 'latitude' => 22.0, 'longitude' => 98.0],
|
||||
'ME' => ['name' => 'Montenegro', 'latitude' => 42.5, 'longitude' => 19.3],
|
||||
'MN' => ['name' => 'Mongolia', 'latitude' => 46.0, 'longitude' => 105.0],
|
||||
'MZ' => ['name' => 'Mozambique', 'latitude' => -18.25, 'longitude' => 35.0],
|
||||
'MR' => ['name' => 'Mauritania', 'latitude' => 20.0, 'longitude' => -12.0],
|
||||
'MU' => ['name' => 'Mauritius', 'latitude' => -20.28, 'longitude' => 57.55],
|
||||
'MW' => ['name' => 'Malawi', 'latitude' => -13.5, 'longitude' => 34.0],
|
||||
'MY' => ['name' => 'Malaysia', 'latitude' => 2.5, 'longitude' => 112.5],
|
||||
'NA' => ['name' => 'Namibia', 'latitude' => -22.0, 'longitude' => 17.0],
|
||||
'NE' => ['name' => 'Niger', 'latitude' => 16.0, 'longitude' => 8.0],
|
||||
'NG' => ['name' => 'Nigeria', 'latitude' => 10.0, 'longitude' => 8.0],
|
||||
'NI' => ['name' => 'Nicaragua', 'latitude' => 13.0, 'longitude' => -85.0],
|
||||
'NL' => ['name' => 'Netherlands', 'latitude' => 52.5, 'longitude' => 5.75],
|
||||
'NO' => ['name' => 'Norway', 'latitude' => 62.0, 'longitude' => 10.0],
|
||||
'NP' => ['name' => 'Nepal', 'latitude' => 28.0, 'longitude' => 84.0],
|
||||
'NR' => ['name' => 'Nauru', 'latitude' => -0.53, 'longitude' => 166.92],
|
||||
'NZ' => ['name' => 'New Zealand', 'latitude' => -41.0, 'longitude' => 174.0],
|
||||
'OM' => ['name' => 'Oman', 'latitude' => 21.0, 'longitude' => 57.0],
|
||||
'PK' => ['name' => 'Pakistan', 'latitude' => 30.0, 'longitude' => 70.0],
|
||||
'PS' => ['name' => 'Palestine', 'latitude' => 31.9, 'longitude' => 35.2],
|
||||
'PA' => ['name' => 'Panama', 'latitude' => 9.0, 'longitude' => -80.0],
|
||||
'PE' => ['name' => 'Peru', 'latitude' => -10.0, 'longitude' => -76.0],
|
||||
'PH' => ['name' => 'Philippines', 'latitude' => 13.0, 'longitude' => 122.0],
|
||||
'PW' => ['name' => 'Palau', 'latitude' => 7.5, 'longitude' => 134.5],
|
||||
'PG' => ['name' => 'Papua New Guinea', 'latitude' => -6.0, 'longitude' => 147.0],
|
||||
'PL' => ['name' => 'Poland', 'latitude' => 52.0, 'longitude' => 20.0],
|
||||
'KP' => ['name' => 'North Korea', 'latitude' => 40.0, 'longitude' => 127.0],
|
||||
'PT' => ['name' => 'Portugal', 'latitude' => 39.5, 'longitude' => -8.0],
|
||||
'PY' => ['name' => 'Paraguay', 'latitude' => -23.0, 'longitude' => -58.0],
|
||||
'QA' => ['name' => 'Qatar', 'latitude' => 25.5, 'longitude' => 51.25],
|
||||
'RO' => ['name' => 'Romania', 'latitude' => 46.0, 'longitude' => 25.0],
|
||||
'RU' => ['name' => 'Russia', 'latitude' => 60.0, 'longitude' => 100.0],
|
||||
'RW' => ['name' => 'Rwanda', 'latitude' => -2.0, 'longitude' => 30.0],
|
||||
'SA' => ['name' => 'Saudi Arabia', 'latitude' => 25.0, 'longitude' => 45.0],
|
||||
'SD' => ['name' => 'Sudan', 'latitude' => 15.0, 'longitude' => 30.0],
|
||||
'SN' => ['name' => 'Senegal', 'latitude' => 14.0, 'longitude' => -14.0],
|
||||
'SG' => ['name' => 'Singapore', 'latitude' => 1.37, 'longitude' => 103.8],
|
||||
'SB' => ['name' => 'Solomon Islands', 'latitude' => -8.0, 'longitude' => 159.0],
|
||||
'SL' => ['name' => 'Sierra Leone', 'latitude' => 8.5, 'longitude' => -11.5],
|
||||
'SV' => ['name' => 'El Salvador', 'latitude' => 13.83, 'longitude' => -88.92],
|
||||
'SM' => ['name' => 'San Marino', 'latitude' => 43.77, 'longitude' => 12.42],
|
||||
'SO' => ['name' => 'Somalia', 'latitude' => 10.0, 'longitude' => 49.0],
|
||||
'RS' => ['name' => 'Serbia', 'latitude' => 44.0, 'longitude' => 21.0],
|
||||
'SS' => ['name' => 'South Sudan', 'latitude' => 8.0, 'longitude' => 30.0],
|
||||
'ST' => ['name' => 'São Tomé and Príncipe', 'latitude' => 1.0, 'longitude' => 7.0],
|
||||
'SR' => ['name' => 'Suriname', 'latitude' => 4.0, 'longitude' => -56.0],
|
||||
'SK' => ['name' => 'Slovakia', 'latitude' => 48.67, 'longitude' => 19.5],
|
||||
'SI' => ['name' => 'Slovenia', 'latitude' => 46.0, 'longitude' => 15.0],
|
||||
'SE' => ['name' => 'Sweden', 'latitude' => 62.0, 'longitude' => 15.0],
|
||||
'SZ' => ['name' => 'Eswatini', 'latitude' => -26.5, 'longitude' => 31.5],
|
||||
'SC' => ['name' => 'Seychelles', 'latitude' => -4.58, 'longitude' => 55.67],
|
||||
'SY' => ['name' => 'Syria', 'latitude' => 35.0, 'longitude' => 38.0],
|
||||
'TD' => ['name' => 'Chad', 'latitude' => 15.0, 'longitude' => 19.0],
|
||||
'TG' => ['name' => 'Togo', 'latitude' => 8.0, 'longitude' => 1.17],
|
||||
'TH' => ['name' => 'Thailand', 'latitude' => 15.0, 'longitude' => 100.0],
|
||||
'TJ' => ['name' => 'Tajikistan', 'latitude' => 39.0, 'longitude' => 71.0],
|
||||
'TM' => ['name' => 'Turkmenistan', 'latitude' => 40.0, 'longitude' => 60.0],
|
||||
'TL' => ['name' => 'Timor-Leste', 'latitude' => -8.83, 'longitude' => 125.92],
|
||||
'TO' => ['name' => 'Tonga', 'latitude' => -20.0, 'longitude' => -175.0],
|
||||
'TT' => ['name' => 'Trinidad and Tobago', 'latitude' => 11.0, 'longitude' => -61.0],
|
||||
'TN' => ['name' => 'Tunisia', 'latitude' => 34.0, 'longitude' => 9.0],
|
||||
'TR' => ['name' => 'Turkey', 'latitude' => 39.0, 'longitude' => 35.0],
|
||||
'TV' => ['name' => 'Tuvalu', 'latitude' => -8.0, 'longitude' => 178.0],
|
||||
'TZ' => ['name' => 'Tanzania', 'latitude' => -6.0, 'longitude' => 35.0],
|
||||
'TW' => ['name' => 'Taiwan', 'latitude' => 23.5, 'longitude' => 121.0],
|
||||
'UG' => ['name' => 'Uganda', 'latitude' => 1.0, 'longitude' => 32.0],
|
||||
'UA' => ['name' => 'Ukraine', 'latitude' => 49.0, 'longitude' => 32.0],
|
||||
'UY' => ['name' => 'Uruguay', 'latitude' => -33.0, 'longitude' => -56.0],
|
||||
'US' => ['name' => 'United States', 'latitude' => 38.0, 'longitude' => -97.0],
|
||||
'UZ' => ['name' => 'Uzbekistan', 'latitude' => 41.0, 'longitude' => 64.0],
|
||||
'VA' => ['name' => 'Vatican City', 'latitude' => 41.9, 'longitude' => 12.45],
|
||||
'VC' => ['name' => 'Saint Vincent and the Grenadines', 'latitude' => 13.25, 'longitude' => -61.2],
|
||||
'VE' => ['name' => 'Venezuela', 'latitude' => 8.0, 'longitude' => -66.0],
|
||||
'VN' => ['name' => 'Vietnam', 'latitude' => 16.0, 'longitude' => 106.0],
|
||||
'VU' => ['name' => 'Vanuatu', 'latitude' => -16.0, 'longitude' => 167.0],
|
||||
'WS' => ['name' => 'Samoa', 'latitude' => -13.58, 'longitude' => -172.33],
|
||||
'YE' => ['name' => 'Yemen', 'latitude' => 15.0, 'longitude' => 48.0],
|
||||
'ZA' => ['name' => 'South Africa', 'latitude' => -29.0, 'longitude' => 24.0],
|
||||
'ZM' => ['name' => 'Zambia', 'latitude' => -15.0, 'longitude' => 30.0],
|
||||
'ZW' => ['name' => 'Zimbabwe', 'latitude' => -20.0, 'longitude' => 30.0],
|
||||
'AF',
|
||||
'AO',
|
||||
'AL',
|
||||
'AD',
|
||||
'AE',
|
||||
'AR',
|
||||
'AM',
|
||||
'AG',
|
||||
'AU',
|
||||
'AT',
|
||||
'AZ',
|
||||
'BI',
|
||||
'BE',
|
||||
'BJ',
|
||||
'BF',
|
||||
'BD',
|
||||
'BG',
|
||||
'BH',
|
||||
'BS',
|
||||
'BA',
|
||||
'BY',
|
||||
'BZ',
|
||||
'BO',
|
||||
'BR',
|
||||
'BB',
|
||||
'BN',
|
||||
'BT',
|
||||
'BW',
|
||||
'CF',
|
||||
'CA',
|
||||
'CH',
|
||||
'CL',
|
||||
'CN',
|
||||
'CI',
|
||||
'CM',
|
||||
'CD',
|
||||
'CG',
|
||||
'CO',
|
||||
'KM',
|
||||
'CV',
|
||||
'CR',
|
||||
'CU',
|
||||
'CY',
|
||||
'CZ',
|
||||
'DE',
|
||||
'DJ',
|
||||
'DM',
|
||||
'DK',
|
||||
'DO',
|
||||
'DZ',
|
||||
'EC',
|
||||
'EG',
|
||||
'ER',
|
||||
'ES',
|
||||
'EE',
|
||||
'ET',
|
||||
'FI',
|
||||
'FJ',
|
||||
'FR',
|
||||
'FM',
|
||||
'GA',
|
||||
'GB',
|
||||
'GE',
|
||||
'GH',
|
||||
'GN',
|
||||
'GM',
|
||||
'GW',
|
||||
'GQ',
|
||||
'GR',
|
||||
'GD',
|
||||
'GT',
|
||||
'GY',
|
||||
'HK',
|
||||
'HN',
|
||||
'HR',
|
||||
'HT',
|
||||
'HU',
|
||||
'ID',
|
||||
'IN',
|
||||
'IE',
|
||||
'IR',
|
||||
'IQ',
|
||||
'IS',
|
||||
'IL',
|
||||
'IT',
|
||||
'JM',
|
||||
'JO',
|
||||
'JP',
|
||||
'KZ',
|
||||
'KE',
|
||||
'KG',
|
||||
'KH',
|
||||
'KI',
|
||||
'KN',
|
||||
'KR',
|
||||
'KW',
|
||||
'LA',
|
||||
'LB',
|
||||
'LR',
|
||||
'LY',
|
||||
'LC',
|
||||
'LI',
|
||||
'LK',
|
||||
'LS',
|
||||
'LT',
|
||||
'LU',
|
||||
'LV',
|
||||
'MA',
|
||||
'MC',
|
||||
'MD',
|
||||
'MG',
|
||||
'MV',
|
||||
'MX',
|
||||
'MH',
|
||||
'MK',
|
||||
'ML',
|
||||
'MT',
|
||||
'MM',
|
||||
'ME',
|
||||
'MN',
|
||||
'MZ',
|
||||
'MR',
|
||||
'MU',
|
||||
'MW',
|
||||
'MY',
|
||||
'NA',
|
||||
'NE',
|
||||
'NG',
|
||||
'NI',
|
||||
'NL',
|
||||
'NO',
|
||||
'NP',
|
||||
'NR',
|
||||
'NZ',
|
||||
'OM',
|
||||
'PK',
|
||||
'PS',
|
||||
'PA',
|
||||
'PE',
|
||||
'PH',
|
||||
'PW',
|
||||
'PG',
|
||||
'PL',
|
||||
'KP',
|
||||
'PT',
|
||||
'PY',
|
||||
'QA',
|
||||
'RO',
|
||||
'RU',
|
||||
'RW',
|
||||
'SA',
|
||||
'SD',
|
||||
'SN',
|
||||
'SG',
|
||||
'SB',
|
||||
'SL',
|
||||
'SV',
|
||||
'SM',
|
||||
'SO',
|
||||
'RS',
|
||||
'SS',
|
||||
'ST',
|
||||
'SR',
|
||||
'SK',
|
||||
'SI',
|
||||
'SE',
|
||||
'SZ',
|
||||
'SC',
|
||||
'SY',
|
||||
'TD',
|
||||
'TG',
|
||||
'TH',
|
||||
'TJ',
|
||||
'TM',
|
||||
'TL',
|
||||
'TO',
|
||||
'TT',
|
||||
'TN',
|
||||
'TR',
|
||||
'TV',
|
||||
'TZ',
|
||||
'TW',
|
||||
'UG',
|
||||
'UA',
|
||||
'UY',
|
||||
'US',
|
||||
'UZ',
|
||||
'VA',
|
||||
'VC',
|
||||
'VE',
|
||||
'VN',
|
||||
'VU',
|
||||
'WS',
|
||||
'YE',
|
||||
'ZA',
|
||||
'ZM',
|
||||
'ZW',
|
||||
];
|
||||
|
||||
@@ -11,7 +11,7 @@ return [
|
||||
[
|
||||
'key' => 'web',
|
||||
'name' => 'Web',
|
||||
'version' => '17.0.1',
|
||||
'version' => '16.1.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-web',
|
||||
'package' => 'https://www.npmjs.com/package/appwrite',
|
||||
'enabled' => true,
|
||||
@@ -59,7 +59,7 @@ return [
|
||||
[
|
||||
'key' => 'flutter',
|
||||
'name' => 'Flutter',
|
||||
'version' => '15.0.0',
|
||||
'version' => '13.1.1',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-flutter',
|
||||
'package' => 'https://pub.dev/packages/appwrite',
|
||||
'enabled' => true,
|
||||
@@ -77,7 +77,7 @@ return [
|
||||
[
|
||||
'key' => 'apple',
|
||||
'name' => 'Apple',
|
||||
'version' => '9.0.0',
|
||||
'version' => '7.1.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-apple',
|
||||
'package' => 'https://github.com/appwrite/sdk-for-apple',
|
||||
'enabled' => true,
|
||||
@@ -134,7 +134,7 @@ return [
|
||||
[
|
||||
'key' => 'react-native',
|
||||
'name' => 'React Native',
|
||||
'version' => '0.7.1',
|
||||
'version' => '0.6.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-react-native',
|
||||
'package' => 'https://npmjs.com/package/react-native-appwrite',
|
||||
'enabled' => true,
|
||||
@@ -217,7 +217,7 @@ return [
|
||||
[
|
||||
'key' => 'cli',
|
||||
'name' => 'Command Line',
|
||||
'version' => '6.2.2',
|
||||
'version' => '6.2.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-cli',
|
||||
'package' => 'https://www.npmjs.com/package/appwrite-cli',
|
||||
'enabled' => true,
|
||||
@@ -245,7 +245,7 @@ return [
|
||||
[
|
||||
'key' => 'nodejs',
|
||||
'name' => 'Node.js',
|
||||
'version' => '15.0.1',
|
||||
'version' => '14.2.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-node',
|
||||
'package' => 'https://www.npmjs.com/package/node-appwrite',
|
||||
'enabled' => true,
|
||||
@@ -299,7 +299,7 @@ return [
|
||||
[
|
||||
'key' => 'python',
|
||||
'name' => 'Python',
|
||||
'version' => '9.0.2',
|
||||
'version' => '6.2.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-python',
|
||||
'package' => 'https://pypi.org/project/appwrite/',
|
||||
'enabled' => true,
|
||||
@@ -371,7 +371,7 @@ return [
|
||||
[
|
||||
'key' => 'dart',
|
||||
'name' => 'Dart',
|
||||
'version' => '14.0.0',
|
||||
'version' => '12.2.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-dart',
|
||||
'package' => 'https://pub.dev/packages/dart_appwrite',
|
||||
'enabled' => true,
|
||||
@@ -411,7 +411,7 @@ return [
|
||||
[
|
||||
'key' => 'swift',
|
||||
'name' => 'Swift',
|
||||
'version' => '8.0.0',
|
||||
'version' => '6.2.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-swift',
|
||||
'package' => 'https://github.com/appwrite/sdk-for-swift',
|
||||
'enabled' => true,
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -6,4 +6,4 @@
|
||||
|
||||
use Appwrite\Runtimes\Runtimes;
|
||||
|
||||
return (new Runtimes('v4'))->getAll();
|
||||
return (new Runtimes('v5'))->getAll();
|
||||
|
||||
@@ -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',
|
||||
],
|
||||
|
||||
@@ -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 => [
|
||||
@@ -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"
|
||||
},
|
||||
|
||||
@@ -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"
|
||||
},
|
||||
|
||||
@@ -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'
|
||||
@@ -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' => [],
|
||||
],
|
||||
];
|
||||
@@ -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);
|
||||
|
||||
@@ -3355,7 +3355,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
$processDocument($collection, $document);
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, max($operations, 1))
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, $operations)
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_OPERATIONS_WRITES), $operations)
|
||||
->addMetric(str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$database->getInternalId(), $collection->getInternalId()], METRIC_DATABASE_ID_COLLECTION_ID_STORAGE), 1); // per collection
|
||||
|
||||
@@ -3520,7 +3520,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
}
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_READS, max($operations, 1))
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_READS, $operations)
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_OPERATIONS_READS), $operations);
|
||||
|
||||
$response->addHeader('X-Debug-Operations', $operations);
|
||||
@@ -3661,7 +3661,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
|
||||
$processDocument($collection, $document);
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_READS, max($operations, 1))
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_READS, $operations)
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_OPERATIONS_READS), $operations);
|
||||
|
||||
$response->addHeader('X-Debug-Operations', $operations);
|
||||
@@ -3959,7 +3959,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum
|
||||
$setCollection($collection, $newDocument);
|
||||
|
||||
$queueForStatsUsage
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, max($operations, 1))
|
||||
->addMetric(METRIC_DATABASES_OPERATIONS_WRITES, $operations)
|
||||
->addMetric(str_replace('{databaseInternalId}', $database->getInternalId(), METRIC_DATABASE_ID_OPERATIONS_WRITES), $operations);
|
||||
|
||||
$response->addHeader('X-Debug-Operations', $operations);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -118,7 +118,7 @@ App::get('/v1/locale/countries')
|
||||
->inject('response')
|
||||
->inject('locale')
|
||||
->action(function (Response $response, Locale $locale) {
|
||||
$list = array_keys(Config::getParam('locale-countries')); /* @var $list array */
|
||||
$list = Config::getParam('locale-countries'); /* @var $list array */
|
||||
$output = [];
|
||||
|
||||
foreach ($list as $value) {
|
||||
@@ -229,7 +229,7 @@ App::get('/v1/locale/continents')
|
||||
->inject('response')
|
||||
->inject('locale')
|
||||
->action(function (Response $response, Locale $locale) {
|
||||
$list = array_keys(Config::getParam('locale-continents'));
|
||||
$list = Config::getParam('locale-continents');
|
||||
|
||||
foreach ($list as $value) {
|
||||
$output[] = new Document([
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -15,157 +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' => '',
|
||||
'owner' => '',
|
||||
'region' => $project->getAttribute('region')
|
||||
]);
|
||||
|
||||
$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'])
|
||||
|
||||
@@ -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', [
|
||||
|
||||
@@ -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();
|
||||
@@ -582,23 +736,17 @@ App::init()
|
||||
]);
|
||||
}
|
||||
|
||||
$owner = '';
|
||||
$functionsDomain = System::getEnv('_APP_DOMAIN_FUNCTIONS', '');
|
||||
if (!empty($functionsDomain) && \str_ends_with($domain->get(), $functionsDomain)) {
|
||||
$owner = 'Appwrite';
|
||||
}
|
||||
|
||||
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->getId(),
|
||||
'projectInternalId' => $console->getInternalId(),
|
||||
'owner' => $owner,
|
||||
'region' => $console->getAttribute('region')
|
||||
'projectId' => 'console',
|
||||
'projectInternalId' => 'console',
|
||||
'search' => implode(' ', [$ruleId, $domain->get()]),
|
||||
]);
|
||||
|
||||
$domainDocument = $dbForPlatform->createDocument('rules', $domainDocument);
|
||||
@@ -632,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 : '');
|
||||
@@ -680,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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -746,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
|
||||
*/
|
||||
@@ -754,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1040,6 +1208,7 @@ App::error()
|
||||
->setParam('trace', $output['trace'] ?? []);
|
||||
|
||||
$response->html($layout->render());
|
||||
return;
|
||||
}
|
||||
|
||||
$response->dynamic(
|
||||
@@ -1064,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', '');
|
||||
|
||||
@@ -1072,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);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1092,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', '');
|
||||
|
||||
@@ -1100,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);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1162,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')
|
||||
@@ -1189,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')
|
||||
@@ -1197,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()));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Utopia\Config\Config;
|
||||
|
||||
Config::load('events', __DIR__ . '/../config/events.php');
|
||||
Config::load('auth', __DIR__ . '/../config/auth.php');
|
||||
Config::load('apis', __DIR__ . '/../config/apis.php'); // List of APIs
|
||||
Config::load('errors', __DIR__ . '/../config/errors.php');
|
||||
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('runtimes', __DIR__ . '/../config/runtimes.php');
|
||||
Config::load('runtimes-v2', __DIR__ . '/../config/runtimes-v2.php');
|
||||
Config::load('usage', __DIR__ . '/../config/usage.php');
|
||||
Config::load('roles', __DIR__ . '/../config/roles.php'); // User roles and scopes
|
||||
Config::load('scopes', __DIR__ . '/../config/scopes.php'); // User roles and scopes
|
||||
Config::load('services', __DIR__ . '/../config/services.php'); // List of services
|
||||
Config::load('variables', __DIR__ . '/../config/variables.php'); // List of env variables
|
||||
Config::load('regions', __DIR__ . '/../config/regions.php'); // List of available regions
|
||||
Config::load('avatar-browsers', __DIR__ . '/../config/avatars/browsers.php');
|
||||
Config::load('avatar-credit-cards', __DIR__ . '/../config/avatars/credit-cards.php');
|
||||
Config::load('avatar-flags', __DIR__ . '/../config/avatars/flags.php');
|
||||
Config::load('locale-codes', __DIR__ . '/../config/locale/codes.php');
|
||||
Config::load('locale-currencies', __DIR__ . '/../config/locale/currencies.php');
|
||||
Config::load('locale-eu', __DIR__ . '/../config/locale/eu.php');
|
||||
Config::load('locale-languages', __DIR__ . '/../config/locale/languages.php');
|
||||
Config::load('locale-phones', __DIR__ . '/../config/locale/phones.php');
|
||||
Config::load('locale-countries', __DIR__ . '/../config/locale/countries.php');
|
||||
Config::load('locale-continents', __DIR__ . '/../config/locale/continents.php');
|
||||
Config::load('locale-templates', __DIR__ . '/../config/locale/templates.php');
|
||||
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');
|
||||
@@ -1,239 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Appwrite\Functions\Specification;
|
||||
|
||||
const APP_NAME = 'Appwrite';
|
||||
const APP_DOMAIN = 'appwrite.io';
|
||||
const APP_EMAIL_TEAM = 'team@localhost.test'; // Default email address
|
||||
const APP_EMAIL_SECURITY = ''; // Default security email address
|
||||
const APP_USERAGENT = APP_NAME . '-Server v%s. Please report abuse at %s';
|
||||
const APP_MODE_DEFAULT = 'default';
|
||||
const APP_MODE_ADMIN = 'admin';
|
||||
const APP_PAGING_LIMIT = 12;
|
||||
const APP_LIMIT_COUNT = 5000;
|
||||
const APP_LIMIT_USERS = 10_000;
|
||||
const APP_LIMIT_USER_PASSWORD_HISTORY = 20;
|
||||
const APP_LIMIT_USER_SESSIONS_MAX = 100;
|
||||
const APP_LIMIT_USER_SESSIONS_DEFAULT = 10;
|
||||
const APP_LIMIT_ANTIVIRUS = 20_000_000; //20MB
|
||||
const APP_LIMIT_ENCRYPTION = 20_000_000; //20MB
|
||||
const APP_LIMIT_COMPRESSION = 20_000_000; //20MB
|
||||
const APP_LIMIT_ARRAY_PARAMS_SIZE = 100; // Default maximum of how many elements can there be in API parameter that expects array value
|
||||
const APP_LIMIT_ARRAY_LABELS_SIZE = 1000; // Default maximum of how many labels elements can there be in API parameter that expects array value
|
||||
const APP_LIMIT_ARRAY_ELEMENT_SIZE = 4096; // Default maximum length of element in array parameter represented by maximum URL length.
|
||||
const APP_LIMIT_SUBQUERY = 1000;
|
||||
const APP_LIMIT_SUBSCRIBERS_SUBQUERY = 1_000_000;
|
||||
const APP_LIMIT_WRITE_RATE_DEFAULT = 60; // Default maximum write rate per rate period
|
||||
const APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT = 60; // Default maximum write rate period in seconds
|
||||
const APP_LIMIT_LIST_DEFAULT = 25; // Default maximum number of items to return in list API calls
|
||||
const APP_KEY_ACCESS = 24 * 60 * 60; // 24 hours
|
||||
const APP_USER_ACCESS = 24 * 60 * 60; // 24 hours
|
||||
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_DATABASE_ATTRIBUTE_EMAIL = 'email';
|
||||
const APP_DATABASE_ATTRIBUTE_ENUM = 'enum';
|
||||
const APP_DATABASE_ATTRIBUTE_IP = 'ip';
|
||||
const APP_DATABASE_ATTRIBUTE_DATETIME = 'datetime';
|
||||
const APP_DATABASE_ATTRIBUTE_URL = 'url';
|
||||
const APP_DATABASE_ATTRIBUTE_INT_RANGE = 'intRange';
|
||||
const APP_DATABASE_ATTRIBUTE_FLOAT_RANGE = 'floatRange';
|
||||
const APP_DATABASE_ATTRIBUTE_STRING_MAX_LENGTH = 1_073_741_824; // 2^32 bits / 4 bits per char
|
||||
const APP_DATABASE_TIMEOUT_MILLISECONDS_API = 15 * 1000; // 15 seconds
|
||||
const APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER = 300 * 1000; // 5 minutes
|
||||
const APP_DATABASE_TIMEOUT_MILLISECONDS_TASK = 300 * 1000; // 5 minutes
|
||||
const APP_DATABASE_QUERY_MAX_VALUES = 500;
|
||||
const APP_STORAGE_UPLOADS = '/storage/uploads';
|
||||
const APP_STORAGE_FUNCTIONS = '/storage/functions';
|
||||
const APP_STORAGE_BUILDS = '/storage/builds';
|
||||
const APP_STORAGE_CACHE = '/storage/cache';
|
||||
const APP_STORAGE_CERTIFICATES = '/storage/certificates';
|
||||
const APP_STORAGE_CONFIG = '/storage/config';
|
||||
const APP_STORAGE_READ_BUFFER = 20 * (1000 * 1000); //20MB other names `APP_STORAGE_MEMORY_LIMIT`, `APP_STORAGE_MEMORY_BUFFER`, `APP_STORAGE_READ_LIMIT`, `APP_STORAGE_BUFFER_LIMIT`
|
||||
const APP_SOCIAL_TWITTER = 'https://twitter.com/appwrite';
|
||||
const APP_SOCIAL_TWITTER_HANDLE = 'appwrite';
|
||||
const APP_SOCIAL_FACEBOOK = 'https://www.facebook.com/appwrite.io';
|
||||
const APP_SOCIAL_LINKEDIN = 'https://www.linkedin.com/company/appwrite';
|
||||
const APP_SOCIAL_INSTAGRAM = 'https://www.instagram.com/appwrite.io';
|
||||
const APP_SOCIAL_GITHUB = 'https://github.com/appwrite';
|
||||
const APP_SOCIAL_DISCORD = 'https://appwrite.io/discord';
|
||||
const APP_SOCIAL_DISCORD_CHANNEL = '564160730845151244';
|
||||
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_PLATFORM_SERVER = 'server';
|
||||
const APP_PLATFORM_CLIENT = 'client';
|
||||
const APP_PLATFORM_CONSOLE = 'console';
|
||||
|
||||
// Database Reconnect
|
||||
const DATABASE_RECONNECT_SLEEP = 2;
|
||||
const DATABASE_RECONNECT_MAX_ATTEMPTS = 10;
|
||||
|
||||
// Database Worker Types
|
||||
const DATABASE_TYPE_CREATE_ATTRIBUTE = 'createAttribute';
|
||||
const DATABASE_TYPE_CREATE_INDEX = 'createIndex';
|
||||
const DATABASE_TYPE_DELETE_ATTRIBUTE = 'deleteAttribute';
|
||||
const DATABASE_TYPE_DELETE_INDEX = 'deleteIndex';
|
||||
const DATABASE_TYPE_DELETE_COLLECTION = 'deleteCollection';
|
||||
const DATABASE_TYPE_DELETE_DATABASE = 'deleteDatabase';
|
||||
|
||||
// Build Worker Types
|
||||
const BUILD_TYPE_DEPLOYMENT = 'deployment';
|
||||
const BUILD_TYPE_RETRY = 'retry';
|
||||
|
||||
// Deletion Types
|
||||
const DELETE_TYPE_DATABASES = 'databases';
|
||||
const DELETE_TYPE_DOCUMENT = 'document';
|
||||
const DELETE_TYPE_COLLECTIONS = 'collections';
|
||||
const DELETE_TYPE_PROJECTS = 'projects';
|
||||
const DELETE_TYPE_FUNCTIONS = 'functions';
|
||||
const DELETE_TYPE_DEPLOYMENTS = 'deployments';
|
||||
const DELETE_TYPE_USERS = 'users';
|
||||
const DELETE_TYPE_TEAM_PROJECTS = 'teams_projects';
|
||||
const DELETE_TYPE_EXECUTIONS = 'executions';
|
||||
const DELETE_TYPE_AUDIT = 'audit';
|
||||
const DELETE_TYPE_ABUSE = 'abuse';
|
||||
const DELETE_TYPE_USAGE = 'usage';
|
||||
const DELETE_TYPE_REALTIME = 'realtime';
|
||||
const DELETE_TYPE_BUCKETS = 'buckets';
|
||||
const DELETE_TYPE_INSTALLATIONS = 'installations';
|
||||
const DELETE_TYPE_RULES = 'rules';
|
||||
const DELETE_TYPE_SESSIONS = 'sessions';
|
||||
const DELETE_TYPE_CACHE_BY_TIMESTAMP = 'cacheByTimeStamp';
|
||||
const DELETE_TYPE_CACHE_BY_RESOURCE = 'cacheByResource';
|
||||
const DELETE_TYPE_SCHEDULES = 'schedules';
|
||||
const DELETE_TYPE_TOPIC = 'topic';
|
||||
const DELETE_TYPE_TARGET = 'target';
|
||||
const DELETE_TYPE_EXPIRED_TARGETS = 'invalid_targets';
|
||||
const DELETE_TYPE_SESSION_TARGETS = 'session_targets';
|
||||
const DELETE_TYPE_MAINTENANCE = 'maintenance';
|
||||
|
||||
// Message types
|
||||
const MESSAGE_SEND_TYPE_INTERNAL = 'internal';
|
||||
const MESSAGE_SEND_TYPE_EXTERNAL = 'external';
|
||||
// Mail Types
|
||||
const MAIL_TYPE_VERIFICATION = 'verification';
|
||||
const MAIL_TYPE_MAGIC_SESSION = 'magicSession';
|
||||
const MAIL_TYPE_RECOVERY = 'recovery';
|
||||
const MAIL_TYPE_INVITATION = 'invitation';
|
||||
const MAIL_TYPE_CERTIFICATE = 'certificate';
|
||||
// Auth Types
|
||||
const APP_AUTH_TYPE_SESSION = 'Session';
|
||||
const APP_AUTH_TYPE_JWT = 'JWT';
|
||||
const APP_AUTH_TYPE_KEY = 'Key';
|
||||
const APP_AUTH_TYPE_ADMIN = 'Admin';
|
||||
// Response related
|
||||
const MAX_OUTPUT_CHUNK_SIZE = 10 * 1024 * 1024; // 10MB
|
||||
// Function headers
|
||||
const FUNCTION_ALLOWLIST_HEADERS_REQUEST = ['content-type', 'agent', 'content-length', 'host'];
|
||||
const FUNCTION_ALLOWLIST_HEADERS_RESPONSE = ['content-type', 'content-length'];
|
||||
// Message types
|
||||
const MESSAGE_TYPE_EMAIL = 'email';
|
||||
const MESSAGE_TYPE_SMS = 'sms';
|
||||
const MESSAGE_TYPE_PUSH = 'push';
|
||||
// API key types
|
||||
const API_KEY_STANDARD = 'standard';
|
||||
const API_KEY_DYNAMIC = 'dynamic';
|
||||
// Usage metrics
|
||||
const METRIC_TEAMS = 'teams';
|
||||
const METRIC_USERS = 'users';
|
||||
const METRIC_WEBHOOKS_SENT = 'webhooks.events.sent';
|
||||
const METRIC_WEBHOOKS_FAILED = 'webhooks.events.failed';
|
||||
const METRIC_WEBHOOK_ID_SENT = '{webhookInternalId}.webhooks.events.sent';
|
||||
const METRIC_WEBHOOK_ID_FAILED = '{webhookInternalId}.webhooks.events.failed';
|
||||
const METRIC_AUTH_METHOD_PHONE = 'auth.method.phone';
|
||||
const METRIC_AUTH_METHOD_PHONE_COUNTRY_CODE = METRIC_AUTH_METHOD_PHONE . '.{countryCode}';
|
||||
const METRIC_MESSAGES = 'messages';
|
||||
const METRIC_MESSAGES_SENT = METRIC_MESSAGES . '.sent';
|
||||
const METRIC_MESSAGES_FAILED = METRIC_MESSAGES . '.failed';
|
||||
const METRIC_MESSAGES_TYPE = METRIC_MESSAGES . '.{type}';
|
||||
const METRIC_MESSAGES_TYPE_SENT = METRIC_MESSAGES . '.{type}.sent';
|
||||
const METRIC_MESSAGES_TYPE_FAILED = METRIC_MESSAGES . '.{type}.failed';
|
||||
const METRIC_MESSAGES_TYPE_PROVIDER = METRIC_MESSAGES . '.{type}.{provider}';
|
||||
const METRIC_MESSAGES_TYPE_PROVIDER_SENT = METRIC_MESSAGES . '.{type}.{provider}.sent';
|
||||
const METRIC_MESSAGES_TYPE_PROVIDER_FAILED = METRIC_MESSAGES . '.{type}.{provider}.failed';
|
||||
const METRIC_SESSIONS = 'sessions';
|
||||
const METRIC_DATABASES = 'databases';
|
||||
const METRIC_COLLECTIONS = 'collections';
|
||||
const METRIC_DATABASES_STORAGE = 'databases.storage';
|
||||
const METRIC_DATABASE_ID_COLLECTIONS = '{databaseInternalId}.collections';
|
||||
const METRIC_DATABASE_ID_STORAGE = '{databaseInternalId}.databases.storage';
|
||||
const METRIC_DOCUMENTS = 'documents';
|
||||
const METRIC_DATABASE_ID_DOCUMENTS = '{databaseInternalId}.documents';
|
||||
const METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS = '{databaseInternalId}.{collectionInternalId}.documents';
|
||||
const METRIC_DATABASE_ID_COLLECTION_ID_STORAGE = '{databaseInternalId}.{collectionInternalId}.databases.storage';
|
||||
const METRIC_DATABASES_OPERATIONS_READS = 'databases.operations.reads';
|
||||
const METRIC_DATABASE_ID_OPERATIONS_READS = '{databaseInternalId}.databases.operations.reads';
|
||||
const METRIC_DATABASES_OPERATIONS_WRITES = 'databases.operations.writes';
|
||||
const METRIC_DATABASE_ID_OPERATIONS_WRITES = '{databaseInternalId}.databases.operations.writes';
|
||||
const METRIC_BUCKETS = 'buckets';
|
||||
const METRIC_FILES = 'files';
|
||||
const METRIC_FILES_STORAGE = 'files.storage';
|
||||
const METRIC_FILES_TRANSFORMATIONS = 'files.transformations';
|
||||
const METRIC_BUCKET_ID_FILES_TRANSFORMATIONS = '{bucketInternalId}.files.transformations';
|
||||
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_FUNCTIONS = 'functions';
|
||||
const METRIC_DEPLOYMENTS = 'deployments';
|
||||
const METRIC_DEPLOYMENTS_STORAGE = 'deployments.storage';
|
||||
const METRIC_BUILDS = 'builds';
|
||||
const METRIC_BUILDS_SUCCESS = 'builds.success';
|
||||
const METRIC_BUILDS_FAILED = 'builds.failed';
|
||||
const METRIC_BUILDS_STORAGE = 'builds.storage';
|
||||
const METRIC_BUILDS_COMPUTE = 'builds.compute';
|
||||
const METRIC_BUILDS_COMPUTE_SUCCESS = 'builds.compute.success';
|
||||
const METRIC_BUILDS_COMPUTE_FAILED = 'builds.compute.failed';
|
||||
const METRIC_BUILDS_MB_SECONDS = 'builds.mbSeconds';
|
||||
const METRIC_FUNCTION_ID_BUILDS = '{functionInternalId}.builds';
|
||||
const METRIC_FUNCTION_ID_BUILDS_SUCCESS = '{functionInternalId}.builds.success';
|
||||
const METRIC_FUNCTION_ID_BUILDS_FAILED = '{functionInternalId}.builds.failed';
|
||||
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_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_NETWORK_REQUESTS = 'network.requests';
|
||||
const METRIC_NETWORK_INBOUND = 'network.inbound';
|
||||
const METRIC_NETWORK_OUTBOUND = 'network.outbound';
|
||||
const METRIC_MAU = 'users.mau';
|
||||
const METRIC_DAU = 'users.dau';
|
||||
const METRIC_WAU = 'users.wau';
|
||||
const METRIC_WEBHOOKS = 'webhooks';
|
||||
const METRIC_PLATFORMS = 'platforms';
|
||||
const METRIC_PROVIDERS = 'providers';
|
||||
const METRIC_TOPICS = 'topics';
|
||||
const METRIC_TARGETS = 'targets';
|
||||
const METRIC_PROVIDER_TYPE_TARGETS = '{providerType}.targets';
|
||||
const METRIC_KEYS = 'keys';
|
||||
const METRIC_DOMAINS = 'domains';
|
||||
const METRIC_RESOURCE_TYPE_ID_BUILDS = '{resourceType}.{resourceInternalId}.builds';
|
||||
const METRIC_RESOURCE_TYPE_ID_BUILDS_STORAGE = '{resourceType}.{resourceInternalId}.builds.storage';
|
||||
const METRIC_RESOURCE_TYPE_ID_DEPLOYMENTS = '{resourceType}.{resourceInternalId}.deployments';
|
||||
const METRIC_RESOURCE_TYPE_ID_DEPLOYMENTS_STORAGE = '{resourceType}.{resourceInternalId}.deployments.storage';
|
||||
|
||||
// Resource types
|
||||
|
||||
const RESOURCE_TYPE_PROJECTS = 'projects';
|
||||
const RESOURCE_TYPE_FUNCTIONS = 'functions';
|
||||
const RESOURCE_TYPE_DATABASES = 'databases';
|
||||
const RESOURCE_TYPE_BUCKETS = 'buckets';
|
||||
const RESOURCE_TYPE_PROVIDERS = 'providers';
|
||||
const RESOURCE_TYPE_TOPICS = 'topics';
|
||||
const RESOURCE_TYPE_SUBSCRIBERS = 'subscribers';
|
||||
const RESOURCE_TYPE_MESSAGES = 'messages';
|
||||
@@ -1,404 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Appwrite\OpenSSL\OpenSSL;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\System\System;
|
||||
|
||||
Database::addFilter(
|
||||
'casting',
|
||||
function (mixed $value) {
|
||||
return json_encode(['value' => $value], JSON_PRESERVE_ZERO_FRACTION);
|
||||
},
|
||||
function (mixed $value) {
|
||||
if (is_null($value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return json_decode($value, true)['value'];
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'enum',
|
||||
function (mixed $value, Document $attribute) {
|
||||
if ($attribute->isSet('elements')) {
|
||||
$attribute->removeAttribute('elements');
|
||||
}
|
||||
|
||||
return $value;
|
||||
},
|
||||
function (mixed $value, Document $attribute) {
|
||||
$formatOptions = \json_decode($attribute->getAttribute('formatOptions', '[]'), true);
|
||||
if (isset($formatOptions['elements'])) {
|
||||
$attribute->setAttribute('elements', $formatOptions['elements']);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'range',
|
||||
function (mixed $value, Document $attribute) {
|
||||
if ($attribute->isSet('min')) {
|
||||
$attribute->removeAttribute('min');
|
||||
}
|
||||
if ($attribute->isSet('max')) {
|
||||
$attribute->removeAttribute('max');
|
||||
}
|
||||
|
||||
return $value;
|
||||
},
|
||||
function (mixed $value, Document $attribute) {
|
||||
$formatOptions = json_decode($attribute->getAttribute('formatOptions', '[]'), true);
|
||||
if (isset($formatOptions['min']) || isset($formatOptions['max'])) {
|
||||
$attribute
|
||||
->setAttribute('min', $formatOptions['min'])
|
||||
->setAttribute('max', $formatOptions['max']);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryAttributes',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
$attributes = $database->find('attributes', [
|
||||
Query::equal('collectionInternalId', [$document->getInternalId()]),
|
||||
Query::equal('databaseInternalId', [$document->getAttribute('databaseInternalId')]),
|
||||
Query::limit($database->getLimitForAttributes()),
|
||||
]);
|
||||
|
||||
foreach ($attributes as $attribute) {
|
||||
if ($attribute->getAttribute('type') === Database::VAR_RELATIONSHIP) {
|
||||
$options = $attribute->getAttribute('options');
|
||||
foreach ($options as $key => $value) {
|
||||
$attribute->setAttribute($key, $value);
|
||||
}
|
||||
$attribute->removeAttribute('options');
|
||||
}
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryIndexes',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('indexes', [
|
||||
Query::equal('collectionInternalId', [$document->getInternalId()]),
|
||||
Query::equal('databaseInternalId', [$document->getAttribute('databaseInternalId')]),
|
||||
Query::limit($database->getLimitForIndexes()),
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryPlatforms',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('platforms', [
|
||||
Query::equal('projectInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryKeys',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('keys', [
|
||||
Query::equal('projectInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryWebhooks',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('webhooks', [
|
||||
Query::equal('projectInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQuerySessions',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn () => $database->find('sessions', [
|
||||
Query::equal('userInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]));
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryTokens',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn () => $database
|
||||
->find('tokens', [
|
||||
Query::equal('userInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]));
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryChallenges',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn () => $database
|
||||
->find('challenges', [
|
||||
Query::equal('userInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]));
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryAuthenticators',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn () => $database
|
||||
->find('authenticators', [
|
||||
Query::equal('userInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]));
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryMemberships',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn () => $database
|
||||
->find('memberships', [
|
||||
Query::equal('userInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]));
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryVariables',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('variables', [
|
||||
Query::equal('resourceInternalId', [$document->getInternalId()]),
|
||||
Query::equal('resourceType', ['function']),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'encrypt',
|
||||
function (mixed $value) {
|
||||
$key = System::getEnv('_APP_OPENSSL_KEY_V1');
|
||||
$iv = OpenSSL::randomPseudoBytes(OpenSSL::cipherIVLength(OpenSSL::CIPHER_AES_128_GCM));
|
||||
$tag = null;
|
||||
|
||||
return json_encode([
|
||||
'data' => OpenSSL::encrypt($value, OpenSSL::CIPHER_AES_128_GCM, $key, 0, $iv, $tag),
|
||||
'method' => OpenSSL::CIPHER_AES_128_GCM,
|
||||
'iv' => \bin2hex($iv),
|
||||
'tag' => \bin2hex($tag ?? ''),
|
||||
'version' => '1',
|
||||
]);
|
||||
},
|
||||
function (mixed $value) {
|
||||
if (is_null($value)) {
|
||||
return;
|
||||
}
|
||||
$value = json_decode($value, true);
|
||||
$key = System::getEnv('_APP_OPENSSL_KEY_V' . $value['version']);
|
||||
|
||||
return OpenSSL::decrypt($value['data'], $value['method'], $key, 0, hex2bin($value['iv']), hex2bin($value['tag']));
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryProjectVariables',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('variables', [
|
||||
Query::equal('resourceType', ['project']),
|
||||
Query::limit(APP_LIMIT_SUBQUERY)
|
||||
]);
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'userSearch',
|
||||
function (mixed $value, Document $user) {
|
||||
$searchValues = [
|
||||
$user->getId(),
|
||||
$user->getAttribute('email', ''),
|
||||
$user->getAttribute('name', ''),
|
||||
$user->getAttribute('phone', '')
|
||||
];
|
||||
|
||||
foreach ($user->getAttribute('labels', []) as $label) {
|
||||
$searchValues[] = 'label:' . $label;
|
||||
}
|
||||
|
||||
$search = implode(' ', \array_filter($searchValues));
|
||||
|
||||
return $search;
|
||||
},
|
||||
function (mixed $value) {
|
||||
return $value;
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryTargets',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return Authorization::skip(fn () => $database
|
||||
->find('targets', [
|
||||
Query::equal('userInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY)
|
||||
]));
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'subQueryTopicTargets',
|
||||
function (mixed $value) {
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
$targetIds = Authorization::skip(fn () => \array_map(
|
||||
fn ($document) => $document->getAttribute('targetInternalId'),
|
||||
$database->find('subscribers', [
|
||||
Query::equal('topicInternalId', [$document->getInternalId()]),
|
||||
Query::limit(APP_LIMIT_SUBSCRIBERS_SUBQUERY)
|
||||
])
|
||||
));
|
||||
if (\count($targetIds) > 0) {
|
||||
return $database->skipValidation(fn () => $database->find('targets', [
|
||||
Query::equal('$internalId', $targetIds)
|
||||
]));
|
||||
}
|
||||
return [];
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'providerSearch',
|
||||
function (mixed $value, Document $provider) {
|
||||
$searchValues = [
|
||||
$provider->getId(),
|
||||
$provider->getAttribute('name', ''),
|
||||
$provider->getAttribute('provider', ''),
|
||||
$provider->getAttribute('type', '')
|
||||
];
|
||||
|
||||
$search = \implode(' ', \array_filter($searchValues));
|
||||
|
||||
return $search;
|
||||
},
|
||||
function (mixed $value) {
|
||||
return $value;
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'topicSearch',
|
||||
function (mixed $value, Document $topic) {
|
||||
$searchValues = [
|
||||
$topic->getId(),
|
||||
$topic->getAttribute('name', ''),
|
||||
$topic->getAttribute('description', ''),
|
||||
];
|
||||
|
||||
$search = \implode(' ', \array_filter($searchValues));
|
||||
|
||||
return $search;
|
||||
},
|
||||
function (mixed $value) {
|
||||
return $value;
|
||||
}
|
||||
);
|
||||
|
||||
Database::addFilter(
|
||||
'messageSearch',
|
||||
function (mixed $value, Document $message) {
|
||||
$searchValues = [
|
||||
$message->getId(),
|
||||
$message->getAttribute('description', ''),
|
||||
$message->getAttribute('status', ''),
|
||||
];
|
||||
|
||||
$data = \json_decode($message->getAttribute('data', []), true);
|
||||
$providerType = $message->getAttribute('providerType', '');
|
||||
|
||||
switch ($providerType) {
|
||||
case MESSAGE_TYPE_EMAIL:
|
||||
$searchValues[] = $data['subject'];
|
||||
$searchValues[] = MESSAGE_TYPE_EMAIL;
|
||||
break;
|
||||
case MESSAGE_TYPE_SMS:
|
||||
$searchValues[] = $data['content'];
|
||||
$searchValues[] = MESSAGE_TYPE_SMS;
|
||||
break;
|
||||
case MESSAGE_TYPE_PUSH:
|
||||
$searchValues[] = $data['title'] ?? '';
|
||||
$searchValues[] = MESSAGE_TYPE_PUSH;
|
||||
break;
|
||||
}
|
||||
|
||||
$search = \implode(' ', \array_filter($searchValues));
|
||||
|
||||
return $search;
|
||||
},
|
||||
function (mixed $value) {
|
||||
return $value;
|
||||
}
|
||||
);
|
||||
@@ -1,43 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Appwrite\Network\Validator\Email;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Validator\Datetime as DatetimeValidator;
|
||||
use Utopia\Database\Validator\Structure;
|
||||
use Utopia\Validator\IP;
|
||||
use Utopia\Validator\Range;
|
||||
use Utopia\Validator\URL;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
||||
Structure::addFormat(APP_DATABASE_ATTRIBUTE_EMAIL, function () {
|
||||
return new Email();
|
||||
}, Database::VAR_STRING);
|
||||
|
||||
Structure::addFormat(APP_DATABASE_ATTRIBUTE_DATETIME, function () {
|
||||
return new DatetimeValidator();
|
||||
}, Database::VAR_DATETIME);
|
||||
|
||||
Structure::addFormat(APP_DATABASE_ATTRIBUTE_ENUM, function ($attribute) {
|
||||
$elements = $attribute['formatOptions']['elements'] ?? [];
|
||||
return new WhiteList($elements, true);
|
||||
}, Database::VAR_STRING);
|
||||
|
||||
Structure::addFormat(APP_DATABASE_ATTRIBUTE_IP, function () {
|
||||
return new IP();
|
||||
}, Database::VAR_STRING);
|
||||
|
||||
Structure::addFormat(APP_DATABASE_ATTRIBUTE_URL, function () {
|
||||
return new URL();
|
||||
}, Database::VAR_STRING);
|
||||
|
||||
Structure::addFormat(APP_DATABASE_ATTRIBUTE_INT_RANGE, function ($attribute) {
|
||||
$min = $attribute['formatOptions']['min'] ?? -INF;
|
||||
$max = $attribute['formatOptions']['max'] ?? INF;
|
||||
return new Range($min, $max, Range::TYPE_INTEGER);
|
||||
}, Database::VAR_INTEGER);
|
||||
|
||||
Structure::addFormat(APP_DATABASE_ATTRIBUTE_FLOAT_RANGE, function ($attribute) {
|
||||
$min = $attribute['formatOptions']['min'] ?? -INF;
|
||||
$max = $attribute['formatOptions']['max'] ?? INF;
|
||||
return new Range($min, $max, Range::TYPE_FLOAT);
|
||||
}, Database::VAR_FLOAT);
|
||||
@@ -1,23 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Locale\Locale;
|
||||
|
||||
Locale::$exceptions = false;
|
||||
|
||||
$locales = Config::getParam('locale-codes', []);
|
||||
|
||||
foreach ($locales as $locale) {
|
||||
$code = $locale['code'];
|
||||
|
||||
$path = __DIR__ . '/../config/locale/translations/' . $code . '.json';
|
||||
|
||||
if (!\file_exists($path)) {
|
||||
$path = __DIR__ . '/../config/locale/translations/' . \substr($code, 0, 2) . '.json'; // if `ar-ae` doesn't exist, look for `ar`
|
||||
if (!\file_exists($path)) {
|
||||
$path = __DIR__ . '/../config/locale/translations/en.json'; // if none translation exists, use default from `en.json`
|
||||
}
|
||||
}
|
||||
|
||||
Locale::setLanguageFromJSON($code, $path);
|
||||
}
|
||||
@@ -1,340 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\GraphQL\Promises\Adapter\Swoole;
|
||||
use Appwrite\Hooks\Hooks;
|
||||
use Appwrite\PubSub\Adapter\Redis as PubSub;
|
||||
use Appwrite\URL\URL as AppwriteURL;
|
||||
use MaxMind\Db\Reader;
|
||||
use PHPMailer\PHPMailer\PHPMailer;
|
||||
use Swoole\Database\PDOProxy;
|
||||
use Utopia\App;
|
||||
use Utopia\Cache\Adapter\Redis as RedisCache;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Adapter\MariaDB;
|
||||
use Utopia\Database\Adapter\MySQL;
|
||||
use Utopia\Database\Adapter\SQL;
|
||||
use Utopia\Domains\Validator\PublicDomain;
|
||||
use Utopia\DSN\DSN;
|
||||
use Utopia\Logger\Adapter\AppSignal;
|
||||
use Utopia\Logger\Adapter\LogOwl;
|
||||
use Utopia\Logger\Adapter\Raygun;
|
||||
use Utopia\Logger\Adapter\Sentry;
|
||||
use Utopia\Logger\Logger;
|
||||
use Utopia\Pools\Group;
|
||||
use Utopia\Pools\Pool;
|
||||
use Utopia\Queue;
|
||||
use Utopia\Registry\Registry;
|
||||
use Utopia\System\System;
|
||||
|
||||
$register = new Registry();
|
||||
|
||||
App::setMode(System::getEnv('_APP_ENV', App::MODE_TYPE_PRODUCTION));
|
||||
|
||||
if (!App::isProduction()) {
|
||||
// Allow specific domains to skip public domain validation in dev environment
|
||||
// Useful for existing tests involving webhooks
|
||||
PublicDomain::allow(['request-catcher']);
|
||||
}
|
||||
$register->set('logger', function () {
|
||||
// Register error logger
|
||||
$providerName = System::getEnv('_APP_LOGGING_PROVIDER', '');
|
||||
$providerConfig = System::getEnv('_APP_LOGGING_CONFIG', '');
|
||||
|
||||
if (empty($providerConfig)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$loggingProvider = new DSN($providerConfig ?? '');
|
||||
|
||||
$providerName = $loggingProvider->getScheme();
|
||||
$providerConfig = match ($providerName) {
|
||||
'sentry' => ['key' => $loggingProvider->getPassword(), 'projectId' => $loggingProvider->getUser() ?? '', 'host' => 'https://' . $loggingProvider->getHost()],
|
||||
'logowl' => ['ticket' => $loggingProvider->getUser() ?? '', 'host' => $loggingProvider->getHost()],
|
||||
default => ['key' => $loggingProvider->getHost()],
|
||||
};
|
||||
} catch (Throwable $th) {
|
||||
// Fallback for older Appwrite versions up to 1.5.x that use _APP_LOGGING_PROVIDER and _APP_LOGGING_CONFIG environment variables
|
||||
Console::warning('Using deprecated logging configuration. Please update your configuration to use DSN format.' . $th->getMessage());
|
||||
$configChunks = \explode(";", $providerConfig);
|
||||
|
||||
$providerConfig = match ($providerName) {
|
||||
'sentry' => [ 'key' => $configChunks[0], 'projectId' => $configChunks[1] ?? '', 'host' => '',],
|
||||
'logowl' => ['ticket' => $configChunks[0] ?? '', 'host' => ''],
|
||||
default => ['key' => $providerConfig],
|
||||
};
|
||||
}
|
||||
|
||||
if (empty($providerName) || empty($providerConfig)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Logger::hasProvider($providerName)) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, "Logging provider not supported. Logging is disabled");
|
||||
}
|
||||
|
||||
try {
|
||||
$adapter = match ($providerName) {
|
||||
'sentry' => new Sentry($providerConfig['projectId'], $providerConfig['key'], $providerConfig['host']),
|
||||
'logowl' => new LogOwl($providerConfig['ticket'], $providerConfig['host']),
|
||||
'raygun' => new Raygun($providerConfig['key']),
|
||||
'appsignal' => new AppSignal($providerConfig['key']),
|
||||
default => null
|
||||
};
|
||||
} catch (Throwable $th) {
|
||||
$adapter = null;
|
||||
}
|
||||
|
||||
if ($adapter === null) {
|
||||
Console::error("Logging provider not supported. Logging is disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
return new Logger($adapter);
|
||||
});
|
||||
|
||||
$register->set('pools', function () {
|
||||
$group = new Group();
|
||||
|
||||
$fallbackForDB = 'db_main=' . AppwriteURL::unparse([
|
||||
'scheme' => 'mariadb',
|
||||
'host' => System::getEnv('_APP_DB_HOST', 'mariadb'),
|
||||
'port' => System::getEnv('_APP_DB_PORT', '3306'),
|
||||
'user' => System::getEnv('_APP_DB_USER', ''),
|
||||
'pass' => System::getEnv('_APP_DB_PASS', ''),
|
||||
'path' => System::getEnv('_APP_DB_SCHEMA', ''),
|
||||
]);
|
||||
$fallbackForRedis = 'redis_main=' . AppwriteURL::unparse([
|
||||
'scheme' => 'redis',
|
||||
'host' => System::getEnv('_APP_REDIS_HOST', 'redis'),
|
||||
'port' => System::getEnv('_APP_REDIS_PORT', '6379'),
|
||||
'user' => System::getEnv('_APP_REDIS_USER', ''),
|
||||
'pass' => System::getEnv('_APP_REDIS_PASS', ''),
|
||||
]);
|
||||
|
||||
$connections = [
|
||||
'console' => [
|
||||
'type' => 'database',
|
||||
'dsns' => $fallbackForDB,
|
||||
'multiple' => false,
|
||||
'schemes' => ['mariadb', 'mysql'],
|
||||
],
|
||||
'database' => [
|
||||
'type' => 'database',
|
||||
'dsns' => $fallbackForDB,
|
||||
'multiple' => true,
|
||||
'schemes' => ['mariadb', 'mysql'],
|
||||
],
|
||||
'logs' => [
|
||||
'type' => 'database',
|
||||
'dsns' => System::getEnv('_APP_CONNECTIONS_DB_LOGS', $fallbackForDB),
|
||||
'multiple' => false,
|
||||
'schemes' => ['mariadb', 'mysql'],
|
||||
],
|
||||
'publisher' => [
|
||||
'type' => 'publisher',
|
||||
'dsns' => $fallbackForRedis,
|
||||
'multiple' => false,
|
||||
'schemes' => ['redis'],
|
||||
],
|
||||
'consumer' => [
|
||||
'type' => 'consumer',
|
||||
'dsns' => $fallbackForRedis,
|
||||
'multiple' => false,
|
||||
'schemes' => ['redis'],
|
||||
],
|
||||
'pubsub' => [
|
||||
'type' => 'pubsub',
|
||||
'dsns' => $fallbackForRedis,
|
||||
'multiple' => false,
|
||||
'schemes' => ['redis'],
|
||||
],
|
||||
'cache' => [
|
||||
'type' => 'cache',
|
||||
'dsns' => $fallbackForRedis,
|
||||
'multiple' => true,
|
||||
'schemes' => ['redis'],
|
||||
],
|
||||
];
|
||||
|
||||
$maxConnections = System::getEnv('_APP_CONNECTIONS_MAX', 151);
|
||||
$instanceConnections = $maxConnections / System::getEnv('_APP_POOL_CLIENTS', 14);
|
||||
|
||||
$multiprocessing = System::getEnv('_APP_SERVER_MULTIPROCESS', 'disabled') === 'enabled';
|
||||
|
||||
if ($multiprocessing) {
|
||||
$workerCount = intval(System::getEnv('_APP_CPU_NUM', swoole_cpu_num())) * intval(System::getEnv('_APP_WORKER_PER_CORE', 6));
|
||||
} else {
|
||||
$workerCount = 1;
|
||||
}
|
||||
|
||||
if ($workerCount > $instanceConnections) {
|
||||
throw new \Exception('Pool size is too small. Increase the number of allowed database connections or decrease the number of workers.', 500);
|
||||
}
|
||||
|
||||
$poolSize = (int)($instanceConnections / $workerCount);
|
||||
|
||||
foreach ($connections as $key => $connection) {
|
||||
$type = $connection['type'] ?? '';
|
||||
$multiple = $connection['multiple'] ?? false;
|
||||
$schemes = $connection['schemes'] ?? [];
|
||||
$config = [];
|
||||
$dsns = explode(',', $connection['dsns'] ?? '');
|
||||
foreach ($dsns as &$dsn) {
|
||||
$dsn = explode('=', $dsn);
|
||||
$name = ($multiple) ? $key . '_' . $dsn[0] : $key;
|
||||
$dsn = $dsn[1] ?? '';
|
||||
$config[] = $name;
|
||||
if (empty($dsn)) {
|
||||
//throw new Exception(Exception::GENERAL_SERVER_ERROR, "Missing value for DSN connection in {$key}");
|
||||
continue;
|
||||
}
|
||||
|
||||
$dsn = new DSN($dsn);
|
||||
$dsnHost = $dsn->getHost();
|
||||
$dsnPort = $dsn->getPort();
|
||||
$dsnUser = $dsn->getUser();
|
||||
$dsnPass = $dsn->getPassword();
|
||||
$dsnScheme = $dsn->getScheme();
|
||||
$dsnDatabase = $dsn->getPath();
|
||||
|
||||
if (!in_array($dsnScheme, $schemes)) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, "Invalid console database scheme");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Resource
|
||||
*
|
||||
* Creation could be reused across connection types like database, cache, queue, etc.
|
||||
*
|
||||
* Resource assignment to an adapter will happen below.
|
||||
*/
|
||||
$resource = match ($dsnScheme) {
|
||||
'mysql',
|
||||
'mariadb' => function () use ($dsnHost, $dsnPort, $dsnUser, $dsnPass, $dsnDatabase) {
|
||||
return new PDOProxy(function () use ($dsnHost, $dsnPort, $dsnUser, $dsnPass, $dsnDatabase) {
|
||||
return new PDO("mysql:host={$dsnHost};port={$dsnPort};dbname={$dsnDatabase};charset=utf8mb4", $dsnUser, $dsnPass, array(
|
||||
PDO::ATTR_TIMEOUT => 3, // Seconds
|
||||
PDO::ATTR_PERSISTENT => false,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_EMULATE_PREPARES => true,
|
||||
PDO::ATTR_STRINGIFY_FETCHES => true
|
||||
));
|
||||
});
|
||||
},
|
||||
'redis' => function () use ($dsnHost, $dsnPort, $dsnPass) {
|
||||
$redis = new \Redis();
|
||||
@$redis->pconnect($dsnHost, (int)$dsnPort);
|
||||
if ($dsnPass) {
|
||||
$redis->auth($dsnPass);
|
||||
}
|
||||
$redis->setOption(\Redis::OPT_READ_TIMEOUT, -1);
|
||||
|
||||
return $redis;
|
||||
},
|
||||
default => throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Invalid scheme'),
|
||||
};
|
||||
|
||||
$pool = new Pool($name, $poolSize, function () use ($type, $resource, $dsn) {
|
||||
// Get Adapter
|
||||
switch ($type) {
|
||||
case 'database':
|
||||
$adapter = match ($dsn->getScheme()) {
|
||||
'mariadb' => new MariaDB($resource()),
|
||||
'mysql' => new MySQL($resource()),
|
||||
default => null
|
||||
};
|
||||
|
||||
$adapter->setDatabase($dsn->getPath());
|
||||
return $adapter;
|
||||
case 'pubsub':
|
||||
return match ($dsn->getScheme()) {
|
||||
'redis' => new PubSub($resource()),
|
||||
default => null
|
||||
};
|
||||
case 'publisher':
|
||||
case 'consumer':
|
||||
return match ($dsn->getScheme()) {
|
||||
'redis' => new Queue\Broker\Redis(new Queue\Connection\Redis($dsn->getHost(), $dsn->getPort())),
|
||||
default => null
|
||||
};
|
||||
case 'cache':
|
||||
return match ($dsn->getScheme()) {
|
||||
'redis' => new RedisCache($resource()),
|
||||
default => null
|
||||
};
|
||||
default:
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, "Server error: Missing adapter implementation.");
|
||||
}
|
||||
});
|
||||
|
||||
$group->add($pool);
|
||||
}
|
||||
|
||||
Config::setParam('pools-' . $key, $config);
|
||||
}
|
||||
|
||||
return $group;
|
||||
});
|
||||
|
||||
$register->set('db', function () {
|
||||
// This is usually for our workers or CLI commands scope
|
||||
$dbHost = System::getEnv('_APP_DB_HOST', '');
|
||||
$dbPort = System::getEnv('_APP_DB_PORT', '');
|
||||
$dbUser = System::getEnv('_APP_DB_USER', '');
|
||||
$dbPass = System::getEnv('_APP_DB_PASS', '');
|
||||
$dbScheme = System::getEnv('_APP_DB_SCHEMA', '');
|
||||
|
||||
return new PDO(
|
||||
"mysql:host={$dbHost};port={$dbPort};dbname={$dbScheme};charset=utf8mb4",
|
||||
$dbUser,
|
||||
$dbPass,
|
||||
SQL::getPDOAttributes()
|
||||
);
|
||||
});
|
||||
|
||||
$register->set('smtp', function () {
|
||||
$mail = new PHPMailer(true);
|
||||
|
||||
$mail->isSMTP();
|
||||
|
||||
$username = System::getEnv('_APP_SMTP_USERNAME');
|
||||
$password = System::getEnv('_APP_SMTP_PASSWORD');
|
||||
|
||||
$mail->XMailer = 'Appwrite Mailer';
|
||||
$mail->Host = System::getEnv('_APP_SMTP_HOST', 'smtp');
|
||||
$mail->Port = System::getEnv('_APP_SMTP_PORT', 25);
|
||||
$mail->SMTPAuth = !empty($username) && !empty($password);
|
||||
$mail->Username = $username;
|
||||
$mail->Password = $password;
|
||||
$mail->SMTPSecure = System::getEnv('_APP_SMTP_SECURE', '');
|
||||
$mail->SMTPAutoTLS = false;
|
||||
$mail->CharSet = 'UTF-8';
|
||||
|
||||
$from = \urldecode(System::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server'));
|
||||
$email = System::getEnv('_APP_SYSTEM_EMAIL_ADDRESS', APP_EMAIL_TEAM);
|
||||
|
||||
$mail->setFrom($email, $from);
|
||||
$mail->addReplyTo($email, $from);
|
||||
|
||||
$mail->isHTML(true);
|
||||
|
||||
return $mail;
|
||||
});
|
||||
$register->set('geodb', function () {
|
||||
return new Reader(__DIR__ . '/../assets/dbip/dbip-country-lite-2024-09.mmdb');
|
||||
});
|
||||
$register->set('passwordsDictionary', function () {
|
||||
$content = \file_get_contents(__DIR__ . '/../assets/security/10k-common-passwords');
|
||||
$content = explode("\n", $content);
|
||||
$content = array_flip($content);
|
||||
return $content;
|
||||
});
|
||||
$register->set('promiseAdapter', function () {
|
||||
return new Swoole();
|
||||
});
|
||||
$register->set('hooks', function () {
|
||||
return new Hooks();
|
||||
});
|
||||
@@ -1,824 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Ahc\Jwt\JWT;
|
||||
use Ahc\Jwt\JWTException;
|
||||
use Appwrite\Auth\Auth;
|
||||
use Appwrite\Auth\Key;
|
||||
use Appwrite\Event\Audit;
|
||||
use Appwrite\Event\Build;
|
||||
use Appwrite\Event\Certificate;
|
||||
use Appwrite\Event\Database as EventDatabase;
|
||||
use Appwrite\Event\Delete;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Func;
|
||||
use Appwrite\Event\Mail;
|
||||
use Appwrite\Event\Messaging;
|
||||
use Appwrite\Event\Migration;
|
||||
use Appwrite\Event\Realtime;
|
||||
use Appwrite\Event\StatsUsage;
|
||||
use Appwrite\Event\Webhook;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\GraphQL\Schema;
|
||||
use Appwrite\Network\Validator\Origin;
|
||||
use Appwrite\Utopia\Request;
|
||||
use Utopia\Abuse\Adapters\TimeLimit\Redis as TimeLimitRedis;
|
||||
use Utopia\App;
|
||||
use Utopia\Cache\Adapter\Sharding;
|
||||
use Utopia\Cache\Cache;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\DSN\DSN;
|
||||
use Utopia\Locale\Locale;
|
||||
use Utopia\Logger\Log;
|
||||
use Utopia\Pools\Group;
|
||||
use Utopia\Queue\Publisher;
|
||||
use Utopia\Storage\Device;
|
||||
use Utopia\Storage\Device\Backblaze;
|
||||
use Utopia\Storage\Device\DOSpaces;
|
||||
use Utopia\Storage\Device\Linode;
|
||||
use Utopia\Storage\Device\Local;
|
||||
use Utopia\Storage\Device\S3;
|
||||
use Utopia\Storage\Device\Wasabi;
|
||||
use Utopia\Storage\Storage;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\Hostname;
|
||||
use Utopia\VCS\Adapter\Git\GitHub as VcsGitHub;
|
||||
|
||||
// Runtime Execution
|
||||
App::setResource('log', fn () => new Log());
|
||||
App::setResource('logger', function ($register) {
|
||||
return $register->get('logger');
|
||||
}, ['register']);
|
||||
|
||||
App::setResource('hooks', function ($register) {
|
||||
return $register->get('hooks');
|
||||
}, ['register']);
|
||||
|
||||
App::setResource('register', fn () => $register);
|
||||
App::setResource('locale', fn () => new Locale(System::getEnv('_APP_LOCALE', 'en')));
|
||||
|
||||
App::setResource('localeCodes', function () {
|
||||
return array_map(fn ($locale) => $locale['code'], Config::getParam('locale-codes', []));
|
||||
});
|
||||
|
||||
// Queues
|
||||
App::setResource('publisher', function (Group $pools) {
|
||||
return $pools->get('publisher')->pop()->getResource();
|
||||
}, ['pools']);
|
||||
App::setResource('consumer', function (Group $pools) {
|
||||
return $pools->get('consumer')->pop()->getResource();
|
||||
}, ['pools']);
|
||||
App::setResource('queueForMessaging', function (Publisher $publisher) {
|
||||
return new Messaging($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForMails', function (Publisher $publisher) {
|
||||
return new Mail($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForBuilds', function (Publisher $publisher) {
|
||||
return new Build($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForDatabase', function (Publisher $publisher) {
|
||||
return new EventDatabase($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForDeletes', function (Publisher $publisher) {
|
||||
return new Delete($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForEvents', function (Publisher $publisher) {
|
||||
return new Event($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForWebhooks', function (Publisher $publisher) {
|
||||
return new Webhook($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForRealtime', function () {
|
||||
return new Realtime();
|
||||
}, []);
|
||||
App::setResource('queueForStatsUsage', function (Publisher $publisher) {
|
||||
return new StatsUsage($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForAudits', function (Publisher $publisher) {
|
||||
return new Audit($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForFunctions', function (Publisher $publisher) {
|
||||
return new Func($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForCertificates', function (Publisher $publisher) {
|
||||
return new Certificate($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForMigrations', function (Publisher $publisher) {
|
||||
return new Migration($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('clients', function ($request, $console, $project) {
|
||||
$console->setAttribute('platforms', [ // Always allow current host
|
||||
'$collection' => ID::custom('platforms'),
|
||||
'name' => 'Current Host',
|
||||
'type' => Origin::CLIENT_TYPE_WEB,
|
||||
'hostname' => $request->getHostname(),
|
||||
], Document::SET_TYPE_APPEND);
|
||||
|
||||
$hostnames = explode(',', System::getEnv('_APP_CONSOLE_HOSTNAMES', ''));
|
||||
$validator = new Hostname();
|
||||
foreach ($hostnames as $hostname) {
|
||||
$hostname = trim($hostname);
|
||||
if (!$validator->isValid($hostname)) {
|
||||
continue;
|
||||
}
|
||||
$console->setAttribute('platforms', [
|
||||
'$collection' => ID::custom('platforms'),
|
||||
'type' => Origin::CLIENT_TYPE_WEB,
|
||||
'name' => $hostname,
|
||||
'hostname' => $hostname,
|
||||
], Document::SET_TYPE_APPEND);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get All verified client URLs for both console and current projects
|
||||
* + Filter for duplicated entries
|
||||
*/
|
||||
$clientsConsole = \array_map(
|
||||
fn ($node) => $node['hostname'],
|
||||
\array_filter(
|
||||
$console->getAttribute('platforms', []),
|
||||
fn ($node) => (isset($node['type']) && ($node['type'] === Origin::CLIENT_TYPE_WEB) && !empty($node['hostname']))
|
||||
)
|
||||
);
|
||||
|
||||
$clients = $clientsConsole;
|
||||
$platforms = $project->getAttribute('platforms', []);
|
||||
|
||||
foreach ($platforms as $node) {
|
||||
if (
|
||||
isset($node['type']) &&
|
||||
($node['type'] === Origin::CLIENT_TYPE_WEB ||
|
||||
$node['type'] === Origin::CLIENT_TYPE_FLUTTER_WEB) &&
|
||||
!empty($node['hostname'])
|
||||
) {
|
||||
$clients[] = $node['hostname'];
|
||||
}
|
||||
}
|
||||
|
||||
return \array_unique($clients);
|
||||
}, ['request', 'console', 'project']);
|
||||
|
||||
App::setResource('user', function ($mode, $project, $console, $request, $response, $dbForProject, $dbForPlatform) {
|
||||
/** @var Appwrite\Utopia\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Utopia\Database\Database $dbForPlatform */
|
||||
/** @var string $mode */
|
||||
|
||||
Authorization::setDefaultStatus(true);
|
||||
|
||||
Auth::setCookieName('a_session_' . $project->getId());
|
||||
|
||||
if (APP_MODE_ADMIN === $mode) {
|
||||
Auth::setCookieName('a_session_' . $console->getId());
|
||||
}
|
||||
|
||||
$session = Auth::decodeSession(
|
||||
$request->getCookie(
|
||||
Auth::$cookieName, // Get sessions
|
||||
$request->getCookie(Auth::$cookieName . '_legacy', '')
|
||||
)
|
||||
);
|
||||
|
||||
// Get session from header for SSR clients
|
||||
if (empty($session['id']) && empty($session['secret'])) {
|
||||
$sessionHeader = $request->getHeader('x-appwrite-session', '');
|
||||
|
||||
if (!empty($sessionHeader)) {
|
||||
$session = Auth::decodeSession($sessionHeader);
|
||||
}
|
||||
}
|
||||
|
||||
// Get fallback session from old clients (no SameSite support) or clients who block 3rd-party cookies
|
||||
if ($response) {
|
||||
$response->addHeader('X-Debug-Fallback', 'false');
|
||||
}
|
||||
|
||||
if (empty($session['id']) && empty($session['secret'])) {
|
||||
if ($response) {
|
||||
$response->addHeader('X-Debug-Fallback', 'true');
|
||||
}
|
||||
$fallback = $request->getHeader('x-fallback-cookies', '');
|
||||
$fallback = \json_decode($fallback, true);
|
||||
$session = Auth::decodeSession(((isset($fallback[Auth::$cookieName])) ? $fallback[Auth::$cookieName] : ''));
|
||||
}
|
||||
|
||||
Auth::$unique = $session['id'] ?? '';
|
||||
Auth::$secret = $session['secret'] ?? '';
|
||||
|
||||
if (APP_MODE_ADMIN !== $mode) {
|
||||
if ($project->isEmpty()) {
|
||||
$user = new Document([]);
|
||||
} else {
|
||||
if ($project->getId() === 'console') {
|
||||
$user = $dbForPlatform->getDocument('users', Auth::$unique);
|
||||
} else {
|
||||
$user = $dbForProject->getDocument('users', Auth::$unique);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$user = $dbForPlatform->getDocument('users', Auth::$unique);
|
||||
}
|
||||
|
||||
if (
|
||||
$user->isEmpty() // Check a document has been found in the DB
|
||||
|| !Auth::sessionVerify($user->getAttribute('sessions', []), Auth::$secret)
|
||||
) { // Validate user has valid login token
|
||||
$user = new Document([]);
|
||||
}
|
||||
|
||||
// if (APP_MODE_ADMIN === $mode) {
|
||||
// if ($user->find('teamInternalId', $project->getAttribute('teamInternalId'), 'memberships')) {
|
||||
// Authorization::setDefaultStatus(false); // Cancel security segmentation for admin users.
|
||||
// } else {
|
||||
// $user = new Document([]);
|
||||
// }
|
||||
// }
|
||||
|
||||
$authJWT = $request->getHeader('x-appwrite-jwt', '');
|
||||
|
||||
if (!empty($authJWT) && !$project->isEmpty()) { // JWT authentication
|
||||
$jwt = new JWT(System::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 3600, 0);
|
||||
|
||||
try {
|
||||
$payload = $jwt->decode($authJWT);
|
||||
} catch (JWTException $error) {
|
||||
throw new Exception(Exception::USER_JWT_INVALID, 'Failed to verify JWT. ' . $error->getMessage());
|
||||
}
|
||||
|
||||
$jwtUserId = $payload['userId'] ?? '';
|
||||
if (!empty($jwtUserId)) {
|
||||
$user = $dbForProject->getDocument('users', $jwtUserId);
|
||||
}
|
||||
|
||||
$jwtSessionId = $payload['sessionId'] ?? '';
|
||||
if (!empty($jwtSessionId)) {
|
||||
if (empty($user->find('$id', $jwtSessionId, 'sessions'))) { // Match JWT to active token
|
||||
$user = new Document([]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$dbForProject->setMetadata('user', $user->getId());
|
||||
$dbForPlatform->setMetadata('user', $user->getId());
|
||||
|
||||
return $user;
|
||||
}, ['mode', 'project', 'console', 'request', 'response', 'dbForProject', 'dbForPlatform']);
|
||||
|
||||
App::setResource('project', function ($dbForPlatform, $request, $console) {
|
||||
/** @var Appwrite\Utopia\Request $request */
|
||||
/** @var Utopia\Database\Database $dbForPlatform */
|
||||
/** @var Utopia\Database\Document $console */
|
||||
|
||||
$projectId = $request->getParam('project', $request->getHeader('x-appwrite-project', ''));
|
||||
|
||||
if (empty($projectId) || $projectId === 'console') {
|
||||
return $console;
|
||||
}
|
||||
|
||||
$project = Authorization::skip(fn () => $dbForPlatform->getDocument('projects', $projectId));
|
||||
|
||||
return $project;
|
||||
}, ['dbForPlatform', 'request', 'console']);
|
||||
|
||||
App::setResource('session', function (Document $user) {
|
||||
if ($user->isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$sessions = $user->getAttribute('sessions', []);
|
||||
$sessionId = Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret);
|
||||
|
||||
if (!$sessionId) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($sessions as $session) {/** @var Document $session */
|
||||
if ($sessionId === $session->getId()) {
|
||||
return $session;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}, ['user']);
|
||||
|
||||
App::setResource('console', function () {
|
||||
return new Document(Config::getParam('console'));
|
||||
}, []);
|
||||
|
||||
App::setResource('dbForProject', function (Group $pools, Database $dbForPlatform, Cache $cache, Document $project) {
|
||||
if ($project->isEmpty() || $project->getId() === 'console') {
|
||||
return $dbForPlatform;
|
||||
}
|
||||
|
||||
try {
|
||||
$dsn = new DSN($project->getAttribute('database'));
|
||||
} catch (\InvalidArgumentException) {
|
||||
// TODO: Temporary until all projects are using shared tables
|
||||
$dsn = new DSN('mysql://' . $project->getAttribute('database'));
|
||||
}
|
||||
|
||||
$dbAdapter = $pools
|
||||
->get($dsn->getHost())
|
||||
->pop()
|
||||
->getResource();
|
||||
|
||||
$database = new Database($dbAdapter, $cache);
|
||||
|
||||
$database
|
||||
->setMetadata('host', \gethostname())
|
||||
->setMetadata('project', $project->getId())
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_API)
|
||||
->setMaxQueryValues(APP_DATABASE_QUERY_MAX_VALUES);
|
||||
|
||||
$sharedTables = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', ''));
|
||||
|
||||
if (\in_array($dsn->getHost(), $sharedTables)) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setTenant($project->getInternalId())
|
||||
->setNamespace($dsn->getParam('namespace'));
|
||||
} else {
|
||||
$database
|
||||
->setSharedTables(false)
|
||||
->setTenant(null)
|
||||
->setNamespace('_' . $project->getInternalId());
|
||||
}
|
||||
|
||||
return $database;
|
||||
}, ['pools', 'dbForPlatform', 'cache', 'project']);
|
||||
|
||||
App::setResource('dbForPlatform', function (Group $pools, Cache $cache) {
|
||||
$dbAdapter = $pools
|
||||
->get('console')
|
||||
->pop()
|
||||
->getResource();
|
||||
|
||||
$database = new Database($dbAdapter, $cache);
|
||||
|
||||
$database
|
||||
->setNamespace('_console')
|
||||
->setMetadata('host', \gethostname())
|
||||
->setMetadata('project', 'console')
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_API)
|
||||
->setMaxQueryValues(APP_DATABASE_QUERY_MAX_VALUES);
|
||||
|
||||
return $database;
|
||||
}, ['pools', 'cache']);
|
||||
|
||||
App::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform, $cache) {
|
||||
$databases = []; // TODO: @Meldiron This should probably be responsibility of utopia-php/pools
|
||||
|
||||
return function (Document $project) use ($pools, $dbForPlatform, $cache, &$databases) {
|
||||
if ($project->isEmpty() || $project->getId() === 'console') {
|
||||
return $dbForPlatform;
|
||||
}
|
||||
|
||||
try {
|
||||
$dsn = new DSN($project->getAttribute('database'));
|
||||
} catch (\InvalidArgumentException) {
|
||||
// TODO: Temporary until all projects are using shared tables
|
||||
$dsn = new DSN('mysql://' . $project->getAttribute('database'));
|
||||
}
|
||||
|
||||
$configure = (function (Database $database) use ($project, $dsn) {
|
||||
$database
|
||||
->setMetadata('host', \gethostname())
|
||||
->setMetadata('project', $project->getId())
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_API)
|
||||
->setMaxQueryValues(APP_DATABASE_QUERY_MAX_VALUES);
|
||||
|
||||
$sharedTables = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', ''));
|
||||
|
||||
if (\in_array($dsn->getHost(), $sharedTables)) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setTenant($project->getInternalId())
|
||||
->setNamespace($dsn->getParam('namespace'));
|
||||
} else {
|
||||
$database
|
||||
->setSharedTables(false)
|
||||
->setTenant(null)
|
||||
->setNamespace('_' . $project->getInternalId());
|
||||
}
|
||||
});
|
||||
|
||||
if (isset($databases[$dsn->getHost()])) {
|
||||
$database = $databases[$dsn->getHost()];
|
||||
$configure($database);
|
||||
return $database;
|
||||
}
|
||||
|
||||
$dbAdapter = $pools
|
||||
->get($dsn->getHost())
|
||||
->pop()
|
||||
->getResource();
|
||||
|
||||
$database = new Database($dbAdapter, $cache);
|
||||
$databases[$dsn->getHost()] = $database;
|
||||
$configure($database);
|
||||
|
||||
return $database;
|
||||
};
|
||||
}, ['pools', 'dbForPlatform', 'cache']);
|
||||
|
||||
App::setResource('getLogsDB', function (Group $pools, Cache $cache) {
|
||||
$database = null;
|
||||
return function (?Document $project = null) use ($pools, $cache, $database) {
|
||||
if ($database !== null && $project !== null && !$project->isEmpty() && $project->getId() !== 'console') {
|
||||
$database->setTenant($project->getInternalId());
|
||||
return $database;
|
||||
}
|
||||
|
||||
$dbAdapter = $pools
|
||||
->get('logs')
|
||||
->pop()
|
||||
->getResource();
|
||||
|
||||
$database = new Database(
|
||||
$dbAdapter,
|
||||
$cache
|
||||
);
|
||||
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setNamespace('logsV1')
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_API)
|
||||
->setMaxQueryValues(APP_DATABASE_QUERY_MAX_VALUES);
|
||||
|
||||
// set tenant
|
||||
if ($project !== null && !$project->isEmpty() && $project->getId() !== 'console') {
|
||||
$database->setTenant($project->getInternalId());
|
||||
}
|
||||
|
||||
return $database;
|
||||
};
|
||||
}, ['pools', 'cache']);
|
||||
|
||||
App::setResource('cache', function (Group $pools) {
|
||||
$list = Config::getParam('pools-cache', []);
|
||||
$adapters = [];
|
||||
|
||||
foreach ($list as $value) {
|
||||
$adapters[] = $pools
|
||||
->get($value)
|
||||
->pop()
|
||||
->getResource()
|
||||
;
|
||||
}
|
||||
|
||||
return new Cache(new Sharding($adapters));
|
||||
}, ['pools']);
|
||||
|
||||
App::setResource('redis', function () {
|
||||
$host = System::getEnv('_APP_REDIS_HOST', 'localhost');
|
||||
$port = System::getEnv('_APP_REDIS_PORT', 6379);
|
||||
$pass = System::getEnv('_APP_REDIS_PASS', '');
|
||||
|
||||
$redis = new \Redis();
|
||||
@$redis->pconnect($host, (int)$port);
|
||||
if ($pass) {
|
||||
$redis->auth($pass);
|
||||
}
|
||||
$redis->setOption(\Redis::OPT_READ_TIMEOUT, -1);
|
||||
|
||||
return $redis;
|
||||
});
|
||||
|
||||
App::setResource('timelimit', function (\Redis $redis) {
|
||||
return function (string $key, int $limit, int $time) use ($redis) {
|
||||
return new TimeLimitRedis($key, $limit, $time, $redis);
|
||||
};
|
||||
}, ['redis']);
|
||||
|
||||
App::setResource('deviceForLocal', function () {
|
||||
return new Local();
|
||||
});
|
||||
|
||||
App::setResource('deviceForFiles', function ($project) {
|
||||
return getDevice(APP_STORAGE_UPLOADS . '/app-' . $project->getId());
|
||||
}, ['project']);
|
||||
|
||||
App::setResource('deviceForFunctions', function ($project) {
|
||||
return getDevice(APP_STORAGE_FUNCTIONS . '/app-' . $project->getId());
|
||||
}, ['project']);
|
||||
|
||||
App::setResource('deviceForBuilds', function ($project) {
|
||||
return getDevice(APP_STORAGE_BUILDS . '/app-' . $project->getId());
|
||||
}, ['project']);
|
||||
|
||||
function getDevice(string $root, string $connection = ''): Device
|
||||
{
|
||||
$connection = !empty($connection) ? $connection : System::getEnv('_APP_CONNECTIONS_STORAGE', '');
|
||||
|
||||
if (!empty($connection)) {
|
||||
$acl = 'private';
|
||||
$device = Storage::DEVICE_LOCAL;
|
||||
$accessKey = '';
|
||||
$accessSecret = '';
|
||||
$bucket = '';
|
||||
$region = '';
|
||||
$url = System::getEnv('_APP_STORAGE_S3_ENDPOINT', '');
|
||||
|
||||
try {
|
||||
$dsn = new DSN($connection);
|
||||
$device = $dsn->getScheme();
|
||||
$accessKey = $dsn->getUser() ?? '';
|
||||
$accessSecret = $dsn->getPassword() ?? '';
|
||||
$bucket = $dsn->getPath() ?? '';
|
||||
$region = $dsn->getParam('region');
|
||||
} catch (\Throwable $e) {
|
||||
Console::warning($e->getMessage() . 'Invalid DSN. Defaulting to Local device.');
|
||||
}
|
||||
|
||||
switch ($device) {
|
||||
case Storage::DEVICE_S3:
|
||||
return new S3($root, $accessKey, $accessSecret, $bucket, $region, $acl, $url);
|
||||
case STORAGE::DEVICE_DO_SPACES:
|
||||
$device = new DOSpaces($root, $accessKey, $accessSecret, $bucket, $region, $acl);
|
||||
$device->setHttpVersion(S3::HTTP_VERSION_1_1);
|
||||
return $device;
|
||||
case Storage::DEVICE_BACKBLAZE:
|
||||
return new Backblaze($root, $accessKey, $accessSecret, $bucket, $region, $acl);
|
||||
case Storage::DEVICE_LINODE:
|
||||
return new Linode($root, $accessKey, $accessSecret, $bucket, $region, $acl);
|
||||
case Storage::DEVICE_WASABI:
|
||||
return new Wasabi($root, $accessKey, $accessSecret, $bucket, $region, $acl);
|
||||
case Storage::DEVICE_LOCAL:
|
||||
default:
|
||||
return new Local($root);
|
||||
}
|
||||
} else {
|
||||
switch (strtolower(System::getEnv('_APP_STORAGE_DEVICE', Storage::DEVICE_LOCAL) ?? '')) {
|
||||
case Storage::DEVICE_LOCAL:
|
||||
default:
|
||||
return new Local($root);
|
||||
case Storage::DEVICE_S3:
|
||||
$s3AccessKey = System::getEnv('_APP_STORAGE_S3_ACCESS_KEY', '');
|
||||
$s3SecretKey = System::getEnv('_APP_STORAGE_S3_SECRET', '');
|
||||
$s3Region = System::getEnv('_APP_STORAGE_S3_REGION', '');
|
||||
$s3Bucket = System::getEnv('_APP_STORAGE_S3_BUCKET', '');
|
||||
$s3Acl = 'private';
|
||||
$s3EndpointUrl = System::getEnv('_APP_STORAGE_S3_ENDPOINT', '');
|
||||
return new S3($root, $s3AccessKey, $s3SecretKey, $s3Bucket, $s3Region, $s3Acl, $s3EndpointUrl);
|
||||
case Storage::DEVICE_DO_SPACES:
|
||||
$doSpacesAccessKey = System::getEnv('_APP_STORAGE_DO_SPACES_ACCESS_KEY', '');
|
||||
$doSpacesSecretKey = System::getEnv('_APP_STORAGE_DO_SPACES_SECRET', '');
|
||||
$doSpacesRegion = System::getEnv('_APP_STORAGE_DO_SPACES_REGION', '');
|
||||
$doSpacesBucket = System::getEnv('_APP_STORAGE_DO_SPACES_BUCKET', '');
|
||||
$doSpacesAcl = 'private';
|
||||
$device = new DOSpaces($root, $doSpacesAccessKey, $doSpacesSecretKey, $doSpacesBucket, $doSpacesRegion, $doSpacesAcl);
|
||||
$device->setHttpVersion(S3::HTTP_VERSION_1_1);
|
||||
return $device;
|
||||
case Storage::DEVICE_BACKBLAZE:
|
||||
$backblazeAccessKey = System::getEnv('_APP_STORAGE_BACKBLAZE_ACCESS_KEY', '');
|
||||
$backblazeSecretKey = System::getEnv('_APP_STORAGE_BACKBLAZE_SECRET', '');
|
||||
$backblazeRegion = System::getEnv('_APP_STORAGE_BACKBLAZE_REGION', '');
|
||||
$backblazeBucket = System::getEnv('_APP_STORAGE_BACKBLAZE_BUCKET', '');
|
||||
$backblazeAcl = 'private';
|
||||
return new Backblaze($root, $backblazeAccessKey, $backblazeSecretKey, $backblazeBucket, $backblazeRegion, $backblazeAcl);
|
||||
case Storage::DEVICE_LINODE:
|
||||
$linodeAccessKey = System::getEnv('_APP_STORAGE_LINODE_ACCESS_KEY', '');
|
||||
$linodeSecretKey = System::getEnv('_APP_STORAGE_LINODE_SECRET', '');
|
||||
$linodeRegion = System::getEnv('_APP_STORAGE_LINODE_REGION', '');
|
||||
$linodeBucket = System::getEnv('_APP_STORAGE_LINODE_BUCKET', '');
|
||||
$linodeAcl = 'private';
|
||||
return new Linode($root, $linodeAccessKey, $linodeSecretKey, $linodeBucket, $linodeRegion, $linodeAcl);
|
||||
case Storage::DEVICE_WASABI:
|
||||
$wasabiAccessKey = System::getEnv('_APP_STORAGE_WASABI_ACCESS_KEY', '');
|
||||
$wasabiSecretKey = System::getEnv('_APP_STORAGE_WASABI_SECRET', '');
|
||||
$wasabiRegion = System::getEnv('_APP_STORAGE_WASABI_REGION', '');
|
||||
$wasabiBucket = System::getEnv('_APP_STORAGE_WASABI_BUCKET', '');
|
||||
$wasabiAcl = 'private';
|
||||
return new Wasabi($root, $wasabiAccessKey, $wasabiSecretKey, $wasabiBucket, $wasabiRegion, $wasabiAcl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
App::setResource('mode', function ($request) {
|
||||
/** @var Appwrite\Utopia\Request $request */
|
||||
|
||||
/**
|
||||
* Defines the mode for the request:
|
||||
* - 'default' => Requests for Client and Server Side
|
||||
* - 'admin' => Request from the Console on non-console projects
|
||||
*/
|
||||
return $request->getParam('mode', $request->getHeader('x-appwrite-mode', APP_MODE_DEFAULT));
|
||||
}, ['request']);
|
||||
|
||||
App::setResource('geodb', function ($register) {
|
||||
/** @var Utopia\Registry\Registry $register */
|
||||
return $register->get('geodb');
|
||||
}, ['register']);
|
||||
|
||||
App::setResource('passwordsDictionary', function ($register) {
|
||||
/** @var Utopia\Registry\Registry $register */
|
||||
return $register->get('passwordsDictionary');
|
||||
}, ['register']);
|
||||
|
||||
|
||||
App::setResource('servers', function () {
|
||||
$platforms = Config::getParam('platforms');
|
||||
$server = $platforms[APP_PLATFORM_SERVER];
|
||||
|
||||
$languages = array_map(function ($language) {
|
||||
return strtolower($language['name']);
|
||||
}, $server['sdks']);
|
||||
|
||||
return $languages;
|
||||
});
|
||||
|
||||
App::setResource('promiseAdapter', function ($register) {
|
||||
return $register->get('promiseAdapter');
|
||||
}, ['register']);
|
||||
|
||||
App::setResource('schema', function ($utopia, $dbForProject) {
|
||||
|
||||
$complexity = function (int $complexity, array $args) {
|
||||
$queries = Query::parseQueries($args['queries'] ?? []);
|
||||
$query = Query::getByType($queries, [Query::TYPE_LIMIT])[0] ?? null;
|
||||
$limit = $query ? $query->getValue() : APP_LIMIT_LIST_DEFAULT;
|
||||
|
||||
return $complexity * $limit;
|
||||
};
|
||||
|
||||
$attributes = function (int $limit, int $offset) use ($dbForProject) {
|
||||
$attrs = Authorization::skip(fn () => $dbForProject->find('attributes', [
|
||||
Query::limit($limit),
|
||||
Query::offset($offset),
|
||||
]));
|
||||
|
||||
return \array_map(function ($attr) {
|
||||
return $attr->getArrayCopy();
|
||||
}, $attrs);
|
||||
};
|
||||
|
||||
$urls = [
|
||||
'list' => function (string $databaseId, string $collectionId, array $args) {
|
||||
return "/v1/databases/$databaseId/collections/$collectionId/documents";
|
||||
},
|
||||
'create' => function (string $databaseId, string $collectionId, array $args) {
|
||||
return "/v1/databases/$databaseId/collections/$collectionId/documents";
|
||||
},
|
||||
'read' => function (string $databaseId, string $collectionId, array $args) {
|
||||
return "/v1/databases/$databaseId/collections/$collectionId/documents/{$args['documentId']}";
|
||||
},
|
||||
'update' => function (string $databaseId, string $collectionId, array $args) {
|
||||
return "/v1/databases/$databaseId/collections/$collectionId/documents/{$args['documentId']}";
|
||||
},
|
||||
'delete' => function (string $databaseId, string $collectionId, array $args) {
|
||||
return "/v1/databases/$databaseId/collections/$collectionId/documents/{$args['documentId']}";
|
||||
},
|
||||
];
|
||||
|
||||
$params = [
|
||||
'list' => function (string $databaseId, string $collectionId, array $args) {
|
||||
return [ 'queries' => $args['queries']];
|
||||
},
|
||||
'create' => function (string $databaseId, string $collectionId, array $args) {
|
||||
$id = $args['id'] ?? 'unique()';
|
||||
$permissions = $args['permissions'] ?? null;
|
||||
|
||||
unset($args['id']);
|
||||
unset($args['permissions']);
|
||||
|
||||
// Order must be the same as the route params
|
||||
return [
|
||||
'databaseId' => $databaseId,
|
||||
'documentId' => $id,
|
||||
'collectionId' => $collectionId,
|
||||
'data' => $args,
|
||||
'permissions' => $permissions,
|
||||
];
|
||||
},
|
||||
'update' => function (string $databaseId, string $collectionId, array $args) {
|
||||
$documentId = $args['id'];
|
||||
$permissions = $args['permissions'] ?? null;
|
||||
|
||||
unset($args['id']);
|
||||
unset($args['permissions']);
|
||||
|
||||
// Order must be the same as the route params
|
||||
return [
|
||||
'databaseId' => $databaseId,
|
||||
'collectionId' => $collectionId,
|
||||
'documentId' => $documentId,
|
||||
'data' => $args,
|
||||
'permissions' => $permissions,
|
||||
];
|
||||
},
|
||||
];
|
||||
|
||||
return Schema::build(
|
||||
$utopia,
|
||||
$complexity,
|
||||
$attributes,
|
||||
$urls,
|
||||
$params,
|
||||
);
|
||||
}, ['utopia', 'dbForProject']);
|
||||
|
||||
App::setResource('contributors', function () {
|
||||
$path = 'app/config/contributors.json';
|
||||
$list = (file_exists($path)) ? json_decode(file_get_contents($path), true) : [];
|
||||
return $list;
|
||||
});
|
||||
|
||||
App::setResource('employees', function () {
|
||||
$path = 'app/config/employees.json';
|
||||
$list = (file_exists($path)) ? json_decode(file_get_contents($path), true) : [];
|
||||
return $list;
|
||||
});
|
||||
|
||||
App::setResource('heroes', function () {
|
||||
$path = 'app/config/heroes.json';
|
||||
$list = (file_exists($path)) ? json_decode(file_get_contents($path), true) : [];
|
||||
return $list;
|
||||
});
|
||||
|
||||
App::setResource('gitHub', function (Cache $cache) {
|
||||
return new VcsGitHub($cache);
|
||||
}, ['cache']);
|
||||
|
||||
App::setResource('requestTimestamp', function ($request) {
|
||||
//TODO: Move this to the Request class itself
|
||||
$timestampHeader = $request->getHeader('x-appwrite-timestamp');
|
||||
$requestTimestamp = null;
|
||||
if (!empty($timestampHeader)) {
|
||||
try {
|
||||
$requestTimestamp = new \DateTime($timestampHeader);
|
||||
} catch (\Throwable $e) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Invalid X-Appwrite-Timestamp header value');
|
||||
}
|
||||
}
|
||||
return $requestTimestamp;
|
||||
}, ['request']);
|
||||
|
||||
App::setResource('plan', function (array $plan = []) {
|
||||
return [];
|
||||
});
|
||||
|
||||
App::setResource('smsRates', function () {
|
||||
return [];
|
||||
});
|
||||
|
||||
App::setResource('team', function (Document $project, Database $dbForPlatform, App $utopia, Request $request) {
|
||||
$teamInternalId = '';
|
||||
if ($project->getId() !== 'console') {
|
||||
$teamInternalId = $project->getAttribute('teamInternalId', '');
|
||||
} else {
|
||||
$route = $utopia->match($request);
|
||||
$path = $route->getPath();
|
||||
if (str_starts_with($path, '/v1/projects/:projectId')) {
|
||||
$uri = $request->getURI();
|
||||
$pid = explode('/', $uri)[3];
|
||||
$p = Authorization::skip(fn () => $dbForPlatform->getDocument('projects', $pid));
|
||||
$teamInternalId = $p->getAttribute('teamInternalId', '');
|
||||
} elseif ($path === '/v1/projects') {
|
||||
$teamId = $request->getParam('teamId', '');
|
||||
$team = Authorization::skip(fn () => $dbForPlatform->getDocument('teams', $teamId));
|
||||
return $team;
|
||||
}
|
||||
}
|
||||
|
||||
$team = Authorization::skip(function () use ($dbForPlatform, $teamInternalId) {
|
||||
return $dbForPlatform->findOne('teams', [
|
||||
Query::equal('$internalId', [$teamInternalId]),
|
||||
]);
|
||||
});
|
||||
|
||||
return $team;
|
||||
}, ['project', 'dbForPlatform', 'utopia', 'request']);
|
||||
|
||||
App::setResource(
|
||||
'isResourceBlocked',
|
||||
fn () => fn (Document $project, string $resourceType, ?string $resourceId) => false
|
||||
);
|
||||
|
||||
App::setResource('previewHostname', function (Request $request) {
|
||||
if (App::isDevelopment()) {
|
||||
$host = $request->getQuery('appwrite-hostname') ?? '';
|
||||
if (!empty($host)) {
|
||||
return $host;
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}, ['request']);
|
||||
|
||||
App::setResource('apiKey', function (Request $request, Document $project): ?Key {
|
||||
$key = $request->getHeader('x-appwrite-key');
|
||||
|
||||
if (empty($key)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Key::decode($project, $key);
|
||||
}, ['request', 'project']);
|
||||
@@ -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 you’re looking for doesn’t 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>
|
||||
@@ -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
|
||||
@@ -168,7 +170,7 @@ $image = $this->getParam('image', '');
|
||||
appwrite-console:
|
||||
<<: *x-logging
|
||||
container_name: appwrite-console
|
||||
image: <?php echo $organization; ?>/console:5.2.53
|
||||
image: <?php echo $organization; ?>/console:5.2.27
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- appwrite
|
||||
@@ -342,8 +344,6 @@ $image = $this->getParam('image', '');
|
||||
- _APP_MAINTENANCE_RETENTION_ABUSE
|
||||
- _APP_MAINTENANCE_RETENTION_AUDIT
|
||||
- _APP_MAINTENANCE_RETENTION_EXECUTION
|
||||
- _APP_SYSTEM_SECURITY_EMAIL_ADDRESS
|
||||
- _APP_EMAIL_CERTIFICATES
|
||||
|
||||
appwrite-worker-databases:
|
||||
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
|
||||
@@ -404,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
|
||||
@@ -495,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
|
||||
@@ -861,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
|
||||
@@ -873,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
|
||||
|
||||
@@ -112,8 +112,6 @@ Server::setResource('dbForProject', function (Cache $cache, Registry $register,
|
||||
->setNamespace('_' . $project->getInternalId());
|
||||
}
|
||||
|
||||
$database->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER);
|
||||
|
||||
return $database;
|
||||
}, ['cache', 'register', 'message', 'project', 'dbForPlatform']);
|
||||
|
||||
@@ -175,8 +173,6 @@ Server::setResource('getProjectDB', function (Group $pools, Database $dbForPlatf
|
||||
->setNamespace('_' . $project->getInternalId());
|
||||
}
|
||||
|
||||
$database->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER);
|
||||
|
||||
return $database;
|
||||
};
|
||||
}, ['pools', 'dbForPlatform', 'cache']);
|
||||
@@ -202,7 +198,7 @@ Server::setResource('getLogsDB', function (Group $pools, Cache $cache) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setNamespace('logsV1')
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER)
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS)
|
||||
->setMaxQueryValues(APP_DATABASE_QUERY_MAX_VALUES);
|
||||
|
||||
// set tenant
|
||||
@@ -337,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']);
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php screenshot $@
|
||||
@@ -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,15 +44,16 @@
|
||||
"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.52.*",
|
||||
"utopia-php/abuse": "0.51.*",
|
||||
"utopia-php/analytics": "0.10.*",
|
||||
"utopia-php/audit": "0.55.*",
|
||||
"utopia-php/audit": "0.54.0",
|
||||
"utopia-php/cache": "0.12.*",
|
||||
"utopia-php/cli": "0.15.*",
|
||||
"utopia-php/config": "0.2.*",
|
||||
"utopia-php/database": "0.61.*",
|
||||
"utopia-php/detector": "0.1.*",
|
||||
"utopia-php/database": "0.60.*",
|
||||
"utopia-php/domains": "0.5.*",
|
||||
"utopia-php/dsn": "0.2.1",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
@@ -60,12 +62,12 @@
|
||||
"utopia-php/locale": "0.4.*",
|
||||
"utopia-php/logger": "0.6.*",
|
||||
"utopia-php/messaging": "0.16.*",
|
||||
"utopia-php/migration": "0.8.*",
|
||||
"utopia-php/migration": "0.6.*",
|
||||
"utopia-php/orchestration": "0.9.*",
|
||||
"utopia-php/platform": "0.7.*",
|
||||
"utopia-php/pools": "0.7.*",
|
||||
"utopia-php/platform": "0.7.3",
|
||||
"utopia-php/pools": "0.5.*",
|
||||
"utopia-php/preloader": "0.2.*",
|
||||
"utopia-php/queue": "0.9.*",
|
||||
"utopia-php/queue": "0.8.*",
|
||||
"utopia-php/registry": "0.5.*",
|
||||
"utopia-php/storage": "0.18.*",
|
||||
"utopia-php/swoole": "0.8.*",
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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": "e0d7f21b681e4591144fec16c4f0d6aa",
|
||||
"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",
|
||||
@@ -709,16 +709,16 @@
|
||||
},
|
||||
{
|
||||
"name": "google/protobuf",
|
||||
"version": "v4.30.1",
|
||||
"version": "v4.30.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/protocolbuffers/protobuf-php.git",
|
||||
"reference": "f29ba8a30dfd940efb3a8a75dc44446539101f24"
|
||||
"reference": "e1d66682f6836aa87820400f0aa07d9eb566feb6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/f29ba8a30dfd940efb3a8a75dc44446539101f24",
|
||||
"reference": "f29ba8a30dfd940efb3a8a75dc44446539101f24",
|
||||
"url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/e1d66682f6836aa87820400f0aa07d9eb566feb6",
|
||||
"reference": "e1d66682f6836aa87820400f0aa07d9eb566feb6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -747,9 +747,9 @@
|
||||
"proto"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.30.1"
|
||||
"source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.30.0"
|
||||
},
|
||||
"time": "2025-03-13T21:08:17+00:00"
|
||||
"time": "2025-03-04T22:54:49+00:00"
|
||||
},
|
||||
{
|
||||
"name": "jean85/pretty-package-versions",
|
||||
@@ -3364,16 +3364,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/abuse",
|
||||
"version": "0.52.0",
|
||||
"version": "0.51.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/abuse.git",
|
||||
"reference": "a0d6421e7e5baa3ac02755496dca9fdeaa814b93"
|
||||
"reference": "661687b03277f1d202a0e8cf9da6e58c97da2b5e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/a0d6421e7e5baa3ac02755496dca9fdeaa814b93",
|
||||
"reference": "a0d6421e7e5baa3ac02755496dca9fdeaa814b93",
|
||||
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/661687b03277f1d202a0e8cf9da6e58c97da2b5e",
|
||||
"reference": "661687b03277f1d202a0e8cf9da6e58c97da2b5e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3381,7 +3381,7 @@
|
||||
"ext-pdo": "*",
|
||||
"ext-redis": "*",
|
||||
"php": ">=8.0",
|
||||
"utopia-php/database": "0.*.*"
|
||||
"utopia-php/database": "0.60.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.*",
|
||||
@@ -3409,9 +3409,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/abuse/issues",
|
||||
"source": "https://github.com/utopia-php/abuse/tree/0.52.0"
|
||||
"source": "https://github.com/utopia-php/abuse/tree/0.51.0"
|
||||
},
|
||||
"time": "2025-03-06T03:48:29+00:00"
|
||||
"time": "2025-02-17T11:10:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/analytics",
|
||||
@@ -3461,21 +3461,21 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/audit",
|
||||
"version": "0.55.0",
|
||||
"version": "0.54.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/audit.git",
|
||||
"reference": "9f8cfe5fa5d5011b8dbf93b710236dfa91dc5518"
|
||||
"reference": "1b0cb8ac6bfbd7703e3f9a753c6ba59ff1c39975"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/audit/zipball/9f8cfe5fa5d5011b8dbf93b710236dfa91dc5518",
|
||||
"reference": "9f8cfe5fa5d5011b8dbf93b710236dfa91dc5518",
|
||||
"url": "https://api.github.com/repos/utopia-php/audit/zipball/1b0cb8ac6bfbd7703e3f9a753c6ba59ff1c39975",
|
||||
"reference": "1b0cb8ac6bfbd7703e3f9a753c6ba59ff1c39975",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0",
|
||||
"utopia-php/database": "0.*.*"
|
||||
"utopia-php/database": "0.60.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.*",
|
||||
@@ -3502,9 +3502,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/audit/issues",
|
||||
"source": "https://github.com/utopia-php/audit/tree/0.55.0"
|
||||
"source": "https://github.com/utopia-php/audit/tree/0.54.0"
|
||||
},
|
||||
"time": "2025-03-06T03:47:47+00:00"
|
||||
"time": "2025-02-25T07:21:07+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/cache",
|
||||
@@ -3705,16 +3705,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/database",
|
||||
"version": "0.61.2",
|
||||
"version": "0.60.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/database.git",
|
||||
"reference": "349fbdf4bc088f7775c7dfb8b80239a617a88436"
|
||||
"reference": "f3c9aa964b39c6205069f038a26e709a15541406"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/349fbdf4bc088f7775c7dfb8b80239a617a88436",
|
||||
"reference": "349fbdf4bc088f7775c7dfb8b80239a617a88436",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/f3c9aa964b39c6205069f038a26e709a15541406",
|
||||
"reference": "f3c9aa964b39c6205069f038a26e709a15541406",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3755,9 +3755,54 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/database/issues",
|
||||
"source": "https://github.com/utopia-php/database/tree/0.61.2"
|
||||
"source": "https://github.com/utopia-php/database/tree/0.60.6"
|
||||
},
|
||||
"time": "2025-03-15T11:47:42+00:00"
|
||||
"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",
|
||||
@@ -4159,16 +4204,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/migration",
|
||||
"version": "0.8.1",
|
||||
"version": "0.6.20",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/migration.git",
|
||||
"reference": "36ec7af2e6bf78de5d86e1b0a953fd7dcdf69dab"
|
||||
"reference": "8c9ba52196f50aaef4aa1903f0d8fe0c8d9997ba"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/migration/zipball/36ec7af2e6bf78de5d86e1b0a953fd7dcdf69dab",
|
||||
"reference": "36ec7af2e6bf78de5d86e1b0a953fd7dcdf69dab",
|
||||
"url": "https://api.github.com/repos/utopia-php/migration/zipball/8c9ba52196f50aaef4aa1903f0d8fe0c8d9997ba",
|
||||
"reference": "8c9ba52196f50aaef4aa1903f0d8fe0c8d9997ba",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4176,7 +4221,7 @@
|
||||
"ext-curl": "*",
|
||||
"ext-openssl": "*",
|
||||
"php": ">=8.1",
|
||||
"utopia-php/database": "0.61.*",
|
||||
"utopia-php/database": "0.60.*",
|
||||
"utopia-php/dsn": "0.2.*",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
"utopia-php/storage": "0.18.*"
|
||||
@@ -4209,9 +4254,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/migration/issues",
|
||||
"source": "https://github.com/utopia-php/migration/tree/0.8.1"
|
||||
"source": "https://github.com/utopia-php/migration/tree/0.6.20"
|
||||
},
|
||||
"time": "2025-03-18T07:48:08+00:00"
|
||||
"time": "2025-02-17T11:02:15+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/mongo",
|
||||
@@ -4325,16 +4370,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/platform",
|
||||
"version": "0.7.4",
|
||||
"version": "0.7.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/platform.git",
|
||||
"reference": "a5b93d8177702ec458c3af9137663133c012b71b"
|
||||
"reference": "463c2d817c893d7dbb678c2eac7a8291f2710e25"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/platform/zipball/a5b93d8177702ec458c3af9137663133c012b71b",
|
||||
"reference": "a5b93d8177702ec458c3af9137663133c012b71b",
|
||||
"url": "https://api.github.com/repos/utopia-php/platform/zipball/463c2d817c893d7dbb678c2eac7a8291f2710e25",
|
||||
"reference": "463c2d817c893d7dbb678c2eac7a8291f2710e25",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4343,7 +4388,7 @@
|
||||
"php": ">=8.0",
|
||||
"utopia-php/cli": "0.15.*",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
"utopia-php/queue": "0.9.*"
|
||||
"utopia-php/queue": "0.8.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.2.*",
|
||||
@@ -4369,32 +4414,31 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/platform/issues",
|
||||
"source": "https://github.com/utopia-php/platform/tree/0.7.4"
|
||||
"source": "https://github.com/utopia-php/platform/tree/0.7.3"
|
||||
},
|
||||
"time": "2025-03-13T13:00:12+00:00"
|
||||
"time": "2025-02-04T15:09:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/pools",
|
||||
"version": "0.7.0",
|
||||
"version": "0.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/pools.git",
|
||||
"reference": "ad64d45afda08ec8b29e2642a8d18075964d40bf"
|
||||
"reference": "6f716a213a08db95eda1b5dddfa90983c1834817"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/pools/zipball/ad64d45afda08ec8b29e2642a8d18075964d40bf",
|
||||
"reference": "ad64d45afda08ec8b29e2642a8d18075964d40bf",
|
||||
"url": "https://api.github.com/repos/utopia-php/pools/zipball/6f716a213a08db95eda1b5dddfa90983c1834817",
|
||||
"reference": "6f716a213a08db95eda1b5dddfa90983c1834817",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.3",
|
||||
"utopia-php/telemetry": "0.1.*"
|
||||
"php": ">=8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.*",
|
||||
"phpstan/phpstan": "1.*",
|
||||
"phpunit/phpunit": "11.*"
|
||||
"laravel/pint": "1.2.*",
|
||||
"phpstan/phpstan": "1.8.*",
|
||||
"phpunit/phpunit": "^9.3"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -4421,9 +4465,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/pools/issues",
|
||||
"source": "https://github.com/utopia-php/pools/tree/0.7.0"
|
||||
"source": "https://github.com/utopia-php/pools/tree/0.5.0"
|
||||
},
|
||||
"time": "2025-03-18T03:55:33+00:00"
|
||||
"time": "2024-04-19T11:11:54+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/preloader",
|
||||
@@ -4480,16 +4524,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/queue",
|
||||
"version": "0.9.0",
|
||||
"version": "0.8.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/queue.git",
|
||||
"reference": "077075f1d57afa430f76c35ed3bf4616e0eee8e7"
|
||||
"reference": "b713b997285c29d120bbcbe3d6e93762d850f87c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/queue/zipball/077075f1d57afa430f76c35ed3bf4616e0eee8e7",
|
||||
"reference": "077075f1d57afa430f76c35ed3bf4616e0eee8e7",
|
||||
"url": "https://api.github.com/repos/utopia-php/queue/zipball/b713b997285c29d120bbcbe3d6e93762d850f87c",
|
||||
"reference": "b713b997285c29d120bbcbe3d6e93762d850f87c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4539,9 +4583,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/queue/issues",
|
||||
"source": "https://github.com/utopia-php/queue/tree/0.9.0"
|
||||
"source": "https://github.com/utopia-php/queue/tree/0.8.6"
|
||||
},
|
||||
"time": "2025-03-13T12:22:41+00:00"
|
||||
"time": "2025-02-10T03:35:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/registry",
|
||||
@@ -4761,16 +4805,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/telemetry",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/telemetry.git",
|
||||
"reference": "437f0021777f0e575dfb9e8a1a081b3aed75e33f"
|
||||
"reference": "d35f2f0632f4ee0be63fb7ace6a94a6adda71a80"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/telemetry/zipball/437f0021777f0e575dfb9e8a1a081b3aed75e33f",
|
||||
"reference": "437f0021777f0e575dfb9e8a1a081b3aed75e33f",
|
||||
"url": "https://api.github.com/repos/utopia-php/telemetry/zipball/d35f2f0632f4ee0be63fb7ace6a94a6adda71a80",
|
||||
"reference": "d35f2f0632f4ee0be63fb7ace6a94a6adda71a80",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4791,7 +4835,7 @@
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Utopia\\Telemetry\\": "src/Telemetry"
|
||||
"Utopia\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
@@ -4805,22 +4849,22 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/telemetry/issues",
|
||||
"source": "https://github.com/utopia-php/telemetry/tree/0.1.1"
|
||||
"source": "https://github.com/utopia-php/telemetry/tree/0.1.0"
|
||||
},
|
||||
"time": "2025-03-17T11:57:52+00:00"
|
||||
"time": "2024-11-13T10:29:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/vcs",
|
||||
"version": "0.9.4",
|
||||
"version": "0.9.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/vcs.git",
|
||||
"reference": "1a8d280b176acc99ea8d9e7364b8767cbb206b4a"
|
||||
"reference": "865a00c67e81a20938b883f9aa802303790dd3b5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/vcs/zipball/1a8d280b176acc99ea8d9e7364b8767cbb206b4a",
|
||||
"reference": "1a8d280b176acc99ea8d9e7364b8767cbb206b4a",
|
||||
"url": "https://api.github.com/repos/utopia-php/vcs/zipball/865a00c67e81a20938b883f9aa802303790dd3b5",
|
||||
"reference": "865a00c67e81a20938b883f9aa802303790dd3b5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4855,9 +4899,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/vcs/issues",
|
||||
"source": "https://github.com/utopia-php/vcs/tree/0.9.4"
|
||||
"source": "https://github.com/utopia-php/vcs/tree/0.9.3"
|
||||
},
|
||||
"time": "2025-03-13T10:09:45+00:00"
|
||||
"time": "2025-02-26T16:33:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/websocket",
|
||||
@@ -5044,16 +5088,16 @@
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "appwrite/sdk-generator",
|
||||
"version": "0.40.9",
|
||||
"version": "0.40.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/sdk-generator.git",
|
||||
"reference": "dbb45a5db22cdc3368fe2573c07ba6088f188fa4"
|
||||
"reference": "9e89b0bc4d8e6c81817d27096629f34a149fa873"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/dbb45a5db22cdc3368fe2573c07ba6088f188fa4",
|
||||
"reference": "dbb45a5db22cdc3368fe2573c07ba6088f188fa4",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/9e89b0bc4d8e6c81817d27096629f34a149fa873",
|
||||
"reference": "9e89b0bc4d8e6c81817d27096629f34a149fa873",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5089,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.9"
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/0.40.7"
|
||||
},
|
||||
"time": "2025-03-17T18:39:14+00:00"
|
||||
"time": "2025-03-12T08:43:55+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
@@ -5318,16 +5362,16 @@
|
||||
},
|
||||
{
|
||||
"name": "laravel/pint",
|
||||
"version": "v1.21.2",
|
||||
"version": "v1.21.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/pint.git",
|
||||
"reference": "370772e7d9e9da087678a0edf2b11b6960e40558"
|
||||
"reference": "c44bffbb2334e90fba560933c45948fa4a3f3e86"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/pint/zipball/370772e7d9e9da087678a0edf2b11b6960e40558",
|
||||
"reference": "370772e7d9e9da087678a0edf2b11b6960e40558",
|
||||
"url": "https://api.github.com/repos/laravel/pint/zipball/c44bffbb2334e90fba560933c45948fa4a3f3e86",
|
||||
"reference": "c44bffbb2334e90fba560933c45948fa4a3f3e86",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5338,9 +5382,9 @@
|
||||
"php": "^8.2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.72.0",
|
||||
"illuminate/view": "^11.44.2",
|
||||
"larastan/larastan": "^3.2.0",
|
||||
"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",
|
||||
@@ -5380,7 +5424,7 @@
|
||||
"issues": "https://github.com/laravel/pint/issues",
|
||||
"source": "https://github.com/laravel/pint"
|
||||
},
|
||||
"time": "2025-03-14T22:31:42+00:00"
|
||||
"time": "2025-03-11T03:22:21+00:00"
|
||||
},
|
||||
{
|
||||
"name": "matthiasmullie/minify",
|
||||
@@ -5891,6 +5935,65 @@
|
||||
],
|
||||
"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",
|
||||
"version": "9.2.32",
|
||||
@@ -8427,5 +8530,5 @@
|
||||
"platform-overrides": {
|
||||
"php": "8.3"
|
||||
},
|
||||
"plugin-api-version": "2.6.0"
|
||||
"plugin-api-version": "2.3.0"
|
||||
}
|
||||
|
||||
@@ -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.53
|
||||
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 @@
|
||||
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 +0,0 @@
|
||||
Create a new proxy rule.
|
||||
@@ -59,7 +59,7 @@ My Awesome Function
|
||||
You can now deploy this function using
|
||||
|
||||
```sh
|
||||
$ appwrite push function
|
||||
$ appwrite deploy function
|
||||
|
||||
? Which functions would you like to deploy? My Awesome Function (61d1a4c81dfcd95bc834)
|
||||
ℹ Info Deploying function My Awesome Function ( 61d1a4c81dfcd95bc834 )
|
||||
@@ -73,7 +73,7 @@ Your function has now been deployed on your Appwrite server! As soon as the buil
|
||||
Similarly, you can deploy all your collections to your Appwrite server using
|
||||
|
||||
```sh
|
||||
appwrite push collections
|
||||
appwrite deploy collections
|
||||
```
|
||||
|
||||
> ### Note
|
||||
@@ -98,7 +98,7 @@ $ appwrite users list
|
||||
|
||||
To create a document you can use the following command
|
||||
```sh
|
||||
$ appwrite databases create-document --database-id <DATABASE_ID> --collection-id <COLLECTION_ID> --document-id "unique()" --data '{"name": "Walter O Brein"}' --permissions 'read("any")' 'read("team:abc")'
|
||||
$ appwrite database createDocument --collectionId <ID> --documentId 'unique()' --data '{ "Name": "Iron Man" }' --permissions 'read("any")' 'read("team:abc")'
|
||||
```
|
||||
|
||||
### Some Gotchas
|
||||
@@ -140,4 +140,4 @@ The Appwrite CLI can also work in a CI environment. The initialisation of the CL
|
||||
|
||||
```sh
|
||||
appwrite client --endpoint http://localhost/v1 --projectId <PROJECT_ID> --key <API KEY>
|
||||
```
|
||||
```
|
||||
@@ -1,15 +1,3 @@
|
||||
## 14.0.0
|
||||
|
||||
* Breaking changes:
|
||||
* Changed the typing of `AppwriteException`'s response parameter from a `dynamic` object to an optional string (`?String`).
|
||||
|
||||
## 13.0.0
|
||||
|
||||
* Fixed realtime pong response.
|
||||
* Fixed issues with `chunkedUpload` method.
|
||||
* Fixed type mismatch bug where `List<dynamic>` was incorrectly causing runtime type errors.
|
||||
* Updated return type of `updateMfaChallenge()` from raw data to properly typed `models.Session` object.
|
||||
|
||||
## 12.0.0
|
||||
|
||||
* Support for Appwrite 1.6
|
||||
|
||||
@@ -1,13 +1,3 @@
|
||||
## 15.0.0
|
||||
|
||||
* Breaking changes:
|
||||
* Changed the typing of `AppwriteException`'s response parameter from a `dynamic` object to an optional string (`?String`).
|
||||
|
||||
## 14.0.0
|
||||
|
||||
* Fixed realtime pong response.
|
||||
* Fixed issues with `chunkedUpload` method.
|
||||
|
||||
## 13.0.0
|
||||
|
||||
* Fixed realtime reconnection issues
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
parameters:
|
||||
level: 8
|
||||
paths:
|
||||
- src/Appwrite/Transformation
|
||||
scanDirectories:
|
||||
- vendor/swoole/ide-helper
|
||||
excludePaths:
|
||||
- tests/resources
|
||||
|
After Width: | Height: | Size: 124 KiB |
|
After Width: | Height: | Size: 124 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 306 KiB |
|
After Width: | Height: | Size: 306 KiB |
|
After Width: | Height: | Size: 104 KiB |
|
After Width: | Height: | Size: 104 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 62 KiB |