@korajs/cli 0.4.0 → 0.6.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 (253) hide show
  1. package/dist/bin.cjs +1636 -601
  2. package/dist/bin.cjs.map +1 -1
  3. package/dist/bin.js +1086 -139
  4. package/dist/bin.js.map +1 -1
  5. package/dist/{chunk-MVP5PDT4.js → chunk-EEZNRI5W.js} +51 -6
  6. package/dist/chunk-EEZNRI5W.js.map +1 -0
  7. package/dist/{chunk-YGVO4POI.js → chunk-Q2FBCOQD.js} +27 -15
  8. package/dist/chunk-Q2FBCOQD.js.map +1 -0
  9. package/dist/{chunk-CMSX76KM.js → chunk-VLTPEATY.js} +172 -99
  10. package/dist/chunk-VLTPEATY.js.map +1 -0
  11. package/dist/create.cjs +130 -54
  12. package/dist/create.cjs.map +1 -1
  13. package/dist/create.js +2 -2
  14. package/dist/index.cjs +143 -62
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +8 -6
  17. package/dist/index.d.ts +8 -6
  18. package/dist/index.js +2 -2
  19. package/package.json +9 -3
  20. package/templates/react-basic/README.md.hbs +10 -1
  21. package/templates/react-basic/src/App.tsx +112 -126
  22. package/templates/react-basic/src/index.css +165 -159
  23. package/templates/react-basic/src/kora-worker.ts +0 -1
  24. package/templates/react-basic/src/main.tsx +12 -12
  25. package/templates/react-basic/src/modules/todos/todo.mutations.ts +25 -0
  26. package/templates/react-basic/src/modules/todos/todo.queries.ts +5 -0
  27. package/templates/react-basic/src/modules/todos/todo.schema.ts +10 -0
  28. package/templates/react-basic/src/modules/todos/useTodos.ts +31 -0
  29. package/templates/react-basic/src/schema.ts +6 -12
  30. package/templates/react-basic/src/vite-env.d.ts +17 -0
  31. package/templates/react-basic/{tsconfig.json → tsconfig.json.hbs} +1 -2
  32. package/templates/react-basic/vite.config.ts +57 -50
  33. package/templates/react-sync/.env.example +19 -0
  34. package/templates/react-sync/README.md.hbs +43 -1
  35. package/templates/react-sync/package.json.hbs +3 -0
  36. package/templates/react-sync/server.ts +90 -26
  37. package/templates/react-sync/src/App.tsx +132 -130
  38. package/templates/react-sync/src/auth.ts +25 -0
  39. package/templates/react-sync/src/index.css +212 -165
  40. package/templates/react-sync/src/kora-worker.ts +0 -1
  41. package/templates/react-sync/src/main.tsx +34 -18
  42. package/templates/react-sync/src/modules/todos/todo.mutations.ts +25 -0
  43. package/templates/react-sync/src/modules/todos/todo.queries.ts +5 -0
  44. package/templates/react-sync/src/modules/todos/todo.schema.ts +10 -0
  45. package/templates/react-sync/src/modules/todos/useTodos.ts +31 -0
  46. package/templates/react-sync/src/schema.ts +6 -12
  47. package/templates/react-sync/src/vite-env.d.ts +17 -0
  48. package/templates/react-sync/{tsconfig.json → tsconfig.json.hbs} +1 -2
  49. package/templates/react-sync/vite.config.ts +67 -60
  50. package/templates/react-tailwind/README.md.hbs +10 -1
  51. package/templates/react-tailwind/src/App.tsx +186 -197
  52. package/templates/react-tailwind/src/index.css +3 -3
  53. package/templates/react-tailwind/src/kora-worker.ts +0 -1
  54. package/templates/react-tailwind/src/main.tsx +19 -12
  55. package/templates/react-tailwind/src/modules/todos/todo.mutations.ts +25 -0
  56. package/templates/react-tailwind/src/modules/todos/todo.queries.ts +5 -0
  57. package/templates/react-tailwind/src/modules/todos/todo.schema.ts +10 -0
  58. package/templates/react-tailwind/src/modules/todos/useTodos.ts +31 -0
  59. package/templates/react-tailwind/src/schema.ts +6 -12
  60. package/templates/react-tailwind/src/vite-env.d.ts +17 -0
  61. package/templates/react-tailwind/{tsconfig.json → tsconfig.json.hbs} +1 -2
  62. package/templates/react-tailwind/vite.config.ts +57 -50
  63. package/templates/react-tailwind-sync/.env.example +19 -0
  64. package/templates/react-tailwind-sync/README.md.hbs +43 -1
  65. package/templates/react-tailwind-sync/package.json.hbs +3 -0
  66. package/templates/react-tailwind-sync/server.ts +90 -26
  67. package/templates/react-tailwind-sync/src/App.tsx +246 -222
  68. package/templates/react-tailwind-sync/src/auth.ts +25 -0
  69. package/templates/react-tailwind-sync/src/index.css +3 -3
  70. package/templates/react-tailwind-sync/src/kora-worker.ts +0 -1
  71. package/templates/react-tailwind-sync/src/main.tsx +48 -18
  72. package/templates/react-tailwind-sync/src/modules/todos/todo.mutations.ts +25 -0
  73. package/templates/react-tailwind-sync/src/modules/todos/todo.queries.ts +5 -0
  74. package/templates/react-tailwind-sync/src/modules/todos/todo.schema.ts +10 -0
  75. package/templates/react-tailwind-sync/src/modules/todos/useTodos.ts +31 -0
  76. package/templates/react-tailwind-sync/src/schema.ts +6 -12
  77. package/templates/react-tailwind-sync/src/vite-env.d.ts +17 -0
  78. package/templates/react-tailwind-sync/{tsconfig.json → tsconfig.json.hbs} +1 -2
  79. package/templates/react-tailwind-sync/vite.config.ts +67 -60
  80. package/templates/svelte-basic/.env.example +3 -0
  81. package/templates/svelte-basic/README.md.hbs +62 -0
  82. package/templates/svelte-basic/index.html.hbs +12 -0
  83. package/templates/svelte-basic/kora.config.ts +12 -0
  84. package/templates/svelte-basic/package.json.hbs +27 -0
  85. package/templates/svelte-basic/src/App.svelte +131 -0
  86. package/templates/svelte-basic/src/Root.svelte +14 -0
  87. package/templates/svelte-basic/src/index.css +287 -0
  88. package/templates/svelte-basic/src/kora-worker.ts +9 -0
  89. package/templates/svelte-basic/src/main.ts +16 -0
  90. package/templates/svelte-basic/src/modules/todos/todo.mutations.ts +25 -0
  91. package/templates/svelte-basic/src/modules/todos/todo.queries.ts +5 -0
  92. package/templates/svelte-basic/src/modules/todos/todo.schema.ts +10 -0
  93. package/templates/svelte-basic/src/modules/todos/useTodos.ts +25 -0
  94. package/templates/svelte-basic/src/schema.ts +9 -0
  95. package/templates/svelte-basic/src/vite-env.d.ts +12 -0
  96. package/templates/svelte-basic/svelte.config.js +5 -0
  97. package/templates/svelte-basic/tsconfig.json.hbs +14 -0
  98. package/templates/svelte-basic/vite.config.ts +52 -0
  99. package/templates/svelte-sync/.env.example +25 -0
  100. package/templates/svelte-sync/README.md.hbs +105 -0
  101. package/templates/svelte-sync/index.html.hbs +12 -0
  102. package/templates/svelte-sync/kora.config.ts +17 -0
  103. package/templates/svelte-sync/package.json.hbs +43 -0
  104. package/templates/svelte-sync/server.ts +90 -0
  105. package/templates/svelte-sync/src/App.svelte +154 -0
  106. package/templates/svelte-sync/src/Root.svelte +22 -0
  107. package/templates/svelte-sync/src/auth.ts +25 -0
  108. package/templates/svelte-sync/src/index.css +339 -0
  109. package/templates/svelte-sync/src/kora-worker.ts +9 -0
  110. package/templates/svelte-sync/src/main.ts +32 -0
  111. package/templates/svelte-sync/src/modules/todos/todo.mutations.ts +25 -0
  112. package/templates/svelte-sync/src/modules/todos/todo.queries.ts +5 -0
  113. package/templates/svelte-sync/src/modules/todos/todo.schema.ts +10 -0
  114. package/templates/svelte-sync/src/modules/todos/useTodos.ts +25 -0
  115. package/templates/svelte-sync/src/schema.ts +9 -0
  116. package/templates/svelte-sync/src/vite-env.d.ts +21 -0
  117. package/templates/svelte-sync/svelte.config.js +5 -0
  118. package/templates/svelte-sync/tsconfig.json.hbs +14 -0
  119. package/templates/svelte-sync/vite.config.ts +79 -0
  120. package/templates/svelte-tailwind/README.md.hbs +62 -0
  121. package/templates/svelte-tailwind/index.html.hbs +12 -0
  122. package/templates/svelte-tailwind/kora.config.ts +12 -0
  123. package/templates/svelte-tailwind/package.json.hbs +30 -0
  124. package/templates/svelte-tailwind/src/App.svelte +79 -0
  125. package/templates/svelte-tailwind/src/Root.svelte +14 -0
  126. package/templates/svelte-tailwind/src/index.css +7 -0
  127. package/templates/svelte-tailwind/src/kora-worker.ts +9 -0
  128. package/templates/svelte-tailwind/src/main.ts +16 -0
  129. package/templates/svelte-tailwind/src/modules/todos/todo.mutations.ts +25 -0
  130. package/templates/svelte-tailwind/src/modules/todos/todo.queries.ts +5 -0
  131. package/templates/svelte-tailwind/src/modules/todos/todo.schema.ts +10 -0
  132. package/templates/svelte-tailwind/src/modules/todos/useTodos.ts +25 -0
  133. package/templates/svelte-tailwind/src/schema.ts +9 -0
  134. package/templates/svelte-tailwind/src/vite-env.d.ts +12 -0
  135. package/templates/svelte-tailwind/svelte.config.js +5 -0
  136. package/templates/svelte-tailwind/tsconfig.json.hbs +14 -0
  137. package/templates/svelte-tailwind/vite.config.ts +53 -0
  138. package/templates/svelte-tailwind-sync/.env.example +25 -0
  139. package/templates/svelte-tailwind-sync/README.md.hbs +105 -0
  140. package/templates/svelte-tailwind-sync/index.html.hbs +12 -0
  141. package/templates/svelte-tailwind-sync/kora.config.ts +17 -0
  142. package/templates/svelte-tailwind-sync/package.json.hbs +46 -0
  143. package/templates/svelte-tailwind-sync/server.ts +90 -0
  144. package/templates/svelte-tailwind-sync/src/App.svelte +196 -0
  145. package/templates/svelte-tailwind-sync/src/Root.svelte +26 -0
  146. package/templates/svelte-tailwind-sync/src/auth.ts +25 -0
  147. package/templates/svelte-tailwind-sync/src/index.css +7 -0
  148. package/templates/svelte-tailwind-sync/src/kora-worker.ts +9 -0
  149. package/templates/svelte-tailwind-sync/src/main.ts +32 -0
  150. package/templates/svelte-tailwind-sync/src/modules/todos/todo.mutations.ts +25 -0
  151. package/templates/svelte-tailwind-sync/src/modules/todos/todo.queries.ts +5 -0
  152. package/templates/svelte-tailwind-sync/src/modules/todos/todo.schema.ts +10 -0
  153. package/templates/svelte-tailwind-sync/src/modules/todos/useTodos.ts +25 -0
  154. package/templates/svelte-tailwind-sync/src/schema.ts +9 -0
  155. package/templates/svelte-tailwind-sync/src/vite-env.d.ts +21 -0
  156. package/templates/svelte-tailwind-sync/svelte.config.js +5 -0
  157. package/templates/svelte-tailwind-sync/tsconfig.json.hbs +14 -0
  158. package/templates/svelte-tailwind-sync/vite.config.ts +80 -0
  159. package/templates/tauri-react/.env.example +20 -0
  160. package/templates/tauri-react/README.md.hbs +36 -1
  161. package/templates/tauri-react/dev.ts +11 -11
  162. package/templates/tauri-react/package.json.hbs +2 -0
  163. package/templates/tauri-react/server.ts +86 -12
  164. package/templates/tauri-react/src/App.tsx +769 -544
  165. package/templates/tauri-react/src/AppShell.tsx +125 -83
  166. package/templates/tauri-react/src/SetupScreen.tsx +257 -208
  167. package/templates/tauri-react/src/auth.ts +45 -0
  168. package/templates/tauri-react/src/main.tsx +3 -3
  169. package/templates/tauri-react/src/modules/todos/todo.mutations.ts +25 -0
  170. package/templates/tauri-react/src/modules/todos/todo.queries.ts +5 -0
  171. package/templates/tauri-react/src/modules/todos/todo.schema.ts +10 -0
  172. package/templates/tauri-react/src/modules/todos/useTodos.ts +31 -0
  173. package/templates/tauri-react/src/schema.ts +6 -12
  174. package/templates/tauri-react/src/sync-config.ts +47 -47
  175. package/templates/tauri-react/src/updater.ts +15 -15
  176. package/templates/tauri-react/src/vite-env.d.ts +17 -0
  177. package/templates/tauri-react/src-tauri/tauri.conf.json +1 -1
  178. package/templates/tauri-react/tsconfig.json.hbs +14 -0
  179. package/templates/tauri-react/vite.config.ts +9 -9
  180. package/templates/vue-basic/README.md.hbs +62 -0
  181. package/templates/vue-basic/index.html.hbs +12 -0
  182. package/templates/vue-basic/kora.config.ts +12 -0
  183. package/templates/vue-basic/package.json.hbs +26 -0
  184. package/templates/vue-basic/src/App.vue +117 -0
  185. package/templates/vue-basic/src/index.css +287 -0
  186. package/templates/vue-basic/src/kora-worker.ts +9 -0
  187. package/templates/vue-basic/src/main.ts +20 -0
  188. package/templates/vue-basic/src/modules/todos/todo.mutations.ts +25 -0
  189. package/templates/vue-basic/src/modules/todos/todo.queries.ts +5 -0
  190. package/templates/vue-basic/src/modules/todos/todo.schema.ts +10 -0
  191. package/templates/vue-basic/src/modules/todos/useTodos.ts +32 -0
  192. package/templates/vue-basic/src/schema.ts +9 -0
  193. package/templates/vue-basic/src/vite-env.d.ts +17 -0
  194. package/templates/vue-basic/tsconfig.json.hbs +15 -0
  195. package/templates/vue-basic/vite.config.ts +69 -0
  196. package/templates/vue-sync/.env.example +25 -0
  197. package/templates/vue-sync/README.md.hbs +105 -0
  198. package/templates/vue-sync/index.html.hbs +12 -0
  199. package/templates/vue-sync/kora.config.ts +17 -0
  200. package/templates/vue-sync/package.json.hbs +42 -0
  201. package/templates/vue-sync/server.ts +90 -0
  202. package/templates/vue-sync/src/App.vue +135 -0
  203. package/templates/vue-sync/src/auth.ts +25 -0
  204. package/templates/vue-sync/src/index.css +339 -0
  205. package/templates/vue-sync/src/kora-worker.ts +9 -0
  206. package/templates/vue-sync/src/main.ts +43 -0
  207. package/templates/vue-sync/src/modules/todos/todo.mutations.ts +25 -0
  208. package/templates/vue-sync/src/modules/todos/todo.queries.ts +5 -0
  209. package/templates/vue-sync/src/modules/todos/todo.schema.ts +10 -0
  210. package/templates/vue-sync/src/modules/todos/useTodos.ts +32 -0
  211. package/templates/vue-sync/src/schema.ts +9 -0
  212. package/templates/vue-sync/src/vite-env.d.ts +26 -0
  213. package/templates/vue-sync/tsconfig.json.hbs +15 -0
  214. package/templates/vue-sync/vite.config.ts +79 -0
  215. package/templates/vue-tailwind/README.md.hbs +62 -0
  216. package/templates/vue-tailwind/index.html.hbs +12 -0
  217. package/templates/vue-tailwind/kora.config.ts +12 -0
  218. package/templates/vue-tailwind/package.json.hbs +29 -0
  219. package/templates/vue-tailwind/src/App.vue +142 -0
  220. package/templates/vue-tailwind/src/index.css +7 -0
  221. package/templates/vue-tailwind/src/kora-worker.ts +9 -0
  222. package/templates/vue-tailwind/src/main.ts +31 -0
  223. package/templates/vue-tailwind/src/modules/todos/todo.mutations.ts +25 -0
  224. package/templates/vue-tailwind/src/modules/todos/todo.queries.ts +5 -0
  225. package/templates/vue-tailwind/src/modules/todos/todo.schema.ts +10 -0
  226. package/templates/vue-tailwind/src/modules/todos/useTodos.ts +32 -0
  227. package/templates/vue-tailwind/src/schema.ts +9 -0
  228. package/templates/vue-tailwind/src/vite-env.d.ts +17 -0
  229. package/templates/vue-tailwind/tsconfig.json.hbs +15 -0
  230. package/templates/vue-tailwind/vite.config.ts +70 -0
  231. package/templates/vue-tailwind-sync/.env.example +25 -0
  232. package/templates/vue-tailwind-sync/README.md.hbs +105 -0
  233. package/templates/vue-tailwind-sync/index.html.hbs +12 -0
  234. package/templates/vue-tailwind-sync/kora.config.ts +17 -0
  235. package/templates/vue-tailwind-sync/package.json.hbs +45 -0
  236. package/templates/vue-tailwind-sync/server.ts +90 -0
  237. package/templates/vue-tailwind-sync/src/App.vue +245 -0
  238. package/templates/vue-tailwind-sync/src/auth.ts +25 -0
  239. package/templates/vue-tailwind-sync/src/index.css +7 -0
  240. package/templates/vue-tailwind-sync/src/kora-worker.ts +9 -0
  241. package/templates/vue-tailwind-sync/src/main.ts +56 -0
  242. package/templates/vue-tailwind-sync/src/modules/todos/todo.mutations.ts +25 -0
  243. package/templates/vue-tailwind-sync/src/modules/todos/todo.queries.ts +5 -0
  244. package/templates/vue-tailwind-sync/src/modules/todos/todo.schema.ts +10 -0
  245. package/templates/vue-tailwind-sync/src/modules/todos/useTodos.ts +32 -0
  246. package/templates/vue-tailwind-sync/src/schema.ts +9 -0
  247. package/templates/vue-tailwind-sync/src/vite-env.d.ts +26 -0
  248. package/templates/vue-tailwind-sync/tsconfig.json.hbs +15 -0
  249. package/templates/vue-tailwind-sync/vite.config.ts +80 -0
  250. package/dist/chunk-CMSX76KM.js.map +0 -1
  251. package/dist/chunk-MVP5PDT4.js.map +0 -1
  252. package/dist/chunk-YGVO4POI.js.map +0 -1
  253. package/templates/tauri-react/tsconfig.json +0 -15
