create-croissant 0.1.44 → 0.1.46

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 (170) hide show
  1. package/dist/add.js +8 -8
  2. package/dist/index.js +8 -8
  3. package/package.json +10 -10
  4. package/template/.env.example +2 -2
  5. package/template/.github/dependabot.yml +15 -0
  6. package/template/.github/workflows/ci.yml +143 -0
  7. package/template/.github/workflows/dependabot-automerge.yml +23 -0
  8. package/template/.husky/pre-push +0 -0
  9. package/template/README.md +23 -23
  10. package/template/apps/desktop/.eslintcache +1 -0
  11. package/template/apps/desktop/README.md +5 -5
  12. package/template/apps/desktop/package.json +5 -5
  13. package/template/apps/mobile/README.md +3 -3
  14. package/template/apps/mobile/app/(tabs)/_layout.tsx +21 -14
  15. package/template/apps/mobile/app/(tabs)/account.tsx +147 -0
  16. package/template/apps/mobile/app/(tabs)/explore.tsx +335 -104
  17. package/template/apps/mobile/app/(tabs)/index.tsx +94 -96
  18. package/template/apps/mobile/app/_layout.tsx +26 -7
  19. package/template/apps/mobile/app/index.tsx +129 -0
  20. package/template/apps/mobile/app/login.tsx +135 -0
  21. package/template/apps/mobile/app/signup.tsx +144 -0
  22. package/template/apps/mobile/app.json +9 -4
  23. package/template/apps/mobile/components/ui/button.tsx +86 -0
  24. package/template/apps/mobile/components/ui/input.tsx +56 -0
  25. package/template/apps/mobile/lib/auth-client.ts +1 -1
  26. package/template/apps/mobile/lib/orpc.ts +28 -0
  27. package/template/apps/mobile/package.json +14 -1
  28. package/template/apps/mobile/scripts/reset-project.js +0 -0
  29. package/template/apps/mobile/tsconfig.json +4 -1
  30. package/template/apps/platform/.env.example +1 -1
  31. package/template/apps/platform/package.json +10 -6
  32. package/template/apps/platform/portless.json +3 -0
  33. package/template/apps/platform/src/components/login-form.tsx +5 -4
  34. package/template/apps/platform/src/components/signup-form.tsx +12 -16
  35. package/template/apps/platform/src/router.tsx +0 -1
  36. package/template/apps/platform/src/routes/__root.tsx +6 -2
  37. package/template/apps/platform/src/routes/_auth/account.tsx +13 -17
  38. package/template/apps/platform/src/routes/_auth/examples/client-orpc-auth.tsx +2 -6
  39. package/template/apps/platform/src/routes/_public/examples/client-orpc.tsx +16 -29
  40. package/template/apps/platform/src/routes/_public/examples/ssr-orpc.tsx +10 -14
  41. package/template/apps/platform/src/routes/api/auth/$.ts +23 -2
  42. package/template/apps/platform/src/routes/api/rpc.$.ts +18 -0
  43. package/template/package.json +23 -18
  44. package/template/packages/auth/package.json +2 -2
  45. package/template/packages/db/package.json +1 -1
  46. package/template/packages/orpc/package.json +11 -4
  47. package/template/packages/orpc/src/lib/planets.ts +18 -18
  48. package/template/packages/orpc/src/lib/router.ts +3 -3
  49. package/template/packages/orpc/src/react/context.tsx +23 -0
  50. package/template/packages/orpc/src/react/general.ts +29 -0
  51. package/template/packages/orpc/src/react/index.ts +3 -0
  52. package/template/packages/orpc/src/react/planets.ts +90 -0
  53. package/template/packages/ui/package.json +3 -2
  54. package/template/pnpm-workspace.yaml +3 -0
  55. package/template/tsconfig.json +2 -1
  56. package/template/apps/mobile/app/modal.tsx +0 -29
  57. package/template/packages/orpc/node_modules/@types/node/LICENSE +0 -21
  58. package/template/packages/orpc/node_modules/@types/node/README.md +0 -15
  59. package/template/packages/orpc/node_modules/@types/node/assert/strict.d.ts +0 -111
  60. package/template/packages/orpc/node_modules/@types/node/assert.d.ts +0 -1078
  61. package/template/packages/orpc/node_modules/@types/node/async_hooks.d.ts +0 -603
  62. package/template/packages/orpc/node_modules/@types/node/buffer.buffer.d.ts +0 -472
  63. package/template/packages/orpc/node_modules/@types/node/buffer.d.ts +0 -1934
  64. package/template/packages/orpc/node_modules/@types/node/child_process.d.ts +0 -1476
  65. package/template/packages/orpc/node_modules/@types/node/cluster.d.ts +0 -578
  66. package/template/packages/orpc/node_modules/@types/node/compatibility/disposable.d.ts +0 -14
  67. package/template/packages/orpc/node_modules/@types/node/compatibility/index.d.ts +0 -9
  68. package/template/packages/orpc/node_modules/@types/node/compatibility/indexable.d.ts +0 -20
  69. package/template/packages/orpc/node_modules/@types/node/compatibility/iterators.d.ts +0 -20
  70. package/template/packages/orpc/node_modules/@types/node/console.d.ts +0 -452
  71. package/template/packages/orpc/node_modules/@types/node/constants.d.ts +0 -21
  72. package/template/packages/orpc/node_modules/@types/node/crypto.d.ts +0 -4545
  73. package/template/packages/orpc/node_modules/@types/node/dgram.d.ts +0 -600
  74. package/template/packages/orpc/node_modules/@types/node/diagnostics_channel.d.ts +0 -578
  75. package/template/packages/orpc/node_modules/@types/node/dns/promises.d.ts +0 -503
  76. package/template/packages/orpc/node_modules/@types/node/dns.d.ts +0 -923
  77. package/template/packages/orpc/node_modules/@types/node/domain.d.ts +0 -170
  78. package/template/packages/orpc/node_modules/@types/node/events.d.ts +0 -976
  79. package/template/packages/orpc/node_modules/@types/node/fs/promises.d.ts +0 -1295
  80. package/template/packages/orpc/node_modules/@types/node/fs.d.ts +0 -4461
  81. package/template/packages/orpc/node_modules/@types/node/globals.d.ts +0 -172
  82. package/template/packages/orpc/node_modules/@types/node/globals.typedarray.d.ts +0 -38
  83. package/template/packages/orpc/node_modules/@types/node/http.d.ts +0 -2089
  84. package/template/packages/orpc/node_modules/@types/node/http2.d.ts +0 -2644
  85. package/template/packages/orpc/node_modules/@types/node/https.d.ts +0 -579
  86. package/template/packages/orpc/node_modules/@types/node/index.d.ts +0 -97
  87. package/template/packages/orpc/node_modules/@types/node/inspector.d.ts +0 -253
  88. package/template/packages/orpc/node_modules/@types/node/inspector.generated.d.ts +0 -4052
  89. package/template/packages/orpc/node_modules/@types/node/module.d.ts +0 -891
  90. package/template/packages/orpc/node_modules/@types/node/net.d.ts +0 -1076
  91. package/template/packages/orpc/node_modules/@types/node/os.d.ts +0 -506
  92. package/template/packages/orpc/node_modules/@types/node/package.json +0 -145
  93. package/template/packages/orpc/node_modules/@types/node/path.d.ts +0 -200
  94. package/template/packages/orpc/node_modules/@types/node/perf_hooks.d.ts +0 -968
  95. package/template/packages/orpc/node_modules/@types/node/process.d.ts +0 -2084
  96. package/template/packages/orpc/node_modules/@types/node/punycode.d.ts +0 -117
  97. package/template/packages/orpc/node_modules/@types/node/querystring.d.ts +0 -152
  98. package/template/packages/orpc/node_modules/@types/node/readline/promises.d.ts +0 -161
  99. package/template/packages/orpc/node_modules/@types/node/readline.d.ts +0 -594
  100. package/template/packages/orpc/node_modules/@types/node/repl.d.ts +0 -428
  101. package/template/packages/orpc/node_modules/@types/node/sea.d.ts +0 -153
  102. package/template/packages/orpc/node_modules/@types/node/sqlite.d.ts +0 -721
  103. package/template/packages/orpc/node_modules/@types/node/stream/consumers.d.ts +0 -38
  104. package/template/packages/orpc/node_modules/@types/node/stream/promises.d.ts +0 -90
  105. package/template/packages/orpc/node_modules/@types/node/stream/web.d.ts +0 -622
  106. package/template/packages/orpc/node_modules/@types/node/stream.d.ts +0 -1687
  107. package/template/packages/orpc/node_modules/@types/node/string_decoder.d.ts +0 -67
  108. package/template/packages/orpc/node_modules/@types/node/test.d.ts +0 -2163
  109. package/template/packages/orpc/node_modules/@types/node/timers/promises.d.ts +0 -108
  110. package/template/packages/orpc/node_modules/@types/node/timers.d.ts +0 -287
  111. package/template/packages/orpc/node_modules/@types/node/tls.d.ts +0 -1319
  112. package/template/packages/orpc/node_modules/@types/node/trace_events.d.ts +0 -197
  113. package/template/packages/orpc/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +0 -468
  114. package/template/packages/orpc/node_modules/@types/node/ts5.6/globals.typedarray.d.ts +0 -34
  115. package/template/packages/orpc/node_modules/@types/node/ts5.6/index.d.ts +0 -97
  116. package/template/packages/orpc/node_modules/@types/node/tty.d.ts +0 -208
  117. package/template/packages/orpc/node_modules/@types/node/url.d.ts +0 -984
  118. package/template/packages/orpc/node_modules/@types/node/util.d.ts +0 -2606
  119. package/template/packages/orpc/node_modules/@types/node/v8.d.ts +0 -920
  120. package/template/packages/orpc/node_modules/@types/node/vm.d.ts +0 -1000
  121. package/template/packages/orpc/node_modules/@types/node/wasi.d.ts +0 -181
  122. package/template/packages/orpc/node_modules/@types/node/web-globals/abortcontroller.d.ts +0 -34
  123. package/template/packages/orpc/node_modules/@types/node/web-globals/domexception.d.ts +0 -68
  124. package/template/packages/orpc/node_modules/@types/node/web-globals/events.d.ts +0 -97
  125. package/template/packages/orpc/node_modules/@types/node/web-globals/fetch.d.ts +0 -55
  126. package/template/packages/orpc/node_modules/@types/node/web-globals/navigator.d.ts +0 -22
  127. package/template/packages/orpc/node_modules/@types/node/web-globals/storage.d.ts +0 -24
  128. package/template/packages/orpc/node_modules/@types/node/worker_threads.d.ts +0 -784
  129. package/template/packages/orpc/node_modules/@types/node/zlib.d.ts +0 -747
  130. package/template/packages/orpc/node_modules/undici-types/LICENSE +0 -21
  131. package/template/packages/orpc/node_modules/undici-types/README.md +0 -6
  132. package/template/packages/orpc/node_modules/undici-types/agent.d.ts +0 -31
  133. package/template/packages/orpc/node_modules/undici-types/api.d.ts +0 -43
  134. package/template/packages/orpc/node_modules/undici-types/balanced-pool.d.ts +0 -29
  135. package/template/packages/orpc/node_modules/undici-types/cache.d.ts +0 -36
  136. package/template/packages/orpc/node_modules/undici-types/client.d.ts +0 -108
  137. package/template/packages/orpc/node_modules/undici-types/connector.d.ts +0 -34
  138. package/template/packages/orpc/node_modules/undici-types/content-type.d.ts +0 -21
  139. package/template/packages/orpc/node_modules/undici-types/cookies.d.ts +0 -28
  140. package/template/packages/orpc/node_modules/undici-types/diagnostics-channel.d.ts +0 -66
  141. package/template/packages/orpc/node_modules/undici-types/dispatcher.d.ts +0 -256
  142. package/template/packages/orpc/node_modules/undici-types/env-http-proxy-agent.d.ts +0 -21
  143. package/template/packages/orpc/node_modules/undici-types/errors.d.ts +0 -149
  144. package/template/packages/orpc/node_modules/undici-types/eventsource.d.ts +0 -61
  145. package/template/packages/orpc/node_modules/undici-types/fetch.d.ts +0 -209
  146. package/template/packages/orpc/node_modules/undici-types/file.d.ts +0 -39
  147. package/template/packages/orpc/node_modules/undici-types/filereader.d.ts +0 -54
  148. package/template/packages/orpc/node_modules/undici-types/formdata.d.ts +0 -108
  149. package/template/packages/orpc/node_modules/undici-types/global-dispatcher.d.ts +0 -9
  150. package/template/packages/orpc/node_modules/undici-types/global-origin.d.ts +0 -7
  151. package/template/packages/orpc/node_modules/undici-types/handlers.d.ts +0 -15
  152. package/template/packages/orpc/node_modules/undici-types/header.d.ts +0 -4
  153. package/template/packages/orpc/node_modules/undici-types/index.d.ts +0 -71
  154. package/template/packages/orpc/node_modules/undici-types/interceptors.d.ts +0 -17
  155. package/template/packages/orpc/node_modules/undici-types/mock-agent.d.ts +0 -50
  156. package/template/packages/orpc/node_modules/undici-types/mock-client.d.ts +0 -25
  157. package/template/packages/orpc/node_modules/undici-types/mock-errors.d.ts +0 -12
  158. package/template/packages/orpc/node_modules/undici-types/mock-interceptor.d.ts +0 -93
  159. package/template/packages/orpc/node_modules/undici-types/mock-pool.d.ts +0 -25
  160. package/template/packages/orpc/node_modules/undici-types/package.json +0 -55
  161. package/template/packages/orpc/node_modules/undici-types/patch.d.ts +0 -33
  162. package/template/packages/orpc/node_modules/undici-types/pool-stats.d.ts +0 -19
  163. package/template/packages/orpc/node_modules/undici-types/pool.d.ts +0 -39
  164. package/template/packages/orpc/node_modules/undici-types/proxy-agent.d.ts +0 -28
  165. package/template/packages/orpc/node_modules/undici-types/readable.d.ts +0 -65
  166. package/template/packages/orpc/node_modules/undici-types/retry-agent.d.ts +0 -8
  167. package/template/packages/orpc/node_modules/undici-types/retry-handler.d.ts +0 -116
  168. package/template/packages/orpc/node_modules/undici-types/util.d.ts +0 -18
  169. package/template/packages/orpc/node_modules/undici-types/webidl.d.ts +0 -228
  170. package/template/packages/orpc/node_modules/undici-types/websocket.d.ts +0 -150
