@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.
- package/README.md +175 -19
- package/dist/android-toolchain.d.ts +23 -0
- package/dist/android-toolchain.d.ts.map +1 -0
- package/dist/android-toolchain.js +319 -0
- package/dist/artifact-build.d.ts +17 -0
- package/dist/artifact-build.d.ts.map +1 -0
- package/dist/artifact-build.js +56 -0
- package/dist/artifact-name.d.ts +1 -1
- package/dist/artifact-name.d.ts.map +1 -1
- package/dist/autolink.d.ts +3 -2
- package/dist/autolink.d.ts.map +1 -1
- package/dist/autolink.js +130 -6
- package/dist/bundle-build.d.ts +2 -0
- package/dist/bundle-build.d.ts.map +1 -1
- package/dist/bundle-build.js +11 -3
- package/dist/config.d.ts +19 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -1
- package/dist/desktop-build.d.ts +22 -0
- package/dist/desktop-build.d.ts.map +1 -0
- package/dist/desktop-build.js +161 -0
- package/dist/desktop-signing.d.ts +14 -0
- package/dist/desktop-signing.d.ts.map +1 -0
- package/dist/desktop-signing.js +200 -0
- package/dist/dev-qr.d.ts +3 -0
- package/dist/dev-qr.d.ts.map +1 -0
- package/dist/dev-qr.js +12 -0
- package/dist/guidance.d.ts.map +1 -1
- package/dist/guidance.js +113 -4
- package/dist/harmony-build.d.ts +22 -0
- package/dist/harmony-build.d.ts.map +1 -0
- package/dist/harmony-build.js +194 -0
- package/dist/index.js +359 -74
- package/dist/ios-toolchain.d.ts +19 -0
- package/dist/ios-toolchain.d.ts.map +1 -0
- package/dist/ios-toolchain.js +303 -0
- package/dist/lynx-devtool.d.ts +18 -0
- package/dist/lynx-devtool.d.ts.map +1 -0
- package/dist/lynx-devtool.js +125 -0
- package/dist/process-runner.d.ts +11 -0
- package/dist/process-runner.d.ts.map +1 -1
- package/dist/process-runner.js +29 -0
- package/dist/prompt.d.ts +1 -0
- package/dist/prompt.d.ts.map +1 -1
- package/dist/prompt.js +6 -0
- package/dist/remote.d.ts +3 -3
- package/dist/remote.d.ts.map +1 -1
- package/dist/target-toolchain.d.ts +17 -0
- package/dist/target-toolchain.d.ts.map +1 -0
- package/dist/target-toolchain.js +122 -0
- package/dist/ui/components.d.ts +1 -0
- package/dist/ui/components.d.ts.map +1 -1
- package/dist/ui/components.js +7 -0
- package/dist/ui/index.d.ts +1 -0
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +4 -1
- package/dist/web-build.d.ts +16 -0
- package/dist/web-build.d.ts.map +1 -0
- package/dist/web-build.js +116 -0
- 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
|
+
}
|
package/dist/ui/components.d.ts
CHANGED
|
@@ -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"}
|
package/dist/ui/components.js
CHANGED
|
@@ -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
|
+
}
|
package/dist/ui/index.d.ts
CHANGED
|
@@ -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 };
|
package/dist/ui/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
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.
|
|
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": {
|