three-blocks-login 0.0.4 → 0.1.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.
- package/bin/login.js +36 -20
- package/package.json +12 -4
package/bin/login.js
CHANGED
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
import fs from "node:fs";
|
|
6
6
|
import os from "node:os";
|
|
7
7
|
import path from "node:path";
|
|
8
|
+
import { createRequire } from "node:module";
|
|
9
|
+
|
|
10
|
+
const require = createRequire(import.meta.url);
|
|
11
|
+
const pkg = require("../package.json");
|
|
8
12
|
|
|
9
13
|
// Simple ANSI color helpers (no deps)
|
|
10
14
|
const ESC = (n) => `\u001b[${n}m`;
|
|
@@ -15,7 +19,7 @@ const red = (s) => ESC(31) + s + reset;
|
|
|
15
19
|
const green = (s) => ESC(32) + s + reset;
|
|
16
20
|
const yellow = (s) => ESC(33) + s + reset;
|
|
17
21
|
const cyan = (s) => ESC(36) + s + reset;
|
|
18
|
-
const plainBanner =
|
|
22
|
+
const plainBanner = `[three-blocks-login@${pkg.version}]`;
|
|
19
23
|
const banner = bold(cyan(plainBanner));
|
|
20
24
|
|
|
21
25
|
const args = parseArgs(process.argv.slice(2));
|
|
@@ -25,6 +29,8 @@ const SCOPE = (args.scope || "@three-blocks").replace(/^\s+|\s+$/g, "");
|
|
|
25
29
|
const MODE = (args.mode || "env").toLowerCase(); // env | project | user
|
|
26
30
|
const QUIET = !!args.quiet;
|
|
27
31
|
const VERBOSE = !!args.verbose;
|
|
32
|
+
let CHANNEL = String(args.channel || process.env.THREE_BLOCKS_CHANNEL || "stable").toLowerCase();
|
|
33
|
+
if (!['stable','alpha','beta'].includes(CHANNEL)) CHANNEL = 'stable';
|
|
28
34
|
|
|
29
35
|
// Load .env from current working directory (no deps)
|
|
30
36
|
loadEnvFromDotfile(process.cwd());
|
|
@@ -35,7 +41,7 @@ const BROKER_URL =
|
|
|
35
41
|
"http://localhost:3000/api/npm/token"; // your Astro broker endpoint
|
|
36
42
|
|
|
37
43
|
const LICENSE =
|
|
38
|
-
args.license || process.env.THREE_BLOCKS_SECRET_KEY
|
|
44
|
+
args.license || process.env.THREE_BLOCKS_SECRET_KEY;
|
|
39
45
|
|
|
40
46
|
if (!LICENSE || String(LICENSE).trim() === "") {
|
|
41
47
|
fail(
|
|
@@ -71,7 +77,7 @@ const log = {
|
|
|
71
77
|
|
|
72
78
|
(async () => {
|
|
73
79
|
try {
|
|
74
|
-
const tokenData = await fetchToken(BROKER_URL, LICENSE_CLEAN);
|
|
80
|
+
const tokenData = await fetchToken(BROKER_URL, LICENSE_CLEAN, CHANNEL);
|
|
75
81
|
const { registry, token, expiresAt } = tokenData;
|
|
76
82
|
|
|
77
83
|
if (!registry || !token) fail("Broker response missing registry/token.");
|
|
@@ -98,6 +104,7 @@ const log = {
|
|
|
98
104
|
`# scope: ${SCOPE} | registry: ${u.href} | expires: ${expiresAt ?? "unknown"}`,
|
|
99
105
|
`export NPM_CONFIG_USERCONFIG="${tmpFile}"`,
|
|
100
106
|
`export npm_config_userconfig="${tmpFile}"`,
|
|
107
|
+
`export THREE_BLOCKS_CHANNEL="${CHANNEL}"`,
|
|
101
108
|
`echo "${plainBanner} ${SCOPE} -> ${u.href} (expires ${expiresAt ?? "unknown"})"`
|
|
102
109
|
];
|
|
103
110
|
console.log(lines.join("\n"));
|
|
@@ -135,7 +142,7 @@ const log = {
|
|
|
135
142
|
if (/ByteString/i.test(msg) || /character at index/i.test(msg)) {
|
|
136
143
|
return fail("License appears malformed. Please copy your tb_… key exactly and retry.");
|
|
137
144
|
}
|
|
138
|
-
return fail("
|
|
145
|
+
return fail("Authentication failed. Please try again. Use --verbose for details.");
|
|
139
146
|
}
|
|
140
147
|
})();
|
|
141
148
|
|
|
@@ -149,30 +156,39 @@ function ensureTrailingSlash(url) {
|
|
|
149
156
|
|
|
150
157
|
function loadEnvFromDotfile(dir) {
|
|
151
158
|
try {
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
val
|
|
159
|
+
const files = [path.join(dir, ".env.local"), path.join(dir, ".env")];
|
|
160
|
+
for (const file of files) {
|
|
161
|
+
if (!fs.existsSync(file)) continue;
|
|
162
|
+
const txt = fs.readFileSync(file, "utf8");
|
|
163
|
+
for (const raw of txt.split(/\r?\n/)) {
|
|
164
|
+
const line = raw.trim();
|
|
165
|
+
if (!line || line.startsWith("#")) continue;
|
|
166
|
+
const eq = line.indexOf("=");
|
|
167
|
+
if (eq === -1) continue;
|
|
168
|
+
const key = line.slice(0, eq).trim();
|
|
169
|
+
let val = line.slice(eq + 1).trim();
|
|
170
|
+
if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"))) {
|
|
171
|
+
val = val.slice(1, -1);
|
|
172
|
+
}
|
|
173
|
+
if (process.env[key] === undefined) process.env[key] = val;
|
|
164
174
|
}
|
|
165
|
-
if (process.env[key] === undefined) process.env[key] = val;
|
|
166
175
|
}
|
|
167
176
|
} catch {}
|
|
168
177
|
}
|
|
169
178
|
|
|
170
|
-
async function fetchToken(endpoint, license) {
|
|
171
|
-
|
|
179
|
+
async function fetchToken(endpoint, license, channel) {
|
|
180
|
+
let url = endpoint;
|
|
181
|
+
try {
|
|
182
|
+
const u = new URL(endpoint);
|
|
183
|
+
if (!u.searchParams.get('channel')) u.searchParams.set('channel', channel);
|
|
184
|
+
url = u.toString();
|
|
185
|
+
} catch {}
|
|
186
|
+
const res = await fetch(url, {
|
|
172
187
|
method: "GET",
|
|
173
188
|
headers: {
|
|
174
189
|
"authorization": `Bearer ${license}`,
|
|
175
|
-
"accept": "application/json"
|
|
190
|
+
"accept": "application/json",
|
|
191
|
+
"x-three-blocks-channel": channel
|
|
176
192
|
}
|
|
177
193
|
});
|
|
178
194
|
if (!res.ok) {
|
package/package.json
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "three-blocks-login",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Fetch a short-lived token from the three-blocks broker and configure npm for the current context.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"three-blocks-login": "bin/login.js"
|
|
8
8
|
},
|
|
9
9
|
"license": "MIT",
|
|
10
|
-
"files": [
|
|
11
|
-
|
|
10
|
+
"files": [
|
|
11
|
+
"bin/"
|
|
12
|
+
],
|
|
13
|
+
"keywords": [
|
|
14
|
+
"npm",
|
|
15
|
+
"login",
|
|
16
|
+
"three-blocks",
|
|
17
|
+
"token",
|
|
18
|
+
"ci"
|
|
19
|
+
],
|
|
12
20
|
"dependencies": {},
|
|
13
21
|
"publishConfig": {
|
|
14
22
|
"access": "public"
|
|
15
23
|
}
|
|
16
|
-
}
|
|
24
|
+
}
|