create-feathersdev 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/CHANGELOG.md +107 -0
  2. package/README.md +3 -0
  3. package/bin/feathersdev +9 -0
  4. package/esm/actions/app.js +51 -0
  5. package/esm/actions/integrate.js +80 -0
  6. package/esm/actions/login.js +8 -0
  7. package/esm/actions/logout.js +12 -0
  8. package/esm/actions/server.js +52 -0
  9. package/esm/base.js +40 -0
  10. package/esm/flows/check-login.js +70 -0
  11. package/esm/flows/with-application.js +81 -0
  12. package/esm/flows/with-organization.js +74 -0
  13. package/esm/index.js +55 -0
  14. package/esm/package.json +1 -0
  15. package/examples/frontend/auth.ts +39 -0
  16. package/examples/frontend/react/.eslintrc.cjs +18 -0
  17. package/examples/frontend/react/README.md +30 -0
  18. package/examples/frontend/react/index.html +13 -0
  19. package/examples/frontend/react/package.json +29 -0
  20. package/examples/frontend/react/public/vite.svg +1 -0
  21. package/examples/frontend/react/src/App.css +42 -0
  22. package/examples/frontend/react/src/App.tsx +37 -0
  23. package/examples/frontend/react/src/assets/react.svg +1 -0
  24. package/examples/frontend/react/src/auth.ts +39 -0
  25. package/examples/frontend/react/src/automerge.ts +16 -0
  26. package/examples/frontend/react/src/index.css +68 -0
  27. package/examples/frontend/react/src/main.tsx +10 -0
  28. package/examples/frontend/react/src/vite-env.d.ts +1 -0
  29. package/examples/frontend/react/tsconfig.app.json +27 -0
  30. package/examples/frontend/react/tsconfig.json +11 -0
  31. package/examples/frontend/react/tsconfig.node.json +13 -0
  32. package/examples/frontend/react/vite.config.ts +7 -0
  33. package/examples/frontend/svelte/.vscode/extensions.json +3 -0
  34. package/examples/frontend/svelte/README.md +47 -0
  35. package/examples/frontend/svelte/index.html +13 -0
  36. package/examples/frontend/svelte/package.json +24 -0
  37. package/examples/frontend/svelte/public/vite.svg +1 -0
  38. package/examples/frontend/svelte/src/App.svelte +30 -0
  39. package/examples/frontend/svelte/src/app.css +79 -0
  40. package/examples/frontend/svelte/src/assets/svelte.svg +1 -0
  41. package/examples/frontend/svelte/src/auth.ts +33 -0
  42. package/examples/frontend/svelte/src/main.ts +9 -0
  43. package/examples/frontend/svelte/src/vite-env.d.ts +2 -0
  44. package/examples/frontend/svelte/svelte.config.js +7 -0
  45. package/examples/frontend/svelte/tsconfig.json +21 -0
  46. package/examples/frontend/svelte/tsconfig.node.json +12 -0
  47. package/examples/frontend/svelte/vite.config.ts +8 -0
  48. package/examples/frontend/vanilla/index.html +13 -0
  49. package/examples/frontend/vanilla/package.json +16 -0
  50. package/examples/frontend/vanilla/public/vite.svg +1 -0
  51. package/examples/frontend/vanilla/src/auth.ts +39 -0
  52. package/examples/frontend/vanilla/src/automerge.ts +16 -0
  53. package/examples/frontend/vanilla/src/main.ts +23 -0
  54. package/examples/frontend/vanilla/src/style.css +96 -0
  55. package/examples/frontend/vanilla/src/vite-env.d.ts +1 -0
  56. package/examples/frontend/vanilla/tsconfig.json +23 -0
  57. package/examples/frontend/vanilla/vite.config.ts +8 -0
  58. package/examples/frontend/vue/.vscode/extensions.json +3 -0
  59. package/examples/frontend/vue/README.md +33 -0
  60. package/examples/frontend/vue/env.d.ts +1 -0
  61. package/examples/frontend/vue/index.html +13 -0
  62. package/examples/frontend/vue/package.json +29 -0
  63. package/examples/frontend/vue/public/favicon.ico +0 -0
  64. package/examples/frontend/vue/src/App.vue +30 -0
  65. package/examples/frontend/vue/src/assets/base.css +86 -0
  66. package/examples/frontend/vue/src/assets/logo.svg +1 -0
  67. package/examples/frontend/vue/src/assets/main.css +35 -0
  68. package/examples/frontend/vue/src/auth.ts +39 -0
  69. package/examples/frontend/vue/src/automerge.ts +16 -0
  70. package/examples/frontend/vue/src/main.ts +6 -0
  71. package/examples/frontend/vue/tsconfig.app.json +14 -0
  72. package/examples/frontend/vue/tsconfig.json +11 -0
  73. package/examples/frontend/vue/tsconfig.node.json +19 -0
  74. package/examples/frontend/vue/vite.config.ts +18 -0
  75. package/examples/server/bun/README.md +15 -0
  76. package/examples/server/bun/bun.lockb +0 -0
  77. package/examples/server/bun/package.json +17 -0
  78. package/examples/server/bun/src/authenticate.ts +17 -0
  79. package/examples/server/bun/src/index.ts +54 -0
  80. package/examples/server/bun/tsconfig.json +27 -0
  81. package/examples/server/cloudflare/.editorconfig +12 -0
  82. package/examples/server/cloudflare/.prettierrc +6 -0
  83. package/examples/server/cloudflare/package.json +22 -0
  84. package/examples/server/cloudflare/src/authenticate.ts +17 -0
  85. package/examples/server/cloudflare/src/index.ts +50 -0
  86. package/examples/server/cloudflare/test/index.spec.ts +25 -0
  87. package/examples/server/cloudflare/test/tsconfig.json +8 -0
  88. package/examples/server/cloudflare/tsconfig.json +105 -0
  89. package/examples/server/cloudflare/vitest.config.mts +11 -0
  90. package/examples/server/cloudflare/worker-configuration.d.ts +4 -0
  91. package/examples/server/cloudflare/wrangler.toml +108 -0
  92. package/examples/server/deno/deno.lock +79 -0
  93. package/examples/server/deno/package.json +13 -0
  94. package/examples/server/deno/src/authenticate.ts +17 -0
  95. package/examples/server/deno/src/server.ts +51 -0
  96. package/examples/server/express/package.json +24 -0
  97. package/examples/server/express/src/app.ts +26 -0
  98. package/examples/server/express/src/authenticate.ts +51 -0
  99. package/examples/server/express/tsconfig.json +108 -0
  100. package/examples/server/nodejs/package.json +20 -0
  101. package/examples/server/nodejs/src/authenticate.ts +28 -0
  102. package/examples/server/nodejs/src/server.ts +38 -0
  103. package/examples/server/nodejs/tsconfig.json +108 -0
  104. package/package.json +67 -0
