plusui-native 0.2.5 → 0.2.7

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "plusui-native",
3
- "version": "0.2.5",
4
- "description": "PlusUI CLI - Build C++ desktop apps with web tech",
3
+ "version": "0.2.7",
4
+ "description": "PlusUI CLI - Build C++ desktop apps modern UI ",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
7
7
  "bin": {
@@ -27,11 +27,11 @@
27
27
  "semver": "^7.6.0",
28
28
  "which": "^4.0.0",
29
29
  "execa": "^8.0.1",
30
- "plusui-native-builder": "^0.1.5",
31
- "plusui-native-bindgen": "^0.1.5"
30
+ "plusui-native-builder": "^0.1.7",
31
+ "plusui-native-bindgen": "^0.1.7"
32
32
  },
33
33
  "peerDependencies": {
34
- "plusui-native-bindgen": "^0.1.5"
34
+ "plusui-native-bindgen": "^0.1.7"
35
35
  },
36
36
  "publishConfig": {
37
37
  "access": "public"
package/src/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { mkdir, readFile, stat, rm, readdir, writeFile } from 'fs/promises';
4
- import { existsSync, watch, statSync } from 'fs';
3
+ import { mkdir, readFile, stat, rm, readdir, writeFile, copyFile } from 'fs/promises';
4
+ import { existsSync, watch, statSync, mkdirSync } from 'fs';
5
5
  import { exec, spawn, execSync } from 'child_process';
6
6
  import { join, dirname, basename, resolve } from 'path';
7
7
  import { fileURLToPath } from 'url';
@@ -199,9 +199,46 @@ function getAppBindgenPaths() {
199
199
  return {
200
200
  featuresDir: join(process.cwd(), 'src', 'features'),
201
201
  outputDir: join(process.cwd(), 'src', 'Bindings_Generated'),
202
+ frontendOutputDir: join(process.cwd(), 'frontend', 'src', 'Bindings_Generated'),
202
203
  };
203
204
  }
204
205
 
206
+ function ensureBuildLayout() {
207
+ const buildRoot = join(process.cwd(), 'build');
208
+ for (const platform of Object.values(PLATFORMS)) {
209
+ mkdirSync(join(buildRoot, platform.folder), { recursive: true });
210
+ }
211
+ }
212
+
213
+ function resolveBindgenScriptPath() {
214
+ const candidates = [
215
+ resolve(__dirname, '../../plusui-bindgen/src/index.js'),
216
+ resolve(__dirname, '../../plusui-native-bindgen/src/index.js'),
217
+ resolve(__dirname, '../../../plusui-native-bindgen/src/index.js'),
218
+ resolve(process.cwd(), 'node_modules', 'plusui-native-bindgen', 'src', 'index.js'),
219
+ ];
220
+
221
+ for (const candidate of candidates) {
222
+ if (existsSync(candidate)) {
223
+ return candidate;
224
+ }
225
+ }
226
+
227
+ return null;
228
+ }
229
+
230
+ async function syncGeneratedTsBindings(backendOutputDir, frontendOutputDir) {
231
+ const generatedTsPath = join(backendOutputDir, 'bindings.gen.ts');
232
+ if (!existsSync(generatedTsPath)) {
233
+ return;
234
+ }
235
+
236
+ await mkdir(frontendOutputDir, { recursive: true });
237
+ const frontendTsPath = join(frontendOutputDir, 'bindings.gen.ts');
238
+ await copyFile(generatedTsPath, frontendTsPath);
239
+ log(`Synced TS bindings: ${frontendTsPath}`, 'dim');
240
+ }
241
+
205
242
  function promptTemplateSelection() {
206
243
  return new Promise((resolve) => {
207
244
  const rl = createInterface({
@@ -259,9 +296,10 @@ function buildBackend(platform = null, devMode = false) {
259
296
 
260
297
  logSection(`Building Backend (${platformConfig.name})`);
261
298
 
262
- const projectName = getProjectName();
263
299
  const buildDir = `build/${platformConfig.folder}`;
264
300
 
301
+ ensureBuildLayout();
302
+
265
303
  // Create build directory
266
304
  if (!existsSync(buildDir)) {
267
305
  execSync(`mkdir -p "${buildDir}"`, { stdio: 'ignore', shell: true });
@@ -399,6 +437,8 @@ async function build(production = true) {
399
437
  function buildAll() {
400
438
  logSection('Building for All Platforms');
401
439
 
440
+ ensureBuildLayout();
441
+
402
442
  buildFrontend();
403
443
 
404
444
  const supportedPlatforms = ['win32', 'darwin', 'linux'];
@@ -416,6 +456,8 @@ function buildAll() {
416
456
  log(' build/Windows/', 'cyan');
417
457
  log(' build/MacOS/', 'cyan');
418
458
  log(' build/Linux/', 'cyan');
459
+ log(' build/Android/', 'cyan');
460
+ log(' build/iOS/', 'cyan');
419
461
  }
420
462
 
421
463
  function buildPlatform(platform) {
@@ -454,7 +496,8 @@ async function startBackend() {
454
496
  const projectName = getProjectName();
455
497
  killProcessByName(projectName);
456
498
 
457
- const buildDir = 'build/dev';
499
+ const platformFolder = PLATFORMS[process.platform]?.folder || 'Windows';
500
+ const buildDir = join('build', platformFolder, 'dev');
458
501
 
459
502
  // Configure with dev mode if not configured
460
503
  if (!existsSync(join(buildDir, 'CMakeCache.txt'))) {
@@ -627,7 +670,8 @@ function devBackend() {
627
670
  const projectName = getProjectName();
628
671
  killProcessByName(projectName);
629
672
 
630
- const buildDir = 'build/dev';
673
+ const platformFolder = PLATFORMS[process.platform]?.folder || 'Windows';
674
+ const buildDir = join('build', platformFolder, 'dev');
631
675
 
632
676
  if (!existsSync(join(buildDir, 'CMakeCache.txt'))) {
633
677
  log('Configuring CMake...', 'blue');
@@ -700,7 +744,7 @@ function devBackend() {
700
744
  function run() {
701
745
  const projectName = getProjectName();
702
746
  const platform = PLATFORMS[process.platform];
703
- const buildDir = `build/${platform?.folder || 'dev'}`;
747
+ const buildDir = `build/${platform?.folder || 'Windows'}`;
704
748
 
705
749
  let exePath;
706
750
  if (process.platform === 'win32') {
@@ -753,14 +797,9 @@ async function runBindgen(providedArgs = null, options = {}) {
753
797
 
754
798
  const { skipIfNoInput = false, source = 'manual' } = options;
755
799
 
756
- // Try to find the bindgen script
757
- let scriptPath = resolve(__dirname, '../../plusui-bindgen/src/index.js');
758
- if (!existsSync(scriptPath)) {
759
- // Try installed location (node_modules/plusui-native-bindgen)
760
- scriptPath = resolve(__dirname, '../../../plusui-native-bindgen/src/index.js');
761
- }
800
+ const scriptPath = resolveBindgenScriptPath();
762
801
 
763
- if (!existsSync(scriptPath)) {
802
+ if (!scriptPath) {
764
803
  error(`Bindgen script not found. Please ensure plusui-native-bindgen is installed.`);
765
804
  }
766
805
 
@@ -771,11 +810,18 @@ async function runBindgen(providedArgs = null, options = {}) {
771
810
  const args = providedArgs ?? process.argv.slice(3);
772
811
  let bindgenArgs = [...args];
773
812
 
813
+ let usedDefaultAppMode = false;
814
+ let defaultOutputDir = null;
815
+ let defaultFrontendOutputDir = null;
816
+
774
817
  if (bindgenArgs.length === 0) {
775
- const { featuresDir: appFeaturesDir, outputDir: appOutputDir } = getAppBindgenPaths();
818
+ const { featuresDir: appFeaturesDir, outputDir: appOutputDir, frontendOutputDir } = getAppBindgenPaths();
776
819
 
777
820
  if (existsSync(appFeaturesDir)) {
778
821
  bindgenArgs = [appFeaturesDir, appOutputDir];
822
+ usedDefaultAppMode = true;
823
+ defaultOutputDir = appOutputDir;
824
+ defaultFrontendOutputDir = frontendOutputDir;
779
825
  log(`App mode: ${appFeaturesDir} -> ${appOutputDir}`, 'dim');
780
826
  } else {
781
827
  if (skipIfNoInput) {
@@ -794,10 +840,17 @@ async function runBindgen(providedArgs = null, options = {}) {
794
840
  });
795
841
 
796
842
  return new Promise((resolve, reject) => {
797
- proc.on('close', (code) => {
843
+ proc.on('close', async (code) => {
798
844
  if (code === 0) {
799
- log('\nBindgen complete!', 'green');
800
- resolve();
845
+ try {
846
+ if (usedDefaultAppMode && defaultOutputDir && defaultFrontendOutputDir) {
847
+ await syncGeneratedTsBindings(defaultOutputDir, defaultFrontendOutputDir);
848
+ }
849
+ log('\nBindgen complete!', 'green');
850
+ resolve();
851
+ } catch (syncErr) {
852
+ reject(syncErr);
853
+ }
801
854
  } else {
802
855
  reject(new Error(`Bindgen failed with code ${code}`));
803
856
  }
@@ -89,9 +89,11 @@ npm run build:all
89
89
  This creates platform-specific builds in:
90
90
  ```
91
91
  build/
92
- ├── Windows/ # Windows executable
93
- ├── MacOS/ # macOS app bundle
94
- └── Linux/ # Linux binary
92
+ ├── Windows/ # Windows builds
93
+ ├── MacOS/ # macOS builds
94
+ ├── Linux/ # Linux builds
95
+ ├── Android/ # Android builds
96
+ └── iOS/ # iOS builds
95
97
  ```
96
98
 
97
99
  ### Platform-specific builds
@@ -117,13 +117,7 @@ if(WIN32)
117
117
  endif()
118
118
 
119
119
  target_link_libraries({{PROJECT_NAME}} PRIVATE ole32 shell32 shlwapi user32 version)
120
-
121
- # Set subsystem to Windows for release builds (no console window)
122
- if(NOT PLUSUI_DEV_MODE)
123
- set_target_properties({{PROJECT_NAME}} PROPERTIES
124
- WIN32_EXECUTABLE TRUE
125
- )
126
- endif()
120
+ # Keep default console subsystem so standard int main() works in all build modes.
127
121
  elseif(APPLE)
128
122
  # macOS: WebKit
129
123
  find_library(WEBKIT_LIBRARY WebKit REQUIRED)
@@ -117,13 +117,7 @@ if(WIN32)
117
117
  endif()
118
118
 
119
119
  target_link_libraries({{PROJECT_NAME}} PRIVATE ole32 shell32 shlwapi user32 version)
120
-
121
- # Set subsystem to Windows for release builds (no console window)
122
- if(NOT PLUSUI_DEV_MODE)
123
- set_target_properties({{PROJECT_NAME}} PROPERTIES
124
- WIN32_EXECUTABLE TRUE
125
- )
126
- endif()
120
+ # Keep default console subsystem so standard int main() works in all build modes.
127
121
  elseif(APPLE)
128
122
  # macOS: WebKit
129
123
  find_library(WEBKIT_LIBRARY WebKit REQUIRED)