windowpp 0.1.3 → 0.1.5
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/windowpp.js +4 -1
- package/lib/create.js +56 -6
- package/package.json +1 -1
- package/templates/solid/frontend/index.html +16 -0
- package/templates/solid/frontend/src/App.tsx +8 -0
- package/templates/solid/frontend/src/index.css +1 -0
- package/templates/solid/frontend/src/index.tsx +12 -0
- package/templates/solid/frontend/tsconfig.json +15 -0
package/bin/windowpp.js
CHANGED
|
@@ -51,7 +51,10 @@ switch (command) {
|
|
|
51
51
|
}
|
|
52
52
|
const flags = parseFlags(args.slice(2));
|
|
53
53
|
const { create } = require('../lib/create');
|
|
54
|
-
create(name, { template: flags.template, outDir: flags.outDir })
|
|
54
|
+
create(name, { template: flags.template, outDir: flags.outDir }).catch((err) => {
|
|
55
|
+
console.error(err.message || err);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
});
|
|
55
58
|
break;
|
|
56
59
|
}
|
|
57
60
|
|
package/lib/create.js
CHANGED
|
@@ -5,8 +5,45 @@
|
|
|
5
5
|
|
|
6
6
|
const path = require('path');
|
|
7
7
|
const fs = require('fs');
|
|
8
|
+
const readline = require('readline');
|
|
8
9
|
const { execSync } = require('child_process');
|
|
9
10
|
|
|
11
|
+
// ─── Interactive template picker ─────────────────────────────────────────────
|
|
12
|
+
function listTemplates(cliDir) {
|
|
13
|
+
const templatesDir = path.join(cliDir, 'templates');
|
|
14
|
+
if (!fs.existsSync(templatesDir)) return [];
|
|
15
|
+
return fs.readdirSync(templatesDir, { withFileTypes: true })
|
|
16
|
+
.filter(d => d.isDirectory())
|
|
17
|
+
.map(d => d.name)
|
|
18
|
+
.sort();
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function promptTemplate(templates) {
|
|
22
|
+
return new Promise((resolve) => {
|
|
23
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
24
|
+
|
|
25
|
+
console.log('\nAvailable templates:');
|
|
26
|
+
templates.forEach((t, i) => console.log(` [${i + 1}] ${t}`));
|
|
27
|
+
console.log();
|
|
28
|
+
|
|
29
|
+
const ask = () => {
|
|
30
|
+
rl.question(`Pick a template [1-${templates.length}] (default: 1): `, (answer) => {
|
|
31
|
+
const trimmed = answer.trim();
|
|
32
|
+
if (trimmed === '') { rl.close(); resolve(templates[0]); return; }
|
|
33
|
+
const idx = parseInt(trimmed, 10) - 1;
|
|
34
|
+
if (idx >= 0 && idx < templates.length) {
|
|
35
|
+
rl.close();
|
|
36
|
+
resolve(templates[idx]);
|
|
37
|
+
} else {
|
|
38
|
+
console.log(` Please enter a number between 1 and ${templates.length}.`);
|
|
39
|
+
ask();
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
ask();
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
10
47
|
const TEXT_EXTENSIONS = new Set([
|
|
11
48
|
'.cpp', '.h', '.ts', '.tsx', '.js', '.json', '.html',
|
|
12
49
|
'.css', '.md', '.txt', '.cmake', '.sh', '.env',
|
|
@@ -38,9 +75,8 @@ function copyDir(src, dest, tokens) {
|
|
|
38
75
|
}
|
|
39
76
|
}
|
|
40
77
|
|
|
41
|
-
function create(name, options = {}) {
|
|
78
|
+
async function create(name, options = {}) {
|
|
42
79
|
const {
|
|
43
|
-
template = 'solid',
|
|
44
80
|
outDir = process.cwd(),
|
|
45
81
|
installDeps = true,
|
|
46
82
|
} = options;
|
|
@@ -50,13 +86,29 @@ function create(name, options = {}) {
|
|
|
50
86
|
process.exit(1);
|
|
51
87
|
}
|
|
52
88
|
|
|
89
|
+
const cliDir = path.resolve(__dirname, '..');
|
|
90
|
+
const templates = listTemplates(cliDir);
|
|
91
|
+
|
|
92
|
+
// Resolve template — prompt if none given
|
|
93
|
+
let template = options.template;
|
|
94
|
+
if (!template) {
|
|
95
|
+
if (templates.length === 0) {
|
|
96
|
+
console.error('Error: no templates found in ' + path.join(cliDir, 'templates'));
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
if (templates.length === 1) {
|
|
100
|
+
template = templates[0];
|
|
101
|
+
} else {
|
|
102
|
+
template = await promptTemplate(templates);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
53
106
|
const appDir = path.join(outDir, name);
|
|
54
107
|
if (fs.existsSync(appDir)) {
|
|
55
108
|
console.error(`Error: directory "${appDir}" already exists.`);
|
|
56
109
|
process.exit(1);
|
|
57
110
|
}
|
|
58
111
|
|
|
59
|
-
const cliDir = path.resolve(__dirname, '..');
|
|
60
112
|
const templateDir = path.join(cliDir, 'templates', template);
|
|
61
113
|
if (!fs.existsSync(templateDir)) {
|
|
62
114
|
console.error(`Error: template "${template}" not found in ${path.join(cliDir, 'templates')}`);
|
|
@@ -73,9 +125,7 @@ function create(name, options = {}) {
|
|
|
73
125
|
'{{APP_NAME}}': name,
|
|
74
126
|
'{{APP_TITLE}}': appTitle,
|
|
75
127
|
'{{CMAKE_TARGET}}': cmakeTarget,
|
|
76
|
-
|
|
77
|
-
// installed framework's src/ tree via the @wpp alias.
|
|
78
|
-
'{{REPO_ROOT}}': path.join(cliDir, 'framework').replace(/\\/g, '/'),
|
|
128
|
+
'{{REPO_ROOT}}': path.join(cliDir, 'framework').replace(/\\/g, '/'),
|
|
79
129
|
};
|
|
80
130
|
|
|
81
131
|
console.log(`\n=== WindowPP Create --- ${name} (template: ${template}) ===\n`);
|
package/package.json
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<title>{{APP_TITLE}}</title>
|
|
7
|
+
<script>
|
|
8
|
+
window.addEventListener('dragover', function(e) { e.preventDefault(); }, false);
|
|
9
|
+
window.addEventListener('drop', function(e) { e.preventDefault(); }, false);
|
|
10
|
+
</script>
|
|
11
|
+
</head>
|
|
12
|
+
<body>
|
|
13
|
+
<div id="root"></div>
|
|
14
|
+
<script src="/src/index.tsx" type="module"></script>
|
|
15
|
+
</body>
|
|
16
|
+
</html>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export default function App() {
|
|
2
|
+
return (
|
|
3
|
+
<div class="min-h-screen flex flex-col items-center justify-center bg-slate-100 text-slate-900 gap-4">
|
|
4
|
+
<h1 class="text-4xl font-bold">{{APP_TITLE}}</h1>
|
|
5
|
+
<p class="text-slate-500 text-sm">Edit <code class="bg-slate-200 px-1 rounded">frontend/src/App.tsx</code> to get started.</p>
|
|
6
|
+
</div>
|
|
7
|
+
);
|
|
8
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import 'tailwindcss';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/* @refresh reload */
|
|
2
|
+
import './index.css';
|
|
3
|
+
import { render } from 'solid-js/web';
|
|
4
|
+
import App from './App';
|
|
5
|
+
|
|
6
|
+
const root = document.getElementById('root');
|
|
7
|
+
|
|
8
|
+
if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
|
|
9
|
+
throw new Error('Root element not found. Did you forget to add it to your index.html?');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
render(() => <App />, root!);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"jsx": "preserve",
|
|
4
|
+
"jsxImportSource": "solid-js",
|
|
5
|
+
"target": "ESNext",
|
|
6
|
+
"allowSyntheticDefaultImports": true,
|
|
7
|
+
"esModuleInterop": true,
|
|
8
|
+
"isolatedModules": true,
|
|
9
|
+
"module": "ESNext",
|
|
10
|
+
"moduleResolution": "bundler",
|
|
11
|
+
"noEmit": true,
|
|
12
|
+
"strict": true,
|
|
13
|
+
"types": ["vite/client"]
|
|
14
|
+
}
|
|
15
|
+
}
|