@sanity/cli 6.5.3 → 6.6.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 CHANGED
@@ -2489,13 +2489,14 @@ Log in to your Sanity account
2489
2489
 
2490
2490
  ```
2491
2491
  USAGE
2492
- $ sanity login [--open] [--provider <providerId> | --sso <slug>] [--sso-provider <name> ]
2492
+ $ sanity login [--open] [--provider <providerId> | --sso <slug> | --with-token] [--sso-provider <name> ]
2493
2493
 
2494
2494
  FLAGS
2495
2495
  --[no-]open Open a browser window to log in (`--no-open` only prints URL)
2496
2496
  --provider=<providerId> Log in using the given provider
2497
2497
  --sso=<slug> Log in using Single Sign-On, using the given organization slug
2498
2498
  --sso-provider=<name> Select a specific SSO provider by name (use with --sso)
2499
+ --with-token Read token from standard input
2499
2500
 
2500
2501
  DESCRIPTION
2501
2502
  Log in to your Sanity account
@@ -2516,6 +2517,10 @@ EXAMPLES
2516
2517
  Log in using a specific SSO provider within an organization
2517
2518
 
2518
2519
  $ sanity login --sso my-organization --sso-provider "Okta SSO"
2520
+
2521
+ Log in using a token from standard input
2522
+
2523
+ $ sanity login --with-token < token.txt
2519
2524
  ```
2520
2525
 
2521
2526
  ## `sanity logout`
package/bin/run.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import {execute} from '@oclif/core'
2
+ import {execute, settings} from '@oclif/core'
3
3
 
4
4
  var err = '\u001B[31m\u001B[1mERROR:\u001B[22m\u001B[39m '
5
5
  var nodeVersionParts = process.version.replace(/^v/i, '').split('.').map(Number)
@@ -30,4 +30,6 @@ if (!isSupportedNodeVersion(majorVersion, minorVersion, patchVersion)) {
30
30
  process.exit(1)
31
31
  }
32
32
 
33
+ settings.enableAutoTranspile = false
34
+
33
35
  await execute({dir: import.meta.url})
@@ -1,16 +1,19 @@
1
1
  import { getCliToken, getUserConfig, setCliUserConfig, subdebug } from '@sanity/cli-core';
2
2
  import { spinner } from '@sanity/cli-core/ux';
3
+ import { isHttpError } from '@sanity/client';
3
4
  import open from 'open';
4
5
  import { logout } from '../../../services/auth.js';
5
6
  import { LoginTrace } from '../../../telemetry/login.telemetry.js';
6
7
  import { canLaunchBrowser } from '../../../util/canLaunchBrowser.js';
7
8
  import { startServerForTokenCallback } from '../authServer.js';
8
9
  import { getProvider } from './getProvider.js';
10
+ import { isSanityApiToken, validateToken } from './validateToken.js';
9
11
  const debug = subdebug('login');
10
12
  /**
11
13
  * Trigger the authentication flow for the CLI.
12
14
  *
13
- * NOTE: This uses terminal prompts and will not work for non-interactive/programmatic uses.
15
+ * NOTE: Without a token option, this uses terminal prompts and will not work for
16
+ * non-interactive/programmatic uses.
14
17
  *
15
18
  * @param options - Options for the login operation
16
19
  * @returns Promise that resolves when the login operation is complete
@@ -19,9 +22,19 @@ const debug = subdebug('login');
19
22
  */ export async function login(options) {
20
23
  const { output, telemetry } = options;
21
24
  const previousToken = await getCliToken();
22
- const hasExistingToken = Boolean(previousToken);
23
25
  const trace = telemetry.trace(LoginTrace);
24
26
  trace.start();
27
+ if (typeof options.token === 'string') {
28
+ try {
29
+ const authToken = await validateToken(options.token);
30
+ await storeAuthToken(authToken, previousToken, output);
31
+ trace.complete();
32
+ } catch (err) {
33
+ trace.error(err);
34
+ throw err;
35
+ }
36
+ return;
37
+ }
25
38
  const provider = await getProvider({
26
39
  experimental: options.experimental,
27
40
  orgSlug: options.sso,
@@ -62,20 +75,30 @@ const debug = subdebug('login');
62
75
  server.close(()=>resolve());
63
76
  });
64
77
  }
