@sanity/runtime-cli 12.4.0 → 13.0.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 +176 -63
- package/dist/actions/blueprints/assets.d.ts +3 -1
- package/dist/actions/blueprints/assets.js +8 -4
- package/dist/actions/blueprints/blueprint.d.ts +2 -1
- package/dist/actions/blueprints/blueprint.js +3 -1
- package/dist/actions/blueprints/config.d.ts +5 -2
- package/dist/actions/blueprints/config.js +4 -4
- package/dist/actions/blueprints/logs-streaming.d.ts +4 -2
- package/dist/actions/blueprints/logs-streaming.js +5 -2
- package/dist/actions/blueprints/logs.d.ts +2 -1
- package/dist/actions/blueprints/logs.js +4 -2
- package/dist/actions/blueprints/resources.d.ts +2 -1
- package/dist/actions/blueprints/resources.js +2 -2
- package/dist/actions/blueprints/stacks.d.ts +12 -6
- package/dist/actions/blueprints/stacks.js +18 -11
- package/dist/actions/functions/dev.d.ts +2 -1
- package/dist/actions/functions/dev.js +2 -2
- package/dist/actions/functions/env/list.d.ts +2 -1
- package/dist/actions/functions/env/list.js +4 -2
- package/dist/actions/functions/env/remove.d.ts +2 -1
- package/dist/actions/functions/env/remove.js +4 -2
- package/dist/actions/functions/env/update.d.ts +2 -1
- package/dist/actions/functions/env/update.js +4 -2
- package/dist/actions/functions/logs.d.ts +4 -3
- package/dist/actions/functions/logs.js +10 -6
- package/dist/actions/node.d.ts +2 -1
- package/dist/actions/node.js +2 -2
- package/dist/actions/sanity/examples.d.ts +5 -2
- package/dist/actions/sanity/examples.js +6 -6
- package/dist/actions/sanity/projects.d.ts +7 -3
- package/dist/actions/sanity/projects.js +11 -7
- package/dist/baseCommands.d.ts +4 -0
- package/dist/baseCommands.js +8 -2
- package/dist/commands/blueprints/add.d.ts +1 -0
- package/dist/commands/blueprints/add.js +12 -8
- package/dist/commands/blueprints/config.d.ts +1 -0
- package/dist/commands/blueprints/config.js +10 -4
- package/dist/commands/blueprints/deploy.d.ts +1 -0
- package/dist/commands/blueprints/deploy.js +8 -2
- package/dist/commands/blueprints/destroy.d.ts +1 -0
- package/dist/commands/blueprints/destroy.js +8 -2
- package/dist/commands/blueprints/doctor.d.ts +1 -0
- package/dist/commands/blueprints/doctor.js +7 -2
- package/dist/commands/blueprints/info.d.ts +1 -0
- package/dist/commands/blueprints/info.js +9 -3
- package/dist/commands/blueprints/init.d.ts +1 -0
- package/dist/commands/blueprints/init.js +20 -11
- package/dist/commands/blueprints/logs.d.ts +1 -0
- package/dist/commands/blueprints/logs.js +8 -2
- package/dist/commands/blueprints/plan.d.ts +1 -0
- package/dist/commands/blueprints/plan.js +6 -2
- package/dist/commands/blueprints/stacks.d.ts +1 -0
- package/dist/commands/blueprints/stacks.js +8 -4
- package/dist/commands/functions/add.d.ts +1 -0
- package/dist/commands/functions/add.js +8 -2
- package/dist/commands/functions/dev.d.ts +1 -0
- package/dist/commands/functions/dev.js +14 -3
- package/dist/commands/functions/env/add.d.ts +2 -1
- package/dist/commands/functions/env/add.js +6 -2
- package/dist/commands/functions/env/list.d.ts +2 -1
- package/dist/commands/functions/env/list.js +6 -2
- package/dist/commands/functions/env/remove.d.ts +2 -1
- package/dist/commands/functions/env/remove.js +6 -2
- package/dist/commands/functions/logs.d.ts +2 -1
- package/dist/commands/functions/logs.js +7 -4
- package/dist/commands/functions/test.d.ts +2 -1
- package/dist/commands/functions/test.js +6 -2
- package/dist/cores/blueprints/config.js +9 -9
- package/dist/cores/blueprints/deploy.js +14 -16
- package/dist/cores/blueprints/destroy.js +6 -6
- package/dist/cores/blueprints/doctor.js +20 -27
- package/dist/cores/blueprints/info.js +3 -3
- package/dist/cores/blueprints/init.d.ts +3 -3
- package/dist/cores/blueprints/init.js +15 -8
- package/dist/cores/blueprints/logs.js +6 -7
- package/dist/cores/blueprints/plan.js +1 -0
- package/dist/cores/blueprints/stacks.js +4 -4
- package/dist/cores/functions/add.js +8 -3
- package/dist/cores/functions/dev.js +2 -2
- package/dist/cores/functions/env/add.js +3 -4
- package/dist/cores/functions/env/list.js +3 -4
- package/dist/cores/functions/env/remove.js +3 -4
- package/dist/cores/functions/index.d.ts +3 -9
- package/dist/cores/functions/logs.js +8 -9
- package/dist/cores/functions/test.js +7 -8
- package/dist/cores/index.d.ts +4 -7
- package/dist/cores/index.js +3 -3
- package/dist/index.d.ts +18 -2
- package/dist/index.js +20 -2
- package/dist/server/app.d.ts +2 -1
- package/dist/server/app.js +4 -4
- package/dist/server/handlers/invoke.d.ts +2 -1
- package/dist/server/handlers/invoke.js +2 -2
- package/dist/server/static/components/response-panel.js +3 -0
- package/dist/server/static/components/rule-panel.js +9 -1
- package/dist/utils/display/prompt.d.ts +5 -2
- package/dist/utils/display/prompt.js +5 -4
- package/dist/utils/functions/fetch-document.d.ts +3 -2
- package/dist/utils/functions/fetch-document.js +7 -6
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/logger.d.ts +13 -0
- package/dist/utils/logger.js +61 -0
- package/dist/utils/other/github.d.ts +2 -1
- package/dist/utils/other/github.js +4 -2
- package/dist/utils/other/npmjs.d.ts +2 -1
- package/dist/utils/other/npmjs.js +4 -2
- package/dist/utils/traced-fetch.d.ts +35 -0
- package/dist/utils/traced-fetch.js +238 -0
- package/dist/utils/validated-token.d.ts +3 -2
- package/dist/utils/validated-token.js +6 -4
- package/oclif.manifest.json +175 -38
- package/package.json +13 -5
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { DeployedStackCommand } from '../../../baseCommands.js';
|
|
2
2
|
export default class EnvListCommand extends DeployedStackCommand<typeof EnvListCommand> {
|
|
3
|
+
static summary: string;
|
|
4
|
+
static description: string;
|
|
3
5
|
static args: {
|
|
4
6
|
name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
7
|
};
|
|
6
|
-
static description: string;
|
|
7
8
|
static examples: string[];
|
|
8
9
|
run(): Promise<void>;
|
|
9
10
|
}
|
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import { Args } from '@oclif/core';
|
|
2
2
|
import { DeployedStackCommand } from '../../../baseCommands.js';
|
|
3
3
|
import { functionEnvListCore } from '../../../cores/functions/env/list.js';
|
|
4
|
+
import { Logger } from '../../../utils/logger.js';
|
|
4
5
|
export default class EnvListCommand extends DeployedStackCommand {
|
|
6
|
+
static summary = 'List environment variables for a deployed function';
|
|
7
|
+
static description = `Displays all environment variables (keys only) configured in a deployed Sanity Function.
|
|
8
|
+
|
|
9
|
+
Use 'functions env add' to set variables or 'functions env remove' to delete them.`;
|
|
5
10
|
static args = {
|
|
6
11
|
name: Args.string({ description: 'The name of the Sanity Function', required: true }),
|
|
7
12
|
};
|
|
8
|
-
static description = 'List the environment variables for a Sanity function';
|
|
9
13
|
static examples = ['<%= config.bin %> <%= command.id %> MyFunction'];
|
|
10
14
|
async run() {
|
|
11
15
|
const { success, error } = await functionEnvListCore({
|
|
12
16
|
bin: this.config.bin,
|
|
13
|
-
log: (
|
|
17
|
+
log: Logger(this.log.bind(this), this.flags),
|
|
14
18
|
args: this.args,
|
|
15
19
|
auth: this.auth,
|
|
16
20
|
blueprint: this.blueprint,
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { DeployedStackCommand } from '../../../baseCommands.js';
|
|
2
2
|
export default class EnvRemoveCommand extends DeployedStackCommand<typeof EnvRemoveCommand> {
|
|
3
|
+
static summary: string;
|
|
4
|
+
static description: string;
|
|
3
5
|
static args: {
|
|
4
6
|
name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
7
|
key: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
8
|
};
|
|
7
|
-
static description: string;
|
|
8
9
|
static examples: string[];
|
|
9
10
|
run(): Promise<void>;
|
|
10
11
|
}
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import { Args } from '@oclif/core';
|
|
2
2
|
import { DeployedStackCommand } from '../../../baseCommands.js';
|
|
3
3
|
import { functionEnvRemoveCore } from '../../../cores/functions/env/remove.js';
|
|
4
|
+
import { Logger } from '../../../utils/logger.js';
|
|
4
5
|
export default class EnvRemoveCommand extends DeployedStackCommand {
|
|
6
|
+
static summary = 'Remove an environment variable from a deployed function';
|
|
7
|
+
static description = `Deletes an environment variable from a deployed Sanity Function. The change takes effect on the next function invocation.
|
|
8
|
+
|
|
9
|
+
Use 'functions env list' to see current variables before removing.`;
|
|
5
10
|
static args = {
|
|
6
11
|
name: Args.string({ description: 'The name of the Sanity Function', required: true }),
|
|
7
12
|
key: Args.string({ description: 'The name of the environment variable', required: true }),
|
|
8
13
|
};
|
|
9
|
-
static description = 'Remove an environment variable for a Sanity function';
|
|
10
14
|
static examples = ['<%= config.bin %> <%= command.id %> MyFunction API_URL'];
|
|
11
15
|
async run() {
|
|
12
16
|
const { success, error } = await functionEnvRemoveCore({
|
|
13
17
|
bin: this.config.bin,
|
|
14
|
-
log: (
|
|
18
|
+
log: Logger(this.log.bind(this), this.flags),
|
|
15
19
|
args: this.args,
|
|
16
20
|
auth: this.auth,
|
|
17
21
|
blueprint: this.blueprint,
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { DeployedStackCommand } from '../../baseCommands.js';
|
|
2
2
|
export default class LogsCommand extends DeployedStackCommand<typeof LogsCommand> {
|
|
3
|
+
static summary: string;
|
|
4
|
+
static description: string;
|
|
3
5
|
static args: {
|
|
4
6
|
name: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
5
7
|
};
|
|
6
|
-
static description: string;
|
|
7
8
|
static examples: string[];
|
|
8
9
|
static flags: {
|
|
9
10
|
limit: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { Args, Flags } from '@oclif/core';
|
|
2
2
|
import { DeployedStackCommand } from '../../baseCommands.js';
|
|
3
3
|
import { functionLogsCore } from '../../cores/functions/logs.js';
|
|
4
|
+
import { Logger } from '../../utils/logger.js';
|
|
4
5
|
export default class LogsCommand extends DeployedStackCommand {
|
|
6
|
+
static summary = 'Retrieve or delete logs for a Sanity Function';
|
|
7
|
+
static description = `Fetches execution logs from a deployed function, useful for debugging production issues or monitoring activity.
|
|
8
|
+
|
|
9
|
+
Use --watch (-w) to stream logs in real-time. Use --delete to clear all logs for a function (requires confirmation unless --force is specified).`;
|
|
5
10
|
static args = {
|
|
6
11
|
name: Args.string({ description: 'The name of the Sanity Function', required: false }),
|
|
7
12
|
};
|
|
8
|
-
static description = 'Retrieve or delete logs for a Sanity Function';
|
|
9
13
|
static examples = [
|
|
10
14
|
'<%= config.bin %> <%= command.id %> <name>',
|
|
11
15
|
'<%= config.bin %> <%= command.id %> <name> --json',
|
|
@@ -48,12 +52,11 @@ export default class LogsCommand extends DeployedStackCommand {
|
|
|
48
52
|
}),
|
|
49
53
|
};
|
|
50
54
|
async run() {
|
|
51
|
-
const { name } = this.args;
|
|
52
55
|
const { success, error } = await functionLogsCore({
|
|
53
56
|
bin: this.config.bin,
|
|
54
|
-
log: (
|
|
57
|
+
log: Logger(this.log.bind(this), this.flags),
|
|
55
58
|
error: (msg, options) => this.error(msg, options),
|
|
56
|
-
args:
|
|
59
|
+
args: this.args,
|
|
57
60
|
flags: this.flags,
|
|
58
61
|
auth: this.auth,
|
|
59
62
|
blueprint: this.blueprint,
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { LocalBlueprintCommand } from '../../baseCommands.js';
|
|
2
2
|
export default class TestCommand extends LocalBlueprintCommand<typeof TestCommand> {
|
|
3
|
+
static summary: string;
|
|
4
|
+
static description: string;
|
|
3
5
|
static args: {
|
|
4
6
|
name: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
5
7
|
};
|
|
6
|
-
static description: string;
|
|
7
8
|
static examples: string[];
|
|
8
9
|
static flags: {
|
|
9
10
|
data: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { Args, Flags } from '@oclif/core';
|
|
2
2
|
import { LocalBlueprintCommand } from '../../baseCommands.js';
|
|
3
3
|
import { functionTestCore } from '../../cores/functions/test.js';
|
|
4
|
+
import { Logger } from '../../utils/logger.js';
|
|
4
5
|
export default class TestCommand extends LocalBlueprintCommand {
|
|
6
|
+
static summary = 'Invoke a local Sanity Function';
|
|
7
|
+
static description = `Executes a function locally with the provided payload, simulating how it would run when deployed. Use this to test your function logic before deploying.
|
|
8
|
+
|
|
9
|
+
Provide test data via --data (inline JSON), --file (JSON file), or --document-id (fetch from Sanity). For update events, use the before/after flag pairs to simulate document changes.`;
|
|
5
10
|
static args = {
|
|
6
11
|
name: Args.string({ description: 'The name of the Sanity Function', required: false }),
|
|
7
12
|
};
|
|
8
|
-
static description = 'Invoke a local Sanity Function';
|
|
9
13
|
static examples = [
|
|
10
14
|
`<%= config.bin %> <%= command.id %> <name> --data '{ "id": 1 }'`,
|
|
11
15
|
`<%= config.bin %> <%= command.id %> <name> --file 'payload.json'`,
|
|
@@ -165,7 +169,7 @@ export default class TestCommand extends LocalBlueprintCommand {
|
|
|
165
169
|
}
|
|
166
170
|
const { success, error } = await functionTestCore({
|
|
167
171
|
bin: this.config.bin,
|
|
168
|
-
log: (
|
|
172
|
+
log: Logger(this.log.bind(this), this.flags),
|
|
169
173
|
error: (msg, options) => this.error(msg, options),
|
|
170
174
|
args: { ...this.args, name },
|
|
171
175
|
flags: this.flags,
|
|
@@ -4,7 +4,7 @@ import { filePathRelativeToCwd, labeledId, warn } from '../../utils/display/pres
|
|
|
4
4
|
import { promptForProject, promptForStack } from '../../utils/display/prompt.js';
|
|
5
5
|
export async function blueprintConfigCore(options) {
|
|
6
6
|
const { bin = 'sanity', blueprint, log, token, flags } = options;
|
|
7
|
-
const { edit: editConfig = false, 'project-id': flagProjectId, 'organization-id': flagOrganizationId, 'stack-id': flagStackId, verbose:
|
|
7
|
+
const { edit: editConfig = false, 'project-id': flagProjectId, 'organization-id': flagOrganizationId, 'stack-id': flagStackId, verbose: _v = false, } = flags;
|
|
8
8
|
const providedConfigFlag = [flagProjectId, flagStackId, flagOrganizationId].some(Boolean);
|
|
9
9
|
const { stackId: configStackId, scopeType: configScopeType, scopeId: configScopeId, blueprintConfig, fileInfo, } = blueprint;
|
|
10
10
|
const blueprintFilePath = fileInfo.blueprintFilePath;
|
|
@@ -17,7 +17,7 @@ export async function blueprintConfigCore(options) {
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
if (blueprintConfig)
|
|
20
|
-
printConfig({ configLabel: 'Current', log, config: blueprintConfig
|
|
20
|
+
printConfig({ configLabel: 'Current', log, config: blueprintConfig });
|
|
21
21
|
// passing new config without --edit flag is not allowed
|
|
22
22
|
if (providedConfigFlag && !editConfig) {
|
|
23
23
|
log('To update the configuration, use the --edit flag.');
|
|
@@ -40,7 +40,7 @@ export async function blueprintConfigCore(options) {
|
|
|
40
40
|
configUpdate.organizationId = flagOrganizationId;
|
|
41
41
|
try {
|
|
42
42
|
const newConfig = patchConfigFile(blueprintFilePath, configUpdate);
|
|
43
|
-
printConfig({ configLabel: 'Updated', log, config: newConfig
|
|
43
|
+
printConfig({ configLabel: 'Updated', log, config: newConfig });
|
|
44
44
|
return { success: true };
|
|
45
45
|
}
|
|
46
46
|
catch {
|
|
@@ -54,6 +54,7 @@ export async function blueprintConfigCore(options) {
|
|
|
54
54
|
const pickedProject = await promptForProject({
|
|
55
55
|
token,
|
|
56
56
|
knownProjectId: configScopeId,
|
|
57
|
+
logger: log,
|
|
57
58
|
});
|
|
58
59
|
updatedProjectId = pickedProject.projectId;
|
|
59
60
|
}
|
|
@@ -61,18 +62,18 @@ export async function blueprintConfigCore(options) {
|
|
|
61
62
|
return { success: false, error: 'Project ID is required.' };
|
|
62
63
|
let updatedStackId = flagStackId;
|
|
63
64
|
if (!updatedStackId) {
|
|
64
|
-
const pickedStack = await promptForStack({ projectId: updatedProjectId, token });
|
|
65
|
+
const pickedStack = await promptForStack({ projectId: updatedProjectId, token, logger: log });
|
|
65
66
|
updatedStackId = pickedStack.stackId;
|
|
66
67
|
}
|
|
67
68
|
if (!updatedStackId)
|
|
68
69
|
return { success: false, error: 'Stack is required.' };
|
|
69
70
|
try {
|
|
70
71
|
// update or create config JSON
|
|
71
|
-
const newConfig =
|
|
72
|
+
const newConfig = writeConfigFile(blueprintFilePath, {
|
|
72
73
|
projectId: updatedProjectId,
|
|
73
74
|
stackId: updatedStackId,
|
|
74
75
|
});
|
|
75
|
-
printConfig({ configLabel: 'Updated', log, config: newConfig
|
|
76
|
+
printConfig({ configLabel: 'Updated', log, config: newConfig });
|
|
76
77
|
return { success: true };
|
|
77
78
|
}
|
|
78
79
|
catch {
|
|
@@ -81,12 +82,11 @@ export async function blueprintConfigCore(options) {
|
|
|
81
82
|
}
|
|
82
83
|
}
|
|
83
84
|
function printConfig(options) {
|
|
84
|
-
const { configLabel, log, config
|
|
85
|
+
const { configLabel, log, config } = options;
|
|
85
86
|
const { projectId, organizationId, stackId, updatedAt } = config;
|
|
86
87
|
const scopeType = projectId ? 'project' : 'organization';
|
|
87
88
|
const scopeId = projectId ? projectId : organizationId;
|
|
88
|
-
|
|
89
|
-
log(JSON.stringify(config));
|
|
89
|
+
log.verbose(JSON.stringify(config));
|
|
90
90
|
log(`${chalk.bold(`${configLabel} configuration:`)}`);
|
|
91
91
|
log(` Deployment: ${labeledId('stack', stackId)}`);
|
|
92
92
|
log(` Scoped to: ${labeledId(scopeType, scopeId)}`);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { setTimeout } from 'node:timers/promises';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
|
-
import ora from 'ora';
|
|
4
3
|
import { stashAsset } from '../../actions/blueprints/assets.js';
|
|
5
4
|
import { setupLogStreaming } from '../../actions/blueprints/logs-streaming.js';
|
|
6
5
|
import { getStack, updateStack } from '../../actions/blueprints/stacks.js';
|
|
@@ -8,7 +7,7 @@ import { niceId } from '../../utils/display/presenters.js';
|
|
|
8
7
|
import { isLocalFunctionCollection, isLocalFunctionResource } from '../../utils/types.js';
|
|
9
8
|
export async function blueprintDeployCore(options) {
|
|
10
9
|
const { bin = 'sanity', log, auth, stackId, scopeType, scopeId, deployedStack, blueprint, flags, } = options;
|
|
11
|
-
const { verbose } = flags;
|
|
10
|
+
const { verbose: _verbose } = flags;
|
|
12
11
|
const noWait = flags['no-wait'] || false;
|
|
13
12
|
log(`Deploying "${deployedStack.name}" ${niceId(deployedStack.id)}...`);
|
|
14
13
|
try {
|
|
@@ -21,8 +20,8 @@ export async function blueprintDeployCore(options) {
|
|
|
21
20
|
if (allFunctionResources.length > 0) {
|
|
22
21
|
log('Processing function assets...');
|
|
23
22
|
for (const resource of allFunctionResources) {
|
|
24
|
-
const fnSpinner = ora({ text: `Processing ${resource.name}...`, prefixText: ' ' }).start();
|
|
25
|
-
const result = await stashAsset({ resource, auth });
|
|
23
|
+
const fnSpinner = log.ora({ text: `Processing ${resource.name}...`, prefixText: ' ' }).start();
|
|
24
|
+
const result = await stashAsset({ resource, auth, logger: log });
|
|
26
25
|
if (result.success && result.assetId) {
|
|
27
26
|
resource.src = result.assetId;
|
|
28
27
|
if (isLocalFunctionCollection(resource)) {
|
|
@@ -45,18 +44,16 @@ export async function blueprintDeployCore(options) {
|
|
|
45
44
|
fnSpinner.succeed(`${resource.name} ${niceId(result.assetId)}`);
|
|
46
45
|
log(` Source: ${resource.src}`);
|
|
47
46
|
}
|
|
48
|
-
if (
|
|
49
|
-
if (result.hash) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
log(` Hash: ${result.hash}`);
|
|
55
|
-
}
|
|
47
|
+
if (result.hash) {
|
|
48
|
+
if (result.hash.length > 24) {
|
|
49
|
+
log.verbose(` Hash: ${result.hash.slice(0, 8)}...${result.hash.slice(-12)}`);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
log.verbose(` Hash: ${result.hash}`);
|
|
56
53
|
}
|
|
57
|
-
if (result.exists)
|
|
58
|
-
log(' Asset unchanged');
|
|
59
54
|
}
|
|
55
|
+
if (result.exists)
|
|
56
|
+
log.verbose(' Asset unchanged');
|
|
60
57
|
}
|
|
61
58
|
else {
|
|
62
59
|
const errorMsg = isLocalFunctionCollection(resource)
|
|
@@ -67,7 +64,7 @@ export async function blueprintDeployCore(options) {
|
|
|
67
64
|
}
|
|
68
65
|
}
|
|
69
66
|
}
|
|
70
|
-
const spinner = ora('Deploying...').start();
|
|
67
|
+
const spinner = log.ora('Deploying...').start();
|
|
71
68
|
const isoNow = new Date().toISOString();
|
|
72
69
|
const { ok: deployOk, stack, error: deployError, } = await updateStack({
|
|
73
70
|
stackId,
|
|
@@ -78,6 +75,7 @@ export async function blueprintDeployCore(options) {
|
|
|
78
75
|
document: { resources: validResources },
|
|
79
76
|
},
|
|
80
77
|
auth,
|
|
78
|
+
logger: log,
|
|
81
79
|
});
|
|
82
80
|
if (!deployOk) {
|
|
83
81
|
spinner.fail(`${chalk.red('Failed')} to update Stack deployment`);
|
|
@@ -99,7 +97,7 @@ export async function blueprintDeployCore(options) {
|
|
|
99
97
|
log,
|
|
100
98
|
});
|
|
101
99
|
while (true) {
|
|
102
|
-
const { ok, stack: currentStack } = await getStack({ stackId: stack.id, auth });
|
|
100
|
+
const { ok, stack: currentStack } = await getStack({ stackId: stack.id, auth, logger: log });
|
|
103
101
|
if (!ok) {
|
|
104
102
|
if (logStreamCleanup)
|
|
105
103
|
logStreamCleanup();
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { setTimeout } from 'node:timers/promises';
|
|
2
2
|
import { confirm } from '@inquirer/prompts';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
|
-
import ora from 'ora';
|
|
5
4
|
import { setupLogStreaming } from '../../actions/blueprints/logs-streaming.js';
|
|
6
5
|
import { destroyStack, getStack } from '../../actions/blueprints/stacks.js';
|
|
7
6
|
import { niceId } from '../../utils/display/presenters.js';
|
|
@@ -26,6 +25,7 @@ export async function blueprintDestroyCore(options) {
|
|
|
26
25
|
const { ok, error, stack } = await destroyStack({
|
|
27
26
|
stackId: flagStackId,
|
|
28
27
|
auth: { token, scopeType, scopeId },
|
|
28
|
+
logger: log,
|
|
29
29
|
});
|
|
30
30
|
if (!ok)
|
|
31
31
|
return { success: false, error: error || 'Failed to destroy Stack deployment' };
|
|
@@ -39,20 +39,20 @@ export async function blueprintDestroyCore(options) {
|
|
|
39
39
|
let stack;
|
|
40
40
|
try {
|
|
41
41
|
if (flagStackId) {
|
|
42
|
-
const flagStack = await getStack({ stackId: flagStackId, auth });
|
|
42
|
+
const flagStack = await getStack({ stackId: flagStackId, auth, logger: log });
|
|
43
43
|
if (!flagStack.ok)
|
|
44
44
|
return { success: false, error: flagStack.error || 'Failed to get Stack' };
|
|
45
45
|
stack = flagStack.stack;
|
|
46
46
|
}
|
|
47
47
|
else if (stackId) {
|
|
48
|
-
const blueprintStack = await getStack({ stackId, auth });
|
|
48
|
+
const blueprintStack = await getStack({ stackId, auth, logger: log });
|
|
49
49
|
if (!blueprintStack.ok)
|
|
50
50
|
return { success: false, error: blueprintStack.error || 'Failed to get Stack' };
|
|
51
51
|
stack = blueprintStack.stack;
|
|
52
52
|
}
|
|
53
53
|
if (!stack)
|
|
54
54
|
return { success: false, error: 'Stack deployment not found' };
|
|
55
|
-
const destroySpinner = ora({
|
|
55
|
+
const destroySpinner = log.ora({
|
|
56
56
|
text: `Destroying Stack deployment "${chalk.bold(stack.name)}" ${niceId(stack.id)}...`,
|
|
57
57
|
color: 'red',
|
|
58
58
|
});
|
|
@@ -79,7 +79,7 @@ export async function blueprintDestroyCore(options) {
|
|
|
79
79
|
destroySpinner.start();
|
|
80
80
|
}
|
|
81
81
|
const isoNow = new Date().toISOString();
|
|
82
|
-
const { ok, error } = await destroyStack({ stackId: stack.id, auth });
|
|
82
|
+
const { ok, error } = await destroyStack({ stackId: stack.id, auth, logger: log });
|
|
83
83
|
if (!ok) {
|
|
84
84
|
destroySpinner.fail('Failed to destroy Stack deployment');
|
|
85
85
|
return { success: false, error: error || 'Failed to destroy Stack deployment' };
|
|
@@ -99,7 +99,7 @@ export async function blueprintDestroyCore(options) {
|
|
|
99
99
|
log,
|
|
100
100
|
});
|
|
101
101
|
while (true) {
|
|
102
|
-
const { ok, stack: currentStack } = await getStack({ stackId: stack.id, auth });
|
|
102
|
+
const { ok, stack: currentStack } = await getStack({ stackId: stack.id, auth, logger: log });
|
|
103
103
|
const operation = currentStack?.recentOperation;
|
|
104
104
|
if (!ok || !operation || operation?.status === 'COMPLETED') {
|
|
105
105
|
// Operation is also marked destroyed when stack is deleted;
|
|
@@ -4,6 +4,7 @@ import { findBlueprintFile, readLocalBlueprint, } from '../../actions/blueprints
|
|
|
4
4
|
import { getStack } from '../../actions/blueprints/stacks.js';
|
|
5
5
|
import config from '../../config.js';
|
|
6
6
|
import { capitalize, check, filePathRelativeToCwd, indent, niceId, severe, unsure, } from '../../utils/display/presenters.js';
|
|
7
|
+
import { createTracedFetch } from '../../utils/traced-fetch.js';
|
|
7
8
|
import { validTokenOrErrorMessage } from '../../utils/validated-token.js';
|
|
8
9
|
import { blueprintConfigCore } from './config.js';
|
|
9
10
|
const diagLookup = {
|
|
@@ -20,24 +21,23 @@ const diagLookup = {
|
|
|
20
21
|
export async function blueprintDoctorCore(options) {
|
|
21
22
|
const { bin, log, token, flags: { verbose: v, path: p, fix }, } = options;
|
|
22
23
|
const yikes = (s) => {
|
|
23
|
-
log(chalk.bgRedBright.whiteBright.bold(` ${s} `));
|
|
24
|
+
log.error(chalk.bgRedBright.whiteBright.bold(` ${s} `));
|
|
24
25
|
};
|
|
25
26
|
const here = cwd();
|
|
26
27
|
const path = p || here;
|
|
27
28
|
let tokenOrError;
|
|
28
|
-
|
|
29
|
-
log(`Checking ${filePathRelativeToCwd(path)}`);
|
|
29
|
+
log.verbose(`Checking ${filePathRelativeToCwd(path)}`);
|
|
30
30
|
// 3 states: null == unknown, true == good, false == bad
|
|
31
31
|
const diagnostics = {};
|
|
32
32
|
for (const key in diagLookup) {
|
|
33
33
|
diagnostics[key] = null;
|
|
34
34
|
}
|
|
35
35
|
// ONLINE
|
|
36
|
+
const fetchFn = createTracedFetch(log);
|
|
36
37
|
try {
|
|
37
|
-
const res = await
|
|
38
|
+
const res = await fetchFn(config.apiUrl);
|
|
38
39
|
if (res.ok) {
|
|
39
|
-
|
|
40
|
-
log(`Successfully pinged ${config.apiUrl}`);
|
|
40
|
+
log.verbose(`Successfully pinged ${config.apiUrl}`);
|
|
41
41
|
diagnostics.online = res.ok;
|
|
42
42
|
}
|
|
43
43
|
else {
|
|
@@ -51,7 +51,7 @@ export async function blueprintDoctorCore(options) {
|
|
|
51
51
|
// TOKEN
|
|
52
52
|
if (token) {
|
|
53
53
|
diagnostics.tokenPresent = true;
|
|
54
|
-
tokenOrError = await validTokenOrErrorMessage(token);
|
|
54
|
+
tokenOrError = await validTokenOrErrorMessage(log, token);
|
|
55
55
|
if (tokenOrError.ok) {
|
|
56
56
|
diagnostics.tokenValid = true;
|
|
57
57
|
}
|
|
@@ -66,8 +66,7 @@ export async function blueprintDoctorCore(options) {
|
|
|
66
66
|
// BLUEPRINT file
|
|
67
67
|
const blueprintFile = findBlueprintFile(path);
|
|
68
68
|
if (blueprintFile?.blueprintFilePath) {
|
|
69
|
-
|
|
70
|
-
log(`Found blueprint file at ${blueprintFile.blueprintFilePath.replace(here, '.')}`);
|
|
69
|
+
log.verbose(`Found blueprint file at ${blueprintFile.blueprintFilePath.replace(here, '.')}`);
|
|
71
70
|
diagnostics.blueprintPresent = true;
|
|
72
71
|
}
|
|
73
72
|
else {
|
|
@@ -75,21 +74,18 @@ export async function blueprintDoctorCore(options) {
|
|
|
75
74
|
}
|
|
76
75
|
let blueprint;
|
|
77
76
|
try {
|
|
78
|
-
blueprint = await readLocalBlueprint(path);
|
|
77
|
+
blueprint = await readLocalBlueprint(log, path);
|
|
79
78
|
if (blueprint.errors.length === 0) {
|
|
80
|
-
|
|
81
|
-
log(`Blueprint has no errors`);
|
|
79
|
+
log.verbose(`Blueprint has no errors`);
|
|
82
80
|
diagnostics.blueprintValid = true;
|
|
83
81
|
}
|
|
84
82
|
else {
|
|
85
|
-
|
|
86
|
-
log(`Blueprint errors: \n${blueprint.errors.join('\n ')}`);
|
|
83
|
+
log.verbose(`Blueprint errors: \n${blueprint.errors.join('\n ')}`);
|
|
87
84
|
diagnostics.blueprintValid = false;
|
|
88
85
|
}
|
|
89
86
|
}
|
|
90
87
|
catch {
|
|
91
|
-
|
|
92
|
-
yikes(`Unable to read blueprint`);
|
|
88
|
+
yikes(`Unable to read blueprint`);
|
|
93
89
|
diagnostics.blueprintValid = false;
|
|
94
90
|
}
|
|
95
91
|
if (blueprint) {
|
|
@@ -97,18 +93,15 @@ export async function blueprintDoctorCore(options) {
|
|
|
97
93
|
const configPath = blueprintConfig?.configPath;
|
|
98
94
|
// CONFIG file
|
|
99
95
|
if (configPath) {
|
|
100
|
-
|
|
101
|
-
log(`Found config file at ${configPath.replace(here, '.')}`);
|
|
96
|
+
log.verbose(`Found config file at ${configPath.replace(here, '.')}`);
|
|
102
97
|
diagnostics.configFilePresent = true;
|
|
103
98
|
if (scopeType && scopeId && stackId) {
|
|
104
99
|
diagnostics.configFileValid = true;
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
log(indent(configOutput));
|
|
111
|
-
}
|
|
100
|
+
const configOutput = [
|
|
101
|
+
`${capitalize(scopeType)}: ${niceId(scopeId)}`,
|
|
102
|
+
`Deployment: ${niceId(stackId)}`,
|
|
103
|
+
].join('\n');
|
|
104
|
+
log.verbose(indent(configOutput));
|
|
112
105
|
}
|
|
113
106
|
else {
|
|
114
107
|
diagnostics.configFileValid = false;
|
|
@@ -122,10 +115,10 @@ export async function blueprintDoctorCore(options) {
|
|
|
122
115
|
const stackResponse = await getStack({
|
|
123
116
|
auth: { token, scopeType: 'project', scopeId: projectId },
|
|
124
117
|
stackId,
|
|
118
|
+
logger: log,
|
|
125
119
|
});
|
|
126
120
|
if (stackResponse.ok) {
|
|
127
|
-
|
|
128
|
-
log(`Deployment "Stack" ${niceId(stackId)} ready`);
|
|
121
|
+
log.verbose(`Deployment "Stack" ${niceId(stackId)} ready`);
|
|
129
122
|
diagnostics.stackReady = true;
|
|
130
123
|
diagnostics.userHasAccess = true;
|
|
131
124
|
}
|
|
@@ -8,9 +8,9 @@ export async function blueprintInfoCore(options) {
|
|
|
8
8
|
const targetStackId = flagStackId || stackId;
|
|
9
9
|
let stack = deployedStack;
|
|
10
10
|
if (flagStackId) {
|
|
11
|
-
const existingStackResponse = await getStack({ stackId: targetStackId, auth });
|
|
11
|
+
const existingStackResponse = await getStack({ stackId: targetStackId, auth, logger: log });
|
|
12
12
|
if (!existingStackResponse.ok) {
|
|
13
|
-
log(`Could not retrieve Stack deployment info for ${niceId(targetStackId)}`);
|
|
13
|
+
log.error(`Could not retrieve Stack deployment info for ${niceId(targetStackId)}`);
|
|
14
14
|
return {
|
|
15
15
|
success: false,
|
|
16
16
|
error: existingStackResponse.error || 'Failed to retrieve Stack deployment',
|
|
@@ -25,7 +25,7 @@ export async function blueprintInfoCore(options) {
|
|
|
25
25
|
}
|
|
26
26
|
catch (error) {
|
|
27
27
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
28
|
-
log(`Error: ${errorMessage}`);
|
|
28
|
+
log.error(`Error: ${errorMessage}`);
|
|
29
29
|
return {
|
|
30
30
|
success: false,
|
|
31
31
|
error: errorMessage,
|
|
@@ -33,13 +33,13 @@ export declare function resolveScopeAndStack(params: {
|
|
|
33
33
|
organizationId: string | undefined;
|
|
34
34
|
stackId: string | undefined;
|
|
35
35
|
stackName: string | undefined;
|
|
36
|
-
log:
|
|
36
|
+
log: CoreConfig['log'];
|
|
37
37
|
token: string;
|
|
38
38
|
}): Promise<ResolvedScope>;
|
|
39
39
|
export declare function determineBlueprintExtension(params: {
|
|
40
40
|
requestedType: string | undefined;
|
|
41
41
|
blueprintDir: string;
|
|
42
|
-
log:
|
|
42
|
+
log: CoreConfig['log'];
|
|
43
43
|
}): Promise<string>;
|
|
44
44
|
export declare function createBlueprintFiles(params: {
|
|
45
45
|
blueprintDir: string;
|
|
@@ -49,6 +49,6 @@ export declare function createBlueprintFiles(params: {
|
|
|
49
49
|
scopeId: string;
|
|
50
50
|
stackId: string | undefined;
|
|
51
51
|
bin: string;
|
|
52
|
-
log:
|
|
52
|
+
log: CoreConfig['log'];
|
|
53
53
|
}): Promise<CoreResult>;
|
|
54
54
|
export {};
|
|
@@ -33,7 +33,7 @@ export async function blueprintInitCore(options) {
|
|
|
33
33
|
// look for existing blueprint file and maybe re-configure it
|
|
34
34
|
const existingBlueprintFile = findBlueprintFile(blueprintDir);
|
|
35
35
|
if (existingBlueprintFile) {
|
|
36
|
-
log(warn(`Existing Blueprint found: ${filePathRelativeToCwd(existingBlueprintFile.blueprintFilePath)}`));
|
|
36
|
+
log.warn(warn(`Existing Blueprint found: ${filePathRelativeToCwd(existingBlueprintFile.blueprintFilePath)}`));
|
|
37
37
|
if (flagExample) {
|
|
38
38
|
return {
|
|
39
39
|
success: false,
|
|
@@ -54,7 +54,7 @@ export async function blueprintInitCore(options) {
|
|
|
54
54
|
if (!overwrite)
|
|
55
55
|
return { success: false, error: 'Initialization cancelled.' };
|
|
56
56
|
}
|
|
57
|
-
const existingBlueprint = await readLocalBlueprint(existingBlueprintFile.blueprintFilePath);
|
|
57
|
+
const existingBlueprint = await readLocalBlueprint(log, existingBlueprintFile.blueprintFilePath);
|
|
58
58
|
return blueprintConfigCore({
|
|
59
59
|
blueprint: existingBlueprint,
|
|
60
60
|
bin,
|
|
@@ -121,16 +121,21 @@ export function validateFlags(flags) {
|
|
|
121
121
|
async function handleExampleInitialization(options) {
|
|
122
122
|
const { exampleName, blueprintDir, userProvidedDirName, projectId, token, log } = options;
|
|
123
123
|
log(warn(`Example feature is experimental. Setting up "${exampleName}"...`));
|
|
124
|
-
const exampleExists = await verifyExampleExists({
|
|
124
|
+
const exampleExists = await verifyExampleExists({
|
|
125
|
+
type: 'blueprint',
|
|
126
|
+
name: exampleName,
|
|
127
|
+
logger: log,
|
|
128
|
+
});
|
|
125
129
|
if (!exampleExists) {
|
|
126
130
|
return { success: false, error: `Blueprint example "${exampleName}" does not exist.` };
|
|
127
131
|
}
|
|
128
|
-
const resolvedProjectId = projectId || (await promptForProject({ token })).projectId;
|
|
132
|
+
const resolvedProjectId = projectId || (await promptForProject({ token, logger: log })).projectId;
|
|
129
133
|
const stack = await createEmptyStack({
|
|
130
134
|
token,
|
|
131
135
|
scopeType: SCOPE_PROJECT,
|
|
132
136
|
scopeId: resolvedProjectId,
|
|
133
137
|
name: `example-${exampleName}`,
|
|
138
|
+
logger: log,
|
|
134
139
|
});
|
|
135
140
|
const exampleDir = userProvidedDirName || join(blueprintDir, exampleName);
|
|
136
141
|
if (existsSync(exampleDir)) {
|
|
@@ -140,6 +145,7 @@ async function handleExampleInitialization(options) {
|
|
|
140
145
|
exampleType: 'blueprint',
|
|
141
146
|
exampleName,
|
|
142
147
|
dir: exampleDir,
|
|
148
|
+
logger: log,
|
|
143
149
|
});
|
|
144
150
|
if (!addedExample) {
|
|
145
151
|
return { success: false, error: `Unable to download example "${exampleName}"` };
|
|
@@ -184,18 +190,19 @@ export async function resolveScopeAndStack(params) {
|
|
|
184
190
|
scopeType,
|
|
185
191
|
scopeId,
|
|
186
192
|
name: stackName,
|
|
193
|
+
logger: log,
|
|
187
194
|
});
|
|
188
195
|
resolvedStackId = stack.id;
|
|
189
196
|
}
|
|
190
197
|
if (!scopeId) {
|
|
191
198
|
log('\nBlueprints are associated with a Sanity Project. Please select one:');
|
|
192
|
-
const pickedProject = await promptForProject({ token });
|
|
199
|
+
const pickedProject = await promptForProject({ token, logger: log });
|
|
193
200
|
scopeType = SCOPE_PROJECT;
|
|
194
201
|
scopeId = pickedProject.projectId;
|
|
195
202
|
}
|
|
196
203
|
if (!resolvedStackId) {
|
|
197
204
|
log('\nBlueprints are deployed to a "Stack".');
|
|
198
|
-
const { stackId } = await promptForStack({ projectId: scopeId, token });
|
|
205
|
+
const { stackId } = await promptForStack({ projectId: scopeId, token, logger: log });
|
|
199
206
|
resolvedStackId = stackId;
|
|
200
207
|
}
|
|
201
208
|
return {
|
|
@@ -252,11 +259,11 @@ export async function createBlueprintFiles(params) {
|
|
|
252
259
|
if (blueprintExtension !== 'json') {
|
|
253
260
|
const blueprintsPackage = '@sanity/blueprints';
|
|
254
261
|
try {
|
|
255
|
-
await writeOrUpdateNodeDependency(blueprintFilePath, blueprintsPackage);
|
|
262
|
+
await writeOrUpdateNodeDependency(blueprintFilePath, blueprintsPackage, log);
|
|
256
263
|
log(check(`${chalk.bold('Added dependency:')} ${blueprintsPackage}`));
|
|
257
264
|
}
|
|
258
265
|
catch {
|
|
259
|
-
log(warn(`Unable to add ${blueprintsPackage} to your project.`));
|
|
266
|
+
log.warn(warn(`Unable to add ${blueprintsPackage} to your project.`));
|
|
260
267
|
}
|
|
261
268
|
}
|
|
262
269
|
const nextStepParts = [];
|