@sanity/runtime-cli 4.4.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/assets.d.ts +1 -0
- package/dist/actions/blueprints/assets.js +21 -4
- 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/actions/functions/test.d.ts +2 -2
- package/dist/actions/functions/test.js +2 -2
- 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 +13 -14
- package/dist/server/app.js +82 -14
- package/dist/server/static/api.js +24 -3
- package/dist/server/static/components/function-list.js +4 -4
- package/dist/server/static/components/response-panel.js +14 -3
- package/dist/server/static/index.html +1 -0
- package/dist/utils/build-payload.d.ts +1 -1
- package/dist/utils/build-payload.js +3 -3
- package/dist/utils/bundle/bundle-function.d.ts +8 -0
- package/dist/utils/bundle/bundle-function.js +125 -0
- package/dist/utils/bundle/cleanup-source-maps.d.ts +10 -0
- package/dist/utils/bundle/cleanup-source-maps.js +53 -0
- package/dist/utils/bundle/find-up.d.ts +16 -0
- package/dist/utils/bundle/find-up.js +39 -0
- package/dist/utils/bundle/verify-handler.d.ts +2 -0
- package/dist/utils/bundle/verify-handler.js +13 -0
- package/dist/utils/child-process-wrapper.js +8 -6
- 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/functions/find-entry-point.d.ts +11 -0
- package/dist/utils/functions/find-entry-point.js +75 -0
- package/dist/utils/functions/should-bundle.d.ts +2 -0
- package/dist/utils/functions/should-bundle.js +23 -0
- package/dist/utils/invoke-local.d.ts +2 -2
- package/dist/utils/invoke-local.js +49 -8
- package/dist/utils/is-record.d.ts +1 -0
- package/dist/utils/is-record.js +3 -0
- package/dist/utils/parse-json-object.d.ts +1 -0
- package/dist/utils/parse-json-object.js +10 -0
- package/dist/utils/types.d.ts +13 -4
- package/dist/utils/types.js +9 -3
- package/oclif.manifest.json +59 -37
- package/package.json +5 -1
- package/dist/utils/is-json.d.ts +0 -1
- package/dist/utils/is-json.js +0 -12
|
@@ -6,18 +6,6 @@ interface ListStacksResponse {
|
|
|
6
6
|
stacks: Stack[];
|
|
7
7
|
}
|
|
8
8
|
export declare function listStacks(auth: AuthParams): Promise<ListStacksResponse>;
|
|
9
|
-
interface GetStackByNameResponse {
|
|
10
|
-
ok: boolean;
|
|
11
|
-
error: string | null;
|
|
12
|
-
stack: Stack | null;
|
|
13
|
-
stackId: string | null;
|
|
14
|
-
availableStacks?: string[];
|
|
15
|
-
}
|
|
16
|
-
/** @deprecated Use getStack instead */
|
|
17
|
-
export declare function getStackByName({ name, auth, }: {
|
|
18
|
-
name: string;
|
|
19
|
-
auth: AuthParams;
|
|
20
|
-
}): Promise<GetStackByNameResponse>;
|
|
21
9
|
interface GetStackResponse {
|
|
22
10
|
ok: boolean;
|
|
23
11
|
error: string | null;
|
|
@@ -14,35 +14,6 @@ export async function listStacks(auth) {
|
|
|
14
14
|
stacks,
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
|
-
/** @deprecated Use getStack instead */
|
|
18
|
-
export async function getStackByName({ name, auth, }) {
|
|
19
|
-
const { ok, stacks, error } = await listStacks(auth);
|
|
20
|
-
if (!ok || !stacks) {
|
|
21
|
-
return {
|
|
22
|
-
ok: false,
|
|
23
|
-
error: error || 'Failed to retrieve stacks',
|
|
24
|
-
stack: null,
|
|
25
|
-
stackId: null,
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
const foundStack = stacks.find((stack) => stack.name === name);
|
|
29
|
-
if (!foundStack) {
|
|
30
|
-
return {
|
|
31
|
-
ok: true,
|
|
32
|
-
error: null,
|
|
33
|
-
stack: null,
|
|
34
|
-
stackId: null,
|
|
35
|
-
availableStacks: stacks.map((s) => s.name),
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
const stackResult = await getStack({ stackId: foundStack.id, auth });
|
|
39
|
-
return {
|
|
40
|
-
ok: stackResult.ok,
|
|
41
|
-
error: stackResult.error,
|
|
42
|
-
stack: stackResult.stack,
|
|
43
|
-
stackId: foundStack.id,
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
17
|
export async function getStack({ stackId, auth, }) {
|
|
47
18
|
const response = await fetch(`${stacksUrl}/${stackId}`, {
|
|
48
19
|
method: 'GET',
|
|
@@ -56,6 +27,8 @@ export async function getStack({ stackId, auth, }) {
|
|
|
56
27
|
};
|
|
57
28
|
}
|
|
58
29
|
export async function createStack({ stackPayload, auth, }) {
|
|
30
|
+
// LAUNCH LIMIT: 1 Stack per Project
|
|
31
|
+
stackPayload.useProjectBasedId = true;
|
|
59
32
|
const response = await fetch(stacksUrl, {
|
|
60
33
|
method: 'POST',
|
|
61
34
|
headers: getHeaders(auth),
|
|
@@ -64,7 +37,7 @@ export async function createStack({ stackPayload, auth, }) {
|
|
|
64
37
|
const stack = await response.json();
|
|
65
38
|
return {
|
|
66
39
|
ok: response.ok,
|
|
67
|
-
error: response.ok ? null : stack.message,
|
|
40
|
+
error: response.ok ? null : stack.message || stack.error,
|
|
68
41
|
stack,
|
|
69
42
|
};
|
|
70
43
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { InvocationResponse, InvokeContextOptions, InvokePayloadOptions } from '../../utils/types.js';
|
|
2
|
-
export declare function testAction(
|
|
1
|
+
import type { InvocationResponse, InvokeContextOptions, InvokePayloadOptions, LocalFunctionResource } from '../../utils/types.js';
|
|
2
|
+
export declare function testAction(resource: LocalFunctionResource, options: InvokePayloadOptions, context: InvokeContextOptions): Promise<InvocationResponse>;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import buildPayload from '../../utils/build-payload.js';
|
|
2
2
|
import invoke from '../../utils/invoke-local.js';
|
|
3
|
-
export async function testAction(
|
|
3
|
+
export async function testAction(resource, options, context) {
|
|
4
4
|
const payload = buildPayload(options);
|
|
5
5
|
const { timeout } = options;
|
|
6
6
|
try {
|
|
7
|
-
const { json, logs } = await invoke(
|
|
7
|
+
const { json, logs } = await invoke(resource, payload, context, timeout);
|
|
8
8
|
return { error: undefined, json, logs };
|
|
9
9
|
}
|
|
10
10
|
catch (error) {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import type { Interfaces } from '@oclif/core';
|
|
3
|
+
import { readLocalBlueprint } from './actions/blueprints/blueprint.js';
|
|
4
|
+
import type { AuthParams, Stack } from './utils/types.js';
|
|
5
|
+
export type Flags<T extends typeof Command> = Interfaces.InferredFlags<(typeof BlueprintCommand)['baseFlags'] & T['flags']>;
|
|
6
|
+
export type Args<T extends typeof Command> = Interfaces.InferredArgs<T['args']>;
|
|
7
|
+
export declare abstract class BlueprintCommand<T extends typeof Command> extends Command {
|
|
8
|
+
protected sanityToken: string;
|
|
9
|
+
protected blueprint: Awaited<ReturnType<typeof readLocalBlueprint>>;
|
|
10
|
+
protected flags: Flags<T>;
|
|
11
|
+
protected args: Args<T>;
|
|
12
|
+
init(): Promise<void>;
|
|
13
|
+
protected catch(err: Error & {
|
|
14
|
+
exitCode?: number;
|
|
15
|
+
}): Promise<unknown>;
|
|
16
|
+
protected finally(_: Error | undefined): Promise<unknown>;
|
|
17
|
+
}
|
|
18
|
+
export declare abstract class DeployedBlueprintCommand<T extends typeof Command> extends BlueprintCommand<T> {
|
|
19
|
+
protected auth: AuthParams;
|
|
20
|
+
protected deployedStack: Stack;
|
|
21
|
+
protected projectId: string;
|
|
22
|
+
protected stackId: string;
|
|
23
|
+
init(): Promise<void>;
|
|
24
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// * https://oclif.io/docs/base_class
|
|
2
|
+
import { Command } from '@oclif/core';
|
|
3
|
+
import { readLocalBlueprint } from './actions/blueprints/blueprint.js';
|
|
4
|
+
import { getStack } from './actions/blueprints/stacks.js';
|
|
5
|
+
import { presentBlueprintParserErrors } from './utils/display/errors.js';
|
|
6
|
+
import { validTokenOrErrorMessage } from './utils/validated-token.js';
|
|
7
|
+
export class BlueprintCommand extends Command {
|
|
8
|
+
sanityToken;
|
|
9
|
+
blueprint;
|
|
10
|
+
flags;
|
|
11
|
+
args;
|
|
12
|
+
async init() {
|
|
13
|
+
const { args, flags } = await this.parse({
|
|
14
|
+
flags: this.ctor.flags,
|
|
15
|
+
baseFlags: super.ctor.baseFlags,
|
|
16
|
+
enableJsonFlag: this.ctor.enableJsonFlag,
|
|
17
|
+
args: this.ctor.args,
|
|
18
|
+
strict: this.ctor.strict,
|
|
19
|
+
});
|
|
20
|
+
this.flags = flags;
|
|
21
|
+
this.args = args;
|
|
22
|
+
await super.init();
|
|
23
|
+
const { token, error: tokenErr } = await validTokenOrErrorMessage();
|
|
24
|
+
if (tokenErr)
|
|
25
|
+
this.error(tokenErr.message);
|
|
26
|
+
this.sanityToken = token;
|
|
27
|
+
const blueprint = await readLocalBlueprint();
|
|
28
|
+
if (blueprint.errors.length > 0) {
|
|
29
|
+
this.log(presentBlueprintParserErrors(blueprint.errors));
|
|
30
|
+
this.error('Blueprint parse errors.');
|
|
31
|
+
}
|
|
32
|
+
this.blueprint = blueprint;
|
|
33
|
+
}
|
|
34
|
+
async catch(err) {
|
|
35
|
+
// add any custom logic to handle errors from the command
|
|
36
|
+
// or simply return the parent class error handling
|
|
37
|
+
return super.catch(err);
|
|
38
|
+
}
|
|
39
|
+
async finally(_) {
|
|
40
|
+
// called after run and catch regardless of whether or not the command errored
|
|
41
|
+
return super.finally(_);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export class DeployedBlueprintCommand extends BlueprintCommand {
|
|
45
|
+
auth;
|
|
46
|
+
deployedStack;
|
|
47
|
+
projectId;
|
|
48
|
+
stackId;
|
|
49
|
+
async init() {
|
|
50
|
+
await super.init();
|
|
51
|
+
const { projectId, stackId } = this.blueprint;
|
|
52
|
+
if (!projectId)
|
|
53
|
+
this.error('Missing Project ID for Blueprint');
|
|
54
|
+
if (!stackId)
|
|
55
|
+
this.error('Missing Stack ID for Blueprint');
|
|
56
|
+
this.projectId = projectId;
|
|
57
|
+
this.stackId = stackId;
|
|
58
|
+
this.auth = { token: this.sanityToken, projectId };
|
|
59
|
+
const stackResponse = await getStack({ stackId, auth: this.auth });
|
|
60
|
+
if (!stackResponse.ok) {
|
|
61
|
+
this.error(stackResponse.error ?? 'Could not retrieve deployment info');
|
|
62
|
+
}
|
|
63
|
+
const { stack: deployedStack } = stackResponse;
|
|
64
|
+
if (!deployedStack) {
|
|
65
|
+
this.error('Unable to find deployed Stack. Run `sanity-run blueprints init`');
|
|
66
|
+
}
|
|
67
|
+
this.deployedStack = deployedStack;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { cwd } from 'node:process';
|
|
1
2
|
import { Args, Command, Flags } from '@oclif/core';
|
|
2
3
|
import highlight from 'color-json';
|
|
3
4
|
import inquirer from 'inquirer';
|
|
4
5
|
import { findBlueprintFile } from '../../actions/blueprints/blueprint.js';
|
|
5
6
|
import { createFunctionResource } from '../../actions/blueprints/resources.js';
|
|
6
7
|
import { validateFunctionName, validateFunctionType } from '../../utils/validate/resource.js';
|
|
7
|
-
export default class
|
|
8
|
+
export default class AddCommand extends Command {
|
|
8
9
|
static description = 'Add a resource to a Blueprint';
|
|
9
10
|
static examples = [
|
|
10
11
|
'<%= config.bin %> <%= command.id %> function',
|
|
@@ -30,13 +31,13 @@ export default class Add extends Command {
|
|
|
30
31
|
}),
|
|
31
32
|
};
|
|
32
33
|
async run() {
|
|
33
|
-
const { args, flags } = await this.parse(
|
|
34
|
+
const { args, flags } = await this.parse(AddCommand);
|
|
35
|
+
if (args.type !== 'function')
|
|
36
|
+
this.error(`Unsupported Resource type: ${args.type}`);
|
|
34
37
|
const existingBlueprint = findBlueprintFile();
|
|
35
38
|
if (!existingBlueprint) {
|
|
36
|
-
this.error('No
|
|
39
|
+
this.error('No Blueprint file found. Run `sanity-run blueprints init` first.');
|
|
37
40
|
}
|
|
38
|
-
if (args.type !== 'function')
|
|
39
|
-
this.error(`Unsupported resource type: ${args.type}`);
|
|
40
41
|
const resourceName = flags.name;
|
|
41
42
|
const functionType = flags['function-type'];
|
|
42
43
|
await this.addFunction({ name: resourceName, type: functionType });
|
|
@@ -82,7 +83,7 @@ export default class Add extends Command {
|
|
|
82
83
|
type: functionType,
|
|
83
84
|
displayName: functionName,
|
|
84
85
|
});
|
|
85
|
-
this.log(`\nCreated function: ${filePath}`);
|
|
86
|
+
this.log(`\nCreated function: ${filePath.replace(cwd(), '')}`);
|
|
86
87
|
if (!resourceAdded) {
|
|
87
88
|
// print the resource JSON for manual addition
|
|
88
89
|
this.log('\nAdd this Function resource to your blueprint:');
|
|
@@ -2,18 +2,21 @@ import { Command, Flags } from '@oclif/core';
|
|
|
2
2
|
import highlight from 'color-json';
|
|
3
3
|
import inquirer from 'inquirer';
|
|
4
4
|
import Spinner from 'yocto-spinner';
|
|
5
|
-
import {
|
|
5
|
+
import { readLocalBlueprint, writeConfigFile } from '../../actions/blueprints/blueprint.js';
|
|
6
6
|
import { listProjects } from '../../actions/blueprints/projects.js';
|
|
7
7
|
import { getStack, listStacks } from '../../actions/blueprints/stacks.js';
|
|
8
8
|
import { bold, dim, niceId } from '../../utils/display/colors.js';
|
|
9
|
+
import { presentBlueprintParserErrors } from '../../utils/display/errors.js';
|
|
9
10
|
import { validTokenOrErrorMessage } from '../../utils/validated-token.js';
|
|
10
|
-
export default class
|
|
11
|
+
export default class ConfigCommand extends Command {
|
|
11
12
|
static description = 'View or edit Blueprint configuration';
|
|
12
13
|
static examples = [
|
|
13
14
|
'<%= config.bin %> <%= command.id %>',
|
|
14
15
|
'<%= config.bin %> <%= command.id %> --test-config',
|
|
15
16
|
'<%= config.bin %> <%= command.id %> --edit',
|
|
16
|
-
'<%= config.bin %> <%= command.id %> --edit --project-id <projectId>
|
|
17
|
+
'<%= config.bin %> <%= command.id %> --edit --project-id <projectId>',
|
|
18
|
+
// LAUNCH LIMIT: 1 Stack per Project - do not allow Stack ID to be set
|
|
19
|
+
// '<%= config.bin %> <%= command.id %> --edit --project-id <projectId> --stack-id <stackId>',
|
|
17
20
|
];
|
|
18
21
|
static flags = {
|
|
19
22
|
'test-config': Flags.boolean({
|
|
@@ -36,20 +39,25 @@ export default class Config extends Command {
|
|
|
36
39
|
description: 'Update the Stack ID in the configuration. Requires --edit flag',
|
|
37
40
|
aliases: ['stack', 'stackId'],
|
|
38
41
|
dependsOn: ['edit'],
|
|
42
|
+
hidden: true, // LAUNCH LIMIT: 1 Stack per Project
|
|
39
43
|
}),
|
|
40
44
|
};
|
|
41
45
|
sanityToken;
|
|
42
46
|
async run() {
|
|
43
|
-
const { flags } = await this.parse(
|
|
47
|
+
const { flags } = await this.parse(ConfigCommand);
|
|
44
48
|
const { edit: editConfig, 'project-id': editProjectId, 'stack-id': editStackId, 'test-config': testConfig, } = flags;
|
|
45
|
-
const blueprint = await
|
|
46
|
-
const { stackId: configStackId, projectId: configProjectId } = blueprint;
|
|
49
|
+
const blueprint = await readLocalBlueprint();
|
|
50
|
+
const { stackId: configStackId, projectId: configProjectId, errors } = blueprint;
|
|
51
|
+
if (errors.length > 0) {
|
|
52
|
+
this.log(presentBlueprintParserErrors(errors));
|
|
53
|
+
this.error('Blueprint parse errors.');
|
|
54
|
+
}
|
|
47
55
|
if (!configStackId && !configProjectId) {
|
|
48
|
-
this.error('Project
|
|
56
|
+
this.error('Project configuration is missing! Use `sanity-run blueprints init` to create a configuration.');
|
|
49
57
|
}
|
|
50
58
|
this.log(bold('Current configuration:'));
|
|
51
59
|
this.log(` Sanity Project: ${niceId(configProjectId)}`);
|
|
52
|
-
this.log(` Blueprint
|
|
60
|
+
this.log(` Blueprint deployment: ${niceId(configStackId)}`);
|
|
53
61
|
if ((editProjectId || editStackId) && !editConfig) {
|
|
54
62
|
this.log('To update the configuration, use the --edit flag.');
|
|
55
63
|
return;
|
|
@@ -73,7 +81,10 @@ export default class Config extends Command {
|
|
|
73
81
|
const projectId = editProjectId || (await this.promptForProjectId({ knownProjectId: configProjectId }));
|
|
74
82
|
if (!projectId)
|
|
75
83
|
this.error('Project ID is required.');
|
|
76
|
-
|
|
84
|
+
// LAUNCH LIMIT: 1 Stack per Project - do not allow Stack ID to be set
|
|
85
|
+
// const stackId =
|
|
86
|
+
// editStackId || (await this.promptForStackId({projectId, knownStackId: configStackId}))
|
|
87
|
+
const stackId = configStackId;
|
|
77
88
|
if (testConfig) {
|
|
78
89
|
if (projectId && stackId) {
|
|
79
90
|
const { ok: newConfigOk } = await this.testConfigAndReport({ stackId, projectId });
|
|
@@ -87,12 +98,14 @@ export default class Config extends Command {
|
|
|
87
98
|
}
|
|
88
99
|
try {
|
|
89
100
|
// update or create .blueprint/config.json
|
|
90
|
-
|
|
101
|
+
// LAUNCH LIMIT: 1 Stack per Project - do not allow Stack ID to be set
|
|
102
|
+
writeConfigFile({ projectId /*, stackId*/ });
|
|
91
103
|
this.log('Configuration updated successfully.');
|
|
92
104
|
}
|
|
93
105
|
catch (error) {
|
|
94
106
|
this.log('Unable to dynamically update config. Use these values in your blueprint:');
|
|
95
|
-
|
|
107
|
+
// LAUNCH LIMIT: 1 Stack per Project - do not allow Stack ID to be set
|
|
108
|
+
this.log(highlight(JSON.stringify({ metadata: { projectId /*, stackId*/ } }, null, 2)));
|
|
96
109
|
}
|
|
97
110
|
}
|
|
98
111
|
async promptForProjectId({ knownProjectId }) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default class
|
|
1
|
+
import { DeployedBlueprintCommand } from '../../baseCommands.js';
|
|
2
|
+
export default class DeployCommand extends DeployedBlueprintCommand<typeof DeployCommand> {
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
5
|
static flags: {
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { setTimeout } from 'node:timers/promises';
|
|
2
|
-
import {
|
|
3
|
-
import { Command, Flags } from '@oclif/core';
|
|
2
|
+
import { Flags } from '@oclif/core';
|
|
4
3
|
import Spinner from 'yocto-spinner';
|
|
5
4
|
import { stashAsset } from '../../actions/blueprints/assets.js';
|
|
6
|
-
import { readBlueprintOnDisk } from '../../actions/blueprints/blueprint.js';
|
|
7
5
|
import { getStack, updateStack } from '../../actions/blueprints/stacks.js';
|
|
6
|
+
import { DeployedBlueprintCommand } from '../../baseCommands.js';
|
|
8
7
|
import { bold, niceId, red } from '../../utils/display/colors.js';
|
|
9
8
|
import { isLocalFunctionResource } from '../../utils/types.js';
|
|
10
|
-
|
|
11
|
-
export default class Deploy extends Command {
|
|
9
|
+
export default class DeployCommand extends DeployedBlueprintCommand {
|
|
12
10
|
static description = 'Deploy a Blueprint';
|
|
13
|
-
static examples = [
|
|
11
|
+
static examples = [
|
|
12
|
+
'<%= config.bin %> <%= command.id %>',
|
|
13
|
+
'<%= config.bin %> <%= command.id %> --no-wait',
|
|
14
|
+
];
|
|
14
15
|
static flags = {
|
|
15
16
|
'no-wait': Flags.boolean({
|
|
16
17
|
description: 'Do not wait for deployment to complete',
|
|
@@ -18,28 +19,15 @@ export default class Deploy extends Command {
|
|
|
18
19
|
}),
|
|
19
20
|
};
|
|
20
21
|
async run() {
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
this.error(tokenErr.message);
|
|
24
|
-
const { flags } = await this.parse(Deploy);
|
|
25
|
-
const { errors, projectId, stackId, parsedBlueprint: { resources }, deployedStack, } = await readBlueprintOnDisk({ getStack: true, token });
|
|
26
|
-
if (errors.length > 0) {
|
|
27
|
-
// printErrors(errors) // TODO: error printer in formatting
|
|
28
|
-
this.error(`Blueprint parse errors:\n${inspect(errors, { depth: null })}`);
|
|
29
|
-
}
|
|
30
|
-
if (!deployedStack || !stackId || !projectId) {
|
|
31
|
-
this.error('Before deploying, run `sanity blueprints init`');
|
|
32
|
-
}
|
|
33
|
-
if (stackId !== deployedStack.id)
|
|
34
|
-
this.error('Stack ID mismatch');
|
|
35
|
-
const auth = { token, projectId };
|
|
22
|
+
const flags = this.flags;
|
|
23
|
+
const { resources } = this.blueprint.parsedBlueprint;
|
|
36
24
|
const validResources = resources?.filter((r) => r.type);
|
|
37
25
|
const functionResources = validResources?.filter(isLocalFunctionResource);
|
|
38
26
|
// First stash all function assets
|
|
39
27
|
if (functionResources?.length) {
|
|
40
28
|
for (const resource of functionResources) {
|
|
41
29
|
const fnSpinner = Spinner({ text: `Processing ${resource.name}...` }).start();
|
|
42
|
-
const result = await stashAsset({ resource, auth });
|
|
30
|
+
const result = await stashAsset({ resource, auth: this.auth });
|
|
43
31
|
if (result.success && result.assetId) {
|
|
44
32
|
const src = resource.src;
|
|
45
33
|
resource.src = result.assetId; // TODO: properly reference asset - for now, the API expects the assetId
|
|
@@ -54,21 +42,19 @@ export default class Deploy extends Command {
|
|
|
54
42
|
}
|
|
55
43
|
}
|
|
56
44
|
const stackPayload = {
|
|
57
|
-
projectId,
|
|
58
|
-
name: deployedStack.name,
|
|
45
|
+
projectId: this.projectId,
|
|
46
|
+
name: this.deployedStack.name,
|
|
59
47
|
document: { resources: validResources },
|
|
60
48
|
};
|
|
61
|
-
|
|
62
|
-
const
|
|
63
|
-
const { ok: deployOk, stack, error: deployError, } = await updateStack({ stackId: deployedStack.id, stackPayload, auth });
|
|
64
|
-
this.debug('STACK RESPONSE:', stack);
|
|
49
|
+
const spinner = Spinner({ text: 'Deploying...' }).start();
|
|
50
|
+
const { ok: deployOk, stack, error: deployError, } = await updateStack({ stackId: this.stackId, stackPayload, auth: this.auth });
|
|
65
51
|
if (deployOk) {
|
|
66
|
-
spinner.success(`
|
|
52
|
+
spinner.success(`Deployment "${bold(stack.name)}" ${niceId(stack.id)} started!`);
|
|
67
53
|
if (!flags['no-wait']) {
|
|
68
54
|
const waitSpinner = Spinner({ text: 'Waiting for deployment to complete...' }).start();
|
|
69
55
|
while (true) {
|
|
70
56
|
// TODO: watch logs and print those while polling
|
|
71
|
-
const { ok, stack: currentStack } = await getStack({ stackId: stack.id, auth });
|
|
57
|
+
const { ok, stack: currentStack } = await getStack({ stackId: stack.id, auth: this.auth });
|
|
72
58
|
if (!ok) {
|
|
73
59
|
waitSpinner.error('Failed to check deployment status');
|
|
74
60
|
break;
|
|
@@ -90,12 +76,11 @@ export default class Deploy extends Command {
|
|
|
90
76
|
}
|
|
91
77
|
}
|
|
92
78
|
else {
|
|
93
|
-
this.log('Use `sanity blueprints info` to check
|
|
79
|
+
this.log('Use `sanity-run blueprints info` to check status');
|
|
94
80
|
}
|
|
95
81
|
}
|
|
96
82
|
else {
|
|
97
|
-
|
|
98
|
-
spinner.error(`${red('Failed')} to update stack`);
|
|
83
|
+
spinner.error(`${red('Failed')} to update deployment`);
|
|
99
84
|
this.log(`Error: ${deployError || JSON.stringify(stack, null, 2) || 'Unknown error'}`);
|
|
100
85
|
}
|
|
101
86
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default class
|
|
1
|
+
import { DeployedBlueprintCommand } from '../../baseCommands.js';
|
|
2
|
+
export default class DestroyCommand extends DeployedBlueprintCommand<typeof DestroyCommand> {
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
5
|
static flags: {
|
|
6
|
-
id: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
6
|
force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
7
|
+
projectId: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
|
+
id: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
9
|
};
|
|
9
10
|
run(): Promise<void>;
|
|
10
11
|
}
|
|
@@ -1,54 +1,51 @@
|
|
|
1
1
|
import { setTimeout } from 'node:timers/promises';
|
|
2
|
-
import {
|
|
2
|
+
import { Flags } from '@oclif/core';
|
|
3
3
|
import inquirer from 'inquirer';
|
|
4
4
|
import Spinner from 'yocto-spinner';
|
|
5
|
-
import { readBlueprintOnDisk } from '../../actions/blueprints/blueprint.js';
|
|
6
5
|
import { destroyStack, getStack } from '../../actions/blueprints/stacks.js';
|
|
6
|
+
import { DeployedBlueprintCommand } from '../../baseCommands.js';
|
|
7
7
|
import { bold, niceId } from '../../utils/display/colors.js';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
static description = 'Destroy a deployed Blueprint Stack';
|
|
8
|
+
export default class DestroyCommand extends DeployedBlueprintCommand {
|
|
9
|
+
static description = 'Destroy a Blueprint deployment';
|
|
11
10
|
static examples = [
|
|
12
11
|
'<%= config.bin %> <%= command.id %>',
|
|
13
|
-
|
|
12
|
+
// LAUNCH LIMIT: 1 Stack per Project - do not allow Stack ID to be set
|
|
13
|
+
// '<%= config.bin %> <%= command.id %> --id ST-a1b2c3 --projectId a1b2c3 --force',
|
|
14
14
|
];
|
|
15
15
|
static flags = {
|
|
16
|
-
id: Flags.string({
|
|
17
|
-
description: 'Stack ID to destroy (defaults to current Stack)',
|
|
18
|
-
required: false,
|
|
19
|
-
}),
|
|
20
16
|
force: Flags.boolean({
|
|
21
17
|
description: 'Force destroy (skip confirmation)',
|
|
22
18
|
default: false,
|
|
23
19
|
}),
|
|
20
|
+
projectId: Flags.string({
|
|
21
|
+
description: 'Project associated with the Stack (defaults to current Project)',
|
|
22
|
+
dependsOn: ['id', 'force'],
|
|
23
|
+
hidden: true, // LAUNCH LIMIT: 1 Stack per Project
|
|
24
|
+
}),
|
|
25
|
+
id: Flags.string({
|
|
26
|
+
description: 'Stack ID to destroy (defaults to current Stack)',
|
|
27
|
+
dependsOn: ['projectId', 'force'],
|
|
28
|
+
hidden: true, // LAUNCH LIMIT: 1 Stack per Project
|
|
29
|
+
}),
|
|
24
30
|
};
|
|
25
31
|
async run() {
|
|
26
|
-
const
|
|
27
|
-
if (
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
this.
|
|
34
|
-
console.dir(errors, { depth: null });
|
|
32
|
+
const flags = this.flags;
|
|
33
|
+
if (flags.projectId && flags.id && flags.force) {
|
|
34
|
+
// just try to destroy it
|
|
35
|
+
const auth = { token: this.sanityToken, projectId: flags.projectId };
|
|
36
|
+
const { ok, error, stack } = await destroyStack({ stackId: flags.id, auth });
|
|
37
|
+
if (!ok)
|
|
38
|
+
this.error(error || 'Failed to destroy deployment');
|
|
39
|
+
this.log(`Deployment "${stack.name}" ${niceId(stack.id)} destroyed`);
|
|
35
40
|
return;
|
|
36
41
|
}
|
|
37
|
-
|
|
38
|
-
this.error('Project resource not found in blueprint');
|
|
39
|
-
const auth = { token, projectId };
|
|
40
|
-
let stack = deployedStack;
|
|
42
|
+
let stack = this.deployedStack;
|
|
41
43
|
if (flags.id) {
|
|
42
|
-
const { ok, stack: foundStack, error } = await getStack({ stackId: flags.id, auth });
|
|
44
|
+
const { ok, stack: foundStack, error } = await getStack({ stackId: flags.id, auth: this.auth });
|
|
43
45
|
if (!ok)
|
|
44
46
|
this.error(error || 'Failed to get stack');
|
|
45
47
|
stack = foundStack;
|
|
46
48
|
}
|
|
47
|
-
else if (!stack) {
|
|
48
|
-
this.error('No stack found');
|
|
49
|
-
}
|
|
50
|
-
if (!stack)
|
|
51
|
-
this.error('Stack not found. Is it deployed?');
|
|
52
49
|
const destroySpinner = Spinner({
|
|
53
50
|
text: `Destroying ${bold(stack.name)} ${niceId(stack.id)}...`,
|
|
54
51
|
color: 'red',
|
|
@@ -63,25 +60,25 @@ export default class Destroy extends Command {
|
|
|
63
60
|
},
|
|
64
61
|
]);
|
|
65
62
|
if (!confirm) {
|
|
66
|
-
this.log('
|
|
63
|
+
this.log('Deployment destruction cancelled');
|
|
67
64
|
return;
|
|
68
65
|
}
|
|
69
66
|
destroySpinner.start();
|
|
70
67
|
let i = 5;
|
|
71
68
|
while (i >= 0) {
|
|
72
|
-
destroySpinner.text = `Destroying
|
|
69
|
+
destroySpinner.text = `Destroying deployment in ${bold((i--).toString())} seconds...`;
|
|
73
70
|
await setTimeout(1000);
|
|
74
71
|
}
|
|
75
|
-
destroySpinner.text = 'Destroying
|
|
72
|
+
destroySpinner.text = 'Destroying deployment 💥';
|
|
76
73
|
await setTimeout(500);
|
|
77
74
|
}
|
|
78
75
|
else {
|
|
79
76
|
destroySpinner.start();
|
|
80
77
|
}
|
|
81
|
-
const { ok, error } = await destroyStack({ stackId: stack.id, auth });
|
|
78
|
+
const { ok, error } = await destroyStack({ stackId: stack.id, auth: this.auth });
|
|
82
79
|
if (!ok)
|
|
83
|
-
this.error(error || 'Failed to destroy
|
|
80
|
+
this.error(error || 'Failed to destroy deployment');
|
|
84
81
|
// TODO: update local config
|
|
85
|
-
destroySpinner.success(`
|
|
82
|
+
destroySpinner.success(`Deployment "${stack.name}" ${niceId(stack.id)} destroyed`);
|
|
86
83
|
}
|
|
87
84
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default class
|
|
1
|
+
import { DeployedBlueprintCommand } from '../../baseCommands.js';
|
|
2
|
+
export default class InfoCommand extends DeployedBlueprintCommand<typeof InfoCommand> {
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
5
|
static flags: {
|
|
@@ -1,53 +1,33 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { readBlueprintOnDisk } from '../../actions/blueprints/blueprint.js';
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
3
2
|
import { getStack } from '../../actions/blueprints/stacks.js';
|
|
3
|
+
import { DeployedBlueprintCommand } from '../../baseCommands.js';
|
|
4
4
|
import { formatResourceTree, formatStackInfo } from '../../utils/display/blueprints-formatting.js';
|
|
5
5
|
import { niceId } from '../../utils/display/colors.js';
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
static description = 'Show information about a deployed Blueprint Stack';
|
|
6
|
+
export default class InfoCommand extends DeployedBlueprintCommand {
|
|
7
|
+
static description = 'Show information about a Blueprint deployment';
|
|
9
8
|
static examples = [
|
|
10
9
|
'<%= config.bin %> <%= command.id %>',
|
|
11
|
-
|
|
10
|
+
// LAUNCH LIMIT: 1 Stack per Project - do not allow Stack ID to be set
|
|
11
|
+
// '<%= config.bin %> <%= command.id %> --id ST-a1b2c3',
|
|
12
12
|
];
|
|
13
13
|
static flags = {
|
|
14
14
|
id: Flags.string({
|
|
15
15
|
description: 'Stack ID to show info for (defaults to current stack)',
|
|
16
|
-
|
|
16
|
+
hidden: true, // LAUNCH LIMIT: 1 Stack per Project
|
|
17
17
|
}),
|
|
18
18
|
};
|
|
19
19
|
async run() {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const { flags } = await this.parse(Info);
|
|
24
|
-
const { errors, deployedStack, projectId, stackId } = await readBlueprintOnDisk({
|
|
25
|
-
getStack: true,
|
|
26
|
-
token,
|
|
27
|
-
});
|
|
28
|
-
if (errors.length > 0) {
|
|
29
|
-
// printErrors(errors)
|
|
30
|
-
this.warn('Blueprint parse errors:');
|
|
31
|
-
console.dir(errors, { depth: null });
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
if (!stackId && !flags.id)
|
|
35
|
-
this.error('No Stack ID provided');
|
|
36
|
-
if (!projectId)
|
|
37
|
-
this.error('Missing Project ID for Blueprint');
|
|
38
|
-
const auth = { token, projectId };
|
|
39
|
-
let stack = deployedStack;
|
|
20
|
+
const flags = this.flags;
|
|
21
|
+
const stackId = flags.id || this.stackId;
|
|
22
|
+
let stack = this.deployedStack;
|
|
40
23
|
if (flags.id) {
|
|
41
|
-
const
|
|
42
|
-
if (!ok)
|
|
43
|
-
this.error(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
this.error(`Stack ${niceId(stackId)} not found`);
|
|
24
|
+
const existingStackResponse = await getStack({ stackId, auth: this.auth });
|
|
25
|
+
if (!existingStackResponse.ok) {
|
|
26
|
+
this.error(existingStackResponse.error ??
|
|
27
|
+
`Could not retrieve deployment info for ${niceId(stackId)}`);
|
|
28
|
+
}
|
|
29
|
+
stack = existingStackResponse.stack;
|
|
48
30
|
}
|
|
49
|
-
if (!stack)
|
|
50
|
-
this.error('Stack not found. Is it deployed?');
|
|
51
31
|
this.log(formatStackInfo(stack, true));
|
|
52
32
|
if (stack.resources) {
|
|
53
33
|
this.log('');
|