@korajs/cli 0.3.1 → 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 +2 -2
  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/create.cjs CHANGED
@@ -50,6 +50,7 @@ var ProjectExistsError = class extends import_core.KoraError {
50
50
  // src/prompts/preferences.ts
51
51
  var import_conf = __toESM(require("conf"), 1);
52
52
  var DEFAULT_PREFERENCES = {
53
+ platform: "web",
53
54
  framework: "react",
54
55
  tailwind: true,
55
56
  sync: true,
@@ -256,7 +257,8 @@ var TEMPLATES = [
256
257
  "react-tailwind-sync",
257
258
  "react-tailwind",
258
259
  "react-sync",
259
- "react-basic"
260
+ "react-basic",
261
+ "tauri-react"
260
262
  ];
261
263
 
262
264
  // src/utils/fs-helpers.ts
@@ -454,12 +456,16 @@ async function findNearestAncestorWithEntry(startDir, entryName) {
454
456
 
455
457
  // src/commands/create/options.ts
456
458
  function determineTemplateFromSelections(input) {
459
+ if (input.platform === "desktop-tauri") return "tauri-react";
457
460
  const shouldSync = input.sync && input.db !== "none";
458
461
  if (input.tailwind && shouldSync) return "react-tailwind-sync";
459
462
  if (input.tailwind && !shouldSync) return "react-tailwind";
460
463
  if (!input.tailwind && shouldSync) return "react-sync";
461
464
  return "react-basic";
462
465
  }
466
+ function isPlatformValue(value) {
467
+ return value === "web" || value === "desktop-tauri";
468
+ }
463
469
  function isFrameworkValue(value) {
464
470
  return value === "react" || value === "vue" || value === "svelte" || value === "solid";
465
471
  }
@@ -494,83 +500,108 @@ async function resolveCreatePreferencesFlow(params) {
494
500
  usedStoredPreferences = true;
495
501
  }
496
502
  }
497
- if (flags.framework !== void 0) {
498
- if (!isFrameworkValue(flags.framework)) {
503
+ if (flags.platform !== void 0) {
504
+ if (!isPlatformValue(flags.platform)) {
499
505
  throw new Error(
500
- `Invalid --framework value "${flags.framework}". Expected one of: react, vue, svelte, solid.`
506
+ `Invalid --platform value "${flags.platform}". Expected one of: web, desktop-tauri.`
501
507
  );
502
508
  }
503
- effective.framework = flags.framework;
509
+ effective.platform = flags.platform;
504
510
  } else if (!flags.useDefaults && !usedStoredPreferences) {
505
- effective.framework = await prompts.select("UI framework:", [
506
- { label: "React", value: "react" },
507
- { label: "Vue (coming soon)", value: "vue", disabled: true },
508
- { label: "Svelte (coming soon)", value: "svelte", disabled: true },
509
- { label: "Solid (coming soon)", value: "solid", disabled: true }
511
+ effective.platform = await prompts.select("Platform:", [
512
+ { label: "Web (browser)", value: "web" },
513
+ { label: "Desktop (Tauri \u2014 native SQLite)", value: "desktop-tauri" }
510
514
  ]);
511
515
  }
512
- if (flags.auth !== void 0) {
513
- if (!isAuthValue(flags.auth)) {
514
- throw new Error(
515
- `Invalid --auth value "${flags.auth}". Expected one of: none, email-password, oauth.`
516
- );
516
+ const isTauri = effective.platform === "desktop-tauri";
517
+ if (isTauri) {
518
+ effective.framework = "react";
519
+ effective.tailwind = false;
520
+ effective.sync = true;
521
+ effective.db = "sqlite";
522
+ effective.dbProvider = "none";
523
+ effective.auth = "none";
524
+ } else {
525
+ if (flags.framework !== void 0) {
526
+ if (!isFrameworkValue(flags.framework)) {
527
+ throw new Error(
528
+ `Invalid --framework value "${flags.framework}". Expected one of: react, vue, svelte, solid.`
529
+ );
530
+ }
531
+ effective.framework = flags.framework;
532
+ } else if (!flags.useDefaults && !usedStoredPreferences) {
533
+ effective.framework = await prompts.select("UI framework:", [
534
+ { label: "React", value: "react" },
535
+ { label: "Vue (coming soon)", value: "vue", disabled: true },
536
+ { label: "Svelte (coming soon)", value: "svelte", disabled: true },
537
+ { label: "Solid (coming soon)", value: "solid", disabled: true }
538
+ ]);
517
539
  }
518
- effective.auth = flags.auth;
519
- } else if (!flags.useDefaults && !usedStoredPreferences) {
520
- effective.auth = await prompts.select("Authentication:", [
521
- { label: "None", value: "none" },
522
- { label: "Email + Password (coming soon)", value: "email-password", disabled: true },
523
- { label: "OAuth (coming soon)", value: "oauth", disabled: true }
524
- ]);
525
- }
526
- if (flags.tailwind !== void 0) {
527
- effective.tailwind = flags.tailwind;
528
- } else if (!flags.useDefaults && !usedStoredPreferences) {
529
- effective.tailwind = await prompts.confirm("Use Tailwind CSS?", true);
530
- }
531
- if (flags.sync !== void 0) {
532
- effective.sync = flags.sync;
533
- } else if (!flags.useDefaults && !usedStoredPreferences) {
534
- effective.sync = await prompts.confirm("Enable multi-device sync?", true);
535
- }
536
- if (flags.db !== void 0) {
537
- if (!isDatabaseValue(flags.db)) {
538
- throw new Error(`Invalid --db value "${flags.db}". Expected one of: none, sqlite, postgres.`);
540
+ if (flags.auth !== void 0) {
541
+ if (!isAuthValue(flags.auth)) {
542
+ throw new Error(
543
+ `Invalid --auth value "${flags.auth}". Expected one of: none, email-password, oauth.`
544
+ );
545
+ }
546
+ effective.auth = flags.auth;
547
+ } else if (!flags.useDefaults && !usedStoredPreferences) {
548
+ effective.auth = await prompts.select("Authentication:", [
549
+ { label: "None", value: "none" },
550
+ { label: "Email + Password (coming soon)", value: "email-password", disabled: true },
551
+ { label: "OAuth (coming soon)", value: "oauth", disabled: true }
552
+ ]);
539
553
  }
540
- effective.db = flags.db;
541
- } else if (!effective.sync) {
542
- effective.db = "none";
543
- } else if (!flags.useDefaults && !usedStoredPreferences) {
544
- effective.db = await prompts.select("Server-side database:", [
545
- { label: "SQLite (zero-config)", value: "sqlite" },
546
- { label: "PostgreSQL (production-scale)", value: "postgres" }
547
- ]);
548
- }
549
- if (effective.db !== "postgres") {
550
- effective.dbProvider = "none";
551
- } else if (flags.dbProvider !== void 0) {
552
- if (!isDatabaseProviderValue(flags.dbProvider)) {
553
- throw new Error(
554
- `Invalid --db-provider value "${flags.dbProvider}". Expected one of: none, local, supabase, neon, railway, vercel-postgres, custom.`
555
- );
554
+ if (flags.tailwind !== void 0) {
555
+ effective.tailwind = flags.tailwind;
556
+ } else if (!flags.useDefaults && !usedStoredPreferences) {
557
+ effective.tailwind = await prompts.confirm("Use Tailwind CSS?", true);
558
+ }
559
+ if (flags.sync !== void 0) {
560
+ effective.sync = flags.sync;
561
+ } else if (!flags.useDefaults && !usedStoredPreferences) {
562
+ effective.sync = await prompts.confirm("Enable multi-device sync?", true);
563
+ }
564
+ if (flags.db !== void 0) {
565
+ if (!isDatabaseValue(flags.db)) {
566
+ throw new Error(`Invalid --db value "${flags.db}". Expected one of: none, sqlite, postgres.`);
567
+ }
568
+ effective.db = flags.db;
569
+ } else if (!effective.sync) {
570
+ effective.db = "none";
571
+ } else if (!flags.useDefaults && !usedStoredPreferences) {
572
+ effective.db = await prompts.select("Server-side database:", [
573
+ { label: "SQLite (zero-config)", value: "sqlite" },
574
+ { label: "PostgreSQL (production-scale)", value: "postgres" }
575
+ ]);
576
+ }
577
+ if (effective.db !== "postgres") {
578
+ effective.dbProvider = "none";
579
+ } else if (flags.dbProvider !== void 0) {
580
+ if (!isDatabaseProviderValue(flags.dbProvider)) {
581
+ throw new Error(
582
+ `Invalid --db-provider value "${flags.dbProvider}". Expected one of: none, local, supabase, neon, railway, vercel-postgres, custom.`
583
+ );
584
+ }
585
+ effective.dbProvider = flags.dbProvider;
586
+ } else if (!flags.useDefaults && !usedStoredPreferences) {
587
+ effective.dbProvider = await prompts.select("Database provider:", [
588
+ { label: "Local Postgres", value: "local" },
589
+ { label: "Supabase", value: "supabase" },
590
+ { label: "Neon", value: "neon" },
591
+ { label: "Railway", value: "railway" },
592
+ { label: "Vercel Postgres", value: "vercel-postgres" },
593
+ { label: "Custom connection string", value: "custom" }
594
+ ]);
556
595
  }
557
- effective.dbProvider = flags.dbProvider;
558
- } else if (!flags.useDefaults && !usedStoredPreferences) {
559
- effective.dbProvider = await prompts.select("Database provider:", [
560
- { label: "Local Postgres", value: "local" },
561
- { label: "Supabase", value: "supabase" },
562
- { label: "Neon", value: "neon" },
563
- { label: "Railway", value: "railway" },
564
- { label: "Vercel Postgres", value: "vercel-postgres" },
565
- { label: "Custom connection string", value: "custom" }
566
- ]);
567
596
  }
568
597
  const template = determineTemplateFromSelections({
598
+ platform: effective.platform,
569
599
  tailwind: effective.tailwind,
570
600
  sync: effective.sync,
571
601
  db: effective.db
572
602
  });
573
603
  return {
604
+ platform: effective.platform,
574
605
  framework: effective.framework,
575
606
  auth: effective.auth,
576
607
  db: effective.db,
@@ -586,6 +617,7 @@ function shouldSavePreferences(flags) {
586
617
  }
587
618
  function saveResolvedPreferences(store, resolution) {
588
619
  store.saveCreatePreferences({
620
+ platform: resolution.platform,
589
621
  framework: resolution.framework,
590
622
  tailwind: resolution.tailwind,
591
623
  sync: resolution.sync,
@@ -596,12 +628,15 @@ function saveResolvedPreferences(store, resolution) {
596
628
  });
597
629
  }
598
630
  function hasExplicitPreferenceFlags(flags) {
599
- 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;
631
+ 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;
600
632
  }
601
633
  function promptSupportsRichOptions() {
602
634
  return typeof process !== "undefined" && process.stdin.isTTY && process.stdout.isTTY;
603
635
  }
604
636
  function formatStoredPreferenceLabel(preferences) {
637
+ if (preferences.platform === "desktop-tauri") {
638
+ return `Use previous settings (tauri-desktop + ${preferences.packageManager})`;
639
+ }
605
640
  const syncLabel = preferences.sync ? `sync/${preferences.db}` : "local-only";
606
641
  const styleLabel = preferences.tailwind ? "tailwind" : "css";
607
642
  return `Use previous settings (${preferences.framework} + ${styleLabel} + ${syncLabel} + ${preferences.packageManager})`;
@@ -703,7 +738,7 @@ async function applySyncProviderPreset(options) {
703
738
  await (0, import_promises3.writeFile)(readmePath, readmeTemplate, "utf-8");
704
739
  }
705
740
  function isSyncTemplate(template) {
706
- return template === "react-sync" || template === "react-tailwind-sync";
741
+ return template === "react-sync" || template === "react-tailwind-sync" || template === "tauri-react";
707
742
  }
708
743
  function getProviderDisplayName(provider) {
709
744
  switch (provider) {
@@ -819,6 +854,18 @@ function createCompatibilityLayerPlan(templateName) {
819
854
  authLayer
820
855
  ]
821
856
  };
857
+ case "tauri-react":
858
+ return {
859
+ compatibilityTarget: templateName,
860
+ layers: [
861
+ { category: "base", name: "tauri", sourceTemplate: "tauri-react" },
862
+ uiLayer,
863
+ { category: "style", name: "plain", sourceTemplate: null },
864
+ { category: "sync", name: "enabled", sourceTemplate: null },
865
+ { category: "db", name: "tauri-sqlite", sourceTemplate: null },
866
+ authLayer
867
+ ]
868
+ };
822
869
  }
823
870
  }
824
871
  async function composeTemplateLayers(plan, targetDir, context) {
@@ -875,9 +922,13 @@ var createCommand = (0, import_citty.defineCommand)({
875
922
  description: "Project directory name",
876
923
  required: false
877
924
  },
925
+ platform: {
926
+ type: "string",
927
+ description: "Target platform (web, desktop-tauri)"
928
+ },
878
929
  template: {
879
930
  type: "string",
880
- description: "Project template (react-tailwind-sync, react-tailwind, react-sync, react-basic)"
931
+ description: "Project template (react-tailwind-sync, react-tailwind, react-sync, react-basic, tauri-react)"
881
932
  },
882
933
  pm: {
883
934
  type: "string",
@@ -948,6 +999,7 @@ var createCommand = (0, import_citty.defineCommand)({
948
999
  return;
949
1000
  }
950
1001
  const preferenceFlags = {
1002
+ platform: typeof args.platform === "string" ? args.platform : void 0,
951
1003
  framework: typeof args.framework === "string" ? args.framework : void 0,
952
1004
  auth: typeof args.auth === "string" ? args.auth : void 0,
953
1005
  db: typeof args.db === "string" ? args.db : void 0,
@@ -1055,6 +1107,7 @@ var createCommand = (0, import_citty.defineCommand)({
1055
1107
  logger.success("Project scaffolded");
1056
1108
  if (shouldSavePreferences(preferenceFlags)) {
1057
1109
  saveResolvedPreferences(preferenceStore, {
1110
+ platform: selection.platform,
1058
1111
  framework: selection.framework,
1059
1112
  auth: selection.auth,
1060
1113
  db: selection.db,
@@ -1106,7 +1159,7 @@ function isValidPackageManager(value) {
1106
1159
  return PACKAGE_MANAGERS.includes(value);
1107
1160
  }
1108
1161
  function isSyncTemplate2(template) {
1109
- return template === "react-sync" || template === "react-tailwind-sync";
1162
+ return template === "react-sync" || template === "react-tailwind-sync" || template === "tauri-react";
1110
1163
  }
1111
1164
  function formatDbProviderForLog(dbProvider) {
1112
1165
  switch (dbProvider) {