@sanity/runtime-cli 17.3.2 → 17.4.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
@@ -90,7 +90,7 @@ EXAMPLES
90
90
  $ sanity-run blueprints add function --name my-function --fn-type document-create --fn-type document-update --lang js
91
91
  ```
92
92
 
93
- _See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v17.3.2/src/commands/blueprints/add.ts)_
93
+ _See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v17.4.0/src/commands/blueprints/add.ts)_
94
94
 
95
95
  ## `sanity-run blueprints config`
96
96
 
@@ -127,7 +127,7 @@ EXAMPLES
127
127
  $ sanity-run blueprints config --edit --project-id <projectId> --stack <name-or-id>
128
128
  ```
129
129
 
130
- _See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v17.3.2/src/commands/blueprints/config.ts)_
130
+ _See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v17.4.0/src/commands/blueprints/config.ts)_
131
131
 
132
132
  ## `sanity-run blueprints deploy`
133
133
 
@@ -181,7 +181,7 @@ EXAMPLES
181
181
  $ sanity-run blueprints deploy --new-stack-name <new-name>
182
182
  ```
183
183
 
184
- _See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v17.3.2/src/commands/blueprints/deploy.ts)_
184
+ _See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v17.4.0/src/commands/blueprints/deploy.ts)_
185
185
 
186
186
  ## `sanity-run blueprints destroy`
187
187
 
@@ -219,7 +219,7 @@ EXAMPLES
219
219
  $ sanity-run blueprints destroy --stack <name-or-id> --project-id <projectId> --force --no-wait
220
220
  ```
221
221
 
222
- _See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v17.3.2/src/commands/blueprints/destroy.ts)_
222
+ _See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v17.4.0/src/commands/blueprints/destroy.ts)_
223
223
 
224
224
  ## `sanity-run blueprints doctor`
225
225
 
@@ -251,7 +251,7 @@ EXAMPLES
251
251
  $ sanity-run blueprints doctor --fix
252
252
  ```
253
253
 
254
- _See code: [src/commands/blueprints/doctor.ts](https://github.com/sanity-io/runtime-cli/blob/v17.3.2/src/commands/blueprints/doctor.ts)_
254
+ _See code: [src/commands/blueprints/doctor.ts](https://github.com/sanity-io/runtime-cli/blob/v17.4.0/src/commands/blueprints/doctor.ts)_
255
255
 
256
256
  ## `sanity-run blueprints info`
257
257
 
@@ -288,7 +288,7 @@ EXAMPLES
288
288
  $ sanity-run blueprints info --organization-id <orgId> --stack <name-or-id>
289
289
  ```
290
290
 
291
- _See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v17.3.2/src/commands/blueprints/info.ts)_
291
+ _See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v17.4.0/src/commands/blueprints/info.ts)_
292
292
 
293
293
  ## `sanity-run blueprints init [DIR]`
294
294
 
@@ -352,7 +352,7 @@ EXAMPLES
352
352
  $ sanity-run blueprints init old-stack --type <json|js|ts> --project-id <projectId> --stack-id <existingStackId>
353
353
  ```
354
354
 
355
- _See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v17.3.2/src/commands/blueprints/init.ts)_
355
+ _See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v17.4.0/src/commands/blueprints/init.ts)_
356
356
 
357
357
  ## `sanity-run blueprints logs`
358
358
 
@@ -398,7 +398,7 @@ EXAMPLES
398
398
  $ sanity-run blueprints logs --before 2026-05-01T00:00:00Z
399
399
  ```
400
400
 
401
- _See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v17.3.2/src/commands/blueprints/logs.ts)_
401
+ _See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v17.4.0/src/commands/blueprints/logs.ts)_
402
402
 
403
403
  ## `sanity-run blueprints mint-deploy-token`
404
404
 
@@ -443,7 +443,7 @@ EXAMPLES
443
443
  $ sanity-run blueprints mint-deploy-token --organization-id <orgId>
