@sanity/runtime-cli 3.0.1 → 3.2.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
@@ -20,7 +20,7 @@ $ npm install -g @sanity/runtime-cli
20
20
  $ sanity-run COMMAND
21
21
  running command...
22
22
  $ sanity-run (--version)
23
- @sanity/runtime-cli/3.0.1 linux-x64 node-v22.14.0
23
+ @sanity/runtime-cli/3.2.0 linux-x64 node-v22.14.0
24
24
  $ sanity-run --help [COMMAND]
25
25
  USAGE
26
26
  $ sanity-run COMMAND
@@ -32,6 +32,7 @@ USAGE
32
32
  * [`sanity-run blueprints add TYPE`](#sanity-run-blueprints-add-type)
33
33
  * [`sanity-run blueprints config`](#sanity-run-blueprints-config)
34
34
  * [`sanity-run blueprints deploy`](#sanity-run-blueprints-deploy)
35
+ * [`sanity-run blueprints destroy`](#sanity-run-blueprints-destroy)
35
36
  * [`sanity-run blueprints info`](#sanity-run-blueprints-info)
36
37
  * [`sanity-run blueprints init`](#sanity-run-blueprints-init)
37
38
  * [`sanity-run blueprints logs`](#sanity-run-blueprints-logs)
@@ -63,7 +64,7 @@ EXAMPLES
63
64
  $ sanity-run blueprints add function
64
65
  ```
65
66
 
66
- _See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v3.0.1/src/commands/blueprints/add.ts)_
67
+ _See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v3.2.0/src/commands/blueprints/add.ts)_
67
68
 
68
69
  ## `sanity-run blueprints config`
69
70
 
@@ -85,7 +86,7 @@ EXAMPLES
85
86
  $ sanity-run blueprints config --edit
86
87
  ```
87
88
 
88
- _See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v3.0.1/src/commands/blueprints/config.ts)_
89
+ _See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v3.2.0/src/commands/blueprints/config.ts)_
89
90
 
90
91
  ## `sanity-run blueprints deploy`
91
92
 
@@ -102,7 +103,30 @@ EXAMPLES
102
103
  $ sanity-run blueprints deploy
103
104
  ```
104
105
 
105
- _See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v3.0.1/src/commands/blueprints/deploy.ts)_
106
+ _See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v3.2.0/src/commands/blueprints/deploy.ts)_
107
+
108
+ ## `sanity-run blueprints destroy`
109
+
110
+ Destroy a deployed Blueprint Stack
111
+
112
+ ```
113
+ USAGE
114
+ $ sanity-run blueprints destroy [--id <value>] [--force]
115
+
116
+ FLAGS
117
+ --force Force destroy (skip confirmation)
118
+ --id=<value> Stack ID to destroy (defaults to current Stack)
119
+
120
+ DESCRIPTION
121
+ Destroy a deployed Blueprint Stack
122
+
123
+ EXAMPLES
124
+ $ sanity-run blueprints destroy
125
+
126
+ $ sanity-run blueprints destroy --id ST-a1b2c3
127
+ ```
128
+
129
+ _See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v3.2.0/src/commands/blueprints/destroy.ts)_
106
130
 
107
131
  ## `sanity-run blueprints info`
108
132
 
@@ -124,7 +148,7 @@ EXAMPLES
124
148
  $ sanity-run blueprints info --id abc123
125
149
  ```
126
150
 
127
- _See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v3.0.1/src/commands/blueprints/info.ts)_
151
+ _See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v3.2.0/src/commands/blueprints/info.ts)_
128
152
 
129
153
  ## `sanity-run blueprints init`
130
154
 
@@ -141,7 +165,7 @@ EXAMPLES
141
165
  $ sanity-run blueprints init
142
166
  ```
143
167
 
144
- _See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v3.0.1/src/commands/blueprints/init.ts)_
168
+ _See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v3.2.0/src/commands/blueprints/init.ts)_
145
169
 
146
170
  ## `sanity-run blueprints logs`
147
171
 
@@ -163,7 +187,7 @@ EXAMPLES
163
187
  $ sanity-run blueprints logs --watch
164
188
  ```
165
189
 
166
- _See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v3.0.1/src/commands/blueprints/logs.ts)_
190
+ _See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v3.2.0/src/commands/blueprints/logs.ts)_
167
191
 
168
192
  ## `sanity-run blueprints plan`
169
193
 
@@ -180,7 +204,7 @@ EXAMPLES
180
204
  $ sanity-run blueprints plan
181
205
  ```
182
206
 
183
- _See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v3.0.1/src/commands/blueprints/plan.ts)_
207
+ _See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v3.2.0/src/commands/blueprints/plan.ts)_
184
208
 
185
209
  ## `sanity-run blueprints stacks`
186
210
 
@@ -197,7 +221,7 @@ EXAMPLES
197
221
  $ sanity-run blueprints stacks
198
222
  ```
199
223
 
200
- _See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v3.0.1/src/commands/blueprints/stacks.ts)_
224
+ _See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v3.2.0/src/commands/blueprints/stacks.ts)_
201
225
 
