@sanity/runtime-cli 14.12.0 → 14.13.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.
Files changed (60) hide show
  1. package/README.md +26 -21
  2. package/dist/actions/blueprints/blueprint.d.ts +17 -0
  3. package/dist/actions/blueprints/blueprint.js +24 -20
  4. package/dist/actions/blueprints/resolve.d.ts +11 -6
  5. package/dist/actions/blueprints/resolve.js +14 -4
  6. package/dist/actions/functions/dev.d.ts +1 -2
  7. package/dist/actions/functions/dev.js +2 -2
  8. package/dist/actions/sanity/projects.d.ts +2 -1
  9. package/dist/actions/sanity/projects.js +5 -2
  10. package/dist/baseCommands.d.ts +10 -23
  11. package/dist/baseCommands.js +26 -75
  12. package/dist/commands/blueprints/add.d.ts +3 -2
  13. package/dist/commands/blueprints/add.js +3 -2
  14. package/dist/commands/blueprints/config.d.ts +3 -2
  15. package/dist/commands/blueprints/config.js +3 -2
  16. package/dist/commands/blueprints/deploy.d.ts +3 -2
  17. package/dist/commands/blueprints/deploy.js +4 -3
  18. package/dist/commands/blueprints/destroy.d.ts +3 -2
  19. package/dist/commands/blueprints/destroy.js +3 -2
  20. package/dist/commands/blueprints/doctor.d.ts +0 -1
  21. package/dist/commands/blueprints/doctor.js +2 -3
  22. package/dist/commands/blueprints/init.d.ts +0 -1
  23. package/dist/commands/blueprints/init.js +1 -2
  24. package/dist/commands/blueprints/logs.d.ts +3 -2
  25. package/dist/commands/blueprints/logs.js +4 -3
  26. package/dist/commands/blueprints/plan.d.ts +3 -2
  27. package/dist/commands/blueprints/plan.js +5 -3
  28. package/dist/commands/blueprints/promote.d.ts +3 -2
  29. package/dist/commands/blueprints/promote.js +3 -2
  30. package/dist/commands/blueprints/stacks.d.ts +4 -2
  31. package/dist/commands/blueprints/stacks.js +15 -4
  32. package/dist/commands/functions/add.d.ts +3 -2
  33. package/dist/commands/functions/add.js +3 -2
  34. package/dist/commands/functions/build.d.ts +3 -2
  35. package/dist/commands/functions/build.js +3 -2
  36. package/dist/commands/functions/dev.d.ts +3 -2
  37. package/dist/commands/functions/dev.js +3 -2
  38. package/dist/commands/functions/env/add.d.ts +3 -2
  39. package/dist/commands/functions/env/add.js +3 -2
  40. package/dist/commands/functions/env/list.d.ts +3 -2
  41. package/dist/commands/functions/env/list.js +3 -2
  42. package/dist/commands/functions/env/remove.d.ts +3 -2
  43. package/dist/commands/functions/env/remove.js +3 -2
  44. package/dist/commands/functions/logs.d.ts +3 -2
  45. package/dist/commands/functions/logs.js +4 -3
  46. package/dist/commands/functions/test.d.ts +3 -2
  47. package/dist/commands/functions/test.js +3 -2
  48. package/dist/cores/blueprints/config.js +9 -4
  49. package/dist/cores/blueprints/destroy.js +78 -56
  50. package/dist/cores/blueprints/doctor.js +19 -5
  51. package/dist/cores/blueprints/init.js +2 -2
  52. package/dist/cores/blueprints/stacks.d.ts +1 -0
  53. package/dist/cores/blueprints/stacks.js +73 -2
  54. package/dist/cores/functions/dev.js +1 -1
  55. package/dist/server/app.d.ts +1 -2
  56. package/dist/server/app.js +16 -8
  57. package/dist/server/handlers/invoke.d.ts +1 -2
  58. package/dist/server/handlers/invoke.js +4 -4
  59. package/oclif.manifest.json +17 -18
  60. package/package.json +1 -1