444
444
  ```
445
445
 
446
- _See code: [src/commands/blueprints/mint-deploy-token.ts](https://github.com/sanity-io/runtime-cli/blob/v17.3.2/src/commands/blueprints/mint-deploy-token.ts)_
446
+ _See code: [src/commands/blueprints/mint-deploy-token.ts](https://github.com/sanity-io/runtime-cli/blob/v17.4.0/src/commands/blueprints/mint-deploy-token.ts)_
447
447
 
448
448
  ## `sanity-run blueprints plan`
449
449
 
@@ -476,7 +476,7 @@ EXAMPLES
476
476
  $ sanity-run blueprints plan --organization-id <orgId> --stack <name-or-id>
477
477
  ```
478
478
 
479
- _See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v17.3.2/src/commands/blueprints/plan.ts)_
479
+ _See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v17.4.0/src/commands/blueprints/plan.ts)_
480
480
 
481
481
  ## `sanity-run blueprints promote`
482
482
 
@@ -512,7 +512,7 @@ EXAMPLES
512
512
  $ sanity-run blueprints promote --new-stack-name <new-name>
513
513
  ```
514
514
 
515
- _See code: [src/commands/blueprints/promote.ts](https://github.com/sanity-io/runtime-cli/blob/v17.3.2/src/commands/blueprints/promote.ts)_
515
+ _See code: [src/commands/blueprints/promote.ts](https://github.com/sanity-io/runtime-cli/blob/v17.4.0/src/commands/blueprints/promote.ts)_
516
516
 
517
517
  ## `sanity-run blueprints stacks`
518
518
 
@@ -548,7 +548,7 @@ EXAMPLES
548
548
  $ sanity-run blueprints stacks --organization-id <organizationId> --include-projects
549
549
  ```
550
550
 
551
- _See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v17.3.2/src/commands/blueprints/stacks.ts)_
551
+ _See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v17.4.0/src/commands/blueprints/stacks.ts)_
552
552
 
553
553
  ## `sanity-run functions add`
554
554
 
@@ -600,7 +600,7 @@ EXAMPLES
600
600
  $ sanity-run functions add --name my-function --type document-create --type document-update --lang js
601
601
  ```
602
602
 
603
- _See code: [src/commands/functions/add.ts](https://github.com/sanity-io/runtime-cli/blob/v17.3.2/src/commands/functions/add.ts)_
603
+ _See code: [src/commands/functions/add.ts](https://github.com/sanity-io/runtime-cli/blob/v17.4.0/src/commands/functions/add.ts)_
604
604
 
605
605
  ## `sanity-run functions dev`
606
606
 
@@ -635,7 +635,7 @@ EXAMPLES
635
635
  $ sanity-run functions dev --timeout 60
636
636
  ```
637
637
 
638
- _See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v17.3.2/src/commands/functions/dev.ts)_
638
+ _See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v17.4.0/src/commands/functions/dev.ts)_
639
639
 
640
640
  ## `sanity-run functions env add NAME KEY VALUE`
641
641
 
@@ -668,7 +668,7 @@ EXAMPLES
668
668
  $ sanity-run functions env add --stack <name-or-id> MyFunction API_URL https://api.example.com/
669
669
  ```
670
670
 
671
- _See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v17.3.2/src/commands/functions/env/add.ts)_
671
+ _See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v17.4.0/src/commands/functions/env/add.ts)_
672
672
 
673
673
  ## `sanity-run functions env list NAME`
674
674
 
@@ -698,7 +698,7 @@ EXAMPLES
698
698
  $ sanity-run functions env list --stack <name-or-id> MyFunction
699
699
  ```
700
700
 
701
- _See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v17.3.2/src/commands/functions/env/list.ts)_
701
+ _See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v17.4.0/src/commands/functions/env/list.ts)_
702
702
 
703
703
  ## `sanity-run functions env remove NAME KEY`
704
704
 
@@ -730,7 +730,7 @@ EXAMPLES
730
730
  $ sanity-run functions env remove --stack <name-or-id> MyFunction API_URL
