three-blocks-login 0.1.0 → 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.
Files changed (2) hide show
  1. package/bin/login.js +30 -18
  2. package/package.json +12 -4
package/bin/login.js CHANGED
@@ -29,6 +29,8 @@ const SCOPE = (args.scope || "@three-blocks").replace(/^\s+|\s+$/g, "");
29
29
  const MODE = (args.mode || "env").toLowerCase(); // env | project | user
30
30
  const QUIET = !!args.quiet;
31
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';
32
34
 
33
35
  // Load .env from current working directory (no deps)
34
36
  loadEnvFromDotfile(process.cwd());
@@ -39,7 +41,7 @@ const BROKER_URL =
39
41
  "http://localhost:3000/api/npm/token"; // your Astro broker endpoint
40
42
 
41
43
  const LICENSE =
42
- args.license || process.env.THREE_BLOCKS_SECRET_KEY || process.env.THREE_BLOCKS_LICENSE_KEY;
44
+ args.license || process.env.THREE_BLOCKS_SECRET_KEY;
43
45
 
44
46
  if (!LICENSE || String(LICENSE).trim() === "") {
45
47
  fail(
@@ -75,7 +77,7 @@ const log = {
75
77
 
76
78
  (async () => {
77
79
  try {
78
- const tokenData = await fetchToken(BROKER_URL, LICENSE_CLEAN);
80
+ const tokenData = await fetchToken(BROKER_URL, LICENSE_CLEAN, CHANNEL);
79
81
  const { registry, token, expiresAt } = tokenData;
80
82
 
81
83
  if (!registry || !token) fail("Broker response missing registry/token.");
@@ -102,6 +104,7 @@ const log = {
102
104
  `# scope: ${SCOPE} | registry: ${u.href} | expires: ${expiresAt ?? "unknown"}`,
103
105
  `export NPM_CONFIG_USERCONFIG="${tmpFile}"`,
104
106
  `export npm_config_userconfig="${tmpFile}"`,
107
+ `export THREE_BLOCKS_CHANNEL="${CHANNEL}"`,
105
108
  `echo "${plainBanner} ${SCOPE} -> ${u.href} (expires ${expiresAt ?? "unknown"})"`
106
109
  ];
107
110
  console.log(lines.join("\n"));
@@ -153,30 +156,39 @@ function ensureTrailingSlash(url) {
153
156
 
154
157
  function loadEnvFromDotfile(dir) {
155
158
  try {
156
- const file = path.join(dir, ".env");
157
- if (!fs.existsSync(file)) return;
158
- const txt = fs.readFileSync(file, "utf8");
159
- for (const raw of txt.split(/\r?\n/)) {
160
- const line = raw.trim();
161
- if (!line || line.startsWith("#")) continue;
162
- const eq = line.indexOf("=");
163
- if (eq === -1) continue;
164
- const key = line.slice(0, eq).trim();
165
- let val = line.slice(eq + 1).trim();
166
- if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"))) {
167
- val = val.slice(1, -1);
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;
168
174
  }
169
- if (process.env[key] === undefined) process.env[key] = val;
170
175
  }
171
176
  } catch {}
172
177
  }
173
178
 
174
- async function fetchToken(endpoint, license) {
175
- const res = await fetch(endpoint, {
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, {
176
187
  method: "GET",
177
188
  headers: {
178
189
  "authorization": `Bearer ${license}`,
179
- "accept": "application/json"
190
+ "accept": "application/json",
191
+ "x-three-blocks-channel": channel
180
192
  }
181
193
  });
182
194
  if (!res.ok) {
package/package.json CHANGED
@@ -1,16 +1,24 @@
1
1
  {
2
2
  "name": "three-blocks-login",
3
- "version": "0.1.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": ["bin/"],
11
- "keywords": ["npm", "login", "three-blocks", "token", "ci"],
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
+ }