@blutui/courier 1.1.0
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 +93 -0
- package/bin/courier +0 -0
- package/package.json +19 -0
- package/scripts/postinstall.js +144 -0
package/README.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
<p align="left">
|
|
2
|
+
<a href="https://blutui.com">
|
|
3
|
+
<img src="https://cdn.blutui.com/assets/favicon/android-chrome-192x192.png" height="42" width="42" alt="Blutui">
|
|
4
|
+
</a>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
`blutui/courier` The command line tool for Blutui.
|
|
8
|
+
|
|
9
|
+
[](https://codecov.io/gh/blutui/courier)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Commands
|
|
14
|
+
|
|
15
|
+
### `config`
|
|
16
|
+
|
|
17
|
+
Manually change the config values.
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
courier config
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### `dev`
|
|
24
|
+
|
|
25
|
+
Starts a web server for local development.
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
courier dev
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### `help`
|
|
32
|
+
|
|
33
|
+
Help about any command.
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
courier help
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### `init`
|
|
40
|
+
|
|
41
|
+
Create a basic `courier.json` file in the current directory.
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
courier init
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### `login`
|
|
48
|
+
|
|
49
|
+
Login into Blutui to access projects associated to your account.
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
courier login
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### `open`
|
|
56
|
+
|
|
57
|
+
Open the current site in your preferred browser.
|
|
58
|
+
|
|
59
|
+
```sh
|
|
60
|
+
courier open
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### `pull`
|
|
64
|
+
|
|
65
|
+
Retrieve the project files from Blutui.
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
courier pull
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### `push`
|
|
72
|
+
|
|
73
|
+
Upload the project files to Blutui.
|
|
74
|
+
|
|
75
|
+
```sh
|
|
76
|
+
courier push
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### `version`
|
|
80
|
+
|
|
81
|
+
Get the version of Blutui Courier.
|
|
82
|
+
|
|
83
|
+
```sh
|
|
84
|
+
courier watch
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Developing Blutui Courier
|
|
88
|
+
|
|
89
|
+
If you're working on developing the CLI, its recommended that you alias the go command to run the dev version.
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
alias courier-dev='go run cmd/courier/main.go'
|
|
93
|
+
```
|
package/bin/courier
ADDED
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@blutui/courier",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"files": [
|
|
6
|
+
"scripts"
|
|
7
|
+
],
|
|
8
|
+
"bin": {
|
|
9
|
+
"courier": "bin/courier"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"postinstall": "node scripts/postinstall.js"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"decompress": "^4.2.1",
|
|
16
|
+
"https-proxy-agent": "^7.0.6",
|
|
17
|
+
"node-fetch": "^3.3.2"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
import fs from "fs";
|
|
6
|
+
import os from "os";
|
|
7
|
+
import path from "path";
|
|
8
|
+
import fetch from "node-fetch";
|
|
9
|
+
import { Agent } from "https";
|
|
10
|
+
import { HttpsProxyAgent } from "https-proxy-agent";
|
|
11
|
+
import { pipeline } from "stream/promises";
|
|
12
|
+
import { createHash } from "crypto";
|
|
13
|
+
import decompress from "decompress";
|
|
14
|
+
|
|
15
|
+
const ARCH_MAPPING = {
|
|
16
|
+
x64: "x86_64", // amd64
|
|
17
|
+
arm64: "arm64",
|
|
18
|
+
ia32: "i386", // 386
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const PLATFORM_MAPPING = {
|
|
22
|
+
darwin: "mac-os",
|
|
23
|
+
linux: "linux",
|
|
24
|
+
win32: "windows",
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const arch = ARCH_MAPPING[process.arch];
|
|
28
|
+
const platform = PLATFORM_MAPPING[process.platform];
|
|
29
|
+
const isWindows = platform === "windows";
|
|
30
|
+
|
|
31
|
+
if (!arch || !platform) {
|
|
32
|
+
console.error(
|
|
33
|
+
`Unsupported platform or architecture: ${process.platform} ${process.arch}`
|
|
34
|
+
);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const readPackageJson = async () => {
|
|
39
|
+
const contents = await fs.promises.readFile("package.json");
|
|
40
|
+
return JSON.parse(contents);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const getArchiveExt = () => (isWindows ? "zip" : "tar.gz");
|
|
44
|
+
|
|
45
|
+
const getArchiveFilename = (name, version) =>
|
|
46
|
+
`${name}_${version}_${platform}_${arch}.${getArchiveExt()}`;
|
|
47
|
+
|
|
48
|
+
const getDownloadUrl = (name, version) =>
|
|
49
|
+
`https://cdn.blutui.com/${name}/v${version}/${getArchiveFilename(
|
|
50
|
+
name,
|
|
51
|
+
version
|
|
52
|
+
)}`;
|
|
53
|
+
|
|
54
|
+
const getChecksumUrl = (name, version) =>
|
|
55
|
+
`https://cdn.blutui.com/${name}/v${version}/${name}_${version}_checksums.txt`;
|
|
56
|
+
|
|
57
|
+
const fetchChecksums = async (url, agent) => {
|
|
58
|
+
const res = await fetch(url, { agent });
|
|
59
|
+
if (!res.ok)
|
|
60
|
+
throw new Error(`Failed to fetch checksum file: ${res.statusText}`);
|
|
61
|
+
const lines = await res.text();
|
|
62
|
+
|
|
63
|
+
const checksums = {};
|
|
64
|
+
for (const line of lines.split("\n")) {
|
|
65
|
+
const [checksum, filename] = line.trim().split(/\s+/);
|
|
66
|
+
if (checksum && filename) checksums[filename] = checksum;
|
|
67
|
+
}
|
|
68
|
+
return checksums;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const verifyChecksum = async (filePath, expectedHash) => {
|
|
72
|
+
const hash = createHash("sha256");
|
|
73
|
+
const input = fs.createReadStream(filePath);
|
|
74
|
+
await pipeline(input, hash);
|
|
75
|
+
const digest = hash.digest("hex");
|
|
76
|
+
|
|
77
|
+
if (digest !== expectedHash) {
|
|
78
|
+
throw new Error(
|
|
79
|
+
`Checksum mismatch!\nExpected: ${expectedHash}\nActual: ${digest}`
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const extractArchive = async (archivePath, destDir) => {
|
|
85
|
+
await decompress(archivePath, destDir);
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
async function main() {
|
|
89
|
+
const pkg = await readPackageJson();
|
|
90
|
+
const binName = "courier";
|
|
91
|
+
const version = pkg.version;
|
|
92
|
+
const archiveFile = getArchiveFilename(binName, version);
|
|
93
|
+
const downloadUrl = getDownloadUrl(binName, version);
|
|
94
|
+
const checksumUrl = getChecksumUrl(binName, version);
|
|
95
|
+
const archivePath = path.join(os.tmpdir(), archiveFile);
|
|
96
|
+
|
|
97
|
+
// Create the agent that will be used for all the fetch requests later.
|
|
98
|
+
const proxyUrl =
|
|
99
|
+
process.env.npm_config_https_proxy ||
|
|
100
|
+
process.env.npm_config_http_proxy ||
|
|
101
|
+
process.env.npm_config_proxy;
|
|
102
|
+
|
|
103
|
+
const agent = proxyUrl
|
|
104
|
+
? new HttpsProxyAgent(proxyUrl, { keepAlive: true })
|
|
105
|
+
: new Agent({ keepAlive: true });
|
|
106
|
+
|
|
107
|
+
console.info("Downloading:", downloadUrl);
|
|
108
|
+
|
|
109
|
+
const res = await fetch(downloadUrl, { agent });
|
|
110
|
+
if (!res.ok) throw new Error(`Failed to download binary: ${res.statusText}`);
|
|
111
|
+
|
|
112
|
+
const fileStream = fs.createWriteStream(archivePath);
|
|
113
|
+
await pipeline(res.body, fileStream);
|
|
114
|
+
|
|
115
|
+
const checksums = await fetchChecksums(checksumUrl, agent);
|
|
116
|
+
const expectedChecksum = checksums[archiveFile];
|
|
117
|
+
if (!expectedChecksum) {
|
|
118
|
+
throw new Error(`Checksum for ${archiveFile} not found`);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
await verifyChecksum(archivePath, expectedChecksum);
|
|
122
|
+
console.info("Checksum verified");
|
|
123
|
+
|
|
124
|
+
const binPath = pkg.bin[binName];
|
|
125
|
+
const binDir = path.dirname(binPath);
|
|
126
|
+
await fs.promises.mkdir(binDir, { recursive: true });
|
|
127
|
+
|
|
128
|
+
await extractArchive(archivePath, binDir);
|
|
129
|
+
|
|
130
|
+
if (isWindows) {
|
|
131
|
+
const original = path.join(binDir, binName);
|
|
132
|
+
const renamed = path.join(binDir, `${binName}.exe`);
|
|
133
|
+
if (fs.existsSync(original)) {
|
|
134
|
+
await fs.promises.rename(original, renamed);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
console.info("Installed Blutui Courier successfully");
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
main().catch((err) => {
|
|
142
|
+
console.error("Install failed:", err);
|
|
143
|
+
process.exit(1);
|
|
144
|
+
});
|