@sanity/runtime-cli 1.8.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -412
- package/bin/dev.cmd +1 -1
- package/bin/dev.js +1 -1
- package/dist/actions/blueprints/blueprint.js +1 -2
- package/dist/actions/blueprints/index.d.ts +16 -0
- package/dist/actions/blueprints/index.js +16 -0
- package/dist/actions/functions/index.d.ts +10 -0
- package/dist/actions/functions/index.js +10 -0
- package/dist/commands/blueprints/add.js +1 -1
- package/dist/commands/blueprints/config.js +1 -1
- package/dist/commands/blueprints/deploy.js +8 -10
- package/dist/commands/blueprints/info.js +5 -39
- package/dist/commands/blueprints/init.js +1 -2
- package/dist/commands/blueprints/logs.js +18 -16
- package/dist/commands/blueprints/plan.js +2 -4
- package/dist/commands/blueprints/stacks.js +2 -2
- package/dist/commands/functions/invoke.js +4 -5
- package/dist/commands/functions/logs.js +4 -5
- package/dist/index.d.ts +4 -4
- package/dist/index.js +4 -4
- package/dist/server/static/vendor/vendor.bundle.d.ts +3 -3
- package/dist/utils/display/blueprints-formatting.d.ts +1 -2
- package/dist/utils/display/blueprints-formatting.js +53 -42
- package/dist/utils/display/colors.d.ts +1 -0
- package/dist/utils/display/colors.js +3 -0
- package/dist/utils/display/dates.js +4 -8
- package/dist/utils/display/index.d.ts +10 -0
- package/dist/utils/display/index.js +10 -0
- package/dist/utils/display/logs-formatting.d.ts +1 -1
- package/dist/utils/display/logs-formatting.js +13 -18
- package/dist/utils/index.d.ts +13 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/vendor/index.d.ts +4 -0
- package/dist/utils/vendor/index.js +4 -0
- package/dist/utils/vendor/parser-validator.d.ts +1 -2
- package/dist/utils/vendor/parser-validator.js +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +24 -26
- /package/dist/actions/blueprints/{stash-asset.d.ts → assets.d.ts} +0 -0
- /package/dist/actions/blueprints/{stash-asset.js → assets.js} +0 -0
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { Command, Flags } from '@oclif/core';
|
|
2
2
|
import { readBlueprintOnDisk } from '../../actions/blueprints/blueprint.js';
|
|
3
3
|
import { getStack } from '../../actions/blueprints/stacks.js';
|
|
4
|
-
import { formatResourceTree } from '../../utils/display/blueprints-formatting.js';
|
|
5
|
-
import { bold, green, red, yellow } from '../../utils/display/colors.js';
|
|
6
|
-
import { formatDate, formatDuration } from '../../utils/display/dates.js';
|
|
4
|
+
import { formatResourceTree, formatStackInfo } from '../../utils/display/blueprints-formatting.js';
|
|
7
5
|
export default class Info extends Command {
|
|
8
6
|
static description = 'Show information about a Blueprint';
|
|
9
7
|
static examples = [
|
|
@@ -21,7 +19,7 @@ export default class Info extends Command {
|
|
|
21
19
|
const { errors, deployedStack, projectId } = await readBlueprintOnDisk({ getStack: true });
|
|
22
20
|
if (errors.length > 0) {
|
|
23
21
|
// printErrors(errors)
|
|
24
|
-
this.
|
|
22
|
+
this.warn('Blueprint parse errors:');
|
|
25
23
|
console.dir(errors, { depth: null });
|
|
26
24
|
return;
|
|
27
25
|
}
|
|
@@ -39,42 +37,10 @@ export default class Info extends Command {
|
|
|
39
37
|
}
|
|
40
38
|
if (!stack)
|
|
41
39
|
this.error('Stack not found. Is it deployed?');
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
this.log(`Stack ID: ${yellow(stack.id)}`);
|
|
45
|
-
if (stack.createdAt) {
|
|
46
|
-
this.log(`Created: ${formatDate(stack.createdAt)}`);
|
|
47
|
-
}
|
|
48
|
-
if (stack.updatedAt) {
|
|
49
|
-
this.log(`Updated: ${formatDate(stack.updatedAt)}`);
|
|
50
|
-
}
|
|
51
|
-
if (stack.recentOperation) {
|
|
52
|
-
const operation = stack.recentOperation;
|
|
53
|
-
if (operation.id) {
|
|
54
|
-
this.log(`Recent Operation <${yellow(operation.id)}>:`);
|
|
55
|
-
}
|
|
56
|
-
if (operation.status) {
|
|
57
|
-
const operationColor = operation.status === 'COMPLETED' ? green : red;
|
|
58
|
-
const status = operation.status || 'UNKNOWN';
|
|
59
|
-
this.log(` Status: ${operationColor(status)}`);
|
|
60
|
-
}
|
|
61
|
-
if (operation.createdAt) {
|
|
62
|
-
this.log(` Started: ${formatDate(operation.createdAt)}`);
|
|
63
|
-
}
|
|
64
|
-
if (operation.status === 'COMPLETED' && operation.completedAt && operation.createdAt) {
|
|
65
|
-
this.log(` Completed: ${formatDate(operation.completedAt)}`);
|
|
66
|
-
this.log(` Duration: ${yellow(formatDuration(operation.createdAt, operation.completedAt))}`);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
40
|
+
this.log(formatStackInfo(stack, true));
|
|
41
|
+
if (stack.resources) {
|
|
69
42
|
this.log('');
|
|
70
|
-
|
|
71
|
-
formatResourceTree(stack.resources, this.log.bind(this));
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
catch (err) {
|
|
75
|
-
if (err instanceof Error) {
|
|
76
|
-
this.log(`Error: ${err.message}`);
|
|
77
|
-
}
|
|
43
|
+
this.log(formatResourceTree(stack.resources));
|
|
78
44
|
}
|
|
79
45
|
}
|
|
80
46
|
}
|
|
@@ -26,9 +26,8 @@ export default class Init extends Command {
|
|
|
26
26
|
},
|
|
27
27
|
]);
|
|
28
28
|
const { ok, projects, error } = await listProjects();
|
|
29
|
-
if (!ok)
|
|
29
|
+
if (!ok)
|
|
30
30
|
this.error(error);
|
|
31
|
-
}
|
|
32
31
|
if (projects.length === 0) {
|
|
33
32
|
this.error('No projects found. Please create a project in Sanity.io first.');
|
|
34
33
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Command, Flags } from '@oclif/core';
|
|
2
|
-
import
|
|
2
|
+
import Spinner from 'yocto-spinner';
|
|
3
3
|
import { readBlueprintOnDisk } from '../../actions/blueprints/blueprint.js';
|
|
4
4
|
import { findNewestLogTimestamp, getLogs, getRecentLogs, isNewerLog, streamLogs, } from '../../actions/blueprints/logs.js';
|
|
5
5
|
import config from '../../config.js';
|
|
@@ -33,17 +33,16 @@ export default class Logs extends Command {
|
|
|
33
33
|
if (!deployedStack)
|
|
34
34
|
this.error('Stack not found'); // returns
|
|
35
35
|
const { id: stackId, projectId, name } = deployedStack;
|
|
36
|
-
const spinner =
|
|
37
|
-
spinner.start();
|
|
36
|
+
const spinner = Spinner({ text: `Fetching logs for stack ${yellow(`<${stackId}>`)}` }).start();
|
|
38
37
|
if (watchMode) {
|
|
39
38
|
const { ok, logs, error } = await getLogs(stackId, projectId, config.token);
|
|
40
39
|
if (!ok) {
|
|
41
|
-
spinner.
|
|
40
|
+
spinner.error(`${red('Failed')} to retrieve logs`);
|
|
42
41
|
this.log(`Error: ${error || 'Unknown error'}`);
|
|
43
42
|
return;
|
|
44
43
|
}
|
|
45
|
-
spinner.stop(); // stop and remove the spinner
|
|
46
|
-
this.log(`${formatTitle('Blueprint', name)}
|
|
44
|
+
spinner.stop().clear(); // stop and remove the spinner
|
|
45
|
+
this.log(`${formatTitle('Blueprint', name)} <${yellow(stackId)}> logs`);
|
|
47
46
|
if (logs.length > 0) {
|
|
48
47
|
this.log('\nMost recent logs:');
|
|
49
48
|
const recentLogs = getRecentLogs(logs);
|
|
@@ -52,18 +51,22 @@ export default class Logs extends Command {
|
|
|
52
51
|
}
|
|
53
52
|
}
|
|
54
53
|
else {
|
|
55
|
-
this.log(`No recent logs found for stack
|
|
54
|
+
this.log(`No recent logs found for stack <${yellow(stackId)}>`);
|
|
55
|
+
}
|
|
56
|
+
const watchSpinner = Spinner();
|
|
57
|
+
function onOpen() {
|
|
58
|
+
if (watchSpinner.isSpinning)
|
|
59
|
+
watchSpinner.stop().clear();
|
|
60
|
+
watchSpinner.text = `Watching for new logs... ${bold('ctrl+c')} to stop`;
|
|
61
|
+
watchSpinner.start();
|
|
56
62
|
}
|
|
57
|
-
const onOpen = () => {
|
|
58
|
-
this.log(`Watching for new logs... ${bold('ctrl+c')} to stop`);
|
|
59
|
-
};
|
|
60
63
|
let newestTimestamp = findNewestLogTimestamp(logs);
|
|
61
64
|
const renderLog = (log) => {
|
|
62
|
-
if (!isNewerLog(log, newestTimestamp))
|
|
65
|
+
if (!isNewerLog(log, newestTimestamp))
|
|
63
66
|
return;
|
|
64
|
-
}
|
|
65
67
|
newestTimestamp = new Date(log.timestamp).getTime();
|
|
66
68
|
this.log(formatLogEntry(log, true));
|
|
69
|
+
onOpen();
|
|
67
70
|
};
|
|
68
71
|
this.debug(`${yellow('Debug:')} Connecting to streaming endpoint for stack ${stackId}...`);
|
|
69
72
|
streamLogs(stackId, projectId, config.token, renderLog, onOpen, (error) => this.log(`${red('Error:')} ${error}`));
|
|
@@ -73,7 +76,7 @@ export default class Logs extends Command {
|
|
|
73
76
|
}
|
|
74
77
|
const { ok, logs, error } = await getLogs(stackId, projectId, config.token);
|
|
75
78
|
if (!ok) {
|
|
76
|
-
spinner.
|
|
79
|
+
spinner.error(`${red('Failed')} to retrieve logs`);
|
|
77
80
|
this.log(`Error: ${error || 'Unknown error'}`);
|
|
78
81
|
return;
|
|
79
82
|
}
|
|
@@ -81,7 +84,7 @@ export default class Logs extends Command {
|
|
|
81
84
|
spinner.info(`No logs found for stack ${stackId}`);
|
|
82
85
|
return;
|
|
83
86
|
}
|
|
84
|
-
spinner.
|
|
87
|
+
spinner.success(`${formatTitle('Blueprint', name)} Logs`);
|
|
85
88
|
this.log(`Found ${bold(logs.length.toString())} log entries for stack ${yellow(stackId)}\n`);
|
|
86
89
|
// Organize and format logs by day
|
|
87
90
|
const logsByDay = organizeLogsByDay(logs);
|
|
@@ -89,9 +92,8 @@ export default class Logs extends Command {
|
|
|
89
92
|
}
|
|
90
93
|
catch (err) {
|
|
91
94
|
this.warn('Failed to retrieve logs');
|
|
92
|
-
if (err instanceof Error)
|
|
95
|
+
if (err instanceof Error)
|
|
93
96
|
this.error(`Error: ${err.message}`);
|
|
94
|
-
}
|
|
95
97
|
}
|
|
96
98
|
}
|
|
97
99
|
}
|
|
@@ -18,9 +18,7 @@ export default class Plan extends Command {
|
|
|
18
18
|
this.log(`${formatTitle('Blueprint', name)} Plan\n`);
|
|
19
19
|
this.log(`Blueprint document: (${fileInfo.fileName})`);
|
|
20
20
|
this.log('');
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
this.log('\nRun `sanity blueprints deploy` to deploy these changes');
|
|
24
|
-
}
|
|
21
|
+
this.log(formatResourceTree(resources));
|
|
22
|
+
this.log('\nRun `sanity blueprints deploy` to deploy these changes');
|
|
25
23
|
}
|
|
26
24
|
}
|
|
@@ -19,10 +19,10 @@ export default class Stacks extends Command {
|
|
|
19
19
|
if (!ok)
|
|
20
20
|
this.error(error || 'Failed to list stacks');
|
|
21
21
|
if (!stacks || stacks.length === 0) {
|
|
22
|
-
this.
|
|
22
|
+
this.warn('No stacks found');
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
25
|
-
this.log(`${bold('Project')} <${yellow(projectId)}> ${bold('Stacks')}
|
|
25
|
+
this.log(`${bold('Project')} <${yellow(projectId)}> ${bold('Stacks')}:\n`);
|
|
26
26
|
this.log(formatStacksListing(stacks, stackId));
|
|
27
27
|
}
|
|
28
28
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Args, Command, Flags } from '@oclif/core';
|
|
2
|
-
import
|
|
2
|
+
import Spinner from 'yocto-spinner';
|
|
3
3
|
import { readBlueprintOnDisk } from '../../actions/blueprints/blueprint.js';
|
|
4
4
|
import { invoke } from '../../actions/functions/invoke.js';
|
|
5
5
|
import config from '../../config.js';
|
|
@@ -24,20 +24,19 @@ export default class Invoke extends Command {
|
|
|
24
24
|
};
|
|
25
25
|
async run() {
|
|
26
26
|
const { args, flags } = await this.parse(Invoke);
|
|
27
|
-
const spinner =
|
|
27
|
+
const spinner = Spinner({ text: `Invoking function "${args.name}"` }).start();
|
|
28
28
|
const { deployedStack } = await readBlueprintOnDisk({ getStack: true });
|
|
29
29
|
if (!deployedStack)
|
|
30
30
|
this.error('Stack not found'); // returns
|
|
31
31
|
const { projectId } = deployedStack;
|
|
32
|
-
spinner.start();
|
|
33
32
|
const { externalId } = findFunctionByName(deployedStack, args.name);
|
|
34
33
|
const result = await invoke(externalId, { data: flags.data, file: flags.file }, { token: config.token, projectId });
|
|
35
34
|
if (result.ok) {
|
|
36
|
-
spinner.
|
|
35
|
+
spinner.success(`Invocation of ${args.name} succeeded`);
|
|
37
36
|
this.log(JSON.stringify(result.json, null, 2));
|
|
38
37
|
}
|
|
39
38
|
else {
|
|
40
|
-
spinner.
|
|
39
|
+
spinner.error(`${red('Failed')} to invoke function`);
|
|
41
40
|
this.log(`Error: ${result.error || 'Unknown error'}`);
|
|
42
41
|
}
|
|
43
42
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Args, Command } from '@oclif/core';
|
|
2
|
-
import
|
|
2
|
+
import Spinner from 'yocto-spinner';
|
|
3
3
|
import { readBlueprintOnDisk } from '../../actions/blueprints/blueprint.js';
|
|
4
4
|
import { logs } from '../../actions/functions/logs.js';
|
|
5
5
|
import config from '../../config.js';
|
|
@@ -13,16 +13,15 @@ export default class Logs extends Command {
|
|
|
13
13
|
static examples = ['<%= config.bin %> <%= command.id %> <ID>'];
|
|
14
14
|
async run() {
|
|
15
15
|
const { args } = await this.parse(Logs);
|
|
16
|
-
const spinner =
|
|
16
|
+
const spinner = Spinner({ text: `Finding logs for function "${args.name}"` }).start();
|
|
17
17
|
const { deployedStack } = await readBlueprintOnDisk({ getStack: true });
|
|
18
18
|
if (!deployedStack)
|
|
19
19
|
this.error('Stack not found'); // returns
|
|
20
20
|
const { name, projectId } = deployedStack;
|
|
21
|
-
spinner.start();
|
|
22
21
|
const { externalId } = findFunctionByName(deployedStack, args.name);
|
|
23
22
|
const result = await logs(externalId, { token: config.token, projectId });
|
|
24
23
|
if (result.ok) {
|
|
25
|
-
spinner.
|
|
24
|
+
spinner.success(`Found logs ${args.name} for blueprint "${name}"`);
|
|
26
25
|
for (const logGroup of result.logs) {
|
|
27
26
|
for (const log of logGroup.events) {
|
|
28
27
|
const { message, timestamp } = log;
|
|
@@ -41,7 +40,7 @@ export default class Logs extends Command {
|
|
|
41
40
|
}
|
|
42
41
|
}
|
|
43
42
|
else {
|
|
44
|
-
spinner.
|
|
43
|
+
spinner.error(`${red('Failed')} to retrieve logs`);
|
|
45
44
|
this.log(`Error: ${result.error || 'Unknown error'}`);
|
|
46
45
|
}
|
|
47
46
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { run } from '@oclif/core';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
export {
|
|
2
|
+
import { blueprintsActions } from './actions/blueprints/index.js';
|
|
3
|
+
import { functionsActions } from './actions/functions/index.js';
|
|
4
|
+
import { utils } from './utils/index.js';
|
|
5
|
+
export { blueprintsActions, functionsActions, utils, run };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { run } from '@oclif/core';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
export {
|
|
2
|
+
import { blueprintsActions } from './actions/blueprints/index.js';
|
|
3
|
+
import { functionsActions } from './actions/functions/index.js';
|
|
4
|
+
import { utils } from './utils/index.js';
|
|
5
|
+
export { blueprintsActions, functionsActions, utils, run };
|
|
@@ -877,7 +877,7 @@ declare class SelectionRange {
|
|
|
877
877
|
the character before its position, 1 the character after, and 0
|
|
878
878
|
means no association.
|
|
879
879
|
*/
|
|
880
|
-
get assoc():
|
|
880
|
+
get assoc(): 0 | 1 | -1;
|
|
881
881
|
/**
|
|
882
882
|
The bidirectional text level associated with this cursor, if
|
|
883
883
|
any.
|
|
@@ -1274,8 +1274,8 @@ declare class FacetProvider {
|
|
|
1274
1274
|
id: number;
|
|
1275
1275
|
dynamicSlot(addresses: any): {
|
|
1276
1276
|
create(state: any): number;
|
|
1277
|
-
update(state: any, tr: any):
|
|
1278
|
-
reconfigure: (state: any, oldState: any) =>
|
|
1277
|
+
update(state: any, tr: any): 0 | 1;
|
|
1278
|
+
reconfigure: (state: any, oldState: any) => 0 | 1;
|
|
1279
1279
|
};
|
|
1280
1280
|
}
|
|
1281
1281
|
declare class PrecExtension {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { BlueprintResource, BlueprintStack } from '../types.js';
|
|
2
2
|
export declare function formatTitle(title: string, name: string): string;
|
|
3
|
-
export declare function
|
|
4
|
-
export declare function formatResourceTree(resources: BlueprintResource[], logger: (msg: string) => void): void;
|
|
3
|
+
export declare function formatResourceTree(resources: BlueprintResource[]): string;
|
|
5
4
|
export declare function formatStackInfo(stack: BlueprintStack, isCurrentStack?: boolean): string;
|
|
6
5
|
export declare function formatStacksListing(stacks: BlueprintStack[], currentStackId?: string): string;
|
|
@@ -1,67 +1,78 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { treeify } from 'array-treeify';
|
|
2
|
+
import { blue, bold, boldnblue, green, red, yellow } from './colors.js';
|
|
3
|
+
import { formatDate, formatDuration } from './dates.js';
|
|
3
4
|
export function formatTitle(title, name) {
|
|
4
5
|
return `${boldnblue(title)} ${bold(`"${name}"`)}`;
|
|
5
6
|
}
|
|
6
|
-
export function
|
|
7
|
-
if (!stacks || stacks.length === 0) {
|
|
8
|
-
return 'No stacks found';
|
|
9
|
-
}
|
|
10
|
-
let result = '\nFound Stacks:\n';
|
|
11
|
-
for (const name of stacks) {
|
|
12
|
-
result += ` ${name}\n`;
|
|
13
|
-
}
|
|
14
|
-
return result;
|
|
15
|
-
}
|
|
16
|
-
export function formatResourceTree(resources, logger) {
|
|
7
|
+
export function formatResourceTree(resources) {
|
|
17
8
|
if (!resources || resources.length === 0) {
|
|
18
|
-
|
|
19
|
-
return;
|
|
9
|
+
return ' No resources in this stack';
|
|
20
10
|
}
|
|
21
|
-
|
|
11
|
+
const output = [];
|
|
12
|
+
output.push(`${blue('Stack Resources')} [${resources.length}]`);
|
|
22
13
|
const functionResources = resources.filter((r) => r.type?.startsWith('sanity.function.'));
|
|
23
14
|
const otherResources = resources.filter((r) => !r.type?.startsWith('sanity.function.'));
|
|
24
15
|
const hasOtherResources = otherResources.length > 0;
|
|
25
16
|
if (functionResources.length > 0) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const prefix = hasOtherResources ? '│' : ' ';
|
|
30
|
-
const connector = isLast ? '└─' : '├─';
|
|
17
|
+
const functionsOutput = [];
|
|
18
|
+
functionsOutput.push(`${bold('Functions')} [${functionResources.length}]`);
|
|
19
|
+
const functionResourcesOutput = functionResources.map((fn) => {
|
|
31
20
|
const name = green(fn.displayName || fn.name);
|
|
32
21
|
const externalId = fn.externalId ? `Fn<${yellow(fn.externalId)}>` : '';
|
|
33
|
-
|
|
34
|
-
}
|
|
22
|
+
return `"${name}" ${externalId}`;
|
|
23
|
+
});
|
|
24
|
+
functionsOutput.push(functionResourcesOutput);
|
|
25
|
+
output.push(functionsOutput);
|
|
35
26
|
}
|
|
36
27
|
if (hasOtherResources) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
28
|
+
const otherOutput = [];
|
|
29
|
+
otherOutput.push(`${bold('Other Resources')} [${otherResources.length}]`);
|
|
30
|
+
const otherResourcesOutput = otherResources.map((other) => {
|
|
31
|
+
return `"${yellow(other.displayName || other.name || other.src)}"`;
|
|
32
|
+
});
|
|
33
|
+
otherOutput.push(otherResourcesOutput);
|
|
34
|
+
output.push(otherOutput);
|
|
42
35
|
}
|
|
36
|
+
return treeify(output);
|
|
43
37
|
}
|
|
44
38
|
export function formatStackInfo(stack, isCurrentStack = false) {
|
|
45
|
-
|
|
39
|
+
const output = [];
|
|
46
40
|
const stackName = isCurrentStack ? boldnblue(stack.name) : bold(stack.name);
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
41
|
+
output.push(`"${stackName}" <${yellow(stack.id)}>${isCurrentStack ? ' (current)' : ''}`);
|
|
42
|
+
const infoOutput = [];
|
|
43
|
+
infoOutput.push(`${stack.resources.length} resource${stack.resources.length === 1 ? '' : 's'}`);
|
|
44
|
+
if (stack.createdAt)
|
|
45
|
+
infoOutput.push(`Created: ${formatDate(stack.createdAt)}`);
|
|
46
|
+
if (stack.updatedAt)
|
|
47
|
+
infoOutput.push(`Updated: ${formatDate(stack.updatedAt)}`);
|
|
48
|
+
if (stack.recentOperation) {
|
|
49
|
+
const operation = stack.recentOperation;
|
|
50
|
+
const operationOutput = [];
|
|
51
|
+
if (operation.id)
|
|
52
|
+
operationOutput.push(`Recent Operation <${yellow(operation.id)}>:`);
|
|
53
|
+
if (operation.status) {
|
|
54
|
+
const operationColor = operation.status === 'COMPLETED' ? green : red;
|
|
55
|
+
const status = operation.status || 'UNKNOWN';
|
|
56
|
+
operationOutput.push(`Status: ${operationColor(status)}`);
|
|
57
|
+
}
|
|
58
|
+
if (operation.createdAt)
|
|
59
|
+
operationOutput.push(`Started: ${formatDate(operation.createdAt)}`);
|
|
60
|
+
if (operation.status === 'COMPLETED' && operation.completedAt && operation.createdAt) {
|
|
61
|
+
operationOutput.push(`Completed: ${formatDate(operation.completedAt)}`);
|
|
62
|
+
operationOutput.push(`Duration: ${yellow(formatDuration(operation.createdAt, operation.completedAt))}`);
|
|
63
|
+
}
|
|
64
|
+
infoOutput.push(operationOutput);
|
|
53
65
|
}
|
|
54
|
-
|
|
55
|
-
return
|
|
66
|
+
output.push(infoOutput);
|
|
67
|
+
return treeify(output, { plain: true });
|
|
56
68
|
}
|
|
57
69
|
export function formatStacksListing(stacks, currentStackId) {
|
|
58
|
-
if (!stacks || stacks.length === 0)
|
|
70
|
+
if (!stacks || stacks.length === 0)
|
|
59
71
|
return 'No stacks found';
|
|
60
|
-
|
|
61
|
-
let result = '';
|
|
72
|
+
const output = [];
|
|
62
73
|
for (const stack of stacks) {
|
|
63
74
|
const isCurrentStack = currentStackId === stack.id;
|
|
64
|
-
|
|
75
|
+
output.push(formatStackInfo(stack, isCurrentStack));
|
|
65
76
|
}
|
|
66
|
-
return
|
|
77
|
+
return output.join('\n');
|
|
67
78
|
}
|
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
export function formatDate(dateString) {
|
|
2
|
-
|
|
3
|
-
return date.toLocaleString();
|
|
2
|
+
return new Date(dateString).toLocaleString();
|
|
4
3
|
}
|
|
5
4
|
export function formatDuration(startDate, endDate) {
|
|
6
5
|
const start = new Date(startDate).getTime();
|
|
7
6
|
const end = new Date(endDate).getTime();
|
|
8
|
-
if (start > end)
|
|
7
|
+
if (start > end)
|
|
9
8
|
return 'Invalid duration';
|
|
10
|
-
}
|
|
11
9
|
const durationMs = end - start;
|
|
12
|
-
if (durationMs < 1000)
|
|
10
|
+
if (durationMs < 1000)
|
|
13
11
|
return `${durationMs}ms`;
|
|
14
|
-
|
|
15
|
-
if (durationMs < 60000) {
|
|
12
|
+
if (durationMs < 60000)
|
|
16
13
|
return `${Math.round(durationMs / 1000)}s`;
|
|
17
|
-
}
|
|
18
14
|
if (durationMs < 3600000) {
|
|
19
15
|
const minutes = Math.floor(durationMs / 60000);
|
|
20
16
|
const seconds = Math.floor((durationMs % 60000) / 1000);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as blueprintsFormatting from './blueprints-formatting.js';
|
|
2
|
+
import * as colors from './colors.js';
|
|
3
|
+
import * as dates from './dates.js';
|
|
4
|
+
import * as logsFormatting from './logs-formatting.js';
|
|
5
|
+
export declare const display: {
|
|
6
|
+
blueprintsFormatting: typeof blueprintsFormatting;
|
|
7
|
+
logsFormatting: typeof logsFormatting;
|
|
8
|
+
colors: typeof colors;
|
|
9
|
+
dates: typeof dates;
|
|
10
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import * as blueprintsFormatting from './blueprints-formatting.js';
|
|
2
|
+
import * as colors from './colors.js';
|
|
3
|
+
import * as dates from './dates.js';
|
|
4
|
+
import * as logsFormatting from './logs-formatting.js';
|
|
5
|
+
export const display = {
|
|
6
|
+
blueprintsFormatting,
|
|
7
|
+
logsFormatting,
|
|
8
|
+
colors,
|
|
9
|
+
dates,
|
|
10
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { BlueprintLog } from '../types.js';
|
|
2
|
-
export declare function formatLogEntry(log: BlueprintLog, isNewest?: boolean): string;
|
|
2
|
+
export declare function formatLogEntry(log: BlueprintLog, withDate?: boolean, isNewest?: boolean): string;
|
|
3
3
|
export declare function formatRecentLogs(logs: BlueprintLog[]): string;
|
|
4
4
|
export declare function organizeLogsByDay(logs: BlueprintLog[]): Map<string, BlueprintLog[]>;
|
|
5
5
|
export declare function formatLogsByDay(logsByDay: Map<string, BlueprintLog[]>): string;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { treeify } from 'array-treeify';
|
|
2
|
+
import { blue, bold, dim, green } from './colors.js';
|
|
3
|
+
export function formatLogEntry(log, withDate = true, isNewest = false) {
|
|
3
4
|
const date = new Date(log.timestamp);
|
|
4
5
|
const time = date.toLocaleTimeString();
|
|
5
6
|
const day = date.toLocaleDateString();
|
|
6
|
-
return `${isNewest ? `${green('>')} ` : ''}${
|
|
7
|
+
return `${isNewest ? `${green('>')} ` : ''}${withDate ? `${day} ` : ''}${dim(time)} ${log.message}`;
|
|
7
8
|
}
|
|
8
9
|
export function formatRecentLogs(logs) {
|
|
9
10
|
if (logs.length === 0)
|
|
@@ -11,9 +12,8 @@ export function formatRecentLogs(logs) {
|
|
|
11
12
|
const sortedLogs = [...logs].sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
|
|
12
13
|
const recentLogs = sortedLogs.slice(-10);
|
|
13
14
|
let result = '\nMost recent logs:\n';
|
|
14
|
-
for (const log of recentLogs)
|
|
15
|
+
for (const log of recentLogs)
|
|
15
16
|
result += ` ${formatLogEntry(log)}\n`;
|
|
16
|
-
}
|
|
17
17
|
return result;
|
|
18
18
|
}
|
|
19
19
|
export function organizeLogsByDay(logs) {
|
|
@@ -21,30 +21,25 @@ export function organizeLogsByDay(logs) {
|
|
|
21
21
|
for (const log of logs) {
|
|
22
22
|
const date = new Date(log.timestamp);
|
|
23
23
|
const day = date.toLocaleDateString();
|
|
24
|
-
if (!logsByDay.has(day))
|
|
24
|
+
if (!logsByDay.has(day))
|
|
25
25
|
logsByDay.set(day, []);
|
|
26
|
-
}
|
|
27
26
|
logsByDay.get(day)?.push(log);
|
|
28
27
|
}
|
|
29
28
|
return logsByDay;
|
|
30
29
|
}
|
|
31
30
|
export function formatLogsByDay(logsByDay) {
|
|
32
|
-
|
|
31
|
+
const output = [];
|
|
33
32
|
const sortedDays = Array.from(logsByDay.keys()).sort((a, b) => {
|
|
34
33
|
return new Date(a).getTime() - new Date(b).getTime();
|
|
35
34
|
});
|
|
36
35
|
for (const day of sortedDays) {
|
|
37
|
-
|
|
36
|
+
output.push(`${blue('Date:')} ${bold(day)}`);
|
|
38
37
|
const dayLogs = logsByDay.get(day) || [];
|
|
39
38
|
dayLogs.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const isLast = i === dayLogs.length - 1;
|
|
44
|
-
result += ` ${isLast ? '└─' : '├─'} ${yellow(time)} ${log.message}\n`;
|
|
45
|
-
}
|
|
46
|
-
// new line between days
|
|
47
|
-
result += '\n';
|
|
39
|
+
const dayLogsOutput = dayLogs.map((log) => formatLogEntry(log, false));
|
|
40
|
+
output.push(dayLogsOutput);
|
|
41
|
+
output.push('');
|
|
48
42
|
}
|
|
49
|
-
|
|
43
|
+
output.pop(); // remove last empty line
|
|
44
|
+
return treeify(output);
|
|
50
45
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as types from './types.js';
|
|
2
|
+
export declare const utils: {
|
|
3
|
+
display: {
|
|
4
|
+
blueprintsFormatting: typeof import("./display/blueprints-formatting.js");
|
|
5
|
+
logsFormatting: typeof import("./display/logs-formatting.js");
|
|
6
|
+
colors: typeof import("./display/colors.js");
|
|
7
|
+
dates: typeof import("./display/dates.js");
|
|
8
|
+
};
|
|
9
|
+
vendor: {
|
|
10
|
+
blueprintParserValidator: typeof import("./vendor/parser-validator.js").blueprintParserValidator;
|
|
11
|
+
};
|
|
12
|
+
types: typeof types;
|
|
13
|
+
};
|
package/oclif.manifest.json
CHANGED