Merge branch 'main' of github.com:appwrite/appwrite-console-poc into functions

This commit is contained in:
Arman
2022-10-17 15:26:05 +02:00
42 changed files with 1411 additions and 339 deletions
+174 -172
View File
@@ -9,42 +9,42 @@
"version": "0.0.1",
"dependencies": {
"@aw-labs/appwrite-console": "^6.0.0",
"@aw-labs/icons": "0.0.0-61",
"@aw-labs/ui": "0.0.0-61",
"@aw-labs/icons": "0.0.0-63",
"@aw-labs/ui": "0.0.0-63",
"echarts": "^5.4.0",
"prismjs": "^1.29.0",
"tippy.js": "^6.3.7",
"web-vitals": "^2.1.4"
"web-vitals": "^3.0.3"
},
"devDependencies": {
"@playwright/test": "^1.26.1",
"@playwright/test": "^1.27.1",
"@sveltejs/adapter-static": "1.0.0-next.44",
"@sveltejs/kit": "1.0.0-next.512",
"@sveltejs/vite-plugin-svelte": "^1.0.8",
"@testing-library/dom": "^8.18.1",
"@sveltejs/kit": "1.0.0-next.516",
"@sveltejs/vite-plugin-svelte": "^1.0.9",
"@testing-library/dom": "^8.19.0",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/svelte": "3.1.3",
"@testing-library/user-event": "^14.4.3",
"@types/gtag.js": "^0.0.12",
"@types/prismjs": "^1.26.0",
"@typescript-eslint/eslint-plugin": "^5.39.0",
"@typescript-eslint/parser": "^5.39.0",
"@vitest/ui": "^0.23.4",
"eslint": "^8.24.0",
"@typescript-eslint/eslint-plugin": "^5.40.0",
"@typescript-eslint/parser": "^5.40.0",
"@vitest/ui": "^0.24.3",
"eslint": "^8.25.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-svelte3": "^4.0.0",
"pre-commit": "^1.2.2",
"prettier": "^2.7.1",
"prettier-plugin-svelte": "^2.7.1",
"prettier-plugin-svelte": "^2.8.0",
"sass": "^1.55.0",
"svelte": "^3.50.1",
"svelte-check": "^2.9.1",
"svelte": "^3.52.0",
"svelte-check": "^2.9.2",
"svelte-jester": "^2.3.2",
"svelte-preprocess": "^4.10.7",
"tslib": "^2.4.0",
"typescript": "^4.8.4",
"vite": "^3.1.4",
"vitest": "^0.23.4"
"vite": "^3.1.8",
"vitest": "^0.24.3"
},
"engines": {
"node": ">=16"
@@ -79,14 +79,14 @@
}
},
"node_modules/@aw-labs/icons": {
"version": "0.0.0-61",
"resolved": "https://registry.npmjs.org/@aw-labs/icons/-/icons-0.0.0-61.tgz",
"integrity": "sha512-kZdiDF+ywVvcoC8R+lZNnxwuxNeCmMNwyoqoFL+VANNeRL6pfABYDUwTRG4cZmY4n/oswe5FeILjl/HlSSf5/w=="
"version": "0.0.0-63",
"resolved": "https://registry.npmjs.org/@aw-labs/icons/-/icons-0.0.0-63.tgz",
"integrity": "sha512-aSVriQp0x2cfyhld3LodKrDBZwkS/rOErjvQtR5HWmrYTjDNm21dmehfg6rVhV5Al8Bvpd82HihAWdTVYP5cwA=="
},
"node_modules/@aw-labs/ui": {
"version": "0.0.0-61",
"resolved": "https://registry.npmjs.org/@aw-labs/ui/-/ui-0.0.0-61.tgz",
"integrity": "sha512-v0+4CWP7x7cNo0sqZlZOeqp3RK45fS+LMg/lVEpyByaluMqXDIPe7p522vp0hgsN2YKtpilbxg0vlqLCIvEa8w==",
"version": "0.0.0-63",
"resolved": "https://registry.npmjs.org/@aw-labs/ui/-/ui-0.0.0-63.tgz",
"integrity": "sha512-+lNFpbMBT/AU2sVefN6gmBJE06Z1L93iqpr6B4Xl8T5YxDwrAeoxjTB5I50vVhughN/JkYxTJd+rMOCSOfh/DQ==",
"dependencies": {
"@aw-labs/icons": "*",
"normalize.css": "^8.0.1",
@@ -1268,13 +1268,13 @@
}
},
"node_modules/@playwright/test": {
"version": "1.26.1",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.26.1.tgz",
"integrity": "sha512-bNxyZASVt2adSZ9gbD7NCydzcb5JaI0OR9hc7s+nmPeH604gwp0zp17NNpwXY4c8nvuBGQQ9oGDx72LE+cUWvw==",
"version": "1.27.1",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.27.1.tgz",
"integrity": "sha512-mrL2q0an/7tVqniQQF6RBL2saskjljXzqNcCOVMUjRIgE6Y38nCNaP+Dc2FBW06bcpD3tqIws/HT9qiMHbNU0A==",
"dev": true,
"dependencies": {
"@types/node": "*",
"playwright-core": "1.26.1"
"playwright-core": "1.27.1"
},
"bin": {
"playwright": "cli.js"
@@ -1344,9 +1344,9 @@
"dev": true
},
"node_modules/@sveltejs/kit": {
"version": "1.0.0-next.512",
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.0.0-next.512.tgz",
"integrity": "sha512-/KywzSMXdNxYGujJfdlAbLgV9m0TSSKqC8XluZ46M6oPAM1fUsjfBBtukU/Vx3hP7ldR8d/vpKX3amENAMw50g==",
"version": "1.0.0-next.516",
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.0.0-next.516.tgz",
"integrity": "sha512-n0oGcv7xpgJ81ld1oER5HVREP4TdeDUJ8S64XNDcl3Y2xfQLKk8C4SLYQw2D6V+DxUm8V3aRrj7N7/tm4CQm6A==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
@@ -1426,9 +1426,9 @@
}
},
"node_modules/@testing-library/dom": {
"version": "8.18.1",
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.18.1.tgz",
"integrity": "sha512-oEvsm2B/WtcHKE+IcEeeCqNU/ltFGaVyGbpcm4g/2ytuT49jrlH9x5qRKL/H3A6yfM4YAbSbC0ceT5+9CEXnLg==",
"version": "8.19.0",
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.0.tgz",
"integrity": "sha512-6YWYPPpxG3e/xOo6HIWwB/58HukkwIVTOaZ0VwdMVjhRUX/01E4FtQbck9GazOOj7MXHc5RBzMrU86iBJHbI+A==",
"dev": true,
"dependencies": {
"@babel/code-frame": "^7.10.4",
@@ -1750,14 +1750,14 @@
"peer": true
},
"node_modules/@typescript-eslint/eslint-plugin": {
"version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.39.0.tgz",
"integrity": "sha512-xVfKOkBm5iWMNGKQ2fwX5GVgBuHmZBO1tCRwXmY5oAIsPscfwm2UADDuNB8ZVYCtpQvJK4xpjrK7jEhcJ0zY9A==",
"version": "5.40.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.40.0.tgz",
"integrity": "sha512-FIBZgS3DVJgqPwJzvZTuH4HNsZhHMa9SjxTKAZTlMsPw/UzpEjcf9f4dfgDJEHjK+HboUJo123Eshl6niwEm/Q==",
"dev": true,
"dependencies": {
"@typescript-eslint/scope-manager": "5.39.0",
"@typescript-eslint/type-utils": "5.39.0",
"@typescript-eslint/utils": "5.39.0",
"@typescript-eslint/scope-manager": "5.40.0",
"@typescript-eslint/type-utils": "5.40.0",
"@typescript-eslint/utils": "5.40.0",
"debug": "^4.3.4",
"ignore": "^5.2.0",
"regexpp": "^3.2.0",
@@ -1782,14 +1782,14 @@
}
},
"node_modules/@typescript-eslint/parser": {
"version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.39.0.tgz",
"integrity": "sha512-PhxLjrZnHShe431sBAGHaNe6BDdxAASDySgsBCGxcBecVCi8NQWxQZMcizNA4g0pN51bBAn/FUfkWG3SDVcGlA==",
"version": "5.40.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.40.0.tgz",
"integrity": "sha512-Ah5gqyX2ySkiuYeOIDg7ap51/b63QgWZA7w6AHtFrag7aH0lRQPbLzUjk0c9o5/KZ6JRkTTDKShL4AUrQa6/hw==",
"dev": true,
"dependencies": {
"@typescript-eslint/scope-manager": "5.39.0",
"@typescript-eslint/types": "5.39.0",
"@typescript-eslint/typescript-estree": "5.39.0",
"@typescript-eslint/scope-manager": "5.40.0",
"@typescript-eslint/types": "5.40.0",
"@typescript-eslint/typescript-estree": "5.40.0",
"debug": "^4.3.4"
},
"engines": {
@@ -1809,13 +1809,13 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.39.0.tgz",
"integrity": "sha512-/I13vAqmG3dyqMVSZPjsbuNQlYS082Y7OMkwhCfLXYsmlI0ca4nkL7wJ/4gjX70LD4P8Hnw1JywUVVAwepURBw==",
"version": "5.40.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.40.0.tgz",
"integrity": "sha512-d3nPmjUeZtEWRvyReMI4I1MwPGC63E8pDoHy0BnrYjnJgilBD3hv7XOiETKLY/zTwI7kCnBDf2vWTRUVpYw0Uw==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.39.0",
"@typescript-eslint/visitor-keys": "5.39.0"
"@typescript-eslint/types": "5.40.0",
"@typescript-eslint/visitor-keys": "5.40.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -1826,13 +1826,13 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
"version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.39.0.tgz",
"integrity": "sha512-KJHJkOothljQWzR3t/GunL0TPKY+fGJtnpl+pX+sJ0YiKTz3q2Zr87SGTmFqsCMFrLt5E0+o+S6eQY0FAXj9uA==",
"version": "5.40.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.40.0.tgz",
"integrity": "sha512-nfuSdKEZY2TpnPz5covjJqav+g5qeBqwSHKBvz7Vm1SAfy93SwKk/JeSTymruDGItTwNijSsno5LhOHRS1pcfw==",
"dev": true,
"dependencies": {
"@typescript-eslint/typescript-estree": "5.39.0",
"@typescript-eslint/utils": "5.39.0",
"@typescript-eslint/typescript-estree": "5.40.0",
"@typescript-eslint/utils": "5.40.0",
"debug": "^4.3.4",
"tsutils": "^3.21.0"
},
@@ -1853,9 +1853,9 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.39.0.tgz",
"integrity": "sha512-gQMZrnfEBFXK38hYqt8Lkwt8f4U6yq+2H5VDSgP/qiTzC8Nw8JO3OuSUOQ2qW37S/dlwdkHDntkZM6SQhKyPhw==",
"version": "5.40.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.40.0.tgz",
"integrity": "sha512-V1KdQRTXsYpf1Y1fXCeZ+uhjW48Niiw0VGt4V8yzuaDTU8Z1Xl7yQDyQNqyAFcVhpYXIVCEuxSIWTsLDpHgTbw==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -1866,13 +1866,13 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.39.0.tgz",
"integrity": "sha512-qLFQP0f398sdnogJoLtd43pUgB18Q50QSA+BTE5h3sUxySzbWDpTSdgt4UyxNSozY/oDK2ta6HVAzvGgq8JYnA==",
"version": "5.40.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.40.0.tgz",
"integrity": "sha512-b0GYlDj8TLTOqwX7EGbw2gL5EXS2CPEWhF9nGJiGmEcmlpNBjyHsTwbqpyIEPVpl6br4UcBOYlcI2FJVtJkYhg==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.39.0",
"@typescript-eslint/visitor-keys": "5.39.0",
"@typescript-eslint/types": "5.40.0",
"@typescript-eslint/visitor-keys": "5.40.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -1893,17 +1893,18 @@
}
},
"node_modules/@typescript-eslint/utils": {
"version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.39.0.tgz",
"integrity": "sha512-+DnY5jkpOpgj+EBtYPyHRjXampJfC0yUZZzfzLuUWVZvCuKqSdJVC8UhdWipIw7VKNTfwfAPiOWzYkAwuIhiAg==",
"version": "5.40.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.40.0.tgz",
"integrity": "sha512-MO0y3T5BQ5+tkkuYZJBjePewsY+cQnfkYeRqS6tPh28niiIwPnQ1t59CSRcs1ZwJJNOdWw7rv9pF8aP58IMihA==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.39.0",
"@typescript-eslint/types": "5.39.0",
"@typescript-eslint/typescript-estree": "5.39.0",
"@typescript-eslint/scope-manager": "5.40.0",
"@typescript-eslint/types": "5.40.0",
"@typescript-eslint/typescript-estree": "5.40.0",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0"
"eslint-utils": "^3.0.0",
"semver": "^7.3.7"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -1917,12 +1918,12 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.39.0.tgz",
"integrity": "sha512-yyE3RPwOG+XJBLrhvsxAidUgybJVQ/hG8BhiJo0k8JSAYfk/CshVcxf0HwP4Jt7WZZ6vLmxdo1p6EyN3tzFTkg==",
"version": "5.40.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.40.0.tgz",
"integrity": "sha512-ijJ+6yig+x9XplEpG2K6FUdJeQGGj/15U3S56W9IqXKJqleuD7zJ2AX/miLezwxpd7ZxDAqO87zWufKg+RPZyQ==",
"dev": true,
"dependencies": {
"@typescript-eslint/types": "5.39.0",
"@typescript-eslint/types": "5.40.0",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
@@ -1934,9 +1935,9 @@
}
},
"node_modules/@vitest/ui": {
"version": "0.23.4",
"resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-0.23.4.tgz",
"integrity": "sha512-lNZVTTrkHThGAwNQ1ah1qCNnm70r7OLB5LCUdSqboStve/1eKTrtt27QfDSSUTG8AVJQzU0eaN/j8UocH+CqfA==",
"version": "0.24.3",
"resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-0.24.3.tgz",
"integrity": "sha512-f5agYA/sdkiipq42TZayJoeUGjWx+opDjIVeNnb1SG2BNxqObFqh6GuJlzpGHerg4a2+ZSoVo4f4p2+dEyXPmg==",
"dev": true,
"dependencies": {
"sirv": "^2.0.2"
@@ -6138,9 +6139,9 @@
}
},
"node_modules/playwright-core": {
"version": "1.26.1",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.26.1.tgz",
"integrity": "sha512-hzFchhhxnEiPc4qVPs9q2ZR+5eKNifY2hQDHtg1HnTTUuphYCBP8ZRb2si+B1TR7BHirgXaPi48LIye5SgrLAA==",
"version": "1.27.1",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.27.1.tgz",
"integrity": "sha512-9EmeXDncC2Pmp/z+teoVYlvmPWUC6ejSSYZUln7YaP89Z6lpAaiaAnqroUt/BoLo8tn7WYShcfaCh+xofZa44Q==",
"dev": true,
"bin": {
"playwright": "cli.js"
@@ -6988,9 +6989,9 @@
}
},
"node_modules/svelte": {
"version": "3.50.1",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.50.1.tgz",
"integrity": "sha512-bS4odcsdj5D5jEg6riZuMg5NKelzPtmsCbD9RG+8umU03TeNkdWnP6pqbCm0s8UQNBkqk29w/Bdubn3C+HWSwA==",
"version": "3.52.0",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.52.0.tgz",
"integrity": "sha512-FxcnEUOAVfr10vDU5dVgJN19IvqeHQCS1zfe8vayTfis9A2t5Fhx+JDe5uv/C3j//bB1umpLJ6quhgs9xyUbCQ==",
"dev": true,
"engines": {
"node": ">= 8"
@@ -7403,9 +7404,9 @@
}
},
"node_modules/vite": {
"version": "3.1.7",
"resolved": "https://registry.npmjs.org/vite/-/vite-3.1.7.tgz",
"integrity": "sha512-5vCAmU4S8lyVdFCInu9M54f/g8qbOMakVw5xJ4pjoaDy5wgy9sLLZkGdSLN52dlsBqh0tBqxjaqqa8LgPqwRAA==",
"version": "3.1.8",
"resolved": "https://registry.npmjs.org/vite/-/vite-3.1.8.tgz",
"integrity": "sha512-m7jJe3nufUbuOfotkntGFupinL/fmuTNuQmiVE7cH2IZMuf4UbfbGYMUT3jVWgGYuRVLY9j8NnrRqgw5rr5QTg==",
"dev": true,
"dependencies": {
"esbuild": "^0.15.9",
@@ -7444,9 +7445,9 @@
}
},
"node_modules/vitest": {
"version": "0.23.4",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-0.23.4.tgz",
"integrity": "sha512-iukBNWqQAv8EKDBUNntspLp9SfpaVFbmzmM0sNcnTxASQZMzRw3PsM6DMlsHiI+I6GeO5/sYDg3ecpC+SNFLrQ==",
"version": "0.24.3",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-0.24.3.tgz",
"integrity": "sha512-aM0auuPPgMSstWvr851hB74g/LKaKBzSxcG3da7ejfZbx08Y21JpZmbmDYrMTCGhVZKqTGwzcnLMwyfz2WzkhQ==",
"dev": true,
"dependencies": {
"@types/chai": "^4.3.3",
@@ -7455,11 +7456,11 @@
"chai": "^4.3.6",
"debug": "^4.3.4",
"local-pkg": "^0.4.2",
"strip-literal": "^0.4.1",
"tinybench": "^2.1.5",
"strip-literal": "^0.4.2",
"tinybench": "^2.3.0",
"tinypool": "^0.3.0",
"tinyspy": "^1.0.2",
"vite": "^2.9.12 || ^3.0.0-0"
"vite": "^3.0.0"
},
"bin": {
"vitest": "vitest.mjs"
@@ -7531,9 +7532,9 @@
}
},
"node_modules/web-vitals": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz",
"integrity": "sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg=="
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.0.3.tgz",
"integrity": "sha512-8K6cl3alkVhwv7RQm3WAWFzvP9dBTH4CwOE7G3DfQDEnBJTdtNgX5XMqgE7aE79wac/kJ8fHWftUfH3AVxxbBw=="
},
"node_modules/webidl-conversions": {
"version": "7.0.0",
@@ -7788,14 +7789,14 @@
}
},
"@aw-labs/icons": {
"version": "0.0.0-61",
"resolved": "https://registry.npmjs.org/@aw-labs/icons/-/icons-0.0.0-61.tgz",
"integrity": "sha512-kZdiDF+ywVvcoC8R+lZNnxwuxNeCmMNwyoqoFL+VANNeRL6pfABYDUwTRG4cZmY4n/oswe5FeILjl/HlSSf5/w=="
"version": "0.0.0-63",
"resolved": "https://registry.npmjs.org/@aw-labs/icons/-/icons-0.0.0-63.tgz",
"integrity": "sha512-aSVriQp0x2cfyhld3LodKrDBZwkS/rOErjvQtR5HWmrYTjDNm21dmehfg6rVhV5Al8Bvpd82HihAWdTVYP5cwA=="
},
"@aw-labs/ui": {
"version": "0.0.0-61",
"resolved": "https://registry.npmjs.org/@aw-labs/ui/-/ui-0.0.0-61.tgz",
"integrity": "sha512-v0+4CWP7x7cNo0sqZlZOeqp3RK45fS+LMg/lVEpyByaluMqXDIPe7p522vp0hgsN2YKtpilbxg0vlqLCIvEa8w==",
"version": "0.0.0-63",
"resolved": "https://registry.npmjs.org/@aw-labs/ui/-/ui-0.0.0-63.tgz",
"integrity": "sha512-+lNFpbMBT/AU2sVefN6gmBJE06Z1L93iqpr6B4Xl8T5YxDwrAeoxjTB5I50vVhughN/JkYxTJd+rMOCSOfh/DQ==",
"requires": {
"@aw-labs/icons": "*",
"normalize.css": "^8.0.1",
@@ -8714,13 +8715,13 @@
}
},
"@playwright/test": {
"version": "1.26.1",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.26.1.tgz",
"integrity": "sha512-bNxyZASVt2adSZ9gbD7NCydzcb5JaI0OR9hc7s+nmPeH604gwp0zp17NNpwXY4c8nvuBGQQ9oGDx72LE+cUWvw==",
"version": "1.27.1",
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.27.1.tgz",
"integrity": "sha512-mrL2q0an/7tVqniQQF6RBL2saskjljXzqNcCOVMUjRIgE6Y38nCNaP+Dc2FBW06bcpD3tqIws/HT9qiMHbNU0A==",
"dev": true,
"requires": {
"@types/node": "*",
"playwright-core": "1.26.1"
"playwright-core": "1.27.1"
}
},
"@polka/url": {
@@ -8777,9 +8778,9 @@
"dev": true
},
"@sveltejs/kit": {
"version": "1.0.0-next.512",
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.0.0-next.512.tgz",
"integrity": "sha512-/KywzSMXdNxYGujJfdlAbLgV9m0TSSKqC8XluZ46M6oPAM1fUsjfBBtukU/Vx3hP7ldR8d/vpKX3amENAMw50g==",
"version": "1.0.0-next.516",
"resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-1.0.0-next.516.tgz",
"integrity": "sha512-n0oGcv7xpgJ81ld1oER5HVREP4TdeDUJ8S64XNDcl3Y2xfQLKk8C4SLYQw2D6V+DxUm8V3aRrj7N7/tm4CQm6A==",
"dev": true,
"requires": {
"@sveltejs/vite-plugin-svelte": "^1.0.5",
@@ -8833,9 +8834,9 @@
}
},
"@testing-library/dom": {
"version": "8.18.1",
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.18.1.tgz",
"integrity": "sha512-oEvsm2B/WtcHKE+IcEeeCqNU/ltFGaVyGbpcm4g/2ytuT49jrlH9x5qRKL/H3A6yfM4YAbSbC0ceT5+9CEXnLg==",
"version": "8.19.0",
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.0.tgz",
"integrity": "sha512-6YWYPPpxG3e/xOo6HIWwB/58HukkwIVTOaZ0VwdMVjhRUX/01E4FtQbck9GazOOj7MXHc5RBzMrU86iBJHbI+A==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.10.4",
@@ -9126,14 +9127,14 @@
"peer": true
},
"@typescript-eslint/eslint-plugin": {
"version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.39.0.tgz",
"integrity": "sha512-xVfKOkBm5iWMNGKQ2fwX5GVgBuHmZBO1tCRwXmY5oAIsPscfwm2UADDuNB8ZVYCtpQvJK4xpjrK7jEhcJ0zY9A==",
"version": "5.40.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.40.0.tgz",
"integrity": "sha512-FIBZgS3DVJgqPwJzvZTuH4HNsZhHMa9SjxTKAZTlMsPw/UzpEjcf9f4dfgDJEHjK+HboUJo123Eshl6niwEm/Q==",
"dev": true,
"requires": {
"@typescript-eslint/scope-manager": "5.39.0",
"@typescript-eslint/type-utils": "5.39.0",
"@typescript-eslint/utils": "5.39.0",
"@typescript-eslint/scope-manager": "5.40.0",
"@typescript-eslint/type-utils": "5.40.0",
"@typescript-eslint/utils": "5.40.0",
"debug": "^4.3.4",
"ignore": "^5.2.0",
"regexpp": "^3.2.0",
@@ -9142,53 +9143,53 @@
}
},
"@typescript-eslint/parser": {
"version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.39.0.tgz",
"integrity": "sha512-PhxLjrZnHShe431sBAGHaNe6BDdxAASDySgsBCGxcBecVCi8NQWxQZMcizNA4g0pN51bBAn/FUfkWG3SDVcGlA==",
"version": "5.40.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.40.0.tgz",
"integrity": "sha512-Ah5gqyX2ySkiuYeOIDg7ap51/b63QgWZA7w6AHtFrag7aH0lRQPbLzUjk0c9o5/KZ6JRkTTDKShL4AUrQa6/hw==",
"dev": true,
"requires": {
"@typescript-eslint/scope-manager": "5.39.0",
"@typescript-eslint/types": "5.39.0",
"@typescript-eslint/typescript-estree": "5.39.0",
"@typescript-eslint/scope-manager": "5.40.0",
"@typescript-eslint/types": "5.40.0",
"@typescript-eslint/typescript-estree": "5.40.0",
"debug": "^4.3.4"
}
},
"@typescript-eslint/scope-manager": {
"version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.39.0.tgz",
"integrity": "sha512-/I13vAqmG3dyqMVSZPjsbuNQlYS082Y7OMkwhCfLXYsmlI0ca4nkL7wJ/4gjX70LD4P8Hnw1JywUVVAwepURBw==",
"version": "5.40.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.40.0.tgz",
"integrity": "sha512-d3nPmjUeZtEWRvyReMI4I1MwPGC63E8pDoHy0BnrYjnJgilBD3hv7XOiETKLY/zTwI7kCnBDf2vWTRUVpYw0Uw==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.39.0",
"@typescript-eslint/visitor-keys": "5.39.0"
"@typescript-eslint/types": "5.40.0",
"@typescript-eslint/visitor-keys": "5.40.0"
}
},
"@typescript-eslint/type-utils": {
"version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.39.0.tgz",
"integrity": "sha512-KJHJkOothljQWzR3t/GunL0TPKY+fGJtnpl+pX+sJ0YiKTz3q2Zr87SGTmFqsCMFrLt5E0+o+S6eQY0FAXj9uA==",
"version": "5.40.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.40.0.tgz",
"integrity": "sha512-nfuSdKEZY2TpnPz5covjJqav+g5qeBqwSHKBvz7Vm1SAfy93SwKk/JeSTymruDGItTwNijSsno5LhOHRS1pcfw==",
"dev": true,
"requires": {
"@typescript-eslint/typescript-estree": "5.39.0",
"@typescript-eslint/utils": "5.39.0",
"@typescript-eslint/typescript-estree": "5.40.0",
"@typescript-eslint/utils": "5.40.0",
"debug": "^4.3.4",
"tsutils": "^3.21.0"
}
},
"@typescript-eslint/types": {
"version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.39.0.tgz",
"integrity": "sha512-gQMZrnfEBFXK38hYqt8Lkwt8f4U6yq+2H5VDSgP/qiTzC8Nw8JO3OuSUOQ2qW37S/dlwdkHDntkZM6SQhKyPhw==",
"version": "5.40.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.40.0.tgz",
"integrity": "sha512-V1KdQRTXsYpf1Y1fXCeZ+uhjW48Niiw0VGt4V8yzuaDTU8Z1Xl7yQDyQNqyAFcVhpYXIVCEuxSIWTsLDpHgTbw==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
"version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.39.0.tgz",
"integrity": "sha512-qLFQP0f398sdnogJoLtd43pUgB18Q50QSA+BTE5h3sUxySzbWDpTSdgt4UyxNSozY/oDK2ta6HVAzvGgq8JYnA==",
"version": "5.40.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.40.0.tgz",
"integrity": "sha512-b0GYlDj8TLTOqwX7EGbw2gL5EXS2CPEWhF9nGJiGmEcmlpNBjyHsTwbqpyIEPVpl6br4UcBOYlcI2FJVtJkYhg==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.39.0",
"@typescript-eslint/visitor-keys": "5.39.0",
"@typescript-eslint/types": "5.40.0",
"@typescript-eslint/visitor-keys": "5.40.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -9197,33 +9198,34 @@
}
},
"@typescript-eslint/utils": {
"version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.39.0.tgz",
"integrity": "sha512-+DnY5jkpOpgj+EBtYPyHRjXampJfC0yUZZzfzLuUWVZvCuKqSdJVC8UhdWipIw7VKNTfwfAPiOWzYkAwuIhiAg==",
"version": "5.40.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.40.0.tgz",
"integrity": "sha512-MO0y3T5BQ5+tkkuYZJBjePewsY+cQnfkYeRqS6tPh28niiIwPnQ1t59CSRcs1ZwJJNOdWw7rv9pF8aP58IMihA==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.9",
"@typescript-eslint/scope-manager": "5.39.0",
"@typescript-eslint/types": "5.39.0",
"@typescript-eslint/typescript-estree": "5.39.0",
"@typescript-eslint/scope-manager": "5.40.0",
"@typescript-eslint/types": "5.40.0",
"@typescript-eslint/typescript-estree": "5.40.0",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0"
"eslint-utils": "^3.0.0",
"semver": "^7.3.7"
}
},
"@typescript-eslint/visitor-keys": {
"version": "5.39.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.39.0.tgz",
"integrity": "sha512-yyE3RPwOG+XJBLrhvsxAidUgybJVQ/hG8BhiJo0k8JSAYfk/CshVcxf0HwP4Jt7WZZ6vLmxdo1p6EyN3tzFTkg==",
"version": "5.40.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.40.0.tgz",
"integrity": "sha512-ijJ+6yig+x9XplEpG2K6FUdJeQGGj/15U3S56W9IqXKJqleuD7zJ2AX/miLezwxpd7ZxDAqO87zWufKg+RPZyQ==",
"dev": true,
"requires": {
"@typescript-eslint/types": "5.39.0",
"@typescript-eslint/types": "5.40.0",
"eslint-visitor-keys": "^3.3.0"
}
},
"@vitest/ui": {
"version": "0.23.4",
"resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-0.23.4.tgz",
"integrity": "sha512-lNZVTTrkHThGAwNQ1ah1qCNnm70r7OLB5LCUdSqboStve/1eKTrtt27QfDSSUTG8AVJQzU0eaN/j8UocH+CqfA==",
"version": "0.24.3",
"resolved": "https://registry.npmjs.org/@vitest/ui/-/ui-0.24.3.tgz",
"integrity": "sha512-f5agYA/sdkiipq42TZayJoeUGjWx+opDjIVeNnb1SG2BNxqObFqh6GuJlzpGHerg4a2+ZSoVo4f4p2+dEyXPmg==",
"dev": true,
"requires": {
"sirv": "^2.0.2"
@@ -12360,9 +12362,9 @@
}
},
"playwright-core": {
"version": "1.26.1",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.26.1.tgz",
"integrity": "sha512-hzFchhhxnEiPc4qVPs9q2ZR+5eKNifY2hQDHtg1HnTTUuphYCBP8ZRb2si+B1TR7BHirgXaPi48LIye5SgrLAA==",
"version": "1.27.1",
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.27.1.tgz",
"integrity": "sha512-9EmeXDncC2Pmp/z+teoVYlvmPWUC6ejSSYZUln7YaP89Z6lpAaiaAnqroUt/BoLo8tn7WYShcfaCh+xofZa44Q==",
"dev": true
},
"postcss": {
@@ -12989,9 +12991,9 @@
"dev": true
},
"svelte": {
"version": "3.50.1",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.50.1.tgz",
"integrity": "sha512-bS4odcsdj5D5jEg6riZuMg5NKelzPtmsCbD9RG+8umU03TeNkdWnP6pqbCm0s8UQNBkqk29w/Bdubn3C+HWSwA==",
"version": "3.52.0",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-3.52.0.tgz",
"integrity": "sha512-FxcnEUOAVfr10vDU5dVgJN19IvqeHQCS1zfe8vayTfis9A2t5Fhx+JDe5uv/C3j//bB1umpLJ6quhgs9xyUbCQ==",
"dev": true
},
"svelte-check": {
@@ -13270,9 +13272,9 @@
}
},
"vite": {
"version": "3.1.7",
"resolved": "https://registry.npmjs.org/vite/-/vite-3.1.7.tgz",
"integrity": "sha512-5vCAmU4S8lyVdFCInu9M54f/g8qbOMakVw5xJ4pjoaDy5wgy9sLLZkGdSLN52dlsBqh0tBqxjaqqa8LgPqwRAA==",
"version": "3.1.8",
"resolved": "https://registry.npmjs.org/vite/-/vite-3.1.8.tgz",
"integrity": "sha512-m7jJe3nufUbuOfotkntGFupinL/fmuTNuQmiVE7cH2IZMuf4UbfbGYMUT3jVWgGYuRVLY9j8NnrRqgw5rr5QTg==",
"dev": true,
"requires": {
"esbuild": "^0.15.9",
@@ -13283,9 +13285,9 @@
}
},
"vitest": {
"version": "0.23.4",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-0.23.4.tgz",
"integrity": "sha512-iukBNWqQAv8EKDBUNntspLp9SfpaVFbmzmM0sNcnTxASQZMzRw3PsM6DMlsHiI+I6GeO5/sYDg3ecpC+SNFLrQ==",
"version": "0.24.3",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-0.24.3.tgz",
"integrity": "sha512-aM0auuPPgMSstWvr851hB74g/LKaKBzSxcG3da7ejfZbx08Y21JpZmbmDYrMTCGhVZKqTGwzcnLMwyfz2WzkhQ==",
"dev": true,
"requires": {
"@types/chai": "^4.3.3",
@@ -13294,11 +13296,11 @@
"chai": "^4.3.6",
"debug": "^4.3.4",
"local-pkg": "^0.4.2",
"strip-literal": "^0.4.1",
"tinybench": "^2.1.5",
"strip-literal": "^0.4.2",
"tinybench": "^2.3.0",
"tinypool": "^0.3.0",
"tinyspy": "^1.0.2",
"vite": "^2.9.12 || ^3.0.0-0"
"vite": "^3.0.0"
}
},
"w3c-hr-time": {
@@ -13334,9 +13336,9 @@
}
},
"web-vitals": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-2.1.4.tgz",
"integrity": "sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg=="
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/web-vitals/-/web-vitals-3.0.3.tgz",
"integrity": "sha512-8K6cl3alkVhwv7RQm3WAWFzvP9dBTH4CwOE7G3DfQDEnBJTdtNgX5XMqgE7aE79wac/kJ8fHWftUfH3AVxxbBw=="
},
"webidl-conversions": {
"version": "7.0.0",
+16 -16
View File
@@ -19,42 +19,42 @@
},
"dependencies": {
"@aw-labs/appwrite-console": "^6.0.0",
"@aw-labs/icons": "0.0.0-61",
"@aw-labs/ui": "0.0.0-61",
"@aw-labs/icons": "0.0.0-63",
"@aw-labs/ui": "0.0.0-63",
"echarts": "^5.4.0",
"prismjs": "^1.29.0",
"tippy.js": "^6.3.7",
"web-vitals": "^2.1.4"
"web-vitals": "^3.0.3"
},
"devDependencies": {
"@playwright/test": "^1.26.1",
"@playwright/test": "^1.27.1",
"@sveltejs/adapter-static": "1.0.0-next.44",
"@sveltejs/kit": "1.0.0-next.512",
"@sveltejs/vite-plugin-svelte": "^1.0.8",
"@testing-library/dom": "^8.18.1",
"@sveltejs/kit": "1.0.0-next.516",
"@sveltejs/vite-plugin-svelte": "^1.0.9",
"@testing-library/dom": "^8.19.0",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/svelte": "3.1.3",
"@testing-library/user-event": "^14.4.3",
"@types/prismjs": "^1.26.0",
"@types/gtag.js": "^0.0.12",
"@typescript-eslint/eslint-plugin": "^5.39.0",
"@typescript-eslint/parser": "^5.39.0",
"@vitest/ui": "^0.23.4",
"eslint": "^8.24.0",
"@typescript-eslint/eslint-plugin": "^5.40.0",
"@typescript-eslint/parser": "^5.40.0",
"@vitest/ui": "^0.24.3",
"eslint": "^8.25.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-svelte3": "^4.0.0",
"pre-commit": "^1.2.2",
"prettier": "^2.7.1",
"prettier-plugin-svelte": "^2.7.1",
"prettier-plugin-svelte": "^2.8.0",
"sass": "^1.55.0",
"svelte": "^3.50.1",
"svelte-check": "^2.9.1",
"svelte": "^3.52.0",
"svelte-check": "^2.9.2",
"svelte-jester": "^2.3.2",
"svelte-preprocess": "^4.10.7",
"tslib": "^2.4.0",
"typescript": "^4.8.4",
"vite": "^3.1.4",
"vitest": "^0.23.4"
"vite": "^3.1.8",
"vitest": "^0.24.3"
},
"type": "module",
"pre-commit": [
+72 -53
View File
@@ -7,50 +7,66 @@
import 'prismjs/components/prism-bash';
import 'prismjs/components/prism-php';
import 'prismjs/components/prism-python';
import 'prismjs/components/prism-yaml';
import 'prismjs/components/prism-swift';
import 'prismjs/plugins/autoloader/prism-autoloader';
import 'prismjs/plugins/custom-class/prism-custom-class';
import 'prismjs/plugins/line-numbers/prism-line-numbers';
import 'prismjs/plugins/line-numbers/prism-line-numbers.css';
import { afterUpdate } from 'svelte';
import { Copy } from '.';
export let label: string = null;
export let labelIcon: 'code' | 'android' | 'flutter' | 'apple' = null;
export let code: string;
export let language: 'js' | 'html' | 'dart' | 'kotlin' | 'json' | 'sh' | 'php' | 'python';
export let showLineNumbers = false;
export let showCopy = false;
export let language: 'js' | 'html' | 'dart' | 'kotlin' | 'json' | 'sh' | 'yml' | 'swift' | 'php' | 'python'''
export let withLineNumbers = false;
export let withCopy = false;
export let scrollable = false;
Prism.plugins.customClass.prefix('prism-');
afterUpdate(async () => {
Prism.highlightAll();
});
</script>
<div class="code" style={scrollable ? 'overflow: auto' : ''}>
<div class="controls">
<section class="box u-overflow-hidden common-section">
<div
class="controls u-position-absolute u-inset-inline-end-8 u-inset-block-start-8 u-flex u-gap-8">
{#if label}
<Pill>{label}</Pill>
<Pill>
{#if labelIcon}
<span class={`icon-${labelIcon}`} aria-hidden="true" />
{/if}
{label}
</Pill>
{/if}
{#if showCopy}
{#if withCopy}
<Copy value={code}>
<span class="icon-duplicate" aria-hidden="true" style="cursor: pointer;" />
<button class="button is-small is-text is-only-icon" aria-label="copy code">
<span class="icon-duplicate" aria-hidden="true" />
</button>
</Copy>
{/if}
</div>
<pre class={`language-${language}`} class:line-numbers={showLineNumbers}><code
<pre class={`language-${language}`} class:line-numbers={withLineNumbers}><code
>{code}</code></pre>
</div>
</section>
<style lang="scss" global>
@import 'prismjs/themes/prism.css';
div.code {
position: relative;
.box {
--p-box-background-color: var(--color-neutral-300) !important;
div.controls {
position: absolute;
right: 0.5rem;
top: 0.5rem;
z-index: 1;
body.theme-light & {
--p-box-background-color: var(--color-neutral-5) !important;
}
.controls {
z-index: 2;
}
}
@@ -60,6 +76,10 @@
color: #fcfcff;
text-shadow: none;
font-family: 'Source Code Pro';
&.line-numbers {
padding-left: 2.5em;
}
body.theme-light & {
color: #373b4d;
}
@@ -81,49 +101,48 @@
:not(pre) > code[class*='language-'],
pre[class*='language-'] {
background: #1b1b28;
body.theme-light & {
background: #fcfcff;
}
background: hsl(var(--p-box-background-color));
padding: 0;
margin: 0;
}
.token {
&.comment,
&.prolog,
&.doctype,
&.cdata {
.prism-token {
&.prism-comment,
&.prism-prolog,
&.prism-doctype,
&.prism-cdata {
color: #868ea3;
}
&.punctuation {
&.prism-punctuation {
color: #fcfcff;
body.theme-light & {
color: #373b4d;
}
}
&.property,
&.tag,
&.boolean,
&.number,
&.constant,
&.symbol,
&.deleted,
&.selector,
&.attr-name,
&.string,
&.char,
&.builtin,
&.inserted {
&.prism-property,
&.prism-tag,
&.prism-boolean,
&.prism-number,
&.prism-constant,
&.prism-symbol,
&.prism-deleted,
&.prism-selector,
&.prism-attr-name,
&.prism-string,
&.prism-char,
&.prism-builtin,
&.prism-inserted {
color: #fdc584;
body.theme-light & {
color: #e49545;
}
}
&.operator,
&.entity,
&.url,
.language-css &.string,
.style &.string {
&.prism-operator,
&.prism-entity,
&.prism-url,
.language-css &.prism-string,
.style &.prism-string {
color: #fcfcff;
background: none;
body.theme-light & {
@@ -131,29 +150,29 @@
}
}
&.atrule,
&.attr-value,
&.keyword {
&.prism-atrule,
&.prism-attr-value,
&.prism-keyword {
color: #cbb1fc;
body.theme-light & {
color: #6a6af7;
}
}
&.function {
&.prism-function {
color: #ffa1ce;
body.theme-light & {
color: #f02e7f;
}
}
&.class-name {
&.prism-class-name {
color: #a1c4ff;
body.theme-light & {
color: #62aed2;
}
}
&.regex,
&.important,
&.variable {
&.prism-regex,
&.prism-important,
&.prism-variable {
color: #a1c4ff;
body.theme-light & {
color: #62aed2;
+2
View File
@@ -1,5 +1,6 @@
<script lang="ts">
import { tooltip } from '$lib/actions/tooltip';
import { clickOnEnter } from '$lib/helpers/a11y';
import { addNotification } from '$lib/stores/notifications';
export let value: string;
@@ -21,6 +22,7 @@
<span
on:click|preventDefault={copy}
on:keyup={clickOnEnter}
on:mouseenter={() => setTimeout(() => (content = 'Click to copy'))}
use:tooltip={{
content,
+3 -1
View File
@@ -1,9 +1,11 @@
<script lang="ts">
import { clickOnEnter } from '$lib/helpers/a11y';
export let href: string;
export let icon: string = null;
</script>
<li class="drop-list-item" on:click>
<li class="drop-list-item" on:click on:keyup={clickOnEnter}>
<a {href} class="drop-button">
<span class="text"><slot /></span>
{#if icon}
+1 -1
View File
@@ -4,4 +4,4 @@
export let code: string;
</script>
<Code showLineNumbers showCopy language="json" {code} />
<Code withLineNumbers withCopy language="json" {code} />
+7 -1
View File
@@ -3,6 +3,7 @@
import { createEventDispatcher } from 'svelte';
import { fade, fly, type FadeParams, type FlyParams } from 'svelte/transition';
import { Alert } from '$lib/components';
import { clickOnEnter } from '$lib/helpers/a11y';
export let show = false;
export let size: 'small' | 'big' = null;
@@ -58,7 +59,12 @@
<svelte:window on:keydown={handleKeydown} />
{#if show}
<div class="modal-curtain" data-curtain on:click={handleBLur} transition:fade={transitionFade}>
<div
class="modal-curtain"
data-curtain
on:click={handleBLur}
on:keyup|self={clickOnEnter}
transition:fade={transitionFade}>
<section
class:is-small={size === 'small'}
class:is-big={size === 'big'}
@@ -15,6 +15,10 @@
export let groups: Writable<Map<string, Permission>>;
const dispatch = createEventDispatcher();
$: if (showUser || showTeam || showCustom) {
showDropdown = false;
}
</script>
<DropList
+3
View File
@@ -1,4 +1,6 @@
<script lang="ts">
import { clickOnEnter } from '$lib/helpers/a11y';
export let completed = false;
export let current = false;
export let currentSub = 0;
@@ -8,6 +10,7 @@
<li
on:click|preventDefault
on:keyup|self={clickOnEnter}
class:steps-item={!isSub}
class:steps-sub-item={isSub}
style={`cursor: ${completed ? 'pointer' : 'default'};`}
+5 -1
View File
@@ -1,3 +1,7 @@
<ul class="form-list">
<script lang="ts">
export let isCommonSection = false;
</script>
<ul class="form-list" class:common-section={isCommonSection}>
<slot />
</ul>
+10
View File
@@ -0,0 +1,10 @@
export function clickOnEnter(
event: KeyboardEvent & {
currentTarget: EventTarget & HTMLElement;
}
) {
if (event.key === 'Enter' && event.currentTarget.contains(event.target as Node)) {
event.preventDefault();
event.currentTarget.click();
}
}
+14 -7
View File
@@ -1,4 +1,6 @@
import { getCLS, getFCP, getFID, getLCP, getTTFB, type Metric } from 'web-vitals';
import { page } from '$app/stores';
import { get } from 'svelte/store';
import type { Metric } from 'web-vitals';
type Options = {
params:
@@ -57,14 +59,19 @@ function sendToAnalytics(metric: Metric, options: Options) {
});
}
export function webVitals(options: Options) {
export function reportWebVitals(metric: Metric) {
try {
getFID((metric) => sendToAnalytics(metric, options));
getTTFB((metric) => sendToAnalytics(metric, options));
getLCP((metric) => sendToAnalytics(metric, options));
getCLS((metric) => sendToAnalytics(metric, options));
getFCP((metric) => sendToAnalytics(metric, options));
sendToAnalytics(metric, createWebVitalsOptions());
} catch (err) {
console.error('[Analytics]', err);
}
}
function createWebVitalsOptions(): Options {
const ctx = get(page);
return {
path: ctx.url.pathname,
params: ctx.params,
analyticsId: window.VERCEL_ANALYTICS_ID || ''
};
}
+17 -4
View File
@@ -2,13 +2,21 @@
<div class="container">
<ul class="inline-links is-center">
<li class="inline-links-item">
<a class="link" href="https://github.com/appwrite/appwrite" target="_blank">
<a
class="link"
href="https://github.com/appwrite/appwrite"
target="_blank"
rel="noopener noreferrer">
<span class="icon-github-circled" aria-hidden="true" />
<span class="text">GitHub</span>
</a>
</li>
<li class="inline-links-item">
<a class="link" href="https://appwrite.io/discord" target="_blank">
<a
class="link"
href="https://appwrite.io/discord"
target="_blank"
rel="noopener noreferrer">
<span class="icon-discord" aria-hidden="true" />
<span class="text">Discord</span>
</a>
@@ -17,12 +25,17 @@
<a
class="link"
href="https://github.com/appwrite/appwrite/issues/new"
target="_blank">
target="_blank"
rel="noopener noreferrer">
<span class="text">Open an Issue</span>
</a>
</li>
<li class="inline-links-item">
<a class="link" href="https://appwrite.io/docs" target="_blank">
<a
class="link"
href="https://appwrite.io/docs"
target="_blank"
rel="noopener noreferrer">
<span class="text">Docs</span>
</a>
</li>
+2 -2
View File
@@ -113,8 +113,8 @@
{/each}
<div class="form-footer">
<div class="u-flex u-main-end u-gap-12">
{#if sortedSteps[currentStep - 1][1].optional}
<Button text on:click={() => (isLastStep = true)} submit
{#if !isLastStep && sortedSteps[currentStep - 1][1].optional}
<Button text on:click={() => dispatch('finish')}
>Skip optional steps</Button>
{/if}
{#if currentStep === 1}
+14 -9
View File
@@ -3,13 +3,14 @@
import { page } from '$app/stores';
import { user } from '$lib/stores/user';
import { redirectTo } from '$lib/stores/organization';
import { onCLS, onFID, onLCP, onFCP, onINP, onTTFB } from 'web-vitals';
import { reportWebVitals } from '$lib/helpers/vitals';
import { onMount } from 'svelte';
import { base } from '$app/paths';
import { browser, dev } from '$app/environment';
import { app } from '$lib/stores/app';
import Notifications from '$lib/layout/notifications.svelte';
import Loading from './_loading.svelte';
import { webVitals } from '$lib/helpers/vitals';
let loaded = false;
@@ -21,6 +22,18 @@
const acceptedRoutes = ['/login', '/register', '/recover', '/invite'];
onMount(async () => {
/**
* Reporting Web Vitals.
*/
if (!dev && window.VERCEL_ANALYTICS_ID) {
onCLS(reportWebVitals);
onFID(reportWebVitals);
onLCP(reportWebVitals);
onFCP(reportWebVitals);
onINP(reportWebVitals);
onTTFB(reportWebVitals);
}
try {
if (!$user) {
await user.fetchUser();
@@ -46,14 +59,6 @@
}
});
$: if (!dev && browser && window.VERCEL_ANALYTICS_ID) {
webVitals({
path: $page.url.pathname,
params: $page.params,
analyticsId: window.VERCEL_ANALYTICS_ID
});
}
$: {
if (browser) {
if ($app.theme === 'auto') {
@@ -6,6 +6,7 @@
import { project } from '../../store';
import { addNotification } from '$lib/stores/notifications';
import { sdkForConsole } from '$lib/stores/sdk';
import { clickOnEnter } from '$lib/helpers/a11y';
const projectId = $project.$id;
let isLimited = $project.authLimit === 0 ? 'unlimited' : 'limited';
@@ -113,7 +114,8 @@
</div>
<div
class="input-text-wrapper u-stretch"
on:click={() => (isLimited = 'limited')}>
on:click={() => (isLimited = 'limited')}
on:keyup|self={clickOnEnter}>
<input
type="number"
name="limit"
@@ -1,23 +1,63 @@
<script lang="ts">
import { page } from '$app/stores';
import { GridItem1 } from '$lib/components';
import { DropList, DropListItem, GridItem1 } from '$lib/components';
import { Button } from '$lib/elements/forms';
import { toLocaleDateTime } from '$lib/helpers/date';
import { wizard } from '$lib/stores/wizard';
import { project } from '../../store';
import Create from './create.svelte';
let show = false;
import CreateAndroid from './createAndroid.svelte';
import CreateApple from './createApple.svelte';
import CreateFlutter from './createFlutter.svelte';
import CreateWeb from './createWeb.svelte';
import { versions } from './wizard/store';
let showDropdown = false;
const path = `/console/project-${$page.params.project}/overview/platforms`;
enum Platform {
Web,
Flutter,
Android,
Apple
}
const platforms = {
[Platform.Web]: CreateWeb,
[Platform.Flutter]: CreateFlutter,
[Platform.Android]: CreateAndroid,
[Platform.Apple]: CreateApple
};
async function addPlatform(type: Platform) {
await versions.load();
wizard.start(platforms[type]);
}
</script>
<div class="common-section u-flex u-gap-12">
<h3 class="heading-level-7">Platforms</h3>
<span class="u-margin-inline-start-auto">
<Button on:click={() => (show = true)}>
<span class="icon-plus" aria-hidden="true" />
<span class="text">Add Platform</span>
</Button>
<DropList
bind:show={showDropdown}
position="bottom"
horizontal="right"
arrow={true}
arrowPosition="start">
<Button on:click={() => (showDropdown = !showDropdown)}>
<span class="icon-plus" aria-hidden="true" />
<span class="text">Add platform</span>
</Button>
<svelte:fragment slot="list">
<DropListItem on:click={() => addPlatform(Platform.Web)}>Web App</DropListItem>
<DropListItem on:click={() => addPlatform(Platform.Flutter)}>
Flutter App
</DropListItem>
<DropListItem on:click={() => addPlatform(Platform.Android)}>
Android App
</DropListItem>
<DropListItem on:click={() => addPlatform(Platform.Apple)}>Apple App</DropListItem>
</svelte:fragment>
</DropList>
</span>
</div>
@@ -25,7 +65,6 @@
{#each $project.platforms as platform}
<GridItem1 href={`${path}/${platform.$id}`}>
<svelte:fragment slot="title">{platform.name}</svelte:fragment>
<div class="grid-item-1-end-start">
<p>Last Updated</p>
<p>{toLocaleDateTime(platform.$updatedAt)}</p>
@@ -33,5 +72,3 @@
</GridItem1>
{/each}
</div>
<Create bind:show />
@@ -19,8 +19,8 @@
message: `${$platform.name} has been deleted`
});
project.load($project.$id);
platform.set(null);
await goto(`${base}/console/project-${$project.$id}/overview/platforms`);
platform.set(null);
} catch (error) {
addNotification({
type: 'error',
@@ -1,47 +0,0 @@
<script lang="ts">
import { Modal } from '$lib/components';
import { InputText, Button, Form, FormList } from '$lib/elements/forms';
import { addNotification } from '$lib/stores/notifications';
import { sdkForConsole } from '$lib/stores/sdk';
import { project } from '../../.../../store';
export let show = false;
let name: string;
let hostname: string;
async function create() {
try {
await sdkForConsole.projects.createPlatform(
$project.$id,
'web',
name,
undefined,
undefined,
hostname
);
name = hostname = null;
project.load($project.$id);
show = false;
} catch (error) {
addNotification({
type: 'error',
message: error.message
});
}
}
</script>
<Form on:submit={create}>
<Modal bind:show>
<svelte:fragment slot="header">Add Platform</svelte:fragment>
<FormList>
<InputText id="name" label="Name" bind:value={name} autofocus required />
<InputText id="host" label="Hostname" bind:value={hostname} required />
</FormList>
<svelte:fragment slot="footer">
<Button submit>Register</Button>
<Button secondary on:click={() => (show = false)}>Cancel</Button>
</svelte:fragment>
</Modal>
</Form>
@@ -0,0 +1,53 @@
<script lang="ts">
import { Wizard } from '$lib/layout';
import { beforeNavigate } from '$app/navigation';
import { page } from '$app/stores';
import { wizard } from '$lib/stores/wizard';
import { project } from '../../store';
import type { WizardStepsType } from '$lib/layout/wizard.svelte';
import Step1 from './wizard/android/step1.svelte';
import Step2 from './wizard/android/step2.svelte';
import Step3 from './wizard/android/step3.svelte';
import Step4 from './wizard/step4.svelte';
import { createPlatform } from './wizard/store';
const projectId = $page.params.project;
async function create() {
project.load(projectId);
createPlatform.reset();
wizard.hide();
}
beforeNavigate(() => {
wizard.hide();
});
const stepsComponents: WizardStepsType = new Map();
stepsComponents.set(1, {
label: 'Register your app',
component: Step1
});
stepsComponents.set(2, {
label: 'Get the SDK',
component: Step2,
optional: true
});
stepsComponents.set(3, {
label: "Let's get coding",
component: Step3,
optional: true
});
stepsComponents.set(4, {
label: 'All set',
component: Step4,
optional: true
});
</script>
<Wizard
title="Add an Android Project"
steps={stepsComponents}
on:finish={create}
on:exit={createPlatform.reset}
finalAction="Take me to my Dashboard" />
@@ -0,0 +1,53 @@
<script lang="ts">
import { Wizard } from '$lib/layout';
import { beforeNavigate } from '$app/navigation';
import { page } from '$app/stores';
import { wizard } from '$lib/stores/wizard';
import { project } from '../../store';
import type { WizardStepsType } from '$lib/layout/wizard.svelte';
import Step1 from './wizard/apple/step1.svelte';
import Step2 from './wizard/apple/step2.svelte';
import Step3 from './wizard/apple/step3.svelte';
import Step4 from './wizard/step4.svelte';
import { createPlatform } from './wizard/store';
const projectId = $page.params.project;
async function create() {
project.load(projectId);
createPlatform.reset();
wizard.hide();
}
beforeNavigate(() => {
wizard.hide();
});
const stepsComponents: WizardStepsType = new Map();
stepsComponents.set(1, {
label: 'Register your app',
component: Step1
});
stepsComponents.set(2, {
label: 'Get the SDK',
component: Step2,
optional: true
});
stepsComponents.set(3, {
label: "Let's get coding",
component: Step3,
optional: true
});
stepsComponents.set(4, {
label: 'All set',
component: Step4,
optional: true
});
</script>
<Wizard
title="Add an Apple Project"
steps={stepsComponents}
on:finish={create}
on:exit={createPlatform.reset}
finalAction="Take me to my Dashboard" />
@@ -0,0 +1,53 @@
<script lang="ts">
import { Wizard } from '$lib/layout';
import { beforeNavigate } from '$app/navigation';
import { page } from '$app/stores';
import { wizard } from '$lib/stores/wizard';
import { project } from '../../store';
import type { WizardStepsType } from '$lib/layout/wizard.svelte';
import Step1 from './wizard/flutter/step1.svelte';
import Step2 from './wizard/flutter/step2.svelte';
import Step3 from './wizard/flutter/step3.svelte';
import Step4 from './wizard/step4.svelte';
import { createPlatform } from './wizard/store';
const projectId = $page.params.project;
async function create() {
project.load(projectId);
createPlatform.reset();
wizard.hide();
}
beforeNavigate(() => {
wizard.hide();
});
const stepsComponents: WizardStepsType = new Map();
stepsComponents.set(1, {
label: 'Register your app',
component: Step1
});
stepsComponents.set(2, {
label: 'Get the SDK',
component: Step2,
optional: true
});
stepsComponents.set(3, {
label: "Let's get coding",
component: Step3,
optional: true
});
stepsComponents.set(4, {
label: 'All set',
component: Step4,
optional: true
});
</script>
<Wizard
title="Add a Flutter Project"
steps={stepsComponents}
on:finish={create}
on:exit={createPlatform.reset}
finalAction="Take me to my Dashboard" />
@@ -0,0 +1,53 @@
<script lang="ts">
import { Wizard } from '$lib/layout';
import { beforeNavigate } from '$app/navigation';
import { page } from '$app/stores';
import { wizard } from '$lib/stores/wizard';
import { project } from '../../store';
import type { WizardStepsType } from '$lib/layout/wizard.svelte';
import Step1 from './wizard/web/step1.svelte';
import Step2 from './wizard/web/step2.svelte';
import Step3 from './wizard/web/step3.svelte';
import Step4 from './wizard/step4.svelte';
import { createPlatform } from './wizard/store';
const projectId = $page.params.project;
async function create() {
project.load(projectId);
createPlatform.reset();
wizard.hide();
}
beforeNavigate(() => {
wizard.hide();
});
const stepsComponents: WizardStepsType = new Map();
stepsComponents.set(1, {
label: 'Register your app',
component: Step1
});
stepsComponents.set(2, {
label: 'Get the SDK',
component: Step2,
optional: true
});
stepsComponents.set(3, {
label: "Let's get coding",
component: Step3,
optional: true
});
stepsComponents.set(4, {
label: 'All set',
component: Step4,
optional: true
});
</script>
<Wizard
title="Add a Web Project"
steps={stepsComponents}
on:finish={create}
on:exit={createPlatform.reset}
finalAction="Take me to my Dashboard" />
@@ -0,0 +1,53 @@
<script lang="ts">
import { page } from '$app/stores';
import { FormList, InputText } from '$lib/elements/forms';
import { WizardStep } from '$lib/layout';
import { sdkForConsole } from '$lib/stores/sdk';
import { createPlatform } from '../store';
const projectId = $page.params.project;
async function beforeSubmit() {
if ($createPlatform.$id) {
await sdkForConsole.projects.updatePlatform(
projectId,
$createPlatform.$id,
$createPlatform.name,
undefined,
undefined,
$createPlatform.hostname
);
return;
}
const platform = await sdkForConsole.projects.createPlatform(
projectId,
'android',
$createPlatform.name,
undefined,
undefined,
$createPlatform.hostname
);
$createPlatform.$id = platform.$id;
}
</script>
<WizardStep {beforeSubmit}>
<svelte:fragment slot="title">Register your Android app</svelte:fragment>
<FormList>
<InputText
id="name"
label="Name"
placeholder="My Android App"
required
bind:value={$createPlatform.name} />
<InputText
id="hostname"
label="Package Name"
placeholder="com.company.appname"
required
bind:value={$createPlatform.hostname} />
</FormList>
</WizardStep>
@@ -0,0 +1,18 @@
<script lang="ts">
import { Code } from '$lib/components';
import { WizardStep } from '$lib/layout';
import { versions } from '../store';
const example1 = `repositories {
mavenCentral()
}`;
const example2 = `implementation("io.appwrite:sdk-for-android:${versions['client-android']}")`;
</script>
<WizardStep>
<svelte:fragment slot="title">Get the SDK</svelte:fragment>
<p>First, add this to your root level build.gradle file:</p>
<Code label="Groovy" labelIcon="android" language="kotlin" code={example1} withCopy />
<p class="common-section">And add this to your project's build.gradle file:</p>
<Code label="Groovy" labelIcon="android" language="kotlin" code={example2} withCopy />
</WizardStep>
@@ -0,0 +1,23 @@
<script lang="ts">
import { Code } from '$lib/components';
import { WizardStep } from '$lib/layout';
import { sdkForProject } from '$lib/stores/sdk';
const { endpoint, project } = sdkForProject.client.config;
const code = `const appwrite = new Appwrite();
appwrite
.setEndpoint('${endpoint}')
.setProject('${project}');`;
</script>
<WizardStep>
<svelte:fragment slot="title">Let's get coding</svelte:fragment>
<h2 class="heading-level-7">Init your SDK</h2>
<p>
Now that you've downloaded the SDK, it's time to initialze it. Use your project ID, which
can be found in your project settings page.
</p>
<Code label="Web SDK" labelIcon="code" language="js" {code} withCopy withLineNumbers />
</WizardStep>
@@ -0,0 +1,98 @@
<script lang="ts">
import { page } from '$app/stores';
import { Alert } from '$lib/components';
import { Pill } from '$lib/elements';
import { FormItem, FormList, InputText } from '$lib/elements/forms';
import { WizardStep } from '$lib/layout';
import { sdkForConsole } from '$lib/stores/sdk';
import { createPlatform } from '../store';
enum Platform {
iOS = 'apple-ios',
macOS = 'apple-macos',
watchOS = 'apple-watchos',
tvOS = 'apple-tvos'
}
let platform: Platform = Platform.iOS;
const projectId = $page.params.project;
async function beforeSubmit() {
if ($createPlatform.$id) {
await sdkForConsole.projects.updatePlatform(
projectId,
$createPlatform.$id,
$createPlatform.name,
undefined,
undefined,
$createPlatform.hostname
);
return;
}
const response = await sdkForConsole.projects.createPlatform(
projectId,
platform,
$createPlatform.name,
undefined,
undefined,
$createPlatform.hostname
);
$createPlatform.$id = response.$id;
}
</script>
<WizardStep {beforeSubmit}>
<svelte:fragment slot="title">Register your Flutter app</svelte:fragment>
<Alert type="warning">
Note: If you are building your Flutter application for multiple devices, you will have to
follow this process for each different device.
</Alert>
<FormList isCommonSection>
<FormItem>
<p>Choose a platform</p>
<div class="u-flex u-gap-16 u-margin-block-start-8">
<Pill
button
on:click={() => (platform = Platform.iOS)}
selected={platform === Platform.iOS}>
iOS
</Pill>
<Pill
button
on:click={() => (platform = Platform.macOS)}
selected={platform === Platform.macOS}>
macOS
</Pill>
<Pill
button
on:click={() => (platform = Platform.watchOS)}
selected={platform === Platform.watchOS}>
watchOS
</Pill>
<Pill
button
on:click={() => (platform = Platform.tvOS)}
selected={platform === Platform.tvOS}>
tvOS
</Pill>
</div>
</FormItem>
<InputText
id="name"
label="Name"
placeholder="My Apple App"
required
bind:value={$createPlatform.name} />
<InputText
id="hostname"
label="Bundle ID"
placeholder="com.company.appname"
required
bind:value={$createPlatform.hostname} />
</FormList>
</WizardStep>
@@ -0,0 +1,78 @@
<script lang="ts">
import { Code } from '$lib/components';
import { Pill } from '$lib/elements';
import { WizardStep } from '$lib/layout';
import { versions } from '../store';
enum Method {
Xcode,
Swift
}
let method: Method = Method.Xcode;
const example1 = `dependencies: [
.package(
name: "Appwrite",
url: "https://github.com/appwrite/sdk-for-swift",
.exact("${$versions['client-apple']}")
)
]')`;
const example2 = `targets: [
.target(
name: "[YOUR_TARGET]",
dependencies: [
"Appwrite"
]
)
]`;
</script>
<WizardStep>
<svelte:fragment slot="title">Get the SDK</svelte:fragment>
<div class="u-flex u-gap-16 u-margin-block-start-8">
<Pill button on:click={() => (method = Method.Xcode)} selected={method === Method.Xcode}>
Xcode
</Pill>
<Pill button on:click={() => (method = Method.Swift)} selected={method === Method.Swift}>
Swift Packages
</Pill>
</div>
<div class="common-section">
{#if method === Method.Xcode}
<ol class="numeric-list">
<li class="numeric-list-item">
<span class="text">
Select File > Swift Packages > Add Package Dependency
</span>
</li>
<li class="numeric-list-item">
<span class="text">
Search for the Appwrite SDK with the URL
<a class="link" href="https://github.com/appwrite/sdk-for-apple">
https://github.com/appwrite/sdk-for-apple
</a>
</span>
</li>
<li class="numeric-list-item">
<span class="text"> Add version rules </span>
</li>
<li class="numeric-list-item">
<span class="text">
Select next and wait for package resolution to complete
</span>
</li>
<li class="numeric-list-item">
<span class="text">
Make sure `Appwrite` is selected to add to your target and select finish
</span>
</li>
</ol>
{:else if method === Method.Swift}
<p>Add this to your Package.swift file:</p>
<Code withCopy withLineNumbers label="Swift" language="swift" code={example1} />
<p class="common-section">Then add the dependency to your target:</p>
<Code withCopy withLineNumbers label="Swift" language="swift" code={example2} />
{/if}
</div>
</WizardStep>
@@ -0,0 +1,37 @@
<script lang="ts">
import { Alert, Code } from '$lib/components';
import { WizardStep } from '$lib/layout';
import { sdkForProject } from '$lib/stores/sdk';
const { endpoint, project } = sdkForProject.client.config;
const code = `import Appwrite
let client = Client()
.setEndpoint("${endpoint}")
.setProject("${project}")
.setSelfSigned(status: true) // For self signed certificates, only use for development`;
</script>
<WizardStep>
<svelte:fragment slot="title">Let's get coding</svelte:fragment>
<h2 class="heading-level-7">Init your SDK</h2>
<p>
Now that you've downloaded the SDK, it's time to initialze it. Use your project ID, which
can be found in your project settings page.
</p>
<Code label="Apple SDK" labelIcon="apple" language="swift" {code} withCopy withLineNumbers />
<p>
Before sending any API calls to your new Appwrite project, make sure your device or emulator
has network access to your Appwrite project's hostname or IP address.
</p>
<div class="common-section">
<Alert type="info">
<svelte:fragment slot="title">For self-hosted solutions</svelte:fragment>
When connecting to a locally hosted Appwrite project from an emulator or a mobile device,
you should use the private IP of the device running your Appwrite project as the hostname
of the endpoint instead of localhost. You can also use a service like ngrok to proxy the
Appwrite server.
</Alert>
</div>
</WizardStep>
@@ -0,0 +1,167 @@
<script lang="ts">
import { page } from '$app/stores';
import { Alert } from '$lib/components';
import { Pill } from '$lib/elements';
import { FormList, InputText } from '$lib/elements/forms';
import { WizardStep } from '$lib/layout';
import { sdkForConsole } from '$lib/stores/sdk';
import { createPlatform } from '../store';
enum Platform {
Android = 'flutter-android',
Ios = 'flutter-ios',
Linux = 'flutter-linux',
Macos = 'flutter-macos',
Windows = 'flutter-windows',
Web = 'flutter-web'
}
let platform: Platform = Platform.Android;
const projectId = $page.params.project;
const suggestions = ['*.vercel.app', '*.netlify.app', '*.gitpod.app'];
const placeholder: Record<
Platform,
{
name: string;
hostname: string;
}
> = {
[Platform.Android]: {
name: 'My Android App',
hostname: 'com.company.appname'
},
[Platform.Ios]: {
name: 'My iOS App',
hostname: 'com.company.appname'
},
[Platform.Linux]: {
name: 'My Linux App',
hostname: 'com.company.appname'
},
[Platform.Macos]: {
name: 'My mac OS App',
hostname: 'com.company.appname'
},
[Platform.Web]: {
name: 'My Web App',
hostname: 'com.company.appname'
},
[Platform.Windows]: {
name: 'My Windows App',
hostname: 'localhost'
}
};
const hostname: Record<Platform, string> = {
[Platform.Android]: 'Package Name',
[Platform.Ios]: 'Package Name',
[Platform.Linux]: 'Package Name',
[Platform.Macos]: 'Bundle ID',
[Platform.Web]: 'Hostname',
[Platform.Windows]: 'Package Name'
};
async function beforeSubmit() {
if ($createPlatform.$id) {
await sdkForConsole.projects.updatePlatform(
projectId,
$createPlatform.$id,
$createPlatform.name,
undefined,
undefined,
$createPlatform.hostname
);
return;
}
const response = await sdkForConsole.projects.createPlatform(
projectId,
platform,
$createPlatform.name,
undefined,
undefined,
$createPlatform.hostname
);
$createPlatform.$id = response.$id;
}
</script>
<WizardStep {beforeSubmit}>
<svelte:fragment slot="title">Register your Flutter app</svelte:fragment>
<svelte:fragment slot="subtitle">
<div class="u-flex u-gap-16 u-margin-block-start-8">
<Pill
button
on:click={() => (platform = Platform.Android)}
selected={platform === Platform.Android}>
Android
</Pill>
<Pill
button
on:click={() => (platform = Platform.Ios)}
selected={platform === Platform.Ios}>
iOS
</Pill>
<Pill
button
on:click={() => (platform = Platform.Linux)}
selected={platform === Platform.Linux}>
Linux
</Pill>
<Pill
button
on:click={() => (platform = Platform.Macos)}
selected={platform === Platform.Macos}>
Mac OS
</Pill>
<Pill
button
on:click={() => (platform = Platform.Windows)}
selected={platform === Platform.Windows}>
Windows
</Pill>
<Pill
button
on:click={() => (platform = Platform.Web)}
selected={platform === Platform.Web}>
Web
</Pill>
</div>
</svelte:fragment>
<Alert type="warning">
Note: If you are building your Flutter application for multiple devices, you will have to
follow this process for each different device.
</Alert>
<FormList isCommonSection>
<InputText
id="name"
label="Name"
placeholder={placeholder[platform].name}
required
bind:value={$createPlatform.name} />
<div>
<InputText
id="hostname"
label={hostname[platform]}
placeholder={placeholder[platform].hostname}
required
bind:value={$createPlatform.hostname} />
{#if platform === Platform.Web}
<div class="u-flex u-gap-16 u-margin-block-start-8">
{#each suggestions as suggestion}
<Pill
button
selected={$createPlatform.hostname === suggestion}
on:click={() => ($createPlatform.hostname = suggestion)}>
{suggestion}
</Pill>
{/each}
</div>
{/if}
</div>
</FormList>
</WizardStep>
@@ -0,0 +1,20 @@
<script lang="ts">
import { Code } from '$lib/components';
import { WizardStep } from '$lib/layout';
import { versions } from '../store';
const example1 = `dependencies:
appwrite: ^${$versions['client-flutter']}`;
const example2 = `pub get appwrite`;
</script>
<WizardStep>
<svelte:fragment slot="title">Get the SDK</svelte:fragment>
<p>Add Appwrite SDK to your package's pubspec.yaml file. You can view an example here.</p>
<Code label="YAML" language="yml" code={example1} withCopy />
<p class="common-section">
You can also install the SDK using the Dart package manager from your terminal:
</p>
<Code label="Bash" language="sh" code={example2} withCopy />
</WizardStep>
@@ -0,0 +1,38 @@
<script lang="ts">
import { Alert, Code } from '$lib/components';
import { WizardStep } from '$lib/layout';
import { sdkForProject } from '$lib/stores/sdk';
const { endpoint, project } = sdkForProject.client.config;
const code = `import 'package:appwrite/appwrite.dart';
Client client = Client();
client
.setEndpoint('${endpoint}')
.setProject('${project}')
.setSelfSigned(status: true); // For self signed certificates, only use for development`;
</script>
<WizardStep>
<svelte:fragment slot="title">Let's get coding</svelte:fragment>
<h2 class="heading-level-7">Init your SDK</h2>
<p>
Now that you've downloaded the SDK, it's time to initialze it. Use your project ID, which
can be found in your project settings page.
</p>
<Code label="Flutter SDK" labelIcon="flutter" language="dart" {code} withCopy withLineNumbers />
<p class="common-section">
Before sending any API calls to your new Appwrite project, make sure your device or emulator
has network access to your Appwrite project's hostname or IP address.
</p>
<div class="common-section">
<Alert type="info">
<svelte:fragment slot="title">For self-hosted solutions</svelte:fragment>
When connecting to a locally hosted Appwrite project from an emulator or a mobile device,
you should use the private IP of the device running your Appwrite project as the hostname
of the endpoint instead of localhost. You can also use a service like ngrok to proxy the
Appwrite server.
</Alert>
</div>
</WizardStep>
@@ -0,0 +1,12 @@
<script lang="ts">
import { WizardStep } from '$lib/layout';
</script>
<WizardStep>
<svelte:fragment slot="title">You're ready to go 🎉</svelte:fragment>
<p>
Congrats, you've just added your first platform to your Appwrite dashboard! Are you ready to
give it a go? Why not add a database to your project, or start uploading files? The choice
is up to you.
</p>
</WizardStep>
@@ -0,0 +1,60 @@
import { writable } from 'svelte/store';
import { sdkForConsole } from '$lib/stores/sdk';
import { cachedStore } from '$lib/helpers/cache';
import type { Models } from '@aw-labs/appwrite-console';
function createPlatformStore() {
const { subscribe, update, set } = writable<Partial<Models.Platform>>({
$id: null,
name: null,
hostname: null,
type: null
});
return {
subscribe,
update,
set,
reset() {
set({
$id: null,
name: null,
hostname: null,
type: null
});
}
};
}
export const createPlatform = createPlatformStore();
export const versions = cachedStore<
{
server: string;
'client-web': string;
'client-flutter': string;
'client-apple': string;
'client-android': string;
'console-web': string;
'console-cli': string;
'server-nodejs': string;
'server-deno': string;
'server-php': string;
'server-python': string;
'server-ruby': string;
'server-dart': string;
'server-kotlin': string;
'server-swift': string;
},
{
load: () => Promise<void>;
}
>('versions', function ({ set }) {
return {
load: async () => {
const { endpoint } = sdkForConsole.client.config;
const response = await fetch(`${endpoint}/../versions`);
set(await response.json());
}
};
});
@@ -0,0 +1,72 @@
<script lang="ts">
import { page } from '$app/stores';
import { Alert } from '$lib/components';
import { Pill } from '$lib/elements';
import { FormList, InputText } from '$lib/elements/forms';
import { WizardStep } from '$lib/layout';
import { sdkForConsole } from '$lib/stores/sdk';
import { createPlatform } from '../store';
const projectId = $page.params.project;
const suggestions = ['*.vercel.app', '*.netlify.app', '*.gitpod.app'];
async function beforeSubmit() {
if ($createPlatform.$id) {
await sdkForConsole.projects.updatePlatform(
projectId,
$createPlatform.$id,
$createPlatform.name,
undefined,
undefined,
$createPlatform.hostname
);
return;
}
const platform = await sdkForConsole.projects.createPlatform(
projectId,
'web',
$createPlatform.name,
undefined,
undefined,
$createPlatform.hostname
);
$createPlatform.$id = platform.$id;
}
</script>
<WizardStep {beforeSubmit}>
<svelte:fragment slot="title">Register your Web app</svelte:fragment>
<FormList>
<InputText
id="name"
label="Name"
placeholder="My Web App"
required
bind:value={$createPlatform.name} />
<div>
<InputText
id="hostname"
label="Hostname"
placeholder="localhost"
required
bind:value={$createPlatform.hostname} />
<div class="u-flex u-gap-16 u-margin-block-start-8">
{#each suggestions as suggestion}
<Pill
button
selected={$createPlatform.hostname === suggestion}
on:click={() => ($createPlatform.hostname = suggestion)}>
{suggestion}
</Pill>
{/each}
</div>
</div>
<Alert type="warning">
Tip: Avoid using wildcard hostnames in production to keep your project secure. Check out
our documentation for more info.
</Alert>
</FormList>
</WizardStep>
@@ -0,0 +1,57 @@
<script lang="ts">
import { versions } from '../store';
import { Code } from '$lib/components';
import { Pill } from '$lib/elements';
import { WizardStep } from '$lib/layout';
enum Method {
NPM,
CDN
}
let method: Method = Method.NPM;
const example1 = `import { Appwrite } from 'appwrite';`;
const example2 = `<script src="https://cdn.jsdelivr.net/npm/appwrite@${$versions['client-web']}" />`;
</script>
<WizardStep>
<svelte:fragment slot="title">Get the SDK</svelte:fragment>
<svelte:fragment slot="subtitle">
Choose your preferred method of installation
<div class="u-flex u-gap-16 u-margin-block-start-8">
<Pill button on:click={() => (method = Method.NPM)} selected={method === Method.NPM}>
NPM
</Pill>
<Pill button on:click={() => (method = Method.CDN)} selected={method === Method.CDN}>
CDN
</Pill>
</div>
</svelte:fragment>
{#if method === Method.NPM}
<p>
Use <a href="https://npmjs.org" target="_blank" rel="noopener noreferrer" class="link"
>NPM (node package manager)</a> from your command line to add Appwrite SDK to your project.
</p>
<Code label="Bash" language="sh" code="npm install appwrite" withCopy />
<p class="common-section">
When you're using a bundler (like <a
href="https://vitejs.dev"
target="_blank"
rel="noopener noreferrer"
class="link">Vite</a>
or
<a href="https://rollupjs.org" target="_blank" rel="noopener noreferrer" class="link"
>Rollup</a
>), import the Appwrite module when you need it:
</p>
<Code label="Web SDK" labelIcon="code" language="js" code={example1} withCopy />
{:else if method === Method.CDN}
<p>
To install with a CDN (content delivery network) add the following scripts to the bottom
of your tag, but before you use any Appwrite services:
</p>
<Code label="HTML" language="html" code={example2} withCopy />
{/if}
</WizardStep>
@@ -0,0 +1,23 @@
<script lang="ts">
import { Code } from '$lib/components';
import { WizardStep } from '$lib/layout';
import { sdkForProject } from '$lib/stores/sdk';
const { endpoint, project } = sdkForProject.client.config;
const code = `const appwrite = new Appwrite();
appwrite
.setEndpoint('${endpoint}')
.setProject('${project}');`;
</script>
<WizardStep>
<svelte:fragment slot="title">Let's get coding</svelte:fragment>
<h2 class="heading-level-7">Init your SDK</h2>
<p>
Now that you've downloaded the SDK, it's time to initialze it. Use your project ID, which
can be found in your project settings page.
</p>
<Code label="Web SDK" labelIcon="code" language="js" {code} withCopy withLineNumbers />
</WizardStep>
@@ -70,6 +70,7 @@
href={downloadFile()}
class="file-preview is-with-image"
target="_blank"
rel="noopener noreferrer"
aria-label="open file in new window">
<div class="file-preview-image">
<img
+7 -2
View File
@@ -59,9 +59,14 @@
By accepting the invitation, you agree to the <a
class="link"
href="https://appwrite.io/policy/terms"
target="_blank">Terms and Conditions</a>
target="_blank"
rel="noopener noreferrer">Terms and Conditions</a>
and
<a class="link" href="https://appwrite.io/policy/privacy" target="_blank">
<a
class="link"
href="https://appwrite.io/policy/privacy"
target="_blank"
rel="noopener noreferrer">
Privacy Policy</a
>.</InputChoice>
+9 -9
View File
@@ -26,7 +26,7 @@ test('shows line numbers', async () => {
const { container } = render(Code, {
code: 'a\nb;\nc;',
language: 'js',
showLineNumbers: true
withLineNumbers: true
});
expect(container.querySelectorAll('.line-numbers').length).toEqual(1);
@@ -39,9 +39,9 @@ test('shows code highlighted javascript', async () => {
language: 'js'
});
expect(container.querySelectorAll('.token.function').length).toEqual(1);
expect(container.querySelectorAll('.token.string').length).toEqual(1);
expect(container.querySelectorAll('.token.punctuation').length).toEqual(4);
expect(container.querySelectorAll('.prism-token.prism-function').length).toEqual(1);
expect(container.querySelectorAll('.prism-token.prism-string').length).toEqual(1);
expect(container.querySelectorAll('.prism-token.prism-punctuation').length).toEqual(4);
});
test('shows code highlighted json', async () => {
@@ -50,17 +50,17 @@ test('shows code highlighted json', async () => {
language: 'json'
});
expect(container.querySelectorAll('.token.property').length).toEqual(1);
expect(container.querySelectorAll('.token.operator').length).toEqual(1);
expect(container.querySelectorAll('.token.string').length).toEqual(1);
expect(container.querySelectorAll('.token.punctuation').length).toEqual(2);
expect(container.querySelectorAll('.prism-token.prism-property').length).toEqual(1);
expect(container.querySelectorAll('.prism-token.prism-operator').length).toEqual(1);
expect(container.querySelectorAll('.prism-token.prism-string').length).toEqual(1);
expect(container.querySelectorAll('.prism-token.prism-punctuation').length).toEqual(2);
});
test('copy to clipboard function called on click', async () => {
const { container } = render(Code, {
code: 'console.log("test");',
language: 'js',
showCopy: true
withCopy: true
});
Object.assign(window.navigator, {
+17
View File
@@ -19,3 +19,20 @@ test('copy to clipboard function called on click', async () => {
expect(window.navigator.clipboard.writeText).toHaveBeenCalledWith('This is a test');
});
test('copy to clipboard function called on enter', async () => {
const { getByTestId } = render(Copy, { value });
Object.assign(window.navigator, {
clipboard: {
writeText: vi.fn().mockImplementation(() => Promise.resolve())
}
});
const button = getByTestId('copy-content');
await fireEvent.keyUp(button, {
key: 'Enter'
});
expect(window.navigator.clipboard.writeText).toHaveBeenCalledWith('This is a test');
});
+13 -1
View File
@@ -29,7 +29,7 @@ test('close modal by click', async () => {
expect(component.show).toStrictEqual(false);
});
test('close modal by key', async () => {
test('close modal by escape', async () => {
const { queryByText, component } = render(Modal, {
show: true
});
@@ -38,3 +38,15 @@ test('close modal by key', async () => {
await userEvent.keyboard('[Escape]');
expect(component.show).toStrictEqual(false);
});
test('close modal by enter key on focus', async () => {
const { container, queryByText, component } = render(Modal, {
show: true
});
expect(queryByText('Content')).toBeInTheDocument();
await fireEvent.keyUp(container.querySelector('[data-curtain]'), {
key: 'Enter'
});
expect(component.show).toStrictEqual(false);
});