create-croissant 0.1.54 → 0.1.56
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.
- package/dist/add.js +9 -9
- package/dist/index.js +8 -8
- package/package.json +1 -1
- package/template/README.md +0 -2
- package/template/apps/platform/package.json +0 -1
- package/template/package.json +0 -2
- package/template/pnpm-workspace.yaml +2 -2
- package/template/apps/desktop/.editorconfig +0 -9
- package/template/apps/desktop/.eslintcache +0 -1
- package/template/apps/desktop/.vscode/extensions.json +0 -3
- package/template/apps/desktop/.vscode/launch.json +0 -39
- package/template/apps/desktop/.vscode/settings.json +0 -11
- package/template/apps/desktop/README.md +0 -34
- package/template/apps/desktop/build/entitlements.mac.plist +0 -12
- package/template/apps/desktop/build/icon.icns +0 -0
- package/template/apps/desktop/build/icon.ico +0 -0
- package/template/apps/desktop/build/icon.png +0 -0
- package/template/apps/desktop/dev-app-update.yml +0 -3
- package/template/apps/desktop/electron-builder.yml +0 -45
- package/template/apps/desktop/electron.vite.config.ts +0 -26
- package/template/apps/desktop/package.json +0 -51
- package/template/apps/desktop/resources/icon.png +0 -0
- package/template/apps/desktop/src/main/index.ts +0 -88
- package/template/apps/desktop/src/preload/index.d.ts +0 -11
- package/template/apps/desktop/src/preload/index.ts +0 -29
- package/template/apps/desktop/src/renderer/index.html +0 -17
- package/template/apps/desktop/src/renderer/src/assets/base.css +0 -67
- package/template/apps/desktop/src/renderer/src/assets/electron.svg +0 -10
- package/template/apps/desktop/src/renderer/src/assets/main.css +0 -171
- package/template/apps/desktop/src/renderer/src/assets/wavy-lines.svg +0 -25
- package/template/apps/desktop/src/renderer/src/components/Versions.tsx +0 -15
- package/template/apps/desktop/src/renderer/src/components/app-sidebar.tsx +0 -186
- package/template/apps/desktop/src/renderer/src/components/login-form.tsx +0 -190
- package/template/apps/desktop/src/renderer/src/components/signup-form.tsx +0 -205
- package/template/apps/desktop/src/renderer/src/env.d.ts +0 -6
- package/template/apps/desktop/src/renderer/src/lib/auth-client.ts +0 -5
- package/template/apps/desktop/src/renderer/src/lib/orpc.ts +0 -12
- package/template/apps/desktop/src/renderer/src/main.tsx +0 -22
- package/template/apps/desktop/src/renderer/src/routeTree.gen.ts +0 -240
- package/template/apps/desktop/src/renderer/src/routes/__root.tsx +0 -48
- package/template/apps/desktop/src/renderer/src/routes/_auth/account.tsx +0 -267
- package/template/apps/desktop/src/renderer/src/routes/_auth/dashboard.tsx +0 -46
- package/template/apps/desktop/src/renderer/src/routes/_auth/examples/client-orpc-auth.tsx +0 -35
- package/template/apps/desktop/src/renderer/src/routes/_auth.tsx +0 -35
- package/template/apps/desktop/src/renderer/src/routes/_public/examples/client-orpc.tsx +0 -310
- package/template/apps/desktop/src/renderer/src/routes/_public/index.tsx +0 -54
- package/template/apps/desktop/src/renderer/src/routes/_public/login.tsx +0 -16
- package/template/apps/desktop/src/renderer/src/routes/_public/signup.tsx +0 -16
- package/template/apps/desktop/src/renderer/src/routes/_public.tsx +0 -23
- package/template/apps/desktop/tsconfig.json +0 -6
- package/template/apps/desktop/tsconfig.node.json +0 -8
- package/template/apps/desktop/tsconfig.web.json +0 -19
- package/template/apps/platform/src/lib/auth-client-electron.ts +0 -13
package/dist/add.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
2
|
+
import s from"path";import{fileURLToPath as x}from"url";import i from"chalk";import{Command as k}from"commander";import{execa as y}from"execa";import t from"fs-extra";import m from"inquirer";import u from"ora";var v=x(import.meta.url),f=s.dirname(v),b=new k;b.name("croissant-add").description("Add a mobile app to an existing Croissant Stack project").action(async()=>{console.log(i.bold.yellow(`
|
|
3
3
|
\u{1F950} Croissant Stack: Add App
|
|
4
|
-
`));let
|
|
4
|
+
`));let n=s.join(process.cwd(),"package.json");await t.pathExists(n)||(console.error(i.red(`
|
|
5
5
|
Error: package.json not found. Are you in the root of your project?
|
|
6
|
-
`)),process.exit(1));let
|
|
6
|
+
`)),process.exit(1));let o=await t.readJson(n);(!o.scripts||!o.scripts.dev&&!o.scripts.build)&&(console.error(i.red(`
|
|
7
7
|
Error: This doesn't look like a Croissant Stack project.
|
|
8
|
-
`)),process.exit(1));let
|
|
9
|
-
`));return}let
|
|
10
|
-
${
|
|
8
|
+
`)),process.exit(1));let c=s.join(process.cwd(),"apps/mobile");if(await t.pathExists(c)){console.log(i.blue(`Mobile app is already present. Nothing to add!
|
|
9
|
+
`));return}let{confirm:h}=await m.prompt([{type:"confirm",name:"confirm",message:"Would you like to add the Mobile App (Expo)?",default:!0}]);if(!h)return;let r=process.cwd(),d=u("Adding mobile app...").start();try{let a=s.join(f,"..","template");await t.pathExists(a)||(a=s.resolve(f,"../../.."));let g=s.join(a,"apps/mobile");await t.copy(g,c),o.scripts=o.scripts||{},o.scripts["dev:mobile"]="turbo run dev --filter=mobile",o.scripts["dev:ios"]="turbo run dev --filter=mobile -- --ios",o.scripts["dev:android"]="turbo run dev --filter=mobile -- --android",o.scripts["build:mobile"]="turbo run build --filter=mobile",await t.writeJson(n,o,{spaces:2});let p=s.join(r,"packages/auth/src/lib/auth.ts");if(await t.pathExists(p)){let e=await t.readFile(p,"utf8");e.includes("@better-auth/expo")||(e=`import { expo } from "@better-auth/expo";
|
|
10
|
+
${e}`),e.includes("plugins: [expo()]")||(e=e.replace("emailAndPassword: { enabled: true },",`emailAndPassword: { enabled: true },
|
|
11
11
|
plugins: [expo()],
|
|
12
12
|
trustedOrigins: [
|
|
13
13
|
"mobile://",
|
|
@@ -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 t.writeFile(
|
|
23
|
-
Next steps:`)),console.log(
|
|
22
|
+
],`)),await t.writeFile(p,e)}let l=s.join(r,"packages/auth/package.json");if(await t.pathExists(l)){let e=await t.readJson(l);e.dependencies=e.dependencies||{},e.dependencies["@better-auth/expo"]||(e.dependencies["@better-auth/expo"]="latest",await t.writeJson(l,e,{spaces:2}))}d.succeed(i.green("Mobile app added successfully!"));let{install:w}=await m.prompt([{type:"confirm",name:"install",message:"Would you like to install dependencies now?",default:!0}]);if(w){let e=u("Installing dependencies...").start();try{await y("pnpm",["install"],{cwd:r}),e.succeed(i.green("Dependencies installed!"))}catch{e.fail(i.red("Failed to install dependencies. Run pnpm install manually."))}}console.log(i.bold.cyan(`
|
|
23
|
+
Next steps:`)),console.log(" pnpm run dev:mobile # Start Expo development server"),console.log(i.yellow(`
|
|
24
24
|
Happy hacking! \u{1F950}
|
|
25
|
-
`))}catch(
|
|
25
|
+
`))}catch(a){d.fail(i.red("An error occurred while adding the mobile app.")),console.error(a),process.exit(1)}});b.parse(process.argv);
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
2
|
+
import n from"path";import{fileURLToPath as b}from"url";import r from"chalk";import{Command as k}from"commander";import{execa as y}from"execa";import e from"fs-extra";import P from"inquirer";import g from"ora";var j=b(import.meta.url),w=n.dirname(j),x=new k;x.name("create-croissant").description("Scaffold a new project using the Croissant Stack").argument("[project-name]","Name of the project").action(async m=>{console.log(r.bold.yellow(`
|
|
3
3
|
\u{1F950} Welcome to the Croissant Stack!
|
|
4
|
-
`));let
|
|
5
|
-
Error: Directory ${
|
|
6
|
-
`)),process.exit(1));let f=g("Scaffolding your project...").start();try{await e.ensureDir(s);let
|
|
4
|
+
`));let u=await P.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}]),p=m||u.name,s=n.resolve(process.cwd(),p);e.existsSync(s)&&(console.error(r.red(`
|
|
5
|
+
Error: Directory ${p} already exists.
|
|
6
|
+
`)),process.exit(1));let f=g("Scaffolding your project...").start();try{await e.ensureDir(s);let l=n.join(w,"..","template");if(await e.pathExists(l))await e.copy(l,s);else{let o=n.resolve(w,"../../.."),i=["node_modules","dist",".git","packages/create-croissant",".turbo","pnpm-lock.yaml"];await e.copy(o,s,{filter:t=>{let c=n.relative(o,t);return!i.some(a=>c.startsWith(a))}})}if(u.mobile){let o=n.join(s,"packages/auth/src/lib/auth.ts");if(await e.pathExists(o)){let t=await e.readFile(o,"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(
|
|
20
|
-
Next steps:`)),console.log(` cd ${
|
|
21
|
-
`),console.log(
|
|
22
|
-
`))}catch(
|
|
19
|
+
],`)),await e.writeFile(o,t)}let i=n.join(s,"packages/auth/package.json");if(await e.pathExists(i)){let t=await e.readJson(i);t.dependencies=t.dependencies||{},t.dependencies["@better-auth/expo"]||(t.dependencies["@better-auth/expo"]="latest",await e.writeJson(i,t,{spaces:2}))}}else{let o=n.join(s,"apps/mobile");if(await e.pathExists(o)){await e.remove(o);let i=n.join(s,"package.json");if(await e.pathExists(i)){let a=await e.readJson(i);a.scripts&&Object.keys(a.scripts).forEach(d=>{(d.includes("mobile")||d.includes("ios")||d.includes("android"))&&delete a.scripts[d]}),await e.writeJson(i,a,{spaces:2})}let t=n.join(s,"packages/auth/src/lib/auth.ts");if(await e.pathExists(t)){let a=await e.readFile(t,"utf8");a=a.replace(/import \{ expo \} from "@better-auth\/expo";\n/,""),a=a.replace(/\s+plugins: \[expo\(\)\],/,""),a=a.replace(/\s+trustedOrigins: \[[\s\S]*?\],/,""),await e.writeFile(t,a)}let c=n.join(s,"packages/auth/package.json");if(await e.pathExists(c)){let a=await e.readJson(c);a.dependencies&&a.dependencies["@better-auth/expo"]&&(delete a.dependencies["@better-auth/expo"],await e.writeJson(c,a,{spaces:2}))}}}let h=n.join(s,"package.json");if(await e.pathExists(h)){let o=await e.readJson(h);o.name=p,o.version="0.1.0",delete o.private,await e.writeJson(h,o,{spaces:2})}if(f.succeed(r.green(`Project ${p} created at ${s}`)),u.install){let o=g("Installing dependencies...").start();try{await y("pnpm",["install"],{cwd:s}),o.succeed(r.green("Dependencies installed!"))}catch{o.fail(r.red("Failed to install dependencies. You may need to run pnpm install manually."))}}console.log(r.bold.cyan(`
|
|
20
|
+
Next steps:`)),console.log(` cd ${p}`),console.log(" pnpm run db:up # Start your PostgreSQL database"),console.log(` pnpm run dev # Start development server
|
|
21
|
+
`),console.log(r.yellow(`Happy hacking! \u{1F950}
|
|
22
|
+
`))}catch(l){f.fail(r.red("An error occurred during scaffolding.")),console.error(l),process.exit(1)}});x.parse(process.argv);
|
package/package.json
CHANGED
package/template/README.md
CHANGED
|
@@ -16,7 +16,6 @@ pnpm dlx create-croissant@latest
|
|
|
16
16
|
|
|
17
17
|
- **Web (Platform)**: [TanStack Start](https://tanstack.com/start) for a seamless, type-safe React experience.
|
|
18
18
|
- **Mobile**: [Expo](https://expo.dev/) (React Native) for cross-platform mobile development.
|
|
19
|
-
- **Desktop**: [Electron](https://www.electronjs.org/) with [electron-vite](https://electron-vite.org/) for native desktop applications.
|
|
20
19
|
- **Authentication**: [Better Auth](https://www.better-auth.com/) with Drizzle adapter and PostgreSQL.
|
|
21
20
|
- **API**: [oRPC](https://orpc.sh/) with a modular, namespaced router for end-to-end type-safety.
|
|
22
21
|
- **Database**: [Drizzle ORM](https://orm.drizzle.team/) with PostgreSQL and Docker Compose setup.
|
|
@@ -32,7 +31,6 @@ pnpm dlx create-croissant@latest
|
|
|
32
31
|
### Apps
|
|
33
32
|
- `apps/platform`: The main TanStack Start web application.
|
|
34
33
|
- `apps/mobile`: Expo-powered mobile application.
|
|
35
|
-
- `apps/desktop`: Electron-powered desktop application.
|
|
36
34
|
|
|
37
35
|
### Packages
|
|
38
36
|
- `packages/auth` (`@workspace/auth`): Authentication logic and Better Auth configuration.
|
package/template/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
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'."]
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": "0.2.0",
|
|
3
|
-
"configurations": [
|
|
4
|
-
{
|
|
5
|
-
"name": "Debug Main Process",
|
|
6
|
-
"type": "node",
|
|
7
|
-
"request": "launch",
|
|
8
|
-
"cwd": "${workspaceRoot}",
|
|
9
|
-
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron-vite",
|
|
10
|
-
"windows": {
|
|
11
|
-
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron-vite.cmd"
|
|
12
|
-
},
|
|
13
|
-
"runtimeArgs": ["--sourcemap"],
|
|
14
|
-
"env": {
|
|
15
|
-
"REMOTE_DEBUGGING_PORT": "9222"
|
|
16
|
-
}
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
"name": "Debug Renderer Process",
|
|
20
|
-
"port": 9222,
|
|
21
|
-
"request": "attach",
|
|
22
|
-
"type": "chrome",
|
|
23
|
-
"webRoot": "${workspaceFolder}/src/renderer",
|
|
24
|
-
"timeout": 60000,
|
|
25
|
-
"presentation": {
|
|
26
|
-
"hidden": true
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
],
|
|
30
|
-
"compounds": [
|
|
31
|
-
{
|
|
32
|
-
"name": "Debug All",
|
|
33
|
-
"configurations": ["Debug Main Process", "Debug Renderer Process"],
|
|
34
|
-
"presentation": {
|
|
35
|
-
"order": 1
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
]
|
|
39
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# desktop
|
|
2
|
-
|
|
3
|
-
An Electron application with React and TypeScript
|
|
4
|
-
|
|
5
|
-
## Recommended IDE Setup
|
|
6
|
-
|
|
7
|
-
- [VSCode](https://code.visualstudio.com/)
|
|
8
|
-
|
|
9
|
-
## Project Setup
|
|
10
|
-
|
|
11
|
-
### Install
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
$ pnpm install
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
### Development
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
$ pnpm run dev
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
### Build
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
# For windows
|
|
27
|
-
$ pnpm run build:win
|
|
28
|
-
|
|
29
|
-
# For macOS
|
|
30
|
-
$ pnpm run build:mac
|
|
31
|
-
|
|
32
|
-
# For Linux
|
|
33
|
-
$ pnpm run build:linux
|
|
34
|
-
```
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
-
<plist version="1.0">
|
|
4
|
-
<dict>
|
|
5
|
-
<key>com.apple.security.cs.allow-jit</key>
|
|
6
|
-
<true/>
|
|
7
|
-
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
|
8
|
-
<true/>
|
|
9
|
-
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
|
|
10
|
-
<true/>
|
|
11
|
-
</dict>
|
|
12
|
-
</plist>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
appId: com.electron.app
|
|
2
|
-
productName: desktop
|
|
3
|
-
directories:
|
|
4
|
-
buildResources: build
|
|
5
|
-
files:
|
|
6
|
-
- "!**/.vscode/*"
|
|
7
|
-
- "!src/*"
|
|
8
|
-
- "!electron.vite.config.{js,ts,mjs,cjs}"
|
|
9
|
-
- "!{dev-app-update.yml,CHANGELOG.md,README.md}"
|
|
10
|
-
- "!{.env,.env.*,.npmrc,pnpm-lock.yaml}"
|
|
11
|
-
- "!{tsconfig.json,tsconfig.node.json,tsconfig.web.json}"
|
|
12
|
-
asarUnpack:
|
|
13
|
-
- resources/**
|
|
14
|
-
win:
|
|
15
|
-
executableName: desktop
|
|
16
|
-
nsis:
|
|
17
|
-
artifactName: ${name}-${version}-setup.${ext}
|
|
18
|
-
shortcutName: ${productName}
|
|
19
|
-
uninstallDisplayName: ${productName}
|
|
20
|
-
createDesktopShortcut: always
|
|
21
|
-
mac:
|
|
22
|
-
entitlementsInherit: build/entitlements.mac.plist
|
|
23
|
-
extendInfo:
|
|
24
|
-
- NSCameraUsageDescription: Application requests access to the device's camera.
|
|
25
|
-
- NSMicrophoneUsageDescription: Application requests access to the device's microphone.
|
|
26
|
-
- NSDocumentsFolderUsageDescription: Application requests access to the user's Documents folder.
|
|
27
|
-
- NSDownloadsFolderUsageDescription: Application requests access to the user's Downloads folder.
|
|
28
|
-
notarize: false
|
|
29
|
-
dmg:
|
|
30
|
-
artifactName: ${name}-${version}.${ext}
|
|
31
|
-
linux:
|
|
32
|
-
target:
|
|
33
|
-
- AppImage
|
|
34
|
-
- snap
|
|
35
|
-
- deb
|
|
36
|
-
maintainer: electronjs.org
|
|
37
|
-
category: Utility
|
|
38
|
-
appImage:
|
|
39
|
-
artifactName: ${name}-${version}.${ext}
|
|
40
|
-
npmRebuild: false
|
|
41
|
-
publish:
|
|
42
|
-
provider: generic
|
|
43
|
-
url: https://example.com/auto-updates
|
|
44
|
-
electronDownload:
|
|
45
|
-
mirror: https://npmmirror.com/mirrors/electron/
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { resolve } from "node:path";
|
|
2
|
-
import { defineConfig } from "electron-vite";
|
|
3
|
-
import react from "@vitejs/plugin-react";
|
|
4
|
-
import { tanstackRouter } from "@tanstack/router-plugin/vite";
|
|
5
|
-
import tailwindcss from "@tailwindcss/vite";
|
|
6
|
-
|
|
7
|
-
export default defineConfig({
|
|
8
|
-
main: {},
|
|
9
|
-
preload: {},
|
|
10
|
-
renderer: {
|
|
11
|
-
resolve: {
|
|
12
|
-
alias: {
|
|
13
|
-
"@": resolve("src/renderer/src"),
|
|
14
|
-
"@renderer": resolve("src/renderer/src"),
|
|
15
|
-
},
|
|
16
|
-
},
|
|
17
|
-
plugins: [
|
|
18
|
-
tanstackRouter({
|
|
19
|
-
routesDirectory: resolve("src/renderer/src/routes"),
|
|
20
|
-
generatedRouteTree: resolve("src/renderer/src/routeTree.gen.ts"),
|
|
21
|
-
}),
|
|
22
|
-
tailwindcss(),
|
|
23
|
-
react(),
|
|
24
|
-
],
|
|
25
|
-
},
|
|
26
|
-
});
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "desktop",
|
|
3
|
-
"version": "1.0.0",
|
|
4
|
-
"description": "An Electron application with React and TypeScript",
|
|
5
|
-
"homepage": "https://electron-vite.org",
|
|
6
|
-
"author": "example.com",
|
|
7
|
-
"main": "./out/main/index.js",
|
|
8
|
-
"scripts": {
|
|
9
|
-
"typecheck:node": "tsc --noEmit -p tsconfig.node.json --composite false",
|
|
10
|
-
"typecheck:web": "tsc --noEmit -p tsconfig.web.json --composite false",
|
|
11
|
-
"typecheck": "pnpm run typecheck:node && pnpm run typecheck:web",
|
|
12
|
-
"start": "electron-vite preview",
|
|
13
|
-
"dev": "electron-vite dev",
|
|
14
|
-
"build": "pnpm run typecheck && electron-vite build",
|
|
15
|
-
"postinstall": "electron-builder install-app-deps",
|
|
16
|
-
"build:unpack": "pnpm run build && electron-builder --dir",
|
|
17
|
-
"build:win": "pnpm run build && electron-builder --win",
|
|
18
|
-
"build:mac": "electron-vite build && electron-builder --mac",
|
|
19
|
-
"build:linux": "electron-vite build && electron-builder --linux"
|
|
20
|
-
},
|
|
21
|
-
"dependencies": {
|
|
22
|
-
"@electron-toolkit/preload": "^3.0.2",
|
|
23
|
-
"@electron-toolkit/utils": "^4.0.0",
|
|
24
|
-
"@tailwindcss/vite": "^4.2.4",
|
|
25
|
-
"@tanstack/react-router": "^1.169.2",
|
|
26
|
-
"@workspace/auth": "workspace:*",
|
|
27
|
-
"@workspace/orpc": "workspace:*",
|
|
28
|
-
"@workspace/ui": "workspace:*",
|
|
29
|
-
"better-auth": "1.6.11",
|
|
30
|
-
"electron-updater": "^6.3.9",
|
|
31
|
-
"lucide-react": "^1.14.0",
|
|
32
|
-
"react": "19.2.5",
|
|
33
|
-
"react-dom": "19.2.5",
|
|
34
|
-
"sonner": "^2.0.7",
|
|
35
|
-
"tailwindcss": "^4.2.4"
|
|
36
|
-
},
|
|
37
|
-
"devDependencies": {
|
|
38
|
-
"@electron-toolkit/tsconfig": "^2.0.0",
|
|
39
|
-
"@tanstack/react-router-devtools": "^1.166.13",
|
|
40
|
-
"@tanstack/router-plugin": "^1.167.35",
|
|
41
|
-
"@types/node": "^22.19.1",
|
|
42
|
-
"@types/react": "^19.2.14",
|
|
43
|
-
"@types/react-dom": "^19.2.3",
|
|
44
|
-
"@vitejs/plugin-react": "^5.1.1",
|
|
45
|
-
"@workspace/config-typescript": "workspace:*",
|
|
46
|
-
"electron": "39.8.9",
|
|
47
|
-
"electron-builder": "^26.0.12",
|
|
48
|
-
"electron-vite": "^5.0.0",
|
|
49
|
-
"vite": "^8.0.12"
|
|
50
|
-
}
|
|
51
|
-
}
|
|
Binary file
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
|
-
import { BrowserWindow, app, ipcMain, shell } from "electron";
|
|
3
|
-
import { electronApp, is, optimizer } from "@electron-toolkit/utils";
|
|
4
|
-
import icon from "../../resources/icon.png?asset";
|
|
5
|
-
|
|
6
|
-
function createWindow(): void {
|
|
7
|
-
// Create the browser window.
|
|
8
|
-
const mainWindow = new BrowserWindow({
|
|
9
|
-
width: 900,
|
|
10
|
-
height: 670,
|
|
11
|
-
show: false,
|
|
12
|
-
autoHideMenuBar: true,
|
|
13
|
-
...(process.platform === "linux" ? { icon } : {}),
|
|
14
|
-
webPreferences: {
|
|
15
|
-
preload: join(__dirname, "../preload/index.js"),
|
|
16
|
-
sandbox: false,
|
|
17
|
-
},
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
// Handle deep links
|
|
21
|
-
if (process.defaultApp) {
|
|
22
|
-
if (process.argv.length >= 2) {
|
|
23
|
-
app.setAsDefaultProtocolClient("desktop", process.execPath, [join(__dirname, "../../")]);
|
|
24
|
-
}
|
|
25
|
-
} else {
|
|
26
|
-
app.setAsDefaultProtocolClient("desktop");
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
app.on("open-url", (event, url) => {
|
|
30
|
-
event.preventDefault();
|
|
31
|
-
mainWindow.webContents.send("auth-callback", url);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
mainWindow.on("ready-to-show", () => {
|
|
35
|
-
mainWindow.show();
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
mainWindow.webContents.setWindowOpenHandler((details) => {
|
|
39
|
-
shell.openExternal(details.url);
|
|
40
|
-
return { action: "deny" };
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
// HMR for renderer base on electron-vite cli.
|
|
44
|
-
// Load the remote URL for development or the local html file for production.
|
|
45
|
-
if (is.dev && process.env["ELECTRON_RENDERER_URL"]) {
|
|
46
|
-
mainWindow.loadURL(process.env["ELECTRON_RENDERER_URL"]);
|
|
47
|
-
} else {
|
|
48
|
-
mainWindow.loadFile(join(__dirname, "../renderer/index.html"));
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// This method will be called when Electron has finished
|
|
53
|
-
// initialization and is ready to create browser windows.
|
|
54
|
-
// Some APIs can only be used after this event occurs.
|
|
55
|
-
app.whenReady().then(() => {
|
|
56
|
-
// Set app user model id for windows
|
|
57
|
-
electronApp.setAppUserModelId("com.electron");
|
|
58
|
-
|
|
59
|
-
// Default open or close DevTools by F12 in development
|
|
60
|
-
// and ignore CommandOrControl + R in production.
|
|
61
|
-
// see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
|
|
62
|
-
app.on("browser-window-created", (_, window) => {
|
|
63
|
-
optimizer.watchWindowShortcuts(window);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
// IPC test
|
|
67
|
-
ipcMain.on("ping", () => console.log("pong"));
|
|
68
|
-
|
|
69
|
-
createWindow();
|
|
70
|
-
|
|
71
|
-
app.on("activate", function () {
|
|
72
|
-
// On macOS it's common to re-create a window in the app when the
|
|
73
|
-
// dock icon is clicked and there are no other windows open.
|
|
74
|
-
if (BrowserWindow.getAllWindows().length === 0) createWindow();
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
// Quit when all windows are closed, except on macOS. There, it's common
|
|
79
|
-
// for applications and their menu bar to stay active until the user quits
|
|
80
|
-
// explicitly with Cmd + Q.
|
|
81
|
-
app.on("window-all-closed", () => {
|
|
82
|
-
if (process.platform !== "darwin") {
|
|
83
|
-
app.quit();
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
// In this file you can include the rest of your app's specific main process
|
|
88
|
-
// code. You can also put them in separate files and require them here.
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { ElectronAPI } from "@electron-toolkit/preload";
|
|
2
|
-
|
|
3
|
-
declare global {
|
|
4
|
-
interface Window {
|
|
5
|
-
electron: ElectronAPI;
|
|
6
|
-
api: {
|
|
7
|
-
onAuthCallback: (callback: (url: string) => void) => () => void;
|
|
8
|
-
openExternal: (url: string) => Promise<void>;
|
|
9
|
-
};
|
|
10
|
-
}
|
|
11
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { contextBridge, ipcRenderer, shell } from "electron";
|
|
2
|
-
import { electronAPI } from "@electron-toolkit/preload";
|
|
3
|
-
|
|
4
|
-
// Custom APIs for renderer
|
|
5
|
-
const api = {
|
|
6
|
-
onAuthCallback: (callback: (url: string) => void) => {
|
|
7
|
-
const listener = (_: any, url: string) => callback(url);
|
|
8
|
-
ipcRenderer.on("auth-callback", listener);
|
|
9
|
-
return () => ipcRenderer.removeListener("auth-callback", listener);
|
|
10
|
-
},
|
|
11
|
-
openExternal: (url: string) => shell.openExternal(url),
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
// Use `contextBridge` APIs to expose Electron APIs to
|
|
15
|
-
// renderer only if context isolation is enabled, otherwise
|
|
16
|
-
// just add to the DOM global.
|
|
17
|
-
if (process.contextIsolated) {
|
|
18
|
-
try {
|
|
19
|
-
contextBridge.exposeInMainWorld("electron", electronAPI);
|
|
20
|
-
contextBridge.exposeInMainWorld("api", api);
|
|
21
|
-
} catch (error) {
|
|
22
|
-
console.error(error);
|
|
23
|
-
}
|
|
24
|
-
} else {
|
|
25
|
-
// @ts-ignore (define in dts)
|
|
26
|
-
window.electron = electronAPI;
|
|
27
|
-
// @ts-ignore (define in dts)
|
|
28
|
-
window.api = api;
|
|
29
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<title>Electron</title>
|
|
6
|
-
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
|
7
|
-
<meta
|
|
8
|
-
http-equiv="Content-Security-Policy"
|
|
9
|
-
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self' https://platform.localhost"
|
|
10
|
-
/>
|
|
11
|
-
</head>
|
|
12
|
-
|
|
13
|
-
<body>
|
|
14
|
-
<div id="root"></div>
|
|
15
|
-
<script type="module" src="/src/main.tsx"></script>
|
|
16
|
-
</body>
|
|
17
|
-
</html>
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
:root {
|
|
2
|
-
--ev-c-white: #ffffff;
|
|
3
|
-
--ev-c-white-soft: #f8f8f8;
|
|
4
|
-
--ev-c-white-mute: #f2f2f2;
|
|
5
|
-
|
|
6
|
-
--ev-c-black: #1b1b1f;
|
|
7
|
-
--ev-c-black-soft: #222222;
|
|
8
|
-
--ev-c-black-mute: #282828;
|
|
9
|
-
|
|
10
|
-
--ev-c-gray-1: #515c67;
|
|
11
|
-
--ev-c-gray-2: #414853;
|
|
12
|
-
--ev-c-gray-3: #32363f;
|
|
13
|
-
|
|
14
|
-
--ev-c-text-1: rgba(255, 255, 245, 0.86);
|
|
15
|
-
--ev-c-text-2: rgba(235, 235, 245, 0.6);
|
|
16
|
-
--ev-c-text-3: rgba(235, 235, 245, 0.38);
|
|
17
|
-
|
|
18
|
-
--ev-button-alt-border: transparent;
|
|
19
|
-
--ev-button-alt-text: var(--ev-c-text-1);
|
|
20
|
-
--ev-button-alt-bg: var(--ev-c-gray-3);
|
|
21
|
-
--ev-button-alt-hover-border: transparent;
|
|
22
|
-
--ev-button-alt-hover-text: var(--ev-c-text-1);
|
|
23
|
-
--ev-button-alt-hover-bg: var(--ev-c-gray-2);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
:root {
|
|
27
|
-
--color-background: var(--ev-c-black);
|
|
28
|
-
--color-background-soft: var(--ev-c-black-soft);
|
|
29
|
-
--color-background-mute: var(--ev-c-black-mute);
|
|
30
|
-
|
|
31
|
-
--color-text: var(--ev-c-text-1);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
*,
|
|
35
|
-
*::before,
|
|
36
|
-
*::after {
|
|
37
|
-
box-sizing: border-box;
|
|
38
|
-
margin: 0;
|
|
39
|
-
font-weight: normal;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
ul {
|
|
43
|
-
list-style: none;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
body {
|
|
47
|
-
min-height: 100vh;
|
|
48
|
-
color: var(--color-text);
|
|
49
|
-
background: var(--color-background);
|
|
50
|
-
line-height: 1.6;
|
|
51
|
-
font-family:
|
|
52
|
-
Inter,
|
|
53
|
-
-apple-system,
|
|
54
|
-
BlinkMacSystemFont,
|
|
55
|
-
"Segoe UI",
|
|
56
|
-
Roboto,
|
|
57
|
-
Oxygen,
|
|
58
|
-
Ubuntu,
|
|
59
|
-
Cantarell,
|
|
60
|
-
"Fira Sans",
|
|
61
|
-
"Droid Sans",
|
|
62
|
-
"Helvetica Neue",
|
|
63
|
-
sans-serif;
|
|
64
|
-
text-rendering: optimizeLegibility;
|
|
65
|
-
-webkit-font-smoothing: antialiased;
|
|
66
|
-
-moz-osx-font-smoothing: grayscale;
|
|
67
|
-
}
|