@sanity/runtime-cli 17.4.0-blueprinit.g0ac8878 → 17.4.0-blueprinit.g596ac51
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 +50 -47
- package/SKILL.md +50 -12
- package/dist/actions/blueprinit/manifest.js +21 -15
- package/dist/actions/blueprints/pre-deploy.d.ts +15 -6
- package/dist/actions/blueprints/pre-deploy.js +29 -70
- package/dist/actions/blueprints/process-assets.d.ts +29 -0
- package/dist/actions/blueprints/process-assets.js +80 -0
- package/dist/commands/blueprints/deploy.js +3 -1
- package/dist/commands/blueprints/destroy.js +1 -1
- package/dist/commands/blueprints/info.d.ts +1 -0
- package/dist/commands/blueprints/info.js +5 -0
- package/dist/commands/blueprints/init.js +1 -2
- package/dist/commands/blueprints/logs.js +1 -0
- package/dist/commands/functions/add.js +3 -3
- package/dist/commands/functions/dev.js +2 -2
- package/dist/commands/functions/logs.d.ts +1 -1
- package/dist/commands/functions/logs.js +3 -0
- package/dist/cores/blueprints/deploy.js +69 -19
- package/dist/cores/functions/add.js +1 -1
- package/dist/utils/display/blueprints-formatting.js +3 -3
- package/dist/utils/style-text.js +1 -0
- package/oclif.manifest.json +21 -15
- package/package.json +27 -17
- package/skills/_functions-build.md +23 -0
- package/skills/_functions-list.md +28 -0
- package/skills/blueprints-add.md +8 -0
- package/skills/blueprints-config.md +33 -0
- package/skills/blueprints-deploy.md +36 -0
- package/skills/blueprints-destroy.md +30 -0
- package/skills/blueprints-doctor.md +31 -0
- package/skills/blueprints-info.md +23 -0
- package/skills/blueprints-init.md +48 -0
- package/skills/blueprints-logs.md +33 -0
- package/skills/blueprints-mint-deploy-token.md +25 -0
- package/skills/blueprints-plan.md +28 -0
- package/skills/blueprints-promote.md +31 -0
- package/skills/blueprints-stacks.md +28 -0
- package/skills/functions-add.md +35 -0
- package/skills/functions-dev.md +21 -0
- package/skills/functions-env-add.md +29 -0
- package/skills/functions-env-list.md +21 -0
- package/skills/functions-env-remove.md +22 -0
- package/skills/functions-logs.md +39 -0
- package/skills/functions-test.md +31 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Logger } from '../../utils/logger.js';
|
|
2
|
+
import type { AssetResource, AuthParams, InstallerType } from '../../utils/types.js';
|
|
3
|
+
type ProcessAssetsOptions = {
|
|
4
|
+
assetResources: AssetResource[];
|
|
5
|
+
auth: AuthParams;
|
|
6
|
+
blueprintFileDir: string;
|
|
7
|
+
installer: InstallerType;
|
|
8
|
+
logger: Logger;
|
|
9
|
+
onProgress?: (progress: ProcessAssetsProgress) => void;
|
|
10
|
+
onResult?: (result: ProcessedAsset) => void;
|
|
11
|
+
};
|
|
12
|
+
export type ProcessAssetsProgress = {
|
|
13
|
+
completed: number;
|
|
14
|
+
total: number;
|
|
15
|
+
slow: boolean;
|
|
16
|
+
};
|
|
17
|
+
export type ProcessedAsset = {
|
|
18
|
+
success: false;
|
|
19
|
+
resource: AssetResource;
|
|
20
|
+
error: string;
|
|
21
|
+
failureKind: 'processing' | 'upload';
|
|
22
|
+
} | {
|
|
23
|
+
success: true;
|
|
24
|
+
resource: AssetResource;
|
|
25
|
+
hash?: string;
|
|
26
|
+
exists?: boolean;
|
|
27
|
+
};
|
|
28
|
+
export declare function processAssets(options: ProcessAssetsOptions): Promise<ProcessedAsset[]>;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { env } from 'node:process';
|
|
2
|
+
import { stashAsset } from './assets.js';
|
|
3
|
+
const DEFAULT_ASSET_CONCURRENCY = 4;
|
|
4
|
+
const DEFAULT_ASSET_TIMEOUT = 180;
|
|
5
|
+
const assetTimeoutS = Number(env.SANITY_ASSET_TIMEOUT) || DEFAULT_ASSET_TIMEOUT;
|
|
6
|
+
const assetTimeoutMs = assetTimeoutS * 1000;
|
|
7
|
+
const warnTimeoutMs = assetTimeoutMs / 3;
|
|
8
|
+
export async function processAssets(options) {
|
|
9
|
+
const { assetResources, onProgress, onResult } = options;
|
|
10
|
+
const total = assetResources.length;
|
|
11
|
+
const processedAssets = [];
|
|
12
|
+
const concurrency = getAssetConcurrency();
|
|
13
|
+
let completed = 0;
|
|
14
|
+
let slow = false;
|
|
15
|
+
const reportProgress = () => onProgress?.({ completed, total, slow });
|
|
16
|
+
reportProgress();
|
|
17
|
+
const warnTimer = setTimeout(() => {
|
|
18
|
+
slow = true;
|
|
19
|
+
reportProgress();
|
|
20
|
+
}, warnTimeoutMs);
|
|
21
|
+
try {
|
|
22
|
+
for (let start = 0; start < total; start += concurrency) {
|
|
23
|
+
const batch = assetResources.slice(start, start + concurrency);
|
|
24
|
+
const batchResults = await Promise.all(batch.map(async (resource) => {
|
|
25
|
+
const result = await processAsset(resource, options);
|
|
26
|
+
completed += 1;
|
|
27
|
+
reportProgress();
|
|
28
|
+
onResult?.(result);
|
|
29
|
+
return result;
|
|
30
|
+
}));
|
|
31
|
+
processedAssets.push(...batchResults);
|
|
32
|
+
if (batchResults.some((result) => !result.success))
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
finally {
|
|
37
|
+
clearTimeout(warnTimer);
|
|
38
|
+
}
|
|
39
|
+
return processedAssets;
|
|
40
|
+
}
|
|
41
|
+
function getAssetConcurrency() {
|
|
42
|
+
const configured = Number(env.SANITY_ASSET_CONCURRENCY);
|
|
43
|
+
return Number.isSafeInteger(configured) && configured > 0 ? configured : DEFAULT_ASSET_CONCURRENCY;
|
|
44
|
+
}
|
|
45
|
+
async function processAsset(resource, options) {
|
|
46
|
+
const { auth, blueprintFileDir, installer, logger } = options;
|
|
47
|
+
let assetTimeoutTimer;
|
|
48
|
+
let result;
|
|
49
|
+
try {
|
|
50
|
+
result = await Promise.race([
|
|
51
|
+
stashAsset({ resource, blueprintFileDir, auth, logger, installer }),
|
|
52
|
+
new Promise((_, reject) => {
|
|
53
|
+
assetTimeoutTimer = setTimeout(() => {
|
|
54
|
+
reject(new Error(`Processing ${resource.name} timed out after ${assetTimeoutS}s`));
|
|
55
|
+
}, assetTimeoutMs);
|
|
56
|
+
}),
|
|
57
|
+
]);
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
61
|
+
return { success: false, resource, error: msg, failureKind: 'processing' };
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
clearTimeout(assetTimeoutTimer);
|
|
65
|
+
}
|
|
66
|
+
if (result.success && result.assetId) {
|
|
67
|
+
return {
|
|
68
|
+
success: true,
|
|
69
|
+
resource: { ...resource, src: result.assetId },
|
|
70
|
+
hash: result.hash,
|
|
71
|
+
exists: result.exists,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
success: false,
|
|
76
|
+
resource,
|
|
77
|
+
error: result.error || 'Failed to process asset',
|
|
78
|
+
failureKind: 'upload',
|
|
79
|
+
};
|
|
80
|
+
}
|
|
@@ -14,7 +14,9 @@ Use --no-wait to queue the deployment and return immediately without waiting for
|
|
|
14
14
|
|
|
15
15
|
Use --fn-installer to force which package manager to use when deploying functions.
|
|
16
16
|
|
|
17
|
-
Set SANITY_ASSET_TIMEOUT (seconds) to override the
|
|
17
|
+
Set SANITY_ASSET_TIMEOUT (seconds) to override the 180-second timeout for processing resource assets.
|
|
18
|
+
|
|
19
|
+
Set SANITY_ASSET_CONCURRENCY to override how many resource assets are processed at once (default 4).
|
|
18
20
|
|
|
19
21
|
Exit codes: 0 deployed, 2 deployment failed, 75 deployment accepted but completion could not be confirmed (rerun 'blueprints info' to check).`;
|
|
20
22
|
static examples = [
|
|
@@ -19,7 +19,7 @@ Exit codes: 0 destroyed, 2 destruction failed, 75 destruction accepted but compl
|
|
|
19
19
|
static flags = {
|
|
20
20
|
force: Flags.boolean({
|
|
21
21
|
description: 'Force Stack destruction (skip confirmation)',
|
|
22
|
-
|
|
22
|
+
char: 'f',
|
|
23
23
|
default: false,
|
|
24
24
|
}),
|
|
25
25
|
'project-id': Flags.string({
|
|
@@ -8,6 +8,7 @@ export default class InfoCommand extends ResolvedCommand<typeof InfoCommand> {
|
|
|
8
8
|
stack: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
9
|
'project-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
10
|
'organization-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
11
|
+
verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
12
|
};
|
|
12
13
|
run(): Promise<Record<string, unknown> | undefined>;
|
|
13
14
|
}
|
|
@@ -23,6 +23,11 @@ Run 'blueprints stacks' to see all available Stacks in your project or organizat
|
|
|
23
23
|
}),
|
|
24
24
|
'project-id': Flags.string({ ...projectIdFlagConfig }),
|
|
25
25
|
'organization-id': Flags.string({ ...organizationIdFlagConfig }),
|
|
26
|
+
verbose: Flags.boolean({
|
|
27
|
+
char: 'v',
|
|
28
|
+
description: 'Show resource and external IDs',
|
|
29
|
+
default: false,
|
|
30
|
+
}),
|
|
26
31
|
};
|
|
27
32
|
async run() {
|
|
28
33
|
const result = await blueprintInfoCore({
|
|
@@ -6,10 +6,9 @@ import { validTokenOrErrorMessage } from '../../utils/validated-token.js';
|
|
|
6
6
|
export default class InitCommand extends RuntimeCommand {
|
|
7
7
|
static summary = 'Initialize a Blueprint and create a remote Stack';
|
|
8
8
|
static description = `A Blueprint is your local infrastructure-as-code configuration that defines Sanity resources (datasets, functions, etc.). A Stack is the remote deployment target where your Blueprint is applied.
|
|
9
|
-
[NOTE: Currently, accounts are limited to three (3) Stacks per project scope.]
|
|
10
9
|
|
|
11
10
|
This is typically the first command you run in a new project. It creates a local Blueprint manifest file (sanity.blueprint.ts, .js, or .json) and provisions a new remote Stack.
|
|
12
|
-
Additionally, a Blueprint configuration file is created in .sanity/ containing the scope and Stack IDs.
|
|
11
|
+
Additionally, a Blueprint configuration file is created in .sanity/ containing the scope and Stack IDs. A .gitignore covering node_modules, .env, and Function build output is created or updated; the .sanity/ config itself is not ignored.
|
|
13
12
|
|
|
14
13
|
After initialization, use 'blueprints plan' to preview changes, then 'blueprints deploy' to apply them.
|
|
15
14
|
|
|
@@ -23,7 +23,7 @@ After adding, use 'functions dev' to test locally, then 'blueprints deploy' to p
|
|
|
23
23
|
example: Flags.string({
|
|
24
24
|
description: 'Example to use for the Function',
|
|
25
25
|
aliases: ['recipe'],
|
|
26
|
-
exclusive: ['name', '
|
|
26
|
+
exclusive: ['name', 'type', 'language', 'javascript', 'helpers', 'installer', 'install'],
|
|
27
27
|
}),
|
|
28
28
|
name: Flags.string({
|
|
29
29
|
description: 'Name of the Function to add',
|
|
@@ -56,9 +56,9 @@ After adding, use 'functions dev' to test locally, then 'blueprints deploy' to p
|
|
|
56
56
|
options: ['skip', ...INSTALLER_OPTIONS],
|
|
57
57
|
}),
|
|
58
58
|
install: Flags.boolean({
|
|
59
|
-
description: 'Shortcut for --
|
|
59
|
+
description: 'Shortcut for --installer npm',
|
|
60
60
|
char: 'i',
|
|
61
|
-
exclusive: ['
|
|
61
|
+
exclusive: ['installer'],
|
|
62
62
|
}),
|
|
63
63
|
};
|
|
64
64
|
async run() {
|
|
@@ -9,11 +9,11 @@ export default class DevCommand extends ResolvedCommand {
|
|
|
9
9
|
|
|
10
10
|
Open the emulator in your browser to interactively test your functions with the payload editor.
|
|
11
11
|
|
|
12
|
-
Optionally, set the host and port with the --host and --port flags. Function timeout can be configured with the --timeout flag.
|
|
12
|
+
Optionally, set the host and port with the --host and --port flags. Port 8974 is reserved for the emulator's live-reload WebSocket server. Function timeout can be configured with the --timeout flag.
|
|
13
13
|
|
|
14
14
|
To invoke a function with the CLI, use 'functions test'.`;
|
|
15
15
|
static examples = [
|
|
16
|
-
'<%= config.bin %> <%= command.id %> --host 127.0.0.1 --port
|
|
16
|
+
'<%= config.bin %> <%= command.id %> --host 127.0.0.1 --port 3333',
|
|
17
17
|
'<%= config.bin %> <%= command.id %> --timeout 60',
|
|
18
18
|
];
|
|
19
19
|
static flags = {
|
|
@@ -15,5 +15,5 @@ export default class LogsCommand extends ResolvedCommand<typeof LogsCommand> {
|
|
|
15
15
|
force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
16
16
|
watch: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
17
17
|
};
|
|
18
|
-
run(): Promise<Record<string, unknown
|
|
18
|
+
run(): Promise<void | Record<string, unknown>>;
|
|
19
19
|
}
|
|
@@ -46,6 +46,7 @@ Use --watch (-w) to stream logs in real-time. Use --delete to clear all logs for
|
|
|
46
46
|
char: 'w',
|
|
47
47
|
description: 'Watch for new logs (streaming mode)',
|
|
48
48
|
aliases: ['follow'],
|
|
49
|
+
exclusive: ['json'],
|
|
49
50
|
}),
|
|
50
51
|
};
|
|
51
52
|
async run() {
|
|
@@ -67,6 +68,8 @@ Use --watch (-w) to stream logs in real-time. Use --delete to clear all logs for
|
|
|
67
68
|
});
|
|
68
69
|
if (!result.success)
|
|
69
70
|
this.coreError(result);
|
|
71
|
+
if (result.streaming)
|
|
72
|
+
return result.streaming;
|
|
70
73
|
return result.json;
|
|
71
74
|
}
|
|
72
75
|
}
|
|
@@ -4,21 +4,21 @@ import { getStack, updateStack } from '../../actions/blueprints/stacks.js';
|
|
|
4
4
|
import { waitForOperation } from '../../actions/blueprints/wait-for-operation.js';
|
|
5
5
|
import { checkUserPermission } from '../../actions/sanity/access.js';
|
|
6
6
|
import { createHintCollector } from '../../utils/blueprints/hints.js';
|
|
7
|
-
import { niceId } from '../../utils/display/presenters.js';
|
|
7
|
+
import { check, niceId, severe } from '../../utils/display/presenters.js';
|
|
8
8
|
import { CODE_OPERATION_UNCONFIRMED, EXIT_OPERATION_UNCONFIRMED } from '../../utils/exit-codes.js';
|
|
9
9
|
import { styleText } from '../../utils/style-text.js';
|
|
10
10
|
import { getWarnings } from '../../utils/warnings.js';
|
|
11
11
|
export async function blueprintDeployCore(options) {
|
|
12
|
-
const { bin = 'sanity', log, auth, stackId, scopeType, scopeId, deployedStack, blueprint, flags, } = options;
|
|
12
|
+
const { bin = 'sanity', log: logger, auth, stackId, scopeType, scopeId, deployedStack, blueprint, flags, } = options;
|
|
13
13
|
const { verbose } = flags;
|
|
14
14
|
const noWait = flags['no-wait'] || false;
|
|
15
15
|
const stackName = flags['new-stack-name'] ?? deployedStack.name;
|
|
16
16
|
const installer = flags['fn-installer'] || undefined;
|
|
17
17
|
const blueprintFileDir = dirname(blueprint.fileInfo.blueprintFilePath);
|
|
18
18
|
const workspaceWarnings = getWarnings({ dir: blueprintFileDir });
|
|
19
|
-
|
|
19
|
+
logger(`Deploying "${stackName}" ${niceId(deployedStack.id)}...`);
|
|
20
20
|
try {
|
|
21
|
-
const { ok: checkOk, stack: currentStack } = await getStack({ stackId, auth, logger
|
|
21
|
+
const { ok: checkOk, stack: currentStack } = await getStack({ stackId, auth, logger });
|
|
22
22
|
if (!checkOk) {
|
|
23
23
|
return { success: false, error: 'Failed to check current Stack status' };
|
|
24
24
|
}
|
|
@@ -37,20 +37,20 @@ export async function blueprintDeployCore(options) {
|
|
|
37
37
|
const preDeployResult = await preDeploy({
|
|
38
38
|
scopeType,
|
|
39
39
|
scopeId,
|
|
40
|
-
resources,
|
|
40
|
+
resources, // mutated by preDeploy
|
|
41
41
|
stackId,
|
|
42
42
|
stackName,
|
|
43
43
|
auth,
|
|
44
44
|
blueprintFileDir,
|
|
45
45
|
installer,
|
|
46
|
-
|
|
46
|
+
logger,
|
|
47
47
|
bin,
|
|
48
48
|
verbose,
|
|
49
|
+
onAssetEvent: createAssetEventHandler(logger),
|
|
49
50
|
});
|
|
50
|
-
if (!preDeployResult?.success)
|
|
51
|
+
if (!preDeployResult?.success)
|
|
51
52
|
return preDeployResult;
|
|
52
|
-
|
|
53
|
-
const spinner = log.ora('Deploying...').start();
|
|
53
|
+
const deploySpinner = logger.ora('Deploying...').start();
|
|
54
54
|
const { ok: deployOk, stack, error: deployError, } = await updateStack({
|
|
55
55
|
stackId,
|
|
56
56
|
stackMutation: {
|
|
@@ -61,10 +61,10 @@ export async function blueprintDeployCore(options) {
|
|
|
61
61
|
userMessage: flags.message,
|
|
62
62
|
},
|
|
63
63
|
auth,
|
|
64
|
-
logger
|
|
64
|
+
logger,
|
|
65
65
|
});
|
|
66
66
|
if (!deployOk) {
|
|
67
|
-
|
|
67
|
+
deploySpinner.fail(`${styleText('red', 'Failed')} to update Stack deployment`);
|
|
68
68
|
const hints = createHintCollector(bin);
|
|
69
69
|
if (deployError) {
|
|
70
70
|
hints.inspectMessage(deployError);
|
|
@@ -79,18 +79,18 @@ export async function blueprintDeployCore(options) {
|
|
|
79
79
|
],
|
|
80
80
|
};
|
|
81
81
|
}
|
|
82
|
-
|
|
82
|
+
deploySpinner.stop().clear();
|
|
83
83
|
const legacyPermissionsNoticePromise = CHECK_LEGACY_DEPLOY_PERMISSION
|
|
84
84
|
? checkLegacyDeployPermission({
|
|
85
85
|
auth,
|
|
86
86
|
scopeType,
|
|
87
87
|
scopeId,
|
|
88
|
-
log,
|
|
88
|
+
log: logger,
|
|
89
89
|
})
|
|
90
90
|
: Promise.resolve(null);
|
|
91
91
|
if (noWait) {
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
logger(styleText(['bold', 'green'], 'Stack deployment started!'));
|
|
93
|
+
logger(`Use \`npx ${bin} blueprints info\` to check status`);
|
|
94
94
|
const legacyWarning = await legacyPermissionsNoticePromise;
|
|
95
95
|
const warnings = [...(legacyWarning ? [legacyWarning] : []), ...workspaceWarnings];
|
|
96
96
|
return {
|
|
@@ -100,19 +100,19 @@ export async function blueprintDeployCore(options) {
|
|
|
100
100
|
warnings: warnings.length ? warnings : undefined,
|
|
101
101
|
};
|
|
102
102
|
}
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
logger(styleText('dim', 'Stack deployment progress:'));
|
|
104
|
+
logger('');
|
|
105
105
|
const outcome = await waitForOperation({
|
|
106
106
|
stackId,
|
|
107
107
|
operationId: stack.operationId,
|
|
108
108
|
auth,
|
|
109
|
-
log,
|
|
109
|
+
log: logger,
|
|
110
110
|
bin,
|
|
111
111
|
verbose,
|
|
112
112
|
progressNoun: 'deployment',
|
|
113
113
|
});
|
|
114
114
|
if (outcome.type === 'completed') {
|
|
115
|
-
|
|
115
|
+
logger(styleText(['bold', 'green'], 'Stack deployment completed!'));
|
|
116
116
|
const legacyWarning = await legacyPermissionsNoticePromise;
|
|
117
117
|
const warnings = [...(legacyWarning ? [legacyWarning] : []), ...workspaceWarnings];
|
|
118
118
|
return {
|
|
@@ -151,6 +151,56 @@ export async function blueprintDeployCore(options) {
|
|
|
151
151
|
return { success: false, error: errorMessage };
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
|
+
function createAssetEventHandler(logger) {
|
|
155
|
+
let spinner;
|
|
156
|
+
const results = [];
|
|
157
|
+
return (event) => {
|
|
158
|
+
switch (event.type) {
|
|
159
|
+
case 'progress': {
|
|
160
|
+
const { completed, total, slow } = event.progress;
|
|
161
|
+
const text = [
|
|
162
|
+
`Processing assets (${completed}/${total})`,
|
|
163
|
+
slow ? ', this can take a moment' : '',
|
|
164
|
+
].join('');
|
|
165
|
+
if (spinner)
|
|
166
|
+
spinner.text = text;
|
|
167
|
+
else
|
|
168
|
+
spinner = logger.ora(text).start();
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
case 'result': {
|
|
172
|
+
results.push(event.result);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
case 'complete': {
|
|
176
|
+
spinner?.stop();
|
|
177
|
+
spinner = undefined;
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// done. print report
|
|
182
|
+
for (const result of results) {
|
|
183
|
+
const { resource } = result;
|
|
184
|
+
if (!result.success) {
|
|
185
|
+
const summary = result.failureKind === 'upload'
|
|
186
|
+
? `Failed uploading ${resource.name} asset`
|
|
187
|
+
: `Failed processing ${resource.name} asset`;
|
|
188
|
+
logger(` ${severe(summary)}`);
|
|
189
|
+
logger.error(` ${result.error}`);
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
logger(` ${check(`${resource.name} ${niceId(resource.src)}`)}`);
|
|
193
|
+
logger(` Source: ${resource.src}`);
|
|
194
|
+
if (result.hash) {
|
|
195
|
+
const hash = result.hash;
|
|
196
|
+
const h = hash.length > 24 ? `${hash.slice(0, 8)}...${hash.slice(-12)}` : hash;
|
|
197
|
+
logger.verbose(` Hash: ${h}`);
|
|
198
|
+
}
|
|
199
|
+
if (result.exists)
|
|
200
|
+
logger.verbose(' Asset unchanged');
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
}
|
|
154
204
|
const CHECK_LEGACY_DEPLOY_PERMISSION = false;
|
|
155
205
|
const BLUEPRINTS_PERMISSION_ENFORCEMENT_DATE = 'July 1, 2026';
|
|
156
206
|
async function checkLegacyDeployPermission({ auth, scopeType, scopeId, log, }) {
|
|
@@ -224,7 +224,7 @@ async function promptForFunctionName() {
|
|
|
224
224
|
const functionName = await input({
|
|
225
225
|
message: 'Enter function name:',
|
|
226
226
|
validate: (input) => validateFunctionName(input) ||
|
|
227
|
-
'Invalid function name. Must be
|
|
227
|
+
'Invalid function name. Must be 3+ characters, no special characters, no spaces',
|
|
228
228
|
});
|
|
229
229
|
return functionName;
|
|
230
230
|
}
|
|
@@ -72,15 +72,15 @@ function resourceName(res, displayNameAttribute) {
|
|
|
72
72
|
nameParts.push(styleText('green', `"${displayName}"`));
|
|
73
73
|
return nameParts.join(' ');
|
|
74
74
|
}
|
|
75
|
-
function deployedResourceName(res, displayNameAttribute,
|
|
75
|
+
function deployedResourceName(res, displayNameAttribute, verbose = false) {
|
|
76
76
|
const nameParts = [styleText(['bold', 'green'], res.name)];
|
|
77
77
|
const displayName = displayNameAttribute &&
|
|
78
78
|
typeof res.parameters[displayNameAttribute] === 'string' &&
|
|
79
79
|
res.parameters[displayNameAttribute];
|
|
80
80
|
if (displayName && displayName !== res.name)
|
|
81
81
|
nameParts.push(styleText('green', `"${displayName}"`));
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
if (verbose)
|
|
83
|
+
nameParts.push(idList(res));
|
|
84
84
|
return nameParts.join(' ');
|
|
85
85
|
}
|
|
86
86
|
function idList(res) {
|
package/dist/utils/style-text.js
CHANGED
package/oclif.manifest.json
CHANGED
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
"skill"
|
|
56
56
|
],
|
|
57
57
|
"description": "Show agent-oriented guidance for this command",
|
|
58
|
+
"hidden": true,
|
|
58
59
|
"name": "llms",
|
|
59
60
|
"allowNo": false,
|
|
60
61
|
"type": "boolean"
|
|
@@ -501,7 +502,7 @@
|
|
|
501
502
|
"blueprints:deploy": {
|
|
502
503
|
"aliases": [],
|
|
503
504
|
"args": {},
|
|
504
|
-
"description": "Applies your local Blueprint to the remote Stack, creating, updating, or removing resources as needed. This is the primary command for applying infrastructure changes.\n\nBefore deploying, run 'blueprints plan' to preview changes. After deployment, use 'blueprints info' to verify Stack status or 'blueprints logs' to monitor activity.\n\nUse --no-wait to queue the deployment and return immediately without waiting for completion.\n\nUse --fn-installer to force which package manager to use when deploying functions.\n\nSet SANITY_ASSET_TIMEOUT (seconds) to override the
|
|
505
|
+
"description": "Applies your local Blueprint to the remote Stack, creating, updating, or removing resources as needed. This is the primary command for applying infrastructure changes.\n\nBefore deploying, run 'blueprints plan' to preview changes. After deployment, use 'blueprints info' to verify Stack status or 'blueprints logs' to monitor activity.\n\nUse --no-wait to queue the deployment and return immediately without waiting for completion.\n\nUse --fn-installer to force which package manager to use when deploying functions.\n\nSet SANITY_ASSET_TIMEOUT (seconds) to override the 180-second timeout for processing resource assets.\n\nSet SANITY_ASSET_CONCURRENCY to override how many resource assets are processed at once (default 4).\n\nExit codes: 0 deployed, 2 deployment failed, 75 deployment accepted but completion could not be confirmed (rerun 'blueprints info' to check).",
|
|
505
506
|
"examples": [
|
|
506
507
|
"<%= config.bin %> <%= command.id %>",
|
|
507
508
|
"<%= config.bin %> <%= command.id %> --message \"Enable staging dataset\"",
|
|
@@ -757,9 +758,7 @@
|
|
|
757
758
|
"type": "option"
|
|
758
759
|
},
|
|
759
760
|
"force": {
|
|
760
|
-
"
|
|
761
|
-
"f"
|
|
762
|
-
],
|
|
761
|
+
"char": "f",
|
|
763
762
|
"description": "Force Stack destruction (skip confirmation)",
|
|
764
763
|
"name": "force",
|
|
765
764
|
"allowNo": false,
|
|
@@ -909,8 +908,8 @@
|
|
|
909
908
|
"type": "boolean"
|
|
910
909
|
},
|
|
911
910
|
"verbose": {
|
|
912
|
-
"
|
|
913
|
-
"
|
|
911
|
+
"char": "v",
|
|
912
|
+
"description": "Show resource and external IDs",
|
|
914
913
|
"name": "verbose",
|
|
915
914
|
"allowNo": false,
|
|
916
915
|
"type": "boolean"
|
|
@@ -983,7 +982,7 @@
|
|
|
983
982
|
"name": "dir"
|
|
984
983
|
}
|
|
985
984
|
},
|
|
986
|
-
"description": "A Blueprint is your local infrastructure-as-code configuration that defines Sanity resources (datasets, functions, etc.). A Stack is the remote deployment target where your Blueprint is applied.\n
|
|
985
|
+
"description": "A Blueprint is your local infrastructure-as-code configuration that defines Sanity resources (datasets, functions, etc.). A Stack is the remote deployment target where your Blueprint is applied.\n\nThis is typically the first command you run in a new project. It creates a local Blueprint manifest file (sanity.blueprint.ts, .js, or .json) and provisions a new remote Stack.\nAdditionally, a Blueprint configuration file is created in .sanity/ containing the scope and Stack IDs. A .gitignore covering node_modules, .env, and Function build output is created or updated; the .sanity/ config itself is not ignored.\n\nAfter initialization, use 'blueprints plan' to preview changes, then 'blueprints deploy' to apply them.\n\nRunning without a directory prompts to confirm the current directory. Run 'blueprints init .' to initialize in the current directory without a prompt.",
|
|
987
986
|
"examples": [
|
|
988
987
|
"<%= config.bin %> <%= command.id %>",
|
|
989
988
|
"<%= config.bin %> <%= command.id %> .",
|
|
@@ -1260,6 +1259,9 @@
|
|
|
1260
1259
|
],
|
|
1261
1260
|
"char": "w",
|
|
1262
1261
|
"description": "Watch for new Stack logs",
|
|
1262
|
+
"exclusive": [
|
|
1263
|
+
"json"
|
|
1264
|
+
],
|
|
1263
1265
|
"name": "watch",
|
|
1264
1266
|
"allowNo": false,
|
|
1265
1267
|
"type": "boolean"
|
|
@@ -1896,11 +1898,12 @@
|
|
|
1896
1898
|
"description": "Example to use for the Function",
|
|
1897
1899
|
"exclusive": [
|
|
1898
1900
|
"name",
|
|
1899
|
-
"
|
|
1901
|
+
"type",
|
|
1900
1902
|
"language",
|
|
1901
1903
|
"javascript",
|
|
1902
|
-
"
|
|
1903
|
-
"
|
|
1904
|
+
"helpers",
|
|
1905
|
+
"installer",
|
|
1906
|
+
"install"
|
|
1904
1907
|
],
|
|
1905
1908
|
"name": "example",
|
|
1906
1909
|
"hasDynamicHelp": false,
|
|
@@ -1984,9 +1987,9 @@
|
|
|
1984
1987
|
},
|
|
1985
1988
|
"install": {
|
|
1986
1989
|
"char": "i",
|
|
1987
|
-
"description": "Shortcut for --
|
|
1990
|
+
"description": "Shortcut for --installer npm",
|
|
1988
1991
|
"exclusive": [
|
|
1989
|
-
"
|
|
1992
|
+
"installer"
|
|
1990
1993
|
],
|
|
1991
1994
|
"name": "install",
|
|
1992
1995
|
"allowNo": false,
|
|
@@ -2152,9 +2155,9 @@
|
|
|
2152
2155
|
"functions:dev": {
|
|
2153
2156
|
"aliases": [],
|
|
2154
2157
|
"args": {},
|
|
2155
|
-
"description": "Runs a local, web-based development server to test your functions before deploying.\n\nOpen the emulator in your browser to interactively test your functions with the payload editor.\n\nOptionally, set the host and port with the --host and --port flags. Function timeout can be configured with the --timeout flag.\n\nTo invoke a function with the CLI, use 'functions test'.",
|
|
2158
|
+
"description": "Runs a local, web-based development server to test your functions before deploying.\n\nOpen the emulator in your browser to interactively test your functions with the payload editor.\n\nOptionally, set the host and port with the --host and --port flags. Port 8974 is reserved for the emulator's live-reload WebSocket server. Function timeout can be configured with the --timeout flag.\n\nTo invoke a function with the CLI, use 'functions test'.",
|
|
2156
2159
|
"examples": [
|
|
2157
|
-
"<%= config.bin %> <%= command.id %> --host 127.0.0.1 --port
|
|
2160
|
+
"<%= config.bin %> <%= command.id %> --host 127.0.0.1 --port 3333",
|
|
2158
2161
|
"<%= config.bin %> <%= command.id %> --timeout 60"
|
|
2159
2162
|
],
|
|
2160
2163
|
"flags": {
|
|
@@ -2538,6 +2541,9 @@
|
|
|
2538
2541
|
],
|
|
2539
2542
|
"char": "w",
|
|
2540
2543
|
"description": "Watch for new logs (streaming mode)",
|
|
2544
|
+
"exclusive": [
|
|
2545
|
+
"json"
|
|
2546
|
+
],
|
|
2541
2547
|
"name": "watch",
|
|
2542
2548
|
"allowNo": false,
|
|
2543
2549
|
"type": "boolean"
|
|
@@ -3248,5 +3254,5 @@
|
|
|
3248
3254
|
]
|
|
3249
3255
|
}
|
|
3250
3256
|
},
|
|
3251
|
-
"version": "17.4.0-blueprinit.
|
|
3257
|
+
"version": "17.4.0-blueprinit.g596ac51"
|
|
3252
3258
|
}
|