plusui-native 0.2.0
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/README.md +162 -0
- package/package.json +36 -0
- package/src/assets/icon-generator.js +251 -0
- package/src/assets/resource-embedder.js +351 -0
- package/src/doctor/detectors/cmake.js +84 -0
- package/src/doctor/detectors/compiler.js +145 -0
- package/src/doctor/detectors/just.js +45 -0
- package/src/doctor/detectors/nodejs.js +57 -0
- package/src/doctor/detectors/webview2.js +66 -0
- package/src/doctor/index.js +184 -0
- package/src/doctor/installers/linux.js +121 -0
- package/src/doctor/installers/macos.js +123 -0
- package/src/doctor/installers/windows.js +117 -0
- package/src/doctor/reporter.js +219 -0
- package/src/index.js +904 -0
- package/templates/base/Justfile +115 -0
- package/templates/base/README.md.template +168 -0
- package/templates/base/assets/README.md +88 -0
- package/templates/base/assets/icon.png +0 -0
- package/templates/manager.js +217 -0
- package/templates/react/.vscode/c_cpp_properties.json +24 -0
- package/templates/react/CMakeLists.txt.template +151 -0
- package/templates/react/frontend/index.html +12 -0
- package/templates/react/frontend/package.json.template +24 -0
- package/templates/react/frontend/src/App.tsx +134 -0
- package/templates/react/frontend/src/main.tsx +10 -0
- package/templates/react/frontend/src/styles/app.css +140 -0
- package/templates/react/frontend/tsconfig.json +21 -0
- package/templates/react/frontend/tsconfig.node.json +11 -0
- package/templates/react/frontend/vite.config.ts +14 -0
- package/templates/react/main.cpp.template +201 -0
- package/templates/react/package.json.template +23 -0
- package/templates/solid/.vscode/c_cpp_properties.json +24 -0
- package/templates/solid/CMakeLists.txt.template +151 -0
- package/templates/solid/frontend/index.html +12 -0
- package/templates/solid/frontend/package.json.template +21 -0
- package/templates/solid/frontend/src/App.tsx +133 -0
- package/templates/solid/frontend/src/main.tsx +5 -0
- package/templates/solid/frontend/src/styles/app.css +140 -0
- package/templates/solid/frontend/tsconfig.json +22 -0
- package/templates/solid/frontend/tsconfig.node.json +11 -0
- package/templates/solid/frontend/vite.config.ts +14 -0
- package/templates/solid/main.cpp.template +192 -0
- package/templates/solid/package.json.template +23 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# PlusUI Project Justfile
|
|
2
|
+
# Cross-platform build automation
|
|
3
|
+
|
|
4
|
+
# Use PowerShell on Windows, bash on Unix
|
|
5
|
+
set windows-shell := ["powershell.exe", "-NoLogo", "-Command"]
|
|
6
|
+
set shell := ["bash", "-cu"]
|
|
7
|
+
|
|
8
|
+
# Project name (from directory)
|
|
9
|
+
project_name := file_stem(justfile_directory())
|
|
10
|
+
|
|
11
|
+
# Default recipe
|
|
12
|
+
default: dev
|
|
13
|
+
|
|
14
|
+
# ============================================================
|
|
15
|
+
# DEVELOPMENT
|
|
16
|
+
# ============================================================
|
|
17
|
+
|
|
18
|
+
# Start development mode (frontend HMR + C++ app)
|
|
19
|
+
dev:
|
|
20
|
+
npm run dev
|
|
21
|
+
|
|
22
|
+
# Start only frontend dev server (Vite with HMR)
|
|
23
|
+
dev-frontend:
|
|
24
|
+
npm run dev:frontend
|
|
25
|
+
|
|
26
|
+
# Start only backend in watch mode
|
|
27
|
+
dev-backend:
|
|
28
|
+
npm run dev:backend
|
|
29
|
+
|
|
30
|
+
# ============================================================
|
|
31
|
+
# BUILD
|
|
32
|
+
# ============================================================
|
|
33
|
+
|
|
34
|
+
# Build for current platform (dev mode, connects to Vite)
|
|
35
|
+
build:
|
|
36
|
+
npm run build
|
|
37
|
+
|
|
38
|
+
# Build frontend only
|
|
39
|
+
build-frontend:
|
|
40
|
+
npm run build:frontend
|
|
41
|
+
|
|
42
|
+
# Build backend only (production mode)
|
|
43
|
+
build-backend:
|
|
44
|
+
npm run build:backend
|
|
45
|
+
|
|
46
|
+
# Build for all platforms
|
|
47
|
+
build-all:
|
|
48
|
+
npm run build:all
|
|
49
|
+
|
|
50
|
+
# ============================================================
|
|
51
|
+
# PLATFORM-SPECIFIC BUILDS
|
|
52
|
+
# ============================================================
|
|
53
|
+
|
|
54
|
+
# Build for Windows
|
|
55
|
+
build-windows:
|
|
56
|
+
@echo "Building for Windows..."
|
|
57
|
+
cmake -S . -B build/Windows -DCMAKE_BUILD_TYPE=Release
|
|
58
|
+
cmake --build build/Windows --config Release
|
|
59
|
+
|
|
60
|
+
# Build for macOS
|
|
61
|
+
build-macos:
|
|
62
|
+
@echo "Building for macOS..."
|
|
63
|
+
cmake -S . -B build/MacOS -G Xcode -DCMAKE_BUILD_TYPE=Release
|
|
64
|
+
cmake --build build/MacOS --config Release
|
|
65
|
+
|
|
66
|
+
# Build for Linux
|
|
67
|
+
build-linux:
|
|
68
|
+
@echo "Building for Linux..."
|
|
69
|
+
cmake -S . -B build/Linux -DCMAKE_BUILD_TYPE=Release
|
|
70
|
+
cmake --build build/Linux --config Release
|
|
71
|
+
|
|
72
|
+
# ============================================================
|
|
73
|
+
# RUN
|
|
74
|
+
# ============================================================
|
|
75
|
+
|
|
76
|
+
# Run the built application
|
|
77
|
+
run:
|
|
78
|
+
npm run start
|
|
79
|
+
|
|
80
|
+
# ============================================================
|
|
81
|
+
# UTILITIES
|
|
82
|
+
# ============================================================
|
|
83
|
+
|
|
84
|
+
# Clean build artifacts
|
|
85
|
+
clean:
|
|
86
|
+
@echo "Cleaning build artifacts..."
|
|
87
|
+
rm -rf build
|
|
88
|
+
rm -rf frontend/dist
|
|
89
|
+
@echo "Done!"
|
|
90
|
+
|
|
91
|
+
# Clean everything including node_modules
|
|
92
|
+
clean-all: clean
|
|
93
|
+
rm -rf node_modules
|
|
94
|
+
rm -rf frontend/node_modules
|
|
95
|
+
|
|
96
|
+
# Install dependencies
|
|
97
|
+
install:
|
|
98
|
+
npm install
|
|
99
|
+
cd frontend && npm install
|
|
100
|
+
|
|
101
|
+
# Check development environment
|
|
102
|
+
doctor:
|
|
103
|
+
plusui doctor
|
|
104
|
+
|
|
105
|
+
# Fix development environment
|
|
106
|
+
doctor-fix:
|
|
107
|
+
plusui doctor --fix
|
|
108
|
+
|
|
109
|
+
# ============================================================
|
|
110
|
+
# HELP
|
|
111
|
+
# ============================================================
|
|
112
|
+
|
|
113
|
+
# Show available commands
|
|
114
|
+
help:
|
|
115
|
+
@just --list
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# {{PROJECT_NAME}}
|
|
2
|
+
|
|
3
|
+
A desktop application built with the PlusUI framework.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
Check your development environment:
|
|
8
|
+
```bash
|
|
9
|
+
plusui doctor
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
If any tools are missing, run:
|
|
13
|
+
```bash
|
|
14
|
+
plusui doctor --fix
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Development
|
|
18
|
+
|
|
19
|
+
Start development server with hot reload:
|
|
20
|
+
```bash
|
|
21
|
+
npm run dev
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
This will:
|
|
25
|
+
- Start the Vite dev server with HMR on http://localhost:5173
|
|
26
|
+
- Build and launch the C++ app pointing to the dev server
|
|
27
|
+
- Changes to frontend code reflect instantly
|
|
28
|
+
- Auto-refresh app bindings when `src/features` exists
|
|
29
|
+
|
|
30
|
+
Note: You can still run `npm run bind` manually anytime.
|
|
31
|
+
|
|
32
|
+
## Bindings (App-level)
|
|
33
|
+
|
|
34
|
+
Generate bindings for your app feature headers:
|
|
35
|
+
```bash
|
|
36
|
+
npm run bind
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Default bindgen paths:
|
|
40
|
+
- Input headers: `src/features`
|
|
41
|
+
- Output: `src/Bindings_Generated`
|
|
42
|
+
|
|
43
|
+
You can also pass custom paths:
|
|
44
|
+
```bash
|
|
45
|
+
plusui bindgen <featuresDir> <outputDir>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Assets & Icons
|
|
49
|
+
|
|
50
|
+
### App Icon
|
|
51
|
+
|
|
52
|
+
Place your app icon at `assets/icon.png` (512x512+ recommended). Generate platform-specific icons:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
plusui icons
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
This creates:
|
|
59
|
+
- **Windows**: `app.ico` for title bar, taskbar, task manager
|
|
60
|
+
- **macOS**: `app.icns` for dock, finder, about dialog
|
|
61
|
+
- **Linux**: Multiple PNG sizes for window managers
|
|
62
|
+
- **Tray**: Small icons for system tray (all platforms)
|
|
63
|
+
|
|
64
|
+
### Embedded Assets
|
|
65
|
+
|
|
66
|
+
All files in `assets/` are embedded into the final executable. Access them in C++:
|
|
67
|
+
|
|
68
|
+
```cpp
|
|
69
|
+
#include <plusui/resources.hpp>
|
|
70
|
+
std::string data = plusui::resources::getResource("path/to/file.png");
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
See `assets/README.md` for details.
|
|
74
|
+
|
|
75
|
+
## Build
|
|
76
|
+
|
|
77
|
+
### Build for current platform
|
|
78
|
+
```bash
|
|
79
|
+
npm run build
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Build also auto-refreshes app bindings when `src/features` exists.
|
|
83
|
+
|
|
84
|
+
### Build for all platforms
|
|
85
|
+
```bash
|
|
86
|
+
npm run build:all
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
This creates platform-specific builds in:
|
|
90
|
+
```
|
|
91
|
+
build/
|
|
92
|
+
├── Windows/ # Windows executable
|
|
93
|
+
├── MacOS/ # macOS app bundle
|
|
94
|
+
└── Linux/ # Linux binary
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Platform-specific builds
|
|
98
|
+
```bash
|
|
99
|
+
plusui build:windows
|
|
100
|
+
plusui build:macos
|
|
101
|
+
plusui build:linux
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Run
|
|
105
|
+
|
|
106
|
+
Run the built application:
|
|
107
|
+
```bash
|
|
108
|
+
npm run start
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Using Just (Optional)
|
|
112
|
+
|
|
113
|
+
If you have [`just`](https://github.com/casey/just) installed:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
just dev # Start development mode
|
|
117
|
+
just build # Build for current platform
|
|
118
|
+
just build-all # Build for all platforms
|
|
119
|
+
just run # Run the built application
|
|
120
|
+
just clean # Clean build artifacts
|
|
121
|
+
just help # Show all commands
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Project Structure
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
{{PROJECT_NAME}}/
|
|
128
|
+
├── src/ # C++ backend code
|
|
129
|
+
│ └── main.cpp # Application entry point
|
|
130
|
+
├── frontend/ # Frontend web code (React + Vite)
|
|
131
|
+
│ ├── src/
|
|
132
|
+
│ │ ├── main.tsx # React entry point
|
|
133
|
+
│ │ ├── App.tsx # Main app component
|
|
134
|
+
│ │ └── styles/ # CSS styles
|
|
135
|
+
│ ├── index.html
|
|
136
|
+
│ └── vite.config.ts
|
|
137
|
+
├── build/ # Build output (generated)
|
|
138
|
+
├── CMakeLists.txt # CMake build configuration
|
|
139
|
+
├── package.json # npm dependencies and scripts
|
|
140
|
+
└── Justfile # Build automation (optional)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Calling C++ from TypeScript
|
|
144
|
+
|
|
145
|
+
Use the `plusui-native-core` SDK to interact with the native backend:
|
|
146
|
+
|
|
147
|
+
```tsx
|
|
148
|
+
import { createPlusUI } from 'plusui-native-core';
|
|
149
|
+
|
|
150
|
+
const plusui = createPlusUI();
|
|
151
|
+
|
|
152
|
+
// Window controls
|
|
153
|
+
await plusui.window.minimize();
|
|
154
|
+
await plusui.window.maximize();
|
|
155
|
+
await plusui.window.close();
|
|
156
|
+
|
|
157
|
+
// Get window info
|
|
158
|
+
const size = await plusui.window.getSize();
|
|
159
|
+
console.log(`Window size: ${size.width}x${size.height}`);
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Learn More
|
|
163
|
+
|
|
164
|
+
- [PlusUI Documentation](https://github.com/yourorg/plusui)
|
|
165
|
+
- [React Documentation](https://react.dev/)
|
|
166
|
+
- [Vite Documentation](https://vitejs.dev/)
|
|
167
|
+
|
|
168
|
+
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Assets Directory
|
|
2
|
+
|
|
3
|
+
## Icon File
|
|
4
|
+
|
|
5
|
+
Place your app icon as **`icon.png`** (512x512 or larger recommended).
|
|
6
|
+
|
|
7
|
+
This single icon will be automatically converted to all platform-specific formats:
|
|
8
|
+
|
|
9
|
+
### Windows
|
|
10
|
+
- `icons/windows/app.ico` - Multi-resolution .ico file
|
|
11
|
+
- Used in: Title bar, taskbar, task manager, system tray
|
|
12
|
+
|
|
13
|
+
### macOS
|
|
14
|
+
- `icons/macos/app.icns` - Apple icon format
|
|
15
|
+
- Used in: Dock, Finder, About dialog, system tray
|
|
16
|
+
|
|
17
|
+
### Linux
|
|
18
|
+
- `icons/linux/icon_*.png` - Multiple PNG sizes
|
|
19
|
+
- Used in: Window manager, system tray, desktop files
|
|
20
|
+
|
|
21
|
+
### Tray Icons
|
|
22
|
+
- `icons/tray/tray_16x16.png` - Small tray icon
|
|
23
|
+
- `icons/tray/tray_32x32.png` - Large tray icon
|
|
24
|
+
- Used in: System tray/notification area (all platforms)
|
|
25
|
+
|
|
26
|
+
## Automatic Generation
|
|
27
|
+
|
|
28
|
+
Run this command to generate all platform icons:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
plusui icons
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Or specify a different source icon:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
plusui icons path/to/my-icon.png
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Icon Guidelines
|
|
41
|
+
|
|
42
|
+
- **Format**: PNG with transparency
|
|
43
|
+
- **Size**: 512x512 pixels minimum (1024x1024 recommended)
|
|
44
|
+
- **Design**: Simple, recognizable at small sizes
|
|
45
|
+
- **Colors**: High contrast for visibility
|
|
46
|
+
|
|
47
|
+
## Other Assets
|
|
48
|
+
|
|
49
|
+
Any other files in this directory will be embedded into your application binary:
|
|
50
|
+
|
|
51
|
+
```cpp
|
|
52
|
+
#include "generated/assets.h"
|
|
53
|
+
|
|
54
|
+
// Access embedded assets
|
|
55
|
+
const char* data = ASSET_MY_FILE_PNG;
|
|
56
|
+
size_t size = ASSET_MY_FILE_PNG_LEN;
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Build Integration
|
|
60
|
+
|
|
61
|
+
Assets are automatically processed during build:
|
|
62
|
+
|
|
63
|
+
1. `plusui icons` - Generates platform-specific icons (manual or in build)
|
|
64
|
+
2. `plusui build` - Embeds all assets into the binary
|
|
65
|
+
3. Production binary includes all resources (single executable!)
|
|
66
|
+
|
|
67
|
+
## Usage in Code
|
|
68
|
+
|
|
69
|
+
### C++ Backend
|
|
70
|
+
```cpp
|
|
71
|
+
#include <plusui/resources.hpp>
|
|
72
|
+
|
|
73
|
+
// Load embedded resource
|
|
74
|
+
std::string html = plusui::resources::getResource("index.html");
|
|
75
|
+
std::string icon = plusui::resources::getResource("icons/tray/tray_32x32.png");
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### TypeScript Frontend
|
|
79
|
+
```typescript
|
|
80
|
+
// Vite handles assets during dev
|
|
81
|
+
import icon from '../assets/icon.png';
|
|
82
|
+
|
|
83
|
+
// In production, assets are served from embedded resources
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
**Note**: The `icons/` subdirectory is auto-generated. Don't edit those files manually!
|
|
Binary file
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { mkdir, readdir, readFile, writeFile, copyFile, stat } from 'fs/promises';
|
|
2
|
+
import { join, dirname, resolve } from 'path';
|
|
3
|
+
import { existsSync } from 'fs';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import { EnvironmentDoctor } from '../src/doctor/index.js';
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import { execSync, spawn } from 'child_process';
|
|
8
|
+
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = dirname(__filename);
|
|
11
|
+
|
|
12
|
+
export class TemplateManager {
|
|
13
|
+
constructor() {
|
|
14
|
+
this.templatesDir = __dirname;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async create(projectName, options = {}) {
|
|
18
|
+
const template = options.template || 'react';
|
|
19
|
+
const templatePath = join(this.templatesDir, template);
|
|
20
|
+
|
|
21
|
+
console.log(chalk.bold(`\nCreating PlusUI project: ${projectName}\n`));
|
|
22
|
+
|
|
23
|
+
// 1. Check environment first
|
|
24
|
+
console.log(chalk.blue('Checking environment...'));
|
|
25
|
+
const doctor = new EnvironmentDoctor();
|
|
26
|
+
const quickCheck = await doctor.quickCheck();
|
|
27
|
+
|
|
28
|
+
if (!quickCheck.ready) {
|
|
29
|
+
console.log(chalk.red('\n✗ Environment not ready!\n'));
|
|
30
|
+
console.log(chalk.yellow('Run: plusui doctor --fix\n'));
|
|
31
|
+
throw new Error('Environment check failed');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
console.log(chalk.green('✓ Environment ready\n'));
|
|
35
|
+
|
|
36
|
+
// 2. Create project directory
|
|
37
|
+
console.log(chalk.blue('Creating project structure...'));
|
|
38
|
+
const projectPath = resolve(projectName);
|
|
39
|
+
|
|
40
|
+
if (existsSync(projectPath)) {
|
|
41
|
+
throw new Error(`Directory ${projectName} already exists`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
await mkdir(projectPath, { recursive: true });
|
|
45
|
+
|
|
46
|
+
// 3. Prepare template variables
|
|
47
|
+
const variables = {
|
|
48
|
+
PROJECT_NAME: projectName,
|
|
49
|
+
PROJECT_NAME_LOWER: projectName.toLowerCase(),
|
|
50
|
+
PROJECT_VERSION: '0.1.0',
|
|
51
|
+
PLUSUI_CORE_PATH: this.resolvePlusUIPath()
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// 4. Copy template files
|
|
55
|
+
await this.copyTemplate(templatePath, projectPath, variables);
|
|
56
|
+
|
|
57
|
+
// 5. Copy base files
|
|
58
|
+
const basePath = join(this.templatesDir, 'base');
|
|
59
|
+
await this.copyTemplate(basePath, projectPath, variables, true);
|
|
60
|
+
|
|
61
|
+
console.log(chalk.green('✓ Project structure created\n'));
|
|
62
|
+
|
|
63
|
+
// 6. Install npm dependencies
|
|
64
|
+
console.log(chalk.blue('Installing dependencies...'));
|
|
65
|
+
await this.runNpmInstall(projectPath);
|
|
66
|
+
console.log(chalk.green('✓ Dependencies installed\n'));
|
|
67
|
+
|
|
68
|
+
// 7. Print success message
|
|
69
|
+
this.printSuccessMessage(projectName);
|
|
70
|
+
|
|
71
|
+
return { success: true, path: projectPath };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async copyTemplate(templatePath, destPath, variables, skipSubdirs = false) {
|
|
75
|
+
if (!existsSync(templatePath)) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const entries = await readdir(templatePath, { withFileTypes: true });
|
|
80
|
+
|
|
81
|
+
for (const entry of entries) {
|
|
82
|
+
const srcPath = join(templatePath, entry.name);
|
|
83
|
+
const destName = entry.name.replace('.template', '');
|
|
84
|
+
const destFilePath = join(destPath, destName);
|
|
85
|
+
|
|
86
|
+
if (entry.isDirectory()) {
|
|
87
|
+
if (!skipSubdirs) {
|
|
88
|
+
await mkdir(destFilePath, { recursive: true });
|
|
89
|
+
await this.copyTemplate(srcPath, destFilePath, variables, false);
|
|
90
|
+
}
|
|
91
|
+
} else {
|
|
92
|
+
// Ensure parent directory exists
|
|
93
|
+
await mkdir(dirname(destFilePath), { recursive: true });
|
|
94
|
+
|
|
95
|
+
// Read file content
|
|
96
|
+
let content = await readFile(srcPath, 'utf8');
|
|
97
|
+
|
|
98
|
+
// Replace variables
|
|
99
|
+
content = this.replaceVariables(content, variables);
|
|
100
|
+
|
|
101
|
+
// Write to destination
|
|
102
|
+
await writeFile(destFilePath, content, 'utf8');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
replaceVariables(content, variables) {
|
|
108
|
+
let result = content;
|
|
109
|
+
|
|
110
|
+
for (const [key, value] of Object.entries(variables)) {
|
|
111
|
+
const placeholder = `{{${key}}}`;
|
|
112
|
+
result = result.split(placeholder).join(value);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
resolvePlusUIPath() {
|
|
119
|
+
// Strategy:
|
|
120
|
+
// 1. Check for global plusui-native-core installation
|
|
121
|
+
// 2. Check for local development version
|
|
122
|
+
// 3. Fall back to npm registry
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
// Check if running in development (from PlusUI repo)
|
|
126
|
+
const localCorePath = resolve(__dirname, '../../plusui-sdk/packages/core');
|
|
127
|
+
if (existsSync(localCorePath)) {
|
|
128
|
+
// Convert Windows backslashes to forward slashes for JSON compatibility
|
|
129
|
+
return `file:${localCorePath.replace(/\\/g, '/')}`;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Check global installation
|
|
133
|
+
const globalPath = this.resolveGlobalPackage('plusui-native-core');
|
|
134
|
+
if (globalPath) {
|
|
135
|
+
return globalPath;
|
|
136
|
+
}
|
|
137
|
+
} catch (e) {
|
|
138
|
+
// Ignore errors, fall back to npm
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Fall back to npm registry (when published)
|
|
142
|
+
return 'plusui-native-core';
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
resolveGlobalPackage(packageName) {
|
|
146
|
+
try {
|
|
147
|
+
const result = execSync(`npm root -g`, { encoding: 'utf8', stdio: ['pipe', 'pipe', 'ignore'] });
|
|
148
|
+
const globalRoot = result.trim();
|
|
149
|
+
const packagePath = join(globalRoot, packageName);
|
|
150
|
+
|
|
151
|
+
if (existsSync(packagePath)) {
|
|
152
|
+
return packagePath;
|
|
153
|
+
}
|
|
154
|
+
} catch (e) {
|
|
155
|
+
// npm not available or package not found
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async runNpmInstall(projectPath) {
|
|
162
|
+
return new Promise((resolve, reject) => {
|
|
163
|
+
const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
164
|
+
|
|
165
|
+
// Install root dependencies
|
|
166
|
+
const rootProc = spawn(npm, ['install'], {
|
|
167
|
+
cwd: projectPath,
|
|
168
|
+
stdio: 'inherit',
|
|
169
|
+
shell: true
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
rootProc.on('close', (code) => {
|
|
173
|
+
if (code !== 0) {
|
|
174
|
+
reject(new Error(`npm install failed with code ${code}`));
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Install frontend dependencies
|
|
179
|
+
const frontendPath = join(projectPath, 'frontend');
|
|
180
|
+
if (existsSync(join(frontendPath, 'package.json'))) {
|
|
181
|
+
const frontendProc = spawn(npm, ['install'], {
|
|
182
|
+
cwd: frontendPath,
|
|
183
|
+
stdio: 'inherit',
|
|
184
|
+
shell: true
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
frontendProc.on('close', (feCode) => {
|
|
188
|
+
if (feCode === 0) {
|
|
189
|
+
resolve();
|
|
190
|
+
} else {
|
|
191
|
+
reject(new Error(`frontend npm install failed with code ${feCode}`));
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
frontendProc.on('error', reject);
|
|
196
|
+
} else {
|
|
197
|
+
resolve();
|
|
198
|
+
}
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
rootProc.on('error', reject);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
printSuccessMessage(projectName) {
|
|
206
|
+
console.log(chalk.green.bold('\n✓ Project created successfully!\n'));
|
|
207
|
+
console.log(chalk.bold('Next steps:\n'));
|
|
208
|
+
console.log(chalk.cyan(` cd ${projectName}`));
|
|
209
|
+
console.log(chalk.cyan(` npm run dev`));
|
|
210
|
+
console.log();
|
|
211
|
+
console.log(chalk.gray('This will start the development server with hot reload.'));
|
|
212
|
+
console.log(chalk.gray('Edit frontend/src/App.tsx and main.cpp to get started!'));
|
|
213
|
+
console.log();
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"configurations": [
|
|
3
|
+
{
|
|
4
|
+
"name": "Windows",
|
|
5
|
+
"includePath": [
|
|
6
|
+
"${workspaceFolder}/src",
|
|
7
|
+
"${workspaceFolder}/../Core/include",
|
|
8
|
+
"${workspaceFolder}/build/dev/_deps/webview2/build/native/include",
|
|
9
|
+
"C:/Users/${env:USERNAME}/.nuget/packages/microsoft.web.webview2/1.0.2903.40/build/native/include"
|
|
10
|
+
],
|
|
11
|
+
"defines": [
|
|
12
|
+
"PLUSUI_DEV_MODE",
|
|
13
|
+
"_WIN32",
|
|
14
|
+
"NDEBUG"
|
|
15
|
+
],
|
|
16
|
+
"compilerPath": "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.43.34808/bin/Hostx64/x64/cl.exe",
|
|
17
|
+
"cStandard": "c17",
|
|
18
|
+
"cppStandard": "c++20",
|
|
19
|
+
"intelliSenseMode": "windows-msvc-x64",
|
|
20
|
+
"compileCommands": "${workspaceFolder}/build/dev/compile_commands.json"
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"version": 4
|
|
24
|
+
}
|