@sanity/runtime-cli 4.3.2 → 4.3.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.
Files changed (42) hide show
  1. package/README.md +17 -17
  2. package/dist/actions/blueprints/assets.js +2 -2
  3. package/dist/actions/blueprints/logs.js +2 -2
  4. package/dist/actions/blueprints/operations.js +2 -2
  5. package/dist/actions/blueprints/projects.js +1 -1
  6. package/dist/actions/blueprints/stacks.js +2 -2
  7. package/dist/actions/functions/env/list.js +2 -2
  8. package/dist/actions/functions/env/remove.js +2 -2
  9. package/dist/actions/functions/env/update.js +2 -2
  10. package/dist/actions/functions/invoke.js +2 -2
  11. package/dist/actions/functions/logs.js +3 -3
  12. package/dist/commands/blueprints/config.d.ts +1 -0
  13. package/dist/commands/blueprints/config.js +15 -5
  14. package/dist/commands/blueprints/deploy.js +4 -2
  15. package/dist/commands/blueprints/destroy.js +4 -2
  16. package/dist/commands/blueprints/info.js +4 -2
  17. package/dist/commands/blueprints/init.d.ts +1 -0
  18. package/dist/commands/blueprints/init.js +14 -6
  19. package/dist/commands/blueprints/logs.js +4 -2
  20. package/dist/commands/blueprints/plan.js +8 -7
  21. package/dist/commands/blueprints/stacks.js +4 -2
  22. package/dist/commands/functions/env/add.js +6 -3
  23. package/dist/commands/functions/env/list.js +6 -3
  24. package/dist/commands/functions/env/remove.js +6 -3
  25. package/dist/commands/functions/invoke.js +6 -3
  26. package/dist/commands/functions/logs.d.ts +5 -0
  27. package/dist/commands/functions/logs.js +25 -17
  28. package/dist/config.d.ts +3 -6
  29. package/dist/config.js +34 -22
  30. package/dist/server/static/components/app.css +850 -40
  31. package/dist/server/static/components/dataset-dropdown.js +5 -3
  32. package/dist/server/static/components/filters.d.ts +1 -0
  33. package/dist/server/static/components/filters.js +20 -0
  34. package/dist/server/static/components/function-list.js +2 -2
  35. package/dist/server/static/components/payload-panel.js +17 -17
  36. package/dist/server/static/components/projects-dropdown.js +5 -3
  37. package/dist/server/static/components/response-panel.js +18 -10
  38. package/dist/server/static/index.html +8 -29
  39. package/dist/utils/validated-token.d.ts +11 -0
  40. package/dist/utils/validated-token.js +59 -0
  41. package/oclif.manifest.json +1 -1
  42. package/package.json +1 -1
@@ -2,9 +2,9 @@ import { Args, Command } from '@oclif/core';
2
2
  import Spinner from 'yocto-spinner';
3
3
  import { readBlueprintOnDisk } from '../../../actions/blueprints/blueprint.js';
4
4
  import { remove } from '../../../actions/functions/env/remove.js';
5
- import config from '../../../config.js';
6
5
  import { red } from '../../../utils/display/colors.js';
7
6
  import { findFunctionByName } from '../../../utils/find-function.js';
