@sanity/runtime-cli 7.0.2 → 7.1.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/7.0.2 linux-x64 node-v22.15.0
23
+ @sanity/runtime-cli/7.1.0 linux-x64 node-v22.15.0
24
24
  $ sanity-run --help [COMMAND]
25
25
  USAGE
26
26
  $ sanity-run COMMAND
@@ -84,7 +84,7 @@ EXAMPLES
84
84
  $ sanity-run blueprints add function --name my-function --fn-type document-publish --lang js
85
85
  ```
86
86
 
87
- _See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v7.0.2/src/commands/blueprints/add.ts)_
87
+ _See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v7.1.0/src/commands/blueprints/add.ts)_
88
88
 
89
89
  ## `sanity-run blueprints config`
90
90
 
@@ -112,7 +112,7 @@ EXAMPLES
112
112
  $ sanity-run blueprints config --edit --project-id <projectId>
113
113
  ```
114
114
 
115
- _See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v7.0.2/src/commands/blueprints/config.ts)_
115
+ _See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v7.1.0/src/commands/blueprints/config.ts)_
116
116
 
117
117
  ## `sanity-run blueprints deploy`
118
118
 
@@ -134,7 +134,7 @@ EXAMPLES
134
134
  $ sanity-run blueprints deploy --no-wait
135
135
  ```
136
136
 
137
- _See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v7.0.2/src/commands/blueprints/deploy.ts)_
137
+ _See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v7.1.0/src/commands/blueprints/deploy.ts)_
138
138
 
139
139
  ## `sanity-run blueprints destroy`
140
140
 
@@ -155,7 +155,7 @@ EXAMPLES
155
155
  $ sanity-run blueprints destroy
156
156
  ```
157
157
 
158
- _See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v7.0.2/src/commands/blueprints/destroy.ts)_
158
+ _See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v7.1.0/src/commands/blueprints/destroy.ts)_
159
159
 
160
160
  ## `sanity-run blueprints info`
161
161
 
@@ -172,7 +172,7 @@ EXAMPLES
172
172
  $ sanity-run blueprints info
173
173
  ```
174
174
 
175
- _See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v7.0.2/src/commands/blueprints/info.ts)_
175
+ _See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v7.1.0/src/commands/blueprints/info.ts)_
176
176
 
177
177
  ## `sanity-run blueprints init [DIR]`
178
178
 
@@ -204,7 +204,7 @@ EXAMPLES
204
204
  $ sanity-run blueprints init --blueprint-type <json|js|ts> --project-id <projectId>
205
205
  ```
206
206
 
207
- _See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v7.0.2/src/commands/blueprints/init.ts)_
207
+ _See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v7.1.0/src/commands/blueprints/init.ts)_
208
208
 
209
209
  ## `sanity-run blueprints logs`
210
210
 
@@ -226,7 +226,7 @@ EXAMPLES
226
226
  $ sanity-run blueprints logs --watch
227
227
  ```
228
228
 
229
- _See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v7.0.2/src/commands/blueprints/logs.ts)_
229
+ _See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v7.1.0/src/commands/blueprints/logs.ts)_
230
230
 
231
231
  ## `sanity-run blueprints plan`
232
232
 
@@ -243,7 +243,7 @@ EXAMPLES
243
243
  $ sanity-run blueprints plan
244
244
  ```
245
245
 
246
- _See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v7.0.2/src/commands/blueprints/plan.ts)_
246
+ _See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v7.1.0/src/commands/blueprints/plan.ts)_
247
247
 
248
248
  ## `sanity-run functions dev`
249
249
 
@@ -263,7 +263,7 @@ EXAMPLES
263
263
  $ sanity-run functions dev --port 8974
264
264
  ```
265
265
 
266
- _See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v7.0.2/src/commands/functions/dev.ts)_
266
+ _See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v7.1.0/src/commands/functions/dev.ts)_
267
267
 
268
268
  ## `sanity-run functions env add NAME KEY VALUE`
269
269
 
@@ -285,7 +285,7 @@ EXAMPLES
285
285
  $ sanity-run functions env add MyFunction API_URL https://api.example.com/
286
286
  ```
287
287
 
288
- _See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v7.0.2/src/commands/functions/env/add.ts)_
288
+ _See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v7.1.0/src/commands/functions/env/add.ts)_
289
289
 
290
290
  ## `sanity-run functions env list NAME`
291
291
 
@@ -305,7 +305,7 @@ EXAMPLES
305
305
  $ sanity-run functions env list MyFunction
306
306
  ```
307
307
 
308
- _See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v7.0.2/src/commands/functions/env/list.ts)_
308
+ _See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v7.1.0/src/commands/functions/env/list.ts)_
309
309
 
310
310
  ## `sanity-run functions env remove NAME KEY`
311
311
 
@@ -326,7 +326,7 @@ EXAMPLES
326
326
  $ sanity-run functions env remove MyFunction API_URL
327
327
  ```
328
328
 
329
- _See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v7.0.2/src/commands/functions/env/remove.ts)_
329
+ _See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v7.1.0/src/commands/functions/env/remove.ts)_
330
330
 
331
331
  ## `sanity-run functions logs NAME`
332
332
 