@@ -0,0 +1,5 @@
1
+ import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
2
+
3
+ export default {
4
+ preprocess: vitePreprocess(),
5
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "strict": true,
7
+ "noUncheckedIndexedAccess": true,
8
+ "esModuleInterop": true,
9
+ "skipLibCheck": true,
10
+ "types": ["vite/client"]
11
+ },
12
+ "include": ["src/**/*.ts", "src/**/*.svelte"],
13
+ "exclude": ["node_modules"]
14
+ }
@@ -0,0 +1,80 @@
1
+ import { copyFileSync, existsSync, readdirSync } from 'node:fs'
2
+ import { join, resolve } from 'node:path'
3
+ import tailwindcss from '@tailwindcss/vite'
4
+ import { svelte } from '@sveltejs/vite-plugin-svelte'
5
+ import type { Plugin } from 'vite'
6
+ import { defineConfig } from 'vite'
7
+
8
+ function crossOriginIsolation(): Plugin {
9
+ return {
10
+ name: 'cross-origin-isolation',
11
+ configureServer(server) {
12
+ server.middlewares.use((_req, res, next) => {
13
+ res.setHeader('Cross-Origin-Opener-Policy', 'same-origin')
14
+ res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp')
15
+ next()
16
+ })
17
+ },
18
+ configurePreviewServer(server) {
19
+ server.middlewares.use((_req, res, next) => {
20
+ res.setHeader('Cross-Origin-Opener-Policy', 'same-origin')
21
+ res.setHeader('Cross-Origin-Embedder-Policy', 'require-corp')
22
+ next()
23
+ })
24
+ },
25
+ }
26
+ }
27
+
28
+ function sqliteWasmHotfix(): Plugin {
29
+ return {
30
+ name: 'sqlite-wasm-hotfix',
31
+ apply: 'build',
32
+ closeBundle() {
33
+ const assetsDir = resolve('dist', 'assets')
34
+ if (!existsSync(assetsDir)) return
35
+
36
+ for (const file of readdirSync(assetsDir)) {
37
+ if (/^sqlite3-.+\.wasm$/.test(file)) {
38
+ copyFileSync(join(assetsDir, file), join(assetsDir, 'sqlite3.wasm'))
39
+ break
40
+ }
41
+ }
42
+
43
+ const proxyFile = resolve(
44
+ 'node_modules',
45
+ '@sqlite.org',
46
+ 'sqlite-wasm',
47
+ 'sqlite-wasm',
48
+ 'jswasm',
49
+ 'sqlite3-opfs-async-proxy.js',
50
+ )
51
+ if (existsSync(proxyFile)) {
52
+ copyFileSync(proxyFile, join(assetsDir, 'sqlite3-opfs-async-proxy.js'))
53
+ }
54
+ },
55
+ }
56
+ }
57
+
58
+ export default defineConfig({
59
+ plugins: [svelte(), tailwindcss(), crossOriginIsolation(), sqliteWasmHotfix()],
60
+ worker: {
61
+ format: 'es',
62
+ },
63
+ optimizeDeps: {
64
+ exclude: ['@sqlite.org/sqlite-wasm', '@korajs/store'],
65
+ include: ['yjs'],
66
+ },
67
+ resolve: {
68
+ dedupe: ['yjs'],
69
+ },
70
+ server: {
71
+ allowedHosts: true,
72
+ proxy: {
73
+ '/kora-sync': {
74
+ target: 'ws://localhost:3001',
75
+ ws: true,
76
+ rewriteWsOrigin: true,
77
+ },
78
+ },
79
+ },
80
+ })
@@ -5,3 +5,23 @@
5
5
 