65
- // Store the token
78
+ await storeAuthToken(authToken, previousToken, output);
79
+ trace.complete();
80
+ }
81
+ async function storeAuthToken(authToken, previousToken, output) {
66
82
  setCliUserConfig('authToken', authToken);
67
- // Clear cached telemetry consent
68
83
  getUserConfig().delete('telemetryConsent');
69
84
  // If we had a session previously, attempt to clear it
70
- if (hasExistingToken) {
71
- await logout(previousToken).catch((err)=>{
72
- const statusCode = err && err.response && err.response.statusCode;
73
- if (statusCode !== 401) {
74
- output.warn('Failed to invalidate previous session');
75
- }
76
- });
85
+ if (previousToken && previousToken !== authToken) {
86
+ await invalidateAuthToken(previousToken, output);
87
+ }
88
+ }
89
+ async function invalidateAuthToken(token, output) {
90
+ try {
91
+ if (await isSanityApiToken(token)) return;
92
+ } catch (err) {
93
+ if (isHttpError(err) && err.statusCode === 401) return;
94
+ }
95
+ try {
96
+ await logout(token);
97
+ } catch (err) {
98
+ if (!isHttpError(err) || err.statusCode !== 401) {
99
+ output.warn('Failed to invalidate previous session');
100
+ }
77
101
  }
78
- trace.complete();
79
102
  }
80
103
 
81
104
  //# sourceMappingURL=login.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/actions/auth/login/login.ts"],"sourcesContent":["import {\n type CLITelemetryStore,\n getCliToken,\n getUserConfig,\n type Output,\n setCliUserConfig,\n subdebug,\n} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\nimport open from 'open'\n\nimport {logout} from '../../../services/auth.js'\nimport {LoginTrace} from '../../../telemetry/login.telemetry.js'\nimport {canLaunchBrowser} from '../../../util/canLaunchBrowser.js'\nimport {startServerForTokenCallback} from '../authServer.js'\nimport {getProvider} from './getProvider.js'\n\nconst debug = subdebug('login')\n\ninterface LoginOptions {\n output: Output\n\n telemetry: CLITelemetryStore\n\n experimental?: boolean\n open?: boolean\n provider?: string\n sso?: string\n ssoProvider?: string\n}\n\n/**\n * Trigger the authentication flow for the CLI.\n *\n * NOTE: This uses terminal prompts and will not work for non-interactive/programmatic uses.\n *\n * @param options - Options for the login operation\n * @returns Promise that resolves when the login operation is complete\n * @throws Will throw if login fails or is cancelled\n * @internal\n */\nexport async function login(options: LoginOptions) {\n const {output, telemetry} = options\n const previousToken = await getCliToken()\n const hasExistingToken = Boolean(previousToken)\n\n const trace = telemetry.trace(LoginTrace)\n trace.start()\n\n const provider = await getProvider({\n experimental: options.experimental,\n orgSlug: options.sso,\n specifiedProvider: options.provider,\n ssoProvider: options.ssoProvider,\n })\n\n trace.log({provider: provider?.name, step: 'selectProvider'})\n\n if (provider === undefined) {\n throw new Error('No authentication providers found')\n }\n\n const {loginUrl, server, token: tokenPromise} = await startServerForTokenCallback(provider.url)\n\n trace.log({step: 'waitForToken'})\n\n // Open a browser on the login page (or tell the user to)\n const shouldLaunchBrowser = canLaunchBrowser() && options.open !== false\n const actionText = shouldLaunchBrowser ? 'Opening browser at' : 'Please open a browser at'\n\n output.log(`\\n${actionText} ${loginUrl.href}\\n`)\n\n const spin = spinner('Waiting for browser login to complete... Press Ctrl + C to cancel').start()\n\n if (shouldLaunchBrowser) {\n open(loginUrl.href)\n }\n\n // Wait for a success/error on the HTTP callback server\n let authToken: string\n try {\n authToken = (await tokenPromise).token\n spin.stop()\n } catch (err: unknown) {\n spin.stop()\n trace.error(err as Error)\n debug('Error retrieving token: %O', err)\n throw err\n } finally {\n await new Promise<void>((resolve) => {\n server.close(() => resolve())\n })\n }\n\n // Store the token\n setCliUserConfig('authToken', authToken)\n\n // Clear cached telemetry consent\n getUserConfig().delete('telemetryConsent')\n\n // If we had a session previously, attempt to clear it\n if (hasExistingToken) {\n await logout(previousToken).catch((err) => {\n const statusCode = err && err.response && err.response.statusCode\n if (statusCode !== 401) {\n output.warn('Failed to invalidate previous session')\n }\n })\n }\n\n trace.complete()\n}\n"],"names":["getCliToken","getUserConfig","setCliUserConfig","subdebug","spinner","open","logout","LoginTrace","canLaunchBrowser","startServerForTokenCallback","getProvider","debug","login","options","output","telemetry","previousToken","hasExistingToken","Boolean","trace","start","provider","experimental","orgSlug","sso","specifiedProvider","ssoProvider","log","name","step","undefined","Error","loginUrl","server","token","tokenPromise","url","shouldLaunchBrowser","actionText","href","spin","authToken","stop","err","error","Promise","resolve","close","delete","catch","statusCode","response","warn","complete"],"mappings":"AAAA,SAEEA,WAAW,EACXC,aAAa,EAEbC,gBAAgB,EAChBC,QAAQ,QACH,mBAAkB;AACzB,SAAQC,OAAO,QAAO,sBAAqB;AAC3C,OAAOC,UAAU,OAAM;AAEvB,SAAQC,MAAM,QAAO,4BAA2B;AAChD,SAAQC,UAAU,QAAO,wCAAuC;AAChE,SAAQC,gBAAgB,QAAO,oCAAmC;AAClE,SAAQC,2BAA2B,QAAO,mBAAkB;AAC5D,SAAQC,WAAW,QAAO,mBAAkB;AAE5C,MAAMC,QAAQR,SAAS;AAcvB;;;;;;;;;CASC,GACD,OAAO,eAAeS,MAAMC,OAAqB;IAC/C,MAAM,EAACC,MAAM,EAAEC,SAAS,EAAC,GAAGF;IAC5B,MAAMG,gBAAgB,MAAMhB;IAC5B,MAAMiB,mBAAmBC,QAAQF;IAEjC,MAAMG,QAAQJ,UAAUI,KAAK,CAACZ;IAC9BY,MAAMC,KAAK;IAEX,MAAMC,WAAW,MAAMX,YAAY;QACjCY,cAAcT,QAAQS,YAAY;QAClCC,SAASV,QAAQW,GAAG;QACpBC,mBAAmBZ,QAAQQ,QAAQ;QACnCK,aAAab,QAAQa,WAAW;IAClC;IAEAP,MAAMQ,GAAG,CAAC;QAACN,UAAUA,UAAUO;QAAMC,MAAM;IAAgB;IAE3D,IAAIR,aAAaS,WAAW;QAC1B,MAAM,IAAIC,MAAM;IAClB;IAEA,MAAM,EAACC,QAAQ,EAAEC,MAAM,EAAEC,OAAOC,YAAY,EAAC,GAAG,MAAM1B,4BAA4BY,SAASe,GAAG;IAE9FjB,MAAMQ,GAAG,CAAC;QAACE,MAAM;IAAc;IAE/B,yDAAyD;IACzD,MAAMQ,sBAAsB7B,sBAAsBK,QAAQR,IAAI,KAAK;IACnE,MAAMiC,aAAaD,sBAAsB,uBAAuB;IAEhEvB,OAAOa,GAAG,CAAC,CAAC,EAAE,EAAEW,WAAW,CAAC,EAAEN,SAASO,IAAI,CAAC,EAAE,CAAC;IAE/C,MAAMC,OAAOpC,QAAQ,qEAAqEgB,KAAK;IAE/F,IAAIiB,qBAAqB;QACvBhC,KAAK2B,SAASO,IAAI;IACpB;IAEA,uDAAuD;IACvD,IAAIE;IACJ,IAAI;QACFA,YAAY,AAAC,CAAA,MAAMN,YAAW,EAAGD,KAAK;QACtCM,KAAKE,IAAI;IACX,EAAE,OAAOC,KAAc;QACrBH,KAAKE,IAAI;QACTvB,MAAMyB,KAAK,CAACD;QACZhC,MAAM,8BAA8BgC;QACpC,MAAMA;IACR,SAAU;QACR,MAAM,IAAIE,QAAc,CAACC;YACvBb,OAAOc,KAAK,CAAC,IAAMD;QACrB;IACF;IAEA,kBAAkB;IAClB5C,iBAAiB,aAAauC;IAE9B,iCAAiC;IACjCxC,gBAAgB+C,MAAM,CAAC;IAEvB,sDAAsD;IACtD,IAAI/B,kBAAkB;QACpB,MAAMX,OAAOU,eAAeiC,KAAK,CAAC,CAACN;YACjC,MAAMO,aAAaP,OAAOA,IAAIQ,QAAQ,IAAIR,IAAIQ,QAAQ,CAACD,UAAU;YACjE,IAAIA,eAAe,KAAK;gBACtBpC,OAAOsC,IAAI,CAAC;YACd;QACF;IACF;IAEAjC,MAAMkC,QAAQ;AAChB"}
1
+ {"version":3,"sources":["../../../../src/actions/auth/login/login.ts"],"sourcesContent":["import {\n type CLITelemetryStore,\n getCliToken,\n getUserConfig,\n type Output,\n setCliUserConfig,\n subdebug,\n} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {isHttpError} from '@sanity/client'\nimport open from 'open'\n\nimport {logout} from '../../../services/auth.js'\nimport {LoginTrace} from '../../../telemetry/login.telemetry.js'\nimport {canLaunchBrowser} from '../../../util/canLaunchBrowser.js'\nimport {startServerForTokenCallback} from '../authServer.js'\nimport {getProvider} from './getProvider.js'\nimport {isSanityApiToken, validateToken} from './validateToken.js'\n\nconst debug = subdebug('login')\n\ninterface LoginOptions {\n output: Output\n\n telemetry: CLITelemetryStore\n\n experimental?: boolean\n open?: boolean\n provider?: string\n sso?: string\n ssoProvider?: string\n token?: string\n}\n\n/**\n * Trigger the authentication flow for the CLI.\n *\n * NOTE: Without a token option, this uses terminal prompts and will not work for\n * non-interactive/programmatic uses.\n *\n * @param options - Options for the login operation\n * @returns Promise that resolves when the login operation is complete\n * @throws Will throw if login fails or is cancelled\n * @internal\n */\nexport async function login(options: LoginOptions) {\n const {output, telemetry} = options\n const previousToken = await getCliToken()\n\n const trace = telemetry.trace(LoginTrace)\n trace.start()\n\n if (typeof options.token === 'string') {\n try {\n const authToken = await validateToken(options.token)\n await storeAuthToken(authToken, previousToken, output)\n trace.complete()\n } catch (err: unknown) {\n trace.error(err as Error)\n throw err\n }\n return\n }\n\n const provider = await getProvider({\n experimental: options.experimental,\n orgSlug: options.sso,\n specifiedProvider: options.provider,\n ssoProvider: options.ssoProvider,\n })\n\n trace.log({provider: provider?.name, step: 'selectProvider'})\n\n if (provider === undefined) {\n throw new Error('No authentication providers found')\n }\n\n const {loginUrl, server, token: tokenPromise} = await startServerForTokenCallback(provider.url)\n\n trace.log({step: 'waitForToken'})\n\n // Open a browser on the login page (or tell the user to)\n const shouldLaunchBrowser = canLaunchBrowser() && options.open !== false\n const actionText = shouldLaunchBrowser ? 'Opening browser at' : 'Please open a browser at'\n\n output.log(`\\n${actionText} ${loginUrl.href}\\n`)\n\n const spin = spinner('Waiting for browser login to complete... Press Ctrl + C to cancel').start()\n\n if (shouldLaunchBrowser) {\n open(loginUrl.href)\n }\n\n // Wait for a success/error on the HTTP callback server\n let authToken: string\n try {\n authToken = (await tokenPromise).token\n spin.stop()\n } catch (err: unknown) {\n spin.stop()\n trace.error(err as Error)\n debug('Error retrieving token: %O', err)\n throw err\n } finally {\n await new Promise<void>((resolve) => {\n server.close(() => resolve())\n })\n }\n\n await storeAuthToken(authToken, previousToken, output)\n\n trace.complete()\n}\n\nasync function storeAuthToken(\n authToken: string,\n previousToken: string | undefined,\n output: Output,\n) {\n setCliUserConfig('authToken', authToken)\n getUserConfig().delete('telemetryConsent')\n\n // If we had a session previously, attempt to clear it\n if (previousToken && previousToken !== authToken) {\n await invalidateAuthToken(previousToken, output)\n }\n}\n\nasync function invalidateAuthToken(token: string, output: Output) {\n try {\n if (await isSanityApiToken(token)) return\n } catch (err) {\n if (isHttpError(err) && err.statusCode === 401) return\n }\n\n try {\n await logout(token)\n } catch (err) {\n if (!isHttpError(err) || err.statusCode !== 401) {\n output.warn('Failed to invalidate previous session')\n }\n }\n}\n"],"names":["getCliToken","getUserConfig","setCliUserConfig","subdebug","spinner","isHttpError","open","logout","LoginTrace","canLaunchBrowser","startServerForTokenCallback","getProvider","isSanityApiToken","validateToken","debug","login","options","output","telemetry","previousToken","trace","start","token","authToken","storeAuthToken","complete","err","error","provider","experimental","orgSlug","sso","specifiedProvider","ssoProvider","log","name","step","undefined","Error","loginUrl","server","tokenPromise","url","shouldLaunchBrowser","actionText","href","spin","stop","Promise","resolve","close","delete","invalidateAuthToken","statusCode","warn"],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { getGlobalCliClient } from '@sanity/cli-core';
2
+ import { isHttpError } from '@sanity/client';
3
+ import { USERS_API_VERSION } from '../../../services/user.js';
4
+ import { getErrorMessage } from '../../../util/getErrorMessage.js';
5
+ export async function validateToken(token) {
6
+ const trimmedToken = token.trim();
7
+ if (!trimmedToken) {
8
+ throw new Error('Token is required on standard input. Run `sanity login --with-token < token.txt`.');
9
+ }
10
+ try {
11
+ await getTokenUser(trimmedToken);
12
+ } catch (error) {
13
+ if (isHttpError(error) && (error.statusCode === 401 || error.statusCode === 403)) {
14
+ throw new Error('Token is invalid or expired. Check the token and try again.', {
15
+ cause: error
16
+ });
17
+ }
18
+ throw new Error(`Could not verify token: ${getErrorMessage(error)}`, {
19
+ cause: error
20
+ });
21
+ }
22
+ return trimmedToken;
23
+ }
24
+ export async function isSanityApiToken(token) {
25
+ return isSanityApiTokenUser(await getTokenUser(token));
26
+ }
27
+ async function getTokenUser(token) {
28
+ const client = await getGlobalCliClient({
29
+ apiVersion: USERS_API_VERSION,
30
+ requireUser: true,
31
+ token
32
+ });
33
+ return client.users.getById('me');
34
+ }
35
+ function isSanityApiTokenUser(user) {
36
+ return typeof user === 'object' && user !== null && 'provider' in user && user.provider === 'sanity-token';
37
+ }
38
+
39
+ //# sourceMappingURL=validateToken.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/actions/auth/login/validateToken.ts"],"sourcesContent":["import {getGlobalCliClient} from '@sanity/cli-core'\nimport {isHttpError} from '@sanity/client'\n\nimport {USERS_API_VERSION} from '../../../services/user.js'\nimport {getErrorMessage} from '../../../util/getErrorMessage.js'\n\nexport async function validateToken(token: string): Promise<string> {\n const trimmedToken = token.trim()\n\n if (!trimmedToken) {\n throw new Error(\n 'Token is required on standard input. Run `sanity login --with-token < token.txt`.',\n )\n }\n\n try {\n await getTokenUser(trimmedToken)\n } catch (error) {\n if (isHttpError(error) && (error.statusCode === 401 || error.statusCode === 403)) {\n throw new Error('Token is invalid or expired. Check the token and try again.', {cause: error})\n }\n\n throw new Error(`Could not verify token: ${getErrorMessage(error)}`, {cause: error})\n }\n\n return trimmedToken\n}\n\nexport async function isSanityApiToken(token: string): Promise<boolean> {\n return isSanityApiTokenUser(await getTokenUser(token))\n}\n\nasync function getTokenUser(token: string): Promise<unknown> {\n const client = await getGlobalCliClient({\n apiVersion: USERS_API_VERSION,\n requireUser: true,\n token,\n })\n\n return client.users.getById('me')\n}\n\nfunction isSanityApiTokenUser(user: unknown): boolean {\n return (\n typeof user === 'object' &&\n user !== null &&\n 'provider' in user &&\n (user as {provider?: unknown}).provider === 'sanity-token'\n )\n}\n"],"names":["getGlobalCliClient","isHttpError","USERS_API_VERSION","getErrorMessage","validateToken","token","trimmedToken","trim","Error","getTokenUser","error","statusCode","cause","isSanityApiToken","isSanityApiTokenUser","client","apiVersion","requireUser","users","getById","user","provider"],"mappings":"AAAA,SAAQA,kBAAkB,QAAO,mBAAkB;AACnD,SAAQC,WAAW,QAAO,iBAAgB;AAE1C,SAAQC,iBAAiB,QAAO,4BAA2B;AAC3D,SAAQC,eAAe,QAAO,mCAAkC;AAEhE,OAAO,eAAeC,cAAcC,KAAa;IAC/C,MAAMC,eAAeD,MAAME,IAAI;IAE/B,IAAI,CAACD,cAAc;QACjB,MAAM,IAAIE,MACR;IAEJ;IAEA,IAAI;QACF,MAAMC,aAAaH;IACrB,EAAE,OAAOI,OAAO;QACd,IAAIT,YAAYS,UAAWA,CAAAA,MAAMC,UAAU,KAAK,OAAOD,MAAMC,UAAU,KAAK,GAAE,GAAI;YAChF,MAAM,IAAIH,MAAM,+DAA+D;gBAACI,OAAOF;YAAK;QAC9F;QAEA,MAAM,IAAIF,MAAM,CAAC,wBAAwB,EAAEL,gBAAgBO,QAAQ,EAAE;YAACE,OAAOF;QAAK;IACpF;IAEA,OAAOJ;AACT;AAEA,OAAO,eAAeO,iBAAiBR,KAAa;IAClD,OAAOS,qBAAqB,MAAML,aAAaJ;AACjD;AAEA,eAAeI,aAAaJ,KAAa;IACvC,MAAMU,SAAS,MAAMf,mBAAmB;QACtCgB,YAAYd;QACZe,aAAa;QACbZ;IACF;IAEA,OAAOU,OAAOG,KAAK,CAACC,OAAO,CAAC;AAC9B;AAEA,SAASL,qBAAqBM,IAAa;IACzC,OACE,OAAOA,SAAS,YAChBA,SAAS,QACT,cAAcA,QACd,AAACA,KAA8BC,QAAQ,KAAK;AAEhD"}
@@ -1,3 +1,4 @@
1
+ import { text } from 'node:stream/consumers';
1
2
  import { Flags } from '@oclif/core';
2
3
  import { SanityCommand } from '@sanity/cli-core';
3
4
  import { login } from '../actions/auth/login/login.js';
@@ -19,6 +20,10 @@ export class LoginCommand extends SanityCommand {
19
20
  {
20
21
  command: '<%= config.bin %> <%= command.id %> --sso my-organization --sso-provider "Okta SSO"',
21
22
  description: 'Log in using a specific SSO provider within an organization'
23
+ },
24
+ {
25
+ command: '<%= config.bin %> <%= command.id %> --with-token < token.txt',
26
+ description: 'Log in using a token from standard input'
22
27
  }
23
28
  ];
24
29
  static flags = {
@@ -34,14 +39,16 @@ export class LoginCommand extends SanityCommand {
34
39
  provider: Flags.string({
35
40
  description: 'Log in using the given provider',
36
41
  exclusive: [
37
- 'sso'
42
+ 'sso',
43
+ 'with-token'
38
44
  ],
39
45
  helpValue: '<providerId>'
40
46
  }),
41
47
  sso: Flags.string({
42
48
  description: 'Log in using Single Sign-On, using the given organization slug',
43
49
  exclusive: [
44
- 'provider'
50
+ 'provider',
51
+ 'with-token'
45
52
  ],
46
53
  helpValue: '<slug>'
47
54
  }),
@@ -51,16 +58,26 @@ export class LoginCommand extends SanityCommand {
51
58
  ],
52
59
  description: 'Select a specific SSO provider by name (use with --sso)',
53
60
  helpValue: '<name>'
61
+ }),
62
+ 'with-token': Flags.boolean({
63
+ description: 'Read token from standard input',
64
+ exclusive: [
65
+ 'provider',
66
+ 'sso'
67
+ ]
54
68
  })
55
69
  };
56
70
  async run() {
57
71
  const { flags } = await this.parse(LoginCommand);
72
+ const { 'sso-provider': ssoProvider, 'with-token': withToken, ...loginFlags } = flags;
58
73
  try {
74
+ const token = withToken ? await readTokenFromStdin() : undefined;
59
75
  await login({
60
- ...flags,
76
+ ...loginFlags,
61
77
  output: this.output,
62
- ssoProvider: flags['sso-provider'],
63
- telemetry: this.telemetry
78
+ ssoProvider,
79
+ telemetry: this.telemetry,
80
+ token
64
81
  });
65
82
  this.log('Login successful');
66
83
  } catch (error) {
@@ -71,5 +88,11 @@ export class LoginCommand extends SanityCommand {
71
88
  }
72
89
  }
73
90
  }
91
+ async function readTokenFromStdin() {
92
+ if (process.stdin.isTTY) {
93
+ throw new Error('Token is required on standard input. Run `sanity login --with-token < token.txt`.');
94
+ }
95
+ return text(process.stdin);
96
+ }
74
97
 
75
98
  //# sourceMappingURL=login.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/login.ts"],"sourcesContent":["import {Command, Flags} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {SanityCommand} from '@sanity/cli-core'\n\nimport {login} from '../actions/auth/login/login.js'\n\nexport class LoginCommand extends SanityCommand<typeof LoginCommand> {\n static override description = 'Log in to your Sanity account'\n static override examples: Array<Command.Example> = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Log in using default settings',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --provider github --no-open',\n description: 'Login with GitHub provider, but do not open a browser window automatically',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --sso my-organization',\n description: 'Log in using Single Sign-On with the \"my-organization\" slug',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> --sso my-organization --sso-provider \"Okta SSO\"',\n description: 'Log in using a specific SSO provider within an organization',\n },\n ]\n static override flags = {\n experimental: Flags.boolean({\n default: false,\n hidden: true,\n }),\n open: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Open a browser window to log in (`--no-open` only prints URL)',\n }),\n provider: Flags.string({\n description: 'Log in using the given provider',\n exclusive: ['sso'],\n helpValue: '<providerId>',\n }),\n sso: Flags.string({\n description: 'Log in using Single Sign-On, using the given organization slug',\n exclusive: ['provider'],\n helpValue: '<slug>',\n }),\n 'sso-provider': Flags.string({\n dependsOn: ['sso'],\n description: 'Select a specific SSO provider by name (use with --sso)',\n helpValue: '<name>',\n }),\n } satisfies FlagInput\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(LoginCommand)\n\n try {\n await login({\n ...flags,\n output: this.output,\n ssoProvider: flags['sso-provider'],\n telemetry: this.telemetry,\n })\n this.log('Login successful')\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n this.error(`Login failed: ${message}`, {exit: 1})\n }\n }\n}\n"],"names":["Flags","SanityCommand","login","LoginCommand","description","examples","command","flags","experimental","boolean","default","hidden","open","allowNo","provider","string","exclusive","helpValue","sso","dependsOn","run","parse","output","ssoProvider","telemetry","log","error","message","Error","String","exit"],"mappings":"AAAA,SAAiBA,KAAK,QAAO,cAAa;AAE1C,SAAQC,aAAa,QAAO,mBAAkB;AAE9C,SAAQC,KAAK,QAAO,iCAAgC;AAEpD,OAAO,MAAMC,qBAAqBF;IAChC,OAAgBG,cAAc,gCAA+B;IAC7D,OAAgBC,WAAmC;QACjD;YACEC,SAAS;YACTF,aAAa;QACf;QACA;YACEE,SAAS;YACTF,aAAa;QACf;QACA;YACEE,SAAS;YACTF,aAAa;QACf;QACA;YACEE,SACE;YACFF,aAAa;QACf;KACD,CAAA;IACD,OAAgBG,QAAQ;QACtBC,cAAcR,MAAMS,OAAO,CAAC;YAC1BC,SAAS;YACTC,QAAQ;QACV;QACAC,MAAMZ,MAAMS,OAAO,CAAC;YAClBI,SAAS;YACTH,SAAS;YACTN,aAAa;QACf;QACAU,UAAUd,MAAMe,MAAM,CAAC;YACrBX,aAAa;YACbY,WAAW;gBAAC;aAAM;YAClBC,WAAW;QACb;QACAC,KAAKlB,MAAMe,MAAM,CAAC;YAChBX,aAAa;YACbY,WAAW;gBAAC;aAAW;YACvBC,WAAW;QACb;QACA,gBAAgBjB,MAAMe,MAAM,CAAC;YAC3BI,WAAW;gBAAC;aAAM;YAClBf,aAAa;YACba,WAAW;QACb;IACF,EAAqB;IAErB,MAAaG,MAAqB;QAChC,MAAM,EAACb,KAAK,EAAC,GAAG,MAAM,IAAI,CAACc,KAAK,CAAClB;QAEjC,IAAI;YACF,MAAMD,MAAM;gBACV,GAAGK,KAAK;gBACRe,QAAQ,IAAI,CAACA,MAAM;gBACnBC,aAAahB,KAAK,CAAC,eAAe;gBAClCiB,WAAW,IAAI,CAACA,SAAS;YAC3B;YACA,IAAI,CAACC,GAAG,CAAC;QACX,EAAE,OAAOC,OAAO;YACd,MAAMC,UAAUD,iBAAiBE,QAAQF,MAAMC,OAAO,GAAGE,OAAOH;YAChE,IAAI,CAACA,KAAK,CAAC,CAAC,cAAc,EAAEC,SAAS,EAAE;gBAACG,MAAM;YAAC;QACjD;IACF;AACF"}
1
+ {"version":3,"sources":["../../src/commands/login.ts"],"sourcesContent":["import {text} from 'node:stream/consumers'\n\nimport {Command, Flags} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {SanityCommand} from '@sanity/cli-core'\n\nimport {login} from '../actions/auth/login/login.js'\n\nexport class LoginCommand extends SanityCommand<typeof LoginCommand> {\n static override description = 'Log in to your Sanity account'\n static override examples: Array<Command.Example> = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Log in using default settings',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --provider github --no-open',\n description: 'Login with GitHub provider, but do not open a browser window automatically',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --sso my-organization',\n description: 'Log in using Single Sign-On with the \"my-organization\" slug',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> --sso my-organization --sso-provider \"Okta SSO\"',\n description: 'Log in using a specific SSO provider within an organization',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --with-token < token.txt',\n description: 'Log in using a token from standard input',\n },\n ]\n static override flags = {\n experimental: Flags.boolean({\n default: false,\n hidden: true,\n }),\n open: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Open a browser window to log in (`--no-open` only prints URL)',\n }),\n provider: Flags.string({\n description: 'Log in using the given provider',\n exclusive: ['sso', 'with-token'],\n helpValue: '<providerId>',\n }),\n sso: Flags.string({\n description: 'Log in using Single Sign-On, using the given organization slug',\n exclusive: ['provider', 'with-token'],\n helpValue: '<slug>',\n }),\n 'sso-provider': Flags.string({\n dependsOn: ['sso'],\n description: 'Select a specific SSO provider by name (use with --sso)',\n helpValue: '<name>',\n }),\n 'with-token': Flags.boolean({\n description: 'Read token from standard input',\n exclusive: ['provider', 'sso'],\n }),\n } satisfies FlagInput\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(LoginCommand)\n const {'sso-provider': ssoProvider, 'with-token': withToken, ...loginFlags} = flags\n\n try {\n const token = withToken ? await readTokenFromStdin() : undefined\n\n await login({\n ...loginFlags,\n output: this.output,\n ssoProvider,\n telemetry: this.telemetry,\n token,\n })\n this.log('Login successful')\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n this.error(`Login failed: ${message}`, {exit: 1})\n }\n }\n}\n\nasync function readTokenFromStdin(): Promise<string> {\n if (process.stdin.isTTY) {\n throw new Error(\n 'Token is required on standard input. Run `sanity login --with-token < token.txt`.',\n )\n }\n\n return text(process.stdin)\n}\n"],"names":["text","Flags","SanityCommand","login","LoginCommand","description","examples","command","flags","experimental","boolean","default","hidden","open","allowNo","provider","string","exclusive","helpValue","sso","dependsOn","run","parse","ssoProvider","withToken","loginFlags","token","readTokenFromStdin","undefined","output","telemetry","log","error","message","Error","String","exit","process","stdin","isTTY"],"mappings":"AAAA,SAAQA,IAAI,QAAO,wBAAuB;AAE1C,SAAiBC,KAAK,QAAO,cAAa;AAE1C,SAAQC,aAAa,QAAO,mBAAkB;AAE9C,SAAQC,KAAK,QAAO,iCAAgC;AAEpD,OAAO,MAAMC,qBAAqBF;IAChC,OAAgBG,cAAc,gCAA+B;IAC7D,OAAgBC,WAAmC;QACjD;YACEC,SAAS;YACTF,aAAa;QACf;QACA;YACEE,SAAS;YACTF,aAAa;QACf;QACA;YACEE,SAAS;YACTF,aAAa;QACf;QACA;YACEE,SACE;YACFF,aAAa;QACf;QACA;YACEE,SAAS;YACTF,aAAa;QACf;KACD,CAAA;IACD,OAAgBG,QAAQ;QACtBC,cAAcR,MAAMS,OAAO,CAAC;YAC1BC,SAAS;YACTC,QAAQ;QACV;QACAC,MAAMZ,MAAMS,OAAO,CAAC;YAClBI,SAAS;YACTH,SAAS;YACTN,aAAa;QACf;QACAU,UAAUd,MAAMe,MAAM,CAAC;YACrBX,aAAa;YACbY,WAAW;gBAAC;gBAAO;aAAa;YAChCC,WAAW;QACb;QACAC,KAAKlB,MAAMe,MAAM,CAAC;YAChBX,aAAa;YACbY,WAAW;gBAAC;gBAAY;aAAa;YACrCC,WAAW;QACb;QACA,gBAAgBjB,MAAMe,MAAM,CAAC;YAC3BI,WAAW;gBAAC;aAAM;YAClBf,aAAa;YACba,WAAW;QACb;QACA,cAAcjB,MAAMS,OAAO,CAAC;YAC1BL,aAAa;YACbY,WAAW;gBAAC;gBAAY;aAAM;QAChC;IACF,EAAqB;IAErB,MAAaI,MAAqB;QAChC,MAAM,EAACb,KAAK,EAAC,GAAG,MAAM,IAAI,CAACc,KAAK,CAAClB;QACjC,MAAM,EAAC,gBAAgBmB,WAAW,EAAE,cAAcC,SAAS,EAAE,GAAGC,YAAW,GAAGjB;QAE9E,IAAI;YACF,MAAMkB,QAAQF,YAAY,MAAMG,uBAAuBC;YAEvD,MAAMzB,MAAM;gBACV,GAAGsB,UAAU;gBACbI,QAAQ,IAAI,CAACA,MAAM;gBACnBN;gBACAO,WAAW,IAAI,CAACA,SAAS;gBACzBJ;YACF;YACA,IAAI,CAACK,GAAG,CAAC;QACX,EAAE,OAAOC,OAAO;YACd,MAAMC,UAAUD,iBAAiBE,QAAQF,MAAMC,OAAO,GAAGE,OAAOH;YAChE,IAAI,CAACA,KAAK,CAAC,CAAC,cAAc,EAAEC,SAAS,EAAE;gBAACG,MAAM;YAAC;QACjD;IACF;AACF;AAEA,eAAeT;IACb,IAAIU,QAAQC,KAAK,CAACC,KAAK,EAAE;QACvB,MAAM,IAAIL,MACR;IAEJ;IAEA,OAAOlC,KAAKqC,QAAQC,KAAK;AAC3B"}
@@ -808,6 +808,10 @@
808
808
  {
809
809
  "command": "<%= config.bin %> <%= command.id %> --sso my-organization --sso-provider \"Okta SSO\"",
810
810
  "description": "Log in using a specific SSO provider within an organization"
811
+ },
812
+ {
813
+ "command": "<%= config.bin %> <%= command.id %> --with-token < token.txt",
814
+ "description": "Log in using a token from standard input"
811
815
  }
812
816
  ],
