@sanity/runtime-cli 13.2.0 → 13.2.2

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/13.2.0 linux-x64 node-v24.13.0
23
+ @sanity/runtime-cli/13.2.2 linux-x64 node-v24.13.0
24
24
  $ sanity-run --help [COMMAND]
25
25
  USAGE
26
26
  $ sanity-run COMMAND
@@ -98,7 +98,7 @@ EXAMPLES
98
98
  $ sanity-run blueprints add function --name my-function --fn-type document-create --fn-type document-update --lang js
99
99
  ```
100
100
 
101
- _See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.0/src/commands/blueprints/add.ts)_
101
+ _See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.2/src/commands/blueprints/add.ts)_
102
102
 
103
103
  ## `sanity-run blueprints config`
104
104
 
@@ -133,7 +133,7 @@ EXAMPLES
133
133
  $ sanity-run blueprints config --edit --project-id <projectId> --stack-id <stackId>
134
134
  ```
135
135
 
136
- _See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.0/src/commands/blueprints/config.ts)_
136
+ _See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.2/src/commands/blueprints/config.ts)_
137
137
 
138
138
  ## `sanity-run blueprints deploy`
139
139
 
@@ -163,7 +163,7 @@ EXAMPLES
163
163
  $ sanity-run blueprints deploy --no-wait
164
164
  ```
165
165
 
166
- _See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.0/src/commands/blueprints/deploy.ts)_
166
+ _See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.2/src/commands/blueprints/deploy.ts)_
167
167
 
168
168
  ## `sanity-run blueprints destroy`
169
169
 
@@ -195,7 +195,7 @@ EXAMPLES
195
195
  $ sanity-run blueprints destroy --stack-id <stackId> --project-id <projectId> --force --no-wait
196
196
  ```
197
197
 
198
- _See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.0/src/commands/blueprints/destroy.ts)_
198
+ _See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.2/src/commands/blueprints/destroy.ts)_
199
199
 
200
200
  ## `sanity-run blueprints doctor`
201
201
 
@@ -221,7 +221,7 @@ DESCRIPTION
221
221
  issues.
222
222
  ```
223
223
 
224
- _See code: [src/commands/blueprints/doctor.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.0/src/commands/blueprints/doctor.ts)_
224
+ _See code: [src/commands/blueprints/doctor.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.2/src/commands/blueprints/doctor.ts)_
225
225
 
226
226
  ## `sanity-run blueprints info`
227
227
 
@@ -251,7 +251,7 @@ EXAMPLES
251
251
  $ sanity-run blueprints info --id <stackId>
252
252
  ```
253
253
 
254
- _See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.0/src/commands/blueprints/info.ts)_
254
+ _See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.2/src/commands/blueprints/info.ts)_
255
255
 
256
256
  ## `sanity-run blueprints init [DIR]`
257
257
 
@@ -301,7 +301,7 @@ EXAMPLES
301
301
  $ sanity-run blueprints init --blueprint-type <json|js|ts> --stack-name <stackName>
302
302
  ```
303
303
 
304
- _See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.0/src/commands/blueprints/init.ts)_
304
+ _See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.2/src/commands/blueprints/init.ts)_
305
305
 
306
306
  ## `sanity-run blueprints logs`
307
307
 
@@ -329,7 +329,7 @@ EXAMPLES
329
329
  $ sanity-run blueprints logs --watch
330
330
  ```
331
331
 
332
- _See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.0/src/commands/blueprints/logs.ts)_
332
+ _See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.2/src/commands/blueprints/logs.ts)_
333
333
 
334
334
  ## `sanity-run blueprints plan`
335
335
 
@@ -352,7 +352,7 @@ EXAMPLES
352
352
  $ sanity-run blueprints plan
353
353
  ```
354
354
 
355
- _See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.0/src/commands/blueprints/plan.ts)_
355
+ _See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.2/src/commands/blueprints/plan.ts)_
356
356
 
357
357
  ## `sanity-run blueprints stacks`
358
358
 
@@ -381,7 +381,7 @@ EXAMPLES
381
381
  $ sanity-run blueprints stacks --organization-id <organizationId>
382
382
  ```
383
383
 
384
- _See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.0/src/commands/blueprints/stacks.ts)_
384
+ _See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.2/src/commands/blueprints/stacks.ts)_
385
385
 
386
386
  ## `sanity-run functions add`
387
387
 
@@ -430,7 +430,7 @@ EXAMPLES
430
430
  $ sanity-run functions add --name my-function --type document-create --type document-update --lang js
431
431
  ```
432
432
 
433
- _See code: [src/commands/functions/add.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.0/src/commands/functions/add.ts)_
433
+ _See code: [src/commands/functions/add.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.2/src/commands/functions/add.ts)_
434
434
 
435
435
  ## `sanity-run functions dev`
436
436
 
@@ -464,7 +464,7 @@ EXAMPLES
464
464
  $ sanity-run functions dev --timeout 60
465
465
  ```
466
466
 
467
- _See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.0/src/commands/functions/dev.ts)_
467
+ _See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.2/src/commands/functions/dev.ts)_
468
468
 
469
469
  ## `sanity-run functions env add NAME KEY VALUE`
470
470
 
@@ -491,7 +491,7 @@ EXAMPLES
491
491
  $ sanity-run functions env add MyFunction API_URL https://api.example.com/
492
492
  ```
493
493
 
494
- _See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.0/src/commands/functions/env/add.ts)_
494
+ _See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.2/src/commands/functions/env/add.ts)_
495
495
 
496
496
  ## `sanity-run functions env list NAME`
497
497
 
@@ -515,7 +515,7 @@ EXAMPLES
515
515
  $ sanity-run functions env list MyFunction
516
516
  ```
517
517
 
518
- _See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.0/src/commands/functions/env/list.ts)_
518
+ _See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.2/src/commands/functions/env/list.ts)_
519
519
 
520
520
  ## `sanity-run functions env remove NAME KEY`
521
521
 
@@ -541,7 +541,7 @@ EXAMPLES
541
541
  $ sanity-run functions env remove MyFunction API_URL
542
542
  ```
543
543
 
544
- _See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.0/src/commands/functions/env/remove.ts)_
544
+ _See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.2/src/commands/functions/env/remove.ts)_
545
545
 
546
546
  ## `sanity-run functions logs [NAME]`
547
547
 
@@ -580,7 +580,7 @@ EXAMPLES
580
580
  $ sanity-run functions logs <name> --delete
581
581
  ```
582
582
 
583
- _See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.0/src/commands/functions/logs.ts)_
583
+ _See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.2/src/commands/functions/logs.ts)_
584
584
 
585
585
  ## `sanity-run functions test [NAME]`
586
586
 
@@ -634,7 +634,7 @@ EXAMPLES
634
634
  $ sanity-run functions test <name> --event update --data-before '{ "title": "before" }' --data-after '{ "title": "after" }'
