@keywaysh/cli 0.1.16 → 0.3.1

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.
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env node
2
+
3
+ const https = require("https");
4
+ const fs = require("fs");
5
+ const path = require("path");
6
+ const { execSync } = require("child_process");
7
+ const zlib = require("zlib");
8
+
9
+ const REPO = "keywaysh/cli";
10
+ const BIN_DIR = path.join(__dirname, "..", "bin");
11
+ const BINARY_NAME = process.platform === "win32" ? "keyway.exe" : "keyway";
12
+
13
+ // Platform mapping
14
+ const PLATFORM_MAP = {
15
+ darwin: "darwin",
16
+ linux: "linux",
17
+ win32: "windows",
18
+ };
19
+
20
+ // Architecture mapping
21
+ const ARCH_MAP = {
22
+ x64: "amd64",
23
+ arm64: "arm64",
24
+ };
25
+
26
+ function getPlatform() {
27
+ const platform = PLATFORM_MAP[process.platform];
28
+ if (!platform) {
29
+ throw new Error(`Unsupported platform: ${process.platform}`);
30
+ }
31
+ return platform;
32
+ }
33
+
34
+ function getArch() {
35
+ const arch = ARCH_MAP[process.arch];
36
+ if (!arch) {
37
+ throw new Error(`Unsupported architecture: ${process.arch}`);
38
+ }
39
+ return arch;
40
+ }
41
+
42
+ function getVersion() {
43
+ const pkg = require("../package.json");
44
+ return pkg.version;
45
+ }
46
+
47
+ function httpsGet(url) {
48
+ return new Promise((resolve, reject) => {
49
+ https
50
+ .get(url, { headers: { "User-Agent": "keyway-npm-installer" } }, (res) => {
51
+ if (res.statusCode === 301 || res.statusCode === 302) {
52
+ return httpsGet(res.headers.location).then(resolve).catch(reject);
53
+ }
54
+ if (res.statusCode !== 200) {
55
+ reject(new Error(`HTTP ${res.statusCode}: ${url}`));
56
+ return;
57
+ }
58
+ const chunks = [];
59
+ res.on("data", (chunk) => chunks.push(chunk));
60
+ res.on("end", () => resolve(Buffer.concat(chunks)));
61
+ res.on("error", reject);
62
+ })
63
+ .on("error", reject);
64
+ });
65
+ }
66
+
67
+ async function downloadAndExtract(url, destPath) {
68
+ console.log(`Downloading ${url}`);
69
+ const data = await httpsGet(url);
70
+
71
+ // Create bin directory if it doesn't exist
72
+ if (!fs.existsSync(BIN_DIR)) {
73
+ fs.mkdirSync(BIN_DIR, { recursive: true });
74
+ }
75
+
76
+ if (url.endsWith(".tar.gz")) {
77
+ // Extract tar.gz
78
+ const tmpDir = path.join(__dirname, "..", "tmp");
79
+ if (!fs.existsSync(tmpDir)) {
80
+ fs.mkdirSync(tmpDir, { recursive: true });
81
+ }
82
+
83
+ const tarPath = path.join(tmpDir, "keyway.tar.gz");
84
+ fs.writeFileSync(tarPath, data);
85
+
86
+ // Use tar command to extract
87
+ execSync(`tar -xzf "${tarPath}" -C "${tmpDir}"`, { stdio: "pipe" });
88
+
89
+ // Find and move binary
90
+ const extractedBinary = path.join(tmpDir, "keyway");
91
+ if (fs.existsSync(extractedBinary)) {
92
+ fs.copyFileSync(extractedBinary, destPath);
93
+ fs.chmodSync(destPath, 0o755);
94
+ }
95
+
96
+ // Cleanup
97
+ fs.rmSync(tmpDir, { recursive: true, force: true });
98
+ } else if (url.endsWith(".zip")) {
99
+ // For Windows, use PowerShell to extract
100
+ const tmpDir = path.join(__dirname, "..", "tmp");
101
+ if (!fs.existsSync(tmpDir)) {
102
+ fs.mkdirSync(tmpDir, { recursive: true });
103
+ }
104
+
105
+ const zipPath = path.join(tmpDir, "keyway.zip");
106
+ fs.writeFileSync(zipPath, data);
107
+
108
+ execSync(
109
+ `powershell -command "Expand-Archive -Path '${zipPath}' -DestinationPath '${tmpDir}' -Force"`,
110
+ { stdio: "pipe" }
111
+ );
112
+
113
+ const extractedBinary = path.join(tmpDir, "keyway.exe");
114
+ if (fs.existsSync(extractedBinary)) {
115
+ fs.copyFileSync(extractedBinary, destPath);
116
+ }
117
+
118
+ // Cleanup
119
+ fs.rmSync(tmpDir, { recursive: true, force: true });
120
+ }
121
+ }
122
+
123
+ async function main() {
124
+ try {
125
+ const platform = getPlatform();
126
+ const arch = getArch();
127
+ const version = getVersion();
128
+
129
+ // Skip download for version 0.0.0 (development)
130
+ if (version === "0.0.0") {
131
+ console.log("Development version detected, skipping binary download");
132
+ // Create a placeholder script
133
+ const placeholder = `#!/bin/sh
134
+ echo "Keyway CLI not installed. Run 'make build' in the cli-go directory."
135
+ exit 1
136
+ `;
137
+ fs.writeFileSync(path.join(BIN_DIR, "keyway"), placeholder);
138
+ fs.chmodSync(path.join(BIN_DIR, "keyway"), 0o755);
139
+ return;
140
+ }
141
+
142
+ const ext = platform === "windows" ? "zip" : "tar.gz";
143
+ const filename = `keyway_${version}_${platform}_${arch}.${ext}`;
144
+ const url = `https://github.com/${REPO}/releases/download/v${version}/${filename}`;
145
+
146
+ const destPath = path.join(BIN_DIR, BINARY_NAME);
147
+ await downloadAndExtract(url, destPath);
148
+
149
+ console.log(`Keyway CLI v${version} installed successfully!`);
150
+ } catch (error) {
151
+ console.error("Failed to install Keyway CLI:", error.message);
152
+ console.error("You can install manually from: https://github.com/keywaysh/cli/releases");
153
+ process.exit(1);
154
+ }
155
+ }
156
+
157
+ main();
@@ -1,12 +0,0 @@
1
- import {
2
- clearAuth,
3
- getAuthFilePath,
4
- getStoredAuth,
5
- saveAuthToken
6
- } from "./chunk-F4C46224.js";
7
- export {
8
- clearAuth,
9
- getAuthFilePath,
10
- getStoredAuth,
11
- saveAuthToken
12
- };
@@ -1,102 +0,0 @@
1
- // src/utils/auth.ts
2
- import Conf from "conf";
3
- import { createCipheriv, createDecipheriv, randomBytes } from "crypto";
4
- import { existsSync, readFileSync, writeFileSync, mkdirSync, chmodSync } from "fs";
5
- import { join } from "path";
6
- import { homedir } from "os";
7
- var store = new Conf({
8
- projectName: "keyway",
9
- configName: "config",
10
- fileMode: 384
11
- });
12
- var KEY_DIR = join(homedir(), ".keyway");
13
- var KEY_FILE = join(KEY_DIR, ".key");
14
- function getOrCreateEncryptionKey() {
15
- if (!existsSync(KEY_DIR)) {
16
- mkdirSync(KEY_DIR, { recursive: true, mode: 448 });
17
- }
18
- if (existsSync(KEY_FILE)) {
19
- const keyHex2 = readFileSync(KEY_FILE, "utf-8").trim();
20
- if (keyHex2.length === 64) {
21
- return Buffer.from(keyHex2, "hex");
22
- }
23
- }
24
- const key = randomBytes(32);
25
- const keyHex = key.toString("hex");
26
- writeFileSync(KEY_FILE, keyHex, { mode: 384 });
27
- try {
28
- chmodSync(KEY_FILE, 384);
29
- } catch {
30
- }
31
- return key;
32
- }
33
- function encryptToken(token) {
34
- const key = getOrCreateEncryptionKey();
35
- const iv = randomBytes(16);
36
- const cipher = createCipheriv("aes-256-gcm", key, iv);
37
- const encrypted = Buffer.concat([cipher.update(token, "utf8"), cipher.final()]);
38
- const authTag = cipher.getAuthTag();
39
- return `${iv.toString("hex")}:${authTag.toString("hex")}:${encrypted.toString("hex")}`;
40
- }
41
- function decryptToken(encryptedData) {
42
- const key = getOrCreateEncryptionKey();
43
- const parts = encryptedData.split(":");
44
- if (parts.length !== 3) {
45
- throw new Error("Invalid encrypted token format");
46
- }
47
- const iv = Buffer.from(parts[0], "hex");
48
- const authTag = Buffer.from(parts[1], "hex");
49
- const encrypted = Buffer.from(parts[2], "hex");
50
- const decipher = createDecipheriv("aes-256-gcm", key, iv);
51
- decipher.setAuthTag(authTag);
52
- const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
53
- return decrypted.toString("utf8");
54
- }
55
- function isExpired(auth) {
56
- if (!auth.expiresAt) return false;
57
- const expires = Date.parse(auth.expiresAt);
58
- if (Number.isNaN(expires)) return false;
59
- return expires <= Date.now();
60
- }
61
- async function getStoredAuth() {
62
- const encryptedData = store.get("auth");
63
- if (!encryptedData) {
64
- return null;
65
- }
66
- try {
67
- const decrypted = decryptToken(encryptedData);
68
- const auth = JSON.parse(decrypted);
69
- if (isExpired(auth)) {
70
- clearAuth();
71
- return null;
72
- }
73
- return auth;
74
- } catch {
75
- console.error("Failed to decrypt stored auth, clearing...");
76
- clearAuth();
77
- return null;
78
- }
79
- }
80
- async function saveAuthToken(token, meta) {
81
- const auth = {
82
- keywayToken: token,
83
- githubLogin: meta?.githubLogin,
84
- expiresAt: meta?.expiresAt,
85
- createdAt: (/* @__PURE__ */ new Date()).toISOString()
86
- };
87
- const encrypted = encryptToken(JSON.stringify(auth));
88
- store.set("auth", encrypted);
89
- }
90
- function clearAuth() {
91
- store.delete("auth");
92
- }
93
- function getAuthFilePath() {
94
- return store.path;
95
- }
96
-
97
- export {
98
- getStoredAuth,
99
- saveAuthToken,
100
- clearAuth,
101
- getAuthFilePath
102
- };