@sanity/runtime-cli 14.13.0 → 14.13.1
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 +24 -23
- package/dist/actions/blueprints/logs-polling.d.ts +20 -0
- package/dist/actions/blueprints/logs-polling.js +48 -0
- package/dist/actions/blueprints/logs.d.ts +7 -1
- package/dist/actions/blueprints/logs.js +9 -2
- package/dist/actions/blueprints/stacks.d.ts +6 -2
- package/dist/commands/blueprints/add.d.ts +4 -1
- package/dist/commands/blueprints/add.js +11 -14
- package/dist/cores/blueprints/deploy.js +3 -4
- package/dist/cores/blueprints/destroy.js +11 -9
- package/dist/cores/blueprints/logs.js +7 -6
- package/dist/utils/display/resources-formatting.js +7 -5
- package/oclif.manifest.json +7 -3
- package/package.json +3 -1
- package/dist/actions/blueprints/logs-streaming.d.ts +0 -30
- package/dist/actions/blueprints/logs-streaming.js +0 -107
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/14.13.
|
|
23
|
+
@sanity/runtime-cli/14.13.1 linux-x64 node-v24.14.1
|
|
24
24
|
$ sanity-run --help [COMMAND]
|
|
25
25
|
USAGE
|
|
26
26
|
$ sanity-run COMMAND
|
|
@@ -50,7 +50,7 @@ USAGE
|
|
|
50
50
|
|
|
51
51
|
## `sanity-run blueprints add TYPE`
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
[deprecated] Use "functions add" instead
|
|
54
54
|
|
|
55
55
|
```
|
|
56
56
|
USAGE
|
|
@@ -82,12 +82,13 @@ FLAGS
|
|
|
82
82
|
--[no-]validate-resources Validate resources
|
|
83
83
|
|
|
84
84
|
DESCRIPTION
|
|
85
|
-
|
|
85
|
+
[deprecated] Use "functions add" instead
|
|
86
86
|
|
|
87
|
-
|
|
88
|
-
(create, update, delete, publish) or media library events.
|
|
87
|
+
This command is deprecated. Use "functions add" instead.
|
|
89
88
|
|
|
90
|
-
|
|
89
|
+
Equivalent usage:
|
|
90
|
+
$ sanity-run functions add
|
|
91
|
+
$ sanity-run functions add --name my-function --type document-create
|
|
91
92
|
|
|
92
93
|
EXAMPLES
|
|
93
94
|
$ sanity-run blueprints add function
|
|
@@ -101,7 +102,7 @@ EXAMPLES
|
|
|
101
102
|
$ sanity-run blueprints add function --name my-function --fn-type document-create --fn-type document-update --lang js
|
|
102
103
|
```
|
|
103
104
|
|
|
104
|
-
_See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.
|
|
105
|
+
_See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.1/src/commands/blueprints/add.ts)_
|
|
105
106
|
|
|
106
107
|
## `sanity-run blueprints config`
|
|
107
108
|
|
|
@@ -140,7 +141,7 @@ EXAMPLES
|
|
|
140
141
|
$ sanity-run blueprints config --edit --project-id <projectId> --stack <name-or-id>
|
|
141
142
|
```
|
|
142
143
|
|
|
143
|
-
_See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.
|
|
144
|
+
_See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.1/src/commands/blueprints/config.ts)_
|
|
144
145
|
|
|
145
146
|
## `sanity-run blueprints deploy`
|
|
146
147
|
|
|
@@ -182,7 +183,7 @@ EXAMPLES
|
|
|
182
183
|
$ sanity-run blueprints deploy --fn-installer npm
|
|
183
184
|
```
|
|
184
185
|
|
|
185
|
-
_See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.
|
|
186
|
+
_See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.1/src/commands/blueprints/deploy.ts)_
|
|
186
187
|
|
|
187
188
|
## `sanity-run blueprints destroy`
|
|
188
189
|
|
|
@@ -218,7 +219,7 @@ EXAMPLES
|
|
|
218
219
|
$ sanity-run blueprints destroy --stack <name-or-id> --project-id <projectId> --force --no-wait
|
|
219
220
|
```
|
|
220
221
|
|
|
221
|
-
_See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.
|
|
222
|
+
_See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.1/src/commands/blueprints/destroy.ts)_
|
|
222
223
|
|
|
223
224
|
## `sanity-run blueprints doctor`
|
|
224
225
|
|
|
@@ -250,7 +251,7 @@ EXAMPLES
|
|
|
250
251
|
$ sanity-run blueprints doctor --fix
|
|
251
252
|
```
|
|
252
253
|
|
|
253
|
-
_See code: [src/commands/blueprints/doctor.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.
|
|
254
|
+
_See code: [src/commands/blueprints/doctor.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.1/src/commands/blueprints/doctor.ts)_
|
|
254
255
|
|
|
255
256
|
## `sanity-run blueprints info`
|
|
256
257
|
|
|
@@ -285,7 +286,7 @@ EXAMPLES
|
|
|
285
286
|
$ sanity-run blueprints info --project-id <id> --stack <name-or-id>
|
|
286
287
|
```
|
|
287
288
|
|
|
288
|
-
_See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.
|
|
289
|
+
_See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.1/src/commands/blueprints/info.ts)_
|
|
289
290
|
|
|
290
291
|
## `sanity-run blueprints init [DIR]`
|
|
291
292
|
|
|
@@ -338,7 +339,7 @@ EXAMPLES
|
|
|
338
339
|
$ sanity-run blueprints init --blueprint-type <json|js|ts> --stack-name <stackName>
|
|
339
340
|
```
|
|
340
341
|
|
|
341
|
-
_See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.
|
|
342
|
+
_See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.1/src/commands/blueprints/init.ts)_
|
|
342
343
|
|
|
343
344
|
## `sanity-run blueprints logs`
|
|
344
345
|
|
|
@@ -369,7 +370,7 @@ EXAMPLES
|
|
|
369
370
|
$ sanity-run blueprints logs --watch
|
|
370
371
|
```
|
|
371
372
|
|
|
372
|
-
_See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.
|
|
373
|
+
_See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.1/src/commands/blueprints/logs.ts)_
|
|
373
374
|
|
|
374
375
|
## `sanity-run blueprints plan`
|
|
375
376
|
|
|
@@ -397,7 +398,7 @@ EXAMPLES
|
|
|
397
398
|
$ sanity-run blueprints plan
|
|
398
399
|
```
|
|
399
400
|
|
|
400
|
-
_See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.
|
|
401
|
+
_See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.1/src/commands/blueprints/plan.ts)_
|
|
401
402
|
|
|
402
403
|
## `sanity-run blueprints stacks`
|
|
403
404
|
|
|
@@ -435,7 +436,7 @@ EXAMPLES
|
|
|
435
436
|
$ sanity-run blueprints stacks --organization-id <organizationId> --include-projects
|
|
436
437
|
```
|
|
437
438
|
|
|
438
|
-
_See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.
|
|
439
|
+
_See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.1/src/commands/blueprints/stacks.ts)_
|
|
439
440
|
|
|
440
441
|
## `sanity-run functions add`
|
|
441
442
|
|
|
@@ -488,7 +489,7 @@ EXAMPLES
|
|
|
488
489
|
$ sanity-run functions add --name my-function --type document-create --type document-update --lang js
|
|
489
490
|
```
|
|
490
491
|
|
|
491
|
-
_See code: [src/commands/functions/add.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.
|
|
492
|
+
_See code: [src/commands/functions/add.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.1/src/commands/functions/add.ts)_
|
|
492
493
|
|
|
493
494
|
## `sanity-run functions dev`
|
|
494
495
|
|
|
@@ -524,7 +525,7 @@ EXAMPLES
|
|
|
524
525
|
$ sanity-run functions dev --timeout 60
|
|
525
526
|
```
|
|
526
527
|
|
|
527
|
-
_See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.
|
|
528
|
+
_See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.1/src/commands/functions/dev.ts)_
|
|
528
529
|
|
|
529
530
|
## `sanity-run functions env add NAME KEY VALUE`
|
|
530
531
|
|
|
@@ -555,7 +556,7 @@ EXAMPLES
|
|
|
555
556
|
$ sanity-run functions env add MyFunction API_URL https://api.example.com/
|
|
556
557
|
```
|
|
557
558
|
|
|
558
|
-
_See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.
|
|
559
|
+
_See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.1/src/commands/functions/env/add.ts)_
|
|
559
560
|
|
|
560
561
|
## `sanity-run functions env list NAME`
|
|
561
562
|
|
|
@@ -583,7 +584,7 @@ EXAMPLES
|
|
|
583
584
|
$ sanity-run functions env list MyFunction
|
|
584
585
|
```
|
|
585
586
|
|
|
586
|
-
_See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.
|
|
587
|
+
_See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.1/src/commands/functions/env/list.ts)_
|
|
587
588
|
|
|
588
589
|
## `sanity-run functions env remove NAME KEY`
|
|
589
590
|
|
|
@@ -613,7 +614,7 @@ EXAMPLES
|
|
|
613
614
|
$ sanity-run functions env remove MyFunction API_URL
|
|
614
615
|
```
|
|
615
616
|
|
|
616
|
-
_See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.
|
|
617
|
+
_See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.1/src/commands/functions/env/remove.ts)_
|
|
617
618
|
|
|
618
619
|
## `sanity-run functions logs [NAME]`
|
|
619
620
|
|
|
@@ -655,7 +656,7 @@ EXAMPLES
|
|
|
655
656
|
$ sanity-run functions logs <name> --delete
|
|
656
657
|
```
|
|
657
658
|
|
|
658
|
-
_See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.
|
|
659
|
+
_See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.1/src/commands/functions/logs.ts)_
|
|
659
660
|
|
|
660
661
|
## `sanity-run functions test [NAME]`
|
|
661
662
|
|
|
@@ -713,7 +714,7 @@ EXAMPLES
|
|
|
713
714
|
$ sanity-run functions test <name> --event update --data-before '{ "title": "before" }' --data-after '{ "title": "after" }'
|
|
714
715
|
```
|
|
715
716
|
|
|
716
|
-
_See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.
|
|
717
|
+
_See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v14.13.1/src/commands/functions/test.ts)_
|
|
717
718
|
|
|
718
719
|
## `sanity-run help [COMMAND]`
|
|
719
720
|
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Logger } from '../../utils/logger.js';
|
|
2
|
+
import type { AuthParams, BlueprintLog } from '../../utils/types.js';
|
|
3
|
+
export declare const LOG_POLL_INTERVAL_MS = 725;
|
|
4
|
+
export interface LogPollingConfig {
|
|
5
|
+
stackId: string;
|
|
6
|
+
operationId?: string;
|
|
7
|
+
knownIds?: string[];
|
|
8
|
+
auth: AuthParams;
|
|
9
|
+
showBanner?: boolean;
|
|
10
|
+
verbose?: boolean;
|
|
11
|
+
log: Logger;
|
|
12
|
+
onActivity?: () => void;
|
|
13
|
+
onLogEntry?: (log: BlueprintLog) => void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Polls the logs list endpoint at a fixed interval and displays new entries.
|
|
17
|
+
* Deduplicates by log ID so no dependency on server timestamps.
|
|
18
|
+
* @returns A cleanup function that stops polling
|
|
19
|
+
*/
|
|
20
|
+
export declare function setupLogPolling(config: LogPollingConfig): () => void;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { formatLogEntry } from '../../utils/display/logs-formatting.js';
|
|
2
|
+
import { styleText } from '../../utils/style-text.js';
|
|
3
|
+
import { getLogs } from './logs.js';
|
|
4
|
+
export const LOG_POLL_INTERVAL_MS = 725;
|
|
5
|
+
/**
|
|
6
|
+
* Polls the logs list endpoint at a fixed interval and displays new entries.
|
|
7
|
+
* Deduplicates by log ID so no dependency on server timestamps.
|
|
8
|
+
* @returns A cleanup function that stops polling
|
|
9
|
+
*/
|
|
10
|
+
export function setupLogPolling(config) {
|
|
11
|
+
const { stackId, operationId, auth, log, showBanner, verbose = false } = config;
|
|
12
|
+
const seenIds = new Set(config.knownIds);
|
|
13
|
+
let previousLog;
|
|
14
|
+
let stopped = false;
|
|
15
|
+
if (showBanner) {
|
|
16
|
+
log(`Watching logs... ${styleText('bold', 'ctrl+c')} to cancel`);
|
|
17
|
+
}
|
|
18
|
+
const fetchAndProcessLogs = async () => {
|
|
19
|
+
if (stopped)
|
|
20
|
+
return;
|
|
21
|
+
try {
|
|
22
|
+
const params = operationId ? { operationId } : { stackId };
|
|
23
|
+
const { ok, logs } = await getLogs(params, auth, log);
|
|
24
|
+
if (!ok || stopped)
|
|
25
|
+
return;
|
|
26
|
+
// API returns newest first; reverse so we display in chronological order
|
|
27
|
+
const newLogs = logs.filter((entry) => !seenIds.has(entry.id)).reverse();
|
|
28
|
+
for (const logEntry of newLogs) {
|
|
29
|
+
seenIds.add(logEntry.id);
|
|
30
|
+
config.onActivity?.();
|
|
31
|
+
config.onLogEntry?.(logEntry);
|
|
32
|
+
log(formatLogEntry(logEntry, verbose, previousLog));
|
|
33
|
+
previousLog = logEntry;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// Swallow fetch errors; the operation status poll in callers handles terminal failure.
|
|
38
|
+
// Logging noise here is not useful.
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
// Fire immediately, then on interval
|
|
42
|
+
fetchAndProcessLogs();
|
|
43
|
+
const intervalId = setInterval(fetchAndProcessLogs, LOG_POLL_INTERVAL_MS);
|
|
44
|
+
return () => {
|
|
45
|
+
stopped = true;
|
|
46
|
+
clearInterval(intervalId);
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import type { Logger } from '../../utils/logger.js';
|
|
2
2
|
import type { ActionResponse, AuthParams, BlueprintLog } from '../../utils/types.js';
|
|
3
3
|
export declare const logsUrl: string;
|
|
4
|
-
export
|
|
4
|
+
export interface GetLogsParams {
|
|
5
|
+
stackId?: string;
|
|
6
|
+
operationId?: string;
|
|
7
|
+
limit?: number;
|
|
8
|
+
before?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function getLogs(params: GetLogsParams, auth: AuthParams, logger: Logger): Promise<ActionResponse & {
|
|
5
11
|
logs: BlueprintLog[];
|
|
6
12
|
}>;
|
|
7
13
|
export declare function getRecentLogs(logs: BlueprintLog[], limit?: number): BlueprintLog[];
|
|
@@ -3,10 +3,17 @@ import getHeaders from '../../utils/get-headers.js';
|
|
|
3
3
|
import { createTracedFetch } from '../../utils/traced-fetch.js';
|
|
4
4
|
const { apiUrl } = config;
|
|
5
5
|
export const logsUrl = `${apiUrl}vX/blueprints/logs`;
|
|
6
|
-
export async function getLogs(
|
|
6
|
+
export async function getLogs(params, auth, logger) {
|
|
7
7
|
const fetchFn = createTracedFetch(logger);
|
|
8
8
|
const url = new URL(logsUrl);
|
|
9
|
-
|
|
9
|
+
if (params.stackId)
|
|
10
|
+
url.searchParams.append('stackId', params.stackId);
|
|
11
|
+
if (params.operationId)
|
|
12
|
+
url.searchParams.append('operationId', params.operationId);
|
|
13
|
+
if (params.limit)
|
|
14
|
+
url.searchParams.append('limit', String(params.limit));
|
|
15
|
+
if (params.before)
|
|
16
|
+
url.searchParams.append('before', params.before);
|
|
10
17
|
const response = await fetchFn(url.toString(), {
|
|
11
18
|
headers: getHeaders(auth),
|
|
12
19
|
method: 'GET',
|
|
@@ -37,7 +37,9 @@ export declare function createEmptyStack({ token, scopeType, scopeId, name, logg
|
|
|
37
37
|
logger: Logger;
|
|
38
38
|
}): Promise<Stack>;
|
|
39
39
|
interface UpdateStackResponse extends ActionResponse {
|
|
40
|
-
stack: Stack
|
|
40
|
+
stack: Stack & {
|
|
41
|
+
operationId?: string;
|
|
42
|
+
};
|
|
41
43
|
}
|
|
42
44
|
export declare function updateStack({ stackId, stackMutation, auth, logger, }: {
|
|
43
45
|
stackId: string;
|
|
@@ -96,7 +98,9 @@ export declare function planStack({ stackId, document, auth, logger, }: {
|
|
|
96
98
|
logger: Logger;
|
|
97
99
|
}): Promise<PlanStackResponse>;
|
|
98
100
|
interface DestroyStackResponse extends ActionResponse {
|
|
99
|
-
stack: Stack
|
|
101
|
+
stack: Stack & {
|
|
102
|
+
operationId?: string;
|
|
103
|
+
};
|
|
100
104
|
}
|
|
101
105
|
export declare function resolveStackIdByNameOrId(value: string, auth: AuthParams, logger: Logger): Promise<string>;
|
|
102
106
|
interface PromoteStackResponse extends ActionResponse {
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file
|
|
3
3
|
* @deprecated Use `functions add` instead.
|
|
4
|
-
* We're in the process of deprecating the `blueprints add` command.
|
|
5
4
|
*/
|
|
6
5
|
import { ResolvedCommand } from '../../baseCommands.js';
|
|
7
6
|
export default class AddCommand extends ResolvedCommand<typeof AddCommand> {
|
|
8
7
|
static needs: readonly ["blueprint"];
|
|
8
|
+
static state: string;
|
|
9
|
+
static deprecationOptions: {
|
|
10
|
+
to: string;
|
|
11
|
+
};
|
|
9
12
|
static summary: string;
|
|
10
13
|
static description: string;
|
|
11
14
|
static examples: string[];
|
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file
|
|
3
3
|
* @deprecated Use `functions add` instead.
|
|
4
|
-
* We're in the process of deprecating the `blueprints add` command.
|
|
5
4
|
*/
|
|
6
5
|
import { Args, Flags } from '@oclif/core';
|
|
7
6
|
import { ResolvedCommand } from '../../baseCommands.js';
|
|
8
7
|
import { FUNCTION_TYPES } from '../../constants.js';
|
|
9
8
|
import { functionAddCore } from '../../cores/functions/index.js';
|
|
9
|
+
import { warn } from '../../utils/display/presenters.js';
|
|
10
10
|
import { Logger } from '../../utils/logger.js';
|
|
11
11
|
import { INSTALLER_OPTIONS } from '../../utils/types.js';
|
|
12
|
-
// import {warn} from '../../utils/display/presenters.js'
|
|
13
12
|
export default class AddCommand extends ResolvedCommand {
|
|
14
13
|
static needs = ['blueprint'];
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
static summary = '
|
|
20
|
-
static description = `
|
|
14
|
+
static state = 'deprecated';
|
|
15
|
+
static deprecationOptions = {
|
|
16
|
+
to: 'functions add',
|
|
17
|
+
};
|
|
18
|
+
static summary = '[deprecated] Use "functions add" instead';
|
|
19
|
+
static description = `This command is deprecated. Use "functions add" instead.
|
|
21
20
|
|
|
22
|
-
|
|
21
|
+
Equivalent usage:
|
|
22
|
+
$ <%= config.bin %> functions add
|
|
23
|
+
$ <%= config.bin %> functions add --name my-function --type document-create`;
|
|
23
24
|
static examples = [
|
|
24
25
|
'<%= config.bin %> <%= command.id %> function',
|
|
25
26
|
'<%= config.bin %> <%= command.id %> function --helpers',
|
|
@@ -84,11 +85,7 @@ After adding a function, use 'functions dev' to test locally, then 'blueprints d
|
|
|
84
85
|
if (resourceType !== 'function') {
|
|
85
86
|
this.error(`Unsupported Resource type: ${resourceType}`);
|
|
86
87
|
}
|
|
87
|
-
|
|
88
|
-
// warn(
|
|
89
|
-
// `\`npx ${bin} blueprints add function\` is deprecated. Use \`npx ${bin} functions add\` instead.`,
|
|
90
|
-
// ),
|
|
91
|
-
// )
|
|
88
|
+
this.log(warn(`"${bin} blueprints add" is deprecated and will be removed in a future release. Use "${bin} functions add" instead.`));
|
|
92
89
|
const result = await functionAddCore({
|
|
93
90
|
bin,
|
|
94
91
|
log: Logger(this.log.bind(this), this.flags),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { setTimeout as sleep } from 'node:timers/promises';
|
|
2
2
|
import { stashAsset } from '../../actions/blueprints/assets.js';
|
|
3
|
-
import {
|
|
3
|
+
import { setupLogPolling } from '../../actions/blueprints/logs-polling.js';
|
|
4
4
|
import { getStack, updateStack } from '../../actions/blueprints/stacks.js';
|
|
5
5
|
import { createLogHintCollector } from '../../utils/blueprints/log-hints.js';
|
|
6
6
|
import { niceId } from '../../utils/display/presenters.js';
|
|
@@ -47,7 +47,6 @@ export async function blueprintDeployCore(options) {
|
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
49
|
const spinner = log.ora('Deploying...').start();
|
|
50
|
-
const isoNow = new Date().toISOString();
|
|
51
50
|
const { ok: deployOk, stack, error: deployError, } = await updateStack({
|
|
52
51
|
stackId,
|
|
53
52
|
stackMutation: {
|
|
@@ -87,9 +86,9 @@ export async function blueprintDeployCore(options) {
|
|
|
87
86
|
try {
|
|
88
87
|
let lastLogAt = Date.now();
|
|
89
88
|
let idleMessageShown = false;
|
|
90
|
-
logStreamCleanup =
|
|
89
|
+
logStreamCleanup = setupLogPolling({
|
|
91
90
|
stackId: stack.id,
|
|
92
|
-
|
|
91
|
+
operationId: stack.operationId,
|
|
93
92
|
auth,
|
|
94
93
|
log,
|
|
95
94
|
verbose,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { setTimeout as sleep } from 'node:timers/promises';
|
|
2
2
|
import { confirm } from '@inquirer/prompts';
|
|
3
|
-
import {
|
|
3
|
+
import { setupLogPolling } from '../../actions/blueprints/logs-polling.js';
|
|
4
4
|
import { destroyStack, getStack, resolveStackIdByNameOrId } from '../../actions/blueprints/stacks.js';
|
|
5
5
|
import { createLogHintCollector } from '../../utils/blueprints/log-hints.js';
|
|
6
6
|
import { niceId } from '../../utils/display/presenters.js';
|
|
@@ -25,7 +25,6 @@ export async function blueprintDestroyCore(options) {
|
|
|
25
25
|
}
|
|
26
26
|
const auth = { token, scopeType, scopeId };
|
|
27
27
|
const resolvedId = await resolveStackIdByNameOrId(flagStack, auth, log);
|
|
28
|
-
const isoNow = new Date().toISOString();
|
|
29
28
|
const { ok, error, stack } = await destroyStack({
|
|
30
29
|
stackId: resolvedId,
|
|
31
30
|
auth,
|
|
@@ -40,10 +39,10 @@ export async function blueprintDestroyCore(options) {
|
|
|
40
39
|
return waitForDestruction({
|
|
41
40
|
stackId: stack.id,
|
|
42
41
|
stackName: stack.name,
|
|
42
|
+
operationId: stack.operationId,
|
|
43
43
|
auth,
|
|
44
44
|
log,
|
|
45
45
|
bin,
|
|
46
|
-
since: isoNow,
|
|
47
46
|
});
|
|
48
47
|
}
|
|
49
48
|
const { scopeType, scopeId, stackId } = blueprint;
|
|
@@ -103,8 +102,11 @@ export async function blueprintDestroyCore(options) {
|
|
|
103
102
|
else {
|
|
104
103
|
destroySpinner.start();
|
|
105
104
|
}
|
|
106
|
-
const
|
|
107
|
-
|
|
105
|
+
const { ok, error, stack: destroyedStack, } = await destroyStack({
|
|
106
|
+
stackId: stack.id,
|
|
107
|
+
auth,
|
|
108
|
+
logger: log,
|
|
109
|
+
});
|
|
108
110
|
if (!ok) {
|
|
109
111
|
destroySpinner.fail('Failed to destroy Stack deployment');
|
|
110
112
|
return { success: false, error: error || 'Failed to destroy Stack deployment' };
|
|
@@ -117,10 +119,10 @@ export async function blueprintDestroyCore(options) {
|
|
|
117
119
|
return waitForDestruction({
|
|
118
120
|
stackId: stack.id,
|
|
119
121
|
stackName: stack.name,
|
|
122
|
+
operationId: destroyedStack.operationId,
|
|
120
123
|
auth,
|
|
121
124
|
log,
|
|
122
125
|
bin,
|
|
123
|
-
since: isoNow,
|
|
124
126
|
});
|
|
125
127
|
}
|
|
126
128
|
catch (error) {
|
|
@@ -129,16 +131,16 @@ export async function blueprintDestroyCore(options) {
|
|
|
129
131
|
}
|
|
130
132
|
}
|
|
131
133
|
async function waitForDestruction(options) {
|
|
132
|
-
const { stackId, stackName, auth, log, bin
|
|
134
|
+
const { stackId, stackName, operationId, auth, log, bin } = options;
|
|
133
135
|
log(styleText('dim', 'Stack destruction progress:'));
|
|
134
136
|
const logHints = createLogHintCollector(bin);
|
|
135
137
|
let logStreamCleanup = null;
|
|
136
138
|
try {
|
|
137
139
|
let lastLogAt = Date.now();
|
|
138
140
|
let idleMessageShown = false;
|
|
139
|
-
logStreamCleanup =
|
|
141
|
+
logStreamCleanup = setupLogPolling({
|
|
140
142
|
stackId,
|
|
141
|
-
|
|
143
|
+
operationId,
|
|
142
144
|
auth,
|
|
143
145
|
log,
|
|
144
146
|
onActivity: () => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getLogs, getRecentLogs } from '../../actions/blueprints/logs.js';
|
|
2
|
-
import {
|
|
2
|
+
import { setupLogPolling } from '../../actions/blueprints/logs-polling.js';
|
|
3
3
|
import { formatTitle } from '../../utils/display/blueprints-formatting.js';
|
|
4
4
|
import { formatLogEntry, formatLogs } from '../../utils/display/logs-formatting.js';
|
|
5
5
|
import { niceId } from '../../utils/display/presenters.js';
|
|
@@ -10,7 +10,7 @@ export async function blueprintLogsCore(options) {
|
|
|
10
10
|
const spinner = log.ora(`Fetching recent logs for Stack deployment ${niceId(stackId)}`).start();
|
|
11
11
|
try {
|
|
12
12
|
if (watch) {
|
|
13
|
-
const { ok, logs, error } = await getLogs(stackId, auth, log);
|
|
13
|
+
const { ok, logs, error } = await getLogs({ stackId }, auth, log);
|
|
14
14
|
if (!ok) {
|
|
15
15
|
spinner.fail(`${styleText('red', 'Failed')} to retrieve logs`);
|
|
16
16
|
log.error(`Error: ${error || 'Unknown error'}`);
|
|
@@ -30,22 +30,23 @@ export async function blueprintLogsCore(options) {
|
|
|
30
30
|
else {
|
|
31
31
|
log(`No recent logs found for Stack deployment ${niceId(stackId)}`);
|
|
32
32
|
}
|
|
33
|
-
// Set up
|
|
34
|
-
|
|
33
|
+
// Set up polling log display, seeding with already-displayed log IDs
|
|
34
|
+
setupLogPolling({
|
|
35
35
|
stackId,
|
|
36
|
+
knownIds: logs.map((l) => l.id),
|
|
36
37
|
auth,
|
|
37
38
|
log,
|
|
38
39
|
showBanner: true,
|
|
39
40
|
verbose,
|
|
40
41
|
});
|
|
41
|
-
// Return a special key for
|
|
42
|
+
// Return a special key for polling mode
|
|
42
43
|
return {
|
|
43
44
|
success: true,
|
|
44
45
|
streaming: new Promise(() => { }),
|
|
45
46
|
};
|
|
46
47
|
}
|
|
47
48
|
// Regular non-streaming logs
|
|
48
|
-
const { ok, logs, error } = await getLogs(stackId, auth, log);
|
|
49
|
+
const { ok, logs, error } = await getLogs({ stackId }, auth, log);
|
|
49
50
|
if (!ok) {
|
|
50
51
|
spinner.fail(`${styleText('red', 'Failed')} to retrieve Stack deployment logs`);
|
|
51
52
|
log.error(`Error: ${error || 'Unknown error'}`);
|
|
@@ -28,11 +28,13 @@ function arrayifyEvent(event) {
|
|
|
28
28
|
if ('projection' in event && event.projection) {
|
|
29
29
|
details.push(formatLabeledValue('projection', event.projection));
|
|
30
30
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
if (event.resource) {
|
|
32
|
+
details.push(formatLabel('resource'));
|
|
33
|
+
details.push([
|
|
34
|
+
formatLabeledValue('type', event.resource.type),
|
|
35
|
+
formatLabeledValue('id', event.resource.id),
|
|
36
|
+
]);
|
|
37
|
+
}
|
|
36
38
|
}
|
|
37
39
|
return details;
|
|
38
40
|
}
|
package/oclif.manifest.json
CHANGED
|
@@ -12,7 +12,10 @@
|
|
|
12
12
|
"required": true
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
|
-
"
|
|
15
|
+
"deprecationOptions": {
|
|
16
|
+
"to": "functions add"
|
|
17
|
+
},
|
|
18
|
+
"description": "This command is deprecated. Use \"functions add\" instead.\n\nEquivalent usage:\n $ <%= config.bin %> functions add\n $ <%= config.bin %> functions add --name my-function --type document-create",
|
|
16
19
|
"examples": [
|
|
17
20
|
"<%= config.bin %> <%= command.id %> function",
|
|
18
21
|
"<%= config.bin %> <%= command.id %> function --helpers",
|
|
@@ -216,8 +219,9 @@
|
|
|
216
219
|
"pluginAlias": "@sanity/runtime-cli",
|
|
217
220
|
"pluginName": "@sanity/runtime-cli",
|
|
218
221
|
"pluginType": "core",
|
|
222
|
+
"state": "deprecated",
|
|
219
223
|
"strict": true,
|
|
220
|
-
"summary": "
|
|
224
|
+
"summary": "[deprecated] Use \"functions add\" instead",
|
|
221
225
|
"enableJsonFlag": true,
|
|
222
226
|
"needs": [
|
|
223
227
|
"blueprint"
|
|
@@ -2688,5 +2692,5 @@
|
|
|
2688
2692
|
]
|
|
2689
2693
|
}
|
|
2690
2694
|
},
|
|
2691
|
-
"version": "14.13.
|
|
2695
|
+
"version": "14.13.1"
|
|
2692
2696
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/runtime-cli",
|
|
3
3
|
"description": "Sanity's Runtime CLI for Blueprints and Functions",
|
|
4
|
-
"version": "14.13.
|
|
4
|
+
"version": "14.13.1",
|
|
5
5
|
"author": "Sanity Runtime Team",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|
|
@@ -94,6 +94,7 @@
|
|
|
94
94
|
"test:api": "cd test/api-types && npm it",
|
|
95
95
|
"test:depmgmt": "vitest run --config ./test-depmgmt/vitest.config.ts",
|
|
96
96
|
"test:vitest": "vitest run",
|
|
97
|
+
"test:coverage": "npm run test:vitest -- --coverage --coverage.include \"runtime-cli/src/**/*\"",
|
|
97
98
|
"typecheck": "tsc --project tsconfig.typecheck.json",
|
|
98
99
|
"watch": "tsc --watch"
|
|
99
100
|
},
|
|
@@ -137,6 +138,7 @@
|
|
|
137
138
|
"@types/node": "20",
|
|
138
139
|
"@types/tar-stream": "^3.1.4",
|
|
139
140
|
"@types/ws": "^8.18.1",
|
|
141
|
+
"@vitest/coverage-v8": "^4.1.0",
|
|
140
142
|
"codemirror": "^6.0.2",
|
|
141
143
|
"mentoss": "^0.13.0",
|
|
142
144
|
"oclif": "^4.22.92",
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import type { Logger } from '../../utils/logger.js';
|
|
2
|
-
import type { AuthParams, BlueprintLog } from '../../utils/types.js';
|
|
3
|
-
export interface LogStreamingConfig {
|
|
4
|
-
stackId: string;
|
|
5
|
-
after?: string;
|
|
6
|
-
auth: AuthParams;
|
|
7
|
-
showBanner?: boolean;
|
|
8
|
-
verbose?: boolean;
|
|
9
|
-
log: Logger;
|
|
10
|
-
onActivity?: () => void;
|
|
11
|
-
onLogEntry?: (log: BlueprintLog) => void;
|
|
12
|
-
}
|
|
13
|
-
export interface StreamLogsOptions {
|
|
14
|
-
stackId: string;
|
|
15
|
-
after?: string;
|
|
16
|
-
auth: AuthParams;
|
|
17
|
-
onLog: (log: BlueprintLog) => void;
|
|
18
|
-
onOpen: () => void;
|
|
19
|
-
onError: (error: string) => void;
|
|
20
|
-
logger: Logger;
|
|
21
|
-
}
|
|
22
|
-
export declare function streamLogs({ stackId, after, auth, onLog, onOpen, onError, logger, }: StreamLogsOptions): () => void;
|
|
23
|
-
/** Check if a log is newer than a given timestamp */
|
|
24
|
-
export declare function isNewerLog(log: BlueprintLog, timestamp: number): boolean;
|
|
25
|
-
/**
|
|
26
|
-
* Sets up log streaming for operations like deploy or destroy with spinner integration
|
|
27
|
-
* @param config Configuration for log streaming
|
|
28
|
-
* @returns A cleanup function for closing the log stream
|
|
29
|
-
*/
|
|
30
|
-
export declare function setupLogStreaming(config: LogStreamingConfig): Promise<() => void>;
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import { EventSource } from 'eventsource';
|
|
2
|
-
import { formatLogEntry } from '../../utils/display/logs-formatting.js';
|
|
3
|
-
import getHeaders from '../../utils/get-headers.js';
|
|
4
|
-
import { styleText } from '../../utils/style-text.js';
|
|
5
|
-
import { createTracedFetch } from '../../utils/traced-fetch.js';
|
|
6
|
-
import { logsUrl } from './logs.js';
|
|
7
|
-
export function streamLogs({ stackId, after, auth, onLog, onOpen, onError, logger, }) {
|
|
8
|
-
const fetchFn = createTracedFetch(logger);
|
|
9
|
-
const url = new URL(`${logsUrl}/stream`);
|
|
10
|
-
url.searchParams.append('stackId', stackId);
|
|
11
|
-
if (after)
|
|
12
|
-
url.searchParams.append('after', after);
|
|
13
|
-
const headers = getHeaders(auth);
|
|
14
|
-
const eventSource = new EventSource(url.toString(), {
|
|
15
|
-
fetch: (input, init) => fetchFn(input, {
|
|
16
|
-
...init,
|
|
17
|
-
headers: {
|
|
18
|
-
...init?.headers,
|
|
19
|
-
...headers,
|
|
20
|
-
},
|
|
21
|
-
}),
|
|
22
|
-
});
|
|
23
|
-
eventSource.onopen = onOpen;
|
|
24
|
-
eventSource.onmessage = (event) => {
|
|
25
|
-
try {
|
|
26
|
-
const log = JSON.parse(event.data);
|
|
27
|
-
onLog(log);
|
|
28
|
-
}
|
|
29
|
-
catch (err) {
|
|
30
|
-
onError(`Failed to parse log data: ${err instanceof Error ? err.message : String(err)}`);
|
|
31
|
-
}
|
|
32
|
-
};
|
|
33
|
-
eventSource.addEventListener('logs', (event) => {
|
|
34
|
-
try {
|
|
35
|
-
const logData = JSON.parse(event.data);
|
|
36
|
-
// usually an array
|
|
37
|
-
if (Array.isArray(logData)) {
|
|
38
|
-
for (const log of logData)
|
|
39
|
-
onLog(log);
|
|
40
|
-
}
|
|
41
|
-
else {
|
|
42
|
-
onLog(logData);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
catch (err) {
|
|
46
|
-
console.error('Error parsing logs event:', err);
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
eventSource.onerror = () => {
|
|
50
|
-
onError('Connection to log stream failed or was closed');
|
|
51
|
-
if (eventSource.readyState === eventSource.CLOSED) {
|
|
52
|
-
console.log('Connection is CLOSED');
|
|
53
|
-
}
|
|
54
|
-
else if (eventSource.readyState === eventSource.CONNECTING) {
|
|
55
|
-
console.log('Connection is attempting to reconnect...');
|
|
56
|
-
return; // Don't close if trying to reconnect
|
|
57
|
-
}
|
|
58
|
-
eventSource.close();
|
|
59
|
-
};
|
|
60
|
-
return () => {
|
|
61
|
-
eventSource.close();
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
/** Check if a log is newer than a given timestamp */
|
|
65
|
-
export function isNewerLog(log, timestamp) {
|
|
66
|
-
const logTimestamp = new Date(log.timestamp).getTime();
|
|
67
|
-
return logTimestamp > timestamp;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Sets up log streaming for operations like deploy or destroy with spinner integration
|
|
71
|
-
* @param config Configuration for log streaming
|
|
72
|
-
* @returns A cleanup function for closing the log stream
|
|
73
|
-
*/
|
|
74
|
-
export async function setupLogStreaming(config) {
|
|
75
|
-
const { stackId, auth, log, showBanner, verbose = false, after } = config;
|
|
76
|
-
let newestTimestamp = Date.now();
|
|
77
|
-
let previousLog;
|
|
78
|
-
const onLogReceived = (logEntry) => {
|
|
79
|
-
if (!isNewerLog(logEntry, newestTimestamp))
|
|
80
|
-
return;
|
|
81
|
-
newestTimestamp = new Date(logEntry.timestamp).getTime();
|
|
82
|
-
config.onActivity?.();
|
|
83
|
-
config.onLogEntry?.(logEntry);
|
|
84
|
-
log(formatLogEntry(logEntry, verbose, previousLog));
|
|
85
|
-
previousLog = logEntry;
|
|
86
|
-
};
|
|
87
|
-
let alreadyOpened = false;
|
|
88
|
-
const onStreamOpen = () => {
|
|
89
|
-
if (!alreadyOpened && showBanner)
|
|
90
|
-
log(`Streaming logs... ${styleText('bold', 'ctrl+c')} to cancel`);
|
|
91
|
-
if (alreadyOpened)
|
|
92
|
-
log(`${styleText('green', 'Reconnected')}`);
|
|
93
|
-
alreadyOpened = true;
|
|
94
|
-
};
|
|
95
|
-
const onStreamError = (error) => {
|
|
96
|
-
log(`${styleText('red', 'Stream error:')} ${error}`);
|
|
97
|
-
};
|
|
98
|
-
return streamLogs({
|
|
99
|
-
stackId,
|
|
100
|
-
after,
|
|
101
|
-
auth,
|
|
102
|
-
onLog: onLogReceived,
|
|
103
|
-
onOpen: onStreamOpen,
|
|
104
|
-
onError: onStreamError,
|
|
105
|
-
logger: log,
|
|
106
|
-
});
|
|
107
|
-
}
|