6
6
  # Sync server port
7
7
  PORT=3001
8
+
9
+ # Server database
10
+ # Leave DATABASE_URL empty to use SQLite at KORA_SERVER_DB.
11
+ # Set DATABASE_URL for cloud Postgres deployments.
12
+ KORA_SERVER_DB=./kora-server.db
13
+ DATABASE_URL=
14
+
15
+ # Operational endpoints (/__kora, /__kora/status, /__kora/events, /__kora/metrics, backups)
16
+ # Set these in production. Use Authorization: Bearer <token> when calling protected endpoints.
17
+ KORA_ADMIN_TOKEN=
18
+ KORA_METRICS_TOKEN=
19
+ KORA_BACKUP_TOKEN=
20
+
21
+ # Optional sync path
22
+ KORA_SYNC_PATH=/kora-sync
23
+
24
+ # Auth
25
+ # Set this to enable built-in /auth/* routes and authenticated sync.
26
+ # Generate with: node -e "console.log(require('node:crypto').randomBytes(32).toString('hex'))"
27
+ KORA_AUTH_SECRET=
@@ -16,10 +16,17 @@ On first launch, you'll see a setup screen to enter your sync server URL. For lo
16
16
 
17
17
  ```
18
18
  src/
19
- schema.ts # Data schema definition
19
+ schema.ts # Schema entry point
20
+ auth.ts # Desktop auth client and OAuth callback helpers
20
21
  main.tsx # Entry point
21
22
  AppShell.tsx # Setup flow + Kora initialization
22
23
  App.tsx # Main application UI
24
+ modules/
25
+ todos/
26
+ todo.schema.ts # Todo collection definition
27
+ todo.queries.ts # Reusable todo query builders
28
+ todo.mutations.ts # Todo mutation helpers
29
+ useTodos.ts # React hook connecting todos to the UI
23
30
  SetupScreen.tsx # First-launch server configuration
24
31
  sync-config.ts # Runtime sync URL storage
25
32
  updater.ts # Auto-update checker
@@ -37,6 +44,9 @@ kora.config.ts # Kora configuration
37
44
  release-desktop.yml # CI/CD for cross-platform builds
38
45
  ```
