@picked/cli 0.0.1-dev.1786675074931 → 0.0.1-dev.1787537193674
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/dist/.tsbuildinfo +1 -1
- package/dist/cjs/cli.js +2 -2
- package/dist/cjs/index.js +1 -1
- package/dist/esm/cli.js +72 -28
- package/dist/esm/index.js +1 -1
- package/dist/types/auth/oauth.d.ts.map +1 -1
- package/dist/types/auth/session.d.ts +3 -3
- package/dist/types/auth/session.d.ts.map +1 -1
- package/dist/types/commands/whoami.d.ts.map +1 -1
- package/dist/types/telemetry.d.ts +26 -0
- package/dist/types/telemetry.d.ts.map +1 -0
- package/dist/workspace-use-CT6_jewh.cjs +48 -0
- package/dist/{workspace-use-CEY180nO.js → workspace-use-Cbz1Bxse.js} +7 -10
- package/package.json +5 -4
- package/dist/workspace-use-DK1LIQd3.cjs +0 -48
package/dist/cjs/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const e=require("../workspace-use-
|
|
2
|
+
const e=require("../workspace-use-CT6_jewh.cjs");let t=require("@picked/config"),n=require("node:util"),r=require("@picked/telemetry");var i=`https://production.otel.picked.app/v1/traces`,a=2e3,o=null,s=0;function c(e){if((0,t.isTelemetryForcedOffByEnvironment)())return;s=Date.now();let n=(0,t.detectHostEnvironment)();o={name:`picked.cli.${e}`,traceId:(0,r.createTraceId)(),spanId:(0,r.createSpanId)(),startTimeUnixNano:(0,r.toUnixNano)(s),endTimeUnixNano:(0,r.toUnixNano)(s),attributes:{"picked.cli.command":e,"picked.env.provider":n.provider,"picked.env.ci":n.ci},status:`unset`}}function l(e){o&&(o.endTimeUnixNano=(0,r.toUnixNano)(Date.now()),o.status=e===0?`ok`:`error`)}async function u(){let e=o;if(o=null,e)try{let n=await(0,t.loadResolvedPickedConfig)();if(!n||!(0,t.isTelemetryEnabled)(n))return;let o=(0,r.createTelemetryEmitter)({endpoint:i,resource:{"service.name":`picked-cli`},headers:{"Picked-Telemetry":`cli`}});o.record(e),await Promise.race([o.flush(),new Promise(e=>{setTimeout(e,a).unref()})])}catch{}}var d=`Usage:
|
|
3
3
|
picked login
|
|
4
4
|
picked logout
|
|
5
5
|
picked whoami
|
|
@@ -7,4 +7,4 @@ const e=require("../workspace-use-DK1LIQd3.cjs");let t=require("node:util");var
|
|
|
7
7
|
picked workspace list [--json]
|
|
8
8
|
picked workspace use [--project <id>] [--workspace <id>] [--no-generate]
|
|
9
9
|
picked use [--project <id>] [--workspace <id>] [--no-generate]
|
|
10
|
-
picked generate types [--check]`;async function
|
|
10
|
+
picked generate types [--check]`;async function f(){let{positionals:t,values:r}=(0,n.parseArgs)({allowPositionals:!0,options:{check:{type:`boolean`,default:!1},project:{type:`string`},workspace:{type:`string`},json:{type:`boolean`,default:!1},generate:{type:`boolean`,default:!0},"no-generate":{type:`boolean`,default:!1}}}),[i,a]=t,o=r.generate&&!r[`no-generate`];if(i===`login`){c(`login`),process.exitCode=await e.o({});return}if(i===`logout`){c(`logout`),process.exitCode=await e.a();return}if(i===`whoami`){c(`whoami`),process.exitCode=await e.r();return}if(i===`status`){c(`status`),process.exitCode=await e.i({});return}if(i===`workspace`&&(a===`list`||a===`ls`)){c(`workspace list`),process.exitCode=await e.n({json:r.json});return}if(i===`workspace`&&a===`use`||i===`use`){c(`workspace use`),process.exitCode=await e.t({project:r.project,workspace:r.workspace,generate:o});return}if(i===`generate`&&a===`types`){c(`generate types`),process.exitCode=await e.s({check:r.check});return}c(`unknown`),console.error(d),process.exitCode=1}function p(e){let t=2,n=()=>{--t,t<=0&&process.exit(e)};setTimeout(()=>{process.exit(e)},2e3).unref(),process.stdout.write(``,n),process.stderr.write(``,n)}f().then(async()=>{let e=typeof process.exitCode==`number`?process.exitCode:0;l(e),await u(),p(e)}).catch(e=>{let t=e instanceof Error?e.message:String(e);console.error(t),l(1),u().finally(()=>{p(1)})});
|
package/dist/cjs/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../workspace-use-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../workspace-use-CT6_jewh.cjs");exports.runGenerateTypes=e.s,exports.runLogin=e.o,exports.runLogout=e.a,exports.runStatus=e.i,exports.runWhoami=e.r,exports.runWorkspaceList=e.n,exports.runWorkspaceUse=e.t;
|
package/dist/esm/cli.js
CHANGED
|
@@ -1,10 +1,51 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "../workspace-use-
|
|
3
|
-
import {
|
|
2
|
+
import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "../workspace-use-Cbz1Bxse.js";
|
|
3
|
+
import { detectHostEnvironment as s, isTelemetryEnabled as c, isTelemetryForcedOffByEnvironment as l, loadResolvedPickedConfig as u } from "@picked/config";
|
|
4
|
+
import { parseArgs as d } from "node:util";
|
|
5
|
+
import { createSpanId as f, createTelemetryEmitter as p, createTraceId as m, toUnixNano as h } from "@picked/telemetry";
|
|
6
|
+
//#region src/telemetry.ts
|
|
7
|
+
var g = "https://production.otel.picked.app/v1/traces", _ = 2e3, v = null, y = 0;
|
|
8
|
+
function b(e) {
|
|
9
|
+
if (l()) return;
|
|
10
|
+
y = Date.now();
|
|
11
|
+
let t = s();
|
|
12
|
+
v = {
|
|
13
|
+
name: `picked.cli.${e}`,
|
|
14
|
+
traceId: m(),
|
|
15
|
+
spanId: f(),
|
|
16
|
+
startTimeUnixNano: h(y),
|
|
17
|
+
endTimeUnixNano: h(y),
|
|
18
|
+
attributes: {
|
|
19
|
+
"picked.cli.command": e,
|
|
20
|
+
"picked.env.provider": t.provider,
|
|
21
|
+
"picked.env.ci": t.ci
|
|
22
|
+
},
|
|
23
|
+
status: "unset"
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function x(e) {
|
|
27
|
+
v && (v.endTimeUnixNano = h(Date.now()), v.status = e === 0 ? "ok" : "error");
|
|
28
|
+
}
|
|
29
|
+
async function S() {
|
|
30
|
+
let e = v;
|
|
31
|
+
if (v = null, e) try {
|
|
32
|
+
let t = await u();
|
|
33
|
+
if (!t || !c(t)) return;
|
|
34
|
+
let n = p({
|
|
35
|
+
endpoint: g,
|
|
36
|
+
resource: { "service.name": "picked-cli" },
|
|
37
|
+
headers: { "Picked-Telemetry": "cli" }
|
|
38
|
+
});
|
|
39
|
+
n.record(e), await Promise.race([n.flush(), new Promise((e) => {
|
|
40
|
+
setTimeout(e, _).unref();
|
|
41
|
+
})]);
|
|
42
|
+
} catch {}
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
4
45
|
//#region src/cli.ts
|
|
5
|
-
var
|
|
6
|
-
async function
|
|
7
|
-
let { positionals:
|
|
46
|
+
var C = "Usage:\n picked login\n picked logout\n picked whoami\n picked status\n picked workspace list [--json]\n picked workspace use [--project <id>] [--workspace <id>] [--no-generate]\n picked use [--project <id>] [--workspace <id>] [--no-generate]\n picked generate types [--check]";
|
|
47
|
+
async function w() {
|
|
48
|
+
let { positionals: s, values: c } = d({
|
|
8
49
|
allowPositionals: !0,
|
|
9
50
|
options: {
|
|
10
51
|
check: {
|
|
@@ -26,42 +67,42 @@ async function l() {
|
|
|
26
67
|
default: !1
|
|
27
68
|
}
|
|
28
69
|
}
|
|
29
|
-
}), [
|
|
30
|
-
if (
|
|
31
|
-
process.exitCode = await r({});
|
|
70
|
+
}), [l, u] = s, f = c.generate && !c["no-generate"];
|
|
71
|
+
if (l === "login") {
|
|
72
|
+
b("login"), process.exitCode = await r({});
|
|
32
73
|
return;
|
|
33
74
|
}
|
|
34
|
-
if (
|
|
35
|
-
process.exitCode = await e();
|
|
75
|
+
if (l === "logout") {
|
|
76
|
+
b("logout"), process.exitCode = await e();
|
|
36
77
|
return;
|
|
37
78
|
}
|
|
38
|
-
if (
|
|
39
|
-
process.exitCode = await i();
|
|
79
|
+
if (l === "whoami") {
|
|
80
|
+
b("whoami"), process.exitCode = await i();
|
|
40
81
|
return;
|
|
41
82
|
}
|
|
42
|
-
if (
|
|
43
|
-
process.exitCode = await t({});
|
|
83
|
+
if (l === "status") {
|
|
84
|
+
b("status"), process.exitCode = await t({});
|
|
44
85
|
return;
|
|
45
86
|
}
|
|
46
|
-
if (
|
|
47
|
-
process.exitCode = await n({ json:
|
|
87
|
+
if (l === "workspace" && (u === "list" || u === "ls")) {
|
|
88
|
+
b("workspace list"), process.exitCode = await n({ json: c.json });
|
|
48
89
|
return;
|
|
49
90
|
}
|
|
50
|
-
if (
|
|
51
|
-
process.exitCode = await o({
|
|
52
|
-
project:
|
|
53
|
-
workspace:
|
|
54
|
-
generate:
|
|
91
|
+
if (l === "workspace" && u === "use" || l === "use") {
|
|
92
|
+
b("workspace use"), process.exitCode = await o({
|
|
93
|
+
project: c.project,
|
|
94
|
+
workspace: c.workspace,
|
|
95
|
+
generate: f
|
|
55
96
|
});
|
|
56
97
|
return;
|
|
57
98
|
}
|
|
58
|
-
if (
|
|
59
|
-
process.exitCode = await a({ check:
|
|
99
|
+
if (l === "generate" && u === "types") {
|
|
100
|
+
b("generate types"), process.exitCode = await a({ check: c.check });
|
|
60
101
|
return;
|
|
61
102
|
}
|
|
62
|
-
console.error(
|
|
103
|
+
b("unknown"), console.error(C), process.exitCode = 1;
|
|
63
104
|
}
|
|
64
|
-
function
|
|
105
|
+
function T(e) {
|
|
65
106
|
let t = 2, n = () => {
|
|
66
107
|
--t, t <= 0 && process.exit(e);
|
|
67
108
|
};
|
|
@@ -69,10 +110,13 @@ function u(e) {
|
|
|
69
110
|
process.exit(e);
|
|
70
111
|
}, 2e3).unref(), process.stdout.write("", n), process.stderr.write("", n);
|
|
71
112
|
}
|
|
72
|
-
|
|
73
|
-
|
|
113
|
+
w().then(async () => {
|
|
114
|
+
let e = typeof process.exitCode == "number" ? process.exitCode : 0;
|
|
115
|
+
x(e), await S(), T(e);
|
|
74
116
|
}).catch((e) => {
|
|
75
117
|
let t = e instanceof Error ? e.message : String(e);
|
|
76
|
-
console.error(t),
|
|
118
|
+
console.error(t), x(1), S().finally(() => {
|
|
119
|
+
T(1);
|
|
120
|
+
});
|
|
77
121
|
});
|
|
78
122
|
//#endregion
|
package/dist/esm/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "../workspace-use-
|
|
1
|
+
import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "../workspace-use-Cbz1Bxse.js";
|
|
2
2
|
export { a as runGenerateTypes, r as runLogin, e as runLogout, t as runStatus, i as runWhoami, n as runWorkspaceList, o as runWorkspaceUse };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../../src/auth/oauth.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAgB,aAAa,EAAqB,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../../src/auth/oauth.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAgB,aAAa,EAAqB,MAAM,eAAe,CAAA;AAyU/F;;;;;;;;;;;GAWG;AACH,wBAAsB,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAyDlE;AAED;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,CAuC/E"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Returns a usable access token for an API origin:
|
|
3
|
-
*
|
|
2
|
+
* Returns a usable access token for an API origin: that origin's stored access token,
|
|
3
|
+
* refreshed first when within 60 seconds of expiry.
|
|
4
4
|
*
|
|
5
5
|
* @param {string} apiUrl - The API origin the token will be used against.
|
|
6
6
|
* @returns {Promise<string>} A bearer token suitable for `Authorization: Bearer <token>`.
|
|
7
|
-
* @throws {Error} When not logged in to `apiUrl
|
|
7
|
+
* @throws {Error} When not logged in to `apiUrl`.
|
|
8
8
|
* @example
|
|
9
9
|
* const token = await getAccessToken('https://api.picked.app')
|
|
10
10
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/auth/session.ts"],"names":[],"mappings":"AAMA;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/auth/session.ts"],"names":[],"mappings":"AAMA;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAcpE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../../src/commands/whoami.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAAC,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../../src/commands/whoami.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAAC,OAAO,CAAC,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAc3E"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Begins recording a command.
|
|
3
|
+
*
|
|
4
|
+
* @param {string} name - The command's own event name, from its dispatch site.
|
|
5
|
+
* @returns {void}
|
|
6
|
+
* @example beginCommand('whoami')
|
|
7
|
+
*/
|
|
8
|
+
export declare function beginCommand(name: string): void;
|
|
9
|
+
/**
|
|
10
|
+
* Finishes the recorded command.
|
|
11
|
+
*
|
|
12
|
+
* @param {number} exitCode - The exit code the command produced.
|
|
13
|
+
* @returns {void}
|
|
14
|
+
* @example endCommand(0)
|
|
15
|
+
*/
|
|
16
|
+
export declare function endCommand(exitCode: number): void;
|
|
17
|
+
/**
|
|
18
|
+
* Sends the recorded command span, if telemetry is on.
|
|
19
|
+
*
|
|
20
|
+
* Races a hard timeout so a captive network cannot delay the process exiting.
|
|
21
|
+
*
|
|
22
|
+
* @returns {Promise<void>} Resolves once the attempt has finished or timed out.
|
|
23
|
+
* @example await flushCommandTelemetry()
|
|
24
|
+
*/
|
|
25
|
+
export declare function flushCommandTelemetry(): Promise<void>;
|
|
26
|
+
//# sourceMappingURL=telemetry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../../src/telemetry.ts"],"names":[],"mappings":"AA8BA;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAqB/C;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAKjD;AAED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAyB3D"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
let e=require("@picked/typegen"),t=require("@picked/config"),n=require("node:http"),r=require("node:child_process"),i=require("node:fs"),a=require("node:fs/promises"),o=require("node:path"),s=require("node:crypto"),c=require("node:os"),l=require("@picked/admin-api-client"),u=require("node:readline");async function d(n){let r=n?.cwd??process.cwd(),i=await(0,t.loadResolvedPickedConfig)(r);if(!i)return console.error(`No picked.config.{ts,js,json} found in the current directory.`),1;try{let t=await(0,e.generate)({config:i,check:n?.check??!1,onWarn:e=>{console.warn(e)}});return n?.check?t.changed?(console.error(`Types are out of date: ${t.typesOutput}`),1):(console.log(`Types are up to date (${t.typesOutput}).`),0):(console.log(`Generated types at ${t.typesOutput}`),0)}catch(e){let t=e instanceof Error?e.message:String(e);return console.error(t),1}}function f(e){return process.platform===`darwin`?{command:`open`,args:[e]}:process.platform===`win32`?{command:`cmd`,args:[`/c`,`start`,`""`,e]}:{command:`xdg-open`,args:[e]}}function p(e){let{command:t,args:n}=f(e);try{let e=(0,r.spawn)(t,n,{detached:!0,stdio:`ignore`});e.on(`error`,()=>void 0),e.unref()}catch{}return Promise.resolve()}var m=8;function ee(){return(0,o.join)((0,c.homedir)(),`.picked`)}function h(e){let n=(0,t.normalizeApiUrl)(e),{hostname:r,port:i}=new URL(n);return`${(i?`${r}-${i}`:r).replace(/[^a-z0-9.-]/gi,`_`)}-${(0,s.createHash)(`sha256`).update(n).digest(`hex`).slice(0,m)}`}function g(e){return(0,o.join)(ee(),`auth`,`${h(e)}.json`)}var _=384;function v(e){return typeof e==`object`&&!!e&&`clientId`in e&&typeof e.clientId==`string`&&`redirectUri`in e&&typeof e.redirectUri==`string`}function y(e){return!(typeof e!=`object`||!e||!(`accessToken`in e)||typeof e.accessToken!=`string`||!(`refreshToken`in e)||typeof e.refreshToken!=`string`||!(`expiresAt`in e)||typeof e.expiresAt!=`number`||`user`in e&&e.user!==void 0&&(typeof e.user!=`object`||e.user===null))}function b(e){return!(typeof e!=`object`||!e||!(`apiUrl`in e)||typeof e.apiUrl!=`string`||`client`in e&&e.client!==void 0&&!v(e.client)||`session`in e&&e.session!==void 0&&!y(e.session))}async function x(e){let t=g(e);if(!(0,i.existsSync)(t))return null;try{let e=JSON.parse(await(0,a.readFile)(t,`utf8`));return b(e)?e:null}catch{return null}}async function S(e){let t=g(e.apiUrl);await(0,a.mkdir)((0,o.dirname)(t),{recursive:!0});let n=`${t}.${process.pid.toString()}.tmp`;await(0,a.writeFile)(n,`${JSON.stringify(e,null,2)}\n`,{encoding:`utf8`,mode:_}),await(0,a.chmod)(n,_),await(0,a.rename)(n,t)}async function C(e,n){let r=await x(e);await S({apiUrl:(0,t.normalizeApiUrl)(e),client:r?.client,session:r?.session,...n})}async function te(e,t){await C(e,{client:t})}async function w(e,t){await C(e,{session:t})}async function ne(e){await(0,a.rm)(g(e),{force:!0})}var re=32,ie=16;function T(e){return e.toString(`base64`).replaceAll(`+`,`-`).replaceAll(`/`,`_`).replaceAll(`=`,``)}function E(){return T((0,s.randomBytes)(re))}function D(e){return T((0,s.createHash)(`sha256`).update(e).digest())}function O(){return T((0,s.randomBytes)(ie))}var k=[8976,8977,8988],A=18e4,j=`openid profile email`;async function M(e){let t;try{t=await fetch(`${e}/.well-known/oauth-authorization-server`)}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`Failed to reach the Picked OAuth discovery endpoint: ${t}`)}if(!t.ok)throw Error(`OAuth discovery request failed (${t.status.toString()}).`);let n=await t.json();if(typeof n!=`object`||!n)throw Error(`Malformed OAuth discovery document.`);if(!(`authorization_endpoint`in n)||typeof n.authorization_endpoint!=`string`)throw Error(`OAuth discovery document is missing authorization_endpoint.`);if(!(`token_endpoint`in n)||typeof n.token_endpoint!=`string`)throw Error(`OAuth discovery document is missing token_endpoint.`);let r=`registration_endpoint`in n&&typeof n.registration_endpoint==`string`?n.registration_endpoint:void 0,i=`code_challenge_methods_supported`in n&&Array.isArray(n.code_challenge_methods_supported)?n.code_challenge_methods_supported.filter(e=>typeof e==`string`):void 0;return{authorizationEndpoint:n.authorization_endpoint,tokenEndpoint:n.token_endpoint,registrationEndpoint:r,codeChallengeMethods:i}}async function N(e,t,n){if(!t.registrationEndpoint)throw Error(`OAuth client registration is not available for this Picked API.`);let r=await fetch(t.registrationEndpoint,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({client_name:`Picked CLI`,redirect_uris:[n],grant_types:[`authorization_code`,`refresh_token`],response_types:[`code`],token_endpoint_auth_method:`none`})});if(!r.ok)throw Error(`OAuth client registration failed (${r.status.toString()}).`);let i=await r.json();if(typeof i!=`object`||!i||!(`client_id`in i)||typeof i.client_id!=`string`)throw Error(`OAuth client registration returned an unexpected response.`);return await te(e,{clientId:i.client_id,redirectUri:n}),i.client_id}async function P(e,t,n){let r=(await x(e))?.client;return r?.redirectUri===n?r.clientId:N(e,t,n)}function F(e,t){return new Promise(n=>{let r=()=>{e.removeListener(`error`,r),n(!1)};e.once(`error`,r),e.listen(t,`127.0.0.1`,()=>{e.removeListener(`error`,r),n(!0)})})}async function I(e){for(let t of k)if(await F(e,t))return t;throw Error(`No loopback port available for the OAuth callback (tried ${k.join(`, `)}).`)}function L(e,t,n){return new Promise((r,i)=>{let a=()=>{clearTimeout(o),process.removeListener(`SIGINT`,s),e.close()},o=setTimeout(()=>{a(),i(Error(`Timed out waiting for the browser sign-in to complete.`))},n),s=()=>{a(),i(Error(`Sign-in cancelled.`))};process.once(`SIGINT`,s),e.on(`request`,(e,n)=>{let o=new URL(e.url??`/`,`http://127.0.0.1`);if(o.pathname!==`/callback`){n.writeHead(404),n.end();return}let s=o.searchParams.get(`error`);if(s){n.writeHead(200,{"content-type":`text/html`}),n.end(`<html><body>Sign-in failed. You can close this tab.</body></html>`),a(),i(Error(`Authorization failed: ${s}`));return}let c=o.searchParams.get(`code`),l=o.searchParams.get(`state`);if(!c||l!==t){n.writeHead(400,{"content-type":`text/html`}),n.end(`<html><body>Invalid sign-in response. Close this tab and try again.</body></html>`),a(),i(Error(`Invalid OAuth callback: missing code or state mismatch.`));return}n.writeHead(200,{"content-type":`text/html`}),n.end(`<html><body>Signed in. You can close this tab and return to the terminal.</body></html>`),a(),r({code:c})})})}async function R(e){let t;try{t=await e.json()}catch{return null}if(typeof t!=`object`||!t||!(`access_token`in t)||typeof t.access_token!=`string`||!(`expires_in`in t)||typeof t.expires_in!=`number`)return null;let n=`refresh_token`in t&&typeof t.refresh_token==`string`?t.refresh_token:void 0;return{accessToken:t.access_token,refreshToken:n,expiresIn:t.expires_in}}function z(e){let t=e.split(`.`),n=t[1];if(t.length!==3||!n)return{};try{let e=JSON.parse(Buffer.from(n,`base64url`).toString(`utf8`));return typeof e!=`object`||!e?{}:{id:`sub`in e&&typeof e.sub==`string`?e.sub:void 0,email:`email`in e&&typeof e.email==`string`?e.email:void 0}}catch{return{}}}async function B(e){let t=await M(e),r=(0,n.createServer)(),i=`http://127.0.0.1:${(await I(r)).toString()}/callback`,a=await P(e,t,i),o=E(),s=D(o),c=O(),l=new URL(t.authorizationEndpoint);l.searchParams.set(`response_type`,`code`),l.searchParams.set(`client_id`,a),l.searchParams.set(`redirect_uri`,i),l.searchParams.set(`code_challenge`,s),l.searchParams.set(`code_challenge_method`,`S256`),l.searchParams.set(`state`,c),l.searchParams.set(`scope`,j),console.log(`Opening your browser to sign in...\n${l.toString()}`),await p(l.toString());let{code:u}=await L(r,c,A),d=new URLSearchParams({grant_type:`authorization_code`,code:u,redirect_uri:i,client_id:a,code_verifier:o}),f=await fetch(t.tokenEndpoint,{method:`POST`,headers:{"content-type":`application/x-www-form-urlencoded`},body:d.toString()});if(!f.ok)throw Error(`Token exchange failed (${f.status.toString()}).`);let m=await R(f);if(!m?.refreshToken)throw Error(`Token exchange did not return a refresh token.`);return{accessToken:m.accessToken,refreshToken:m.refreshToken,expiresAt:Date.now()+m.expiresIn*1e3,user:z(m.accessToken)}}async function ae(e){if(!e.client||!e.session)throw Error("Session expired. Run `picked login`.");let t=await M(e.apiUrl),n=new URLSearchParams({grant_type:`refresh_token`,refresh_token:e.session.refreshToken,client_id:e.client.clientId}),r;try{r=await fetch(t.tokenEndpoint,{method:`POST`,headers:{"content-type":`application/x-www-form-urlencoded`},body:n.toString()})}catch{throw Error("Session expired. Run `picked login`.")}if(!r.ok)throw Error("Session expired. Run `picked login`.");let i=await R(r);if(!i)throw Error("Session expired. Run `picked login`.");return{accessToken:i.accessToken,refreshToken:i.refreshToken??e.session.refreshToken,expiresAt:Date.now()+i.expiresIn*1e3,user:e.session.user}}var V=`https://api.picked.app`;async function H(e=process.cwd()){let n=process.env.PICKED_API_URL;if(n)return(0,t.normalizeApiUrl)(n);let r=await(0,t.loadPickedConfig)(e);return(0,t.normalizeApiUrl)(r?.apiUrl??V)}async function U(e){let t=await H(e?.cwd);try{let e=await B(t);await w(t,e);let n=e.user?.email??e.user?.id??`unknown user`;return console.log(`Logged in as ${n} (${t})`),0}catch(e){let t=e instanceof Error?e.message:String(e);return console.error(t),1}}async function W(e){let t=await H(e?.cwd);return await ne(t),console.log(`Logged out of ${t}.`),0}async function G(e){let n=e?.cwd??process.cwd(),r=await(0,t.loadPickedConfig)(n);if(!r)return console.error(`No picked.config.{ts,js,json} found in the current directory.`),1;let i=await H(n);console.log(`API: ${i}`),console.log(`Config default: project ${r.projectId} (source: ${r.source??`published`})`);let a=await(0,t.readActiveSelection)(n,i);if(!a)return console.log(`Active selection: none (using the config default).`),0;if(!a.workspace)return console.log(`Active selection: live (published) in project ${a.projectId}`),0;let{name:o,status:s,source:c}=a.workspace;return console.log(`Active selection: ${o} [${s}] in project ${a.projectId} (source: ${c})`),0}async function K(e){let t=await H(e?.cwd),n=await x(t);if(!n?.session)return console.error(`Not logged in to ${t}. Run \`picked login\`.`),1;let{user:r}=n.session,i=r?.email??r?.id??`unknown user`;return console.log(`${i} (${t})`),0}var q=6e4;async function J(e){let t=await x(e);if(!t?.session)throw Error(`Not logged in to ${e}. Run \`picked login\`.`);if(t.session.expiresAt-Date.now()>q)return t.session.accessToken;let n=await ae(t);return await w(e,n),n.accessToken}var oe=(0,l.graphql)(`
|
|
2
|
+
query PickedWorkspaces {
|
|
3
|
+
user {
|
|
4
|
+
organizations(first: 50) {
|
|
5
|
+
edges {
|
|
6
|
+
node {
|
|
7
|
+
id
|
|
8
|
+
name
|
|
9
|
+
slug
|
|
10
|
+
projects(first: 100) {
|
|
11
|
+
edges {
|
|
12
|
+
node {
|
|
13
|
+
id
|
|
14
|
+
name
|
|
15
|
+
liveWorkspace {
|
|
16
|
+
id
|
|
17
|
+
}
|
|
18
|
+
liveWorkspaceVersion {
|
|
19
|
+
id
|
|
20
|
+
}
|
|
21
|
+
workspaces(first: 100) {
|
|
22
|
+
edges {
|
|
23
|
+
node {
|
|
24
|
+
id
|
|
25
|
+
name
|
|
26
|
+
status
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
`),se=(0,l.graphql)(`
|
|
39
|
+
query PickedPreviewToken($id: ID!, $projectId: ID!) {
|
|
40
|
+
workspace(id: $id, projectId: $projectId) {
|
|
41
|
+
id
|
|
42
|
+
name
|
|
43
|
+
status
|
|
44
|
+
previewToken
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
`);async function Y(e,t){let n=await(0,l.createAdminApiClient)({apiUrl:e,token:t}).request(oe,{});if(!n.user)throw Error(`Not authenticated, or no organizations are visible to this account.`);return n.user.organizations.edges.map(e=>{let t=e.node;return{id:t.id,name:t.name,slug:t.slug??``,projects:t.projects.edges.map(e=>{let t=e.node;return{id:t.id,name:t.name,liveWorkspaceId:t.liveWorkspace?.id??null,liveVersionId:t.liveWorkspaceVersion?.id??null,workspaces:t.workspaces.edges.map(e=>({id:e.node.id,name:e.node.name,status:e.node.status}))}})}})}async function X(e,t,n,r){let i=(await(0,l.createAdminApiClient)({apiUrl:e,token:t}).request(se,{id:r,projectId:n})).workspace;if(!i)throw Error(`Workspace "${r}" was not found in project "${n}".`);return{status:i.status,name:i.name,previewToken:i.previewToken}}function ce(e){for(let t of e){console.log(`${t.name} (${t.slug})`);for(let e of t.projects){console.log(` ${e.name} [${e.id}]`);for(let t of e.workspaces){let n=t.status===`LIVE`||t.id===e.liveWorkspaceId?` (live)`:``;console.log(` ${t.name} [${t.status}]${n}`)}}}}async function Z(e){try{let t=await H(e?.cwd),n=await Y(t,await J(t));return e?.json?(console.log(JSON.stringify(n,null,2)),0):(ce(n),0)}catch(e){let t=e instanceof Error?e.message:String(e);return console.error(t),1}}function le(e,t){return new Promise(n=>{e.question(t,n)})}async function Q(e,t){if(t.length===0)throw Error(`No choices available to select from.`);let n=(0,u.createInterface)({input:process.stdin,output:process.stderr});process.stderr.write(`${e}\n`),t.forEach((e,t)=>{process.stderr.write(` ${(t+1).toString()}. ${e.label}\n`)});try{for(;;){let e=await le(n,`Enter a number (1-${t.length.toString()}): `),r=Number.parseInt(e,10),i=Number.isInteger(r)?t[r-1]:void 0;if(i)return i.value;process.stderr.write(`Invalid choice, try again.
|
|
48
|
+
`)}}finally{n.close()}}function $(e,t,n){return{projectId:e,workspace:{id:t,name:n.name,status:n.status,source:`preview`,previewToken:n.previewToken}}}async function ue(e,t,n,r){return r?$(n,r,await X(e,t,n,r)):{projectId:n}}async function de(e,t){let n=await Q(`Select a project`,(await Y(e,t)).flatMap(e=>e.projects.map(t=>({label:`${e.name} / ${t.name}`,value:t})))),r=n.workspaces.map(e=>({label:`${e.name} [${e.status}]`,value:e}));n.liveVersionId&&r.unshift({label:`Published (live version)`,value:null});let i=await Q(`Select a workspace`,r);if(!i)return{projectId:n.id};i.status===`ARCHIVED`&&console.error(`Warning: archived workspaces may fail to load via the delivery API.`);let a=await X(e,t,n.id,i.id);return $(n.id,i.id,a)}function fe(e){if(!e.workspace){console.log(`Active workspace: live (published) in project ${e.projectId}`);return}let{name:t,status:n,source:r}=e.workspace;console.log(`Active workspace: ${t} [${n}] in project ${e.projectId} (source: ${r})`)}async function pe(e){let n=e?.cwd??process.cwd();try{let r=await H(n),i=await J(r),a=e?.project?await ue(r,i,e.project,e.workspace):await de(r,i);return await(0,t.writeActiveSelection)(n,r,a),fe(a),e?.generate!==!1&&await d({cwd:n}),0}catch(e){let t=e instanceof Error?e.message:String(e);return console.error(t),1}}Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return W}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return G}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return Z}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return U}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return K}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return pe}});
|
|
@@ -7,7 +7,7 @@ import { chmod as l, mkdir as u, readFile as d, rename as f, rm as p, writeFile
|
|
|
7
7
|
import { dirname as ee, join as h } from "node:path";
|
|
8
8
|
import { createHash as g, randomBytes as _ } from "node:crypto";
|
|
9
9
|
import { homedir as te } from "node:os";
|
|
10
|
-
import {
|
|
10
|
+
import { createAdminApiClient as v, graphql as y } from "@picked/admin-api-client";
|
|
11
11
|
import { createInterface as b } from "node:readline";
|
|
12
12
|
//#region src/commands/generate-types.ts
|
|
13
13
|
async function x(t) {
|
|
@@ -163,7 +163,7 @@ async function V(e) {
|
|
|
163
163
|
};
|
|
164
164
|
}
|
|
165
165
|
async function H(e, t, n) {
|
|
166
|
-
if (!t.registrationEndpoint) throw Error("OAuth client registration is not available for this Picked API.
|
|
166
|
+
if (!t.registrationEndpoint) throw Error("OAuth client registration is not available for this Picked API.");
|
|
167
167
|
let r = await fetch(t.registrationEndpoint, {
|
|
168
168
|
method: "POST",
|
|
169
169
|
headers: { "content-type": "application/json" },
|
|
@@ -353,7 +353,6 @@ async function me(e) {
|
|
|
353
353
|
//#endregion
|
|
354
354
|
//#region src/commands/whoami.ts
|
|
355
355
|
async function he(e) {
|
|
356
|
-
if (process.env.PICKED_TOKEN) return console.log("Using PICKED_TOKEN from environment."), 0;
|
|
357
356
|
let t = await J(e?.cwd), n = await D(t);
|
|
358
357
|
if (!n?.session) return console.error(`Not logged in to ${t}. Run \`picked login\`.`), 1;
|
|
359
358
|
let { user: r } = n.session, i = r?.email ?? r?.id ?? "unknown user";
|
|
@@ -363,13 +362,11 @@ async function he(e) {
|
|
|
363
362
|
//#region src/auth/session.ts
|
|
364
363
|
var ge = 6e4;
|
|
365
364
|
async function Y(e) {
|
|
366
|
-
let t =
|
|
367
|
-
if (t)
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
let r = await ue(n);
|
|
372
|
-
return await A(e, r), r.accessToken;
|
|
365
|
+
let t = await D(e);
|
|
366
|
+
if (!t?.session) throw Error(`Not logged in to ${e}. Run \`picked login\`.`);
|
|
367
|
+
if (t.session.expiresAt - Date.now() > ge) return t.session.accessToken;
|
|
368
|
+
let n = await ue(t);
|
|
369
|
+
return await A(e, n), n.accessToken;
|
|
373
370
|
}
|
|
374
371
|
//#endregion
|
|
375
372
|
//#region src/lib/workspaces.ts
|
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@picked/cli",
|
|
3
3
|
"description": "Picked command-line interface for local development workflows",
|
|
4
|
-
"version": "0.0.1-dev.
|
|
4
|
+
"version": "0.0.1-dev.1787537193674",
|
|
5
5
|
"bin": {
|
|
6
6
|
"picked": "dist/esm/cli.js"
|
|
7
7
|
},
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@picked/admin-api-client": "0.0.1-dev.
|
|
10
|
-
"@picked/config": "0.0.1-dev.
|
|
11
|
-
"@picked/
|
|
9
|
+
"@picked/admin-api-client": "0.0.1-dev.1787537193674",
|
|
10
|
+
"@picked/config": "0.0.1-dev.1787537193674",
|
|
11
|
+
"@picked/telemetry": "0.0.1-dev.1787537193674",
|
|
12
|
+
"@picked/typegen": "0.0.1-dev.1787537193674"
|
|
12
13
|
},
|
|
13
14
|
"devDependencies": {
|
|
14
15
|
"@repo/eslint-config": "workspace:*",
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
let e=require("@picked/typegen"),t=require("@picked/config"),n=require("node:http"),r=require("node:child_process"),i=require("node:fs"),a=require("node:fs/promises"),o=require("node:path"),s=require("node:crypto"),c=require("node:os"),l=require("@picked/admin-api-client"),u=require("node:readline");async function d(n){let r=n?.cwd??process.cwd(),i=await(0,t.loadResolvedPickedConfig)(r);if(!i)return console.error(`No picked.config.{ts,js,json} found in the current directory.`),1;try{let t=await(0,e.generate)({config:i,check:n?.check??!1,onWarn:e=>{console.warn(e)}});return n?.check?t.changed?(console.error(`Types are out of date: ${t.typesOutput}`),1):(console.log(`Types are up to date (${t.typesOutput}).`),0):(console.log(`Generated types at ${t.typesOutput}`),0)}catch(e){let t=e instanceof Error?e.message:String(e);return console.error(t),1}}function f(e){return process.platform===`darwin`?{command:`open`,args:[e]}:process.platform===`win32`?{command:`cmd`,args:[`/c`,`start`,`""`,e]}:{command:`xdg-open`,args:[e]}}function p(e){let{command:t,args:n}=f(e);try{let e=(0,r.spawn)(t,n,{detached:!0,stdio:`ignore`});e.on(`error`,()=>void 0),e.unref()}catch{}return Promise.resolve()}var m=8;function ee(){return(0,o.join)((0,c.homedir)(),`.picked`)}function h(e){let n=(0,t.normalizeApiUrl)(e),{hostname:r,port:i}=new URL(n);return`${(i?`${r}-${i}`:r).replace(/[^a-z0-9.-]/gi,`_`)}-${(0,s.createHash)(`sha256`).update(n).digest(`hex`).slice(0,m)}`}function g(e){return(0,o.join)(ee(),`auth`,`${h(e)}.json`)}var _=384;function v(e){return typeof e==`object`&&!!e&&`clientId`in e&&typeof e.clientId==`string`&&`redirectUri`in e&&typeof e.redirectUri==`string`}function y(e){return!(typeof e!=`object`||!e||!(`accessToken`in e)||typeof e.accessToken!=`string`||!(`refreshToken`in e)||typeof e.refreshToken!=`string`||!(`expiresAt`in e)||typeof e.expiresAt!=`number`||`user`in e&&e.user!==void 0&&(typeof e.user!=`object`||e.user===null))}function b(e){return!(typeof e!=`object`||!e||!(`apiUrl`in e)||typeof e.apiUrl!=`string`||`client`in e&&e.client!==void 0&&!v(e.client)||`session`in e&&e.session!==void 0&&!y(e.session))}async function x(e){let t=g(e);if(!(0,i.existsSync)(t))return null;try{let e=JSON.parse(await(0,a.readFile)(t,`utf8`));return b(e)?e:null}catch{return null}}async function S(e){let t=g(e.apiUrl);await(0,a.mkdir)((0,o.dirname)(t),{recursive:!0});let n=`${t}.${process.pid.toString()}.tmp`;await(0,a.writeFile)(n,`${JSON.stringify(e,null,2)}\n`,{encoding:`utf8`,mode:_}),await(0,a.chmod)(n,_),await(0,a.rename)(n,t)}async function C(e,n){let r=await x(e);await S({apiUrl:(0,t.normalizeApiUrl)(e),client:r?.client,session:r?.session,...n})}async function te(e,t){await C(e,{client:t})}async function w(e,t){await C(e,{session:t})}async function ne(e){await(0,a.rm)(g(e),{force:!0})}var re=32,ie=16;function T(e){return e.toString(`base64`).replaceAll(`+`,`-`).replaceAll(`/`,`_`).replaceAll(`=`,``)}function E(){return T((0,s.randomBytes)(re))}function D(e){return T((0,s.createHash)(`sha256`).update(e).digest())}function O(){return T((0,s.randomBytes)(ie))}var k=[8976,8977,8988],A=18e4,j=`openid profile email`;async function M(e){let t;try{t=await fetch(`${e}/.well-known/oauth-authorization-server`)}catch(e){let t=e instanceof Error?e.message:String(e);throw Error(`Failed to reach the Picked OAuth discovery endpoint: ${t}`)}if(!t.ok)throw Error(`OAuth discovery request failed (${t.status.toString()}).`);let n=await t.json();if(typeof n!=`object`||!n)throw Error(`Malformed OAuth discovery document.`);if(!(`authorization_endpoint`in n)||typeof n.authorization_endpoint!=`string`)throw Error(`OAuth discovery document is missing authorization_endpoint.`);if(!(`token_endpoint`in n)||typeof n.token_endpoint!=`string`)throw Error(`OAuth discovery document is missing token_endpoint.`);let r=`registration_endpoint`in n&&typeof n.registration_endpoint==`string`?n.registration_endpoint:void 0,i=`code_challenge_methods_supported`in n&&Array.isArray(n.code_challenge_methods_supported)?n.code_challenge_methods_supported.filter(e=>typeof e==`string`):void 0;return{authorizationEndpoint:n.authorization_endpoint,tokenEndpoint:n.token_endpoint,registrationEndpoint:r,codeChallengeMethods:i}}async function N(e,t,n){if(!t.registrationEndpoint)throw Error("OAuth client registration is not available for this Picked API. Set PICKED_TOKEN instead of running `picked login`.");let r=await fetch(t.registrationEndpoint,{method:`POST`,headers:{"content-type":`application/json`},body:JSON.stringify({client_name:`Picked CLI`,redirect_uris:[n],grant_types:[`authorization_code`,`refresh_token`],response_types:[`code`],token_endpoint_auth_method:`none`})});if(!r.ok)throw Error(`OAuth client registration failed (${r.status.toString()}).`);let i=await r.json();if(typeof i!=`object`||!i||!(`client_id`in i)||typeof i.client_id!=`string`)throw Error(`OAuth client registration returned an unexpected response.`);return await te(e,{clientId:i.client_id,redirectUri:n}),i.client_id}async function P(e,t,n){let r=(await x(e))?.client;return r?.redirectUri===n?r.clientId:N(e,t,n)}function F(e,t){return new Promise(n=>{let r=()=>{e.removeListener(`error`,r),n(!1)};e.once(`error`,r),e.listen(t,`127.0.0.1`,()=>{e.removeListener(`error`,r),n(!0)})})}async function I(e){for(let t of k)if(await F(e,t))return t;throw Error(`No loopback port available for the OAuth callback (tried ${k.join(`, `)}).`)}function L(e,t,n){return new Promise((r,i)=>{let a=()=>{clearTimeout(o),process.removeListener(`SIGINT`,s),e.close()},o=setTimeout(()=>{a(),i(Error(`Timed out waiting for the browser sign-in to complete.`))},n),s=()=>{a(),i(Error(`Sign-in cancelled.`))};process.once(`SIGINT`,s),e.on(`request`,(e,n)=>{let o=new URL(e.url??`/`,`http://127.0.0.1`);if(o.pathname!==`/callback`){n.writeHead(404),n.end();return}let s=o.searchParams.get(`error`);if(s){n.writeHead(200,{"content-type":`text/html`}),n.end(`<html><body>Sign-in failed. You can close this tab.</body></html>`),a(),i(Error(`Authorization failed: ${s}`));return}let c=o.searchParams.get(`code`),l=o.searchParams.get(`state`);if(!c||l!==t){n.writeHead(400,{"content-type":`text/html`}),n.end(`<html><body>Invalid sign-in response. Close this tab and try again.</body></html>`),a(),i(Error(`Invalid OAuth callback: missing code or state mismatch.`));return}n.writeHead(200,{"content-type":`text/html`}),n.end(`<html><body>Signed in. You can close this tab and return to the terminal.</body></html>`),a(),r({code:c})})})}async function R(e){let t;try{t=await e.json()}catch{return null}if(typeof t!=`object`||!t||!(`access_token`in t)||typeof t.access_token!=`string`||!(`expires_in`in t)||typeof t.expires_in!=`number`)return null;let n=`refresh_token`in t&&typeof t.refresh_token==`string`?t.refresh_token:void 0;return{accessToken:t.access_token,refreshToken:n,expiresIn:t.expires_in}}function z(e){let t=e.split(`.`),n=t[1];if(t.length!==3||!n)return{};try{let e=JSON.parse(Buffer.from(n,`base64url`).toString(`utf8`));return typeof e!=`object`||!e?{}:{id:`sub`in e&&typeof e.sub==`string`?e.sub:void 0,email:`email`in e&&typeof e.email==`string`?e.email:void 0}}catch{return{}}}async function B(e){let t=await M(e),r=(0,n.createServer)(),i=`http://127.0.0.1:${(await I(r)).toString()}/callback`,a=await P(e,t,i),o=E(),s=D(o),c=O(),l=new URL(t.authorizationEndpoint);l.searchParams.set(`response_type`,`code`),l.searchParams.set(`client_id`,a),l.searchParams.set(`redirect_uri`,i),l.searchParams.set(`code_challenge`,s),l.searchParams.set(`code_challenge_method`,`S256`),l.searchParams.set(`state`,c),l.searchParams.set(`scope`,j),console.log(`Opening your browser to sign in...\n${l.toString()}`),await p(l.toString());let{code:u}=await L(r,c,A),d=new URLSearchParams({grant_type:`authorization_code`,code:u,redirect_uri:i,client_id:a,code_verifier:o}),f=await fetch(t.tokenEndpoint,{method:`POST`,headers:{"content-type":`application/x-www-form-urlencoded`},body:d.toString()});if(!f.ok)throw Error(`Token exchange failed (${f.status.toString()}).`);let m=await R(f);if(!m?.refreshToken)throw Error(`Token exchange did not return a refresh token.`);return{accessToken:m.accessToken,refreshToken:m.refreshToken,expiresAt:Date.now()+m.expiresIn*1e3,user:z(m.accessToken)}}async function ae(e){if(!e.client||!e.session)throw Error("Session expired. Run `picked login`.");let t=await M(e.apiUrl),n=new URLSearchParams({grant_type:`refresh_token`,refresh_token:e.session.refreshToken,client_id:e.client.clientId}),r;try{r=await fetch(t.tokenEndpoint,{method:`POST`,headers:{"content-type":`application/x-www-form-urlencoded`},body:n.toString()})}catch{throw Error("Session expired. Run `picked login`.")}if(!r.ok)throw Error("Session expired. Run `picked login`.");let i=await R(r);if(!i)throw Error("Session expired. Run `picked login`.");return{accessToken:i.accessToken,refreshToken:i.refreshToken??e.session.refreshToken,expiresAt:Date.now()+i.expiresIn*1e3,user:e.session.user}}var V=`https://api.picked.app`;async function H(e=process.cwd()){let n=process.env.PICKED_API_URL;if(n)return(0,t.normalizeApiUrl)(n);let r=await(0,t.loadPickedConfig)(e);return(0,t.normalizeApiUrl)(r?.apiUrl??V)}async function U(e){let t=await H(e?.cwd);try{let e=await B(t);await w(t,e);let n=e.user?.email??e.user?.id??`unknown user`;return console.log(`Logged in as ${n} (${t})`),0}catch(e){let t=e instanceof Error?e.message:String(e);return console.error(t),1}}async function W(e){let t=await H(e?.cwd);return await ne(t),console.log(`Logged out of ${t}.`),0}async function G(e){let n=e?.cwd??process.cwd(),r=await(0,t.loadPickedConfig)(n);if(!r)return console.error(`No picked.config.{ts,js,json} found in the current directory.`),1;let i=await H(n);console.log(`API: ${i}`),console.log(`Config default: project ${r.projectId} (source: ${r.source??`published`})`);let a=await(0,t.readActiveSelection)(n,i);if(!a)return console.log(`Active selection: none (using the config default).`),0;if(!a.workspace)return console.log(`Active selection: live (published) in project ${a.projectId}`),0;let{name:o,status:s,source:c}=a.workspace;return console.log(`Active selection: ${o} [${s}] in project ${a.projectId} (source: ${c})`),0}async function K(e){if(process.env.PICKED_TOKEN)return console.log(`Using PICKED_TOKEN from environment.`),0;let t=await H(e?.cwd),n=await x(t);if(!n?.session)return console.error(`Not logged in to ${t}. Run \`picked login\`.`),1;let{user:r}=n.session,i=r?.email??r?.id??`unknown user`;return console.log(`${i} (${t})`),0}var q=6e4;async function J(e){let t=process.env.PICKED_TOKEN;if(t)return t;let n=await x(e);if(!n?.session)throw Error(`Not logged in to ${e}. Run \`picked login\` (or set PICKED_TOKEN).`);if(n.session.expiresAt-Date.now()>q)return n.session.accessToken;let r=await ae(n);return await w(e,r),r.accessToken}var oe=(0,l.graphql)(`
|
|
2
|
-
query PickedWorkspaces {
|
|
3
|
-
user {
|
|
4
|
-
organizations(first: 50) {
|
|
5
|
-
edges {
|
|
6
|
-
node {
|
|
7
|
-
id
|
|
8
|
-
name
|
|
9
|
-
slug
|
|
10
|
-
projects(first: 100) {
|
|
11
|
-
edges {
|
|
12
|
-
node {
|
|
13
|
-
id
|
|
14
|
-
name
|
|
15
|
-
liveWorkspace {
|
|
16
|
-
id
|
|
17
|
-
}
|
|
18
|
-
liveWorkspaceVersion {
|
|
19
|
-
id
|
|
20
|
-
}
|
|
21
|
-
workspaces(first: 100) {
|
|
22
|
-
edges {
|
|
23
|
-
node {
|
|
24
|
-
id
|
|
25
|
-
name
|
|
26
|
-
status
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
`),se=(0,l.graphql)(`
|
|
39
|
-
query PickedPreviewToken($id: ID!, $projectId: ID!) {
|
|
40
|
-
workspace(id: $id, projectId: $projectId) {
|
|
41
|
-
id
|
|
42
|
-
name
|
|
43
|
-
status
|
|
44
|
-
previewToken
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
`);async function Y(e,t){let n=await(0,l.createClient)({apiUrl:e,token:t}).request(oe,{});if(!n.user)throw Error(`Not authenticated, or no organizations are visible to this account.`);return n.user.organizations.edges.map(e=>{let t=e.node;return{id:t.id,name:t.name,slug:t.slug??``,projects:t.projects.edges.map(e=>{let t=e.node;return{id:t.id,name:t.name,liveWorkspaceId:t.liveWorkspace?.id??null,liveVersionId:t.liveWorkspaceVersion?.id??null,workspaces:t.workspaces.edges.map(e=>({id:e.node.id,name:e.node.name,status:e.node.status}))}})}})}async function X(e,t,n,r){let i=(await(0,l.createClient)({apiUrl:e,token:t}).request(se,{id:r,projectId:n})).workspace;if(!i)throw Error(`Workspace "${r}" was not found in project "${n}".`);return{status:i.status,name:i.name,previewToken:i.previewToken}}function ce(e){for(let t of e){console.log(`${t.name} (${t.slug})`);for(let e of t.projects){console.log(` ${e.name} [${e.id}]`);for(let t of e.workspaces){let n=t.status===`LIVE`||t.id===e.liveWorkspaceId?` (live)`:``;console.log(` ${t.name} [${t.status}]${n}`)}}}}async function Z(e){try{let t=await H(e?.cwd),n=await Y(t,await J(t));return e?.json?(console.log(JSON.stringify(n,null,2)),0):(ce(n),0)}catch(e){let t=e instanceof Error?e.message:String(e);return console.error(t),1}}function le(e,t){return new Promise(n=>{e.question(t,n)})}async function Q(e,t){if(t.length===0)throw Error(`No choices available to select from.`);let n=(0,u.createInterface)({input:process.stdin,output:process.stderr});process.stderr.write(`${e}\n`),t.forEach((e,t)=>{process.stderr.write(` ${(t+1).toString()}. ${e.label}\n`)});try{for(;;){let e=await le(n,`Enter a number (1-${t.length.toString()}): `),r=Number.parseInt(e,10),i=Number.isInteger(r)?t[r-1]:void 0;if(i)return i.value;process.stderr.write(`Invalid choice, try again.
|
|
48
|
-
`)}}finally{n.close()}}function $(e,t,n){return{projectId:e,workspace:{id:t,name:n.name,status:n.status,source:`preview`,previewToken:n.previewToken}}}async function ue(e,t,n,r){return r?$(n,r,await X(e,t,n,r)):{projectId:n}}async function de(e,t){let n=await Q(`Select a project`,(await Y(e,t)).flatMap(e=>e.projects.map(t=>({label:`${e.name} / ${t.name}`,value:t})))),r=n.workspaces.map(e=>({label:`${e.name} [${e.status}]`,value:e}));n.liveVersionId&&r.unshift({label:`Published (live version)`,value:null});let i=await Q(`Select a workspace`,r);if(!i)return{projectId:n.id};i.status===`ARCHIVED`&&console.error(`Warning: archived workspaces may fail to load via the delivery API.`);let a=await X(e,t,n.id,i.id);return $(n.id,i.id,a)}function fe(e){if(!e.workspace){console.log(`Active workspace: live (published) in project ${e.projectId}`);return}let{name:t,status:n,source:r}=e.workspace;console.log(`Active workspace: ${t} [${n}] in project ${e.projectId} (source: ${r})`)}async function pe(e){let n=e?.cwd??process.cwd();try{let r=await H(n),i=await J(r),a=e?.project?await ue(r,i,e.project,e.workspace):await de(r,i);return await(0,t.writeActiveSelection)(n,r,a),fe(a),e?.generate!==!1&&await d({cwd:n}),0}catch(e){let t=e instanceof Error?e.message:String(e);return console.error(t),1}}Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return W}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return G}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return Z}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return U}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return K}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return pe}});
|