@@ -8,7 +8,7 @@ import { styleText } from '../../utils/style-text.js';
8
8
  export async function blueprintDestroyCore(options) {
9
9
  const { bin = 'sanity', log, token, blueprint, flags } = options;
10
10
  const { force = false, 'project-id': flagProjectId, 'organization-id': flagOrganizationId, stack: flagStack, 'no-wait': noWait = false, verbose: _verbose = false, } = flags;
11
- // 3-flag combo: just destroy it
11
+ // 3-flag combo: destroy without needing a local blueprint config
12
12
  if ((flagProjectId || flagOrganizationId) && flagStack && force) {
13
13
  let scopeType;
14
14
  let scopeId;
@@ -25,6 +25,7 @@ export async function blueprintDestroyCore(options) {
25
25
  }
26
26
  const auth = { token, scopeType, scopeId };
27
27
  const resolvedId = await resolveStackIdByNameOrId(flagStack, auth, log);
28
+ const isoNow = new Date().toISOString();
28
29
  const { ok, error, stack } = await destroyStack({
29
30
  stackId: resolvedId,
30
31
  auth,
@@ -32,8 +33,18 @@ export async function blueprintDestroyCore(options) {
32
33
  });
33
34
  if (!ok)
34
35
  return { success: false, error: error || 'Failed to destroy Stack deployment' };
35
- log(`Stack deployment "${stack.name}" ${niceId(stack.id)} destroyed`);
36
- return { success: true, json: { stackId: stack.id, stackName: stack.name } };
36
+ if (noWait) {
37
+ log(styleText(['bold', 'magenta'], 'Stack destruction started!'));
38
+ return { success: true, json: { stackId: stack.id, stackName: stack.name } };
39
+ }
40
+ return waitForDestruction({
41
+ stackId: stack.id,
42
+ stackName: stack.name,
43
+ auth,
44
+ log,
45
+ bin,
46
+ since: isoNow,
47
+ });
37
48
  }
38
49
  const { scopeType, scopeId, stackId } = blueprint;
39
50
  if (!scopeType || !scopeId)
@@ -103,62 +114,73 @@ export async function blueprintDestroyCore(options) {
103
114
  log(styleText(['bold', 'magenta'], 'Stack destruction started!'));
104
115
  return { success: true, json: { stackId: stack.id, stackName: stack.name } };
105
116
  }
106
- log(styleText('dim', 'Stack destruction progress:'));
107
- const logHints = createLogHintCollector(bin);
108
- let logStreamCleanup = null;
109
- try {
110
- let lastLogAt = Date.now();
111
- let idleMessageShown = false;
112
- logStreamCleanup = await setupLogStreaming({
113
- stackId: stack.id,
114
- after: isoNow,
115
- auth,
116
- log,
117
- onActivity: () => {
118
- lastLogAt = Date.now();
119
- },
120
- onLogEntry: (logEntry) => logHints.inspect(logEntry),
121
- });
122
- while (true) {
123
- const { ok, stack: currentStack } = await getStack({ stackId: stack.id, auth, logger: log });
124
- const operation = currentStack?.recentOperation;
125
- if (!ok || !operation || operation?.status === 'COMPLETED') {
126
- // Operation is also marked destroyed when stack is deleted;
127
- // it's possible that the operation is "gone" or available and "COMPLETED"
128
- if (logStreamCleanup)
129
- logStreamCleanup();
130
- log(styleText(['bold', 'magenta'], 'Stack destruction completed!'));
131
- return { success: true, json: { stackId: stack.id, stackName: stack.name } };
132
- }
133
- if (operation.status === 'FAILED') {
134
- if (logStreamCleanup)
135
- logStreamCleanup();
136
- return {
137
- success: false,
138
- error: 'Stack destruction failed',
139
- suggestions: [
140
- ...logHints.getSuggestions(),
141
- `Run \`npx ${bin} blueprints logs\` to review destruction logs.`,
142
- `Run \`npx ${bin} blueprints info\` to view current Stack status.`,
143
- ],
144
- };
145
- }
146
- if (!idleMessageShown && Date.now() - lastLogAt > 60_000) {
147
- log(`No new activity for 60 seconds. The destruction is still running on Sanity servers.`);
148
- log(`You can safely exit and check status later with \`npx ${bin} blueprints info\`.`);
149
- idleMessageShown = true;
150
- }
151
- await sleep(1500);
152
- }
153
- }
154
- catch (error) {
155
- if (logStreamCleanup)
156
- logStreamCleanup();
157
- throw error;
158
- }
117
+ return waitForDestruction({
118
+ stackId: stack.id,
119
+ stackName: stack.name,
120
+ auth,
121
+ log,
122
+ bin,
123
+ since: isoNow,
124
+ });
159
125
  }
160
126
  catch (error) {
161
127
  const errorMessage = error instanceof Error ? error.message : String(error);
162
128
  return { success: false, error: errorMessage };
163
129
  }
164
130
  }
