@sanity/runtime-cli 4.5.0 → 4.5.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 +49 -77
- package/dist/actions/blueprints/blueprint.d.ts +6 -12
- package/dist/actions/blueprints/blueprint.js +38 -45
- package/dist/actions/blueprints/index.d.ts +33 -0
- package/dist/actions/blueprints/index.js +32 -0
- package/dist/actions/blueprints/projects.d.ts +9 -0
- package/dist/actions/blueprints/projects.js +12 -0
- package/dist/actions/blueprints/stacks.d.ts +0 -12
- package/dist/actions/blueprints/stacks.js +3 -30
- package/dist/baseCommands.d.ts +24 -0
- package/dist/baseCommands.js +69 -0
- package/dist/commands/blueprints/add.d.ts +1 -1
- package/dist/commands/blueprints/add.js +7 -6
- package/dist/commands/blueprints/config.d.ts +1 -1
- package/dist/commands/blueprints/config.js +24 -11
- package/dist/commands/blueprints/deploy.d.ts +2 -2
- package/dist/commands/blueprints/deploy.js +18 -33
- package/dist/commands/blueprints/destroy.d.ts +4 -3
- package/dist/commands/blueprints/destroy.js +32 -35
- package/dist/commands/blueprints/info.d.ts +2 -2
- package/dist/commands/blueprints/info.js +16 -36
- package/dist/commands/blueprints/init.d.ts +10 -2
- package/dist/commands/blueprints/init.js +85 -26
- package/dist/commands/blueprints/logs.d.ts +2 -2
- package/dist/commands/blueprints/logs.js +18 -32
- package/dist/commands/blueprints/plan.d.ts +2 -2
- package/dist/commands/blueprints/plan.js +10 -16
- package/dist/commands/blueprints/stacks.d.ts +3 -2
- package/dist/commands/blueprints/stacks.js +10 -29
- package/dist/commands/functions/env/add.d.ts +2 -2
- package/dist/commands/functions/env/add.js +6 -17
- package/dist/commands/functions/env/list.d.ts +2 -2
- package/dist/commands/functions/env/list.js +10 -17
- package/dist/commands/functions/env/remove.d.ts +2 -2
- package/dist/commands/functions/env/remove.js +6 -17
- package/dist/commands/functions/invoke.d.ts +2 -2
- package/dist/commands/functions/invoke.js +7 -14
- package/dist/commands/functions/logs.d.ts +3 -7
- package/dist/commands/functions/logs.js +21 -37
- package/dist/commands/functions/test.d.ts +3 -3
- package/dist/commands/functions/test.js +10 -8
- package/dist/server/app.js +3 -3
- package/dist/server/static/vendor/vendor.bundle.d.ts +2 -2
- package/dist/utils/display/blueprints-formatting.js +2 -2
- package/dist/utils/display/errors.d.ts +4 -0
- package/dist/utils/display/errors.js +27 -0
- package/dist/utils/display/index.d.ts +1 -0
- package/dist/utils/display/index.js +1 -0
- package/dist/utils/types.d.ts +10 -3
- package/dist/utils/types.js +9 -3
- package/oclif.manifest.json +59 -37
- package/package.json +2 -1
|
@@ -1,21 +1,33 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
2
|
import { cwd } from 'node:process';
|
|
3
|
-
import { Command, Flags } from '@oclif/core';
|
|
3
|
+
import { Args, Command, Flags } from '@oclif/core';
|
|
4
4
|
import inquirer from 'inquirer';
|
|
5
5
|
import { findBlueprintFile, writeBlueprintToDisk, writeConfigFile, } from '../../actions/blueprints/blueprint.js';
|
|
6
|
-
import { listProjects } from '../../actions/blueprints/projects.js';
|
|
7
|
-
import { createStack, listStacks } from '../../actions/blueprints/stacks.js';
|
|
6
|
+
import { getProject, listProjects } from '../../actions/blueprints/projects.js';
|
|
7
|
+
import { createStack, getStack, listStacks } from '../../actions/blueprints/stacks.js';
|
|
8
8
|
import { bold, dim, niceId, underline } from '../../utils/display/colors.js';
|
|
9
9
|
import { validTokenOrErrorMessage } from '../../utils/validated-token.js';
|
|
10
|
-
|
|
10
|
+
const LAUNCH_LIMIT_STACK_PER_PROJECT = true;
|
|
11
|
+
export default class InitCommand extends Command {
|
|
11
12
|
static description = 'Initialize a new Blueprint';
|
|
12
13
|
static examples = [
|
|
13
14
|
'<%= config.bin %> <%= command.id %>',
|
|
15
|
+
'<%= config.bin %> <%= command.id %> [directory]',
|
|
14
16
|
'<%= config.bin %> <%= command.id %> --blueprint-type <json|js|ts>',
|
|
15
|
-
'<%= config.bin %> <%= command.id %> --blueprint-type <json|js|ts> --project-id <projectId>
|
|
16
|
-
|
|
17
|
+
'<%= config.bin %> <%= command.id %> --blueprint-type <json|js|ts> --project-id <projectId>',
|
|
18
|
+
// LAUNCH LIMIT: 1 Stack per Project - do not prompt for Stack, just create one
|
|
19
|
+
// '<%= config.bin %> <%= command.id %> --blueprint-type <json|js|ts> --project-id <projectId> --stack-id <stackId>',
|
|
20
|
+
// '<%= config.bin %> <%= command.id %> --blueprint-type <json|js|ts> --project-id <projectId> --stack-name <stackName>',
|
|
17
21
|
];
|
|
22
|
+
static args = {
|
|
23
|
+
dir: Args.string({
|
|
24
|
+
description: 'Directory to create the Blueprint in',
|
|
25
|
+
}),
|
|
26
|
+
};
|
|
18
27
|
static flags = {
|
|
28
|
+
dir: Flags.string({
|
|
29
|
+
description: 'Directory to create the Blueprint in',
|
|
30
|
+
}),
|
|
19
31
|
'blueprint-type': Flags.string({
|
|
20
32
|
description: 'Blueprint manifest type to use for the Blueprint',
|
|
21
33
|
options: ['json', 'js', 'ts'],
|
|
@@ -30,22 +42,29 @@ export default class Init extends Command {
|
|
|
30
42
|
aliases: ['stack', 'stackId'],
|
|
31
43
|
dependsOn: ['project-id'],
|
|
32
44
|
exclusive: ['stack-name'],
|
|
45
|
+
hidden: true, // LAUNCH LIMIT: 1 Stack per Project
|
|
33
46
|
}),
|
|
34
47
|
'stack-name': Flags.string({
|
|
35
|
-
char: 'n',
|
|
36
48
|
description: 'Name to use for a NEW Stack',
|
|
37
49
|
aliases: ['name'],
|
|
38
50
|
dependsOn: ['project-id'],
|
|
39
51
|
exclusive: ['stack-id'],
|
|
52
|
+
hidden: true, // LAUNCH LIMIT: 1 Stack per Project
|
|
40
53
|
}),
|
|
41
54
|
};
|
|
42
55
|
sanityToken;
|
|
43
56
|
async run() {
|
|
44
|
-
const { flags } = await this.parse(
|
|
45
|
-
const { 'blueprint-type': flagBlueprintType, 'project-id': flagProjectId, 'stack-id': flagStackId, 'stack-name': flagStackName, } = flags;
|
|
46
|
-
const
|
|
57
|
+
const { args, flags } = await this.parse(InitCommand);
|
|
58
|
+
const { 'blueprint-type': flagBlueprintType, 'project-id': flagProjectId, 'stack-id': flagStackId, 'stack-name': flagStackName, dir: flagDir, } = flags;
|
|
59
|
+
const { dir: argDir } = args;
|
|
60
|
+
const dirProvided = argDir || flagDir;
|
|
61
|
+
const here = cwd();
|
|
62
|
+
const dir = argDir || flagDir || here;
|
|
63
|
+
const existingBlueprint = findBlueprintFile(dir);
|
|
47
64
|
if (existingBlueprint) {
|
|
48
|
-
this.
|
|
65
|
+
this.log(`A Blueprint file already exists: ${existingBlueprint.blueprintFilePath.replace(here, '')}`);
|
|
66
|
+
this.log('Use `sanity-run blueprints config --edit` to edit the configuration.');
|
|
67
|
+
this.error('Existing Blueprint found.');
|
|
49
68
|
}
|
|
50
69
|
const { token, error: tokenErr } = await validTokenOrErrorMessage();
|
|
51
70
|
if (tokenErr)
|
|
@@ -54,15 +73,24 @@ export default class Init extends Command {
|
|
|
54
73
|
const blueprintExtension = flagBlueprintType || (await this.promptForBlueprintType());
|
|
55
74
|
if (!blueprintExtension)
|
|
56
75
|
this.error('Blueprint type is required.');
|
|
57
|
-
|
|
58
|
-
if (!projectId)
|
|
59
|
-
this.error('Project ID is required.');
|
|
76
|
+
let projectId = flagProjectId;
|
|
60
77
|
let stackId = flagStackId;
|
|
78
|
+
if (!projectId) {
|
|
79
|
+
const pickedProject = await this.promptForProject();
|
|
80
|
+
projectId = pickedProject.projectId;
|
|
81
|
+
}
|
|
82
|
+
const auth = { token: this.sanityToken, projectId };
|
|
83
|
+
// LAUNCH LIMIT: 1 Stack per Project - do not prompt for Stack, just create one
|
|
84
|
+
if (LAUNCH_LIMIT_STACK_PER_PROJECT) {
|
|
85
|
+
const stack = await this.createProjectBasedStack(auth);
|
|
86
|
+
stackId = stack.id;
|
|
87
|
+
}
|
|
88
|
+
// while LAUNCH_LIMIT_STACK_PER_PROJECT is true, the stackId is already set
|
|
61
89
|
if (!stackId) {
|
|
62
90
|
if (flagStackName) {
|
|
63
91
|
const stack = await this.createEmptyStack({
|
|
64
92
|
stackPayload: { name: flagStackName, projectId, document: { resources: [] } },
|
|
65
|
-
auth
|
|
93
|
+
auth,
|
|
66
94
|
});
|
|
67
95
|
stackId = stack.id;
|
|
68
96
|
}
|
|
@@ -71,11 +99,14 @@ export default class Init extends Command {
|
|
|
71
99
|
}
|
|
72
100
|
}
|
|
73
101
|
const fileName = `blueprint.${blueprintExtension}`;
|
|
74
|
-
const filePath = join(
|
|
102
|
+
const filePath = join(dir, fileName);
|
|
103
|
+
if (dirProvided)
|
|
104
|
+
this.log(`New Blueprint created: ${dirProvided}/`);
|
|
75
105
|
writeBlueprintToDisk({ blueprintFilePath: filePath });
|
|
76
|
-
this.log(`Created new blueprint:
|
|
77
|
-
|
|
78
|
-
|
|
106
|
+
this.log(`Created new blueprint: ${dirProvided ?? '.'}/${fileName}`);
|
|
107
|
+
// LAUNCH LIMIT: 1 Stack per Project - do not persist stackId
|
|
108
|
+
writeConfigFile({ blueprintFilePath: filePath, projectId /*, stackId*/ });
|
|
109
|
+
this.log(`Created new config file: ${dirProvided ?? '.'}/.blueprint/config.json`);
|
|
79
110
|
if (blueprintExtension === 'ts') {
|
|
80
111
|
this.log('\nNote: TypeScript support requires "tsx" to be installed. Run: npm install -D tsx');
|
|
81
112
|
}
|
|
@@ -96,7 +127,7 @@ export default class Init extends Command {
|
|
|
96
127
|
]);
|
|
97
128
|
return pickedBlueprintsType;
|
|
98
129
|
}
|
|
99
|
-
async
|
|
130
|
+
async promptForProject() {
|
|
100
131
|
if (!this.sanityToken)
|
|
101
132
|
this.error('Unable to list projects. Missing API token.');
|
|
102
133
|
const { ok: projectsOk, error: projectsErr, projects, } = await listProjects({ token: this.sanityToken });
|
|
@@ -107,17 +138,17 @@ export default class Init extends Command {
|
|
|
107
138
|
}
|
|
108
139
|
const projectChoices = projects.map(({ displayName, id: projectId }) => ({
|
|
109
140
|
name: `"${displayName}" ${niceId(projectId)}`,
|
|
110
|
-
value: projectId,
|
|
141
|
+
value: { projectId, displayName },
|
|
111
142
|
}));
|
|
112
|
-
const {
|
|
143
|
+
const { pickedProject } = await inquirer.prompt([
|
|
113
144
|
{
|
|
114
145
|
type: 'list',
|
|
115
|
-
name: '
|
|
146
|
+
name: 'pickedProject',
|
|
116
147
|
message: 'Select your Sanity project:',
|
|
117
148
|
choices: projectChoices,
|
|
118
149
|
},
|
|
119
150
|
]);
|
|
120
|
-
return
|
|
151
|
+
return pickedProject;
|
|
121
152
|
}
|
|
122
153
|
async promptForStackId({ projectId }) {
|
|
123
154
|
if (!this.sanityToken)
|
|
@@ -137,7 +168,7 @@ export default class Init extends Command {
|
|
|
137
168
|
{
|
|
138
169
|
type: 'list',
|
|
139
170
|
name: 'pickedStackId',
|
|
140
|
-
message: 'Select
|
|
171
|
+
message: 'Select an existing deployment or create a new one:',
|
|
141
172
|
choices: stackChoices,
|
|
142
173
|
},
|
|
143
174
|
]);
|
|
@@ -161,7 +192,35 @@ export default class Init extends Command {
|
|
|
161
192
|
async createEmptyStack({ stackPayload, auth, }) {
|
|
162
193
|
const response = await createStack({ stackPayload, auth });
|
|
163
194
|
if (!response.ok)
|
|
164
|
-
this.error(response.error || 'Failed to create Stack');
|
|
195
|
+
this.error(response.error || 'Failed to create new Stack');
|
|
165
196
|
return response.stack;
|
|
166
197
|
}
|
|
198
|
+
// LAUNCH LIMIT: 1 Stack per Project - create exclusive stack for project
|
|
199
|
+
async createProjectBasedStack(auth) {
|
|
200
|
+
const { projectId } = auth;
|
|
201
|
+
// get project
|
|
202
|
+
const { ok: projectOk, project } = await getProject(auth);
|
|
203
|
+
if (!projectOk)
|
|
204
|
+
this.error('Failed to find Project while creating Stack');
|
|
205
|
+
const projectDisplayName = project.displayName;
|
|
206
|
+
// check if project has a stack
|
|
207
|
+
const inferredStackId = `ST-${projectId}`;
|
|
208
|
+
const { stack: existingStack, ok: stackOk } = await getStack({ stackId: inferredStackId, auth });
|
|
209
|
+
// if existing stack, return stack
|
|
210
|
+
if (stackOk && existingStack) {
|
|
211
|
+
this.warn(`Found existing deployment for "${projectDisplayName}" Blueprint`);
|
|
212
|
+
this.warn('Deploying an empty Blueprint will override the existing deployment.');
|
|
213
|
+
return existingStack;
|
|
214
|
+
}
|
|
215
|
+
// if not, create a stack
|
|
216
|
+
const stack = await this.createEmptyStack({
|
|
217
|
+
stackPayload: {
|
|
218
|
+
projectId,
|
|
219
|
+
name: projectDisplayName,
|
|
220
|
+
document: { resources: [] },
|
|
221
|
+
},
|
|
222
|
+
auth,
|
|
223
|
+
});
|
|
224
|
+
return stack;
|
|
225
|
+
}
|
|
167
226
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default class
|
|
1
|
+
import { DeployedBlueprintCommand } from '../../baseCommands.js';
|
|
2
|
+
export default class LogsCommand extends DeployedBlueprintCommand<typeof LogsCommand> {
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
5
|
static flags: {
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
2
|
import Spinner from 'yocto-spinner';
|
|
3
|
-
import { readBlueprintOnDisk } from '../../actions/blueprints/blueprint.js';
|
|
4
3
|
import { findNewestLogTimestamp, getLogs, getRecentLogs, isNewerLog, streamLogs, } from '../../actions/blueprints/logs.js';
|
|
4
|
+
import { DeployedBlueprintCommand } from '../../baseCommands.js';
|
|
5
5
|
import { formatTitle } from '../../utils/display/blueprints-formatting.js';
|
|
6
6
|
import { bold, niceId, red } from '../../utils/display/colors.js';
|
|
7
7
|
import { formatLogEntry, formatLogsByDay, organizeLogsByDay, } from '../../utils/display/logs-formatting.js';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
static description = 'Display logs for a Blueprint stack';
|
|
8
|
+
export default class LogsCommand extends DeployedBlueprintCommand {
|
|
9
|
+
static description = 'Display logs for a Blueprint deployment';
|
|
11
10
|
static examples = [
|
|
12
11
|
'<%= config.bin %> <%= command.id %>',
|
|
13
12
|
'<%= config.bin %> <%= command.id %> --watch',
|
|
@@ -21,32 +20,20 @@ export default class Logs extends Command {
|
|
|
21
20
|
}),
|
|
22
21
|
};
|
|
23
22
|
async run() {
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
this.
|
|
27
|
-
|
|
28
|
-
const watchMode = flags.watch;
|
|
23
|
+
const flags = this.flags;
|
|
24
|
+
const spinner = Spinner({
|
|
25
|
+
text: `Fetching recent logs for deployment ${niceId(this.stackId)}`,
|
|
26
|
+
}).start();
|
|
29
27
|
try {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
this.log('Blueprint parse errors:');
|
|
33
|
-
console.dir(errors, { depth: null });
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
if (!deployedStack)
|
|
37
|
-
this.error('Stack not found'); // returns
|
|
38
|
-
const { id: stackId, projectId, name } = deployedStack;
|
|
39
|
-
const auth = { token, projectId };
|
|
40
|
-
const spinner = Spinner({ text: `Fetching logs for stack ${niceId(stackId)}` }).start();
|
|
41
|
-
if (watchMode) {
|
|
42
|
-
const { ok, logs, error } = await getLogs(stackId, auth);
|
|
28
|
+
if (flags.watch) {
|
|
29
|
+
const { ok, logs, error } = await getLogs(this.stackId, this.auth);
|
|
43
30
|
if (!ok) {
|
|
44
31
|
spinner.error(`${red('Failed')} to retrieve logs`);
|
|
45
32
|
this.log(`Error: ${error || 'Unknown error'}`);
|
|
46
33
|
return;
|
|
47
34
|
}
|
|
48
|
-
spinner.stop().clear();
|
|
49
|
-
this.log(`${formatTitle('Blueprint', name)} ${niceId(stackId)} logs`);
|
|
35
|
+
spinner.stop().clear();
|
|
36
|
+
this.log(`${formatTitle('Blueprint', this.deployedStack.name)} ${niceId(this.stackId)} logs`);
|
|
50
37
|
if (logs.length > 0) {
|
|
51
38
|
this.log('\nMost recent logs:');
|
|
52
39
|
const recentLogs = getRecentLogs(logs);
|
|
@@ -55,7 +42,7 @@ export default class Logs extends Command {
|
|
|
55
42
|
}
|
|
56
43
|
}
|
|
57
44
|
else {
|
|
58
|
-
this.log(`No recent logs found for
|
|
45
|
+
this.log(`No recent logs found for deployment ${niceId(this.stackId)}`);
|
|
59
46
|
}
|
|
60
47
|
const onOpen = () => {
|
|
61
48
|
this.log(`Watching for new logs... ${bold('ctrl+c')} to stop`);
|
|
@@ -67,24 +54,23 @@ export default class Logs extends Command {
|
|
|
67
54
|
newestTimestamp = new Date(log.timestamp).getTime();
|
|
68
55
|
this.log(formatLogEntry(log, true));
|
|
69
56
|
};
|
|
70
|
-
this.
|
|
71
|
-
streamLogs(stackId, auth, renderLog, onOpen, (error) => this.log(`${red('Error:')} ${error}`));
|
|
57
|
+
streamLogs(this.stackId, this.auth, renderLog, onOpen, (error) => this.log(`${red('Error:')} ${error}`));
|
|
72
58
|
return new Promise(() => {
|
|
73
59
|
// hold the line until the user terminates with Ctrl+C
|
|
74
60
|
});
|
|
75
61
|
}
|
|
76
|
-
const { ok, logs, error } = await getLogs(stackId, auth);
|
|
62
|
+
const { ok, logs, error } = await getLogs(this.stackId, this.auth);
|
|
77
63
|
if (!ok) {
|
|
78
64
|
spinner.error(`${red('Failed')} to retrieve logs`);
|
|
79
65
|
this.log(`Error: ${error || 'Unknown error'}`);
|
|
80
66
|
return;
|
|
81
67
|
}
|
|
82
68
|
if (logs.length === 0) {
|
|
83
|
-
spinner.info(`No logs found for
|
|
69
|
+
spinner.info(`No logs found for deployment ${this.stackId}`);
|
|
84
70
|
return;
|
|
85
71
|
}
|
|
86
|
-
spinner.success(`${formatTitle('Blueprint', name)} Logs`);
|
|
87
|
-
this.log(`Found ${bold(logs.length.toString())} log entries for
|
|
72
|
+
spinner.success(`${formatTitle('Blueprint', this.deployedStack.name)} Logs`);
|
|
73
|
+
this.log(`Found ${bold(logs.length.toString())} log entries for deployment ${niceId(this.stackId)}\n`);
|
|
88
74
|
// Organize and format logs by day
|
|
89
75
|
const logsByDay = organizeLogsByDay(logs);
|
|
90
76
|
this.log(formatLogsByDay(logsByDay));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default class
|
|
1
|
+
import { BlueprintCommand } from '../../baseCommands.js';
|
|
2
|
+
export default class PlanCommand extends BlueprintCommand<typeof PlanCommand> {
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
5
|
run(): Promise<void>;
|
|
@@ -1,26 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { readBlueprintOnDisk } from '../../actions/blueprints/blueprint.js';
|
|
1
|
+
import { BlueprintCommand } from '../../baseCommands.js';
|
|
3
2
|
import { formatResourceTree, formatTitle } from '../../utils/display/blueprints-formatting.js';
|
|
4
|
-
import {
|
|
5
|
-
export default class
|
|
3
|
+
import { presentBlueprintParserErrors } from '../../utils/display/errors.js';
|
|
4
|
+
export default class PlanCommand extends BlueprintCommand {
|
|
6
5
|
static description = 'Enumerate resources to be deployed - will not modify any resources';
|
|
7
6
|
static examples = ['<%= config.bin %> <%= command.id %>'];
|
|
8
7
|
async run() {
|
|
9
|
-
const {
|
|
10
|
-
|
|
11
|
-
this.error(tokenErr.message);
|
|
12
|
-
const { errors, projectId, stackId, parsedBlueprint: { resources }, fileInfo, deployedStack, } = await readBlueprintOnDisk({ getStack: true, token });
|
|
8
|
+
const { parsedBlueprint, fileInfo, errors } = this.blueprint;
|
|
9
|
+
const { resources } = parsedBlueprint;
|
|
13
10
|
if (errors.length > 0) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
console.dir(errors, { depth: null });
|
|
11
|
+
this.log(presentBlueprintParserErrors(errors));
|
|
12
|
+
// continue to show plan
|
|
17
13
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const name = deployedStack?.name ?? stackId ?? 'Unknown';
|
|
21
|
-
this.log(`${formatTitle('Stack', name)} Plan`);
|
|
14
|
+
// TODO: compare local to existingStack
|
|
15
|
+
this.log(`${formatTitle('Deployment', 'Plan')}`);
|
|
22
16
|
this.log(`(${fileInfo.fileName})\n`);
|
|
23
17
|
this.log(formatResourceTree(resources));
|
|
24
|
-
this.log('\nRun `sanity blueprints deploy` to deploy these changes');
|
|
18
|
+
this.log('\nRun `sanity-run blueprints deploy` to deploy these changes');
|
|
25
19
|
}
|
|
26
20
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default class
|
|
1
|
+
import { BlueprintCommand } from '../../baseCommands.js';
|
|
2
|
+
export default class StacksCommand extends BlueprintCommand<typeof StacksCommand> {
|
|
3
|
+
static hidden: boolean;
|
|
3
4
|
static description: string;
|
|
4
5
|
static examples: string[];
|
|
5
6
|
static flags: {
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { readBlueprintOnDisk } from '../../actions/blueprints/blueprint.js';
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
3
2
|
import { listStacks } from '../../actions/blueprints/stacks.js';
|
|
3
|
+
import { BlueprintCommand } from '../../baseCommands.js';
|
|
4
4
|
import { formatStacksListing } from '../../utils/display/blueprints-formatting.js';
|
|
5
5
|
import { bold, niceId } from '../../utils/display/colors.js';
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
export default class StacksCommand extends BlueprintCommand {
|
|
7
|
+
// LAUNCH LIMIT: 1 Stack per Project - hide stacks command
|
|
8
|
+
static hidden = true;
|
|
8
9
|
static description = 'List all Blueprint stacks';
|
|
9
10
|
static examples = [
|
|
10
11
|
'<%= config.bin %> <%= command.id %>',
|
|
@@ -17,34 +18,14 @@ export default class Stacks extends Command {
|
|
|
17
18
|
}),
|
|
18
19
|
};
|
|
19
20
|
async run() {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
this.error(tokenErr.message);
|
|
23
|
-
const { flags } = await this.parse(Stacks);
|
|
24
|
-
let { projectId } = flags;
|
|
25
|
-
let stackId;
|
|
26
|
-
if (!projectId) {
|
|
27
|
-
try {
|
|
28
|
-
const { errors, projectId: projectIdFromBlueprint, stackId: stackIdFromBlueprint, } = await readBlueprintOnDisk();
|
|
29
|
-
if (errors.length > 0) {
|
|
30
|
-
this.log('Blueprint parse errors:');
|
|
31
|
-
console.dir(errors, { depth: null });
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
projectId = projectIdFromBlueprint;
|
|
35
|
-
stackId = stackIdFromBlueprint;
|
|
36
|
-
}
|
|
37
|
-
catch {
|
|
38
|
-
// continue to print error
|
|
39
|
-
}
|
|
40
|
-
}
|
|
21
|
+
const flags = this.flags;
|
|
22
|
+
const projectId = flags.projectId || this.blueprint.projectId;
|
|
41
23
|
if (!projectId) {
|
|
42
24
|
this.log('Unable to determine Project ID. Provide one with --projectId');
|
|
43
|
-
this.log('Or create a Blueprint with `sanity blueprints init`');
|
|
25
|
+
this.log('Or create a Blueprint with `sanity-run blueprints init`');
|
|
44
26
|
return;
|
|
45
27
|
}
|
|
46
|
-
const
|
|
47
|
-
const { ok, stacks, error } = await listStacks(auth);
|
|
28
|
+
const { ok, stacks, error } = await listStacks({ token: this.sanityToken, projectId });
|
|
48
29
|
if (!ok)
|
|
49
30
|
this.error(error || 'Failed to list stacks');
|
|
50
31
|
if (!stacks || stacks.length === 0) {
|
|
@@ -52,6 +33,6 @@ export default class Stacks extends Command {
|
|
|
52
33
|
return;
|
|
53
34
|
}
|
|
54
35
|
this.log(`${bold('Project')} ${niceId(projectId)} ${bold('Stacks')}:\n`);
|
|
55
|
-
this.log(formatStacksListing(stacks, stackId));
|
|
36
|
+
this.log(formatStacksListing(stacks, this.blueprint.stackId));
|
|
56
37
|
}
|
|
57
38
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default class
|
|
1
|
+
import { DeployedBlueprintCommand } from '../../../baseCommands.js';
|
|
2
|
+
export default class EnvAddCommand extends DeployedBlueprintCommand<typeof EnvAddCommand> {
|
|
3
3
|
static args: {
|
|
4
4
|
name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
5
|
key: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { Args
|
|
1
|
+
import { Args } from '@oclif/core';
|
|
2
2
|
import Spinner from 'yocto-spinner';
|
|
3
|
-
import { readBlueprintOnDisk } from '../../../actions/blueprints/blueprint.js';
|
|
4
3
|
import { update } from '../../../actions/functions/env/update.js';
|
|
4
|
+
import { DeployedBlueprintCommand } from '../../../baseCommands.js';
|
|
5
5
|
import { red } from '../../../utils/display/colors.js';
|
|
6
6
|
import { findFunctionByName } from '../../../utils/find-function.js';
|
|
7
|
-
|
|
8
|
-
export default class Add extends Command {
|
|
7
|
+
export default class EnvAddCommand extends DeployedBlueprintCommand {
|
|
9
8
|
static args = {
|
|
10
9
|
name: Args.string({ description: 'The name of the Sanity Function', required: true }),
|
|
11
10
|
key: Args.string({ description: 'The name of the environment variable', required: true }),
|
|
@@ -16,22 +15,12 @@ export default class Add extends Command {
|
|
|
16
15
|
'<%= config.bin %> <%= command.id %> MyFunction API_URL https://api.example.com/',
|
|
17
16
|
];
|
|
18
17
|
async run() {
|
|
19
|
-
const
|
|
20
|
-
if (tokenErr)
|
|
21
|
-
this.error(tokenErr.message);
|
|
22
|
-
const { args } = await this.parse(Add);
|
|
18
|
+
const args = this.args;
|
|
23
19
|
const spinner = Spinner({
|
|
24
20
|
text: `Updating "${args.key}" environment variable in "${args.name}"`,
|
|
25
21
|
}).start();
|
|
26
|
-
const {
|
|
27
|
-
|
|
28
|
-
this.error('Stack not found'); // returns
|
|
29
|
-
const { projectId } = deployedStack;
|
|
30
|
-
const { externalId } = findFunctionByName(deployedStack, args.name);
|
|
31
|
-
const result = await update(externalId, args.key, args.value, {
|
|
32
|
-
token,
|
|
33
|
-
projectId,
|
|
34
|
-
});
|
|
22
|
+
const { externalId } = findFunctionByName(this.deployedStack, args.name);
|
|
23
|
+
const result = await update(externalId, args.key, args.value, this.auth);
|
|
35
24
|
if (result.ok) {
|
|
36
25
|
spinner.success(`Update of ${args.key} succeeded`);
|
|
37
26
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default class
|
|
1
|
+
import { DeployedBlueprintCommand } from '../../../baseCommands.js';
|
|
2
|
+
export default class EnvListCommand extends DeployedBlueprintCommand<typeof EnvListCommand> {
|
|
3
3
|
static args: {
|
|
4
4
|
name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
5
|
};
|
|
@@ -1,31 +1,24 @@
|
|
|
1
|
-
import { Args
|
|
2
|
-
import
|
|
1
|
+
import { Args } from '@oclif/core';
|
|
2
|
+
import Spinner from 'yocto-spinner';
|
|
3
3
|
import { list } from '../../../actions/functions/env/list.js';
|
|
4
|
+
import { DeployedBlueprintCommand } from '../../../baseCommands.js';
|
|
4
5
|
import { findFunctionByName } from '../../../utils/find-function.js';
|
|
5
|
-
|
|
6
|
-
export default class List extends Command {
|
|
6
|
+
export default class EnvListCommand extends DeployedBlueprintCommand {
|
|
7
7
|
static args = {
|
|
8
8
|
name: Args.string({ description: 'The name of the Sanity Function', required: true }),
|
|
9
9
|
};
|
|
10
10
|
static description = 'List the environment variables for a Sanity function';
|
|
11
11
|
static examples = ['<%= config.bin %> <%= command.id %> MyFunction'];
|
|
12
12
|
async run() {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
const { deployedStack } = await readBlueprintOnDisk({ getStack: true, token });
|
|
18
|
-
if (!deployedStack)
|
|
19
|
-
this.error('Stack not found. Is it deployed?'); // returns
|
|
20
|
-
const { projectId } = deployedStack;
|
|
21
|
-
const { externalId } = findFunctionByName(deployedStack, args.name);
|
|
22
|
-
const result = await list(externalId, {
|
|
23
|
-
token,
|
|
24
|
-
projectId,
|
|
25
|
-
});
|
|
13
|
+
const args = this.args;
|
|
14
|
+
const spinner = Spinner({ text: `Listing environment variables for "${args.name}"` }).start();
|
|
15
|
+
const { externalId } = findFunctionByName(this.deployedStack, args.name);
|
|
16
|
+
const result = await list(externalId, this.auth);
|
|
26
17
|
if (!result.ok) {
|
|
18
|
+
spinner.stop().clear();
|
|
27
19
|
this.error(`Error: ${result.error || 'Unknown error'}`);
|
|
28
20
|
}
|
|
21
|
+
spinner.success(`Environment variables for "${args.name}"`);
|
|
29
22
|
for (const key of result.envvars) {
|
|
30
23
|
this.log(key);
|
|
31
24
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default class
|
|
1
|
+
import { DeployedBlueprintCommand } from '../../../baseCommands.js';
|
|
2
|
+
export default class EnvRemoveCommand extends DeployedBlueprintCommand<typeof EnvRemoveCommand> {
|
|
3
3
|
static args: {
|
|
4
4
|
name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
5
|
key: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { Args
|
|
1
|
+
import { Args } from '@oclif/core';
|
|
2
2
|
import Spinner from 'yocto-spinner';
|
|
3
|
-
import { readBlueprintOnDisk } from '../../../actions/blueprints/blueprint.js';
|
|
4
3
|
import { remove } from '../../../actions/functions/env/remove.js';
|
|
4
|
+
import { DeployedBlueprintCommand } from '../../../baseCommands.js';
|
|
5
5
|
import { red } from '../../../utils/display/colors.js';
|
|
6
6
|
import { findFunctionByName } from '../../../utils/find-function.js';
|
|
7
|
-
|
|
8
|
-
export default class Remove extends Command {
|
|
7
|
+
export default class EnvRemoveCommand extends DeployedBlueprintCommand {
|
|
9
8
|
static args = {
|
|
10
9
|
name: Args.string({ description: 'The name of the Sanity Function', required: true }),
|
|
11
10
|
key: Args.string({ description: 'The name of the environment variable', required: true }),
|
|
@@ -13,22 +12,12 @@ export default class Remove extends Command {
|
|
|
13
12
|
static description = 'Remove an environment variable for a Sanity function';
|
|
14
13
|
static examples = ['<%= config.bin %> <%= command.id %> MyFunction API_URL'];
|
|
15
14
|
async run() {
|
|
16
|
-
const
|
|
17
|
-
if (tokenErr)
|
|
18
|
-
this.error(tokenErr.message);
|
|
19
|
-
const { args } = await this.parse(Remove);
|
|
15
|
+
const args = this.args;
|
|
20
16
|
const spinner = Spinner({
|
|
21
17
|
text: `Removing "${args.key}" environment variable in "${args.name}"`,
|
|
22
18
|
}).start();
|
|
23
|
-
const {
|
|
24
|
-
|
|
25
|
-
this.error('Stack not found'); // returns
|
|
26
|
-
const { projectId } = deployedStack;
|
|
27
|
-
const { externalId } = findFunctionByName(deployedStack, args.name);
|
|
28
|
-
const result = await remove(externalId, args.key, {
|
|
29
|
-
token,
|
|
30
|
-
projectId,
|
|
31
|
-
});
|
|
19
|
+
const { externalId } = findFunctionByName(this.deployedStack, args.name);
|
|
20
|
+
const result = await remove(externalId, args.key, this.auth);
|
|
32
21
|
if (result.ok) {
|
|
33
22
|
spinner.success(`Removal of ${args.key} succeeded`);
|
|
34
23
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default class
|
|
1
|
+
import { DeployedBlueprintCommand } from '../../baseCommands.js';
|
|
2
|
+
export default class InvokeCommand extends DeployedBlueprintCommand<typeof InvokeCommand> {
|
|
3
3
|
static args: {
|
|
4
4
|
name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
5
|
};
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { Args,
|
|
1
|
+
import { Args, Flags } from '@oclif/core';
|
|
2
2
|
import Spinner from 'yocto-spinner';
|
|
3
|
-
import { readBlueprintOnDisk } from '../../actions/blueprints/blueprint.js';
|
|
4
3
|
import { invoke } from '../../actions/functions/invoke.js';
|
|
4
|
+
import { DeployedBlueprintCommand } from '../../baseCommands.js';
|
|
5
5
|
import { red } from '../../utils/display/colors.js';
|
|
6
6
|
import { findFunctionByName } from '../../utils/find-function.js';
|
|
7
|
-
|
|
8
|
-
export default class Invoke extends Command {
|
|
7
|
+
export default class InvokeCommand extends DeployedBlueprintCommand {
|
|
9
8
|
static args = {
|
|
10
9
|
name: Args.string({ description: 'The name of the Sanity Function', required: true }),
|
|
11
10
|
};
|
|
@@ -23,17 +22,11 @@ export default class Invoke extends Command {
|
|
|
23
22
|
}),
|
|
24
23
|
};
|
|
25
24
|
async run() {
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
this.error(tokenErr.message);
|
|
29
|
-
const { args, flags } = await this.parse(Invoke);
|
|
25
|
+
const args = this.args;
|
|
26
|
+
const flags = this.flags;
|
|
30
27
|
const spinner = Spinner({ text: `Invoking function "${args.name}"` }).start();
|
|
31
|
-
const {
|
|
32
|
-
|
|
33
|
-
this.error('Stack not found'); // returns
|
|
34
|
-
const { projectId } = deployedStack;
|
|
35
|
-
const { externalId } = findFunctionByName(deployedStack, args.name);
|
|
36
|
-
const result = await invoke(externalId, { data: flags.data, file: flags.file }, { token, projectId });
|
|
28
|
+
const { externalId } = findFunctionByName(this.deployedStack, args.name);
|
|
29
|
+
const result = await invoke(externalId, { data: flags.data, file: flags.file }, this.auth);
|
|
37
30
|
if (result.ok) {
|
|
38
31
|
spinner.success(`Invocation of ${args.name} succeeded`);
|
|
39
32
|
if (result.json?.data?.type === 'Buffer') {
|