@presencenet/create-pnet-stack 0.0.0-stage → 0.2.1
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/bin/create-pnet-stack.js +106 -0
- package/package.json +26 -4
- package/templates/electron/apps/app/electron.vite.config.ts +13 -0
- package/templates/electron/apps/app/package.json +27 -0
- package/templates/electron/apps/app/src/main/index.ts +22 -0
- package/templates/electron/apps/app/src/preload/index.ts +3 -0
- package/templates/electron/apps/app/src/renderer/index.html +2 -0
- package/templates/electron/apps/app/src/renderer/src/main.tsx +26 -0
- package/templates/electron/apps/app/src/renderer/src/style.css +8 -0
- package/templates/electron/biome.json +7 -0
- package/templates/electron/gitignore +5 -0
- package/templates/electron/package.json +18 -0
- package/templates/electron/turbo.json +8 -0
- package/templates/mobile/apps/app/app/_layout.tsx +17 -0
- package/templates/mobile/apps/app/app/index.tsx +17 -0
- package/templates/mobile/apps/app/app.json +11 -0
- package/templates/mobile/apps/app/babel.config.js +9 -0
- package/templates/mobile/apps/app/global.css +3 -0
- package/templates/mobile/apps/app/metro.config.js +6 -0
- package/templates/mobile/apps/app/nativewind-env.d.ts +1 -0
- package/templates/mobile/apps/app/package.json +33 -0
- package/templates/mobile/apps/app/tailwind.config.js +7 -0
- package/templates/mobile/apps/app/tsconfig.json +11 -0
- package/templates/mobile/biome.json +18 -0
- package/templates/mobile/gitignore +6 -0
- package/templates/mobile/package.json +18 -0
- package/templates/mobile/turbo.json +8 -0
- package/templates/tauri/apps/app/index.html +2 -0
- package/templates/tauri/apps/app/package.json +28 -0
- package/templates/tauri/apps/app/src/main.tsx +26 -0
- package/templates/tauri/apps/app/src/style.css +8 -0
- package/templates/tauri/apps/app/src-tauri/Cargo.toml +20 -0
- package/templates/tauri/apps/app/src-tauri/build.rs +3 -0
- package/templates/tauri/apps/app/src-tauri/src/lib.rs +6 -0
- package/templates/tauri/apps/app/src-tauri/src/main.rs +5 -0
- package/templates/tauri/apps/app/src-tauri/tauri.conf.json +17 -0
- package/templates/tauri/apps/app/tsconfig.json +12 -0
- package/templates/tauri/apps/app/vite.config.ts +18 -0
- package/templates/tauri/biome.json +7 -0
- package/templates/tauri/gitignore +6 -0
- package/templates/tauri/package.json +18 -0
- package/templates/tauri/turbo.json +8 -0
- package/templates/web/apps/app/package.json +26 -0
- package/templates/web/apps/app/src/router.tsx +6 -0
- package/templates/web/apps/app/src/routes/__root.tsx +29 -0
- package/templates/web/apps/app/src/routes/index.tsx +19 -0
- package/templates/web/apps/app/src/styles.css +1 -0
- package/templates/web/apps/app/tsconfig.json +13 -0
- package/templates/web/apps/app/vite.config.ts +8 -0
- package/templates/web/biome.json +7 -0
- package/templates/web/gitignore +7 -0
- package/templates/web/package.json +18 -0
- package/templates/web/turbo.json +11 -0
- package/README.md +0 -3
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { execFileSync } from "node:child_process";
|
|
3
|
+
import {
|
|
4
|
+
cp,
|
|
5
|
+
mkdir,
|
|
6
|
+
readdir,
|
|
7
|
+
readFile,
|
|
8
|
+
rename,
|
|
9
|
+
writeFile,
|
|
10
|
+
} from "node:fs/promises";
|
|
11
|
+
import { dirname, join, resolve } from "node:path";
|
|
12
|
+
import { stdin, stdout } from "node:process";
|
|
13
|
+
import { createInterface } from "node:readline/promises";
|
|
14
|
+
import { fileURLToPath } from "node:url";
|
|
15
|
+
|
|
16
|
+
const templates = ["web", "mobile", "electron", "tauri"];
|
|
17
|
+
const templateNames = {
|
|
18
|
+
web: "TanStack Start",
|
|
19
|
+
mobile: "React Native (Expo)",
|
|
20
|
+
electron: "Electron",
|
|
21
|
+
tauri: "Tauri",
|
|
22
|
+
};
|
|
23
|
+
const cliDir = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
24
|
+
|
|
25
|
+
async function main() {
|
|
26
|
+
const args = process.argv.slice(2);
|
|
27
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
28
|
+
stdout.write(
|
|
29
|
+
"Usage: npx @presencenet/create-pnet-stack [project-name] [--template web|mobile|electron|tauri]\n",
|
|
30
|
+
);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
let projectName = args.find((arg) => !arg.startsWith("--"));
|
|
34
|
+
let template = args
|
|
35
|
+
.find((arg) => arg.startsWith("--template="))
|
|
36
|
+
?.split("=")[1];
|
|
37
|
+
if (!template && args.includes("--template"))
|
|
38
|
+
template = args[args.indexOf("--template") + 1];
|
|
39
|
+
|
|
40
|
+
const rl = createInterface({ input: stdin, output: stdout });
|
|
41
|
+
if (!projectName) projectName = (await rl.question("Project name: ")).trim();
|
|
42
|
+
while (!templates.includes(template)) {
|
|
43
|
+
stdout.write(
|
|
44
|
+
`\nChoose a starter: ${templates.map((item, i) => `${i + 1}) ${templateNames[item]}`).join(" ")}\n`,
|
|
45
|
+
);
|
|
46
|
+
const answer = (await rl.question("Starter [1]: ")).trim() || "1";
|
|
47
|
+
template = templates[Number(answer) - 1] ?? answer;
|
|
48
|
+
if (!templates.includes(template))
|
|
49
|
+
stdout.write("Choose web, mobile, electron, or tauri.\n");
|
|
50
|
+
}
|
|
51
|
+
rl.close();
|
|
52
|
+
|
|
53
|
+
if (!projectName || !/^[a-z0-9][a-z0-9-]*$/.test(projectName))
|
|
54
|
+
throw new Error(
|
|
55
|
+
"Use a lowercase project name containing letters, numbers, or hyphens.",
|
|
56
|
+
);
|
|
57
|
+
const target = resolve(process.cwd(), projectName);
|
|
58
|
+
if (target === process.cwd())
|
|
59
|
+
throw new Error("Choose a project directory name.");
|
|
60
|
+
try {
|
|
61
|
+
if ((await readdir(target)).length)
|
|
62
|
+
throw new Error(`Target directory is not empty: ${target}`);
|
|
63
|
+
} catch (error) {
|
|
64
|
+
if (error.code !== "ENOENT") throw error;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const source = join(cliDir, "templates", template);
|
|
68
|
+
await mkdir(target, { recursive: true });
|
|
69
|
+
await cp(source, target, { recursive: true });
|
|
70
|
+
// npm strips .gitignore from published packages, so templates ship it as gitignore.
|
|
71
|
+
await rename(join(target, "gitignore"), join(target, ".gitignore"));
|
|
72
|
+
const rustName = projectName.replaceAll("-", "_");
|
|
73
|
+
await replaceTokens(target, {
|
|
74
|
+
"{{projectName}}": projectName,
|
|
75
|
+
"{{projectNameRust}}": rustName,
|
|
76
|
+
'"root": false': '"root": true',
|
|
77
|
+
});
|
|
78
|
+
execFileSync("git", ["init"], { cwd: target, stdio: "ignore" });
|
|
79
|
+
stdout.write(`\nCreated ${projectName} (${templateNames[template]}).\n`);
|
|
80
|
+
stdout.write("Initialized Git repository.\n");
|
|
81
|
+
stdout.write(`\n cd ${projectName}\n bun install\n bun run dev\n`);
|
|
82
|
+
if (template === "tauri")
|
|
83
|
+
stdout.write(
|
|
84
|
+
"\nTauri also requires the platform prerequisites: https://tauri.app/start/prerequisites/\n",
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
async function replaceTokens(directory, replacements) {
|
|
89
|
+
for (const entry of await readdir(directory, { withFileTypes: true })) {
|
|
90
|
+
const path = join(directory, entry.name);
|
|
91
|
+
if (entry.isDirectory()) await replaceTokens(path, replacements);
|
|
92
|
+
else {
|
|
93
|
+
const contents = await readFile(path, "utf8");
|
|
94
|
+
const updated = Object.entries(replacements).reduce(
|
|
95
|
+
(text, [token, value]) => text.replaceAll(token, value),
|
|
96
|
+
contents,
|
|
97
|
+
);
|
|
98
|
+
if (updated !== contents) await writeFile(path, updated);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
main().catch((error) => {
|
|
104
|
+
process.stderr.write(`\ncreate-pnet-stack: ${error.message}\n`);
|
|
105
|
+
process.exitCode = 1;
|
|
106
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@presencenet/create-pnet-stack",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "Create a Bun and Turborepo app with pnet-stack",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"create-pnet-stack": "./bin/create-pnet-stack.js"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/Presence-Net/pnet-stack.git",
|
|
12
|
+
"directory": "packages/create-pnet-stack"
|
|
13
|
+
},
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"bin",
|
|
19
|
+
"templates"
|
|
20
|
+
],
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=18"
|
|
23
|
+
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "node --check bin/create-pnet-stack.js",
|
|
26
|
+
"check": "biome check bin"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
2
|
+
import tailwindcss from "@tailwindcss/vite";
|
|
3
|
+
import react from "@vitejs/plugin-react";
|
|
4
|
+
import { defineConfig, externalizeDepsPlugin } from "electron-vite";
|
|
5
|
+
|
|
6
|
+
export default defineConfig({
|
|
7
|
+
main: { plugins: [externalizeDepsPlugin()] },
|
|
8
|
+
preload: { plugins: [externalizeDepsPlugin()] },
|
|
9
|
+
renderer: {
|
|
10
|
+
resolve: { alias: { "@": resolve("src/renderer/src") } },
|
|
11
|
+
plugins: [react(), tailwindcss()],
|
|
12
|
+
},
|
|
13
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@{{projectName}}/app",
|
|
3
|
+
"private": true,
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "out/main/index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "electron-vite dev",
|
|
8
|
+
"build": "electron-vite build",
|
|
9
|
+
"check": "biome check ."
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@tailwindcss/vite": "^4.3.4",
|
|
13
|
+
"react": "^19.3.0",
|
|
14
|
+
"react-dom": "^19.3.0",
|
|
15
|
+
"tailwindcss": "^4.3.4"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@types/node": "^26.6.6",
|
|
19
|
+
"@types/react": "^19.3.0",
|
|
20
|
+
"@types/react-dom": "^19.3.0",
|
|
21
|
+
"@vitejs/plugin-react": "^6.2.1",
|
|
22
|
+
"electron": "^45.2.2",
|
|
23
|
+
"electron-vite": "^6.0.0",
|
|
24
|
+
"typescript": "^6.0.3",
|
|
25
|
+
"vite": "^8.3.5"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { app, BrowserWindow } from "electron";
|
|
3
|
+
|
|
4
|
+
function createWindow() {
|
|
5
|
+
const window = new BrowserWindow({
|
|
6
|
+
width: 1100,
|
|
7
|
+
height: 760,
|
|
8
|
+
webPreferences: {
|
|
9
|
+
preload: join(__dirname, "../preload/index.js"),
|
|
10
|
+
contextIsolation: true,
|
|
11
|
+
nodeIntegration: false,
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
if (process.env.ELECTRON_RENDERER_URL)
|
|
15
|
+
window.loadURL(process.env.ELECTRON_RENDERER_URL);
|
|
16
|
+
else window.loadFile(join(__dirname, "../renderer/index.html"));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
app.whenReady().then(createWindow);
|
|
20
|
+
app.on("window-all-closed", () => {
|
|
21
|
+
if (process.platform !== "darwin") app.quit();
|
|
22
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { createRoot } from "react-dom/client";
|
|
3
|
+
import "./style.css";
|
|
4
|
+
|
|
5
|
+
function App() {
|
|
6
|
+
return (
|
|
7
|
+
<main className="flex min-h-screen flex-col justify-center px-12">
|
|
8
|
+
<p className="text-sm font-bold uppercase tracking-widest text-cyan-300">
|
|
9
|
+
Presence-Net starter
|
|
10
|
+
</p>
|
|
11
|
+
<h1 className="mt-3 text-5xl font-bold">{"{{projectName}}"}</h1>
|
|
12
|
+
<p className="mt-5 text-lg text-slate-300">
|
|
13
|
+
Electron, React, Tailwind, and a Bun-powered Turborepo workspace.
|
|
14
|
+
</p>
|
|
15
|
+
</main>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const root = document.getElementById("root");
|
|
20
|
+
if (!root) throw new Error("Root element not found");
|
|
21
|
+
|
|
22
|
+
createRoot(root).render(
|
|
23
|
+
<React.StrictMode>
|
|
24
|
+
<App />
|
|
25
|
+
</React.StrictMode>,
|
|
26
|
+
);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"root": false,
|
|
3
|
+
"$schema": "https://biomejs.dev/schemas/2.6.5/schema.json",
|
|
4
|
+
"formatter": { "enabled": true, "indentStyle": "space", "indentWidth": 2 },
|
|
5
|
+
"linter": { "enabled": true, "rules": { "preset": "recommended" } },
|
|
6
|
+
"javascript": { "formatter": { "quoteStyle": "double" } }
|
|
7
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{projectName}}",
|
|
3
|
+
"private": true,
|
|
4
|
+
"packageManager": "bun@1.3.14",
|
|
5
|
+
"workspaces": [
|
|
6
|
+
"apps/*",
|
|
7
|
+
"packages/*"
|
|
8
|
+
],
|
|
9
|
+
"scripts": {
|
|
10
|
+
"dev": "turbo run dev",
|
|
11
|
+
"build": "turbo run build",
|
|
12
|
+
"check": "turbo run check"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@biomejs/biome": "2.6.5",
|
|
16
|
+
"turbo": "^2.5.0"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import "../global.css";
|
|
2
|
+
import { Stack } from "expo-router";
|
|
3
|
+
import { StatusBar } from "expo-status-bar";
|
|
4
|
+
|
|
5
|
+
export default function Layout() {
|
|
6
|
+
return (
|
|
7
|
+
<>
|
|
8
|
+
<StatusBar style="light" />
|
|
9
|
+
<Stack
|
|
10
|
+
screenOptions={{
|
|
11
|
+
contentStyle: { backgroundColor: "#020617" },
|
|
12
|
+
headerShown: false,
|
|
13
|
+
}}
|
|
14
|
+
/>
|
|
15
|
+
</>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Text, View } from "react-native";
|
|
2
|
+
|
|
3
|
+
export default function Home() {
|
|
4
|
+
return (
|
|
5
|
+
<View className="flex-1 items-center justify-center bg-slate-950 px-8">
|
|
6
|
+
<Text className="text-sm font-bold uppercase tracking-widest text-cyan-300">
|
|
7
|
+
Presence-Net starter
|
|
8
|
+
</Text>
|
|
9
|
+
<Text className="mt-3 text-4xl font-bold text-white">
|
|
10
|
+
{"{{projectName}}"}
|
|
11
|
+
</Text>
|
|
12
|
+
<Text className="mt-4 text-center text-lg text-slate-300">
|
|
13
|
+
React Native, NativeWind, and a Bun-powered Turborepo workspace.
|
|
14
|
+
</Text>
|
|
15
|
+
</View>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"expo": {
|
|
3
|
+
"name": "{{projectName}}",
|
|
4
|
+
"slug": "{{projectName}}",
|
|
5
|
+
"scheme": "{{projectName}}",
|
|
6
|
+
"plugins": ["expo-router"],
|
|
7
|
+
"experiments": { "typedRoutes": true },
|
|
8
|
+
"ios": { "supportsTablet": true },
|
|
9
|
+
"android": { "package": "net.presence.{{projectNameRust}}" }
|
|
10
|
+
}
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="nativewind/types" />
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@{{projectName}}/app",
|
|
3
|
+
"private": true,
|
|
4
|
+
"main": "expo-router/entry",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "expo start",
|
|
7
|
+
"build": "expo export",
|
|
8
|
+
"check": "biome check ."
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"expo": "~58.0.23",
|
|
12
|
+
"expo-constants": "~58.0.15",
|
|
13
|
+
"expo-linking": "~58.0.16",
|
|
14
|
+
"expo-router": "~58.0.30",
|
|
15
|
+
"expo-splash-screen": "~58.0.13",
|
|
16
|
+
"expo-status-bar": "~58.0.4",
|
|
17
|
+
"nativewind": "^4.2.7",
|
|
18
|
+
"react": "19.3.0",
|
|
19
|
+
"react-native": "0.88.1",
|
|
20
|
+
"react-native-reanimated": "4.7.1",
|
|
21
|
+
"react-native-gesture-handler": "~3.3.0",
|
|
22
|
+
"react-native-safe-area-context": "~5.11.1",
|
|
23
|
+
"react-native-screens": "~4.30.1",
|
|
24
|
+
"react-native-worklets": "0.13.0"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@babel/core": "^7.29.7",
|
|
28
|
+
"@types/react": "~19.3.0",
|
|
29
|
+
"babel-preset-expo": "~58.0.0",
|
|
30
|
+
"tailwindcss": "^3.4.17",
|
|
31
|
+
"typescript": "~6.0.3"
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"root": false,
|
|
3
|
+
"$schema": "https://biomejs.dev/schemas/2.6.5/schema.json",
|
|
4
|
+
"formatter": { "enabled": true, "indentStyle": "space", "indentWidth": 2 },
|
|
5
|
+
"linter": {
|
|
6
|
+
"enabled": true,
|
|
7
|
+
"rules": {
|
|
8
|
+
"preset": "recommended",
|
|
9
|
+
"suspicious": {
|
|
10
|
+
"noUnknownAtRules": {
|
|
11
|
+
"level": "on",
|
|
12
|
+
"options": { "ignore": ["tailwind"] }
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"javascript": { "formatter": { "quoteStyle": "double" } }
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{projectName}}",
|
|
3
|
+
"private": true,
|
|
4
|
+
"packageManager": "bun@1.3.14",
|
|
5
|
+
"workspaces": [
|
|
6
|
+
"apps/*",
|
|
7
|
+
"packages/*"
|
|
8
|
+
],
|
|
9
|
+
"scripts": {
|
|
10
|
+
"dev": "turbo run dev",
|
|
11
|
+
"build": "turbo run build",
|
|
12
|
+
"check": "turbo run check"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@biomejs/biome": "2.6.5",
|
|
16
|
+
"turbo": "^2.5.0"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@{{projectName}}/app",
|
|
3
|
+
"private": true,
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "tauri dev",
|
|
7
|
+
"build": "tauri build",
|
|
8
|
+
"web:dev": "vite --host 0.0.0.0",
|
|
9
|
+
"web:build": "vite build",
|
|
10
|
+
"check": "biome check ."
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@tailwindcss/vite": "^4.3.4",
|
|
14
|
+
"@tauri-apps/api": "^2.12.4",
|
|
15
|
+
"react": "^19.3.0",
|
|
16
|
+
"react-dom": "^19.3.0",
|
|
17
|
+
"tailwindcss": "^4.3.4"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"@types/node": "^26.6.6",
|
|
21
|
+
"@types/react": "^19.3.0",
|
|
22
|
+
"@types/react-dom": "^19.3.0",
|
|
23
|
+
"@tauri-apps/cli": "^2.12.4",
|
|
24
|
+
"@vitejs/plugin-react": "^6.2.1",
|
|
25
|
+
"typescript": "^6.0.3",
|
|
26
|
+
"vite": "^8.3.5"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { createRoot } from "react-dom/client";
|
|
3
|
+
import "./style.css";
|
|
4
|
+
|
|
5
|
+
function App() {
|
|
6
|
+
return (
|
|
7
|
+
<main className="flex min-h-screen flex-col justify-center px-12">
|
|
8
|
+
<p className="text-sm font-bold uppercase tracking-widest text-cyan-300">
|
|
9
|
+
Presence-Net starter
|
|
10
|
+
</p>
|
|
11
|
+
<h1 className="mt-3 text-5xl font-bold">{"{{projectName}}"}</h1>
|
|
12
|
+
<p className="mt-5 text-lg text-slate-300">
|
|
13
|
+
Tauri, React, Tailwind, and a Bun-powered Turborepo workspace.
|
|
14
|
+
</p>
|
|
15
|
+
</main>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const root = document.getElementById("root");
|
|
20
|
+
if (!root) throw new Error("Root element not found");
|
|
21
|
+
|
|
22
|
+
createRoot(root).render(
|
|
23
|
+
<React.StrictMode>
|
|
24
|
+
<App />
|
|
25
|
+
</React.StrictMode>,
|
|
26
|
+
);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
[package]
|
|
2
|
+
name = "{{projectName}}"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "A Presence-Net desktop app"
|
|
5
|
+
authors = ["Presence-Net"]
|
|
6
|
+
edition = "2021"
|
|
7
|
+
|
|
8
|
+
[lib]
|
|
9
|
+
name = "{{projectNameRust}}_lib"
|
|
10
|
+
crate-type = ["staticlib", "cdylib", "rlib"]
|
|
11
|
+
|
|
12
|
+
[build-dependencies]
|
|
13
|
+
tauri-build = { version = "2", features = [] }
|
|
14
|
+
|
|
15
|
+
[dependencies]
|
|
16
|
+
tauri = { version = "2", features = [] }
|
|
17
|
+
|
|
18
|
+
[features]
|
|
19
|
+
default = ["custom-protocol"]
|
|
20
|
+
custom-protocol = ["tauri/custom-protocol"]
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://schema.tauri.app/config/2",
|
|
3
|
+
"productName": "{{projectName}}",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"identifier": "net.presence.{{projectName}}",
|
|
6
|
+
"build": {
|
|
7
|
+
"beforeDevCommand": "bun run web:dev",
|
|
8
|
+
"devUrl": "http://localhost:1420",
|
|
9
|
+
"beforeBuildCommand": "bun run web:build",
|
|
10
|
+
"frontendDist": "../dist"
|
|
11
|
+
},
|
|
12
|
+
"app": {
|
|
13
|
+
"windows": [{ "title": "{{projectName}}", "width": 1100, "height": 760 }],
|
|
14
|
+
"security": { "csp": null }
|
|
15
|
+
},
|
|
16
|
+
"bundle": { "active": true, "targets": "all" }
|
|
17
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import tailwindcss from "@tailwindcss/vite";
|
|
2
|
+
import react from "@vitejs/plugin-react";
|
|
3
|
+
import { defineConfig } from "vite";
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
clearScreen: false,
|
|
7
|
+
server: {
|
|
8
|
+
host: process.env.TAURI_DEV_HOST || "0.0.0.0",
|
|
9
|
+
port: 1420,
|
|
10
|
+
strictPort: true,
|
|
11
|
+
watch: { ignored: ["**/src-tauri/**"] },
|
|
12
|
+
},
|
|
13
|
+
plugins: [react(), tailwindcss()],
|
|
14
|
+
build: {
|
|
15
|
+
target:
|
|
16
|
+
process.env.TAURI_ENV_PLATFORM === "windows" ? "chrome105" : "safari13",
|
|
17
|
+
},
|
|
18
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"root": false,
|
|
3
|
+
"$schema": "https://biomejs.dev/schemas/2.6.5/schema.json",
|
|
4
|
+
"formatter": { "enabled": true, "indentStyle": "space", "indentWidth": 2 },
|
|
5
|
+
"linter": { "enabled": true, "rules": { "preset": "recommended" } },
|
|
6
|
+
"javascript": { "formatter": { "quoteStyle": "double" } }
|
|
7
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{projectName}}",
|
|
3
|
+
"private": true,
|
|
4
|
+
"packageManager": "bun@1.3.14",
|
|
5
|
+
"workspaces": [
|
|
6
|
+
"apps/*",
|
|
7
|
+
"packages/*"
|
|
8
|
+
],
|
|
9
|
+
"scripts": {
|
|
10
|
+
"dev": "turbo run dev",
|
|
11
|
+
"build": "turbo run build",
|
|
12
|
+
"check": "turbo run check"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@biomejs/biome": "2.6.5",
|
|
16
|
+
"turbo": "^2.5.0"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@{{projectName}}/app",
|
|
3
|
+
"private": true,
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "vite dev",
|
|
7
|
+
"build": "vite build",
|
|
8
|
+
"check": "biome check ."
|
|
9
|
+
},
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@tanstack/react-router": "^1.170.46",
|
|
12
|
+
"@tanstack/react-start": "^1.169.4",
|
|
13
|
+
"react": "^19.3.0",
|
|
14
|
+
"react-dom": "^19.3.0"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@tailwindcss/vite": "^4.3.4",
|
|
18
|
+
"@types/node": "^26.6.6",
|
|
19
|
+
"@types/react": "^19.3.0",
|
|
20
|
+
"@types/react-dom": "^19.3.0",
|
|
21
|
+
"@vitejs/plugin-react": "^6.2.1",
|
|
22
|
+
"tailwindcss": "^4.3.4",
|
|
23
|
+
"typescript": "^6.0.3",
|
|
24
|
+
"vite": "^8.3.5"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createRootRoute,
|
|
3
|
+
HeadContent,
|
|
4
|
+
Outlet,
|
|
5
|
+
Scripts,
|
|
6
|
+
} from "@tanstack/react-router";
|
|
7
|
+
import "../styles.css";
|
|
8
|
+
|
|
9
|
+
export const Route = createRootRoute({
|
|
10
|
+
head: () => ({
|
|
11
|
+
meta: [
|
|
12
|
+
{ charSet: "utf-8" },
|
|
13
|
+
{ name: "viewport", content: "width=device-width, initial-scale=1" },
|
|
14
|
+
{ title: "{{projectName}}" },
|
|
15
|
+
{ name: "description", content: "A Presence-Net app" },
|
|
16
|
+
],
|
|
17
|
+
}),
|
|
18
|
+
component: () => (
|
|
19
|
+
<html lang="en">
|
|
20
|
+
<head>
|
|
21
|
+
<HeadContent />
|
|
22
|
+
</head>
|
|
23
|
+
<body className="min-h-screen bg-slate-950 text-white antialiased">
|
|
24
|
+
<Outlet />
|
|
25
|
+
<Scripts />
|
|
26
|
+
</body>
|
|
27
|
+
</html>
|
|
28
|
+
),
|
|
29
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { createFileRoute } from "@tanstack/react-router";
|
|
2
|
+
|
|
3
|
+
export const Route = createFileRoute("/")({
|
|
4
|
+
component: Home,
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
function Home() {
|
|
8
|
+
return (
|
|
9
|
+
<main className="mx-auto flex min-h-screen max-w-3xl flex-col justify-center px-8">
|
|
10
|
+
<p className="mb-3 text-sm font-semibold uppercase tracking-[0.2em] text-cyan-300">
|
|
11
|
+
Presence-Net starter
|
|
12
|
+
</p>
|
|
13
|
+
<h1 className="text-5xl font-bold tracking-tight">{"{{projectName}}"}</h1>
|
|
14
|
+
<p className="mt-5 max-w-xl text-lg text-slate-300">
|
|
15
|
+
TanStack Start, Tailwind CSS, and a Bun-powered Turborepo workspace.
|
|
16
|
+
</p>
|
|
17
|
+
</main>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import "tailwindcss";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"moduleResolution": "Bundler",
|
|
7
|
+
"jsx": "react-jsx",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
"types": ["vite/client"]
|
|
11
|
+
},
|
|
12
|
+
"include": ["src", "vite.config.ts"]
|
|
13
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import tailwindcss from "@tailwindcss/vite";
|
|
2
|
+
import { tanstackStart } from "@tanstack/react-start/plugin/vite";
|
|
3
|
+
import react from "@vitejs/plugin-react";
|
|
4
|
+
import { defineConfig } from "vite";
|
|
5
|
+
|
|
6
|
+
export default defineConfig({
|
|
7
|
+
plugins: [tanstackStart(), react(), tailwindcss()],
|
|
8
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"root": false,
|
|
3
|
+
"$schema": "https://biomejs.dev/schemas/2.6.5/schema.json",
|
|
4
|
+
"formatter": { "enabled": true, "indentStyle": "space", "indentWidth": 2 },
|
|
5
|
+
"linter": { "enabled": true, "rules": { "preset": "recommended" } },
|
|
6
|
+
"javascript": { "formatter": { "quoteStyle": "double" } }
|
|
7
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{projectName}}",
|
|
3
|
+
"private": true,
|
|
4
|
+
"packageManager": "bun@1.3.14",
|
|
5
|
+
"workspaces": [
|
|
6
|
+
"apps/*",
|
|
7
|
+
"packages/*"
|
|
8
|
+
],
|
|
9
|
+
"scripts": {
|
|
10
|
+
"dev": "turbo run dev",
|
|
11
|
+
"build": "turbo run build",
|
|
12
|
+
"check": "turbo run check"
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@biomejs/biome": "2.6.5",
|
|
16
|
+
"turbo": "^2.5.0"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://turbo.build/schema.json",
|
|
3
|
+
"tasks": {
|
|
4
|
+
"build": {
|
|
5
|
+
"dependsOn": ["^build"],
|
|
6
|
+
"outputs": ["dist/**", ".output/**", ".tanstack/**"]
|
|
7
|
+
},
|
|
8
|
+
"dev": { "cache": false, "persistent": true },
|
|
9
|
+
"check": { "dependsOn": ["^check"] }
|
|
10
|
+
}
|
|
11
|
+
}
|
package/README.md
DELETED