131
+ async function waitForDestruction(options) {
132
+ const { stackId, stackName, auth, log, bin, since } = options;
133
+ log(styleText('dim', 'Stack destruction progress:'));
134
+ const logHints = createLogHintCollector(bin);
135
+ let logStreamCleanup = null;
136
+ try {
137
+ let lastLogAt = Date.now();
138
+ let idleMessageShown = false;
139
+ logStreamCleanup = await setupLogStreaming({
140
+ stackId,
141
+ after: since,
142
+ auth,
143
+ log,
144
+ onActivity: () => {
145
+ lastLogAt = Date.now();
146
+ },
147
+ onLogEntry: (logEntry) => logHints.inspect(logEntry),
148
+ });
149
+ while (true) {
150
+ const { ok, stack: currentStack } = await getStack({ stackId, auth, logger: log });
151
+ const operation = currentStack?.recentOperation;
152
+ if (!ok || !operation || operation?.status === 'COMPLETED') {
153
+ // Operation is also marked destroyed when stack is deleted;
154
+ // it's possible that the operation is "gone" or available and "COMPLETED"
155
+ if (logStreamCleanup)
156
+ logStreamCleanup();
157
+ log(styleText(['bold', 'magenta'], 'Stack destruction completed!'));
158
+ return { success: true, json: { stackId, stackName } };
159
+ }
160
+ if (operation.status === 'FAILED') {
161
+ if (logStreamCleanup)
162
+ logStreamCleanup();
163
+ return {
164
+ success: false,
165
+ error: 'Stack destruction failed',
166
+ suggestions: [
167
+ ...logHints.getSuggestions(),
168
+ `Run \`npx ${bin} blueprints logs\` to review destruction logs.`,
169
+ `Run \`npx ${bin} blueprints info\` to view current Stack status.`,
170
+ ],
171
+ };
172
+ }
173
+ if (!idleMessageShown && Date.now() - lastLogAt > 60_000) {
174
+ log(`No new activity for 60 seconds. The destruction is still running on Sanity servers.`);
175
+ log(`You can safely exit and check status later with \`npx ${bin} blueprints info\`.`);
176
+ idleMessageShown = true;
177
+ }
178
+ await sleep(1500);
179
+ }
180
+ }
181
+ catch (error) {
182
+ if (logStreamCleanup)
183
+ logStreamCleanup();
184
+ throw error;
185
+ }
186
+ }
@@ -2,7 +2,9 @@ import { readFileSync } from 'node:fs';
2
2
  import { arch, cwd, env, version as nodeVersion, platform } from 'node:process';
3
3
  import * as resolve from 'empathic/resolve';
4
4
  import ora from 'ora';
5
- import { readLocalBlueprint, } from '../../actions/blueprints/blueprint.js';
5
+ import { loadAndParseBlueprint, } from '../../actions/blueprints/blueprint.js';
6
+ import { readConfigFile } from '../../actions/blueprints/config.js';
7
+ import { resolveIds } from '../../actions/blueprints/resolve.js';
6
8
  import { getStack } from '../../actions/blueprints/stacks.js';
7
9
  import config, { RUNTIME_CLI_VERSION } from '../../config.js';
8
10
  import { check, filePathRelativeToCwd, niceId, renderSection, severe, unsure, } from '../../utils/display/presenters.js';
