@sanity/cli 6.1.3 → 6.1.4

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.
@@ -0,0 +1,61 @@
1
+ import { getCliToken } from '@sanity/cli-core';
2
+ import { isHttpError } from '@sanity/client';
3
+ import { LoginError } from '../../errors/LoginError.js';
4
+ import { getCliUser } from '../../services/user.js';
5
+ import { getErrorMessage } from '../../util/getErrorMessage.js';
6
+ import { login } from './login/login.js';
7
+ /**
8
+ * Ensure the user is authenticated. Validates the current token via /users/me
9
+ * and triggers interactive login if the token is missing or invalid.
10
+ *
11
+ * @returns The authenticated user.
12
+ * @throws LoginError if interactive login fails or is cancelled.
13
+ * @throws Error if a network/server error occurs during validation.
14
+ * @internal
15
+ */ export async function ensureAuthenticated(options) {
16
+ const user = await validateSession();
17
+ if (user) return user;
18
+ try {
19
+ await login({
20
+ output: options.output,
21
+ telemetry: options.telemetry
22
+ });
23
+ } catch (cause) {
24
+ throw new LoginError(getErrorMessage(cause), {
25
+ cause
26
+ });
27
+ }
28
+ try {
29
+ return await getCliUser();
30
+ } catch (cause) {
31
+ if (isHttpError(cause) && (cause.statusCode === 401 || cause.statusCode === 403)) {
32
+ throw new LoginError(`Login succeeded but failed to verify session: ${getErrorMessage(cause)}`, {
33
+ cause
34
+ });
35
+ }
36
+ throw cause;
37
+ }
38
+ }
39
+ /**
40
+ * Validate the current CLI auth token by calling /users/me.
41
+ *
42
+ * Returns null only for auth failures (401/403). Re-throws network errors,
43
+ * timeouts, and server errors so callers can handle them appropriately
44
+ * instead of triggering an unnecessary re-login prompt.
45
+ *
46
+ * @returns The authenticated user if valid, null if invalid/missing.
47
+ * @internal
48
+ */ export async function validateSession() {
49
+ const token = await getCliToken();
50
+ if (!token) return null;
51
+ try {
52
+ return await getCliUser();
53
+ } catch (error) {
54
+ if (isHttpError(error) && (error.statusCode === 401 || error.statusCode === 403)) {
55
+ return null;
56
+ }
57
+ throw error;
58
+ }
59
+ }
60
+
61
+ //# sourceMappingURL=ensureAuthenticated.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/actions/auth/ensureAuthenticated.ts"],"sourcesContent":["import {\n type CLITelemetryStore,\n getCliToken,\n type Output,\n type SanityOrgUser,\n} from '@sanity/cli-core'\nimport {isHttpError} from '@sanity/client'\n\nimport {LoginError} from '../../errors/LoginError.js'\nimport {getCliUser} from '../../services/user.js'\nimport {getErrorMessage} from '../../util/getErrorMessage.js'\nimport {login} from './login/login.js'\n\n/**\n * Ensure the user is authenticated. Validates the current token via /users/me\n * and triggers interactive login if the token is missing or invalid.\n *\n * @returns The authenticated user.\n * @throws LoginError if interactive login fails or is cancelled.\n * @throws Error if a network/server error occurs during validation.\n * @internal\n */\nexport async function ensureAuthenticated(options: {\n output: Output\n telemetry: CLITelemetryStore\n}): Promise<SanityOrgUser> {\n const user = await validateSession()\n if (user) return user\n\n try {\n await login({output: options.output, telemetry: options.telemetry})\n } catch (cause) {\n throw new LoginError(getErrorMessage(cause), {cause})\n }\n\n try {\n return await getCliUser()\n } catch (cause) {\n if (isHttpError(cause) && (cause.statusCode === 401 || cause.statusCode === 403)) {\n throw new LoginError(\n `Login succeeded but failed to verify session: ${getErrorMessage(cause)}`,\n {cause},\n )\n }\n throw cause\n }\n}\n\n/**\n * Validate the current CLI auth token by calling /users/me.\n *\n * Returns null only for auth failures (401/403). Re-throws network errors,\n * timeouts, and server errors so callers can handle them appropriately\n * instead of triggering an unnecessary re-login prompt.\n *\n * @returns The authenticated user if valid, null if invalid/missing.\n * @internal\n */\nexport async function validateSession(): Promise<SanityOrgUser | null> {\n const token = await getCliToken()\n if (!token) return null\n\n try {\n return await getCliUser()\n } catch (error) {\n if (isHttpError(error) && (error.statusCode === 401 || error.statusCode === 403)) {\n return null\n }\n throw error\n }\n}\n"],"names":["getCliToken","isHttpError","LoginError","getCliUser","getErrorMessage","login","ensureAuthenticated","options","user","validateSession","output","telemetry","cause","statusCode","token","error"],"mappings":"AAAA,SAEEA,WAAW,QAGN,mBAAkB;AACzB,SAAQC,WAAW,QAAO,iBAAgB;AAE1C,SAAQC,UAAU,QAAO,6BAA4B;AACrD,SAAQC,UAAU,QAAO,yBAAwB;AACjD,SAAQC,eAAe,QAAO,gCAA+B;AAC7D,SAAQC,KAAK,QAAO,mBAAkB;AAEtC;;;;;;;;CAQC,GACD,OAAO,eAAeC,oBAAoBC,OAGzC;IACC,MAAMC,OAAO,MAAMC;IACnB,IAAID,MAAM,OAAOA;IAEjB,IAAI;QACF,MAAMH,MAAM;YAACK,QAAQH,QAAQG,MAAM;YAAEC,WAAWJ,QAAQI,SAAS;QAAA;IACnE,EAAE,OAAOC,OAAO;QACd,MAAM,IAAIV,WAAWE,gBAAgBQ,QAAQ;YAACA;QAAK;IACrD;IAEA,IAAI;QACF,OAAO,MAAMT;IACf,EAAE,OAAOS,OAAO;QACd,IAAIX,YAAYW,UAAWA,CAAAA,MAAMC,UAAU,KAAK,OAAOD,MAAMC,UAAU,KAAK,GAAE,GAAI;YAChF,MAAM,IAAIX,WACR,CAAC,8CAA8C,EAAEE,gBAAgBQ,QAAQ,EACzE;gBAACA;YAAK;QAEV;QACA,MAAMA;IACR;AACF;AAEA;;;;;;;;;CASC,GACD,OAAO,eAAeH;IACpB,MAAMK,QAAQ,MAAMd;IACpB,IAAI,CAACc,OAAO,OAAO;IAEnB,IAAI;QACF,OAAO,MAAMX;IACf,EAAE,OAAOY,OAAO;QACd,IAAId,YAAYc,UAAWA,CAAAA,MAAMF,UAAU,KAAK,OAAOE,MAAMF,UAAU,KAAK,GAAE,GAAI;YAChF,OAAO;QACT;QACA,MAAME;IACR;AACF"}
@@ -10,6 +10,7 @@ import { isHttpError } from '@sanity/client';
10
10
  import { frameworks } from '@vercel/frameworks';
