@sanity/runtime-cli 11.2.1 → 12.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 +36 -38
- package/dist/actions/blueprints/blueprint.d.ts +3 -0
- package/dist/actions/blueprints/blueprint.js +26 -14
- package/dist/actions/blueprints/config.d.ts +34 -3
- package/dist/actions/blueprints/config.js +67 -14
- package/dist/actions/blueprints/stacks.d.ts +1 -2
- package/dist/actions/blueprints/stacks.js +2 -3
- package/dist/commands/blueprints/config.d.ts +0 -1
- package/dist/commands/blueprints/config.js +4 -12
- package/dist/commands/blueprints/deploy.js +1 -1
- package/dist/commands/blueprints/destroy.js +3 -3
- package/dist/commands/blueprints/info.js +2 -2
- package/dist/commands/blueprints/init.d.ts +1 -0
- package/dist/commands/blueprints/init.js +4 -0
- package/dist/commands/blueprints/logs.js +2 -2
- package/dist/commands/blueprints/plan.js +1 -0
- package/dist/config.d.ts +2 -1
- package/dist/config.js +8 -1
- package/dist/cores/blueprints/config.d.ts +1 -1
- package/dist/cores/blueprints/config.js +92 -78
- package/dist/cores/blueprints/deploy.js +8 -8
- package/dist/cores/blueprints/destroy.d.ts +1 -0
- package/dist/cores/blueprints/destroy.js +22 -26
- package/dist/cores/blueprints/doctor.js +24 -72
- package/dist/cores/blueprints/info.d.ts +1 -0
- package/dist/cores/blueprints/info.js +5 -4
- package/dist/cores/blueprints/init.d.ts +1 -1
- package/dist/cores/blueprints/init.js +50 -78
- package/dist/cores/blueprints/logs.d.ts +1 -0
- package/dist/cores/blueprints/logs.js +7 -7
- package/dist/cores/blueprints/plan.d.ts +3 -0
- package/dist/cores/blueprints/plan.js +5 -4
- package/dist/cores/blueprints/stacks.d.ts +1 -0
- package/dist/cores/blueprints/stacks.js +1 -2
- package/dist/cores/functions/add.js +58 -70
- package/dist/cores/functions/logs.js +2 -4
- package/dist/cores/index.js +3 -3
- package/dist/utils/display/blueprints-formatting.js +8 -3
- package/dist/utils/display/errors.js +2 -2
- package/dist/utils/display/presenters.d.ts +2 -0
- package/dist/utils/display/presenters.js +7 -0
- package/dist/utils/display/prompt.d.ts +14 -2
- package/dist/utils/display/prompt.js +60 -41
- package/dist/utils/types.d.ts +0 -1
- package/oclif.manifest.json +19 -26
- package/package.json +4 -3
|
@@ -1,23 +1,20 @@
|
|
|
1
1
|
import { cwd } from 'node:process';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
-
import inquirer from 'inquirer';
|
|
4
|
-
import ora from 'ora';
|
|
5
3
|
import { findBlueprintFile, readLocalBlueprint, } from '../../actions/blueprints/blueprint.js';
|
|
6
|
-
import {
|
|
7
|
-
import { getProject } from '../../actions/sanity/projects.js';
|
|
4
|
+
import { getStack } from '../../actions/blueprints/stacks.js';
|
|
8
5
|
import config from '../../config.js';
|
|
9
|
-
import { capitalize, check, indent, niceId, severe,
|
|
6
|
+
import { capitalize, check, filePathRelativeToCwd, indent, niceId, severe, unsure, } from '../../utils/display/presenters.js';
|
|
10
7
|
import { validTokenOrErrorMessage } from '../../utils/validated-token.js';
|
|
11
8
|
const diagLookup = {
|
|
12
9
|
online: 'Online',
|
|
13
10
|
tokenPresent: 'Auth token present',
|
|
14
11
|
tokenValid: 'Auth token valid',
|
|
15
|
-
configFilePresent: '
|
|
16
|
-
configFileValid: '
|
|
12
|
+
configFilePresent: 'Blueprint config file present',
|
|
13
|
+
configFileValid: 'Blueprint config file valid',
|
|
17
14
|
blueprintPresent: 'Blueprint file present',
|
|
18
15
|
blueprintValid: 'Blueprint file valid',
|
|
19
|
-
stackReady: '
|
|
20
|
-
userHasAccess: 'User has access to "Stack"',
|
|
16
|
+
stackReady: 'Stack deployment ready',
|
|
17
|
+
userHasAccess: 'User has access to deployed "Stack"',
|
|
21
18
|
};
|
|
22
19
|
export async function blueprintDoctorCore(options) {
|
|
23
20
|
const { log, token, flags: { verbose: v, path: p }, } = options;
|
|
@@ -27,15 +24,12 @@ export async function blueprintDoctorCore(options) {
|
|
|
27
24
|
const here = cwd();
|
|
28
25
|
const path = p || here;
|
|
29
26
|
if (v)
|
|
30
|
-
log(`Checking ${path}`);
|
|
27
|
+
log(`Checking ${filePathRelativeToCwd(path)}`);
|
|
31
28
|
// 3 states: null == unknown, true == good, false == bad
|
|
32
29
|
const diagnostics = {};
|
|
33
30
|
for (const key in diagLookup) {
|
|
34
31
|
diagnostics[key] = null;
|
|
35
32
|
}
|
|
36
|
-
let spinner;
|
|
37
|
-
if (!v)
|
|
38
|
-
spinner = ora('Checking environment').start();
|
|
39
33
|
// ONLINE
|
|
40
34
|
try {
|
|
41
35
|
const res = await fetch(config.apiUrl);
|
|
@@ -45,14 +39,12 @@ export async function blueprintDoctorCore(options) {
|
|
|
45
39
|
diagnostics.online = res.ok;
|
|
46
40
|
}
|
|
47
41
|
else {
|
|
48
|
-
|
|
49
|
-
yikes(`Failed to ping ${config.apiUrl}: ${res.status} ${res.statusText}`);
|
|
42
|
+
yikes(`Failed to ping ${config.apiUrl}: ${res.status} ${res.statusText}`);
|
|
50
43
|
diagnostics.online = false;
|
|
51
44
|
}
|
|
52
45
|
}
|
|
53
46
|
catch {
|
|
54
|
-
|
|
55
|
-
yikes(`Failed to ping ${config.apiUrl}`);
|
|
47
|
+
yikes(`Failed to ping ${config.apiUrl}`);
|
|
56
48
|
}
|
|
57
49
|
// TOKEN
|
|
58
50
|
if (token) {
|
|
@@ -62,8 +54,7 @@ export async function blueprintDoctorCore(options) {
|
|
|
62
54
|
diagnostics.tokenValid = true;
|
|
63
55
|
}
|
|
64
56
|
else {
|
|
65
|
-
|
|
66
|
-
yikes(`Token error: ${tokenOrError.error}`);
|
|
57
|
+
yikes(`Token error: ${tokenOrError.error}`);
|
|
67
58
|
diagnostics.tokenValid = false;
|
|
68
59
|
}
|
|
69
60
|
}
|
|
@@ -136,35 +127,34 @@ export async function blueprintDoctorCore(options) {
|
|
|
136
127
|
diagnostics.userHasAccess = true;
|
|
137
128
|
}
|
|
138
129
|
else if (stackResponse.response?.status === 404) {
|
|
139
|
-
|
|
140
|
-
yikes(`Deployment "Stack" <${stackId}> not found`);
|
|
130
|
+
yikes(`Deployment "Stack" <${stackId}> not found`);
|
|
141
131
|
diagnostics.stackReady = false;
|
|
142
132
|
}
|
|
143
133
|
else if (stackResponse.response?.status === 403 || stackResponse.response?.status === 401) {
|
|
144
|
-
|
|
145
|
-
yikes(`User does not have access to "Stack" <${stackId}>`);
|
|
134
|
+
yikes(`User does not have access to "Stack" <${stackId}>`);
|
|
146
135
|
diagnostics.userHasAccess = false;
|
|
147
136
|
}
|
|
148
137
|
else {
|
|
149
|
-
|
|
150
|
-
yikes(`Unknown error with "Stack" <${stackId}>: ${stackResponse.error}`);
|
|
138
|
+
yikes(`Unknown error with "Stack" <${stackId}>: ${stackResponse.error}`);
|
|
151
139
|
}
|
|
152
140
|
}
|
|
153
141
|
else {
|
|
154
|
-
if (
|
|
155
|
-
yikes('Unable to
|
|
142
|
+
if (!diagnostics.online)
|
|
143
|
+
yikes('Unable to connect to Sanity API.');
|
|
144
|
+
if (!diagnostics.tokenValid)
|
|
145
|
+
yikes('Invalid authentication token.');
|
|
146
|
+
if (!stackId)
|
|
147
|
+
yikes(`Blueprints configuration is missing a Stack ID`);
|
|
148
|
+
if (!projectId)
|
|
149
|
+
yikes(`Blueprints configuration is missing a Project ID`);
|
|
156
150
|
}
|
|
157
151
|
}
|
|
158
|
-
|
|
159
|
-
spinner.stop();
|
|
160
|
-
if (v)
|
|
161
|
-
log('');
|
|
152
|
+
log('');
|
|
162
153
|
let allGood = true;
|
|
163
154
|
for (const [key, value] of Object.entries(diagnostics)) {
|
|
164
155
|
switch (value) {
|
|
165
156
|
case true:
|
|
166
|
-
|
|
167
|
-
log(check(diagLookup[key]));
|
|
157
|
+
log(check(diagLookup[key]));
|
|
168
158
|
break;
|
|
169
159
|
case false:
|
|
170
160
|
allGood = false;
|
|
@@ -172,7 +162,7 @@ export async function blueprintDoctorCore(options) {
|
|
|
172
162
|
break;
|
|
173
163
|
case null:
|
|
174
164
|
allGood = false;
|
|
175
|
-
log(
|
|
165
|
+
log(unsure(diagLookup[key]));
|
|
176
166
|
break;
|
|
177
167
|
default:
|
|
178
168
|
allGood = false;
|
|
@@ -187,41 +177,3 @@ export async function blueprintDoctorCore(options) {
|
|
|
187
177
|
return { success: false, error: 'One or more checks failed', data: { diagnostics } };
|
|
188
178
|
}
|
|
189
179
|
}
|
|
190
|
-
// copied from old config --edit --test flow
|
|
191
|
-
async function _startReinitializeStack({ token, projectId, }) {
|
|
192
|
-
const auth = { token, scopeType: 'project', scopeId: projectId };
|
|
193
|
-
// stack id IS ST-${projectId} – it has already been checked and doesn't exist
|
|
194
|
-
const { confirm } = await inquirer.prompt([
|
|
195
|
-
{
|
|
196
|
-
type: 'confirm',
|
|
197
|
-
name: 'confirm',
|
|
198
|
-
message: `Do you want to create a ${chalk.blue('new')}, empty Blueprint deployment with the ${chalk.blue('existing')} configuration?`,
|
|
199
|
-
},
|
|
200
|
-
]);
|
|
201
|
-
if (!confirm)
|
|
202
|
-
return { ok: false, error: 'Reinitialization cancelled' };
|
|
203
|
-
const { ok: projectOk, project, error: projectError } = await getProject(auth);
|
|
204
|
-
if (!projectOk) {
|
|
205
|
-
return {
|
|
206
|
-
ok: false,
|
|
207
|
-
error: projectError || 'Failed to find Project while creating Stack',
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
const projectDisplayName = project.displayName;
|
|
211
|
-
const response = await createStack({
|
|
212
|
-
stackMutation: {
|
|
213
|
-
name: projectDisplayName,
|
|
214
|
-
scopeType: 'project',
|
|
215
|
-
scopeId: projectId,
|
|
216
|
-
document: { resources: [] },
|
|
217
|
-
},
|
|
218
|
-
auth,
|
|
219
|
-
});
|
|
220
|
-
if (!response.ok)
|
|
221
|
-
return { ok: false, error: response.error || 'Failed to create new Stack' };
|
|
222
|
-
return {
|
|
223
|
-
ok: true,
|
|
224
|
-
stackId: response.stack.id,
|
|
225
|
-
projectDisplayName,
|
|
226
|
-
};
|
|
227
|
-
}
|
|
@@ -3,16 +3,17 @@ import { formatResourceTree, formatStackInfo } from '../../utils/display/bluepri
|
|
|
3
3
|
import { niceId } from '../../utils/display/presenters.js';
|
|
4
4
|
export async function blueprintInfoCore(options) {
|
|
5
5
|
const { log, auth, stackId, flags, deployedStack } = options;
|
|
6
|
+
const { id: flagStackId, verbose: _verbose = false } = flags;
|
|
6
7
|
try {
|
|
7
|
-
const targetStackId =
|
|
8
|
+
const targetStackId = flagStackId || stackId;
|
|
8
9
|
let stack = deployedStack;
|
|
9
|
-
if (
|
|
10
|
+
if (flagStackId) {
|
|
10
11
|
const existingStackResponse = await getStack({ stackId: targetStackId, auth });
|
|
11
12
|
if (!existingStackResponse.ok) {
|
|
12
|
-
log(`Could not retrieve deployment info for ${niceId(targetStackId)}`);
|
|
13
|
+
log(`Could not retrieve Stack deployment info for ${niceId(targetStackId)}`);
|
|
13
14
|
return {
|
|
14
15
|
success: false,
|
|
15
|
-
error: existingStackResponse.error || 'Failed to retrieve
|
|
16
|
+
error: existingStackResponse.error || 'Failed to retrieve Stack deployment',
|
|
16
17
|
};
|
|
17
18
|
}
|
|
18
19
|
stack = existingStackResponse.stack;
|
|
@@ -13,6 +13,7 @@ export interface BlueprintInitOptions extends CoreConfig {
|
|
|
13
13
|
'organization-id'?: string;
|
|
14
14
|
'stack-id'?: string;
|
|
15
15
|
'stack-name'?: string;
|
|
16
|
+
verbose?: boolean;
|
|
16
17
|
};
|
|
17
18
|
}
|
|
18
19
|
export declare function blueprintInitCore(options: BlueprintInitOptions): Promise<CoreResult>;
|
|
@@ -33,7 +34,6 @@ export declare function resolveScopeAndStack(params: {
|
|
|
33
34
|
stackId: string | undefined;
|
|
34
35
|
stackName: string | undefined;
|
|
35
36
|
token: string;
|
|
36
|
-
log: (message: string) => void;
|
|
37
37
|
}): Promise<ResolvedScope>;
|
|
38
38
|
export declare function determineBlueprintExtension(params: {
|
|
39
39
|
requestedType: string | undefined;
|
|
@@ -1,38 +1,58 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
|
+
import { confirm } from '@inquirer/prompts';
|
|
3
4
|
import chalk from 'chalk';
|
|
4
|
-
import
|
|
5
|
-
import { findBlueprintFile, writeBlueprintToDisk } from '../../actions/blueprints/blueprint.js';
|
|
5
|
+
import { findBlueprintFile, readLocalBlueprint, writeBlueprintToDisk, } from '../../actions/blueprints/blueprint.js';
|
|
6
6
|
import { writeConfigFile } from '../../actions/blueprints/config.js';
|
|
7
|
-
import { createEmptyStack
|
|
7
|
+
import { createEmptyStack } from '../../actions/blueprints/stacks.js';
|
|
8
8
|
import { writeGitignoreFile } from '../../actions/git.js';
|
|
9
9
|
import { writeOrUpdateNodeDependency } from '../../actions/node.js';
|
|
10
10
|
import { verifyExampleExists, writeExample } from '../../actions/sanity/examples.js';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
11
|
+
import { BLUEPRINT_CONFIG_DIR, BLUEPRINT_CONFIG_FILE } from '../../config.js';
|
|
12
|
+
import { check, filePathRelativeToCwd, warn } from '../../utils/display/presenters.js';
|
|
13
|
+
import { promptForBlueprintType, promptForProject, promptForStack, } from '../../utils/display/prompt.js';
|
|
14
|
+
import { blueprintConfigCore } from './config.js';
|
|
15
15
|
const SCOPE_PROJECT = 'project';
|
|
16
16
|
const SCOPE_ORGANIZATION = 'organization';
|
|
17
17
|
export async function blueprintInitCore(options) {
|
|
18
18
|
const { bin = 'sanity', log, token, args, flags } = options;
|
|
19
|
+
const { dir: flagDir, example: flagExample, 'blueprint-type': flagBlueprintType, 'project-id': flagProjectId, 'organization-id': flagOrganizationId, 'stack-id': flagStackId, 'stack-name': flagStackName, verbose: v = false, } = flags;
|
|
20
|
+
const { dir: argDir } = args;
|
|
21
|
+
const userProvidedDirName = argDir || flagDir;
|
|
22
|
+
const blueprintDir = userProvidedDirName || '.';
|
|
23
|
+
const validationError = validateFlags({
|
|
24
|
+
stackId: flagStackId,
|
|
25
|
+
stackName: flagStackName,
|
|
26
|
+
organizationId: flagOrganizationId,
|
|
27
|
+
projectId: flagProjectId,
|
|
28
|
+
});
|
|
29
|
+
if (validationError)
|
|
30
|
+
return validationError;
|
|
19
31
|
try {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
const existingBlueprintFile = findBlueprintFile(blueprintDir);
|
|
33
|
+
if (existingBlueprintFile) {
|
|
34
|
+
log(warn(`Existing Blueprint found: ${filePathRelativeToCwd(existingBlueprintFile.blueprintFilePath)}`));
|
|
35
|
+
const overwrite = await confirm({
|
|
36
|
+
message: 'Would you like to re-configure deployment for this Blueprint?',
|
|
37
|
+
default: true,
|
|
38
|
+
});
|
|
39
|
+
if (!overwrite)
|
|
40
|
+
return { success: false, error: 'Initialization cancelled.' };
|
|
41
|
+
const existingBlueprint = await readLocalBlueprint(existingBlueprintFile.blueprintFilePath);
|
|
42
|
+
return blueprintConfigCore({
|
|
43
|
+
blueprint: existingBlueprint,
|
|
44
|
+
bin,
|
|
45
|
+
log,
|
|
46
|
+
token,
|
|
47
|
+
flags: {
|
|
48
|
+
edit: true,
|
|
49
|
+
'project-id': flagProjectId,
|
|
50
|
+
'organization-id': flagOrganizationId,
|
|
51
|
+
'stack-id': flagStackId,
|
|
52
|
+
verbose: v,
|
|
53
|
+
},
|
|
54
|
+
});
|
|
27
55
|
}
|
|
28
|
-
const validationError = validateFlags({
|
|
29
|
-
stackId: flagStackId,
|
|
30
|
-
stackName: flagStackName,
|
|
31
|
-
organizationId: flagOrganizationId,
|
|
32
|
-
projectId: flagProjectId,
|
|
33
|
-
});
|
|
34
|
-
if (validationError)
|
|
35
|
-
return validationError;
|
|
36
56
|
if (flagExample) {
|
|
37
57
|
return handleExampleInitialization({
|
|
38
58
|
exampleName: flagExample,
|
|
@@ -49,7 +69,6 @@ export async function blueprintInitCore(options) {
|
|
|
49
69
|
stackId: flagStackId,
|
|
50
70
|
stackName: flagStackName,
|
|
51
71
|
token,
|
|
52
|
-
log,
|
|
53
72
|
});
|
|
54
73
|
const blueprintExtension = await determineBlueprintExtension({
|
|
55
74
|
requestedType: flagBlueprintType,
|
|
@@ -95,7 +114,6 @@ async function handleExampleInitialization(options) {
|
|
|
95
114
|
scopeType: SCOPE_PROJECT,
|
|
96
115
|
scopeId: resolvedProjectId,
|
|
97
116
|
name: `example-${exampleName}`,
|
|
98
|
-
projectBased: false,
|
|
99
117
|
});
|
|
100
118
|
const exampleDir = userProvidedDirName || join(blueprintDir, exampleName);
|
|
101
119
|
if (existsSync(exampleDir)) {
|
|
@@ -119,7 +137,7 @@ async function handleExampleInitialization(options) {
|
|
|
119
137
|
}
|
|
120
138
|
const { blueprintFilePath } = discoveredBlueprint;
|
|
121
139
|
writeConfigFile({ blueprintFilePath, projectId: resolvedProjectId, stackId: stack.id });
|
|
122
|
-
log(check(`${chalk.bold('Configured:')} ${exampleDir}/${
|
|
140
|
+
log(check(`${chalk.bold('Configured:')} ${exampleDir}/${BLUEPRINT_CONFIG_DIR}/${BLUEPRINT_CONFIG_FILE}`));
|
|
123
141
|
log(`\n Run "${chalk.bold.magenta(`cd ${exampleDir} && npm i`)}" and check out the README`);
|
|
124
142
|
if (instructions) {
|
|
125
143
|
log('');
|
|
@@ -128,7 +146,7 @@ async function handleExampleInitialization(options) {
|
|
|
128
146
|
return { success: true };
|
|
129
147
|
}
|
|
130
148
|
export async function resolveScopeAndStack(params) {
|
|
131
|
-
const { projectId, organizationId, stackId, stackName, token
|
|
149
|
+
const { projectId, organizationId, stackId, stackName, token } = params;
|
|
132
150
|
let scopeType = SCOPE_PROJECT;
|
|
133
151
|
let scopeId;
|
|
134
152
|
if (projectId) {
|
|
@@ -147,7 +165,6 @@ export async function resolveScopeAndStack(params) {
|
|
|
147
165
|
scopeType,
|
|
148
166
|
scopeId,
|
|
149
167
|
name: stackName,
|
|
150
|
-
projectBased: false,
|
|
151
168
|
});
|
|
152
169
|
resolvedStackId = stack.id;
|
|
153
170
|
}
|
|
@@ -157,7 +174,8 @@ export async function resolveScopeAndStack(params) {
|
|
|
157
174
|
scopeId = pickedProject.projectId;
|
|
158
175
|
}
|
|
159
176
|
if (!resolvedStackId) {
|
|
160
|
-
await
|
|
177
|
+
const { stackId } = await promptForStack({ projectId: scopeId, token });
|
|
178
|
+
resolvedStackId = stackId;
|
|
161
179
|
}
|
|
162
180
|
return {
|
|
163
181
|
scopeType,
|
|
@@ -167,7 +185,9 @@ export async function resolveScopeAndStack(params) {
|
|
|
167
185
|
}
|
|
168
186
|
export async function determineBlueprintExtension(params) {
|
|
169
187
|
const { requestedType, blueprintDir } = params;
|
|
170
|
-
|
|
188
|
+
let extension = requestedType;
|
|
189
|
+
if (!extension)
|
|
190
|
+
extension = await promptForBlueprintType();
|
|
171
191
|
if (extension === 'js') {
|
|
172
192
|
const packageJsonPath = join(blueprintDir, 'package.json');
|
|
173
193
|
const packageExists = existsSync(packageJsonPath);
|
|
@@ -202,7 +222,7 @@ export async function createBlueprintFiles(params) {
|
|
|
202
222
|
stackId,
|
|
203
223
|
...(scopeType === SCOPE_ORGANIZATION ? { organizationId: scopeId } : { projectId: scopeId }),
|
|
204
224
|
});
|
|
205
|
-
log(check(`${chalk.bold('Added configuration:')} ${displayPath}/${
|
|
225
|
+
log(check(`${chalk.bold('Added configuration:')} ${displayPath}/${BLUEPRINT_CONFIG_DIR}/${BLUEPRINT_CONFIG_FILE}`));
|
|
206
226
|
writeGitignoreFile(blueprintFilePath);
|
|
207
227
|
log(check(`${chalk.bold('Added .gitignore:')} ${displayPath}/.gitignore`));
|
|
208
228
|
if (blueprintExtension !== 'json') {
|
|
@@ -224,51 +244,3 @@ export async function createBlueprintFiles(params) {
|
|
|
224
244
|
log(`\n Run "${chalk.bold.magenta(nextStepParts.join(' && '))}" to get started`);
|
|
225
245
|
return { success: true };
|
|
226
246
|
}
|
|
227
|
-
async function promptForBlueprintType() {
|
|
228
|
-
const { pickedBlueprintsType } = await inquirer.prompt([
|
|
229
|
-
{
|
|
230
|
-
type: 'list',
|
|
231
|
-
name: 'pickedBlueprintsType',
|
|
232
|
-
message: 'Choose a Blueprint file type:',
|
|
233
|
-
choices: [
|
|
234
|
-
{ name: 'TypeScript', value: 'ts' },
|
|
235
|
-
{ name: 'JavaScript', value: 'js' },
|
|
236
|
-
{ name: 'JSON', value: 'json' },
|
|
237
|
-
],
|
|
238
|
-
default: 'ts',
|
|
239
|
-
},
|
|
240
|
-
]);
|
|
241
|
-
return pickedBlueprintsType;
|
|
242
|
-
}
|
|
243
|
-
// LAUNCH LIMIT: 1 Stack per Project - create exclusive stack for project
|
|
244
|
-
async function getOrCreateProjectBasedStack(params) {
|
|
245
|
-
const { projectId, token, log } = params;
|
|
246
|
-
const { ok: projectOk, project } = await getProject({
|
|
247
|
-
token,
|
|
248
|
-
scopeType: SCOPE_PROJECT,
|
|
249
|
-
scopeId: projectId,
|
|
250
|
-
});
|
|
251
|
-
if (!projectOk) {
|
|
252
|
-
throw new Error('Failed to find Project while creating Stack');
|
|
253
|
-
}
|
|
254
|
-
// check if project has a stack
|
|
255
|
-
const { stack: existingStack, ok: stackOk } = await getStack({
|
|
256
|
-
auth: { token, scopeType: SCOPE_PROJECT, scopeId: projectId },
|
|
257
|
-
stackId: `ST-${projectId}`,
|
|
258
|
-
});
|
|
259
|
-
// if existing stack, return stack
|
|
260
|
-
if (stackOk && existingStack) {
|
|
261
|
-
log(warn(`"${project.displayName}" has an existing deployment.`));
|
|
262
|
-
log(warn(`Deploying an empty Blueprint ${chalk.bold.red('will override the existing deployment!')}`));
|
|
263
|
-
log('');
|
|
264
|
-
return existingStack;
|
|
265
|
-
}
|
|
266
|
-
// if not, create a stack
|
|
267
|
-
const stack = await createEmptyStack({
|
|
268
|
-
token,
|
|
269
|
-
scopeType: SCOPE_PROJECT,
|
|
270
|
-
scopeId: projectId,
|
|
271
|
-
name: project.displayName,
|
|
272
|
-
});
|
|
273
|
-
return stack;
|
|
274
|
-
}
|
|
@@ -7,8 +7,8 @@ import { formatLogEntry, formatLogsByDay, organizeLogsByDay, } from '../../utils
|
|
|
7
7
|
import { niceId } from '../../utils/display/presenters.js';
|
|
8
8
|
export async function blueprintLogsCore(options) {
|
|
9
9
|
const { log, auth, stackId, deployedStack, flags } = options;
|
|
10
|
-
const { watch = false } = flags;
|
|
11
|
-
const spinner = ora(`Fetching recent logs for deployment ${niceId(stackId)}`).start();
|
|
10
|
+
const { watch = false, verbose: _verbose = false } = flags;
|
|
11
|
+
const spinner = ora(`Fetching recent logs for Stack deployment ${niceId(stackId)}`).start();
|
|
12
12
|
try {
|
|
13
13
|
if (watch) {
|
|
14
14
|
const { ok, logs, error } = await getLogs(stackId, auth);
|
|
@@ -27,7 +27,7 @@ export async function blueprintLogsCore(options) {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
else {
|
|
30
|
-
log(`No recent logs found for deployment ${niceId(stackId)}`);
|
|
30
|
+
log(`No recent logs found for Stack deployment ${niceId(stackId)}`);
|
|
31
31
|
}
|
|
32
32
|
// Set up streaming log display
|
|
33
33
|
await setupLogStreaming({
|
|
@@ -45,23 +45,23 @@ export async function blueprintLogsCore(options) {
|
|
|
45
45
|
// Regular non-streaming logs
|
|
46
46
|
const { ok, logs, error } = await getLogs(stackId, auth);
|
|
47
47
|
if (!ok) {
|
|
48
|
-
spinner.fail(`${chalk.red('Failed')} to retrieve logs`);
|
|
48
|
+
spinner.fail(`${chalk.red('Failed')} to retrieve Stack deployment logs`);
|
|
49
49
|
log(`Error: ${error || 'Unknown error'}`);
|
|
50
50
|
return { success: false, error: error || 'Failed to retrieve logs' };
|
|
51
51
|
}
|
|
52
52
|
if (logs.length === 0) {
|
|
53
|
-
spinner.info(`No logs found for deployment ${stackId}`);
|
|
53
|
+
spinner.info(`No logs found for Stack deployment ${stackId}`);
|
|
54
54
|
return { success: true };
|
|
55
55
|
}
|
|
56
56
|
spinner.succeed(`${formatTitle('Blueprint', deployedStack.name)} Logs`);
|
|
57
|
-
log(`Found ${chalk.bold(logs.length.toString())} log entries for deployment ${niceId(stackId)}\n`);
|
|
57
|
+
log(`Found ${chalk.bold(logs.length.toString())} log entries for Stack deployment ${niceId(stackId)}\n`);
|
|
58
58
|
// Organize and format logs by day
|
|
59
59
|
const logsByDay = organizeLogsByDay(logs);
|
|
60
60
|
log(formatLogsByDay(logsByDay));
|
|
61
61
|
return { success: true };
|
|
62
62
|
}
|
|
63
63
|
catch (err) {
|
|
64
|
-
spinner.fail('Failed to retrieve logs');
|
|
64
|
+
spinner.fail('Failed to retrieve Stack deployment logs');
|
|
65
65
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
66
66
|
log(`Error: ${errorMessage}`);
|
|
67
67
|
return { success: false, error: errorMessage };
|
|
@@ -3,5 +3,8 @@ import type { CoreConfig, CoreResult } from '../index.js';
|
|
|
3
3
|
export interface BlueprintPlanOptions extends CoreConfig {
|
|
4
4
|
blueprint: ReadBlueprintResult;
|
|
5
5
|
token?: string;
|
|
6
|
+
flags: {
|
|
7
|
+
verbose?: boolean;
|
|
8
|
+
};
|
|
6
9
|
}
|
|
7
10
|
export declare function blueprintPlanCore(options: BlueprintPlanOptions): Promise<CoreResult>;
|
|
@@ -2,9 +2,10 @@ import chalk from 'chalk';
|
|
|
2
2
|
import { getStack } from '../../actions/blueprints/stacks.js';
|
|
3
3
|
import { formatResourceTree, stackDeployDiff } from '../../utils/display/blueprints-formatting.js';
|
|
4
4
|
export async function blueprintPlanCore(options) {
|
|
5
|
-
const { bin = 'sanity', log, blueprint, token } = options;
|
|
5
|
+
const { bin = 'sanity', log, blueprint, token, flags } = options;
|
|
6
|
+
const { verbose: _verbose = false } = flags;
|
|
6
7
|
const { scopeType, scopeId, stackId, parsedBlueprint, fileInfo } = blueprint;
|
|
7
|
-
log(`${chalk.bold.blueBright('Blueprint
|
|
8
|
+
log(`${chalk.bold.blueBright('Blueprint Stack deployment plan')} ${chalk.dim(`(${fileInfo.fileName})`)}`);
|
|
8
9
|
log(formatResourceTree(parsedBlueprint.resources));
|
|
9
10
|
if (token && scopeType && scopeId && stackId) {
|
|
10
11
|
const stackResponse = await getStack({
|
|
@@ -12,7 +13,7 @@ export async function blueprintPlanCore(options) {
|
|
|
12
13
|
stackId,
|
|
13
14
|
});
|
|
14
15
|
if (!stackResponse.ok) {
|
|
15
|
-
log(chalk.dim('Unable to retrieve live deployment for comparison'));
|
|
16
|
+
log(chalk.dim('Unable to retrieve live Stack deployment for comparison'));
|
|
16
17
|
}
|
|
17
18
|
else {
|
|
18
19
|
const diff = stackDeployDiff(parsedBlueprint, stackResponse.stack);
|
|
@@ -20,6 +21,6 @@ export async function blueprintPlanCore(options) {
|
|
|
20
21
|
log(diff);
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
|
-
log(`\n Run "${chalk.bold.magenta(`${bin} blueprints deploy`)}" to deploy these changes`);
|
|
24
|
+
log(`\n Run "${chalk.bold.magenta(`${bin} blueprints deploy`)}" to deploy these Stack changes`);
|
|
24
25
|
return { success: true };
|
|
25
26
|
}
|
|
@@ -5,8 +5,7 @@ import { capitalize, niceId } from '../../utils/display/presenters.js';
|
|
|
5
5
|
export async function blueprintStacksCore(options) {
|
|
6
6
|
const { log, token, blueprint, flags } = options;
|
|
7
7
|
const { scopeType: blueprintScopeType, scopeId: blueprintScopeId, stackId: blueprintStackId, } = blueprint;
|
|
8
|
-
const
|
|
9
|
-
const flagOrganizationId = flags['organization-id'];
|
|
8
|
+
const { 'project-id': flagProjectId, 'organization-id': flagOrganizationId, verbose: _verbose = false, } = flags;
|
|
10
9
|
if (flagOrganizationId && flagProjectId) {
|
|
11
10
|
log('Cannot specify both --organization-id and --project-id');
|
|
12
11
|
return { success: false, error: 'Cannot specify both --organization-id and --project-id' };
|