@sanity/runtime-cli 13.2.1 → 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 +18 -18
- package/dist/actions/blueprints/blueprint.js +1 -1
- package/dist/actions/blueprints/logs-streaming.js +4 -4
- package/dist/actions/blueprints/resources.js +2 -2
- package/dist/cores/blueprints/config.js +2 -2
- package/dist/cores/blueprints/deploy.js +5 -5
- package/dist/cores/blueprints/destroy.js +6 -6
- package/dist/cores/blueprints/doctor.js +4 -4
- package/dist/cores/blueprints/init.js +11 -11
- package/dist/cores/blueprints/logs.js +4 -4
- package/dist/cores/blueprints/plan.js +4 -4
- package/dist/cores/blueprints/stacks.js +2 -2
- package/dist/cores/functions/add.js +8 -8
- package/dist/cores/functions/env/add.js +2 -2
- package/dist/cores/functions/env/remove.js +2 -2
- package/dist/cores/functions/logs.js +15 -15
- package/dist/utils/display/blueprints-formatting.js +19 -17
- package/dist/utils/display/logs-formatting.js +3 -3
- package/dist/utils/display/presenters.js +8 -8
- package/dist/utils/display/prompt.js +5 -5
- package/dist/utils/display/resources-formatting.js +3 -3
- package/dist/utils/style-text.d.ts +2 -0
- package/dist/utils/style-text.js +44 -0
- package/dist/utils/traced-fetch.js +3 -3
- package/oclif.manifest.json +1 -1
- package/package.json +2 -3
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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... ${
|
|
86
|
+
log(`Streaming logs... ${styleText('bold', 'ctrl+c')} to cancel`);
|
|
87
87
|
if (alreadyOpened)
|
|
88
|
-
log(`${
|
|
88
|
+
log(`${styleText('green', 'Reconnected')}`);
|
|
89
89
|
alreadyOpened = true;
|
|
90
90
|
};
|
|
91
91
|
const onStreamError = (error) => {
|
|
92
|
-
log(`${
|
|
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
|
|
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) => ` ${
|
|
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(`${
|
|
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(`${
|
|
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(
|
|
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(
|
|
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(
|
|
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 "${
|
|
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 ${
|
|
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(
|
|
89
|
+
log(styleText(['bold', 'magenta'], 'Stack destruction started!'));
|
|
90
90
|
return { success: true };
|
|
91
91
|
}
|
|
92
|
-
log(
|
|
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(
|
|
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(
|
|
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(
|
|
170
|
+
log(styleText(['bold', 'green'], 'All checks passed'));
|
|
171
171
|
if (fix)
|
|
172
|
-
log(
|
|
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(`${
|
|
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(`${
|
|
167
|
-
log(`\n Run "${
|
|
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(`${
|
|
274
|
+
log(check(`${styleText('bold', 'New folder created:')} ${userProvidedDirName}/`));
|
|
275
275
|
}
|
|
276
276
|
const displayPath = userProvidedDirName || '.';
|
|
277
|
-
log(check(`${
|
|
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(`${
|
|
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(`${
|
|
285
|
+
log(check(`${styleText('bold', 'Added .gitignore:')} ${displayPath}/.gitignore`));
|
|
286
286
|
}
|
|
287
287
|
else if (gitignoreResult.action === 'updated') {
|
|
288
|
-
log(check(`${
|
|
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(`${
|
|
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 "${
|
|
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(`${
|
|
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(`${
|
|
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 ${
|
|
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(`${
|
|
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(
|
|
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 "${
|
|
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(`${
|
|
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(`${
|
|
64
|
+
log(check(`${styleText('bold', 'Created:')} ${newDir}/${filePath}`));
|
|
65
65
|
}
|
|
66
66
|
if (functionConfig) {
|
|
67
67
|
log('');
|
|
68
|
-
log(
|
|
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: "${
|
|
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 "${
|
|
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(`${
|
|
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${
|
|
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 "${
|
|
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(`${
|
|
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(`${
|
|
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 ${
|
|
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 ${
|
|
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(`${
|
|
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... ${
|
|
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(`${
|
|
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(`${
|
|
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(`${
|
|
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 ${
|
|
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 ${
|
|
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
|
-
|
|
110
|
-
|
|
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
|
|
117
|
+
return styleText('red', level);
|
|
118
118
|
if (level === 'WARN')
|
|
119
|
-
return
|
|
120
|
-
return
|
|
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 = [
|
|
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(
|
|
63
|
+
nameParts.push(styleText('green', `"${displayName}"`));
|
|
64
64
|
return nameParts.join(' ');
|
|
65
65
|
}
|
|
66
66
|
function deployedResourceName(res, displayNameAttribute, _verbose = false) {
|
|
67
|
-
const nameParts = [
|
|
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(
|
|
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 `${
|
|
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 = [
|
|
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(`${
|
|
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(`${
|
|
131
|
+
children.push(`${styleText('bold', 'Other Resources')} [${categorized['Other Resources'].length}]`);
|
|
130
132
|
const otherResourcesOutput = categorized['Other Resources'].map((other) => {
|
|
131
|
-
return `${
|
|
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 =
|
|
157
|
+
let stackName = styleText('bold', `"${stack.name}"`);
|
|
156
158
|
if (isCurrentStack)
|
|
157
|
-
stackName = `${
|
|
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' ?
|
|
185
|
+
const operationColor = operation.status === 'COMPLETED' ? 'green' : 'red';
|
|
184
186
|
const status = operation.status || 'UNKNOWN';
|
|
185
|
-
operationOutput.push(`Status: ${operationColor
|
|
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: ${
|
|
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(` ${
|
|
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(` ${
|
|
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
|
|
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 ? `${
|
|
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(`${
|
|
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
|
|
2
|
+
import { styleText } from '../style-text.js';
|
|
3
3
|
export function check(str) {
|
|
4
|
-
return `${
|
|
4
|
+
return `${styleText('bold', styleText('green', '✔︎'))} ${str}`;
|
|
5
5
|
}
|
|
6
6
|
export function info(str) {
|
|
7
|
-
return `${
|
|
7
|
+
return `${styleText(['bold', 'blue'], 'ℹ︎')} ${str}`;
|
|
8
8
|
}
|
|
9
9
|
export function warn(str) {
|
|
10
|
-
return `${
|
|
10
|
+
return `${styleText(['bold', 'yellow'], '▶︎')} ${str}`;
|
|
11
11
|
}
|
|
12
12
|
export function unsure(str) {
|
|
13
|
-
return `${
|
|
13
|
+
return `${styleText(['bold', 'cyan'], '?')} ${str}`;
|
|
14
14
|
}
|
|
15
15
|
export function severe(str) {
|
|
16
|
-
return `${
|
|
16
|
+
return `${styleText(['bold', 'red'], '✘')} ${str}`;
|
|
17
17
|
}
|
|
18
18
|
export function niceId(id) {
|
|
19
19
|
if (!id)
|
|
20
20
|
return '';
|
|
21
|
-
return `<${
|
|
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 `${
|
|
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(
|
|
95
|
-
stackChoices.push({ name:
|
|
96
|
-
stackChoices.push(new Separator(
|
|
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)} ${
|
|
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
|
|
4
|
+
return styleText('dim', `${label}:`);
|
|
5
5
|
}
|
|
6
6
|
function formatLabeledValue(label, value) {
|
|
7
|
-
return `${
|
|
7
|
+
return `${styleText('dim', `${label}:`)} ${value}`;
|
|
8
8
|
}
|
|
9
9
|
function arrayifyEvent(event) {
|
|
10
10
|
if (!event)
|
|
@@ -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
|
|
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' ? '←' :
|
|
182
|
-
logger.trace(`${
|
|
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);
|
package/oclif.manifest.json
CHANGED
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.
|
|
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.
|
|
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",
|