@iamcoder18/huly-cli 0.1.0
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/README.md +2576 -0
- package/bin/huly +9 -0
- package/dist/auth/cache.js +129 -0
- package/dist/auth/cache.js.map +1 -0
- package/dist/auth/client.js +192 -0
- package/dist/auth/client.js.map +1 -0
- package/dist/auth/env.js +101 -0
- package/dist/auth/env.js.map +1 -0
- package/dist/auth/prompts.js +68 -0
- package/dist/auth/prompts.js.map +1 -0
- package/dist/cli.js +1959 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/dry-run.js +39 -0
- package/dist/commands/dry-run.js.map +1 -0
- package/dist/commands/login.js +92 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/whoami.js +64 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/index.js +59 -0
- package/dist/index.js.map +1 -0
- package/dist/output/errors.js +99 -0
- package/dist/output/errors.js.map +1 -0
- package/dist/output/format.js +607 -0
- package/dist/output/format.js.map +1 -0
- package/dist/output/progress.js +30 -0
- package/dist/output/progress.js.map +1 -0
- package/dist/raw/api.js +67 -0
- package/dist/raw/api.js.map +1 -0
- package/dist/raw/ws.js +157 -0
- package/dist/raw/ws.js.map +1 -0
- package/dist/resources/_helpers.js +258 -0
- package/dist/resources/_helpers.js.map +1 -0
- package/dist/resources/_project-resolve.js +24 -0
- package/dist/resources/_project-resolve.js.map +1 -0
- package/dist/resources/calendar.js +659 -0
- package/dist/resources/calendar.js.map +1 -0
- package/dist/resources/card.js +358 -0
- package/dist/resources/card.js.map +1 -0
- package/dist/resources/channel.js +709 -0
- package/dist/resources/channel.js.map +1 -0
- package/dist/resources/comment.js +142 -0
- package/dist/resources/comment.js.map +1 -0
- package/dist/resources/component.js +154 -0
- package/dist/resources/component.js.map +1 -0
- package/dist/resources/document.js +584 -0
- package/dist/resources/document.js.map +1 -0
- package/dist/resources/issue-template.js +228 -0
- package/dist/resources/issue-template.js.map +1 -0
- package/dist/resources/issue.js +909 -0
- package/dist/resources/issue.js.map +1 -0
- package/dist/resources/milestone.js +177 -0
- package/dist/resources/milestone.js.map +1 -0
- package/dist/resources/misc.js +2 -0
- package/dist/resources/misc.js.map +1 -0
- package/dist/resources/project.js +341 -0
- package/dist/resources/project.js.map +1 -0
- package/dist/resources/project.parse.js +25 -0
- package/dist/resources/project.parse.js.map +1 -0
- package/dist/resources/time.js +148 -0
- package/dist/resources/time.js.map +1 -0
- package/dist/resources/todo.js +463 -0
- package/dist/resources/todo.js.map +1 -0
- package/dist/resources/user.js +131 -0
- package/dist/resources/user.js.map +1 -0
- package/dist/resources/workspace.js +252 -0
- package/dist/resources/workspace.js.map +1 -0
- package/dist/transport/identifiers.js +67 -0
- package/dist/transport/identifiers.js.map +1 -0
- package/dist/transport/ref-resolver.js +108 -0
- package/dist/transport/ref-resolver.js.map +1 -0
- package/dist/transport/sdk.js +69 -0
- package/dist/transport/sdk.js.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +40 -0
package/bin/huly
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -e
|
|
3
|
+
SOURCE="${BASH_SOURCE[0]}"
|
|
4
|
+
while [ -L "$SOURCE" ]; do
|
|
5
|
+
DIR="$(cd -P "$(dirname "$SOURCE")" >/dev/null 2>&1 && pwd)"
|
|
6
|
+
SOURCE="$(readlink "$SOURCE")"
|
|
7
|
+
[[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE"
|
|
8
|
+
done
|
|
9
|
+
exec node "$(cd "$(dirname "$SOURCE")/.." && pwd)/dist/index.js" "$@"
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { promises as fs } from 'node:fs';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
import { activeAccountPath, activeWorkspacePath, configDir, credentialsPath } from './env.js';
|
|
4
|
+
/** Normalize a Huly host URL: lowercase hostname, strip trailing slash, drop default ports. */
|
|
5
|
+
export function normalizeHost(s) {
|
|
6
|
+
try {
|
|
7
|
+
const u = new URL(s);
|
|
8
|
+
const isDefault = (u.protocol === 'https:' && u.port === '443') || (u.protocol === 'http:' && u.port === '80');
|
|
9
|
+
const port = isDefault || u.port === '' ? '' : `:${u.port}`;
|
|
10
|
+
return `${u.protocol}//${u.hostname.toLowerCase()}${port}${u.pathname.replace(/\/$/, '')}`;
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return s.replace(/\/$/, '');
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export async function loadCredentials() {
|
|
17
|
+
try {
|
|
18
|
+
const raw = await fs.readFile(credentialsPath(), 'utf8');
|
|
19
|
+
return JSON.parse(raw);
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
if (err.code === 'ENOENT')
|
|
23
|
+
return {};
|
|
24
|
+
throw err;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export async function saveCredentials(creds) {
|
|
28
|
+
await fs.mkdir(configDir(), { recursive: true });
|
|
29
|
+
await fs.writeFile(credentialsPath(), JSON.stringify(creds, null, 2), { mode: 0o600 });
|
|
30
|
+
// mode is only applied on file creation; harden existing files too.
|
|
31
|
+
await fs.chmod(credentialsPath(), 0o600).catch(() => { });
|
|
32
|
+
}
|
|
33
|
+
export async function getCachedCreds(host, email) {
|
|
34
|
+
const all = await loadCredentials();
|
|
35
|
+
return all[normalizeHost(host)]?.[email];
|
|
36
|
+
}
|
|
37
|
+
export async function setCachedCreds(host, email, data) {
|
|
38
|
+
const all = await loadCredentials();
|
|
39
|
+
const key = normalizeHost(host);
|
|
40
|
+
all[key] = all[key] ?? {};
|
|
41
|
+
all[key][email] = data;
|
|
42
|
+
await saveCredentials(all);
|
|
43
|
+
}
|
|
44
|
+
export async function setCachedWorkspaceToken(host, email, workspaceKey, data) {
|
|
45
|
+
const all = await loadCredentials();
|
|
46
|
+
const key = normalizeHost(host);
|
|
47
|
+
if (!all[key]?.[email])
|
|
48
|
+
return;
|
|
49
|
+
all[key][email].workspaces[workspaceKey] = data;
|
|
50
|
+
await saveCredentials(all);
|
|
51
|
+
}
|
|
52
|
+
export async function getCachedWorkspaceToken(host, email, workspaceKey) {
|
|
53
|
+
const all = await loadCredentials();
|
|
54
|
+
return all[normalizeHost(host)]?.[email]?.workspaces[workspaceKey];
|
|
55
|
+
}
|
|
56
|
+
export async function readActiveWorkspace() {
|
|
57
|
+
try {
|
|
58
|
+
const raw = await fs.readFile(activeWorkspacePath(), 'utf8');
|
|
59
|
+
const trimmed = raw.trim();
|
|
60
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
if (err.code === 'ENOENT')
|
|
64
|
+
return undefined;
|
|
65
|
+
throw err;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export async function writeActiveWorkspace(name) {
|
|
69
|
+
await fs.mkdir(dirname(activeWorkspacePath()), { recursive: true });
|
|
70
|
+
await fs.writeFile(activeWorkspacePath(), name + '\n', { mode: 0o600 });
|
|
71
|
+
await fs.chmod(activeWorkspacePath(), 0o600).catch(() => { });
|
|
72
|
+
}
|
|
73
|
+
export async function readActiveAccount(host) {
|
|
74
|
+
try {
|
|
75
|
+
const raw = await fs.readFile(activeAccountPath(), 'utf8');
|
|
76
|
+
const lines = raw.split('\n').map((l) => l.trim()).filter(Boolean);
|
|
77
|
+
const key = normalizeHost(host);
|
|
78
|
+
const entry = lines.find((l) => l.startsWith(key + '|') || l.startsWith(host + '|'));
|
|
79
|
+
if (!entry)
|
|
80
|
+
return undefined;
|
|
81
|
+
const sepIdx = entry.indexOf('|');
|
|
82
|
+
return sepIdx >= 0 ? entry.slice(sepIdx + 1) : undefined;
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
if (err.code === 'ENOENT')
|
|
86
|
+
return undefined;
|
|
87
|
+
throw err;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
export async function writeActiveAccount(host, email) {
|
|
91
|
+
await fs.mkdir(dirname(activeAccountPath()), { recursive: true });
|
|
92
|
+
const key = normalizeHost(host);
|
|
93
|
+
let lines = [];
|
|
94
|
+
try {
|
|
95
|
+
const raw = await fs.readFile(activeAccountPath(), 'utf8');
|
|
96
|
+
lines = raw.split('\n').map((l) => l.trim()).filter(Boolean);
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
if (err.code !== 'ENOENT')
|
|
100
|
+
throw err;
|
|
101
|
+
}
|
|
102
|
+
const entry = `${key}|${email}`;
|
|
103
|
+
const filtered = lines.filter((l) => {
|
|
104
|
+
const sep = l.indexOf('|');
|
|
105
|
+
return sep <= 0 || normalizeHost(l.slice(0, sep)) !== key;
|
|
106
|
+
});
|
|
107
|
+
filtered.push(entry);
|
|
108
|
+
await fs.writeFile(activeAccountPath(), filtered.join('\n') + '\n', { mode: 0o600 });
|
|
109
|
+
await fs.chmod(activeAccountPath(), 0o600).catch(() => { });
|
|
110
|
+
}
|
|
111
|
+
export async function findAnyCachedCreds(host) {
|
|
112
|
+
const all = await loadCredentials();
|
|
113
|
+
const key = normalizeHost(host);
|
|
114
|
+
const hostCreds = all[key];
|
|
115
|
+
if (!hostCreds)
|
|
116
|
+
return undefined;
|
|
117
|
+
const active = await readActiveAccount(host);
|
|
118
|
+
const emails = Object.keys(hostCreds);
|
|
119
|
+
if (active && hostCreds[active])
|
|
120
|
+
return { email: active, data: hostCreds[active] };
|
|
121
|
+
if (emails.length === 0)
|
|
122
|
+
return undefined;
|
|
123
|
+
return { email: emails[0], data: hostCreds[emails[0]] };
|
|
124
|
+
}
|
|
125
|
+
export async function findAnyCachedToken(host) {
|
|
126
|
+
const found = await findAnyCachedCreds(host);
|
|
127
|
+
return found ? { email: found.email, token: found.data.accountToken } : undefined;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/auth/cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import pkg from '@hcengineering/api-client';
|
|
2
|
+
import accountPkg from '@hcengineering/account-client';
|
|
3
|
+
import { createRequire } from 'node:module';
|
|
4
|
+
import { readEnv, insecureTLS } from './env.js';
|
|
5
|
+
import { getCachedCreds, setCachedCreds, setCachedWorkspaceToken, findAnyCachedToken, writeActiveAccount } from './cache.js';
|
|
6
|
+
const require = createRequire(import.meta.url);
|
|
7
|
+
const wsModule = require('ws');
|
|
8
|
+
const NodeWebSocketFactory = (url) => {
|
|
9
|
+
const wsOpts = insecureTLS() ? { rejectUnauthorized: false } : {};
|
|
10
|
+
const ws = new wsModule.WebSocket(url, wsOpts);
|
|
11
|
+
const client = {
|
|
12
|
+
get readyState() {
|
|
13
|
+
return ws.readyState;
|
|
14
|
+
},
|
|
15
|
+
send: (data) => {
|
|
16
|
+
if (data instanceof Blob) {
|
|
17
|
+
void data.arrayBuffer().then((buffer) => { ws.send(buffer); });
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
ws.send(data);
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
close: (code) => {
|
|
24
|
+
ws.close(code);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
ws.on('message', (data) => {
|
|
28
|
+
if (client.onmessage != null) {
|
|
29
|
+
let eventData = data;
|
|
30
|
+
if (typeof Buffer !== 'undefined' && data instanceof Buffer) {
|
|
31
|
+
eventData = new Uint8Array(data).buffer;
|
|
32
|
+
}
|
|
33
|
+
const event = { data: eventData, type: 'message', target: client };
|
|
34
|
+
client.onmessage(event);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
ws.on('close', (code, _reason) => {
|
|
38
|
+
if (client.onclose != null) {
|
|
39
|
+
const evt = { code, reason: '', wasClean: code === 1000, type: 'close', target: client };
|
|
40
|
+
client.onclose(evt);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
ws.on('open', () => {
|
|
44
|
+
if (client.onopen != null) {
|
|
45
|
+
const evt = { type: 'open', target: client };
|
|
46
|
+
client.onopen(evt);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
ws.on('error', (err) => {
|
|
50
|
+
if (client.onerror != null) {
|
|
51
|
+
const evt = { type: 'error', target: client, error: err };
|
|
52
|
+
client.onerror(evt);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
return client;
|
|
56
|
+
};
|
|
57
|
+
// Polyfills for `window` / `WebSocket` are installed in src/index.ts before
|
|
58
|
+
// the SDK is loaded; no need to repeat here.
|
|
59
|
+
const { connect } = pkg;
|
|
60
|
+
const { getClient } = accountPkg;
|
|
61
|
+
const accountsUrlCache = new Map();
|
|
62
|
+
async function resolveAccountsUrl(url) {
|
|
63
|
+
const host = url.replace(/\/$/, '');
|
|
64
|
+
if (accountsUrlCache.has(host))
|
|
65
|
+
return accountsUrlCache.get(host);
|
|
66
|
+
let accountsUrl = `${host}/_accounts`;
|
|
67
|
+
try {
|
|
68
|
+
// CLI-08: HULY_INSECURE_TLS is enforced globally via applyInsecureTLS()
|
|
69
|
+
// (Node's built-in undici fetch ignores per-request `agent`), so we no
|
|
70
|
+
// longer pass an `agent` here. The fetch below honors NODE_TLS_REJECT_UNAUTHORIZED.
|
|
71
|
+
const r = await fetch(`${host}/config.json`);
|
|
72
|
+
if (r.ok) {
|
|
73
|
+
const cfg = (await r.json());
|
|
74
|
+
if (cfg.ACCOUNTS_URL)
|
|
75
|
+
accountsUrl = cfg.ACCOUNTS_URL;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// fall through to default
|
|
80
|
+
}
|
|
81
|
+
accountsUrlCache.set(host, accountsUrl);
|
|
82
|
+
return accountsUrl;
|
|
83
|
+
}
|
|
84
|
+
export async function accountClient(url, token) {
|
|
85
|
+
const accountsUrl = await resolveAccountsUrl(url);
|
|
86
|
+
return getClient(accountsUrl, token);
|
|
87
|
+
}
|
|
88
|
+
export async function login(url, email, password) {
|
|
89
|
+
const c = await accountClient(url);
|
|
90
|
+
const info = await c.login(email, password);
|
|
91
|
+
if (!info.token)
|
|
92
|
+
throw new Error('login succeeded but no token returned');
|
|
93
|
+
return { token: info.token, account: info.account };
|
|
94
|
+
}
|
|
95
|
+
export async function loginAndCache(url, email, password) {
|
|
96
|
+
const result = await login(url, email, password);
|
|
97
|
+
// Preserve any cached workspace tokens — only refresh the account token.
|
|
98
|
+
const existing = await getCachedCreds(url, email);
|
|
99
|
+
await setCachedCreds(url, email, {
|
|
100
|
+
accountToken: result.token,
|
|
101
|
+
workspaces: existing?.workspaces ?? {}
|
|
102
|
+
});
|
|
103
|
+
await writeActiveAccount(url, email);
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
export async function listWorkspaces(url, token) {
|
|
107
|
+
const c = await accountClient(url, token);
|
|
108
|
+
return await c.getUserWorkspaces();
|
|
109
|
+
}
|
|
110
|
+
export async function selectWorkspace(url, token, workspaceUrl) {
|
|
111
|
+
const c = await accountClient(url, token);
|
|
112
|
+
return await c.selectWorkspace(workspaceUrl);
|
|
113
|
+
}
|
|
114
|
+
export async function connectPlatform(opts) {
|
|
115
|
+
const env = readEnv();
|
|
116
|
+
const url = opts.url ?? env.url;
|
|
117
|
+
const workspace = opts.workspace ?? env.workspace;
|
|
118
|
+
const email = opts.email ?? env.email;
|
|
119
|
+
const password = opts.password ?? env.password;
|
|
120
|
+
let token = opts.token ?? env.token;
|
|
121
|
+
let resolvedEmail = email;
|
|
122
|
+
if (!workspace) {
|
|
123
|
+
throw new Error('workspace required: pass --workspace, set HULY_WORKSPACE, or run `huly workspace use <name>`');
|
|
124
|
+
}
|
|
125
|
+
if (!token && email && password) {
|
|
126
|
+
const loginResult = await loginAndCache(url, email, password);
|
|
127
|
+
token = loginResult.token;
|
|
128
|
+
}
|
|
129
|
+
if (!token) {
|
|
130
|
+
if (email) {
|
|
131
|
+
const cached = await getCachedCreds(url, email);
|
|
132
|
+
if (cached) {
|
|
133
|
+
token = cached.accountToken;
|
|
134
|
+
resolvedEmail = email;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (!token) {
|
|
138
|
+
const cached = await findAnyCachedToken(url);
|
|
139
|
+
if (cached) {
|
|
140
|
+
token = cached.token;
|
|
141
|
+
resolvedEmail = cached.email;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
if (!token) {
|
|
145
|
+
throw new Error('auth required: set HULY_EMAIL/HULY_PASSWORD, HULY_TOKEN, or run `huly login`');
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
const connectOpts = token
|
|
149
|
+
? { token, workspace, socketFactory: NodeWebSocketFactory }
|
|
150
|
+
: { email: email, password: password, workspace, socketFactory: NodeWebSocketFactory };
|
|
151
|
+
const client = await connect(url, connectOpts);
|
|
152
|
+
if (resolvedEmail && token) {
|
|
153
|
+
try {
|
|
154
|
+
const wsLogin = await selectWorkspace(url, token, workspace);
|
|
155
|
+
await setCachedWorkspaceToken(url, resolvedEmail, wsLogin.workspaceUrl ?? workspace, {
|
|
156
|
+
token: wsLogin.token,
|
|
157
|
+
role: wsLogin.role,
|
|
158
|
+
endpoint: wsLogin.endpoint,
|
|
159
|
+
workspaceId: wsLogin.workspace
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
// best-effort caching
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return client;
|
|
167
|
+
}
|
|
168
|
+
export async function resolveToken(opts) {
|
|
169
|
+
const env = readEnv();
|
|
170
|
+
const url = opts.url ?? env.url;
|
|
171
|
+
const token = opts.token ?? env.token;
|
|
172
|
+
if (token)
|
|
173
|
+
return token;
|
|
174
|
+
const email = opts.email ?? env.email;
|
|
175
|
+
const password = opts.password ?? env.password;
|
|
176
|
+
// Prefer cached credentials over re-authenticating. Re-login would clobber
|
|
177
|
+
// any cached workspace tokens.
|
|
178
|
+
if (email) {
|
|
179
|
+
const cached = await getCachedCreds(url, email);
|
|
180
|
+
if (cached)
|
|
181
|
+
return cached.accountToken;
|
|
182
|
+
}
|
|
183
|
+
if (email && password) {
|
|
184
|
+
const r = await loginAndCache(url, email, password);
|
|
185
|
+
return r.token;
|
|
186
|
+
}
|
|
187
|
+
const any = await findAnyCachedToken(url);
|
|
188
|
+
if (any)
|
|
189
|
+
return any.token;
|
|
190
|
+
throw new Error('auth required: set HULY_EMAIL/HULY_PASSWORD, HULY_TOKEN, or run `huly login`');
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/auth/client.ts"],"names":[],"mappings":"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"}
|
package/dist/auth/env.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
let dotenvLoaded = false;
|
|
5
|
+
function loadDotenvFile() {
|
|
6
|
+
if (dotenvLoaded)
|
|
7
|
+
return;
|
|
8
|
+
dotenvLoaded = true;
|
|
9
|
+
const file = process.env.HULY_ENV_FILE ?? path.join(os.homedir(), '.config', 'huly', '.env');
|
|
10
|
+
if (!fs.existsSync(file))
|
|
11
|
+
return;
|
|
12
|
+
for (const line of fs.readFileSync(file, 'utf8').split('\n')) {
|
|
13
|
+
const m = line.match(/^\s*(?:export\s+)?([A-Z_][A-Z0-9_]*)\s*=\s*(.*)\s*$/);
|
|
14
|
+
if (!m)
|
|
15
|
+
continue;
|
|
16
|
+
const key = m[1];
|
|
17
|
+
let raw = m[2].trim();
|
|
18
|
+
if ((raw.startsWith('"') && raw.endsWith('"')) || (raw.startsWith("'") && raw.endsWith("'"))) {
|
|
19
|
+
raw = raw.slice(1, -1);
|
|
20
|
+
}
|
|
21
|
+
if (process.env[key] === undefined)
|
|
22
|
+
process.env[key] = raw;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export function readEnv(env = process.env) {
|
|
26
|
+
loadDotenvFile();
|
|
27
|
+
return {
|
|
28
|
+
url: env.HULY_URL ?? 'https://huly.aaravlabs.com',
|
|
29
|
+
email: env.HULY_EMAIL,
|
|
30
|
+
password: env.HULY_PASSWORD,
|
|
31
|
+
token: env.HULY_TOKEN,
|
|
32
|
+
workspace: env.HULY_WORKSPACE,
|
|
33
|
+
project: env.HULY_PROJECT,
|
|
34
|
+
teamspace: env.HULY_TEAMSPACE
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export function isNonInteractive(env = process.env) {
|
|
38
|
+
if (env.HULY_NONINTERACTIVE === '1')
|
|
39
|
+
return true;
|
|
40
|
+
if (env.CI)
|
|
41
|
+
return true;
|
|
42
|
+
if (process.env.__HULY_NONINTERACTIVE === '1')
|
|
43
|
+
return true;
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
export function markNonInteractive() {
|
|
47
|
+
process.env.HULY_NONINTERACTIVE = '1';
|
|
48
|
+
process.env.__HULY_NONINTERACTIVE = '1';
|
|
49
|
+
}
|
|
50
|
+
export function insecureTLS(env = process.env) {
|
|
51
|
+
return env.HULY_INSECURE_TLS === '1';
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Apply `HULY_INSECURE_TLS=1` to the global Node TLS state so that ALL
|
|
55
|
+
* outgoing HTTPS requests (including those performed by Node's built-in
|
|
56
|
+
* undici `fetch` and SDK code that ignores our `agent` option) skip TLS
|
|
57
|
+
* verification. Must be called as early as possible — before any fetch or
|
|
58
|
+
* SDK connect — to take effect for the lifetime of the process.
|
|
59
|
+
*
|
|
60
|
+
* Effect: sets NODE_TLS_REJECT_UNAUTHORIZED=0 and the internal undici
|
|
61
|
+
* dispatcher equivalent via NODE_EXTRA_CA_CERTS-style fallbacks. Future
|
|
62
|
+
* fetches use rejectUnauthorized=false.
|
|
63
|
+
*/
|
|
64
|
+
export function applyInsecureTLS() {
|
|
65
|
+
if (!insecureTLS())
|
|
66
|
+
return;
|
|
67
|
+
if (process.env.NODE_TLS_REJECT_UNAUTHORIZED === '0')
|
|
68
|
+
return;
|
|
69
|
+
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
70
|
+
// Also disable verification for the legacy `https` agent path used by
|
|
71
|
+
// some SDK bridges.
|
|
72
|
+
try {
|
|
73
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
74
|
+
const https = require('node:https');
|
|
75
|
+
https.globalAgent.options.rejectUnauthorized = false;
|
|
76
|
+
}
|
|
77
|
+
catch { /* ignore */ }
|
|
78
|
+
}
|
|
79
|
+
export function isHttp(env = process.env) {
|
|
80
|
+
if (!env.HULY_URL)
|
|
81
|
+
return false;
|
|
82
|
+
return env.HULY_URL.startsWith('http://');
|
|
83
|
+
}
|
|
84
|
+
export function activeAccountPath() {
|
|
85
|
+
return `${configDir()}/active-account`;
|
|
86
|
+
}
|
|
87
|
+
export function noColor(env = process.env) {
|
|
88
|
+
return env.NO_COLOR != null && env.NO_COLOR !== '';
|
|
89
|
+
}
|
|
90
|
+
export function configDir() {
|
|
91
|
+
const xdg = process.env.XDG_CONFIG_HOME;
|
|
92
|
+
const home = process.env.HOME ?? '~';
|
|
93
|
+
return `${xdg ?? `${home}/.config`}/huly`;
|
|
94
|
+
}
|
|
95
|
+
export function credentialsPath() {
|
|
96
|
+
return `${configDir()}/credentials.json`;
|
|
97
|
+
}
|
|
98
|
+
export function activeWorkspacePath() {
|
|
99
|
+
return `${configDir()}/active-workspace`;
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/auth/env.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import inquirer from 'inquirer';
|
|
2
|
+
import { isNonInteractive } from './env.js';
|
|
3
|
+
import { CliError, ExitCode } from '../output/errors.js';
|
|
4
|
+
export async function promptEmail(defaultEmail, opts = {}) {
|
|
5
|
+
if (!opts.forceInteractive && isNonInteractive()) {
|
|
6
|
+
throw new CliError(ExitCode.Validation, 'no email', 'set HULY_EMAIL or run interactively');
|
|
7
|
+
}
|
|
8
|
+
const { email } = await inquirer.prompt([
|
|
9
|
+
{
|
|
10
|
+
type: 'input',
|
|
11
|
+
name: 'email',
|
|
12
|
+
message: 'Email:',
|
|
13
|
+
default: defaultEmail,
|
|
14
|
+
validate: (v) => (v.includes('@') ? true : 'enter a valid email')
|
|
15
|
+
}
|
|
16
|
+
]);
|
|
17
|
+
return email;
|
|
18
|
+
}
|
|
19
|
+
export async function promptPassword(opts = {}) {
|
|
20
|
+
if (!opts.forceInteractive && isNonInteractive()) {
|
|
21
|
+
throw new CliError(ExitCode.Validation, 'no password', 'set HULY_PASSWORD or run interactively');
|
|
22
|
+
}
|
|
23
|
+
const { password } = await inquirer.prompt([
|
|
24
|
+
{ type: 'password', name: 'password', message: 'Password:', mask: '*' }
|
|
25
|
+
]);
|
|
26
|
+
return password;
|
|
27
|
+
}
|
|
28
|
+
export async function pickWorkspace(workspaces, opts = {}) {
|
|
29
|
+
if (!opts.forceInteractive && isNonInteractive()) {
|
|
30
|
+
throw new CliError(ExitCode.Validation, 'no workspace selected', 'set HULY_WORKSPACE or run interactively');
|
|
31
|
+
}
|
|
32
|
+
if (workspaces.length === 0) {
|
|
33
|
+
throw new CliError(ExitCode.NotFound, 'no workspaces accessible for this account');
|
|
34
|
+
}
|
|
35
|
+
const { workspace } = await inquirer.prompt([
|
|
36
|
+
{
|
|
37
|
+
type: 'list',
|
|
38
|
+
name: 'workspace',
|
|
39
|
+
message: 'Workspace:',
|
|
40
|
+
choices: workspaces.map((w) => ({
|
|
41
|
+
name: `${w.name} (${w.url}) [${w.mode}]`,
|
|
42
|
+
value: w
|
|
43
|
+
}))
|
|
44
|
+
}
|
|
45
|
+
]);
|
|
46
|
+
return workspace;
|
|
47
|
+
}
|
|
48
|
+
export async function pickProject(projects, message = 'Project:', opts = {}) {
|
|
49
|
+
if (!opts.forceInteractive && isNonInteractive()) {
|
|
50
|
+
throw new CliError(ExitCode.Validation, 'no project selected', 'pass --project, set HULY_PROJECT, or run interactively');
|
|
51
|
+
}
|
|
52
|
+
if (projects.length === 0) {
|
|
53
|
+
throw new CliError(ExitCode.NotFound, 'no projects found in this workspace');
|
|
54
|
+
}
|
|
55
|
+
const { project } = await inquirer.prompt([
|
|
56
|
+
{
|
|
57
|
+
type: 'list',
|
|
58
|
+
name: 'project',
|
|
59
|
+
message,
|
|
60
|
+
choices: projects.map((p) => ({
|
|
61
|
+
name: p.label ?? p.name ?? p.identifier ?? p._id,
|
|
62
|
+
value: p
|
|
63
|
+
}))
|
|
64
|
+
}
|
|
65
|
+
]);
|
|
66
|
+
return project;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/auth/prompts.ts"],"names":[],"mappings":"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"}
|