@@ -359,7 +359,7 @@ EXAMPLES
359
359
  $ sanity-run functions logs <name> --delete
360
360
  ```
361
361
 
362
- _See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v7.0.2/src/commands/functions/logs.ts)_
362
+ _See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v7.1.0/src/commands/functions/logs.ts)_
363
363
 
364
364
  ## `sanity-run functions test NAME`
365
365
 
@@ -392,7 +392,7 @@ EXAMPLES
392
392
  $ sanity-run functions test <name> --data '{ "id": 1 }' --timeout 60
393
393
  ```
394
394
 
395
- _See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v7.0.2/src/commands/functions/test.ts)_
395
+ _See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v7.1.0/src/commands/functions/test.ts)_
396
396
 
397
397
  ## `sanity-run help [COMMAND]`
398
398
 
@@ -27,11 +27,15 @@ export class BlueprintCommand extends Command {
27
27
  if (tokenErr)
28
28
  this.error(tokenErr.message);
29
29
  this.sanityToken = token;
30
- const result = await initBlueprintConfig(this.config.bin, (msg) => this.log(msg), token);
30
+ const result = await initBlueprintConfig({
31
+ bin: this.config.bin,
32
+ log: (msg) => this.log(msg),
33
+ token,
34
+ });
31
35
  if (!result.ok) {
32
36
  this.error(result.error);
33
37
  }
34
- this.sanityToken = result.value.sanityToken;
38
+ this.sanityToken = result.value.token;
35
39
  this.blueprint = result.value.blueprint;
36
40
  }
37
41
  async catch(err) {
@@ -60,7 +64,7 @@ export class DeployedBlueprintCommand extends BlueprintCommand {
60
64
  bin: this.config.bin,
61
65
  blueprint: this.blueprint,
62
66
  log: (msg) => this.log(msg),
63
- sanityToken: this.sanityToken,
67
+ token: this.sanityToken,
64
68
  });