813
817
  "flags": {
@@ -826,7 +830,8 @@
826
830
  "provider": {
827
831
  "description": "Log in using the given provider",
828
832
  "exclusive": [
829
- "sso"
833
+ "sso",
834
+ "with-token"
830
835
  ],
831
836
  "name": "provider",
832
837
  "hasDynamicHelp": false,
@@ -837,7 +842,8 @@
837
842
  "sso": {
838
843
  "description": "Log in using Single Sign-On, using the given organization slug",
839
844
  "exclusive": [
840
- "provider"
845
+ "provider",
846
+ "with-token"
841
847
  ],
842
848
  "name": "sso",
843
849
  "hasDynamicHelp": false,
@@ -855,6 +861,16 @@
855
861
  "helpValue": "<name>",
856
862
  "multiple": false,
857
863
  "type": "option"
864
+ },
865
+ "with-token": {
866
+ "description": "Read token from standard input",
867
+ "exclusive": [
868
+ "provider",
869
+ "sso"
870
+ ],
871
+ "name": "with-token",
872
+ "allowNo": false,
873
+ "type": "boolean"
858
874
  }
859
875
  },
860
876
  "hasDynamicHelp": false,
@@ -4816,26 +4832,26 @@
4816
4832
  "unlink.js"
4817
4833
  ]
