@jskit-ai/jskit-cli 0.2.74 → 0.2.76
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 +4 -4
- package/src/server/cliRuntime/completion.js +40 -4
- package/src/server/cliRuntime/mutations/textMutations.js +8 -2
- package/src/server/cliRuntime/packageIntrospection/placementNormalization.js +19 -5
- package/src/server/commandHandlers/health.js +10 -6
- package/src/server/commandHandlers/list.js +420 -17
- package/src/server/commandHandlers/mobile.js +178 -277
- package/src/server/commandHandlers/mobileCommandCatalog.js +34 -39
- package/src/server/commandHandlers/mobileShellSupport.js +30 -7
- package/src/server/core/argParser.js +6 -0
- package/src/server/core/buildCommandDeps.js +3 -1
- package/src/server/core/commandCatalog.js +18 -12
- package/src/server/core/createCliRunner.js +8 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { spawn } from "node:child_process";
|
|
3
|
-
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
4
4
|
import {
|
|
5
5
|
createColorFormatter,
|
|
6
6
|
writeWrappedLines
|
|
@@ -23,6 +23,10 @@ import {
|
|
|
23
23
|
} from "./mobileShellSupport.js";
|
|
24
24
|
const CAPACITOR_RUNTIME_PACKAGE_ID = "@jskit-ai/mobile-capacitor";
|
|
25
25
|
const MOBILE_NOTES_RELATIVE_PATH = path.join(".jskit", "mobile-capacitor.md");
|
|
26
|
+
const MANAGED_MOBILE_FILE_RELATIVE_PATHS = Object.freeze([
|
|
27
|
+
"capacitor.config.json",
|
|
28
|
+
MOBILE_NOTES_RELATIVE_PATH
|
|
29
|
+
]);
|
|
26
30
|
|
|
27
31
|
async function collectManagedMobileFileDriftIssues({
|
|
28
32
|
ctx,
|
|
@@ -34,12 +38,7 @@ async function collectManagedMobileFileDriftIssues({
|
|
|
34
38
|
path: pathModule,
|
|
35
39
|
normalizeRelativePath
|
|
36
40
|
} = ctx;
|
|
37
|
-
const
|
|
38
|
-
"capacitor.config.json",
|
|
39
|
-
MOBILE_NOTES_RELATIVE_PATH
|
|
40
|
-
];
|
|
41
|
-
|
|
42
|
-
for (const relativePath of managedRelativePaths) {
|
|
41
|
+
for (const relativePath of MANAGED_MOBILE_FILE_RELATIVE_PATHS) {
|
|
43
42
|
const absolutePath = pathModule.join(appRoot, relativePath);
|
|
44
43
|
if (!(await fileExists(absolutePath))) {
|
|
45
44
|
continue;
|
|
@@ -60,70 +59,59 @@ async function collectManagedMobileFileDriftIssues({
|
|
|
60
59
|
}
|
|
61
60
|
if (currentContent !== expectedContent) {
|
|
62
61
|
issues.push(
|
|
63
|
-
`${normalizeRelativePath(appRoot, absolutePath)} is stale and no longer matches config.mobile. Re-run jskit mobile sync
|
|
62
|
+
`${normalizeRelativePath(appRoot, absolutePath)} is stale and no longer matches config.mobile. Re-run jskit mobile android sync to refresh managed mobile-shell files.`
|
|
64
63
|
);
|
|
65
64
|
}
|
|
66
65
|
}
|
|
67
66
|
}
|
|
68
67
|
|
|
69
|
-
|
|
70
|
-
const {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const sections = [
|
|
75
|
-
packageJson?.dependencies,
|
|
76
|
-
packageJson?.devDependencies,
|
|
77
|
-
packageJson?.optionalDependencies
|
|
78
|
-
];
|
|
79
|
-
const missing = [];
|
|
80
|
-
const seen = new Set();
|
|
81
|
-
|
|
82
|
-
for (const section of sections) {
|
|
83
|
-
if (!section || typeof section !== "object" || Array.isArray(section)) {
|
|
84
|
-
continue;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
for (const packageName of Object.keys(section).sort((left, right) => left.localeCompare(right))) {
|
|
88
|
-
const normalizedPackageName = String(packageName || "").trim();
|
|
89
|
-
if (!normalizedPackageName || seen.has(normalizedPackageName)) {
|
|
90
|
-
continue;
|
|
91
|
-
}
|
|
92
|
-
seen.add(normalizedPackageName);
|
|
93
|
-
|
|
94
|
-
const packageJsonPath = pathModule.join(
|
|
95
|
-
appRoot,
|
|
96
|
-
"node_modules",
|
|
97
|
-
...normalizedPackageName.split("/"),
|
|
98
|
-
"package.json"
|
|
68
|
+
function renderAndroidMobileCommandList(lines, color) {
|
|
69
|
+
for (const entry of listMobileCommandDefinitions()) {
|
|
70
|
+
if (entry.name === "dev") {
|
|
71
|
+
lines.push(
|
|
72
|
+
` - ${color.item(entry.name)}: Shortcut to run ${color.emphasis("sync")}, ${color.emphasis("tunnel")}, ${color.emphasis("run")} in this order`
|
|
99
73
|
);
|
|
100
|
-
|
|
101
|
-
missing.push(normalizedPackageName);
|
|
102
|
-
}
|
|
74
|
+
continue;
|
|
103
75
|
}
|
|
76
|
+
lines.push(` - ${color.item(entry.name)}: ${entry.summary}`);
|
|
104
77
|
}
|
|
105
|
-
|
|
106
|
-
return missing;
|
|
107
78
|
}
|
|
108
79
|
|
|
109
|
-
function renderMobileHelp(stream, definition = null) {
|
|
80
|
+
function renderMobileHelp(stream, definition = null, platform = "") {
|
|
110
81
|
const color = createColorFormatter(stream);
|
|
111
82
|
const lines = [];
|
|
112
83
|
|
|
113
|
-
if (!definition) {
|
|
84
|
+
if (!definition && !platform) {
|
|
114
85
|
lines.push(`Command: ${color.emphasis("mobile")}`);
|
|
115
86
|
lines.push("");
|
|
116
87
|
lines.push(color.heading("1) Minimal use"));
|
|
117
|
-
lines.push(" jskit mobile <subcommand>");
|
|
88
|
+
lines.push(" jskit mobile <platform> <subcommand>");
|
|
118
89
|
lines.push("");
|
|
119
|
-
lines.push(color.heading("2)
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
90
|
+
lines.push(color.heading("2) Platforms"));
|
|
91
|
+
lines.push(` - ${color.item("android")}`);
|
|
92
|
+
renderAndroidMobileCommandList(lines, color);
|
|
123
93
|
lines.push("");
|
|
124
94
|
lines.push(color.heading("3) Notes"));
|
|
125
95
|
lines.push(" - Mobile helpers are for the Stage 1 Android Capacitor shell flow.");
|
|
126
|
-
lines.push(" - Use jskit mobile <
|
|
96
|
+
lines.push(" - Use jskit mobile <platform> help for platform-specific usage.");
|
|
97
|
+
writeWrappedLines({
|
|
98
|
+
stdout: stream,
|
|
99
|
+
lines
|
|
100
|
+
});
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!definition) {
|
|
105
|
+
lines.push(`Mobile platform: ${color.emphasis(platform)}`);
|
|
106
|
+
lines.push("");
|
|
107
|
+
lines.push(color.heading("1) Minimal use"));
|
|
108
|
+
lines.push(` jskit mobile ${platform} <subcommand>`);
|
|
109
|
+
lines.push("");
|
|
110
|
+
lines.push(color.heading("2) Subcommands"));
|
|
111
|
+
renderAndroidMobileCommandList(lines, color);
|
|
112
|
+
lines.push("");
|
|
113
|
+
lines.push(color.heading("3) Notes"));
|
|
114
|
+
lines.push(` - Use jskit mobile ${platform} <subcommand> help for subcommand-specific usage.`);
|
|
127
115
|
writeWrappedLines({
|
|
128
116
|
stdout: stream,
|
|
129
117
|
lines
|
|
@@ -256,7 +244,7 @@ function resolveAdbReversePort({
|
|
|
256
244
|
const port = Number(parsedUrl.port || "");
|
|
257
245
|
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
258
246
|
throw createCliError(
|
|
259
|
-
`config.mobile.apiBaseUrl "${apiBaseUrl}" must include an explicit port so jskit mobile tunnel
|
|
247
|
+
`config.mobile.apiBaseUrl "${apiBaseUrl}" must include an explicit port so jskit mobile android tunnel can infer adb reverse.`
|
|
260
248
|
);
|
|
261
249
|
}
|
|
262
250
|
|
|
@@ -337,7 +325,7 @@ async function resolveAndroidDeviceTarget({
|
|
|
337
325
|
appRoot
|
|
338
326
|
});
|
|
339
327
|
if (devices.length < 1) {
|
|
340
|
-
throw ctx.createCliError(`No Android devices are visible to adb. Run jskit mobile devices
|
|
328
|
+
throw ctx.createCliError(`No Android devices are visible to adb. Run jskit mobile android devices before ${commandLabel}.`);
|
|
341
329
|
}
|
|
342
330
|
|
|
343
331
|
const normalizedExplicitTarget = String(explicitTarget || "").trim();
|
|
@@ -346,7 +334,7 @@ async function resolveAndroidDeviceTarget({
|
|
|
346
334
|
: devices[0];
|
|
347
335
|
|
|
348
336
|
if (!selectedDevice) {
|
|
349
|
-
throw ctx.createCliError(`Android device "${normalizedExplicitTarget}" is not visible to adb. Run jskit mobile devices
|
|
337
|
+
throw ctx.createCliError(`Android device "${normalizedExplicitTarget}" is not visible to adb. Run jskit mobile android devices first.`);
|
|
350
338
|
}
|
|
351
339
|
if (selectedDevice.state !== "device") {
|
|
352
340
|
throw ctx.createCliError(`Android device "${selectedDevice.serial}" is currently "${selectedDevice.state}", not ready for ${commandLabel}.`);
|
|
@@ -400,9 +388,13 @@ async function runLocalBinary(binaryName, args = [], {
|
|
|
400
388
|
|
|
401
389
|
child.on("error", (error) => {
|
|
402
390
|
if (error?.code === "ENOENT") {
|
|
391
|
+
const installHint =
|
|
392
|
+
binaryName === "cap"
|
|
393
|
+
? ` Run npm install after adding ${CAPACITOR_RUNTIME_PACKAGE_ID}, then rerun this command.`
|
|
394
|
+
: "";
|
|
403
395
|
reject(
|
|
404
396
|
createCliError(
|
|
405
|
-
`Could not find local "${binaryName}" in node_modules/.bin
|
|
397
|
+
`Could not find local "${binaryName}" in node_modules/.bin.${installHint}`
|
|
406
398
|
)
|
|
407
399
|
);
|
|
408
400
|
return;
|
|
@@ -422,122 +414,93 @@ async function runLocalBinary(binaryName, args = [], {
|
|
|
422
414
|
});
|
|
423
415
|
}
|
|
424
416
|
|
|
425
|
-
|
|
417
|
+
function hasPackageDependency(packageJson = {}, packageId = "") {
|
|
418
|
+
const sections = [
|
|
419
|
+
packageJson?.dependencies,
|
|
420
|
+
packageJson?.devDependencies,
|
|
421
|
+
packageJson?.optionalDependencies
|
|
422
|
+
];
|
|
423
|
+
return sections.some((section) => (
|
|
424
|
+
section &&
|
|
425
|
+
typeof section === "object" &&
|
|
426
|
+
!Array.isArray(section) &&
|
|
427
|
+
Object.prototype.hasOwnProperty.call(section, packageId)
|
|
428
|
+
));
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
async function readJsonFileForMobileCommand(filePath = "", label = "", createCliError) {
|
|
432
|
+
try {
|
|
433
|
+
return JSON.parse(await readFile(filePath, "utf8"));
|
|
434
|
+
} catch (error) {
|
|
435
|
+
const message = String(error?.message || error || "unknown error");
|
|
436
|
+
throw createCliError(`Could not read ${label}: ${message}`);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
async function assertMobileRuntimePackageInstalled({
|
|
426
441
|
ctx,
|
|
427
|
-
appRoot
|
|
428
|
-
stdout,
|
|
429
|
-
stderr,
|
|
430
|
-
dryRun = false,
|
|
431
|
-
devlinks = false
|
|
442
|
+
appRoot
|
|
432
443
|
} = {}) {
|
|
433
444
|
const {
|
|
434
445
|
path: pathModule,
|
|
435
|
-
|
|
446
|
+
createCliError
|
|
436
447
|
} = ctx;
|
|
437
|
-
const
|
|
438
|
-
const
|
|
439
|
-
|
|
440
|
-
await
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
stdout,
|
|
444
|
-
pathModule,
|
|
445
|
-
createCliError: ctx.createCliError,
|
|
446
|
-
dryRun
|
|
447
|
-
});
|
|
448
|
+
const packageJsonPath = pathModule.join(appRoot, "package.json");
|
|
449
|
+
const lockPath = pathModule.join(appRoot, ".jskit", "lock.json");
|
|
450
|
+
const packageJson = await readJsonFileForMobileCommand(packageJsonPath, "package.json", createCliError);
|
|
451
|
+
const lock = await readJsonFileForMobileCommand(lockPath, ".jskit/lock.json", createCliError);
|
|
452
|
+
const hasDependency = hasPackageDependency(packageJson, CAPACITOR_RUNTIME_PACKAGE_ID);
|
|
453
|
+
const hasLockRecord = Boolean(lock?.installedPackages?.[CAPACITOR_RUNTIME_PACKAGE_ID]);
|
|
448
454
|
|
|
449
|
-
if (
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
stdout,
|
|
454
|
-
pathModule,
|
|
455
|
-
createCliError: ctx.createCliError,
|
|
456
|
-
dryRun
|
|
457
|
-
});
|
|
455
|
+
if (!hasDependency || !hasLockRecord) {
|
|
456
|
+
throw createCliError(
|
|
457
|
+
`Mobile Capacitor runtime package is not installed for this app. Run jskit add package ${CAPACITOR_RUNTIME_PACKAGE_ID} first.`
|
|
458
|
+
);
|
|
458
459
|
}
|
|
459
460
|
}
|
|
460
461
|
|
|
461
462
|
async function refreshManagedMobileFiles({
|
|
462
463
|
ctx,
|
|
463
|
-
commandAdd,
|
|
464
464
|
appRoot,
|
|
465
465
|
options = {},
|
|
466
|
-
stdout
|
|
467
|
-
stderr
|
|
466
|
+
stdout
|
|
468
467
|
} = {}) {
|
|
469
468
|
const {
|
|
470
|
-
|
|
469
|
+
fileExists,
|
|
470
|
+
path: pathModule,
|
|
471
|
+
normalizeRelativePath,
|
|
472
|
+
createCliError
|
|
471
473
|
} = ctx;
|
|
472
|
-
const packageJsonPath = pathModule.join(appRoot, "package.json");
|
|
473
|
-
const packageJsonBefore = await readFile(packageJsonPath, "utf8");
|
|
474
|
-
let capturedStdout = "";
|
|
475
|
-
await commandAdd({
|
|
476
|
-
positional: ["package", CAPACITOR_RUNTIME_PACKAGE_ID],
|
|
477
|
-
options: {
|
|
478
|
-
...options,
|
|
479
|
-
forceReapplyTarget: true,
|
|
480
|
-
runNpmInstall: false,
|
|
481
|
-
inlineOptions: {}
|
|
482
|
-
},
|
|
483
|
-
cwd: appRoot,
|
|
484
|
-
io: {
|
|
485
|
-
stdout: {
|
|
486
|
-
write(chunk) {
|
|
487
|
-
capturedStdout += String(chunk || "");
|
|
488
|
-
}
|
|
489
|
-
},
|
|
490
|
-
stderr
|
|
491
|
-
}
|
|
492
|
-
});
|
|
493
|
-
const packageJsonAfter = await readFile(packageJsonPath, "utf8");
|
|
494
|
-
const parsedPackageJsonAfter = JSON.parse(packageJsonAfter);
|
|
495
|
-
const missingInstalledDependencies = await collectMissingInstalledDependencyNames(ctx, appRoot, parsedPackageJsonAfter);
|
|
496
474
|
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
475
|
+
for (const relativePath of MANAGED_MOBILE_FILE_RELATIVE_PATHS) {
|
|
476
|
+
const absolutePath = pathModule.join(appRoot, relativePath);
|
|
477
|
+
if (!(await fileExists(absolutePath))) {
|
|
478
|
+
throw createCliError(
|
|
479
|
+
`Managed mobile file is missing: ${normalizeRelativePath(appRoot, absolutePath)}. Run jskit add package ${CAPACITOR_RUNTIME_PACKAGE_ID} first.`
|
|
480
|
+
);
|
|
481
|
+
}
|
|
500
482
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
(packageJsonAfter !== packageJsonBefore || missingInstalledDependencies.length > 0)
|
|
504
|
-
) {
|
|
505
|
-
await runMobileAppInstall({
|
|
506
|
-
ctx,
|
|
483
|
+
const currentSource = await readFile(absolutePath, "utf8");
|
|
484
|
+
const nextSource = await renderManagedMobileFile({
|
|
507
485
|
appRoot,
|
|
508
|
-
|
|
509
|
-
stderr,
|
|
510
|
-
dryRun: false,
|
|
511
|
-
devlinks: options?.devlinks === true
|
|
486
|
+
relativeTargetPath: relativePath
|
|
512
487
|
});
|
|
513
|
-
|
|
514
|
-
|
|
488
|
+
if (nextSource === currentSource) {
|
|
489
|
+
continue;
|
|
490
|
+
}
|
|
515
491
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
options = {},
|
|
520
|
-
stdout,
|
|
521
|
-
stderr
|
|
522
|
-
}) {
|
|
523
|
-
return await commandAdd({
|
|
524
|
-
positional: ["package", CAPACITOR_RUNTIME_PACKAGE_ID],
|
|
525
|
-
options: {
|
|
526
|
-
...options,
|
|
527
|
-
runNpmInstall: true,
|
|
528
|
-
inlineOptions: {}
|
|
529
|
-
},
|
|
530
|
-
cwd: appRoot,
|
|
531
|
-
io: {
|
|
532
|
-
stdout,
|
|
533
|
-
stderr
|
|
492
|
+
if (options?.dryRun === true) {
|
|
493
|
+
stdout?.write(`[dry-run] refresh ${normalizeRelativePath(appRoot, absolutePath)}\n`);
|
|
494
|
+
continue;
|
|
534
495
|
}
|
|
535
|
-
|
|
496
|
+
|
|
497
|
+
await writeFile(absolutePath, nextSource, "utf8");
|
|
498
|
+
stdout?.write(`[mobile] Refreshed ${normalizeRelativePath(appRoot, absolutePath)}.\n`);
|
|
499
|
+
}
|
|
536
500
|
}
|
|
537
501
|
|
|
538
502
|
async function runMobileSyncAndroidCommand({
|
|
539
503
|
ctx,
|
|
540
|
-
commandAdd,
|
|
541
504
|
appRoot,
|
|
542
505
|
options = {},
|
|
543
506
|
stdout,
|
|
@@ -547,19 +510,20 @@ async function runMobileSyncAndroidCommand({
|
|
|
547
510
|
path: pathModule
|
|
548
511
|
} = ctx;
|
|
549
512
|
|
|
550
|
-
await
|
|
513
|
+
await assertMobileRuntimePackageInstalled({
|
|
551
514
|
ctx,
|
|
552
|
-
|
|
553
|
-
appRoot,
|
|
554
|
-
options,
|
|
555
|
-
stdout,
|
|
556
|
-
stderr
|
|
515
|
+
appRoot
|
|
557
516
|
});
|
|
558
|
-
|
|
559
517
|
await assertCapacitorShellInstalled({
|
|
560
518
|
ctx,
|
|
561
519
|
appRoot
|
|
562
520
|
});
|
|
521
|
+
await refreshManagedMobileFiles({
|
|
522
|
+
ctx,
|
|
523
|
+
appRoot,
|
|
524
|
+
options,
|
|
525
|
+
stdout
|
|
526
|
+
});
|
|
563
527
|
await ensureAndroidNativeShellIdentity({
|
|
564
528
|
ctx,
|
|
565
529
|
appRoot,
|
|
@@ -600,7 +564,6 @@ async function runMobileSyncAndroidCommand({
|
|
|
600
564
|
|
|
601
565
|
async function runMobileRunAndroidCommand({
|
|
602
566
|
ctx,
|
|
603
|
-
commandAdd,
|
|
604
567
|
appRoot,
|
|
605
568
|
options = {},
|
|
606
569
|
stdout,
|
|
@@ -625,26 +588,26 @@ async function runMobileRunAndroidCommand({
|
|
|
625
588
|
if (mobileConfig.assetMode === "bundled") {
|
|
626
589
|
await runMobileSyncAndroidCommand({
|
|
627
590
|
ctx,
|
|
628
|
-
commandAdd,
|
|
629
591
|
appRoot,
|
|
630
592
|
options,
|
|
631
593
|
stdout,
|
|
632
594
|
stderr
|
|
633
595
|
});
|
|
634
596
|
} else {
|
|
635
|
-
await
|
|
597
|
+
await assertMobileRuntimePackageInstalled({
|
|
636
598
|
ctx,
|
|
637
|
-
|
|
638
|
-
appRoot,
|
|
639
|
-
options,
|
|
640
|
-
stdout,
|
|
641
|
-
stderr
|
|
599
|
+
appRoot
|
|
642
600
|
});
|
|
643
|
-
|
|
644
601
|
await assertCapacitorShellInstalled({
|
|
645
602
|
ctx,
|
|
646
603
|
appRoot
|
|
647
604
|
});
|
|
605
|
+
await refreshManagedMobileFiles({
|
|
606
|
+
ctx,
|
|
607
|
+
appRoot,
|
|
608
|
+
options,
|
|
609
|
+
stdout
|
|
610
|
+
});
|
|
648
611
|
await ensureAndroidNativeShellIdentity({
|
|
649
612
|
ctx,
|
|
650
613
|
appRoot,
|
|
@@ -715,7 +678,6 @@ async function runCapRunAndroidCommand({
|
|
|
715
678
|
|
|
716
679
|
async function runMobileBuildAndroidCommand({
|
|
717
680
|
ctx,
|
|
718
|
-
commandAdd,
|
|
719
681
|
appRoot,
|
|
720
682
|
options = {},
|
|
721
683
|
stdout,
|
|
@@ -738,13 +700,12 @@ async function runMobileBuildAndroidCommand({
|
|
|
738
700
|
|
|
739
701
|
if (mobileConfig.assetMode !== "bundled") {
|
|
740
702
|
throw createCliError(
|
|
741
|
-
'jskit mobile build
|
|
703
|
+
'jskit mobile android build requires config.mobile.assetMode="bundled" so the release shell does not depend on a live dev server.'
|
|
742
704
|
);
|
|
743
705
|
}
|
|
744
706
|
|
|
745
707
|
await runMobileSyncAndroidCommand({
|
|
746
708
|
ctx,
|
|
747
|
-
commandAdd,
|
|
748
709
|
appRoot,
|
|
749
710
|
options,
|
|
750
711
|
stdout,
|
|
@@ -906,9 +867,6 @@ async function runMobileTunnelAndroidCommand({
|
|
|
906
867
|
}) {
|
|
907
868
|
const inlineOptions = normalizeInlineOptions(options);
|
|
908
869
|
const target = String(inlineOptions.target || "").trim();
|
|
909
|
-
if (!target) {
|
|
910
|
-
throw ctx.createCliError("jskit mobile tunnel android requires --target <device-id>.");
|
|
911
|
-
}
|
|
912
870
|
|
|
913
871
|
const mobileConfig = await resolveInstalledMobileConfigForCommand({
|
|
914
872
|
appRoot,
|
|
@@ -960,9 +918,6 @@ async function runMobileRestartAndroidCommand({
|
|
|
960
918
|
}) {
|
|
961
919
|
const inlineOptions = normalizeInlineOptions(options);
|
|
962
920
|
const target = String(inlineOptions.target || "").trim();
|
|
963
|
-
if (!target) {
|
|
964
|
-
throw ctx.createCliError("jskit mobile restart android requires --target <device-id>.");
|
|
965
|
-
}
|
|
966
921
|
|
|
967
922
|
const mobileConfig = await resolveInstalledMobileConfigForCommand({
|
|
968
923
|
appRoot,
|
|
@@ -1004,7 +959,6 @@ async function runMobileRestartAndroidCommand({
|
|
|
1004
959
|
|
|
1005
960
|
async function runMobileDevAndroidCommand({
|
|
1006
961
|
ctx,
|
|
1007
|
-
commandAdd,
|
|
1008
962
|
appRoot,
|
|
1009
963
|
options = {},
|
|
1010
964
|
stdout,
|
|
@@ -1020,30 +974,17 @@ async function runMobileDevAndroidCommand({
|
|
|
1020
974
|
|
|
1021
975
|
stdout.write(`[mobile] Using Android device: ${selectedDevice.serial}\n`);
|
|
1022
976
|
stdout.write("[mobile] Building and syncing the Android shell:\n");
|
|
1023
|
-
stdout.write("[mobile] npx jskit mobile sync
|
|
977
|
+
stdout.write("[mobile] npx jskit mobile android sync\n");
|
|
1024
978
|
await runMobileSyncAndroidCommand({
|
|
1025
979
|
ctx,
|
|
1026
|
-
commandAdd,
|
|
1027
980
|
appRoot,
|
|
1028
981
|
options,
|
|
1029
982
|
stdout,
|
|
1030
983
|
stderr
|
|
1031
984
|
});
|
|
1032
985
|
|
|
1033
|
-
stdout.write(`[mobile] Installing and launching the app on ${selectedDevice.serial}:\n`);
|
|
1034
|
-
stdout.write(`[mobile] npx jskit mobile run android --target ${selectedDevice.serial}\n`);
|
|
1035
|
-
await runCapRunAndroidCommand({
|
|
1036
|
-
ctx,
|
|
1037
|
-
appRoot,
|
|
1038
|
-
pathModule: ctx.path,
|
|
1039
|
-
target: selectedDevice.serial,
|
|
1040
|
-
stdout,
|
|
1041
|
-
stderr,
|
|
1042
|
-
dryRun: false
|
|
1043
|
-
});
|
|
1044
|
-
|
|
1045
986
|
stdout.write(`[mobile] Creating the adb reverse tunnel on ${selectedDevice.serial}:\n`);
|
|
1046
|
-
stdout.write(`[mobile] npx jskit mobile tunnel
|
|
987
|
+
stdout.write(`[mobile] npx jskit mobile android tunnel --target ${selectedDevice.serial}\n`);
|
|
1047
988
|
await runMobileTunnelAndroidCommand({
|
|
1048
989
|
ctx,
|
|
1049
990
|
appRoot,
|
|
@@ -1056,23 +997,32 @@ async function runMobileDevAndroidCommand({
|
|
|
1056
997
|
stderr
|
|
1057
998
|
});
|
|
1058
999
|
|
|
1000
|
+
stdout.write(`[mobile] Installing and launching the app on ${selectedDevice.serial}:\n`);
|
|
1001
|
+
stdout.write(`[mobile] npx jskit mobile android run --target ${selectedDevice.serial}\n`);
|
|
1002
|
+
await runCapRunAndroidCommand({
|
|
1003
|
+
ctx,
|
|
1004
|
+
appRoot,
|
|
1005
|
+
pathModule: ctx.path,
|
|
1006
|
+
target: selectedDevice.serial,
|
|
1007
|
+
stdout,
|
|
1008
|
+
stderr,
|
|
1009
|
+
dryRun: false
|
|
1010
|
+
});
|
|
1011
|
+
|
|
1059
1012
|
return 0;
|
|
1060
1013
|
}
|
|
1061
1014
|
|
|
1062
|
-
function createMobileCommands(ctx = {}
|
|
1015
|
+
function createMobileCommands(ctx = {}) {
|
|
1063
1016
|
const {
|
|
1064
1017
|
createCliError,
|
|
1065
1018
|
resolveAppRootFromCwd
|
|
1066
1019
|
} = ctx;
|
|
1067
1020
|
|
|
1068
|
-
if (typeof commandAdd !== "function") {
|
|
1069
|
-
throw new TypeError("createMobileCommands requires commandAdd().");
|
|
1070
|
-
}
|
|
1071
|
-
|
|
1072
1021
|
async function commandMobile({ positional = [], options = {}, cwd = "", stdout, stderr }) {
|
|
1073
1022
|
const firstToken = String(positional[0] || "").trim();
|
|
1074
1023
|
const secondToken = String(positional[1] || "").trim();
|
|
1075
|
-
const
|
|
1024
|
+
const thirdToken = String(positional[2] || "").trim();
|
|
1025
|
+
const remainingPositionals = positional.slice(3);
|
|
1076
1026
|
|
|
1077
1027
|
if (!firstToken) {
|
|
1078
1028
|
renderMobileHelp(stdout);
|
|
@@ -1080,19 +1030,31 @@ function createMobileCommands(ctx = {}, { commandAdd } = {}) {
|
|
|
1080
1030
|
}
|
|
1081
1031
|
|
|
1082
1032
|
if (firstToken === "help") {
|
|
1083
|
-
renderMobileHelp(stdout
|
|
1033
|
+
renderMobileHelp(stdout);
|
|
1084
1034
|
return 0;
|
|
1085
1035
|
}
|
|
1086
1036
|
|
|
1087
|
-
const
|
|
1088
|
-
if (
|
|
1089
|
-
throw createCliError(`Unknown mobile
|
|
1037
|
+
const platform = firstToken;
|
|
1038
|
+
if (platform !== "android") {
|
|
1039
|
+
throw createCliError(`Unknown mobile platform: ${platform}.`, {
|
|
1090
1040
|
renderUsage: () => renderMobileHelp(stderr)
|
|
1091
1041
|
});
|
|
1092
1042
|
}
|
|
1093
1043
|
|
|
1094
|
-
if (secondToken === "help") {
|
|
1095
|
-
renderMobileHelp(stdout,
|
|
1044
|
+
if (!secondToken || secondToken === "help") {
|
|
1045
|
+
renderMobileHelp(stdout, null, platform);
|
|
1046
|
+
return 0;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
const definition = resolveMobileCommandDefinition(secondToken);
|
|
1050
|
+
if (!definition) {
|
|
1051
|
+
throw createCliError(`Unknown mobile ${platform} subcommand: ${secondToken}.`, {
|
|
1052
|
+
renderUsage: () => renderMobileHelp(stderr, null, platform)
|
|
1053
|
+
});
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
if (thirdToken === "help") {
|
|
1057
|
+
renderMobileHelp(stdout, definition, platform);
|
|
1096
1058
|
return 0;
|
|
1097
1059
|
}
|
|
1098
1060
|
|
|
@@ -1102,14 +1064,14 @@ function createMobileCommands(ctx = {}, { commandAdd } = {}) {
|
|
|
1102
1064
|
const unknownInlineOptionNames = inlineOptionNames.filter((optionName) => !supportedOptionNames.has(optionName));
|
|
1103
1065
|
if (unknownInlineOptionNames.length > 0) {
|
|
1104
1066
|
throw createCliError(
|
|
1105
|
-
`Unknown option${unknownInlineOptionNames.length === 1 ? "" : "s"} for jskit mobile ${definition.name}: ${unknownInlineOptionNames.map((optionName) => `--${optionName}`).join(", ")}.`,
|
|
1067
|
+
`Unknown option${unknownInlineOptionNames.length === 1 ? "" : "s"} for jskit mobile ${platform} ${definition.name}: ${unknownInlineOptionNames.map((optionName) => `--${optionName}`).join(", ")}.`,
|
|
1106
1068
|
{
|
|
1107
1069
|
renderUsage: () => renderMobileHelp(stderr, definition)
|
|
1108
1070
|
}
|
|
1109
1071
|
);
|
|
1110
1072
|
}
|
|
1111
1073
|
if (options?.dryRun === true && !supportedOptionNames.has("dry-run")) {
|
|
1112
|
-
throw createCliError(`Unknown option for jskit mobile ${definition.name}: --dry-run.`, {
|
|
1074
|
+
throw createCliError(`Unknown option for jskit mobile ${platform} ${definition.name}: --dry-run.`, {
|
|
1113
1075
|
renderUsage: () => renderMobileHelp(stderr, definition)
|
|
1114
1076
|
});
|
|
1115
1077
|
}
|
|
@@ -1117,13 +1079,8 @@ function createMobileCommands(ctx = {}, { commandAdd } = {}) {
|
|
|
1117
1079
|
const appRoot = await resolveAppRootFromCwd(cwd);
|
|
1118
1080
|
|
|
1119
1081
|
if (definition.name === "devices") {
|
|
1120
|
-
if (
|
|
1121
|
-
throw createCliError(`jskit mobile devices
|
|
1122
|
-
renderUsage: () => renderMobileHelp(stderr, definition)
|
|
1123
|
-
});
|
|
1124
|
-
}
|
|
1125
|
-
if (remainingPositionals.length > 0) {
|
|
1126
|
-
throw createCliError(`Unexpected positional arguments for jskit mobile devices: ${remainingPositionals.join(" ")}`, {
|
|
1082
|
+
if (thirdToken || remainingPositionals.length > 0) {
|
|
1083
|
+
throw createCliError(`Unexpected positional arguments for jskit mobile ${platform} devices: ${[thirdToken, ...remainingPositionals].filter(Boolean).join(" ")}`, {
|
|
1127
1084
|
renderUsage: () => renderMobileHelp(stderr, definition)
|
|
1128
1085
|
});
|
|
1129
1086
|
}
|
|
@@ -1137,20 +1094,14 @@ function createMobileCommands(ctx = {}, { commandAdd } = {}) {
|
|
|
1137
1094
|
}
|
|
1138
1095
|
|
|
1139
1096
|
if (definition.name === "dev") {
|
|
1140
|
-
if (
|
|
1141
|
-
throw createCliError(`jskit mobile dev
|
|
1142
|
-
renderUsage: () => renderMobileHelp(stderr, definition)
|
|
1143
|
-
});
|
|
1144
|
-
}
|
|
1145
|
-
if (remainingPositionals.length > 0) {
|
|
1146
|
-
throw createCliError(`Unexpected positional arguments for jskit mobile dev: ${remainingPositionals.join(" ")}`, {
|
|
1097
|
+
if (thirdToken || remainingPositionals.length > 0) {
|
|
1098
|
+
throw createCliError(`Unexpected positional arguments for jskit mobile ${platform} dev: ${[thirdToken, ...remainingPositionals].filter(Boolean).join(" ")}`, {
|
|
1147
1099
|
renderUsage: () => renderMobileHelp(stderr, definition)
|
|
1148
1100
|
});
|
|
1149
1101
|
}
|
|
1150
1102
|
|
|
1151
1103
|
return runMobileDevAndroidCommand({
|
|
1152
1104
|
ctx,
|
|
1153
|
-
commandAdd,
|
|
1154
1105
|
appRoot,
|
|
1155
1106
|
options,
|
|
1156
1107
|
stdout,
|
|
@@ -1159,13 +1110,8 @@ function createMobileCommands(ctx = {}, { commandAdd } = {}) {
|
|
|
1159
1110
|
}
|
|
1160
1111
|
|
|
1161
1112
|
if (definition.name === "tunnel") {
|
|
1162
|
-
if (
|
|
1163
|
-
throw createCliError(`jskit mobile tunnel
|
|
1164
|
-
renderUsage: () => renderMobileHelp(stderr, definition)
|
|
1165
|
-
});
|
|
1166
|
-
}
|
|
1167
|
-
if (remainingPositionals.length > 0) {
|
|
1168
|
-
throw createCliError(`Unexpected positional arguments for jskit mobile tunnel: ${remainingPositionals.join(" ")}`, {
|
|
1113
|
+
if (thirdToken || remainingPositionals.length > 0) {
|
|
1114
|
+
throw createCliError(`Unexpected positional arguments for jskit mobile ${platform} tunnel: ${[thirdToken, ...remainingPositionals].filter(Boolean).join(" ")}`, {
|
|
1169
1115
|
renderUsage: () => renderMobileHelp(stderr, definition)
|
|
1170
1116
|
});
|
|
1171
1117
|
}
|
|
@@ -1180,13 +1126,8 @@ function createMobileCommands(ctx = {}, { commandAdd } = {}) {
|
|
|
1180
1126
|
}
|
|
1181
1127
|
|
|
1182
1128
|
if (definition.name === "restart") {
|
|
1183
|
-
if (
|
|
1184
|
-
throw createCliError(`jskit mobile restart
|
|
1185
|
-
renderUsage: () => renderMobileHelp(stderr, definition)
|
|
1186
|
-
});
|
|
1187
|
-
}
|
|
1188
|
-
if (remainingPositionals.length > 0) {
|
|
1189
|
-
throw createCliError(`Unexpected positional arguments for jskit mobile restart: ${remainingPositionals.join(" ")}`, {
|
|
1129
|
+
if (thirdToken || remainingPositionals.length > 0) {
|
|
1130
|
+
throw createCliError(`Unexpected positional arguments for jskit mobile ${platform} restart: ${[thirdToken, ...remainingPositionals].filter(Boolean).join(" ")}`, {
|
|
1190
1131
|
renderUsage: () => renderMobileHelp(stderr, definition)
|
|
1191
1132
|
});
|
|
1192
1133
|
}
|
|
@@ -1200,43 +1141,15 @@ function createMobileCommands(ctx = {}, { commandAdd } = {}) {
|
|
|
1200
1141
|
});
|
|
1201
1142
|
}
|
|
1202
1143
|
|
|
1203
|
-
if (definition.name === "add") {
|
|
1204
|
-
if (secondToken !== "capacitor") {
|
|
1205
|
-
throw createCliError(`jskit mobile add currently supports only "capacitor".`, {
|
|
1206
|
-
renderUsage: () => renderMobileHelp(stderr, definition)
|
|
1207
|
-
});
|
|
1208
|
-
}
|
|
1209
|
-
if (remainingPositionals.length > 0) {
|
|
1210
|
-
throw createCliError(`Unexpected positional arguments for jskit mobile add: ${remainingPositionals.join(" ")}`, {
|
|
1211
|
-
renderUsage: () => renderMobileHelp(stderr, definition)
|
|
1212
|
-
});
|
|
1213
|
-
}
|
|
1214
|
-
|
|
1215
|
-
return runMobileAddCapacitorCommand({
|
|
1216
|
-
ctx,
|
|
1217
|
-
commandAdd,
|
|
1218
|
-
appRoot,
|
|
1219
|
-
options,
|
|
1220
|
-
stdout,
|
|
1221
|
-
stderr
|
|
1222
|
-
});
|
|
1223
|
-
}
|
|
1224
|
-
|
|
1225
1144
|
if (definition.name === "sync") {
|
|
1226
|
-
if (
|
|
1227
|
-
throw createCliError(`jskit mobile sync
|
|
1228
|
-
renderUsage: () => renderMobileHelp(stderr, definition)
|
|
1229
|
-
});
|
|
1230
|
-
}
|
|
1231
|
-
if (remainingPositionals.length > 0) {
|
|
1232
|
-
throw createCliError(`Unexpected positional arguments for jskit mobile sync: ${remainingPositionals.join(" ")}`, {
|
|
1145
|
+
if (thirdToken || remainingPositionals.length > 0) {
|
|
1146
|
+
throw createCliError(`Unexpected positional arguments for jskit mobile ${platform} sync: ${[thirdToken, ...remainingPositionals].filter(Boolean).join(" ")}`, {
|
|
1233
1147
|
renderUsage: () => renderMobileHelp(stderr, definition)
|
|
1234
1148
|
});
|
|
1235
1149
|
}
|
|
1236
1150
|
|
|
1237
1151
|
return runMobileSyncAndroidCommand({
|
|
1238
1152
|
ctx,
|
|
1239
|
-
commandAdd,
|
|
1240
1153
|
appRoot,
|
|
1241
1154
|
options,
|
|
1242
1155
|
stdout,
|
|
@@ -1245,20 +1158,14 @@ function createMobileCommands(ctx = {}, { commandAdd } = {}) {
|
|
|
1245
1158
|
}
|
|
1246
1159
|
|
|
1247
1160
|
if (definition.name === "run") {
|
|
1248
|
-
if (
|
|
1249
|
-
throw createCliError(`jskit mobile run
|
|
1250
|
-
renderUsage: () => renderMobileHelp(stderr, definition)
|
|
1251
|
-
});
|
|
1252
|
-
}
|
|
1253
|
-
if (remainingPositionals.length > 0) {
|
|
1254
|
-
throw createCliError(`Unexpected positional arguments for jskit mobile run: ${remainingPositionals.join(" ")}`, {
|
|
1161
|
+
if (thirdToken || remainingPositionals.length > 0) {
|
|
1162
|
+
throw createCliError(`Unexpected positional arguments for jskit mobile ${platform} run: ${[thirdToken, ...remainingPositionals].filter(Boolean).join(" ")}`, {
|
|
1255
1163
|
renderUsage: () => renderMobileHelp(stderr, definition)
|
|
1256
1164
|
});
|
|
1257
1165
|
}
|
|
1258
1166
|
|
|
1259
1167
|
return runMobileRunAndroidCommand({
|
|
1260
1168
|
ctx,
|
|
1261
|
-
commandAdd,
|
|
1262
1169
|
appRoot,
|
|
1263
1170
|
options,
|
|
1264
1171
|
stdout,
|
|
@@ -1267,20 +1174,14 @@ function createMobileCommands(ctx = {}, { commandAdd } = {}) {
|
|
|
1267
1174
|
}
|
|
1268
1175
|
|
|
1269
1176
|
if (definition.name === "build") {
|
|
1270
|
-
if (
|
|
1271
|
-
throw createCliError(`jskit mobile build
|
|
1272
|
-
renderUsage: () => renderMobileHelp(stderr, definition)
|
|
1273
|
-
});
|
|
1274
|
-
}
|
|
1275
|
-
if (remainingPositionals.length > 0) {
|
|
1276
|
-
throw createCliError(`Unexpected positional arguments for jskit mobile build: ${remainingPositionals.join(" ")}`, {
|
|
1177
|
+
if (thirdToken || remainingPositionals.length > 0) {
|
|
1178
|
+
throw createCliError(`Unexpected positional arguments for jskit mobile ${platform} build: ${[thirdToken, ...remainingPositionals].filter(Boolean).join(" ")}`, {
|
|
1277
1179
|
renderUsage: () => renderMobileHelp(stderr, definition)
|
|
1278
1180
|
});
|
|
1279
1181
|
}
|
|
1280
1182
|
|
|
1281
1183
|
return runMobileBuildAndroidCommand({
|
|
1282
1184
|
ctx,
|
|
1283
|
-
commandAdd,
|
|
1284
1185
|
appRoot,
|
|
1285
1186
|
options,
|
|
1286
1187
|
stdout,
|
|
@@ -1289,8 +1190,8 @@ function createMobileCommands(ctx = {}, { commandAdd } = {}) {
|
|
|
1289
1190
|
}
|
|
1290
1191
|
|
|
1291
1192
|
if (definition.name === "doctor") {
|
|
1292
|
-
if (
|
|
1293
|
-
throw createCliError(`Unexpected positional arguments for jskit mobile doctor: ${[
|
|
1193
|
+
if (thirdToken || remainingPositionals.length > 0) {
|
|
1194
|
+
throw createCliError(`Unexpected positional arguments for jskit mobile ${platform} doctor: ${[thirdToken, ...remainingPositionals].filter(Boolean).join(" ")}`, {
|
|
1294
1195
|
renderUsage: () => renderMobileHelp(stderr, definition)
|
|
1295
1196
|
});
|
|
1296
1197
|
}
|