202
226
  ## `sanity-run functions dev`
203
227
 
@@ -217,7 +241,7 @@ EXAMPLES
217
241
  $ sanity-run functions dev --port 8974
218
242
  ```
219
243
 
220
- _See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v3.0.1/src/commands/functions/dev.ts)_
244
+ _See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v3.2.0/src/commands/functions/dev.ts)_
221
245
 
222
246
  ## `sanity-run functions env add NAME KEY VALUE`
223
247
 
@@ -239,7 +263,7 @@ EXAMPLES
239
263
  $ sanity-run functions env add MyFunction API_URL https://api.example.com/
240
264
  ```
241
265
 
242
- _See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v3.0.1/src/commands/functions/env/add.ts)_
266
+ _See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v3.2.0/src/commands/functions/env/add.ts)_
243
267
 
244
268
  ## `sanity-run functions env remove NAME KEY`
245
269
 
@@ -260,7 +284,7 @@ EXAMPLES
260
284
  $ sanity-run functions env remove MyFunction API_URL
261
285
  ```
262
286
 
263
- _See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v3.0.1/src/commands/functions/env/remove.ts)_
287
+ _See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v3.2.0/src/commands/functions/env/remove.ts)_
264
288
 
265
289
  ## `sanity-run functions invoke NAME`
266
290
 
@@ -286,25 +310,27 @@ EXAMPLES
286
310
  $ sanity-run functions invoke <name> --file 'payload.json'
287
311
  ```
288
312
 
289
- _See code: [src/commands/functions/invoke.ts](https://github.com/sanity-io/runtime-cli/blob/v3.0.1/src/commands/functions/invoke.ts)_
313
+ _See code: [src/commands/functions/invoke.ts](https://github.com/sanity-io/runtime-cli/blob/v3.2.0/src/commands/functions/invoke.ts)_
290
314
 
291
315
  ## `sanity-run functions logs NAME`
292
316
 
293
- Retrieve logs for a Sanity Function
317
+ Retrieve or delete logs for a Sanity Function
294
318
 
295
319
  ```
296
320
  USAGE
297
- $ sanity-run functions logs NAME [-l <value>] [-j]
321
+ $ sanity-run functions logs NAME [-f [-d | -l <value> | -j]]
298
322
 
299
323
  ARGUMENTS
300
324
  NAME The name of the Sanity Function
301
325
 
302
326
  FLAGS
327
+ -d, --delete Delete all logs for the function
328
+ -f, --force Skip confirmation for deleting logs
303
329
  -j, --json Return logs in JSON format
304
330
  -l, --limit=<value> [default: 50] Total number of log entries to retrieve
305
331
 
306
332
  DESCRIPTION
307
- Retrieve logs for a Sanity Function
333
+ Retrieve or delete logs for a Sanity Function
308
334
 
309
335
  EXAMPLES
310
336
  $ sanity-run functions logs <name>
@@ -312,9 +338,11 @@ EXAMPLES
312
338
  $ sanity-run functions logs <name> --json
313
339
 
314
340
  $ sanity-run functions logs <name> --limit 100
341
+
342
+ $ sanity-run functions logs <name> --delete
315
343
  ```
316
344
 
317
- _See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v3.0.1/src/commands/functions/logs.ts)_
345
+ _See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v3.2.0/src/commands/functions/logs.ts)_
318
346
 