@@ -0,0 +1,33 @@
1
+ import { createClient } from '@feathersdev/auth'
2
+ import { createAutomerge } from '@feathersdev/automerge'
3
+
4
+ export const appId = '<your-app-id>'
5
+
6
+ export const auth = createClient({
7
+ appId,
8
+ onLoginRequired: async (error) => {
9
+ window.location.href = await auth.getLoginUrl(error)
10
+ },
11
+ })
12
+
13
+ export const automerge = createAutomerge(auth)
14
+
15
+ /**
16
+ * Make an authenticated request using the fetch API or
17
+ * redirect to the login page if the user needs to log in.
18
+ *
19
+ * @param url The URL for the request
20
+ * @param options Additional request options.
21
+ * @returns The fetch response
22
+ */
23
+ export async function authFetch(url: string, options?: RequestInit) {
24
+ const headers = new Headers(options?.headers)
25
+
26
+ // Set the authorization header with the Feathers Auth token
27
+ headers.set('Authorization', await auth.getHeader())
28
+
29
+ return fetch(url, {
30
+ ...options,
31
+ headers,
32
+ })
33
+ }
@@ -0,0 +1,9 @@
1
+ import { mount } from 'svelte'
2
+ import App from './App.svelte'
3
+ import './app.css'
4
+
5
+ const app = mount(App, {
6
+ target: document.getElementById('app')!,
7
+ })
8
+
9
+ export default app
@@ -0,0 +1,2 @@
1
+ /// <reference types="svelte" />
2
+ /// <reference types="vite/client" />
@@ -0,0 +1,7 @@
1
+ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
2
+
3
+ export default {
4
+ // Consult https://svelte.dev/docs#compile-time-svelte-preprocess
5
+ // for more information about preprocessors
6
+ preprocess: vitePreprocess(),
7
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "extends": "@tsconfig/svelte/tsconfig.json",
3
+ "compilerOptions": {
4
+ "target": "ESNext",
5
+ "moduleDetection": "force",
6
+ "useDefineForClassFields": true,
7
+ "module": "ESNext",
8
+ "resolveJsonModule": true,
9
+ /**
10
+ * Typecheck JS in `.svelte` and `.js` files by default.
11
+ * Disable checkJs if you'd like to use dynamic types in JS.
12
+ * Note that setting allowJs false does not prevent the use
13
+ * of JS in `.svelte` files.
14
+ */
15
+ "allowJs": true,
16
+ "checkJs": true,
17
+ "isolatedModules": true
18
+ },
19
+ "references": [{ "path": "./tsconfig.node.json" }],
20
+ "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"]
21
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "compilerOptions": {
3
+ "composite": true,
4
+ "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
5
+ "module": "ESNext",
6
+ "moduleResolution": "bundler",
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "skipLibCheck": true
10
+ },
11
+ "include": ["vite.config.ts"]
12
+ }
@@ -0,0 +1,8 @@
1
+ import { svelte } from '@sveltejs/vite-plugin-svelte'
2
+ import { defineConfig } from 'vite'
3
+ import wasm from 'vite-plugin-wasm'
4
+
5
+ // https://vitejs.dev/config/
6
+ export default defineConfig({
7
+ plugins: [wasm(), svelte()],
8
+ })
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Vite + TS</title>
8
+ </head>
9
+ <body>
10
+ <div id="app"></div>
11
+ <script type="module" src="/src/main.ts"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "vanilla-frontend",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite --port 3000",
8
+ "build": "tsc && vite build",
9
+ "preview": "vite preview"
10
+ },
11
+ "devDependencies": {
12
+ "typescript": "^5.6.3",
13
+ "vite-plugin-wasm": "^3.4.1",
14
+ "vite": "^5.4.11"
15
+ }
16
+ }
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
@@ -0,0 +1,39 @@
1
+ import { createClient } from '@feathersdev/auth'
2
+
3
+ /**
4
+ * This is your public application id
5
+ */
6
+ export const appId = '<your-app-id>'
7
+
8
+ /**
9
+ * The Feathers auth client instance. You can use it to get a token,
10
+ * retrieve the current user and to log in and out.
11
+ */
12
+ export const auth = createClient({
13
+ appId,
14
+ onLoginRequired: async (error) => {
15
+ // Redirect to login page if a login is required
16
+ // You can also do other things here like show a modal before redirecting
17
+ window.location.href = await auth.getLoginUrl(error)
18
+ },
19
+ })
20
+
21
+ /**
22
+ * Make an authenticated request to a server using the standard fetch API.
23
+ * Will redirect to the login page instead if the user needs to log in.
24
+ *
25
+ * @param url The URL for the request
26
+ * @param options Additional request options.
27
+ * @returns The fetch response
28
+ */
29
+ export async function authFetch(url: string, options?: RequestInit) {
30
+ const headers = new Headers(options?.headers)
31
+
32
+ // Set the authorization header with the Feathers Auth token
33
+ headers.set('Authorization', await auth.getHeader())
34
+
35
+ return fetch(url, {
36
+ ...options,
37
+ headers,
38
+ })
39
+ }
@@ -0,0 +1,16 @@
1
+ import { createAutomerge } from '@feathersdev/automerge'
2
+ import { auth } from './auth.js'
3
+
4
+ /**
5
+ * The Feathers Automerge client. Use it to retrieve the document
6
+ * for your application with `automerge.find()`.
7
+ */
8
+ export const automerge = createAutomerge(auth)
9
+
10
+ interface AppData {
11
+ counter: number
12
+ }
13
+
14
+ export async function getHandle() {
15
+ return automerge.find<AppData>()
16
+ }
@@ -0,0 +1,23 @@
1
+ import { authFetch } from './auth.js'
2
+ import { getHandle } from './automerge.js'
3
+ import './style.css'
4
+
5
+ getHandle().then((handle) => {
6
+ document.querySelector<HTMLDivElement>('#app')!.innerHTML = `
7
+ <div>
8
+ <div class="wrapper">
9
+ <h1>Feathers Auth + TypeScript demo</h1>
10
+ <p>Our community counter is</p>
11
+ <h2 id="counter">...</h2>
12
+ </div>
13
+ </div>
14
+ `
15
+
16
+ handle.on('change', ({ doc }) => {
17
+ document.getElementById('message')!.innerHTML = doc.counter.toString()
18
+ })
19
+
20
+ handle.change((doc) => {
21
+ doc.counter = (doc.counter || 0) + 1
22
+ })
23
+ })
@@ -0,0 +1,96 @@
1
+ :root {
2
+ font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
3
+ line-height: 1.5;
4
+ font-weight: 400;
5
+
6
+ color-scheme: light dark;
7
+ color: rgba(255, 255, 255, 0.87);
8
+ background-color: #242424;
9
+
10
+ font-synthesis: none;
11
+ text-rendering: optimizeLegibility;
12
+ -webkit-font-smoothing: antialiased;
13
+ -moz-osx-font-smoothing: grayscale;
14
+ }
15
+
16
+ a {
17
+ font-weight: 500;
18
+ color: #646cff;
19
+ text-decoration: inherit;
20
+ }
21
+ a:hover {
22
+ color: #535bf2;
23
+ }
24
+
25
+ body {
26
+ margin: 0;
27
+ display: flex;
28
+ place-items: center;
29
+ min-width: 320px;
30
+ min-height: 100vh;
31
+ }
32
+
33
+ h1 {
34
+ font-size: 3.2em;
35
+ line-height: 1.1;
36
+ }
37
+
38
+ #app {
39
+ max-width: 1280px;
40
+ margin: 0 auto;
41
+ padding: 2rem;
42
+ text-align: center;
43
+ }
44
+
45
+ .logo {
46
+ height: 6em;
47
+ padding: 1.5em;
48
+ will-change: filter;
49
+ transition: filter 300ms;
50
+ }
51
+ .logo:hover {
52
+ filter: drop-shadow(0 0 2em #646cffaa);
53
+ }
54
+ .logo.vanilla:hover {
55
+ filter: drop-shadow(0 0 2em #3178c6aa);
56
+ }
57
+
58
+ .card {
59
+ padding: 2em;
60
+ }
61
+
62
+ .read-the-docs {
63
+ color: #888;
64
+ }
65
+
66
+ button {
67
+ border-radius: 8px;
68
+ border: 1px solid transparent;
69
+ padding: 0.6em 1.2em;
70
+ font-size: 1em;
71
+ font-weight: 500;
72
+ font-family: inherit;
73
+ background-color: #1a1a1a;
74
+ cursor: pointer;
75
+ transition: border-color 0.25s;
76
+ }
77
+ button:hover {
78
+ border-color: #646cff;
79
+ }
80
+ button:focus,
81
+ button:focus-visible {
82
+ outline: 4px auto -webkit-focus-ring-color;
83
+ }
84
+
85
+ @media (prefers-color-scheme: light) {
86
+ :root {
87
+ color: #213547;
88
+ background-color: #ffffff;
89
+ }
90
+ a:hover {
91
+ color: #747bff;
92
+ }
93
+ button {
94
+ background-color: #f9f9f9;
95
+ }
96
+ }
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "module": "ESNext",
6
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
7
+ "skipLibCheck": true,
8
+
9
+ /* Bundler mode */
10
+ "moduleResolution": "bundler",
11
+ "allowImportingTsExtensions": true,
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "noEmit": true,
15
+
16
+ /* Linting */
17
+ "strict": true,
18
+ "noUnusedLocals": true,
19
+ "noUnusedParameters": true,
20
+ "noFallthroughCasesInSwitch": true
21
+ },
22
+ "include": ["src"]
23
+ }
@@ -0,0 +1,8 @@
1
+ import react from '@vitejs/plugin-react'
2
+ import { defineConfig } from 'vite'
3
+ import wasm from 'vite-plugin-wasm'
4
+
5
+ // https://vitejs.dev/config/
6
+ export default defineConfig({
7
+ plugins: [wasm()],
8
+ })
@@ -0,0 +1,3 @@
1
+ {
2
+ "recommendations": ["Vue.volar"]
3
+ }
@@ -0,0 +1,33 @@
1
+ # vue-app
2
+
3
+ This template should help get you started developing with Vue 3 in Vite.
4
+
5
+ ## Recommended IDE Setup
6
+
7
+ [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
8
+
9
+ ## Type Support for `.vue` Imports in TS
10
+
11
+ TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types.
12
+
13
+ ## Customize configuration
14
+
15
+ See [Vite Configuration Reference](https://vitejs.dev/config/).
16
+
17
+ ## Project Setup
18
+
19
+ ```sh
20
+ npm install
21
+ ```
22
+
23
+ ### Compile and Hot-Reload for Development
24
+
25
+ ```sh
26
+ npm run dev
27
+ ```
28
+
29
+ ### Type-Check, Compile and Minify for Production
30
+
31
+ ```sh
32
+ npm run build
33
+ ```
@@ -0,0 +1 @@
1
+ /// <reference types="vite/client" />
@@ -0,0 +1,13 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <link rel="icon" href="/favicon.ico">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Vite App</title>
8
+ </head>
9
+ <body>
10
+ <div id="app"></div>
11
+ <script type="module" src="/src/main.ts"></script>
12
+ </body>
13
+ </html>
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "vue-Frontend",
3
+ "type": "module",
4
+ "version": "0.0.0",
5
+ "private": true,
6
+ "scripts": {
7
+ "dev": "vite --port 3000",
8
+ "build": "run-p type-check \"build-only {@}\" --",
9
+ "preview": "vite preview",
10
+ "build-only": "vite build",
11
+ "type-check": "vue-tsc --build --force"
12
+ },
13
+ "dependencies": {
14
+ "@feathersdev/auth": "^0.10.0",
15
+ "@feathersdev/automerge": "^0.10.0",
16
+ "vue": "^3.5.12"
17
+ },
18
+ "devDependencies": {
19
+ "@tsconfig/node20": "^20.1.4",
20
+ "@types/node": "^22.9.0",
21
+ "@vitejs/plugin-vue": "^5.2.0",
22
+ "@vue/tsconfig": "^0.6.0",
23
+ "npm-run-all2": "^7.0.1",
24
+ "typescript": "~5.6.3",
25
+ "vite": "^5.4.11",
26
+ "vite-plugin-wasm": "^3.4.1",
27
+ "vue-tsc": "^2.1.10"
28
+ }
29
+ }
@@ -0,0 +1,30 @@
1
+ <script setup lang="ts">
2
+ import { ref } from 'vue'
3
+ import { automerge } from './auth'
4
+
5
+ const handle = await automerge.find<{ counter: number }>()
6
+ const counter = ref<number>(0)
7
+
8
+ handle.on('change', ({ doc }) => {
9
+ counter.value = doc.counter
10
+ })
11
+
12
+ async function incrementCounter() {
13
+ handle.change((doc) => {
14
+ doc.counter = (doc.counter || 0) + 1
15
+ })
16
+ }
17
+ </script>
18
+
19
+ <template>
20
+ <header>
21
+ <div class="wrapper">
22
+ <h1>feathers.dev Vue demo</h1>
23
+ <p>Our community counter is:</p>
24
+ <h2><strong>{{ counter }}</strong></h2>
25
+ <button @click="incrementCounter">
26
+ Increment
27
+ </button>
28
+ </div>
29
+ </header>
30
+ </template>
@@ -0,0 +1,86 @@
1
+ /* color palette from <https://github.com/vuejs/theme> */
2
+ :root {
3
+ --vt-c-white: #ffffff;
4
+ --vt-c-white-soft: #f8f8f8;
5
+ --vt-c-white-mute: #f2f2f2;
6
+
7
+ --vt-c-black: #181818;
8
+ --vt-c-black-soft: #222222;
9
+ --vt-c-black-mute: #282828;
10
+
11
+ --vt-c-indigo: #2c3e50;
12
+
13
+ --vt-c-divider-light-1: rgba(60, 60, 60, 0.29);
14
+ --vt-c-divider-light-2: rgba(60, 60, 60, 0.12);
15
+ --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65);
16
+ --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48);
17
+
18
+ --vt-c-text-light-1: var(--vt-c-indigo);
19
+ --vt-c-text-light-2: rgba(60, 60, 60, 0.66);
20
+ --vt-c-text-dark-1: var(--vt-c-white);
21
+ --vt-c-text-dark-2: rgba(235, 235, 235, 0.64);
22
+ }
23
+
24
+ /* semantic color variables for this project */
25
+ :root {
26
+ --color-background: var(--vt-c-white);
27
+ --color-background-soft: var(--vt-c-white-soft);
28
+ --color-background-mute: var(--vt-c-white-mute);
29
+
30
+ --color-border: var(--vt-c-divider-light-2);
31
+ --color-border-hover: var(--vt-c-divider-light-1);
32
+
33
+ --color-heading: var(--vt-c-text-light-1);
34
+ --color-text: var(--vt-c-text-light-1);
35
+
36
+ --section-gap: 160px;
37
+ }
38
+
39
+ @media (prefers-color-scheme: dark) {
40
+ :root {
41
+ --color-background: var(--vt-c-black);
42
+ --color-background-soft: var(--vt-c-black-soft);
43
+ --color-background-mute: var(--vt-c-black-mute);
44
+
45
+ --color-border: var(--vt-c-divider-dark-2);
46
+ --color-border-hover: var(--vt-c-divider-dark-1);
47
+
48
+ --color-heading: var(--vt-c-text-dark-1);
49
+ --color-text: var(--vt-c-text-dark-2);
50
+ }
51
+ }
52
+
53
+ *,
54
+ *::before,
55
+ *::after {
56
+ box-sizing: border-box;
57
+ margin: 0;
58
+ font-weight: normal;
59
+ }
60
+
61
+ body {
62
+ min-height: 100vh;
63
+ color: var(--color-text);
64
+ background: var(--color-background);
65
+ transition:
66
+ color 0.5s,
67
+ background-color 0.5s;
68
+ line-height: 1.6;
69
+ font-family:
70
+ Inter,
71
+ -apple-system,
72
+ BlinkMacSystemFont,
73
+ 'Segoe UI',
74
+ Roboto,
75
+ Oxygen,
76
+ Ubuntu,
77
+ Cantarell,
78
+ 'Fira Sans',
79
+ 'Droid Sans',
80
+ 'Helvetica Neue',
81
+ sans-serif;
82
+ font-size: 15px;
83
+ text-rendering: optimizeLegibility;
84
+ -webkit-font-smoothing: antialiased;
85
+ -moz-osx-font-smoothing: grayscale;
86
+ }
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg>
@@ -0,0 +1,35 @@
1
+ @import './base.css';
2
+
3
+ #app {
4
+ max-width: 1280px;
5
+ margin: 0 auto;
6
+ padding: 2rem;
7
+ font-weight: normal;
8
+ }
9
+
10
+ a,
11
+ .green {
12
+ text-decoration: none;
13
+ color: hsla(160, 100%, 37%, 1);
14
+ transition: 0.4s;
15
+ padding: 3px;
16
+ }
17
+
18
+ @media (hover: hover) {
19
+ a:hover {
20
+ background-color: hsla(160, 100%, 37%, 0.2);
21
+ }
22
+ }
23
+
24
+ @media (min-width: 1024px) {
25
+ body {
26
+ display: flex;
27
+ place-items: center;
28
+ }
29
+
30
+ #app {
31
+ display: grid;
32
+ grid-template-columns: 1fr 1fr;
33
+ padding: 0 2rem;
34
+ }
35
+ }
@@ -0,0 +1,39 @@
1
+ import { createClient } from '@feathersdev/auth'
2
+
3
+ /**
4
+ * This is your public application id
5
+ */
6
+ export const appId = '<your-app-id>'
7
+
8
+ /**
9
+ * The Feathers auth client instance. You can use it to get a token,
10
+ * retrieve the current user and to log in and out.
11
+ */
12
+ export const auth = createClient({
13
+ appId,
14
+ onLoginRequired: async (error) => {
15
+ // Redirect to login page whenever a login is required
16
+ // You can also do other things here like show a modal before redirecting
17
+ window.location.href = await auth.getLoginUrl(error)
18
+ },
19
+ })
20
+
21
+ /**
22
+ * Make an authenticated request to a server using the standard fetch API.
23
+ * Will redirect to the login page instead if the user needs to log in.
24
+ *
25
+ * @param url The URL for the request
26
+ * @param options Additional request options.
27
+ * @returns The fetch response
28
+ */
29
+ export async function authFetch(url: string, options?: RequestInit) {
30
+ const headers = new Headers(options?.headers)
31
+
32
+ // Set the authorization header with the Feathers Auth token
33
+ headers.set('Authorization', await auth.getHeader())
34
+
35
+ return fetch(url, {
36
+ ...options,
37
+ headers,
38
+ })
39
+ }
@@ -0,0 +1,16 @@
1
+ import { createAutomerge } from '@feathersdev/automerge'
2
+ import { auth } from './auth.js'
3
+
4
+ /**
5
+ * The Feathers Automerge client. Use it to retrieve the document
6
+ * for your application with `automerge.find()`.
7
+ */
8
+ export const automerge = createAutomerge(auth)
9
+
10
+ interface AppData {
11
+ counter: number
12
+ }
13
+
14
+ export async function getHandle() {
15
+ return automerge.find<AppData>()
16
+ }
@@ -0,0 +1,6 @@
1
+ import { createApp } from 'vue'
2
+
3
+ import App from './App.vue'
4
+ import './assets/main.css'
5
+
6
+ createApp(App).mount('#app')