635
635
  ```
636
636
 
637
- _See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.0/src/commands/functions/test.ts)_
637
+ _See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v13.2.2/src/commands/functions/test.ts)_
638
638
 
639
639
  ## `sanity-run help [COMMAND]`
640
640
 
@@ -198,7 +198,7 @@ export async function readLocalBlueprint(logger, validate, blueprintPath) {
198
198
  const errors = parserResult.result !== 'valid' ? parserResult.errors : [];
199
199
  // resource validation
200
200
  if (parsedBlueprint?.resources) {
201
- if (validate.resources) {
201
+ if (validate?.resources) {
202
202
  // validate function resources
203
203
  errors.push(...validateResources(parsedBlueprint.resources));
204
204
  }
@@ -1,7 +1,7 @@
1
- import chalk from 'chalk';
2
1
  import { EventSource } from 'eventsource';
3
2
  import { formatLogEntry } from '../../utils/display/logs-formatting.js';
4
3
  import getHeaders from '../../utils/get-headers.js';
4
+ import { styleText } from '../../utils/style-text.js';
5
5
  import { createTracedFetch } from '../../utils/traced-fetch.js';
6
6
  import { logsUrl } from './logs.js';
7
7
  export function streamLogs({ stackId, after, auth, onLog, onOpen, onError, logger, }) {
@@ -83,13 +83,13 @@ export async function setupLogStreaming(config) {
83
83
  let alreadyOpened = false;
84
84
  const onStreamOpen = () => {
85
85
  if (!alreadyOpened && showBanner)
86
- log(`Streaming logs... ${chalk.bold('ctrl+c')} to cancel`);
86
+ log(`Streaming logs... ${styleText('bold', 'ctrl+c')} to cancel`);
87
87
  if (alreadyOpened)
88
- log(`${chalk.green('Reconnected')}`);
88
+ log(`${styleText('green', 'Reconnected')}`);
89
89
  alreadyOpened = true;
90
90
  };
91
91
  const onStreamError = (error) => {
92
- log(`${chalk.red('Stream error:')} ${error}`);
92
+ log(`${styleText('red', 'Stream error:')} ${error}`);
93
93
  };
94
94
  return streamLogs({
95
95
  stackId,
@@ -2,7 +2,7 @@ import { spawn } from 'node:child_process';
2
2
  import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
3
3
  import { dirname, join } from 'node:path';
4
4
  import { cwd } from 'node:process';
5
- import chalk from 'chalk';
5
+ import { styleText } from '../../utils/style-text.js';
6
6
  import { writeOrUpdateNodeDependency } from '../node.js';
7
7
  import { addResourceToBlueprint } from './blueprint.js';
8
8
  const DEFAULT_FUNCTION_TEMPLATE = /*js*/ `export async function handler({context, event}) {
@@ -83,7 +83,7 @@ async function runPackageInstall(cwd, command) {
83
83
  const lines = data.toString().split('\n');
84
84
  return lines
85
85
  .filter(Boolean)
86
- .map((line) => ` ${chalk.magenta('│')} ${chalk.dim(line)}`)
86
+ .map((line) => ` ${styleText('magenta', '│')} ${styleText('dim', line)}`)
87
87
  .join('\n');
88
88
  };
89
89
  install.stdout?.on('data', (data) => {
@@ -1,7 +1,7 @@
1
- import chalk from 'chalk';
2
1
  import { patchConfigFile, writeConfigFile, } from '../../actions/blueprints/config.js';
3
2
  import { filePathRelativeToCwd, labeledId, warn } from '../../utils/display/presenters.js';
4
3
  import { promptForProject, promptForStack } from '../../utils/display/prompt.js';
4
+ import { styleText } from '../../utils/style-text.js';
5
5
  export async function blueprintConfigCore(options) {
6
6
  const { bin = 'sanity', blueprint, log, token, flags } = options;
7
7
  const { edit: editConfig = false, 'project-id': flagProjectId, 'organization-id': flagOrganizationId, 'stack-id': flagStackId, verbose: _v = false, } = flags;
@@ -87,7 +87,7 @@ function printConfig(options) {
87
87
  const scopeType = projectId ? 'project' : 'organization';
88
88
  const scopeId = projectId ? projectId : organizationId;
89
89
  log.verbose(JSON.stringify(config));
90
- log(`${chalk.bold(`${configLabel} configuration:`)}`);
90
+ log(`${styleText('bold', `${configLabel} configuration:`)}`);
91
91
  log(` Deployment: ${labeledId('stack', stackId)}`);
92
92
  log(` Scoped to: ${labeledId(scopeType, scopeId)}`);
93
93
  if (updatedAt)
@@ -1,9 +1,9 @@
1
1
  import { setTimeout } from 'node:timers/promises';
2
- import chalk from 'chalk';
3
2
  import { stashAsset } from '../../actions/blueprints/assets.js';
4
3
  import { setupLogStreaming } from '../../actions/blueprints/logs-streaming.js';
5
4
  import { getStack, updateStack } from '../../actions/blueprints/stacks.js';
6
5
  import { niceId } from '../../utils/display/presenters.js';
6
+ import { styleText } from '../../utils/style-text.js';
7
7
  import { isLocalFunctionCollection, isLocalFunctionResource } from '../../utils/types.js';
8
8
  export async function blueprintDeployCore(options) {
9
9
  const { bin = 'sanity', log, auth, stackId, scopeType, scopeId, deployedStack, blueprint, flags, } = options;
@@ -78,16 +78,16 @@ export async function blueprintDeployCore(options) {
78
78
  logger: log,
79
79
  });
80
80
  if (!deployOk) {
81
- spinner.fail(`${chalk.red('Failed')} to update Stack deployment`);
81
+ spinner.fail(`${styleText('red', 'Failed')} to update Stack deployment`);
82
82
  return { success: false, error: deployError || 'Failed to update Stack deployment' };
83
83
  }
84
84
  spinner.stop().clear();
85
85
  if (noWait) {
86
- log(chalk.bold.green('Stack deployment started!'));
86
+ log(styleText(['bold', 'green'], 'Stack deployment started!'));
87
87
  log(`Use \`${bin} blueprints info\` to check status`);
88
88
  return { success: true, data: { resources } };
89
89
  }
90
- log(chalk.dim('Stack deployment progress:'));
90
+ log(styleText('dim', 'Stack deployment progress:'));
91
91
  let logStreamCleanup = null;
92
92
  try {
93
93
  logStreamCleanup = await setupLogStreaming({
@@ -117,7 +117,7 @@ export async function blueprintDeployCore(options) {
117
117
  if (operation.status === 'COMPLETED') {
118
118
  if (logStreamCleanup)
119
119
  logStreamCleanup();
120
- log(chalk.bold.green('Stack deployment completed!'));
120
+ log(styleText(['bold', 'green'], 'Stack deployment completed!'));
121
121
  return { success: true, data: { resources } };
122
122
  }
123
123
  await setTimeout(1500);
@@ -1,9 +1,9 @@
1
1
  import { setTimeout } from 'node:timers/promises';
2
2
  import { confirm } from '@inquirer/prompts';
3
- import chalk from 'chalk';
4
3
  import { setupLogStreaming } from '../../actions/blueprints/logs-streaming.js';
5
4
  import { destroyStack, getStack } from '../../actions/blueprints/stacks.js';
6
5
  import { niceId } from '../../utils/display/presenters.js';
6
+ import { styleText } from '../../utils/style-text.js';
7
7
  export async function blueprintDestroyCore(options) {
8
8
  const { log, token, blueprint, flags } = options;
9
9
  const { force = false, 'project-id': flagProjectId, 'organization-id': flagOrganizationId, 'stack-id': flagStackId, 'no-wait': noWait = false, verbose: _verbose = false, } = flags;
@@ -53,7 +53,7 @@ export async function blueprintDestroyCore(options) {
53
53
  if (!stack)
54
54
  return { success: false, error: 'Stack deployment not found' };
55
55
  const destroySpinner = log.ora({
56
- text: `Destroying Stack deployment "${chalk.bold(stack.name)}" ${niceId(stack.id)}...`,
56
+ text: `Destroying Stack deployment "${styleText('bold', stack.name)}" ${niceId(stack.id)}...`,
57
57
  color: 'red',
58
58
  });
59
59
  if (!force) {
@@ -69,7 +69,7 @@ export async function blueprintDestroyCore(options) {
69
69
  // 5 second countdown
70
70
  let i = 5;
71
71
  while (i >= 0) {
72
- destroySpinner.text = `Destroying Stack deployment in ${chalk.bold((i--).toString())} seconds...`;
72
+ destroySpinner.text = `Destroying Stack deployment in ${styleText('bold', (i--).toString())} seconds...`;
73
73
  await setTimeout(1000);
74
74
  }
75
75
  destroySpinner.text = 'Destroying Stack deployment 💥';
@@ -86,10 +86,10 @@ export async function blueprintDestroyCore(options) {
86
86
  }
87
87
  destroySpinner.stop().clear();
88
88
  if (noWait) {
89
- log(chalk.bold.magenta('Stack destruction started!'));
89
+ log(styleText(['bold', 'magenta'], 'Stack destruction started!'));
90
90
  return { success: true };
91
91
  }
92
- log(chalk.dim('Stack destruction progress:'));
92
+ log(styleText('dim', 'Stack destruction progress:'));
93
93
  let logStreamCleanup = null;
94
94
  try {
95
95
  logStreamCleanup = await setupLogStreaming({
@@ -106,7 +106,7 @@ export async function blueprintDestroyCore(options) {
106
106
  // it's possible that the operation is "gone" or available and "COMPLETED"
107
107
  if (logStreamCleanup)
108
108
  logStreamCleanup();
109
- log(chalk.bold.magenta('Stack destruction completed!'));
109
+ log(styleText(['bold', 'magenta'], 'Stack destruction completed!'));
110
110
  return { success: true };
111
111
  }
112
112
  if (operation.status === 'FAILED') {
@@ -1,9 +1,9 @@
1
1
  import { cwd } from 'node:process';
2
- import chalk from 'chalk';
3
2
  import { findBlueprintFile, readLocalBlueprint, } from '../../actions/blueprints/blueprint.js';
4
3
  import { getStack } from '../../actions/blueprints/stacks.js';
5
4
  import config from '../../config.js';
6
5
  import { capitalize, check, filePathRelativeToCwd, indent, niceId, severe, unsure, } from '../../utils/display/presenters.js';
6
+ import { styleText } from '../../utils/style-text.js';
7
7
  import { createTracedFetch } from '../../utils/traced-fetch.js';
8
8
  import { validTokenOrErrorMessage } from '../../utils/validated-token.js';
9
9
  import { blueprintConfigCore } from './config.js';
@@ -21,7 +21,7 @@ const diagLookup = {
21
21
  export async function blueprintDoctorCore(options) {
22
22
  const { bin, log, token, validateResources, flags: { verbose: v, path: p, fix }, } = options;
23
23
  const yikes = (s) => {
24
- log.error(chalk.bgRedBright.whiteBright.bold(` ${s} `));
24
+ log.error(styleText(['bgRedBright', 'whiteBright', 'bold'], ` ${s} `));
25
25
  };
26
26
  const here = cwd();
27
27
  const path = p || here;
@@ -167,9 +167,9 @@ export async function blueprintDoctorCore(options) {
167
167
  }
168
168
  const errorMessage = 'One or more checks failed';
169
169
  if (allGood) {
170
- log(chalk.bold.green('All checks passed'));
170
+ log(styleText(['bold', 'green'], 'All checks passed'));
171
171
  if (fix)
172
- log(chalk.bold.yellow('Nothing to fix; --fix flag is ignored'));
172
+ log(styleText(['bold', 'yellow'], 'Nothing to fix; --fix flag is ignored'));
173
173
  return { success: true, data: { diagnostics } };
174
174
  }
175
175
  else if (fix) {
@@ -1,7 +1,6 @@
1
1
  import { existsSync, readFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
3
  import { confirm } from '@inquirer/prompts';
4
- import chalk from 'chalk';
5
4
  import { findBlueprintFile, readLocalBlueprint, writeBlueprintToDisk, } from '../../actions/blueprints/blueprint.js';
6
5
  import { writeConfigFile } from '../../actions/blueprints/config.js';
7
6
  import { createEmptyStack } from '../../actions/blueprints/stacks.js';
@@ -12,6 +11,7 @@ import { getProject } from '../../actions/sanity/projects.js';
12
11
  import { BLUEPRINT_CONFIG_DIR, BLUEPRINT_CONFIG_FILE } from '../../config.js';
13
12
  import { check, filePathRelativeToCwd, labeledId, warn } from '../../utils/display/presenters.js';
14
13
  import { promptForBlueprintType, promptForProject, promptForStack, } from '../../utils/display/prompt.js';
14
+ import { styleText } from '../../utils/style-text.js';
15
15
  import { blueprintConfigCore } from './config.js';
16
16
  const SCOPE_PROJECT = 'project';
17
17
  const SCOPE_ORGANIZATION = 'organization';
@@ -155,7 +155,7 @@ async function handleExampleInitialization(options) {
155
155
  }
156
156
  const { files, dir: newDir, instructions } = addedExample;
157
157
  for (const filePath of Object.keys(files)) {
158
- log(check(`${chalk.bold('Created:')} ${newDir}/${filePath}`));
158
+ log(check(`${styleText('bold', 'Created:')} ${newDir}/${filePath}`));
159
159
  }
160
160
  const discoveredBlueprint = findBlueprintFile(exampleDir);
161
161
  if (!discoveredBlueprint) {
@@ -163,8 +163,8 @@ async function handleExampleInitialization(options) {
163
163
  }
164
164
  const { blueprintFilePath } = discoveredBlueprint;
165
165
  writeConfigFile(blueprintFilePath, { projectId: resolvedProjectId, stackId: stack.id });
166
- log(check(`${chalk.bold('Configured:')} ${exampleDir}/${BLUEPRINT_CONFIG_DIR}/${BLUEPRINT_CONFIG_FILE}`));
167
- log(`\n Run "${chalk.bold.magenta(`cd ${exampleDir} && npm i`)}" and check out the README`);
166
+ log(check(`${styleText('bold', 'Configured:')} ${exampleDir}/${BLUEPRINT_CONFIG_DIR}/${BLUEPRINT_CONFIG_FILE}`));
167
+ log(`\n Run "${styleText(['bold', 'magenta'], `cd ${exampleDir} && npm i`)}" and check out the README`);
168
168
  if (instructions) {
169
169
  log('');
170
170
  log(instructions);
@@ -271,27 +271,27 @@ export async function createBlueprintFiles(params) {
271
271
  const blueprintFilePath = join(blueprintDir, blueprintFileName);
272
272
  writeBlueprintToDisk({ blueprintFilePath });
273
273
  if (userProvidedDirName) {
274
- log(check(`${chalk.bold('New folder created:')} ${userProvidedDirName}/`));
274
+ log(check(`${styleText('bold', 'New folder created:')} ${userProvidedDirName}/`));
275
275
  }
276
276
  const displayPath = userProvidedDirName || '.';
277
- log(check(`${chalk.bold('Created Blueprint:')} ${displayPath}/${blueprintFileName}`));
277
+ log(check(`${styleText('bold', 'Created Blueprint:')} ${displayPath}/${blueprintFileName}`));
278
278
  writeConfigFile(blueprintFilePath, {
279
279
  stackId,
280
280
  ...(scopeType === SCOPE_ORGANIZATION ? { organizationId: scopeId } : { projectId: scopeId }),
281
281
  });
282
- log(check(`${chalk.bold('Added configuration:')} ${displayPath}/${BLUEPRINT_CONFIG_DIR}/${BLUEPRINT_CONFIG_FILE}`));
282
+ log(check(`${styleText('bold', 'Added configuration:')} ${displayPath}/${BLUEPRINT_CONFIG_DIR}/${BLUEPRINT_CONFIG_FILE}`));
283
283
  const gitignoreResult = writeGitignoreFile(blueprintFilePath);
284
284
  if (gitignoreResult.action === 'created') {
285
- log(check(`${chalk.bold('Added .gitignore:')} ${displayPath}/.gitignore`));
285
+ log(check(`${styleText('bold', 'Added .gitignore:')} ${displayPath}/.gitignore`));
286
286
  }
287
287
  else if (gitignoreResult.action === 'updated') {
288
- log(check(`${chalk.bold('Updated .gitignore:')} ${displayPath}/.gitignore`));
288
+ log(check(`${styleText('bold', 'Updated .gitignore:')} ${displayPath}/.gitignore`));
289
289
  }
290
290
  if (blueprintExtension !== 'json') {
291
291
  const blueprintsPackage = '@sanity/blueprints';
292
292
  try {
293
293
  await writeOrUpdateNodeDependency(blueprintFilePath, blueprintsPackage, log);
294
- log(check(`${chalk.bold('Added dependency:')} ${blueprintsPackage}`));
294
+ log(check(`${styleText('bold', 'Added dependency:')} ${blueprintsPackage}`));
295
295
  }
296
296
  catch {
297
297
  log.warn(warn(`Unable to add ${blueprintsPackage} to your project.`));
@@ -303,6 +303,6 @@ export async function createBlueprintFiles(params) {
303
303
  if (blueprintExtension !== 'json')
304
304
  nextStepParts.push('npm install');
305
305
  nextStepParts.push(`${bin} blueprints --help`);
306
- log(`\n Run "${chalk.bold.magenta(nextStepParts.join(' && '))}" to get started`);
306
+ log(`\n Run "${styleText(['bold', 'magenta'], nextStepParts.join(' && '))}" to get started`);
307
307
  return { success: true };
308
308
  }
@@ -1,9 +1,9 @@
1
- import chalk from 'chalk';
2
1
  import { getLogs, getRecentLogs } from '../../actions/blueprints/logs.js';
3
2
  import { setupLogStreaming } from '../../actions/blueprints/logs-streaming.js';
4
3
  import { formatTitle } from '../../utils/display/blueprints-formatting.js';
5
4
  import { formatLogEntry, formatLogsByDay, organizeLogsByDay, } from '../../utils/display/logs-formatting.js';
6
5
  import { niceId } from '../../utils/display/presenters.js';
6
+ import { styleText } from '../../utils/style-text.js';
7
7
  export async function blueprintLogsCore(options) {
8
8
  const { log, auth, stackId, deployedStack, flags } = options;
9
9
  const { watch = false, verbose: _verbose = false } = flags;
@@ -12,7 +12,7 @@ export async function blueprintLogsCore(options) {
12
12
  if (watch) {
13
13
  const { ok, logs, error } = await getLogs(stackId, auth, log);
14
14
  if (!ok) {
15
- spinner.fail(`${chalk.red('Failed')} to retrieve logs`);
15
+ spinner.fail(`${styleText('red', 'Failed')} to retrieve logs`);
16
16
  log.error(`Error: ${error || 'Unknown error'}`);
17
17
  return { success: false, error: error || 'Failed to retrieve logs' };
18
18
  }
@@ -44,7 +44,7 @@ export async function blueprintLogsCore(options) {
44
44
  // Regular non-streaming logs
45
45
  const { ok, logs, error } = await getLogs(stackId, auth, log);
46
46
  if (!ok) {
47
- spinner.fail(`${chalk.red('Failed')} to retrieve Stack deployment logs`);
47
+ spinner.fail(`${styleText('red', 'Failed')} to retrieve Stack deployment logs`);
48
48
  log.error(`Error: ${error || 'Unknown error'}`);
49
49
  return { success: false, error: error || 'Failed to retrieve logs' };
50
50
  }
@@ -53,7 +53,7 @@ export async function blueprintLogsCore(options) {
53
53
  return { success: true };
54
54
  }
55
55
  spinner.succeed(`${formatTitle('Blueprint', deployedStack.name)} Logs`);
56
- log(`Found ${chalk.bold(logs.length.toString())} log entries for Stack deployment ${niceId(stackId)}\n`);
56
+ log(`Found ${styleText('bold', logs.length.toString())} log entries for Stack deployment ${niceId(stackId)}\n`);
57
57
  // Organize and format logs by day
58
58
  const logsByDay = organizeLogsByDay(logs);
59
59
  log(formatLogsByDay(logsByDay));
@@ -1,11 +1,11 @@
1
- import chalk from 'chalk';
2
1
  import { getStack } from '../../actions/blueprints/stacks.js';
3
2
  import { formatResourceTree, stackDeployDiff } from '../../utils/display/blueprints-formatting.js';
3
+ import { styleText } from '../../utils/style-text.js';
4
4
  export async function blueprintPlanCore(options) {
5
5
  const { bin = 'sanity', log, blueprint, token, flags } = options;
6
6
  const { verbose: _verbose = false } = flags;
7
7
  const { scopeType, scopeId, stackId, parsedBlueprint, fileInfo } = blueprint;
8
- log(`${chalk.bold.blueBright('Blueprint Stack deployment plan')} ${chalk.dim(`(${fileInfo.fileName})`)}`);
8
+ log(`${styleText(['bold', 'blueBright'], 'Blueprint Stack deployment plan')} ${styleText('dim', `(${fileInfo.fileName})`)}`);
9
9
  log(formatResourceTree(parsedBlueprint.resources));
10
10
  if (token && scopeType && scopeId && stackId) {
11
11
  const stackResponse = await getStack({
@@ -14,7 +14,7 @@ export async function blueprintPlanCore(options) {
14
14
  logger: log,
15
15
  });
16
16
  if (!stackResponse.ok) {
17
- log(chalk.dim('Unable to retrieve live Stack deployment for comparison'));
17
+ log(styleText('dim', 'Unable to retrieve live Stack deployment for comparison'));
18
18
  }
19
19
  else {
20
20
  const diff = stackDeployDiff(parsedBlueprint, stackResponse.stack);
@@ -22,6 +22,6 @@ export async function blueprintPlanCore(options) {
22
22
  log(diff);
23
23
  }
24
24
  }
25
- log(`\n Run "${chalk.bold.magenta(`${bin} blueprints deploy`)}" to deploy these Stack changes`);
25
+ log(`\n Run "${styleText(['bold', 'magenta'], `${bin} blueprints deploy`)}" to deploy these Stack changes`);
26
26
  return { success: true };
27
27
  }
@@ -1,7 +1,7 @@
1
- import chalk from 'chalk';
2
1
  import { listStacks } from '../../actions/blueprints/stacks.js';
3
2
  import { formatStacksListing } from '../../utils/display/blueprints-formatting.js';
4
3
  import { capitalize, niceId } from '../../utils/display/presenters.js';
4
+ import { styleText } from '../../utils/style-text.js';
5
5
  export async function blueprintStacksCore(options) {
6
6
  const { log, token, blueprint, flags } = options;
7
7
  const { scopeType: blueprintScopeType, scopeId: blueprintScopeId, stackId: blueprintStackId, } = blueprint;
@@ -32,7 +32,7 @@ export async function blueprintStacksCore(options) {
32
32
  log('No stacks found');
33
33
  return { success: true };
34
34
  }
35
- log(`${chalk.bold(capitalize(scopeType))} ${niceId(scopeId)} ${chalk.bold('Stacks')}:\n`);
35
+ log(`${styleText('bold', capitalize(scopeType))} ${niceId(scopeId)} ${styleText('bold', 'Stacks')}:\n`);
36
36
  log(formatStacksListing(stacks, blueprintStackId));
37
37
  return { success: true };
38
38
  }
@@ -3,11 +3,11 @@ import { dirname, join } from 'node:path';
3
3
  import { cwd } from 'node:process';
4
4
  import { checkbox, confirm, input, select } from '@inquirer/prompts';
5
5
  import { highlight } from 'cardinal';
6
- import chalk from 'chalk';
7
6
  import { createFunctionResource } from '../../actions/blueprints/resources.js';
8
7
  import { verifyExampleExists, writeExample } from '../../actions/sanity/examples.js';
9
8
  import { SANITY_FUNCTION_MEDIA_LIBRARY_ASSET, SANITY_FUNCTION_SCHEDULE } from '../../constants.js';
10
9
  import { check, indent, warn } from '../../utils/display/presenters.js';
10
+ import { styleText } from '../../utils/style-text.js';
11
11
  import { validateFunctionName } from '../../utils/validate/resource.js';
12
12
  const generateFunctionBlueprintResourceTemplate = (fnName, eventNames) => {
13
13
  const definer = eventNames[0].substring(0, eventNames[0].lastIndexOf('-')) === 'document'
@@ -61,11 +61,11 @@ export async function functionAddCore(options) {
61
61
  const { files, dir, instructions, functionConfig } = addedExample;
62
62
  const newDir = dir.replace(root, '').replace(/^[/\\]+/, '');
63
63
  for (const filePath of Object.keys(files)) {
64
- log(check(`${chalk.bold('Created:')} ${newDir}/${filePath}`));
64
+ log(check(`${styleText('bold', 'Created:')} ${newDir}/${filePath}`));
65
65
  }
66
66
  if (functionConfig) {
67
67
  log('');
68
- log(chalk.bold(`Add the following to ${blueprint.fileInfo.fileName}:`));
68
+ log(styleText('bold', `Add the following to ${blueprint.fileInfo.fileName}:`));
69
69
  const configString = JSON.stringify(functionConfig, null, 2);
70
70
  if (blueprint.fileInfo.extension === '.json') {
71
71
  log(indent(highlight(configString)));
@@ -111,7 +111,7 @@ export async function functionAddCore(options) {
111
111
  if (flagResourceName && !validateFunctionName(flagResourceName)) {
112
112
  return {
113
113
  success: false,
114
- error: `Invalid function name: "${chalk.bold(flagResourceName)}"`,
114
+ error: `Invalid function name: "${styleText('bold', flagResourceName)}"`,
115
115
  };
116
116
  }
117
117
  try {
@@ -119,7 +119,7 @@ export async function functionAddCore(options) {
119
119
  if (blueprint.parsedBlueprint.resources?.some((r) => r.name === fnName)) {
120
120
  return {
121
121
  success: false,
122
- error: `Function "${chalk.bold(fnName)}" already exists.`,
122
+ error: `Function "${styleText('bold', fnName)}" already exists.`,
123
123
  };
124
124
  }
125
125
  let fnTypes;
@@ -176,7 +176,7 @@ export async function functionAddCore(options) {
176
176
  installCommand = addHelpers ? await promptForInstallCommand() : null;
177
177
  }
178
178
  if (installCommand)
179
- log(`${chalk.magenta('Installing')} with ${installCommand}...`);
179
+ log(`${styleText('magenta', 'Installing')} with ${installCommand}...`);
180
180
  const { filePath, resourceAdded, resource } = await createFunctionResource({
181
181
  blueprintFilePath,
182
182
  name: fnName,
@@ -187,7 +187,7 @@ export async function functionAddCore(options) {
187
187
  }, log);
188
188
  log(`\nCreated function: ${filePath.replace(root, '')}`);
189
189
  if (!resourceAdded) {
190
- log(`\n${chalk.bold('Add the Resource to your Blueprint:')}`);
190
+ log(`\n${styleText('bold', 'Add the Resource to your Blueprint:')}`);
191
191
  switch (blueprint.fileInfo.extension) {
192
192
  case '.ts':
193
193
  case '.js':
@@ -201,7 +201,7 @@ export async function functionAddCore(options) {
201
201
  }
202
202
  }
203
203
  else {
204
- log(`Function "${chalk.bold(fnName)}" added to Blueprint file.`);
204
+ log(`Function "${styleText('bold', fnName)}" added to Blueprint file.`);
205
205
  }
206
206
  return { success: true };
207
207
  }
@@ -1,13 +1,13 @@
1
- import chalk from 'chalk';
2
1
  import { update } from '../../../actions/functions/env/update.js';
3
2
  import { findFunctionInStack } from '../../../utils/find-function.js';
3
+ import { styleText } from '../../../utils/style-text.js';
4
4
  export async function functionEnvAddCore(options) {
5
5
  const { args, log } = options;
6
6
  const spinner = log.ora(`Updating "${args.key}" environment variable in "${args.name}"`).start();
7
7
  const { externalId } = findFunctionInStack(options.deployedStack, args.name);
8
8
  const result = await update(externalId, args.key, args.value, options.auth, options.log);
9
9
  if (!result.ok) {
10
- spinner.fail(`${chalk.red('Failed')} to update ${args.key}`);
10
+ spinner.fail(`${styleText('red', 'Failed')} to update ${args.key}`);
11
11
  return {
12
12
  success: false,
13
13
  error: result.error || 'Unknown error',
@@ -1,13 +1,13 @@
1
- import chalk from 'chalk';
2
1
  import { remove } from '../../../actions/functions/env/remove.js';
3
2
  import { findFunctionInStack } from '../../../utils/find-function.js';
3
+ import { styleText } from '../../../utils/style-text.js';
4
4
  export async function functionEnvRemoveCore(options) {
5
5
  const { args, log } = options;
6
6
  const spinner = log.ora(`Removing "${args.key}" environment variable in "${args.name}"`).start();
7
7
  const { externalId } = findFunctionInStack(options.deployedStack, args.name);
8
8
  const result = await remove(externalId, args.key, options.auth, options.log);
9
9
  if (!result.ok) {
10
- spinner.fail(`${chalk.red('Failed')} to remove ${args.key}`);
10
+ spinner.fail(`${styleText('red', 'Failed')} to remove ${args.key}`);
11
11
  return { success: false, error: result.error || 'Unknown error' };
12
12
  }
13
13
  spinner.succeed(`Removal of ${args.key} succeeded`);
@@ -1,9 +1,9 @@
1
1
  import { confirm } from '@inquirer/prompts';
2
- import chalk from 'chalk';
3
2
  import { deleteLogs as deleteLogsAction, logs as getLogsAction, streamLogs as streamLogsAction, } from '../../actions/functions/logs.js';
4
3
  import { formatTitle } from '../../utils/display/blueprints-formatting.js';
5
4
  import { niceId } from '../../utils/display/presenters.js';
6
5
  import { findFunctionInStack, getFunctionNames } from '../../utils/find-function.js';
6
+ import { styleText } from '../../utils/style-text.js';
7
7
  export async function functionLogsCore(options) {
8
8
  const { args, flags, log, error, auth, deployedStack, blueprint, helpText } = options;
9
9
  const { name } = args;
@@ -27,16 +27,16 @@ export async function functionLogsCore(options) {
27
27
  async function deleteLogs({ name, externalId, auth, force, log, }) {
28
28
  if (!force) {
29
29
  const certain = await confirm({
30
- message: `Are you sure you want to delete ${chalk.bold('all')} logs for function ${chalk.yellow(name)}?`,
30
+ message: `Are you sure you want to delete ${styleText('bold', 'all')} logs for function ${styleText('yellow', name)}?`,
31
31
  default: false,
32
32
  });
33
33
  if (!certain)
34
34
  return { success: true };
35
35
  }
36
- const spinner = log.ora(`Deleting logs for function ${chalk.yellow(name)}`).start();
36
+ const spinner = log.ora(`Deleting logs for function ${styleText('yellow', name)}`).start();
37
37
  const { ok, error } = await deleteLogsAction(externalId, auth, log);
38
38
  if (!ok) {
39
- spinner.fail(`${chalk.red('Failed')} to delete logs`);
39
+ spinner.fail(`${styleText('red', 'Failed')} to delete logs`);
40
40
  return { success: false, error: error || 'Unknown error' };
41
41
  }
42
42
  spinner.succeed('Logs deleted');
@@ -47,18 +47,18 @@ async function streamLogs({ name, externalId, auth, log, }) {
47
47
  try {
48
48
  spinner.stop();
49
49
  log(`Streaming log session for function ${niceId(name)}`);
50
- log(`Watching for new logs... ${chalk.bold('ctrl+c')} to stop`);
50
+ log(`Watching for new logs... ${styleText('bold', 'ctrl+c')} to stop`);
51
51
  let alreadyOpened = false;
52
52
  const onOpen = () => {
53
53
  if (alreadyOpened)
54
- log(`${chalk.green('Reconnected')}`);
54
+ log(`${styleText('green', 'Reconnected')}`);
55
55
  alreadyOpened = true;
56
56
  };
57
57
  const renderLog = (logEntry) => {
58
58
  const { time, level, message } = logEntry;
59
59
  log(formatLog(time, level, message, true));
60
60
  };
61
- streamLogsAction(externalId, auth, renderLog, onOpen, (error) => log.error(`${chalk.red('Error:')} ${error}`), log);
61
+ streamLogsAction(externalId, auth, renderLog, onOpen, (error) => log.error(`${styleText('red', 'Error:')} ${error}`), log);
62
62
  // Return a special key for streaming mode
63
63
  return {
64
64
  success: true,
@@ -76,7 +76,7 @@ async function getLogs({ name, externalId, auth, limit, json, utc, log, }) {
76
76
  const spinner = log.ora(`Finding logs for function "${name}"`).start();
77
77
  const { ok, error, logs, total } = await getLogsAction(externalId, { limit }, auth, log);
78
78
  if (!ok) {
79
- spinner.fail(`${chalk.red('Failed')} to retrieve logs`);
79
+ spinner.fail(`${styleText('red', 'Failed')} to retrieve logs`);
80
80
  return { success: false, error: error || 'Unknown error' };
81
81
  }
82
82
  const filteredLogs = logs.filter((entry) => entry.level && entry.message);
@@ -86,9 +86,9 @@ async function getLogs({ name, externalId, auth, limit, json, utc, log, }) {
86
86
  }
87
87
  spinner.succeed(`${formatTitle('Function', name)} Logs`);
88
88
  if (!json) {
89
- log(`Found ${chalk.bold(total)} log entries for function ${chalk.yellow(name)}`);
89
+ log(`Found ${styleText('bold', String(total))} log entries for function ${styleText('yellow', name)}`);
90
90
  if (logs.length < total) {
91
- log(`Here are the last ${chalk.bold(filteredLogs.length.toString())} entries`);
91
+ log(`Here are the last ${styleText('bold', filteredLogs.length.toString())} entries`);
92
92
  }
93
93
  log('\n');
94
94
  for (const { time, level, message } of filteredLogs) {
@@ -106,16 +106,16 @@ function formatLog(time, level, message, utc) {
106
106
  ? date.toISOString().slice(0, 19).split('T')
107
107
  : [date.toLocaleDateString(), date.toLocaleTimeString()];
108
108
  return [
109
- chalk.bold(dateString),
110
- chalk.bold.blue(timeString),
109
+ styleText('bold', dateString),
110
+ styleText(['bold', 'blue'], timeString),
111
111
  logLevel(level.toUpperCase()),
112
112
  message,
113
113
  ].join(' ');
114
114
  }
115
115
  function logLevel(level) {
116
116
  if (level === 'ERROR')
117
- return chalk.red(level);
117
+ return styleText('red', level);
118
118
  if (level === 'WARN')
119
- return chalk.yellow(level);
120
- return chalk.green(level);
119
+ return styleText('yellow', level);
120
+ return styleText('green', level);
121
121
  }
@@ -1,6 +1,6 @@
1
1
  import { treeify } from 'array-treeify';
2
- import chalk from 'chalk';
3
2
  import { SANITY_ACCESS_ROBOT, SANITY_ACCESS_ROLE, SANITY_FUNCTION_DOCUMENT, SANITY_FUNCTION_MEDIA_LIBRARY_ASSET, SANITY_FUNCTION_SCHEDULE, SANITY_PROJECT_CORS, SANITY_PROJECT_DATASET, SANITY_PROJECT_WEBHOOK, } from '../../constants.js';
3
+ import { styleText } from '../style-text.js';
4
4
  import { isCorsOriginResource, isDatasetResource, isRobotResource, isRoleResource, isWebhookResource, } from '../types.js';
5
5
  import { formatDate, formatDuration } from './dates.js';
6
6
  import { niceId } from './presenters.js';
@@ -54,22 +54,22 @@ const categoryByLabel = Object.values(RESOURCE_CATEGORIES).reduce((acc, curr) =>
54
54
  return acc;
55
55
  }, {});
56
56
  function resourceName(res, displayNameAttribute) {
57
- const nameParts = [chalk.bold.green(res.name)];
57
+ const nameParts = [styleText(['bold', 'green'], res.name)];
58
58
  const displayName = displayNameAttribute &&
59
59
  displayNameAttribute in res &&
60
60
  typeof res[displayNameAttribute] === 'string' &&
61
61
  res[displayNameAttribute];
62
62
  if (displayName && displayName !== res.name)
63
- nameParts.push(chalk.green(`"${displayName}"`));
63
+ nameParts.push(styleText('green', `"${displayName}"`));
64
64
  return nameParts.join(' ');
65
65
  }
66
66
  function deployedResourceName(res, displayNameAttribute, _verbose = false) {
67
- const nameParts = [chalk.bold.green(res.name)];
67
+ const nameParts = [styleText(['bold', 'green'], res.name)];
68
68
  const displayName = displayNameAttribute &&
69
69
  typeof res.parameters[displayNameAttribute] === 'string' &&
70
70
  res.parameters[displayNameAttribute];
71
71
  if (displayName && displayName !== res.name)
72
- nameParts.push(chalk.green(`"${displayName}"`));
72
+ nameParts.push(styleText('green', `"${displayName}"`));
73
73
  // if (verbose)
74
74
  nameParts.push(idList(res));
75
75
  return nameParts.join(' ');
@@ -85,7 +85,7 @@ function idList(res) {
85
85
  return ids.length > 0 ? ids.join(' ') : '';
86
86
  }
87
87
  export function formatTitle(title, name) {
88
- return `${chalk.bold.blue(title)} ${chalk.bold(`"${name}"`)}`;
88
+ return `${styleText(['bold', 'blue'], title)} ${styleText('bold', `"${name}"`)}`;
89
89
  }
90
90
  function categorizeResources(resources) {
91
91
  const categorized = {};
@@ -108,13 +108,15 @@ function categorizeResources(resources) {
108
108
  return categorized;
109
109
  }
110
110
  function buildOutputTree(resources, createName, mapToResource, verbose = false) {
111
- const output = [`${chalk.bold.underline('Resources')} [${resources.length}]`];
111
+ const output = [
112
+ `${styleText(['bold', 'underline'], 'Resources')} [${resources.length}]`,
113
+ ];
112
114
  const children = [];
113
115
  const categorized = categorizeResources(resources);
114
116
  for (const category of Object.values(categoryByLabel)) {
115
117
  const catResources = categorized[category.label];
116
118
  if (catResources && catResources.length > 0) {
117
- children.push(`${chalk.bold(category.label)} [${catResources.length}]`);
119
+ children.push(`${styleText('bold', category.label)} [${catResources.length}]`);
118
120
  const details = [];
119
121
  for (const res of catResources) {
120
122
  details.push(createName(category, res, verbose));
@@ -126,9 +128,9 @@ function buildOutputTree(resources, createName, mapToResource, verbose = false)
126
128
  }
127
129
  }
128
130
  if (categorized['Other Resources'] && categorized['Other Resources'].length > 0) {
129
- children.push(`${chalk.bold('Other Resources')} [${categorized['Other Resources'].length}]`);
131
+ children.push(`${styleText('bold', 'Other Resources')} [${categorized['Other Resources'].length}]`);
130
132
  const otherResourcesOutput = categorized['Other Resources'].map((other) => {
131
- return `${chalk.yellow(other.name ?? 'unnamed')} ${chalk.dim(other.type)}`;
133
+ return `${styleText('yellow', other.name ?? 'unnamed')} ${styleText('dim', other.type)}`;
132
134
  });
133
135
  children.push(otherResourcesOutput);
134
136
  }
@@ -152,9 +154,9 @@ export function formatStackInfo(stack, isCurrentStack = false) {
152
154
  const isProjectBasedStack = isStack && stack.id === `ST-${stack.scopeId}`;
153
155
  const output = [];
154
156
  if (isStack) {
155
- let stackName = chalk.bold(`"${stack.name}"`);
157
+ let stackName = styleText('bold', `"${stack.name}"`);
156
158
  if (isCurrentStack)
157
- stackName = `${chalk.blue(stackName)} (current)`;
159
+ stackName = `${styleText('blue', stackName)} (current)`;
158
160
  if (isProjectBasedStack)
159
161
  stackName += ' (project-based)';
160
162
  output.push(`${stackName} ${niceId(stack.id)}`);
@@ -180,15 +182,15 @@ export function formatStackInfo(stack, isCurrentStack = false) {
180
182
  if (operation.id)
181
183
  operationOutput.push(`Recent Operation ${niceId(operation.id)}:`);
182
184
  if (operation.status) {
183
- const operationColor = operation.status === 'COMPLETED' ? chalk.green : chalk.red;
185
+ const operationColor = operation.status === 'COMPLETED' ? 'green' : 'red';
184
186
  const status = operation.status || 'UNKNOWN';
185
- operationOutput.push(`Status: ${operationColor(status)}`);
187
+ operationOutput.push(`Status: ${styleText(operationColor, status)}`);
186
188
  }
187
189
  if (operation.createdAt)
188
190
  operationOutput.push(`Started: ${formatDate(operation.createdAt)}`);
189
191
  if (operation.status === 'COMPLETED' && operation.completedAt && operation.createdAt) {
190
192
  operationOutput.push(`Completed: ${formatDate(operation.completedAt)}`);
191
- operationOutput.push(`Duration: ${chalk.yellow(formatDuration(operation.createdAt, operation.completedAt))}`);
193
+ operationOutput.push(`Duration: ${styleText('yellow', formatDuration(operation.createdAt, operation.completedAt))}`);
192
194
  }
193
195
  infoOutput.push(operationOutput);
194
196
  }
@@ -225,10 +227,10 @@ export function stackDeployDiff(localBlueprint, deployedStack) {
225
227
  return null;
226
228
  const output = [];
227
229
  if (added.length > 0) {
228
- output.push(` ${chalk.bold.greenBright('++')} ${added.map(({ name }) => chalk.bgGreen.whiteBright(`"${name}"`)).join(' ')}`);
230
+ output.push(` ${styleText(['bold', 'greenBright'], '++')} ${added.map(({ name }) => styleText(['bgGreen', 'whiteBright'], `"${name}"`)).join(' ')}`);
229
231
  }
230
232
  if (removed.length > 0) {
231
- output.push(` ${chalk.bold.redBright('--')} ${removed.map(({ name }) => chalk.bgRed.whiteBright(`"${name}"`)).join(' ')}`);
233
+ output.push(` ${styleText(['bold', 'redBright'], '--')} ${removed.map(({ name }) => styleText(['bgRed', 'whiteBright'], `"${name}"`)).join(' ')}`);
232
234
  }
233
235
  return output.join('\n');
234
236
  }
@@ -1,10 +1,10 @@
1
1
  import { treeify } from 'array-treeify';
2
- import chalk from 'chalk';
2
+ import { styleText } from '../style-text.js';
3
3
  export function formatLogEntry(log, withDate = true, isNewest = false) {
4
4
  const date = new Date(log.timestamp);
5
5
  const time = date.toLocaleTimeString();
6
6
  const day = date.toLocaleDateString();
7
- return `${isNewest ? `${chalk.green('>')} ` : ''}${withDate ? `${day} ` : ''}${chalk.dim(time)} ${log.message}`;
7
+ return `${isNewest ? `${styleText('green', '>')} ` : ''}${withDate ? `${day} ` : ''}${styleText('dim', time)} ${log.message}`;
8
8
  }
9
9
  export function organizeLogsByDay(logs) {
10
10
  const logsByDay = new Map();
@@ -23,7 +23,7 @@ export function formatLogsByDay(logsByDay) {
23
23
  return new Date(a).getTime() - new Date(b).getTime();
24
24
  });
25
25
  for (const day of sortedDays) {
26
- output.push(`${chalk.blue('Date:')} ${chalk.bold(day)}`);
26
+ output.push(`${styleText('blue', 'Date:')} ${styleText('bold', day)}`);
27
27
  const dayLogs = logsByDay.get(day) || [];
28
28
  dayLogs.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
29
29
  const dayLogsOutput = dayLogs.map((log) => formatLogEntry(log, false));
@@ -1,24 +1,24 @@
1
1
  import { cwd } from 'node:process';
2
- import chalk from 'chalk';
2
+ import { styleText } from '../style-text.js';
3
3
  export function check(str) {
4
- return `${chalk.bold(chalk.green('✔︎'))} ${str}`;
4
+ return `${styleText('bold', styleText('green', '✔︎'))} ${str}`;
5
5
  }
6
6
  export function info(str) {
7
- return `${chalk.bold.blue('ℹ︎')} ${str}`;
7
+ return `${styleText(['bold', 'blue'], 'ℹ︎')} ${str}`;
8
8
  }
9
9
  export function warn(str) {
10
- return `${chalk.bold.yellow('▶︎')} ${str}`;
10
+ return `${styleText(['bold', 'yellow'], '▶︎')} ${str}`;
11
11
  }
12
12
  export function unsure(str) {
13
- return `${chalk.bold.cyan('?')} ${str}`;
13
+ return `${styleText(['bold', 'cyan'], '?')} ${str}`;
14
14
  }
15
15
  export function severe(str) {
16
- return `${chalk.bold.red('✘')} ${str}`;
16
+ return `${styleText(['bold', 'red'], '✘')} ${str}`;
17
17
  }
18
18
  export function niceId(id) {
19
19
  if (!id)
20
20
  return '';
21
- return `<${chalk.yellow(id)}>`;
21
+ return `<${styleText('yellow', id)}>`;
22
22
  }
23
23
  export function indent(str, spaces = 2) {
24
24
  const pad = ' '.repeat(spaces);
@@ -34,5 +34,5 @@ export function filePathRelativeToCwd(filePath) {
34
34
  return filePath.replace(cwd(), '.');
35
35
  }
36
36
  export function labeledId(label, id) {
37
- return `${chalk.blue(capitalize(label || 'unknown'))} ${niceId(id || 'unknown')}`;
37
+ return `${styleText('blue', capitalize(label || 'unknown'))} ${niceId(id || 'unknown')}`;
38
38
  }
@@ -1,7 +1,7 @@
1
1
  import { confirm, input, Separator, select } from '@inquirer/prompts';
2
- import chalk from 'chalk';
3
2
  import { createEmptyStack, listStacks } from '../../actions/blueprints/stacks.js';
4
3
  import { groupProjectsByOrganization } from '../../actions/sanity/projects.js';
4
+ import { styleText } from '../style-text.js';
5
5
  import { niceId } from './presenters.js';
6
6
  export async function promptForBlueprintType() {
7
7
  return await select({
@@ -91,11 +91,11 @@ export async function promptForStack({ projectId, token, logger, }) {
91
91
  let pickedStackId = NEW_STACK_ID;
92
92
  if (stacks.length > 0) {
93
93
  const stackChoices = [];
94
- stackChoices.push(new Separator(chalk.underline('Create a new Stack:')));
95
- stackChoices.push({ name: chalk.bold('New Stack ✨'), value: NEW_STACK_ID });
96
- stackChoices.push(new Separator(chalk.underline('Use an existing Stack:')));
94
+ stackChoices.push(new Separator(styleText('underline', 'Create a new Stack:')));
95
+ stackChoices.push({ name: styleText('bold', 'New Stack ✨'), value: NEW_STACK_ID });
96
+ stackChoices.push(new Separator(styleText('underline', 'Use an existing Stack:')));
97
97
  stackChoices.push(...stacks.map((s) => ({
98
- name: `"${s.name}" ${niceId(s.id)} ${chalk.dim(`(${s.resources.length} res)`)}`,
98
+ name: `"${s.name}" ${niceId(s.id)} ${styleText('dim', `(${s.resources.length} res)`)}`,
99
99
  value: s.id,
100
100
  })));
101
101
  pickedStackId = await select({
@@ -1,10 +1,10 @@
1
- import chalk from 'chalk';
2
1
  import { isScheduleEvent, } from '../../utils/types.js';
2
+ import { styleText } from '../style-text.js';
3
3
  function formatLabel(label) {
4
- return chalk.dim(`${label}:`);
4
+ return styleText('dim', `${label}:`);
5
5
  }
6
6
  function formatLabeledValue(label, value) {
7
- return `${chalk.dim(`${label}:`)} ${value}`;
7
+ return `${styleText('dim', `${label}:`)} ${value}`;
8
8
  }
9
9
  function arrayifyEvent(event) {
10
10
  if (!event)
@@ -1,11 +1,27 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
1
3
  import hydrate from '@architect/hydrate';
2
4
  import inventory from '@architect/inventory';
3
5
  import { convertResourceToArcFormat } from './resource-to-arc.js';
4
6
  export async function resolveResourceDependencies(resource, transpiled) {
5
7
  const rawArc = await convertResourceToArcFormat(resource, transpiled);
6
8
  const inv = await inventory({ rawArc });
9
+ const cwd = inv.inv._project.cwd;
10
+ const installOptions = {
11
+ inventory: inv,
12
+ hydrateShared: false,
13
+ quiet: true,
14
+ pnpm: false,
15
+ yarn: false,
16
+ };
17
+ if (existsSync(join(cwd, 'pnpm-lock.yaml'))) {
18
+ installOptions.pnpm = true;
19
+ }
20
+ else if (existsSync(join(cwd, 'yarn.lock'))) {
21
+ installOptions.yarn = true;
22
+ }
7
23
  try {
8
- await hydrate.install({ inventory: inv, hydrateShared: false, quiet: true });
24
+ await hydrate.install(installOptions);
9
25
  }
10
26
  catch (err) {
11
27
  // This is a temporary fix.
@@ -0,0 +1,2 @@
1
+ import { styleText as nodeStyleText } from 'node:util';
2
+ export declare const styleText: typeof nodeStyleText;
@@ -0,0 +1,44 @@
1
+ import { env, stdout } from 'node:process';
2
+ import { styleText as nodeStyleText } from 'node:util';
3
+ function supportsColor() {
4
+ /*
5
+ * https://force-color.org
6
+ * Command-line software which outputs colored text should check for a
7
+ * FORCE_COLOR environment variable. When this variable is present and
8
+ * not an empty string (regardless of its value), it should force the
9
+ * addition of ANSI color.
10
+ *
11
+ * But the sample implementation accounts for when FORCE_COLOR is 0:
12
+ * if (force_color != NULL && force_color[0] != '\0') color = true;
13
+ * So we check for '0' and 'false' as well.
14
+ */
15
+ if (env.FORCE_COLOR !== undefined && env.FORCE_COLOR !== '0' && env.FORCE_COLOR !== 'false') {
16
+ return true;
17
+ }
18
+ /*
19
+ * https://no-color.org
20
+ * Command-line software which adds ANSI color to its output by default
21
+ * should check for a NO_COLOR environment variable that, when present
22
+ * and not an empty string (regardless of its value), prevents the
23
+ * addition of ANSI color.
24
+ */
25
+ if (env.NO_COLOR !== undefined && env.NO_COLOR !== '') {
26
+ return false;
27
+ }
28
+ /*
29
+ * https://nodejs.org/docs/latest/api/cli.html#node_disable_colors1
30
+ * When set, colors will not be used in the REPL.
31
+ */
32
+ if (env.NODE_DISABLE_COLORS !== undefined && env.NODE_DISABLE_COLORS !== '') {
33
+ return false;
34
+ }
35
+ /*
36
+ * If the stdout is a TTY, use colors.
37
+ */
38
+ return typeof stdout?.isTTY === 'boolean' && stdout.isTTY;
39
+ }
40
+ export const styleText = (format, text) => {
41
+ if (!supportsColor())
42
+ return String(text);
43
+ return nodeStyleText(format, text);
44
+ };
@@ -1,7 +1,7 @@
1
1
  import { randomUUID } from 'node:crypto';
2
2
  import { performance } from 'node:perf_hooks';
3
3
  import { env } from 'node:process';
4
- import chalk from 'chalk';
4
+ import { styleText } from './style-text.js';
5
5
  let defaultMaxLength = env.SANITY_TRACE_MAX_LENGTH
6
6
  ? Number.parseInt(env.SANITY_TRACE_MAX_LENGTH, 10)
7
7
  : 500;
@@ -178,8 +178,8 @@ export function createTracedFetch(logger, options) {
178
178
  const method = init?.method || 'GET';
179
179
  const startTime = performance.now();
180
180
  function trace(type, msgTemplate, ...args) {
181
- const arrow = type === 'req' ? '→' : type === 'res' ? '←' : chalk.red('✗');
182
- logger.trace(`${chalk.dim('[%s]')} HTTP ${arrow} ${msgTemplate}`, requestId, ...args);
181
+ const arrow = type === 'req' ? '→' : type === 'res' ? '←' : styleText('red', '✗');
182
+ logger.trace(`${styleText('dim', '[%s]')} HTTP ${arrow} ${msgTemplate}`, requestId, ...args);
183
183
  }
184
184
  // Log request URL
185
185
  trace('req', '%s %s', method, url);
@@ -1933,5 +1933,5 @@
1933
1933
  ]
1934
1934
  }
1935
1935
  },
1936
- "version": "13.2.0"
1936
+ "version": "13.2.2"
1937
1937
  }
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": "13.2.0",
4
+ "version": "13.2.2",
5
5
  "author": "Sanity Runtime Team",
6
6
  "type": "module",
7
7
  "license": "MIT",
@@ -102,12 +102,11 @@
102
102
  "@oclif/core": "^4.8.0",
103
103
  "@oclif/plugin-help": "^6.2.36",
104
104
  "@sanity/blueprints": "^0.9.0",
105
- "@sanity/blueprints-parser": "^0.3.0",
105
+ "@sanity/blueprints-parser": "^0.3.1",
106
106
  "@sanity/client": "^7.14.0",
107
107
  "adm-zip": "^0.5.16",
108
108
  "array-treeify": "^0.1.5",
109
109
  "cardinal": "^2.1.1",
110
- "chalk": "^5.6.2",
111
110
  "eventsource": "^4.1.0",
112
111
  "find-up": "^8.0.0",
113
112
  "get-folder-size": "^5.0.0",