@spfn/cli 0.0.2 → 0.0.4
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/lib/login.js +115 -67
- package/package.json +1 -1
package/lib/login.js
CHANGED
@@ -3,93 +3,134 @@ 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
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
) {
|
18
|
-
const src = path.join(process.cwd(), "templates", templateName);
|
19
|
-
if (!fs.existsSync(src)) {
|
20
|
-
throw new Error(`Template not found: ${src}`);
|
10
|
+
function installGitCredentials(username, token) {
|
11
|
+
// 1) credential helper 설정
|
12
|
+
if (process.platform === "win32") {
|
13
|
+
// Git Credential Manager (Windows)
|
14
|
+
execSync("git config --global credential.helper manager-core");
|
15
|
+
} else {
|
16
|
+
// 단순 파일 저장소
|
17
|
+
execSync("git config --global credential.helper store");
|
21
18
|
}
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
19
|
+
|
20
|
+
// 2) 승인 명령어로 크리덴셜 저장
|
21
|
+
// git credential approve 는 stdin으로 프로토콜/호스트/유저/패스워드를 받습니다.
|
22
|
+
const cred = [
|
23
|
+
"protocol=https",
|
24
|
+
"host=git.superfunctions.ai",
|
25
|
+
`username=${username}`,
|
26
|
+
`password=${token}`,
|
27
|
+
"" // 빈 줄로 끝내야 인풋 종료
|
28
|
+
].join("\n");
|
29
|
+
|
30
|
+
execSync("git credential approve", {
|
31
|
+
input: cred,
|
32
|
+
stdio: ["pipe", "ignore", "inherit"]
|
33
|
+
});
|
34
|
+
|
35
|
+
console.log("✔️ Git credentials stored via credential helper");
|
36
|
+
}
|
37
|
+
|
38
|
+
function mergeGradleInit()
|
39
|
+
{
|
40
|
+
const dir = path.join(os.homedir(), ".gradle");
|
41
|
+
const file = path.join(dir, "init.gradle");
|
42
|
+
const startMarker = "// sf-cli start";
|
43
|
+
const endMarker = "// sf-cli end";
|
44
|
+
|
45
|
+
let content = "";
|
46
|
+
if (fs.existsSync(file))
|
47
|
+
{
|
48
|
+
content = fs.readFileSync(file, "utf-8");
|
49
|
+
const regex = new RegExp(
|
50
|
+
`${startMarker}[\\s\\S]*?${endMarker}\n?`,
|
51
|
+
"m"
|
52
|
+
);
|
53
|
+
content = content.replace(regex, "");
|
54
|
+
}
|
55
|
+
|
56
|
+
const block = [
|
57
|
+
startMarker,
|
58
|
+
"allprojects {",
|
59
|
+
" repositories {",
|
60
|
+
" maven {",
|
61
|
+
" name = 'Gitea'",
|
62
|
+
" url = uri('https://git.superfunctions.ai/api/packages/sf/maven')",
|
63
|
+
" credentials {",
|
64
|
+
" username = System.getenv('SF_USERNAME')",
|
65
|
+
" password = System.getenv('SF_AUTH_TOKEN')'",
|
66
|
+
" }",
|
67
|
+
" }",
|
68
|
+
" mavenCentral()",
|
69
|
+
" }",
|
70
|
+
"}",
|
71
|
+
endMarker,
|
72
|
+
""
|
73
|
+
].join("\n");
|
74
|
+
|
75
|
+
fs.mkdirSync(dir, { recursive: true });
|
76
|
+
fs.writeFileSync(file, content + "\n" + block, "utf-8");
|
77
|
+
console.log(`✔️ Merged Gradle init script: ${file}`);
|
30
78
|
}
|
31
79
|
|
32
|
-
export function login()
|
33
|
-
|
34
|
-
|
35
|
-
|
80
|
+
export function login()
|
81
|
+
{
|
82
|
+
try
|
83
|
+
{
|
84
|
+
const server = http.createServer((req, res) =>
|
85
|
+
{
|
36
86
|
res.setHeader("Access-Control-Allow-Origin", "*");
|
37
87
|
res.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
|
38
88
|
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
39
89
|
|
40
|
-
if (req.method === "OPTIONS")
|
90
|
+
if (req.method === "OPTIONS")
|
91
|
+
{
|
41
92
|
res.writeHead(200);
|
42
93
|
res.end();
|
43
94
|
return;
|
44
95
|
}
|
45
96
|
|
46
|
-
if (req.url === "/callback" && req.method === "POST")
|
97
|
+
if (req.url === "/callback" && req.method === "POST")
|
98
|
+
{
|
47
99
|
let body = "";
|
48
100
|
req.on("data", (chunk) => (body += chunk));
|
49
|
-
req.on("end", () =>
|
50
|
-
|
101
|
+
req.on("end", () =>
|
102
|
+
{
|
103
|
+
try
|
104
|
+
{
|
51
105
|
const { username, token, projectSlug } = JSON.parse(body);
|
52
|
-
if (!username || !token)
|
106
|
+
if (!username || !token)
|
107
|
+
{
|
53
108
|
res.writeHead(400).end("Missing username or token");
|
54
109
|
return;
|
55
110
|
}
|
56
111
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
applyTemplate("npm.tmpl", npmDest, {
|
72
|
-
SF_AUTH_TOKEN: token,
|
73
|
-
});
|
74
|
-
if (process.platform !== "win32") {
|
75
|
-
try {
|
76
|
-
fs.chmodSync(npmDest, 0o600);
|
77
|
-
} catch {}
|
112
|
+
mergeGradleInit();
|
113
|
+
try
|
114
|
+
{
|
115
|
+
execSync(
|
116
|
+
`npm config set @sf:registry https://git.superfunctions.ai/api/packages/sf/npm/`,
|
117
|
+
{ stdio: "inherit", env: process.env }
|
118
|
+
);
|
119
|
+
execSync(
|
120
|
+
`npm config set //git.superfunctions.ai/api/packages/sf/npm/:_authToken "${token}"`,
|
121
|
+
{ stdio: "inherit", env: process.env }
|
122
|
+
);
|
123
|
+
console.log(
|
124
|
+
"✔️ npm registry and authToken set via npm config"
|
125
|
+
);
|
78
126
|
}
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
process.platform === "win32" ? "_netrc" : ".netrc";
|
83
|
-
const netrcDest = path.join(os.homedir(), netrcName);
|
84
|
-
applyTemplate("netrc.tmpl", netrcDest, {
|
85
|
-
SF_USERNAME: username,
|
86
|
-
SF_AUTH_TOKEN: token,
|
87
|
-
});
|
88
|
-
if (process.platform !== "win32") {
|
89
|
-
fs.chmodSync(netrcDest, 0o600);
|
127
|
+
catch (e)
|
128
|
+
{
|
129
|
+
console.error("❌ npm config set failed:", e);
|
90
130
|
}
|
91
131
|
|
92
|
-
|
132
|
+
installGitCredentials(username, token);
|
133
|
+
|
93
134
|
res.writeHead(200, { "Content-Type": "text/plain" });
|
94
135
|
res.end("✅ Login successful! You can now close this window.");
|
95
136
|
|
@@ -104,22 +145,29 @@ export function login() {
|
|
104
145
|
console.log();
|
105
146
|
|
106
147
|
server.close();
|
107
|
-
}
|
148
|
+
}
|
149
|
+
catch (err)
|
150
|
+
{
|
108
151
|
console.error(err);
|
109
152
|
res.writeHead(500).end("Error during login callback");
|
110
153
|
server.close();
|
111
154
|
}
|
112
155
|
});
|
113
|
-
}
|
156
|
+
}
|
157
|
+
else
|
158
|
+
{
|
114
159
|
res.writeHead(404).end("Not Found");
|
115
160
|
}
|
116
161
|
});
|
117
162
|
|
118
|
-
server.listen(PORT, () =>
|
163
|
+
server.listen(PORT, () =>
|
164
|
+
{
|
119
165
|
console.log("🌐 Opening browser for login...");
|
120
166
|
open(`https://console.superfunctions.ai/cli-login?port=${PORT}`);
|
121
167
|
});
|
122
|
-
}
|
168
|
+
}
|
169
|
+
catch (err)
|
170
|
+
{
|
123
171
|
console.error(err);
|
124
172
|
}
|
125
|
-
}
|
173
|
+
}
|