@instafy/cli 0.1.7 → 0.1.8-staging.348
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 +7 -1
- package/dist/api.js +3 -1
- package/dist/auth.js +112 -0
- package/dist/config-command.js +104 -0
- package/dist/config.js +111 -0
- package/dist/errors.js +10 -0
- package/dist/git-credential.js +201 -0
- package/dist/git-setup.js +56 -0
- package/dist/git.js +4 -1
- package/dist/index.js +260 -15
- package/dist/org.js +5 -18
- package/dist/project.js +11 -24
- package/dist/runtime.js +266 -57
- package/dist/tunnel.js +300 -13
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -2,11 +2,14 @@ import { Command, Option } from "commander";
|
|
|
2
2
|
import { pathToFileURL } from "node:url";
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import kleur from "kleur";
|
|
5
|
-
import { runtimeStart, runtimeStatus, runtimeStop, runtimeToken, } from "./runtime.js";
|
|
5
|
+
import { runtimeStart, runtimeStatus, runtimeStop, runtimeToken, findProjectManifest, } from "./runtime.js";
|
|
6
|
+
import { login, logout } from "./auth.js";
|
|
6
7
|
import { gitToken } from "./git.js";
|
|
8
|
+
import { runGitCredentialHelper } from "./git-credential.js";
|
|
7
9
|
import { projectInit } from "./project.js";
|
|
8
|
-
import { runTunnelCommand } from "./tunnel.js";
|
|
10
|
+
import { listTunnelSessions, startTunnelDetached, stopTunnelSession, tailTunnelLogs, runTunnelCommand } from "./tunnel.js";
|
|
9
11
|
import { requestControllerApi } from "./api.js";
|
|
12
|
+
import { configGet, configList, configPath, configSet, configUnset } from "./config-command.js";
|
|
10
13
|
export const program = new Command();
|
|
11
14
|
const require = createRequire(import.meta.url);
|
|
12
15
|
const pkg = require("../package.json");
|
|
@@ -32,6 +35,114 @@ program
|
|
|
32
35
|
.name("instafy")
|
|
33
36
|
.description("Instafy CLI — run your project locally and connect to Studio")
|
|
34
37
|
.version(pkg.version ?? "0.1.0");
|
|
38
|
+
program
|
|
39
|
+
.command("login")
|
|
40
|
+
.description("Log in and save an access token for future CLI commands")
|
|
41
|
+
.option("--studio-url <url>", "Studio web URL (default: staging or localhost)")
|
|
42
|
+
.option("--server-url <url>", "Instafy server/controller URL")
|
|
43
|
+
.option("--token <token>", "Provide token directly (skips prompt)")
|
|
44
|
+
.option("--no-git-setup", "Do not configure git credential helper")
|
|
45
|
+
.option("--no-store", "Do not save token to ~/.instafy/config.json")
|
|
46
|
+
.option("--json", "Output JSON")
|
|
47
|
+
.action(async (opts) => {
|
|
48
|
+
try {
|
|
49
|
+
await login({
|
|
50
|
+
controllerUrl: opts.serverUrl,
|
|
51
|
+
studioUrl: opts.studioUrl,
|
|
52
|
+
token: opts.token,
|
|
53
|
+
gitSetup: opts.gitSetup,
|
|
54
|
+
noStore: opts.store === false,
|
|
55
|
+
json: opts.json,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
console.error(kleur.red(String(error)));
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
program
|
|
64
|
+
.command("logout")
|
|
65
|
+
.description("Clear the saved CLI access token")
|
|
66
|
+
.option("--json", "Output JSON")
|
|
67
|
+
.action(async (opts) => {
|
|
68
|
+
try {
|
|
69
|
+
await logout({ json: opts.json });
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
console.error(kleur.red(String(error)));
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
const configCommand = program.command("config").description("Get/set saved CLI configuration");
|
|
77
|
+
configCommand
|
|
78
|
+
.command("path")
|
|
79
|
+
.description("Print the config file path")
|
|
80
|
+
.option("--json", "Output JSON")
|
|
81
|
+
.action(async (opts) => {
|
|
82
|
+
try {
|
|
83
|
+
configPath({ json: opts.json });
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
console.error(kleur.red(String(error)));
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
configCommand
|
|
91
|
+
.command("list")
|
|
92
|
+
.description("List saved configuration")
|
|
93
|
+
.option("--json", "Output JSON")
|
|
94
|
+
.action(async (opts) => {
|
|
95
|
+
try {
|
|
96
|
+
configList({ json: opts.json });
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
console.error(kleur.red(String(error)));
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
configCommand
|
|
104
|
+
.command("get")
|
|
105
|
+
.description("Get a config value (controller-url, studio-url)")
|
|
106
|
+
.argument("<key>", "Config key")
|
|
107
|
+
.option("--json", "Output JSON")
|
|
108
|
+
.action(async (key, opts) => {
|
|
109
|
+
try {
|
|
110
|
+
configGet({ key, json: opts.json });
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
console.error(kleur.red(String(error)));
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
configCommand
|
|
118
|
+
.command("set")
|
|
119
|
+
.description("Set a config value (controller-url, studio-url)")
|
|
120
|
+
.argument("<key>", "Config key")
|
|
121
|
+
.argument("<value>", "Config value")
|
|
122
|
+
.option("--json", "Output JSON")
|
|
123
|
+
.action(async (key, value, opts) => {
|
|
124
|
+
try {
|
|
125
|
+
configSet({ key, value, json: opts.json });
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
console.error(kleur.red(String(error)));
|
|
129
|
+
process.exit(1);
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
configCommand
|
|
133
|
+
.command("unset")
|
|
134
|
+
.description("Unset a config value (controller-url, studio-url)")
|
|
135
|
+
.argument("<key>", "Config key")
|
|
136
|
+
.option("--json", "Output JSON")
|
|
137
|
+
.action(async (key, opts) => {
|
|
138
|
+
try {
|
|
139
|
+
configUnset({ key, json: opts.json });
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
console.error(kleur.red(String(error)));
|
|
143
|
+
process.exit(1);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
35
146
|
const runtimeStartCommand = program
|
|
36
147
|
.command("runtime:start")
|
|
37
148
|
.description("Start a local runtime for this project")
|
|
@@ -46,6 +157,7 @@ runtimeStartCommand
|
|
|
46
157
|
.option("--codex-bin <path>", "Path to codex binary (fallback to PATH)")
|
|
47
158
|
.option("--proxy-base-url <url>", "Codex proxy base URL")
|
|
48
159
|
.option("--workspace <path>", "Workspace directory (defaults to ./.instafy/workspace)")
|
|
160
|
+
.option("--runtime-mode <mode>", "Runtime runner (auto|docker|process)", "auto")
|
|
49
161
|
.option("--origin-id <uuid>", "Origin ID to use (auto-generated if omitted)")
|
|
50
162
|
.option("--origin-endpoint <url>", "Explicit origin endpoint (skip tunnel setup when provided)")
|
|
51
163
|
.option("--origin-token <token>", "Runtime/origin access token for Studio registration")
|
|
@@ -100,7 +212,7 @@ program
|
|
|
100
212
|
const runtimeTokenCommand = program
|
|
101
213
|
.command("runtime:token")
|
|
102
214
|
.description("Mint a runtime access token")
|
|
103
|
-
.
|
|
215
|
+
.option("--project <id>", "Project UUID (defaults to .instafy/project.json)");
|
|
104
216
|
addServerUrlOptions(runtimeTokenCommand);
|
|
105
217
|
addAccessTokenOptions(runtimeTokenCommand, "Instafy access token (required)");
|
|
106
218
|
runtimeTokenCommand
|
|
@@ -109,8 +221,14 @@ runtimeTokenCommand
|
|
|
109
221
|
.option("--json", "Output token as JSON")
|
|
110
222
|
.action(async (opts) => {
|
|
111
223
|
try {
|
|
224
|
+
const project = typeof opts.project === "string" && opts.project.trim()
|
|
225
|
+
? opts.project.trim()
|
|
226
|
+
: findProjectManifest(process.cwd()).manifest?.projectId ?? null;
|
|
227
|
+
if (!project) {
|
|
228
|
+
throw new Error("No project configured. Run `instafy project:init` or pass --project.");
|
|
229
|
+
}
|
|
112
230
|
await runtimeToken({
|
|
113
|
-
project
|
|
231
|
+
project,
|
|
114
232
|
controllerUrl: opts.serverUrl ?? opts.controllerUrl,
|
|
115
233
|
controllerAccessToken: opts.accessToken ?? opts.controllerAccessToken,
|
|
116
234
|
runtimeId: opts.runtimeId,
|
|
@@ -126,7 +244,7 @@ runtimeTokenCommand
|
|
|
126
244
|
const gitTokenCommand = program
|
|
127
245
|
.command("git:token")
|
|
128
246
|
.description("Mint a git access token for the project repo")
|
|
129
|
-
.
|
|
247
|
+
.option("--project <id>", "Project UUID (defaults to .instafy/project.json)");
|
|
130
248
|
addServerUrlOptions(gitTokenCommand);
|
|
131
249
|
addAccessTokenOptions(gitTokenCommand, "Instafy access token (required)");
|
|
132
250
|
gitTokenCommand
|
|
@@ -137,13 +255,19 @@ gitTokenCommand
|
|
|
137
255
|
.option("--json", "Output token response as JSON")
|
|
138
256
|
.action(async (opts) => {
|
|
139
257
|
try {
|
|
258
|
+
const project = typeof opts.project === "string" && opts.project.trim()
|
|
259
|
+
? opts.project.trim()
|
|
260
|
+
: findProjectManifest(process.cwd()).manifest?.projectId ?? null;
|
|
261
|
+
if (!project) {
|
|
262
|
+
throw new Error("No project configured. Run `instafy project:init` or pass --project.");
|
|
263
|
+
}
|
|
140
264
|
const ttlSecondsRaw = typeof opts.ttlSeconds === "string" ? opts.ttlSeconds.trim() : "";
|
|
141
265
|
const ttlSeconds = ttlSecondsRaw.length > 0 ? Number.parseInt(ttlSecondsRaw, 10) : undefined;
|
|
142
266
|
if (ttlSecondsRaw.length > 0 && (!Number.isFinite(ttlSeconds) || ttlSeconds <= 0)) {
|
|
143
267
|
throw new Error("--ttl-seconds must be a positive integer");
|
|
144
268
|
}
|
|
145
269
|
await gitToken({
|
|
146
|
-
project
|
|
270
|
+
project,
|
|
147
271
|
controllerUrl: opts.serverUrl ?? opts.controllerUrl,
|
|
148
272
|
controllerAccessToken: opts.accessToken ?? opts.controllerAccessToken,
|
|
149
273
|
supabaseAccessToken: opts.supabaseAccessToken,
|
|
@@ -158,6 +282,19 @@ gitTokenCommand
|
|
|
158
282
|
process.exit(1);
|
|
159
283
|
}
|
|
160
284
|
});
|
|
285
|
+
program
|
|
286
|
+
.command("git:credential", { hidden: true })
|
|
287
|
+
.description("Internal: git credential helper (used by Git when configured)")
|
|
288
|
+
.argument("<operation>", "Operation (get|store|erase)")
|
|
289
|
+
.action(async (operation) => {
|
|
290
|
+
try {
|
|
291
|
+
await runGitCredentialHelper(operation);
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
console.error(String(error));
|
|
295
|
+
process.exit(1);
|
|
296
|
+
}
|
|
297
|
+
});
|
|
161
298
|
const projectInitCommand = program
|
|
162
299
|
.command("project:init")
|
|
163
300
|
.description("Create an Instafy project and link this folder (.instafy/project.json)")
|
|
@@ -192,22 +329,130 @@ projectInitCommand
|
|
|
192
329
|
});
|
|
193
330
|
const tunnelCommand = program
|
|
194
331
|
.command("tunnel")
|
|
195
|
-
.description("
|
|
196
|
-
.option("--
|
|
332
|
+
.description("Start a shareable tunnel URL for a local port (defaults to detached)")
|
|
333
|
+
.option("--port <port>", "Local port to expose (default 3000)")
|
|
334
|
+
.option("--project <id>", "Project UUID (defaults to .instafy/project.json or PROJECT_ID)");
|
|
197
335
|
addServerUrlOptions(tunnelCommand);
|
|
336
|
+
addAccessTokenOptions(tunnelCommand, "Instafy access token (defaults to saved `instafy login` token)");
|
|
198
337
|
addServiceTokenOptions(tunnelCommand, "Instafy service token (advanced)");
|
|
199
338
|
tunnelCommand
|
|
200
|
-
.option("--
|
|
339
|
+
.option("--no-detach", "Run in foreground until interrupted")
|
|
201
340
|
.option("--rathole-bin <path>", "Path to rathole binary (or set RATHOLE_BIN)")
|
|
341
|
+
.option("--log-file <path>", "Write tunnel logs to a file (default: ~/.instafy/cli-tunnel-logs/*)")
|
|
342
|
+
.option("--json", "Output JSON")
|
|
202
343
|
.action(async (opts) => {
|
|
203
344
|
try {
|
|
204
345
|
const port = opts.port ? Number(opts.port) : undefined;
|
|
205
|
-
|
|
346
|
+
const controllerToken = opts.serviceToken ??
|
|
347
|
+
opts.controllerToken ??
|
|
348
|
+
opts.accessToken ??
|
|
349
|
+
opts.controllerAccessToken;
|
|
350
|
+
if (opts.detach === false) {
|
|
351
|
+
await runTunnelCommand({
|
|
352
|
+
project: opts.project,
|
|
353
|
+
controllerUrl: opts.serverUrl ?? opts.controllerUrl,
|
|
354
|
+
controllerToken,
|
|
355
|
+
port,
|
|
356
|
+
ratholeBin: opts.ratholeBin,
|
|
357
|
+
});
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
const started = await startTunnelDetached({
|
|
206
361
|
project: opts.project,
|
|
207
362
|
controllerUrl: opts.serverUrl ?? opts.controllerUrl,
|
|
208
|
-
controllerToken
|
|
363
|
+
controllerToken,
|
|
209
364
|
port,
|
|
210
365
|
ratholeBin: opts.ratholeBin,
|
|
366
|
+
logFile: opts.logFile,
|
|
367
|
+
});
|
|
368
|
+
if (opts.json) {
|
|
369
|
+
console.log(JSON.stringify(started, null, 2));
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
console.log(kleur.green(`Tunnel started: ${started.url} (tunnelId=${started.tunnelId})`));
|
|
373
|
+
console.log(kleur.gray(`pid=${started.pid} · port=${started.localPort}`));
|
|
374
|
+
console.log(kleur.gray(`log: ${started.logFile}`));
|
|
375
|
+
console.log("");
|
|
376
|
+
console.log("Next:");
|
|
377
|
+
console.log(`- ${kleur.cyan(`instafy tunnel:list`)}`);
|
|
378
|
+
console.log(`- ${kleur.cyan(`instafy tunnel:logs ${started.tunnelId} --follow`)}`);
|
|
379
|
+
console.log(`- ${kleur.cyan(`instafy tunnel:stop ${started.tunnelId}`)}`);
|
|
380
|
+
if (process.platform !== "win32") {
|
|
381
|
+
console.log(kleur.gray(`(or) tail -n 200 -f ${started.logFile}`));
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
catch (error) {
|
|
385
|
+
console.error(kleur.red(String(error)));
|
|
386
|
+
process.exit(1);
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
program
|
|
390
|
+
.command("tunnel:list")
|
|
391
|
+
.description("List local tunnel sessions started by this CLI")
|
|
392
|
+
.option("--all", "Include stopped/stale tunnels")
|
|
393
|
+
.option("--json", "Output JSON")
|
|
394
|
+
.action(async (opts) => {
|
|
395
|
+
try {
|
|
396
|
+
const tunnels = listTunnelSessions({ all: Boolean(opts.all), json: Boolean(opts.json) });
|
|
397
|
+
if (opts.json) {
|
|
398
|
+
console.log(JSON.stringify(tunnels, null, 2));
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
if (tunnels.length === 0) {
|
|
402
|
+
console.log(kleur.yellow("No tunnels found."));
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
for (const tunnel of tunnels) {
|
|
406
|
+
console.log(`${tunnel.tunnelId} · ${tunnel.url} · port=${tunnel.localPort} · pid=${tunnel.pid}`);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
catch (error) {
|
|
410
|
+
console.error(kleur.red(String(error)));
|
|
411
|
+
process.exit(1);
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
program
|
|
415
|
+
.command("tunnel:stop")
|
|
416
|
+
.description("Stop a local tunnel session and revoke it")
|
|
417
|
+
.argument("[tunnelId]", "Tunnel ID (defaults to the only active tunnel)")
|
|
418
|
+
.option("--server-url <url>", "Instafy server URL")
|
|
419
|
+
.option("--access-token <token>", "Instafy access token (defaults to saved `instafy login` token)")
|
|
420
|
+
.option("--service-token <token>", "Instafy service token (advanced)")
|
|
421
|
+
.option("--json", "Output JSON")
|
|
422
|
+
.action(async (tunnelId, opts) => {
|
|
423
|
+
try {
|
|
424
|
+
const result = await stopTunnelSession({
|
|
425
|
+
tunnelId,
|
|
426
|
+
controllerUrl: opts.serverUrl,
|
|
427
|
+
controllerToken: opts.serviceToken ?? opts.accessToken,
|
|
428
|
+
json: opts.json,
|
|
429
|
+
});
|
|
430
|
+
if (opts.json) {
|
|
431
|
+
console.log(JSON.stringify(result, null, 2));
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
console.log(kleur.green(`Tunnel stopped: ${result.tunnelId}`));
|
|
435
|
+
}
|
|
436
|
+
catch (error) {
|
|
437
|
+
console.error(kleur.red(String(error)));
|
|
438
|
+
process.exit(1);
|
|
439
|
+
}
|
|
440
|
+
});
|
|
441
|
+
program
|
|
442
|
+
.command("tunnel:logs")
|
|
443
|
+
.description("Show logs for a local tunnel session")
|
|
444
|
+
.argument("[tunnelId]", "Tunnel ID (defaults to the only active tunnel)")
|
|
445
|
+
.option("--lines <n>", "Number of lines to show", "200")
|
|
446
|
+
.option("--follow", "Follow log output (like tail -f)")
|
|
447
|
+
.option("--json", "Output JSON")
|
|
448
|
+
.action(async (tunnelId, opts) => {
|
|
449
|
+
try {
|
|
450
|
+
const lines = typeof opts.lines === "string" ? Number(opts.lines) : undefined;
|
|
451
|
+
await tailTunnelLogs({
|
|
452
|
+
tunnelId,
|
|
453
|
+
lines,
|
|
454
|
+
follow: Boolean(opts.follow),
|
|
455
|
+
json: Boolean(opts.json),
|
|
211
456
|
});
|
|
212
457
|
}
|
|
213
458
|
catch (error) {
|
|
@@ -292,22 +537,22 @@ function configureApiCommand(command, method) {
|
|
|
292
537
|
}
|
|
293
538
|
const apiGetCommand = program
|
|
294
539
|
.command("api:get")
|
|
295
|
-
.description("
|
|
540
|
+
.description("Advanced: authenticated GET request to the controller API")
|
|
296
541
|
.argument("<path>", "API path (or full URL), e.g. /conversations/<id>/messages?limit=50");
|
|
297
542
|
configureApiCommand(apiGetCommand, "GET");
|
|
298
543
|
const apiPostCommand = program
|
|
299
544
|
.command("api:post")
|
|
300
|
-
.description("
|
|
545
|
+
.description("Advanced: authenticated POST request to the controller API")
|
|
301
546
|
.argument("<path>", "API path (or full URL)");
|
|
302
547
|
configureApiCommand(apiPostCommand, "POST");
|
|
303
548
|
const apiPatchCommand = program
|
|
304
549
|
.command("api:patch")
|
|
305
|
-
.description("
|
|
550
|
+
.description("Advanced: authenticated PATCH request to the controller API")
|
|
306
551
|
.argument("<path>", "API path (or full URL)");
|
|
307
552
|
configureApiCommand(apiPatchCommand, "PATCH");
|
|
308
553
|
const apiDeleteCommand = program
|
|
309
554
|
.command("api:delete")
|
|
310
|
-
.description("
|
|
555
|
+
.description("Advanced: authenticated DELETE request to the controller API")
|
|
311
556
|
.argument("<path>", "API path (or full URL)");
|
|
312
557
|
configureApiCommand(apiDeleteCommand, "DELETE");
|
|
313
558
|
export async function runCli(argv = process.argv) {
|
package/dist/org.js
CHANGED
|
@@ -1,24 +1,11 @@
|
|
|
1
1
|
import kleur from "kleur";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
if (!value)
|
|
5
|
-
return "http://127.0.0.1:8788";
|
|
6
|
-
return value.replace(/\/$/, "");
|
|
7
|
-
}
|
|
8
|
-
function normalizeToken(raw) {
|
|
9
|
-
if (!raw)
|
|
10
|
-
return null;
|
|
11
|
-
const trimmed = raw.trim();
|
|
12
|
-
return trimmed.length ? trimmed : null;
|
|
13
|
-
}
|
|
2
|
+
import { resolveControllerUrl, resolveUserAccessToken } from "./config.js";
|
|
3
|
+
import { formatAuthRequiredError } from "./errors.js";
|
|
14
4
|
export async function listOrganizations(params) {
|
|
15
|
-
const controllerUrl =
|
|
16
|
-
const token =
|
|
17
|
-
normalizeToken(process.env["INSTAFY_ACCESS_TOKEN"]) ??
|
|
18
|
-
normalizeToken(process.env["CONTROLLER_ACCESS_TOKEN"]) ??
|
|
19
|
-
normalizeToken(process.env["SUPABASE_ACCESS_TOKEN"]);
|
|
5
|
+
const controllerUrl = resolveControllerUrl({ controllerUrl: params.controllerUrl ?? null });
|
|
6
|
+
const token = resolveUserAccessToken({ accessToken: params.accessToken ?? null });
|
|
20
7
|
if (!token) {
|
|
21
|
-
throw
|
|
8
|
+
throw formatAuthRequiredError({ retryCommand: "instafy org:list" });
|
|
22
9
|
}
|
|
23
10
|
const response = await fetch(`${controllerUrl}/orgs`, {
|
|
24
11
|
headers: { authorization: `Bearer ${token}` },
|
package/dist/project.js
CHANGED
|
@@ -1,18 +1,8 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import kleur from "kleur";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
if (!value)
|
|
7
|
-
return "http://127.0.0.1:8788";
|
|
8
|
-
return value.replace(/\/$/, "");
|
|
9
|
-
}
|
|
10
|
-
function normalizeToken(raw) {
|
|
11
|
-
if (!raw)
|
|
12
|
-
return null;
|
|
13
|
-
const trimmed = raw.trim();
|
|
14
|
-
return trimmed.length ? trimmed : null;
|
|
15
|
-
}
|
|
4
|
+
import { resolveControllerUrl, resolveUserAccessToken } from "./config.js";
|
|
5
|
+
import { formatAuthRequiredError } from "./errors.js";
|
|
16
6
|
async function fetchOrganizations(controllerUrl, token) {
|
|
17
7
|
const response = await fetch(`${controllerUrl}/orgs`, {
|
|
18
8
|
headers: {
|
|
@@ -73,13 +63,10 @@ async function resolveOrg(controllerUrl, token, options) {
|
|
|
73
63
|
return { orgId, orgName: json.org_name ?? null };
|
|
74
64
|
}
|
|
75
65
|
export async function listProjects(options) {
|
|
76
|
-
const controllerUrl =
|
|
77
|
-
const token =
|
|
78
|
-
normalizeToken(process.env["INSTAFY_ACCESS_TOKEN"]) ??
|
|
79
|
-
normalizeToken(process.env["CONTROLLER_ACCESS_TOKEN"]) ??
|
|
80
|
-
normalizeToken(process.env["SUPABASE_ACCESS_TOKEN"]);
|
|
66
|
+
const controllerUrl = resolveControllerUrl({ controllerUrl: options.controllerUrl ?? null });
|
|
67
|
+
const token = resolveUserAccessToken({ accessToken: options.accessToken ?? null });
|
|
81
68
|
if (!token) {
|
|
82
|
-
throw
|
|
69
|
+
throw formatAuthRequiredError({ retryCommand: "instafy project:list" });
|
|
83
70
|
}
|
|
84
71
|
const orgs = await fetchOrganizations(controllerUrl, token);
|
|
85
72
|
let targetOrgs = orgs;
|
|
@@ -124,13 +111,13 @@ export async function listProjects(options) {
|
|
|
124
111
|
}
|
|
125
112
|
export async function projectInit(options) {
|
|
126
113
|
const rootDir = path.resolve(options.path ?? process.cwd());
|
|
127
|
-
const controllerUrl =
|
|
128
|
-
const token =
|
|
129
|
-
normalizeToken(process.env["INSTAFY_ACCESS_TOKEN"]) ??
|
|
130
|
-
normalizeToken(process.env["CONTROLLER_ACCESS_TOKEN"]) ??
|
|
131
|
-
normalizeToken(process.env["SUPABASE_ACCESS_TOKEN"]);
|
|
114
|
+
const controllerUrl = resolveControllerUrl({ controllerUrl: options.controllerUrl ?? null });
|
|
115
|
+
const token = resolveUserAccessToken({ accessToken: options.accessToken ?? null });
|
|
132
116
|
if (!token) {
|
|
133
|
-
throw
|
|
117
|
+
throw formatAuthRequiredError({
|
|
118
|
+
retryCommand: "instafy project:init",
|
|
119
|
+
advancedHint: "pass --access-token or set INSTAFY_ACCESS_TOKEN / SUPABASE_ACCESS_TOKEN",
|
|
120
|
+
});
|
|
134
121
|
}
|
|
135
122
|
const org = await resolveOrg(controllerUrl, token, options);
|
|
136
123
|
const body = {
|