@usesocial/cli 0.11.0 → 0.11.2
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/CHANGELOG.md +12 -0
- package/dist/index.mjs +38 -17
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @usesocial/cli
|
|
2
2
|
|
|
3
|
+
## 0.11.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#46](https://github.com/usesocial/monorepo/pull/46) [`88f7b42`](https://github.com/usesocial/monorepo/commit/88f7b42abaec62175fb6ca030e301c8497601901) Thanks [@CyrusNuevoDia](https://github.com/CyrusNuevoDia)! - Fix `social account connect x` so it finishes when OAuth refreshes an already-connected X account instead of waiting until timeout.
|
|
8
|
+
|
|
9
|
+
## 0.11.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#45](https://github.com/usesocial/monorepo/pull/45) [`940ff35`](https://github.com/usesocial/monorepo/commit/940ff356c07cd1f1a01be059b022eafcb5a82a1b) Thanks [@CyrusNuevoDia](https://github.com/CyrusNuevoDia)! - Create the server-side CLI session grant after non-TTY device login approval so read/write device sessions are not reported locally as write-capable while the API still treats them as read-only.
|
|
14
|
+
|
|
3
15
|
## 0.11.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
package/dist/index.mjs
CHANGED
|
@@ -18702,6 +18702,7 @@ const prepareAccountConnect = async (deps) => {
|
|
|
18702
18702
|
await pollForSeat$1(deps);
|
|
18703
18703
|
};
|
|
18704
18704
|
const accountKey = (account) => account.profileId;
|
|
18705
|
+
const timestampMS = (value) => value instanceof Date ? value.getTime() : void 0;
|
|
18705
18706
|
const normalizeIdentifier = (value) => value.trim().replace(/^@+/, "").toLowerCase();
|
|
18706
18707
|
const accountSelectorFor$1 = (account) => account.username ? `@${account.username.replace(/^@+/, "")}` : `profile_id:${account.profileId}`;
|
|
18707
18708
|
const assertXAccountSelector = (target) => {
|
|
@@ -18733,13 +18734,20 @@ const createXConnectURL = (deps, reconnectProfileId) => connectURLFor(deps, reco
|
|
|
18733
18734
|
const connectXAccount = async (deps) => {
|
|
18734
18735
|
const before = await listXLifecycleAccounts(deps, true);
|
|
18735
18736
|
const connectedBefore = new Set(before.filter((account) => account.status === "connected").map(accountKey));
|
|
18737
|
+
const lastSeenBefore = new Map(before.filter((account) => account.status === "connected").map((account) => [accountKey(account), timestampMS(account.lastSeenAt)]));
|
|
18736
18738
|
await prepareAccountConnect(deps);
|
|
18737
18739
|
const authURL = await authURLFor(deps, () => connectURLFor(deps));
|
|
18738
18740
|
await openOrPrint(deps, authURL.url, { log: !authURL.openingLogged });
|
|
18739
18741
|
return {
|
|
18740
18742
|
platform: "x",
|
|
18741
18743
|
status: "connected",
|
|
18742
|
-
account: await pollForAccount(deps, (candidate) =>
|
|
18744
|
+
account: await pollForAccount(deps, (candidate) => {
|
|
18745
|
+
if (candidate.status !== "connected") return false;
|
|
18746
|
+
if (!connectedBefore.has(candidate.profileId)) return true;
|
|
18747
|
+
const previousLastSeen = lastSeenBefore.get(candidate.profileId);
|
|
18748
|
+
const currentLastSeen = timestampMS(candidate.lastSeenAt);
|
|
18749
|
+
return previousLastSeen !== void 0 && currentLastSeen !== void 0 && currentLastSeen > previousLastSeen;
|
|
18750
|
+
})
|
|
18743
18751
|
};
|
|
18744
18752
|
};
|
|
18745
18753
|
const reconnectXAccount = async (deps, args) => {
|
|
@@ -21414,7 +21422,7 @@ function createEnv(opts) {
|
|
|
21414
21422
|
}
|
|
21415
21423
|
//#endregion
|
|
21416
21424
|
//#region package.json
|
|
21417
|
-
var version$1 = "0.11.
|
|
21425
|
+
var version$1 = "0.11.2";
|
|
21418
21426
|
//#endregion
|
|
21419
21427
|
//#region src/lib/env.ts
|
|
21420
21428
|
const URLWithTrailingSlash = url().transform(ensureTrailingSlash);
|
|
@@ -28783,13 +28791,16 @@ const errorOutput = (error) => ({
|
|
|
28783
28791
|
const isInteractiveTerminal = () => process.stdin.isTTY === true && process.stdout.isTTY === true;
|
|
28784
28792
|
const nextCommands = ["social account connect linkedin", "social account connect x"];
|
|
28785
28793
|
const deviceExpiredMessage = "Sign-in expired before approval. Run `social account login` again to restart.";
|
|
28794
|
+
const scopeUpgradeRequiresReauthorization = "Existing CLI session is read-only. Run `social account logout`, then `social account login` to approve a new write-capable session.";
|
|
28795
|
+
const scopeAliasIncludes = (granted, requested) => granted === requested || granted === "read,write";
|
|
28786
28796
|
/**
|
|
28787
28797
|
* Drive one step of the non-TTY device-authorization login and map it onto the
|
|
28788
28798
|
* login output union. The first call starts the device flow and returns
|
|
28789
28799
|
* `pending_approval`; later calls poll until `logged_in` or `expired`.
|
|
28790
28800
|
*/
|
|
28791
|
-
const deviceLoginOutput = async (loginArgs) => {
|
|
28792
|
-
const
|
|
28801
|
+
const deviceLoginOutput = async (client, loginArgs) => {
|
|
28802
|
+
const scope = parseScopeAlias(loginArgs.scope);
|
|
28803
|
+
const state = await advanceDeviceLogin(scope);
|
|
28793
28804
|
switch (state.status) {
|
|
28794
28805
|
case "pending_approval": return {
|
|
28795
28806
|
status: "pending_approval",
|
|
@@ -28801,7 +28812,10 @@ const deviceLoginOutput = async (loginArgs) => {
|
|
|
28801
28812
|
};
|
|
28802
28813
|
case "logged_in": return {
|
|
28803
28814
|
status: "logged_in",
|
|
28804
|
-
account:
|
|
28815
|
+
account: {
|
|
28816
|
+
...state.account,
|
|
28817
|
+
scope: (await client.cli.session.upsert({ scopeAlias: scope })).scopeAlias
|
|
28818
|
+
},
|
|
28805
28819
|
nextCommands
|
|
28806
28820
|
};
|
|
28807
28821
|
case "expired": return {
|
|
@@ -28891,23 +28905,30 @@ const loginCommand = defineCommand({
|
|
|
28891
28905
|
try {
|
|
28892
28906
|
const client = createORPCAPIClient();
|
|
28893
28907
|
const existing = await readExistingAuthSession(client);
|
|
28894
|
-
if (existing.kind === "existing")
|
|
28895
|
-
|
|
28896
|
-
|
|
28897
|
-
|
|
28898
|
-
|
|
28899
|
-
|
|
28900
|
-
|
|
28901
|
-
|
|
28902
|
-
|
|
28903
|
-
|
|
28904
|
-
|
|
28908
|
+
if (existing.kind === "existing") {
|
|
28909
|
+
const requestedScope = parseScopeAlias(loginArgs.scope);
|
|
28910
|
+
if (!scopeAliasIncludes(existing.session.session.scope, requestedScope)) output = {
|
|
28911
|
+
status: "error",
|
|
28912
|
+
code: "scope_upgrade_requires_reauthorization",
|
|
28913
|
+
message: scopeUpgradeRequiresReauthorization
|
|
28914
|
+
};
|
|
28915
|
+
else if (billingReady(await client.billing.status())) output = alreadyLoggedInOutput(existing.session);
|
|
28916
|
+
else if (isInteractiveTerminal()) output = await runLogin({
|
|
28917
|
+
ui: createUI(true),
|
|
28918
|
+
client,
|
|
28919
|
+
args: loginArgs
|
|
28920
|
+
}, [{
|
|
28921
|
+
name: "seat",
|
|
28922
|
+
run: seatPhase
|
|
28923
|
+
}], { authenticated: true });
|
|
28924
|
+
else output = alreadyLoggedInOutput(existing.session);
|
|
28925
|
+
} else if (existing.kind === "offline") output = offlineOutput();
|
|
28905
28926
|
else if (isInteractiveTerminal()) output = await runLogin({
|
|
28906
28927
|
ui: createUI(true),
|
|
28907
28928
|
client,
|
|
28908
28929
|
args: loginArgs
|
|
28909
28930
|
});
|
|
28910
|
-
else output = await deviceLoginOutput(loginArgs);
|
|
28931
|
+
else output = await deviceLoginOutput(client, loginArgs);
|
|
28911
28932
|
} catch (error) {
|
|
28912
28933
|
output = errorOutput(error);
|
|
28913
28934
|
exitCode = exitCodeFor(error);
|