@korajs/cli 0.3.2 → 0.3.4

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 (48) hide show
  1. package/dist/bin.cjs +120 -67
  2. package/dist/bin.cjs.map +1 -1
  3. package/dist/bin.js +3 -3
  4. package/dist/{chunk-KTSRAPSE.js → chunk-HNVCNPER.js} +105 -65
  5. package/dist/chunk-HNVCNPER.js.map +1 -0
  6. package/dist/{chunk-E7OCVRYL.js → chunk-MIMLCXSX.js} +2 -2
  7. package/dist/{chunk-ZGYRDYXS.js → chunk-ULTO5NFA.js} +22 -4
  8. package/dist/chunk-ULTO5NFA.js.map +1 -0
  9. package/dist/create.cjs +119 -66
  10. package/dist/create.cjs.map +1 -1
  11. package/dist/create.js +2 -2
  12. package/dist/index.cjs +105 -65
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.cts +6 -1
  15. package/dist/index.d.ts +6 -1
  16. package/dist/index.js +2 -2
  17. package/package.json +1 -1
  18. package/templates/tauri-react/.env.example +7 -0
  19. package/templates/tauri-react/.github/workflows/release-desktop.yml +107 -0
  20. package/templates/tauri-react/README.md.hbs +148 -0
  21. package/templates/tauri-react/dev.ts +37 -0
  22. package/templates/tauri-react/index.html.hbs +16 -0
  23. package/templates/tauri-react/kora.config.ts +17 -0
  24. package/templates/tauri-react/package.json.hbs +44 -0
  25. package/templates/tauri-react/server.ts +23 -0
  26. package/templates/tauri-react/src/App.tsx +578 -0
  27. package/templates/tauri-react/src/AppShell.tsx +116 -0
  28. package/templates/tauri-react/src/SetupScreen.tsx +239 -0
  29. package/templates/tauri-react/src/main.tsx +9 -0
  30. package/templates/tauri-react/src/schema.ts +15 -0
  31. package/templates/tauri-react/src/sync-config.ts +103 -0
  32. package/templates/tauri-react/src/updater.ts +38 -0
  33. package/templates/tauri-react/src-tauri/Cargo.toml +19 -0
  34. package/templates/tauri-react/src-tauri/build.rs +3 -0
  35. package/templates/tauri-react/src-tauri/capabilities/default.json +12 -0
  36. package/templates/tauri-react/src-tauri/icons/128x128.png +0 -0
  37. package/templates/tauri-react/src-tauri/icons/128x128@2x.png +0 -0
  38. package/templates/tauri-react/src-tauri/icons/32x32.png +0 -0
  39. package/templates/tauri-react/src-tauri/icons/icon.icns +0 -0
  40. package/templates/tauri-react/src-tauri/icons/icon.ico +0 -0
  41. package/templates/tauri-react/src-tauri/src/lib.rs +8 -0
  42. package/templates/tauri-react/src-tauri/src/main.rs +6 -0
  43. package/templates/tauri-react/src-tauri/tauri.conf.json +44 -0
  44. package/templates/tauri-react/tsconfig.json +15 -0
  45. package/templates/tauri-react/vite.config.ts +15 -0
  46. package/dist/chunk-KTSRAPSE.js.map +0 -1
  47. package/dist/chunk-ZGYRDYXS.js.map +0 -1
  48. /package/dist/{chunk-E7OCVRYL.js.map → chunk-MIMLCXSX.js.map} +0 -0