4818
4834
  },
4819
- "datasets:visibility:get": {
4835
+ "datasets:embeddings:disable": {
4820
4836
  "aliases": [],
4821
4837
  "args": {
4822
4838
  "dataset": {
4823
- "description": "The name of the dataset to get visibility for",
4839
+ "description": "Dataset name to disable embeddings for",
4824
4840
  "name": "dataset",
4825
- "required": true
4841
+ "required": false
4826
4842
  }
4827
4843
  },
4828
- "description": "Get the visibility of a dataset",
4844
+ "description": "Disable embeddings for a dataset",
4829
4845
  "examples": [
4830
4846
  {
4831
- "command": "<%= config.bin %> <%= command.id %> my-dataset",
4832
- "description": "Check the visibility of a dataset"
4847
+ "command": "<%= config.bin %> <%= command.id %> production",
4848
+ "description": "Disable embeddings for the production dataset"
4833
4849
  }
4834
4850
  ],
4835
4851
  "flags": {
4836
4852
  "project-id": {
4837
4853
  "char": "p",
4838
- "description": "Project ID to get dataset visibility for (overrides CLI configuration)",
4854
+ "description": "Project ID to disable embeddings for (overrides CLI configuration)",
4839
4855
  "helpGroup": "OVERRIDE",
4840
4856
  "name": "project-id",
4841
4857
  "hasDynamicHelp": false,
@@ -4846,9 +4862,9 @@
4846
4862
  },
4847
4863
  "hasDynamicHelp": false,
4848
4864
  "hiddenAliases": [
4849
- "dataset:visibility:get"
4865
+ "dataset:embeddings:disable"
4850
4866
  ],
4851
- "id": "datasets:visibility:get",
4867
+ "id": "datasets:embeddings:disable",
4852
4868
  "pluginAlias": "@sanity/cli",
4853
4869
  "pluginName": "@sanity/cli",
4854
4870
  "pluginType": "core",
@@ -4858,56 +4874,65 @@
4858
4874
  "dist",
4859
4875
  "commands",
4860
4876
  "datasets",
4861
- "visibility",
4862
- "get.js"
4877
+ "embeddings",
4878
+ "disable.js"
4863
4879
  ]
4864
4880
  },
4865
- "datasets:visibility:set": {
4881
+ "datasets:embeddings:enable": {
4866
4882
  "aliases": [],
4867
4883
  "args": {
4868
4884
  "dataset": {
4869
- "description": "The name of the dataset to set visibility for",
4885
+ "description": "Dataset name to enable embeddings for",
4870
4886
  "name": "dataset",
4871
- "required": true
4872
- },
4873
- "mode": {
4874
- "description": "The visibility mode to set",
4875
- "name": "mode",
4876
- "options": [
4877
- "public",
4878
- "private"
4879
- ],
4880
- "required": true
4887
+ "required": false
4881
4888
  }
4882
4889
  },
4883
- "description": "Set the visibility of a dataset",
4890
+ "description": "Enable embeddings for a dataset",
4884
4891
  "examples": [
4885
4892
  {
4886
- "command": "<%= config.bin %> <%= command.id %> my-dataset private",
4887
- "description": "Make a dataset private"
4893
+ "command": "<%= config.bin %> <%= command.id %> production",
4894
+ "description": "Enable embeddings for the production dataset"
4888
4895
  },
4889
4896
  {
4890
- "command": "<%= config.bin %> <%= command.id %> my-dataset public",
4891
- "description": "Make a dataset public"
4897
+ "command": "<%= config.bin %> <%= command.id %> production --projection \"{ title, body }\"",
4898
+ "description": "Enable embeddings with a specific projection"
4899
+ },
4900
+ {
4901
+ "command": "<%= config.bin %> <%= command.id %> production --wait",
4902
+ "description": "Enable embeddings and wait for processing to complete"
4892
4903
  }
4893
4904
  ],
4894
4905
  "flags": {
4895
4906
  "project-id": {
4896
4907
  "char": "p",
4897
- "description": "Project ID to set dataset visibility for (overrides CLI configuration)",
4908
+ "description": "Project ID to enable embeddings for (overrides CLI configuration)",
4898
4909
  "helpGroup": "OVERRIDE",
4899
4910
  "name": "project-id",
4900
4911
  "hasDynamicHelp": false,
4901
4912
  "helpValue": "<id>",
4902
4913
  "multiple": false,
4903
4914
  "type": "option"
4915
+ },
4916
+ "projection": {
4917
+ "description": "GROQ projection defining which fields to embed (e.g. \"{ title, body }\")",
4918
+ "name": "projection",
4919
+ "required": false,
4920
+ "hasDynamicHelp": false,
4921
+ "multiple": false,
4922
+ "type": "option"
4923
+ },
4924
+ "wait": {
4925
+ "description": "Wait for embeddings processing to complete before returning",
4926
+ "name": "wait",
4927
+ "allowNo": false,
4928
+ "type": "boolean"
4904
4929
  }
4905
4930
  },
4906
4931
  "hasDynamicHelp": false,
4907
4932
  "hiddenAliases": [
4908
- "dataset:visibility:set"
4933
+ "dataset:embeddings:enable"
4909
4934
  ],
4910
- "id": "datasets:visibility:set",
4935
+ "id": "datasets:embeddings:enable",
4911
4936
  "pluginAlias": "@sanity/cli",
4912
4937
  "pluginName": "@sanity/cli",
4913
4938
  "pluginType": "core",
@@ -4917,30 +4942,30 @@
4917
4942
  "dist",
4918
4943
  "commands",
4919
4944
  "datasets",
4920
- "visibility",
4921
- "set.js"
4945
+ "embeddings",
4946
+ "enable.js"
4922
4947
  ]
4923
4948
  },
4924
- "datasets:embeddings:disable": {
4949
+ "datasets:embeddings:status": {
4925
4950
  "aliases": [],
4926
4951
  "args": {
4927
4952
  "dataset": {
4928
- "description": "Dataset name to disable embeddings for",
4953
+ "description": "The name of the dataset to check embeddings status for",
4929
4954
  "name": "dataset",
4930
4955
  "required": false
4931
4956
  }
4932
4957
  },
4933
- "description": "Disable embeddings for a dataset",
4958
+ "description": "Show embeddings settings and status for a dataset",
4934
4959
  "examples": [
4935
4960
  {
4936
4961
  "command": "<%= config.bin %> <%= command.id %> production",
4937
- "description": "Disable embeddings for the production dataset"
4962
+ "description": "Show embeddings status for the production dataset"
4938
4963
  }
4939
4964
  ],
4940
4965
  "flags": {
4941
4966
  "project-id": {
4942
4967
  "char": "p",
4943
- "description": "Project ID to disable embeddings for (overrides CLI configuration)",
4968
+ "description": "Project ID to check embeddings status for (overrides CLI configuration)",
4944
4969
  "helpGroup": "OVERRIDE",
4945
4970
  "name": "project-id",
4946
4971
  "hasDynamicHelp": false,
@@ -4951,9 +4976,9 @@
4951
4976
  },
4952
4977
  "hasDynamicHelp": false,
4953
4978
  "hiddenAliases": [
4954
- "dataset:embeddings:disable"
4979
+ "dataset:embeddings:status"
4955
4980
  ],
4956
- "id": "datasets:embeddings:disable",
4981
+ "id": "datasets:embeddings:status",
4957
4982
  "pluginAlias": "@sanity/cli",
4958
4983
  "pluginName": "@sanity/cli",
4959
4984
  "pluginType": "core",
@@ -4964,64 +4989,42 @@
4964
4989
  "commands",
4965
4990
  "datasets",
4966
4991
  "embeddings",
4967
- "disable.js"
4992
+ "status.js"
4968
4993
  ]
4969
4994
  },
4970
- "datasets:embeddings:enable": {
4995
+ "datasets:visibility:get": {
4971
4996
  "aliases": [],
4972
4997
  "args": {
4973
4998
  "dataset": {
4974
- "description": "Dataset name to enable embeddings for",
4999
+ "description": "The name of the dataset to get visibility for",
4975
5000
  "name": "dataset",
4976
- "required": false
5001
+ "required": true
4977
5002
  }
4978
5003
  },
4979
- "description": "Enable embeddings for a dataset",
5004
+ "description": "Get the visibility of a dataset",
4980
5005
  "examples": [
4981
5006
  {
4982
- "command": "<%= config.bin %> <%= command.id %> production",
4983
- "description": "Enable embeddings for the production dataset"
4984
- },
4985
- {
4986
- "command": "<%= config.bin %> <%= command.id %> production --projection \"{ title, body }\"",
4987
- "description": "Enable embeddings with a specific projection"
4988
- },
4989
- {
4990
- "command": "<%= config.bin %> <%= command.id %> production --wait",
4991
- "description": "Enable embeddings and wait for processing to complete"
5007
+ "command": "<%= config.bin %> <%= command.id %> my-dataset",
5008
+ "description": "Check the visibility of a dataset"
4992
5009
  }
4993
5010
  ],
4994
5011
  "flags": {
4995
5012
  "project-id": {
4996
5013
  "char": "p",
4997
- "description": "Project ID to enable embeddings for (overrides CLI configuration)",
5014
+ "description": "Project ID to get dataset visibility for (overrides CLI configuration)",
4998
5015
  "helpGroup": "OVERRIDE",
4999
5016
  "name": "project-id",
5000
5017
  "hasDynamicHelp": false,
5001
5018
  "helpValue": "<id>",
5002
5019
  "multiple": false,
5003
5020
  "type": "option"
5004
- },
5005
- "projection": {
5006
- "description": "GROQ projection defining which fields to embed (e.g. \"{ title, body }\")",
5007
- "name": "projection",
5008
- "required": false,
5009
- "hasDynamicHelp": false,
5010
- "multiple": false,
5011
- "type": "option"
5012
- },
5013
- "wait": {
5014
- "description": "Wait for embeddings processing to complete before returning",
5015
- "name": "wait",
5016
- "allowNo": false,
5017
- "type": "boolean"
5018
5021
  }
5019
5022
  },
5020
5023
  "hasDynamicHelp": false,
5021
5024
  "hiddenAliases": [
5022
- "dataset:embeddings:enable"
5025
+ "dataset:visibility:get"
5023
5026
  ],
5024
- "id": "datasets:embeddings:enable",
5027
+ "id": "datasets:visibility:get",
5025
5028
  "pluginAlias": "@sanity/cli",
5026
5029
  "pluginName": "@sanity/cli",
5027
5030
  "pluginType": "core",
@@ -5031,30 +5034,43 @@
5031
5034
  "dist",
5032
5035
  "commands",
5033
5036
  "datasets",
5034
- "embeddings",
5035
- "enable.js"
5037
+ "visibility",
5038
+ "get.js"
5036
5039
  ]
5037
5040
  },
5038
- "datasets:embeddings:status": {
5041
+ "datasets:visibility:set": {
5039
5042
  "aliases": [],
5040
5043
  "args": {
5041
5044
  "dataset": {
5042
- "description": "The name of the dataset to check embeddings status for",
5045
+ "description": "The name of the dataset to set visibility for",
5043
5046
  "name": "dataset",
5044
- "required": false
5047
+ "required": true
5048
+ },
5049
+ "mode": {
5050
+ "description": "The visibility mode to set",
5051
+ "name": "mode",
5052
+ "options": [
5053
+ "public",
5054
+ "private"
5055
+ ],
5056
+ "required": true
5045
5057
  }
5046
5058
  },
5047
- "description": "Show embeddings settings and status for a dataset",
5059
+ "description": "Set the visibility of a dataset",
5048
5060
  "examples": [
5049
5061
  {
5050
- "command": "<%= config.bin %> <%= command.id %> production",
5051
- "description": "Show embeddings status for the production dataset"
5062
+ "command": "<%= config.bin %> <%= command.id %> my-dataset private",
5063
+ "description": "Make a dataset private"
5064
+ },
5065
+ {
5066
+ "command": "<%= config.bin %> <%= command.id %> my-dataset public",
5067
+ "description": "Make a dataset public"
5052
5068
  }
5053
5069
  ],
5054
5070
  "flags": {
5055
5071
  "project-id": {
5056
5072
  "char": "p",
5057
- "description": "Project ID to check embeddings status for (overrides CLI configuration)",
5073
+ "description": "Project ID to set dataset visibility for (overrides CLI configuration)",
5058
5074
  "helpGroup": "OVERRIDE",
5059
5075
  "name": "project-id",
5060
5076
  "hasDynamicHelp": false,
@@ -5065,9 +5081,9 @@
5065
5081
  },
5066
5082
  "hasDynamicHelp": false,
5067
5083
  "hiddenAliases": [
5068
- "dataset:embeddings:status"
5084
+ "dataset:visibility:set"
5069
5085
  ],
5070
- "id": "datasets:embeddings:status",
5086
+ "id": "datasets:visibility:set",
5071
5087
  "pluginAlias": "@sanity/cli",
5072
5088
  "pluginName": "@sanity/cli",
5073
5089
  "pluginType": "core",
@@ -5077,10 +5093,10 @@
5077
5093
  "dist",
5078
5094
  "commands",
5079
5095
  "datasets",
5080
- "embeddings",
5081
- "status.js"
5096
+ "visibility",
5097
+ "set.js"
5082
5098
  ]
5083
5099
  }
5084
5100
  },
5085
- "version": "6.5.3"
5101
+ "version": "6.6.0"
5086
5102
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/cli",
3
- "version": "6.5.3",
3
+ "version": "6.6.0",
4
4
  "description": "Sanity CLI tool for managing Sanity projects and organizations",
5
5
  "keywords": [
6
6
  "cli",