39
46
 
47
+ In a feature module, `schema` defines data shape, `queries` contain reads only, `mutations` contain
48
+ writes, and `useTodos.ts` is the React binding that exposes todo data and actions to components.
49
+
40
50
  ## Scripts
41
51
 
42
52
  | Script | Description |
@@ -124,7 +134,32 @@ Users can also skip setup and use the app offline — they can connect later fro
124
134
  | Variable | Default | Description |
125
135
  |----------|---------|-------------|
126
136
  | `VITE_SYNC_URL` | (none) | Pre-configure sync URL at build time |
137
+ | `VITE_AUTH_URL` | derived from sync URL | HTTP URL for `/auth/*` routes |
127
138
  | `PORT` | `3001` | Sync server port |
139
+ | `KORA_SERVER_DB` | `./kora-server.db` | SQLite file used by the sync server when `DATABASE_URL` is empty |
140
+ | `KORA_AUTH_DB` | `./kora-auth.db` | SQLite file used by OAuth state and linked identities when `DATABASE_URL` is empty |
141
+ | `DATABASE_URL` | (none) | PostgreSQL connection string for production sync server deployments |
142
+ | `KORA_SYNC_PATH` | `/kora-sync` | WebSocket path exposed by the sync server |
143
+ | `KORA_AUTH_SECRET` | (none) | Enables built-in `/auth/*` routes and authenticated sync when set |
144
+ | `KORA_GOOGLE_CLIENT_ID` | (none) | Enables Google OAuth when set with `KORA_GOOGLE_REDIRECT_URI` |
145
+ | `KORA_GOOGLE_CLIENT_SECRET` | (none) | Google OAuth client secret for confidential web clients |
146
+ | `KORA_GOOGLE_REDIRECT_URI` | (none) | OAuth callback URL for loopback, custom scheme, or hosted handoff |
147
+ | `KORA_OAUTH_PKCE` | `true` when no client secret | Enables PKCE for public desktop/mobile OAuth clients |
148
+ | `KORA_ADMIN_TOKEN` | (none) | Protects `/__kora`, `/__kora/status`, and `/__kora/events` |
149
+ | `KORA_METRICS_TOKEN` | (none) | Protects `/__kora/metrics` |
150
+ | `KORA_BACKUP_TOKEN` | (none) | Protects server backup and restore endpoints |
151
+
152
+ ## Authentication
153
+
154
+ Set `KORA_AUTH_SECRET` to enable built-in auth on the sync server. Generate a secret with:
155
+
156
+ ```bash
157
+ node -e "console.log(require('node:crypto').randomBytes(32).toString('hex'))"
158
+ ```
159
+
160
+ The template creates a desktop auth client, wraps the app in `AuthProvider`, and wires sync with `createKoraAuthSync({ authClient, schema })`. Google OAuth is enabled on the server when `KORA_GOOGLE_CLIENT_ID` and `KORA_GOOGLE_REDIRECT_URI` are set.
161
+
162
+ For production desktop OAuth, use a loopback callback, custom URL scheme, or hosted handoff that returns `code` and `state` to the app, then complete the flow with `authClient.completeOAuthSignIn('google', { code, state })`. The generated `src/auth.ts` includes the callback completion helper. See the [Authentication Guide](https://ehoneahobed.github.io/kora/guide/authentication#desktop-and-tauri-apps).
128
163
 
129
164
  ## Code Signing
130
165
 
@@ -1,4 +1,4 @@
1
- import { spawn, type ChildProcess } from 'node:child_process'
1
+ import { type ChildProcess, spawn } from 'node:child_process'
2
2
 
3
3
  // Starts both the sync server and the Tauri app with a single command.
4
4
  // The sync server runs in the background so the desktop app can sync
@@ -7,10 +7,10 @@ import { spawn, type ChildProcess } from 'node:child_process'
7
7
  const children: ChildProcess[] = []
8
8
 
9
9
  function cleanup() {
10
- for (const child of children) {
11
- child.kill()
12
- }
13
- process.exit()
10
+ for (const child of children) {
11
+ child.kill()
12
+ }
13
+ process.exit()
14
14
  }
15
15
 
16
16
  process.on('SIGINT', cleanup)
@@ -18,20 +18,20 @@ process.on('SIGTERM', cleanup)
18
18
 
19
19
  // Start the sync server
20
20
  const syncServer = spawn('tsx', ['server.ts'], {
21
- stdio: 'inherit',
22
- shell: true,
21
+ stdio: 'inherit',
22
+ shell: true,
23
23
  })
24
24
  children.push(syncServer)
25
25
 
26
26
  // Start the Tauri app (manages Vite dev server + Rust build)
27
27
  const tauriApp = spawn('tauri', ['dev'], {
28
- stdio: 'inherit',
29
- shell: true,
28
+ stdio: 'inherit',
29
+ shell: true,
30
30
  })
31
31
  children.push(tauriApp)
32
32
 
33
33
  // If the Tauri app exits, stop everything
34
34
  tauriApp.on('close', (code) => {
35
- syncServer.kill()
36
- process.exit(code ?? 0)
35
+ syncServer.kill()
36
+ process.exit(code ?? 0)
37
37
  })
@@ -13,6 +13,7 @@
13
13
  },
