@lynxship/cli 0.1.8 → 0.1.11

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 (60) hide show
  1. package/README.md +175 -19
  2. package/dist/android-toolchain.d.ts +23 -0
  3. package/dist/android-toolchain.d.ts.map +1 -0
  4. package/dist/android-toolchain.js +319 -0
  5. package/dist/artifact-build.d.ts +17 -0
  6. package/dist/artifact-build.d.ts.map +1 -0
  7. package/dist/artifact-build.js +56 -0
  8. package/dist/artifact-name.d.ts +1 -1
  9. package/dist/artifact-name.d.ts.map +1 -1
  10. package/dist/autolink.d.ts +3 -2
  11. package/dist/autolink.d.ts.map +1 -1
  12. package/dist/autolink.js +130 -6
  13. package/dist/bundle-build.d.ts +2 -0
  14. package/dist/bundle-build.d.ts.map +1 -1
  15. package/dist/bundle-build.js +11 -3
  16. package/dist/config.d.ts +19 -0
  17. package/dist/config.d.ts.map +1 -1
  18. package/dist/config.js +1 -1
  19. package/dist/desktop-build.d.ts +22 -0
  20. package/dist/desktop-build.d.ts.map +1 -0
  21. package/dist/desktop-build.js +161 -0
  22. package/dist/desktop-signing.d.ts +14 -0
  23. package/dist/desktop-signing.d.ts.map +1 -0
  24. package/dist/desktop-signing.js +200 -0
  25. package/dist/dev-qr.d.ts +3 -0
  26. package/dist/dev-qr.d.ts.map +1 -0
  27. package/dist/dev-qr.js +12 -0
  28. package/dist/guidance.d.ts.map +1 -1
  29. package/dist/guidance.js +113 -4
  30. package/dist/harmony-build.d.ts +22 -0
  31. package/dist/harmony-build.d.ts.map +1 -0
  32. package/dist/harmony-build.js +194 -0
  33. package/dist/index.js +359 -74
  34. package/dist/ios-toolchain.d.ts +19 -0
  35. package/dist/ios-toolchain.d.ts.map +1 -0
  36. package/dist/ios-toolchain.js +303 -0
  37. package/dist/lynx-devtool.d.ts +18 -0
  38. package/dist/lynx-devtool.d.ts.map +1 -0
  39. package/dist/lynx-devtool.js +125 -0
  40. package/dist/process-runner.d.ts +11 -0
  41. package/dist/process-runner.d.ts.map +1 -1
  42. package/dist/process-runner.js +29 -0
  43. package/dist/prompt.d.ts +1 -0
  44. package/dist/prompt.d.ts.map +1 -1
  45. package/dist/prompt.js +6 -0
  46. package/dist/remote.d.ts +3 -3
  47. package/dist/remote.d.ts.map +1 -1
  48. package/dist/target-toolchain.d.ts +17 -0
  49. package/dist/target-toolchain.d.ts.map +1 -0
  50. package/dist/target-toolchain.js +122 -0
  51. package/dist/ui/components.d.ts +1 -0
  52. package/dist/ui/components.d.ts.map +1 -1
  53. package/dist/ui/components.js +7 -0
  54. package/dist/ui/index.d.ts +1 -0
  55. package/dist/ui/index.d.ts.map +1 -1
  56. package/dist/ui/index.js +4 -1
  57. package/dist/web-build.d.ts +16 -0
  58. package/dist/web-build.d.ts.map +1 -0
  59. package/dist/web-build.js +116 -0
  60. package/package.json +3 -3