package/dist/bin.cjs CHANGED
@@ -88,6 +88,7 @@ var DevServerError = class extends import_core.KoraError {
88
88
  // src/prompts/preferences.ts
89
89
  var import_conf = __toESM(require("conf"), 1);
90
90
  var DEFAULT_PREFERENCES = {
91
+ platform: "web",
91
92
  framework: "react",
92
93
  tailwind: true,
93
94
  sync: true,
@@ -294,7 +295,8 @@ var TEMPLATES = [
294
295
  "react-tailwind-sync",
295
296
  "react-tailwind",
296
297
  "react-sync",
297
- "react-basic"
298
+ "react-basic",
299
+ "tauri-react"
298
300
  ];
299
301
 
300
302
  // src/utils/fs-helpers.ts
@@ -562,12 +564,16 @@ async function findNearestAncestorWithEntry(startDir, entryName) {
562
564
 
563
565
  // src/commands/create/options.ts
564
566
  function determineTemplateFromSelections(input) {
567
+ if (input.platform === "desktop-tauri") return "tauri-react";
565
568
  const shouldSync = input.sync && input.db !== "none";
566
569
  if (input.tailwind && shouldSync) return "react-tailwind-sync";
567
570
  if (input.tailwind && !shouldSync) return "react-tailwind";
568
571
  if (!input.tailwind && shouldSync) return "react-sync";
569
572
  return "react-basic";
570
573
  }
574
+ function isPlatformValue(value) {
575
+ return value === "web" || value === "desktop-tauri";
576
+ }
571
577
  function isFrameworkValue(value) {
572
578
  return value === "react" || value === "vue" || value === "svelte" || value === "solid";
573
579
  }
@@ -602,83 +608,108 @@ async function resolveCreatePreferencesFlow(params) {
602
608
  usedStoredPreferences = true;
603
609
  }
604
610
  }
605
- if (flags.framework !== void 0) {
606
- if (!isFrameworkValue(flags.framework)) {
607
- throw new Error(
608
- `Invalid --framework value "${flags.framework}". Expected one of: react, vue, svelte, solid.`
609
- );
610
- }
611
- effective.framework = flags.framework;
612
- } else if (!flags.useDefaults && !usedStoredPreferences) {
613
- effective.framework = await prompts.select("UI framework:", [
614
- { label: "React", value: "react" },
615
- { label: "Vue (coming soon)", value: "vue", disabled: true },
616
- { label: "Svelte (coming soon)", value: "svelte", disabled: true },
617
- { label: "Solid (coming soon)", value: "solid", disabled: true }
618
- ]);
619
- }
620
- if (flags.auth !== void 0) {
621
- if (!isAuthValue(flags.auth)) {
611
+ if (flags.platform !== void 0) {
612
+ if (!isPlatformValue(flags.platform)) {
622
613
  throw new Error(
623
- `Invalid --auth value "${flags.auth}". Expected one of: none, email-password, oauth.`
614
+ `Invalid --platform value "${flags.platform}". Expected one of: web, desktop-tauri.`
624
615
  );
625
616
  }
626
- effective.auth = flags.auth;
617
+ effective.platform = flags.platform;
627
618
  } else if (!flags.useDefaults && !usedStoredPreferences) {
628
- effective.auth = await prompts.select("Authentication:", [
629
- { label: "None", value: "none" },
630
- { label: "Email + Password (coming soon)", value: "email-password", disabled: true },
631
- { label: "OAuth (coming soon)", value: "oauth", disabled: true }
619
+ effective.platform = await prompts.select("Platform:", [
620
+ { label: "Web (browser)", value: "web" },
621
+ { label: "Desktop (Tauri \u2014 native SQLite)", value: "desktop-tauri" }
632
622
  ]);
633
623
  }
634
- if (flags.tailwind !== void 0) {
635
- effective.tailwind = flags.tailwind;
636
- } else if (!flags.useDefaults && !usedStoredPreferences) {
637
- effective.tailwind = await prompts.confirm("Use Tailwind CSS?", true);
638
- }
639
- if (flags.sync !== void 0) {
640
- effective.sync = flags.sync;
641
- } else if (!flags.useDefaults && !usedStoredPreferences) {
642
- effective.sync = await prompts.confirm("Enable multi-device sync?", true);
643
- }
644
- if (flags.db !== void 0) {
645
- if (!isDatabaseValue(flags.db)) {
646
- throw new Error(`Invalid --db value "${flags.db}". Expected one of: none, sqlite, postgres.`);
647
- }
648
- effective.db = flags.db;
649
- } else if (!effective.sync) {
650
- effective.db = "none";
651
- } else if (!flags.useDefaults && !usedStoredPreferences) {
652
- effective.db = await prompts.select("Server-side database:", [
653
- { label: "SQLite (zero-config)", value: "sqlite" },
654
- { label: "PostgreSQL (production-scale)", value: "postgres" }
655
- ]);
656
- }
657
- if (effective.db !== "postgres") {
624
+ const isTauri = effective.platform === "desktop-tauri";
625
+ if (isTauri) {
626
+ effective.framework = "react";
627
+ effective.tailwind = false;
628
+ effective.sync = true;
629
+ effective.db = "sqlite";
658
630
  effective.dbProvider = "none";
659
- } else if (flags.dbProvider !== void 0) {
660
- if (!isDatabaseProviderValue(flags.dbProvider)) {
661
- throw new Error(
662
- `Invalid --db-provider value "${flags.dbProvider}". Expected one of: none, local, supabase, neon, railway, vercel-postgres, custom.`
663
- );
631
+ effective.auth = "none";
632
+ } else {
633
+ if (flags.framework !== void 0) {
634
+ if (!isFrameworkValue(flags.framework)) {
635
+ throw new Error(
636
+ `Invalid --framework value "${flags.framework}". Expected one of: react, vue, svelte, solid.`
637
+ );
638
+ }
639
+ effective.framework = flags.framework;
640
+ } else if (!flags.useDefaults && !usedStoredPreferences) {
641
+ effective.framework = await prompts.select("UI framework:", [
642
+ { label: "React", value: "react" },
643
+ { label: "Vue (coming soon)", value: "vue", disabled: true },
644
+ { label: "Svelte (coming soon)", value: "svelte", disabled: true },
645
+ { label: "Solid (coming soon)", value: "solid", disabled: true }
646
+ ]);
647
+ }
648
+ if (flags.auth !== void 0) {
649
+ if (!isAuthValue(flags.auth)) {
650
+ throw new Error(
651
+ `Invalid --auth value "${flags.auth}". Expected one of: none, email-password, oauth.`
652
+ );
653
+ }
654
+ effective.auth = flags.auth;
655
+ } else if (!flags.useDefaults && !usedStoredPreferences) {
656
+ effective.auth = await prompts.select("Authentication:", [
657
+ { label: "None", value: "none" },
658
+ { label: "Email + Password (coming soon)", value: "email-password", disabled: true },
659
+ { label: "OAuth (coming soon)", value: "oauth", disabled: true }
660
+ ]);
661
+ }
662
+ if (flags.tailwind !== void 0) {
663
+ effective.tailwind = flags.tailwind;
664
+ } else if (!flags.useDefaults && !usedStoredPreferences) {
665
+ effective.tailwind = await prompts.confirm("Use Tailwind CSS?", true);
666
+ }
667
+ if (flags.sync !== void 0) {
668
+ effective.sync = flags.sync;
669
+ } else if (!flags.useDefaults && !usedStoredPreferences) {
670
+ effective.sync = await prompts.confirm("Enable multi-device sync?", true);
671
+ }
672
+ if (flags.db !== void 0) {
673
+ if (!isDatabaseValue(flags.db)) {
674
+ throw new Error(`Invalid --db value "${flags.db}". Expected one of: none, sqlite, postgres.`);
675
+ }
676
+ effective.db = flags.db;
677
+ } else if (!effective.sync) {
678
+ effective.db = "none";
679
+ } else if (!flags.useDefaults && !usedStoredPreferences) {
680
+ effective.db = await prompts.select("Server-side database:", [
681
+ { label: "SQLite (zero-config)", value: "sqlite" },
682
+ { label: "PostgreSQL (production-scale)", value: "postgres" }
683
+ ]);
684
+ }
685
+ if (effective.db !== "postgres") {
686
+ effective.dbProvider = "none";
687
+ } else if (flags.dbProvider !== void 0) {
688
+ if (!isDatabaseProviderValue(flags.dbProvider)) {
689
+ throw new Error(
690
+ `Invalid --db-provider value "${flags.dbProvider}". Expected one of: none, local, supabase, neon, railway, vercel-postgres, custom.`
691
+ );
692
+ }
693
+ effective.dbProvider = flags.dbProvider;
694
+ } else if (!flags.useDefaults && !usedStoredPreferences) {
695
+ effective.dbProvider = await prompts.select("Database provider:", [
696
+ { label: "Local Postgres", value: "local" },
697
+ { label: "Supabase", value: "supabase" },
698
+ { label: "Neon", value: "neon" },
699
+ { label: "Railway", value: "railway" },
700
+ { label: "Vercel Postgres", value: "vercel-postgres" },
701
+ { label: "Custom connection string", value: "custom" }
702
+ ]);
664
703
  }
665
- effective.dbProvider = flags.dbProvider;
666
- } else if (!flags.useDefaults && !usedStoredPreferences) {
667
- effective.dbProvider = await prompts.select("Database provider:", [
668
- { label: "Local Postgres", value: "local" },
669
- { label: "Supabase", value: "supabase" },
670
- { label: "Neon", value: "neon" },
671
- { label: "Railway", value: "railway" },
672
- { label: "Vercel Postgres", value: "vercel-postgres" },
673
- { label: "Custom connection string", value: "custom" }
674
- ]);
675
704
  }
676
705
  const template = determineTemplateFromSelections({
706
+ platform: effective.platform,
677
707
  tailwind: effective.tailwind,
678
708
  sync: effective.sync,
679
709
  db: effective.db
680
710
  });
681
711
  return {
712
+ platform: effective.platform,
682
713
  framework: effective.framework,
683
714
  auth: effective.auth,
684
715
  db: effective.db,
@@ -694,6 +725,7 @@ function shouldSavePreferences(flags) {
694
725
  }
695
726
  function saveResolvedPreferences(store, resolution) {
696
727
  store.saveCreatePreferences({
728
+ platform: resolution.platform,
697
729
  framework: resolution.framework,
698
730
  tailwind: resolution.tailwind,
699
731
  sync: resolution.sync,
@@ -704,12 +736,15 @@ function saveResolvedPreferences(store, resolution) {
704
736
  });
705
737
  }
706
738
  function hasExplicitPreferenceFlags(flags) {
707
- return flags.framework !== void 0 || flags.auth !== void 0 || flags.db !== void 0 || flags.dbProvider !== void 0 || flags.tailwind !== void 0 || flags.sync !== void 0;
739
+ return flags.platform !== void 0 || flags.framework !== void 0 || flags.auth !== void 0 || flags.db !== void 0 || flags.dbProvider !== void 0 || flags.tailwind !== void 0 || flags.sync !== void 0;
708
740
  }
709
741
  function promptSupportsRichOptions() {
710
742
  return typeof process !== "undefined" && process.stdin.isTTY && process.stdout.isTTY;
711
743
  }
712
744
  function formatStoredPreferenceLabel(preferences) {
745
+ if (preferences.platform === "desktop-tauri") {
746
+ return `Use previous settings (tauri-desktop + ${preferences.packageManager})`;
747
+ }
713
748
  const syncLabel = preferences.sync ? `sync/${preferences.db}` : "local-only";
714
749
  const styleLabel = preferences.tailwind ? "tailwind" : "css";
715
750
  return `Use previous settings (${preferences.framework} + ${styleLabel} + ${syncLabel} + ${preferences.packageManager})`;
@@ -811,7 +846,7 @@ async function applySyncProviderPreset(options) {
811
846
  await (0, import_promises3.writeFile)(readmePath, readmeTemplate, "utf-8");
812
847
  }
813
848
  function isSyncTemplate(template) {
814
- return template === "react-sync" || template === "react-tailwind-sync";
849
+ return template === "react-sync" || template === "react-tailwind-sync" || template === "tauri-react";
815
850
  }
816
851
  function getProviderDisplayName(provider) {
817
852
  switch (provider) {
@@ -927,6 +962,18 @@ function createCompatibilityLayerPlan(templateName) {
927
962
  authLayer
928
963
  ]
929
964
  };
965
+ case "tauri-react":
966
+ return {
967
+ compatibilityTarget: templateName,
968
+ layers: [
969
+ { category: "base", name: "tauri", sourceTemplate: "tauri-react" },
970
+ uiLayer,
971
+ { category: "style", name: "plain", sourceTemplate: null },
972
+ { category: "sync", name: "enabled", sourceTemplate: null },
973
+ { category: "db", name: "tauri-sqlite", sourceTemplate: null },
974
+ authLayer
975
+ ]
976
+ };
930
977
  }
931
978
  }
932
979
  async function composeTemplateLayers(plan, targetDir, context) {
@@ -983,9 +1030,13 @@ var createCommand = (0, import_citty.defineCommand)({
983
1030
  description: "Project directory name",
984
1031
  required: false
985
1032
  },
1033
+ platform: {
1034
+ type: "string",
1035
+ description: "Target platform (web, desktop-tauri)"
1036
+ },
986
1037
  template: {
987
1038
  type: "string",
988
- description: "Project template (react-tailwind-sync, react-tailwind, react-sync, react-basic)"
1039
+ description: "Project template (react-tailwind-sync, react-tailwind, react-sync, react-basic, tauri-react)"
989
1040
  },
990
1041
  pm: {
991
1042
  type: "string",
@@ -1056,6 +1107,7 @@ var createCommand = (0, import_citty.defineCommand)({
1056
1107
  return;
1057
1108
  }
1058
1109
  const preferenceFlags = {
1110
+ platform: typeof args.platform === "string" ? args.platform : void 0,
1059
1111
  framework: typeof args.framework === "string" ? args.framework : void 0,
1060
1112
  auth: typeof args.auth === "string" ? args.auth : void 0,
1061
1113
  db: typeof args.db === "string" ? args.db : void 0,
@@ -1163,6 +1215,7 @@ var createCommand = (0, import_citty.defineCommand)({
1163
1215
  logger.success("Project scaffolded");
1164
1216
  if (shouldSavePreferences(preferenceFlags)) {
1165
1217
  saveResolvedPreferences(preferenceStore, {
1218
+ platform: selection.platform,
1166
1219
  framework: selection.framework,
1167
1220
  auth: selection.auth,
1168
1221
  db: selection.db,
@@ -1214,7 +1267,7 @@ function isValidPackageManager(value) {
1214
1267
  return PACKAGE_MANAGERS.includes(value);
1215
1268
  }
1216
1269
  function isSyncTemplate2(template) {
1217
- return template === "react-sync" || template === "react-tailwind-sync";
1270
+ return template === "react-sync" || template === "react-tailwind-sync" || template === "tauri-react";
1218
1271
  }
1219
1272
  function formatDbProviderForLog(dbProvider) {
1220
1273
  switch (dbProvider) {