@@ -76,15 +78,27 @@ export async function blueprintDoctorCore(options) {
76
78
  // --- BLUEPRINT ---
77
79
  let localBlueprint;
78
80
  try {
79
- localBlueprint = await readLocalBlueprint(log, { resources: options.validateResources || false }, path);
80
- envRows.push(['Blueprint', filePathRelativeToCwd(localBlueprint.fileInfo.blueprintFilePath)]);
81
- if (localBlueprint.errors.length === 0) {
81
+ const blueprint = await loadAndParseBlueprint(path, {
82
+ validateResources: options.validateResources || false,
83
+ });
84
+ const blueprintConfig = readConfigFile(blueprint.fileInfo.blueprintFilePath);
85
+ const resolved = resolveIds({
86
+ module: blueprint.module,
87
+ config: blueprintConfig,
88
+ });
89
+ localBlueprint = {
90
+ ...blueprint,
91
+ blueprintConfig,
92
+ ...resolved,
93
+ };
94
+ envRows.push(['Blueprint', filePathRelativeToCwd(blueprint.fileInfo.blueprintFilePath)]);
95
+ if (blueprint.errors.length === 0) {
82
96
  diagnostics.blueprintValid = { status: true };
83
97
  }
84
98
  else {
85
99
  diagnostics.blueprintValid = {
86
100
  status: false,
87
- detail: `${localBlueprint.errors.length} error(s)`,
101
+ detail: `${blueprint.errors.length} error(s)`,
88
102
  };
89
103
  }
90
104
  }
@@ -17,7 +17,7 @@ const SCOPE_PROJECT = 'project';
17
17
  const SCOPE_ORGANIZATION = 'organization';
18
18
  export async function blueprintInitCore(options) {
19
19
  const { bin = 'sanity', log, token, knownProjectId, args, flags, validateResources } = options;
20
- const { dir: flagDir, example: flagExample, 'blueprint-type': flagBlueprintType, 'project-id': flagProjectId, 'organization-id': flagOrganizationId, 'stack-id': flagStackId, 'stack-name': flagStackName, verbose: v = false, } = flags;
20
+ const { dir: flagDir, example: flagExample, 'blueprint-type': flagBlueprintType, 'project-id': flagProjectId, 'organization-id': flagOrganizationId, 'stack-id': flagStackId, 'stack-name': flagStackName, verbose = false, } = flags;
21
21
  const { dir: argDir } = args;
22
22
  const userProvidedDirName = argDir || flagDir;
23
23
  const blueprintDir = userProvidedDirName || '.';
@@ -44,7 +44,7 @@ export async function blueprintInitCore(options) {
44
44
  flagOrganizationId,
45
45
  flagStackId,
46
46
  flagStackName,
47
- verbose: v,
47
+ verbose,
48
48
  });
49
49
  }
50
50
  // --example flag → scaffold from an example template
@@ -3,6 +3,7 @@ export interface BlueprintStacksOptions extends BlueprintConfig {
3
3
  flags: {
4
4
  'project-id'?: string;
5
5
  'organization-id'?: string;
6
+ 'include-projects'?: boolean;
6
7
  verbose?: boolean;
7
8
  };
8
9
  }
@@ -1,11 +1,14 @@
1
1
  import { listStacks } from '../../actions/blueprints/stacks.js';
2
+ import { listProjects } from '../../actions/sanity/projects.js';
2
3
  import { formatStacksListing } from '../../utils/display/blueprints-formatting.js';
3
- import { capitalize, niceId } from '../../utils/display/presenters.js';
4
+ import { capitalize, niceId, warn } from '../../utils/display/presenters.js';
4
5
  import { styleText } from '../../utils/style-text.js';
6
+ /** Max projects to query for stacks during --include-projects */
7
+ const PROJECT_LIMIT = 50;
5
8
  export async function blueprintStacksCore(options) {
6
9
  const { log, token, blueprint, flags } = options;
7
10
  const { scopeType: blueprintScopeType, scopeId: blueprintScopeId, stackId: blueprintStackId, } = blueprint;
8
- const { 'project-id': flagProjectId, 'organization-id': flagOrganizationId, verbose: _verbose = false, } = flags;
11
+ const { 'project-id': flagProjectId, 'organization-id': flagOrganizationId, 'include-projects': includeProjects = false, verbose: _verbose = false, } = flags;
9
12
  if (flagOrganizationId && flagProjectId) {
10
13
  log.error('Cannot specify both --organization-id and --project-id');
11
14
  return { success: false, error: 'Cannot specify both --organization-id and --project-id' };
@@ -27,6 +30,9 @@ export async function blueprintStacksCore(options) {
27
30
  suggestions: ['Run in a Blueprint directory or provide a project with --project-id.'],
28
31
  };
29
32
  }
33
+ if (includeProjects && scopeType === 'organization') {
34
+ return deepListStacks({ organizationId: scopeId, token, log, blueprintStackId });
35
+ }
30
36
  try {
31
37
  const spinner = log.ora('Fetching Stacks...').start();
32
38
  const { ok, stacks, error } = await listStacks({ token, scopeType, scopeId }, log);
@@ -57,3 +63,68 @@ export async function blueprintStacksCore(options) {
57
63
  return { success: false, error: errorMessage };
58
64
  }
59
65
  }
66
+ async function deepListStacks(options) {
67
+ const { organizationId, token, log, blueprintStackId } = options;
68
+ const allStacks = [];
69
+ const spinner = log.ora('Fetching Stacks...').start();
70
+ try {
71
+ // 1. Org-scoped stacks
72
+ const orgResult = await listStacks({ token, scopeType: 'organization', scopeId: organizationId }, log);
73
+ const orgStacks = orgResult.ok ? orgResult.stacks : [];
74
+ // 2. Get projects in the organization
75
+ const projectsResult = await listProjects({ token, organizationId, logger: log });
76
+ if (!projectsResult.ok) {
77
+ spinner.fail('Failed to list projects');
78
+ return { success: false, error: projectsResult.error || 'Failed to list projects' };
79
+ }
80
+ const projects = projectsResult.projects;
81
+ const totalProjects = projects.length;
82
+ const cappedProjects = projects.slice(0, PROJECT_LIMIT);
83
+ // 3. Fetch stacks for each project
84
+ const projectGroups = [];
85
+ for (let i = 0; i < cappedProjects.length; i++) {
86
+ const project = cappedProjects[i];
87
+ spinner.text = `Fetching Stacks... (project ${i + 1}/${cappedProjects.length})`;
88
+ const result = await listStacks({ token, scopeType: 'project', scopeId: project.id }, log);
89
+ if (result.ok && result.stacks.length > 0) {
90
+ projectGroups.push({
91
+ projectId: project.id,
92
+ displayName: project.displayName,
93
+ stacks: result.stacks,
94
+ });
95
+ allStacks.push(...result.stacks);
96
+ }
97
+ }
98
+ spinner.stop().clear();
99
+ // 4. Print results
100
+ if (orgStacks.length > 0) {
101
+ log(`${styleText('bold', 'Organization')} ${niceId(organizationId)} ${styleText('bold', 'Stacks')}:\n`);
102
+ log(formatStacksListing(orgStacks, blueprintStackId));
103
+ if (projectGroups.length > 0)
104
+ log(''); // blank line between sections
105
+ }
106
+ for (const group of projectGroups) {
107
+ log(`${styleText('bold', 'Project')} "${group.displayName}" ${niceId(group.projectId)} ${styleText('bold', 'Stacks')}:`);
108
+ log(formatStacksListing(group.stacks, blueprintStackId));
109
+ log('');
110
+ }
111
+ if (totalProjects > PROJECT_LIMIT) {
112
+ log(warn(`Organization has ${totalProjects} projects, only checked the first ${PROJECT_LIMIT}.`));
113
+ }
114
+ if (orgStacks.length === 0 && allStacks.length === 0) {
115
+ log('No stacks found');
116
+ return { success: true };
117
+ }
118
+ allStacks.push(...orgStacks);
119
+ return {
120
+ success: true,
121
+ json: { stacks: allStacks, scopeType: 'organization', scopeId: organizationId },
122
+ };
123
+ }
124
+ catch (error) {
125
+ spinner.stop().clear();
126
+ const errorMessage = error instanceof Error ? error.message : String(error);
127
+ log.error(`Error: ${errorMessage}`);
128
+ return { success: false, error: errorMessage };
129
+ }
130
+ }
@@ -7,7 +7,7 @@ export async function functionDevCore(options) {
7
7
  ? { timeout }
8
8
  : undefined;
9
9
  try {
10
- await dev(host, Number(port), log, options.validateResources || false, executionOptions);
10
+ await dev(host, Number(port), options.validateResources || false, executionOptions);
11
11
  log(`Server is running on http://${host}:${port}\n`);
12
12
  return {
13
13
  success: true,
@@ -1,6 +1,5 @@
1
- import type { Logger } from '../utils/logger.js';
2
1
  import { type InvokeExecutionOptions } from '../utils/types.js';
3
- declare const app: (host: string, port: number, logger: Logger, validateResources: boolean, executionOptions?: Partial<InvokeExecutionOptions>) => void;
2
+ declare const app: (host: string, port: number, validateResources: boolean, executionOptions?: Partial<InvokeExecutionOptions>) => void;
4
3
  declare function parseDocumentUrl(url: string): {
5
4
  projectId: string;
6
5
  dataset: string;
@@ -2,19 +2,25 @@ import { existsSync, readFileSync, watchFile } from 'node:fs';
2
2
  import * as http from 'node:http';
3
3
  import { default as mime } from 'mime-types';
4
4
  import { WebSocketServer } from 'ws';
5
- import { readLocalBlueprint } from '../actions/blueprints/blueprint.js';
5
+ import { findBlueprintFile, loadAndParseBlueprint } from '../actions/blueprints/blueprint.js';
6
+ import { readConfigFile } from '../actions/blueprints/config.js';
7
+ import { resolveIds } from '../actions/blueprints/resolve.js';
6
8
  import config from '../config.js';
7
9
  import { isRecord } from '../utils/is-record.js';
8
10
  import { isEventType, isGroqContextOptions, } from '../utils/types.js';
9
11
  import { handleInvokeRequest } from './handlers/invoke.js';
10
- const app = (host, port, logger, validateResources, executionOptions) => {
12
+ const app = (host, port, validateResources, executionOptions) => {
11
13
  const requestListener = async (req, res) => {
12
14
  res.setHeader('Content-Type', 'application/json');
13
15
  switch (true) {
14
16
  case req.url === '/blueprint': {
15
17
  try {
16
- const { parsedBlueprint, projectId, organizationId } = await readLocalBlueprint(logger, {
17
- resources: validateResources,
18
+ const blueprint = await loadAndParseBlueprint(undefined, { validateResources });
19
+ const { parsedBlueprint, fileInfo, module: blueprintModule } = blueprint;
20
+ const blueprintConfig = readConfigFile(fileInfo.blueprintFilePath);
21
+ const { projectId, organizationId } = resolveIds({
22
+ module: blueprintModule,
23
+ config: blueprintConfig,
18
24
  });
19
25
  res.setHeader('Content-Type', 'application/json');
20
26
  res.writeHead(200);
@@ -44,7 +50,7 @@ const app = (host, port, logger, validateResources, executionOptions) => {
44
50
  delete context.clientOptions.token;
45
51
  }
46
52
  }
47
- const result = await handleInvokeRequest(functionName, event, metadata, context, logger, validateResources, executionOptions);
53
+ const result = await handleInvokeRequest(functionName, event, metadata, context, validateResources, executionOptions);
48
54
  // Add Server-Timing header
49
55
  const timingHeaders = [];
50
56
  for (const [key, value] of Object.entries(result.timings)) {
@@ -230,10 +236,12 @@ const app = (host, port, logger, validateResources, executionOptions) => {
230
236
  const server = http.createServer(requestListener);
231
237
  server.listen(port, host, () => { });
232
238
  const wss = new WebSocketServer({ port: 8974 });
233
- wss.on('connection', async function connection(ws) {
239
+ wss.on('connection', function connection(ws) {
234
240
  ws.on('error', console.error);
235
- const { fileInfo } = await readLocalBlueprint(logger, { resources: validateResources });
236
- watchFile(fileInfo.blueprintFilePath, { interval: 2007 }, async () => {
241
+ const fileInfo = findBlueprintFile();
242
+ if (!fileInfo)
243
+ return;
244
+ watchFile(fileInfo.blueprintFilePath, { interval: 2007 }, () => {
237
245
  ws.send('reload-blueprint');
238
246
  });
239
247
  });
@@ -1,5 +1,4 @@
1
- import type { Logger } from '../../utils/logger.js';
2
1
  import type { InvocationResponse, InvokeContextOptions, InvokeExecutionOptions, InvokePayloadMetadata } from '../../utils/types.js';
3
- export declare function handleInvokeRequest(functionName: string, event: Record<string, unknown>, metadata: InvokePayloadMetadata, context: InvokeContextOptions, logger: Logger, validateResources: boolean, executionOptions?: Partial<InvokeExecutionOptions>): Promise<InvocationResponse & {
2
+ export declare function handleInvokeRequest(functionName: string, event: Record<string, unknown>, metadata: InvokePayloadMetadata, context: InvokeContextOptions, validateResources: boolean, executionOptions?: Partial<InvokeExecutionOptions>): Promise<InvocationResponse & {
4
3
  timings: Record<string, number>;
5
4
  }>;
@@ -1,10 +1,10 @@
1
- import { readLocalBlueprint } from '../../actions/blueprints/blueprint.js';
1
+ import { loadAndParseBlueprint } from '../../actions/blueprints/blueprint.js';
2
2
  import { findFunctionInResources } from '../../utils/find-function.js';
3
3
  import invoke from '../../utils/invoke-local.js';
4
- export async function handleInvokeRequest(functionName, event, metadata, context, logger, validateResources, executionOptions) {
4
+ export async function handleInvokeRequest(functionName, event, metadata, context, validateResources, executionOptions) {
5
5
  const start = performance.now();
6
- const blueprint = await readLocalBlueprint(logger, { resources: validateResources });
7
- const resource = findFunctionInResources(blueprint.resources, functionName);
6
+ const { resources } = await loadAndParseBlueprint(undefined, { validateResources });
7
+ const resource = findFunctionInResources(resources, functionName);
8
8
  const readBlueprintTime = performance.now() - start;
9
9
  const payload = {
10
10
  payload: event,
@@ -220,7 +220,6 @@
220
220
  "summary": "Add a function resource to a Blueprint",
221
221
  "enableJsonFlag": true,
222
222
  "needs": [
223
- "token",
224
223
  "blueprint"
225
224
  ],
226
225
  "isESM": true,
@@ -405,7 +404,6 @@
405
404
  },
406
405
  "stack": {
407
406
  "description": "Stack name or ID to use instead of the locally configured Stack",
408
- "hidden": false,
409
407
  "name": "stack",
410
408
  "hasDynamicHelp": false,
411
409
  "multiple": false,
@@ -641,7 +639,6 @@
641
639
  "flags": {
642
640
  "json": {
643
641
  "description": "Format output as json",
644
- "hidden": false,
645
642
  "name": "json",
646
643
  "allowNo": false,
647
644
  "type": "boolean"
@@ -653,7 +650,6 @@
653
650
  "char": "p",
654
651
  "description": "Path to a Blueprint file or directory containing one",
655
652
  "env": "SANITY_BLUEPRINT_PATH",
656
- "hidden": false,
657
653
  "name": "path",
658
654
  "hasDynamicHelp": false,
659
655
  "multiple": false,
@@ -857,7 +853,7 @@
857
853
  },
858
854
  "verbose": {
859
855
  "description": "Verbose output",
860
- "hidden": false,
856
+ "hidden": true,
861
857
  "name": "verbose",
862
858
  "allowNo": false,
863
859
  "type": "boolean"
@@ -1016,7 +1012,6 @@
1016
1012
  },
1017
1013
  "stack": {
1018
1014
  "description": "Stack name or ID to use instead of the locally configured Stack",
1019
- "hidden": false,
1020
1015
  "name": "stack",
1021
1016
  "hasDynamicHelp": false,
1022
1017
  "multiple": false,
@@ -1068,8 +1063,7 @@
1068
1063
  "summary": "Display logs for the current Blueprint's Stack deployment",
1069
1064
  "enableJsonFlag": true,
1070
1065
  "needs": [
1071
- "deployedStack",
1072
- "blueprint"
1066
+ "deployedStack"
1073
1067
  ],
1074
1068
  "isESM": true,
1075
1069
  "relativePath": [
@@ -1128,7 +1122,6 @@
1128
1122
  },
1129
1123
  "stack": {
1130
1124
  "description": "Stack name or ID to use instead of the locally configured Stack",
1131
- "hidden": false,
1132
1125
  "name": "stack",
1133
1126
  "hasDynamicHelp": false,
1134
1127
  "multiple": false,
@@ -1296,11 +1289,12 @@
1296
1289
  "blueprints:stacks": {
1297
1290
  "aliases": [],
1298
1291
  "args": {},
1299
- "description": "Shows all Stacks associated with a project or organization. By default, lists Stacks scoped to the local Blueprint.\n\nUse this to discover existing Stacks you can scope a local Blueprint to (using 'blueprints config --edit'), or to audit what's deployed across your project.",
1292
+ "description": "Shows all Stacks associated with a project or organization. By default, lists Stacks scoped to the local Blueprint.\n\nUse this to discover existing Stacks you can scope a local Blueprint to (using 'blueprints config --edit'), or to audit what's deployed across your project.\n\nUse --include-projects with --organization-id to also list Stacks from all projects within the organization.",
1300
1293
  "examples": [
1301
1294
  "<%= config.bin %> <%= command.id %>",
1302
1295
  "<%= config.bin %> <%= command.id %> --project-id <projectId>",
1303
- "<%= config.bin %> <%= command.id %> --organization-id <organizationId>"
1296
+ "<%= config.bin %> <%= command.id %> --organization-id <organizationId>",
1297
+ "<%= config.bin %> <%= command.id %> --organization-id <organizationId> --include-projects"
1304
1298
  ],
1305
1299
  "flags": {
1306
1300
  "json": {
@@ -1357,7 +1351,8 @@
1357
1351
  ],
1358
1352
  "description": "Sanity project ID used to scope Blueprint and Stack",
1359
1353
  "exclusive": [
1360
- "organization-id"
1354
+ "organization-id",
1355
+ "include-projects"
1361
1356
  ],
1362
1357
  "name": "project-id",
1363
1358
  "hasDynamicHelp": false,
@@ -1378,6 +1373,15 @@
1378
1373
  "hasDynamicHelp": false,
1379
1374
  "multiple": false,
1380
1375
  "type": "option"
1376
+ },
1377
+ "include-projects": {
1378
+ "dependsOn": [
1379
+ "organization-id"
1380
+ ],
1381
+ "description": "Include Stacks from all projects within the organization. Requires --organization-id.",
1382
+ "name": "include-projects",
1383
+ "allowNo": false,
1384
+ "type": "boolean"
1381
1385
  }
1382
1386
  },
1383
1387
  "hasDynamicHelp": false,
@@ -1599,7 +1603,6 @@
1599
1603
  "summary": "Add a Function to your Blueprint",
1600
1604
  "enableJsonFlag": true,
1601
1605
  "needs": [
1602
- "token",
1603
1606
  "blueprint"
1604
1607
  ],
1605
1608
  "isESM": true,
@@ -1729,7 +1732,6 @@
1729
1732
  "summary": "Build Sanity Function(s) to zip archives",
1730
1733
  "enableJsonFlag": true,
1731
1734
  "needs": [
1732
- "token",
1733
1735
  "blueprint"
1734
1736
  ],
1735
1737
  "isESM": true,
@@ -1859,7 +1861,6 @@
1859
1861
  "summary": "Start the Sanity Function emulator",
1860
1862
  "enableJsonFlag": true,
1861
1863
  "needs": [
1862
- "token",
1863
1864
  "blueprint"
1864
1865
  ],
1865
1866
  "isESM": true,
@@ -1928,7 +1929,6 @@
1928
1929
  },
1929
1930
  "stack": {
1930
1931
  "description": "Stack name or ID to use instead of the locally configured Stack",
1931
- "hidden": false,
1932
1932
  "name": "stack",
1933
1933
  "hasDynamicHelp": false,
1934
1934
  "multiple": false,
@@ -2335,7 +2335,6 @@
2335
2335
  "summary": "Invoke a local Sanity Function",
2336
2336
  "enableJsonFlag": true,
2337
2337
  "needs": [
2338
- "token",
2339
2338
  "blueprint"
2340
2339
  ],
2341
2340
  "isESM": true,
@@ -2689,5 +2688,5 @@
2689
2688
  ]
2690
2689
  }
2691
2690
  },
2692
- "version": "14.12.0"
2691
+ "version": "14.13.0"
2693
2692
  }
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": "14.12.0",
4
+ "version": "14.13.0",
5
5
  "author": "Sanity Runtime Team",
6
6
  "type": "module",
7
7
  "license": "MIT",