7
+ import { validTokenOrErrorMessage } from '../../../utils/validated-token.js';
8
8
  export default class Remove extends Command {
9
9
  static args = {
10
10
  name: Args.string({ description: 'The name of the Sanity Function', required: true }),
@@ -13,17 +13,20 @@ export default class Remove extends Command {
13
13
  static description = 'Remove an environment variable for a Sanity function';
14
14
  static examples = ['<%= config.bin %> <%= command.id %> MyFunction API_URL'];
15
15
  async run() {
16
+ const { token, error: tokenErr } = await validTokenOrErrorMessage();
17
+ if (tokenErr)
18
+ this.error(tokenErr.message);
16
19
  const { args } = await this.parse(Remove);
17
20
  const spinner = Spinner({
18
21
  text: `Removing "${args.key}" environment variable in "${args.name}"`,
19
22
  }).start();
20
- const { deployedStack } = await readBlueprintOnDisk({ getStack: true, token: config.token });
23
+ const { deployedStack } = await readBlueprintOnDisk({ getStack: true, token });
21
24
  if (!deployedStack)
22
25
  this.error('Stack not found'); // returns
23
26
  const { projectId } = deployedStack;
24
27
  const { externalId } = findFunctionByName(deployedStack, args.name);
25
28
  const result = await remove(externalId, args.key, {
26
- token: config.token,
29
+ token,
27
30
  projectId,
28
31
  });
29
32
  if (result.ok) {
@@ -2,9 +2,9 @@ import { Args, Command, Flags } from '@oclif/core';
2
2
  import Spinner from 'yocto-spinner';
3
3
  import { readBlueprintOnDisk } from '../../actions/blueprints/blueprint.js';
4
4
  import { invoke } from '../../actions/functions/invoke.js';
5
- import config from '../../config.js';
6
5
  import { red } from '../../utils/display/colors.js';
7
6
  import { findFunctionByName } from '../../utils/find-function.js';
7
+ import { validTokenOrErrorMessage } from '../../utils/validated-token.js';
8
8
  export default class Invoke extends Command {
9
9
  static args = {
10
10
  name: Args.string({ description: 'The name of the Sanity Function', required: true }),
@@ -23,14 +23,17 @@ export default class Invoke extends Command {
23
23
  }),
24
24
  };
25
25
  async run() {
26
+ const { token, error: tokenErr } = await validTokenOrErrorMessage();
27
+ if (tokenErr)
28
+ this.error(tokenErr.message);
26
29
  const { args, flags } = await this.parse(Invoke);
27
30
  const spinner = Spinner({ text: `Invoking function "${args.name}"` }).start();
28
- const { deployedStack } = await readBlueprintOnDisk({ getStack: true, token: config.token });
31
+ const { deployedStack } = await readBlueprintOnDisk({ getStack: true, token });
29
32
  if (!deployedStack)
30
33
  this.error('Stack not found'); // returns
31
34
  const { projectId } = deployedStack;
32
35
  const { externalId } = findFunctionByName(deployedStack, args.name);
33
- const result = await invoke(externalId, { data: flags.data, file: flags.file }, { token: config.token, projectId });
36
+ const result = await invoke(externalId, { data: flags.data, file: flags.file }, { token, projectId });
34
37
  if (result.ok) {
35
38
  spinner.success(`Invocation of ${args.name} succeeded`);
36
39
  if (result.json?.data?.type === 'Buffer') {
@@ -18,8 +18,13 @@ export default class Logs extends Command {
18
18
  delete: import("@oclif/core/interfaces").BooleanFlag<boolean>;
19
19
  force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
20
20
  };
21
+ sanityToken: string | undefined;
21
22
  run(): Promise<void>;
22
23
  runDeleteLogs(name: string, options: RunDeleteOptions): Promise<void>;
23
24
  runGetLogs(name: string, options: RunGetOptions): Promise<void>;
25
+ getProjectAndExternalId(name: string): Promise<{
26
+ projectId?: string;
27
+ externalId?: string;
28
+ }>;
24
29
  }
25
30
  export {};
@@ -3,10 +3,10 @@ import inquirer from 'inquirer';
3
3
  import Spinner from 'yocto-spinner';
4
4
  import { readBlueprintOnDisk } from '../../actions/blueprints/blueprint.js';
5
5
  import { deleteLogs as deleteLogsAction, logs as logsAction } from '../../actions/functions/logs.js';
6
- import config from '../../config.js';
7
6
  import { formatTitle } from '../../utils/display/blueprints-formatting.js';
8
7
  import { blue, bold, green, red, yellow } from '../../utils/display/colors.js';
9
8
  import { findFunctionByName } from '../../utils/find-function.js';
9
+ import { validTokenOrErrorMessage } from '../../utils/validated-token.js';
10
10
  function logLevel(level) {
11
11
  if (level === 'ERROR') {
12
12
  return red(level);
@@ -16,16 +16,6 @@ function logLevel(level) {
16
16
  }
17
17
  return green(level);
18
18
  }
19
- // TODO extract to a shared module
20
- async function getProjectAndExternalId(name) {
21
- const { deployedStack } = await readBlueprintOnDisk({ getStack: true, token: config.token });
22
- if (!deployedStack) {
23
- return {};
24
- }
25
- const { projectId } = deployedStack;
26
- const { externalId } = findFunctionByName(deployedStack, name);
27
- return { projectId, externalId };
28
- }
29
19
  export default class Logs extends Command {
30
20
  static args = {
31
21
  name: Args.string({ description: 'The name of the Sanity Function', required: true }),
@@ -62,7 +52,12 @@ export default class Logs extends Command {
62
52
  required: false,
63
53
  }),
64
54
  };
55
+ sanityToken;
65
56
  async run() {
57
+ const { token, error: tokenErr } = await validTokenOrErrorMessage();
58
+ if (tokenErr)
59
+ this.error(tokenErr.message);
60
+ this.sanityToken = token;
66
61
  const { args, flags } = await this.parse(Logs);
67
62
  if (flags.delete === true) {
68
63
  await this.runDeleteLogs(args.name, flags);
@@ -82,13 +77,14 @@ export default class Logs extends Command {
82
77
  if (!certain)
83
78
  return;
84
79
  }
85
- const { projectId, externalId } = await getProjectAndExternalId(name);
80
+ const { projectId, externalId } = await this.getProjectAndExternalId(name);
86
81
  if (!projectId || !externalId) {
87
82
  this.error('Stack not found');
88
- return;
89
83
  }
84
+ if (!this.sanityToken)
85
+ this.error('Unable to delete logs. Missing API token.');
90
86
  const spinner = Spinner({ text: `Deleting logs for function ${yellow(name)}` }).start();
91
- const { ok, error } = await deleteLogsAction(externalId, { token: config.token, projectId });
87
+ const { ok, error } = await deleteLogsAction(externalId, { token: this.sanityToken, projectId });
92
88
  if (!ok) {
93
89
  spinner.error(`${red('Failed')} to retrieve logs`);
94
90
  this.log(`Error: ${error || 'Unknown error'}`);
@@ -98,12 +94,13 @@ export default class Logs extends Command {
98
94
  }
99
95
  async runGetLogs(name, options) {
100
96
  const spinner = Spinner({ text: `Finding logs for function "${name}"` }).start();
101
- const { projectId, externalId } = await getProjectAndExternalId(name);
97
+ const { projectId, externalId } = await this.getProjectAndExternalId(name);
102
98
  if (!projectId || !externalId) {
103
99
  this.error('Stack not found');
104
- return;
105
100
  }
106
- const { ok, error, logs, total } = await logsAction(externalId, { limit: options.limit }, { token: config.token, projectId });
101
+ if (!this.sanityToken)
102
+ this.error('Unable to retrieve logs. Missing API token.');
103
+ const { ok, error, logs, total } = await logsAction(externalId, { limit: options.limit }, { token: this.sanityToken, projectId });
107
104
  if (!ok) {
108
105
  spinner.error(`${red('Failed')} to retrieve logs`);
109
106
  this.log(`Error: ${error || 'Unknown error'}`);
@@ -131,4 +128,15 @@ export default class Logs extends Command {
131
128
  this.log(JSON.stringify(filteredLogs, null, 2));
132
129
  }
133
130
  }
131
+ async getProjectAndExternalId(name) {
132
+ if (!this.sanityToken)
133
+ this.error('Missing API token.');
134
+ const { deployedStack } = await readBlueprintOnDisk({ getStack: true, token: this.sanityToken });
135
+ if (!deployedStack) {
136
+ return {};
137
+ }
138
+ const { projectId } = deployedStack;
139
+ const { externalId } = findFunctionByName(deployedStack, name);
140
+ return { projectId, externalId };
141
+ }
134
142
  }
package/dist/config.d.ts CHANGED
@@ -1,9 +1,6 @@
1
1
  declare const _default: {
2
- token: string;
3
- apiUrl: URL;
4
- server: {
5
- functions: URL;
6
- blueprints: URL;
7
- };
2
+ isTest: boolean;
3
+ apiUrl: string;
4
+ token: string | null;
8
5
  };
9
6
  export default _default;
package/dist/config.js CHANGED
@@ -1,33 +1,45 @@
1
1
  import { env } from 'node:process';
2
2
  import getToken from './utils/get-token.js';
3
- const nodeEnv = env.SANITY_INTERNAL_ENV ?? 'production';
3
+ const nodeEnv = env.NODE_ENV?.toLowerCase() ?? 'production';
4
4
  const isTest = nodeEnv === 'test';
5
- const isDev = nodeEnv === 'development';
6
- const useProd = nodeEnv === 'production';
7
- const isPublishing = env?.PUBLISHING === 'true';
5
+ const sanityEnv = env.SANITY_INTERNAL_ENV?.toLowerCase() ?? 'production';
6
+ const sanityProd = sanityEnv === 'production';
7
+ const isPublishing = env?.PUBLISHING?.toLowerCase() === 'true';
8
8
  const apiUrls = {
9
9
  production: 'https://api.sanity.io/',
10
10
  staging: 'https://api.sanity.work/',
11
+ default: 'http://api.sanity/',
11
12
  };
12
- const apiUrl = new URL(apiUrls[nodeEnv] ?? apiUrls.production);
13
- const functionsUrls = {
14
- production: apiUrl.toString(),
15
- staging: apiUrl.toString(),
16
- default: 'http://localhost:4567',
17
- };
18
- const blueprintsUrls = {
19
- production: apiUrl.toString(),
20
- staging: apiUrl.toString(),
21
- default: 'http://blueprints/',
22
- };
23
- const functionsUrl = new URL(functionsUrls[nodeEnv] ?? functionsUrls.default);
24
- const blueprintsUrl = new URL(blueprintsUrls[nodeEnv] ?? blueprintsUrls.default);
25
- const token = isDev || isTest || isPublishing ? 'token' : getToken({ prod: useProd });
13
+ const apiUrl = apiUrls[sanityEnv] ?? apiUrls.default;
14
+ let _token = undefined;
15
+ function loadToken() {
16
+ let token = null;
17
+ if (isTest || isPublishing) {
18
+ token = 'token';
19
+ }
20
+ else {
21
+ try {
22
+ token = getToken({ prod: sanityProd });
23
+ }
24
+ catch (error) {
25
+ if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
26
+ // do nothing, validateToken and commands handle missing config file
27
+ }
28
+ else {
29
+ // rethrow other errors like JSON.parse failure
30
+ throw error;
31
+ }
32
+ }
33
+ }
34
+ return token;
35
+ }
26
36
  export default {
27
- token,
37
+ isTest,
28
38
  apiUrl,
29
- server: {
30
- functions: functionsUrl,
31
- blueprints: blueprintsUrl,
39
+ get token() {
40
+ return _token === undefined ? loadToken() : _token;
41
+ },
42
+ set token(value) {
43
+ _token = value;
32
44
  },
33
45
  };