package/dist/add.js CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import i from"path";import{fileURLToPath as E}from"url";import s from"chalk";import{Command as P}from"commander";import{execa as j}from"execa";import e from"fs-extra";import k from"inquirer";import g from"ora";var A=E(import.meta.url),x=i.dirname(A),y=new P;y.name("croissant-add").description("Add a mobile or desktop app to an existing Croissant Stack project").action(async()=>{console.log(s.bold.yellow(`
2
+ import i from"path";import{fileURLToPath as E}from"url";import s from"chalk";import{Command as P}from"commander";import{execa as j}from"execa";import t from"fs-extra";import k from"inquirer";import g from"ora";var A=E(import.meta.url),x=i.dirname(A),v=new P;v.name("croissant-add").description("Add a mobile or desktop app to an existing Croissant Stack project").action(async()=>{console.log(s.bold.yellow(`
3
3
  \u{1F950} Croissant Stack: Add App
4
- `));let p=i.join(process.cwd(),"package.json");await e.pathExists(p)||(console.error(s.red(`
4
+ `));let p=i.join(process.cwd(),"package.json");await t.pathExists(p)||(console.error(s.red(`
5
5
  Error: package.json not found. Are you in the root of your project?
6
- `)),process.exit(1));let t=await e.readJson(p);(!t.scripts||!t.scripts.dev&&!t.scripts.build)&&(console.error(s.red(`
6
+ `)),process.exit(1));let e=await t.readJson(p);(!e.scripts||!e.scripts.dev&&!e.scripts.build)&&(console.error(s.red(`
7
7
  Error: This doesn't look like a Croissant Stack project.
8
- `)),process.exit(1));let u=i.join(process.cwd(),"apps/mobile"),h=i.join(process.cwd(),"apps/desktop"),f=await e.pathExists(u),b=await e.pathExists(h);if(f&&b){console.log(s.blue(`Both mobile and desktop apps are already present. Nothing to add!
9
- `));return}let l=[];f||l.push({name:"Mobile App (Expo)",value:"mobile"}),b||l.push({name:"Desktop App (Electron)",value:"desktop"});let{type:a}=await k.prompt([{type:"list",name:"type",message:"Which app would you like to add?",choices:l}]),c=process.cwd(),w=g(`Adding ${a} app...`).start();try{let n=i.join(x,"..","template");if(await e.pathExists(n)||(n=i.resolve(x,"../../..")),a==="mobile"){let r=i.join(n,"apps/mobile");await e.copy(r,u),t.scripts=t.scripts||{},t.scripts["dev:mobile"]="turbo run dev --filter=mobile",t.scripts["build:mobile"]="turbo run build --filter=mobile",await e.writeJson(p,t,{spaces:2});let d=i.join(c,"packages/auth/src/lib/auth.ts");if(await e.pathExists(d)){let o=await e.readFile(d,"utf8");o.includes("@better-auth/expo")||(o=`import { expo } from "@better-auth/expo";
8
+ `)),process.exit(1));let u=i.join(process.cwd(),"apps/mobile"),h=i.join(process.cwd(),"apps/desktop"),b=await t.pathExists(u),f=await t.pathExists(h);if(b&&f){console.log(s.blue(`Both mobile and desktop apps are already present. Nothing to add!
9
+ `));return}let l=[];b||l.push({name:"Mobile App (Expo)",value:"mobile"}),f||l.push({name:"Desktop App (Electron)",value:"desktop"});let{type:a}=await k.prompt([{type:"list",name:"type",message:"Which app would you like to add?",choices:l}]),c=process.cwd(),w=g(`Adding ${a} app...`).start();try{let n=i.join(x,"..","template");if(await t.pathExists(n)||(n=i.resolve(x,"../../..")),a==="mobile"){let r=i.join(n,"apps/mobile");await t.copy(r,u),e.scripts=e.scripts||{},e.scripts["dev:mobile"]="turbo run dev --filter=mobile",e.scripts["dev:ios"]="turbo run dev --filter=mobile -- --ios",e.scripts["dev:android"]="turbo run dev --filter=mobile -- --android",e.scripts["build:mobile"]="turbo run build --filter=mobile",await t.writeJson(p,e,{spaces:2});let d=i.join(c,"packages/auth/src/lib/auth.ts");if(await t.pathExists(d)){let o=await t.readFile(d,"utf8");o.includes("@better-auth/expo")||(o=`import { expo } from "@better-auth/expo";
10
10
  ${o}`),o.includes("plugins: [expo()]")||(o=o.replace("emailAndPassword: { enabled: true },",`emailAndPassword: { enabled: true },
11
11
  plugins: [expo()],
12
12
  trustedOrigins: [
@@ -19,7 +19,7 @@ ${o}`),o.includes("plugins: [expo()]")||(o=o.replace("emailAndPassword: { enable
19
19
  "http://localhost:8081",
20
20
  ]
21
21
  : []),
22
- ],`)),await e.writeFile(d,o)}let m=i.join(c,"packages/auth/package.json");if(await e.pathExists(m)){let o=await e.readJson(m);o.dependencies=o.dependencies||{},o.dependencies["@better-auth/expo"]||(o.dependencies["@better-auth/expo"]="latest",await e.writeJson(m,o,{spaces:2}))}}else if(a==="desktop"){let r=i.join(n,"apps/desktop");await e.copy(r,h),t.scripts=t.scripts||{},t.scripts["dev:desktop"]="turbo run dev --filter=desktop",t.scripts["build:desktop"]="turbo run build --filter=desktop",await e.writeJson(p,t,{spaces:2})}w.succeed(s.green(`${a==="mobile"?"Mobile":"Desktop"} app added successfully!`));let{install:v}=await k.prompt([{type:"confirm",name:"install",message:"Would you like to install dependencies now?",default:!0}]);if(v){let r=g("Installing dependencies...").start();try{await j("npm",["install"],{cwd:c}),r.succeed(s.green("Dependencies installed!"))}catch{r.fail(s.red("Failed to install dependencies. Run npm install manually."))}}console.log(s.bold.cyan(`
23
- Next steps:`)),console.log(a==="mobile"?" npm run dev:mobile # Start Expo development server":" npm run dev:desktop # Start Electron development server"),console.log(s.yellow(`
22
+ ],`)),await t.writeFile(d,o)}let m=i.join(c,"packages/auth/package.json");if(await t.pathExists(m)){let o=await t.readJson(m);o.dependencies=o.dependencies||{},o.dependencies["@better-auth/expo"]||(o.dependencies["@better-auth/expo"]="latest",await t.writeJson(m,o,{spaces:2}))}}else if(a==="desktop"){let r=i.join(n,"apps/desktop");await t.copy(r,h),e.scripts=e.scripts||{},e.scripts["dev:desktop"]="turbo run dev --filter=desktop",e.scripts["build:desktop"]="turbo run build --filter=desktop",await t.writeJson(p,e,{spaces:2})}w.succeed(s.green(`${a==="mobile"?"Mobile":"Desktop"} app added successfully!`));let{install:y}=await k.prompt([{type:"confirm",name:"install",message:"Would you like to install dependencies now?",default:!0}]);if(y){let r=g("Installing dependencies...").start();try{await j("pnpm",["install"],{cwd:c}),r.succeed(s.green("Dependencies installed!"))}catch{r.fail(s.red("Failed to install dependencies. Run pnpm install manually."))}}console.log(s.bold.cyan(`
23
+ Next steps:`)),console.log(a==="mobile"?" pnpm run dev:mobile # Start Expo development server":" pnpm run dev:desktop # Start Electron development server"),console.log(s.yellow(`
24
24
  Happy hacking! \u{1F950}
25
- `))}catch(n){w.fail(s.red(`An error occurred while adding the ${a} app.`)),console.error(n),process.exit(1)}});y.parse(process.argv);
25
+ `))}catch(n){w.fail(s.red(`An error occurred while adding the ${a} app.`)),console.error(n),process.exit(1)}});v.parse(process.argv);
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import i from"path";import{fileURLToPath as x}from"url";import c from"chalk";import{Command as b}from"commander";import{execa as P}from"execa";import e from"fs-extra";import y from"inquirer";import g from"ora";var j=x(import.meta.url),w=i.dirname(j),k=new b;k.name("create-croissant").description("Scaffold a new project using the Croissant Stack").argument("[project-name]","Name of the project").action(async m=>{console.log(c.bold.yellow(`
2
+ import i from"path";import{fileURLToPath as k}from"url";import p from"chalk";import{Command as b}from"commander";import{execa as P}from"execa";import e from"fs-extra";import y from"inquirer";import g from"ora";var j=k(import.meta.url),w=i.dirname(j),x=new b;x.name("create-croissant").description("Scaffold a new project using the Croissant Stack").argument("[project-name]","Name of the project").action(async u=>{console.log(p.bold.yellow(`
3
3
  \u{1F950} Welcome to the Croissant Stack!
4
- `));let l=await y.prompt([{type:"input",name:"name",message:"What is your project named?",default:m||"my-croissant-app",when:!m},{type:"confirm",name:"install",message:"Would you like to install dependencies?",default:!0},{type:"confirm",name:"mobile",message:"Would you like to include the mobile app (Expo)?",default:!0},{type:"confirm",name:"desktop",message:"Would you like to include the desktop app (Electron)?",default:!0}]),p=m||l.name,s=i.resolve(process.cwd(),p);e.existsSync(s)&&(console.error(c.red(`
5
- Error: Directory ${p} already exists.
6
- `)),process.exit(1));let h=g("Scaffolding your project...").start();try{await e.ensureDir(s);let d=i.join(w,"..","template");if(await e.pathExists(d))await e.copy(d,s);else{let a=i.resolve(w,"../../.."),n=["node_modules","dist",".git","packages/create-croissant",".turbo","package-lock.json"];await e.copy(a,s,{filter:t=>{let r=i.relative(a,t);return!n.some(o=>r.startsWith(o))}})}if(l.mobile){let a=i.join(s,"packages/auth/src/lib/auth.ts");if(await e.pathExists(a)){let t=await e.readFile(a,"utf8");t.includes("@better-auth/expo")||(t=`import { expo } from "@better-auth/expo";
4
+ `));let l=await y.prompt([{type:"input",name:"name",message:"What is your project named?",default:u||"my-croissant-app",when:!u},{type:"confirm",name:"install",message:"Would you like to install dependencies?",default:!0},{type:"confirm",name:"mobile",message:"Would you like to include the mobile app (Expo)?",default:!0},{type:"confirm",name:"desktop",message:"Would you like to include the desktop app (Electron)?",default:!0}]),c=u||l.name,s=i.resolve(process.cwd(),c);e.existsSync(s)&&(console.error(p.red(`
5
+ Error: Directory ${c} already exists.
6
+ `)),process.exit(1));let f=g("Scaffolding your project...").start();try{await e.ensureDir(s);let d=i.join(w,"..","template");if(await e.pathExists(d))await e.copy(d,s);else{let a=i.resolve(w,"../../.."),n=["node_modules","dist",".git","packages/create-croissant",".turbo","pnpm-lock.yaml"];await e.copy(a,s,{filter:t=>{let r=i.relative(a,t);return!n.some(o=>r.startsWith(o))}})}if(l.mobile){let a=i.join(s,"packages/auth/src/lib/auth.ts");if(await e.pathExists(a)){let t=await e.readFile(a,"utf8");t.includes("@better-auth/expo")||(t=`import { expo } from "@better-auth/expo";
7
7
  ${t}`),t.includes("plugins: [expo()]")||(t=t.replace("emailAndPassword: { enabled: true },",`emailAndPassword: { enabled: true },
8
8
  plugins: [expo()],
9
9
  trustedOrigins: [
@@ -16,7 +16,7 @@ ${t}`),t.includes("plugins: [expo()]")||(t=t.replace("emailAndPassword: { enable
16
16
  "http://localhost:8081",
17
17
  ]
18
18
  : []),
19
- ],`)),await e.writeFile(a,t)}let n=i.join(s,"packages/auth/package.json");if(await e.pathExists(n)){let t=await e.readJson(n);t.dependencies=t.dependencies||{},t.dependencies["@better-auth/expo"]||(t.dependencies["@better-auth/expo"]="latest",await e.writeJson(n,t,{spaces:2}))}}else{let a=i.join(s,"apps/mobile");if(await e.pathExists(a)){await e.remove(a);let n=i.join(s,"package.json");if(await e.pathExists(n)){let o=await e.readJson(n);o.scripts&&Object.keys(o.scripts).forEach(f=>{f.includes("mobile")&&delete o.scripts[f]}),await e.writeJson(n,o,{spaces:2})}let t=i.join(s,"packages/auth/src/lib/auth.ts");if(await e.pathExists(t)){let o=await e.readFile(t,"utf8");o=o.replace(/import \{ expo \} from "@better-auth\/expo";\n/,""),o=o.replace(/\s+plugins: \[expo\(\)\],/,""),o=o.replace(/\s+trustedOrigins: \[[\s\S]*?\],/,""),await e.writeFile(t,o)}let r=i.join(s,"packages/auth/package.json");if(await e.pathExists(r)){let o=await e.readJson(r);o.dependencies&&o.dependencies["@better-auth/expo"]&&(delete o.dependencies["@better-auth/expo"],await e.writeJson(r,o,{spaces:2}))}}}if(!l.desktop){let a=i.join(s,"apps/desktop");if(await e.pathExists(a)){await e.remove(a);let n=i.join(s,"package.json");if(await e.pathExists(n)){let t=await e.readJson(n);t.scripts&&Object.keys(t.scripts).forEach(r=>{r.includes("desktop")&&delete t.scripts[r]}),await e.writeJson(n,t,{spaces:2})}}}let u=i.join(s,"package.json");if(await e.pathExists(u)){let a=await e.readJson(u);a.name=p,a.version="0.1.0",delete a.private,await e.writeJson(u,a,{spaces:2})}if(h.succeed(c.green(`Project ${p} created at ${s}`)),l.install){let a=g("Installing dependencies...").start();try{await P("npm",["install"],{cwd:s}),a.succeed(c.green("Dependencies installed!"))}catch{a.fail(c.red("Failed to install dependencies. You may need to run npm install manually."))}}console.log(c.bold.cyan(`
20
- Next steps:`)),console.log(` cd ${p}`),console.log(" npm run db:up # Start your PostgreSQL database"),console.log(` npm run dev # Start development server
21
- `),console.log(c.yellow(`Happy hacking! \u{1F950}
22
- `))}catch(d){h.fail(c.red("An error occurred during scaffolding.")),console.error(d),process.exit(1)}});k.parse(process.argv);
19
+ ],`)),await e.writeFile(a,t)}let n=i.join(s,"packages/auth/package.json");if(await e.pathExists(n)){let t=await e.readJson(n);t.dependencies=t.dependencies||{},t.dependencies["@better-auth/expo"]||(t.dependencies["@better-auth/expo"]="latest",await e.writeJson(n,t,{spaces:2}))}}else{let a=i.join(s,"apps/mobile");if(await e.pathExists(a)){await e.remove(a);let n=i.join(s,"package.json");if(await e.pathExists(n)){let o=await e.readJson(n);o.scripts&&Object.keys(o.scripts).forEach(m=>{(m.includes("mobile")||m.includes("ios")||m.includes("android"))&&delete o.scripts[m]}),await e.writeJson(n,o,{spaces:2})}let t=i.join(s,"packages/auth/src/lib/auth.ts");if(await e.pathExists(t)){let o=await e.readFile(t,"utf8");o=o.replace(/import \{ expo \} from "@better-auth\/expo";\n/,""),o=o.replace(/\s+plugins: \[expo\(\)\],/,""),o=o.replace(/\s+trustedOrigins: \[[\s\S]*?\],/,""),await e.writeFile(t,o)}let r=i.join(s,"packages/auth/package.json");if(await e.pathExists(r)){let o=await e.readJson(r);o.dependencies&&o.dependencies["@better-auth/expo"]&&(delete o.dependencies["@better-auth/expo"],await e.writeJson(r,o,{spaces:2}))}}}if(!l.desktop){let a=i.join(s,"apps/desktop");if(await e.pathExists(a)){await e.remove(a);let n=i.join(s,"package.json");if(await e.pathExists(n)){let t=await e.readJson(n);t.scripts&&Object.keys(t.scripts).forEach(r=>{r.includes("desktop")&&delete t.scripts[r]}),await e.writeJson(n,t,{spaces:2})}}}let h=i.join(s,"package.json");if(await e.pathExists(h)){let a=await e.readJson(h);a.name=c,a.version="0.1.0",delete a.private,await e.writeJson(h,a,{spaces:2})}if(f.succeed(p.green(`Project ${c} created at ${s}`)),l.install){let a=g("Installing dependencies...").start();try{await P("pnpm",["install"],{cwd:s}),a.succeed(p.green("Dependencies installed!"))}catch{a.fail(p.red("Failed to install dependencies. You may need to run pnpm install manually."))}}console.log(p.bold.cyan(`
20
+ Next steps:`)),console.log(` cd ${c}`),console.log(" pnpm run db:up # Start your PostgreSQL database"),console.log(` pnpm run dev # Start development server
21
+ `),console.log(p.yellow(`Happy hacking! \u{1F950}
22
+ `))}catch(d){f.fail(p.red("An error occurred during scaffolding.")),console.error(d),process.exit(1)}});x.parse(process.argv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-croissant",
3
- "version": "0.1.44",
3
+ "version": "0.1.46",
4
4
  "description": "Scaffold a new project using the Croissant Stack",
5
5
  "repository": {
6
6
  "type": "git",
@@ -20,12 +20,6 @@
20
20
  "publishConfig": {
21
21
  "access": "public"
22
22
  },
23
- "scripts": {
24
- "build": "npm run prepare-template && tsup src/index.ts src/add.ts --format esm --clean --minify",
25
- "dev": "tsup src/index.ts src/add.ts --format esm --watch",
26
- "typecheck": "tsc --noEmit",
27
- "prepare-template": "node scripts/prepare-template.js"
28
- },
29
23
  "dependencies": {
30
24
  "chalk": "^5.6.2",
31
25
  "commander": "^14.0.3",
@@ -38,7 +32,13 @@
38
32
  "@types/fs-extra": "^11.0.4",
39
33
  "@types/inquirer": "^9.0.9",
40
34
  "@types/node": "^25.6.0",
41
- "@workspace/config-typescript": "*",
42
- "tsup": "^8.5.1"
35
+ "tsup": "^8.5.1",
36
+ "@workspace/config-typescript": "0.0.0"
37
+ },
38
+ "scripts": {
39
+ "build": "pnpm run prepare-template && tsup src/index.ts src/add.ts --format esm --clean --minify",
40
+ "dev": "tsup src/index.ts src/add.ts --format esm --watch",
41
+ "typecheck": "tsc --noEmit",
42
+ "prepare-template": "node scripts/prepare-template.js"
43
43
  }
44
- }
44
+ }
@@ -1,5 +1,5 @@
1
1
  DATABASE_URL=postgresql://postgres:postgres@localhost:5432/auth