731
731
  ```
732
732
 
733
- _See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v17.3.2/src/commands/functions/env/remove.ts)_
733
+ _See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v17.4.0/src/commands/functions/env/remove.ts)_
734
734
 
735
735
  ## `sanity-run functions logs [NAME]`
736
736
 
@@ -770,7 +770,7 @@ EXAMPLES
770
770
  $ sanity-run functions logs <name> --delete
771
771
  ```
772
772
 
773
- _See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v17.3.2/src/commands/functions/logs.ts)_
773
+ _See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v17.4.0/src/commands/functions/logs.ts)_
774
774
 
775
775
  ## `sanity-run functions test [NAME]`
776
776
 
@@ -827,7 +827,7 @@ EXAMPLES
827
827
  $ sanity-run functions test <name> --event update --data-before '{ "title": "before" }' --data-after '{ "title": "after" }'
828
828
  ```
829
829
 
830
- _See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v17.3.2/src/commands/functions/test.ts)_
830
+ _See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v17.4.0/src/commands/functions/test.ts)_
831
831
 
832
832
  ## `sanity-run help [COMMAND]`
833
833
 
@@ -0,0 +1,34 @@
1
+ import type { Logger } from '../../utils/logger.js';
2
+ import type { AuthParams } from '../../utils/types.js';
3
+ /** A deployed function returned by the Functions API. */
4
+ export interface DeployedFunction {
5
+ id: string;
6
+ name: string | null;
7
+ displayName: string | null;
8
+ type: string | null;
9
+ runtime: string | null;
10
+ status: string | null;
11
+ memory: number | null;
12
+ storage: number | null;
13
+ timeout: number | null;
14
+ resourceType: string | null;
15
+ resourceId: string | null;
16
+ robotId: string | null;
17
+ url: string | null;
18
+ eventRule?: unknown;
19
+ contentSub?: Record<string, unknown> | null;
20
+ createdAt: string | null;
21
+ updatedAt: string | null;
22
+ deletedAt?: string | null;
23
+ }
24
+ type ListFunctionsResponse = {
25
+ ok: true;
26
+ error: null;
27
+ functions: DeployedFunction[];
28
+ } | {
29
+ ok: false;
30
+ error: string;
31
+ functions: [];
32
+ };
33
+ export declare function listFunctions(auth: AuthParams, logger: Logger): Promise<ListFunctionsResponse>;
34
+ export {};
@@ -0,0 +1,33 @@
1
+ import config from '../../config.js';
2
+ import getHeaders from '../../utils/get-headers.js';
3
+ import { createTracedFetch } from '../../utils/traced-fetch.js';
4
+ const { apiUrl } = config;
5
+ export async function listFunctions(auth, logger) {
6
+ try {
7
+ const fetchFn = createTracedFetch(logger);
8
+ const response = await fetchFn(`${apiUrl}v2025-07-30/functions/`, {
9
+ headers: getHeaders(auth),
10
+ method: 'GET',
11
+ });
12
+ const payload = (await response.json());
13
+ if (!response.ok) {
14
+ return {
15
+ ok: false,
16
+ error: payload.error?.message ?? payload.message ?? 'Failed to list functions',
17
+ functions: [],
18
+ };
19
+ }
20
+ return {
21
+ ok: true,
22
+ error: null,
23
+ functions: Array.isArray(payload.functions) ? payload.functions : [],
24
+ };
25
+ }
26
+ catch (error) {
27
+ return {
28
+ ok: false,
29
+ error: error instanceof Error ? error.message : String(error),
30
+ functions: [],
31
+ };
32
+ }
33
+ }
@@ -138,5 +138,7 @@ export declare abstract class ResolvedCommand<T extends typeof Command> extends
138
138
  protected blueprintConfig?: LocatedBlueprintsConfig | null;
139
139
  protected auth: AuthParams;
140
140
  protected deployedStack: Stack;
141
+ /** Runs after flag parsing and before declared command context is resolved. */
142
+ protected preResolve(): Promise<void>;
141
143
  init(): Promise<void>;
142
144
  }
@@ -220,8 +220,11 @@ export class ResolvedCommand extends RuntimeCommand {
220
220
  blueprintConfig;
221
221
  auth;
222
222
  deployedStack;
223
+ /** Runs after flag parsing and before declared command context is resolved. */
224
+ async preResolve() { }
223
225
  async init() {
224
226
  await super.init(); // RuntimeCommand: parse flags + args
227
+ await this.preResolve();
225
228
  const needs = new Set(this.constructor.needs);
226
229
  if (needs.size === 0)
227
230
  return;
@@ -11,7 +11,9 @@ export default class DeployCommand extends ResolvedCommand<typeof DeployCommand>
11
11
  message: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
12
  'fn-installer': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
13
  'no-wait': import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
+ configure: import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
15
  'new-stack-name': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
15
16
  };
17
+ protected preResolve(): Promise<void>;
16
18
  run(): Promise<Record<string, unknown> | undefined>;
17
19
  }
@@ -21,6 +21,7 @@ Exit codes: 0 deployed, 2 deployment failed, 75 deployment accepted but completi
21
21
  '<%= config.bin %> <%= command.id %>',
22
22
  '<%= config.bin %> <%= command.id %> --message "Enable staging dataset"',
23
23
  '<%= config.bin %> <%= command.id %> --no-wait',
24
+ // '<%= config.bin %> <%= command.id %> --configure',
24
25
  '<%= config.bin %> <%= command.id %> --fn-installer npm',
25
26
  '<%= config.bin %> <%= command.id %> --stack <name-or-id>',
26
27
  '<%= config.bin %> <%= command.id %> --organization-id <orgId> --stack <name-or-id>',
@@ -44,10 +45,28 @@ Exit codes: 0 deployed, 2 deployment failed, 75 deployment accepted but completi
44
45
  description: 'Do not wait for Stack deployment to complete',
45
46
  default: false,
46
47
  }),
48
+ configure: Flags.boolean({
49
+ description: 'Configure the local Blueprint interactively before deploying',
50
+ aliases: ['config', 'init'],
51
+ default: false,
52
+ hidden: true,
53
+ }),
47
54
  'new-stack-name': Flags.string({
48
55
  description: 'Set a new name for the Stack',
49
56
  }),
50
57
  };
58
+ async preResolve() {
59
+ if (!this.flags.configure)
60
+ return;
61
+ const args = ['--edit'];
62
+ if (this.flags.path)
63
+ args.push('--path', this.flags.path);
64
+ if (!this.flags['validate-resources'])
65
+ args.push('--no-validate-resources');
66
+ if (this.flags.verbose)
67
+ args.push('--verbose');
68
+ await this.config.runCommand('blueprints:config', args);
69
+ }
51
70
  async run() {
52
71
  const result = await blueprintDeployCore({
53
72
  bin: this.config.bin,
@@ -0,0 +1,14 @@
1
+ import { ResolvedCommand } from '../../baseCommands.js';
2
+ export default class FunctionsListCommand extends ResolvedCommand<typeof FunctionsListCommand> {
3
+ static needs: readonly ['scope'];
4
+ static hidden: boolean;
5
+ static summary: string;
6
+ static description: string;
7
+ static examples: string[];
8
+ static flags: {
9
+ 'project-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ 'organization-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
+ };
13
+ run(): Promise<Record<string, unknown> | undefined>;
14
+ }
@@ -0,0 +1,38 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { organizationIdFlagConfig, projectIdFlagConfig, ResolvedCommand } from '../../baseCommands.js';
3
+ import { functionListCore } from '../../cores/functions/list.js';
4
+ import { Logger } from '../../utils/logger.js';
5
+ export default class FunctionsListCommand extends ResolvedCommand {
6
+ static needs = ['scope'];
7
+ static hidden = true;
8
+ static summary = 'List deployed Sanity Functions';
9
+ static description = `Lists functions deployed directly in the selected project or organization scope. The local Blueprint config supplies the scope by default.
10
+
11
+ Use --project-id or --organization-id to select a scope without a local Blueprint. Organization results include organization-scoped functions only.`;
12
+ static examples = [
13
+ '<%= config.bin %> <%= command.id %>',
14
+ '<%= config.bin %> <%= command.id %> --verbose',
15
+ '<%= config.bin %> <%= command.id %> --project-id <projectId>',
16
+ '<%= config.bin %> <%= command.id %> --organization-id <organizationId>',
17
+ '<%= config.bin %> <%= command.id %> --project-id <projectId> --json',
18
+ ];
19
+ static flags = {
20
+ 'project-id': Flags.string({ ...projectIdFlagConfig }),
21
+ 'organization-id': Flags.string({ ...organizationIdFlagConfig }),
22
+ verbose: Flags.boolean({
23
+ char: 'v',
24
+ description: 'Show function configuration details',
25
+ default: false,
26
+ }),
27
+ };
28
+ async run() {
29
+ const result = await functionListCore({
30
+ log: Logger(this.log.bind(this), this.flags),
31
+ auth: this.auth,
32
+ flags: this.flags,
33
+ });
34
+ if (!result.success)
35
+ this.coreError(result);
36
+ return result.json;
37
+ }
38
+ }
@@ -0,0 +1,10 @@
1
+ import type { AuthParams } from '../../utils/types.js';
2
+ import type { CoreConfig, CoreResult } from '../index.js';
3
+ export interface FunctionListOptions extends Pick<CoreConfig, 'log'> {
4
+ auth: AuthParams;
5
+ flags: {
6
+ json?: boolean;
7
+ verbose?: boolean;
8
+ };
9
+ }
10
+ export declare function functionListCore(options: FunctionListOptions): Promise<CoreResult>;
@@ -0,0 +1,34 @@
1
+ import { listFunctions } from '../../actions/functions/list.js';
2
+ import { formatFunctionsList } from '../../utils/display/functions-formatting.js';
3
+ import { capitalize, niceId } from '../../utils/display/presenters.js';
4
+ import { styleText } from '../../utils/style-text.js';
5
+ export async function functionListCore(options) {
6
+ const { auth, flags, log } = options;
7
+ const { scopeId, scopeType } = auth;
8
+ const spinner = flags.json ? undefined : log.ora('Fetching functions...').start();
9
+ const result = await listFunctions(auth, log);
10
+ if (!result.ok) {
11
+ spinner?.fail('Failed to list functions');
12
+ const suggestions = /access|permission|forbidden/i.test(result.error)
13
+ ? [
14
+ `Verify you have access to ${scopeType} "${scopeId}".`,
15
+ 'Try a different scope with --project-id or --organization-id.',
16
+ ]
17
+ : undefined;
18
+ return { success: false, error: result.error, suggestions };
19
+ }
20
+ spinner?.stop().clear();
21
+ if (!flags.json) {
22
+ if (result.functions.length === 0) {
23
+ log(`No functions found for ${scopeType} ${niceId(scopeId)}`);
24
+ }
25
+ else {
26
+ log(`${styleText('bold', capitalize(scopeType))} ${niceId(scopeId)} ${styleText('bold', 'Functions')} [${result.functions.length}]:`);
27
+ log(formatFunctionsList(result.functions, { verbose: flags.verbose }));
28
+ }
29
+ }
30
+ return {
31
+ success: true,
32
+ json: { functions: result.functions, scopeType, scopeId },
33
+ };
34
+ }
@@ -0,0 +1,7 @@
1
+ import type { DeployedFunction } from '../../actions/functions/list.js';
2
+ export declare function formatFunctionsList(functions: DeployedFunction[], options?: {
3
+ verbose?: boolean;
4
+ }): string;
5
+ export declare function formatFunction(fn: DeployedFunction, options?: {
6
+ verbose?: boolean;
7
+ }): string;
@@ -0,0 +1,95 @@
1
+ import { SANITY_FUNCTION_PREFIX } from '../../constants.js';
2
+ import { styleText } from '../style-text.js';
3
+ import { formatDateTime } from './dates.js';
4
+ import { niceId, renderSection } from './presenters.js';
5
+ export function formatFunctionsList(functions, options = {}) {
6
+ if (!options.verbose)
7
+ return formatCompactList(functions);
8
+ return functions.map((fn) => formatFunction(fn, options)).join('\n');
9
+ }
10
+ export function formatFunction(fn, options = {}) {
11
+ if (!options.verbose)
12
+ return formatCompactList([fn]);
13
+ const rows = [];
14
+ if (fn.type)
15
+ rows.push(['Type', shortType(fn.type)]);
16
+ if (fn.updatedAt) {
17
+ const updatedAt = formatDateTime(fn.updatedAt);
18
+ if (updatedAt)
19
+ rows.push(['Updated', updatedAt]);
20
+ }
21
+ if (typeof fn.memory === 'number')
22
+ rows.push(['Memory', `${fn.memory} MB`]);
23
+ if (typeof fn.timeout === 'number')
24
+ rows.push(['Timeout', `${fn.timeout}s`]);
25
+ const rule = formatEventRule(fn.eventRule);
26
+ if (rule)
27
+ rows.push(['Rule', rule]);
28
+ return renderSection(formatTitle(fn), rows);
29
+ }
30
+ function formatCompactList(functions) {
31
+ const titles = functions.map(plainTitle);
32
+ const ids = functions.map((fn) => `<${fn.id}>`);
33
+ const types = functions.map((fn) => (fn.type ? shortType(fn.type) : '-'));
34
+ const updated = functions.map((fn) => (fn.updatedAt ? formatDateTime(fn.updatedAt) || '-' : '-'));
35
+ const titlePad = Math.max(...titles.map((title) => title.length));
36
+ const idPad = Math.max(...ids.map((id) => id.length));
37
+ const typePad = Math.max(...types.map((type) => type.length));
38
+ return functions
39
+ .map((fn, index) => {
40
+ const title = formatIdentity(fn) + ' '.repeat(titlePad - titles[index].length);
41
+ const id = niceId(fn.id) + ' '.repeat(idPad - ids[index].length);
42
+ const type = styleText('dim', types[index].padEnd(typePad));
43
+ const timestamp = styleText('dim', updated[index]);
44
+ return ` ${title} ${id} ${type} ${timestamp}`;
45
+ })
46
+ .join('\n');
47
+ }
48
+ function formatTitle(fn) {
49
+ return `${formatIdentity(fn)} ${niceId(fn.id)}`;
50
+ }
51
+ function formatIdentity(fn) {
52
+ const parts = [];
53
+ if (fn.name)
54
+ parts.push(styleText('bold', fn.name));
55
+ if (fn.displayName && fn.displayName !== fn.name) {
56
+ parts.push(styleText('green', `"${fn.displayName}"`));
57
+ }
58
+ if (parts.length === 0)
59
+ parts.push(styleText('bold', 'Unnamed'));
60
+ return parts.join(' ');
61
+ }
62
+ function plainTitle(fn) {
63
+ const parts = [];
64
+ if (fn.name)
65
+ parts.push(fn.name);
66
+ if (fn.displayName && fn.displayName !== fn.name)
67
+ parts.push(`"${fn.displayName}"`);
68
+ return parts.length > 0 ? parts.join(' ') : 'Unnamed';
69
+ }
70
+ function shortType(type) {
71
+ return type.startsWith(SANITY_FUNCTION_PREFIX) ? type.slice(SANITY_FUNCTION_PREFIX.length) : type;
72
+ }
73
+ function formatEventRule(rule) {
74
+ if (rule === null || rule === undefined)
75
+ return undefined;
76
+ if (typeof rule !== 'object')
77
+ return String(rule);
78
+ if (Array.isArray(rule))
79
+ return rule.map(formatRuleValue).join(', ');
80
+ const entries = Object.entries(rule);
81
+ if (entries.length === 0)
82
+ return undefined;
83
+ return entries.map(([key, value]) => `${key}: ${formatRuleValue(value)}`).join(' · ');
84
+ }
85
+ function formatRuleValue(value) {
86
+ if (typeof value === 'string')
87
+ return value;
88
+ if (value === null || value === undefined)
89
+ return String(value);
90
+ if (Array.isArray(value))
91
+ return value.map(formatRuleValue).join(', ');
92
+ if (typeof value === 'object')
93
+ return JSON.stringify(value);
94
+ return String(value);
95
+ }
@@ -491,6 +491,17 @@
491
491
  "allowNo": false,
492
492
  "type": "boolean"
493
493
  },
494
+ "configure": {
495
+ "aliases": [
496
+ "config",
497
+ "init"
498
+ ],
499
+ "description": "Configure the local Blueprint interactively before deploying",
500
+ "hidden": true,
501
+ "name": "configure",
502
+ "allowNo": false,
503
+ "type": "boolean"
504
+ },
494
505
  "new-stack-name": {
495
506
  "description": "Set a new name for the Stack",
496
507
  "name": "new-stack-name",
@@ -2146,6 +2157,117 @@
2146
2157
  "dev.js"
2147
2158
  ]
2148
2159
  },
2160
+ "functions:list": {
2161
+ "aliases": [],
2162
+ "args": {},
2163
+ "description": "Lists functions deployed directly in the selected project or organization scope. The local Blueprint config supplies the scope by default.\n\nUse --project-id or --organization-id to select a scope without a local Blueprint. Organization results include organization-scoped functions only.",
2164
+ "examples": [
2165
+ "<%= config.bin %> <%= command.id %>",
2166
+ "<%= config.bin %> <%= command.id %> --verbose",
2167
+ "<%= config.bin %> <%= command.id %> --project-id <projectId>",
2168
+ "<%= config.bin %> <%= command.id %> --organization-id <organizationId>",
2169
+ "<%= config.bin %> <%= command.id %> --project-id <projectId> --json"
2170
+ ],
2171
+ "flags": {
2172
+ "json": {
2173
+ "description": "Format output as json",
2174
+ "name": "json",
2175
+ "allowNo": false,
2176
+ "type": "boolean"
2177
+ },
2178
+ "path": {
2179
+ "aliases": [
2180
+ "blueprint-path"
2181
+ ],
2182
+ "char": "p",
2183
+ "description": "Path to a Blueprint file or directory containing one",
2184
+ "env": "SANITY_BLUEPRINT_PATH",
2185
+ "hidden": true,
2186
+ "name": "path",
2187
+ "hasDynamicHelp": false,
2188
+ "multiple": false,
2189
+ "type": "option"
2190
+ },
2191
+ "trace": {
2192
+ "description": "Trace output",
2193
+ "hidden": true,
2194
+ "name": "trace",
2195
+ "allowNo": false,
2196
+ "type": "boolean"
2197
+ },
2198
+ "validate-resources": {
2199
+ "description": "Validate resources",
2200
+ "hidden": true,
2201
+ "name": "validate-resources",
2202
+ "allowNo": true,
2203
+ "type": "boolean"
2204
+ },
2205
+ "verbose": {
2206
+ "char": "v",
2207
+ "description": "Show function configuration details",
2208
+ "name": "verbose",
2209
+ "allowNo": false,
2210
+ "type": "boolean"
2211
+ },
2212
+ "stack": {
2213
+ "description": "Stack name or ID to use instead of the locally configured Stack",
2214
+ "hidden": true,
2215
+ "name": "stack",
2216
+ "hasDynamicHelp": false,
2217
+ "multiple": false,
2218
+ "type": "option"
2219
+ },
2220
+ "project-id": {
2221
+ "aliases": [
2222
+ "project",
2223
+ "projectId"
2224
+ ],
2225
+ "description": "Sanity project ID used to scope Blueprint and Stack",
2226
+ "exclusive": [
2227
+ "organization-id"
2228
+ ],
2229
+ "name": "project-id",
2230
+ "hasDynamicHelp": false,
2231
+ "multiple": false,
2232
+ "type": "option"
2233
+ },
2234
+ "organization-id": {
2235
+ "aliases": [
2236
+ "organization",
2237
+ "organizationId",
2238
+ "org"
2239
+ ],
2240
+ "description": "Sanity organization ID used to scope Blueprint and Stack",
2241
+ "exclusive": [
2242
+ "project-id"
2243
+ ],
2244
+ "name": "organization-id",
2245
+ "hasDynamicHelp": false,
2246
+ "multiple": false,
2247
+ "type": "option"
2248
+ }
2249
+ },
2250
+ "hasDynamicHelp": false,
2251
+ "hidden": true,
2252
+ "hiddenAliases": [],
2253
+ "id": "functions:list",
2254
+ "pluginAlias": "@sanity/runtime-cli",
2255
+ "pluginName": "@sanity/runtime-cli",
2256
+ "pluginType": "core",
2257
+ "strict": true,
2258
+ "summary": "List deployed Sanity Functions",
2259
+ "enableJsonFlag": true,
2260
+ "needs": [
2261
+ "scope"
2262
+ ],
2263
+ "isESM": true,
2264
+ "relativePath": [
2265
+ "dist",
2266
+ "commands",
2267
+ "functions",
2268
+ "list.js"
2269
+ ]
2270
+ },
2149
2271
  "functions:logs": {
2150
2272
  "aliases": [],
2151
2273
  "args": {
@@ -2998,5 +3120,5 @@
2998
3120
  ]
2999
3121
  }
3000
3122
  },
3001
- "version": "17.3.2"
3123
+ "version": "17.4.0"
3002
3124
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sanity/runtime-cli",
3
3
  "description": "Sanity's Runtime CLI for Blueprints and Functions",
4
- "version": "17.3.2",
4
+ "version": "17.4.0",
5
5
  "author": "Sanity Runtime Team",
6
6
  "type": "module",
7
7
  "license": "MIT",
@@ -68,9 +68,9 @@
68
68
  "@sanity-labs/design-tokens": "^0.0.2-alpha.2",
69
69
  "@sanity/blueprints": "^0.23.1",
70
70
  "@sanity/blueprints-parser": "^0.4.0",
71
- "@sanity/cli-build": "^5.0.0",
72
- "@sanity/cli-core": "^2.5.1",
73
- "@sanity/client": "^7.25.0",
71
+ "@sanity/cli-build": "^5.1.0",
72
+ "@sanity/cli-core": "^2.7.1",
73
+ "@sanity/client": "^7.26.0",
74
74
  "adm-zip": "^0.6.0",
75
75
  "array-treeify": "^0.1.5",
76
76
  "cardinal": "^2.1.1",
@@ -89,15 +89,15 @@
89
89
  "xdg-basedir": "^5.1.0"
90
90
  },
91
91
  "devDependencies": {
92
- "@biomejs/biome": "2.5.5",
92
+ "@biomejs/biome": "2.5.6",
93
93
  "@codemirror/lang-json": "^6.0.2",
94
94
  "@codemirror/state": "^6.7.1",
95
95
  "@enhance/store": "^1.0.2",
96
96
  "@lezer/highlight": "^1.2.3",
97
97
  "@oclif/test": "^4.1.21",
98
- "@playwright/test": "^1.62.0",
98
+ "@playwright/test": "^1.62.1",
99
99
  "@rollup/plugin-node-resolve": "^16.0.3",
100
- "@sanity/functions": "^1.4.0",
100
+ "@sanity/functions": "^1.5.0",
101
101
  "@types/adm-zip": "^0.5.8",
102
102
  "@types/cardinal": "^2.1.1",
103
103
  "@types/mime-types": "^3.0.1",