@spfn/cli 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/lib/login.js +150 -38
  2. package/package.json +2 -2
package/lib/login.js CHANGED
@@ -3,79 +3,191 @@ import open from "open";
3
3
  import fs from "fs";
4
4
  import os from "os";
5
5
  import path from "path";
6
+ import { execSync } from "child_process";
6
7
 
7
8
  const PORT = 5678;
8
9
 
9
- export function login() {
10
- try {
11
- const server = http.createServer((req, res) => {
12
- // CORS 헤더 공통 추가
10
+ function mergeNetrc(
11
+ username,
12
+ token
13
+ )
14
+ {
15
+ const name = process.platform === "win32" ? "_netrc" : ".netrc";
16
+ const file = path.join(os.homedir(), name);
17
+ let lines = [];
18
+
19
+ if (fs.existsSync(file))
20
+ {
21
+ lines = fs.readFileSync(file, "utf-8").split(/\r?\n/);
22
+ const filtered = [];
23
+ let skip = false;
24
+ for (const l of lines)
25
+ {
26
+ if (l.trim().startsWith("machine git.superfunctions.ai"))
27
+ {
28
+ skip = true;
29
+ }
30
+ if (!skip)
31
+ {
32
+ filtered.push(l);
33
+ }
34
+ if (skip && l.trim() === "")
35
+ {
36
+ skip = false;
37
+ }
38
+ }
39
+ lines = filtered;
40
+ }
41
+
42
+ lines.push(
43
+ "",
44
+ "machine git.superfunctions.ai",
45
+ ` login ${username}`,
46
+ ` password ${token}`,
47
+ ""
48
+ );
49
+
50
+ fs.writeFileSync(file, lines.join("\n"), "utf-8");
51
+ if (process.platform !== "win32")
52
+ {
53
+ fs.chmodSync(file, 0o600);
54
+ }
55
+ console.log(`✔️ Merged netrc: ${file}`);
56
+ }
57
+
58
+ function mergeGradleInit()
59
+ {
60
+ const dir = path.join(os.homedir(), ".gradle");
61
+ const file = path.join(dir, "init.gradle");
62
+ const startMarker = "// sf-cli start";
63
+ const endMarker = "// sf-cli end";
64
+
65
+ let content = "";
66
+ if (fs.existsSync(file))
67
+ {
68
+ content = fs.readFileSync(file, "utf-8");
69
+ const regex = new RegExp(
70
+ `${startMarker}[\\s\\S]*?${endMarker}\n?`,
71
+ "m"
72
+ );
73
+ content = content.replace(regex, "");
74
+ }
75
+
76
+ const block = [
77
+ startMarker,
78
+ "allprojects {",
79
+ " repositories {",
80
+ " maven {",
81
+ " name = 'Gitea'",
82
+ " url = uri('https://git.superfunctions.ai/api/packages/sf/maven')",
83
+ " credentials {",
84
+ " username = System.getenv('SF_USERNAME')",
85
+ " password = System.getenv('SF_AUTH_TOKEN')'",
86
+ " }",
87
+ " }",
88
+ " mavenCentral()",
89
+ " }",
90
+ "}",
91
+ endMarker,
92
+ ""
93
+ ].join("\n");
94
+
95
+ fs.mkdirSync(dir, { recursive: true });
96
+ fs.writeFileSync(file, content + "\n" + block, "utf-8");
97
+ console.log(`✔️ Merged Gradle init script: ${file}`);
98
+ }
99
+
100
+ export function login()
101
+ {
102
+ try
103
+ {
104
+ const server = http.createServer((req, res) =>
105
+ {
13
106
  res.setHeader("Access-Control-Allow-Origin", "*");
14
107
  res.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
15
108
  res.setHeader("Access-Control-Allow-Headers", "Content-Type");
16
109
 
17
- if (req.method === "OPTIONS") {
110
+ if (req.method === "OPTIONS")
111
+ {
18
112
  res.writeHead(200);
19
113
  res.end();
20
114
  return;
21
115
  }
22
116
 
23
- if (req.url === "/callback" && req.method === "POST") {
117
+ if (req.url === "/callback" && req.method === "POST")
118
+ {
24
119
  let body = "";
25
-
26
- req.on("data", chunk => {
27
- body += chunk;
28
- });
29
-
30
- req.on("end", () => {
31
- try {
120
+ req.on("data", (chunk) => (body += chunk));
121
+ req.on("end", () =>
122
+ {
123
+ try
124
+ {
32
125
  const { username, token, projectSlug } = JSON.parse(body);
33
-
34
- if (!token || !username) {
126
+ if (!username || !token)
127
+ {
35
128
  res.writeHead(400).end("Missing username or token");
36
129
  return;
37
130
  }
38
131
 
39
- const shell = process.env.SHELL?.includes("zsh") ? ".zshrc" : ".bashrc";
40
- const rcFile = path.join(os.homedir(), shell);
41
- const exportUsername = `export SF_USERNAME=${username}`;
42
- const exportToken = `export SF_AUTH_TOKEN=${token}`;
43
-
44
- let content = fs.readFileSync(rcFile, "utf-8");
45
- content = content
46
- .replace(/^# Added by sf-cli[\s\S]*?export SF_USERNAME=.*\n?/m, "")
47
- .replace(/^export SF_AUTH_TOKEN=.*\n?/m, "");
132
+ mergeGradleInit();
133
+ try
134
+ {
135
+ execSync(
136
+ `npm config set @sf:registry https://git.superfunctions.ai/api/packages/sf/npm/`,
137
+ { stdio: "inherit", env: process.env }
138
+ );
139
+ execSync(
140
+ `npm config set //git.superfunctions.ai/api/packages/sf/npm/:_authToken "${token}"`,
141
+ { stdio: "inherit", env: process.env }
142
+ );
143
+ console.log(
144
+ "✔️ npm registry and authToken set via npm config"
145
+ );
146
+ }
147
+ catch (e)
148
+ {
149
+ console.error("❌ npm config set failed:", e);
150
+ }
48
151
 
49
- content += `\n# Added by sf-cli\n${exportUsername}\n${exportToken}\n`;
50
- fs.writeFileSync(rcFile, content, "utf-8");
152
+ mergeNetrc(username, token);
51
153
 
52
154
  res.writeHead(200, { "Content-Type": "text/plain" });
53
155
  res.end("✅ Login successful! You can now close this window.");
54
156
 
55
- console.log("✔️ Login approved via browser.");
56
- console.log(`✔️ Credentials updated in ~/${shell}`);
57
- console.log(`👉 Run: source ~/${shell}`);
58
157
  console.log();
59
- console.log(`💡 Tip: Run \`git clone git.superfunctions.ai/${projectSlug}/${projectSlug}-server\` to start your server project.`);
60
- console.log(`💡 Tip: Run \`git clone git.superfunctions.ai/${projectSlug}/${projectSlug}-app\` to start your app project.`);
158
+ console.log("💡 Tips:");
159
+ console.log(
160
+ ` git clone git.superfunctions.ai/${projectSlug}/${projectSlug}-server`
161
+ );
162
+ console.log(
163
+ ` git clone git.superfunctions.ai/${projectSlug}/${projectSlug}-app`
164
+ );
165
+ console.log();
61
166
 
62
167
  server.close();
63
- } catch (err) {
64
- res.writeHead(500).end("Invalid request format");
168
+ }
169
+ catch (err)
170
+ {
65
171
  console.error(err);
172
+ res.writeHead(500).end("Error during login callback");
66
173
  server.close();
67
174
  }
68
175
  });
69
- } else {
176
+ }
177
+ else
178
+ {
70
179
  res.writeHead(404).end("Not Found");
71
180
  }
72
181
  });
73
182
 
74
- server.listen(PORT, () => {
183
+ server.listen(PORT, () =>
184
+ {
75
185
  console.log("🌐 Opening browser for login...");
76
- open(`http://localhost:3000/cli-login?port=${PORT}`);
186
+ open(`https://console.superfunctions.ai/cli-login?port=${PORT}`);
77
187
  });
78
- } catch (err) {
188
+ }
189
+ catch (err)
190
+ {
79
191
  console.error(err);
80
192
  }
81
- }
193
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spfn/cli",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "Superfunction CLI",
5
5
  "keywords": [
6
6
  "cli",
@@ -9,7 +9,7 @@
9
9
  "devtools",
10
10
  "automation"
11
11
  ],
12
- "homepage": "https://superfunctions.ai",
12
+ "homepage": "https://console.superfunctions.ai",
13
13
  "repository": {
14
14
  "type": "git",
15
15
  "url": "https://git.superfunctions.ai/sf/sf-cli.git"