14
14
  "dependencies": {
15
15
  "korajs": "{{koraVersion}}",
16
+ "@korajs/auth": "{{koraVersion}}",
16
17
  "@korajs/core": "{{koraVersion}}",
17
18
  "@korajs/react": "{{koraVersion}}",
18
19
  "@korajs/tauri": "{{koraVersion}}",
@@ -30,6 +31,7 @@
30
31
  "@types/react-dom": "^19.0.0",
31
32
  "@vitejs/plugin-react": "^4.3.0",
32
33
  "better-sqlite3": "^12.9.0",
34
+ "postgres": "^3.4.0",
33
35
  "tsx": "^4.19.0",
34
36
  "typescript": "^5.7.0",
35
37
  "vite": "^6.0.0",
@@ -1,4 +1,16 @@
1
- import { createProductionServer, createSqliteServerStore } from '@korajs/server'
1
+ import {
2
+ type CreateKoraAuthServerOptions,
3
+ createKoraAuthServer,
4
+ createPostgresOAuthStores,
5
+ createSqliteOAuthStores,
6
+ googleProvider,
7
+ } from '@korajs/auth/server'
8
+ import {
9
+ createPostgresServerStore,
10
+ createProductionServer,
11
+ createSqliteServerStore,
12
+ } from '@korajs/server'
13
+ import schema from './src/schema'
2
14
 
3
15
  // Sync server for your Kora desktop app.
4
16
  // Started automatically by `pnpm dev`, or run standalone with `pnpm dev:server`.
@@ -8,16 +20,78 @@ import { createProductionServer, createSqliteServerStore } from '@korajs/server'
8
20
  // For production, deploy this server and set VITE_SYNC_URL when building
9
21
  // the desktop app: VITE_SYNC_URL=wss://your-server.com/kora-sync pnpm build
10
22
 
11
- const store = createSqliteServerStore({ filename: './kora-server.db' })
23
+ async function createStore() {
24
+ if (process.env.DATABASE_URL) {
25
+ return createPostgresServerStore({
26
+ connectionString: process.env.DATABASE_URL,
27
+ })
28
+ }
12
29
 
13
- const server = createProductionServer({
14
- store,
15
- port: Number(process.env.PORT) || 3001,
16
- staticDir: './dist',
17
- syncPath: '/kora-sync',
18
- })
30
+ return createSqliteServerStore({
31
+ filename: process.env.KORA_SERVER_DB || './kora-server.db',
32
+ })
33
+ }
19
34
 
20
- server.start().then((url) => {
21
- console.log(`Kora sync server running at ${url}`)
22
- console.log(` Sync endpoint: ${url.replace('http', 'ws')}/kora-sync`)
23
- })
35
+ async function start() {
36
+ const store = await createStore()
37
+ await store.setSchema(schema)
38
+
39
+ const syncPath = process.env.KORA_SYNC_PATH || '/kora-sync'
40
+ const auth = await createAuth()
41
+ const server = createProductionServer({
42
+ store,
43
+ port: Number(process.env.PORT) || 3001,
44
+ syncPath,
45
+ httpRoutes: auth ? [{ path: '/auth', handle: auth.handleRequest }] : undefined,
46
+ syncOptions: auth ? { auth: auth.auth } : undefined,
47
+ operationalAuth: {
48
+ adminToken: process.env.KORA_ADMIN_TOKEN,
49
+ metricsToken: process.env.KORA_METRICS_TOKEN,
50
+ backupToken: process.env.KORA_BACKUP_TOKEN,
51
+ },
52
+ })
53
+
54
+ const url = await server.start()
55
+ console.log(`Kora sync server running at ${url}`)
56
+ console.log(` Sync endpoint: ${url.replace('http', 'ws')}${syncPath}`)
57
+ if (auth) console.log(` Auth endpoint: ${url}/auth`)
58
+ }
59
+
60
+ void start()
61
+
62
+ async function createAuth() {
63
+ if (!process.env.KORA_AUTH_SECRET) {
64
+ return null
65
+ }
66
+
67
+ const oauth = await createOAuthConfig()
68
+ return createKoraAuthServer({
69
+ jwtSecret: process.env.KORA_AUTH_SECRET,
70
+ ...(oauth ? { oauth } : {}),
71
+ })
72
+ }
73
+
74
+ async function createOAuthConfig(): Promise<CreateKoraAuthServerOptions['oauth'] | undefined> {
75
+ if (!process.env.KORA_GOOGLE_CLIENT_ID || !process.env.KORA_GOOGLE_REDIRECT_URI) {
76
+ return undefined
77
+ }
78
+
79
+ const oauthStores = process.env.DATABASE_URL
80
+ ? await createPostgresOAuthStores({ connectionString: process.env.DATABASE_URL })
81
+ : await createSqliteOAuthStores({
82
+ filename: process.env.KORA_AUTH_DB || './kora-auth.db',
83
+ })
84
+
85
+ return {
86
+ providers: [
87
+ googleProvider({
88
+ clientId: process.env.KORA_GOOGLE_CLIENT_ID,
89
+ clientSecret: process.env.KORA_GOOGLE_CLIENT_SECRET,
90
+ redirectUri: process.env.KORA_GOOGLE_REDIRECT_URI,
91
+ pkce: process.env.KORA_OAUTH_PKCE === 'true' || !process.env.KORA_GOOGLE_CLIENT_SECRET,
92
+ }),
93
+ ],
94
+ stateStore: oauthStores.stateStore,
95
+ linkedIdentityStore: oauthStores.linkedIdentityStore,
96
+ }
97
+ }