create-pebble-app 0.1.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.
Files changed (2) hide show
  1. package/index.js +201 -0
  2. package/package.json +16 -0
package/index.js ADDED
@@ -0,0 +1,201 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * create-pebble-app — scaffold a new react-pebble project.
5
+ *
6
+ * Usage:
7
+ * npx create-pebble-app my-watchface
8
+ * npx create-pebble-app my-watchface --counter (counter template)
9
+ */
10
+
11
+ import { mkdirSync, writeFileSync, existsSync } from 'node:fs';
12
+ import { join, resolve } from 'node:path';
13
+ import { execSync } from 'node:child_process';
14
+
15
+ const args = process.argv.slice(2);
16
+ const projectName = args.find(a => !a.startsWith('--'));
17
+ const template = args.includes('--counter') ? 'counter' : 'watchface';
18
+
19
+ if (!projectName) {
20
+ console.log(`
21
+ Usage: npx create-pebble-app <project-name> [--counter]
22
+
23
+ Examples:
24
+ npx create-pebble-app my-watchface
25
+ npx create-pebble-app my-counter --counter
26
+ `);
27
+ process.exit(1);
28
+ }
29
+
30
+ const dir = resolve(projectName);
31
+
32
+ if (existsSync(dir)) {
33
+ console.error(`Error: directory "${projectName}" already exists.`);
34
+ process.exit(1);
35
+ }
36
+
37
+ console.log(`\n Creating ${projectName}...\n`);
38
+
39
+ mkdirSync(join(dir, 'src'), { recursive: true });
40
+
41
+ // package.json
42
+ writeFileSync(join(dir, 'package.json'), JSON.stringify({
43
+ name: projectName,
44
+ version: '0.1.0',
45
+ private: true,
46
+ type: 'module',
47
+ scripts: {
48
+ build: 'vite build',
49
+ deploy: 'vite build',
50
+ typecheck: 'tsc --noEmit',
51
+ },
52
+ dependencies: {
53
+ 'react-pebble': '^0.1.0',
54
+ },
55
+ devDependencies: {
56
+ 'typescript': '^5.0.0',
57
+ 'vite': '^8.0.0',
58
+ },
59
+ }, null, 2) + '\n');
60
+
61
+ // vite.config.ts
62
+ writeFileSync(join(dir, 'vite.config.ts'), `import { defineConfig } from 'vite';
63
+ import { pebblePiu } from 'react-pebble/plugin';
64
+
65
+ export default defineConfig({
66
+ plugins: [
67
+ pebblePiu({
68
+ entry: 'src/App.tsx',
69
+ deploy: true,
70
+ }),
71
+ ],
72
+ });
73
+ `);
74
+
75
+ // tsconfig.json
76
+ writeFileSync(join(dir, 'tsconfig.json'), JSON.stringify({
77
+ compilerOptions: {
78
+ target: 'es2022',
79
+ module: 'esnext',
80
+ moduleResolution: 'bundler',
81
+ lib: ['es2022'],
82
+ jsx: 'react-jsx',
83
+ jsxImportSource: 'preact',
84
+ strict: true,
85
+ esModuleInterop: true,
86
+ skipLibCheck: true,
87
+ noEmit: true,
88
+ },
89
+ include: ['src'],
90
+ }, null, 2) + '\n');
91
+
92
+ // .gitignore
93
+ writeFileSync(join(dir, '.gitignore'), `node_modules/
94
+ dist/
95
+ .pebble-build/
96
+ *.log
97
+ `);
98
+
99
+ // src/App.tsx
100
+ if (template === 'counter') {
101
+ writeFileSync(join(dir, 'src/App.tsx'), `import { render, Text, Rect, Group } from 'react-pebble';
102
+ import { useButton, useState } from 'react-pebble/hooks';
103
+
104
+ function Counter() {
105
+ const [count, setCount] = useState(0);
106
+
107
+ useButton('up', () => setCount((c: number) => c + 1));
108
+ useButton('down', () => setCount((c: number) => c - 1));
109
+ useButton('select', () => setCount(0));
110
+
111
+ return (
112
+ <Group>
113
+ <Rect x={0} y={0} w={200} h={228} fill="black" />
114
+ <Rect x={0} y={0} w={200} h={32} fill="white" />
115
+ <Text x={4} y={6} w={192} font="gothic18Bold" color="black">
116
+ Counter
117
+ </Text>
118
+ <Text x={0} y={80} w={200} font="bitham42Bold" color="white" align="center">
119
+ {count.toString()}
120
+ </Text>
121
+ <Text x={0} y={180} w={200} font="gothic14" color="lightGray" align="center">
122
+ UP/DOWN to count, SELECT to reset
123
+ </Text>
124
+ </Group>
125
+ );
126
+ }
127
+
128
+ export function main() {
129
+ return render(<Counter />);
130
+ }
131
+ `);
132
+ } else {
133
+ writeFileSync(join(dir, 'src/App.tsx'), `import { render, Text, Rect, Circle, Group } from 'react-pebble';
134
+ import { useTime } from 'react-pebble/hooks';
135
+
136
+ function WatchFace() {
137
+ const time = useTime();
138
+ const hours = time.getHours().toString().padStart(2, '0');
139
+ const minutes = time.getMinutes().toString().padStart(2, '0');
140
+ const seconds = time.getSeconds().toString().padStart(2, '0');
141
+
142
+ const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
143
+ const dateStr = days[time.getDay()] + ' ' + time.getDate();
144
+
145
+ return (
146
+ <Group>
147
+ <Rect x={0} y={0} w={200} h={228} fill="black" />
148
+
149
+ {/* Hour markers */}
150
+ <Circle x={92} y={10} r={6} fill="white" />
151
+ <Circle x={174} y={100} r={6} fill="white" />
152
+ <Circle x={92} y={190} r={6} fill="white" />
153
+ <Circle x={10} y={100} r={6} fill="white" />
154
+
155
+ {/* Center dot */}
156
+ <Circle x={90} y={100} r={10} fill="red" />
157
+
158
+ {/* Time */}
159
+ <Text x={0} y={70} w={200} font="bitham42Bold" color="white" align="center">
160
+ {hours}:{minutes}
161
+ </Text>
162
+
163
+ {/* Seconds */}
164
+ <Text x={0} y={122} w={200} font="gothic24" color="lightGray" align="center">
165
+ {seconds}
166
+ </Text>
167
+
168
+ {/* Date */}
169
+ <Text x={0} y={158} w={200} font="gothic18" color="white" align="center">
170
+ {dateStr}
171
+ </Text>
172
+ </Group>
173
+ );
174
+ }
175
+
176
+ export function main() {
177
+ return render(<WatchFace />);
178
+ }
179
+ `);
180
+ }
181
+
182
+ // Install dependencies
183
+ console.log(' Installing dependencies...\n');
184
+ try {
185
+ execSync('npm install', { cwd: dir, stdio: 'inherit' });
186
+ } catch {
187
+ console.log('\n npm install failed — you can run it manually.');
188
+ }
189
+
190
+ console.log(`
191
+ Done! Created ${projectName}/
192
+
193
+ Next steps:
194
+ cd ${projectName}
195
+ npx vite build Build + deploy to Pebble emulator
196
+
197
+ Your app is in src/App.tsx — edit it and rebuild.
198
+ The Vite plugin handles everything: compile → scaffold → deploy.
199
+
200
+ Requires: Pebble SDK v4.9+ (pebble --version)
201
+ `);
package/package.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "create-pebble-app",
3
+ "version": "0.1.0",
4
+ "description": "Scaffold a new react-pebble watchface or app project",
5
+ "type": "module",
6
+ "bin": {
7
+ "create-pebble-app": "index.js"
8
+ },
9
+ "files": ["index.js"],
10
+ "keywords": ["pebble", "smartwatch", "create", "scaffold", "watchface"],
11
+ "license": "MIT",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/eddiemoore/react-pebble"
15
+ }
16
+ }