11
11
  import { execa } from 'execa';
12
12
  import deburr from 'lodash-es/deburr.js';
13
+ import { validateSession } from '../actions/auth/ensureAuthenticated.js';
13
14
  import { getProviderName } from '../actions/auth/getProviderName.js';
14
15
  import { login } from '../actions/auth/login/login.js';
15
16
  import { createDataset } from '../actions/dataset/create.js';
@@ -681,49 +682,40 @@ export class InitCommand extends SanityCommand {
681
682
  }
682
683
  // @todo do we actually need to be authenticated for init? check flags and determine.
683
684
  async ensureAuthenticated() {
684
- let isAuthenticated = await getCliToken() !== undefined;
685
- debug(isAuthenticated ? 'User already has a token' : 'User has no token');
686
- let user;
687
- if (isAuthenticated) {
688
- // It _appears_ we are authenticated, but the token might be invalid/expired,
689
- // so we need to verify that we can actually make an authenticated request.
690
- try {
691
- user = await getCliUser();
692
- } catch {
693
- // assume that any error means that the token is invalid
694
- isAuthenticated = false;
695
- }
696
- }
697
- if (isAuthenticated) {
685
+ const user = await validateSession();
686
+ if (user) {
698
687
  this._trace.log({
699
688
  alreadyLoggedIn: true,
700
689
  step: 'login'
701
690
  });
702
- } else {
703
- if (this.isUnattended()) {
704
- this.error('Must be logged in to run this command in unattended mode, run `sanity login`', {
705
- exit: 1
706
- });
707
- }
708
- this._trace.log({
709
- step: 'login'
691
+ this.log(`${logSymbols.success} You are logged in as ${user.email} using ${getProviderName(user.provider)}`);
692
+ return {
693
+ user
694
+ };
695
+ }
696
+ if (this.isUnattended()) {
697
+ this.error('Must be logged in to run this command in unattended mode, run `sanity login`', {
698
+ exit: 1
710
699
  });
711
- try {
712
- await login({
713
- output: this.output,
714
- telemetry: this._trace.newContext('login')
715
- });
716
- } catch (error) {
717
- const message = error instanceof Error ? error.message : String(error);
718
- this.error(`Login failed: ${message}`, {
719
- exit: 1
720
- });
721
- }
722
700
  }
723
- user = await getCliUser();
724
- this.log(`${logSymbols.success} You are logged in as ${user.email} using ${getProviderName(user.provider)}`);
701
+ this._trace.log({
702
+ step: 'login'
703
+ });
704
+ try {
705
+ await login({
706
+ output: this.output,
707
+ telemetry: this._trace.newContext('login')
708
+ });
709
+ } catch (error) {
710
+ const message = error instanceof Error ? error.message : String(error);
711
+ this.error(`Login failed: ${message}`, {
712
+ exit: 1
713
+ });
714
+ }
715
+ const loggedInUser = await getCliUser();
716
+ this.log(`${logSymbols.success} You are logged in as ${loggedInUser.email} using ${getProviderName(loggedInUser.provider)}`);
725
717
  return {
726
- user
718
+ user: loggedInUser
727
719
  };
728
720
  }
729
721
  flagOrDefault(flag, defaultValue) {