@@ -0,0 +1,122 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { join, resolve } from "node:path";
3
+ import { commandExists } from "./process-runner.js";
4
+ import { hasDesktopHost, resolveDesktopPackScript } from "./desktop-build.js";
5
+ import { hasHarmonyHost, harmonyToolchain } from "./harmony-build.js";
6
+ import { hasWebConfiguration } from "./web-build.js";
7
+ import { inspectDesktopSigning } from "./desktop-signing.js";
8
+ function check(name, status, value, fix) {
9
+ return { name, status, ok: status !== "fail", value, fix };
10
+ }
11
+ function packageManifest(root) {
12
+ try {
13
+ return JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
14
+ }
15
+ catch {
16
+ return {};
17
+ }
18
+ }
19
+ function hasDependency(manifest, name) {
20
+ return Boolean(manifest.dependencies?.[name] || manifest.devDependencies?.[name]);
21
+ }
22
+ export async function inspectWebTarget(root, profile) {
23
+ const manifest = packageManifest(root);
24
+ const configured = hasWebConfiguration(root);
25
+ const customScript = Boolean(profile.web?.script || manifest.scripts?.["build:web"]);
26
+ const hasRspeedy = hasDependency(manifest, "@lynx-js/rspeedy");
27
+ const checks = [
28
+ check("web-configuration", configured ? "pass" : "fail", configured
29
+ ? "Lynx Web environment configured"
30
+ : "missing lynx.config.* or build:web script", configured
31
+ ? undefined
32
+ : "Configure environments.web in lynx.config.* or add a build:web script, then rerun lynxship doctor --platform web"),
33
+ check("web-build-tool", hasRspeedy || customScript ? "pass" : "fail", hasRspeedy
34
+ ? "@lynx-js/rspeedy detected"
35
+ : customScript
36
+ ? "project web build script detected"
37
+ : "@lynx-js/rspeedy not found", hasRspeedy || customScript
38
+ ? undefined
39
+ : "Install the project Lynx Web toolchain with the package manager, then rerun lynxship doctor --platform web"),
40
+ check("web-output", "warn", "dist/*.web.bundle is checked during the build", "Run lynxship build --platform web --profile production"),
41
+ ];
42
+ return { ok: checks.every((item) => item.status !== "fail"), checks };
43
+ }
44
+ function harmonySignTool(root, profile) {
45
+ const candidates = [
46
+ profile.harmony?.signTool
47
+ ? resolve(root, profile.harmony.signTool)
48
+ : undefined,
49
+ process.env.LYNXSHIP_HAP_SIGN_TOOL,
50
+ process.env.DEVECO_HAP_SIGN_TOOL,
51
+ process.env.HOS_SDK_HOME
52
+ ? join(process.env.HOS_SDK_HOME, "toolchains", "lib", "hap-sign-tool.jar")
53
+ : undefined,
54
+ process.env.DEVECO_SDK_HOME
55
+ ? join(process.env.DEVECO_SDK_HOME, "toolchains", "lib", "hap-sign-tool.jar")
56
+ : undefined,
57
+ ].filter((value) => Boolean(value));
58
+ return candidates.find((value) => existsSync(value));
59
+ }
60
+ export async function inspectHarmonyTarget(root, profile) {
61
+ const host = hasHarmonyHost(root);
62
+ const tools = harmonyToolchain(root);
63
+ const signTool = harmonySignTool(root, profile);
64
+ const checks = [
65
+ check("harmony-host", host ? "pass" : "fail", host
66
+ ? "Hvigor Harmony host found"
67
+ : "missing official harmony/ host files", host
68
+ ? undefined
69
+ : "Add the official Lynx Harmony host with harmony/hvigorw, hvigorfile.ts, build-profile.json5 and oh-package.json5"),
70
+ check("ohpm", tools.ohpm ? "pass" : "fail", tools.ohpm ? "ohpm detected" : "missing", tools.ohpm
71
+ ? undefined
72
+ : "Install DevEco Studio/OpenHarmony SDK and make ohpm available on PATH"),
73
+ check("harmony-java", commandExists("java") ? "pass" : "fail", commandExists("java") ? "Java detected" : "missing", commandExists("java")
74
+ ? undefined
75
+ : "Install the JDK required by the pinned DevEco/Hvigor project"),
76
+ check("hap-sign-tool", signTool ? "pass" : "fail", signTool ? "official hap-sign-tool.jar detected" : "missing", signTool
77
+ ? undefined
78
+ : "Set LYNXSHIP_HAP_SIGN_TOOL or build.<profile>.harmony.signTool to the official hap-sign-tool.jar"),
79
+ check("hdc", tools.hdc ? "pass" : "warn", tools.hdc
80
+ ? "hdc detected"
81
+ : "missing · required only for lynxship run/logs", tools.hdc
82
+ ? undefined
83
+ : "Install the OpenHarmony SDK platform tools before installing on a device"),
84
+ ];
85
+ return { ok: checks.every((item) => item.status !== "fail"), checks };
86
+ }
87
+ export async function inspectDesktopTarget(root, profile) {
88
+ const host = await hasDesktopHost(root, profile);
89
+ const manifest = packageManifest(root);
90
+ const builder = Boolean(resolveDesktopPackScript(manifest, profile)) ||
91
+ hasDependency(manifest, "@lynx-js/lynxtron-builder") ||
92
+ hasDependency(manifest, "electron-builder") ||
93
+ existsSync(join(root, "electron-builder.yml")) ||
94
+ existsSync(join(root, "electron-builder.yaml")) ||
95
+ existsSync(join(root, "electron-builder.json"));
96
+ const signing = await inspectDesktopSigning(root);
97
+ const checks = [
98
+ check("desktop-host", host ? "pass" : "fail", host
99
+ ? "Lynxtron/Electron desktop host found"
100
+ : "missing Lynxtron host or pack script", host
101
+ ? undefined
102
+ : "Use the official Lynxtron template and configure @lynx-js/lynxtron-builder, electron-builder.yml or a pack script"),
103
+ check("desktop-packager", builder ? "pass" : "fail", builder
104
+ ? "Lynxtron/Electron Builder packaging entry detected"
105
+ : "packaging entry not found", builder
106
+ ? undefined
107
+ : "Install @lynx-js/lynxtron-builder and add a pack script, then rerun lynxship doctor --platform desktop"),
108
+ check("desktop-platform", process.platform === "win32" || process.platform === "darwin"
109
+ ? "pass"
110
+ : "warn", process.platform === "win32" || process.platform === "darwin"
111
+ ? `${process.platform} desktop target`
112
+ : `${process.platform} host · verify the Lynxtron target explicitly`, process.platform === "win32" || process.platform === "darwin"
113
+ ? undefined
114
+ : "Run the desktop build on the target OS supported by the project’s Lynxtron/electron-builder configuration"),
115
+ check("desktop-signing", signing.status === "configured" || signing.status === "not-required"
116
+ ? "pass"
117
+ : signing.status === "unknown"
118
+ ? "warn"
119
+ : "fail", signing.value, signing.fix),
120
+ ];
121
+ return { ok: checks.every((item) => item.status !== "fail"), checks };
122
+ }
@@ -35,4 +35,5 @@ export declare const pill: {
35
35
  export declare function finalLine(message: string, success?: boolean): void;
36
36
  export declare function nextSteps(commands: string[], note?: string): void;
37
37
  export declare function downloadArtifact(url: string, expiresAt?: string, enabled?: boolean): void;
38
+ export declare function devServerQr(url: string, enabled?: boolean): void;
38
39
  //# sourceMappingURL=components.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../src/ui/components.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAI7C,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,SAAS,CAAC;CACxB;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAEjD;AAED,eAAO,MAAM,GAAG;qBACG,MAAM,GAAG,IAAI;kBAGhB,MAAM,GAAG,IAAI;mBAGZ,MAAM,GAAG,IAAI;kBAGd,MAAM,GAAG,IAAI;mBAGZ,MAAM,GAAG,IAAI;CAG7B,CAAC;AAgBF,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA6C9D;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C,IAAI,IAAI,IAAI,CAAC;CACd;AA6CD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAoBnD;AA6BD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,GACf,cAAc,CAuEhB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,IAAI,IAAI,CAAC;CACd;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,aAAa,CA2BlE;AAYD,eAAO,MAAM,IAAI;oBACC,MAAM;iBACT,MAAM;iBACN,MAAM;kBACL,MAAM;CACrB,CAAC;AAEF,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,UAAO,GAAG,IAAI,CAE/D;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAOjE;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,UAAO,GACb,IAAI,CAQN"}
1
+ {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../src/ui/components.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAI7C,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,SAAS,CAAC;CACxB;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAEjD;AAED,eAAO,MAAM,GAAG;qBACG,MAAM,GAAG,IAAI;kBAGhB,MAAM,GAAG,IAAI;mBAGZ,MAAM,GAAG,IAAI;kBAGd,MAAM,GAAG,IAAI;mBAGZ,MAAM,GAAG,IAAI;CAG7B,CAAC;AAgBF,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA6C9D;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C,IAAI,IAAI,IAAI,CAAC;CACd;AA6CD,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAoBnD;AA6BD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,OAAO,GACf,cAAc,CAuEhB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,IAAI,IAAI,CAAC;CACd;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,aAAa,CA2BlE;AAYD,eAAO,MAAM,IAAI;oBACC,MAAM;iBACT,MAAM;iBACN,MAAM;kBACL,MAAM;CACrB,CAAC;AAEF,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,UAAO,GAAG,IAAI,CAE/D;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAOjE;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,UAAO,GACb,IAAI,CAQN;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,UAAO,GAAG,IAAI,CAK7D"}
@@ -286,3 +286,10 @@ export function downloadArtifact(url, expiresAt, enabled = true) {
286
286
  if (expiresAt)
287
287
  console.log(` ${c.muted(`Link expires at ${expiresAt}`)}`);
288
288
  }
289
+ export function devServerQr(url, enabled = true) {
290
+ if (!enabled)
291
+ return;
292
+ console.log(`\n${c.brandBold("Lynx Explorer")}`);
293
+ qrcode.generate(url, { small: true }, (code) => console.log(code));
294
+ console.log(` ${c.teal("URL")} ${url}\n`);
295
+ }
@@ -19,6 +19,7 @@ export declare class CliUi {
19
19
  spinner(text: string): SpinnerHandle;
20
20
  done(message: string, success?: boolean): void;
21
21
  downloadArtifact(url: string, expiresAt?: string): void;
22
+ devServerQr(url: string): void;
22
23
  }
23
24
  export declare function createCliUi(args: string[]): CliUi;
24
25
  export { terminalOptions };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA,OAAO,EASL,KAAK,MAAM,EACX,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAEL,eAAe,EACf,KAAK,eAAe,EACrB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,qBAAa,KAAK;IAChB,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAElC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;gBAElB,IAAI,EAAE,MAAM,EAAE;IAU1B,MAAM,IAAI,IAAI;IAId,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI3B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI9B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI3B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI3B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAK5B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI5B,SAAS,CAAC,QAAQ,EAAE,WAAW,GAAG,IAAI;IAKtC,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI;IAI5C,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI;IAKzC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc;IAIvC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa;IAIpC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,UAAO,GAAG,IAAI;IAI3C,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;CAGxD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,CAEjD;AAED,OAAO,EAAE,eAAe,EAAE,CAAC;AAE3B,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAUL,KAAK,MAAM,EACX,KAAK,cAAc,EACnB,KAAK,aAAa,EACnB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAEL,eAAe,EACf,KAAK,eAAe,EACrB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,qBAAa,KAAK;IAChB,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAElC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;gBAElB,IAAI,EAAE,MAAM,EAAE;IAU1B,MAAM,IAAI,IAAI;IAId,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI3B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI9B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI3B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI3B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAK5B,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAI5B,SAAS,CAAC,QAAQ,EAAE,WAAW,GAAG,IAAI;IAKtC,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI;IAI5C,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI;IAKzC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc;IAIvC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa;IAIpC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,UAAO,GAAG,IAAI;IAI3C,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAIvD,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;CAG/B;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,CAEjD;AAED,OAAO,EAAE,eAAe,EAAE,CAAC;AAE3B,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,eAAe,EAAE,CAAC"}
package/dist/ui/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { finalLine, log, sectionHeader, summaryBox, nextSteps, createProgress, spin, downloadArtifact, } from "./components.js";
1
+ import { finalLine, log, sectionHeader, summaryBox, nextSteps, createProgress, spin, downloadArtifact, devServerQr, } from "./components.js";
2
2
  import { printBanner } from "./logo.js";
3
3
  import { setColors } from "./state.js";
4
4
  import { isInteractive, terminalOptions, } from "./terminal.js";
@@ -66,6 +66,9 @@ export class CliUi {
66
66
  downloadArtifact(url, expiresAt) {
67
67
  downloadArtifact(url, expiresAt, this.interactive);
68
68
  }
69
+ devServerQr(url) {
70
+ devServerQr(url, this.interactive && !this.options.quiet);
71
+ }
69
72
  }
70
73
  export function createCliUi(args) {
71
74
  return new CliUi(args);
@@ -0,0 +1,16 @@
1
+ import { type BuildJob } from "@lynxship/contracts";
2
+ import type { BuildProfile } from "./config.js";
3
+ interface WebBuildOptions {
4
+ root: string;
5
+ profile: BuildProfile;
6
+ uploadArtifacts?: boolean;
7
+ skipBundleBuild?: boolean;
8
+ quiet?: boolean;
9
+ onEvent?: (message: string) => void;
10
+ onProgress?: (value?: number, label?: string) => void;
11
+ }
12
+ export declare function detectWebBuildScript(root: string): string | undefined;
13
+ export declare function hasWebConfiguration(root: string): boolean;
14
+ export declare function runRealWebBuild(job: BuildJob, options: WebBuildOptions): Promise<BuildJob>;
15
+ export {};
16
+ //# sourceMappingURL=web-build.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-build.d.ts","sourceRoot":"","sources":["../src/web-build.ts"],"names":[],"mappings":"AAGA,OAAO,EAAU,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIhD,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,UAAU,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACvD;AAgBD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAOrE;AAiCD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAczD;AAED,wBAAsB,eAAe,CACnC,GAAG,EAAE,QAAQ,EACb,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,QAAQ,CAAC,CAsDnB"}
@@ -0,0 +1,116 @@
1
+ import { readdir } from "node:fs/promises";
2
+ import { existsSync, readFileSync } from "node:fs";
3
+ import { join, resolve } from "node:path";
4
+ import { assert } from "@lynxship/contracts";
5
+ import { transitionBuild } from "@lynxship/build-orchestrator";
6
+ import { publishBuiltArtifact } from "./artifact-build.js";
7
+ import { buildLynxBundle } from "./bundle-build.js";
8
+ function readPackageManifest(root) {
9
+ try {
10
+ return JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
11
+ }
12
+ catch {
13
+ return {};
14
+ }
15
+ }
16
+ export function detectWebBuildScript(root) {
17
+ const scripts = readPackageManifest(root).scripts;
18
+ if (!scripts)
19
+ return undefined;
20
+ for (const name of ["build:web", "build:web:production"]) {
21
+ if (scripts[name])
22
+ return name;
23
+ }
24
+ return undefined;
25
+ }
26
+ async function webBundle(root, profile) {
27
+ const configured = profile.web?.artifact;
28
+ if (configured) {
29
+ const file = resolve(root, configured);
30
+ assert(existsSync(file), "WEB_BUNDLE_MISSING", `Configured Web bundle was not found: ${file}`);
31
+ return file;
32
+ }
33
+ const candidates = [];
34
+ for (const directory of ["dist", "build/web", "build"]) {
35
+ const entries = await readdir(join(root, directory), {
36
+ withFileTypes: true,
37
+ }).catch(() => []);
38
+ for (const entry of entries) {
39
+ if (entry.isFile() && entry.name.endsWith(".web.bundle"))
40
+ candidates.push(join(root, directory, entry.name));
41
+ }
42
+ }
43
+ assert(candidates.length === 1, "WEB_BUNDLE_MISSING", candidates.length === 0
44
+ ? "Rspeedy did not produce a *.web.bundle in dist/, build/web/ or build/. Configure environments.web in lynx.config.* or set build.<profile>.web.artifact."
45
+ : "Rspeedy produced multiple *.web.bundle files. Set build.<profile>.web.artifact explicitly.");
46
+ return candidates[0];
47
+ }
48
+ export function hasWebConfiguration(root) {
49
+ const config = [
50
+ "lynx.config.ts",
51
+ "lynx.config.js",
52
+ "lynx.config.mjs",
53
+ "lynx.config.cjs",
54
+ ]
55
+ .map((file) => join(root, file))
56
+ .find((file) => existsSync(file));
57
+ if (config) {
58
+ const source = readFileSync(config, "utf8");
59
+ if (/environments[\s\S]{0,500}\bweb\b/i.test(source))
60
+ return true;
61
+ }
62
+ return Boolean(detectWebBuildScript(root));
63
+ }
64
+ export async function runRealWebBuild(job, options) {
65
+ const uploadArtifacts = options.uploadArtifacts ?? true;
66
+ const step = (message, value) => {
67
+ options.onEvent?.(message);
68
+ options.onProgress?.(value, message);
69
+ };
70
+ try {
71
+ transitionBuild(job, "uploading_source", "Web source prepared");
72
+ if (!options.skipBundleBuild) {
73
+ step("Building Lynx Web bundle with Rspeedy…", 10);
74
+ const script = options.profile.web?.script ?? detectWebBuildScript(options.root);
75
+ await buildLynxBundle(options.root, {
76
+ quiet: options.quiet,
77
+ onOutput: options.onEvent,
78
+ script,
79
+ rspeedyArgs: script
80
+ ? undefined
81
+ : ["--environment", options.profile.web?.environment ?? "web"],
82
+ });
83
+ }
84
+ else
85
+ step("Using existing Lynx Web bundle", 20);
86
+ const artifact = await webBundle(options.root, options.profile);
87
+ transitionBuild(job, "queued", "Web bundle queued locally");
88
+ transitionBuild(job, "provisioning", "Lynx Web environment selected");
89
+ transitionBuild(job, "installing_dependencies", "Web bundle verified");
90
+ transitionBuild(job, "building", "Web bundle created");
91
+ step("Lynx Web bundle ready", 70);
92
+ return await publishBuiltArtifact({
93
+ root: options.root,
94
+ job,
95
+ platform: "web",
96
+ artifactPath: artifact,
97
+ extension: "web.bundle",
98
+ contentType: "application/octet-stream",
99
+ uploadArtifacts,
100
+ verificationMessage: "Web bundle output verified",
101
+ quiet: options.quiet,
102
+ onEvent: options.onEvent,
103
+ onProgress: options.onProgress,
104
+ });
105
+ }
106
+ catch (error) {
107
+ if (!["success", "failed", "canceled", "timed_out"].includes(job.state))
108
+ transitionBuild(job, "failed", error instanceof Error ? error.message : "Web build failed");
109
+ job.logs.push({
110
+ level: "error",
111
+ message: error instanceof Error ? error.message : "Web build failed",
112
+ at: new Date().toISOString(),
113
+ });
114
+ throw error;
115
+ }
116
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lynxship/cli",
3
- "version": "0.1.8",
3
+ "version": "0.1.11",
4
4
  "description": "Build, sign, store, submit and update LynxJS applications from the terminal.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -68,10 +68,10 @@
68
68
  "cli-progress": "3.12.0",
69
69
  "ora": "8.2.0",
70
70
  "qrcode-terminal": "0.12.0",
71
+ "@lynxship/signing": "0.1.0",
72
+ "@lynxship/db": "0.1.0",
71
73
  "@lynxship/build-orchestrator": "0.1.0",
72
74
  "@lynxship/contracts": "0.1.0",
73
- "@lynxship/db": "0.1.0",
74
- "@lynxship/signing": "0.1.0",
75
75
  "@lynxship/submit": "0.1.0"
76
76
  },
77
77
  "devDependencies": {