319
347
  ## `sanity-run functions test NAME`
320
348
 
@@ -347,7 +375,7 @@ EXAMPLES
347
375
  $ sanity-run functions test <name> --data '{ "id": 1 }' --timeout 60
348
376
  ```
349
377
 
350
- _See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v3.0.1/src/commands/functions/test.ts)_
378
+ _See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v3.2.0/src/commands/functions/test.ts)_
351
379
 
352
380
  ## `sanity-run help [COMMAND]`
353
381
 
@@ -46,4 +46,13 @@ export declare function updateStack({ stackId, stackPayload, auth, }: {
46
46
  stackPayload: StackPayload;
47
47
  auth: AuthParams;
48
48
  }): Promise<UpdateStackResponse>;
49
+ interface DestroyStackResponse {
50
+ ok: boolean;
51
+ error: string | null;
52
+ stack: Stack;
53
+ }
54
+ export declare function destroyStack({ stackId, auth, }: {
55
+ stackId: string;
56
+ auth: AuthParams;
57
+ }): Promise<DestroyStackResponse>;
49
58
  export {};
@@ -81,3 +81,15 @@ export async function updateStack({ stackId, stackPayload, auth, }) {
81
81
  stack,
82
82
  };
83
83
  }
84
+ export async function destroyStack({ stackId, auth, }) {
85
+ const response = await fetch(`${stacksUrl}/${stackId}`, {
86
+ method: 'DELETE',
87
+ headers: getHeaders(auth),
88
+ });
89
+ const stack = await response.json();
90
+ return {
91
+ ok: response.ok,
92
+ error: response.ok ? null : stack.message,
93
+ stack,
94
+ };
95
+ }
@@ -1,5 +1,5 @@
1
1
  import type { AuthParams } from '../../utils/types.js';
2
- /** internal */
2
+ /** @internal */
3
3
  export interface LoggingOptions {
4
4
  limit: number;
5
5
  }
@@ -9,3 +9,7 @@ export declare function logs(id: string, options: LoggingOptions, auth: AuthPara
9
9
  logs: any;
10
10
  total: any;
11
11
  }>;
12
+ export declare function deleteLogs(id: string, auth: AuthParams): Promise<{
13
+ ok: boolean;
14
+ error: any;
15
+ }>;
@@ -15,3 +15,14 @@ export async function logs(id, options, auth) {
15
15
  total: response.ok ? json.total : 0,
16
16
  };
17
17
  }
18
+ export async function deleteLogs(id, auth) {
19
+ const response = await fetch(`${functions}vX/functions/${id}/logs`, {
20
+ headers: getHeaders(auth),
21
+ method: 'DELETE',
22
+ });
23
+ const json = response.ok ? null : await response.json();
24
+ return {
25
+ ok: response.ok,
26
+ error: response.ok ? null : json?.error?.message,
27
+ };
28
+ }
@@ -6,6 +6,7 @@ import { readBlueprintOnDisk, writeConfigFile } from '../../actions/blueprints/b
6
6
  import { createStack, updateStack } from '../../actions/blueprints/stacks.js';
7
7
  import config from '../../config.js';
8
8
  import { bold, green, red, yellow } from '../../utils/display/colors.js';
9
+ import { isLocalFunctionResource } from '../../utils/types.js';
9
10
  const { token } = config;
10
11
  export default class Deploy extends Command {
11
12
  static description = 'Deploy a Blueprint';
@@ -50,7 +51,7 @@ export default class Deploy extends Command {
50
51
  if (!name)
51
52
  this.error('Stack name is required');
52
53
  const validResources = resources?.filter((r) => r.type);
53
- const functionResources = validResources?.filter((r) => r.type.startsWith('sanity.function.'));
54
+ const functionResources = validResources?.filter(isLocalFunctionResource);
54
55
  // First stash all function assets
55
56
  if (functionResources?.length) {
56
57
  for (const resource of functionResources) {
@@ -0,0 +1,10 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Destroy extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ id: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
+ force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
+ };
9
+ run(): Promise<void>;
10
+ }
@@ -0,0 +1,85 @@
1
+ import { setTimeout } from 'node:timers/promises';
2
+ import { Command, Flags } from '@oclif/core';
3
+ import inquirer from 'inquirer';
4
+ import Spinner from 'yocto-spinner';
5
+ import { readBlueprintOnDisk } from '../../actions/blueprints/blueprint.js';
6
+ import { destroyStack, getStack } from '../../actions/blueprints/stacks.js';
7
+ import config from '../../config.js';
8
+ import { bold, niceId } from '../../utils/display/colors.js';
9
+ const { token } = config;
10
+ export default class Destroy extends Command {
11
+ static description = 'Destroy a deployed Blueprint Stack';
12
+ static examples = [
13
+ '<%= config.bin %> <%= command.id %>',
14
+ '<%= config.bin %> <%= command.id %> --id ST-a1b2c3',
15
+ ];
16
+ static flags = {
17
+ id: Flags.string({
18
+ description: 'Stack ID to destroy (defaults to current Stack)',
19
+ required: false,
20
+ }),
21
+ force: Flags.boolean({
22
+ description: 'Force destroy (skip confirmation)',
23
+ default: false,
24
+ }),
25
+ };
26
+ async run() {
27
+ const { flags } = await this.parse(Destroy);
28
+ const { errors, deployedStack, projectId } = await readBlueprintOnDisk({ getStack: true, token });
29
+ if (errors.length > 0) {
30
+ // printErrors(errors)
31
+ this.warn('Blueprint parse errors:');
32
+ console.dir(errors, { depth: null });
33
+ return;
34
+ }
35
+ if (!projectId)
36
+ this.error('Project resource not found in blueprint');
37
+ const auth = { token, projectId };
38
+ let stack = deployedStack;
39
+ if (flags.id) {
40
+ const { ok, stack: foundStack, error } = await getStack({ stackId: flags.id, auth });
41
+ if (!ok)
42
+ this.error(error || 'Failed to get stack');
43
+ stack = foundStack;
44
+ }
45
+ else if (!stack) {
46
+ this.error('No stack found');
47
+ }
48
+ if (!stack)
49
+ this.error('Stack not found. Is it deployed?');
50
+ const destroySpinner = Spinner({
51
+ text: `Destroying ${bold(stack.name)} ${niceId(stack.id)}...`,
52
+ color: 'red',
53
+ });
54
+ if (!flags.force) {
55
+ const { confirm } = await inquirer.prompt([
56
+ {
57
+ type: 'confirm',
58
+ name: 'confirm',
59
+ message: `Are you sure you want to destroy stack "${stack.name}" ${niceId(stack.id)}?`,
60
+ default: false,
61
+ },
62
+ ]);
63
+ if (!confirm) {
64
+ this.log('Stack destruction cancelled');
65
+ return;
66
+ }
67
+ destroySpinner.start();
68
+ let i = 5;
69
+ while (i >= 0) {
70
+ destroySpinner.text = `Destroying stack in ${bold((i--).toString())} seconds...`;
71
+ await setTimeout(1000);
72
+ }
73
+ destroySpinner.text = 'Destroying stack 💥';
74
+ await setTimeout(500);
75
+ }
76
+ else {
77
+ destroySpinner.start();
78
+ }
79
+ const { ok, error } = await destroyStack({ stackId: stack.id, auth });
80
+ if (!ok)
81
+ this.error(error || 'Failed to destroy stack');
82
+ // TODO: update local config
83
+ destroySpinner.success(`Stack "${stack.name}" ${niceId(stack.id)} destroyed`);
84
+ }
85
+ }
@@ -1,4 +1,11 @@
1
1
  import { Command } from '@oclif/core';
2
+ type RunDeleteOptions = {
3
+ force: boolean;
4
+ };
5
+ type RunGetOptions = {
6
+ limit: number;
7
+ json?: boolean;
8
+ };
2
9
  export default class Logs extends Command {
3
10
  static args: {
4
11
  name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
@@ -8,6 +15,11 @@ export default class Logs extends Command {
8
15
  static flags: {
9
16
  limit: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
10
17
  json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
18
+ delete: import("@oclif/core/interfaces").BooleanFlag<boolean>;
19
+ force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
20
  };
12
21
  run(): Promise<void>;
22
+ runDeleteLogs(name: string, options: RunDeleteOptions): Promise<void>;
23
+ runGetLogs(name: string, options: RunGetOptions): Promise<void>;
13
24
  }
25
+ export {};
@@ -1,7 +1,8 @@
1
1
  import { Args, Command, Flags } from '@oclif/core';
2
+ import inquirer from 'inquirer';
2
3
  import Spinner from 'yocto-spinner';
3
4
  import { readBlueprintOnDisk } from '../../actions/blueprints/blueprint.js';
4
- import { logs as logsAction } from '../../actions/functions/logs.js';
5
+ import { deleteLogs as deleteLogsAction, logs as logsAction } from '../../actions/functions/logs.js';
5
6
  import config from '../../config.js';
6
7
  import { formatTitle } from '../../utils/display/blueprints-formatting.js';
7
8
  import { blue, bold, green, red, yellow } from '../../utils/display/colors.js';
@@ -15,15 +16,26 @@ function logLevel(level) {
15
16
  }
16
17
  return green(level);
17
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
+ }
18
29
  export default class Logs extends Command {
19
30
  static args = {
20
31
  name: Args.string({ description: 'The name of the Sanity Function', required: true }),
21
32
  };
22
- static description = 'Retrieve logs for a Sanity Function';
33
+ static description = 'Retrieve or delete logs for a Sanity Function';
23
34
  static examples = [
24
35
  '<%= config.bin %> <%= command.id %> <name>',
25
36
  '<%= config.bin %> <%= command.id %> <name> --json',
26
37
  '<%= config.bin %> <%= command.id %> <name> --limit 100',
38
+ '<%= config.bin %> <%= command.id %> <name> --delete',
27
39
  ];
28
40
  static flags = {
29
41
  limit: Flags.integer({
@@ -37,16 +49,61 @@ export default class Logs extends Command {
37
49
  description: 'Return logs in JSON format',
38
50
  required: false,
39
51
  }),
52
+ delete: Flags.boolean({
53
+ char: 'd',
54
+ exclusive: ['limit', 'json'],
55
+ description: 'Delete all logs for the function',
56
+ required: false,
57
+ }),
58
+ force: Flags.boolean({
59
+ char: 'f',
60
+ dependsOn: ['delete'],
61
+ description: 'Skip confirmation for deleting logs',
62
+ required: false,
63
+ }),
40
64
  };
41
65
  async run() {
42
66
  const { args, flags } = await this.parse(Logs);
43
- const spinner = Spinner({ text: `Finding logs for function "${args.name}"` }).start();
44
- const { deployedStack } = await readBlueprintOnDisk({ getStack: true, token: config.token });
45
- if (!deployedStack)
46
- this.error('Stack not found'); // returns
47
- const { projectId } = deployedStack;
48
- const { externalId } = findFunctionByName(deployedStack, args.name);
49
- const { ok, error, logs, total } = await logsAction(externalId, { limit: flags.limit }, { token: config.token, projectId });
67
+ if (flags.delete === true) {
68
+ await this.runDeleteLogs(args.name, flags);
69
+ }
70
+ else {
71
+ await this.runGetLogs(args.name, flags);
72
+ }
73
+ }
74
+ async runDeleteLogs(name, options) {
75
+ if (!options.force) {
76
+ const { certain } = await inquirer.prompt({
77
+ type: 'confirm',
78
+ name: 'certain',
79
+ message: `Are you sure you want to delete ${bold('all')} logs for function ${yellow(name)}?`,
80
+ default: false,
81
+ });
82
+ if (!certain)
83
+ return;
84
+ }
85
+ const { projectId, externalId } = await getProjectAndExternalId(name);
86
+ if (!projectId || !externalId) {
87
+ this.error('Stack not found');
88
+ return;
89
+ }
90
+ const spinner = Spinner({ text: `Deleting logs for function ${yellow(name)}` }).start();
91
+ const { ok, error } = await deleteLogsAction(externalId, { token: config.token, projectId });
92
+ if (!ok) {
93
+ spinner.error(`${red('Failed')} to retrieve logs`);
94
+ this.log(`Error: ${error || 'Unknown error'}`);
95
+ return;
96
+ }
97
+ spinner.success('Logs deleted');
98
+ }
99
+ async runGetLogs(name, options) {
100
+ const spinner = Spinner({ text: `Finding logs for function "${name}"` }).start();
101
+ const { projectId, externalId } = await getProjectAndExternalId(name);
102
+ if (!projectId || !externalId) {
103
+ this.error('Stack not found');
104
+ return;
105
+ }
106
+ const { ok, error, logs, total } = await logsAction(externalId, { limit: options.limit }, { token: config.token, projectId });
50
107
  if (!ok) {
51
108
  spinner.error(`${red('Failed')} to retrieve logs`);
52
109
  this.log(`Error: ${error || 'Unknown error'}`);
@@ -54,12 +111,12 @@ export default class Logs extends Command {
54
111
  }
55
112
  const filteredLogs = logs.filter((entry) => entry.level && entry.message);
56
113
  if (filteredLogs.length === 0) {
57
- spinner.info(`No logs found for function ${args.name}`);
114
+ spinner.info(`No logs found for function ${name}`);
58
115
  return;
59
116
  }
60
- spinner.success(`${formatTitle('Function', args.name)} Logs`);
61
- if (!flags.json) {
62
- this.log(`Found ${bold(total)} log entries for function ${yellow(args.name)}`);
117
+ spinner.success(`${formatTitle('Function', name)} Logs`);
118
+ if (!options.json) {
119
+ this.log(`Found ${bold(total)} log entries for function ${yellow(name)}`);
63
120
  if (logs.length < total) {
64
121
  this.log(`Here are the last ${bold(filteredLogs.length.toString())} entries`);
65
122
  }
@@ -5,3 +5,4 @@ export declare function green(str: string): string;
5
5
  export declare function red(str: string): string;
6
6
  export declare function yellow(str: string): string;
7
7
  export declare function boldnblue(str: string): string;
8
+ export declare function niceId(id: string | undefined): string;
@@ -20,3 +20,8 @@ export function yellow(str) {
20
20
  export function boldnblue(str) {
21
21
  return chalk.bold.blue(str);
22
22
  }
23
+ export function niceId(id) {
24
+ if (!id)
25
+ return '';
26
+ return `<${yellow(id)}>`;
27
+ }
@@ -1,3 +1,4 @@
1
1
  import type { LocalBlueprint, LocalFunctionResource, Stack, StackFunctionResource } from './types.js';
2
- export declare function findFunctionByName(blueprintOrStack: LocalBlueprint | Stack, name: string): LocalFunctionResource | StackFunctionResource;
2
+ export declare function findFunctionByName(blueprintOrStack: LocalBlueprint, name: string): LocalFunctionResource;
3
+ export declare function findFunctionByName(blueprintOrStack: Stack, name: string): StackFunctionResource;
3
4
  export declare function getFunctionSource(blueprintOrStack: LocalBlueprint | Stack, name: string): string;
@@ -15,8 +15,8 @@ export interface LocalResource {
15
15
  name: string;
16
16
  type: string;
17
17
  displayName?: string;
18
- [key: string]: unknown;
19
18
  }
19
+ export declare function isLocalFunctionResource(r: LocalResource): r is LocalFunctionResource;
20
20
  /** @internal */
21
21
  export interface LocalFunctionResource extends LocalResource {
22
22
  src?: string;
@@ -1,3 +1,6 @@
1
+ export function isLocalFunctionResource(r) {
2
+ return r.type.startsWith('sanity.function.');
3
+ }
1
4
  /** @internal */
2
5
  export var BlueprintParserErrorType;
3
6
  (function (BlueprintParserErrorType) {
@@ -89,6 +89,46 @@
89
89
  "deploy.js"
90
90
  ]
91
91
  },
92
+ "blueprints:destroy": {
93
+ "aliases": [],
94
+ "args": {},
95
+ "description": "Destroy a deployed Blueprint Stack",
96
+ "examples": [
97
+ "<%= config.bin %> <%= command.id %>",
98
+ "<%= config.bin %> <%= command.id %> --id ST-a1b2c3"
99
+ ],
100
+ "flags": {
101
+ "id": {
102
+ "description": "Stack ID to destroy (defaults to current Stack)",
103
+ "name": "id",
104
+ "required": false,
105
+ "hasDynamicHelp": false,
106
+ "multiple": false,
107
+ "type": "option"
108
+ },
109
+ "force": {
110
+ "description": "Force destroy (skip confirmation)",
111
+ "name": "force",
112
+ "allowNo": false,
113
+ "type": "boolean"
114
+ }
115
+ },
116
+ "hasDynamicHelp": false,
117
+ "hiddenAliases": [],
118
+ "id": "blueprints:destroy",
119
+ "pluginAlias": "@sanity/runtime-cli",
120
+ "pluginName": "@sanity/runtime-cli",
121
+ "pluginType": "core",
122
+ "strict": true,
123
+ "enableJsonFlag": false,
124
+ "isESM": true,
125
+ "relativePath": [
126
+ "dist",
127
+ "commands",
128
+ "blueprints",
129
+ "destroy.js"
130
+ ]
131
+ },
92
132
  "blueprints:info": {
93
133
  "aliases": [],
94
134
  "args": {},
@@ -322,11 +362,12 @@
322
362
  "required": true
323
363
  }
324
364
  },
325
- "description": "Retrieve logs for a Sanity Function",
365
+ "description": "Retrieve or delete logs for a Sanity Function",
326
366
  "examples": [
327
367
  "<%= config.bin %> <%= command.id %> <name>",
328
368
  "<%= config.bin %> <%= command.id %> <name> --json",
329
- "<%= config.bin %> <%= command.id %> <name> --limit 100"
369
+ "<%= config.bin %> <%= command.id %> <name> --limit 100",
370
+ "<%= config.bin %> <%= command.id %> <name> --delete"
330
371
  ],
331
372
  "flags": {
332
373
  "limit": {
@@ -346,6 +387,29 @@
346
387
  "required": false,
347
388
  "allowNo": false,
348
389
  "type": "boolean"
390
+ },
391
+ "delete": {
392
+ "char": "d",
393
+ "description": "Delete all logs for the function",
394
+ "exclusive": [
395
+ "limit",
396
+ "json"
397
+ ],
398
+ "name": "delete",
399
+ "required": false,
400
+ "allowNo": false,
401
+ "type": "boolean"
402
+ },
403
+ "force": {
404
+ "char": "f",
405
+ "dependsOn": [
406
+ "delete"
407
+ ],
408
+ "description": "Skip confirmation for deleting logs",
409
+ "name": "force",
410
+ "required": false,
411
+ "allowNo": false,
412
+ "type": "boolean"
349
413
  }
350
414
  },
351
415
  "hasDynamicHelp": false,
@@ -527,5 +591,5 @@
527
591
  ]
528
592
  }
529
593
  },
530
- "version": "3.0.1"
594
+ "version": "3.2.0"
531
595
  }
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": "3.0.1",
4
+ "version": "3.2.0",
5
5
  "author": "Sanity Runtime Team",
6
6
  "type": "module",
7
7
  "license": "MIT",
@@ -84,10 +84,10 @@
84
84
  "@types/node": "18",
85
85
  "codemirror": "^6.0.1",
86
86
  "mentoss": "^0.9.2",
87
- "oclif": "^4.17.43",
87
+ "oclif": "^4.17.44",
88
88
  "pretty-bytes": "^6.1.1",
89
89
  "pretty-ms": "^9.2.0",
90
- "rollup": "^4.39.0",
90
+ "rollup": "^4.40.0",
91
91
  "shx": "^0.4.0",
92
92
  "ts-node": "^10.9.2",
93
93
  "tsx": "^4.19.3",