2
- BETTER_AUTH_URL=http://localhost:3000
2
+ BETTER_AUTH_URL=https://platform.local
3
3
  BETTER_AUTH_SECRET=your-secret-here
4
4
  # For production, set this to your domain
5
- # NEXT_PUBLIC_APP_URL=http://localhost:3000
5
+ # NEXT_PUBLIC_APP_URL=https://platform.local
@@ -0,0 +1,15 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "pnpm"
4
+ directory: "/"
5
+ schedule:
6
+ interval: "weekly"
7
+ open-pull-requests-limit: 10
8
+ groups:
9
+ dependencies:
10
+ patterns:
11
+ - "*"
12
+ - package-ecosystem: "github-actions"
13
+ directory: "/"
14
+ schedule:
15
+ interval: "monthly"
@@ -0,0 +1,143 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: ["main"]
6
+ pull_request:
7
+ branches: ["main"]
8
+
9
+ permissions:
10
+ contents: write
11
+ id-token: write
12
+
13
+ jobs:
14
+ build:
15
+ name: Build and Test
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - name: Checkout Repo
19
+ uses: actions/checkout@v4
20
+ with:
21
+ fetch-depth: 0
22
+
23
+ - name: Setup Node.js
24
+ uses: actions/setup-node@v4
25
+ with:
26
+ node-version: 24
27
+
28
+ - name: Setup pnpm
29
+ uses: pnpm/action-setup@v4
30
+ with:
31
+ version: 9.15.0
32
+ run_install: false
33
+
34
+ - name: Get pnpm store directory
35
+ shell: bash
36
+ run: |
37
+ echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
38
+
39
+ - name: Setup pnpm cache
40
+ uses: actions/cache@v4
41
+ with:
42
+ path: ${{ env.STORE_PATH }}
43
+ key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
44
+ restore-keys: |
45
+ ${{ runner.os }}-pnpm-store-
46
+
47
+ - name: Install Dependencies
48
+ run: pnpm install
49
+
50
+ - name: Lint
51
+ run: pnpm run lint
52
+
53
+ - name: Typecheck
54
+ run: pnpm run typecheck
55
+
56
+ - name: Build
57
+ run: pnpm run build
58
+
59
+ release:
60
+ name: Release create-croissant
61
+ needs: build
62
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
63
+ runs-on: ubuntu-latest
64
+ steps:
65
+ - name: Checkout Repo
66
+ uses: actions/checkout@v4
67
+ with:
68
+ fetch-depth: 0
69
+
70
+ - name: Setup Node.js
71
+ uses: actions/setup-node@v4
72
+ with:
73
+ node-version: 24
74
+ registry-url: "https://registry.npmjs.org"
75
+
76
+ - name: Setup pnpm
77
+ uses: pnpm/action-setup@v4
78
+ with:
79
+ version: 9.15.0
80
+ run_install: false
81
+
82
+ - name: Install Dependencies
83
+ run: pnpm install
84
+
85
+ - name: Bump Version and Publish
86
+ run: |
87
+ # Configure git
88
+ git config --global user.name "github-actions[bot]"
89
+ git config --global user.email "github-actions[bot]@users.noreply.github.com"
90
+
91
+ # Prepare the template from the latest monorepo state
92
+ pnpm --filter create-croissant run prepare-template
93
+
94
+ # Move into the package directory for versioning and publishing
95
+ cd packages/create-croissant
96
+
97
+ # Get the latest version from npm to avoid conflicts
98
+ NPM_VERSION=$(pnpm view create-croissant version 2>/dev/null || echo "0.0.0")
99
+ LOCAL_VERSION=$(node -p "require('./package.json').version")
100
+
101
+ echo "NPM version: $NPM_VERSION"
102
+ echo "Local version: $LOCAL_VERSION"
103
+
104
+ # If npm has a higher version, sync local version first
105
+ if [ "$NPM_VERSION" != "$LOCAL_VERSION" ] && [ "$(printf '%s\n' "$NPM_VERSION" "$LOCAL_VERSION" | sort -V | tail -n1)" = "$NPM_VERSION" ] && [ "$NPM_VERSION" != "0.0.0" ]; then
106
+ echo "Syncing local version to $NPM_VERSION to avoid conflict"
107
+ npm version $NPM_VERSION --no-git-tag-version
108
+ fi
109
+
110
+ # Bump version (patch)
111
+ npm version patch --no-git-tag-version
112
+
113
+ NEW_VERSION=$(node -p "require('./package.json').version")
114
+ echo "New version to be published: $NEW_VERSION"
115
+
116
+ # Build the package
117
+ pnpm run build
118
+
119
+ # Publish to npm (using Trusted Publishing)
120
+ pnpm publish --provenance --access public --no-git-checks
121
+
122
+ # Go back to root for git operations
123
+ cd ../..
124
+
125
+ # After successful publish, commit the version change and tag it
126
+ git add packages/create-croissant/package.json
127
+ git commit -m "chore: release create-croissant v$NEW_VERSION [skip ci]"
128
+ git tag "v$NEW_VERSION"
129
+
130
+ # Push the version bump commit and tag back to main
131
+ git push origin main --follow-tags
132
+
133
+ # Create a GitHub Release
134
+ # --generate-notes automatically creates a changelog based on commits
135
+ # We use --target main to ensure the release is associated with the pushed branch
136
+ gh release create "v$NEW_VERSION" \
137
+ --target main \
138
+ --title "Release v$NEW_VERSION (create-croissant)" \
139
+ --generate-notes \
140
+ --latest
141
+ env:
142
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
143
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -0,0 +1,23 @@
1
+ name: Dependabot Auto-Merge
2
+ on: pull_request
3
+
4
+ permissions:
5
+ contents: write
6
+ pull-requests: write
7
+
8
+ jobs:
9
+ dependabot:
10
+ runs-on: ubuntu-latest
11
+ if: github.actor == 'dependabot[bot]'
12
+ steps:
13
+ - name: Dependabot metadata
14
+ id: metadata
15
+ uses: dependabot/fetch-metadata@v3
16
+ with:
17
+ github-token: "${{ secrets.GITHUB_TOKEN }}"
18
+ - name: Enable auto-merge for Dependabot PRs
19
+ if: steps.metadata.outputs.update-type != 'version-update:semver-major'
20
+ run: gh pr merge --auto --squash "$PR_URL"
21
+ env:
22
+ PR_URL: ${{github.event.pull_request.html_url}}
23
+ GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
File without changes
@@ -7,7 +7,7 @@ A modern, type-safe full-stack monorepo powered by **TanStack Start**, **Better
7
7
  The fastest way to scaffold a new project with the Croissant Stack is using our CLI:
8
8
 
9
9
  ```bash
10
- npx create-croissant@latest
10
+ pnpm dlx create-croissant@latest
11
11
  ```
12
12
 
13
13
  ---
@@ -21,7 +21,7 @@ npx create-croissant@latest
21
21
  - **API**: [oRPC](https://orpc.sh/) with a modular, namespaced router for end-to-end type-safety.
22
22
  - **Database**: [Drizzle ORM](https://orm.drizzle.team/) with PostgreSQL and Docker Compose setup.
23
23
  - **Styling**: [shadcn/ui](https://ui.shadcn.com/) components with Tailwind CSS.
24
- - **Monorepo Management**: Powered by [Turborepo](https://turbo.build/) for lightning-fast builds and smart task orchestration.
24
+ - **Monorepo Management**: Powered by [pnpm](https://pnpm.io/) and [Turborepo](https://turbo.build/) for lightning-fast builds and smart task orchestration.
25
25
  - **Developer Experience**:
26
26
  - Path aliases (`@/`) for clean imports.
27
27
  - Strict TypeScript across the entire stack.
@@ -47,7 +47,7 @@ npx create-croissant@latest
47
47
  ### 1. Install Dependencies
48
48
 
49
49
  ```bash
50
- npm install
50
+ pnpm install
51
51
  ```
52
52
 
53
53
  ### 2. Set Up the Database
@@ -55,7 +55,7 @@ npm install
55
55
  Start the PostgreSQL database using Docker Compose:
56
56
 
57
57
  ```bash
58
- npm run db:up
58
+ pnpm run db:up
59
59
  ```
60
60
 
61
61
  This command runs a PostgreSQL container named `samstack` on port `5432`.
@@ -72,7 +72,7 @@ Ensure you provide the necessary variables:
72
72
 
73
73
  ```env
74
74
  DATABASE_URL=postgresql://postgres:postgres@localhost:5432/auth
75
- BETTER_AUTH_URL=http://localhost:3000
75
+ BETTER_AUTH_URL=https://platform.local
76
76
  BETTER_AUTH_SECRET=your-secret-here
77
77
  ```
78
78
 
@@ -82,36 +82,36 @@ Synchronize your schema with the database:
82
82
 
83
83
  ```bash
84
84
  # From packages/db or via turbo
85
- npm run db:push --filter @workspace/db
85
+ pnpm run db:push --filter @workspace/db
86
86
  ```
87
87
 
88
88
  ### 5. Run Development Server
89
89
 
90
90
  ```bash
91
- npm run dev
91
+ pnpm run dev
92
92
  ```
93
93
 
94
- The web application will be available at `http://localhost:3000`.
94
+ The web application will be available at `https://platform.local`.
95
95
 
96
96
  ## 📦 Scripts
97
97
 
98
98
  All scripts are orchestrated by Turborepo. You can run them from the root directory:
99
99
 
100
100
  ### Core Scripts
101
- - `npm run dev`: Start all applications in development mode.
102
- - `npm run build`: Build all applications for production.
103
- - `npm run quality`: Run all quality checks (linting and formatting) using Oxc.
104
- - `npm run quality:fix`: Automatically fix linting and formatting issues using Oxc.
105
- - `npm run typecheck`: Run TypeScript type checking across the workspace.
106
- - `npm run ci`: Run linting, type-checking, and build (used in CI/CD).
101
+ - `pnpm run dev`: Start all applications in development mode.
102
+ - `pnpm run build`: Build all applications for production.
103
+ - `pnpm run quality`: Run all quality checks (linting and formatting) using Oxc.
104
+ - `pnpm run quality:fix`: Automatically fix linting and formatting issues using Oxc.
105
+ - `pnpm run typecheck`: Run TypeScript type checking across the workspace.
106
+ - `pnpm run ci`: Run linting, type-checking, and build (used in CI/CD).
107
107
 
108
108
  ### 🗄️ Database Scripts
109
109
  These handle Docker and Drizzle operations:
110
- - `npm run db:up`: Start the PostgreSQL Docker container.
111
- - `npm run db:down`: Stop and remove the database container.
112
- - `npm run db:logs`: Tail logs from the database container.
113
- - `npm run db:push --filter @workspace/db`: Push Drizzle schema to the database.
114
- - `npm run db:studio --filter @workspace/db`: Open Drizzle Studio to explore your data.
110
+ - `pnpm run db:up`: Start the PostgreSQL Docker container.
111
+ - `pnpm run db:down`: Stop and remove the database container.
112
+ - `pnpm run db:logs`: Tail logs from the database container.
113
+ - `pnpm run db:push --filter @workspace/db`: Push Drizzle schema to the database.
114
+ - `pnpm run db:studio --filter @workspace/db`: Open Drizzle Studio to explore your data.
115
115
 
116
116
  ## 🎯 Turborepo Power
117
117
 
@@ -120,10 +120,10 @@ Turbo allows you to run tasks for specific packages using the `--filter` flag:
120
120
 
121
121
  ```bash
122
122
  # Only lint the platform app
123
- npm run lint -- --filter platform
123
+ pnpm run lint --filter platform
124
124
 
125
125
  # Build the db package and everything that depends on it
126
- npm run build -- --filter @workspace/db...
126
+ pnpm run build --filter @workspace/db...
127
127
  ```
128
128
 
129
129
  ### Smart Caching
@@ -151,14 +151,14 @@ type Outputs = InferRouterOutputs<typeof router>;
151
151
  To add components to the shared UI package:
152
152
 
153
153
  ```bash
154
- npx shadcn@latest add [component-name] -c apps/platform
154
+ pnpm dlx shadcn@latest add [component-name] -c apps/platform
155
155
  ```
156
156
 
157
157
  This will place the UI components in `packages/ui/src/components`.
158
158
 
159
159
  ## 🛡️ Quality & Git Hooks
160
160
 
161
- This project uses **Husky** to ensure code quality. When pushing to the `main` branch, it automatically runs the CI pipeline (`npm run ci`) to prevent broken code from being pushed.
161
+ This project uses **Husky** to ensure code quality. When pushing to the `main` branch, it automatically runs the CI pipeline (`pnpm run ci`) to prevent broken code from being pushed.
162
162
 
163
163
  Formatting and linting are handled by **Oxc**, which is significantly faster than ESLint and Prettier.
164
164
 
@@ -0,0 +1 @@
1
+ [{"/Users/sam/Dev/croissant-stack/apps/desktop/electron.vite.config.ts":"1","/Users/sam/Dev/croissant-stack/apps/desktop/src/main/index.ts":"2","/Users/sam/Dev/croissant-stack/apps/desktop/src/preload/index.d.ts":"3","/Users/sam/Dev/croissant-stack/apps/desktop/src/preload/index.ts":"4","/Users/sam/Dev/croissant-stack/apps/desktop/src/renderer/src/App.tsx":"5","/Users/sam/Dev/croissant-stack/apps/desktop/src/renderer/src/components/Versions.tsx":"6","/Users/sam/Dev/croissant-stack/apps/desktop/src/renderer/src/env.d.ts":"7","/Users/sam/Dev/croissant-stack/apps/desktop/src/renderer/src/main.tsx":"8","/Users/sam/Dev/croissant-stack/apps/desktop/out/main/index.js":"9","/Users/sam/Dev/croissant-stack/apps/desktop/out/preload/index.js":"10","/Users/sam/Dev/croissant-stack/apps/desktop/eslint.config.ts":"11","/Users/sam/Dev/croissant-stack/apps/desktop/prettier.config.ts":"12"},{"size":318,"mtime":1777164701886,"results":"13","hashOfConfig":"14"},{"size":2424,"mtime":1777164701886,"results":"15","hashOfConfig":"14"},{"size":149,"mtime":1777164701886,"results":"16","hashOfConfig":"14"},{"size":611,"mtime":1777163425865,"results":"17","hashOfConfig":"14"},{"size":1047,"mtime":1777163425865,"results":"18","hashOfConfig":"14"},{"size":428,"mtime":1777163425866,"results":"19","hashOfConfig":"14"},{"size":38,"mtime":1777163425866,"results":"20","hashOfConfig":"14"},{"size":232,"mtime":1777163425866,"results":"21","hashOfConfig":"14"},{"size":1579,"mtime":1777164321368,"results":"22","hashOfConfig":"23"},{"size":477,"mtime":1777164321388,"results":"24","hashOfConfig":"23"},{"size":239,"mtime":1777245470570,"results":"25","hashOfConfig":"14"},{"size":71,"mtime":1777165267271,"results":"26","hashOfConfig":"14"},{"filePath":"27","messages":"28","suppressedMessages":"29","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"19x1ah4",{"filePath":"30","messages":"31","suppressedMessages":"32","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"33","messages":"34","suppressedMessages":"35","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"36","messages":"37","suppressedMessages":"38","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"39","messages":"40","suppressedMessages":"41","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"42","messages":"43","suppressedMessages":"44","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"45","messages":"46","suppressedMessages":"47","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"48","messages":"49","suppressedMessages":"50","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"51","messages":"52","suppressedMessages":"53","errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},"7zths6",{"filePath":"54","messages":"55","suppressedMessages":"56","errorCount":1,"fatalErrorCount":1,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"source":null},{"filePath":"57","messages":"58","suppressedMessages":"59","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"60","messages":"61","suppressedMessages":"62","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"/Users/sam/Dev/croissant-stack/apps/desktop/electron.vite.config.ts",[],[],"/Users/sam/Dev/croissant-stack/apps/desktop/src/main/index.ts",[],[],"/Users/sam/Dev/croissant-stack/apps/desktop/src/preload/index.d.ts",[],[],"/Users/sam/Dev/croissant-stack/apps/desktop/src/preload/index.ts",[],[],"/Users/sam/Dev/croissant-stack/apps/desktop/src/renderer/src/App.tsx",[],[],"/Users/sam/Dev/croissant-stack/apps/desktop/src/renderer/src/components/Versions.tsx",[],[],"/Users/sam/Dev/croissant-stack/apps/desktop/src/renderer/src/env.d.ts",[],[],"/Users/sam/Dev/croissant-stack/apps/desktop/src/renderer/src/main.tsx",[],[],"/Users/sam/Dev/croissant-stack/apps/desktop/out/main/index.js",["63"],[],"/Users/sam/Dev/croissant-stack/apps/desktop/out/preload/index.js",["64"],[],"/Users/sam/Dev/croissant-stack/apps/desktop/eslint.config.ts",[],[],"/Users/sam/Dev/croissant-stack/apps/desktop/prettier.config.ts",[],[],{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"65"},{"ruleId":null,"nodeType":null,"fatal":true,"severity":2,"message":"66"},"Parsing error: /Users/sam/Dev/croissant-stack/apps/desktop/out/main/index.js was not found by the project service. Consider either including it in the tsconfig.json or including it in allowDefaultProject.\nallowDefaultProject is set to [\"*.js\",\"*.mjs\"], which does not match 'out/main/index.js'.","Parsing error: /Users/sam/Dev/croissant-stack/apps/desktop/out/preload/index.js was not found by the project service. Consider either including it in the tsconfig.json or including it in allowDefaultProject.\nallowDefaultProject is set to [\"*.js\",\"*.mjs\"], which does not match 'out/preload/index.js'."]
@@ -11,24 +11,24 @@ An Electron application with React and TypeScript
11
11
  ### Install
12
12
 
13
13
  ```bash
14
- $ npm install
14
+ $ pnpm install
15
15
  ```
16
16
 
17
17
  ### Development
18
18
 
19
19
  ```bash
20
- $ npm run dev
20
+ $ pnpm run dev
21
21
  ```
22
22
 
23
23
  ### Build
24
24
 
25
25
  ```bash
26
26
  # For windows
27
- $ npm run build:win
27
+ $ pnpm run build:win
28
28
 
29
29
  # For macOS
30
- $ npm run build:mac
30
+ $ pnpm run build:mac
31
31
 
32
32
  # For Linux
33
- $ npm run build:linux
33
+ $ pnpm run build:linux
34
34
  ```
@@ -8,13 +8,13 @@
8
8
  "scripts": {
9
9
  "typecheck:node": "tsc --noEmit -p tsconfig.node.json --composite false",
10
10
  "typecheck:web": "tsc --noEmit -p tsconfig.web.json --composite false",
11
- "typecheck": "npm run typecheck:node && npm run typecheck:web",
11
+ "typecheck": "pnpm run typecheck:node && pnpm run typecheck:web",
12
12
  "start": "electron-vite preview",
13
13
  "dev": "electron-vite dev",
14
- "build": "npm run typecheck && electron-vite build",
14
+ "build": "pnpm run typecheck && electron-vite build",
15
15
  "postinstall": "electron-builder install-app-deps",
16
- "build:unpack": "npm run build && electron-builder --dir",
17
- "build:win": "npm run build && electron-builder --win",
16
+ "build:unpack": "pnpm run build && electron-builder --dir",
17
+ "build:win": "pnpm run build && electron-builder --win",
18
18
  "build:mac": "electron-vite build && electron-builder --mac",
19
19
  "build:linux": "electron-vite build && electron-builder --linux"
20
20
  },
@@ -27,7 +27,7 @@
27
27
  "@electron-toolkit/tsconfig": "^2.0.0",
28
28
  "@types/node": "^22.19.1",
29
29
  "@vitejs/plugin-react": "^5.1.1",
30
- "@workspace/config-typescript": "*",
30
+ "@workspace/config-typescript": "workspace:*",
31
31
  "electron": "39.8.9",
32
32
  "electron-builder": "^26.0.12",
33
33
  "electron-vite": "^5.0.0"
@@ -7,13 +7,13 @@ This is an [Expo](https://expo.dev) project created with [`create-expo-app`](htt
7
7
  1. Install dependencies
8
8
 
9
9
  ```bash
10
- npm install
10
+ pnpm install
11
11
  ```
12
12
 
13
13
  2. Start the app
14
14
 
15
15
  ```bash
16
- npx expo start
16
+ pnpm dlx expo start
17
17
  ```
18
18
 
19
19
  In the output, you'll find options to open the app in a
@@ -30,7 +30,7 @@ You can start developing by editing the files inside the **app** directory. This
30
30
  When you're ready, run:
31
31
 
32
32
  ```bash
33
- npm run reset-project
33
+ pnpm run reset-project
34
34
  ```
35
35
 
36
36
  This command will move the starter code to the **app-example** directory and create a blank **app** directory where you can start developing.
@@ -1,34 +1,41 @@
1
- import { Tabs } from "expo-router";
2
1
  import React from "react";
3
-
4
- import { HapticTab } from "@/components/haptic-tab";
5
- import { IconSymbol } from "@/components/ui/icon-symbol";
6
- import { Colors } from "@/constants/theme";
7
- import { useColorScheme } from "@/hooks/use-color-scheme";
2
+ import { Tabs } from "expo-router";
3
+ import { Ionicons } from "@expo/vector-icons";
8
4
 
9
5
  export default function TabLayout() {
10
- const colorScheme = useColorScheme();
11
-
12
6
  return (
13
7
  <Tabs
14
8
  screenOptions={{
15
- tabBarActiveTintColor: Colors[colorScheme ?? "light"].tint,
16
- headerShown: false,
17
- tabBarButton: HapticTab,
9
+ tabBarActiveTintColor: "#000",
10
+ tabBarInactiveTintColor: "#888",
11
+ headerShown: true,
18
12
  }}
19
13
  >
20
14
  <Tabs.Screen
21
15
  name="index"
22
16
  options={{
23
- title: "Home",
24
- tabBarIcon: ({ color }) => <IconSymbol size={28} name="house.fill" color={color} />,
17
+ title: "Dashboard",
18
+ tabBarIcon: ({ color, size }) => (
19
+ <Ionicons name="home" size={size} color={color} />
20
+ ),
25
21
  }}
26
22
  />
27
23
  <Tabs.Screen
28
24
  name="explore"
29
25
  options={{
30
26
  title: "Explore",
31
- tabBarIcon: ({ color }) => <IconSymbol size={28} name="paperplane.fill" color={color} />,
27
+ tabBarIcon: ({ color, size }) => (
28
+ <Ionicons name="planet" size={size} color={color} />
29
+ ),
30
+ }}
31
+ />
32
+ <Tabs.Screen
33
+ name="account"
34
+ options={{
35
+ title: "Account",
36
+ tabBarIcon: ({ color, size }) => (
37
+ <Ionicons name="person" size={size} color={color} />
38
+ ),
32
39
  }}
33
40
  />
34
41
  </Tabs>