@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
package/dist/index.d.cts CHANGED
@@ -5,7 +5,7 @@ import * as citty from 'citty';
5
5
  declare const PACKAGE_MANAGERS: readonly ["pnpm", "npm", "yarn", "bun"];
6
6
  type PackageManager = (typeof PACKAGE_MANAGERS)[number];
7
7
  /** Available project templates */
8
- declare const TEMPLATES: readonly ["react-tailwind-sync", "react-tailwind", "react-sync", "react-basic", "tauri-react"];
8
+ declare const TEMPLATES: readonly ["react-tailwind-sync", "react-tailwind", "react-sync", "react-basic", "vue-sync", "vue-basic", "vue-tailwind-sync", "vue-tailwind", "svelte-sync", "svelte-basic", "svelte-tailwind-sync", "svelte-tailwind", "tauri-react"];
9
9
  type TemplateName = (typeof TEMPLATES)[number];
10
10
  /** Metadata for a project template */
11
11
  interface TemplateInfo {
@@ -117,6 +117,7 @@ interface ProjectConfig {
117
117
  region: string | null;
118
118
  environment: 'preview' | 'production';
119
119
  confirm: boolean;
120
+ deployTarget?: 'full-stack' | 'sync-server';
120
121
  }
121
122
  interface ProvisionResult {
122
123
  applicationId: string;
@@ -425,7 +426,7 @@ declare function resetDeployState(projectRoot: string): Promise<void>;
425
426
  interface DockerfileOptions {
426
427
  nodeVersion?: string;
427
428
  port?: number;
428
- clientDirectory?: string;
429
+ clientDirectory?: string | null;
429
430
  serverBundleFile?: string;
430
431
  /** Native modules that must be installed at runtime (externalized from bundle). */
431
432
  nativeDependencies?: Record<string, string>;
@@ -555,13 +556,13 @@ type DatabaseOption = 'none' | 'sqlite' | 'postgres';
555
556
  type DatabaseProviderOption = 'none' | 'local' | 'supabase' | 'neon' | 'railway' | 'vercel-postgres' | 'custom';
556
557
  interface TemplateSelectionInput {
557
558
  platform: PlatformOption;
559
+ framework: FrameworkOption;
558
560
  tailwind: boolean;
559
561
  sync: boolean;
560
562
  db: DatabaseOption;
561
563
  }
562
564
  /**
563
- * Converts high-level scaffold selections into the currently supported
564
- * concrete template names.
565
+ * Converts high-level scaffold selections into a concrete template name.
565
566
  */
566
567
  declare function determineTemplateFromSelections(input: TemplateSelectionInput): TemplateName;
567
568
  declare function isFrameworkValue(value: string): value is FrameworkOption;
@@ -685,8 +686,9 @@ interface SyncProviderPresetOptions {
685
686
  /**
686
687
  * Applies provider-specific sync scaffolding adjustments after template copy.
687
688
  *
688
- * This is a lightweight bridge until template-layer composition lands.
689
- * Today we only specialize the sync server template when Postgres is selected.
689
+ * The sync server template is environment-driven: SQLite is used when
690
+ * DATABASE_URL is absent, and PostgreSQL is used when DATABASE_URL is present.
691
+ * Provider presets only add provider-specific guidance.
690
692
  */
691
693
  declare function applySyncProviderPreset(options: SyncProviderPresetOptions): Promise<void>;
692
694
 
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@ import * as citty from 'citty';
5
5
  declare const PACKAGE_MANAGERS: readonly ["pnpm", "npm", "yarn", "bun"];
6
6
  type PackageManager = (typeof PACKAGE_MANAGERS)[number];
7
7
  /** Available project templates */
8
- declare const TEMPLATES: readonly ["react-tailwind-sync", "react-tailwind", "react-sync", "react-basic", "tauri-react"];
8
+ declare const TEMPLATES: readonly ["react-tailwind-sync", "react-tailwind", "react-sync", "react-basic", "vue-sync", "vue-basic", "vue-tailwind-sync", "vue-tailwind", "svelte-sync", "svelte-basic", "svelte-tailwind-sync", "svelte-tailwind", "tauri-react"];
9
9
  type TemplateName = (typeof TEMPLATES)[number];
10
10
  /** Metadata for a project template */
11
11
  interface TemplateInfo {
@@ -117,6 +117,7 @@ interface ProjectConfig {
117
117
  region: string | null;
118
118
  environment: 'preview' | 'production';
119
119
  confirm: boolean;
120
+ deployTarget?: 'full-stack' | 'sync-server';
120
121
  }
121
122
  interface ProvisionResult {
122
123
  applicationId: string;
@@ -425,7 +426,7 @@ declare function resetDeployState(projectRoot: string): Promise<void>;
425
426
  interface DockerfileOptions {
426
427
  nodeVersion?: string;
427
428
  port?: number;
428
- clientDirectory?: string;
429
+ clientDirectory?: string | null;
429
430
  serverBundleFile?: string;
430
431
  /** Native modules that must be installed at runtime (externalized from bundle). */
431
432
  nativeDependencies?: Record<string, string>;
@@ -555,13 +556,13 @@ type DatabaseOption = 'none' | 'sqlite' | 'postgres';
555
556
  type DatabaseProviderOption = 'none' | 'local' | 'supabase' | 'neon' | 'railway' | 'vercel-postgres' | 'custom';
556
557
  interface TemplateSelectionInput {
557
558
  platform: PlatformOption;
559
+ framework: FrameworkOption;
558
560
  tailwind: boolean;
559
561
  sync: boolean;
560
562
  db: DatabaseOption;
561
563
  }
562
564
  /**
563
- * Converts high-level scaffold selections into the currently supported
564
- * concrete template names.
565
+ * Converts high-level scaffold selections into a concrete template name.
565
566
  */
566
567
  declare function determineTemplateFromSelections(input: TemplateSelectionInput): TemplateName;
567
568
  declare function isFrameworkValue(value: string): value is FrameworkOption;
@@ -685,8 +686,9 @@ interface SyncProviderPresetOptions {
685
686
  /**
686
687
  * Applies provider-specific sync scaffolding adjustments after template copy.
687
688
  *
688
- * This is a lightweight bridge until template-layer composition lands.
689
- * Today we only specialize the sync server template when Postgres is selected.
689
+ * The sync server template is environment-driven: SQLite is used when
690
+ * DATABASE_URL is absent, and PostgreSQL is used when DATABASE_URL is present.
691
+ * Provider presets only add provider-specific guidance.
690
692
  */
691
693
  declare function applySyncProviderPreset(options: SyncProviderPresetOptions): Promise<void>;
692
694
 
package/dist/index.js CHANGED
@@ -27,7 +27,7 @@ import {
27
27
  writeDockerfileArtifact,
28
28
  writeFlyTomlArtifact,
29
29
  writeRailwayJsonArtifact
30
- } from "./chunk-YGVO4POI.js";
30
+ } from "./chunk-Q2FBCOQD.js";
31
31
  import {
32
32
  ClackPromptClient,
33
33
  CliError,
@@ -54,7 +54,7 @@ import {
54
54
  saveResolvedPreferences,
55
55
  shouldSavePreferences,
56
56
  validateProjectName
57
- } from "./chunk-CMSX76KM.js";
57
+ } from "./chunk-VLTPEATY.js";
58
58
  export {
59
59
  ClackPromptClient,
60
60
  CliError,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@korajs/cli",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "Kora.js CLI tooling and project scaffolding",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -36,14 +36,20 @@
36
36
  "conf": "^15.1.0",
37
37
  "esbuild": "^0.28.0",
38
38
  "validate-npm-package-name": "^7.0.2",
39
- "@korajs/core": "0.4.0"
39
+ "@korajs/core": "0.6.0"
40
40
  },
41
41
  "devDependencies": {
42
+ "@types/better-sqlite3": "^7.6.13",
42
43
  "@types/node": "^25.5.2",
43
44
  "@types/validate-npm-package-name": "^4.0.2",
45
+ "better-sqlite3": "^12.8.0",
44
46
  "tsup": "^8.3.6",
45
47
  "typescript": "^5.7.3",
46
- "vitest": "^3.0.4"
48
+ "vitest": "^3.0.4",
49
+ "@korajs/merge": "0.6.0",
50
+ "@korajs/store": "0.6.0",
51
+ "@korajs/sync": "0.6.0",
52
+ "korajs": "0.6.0"
47
53
  },
48
54
  "license": "MIT",
49
55
  "scripts": {
@@ -14,14 +14,23 @@ npm run dev
14
14
 
15
15
  ```
16
16
  src/
17
- schema.ts # Data schema definition
17
+ schema.ts # Schema entry point
18
18
  main.tsx # App initialization and Kora setup
19
19
  App.tsx # Main application component
20
+ modules/
21
+ todos/
22
+ todo.schema.ts # Todo collection definition
23
+ todo.queries.ts # Reusable todo query builders
24
+ todo.mutations.ts # Todo mutation helpers
25
+ useTodos.ts # React hook connecting todos to the UI
20
26
  kora-worker.ts # SQLite WASM web worker
21
27
  index.css # Styles
22
28
  kora.config.ts # Kora configuration
23
29
  ```
24
30
 
31
+ In a feature module, `schema` defines data shape, `queries` contain reads only, `mutations` contain
32
+ writes, and `useTodos.ts` is the React binding that exposes todo data and actions to components.
33
+
25
34
  ## Scripts
26
35
 
27
36
  | Script | Description |
@@ -1,146 +1,132 @@
1
1
  import { useState } from 'react'
2
- import { useQuery, useMutation, useCollection } from '@korajs/react'
2
+ import { useTodos } from './modules/todos/useTodos'
3
3
 
4
4
  type Filter = 'all' | 'active' | 'completed'
5
5
 
6
6
  export function App() {
7
- const todos = useCollection('todos')
8
- const allTodos = useQuery(todos.where({}).orderBy('createdAt', 'desc'))
9
- const { mutate: addTodo } = useMutation(
10
- (data: { title: string }) => todos.insert(data)
11
- )
12
- const { mutate: toggleTodo } = useMutation(
13
- (id: string, data: { completed: boolean }) => todos.update(id, data)
14
- )
15
- const { mutate: deleteTodo } = useMutation(
16
- (id: string) => todos.delete(id)
17
- )
7
+ const { allTodos, activeTodos, completedTodos, addTodo, toggleTodo, deleteTodo } = useTodos()
18
8
 
19
- const [filter, setFilter] = useState<Filter>('all')
20
- const [input, setInput] = useState('')
9
+ const [filter, setFilter] = useState<Filter>('all')
10
+ const [input, setInput] = useState('')
21
11
 
22
- const activeTodos = allTodos.filter((t) => !t.completed)
23
- const completedTodos = allTodos.filter((t) => !!t.completed)
24
- const filteredTodos =
25
- filter === 'active' ? activeTodos : filter === 'completed' ? completedTodos : allTodos
12
+ const filteredTodos =
13
+ filter === 'active' ? activeTodos : filter === 'completed' ? completedTodos : allTodos
26
14
 
27
- const handleSubmit = (e: React.FormEvent) => {
28
- e.preventDefault()
29
- const title = input.trim()
30
- if (title) {
31
- addTodo({ title })
32
- setInput('')
33
- }
34
- }
15
+ const handleSubmit = (e: React.FormEvent) => {
16
+ e.preventDefault()
17
+ const title = input.trim()
18
+ if (title) {
19
+ addTodo.mutate({ title })
20
+ setInput('')
21
+ }
22
+ }
35
23
 
36
- const clearCompleted = () => {
37
- for (const todo of completedTodos) {
38
- deleteTodo(todo.id)
39
- }
40
- }
24
+ const clearCompleted = () => {
25
+ for (const todo of completedTodos) {
26
+ deleteTodo.mutate(todo.id)
27
+ }
28
+ }
41
29
 
42
- return (
43
- <div className="app">
44
- <div className="header">
45
- <h1>My Tasks</h1>
46
- <span className="local-badge">Local-first</span>
47
- </div>
30
+ return (
31
+ <div className="app">
32
+ <div className="header">
33
+ <h1>My Tasks</h1>
34
+ <span className="local-badge">Local-first</span>
35
+ </div>
48
36
 
49
- <div className="stats">
50
- <div className="stat-card">
51
- <div className="label">Total</div>
52
- <div className="value muted">{allTodos.length}</div>
53
- </div>
54
- <div className="stat-card">
55
- <div className="label">Remaining</div>
56
- <div className="value warning">{activeTodos.length}</div>
57
- </div>
58
- <div className="stat-card">
59
- <div className="label">Done</div>
60
- <div className="value success">{completedTodos.length}</div>
61
- </div>
62
- </div>
37
+ <div className="stats">
38
+ <div className="stat-card">
39
+ <div className="label">Total</div>
40
+ <div className="value muted">{allTodos.length}</div>
41
+ </div>
42
+ <div className="stat-card">
43
+ <div className="label">Remaining</div>
44
+ <div className="value warning">{activeTodos.length}</div>
45
+ </div>
46
+ <div className="stat-card">
47
+ <div className="label">Done</div>
48
+ <div className="value success">{completedTodos.length}</div>
49
+ </div>
50
+ </div>
63
51
 
64
- <form className="add-form" onSubmit={handleSubmit}>
65
- <input
66
- type="text"
67
- value={input}
68
- onChange={(e) => setInput(e.target.value)}
69
- placeholder="What needs to be done?"
70
- />
71
- <button type="submit" disabled={!input.trim()}>
72
- Add
73
- </button>
74
- </form>
52
+ <form className="add-form" onSubmit={handleSubmit}>
53
+ <input
54
+ type="text"
55
+ value={input}
56
+ onChange={(e) => setInput(e.target.value)}
57
+ placeholder="What needs to be done?"
58
+ />
59
+ <button type="submit" disabled={!input.trim()}>
60
+ Add
61
+ </button>
62
+ </form>
75
63
 
76
- <div className="filters">
77
- {(['all', 'active', 'completed'] as const).map((f) => {
78
- const count = f === 'all' ? allTodos.length : f === 'active' ? activeTodos.length : completedTodos.length
79
- return (
80
- <button
81
- key={f}
82
- className={`filter-btn ${filter === f ? 'active' : ''}`}
83
- onClick={() => setFilter(f)}
84
- >
85
- {f.charAt(0).toUpperCase() + f.slice(1)}
86
- <span className="badge">{count}</span>
87
- </button>
88
- )
89
- })}
90
- </div>
64
+ <div className="filters">
65
+ {(['all', 'active', 'completed'] as const).map((f) => {
66
+ const count =
67
+ f === 'all'
68
+ ? allTodos.length
69
+ : f === 'active'
70
+ ? activeTodos.length
71
+ : completedTodos.length
72
+ return (
73
+ <button
74
+ key={f}
75
+ className={`filter-btn ${filter === f ? 'active' : ''}`}
76
+ onClick={() => setFilter(f)}
77
+ >
78
+ {f.charAt(0).toUpperCase() + f.slice(1)}
79
+ <span className="badge">{count}</span>
80
+ </button>
81
+ )
82
+ })}
83
+ </div>
91
84
 
92
- <div className="todo-list">
93
- {filteredTodos.length === 0 ? (
94
- <div className="empty-state">
95
- {filter === 'all' && 'No tasks yet. Add one above!'}
96
- {filter === 'active' && 'All caught up! No active tasks.'}
97
- {filter === 'completed' && 'No completed tasks yet.'}
98
- </div>
99
- ) : (
100
- filteredTodos.map((todo) => (
101
- <div key={todo.id} className="todo-item">
102
- <button
103
- className={`toggle ${todo.completed ? 'checked' : ''}`}
104
- onClick={() => toggleTodo(todo.id, { completed: !todo.completed })}
105
- >
106
- {todo.completed ? '\u2713' : ''}
107
- </button>
108
- <span className={`title ${todo.completed ? 'done' : ''}`}>
109
- {String(todo.title)}
110
- </span>
111
- {todo.createdAt && (
112
- <span className="time">{formatTime(Number(todo.createdAt))}</span>
113
- )}
114
- <button
115
- className="delete-btn"
116
- onClick={() => deleteTodo(todo.id)}
117
- >
118
- \u00d7
119
- </button>
120
- </div>
121
- ))
122
- )}
123
- </div>
85
+ <div className="todo-list">
86
+ {filteredTodos.length === 0 ? (
87
+ <div className="empty-state">
88
+ {filter === 'all' && 'No tasks yet. Add one above!'}
89
+ {filter === 'active' && 'All caught up! No active tasks.'}
90
+ {filter === 'completed' && 'No completed tasks yet.'}
91
+ </div>
92
+ ) : (
93
+ filteredTodos.map((todo) => (
94
+ <div key={todo.id} className="todo-item">
95
+ <button
96
+ className={`toggle ${todo.completed ? 'checked' : ''}`}
97
+ onClick={() => toggleTodo.mutate(todo.id, { completed: !todo.completed })}
98
+ >
99
+ {todo.completed ? '\u2713' : ''}
100
+ </button>
101
+ <span className={`title ${todo.completed ? 'done' : ''}`}>{String(todo.title)}</span>
102
+ {todo.createdAt && <span className="time">{formatTime(Number(todo.createdAt))}</span>}
103
+ <button className="delete-btn" onClick={() => deleteTodo.mutate(todo.id)}>
104
+ \u00d7
105
+ </button>
106
+ </div>
107
+ ))
108
+ )}
109
+ </div>
124
110
 
125
- {allTodos.length > 0 && (
126
- <div className="footer">
127
- <span>{activeTodos.length} item{activeTodos.length !== 1 ? 's' : ''} left</span>
128
- {completedTodos.length > 0 && (
129
- <button onClick={clearCompleted}>Clear completed</button>
130
- )}
131
- </div>
132
- )}
111
+ {allTodos.length > 0 && (
112
+ <div className="footer">
113
+ <span>
114
+ {activeTodos.length} item{activeTodos.length !== 1 ? 's' : ''} left
115
+ </span>
116
+ {completedTodos.length > 0 && <button onClick={clearCompleted}>Clear completed</button>}
117
+ </div>
118
+ )}
133
119
 
134
- <p className="branding">Powered by Kora &mdash; offline-first, real-time sync</p>
135
- </div>
136
- )
120
+ <p className="branding">Powered by Kora &mdash; offline-first, real-time sync</p>
121
+ </div>
122
+ )
137
123
  }
138
124
 
139
125
  function formatTime(timestamp: number): string {
140
- const date = new Date(timestamp)
141
- const now = new Date()
142
- if (date.toDateString() === now.toDateString()) {
143
- return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
144
- }
145
- return date.toLocaleDateString([], { month: 'short', day: 'numeric' })
126
+ const date = new Date(timestamp)
127
+ const now = new Date()
128
+ if (date.toDateString() === now.toDateString()) {
129
+ return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
130
+ }
131
+ return date.toLocaleDateString([], { month: 'short', day: 'numeric' })
146
132
  }