@lynxship/cli 0.1.14 → 0.1.16
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 +34 -5
- package/dist/android-build.d.ts.map +1 -1
- package/dist/android-build.js +1 -0
- package/dist/bundle-build.d.ts +5 -0
- package/dist/bundle-build.d.ts.map +1 -1
- package/dist/bundle-build.js +42 -3
- package/dist/config.d.ts +4 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/desktop-build.d.ts.map +1 -1
- package/dist/desktop-build.js +1 -0
- package/dist/frameworks.d.ts +10 -0
- package/dist/frameworks.d.ts.map +1 -0
- package/dist/frameworks.js +104 -0
- package/dist/guidance.d.ts.map +1 -1
- package/dist/guidance.js +22 -0
- package/dist/harmony-build.d.ts.map +1 -1
- package/dist/harmony-build.js +1 -0
- package/dist/index.js +43 -6
- package/dist/ios-build.d.ts.map +1 -1
- package/dist/ios-build.js +2 -0
- package/dist/ui/components.d.ts +1 -1
- package/dist/ui/components.d.ts.map +1 -1
- package/dist/ui/components.js +15 -5
- package/dist/ui/index.d.ts +1 -1
- package/dist/ui/index.d.ts.map +1 -1
- package/dist/ui/index.js +2 -2
- package/dist/ui/qr.d.ts +4 -6
- package/dist/ui/qr.d.ts.map +1 -1
- package/dist/ui/qr.js +121 -65
- package/dist/web-build.d.ts.map +1 -1
- package/dist/web-build.js +1 -0
- package/package.json +11 -4
package/README.md
CHANGED
|
@@ -14,13 +14,13 @@ expiring download URL with a compact terminal QR code.
|
|
|
14
14
|
## Install
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
npm install --global @lynxship/cli
|
|
17
|
+
npm install --global @lynxship/cli@latest
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
Or run it without a global install:
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
npx @lynxship/cli doctor --project-dir ./my-lynx-app
|
|
23
|
+
npx @lynxship/cli@latest doctor --project-dir ./my-lynx-app
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
The package exposes the `lynxship` executable.
|
|
@@ -52,6 +52,34 @@ The CLI generator itself creates ReactLynx templates by default. Use the
|
|
|
52
52
|
official `create-vue-lynx` scaffold when Vue is required, then add LynxShip to
|
|
53
53
|
that existing project with `init`.
|
|
54
54
|
|
|
55
|
+
## Octane and Miso
|
|
56
|
+
|
|
57
|
+
LynxShip detects Octane and Miso projects without replacing their
|
|
58
|
+
project-owned configuration.
|
|
59
|
+
|
|
60
|
+
Octane uses the official `@octanejs/rspeedy-plugin`. The Lynx integration is
|
|
61
|
+
still early access and its Lynx packages are not currently published on npm,
|
|
62
|
+
so development validation must use the official Octane repository and its
|
|
63
|
+
pnpm workspace:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
git clone https://github.com/octanejs/octane.git
|
|
67
|
+
cd octane
|
|
68
|
+
pnpm install --filter @octanejs/rspeedy-plugin... --frozen-lockfile
|
|
69
|
+
pnpm --filter @octanejs/rspeedy-plugin exec rspeedy dev \
|
|
70
|
+
--root examples/gallery --environment lynx
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Miso uses the official Haskell/Nix flake rather than an npm build script.
|
|
74
|
+
Install Nix and the project's Haskell toolchain, then let LynxShip use the
|
|
75
|
+
flake's `default`/`bundle` output or configure a project-specific output in
|
|
76
|
+
`lynxship.json`. Miso remains experimental; a successful bundle does not
|
|
77
|
+
prove a signed Android or iOS production build.
|
|
78
|
+
|
|
79
|
+
See the source-verified fixture notes in the repository's
|
|
80
|
+
`examples/lynx-octane-fixture` and `examples/miso-lynx-fixture` directories,
|
|
81
|
+
plus `docs/compatibility.md`.
|
|
82
|
+
|
|
55
83
|
## Requirements
|
|
56
84
|
|
|
57
85
|
- Node.js 22 or 24 LTS, or Node.js 26 Current; Node.js 24 LTS is the
|
|
@@ -486,9 +514,10 @@ actual recording and analysis.
|
|
|
486
514
|
|
|
487
515
|
## Package layout
|
|
488
516
|
|
|
489
|
-
The CLI is backed by
|
|
490
|
-
|
|
491
|
-
|
|
517
|
+
The CLI is backed by public `@lynxship/*` runtime packages in this workspace.
|
|
518
|
+
Their published versions may differ from the CLI version; workspace ranges are
|
|
519
|
+
rewritten to released versions when the package is packed. Publish a changed
|
|
520
|
+
runtime package before publishing the CLI when its source or version changed.
|
|
492
521
|
|
|
493
522
|
## License
|
|
494
523
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"android-build.d.ts","sourceRoot":"","sources":["../src/android-build.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAWhD,UAAU,mBAAmB;IAC3B,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,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,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;AA8KD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAa7D;AAED,wBAAgB,0BAA0B,IAAI,OAAO,CAEpD;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAsCpE;AAED,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,QAAQ,EACb,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"android-build.d.ts","sourceRoot":"","sources":["../src/android-build.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAWhD,UAAU,mBAAmB;IAC3B,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,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,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;AA8KD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAa7D;AAED,wBAAgB,0BAA0B,IAAI,OAAO,CAEpD;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAsCpE;AAED,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,QAAQ,EACb,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,QAAQ,CAAC,CAgKnB"}
|
package/dist/android-build.js
CHANGED
package/dist/bundle-build.d.ts
CHANGED
|
@@ -4,6 +4,11 @@ export interface BundleBuildOptions {
|
|
|
4
4
|
onOutput?: (line: string) => void;
|
|
5
5
|
script?: string;
|
|
6
6
|
rspeedyArgs?: string[];
|
|
7
|
+
miso?: {
|
|
8
|
+
attribute?: string;
|
|
9
|
+
artifact?: string;
|
|
10
|
+
};
|
|
7
11
|
}
|
|
12
|
+
export declare function resolveMisoBuildTarget(flake: string, configuredAttribute?: string): string | undefined;
|
|
8
13
|
export declare function buildLynxBundle(root: string, options?: BundleBuildOptions): Promise<void>;
|
|
9
14
|
//# sourceMappingURL=bundle-build.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bundle-build.d.ts","sourceRoot":"","sources":["../src/bundle-build.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bundle-build.d.ts","sourceRoot":"","sources":["../src/bundle-build.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,kBAAkB;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,IAAI,CAAC,EAAE;QACL,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,EACb,mBAAmB,CAAC,EAAE,MAAM,GAC3B,MAAM,GAAG,SAAS,CAWpB;AAcD,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CA8Df"}
|
package/dist/bundle-build.js
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
|
-
import { readFile } from "node:fs/promises";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { copyFile, mkdir, readFile } from "node:fs/promises";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { basename, join, resolve } from "node:path";
|
|
4
|
+
import { assert } from "@lynxship/contracts";
|
|
5
|
+
import { commandExists, packageManagerScriptCommand, runProcess, runRspeedy, } from "./process-runner.js";
|
|
6
|
+
import { detectLynxFramework } from "./frameworks.js";
|
|
7
|
+
export function resolveMisoBuildTarget(flake, configuredAttribute) {
|
|
8
|
+
const explicitAttribute = configuredAttribute?.trim();
|
|
9
|
+
if (explicitAttribute)
|
|
10
|
+
return ".#" + explicitAttribute;
|
|
11
|
+
if (flake.includes("counter-bundle"))
|
|
12
|
+
return ".#counter-bundle";
|
|
13
|
+
if (/\binherit\s+bundle\b|\bdefault\s*=\s*bundle\b/.test(flake)) {
|
|
14
|
+
return ".#bundle";
|
|
15
|
+
}
|
|
16
|
+
if (/\bdefault\s*=/.test(flake) && flake.includes("mkLynxBundle")) {
|
|
17
|
+
return ".";
|
|
18
|
+
}
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
4
21
|
async function resolveBundleScript(root) {
|
|
5
22
|
try {
|
|
6
23
|
const manifest = JSON.parse(await readFile(join(root, "package.json"), "utf8"));
|
|
@@ -13,6 +30,28 @@ async function resolveBundleScript(root) {
|
|
|
13
30
|
return "build";
|
|
14
31
|
}
|
|
15
32
|
export async function buildLynxBundle(root, options = {}) {
|
|
33
|
+
const framework = await detectLynxFramework(root);
|
|
34
|
+
if (framework.buildSystem === "miso-nix" &&
|
|
35
|
+
!options.script &&
|
|
36
|
+
!options.rspeedyArgs) {
|
|
37
|
+
assert(commandExists("nix"), "BUILD_MISO_NIX_REQUIRED", "Miso requires Nix. Install Nix, then rerun lynxship doctor or provide a project build script.");
|
|
38
|
+
const flake = await readFile(join(root, "flake.nix"), "utf8").catch(() => "");
|
|
39
|
+
const target = resolveMisoBuildTarget(flake, options.miso?.attribute);
|
|
40
|
+
assert(target, "BUILD_MISO_ATTRIBUTE_REQUIRED", "Miso bundle output is not discoverable. Set build.<profile>.miso.attribute in lynxship.json, or expose a default/mkLynxBundle output in flake.nix.");
|
|
41
|
+
await runProcess("nix", ["build", target], {
|
|
42
|
+
cwd: root,
|
|
43
|
+
env: options.env,
|
|
44
|
+
quiet: options.quiet,
|
|
45
|
+
onOutput: options.onOutput,
|
|
46
|
+
});
|
|
47
|
+
const artifact = resolve(root, options.miso?.artifact ?? "result/main.lynx.bundle");
|
|
48
|
+
assert(existsSync(artifact), "BUILD_MISO_BUNDLE_MISSING", "Miso did not produce the configured Lynx bundle: " + artifact);
|
|
49
|
+
const output = join(root, "dist", basename(artifact));
|
|
50
|
+
await mkdir(join(root, "dist"), { recursive: true });
|
|
51
|
+
await copyFile(artifact, output);
|
|
52
|
+
options.onOutput?.("Miso bundle ready: " + output);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
16
55
|
if (!options.script && options.rspeedyArgs) {
|
|
17
56
|
await runRspeedy(root, "build", options.rspeedyArgs, {
|
|
18
57
|
env: options.env,
|
package/dist/config.d.ts
CHANGED
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"desktop-build.d.ts","sourceRoot":"","sources":["../src/desktop-build.ts"],"names":[],"mappings":"AAGA,OAAO,EAAU,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAahD,UAAU,mBAAmB;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,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;AAED,UAAU,WAAW;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,WAAW,EACrB,OAAO,CAAC,EAAE,YAAY,GACrB,MAAM,GAAG,SAAS,CAMpB;AAYD,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,OAAO,CAAC,CAmBlB;AA+DD,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,QAAQ,EACb,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"desktop-build.d.ts","sourceRoot":"","sources":["../src/desktop-build.ts"],"names":[],"mappings":"AAGA,OAAO,EAAU,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAahD,UAAU,mBAAmB;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,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;AAED,UAAU,WAAW;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,WAAW,EACrB,OAAO,CAAC,EAAE,YAAY,GACrB,MAAM,GAAG,SAAS,CAMpB;AAYD,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,OAAO,CAAC,CAmBlB;AA+DD,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,QAAQ,EACb,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,QAAQ,CAAC,CA2GnB"}
|
package/dist/desktop-build.js
CHANGED
|
@@ -99,6 +99,7 @@ export async function runRealDesktopBuild(job, options) {
|
|
|
99
99
|
await buildLynxBundle(options.root, {
|
|
100
100
|
quiet: options.quiet,
|
|
101
101
|
onOutput: options.onEvent,
|
|
102
|
+
miso: options.profile.miso,
|
|
102
103
|
});
|
|
103
104
|
}
|
|
104
105
|
transitionBuild(job, "queued", "Desktop build queued locally");
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type LynxFramework = "react" | "vue" | "octane" | "miso" | "vanilla" | "unknown";
|
|
2
|
+
export interface FrameworkDetection {
|
|
3
|
+
framework: LynxFramework;
|
|
4
|
+
label: string;
|
|
5
|
+
evidence: string;
|
|
6
|
+
buildSystem: "rspeedy" | "miso-nix" | "unknown";
|
|
7
|
+
experimental: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function detectLynxFramework(root: string): Promise<FrameworkDetection>;
|
|
10
|
+
//# sourceMappingURL=frameworks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frameworks.d.ts","sourceRoot":"","sources":["../src/frameworks.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,aAAa,GACrB,OAAO,GACP,KAAK,GACL,QAAQ,GACR,MAAM,GACN,SAAS,GACT,SAAS,CAAC;AAEd,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,aAAa,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;IAChD,YAAY,EAAE,OAAO,CAAC;CACvB;AAiCD,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,kBAAkB,CAAC,CA+F7B"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
async function readText(file) {
|
|
5
|
+
return readFile(file, "utf8").catch(() => "");
|
|
6
|
+
}
|
|
7
|
+
async function readManifest(root) {
|
|
8
|
+
try {
|
|
9
|
+
return JSON.parse(await readText(join(root, "package.json")));
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return {};
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function dependencyNames(manifest) {
|
|
16
|
+
return new Set([
|
|
17
|
+
...Object.keys(manifest.dependencies ?? {}),
|
|
18
|
+
...Object.keys(manifest.devDependencies ?? {}),
|
|
19
|
+
]);
|
|
20
|
+
}
|
|
21
|
+
function hasAny(names, candidates) {
|
|
22
|
+
return candidates.find((name) => names.has(name));
|
|
23
|
+
}
|
|
24
|
+
export async function detectLynxFramework(root) {
|
|
25
|
+
const manifest = await readManifest(root);
|
|
26
|
+
const names = dependencyNames(manifest);
|
|
27
|
+
const scripts = Object.values(manifest.scripts ?? {}).join(" ");
|
|
28
|
+
const configFiles = [
|
|
29
|
+
"lynx.config.ts",
|
|
30
|
+
"lynx.config.js",
|
|
31
|
+
"lynx.config.mjs",
|
|
32
|
+
"lynx.config.cjs",
|
|
33
|
+
"octane.config.ts",
|
|
34
|
+
"octane.config.js",
|
|
35
|
+
];
|
|
36
|
+
const config = (await Promise.all(configFiles
|
|
37
|
+
.filter((file) => existsSync(join(root, file)))
|
|
38
|
+
.map((file) => readText(join(root, file))))).join("\n");
|
|
39
|
+
const flake = await readText(join(root, "flake.nix"));
|
|
40
|
+
const cabal = await readText(join(root, "cabal.project"));
|
|
41
|
+
const hasCabalFile = existsSync(join(root, "cabal.project"));
|
|
42
|
+
const hasMiso = hasAny(names, ["miso", "miso-lynx"]) ||
|
|
43
|
+
(existsSync(join(root, "flake.nix")) &&
|
|
44
|
+
/miso|mkLynxBundle|Miso\\.Native|lynx/i.test(flake + "\n" + cabal)) ||
|
|
45
|
+
(hasCabalFile && /miso|lynx/i.test(cabal));
|
|
46
|
+
if (hasMiso) {
|
|
47
|
+
return {
|
|
48
|
+
framework: "miso",
|
|
49
|
+
label: "Miso (Haskell)",
|
|
50
|
+
evidence: "Miso.Native/Haskell project detected",
|
|
51
|
+
buildSystem: "miso-nix",
|
|
52
|
+
experimental: true,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
const hasOctane = hasAny(names, ["octane", "@octanejs/lynx", "@octanejs/rspeedy-plugin"]) ||
|
|
56
|
+
existsSync(join(root, "octane.config.ts")) ||
|
|
57
|
+
existsSync(join(root, "octane.config.js")) ||
|
|
58
|
+
/pluginOctane|@jsxImportSource\\s+octane|\\.tsrx\\b/.test(config + scripts);
|
|
59
|
+
if (hasOctane) {
|
|
60
|
+
return {
|
|
61
|
+
framework: "octane",
|
|
62
|
+
label: "Octane",
|
|
63
|
+
evidence: "Octane compiler/Rspeedy integration detected",
|
|
64
|
+
buildSystem: "rspeedy",
|
|
65
|
+
experimental: true,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
const vueDependency = hasAny(names, ["vue-lynx", "@lynx-js/vue"]);
|
|
69
|
+
if (vueDependency || /pluginVueLynx|vue-lynx/i.test(config)) {
|
|
70
|
+
return {
|
|
71
|
+
framework: "vue",
|
|
72
|
+
label: "Vue Lynx",
|
|
73
|
+
evidence: "Vue Lynx integration detected",
|
|
74
|
+
buildSystem: "rspeedy",
|
|
75
|
+
experimental: false,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
if (hasAny(names, ["@lynx-js/react", "@lynx-js/react-rsbuild-plugin"])) {
|
|
79
|
+
return {
|
|
80
|
+
framework: "react",
|
|
81
|
+
label: "ReactLynx",
|
|
82
|
+
evidence: "official ReactLynx package detected",
|
|
83
|
+
buildSystem: "rspeedy",
|
|
84
|
+
experimental: false,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
if (names.has("@lynx-js/rspeedy") ||
|
|
88
|
+
/rspeedy|environments\\s*:/i.test(config + scripts)) {
|
|
89
|
+
return {
|
|
90
|
+
framework: "vanilla",
|
|
91
|
+
label: "Vanilla Lynx",
|
|
92
|
+
evidence: "Rspeedy/Lynx project detected",
|
|
93
|
+
buildSystem: "rspeedy",
|
|
94
|
+
experimental: false,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
framework: "unknown",
|
|
99
|
+
label: "Unknown",
|
|
100
|
+
evidence: "No supported Lynx framework marker found",
|
|
101
|
+
buildSystem: "unknown",
|
|
102
|
+
experimental: false,
|
|
103
|
+
};
|
|
104
|
+
}
|
package/dist/guidance.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guidance.d.ts","sourceRoot":"","sources":["../src/guidance.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;CAChC;
|
|
1
|
+
{"version":3,"file":"guidance.d.ts","sourceRoot":"","sources":["../src/guidance.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;CAChC;AAmoBD,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,eAAoB,GAC5B,WAAW,CAEb"}
|
package/dist/guidance.js
CHANGED
|
@@ -105,6 +105,28 @@ const guidance = {
|
|
|
105
105
|
],
|
|
106
106
|
note: "Configure environments.web in lynx.config.* or provide the project's build:web script.",
|
|
107
107
|
},
|
|
108
|
+
BUILD_MISO_NIX_REQUIRED: {
|
|
109
|
+
commands: [
|
|
110
|
+
"lynxship doctor --platform android",
|
|
111
|
+
"nix --version",
|
|
112
|
+
"lynxship build --platform android --profile production",
|
|
113
|
+
],
|
|
114
|
+
note: "Install Nix and use the project's flake to build the Miso Lynx bundle.",
|
|
115
|
+
},
|
|
116
|
+
BUILD_MISO_ATTRIBUTE_REQUIRED: {
|
|
117
|
+
commands: [
|
|
118
|
+
"lynxship init",
|
|
119
|
+
"lynxship build --platform android --profile production",
|
|
120
|
+
],
|
|
121
|
+
note: "Expose a default/mkLynxBundle output or set build.production.miso.attribute to the Nix flake output that creates main.lynx.bundle.",
|
|
122
|
+
},
|
|
123
|
+
BUILD_MISO_BUNDLE_MISSING: {
|
|
124
|
+
commands: [
|
|
125
|
+
"nix build",
|
|
126
|
+
"lynxship build --platform android --profile production",
|
|
127
|
+
],
|
|
128
|
+
note: "Check build.production.miso.artifact and the output produced by the Miso flake.",
|
|
129
|
+
},
|
|
108
130
|
WEB_BUNDLE_MISSING: {
|
|
109
131
|
commands: [
|
|
110
132
|
"lynxship doctor --platform web",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harmony-build.d.ts","sourceRoot":"","sources":["../src/harmony-build.ts"],"names":[],"mappings":"AAIA,OAAO,EAAU,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAKhD,UAAU,mBAAmB;IAC3B,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;AAeD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOpD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG;IAC9C,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,EAAE,OAAO,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAcA;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,MAAM,EAAE,CAAC,CA4BnB;AA2GD,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,QAAQ,EACb,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"harmony-build.d.ts","sourceRoot":"","sources":["../src/harmony-build.ts"],"names":[],"mappings":"AAIA,OAAO,EAAU,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAKhD,UAAU,mBAAmB;IAC3B,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;AAeD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOpD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG;IAC9C,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,EAAE,OAAO,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAcA;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,MAAM,EAAE,CAAC,CA4BnB;AA2GD,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,QAAQ,EACb,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,QAAQ,CAAC,CAqGnB"}
|
package/dist/harmony-build.js
CHANGED
|
@@ -141,6 +141,7 @@ export async function runRealHarmonyBuild(job, options) {
|
|
|
141
141
|
await buildLynxBundle(options.root, {
|
|
142
142
|
quiet: options.quiet,
|
|
143
143
|
onOutput: options.onEvent,
|
|
144
|
+
miso: options.profile.miso,
|
|
144
145
|
});
|
|
145
146
|
}
|
|
146
147
|
step("Syncing bundle into the HarmonyOS HAP resources…", 20);
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { access, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
|
3
3
|
import { existsSync } from "node:fs";
|
|
4
4
|
import { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
5
5
|
import { basename, dirname, join, resolve } from "node:path";
|
|
6
|
+
import { detectLynxFramework } from "./frameworks.js";
|
|
6
7
|
import { BuildOrchestrator } from "@lynxship/build-orchestrator";
|
|
7
8
|
import { JsonRepository } from "@lynxship/db";
|
|
8
9
|
import { assert, createId, sha256, } from "@lynxship/contracts";
|
|
@@ -364,13 +365,14 @@ async function executeBuild(options, showResult = true) {
|
|
|
364
365
|
}
|
|
365
366
|
return result;
|
|
366
367
|
}
|
|
367
|
-
async function buildSharedLynxBundle() {
|
|
368
|
+
async function buildSharedLynxBundle(miso) {
|
|
368
369
|
const progress = ui.progress("Shared Lynx bundle");
|
|
369
370
|
try {
|
|
370
371
|
progress.update(undefined, "Building the shared Lynx bundle once for native targets…");
|
|
371
372
|
await buildLynxBundle(root, {
|
|
372
373
|
quiet: json,
|
|
373
374
|
onOutput: (message) => progress.event(message),
|
|
375
|
+
miso,
|
|
374
376
|
});
|
|
375
377
|
progress.update(100, "Shared native Lynx bundle ready");
|
|
376
378
|
}
|
|
@@ -515,6 +517,9 @@ Global options:
|
|
|
515
517
|
Node support: Node 22/24 LTS or Node 26 Current. Use Node 24 LTS for production.`;
|
|
516
518
|
}
|
|
517
519
|
async function looksLikeLynxProject() {
|
|
520
|
+
const framework = await detectLynxFramework(root);
|
|
521
|
+
if (framework.framework !== "unknown")
|
|
522
|
+
return true;
|
|
518
523
|
const configFiles = [
|
|
519
524
|
"lynx.config.ts",
|
|
520
525
|
"lynx.config.js",
|
|
@@ -644,13 +649,13 @@ async function runRspeedyCommand(subcommand, environment) {
|
|
|
644
649
|
let devUrl;
|
|
645
650
|
let devQrPrinted = false;
|
|
646
651
|
let devQrTimer;
|
|
647
|
-
const printDevQr = () => {
|
|
652
|
+
const printDevQr = async () => {
|
|
648
653
|
if (!devUrl || devQrPrinted || json || ui.options.quiet)
|
|
649
654
|
return;
|
|
650
655
|
devQrPrinted = true;
|
|
651
656
|
if (devQrTimer)
|
|
652
657
|
clearTimeout(devQrTimer);
|
|
653
|
-
ui.devServerQr(devUrl);
|
|
658
|
+
await ui.devServerQr(devUrl);
|
|
654
659
|
};
|
|
655
660
|
await runRspeedy(root, subcommand, forwarded, {
|
|
656
661
|
env: environment,
|
|
@@ -664,10 +669,12 @@ async function runRspeedyCommand(subcommand, environment) {
|
|
|
664
669
|
devUrl = url;
|
|
665
670
|
if (devQrTimer)
|
|
666
671
|
clearTimeout(devQrTimer);
|
|
667
|
-
devQrTimer = setTimeout(
|
|
672
|
+
devQrTimer = setTimeout(() => {
|
|
673
|
+
void printDevQr();
|
|
674
|
+
}, 500);
|
|
668
675
|
}
|
|
669
676
|
if (devUrl && shouldPrintDevServerQr(line))
|
|
670
|
-
printDevQr();
|
|
677
|
+
void printDevQr();
|
|
671
678
|
},
|
|
672
679
|
});
|
|
673
680
|
printValue({ status: "success", command: `rspeedy ${subcommand}` }, {
|
|
@@ -938,7 +945,37 @@ async function main() {
|
|
|
938
945
|
const nodeMajor = Number(process.versions.node.split(".")[0]);
|
|
939
946
|
const nodeSupported = nodeMajor >= 22;
|
|
940
947
|
const nodeRecommended = nodeMajor % 2 === 0;
|
|
948
|
+
const framework = await detectLynxFramework(root);
|
|
941
949
|
const checks = [
|
|
950
|
+
{
|
|
951
|
+
name: "lynx-framework",
|
|
952
|
+
ok: framework.framework !== "unknown",
|
|
953
|
+
status: framework.framework === "unknown"
|
|
954
|
+
? "warn"
|
|
955
|
+
: framework.experimental
|
|
956
|
+
? "warn"
|
|
957
|
+
: "pass",
|
|
958
|
+
value: framework.framework === "unknown"
|
|
959
|
+
? "unknown · verify the official Lynx/Rspeedy integration"
|
|
960
|
+
: framework.label +
|
|
961
|
+
" · " +
|
|
962
|
+
framework.evidence +
|
|
963
|
+
(framework.experimental ? " · early access" : ""),
|
|
964
|
+
},
|
|
965
|
+
...(framework.framework === "miso"
|
|
966
|
+
? [
|
|
967
|
+
{
|
|
968
|
+
name: "miso-nix",
|
|
969
|
+
ok: commandExists("nix"),
|
|
970
|
+
status: commandExists("nix")
|
|
971
|
+
? "pass"
|
|
972
|
+
: "fail",
|
|
973
|
+
value: commandExists("nix")
|
|
974
|
+
? "Nix detected"
|
|
975
|
+
: "missing · fix: install Nix and rerun doctor",
|
|
976
|
+
},
|
|
977
|
+
]
|
|
978
|
+
: []),
|
|
942
979
|
{
|
|
943
980
|
name: "node",
|
|
944
981
|
ok: nodeSupported,
|
|
@@ -1717,7 +1754,7 @@ async function main() {
|
|
|
1717
1754
|
return;
|
|
1718
1755
|
}
|
|
1719
1756
|
if (buildAll && wait && !local)
|
|
1720
|
-
await buildSharedLynxBundle();
|
|
1757
|
+
await buildSharedLynxBundle(resolveProfile(config, profile).miso);
|
|
1721
1758
|
const progress = ui.progress("All Lynx targets build");
|
|
1722
1759
|
const progressValues = {};
|
|
1723
1760
|
const progressLabels = {};
|
package/dist/ios-build.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ios-build.d.ts","sourceRoot":"","sources":["../src/ios-build.ts"],"names":[],"mappings":"AAYA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAMhD,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,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;AAyHD;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,EAAE,CAAC,CAoBnB;AAoED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,EACnB,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAO,GACxC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAuD7B;AAgCD,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IACP,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC,GACL,OAAO,CAAC,IAAI,CAAC,CAcf;
|
|
1
|
+
{"version":3,"file":"ios-build.d.ts","sourceRoot":"","sources":["../src/ios-build.ts"],"names":[],"mappings":"AAYA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAMhD,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,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;AAyHD;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,EAAE,CAAC,CAoBnB;AAoED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,EACnB,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAO,GACxC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAuD7B;AAgCD,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IACP,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC,GACL,OAAO,CAAC,IAAI,CAAC,CAcf;AAmND,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAcxE;AA+DD,wBAAsB,eAAe,CACnC,GAAG,EAAE,QAAQ,EACb,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,QAAQ,CAAC,CAsNnB"}
|
package/dist/ios-build.js
CHANGED
|
@@ -264,6 +264,7 @@ async function runRealIosSimulatorBuild(job, options) {
|
|
|
264
264
|
await buildLynxBundle(options.root, {
|
|
265
265
|
quiet: options.quiet,
|
|
266
266
|
onOutput: options.onEvent,
|
|
267
|
+
miso: options.profile.miso,
|
|
267
268
|
});
|
|
268
269
|
}
|
|
269
270
|
if (ios.bundleScript) {
|
|
@@ -454,6 +455,7 @@ export async function runRealIosBuild(job, options) {
|
|
|
454
455
|
await buildLynxBundle(options.root, {
|
|
455
456
|
quiet: options.quiet,
|
|
456
457
|
onOutput: options.onEvent,
|
|
458
|
+
miso: options.profile.miso,
|
|
457
459
|
});
|
|
458
460
|
}
|
|
459
461
|
if (ios.bundleScript) {
|
package/dist/ui/components.d.ts
CHANGED
|
@@ -35,5 +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, environment?: 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
|
+
export declare function devServerQr(url: string, enabled?: boolean): Promise<void>;
|
|
39
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;AAK7C,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,CACvB,QAAQ,EAAE,MAAM,EAAE,EAClB,IAAI,CAAC,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,MAAM,GACnB,IAAI,CAQN;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,UAAO,GACb,IAAI,CAQN;AAED,
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../src/ui/components.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAK7C,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,CACvB,QAAQ,EAAE,MAAM,EAAE,EAClB,IAAI,CAAC,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,MAAM,GACnB,IAAI,CAQN;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,SAAS,CAAC,EAAE,MAAM,EAClB,OAAO,UAAO,GACb,IAAI,CAQN;AAED,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,UAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB5E"}
|
package/dist/ui/components.js
CHANGED
|
@@ -289,15 +289,25 @@ export function downloadArtifact(url, expiresAt, enabled = true) {
|
|
|
289
289
|
if (expiresAt)
|
|
290
290
|
console.log(` ${c.muted(`Link expires at ${expiresAt}`)}`);
|
|
291
291
|
}
|
|
292
|
-
export function devServerQr(url, enabled = true) {
|
|
292
|
+
export async function devServerQr(url, enabled = true) {
|
|
293
293
|
if (!enabled)
|
|
294
294
|
return;
|
|
295
|
-
|
|
295
|
+
const rail = c.teal("│");
|
|
296
|
+
const printRail = (value = "") => console.log(` ${rail}${value}`);
|
|
297
|
+
printRail();
|
|
298
|
+
printRail(` ${c.brandBold("Lynx Explorer")}`);
|
|
296
299
|
if (colorsEnabled && supportsUnicode()) {
|
|
297
|
-
|
|
300
|
+
(await renderTerminalQr(url))
|
|
301
|
+
.split("\n")
|
|
302
|
+
.forEach((line) => printRail(` ${line}`));
|
|
298
303
|
}
|
|
299
304
|
else {
|
|
300
|
-
qrcode.generate(url, { small: true }, (code) =>
|
|
305
|
+
qrcode.generate(url, { small: true }, (code) => {
|
|
306
|
+
code.split("\n").forEach((line) => printRail(` ${line}`));
|
|
307
|
+
});
|
|
301
308
|
}
|
|
302
|
-
|
|
309
|
+
printRail();
|
|
310
|
+
printRail(` ${c.teal("URL")} ${url}`);
|
|
311
|
+
printRail();
|
|
312
|
+
console.log();
|
|
303
313
|
}
|
package/dist/ui/index.d.ts
CHANGED
|
@@ -19,7 +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
|
+
devServerQr(url: string): Promise<void>;
|
|
23
23
|
}
|
|
24
24
|
export declare function createCliUi(args: string[]): CliUi;
|
|
25
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,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;
|
|
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;IAIjD,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAS9C;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
|
@@ -66,11 +66,11 @@ export class CliUi {
|
|
|
66
66
|
downloadArtifact(url, expiresAt) {
|
|
67
67
|
downloadArtifact(url, expiresAt, this.interactive);
|
|
68
68
|
}
|
|
69
|
-
devServerQr(url) {
|
|
69
|
+
async devServerQr(url) {
|
|
70
70
|
// Rspeedy suppresses its own QR when its stdout is piped. LynxShip
|
|
71
71
|
// captures that output, so render the fallback unless the caller asked
|
|
72
72
|
// for machine JSON, quiet output, or an explicitly non-interactive run.
|
|
73
|
-
devServerQr(url, !this.options.json && !this.options.quiet && !this.options.nonInteractive);
|
|
73
|
+
await devServerQr(url, !this.options.json && !this.options.quiet && !this.options.nonInteractive);
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
export function createCliUi(args) {
|
package/dist/ui/qr.d.ts
CHANGED
|
@@ -53,11 +53,9 @@ export declare const LYNXSHIP_QR_STYLE: {
|
|
|
53
53
|
};
|
|
54
54
|
};
|
|
55
55
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* display. The terminal adapter therefore uses its public QR matrix engine
|
|
60
|
-
* and applies the exact shared ECC, gradient, rotation and quiet-zone values.
|
|
56
|
+
* Generate the QR with qr-code-styling itself, exactly like the WISA renderer.
|
|
57
|
+
* The SVG is then rasterized only to make the library's real rounded shapes
|
|
58
|
+
* displayable in a normal terminal; no QR modules are recreated by LynxShip.
|
|
61
59
|
*/
|
|
62
|
-
export declare function renderTerminalQr(data: string
|
|
60
|
+
export declare function renderTerminalQr(data: string): Promise<string>;
|
|
63
61
|
//# sourceMappingURL=qr.d.ts.map
|
package/dist/ui/qr.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qr.d.ts","sourceRoot":"","sources":["../../src/ui/qr.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"qr.d.ts","sourceRoot":"","sources":["../../src/ui/qr.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwCpB,CAAC;AAyLX;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBpE"}
|
package/dist/ui/qr.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import qrcodeGenerator from "qrcode-generator";
|
|
2
1
|
import { LYNX_BRAND } from "./colors.js";
|
|
2
|
+
import { terminalWidth } from "./terminal.js";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
3
4
|
export const LYNXSHIP_QR_STYLE = {
|
|
4
5
|
type: "svg",
|
|
5
6
|
width: 300,
|
|
@@ -41,84 +42,139 @@ export const LYNXSHIP_QR_STYLE = {
|
|
|
41
42
|
},
|
|
42
43
|
backgroundOptions: { color: "#FFFFFF" },
|
|
43
44
|
};
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
45
|
+
async function loadDependencies() {
|
|
46
|
+
const require = createRequire(import.meta.url);
|
|
47
|
+
const qrModule = require("qr-code-styling");
|
|
48
|
+
const jsdomModule = require("jsdom");
|
|
49
|
+
const resvgModule = require("@resvg/resvg-js");
|
|
50
|
+
const pngModule = require("pngjs");
|
|
51
|
+
return {
|
|
52
|
+
QRCodeStyling: "default" in qrModule && qrModule.default
|
|
53
|
+
? qrModule.default
|
|
54
|
+
: qrModule,
|
|
55
|
+
JSDOM: jsdomModule.JSDOM,
|
|
56
|
+
Resvg: resvgModule.Resvg,
|
|
57
|
+
PNG: pngModule.PNG,
|
|
58
|
+
};
|
|
54
59
|
}
|
|
55
|
-
function
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
const minimum = Math.min(0, Math.cos(angle), Math.sin(angle));
|
|
61
|
-
const maximum = Math.max(0, Math.cos(angle), Math.sin(angle));
|
|
62
|
-
const ratio = Math.max(0, Math.min(1, (projection - minimum) / (maximum - minimum)));
|
|
63
|
-
const start = hexToRgb(LYNXSHIP_QR_STYLE.dotsOptions.gradient.colorStops[0].color);
|
|
64
|
-
const end = hexToRgb(LYNXSHIP_QR_STYLE.dotsOptions.gradient.colorStops[1].color);
|
|
60
|
+
function ansiColor(channel, red, green, blue) {
|
|
61
|
+
return "\u001b[" + channel + ";2;" + red + ";" + green + ";" + blue + "m";
|
|
62
|
+
}
|
|
63
|
+
function pixelAt(image, x, y) {
|
|
64
|
+
const offset = (y * image.width + x) * 4;
|
|
65
65
|
return [
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
image.data[offset] ?? 255,
|
|
67
|
+
image.data[offset + 1] ?? 255,
|
|
68
|
+
image.data[offset + 2] ?? 255,
|
|
69
|
+
image.data[offset + 3] ?? 255,
|
|
69
70
|
];
|
|
70
71
|
}
|
|
71
|
-
function
|
|
72
|
-
return
|
|
72
|
+
function isBackground([red, green, blue, alpha]) {
|
|
73
|
+
return alpha < 16 || (red > 248 && green > 248 && blue > 248);
|
|
73
74
|
}
|
|
74
|
-
function
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
75
|
+
function cropToQrContent(image) {
|
|
76
|
+
let left = image.width;
|
|
77
|
+
let top = image.height;
|
|
78
|
+
let right = -1;
|
|
79
|
+
let bottom = -1;
|
|
80
|
+
for (let y = 0; y < image.height; y += 1) {
|
|
81
|
+
for (let x = 0; x < image.width; x += 1) {
|
|
82
|
+
if (!isBackground(pixelAt(image, x, y))) {
|
|
83
|
+
left = Math.min(left, x);
|
|
84
|
+
top = Math.min(top, y);
|
|
85
|
+
right = Math.max(right, x);
|
|
86
|
+
bottom = Math.max(bottom, y);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (right < left || bottom < top)
|
|
91
|
+
return image;
|
|
92
|
+
const padding = Math.max(3, Math.round(Math.min(image.width, image.height) * 0.02));
|
|
93
|
+
const cropLeft = Math.max(0, left - padding);
|
|
94
|
+
const cropTop = Math.max(0, top - padding);
|
|
95
|
+
const cropRight = Math.min(image.width - 1, right + padding);
|
|
96
|
+
const cropBottom = Math.min(image.height - 1, bottom + padding);
|
|
97
|
+
const width = cropRight - cropLeft + 1;
|
|
98
|
+
const height = cropBottom - cropTop + 1;
|
|
99
|
+
const data = new Uint8Array(width * height * 4);
|
|
100
|
+
for (let y = 0; y < height; y += 1) {
|
|
101
|
+
for (let x = 0; x < width; x += 1) {
|
|
102
|
+
const source = ((cropTop + y) * image.width + cropLeft + x) * 4;
|
|
103
|
+
const target = (y * width + x) * 4;
|
|
104
|
+
data[target] = image.data[source] ?? 255;
|
|
105
|
+
data[target + 1] = image.data[source + 1] ?? 255;
|
|
106
|
+
data[target + 2] = image.data[source + 2] ?? 255;
|
|
107
|
+
data[target + 3] = image.data[source + 3] ?? 255;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return { width, height, data };
|
|
81
111
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
* display. The terminal adapter therefore uses its public QR matrix engine
|
|
87
|
-
* and applies the exact shared ECC, gradient, rotation and quiet-zone values.
|
|
88
|
-
*/
|
|
89
|
-
export function renderTerminalQr(data, colored) {
|
|
90
|
-
const matrix = qrcodeGenerator(0, "H");
|
|
91
|
-
matrix.addData(data, "Byte");
|
|
92
|
-
matrix.make();
|
|
93
|
-
const size = matrix.getModuleCount();
|
|
94
|
-
const fullSize = size + QUIET_ZONE * 2;
|
|
112
|
+
function renderRasterInTerminal(image) {
|
|
113
|
+
const columns = Math.max(35, Math.min(72, terminalWidth() - 8));
|
|
114
|
+
const scale = image.width / columns;
|
|
115
|
+
const rows = Math.ceil(image.height / scale / 2);
|
|
95
116
|
const lines = [];
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
117
|
+
const whiteBackground = ansiColor("48", 255, 255, 255);
|
|
118
|
+
const reset = "\u001b[0m";
|
|
119
|
+
for (let row = 0; row < rows; row += 1) {
|
|
120
|
+
const topY = Math.min(image.height - 1, Math.floor(row * 2 * scale));
|
|
121
|
+
const bottomY = Math.min(image.height - 1, Math.floor((row * 2 + 1) * scale));
|
|
122
|
+
let line = whiteBackground;
|
|
123
|
+
for (let column = 0; column < columns; column += 1) {
|
|
124
|
+
const x = Math.min(image.width - 1, Math.floor(column * scale));
|
|
125
|
+
const top = pixelAt(image, x, topY);
|
|
126
|
+
const bottom = pixelAt(image, x, bottomY);
|
|
127
|
+
const topBackground = isBackground(top);
|
|
128
|
+
const bottomBackground = isBackground(bottom);
|
|
129
|
+
if (topBackground && bottomBackground) {
|
|
102
130
|
line += " ";
|
|
103
|
-
continue;
|
|
104
|
-
}
|
|
105
|
-
if (!colored) {
|
|
106
|
-
line += top && bottom ? "█" : top ? "▀" : "▄";
|
|
107
|
-
continue;
|
|
108
131
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
132
|
+
else if (!topBackground && bottomBackground) {
|
|
133
|
+
line +=
|
|
134
|
+
ansiColor("38", top[0], top[1], top[2]) +
|
|
135
|
+
ansiColor("48", 255, 255, 255) +
|
|
136
|
+
"▀";
|
|
113
137
|
}
|
|
114
|
-
else if (
|
|
115
|
-
line +=
|
|
138
|
+
else if (topBackground && !bottomBackground) {
|
|
139
|
+
line +=
|
|
140
|
+
ansiColor("38", bottom[0], bottom[1], bottom[2]) +
|
|
141
|
+
ansiColor("48", 255, 255, 255) +
|
|
142
|
+
"▄";
|
|
116
143
|
}
|
|
117
144
|
else {
|
|
118
|
-
line +=
|
|
145
|
+
line +=
|
|
146
|
+
ansiColor("38", top[0], top[1], top[2]) +
|
|
147
|
+
ansiColor("48", bottom[0], bottom[1], bottom[2]) +
|
|
148
|
+
"▀";
|
|
119
149
|
}
|
|
120
150
|
}
|
|
121
|
-
lines.push(
|
|
151
|
+
lines.push(line + reset);
|
|
122
152
|
}
|
|
123
153
|
return lines.join("\n");
|
|
124
154
|
}
|
|
155
|
+
/**
|
|
156
|
+
* Generate the QR with qr-code-styling itself, exactly like the WISA renderer.
|
|
157
|
+
* The SVG is then rasterized only to make the library's real rounded shapes
|
|
158
|
+
* displayable in a normal terminal; no QR modules are recreated by LynxShip.
|
|
159
|
+
*/
|
|
160
|
+
export async function renderTerminalQr(data) {
|
|
161
|
+
const { QRCodeStyling, JSDOM, Resvg, PNG } = await loadDependencies();
|
|
162
|
+
const qrCode = new QRCodeStyling({
|
|
163
|
+
jsdom: JSDOM,
|
|
164
|
+
data,
|
|
165
|
+
...LYNXSHIP_QR_STYLE,
|
|
166
|
+
});
|
|
167
|
+
const svg = await qrCode.getRawData("svg");
|
|
168
|
+
if (!svg)
|
|
169
|
+
throw new Error("qr-code-styling returned no SVG data");
|
|
170
|
+
const svgText = Buffer.isBuffer(svg)
|
|
171
|
+
? svg.toString("utf8")
|
|
172
|
+
: new TextDecoder().decode(svg);
|
|
173
|
+
// jsdom serializes SVG references as url('#id'). Normalize only those
|
|
174
|
+
// references for resvg; the SVG generated by qr-code-styling is unchanged
|
|
175
|
+
// for browsers and for the file returned by the library.
|
|
176
|
+
const rasterSvg = svgText.replaceAll("url('#", "url(#").replaceAll("')", ")");
|
|
177
|
+
const png = new Resvg(rasterSvg).render().asPng();
|
|
178
|
+
const image = cropToQrContent(PNG.sync.read(Buffer.from(png)));
|
|
179
|
+
return renderRasterInTerminal(image);
|
|
180
|
+
}
|
package/dist/web-build.d.ts.map
CHANGED
|
@@ -1 +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,
|
|
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,CAuDnB"}
|
package/dist/web-build.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lynxship/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.16",
|
|
4
4
|
"description": "Build, sign, store, submit and update LynxJS applications from the terminal.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -54,6 +54,10 @@
|
|
|
54
54
|
"types": "./dist/autolink.d.ts",
|
|
55
55
|
"import": "./dist/autolink.js"
|
|
56
56
|
},
|
|
57
|
+
"./frameworks": {
|
|
58
|
+
"types": "./dist/frameworks.d.ts",
|
|
59
|
+
"import": "./dist/frameworks.js"
|
|
60
|
+
},
|
|
57
61
|
"./ui/*": {
|
|
58
62
|
"types": "./dist/ui/*.d.ts",
|
|
59
63
|
"import": "./dist/ui/*.js"
|
|
@@ -67,17 +71,20 @@
|
|
|
67
71
|
"chalk": "5.4.1",
|
|
68
72
|
"cli-progress": "3.12.0",
|
|
69
73
|
"ora": "8.2.0",
|
|
70
|
-
"qrcode-generator": "1.4.4",
|
|
71
74
|
"qrcode-terminal": "0.12.0",
|
|
72
75
|
"qr-code-styling": "1.9.2",
|
|
76
|
+
"@resvg/resvg-js": "2.6.2",
|
|
77
|
+
"jsdom": "29.1.1",
|
|
78
|
+
"pngjs": "7.0.0",
|
|
73
79
|
"@lynxship/contracts": "0.1.0",
|
|
74
80
|
"@lynxship/build-orchestrator": "0.1.0",
|
|
75
|
-
"@lynxship/db": "0.1.0",
|
|
76
81
|
"@lynxship/submit": "0.1.0",
|
|
77
|
-
"@lynxship/signing": "0.1.0"
|
|
82
|
+
"@lynxship/signing": "0.1.0",
|
|
83
|
+
"@lynxship/db": "0.1.0"
|
|
78
84
|
},
|
|
79
85
|
"devDependencies": {
|
|
80
86
|
"@types/cli-progress": "3.11.6",
|
|
87
|
+
"@types/pngjs": "6.0.4",
|
|
81
88
|
"@types/qrcode-terminal": "0.12.2"
|
|
82
89
|
},
|
|
83
90
|
"scripts": {
|