@lotus-gui/dev 0.1.0 ā 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 +40 -4
- package/bin/lotus.js +226 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -27,7 +27,43 @@ lotus dev main.js # Custom entry point
|
|
|
27
27
|
- Auto-restarts on any file change
|
|
28
28
|
- Kills the previous process cleanly
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
- Kills the previous process cleanly
|
|
31
|
+
|
|
32
|
+
### `lotus init [projectName]`
|
|
33
|
+
|
|
34
|
+
Initialize a new Lotus project with interactive prompts.
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
lotus init # Prompts for project name
|
|
38
|
+
lotus init my-app # Creates 'my-app' directory
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
**Interactive Prompts:**
|
|
42
|
+
If flags are not provided, the CLI will ask for:
|
|
43
|
+
- Project Name (directory)
|
|
44
|
+
- Application Name
|
|
45
|
+
- Version
|
|
46
|
+
- Description
|
|
47
|
+
- Author
|
|
48
|
+
- Homepage / Repository URL (Important for Linux packages)
|
|
49
|
+
- License
|
|
50
|
+
|
|
51
|
+
**Non-Interactive Flags:**
|
|
52
|
+
You can skip prompts by providing flags:
|
|
53
|
+
```bash
|
|
54
|
+
lotus init my-app --name "My App" --app-version 1.0.0 --homepage "https://example.com"
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
| Flag | Description |
|
|
58
|
+
|------|-------------|
|
|
59
|
+
| `--name` | Application display name |
|
|
60
|
+
| `--app-version` | Application version (e.g., `1.0.0`) |
|
|
61
|
+
| `--description` | Short description |
|
|
62
|
+
| `--author` | Author name |
|
|
63
|
+
| `--homepage` | Repository or homepage URL |
|
|
64
|
+
| `--license` | License identifier (default: `MIT`) |
|
|
65
|
+
|
|
66
|
+
### `lotus build`
|
|
31
67
|
|
|
32
68
|
Build your application into a distributable installer package.
|
|
33
69
|
|
|
@@ -38,7 +74,7 @@ lotus build --platform linux --target rpm
|
|
|
38
74
|
|
|
39
75
|
| Flag | Values | Default | Description |
|
|
40
76
|
|------|--------|---------|-------------|
|
|
41
|
-
| `--platform` | `linux`, `win32` | Current OS | Target platform |
|
|
77
|
+
| `--platform` | `linux`, `win32` | Current OS | Target platform (Windows support is experimental/WIP) |
|
|
42
78
|
| `--target` | `deb`, `rpm` | `deb` | Installer format (Linux only) |
|
|
43
79
|
|
|
44
80
|
**What it does:**
|
|
@@ -158,10 +194,10 @@ my-lotus-app/
|
|
|
158
194
|
"version": "1.0.0",
|
|
159
195
|
"main": "main.js",
|
|
160
196
|
"dependencies": {
|
|
161
|
-
"@lotus-gui/core": "^0.
|
|
197
|
+
"@lotus-gui/core": "^0.2.0"
|
|
162
198
|
},
|
|
163
199
|
"devDependencies": {
|
|
164
|
-
"@lotus-gui/dev": "^0.
|
|
200
|
+
"@lotus-gui/dev": "^0.2.0"
|
|
165
201
|
}
|
|
166
202
|
}
|
|
167
203
|
```
|
package/bin/lotus.js
CHANGED
|
@@ -5,6 +5,7 @@ const { spawn } = require('child_process');
|
|
|
5
5
|
const chokidar = require('chokidar');
|
|
6
6
|
const path = require('path');
|
|
7
7
|
const fs = require('fs');
|
|
8
|
+
const prompts = require('prompts');
|
|
8
9
|
|
|
9
10
|
const program = new Command();
|
|
10
11
|
|
|
@@ -253,4 +254,229 @@ exec node "/usr/lib/${options.name}/resources/app/${entryPoint}" "$@"
|
|
|
253
254
|
|
|
254
255
|
});
|
|
255
256
|
|
|
257
|
+
program
|
|
258
|
+
.command('init [projectName]')
|
|
259
|
+
.description('Initialize a new Lotus project')
|
|
260
|
+
.option('--name <name>', 'Application name')
|
|
261
|
+
.option('--app-version <version>', 'Application version')
|
|
262
|
+
.option('--description <description>', 'Application description')
|
|
263
|
+
.option('--author <author>', 'Author name')
|
|
264
|
+
.option('--license <license>', 'License (default: MIT)')
|
|
265
|
+
.option('--homepage <homepage>', 'Project homepage/repository URL')
|
|
266
|
+
.action(async (projectName, options) => {
|
|
267
|
+
let targetDir = projectName;
|
|
268
|
+
|
|
269
|
+
// 1. Prompt for project directory if not provided
|
|
270
|
+
if (!targetDir) {
|
|
271
|
+
const response = await prompts({
|
|
272
|
+
type: 'text',
|
|
273
|
+
name: 'value',
|
|
274
|
+
message: 'Project name (directory):',
|
|
275
|
+
initial: 'my-lotus-app'
|
|
276
|
+
});
|
|
277
|
+
targetDir = response.value;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (!targetDir) {
|
|
281
|
+
console.log('Operation cancelled.');
|
|
282
|
+
process.exit(0);
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const projectPath = path.resolve(targetDir);
|
|
286
|
+
if (fs.existsSync(projectPath)) {
|
|
287
|
+
const { overwrite } = await prompts({
|
|
288
|
+
type: 'confirm',
|
|
289
|
+
name: 'overwrite',
|
|
290
|
+
message: `Directory ${targetDir} already exists. Overwrite?`,
|
|
291
|
+
initial: false
|
|
292
|
+
});
|
|
293
|
+
if (!overwrite) {
|
|
294
|
+
console.log('Aborting.');
|
|
295
|
+
process.exit(1);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// 2. Gather Metadata (prompts if flags missing)
|
|
300
|
+
const questions = [
|
|
301
|
+
{
|
|
302
|
+
type: options.name ? null : 'text',
|
|
303
|
+
name: 'name',
|
|
304
|
+
message: 'Application Name:',
|
|
305
|
+
initial: targetDir
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
type: options.appVersion ? null : 'text',
|
|
309
|
+
name: 'version',
|
|
310
|
+
message: 'Version:',
|
|
311
|
+
initial: '0.1.0'
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
type: options.description ? null : 'text',
|
|
315
|
+
name: 'description',
|
|
316
|
+
message: 'Description:',
|
|
317
|
+
initial: 'A Lotus desktop application'
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
type: options.author ? null : 'text',
|
|
321
|
+
name: 'author',
|
|
322
|
+
message: 'Author:',
|
|
323
|
+
initial: ''
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
type: options.homepage ? null : 'text',
|
|
327
|
+
name: 'homepage',
|
|
328
|
+
message: 'Homepage / Repository URL:',
|
|
329
|
+
initial: ''
|
|
330
|
+
},
|
|
331
|
+
{
|
|
332
|
+
type: options.license ? null : 'text',
|
|
333
|
+
name: 'license',
|
|
334
|
+
message: 'License:',
|
|
335
|
+
initial: 'MIT'
|
|
336
|
+
}
|
|
337
|
+
];
|
|
338
|
+
|
|
339
|
+
const answers = await prompts(questions);
|
|
340
|
+
const metadata = { ...options, ...answers };
|
|
341
|
+
metadata.version = options.appVersion || answers.version;
|
|
342
|
+
// Clean up undefined/null
|
|
343
|
+
Object.keys(metadata).forEach(k => metadata[k] == null && delete metadata[k]);
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
// 3. Generate Files
|
|
347
|
+
console.log(`\nCreating project in ${projectPath}...`);
|
|
348
|
+
fs.mkdirSync(projectPath, { recursive: true });
|
|
349
|
+
|
|
350
|
+
// package.json
|
|
351
|
+
const packageJson = {
|
|
352
|
+
name: targetDir.toLowerCase().replace(/[^a-z0-9-]/g, '-'), // npm safe name
|
|
353
|
+
version: metadata.version,
|
|
354
|
+
description: metadata.description,
|
|
355
|
+
main: "main.js",
|
|
356
|
+
scripts: {
|
|
357
|
+
"start": "lotus dev main.js",
|
|
358
|
+
"build": "lotus build"
|
|
359
|
+
},
|
|
360
|
+
keywords: ["lotus", "desktop", "gui"],
|
|
361
|
+
author: metadata.author,
|
|
362
|
+
homepage: metadata.homepage,
|
|
363
|
+
license: metadata.license,
|
|
364
|
+
dependencies: {
|
|
365
|
+
"@lotus-gui/core": "latest"
|
|
366
|
+
},
|
|
367
|
+
devDependencies: {
|
|
368
|
+
"@lotus-gui/dev": "latest"
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
fs.writeFileSync(path.join(projectPath, 'package.json'), JSON.stringify(packageJson, null, 2));
|
|
372
|
+
|
|
373
|
+
// lotus.config.json
|
|
374
|
+
const lotusConfig = {
|
|
375
|
+
name: metadata.name, // Display name
|
|
376
|
+
version: metadata.version,
|
|
377
|
+
license: metadata.license,
|
|
378
|
+
description: metadata.description,
|
|
379
|
+
main: "main.js",
|
|
380
|
+
executableName: targetDir.toLowerCase().replace(/[^a-z0-9-]/g, '-'),
|
|
381
|
+
author: metadata.author,
|
|
382
|
+
homepage: metadata.homepage || undefined,
|
|
383
|
+
build: {
|
|
384
|
+
linux: {
|
|
385
|
+
wmClass: metadata.name.toLowerCase().replace(/ /g, '-'),
|
|
386
|
+
categories: ["Utility"]
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
// Remove undefined keys
|
|
391
|
+
Object.keys(lotusConfig).forEach(key => lotusConfig[key] === undefined && delete lotusConfig[key]);
|
|
392
|
+
|
|
393
|
+
fs.writeFileSync(path.join(projectPath, 'lotus.config.json'), JSON.stringify(lotusConfig, null, 4));
|
|
394
|
+
|
|
395
|
+
// main.js
|
|
396
|
+
const mainJs = `const { ServoWindow, app, ipcMain } = require('@lotus-gui/core');
|
|
397
|
+
const path = require('path');
|
|
398
|
+
|
|
399
|
+
app.warmup();
|
|
400
|
+
|
|
401
|
+
const win = new ServoWindow({
|
|
402
|
+
id: 'main-window',
|
|
403
|
+
root: path.join(__dirname, 'ui'),
|
|
404
|
+
index: 'index.html',
|
|
405
|
+
width: 1024,
|
|
406
|
+
height: 768,
|
|
407
|
+
title: "${metadata.name}",
|
|
408
|
+
transparent: true,
|
|
409
|
+
visible: false
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
win.once('frame-ready', () => win.show());
|
|
413
|
+
|
|
414
|
+
ipcMain.on('hello', (data) => {
|
|
415
|
+
console.log('Received from renderer:', data);
|
|
416
|
+
ipcMain.send('reply', { message: 'Hello from Node.js!' });
|
|
417
|
+
});
|
|
418
|
+
`;
|
|
419
|
+
fs.writeFileSync(path.join(projectPath, 'main.js'), mainJs);
|
|
420
|
+
|
|
421
|
+
// UI Directory
|
|
422
|
+
const uiDir = path.join(projectPath, 'ui');
|
|
423
|
+
fs.mkdirSync(uiDir);
|
|
424
|
+
|
|
425
|
+
// ui/index.html
|
|
426
|
+
const indexHtml = `<!DOCTYPE html>
|
|
427
|
+
<html>
|
|
428
|
+
<head>
|
|
429
|
+
<title>${metadata.name}</title>
|
|
430
|
+
<style>
|
|
431
|
+
body { margin: 0; padding: 0; background: transparent; font-family: sans-serif; }
|
|
432
|
+
.app {
|
|
433
|
+
background: rgba(30, 30, 30, 0.95);
|
|
434
|
+
color: white;
|
|
435
|
+
height: 100vh;
|
|
436
|
+
display: flex;
|
|
437
|
+
flex-direction: column;
|
|
438
|
+
align-items: center;
|
|
439
|
+
justify-content: center;
|
|
440
|
+
border-radius: 8px; /* Optional rounded corners for the view */
|
|
441
|
+
}
|
|
442
|
+
button {
|
|
443
|
+
padding: 10px 20px;
|
|
444
|
+
font-size: 16px;
|
|
445
|
+
cursor: pointer;
|
|
446
|
+
background: #646cff;
|
|
447
|
+
color: white;
|
|
448
|
+
border: none;
|
|
449
|
+
border-radius: 4px;
|
|
450
|
+
}
|
|
451
|
+
button:hover { background: #535bf2; }
|
|
452
|
+
</style>
|
|
453
|
+
</head>
|
|
454
|
+
<body>
|
|
455
|
+
<div class="app">
|
|
456
|
+
<h1>Welcome to ${metadata.name} šŖ·</h1>
|
|
457
|
+
<p>Powered by Lotus (Servo + Node.js)</p>
|
|
458
|
+
<button onclick="sendMessage()">Ping Node.js</button>
|
|
459
|
+
<p id="response"></p>
|
|
460
|
+
</div>
|
|
461
|
+
|
|
462
|
+
<script>
|
|
463
|
+
function sendMessage() {
|
|
464
|
+
window.lotus.send('hello', { timestamp: Date.now() });
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
window.lotus.on('reply', (data) => {
|
|
468
|
+
document.getElementById('response').innerText = data.message;
|
|
469
|
+
});
|
|
470
|
+
</script>
|
|
471
|
+
</body>
|
|
472
|
+
</html>`;
|
|
473
|
+
fs.writeFileSync(path.join(uiDir, 'index.html'), indexHtml);
|
|
474
|
+
|
|
475
|
+
console.log(`\nā
Project initialized in ${projectPath}`);
|
|
476
|
+
console.log(`\nNext steps:`);
|
|
477
|
+
console.log(` cd ${targetDir}`);
|
|
478
|
+
console.log(` npm install`);
|
|
479
|
+
console.log(` npx lotus dev\n`);
|
|
480
|
+
});
|
|
481
|
+
|
|
256
482
|
program.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lotus-gui/dev",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "The Lotus Toolkit",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"chokidar": "^3.5.3",
|
|
17
17
|
"commander": "^11.1.0",
|
|
18
|
-
"electron-winstaller": "^5.4.0"
|
|
18
|
+
"electron-winstaller": "^5.4.0",
|
|
19
|
+
"prompts": "^2.4.2"
|
|
19
20
|
},
|
|
20
21
|
"optionalDependencies": {
|
|
21
22
|
"electron-installer-debian": "^3.2.0",
|