65
69
  if (!result.ok) {
66
70
  this.error(result.error);
@@ -1,9 +1,9 @@
1
1
  import { Command } from '@oclif/core';
2
- export default class Dev extends Command {
2
+ export default class DevCommand extends Command {
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  static flags: {
6
- port: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
+ port: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
7
  };
8
8
  run(): Promise<void>;
9
9
  }
@@ -1,15 +1,21 @@
1
1
  import { Command, Flags } from '@oclif/core';
2
- import { dev } from '../../actions/functions/dev.js';
3
- export default class Dev extends Command {
2
+ import { functionDevCore } from '../../cores/functions/dev.js';
3
+ export default class DevCommand extends Command {
4
4
  static description = 'Start the Sanity Function emulator';
5
5
  static examples = ['<%= config.bin %> <%= command.id %> --port 8974'];
6
6
  static flags = {
7
- port: Flags.string({ char: 'p', description: 'Port to start emulator on', required: false }),
7
+ port: Flags.integer({ char: 'p', description: 'Port to start emulator on', required: false }),
8
8
  };
9
9
  async run() {
10
- const { flags } = await this.parse(Dev);
11
- const { port = 8080 } = flags;
12
- dev(Number(port));
13
- this.log(`Server is running on port ${port}\n`);
10
+ const { flags } = await this.parse(DevCommand);
11
+ const { success, error, streaming } = await functionDevCore({
12
+ bin: this.config.bin,
13
+ log: (msg) => this.log(msg),
14
+ flags,
15
+ });
16
+ if (!success)
17
+ this.error(error);
18
+ if (streaming)
19
+ await streaming;
14
20
  }
15
21
  }
@@ -1,6 +1,6 @@
1
1
  import { Args } from '@oclif/core';
2
2
  import { DeployedBlueprintCommand } from '../../../baseCommands.js';
3
- import { envAddCore } from '../../../cores/functions/env/add.js';
3
+ import { functionEnvAddCore } from '../../../cores/functions/env/add.js';
4
4
  export default class EnvAddCommand extends DeployedBlueprintCommand {
5
5
  static args = {
6
6
  name: Args.string({ description: 'The name of the Sanity Function', required: true }),
@@ -12,7 +12,7 @@ export default class EnvAddCommand extends DeployedBlueprintCommand {
12
12
  '<%= config.bin %> <%= command.id %> MyFunction API_URL https://api.example.com/',
13
13
  ];
14
14
  async run() {
15
- const { success, error } = await envAddCore({
15
+ const { success, error } = await functionEnvAddCore({
16
16
  bin: this.config.bin,
17
17
  log: (msg) => this.log(msg),
18
18
  args: this.args,
@@ -20,7 +20,7 @@ export default class EnvAddCommand extends DeployedBlueprintCommand {
20
20
  blueprint: this.blueprint,
21
21
  deployedStack: this.deployedStack,
22
22
  projectId: this.projectId,
23
- sanityToken: this.sanityToken,
23
+ token: this.sanityToken,
24
24
  stackId: this.stackId,
25
25
  });
26
26
  if (!success)
@@ -1,6 +1,6 @@
1
1
  import { Args } from '@oclif/core';
2
2
  import { DeployedBlueprintCommand } from '../../../baseCommands.js';
3
- import { envListCore } from '../../../cores/functions/env/list.js';
3
+ import { functionEnvListCore } from '../../../cores/functions/env/list.js';
4
4
  export default class EnvListCommand extends DeployedBlueprintCommand {
5
5
  static args = {
6
6
  name: Args.string({ description: 'The name of the Sanity Function', required: true }),
@@ -8,7 +8,7 @@ export default class EnvListCommand extends DeployedBlueprintCommand {
8
8
  static description = 'List the environment variables for a Sanity function';
9
9
  static examples = ['<%= config.bin %> <%= command.id %> MyFunction'];
10
10
  async run() {
11
- const { success, error } = await envListCore({
11
+ const { success, error } = await functionEnvListCore({
12
12
  bin: this.config.bin,
13
13
  log: (msg) => this.log(msg),
14
14
  args: this.args,
@@ -16,7 +16,7 @@ export default class EnvListCommand extends DeployedBlueprintCommand {
16
16
  blueprint: this.blueprint,
17
17
  deployedStack: this.deployedStack,
18
18
  projectId: this.projectId,
19
- sanityToken: this.sanityToken,
19
+ token: this.sanityToken,
20
20
  stackId: this.stackId,
21
21
  });
22
22
  if (!success)
@@ -1,6 +1,6 @@
1
1
  import { Args } from '@oclif/core';
2
2
  import { DeployedBlueprintCommand } from '../../../baseCommands.js';
3
- import { envRemoveCore } from '../../../cores/functions/env/remove.js';
3
+ import { functionEnvRemoveCore } from '../../../cores/functions/env/remove.js';
4
4
  export default class EnvRemoveCommand extends DeployedBlueprintCommand {
5
5
  static args = {
6
6
  name: Args.string({ description: 'The name of the Sanity Function', required: true }),
@@ -9,7 +9,7 @@ export default class EnvRemoveCommand extends DeployedBlueprintCommand {
9
9
  static description = 'Remove an environment variable for a Sanity function';
10
10
  static examples = ['<%= config.bin %> <%= command.id %> MyFunction API_URL'];
11
11
  async run() {
12
- const { success, error } = await envRemoveCore({
12
+ const { success, error } = await functionEnvRemoveCore({
13
13
  bin: this.config.bin,
14
14
  log: (msg) => this.log(msg),
15
15
  args: this.args,
@@ -17,7 +17,7 @@ export default class EnvRemoveCommand extends DeployedBlueprintCommand {
17
17
  blueprint: this.blueprint,
18
18
  deployedStack: this.deployedStack,
19
19
  projectId: this.projectId,
20
- sanityToken: this.sanityToken,
20
+ token: this.sanityToken,
21
21
  stackId: this.stackId,
22
22
  });
23
23
  if (!success)
@@ -1,12 +1,4 @@
1
1
  import { DeployedBlueprintCommand } from '../../baseCommands.js';
2
- type RunDeleteOptions = {
3
- force: boolean;
4
- };
5
- type RunGetOptions = {
6
- limit: number;
7
- json?: boolean;
8
- utc?: boolean;
9
- };
10
2
  export default class LogsCommand extends DeployedBlueprintCommand<typeof LogsCommand> {
11
3
  static args: {
12
4
  name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
@@ -20,9 +12,5 @@ export default class LogsCommand extends DeployedBlueprintCommand<typeof LogsCom
20
12
  delete: import("@oclif/core/interfaces").BooleanFlag<boolean>;
21
13
  force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
22
14
  };
23
- externalId: string | undefined;
24
15
  run(): Promise<void>;
25
- runDeleteLogs(name: string, options: RunDeleteOptions): Promise<void>;
26
- runGetLogs(name: string, options: RunGetOptions): Promise<void>;
27
16
  }
28
- export {};
@@ -1,20 +1,6 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
- import chalk from 'chalk';
3
- import inquirer from 'inquirer';
4
- import ora from 'ora';
5
- import { deleteLogs as deleteLogsAction, logs as getLogsAction, } from '../../actions/functions/logs.js';
6
2
  import { DeployedBlueprintCommand } from '../../baseCommands.js';
7
- import { formatTitle } from '../../utils/display/blueprints-formatting.js';
8
- import { findFunctionByName } from '../../utils/find-function.js';
9
- function logLevel(level) {
10
- if (level === 'ERROR') {
11
- return chalk.red(level);
12
- }
13
- if (level === 'WARN') {
14
- return chalk.yellow(level);
15
- }
16
- return chalk.green(level);
17
- }
3
+ import { functionLogsCore } from '../../cores/functions/logs.js';
18
4
  export default class LogsCommand extends DeployedBlueprintCommand {
19
5
  static args = {
20
6
  name: Args.string({ description: 'The name of the Sanity Function', required: true }),
@@ -56,74 +42,20 @@ export default class LogsCommand extends DeployedBlueprintCommand {
56
42
  required: false,
57
43
  }),
58
44
  };
59
- externalId;
60
45
  async run() {
61
- const args = this.args;
62
- const flags = this.flags;
63
- const { externalId } = findFunctionByName(this.deployedStack, args.name);
64
- this.externalId = externalId;
65
- if (flags.delete === true) {
66
- await this.runDeleteLogs(args.name, flags);
67
- }
68
- else {
69
- await this.runGetLogs(args.name, flags);
70
- }
71
- }
72
- async runDeleteLogs(name, options) {
73
- if (!this.externalId)
74
- this.error('Unable to delete logs. Unable to determine function ID.');
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 ${chalk.bold('all')} logs for function ${chalk.yellow(name)}?`,
80
- default: false,
81
- });
82
- if (!certain)
83
- return;
84
- }
85
- const spinner = ora(`Deleting logs for function ${chalk.yellow(name)}`).start();
86
- const { ok, error } = await deleteLogsAction(this.externalId, this.auth);
87
- if (!ok) {
88
- spinner.fail(`${chalk.red('Failed')} to retrieve logs`);
89
- this.log(`Error: ${error || 'Unknown error'}`);
90
- return;
91
- }
92
- spinner.succeed('Logs deleted');
93
- }
94
- async runGetLogs(name, options) {
95
- if (!this.externalId)
96
- this.error('Unable to retrieve logs. Unable to determine function ID.');
97
- const spinner = ora(`Finding logs for function "${name}"`).start();
98
- const { ok, error, logs, total } = await getLogsAction(this.externalId, { limit: options.limit }, this.auth);
99
- if (!ok) {
100
- spinner.fail(`${chalk.red('Failed')} to retrieve logs`);
101
- this.log(`Error: ${error || 'Unknown error'}`);
102
- return;
103
- }
104
- const filteredLogs = logs.filter((entry) => entry.level && entry.message);
105
- if (filteredLogs.length === 0) {
106
- spinner.info(`No logs found for function ${name}`);
107
- return;
108
- }
109
- spinner.succeed(`${formatTitle('Function', name)} Logs`);
110
- if (!options.json) {
111
- this.log(`Found ${chalk.bold(total)} log entries for function ${chalk.yellow(name)}`);
112
- if (logs.length < total) {
113
- this.log(`Here are the last ${chalk.bold(filteredLogs.length.toString())} entries`);
114
- }
115
- this.log('\n');
116
- for (const log of filteredLogs) {
117
- const { time, level, message } = log;
118
- const date = new Date(time);
119
- const [dateString, timeString] = options.utc
120
- ? date.toISOString().slice(0, 19).split('T')
121
- : [date.toLocaleDateString(), date.toLocaleTimeString()];
122
- this.log([chalk.bold(dateString), chalk.bold.blue(timeString), logLevel(level), message].join(' '));
123
- }
124
- }
125
- else {
126
- this.log(JSON.stringify(filteredLogs, null, 2));
127
- }
46
+ const { success, error } = await functionLogsCore({
47
+ bin: this.config.bin,
48
+ log: (msg) => this.log(msg),
49
+ args: this.args,
50
+ flags: this.flags,
51
+ auth: this.auth,
52
+ blueprint: this.blueprint,
53
+ deployedStack: this.deployedStack,
54
+ projectId: this.projectId,
55
+ token: this.sanityToken,
56
+ stackId: this.stackId,
57
+ });
58
+ if (!success)
59
+ this.error(error);
128
60
  }
129
61
  }
@@ -1,7 +1,6 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
- import { testAction } from '../../actions/functions/test.js';
3
2
  import { BlueprintCommand } from '../../baseCommands.js';
4
- import { findFunctionByName } from '../../utils/find-function.js';
3
+ import { functionTestCore } from '../../cores/functions/test.js';
5
4
  export default class TestCommand extends BlueprintCommand {
6
5
  static args = {
7
6
  name: Args.string({ description: 'The name of the Sanity Function', required: true }),
@@ -40,34 +39,14 @@ export default class TestCommand extends BlueprintCommand {
40
39
  }),
41
40
  };
42
41
  async run() {
43
- const args = this.args;
44
- const flags = this.flags;
45
- const parsedBlueprint = this.blueprint.parsedBlueprint;
46
- try {
47
- const resource = findFunctionByName(parsedBlueprint, args.name);
48
- const { json, logs, error } = await testAction(resource, {
49
- data: flags.data,
50
- file: flags.file,
51
- timeout: flags.timeout,
52
- }, {
53
- clientOptions: {
54
- apiVersion: flags.api,
55
- dataset: flags.dataset,
56
- projectId: flags['project-id'],
57
- },
58
- });
59
- if (!error) {
60
- this.log('Logs:');
61
- this.log(logs);
62
- this.log('Response:');
63
- this.log(JSON.stringify(json, null, 2));
64
- }
65
- else {
66
- this.log(error.toString());
67
- }
68
- }
69
- catch (error) {
70
- this.log(`Error: ${error || 'Unknown error'}`);
71
- }
42
+ const { success, error } = await functionTestCore({
43
+ bin: this.config.bin,
44
+ log: (msg) => this.log(msg),
45
+ args: this.args,
46
+ flags: this.flags,
47
+ blueprint: this.blueprint,
48
+ });
49
+ if (!success)
50
+ this.error(error);
72
51
  }
73
52
  }
@@ -7,37 +7,38 @@ import { validateFunctionName } from '../../utils/validate/resource.js';
7
7
  export async function blueprintAddCore(options) {
8
8
  const { bin = 'sanity', log, blueprint, args, flags } = options;
9
9
  const { type: resourceType } = args;
10
- const { name: flagResourceName, 'fn-type': flagFnType, javascript: flagJs, 'fn-helpers': flagFnHelpers, install: flagI, } = flags;
11
- let { language: flagFnLang, 'fn-installer': flagFnInstaller, // can be 'skip'!
10
+ const { name: flagResourceName, 'fn-type': flagFnType, javascript: flagJs, 'fn-helpers': flagFnHelpers, install: flagI, 'fn-installer': flagFnInstaller, // can be 'skip'!
12
11
  } = flags;
12
+ let { language: flagFnLang } = flags;
13
13
  flagFnLang = flagJs ? 'js' : flagFnLang;
14
- flagFnInstaller = flagFnInstaller === 'skip' ? undefined : flagFnInstaller;
15
14
  if (resourceType !== 'function') {
16
15
  return {
17
16
  success: false,
18
17
  error: `Unsupported Resource type: ${resourceType}`,
19
18
  };
20
19
  }
21
- if (flagI && flagFnInstaller) {
22
- return {
23
- success: false,
24
- error: 'Cannot use -i flag with the --fn-installer flag',
25
- };
20
+ if (flagI) {
21
+ if (flagFnInstaller) {
22
+ return {
23
+ success: false,
24
+ error: 'Cannot use --fn-installer flag with the --install flag',
25
+ };
26
+ }
27
+ if (!flagFnHelpers) {
28
+ return {
29
+ success: false,
30
+ error: 'Cannot use --no-fn-helpers flag with the --install flag',
31
+ };
32
+ }
26
33
  }
27
- if (flagI && flagFnHelpers === false) {
34
+ if (flagResourceName && !validateFunctionName(flagResourceName)) {
35
+ // if provided && invalid, return error ASAP
28
36
  return {
29
37
  success: false,
30
- error: 'Cannot use -i flag with the --no-fn-helpers flag',
38
+ error: `Invalid function name: ${flagResourceName}`,
31
39
  };
32
40
  }
33
41
  try {
34
- if (flagResourceName && !validateFunctionName(flagResourceName)) {
35
- // if provided && invalid, return error
36
- return {
37
- success: false,
38
- error: `Invalid function name: ${flagResourceName}`,
39
- };
40
- }
41
42
  const fnName = flagResourceName || (await promptForFunctionName());
42
43
  // look for existing function with same name
43
44
  if (blueprint.parsedBlueprint.resources?.some((r) => r.name === fnName)) {
@@ -69,9 +70,8 @@ export async function blueprintAddCore(options) {
69
70
  installCommand = 'npm';
70
71
  }
71
72
  else if (flagFnInstaller) {
72
- // user wants to install helpers using a specific command
73
- addHelpers = true;
74
- installCommand = flagFnInstaller;
73
+ addHelpers = true; // if installer is passed, assume addHelpers
74
+ installCommand = flagFnInstaller === 'skip' ? null : flagFnInstaller;
75
75
  }
76
76
  else {
77
77
  // unsure; ask...
@@ -90,7 +90,7 @@ export async function blueprintAddCore(options) {
90
90
  log(`\nCreated function: ${filePath.replace(cwd(), '')}`);
91
91
  if (!resourceAdded) {
92
92
  // print the resource JSON for manual addition
93
- log('\nAdd this Function resource to your blueprint:');
93
+ log('\nAdd this Function resource to your Blueprint:');
94
94
  log(highlight(JSON.stringify(resource, null, 2), undefined, undefined, 2));
95
95
  }
96
96
  else {
@@ -0,0 +1,7 @@
1
+ import type { CoreConfig, CoreResult } from '../index.js';
2
+ export interface FunctionDevOptions extends CoreConfig {
3
+ flags: {
4
+ port?: number;
5
+ };
6
+ }
7
+ export declare function functionDevCore(options: FunctionDevOptions): Promise<CoreResult>;
@@ -0,0 +1,22 @@
1
+ import { dev } from '../../actions/functions/dev.js';
2
+ export async function functionDevCore(options) {
3
+ const { log, flags } = options;
4
+ const { port = 8080 } = flags;
5
+ try {
6
+ await dev(Number(port));
7
+ log(`Server is running on http://localhost:${port}\n`);
8
+ return {
9
+ success: true,
10
+ // hold the line...
11
+ streaming: new Promise(() => { }),
12
+ };
13
+ }
14
+ catch (error) {
15
+ const errorMessage = error instanceof Error ? error.message : String(error);
16
+ log(`Error starting server: ${errorMessage}`);
17
+ return {
18
+ success: false,
19
+ error: errorMessage,
20
+ };
21
+ }
22
+ }
@@ -1,9 +1,9 @@
1
1
  import type { CoreResult, DeployedBlueprintConfig } from '../../index.js';
2
- export interface EnvAddOptions extends DeployedBlueprintConfig {
2
+ export interface FunctionEnvAddOptions extends DeployedBlueprintConfig {
3
3
  args: {
4
4
  name: string;
5
5
  key: string;
6
6
  value: string;
7
7
  };
8
8
  }
9
- export declare function envAddCore(options: EnvAddOptions): Promise<CoreResult>;
9
+ export declare function functionEnvAddCore(options: FunctionEnvAddOptions): Promise<CoreResult>;
@@ -2,7 +2,7 @@ import chalk from 'chalk';
2
2
  import ora from 'ora';
3
3
  import { update } from '../../../actions/functions/env/update.js';
4
4
  import { findFunctionByName } from '../../../utils/find-function.js';
5
- export async function envAddCore(options) {
5
+ export async function functionEnvAddCore(options) {
6
6
  const args = options.args;
7
7
  const spinner = ora(`Updating "${args.key}" environment variable in "${args.name}"`).start();
8
8
  const { externalId } = findFunctionByName(options.deployedStack, args.name);
@@ -1,7 +1,7 @@
1
1
  import type { CoreResult, DeployedBlueprintConfig } from '../../index.js';
2
- export interface EnvListOptions extends DeployedBlueprintConfig {
2
+ export interface FunctionEnvListOptions extends DeployedBlueprintConfig {
3
3
  args: {
4
4
  name: string;
5
5
  };
6
6
  }
7
- export declare function envListCore(options: EnvListOptions): Promise<CoreResult>;
7
+ export declare function functionEnvListCore(options: FunctionEnvListOptions): Promise<CoreResult>;
@@ -1,7 +1,7 @@
1
1
  import ora from 'ora';
2
2
  import { list } from '../../../actions/functions/env/list.js';
3
3
  import { findFunctionByName } from '../../../utils/find-function.js';
4
- export async function envListCore(options) {
4
+ export async function functionEnvListCore(options) {
5
5
  const args = options.args;
6
6
  const spinner = ora(`Listing environment variables for "${args.name}"`).start();
7
7
  const { externalId } = findFunctionByName(options.deployedStack, args.name);
@@ -1,8 +1,8 @@
1
1
  import type { CoreResult, DeployedBlueprintConfig } from '../../index.js';
2
- export interface EnvRemoveOptions extends DeployedBlueprintConfig {
2
+ export interface FunctionEnvRemoveOptions extends DeployedBlueprintConfig {
3
3
  args: {
4
4
  name: string;
5
5
  key: string;
6
6
  };
7
7
  }
8
- export declare function envRemoveCore(options: EnvRemoveOptions): Promise<CoreResult>;
8
+ export declare function functionEnvRemoveCore(options: FunctionEnvRemoveOptions): Promise<CoreResult>;
@@ -2,7 +2,7 @@ import chalk from 'chalk';
2
2
  import ora from 'ora';
3
3
  import { remove } from '../../../actions/functions/env/remove.js';
4
4
  import { findFunctionByName } from '../../../utils/find-function.js';
5
- export async function envRemoveCore(options) {
5
+ export async function functionEnvRemoveCore(options) {
6
6
  const args = options.args;
7
7
  const spinner = ora(`Removing "${args.key}" environment variable in "${args.name}"`).start();
8
8
  const { externalId } = findFunctionByName(options.deployedStack, args.name);
@@ -1,6 +1,12 @@
1
- export { envAddCore } from './env/add.js';
2
- export type { EnvAddOptions } from './env/add.js';
3
- export { envListCore } from './env/list.js';
4
- export type { EnvListOptions } from './env/list.js';
5
- export { envRemoveCore } from './env/remove.js';
6
- export type { EnvRemoveOptions } from './env/remove.js';
1
+ export { functionEnvAddCore } from './env/add.js';
2
+ export type { FunctionEnvAddOptions as EnvAddOptions } from './env/add.js';
3
+ export { functionEnvListCore } from './env/list.js';
4
+ export type { FunctionEnvListOptions as EnvListOptions } from './env/list.js';
5
+ export { functionEnvRemoveCore } from './env/remove.js';
6
+ export type { FunctionEnvRemoveOptions as EnvRemoveOptions } from './env/remove.js';
7
+ export { functionLogsCore } from './logs.js';
8
+ export type { FunctionLogsOptions } from './logs.js';
9
+ export { functionTestCore } from './test.js';
10
+ export type { FunctionTestOptions } from './test.js';
11
+ export { functionDevCore } from './dev.js';
12
+ export type { FunctionDevOptions } from './dev.js';
@@ -1,3 +1,6 @@
1
- export { envAddCore } from './env/add.js';
2
- export { envListCore } from './env/list.js';
3
- export { envRemoveCore } from './env/remove.js';
1
+ export { functionEnvAddCore } from './env/add.js';
2
+ export { functionEnvListCore } from './env/list.js';
3
+ export { functionEnvRemoveCore } from './env/remove.js';
4
+ export { functionLogsCore } from './logs.js';
5
+ export { functionTestCore } from './test.js';
6
+ export { functionDevCore } from './dev.js';
@@ -0,0 +1,14 @@
1
+ import type { CoreResult, DeployedBlueprintConfig } from '../index.js';
2
+ export interface FunctionLogsOptions extends DeployedBlueprintConfig {
3
+ args: {
4
+ name: string;
5
+ };
6
+ flags: {
7
+ limit: number;
8
+ json?: boolean;
9
+ utc?: boolean;
10
+ delete?: boolean;
11
+ force?: boolean;
12
+ };
13
+ }
14
+ export declare function functionLogsCore(options: FunctionLogsOptions): Promise<CoreResult>;
@@ -0,0 +1,74 @@
1
+ import chalk from 'chalk';
2
+ import inquirer from 'inquirer';
3
+ import ora from 'ora';
4
+ import { deleteLogs as deleteLogsAction, logs as getLogsAction, } from '../../actions/functions/logs.js';
5
+ import { formatTitle } from '../../utils/display/blueprints-formatting.js';
6
+ import { findFunctionByName } from '../../utils/find-function.js';
7
+ export async function functionLogsCore(options) {
8
+ const { args, flags, log, auth, deployedStack } = options;
9
+ const { name } = args;
10
+ const { delete: shouldDelete, force, limit, json, utc } = flags;
11
+ const { externalId } = findFunctionByName(deployedStack, name); // throws if not found
12
+ if (shouldDelete)
13
+ return deleteLogs({ name, externalId, auth, force, log });
14
+ return getLogs({ name, externalId, auth, limit, json, utc, log });
15
+ }
16
+ async function deleteLogs({ name, externalId, auth, force, log, }) {
17
+ if (!force) {
18
+ const { certain } = await inquirer.prompt({
19
+ type: 'confirm',
20
+ name: 'certain',
21
+ message: `Are you sure you want to delete ${chalk.bold('all')} logs for function ${chalk.yellow(name)}?`,
22
+ default: false,
23
+ });
24
+ if (!certain)
25
+ return { success: true };
26
+ }
27
+ const spinner = ora(`Deleting logs for function ${chalk.yellow(name)}`).start();
28
+ const { ok, error } = await deleteLogsAction(externalId, auth);
29
+ if (!ok) {
30
+ spinner.fail(`${chalk.red('Failed')} to delete logs`);
31
+ return { success: false, error: error || 'Unknown error' };
32
+ }
33
+ spinner.succeed('Logs deleted');
34
+ return { success: true };
35
+ }
36
+ async function getLogs({ name, externalId, auth, limit, json, utc, log, }) {
37
+ const spinner = ora(`Finding logs for function "${name}"`).start();
38
+ const { ok, error, logs, total } = await getLogsAction(externalId, { limit }, auth);
39
+ if (!ok) {
40
+ spinner.fail(`${chalk.red('Failed')} to retrieve logs`);
41
+ return { success: false, error: error || 'Unknown error' };
42
+ }
43
+ const filteredLogs = logs.filter((entry) => entry.level && entry.message);
44
+ if (filteredLogs.length === 0) {
45
+ spinner.info(`No logs found for function ${name}`);
46
+ return { success: true };
47
+ }
48
+ spinner.succeed(`${formatTitle('Function', name)} Logs`);
49
+ if (!json) {
50
+ log(`Found ${chalk.bold(total)} log entries for function ${chalk.yellow(name)}`);
51
+ if (logs.length < total) {
52
+ log(`Here are the last ${chalk.bold(filteredLogs.length.toString())} entries`);
53
+ }
54
+ log('\n');
55
+ for (const { time, level, message } of filteredLogs) {
56
+ const date = new Date(time);
57
+ const [dateString, timeString] = utc
58
+ ? date.toISOString().slice(0, 19).split('T')
59
+ : [date.toLocaleDateString(), date.toLocaleTimeString()];
60
+ log([chalk.bold(dateString), chalk.bold.blue(timeString), logLevel(level), message].join(' '));
61
+ }
62
+ }
63
+ else {
64
+ log(JSON.stringify(filteredLogs, null, 2));
65
+ }
66
+ return { success: true };
67
+ }
68
+ function logLevel(level) {
69
+ if (level === 'ERROR')
70
+ return chalk.red(level);
71
+ if (level === 'WARN')
72
+ return chalk.yellow(level);
73
+ return chalk.green(level);
74
+ }
@@ -0,0 +1,17 @@
1
+ import type { ReadBlueprintResult } from '../../actions/blueprints/blueprint.js';
2
+ import type { CoreConfig, CoreResult } from '../index.js';
3
+ export interface FunctionTestOptions extends CoreConfig {
4
+ blueprint: ReadBlueprintResult;
5
+ args: {
6
+ name: string;
7
+ };
8
+ flags: {
9
+ data?: string;
10
+ file?: string;
11
+ timeout?: number;
12
+ api?: string;
13
+ dataset?: string;
14
+ 'project-id'?: string;
15
+ };
16
+ }
17
+ export declare function functionTestCore(options: FunctionTestOptions): Promise<CoreResult>;
@@ -0,0 +1,43 @@
1
+ import { testAction } from '../../actions/functions/test.js';
2
+ import { findFunctionByName } from '../../utils/find-function.js';
3
+ export async function functionTestCore(options) {
4
+ const { blueprint, log, args, flags } = options;
5
+ const { name: fnName } = args;
6
+ const { data, file, timeout, api, dataset, 'project-id': projectId } = flags;
7
+ const { parsedBlueprint } = blueprint;
8
+ try {
9
+ const resource = findFunctionByName(parsedBlueprint, fnName); // throws if not found
10
+ const invokeOptions = {
11
+ data,
12
+ file,
13
+ timeout,
14
+ };
15
+ const contextOptions = {
16
+ clientOptions: {
17
+ apiVersion: api,
18
+ dataset,
19
+ projectId,
20
+ },
21
+ };
22
+ const { json, logs, error } = await testAction(resource, invokeOptions, contextOptions);
23
+ if (error) {
24
+ return {
25
+ success: false,
26
+ error: error.toString(),
27
+ };
28
+ }
29
+ log('Logs:');
30
+ log(logs || '');
31
+ if (json) {
32
+ log('Response:');
33
+ log(JSON.stringify(json, null, 2));
34
+ }
35
+ return { success: true };
36
+ }
37
+ catch (error) {
38
+ return {
39
+ success: false,
40
+ error: error instanceof Error ? error.message : String(error),
41
+ };
42
+ }
43
+ }
@@ -9,7 +9,7 @@ export interface CoreConfig {
9
9
  log: (message: string) => void;
10
10
  }
11
11
  export interface BlueprintConfig extends CoreConfig {
12
- sanityToken: string;
12
+ token: string;
13
13
  blueprint: ReadBlueprintResult;
14
14
  }
15
15
  export interface DeployedBlueprintConfig extends BlueprintConfig {
@@ -31,5 +31,9 @@ export type CoreResult = {
31
31
  streaming?: Promise<void>;
32
32
  error?: never;
33
33
  };
34
- export declare function initBlueprintConfig(bin: string, log: (msg: string) => void, token: string): Promise<Result<BlueprintConfig>>;
35
- export declare function initDeployedBlueprintConfig(config: Partial<BlueprintConfig> & Pick<BlueprintConfig, 'bin' | 'log' | 'sanityToken'>): Promise<Result<DeployedBlueprintConfig>>;
34
+ export declare function initBlueprintConfig({ bin, log, token, }: {
35
+ bin: string;
36
+ log: (msg: string) => void;
37
+ token: string;
38
+ }): Promise<Result<BlueprintConfig>>;
39
+ export declare function initDeployedBlueprintConfig(config: Partial<BlueprintConfig> & Pick<BlueprintConfig, 'bin' | 'log' | 'token'>): Promise<Result<DeployedBlueprintConfig>>;
@@ -4,7 +4,7 @@ import { presentBlueprintParserErrors } from '../utils/display/errors.js';
4
4
  import { niceId } from '../utils/display/presenters.js';
5
5
  export * as blueprintsCores from './blueprints/index.js';
6
6
  export * as functionsCores from './functions/index.js';
7
- export async function initBlueprintConfig(bin, log, token) {
7
+ export async function initBlueprintConfig({ bin, log, token, }) {
8
8
  const blueprint = await readLocalBlueprint();
9
9
  if (blueprint.errors.length > 0) {
10
10
  log(presentBlueprintParserErrors(blueprint.errors));
@@ -16,18 +16,18 @@ export async function initBlueprintConfig(bin, log, token) {
16
16
  bin,
17
17
  blueprint,
18
18
  log,
19
- sanityToken: token,
19
+ token,
20
20
  },
21
21
  };
22
22
  }
23
23
  export async function initDeployedBlueprintConfig(config) {
24
24
  if (!config.blueprint) {
25
- const blueprintResult = await initBlueprintConfig(config.bin, config.log, config.sanityToken);
25
+ const blueprintResult = await initBlueprintConfig(config);
26
26
  if (!blueprintResult.ok) {
27
27
  return blueprintResult;
28
28
  }
29
29
  config.blueprint = blueprintResult.value.blueprint;
30
- config.sanityToken = blueprintResult.value.sanityToken;
30
+ config.token = blueprintResult.value.token;
31
31
  }
32
32
  const { projectId, stackId } = config.blueprint;
33
33
  if (!(projectId && stackId)) {
@@ -37,7 +37,7 @@ export async function initDeployedBlueprintConfig(config) {
37
37
  if (!stackId)
38
38
  return { ok: false, error: 'Missing deployment configuration for Blueprint' };
39
39
  }
40
- const auth = { token: config.sanityToken, projectId };
40
+ const auth = { token: config.token, projectId };
41
41
  const stackResponse = await getStack({ stackId, auth });
42
42
  if (!stackResponse.ok) {
43
43
  config.log(`Could not retrieve deployment info for ${niceId(stackId)}. Was it destroyed?`);
@@ -50,7 +50,7 @@ export async function initDeployedBlueprintConfig(config) {
50
50
  bin: config.bin,
51
51
  log: config.log,
52
52
  blueprint: config.blueprint,
53
- sanityToken: config.sanityToken,
53
+ token: config.token,
54
54
  projectId,
55
55
  stackId,
56
56
  auth,
@@ -82,10 +82,10 @@ export interface Stack {
82
82
  /** @internal */
83
83
  export interface StackResource {
84
84
  id: string;
85
- displayName: string;
86
85
  name: string;
87
86
  type: string;
88
87
  externalId: string;
88
+ displayName?: string;
89
89
  parameters?: Record<string, unknown>;
90
90
  }
91
91
  /** @internal */
@@ -829,5 +829,5 @@
829
829
  ]
830
830
  }
831
831
  },
832
- "version": "7.0.2"
832
+ "version": "7.1.0"
833
833
  }
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": "7.0.2",
4
+ "version": "7.1.0",
5
5
  "author": "Sanity Runtime Team",
6
6
  "type": "module",
7
7
  "license": "MIT",