@geastack/cli 0.1.2 → 0.1.4
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 +10 -9
- package/docs/SPEC.md +1 -2
- package/package.json +1 -1
- package/src/create-geastack.mjs +36 -15
- package/src/gea.mjs +9 -1
- package/starters/bundled/counter/package.json +0 -1
- package/starters/catalog.json +0 -1
package/README.md
CHANGED
|
@@ -9,16 +9,17 @@ keeping target-specific build logic behind stable backend contracts.
|
|
|
9
9
|
## Commands
|
|
10
10
|
|
|
11
11
|
```sh
|
|
12
|
-
|
|
12
|
+
npm install --global @geastack/cli
|
|
13
|
+
gea create my-panel
|
|
13
14
|
cd my-panel
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
gea doctor
|
|
16
|
+
gea setup
|
|
17
|
+
gea dev
|
|
18
|
+
gea build --target web
|
|
19
|
+
gea build --target ios
|
|
20
|
+
gea flash --board amoled --monitor
|
|
21
|
+
gea monitor --board amoled
|
|
22
|
+
gea inspect --json
|
|
22
23
|
```
|
|
23
24
|
|
|
24
25
|
## Interactive Menu Map
|
package/docs/SPEC.md
CHANGED
|
@@ -154,7 +154,6 @@ Core fields:
|
|
|
154
154
|
"id": "bouncing-balls-jsx",
|
|
155
155
|
"name": "Balls JSX",
|
|
156
156
|
"entry": "index.tsx",
|
|
157
|
-
"runtime": "gea",
|
|
158
157
|
"targets": {
|
|
159
158
|
"web": true,
|
|
160
159
|
"esp32": true,
|
|
@@ -171,7 +170,7 @@ Validation rules:
|
|
|
171
170
|
|
|
172
171
|
- `id` is required and should be stable.
|
|
173
172
|
- `entry` is required and must exist.
|
|
174
|
-
- `runtime` defaults to `gea
|
|
173
|
+
- `runtime` defaults to `gea`; only non-Gea native applications should set it.
|
|
175
174
|
- `targets` must be explicit for generated apps.
|
|
176
175
|
- target backends may reject apps whose runtime or capabilities they do not
|
|
177
176
|
support.
|
package/package.json
CHANGED
package/src/create-geastack.mjs
CHANGED
|
@@ -38,13 +38,19 @@ export async function runCreateGeastack(argv, io = {}) {
|
|
|
38
38
|
const ctx = createContext(parsed, env, cwd)
|
|
39
39
|
const displayName = option(parsed, 'name', titleFromId(appId))
|
|
40
40
|
const coreDependency = option(parsed, 'core-dependency') || '^0.1.4'
|
|
41
|
-
const cliDependency = option(parsed, 'cli-dependency') || '^0.1.
|
|
41
|
+
const cliDependency = option(parsed, 'cli-dependency') || '^0.1.4'
|
|
42
42
|
const starter = await resolveStarter(ctx, parsed, io)
|
|
43
|
+
const entry = projectRelativePath(option(parsed, 'entry') || starter.starter?.entry || starter.example?.entry || 'index.tsx', 'entry')
|
|
44
|
+
if (option(parsed, 'entry') && starter.kind !== 'empty') {
|
|
45
|
+
fail('--entry can only be used with --starter empty.', ExitCode.usage)
|
|
46
|
+
}
|
|
43
47
|
|
|
44
48
|
fs.mkdirSync(targetDir, { recursive: true })
|
|
45
49
|
if (starter.kind === 'empty') {
|
|
46
|
-
|
|
47
|
-
fs.
|
|
50
|
+
const entryPath = path.join(targetDir, entry)
|
|
51
|
+
fs.mkdirSync(path.dirname(entryPath), { recursive: true })
|
|
52
|
+
fs.writeFileSync(entryPath, indexTsx(displayName))
|
|
53
|
+
fs.writeFileSync(path.join(path.dirname(entryPath), 'styles.css'), stylesCss())
|
|
48
54
|
} else if (starter.kind === 'bundled') {
|
|
49
55
|
copyStarterFiles(starter.starter.root, targetDir)
|
|
50
56
|
} else if (starter.kind === 'example') {
|
|
@@ -69,12 +75,14 @@ export async function runCreateGeastack(argv, io = {}) {
|
|
|
69
75
|
appId,
|
|
70
76
|
displayName,
|
|
71
77
|
targets,
|
|
78
|
+
entry,
|
|
79
|
+
bleOta: flag(parsed, 'ble-ota'),
|
|
72
80
|
coreDependency,
|
|
73
81
|
cliDependency,
|
|
74
82
|
sourcePackage,
|
|
75
83
|
sourceManifest
|
|
76
84
|
}))
|
|
77
|
-
ensureFile(path.join(targetDir, 'index.html'), () => indexHtml(displayName))
|
|
85
|
+
ensureFile(path.join(targetDir, 'index.html'), () => indexHtml(displayName, entry))
|
|
78
86
|
fs.mkdirSync(path.join(targetDir, '.gea'), { recursive: true })
|
|
79
87
|
writeJson(path.join(targetDir, '.gea', 'boards.json'), {})
|
|
80
88
|
ensureJson(path.join(targetDir, 'tsconfig.json'), tsconfigJson)
|
|
@@ -203,7 +211,17 @@ function targetManifestFromObject(targets = {}) {
|
|
|
203
211
|
}
|
|
204
212
|
}
|
|
205
213
|
|
|
206
|
-
function packageJson({ appId, displayName, targets, coreDependency, cliDependency, sourcePackage = {}, sourceManifest = {} }) {
|
|
214
|
+
function packageJson({ appId, displayName, targets, entry, bleOta, coreDependency, cliDependency, sourcePackage = {}, sourceManifest = {} }) {
|
|
215
|
+
const geaManifest = {
|
|
216
|
+
...sourceManifest,
|
|
217
|
+
id: appId,
|
|
218
|
+
name: displayName,
|
|
219
|
+
entry,
|
|
220
|
+
targets
|
|
221
|
+
}
|
|
222
|
+
if (bleOta) geaManifest.ota = { ...(geaManifest.ota || {}), ble: true }
|
|
223
|
+
if (!geaManifest.runtime || geaManifest.runtime === 'gea') delete geaManifest.runtime
|
|
224
|
+
|
|
207
225
|
return {
|
|
208
226
|
name: `gea-${appId}`,
|
|
209
227
|
version: '0.1.0',
|
|
@@ -226,14 +244,7 @@ function packageJson({ appId, displayName, targets, coreDependency, cliDependenc
|
|
|
226
244
|
typescript: sourcePackage.devDependencies?.typescript || 'latest',
|
|
227
245
|
vite: sourcePackage.devDependencies?.vite || 'latest'
|
|
228
246
|
},
|
|
229
|
-
gea:
|
|
230
|
-
...sourceManifest,
|
|
231
|
-
id: appId,
|
|
232
|
-
name: displayName,
|
|
233
|
-
entry: sourceManifest.entry || 'index.tsx',
|
|
234
|
-
runtime: sourceManifest.runtime || 'gea',
|
|
235
|
-
targets
|
|
236
|
-
},
|
|
247
|
+
gea: geaManifest,
|
|
237
248
|
license: 'MIT'
|
|
238
249
|
}
|
|
239
250
|
}
|
|
@@ -297,7 +308,7 @@ h1 {
|
|
|
297
308
|
`
|
|
298
309
|
}
|
|
299
310
|
|
|
300
|
-
function indexHtml(displayName) {
|
|
311
|
+
function indexHtml(displayName, entry = 'index.tsx') {
|
|
301
312
|
return `<!doctype html>
|
|
302
313
|
<html lang="en">
|
|
303
314
|
<head>
|
|
@@ -307,7 +318,7 @@ function indexHtml(displayName) {
|
|
|
307
318
|
</head>
|
|
308
319
|
<body>
|
|
309
320
|
<div id="app"></div>
|
|
310
|
-
<script type="module" src="
|
|
321
|
+
<script type="module" src="/${entry}"></script>
|
|
311
322
|
</body>
|
|
312
323
|
</html>
|
|
313
324
|
`
|
|
@@ -396,6 +407,14 @@ function normalizeStarter(value) {
|
|
|
396
407
|
return normalized
|
|
397
408
|
}
|
|
398
409
|
|
|
410
|
+
function projectRelativePath(value, label) {
|
|
411
|
+
const normalized = path.posix.normalize(String(value || '').replaceAll('\\', '/')).replace(/^\.\//, '')
|
|
412
|
+
if (!normalized || normalized === '.' || normalized === '..' || normalized.startsWith('../') || path.posix.isAbsolute(normalized)) {
|
|
413
|
+
fail(`--${label} must be a path inside the project.`, ExitCode.usage)
|
|
414
|
+
}
|
|
415
|
+
return normalized
|
|
416
|
+
}
|
|
417
|
+
|
|
399
418
|
function readPackageJson(targetDir) {
|
|
400
419
|
const packagePath = path.join(targetDir, 'package.json')
|
|
401
420
|
if (!exists(packagePath)) return {}
|
|
@@ -420,6 +439,8 @@ Options:
|
|
|
420
439
|
--examples-repo <git-url-or-local-path>
|
|
421
440
|
--examples-ref <git-ref>
|
|
422
441
|
--targets web,esp32,rp2350,geaos,macos,ios,android
|
|
442
|
+
--entry <relative-path>
|
|
443
|
+
--ble-ota
|
|
423
444
|
--core-dependency <specifier>
|
|
424
445
|
--cli-dependency <specifier>
|
|
425
446
|
--install / --no-install
|
package/src/gea.mjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import path from 'node:path'
|
|
2
|
+
import fs from 'node:fs'
|
|
2
3
|
|
|
3
4
|
import { flag, option, parseArgs } from './args.mjs'
|
|
5
|
+
import { runCreateGeastack } from './create-geastack.mjs'
|
|
4
6
|
import { createChildEnv, createContext } from './context.mjs'
|
|
5
7
|
import { ExitCode, fail } from './errors.mjs'
|
|
6
8
|
import { exists, readJson } from './fs-utils.mjs'
|
|
@@ -18,7 +20,7 @@ import { runExternal } from './run.mjs'
|
|
|
18
20
|
import { runSetupWizard } from './setup-wizard.mjs'
|
|
19
21
|
import { commandVersion, nodeAtLeast } from './toolchain.mjs'
|
|
20
22
|
|
|
21
|
-
const version = '
|
|
23
|
+
const version = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version
|
|
22
24
|
|
|
23
25
|
export async function runGea(argv, io = {}) {
|
|
24
26
|
const parsed = parseArgs(argv)
|
|
@@ -35,6 +37,11 @@ export async function runGea(argv, io = {}) {
|
|
|
35
37
|
stdout(version)
|
|
36
38
|
return 0
|
|
37
39
|
}
|
|
40
|
+
if (command === 'create') {
|
|
41
|
+
const createArgs = argv.slice(1)
|
|
42
|
+
if (option(parsed, 'install') === undefined) createArgs.push('--install')
|
|
43
|
+
return runCreateGeastack(createArgs, io)
|
|
44
|
+
}
|
|
38
45
|
if (!command || command === 'help' || flag(parsed, 'help')) {
|
|
39
46
|
stdout(usage())
|
|
40
47
|
return 0
|
|
@@ -422,6 +429,7 @@ function requirePath(filePath, label) {
|
|
|
422
429
|
|
|
423
430
|
function usage() {
|
|
424
431
|
return `Usage:
|
|
432
|
+
gea create <name> [--starter counter|empty|example] [--targets <list>]
|
|
425
433
|
gea doctor [--strict] [--json]
|
|
426
434
|
gea setup --board <alias>
|
|
427
435
|
gea dev [app] [--target web] [--port 5181]
|